Saturday, April 7, 2012

Python: How to search a list of class element by their data (self.name) variable

Reference: http://stackoverflow.com/q/10052322/1276534
Credits: nitin, kindall

Imagine you have a class of Food, and you want to create a list that store your class of Food. How do you search your class element within your list? Take a look at the code.
class Food:
    def __init__(self, name):
        self.name = name

chicken = Food('Egg')
cow = Food('Beef')
potato = Food('French Fries')

# And then you create the list of food?
myFoodList = [chicken, cow, potato]
The way you want to implement your class so you can search through them by their name variable is done via dictionary. (This is one way to do it, set also might work depend on your class's implementation and required functionality).
class Food:
    lookup = {}
    def __init__(self, name):
        self.name = name
        Food.lookup[name] = self

chicken = Food('Egg')
cow = Food('Beef')
potato = Food('French Fries')

# Example of a lookup from the dictionary
# If your name is in your class Food's lookup dictionary
if 'Egg' in Food.lookup:
    # Do something that you want
    print (Food.lookup['Egg'].name)

Friday, April 6, 2012

Python: How to remove, or pop an element randomly from a list

Reference: http://stackoverflow.com/q/10048069/1276534
Credit: Henrik, F.J, Óscar López, Niklas B.

Assuming you want to randomly remove an element from your list, you can use the random module, to generate a random number, between the valid index in your list. Take a look at the code below.
# Import the random module
import random

# This is your list with some number
# But you can of course have anything you in your list
myList = [1, 3, 5, 7, 9, 11]

# Method #1
myList.pop(random.randrange(len(myList)))

# Method #2 (This one will change your list)
random.shuffle(myList)
# While my list is not empty
while myList:
    myList.pop

(Method 1) Let's studying this code from the inner to the outer layer.
  1. We get the length of the list, with my len(myList)
  2. Then we call randrange(), what randrange does it return a number that is pick randomly between the range we provide it. But except we do not actually create this list. Like range() would.
  3. Then finally we pop it from our list.
(Method 2) This will be good, if you want to use your list all together, instead of just popping one element. This is used in the csci133 example in the playing deck, since you have to shuffle your whole deck and then pick 1 card at a time. It make sense to have it shuffled.

    Thursday, April 5, 2012

    Python: When NOT To use Global Variable, Use Return!

    Reference: http://stackoverflow.com/q/10036747/1276534
    Credit: Ricky, jdi, Maty

    Using global variable in your Python function is really easy, but today I read a post that explain why not to use it. And I found it make a lot of sense, I am not used to write without the pass by reference. Take a look at this code below.
    def getSalary():
        global a, b, c
        a = input("Please enter the boss's salary")
        b = input("Please enter the director's salary")
        c = input("Please enter the factory worker's salary")
    

    Notice this function, it asks the user for 3 different salary and store them in a, b, c respectively. But it is not a good practice, instead we should use the return function.

    def getSalary():
        a = input("Please enter the boss's salary")
        b = input("Please enter the director's salary")
        c = input("Please enter the factory worker's salary")
        return a, b, c
    
    # And to way to use this function is like
    a, b, c = getSalary()
    
    This make the code a lot more readable, and useable. Imagine if you make a mistake in the program, if you use global variable, you will have a very hard time tracking where exactly does your value get changed. While doing it the second method, you will know a, b, c is changed on the getSalary line's return. And you can print them as you writing your program to debug it.

    And as jdi pointed out, it is always always better to use more meaningful variable name than a,b,c,d, or x,y,z. Imagine you use bossSalary, directorSalary, factoryWorkerSalary, the code is a lot easier to understand. Granted, maybe a little bit long. But maybe you can use workerSalary at least!

    And when you have a function that modify your object, such as your own class, a list. Maybe (depending on the situation), you might want to create a new variable and assign it, or you can overwrite it too!
    def newSalary(salary):
        return salary + salary * 0.02
    
    # Use it like this
    nextYearSalary = newSalary(salary)
    # Or overwrite the old one
    mySalary = newSalary(salary)
    

    Tuesday, April 3, 2012

    Python: How to print the ValueError Error Message

    try:
        ...
    except ValueError as e:
        print(e)
    
    

    Python Tkinter: How to set the window size without using canvas

    Reference: http://stackoverflow.com/q/9996599/1276534
    Credit: George, Bryan Oakley

    Here is the code on how to set the window size without using canvas, it is great if you just starting, or do not want to use canvas to do this. You can specify your dimension in your frame, and then use pack_progate(0) flag to tell tkinter to use your size.
    import tkinter as tk
    
    root = tk.Tk()
    frame = tk.Frame(root, width=400, height=400)
    frame.pack_propagate(0) # set the flag to use the size
    frame.pack() # remember to pack it or else it will not be pack
    
    textBox = tk.Label(frame, text="(x,y): ")
    textBox.pack()
    
    root.mainloop()
    
    Note: If your frame is not big enough to how the items, it will expand to fit your items). And the pack_progate(0) is a flag, it does not replace pack() method, you still have to call it or otherwise it will not appear. Hope this help.

    Reference: stackoverflow 1, stackoverflow 2

    Monday, April 2, 2012

    Python: [] vs. {} vs. ()

    Reference: http://stackoverflow.com/q/4407873/1276534
    Authors: Zolomon, Greg Hewgill, Andrew Jaffe

    It is a good note post to make sure we remember what is [] vs. {} vs. ()

    () - tuple

    A tuple is a sequence of items that can't be changed (immutable).

    [] - list

    A list is a sequence of items that can be changed (mutable).

    {} - dictionary or set

    A dictionary is a list of key-value pairs, with unique keys (mutable). From Python 2.7/3.1, {} can also represent a set of unique values (mutable).

    Python: Regular Expression 101 Example Code

    Reference: http://stackoverflow.com/q/9980381/1276534
    Authors: Rajeev, George

    In computer science theory class, we learned about regular expression. But it is unclear what exactly can it do at first, today I would like to introduce data validation as an example that uses the concept of regular expression. Python itself, like other language I assume (heard), has an implementation of regular expression. It comes standard from python too, see: http://docs.python.org/library/re.html

    For example, you would like to ask the user for a telephone number, in the format of: 917-222-1234, if it is not in the format of XXX-XXX-XXXX, it will ask the user again until it is store. Let's take a look at the sample code.
    import re
    
    while True:
        # Get the user's input into the string
        myString = input('Enter your telephone number: ')
        
        # Matching it with the regular expresssion
        # isGoodTelephone will return True if it matches
        isGoodTelephone = re.match('^[0-9]{3}-[0-9]{3}-[0-9]{4}$', myString)
        
        if (isGoodTelephone):
            print('Great! Got your phone number into the system')
            print('Entry:', myString)
        else:
            print('Not in the correct format. Ex: xxx-xxx-xxxx')
        print()
    
    
    Output of the csci133rep1.py:
    Enter your telephone number: 917-123-1234
    Great! Got your phone number into the system
    Entry: 917-123-1234
    
    Enter your telephone number: 9171231234
    Not in the correct format. Ex: xxx-xxx-xxxx
    
    Actually the basic of the regular expression is not too hard to learn, take a look at the bottom and you will able to figure out how to use it with no problem. Didn't need to put too much comment to make it understandable. Although there are much more ways to use it than just the telephone.
    ^[0-9]{3}-[0-9]{3}-[0-9]{4}$
    ^       # mark the start of the telephone string
    [0-9]   # any one of the 0123456789
    {3}     # match it exactly three times, no less
    -       # a hyphen symbol
    [0-9]   # any one of the number between 0 and 9
    {3}     # exactly three copies
    -       # another hyphen symbol
    [0-0]   # any one of the number 0-9
    {4}     # four times
    $       # mark the end of the telephone string
    

    Sunday, April 1, 2012

    Python: Calculate Grade Point Average In a 4.0 Scale

    This is a simple program that take a list of grade, and then convert it to a 4.0 GPA scale with 1 decimal point, finally calculate the grade point average.
    # Take the list of grade as input, assume list is not empty
    def convertGrade(myGrades):
        myResult = [] # List that store the new grade
        for grade in myGrades:
            gpa = (grade / 20) -1
            # Depending on how many deciaml you want
            gpa = round(gpa, 1)
            myResult.append(gpa)
        return myResult
    
    # The list of grades, can be more than 5 if you want to
    grades = [88.3, 93.6, 50.2, 70.2, 80.5]
    convertedGrades = convertGrade(grades)
    print(convertedGrades)
    
    total = 0
    # If you want the average of them
    for grade in convertedGrades:
        total += grade # add each grade into the total
        
    average = total / len(convertedGrades)
    print('Average GPA is:', average)
    
    Output:
    [3.4, 3.7, 1.5, 2.5, 3.0]
    Average GPA is: 2.82
    

    Saturday, March 31, 2012

    Python: Get the most frequent elements from list when there is more than one

    Reference: stackoverflow
    Authors: james_kansas, Niklas B.

    The question is: When you are given a list that is unsorted, how do you get the most frequent appeared element, in particular, when there is more than one.
    from collections import Counter
    
    def myFunction(myDict):
        myMax = 0 # Keep track of the max frequence
        myResult = [] # A list for return
        for key in myDict:
            # Finding out the max frequence
            if myDict[key] >= myMax:
                if myDict[key] == myMax:
                    myMax = myDict[key]
                    myResult.append(key)
                # Case when it is greater than, we will delete and append
                else:
                    myMax = myDict[key]
                    del myResult[:]
                    myResult.append(key)
        return myResult
    
    foo = ['1', '1', '5', '2', '1', '6', '7', '10', '2', '2']
    print('The list:', foo)
    myCount = Counter(foo)
    print(myCount)
    
    print(myFunction(myCount))
    
    Output
    The list: ['1', '1', '5', '2', '1', '6', '7', '10', '2', '2']
    Counter({'1': 3, '2': 3, '10': 1, '5': 1, '7': 1, '6': 1})
    ['1', '2']
    
    
    More Reading: http://stackoverflow.com/questions/1518522/python-most-common-element-in-a-list

    csci133allCombination.py

    Reference: http://stackoverflow.com/q/9961077/1276534
    Authors: PePe, Li-aung Yip

    Overview: Example of this nested while loop is a bad idea, and noting the while loop in python require resetting the loop counter to be 0. And for usage of getting the combination of everything, use either nested for loop with range() function, or itertools, which takes list and return every possible combination from each element in the list you give as argument. And also, xrange() is replaced by range() at 3.0.

    In C++, although it might not be recommended, we can write a nested while loop and the following code will work. Because of unknown reason.
    a = 0
    b = 0
    c = 0
    while a <= 5:
        while b <=3:
            while c <= 8:
                print(a , b , c)
                c += 1
            b += 1
        a += 1
    
    Output is the following
    0 0 0
    0 0 1
    0 0 2
    0 0 3
    0 0 4
    0 0 5
    0 0 6
    0 0 7
    0 0 8
    
    Answer Because we need to remember to reset the loop's counter, a, b, c respectively on each iteration. But this method is kind of funky.
    a = 0
    b = 0
    c = 0
    
    while a <= 5:
        while b <=3:
            while c <= 8:
                print(a , b , c)
                c += 1
            b += 1
            c = 0 # reset
        a += 1
        b = 0 # reset
        c = 0 # reset
    
    I think most python programmer would prefer using the for loop over the range() function. It is interesting also to note and learn that, xrange() is the range() function, if you are using python 2.x. From 3.0 on, use range instead. :)
    for a in range(5+1): # Note xrange(n) produces 0,1,2...(n-1) and does not include n.
        for b in range (3+1):
            for c in range (8+1):
                print(a, b, c)
    
    But then wait... from the Li-aung Yip, there is a better way. Check out this solution which involve using itertools.product()
    import itertools
    for a, b, c in itertools.product(range(5+1), range(3+1), range(8+1)):
        print a,b,c
    For even more reading: Dan Goodger's "Code Like a Pythonista: Idiomatic Python" Thought: I think 2 second way resemble C++ the most to me, I don't know if I want to use while loop even in C++. But it is great to learn another function from the itertools, the itertools.product(). And nice to see the use for for a, b, c. I think it is powerful, but never use it in my code yet, should practice using it.
    import itertools
    
    colors = ['red', 'green', 'blue']
    vehicles = ['car', 'train', 'ship', 'boat']
    numbers = [1, 2, 3, 4, 5]
    
    """Pints out all the possible combination of number of color vehicles"""
    for color, vehicle, number in itertools.product(colors, vehicles, numbers):
        print(number, color, vehicle)
    
    
    More reference: http://docs.python.org/library/itertools.html