better living through python

An adventure in programming and recovery.

Problem Set 5; problem 3 of 6

September 26, 2011

This problem came to me more easily, however the end solution is not quite my own.  I learned how to use dict.get, but it hasn’t truly sunk in yet.  The premise of this problem is simply to verify that the word submitted is indeed an approved and real word and then to make sure that the player has submitted a word that be created out of the letters that appear in their hand.  Sounds simple, right?  Well it is, mostly.  We already have, in this Problem Set, the provided word_list which gives us something to compare all submitted words, to verify for authenticity.  Here is the official problem description.
 

This function should return True if the word is in the word_list and is entirely composed of letters in the hand. Otherwise, it returns False.  This function should not mutate the hand or word_list.

 
Like I mentioned above, this problem is fairly simply.  The implementation is fairly simple, there was only one real hump I had to get over.  One that I’m still working on.  Understanding how get() works.  Get() is a function one can use on dictionaries (a method of dictionaries, if you want to get technical).  As described on docs.python.org, it; returns the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.  To better explain, here is an example dictionary:
 
hand = {'a':1, 'q':1, 'l':2, 'm':1, 'u':1, 'i':1}
 
Hand is the name of the dictionary.  A key is the letters, such as ‘a’, or ‘m’.  The value is the frequency in which the letters occur in the hand, or the number listed next to each letter (key).  To use get(), one could simply type print hand.get(‘a’,0), and you would get the number 1 printed in the next line.  If the letter you were looking for did not exist in the dictionary it would return ‘0’.  Learning how to use get() was very useful, as it simplified my function greatly.

def is_valid_word(word, hand, word_list):
   newlist = get_frequency_dict(word)
   newhand = hand.copy()
   if word in word_list:
       for letter in newlist:
           if newhand.get(letter,0) < newlist[letter]:
                return False
       return True            
   else:
       return False
First I create a new dictionary based off of the word submitted, and call it newlist.  Then I copy the hand that was submitted to the function, so that I don’t alter it during my processing.  Then I verify that the word submitted is in the word_list, by using an if statement.  Afterwards I run a for loop for each letter in the newlist, and verify that there are enough appropriate letters needed from the newhand to make up the word.  If all is True (correct), the function will simply return True, and the code is complete.  

Up Next: More Python Love

 

Problem Set 5; problem 2 of 6

September 23, 2011

 

Using and referencing dictionaries was more a part of problem two than problem one.  Learning how to interact with dictionaries was difficult at first, mainly in understanding where and how you could use the syntax.  Learning and understanding how to create copies so I would not alter the originals was something I had to relearn.  A description of problem two is listed below:

You will now write a function that takes a hand and a word as inputs, uses letters from that hand to

spell the word, and returns the remaining letters in the hand.  This function will return True if the word is in the word_list and is entirely composed of letters in the hand. Otherwise, the function returns False.  The function also does not mutate hand or word_list.


The part that was the most difficult for this problem, was re-learning why I needed to make sure the original hand inputted was not altered, and how to do it.  I remembered that there was a copy function but I honestly couldn’t remember how to use it.  Once I got that done, it was only a question of using one of the created functions in the problem set (get_frequency_dict(word), which takes a word and returns a dictionary with each letter being the key to the frequency in which that letter occurred).  Then I used that dictionary it created and went through each key (letter), by using a for loop.  Here is my function below.

 

def update_hand(hand, word):
       newlist = get_frequency_dict(word)
       newhand = hand.copy()
       for letter in newlist:
            if newhand[letter] > 1:
                newhand[letter] = newhand[letter] - 1
            elif newhand[letter] == 1:    
                del newhand[letter]
       return newhand

 


First I assign newlist to a function that creates a dictionary out of the variable word.  Then I create a copy of the hand, so that I don’t alter it during the processing of the function.  I do this by using the copy() function to process it.  Next I institute a for loop, where I go through each letter in the newlist dictionary.  The beginning of the for loop asks the following: if there is a letter that matches the newlist letter, and its key is greater than one, then the function is to subtract one from the key.  If the key is equal to one, then it is simply deleted from the list.  Once all letters have been processed through the for loop, the end result will be a dictionary that only includes letters that are not used in the word submitted.  

The important factor, is that the information that is spit out of this function is not altering some of the information used to create it, because I copied it.  The other important part is that this function can take into account when a player has two or more of the same kind of letter in their hand.  That part was something I realized after most of the problem was finished.  So I had to go back and put in the bit of code that subtracts one from from the key.  Before I had simply been deleting it if it showed up in newlist.  Now THAT was not providing accurate data.  

