Design

Tuesday, June 12, 2012

Moving :)

I have been busy with reStructuredText lately because I'm moving to housewifehacker.com. I've also been busy with reading entrepreneur blogs and books because our conference management system has been accepted to StartUp Chile to receive $40,000 in equity free funding. July is going to be busy with hacking on different technologies as well as getting our work visas to live in Chile. My new blog will have categories for Code and StartUp, maybe Personal/Travel too, so you can subscribe to which categories you are interested in. I dont have feed burner or RSS set up on the new domain yet, but you can check out my most recent code tutorial on there now. It's a guess the number script using the new preferred string formatting for python. It also addresses some exception handling, the process of developing a script, and a teensy bit about global variables and scope. Please follow me on twitter @housewifehacker

Tuesday, May 15, 2012

Simple Dictionary Practice: Is Anagram?

I do not use dictionaries very often. Friday, I was without internet all day, so I took the opportunity to play with dir() and help() to discover some dictionary properties. My short-lived obsession with Draw Something on the iPhone has gotten me interested in anagrams (kicked the habit by reading programming books). I believe using dictionaries is the fastest and most accurate way to determine if two words are anagrams of each other.

A dictionary is an unordered set of key: value pairs. Keys must be an immutable type. Values can be anything. Review on mutable versus immutable here. Being unordered causes some interesting properties for working with dictionaries, different from any other python data structure. Instead of being indexed by numbers, dictionaries are indexed by keys. Because they are indexed by keys, each key is unique within it's dictionary. If two dictionaries with the same keys are added to each other, the values of the same data type combine. This is convenient for our anagram activity. But first, some dictionary review.


>>> sample_dict = {}        # creates an empty dictionary
>>> type( sample_dict )
<type 'dict'>
>>> sample_dict['Name'] = 'Jessie'        # creating a key:value pair
>>> sample_dict['Age'] = 23        # another key:value pair
>>> sample_dict
{'Age': 23, 'Name': 'Jessie'}
>>> sample_dict2 = {'Name': 'Jessie', 'Age': 23}        # another way to create dict
>>> type (sample_dict2)
<type 'dict'>
>>> sample_dict2
{'Age': 23, 'Name': 'Jessie'}
>>> sample_dict + sample_dict2        # cannot add dictionaries, only values
Traceback (most recent call last):
  File "<console>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'dict' and 'dict'
>>> sample_dict['Age'] + sample_dict2['Age']        # adds values
46
>>> sample_dict.keys()
['Age', 'Name']
>>> sample_dict.values()
[23, 'Jessie']
>>> type( sample_dict.values() )        # keys and values are returned as lists
<type 'list'>
>>> sample_dict.get('Age')        # gets the value at a specific key
23
>>> type( sample_dict.get('Age'))         # value maintains data type in dictionary
<type 'int'>
>>> sample_dict.has_key('Age')        # D.has_key() returns boolean
True
>>> sample_dict3 = {'Children': 'Graham'}
>>> sample_dict3.update(sample_dict)        # update keys and values
>>> sample_dict
{'Age': 23, 'Name': 'Jessie'}
>>> sample_dict3        # Children field is added as a key:value pair
{'Age': 23, 'Children': 'Graham', 'Name': 'Jessie'}
>>> {'Age': 23, 'Name': 'Jessie'} == {'Name': 'Jessie', 'Age': 23}        # different order is equal
True


How do we know if two words are anagrams? Consider the anagrams odor and door. We could say that they are reshuffled strings. Each word uses the same letters, but in a different order: 2 o's, 1 r, and 1 d. My simple program creates empty dictionaries for the two words being compared, stores the letters as keys, and adds to the value for each occurrence of the same letter, then checks that the dictionaries are equivalent. I have not included exception handling and I made the design decision to count white space as part of the anagram such that 'abc def' is not an anagram of 'fdeabc,' but is an anagram of 'abc fed.'


