DEV Community

Cover image for Month 2: From OOP to Algorithms.
Om Kolhapure
Om Kolhapure

Posted on

Month 2: From OOP to Algorithms.

Month 1 was about learning the language.

Month 2 was about learning to think like a programmer.

The difference shows up everywhere. Month 1 me wrote functions because a lesson told me to. Month 2 me reaches for a class because the data has relationships, or a stack because the problem is fundamentally "last thing in, first thing out." This month had four weeks, each with a completely different texture — deep OOP, a full real-world project shipped publicly, a hard pivot into algorithms, and finally building data structures from scratch. Here's the whole story.


The Structure: Four Very Different Weeks

Week Theme Days Energy
Week 5 OOP Deep Dive 29–34 Conceptual — learning to model the world in code
Week 6 Real Project 36–41 Practical — designing, shipping, and defending one project
Week 7 DSA: Arrays & Hashing 43–48 New territory — algorithms instead of applications
Week 8 Stacks, Queues, Linked Lists 50–55 Foundational — building the structures themselves

Two brand-new GitHub repos exist because of this month. progress-on-python kept growing with OOP and project work. neetcode-submissions was born in Week 7 specifically to hold algorithm practice — a sign that DSA started to feel like its own distinct skill, deserving its own home.


Week 5 — OOP Deep Dive

Theme: Stop writing functions. Start modeling things.

What I learned

  • Classes, __init__, self, instance attributes
  • Inheritance and super() — sharing behaviour between related classes
  • Encapsulation with @property getters and setters
  • Dunder methods — __str__, __repr__, __eq__
  • Composition vs inheritance — the "is-a" vs "has-a" question

What I built

Project Highlight
Bank Account Deposit, withdraw, transfer, full transaction history per account
CheckingAccount / SavingsAccount Inheritance, super().__init__(), overdraft fees, interest
Dunder Methods print(account) returning BankAccount(Alice, 85.0) instead of a memory address
Library System Composition — Book, Member, Loan, Library as four separate classes
Task Manager Walrus operator in regex property setters, date.today() overdue checks, 8 structured tests

The moment that clicked

The library system's Loan class — capturing the relationship between a Book and a Member as its own object, rather than cramming that logic into either one. That's when composition stopped being a vocabulary word and became a design instinct.

Biggest surprise

OOP is about grouping, not just syntax. Wrapping related behaviour into a class doesn't change what code does — it changes how it's organised. That distinction reframed how I think about every program since.


Week 6 — One Project, One Week

Theme: Design it. Build it. Ship it. Defend it. Improve it.

What I learned

  • Writing a design document before any code — data model, API shape, edge cases
  • Building a complete CLI tool with JSON persistence
  • Tracking analytics in CSV with a read-modify-rewrite pattern
  • Writing a README for strangers
  • Asking for public code review — and actually using the feedback

What I built

A URL shortener. One project, six days, fully designed before being built:

  • Design.txt — six sections answering what it does, the data model, the "API," storage choice, code generation strategy, and edge cases
  • url_shortner.py — an Url class handling shortening, deduplication, and visit tracking
  • clicked_report.csv — analytics tracking how many times each URL was visited
  • A public README with real usage examples
  • Public sharing on Reddit and Discord, three+ code reviews, and a real bug fix afterward

The moment that clicked

Writing the design doc before touching the editor. The line "I will use Python's random module to generate 6 characters... I will check if the code already exists... if the code exists I will generate it again" became, almost word for word, the generate_code() method a day later. Planning wasn't separate from coding — it was coding in plain English first.

Biggest surprise

Public code review wasn't the ordeal I expected. A reviewer caught a real bug — most_clicked() was calling self.visit() twice in some cases, double-prompting the user. Strangers online were more useful for catching that than another week of solo work would have been.


Week 7 — A Hard Pivot Into Algorithms

Theme: Stop building. Start solving.

What I learned

  • Big O notation — naming the "feels slow" instinct I already had
  • Hash maps and sets as the "trade memory for speed" pattern
  • Two pointers — and recognising sorted input as a signal to use them
  • Sliding window — never re-scanning data you've already passed
  • A brand-new repo, neetcode-submissions, just for this kind of work

What I built

Problem Pattern
Two Sum Hash map
Contains Duplicate Set
Valid Anagram Hash map counting
Group Anagrams Canonical sorted key
Top K Frequent Elements Bucket sort (no sorting algorithm needed)
Valid Palindrome Two pointers
Two Sum II Two pointers (sorted input)
3Sum Two pointers nested inside a loop
Best Time to Buy/Sell Stock Running minimum
Longest Substring Without Repeating Characters Sliding window

The moment that clicked

Revisiting the Week 6 URL shortener's if code not in urls: line and realising it was already O(1) because urls was a dictionary — a design decision I'd made for convenience back in Week 6 turned out to already be the efficient choice. Naming why it was right, using Big O, was the real Week 7 lesson.

Biggest surprise

Mock-solving problems under a timer on Day 48 revealed the gap between "I understand this" and "I can rebuild this from a blank file." The patterns that came back fastest were the ones I'd genuinely internalised, not just followed along with once.


Week 8 — Building the Structures Themselves

Theme: Stop using built-in types. Build the data structures from scratch.