Up Next: More Python Love
        



 

Problem Set 5; problem 1 of 6

September 22, 2011

As I’ve mentioned in blogs and tweets, I’m onto a new problem set.  This one is finally more along the lines of what I will be doing once I’ve completed the course, i.e. game development.  This problem set is particularly the creation of a game very similar to scrabble but without the board.  Much of the problem set was actually created for me (through the MIT Open Course Ware course information).  The problems I am to solve are just chunks out of the overall game.  The first problem is shown below.

This function returns the score for a word. It assumes the word is a valid word.  The score for a word is the sum of the points for letters in the word, plus 50 points if all n letters are used on the first go.  Letters are scored as in Scrabble; A is worth 1, B is worth 3, C is worth 3, D is worth 2, E is worth 1, and so on.  The dictionary with letters and subsequent values are provided.  


It took me about 4 hours to solve this problem.  The first day I was convinced that the way to solve it was by making the word into a list, and then comparing the lists.  Thankfully I had a days break before I revisited my work, and realized there was a much simpler way to do it.  Here is my function.

 

def get_word_score(word, n):
     total = 0
     for letter in word:
         total += SCRABBLE_LETTER_VALUES [letter]
     if len (word) == n:
         total = total + 50
     return total

SCRABBLE_LETTER_VALUES was not entered because it’s HUGE.  It is a dictionary that associates with every letter in the English alphabet, a point value based on the Scrabble point system.  That dictionary was extremely helpful in creating my function, and represented just why they have dictionaries in python in the first place.  

In this function there are two variables.  The first is a word (a string), that is entered.  The second is n, which is a value for the total amount of letters in the players hand.  This total amount can change, thus it was entered as a variable.  

To start my function off I begin by assigning (designating) total to zero.  I know I need to go through each letter in the word I’ve been given, and figure out what each letter is valued at.  Easiest way to do that is a for loop.  So I go through each letter in my word, and compare it to the keys in the dictionary to find the value associated with each letter.  I then add them up as I go, which also means I’m not missing any repeat letters.  If I had compared the lists in some way, I might have come up with some errors because of multiple occurrences of the same letter in a word.

There isn’t much else to this function, except verifying if the word is using up all the letters in the players hand.  That’s done by verifying the length of the word against the variable n.  If it is, then I simply add 50 points to the total value of total.  Once all items have been processed I simply pop out the value of total at the end of the function.  Dictionaries are very, very useful.     

 

How to find the balance, physically and mentally

September 21, 2011

This is short today, as I've been lately focusing on my mental health.  I just have two questions to ask.  What do you do to take care of yourself mentally and physically?  Do you find there is a delicate balance to making it work?

For myself I feel like I'm constantly battling my wish to be more mentally capable as well as pushing myself physically.  Finding that balance is always a challenge.  I enjoy a variety of sport activities (indoor soccer, ultimate frisbee, running, cycling, rock climbing, hiking, and yoga from time to time).  I also enjoy learning constantly.  Whether that be dead languages, live languages, reading non-fiction for fun, pursuing programming or delving back into piano and french horn when I feel I have the time.  I just never have enough time.  If I had enough time I would devote myself entirely to the study of all and the physical exertion of all activities that I listed above.  But I don't have the time, and therefore must pick at choose.  What do I devote myself to today?  

 

 

Dictionaries and Modules, my own personal perspective

September 20, 2011

I learned more about a couple of important aspects of coding today, dictionaries and modules.

A python dictionary is like a list, except it’s formatted more like the popularly known paperback dictionaries, in that it’s for reference.  One creates a dictionary in python to look up a static set of information.  Unlike our paperback versions with only words and definitions, these dictionaries can be set up with whatever organizational system you want.  

Things can be referenced by letter, by number, using colors or maybe even fruits.  It might be fun, while unproductive, to create a dictionary organized on something totally nonsensical someday...

Another interesting thing I ran into during programming today was modules.  Modules are collections of functions that have been pre-written and set aside to help better organize your code.  You can then import various modules at the beginning of your file, so you don’t have to have a bunch of functions listed there mucking things up.

From what I understand modules are all about allowing programmers access to functions that do general things.  It’s like having access to tons of books that solve problems for you, and provide you with the details if you want it.  The one drawback from this is that there are simply tons of modules out there.  Knowing if one already exists, let alone being able to correctly debug it if you’ve never interacted with it before could prove difficult.  

