Hangman code

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • St33med
    New Member
    • Mar 2007
    • 21

    Hangman code

    Making a hangman code (I'm a n00b, still in the tutorial stage)

    Anyway, here's my (top-secret) code:
    Code:
    def guess():
        choice=raw_input("Guess!(lowercase only please!)")
        if len(choice)>1:
            print "Don't cheat!"
            guess()
        elif guess in y:
            b[z.find(choice)]=choice
            print "Good Choice!"
            print ''.join(b)
            guess()
        
    def main():
        x=raw_input("Type a name")
        y=x.lower().split(' ')
        z=''.join(y)
        print z
        b=['_ ']*len(z)
        print ''.join(b)
        guess()
    
    if __name__=='__main__':
        main()
    Anyways, I get down to line 6 and it tells me that global name z is not defined. I'm guessing I have to put the z thing in there, but I don't know how.

    What should I do?
    P.S. the code is still in development. That is why it is not finished.
  • bartonc
    Recognized Expert Expert
    • Sep 2006
    • 6478

    #2
    Originally posted by St33med
    Making a hangman code (I'm a n00b, still in the tutorial stage)

    Anyway, here's my (top-secret) code:
    Code:
    def guess():
        choice=raw_input("Guess!(lowercase only please!)")
        if len(choice)>1:
            print "Don't cheat!"
            guess()
        elif guess in y:
            b[z.find(choice)]=choice
            print "Good Choice!"
            print ''.join(b)
            guess()
        
    def main():
        x=raw_input("Type a name")
        y=x.lower().split(' ')
        z=''.join(y)
        print z
        b=['_ ']*len(z)
        print ''.join(b)
        guess()
    
    if __name__=='__main__':
        main()
    Anyways, I get down to line 6 and it tells me that global name z is not defined. I'm guessing I have to put the z thing in there, but I don't know how.

    What should I do?
    P.S. the code is still in development. That is why it is not finished.
    Hi St33med. Most code we see here is "still in development"; we're here to help you get it working. So, welcome to the Python help forum on TSDN!

    This is an issue of "scope". The scope rules say that variables assigned in a function are "local" to that function. I quick way to make this work is (but maybe not the best):
    Code:
    def guess():
        choice=raw_input("Guess!(lowercase only please!)")
        if len(choice)>1:
            print "Don't cheat!"
            guess()
        elif guess in y:
            b[z.find(choice)]=choice
            print "Good Choice!"
            print ''.join(b)
            guess()
        
    if __name__=='__main__':
        x=raw_input("Type a name")
        y=x.lower().split(' ')
        z=''.join(y)
        print z
        b=['_ ']*len(z)
        print ''.join(b)
        guess()
    I'm in a rush at this second, but I'll have some time in just a bit...
    Thanks for joining.

    Comment

    • bartonc
      Recognized Expert Expert
      • Sep 2006
      • 6478

      #3
      Originally posted by bartonc
      Hi St33med. Most code we see here is "still in development"; we're here to help you get it working. So, welcome to the Python help forum on TSDN!

      This is an issue of "scope". The scope rules say that variables assigned in a function are "local" to that function. I quick way to make this work is (but maybe not the best):
      Code:
      def guess():
          choice=raw_input("Guess!(lowercase only please!)")
          if len(choice)>1:
              print "Don't cheat!"
              guess()
          elif guess in y:
              b[z.find(choice)]=choice
              print "Good Choice!"
              print ''.join(b)
              guess()
          
      if __name__=='__main__':
          x=raw_input("Type a name")
          y=x.lower().split(' ')
          z=''.join(y)
          print z
          b=['_ ']*len(z)
          print ''.join(b)
          guess()
      I'm in a rush at this second, but I'll have some time in just a bit...
      Thanks for joining.
      What this does is put the varaibles x, y and z into the module scope. As such, they can be "seen" by functions that are also in that scope. This use of "global" scope variables is good for learning because it is fairly simple. There are lot's of other things to change before we get to the final working program, but let's take it one step at a time. And HAVE FUN.

      Comment

      • St33med
        New Member
        • Mar 2007
        • 21

        #4
        Well, the code worked and I made some enhancements:
        Code:
        def guess():
            choice=raw_input("Guess!(lowercase only please!)")
            a=type.find(str(choice))
            if len(choice)>1:
                print "Don't cheat!"
                guess()
            elif a!=-1:
                b[a]=str(choice)
                print "Good Choice!"
                c=''.join(b)
                print c
                if type==c:
                    print "You Win!"
                else:
                    guess()
            else:
                d+=1
                e[d]=choice
                if d==0:
                    print "O",e
                    guess()
                elif d==1:
                    print e,"O<"
                    guess()
                elif d==2:
                    print e,"0<-"
                    guess()
                elif d==3:
                    print e,"O<-<\n Game Over"
                    
        if __name__=='__main__':
            type=raw_input("Type a name:")
            type=''.join(type.lower().split(' '))
            #print type
            b=['_ ']*len(type)
            print ''.join(b)
            d=-1
            e=['']*5
            guess()
        The problem with this code is that it tells me that d was referenced before assignment. If I put d in def guess, then it will always return d to -1 and the guy taking guesses will have infinite amount of guesses. That might have been why you said that the solution was not the best. What should I do?

        Comment

        • ghostdog74
          Recognized Expert Contributor
          • Apr 2006
          • 511

          #5
          Originally posted by St33med
          Well, the code worked and I made some enhancements:
          Code:
          def guess():
              choice=raw_input("Guess!(lowercase only please!)")
              a=type.find(str(choice))
              if len(choice)>1:
                  print "Don't cheat!"
                  guess()
              elif a!=-1:
                  b[a]=str(choice)
                  print "Good Choice!"
                  c=''.join(b)
                  print c
                  if type==c:
                      print "You Win!"
                  else:
                      guess()
              else:
                  d+=1
                  e[d]=choice
                  if d==0:
                      print "O",e
                      guess()
                  elif d==1:
                      print e,"O<"
                      guess()
                  elif d==2:
                      print e,"0<-"
                      guess()
                  elif d==3:
                      print e,"O<-<\n Game Over"
                      
          if __name__=='__main__':
              type=raw_input("Type a name:")
              type=''.join(type.lower().split(' '))
              #print type
              b=['_ ']*len(type)
              print ''.join(b)
              d=-1
              e=['']*5
              guess()
          The problem with this code is that it tells me that d was referenced before assignment. If I put d in def guess, then it will always return d to -1 and the guy taking guesses will have infinite amount of guesses. That might have been why you said that the solution was not the best. What should I do?
          in your guess() function, 'd' is never 'initialized' before you do d+=1.
          Either you pass 'd' value into guess(), as in guess(d) , or use global.

          Comment

          • bartonc
            Recognized Expert Expert
            • Sep 2006
            • 6478

            #6
            What my friend ghostdog74 means is:
            Code:
            def guess():
                global d
                choice=raw_input("Guess!(lowercase only please!)")
                a=type.find(str(choice))
                if len(choice)>1:
                    print "Don't cheat!"
                    guess()
                elif a!=-1:
                    b[a]=str(choice)
                    print "Good Choice!"
                    c=''.join(b)
                    print c
                    if type==c:
                        print "You Win!"
                    else:
                        guess()
                else:
                    d+=1
                    e[d]=choice
                    if d==0:
                        print "O",e
                        guess()
                    elif d==1:
                        print e,"O<"
                        guess()
                    elif d==2:
                        print e,"0<-"
                        guess()
                    elif d==3:
                        print e,"O<-<\n Game Over"
            
            if __name__=='__main__':
                type=raw_input("Type a name:")
                type=''.join(type.lower().split(' '))
                #print type
                b=['_ ']*len(type)
                print ''.join(b)
                d=-1
                e=['']*5
                guess()
            It's very cute! I ran it and it work using this global scope technique. You a really quit a good pythoneer. Keep it up! Next you may want to play with parameter passing (also as GD has suggested).

            Comment

            • ghostdog74
              Recognized Expert Contributor
              • Apr 2006
              • 511

              #7
              Just an opinion of mine, its better to use while loop for tasks like this:
              for example:
              Code:
              while 1:
                       ask for input
                       if input is quit or exit:
                              break
                       else:
                              call your functions.
              In the original code, guess() is defined as a function, but in it, there are also calls to guess() itself. In programming concepts, this is something like recursion. Before the first call to guess() has returned to caller, another guess() gets called and so on. The stack gets slowly "filled up" due to storing of return addresses and etc etc......at least that's how i feel.

              Comment

              • bvdet
                Recognized Expert Specialist
                • Oct 2006
                • 2851

                #8
                Originally posted by bartonc
                What my friend ghostdog74 means is:
                Code:
                def guess():
                    global d
                    choice=raw_input("Guess!(lowercase only please!)")
                    a=type.find(str(choice))
                    if len(choice)>1:
                        print "Don't cheat!"
                        guess()
                    elif a!=-1:
                        b[a]=str(choice)
                        print "Good Choice!"
                        c=''.join(b)
                        print c
                        if type==c:
                            print "You Win!"
                        else:
                            guess()
                    else:
                        d+=1
                        e[d]=choice
                        if d==0:
                            print "O",e
                            guess()
                        elif d==1:
                            print e,"O<"
                            guess()
                        elif d==2:
                            print e,"0<-"
                            guess()
                        elif d==3:
                            print e,"O<-<\n Game Over"
                
                if __name__=='__main__':
                    type=raw_input("Type a name:")
                    type=''.join(type.lower().split(' '))
                    #print type
                    b=['_ ']*len(type)
                    print ''.join(b)
                    d=-1
                    e=['']*5
                    guess()
                It's very cute! I ran it and it work using this global scope technique. You a really quit a good pythoneer. Keep it up! Next you may want to play with parameter passing (also as GD has suggested).
                It does work well. However, if you enter a word that has two of the same letter as in "sell", you can never solve it. You should not use a variable name that masks a Python built-in function (type). We had another thread on Hangman recently, and we used this function to determine the occurances of a letter in a word:
                Code:
                def indexList(s, item, i=0):
                    i_list = []
                    while True:
                        try:
                            i = s.index(item, i)
                            i_list.append(i)
                            i += 1
                        except:
                            break
                    return i_list
                I agree with ghostdog74 abot the use of a loop instead of recursion. I also encourage you to avoid using global variables where possible. As in the function listed above, the word (s) and letter (item) are passed to get_index() and in return we receive a list of indices or an empty list if there were no occurances of 'item' in 's':
                Code:
                >>> iLst = indexList('mississippi', 's')
                >>> iLst
                [2, 3, 5, 6]
                >>> hint_string = '_'*len('mississippi')
                >>> for i in iLst:
                ... 	lst = [hint_string[:i], ]
                ... 	if len(hint_string) >= i+1:
                ... 		lst.append(hint_string[(i+1):])
                ... 	hint_string = 's'.join(lst)
                ... 	
                >>> hint_string
                '__ss_ss____'
                >>>

                Comment

                • St33med
                  New Member
                  • Mar 2007
                  • 21

                  #9
                  Well here is my code, almost finished:
                  Code:
                  import sys
                  def guess(d,x,e):
                              choice=raw_input("Guess!(lowercase only please!)")
                              a=type.find(str(choice))
                              if len(choice)>1:
                                  print "Don't cheat!"
                                  guess(d,x,e)
                              elif a!=-1:
                                  b[a]=str(choice)
                                  print "Good Choice!"
                                  c=''.join(b)
                                  print c, e
                                  if type==c:
                                      print "You Win!"
                                      sys.exit()
                                  else:
                                      guess(d,x,e)
                              else:
                                  d+=x
                                  if guess in e:
                                      print "You have already guessed this!"
                                      guess(d,x,e)
                                  e[d]=choice
                                  if d==0:
                                      print "O"
                                      x=1
                                  elif d==1:
                                      print "O<"
                                      x=2
                                  elif d==2:
                                      print "0<-"
                                      x=3
                                  elif d==3:
                                      print "O<-<\n Game Over"
                                      sys.exit()
                                  print "Letters Guessed: ", ' '.join(e)
                                  guess(d,x,e)
                  if __name__=='__main__':
                      type=raw_input("Type a name:")
                      type=''.join(type.lower().split(' '))
                      #print type
                      b=['_ ']*len(type)
                      print ''.join(b)
                      d=0
                      x=0
                      e=['']*4
                      guess(d,x,e)
                  Where should I put this indexList?

                  Comment

                  • bvdet
                    Recognized Expert Specialist
                    • Oct 2006
                    • 2851

                    #10
                    Originally posted by St33med
                    Well here is my code, almost finished:
                    Code:
                    import sys
                    def guess(d,x,e):
                                choice=raw_input("Guess!(lowercase only please!)")
                                a=type.find(str(choice))
                                if len(choice)>1:
                                    print "Don't cheat!"
                                    guess(d,x,e)
                                elif a!=-1:
                                    b[a]=str(choice)
                                    print "Good Choice!"
                                    c=''.join(b)
                                    print c, e
                                    if type==c:
                                        print "You Win!"
                                        sys.exit()
                                    else:
                                        guess(d,x,e)
                                else:
                                    d+=x
                                    if guess in e:
                                        print "You have already guessed this!"
                                        guess(d,x,e)
                                    e[d]=choice
                                    if d==0:
                                        print "O"
                                        x=1
                                    elif d==1:
                                        print "O<"
                                        x=2
                                    elif d==2:
                                        print "0<-"
                                        x=3
                                    elif d==3:
                                        print "O<-<\n Game Over"
                                        sys.exit()
                                    print "Letters Guessed: ", ' '.join(e)
                                    guess(d,x,e)
                    if __name__=='__main__':
                        type=raw_input("Type a name:")
                        type=''.join(type.lower().split(' '))
                        #print type
                        b=['_ ']*len(type)
                        print ''.join(b)
                        d=0
                        x=0
                        e=['']*4
                        guess(d,x,e)
                    Where should I put this indexList?
                    Anywhere above "if __name__ == '__main__':"

                    Comment

                    • St33med
                      New Member
                      • Mar 2007
                      • 21

                      #11
                      Originally posted by bvdet
                      Anywhere above "if __name__ == '__main__':"
                      And then put the indexList in what part of the code?

                      Comment

                      • bvdet
                        Recognized Expert Specialist
                        • Oct 2006
                        • 2851

                        #12
                        Originally posted by St33med
                        And then put the indexList in what part of the code?
                        You will need to rework your code somewhat, because you have a list of indices instead of a single index. Here's a start:
                        Code:
                                def guess(d,x,e):
                                    choice = raw_input("Guess!(lowercase only please!)")
                                    aList = indexList(word, choice)
                                    ...........................
                                    elif len(aList) > 0:
                                        print 'There are %d occurrances of %s in %s' % (len(aList), choice, word)
                        Notice that I am using 'word' instead of 'type'.

                        Comment

                        • St33med
                          New Member
                          • Mar 2007
                          • 21

                          #13
                          Need an explanation of what indexList does. I'm just having a hard time following what it does.

                          Comment

                          • St33med
                            New Member
                            • Mar 2007
                            • 21

                            #14
                            Never mind about last. The problem is when I put aList as the element in b (as in b[aList]=str(choice)) , it tells me that aList needs to be an integer, not a list. How do I transform aList into an integer?

                            Comment

                            • bartonc
                              Recognized Expert Expert
                              • Sep 2006
                              • 6478

                              #15
                              Originally posted by St33med
                              Need an explanation of what indexList does. I'm just having a hard time following what it does.
                              Code:
                              def indexList(s, item, i=0):
                                  i_list = []
                                  while True:
                                      try:
                                          i = s.index(item, i)
                                          i_list.append(i)
                                          i += 1
                                      except:
                                          break
                                  return i_list
                              returns a list of inexes for every occurance of item in s.

                              Comment

                              Working...