def get_dict(word, count):
     for i in word.lower():
         if count.has_key(i):
             count[i] += 1
         else:
             count[i] = 1
     return count

 def main():
     word1 = raw_input("What is the first word? \n")
     word2 = raw_input("What is the second? \n")
     count1 = {}
     count2 = {}
     count1 = get_dict(word1, count1)                              
     count2 = get_dict(word2, count2)
     if count1 == count2:
         print("Yes, those are anagrams!\n")
     else:
         print("No, you've failed \n")

 if __name__ == "__main__":
     main()


Friday, May 11, 2012

Book Review: The Practice of Programming

Affiliate Link

The Practice of Programming, written by Brian W. Kernighan and Rob Pike, was originally published in 1999. Although most programming books more than a couple years old are obsolete with out of date technology, The Practice of Programming is a pragmatic guide to become a better programmer regardless of your chosen language, framework, or supporting technologies. To quote the epilogue, "The world of computing changes all the time... but there are some constants, some points of stability, where lessons and insight from the past can help with the future." I highly recommend this book to any programmer who wants to establish good habits for writing understandable and consistent code. I also recommend this for programmers who want to or need to be able to work on projects with other developers. Although the exercises and examples were written in languages other than python, I was able to learn a lot. I reflected a lot on my own code, figured out new questions to ask about python, and am more appreciative that python does not suffer from some of the common pitfalls of other languages.

Monday, May 7, 2012

Mutable versus Immutable Objects

Strings, lists, tuples, integers, float, dictionaries, and sets are all types of python objects with different properties and uses. When using an object in a program or in your terminal, your session assigns an Id to access the computer's memory. The Id will be unique each session and on each computer, so the actual number returned by the id() function is irrelevant. What is relevant is when that number changes. If the id changes as the value changes, the computer had to assign a new id to the immutable object. If the id stays the same, then it is a mutable object, because the value associated with the id can be changed without changing the id. Integers are immutable:

>>> x = 5
>>> y = x    # direct the reference of y to be the reference of x
>>> id(x) == id(y)    # x and y point to same reference
True
>>> x = 4    # change the value of x
>>> id(x) == id(y)    # the id of x changed when we changed the value
False
>>> x == y    # the value of y did not change with x
False


I'm the type of learner that skims through vocabulary lessons to get to the action, but understanding this next part will save you some headaches when trying to manipulate mutable objects. Look what happens when I try to do the same thing I just did to the integers, but now to a list:

>>> x = [5]
>>> y = x    # direct the reference of y to be the reference of x
>>> id(x) == id(y)    # x and y point to the same reference
True
>>> x.append(4)    #change x from [5] to [5, 4]
>>> id(x) == id(y)    # x and y still point to the same reference
True
>>> x == y    # y changed with x
True
>>> y
[5, 4]
>>> z = [5, 5]    
>>> id(z)    # will be a different number for everyone
3075316972L
>>> z.append(3)    #z is now [5, 5, 3]
>>> id(z)    # id is constant, the list is mutable
3075316972L


I stumbled upon this while using random.shuffle on a list, while wishing to keep a copy of the list in it's original form. As you can see by assigning x equal to y, the lists changed together. That was an ineffective way to make a copy because all I did was assign the same Id two different names. Try determining if the other object types are mutable or immutable. I don't want to spoil the fun for you.

Sunday, April 22, 2012

Python Style Guide

Did you realize Python has a style guide to clarify consistent and readable code? It covers topics such as white space of indentations in-line, capitalization of variable, function, and class names, and formatting of comments. Read Pep8

Now I look at my code examples and see a whole lot of ugly. Some good news is that some of the proper styles can be integrated into your vim configuration. A tab on your keyboard can type four spaces. A red line can be drawn vertically to show when a line exceeds the recommended 79 characters. The other good news is that you can run the pep8 script to find style errors. I am going to make an effort to follow the style guide, as well as improve my names. By using "is" to preface boolean tests, verbs such as "get" prefacing function names, and complete words or widely accepted abbreviations (such as str for string), my code can be more readable. I am also going to make my names something that I can sound out. As my code becomes more complicated, variable class and method names are easier to remember if you can pronounce them out loud. 