Many modules have the code provided so you know exactly what it’s supposed to be doing.  A common malady, it seems, is when modules are provided without any of the underlying code being accessible.  That way, if you have a problem in your code, but it’s part of that undocumented function, it makes it incredibly difficult to debug.  Your error is occurring within, but you have no idea how or where. Luckily I'm not really interacting with undocumented modules at this time. But I'm sure it will happen soon...*cue erie suspense violin*


 

 

Discovering your own self-destructiveness

September 19, 2011

  Recently I spent an entire day watching Smallville.  I’ve also been reading fantasy novels or watching TV shows a bunch.  Two things came from this entire lack of productivity.  I distracted myself from all the stress I’ve been dealing with lately because of my mother being in the hospital.  I also wasted a TON of time.  I had lazy muscles and butt sores from sitting all day.  

In order to put a stop to all this time wasting and self destructive behavior I finally created myself a schedule for each day.  

Time Period Work Activities
8am to 10am Answer emails, tweet, read blogs, comment on blogs, find new blogs...
10am to 12pm Programming study with MIT OpenCourseWare
12pm to 1:30pm Post daily blog, write blogs, edit existing blogs...
1:30pm to 3:30pm Brainstorming new game ideas, more tweeting, any HTML/CSS work
3:30pm to 6pm Graphic art projects, photo work as needed; programming as side option
6pm to 7pm Review daily todo list, tweet, anything else needing finalizing
Still allowing for some flexibility with each day, this schedule has greatly increased my productivity.  In order to make me more interested in waking up early each morning, I’ve put my favorite item of the day on first.  My day is planned out based on my brain/productivity levels.  You can see that in the following table below.  

Time Period Brain/Productivity Levels
8am to 10am Medium speed, low to medium focus, partial fog-brain
10am to 12pm High speed, high focus
12pm to 1:30pm High speed, medium to low focus
1:30pm to 3:30pm Medium speed, low focus, sometimes high focus depending
3:30pm to 6pm Low speed, medium to high focus, high creativity as mind wanders
6pm to 7pm Medium speed, medium to low focus
This is the first time I’ve ever created a productivity level assessment of my own brain.  I don’t think I ever would have been able to truly make that assessment, without being self-employed.  There are always variations to my daily schedule.  Such things include pushing a starting time forward 20 minutes, but the baseline schedule stays the same.  And it’s working.

Python Lesson

September 16, 2011
After much frustration and stress, I finally was able to complete the final aspect of this Problem Set.  Here is a description of the 4th problem.

Write a function, called findMaxExpenses, which takes five arguments: a salary

(salary), a percentage of your salary to save (save), a list of annual growth percentages

on investments while you are still working (preRetireGrowthRates), a list of annual

growth percentages on investments while you are retired (postRetireGrowthRates), and

a value for epsilon (epsilon).  As with problems 2 and 3, the lengths of

and postRetireGrowthRates determine the number of years you

plan to be working and retired, respectively.

Use the idea of binary search to find a value for the amount of expenses you can

withdraw each year from your retirement fund, such that at the end of your retirement,

the absolute value of the amount remaining in your retirement fund is less than epsilon

(note that you can overdraw by a small amount).  Start with a range of possible values

for your annual expenses between 0 and your savings at the start of your retirement

