Open Side Menu Go to the Top
Register
** Python Support Thread ** ** Python Support Thread **

07-07-2011 , 07:38 PM
Here's the mit version of Fibonacci.

Code:
def fastFib(n, memo):
    global numCalls
    numCalls += 1
    print 'fib1 called with', n
    if not n in memo:
        memo[n] = fastFib(n-1, memo) + fastFib(n-2, memo)
    return memo[n]
which breaks down to 4+1 lines:

Code:
def fastFib(n, memo):
    if not n in memo:
        memo[n] = fastFib(n-1, memo) + fastFib(n-2, memo)
    return memo[n]

fastFib(6, {0:0, 1:1}).
I guess that how many lines you need is a function of whether you want to use 'if not' and how you want to initialize memo and where.
** Python Support Thread ** Quote
07-07-2011 , 10:36 PM
For amusement value, here was my first python generator function.

Code:
def fibonacci():
    a,b = 1,1
    while True:
        yield a
        a,b = b,a+b
To use:
Code:
for i, seq in enumerate(fibonacci(), start=1):
     print "%d: %d" % (i, seq)
** Python Support Thread ** Quote
07-07-2011 , 10:48 PM
Quote:
Originally Posted by daveT
This'll rankle some posters here:

For at least four decades, people have been building tools called debuggers. Things to help you find bugs. And there are some built into Idol. My personal view is most of them are not worth the trouble. The two best debugging tools are the same now that they have almost always been. And they are the print statement, and reading.

-- Prof. John Guttag, MIT
It would be a little interesting to know more about the context of this statement. I don't actually disagree since if I had to choose any single debugging tool it would be the print statement (even though I'm obviously missing out on lots of good features in a real debugger) and most debugging tools offer a lot of advanced features that aren't that useful except for special cases.

This is especially true if he's talking about doing assignment questions and other toy/small problems.
** Python Support Thread ** Quote
07-08-2011 , 12:45 AM
The biggest reason I can think of to use a debugger more often is that you get better at using it and don't have to learn it the first time AND find a problem in your code.
** Python Support Thread ** Quote
07-08-2011 , 02:56 PM
Does anybody develop python on windows? I was just hired at a startup that mostly uses python and they currently don't have a single developer out of about 25 that uses a windows machine. I've pretty much only used windows in the past, but looks like it might be time to switch. From reading through the talk regarding IDEs on the previous page, I'm guessing the easy access to a unix shell is pretty important?
** Python Support Thread ** Quote
07-08-2011 , 03:23 PM
Learning unix is always a good idea, doubly so if you work in a unix shop. However, there are plenty of legit python interpreters and ides for win. One of the points of python is to be a cross-platform scripting language, so unless you go crazy, scripts will run equivalently on nix and win.
** Python Support Thread ** Quote
07-08-2011 , 03:25 PM
About 3-4 years ago I did a small amount of python development in cygwin on a Windows machine. It was kind of painful since cygwin had a few incompatibilities with libraries.
** Python Support Thread ** Quote
07-08-2011 , 03:27 PM
Yeah, don't use cygwin. Use the native windows tools.
** Python Support Thread ** Quote
07-10-2011 , 01:16 AM
I have a question about objects and inheritance, or rather the style of using inheritance.

So a very generic and dysfunctional Python code:

Code:
## Is object needed here or can it just be open parameters?
## I observe that it works either way.
class iClass(object):
    def __init__:
        pass
    def action(self):
        pass

class subClass(iClass):
    def __init__:
        pass

class subSub(subClass):
    def __init__:
        pass

    #The question is that I can use either of these to access
    #the action in iClass, but which one is better?
    #Although the teacher used the first option, perhaps to
    #demonstrate inheritance, I found that the second one
    #works as well. I like it better because the flow is easier to
    #see. However, I can see a good argument for the first option
    # since the chain of inheritance goes up the code.

    #I don't know much about over-riding/shadowing atm, so perhaps
    # I am missing that point for now. 
    def action(self):
        return subClass.action(self, param)
        return iClass.action(self, param)

x = 'foo'
x.action(x, 'bar')
** Python Support Thread ** Quote
07-10-2011 , 01:23 AM
i haven't done much oop with python, but i think the general answer is: do whatever makes the code easiest to understand. oop is all about modeling something in the world. thinking about your model will help you figure out where methods belong and how to call them.

btw are you deliberately using iClass to signify that it is an interface? or are you not there yet?
** Python Support Thread ** Quote
07-10-2011 , 01:25 AM
I know what I'd do in Ruby, so I looked up the Python equivalent. Perhaps try this:

Try, from the Python docs,
Code:
class C(B):
    def method(self, arg):
        super(C, self).method(arg)
