Search                        Top                                  Index
/*
FILE:            /bham/common/com/packages/poplog/local/teach/proglect9
AUTHOR:          Aaron Sloman
CREATION DATE:   22 Oct 1996
COURSE:          several
PURPOSE:         Help with programming, e.g. for mini projects
LAST MODIFIED:   20 Oct 1998

*/

TEACH PROGLECT9                                    Aaron Sloman Oct 1998

This lecture is intended to be useful when students are beginning to
work on their mini-projects. It identifies some common faults in project
reports and how to avoid them.

Previous lectures are summarised as teach files, with examples which you
can run.

    TEACH * PROGLECT1
    TEACH * PROGLECT2
    TEACH * PROGLECT3
    TEACH * PROGLECT4
    TEACH * PROGLECT5
    TEACH * PROGLECT6
    TEACH * PROGLECT7
    TEACH * PROGLECT8

CONTENTS

 -- Introduction
 -- File and procedure headers
 -- Problems found in programming files
 -- a. Poor file headers
 -- b. Lack of test examples for procedures
 -- c. Test examples outside comment brackets
 -- d. Problems with apostrophes
 -- e. Inconsistent use of "?" and "^", "??" and "^^"
 -- f. Poor use of program and documentation libraries
 -- g. Mixing up foreach and forevery
 -- h. Undeclared variables
 -- Problems found in reports
 -- a. Missing introduction
 -- b. Missing sample interaction
 -- c. Explanations too low level and detailed
 -- d. Missing critical evaluation
 -- e. No links to literature
 -- f. Incomplete pathnames for load commands

-- Introduction -------------------------------------------------------

There are many little problems that reduce the quality of programming
files. Some of these actually make the programming tasks harder for the
student. Some are more concerned with presentation to others, e.g.
examiners, or other people who wish to use and possibly extend or
maintain the programs.

It may be useful to look at the checklist used to help with marking of
mini_projects.
    TEACH MSC.PROJECT.CHECKLIST

-- File and procedure headers -----------------------------------------

Use
    ENTER fileheader

To set up a header for each file, and remember to update the header as
the file develops. The header of this file was created with that
command.

Remember to change the file path name if you change the directory.

When giving file locations, don't just use ~ to indicate your top
level directory. For other people that will refer to THEIR top level
directory. So if your login name is "xyz" always use ~xyz, e.g.

    ~xyz/project/startup.p

Use
    ENTER procheader

inside a procedure definition, to set up a header for each procedure
definition. E.g.

Given this definition

define search_for(target, list) -> (found, location);
    0 -> location;

    lvars item;
    for item in list do
        location + 1 -> location;
        if item = target then
            true -> found;
            return()
        endif
    endfor;

    false -> found;
    0 -> location;

enddefine;

    ENTER procheader

Will produce the following header, above the procedure definition, for
you to complete:

/*
PROCEDURE: search_for (target, list) -> (found, location)
INPUTS   : target, list
  Where  :
    target is a ???
    list is a ???
OUTPUTS  : found, location
  Where  :
    found is a ???
    location is a ???
USED IN  : ???
CREATED  : 22 Feb 1998
PURPOSE  : ???

TESTS:

*/

(For details see HELP * VED_PROCHEADER).


-- Problems found in programming files --------------------------------

The following comments arise out of my examination of student
files produced while working through TEACH RESPOND, TEACH RIVER2
and other things.

Not everyone has followed the instructions carefully. Here are points to
remember:

-- a. Poor file headers

Ensure that information at the top of the file is adequate (e.g. if
printed). E.g. give the FULL path name of the file, author, what it is
about, etc. in a comment at the top of the file, as explained above.
The full pathname can start with ~XXXYZ/ if your login name is XXXYZ.

-- b. Lack of test examples for procedures

Include test examples for your procedures, or have them in a separate
file, clearly indicated in the file header and procedure headers.


-- c. Test examples outside comment brackets

Do not have test examples or "run" instructions at "top-level"
in the file. Put them inside comments. Often it is useful to have
a file that starts things up by loading other files and then runs the
program. If you load up a file of procedure definitions and it includes
test commands you will probably have unnecessary problems. Putting the
tests inside comments, like this, avoids the problems:

    /*
    ;;; test for run_prog
    run_prog(list1, list2) =>
    */

See TEACH * RIVER2, TEACH * TOWER for examples.

-- d. Problems with apostrophes

Apostrophes in words like "don't" cause problems:

Use
    [sorry I do not understand] ==>

