Preparing git repo for final project

This commit is contained in:
Davte 2023-07-09 11:19:26 +02:00
parent 6a38966eef
commit 63d06d6b35
Signed by: Davte
GPG Key ID: 70336F92E6814706
67 changed files with 1587 additions and 0 deletions

8
problems/prepare.sh Executable file
View File

@ -0,0 +1,8 @@
#!/usr/bin/bash
this_script_directory=$(cd "$(dirname "${0}")" && pwd);
read -r -p "Enter the name of the next challenge " challengeName;
cd "$this_script_directory";
mkdir "$challengeName";
cd "$challengeName";
code "$challengeName".py
code "test_$challengeName".py

View File

@ -0,0 +1,16 @@
c = 300000000
def compute_energy():
mass = None
while not isinstance(mass, int):
input_string = input("Enter a mass:\t\t")
try:
mass = int(input_string)
except (ValueError, TypeError):
mass = None
print(mass*(c**2))
if __name__ == "__main__":
compute_energy()

View File

@ -0,0 +1,9 @@
def replace_emoticons_with_emojis():
input_string = input("Say something quickly and I will repeat it slowly!\t\t")
for emoticon, emoji in {':)': '🙂', ':(': '🙁'}.items():
input_string = input_string.replace(emoticon, emoji)
print(input_string)
if __name__ == "__main__":
replace_emoticons_with_emojis()

View File

@ -0,0 +1,7 @@
def prompt_user_and_echo_lowercase():
input_string = input("Shout me something and I will repeat it with indoor voice!\t\t")
print(input_string.lower())
if __name__ == "__main__":
prompt_user_and_echo_lowercase()

View File

@ -0,0 +1,7 @@
def prompt_user_and_echo_lowercase():
input_string = input("Say something quickly and I will repeat it slowly!\t\t")
print(input_string.replace(' ', '...'))
if __name__ == "__main__":
prompt_user_and_echo_lowercase()

17
problems/pset0/tip/tip.py Normal file
View File

@ -0,0 +1,17 @@
def main():
dollars = dollars_to_float(input("How much was the meal? "))
percent = percent_to_float(input("What percentage would you like to tip? "))
tip = dollars * percent
print(f"Leave ${tip:.2f}")
def dollars_to_float(d):
return float(d[1:])
def percent_to_float(p):
return float(p[:-1])/100
if __name__ == "__main__":
main()

View File

@ -0,0 +1,12 @@
def main():
greeting = input("Greeting:\t\t").lower().strip()
if greeting.startswith("hello"):
print("$0")
elif greeting.startswith("h"):
print("$20")
else:
print("$100")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,28 @@
import re
answer_regex = re.compile(r"\s*(42|forty[ -]?two)\s*", re.IGNORECASE)
def ifelse_answer():
answer = input("What is the Answer to the Great Question of Life, the Universe, and Everything?\t\t")
answer = answer.strip()
answer = answer.replace('-', '')
answer = answer.replace(' ', '')
answer = answer.lower()
if answer in ('42', 'fortytwo'):
print("Yes")
else:
print("No")
def regex_answer():
print('Yes'
if answer_regex.match(
input("What is the Answer to the Great Question of Life, the Universe, and Everything?\t\t"))
else 'No')
def oneliner():
print({True: 'Yes', False: 'No'}[input("What is the Answer to the Great Question of Life, the Universe, and Everything?\t\t").lower().strip() in ('42', 'fortytwo', 'forty two', 'forty-two')])
if __name__ == "__main__":
regex_answer()

View File

@ -0,0 +1,22 @@
extensions = {
".gif": "image/gif",
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".png": "image/png",
".pdf": "application/pdf",
".txt": "text/plain",
".zip": "application/zip"
}
def main():
file_name = input("Enter file name:\t\t").lower().strip()
for extension, mime in extensions.items():
if file_name.endswith(extension):
print(mime)
break
else:
print("application/octet-stream")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,17 @@
def main():
expression = input("Enter an arithmetic expression:\t\t")
x, y, z = expression.split()
result = 0.0
if y == '+':
result = int(x) + int(z)
elif y == '-':
result = int(x) - int(z)
elif y == '*':
result = int(x) * int(z)
elif y == '/':
result = int(x) / int(z)
print(round(float(result), 1))
if __name__ == "__main__":
main()

View File

@ -0,0 +1,17 @@
def main():
t = convert(input("What time is it?\t\t"))
if 7 <= t <= 8:
print("breakfast time")
elif 12 <= t <= 13:
print("lunch time")
elif 18 <= t <= 19:
print("dinner time")
def convert(time):
h ,m = map(int, time.split(":"))
return float(h + m / 60)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,16 @@
def main():
camel_string = input("camelCase:\t\t")
print(f"snake_case:\t\t{convert_to_snake_case(camel_string)}")
def convert_to_snake_case(s: str):
result = ''
for char in s:
if char == char.upper():
result += '_'
result += char.lower()
return result
if __name__ == "__main__":
main()

View File

