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

06-24-2011 , 07:02 PM
lol shabby isn't this exactly the same as the list filtering problem i posed last week?
** Python Support Thread ** Quote
06-24-2011 , 10:48 PM
Quote:
Originally Posted by daveT
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.
** Python Support Thread ** Quote
06-25-2011 , 11:47 AM
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.
** Python Support Thread ** Quote
06-25-2011 , 01:26 PM
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 .
** Python Support Thread ** Quote
06-25-2011 , 05:41 PM
Quote:
Originally Posted by jjshabado
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
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.
** Python Support Thread ** Quote
06-25-2011 , 05:57 PM
Quote:
Originally Posted by tyler_cracker
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.
** Python Support Thread ** Quote
06-25-2011 , 06:44 PM
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.
** Python Support Thread ** Quote
06-25-2011 , 08:45 PM
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.
** Python Support Thread ** Quote
06-26-2011 , 04:24 PM
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.
** Python Support Thread ** Quote
06-26-2011 , 04:29 PM
Code:
if any([ v < 0 for v in d.values() ]):
    print 'hey'
** Python Support Thread ** Quote
06-26-2011 , 05:19 PM
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"?
** Python Support Thread ** Quote
06-26-2011 , 05:21 PM
Quote:
Originally Posted by RoundTower
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.
** Python Support Thread ** Quote
06-27-2011 , 09:13 PM
Quote:
Originally Posted by jjshabado
Code:
if any([ v < 0 for v in d.values() ]):
    print 'hey'
Amazing. thanks.

Quote:
Originally Posted by RoundTower
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
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.
** Python Support Thread ** Quote
06-27-2011 , 10:00 PM
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.)
** Python Support Thread ** Quote
06-27-2011 , 10:15 PM
Google YAGNI and I am now sad.

I hated the .copy anyways.
** Python Support Thread ** Quote
06-28-2011 , 12:06 AM
YAGNI should not make you sad; it should appeal to your well-developed senses of Laziness and Impatience!
** Python Support Thread ** Quote
06-28-2011 , 10:47 PM
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.
** Python Support Thread ** Quote
06-29-2011 , 12:02 AM
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).
** Python Support Thread ** Quote
06-29-2011 , 12:47 AM
That's true. Functions default to false. I forgot about that one.
** Python Support Thread ** Quote
06-29-2011 , 02:44 AM
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.
** Python Support Thread ** Quote
06-29-2011 , 08:14 AM
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.
** Python Support Thread ** Quote
06-30-2011 , 03:54 AM
Quote:
Originally Posted by jjshabado
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.
** Python Support Thread ** Quote
06-30-2011 , 09:22 AM
Very good point. I'm not sure why, but I'd been assuming that list comprehensions returned an iterator. Thanks for pointing that out.
** Python Support Thread ** Quote
06-30-2011 , 04:11 PM
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))
** Python Support Thread ** Quote
07-03-2011 , 08:23 PM
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
** Python Support Thread ** Quote

      
m