CS 1110/1111 - Spring 2016 - Previous POTDs

Important Links: Submit POTDs to the Automated Grading System and Join the TA Office Hour Queue

Program of the Day

POTD 1 - c2f.py - Due: Monday, February 8, 11:00 AM

Write a program to convert from Celsius to Fahrenheit.

You should prompt the user for the current temperature in Celsius, then print out the corresponding temperature in Fahrenheit (recall that 5(F − 32) = 9 C). An example run of the program might look like:

What is the temperature in Celsius? 31
It is 87.8 degrees Fahrenheit

Another run might look like:

What is the temperature in Celsius? 100
It is 212.0 degrees Fahrenheit

One quick hint: Consider that you might need to use float to get decimal numbers. Also, if you are having issues with decimal places, check out the format() function found in Section 2.8 of the Gaddis book.

Please match our prompts, etc, exactly. Your program should work for any integer Celsius temperature we provide.

Submission: Please submit one .py file named c2f.py to the grading system.

POTD 2 - dating.py - Due: Wednesday, February 10, 11:00 AM

Write a program that uses a folk rule to tell you the age range of people you can date.

There is a folk rule that says you can date people as young as half your age plus seven years old. This suggests they can date you if they are as old as twice your age minus thirteen.

An example run of the program might look like:

How old are you? 17
You can date people between 15 and 21 years old

Another run might look like:

How old are you? 70
You can date people between 42 and 127 years old

Please match our prompts, etc, exactly. Your program should work for any integer age ≥ 14 that we provide.

Submission: Please submit one .py file named dating.py to the grading system.

POTD 3 - number_list.py - Due: Friday, February 12, 11:00 AM

Write a program called number_list.py that will read in 5 integer values from the user, store them in a list, and perform some basic mathematical operations. Then, prompt the user to remove one item and perform the same operations. You will need to calculate the range (the difference between the largest and smallest numbers) and the average.

An example run of the program might look like this:

Number 1: 1
Number 2: 2
Number 3: 3
Number 4: 4
Number 5: 5

You entered: [1, 2, 3, 4, 5]
The average is: 3.0
The range is: 4
Which item do you want to remove?: 5

The new list has the following values: [1, 2, 3, 4]
The average is: 2.5
The range is: 3

Another run might look like:

Number 1: 34
Number 2: -12
Number 3: 109
Number 4: -34
Number 5: 6

You entered: [34, -12, 109, -34, 6]
The average is: 20.6
The range is: 143
Which item do you want to remove?: -34

The new list has the following values: [34, -12, 109, 6]
The average is: 34.25
The range is: 121

Please match our prompts, etc, exactly. Your program should work for any 5 integers that we provide. You can leave the default precision (i.e. you do not have to format to a certain number of decimal places)

Submission: Please submit one .py file named number_list.py to the grading system.

POTD 4 - phone_book.py - Due: Monday, February 15, 11:00 AM

Write a program called phone_book.py that will read in 5 entries into a phone book dictionary. Then, prompt the user to find a number by a given name, and a name by a given number.

An example run of the program might look like this:

Add an entry to the phone book: Mark 434-982-2688
Add an entry to the phone book: Sally 434-893-5665
Add an entry to the phone book: Carl 804-889-4554
Add an entry to the phone book: Carol 804-327-2414
Add an entry to the phone book: Jackie 545-677-0984

Who do you want to call?: Sally
Sally’s number is: 434-893-5665

Which number do you want to lookup?: 545-677-0984
That number belongs to: Jackie

Another run might look like:

Add an entry to the phone book: Mark 434-982-2688
Add an entry to the phone book: Sally 434-893-5665
Add an entry to the phone book: Carl 804-889-4554
Add an entry to the phone book: Carol 804-327-2414
Add an entry to the phone book: Jackie 545-677-0984

Who do you want to call?: Bob
That name is not in the phone book.

Which number do you want to lookup?: 111-111-1111
That number is not in the phone book.

Please match our prompts, etc, exactly. Your program should work for any names and phone numbers.

Submission: Please submit one .py file named phone_book.py to the grading system.

POTD 5 - higher_lower.py - Due: Wednesday, February 17, 11:00 AM

Write a program to play a simple guessing game with you.

The computer will pick a number between 1 and 100, then give you 5 guesses. If you guess right, it will say “You win!”. If you guess higher or lower than correct, it will say “The number is higher than that.” (or lower). If after five guesses they still don’t know the number, print “You lose; the number was x.” where x was the number you were to guess.

