ACIT 1515讲解、辅导Midterm Programming、讲解Python语言、辅导Python设计
- 首页 >> Python编程ACIT 1515 Take-Home Midterm Programming Assignment
Christopher Thompson
cthompson98@bcit.ca
BCIT — 23 November 2018
Welcome!
Hello! Welcome to your midterm! This programming assignment is worth 25% of your final mark. This
midterm must be submitted before the next lecture begins. Good luck!
1 Requirements
Please complete the following:
1. Create a new project in PyCharm called midterm.
2. Implement the requirements described in this document. The names you must use are below. Do
not modify the names I have provided.
3. Include correctly formatted docstrings that include comprehensive doctests (where necessary) for
each function. These docstrings must explain to the user how the function is meant to be used, and
what the expected output will be when input is provided.
4. Each function must also be tested in a separate unit test file by a separate collection of unit tests.
Ensure your test cases and functions have descriptive, meaningful names, and ensure that every
possible valid input is tested for each function.
5. Ensure that the docstring for each function you write has the following components (in this order):
(a) Short one-sentence description that begins with a verb in imperative tense
(b) One blank line
(c) Additional comments if the single line description is not sufficient (this is a good place to describe
in detail how the function is meant to be used)
(d) PRECONDITION statement for each precondition which the user promises to meet before using
the function
(e) POSTCONDITION statement for each postcondition which the function promises to meet if the
precondition is met
(f) One blank line
(g) And finally, the doctests. Here is an example:
def my_factorial(number):
"""Calculate factorial.
A simple function that demonstrates good comment construction.
PRECONDITION: number must be a positive integer
POSTCONDITION: calculates the correct factorial
>>> my_factorial(0)
1
1
>>> my_factorial(1)
1
>>> my_factorial(5)
120
"""
return math.factorial(number)
6. Ready? Alright, let’s start!
2 First program
1. Create a file called part_one.py. All of the code for part_one.py must go into a function called main.
2. Ask the user to enter a single line of text. The line of text must contain at least one non-blank
character, and must be 80 characters long or less. If either of these conditions is not met, ask the
user to enter a new string. Keep asking the user to enter a new string until the user provides one
that has at least one non-blank character and is 80 characters long or less.
3. Your part_one.py program must now display:
(a) The number of words in the input
(b) The number of characters in the input
(c) a line with a ’ruler’ that marks off every 10 characters (you can just use a hard-coded string)
(d) the line of text that was entered with leading and trailing white space removed.
Here is some sample input and output so you can see what your program should do:
python3 part_one.py
Enter a line: I just wanna get outta this place!
(7 words, 34 characters)
0---------1---------2---------3---------4---------5---------6---------7---------|
I just wanna get outta this place!
C:\> python3 part_one.py
Enter a line:
Error: Invalid Line - must have at least one character
C:\> python3 part_one.py
Enter a line: This is a1 super lo2ng line o3f or more4 chars! H5ow about 6that you 7punk rock8ers?
Error: Invalid Line - maximum line length is 80 characters
3 Second program
1. Question two tests your ability to create and use functions. You can refactor your program from part
1, or start a new program. Your program does not need to retain functionality from part 1 - unless
you want to.
2. This program should be named part_two.py.
3. Write a program that asks the user to enter an edit command, and then run the command. Minimally
your solution will include the following functions, which should be called from main():
2
(a) get_command(prompt): displays the specified prompt and asks the user enter a command.
The command entered is returned as a list where the first item is the command and subsequent
items are the arguments. For example if the user enters ’d abc’ your function will return [’d’,
’abc’].
(b) run_command(line, command): this function has two parameters: the line to be edited, and
command (ie: the list returned from get_command). At this point the only valid command is
’d’ which will delete as described below. This function will run the command if it is a valid
command, and print an error message if it is not.
(c) delete_chars(line, pattern): this function has two parameters: a line to be edited, and a pattern
to be removed. The function removes the first occurrence of the pattern, and returns the result.
Note that this function is run when the user enters d [pattern] as shown below.
Here is some sample input and output so you can see what your program should do:
C:\> python3 part_two.py
Enter a line: This is a test is it not?
Enter command: d is
--> result: Th is a test is it not?
C:\> python3 part_two.py
Enter a line: How are ya doin?
Enter command: del foo
Error: invalid command ’del’
C:\> python3 part_two.py
Enter a line: Another test from hell
Enter command: d XXX
--> result: Another test from hell
C:\> python3 part_two.py
Enter a line: This is a test
Enter command: d is is
--> result: Th a test
4 Third program
1. This third part is also completely independent of the previous parts. You may be able to reuse some
of the functions from the previous parts - but if you did not get them working you can write this from
scratch.
2. Write a program in a file called part_three.py that lets a user continuously enter editor commands.
The program will not actually run the commands. It should operate like this:
(a) continuously prompt for commands until the quit command is entered
(b) when a valid command is entered, the command is displayed along with the phrase ’Valid
command’
(c) when an invalid command is entered an error message is displayed
3
(d) when nothing is entered (just Enter key) it is ignored and the user is re-prompted for a new
command
3. For purposes of this part the valid commands will be:
(a) d [string] - delete first occurrence of string
(b) i [index] [string] - insert the string at the specified index
(c) r [word] [string] - replace first occurrence of a word with string
(d) q - exit the program
4. Note that the above commands assume the following definitions:
(a) string - any sequence of characters including spaces
(b) word - a single word containing no whitespace
(c) index - a positive integer
5. Your solution must use small single-purpose functions.
Here is some sample input and output so you can see what your program should do:
C:\> python3 part_three.py (this first example shows correct commands only)
Enter command > d cat food
--> d string=’cat food’ (valid command)
Enter command > i 2 dog food
--> i index=2 string=’dog food’ (valid command)
Enter command > r foo moo moo
--> ’r’ word=’foo’ string=’moo moo’ (valid command)
Enter command > q
C:\> python part_three.py (this example shows correct types of errors detected)
Enter command > d
Error: missing arguments - syntax is: d [string]
Enter command > i 2
Error: missing arguments - syntax is: i [index] [string]
Enter command > i abd def
Error: invalid index - syntax is: i [index] [string]
Enter command > r foo
Error: missing arguments - syntax is: r [word] [string]
Enter command > x dog
Error: invalid command ’x’
Enter command > q
C:\> python part_three.py (this example shows what happens when nothing is entered)
Enter command > d dog
--> d string=’dog’ (valid command)
Enter command >
Enter command >
Enter command > <-- at these parts I am just pressing enter
Enter command >
Enter command > d cat
--> d string=’cat’ (valid command)
Enter command > q
4
5 Modify program three
1. This part can use functions from Parts 1 and 2, or not. You can consider it as a separate program if
you like.
2. Modify part_three.py.
3. In this part you will enhance your program by adding functions as necessary to:
(a) Let the user continuously enter lines to be edited, and
(b) Save all the lines in a list, with one line per item, and
(c) Allow single empty strings but stop entering when a second empty string is entered, and
(d) Update the display to show lines formatted exactly as below.
4. Note that you do not need to be able to edit the lines anymore, just get them entered and displayed
as shown.
Here is some sample input and output so you can see what your program should do:
Enter a line > This is the first line
Enter a line > and this is the second
Enter a line > now I will press enter, and then I will press x after the prompt
so I can continue entering lines
Error: Invalid Line - maximum line length is 80 characters
Enter a line > Ok that was too long, sorry, now enter and then x ...
Enter a line >
[press Enter again to display lines, anything else to enter more lines]x
Enter a line > That should have inserted a line
Enter a line > and now enter twice to exit
Enter a line >
[press Enter again to display lines, anything else to enter more lines]
0---------1---------2---------3---------4---------5---------6---------7---------|
1: This is the first line
2: and this is the second
3: Ok that was too long, sorry, now enter and then x ...
4:
5: That should have inserted a line
6: and now enter twice to exit
6 Modify program three some more
1. In this part you will write a program (or extend your previous program) to calculate some statistics.
2. What we want to know is the relative frequency of each letter in the text that was entered (sound
familiar?).
3. Your solution should use a dictionary that counts the number of occurrences of each character. Note
that characters ’a’ and ’A’ are considered as the same thing.
4. Hint: if you have already written code somewhere that does this, use it! Don’t reinvent the wheel!
Use tools you’ve already developed!
Here is some sample input and output so you can see what your program should do:
C:\> python part_three.py
|--------1---------2---------3---------4---------5---------6---------7---------|
5
1: this is a test
2: and this is not a test
3:
4: that last line was empty
5: and this is that by that is not this
Input contains: 5 lines, 76 words, 96 characters
Letter frequency:
T - 18 (18.8%)
H - 7 (7.3%)
I - 9 (9.4%)
S - 12 (12.5%)
- 20 (20.8%)
A - 9 (9.4%)
E - 4 (4.2%)
N - 5 (5.2%)
D - 2 (2.1%)
O - 2 (2.1%)
L - 2 (2.1%)
W - 1 (1.0%)
M - 1 (1.0%)
P - 1 (1.0%)
Y - 2 (2.1%)
B - 1 (1.0%)
7 And something different...
1. This part has nothing to do with the previous parts - it is a completely separate program.
2. Your program should be named sgrep.py.
3. Write a program that reads the contents of a file, finds all lines that contain occurrences of a specified
pattern, and writes the result to the console.
4. Ask the user for the filename and the search pattern. For example using the file zen.txt and the
search pattern ’better than’ will look for any lines in file zen.txt that contain the phrase better than.
Matching lines are displayed on the console, with the matching phrase in upper case, and all other
characters in lowercase.
Here is some sample input and output so you can see what your program should do:
C:\> python3 sgrep.py
Enter the name of the file: zen.txt
Enter the search pattern: better than
beautiful is BETTER THAN ugly.
explicit is BETTER THAN implicit.
simple is BETTER THAN complex.
complex is BETTER THAN complicated.
flat is BETTER THAN nested.
sparse is BETTER THAN dense.
now is BETTER THAN never.
although never is often BETTER THAN *right* now.
Of note, the above session used file zen.txt which can be found at https://www.python.org/dev/peps/
pep-0020/ and which contains:
6
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren’t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you’re Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it’s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let’s do more of those!
8 Grading
This midterm will be marked out of 25. For full marks, you must:
1. (10 points) Correctly implement the requirements in this lab
2. (5 point) Correctly write and execute doctests for each function that thorough test the function
3. (5 point) Correctly write and execute unit tests for each function that thorough test the function
4. (5 point) Correctly format and comment your code including all comments. Eliminate all warnings
offered by PyCharm, too.