CSCI-UA.0002 Introduction to Computer Programming - Assignment 09: Email Service
Assignment #9
For this assignment you will be writing 2 programs which should be saved independently . The filename you should use for each program is outlined in the sections below . When you're finished, you should submit your programs using the 'Assignments' tool in Brightspace.
You may work by yourself or with a partner . If you choose to work with someone else please be sure to give them credit in your source code and on Brightspace when you submit your work. Each member of a team must submit their own copy of the assignment to get credit for the assignment.
Part 0: In-class Warm Up Exercise
This program relies on a series of data files. Simply right-click on the links below (control- click on a Mac) and select "Save As" or "Save Link As" to save these files to your computer . Ensure that these files are stored in a folder that contains your source code file (i.e. 'LastnameFirstname_assign9_part0.py') for this project as well. class_data.txt (data/class_data.txt) enrollment_data.txt (data/enrollment_data.txt) You've been hired by NYU's Computer Science department to create a tool that will allow professors to look up their course rosters online. Currently course registration data is stored using two dif ferent text files. class_data.txt Stores the course ID and the title of each course. There will always be one record in this file for every course that the CS department is currently of fering. Here's what this file looks like:
CS0002,Introduction to Computer Programming
CS0004,Introduction to Web Design and Computer Principles
CS0060,Database Design and Implementation
CS0061,Web Development
CS0101,Introduction to Computer Science
CS0102,Data Structures
CS0201,Computer Systems Organization
CS0380,Special Topics in Computer Science
enrollment_data.txt
Stores the course ID, last name and first name of each student enrolled in the course. Note that there are multiple records per course (one per student enrolled). For example, here's the beginning of this file showing six students enrolled in CS0002:
CS0002,Hiner,Judith
CS0002,Mcmahon,Ludivina
CS0002,Trusty,Beatrice
CS0002,Brinn,Jacqulyn
CS0002,Hintzen,Floria
CS0002,Amyx,Randolph
Your task is to write a program that asks the user for a course ID. The program will then determine if the course ID is valid or not -- if it is not, the program can safely end. If it is valid, the program should report the full title of the course, how many students are enrolled in the course and the names of each student enrolled.
You cannot hard code your program to only work with the values contained within these files. When we test your work we will be using completely dif ferent data files that are organized in the same way as these sample files. Your program should work flawlessly using this new data.
I've broken up this program into smaller tasks that you should attempt one at a time as a group. Do these in order .
Task #1
Begin by asking the user for a course. Next, open the file class_data.txt for reading and obtain all data from the file. You'll need to parse this file so you can access the data you care about. Take a look at how the file is being organized: COURSE_NUMBER_1,COURSE_DESCRIPTION_1 COURSE_NUMBER_2,COURSE_DESCRIPTION_2 COURSE_NUMBER_2,COURSE_DESCRIPTION_2 Each line contains information about a course. On each line you have two values to work with - the course number and the course description. These values are separated by commas. The first step is to isolate the individual lines from one another . Hint: the split method may be useful here! After this, you need to examine each line and identify if that line contains the course number that the user typed in. This will require you to isolate the course number from the course description. Hint: a for loop along with another call to the split method may be useful here! Store the title somewhere (an accumulator variable?) so you can access it later .
Finally , generate some output to let the user know if (a) the course cannot be found or (b) the course can be found, along with the title. Do this outside of the loop that you used to find the course. Hint: you may need to set a variable to indicate that you found the course, along with the course title to do this.
At the end of task #1 your program should operate as follows: NYU Computer Science Registration System Enter a course ID (i.e. CS0002, CS0004): pikachu Cannot find this course NYU Computer Science Registration System Enter a course ID (i.e. CS0002, CS0004): CS Cannot find this course NYU Computer Science Registration System Enter a course ID (i.e. CS0002, CS0004): CS0002 The title of this course is: Introduction to Computer Programming Task #2 Next you will need to see how many students are enrolled in the course (if it exists). Here's how to get started: If the course is running you will need to open up the enrollment_data.txt file and read in the contents of this file as a string. This file is organized as follows: COURSE_NUMBER,STUDENT_LAST_NAME,STUDENT_FIRST_NAME COURSE_NUMBER,STUDENT_LAST_NAME,STUDENT_FIRST_NAME COURSE_NUMBER,STUDENT_LAST_NAME,STUDENT_FIRST_NAME COURSE_NUMBER,STUDENT_LAST_NAME,STUDENT_FIRST_NAME Each line contains information about a student. On each line you have three values to work with - the course number , the last name of the student and the first name of the student. These are all separated by commas. Begin by isolating the individual records from one another (the lines). Then examine each line to see if that line contains a student enrolled in the desired course. When examining a line of data you will need to further process that line it (to extract the course number and the student name) If that line contains the course number in question you should make a note of it. Hint: an accumulator list may be useful to store all of the students enrolled in this course. Finally , after you've finished examining each line you should print out your final report (how many students are enrolled and each of their names) At the end of task #2 your program should operate as follows: NYU Computer Science Registration System Enter a course ID (i.e. CS0002, CS0004): pikachu Cannot find this course NYU Computer Science Registration System Enter a course ID (i.e. CS0002, CS0004): CS Cannot find this course NYU Computer Science Registration System Enter a course ID (i.e. CS0002, CS0004): CS0002 The title of this course is: Introduction to Computer Programming The course has 6 students enrolled
- Hiner,Judith
- Mcmahon,Ludivina
- Trusty,Beatrice
- Brinn,Jacqulyn
- Hintzen,Floria
- Amyx,Randolph NYU Computer Science Registration System Enter a course ID (i.e. CS0002, CS0004): CS0004 The title of this course is: Introduction to Web Design and Computer Principles The course has 7 students enrolled
- Woodman,Tilda
- Schneiderman,Saran
- Conn,Glayds
- Cales,Edgar
- Hiner,Judith
- Lukens,Refugio
- Alfrey,Jerrica NYU Computer Science Registration System Enter a course ID (i.e. CS0002, CS0004): CS0201 The title of this course is: Computer Systems Organization The course has 0 students enrolled Some hints to get you started: Ensure that your source code file ('LastnameFirstname_assign9_part0.py') is saved in a folder along with the data files linked above. Begin by asking the user for a course name. You will need to consult with the 'class_data.txt' file to check to make sure the course is valid, as well as determine the title of the course. This most likely will involve reading the file and examining each line in the file to see if the name on that line matches the name the user supplied. Hint: How can you isolate each line in the file? What separates each line? How can you
Part 1: E-mail Service
Note that the programs you will be writing build on one another . You will want to attempt these parts in order . You can also feel free to save all of your work in one big file named as follows: LastNameFirstName_assign9_part1.py (for example, "KappCraig_assign9_part1.py")
You have just been hired by a tech startup that is planning on releasing a new e-mail service to its clients. They have asked you to create a prototype of this service using your Python skills.
The final version of this prototype should do the following: Allow the user to register for a new account. When they register , they will supply a username and password, which will need to be validated. The username will also need to be unique (i.e. only one person can have a given username). If the user registers successfully their information will need to be stored in a permeant storage mechanism (in this case, a file)
The user should also be able to log into their account. This part of the system will ask the user for a username and password and match it up against the one the company has on file for them. Note that the company plans on having millions of clients, so this information must be cross-referenced against a file and cannot be 'hard-coded'.
The user should be able to send messages to any other user on the system. To send a message the system will ask the user for the name of a recipient and a message to send (one line of text). If the recipient is registered the message will be delivered through a file. The user should be able to read messages that have been sent to them (and only them) The user should be able to delete all of the messages that have been sent to them (and only them)
In order to do this the software engineers at the company have outlined a series of functions that will need to be build to create the prototype. Your job is to build these functions and test them as you go - don't skip ahead! When all of the necessary functions are built you will use them to construct the prototype e-mail system
Part 1a
Begin by writing functions that conform to the following IPO specifications. Tester code is listed below each function.
# function: valid_username
# input: a username (string)
# processing: determines if the username supplied is valid. for the purpose
# of this program a valid username is defined as follows:
# (1) must be 5 characters or longer
# (2) must be alphanumeric (only letters or numbers)
# (3) the first character cannot be a number
# output: boolean (True if valid, False if invalid)
# TESTER CODE
print( valid_username('abc123') ) # True
print( valid_username('abcde') ) # True
print( valid_username('abc') ) # False
print( valid_username('@#$%^') ) # False
print( valid_username('1abcde') ) # False
print( valid_username('') ) # False
# function: valid_password
# input: a password (string)
# processing: determines if the password supplied is valid. for the purpose
# of this program a valid password is defined as follows:
# (1) must be 5 characters or longer
# (2) must be alphanumeric (only letters or numbers)
# (3) must contain at least one lowercase letter
# (4) must contain at least one uppercase letter
# (5) must contain at least one number
# output: boolean (True if valid, False if invalid)
# TESTER CODE
print( valid_password('Abc123') ) # True
print( valid_password('Abc123xyz') ) # True
print( valid_password('Ab12') ) # False
print( valid_password('abc123') ) # False
print( valid_password('123456') ) # False
print( valid_password('Abc123#') ) # False
print( valid_password('') ) # False
Part 1b
Now that you can validate usernames and passwords it's time to write some code that will register new user accounts. In order to do this you will need to create a file that will contain the usernames and passwords for all users of the system. This file, user_info.txt - which you can download here (data/user_info.txt) (right-click on the link and select "Save As" or "Save Link As") is set up with five demo accounts and is organized as follows: pikachu,Abc123 charmander,Xyz123 squirtle,SquirtleSquad99 Pidgey2020,Pqr123 fearow,Pidgey2020 Note that this file is organized as follows: The file is organized into multiple lines Each line represents a single user On each line there are two values, separated by commas. The first value (before the comma) is the username and the second value (after the comma) is the password for that user. The first thing you will want to do is download the user_info.txt file and save it in the same folder as your source code file for this program. Once this file is in place you can begin writing the following two functions:
# function: username_exists
# input: a username (string)
# processing: determines if the username exists in the file 'user_info.txt'
# output: boolean (True if found, False if not found)
# TESTER CODE
print( username_exists('pikachu') ) # True
print( username_exists('charmander') ) # True
print( username_exists('squirtle') ) # True
print( username_exists('Pidgey2020') ) # True
print( username_exists('SquirtleSquad99') ) # False
print( username_exists('eevee') ) # False
print( username_exists('bobcat') ) # False
print( username_exists('') ) # False
# function: check_password
# input: a username (string) and a password (string)
# processing: determines if the username / password combination
# supplied matches one of the user accounts represented
# in the 'user_info.txt' file
# output: boolean (True if valid, False if invalid)
# TESTER CODE
print( check_password('pikachu', 'Abc123') ) # True
print( check_password('squirtle', 'SquirtleSquad99') ) # True
print( check_password('fearow', 'Pqr123') ) # False
print( check_password('foobar', 'Hello123') ) # False
print( check_password('', '') ) # False
Part 1c
For this part you will be writing a function that will create new users for the system. This function should be designed as follows:
# function: add_user
# input: a username (string) and a password (string)
# processing: if the user being supplied is not already in the
# 'user_info.txt' file they should be added, along with
# their password.
# output: boolean (True if added successfully, False if not)
# TESTER CODE
add_user('foobar', 'abcABC123')
add_user('barfoo', 'xyz123ABC')
add_user('foobar', 'aTest123') # this should fail and the user should not be re-created,
# OUTPUT - check 'user_info.txt' to ensure that that two new accounts have been created
Part 1d
Next you will need to write a function to allow users to send messages to one another . Messages will be stored in a folder named 'messages' which you will need to create. Your file structure should look as follows:
LastNameFirstName_assign9_part1.py (main program)
user_info.txt (user database)
messages/ (folder)
After you have manually created this 'messages' folder you be able to start sending messages from one user to another . When a user is registered with the system we will create a new file in this 'messages' folder for that user - the name of this file will be their username with the file extension '.txt' - for example, if I register an account called 'snorlax' a file called 'snorlax.txt' should be created inside of the 'messages' folder for this user . All messages that will be sent to this user will be stored in this file. Note that you can easily create, edit and read files in sub-folders by using this syntax: file_object = open("messages/somefile.txt", "w") Here's the function IPO for the new function that can be used to send messages:
# function: send_message
# input: a sender (string), a recipient (string) and a message (string)
# processing: writes a new line into the specific messages file for the given users
# with the following information:
#
# sender|date_and_time|message\n
#
# for example, if you call this function using the following arguments:
#
# send_message('craig', 'pikachu', 'Hello there! nice to see you!')
#
# the file 'messages/pikachu.txt' should gain an additional line data
# that looks like the following:
#
# craig|11/12/2022 12:08:05|Hello there! nice to see you!\n
#
# note that you can generate the current time by doing the following:
#
# import datetime
# d = datetime.datetime.now()
# month = d.month
# day = d.day
# year = d.year
# ... etc. for hour, minute and second
#
# keep in mind that you may need to 'append' to the correct messages file
# since a user can receive an unlimited number of messages. you may also
# need to create a new message file if one does not exist for a user.
# output: nothing
# TESTER CODE
send_message('pikachu', 'charmander', 'Hey there!')
send_message('charmander', 'pikachu', 'Good to see you!')
send_message('pikachu', 'charmander', 'You too, ttyl')
# OUTPUT - two new messages files should be created - 'pikachu.txt' and 'charmander.txt'
# each should have the following content (dates will be different, though)
# take note of how the time for each message is formatted properly - 13:05:07 (instead o
#
# pikachu.txt
# charmander|11/12/2022 13:05:07|Good to see you!
#
# charmander.txt
Once this is working as expected you should update your 'add_user' function so that every time a new user is added a default message is sent to that user welcoming them to the system. This message should be sent from the user account 'admin' and should contain the text 'W elcome to your account!'. No welcome message should be sent if the username supplied to the 'add_user' function already exists in user_info.txt.
# TESTER CODE
add_user('testuser', 'Abc123')
# OUTPUT
#
# testuser.txt
# admin|11/12/2022 13:01:48|Welcome to your account!
Part 1e
Finally you will be writing two additional functions to complete the tools needed to write this program. The first function you will be writing will print out all messages for a specific user . Here's the IPO for this function:
# function: print_messages
# input: a username (string)
# processing: prints all messages sent to the username
# assume you have a file named 'charmander.txt' that contains the following
#
# admin|11/12/2022 13:01:48|Welcome to your account!
# pikachu|11/12/2022 13:05:07|Hey there!
# pikachu|11/12/2022 13:05:07|You too, ttyl
#
# this function should generate the following output:
#
# Message #1 received from admin
# Time: 11/12/2022 13:01:48
# Welcome to your account!
#
# Message #2 received from pikachu
# Time: 11/12/2022 13:05:07
# Hey there!
#
# Message #3 received from pikachu
# Time: 11/12/2022 13:05:07
# You too, ttyl
#
# assume you have an empty file named 'squirtle.txt':
#
# this function should generate the following output:
#
# No messages in your inbox
#
# output: no return value (simply prints the messages)
# TESTER CODE
print_messages("charmander")
print_messages("squirtle")
# OUTPUT
# Message #1 received from admin
# Time: 11/12/2022 13:01:48
# Welcome to your account!
#
# Message #2 received from pikachu
# Time: 11/12/2022 13:05:07
# Hey there!
#
# Message #3 received from pikachu
Once you can print messages successfully the last function you will need to write will be a function to delete all messages for a given user . The IPO for this function is as follows:
# function: delete_messages
# input: a username (string)
# processing: erases all data in the messages file for this user
# assume you have a file named 'pikachu.txt' that contains the following con
#
# admin|11/12/2022 13:01:48|Welcome to your account!
# charmander|11/12/2022 13:05:07|Good to see you!
#
# output: no return value
# TESTER CODE
delete_messages("pikachu")
# OUTPUT
# pikachu.txt - empty (all data erased)
#
Part 1f
Now you are ready to write the main program for this project! Here's what your program should do: Present the user with a menu of choices - login, register or quit If they choose to quit you should immeidately end the program. If they choose to register you should prompt them for a username and a password. Ensure that the username and password are valid using functions you've previously written. Then ensure that the username has not already been taken. If all of these items are OK you can go ahead and register the user for an account and return them to the main menu. If they choose to login you should prompt them for a username and a password. If the username and password does not match the data in user_info.txt, the login attempt should If the username and password is correct they should be logged in. They then should receive a new menu of options (hint - user a nested 'while' loop for this): Present the user with the options to read messages, send messages, delete messages or logout. If they choose to logout they should return to the main menu If they choose to read messages you should display their messages. If they choose to send a message you should prompt them for a recipient username and a message. If the recipient is unknown you should reject the message. If they are known, you should send a message to that user using your function. If they choose to delete messages you should delete all their messages. Here's a sample running of the program. This program assumes that you have an empty "user_info.txt" file (no users registered) and an empty "messages" folder (folder exists, but no files are stored inside of it). User input is highlighted in yellow: (l)ogin, (r)egister or (q)uit: r