Why isnt the append() working in this block of code? - python

I've broken down the pieces of this code individually and it all works fine. Yet the append() method only appends once and then refuses to add anything else. I am absolutely losing my mind over this.
x = input("Input Password: ")
epicfail = []
def numberchecker(b):
return any(i.isdigit() for i in b)
def spacechecker(c):
return any(o.isspace() for o in c)
def passwordvalidator(a):
if len(a) < 12:
epicfail.append("Your password is too short!")
elif a.islower() == True:
epicfail.append("Your password contains zero uppercase letters!")
elif a.isupper() == True:
epicfail.append("Your password contains zero lowercase letters!")
elif numberchecker(x) == False:
epicfail.append("Your password contains zero numbers!")
elif spacechecker(x) == True:
epicfail.append("Your password contains a whitespace!")
return epicfail
print(passwordvalidator(x))
I expect the append() method to append to the epicfail list every time it is activated. Yet is only appends once. I have tried breaking down every piece of the code individually and it all works fine.

As you use elif, when one condition is met, all the others are ignored. If you want multiple to trigger, just use if instead.
Furthermore, you can remove "== True" when you are checking a boolean, and replace "if xxx == False:" by "if not xxx:".

Related

I was creating my own palindrome program when I came across that if I use [ ] for 'if' loop, every time it printed the 'if' statement

The use of parentheses for 'if' loop results in two different output for a palindrome program!
1.) () this gives the accurate result
2.) [] this only gives you the result of 'if' statement even if the "String" is not a palindrome
def isapalindrome(String):
if(String == String[::-1]):
return("is a palindrome!")
else:
return("is not a palindrome!")
String = input("Enter the String of your choice: ")
isapalindrome(String)
this code executes properly!
def isapalindrome(String):
if[String == String[::-1]]:
return("is a palindrome!")
else:
return("is not a palindrome!")
String = input("Enter the String of your choice: ")
isapalindrome(String)
this code executes only the 'if' statement!
() and [] are nothing alike.
() does what you expect it to, but wouldn't even be necessary since there is only one operator.
[] will create a list with a single element that equals the truth value of String == String[::-1], so either [True] or [False]. Independently of what the list contains, non-empty list in python are truthy. This means that your if condition will always evaluate to True
As other comments suggest, the correct structure of an if statement is:
if condition:
print("Do something")
else:
print("Do nothing")
Parenthesis are useful when using boolean expressions:
if (A==B) == C:
print("Do")
Point being, the brackets '[ ]' do not really belong there. As they are used to select a memory space within a given memory slot. Just like we would do with arrays.
I think is good that you are exploring different things, it is always good to know why things are the way they are.

Why doesn't if any(var0) == any(var1) work?

I'm very new to programming, and more new to Python, and I'm having a hard time figuring this out. I'm trying to make a simple text hangman game, and I'm trying to validate player1's input. Here's what I have so far.
a = 0
int = ["1","2","3","4","5","6","7","8","9","0"]
while a == 0:
print("Please choose any word by typing it here:")
d = input()
d = list(d)
print(d)
if any(int) == any(d):
print("Invalid input. Please choose a non-number with no spaces or special characters.")
I can't figure why, whether I include a number in my response or not, it always meets my any(int) == any(d) condition. I know I must just be misunderstanding how any() works.
You are right: the issue is with how you use the any() function. any() returns either True or False depending on whether or not any of the elements in its iterable argument are True, in other words if they exist and are not False or an empty list or empty string or 0. This will always evaluate as True for int because int does contain an element that is True and the same will happen for d unless you do not give any input when the input() function prompts you (you hit return without typing anything). What your conditional is basically asking is the following:
if True==True
To fix this, just change your code to the following:
a = 0
int = ["1","2","3","4","5","6","7","8","9","0"]
while a == 0:
print("Please choose any word by typing it here:")
d = input()
print(d)
for letter in d:
if letter in int:
print("Invalid input. Please choose a non-number with no spaces or special characters.")
break
The easiest solution, however, does not involve the int list at all. There is actually a special method in python that can gauge whether or not a string has a number (or special character) in it, and this method, .isalpha() can be used to streamline this process even further. Here's how to implement this solution:
while True:
d = input("Please choose any word by typing it here: \n")
print(d)
if not d.isalpha():
print("Invalid input. Please choose a non-number with no spaces or special characters.")
Try this:
a = 0
ints = ["1","2","3","4","5","6","7","8","9","0"]
while a == 0:
print("Please choose any word by typing it here:")
word = input()
word_list = list(word)
if any(letter in ints for letter in word_list):
print("Invalid input. Please choose a non-number with no spaces or special characters.")

I need advice with while loop in python