@ -0,0 +1,15 @@
def main():
total_coins = 0
while total_coins < 50:
print(f"Amount Due: {50 - total_coins}")
new_coin = input("Insert coin:\t\t")
if new_coin not in ('5', '10', '25'):
new_coin = 0
else:
new_coin = int(new_coin)
total_coins += new_coin
print(f"Change Owed: {total_coins - 50}")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,14 @@
fruits = {'apple': '130', 'avocado': '50', 'banana': '110', 'cantaloupe': '50',
'grapefruit': '60', 'grapes': '90', 'honeydew melon': '50', 'kiwifruit': '90', 'lemon': '15', 'lime': '20',
'nectarine': '60', 'orange': '80', 'peach': '60', 'pear': '100', 'pineapple': '50', 'plums': '70', 'strawberries': '50',
'sweet cherries': '100', 'tangerine': '50', 'watermelon': '80'}
def main():
fruit = input("Item:\t\t").lower()
if fruit in fruits:
print(f"Calories:\t\t{fruits[fruit]}")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,39 @@
import re
def main():
plate = input("Plate: ")
if is_valid(plate):
print("Valid")
else:
print("Invalid")
def is_valid(s):
if len(s) < 2 or len(s) > 6:
return False
return re.match(r"^[A-Z]{2,}([1-9]\d+)?(?![A-Z])$", s)
def loopy_is_valid(s):
length = 0
has_digits = False
for n, c in enumerate(s):
if n > 6:
return False
if not c.isalnum():
return False
if n < 2 and not c.isalpha():
return False
if c.isdigit():
if not has_digits and c == '0':
return False
has_digits = True
elif has_digits:
return False
length += 1
return length >= 2
if __name__ == "__main__":
main()

View File

@ -0,0 +1,11 @@
def main():
tweet = input("Input: \t\t")
result = ''
for c in tweet:
if c.lower() not in ('a', 'e', 'i', 'o', 'u'):
result += c
print(f"Output: {result}")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,21 @@
def main():
while True:
fuel = input("Fraction:\t\t")
try:
x, y = map(int, fuel.split('/'))
if x > y:
continue
result = x / y
break
except (ValueError, ZeroDivisionError):
continue
if result <= 0.01:
print("E")
elif result >= 0.99:
print("F")
else:
print(f"{int(round(result*100, 0))}%")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,16 @@
def main():
shopping_list = {}
while True:
try:
item = input("").upper()
except EOFError:
break
if item not in shopping_list:
shopping_list[item] = 0
shopping_list[item] += 1
for item, quantity in sorted(shopping_list.items(), key=lambda x: x[0]):
print(f"{quantity} {item}")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,41 @@
import re
months = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
]
def main():
while True:
try:
entered_date = input("Date: ").strip()
except Exception:
continue
if re.match(r"\d+/\d+/\d+", entered_date):
month, day, year = map(int, entered_date.split('/'))
elif re.match(r"\w+ \d{1,2}, \d{4}", entered_date):
entered_date = entered_date.replace(",", "")
month, day, year = entered_date.split(' ')
month = months.index(month) + 1
day, year = map(int, (day, year))
else:
continue
if month > 12 or day > 31:
continue
break
print(f"{year:04d}-{month:02d}-{day:02d}")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,27 @@
menu = {
"Baja Taco": 4.00,
"Burrito": 7.50,
"Bowl": 8.50,
"Nachos": 11.00,
"Quesadilla": 8.50,
"Super Burrito": 8.50,
"Super Quesadilla": 9.50,
"Taco": 3.00,
"Tortilla Salad": 8.00
}
def main():
total = 0.0
while True:
try:
dish = input("Item: :\t\t").title()
except EOFError:
break
if dish in menu:
total += menu[dish]
print(f"Total: ${total:.2f}")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,25 @@
def main():
names = []
while True:
try:
name = input("Name: ")
names.append(name)
except EOFError:
break
if len(names) == 0:
return
result = "Adieu, adieu, to "
for n, name in enumerate(names):
if n == 0:
result += name
elif n == 1 and len(names) == 2:
result += f" and {name}"
elif n == len(names) - 1:
result += f", and {name}"
else:
result += f", {name}"
print(result)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,24 @@
import json
import requests
import sys
def main():
try:
n = float(sys.argv[1])
except IndexError:
sys.exit("Missing command-line argument")
except (ValueError, TypeError):
sys.exit("Command-line argument is not a number")
try:
response = requests.get("https://api.coindesk.com/v1/bpi/currentprice.json")
data = response.json()
conversion_rate = float(data['bpi']['USD']['rate'].replace(',', ''))
except requests.RequestException:
pass
print(f"${n * conversion_rate:,.4f}")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,10 @@
import emoji
def main():
input_text = input("Input: ").strip()
print(emoji.emojize(emoji.emojize(input_text, language='alias'), language='en'))
if __name__ == "__main__":
main()

View File

@ -0,0 +1,24 @@
import sys
from pyfiglet import Figlet
figlet = Figlet()
def main():
if len(sys.argv) > 1:
if len(sys.argv) != 3:
sys.exit("This script takes 2 or no command-line arguments")
if sys.argv[1] not in ('-f', '--font'):
sys.exit(f"Unknown option `{sys.argv[1]}`")
available_fonts = figlet.getFonts()
font = sys.argv[2]
if font not in available_fonts:
sys.exit(f"Unknown font `{sys.argv[2]}`")
figlet.setFont(font=font)
input_text = input("Input: ")
print(figlet.renderText(input_text))
if __name__ == "__main__":
main()

View File