rather than

    [sorry I don't understand] ==>

as the latter won't work. WHY?

An apostrophe in Pop-11 is treated as as introducing a string. That's
why it is called the "string quote" character, as opposed to the word
quote character.

Make sure you understand the error message. (Where's the closing string
quote?)

There are three types of quotes in Pop-11.

    String quote:    '
    Word quote:      "
    Character quote: `

A previous lecture explained some of the subtle difference between
strings and words in Pop-11, and how words, but not strings, are entered
in the Pop-11 dictionary. See also The Pop-11 Primer, and
    HELP * STRINGS
    HELP * WORDS


If you must print an apostrophe you can use a string, with "\" before
the apostrophe, e.g.

    [sorry I 'don\'t' understand] ==>
or even
    ['sorry I don\'t understand'] ==>

or, if you don't need a list, use just a string

    'sorry I don\'t understand' =>

(See HELP * PRINTF for more information on formatted printing.)


-- e. Inconsistent use of "?" and "^", "??" and "^^"

This is a very common source of problems.

Using "?" in a pattern to pick up an element of a list, and then using
"^^" to merge the result into another list can cause a "LIST NEEDED"
mishap. WHY?

Example:

    if input matches ! [is the ?obj1 ?rel the ?obj2] then
        ....
        [No the ^^obj1 is not ^^rel the ^^obj2] ==>

will produce an error (LIST NEEDED). Why?

The answer is to be consistent:
    "?obj1" may match ONE word, without making a list containing that
    word.

    "^^obj1" assumes that the value of obj1 is a LIST, not a WORD.

"^^" means something like "include the list elements".

Another problem can arise if you use something like "??xx" in a pattern.
Then if the match succeeds, the variable xx will be given as its value a
LIST of items whatever matched the pattern. It could be an empty list.
It could be a list with exactly one element. It could have many
elements.

Then if you wish to create another list using xx, e.g. to print out a
message or to insert information in the database, then you must think
very clearly whether to use "^xx" or "^^xx". The former will insert the
whole list as a single element. The latter will insert the elements
of the list separately.

When you've inserted the new information in a new database item, you
have to make sure that subsequent searches use a pattern that is in the
right format to find what you have inserted. E.g. use the "??" form to
match items inserted in a list using "^^", and use "?" to match an item
inserted using "^".

If you don't think very clearly about this, then you may insert
something in the database and later search for it using the wrong form
of pattern. You may then wonder why your program does not work, despite
having all the information it needs.


See TEACH * ARROW, and HELP * MATCHES


-- f. Poor use of program and documentation libraries

VED uses several search lists to find information, in particular:

    popuseslist
    popautolist
    vedhelplist
    vedteachlist
    vedreflist

Each of these is a list of directories in which to search.

The first two lists are also used by the "uses" and "lib" commands.

Use of the commands is subtly different:

    uses ....
    lib ....

The latter always compiles compiles the file. The former only compiles
the file if the identifier given has not yet been declared.

In general uses "uses" not "lib", to prevent unnecessary recompilation.
Also remember NOT to put those commands inside procedures. They should
be at "top level" i.e. direct commands in a file, before the procedures
that require the libraries.

    See HELP * LIBRARIES
    REF * LIBRARY for full information ....


-- g. Mixing up foreach and forevery

What's the difference?

    foreach ! <pattern> do <actions> endforeach

    forevery ! <list of patterns> do <actions> endforevery;

Note: both allow the "in list" extension before "do".

See TEACH FOREACH, HELP FOREVERY

-- h. Undeclared variables

Autoloading and warning messages.

If you don't declare a variable, and you have not previously used it as
a global variable in the current pop-11 session, then the system will
look to see if the variable is a name of an autoloadable library, in
popautolist.

This can involve searching in a lot of different directories, which
causes network traffic and unnecessary use of the disks on the file
store, and can slow things down a lot, for you and other users.

Worse, it can cause a library to be found that you did not want, and it
may be compiled automatically without your knowing, causing problems
when you run your programs.

When you use an undeclared variable, the procedure prwarning is used to
print out a warning. This gives you a clue

    wrwrw =>
    ;;; DECLARING VARIABLE wrwrw
    ** <undef wrwrw>

Those DECLARING VARIABLE messages are an indication that you must
fix something.

ALWAYS pay attention to those warnings and find the right place to
insert declarations. If you use a procedure before it is defined you
can insert a global definition at the top of the file.

Sometimes inserting one declaration does not solve all the problems
because the same variable has been used in another procedure where it
should have been declared as local but was not. This will not show up
when you recompile your file (in the same session) because the variable
has already been declared as global automatically.

You can use the command
    ENTER resetvars

to cancel the variables which were automatically declared, with warning
messages. Then if you recompile your file and one of the variables is
still used without a proper declaration you will get another warning.

ENTER resetvars
resets the state of the system by removing the automatically declared
variables from the Pop-11 dictionary.

HELP * VED_RESETVARS

-- Problems found in reports ------------------------------------------

-- a. Missing introduction

-- b. Missing sample interaction

-- c. Explanations too low level and detailed

-- d. Missing critical evaluation
    Including discussion of weakness and possible further developments.

-- e. No links to literature

-- f. Incomplete pathnames for load commands

In appendix giving instructions on how to run the programs, or in the
project report if there are references to some existing programs,
any load commands should have full pathname, e.g.

Not just
    load river2.p
nor
    load ~/river2.p

but, if your user name is "xyz",  something like

    load ~xyz/river2.p

WHY?

Answer: so that other people (including examiners) can check out your
programs, without having to log in as you.



... this file may be extended ....

NB See TEACH * REPORTS for information on presenting project reports.

--- $poplocal/local/teach/proglect9
--- Copyright University of Birmingham 1998. All rights reserved. ------