I'm using python3 on mac.
I'm currently doing a project. However, I was trying to use "while = True" to continuously use the program until a condition is met. Please, tell me what am I missing in my code. Thanks!
import json
import difflib
from difflib import get_close_matches
data = json.load(open("project1/data.json"))
word = input("Enter a word or enter 'END' to quit: ")
def keyword(word):
word = word.lower()
while type(word) == str:
if word in data:
return data[word]
elif word == 'END'.lower():
break
elif len(get_close_matches(word, data.keys())) > 0:
correction = input("Did you mean %s insted? Enter Yes of No: " % get_close_matches(word, data.keys())[0])
if correction == "Yes".lower():
return data[get_close_matches(word, data.keys())[0]]
elif correction == "No".lower():
return "This word doesn't exist. Plese enter again. "
else:
return "Please enter 'Yes' or 'No: "
else:
return "This word doesn't exist. Please enter again."
print("Thanks!")
output = (keyword(word))
if type(output) == list:
for item in output:
print(item)
else:
print(output)
I think this might be the setup you are looking for.
def keyword(word):
if word in data:
return data[word]
elif len(get_close_matches(word, data.keys())):
correction = input(f"Did you mean {get_close_matches(word, data.keys())[0]} instead? y/n: ")
if correction == 'y':
return data[get_close_matches(word, data.keys())[0]]
elif correction == 'n':
return "This word doesn't exist. Please enter again."
else:
return "Please type 'y' or 'n': "
else:
return "This word doesn't exist. Please enter again."
while True:
word = input("Enter a word: ").lower()
if word == 'end':
print("Thanks!")
break
else:
print(keyword(word))
Looking at the source code and your question, it seems like what you want to achieve is basically to continuously accept input from the user until the user enters something like 'end'. One way to go about this is to separate out the while-loop logic from the function. The overarching while-loop logic is at the bottom half of the code, where we continuously accept input from the user until the user inputs some lower or upper case variant of 'end'. If this condition is not met, we proceed to printing out the result of the function call keyword(word).
Minimal modifications were made to the original keyword() function, but here are a few changes worthy of note:
The while type(word) == str is unnecessary, since the result stored from the input() function will always be a string. In other words, the condition will always return True.
Having return statements within a while loop defeats the purpose of a loop, since the loop will only be executed once. After returning the specified value, the function will exit out of the loop. This is why we need to separate out the loop logic from the function.
Although %s works, it's a relic of C. This might be a matter of personal choice, but I find f-strings to be much more pythonic.
You are using the worng condition.
type((3,4))== list
is False. You must use
type((3,4)) == tuple

compare user input to list of key words

I want to take user input and compare it to a list of key words through a function, if any of the words input by the user match a key word, the condition is met and breaks the loop. If none of the words match a key word, then the console asks for input again. I have been manipulating this loop and have either gotten it to continuously ask for input no matter if a key word is met or validate every word input. Any advice on how to correct it would be great appreciated.
def validated_response(user_complaint):
valid_list = user_complaint.split()
while True:
if user_complaint == "stop":
break
for valid in valid_list:
if valid.lower() not in user_complaint.lower():
print("Response not recognized, please try again")
input("Enter response: ")
continue
else:
print("response validated: ")
break
return True
This function will continue getting user input until the input matches "kwrd1", "kwrd2", or "kwrd3":
def get_input():
keywords = ['kwrd1', 'kwrd2', 'kwrd3']
user_input = None
while True:
user_input = input()
if user_input in keywords:
break
return user_input
If you are matching it against a python keyword, there is a builtin keyword module:
import keyword
def get_input():
user_input = None
while True:
user_input = input()
if keyword.iskeyword(user_input):
break
return user_input
You are always reaching the else statement if the first element in valid_list is not a substring of the user_complaint string. That means you're always breaking out of the for loop and reentering the infinite while loop. Try this instead:
def validated_response(user_complaint):
valid_list = user_complaint.split()
if user_complaint == "stop":
return
inp = input("Enter response: ")
while inp.lower() not in valid_list:
inp = input("Enter response: ")
The provided code has a number of problems. The example does also not show how the function would be called, but I assumed you'd want to call it with a text that has all the keywords you're looking for.
The first problem is you are calling input, but not storing its return value, so you're not actually collecting the user input.
Secondly, you're comparing the various parts of valid_list to the contents of user_complaint.lower(), but that means you're compare a string to the characters in another string - not what you want.
Thirdly, you're asking for new input in a single clause of a condition, inside your loop, so this will lead to messages printing repeatedly and the user having to enter new text before all the comparisons are done.
Finally, you're mixing continue, break and return in a way that doesn't work. continue tells Python to move on to the next cycle of a loop, skipping any remaining code in the current cycle. break tells Python to get out of the current block (in this case the loop). return tells Python to exit the function altogether and return a provided value (or None if none is provided).
Here is an example that more or less follows the structure you set up, but with all of the problems remedied:
def validated_response(keywords):
valid_list = keywords.split()
while True:
user_input = input('Enter response: ').lower().split()
if user_input == ['stop']:
return False
for valid in valid_list:
if valid.lower() in user_input:
print('response validated: ')
return True
print('Response not recognized, please try again')
print(validated_response('trigger test'))