@ -0,0 +1,28 @@
import random
def main():
n = -1
while n < 1:
try:
n = int(input("Level: "))
except (TypeError, ValueError):
continue
random.seed()
n_to_guess = random.randint(1, n)
guess = -1
while n_to_guess - guess != 0:
try:
guess = int(input("Guess: "))
except (TypeError, ValueError):
continue
if guess == n_to_guess:
print("Just right!")
if guess < n_to_guess:
print("Too small!")
if guess > n_to_guess:
print("Too large!")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,43 @@
import random
def main():
# random.seed() # This breaks check50 😠
score = 0
level = get_level()
for _ in range(10):
x = generate_integer(level)
y = generate_integer(level)
for _ in range(3):
try:
answer = int(input(f"{x} + {y} ="))
except (ValueError, TypeError):
answer = -1
if answer == x + y:
score += 1
break
else:
print("EEE")
else:
print(f"{x} + {y} = {x + y}")
print(f"Score: {score}")
def get_level():
level = 0
while level not in (1, 2, 3):
try:
level = int(input("Level: "))
except (ValueError, TypeError):
level = 0
return level
def generate_integer(level):
if level not in (1, 2, 3):
raise ValueError
return random.randint((10**(level - 1) if level > 1 else 0), 10**level - 1)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,17 @@
def main():
greeting = input("Greeting:\t\t")
print(value(f"${greeting}"))
def value(greeting: str) -> str:
greeting = greeting.lower().strip()
if greeting.startswith("hello"):
return 0
elif greeting.startswith("h"):
return 20
else:
return 100
if __name__ == "__main__":
main()

View File

@ -0,0 +1,77 @@
from bank import value
def main():
test_lower()
test_upper()
test_title_case()
test_mixed_case()
test_zero()
test_twenty()
test_empty()
test_hundred()
test_containing_hello()
def test_lower():
assert value('hello') == 0
assert value('hey') == 20
assert value('banana') == 100
def test_upper():
assert value('HELLO') == 0
assert value('HEY') == 20
assert value('BANANA') == 100
def test_title_case():
assert value('Hello') == 0
assert value('Hey') == 20
assert value('Banana') == 100
def test_mixed_case():
assert value('Hello') == 0
assert value('Hey') == 20
assert value('Banana') == 100
def test_zero():
assert value('Hello') == 0
assert value('hello') == 0
assert value('HELLO') == 0
assert value('HeLlO') == 0
assert value('hElLo') == 0
def test_twenty():
assert value('Hey') == 20
assert value('hey') == 20
assert value('HEY') == 20
assert value('HeY') == 20
assert value('hEy') == 20
assert value('h') == 20
assert value('h20') == 20
def test_empty():
assert value('') == 100
def test_hundred():
assert value('Banana') == 100
assert value('banana') == 100
assert value('BANANA') == 100
assert value('12345678') == 100
assert value('nothello') == 100
def test_containing_hello():
assert value('aHello') == 100
assert value('ahello') == 100
assert value('aHELLO') == 100
assert value('aHeLlO') == 100
assert value('ahElLo') == 100
if __name__ == "__main__":
main()

View File

@ -0,0 +1,35 @@
def main():
while True:
fuel = input("Fraction:\t\t")
try:
result = convert(fuel)
break
except (ValueError, ZeroDivisionError):
continue
print(gauge(result))
def convert(fraction: str) -> int:
try:
x, y = map(int, fraction.split('/'))
except (ValueError, TypeError):
raise ValueError
if x > y:
raise ValueError
if y == 0:
raise ZeroDivisionError
return int(round(x / y*100, 0))
def gauge(percentage):
if percentage <= 1:
return "E"
elif percentage >= 99:
return "F"
else:
return f"{percentage}%"
if __name__ == "__main__":
main()

View File

@ -0,0 +1,41 @@
from fuel import convert, gauge
def main():
test_convert()
test_gauge()
test_value_error()
test_zero_division_error()
def test_convert():
assert convert("0/4") == 0
assert convert("1/4") == 25
assert convert("4/4") == 100
def test_value_error():
try:
convert("5/4")
except ValueError:
pass
else:
raise Exception("ValueError not raised with y>x")
def test_zero_division_error():
try:
convert("5/0")
except ZeroDivisionError:
pass
else:
raise Exception("ZeroDivisionError not raised with y = 0")
def test_gauge():
assert gauge(100) == 'F'
assert gauge(99) == 'F'
assert gauge(0) == 'E'
assert gauge(1) == 'E'
assert gauge(27) == '27%'
if __name__ == '__main__':
main()

View File

@ -0,0 +1,39 @@
import re
def main():
plate = input("Plate: ")
if is_valid(plate):
print("Valid")
else:
print("Invalid")
def is_valid(s):
if len(s) < 2 or len(s) > 6:
return False
return re.match(r"^[A-Z]{2,}([1-9]\d+)?(?![A-Z])$", s) is not None
def loopy_is_valid(s):
length = 0
has_digits = False
for n, c in enumerate(s):
if n > 6:
return False
if not c.isalnum():
return False
if n < 2 and not c.isalpha():
return False
if c.isdigit():
if not has_digits and c == '0':
return False
has_digits = True
elif has_digits:
return False
length += 1
return length >= 2
if __name__ == "__main__":
main()

View File

@ -0,0 +1,39 @@
from plates import is_valid
def main():
test_incipit()
test_length()
test_digits()
test_forbidden_characters()
def test_incipit():
assert is_valid('11AA11') == False
assert is_valid('11AA') == False
assert is_valid('1AA2') == False
assert is_valid('2AAP') == False
assert is_valid('A1111') == False
assert is_valid('AA1111') == True
def test_length():
assert is_valid('') == False
assert is_valid('A') == False
assert is_valid('AAAAAA111111') == False
def test_digits():
assert is_valid('AA111A') == False
assert is_valid('AA0111') == False
def test_forbidden_characters():
assert is_valid('AA1.1') == False
assert is_valid('AA1,1') == False
assert is_valid('AA1 1') == False
assert is_valid('AA11!') == False
if __name__ == "__main__":
main()

View File