Before the game begins, ask what number to pick. If they say “−1”, pick randomly; otherwise, use their number even if it is outside the 1–100 range. Check your notes for how to get a random integer by using the random.randint() method.

An example run of the program might look like:

What should the answer be? 19
Guess a number: 9
The number is higher than that.
Guess a number: 40
The number is lower than that.
Guess a number: 19
You win!

Another run might look like:

What should the answer be? -1
Guess a number: 5
The number is higher than that.
Guess a number: 100
The number is lower than that.
Guess a number: 50
The number is lower than that.
Guess a number: 25
The number is lower than that.
Guess a number: 12
You lose; the number was 7.

You do not have to use loops to make the program work. If, however, you know how to use loops or would like to try, you may do so.

Submission: Please submit one .py file named higher_lower.py to the grading system.

POTD 6 - roman.py - Due: Friday, February 19, 11:00 AM

Write a program to compute the roman numeral representation of integers.

Given an integer larger than 0 and less than 4000, convert it to roman numerals. You can find the rules for this here, or simply search for it online.

There are many ways to do this, some more efficient than others. If it works and you wrote it yourself that’s good enough.

If the integer they provide is not in the right range, print “Input must be between 1 and 3999”

An example run of the program might look like:

Enter an integer: 1997
In roman numerals, 1997 is MCMXCVII

Another run might look like:

Enter an integer: 5820
Input must be between 1 and 3999

Submission: Please submit one .py file named roman.py to the grading system.

POTD 7 - caesar.py - Due: Monday, February 22, 11:00 AM

Write a program to decode text that was encoding using the Caesar cipher.

Caesar’s cihper works by shifting every letter in a piece of text three characters over, so “A” becomes “D”, “B” becomes “E”, etc.

An example run of the program might look like:

Enter your cipher text: zhofrph wr xyd!
The decoded phrase is: welcome to uva!

An example run of the program might look like:

Enter your cipher text: fv 1110 lv pb idyrulwh fodvv!!!
The decoded phrase is: cs 1110 is my favorite class!!!

Note: To make it easier, convert all text to lowercase before doing any conversion. We will be checking for lowercase letters only. However, you should allow all punctuation and spacing to go through unchanged.

Submission: Please submit one .py file named caesar.py to the grading system. (note the spelling: ae not e or ea; and ar not er)

POTD 8 - syllables.py - Due: Friday, February 26, 11:00 AM

Write a program that reads a word and prints the number of syllables in the word. For this program, assume the following rules are the only ones you need to determine the number of syllables (there are some special case words that do not follow these rules and we will NOT test for those):

  • Each vowel (a,e,i,o,u,y) counts as 1 syllable except as noted below
  • A sequence of adjacent vowels count as 1 syllable
  • An ‘e’ at the end of a word does not count
  • If the program determines there are no syllables, then set the count to 1 syllable

Here are some examples:

Please give me a word: harry
The word harry has 2 syllables.
Please give me a word: hairy
The word hairy has 2 syllables.
Please give me a word: hare
The word hare has 1 syllables.
Please give me a word: the
The word the has 1 syllables.

Submission: Please submit one .py file named syllables.py to the grading system.

POTD 9 - credit_card.py - Due: Monday, February 29, 11:00 AM

Write a program to compute if a given number is a valid credit card number.

Credit card numbers have what is called a check digit. This is a simple way of detecting common mis-typings of card numbers. The algorithm is as follows:

  1. Form a sum of every other digit, including the right-most digit; so 5490123456789128 sums to 8+1+8+6+4+2+0+4 = 33
  2. Form double each remaining digit, then sum all the digits that creates it; the remaining digits in our example (5 9 1 3 5 7 9 2) double to 10 18 2 6 10 14 18 4, which sums to 1+0+1+8+2+6+1+0+1+4+1+8+4 = 37
  3. Add the two sums above (33+37 = 70)
  4. If the result is a multiple of 10 (i.e., its last digit is 0) then it was a valid credit card number.

An example run might be:

Type a credit card number (just digits): 1
1 is not a valid credit card number

Another run might be:

Type a credit card number (just digits): 240
Yes, 240 is a valid credit card number

Another run might be:

Type a credit card number (just digits): 9548
Yes, 9548 is a valid credit card number

Another run might be:

Type a credit card number (just digits): 5490123456789129
5490123456789129 is not a valid credit card number

Submission: Please submit one .py file named credit_card.py to the grading system.

POTD 10 - nim.py - Due: Wednesday, March 2, 11:00 AM

Write a program that will play the game of Nim.

