Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
trashmatic
Jan 27, 2006

Kresher posted:

Another python newbie assignment question time! (Yay, me)

I'm programming a hangman game, and I've got a working version that has 1 flaw I cannot fix.
Your effort here is in some ways similar to others I've seen from intro-level CS courses. As you mention, the programming style could use a lot of work, but that's not a big deal. You've done a pretty good job of making the computer do things. The problem is that you haven't thoroughly decided what it should be doing.

Start analyzing the program from the beginning of the inner while loop. Write out a few possible inputs you could give the program at ask_user_guess(). For each one of those, go very carefully line by line and see what the program will do.

You have five possibilities, in general: nothing, a single letter not in the word, a single letter that is in the word, multiple letters that do not equal the word, multiple letters that equal the word.

For example, if you give it multiple letters that do not equal the word, 'guess not in word' will evaluate true, so you will enter that if-block. It will print "You've made a wrong guess", and hit the continue statement and reset the while loop. Not what you were intending.

If you patch that up, you may find that the program is appending all the letters in the guess to 'letters' even if the guess is wrong, with entertaining results.

Also, due to the way the last if-else block is written, it will print "You've guessed wrong too many times" every time the set of letters is not equal to the set of words, even if your guess was correct! What's with that?

Basically, the core logic is all wrong. Rethink it, flowchart it, then rewrite it, and you'll be off and running.

quote:

However, I cannot use the functions to syntactically add 1 to the variable 'guesses', using the continue statement.
What are you talking about here? Less jargon, please. If you mean that you can't call 'continue' inside a function and expect it to abort the loop it was called from... well, yes. You can't do that.

Adbot
ADBOT LOVES YOU

trashmatic
Jan 27, 2006

Kresher posted:

This is what I've got after working on the program some more (before reading the reply)

I didn't really touch it much, other than cutting out bits of the code to fit the top level programming model. (Also added the variable user_won to control)
Try to clarify with your teacher what the "top level programming model" (I found nothing on Google) means with respect to your code. I think it's leading you further away from a solution. Functions are generally to take input data, perform a specific task, and return data -- not act as cutely named containers for fragments of your program's control structures.

trashmatic
Jan 27, 2006

Kresher posted:

The following is what my prof showed us as an example of "top level" programming.

code:
def check_if_user_guessed():
    return  (user_number == the_number)
...
the_number = program_picks()
...
user_number = ask_user_for_number()
...
won = check_if_user_guessed()
There is no excuse for a professor to be showing code like this in an intro class. The rest of the program is pretty bad, too, but drat.

To elaborate, this code is completely abusing global variables in order to make a so-called subroutine out of a function which should logically be taking two arguments (i.e. check_if_user_guessed(user_number, the_number)). The way it is now, if for whatever reason those variables are not in the global scope, it will fail. Terrible programming practice.

Further, it's stupidly named because of course the user guessed, we want to know whether they guessed correctly! So we should write something more like check_if_guess_correct(users_guess, correct_answer). But wait, we can generalize here and just call it check_if_equal(a, b). Brilliant! OH WAIT THAT IS BUILT INTO THE LANGUAGE IT IS CALLED THE == OPERATOR.


Your prof is doing a piss-poor job of teaching functional abstraction.


He/she seems to have created the perception that Python functions work like assembly language subroutines or C preprocessor macros, where the code in the function is simply copy-pasted into your "top level" code at runtime. This is completely wrong.

Try think of a function as a its own box, if you will, that is connected to its caller only by a thin straw. Nothing inside one box can directly alter anything happening inside the other box, it can only send things down the straw as either function arguments or return values and hope the other box does something intelligent with it. That's why you can't use a 'continue' statement inside a function and expect it to bust out of your main program's 'while' loop -- because your function is operating in its own little universe. Data in, data out.

Of course, using global variables completely fucks with this picture because now you have these things that are visible and alterable by both boxes, so you can "cheat" that way. But the picture is still very different from the copy-n-paste idea.

I dunno, hope this helps a little.

trashmatic fucked around with this message at 19:58 on Feb 26, 2008

trashmatic
Jan 27, 2006

leinad posted:

Anyway, do I have to create a new event handler function for each number and operator button in order to append the symbol to the end of the text box, or is there a way to do it in a single function? Could I set the id of each number button to its value and get the id in the handler?
I don't know whether you can do that exactly, but using unique event handler functions doesn't need to be a lot of work at all. All you need to do is write a function that takes a symbol and returns an event handler function to put that symbol in the box.

code:
def make_append_fn(symbol):
    def handler(event):
        yourwidget.append(symbol)
    return handler
Then you can just put all your symbols and corresponding button IDs in a dict or a list of tuples or whatever and iterate through, creating and attaching a handler function for each button.

code:
symbol_buttons = [('+', 11), ('7', 13)]
for symbol, button_id in symbol_buttons:
    wx.bindfunctiontowidget(button_id, make_append_fn(symbol))

  • Locked thread