@ -0,0 +1,33 @@
from twttr import shorten
def main():
test_uppercase()
test_lowercase()
test_null()
test_digits()
test_punctuation()
def test_uppercase():
assert shorten('TWITTER') == 'TWTTR'
def test_lowercase():
assert shorten('twitter') == 'twttr'
def test_null():
assert shorten('') == ''
def test_digits():
assert shorten('abc123') == 'bc123'
def test_punctuation():
assert shorten('abc,') == 'bc,'
if __name__ == "__main__":
main()

View File

@ -0,0 +1,16 @@
def main():
tweet = input("Input: \t\t")
result = shorten(tweet)
print(f"Output: {result}")
def shorten(word: str) -> str:
result = ''
for c in word:
if c.lower() not in ('a', 'e', 'i', 'o', 'u'):
result += c
return result
if __name__ == "__main__":
main()

View File

@ -0,0 +1,33 @@
import os
import sys
def main():
try:
file_name = sys.argv[1]
except IndexError:
print("Provide a file name from command line!")
sys.exit(1)
if len(sys.argv) > 2:
print("Too many command-line arguments")
sys.exit(1)
if not os.path.isfile(file_name): # Or try opening and catch FileNotFoundError
print(f"The file `{file_name}` does not exist!")
sys.exit(1)
if not file_name.endswith('.py'):
print(f"The file `{file_name}` is not a python script (does not end with the proper suffix)!")
sys.exit(1)
line_count = count_lines(file_name)
print(line_count)
def count_lines(file_name: str) -> int:
line_count = 0
with open(file_name, 'r') as file_object:
for line in file_object:
if len(line.strip()) > 0 and not line.strip().startswith('#'):
line_count += 1
return line_count
if __name__ == "__main__":
main()

View File

@ -0,0 +1,13 @@
from lines import count_lines
def main():
test_count_lines()
def test_count_lines():
assert count_lines('lines.py') == 28
if __name__ == "__main__":
main()

View File

@ -0,0 +1,39 @@
import csv
import os
import sys
import tabulate
def main():
try:
file_name = sys.argv[1]
except IndexError:
print("Too few command-line arguments")
sys.exit(1)
if len(sys.argv) > 2:
print("Too many command-line arguments")
sys.exit(1)
if not os.path.isfile(file_name): # Or try opening and catch FileNotFoundError
print(f"File does not exist")
sys.exit(1)
if not file_name.endswith('.csv'):
print(f"Not a CSV file")
sys.exit(1)
grid = get_grid_from_csv(file_name)
print(grid)
def get_grid_from_csv(file_name: str) -> str:
headers = None
table = []
with open(file_name, 'r') as file_object:
reader = csv.DictReader(file_object)
for row in reader:
if headers is None:
headers = list(row.keys())
table.append(tuple(row[field] for field in row))
return tabulate.tabulate(table, headers, tablefmt="grid")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,6 @@
Regular Pizza,Small,Large
Cheese,$13.50,$18.95
1 topping,$14.75,$20.95
2 toppings,$15.95,$22.95
3 toppings,$16.95,$24.95
Special,$18.50,$26.95
1 Regular Pizza Small Large
2 Cheese $13.50 $18.95
3 1 topping $14.75 $20.95
4 2 toppings $15.95 $22.95
5 3 toppings $16.95 $24.95
6 Special $18.50 $26.95

View File

@ -0,0 +1,54 @@
first,last,house
Hannah,Abbott,Hufflepuff
Katie,Bell,Gryffindor
Susan,Bones,Hufflepuff
Terry,Boot,Ravenclaw
Lavender,Brown,Gryffindor
Millicent,Bulstrode,Slytherin
Cho,Chang,Ravenclaw
Penelope,Clearwater,Ravenclaw
Vincent,Crabbe,Slytherin
Colin,Creevey,Gryffindor
Dennis,Creevey,Gryffindor
Cedric,Diggory,Hufflepuff
Marietta,Edgecombe,Ravenclaw
Justin,Finch-Fletchley,Hufflepuff
Seamus,Finnigan,Gryffindor
Anthony,Goldstein,Ravenclaw
Gregory,Goyle,Slytherin
Hermione,Granger,Gryffindor
Angelina,Johnson,Gryffindor
Lee,Jordan,Gryffindor
Neville,Longbottom,Gryffindor
Luna,Lovegood,Ravenclaw
Remus,Lupin,Gryffindor
Draco,Malfoy,Slytherin
Scorpius,Malfoy,Slytherin
Ernie,Macmillan,Hufflepuff
Minerva,McGonagall,Gryffindor
Eloise,Midgen,Gryffindor
Cormac,McLaggen,Gryffindor
Graham,Montague,Slytherin
Theodore,Nott,Slytherin
Pansy,Parkinson,Slytherin
Padma,Patil,Gryffindor
Parvati,Patil,Gryffindor
Harry,Potter,Gryffindor
Tom,Riddle,Slytherin
Demelza,Robins,Gryffindor
Newt,Scamander,Hufflepuff
Horace,Slughorn,Slytherin
Zacharias,Smith,Hufflepuff
Severus,Snape,Slytherin
Alicia,Spinnet,Gryffindor
Pomona,Sprout,Hufflepuff
Dean,Thomas,Gryffindor
Romilda,Vane,Gryffindor
Myrtle,Warren,Ravenclaw
Fred,Weasley,Gryffindor
George,Weasley,Gryffindor
Ginny,Weasley,Gryffindor
Percy,Weasley,Gryffindor
Ron,Weasley,Gryffindor
Oliver,Wood,Gryffindor
Blaise,Zabini,Slytherin
1 first last house
2 Hannah Abbott Hufflepuff
3 Katie Bell Gryffindor
4 Susan Bones Hufflepuff
5 Terry Boot Ravenclaw
6 Lavender Brown Gryffindor
7 Millicent Bulstrode Slytherin
8 Cho Chang Ravenclaw
9 Penelope Clearwater Ravenclaw
10 Vincent Crabbe Slytherin
11 Colin Creevey Gryffindor
12 Dennis Creevey Gryffindor
13 Cedric Diggory Hufflepuff
14 Marietta Edgecombe Ravenclaw
15 Justin Finch-Fletchley Hufflepuff
16 Seamus Finnigan Gryffindor
17 Anthony Goldstein Ravenclaw
18 Gregory Goyle Slytherin
19 Hermione Granger Gryffindor
20 Angelina Johnson Gryffindor
21 Lee Jordan Gryffindor
22 Neville Longbottom Gryffindor
23 Luna Lovegood Ravenclaw
24 Remus Lupin Gryffindor
25 Draco Malfoy Slytherin
26 Scorpius Malfoy Slytherin
27 Ernie Macmillan Hufflepuff
28 Minerva McGonagall Gryffindor
29 Eloise Midgen Gryffindor
30 Cormac McLaggen Gryffindor
31 Graham Montague Slytherin
32 Theodore Nott Slytherin
33 Pansy Parkinson Slytherin
34 Padma Patil Gryffindor
35 Parvati Patil Gryffindor
36 Harry Potter Gryffindor
37 Tom Riddle Slytherin
38 Demelza Robins Gryffindor
39 Newt Scamander Hufflepuff
40 Horace Slughorn Slytherin
41 Zacharias Smith Hufflepuff
42 Severus Snape Slytherin
43 Alicia Spinnet Gryffindor
44 Pomona Sprout Hufflepuff
45 Dean Thomas Gryffindor
46 Romilda Vane Gryffindor
47 Myrtle Warren Ravenclaw
48 Fred Weasley Gryffindor
49 George Weasley Gryffindor
50 Ginny Weasley Gryffindor
51 Percy Weasley Gryffindor
52 Ron Weasley Gryffindor
53 Oliver Wood Gryffindor
54 Blaise Zabini Slytherin