To use pep8, you simply install it using pip or easy install, run it against your python file, then read the corrections pep8 expects. Example corrections may be that two empty lines were expected instead of one, max line length was surpassed, or extra spacing was found. The script prints the lines that each instance is found on, so you can easily make changes if you want to comply with the preferred style. Documentation can be found here.

I am reaching a stage in my learning where I am reading more code than I am writing. Ambiguous names, inconsistent capitalization, incorrect spelling, and weird in-line spacing makes reading code more difficult. I did have the mindset that if Python didn't care, why should I? Well, now I do care. Just like when learning a spoken language, reading is an important part of learning how to communicate with the language properly.

Tuesday, April 17, 2012

Just a reflection

We have moved to Chile. Yes, the country. I really like it ere, except that my husband's laptop warranty does not apply here. So because he spilt Zuko on his computer, he is using mine and I cannot code Python on an iPhone. I have had some recent experiences that I thought I'd share. First, I want to get better with Linux. If you do not know Linux, you are not a nerd and you are powerless to improve your operating system and most of your coding environment. A friend's business uses Linux machines as kiosks, so I was setting up all the applications they use on their newest system. The newest version of Ubuntu is insanely beginner friendly. Instead of just giving an error sound when you've messed up, it attempts to correct your mistake or explain why you couldn't do what you were trying to do. Of course Linux is free and so are the programs for it. Just about anything you would buy for your Windows or iOS computer has a free open source version that runs on Linux. In Linux, you can customize everything to suit your needs and style. I can have a window manager that allows me to never use my touchpad/mouse. With a custom operating system and vim configuration, coding could be more productive.

Another reflection is the cool use of Python for games. Blender is a gaming engine with a GUI, simple enough for artistic people to draw and program 3D games. Blender can also be used for video animations. I like Khan Academy, but think that their videos resemble a lecture. After five minutes, I want to fall asleep or check Facebook. I want to try to make instructional videos in Blender to teach math and physics. Blender has a built in physics engine, so I do not think creating physics animations would be difficult. Check out Pissed Off Penguins on YouTube to see Blender being used to make an Angry Birds similar game. The other cool gaming technology in Python is Pygame. I was not previously interested in Pygame. Tetris, Woohoo. But a friend's application of Pygame in his kiosks is so intriguing to me. I now want to learn other applications of PyGame.

