Hello, world and welcome, this is a breakdown, or guide, to the problem sets (psets) to CS50’s Introduction to Programming with Python (CS50P).

If you’re unaware, CS50 Python comes from Havard which operates edx CS50. It’s a great introduction to the programming language Python. If you’re brand new to Computer Science (CS) or have a background in technology, CS50 covers the fundamentals really well. It’s one of the best places to learn Python online.

For me learning Cyber Security, I’m fascinated with the abilities programming unlocks like automation and threat detection. However, I’ve found learning any programming language really difficult. So, I write and share articles like this to help myself reinforce what I learn while (hopefully) distilling some help your way.

Disclaimer, following CS50’s Academic Honesty, this article will be written as if you’ve asked for help and therefore will not show my code. However, I will share thoughts and Python constructs that helped me solve each one. PS, big shoutout to the CS50 community on Discord for their help, lots of amazing people there. PSS, I’m a fellow student, I’m not a professional nor do I claim my code is of any standard, code your way.

Functions, Variables

Most of the starting psets involve functions such as input(), print() and a single variable.

Let’s take a look at Week 0:

Indoor Voice: this can be completed in 3 lines of code using string methods and a single variable.

Playback Speed: similar to indoor with 3 lines of code, but using a different string method. I used str.replace() to complete this problem set.

Making Faces: the same length of code again, and also the same string method can be used. If stuck, you can copy/paste emojis into your code editor.

Einstein: a few more lines might be needed for this pset, here’s my pseudo code # E = mc2, mass + c (speed of light 300000000) squared. You’ll need to convert the user’s input to an int and use some math operators to get the end result.

Tip Calculator: this one escalates quickly imo, well for me anyway. I completed this pset within 20 lines of code, and multiple variables and defined the 3 recommended custom functions. You’ll need to strip and convert user input before returning the custom functions. Lastly, you’ll need to apply a simple math equation to get the correct percent.


Next up are conditions, let’s tackle the psets for Week 1:

Deep Thought: you can complete this within 5-6 lines of code, a single variable and one if else conditional statement. Note, you’ll need multiple conditions using logical operators for the single if statement, for help see Python Operators.

Home Federal Savings Bank: a bit longer than deep at 7-8 lines of code and similar in logic, bank takes some more elif statements. Remember, if you want to use a character that python relies on, use \\ to force it e.g. 'What\\'s up?'.

File Extensions: ~15 lines of code can work for this pset, I used a lot of elif statements with a specific string method to check the end of the user input.

Math Interpreter: takes about 15 lines like extensions, similar in logic but I used a few more variables. For help, take the user input, assign them to variables and then perform some conditional logic with the math operators. You can assign multiple variables at once and use the str.split() function so they’re assigned correctly.

Meal Time: this is good to go on from math as it builds upon the same concepts like assigning multiple variables at once. You’ll need a couple more variables to make this pset work along with the condition, of course.


Python has a powerful set of constructs to repeat or iterate values we pass to it.

Let’s look at Week 2:

camelCase: completed within 10 lines of code, this is the most nested of the psets so far, meaning there are more indented blocks of code. Relying heavily on the for loop (like most of the psets this week), you’ll need a couple more string methods like str.isupper() to complete this one.

Coke Machine: the longest pset yet coming in at ~25 lines, there’s nothing new you haven’t used in the past psets besides a while True loop. Remember to start with checking the user input first before applying math to the variables.

Just setting up my twttr: this is a fun one, coming in at about 10 lines for me, I used a simple for loop around an if condition to assess if a letter in a user string is a vowel.

Vanity Plates: this felt long a big leap forward, I recommend reading the instructions and listing all the steps. With nearly 50 lines of code, my program worked but was bloated and need reworking if I’m honest. Tip, it was easier to avoid slicing strings and focus on if conditions to match the beginning or end of the input.

Nutrition Facts: longer than some psets at ~30 lines due to using a dict, I solved this one without using a loop… whoops. It goes to show there are many ways to make the cat meow. For help, I recommend making a simple dict and not simply copying the lecture’s example. A single dict is much easier than a list with multiple dict‘s.


Here are my notes for Week 3’s lecture, be aware you’ll use all of the concepts outlined in the psets.