View File

@ -0,0 +1,54 @@
name,house
"Abbott, Hannah",Hufflepuff
"Bell, Katie",Gryffindor
"Bones, Susan",Hufflepuff
"Boot, Terry",Ravenclaw
"Brown, Lavender",Gryffindor
"Bulstrode, Millicent",Slytherin
"Chang, Cho",Ravenclaw
"Clearwater, Penelope",Ravenclaw
"Crabbe, Vincent",Slytherin
"Creevey, Colin",Gryffindor
"Creevey, Dennis",Gryffindor
"Diggory, Cedric",Hufflepuff
"Edgecombe, Marietta",Ravenclaw
"Finch-Fletchley, Justin",Hufflepuff
"Finnigan, Seamus",Gryffindor
"Goldstein, Anthony",Ravenclaw
"Goyle, Gregory",Slytherin
"Granger, Hermione",Gryffindor
"Johnson, Angelina",Gryffindor
"Jordan, Lee",Gryffindor
"Longbottom, Neville",Gryffindor
"Lovegood, Luna",Ravenclaw
"Lupin, Remus",Gryffindor
"Malfoy, Draco",Slytherin
"Malfoy, Scorpius",Slytherin
"Macmillan, Ernie",Hufflepuff
"McGonagall, Minerva",Gryffindor
"Midgen, Eloise",Gryffindor
"McLaggen, Cormac",Gryffindor
"Montague, Graham",Slytherin
"Nott, Theodore",Slytherin
"Parkinson, Pansy",Slytherin
"Patil, Padma",Gryffindor
"Patil, Parvati",Gryffindor
"Potter, Harry",Gryffindor
"Riddle, Tom",Slytherin
"Robins, Demelza",Gryffindor
"Scamander, Newt",Hufflepuff
"Slughorn, Horace",Slytherin
"Smith, Zacharias",Hufflepuff
"Snape, Severus",Slytherin
"Spinnet, Alicia",Gryffindor
"Sprout, Pomona",Hufflepuff
"Thomas, Dean",Gryffindor
"Vane, Romilda",Gryffindor
"Warren, Myrtle",Ravenclaw
"Weasley, Fred",Gryffindor
"Weasley, George",Gryffindor
"Weasley, Ginny",Gryffindor
"Weasley, Percy",Gryffindor
"Weasley, Ron",Gryffindor
"Wood, Oliver",Gryffindor
"Zabini, Blaise",Slytherin
1 name house
2 Abbott, Hannah Hufflepuff
3 Bell, Katie Gryffindor
4 Bones, Susan Hufflepuff
5 Boot, Terry Ravenclaw
6 Brown, Lavender Gryffindor
7 Bulstrode, Millicent Slytherin
8 Chang, Cho Ravenclaw
9 Clearwater, Penelope Ravenclaw
10 Crabbe, Vincent Slytherin
11 Creevey, Colin Gryffindor
12 Creevey, Dennis Gryffindor
13 Diggory, Cedric Hufflepuff
14 Edgecombe, Marietta Ravenclaw
15 Finch-Fletchley, Justin Hufflepuff
16 Finnigan, Seamus Gryffindor
17 Goldstein, Anthony Ravenclaw
18 Goyle, Gregory Slytherin
19 Granger, Hermione Gryffindor
20 Johnson, Angelina Gryffindor
21 Jordan, Lee Gryffindor
22 Longbottom, Neville Gryffindor
23 Lovegood, Luna Ravenclaw
24 Lupin, Remus Gryffindor
25 Malfoy, Draco Slytherin
26 Malfoy, Scorpius Slytherin
27 Macmillan, Ernie Hufflepuff
28 McGonagall, Minerva Gryffindor
29 Midgen, Eloise Gryffindor
30 McLaggen, Cormac Gryffindor
31 Montague, Graham Slytherin
32 Nott, Theodore Slytherin
33 Parkinson, Pansy Slytherin
34 Patil, Padma Gryffindor
35 Patil, Parvati Gryffindor
36 Potter, Harry Gryffindor
37 Riddle, Tom Slytherin
38 Robins, Demelza Gryffindor
39 Scamander, Newt Hufflepuff
40 Slughorn, Horace Slytherin
41 Smith, Zacharias Hufflepuff
42 Snape, Severus Slytherin
43 Spinnet, Alicia Gryffindor
44 Sprout, Pomona Hufflepuff
45 Thomas, Dean Gryffindor
46 Vane, Romilda Gryffindor
47 Warren, Myrtle Ravenclaw
48 Weasley, Fred Gryffindor
49 Weasley, George Gryffindor
50 Weasley, Ginny Gryffindor
51 Weasley, Percy Gryffindor
52 Weasley, Ron Gryffindor
53 Wood, Oliver Gryffindor
54 Zabini, Blaise Slytherin