The Game of Nim is a well-known game with a number of variants. One particularly interesting version plays like this:

Assume you have a large pile of marbles. Two players alternate taking marbles from the pile. In each move, a player is allowed to take between 1 and half of the total marbles. So, for instance, if there are 64 marbles in the pile, any number between and including 1 and 32 is a legal move. Whichever player takes the last marble loses.

Write a program called Nim.java in which a human player plays against the computer. The program should first ask for how many marbles are in the starting pile. Then the program should ask for a character for who will start the game (‘p’ for player, ‘c’ for computer). The game will then alternate between the computer and the player, asking the player for how many marbles they want to take (making sure they take a positive integer between 1 and half the pile and making them pick another number if they do it wrong).

The computer should always take enough marbles to make the size of the pile a power of 2 minus 1 - such as 3, 7, 15, 31, 63, etc. If that’s not possible, the computer will take one marble.

You should find that the computer, if it gets to go first, will always win. Similarly, if you go first and know the strategy, you’ll always win!

An example run might be:

The Game of Nim

Number of marbles are in the pile: 100
Who will start? (p or c): c
The pile has 100 marbles in it.
The computer takes 37 marbles.
The pile has 63 marbles in it.
How many marbles do you want to take? (1-31): 4
The pile has 59 marbles in it.
The computer takes 28 marbles.
The pile has 31 marbles in it.
How many marbles do you want to take? (1-15): 13
The pile has 18 marbles in it.
The computer takes 3 marbles.
The pile has 15 marbles in it.
How many marbles do you want to take? (1-7): 6
The pile has 9 marbles in it.
The computer takes 2 marbles.
The pile has 7 marbles in it.
How many marbles do you want to take? (1-3): 2
The pile has 5 marbles in it.
The computer takes 2 marbles.
The pile has 3 marbles in it.
How many marbles do you want to take? (1-1): 1
The pile has 2 marbles in it.
The computer takes 1 marbles.
The pile has 1 marbles in it.
How many marbles do you want to take? (1-1): 1
The computer wins!

Another run might be:

The Game of Nim

Number of marbles are in the pile: 64
Who will start? (p or c): p
The pile has 64 marbles in it.
How many marbles do you want to take? (1-32): 1
The pile has 63 marbles in it.
The computer takes 1 marbles.
The pile has 62 marbles in it.
How many marbles do you want to take? (1-31): 45
How many marbles do you want to take? (1-31): 90
How many marbles do you want to take? (1-31): 31
The pile has 31 marbles in it.
The computer takes 1 marbles.
The pile has 30 marbles in it.
How many marbles do you want to take? (1-15): 15
The pile has 15 marbles in it.
The computer takes 1 marbles.
The pile has 14 marbles in it.
How many marbles do you want to take? (1-7): 7
The pile has 7 marbles in it.
The computer takes 1 marbles.
The pile has 6 marbles in it.
How many marbles do you want to take? (1-3): 3
The pile has 3 marbles in it.
The computer takes 1 marbles.
The pile has 2 marbles in it.
How many marbles do you want to take? (1-1): 1
The pile has 1 marbles in it.
The computer takes 1 marbles.
The player wins!

Submission: Please submit one .py file named nim.py to the grading system.

POTD 11 - hangman.py - Due: Wednesday, March 16, 11:00 AM

Write a program that will let the user play Hangman as shown in the examples below.

The user will guess letters until either:

  • They have correctly guessed all the letters in the word.
  • They have incorrectly guessed 6 times.

At each turn, display the player’s progress by showing the word they’re guessing in all capital letters, with all non-guessed characters replaced by dashes (“-”).

Suggested Approach

Here’s one possible way to approach this program:

  1. Prompt the user to enter a word
  2. Create a display string with the right number of hyphens (loop and add one for each letter in the target word).
  3. For each letter they guess,
    1. If the letter is not in the target word, count a miss
    2. Otherwise, make a new display string by
      1. loop through the target word’s letters
        1. if the letter matches their guess, add it to the new display string
        2. if the letter does not match their guess, copy whatever was in that spot of the old display string over
      2. replace the old display string with the new one
    3. If they have too many misses, tell them they lose; if there are no - left in the display string, tell them they win.

The specific output format is shown in the examples below:

Enter a word: HANGMAN
[-------] You have 6 left, enter a letter: A
Correct!
[-A---A-] You have 6 left, enter a letter: B
Incorrect!
[-A---A-] You have 5 left, enter a letter: C
Incorrect!
[-A---A-] You have 4 left, enter a letter: D
Incorrect!
[-A---A-] You have 3 left, enter a letter: E
Incorrect!
[-A---A-] You have 2 left, enter a letter: F
Incorrect!
[-A---A-] You have 1 left, enter a letter: G
Correct!
[-A-G-A-] You have 1 left, enter a letter: K
You lose! The word was “HANGMAN”