(HINT #1: this can be determined by utilizing your solution to problem 2).  Your function

should print out the current estimate for the amount of expenses on each iteration

through the binary search (HINT #2: your binary search should make use of your

solution to problem 3), and should return the estimate for the amount of expenses to

withdraw. (HINT #3


As you can tell from the description, this function is more complicated than the other functions from this Problem Set.  I have to use several of my previous functions, create the final function.  What does this final function do?  It takes the total amount you are depositing into your retirement account, the years you are employed and the interest rates, and determines what your total savings upon retirement will be (otherwise known as problem 2).  Then, you must determine what your total budget is for your years in retirement.  Your total retirement account value is different each year during retirement, because of A, the amount you withdraw each year, and B, the interest that is accrued on the total value of your account.  These two aspects are processed by the function from problem 3.  

To determine my ultimate budget for each year during retirement, I must use the final function from problem three, and search until I find a value for expenses, that will not put me in the hole upon the last year of my life.  That means search through all the possible values to determine which one will leave me with a value greater than zero, but less than .01 (epsilon in this problem).  

Using binary search, I can cut down the time it would take to solve the problem.  Binary search uses the following idea.  Choose a number which lies between zero and 1000.  How does someone else determine that number?  Once can find the solution by systematically choosing the midway point, while also using a higher or lower game.  Start with the first question.  What is the midway point?  It is 500.  Is the answer higher or lower than 500?  It is lower.  Now your minimum and maximum points have changed.  Your minimum value is still zero, but your maximum is now 500.  What is the midway point?  It is 250.  Is the answer higher or lower than 250?  Higher.  Your maximum value is still 500, but your minimum value is now 250.  Slowly but surely you’ll find the answer.  That is the basic idea of binary search.  Now returning to my function for problem 4.

 

def findMaxExpenses(salary,save,preRetireGrowthRates,postRetireGrowthRates,epsilon):
savings = nestEggVariable(salary,save,preRetireGrowthRates)
endtotal = savings[-1]
minguess = 0
maxguess = endtotal + epsilon
finalexpenses = postRetirement(endtotal,postRetireGrowthRates,endtotal/2)
while finalexpenses[-1] < 0 or finalexpenses[-1] > epsilon:  
guess = (maxguess-minguess)/2 + minguess
finalexpenses = postRetirement(endtotal,postRetireGrowthRates,guess)
if finalexpenses[-1] < 0:
maxguess = guess
elif finalexpenses[-1] > epsilon:
minguess = guess
else:
return guess

 

First I define my total savings from each year by using my function nestEggVariable from problem 2 of 4.  This creates a list of the total amount I saved each year.  Next I identify the last entry in that list, as my endtotal.  Then I identify my minguess and maxguess.  Therefore I have the minimum and maximum for my binary search model.  The last part of identification is the finalexpenses.  finalexpenses is the variable used for my postRetirement function.  This function will process, for each year in retirement, the growth rate of my retirement accounts.  The result is a list,  indicating how much I have left at the end of each year during retirement.  Looking at the variables one will see the endtotal savings, the postRetireGrowthRates list, and the first guess in my binary search model.  They are all variables for the function.  My first guess as you can see is the midway point, or half of the endtotal.  

I use a ‘while’ loop to run the binary search.  I state that as long as my last entry in the finalexpenses list (last year of retirement) IS NOT greater than zero and less than epsilon it is to process the following.  First it defines guess as the halfway point between the maxguess and the minguess.  Then it runs the postRetirement function, replacing endtotal/2 with the guess variable.  Now for the actual binary search piece.  I indicate that ‘if’ the last entry of finalexpenses is less than zero my new maxguess is guess.  I am lowering the maximum(maxguess) on my scale because my total account value was less than zero in the end, which means I spent too much money each year during retirement.  However ‘elif’ (else if), my final entry is above epsilon (.01), it seems I spent too little each year during retirement.  Therefore I would increase my minimum guess(minguess) to the value to guess, so that my scale adjusts to include only higher values, and thus bring me closer to my solution.  

Once the binary search has run its course and I have found a value not only above zero, but also below epsilon, I have found the solution to the problem.  Thus my ‘else’ will ‘return’ from the function with the guess last found.  Final answer?  Off of these starting numbers: findMaxExpenses(10000,10,[3,4,5,0,3],[10,5,0,5,1],.01), the answer is: 1229.9528031.

Overview

Just a quick reflection on the difficulties I found when working on this Problem Set.  I think one of the hardest part of this Problem Set was the relative ease I found when completing the first 3 problems.  The final culmination function was the most difficult and it made me implement a binary search.  This was something I hadn’t done before.  But I get ahead of myself.

I wanted to mention the first thing that I had to learn before I could complete the first three problems in this Problem Set.  The first three made me learn to use slices within a function.  Learning to use the last item in a list, whenever and wheresoever needed, by taking a slice of the list.  The next aspect, which was a little more difficult to learn, was how to use lists as variables for functions.  That was a more difficult challenge.  Understanding how to think about lists as you input them into the variable, and how to process their information within the function.  I also have a much better understanding of appending.  

Back to the fourth problem.  I’m still getting used to using multiple functions within one master function.  Making sure I understand the information each of my functions spit out, and knowing how to use them in a function is still taking some work.  The most difficult part was learning how to use and write a binary search.  I attempted to do so on my own several times before I asked for help.  Even then I was still having difficulties because I didn’t understand the need for a minimum value.  Frustrating for myself as well as my helper.  On top of that I had written my code incorrectly, and yet I kept referring to it when trying to understand what I was doing wrong.  Each time I referenced it, it made me more and more confused as to what I was doing wrong, and where the error was.  

After some serious discussion, I finally started understanding what I was misunderstanding.  What I think might have been more helpful for myself, was if I allowed myself to have multiple versions of the same function on different files, without looking at the former functions, so I didn’t have them there to visually confuse me.  In all honesty, although I understand how my function works, I realise I still have some holes when it comes to simply understanding binary function in a mathematical sense.  I can’t simply visualize it.  I know that is causing me some difficulties, and it will be something I work on in the coming weeks.  I know that I can recreate things that I’ve seen and had explained to me, but I fear for my ability to understand something I’ve never seen before.  

That’s it for today.  I wish everyone a happy, happy weekend!           

 

Binary search pains

September 15, 2011

Sometimes when I program, it flows well and I seem to get everything.  Other times, I feel like nothing makes sense, and then it all cascades downhill into a swampy, sticky mess.  Then it seems that more and more of the problem is not working, and it becomes more convoluted, and my frustration increases.  

I just spent my morning allotment of programming time on one problem.  When I first started I thought the final bits were sitting right in front of me, and that I would be able to complete it in no time.  Then as time wore on it became more complicated, I started to rewrite my code over and over.  By the end of it, after asking for help multiple times, I felt like I was just banging my head against a wall, and I was almost ready to cry.  Why wasn’t I understanding it?  What wasn’t clicking?  

This problem that I’m talking about, that is causing me so much pain and anguish, is the culmination of the recent problem set I’ve been working on.  This particular problem is using a part of coding I haven’t yet used before, and it’s proving to be a challenge.  This part is called binary search.  Anyways, when I went to the wiki it didn’t help that the main example I looked at was written in Pascal (different programming language) which I tried to interpret.  That didn’t work out so well.  That same example was also written to be used against an array, which was also not helpful.  

I was hoping to finish that piece of code, and write up my final blog entries for the problem set today.  Suffice it to say I’m still not finished.  I’m fairly frustrated at the moment, but I decided to take some time before I dive back in.  I think I might go on a bike ride to let the stress fizzle away.         

 

Stress Factories

September 14, 2011

Where does my stress come from?
  1. Unsolved problems; because a hangnail is always painful.
  2. Lack of funds; because money stresses us all out.
  3. Over planning my schedule; Too much to do and not enough time to do it all.  
  4. Guilt; over anything that falls through the cracks.
So if you add all of these stress factories together, and then refer to my previous entry about how I react to stress, you can probably imagine that I use distractions (usually exercise and TV shows) coupled with talk(which is really a combination of fighting and stress chatter).  
 
Ugh, escape sounds so good sometimes...Now back to work.

 

Takotsubo syndrome

September 13, 2011

 

It’s been about 5 days since I’ve had a chance to sit at my computer.  My mother, nigh on 60 years old, had gone to a conference about 4 hours out of town.  Then, after some complications from an old problem, was admitted to the local emergency room.  Robey and I then headed down there to help out, take over her room, pack her things, and deliver her personal items she might need.  She was discharged on Sunday, and we drove her back home.  All was well until the next morning when she was taken by emergency vehicle to the local hospital, as she was continuing to have complications.  After further testing, medication, she is on her way to recovery after the final testing done earlier this morning.  Check my photos link above for pics!

That said, I’m now home, and able to work again.  It seems my mother stresses out too much, which really isn’t a big surprise, and that stress further complicated her recovery.  Her near future includes lots of relaxation, and probably a reassessment of her obligations and plans.  She is not happy about having to start to cut back on some of her hobbies and other projects.  

This experience brought to light some information about a problem called Takotsubo syndrome.  It seems this heart condition, which is sometimes stress induced, is currently on the rise.  It used to be a more rare form of heart disease.  I would deduce its rise in occurrence has something to do with the higher stress lives most of us experience these days.  My mother, while living a rather stressful life is by no means the top of the scale.  I’ve always known about the problems stress can cause mentally and emotionally.  It seems the physical signs are starting to take more presence in our lives.  

So, I’ll be doing my best to calm my own life down a bit, so that I can help my mothers transition to a less stressful lifestyle.  They always chat about stopping to smell the roses, but I think there is more to it than simply enjoy life as you live it.  It’s also about making sure you have a longer life to enjoy.  Take care of yourself, and take time to relax.  It’s more worth it than you may believe.

 

 

Links