June was mostly Python, although I did do chapter 1 of Scratch 3 Games for Kids with Sam. He really, really enjoyed it and I anticipate doing the challenge problems and maybe chapter 2 in July or August.
Books
I read the intro and first couple chapters of both Flask Web Development, 2nd Edition and Data Visualization with Python and Javascript, both from a recent Humble Bundle. The Flask book may be useful for learning more about creating a non-Django site and, even if I mostly stick with FastAPI, it should provide some concepts that are applicable across both frameworks. With the data visualization book, I would love to use that to better visualize my annual Last.fm stats.
Advent of Code
While at my in-laws’ house, I completed days 13 and 14 of 2015’s Advent of Code. Back when I first started working on Advent of Code 2015, I went through all the problems and posted my first stab at a solution into a Google document. For day 13 I’d predicted that a modified version of the Traveling Salesman problem I’d done in 2015 Day 9 might work, using an asymmetrical matrix. That turned out to be exactly the right solution. In Ruby I learned how to do a Ternary expression. In the function “create_guest_hash” see the number = expression.
require "../../input_parsing/parse_input"
def create_guest_hash(lines)
guest_hash = Hash.new
lines.each do | line |
people_and_values = line.scan(/(\w+) would (gain|lose) (\d+) happiness units by sitting next to (\w+)\./)
if !guest_hash.has_key?(people_and_values[0][0])
guest_hash[people_and_values[0][0]] = {}
end
number = people_and_values[0][1] == "lose" ? "-#{people_and_values[0][2]}" : "#{people_and_values[0][2]}"
guest_hash[people_and_values[0][0]][people_and_values[0][3]] = number
end
guest_hash
end
def create_matrix(guest_hash)
index_hash = Hash.new
guest_hash.keys.each_with_index do | key, index |
index_hash[index] = key
end
matrix = []
index_hash.keys.each_with_index do |index|
temp_internal_list = []
current_person = index_hash[index]
index_hash.keys.each_with_index do |internal_index|
if internal_index == index
temp_internal_list.append(0)
else
temp_internal_list.append(guest_hash[current_person][index_hash[internal_index]].to_i)
end
end
matrix.append(temp_internal_list)
end
matrix
end
def perfect_seating(happiness_graph, starting_person, number_of_people)
vertex = []
(0...number_of_people).each do |number|
if number != starting_person
vertex.append(number)
end
end
max_happiness = 0
permutation_list = vertex.permutation.to_a
permutation_list.each do |permutation|
current_happiness_weight = 0
outer_array_index = starting_person
permutation.each do |inner_array_index|
current_happiness_weight += happiness_graph[outer_array_index][inner_array_index]
current_happiness_weight += happiness_graph[inner_array_index][outer_array_index]
outer_array_index = inner_array_index
end
current_happiness_weight += happiness_graph[outer_array_index][starting_person]
current_happiness_weight += happiness_graph[starting_person][outer_array_index]
max_happiness = [max_happiness, current_happiness_weight].max
end
max_happiness
end
if $PROGRAM_NAME == __FILE__
guest_preferences = input_per_line('../input.txt')
guest_preference_hash = create_guest_hash(guest_preferences)
guest_preference_matrix = create_matrix(guest_preference_hash)
starting_person = 0
total_happiness = perfect_seating(guest_preference_matrix, starting_person, guest_preference_matrix.length)
puts "With the perfect seating arrangement total happiness is #{total_happiness}."
end
Day 14 turned out to be a very easy solution that was able to use what I’d come up with ahead of time without modification; for part 1, anyway. Part 2 became a bit of a mess that seemed to require create a Reindeer class in order to keep track of which Reindeer to award points to. Since I hadn’t done anything with Ruby classes yet (wasn’t really covered in the Ruby book I read with the kids), I haven’t yet done the Ruby or Perl solutions. You can see my Python solution here.
Prophecy Practicum
I made a bunch of quality of life improvements for my friend, aka The Client. I was pretty happy at my ability to continue to figure out how to make use of Django’s many built-in features.
Extra Life Donation Tracker (eldonationtracker)
I had to do a bug fix for a change in the way the API handled anonymous donations. Overall it wasn’t too hard. Sometime soon I intend to start separating out the Donor Drive API into its own project apart from the Extra Life code.
Impractical Python
After a long hiatus, I returned to Impractical Python and finished the Haiku chapter. It used Markov Chains and the CMU language module to help teach the computer what a valid Haiku was. Here is one of the Haikus it generated:
listen: new year's bell! bell! standing still at dusk house listen in far in
This next one is kind of nonsense, but I like it. Seems faux-zen:
oh no! a white swan butterfly butterflies the only fluttering
This one is closer to a real Haiku:
let myself pretend my old sadness winter rain rain deepens lichened
I’ll leave you with this last one which actually sounds like a human-written Haiku:
closer, quilt and leaves, enfold my passionate cold! cold! dry cheerful bright