FAQ
I'm trying to create an option for the program to repeat if the user types 'y' or 'yes', using true and false values, or otherwise end the program. If anyone could explain to me how to get this code working, I'd appreciate it.


letters='abcdefghijklmn'
batman=True
def thingy():
     print('type letter from a to n')
     typedletter=input()
     if typedletter in letters:
         print('yes')
     else:
         print('no')
def repeat():
     print('go again?')
     goagain=input()
     if goagain in ('y', 'yes'):
         print('ok')
     else:
         print('goodbye')
         batman=False
while batman==True:
     thingy()
     repeat()
     print('this is the end')

Search Discussions

  • Joshua Landau at Aug 7, 2013 at 8:42 am

    On 7 August 2013 09:17, wrote:
    I'm trying to create an option for the program to repeat if the user types 'y' or 'yes', using true and false values, or otherwise end the program. If anyone could explain to me how to get this code working, I'd appreciate it.

    Always tell people what in particular you don't understand (*ducks*)
    because it wasn't obvious what part of the problem you were unable to
    fulfil.

    letters='abcdefghijklmn'
    batman=True
    def thingy():
    print('type letter from a to n')
    typedletter=input()
    if typedletter in letters:
    print('yes')
    else:
    print('no')
    def repeat():
    print('go again?')
    goagain=input()
    if goagain in ('y', 'yes'):
    print('ok')
    else:
    print('goodbye')
    batman=False

    This doesn't do what you want it to.


         x = "old thing"


         def change_x():
             x = "new thing"


         change_x()


         print(x) # Not changed!


    The solution is to put "global x" at the start of the function.

    while batman==True:
    thingy()
    repeat()
    print('this is the end')



    Note that this isn't actually a good way to do it. Imagine you had
    several hundred function -- would you really want to have an
    equivalent number of names floating around that you have to look
    after?


    The solution is to make the functions simply return values:


         x = "old thing"


         def return_thing():
             x = "new thing"
             return "new thing" # You can do this in one line


         x = return_thing() # Get the value from the function and change x with it




    Does this make sense?
  • Eschneider92 at Aug 7, 2013 at 8:59 pm
    What I wanted to happen is when the user typed something other than 'y' or 'yes' after being asked 'go again?', the batman==False line would cause the program to stop asking anything and say 'this is the end'. Instead, what is happening is that the program just keeps going. I figured that after defining the function (thingy(), repeat()), that the while statement would repeat until the 'go again' user input was something other than 'y' or 'yes', and the batman==False part of the repeat() function would cause the 'while batman==True' part to become False and end. You probably answered my question and I'm too dumb to see it, but that's a slight elaboration on my problem.
  • Dave Angel at Aug 8, 2013 at 1:18 am

    eschneider92 at comcast.net wrote:


    What I wanted to happen is when the user typed something other than 'y' or 'yes' after being asked 'go again?', the batman==False line would cause the program to stop asking anything and say 'this is the end'. Instead, what is happening is that the program just keeps going. I figured that after defining the function (thingy(), repeat()), that the while statement would repeat until the 'go again' user input was something other than 'y' or 'yes', and the batman==False part of the repeat() function would cause the 'while batman==True' part to become False and end. You probably answered my question and I'm too dumb to see it, but that's a slight elaboration on my problem.

    When you assign a variable inside a function, it has no effect on a
    global variable with similar name. In order to make it change the
    global, you'd have needed the global declaration.


    Try this:


    var = 42
    def myfunc():
          var = 90




    print "before:", var
    myfunc()
    print "after:", var


    Now, change the function, by adding a declaration:


    def myfunc():
         global var
         var = 90


    and the result will change.




    --
    DaveA
  • Larry Hudson at Aug 8, 2013 at 2:49 am

    On 08/07/2013 01:17 AM, eschneider92 at comcast.net wrote:
    I'm trying to create an option for the program to repeat if the user types 'y' or 'yes', using true and false values, or otherwise end the program. If anyone could explain to me how to get this code working, I'd appreciate it.

    letters='abcdefghijklmn'
    batman=True
    def thingy():
    print('type letter from a to n')
    typedletter=input()
    if typedletter in letters:
    print('yes')
    else:
    print('no')
    def repeat():
    print('go again?')
    goagain=input()
    if goagain in ('y', 'yes'):
    print('ok')
    else:
    print('goodbye')
    batman=False
    while batman==True:
    thingy()
    repeat()
    print('this is the end')
    You've already received answers to this, primarily pointing out that batman needs to be declared
    as global in your repeat() function. Global variables can be read from inside a function
    without declaring them as such, but if you need to change them, they MUST be declared as
    globals, otherwise it will merely create an independant local variable with the same name.


    A second possibility is to do away with batman in the repeat() function, and instead return True
    in the 'yes' clause and False in the else clause. Then in your while loop, change the repeat()
    line to:
          batman = repeat()


    A third version (which I would prefer) is to do away with batman altogether (maybe the Penguin
    got 'im??) ;-) Use the True/False version of repeat() and change the while loop to:


    while True:
          thingy()
          if not repeat():
              break


    And finally unindent your final print() line. The way you have it will print 'The end' every
    time in your loop. Not what you want, I'm sure.


           -=- Larry -=-
  • Wxjmfauth at Aug 8, 2013 at 6:20 am

    Le mercredi 7 ao?t 2013 10:17:21 UTC+2, eschne... at comcast.net a ?crit?:
    I'm trying to create an option for the program to repeat if the user types 'y' or 'yes', using true and false values, or otherwise end the program. If anyone could explain to me how to get this code working, I'd appreciate it.



    letters='abcdefghijklmn'

    batman=True

    def thingy():

    print('type letter from a to n')

    typedletter=input()

    if typedletter in letters:

    print('yes')

    else:

    print('no')

    def repeat():

    print('go again?')

    goagain=input()

    if goagain in ('y', 'yes'):

    print('ok')

    else:

    print('goodbye')

    batman=False

    while batman==True:

    thingy()

    repeat()

    print('this is the end')

    -----------


    Your loop is not very well organized. It should be
    at the same time the "loop" and the "condition tester".
    Compare your code with this and note the missing and
    unnecessary "batman":



    def z():
    ... letters = 'abc'
    ... c = input('letter: ')
    ... while c in letters:
    ... print('do stuff')
    ... c = input('letter: ')
    ... print('end, fin, Schluss')
    ...
    z()
    letter: a
    do stuff
    letter: b
    do stuff
    letter: b
    do stuff
    letter: c
    do stuff
    letter: n
    end, fin, Schluss
    z()
    letter: q
    end, fin, Schluss




    Variant
    It is common to use a infinite loop and to break it
    in order to end the job.



    def z2():
    ... letters = 'abc'
    ... while True:
    ... c = input('letter: ')
    ... if c not in letters:
    ... print('end, fin, Schluss')
    ... break
    ... else:
    ... print('do stuff')
    ...
    z2()
    letter: a
    do stuff
    letter: b
    do stuff
    letter: a
    do stuff
    letter: q
    end, fin, Schluss




    jmf
  • Chris Angelico at Aug 8, 2013 at 11:41 am

    On Thu, Aug 8, 2013 at 7:20 AM, wrote:
    def z2():
    ... letters = 'abc'
    ... while True:
    ... c = input('letter: ')
    ... if c not in letters:
    ... print('end, fin, Schluss')
    ... break
    ... else:
    ... print('do stuff')



    Minor quibble: I don't like having a hard exit followed by an "else".
    If the "if" branch will unconditionally quit the loop (with a break,
    here, but could also be a return, a thrown exception, etc etc), I
    would prefer to see the "else" removed and its code unindented one
    level. Maybe this is just personal preference, though, learned from
    assembly language programming where a "block if" looks something like
    this:


    ; if x == y:
    CMP x,y
    JNZ .else
    ; Code for "x == y"
    JMP .endif
    .else:
    ; Code for "else"
    .endif


    Putting an unconditional departure in the "x == y" branch makes the
    "JMP .endif" redundant.


    ChrisA
  • Terry Reedy at Aug 8, 2013 at 8:29 pm

    On 8/8/2013 7:41 AM, Chris Angelico wrote:
    On Thu, Aug 8, 2013 at 7:20 AM, wrote:
    def z2():
    ... letters = 'abc'
    ... while True:
    ... c = input('letter: ')
    ... if c not in letters:
    ... print('end, fin, Schluss')
    ... break
    ... else:
    ... print('do stuff')

    Minor quibble: I don't like having a hard exit followed by an "else".

    Whereas I tend to prefer to have the two alternatives cleanly marked as
    alternatives by both being indented the same.


    Many alternatives are not so trivial as the above. I remember reading
    one snippet in the CPython codebase where the 'else' was omitted and the
    if clause subdivided into about three paths. It took at least a minute
    to determine that all paths terminated in such a way that there really
    was an inplied else. How much easier it would have been to read the code
    if the author had explicitly types the 'else'.

    If the "if" branch will unconditionally quit the loop (with a break,
    here, but could also be a return, a thrown exception, etc etc), I
    would prefer to see the "else" removed and its code unindented one
    level. Maybe this is just personal preference, though, learned from
    assembly language programming where a "block if" looks something like
    this:

    ; if x == y:
    CMP x,y
    JNZ .else
    ; Code for "x == y"
    JMP .endif
    .else:
    ; Code for "else"
    .endif

    Putting an unconditional departure in the "x == y" branch makes the
    "JMP .endif" redundant.

    Python is not assembly ;-). 3.3 effectively ignores the extraneous
    'else:'. Either way, if the condition is false, control jumps to the
    second print. For what little it matters, the bytecode is the same length.


    def f():
        while True:
          if a:
            b = 1
            break
          else:
            b = 2

    dis(f)
        2 0 SETUP_LOOP 25 (to 28)


        3 >> 3 LOAD_GLOBAL 0 (a)
                    6 POP_JUMP_IF_FALSE 19


        4 9 LOAD_CONST 1 (1)
                   12 STORE_FAST 0 (b)


        5 15 BREAK_LOOP
                   16 JUMP_ABSOLUTE 3


        7 >> 19 LOAD_CONST 2 (2)
                   22 STORE_FAST 0 (b)
                   25 JUMP_ABSOLUTE 3
    28 LOAD_CONST 0 (None)
                   31 RETURN_VALUE


    def f():
        while True:
          if a:
            b = 1
            break
          b = 2

    dis(f)
        2 0 SETUP_LOOP 25 (to 28)


        3 >> 3 LOAD_GLOBAL 0 (a)
                    6 POP_JUMP_IF_FALSE 19


        4 9 LOAD_CONST 1 (1)
                   12 STORE_FAST 0 (b)


        5 15 BREAK_LOOP
                   16 JUMP_FORWARD 0 (to 19)


        6 >> 19 LOAD_CONST 2 (2)
                   22 STORE_FAST 0 (b)
                   25 JUMP_ABSOLUTE 3
    28 LOAD_CONST 0 (None)
                   31 RETURN_VALUE


    --
    Terry Jan Reedy
  • Wxjmfauth at Aug 9, 2013 at 8:05 am

    Le jeudi 8 ao?t 2013 22:29:00 UTC+2, Terry Reedy a ?crit?:
    On 8/8/2013 7:41 AM, Chris Angelico wrote:
    On Thu, Aug 8, 2013 at 7:20 AM, wrote:

    def z2():
    ... letters = 'abc'
    ... while True:
    ... c = input('letter: ')
    ... if c not in letters:
    ... print('end, fin, Schluss')
    ... break
    ... else:
    ... print('do stuff')


    Minor quibble: I don't like having a hard exit followed by an "else".


    Whereas I tend to prefer to have the two alternatives cleanly marked as

    alternatives by both being indented the same.



    Many alternatives are not so trivial as the above. I remember reading

    one snippet in the CPython codebase where the 'else' was omitted and the

    if clause subdivided into about three paths. It took at least a minute

    to determine that all paths terminated in such a way that there really

    was an inplied else. How much easier it would have been to read the code

    if the author had explicitly types the 'else'.


    If the "if" branch will unconditionally quit the loop (with a break,
    here, but could also be a return, a thrown exception, etc etc), I
    would prefer to see the "else" removed and its code unindented one
    level. Maybe this is just personal preference, though, learned from
    assembly language programming where a "block if" looks something like
    this:

    ; if x == y:
    CMP x,y
    JNZ .else
    ; Code for "x == y"
    JMP .endif
    .else:
    ; Code for "else"
    .endif

    Putting an unconditional departure in the "x == y" branch makes the
    "JMP .endif" redundant.


    Python is not assembly ;-). 3.3 effectively ignores the extraneous

    'else:'. Either way, if the condition is false, control jumps to the

    second print. For what little it matters, the bytecode is the same length.



    def f():

    while True:

    if a:

    b = 1

    break

    else:

    b = 2


    dis(f)
    2 0 SETUP_LOOP 25 (to 28)



    3 >> 3 LOAD_GLOBAL 0 (a)

    6 POP_JUMP_IF_FALSE 19



    4 9 LOAD_CONST 1 (1)

    12 STORE_FAST 0 (b)



    5 15 BREAK_LOOP

    16 JUMP_ABSOLUTE 3



    7 >> 19 LOAD_CONST 2 (2)

    22 STORE_FAST 0 (b)

    25 JUMP_ABSOLUTE 3
    28 LOAD_CONST 0 (None)
    31 RETURN_VALUE



    def f():

    while True:

    if a:

    b = 1

    break

    b = 2


    dis(f)
    2 0 SETUP_LOOP 25 (to 28)



    3 >> 3 LOAD_GLOBAL 0 (a)

    6 POP_JUMP_IF_FALSE 19



    4 9 LOAD_CONST 1 (1)

    12 STORE_FAST 0 (b)



    5 15 BREAK_LOOP

    16 JUMP_FORWARD 0 (to 19)



    6 >> 19 LOAD_CONST 2 (2)

    22 STORE_FAST 0 (b)

    25 JUMP_ABSOLUTE 3
    28 LOAD_CONST 0 (None)
    31 RETURN_VALUE



    --

    Terry Jan Reedy

    -----


    The problem of this guy is not at this level.
    His problem is more simply, he most probably
    does not understand how to build a correct,
    proper loop.


    "What I wanted to happen is when the user typed something ...
    ... would cause the program to stop ... "




    jmf
  • Eschneider92 at Aug 9, 2013 at 10:27 pm
    This is what I ended up with btw. Does this insult anyone's more well attuned Python sensibilities?


    letters='abcdefghijkl'
    def repeat():
         print('wanna go again?')
         batman=input()
         if batman in ('y','yes'):
             main()
         else:
             return
    def main():
         print('guess a letter')
         batman=input()
         if batman in letters:
             print('ok that letter was in letters')
             repeat()
         else:
             print('asdasdasd')
             repeat()
    main()
    print('how ya doin')
  • Joshua Landau at Aug 9, 2013 at 11:05 pm

    On 9 August 2013 23:27, wrote:
    This is what I ended up with btw. Does this insult anyone's more well attuned Python sensibilities?

    ...


    Yes.


    You didn't listen to any of the advice we've been giving you. You've
    had *much* better answers given than this.




    Start from the top.


    We need letters, so define that:


         letters = "abcdefghijkl"


    We then want to loop, possibly forever. A good choice is a "while" loop.


         # True is always True, so will loop forever
         while True:


    We then want to ask for a letter. We want to use "input". Write
    "help(input)" in the Python Shell and you get

    help(input)
         Help on built-in function input in module builtins:


         input(...)
             input([prompt]) -> string


             Read a string from standard input. The trailing newline is stripped.
             If the user hits EOF (Unix: Ctl-D, Windows: Ctl-Z+Return),
    raise EOFError.
             On Unix, GNU readline is used if enabled. The prompt string, if given,
             is printed without a trailing newline before reading.


    So our line should be:


         letter = input("Type a letter from 'a' to 'n' in the alphabet: ")


    Then we want to test if it's on of our letters:


         if letter in letters:


    And if so we want to say something positive:


             print("That's right.")


    If not we want to say something negative:


         else:
             print("That's wrong.")


    And then we want to ask if we should go again:


         go_again = input("Do you want to do this again? ")


    If the response is "y" or "yes", we want to continue looping. The
    while loop will do that automatically, so we can do nothing in this
    circumstance.


    If the response in *not* "y" or "yes", we want to stop:


         if go_again not in ("y", "yes"):
            break




    That's it. No need to complicate things. Just take it one step at a time.
  • Eschneider92 at Aug 9, 2013 at 10:28 pm
    This is what I ended up with btw. Does this insult anyone's more well-attuned Pythonic sensibilities?


    letters='abcdefghijkl'
    def repeat():
         print('wanna go again?')
         batman=input()
         if batman in ('y','yes'):
             main()
         else:
             return
    def main():
         print('guess a letter')
         batman=input()
         if batman in letters:
             print('ok that letter was in letters')
             repeat()
         else:
             print('asdasdasd')
             repeat()
    main()
    print('how ya doin')
  • Eschneider92 at Aug 9, 2013 at 11:14 pm
    I don't understand any of the advice any of you have given.
  • Joshua Landau at Aug 9, 2013 at 11:30 pm

    On 10 August 2013 00:14, wrote:
    I don't understand any of the advice any of you have given.

    What about it don't you understand? Pick a sentence you don't
    understand and throw it back at us. If you understand all the
    sentences but not how they come together, say so. If there's a leap
    that you don't understand, say that you don't get it.


    We've tried rephrasing things a few ways but without any interaction
    we can't really help.


    ---


    You have said "I figured that ... the batman==False part of the
    repeat() function would cause the 'while batman==True' part to become
    False and end."


    We have said this is untrue. The "batman = False" inside the function
    does not affect "batman" outside of the function. You need to put
    "global batman" in the function for it to change "batman" on a global
    scope.


    You've not once explained what part of this explanation confuses you.
  • Eschneider92 at Aug 9, 2013 at 11:24 pm
    Thanks, though me not utilizing any of the other advice wasn't from lack of trying; I couldn't understand any of it. I get it now that I have a corrrect example code in front of me.
  • Eschneider92 at Aug 9, 2013 at 11:34 pm
    What does global mean?
  • Joshua Landau at Aug 10, 2013 at 1:22 am

    On 10 August 2013 00:34, wrote:
    What does global mean?

    Python has "scopes" for its variables. Most programming languages do.
    A "scope" is a restriction on where variables exist -- they exist only
    within the scope.


    This can be seen in this example:


         def function():
             # A new "scope" is made when you enter a function
             variable = 100


         function()
         print(variable)
         # Error, as variable doesn't exist outside of "function"'s scope


    There are lots of different "scopes" in code. Every function has one,
    and there are some more too.


    One of the scopes is the "global" scope. This is the scope *outside*
    of all the functions and other scopes. Everything in the file is
    within this sope:


         # Make in global scope
         variable = 100


         def function():
            # Works because we're inside the global scope
             print(variable)


         # Prints "100"
         function()


    So "a = b" inside the function applies to the function's scope, but
    when accessing variables (such as "print(variable)") it will look in
    all of the outer scopes too.


    If you want to write "a = b" inside the function and change the global
    scope, you need to say that "a" refers to the "a" in the global scope.
    You do that like this:


         def function():
             # "variable" is in the global scope, not the functions'
             global variable
             variable = 100


         function()
         # Prints "100"
         print(variable)




    Does that help you understand what "global" means?
  • Steven D'Aprano at Aug 10, 2013 at 1:40 am

    On Fri, 09 Aug 2013 16:34:48 -0700, eschneider92 wrote:


    What does global mean?

    Hi eschneider92,


    A few bits of advice:


    - You may like to actually sign your emails with a real name, or at least
    an alias that you want to be called, otherwise we'll just call you by
    your email address, and apart from sounding silly, many people don't like
    that.


    - You might also find that the tutor mailing list is a better match for
    your status as a complete beginner to Python. You can subscribe to it
    here:


    http://mail.python.org/mailman/listinfo/tutor




    - If you do, please take my advice and use individual emails, not daily
    digests. It is MUCH easier to carry on a back-and-forth conversation with
    individual emails.


    - Please try to quote enough of the message you are replying to to
    establish context, but without filling the email with page after page of
    irrelevant history. (Notice the line at the top of this message, starting
    with ">"? That's what you previously wrote.) If you need help configuring
    your email program to quote the previous message, just ask.






    --
    Steven
  • Eschneider92 at Aug 9, 2013 at 11:40 pm
    (I forgot to post this with my last post.)
    Also, I don't understand any part of the following example, so there's no specific line that's confusing me. Thanks for the help btw.


    var = 42
    def myfunc():
          var = 90


    print "before:", var
    myfunc()
    print "after:", var


    def myfunc():
         global var
         var = 90
  • MRAB at Aug 10, 2013 at 12:39 am

    On 10/08/2013 00:40, eschneider92 at comcast.net wrote:
    (I forgot to post this with my last post.)
    Also, I don't understand any part of the following example, so there's no specific line that's confusing me. Thanks for the help btw.
    You don't understand _any_ of it?



    var = 42

    Here you're assigning to 'var'. You're not in a function, so 'var' is a
    global variable.

    def myfunc():
    var = 90

    Here you're assigning to 'var'. If you assign to a variable anywhere in
    a function, and you don't say that that variable is global, then it's
    treated as being local to that function, and completely unrelated to
    any other variable outside that function.
    print "before:", var
    myfunc()
    print "after:", var

    def myfunc():
    global var
    var = 90
    Here you're assigning to 'var', but this time you've declared that it's
    global, so you're assigning to the global variable called 'var'.
  • Eschneider92 at Aug 9, 2013 at 11:43 pm
    (I forgot to post this with my last post.)
    Also, I don't understand any part of the following example, so there's no specific line that's confusing me. Thanks for the help btw.


    var = 42
    def myfunc():
          var = 90


    print "before:", var
    myfunc()
    print "after:", var


    def myfunc():
         global var
         var = 90
  • Eschneider92 at Aug 10, 2013 at 1:08 am
    I'm sorry, but I still don't understand how it applies to my problem. Thanks for everyone's patience.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedAug 7, '13 at 8:17a
activeAug 10, '13 at 1:40a
posts22
users9
websitepython.org

People

Translate

site design / logo © 2021 Grokbase