python secret word program

I'm trying to write a program where the user has to guess a letter in the goal of unlocking the secret word. If the secret word is guessed correctly before the maximum 8 guesses, the function returns true else the function returns false. For some reason my function just doesn't produce the right output. I would enter the letter 'a' and it would print "Letters guessed so far: ['a']" and then the program would end. I need help in fixing this issue.
secretWord = 'hello'
lettersGuessed = []
def isWordGuessed(secretWord,lettersGuessed):
guess = 0
while guess <= 8:
secretLetters = list(secretWord)
secretWordLen = len(secretLetters)
letter = input('Enter a letter: ')
lettersGuessed.append(letter)
print('Letters guessed so far: ',lettersGuessed)
if letter not in secretLetters:
guess += 1
while letter in secretLetters:
secretLetters.remove(letter)
if secretLetters == []:
return True
else:
return False
isWordGuessed(secretWord,lettersGuessed)
Your first problem is, as kwatford explained, that you are returning every time through the loop. You can fix that by moving the if statement outside the while loop.
Your next problem, as Vorticity explained, is that it will never return early, even if the user guesses the whole word. To fix that, move the if part back inside the loop, but leave the else part outside the loop (meaning you no longer need the else)
After that, it still won't work, because you're doing secretLetters = list(secretWord) each time through the loop, so you can only win if you guess all the letters in one guess (which is impossible, unless the word is, say, "a" or "aaaaa"). To fix that, move that line outside the loop.
Putting it all together:
def isWordGuessed(secretWord,lettersGuessed):
guess = 0
secretLetters = list(secretWord)
while guess <= 8:
secretWordLen = len(secretLetters)
letter = input('Enter a letter: ')
lettersGuessed.append(letter)
print('Letters guessed so far: ',lettersGuessed)
if letter not in secretLetters:
guess += 1
while letter in secretLetters:
secretLetters.remove(letter)
if secretLetters == []:
return True
return False
As a side note, there are a lot of things you can do to simplify this.
First, you really just need a set of all letters in the secret word—you don't need to know the order, or how many copies there are of each, etc. So, instead of a list, use a set. This also means you don't need the loop around secretLetters.remove(letter).
More trivially, you create secretWordLen but never use it.
You also accept and append to a lettersGuessed passed in by the caller, but the caller is just passing you an empty list, and never using it after the fact, so why bother? And if you don't need to mutate it for the caller's benefit, you can just keep it as a string, so the user sees help instead of ['h', 'e', 'l', 'p'], which is a lot nicer.
You've also got a few cases that are being tested even when they can't possibly be true.
Finally, an empty list (or set, or any other sequence) is false, so there's no reason to explicitly compare to the empty list.
While I'm at it, I'm going to PEP8-ify the spacing to make it easier to see the indentation.
So:
def isWordGuessed(secretWord):
guess = 0
lettersGuessed = ''
secretLetters = set(secretWord)
while guess <= 8:
letter = input('Enter a letter: ')
lettersGuessed += letter
print('Letters guessed so far:', lettersGuessed)
if letter not in secretLetters:
guess += 1
else:
secretLetters.remove(letter)
if not secretLetters:
return True
return False
The last if statement is indented too far, causing it to be part of your while loop. Since both branches of the condition cause the function to return, it always returns on the first iteration of the loop.
You just need to move your return for the False case. Basically, the way your code is written right now, you will never go back to the beginning of your loop. Also, as noted by abarnert, you will never exit the loop because you are reinitializing secretLetters every time you loop. You have to initialize it outside the loop. Your code should look like this:
secretWord = 'hello'
lettersGuessed = []
def isWordGuessed(secretWord,lettersGuessed):
guess = 0
secretLetters = list(secretWord)
secretWordLen = len(secretLetters)
while guess <= 8:
letter = input('Enter a letter: ')
lettersGuessed.append(letter)
print('Letters guessed so far: ',lettersGuessed)
if letter not in secretLetters:
guess += 1
while letter in secretLetters:
secretLetters.remove(letter)
if secretLetters == []:
#Return true if all correct letters have been guessed
return True
#Return false if guessed incorrectly eight times
return False

Categories