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.
Related
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 != " "]))
I am making a program which has a login; it checks the input against the user's input. However, it won't accept that they have entered the correct password, even when it is correct:
for i in range(5):
existingUsername = input("What is your user name?")
if existingUsername in open('logins.txt').read():
with open("logins.txt", "r") as myFile:
for num, line in enumerate(myFile, 1):
if existingUsername in line:
passwordLine = num + 1
passwordAttempt = input(str("What is your password?"))
passwordText = linecache.getline("logins.txt", passwordLine)
if passwordAttempt == passwordText:
print("That is correct")
quizSelection()
break
else:
print("That doesn't seem to match. Please try again")
The text file it references only has Har16 and Google in it, on separate lines with Har16 at the top
When you run passwordText = linecache.getline("logins.txt", passwordLine), if your file has multiple lines, it may return the string with \n at the end.
When I run the program it asks for my input multiple times even after I've entered it once already.
Peeps = {"Juan":244, "Jayne":433, "Susan":751}
Asks the user to input a name which is the key to a value, which it returns
for i in Peeps:
if i == input("Type in a name: "):
print("The amount", [i], "owes is:", "$" + str(Peeps[i]))
break
else:
print("Sorry that name does not exist, please enter a new name.")
You need to ask the user input first instead of comparing the user input directly to the key.
You do not want to do it like that. Take a look at the following instead:
Peeps = {"Juan":244, "Jayne":433, "Susan":751}
name = input("Type in a name: ")
if name in Peeps:
print("The amount", name, "owes is:", "$" + str(Peeps[name]))
else:
print("Sorry that name does not exist, please enter a new name.")
You do not have to loop through your dict and check the user input against each value individually (plus you are forcing the user to update\re-enter his input continuously).
Just receive it once and process it.
If you want to keep the loop running to allow for multiple queries, use while like so:
Peeps = {"Juan": 244, "Jayne": 433, "Susan": 751}
name = input("Type in a name or leave blank to exit: ")
while name:
if name in Peeps:
print("The amount", name, "owes is:", "$" + str(Peeps[name]))
else:
print("Sorry that name does not exist, please enter a new name.")
name = input("Type in a name or leave blank to exit: ")
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.
Alright, so I defined a function where the user can input his/her name. I want to make it so that the user is not allowed to input a number like "69" for his/her name. How would I go about doing this? Here is the code I used:
def name():
while True:
name = input("What is your name? "))
try:
return str(name)
break
except TypeError:
print("Make sure to enter your actual name.")
You can use isalpha() to check name:
Return true if all characters in the string are alphabetic and there
is at least one character, false otherwise.
>>> "69".isalpha()
False
>>> "test".isalpha()
True
Here's your code with modifications:
while True:
name = input("What is your name? ")
if name.isalpha():
break
else:
print("Make sure to enter your actual name.")
continue
Or:
name = input("What is your name? ")
while not name.isalpha():
print("Make sure to enter your actual name.")
name = input("What is your name? ")
You can use str.isdigit() method to check if the string contains just digits:
name = input("What is your name? ")
while name.isdigit():
print("Make sure to enter your actual name.")
name = input("What is your name? ")
Note that this will allow names like - "Rohit1234". If you just want to allow alphabetic characters, then you can use str.isalpha() method instead.
Invert your logic:
while True:
name = ...
try:
int(name)
print "Name can't be a number."
except TypeError:
return str(name)
Mind you, this will accept any input that is not a valid integer, including 123abc or so.