Enter a word: COMPUTER
[--------] You have 6 left, enter a letter: E
Correct!
[------E-] You have 6 left, enter a letter: B
Incorrect!
[------E-] You have 5 left, enter a letter: C
Correct!
[C-----E-] You have 5 left, enter a letter: A
Incorrect!
[C-----E-] You have 4 left, enter a letter: P
Correct!
[C--P--E-] You have 4 left, enter a letter: E
Correct!
[C--P--E-] You have 4 left, enter a letter: R
Correct!
[C--P--ER] You have 4 left, enter a letter: M
Correct!
[C-MP--ER] You have 4 left, enter a letter: A
Incorrect!
[C-MP--ER] You have 3 left, enter a letter: T
Correct!
[C-MP-TER] You have 3 left, enter a letter: O
Correct!
[COMP-TER] You have 3 left, enter a letter: U
You win! The word was “COMPUTER”

Enter a word: Aa
[--] You have 6 left, enter a letter: a
You win! The word was “AA”

Notes
  • We will only grade you on words and guesses made up of letters in the alphabet.
  • Convert both the word and the guesses to upper case; word Aa and guess a should say You win! The word was "AA".
  • If the user guesses a letter twice, handle it the same as the first time. If it initially matched a letter in the string, it should still count as a match and not as a miss. If it was initially a miss, it will count as another miss. This is shown in the examples above.
  • You may assume that the user only types single-letter guesses.

Submission: Please submit one .py file named hangman.py to the grading system.

POTD 12 - vigenere.py - Due: Monday, March 21, 11:00 AM

Write a program called vigenere.py that can take text both encode and decode a Vigenere ciphertext based on a given key word. For all given text, convert all letters to lowercase for processing. For the purposes of this assignment, assume ‘alphabet’ refers to only lowercase a-z (no symbols or uppercase).

You’ve already written a program based on the caesar cipher. That cipher can be pretty easy to crack with a computer - you only have to check a set number of shift values. So, what if we shifted each letter by a different letter. In other words, instead of shifting each letter by the same number (like 3), we shift each letter by a regular pattern, using another word.

If we encrypt:

WE ARE DISCOVERED FLEE AT ONCE

with the keyword LEAD, we get:

W + L = ?
Convert to numbers: 22 + 11 = 33
Wrap around: 33 - 26 = 7
Convert back to a letter: 7 = H

So the first letter is H. But this will take a long time to do this way! Thankfully, we have a chart we can use so we don’t have to do the math! Vigenre Square

If you look up W on the left column and L on the top row, where they meet is the letter that is encrypted.

Of course, we can do better than the chart by writing a program to do the same thing.

The catch to this POTD, however, is that you must do this program by writing particular functions that are laid out below. In your vigenere.py file, there should only be these six functions! You should not make any calls to input here for a user to type anything in. This file is just a library of functions. More information can be found below on how to test your program.

Functions

1. letter_to_index(letter): Given a letter, return the index position of that letter in the alphabet (assuming ‘a’ is at position 0). If the letter provided is not one of the 26 letters of the alphabet, return -1.

2. index_to_letter(index): Given an integer value, return the letter at that position in the alphabet (again assuming ‘a’ is at position 0). If the index provided is not between 0 and 25 (inclusive), return a question mark.

3. vigenere_encrypt(plain_letter, key_letter): Given a letter to encrypt and a key letter, return the encrypted letter. If either the plaintext letter or key letter are not in the alphabet, return the original plaintext letter.

4. vigenere_decrypt(cipher_letter, key_letter): Given a letter to decrypt and a key letter, return the decrypted letter. If either the ciphertext letter or key letter are not in the alphabet, return the original ciphertext letter.

5. encrypt(plaintext, key): Given a plaintext phrase or sentence and a key word, return the phrase or sentence encrypted. For the purposes of this assignment, you should ‘line up’ the key exactly with the plaintext, including punctuation and spacing, even though the punctuation and spacing is not encrypted.

For example:

Plaintexts: This is cool!!
EncryptKey: baconbaconbaco
Ciphertext: uhkg js qbpl!!

Notice that we converted the uppercase letter to lowercase and ignored the punctuation and spacing.

