Two Plus Two Poker Forums

Two Plus Two Poker Forums (https://forumserver.twoplustwo.com/)
-   Computer and Technical Help (https://forumserver.twoplustwo.com/48/computer-technical-help/)
-   -   ** Python Support Thread ** (https://forumserver.twoplustwo.com/48/computer-technical-help/python-support-thread-1007515/)

tyler_cracker 06-24-2011 07:02 PM

Re: ** Python Support Thread **
 
lol shabby isn't this exactly the same as the list filtering problem i posed last week?

TheIrishThug 06-24-2011 10:48 PM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by daveT (Post 27280665)
May seem totally out of place, but the only thing I am against is using 'l' and '1' in the same program. People like to use various fonts and some of those fonts aren't going to show the difference between 'l' and '1'. Even with a decent font, it is still easy to mistaken the stuff.

l is a terrible variable name, you shouldn't be using it in the first place. Shame on jj for including it in his example.

jjshabado 06-25-2011 11:47 AM

Re: ** Python Support Thread **
 
I'm not sure if people get that the code I wrote was purely an example for this thread...

@tyler: Almost, since I'm combining it with a for loop. I would normally have just used filter, but I wanted to know what the "pythonic" way of doing it was. :)

tyler_cracker 06-25-2011 01:26 PM

Re: ** Python Support Thread **
 
shabby,

just pointing out that this thread already contains some examples of pythonic ways to solve this problem.

although in other news i have to use python at work so i'm thinking about picking up scheme and SICP in my copious free time :).

daveT 06-25-2011 05:41 PM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by jjshabado (Post 27288921)
I'm not sure if people get that the code I wrote was purely an example for this thread...

@tyler: Almost, since I'm combining it with a for loop. I would normally have just used filter, but I wanted to know what the "pythonic" way of doing it was. :)

I know it was for example, I was just messing around with you. I know your ten times better than me, and this basic issue would likely not be a real-world example from you.

I was reading SO and came across this:

This throws and error instead of a code, which is more Pythonic IMO.

I laughed.

Quote:

Originally Posted by tyler_cracker (Post 27290088)
shabby,

just pointing out that this thread already contains some examples of pythonic ways to solve this problem.

although in other news i have to use python at work so i'm thinking about picking up scheme and SICP in my copious free time :).

Next class of ocw is in Scheme. I figure I'm mostly left to my own devices on this one. I am excited to learn it though.

But I'm on class number 9/24 and problemSet 6/13, so that's probably another 3 to 4 weeks.

jjshabado 06-25-2011 05:57 PM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by tyler_cracker (Post 27290088)
just pointing out that this thread already contains some examples of pythonic ways to solve this problem.

What is it though? List comprehensions aren't good when you want to embed 5 or 6 statements of logic. Something like list comprehension syntax for for loops would be cool, but that doesn't exist (that I know of).

Just curious if people had favorite ways of addressing this.

daveT 06-25-2011 06:44 PM

Re: ** Python Support Thread **
 
Here's the python docs on list comprehensions, followed by nested list comprehensions.

http://docs.python.org/tutorial/data...comprehensions

and then there is a quick explanation that is a bit closer to English, and it uses FOR LOOPs:

http://www.greenteapress.com/thinkpy...ml/chap08.html

I think that option one looks cleaner.

daveT 06-25-2011 08:45 PM

Re: ** Python Support Thread **
 
Had to do a problem where the teachers conveniently added their own test codes. I was really proud of myself for creating a nice eloquent solution that only took one parameter. The test code is this cheesy thing:

Code:

def test_get_word_score():
    """
    Unit test for get_word_score
    """
    failure=False
    # dictionary of words and scores
    words = {("", 7):0, ("it", 7):2, ("was", 7):6, ("scored", 7):9, ("waybill", 7):65, ("outgnaw", 7):61, ("outgnawn", 8):62}
    for (word, n) in words.keys():
        score = get_word_score(word, n)
        if score != words[(word, n)]:
            print "FAILURE: test_get_word_score()"
            print "\tExpected", words[(word, n)], "points but got '" + str(score) + "' for word '" + word + "', n=" + str(n)
            failure=True
    if not failure:
        print "SUCCESS: test_get_word_score()"

and of course, I wrote this function which did tested every word as it is supposed to be tested:

Code:

def get_word_score(word, n):
    points = 0
    for letters in word:
        if letters == ' ':
            points = 0
            break
        x = SCRABBLE_LETTER_VALUES[letters]
        points = points + x
    if n >= 7:
        points = points + 50
    return points


##word = 'it'
##word = 'outgnawn'
##word = 'scored'
##word = ' '
##word = 'outgnaw'
##word = 'was'
##word = 'waybill'
##get_word_score(word, len(word))

(I know, the testing I created is lazy and horrible)

but end up having to change

Code:

if n >= 7:
to:

Code:

if len(word) >= 7 and n >= 7:
Just so I can pass the testing. Why? Apparently, they want to have the players type in how many letters they used rather than automate it? I doubt that. Why not automate the word-counting in the function and have one parameter?

and seriusly, Python:

Code:

if len(word) and n >= 7:
is 10x better. Mmmkay?

I feel oppressed.

daveT 06-26-2011 04:24 PM

Re: ** Python Support Thread **
 
I have a dictionary problem (written in pseudocode):

Code:


d = {'a':1, 'b':-2}

## want something like:

if any d.value() < 0:
      do this
else: do that

not sure if something like this is possible.

jjshabado 06-26-2011 04:29 PM

Re: ** Python Support Thread **
 
Code:

if any([ v < 0 for v in d.values() ]):
    print 'hey'


RoundTower 06-26-2011 05:19 PM

Re: ** Python Support Thread **
 
The n parameter doesn't look like the word length. As you say, it would be ******ed to force the caller to supply that to the function. Look at their test cases, n is always 7 or 8 even if the word has only 3 letters. Maybe it's the number of letters they started with on their rack, for some generalised Scrabble game where you can have more than 7 letters?

You probably shouldn't be so quick to assume the lecturers wrote something really stupid: a more appropriate reaction would be to think "what did I misread"?

jjshabado 06-26-2011 05:21 PM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by RoundTower (Post 27306216)
You probably shouldn't be so quick to assume the lecturers wrote something really stupid: a more appropriate reaction would be to think "what did I misread"?

This is similar to the advice I use to give my students in office hours.

You shouldn't assume the programming language is broken. You should assume your code is broken.

daveT 06-27-2011 09:13 PM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by jjshabado (Post 27305532)
Code:

if any([ v < 0 for v in d.values() ]):
    print 'hey'


Amazing. thanks.

Quote:

Originally Posted by RoundTower (Post 27306216)
The n parameter doesn't look like the word length. As you say, it would be ******ed to force the caller to supply that to the function. Look at their test cases, n is always 7 or 8 even if the word has only 3 letters. Maybe it's the number of letters they started with on their rack, for some generalised Scrabble game where you can have more than 7 letters?

You probably shouldn't be so quick to assume the lecturers wrote something really stupid: a more appropriate reaction would be to think "what did I misread"?

Quote:

Originally Posted by jjshabado (Post 27306250)
This is similar to the advice I use to give my students in office hours.

You shouldn't assume the programming language is broken. You should assume your code is broken.

I assumed I understood what the project is before I started working on this one, which obviously I don't. The point of the project is learning to do case testing and perhaps the game itself is only an adjunct to this purpose.

The code should probably be malleable enough so that if there are variations on the rules/ deal/ scoring/ etc, then what I have should be able to deal with that without turning into a total rewrite. I had some epiphany about why they did this particular test case, which basically deals with adding variations on scoring, what amount of letters are in a hand, etc.

ocw-specific observation:

Spoiler:
There are hints in the error messages that may or may not guide me to the correct path of what I have to do. For example, one error says 'if this is your only error, check to be sure your code isn't mutating the hand.' I took that to mean that there is some mutation involved, but not in the hand itself:

Code:

def function (hand, etc, etc, etc):
test = hand.copy()

do a bunch of mutation with test.

if the hand is good:
                return test;
 
else:
              return hand
              tell the player they are trying cheat
                deduct 100 points (j/k).



It is stupid and stubborn of me to imply I know all the goals when I am still a crappy programmer learning the ropes. If I can barely handle the coding, then the architecture shouldn't be something I feel I can judge.

I always promise myself not to do this when I am tired and/or grumpy. I should keep my thoughts to myself for a day or two.

I take this all as a valuable lesson.

Anyways, I didn't do what I should have: draw a bunch of diagrams to show what the functions do. I have that done now, and hopefully all of this will be put into a semi-readable flow-chart when it is time to figure out the interactions.

tyler_cracker 06-27-2011 10:00 PM

Re: ** Python Support Thread **
 
dave,

it's good to think about variations and stuff, particularly on larger projects. but more importantly, there's a rule that you may as well start learning now[1]: YAGNI -- you ain't gonna need it.

[1] and i say "start learning" because this is a temptation that all coders must fight until their dying keystroke.

(of course programming is like poker in that there are no absolutes, so by the time you've got YAGNI figured out you'll encounter YMGNI -- you might gonna need it.)

daveT 06-27-2011 10:15 PM

Re: ** Python Support Thread **
 
Google YAGNI and I am now sad.

I hated the .copy anyways.

tyler_cracker 06-28-2011 12:06 AM

Re: ** Python Support Thread **
 
YAGNI should not make you sad; it should appeal to your well-developed senses of Laziness and Impatience!

daveT 06-28-2011 10:47 PM

Re: ** Python Support Thread **
 
I'm in the process of moving, so things are slowed down with the ocw.

I am upset. I know that if I created this code one month ago, I would be very pleased with myself. Now I am displeased, but I don't know why I am displeased. I only feel like this wasn't the best solution and that upsets me. One month from now, I can look back and think I am an idiot, but now I know I am an idiot, so I am stuck with this:

Spoiler:
Code:

def is_valid_word(word, hand, word_list):
    """
    Returns True if word is in the word_list and is entirely
    composed of letters in the hand. Otherwise, returns False.
    Does not mutate hand or word_list.
   
    word: string
    hand: dictionary (string -> int)
    word_list: list of lowercase strings
    """
   
    # TO DO ...
# my code starts here:
# obviously worried about the whole mutation thing, so I couldn't bring
myself to let the .copy go.

    tester = hand.copy()
    test = False


# should be self-explanatory:

    if word in word_list:
        test = True
    else:
        test = False

## fmgdmfl:
       
    for letters in word:
        if letters in tester.keys():
            tester[letters] -= 1
            test = True
            if any([v < 0 for v in tester.values()]):
                test = False
            else:
                test = True
        else:
            test = False
           
    if not test:
        return False
    else:
        return True

##    or?????
##    if test == True:
##        return True
##    else:
##        return False



I don't know if/when I should use 'if' or 'if not.' Both solutions work though, at least in this particular assignment.

jjshabado 06-29-2011 12:02 AM

Re: ** Python Support Thread **
 
First, your code really isn't too bad. I use to work with first and second year CS students and code like this is very common (and a lot of it is a lot worse).

A couple things in terms of improving your code:

1. You've got a pretty big bug in there with how you treat the return value. One hint, once you know that a word isn't in the word list or that a letter isn't in the hand, do you need to keep doing more work?

2. Don't forget that you can return variables and that conditional checks with one of the operators being a constant boolean are usually unnecessary. So we can simplify as follows:
Code:

if test == True:
  return True
else:
  return False

to:
Code:

if test:
  return True
else:
  return False

to:
Code:

return test
Edit:
About the mutation thing: I wouldn't worry about it until you get this function in a good place, but I think it's worth thinking about/understanding what exactly is happening and if/why you need the copy (or how you could modify your solution to avoid needing it).

daveT 06-29-2011 12:47 AM

Re: ** Python Support Thread **
 
That's true. Functions default to false. I forgot about that one.

daveT 06-29-2011 02:44 AM

Re: ** Python Support Thread **
 
ocw specific:

Spoiler:
One thing they didn't say is that the unit tests are all-catching. Thinking they were was a stupid assumption on my part.


The bug you mentioned was the first to go, but now there's about 5 more to go. If I read an output plus None again, I am going to scream. At least that corrects my misstatement about functions defaulting to False.

kerowo 06-29-2011 08:14 AM

Re: ** Python Support Thread **
 
Potentially interesting link on Slashdot yesterday:

http://learnpythonthehardway.org/book/

seems to be a lot of "if this doesn't work you did something wrong, figure it out" type statements in the exercises.

ralu 06-30-2011 03:54 AM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by jjshabado (Post 27305532)
Code:

if any([ v < 0 for v in d.values() ]):
    print 'hey'


You do not need to create list when you can use only iterator.

for instance:
Code:

g = (v < 0 for v in d.values()) #g is now iterator
if any (g):
  print("hey")

or
Code:

if any( v < 0 for v in d.values() ):
    print 'hey'


Difference is that you do not create list, use extra storage and iteration is stooped as soon as first true element is found.

jjshabado 06-30-2011 09:22 AM

Re: ** Python Support Thread **
 
Very good point. I'm not sure why, but I'd been assuming that list comprehensions returned an iterator. Thanks for pointing that out.

ralu 06-30-2011 04:11 PM

Re: ** Python Support Thread **
 
Python reduce, generators and lazy evaluation is awesome. I have assembled haskell like code and cursed functions.
Code:

from functools import reduce #remove this line for python 2.x
 
def operator(d):
        if d<=1:
                return lambda x,y:x+y
        else:
                return lambda x,y:reduce(operator(d-1),(x for i in range(y)))
 
f1 = operator(1) #f1 is addition
print(f1(99,99))
 
f2 = operator(2) #f2 is multiplication
print(f2(99,99))
 
f3 = operator(3) #f3 is power
print(f3(99,99))


daveT 07-03-2011 08:23 PM

Re: ** Python Support Thread **
 
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


All times are GMT -4. The time now is 07:40 AM.

Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.

Copyright © 2008-2020, Two Plus Two Interactive