In 9 weeks and 2 days, I will be starting App Academy in San Francisco. For my Pythonistas out there, yes I am aware I may be made fun of for becoming a Rubyist, but I'm confident this is a good decision for me to have career options as a developer for Rails, Backbone, or Django. For those unfamiliar with App Academy, it is a 12 week hacker bootcamp for Ruby, Rails, SQL, JavaScript, and Backbone.js that includes portfolio building, interview preparation and a final project. What is the most different about App Academy is their payment model. Tuition is collected after you get a job, 18% of your yearly earnings payable over 6 months. As someone with two kids too young for public schools, I'm not going to see much of my first 12 paychecks, but it will still be worth the investment.
I learned more about the program through the application and acceptance process. I submitted my application 2.5 weeks ago, never having done any Ruby, but with Python experience. I got an email back the same day for me to do the coding challenge that included reading assignments from Ruby Monk and Chris Pine's Learn to Program. I spent about 5 days learning Ruby very slowly, because I was visiting family. App Academy does not give a deadline for the coding challenge, so you can take the time you need to prepare. I was prepared to do the coding challenge in Ruby, but the directions said I could do Ruby or Python and it would take about 40 minutes. It took me about 20 minutes to do it in Python while my 9 month old was nursing and my almost 3 year old was "going Bananas" with a cartoon on Netflix (Bruno and the Banana Bunch). The next day, I got an email to schedule an interview with a TA. The Skype interview was audio only and consisted of just one programming question. I did make an error with initializing a variable in the wrong level of my nested loops, but solved it in 9 minutes in Python. I made an effort to talk through my logic process while solving the problem. Less than an hour later, I got an email to schedule a final interview with Kush Patel. There was another live coding problem, which took me 12 minutes to solve in Ruby. I talked through some of the logic, but I realized I was humming at one point (something I do when I'm enjoying a problem). Kush did ask some questions to make sure the program could work for me and that I was aware of some of the requirements. I was accepted the next day, which was quite a surprise because it was a Saturday. So from the time I completed the coding challenge, the interview process took me only 6 days.
One of the requirements of the program is the reason I was being silly with my post title. Every weekday, students post a blog entry with the week number and day number. I have 9 weeks and 2 days until my cohort begins, hence negative numbers. Although tuition is collected afterwards, there is a $3,000 deposit. The deposit holds your spot in the program and goes towards that 18% fee (tuition) when you do get a job, plus or minus any money from fees. Fees are used to keep students focused by penalizing tardiness, absences, getting off task with phones or emails, and failing to write daily blog posts. Fines are redistributed among the graduates at the end so that you only lose money if you were worse than your classmates about following the rules. Another rule of the program is that students may be asked to leave the program. Assessments are taken each week to evaluate if someone is falling behind. It is definitely an intense program, but I'm prepared for a challenge. The gamer inside me expected some fireworks or ominous music when I transferred the first $1250 to hold my place in the program yesterday. And so our hero begins her journey... I've currently worked through 12 chapters of Chris Pine's Learn to Program, 2 chapters of Peter Cooper's Beginning Ruby, and the first half of the Ruby Primer section on Ruby Monk. I am preparing to have a strong foundation for W1D1 !!
Design
Saturday, May 31, 2014
Thursday, February 13, 2014
Recursive Turtle Tree
I know the title of this post may sound like random words thrown together, but it's actually a really cool activity to learn about recursion using the turtle module in Python (Linux users need to install tkinter). I've been learning about algorithms and abstract data structures as part of my faking a CS degree personal mission. Problem Solving with Algorithms and Data Structures has been a fantastic resource so far (and free). Although the authors' explanation of recursion is the best I've ever seen, I think I could just add a little to the tree drawing example. Here's the program they provide:
import turtle
def tree(branchLen,t):
if branchLen > 5:
t.forward(branchLen)
t.right(20)
tree(branchLen-15,t)
t.left(40)
tree(branchLen-15,t)
t.right(20)
t.backward(branchLen)
def main():
t = turtle.Turtle()
myWin = turtle.Screen()
t.left(90)
t.up()
t.backward(100)
t.down()
t.color("green")
tree(75,t)
myWin.exitonclick()
main()
import turtle
def tree(branchLen,t):
if branchLen > 5:
t.forward(branchLen)
t.right(20)
tree(branchLen-15,t)
t.left(40)
tree(branchLen-15,t)
t.right(20)
t.backward(branchLen)
def main():
t = turtle.Turtle()
myWin = turtle.Screen()
t.left(90)
t.up()
t.backward(100)
t.down()
t.color("green")
tree(75,t)
myWin.exitonclick()
main()
Now I'm going to focus on the tree function. Notice tree calls itself twice. Now to step through how this function works, I am going to give each line a number and each recursive call a number such that 1.2 is the second time the first recursive call has been made and 2.3 is the third time the second call has been made.
def tree(branchLen,t):
0 if branchLen > 5:
1 t.forward(branchLen)
2 t.right(20)
3 tree(branchLen-15,t) first recursive call
4 t.left(40)
5 tree(branchLen-15,t) second recursive call
6 t.right(20)
7 t.backward(branchLen)
Let's trace branchLen = 30, following the code and what the turtle does. I've color coded each recursive call:
Code Line Action Recursive Call
0 Passes > 5 test none
1 Forward 30 none
2 Turns right 20 degrees none
3 Calls tree(15) none
0 Passes > 5 test 1.1
1 Forward 15 1.1
2 Turns right 20 degrees 1.1
3 Calls tree(0) 1.1
0 Fails > 5 test 1.2
4 Turns Left 40 degrees 1.1
5 Calls tree(0) 1.1
0 Fails > 5 test 2.1
6 Turns right 20 degrees 1.1
7 Backward 15 1.1
4 Turns Left 40 degrees none
5 Calls tree(15) none
0 Passes > 5 test 2.2
1 Forward 15 2.2
2 Turns right 20 degrees 2.2
3 Calls tree(0) 2.2
0 Fails > 5 test 1.3
4 Turns Left 40 degrees 2.2
5 Calls tree(0) 2.2
0 Fails > 5 test 2.3
6 Turns right 20 degrees 2.2
7 Backward 15 2.2
6 Turns right 20 degrees none
7 Backward 30 none
If you choose a color such as red or orange, you can see how the function is executed in its entirety, but with interruptions. The colors that appear nested, such as orange inside the red, appear higher in the stack frame. They are completed first even though they started second, but the program continues to the red after the orange is completed. The next value of branchLen to create more recursive calls is 45. You could also try tracing tree(45), using tree(30) as a shortcut to emphasize the benefit of recursion.
0 if branchLen > 5:
1 t.forward(branchLen)
2 t.right(20)
3 tree(branchLen-15,t) first recursive call
4 t.left(40)
5 tree(branchLen-15,t) second recursive call
6 t.right(20)
7 t.backward(branchLen)
Let's trace branchLen = 30, following the code and what the turtle does. I've color coded each recursive call:
Code Line Action Recursive Call
0 Passes > 5 test none
1 Forward 30 none
2 Turns right 20 degrees none
3 Calls tree(15) none
0 Passes > 5 test 1.1
1 Forward 15 1.1
2 Turns right 20 degrees 1.1
3 Calls tree(0) 1.1
0 Fails > 5 test 1.2
4 Turns Left 40 degrees 1.1
5 Calls tree(0) 1.1
0 Fails > 5 test 2.1
6 Turns right 20 degrees 1.1
7 Backward 15 1.1
4 Turns Left 40 degrees none
5 Calls tree(15) none
0 Passes > 5 test 2.2
1 Forward 15 2.2
2 Turns right 20 degrees 2.2
3 Calls tree(0) 2.2
0 Fails > 5 test 1.3
4 Turns Left 40 degrees 2.2
5 Calls tree(0) 2.2
0 Fails > 5 test 2.3
6 Turns right 20 degrees 2.2
7 Backward 15 2.2
6 Turns right 20 degrees none
7 Backward 30 none
If you choose a color such as red or orange, you can see how the function is executed in its entirety, but with interruptions. The colors that appear nested, such as orange inside the red, appear higher in the stack frame. They are completed first even though they started second, but the program continues to the red after the orange is completed. The next value of branchLen to create more recursive calls is 45. You could also try tracing tree(45), using tree(30) as a shortcut to emphasize the benefit of recursion.
Coursera -- Introduction to Interactive Programming in Python
A couple months ago, I took a free course on Coursera.com offered by Rice University and taught by Joe Warren, Scott Rixner, John Greiner, and Stephen Wong. Coursera offers the course a couple times a year, with 2014 offerings including March 24th and October 7th. The course is now part of the Fundamentals of Computing specialization and you earn a certificate after completion with the ability to earn additional "distinction" for scoring an A in the course (I did).
I recommend the course for anyone between "Isn't Python a snake?" to "Why should I use classes?" Students learn Python by developing simple games in CodeSkulptor, which includes a simple GUI like PyGame without using a terminal or setting up a coding environment. Homework includes quizzes over video material, building games in Python, and evaluating peers' code. I enjoyed the peer reviews because you can recognize common mistakes and see how other people solved the same problem you did. The game development approach finally helped me understand the point of object oriented programming. I went from fear of using classes, to empowered by building my own classes in the last three weeks of the course.
I am looking forward to the next course in the Fundamentals of Computing specialization, Principles of Computing. It is exciting to have an option for continuing to learn after a course. Us self-taught learners often waste time trying to decide what is the most appropriate and useful for us to learn next. If you can tolerate some corny Big Bang references and want to take your Python development to the level of using and understanding classes, you can enroll for free on Coursera.com
I recommend the course for anyone between "Isn't Python a snake?" to "Why should I use classes?" Students learn Python by developing simple games in CodeSkulptor, which includes a simple GUI like PyGame without using a terminal or setting up a coding environment. Homework includes quizzes over video material, building games in Python, and evaluating peers' code. I enjoyed the peer reviews because you can recognize common mistakes and see how other people solved the same problem you did. The game development approach finally helped me understand the point of object oriented programming. I went from fear of using classes, to empowered by building my own classes in the last three weeks of the course.
I am looking forward to the next course in the Fundamentals of Computing specialization, Principles of Computing. It is exciting to have an option for continuing to learn after a course. Us self-taught learners often waste time trying to decide what is the most appropriate and useful for us to learn next. If you can tolerate some corny Big Bang references and want to take your Python development to the level of using and understanding classes, you can enroll for free on Coursera.com
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.
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.'
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.
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
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:
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.
>>> 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.
Subscribe to:
Posts (Atom)