__6. decrypt(ciphertext, key): Given a cipher text phrase or sentence and a key word, return the phrase or sentence decrypted. For the purposes of this assignment, you should ‘line up’ the key exactly with the ciphertext, including punctuation and spacing, even though the punctuation and spacing is not encrypted.

For example:

Ciphertext: Uhkg Js qbpl!!
DecryptKey: baconbaconbaco
Plaintexts: this is cool!!

Notice that we converted the uppercase letter to lowercase and ignored the punctuation and spacing.

Testing Your Code

You can check any letter’s encryption or decryption with the Vigenre Square from Wikipedia.

To use this square:

  • To encrypt: Find the plaintext letter on the left and the key along the top. Where they meet in the grid is the encrypted letter.
  • To decrypt: Find the key letter on the top and scan down the column to find the encrypted letter. Then follow the row to the left to find the plaintext letter.

To actually test your code, we suggest you create a separate file called testing_vigenere.py. In this file, make the first line:

1
from vigenere import letter_to_index, index_to_letter, vigenere_encrypt, vigenere_decrypt, encrypt, decrypt

This will allow you to call all of the functions from vigenere.py in the testing_vigenere,py program. We suggest you write individual tests for each method in this file. For instance, to test letter_to_index, you could write the following:

1
2
3
4
if letter_to_index('a') == 0:
    print("letter_to_index - Passed 'a' test!")
else:
    print("letter_to_index - FAILED 'a' test! Expected 0, but got", letter_to_index('a'))

By writing tests like these for each method, you can ensure that each works properly!

Submission: Please submit one .py file named vigenere.py to the grading system. DO NOT submit any testing files. We only want your vignere.py file.

POTD 13 - election_polling.py - Due: Friday, March 25, 11:00 AM

Write a program called election_polling.py that will read polling data taken from Real Clear Politics to see how GOP candidates were doing from January through mid-March in Florida, Ohio, and North Carolina. We chose the GOP simply because there are more candidates currently in the race which makes the data a little more interesting.

You will use a subset of data that we provide for this assignment. The files you need are:

The fields in each file are, in order:

polling company,date range,how many polled,margin of error,cruz,kasich,rubio,trump

You must write the functions below, and only the functions below, to complete this POTD.

Functions

1. read_data_file(filename): Given a string representing a filename of the file that you want to open, open the file and read the data into a list of lists, in which each poll is a list consisting of the data items mentioned above. You will need to cast the numeric values to int before returning. Return this lists of lists.

For example, running read_data_file('ohio-gop.csv') should return:

[['Quinnipiac', '3/8 - 3/13', 721, 4, 16, 38, 3, 38], ['Monmouth', '3/11 - 3/13', 503, 4, 15, 40, 5, 35], ['CBS News/YouGov', '3/9 - 3/11', 828, 4, 27, 33, 5, 33], ['NBC/WSJ/Marist', '3/4 - 3/10', 564, 4, 19, 39, 6, 33], ['FOX News', '3/5 - 3/8', 806, 4, 19, 34, 7, 29], ['PPP (D)', '3/4 - 3/6', 638, 4, 15, 35, 5, 38], ['Quinnipiac', '3/2 - 3/7', 685, 4, 16, 32, 9, 38], ['CNN/ORC', '3/2 - 3/6', 359, 5, 15, 35, 7, 41], ['Quinnipiac', '2/16 - 2/20', 759, 4, 21, 26, 13, 31]]

2. poll_winner(poll_to_examine): Given a list in the order shown in the example, return two values - the last name of who is winning, along with the margin of victory (i.e. how much did first place beat second place). For example, it may be Trump and +14 for one poll or Rubio and +3 for another poll. When printed, it will appear as (‘Trump’, ‘+14’), but the parentheses and other punctuation are just done by the print. Your return statement should have two values in it, such as return name, value.

For example, running poll_winner(['Company X', 'Some Dates', 100,5,5,50,25,20]) should return:

('Kasich', '+25') - this is two values, not to be confused with a tuple or set

If there is a tie, return just the word TIE with no value.

3. latest_poll_winner_by_state(state): Given a state, return the same information as poll_winner for the latest poll for that given state. Note that this is always the first poll in the file. Also, note that you can use poll_winner inside this function, which makes this function ostensibly very short.

For example, running latest_poll_winner_by_state('florida-gop.csv') should return:

('Trump', '+24') - this is two values, not to be confused with a tuple or set

If there is a tie, return just the word TIE with no value.

4. average_of_polls(state, number_of_polls=5): Given a state and optionally a number of polls, calculate the average of all relevant values and return a new list representing the average poll.

