Vibe code is legacy code

Programming is fundamentally theory building, not producing lines of code. We know this. This is why we make fun of business people who try to measure developer productivity in lines of code.

When you vibe code, you are incurring tech debt as fast as the LLM can spit it out.

I love the graph as a simple reminder for when I am learning: the more I’m vibing the less I’m understading.

Related: Understanding requires effortful engagement.

via Simon Willison


The datetime module is handy when dealing with dates, times, and durations in Python. The four core classes are:

  • datetime.datetime - specific moment in time (2025-07-30 17:43:20)
  • datetime.timedelta - duration expressing the difference between two datetime or date instances to microsecond resolution.
  • dateime.date - calendar date (2025-07-30) asssuming gregorian calendar
  • dateime.time - time of day (17:43:20)

Common patterns to remember

  • Timestamps for filenames: datetime.now().strftime("%Y%m%d_%H%M%S")
  • Age calculations: (date.today() - birth_date).days // 365
  • Checking if recent: timestamp > datetime.now() - timedelta(hours=24)
  • Duration between events: end_time - start_time
  • Adding business days: start_date + timedelta(days=5)
  • End of day: datetime.combine(date.today(), time.max)
  • ISO format for APIs: datetime.now().isoformat()
  • Parsing user input with try/except for multiple formats

A sample of the format codes for formating the datetime objects:

CodeMeaningExample
%Y4-digit year2025
%y2-digit year25
%mMonth (01-12)07
%BFull month nameJuly
%bShort month nameJul
%dDay (01-31)30
%HHour 24-hour (00-23)14
%IHour 12-hour (01-12)02
%MMinute (00-59)30
%SSecond (00-59)45
%pAM/PMPM

Gotchas to be mindful of

  • Doesn’t work well with timezones
  • timedelta doesn’t handle months/years reliably

Missed the last update as I was on summer vacation; I should have planned to start this week instead.

This week my focus has largely been on the bookshelf project. It has been tough but also rewarding to get to where I am, and I feel like I’m learning at the edge of my abilities. I far overestimated that I would be done by now, but it’s been good progress just putting in the time to learn.

I started by learning a lot about Typer and how it works as the CLI tool of choice.

I implemented a skeleton cli.py with all the commands I plan on adding so that I can see with bookshelf --help what the interface looks like. Most of the work has been creating data models for the Book and Review classes, and setting up a database.

Below is the demo of the app with the bookshelf add command in action. Inspired by libro - a command-line book tracking tool

Not sure what I’ll show in next weeks demo, but I hope to have a few more commands implemented. I’d be very happy if I can get to importing some data directly from Goodreads, which will involve working on a custom parser.

Some things I learned this week

Learning Typer at first by going through the tutorial, but found it more helpful to sketch out what I wanted and then ask an LLM for specific things as I needed them.

A review of classes in Python and using dataclasses to build the Book and Review data models. A good refresher on class methods, static methods, and using the typing module to enforce type hints. It was really nice to finally use dataclasses for a non-trivial project.

Working with SQLite, which was a highlight. One of my joys has been exploring information stored in SQLite databases e.g. book info from my ereader; bookmarks, history from web browser, messages from iMessage… This was my first time creating one myself, and it was delightful. Already thinking of mother projects to take on after. Some notes to self for the future:

  • conn.row_factory = sqlite3.Row to access columns by name instead of index
  • using context managers instead of manually closing connections, and using json to store tags in the database as a list of strings
  • ALWAYS use parameterized queries with ? placeholders and pass values as a tuple. Using f-strings or concatenation with user input is unsafe and makes the app vulnerable to SQL injection.
with get_db_connection() as conn:
    book_dict = self.to_dict()

    # convert tags to a json string
    book_dict["tags"] = json.dumps(book_dict["tags"])

    cursor = conn.execute(
    """
    INSERT INTO books (title, author, tags)
    VALUES (?, ?, ?)""",
    tuple(book_dict.values()),
    )
    
    book_id = cursor.lastrowid
    
    conn.commit()

Other updates this week

  • Worked on 3 Exercisms: Difference of Squares, ETL, and Flatten Array. The last one was quite challenging since I didn’t think of using recursion at all.
  • Made it through the Recursion and Quick Sort chapters of Grokking Algorithms. I need to spend more time on exercises here to make sure it sticks before I move on; especially to develop an intuition around choosing base cases.

I’ve been working on Python a bit more casually but now decided to make it a focus of my summer. Inspired by CGP Grey, it’s the summer of Python. And I’ll be writing weeknotes to keep myself accountable.

Where I’m starting from: familar with loops, variables, funtions, classes… but never put all these together to make any concrete project or in production code. At work I use Python ocassionally to write scripts for different data tasks and Jupyter Notebooks for analysis. My implementations get the job done but I’m keen on learning more Pythonic ways of approaching things.

The goal more concretely is to improve my problem solving using Python, learn more advanced features (standard library, common libraries) and building small personal tools. Losely the plan over the next few weeks is to:

  • Work through different practice tasks on Exercism
  • Read Grokking Algorithms
  • Reimplement small Python projects I’ve collected on GitHub. Top of the list is: libro - a command-line book tracking tool which I’m reimplementing as bookshelf.
  • Using Anki for spaced repetition to make memory a choice.
  • Follow my curiosity. I’m optimizing for fun as I learn so detours in service of the main goal are encouraged.

This week I worked through the following Exercism tasks: Resistor Color Expert, Secret Handshake, Anagram, House and Binary Search . Took a lot of detours and learned about a few things that were new to me:

:g - the general formatter for floats which chooses between fixed-point and scientific notation, depending on the value.It defaults to 6 significant digits unless you specify a precision with .Ng where N is the significant digits.

f"{123456.789:g}"    # → '123457'
f"{0.000012345:g}"   # → '1.2345e-05'
f"{123.0:g}"         # → '123'
f"{123456.789:.2g}"  # → '1.2e+05'
f"{0.0123456:.4g}"   # → '0.01235'
f"{123.456:.5g}"     # → '123.46'

Reversing lists - I kept getting TypeError as I tried to enumerate over mylist.reverse() directly. Some reminders on reversing lists:

  • list.reverse() reverses the list in-place and returns None. Be careful using in a loop or anywhere were you expect the reversed loop in the same operation.
  • reverse(list) returns a generator object which you need to cast into a list or use elements one by one. Remember generator objects can only be used once.
  • list[::-1 gets you a convenient reversed copy to use without modifying the original which I’ve sure encountered before.

bisect module - learned about this module while consulting Claude on alternative solutions binary search. The module provides efficient binary search operations on sorted lists, allowing you to find insertion points and maintain sorted order without implementing binary search yourself. It has 3 common operations:

  • bisect.bisect_left(sorted_list, num) - returns leftmost insertion index
  • bisect.bisect_right(sorted_list, num) - returns leftmost insertion index
  • bisect.insort(sorted_list, num) - insert while maintaining order

Overall a good week. I struggled the most when I started writing the solution as I thought of the logic. To try in the future, map out the complete logic on paper before typing in the IDE. Next week: more exercism workouts, work my way throug Grokking Algorithms and try ship my bookshelf implementation of libro.