Rejecting Strings with a space between two words - python

So I've almost finished a program in which the user inputs a name/word and it spits out the Soundex counterpart.
The code runs well and the Soundex methodology is sound, "Get it Sound". What I had issues with were the strings being returned. Things like space before or after the word typed in or having an uppercase and lowercase name being repeated when they shouldn't have been. Those got fixed rather easily.
What I'm having issues with now is when the user inputs something like, "Carl Sagan" it returns the ("Word should only contain characters") elif of my program.
What I'd like to do is respond to the user and say, ("Two words entered at once, Please enter one at a time."). When those instances happen.
Here's a snippet of my code:
#input name
name = input("To start, Please give your name :")
print("\nGreetings,", name.strip().capitalize(), "Your Soundex-name is:", convert_to_soundex(name), "\n" )
#creating dictionary
dicti={}
#convert name to code and store in dictionary
dicti[name]=convert_to_soundex(name)
# keeping asking user for a word or name until user enters 0
while(True):
word=input("Please give a word to convert (0 to exit) :").strip().capitalize()
if word=='0':
break
elif word=="":
print("Please give word with atleast one character.")
elif not word.isalpha():
print("Word should only contain characters.")
else:
if word in dicti:
print("Word already exists")
else:
dicti[word]=convert_to_soundex(word)
#printing formatted data
printData(dicti)

You can add another while..if instead of name input like this:
while True:
name = input("To start, Please give your name :")
if ' ' in name:
print("Two words entered at once, Please enter one at a time.")
else:
break

#input name
name = input("To start, Please give your name :")
print("\nGreetings,", name.strip().capitalize(), "Your Soundex-name is:", convert_to_soundex(name), "\n" )
#creating dictionary
dicti={}
#convert name to code and store in dictionary
dicti[name]=convert_to_soundex(name)
# keeping asking user for a word or name until user enters 0
while(True):
word=input("Please give a word to convert (0 to exit) :").strip().capitalize()
if word=='0':
break
elif ' ' in word:
print("Two words entered at once, Please enter one at a time.")
elif word=="":
print("Please give word with atleast one character.")
elif not word.isalpha():
print("Word should only contain characters.")
else:
if word in dicti:
print("Word already exists")
else:
dicti[word]=convert_to_soundex(word)
#printing formatted data
printData(dicti)

name = input("give name please...")
for nam in name:
if nam == " ":
print('invalid input')
# removes space from input
print(''.join([i for i in name if i != " "]))

Related

Word guesser doesn't print enough characters

The idea is that you enter any passwords/characters and then it tries to find that word that you have entered by trying out different combinations of letters and numbers (it really is pointless huh)
The problem right now is that "pw_guess" only prints out one letter or number at a time. There also appears to be duplicates. For example i found that letter "e" was printed 6 times, though should only print it once.
import random
characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
pw = input("Enter a password: \n")
pw_lenght = len(pw)
while True:
for i in range(pw_lenght):
random_character = random.randrange(len(characters))
pw_guess = characters[random_character]
if pw_guess == pw:
print('Password found!\nPassword: ', pw)
exit()
print(pw_guess)
It is suppose to print and try out as many letter/numbers at a time as how many have been entered in to the user input.
For example:
You type "password123" to the input. Then it will count how many
characters there are in that user input (11 in this example), and
starts trying out and printing different combinations of characters.
One print should now include 11 random characters. Then at some point
it will get right combination and stop.
As said above, now it only prints one character at a time and there are also duplicate characters which i don't want.
I've tried putting just one letter to the user input, and it guessed it right, so otherwise it works fine.
import random
characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
pw = input("Enter a password: \n")
pw_lenght = len(pw)
while True:
for i in range(pw_lenght):
random_character = random.randrange(len(characters))
pw_guess = ''.join([characters[random.randrange(len(characters))] for x in range(len(pw))])
if pw_guess == pw:
print('Password found!\nPassword: ', pw)
exit()
print(pw_guess)
Your inner loop should assemble all the random characters into a single password guess, instead of guessing each letter separately.
import random
characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
pw = input("Enter a password: \n")
while True:
pw_guess = ''
for i in range(len(pw)):
pw_guess += random.choice(characters)
if pw_guess == pw:
print('Password found!\nPassword: ', pw)
break
print('Password not found. Incorrect guess: ', pw_guess)
Since Python 3.6 you can use random.choises to get more characters at once.
I would recommend the string-module for better readability.
It's very annoying to fill the terminal with thousands of incorrect guesses, so I've changed the code a little.
import string
import random
characters = string.digits + string.ascii_letters
password = input('Enter a password:\n')
guesses = 1
while True:
pw_guess = ''.join(random.choices(characters, k=len(password)))
if password == pw_guess:
break
guesses += 1
print('Password found!')
print(f'Password: {pw_guess}')
print(f'{guesses} guesses needed')

