Goals of this assignment
The main goal of this assignment is that you will practice and use the Function Design Recipe to plan, document, implement, and test many functions.
This entails the following sub-goals:
- You will show how to call each function appropriately with docstring examples.
- You will describe what each function does appropriately using docstrings (review the CSC108 Python Style Guidelines for the rules on how to write a docstring description).
- You will write function bodies using variables, numeric types, strings, and conditional statements.
- You will learn to use: Python 3, Wing 101, the provided starter code, a checker module, and other tools.
ELIZA (https://en.wikipedia.org/wiki/ELIZA) is a chatbot (https://en.wikipedia.org/wiki/Chatbot) a program that can take part in a conversation. ELIZA was created in 1964 by Joseph Weizenbaum at MIT to demonstrate how shallow conversation generally was. ELIZA fooled some people, who thought they were communicating with a human rather than a computer.
You will be writing a chatbot for this assignment.
Every chatbot takes a different approach.ELIZA acts like a Rogerian psychiatrist (https://en.wikipedia.org/wiki/Rogerian_argument) , but there are many applications of chatbots, including banking and other kinds of customer service. Many websites provide help using a chatbot.
To see ELIZA in action, visit Eliza, the Rogerian Therapist (http://psych.fullerton.edu/mbirnbaum/psych101/Eliza.htm) . Type anything you like in the Input field, and watch the conversation flow! (Seriously, you should go do that now so that the rest of the handout makes more sense.)
Here is a sample ELIZA conversation:
* What do I say? > What answer would please you the most? * I'd like to ask about owning a capybara. > Can you elaborate on that? * I want a capybara. They're so cute! > Suppose you got a capybara. They're so cute? * Yes, and I like the crittersoncapybaras subreddit. > Are you sure about that? * Yes! Don't you think the pictures are awesome? > We were discussing you, not me.
>‘s are ELIZA’s response to each sentence. A sentence is a statement (ends in a period a question (ends in a question mark
?), or exclamation (ends in an exclamation mark
The central feature of your chatbot is going to be a function that you design and implement called chat. Your chat function will act like ELIZA does, creating and returning a response based on the sentence.
Function char has a str parameter that receives its value when chat is called, and acts like
>>> chat("Capybaras ate my homework!") 'Homework is a meme.'
You can (and should) complete the whole assignment with only the concepts from Weeks 1, 2, and 3 of the course. This handout explains the problem being solved, and the tasks to complete, for the assignment. Please read it carefully and in its entirety so you don’t miss important and helpful tips!
For this assignment, we are giving you some files to help you get started. Please download the Assignment 1 Files and extract the zip archive (instructions for extracting a zip. We have provided you with the following files:
This is the file where you will write your solution. Your job is to complete the file by implementing all the required functions. See section Functions you need to implement for more details. You can run this file to start the chatbot.
This is the file containing several helper functions we have implemented for you. You will not modify this file.
a1_checker.py, checker_generic.py, and a1_pythonta.json
These files are part of a checker program that you should use to check your code. You will not modify this file. See the Using a1_checker.py section for more information about the A1 checker.
Our chatbot will have different responses for each of the following categories of user input:
- Input mentions the word homework
- Input is a question exclamation (ends with ?!)
- Input is an exclamation (ends with !)
- Input has a helping verb (these are: has, should, would, could, might, may or will) as the third word
- Input is a “Canadian question” (contains the word snow, ice or hockey, and ends with ?)
- Input is a question (ends with ?)
An input is placed into any one of the above categories in the order provided above. That is, if the input mentions homework , our chatbot will deal with it based on category 1 above, regardless of whether the input also mentions snow and ends with a ? .
Constants are special variables whose values should not change once assigned. A different naming convention (uppercase pothole) is used for constants, so that programmers know to not change their values.
For example, in the starter code, the constant QUESTION_SYMBOL is assigned the value ? near the beginning of the module, and because it’s all caps, that indicates that the value of QUESTION_SYMBOL should never change in your code. When writing your code, if you need to use a question mark character, you should use the QUESTION_SYMBOL constant variable.
The same applies for the other constant values. Using constants simplifies code modifications and improves readability and changeability, although it’s a little bit more effort to set up initially. Because code is read far more than it’s written, learning how to do the extra up-front effort is worth it.
For example, if we later decide to use a different character for QUESTION_SYMBOL , maybe a black square, we would only have to make a change in one place (the QUESTION_SYMBOL assignment statement), rather than throughout the program.
Constants also make the code more readable.
A very big reason why we ask you to use constants is that it dramatically reduces the number of typos in strings, which are quite hard to test for automatically.
Coding Rules and Guidelines (important!)
- For every function you write, make sure you follow the Function Design Recipe and include a complete docstring which follows the CSC108 Python Style Guidelines for good docstring descriptions, and at least two docstring examples per function, we provide a few example calls for some functions within this handout; you may include these examples as part of your docstrings as applicable.
- We have provided several constants for you within questionbot.py and helper functions in chat_utilities.py . You must use these whenever applicable, throughout your program.
Rules to make your lives easier
- We will always use regular English sentences in the test cases. A sentence includes at least one word, and ends with a period, a question mark, or exclamation mark. We won’t use a sentence that doesn’t have any words, like ‘?’.
- For helping verbs, we will only test with sentences that have a verb following the helping verb. For example, we won’t test with a sentence like ‘Yes it has.’ , where has doesn’t have any words after it.
- For Canadian words, you should treat capitalized versions as non-Canadian. ‘Snow’, for example, isn’t a Canadian word because of the capital S .
Functions you need to implement
Each category of input listed above will be handled by a separate pair of functions. For each category, we will write:
- A checking function that returns a boolean value stating whether the input matches this category
- A response generation function which returns the chatbot’s response based on an input of this category
Task 0: Familiarize yourself with the helper functions
In generating your chatbot responses, there are several string and word manipulations you may need to apply, such as:
- Select the first and last words
- Make an uppercase or lowercase version of a word
- Get the index of a substring in another string
- Drop the first word
We provide functions that do some of these things for you. These were created to make pulling apart and reconstructing the sentences easier, and they are in module chat_utilities .
When you open file chat_utilities.py and run it, all the doctests will be run. No more copying and pasting into the shell! The code inside the if statement at the bottom of the file makes this happen.
Read the docstrings and study the doctests. Call each of the functions from the Python shell to become familiar with them.
Once you’re done this, you can move on to the rest of the tasks, which involve finishing all the functions in questionbot.py . Note that the tasks listed below do not need to be completed in order if you get stuck on one, try another!
Task 1: Homework-related responses
Task 1.1: Checking and response generation functions
- NOTE: For this task, you only need to complete the docstring examples step of the Function Design Recipe. The rest of the function has been completed for you.
Consider the description and code provided for following two functions in the starter file:
These functions deal with input that contain the word “homework” (regardless of the letters being uppercase, lowercase, or a mix). You do not have to write any code for this task, but rather, read the code we have provided, understand it, and pay attention to our use of constants.
Then, complete the docstring examples with the expected return values based on the provided code and descriptions.
Task 1.2: Chat functionality
After completing Task 1.1, you should run questionbot.py to try out your chatbot. Currently, the chatbot will only work with homework-related inputs and give no responses otherwise. What happens if you try this in the Python shell? Do you get the value you expect?
>>> chat('The dog ate my homework!')
This works because of the code we have already started for you in the chat function provided. Read and understand this code.
If you have questions, search the discussion board to see if they have been answered, and if not, please ask!
Task 2: Exclamations
Task 2.1: Checking and response generation functions
Complete the following two functions using the Function Design Recipe (remember to also follow our Coding Rules and Guidelines).
For both, we have provided an outline, but for each you need to add at least two examples, complete the function header by adding parameters and their types and also the return type, write a complete docstring description, and then write the body of the function.
Base your work on these descriptions:
- This function should return True if the argument value (the one that is assigned to the parameter when the function is called) ends with a ! symbol, and False otherwise.
- The argument for this function must be a sentence that ends with an
exclamation symbol (this is a precondition for this function). This function will return the last word, capitalized, plus ate my homework. . There should be exactly one space after the capitalized word. There is an example sentence in the next Task 2.2.
Hint: In chat_utilities.py there are functions get_last_word and get_capitalized_word which you should call within this function.
Task 2.2: Chat functionality
Add code to the chat function to be able to deal with exclamations. Remember the order: check first whether it’s a homework sentence, and if it isn’t, check whether it’s an exclamation.
Here’s an example of how the chat function will behave once Task 2.1 and 2.2 are complete:
>>> chat("I play with my dog!") 'Dog ate my homework.'
Task 3: Helping verbs
Sometimes the input will contain a helping verb: the various tenses of “to be”, “to have”, and “to do”, such as have/has/had, is/am/are/was, and do/does/did.
Helping verbs help other verbs. In the statement “The dog was eating my homework.”, “was” is the helping verb, helping “eating”, making it an action that happened in the past.
Some helping verbs involve two words. Here is the same sentence that uses “will be” to set it in the future: “The dog will be eating my homework.” You do not need to handle two-word helping verbs in this assignment.
Go look at the HELPING_VERBS constant defined in file questionbot.py. How can you make use of it?
Task 3.1: Checking and response generation functions
Complete the following two functions (remember to follow our Coding Rules and Guidelines), based on the description below:
- This function should return True if the string argument ends with a period and contains a lowercase helping verb as its third word, and False otherwise. If there are less than three words in the given string, return False.
>>> contains_helping_verb('The dog has eaten my notes.') True >>> contains_helping_verb('The big dog has eaten my notes.') False
Hint: In questionbot.py we have included a completed function is_helping_verb . You can use it as a helper function to figure out whether the third word of a sentence is a helping verb.
- The argument for this function must be a statement (ends with a . ) whose third word is a helping verb. This function will return a question generated by moving the helping verb to the front.
Here are examples of how function do_helping_verb(str) will behave:
>>> do_helping_verb('The dog has eaten my notes.') 'Has the dog eaten my notes?' >>> do_helping_verb('Poor Clara had slept through her test.') 'Had poor Clara slept through her test?'
Note there are several things that have happened:
- The helping verb was capitalized and moved to the front (and a space was inserted after it).
- The original first letter of the sentence was made lowercase.
- The statement was turned into a question by replacing . with ? .
Task 3.2: Chat functionality
Update function chat to handle helping verb sentences so that it behaves like the examples above.
Task 4: Canadian questions
We’re defining Canadian questions as any questions that involve one or more of the words ice , snow , and hockey , even as part of another word. Be nice? , for instance, will be considered a Canadian question because of the ice within the word nice.
We have provided constants for these that you should use within your code.
Task 4.1: Checking and response generation functions
Complete the following two functions, based on the descriptions below. Unlike the previous tasks, we have not provided function outlines, so you will have to write them yourself. (The point here is to help you better learn the Python syntax for defining a function, since you will need to write dozens of functions in CSC108.)
Start with an example for each. You can use this sentence in your example: Is it snowing outside?
- This function should return True if the given string is a question (ends with a QUESTION_SYMBOL ) and contains at least one Canadian word (even as part of another word), and False otherwise. (Note: You should treat capitalized versions as nonCanadian. ‘Snow’ , for example, isn’t a Canadian word because of the capital S .)
Here is an example:
>>> is_canadian_question("Is it snowing outside?") True
- The argument for this function must be a question that contains at least one Canadian word. The function should then return the same string back except that it should end with , eh? . (Including the space after the comma. Canadians are careful about their whitespace.) (See example under Task 4.2)
Task 4.2: Chat functionality
Update function chat to handle Canadian question sentences. Here’s an example of how the chat function will behave once Task 4.1 and 4.2 are complete:
>>> chat("Is it snowing outside?") 'Is it snowing outside, eh?'
Task 5: Questions
These are for handling all the questions that do not match the kinds of sentences handled by the above tasks.
Task 5.1: Checking and response generation functions
Complete the following two functions, based on the descriptions below:
- This function should return True if the given string ends with a question mark.
- The argument for this function must be a question. The function should then return a response based on the following rules:
- If there is only one word in the argument, the returned response should be Is followed by the lowercase version of the word followed by the homework topic?
- If the first word of the question is:
- Will, the response should be The future is opaque.
- Can, the response should be the last word of the sentence capitalized, followed by is as, followed by the last word again, followed by does. For example, Rain is as rain does. is a possible response.
- In all other cases:
- If the last word and second word are the same (ignoring case) the response should be: Why do you say “ followed by the second word from the argument, followed by “? .
- If the last word and second word are different, the response should be Why do you say” followed by the second word, then “ and “ followed by the last word from the argument, followed by “? .
- Note: we have defined constants you should use for all these pieces!
Here are examples of how function do_question will behave:
>>> do_question("Yes! Do you think the pictures are awesome?") 'Why do you say "Do" and "awesome"?' >>> do_question("Hungry?") 'Is hungry the homework topic?' >>> do_question("Will you help me with the cleaning?") 'The future is opaque.' >>> do_question("Can a dog go to the gym?") 'Gym is as gym does.'
Hint: you can use each of the above sentences in your docstring examples for this function.
Task 5.2: Chat functionality
Update function chat to handle question sentences, so your program behaves like the examples above.
Task 6: Question Exclamation
Some sentences are excited or incredulous, and writers sometimes use ?! to indicate this. Note that statements ending with !? do not fall into this category, and should be treated like a regular question.
Task 6.1: Checking and response generation functions
Complete the following two functions, based on the description below:
- This function should return True if the given string ends with a question exclamation symbol. (And, of course, False otherwise.)
Hint: Use constants QUESTION_SYMBOL and EXCLAMATION_SYMBOL. Check that QUESTION_SYMBOL should be at second last index and EXCLAMATION_SYMBOL at last index.
- The argument for this function must end with a question exclamation symbol. This function will remove the exclamation mark from the argument to get a string ending with only the question mark, and then return the output from calling do_question (from Task 5.1) with this modified question string. (See examples under Task 6.2)
Task 6.2: Chat functionality
Update function chat to handle question-exclamation sentences.
Here are examples of how function chat will behave once Task 6.1 and 6.2 are complete:
>>> chat("Will you study for the midterm?!") 'The future is opaque.' >>> chat("Can a dog go to the gym?!") 'Gym is as gym does.'
Task 7: Fix the order of checks in function chat
Remember that the order you check the user input and generate a response should be the following: examine your chat functions to make sure you’re following this order. You may not have written them in this order, but the if statement needs to use them in this order:
Task 8: None of the above
Task 8.1: Response generation function
This is for all other sentences. There is no Boolean function to write; instead, declare an appropriate constant and then complete this function:
- This function should return What do you mean?
- Note: You must declare your own constant for this task and use that within your code for the above function.
Task 8.2: Chat functionality
Update function chat to handle unmatched cases. Here is an example of how the chat function will behave once Task 8.1 and 8.2 are complete (basically, if the input matches none of the above response types from Tasks 1-6, your program should respond with a What do you mean?):
>>> chat('There is snow outside.') 'What do you mean?'
We have provided a1_checker.py, which is a Python module that checks two things:
- Whether your code follows the Python style guidelines, and
- Whether your functions are named correctly, have the correct number of parameters, and return the correct types.
The checker does NOT check whether your functions return the correct values. You should do this yourself in the doctests and in the Python shell.
To run the checker, open a1_checker.py in Wing and run it.
- Note: the checker file needs to be in the same directory as questionbot.py, as provided in the starter code zip file.
Sample messages from the checker being run are below.
After running the checker, be sure to scroll up to the top of the shell and read all the messages!
The checker passes for both style and types
This means that:
- Your code follows the style guidelines.
- Your function names, number of parameters, and return types match the assignment specification.
This does not mean that your code works correctly in all situations. We will run a different set of tests on your code once you hand it in, so be sure to thoroughly test your code yourself before submitting (remember to check for both typical cases and corner cases such as empty strings for the functions that deal with string arguments).
The checker did not pass
Carefully read all the messages provided.
- It may have failed because your code did not follow the style guidelines. Review the error description(s) and fix the code style. Please see the PyTA documentation for more information about errors.
- It may have failed because:
- you are missing one or more functions,
- one or more of your functions are misnamed,
- one or more of your functions have the incorrect number or type of parameters, or
- one of more of your function return types do not match the assignment specification. Read the error message to identify the problematic function, review the function specification in the handout, and fix your code. Make sure the checker passes before submitting.
This section describes the aspects of your work that may be marked for A1.
Make sure that you follow Python style guidelines that we have introduced and the Python coding conventions that we have been using throughout the semester. Although we don’t provide an exhaustive list of style rules, the checker tests for style are complete. So if your code passes the checker, then it will earn full marks for coding style with one exception: docstrings may be evaluated separately. Make sure you review the CSC108 Python Style Guidelines for the rules on how to write a docstring description.
For each occurrence of a PyTA error, one mark (out of 20) deduction will be applied. For example, if a C0301 (line-too-long) error occurs 3 times, then 3 marks will be deducted. All functions, including helper functions, should have complete docstrings including preconditions when you think they are necessary.
Your functions should perform as specified. Correctness, as measured by our tests, will count for the largest single portion of your marks. Once your assignment is submitted, we will run additional tests not provided in the checker. Passing the checker does not mean that your code will earn full marks for correctness.
No Remark Requests
As mentioned earlier: No remark requests will be accepted. A syntax error could result in a grade of 0 on the assignment. Before the deadline, you are responsible for running your code and the checker program to identify and resolve any errors that will prevent our tests from running. The best way to check for this is to run the tests on MarkUs via the Automated Testing tab for this assignment.
What to Hand In
The very last thing you do before submitting should be to run the checker program one last time. Otherwise, you could make a small error in your final changes before submitting that causes your code to receive zero for correctness. Submit questionbot.py to Assignment 1 (i.e., a1) on MarkUs. Remember that spelling of filenames, including case, counts: your file must be named exactly as above.