Exceptions: when things go wrong with code i.e. errors. SyntaxError: missing syntax, can’t solve itself, you must. ValueError: can’t understand value e.g. stringint. NameError: incorrectly using your own code e.g. local/global vars.

try statement attempts to run code, except handles errors, else in case all else. Best practice: try only surrounds suspect code producing errors. def own function, return more powerful than break, can shorten code. pass catches error but ignores it.

Now let’s get into the psets:

Fuel Gauge: completed within 30 lines, it’s a good intro to applying try and except. After you check the user’s input, you’ll need to apply a bit of math to find the percentage of the given fraction, hint: divide each number and multiply by 100.

Felipe’s Taqueria: in 20 lines of code, good exercise for understanding dict in more detail. Remember Week 2 info and all you need is to index the key’s value and add it to a variable.

Grocery List: following taqueria and stressing your dict skills, I completed this pset in less than 15 lines. Remember you can use a for loop with two iterative values, meaning you can use that to print both keys and values. Also, don’t forget to print() in a sorted fashion i.e. alphabetical.

Outdated: with less than 40 lines, this is another bloated monster that needs to be cut down… but it works! I looked at this as two functions, both matching each input allowed of dates, this is what makes the program so long. Essentially, take the input, pick a function, match it against its requirements and output in the new format. Tip, use the index() method to extract the location of the item as a number, you can +1 so it doesn’t start at 0.

Alright, now Week 3 psets have come and gone, the wait for Week 4 is on. Enjoy the learning (struggle) haha.


If interested, here’s my notes from W4’s lecture:

Libraries: generic term module/package, other code/programs avaliable for use. modules: library implimented in a file with functions/features built-in. import <module>: imports all functions/features within single module. <module>.<function>(): allows the use of function e.g. random.choice(seq) seq = list(like). from <module> import <function>: only imports single function from module. <function>(): if single function is called, module name can be removed e.g. choice(seq). sys.argv (System Argument Vector): takes CL input/argument to use in program.

packages: (3rd party) library implemented in a folder e.g. PyPi (Python Pacakge Index) > cowsay. pip: pre-built python program/packet manager for Python. API (Application Programming Interface): 3rd party services code can communicate with. requests: popular web requests module, pretends to be browser. JSON (JavaScript Object Notation): lang. agnostic format, non-dependant on JS, all lang. friendly.

With that out of the way, let’s get into the psets:

Emojize: a lot easier than I expected being at W4, after import it can be completed in two lines of code. Make sure to read the documentation and use the right function from the emoji module.

Frank, Ian and Glen’s Letters: this was a lot of fun as I’ve always liked ASCII Art. Really make sure to follow the module docs, it’s almost just a follow your nose situation. The only thing I’ll add is sys.exit(1) – you’ll know when you need it.

Adieu, Adieu: I’ve never seen The Sound of Music so I’ve got no idea what’s going on. In confession, I didn’t use the module required but was still able to pass. Instead, I used a series of methods like join() and replace() which made it work… yes, I know it’s not right, but it’s what I got for now.

Guessing Game: funny enough, I’ve completed a similar project so this wasn’t too challenging. Really it’s just using the random module and its function with a few try except and if elif else statements.

Little Professor: another good pset to stretch the custom function abilities, something I’m still struggling with. Focus on one function at a time, first get_level(), then generate_integer() and lastly main(). I completed it in about 40 lines of code, but I think it’s way to long for what it does.

Bitcoin Price Index: after professor this was much easier, I used the same problem-solving method and am now understanding why custom functions are so valuable. I created check_argv() and get_bc_value() both serve there own abstracted purpose. Regarding using json I didn’t need to import json but just used requests.get() and then the .json() method. Don’t forget you can index by specifying the key, example o['bpi'].

Unit Tests

I found Week 5 psets really hard and not as interesting as previous weeks. It’s worth taking your time to improve your code when reworking some previous psets. You’ll find it will deepen your understanding of earlier weeks. Also, no notes from me this week, see the official notes.

Testing my twttr: reworking twttr shouldn’t be too difficult for you at this stage. If you follow the lectures, writing the test_twtter will be very doable, just take your time. Writing the test_twttr is also doable, don’t forget to import the function you’re testing and use assert.