** Python Support Thread ** Quote
07-10-2011 , 02:03 AM
Quote:
Originally Posted by jjshabado
It would be a little interesting to know more about the context of this statement. I don't actually disagree since if I had to choose any single debugging tool it would be the print statement (even though I'm obviously missing out on lots of good features in a real debugger) and most debugging tools offer a lot of advanced features that aren't that useful except for special cases.

This is especially true if he's talking about doing assignment questions and other toy/small problems.
Here is the code he used to demo his idea. He did point out that the function is called 'silly' because it is silly:

He suggests using a bisection/ divide in half style of debugging. Obviously there was no need to create so many print statements. I only use the numbers to demonstrate the order he checked, not what he actually wrote. Perhaps 3 and 4 are mixed up; regardless, you can see what he did.

Code:
def silly():
    res = []
    done = False
    while not done:
        elem = raw_input('Enter element. Return when done. ')
        if elem == '':
            done = True
        else:
            res.append(elem)
    #print statement 1
    tmp = res
    #print statement 4
    tmp.reverse()
    #print statemtent 3
    isPal = (res == tmp)
    #print statement 2
    if isPal:
        print 'is a palindrome'
    else:
        print 'is NOT a palindrome'
I'll point out that .reverse is just like .copy in that it doesn't seem to return a value either. I guess using tmp = res.reverse() would be a great feature to have, but that is something I'll let ruby vs a vis python flame on about.

Quote:
Originally Posted by tyler_cracker
i haven't done much oop with python, but i think the general answer is: do whatever makes the code easiest to understand. oop is all about modeling something in the world. thinking about your model will help you figure out where methods belong and how to call them.

btw are you deliberately using iClass to signify that it is an interface? or are you not there yet?
No, not at interfacing. I would embarrassingly ask if you are talking GUI, but that would probably be way off. GUI is the next assignment.

Quote:
Originally Posted by Neil S
I know what I'd do in Ruby, so I looked up the Python equivalent. Perhaps try this:

Try, from the Python docs,
Code:
class C(B):
    def method(self, arg):
        super(C, self).method(arg)
Jesus, that looks confusing. Thanks for the link. I'm now interested in super().

But according to this post linked from the pyDocs: http://rhettinger.wordpress.com/2011...sidered-super/

super() isn't so good to use in Python 2.x, which is what I am learning to use atm. I'll definitely keep this one in mind for the day I decide to download Python 3.x. (*shiver*)

------------

The course went to lullaby easy to monster hard in a matter of a few lectures. The assignments jump from recursion to knapsack algorithms and OOP.
** Python Support Thread ** Quote
07-10-2011 , 07:46 AM
Code:
class MyNewStyleClass(object):
  pass
class MyOldStyleClass:
  pass
In Python 2.x, if you don't explicitly inherit from object, you are using the old class implementation. docs

Using super is better because it doesn't require you to explicitly know the super class that defined the method. This is important when you have multiple inheritance.
** Python Support Thread ** Quote
07-12-2011 , 02:41 AM
I was so confused about OOP in Python-land that I decided to type out the entire lecture notes plus some other stuff. During the lecture, Python apparently wasn't working the way it was supposed to. I figured out the problem: lots of bugs.

I think now is time to start learning how to use a debugger. I felt really stupid using print all over the place.

I put more thought into the .sort, .reverse idea. I don't understand why these functions should return new values. What benefit is it to have extra variables when your function returns a mutated output? It seems like it is a cleaner solution to simply have one variable. If you really need to return the non-mutated variable, then having an explicit copied variable seems to make the code easier to read. I guess having .copy set so that it either returns or not returns a new variable would be a nifty addition, though I'm not sure how hard that would be to implement.

I guess if it really upsets you, you can create your own object and over-ride .sort. Maybe at the end of this class, I could try to create a new .sort function that could return a new variable or not. Shouldn't be too hard, really.
** Python Support Thread ** Quote
07-12-2011 , 04:10 AM
Quote:
Originally Posted by daveT
I was so confused about OOP in Python-land that I decided to type out the entire lecture notes plus some other stuff. During the lecture, Python apparently wasn't working the way it was supposed to. I figured out the problem: lots of bugs.

I think now is time to start learning how to use a debugger. I felt really stupid using print all over the place.

I put more thought into the .sort, .reverse idea. I don't understand why these functions should return new values. What benefit is it to have extra variables when your function returns a mutated output? It seems like it is a cleaner solution to simply have one variable. If you really need to return the non-mutated variable, then having an explicit copied variable seems to make the code easier to read. I guess having .copy set so that it either returns or not returns a new variable would be a nifty addition, though I'm not sure how hard that would be to implement.