What I learned

  • Stacks (LIFO) and queues (FIFO) implemented from raw Python lists and deque
  • Linked lists — my first pointer-based structure with no array underneath
  • The dummy node pattern for removing special cases in list problems
  • Fast and slow pointers for "distance from the end" problems
  • How stack thinking quietly shows up in completely unrelated problems

What I built

Project Highlight
Valid Parentheses A stack matching brackets, with an odd-length early exit
Stack Using Queues Implementing one structure's behaviour using only the other's primitives
Reverse Linked List Three pointers (prev, curr, nxt) flipping arrows one at a time
Merge Two Sorted Lists The dummy node pattern removing every "first node" special case
Remove Nth Node From End Fast and slow pointers with a fixed gap, solved in one pass
Browser History Tracker A single pointer + list quietly acting as two stacks glued together

The moment that clicked

The browser history tracker's visit_site() truncating everything ahead of the current pointer before adding a new entry — exactly how real browsers discard "forward" history once you branch into a new page. That one line of code, self.history = self.history[:self.pointer + 1], is Day 50's stack thinking showing up in Day 54's project without ever mentioning a stack.

Biggest surprise

Drawing pointer diagrams on paper before writing the Reverse Linked List function made the logic obvious in a way that reading code never did. Two minutes of sketching saved twenty minutes of confusion.


Everything I Built in Month 2

# Project Week Key Concepts
1 Bank Account 5 __init__, @property, transaction history
2 CheckingAccount / SavingsAccount 5 Inheritance, super(), overdraft, interest
3 Dunder Methods 5 __str__, __repr__, __eq__
4 Library System 5 Composition, 4-class design
5 Task Manager 5 Walrus operator, regex setters, 8 tests
6 URL Shortener 6 Design doc, OOP, JSON storage, CSV analytics
7 Two Sum 7 Hash map
8 Contains Duplicate 7 Set
9 Valid Anagram 7 Hash map counting
10 Group Anagrams 7 Canonical key
11 Top K Frequent Elements 7 Bucket sort
12 Valid Palindrome 7 Two pointers
13 Two Sum II 7 Two pointers
14 3Sum 7 Two pointers + dedup
15 Best Time to Buy/Sell Stock 7 Running minimum
16 Longest Substring Without Repeating Characters 7 Sliding window
17 Valid Parentheses 8 Stack
18 Stack Using Queues 8 Stack/queue relationship
19 Reverse Linked List 8 Pointer reversal
20 Merge Two Sorted Lists 8 Dummy node
21 Remove Nth Node From End 8 Fast & slow pointers
22 Browser History Tracker 8 Stack logic, pointer state

All of it is on GitHub:
👉 github.com/Omk4314/progress-on-python
👉 github.com/Omk4314/neetcode-submissions


What Changed in Month 2

How I design before I build. Week 6's design doc was the first time planning happened entirely separate from coding. By Week 8, sketching pointer diagrams on paper before writing linked list functions had become a habit, not an assignment.

How I think about efficiency. Month 1 me had a vague sense that some code "felt slow." Month 2 me can say why — O(1) dictionary lookups versus O(n) list scans, two pointers beating a hash map when the input is sorted, sliding windows avoiding redundant re-scans.

How I relate classes to each other. Inheritance for "is-a," composition for "has-a." That single distinction, learned in Week 5's library system, now shapes every design decision before a line of code gets written.

How I receive feedback. Week 6 was the first time I shared code publicly and asked strangers to find problems with it. The bug they found — a double-call in most_clicked() — was real, and fixing it based on someone else's eyes was more valuable than another week of solo debugging would have been.

How fast old patterns come back. Week 7's Day 48 mock test was uncomfortable. Week 8's Day 55 review of the same kind of exercise was fast. That gap is the clearest evidence that the patterns from this month are becoming reflexes rather than lessons.


What I'd Tell Myself at the Start of Month 2

  • Write the design doc first, even for small projects. The URL shortener's Design.txt made every day of building faster because the hard thinking happened once, up front.
  • A new kind of problem deserves a new repo. Splitting neetcode-submissions away from progress-on-python wasn't bureaucracy — it made it obvious which skill was being practiced on any given day.
  • Ask for code review before you feel ready. The feedback on the URL shortener was more useful because the code wasn't perfect yet.
  • Sketch before you code, especially for pointers. Linked lists are a visual problem wearing a syntax costume.
  • Re-solving old problems is the real test. Not whether you can follow a solution, but whether you can rebuild it cold, days later, without panic.

What's Next

Month 3 has clear targets already taking shape from Week 8's closing thoughts:

  • Trees and recursion — the next data structure family, and the first one that forces recursive thinking
  • Binary search trees — ordered structures with their own traversal rules
  • Heaps and priority queues — a natural extension of this month's queue work
  • Bigger, multi-class projects — combining OOP from Week 5 with the algorithmic thinking from Weeks 7 and 8

Two months down. The foundation isn't just "I know Python syntax" anymore — it's "I can model a problem, choose the right structure, and explain why." That's a different kind of confidence than the one I had at the end of Month 1.

If you're following along, building your own projects, or grinding the same NeetCode list — drop a comment. I'd genuinely like to see what Month 2 looked like for you.

See you in Month 3. 🐍


8 weeks. 22 projects and solutions. Two repos. One streak still going.

Top comments (0)