View File

@ -0,0 +1,7 @@
name,house
"Abbott, Hannah",Hufflepuff
"Bell, Katie",Gryffindor
"Bones, Susan",Hufflepuff
"Boot, Terry",Ravenclaw
"Brown, Lavender",Gryffindor
"Bulstrode, Millicent",Slytherin
1 name house
2 Abbott, Hannah Hufflepuff
3 Bell, Katie Gryffindor
4 Bones, Susan Hufflepuff
5 Boot, Terry Ravenclaw
6 Brown, Lavender Gryffindor
7 Bulstrode, Millicent Slytherin

View File

@ -0,0 +1,5 @@
first,last,house
Susan,Bones,Hufflepuff
Terry,Boot,Ravenclaw
Lavender,Brown,Gryffindor
Millicent,Bulstrode,Slytherin
1 first last house
2 Susan Bones Hufflepuff
3 Terry Boot Ravenclaw
4 Lavender Brown Gryffindor
5 Millicent Bulstrode Slytherin

View File

@ -0,0 +1,42 @@
import csv
import os
import sys
def main():
try:
input_file_name, output_file_name = sys.argv[1:3]
except IndexError:
print("Too few command-line arguments")
sys.exit(1)
if len(sys.argv) > 3:
print("Too many command-line arguments")
sys.exit(1)
if not os.path.isfile(input_file_name): # Or try opening and catch FileNotFoundError
print(f"Could not read {input_file_name}")
sys.exit(1)
if not input_file_name.endswith('.csv'):
print(f"Not a CSV file")
sys.exit(1)
write_names_to_csv_file(read_names_from_csv_file(input_file_name), output_file_name)
def read_names_from_csv_file(input_file_name):
with open(input_file_name, 'r') as input_file:
reader = csv.DictReader(input_file)
for row in reader:
yield row
def write_names_to_csv_file(input_data, output_file_name):
with open(output_file_name, 'w') as output_file:
writer = csv.DictWriter(output_file, fieldnames=['first', 'last', 'house'])
writer.writeheader()
for row in input_data:
row['last'], row['first'] = row['name'].split(', ')
del row['name']
writer.writerow(row)
if __name__ == "__main__":
main()

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 980 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -0,0 +1,43 @@
import os
import sys
import PIL
from PIL import Image
def main():
try:
input_file_name, output_file_name = sys.argv[1:3]
except (IndexError, ValueError):
print("Too few command-line arguments")
sys.exit(1)
if len(sys.argv) > 3:
print("Too many command-line arguments")
sys.exit(1)
if not os.path.isfile(input_file_name): # Or try opening and catch FileNotFoundError
print(f"Input does not exist")
sys.exit(1)
if not (any(input_file_name.lower().endswith(format) for format in (".jpg", ".jpeg", ".png")) and any(output_file_name.lower().endswith(format) for format in (".jpg", ".jpeg", ".png"))):
print(f"Invalid input")
sys.exit(1)
if (input_file_name[-4] == '.' and input_file_name[-4:] != output_file_name[-4:]) or (input_file_name[-3] == '.' and input_file_name[-3:] != output_file_name[-3:]):
print(f"Input and output have different extensions")
sys.exit(1)
overlap_t_shirt(input_file_name, output_file_name)
"""Open the input with Image.open, per pillow.
resize and crop the input with ImageOps.fit, per pillow.readthedocs.io/en/stable/reference/ImageOps.html#PIL.ImageOps.fit,
using default values for method, bleed, and centering, overlay the shirt with Image.paste,
per pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.paste,
and save the result with Image.save, per pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.save."""
def overlap_t_shirt(input_file_name, output_file_name):
image = Image.open(input_file_name)
shirt = Image.open('shirt.png')
image = PIL.ImageOps.fit(image, size=shirt.size)
image.paste(shirt, mask=shirt)
image.save(output_file_name)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,19 @@
import re
import sys
def main():
print(validate(input("IPv4 Address: ")))
def validate(ip):
if not re.match(r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$', ip):
return False
for n in map(int, ip.split('.')):
if not 0 <= n <= 255:
return False
return True
if __name__ == "__main__":
main()

View File

@ -0,0 +1,32 @@
from numb3rs import validate
def main():
test_non_digits()
test_negative_numbers()
test_numbers_too_big()
test_numbers_too_long()
def test_non_digits():
assert validate('aaa.bbb.ccc.ddd') == False
assert validate('cat') == False
def test_negative_numbers():
assert validate('-11.111.-1.-1') == False
def test_numbers_too_big():
assert validate('257.200.1.1') == False
assert validate('200.257.1.1') == False
assert validate('200.1.257.1') == False
assert validate('200.1.5.257') == False
def test_numbers_too_long():
assert validate('200.1.5.2.57') == False
if __name__ == '__main__':
main()

View File

@ -0,0 +1,23 @@
from validator_collection import validators
def main():
if validate_email(input("What's your email address?\t\t")):
print("Valid")
else:
print("Invalid")
def validate_email(email: str) -> bool:
try:
email_address = validators.email(email, allow_empty = True)
except Exception as e:
email_address = None
if not email_address:
return False
return True
if __name__ == '__main__':
main()

View File

@ -0,0 +1,16 @@
from response import validate_email
def main():
test_cs50p()
def test_cs50p():
assert validate_email("malan@harvard.edu")== True
assert validate_email("info@cheznadi.com")== True
assert validate_email("malan@@@harvard.edu")== False
assert validate_email("info@cheznadi..com")== False
if __name__ == "__main__":
main()

View File

@ -0,0 +1,37 @@
from um import count
def main():
test_count_ums()
test_words_containing_ums()
test_punctuation()
test_from_cs50p()
def test_count_ums():
assert count("Hello, um, world") == 1
assert count("Hello um, um, world um") == 3
assert count("Um Hello, um, world um") == 3
def test_words_containing_ums():
assert count("instrumentation") == 0
assert count("umbrella") == 0
assert count("momentum") == 0
def test_punctuation():
assert count("Hello um?") == 1
assert count("Hello um!") == 1
assert count("Hello um") == 1
assert count("Hello um.") == 1
def test_from_cs50p():
assert count("um") == 1
assert count("um?") == 1
assert count("Um, thanks for the album.") == 1
assert count("Um, thanks, um...") == 2
if __name__ == '__main__':
main()

15
problems/pset7/um/um.py Normal file
View File

@ -0,0 +1,15 @@
import re
um_regex = re.compile(r"\bum\b", re.IGNORECASE)
def main():
print(count(input("Text: ")))
def count(s):
return len(um_regex.findall(s))
if __name__ == "__main__":
main()

View File

@ -0,0 +1,20 @@
import re
youtube_regex = re.compile(r"<iframe.*https?://(?:www\.)?youtube\.com/embed/(\w+).*</iframe>")
def main():
print(parse(input("HTML: ")))
def parse(s):
video_id = youtube_regex.search(s)
if video_id:
video_id = video_id.groups()[0]
else:
return None
return f"https://youtu.be/{video_id}"
if __name__ == "__main__":
main()

View File

@ -0,0 +1,102 @@
import pytest
from working import convert
def main():
test_missing_to()
test_out_of_range_times()
test_exception()
test_hours_off_by_one()
def test_missing_to():
try:
convert('09:00 AM - 05:00 PM')
except ValueError:
pass
else:
raise ValueError("Missing to")
try:
convert('09:00 AM 05:00 PM')
except Exception as e:
assert isinstance(e, ValueError)
def test_out_of_range_times():
try:
convert('09:00 AM to 05:61 PM')
except Exception as e:
assert isinstance(e, ValueError)
try:
convert('31:00 AM to 05:00 PM')
except Exception as e:
assert isinstance(e, ValueError)
try:
convert('13:00 PM to 8:00 AM')
except Exception as e:
assert isinstance(e, ValueError)
try:
convert('13:00PM to 8:00 AM')
except Exception as e:
assert isinstance(e, ValueError)
try:
convert('13:00 to 8:00')
except Exception as e:
assert isinstance(e, ValueError)
try:
convert("09:00 AM - 17:00 PM")
except Exception as e:
assert isinstance(e, ValueError)
try:
convert("9:00 AM 5:00 PM")
except Exception as e:
assert isinstance(e, ValueError)
try:
convert("9:60 AM to 5:60 PM")
except Exception as e:
assert isinstance(e, ValueError)
try:
convert("9 AM - 5 PM")
except Exception as e:
assert isinstance(e, ValueError)
try:
convert("9 AM5 PM")
except Exception as e:
assert isinstance(e, ValueError)
try:
convert("9 AM 5 PM")
except Exception as e:
assert isinstance(e, ValueError)
with pytest.raises(ValueError):
convert("9:72 to 6:30")
def test_exception():
with pytest.raises(ValueError):
convert("09:00 AM - 17:00 PM")
with pytest.raises(ValueError):
convert("9:00 AM 5:00 PM")
with pytest.raises(ValueError):
convert("9:60 AM to 5:60 PM")
with pytest.raises(ValueError):
convert("9 AM - 5 PM")
with pytest.raises(ValueError):
convert("9 AM5 PM")
with pytest.raises(ValueError):
convert("9 AM 5 PM")
with pytest.raises(ValueError):
convert("9:72 to 6:30")
def test_hours_off_by_one():
assert convert('12:00 AM to 12:00 PM') == "00:00 to 12:00"
assert convert("9 AM to 5 PM") == "09:00 to 17:00"
assert convert("8 PM to 8 AM") == "20:00 to 08:00"
assert convert("8:00 PM to 8:00 AM") == "20:00 to 08:00"
assert convert("12 AM to 12 PM") == "00:00 to 12:00"
assert convert("12:00 AM to 12:00 PM") == "00:00 to 12:00"
if __name__ == '__main__':
main()

View File

@ -0,0 +1,39 @@
import re
american_time_regex = re.compile(r"^\s*(\d+)(?:\:(\d{2}))? ([AP])M to (\d+)(?:\:(\d{2}))? ([AP])\s*M$")
def main():
print(convert(input("Hours: ")))
def convert(s):
time = american_time_regex.match(s)
if time is None:
raise ValueError("Invalid input time")
if len(time.groups()) == 4:
start_h, start_ampm, end_h, end_ampm = time.groups()
start_m, end_m = 0, 0
else:
start_h, start_m, start_ampm, end_h, end_m, end_ampm = time.groups()
start_m, end_m = map(lambda x: int(x) if x else 0, (start_m, end_m))
start_h, end_h = map(int, (start_h, end_h))
if start_h > 12 or end_h > 12:
raise ValueError
if (start_ampm == 'P' and start_h != 12) or (start_ampm == 'A' and start_h == 12):
start_h += 12
if (end_ampm == 'P' and end_h != 12) or (end_ampm == 'A' and end_h == 12):
end_h += 12
if start_h > 24 or end_h > 24 or start_m > 59 or end_m > 59:
raise ValueError
start_h = start_h % 24
end_h = end_h % 24
return f"{start_h:0>2}:{start_m:0>2} to {end_h:0>2}:{end_m:0>2}"
...
if __name__ == "__main__":
main()

26
problems/pset8/jar/jar.py Normal file
View File

@ -0,0 +1,26 @@
class Jar:
def __init__(self, capacity=12):
if not isinstance(capacity, int) or capacity < 0:
raise ValueError("Invalid capacity")
self._capacity = capacity
self._size = 0
def __str__(self):
return '🍪' * self.size
def deposit(self, n):
new_size = n + self.size
if new_size > self.capacity or new_size < 0:
raise ValueError("Exceeded capacity")
self._size += n
def withdraw(self, n):
return self.deposit(-n)
@property
def capacity(self):
return self._capacity
@property
def size(self):
return self._size

View File

@ -0,0 +1,46 @@
from jar import Jar
def main():
test_capacity()
test_size()
test_deposit()
test_withdraw()
def test_capacity():
j = Jar(capacity=3)
assert j.capacity == 3
def test_size():
j = Jar(capacity=5)
assert j.size == 0
j.deposit(3)
j.withdraw(1)
assert j.size == 2
def test_deposit():
j = Jar(capacity=5)
j.deposit(3)
try:
j.deposit(3)
raise Exception("Deposit n > capacity did not raise ValueError")
except Exception as e:
assert isinstance(e, ValueError)
def test_withdraw():
j = Jar(capacity=5)
j.deposit(3)
j.withdraw(2)
try:
j.withdraw(2)
raise Exception("Withdraw n > size did not raise ValueError")
except Exception as e:
assert isinstance(e, ValueError)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,39 @@
import datetime
import re
import sys
import inflect
date_regex = re.compile(r"\d{4}-\d{2}-\d{2}")
p = inflect.engine()
def main():
today = datetime.date.today()
users_date = input("Date of Birth: ")
try:
users_date = parse_date(users_date)
except ValueError:
sys.exit(1)
minutes = get_minutes(users_date, today)
print(format_minutes(minutes))
def get_minutes(start_date, end_date):
minutes = (end_date - start_date).total_seconds() / 60
return int(round(minutes, 0))
def format_minutes(minutes: int) -> str:
stringed_number = p.number_to_words(minutes, andword="").capitalize()
return f"{stringed_number} minute{'s' if minutes > 1 else ''}"
def parse_date(date_string):
if not date_regex.match(date_string): # Acutally not necessary: strptime would raise ValueError anyway
raise ValueError
return datetime.datetime.strptime(date_string, '%Y-%m-%d').date()
if __name__ == '__main__':
main()

View File

@ -0,0 +1,44 @@
from seasons import format_minutes, parse_date
def main():
test_format_minutes()
test_invalid_dates()
test_known_intervals()
def test_format_minutes():
assert format_minutes(1) == 'One minute'
assert format_minutes(2) == 'Two minutes'
def test_invalid_dates():
try:
parse_date('91-5-9')
raise Exception
except Exception as e:
assert isinstance(e, ValueError)
try:
parse_date('cacao')
raise Exception
except Exception as e:
assert isinstance(e, ValueError)
try:
parse_date('1991-13-09')
raise Exception
except Exception as e:
assert isinstance(e, ValueError)
try:
parse_date('1991-11-40')
raise Exception
except Exception as e:
assert isinstance(e, ValueError)
def test_known_intervals():
assert format_minutes(525600) == "Five hundred twenty-five thousand, six hundred minutes"
assert format_minutes(1051200) == "One million, fifty-one thousand, two hundred minutes"
if __name__ == '__main__':
main()

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -0,0 +1,22 @@
from fpdf import FPDF
def main():
username = input("What's your name?\t\t")
pdf = FPDF(orientation="P", unit="mm", format="A4")
pdf.set_auto_page_break(False)
pdf.add_page()
pdf.set_font("helvetica", "B", 45)
pdf.cell(0, 10, 'CS50 Shirtificate', new_x="LMARGIN", new_y="NEXT", align='C')
page_width = pdf.w
total_horizontal_margin = 0.2 * page_width
image_width = pdf.w-total_horizontal_margin
pdf.image("shirtificate.png", x=total_horizontal_margin/2, y=50, w=image_width)
pdf.set_font("helvetica", "B", 32)
pdf.set_text_color(255, 255, 255)
pdf.cell(0, 230, f'{username} took CS50', new_x="LMARGIN", new_y="NEXT", align='C')
pdf.output("shirtificate.pdf")
if __name__ == '__main__':
main()