1. A Modula-2 string is an ARRAY [0..n-1] OF CHAR, zero based, and terminated (usually by the null character).
2. An implied abstract type has its basic structure visible, but can be treated abstractly. Modula-2 allows an array of char to be thought of and used in most cases as an abstract string.
3. (a) E = "dogs chasecats "
(b) m = 5
(c) found = FALSE, position = undefined;
(d) i = less
(e) cogs
(f) str1 = docatsg
(g) found = TRUE, position = 8
(h) found = TRUE, position = 4
4. Silent truncation is the discarding of characters in a string without the user knowing. This arises, for example, when two strings are concatenated and the result does not have enough room for both strings. In the case of Concat, the first string is placed in the result and the second string (whatever can fit), is then placed in the rest of the array.
5. Length returns of the number of characters in the string whereas HIGH returns the highest index used when the actual parameter array is assigned to the open formal parameter array. The latter depends on the string type, not its contents.
6. (a) greater; "r" > "i"
(b) greater; lower case letters have higher ASCII values than upper case letters.
7. An unused (uninitialized) string will contain characters that are in the memory location at that moment. The user will not know what that will be and it will therefore affect the output of the string.
8. See http://searchSecurity.techtarget.com/sDefinition/0,,sid14_gci213893,00.html
9. The mean is the ordinary average. More formally, the mean of a group of data is their sum divided by the number of items in the group.
Variance is the mean of the squares of the differences between data items and the mean.
If the data is a sample, we divide by (n-1) rather then n when calculating variance.
10. The median is the middle observation of an ordered distribution. One needs a facility to find whether the data set size is even or odd and to sort the data.
11. The mode is the value that occurs the most in a data set. One needs a facility to keep track of how many occurrences of each data item there are.
12. Separating low and high level functions makes code easier to debug. All procedures in the modules are small and therefore easy to manage.
13. Random numbers generated from a formula produce the same sequence every time. They are better defined as pseudo-random numbers. To make the numbers more random, a seed can be used and a new seed produced every time a random number is called for.
14. A matrix is a rectangular arrangement of symbols in a two dimensional array. They are used for such tasks as equation solving, expressing tables, representing abstract graphs and as abstractions in and of themselves.
15. A vector is an entity that has magnitude and direction. In computing science, it can be represented as a one-dimensional array. They are used to represent velocities, forces, displacements, and accelerations.
16. The ADT Vectors include the following procedures not in the ADT Points:
PROCEDURE assignP (ABS, ARG: REAL) : Vector;
PROCEDURE add (u, v : Vector) : Vector;
PROCEDURE sub (u, v : Vector) : Vector;
PROCEDURE dotProduct (u, v : Vector) : REAL;
The ADT Points include the following procedures not in the ADT Vectors:
PROCEDURE polarToRect (abs, arg : REAL) : Point;
PROCEDURE reflectX (p: Point) : Point;
PROCEDURE reflectY (p: Point) : Point;
PROCEDURE reflect0 (p: Point) : Point;
PROCEDURE reflect45 (p: Point) : Point;
PROCEDURE rotate (p : Point; rotAngle : REAL) : Point;
PROCEDURE translate (p : Point; deltaX, deltaY : REAL) : Point;
Note: Not all problems are shown. Most problems are left up to students as labs.
(* Translated to ISO standard Modula-2 June 15 1999 Chapter 7 Question 18 NO ERROR TRAPPING *) DEFINITION MODULE StringFunc; TYPE STRING = ARRAY [0..80] OF CHAR; CONST nul = CHR(0); VAR strDone : BOOLEAN; PROCEDURE Insert (VAR str, substr : ARRAY OF CHAR; pos : CARDINAL); (* inserts a string into another string *) PROCEDURE Delete (VAR str : ARRAY OF CHAR; pos, len : CARDINAL); (* deletes n characters from a specifed index from a string *) PROCEDURE ConCat (VAR str1, str2, result : ARRAY OF CHAR); (* concatenates 2 strings and puts it in the variable result *) PROCEDURE Length (str : ARRAY OF CHAR) : CARDINAL; (* returns the length of a string *) END StringFunc. IMPLEMENTATION MODULE StringFunc; PROCEDURE Insert (VAR str, substr : ARRAY OF CHAR; pos : CARDINAL); VAR len, count, subcount : CARDINAL; BEGIN (* see if we have room to fit the entire substring into the string if so then strDone = TRUE and set 'len' to the length of the substring otherwise strDone = FALSE and set 'len' to the max size it can be, that is the HIGH of the string minus the string's length. *) IF Length (str) + Length (substr) <= HIGH (str) THEN strDone := TRUE; len := Length (substr); ELSE strDone := FALSE; len := HIGH (str) - Length (str) END; (* make room within the string to insert the substring *) FOR count := Length (str) TO pos BY -1 DO str [count + len] := str [count] END; (* insert the substring into the string at the position 'pos' *) subcount := 0; (* init the substring counter to 0 *) FOR count := pos TO pos + len DO (* if this character isn't the string terminator then insert it *) IF substr [subcount] # nul THEN str [count] := substr [subcount]; INC (subcount) END END; (* if the new string doesn't fill the string set a null terminator at end *) IF Length (str) <= HIGH (str) THEN str [Length (str)] := nul (* mark end of the new string *) END END Insert; (*-------------------------------------------------------------------------*) PROCEDURE Delete (VAR str : ARRAY OF CHAR; pos, len : CARDINAL); VAR count, count2 : CARDINAL; BEGIN (* if there is something beyond the deleted part of the string move it down, and set strDone to TRUE; otherwise delete the remainder of the string and set strDone to FALSE. *) IF len + pos < Length (str) THEN strDone := TRUE; (* move remainder of the string down to overwrite the deleted part *) count2 := pos; (* init to start of area to delete *) FOR count := pos + len TO Length (str) DO str [count2] := str [count]; INC (count2); END; str [Length (str)] := nul (* mark end of new string *) ELSE strDone := FALSE; str [pos] := nul; END END Delete; (*-------------------------------------------------------------------------*) PROCEDURE ConCat (VAR str1, str2, result : ARRAY OF CHAR); VAR count, count2 : CARDINAL; BEGIN (* initialize variables *) FOR count := 0 TO Length (str1) DO result [count] := str1 [count] (* set result equal to string1 *) END; count2 := 0; (* init string2 counter to 0 *) (* check to see if both strings will fit into the result, if so then set strDone to TRUE, othewise to FALSE. *) IF Length (str1) + Length (str2) <= HIGH (result) THEN strDone := TRUE ELSE strDone := FALSE END; (* insert string2 onto the end of result until you run out of room *) FOR count := Length (result) TO HIGH (result) DO result [count] := str2 [count2]; INC (count2) END; (* put a string terminator at the end of the new string if it isn't full *) IF Length (result) < HIGH (result) THEN result [Length (result)] := nul END END ConCat; PROCEDURE Length (str : ARRAY OF CHAR) : CARDINAL; VAR count : CARDINAL; BEGIN count := 0; (* init count (* number of characters in string *) to 0 *) (* check to see if there is anything in the string *) IF str [count] # nul THEN strDone := TRUE; (* if yes then set strDone to TRUE, find its length *) (* loop through the string to the end of it *) REPEAT INC (count) UNTIL (count > HIGH (str)) OR (str [count] = nul) ELSE strDone := FALSE (* if not then set strDone to TRUE and return 0 *) END; RETURN count END Length; (*=========================================================================*) (* BEGIN strDone := TRUE; (* init to TRUE so that it is initialized before a *) (* procedure from StringFunc is called *) *) END StringFunc. MODULE StringTest; FROM STextIO IMPORT WriteLn, WriteString, ReadChar, ReadString, SkipLine; FROM SWholeIO IMPORT WriteCard, ReadCard; FROM StringFunc IMPORT STRING, Insert, Delete, ConCat, Length; (*=========================================================================*) VAR str1, str2, str3 : STRING; len, pos : CARDINAL; ch : CHAR; (*=========================================================================*) BEGIN (* Main Body *) (* Start up *) REPEAT (* Introduction *) WriteLn; WriteString ("This little program tests the String module that we just"); WriteString ("created."); WriteLn; WriteLn; (* Calculations *) (* Insertion *) WriteString ("Enter a string please ==> "); ReadString (str1); SkipLine; WriteLn; WriteLn; WriteString (" Insertion"); WriteLn; WriteString ("Enter a string to insert into the previous ==> "); ReadString (str2); SkipLine; WriteLn; WriteString ("At what position do you want it inserted ==> "); ReadCard (pos); SkipLine; WriteLn; WriteLn; Insert (str1, str2, pos); WriteString (str1); WriteLn; WriteLn; (* Deletion *) WriteString (" Deletion"); WriteLn; WriteString ("Where do you want to start deleting from the first string "); WriteString ("==> "); ReadCard (pos); SkipLine; WriteLn; WriteString ("How much do you want to delete ==> "); ReadCard (len); SkipLine; WriteLn; WriteLn; Delete (str1, pos, len); WriteString (str1); WriteLn; WriteLn; (* ConCatination *) WriteString (" Concatination"); WriteLn; WriteString ("What do you want to add to the first string ==> "); ReadString (str2); SkipLine; WriteLn; WriteLn; ConCat (str1, str2, str3); WriteString (str3); WriteLn; WriteLn; (* Length *) WriteString (" Length "); WriteLn; len := Length (str1); WriteString ("The length of the first string was "); WriteCard (len,0); (* Conclusion *) WriteLn; WriteLn; WriteString("Press 'Q' to quit, any other key to continue. "); ReadChar (ch); UNTIL CAP (ch) = 'Q'; WriteLn; END StringTest.
(* Translated to ISO standard Modula-2 June.15.1999 Chpater 7 Question 20 NO ERROR TRAPPING MODIFICATIONS: Created a pascal string type (str255) Created a procedure to write the pascal string type since there was no library for the original created. Added a WriteCard to show the lenght of the string *) MODULE ModToPas; FROM STextIO IMPORT WriteLn, WriteChar, WriteString, ReadString, ReadChar, SkipLine; FROM SWholeIO IMPORT WriteCard; TYPE Str255 = ARRAY [0..255] OF CHAR; VAR ModStr : ARRAY [0..80] OF CHAR; PasStr : Str255; ch : CHAR; (* <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> *) PROCEDURE StrModToPas (VAR source : ARRAY OF CHAR; VAR result : Str255); VAR count : CARDINAL; BEGIN count := 0; (* initialize *) (* loop through until the end of the source is reached *) WHILE (source[count] # 0C) AND (count < HIGH (source)) DO result[count + 1] := source[count]; INC (count) END; (* while *) result[0] := CHR (count) (* length of source read into result *) END StrModToPas; PROCEDURE WritePascal (str : ARRAY OF CHAR); (* pre: str has to be a pascal string already. post: writes out the pascal string without str[0] *) VAR count : CARDINAL; BEGIN count := 1; WHILE (count < 255) OR (str[count] # 0C) DO WriteChar (str[count]); INC (count); END; END WritePascal; (* <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> *) (* main program *) BEGIN WriteString ('We will be testing the conversion from Modula-2 strings to'); WriteString (' Pascal strings'); WriteLn; WriteLn; WriteLn; WriteString ('Please input a Modula-2 string now.'); WriteLn; ReadString (ModStr); SkipLine; WriteLn; WriteLn; WriteLn; StrModToPas (ModStr, PasStr); (* convert *) WriteString ("The pascal string seen as M2 string:"); WriteLn; WriteString (PasStr); WriteLn; WriteString ('The Pascal string is:'); WriteLn; WritePascal (PasStr); WriteLn; (* this line added to show the length in the first element of the array--ry *) WriteString ("String length PasStr[0]: "); WriteLn; WriteCard (ORD(PasStr[0]), 1); WriteLn; WriteLn; WriteLn; WriteString ('Press any key to return to the desktop.'); ReadChar (ch); SkipLine; END ModToPas.