This following document offers a step-by-step approach, complete with handouts, explanations and programs, for teaching the topics of sequential files, arrays and records in Turing. A concerted effort has been made to develop these topics so that one topic logically progresses to the next. If you choose to make use of this resource for teaching or learning these topics, maintaining the sequence would be advisable. If you choose to utilize only selected handouts then you may have to make minor alterations as they may refer a previous topic.
The philosophy behind this sequential approach originates in a strong belief that students, like all of us, are most receptive to learning and then applying this knowledge, when they are presented with solid reasons for doing so. In short, they must see the benefit derived in putting the required effort into the learning. This document, by presenting these units in a step-by-step approach, hopefully is consistent with this end.
Because of the sequential nature of this document, it is necessary to outline what the students should already have been exposed to. Basically, students should be well-versed in the basics of structured programming in Turing. This would constitute familiarity with the following general topics:
The topic of sorting is not adequately handled in this document. Although, the bubble sort is used in the programming examples, no handouts are given to present the topic. After the students have a good working knowledge of arrays and can manipulate them proficiently, it would be timely to then present them with a unit on sorting. In this document the ideal spot to interject a topic on sorting would be after subtopic #2 in the array unit. The remainder of this document can then be tackled. Depending on the sorting algorithm you choose to accentuate, the sorting procedures may have to be altered. As mentioned, for simplicity's sake, the programs make use of the bubble sort.
I have also tried to show the connection with records and the more advanced topic, binary files. Depending on the level of programming you wish to cover in this course, you may elect to follow the records unit with the topic of binary files. In that case you may want to modify the last project so that it encompasses both sequential and binary files.
You may also want to consider elaborating on the topic of data types in the array unit by covering subrange types and two-dimenstional arrays or tables. It would certainly depend upon the ability of your students and difficulty level of your course. The keener programmers in your class should be capable of programming at this level.
The main topics, SEQUENTIAL FILES, ARRAYS and RECORDS are presented as three separate units, that is B, C and D, respectivley. They are further divided into subtopics and sometimes sub-sub topics. The title of the subdivisions serves as a description of the topic covered. These three units can serve as handouts to the students. As each topic is covered, explanations are given and illustrative, sample programs are provided.
A listing of the programs is provided. As well, the appendix at the end of this document contains a hardcopy of each program.
| Suggested Time Allotments Per Topic | (Approx 70 Min Periods) |
|---|---|
| File Creation And Reading | 1 |
| File Modification | 2 |
| Assignment Practice | 3 |
| Project | 3 |
| Test | 1 |
| Arrays - Introduction | 2 |
| Array Stuff To Keep In Mind | 1 |
| Related Arrays | 2 |
| Dynamic Arrays | 2 |
| Assignment Practice | 3 |
| Project | 3 |
| Test | 1 |
| Records - Introduction | 1 |
| Sorting Using Arrays Of Records | 2 |
| Assignment Practice | 3 |
| Project | 3 |
| Overall Project | 5 |
| Overall Test | 1 |
About 7 - 8 weeks is required. If you have less time available eliminate the sub-projects. This will lessen the time by about 2 weeks.
There are various grade 11
handouts dealing with sequential files in the Turing Stuff binder
which may expect knowledge of arrays, records and sorting. They provide
excellent alternate assignments and projects. The exercises are:
Sequential files in Turing are text files and as such they can be created in two ways:
1) by using the editor
This method requires you to start a new file, and then simply key in the data. Save the file and your data file is created.
2) by creating a file using the open statement
Below is an example of a Turing program which creates a file. In this example our file is named, "example". Each record consists of three fields. The name is a string, the age is an integer and the income is a real.
% This program creates a sequential file "example".
% The file is composed of the name, age and salary for
% an indeterminate number of people. The highlighted
% sections are the new statements you need to learn when
% creating sequential files in Turing.
var stream, age : int
var income : real
var name : string
open : stream, "example", put
assert stream > 0
loop
put "Please enter the name of your friend or \"stop\" to quit."
get name : *
exit when name = "stop"
put "Enter the age of ", name, "."
get age
put "Enter the income of your friend ", name, ".'"
get income
put : stream, name
put : stream, age
put : stream, income
end loop
close : stream
Explanation of Turing code
open : stream, "example", put
open is a Turing command which creates a connection to a file. It takes three arguments. A connection to the file is assigned via the first argument, the integer variable, stream. If the connection is successful, then stream is assigned a positive integer value. This stream value represents the number of the busline assigned for this connection. If the connection is not successful, a value of zero is assigned to the variable stream. The next argument is the name of the file requiring the connection. In this instance the file is named "example", a constant. A filename can also be in variable form, or can even specify a path and the filename. The third argument is the attribute for opening the file. In this case the attribute is put. This means that the file is to be created. Be careful when using put. If a file already exists with the name "example", this statement will erase what was in memory before.
assert stream > 0
This statement is not necessary for execution. It simply confirms that the open statement was successful. If it was successful, assert returns true and the program continues to execute. If open was unsuccessful, that is, stream has a value of zero, then the program breaks and the error message, "assert condition false", is returned. This is not a very elegant method for checking to ensure that the file opened successfully. Error trapping stream is much more effective. In the initial programs, assert will be satisfactory, but note that a more elegant method will be expected.
put : stream, name
put : stream, age
put : stream, income
These statements send information
to the file "example". The stream argument means that the data is transmitted
to the file via the busline assigned to "example" in the open statement.
Following this argument is the data that is to be sent via the busline
to the file. The data is sent in the sequence stated, that is, a string,
an integer and a real. An example could be:
name as Fred Flintstone;
age as 47 and income as 23234.12.
close : stream
This statement closes the connection to the file "example".
After this program has executed, the file "example" will be in your directory. It will contain all the data that you have entered. Here is a sample of what this file may contain:
Fred Flintstone 47 23234.12 Barney Rubble 46 1123.67 Wilma Flintstone 45 11235.6 Betty Rubble 42 3425.67 Pebbles Flintstone 2 234.5 Bam-Bam Rubble 3 234.5 Mr. Slate 55 100000 Joe Rockhead 49 23412.9 Kazoo 10000 123456.87
You will notice that the data follows the sequence in the program. A name, an age and an income value appear for each record.
The accessing of data from a sequential files must, as the type implies, be "sequential". In order to access the nth piece of data in a file, all previous (n-1) pieces of data must have already been accessed. In the same vein, if an item has already been accessed, the only way to reaccess it would be to close the file, reopen the file and then access all items before the data item which is required and then the item itself.
The analogy of playing a specific song from a tape is useful here. Suppose, your tape cassette, "Freddy Flintstone Sings the Blues", has eight songs on it. To listen to the fifth song, you must have already listened to the prior four songs on the cassette. Unlike this analogy, however, in order to listen to the fifth song on the cassette again, you need only rewind the portion of the tape, to the beginning of the fifth song. When reading sequential files, the only way to reread or reaccess already retrieved data is to close the file, reopen the file for reading and then reread the entire file until you re-encounter the data your wish to review.
% This Turing program retrieves the data from the file
% "example". It retrieves the data into the three
% variables: name, age, and income. In essence these three
% variables make up a complete record.
var stream, age : int
var income :real
var name : string
open : stream, "example", get
assert stream > 0
loop
get : stream, skip
exit when eof(stream)
get : stream, name : *
get : stream, age
get : stream, income
put name:30, age:10, "$",income:0:2
end loop
close : stream
Explanation of Turing code:
open : steam, "example", get
Like the previous explanation for the open statement, we see three arguments. The first is the integer stream. If the open statement is successful, then stream contains a positive integer. If the open statement is not successful, then the value of stream is zero. The second argument is the name of the file. In this case "example" is a constant. Variables and paths can be used as this argument. The last argument is the file attribute. In this case the file is to be opened for reading. The get attribute will allow the program to retrieve the data in the file sequentially.
assert stream > 0
As before, this statement is not necessary for execution. It simply determines whether the open statement was successful. If the open statement was successful, assert returns true and then the program continues. If it was unsuccessful, then the program breaks. As was already mentioned, this is not a very elegant method for checking to ensure open is successful. Error trapping stream is much more effective.
get : stream, skip
This statement skips over the white spaces in the file and sets the reading 'marker' or 'cursor' or 'pointer' to the beginning of the next data item to be read. White spaces in Turing include new line markers, new page markers, and so on. They do not effect the actual text or data that constitutes the file.
exit when eof (stream)
The end of a Turing file is appended by an end of file marker. This marker indicates that there is no more data to be retrieved. The above conditional statement returns true when the end of file marker is found. This indicates that there is no more data to be read from the file "example". The loop is then exited and retrieval of the data from the file stops. If the condition returns false, then the retrieval of name, age and income will continue for yet another record.
get : stream, name : *
get : stream, age
get : stream, income
These statements retrieve data from the file "example". Care is required to ensure that the items are retrieved in the same order as they were created. In this particular program, first a string, then an integer and then a real must be retrieved. The names of the variable are arbitrary. They do not need to be the same as the variables used in the creation program. The order of retrieving the variables, however, is very important. It must match the order used in the creation of the file or you may be unpleasantly surprised by the results.
This program assumes that the file has been created so that each record has three fields. If the file has not been created in this manner, then this approach will cause an end of file error. When you are unsure of the integrity of a file, precede each get of the above get statements with, "get : stream, skip", and "exit when eof(stream)" as demonstrated below.
get : stream, skip
exit when eof (stream)
get : stream, name : *
get : stream, skip
exit when eof (stream)
get : stream, age
get : stream, skip
exit when eof (stream)
get : stream, income
This will ensure that if a record has not been created properly, then the program will not break and give an end of file error.
close : stream
This statement ends the connection to the file "example". It closes the named file.
Once a file has been created there will undoubtedly be occasion to make amendments to its contents. Turing makes allowances for this but the task, though simple, is a bit tedious. Because sequential files are accessed for either creating or reading (put or get) modification requires the creation of a temporary file which assists in the modification. Basically the steps are that the original file is copied into the temporary file and the copy file complete with the desired changes is written back into the original file.
To illustrate file modification, the program below will modify the data in the data file "example" so that each record will be modified. Each person is made one year older and given a raise of $5000.00.
Step One
The original file "example" will be opened with the get attribute, and the file "temp" is opened with the put attribute. This will allow for the contents of "example" to be copied into the file "temp". The result will be two identical files, one called "example" and the copy called "temp". As shown below, if Fred and Barney constitute the two records in "example", then they will also make up the two records in "temp".
| example | temp |
|---|---|
| Fred Flintstone | Fred Flintstone |
| 47 | 47 |
| 23234.12 | 23234.12 |
| Barney Rubble | Barney Rubble |
| 46 | 46 |
| 1123.67 | 1123.67 |
Step Two
Now open "temp" with the get attribute and "example" with the put attribute. Retrieve data from "temp", make the alterations to the data that are required and then rewrite the altered data back into the original file "example". Make each person one year older and give them a raise of 5000 dollars.
| temp | example | |
|---|---|---|
| name | Fred Flintstone | Fred Flintstone |
| age | 47 (+1 to age) | 48 |
| income | 23234.12 (+5000 to income) | 28234.12 |
| name | Barney Rubble | Barney Rubble |
| age | 46 (+1 to age) | 47 |
| income | 1123.67 (+5000 to income) | 6123.67 |
% This program will modify the file "example" so that each
% person is one year older and makes $5000.00
% more than before.
var stream1, stream2, age : int
var income :real
var name : string
open : stream1, "example", get
open : stream2, "temp", put
assert stream1 > 0
assert stream2 > 0
% opens example and makes a copy of all data into temp
% like Step One above
loop
get : stream1, skip
exit when eof (stream1)
get : stream1, name : *
get : stream1, age
get : stream1, income
put : stream2, name
put : stream2, age
put : stream2, income
end loop
close : stream1
close : stream2
% at this point there are two identical files in memory,
% "example" and "temp"
% opens "temp" for reading and rewrites data and changes to
% "example"
% Like Step Two above.
open : stream1, "temp", get
open : stream2, "example", put
assert stream1 > 0
assert stream2 > 0
loop
get : stream1, skip
exit when eof (stream1)
get : stream1, name : *
get : stream1, age
get : stream1, income
put : stream2, name
put : stream2, age+1 % person one year older
put : stream2, income+5000 % raise of $5000.00
end loop
close : stream1
close : stream2
At the end of this program, example will have been modified and "temp" will be a copy of what "example" looked like before the modifications. The user need have no knowledge of "temp" having been used at all. You can use the system commands to delete "temp" from memory if you wish. In this way no record of "temp" is left. Adding the following two lines of code to the program will delete the file "temp". A word of caution, if you run Turing on a secured network environment, this system command may not run because students may not have the access necessary to delete the file.
var success : intThere can be a variety of file modifications necessary. In the file "example", for instance, we may want to do the following:
1)Add records to the file
Add new characters (their name, age and income) to the file "example"
2)Add fields to each record
Give each record more information such as an address, a phone number or a fax number
3)Delete a record from the file
Get rid of one of the characters in the file
4)Delete fields from each record
Since we are in an era of equality of opportunity in the job market, we may want to, for instance, remove the age field as it may be seen as discriminatory
5)Change data within a record
As in the program above, we want to make each person one year older or give them a raise of $5000.
In each of the above cases, there are minor differences in programming code. Essentially, however, a copy must be made of the original file. The copy file along with the desired changes is then re-written into the original file.
This program below will be used to add a record (name, age and income) to the file, "example". This program appends the new record to the end of the file but alterations to the code can put the record at the beginning or between other records, as desired.
% The first step in modifying the program is to make a copy of
% the file "temp". It is an exact duplicate of "example"
proc copy
cls
var age, s1, s2 : int
var name : string
var income : real
open : s1, "example", get
open : s2, "temp", put
loop
get : s1, skip
exit when eof (s1)
get : s1, name : *
get : s1, age
get : s1, income
put : s2, name
put : s2, age
put : s2, income
end loop
close : s1
close : s2
end copy
% This is the second step. The old records found in "temp" are
% first recopied into the file "example". A new record is
% input via the keyboard and then added to the end of the
% modified file "example".
proc addrecord
% Makes a duplicate of the file "example" in "temp"
copy
var age, s1, s2 : int
var name : string
var income : real
open : s1, "temp", get
open : s2, "example", put
loop
% Retrieves one record from "temp"
get : s1, skip
exit when eof (s1)
get : s1, name : *
get : s1, age
get : s1, income
% Rewrites one record into "example"
put : s2, name
put : s2, age
put : s2, income
end loop
% Inputs from the user three fields that constitute the
% new record
put "Enter the name of the friend you want to add"
get name : *
put "Enter the age of your friend ", name, "."
get age
put "Enter the income of your friend ", name, "."
get income
% Appends new record to the end of the file "example"
put : s2, name
put : s2, age
put : s2, income
close : s2
close : s1
put name, " has been added to the file!"
end addrecord
% Main Program
put "This program will add a record to the file \"example\"."
add_record
put "A record has been added to the file \"example\"."
The file "example" will now have one more record then it did before the program was executed. The file "temp" will have the contents of "example" before the new record was inserted.
This program addresses the problem of modifying a record so that additional data may be added to the file. For instance, the address of each of the people in the file may now be necessary. That means that the new data must be entered using the keyboard or read from a file. Each record will now be comprised of four fields (name, age, income and address).
% The first step in modifying is to make a copy of the
% file "temp". It is an exact duplicate of "example".
proc copy
cls
var age, s1, s2 : int
var name : string
var income : real
open : s1, "example", get
open : s2, "temp", put
loop
get : s1, skip
exit when eof (s1)
get : s1, name : *
get : s1, age
get : s1, income
put : s2, name
put : s2, age
put : s2, income
end loop
close : s1
close : s2
end copy
% The second step is to read the current fields for each record
% from the file "temp" and then rewrite this data to the file
% "example". The information for the new field "address" is
% input through the keyboard. The program prompts the user
% for the address of each record and then adds it to the file
% "example". Each record now has four fields.
proc addfield
copy
var age, s1, s2 : int
var name, address : string
var income : real
open : s1, "temp", get
open : s2, "example", put
loop
% retrieves one record from the file "temp"
get : s1, skip
exit when eof (s1)
get : s1, name : *
get : s1, age
get : s1, income
% Prompt to the user to enter the address via the keyboard
put "Enter the address for ", name, "."
get address : *
% Writes three old fields (name, age, income) and then
% the new field (address) to the file "example"
put : s2, name
put : s2, age
put : s2, income
put : s2, address
end loop
close : s2
close : s1
put "The file now has an address field!"
end addfield
% Main Program
put "This program will add an address field to the file \"example\". "
put "Keyboard input is required to add an address for each record."
addfield
put "The file \"example\" now has a new address field added to each "
put "record. The fields are now name, age, income and address."
The above program has altered the file "example" so that it now contains four fields per record: a name, an age, an income and an address. Again, it is important to adhere to this order.
We will now modify the program by deleting a complete record. The record to be deleted must be first inputted by the user. The file is scanned, record by record, until the desired record is identified. This is the record which will not be rewritten into the file. All other records are rewritten.
% The first step in modifying is to make a copy of the
% file "temp". This is true for every case of modification.
% "temp" is an exact duplicate of "example".
proc copy
cls
var age, s1, s2 : int
var name : string
var income : real
open : s1, "example", get
open : s2, "temp", put
loop
get : s1, skip
exit when eof (s1)
get : s1, name : *
get : s1, age
get : s1, income
put : s2, name
put : s2, age
put : s2, income
end loop
close : s1
close : s2
end copy
% This program will search for the record represented by the
% variable key and it will rewrite into "example" every record
% except this key record. If the person isn't found then
% a message is sent to the user to indicate this.
proc deleterecord (key : string)
copy
var age, s1, s2 : int
var name : string
var income : real
var found := false
open : s1, "temp", get
open : s2, "example", put
loop
%retrieves a record from "temp"
get : s1, skip
exit when eof (s1)
get : s1, name : *
get : s1, age
get : s1, income
% if this is the record to be deleted, the boolean is true
if key = name then
found := true
else
% if this is not the record to be deleted, rewrite it into
% the file "example"
put : s2, name
put : s2, age
put : s2, income
end if
end loop
close : s1
close : s2
% give appropriate message to the user
if found then
put key, " has been deleted from the file!"
else
put key, " is not in this file, either view file or try again!"
end if
end deleterecord
% Main Program
var keyfield : string
var reply : string (1)
put "This program will delete a record from the file \"example\"."
put "Enter the complete name of the person whom you wish to delete from the
file."
get keyfield : *
deleterecord (keyfield)
At the end of the execution of this program, the file "example" should have one less record in it than it did before. The file "temp" will contain all the records that were in "example" before the record was deleted. Some error trapping exists. If the record was not in the file, then Turing gives the user this information. If deletion is successful, then the user is likewise informed.
This modification looks at the possibility that some fields in the file will no longer be needed. For instance, with all of the legitimate concern regarding equal opportunity in the job market, it may be necessary to delete the age of each person. This kind of change would require that a field be deleted. Again a similar approach is necessary. A copy of the file is made. All the wanted fields are rewritten into the original file from the copy. The unwanted field is omitted.
The program below allows the user a choice in the fields to be omitted. The field to be omitted is first identified. Again, as in all modifications, a copy of the original file is made. The copy is then used to retrieve the original data. All wanted fields are rewritten into the original file.
% This is the first step in modifying files. A copy of
% "example" is made in "temp"
proc copy
cls
var age, s1, s2 : int
var name : string
var income : real
open : s1, "example", get
open : s2, "temp", put
loop
get : s1, skip
exit when eof (s1)
get : s1, name : *
get : s1, age
get : s1, income
put : s2, name
put : s2, age
put : s2, income
end loop
close : s1
close : s2
end copy
% This procedure receives the field to be deleted from the user.
% The entire record is retrieved from the copy and then the
% desired fields only are rewritten into the original file.
proc deletefield (option : string (1))
copy
var age, s1, s2 : int
var name : string
var income : real
open : s1, "temp", get
open : s2, "example", put
loop
% retrieves a complete record from "temp"
get : s1, skip
exit when eof (s1)
get : s1, name : *
get : s1, age
get : s1, income
% rewrites into the original file, all fields except
% the field to be deleted.
if option = "1" then
put : s2, age
put : s2, income
elsif option = "2" then
put : s2, name
put : s2, income
else
put : s2, name
put : s2, age
end if
end loop
close : s2
close : s1
% give user appropriate message to ensure field has been deleted
if option = "1" then
put "The file no longer has a name field."
elsif option = "2" then
put "The file no longer has an age field."
else
put "The file no longer has an income field."
end if
end deletefield
% Main Program
var choice : string (1)
put "This program will delete a field from the file."
put "The user will choose a field. "
put "Choose the field you wish to alter."
put "Enter 1 to delete the field \"name\"."
put "Enter 2 to delete the field \"age\"."
put "Enter 3 to delete the field \"income\"."
loop
getch (choice)
exit when index ("123", choice) 0
put "Error in input"
put "Valid input is 1 or 2 or 3 only."
end loop
deletefield (choice)
After this program runs the file "example" will contain two fields per record while "temp" contains the original three.
Little Black Book
1. Create a data file llbook which will contain the name, address, phone number, fax number and email address of your friends. Each of the above fields will be a string variable. Make your program user-friendly and use a sentinel to indicate when the user has finished entering data. Insert at least 10 records. Save this program as create.t.
2. Display all the records in your file lbbook in chart form under appropriate headings. Take care to display one screen of data at a time. Use a getch to get from one screen to another. Even if your file is not so long, you only have 10 friends, boo-hoo, your program should still include this feature to prevent names and other data from scrolling off the page. Headings should appear on each screen. Save this program as display.t.
3. Write a program to modify the file lbbook so that you can add or delete one friend at a time. Give the user a menu which includes: adding a friend to the file, deleting a friend from the file, viewing the current file and exiting the program.
Menu
&nbs; *****
1. Add a Record
2. Delete a Record
3. View the File
4. Exit
Error trap the menu choice. In the case of option 2, if the record to be deleted does not exist in the file, give the user a message to this effect. Save as add_del.t.
4. You decide to have two files, llbook and llbook2. The difference is that the later, llbook2 should also contain the birthday of your friends. Create this new file llbook2. Save as create2.t.
5. Create a program which uses a function to return how many friends are in your file llbook. Save as popular.t.
1. Create a program which inputs the name of the file to be accessed. The program should use one function to determine whether or not the file can be opened successfully. It should use another function to determine whether or not the file is empty. Save as filechk.t. This program provides a much more elegant manner to determine if a file has opened successfully. It is much better than using assert.
2. Create a program which gives the user the following options via an error trapped menu.
Menu
*****
1. Create a file
2. Display a file
3. Display a particular record in a file
4. Exit
The first option should input a file name. The choice should be error trapped. Every record would consist of one string, one integer and one real input. Include a fourth field, a real which is the product of the second and third fields. Use any application you wish. An example could be that it is an inventory system which will input the name of the item, how many there are in stock, the cost of this item and the total value of this item in inventory.
The second option should display the contents of the entire file to the screen under appropriate headings. Prompt the user for a filename and error trap this input to ensure that the file exists and contains data. Again, the data should not scroll off the screen. Control this using a getch.
The third option should prompt the user for a filename and again this should be error trapped to ensure the file exists and has data in it. Prompt the user for the name of the item to be viewed. If the item does exist in the file, display it for the user. If the item is not found in the file, give the user an appropriate message.
The fourth option should be the only method to exit the program.
Make your program user-friendly and save as general.t.
Turing Sequential Files
Unit Project
Create a Turing program which will allow the user to create, modify, sort and display files. The program should be modular (make good use of procedures and functions) and it should be menu driven. The program begins with the following error trapped menu choices:
Menu
*****
Expectations and explanation of menu options:
1. Create file - asks for a file name, and then asks for the data in the file. Use a sentinel to indicate that the user is finished inputting data. The file should contain at least four fields with at least one of string, integer and real.
2. Add records to a file - prompts the user for a file name, prompts the user for the number of records to be added to the file and asks for the data. Error trap the file name to ensure the file exists.
3. Delete records - prompts the user for a file name, asks the user for the name of the record to be deleted and then deletes the record. Error trap the file name to ensure the file exists.
4. Modify fields within a record - prompts the user for a file name, displays the file by record and asks the user if she or he wish to change individual fields. If the user wishes to make a change, prompt the user for the new data. Again, the file name should be error trapped to ensure it exists.
5. Display a record in a file - prompts for the file name, and error traps to ensure file exists. Prompt the user for key field of record to be viewed. Display the record for the user. If the record does not exist, give an appropriate message to the user.
6. Display file - prompts for the file name, displays the file under appropriate headings with no scrolling. Use getches to get from screen to screen. Error trap the file name to ensure the file exists.
7. Exit - exits the program.
Once an option other than number 7 is chosen, and the option is executed, refresh the screen with the menu. Ensure appropriate prompting is given to the user.
You should consider including the following procedures and functions in your program. Each of the described options below, if put into a subprogram, would enhance your program and encourage modularity and organization. Carefully consider appropriate parameters.
1. Menu options and error trapping choice
2. Validate file name
3. Create file
4. Display a record from a file
5. Display file
6. Copy one file into another file.
7. Add records
8. Delete records
9. Modify fields
Suggested main program structure
Loop
Show menu, get and error trap choice
If selection is 1 then
Call create
Elsif's
Etc..
End if
End loop
Evaluation Used
Menu
5 4 3 2 1 0
Creation
5 4 3 2 1 0
Adding records
5 4 3 2 1 0
Deleting records
5 4 3 2 1 0
Modifying fields
5 4 3 2 1 0
Displaying record in a file
5 4 3 2 1 0
Displaying file
5 4 3 2 1 0
Exiting
5 4 3 2 1 0
Error trapping file name
5 4 3 2 1 0
Error trapping choices
5 4 3 2 1 0
Total ____________ / 50 = _____ %
PROGRAMMING TEST
SEQUENTIAL FILES
Name ______________________
Answer all questions on the foolscap provided.
Total Marks 40
Part A
Predict the output for each of the following. Use "^" to indicate
a space. (10 marks)
1. (5 marks)
var stream : int
var temp : string := ""
var file : string := "tes.t"
open : stream, file, put
for i : 1 .. length(file)
temp := file(i) + intstr(i)
put : stream, temp
put temp
end for
close : stream
2. (5 marks)
var stream :int
var word1, word2 : string
open : stream, "test", get
loop
get : stream. skip
exit when eof (stream)
get : stream, word1:*
get : stream, word2:*
put word1(1), word1(*), word2(1), word2(*)
end loop
close : stream
The file "test" has the following contents:
I love computers.
Turing has great sequential files.
Living with Turing.
Do you believe this file?
Tests are fun!
I love computers.
Turing has great sequential files.
Living with Turing.
Do you believe this file?
Tests are fun!
Part B
Draw the appropriate flowcharts for each problem listed below. (10
marks, 5 marks each)
1. The number of records in a file should be calculated and output to the screen. The file consists of records with three strings and one integer value.
2. Create a file for an indeterminant number of records. Input a sentinel for stopping the program. The file is called "test". Each record consists of four fields: first name, last name, phone number and address.
Part C
Short answer questions (8 marks)
1. Explain why two files must be opened when modifying one sequential data file. (2 marks)
2. Explain what each of the following statements accomplish in regards
to sequential file management: (4 marks)
a) get : stream , skip
b) exit when eof (stream)
c) open : stream, "original", put
open : stream, "copy", get
d) close : stream
3. Give the statements which would delete a file within a Turing program. The file is named "test.t". ( 2 marks)
Part D
Write a Turing program which will do the following. (12 marks)
Modify a file called "test" which contains an indeterminant amount of records. Each record has three fields: name, age and income. Test should add an "s" to the end of each person's name, make each person one year older and give them each a $1000 raise. In addition, it should add an address field to each record. The user should be prompted for the necessary information for each record. Display the contents of the newly modified "test" to the screen. Do not worry about scrolling or headings for your data.
| Fred Flinstone | Fred Flinstones | |
| 23 | becomes | 24 |
|---|---|---|
| 45000 | 46000 |
| marks | tasks |
|---|---|
| 2 | modify name |
| 2 | modify age |
| 2 | modify income |
| 3 | add field |
| 3 | display to screen |
Part A
1. one mark per line
t1
t1e2
t1e2s3
t1e2s3.4
t1e2s3.4t5
2. one mark per line
I.T.
L.D?
T!I.
T.L.
D?T!
Part B
flowcharts - 2 at 5 marks each
Part C
1. Two files are required because a sequential file can not be opened and read from simultaneously. One temporary file will be a copy of the original. This will serve as the source document during modification. We read from the temporary file and then we rewrite the changes to the newly recreated original file. 2 marks
2.
Part D
var stream1, stream2, age : int
var income : real
var name, address : string
open : stream1, "test", get
open : stream2, "temp", put
loop
get : stream1, skip
exit when eof (stream1)
get : stream1, name:*
get : stream1, age
get : stream1, income
put : stream2, name
put : stream2, age
put : stream2, income
end loop
close : stream1
close : stream2
open : stream1, "temp", get
open : stream2, "test", put
loop
get : stream1, skip
exit when eof (stream1)
get : stream1, name:*
get : stream1, age
get : stream1, income
put : stream2, name + "s"
put : stream2, age + 1
put : stream2, income + 1000
put "please enter the address for : ", name
get address:*
put : stream2, address
end loop
close : stream1
close : stream2
| Name of Program | Description |
|---|---|
| create.t | assignment practice exercise #1 |
| display.t | assignment practice exercise #2 |
| add_del.t | assignment practice exercise #3 |
| create2.t | assignment practice exercise #4 |
| popular.t | assignment practice exercise #5 |
| filechk.t | assignment general exercise #1 |
| general.t | assignment general exercise #2 |
| mainproj.t | main project |
** Note that files with no extension are probably sequential data files such as lbbook, lbbook2, temp, inventory
Presently, every variable that is declared in Turing can contain only one data item at a time. In fact, when another data item is assigned to the variable, the piece of information that the variable previously contained will be replaced by the newly assigned data. This is called destructive input.
var name : string name := "Fred Flintstone put "The name is ", name, "." name := "Barney Rubble" put "The contents of name is ", name, "." name := "George Jetson" put "The contents of name is now ", name, "."
The above code demonstrates the concept of destructive input. The original contents, "Fred Flintstone", gets erased when the new value, "Barney Rubble", is assigned to the variable name. In addition, when the third change is made to the contents of name, both previous contents are gone, and the latest content, "George Jetson", will be the only available content.
Arrays provide a mechanism so that all three contents can be stored under one variable. Destructive input will no longer be the same stumbling block that it once presented to your programs. In arrays, each element or content we want to address is accessed by the name of the variable and the number of the content (subscript) we wish to address.
The need for arrays also becomes apparent when we want to organize data in a specific order, either alphabetical or numerical. Sorting data requires that the items be available in memory simultaneously so that comparisons can be made. Arrays allows this to occur.
Again, it is possible to store more than one data item into one variable by using the data structure called an array. By declaring a variable as an array, we can store as many items as we wish under the same variable name. There will be no destructive input because the item is accessed by variable name and number. This identifies precisely which of the items in that variable list we are referring to.
An array consists of a number of same-typed elements which can be stored and accessed via the variable name and the corresponding subscript.
The following are four sample declarations. In each case 4 items of each type is being declared. The declaration must include the variable name, an integer range and a type.
var names : array 1..4 of string
4 strings accessed as names(1), names(2), names(3), names(4)
var nums : array 0..3 of int
4 integers accessed as nums(0), nums(1), nums(2), nums(3)
var realnums : array 11..14 of real
4 reals accessed by realnums(11), realnums(12), realnums(13), realnums(14)
var status : array 1..4 of boolean
4 booleans accessed by status(1), status(2), status(3), status(4)
Storing or accessing information to or from an array must include assigning to the variable name along with the subscript.
The following program declares an array of 10 integers, randomly generates numbers between 1 and 100 and stores them into the array, displays the numbers in the order in which they were generated, displays the numbers in the reverse order (last to first generated), and then calculates and displays the average of the 10 numbers. Finally it will output the contents of the fifth element in the array.
% declaring the array of 10 integers
var nums : array 1..10 of int
randomize
% randomly generating 10 numbers between 1 and 100 and
% storing them in the array
for i : 1..10
randint (nums (i), 1, 100)
end for
% output the list from the first to tenth element. As i
% increases from 1 to 10, it serves as the subscript to
% identify which array element we want. On the first
% iteration of the counted loop, i has a value of 1 so
% nums(i) is accessing the contents of num(1), etc.
put "The list of numbers between 1 and 100 that has been generated is"
for i : 1..10
put nums(i)
end for
% output the list from the tenth to the first element
% as i decreases from 10 to 1, it serves as the subscript
% for the variable to indicate which element of the array
% needs to be outputted
put "The list of numbers between 1 and 100 in backwards order is "
for decreasing i : 10 ..1
put nums(i)
end for
% output the fifth element from the list
put "The fifth number to be generated was ", nums(5), "."
There are two methods of initializing a complete array. You can use the init command or you can use loops.
i. init
This command is very useful when the size of the array is small.
var nums : array 1..6 of int := init (11,12,13,14,15,16)The above statement initializes the array nums so that nums(1) is 11, nums(2) is 12, nums(3) is 13, nums(4) is 14, nums(5) is 15 and nums(6) is 16.
var animals : array 1..3 of string:=init("piglet","bees","cats")
The above statement initializes animals(1) to "piglet",animals(2) to
"bees" and animals(3) to "cats".
ii. loops
The below statements declare two arrays; names and listnum. The program then initializes the integer elements of listnum to zero and the string elements of names to blank. This could be useful when elements of an array must be used as accumulators. You can see how using init here would be very tedious.
var names : array 1..100 of string var listnum : array 1.. 100 of int for i : 1..100 listnum(i) := 0 names (i) := "" end for
1. Limits for the range must be integer.
2. When the range is given as a variable, the value must be known before the array is declared. The following declaration is not valid because num has no value.
var num : int var list : array 1..num of int
3. Init statements must have a constant range. Turing will give the error message that dynamic arrays can not use init. Both examples are not allowed in Turing.
%example one var num : int get num var list : array 1..num of int := init(2,23,34,23) %example two var num : int := 5 var list : array 1..num of int := init(2,23,34,23)
4. If arrays are being read from a file, then the number of records in the file must be known before the arrays are declared. This means that the file must be opened, read and counted and then the file closed. The array can then be declared. The file is then re-opened, and the data can be read into the array.
This portion of a program assumes the existence of a sequential file called "numbers" which contains an indeterminate number of integers. The file is opened, counted and closed. The array is then declared. The file is re-opened, read into the array and closed.
var count := 0
var stream, num : int
% opens and counts the number of integers in the file
open : stream, "numbers" , get
loop
get : stream, skip
exit when eof(stream)
get : stream, num
count +=1
end loop
close : stream
% declare the array once the number of integers is known
var listnum : array 1..count of int
% reopens file and reads the numbers into the array listnum
open : stream, "numbers", get
for i : 1..count
get : stream, numbers(i)
end loop
close : stream
% output the list of numbers to the screen
put "The original list of numbers."
for i : 1..count
put numbers(i)
end for
Here is another sample program, this time using strings. It asks the user for the number of nonsense words (concatenated upper case letters) that the computer should generate. It then declares the array to store the words, generates, stores and finally displays the silly words in various ways.
var reply : string (1)
var amount, size, letter : int
% determine size of the array
put "How many nonsense words do you want to store in the array?"
get amount
% declare the array
var list : array 1 .. amount of string
% initialize array for concatenation
for i : 1 .. amount
list (i) := ""
end for
% fill array with concatenated letters
for i : 1 .. amount
randint (size, 1, 10)
% generate length for this word
for j : 1 .. size
randint (letter, 65, 90)
% choose ascii for upper case
list (i) := list (i) + chr (letter)
% concatenate letter
end for
end for
put "The silly words are being generated!"
put "press any key to view the silly nonsense"
getch (reply)
cls
% output the silly words to the screen in the order they were
% created
put "The nonsense words in the order generated are"
for i : 1 .. amount
if i mod 23 = 0 then
put "press any key to view the continue viewing nonsense"
getch (reply)
cls
end if
put list (i)
end for
put "press any key to view the nonsense words in reverse order"
getch (reply)
cls
var count := 0
put "The nonsense words in reverse order are:"
% output the silly words to the screen in reverse order
for decreasing i : amount .. 1
count += 1
if count mod 23 = 0 then
put "press any key to view the nonsense words."
getch (reply)
cls
end if
put list (i)
end for
% output the silly words in the middle of the array
put "The middle word(s) in the list."
if count mod 2 = 0 then
put "There are an even numbers of words in the list."
put "There will be two middle words and they are :"
put list (count div 2), " and ", list (count div 2 + 1)
else
put "There are an odd number of words in the list."
put "The middle word is :"
put list (count div 2 + 1)
end if
% output the first and last words in the list
put "The first silly word is ", list(1),"."
put "The last silly word is ", list(count),"."
There are cases where arrays used in a program may be related. Look at the below example of data. Assume this data is stored in a sequential file named "cartoons".
| CHARACTER | TV SHOW | GENDER | ROLE | |
|---|---|---|---|---|
| 1 | Fred Flintstone | The Flintstones | male | lead |
| 2 | Barney Rubble | The Flintstones | male | support |
| 3 | Wilma Flintstone | The Flintstones | female | support |
| 4 | George Jetson | The Jetsons | male | lead |
The following code reads the above data into arrays from the file "cartoons".
var charname, showname, gender, role : array 1..4 of string
var stream : int
open : stream, "cartoons", get
for i : 1..4
get : stream, charname(i):*
get : stream, showname(i):*
get : stream, gender(i):*
get : stream, role(i):*
end for
close : stream
The first element in each of the above arrays refers to data about Fred; the second about Barney; the third about Wilma and the fourth about George. Related arrays, as the arrays above illustrate, are such that that elements in the nth position of each array, will inevitably refer to the same record.
As an example, the following code will ask the user which record they wish to view. It will then show the requested data. The variable name and subscript will address the correct element in each array.
var whichone : int put "Which of the four records do you wish to view?" get whichone put "The information regarding record #",whichone,":" put "" put "Character Name: ",charname(whichone) put "Show Name: ",showname(whichone) put "Gender: ",gender(whichone) put "Role Description: ",role(whichone)
The sequential data file "students" contains the following data:
5 test marks (what the each of 5 tests is marked out of) student name student's 5 marks in the above tests next student name next student's 5 marks, etc.
This program reads the student data into related arrays and then calculates the weighted and evenly weighted averages for each student. The two averages are compared and the better of the two is assigned to the student.
function recnum : int
var count := 0
var stream, dumnum : int
var dumname : string
% open file
open : stream, "students", get
% skip over 5 test marks
for i : 1..5
get : stream , dumnum
end for
loop
get : stream, skip
exit when eof (stream)
% input name of student
get : stream, dumname:*
% input 5 student marks
for i : 1..5
get : stream , dumnum
end for
% increment number of records by one
count += 1
end loop
close : stream
result count
end recnum
var num, stream, count : int
% counts the number of records in file
count := recnum
var reply : string (1)
var t1, t2, t3, t4, t5, totoftests, stream : int
% declare arrays
var student : array 1 .. num of string
var m1, m2, m3, m4, m5 : array 1 .. num of int
var evenlyweighted, weighted, assigned : array 1 .. num of real
% re-open file
open : stream, "students", get
% input 5 test marks
get : stream, t1
get : stream, t2
get : stream, t3
get : stream, t4
get : stream, t5
totoftests := t1 + t2 + t3 + t4 + t5
% input student names and marks into arrays
for i : 1.. num
get : stream, student(i):*
get : stream, m1(i)
get : stream, m2(i)
get : stream, m3(i)
get : stream, m4(i)
get : stream, m5(i)
end for
close : stream
% calculating two averages and store in arrays
for i : 1 .. num
weighted (i) := (m1 (i) + m2 (i) + m3 (i) + m4 (i) + m5 (i)) /totoftests
* 100
evenlyweighted (i) := (m1 (i) / t1 + m2 (i) / t2 + m3 (i)/t3 + m4 (i)/
t4 + m5 (i) / t5) / 5 * 100
% assign better average of the two and store into array
if weighted (i) > evenlyweighted (i) then
assigned (i) := weighted (i)
else
assigned (i) := evenlyweighted (i)
end if
end for
cls
% display student name, marks, and three averages in chart form
put "student name" : 20,
"m1 m2 m3 m4 m5 weighted evenly weighted assigned"
put "_________________", t1, "___", t2, "___", t3, "___", t4, "___", t5,
"_______________________________________"
put ""
for i : 1 .. num
if i mod 20 = 0 then
put "Press any key to continue"
getch (reply)
cls
put "student name" : 20, "m1 m2 m3 m4 m5 weighted evenly weighted assigned"
put "_________________", t1, "___", t2, "___", t3, "___", t4, "___", t5, "_______________________________________"
put ""
end if
put student (i) : 14, m1 (i) : 5, m2 (i) : 5, m3 (i) : 5, m4 (i) : 5, m5
(i) : 5, weighted (i) : 10 : 2, evenlyweighted (i) : 15 : 2,
assigned (i) : 11 : 2
end for
In the above program you will note that from the point in the program where arrays are declared we did not make use of subprograms. It would have been much more efficient to have a procedure to read the data into arrays and then to display the data but that would require that the arrays be used as parameters. The problem this presents is that until the program actually runs, the numbers of students in the file is unknown. This prevents the declaring of the arrays as parameters in the header of the subprograms because we do not know what the range is to be. Dynamic arrays are the solution to this predicament. We can declare the parameters with an "*" for the upper range as long as the actual size of the dynamic array is known by the time the procedure or function is called.
** Note ** It is not the purpose of this unit to present a package on sorting. I will assume that the students will be taught various sorting techniques. For simplicity, I will use bubble sort. The program listed below makes effective use of dynamic arrays.
% counts the records in the file
function countrec (file : string) : int
var stream , x : int
var howmany := 0
open : stream, file, get
loop
get : stream, skip
exit when eof (stream)
get : stream, x : *
howmany := howmany + 1
end loop
close : stream
result howmany
end countrec
% reads into the dynamic array, "numbers", "num" integers from
% the sequential file "file". Note "numbers" must be a
% variable parameter as its value is changed in proc readlist
procedure readlist (var numbers : array 1 .. * of int, num : int, file :string)
var stream : int
open : stream, file, get
for i : 1 .. num
get : stream, numbers (i) : *
end for
close : stream
end readlist
% outputs the numbers in the dynamic array to screen. Note that
% numbers is a value parameter
procedure output (numbers : array 1 .. * of string, x : int)
for i : 1 .. x
put numbers (i), " "
end for
end output
% sorts the data in the array numbers in ascending order
% Note that the array is a variable parameter because the
% swapping will cause the array to be changed in the proc
proc pause
var reply : string(1)
put "Press any key to continue"
getch(reply)
cls
end pause
% the bubble sort on the array numbers. Note the necessity for
% variable parametes as sorting will change the array
procedure sortlist (var numbers : array 1 .. * of string, num: int)
for i : 1 .. num -1
for j : 1 .. num -i
if numbers (j) < numbers (j + 1) then
var temp := numbers (j)
numbers (j) := numbers (j + 1)
numbers (j + 1) := temp
end if
end for
end for
end sortlist
% main program
var filename : string
put "please enter a filename"
get filename
% counts the numbers to determine size of the array
var count := countrec (filename)
% declares the array "list"
var list : array 1 .. count of string
% reads the numbers into the dynamic array "list"
readlist (list, count, filename)
pause
% outputs the dynamic array "list" in the order inputted
put "The original list is "
output (list, count)
pause
% sorts the dynamic array "list"
sortlist (list, count)
pause
% outputs the dynamic array "list" in sorted order
put "The original list is "
output (list, count)
Remember the file "lbbook" which represented your sequential file of friends? The fields were: name of friend, address, fax number, phone number and email address. This program will illustrate how to read this file into the 5 required related dynamic arrays and how to sort them according to the name fields.
Look over the code for this program and note the following:
a) how the arrays are sent as parameters - either variable (reading
and sorting) or value (displaying),
b) how the arrays whether they be value or variable parameters, are
nonetheless dynamic, and
c) how many lines of swapping are required for sorting. As one of the
related fields is swapped so must all the other fields. For example suppose
the following represented two records in your file:
Fred Flintstone 23 Rocky Road 123-4567 123@tvland.com 678-3456 Barney Rubble 26 Rocky Road 765-4321 321@7654.ca 234-7890
When the names of Fred and Barney are compared, Barney will be swapped with Fred. If we stop here then the other related fields will be with the wrong person. Fred's address, phone, fax and email will be Barney's and vise versa. It is therefore necessary to swap all related fields. Whew!! A sorted array of the positions of records would help this but there is a better way, record structures. We will soon deal with that topic! For now, use cut and paste!!
proc menu (var opt : string (1))
put " MENU"
put " ****"
put " 1. READ A FILE "
put " 2. SORT A FILE "
put " 3. VIEW A FILE"
put " 4. EXIT"
loop
put "Make a selection 1-4 from above"
getch (opt)
exit when index ("1 2 3 4", opt) > 0
put "Error in input, try again please!"
end loop
end menu
% counts the number of records in the file to determine the size
% of the arrays
function recnum : int
var count := 0
var stream : int
var dummy : string
open : stream, "lbbook", get
loop
get : stream, skip
exit when eof (stream)
count+=1
for i : 1 .. 5
get : stream, dummy : *
end for
end loop
close : stream
result count
end recnum
% sorts the data in the dynamic arrays according to name
% note the use of variable parameters. Bubble sort is used.
proc sortfile (var name, address, phone, fax, email : array 1..*
of string, n : int)
var temp : string
for i : 1 .. n
for j : 1 .. n -i
% does this record need to be swapped?
if name (j) > name (j + 1) then
% swap the elements in name
temp := name (j)
name (j) := name (j + 1)
name (j + 1) := temp
% swap all related arrays, 3 lines per item
temp := address (j)
address (j) := address (j + 1)
address (j + 1) := temp
temp := phone (j)
phone (j) := phone (j + 1)
phone (j + 1) := temp
temp := fax (j)
fax (j) := fax (j + 1)
fax (j + 1) := temp
temp := email (j)
email (j) := email (j + 1)
email (j + 1) := temp
end if
end for
end for
end sortfile
% display the dynamic arrays. Note they are value parameters.
proc viewfile (name, address, phone, fax, email : array 1..* of string, n : int)
var stream : int
var reply : string (1)
put "NAME ADDRESS PHONE FAX EMAIL"
for count : 1 .. n
if count mod 20 = 0 then
put "Press any key to continue"
getch (reply)
cls
put "NAME ADDRESS PHONE FAX EMAIL"
end if
put name (count) : 14, address (count) : 21, phone (count) : 10, fax
(count) : 10, email (count)
end for
end viewfile
% Read the data into dynamic arrays. Note the necessity for
% variable parameters
proc readfile (var name, address, phone, fax, email : array 1 .. * of
string, n : int)
var stream : int
open : stream, "lbbook", get
for i : 1 .. n
get : stream, name (i) : *
get : stream, address (i) : *
get : stream, phone (i) : *
get : stream, fax (i) : *
get : stream, email (i) : *
end for
close : stream
end readfile
% Main Program
var choice, stall : string (1)
var num := recnum
var names, address, phone, fax, email : array 1 .. num of string
loop
menu (choice)
put ""
put "Press any key to continue"
getch (stall)
cls
if choice = "1" then
% silly option to read a file, just to show how to do it
readfile (names, address, phone, fax, email, num)
put "The file has been read!"
elsif choice = "2" then
% option to sort files. Readfile is included to ensure
% that the file is opened and read into arrays. As
% well, viewfile is called to display the sorted arrays
readfile (names, address, phone, fax, email, num)
sortfile (names, address, phone, fax, email, num)
put "This is the sorted file"
viewfile (names, address, phone, fax, email, num)
elsif choice = "3" then
% option to view the file. Readfile is included to
% ensure that the file is opened and read into arrays.
readfile (names, address, phone, fax, email, num)
viewfile (names, address, phone, fax, email, num)
else
exit
end if
put "Press any key to continue"
getch (stall)
cls
end loop
Use the array structure to write the following Turing programs.
1. Create a program which prompts the user for a student's name and their mark in a test which is marked out of 67. Use a sentinel to determine the end of input. Output the marks in chart form (Name and Mark) in the order input as a percent. Sort the data in descending order according to marks and redisplay the sorted list in chart form. Save as array#1.t.
2. Write a program which inputs a number of names in any order. Use a sentinel to stop user input. Ouput to the screen the names in alphabetical order so that there are no duplicate names output. At the end of the program output the names of the duplicates. Save as array#2.t.
3. Prompt the user for the number of integers they want to generate. Randomly generate the numbers, sort them in ascending order and then output the median. If the amount of numbers in the array is odd, there is a single median value. If the amount of numbers in the array is even, there are two median values. When there is an even amount of numbers, output the average of these two numbers. Save as array#3.t. The following is an example of the handling of an odd and even amount of numbers:
List : 2, 6, 7, 9, 10 (5 numbers - odd)
Median : 7
List : 5, 6, 7, 8, 9, 10 (6 numbers - even)
Median: 7.5 from (7+8)/2
4. Randomly generate 20 integers between the range 1 and 1000. Sort the numbers and then output for each number the following in chart form under appropriate headings:
| Number | Square Root | Square | Cube |
| 9 | 3 | 81 | 729 |
5. Input text from the user until a sentinel indicates end of input. After the user indicates that there is no more input, clear the screen and redisplay the input so that the originial word is in one column, vowels are in another column and consonants are in the last column. Save as array#5.t.
PROJECT
ARRAYS
There are two questions in this assignment. You should not only concentrate on completing the task so that the required output is created, but take care to program with efficiency and modularity in mind. Remember that this unit has its emphasis on arrays and that these programs are best handled using arrays effectively.
Problem #1
Old MacDonald
Initialize two arrays, animals and sounds, so that they contain the animals and their corresponding sounds, as can be heard on "Old MacDonald's Farm".
| Animals | Sounds |
|---|---|
| pig | oink |
| horse | neigh |
| dog | bow |
| etc. |
Output the song, "Old MacDonald Had A Farm", to the screen in the following way:
1. Once verse at a time, with a getch between verses.
2. The animals and sounds should be preceded by the appropriate "a" or "an", as required. This will change the initialization lines of the arrays so make sure you do not assume, as in the list above, that only "oink" will require "an".
3. Take care to prevent scolling of the song on the screen. You should provide for a verse possibly taking up more than one screen of output. If more than one screen is required, use a getch so the user can proceed when ready.
4. Output for the above would look like:
Old MacDonald Had A Farm - verse #1 ************************ Old MacDonald had a farm, e-i-e-i-o And on the farm he had a pig, e-i-e-i-o With an oink-oink here, and an oink-oink there Here an oink, there an oink, everywhere an oink-oink Old MacDonald had a farm, e-e-i-o. (getch) Old MacDonald Had A Farm - verse #2 ************************ Old MacDonald had a farm, e-i-e-i-o And on the farm he had a horse, e-i-e-i-o With a neigh-neigh here, and a neigh-neigh there Here a neigh, there a neigh, everywhere a neigh-neigh With an oink-oink here, and an oink-oink there Here an oink, there an oink, everywhere an oink-oink Old MacDonald had a farm, e-e-i-o. (getch) Old MacDonald Had A Farm - verse #3 ************************ Old MacDonald had a farm, e-i-e-i-o And on the farm he had a dog, e-i-e-i-o With a bow-bow here, and a bow-bow there Here a bow, there a bow, everywhere a bow-bow With a neigh-neigh here, and a neigh-neigh there Here a neigh, there a neigh, everywhere a neigh-neigh With an oink-oink here, and an oink-oink there Here an oink, there an oink, everywhere an oink-oink Old MacDonald had a farm, e-e-i-o.
Save as oldmac.t.
Problem #2
Ask the user for the number of numbers you want to generate. Error trap
this number to ensure that it is an integer value. Generate the numbers
and then with getches inbetween display the following:
a) the original list with no scrolling
getch
b) the sorted list
getch
c) the mean, median and mode
Mean - average of the numbers
Median - middle value in the sorted list of numbers. If the list has an odd number of elements, the median is only one value. For example in a list of 15 numbers, the eighth element is the median. When the list has an even number of numbers, display the average of the two middle numbers. For example in a list of 10 numbers the median would be the average of the fifth and sixth numbers.
Mode - displays the number or numbers which occur most often. View the following example lists and their mode(s).
| List | Mode(s) |
|---|---|
| 1,2,2,3,4,5,6 | 2 |
| 13,13,20,20,25,25,25,26,26,26 | 25,26 |
| 1,2,3,4,5,6 | 1,2,3,4,5,6 |
There is no need to repeat the program after one execution. Save as mmm.t.
Evaluation Scheme
Name ______________________
total mark ( _____ / 70 = _____ % )
Old MacDonald ( ____ / 30)
a and an handling
5 4 3 2 1 0
correct output
10 9 8 7 6 5 4 3 2 1 0
scrolling control and other getches
5 4 3 2 1 0
efficiency of array usage
10 9 8 7 6 5 4 3 2 1 0
Mean, Median, Mode ( ____ / 40)
input # of numbers and error trap
5 4 3 2 1 0
display original list - no scrolling and getch
4 3 2 1 0
sort list
4 3 2 1 0
display sorted list - no scrolling and getch
4 3 2 1 0
calculating and displaying mean
5 4 3 2 1 0
calculating and displaying median
8 7 6 5 4 3 2 1 0
calculating and displaying mode(s)
10 9 8 7 6 5 4 3 2 1 0
_____ /50 marks = __________ %
NAME ________________
Part A Predict the output for each of the statements. Show the output
in the space provided and mark all spaces with a " ^ ".
(10 marks)
1. 3 marks
var x : array 1..6 of string
x(1) := "1"
for i : 2 .. 6
x(i):= intstr(i)+x(i-1)
end for
for i : 1 .. 3
put x(i)," ",x(i+3)
end for
2. 4 marks
var name : array 1 .. 4 of string:=init ("Flintstone, F.",
Flintstone, W.","Rubble, B.", "Rubble, B.")
for i : 1..3
for j : 1..4-i
if name(j)>name(j+1) then
var temp:=name(j)
name(j):=name(j+1)
name(j+1):=temp
end if
end for
end for
for i : 1..4
put name(i)(1..index(name(i),",")
end for
3. 3 marks
var nums : array 1 .. 10 := init (1,2,2,3,4,5,6,7,8,10) var ten:=10 put "Median: ",(nums(ten div 2) + nums(ten div 2 + 1))/2 put "Median: ",nums((ten div 2) + (ten div 2 ))/2 put "Median: ",nums(ten div 2 +1) + (ten div 2)
Part B Draw flowcharts for each of the problems outlined below. (10 marks, 5 marks each)
1. Prompt the user the number of integers that a user would like to be generated and then output the original list and output the number in the middle of the list.
2. Prompt the user for 10 first and last names. Concatenate each first and last name into one variable as illustrated below and then store it into one array element. Here is an example:
Part C (30 marks)
1. Write a Turing program that would do the following.
a) Read a file named "dst", which would have an indeterminant number
of records. This means that you must count the number of records first.
The file is to be stored or read into related arrays. The fields for each
record are:
first name of the student - string
last name of the student - string
3 marks for first 3 tests - real ( out of 100 )
3 marks for first 3 projects - real ( out of 100 )
b) Calculate the final average mark for each student in this manner. The three tests constitute 70% of the overall mark and the 3 projects make up 30%. Store this calculation in an array. Sort according to descending order. Output the student's first and last names, the test component out of 70%, the project component out of 30% and the overall average to the screen in chart form. You do not need to worry about lining up the chart headings with their corresponding data but you must make sure to display one full screen at a time. Do not allow the data to scroll past the user. (And you thought I didn't have a heart!)
mark allocation (30)
| opening file & counting records | (4) |
| declaration of arrays | (4) |
| inputting data into array | (4) |
| calculating test component | (3) |
| calculating project component | (3) |
| storing averages into array | (3) |
| sorting data | (5) |
| output to screen | (4) |
Part A -10 marks
predicting output -one mark per line
1.
1^654321 21^7654321 321^87654321
2.
Rubble, Rubble, Flintstone, Flintstone,
3.
Median:^4.5 Median:^5 Median:^10
Part B -10 marks
flowcharts -5 marks each
Part C - 30 marks
fcn count : int
var tot := 0
var stream : int
var dummy : string
open : stream, "dst", get
loop
get : stream, skip
exit when eof (stream)
for i : 1 .. 8
get : stream, dummy : *
end for
tot += 1
end loop
close : stream
result tot
end count
proc readarray (var a, b : array 1 .. * of string, var t1, t2, t3, p1,
p2,p3 : array 1 .. * of int, var ta, pa, av : array 1 .. * of real, num: int)
var stream : int
open : stream, "dst", get
for i : 1 .. num
get : stream, a (i) : *
get : stream, b (i) : *
get : stream, t1 (i)
get : stream, t2 (i)
get : stream, t3 (i)
get : stream, p1 (i)
get : stream, p2 (i)
get : stream, p3 (i)
ta (i) := (t1 (i) + t2 (i) + t3 (i)) / 300 * 70
pa (i) := (p1 (i) + p2 (i) + p3 (i)) / 300 * 30
av (i) := ta (i) + pa (i)
end for
close : stream
end readarray
proc sort (var a, b : array 1 .. * of string, var t1, t2, t3, p1, p2,p3
: array 1 .. * of int, var ta, pa, av : array 1 .. * of real, num : int)
for i : 1 .. num -1
for j : 1 .. num -i
if av (j) < av (j + 1) then
var temp := av (j)
av (j) := av (j + 1)
av (j + 1) := temp
temp := pa (j)
pa (j) := pa (j + 1)
pa (j + 1) := temp
temp := ta (j)
ta (j) := ta (j + 1)
ta (j + 1) := temp
var temp2 := t1 (j)
t1 (j) := t1 (j + 1)
t1 (j + 1) := temp2
temp2 := t2 (j)
t2 (j) := t2 (j + 1)
t2 (j + 1) := temp2
temp2 := t3 (j)
t3 (j) := t3 (j + 1)
t3 (j + 1) := temp2
temp2 := p1 (j)
p1 (j) := p1 (j + 1)
p1 (j + 1) := temp2
temp2 := p2 (j)
p2 (j) := p2 (j + 1)
p2 (j + 1) := temp2
temp2 := p3 (j)
p3 (j) := p3 (j + 1)
p3 (j + 1) := temp2
var temp3 := a (j)
a (j) := a (j + 1)
a (j + 1) := temp3
temp3 := b (j)
b (j) := b (j + 1)
b (j + 1) := temp3
end if
end for
end for
end sort
proc display (a, b : array 1 .. * of string, c, d, e : array 1 .. * of real, num : int)
cls
put ""
put"First Name Last Name tests(70%) projects(30%) total(100%)"
for i : 1 .. num
if i mod 20 = 0 then
var reply : string (1)
put "Press any key to continue"
getch (reply)
cls
put "First Name Last Name tests(70%) projects(30%) total(100%)"
end if
put a (i) : 15, b (i) : 15, c (i) : 10 : 2, d (i) : 17 : 2, e (i) :
12 : 2
end for
end display
% program main
var numrec := count
put count
var first, last : array 1 .. count of string
var t1, t2, t3, p1, p2, p3 : array 1 .. count of int
var t, p, a : array 1 .. count of real
readarray (first, last, t1, t2, t3, p1, p2, p3, t, p, a, count)
sort (first, last, t1, t2, t3, p1, p2, p3, t, p, a, count)
display (first, last, t, p, a, count)
| program | description |
|---|---|
| arr_test.t | test question |
| array#1.t | assignment question #1 |
| array#2.t | assignment question #2 |
| array#3.t | assignment question #3 |
| array#4.t | assignment question #4 |
| array#5.t | assignment question #5 |
| oldmac.t | suggested project question #1 |
| mmm.t | suggested project question #2 |
| marks.t | illustrate related lists and sorting |
| cartoon.t | illustrate related lists and sorting |
NOTE *** Any Turing files with no extension are sequential files such as animate, dst and students.
One of the best reasons to use records is that records group related arrays into one data structure. In the file that we have been using "lbbook" which contains the name, address, phone, fax and email of all your friends, related arrays were declared. Recall that in related arrays the nth element in each separate related array refers to information about the same record or in this case, the same friend. When we were sorting the arrays, we were required to swap each array to prevent the corruption of our data. Remember the example where Fred gets swapped with Barney in the array "name". We had to ensure that all of Fred's data, which were contained in the other four related arrays, were also swapped. This means we were entering 15 lines of code, 3 per item swapped. If records were used, we would just require 3 lines because the record is swapped in its entirety. As well as decreasing the necessary sorting code, records ensure that you do not forget to swap any of the related arrays as they are already a single unit.
There is another terrific reason to use a record structure but it only becomes obvious when you begin using binary files. Binary files write and read a record structure in one fell swoop. This would mean that in the above example, if it were a binary file, one statement would be sufficient to write or read the entire record. More importantly, it allows random access in binary files. You can seek to any given position within the file and access the record of the choice. This is because when a record is read or written to a binary file, it occupies a constant calculatable memory block. This record size can be used to calculate the exact position of any record in the file. This is an advanced topic and it is beyond the scope of this unit. However, the advantage of using record structures in binary files is worth mentioning.
Unfortunately, unlike binary files, sequential files require that the get and put statements access record structures field-by-field. This requires the same care when dealing with records as with related arrays. Keyboard input using get and put must also be addressed by field. The advantages of swapping a record in one step and of having the record logically grouped as one unit is still a substantial advantage that records have over related data fields. This is sufficient reason to implement records.
A record data type is a data type that permits a group of items of possibly different types to be grouped together as a unit and thus be manipulated as a unit.
The following examples will show various record declarations.
% example one
var friend: record name : string address : string phone : string fax : string email : string end record
The above declaration defines the record "friend". This record contains 5 string fields: name, address, phone, fax and email. If one field needs to be addressed, then the format is:
friend.name := "Fred Flintstone"
To output this data to the screen we would use:
put friend.name
% example two
var employee:
record
name : string
address : string
weekhrs : real
rateofpay : real
taxcode : int
full : boolean
end record
The above declaration defines the record "employee" which contains 6 fields of different variable types. They include: name, address, hours worked per week, the rate of pay, a number to reference tax deduction and true or false to determine if they are full or part time workers. A sample initialization for the above record could be:
employee.name := "Fred Flintstone" employee.address := "23 Rocky Road" employee.weekhrs := 40.5 employee.rateofpay := 15.78 employee.taxcode := 4 employee.full := true
A sample piece of code to illustrate manipulating this record would be:
if employee.full then
put employee.name, " is a full time employee."
else
put employee.name, " is a part time employee."
end if
The declarations thus far do not handle the need presented when a program requires the sorting of data. Recall that in order to sort, the data must be in memory simultaneously and this requires data to be stored in arrays. The next set of examples illustrates how to declare arrays of records.
The first step is to use the type statement to create a record type. Once that is completed an array of that type can be declared. Using the same records as illustrated above, we will create the types required and then declare the array for each record type.
% creates the record type friendtype as per above example one type friendtype: record name : string address : string phone : string fax : string email : string end record % declares an array of friendtype var myfriends : array 1..100 of friendtype % creates the record type employeetype as per above example two type employeetype: record name : string address : string weekhrs : real rateofpay : real taxcode : int full : boolean end record % declares an array of employeetype var staff : array 1..50 of employeetype
The program below assumes that a file exists in memory. The fields are: a character name for a cartoon, the network the show is found on, the name of the show that the cartoon character belongs to and the year that the show started on television. The fields are four strings and an integer.
The program below illustrates how this file can be read into an array of records. The record type is "CartoonType". As in all previous cases we must count the number of records in the file before the array can be declared. To count the records we must open the file, and extract each record and increment the counter by one. We then close the connection to the file.
Once the number of records is known, the array of records can be declared. The file is then read into the array of records. Note that in sequential files the retrieval of data must be field-by-field.
The program then displays the data in chart form to the screen. When outputting to the screen, field-by-field retrieval is again the method that must be used.
The program then goes on to sort the array of records according to the name of the cartoon character. This illustrates the significant advantage of having the data in an array of records rather than in many related arrays. The selection is based on a particular field but the swap includes the entire record. The sorted list is then re-output to the screen.
% type declaration for a record type named CartoonType
% it contains 5 fields as listed below
type CartoonType :
record
charname : string
network : string
rating : string
showname : string
startyr : int
end record
procedure pause
var reply : string (1)
locate (23, 1)
put "Press any key to clear the screen and continue."
getch (reply)
cls
end pause
% prompts the user for a filename and ensures it exists
proc getfilename (var file : string)
var stream : int
loop
put "Please enter the name of the cartoon file you wish to access."
get file
open : stream, file, get
exit when stream > 0
put "Sorry this file does not exist, try again"
pause
end loop
end getfilename
% counts the number of records in the file
% note that the retrieval, even if the record structure is used,
% must be field by field in a sequential file
function countrec (file : string) : int
var num := 0
var stream : int
var cartoon : CartoonType
open : stream, file, get
loop
get : stream, skip
exit when eof (stream)
get : stream, cartoon.charname : *
get : stream, cartoon.network : *
get : stream, cartoon.rating : *
get : stream, cartoon.showname : *
get : stream, cartoon.startyr
num += 1
end loop
close : stream
result num
end countrec
% reads the data into the array of records, cartoon. Note
% that the array is a variable parameter and that
% the retrieval in a sequential file is field by field
proc readrecords (file : string, var cartoon : array 1 .. * of CartoonType,
num : int)
var stream : int
open : stream, file, get
for i : 1 .. num
get : stream, cartoon (i).charname : *
get : stream, cartoon (i).network : *
get : stream, cartoon (i).rating : *
get : stream, cartoon (i).showname : *
get : stream, cartoon (i).startyr
end for
close : stream
end readrecords
% Again, get and put must access record structures
% field-by-field. This uses the array of records, cartoon as a
% value parameter
proc view_records (cartoon : array 1 .. * of CartoonType, num : int)
put "CARTOON CHARACTER NETWORK RATING NAME OF SHOW YEAR CREATED"
put ""
for i : 1 .. num
if i mod 20 = 0 then
pause
put "CARTOON CHARACTER NETWORK RATING NAME OF SHOW YEAR CREATED"
put ""
end if
put cartoon (i).charname : 23, cartoon (i).network : 9, cartoon(i).rating :5, cartoon (i).showname : 30, cartoon (i).startyr
end for
end viewrecords
% sorts the array of records cartoon according to the field
% char_name. Note that the record structure comes in handy
% when sorting for the record is swapped in its entirety.
% This makes records worthwhile
proc sortrecords (var cartoon : array 1 .. * of CartoonType, num : int)
for i : 1 .. num -1
for j : 1 .. num -i
if cartoon (j).charname > cartoon (j + 1).charname then
var temp := cartoon (j)
cartoon (j) := cartoon (j + 1)
cartoon (j + 1) := temp
end if
end for
end for
end sortrecords
% Main Program
var file : string
% ask user for legitimate filename
getfilename (file)
% count number of records in the file
var numrecords := countrec (file)
% declare the array of records
var cartoonlist : array 1 .. numrecords of CartoonType
% read records in file into the array of records
readrecords (file, cartoonlist, numrecords)
put "The records as per listed in the file ", file, "."
put ""
% display contents of the array of records in chart form
viewrecords (cartoonlist, numrecords)
pause
% sort the array of record according to cartoon name and
% then display the contents of the sorted array to the screen
sortrecords (cartoonlist, numrecords)
put "The cartoons sorted by ascending first name."
put ""
viewrecords (cartoonlist, numrecords)
Write Turing programs which will do the following:
1. Define a record structure appropriate for collecting data for an
athletic league whether it be CFL, AFL, NHL, NBA etc. It could even be
for a league you find yourself a member of. The record structure should
include data for players in the paricular league you have chosen:
player name
current team
position
salary
age
rating (1 to 10 with 10 is best rating and 1 is the worst)
Write a procedure to read the data from a sequential file named "sports".
Save as record#1.t.
2. Write subprograms for #1 which will enable you to sort the data according to any field the user chooses: player name, current team, position, salary, age or rating. Add to the first program and save as record#2.t.
3. Write the subprograms to display #1 or #2 to the screen under appropriate headings with no scrolling. Add to the second program and save as record#3.t.
4. Modify the program "cartoon.t" which is in this package. Currently there are five fields: the name of the character, the network on which the cartoon is shown, the rating, the name of the cartooon show and the year the cartoon came into existence. Add the search feature to the program. Using either the name of the cartoon character or the nane of the show the character appears, do a search for the particular data. If no match is found, communicate this to the user. Save as record#4.t.
Making use of the record structure, create a program which will do the following.
1. Present the following options to the user via a menu.
Menu
1. Shuffle and Deal Out Cards
If user selects this option, the deck is recreated and shuffled so that
it is ready to be dealt. The deck is then dealt out to the four players.
2. Play the Game
This can only be done if the cards have been dealt. Display the winner
per game and the on-going score for each of the four players. A win is
awarded if the player is the only one with the highest card. If there is
a tie, no one gets the point. At the end of the thirteen hands, a winner
or winners is/are declared. There is no graphics component but some graphics
would certainly enhance the mark.
At the end of a game, re-start the initializing of the deck. The user must again shuffle the deck and deal before the subsequent game is played.
3. Quit
This should be the only way to exit the program.
assign cards to record
10 9 8 7 6 5 4 3 2 1 0
shuffle the dec
10 9 8 7 6 5 4 3 2 1 0
deal the hands
10 9 8 7 6 5 4 3 2 1 0
hand by hand playing and assigning of winner
10 9 8 7 6 5 4 3 2 1 0
overall winner
10 9 8 7 6 5 4 3 2 1 0
ease of play for user
10 9 8 7 6 5 4 3 2 1 0
| program | description |
|---|---|
| record#1.t | assignment exercise #1 |
| record#2.t | assignment exercise #2 |
| record#3.t | assignment exercise #3 |
| record#4.t | assignment exercise #4 |
| cartoon.t | required for amending question #4 |
| rec_proj.t | project question |
Note *** - Turing files without extensions such as animate and sports are sequential files
Program Description
You will be required to create a program for data manipulation. The data that you manipulate will be of your choice. A good suggestion would be that it would be something that appeals to you and that you could make use of. For instance, if you are a collector, perhaps a database to handle your collection would be useful. It will be tedious to work on something that is not of use. Even if you do not have a personal need for this database, creating one for someone else would give a meaningful purpose to your project.
Decide what fields are necessary in your database and create the appropriate record structure for these fields. A menu driven approach would be most suitable.
Your program must allow the user to:
a) Create and modify the database. The modifications must be such that the number of fields in the record structure would not be altered. These other file modifications must be available: adding records, deleting records and modifying existing fields.
If problems arise during the modification process keep the user informed. For example:
b) Search the database by important fields. You decide which fields are important. Ask if you are unsure. For instance, if your database deals with stamp collection, perhaps viewing stamps worth over a given price, viewing the origin country of stamps or the age of stamps would be suitable search options. The user should be informed if the query has failed and when possible given the reason. For example:
c) Display the database by individual record or file (chart form)
d) Sort the database according to important fields. Again the importance of a field is up to your discretion.
e) Provide adequate error trapping. Take precaution will all interaction to ensure that the input does not crash your program or create unsuspected results.
Evaluation of Collection Project
TOTAL MARKS _____ / 100
Name_________________________
appropriateness of plan and design of database
10 9 8 7 6 5 4 3 2 1 0
error trapping
10 9 8 7 6 5 4 3 2 1 0
modularity and efficiency in program structure
20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
creation and updating of database
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
searching database by important fields
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
sorting database by important fields
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
displaying file and individual records
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
total marks ______ / = _____ %
NAME ________________________________
Place answers on the foolscap provided.
PART A Predict the output for each of the following Turing programs. Use "^" to indicate a space. 16 MARKS - 1 each line
1.
% assume keyboard input is "p", then "y", then "y"
var cartoon :
record
sing, dance, act : boolean
salary : real
end record
var ans : string (1)
var sum := 0
put "Can you sing?(y/n)"
getch (ans)
put ""
if ans = "y" then
cartoon.sing := true
sum += 1
else
cartoon.sing := false
end if
put "Can you dance?(y/n)"
getch (ans)
put ""
if ans = "y" then
cartoon.dance := true
sum += 1
else
cartoon.dance := false
end if
put "Can you act?(y/n)"
getch (ans)
put ""
if ans = "y" then
cartoon.act := true
sum += 1
else
cartoon.act := false
end if
cartoon.salary := sum * 10000
put "Your salary is $", cartoon.salary : 0 : 2, "."
2.
var word := "array_files_record"
var a : array 1 .. 4 of string := init ("a", "b", "c", "d")
for i : 1 .. 4
a (i):=a(i) + word(i*2) + word(index (word,"_")..*)
put a (i)
end for
3.
var word2 := "Turing is great!"
var eachone:array 1..length(word2) of string(1)
for decreasing i:length(word2) ..1
eachone(i) := word2(i)
end for
for i: 1..length(word2) div 3
put eachone((i-1)*3+1):2,eachone((i-1)*3+2):2,
eachone((i-1)*3+3):2
end for
PART B - Draw flowcharts for each of the following problems - 15 marks, 5 marks each
1. Create a file called "TEST" with the following fields: student name, array test mark, files test mark, and overall test mark. The name is a string and the three test marks are integer values. Prompt the user for this information and use a sentinel to determine when there is no more input.
2. Read the above file "TEST". Output the average for each student. Output all data read and calculated in chart form.
3. Output the middle letter of the middle name in the file "TEST".
PART C - Short answer questions. (10 marks)
1. Define each of the following and provide a few lines of Turing to
illustrate each: (4 marks)
a) init
b) record type
c) array of records
d) dynamic array
2. What is the advantage of using an array of records over related arrays? Provide a concrete example. (3 marks)
3. We have studied that modifying files requires the use of an extra temporary file which contains a copy of the original file data. Explain how using arrays could replace the second. (3 marks)
PART D - TURING PROGRAM - 19 marks
The following code constitutes the type definition and main program of a Turing file.
% type definition
type numType :
record
num : int
square, cube, squareroot, cuberoot : real
isprime : boolean
end record
%main program
var num : int
var word : string
inputnum (word, num)
var numbers : array 1 .. num of numType
assignnums (numbers, num)
sortnums (numbers, num)
printnums (numbers, num)
Create all the necessary subprogams to complete this program. Do not make changes to the main program. The following is a description of the purpose of each subprogram.
inputnum - prompts the user for a number. The number has no restrictions except that it must be an integer. This subprogram must ensure that the input is a valid integer. If it is not, the user will continue to be prompted until the input is correct.
assignnums - randomly generates a number between 1 and 100.
Assigns this number to the field num. Finds the square, cube, square root and cube root of this number and then assigns each to the respective fields. It also determines whether the number is prime or not. If it is prime, the field contains true. If it is false, the field contains false. This is repeated for all the numbers generated and they must be stored in the array of records "numbers".
sortnums - sorts the array of records according to number in your choice of ascending or descending order.
printnums - outputs the contents of the array of records "numbers" in chart form. Uses a getch to move from screen to screen if the output exceeds one screen length.
| inputnum | 4 marks |
| assignnums | 6 marks |
| sortnums | 5 marks |
| printnums | 4 marks |
| total | 19 marks |
PART A -PREDICTING OUTPUT 1 mark per line (16 marks)
1.
Can^you^sing?(y/n)
p
Can^you^dance?(y/n)
y
Can^you^act?(y/n)
y
Your^salary^is^$30000.00.
2.
ar_files_record
ba_files_record
c__files_record
di_files_record
3.
T^u^r^
i^n^g^
^^i^s^
^^g^r^
e^a^t^
PART B - FLOWCHARTS - 15 marks - 5 each
PART C - SHORT ANSWER - 10 marks as outlined in test
1a. init - a statement used in Turing to initialize an array. The bounds of the array must be constants.
var friends:array 1..4 of string := init ("Fred", "Barney", "Wilma",
"Betty")
1b. Record type - a type declaration of a set of fields which can be of various types grouped as one data structure and treated as one unit.
type RecordType:
record
name:string
address:string
age:int
end record
1c. Array of records - an array declaration of a programmed defined record type.
type RecordType:
record
name:string
address:string
age:int
end record
var people : array 1 .. 3 of RecordType
1d. Dynamic array - The size of an array is dependent on data which is known at least just before the dyamic array is used. It is useful when using arrays as subprogram parameters
proc generatenum ( var a : array 1..* of int, n:int)
% contents of procedure
end generatenum
%main program
var n:int
put "How many numbers?"
get n
var numbers : array 1..n of int
generatenum(list,n)
2. The advantage of using an array of records over a group of related arrays is that the record structure makes the fields one data unit in memory. It minimizes the chance of forgetting to assign to a field. The greatest benefit is when sorting. Regardless of the number of fields, comparisons can be done by a field and the record can be swapped as a whole. (3 lines complete a swap of n fields, n*3 lines required for related arrays swapping)
3. The file can be opened counted and closed. The arrays can be declared. The file is re-opened and read into the arrays. The original data and the changes can then be re-written into the file. The array serves as a holding tank for the original data eliminating the need for the second file.
PART D - TURING PROGRAM - 19 marks as outlined in test
type numType :
record
num : int
square, cube, squareroot, cuberoot : real
isprime : boolean
end record
function primenum (n : int) : boolean
var count := 0
for i : 1 .. n
if 1 mod n = 0 then
count += 1
end if
end for
if count > 2 then
result false
else
result true
end if
end primenum
function square (n : int) : real
result n ** 2
end square
function cube (n : int) : real
result n ** 3
end cube
function squareroot (n : int) : real
result n ** (1 / 2)
end squareroot
function cuberoot (n : int) : real
result n ** (1 / 3)
end cuberoot
proc inputnum (var word : string, var n : int)
loop
var stat := true
put "How many numbers would you like to generate?"
get word
for i : 1 .. length (word)
if index ("0123456789", word (i)) = 0 then
stat := false
exit
end if
end for
exit when stat
put "Wrong input, try a number"
end loop
n := strint (word)
end inputnum
proc assignnums (var nums : array 1 .. * of numType, n : int)
randomize
for i : 1 .. n
randint (nums (i).num, 1, 100)
nums (i).square := square (nums (i).num)
nums (i).cube := cube (nums (i).num)
nums (i).squareroot := squareroot (nums (i).num)
nums (i).cuberoot := cuberoot (nums (i).num)
nums (i).isprime := primenum (nums (i).num)
end for
end assignnums
proc sortnums (var nums : array 1 .. * of numType, n : int)
for i : 1 .. n -1
for j : 1 .. n -i
if nums (j).num > nums (j + 1).num then
var temp := nums (j)
nums (j) := nums (j + 1)
nums (j + 1) := temp
end if
end for
end for
end sortnums
proc printnums (nums : array 1 .. * of numType, n : int)
var reply : string (1)
for i : 1 .. n
if i mod 20 = 0 then
put "press any key to see next screen"
getch (reply)
cls
end if
put nums (i).num : 6, nums (i).square : 10, nums (i).cube : 10, nums(i).square_root
: 20 : 2, nums (i).cube_root : 20 : 2
end for
end printnums
% main program
var num : int
var word : string
inputnum (word, num)
var numbers : array 1 .. num of numType
assignnums (numbers, num)
sortnums (numbers, num)
printnums (numbers, num)
% add_del.t - sequential assignment question # 3
proc menu (var opt : string (1))
put " MENU"
put " ****"
put " 1. ADD A RECORD "
put " 2. DELETE A RECORD"
put " 3. VIEW A FILE"
put " 4. EXIT"
loop
put "Make a selection 1-4 from above"
getch (opt)
exit when index ("1 2 3 4", opt) > 0
put "Error in input, try again please!"
end loop
end menu
proc copy
var s1, s2 : int
var name, address, phone, fax, email : string
open : s1, "lbbook", get
open : s2, "temp", put
loop
get : s1, skip
exit when eof (s1)
get : s1, name : *
get : s1, address : *
get : s1, phone : *
get : s1, fax : *
get : s1, email : *
put : s2, name
put : s2, address
put : s2, phone
put : s2, fax
put : s2, email
end loop
close : s1
close : s2
end copy
proc add_record
copy
var s1, s2 : int
var name, address, phone, fax, email : string
open : s1, "temp", get
open : s2, "lbbook", put
loop
get : s1, skip
exit when eof (s1)
get : s1, name : *
get : s1, address : *
get : s1, phone : *
get : s1, fax : *
get : s1, email : *
put : s2, name
put : s2, address
put : s2, phone
put : s2, fax
put : s2, email
end loop
put "Enter the name of the friend you want to add"
get name : *
put "Enter the address of your friend ", name, "."
get address : *
put "Enter the phone number for your friend ", name, "."
get phone : *
put "Enter the fax number for your friend ", name, "."
get fax : *
put "Enter the email address of your friend ", name, "."
get email : *
put : s2, name
put : s2, address
put : s2, phone
put : s2, fax
put : s2, email
close : s2
close : s1
put name, " has been added to the file!"
end add_record
proc del_record
copy
var s1, s2 : int
var name, address, phone, fax, email, key : string
var found := false
open : s1, "temp", get
open : s2, "lbbook", put
put "Enter the name of person whom you want to delete from the file"
get key : *
loop
get : s1, skip
exit when eof (s1)
get : s1, name : *
get : s1, address : *
get : s1, phone : *
get : s1, fax : *
get : s1, email : *
if name = key then
found := true
else
put : s2, name
put : s2, address
put : s2, phone
put : s2, fax
put : s2, email
end if
end loop
close : s2
close : s1
if found then
put key, " has been successfully deleted from the file!"
else
put key, " could not be found in the file. Deletion aborted."
end if
end del_record
proc view_file
var stream : int
var count := 0
var reply : string (1)
var name, address, phone, fax, email : string
open : stream, "lbbook", get
put "NAME ADDRESS PHONE FAX EMAIL"
loop
get : stream, skip
exit when eof (stream)
count += 1
get : stream, name : *
get : stream, address : *
get : stream, phone : *
get : stream, fax : *
get : stream, email : *
if count mod 20 = 0 then
put "Press any key to continue"
getch (reply)
cls
put "NAME ADDRESS PHONE FAX EMAIL"
end if
put name : 14, address : 21, phone : 10, fax : 10, email
end loop
close : stream
end view_file
% main program
var choice, stall : string (1)
loop
menu (choice)
put ""
put "Press any key to continue"
getch (stall)
cls
if choice = "1" then
add_record
elsif choice = "2" then
del_record
elsif choice = "3" then
view_file
else
exit
end if
put "Press any key to continue"
getch (stall)
cls
end loop
% file animate - text file (animate)
Fred Flintstone
ABC
G
The Flintstones
1967
Wilma Flintstone
ABC
G
The Flintstones
1967
Barney Rubble
ABC
G
The Flintstones
1967
Betty Rubble
ABC
G
The Flintstones
1967
George Jetson
ABC
G
The Jetsons
1970
Jane Jetson
ABC
G
The Jetsons
1970
Judy Jetson
ABC
G
The Jetsons
1970
Elroy Jetson
ABC
G
The Jetsons
1970
Scooby-Do
NBC
G
The Adventures of Scooby-Do
1974
Scrappy
NBC
G
The Adventures of Scooby-Do
1974
% array test solution - part D - Turing program (arr_test.t)
fcn count : int
var tot := 0
var stream : int
var dummy : string
open : stream, "dst", get
loop
get : stream, skip
exit when eof (stream)
for i : 1 .. 8
get : stream, dummy : *
end for
tot += 1
end loop
close : stream
result tot
end count
proc read_array (var a, b : array 1 .. * of string, var t1, t2, t3, p1, p2,p3 : array 1 .. * of int, var ta, pa, av : array 1 .. * of real, num: int)
var stream : int
open : stream, "dst", get
for i : 1 .. num
get : stream, a (i) : *
get : stream, b (i) : *
get : stream, t1 (i)
get : stream, t2 (i)
get : stream, t3 (i)
get : stream, p1 (i)
get : stream, p2 (i)
get : stream, p3 (i)
ta (i) := (t1 (i) + t2 (i) + t3 (i)) / 300 * 70
pa (i) := (p1 (i) + p2 (i) + p3 (i)) / 300 * 30
av (i) := ta (i) + pa (i)
end for
close : stream
end read_array
proc sort (var a, b : array 1 .. * of string, var t1, t2, t3, p1, p2,
p3 : array 1 .. * of int, var ta, pa, av : array 1 .. * of real, num : int)
for i : 1 .. num -1
for j : 1 .. num -i
if av (j) < av (j + 1) then
var temp := av (j)
av (j) := av (j + 1)
av (j + 1) := temp
temp := pa (j)
pa (j) := pa (j + 1)
pa (j + 1) := temp
temp := ta (j)
ta (j) := ta (j + 1)
ta (j + 1) := temp
var temp2 := t1 (j)
t1 (j) := t1 (j + 1)
t1 (j + 1) := temp2
temp2 := t2 (j)
t2 (j) := t2 (j + 1)
t2 (j + 1) := temp2
temp2 := t3 (j)
t3 (j) := t3 (j + 1)
t3 (j + 1) := temp2
temp2 := p1 (j)
p1 (j) := p1 (j + 1)
p1 (j + 1) := temp2
temp2 := p2 (j)
p2 (j) := p2 (j + 1)
p2 (j + 1) := temp2
temp2 := p3 (j)
p3 (j) := p3 (j + 1)
p3 (j + 1) := temp2
var temp3 := a (j)
a (j) := a (j + 1)
a (j + 1) := temp3
temp3 := b (j)
b (j) := b (j + 1)
b (j + 1) := temp3
end if
end for
end for
end sort
proc display (a, b : array 1 .. * of string, c, d, e : array 1 .. *
of real, num : int)
cls
put ""
put "First Name Last Name tests(70%) projects(30%) total(100%)"
for i : 1 .. num
if i mod 20 = 0 then
var reply : string (1)
put "Press any key to continue"
getch (reply)
cls
put "First Name Last Name tests(70%) projects(30%) total(100%)"
end if
put a (i) : 15, b (i) : 15, c (i) : 10 : 2, d (i) : 17 : 2, e (i) : 12 : 2
end for
end display
% program main
var num