Event 3 - 2025-10-29

Don't forget your homework, it's at the bottom of this page.

What did we talk about?

The % sign

We had a question of what does the '%' sign mean.
It's the modulues operator, that you can use to find the reminder from a division.
# Examples
remainder = 2000 % 4 # Here remainder is 0
remainder = 2001 % 4 # Here remainder is 1
remainder = 2002 % 4 # Here remainder is 2
remainder = 2003 % 4 # Here remainder is 3
remainder = 2004 % 4 # Here remainder is 0
remainder = 2005 % 4 # Here remainder is 1
remainder = 2006 % 4 # Here remainder is 2
remainder = 2007 % 4 # Here remainder is 3
remainder = 2008 % 4 # Here remainder is 0

F-Strings

F-Strings are a quite nice way to format text output.
the_answer = 42

print("One way of using variables is like this", the_answer)
# Result: One way of using variables is like this 42

print(f"The answer is {the_answer}")
# Result: The answer is 42

# If your forge the f this happens:
print("The answer is {the_answer}")
# Result: The answer is {the_answer}
Read more about f-strings

Lists

some_numbers = [ 100, 42, 4, 11, 45 ]
# If we want to just go through the list, we can do a for loop like this
# For another example of a for loop, look at the Advent of Code code below
for n in some_numbers:
    print(f"This number is {n}")

# We start counting with zero...
# In the beginning of programming, storing numbers was very
# expensive, and not using 0 was a waste of money and other
# resources
first_number = some_numbers[0] # first_number is the number 100
More information about lists.

What does Kenneth think good code is?

  1. It works!

    If it does not work, how can it be good?!? :)
  2. It is easy to read

    You should not have to spend alot of brain power to try to figure out what the code is supposed to do.
    Avoid falling it the beginner trap of being "smart" and to "show off" how short you can write things, you will regret it when you read your own code in a few weeks trying to figure out why it does not work. :O
    This is of course also subjective, and with more experience you will learn common shorthands that programmers often use.
  3. It is easy to change

    Kind of depends of number 2. This is also subjective and easier with experience.I try to be kind to my future self (and collegues of course) so that my/their required as little brain power as necessary

Assignment operators

Programmers often use short hands like "some_thing += 1"
number = 10

# This shorthand "+="
number += 1
# Does the same thing as this
number = number + 1
For an experienced programmer this is easy to read, you only have to read "number" once and then quickly see that we want to increase it with 1.
Also works with other operators like % * / - etc.
Read more about assignment operators

What did we code?

A few brave souls showed their homework, thank you for bravery! :)
Fun fact - different rules for leap years before 1582 (the year the Gregorian Calendar was introduced)... Which noone implentet - including me.

I showed a few examples on how to solve the homework

def years_to_months(number_of_years):
    return number_of_years * 12

def is_this_a_leap_year(year):
    return False

def is_this_a_leap_year(year):
   return year % 4 == 0

def is_this_a_leap_year(year):
    if year % 4 == 0:
        return year % 100 != 0
    else:
        return False

def is_this_a_leap_year(year):
    if year % 4 == 0:
        if year % 100 == 0:
            return year % 400 == 0
        else:
            return True
    else:
        return False

def is_this_a_leap_year(year):
    if year % 400 == 0:
        return True
    if year % 100 == 0:
        return False
    return year % 4 == 0

def is_this_a_leap_year(year):
    return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0

Test suite

I showed and exampel of a "test suite" which I used to test my code with to see how good it was.
from homework import years_to_months, is_this_a_leap_year

years = 3
months = years_to_months(years)
print(f"{years} years = {months} months")

years = 13
months = years_to_months(years)
print(f"{years} years = {months} months")

number_of_correct = 0

year = 1999
should_be = False
is_leap = is_this_a_leap_year(year)
correct = is_leap == should_be
if correct:
    number_of_correct += 1
print(f"is leap {year} gives {is_leap} should be {should_be} --- {correct}")

