Programming Update for June 2021


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