For example, running average_of_polls('florida-gop.csv') should return:

['Average Poll', 5, 651, 4, 19, 9, 22, 44] - the 5 in the date field represents the number of polls used in the average

Testing

We highly suggest you test these methods by importing them into another file and testing them out there. Also, feel free to create your own super-simple data sets to make it easier to test with! A file with just 3-5 entries is enough to make sure your basic algorithms work!

Note that if you have any print statements (even commented out) in your submission, it will not be graded.

Submission: Please submit one .py file named election_polling.py to the grading system. DO NOT submit any testing files. We only want your election_polling.py file.

POTD 14 - lous_list.py - Due: Wednesday, March 30, 11:00 AM

It’s advising time! Time to start thinking about classes for the Fall! It can be tough to search through the course listings to find the classes you want. So let’s write a program to help you out! (The problem here is that since registration hasn’t started yet, the data for the Fall is kinda boring… so were are going to use data from this semester - Spring 2016.)

Write a library called lous_list.py that will contain two methods that will aid students in finding information about classes.

These methods will all need to read from our online custom Lou’s List interface. For example, if you want to see all the courses in the CS department, can go to:

http://stardock.cs.virginia.edu/louslist/Courses/view/CS

and you’ll see many lines like

1
CS;1110;001;Introduction to Programming;Mark Sherriff;Lecture;3;true;false;true;false;true;1100;1150;Rice Hall 130;148;147;38.031639;-78.510811

if you view the source of the page (Chrome: View->Developer->View Source and Firefox: Tools->Web Developer->Page Source).

By replacing the text after the last / with any department at UVa, you can see their classes! For example, BIOL will load all Biology classes.

For each line on the page, the fields are (in order):

  • Dept ID (0)
  • Course Number (1)
  • Section (2)
  • Course Title (3)
  • Instructor (4)
  • Type of class (5)
  • Hours (6)
  • Monday (7)
  • Tuesday (8)
  • Wednesday (9)
  • Thursday (10)
  • Friday (11)
  • Start Time (12)
  • End Time (13)
  • Location (14)
  • Enrollment (15)
  • Allowable Enrollment (16)
  • Latitude (17)
  • Longitude (18)

Start and end times are expressed in the CSV as a 3- or 4-character string representing a 24-hour clock so, e.g., CS 1112 starts at 1400 and ends at 1515, for a duration of 75 minutes and CS 2150 section 105 starts at 1330 and ends at 1515 for a duration of 105 minutes.

Some sections have a listed start and end time of -1, meaning they do not have a fixed schedule.

instructors(department): Returns a sorted list containing each instructor listed in Lou’s List for the given department. Do not count the same instructor twice. For example, Mark Sherriff is listed as instructor for around 19 courses for the CS department but should only appear in the resulting list once.

To test this function, you should create a separate testing file, just as you did for previous POTDs. If you invoke instructors("EAST") you should get back a list with three elements: [‘Benedetta Lomi’, ‘Michiko Wilson’, ‘Staff’]. Note that the order does matter here. If you invoke instructors("URDU") you should get back a list with one element: [‘Griffith Chaussee’].

class_search(dept_name, has_seats_available=True, level=None, not_before=None, not_after=None): Returns a list of lists which contains all the information for all the classes that meet the provided criteria.

By default, if you invoke class_search("CS"), the function should return a list containing all of the information from all of the CS courses in which there are seats available (Enrollment < Allowable Enrollment). If you invoke class_search("CS", False), then all classes should be displayed, regardless of enrollment. As you add the optional parameters, you can adjust the search even more.

  • has_seats_available - If set to True, the function will check to ensure that Enrollment is not greater than or equal to Allowable Enrollment (i.e. there are seats actually available for a student to take). If set to False then it doesn’t matter if there are seats available or not and current enrollment should be ignored when determining if the class should be returned or not.
  • level - Given a 4-digit level value, the function should only include classes that are at that level. For example, saying level=2000 should limit the list to only courses whose first digit is 2.
  • not_before - Tells the function to exclude all classes that start before (but not at) that time. For example, if you say not_before=1000, then the function should exclude 9:00 and 9:30 classes, but still include 10:00 classes.
  • not_after - Tells the function to exclude all classes that start after (but not at) that time. For example, if you say not_after=1400, then the function should exclude classes that start at 3:00, but not 2:00.

For example, if you invoke class_search("CS", level=1000, not_before=1600) it should return (example formatted to make it easier to read):