I guess if it really upsets you, you can create your own object and over-ride .sort. Maybe at the end of this class, I could try to create a new .sort function that could return a new variable or not. Shouldn't be too hard, really.
Not referencing your notes, but for builtin datatypes there is an inplace and copy version of sort.

Code:
>>> a = [1,2,3,9,7,8]
>>> sorted(a)
[1, 2, 3, 7, 8, 9]
>>> a
[1, 2, 3, 9, 7, 8]
>>> a.sort()
>>> a
[1, 2, 3, 7, 8, 9]
** Python Support Thread ** Quote
07-12-2011 , 11:29 AM
yes, of course. if i want to modify the list in place i use listObject.sort() but if i want to return a copy of the sorted list i use sorted(listObject). how consistent and easy to understand! hooray for python!

(again, i know why it's set up this way. i'm just trying to elaborate on why i think it's bad language design.)
** Python Support Thread ** Quote
07-12-2011 , 12:33 PM
yeah the Ruby (Scheme, I guess) notation is pretty cool for that. I'm not sure that sorted and reversed should be builtins at all in Python.
** Python Support Thread ** Quote
07-12-2011 , 01:05 PM
Quote:
Originally Posted by tyler_cracker
yes, of course. if i want to modify the list in place i use listObject.sort() but if i want to return a copy of the sorted list i use sorted(listObject). how consistent and easy to understand! hooray for python!

(again, i know why it's set up this way. i'm just trying to elaborate on why i think it's bad language design.)
I'm not sure I understand your issue. It seems really clear to me that .sort() on an object would mutate that object. It also seems clear to me that calling a non-object function wouldn't mutate the object parameter.

Looking at the keys() vs sort() distinction, it still seems pretty clear to me. keys() is obviously a property of the object (and so returns that property) while sort() is obviously an operation (and so just mutates the object and returns nothing).

Are there other examples that are inconsistent?
** Python Support Thread ** Quote
07-12-2011 , 07:42 PM
shabby,

i already trucked out the str(object) vs object.toString() example. i'll try to post another if i think of it.

to me, the keys() vs sort() distinction to be obvious. i'm not sure what else to say about it. for me, it forces me to think about something which i believe should be natural, it creates friction, it slows down my coding, etc. maybe this is because i learned ruby before python, maybe it's because i'm a dullard, maybe it's because i have the heart of a pure programming champion while you are a nasty, brutish hacker. i guess we'll all have to decide for ourselves .
** Python Support Thread ** Quote
07-16-2011 , 05:41 AM
I have my first official beef with Python. Well, maybe not Python, but probably the packaged IDLE and Shell.

This only happens with larger codes (probably 100+ lines because that's 'large' in my world, lol). I f5 and the Shell crashes. Okay, fine, close down the Shell and run the file again. Yes, this sucks but I can sort of get over it.

The thing I can't get over is that Shell/IDLE can't handle Classes and OOP worth a ****. Run a file and the code executes. Does this mean I have a good piece of code? I always assume like 80% yes even if I 'know' I have it right. But not now: I can only flip a coin and hope it is correct. f5 again and find out that the code that just ran great for the past 3 runs is now throwing an error! Fine, whatever, I fix the bug and the code runs fine again (I think).

This would only be a minor irritation if that only happened when the code is bad, but no, it also happens when the code is plenty fine. Run the good code, get an error (or maybe Shell crashes). Screw that. Close Shell, re-run and all is good again.

Wow, I really hope it isn't Python doing this. I most certainly would not understand it's popularity if this is a constant thing. I can only conclude, at this time, that IDLE is only good for learning the real basics: loop, add, subtract. Add in functions and you get some problems. Add in classes and all hell breaks loose.

I think there was talk of IDEs earlier, but since I only have 1 3/4 assignments left, I really don't feel like going through the trouble. These issues also happened on the OCW videos, so I know it isn't just me.
** Python Support Thread ** Quote
07-16-2011 , 06:29 AM
The command line is your friend. Edit in one window, run from another. I only use IDLE to work out syntax stuff I should know but didn't remember...
** Python Support Thread ** Quote
07-16-2011 , 07:08 AM
IDLE works fine for me unless I write infinite loops, which I do too often. As usual, it's probably you.
** Python Support Thread ** Quote
07-16-2011 , 12:07 PM
idle sucks. there's a better one that a couple of my colleagues use but i can't remember the name right now :\.

edit: and honestly, learning how to use vim as a poor man's ide (or emacs as a crazy man's ide) is probably better than learning any language-specific ide.
** Python Support Thread ** Quote
07-16-2011 , 05:03 PM
Quote:
Originally Posted by RoundTower
IDLE works fine for me unless I write infinite loops, which I do too often. As usual, it's probably you.
I don't know. I always blame myself first, which is basically the responsible thing to do, IME, but this is different.

I run the same exact code, with the same exact test case, multiple times and I get error or completion. I can't blame myself for this, unless I am missing something egregious. I simply can't understand why pressing f5 at :37 vs :21 is my fault.

en re: Emacs. I agree it's nuts (and ugly to look at). The Scheme class uses Emacs. C-x C-e? That's crazy.

I am pretty happy to say that after running infinite loops a billion times when I first started Python, I haven't done that one in a long while. Lesson (hopefully) learned. For... var is your best friend.

Speaking of for..., I just learned about xrange. Further research suggests that Python 3 deprecated xrange, and it has its own variant on range and xrange.

http://stackoverflow.com/questions/1...nge-over-range

Last edited by daveT; 07-16-2011 at 05:09 PM.
** Python Support Thread ** Quote
07-17-2011 , 09:49 PM
In light of all the requests about poker evaluator/hand this hand that stuff in this forum, I decided that may be a semi-fun project to attempt.

I just started this last night. It is already 111 lines long. I obviously need to abstract a ton of this, but I'm okay with the extra visuals right now.

I guess it'll be done in about a month. Taking the next series of classes, which is on Scheme, so I won't be able to commit tons of time to this.

Code:
#Hold'em poker eval that is extensible to other variants:

import random

#createDeck():
#To create alternate deck, change deck size and/or (numSuits and suits):

#returns dictionary mapping of deck:
####{'hearts': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
##'clubs': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
##'spades': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
##'diamonds': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]}

def createDeck(deck = 52):
    numSuits = deck/4
    deck = {}
    ranks = []
    suits = 'clubs', 'hearts', 'spades', 'diamonds'
    for i in range(1, numSuits + 1):
        ranks.append(i)
    for suitPlace in range(4):
        deck[suits[suitPlace]] = ranks
    return deck

#createDeck()

#Creates pseudo-random two-card hand for each player:
#converts numericals to trump-ranks.
#returns list with tuples:
#ex: [(8, 'hearts'), (7, 'spades')]
#To change hand-size, change handSize
#Only need to change ranked if deck in createDeck() is larger than 52

def createHand():
    wholeDeck = createDeck()
    handSize = 2
    returnHand = []
    while handSize > 0:
        for n in range(handSize):
            suited = random.choice(wholeDeck.keys())
            ranked = random.choice(wholeDeck[suited])
##            This is a bug that I'll get to fixing later:
##            the attempt is to chop off the cards so I don't get doubles
##            del wholeDeck[suited][ranked]
##            print wholeDeck
        if ranked == 1:
            ranked = 'A'
        elif ranked == 10:
            ranked = 'T'
        elif ranked == 11:
            ranked = 'J'
        elif ranked == 12:
            ranked = 'Q'
        elif ranked == 13:
            ranked = 'K'
        handSize -= 1
        newHand = ranked, suited
        returnHand.append(newHand)
    return returnHand

##hand = createHand(1)
##print hand

#Initializes players and returns player hands:

def createPlayerHands(players = 1):
    playerHand = {}
    playerID = 0
    for i in range(players):
        playerID += 1
        rawHand = createHand()
        playerHand[playerID] = rawHand
    return playerHand

#dealBoard decides how many cards to deal. Will create function later that asks what
#streets to deal. 

def dealBoard(cardsUsed = 0):
    cardsToDeal = 5 - cardsUsed
    lessDeck = createDeck()
    returnHand = []
    for i in range(cardsToDeal):
        suited = random.choice(lessDeck.keys())
        ranked = random.choice(lessDeck[suited])
        if ranked == 1:
            ranked = 'A'
        elif ranked == 10:
            ranked = 'T'
        elif ranked == 11:
            ranked = 'J'
        elif ranked == 12:
            ranked = 'Q'
        elif ranked == 13:
            ranked = 'K'
        newHand = ranked, suited
        returnHand.append(newHand)
    return returnHand
        

##showBoard = dealBoard(3)  
##print showBoard

#play starts here:
##example output:
##how many players in this hand? 4
##player 1 : [(9, 'spades'), (4, 'hearts')]
##player 2 : [(7, 'spades'), ('J', 'diamonds')]
##player 3 : [(6, 'spades'), (6, 'diamonds')]
##player 4 : [(5, 'hearts'), (6, 'spades')]

numPlayers = int(raw_input('how many players in this hand? '))    
playerHand = createPlayerHands(numPlayers)
for k, v in playerHand.iteritems():
    print 'player', k, ':', v

#See the error message: tells me how many lines this thing is getting to be:
#createPlayerHan(4)
** Python Support Thread ** Quote

      
m