Python- Reading and Appending a File

I am trying to create a program that asks a user for input "name" and checks to make sure that the name is alphabetic, not too long, and not in a file called Unacceptable_Names (that contains inappropriate names)
To make sure that each user of the program doesn't use the same name, when a player enters a name I append it to Unacceptable_Names, then when the next player plays it should give them an error if they enter a name in this file.
The code below works for the words already created in the file, but when I replay and enter the same name I do not get an error. Can someone help troubleshoot why the name is not being checked?
def Char_Name(self,name):
string1=str(name).lower()
unacceptable_names=open("C://Users//Documents//Unacceptable_Names.txt", "r")
unacceptable_names2=open("C://Users//Documents//Unacceptable_Names.txt", "a")
names_list= []
for line in unacceptable_names.readlines():
for i in line.split(","):
names_list.append(i.strip())
if name.isalpha()==False:
print("You entered a name containing non-alphabetic characters, pease reenter a new name:")
main()
elif len(name)>=10:
print("You entered a name containing 10 or more characters, pease reenter a new name:")
main()
elif string1 in names_list:
print("You entered a name containing bad words or a name already in use! Try again.")
main()
else:
unacceptable_names2.write("\n"+str(name)+",")
unacceptable_names2.close()
self.character_name=name
This is what unacceptable_names looks like after entering a name "Emily": [along with some other bad words in the file before it- all of which if entered give me an error]
wrinkled starfish,
xx,
xxx,
yaoi,
yellow showers,
yiffy,
zoophilia,
Emily,
However, if I manually go into the text file and write "Emily" exactly how it is above, it will give me the error message that I need.
This line unacceptable_names2.write(name) appends names to the same line.
You should each name with a , after each name. Only then will
for line in unacceptable_names.readlines():
for i in line.split(","):
names_list.append(i.strip())`
work.
Current file content after unacceptable_names2.write(name):
helloonetwothree
What you want it to be:
hello,one,two,three
Updated code:
def Char_Name(self,name):
string1=str(name).lower()
unacceptable_names=open("C://Users//Documents//Unacceptable_Names.txt", "r")
unacceptable_names2=open("C://Users//Documents//Unacceptable_Names.txt", "a")
names_list= []
for line in unacceptable_names.readlines():
for i in line.split(","):
names_list.append(i.strip())
if name.isalpha()==False:
print("You entered a name containing non-alphabetic characters, pease reenter a new name:")
main()
elif len(name)>=10:
print("You entered a name containing 10 or more characters, pease reenter a new name:")
main()
elif string1 in names_list:
print("You entered a name containing bad words or a name already in use! Try again.")
main()
else:
unacceptable_names2.write(name+',')
unacceptable_names2.close()
self.character_name=name
Update:
Add i.strip() to the code above.
You are somehow adding a whitespace to the beginning of each name.
So when you search for yiffy it is not able to find the match. Because it is stored as yiffy instead.
In [54]: 'wrinkled starfish, xx, xxx, yaoi, yellow showers, yiffy, zoophilia, Emily,'.split(','
....: )
Out[54]:
['wrinkled starfish',
' xx',
' xxx',
' yaoi',
' yellow showers',
' yiffy',
' zoophilia',
' Emily',
'']
def Char_Name(self,name):
string1=str(name).lower()
unacceptable_names=open("C://Users//Documents//Unacceptable_Names.txt", "r")
unacceptable_names2=open("C://Users//Documents//Unacceptable_Names.txt", "a")
names_list= []
for line in unacceptable_names.readlines():
for i in line.split(","):
names_list.append(i)
if name.isalpha()==False:
print("You entered a name containing non-alphabetic characters, pease reenter a new name:")
main()
elif len(name)>=10:
print("You entered a name containing 10 or more characters, pease reenter a new name:")
main()
elif string1 in names_list:
print("You entered a name containing bad words or a name already in use! Try again.")
main()
else:
unacceptable_names2.write(',' + str(name) ) # <-------
unacceptable_names2.close()
self.character_name=name
or you can change last else into:
else:
unacceptable_names2.write('\n' + str(name) + '\n')
unacceptable_names2.close()
self.character_name=name
You should also make sure to exact match names. If you simply match in python, it can confuse one name to be other. Example,there are two users with similar user names example:
1) Megan
2) Megan2015.
In a simple match case: if you search for Megan, python may find Megan2015 and say it has found it, since "Megan" in "Megan2015"
def exact_match(phrase, word):
import re
b = r'(\s|^|$)'
res = re.match(b + word + b, phrase, flags=re.IGNORECASE)
return bool(res) # returns true or false
def Char_Name(self,name):
string1=str(name).lower()
unacceptable_names=open("C://Users//Documents//Unacceptable_Names.txt", "r")
unacceptable_names2=open("C://Users//Documents//Unacceptable_Names.txt","a")
names_list= []
for line in unacceptable_names.readlines():
for i in line.split(","):
names_list.append(i)
if name.isalpha()==False:
print("You entered a name containing non-alphabetic characters, please reenter a new name:")
main()
elif len(name)>=10:
print("You entered a name containing 10 or more characters, pease reenter a new name:")
main()
elif:
for n in range(0,len(names_list)):
if exact_match(string1, names_list[n]) == True:
print("You entered a name containing bad words or a name already in use! Try again.")
main()
else:
unacceptable_names2.write(str(name + " , ") )
unacceptable_names2.close()
self.character_name=name
You should write each name on separate lines and you won't need to aplit at all, make a set of the names when you open the file and use a+ to open once for reading and appending:
def Char_Name(self,name):
string1 = name.lower()
with open("C://Users//Documents//Unacceptable_Names.txt", "a+") as f:
unacceptable_names = set(line.rstrip() for line in f)
if not name.isalpha():
print("You entered a name containing non-alphabetic characters, please re-enter a new name:")
main()
elif len(name) >= 10:
print("You entered a name containing 10 or more characters, please re-enter a new name:")
main()
elif string1 in unacceptable_names:
print("You entered a name containing bad words or a name already in use! Try again.")
main()
f.write("{}\n".format(name))
self.character_name = name
It might be a better idea to use pickle to store a set of names.
I would also use a while loop asking the user for their name in the loop instead of repeatedly calling main.
def Char_Name(self):
with open("C://Users//Documents//Unacceptable_Names.txt", "a+") as f:
unacceptable_names = set(line.rstrip() for line in f)
while True:
name = input("Please enter your username")
_name = name.lower()
if _name in unacceptable_names:
print("You entered a name containing bad words or a name already in use! Try again.")
elif _name.isalpha():
print("You entered a name containing non-alphabetic characters, please re-enter a new name:")
elif len(name) >= 10:
print("You entered a name containing 10 or more characters, please re-enter a new name:")
else:
break
f.write("{}\n".format(name))
self.character_name = name
There is no need to ever use readlines unless you actually want a list, if you are going to build a container of names then a set is the most efficient way to check for membership.

Alphabet check as input

Hi I just start learning python today and get to apply what I learning on a flash cards program, I want to ask the user for their name, and only accept alphabet without numbers or symbols, I've tried several ways but there is something I am missing in my attempts. Here is what I did so far.
yname = raw_input('Your Name ?: ')
if yname.isdigit():
print ('{0}, can\'t be your name!'.format(yname))
print "Please use alphbetic characters only!."
yname = raw_input("Enter your name:?")
print "Welcome %s !" %yname
but I figured in this one is if the user input any character more than one time it will eventually continue...So I did this instead.
yname = raw_input("EnterName").isalpha()
while yname == True:
if yname == yname.isalpha():
print "Welcome %s " %(yname)
else:
if yname == yname.isdigit():
print ("Name must be alphabetical only!")
yname = raw_input('Enter Name:').isalpha()
This while loop goes on forever, as well as I tried (-) and (+) the raw input variable as I've seen in some tutorials. So I thought of using while loop.
name = raw_input("your name"):
while True:
if name > 0 and name.isalpha():
print "Hi %s " %name
elif name < 0 and name.isdigit():
print "Name must be Alphabet characters only!"
try:
name != name.isalpha():
except (ValueError):
print "Something went wrong"
This will check for both alphabet in the raw_input and check for the length of the name as I see you tried to do in your last try.
import string
import re
name = re.compile(r'[a-zA-Z]+') #This will check for alphabet.
yname = raw_input("Your Name:") #ask the user for input.
while not name.match(yname):
print "invalid characters"
yname = raw_input("Your Name:")
if 5<=len(yname)<=10:
print "Hi,", yname, "!"
elif len(yname)>10:
print "too long!"
elif len(yname)<5:
print "too short!"
You can rearrange your last attempt a bit to get what you want:
while True:
name = raw_input("your name") # ask inside the loop
if name and name.isalpha():
print "Hi %s " %name
break # leave the loop if done
elif name and name.isdigit():
print "Name must be Alphabet characters only!"
else:
print "Please enter something"
Note that if name will be True if name != "".
name = raw_input('Enter your name: ')
while not name.isalpha():
print 'Invaid characters in name'
name = raw_input('Enter your name: ')
Use regexes:
import re
regex = re.compile("^[a-zA-Z]+$")
valid_name = False
while not valid_name:
user_name = raw_input("EnterName")
if not regex.search(user_name):
print "this can't be your name"
else:
print "Hi there, {0}".format(user_name)
valid_name = True
Also, please take note that programmers often make false assumptions about human names
Edit: as an alternative you can skip compiling a regex and just use the pattern in place:
if not re.search("^[a-zA-Z]+$", user_name):
...
However, since you're doing it in a loop compiled version would have slightly better performance, since re.search actually compiles a regex behind the scenes each time invoked.
Also, please note I've changed match to search and slightly modified a regex since there're some differences and it appears tome me that search suits your situation more.

How can I let the users of my python hangman game input their own words?

I have been stuck on this for a while now and I can't figure out what to do. I know that it will probably involve creating an empty list and then adding the words to the list but I haven't got a clue when it comes to retrieving the words as I have never done this before.
the code itself works, it's just adding this new function I'm having trouble with.
import random
import sys
#importing both random and time modules
print("Hello!")
playAgn = 'yes'
animalNames = ['wildebeest','wolverine','woodlouse','woodpecker','yak','zebra']
#this is the list of words that the user will have to guess if they play the game multiple times
while playAgn == 'yes':
secretWord = random.choice(animalNames)
#this line tells the computer to randomly select one of the words in the list "animalNames"
lives = 6
#Defining how many lives the user has
guessedletters = []
print("Okay!\n Lets play hangman!!")
while lives > 0:
inword = False
#user has not guessed word yet so the boolean value is automatically off (False)
print("you have",lives, "lives")
#tells the user how many lives they have left
guessedletter = input("Guess a letter: ")
if len(guessedletter) > 1:
print("Error! Please only enter 1 letter at a time")
#if the user tries to guess something longer than 1 character the computer displays a message asking to only enter 1 letter at a time
elif guessedletter in guessedletters:
print("Sorry, you have already guessed this letter. Try again")
#if the user tries to guess a letter that has already been guessed the computer displays a message telling the user to choose another letter as they have already chose this one
else:
guessedletters+=str(guessedletter)
#adds the guessed letter to guessedletters variable
print("You have guessed:")
for letter in guessedletters:
print(letter.upper(),"")
#prints the letters already guessed in uppercase
shownword = ""
for letter in secretWord:
if letter in guessedletters:
shownword +=str(letter)
#if the letter is in guessedletters then add the letter to shownword(word displayed to user)
if letter == guessedletter:
inword = True
#inword is true as the guessed letter is in the secret word
else:
shownword+=str("_")
#the computer is now adding the underscores too the word being displayed to the user
print(shownword)
#the computer prints the word with the letters that the user has guessed so far (word including underscores for not yet guessed characters)
if "_" not in shownword:
print("Congratulations, you won! The word was '", shownword,"'")
#if there are no underscores(meaning the word is completed) tell the user they have won the game
break
elif inword == False:
#the guessed word is not in the secret word so the boolean value is now off (False)
print("No luck," , guessedletter , "is not in my word")
lives -= 1
#deducts a life for the wrong letter being guessed and also displays a message telling the user that the letter just guessed isn't in the secret word
if lives == 0:
print("You have run out of lives. The word was '",secretWord,"'")
#if the user runs out of lives and still hasn't guessed the word, tell them they failed to beat the game and also tell them the word
while True:
playAgn = input("Would you like to play again? yes/no: ")
if playAgn == 'no':
print("okay\n Goodbye!")
break
elif playAgn == 'yes':
break
thanks a lot to anyone who can help figure this out :)
You could just swap this:
animalNames = ['wildebeest','wolverine','woodlouse','woodpecker','yak','zebra']
For this:
animalNames = getNames()
And define the function:
def getNames():
names = []
while True:
name = raw_input("Add a word to the list (or press enter to cancel): ")
if name == "":
break
else:
names.append(name)
return names
Look at this line:
animal_names.append(input("Enter Word To Word Pool:"))
like that?

While loop initiating when I dont want it to

I'm going over the formatting of the while loop and I remain unsure (I'm a beginner- forgive me) of how I can go about fixing this. Any assistance would be greatly appreciated! I do not want the 'Sorry that's not it' message to pop up when the user asks for a hint- and yet it persists in doing just that.
# Word Jumble
#
# The computer picks a random word and then "jumbles" it
# The player has to guess the original word
import random
# create a sequence of words to choose from
WORDS = ("python", "jumble", "easy", "difficult", "answer", "xylophone")
# pick one word randomly from the sequence
word = random.choice(WORDS)
hint = ''
if word == 'python':
hint = 'snake'
if word == 'jumble':
hint = 'jumble'
if word == 'easy':
hint = 'opposite of hard'
if word == 'difficult':
hint = 'opposite of easy'
if word == 'answer':
hint = 'question'
if word == 'xylophone':
hint = 'dingding'
# create a variable to use later to see if the guess is correct
correct = word
# create a jumbled version of the word
jumble =""
while word:
position = random.randrange(len(word))
jumble += word[position]
word = word[:position] + word[(position + 1):]
count = 0
# start the game
print(
"""
Welcome to Word Jumble!
Unscramble the letters to make a word.
(Press the enter key at the prompt to quit.)
"""
)
print("The jumble is:", jumble)
guess = input("\nYour guess: ")
while guess != correct and guess != "":
print("Sorry, that's not it.")
count += 1
hint_input = input('would you like a hint')
if hint_input == 'y':
print(hint)
else:
guess = input("Your guess: ")
if guess == correct:
print("That's it! You guessed it!\n")
print("Thanks for playing.")
input("\n\nPress the enter key to exit.")
Remove the else: since you always wish to get a new guess from the user, regardless of if they've received a hint.
if hint_input == 'y':
print(hint)
guess = input("Your guess: ")
Your code works fine - but you are expected to enter a string including the " or ' in the input field. So enter "jumble" and not just jumble or "y" and not just y.
(well, there is some strange logic in there, e.g. after giving a hint it asks once more whether you want a hint - jus remove the else to get rid of this behaviour) but at least it works...)
I've copied your code and ran it.
I changed input to raw_input, which makes input much nicer.
Removed else: after print(hint) , which should fix your problem.
Lastly, I've added extra space after "Would you like a hint? " - makes it a bit easier to read.
# Word Jumble
#
# The computer picks a random word and then "jumbles" it
# The player has to guess the original word
import random
# create a sequence of words to choose from
WORDS = ("python", "jumble", "easy", "difficult", "answer", "xylophone")
# pick one word randomly from the sequence
word = random.choice(WORDS)
hint = ''
if word == 'python':
hint = 'snake'
if word == 'jumble':
hint = 'jumble'
if word == 'easy':
hint = 'opposite of hard'
if word == 'difficult':
hint = 'opposite of easy'
if word == 'answer':
hint = 'question'
if word == 'xylophone':
hint = 'dingding'
# create a variable to use later to see if the guess is correct
correct = word
# create a jumbled version of the word
jumble =""
while word:
position = random.randrange(len(word))
jumble += word[position]
word = word[:position] + word[(position + 1):]
count = 0
# start the game
print(
"""
Welcome to Word Jumble!
Unscramble the letters to make a word.
(Press the enter key at the prompt to quit.)
"""
)
print("The jumble is:", jumble)
guess = raw_input("\nYour guess: ")
while guess != correct and guess != "":
print("Sorry, that's not it.")
count += 1
hint_input = raw_input('would you like a hint? ')
if hint_input == 'y':
print(hint)
guess = raw_input("Your guess: ")
if guess == correct:
print("That's it! You guessed it!\n")
print("Thanks for playing.")
raw_input("\n\nPress the enter key to exit.")

Categories