1
2
3
4
5
[
   ['CS', '1110', '106', 'Introduction to Programming', 'Mark Sherriff', 'Laboratory', '3', 'false', 'false', 'false', 'true', 'false', '1700', '1815', 'Olsson Hall 001', '0', '44', '38.032079', '-78.510755'], 
   ['CS', '1110', '107', 'Introduction to Programming', 'Mark Sherriff', 'Laboratory', '3', 'false', 'false', 'false', 'true', 'false', '1830', '1945', 'Olsson Hall 001', '0', '44', '38.032079', '-78.510755'], 
   ['CS', '1110', '108', 'Introduction to Programming', 'Mark Sherriff', 'Laboratory', '3', 'false', 'false', 'false', 'true', 'false', '2000', '2115', 'Olsson Hall 001', '0', '44', '38.032079', '-78.510755']
]

Suggested Algorithms: Unlike the previous POTD, you don’t necessarily need to create a separate function to read the website data (although you can if you want). And you don’t have to load all of the data into a data structure. Consider including the code to read the website at the top of each of these methods and then doing your work inside the loop in which you read each line from the website.

Submission: Please submit one .py file named lous_list.py to the grading system.

POTD 15 - email_finder.py - Due: Monday, April 4, 11:00 AM

Have you ever wondered how spammers get all their email addresses to send those lovely messages about foreign princes with banking troubles or the latest and greatest medication for… whatever?

We here in CS 111X want to equip you with the skills to become a spammer yourself! Well, not really, but the techniques used to farm email addresses can be really useful!

The goal of this assignment is to write a program that will scan a web page and harvest as many email addresses as possible. Many of these email address will be obfuscated in some way. It’s up to you to get the computer to figure out how to recognize the obfuscation and return a good result!

Your grade will be based on how many (and what types) of email addresses you can find in the page. We will provide examples of most types of obfuscation, but not necessarily all. Some bonus points may be earned for some really tricky ones.

Here are some examples to get you started (in the form “obfuscated email” => “what your program should interpret the email as”):

Tips

You can read the entire web page line by line to make it easier to search.

1
2
3
4
5
6
7
import urllib.request

stream = urllib.request.urlopen( "https://cs1110.cs.virginia.edu/emails.html" )

for line in stream:
    decoded = line.decode("UTF-8")
    print(decoded.strip())

Once you have a line from the web site, you have a couple different options:

  1. You can manually look for particular symbols by using the in keyword. For example, you could try if "@" in line: to see if there is an @ sign in the line you are looking at. If so, you might want to take a closer look.
  2. You can come up with regular expressions that will look for particular patterns in a line that could be an email address. You can test regular expressions against test data you provide here: http://www.regexr.com/

You cannot use BeautifulSoup for this as most of the email addresses are not within HTML tags that you can identify. So, we’re going to save you some time here and just say don’t try it. Further, the server will just reject your assignment.

No one method or one regular expression will get every email address. As mentioned above, we’ve intentionally put some extremely difficult addresses in the page just to see what you can do!

Your program must implement the following function:

find_emails_in_website(url): This function takes as input a string representation of the URL of a website that you want to search.
We have a page https://cs1110.cs.virginia.edu/emails.html that has a set of example emails you should be able to find (and some that you can look for but we are not requiring). This function should return a list of all of the valid email addresses that you find.

You can create as many other functions as you like, but this is the function that we will call with various different sites to see how well your program works.

For the example page, you should hopefully find:

basic@virginia.edu
link-only@virginia.edu
multi-domain@cs.virginia.edu
Mr.N0body@cand3lwick-burnERS.rentals
a@b.ca
no-at-sign@virginia.edu
no-at-or-dot@virginia.edu
first.last.name@cs.virginia.edu
with-parenthesis@Virginia.EDU
added-words1@virginia.edu
added-words2@virginia.edu
may.end@with-a-period.com

Do not “hardcode” your solutions! In other words, you’re looking for these exact emails, which is not the case. These are examples. To aid in your testing, here’s another page you can look at: https://cs1110.cs.virginia.edu/emails2.html

Here are the emails it should find:

abasicemail@wfu.edu
a-link-only@unc.edu
so-many-domains@ece.berkeley.edu
SomE.CRAZY343@ea.info
w@x.yz
an-at-sign@ncsu.edu
some-other-email@gt.com
so.many.periods@why.do.this
parensarecool@duke.edu
morewords@place.net
extrawords@coolrunnings.ja
period.at@at.the.end

Submission: Submit your file email_finder.py on the project submission page.

NOTE: Make sure to remove all print() statements from your code before submitting. We will not run any tests on any file that still has print() statements in the code!