year = 2004
should_be = True
is_leap = is_this_a_leap_year(year)
correct = is_leap == should_be
if correct:
    number_of_correct += 1
print(f"is leap {year} gives {is_leap} should be {should_be} --- {correct}")

year = 2100
should_be = False
is_leap = is_this_a_leap_year(year)
correct = is_leap == should_be
if correct:
    number_of_correct += 1
print(f"is leap {year} gives {is_leap} should be {should_be} --- {correct}")

year = 2900
should_be = False
is_leap = is_this_a_leap_year(year)
correct = is_leap == should_be
if correct:
    number_of_correct += 1
print(f"is leap {year} gives {is_leap} should be {should_be} --- {correct}")

year = 2000
should_be = True
is_leap = is_this_a_leap_year(year)
correct = is_leap == should_be
if correct:
    number_of_correct += 1
print(f"is leap {year} gives {is_leap} should be {should_be} --- {correct}")

year = 2400
should_be = True
is_leap = is_this_a_leap_year(year)
correct = is_leap == should_be
if correct:
    number_of_correct += 1
print(f"is leap {year} gives {is_leap} should be {should_be} --- {correct}")

year = 1453
should_be = False
is_leap = is_this_a_leap_year(year)
correct = is_leap == should_be
if correct:
    number_of_correct += 1
print(f"is leap {year} gives {is_leap} should be {should_be} --- {correct}")

print()
total_amount_of_tests = 7
if number_of_correct == total_amount_of_tests:
    print(f"{number_of_correct} of {total_amount_of_tests} is correct, oh happy joy!!!")
else:
    print(f"{number_of_correct} of {total_amount_of_tests} is correct")
I then showed how we could that that very verbose and long testcode and simplify it, making it more compact, and hopefully more readalble for all
number_of_correct = 0

def test_leap_year(year, should_be):
    is_leap = is_this_a_leap_year(year)
    correct = is_leap == should_be
    return correct

test_data = [
        [1999, False],
        [2004, True],
        [2100, False],
        [2900, False],
        [2000, True],
        [2400, True],
        [1453, False],
        [1996, True],
        ]

number_of_correct = 0
for year, should_be in test_data:
    correct = test_leap_year(year, should_be)
    if correct:
        print(f"✓ year {year} shoud be {should_be}")
        number_of_correct += 1
    else:
        print(f"x year {year} shoud be {should_be}")

print()
total_amount_of_tests = len(test_data)
if number_of_correct == total_amount_of_tests:
    print(f"{number_of_correct} of {total_amount_of_tests} is correct, oh happy joy!!!")
else:
    print(f"{number_of_correct} of {total_amount_of_tests} is correct")

Advent of code 2024 day 1 part 1

I showed an example of how to solve the first part of the homework
f = open("puzzle.txt", "r")

lefties = []
righties = []

for line in f.readlines():
    line = line.strip()
    # print(f"Line is {line}")
    words = line.split()
    # print(f"words is {words}")
    left, right = words
    # print(f"left {left} right {right}")
    left = int(left)
    right = int(right)
    lefties.append(left)
    righties.append(right)

# print(f"lefties is {lefties}")
# print(f"righties is {righties}")

lefties = sorted(lefties)
righties = sorted(righties)
print(f"sorted lefties is {lefties}")
print(f"sorted righties is {righties}")

number_of_numbers = len(lefties)

total_distance = 0

for n in range(0, number_of_numbers):
    # print(f"process line {n}")
    left = lefties[n]
    right = righties[n]
    # print(f"left is {left}, right is {right}")

    distance = abs(right - left)

    # if distance < 0:
    #     distance = - distance

    # print(f"distance is {distance}")

    total_distance += distance

print(f"total distance is {total_distance}")

Homework

Do part 1 and part 2 of the first the Advent of Code from last year that you can find here.
2025-11-06Kenneth Hedmanprogrammingpython