Following the Python3 Tutorial for non-programmers I took on the exercise of creating "quit" and "lock/log out" options for a very simple program, as follows (comments in the code are pretty dumb and obvious, but they are notes for mydumbself):

#!/usr/bin/python3
# Filename: lockunlock.py

password = str()
logged = 2
count = 0

def printMax(a, b):   #This is the core "utlity" of the program. In this case, to compare two numbers. 
    if float(a) > float(b): #The input is taken as string and not as float in its origin, in order to allow the "quit" and "lock" commands without separate prompt
      print(a, 'is maximum')              
    elif float(a) == float(b):
      print(a, 'is equal to', b)              
    else:   
      print(b, 'is maximum')

while logged !=0: 
  while password != "key":
    password = input("Password: ")
    count = count + 1 #to limit the number of password attempts
    if count >= 3:
      break # to get out of inner while loop
  logged = 1 
  
  if count >= 3: #to get of outer while loop
    logged = 0
    print("Wrong password for three times. Bye!")
    break 
  
  print("Welcome in") #Here starts the logged-in zone. 
  print("Type 'quit' to leave or 'lock' to log-out")
  
  while logged == 1:
    x = (input('Give a value for \'a\': '))
    if x == 'quit':
      logged = 0
      break
    elif x == 'lock':
      count = 0
      password = None
      break
        
    y = (input('Give a value for \'b\': '))
    if y == 'quit':
      logged = 0
      break
    elif y == 'lock':
      count = 0
      password = None
      break
          
    printMax(x,y)

print('Done')

There is an apparent unnecessary repetition, first with the lock/quit choices in the prompt for number “x”, and then for number “y”, and I read that repetitions are not good practice. I tried, therefore, to create a lock and quit function in the beggining of the file that could be recalled for each of "x" and "y":

def quitlock(a):
  if a == 'quit':
    global logged
    logged = 0    
    break  
  elif a == 'lock':
    global count
    count = 0
    global password
    password = None
    break

And I expected to recall the function this way:

while logged == 1:
    x = (input('Give a value for \'a\': '))
    quitlock(x)
        
    y = (input('Give a value for \'b\': '))
    quitlock(y)
          
    printMax(x,y)

However, I got the error message and learned that I cannot have a "break" statement outside of a loop. Which sounds strange for me, because I am not actually "applying" the break here, I am only defining it. It will be used only when the function is recall'ed, inside the while loop.

Anyway, for the "quit" choice, I learned that I can solve the problem adding the following to the first part of the definition of the function "quitlock" (and importing sys, naturally):

sys.exit('Bye!')

Still, I found no solution for the lock/log-out option. I need the function to get me out of the inner loop with variable 'Password' being different from 'key'. Any hints?

Many thanks in advance for any help.

You don't need to have a break commend in the quitLoc function. Just erase the two instances at lines 5 and 11 and all will be well: if/elif will enter only one of the blocks, then exit the function with a None return value

Aside: All those globals are bad form... but I'm not going to ding you too much at this point, since you are just beginning. The better technique is to have shared data in a class (which you will get to soon); or to pass it into functions as parameters and recover it as returned values. Note that one of Python's interesting features is multiple returns:

def exampleM(*args):
  joined = " ".join((str(x) for x in args))
  count = len(args)
  return count,joined

print("You passed %d args: %s"%(exampleM("one",2,"three")))
print("You passed %d args: %s"%(exampleM("four",5,6,7,8,"nine")))

so you can return more than one value if the values were mutated inside the function.

Another thing: You may want to think about a loop like this:

while True:
  #... do something
  if breakCondition:
     break
  #... do something more
  if anotherBreakCondition:
     break
  # etc
  # (end of loop)

This is a standard Python idiom for loops that have a variety of exit conditions.

Thank you griswolf!

I tried leaving nothing in the lines you mentioned (5 and 11) of the "quitlock" function.

But then I would arrive at the "PrintMax(x,y)" function (line 51 of original program) with strings not convertable to floats or integers and, thus, get an error message for trying math operations with strings.

I could filter activation of the PrintMax function using something like:

if x != "quit" or "lock"

But, in that case, it would be almost as bad as the original repetition.

I guess I have a lot of homework to do (noticeably with classes) before I am able to write the original code in a more logical and elegant manner.

Thanks once again!

This article has been dead for over six months. Start a new discussion instead.