POTD 16 - first_game.py - Due: Friday, April 15, 11:00 AM

For this POTD, you should take the basic game you created in the gamebox lab and add and improve upon it. You must include at least 4 of the following features for your game. However - the exact game you make is totally up to you!

Your game should be different than your partner’s!!! You can start from the same base code, but try to expand in different ways!

  1. The ability to jump - To do this, set the yspeed to -15 when the user taps the space bar. However, you ONLY want this to work if the character is touching the ground.
  2. Other platforms - Instead of just having ground, create a list of walls (to which you can add ground). Then, you can add more walls and platforms to this list and then have a loop (for wall in walls:) where you check if your character is touching any platform.
  3. Enemy - See if you can make another character that always moves toward your character.
  4. Coins - Add coins to the level that can be picked up by the character with a counter that appears on the screen.
  5. Scrolling level - Make it so you can keep going off the screen! (You may need to add a background image to make this more obvious.)
  6. Timer - Have a countdown (or count up) timer for your game.
  7. Health meter - Have a health meter that changes as you hit enemies/obstacles.
  8. Game start and end - Have a proper start and end to the game, with titles, etc.

You will be able to find gamebox and some example code at https://cs1110.cs.virginia.edu/code/gamebox. We will be adding more example code as we move through POTD 16 and the project.

You should also download and look over the gamebox API and introduction - gamebox.pdf

Submission: Please submit one .py file named first_game.py to the grading system. NOTE: There is no automatic grading for this assignment! We’ll run a few simple tests to make sure you have submitted a “good” file, but you will receive no preliminary feedback!

Partner Project: Building a Game - Due: Friday, April 29, 11:00 AM

Game Project Partner Registration - NOTE: Your partner must be in the same lab as you (or both in 1111)!

Following on from POTD 16, your goal in this partner project is to build a bigger game! You need to use PyGame and gamebox, just as you did before.

However, this time we are letting you build whatever game you want! We will be requiring that you implement at least a basic set of features to ensure that your game is complex enough, but feel free to do more! Be careful you don’t overscope, though! You don’t want to set out to build something too big that you can’t finish it. If you have any questions about the scope of your game, please ask an instructor or TA.

You will be able to find gamebox and all of our example code at https://cs1110.cs.virginia.edu/code/gamebox. We will be adding more example code as we move through POTD 16 and the project.

You should also download and look over the gamebox API and introduction - gamebox.pdf

Required Features:

  1. User Input - Either through the keyboard or mouse, you should have appropriate and working user controls.
  2. Graphics/Images - You should use some appropriate images in your game.
  3. Game start and end - Have a proper start and end to the game, with titles, etc.

Optional Features:

You must implement at least 4 of these:

  1. Animation - Use a sprite sheet to have an animated character.
  2. Enemies - Have characters that can hinder the player character from accomplishing the goal.
  3. Collectables - Add collectables (i.e. coins) to the level that can be picked up by the character with a counter that appears on the screen.
  4. Scrolling level - Make it so you can keep going off the screen! (You may need to add a background image to make this more obvious.)
  5. Timer - Have a countdown (or count up) timer for your game.
  6. Health meter - Have a health meter that changes as you hit enemies/obstacles.
  7. Music/Sound effects - Have some good sound design.
  8. Two players simultaneously - The two players MUST be able to interact directly in some way.

Game Ideas:

Having trouble coming up with a game idea? Try one of these! Or make a variation of one of these!

  • Frogger - Can you get the frog across the road without getting hit by a car? Frogger on SmashingArcade
  • Pac-Man - This classic game is completely reasonable to pull off! Pac-Man on SmashingArcade
  • Infinite Runners - Any basic game where you are running left to right and there are things to jump over, etc.
  • Keep-Away - Build a game where you character has to keep from getting “tagged” by other characters running around the level!

And many, many more! We will add more here in coming days and feel free to ask for suggestions too!

Submission: Unlike all the other submissions, this one needs to go to Collab since you may be turning in images, audio, etc. Make sure you game is called game.py and is in its own folder with all the game assets (images, audio) along with gamebox.py. Zip/archive this entire directory and submit that along with a .txt document describing what your game is, what your features are that you want us to grade, and how to play it. TAs that can’t figure out how to play your game will definitely give you a low score!

ONLY ONE PARTNER SHOULD SUBMIT! PLEASE DO NOT DOUBLE SUBMIT YOUR PROJECT!!!

Partner Evals: Please fill out this evaluation form for your partner!

Current POTD

Upcoming POTDs