|
|
1.1 ! root 1: .\" @(#)p5 6.1 (Berkeley) 5/23/86 ! 2: .\" ! 3: .NH ! 4: The Script Interpreter. ! 5: .PP ! 6: The ! 7: .I ! 8: learn ! 9: .R ! 10: program itself merely interprets scripts. It provides ! 11: facilities for the script writer to capture student ! 12: responses and their effects, and simplifies the job ! 13: of passing control to and recovering control from the student. ! 14: This section describes the operation and ! 15: usage of the driver program, ! 16: and indicates what is ! 17: required to produce a new script. ! 18: Readers only interested in ! 19: the existing scripts may skip this section. ! 20: .PP ! 21: The file structure used by ! 22: .I learn ! 23: is shown in Figure 2. ! 24: There is one parent directory (named \f2lib\f1\^) containing the script data. ! 25: Within this directory are subdirectories, one for each ! 26: subject in which a course is available, ! 27: one for logging (named ! 28: .I log ), ! 29: and one in which user sub-directories ! 30: are created (named ! 31: .I play ). ! 32: The subject directory contains master copies of all lessons, ! 33: plus any supporting material for that subject. ! 34: In a given subdirectory, ! 35: each lesson is a single text file. ! 36: Lessons are usually named systematically; ! 37: the file that contains lesson ! 38: .I n ! 39: is called ! 40: .I Ln . ! 41: .br ! 42: .KF ! 43: .sp ! 44: .TS ! 45: center, box; ! 46: c s s s ! 47: l l l l. ! 48: Figure 2: Directory structure for \fIlearn\fR ! 49: .sp ! 50: .nf ! 51: lib ! 52: .if t .sp .5 ! 53: play ! 54: student1 ! 55: files for student1... ! 56: student2 ! 57: files for student2... ! 58: .if t .sp .5 ! 59: files ! 60: L0.1a lessons for files course ! 61: L0.1b ! 62: ... ! 63: .if t .sp .5 ! 64: editor ! 65: ... ! 66: .if t .sp .5 ! 67: (other courses) ! 68: .if t .sp .5 ! 69: log ! 70: .TE ! 71: .sp ! 72: .KE ! 73: .PP ! 74: When ! 75: .I ! 76: learn ! 77: .R ! 78: is executed, it makes a private directory ! 79: for the user to work in, ! 80: within the ! 81: .I ! 82: learn ! 83: .R ! 84: portion of the file system. ! 85: A fresh copy of all the files used in each lesson ! 86: (mostly data for the student to operate upon) is made each ! 87: time a student starts a lesson, ! 88: so the script writer may assume that everything ! 89: is reinitialized each time a lesson is entered. ! 90: The student directory is deleted after each session; any permanent records ! 91: must be kept elsewhere. ! 92: .PP ! 93: The script writer must provide certain basic items ! 94: in each ! 95: lesson: ! 96: .IP (1) ! 97: the text of the lesson; ! 98: .IP (2) ! 99: the set-up commands to be executed before the user gets control; ! 100: .IP (3) ! 101: the data, if any, which the user is supposed to edit, transform, or otherwise ! 102: process; ! 103: .IP (4) ! 104: the evaluating commands to be executed after the user ! 105: has finished the lesson, to decide whether the answer is right; ! 106: and ! 107: .IP (5) ! 108: a list of possible successor lessons. ! 109: .LP ! 110: .I ! 111: Learn ! 112: .R ! 113: tries to minimize the work ! 114: of bookkeeping and installation, so ! 115: that most of the effort involved in ! 116: script production is in planning lessons, ! 117: writing tutorial paragraphs, ! 118: and coding tests of student performance. ! 119: .PP ! 120: The basic sequence of events is ! 121: as follows. ! 122: First, ! 123: .I learn ! 124: creates the working directory. ! 125: Then, for each lesson, ! 126: .I learn ! 127: reads the script for the lesson and processes ! 128: it a line at a time. ! 129: The lines in the script are: ! 130: (1) commands to the script interpreter ! 131: to print something, to create a files, ! 132: to test something, etc.; ! 133: (2) text to be printed or put in a file; ! 134: (3) other lines, which are sent to ! 135: the shell to be executed. ! 136: One line in each lesson turns control over ! 137: to the user; ! 138: the user can run any ! 139: .UX ! 140: commands. ! 141: The user mode terminates when the user ! 142: types ! 143: .I yes , ! 144: .I no , ! 145: .I ready , ! 146: or ! 147: .I answer . ! 148: At this point, the user's work is tested; ! 149: if the lesson is passed, ! 150: a new lesson is selected, and if not ! 151: the old one is repeated. ! 152: .PP ! 153: Let us illustrate this with the script ! 154: for the second lesson of Figure 1; ! 155: this is shown in Figure 3. ! 156: .KF ! 157: .sp ! 158: .TS ! 159: center, box; ! 160: c. ! 161: T{ ! 162: Figure 3: Sample Lesson ! 163: .sp ! 164: .nf ! 165: #print ! 166: Of course, you can print any file with "cat". ! 167: In particular, it is common to first use ! 168: "ls" to find the name of a file and then "cat" ! 169: to print it. Note the difference between ! 170: "ls", which tells you the name of the files, ! 171: and "cat", which tells you the contents. ! 172: One file in the current directory is named for ! 173: a President. Print the file, then type "ready". ! 174: #create roosevelt ! 175: this file is named roosevelt ! 176: and contains three lines of ! 177: text. ! 178: #copyout ! 179: #user ! 180: #uncopyout ! 181: tail \-3 .ocopy >X1 ! 182: #cmp X1 roosevelt ! 183: #log ! 184: #next ! 185: 3.2b 2 ! 186: .fi ! 187: T} ! 188: .TE ! 189: .sp ! 190: .KE ! 191: .LP ! 192: Lines which begin with ! 193: # are commands to the ! 194: .I learn ! 195: script interpreter. ! 196: For example, ! 197: .LP ! 198: .ul ! 199: #print ! 200: .LP ! 201: causes printing of any text that follows, ! 202: up to the next line that begins with a sharp. ! 203: .LP ! 204: .ul ! 205: #print file ! 206: .LP ! 207: prints the contents of ! 208: .I file ; ! 209: it ! 210: is the same as ! 211: .ul ! 212: cat file ! 213: but has ! 214: less overhead. ! 215: Both forms of ! 216: .I #print ! 217: have the added property that if a lesson is failed, ! 218: the ! 219: .ul ! 220: #print ! 221: will not be executed the second time through; ! 222: this avoids annoying the student by repeating the preamble ! 223: to a lesson. ! 224: .LP ! 225: .ul ! 226: #create filename ! 227: .LP ! 228: creates a file of the specified name, ! 229: and copies any subsequent text up to a ! 230: # to the file. ! 231: This is used for creating and initializing working files ! 232: and reference data for the lessons. ! 233: .LP ! 234: .ul ! 235: #user ! 236: .LP ! 237: gives control to the student; ! 238: each line he or she types is passed to the shell ! 239: for execution. ! 240: The ! 241: .I #user ! 242: mode ! 243: is terminated when the student types one of ! 244: .I yes , ! 245: .I no , ! 246: .I ready ! 247: or ! 248: .I answer . ! 249: At that time, the driver ! 250: resumes interpretation of the script. ! 251: .LP ! 252: .ul ! 253: #copyin ! 254: .br ! 255: .ul ! 256: #uncopyin ! 257: .LP ! 258: Anything the student types between these ! 259: commands is copied onto a file ! 260: called ! 261: .ul ! 262: \&.copy. ! 263: This lets the script writer interrogate the student's ! 264: responses upon regaining control. ! 265: .LP ! 266: .ul ! 267: #copyout ! 268: .br ! 269: .ul ! 270: #uncopyout ! 271: .LP ! 272: Between these commands, any material typed at the student ! 273: by any program ! 274: is copied to the file ! 275: .ul ! 276: \&.ocopy. ! 277: This lets the script writer interrogate the ! 278: effect of what the student typed, ! 279: which true believers in the performance theory of learning ! 280: usually ! 281: prefer to the student's actual input. ! 282: .LP ! 283: .ul ! 284: #pipe ! 285: .br ! 286: .ul ! 287: #unpipe ! 288: .LP ! 289: Normally the student input and the script commands ! 290: are fed to the ! 291: .UX ! 292: command interpreter (the ``shell'') one line at a time. This won't do ! 293: if, for example, a sequence of editor commands ! 294: is provided, ! 295: since the input to the editor must be handed to the editor, ! 296: not to the shell. ! 297: Accordingly, the material between ! 298: .ul ! 299: #pipe ! 300: and ! 301: .ul ! 302: #unpipe ! 303: commands ! 304: is fed ! 305: continuously through a pipe so that such sequences ! 306: work. ! 307: If ! 308: .ul ! 309: copyout ! 310: is also desired ! 311: the ! 312: .ul ! 313: copyout ! 314: brackets must include ! 315: the ! 316: .ul ! 317: pipe ! 318: brackets. ! 319: .PP ! 320: There are several commands for setting status ! 321: after the student has attempted the lesson. ! 322: .LP ! 323: .ul ! 324: #cmp file1 file2 ! 325: .LP ! 326: is an in-line implementation of ! 327: .I cmp , ! 328: which compares two files for identity. ! 329: .LP ! 330: .ul ! 331: #match stuff ! 332: .LP ! 333: The last line of the student's input ! 334: is compared to ! 335: .I stuff , ! 336: and the success or fail status is set ! 337: according to it. ! 338: Extraneous things like the word ! 339: .I answer ! 340: are stripped before the comparison is made. ! 341: There may be several ! 342: .I #match ! 343: lines; ! 344: this provides a convenient mechanism for handling multiple ! 345: ``right'' answers. ! 346: Any text up to a ! 347: # on subsequent lines after a successful ! 348: .I #match ! 349: is printed; ! 350: this is illustrated in Figure 4, another sample lesson. ! 351: .br ! 352: .KF ! 353: .sp ! 354: .TS ! 355: center, box; ! 356: c. ! 357: T{ ! 358: Figure 4: Another Sample Lesson ! 359: .sp ! 360: .nf ! 361: #print ! 362: What command will move the current line ! 363: to the end of the file? Type ! 364: "answer COMMAND", where COMMAND is the command. ! 365: #copyin ! 366: #user ! 367: #uncopyin ! 368: #match m$ ! 369: #match .m$ ! 370: "m$" is easier. ! 371: #log ! 372: #next ! 373: 63.1d 10 ! 374: T} ! 375: .TE ! 376: .sp ! 377: .KE ! 378: .LP ! 379: .ul ! 380: #bad stuff ! 381: .LP ! 382: This is similar to ! 383: .I #match , ! 384: except that it corresponds to specific failure answers; ! 385: this can be used to produce hints for particular wrong answers ! 386: that have been anticipated by the script writer. ! 387: .LP ! 388: .ul ! 389: #succeed ! 390: .br ! 391: .ul ! 392: #fail ! 393: .LP ! 394: print a message ! 395: upon success or failure ! 396: (as determined by some previous mechanism). ! 397: .PP ! 398: When the student types ! 399: one of the ``commands'' ! 400: .I yes , ! 401: .I no , ! 402: .I ready , ! 403: or ! 404: .I answer , ! 405: the driver terminates the ! 406: .I #user ! 407: command, ! 408: and evaluation of the student's work can begin. ! 409: This can be done either by ! 410: the built-in commands above, such as ! 411: .I #match ! 412: and ! 413: .I #cmp , ! 414: or by status returned by normal ! 415: .UX ! 416: commands, typically ! 417: .I grep ! 418: and ! 419: .I test . ! 420: The last command ! 421: should return status true ! 422: (0) if the task was done successfully and ! 423: false (non-zero) otherwise; ! 424: this status return tells the driver ! 425: whether or not the student ! 426: has successfully passed the lesson. ! 427: .PP ! 428: Performance can be logged: ! 429: .LP ! 430: .ul ! 431: #log file ! 432: .LP ! 433: writes the date, lesson, user name and speed rating, and ! 434: a success/failure indication on ! 435: .ul ! 436: file. ! 437: The command ! 438: .LP ! 439: .ul ! 440: #log ! 441: .LP ! 442: by itself writes the logging information ! 443: in the logging directory ! 444: within the ! 445: .I learn ! 446: hierarchy, ! 447: and is the normal form. ! 448: .LP ! 449: .ul ! 450: #next ! 451: .LP ! 452: is followed by a few lines, each with a successor ! 453: lesson name and an optional speed rating on it. ! 454: A typical set might read ! 455: .LP ! 456: .nf ! 457: 25.1a 10 ! 458: 25.2a 5 ! 459: 25.3a 2 ! 460: .fi ! 461: .LP ! 462: indicating that unit 25.1a is a suitable follow-on lesson ! 463: for students with ! 464: a speed rating of 10 units, ! 465: 25.2a for student with speed near 5, ! 466: and 25.3a for speed near 2. ! 467: Speed ratings are maintained for ! 468: each session with a student; the ! 469: rating is increased by one each time ! 470: the student gets a lesson right and decreased ! 471: by four each ! 472: time the student gets a lesson wrong. ! 473: Thus the driver tries to maintain a level such ! 474: that the users get 80% right answers. ! 475: The maximum rating is limited to 10 and the minimum to 0. ! 476: The initial rating is zero unless the student ! 477: specifies a different rating when starting ! 478: a session. ! 479: .PP ! 480: If the student passes a lesson, ! 481: a new lesson is selected and the process repeats. ! 482: If the student fails, a false status is returned ! 483: and the program ! 484: reverts to the previous lesson and tries ! 485: another alternative. ! 486: If it can not find another alternative, it skips forward ! 487: a lesson. ! 488: .I bye , ! 489: bye, ! 490: which causes a graceful exit ! 491: from the ! 492: .ul ! 493: learn ! 494: system. Hanging up is the usual novice's way out. ! 495: .PP ! 496: The lessons may form an arbitrary directed graph, ! 497: although the present program imposes a limitation on cycles in that ! 498: it will not present a lesson twice in the ! 499: same session. ! 500: If the student is unable to answer one of the exercises ! 501: correctly, the driver searches for a previous lesson ! 502: with a set of alternatives as successors ! 503: (following the ! 504: .I #next ! 505: line). ! 506: From the previous lesson with alternatives one route was taken ! 507: earlier; the program simply tries a different one. ! 508: .PP ! 509: It is perfectly possible ! 510: to write sophisticated scripts that evaluate ! 511: the student's speed of response, or try to estimate the ! 512: elegance of the answer, or provide detailed ! 513: analysis of wrong answers. ! 514: Lesson writing is so tedious already, however, that most ! 515: of these abilities are likely to go unused. ! 516: .PP ! 517: The driver program depends heavily on features ! 518: of ! 519: .UX ! 520: that are not available on many other operating systems. ! 521: These include ! 522: the ease of manipulating files and directories, ! 523: file redirection, ! 524: the ability to use the command interpreter ! 525: as just another program (even in a pipeline), ! 526: command status testing and branching, ! 527: the ability to catch signals like interrupts, ! 528: and of course ! 529: the pipeline mechanism itself. ! 530: Although some parts of ! 531: .ul ! 532: learn ! 533: might be transferable to other systems, ! 534: some generality will probably be lost. ! 535: .PP ! 536: A bit of history: ! 537: The first version of ! 538: .I learn ! 539: had fewer built-in words ! 540: in the driver program, ! 541: and made more use of the ! 542: facilities of ! 543: .UX . ! 544: For example, ! 545: file comparison was done by creating a ! 546: .I cmp ! 547: process, ! 548: rather than comparing the two files within ! 549: .I learn . ! 550: Lessons were not stored as text files, ! 551: but as archives. ! 552: There was no concept of the in-line document; ! 553: even ! 554: .I #print ! 555: had to be followed by a file name. ! 556: Thus the initialization for each lesson ! 557: was to extract the archive into the working directory ! 558: (typically 4-8 files), ! 559: then ! 560: .I #print ! 561: the lesson text. ! 562: .PP ! 563: The combination of such things made ! 564: .I learn ! 565: slower. ! 566: The new version is about 4 or 5 times faster. ! 567: Furthermore, it appears even faster to the user ! 568: because in a typical lesson, ! 569: the printing of the message comes first, ! 570: and file setup with ! 571: .I #create ! 572: can be overlapped with the printng, ! 573: so that when the program ! 574: finishes printing, ! 575: it is really ready for the user ! 576: to type at it. ! 577: .PP ! 578: It is also a great advantage to the script maintainer ! 579: that lessons are now just ordinary text files. ! 580: They can be edited without any difficulty, ! 581: and ! 582: .UX ! 583: text manipulation tools can be applied ! 584: to them. ! 585: The result has been that ! 586: there is much less resistance ! 587: to going in and fixing substandard lessons.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.