Every senior engineer's GitHub started with a tiny calculator, a CLI todo app, and a half-finished web scraper. Tutorials teach syntax; projects teach engineering — naming, error handling, file layout, "what to do when something breaks at 11 PM." Part 1 takes you through three foundational projects (calculator, contact book, word frequency analyzer); Part 2 covers the data dashboard and CLI quiz game.
Learning Objectives
After this lesson, you will be able to:
Apply functions, data structures, and control flow together to build a working calculator with history
Combine dictionaries, OOP, and file I/O to create a persistent contact book
Use string processing, collections.Counter, and file I/O to build a word frequency analyzer
This is not a typical lesson. There are no new concepts to learn here. Instead, you will build three mini-projects in Part 1 (and two more in Part 2) that combine everything you have learned so far.
For each project, you will get:
A problem statement -- what you are building and why
Concepts used -- which earlier lessons are relevant
Starter code -- a skeleton with TODOs to guide you
A full solution -- to compare against after you try it yourself
Challenge extensions -- harder tasks for when you want more
The most important rule: try the starter code BEFORE looking at the solution. Struggling is where the real learning happens.
Build an interactive calculator that supports basic arithmetic operations and keeps a history stack of all calculations. The user can view their history and undo the last calculation.
This is a classic first project because it ties together user input, functions, conditionals, and data structures in a way that feels like a real application.
Build a contact book application that lets you add, search, delete, and list contacts. Each contact has a name, phone number, and email. The contacts are stored in a dictionary and can be saved to a JSON file for persistence.
This project combines data structures with file I/O and introduces you to the kind of CRUD (Create, Read, Update, Delete) operations that are the foundation of almost every software application.
Build a tool that reads text, counts the frequency of each word, filters out common "stop words" (like "the", "a", "is"), and reports the top N most frequent words.
This is the exact foundation of how text processing works in NLP. When you hear about "tokenization" and "term frequency" in machine learning, this is what is happening at the simplest level. Every NLP pipeline starts with exactly this kind of word counting -- you are building the first stage of a natural language processing system.
This is how tokenization works at the simplest level. In NLP, the first step of any text pipeline is breaking text into tokens (words) and counting their frequency. The techniques you build here -- lowercasing, removing punctuation, filtering stop words, counting frequencies -- are the exact preprocessing steps used before feeding text into models like BERT, GPT, and other transformers. The only difference is that production systems use more sophisticated tokenizers (like BPE or WordPiece), but the principle is identical.
Bigrams -- instead of single words, count pairs of consecutive words (e.g., "machine learning" appears together). This is called bigram analysis and is used heavily in NLP
TF-IDF -- if you have multiple documents, compute Term Frequency-Inverse Document Frequency to find words that are important to a specific document but not common across all documents
Read from file -- modify analyze_text to accept a filename instead of a string, and read the file contents
Sentiment words -- create a list of positive words and negative words, then count how many of each appear in the text to get a basic sentiment score
Zipf's Law -- plot word rank vs. frequency and observe that it follows Zipf's law (the nth most common word appears roughly 1/n times as often as the most common word)
Take a moment to appreciate what you just did. In three projects, you used:
Concept
Project 1
Project 2
Project 3
Functions
Yes
Yes
Yes
Control Flow
Yes
Yes
Yes
Lists
Yes
Yes
Yes
Dictionaries
Yes
Yes
Yes
OOP (Classes)
--
Yes
--
File I/O
--
Yes
Yes
String Processing
Yes
--
Yes
collections.Counter
This is the whole point — programming is about combining concepts, not using them in isolation. Part 2 picks up where this leaves off with pandas-driven analysis and an OOP-driven CLI quiz game that adds decorators and the random module.
Each function does one thing. clean_text() only cleans text. tokenize() only splits into words. count_words() only counts. This makes code easier to test, debug, and reuse.
Instead of writing the same calculation in multiple places, you wrote it once as a function and called it from wherever needed. The calculate() function in Project 1 routes to specific operation functions instead of repeating arithmetic logic.
In Project 2, you bundled related data and behavior into a class. The ContactBook class owns its contacts dict and all the methods that operate on it. Outside code does not need to know how contacts are stored internally. Part 2's quiz game pushes this further with three cooperating classes.
Project 3 (Word Frequency Analyzer) is a pipeline: text goes in, passes through clean -> tokenize -> filter -> count -> display. This is exactly how ML pipelines work: data goes through load -> preprocess -> transform -> train -> evaluate.
Quick Check1 / 4
In the Calculator project, why is history implemented as a list (stack) rather than a dictionary?