I learned what I could from SICP, but it wasn't applicable to my interests. I like math, physics, and chemistry, but I'm not interested in using Scheme to prove all of Newton's theorems. The first chapter was worth reading, but that's all. So for now I am learning Spanish, playing with my dSLR, and wishing I could build something with Python. Web apps are intimidating, but I'm pretty sure I can do Blender and PyGame. Hopefully I'll get my computer back in the next three weeks, but probably not :(

Thursday, March 15, 2012

ABC and The Birth of Python

As I have mentioned in a previous post, I am very interested in the how and why of programming, which includes the history of different languages. One of the posters at PyCon 2012 held in Santa Clara over the past week was about the programming language ABC. There is a Youtube video that is unfortunately edited poorly and has the microphones off during the most important part of the interview here.

Guido van Rossum is often called "The Father of Python" because of his critical involvement in the development of the language. He wanted programming to be more intuitive, easier to learn, written in true English, and available to everyone. However, he did not start Python until ABC lost its funding. He also did not come up with all the basic principles on his own. Although he did work on the ABC project, he was not one of the original creators, nor is he attributed a large portion of the credit. Leo Geurts, Lambert Meertens, and Steven Pemberton are acknowledged as the leads on the ABC Project sponsored by CWI, Netherlands.

Like Python, ABC uses indentions (white space) to organize loops. ABC is also much easier to read than the programming languages of its time, BASIC, Pascal, and AWK. Tuples, lists, and strings were important in ABC, as they now are in Python. Tuples and indentations were actually utilized by SETL before they were used by ABC.

By looking at examples of SETL developed in the late 1960's, then examples of ABC from the 1980's, and finally modern Python, the progression of the structure and readability is apparent. Python is a beautiful language because of its intuitive design.

Wednesday, March 14, 2012

SICP Square Root Procedure

I haven't progressed much further in SICP. There have been so many interruptions. We traveled to Santa Clara for Pycon, where my husband, sontek, lead a tutorial on gevent, socketio, and realtime web (all things currently above my comprehension). Our son met Steve Holden, the chair of the Python Foundation, and many other developers known in the world of Python. I was hanging out in the lobby of the conference center one day so that I could see some of my husband despite the time involvement of the conference. Oddly enough, my SICP book got just as much attention as having a baby in a stroller and being female. I was more than the elephant in the room. I was a pink elephant wearing roller skates.

Continuing with SICP, I want to discuss the square root procedure example. It is excellent at demonstrating a lot of basic programming principles. Of course, Python has excellent math tools that make defining a procedure for square root unneccesary, but let's just do it for fun. First, we need to understand Newton's Method.

Let's pretend we did not know the square root of 9. We GUESS the answer is 2. But 2 squared is 4. So how do we get closer to the answer? We take the average of our GUESS and X, which is 9, divided by our most recent guess. The average would be 2.75 ( (9/2+2)/2 ). Now 2.75 becomes our new GUESS. We repeat, until guess squared is equal to 9, our x. So what does our code need to do?

make a guess -> square guess to check if good enough -> take the average of guess and x divided by guess if not good enough -> use computed average to improve guess -> square guess to check if good enough -> take the average...
An iterative procedure (repeating) until when?

Some numbers may take a very long time to solve exactly, or the square root may be a decimal with over 10 numbers beyond the decimal, so we also need to allow for some error. When we check if the square of the guess is equal to our x value, we can allow a difference less than .001, between the squared guess and the value of x, ending the iterations. We also need to define what our original guess will be. SICP uses 1.0, so let's try that. In both lisp and python, a number with a decimal allows floating numbers to be computed, while an integer without a decimal does not. Some of our definitions are modular, or reusable, so I'm going to give square, average, and abs their own definitions. I am ignoring the built-in absolute value, just so we can do more coding. I'm calling the absolute value definition abs2. I solve this problem in a different order than SICP, so I'm going to show my logic, in Python.

First, I wrote my code in Vim, so I could fix typos easily and experiment more quickly. In my terminal, I created sqrtsicp.py:

vim sqrtsicp.py

Our modular definitions mentioned previously are easy. Let's get them out of the way.
def square(x):
    return x*x

#naming absolute as abs2 to avoid built-in "abs"
def abs2(x):
    if x<0:
        return -x
   else:
        return x

def average(x,y):
   return (x+y)/2

Now for the hard part. We'll skip the first guess right now. The iterative part involves checking if our guess is good enough, then improving our guess if it is not good enough (good enough is false), only to try to determine if our improved guess is good enough.

def sqrt_iter(guess):
   if good_enough(guess):
       return guess
   else:
       return sqrt_iter(improve(guess))

Next we define how we determine if good_enough is true and how to improve our guess. Both of these need to know the value of x to compute.

def good_enough(guess,x):
   return abs2(square(guess)-x)<.001

def improve(guess,x):
    return average(guess,x/guess)

Now we have two problems. One, the x is being used for good_enough() and improve() without receiving the value of x from sqrt_iter(). Second, we need a starting guess. This is the point where I put good_enough(), improve() and sqrt_iter() all together and give it an initial guess. Our variable x is a constant and can be passed in from the overall procedure sqrt().
def sqrt(x):
    def good_enough(guess):
         return abs2(square(guess)-x)<.001
    def improve(guess):
         return average(guess,x/guess)  
    def sqrt_iter(guess):      
         if good_enough(guess):          
             return guess
         else:
             return sqrt_iter(improve(guess))
     return sqrt_iter(1.0)

It's good structuring to have all your definitions before your actions. The final line is the return function that causes the dominos to fall. sqrt_iter() calls itself on the new guess if our latest guess was not good enough. "Calling itself" is known as recursion. Now just make it a program. Within my file, I define the main procedure (not sure of the programmers vernacular)where my program is going to ask what to take the square root of. I want the input to be any positive number, including decimals. I want to use exception handling to ask for a floating number if the user inputs a string. I'm also going to define the decimal places for the output of the square root procedure to 3 digits past the decimal. If a negative number is entered, I ask for a positive number and attempt the program again. If a string is entered, I say "Oops, that's not a number" before calling the program again.

def main():
    try:
        x=float(raw_input("What number do you want to find the square root of? "))
        answer = sqrt(x)
        print("The answer is \n%.3f") %answer
    except:
        print("Oops, that is not a number")
        main()

if __name__=="__main__":
    main()

Those three pieces combined are a completed program. In my terminal, I can run it by typing:
python sqrtsicp.py

Playing with it, I attempt to find the square root of -9, 874, .04, and L. All my results are what I expect. This may be a good candidate for selenium testing or a unit test in more complicated programs. For another example of exception handling, view my Caesar's Shift. For more information of float from wikipedia, read this article. You can also refresh your math tools knowledge, including absolute value here.

Friday, March 9, 2012

Applicative Order Versus Normal Order Interpreter

How would you solve for c in the following problem? Ignore computer programming languages for just a minute.
b=(a+2)*(a+1) c=a*b a=3
Choice 1:
c=(3)*(3+2)*(3+1)
c=3*5*4
c=60
Choice 2:
c= (3)*((3+2)*(3+1))
c=(3)*(5*4)
c=(3)*(20)
c=60

They look very similar and yield the same result, however they act differently. In choice 1, the numbers are substituted and evaluated at the end. In Choice 2, the intermediate step (solving for b) is completed before evaluating for c. Choice 2 is applicative order, or strict evaluation. Choice 1 is normal order, also known as lazy evaluation because it only calls what is needed. The Lisp interpreter acts like Choice 2.

Knowing that lisp is applicative-order, we can now theorize the results of the somewhat famous Ben Bitdiddle Test, exercise 1.5 in SICP.I attempted to predict the outcome yesterday when I did not have access to my computer. I'm still bitter about it. First is the example written in lisp. Second is the test translated into Python. Do you think lisp and python act the same? What will they do when tested?
(define (p) (p))
(define (test x y)
(if (= x 0)
0
y))

(test 0 (p))
Or in Python
def p():
return p()

def test(x, y):
return 0 if x==0 else y

test(0, p())

I spent about 45 minutes irritated, thinking there was no way lisp would return either 0 or y, because the p would be looping forever, I was able to get on a computer. I WAS RIGHT! Applicative order interpreters cannot evaluate the test, because they are too concerned with the definition of p. "Lazy" or normal order interpreters only apply the needed information, so they are able to return 0. According to this test, Python is also a strict interpreter, using applicative order like lisp. I expect the differences between normal order and applicative order will be relevant again in further reading of SICP.

Saturday, March 3, 2012

Getting Back Into It

It has been awhile since I have posted anything for two reasons. First, I got stuck. Python came easy for me, but programming requires much more than knowing one language. For that reason, I have decided to resume my learning with more elementary programming concepts. Some people learn by doing, but I learn by dissecting. I need to know how and why things work the way they do. Which programming languages came first? How does a program evaluate a complex math problem with variables? What are the strengths and weaknesses of each of the languages? What are interpreters and how do they work? How does code become a website? My second reason for my absence is that I had a baby. Now 8 months old, he is a little less demanding of my attention and energy than he was before he was capable of sitting up on his own.

I am currently reading Structure and Interpretation of Computer Programs. SICP and Little Schemer are used to teach generalized computer programming principles, utilizing the languages of LISP and Scheme for examples. Both books were created at MIT for computer programmers. Lisp is the second oldest programming language still in use. Reddit.com was written in Lisp before it was converted to Python. Unlike how Python is organized by white space, Lisp uses parenthesis. A ridiculous amount of parenthesis. I have not yet attempted to write code in Lisp, but I am anticipating customizing a VIM configuration for using only with Lisp will be beneficial. I am enjoying the conciseness and organization of Lisp, compared to Python. Below is an example of the same mathematical expression in the two languages.

Python
3 * a + 7 + b
Lisp
(+ (* 3 a) 7 b)

I'll be discussing any "Eureka" revelations here on the blog, though it may take me a couple weeks to get through SICP.