I am creating code for a class project and part of it is that I need to find out if a set of randomly selected key words has a collective charachter length between two desired values. the issue i'm having is that Python stops executing as soon as it reaches the loop section. here is the whole code, I am having trouble with the part after the second user input.
import random #allows us to generate random numbers elsewhere in the code
set1=[] # creates empty sets
print("type genPassword() to initiate the program")
def genPassword():
print("Answer the following questions in order. What is your first pet’s name? What is your favorite word? What was your first car? What city/town were you born in? What was the name of your first partner? dont forget to press enter after each word, no spaces.")
for c in range(0,5): #allows the user to add elements to the list, each element has to be on a seperate line
ele=input()
set1.append(ele)
print(set1)#displays the current set, currently used for debugging purposes, making sure the code works
minlen=int(input("what is the minimum length you would like the password to be?: "))
maxlen=int(input("what is the max length you would like your password to be? (must be more than the shortest word you input in previous section): "))
passlen=0
while minlen >= passlen >= maxlen:
set2=[] #empties set 2
amnt = random.randint (1,5) #selects a random number for the anount of keywords to use
for f in range(0,amnt):
keys=random.sample(set1,1) #selects a random key word
set2.append(keys) #adds word to set 2
print(set2)#shows the words it chose
set_amnt=len(set2) #how many words in the set
iteration=0
string_len=0
for i in range(0,set_amnt):
word_len=len(set2[iteration][0]) #takes the length of each word and adds it to the lenght of the whole string
iteration=iteration 1
string_len=string_len word_len
print(string_len) #shows how long the string is (how many letters it is total)
passlen=string_len
I tried switching the loop types and adjusting where variables are in the code, but neither of those things worked and I cant think of what else to try to make it work. I even took the section out of a looping statement and it works then but it for some reason is having trouble with the loop. I expect it to select a random amount of words and tell me how long the whole string is and what words it picked out of a set of five words and then if the string is too long or too short it repicks and does it again and again until the string is within the accepted range of values for charachter length, printing the length and what words it chose each itteration.
CodePudding user response:
Edit: just tidying up this answer, since its been changed a few times based on my discussion in comments with the OP
This is your problem:
minlen=int(input("what is the minimum length you would like the password to>
maxlen=int(input("what is the max length you would like your password to be>
passlen=0
print ("Entering while loop ", minlen, passlen, maxlen)
while minlen >= passlen >= maxlen:
The passlen is set to zero, in the line above the while - so the condition is never met, as shown in my example output:
['Happy', 'Blue', 'Citroen', 'Liverpool', 'Rachel']
what is the minimum length you would like the password to be?: 5
what is the max length you would like your password to be? (must be more than the shortest word you input in previous section): 19
Entering while loop 5 0 19
I think you are logically trying to say:
if maxlen is bigger than minlen and minlen is bigger than passlen, do the loop.
But what you are actually saying is
if passlen is bigger than minlen and if minlen is bigger than maxlen then do the loop`
so the while line condition becomes (with my sample data):
while 5 >= 0 >= 19:
# some code that will never get executed unless they enter 0 for minimum password length
Firstly, you should re-write the logic of the while condition test, so it does what you intend.
while maxlen >= minlen >= passlen:
Should do the trick.
If that is not what you are intending, then unless you completely refactor the while (and maybe even the for) loop, and what you initially wrote was intended - then the goal you are aiming for is to have the code executed at least once, because you are setting passlen to a meaningful value only the end of the loop, so you only get a meaningful value of passlen after the loop executes once.
When examining logic, I ask myself
- Are you sure the logic of the condition statement is correct?
- Have a think, what am I trying to achieve with the conditional block/loop,
- does my condition test do what I intended to achieve that goal? and
- is it better served a different way.
Finally, I would add an if before the while, to test user input. If the min len is bigger than the max len, tell the user they made a boo-boo and exit.
This executes fine, and also goes around the for loop (I think 5? times on the first pass):
minlen=int(input("what is the minimum length you would like the password to>
maxlen=int(input("what is the max length you would like your password to be>
passlen=0
if minlen >= maxlen:
print ("minimum length is greater than or equal to maximum length! Abort")
exit()
while maxlen >= minlen >= passlen:
# the rest of your code
Some stuff I did not want to delete but is no longer the answer
edit: My original answer (before I tidied it up) went off on a tangent with a bunch of waffle about implementing a do code...while test
(a do foo until bar) loop for python, since there is no in-built one. I subsequently spotted the (in hindsight obvious) logic error and so don't necessarily need this tangent, but the text might be useful, so rather than delete it, I'm just plopping it here at the end:
How do we get one run of the loop before exiting? Instead of a while do while test do code
, we need a do until do code while test
which python does not have!
There is a fudge-y workaround to get do-until functionality into python, as detailed here, which goes along the lines of:
while true:
do code
if condition X:
break
This is checking the condition manually at the end of the loop, so that it always gets at least one pass. If you don't like the break
, and I am not keen either, you could have
boolTest = true
while boolTest
# do code
if condition_to_test:
boolTest = false
where the boolTest being set to false will cause the while loop to terminate, without having to use a break (I don't know about you, but when I see break - especially if there are several - I instantly am reminded of BBC BASIC and my heroic use of goto
as a child!