Back to the Bank: reworking bank left me with almost the same amount of lines, but more optimized and cleaner, I think. This pset is similar in spirit to twttr, again, take your time.

Refueling: the rework saved me ~10 lines of code, but for test_fuel make sure to use pytest.raises() to test for errors. Otherwise testing your functions is similar to the other test psets.

File I/O

Alright, Week 6, file in out, let’s go. Here are my notes for the week:

Typically, python stores data in RAM (memory), until File Input/Output changes that. open() opens/reads file in a state e.g. a append, w write, x create, r read etc. write() writes to file, close() closes file. with open('<file>') as variable: can open and assign file, then close after block. readlines() method returns a list with each line is an item. lambda writing inline functions, no need to def custom function elsewhere.

csv module, apart of standard library, must import. csv.reader() reads csv files, can pass variable through. csv.writer() writes to csv files, can use writerow([<value 1>, <value 2>]). csv.DictReader() for dict uses key: value pair. csv.DictWriter() for dict uses key: value pair, specify fieldnames=['1', '2']. PIL pillow module, allows image manipulation, from PIL import Image.

Notes done, now let’s see the psets:

Lines of Code: completed in ~30 lines of code, I used two functions 1) validate, and 2) find_lines. Don’t forget you can declare new variables when you define a function.

Pizza Py: around ~20 lines of code for this pset, two functions 1) validate, and 2) tab. To complete pizza use similar sys.argv code from the previous pset, and then a simple for loop. Make sure to read the tabulate docs for more detail.

Scourgify: in about ~40 lines with again, two functions 1) validate, and 2) clean_files, this time getting used to csv.DictReader(). Use next() to skip the heading, that could save you a lot of time, plus writeheader() too.

CS50 P-Shirt: this was a lot of fun, moving from text/terminals to graphics/images is awesome. In approx ~30 lines, with again two functions of 1) validate, and 2) edit, this is all about the PIL library. You’ll need a few if, elif statements to validate and for the edit function use ImageOps.fit().

Regular Expressions

Great, now Week 7 RegEx (RE). I was worried about the increased difficulty of RE but glad to finally learn the language within the language. No custom notes from me so here are the official notes.

NUMB3RS: great introduction to RE, with about 7 lines of code and one function of validate. Ensure to search() your pattern, if it matches then use an if statement to check and return either False or True.

Watch on YouTube: similar length as numb3rs with the single function, this time called parse. The difference compared to the previous pset is using two separate patterns of RE.

Working 9 to 5: this ramped up in difficulty, about ~30 lines with a single RE pattern match, but over 9 if statements. Sure, my program passed but it could use some optimization. I took the group approach by splitting up the pattern match into multiple groups and then running conditions against them.

Regular, um, Expressions: after work, this was a nice break, in just 7 lines of code again, um was a simple pset. Use findall() for this one!

Response Validation: great use of the validator_collection library, and again just 7 lines of code with a single function. Make sure to read the docs linked and don’t overthink it.

Object-Oriented Programming

Well Week 8 nearly broke me, I thought Unit Testing was a challenge, that was nothing compared to Object-Oriented Programming (OOP). In short, I passed all psets with significant assistance from a work colleague, CS50P staff and fellow students via Discord. I couldn’t have done it without them.

Seasons of Love: ah, seasons I hate you, haha, no, you are a good learning experience. I’m not going to pretend like I fully understand classes, but a single class with five methods did the trick for me.

Cookie Jar: in ~40 lines, this was extremely difficult like seasons, a single class with six methods. All I know is I need to rewatch the lecture, I’m sorry I am of no help here.

CS50 Shirtificate: this was actually a nice last pset as it was a bit challenging but pretty straightforward. After the last two psets, I think it was nice to end on an easier one imo. Less than 20 lines, just a single main function and six methods from FPDF() – and that’s it!

Et Cetera

No psets for this week, just the final project, how exciting! Stay tuned as I’ll be writing a full breakdown of my final project along with a course review and reflection.

Thanks for reading and I hope you learned something from this little exercise. This is days 48, 49, 51 and 55 of #100DaysOfHacking on the Hackers Learning Path. Subscribe for CyberSec updates or read more, happy hacking.