So I'm doing my homework but I can't seem to figure out how to add "extra" characters to regular statement.
I want this code to say that lname have to consist only from letters and " " or/and "-" symbols and can't start with " ". How can I achieve this? I don't even know what to search for or try. Isn't there some kind of “includes” function built in? I'm getting desperate.
def perenimi2():
global lname
lname = perenimi.get()
if lname.isalpha():
textVar.set("")
nd2 = {"Perenimi": str(lname)}
uusklient.update(nd2)
post2()
else:
textVar.set ("Sisestage korrektne perekonnanimi!")
What I mean is how can I make IF statement that MUST include letters and may also include "-" or/and space. I want to make fname to be only letters and "-" or/and space. (This is for a name field which also can't start with space)
I'm sorry if this has been asked before but I haven't been able to find the solution.
-----CODE AFTER USING POSTED ANSWER-----
With the posted answer I found a new problem, it now allows input or entry to be empty which can't be empty.
I translated everything to English.
import string
###FirstName
def firstname1():
global fname
allowed = " -"
cantStart = " "
fname = firstname.get()
if (set(fname) <= set(allowed + string.ascii_letters) and not fname.startswith(cantStart)):
textVar.set("")
familyname2()
elif fname == "":
textVar.set("Insert correct name!")
else:
textVar.set("Insert correct name!")
###FamilyName
def familyname2():
global lname
lname = familyname2.get()
allowed = " -"
cantStart = " "
empty = ""
if (set(lname) <= set(allowed + string.ascii_letters) and not lname.startswith(cantStart)):
textVar.set("")
post2()
elif lname == "":
textVar.set("Insert correct family name!")
else:
textVar.set("Insert correct family name!")
firstname1()
import string
ALLOWED = " -"
CANT_START = " "
if (set(lname) <= set(ALLOWED + string.ascii_letters)
and not lname.startswith(CANT_START)
and lname):
No elif branch (i.e. remove it from your code).
The explanation:
string.ascii_letters is "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
set(lname) is the set of all characters in lname, e. g. if lname == "abba", then set(lname) will be "ab".
The <= operation between two sets means “is a subset of”, i.e. if all elements in the left set exist in the right set, too.
lname is True only for nonempty strings (you may also use lname != "", but using only lname is more Pythonic).
The long expression in the if branch is surrounded with parentheses only for the possibility to split it freely into more lines, i.e. without the necessity to end every non-complete line with the continuation symbol (\). Otherwise, it has to be in the form as
if set(lname) <= set(ALLOWED + string.ascii_letters) \
and not lname.startswith(CANT_START) \
and lname:
(or be written fully only in one, very long line).
Related
I'm new to programming and trying to make a vocabulary test machine in python, and the problem I'm having is when you're restarting the test and trying to redo the wrong answers, the correct answers being inputted should be removed from the list which contains the wrong answers.
So basically, in beginning you are putting in custom vocabulary words and then answering them, if any words are incorrect they are put in a list, and when redoing the test, if they are correct this time they should be removed from the list. So at the end if you are answering the words correctly the list should be empty. But I am getting this error: IndexError: list index out of range
What do you suggest I should do?
(I translated the code from another language so if anything is not matching that's the reason)
import replit, sys, time, os
word = []
word1 = []
wordwrong = []
wordwrong1 = []
incorrect = 0
correct = 0
swedish = ""
print("Type: 'Stop' to stop")
while swedish.lower() != "stop":
swedish = input("\nType the word in swedish:")
if swedish.lower() != "stop":
word.append(swedish)
else:
replit.clear()
break
english = input("\nType the word in english:")
word1.append(english)
replit.clear()
print("Type: 'Stop' to stop")
for x in range(len(word)):
wordanswer = input("translate word " + "'" + word[x] + "'" + ":").lower()
replit.clear()
while wordanswer != word1[x]:
print("Incorrect answer! try again, " + str(2-incorrect) + " tries left")
wordanswer = input("translate " + "'" + word[x] + "'" + ":")
incorrect = incorrect + 1
replit.clear()
if incorrect == 2:
replit.clear()
incorrect = incorrect-2
wordwrong.append(word[x])
wordwrong1.append(word1[x])
break
else:
print("Correct answer!")
correct = correct + 1
incorrect = incorrect*0
replit.clear()
print("Your result:", correct, "/", len(word), "correct answers " +"(" + str(correct/len(word)*100)+"%)")
restart = input("\nTo restart; type 'restart':").lower()
correct = correct*0
incorrect = incorrect*0
restart = "restart"
while restart == "restart" and len(wordwrong) > 0:
for x in range(len(wordwrong)):
wordanswer = input("translate word " + "'" + wordwrong[x] + "'" + ":").lower()
while wordanswer != wordwrong[x]:
print("Incorrect answer! try again, " + str(2-incorrect) + " tries left")
wordanswer = input("translate word " + "'" + wordwrong[x] + "'" + ":")
incorrect = incorrect + 1
if incorrect == 2:
incorrect = incorrect-2
break
else:
print("Correct answer!")
correct = correct + 1
incorrect = incorrect*0
wordwrong.remove(wordwrong[x])
wordwrong1.remove(wordwrong1[x]) (here i am trying to remove the words that got corrected)
print("Your result:", correct, "/", len(word), "correct answers " +"(" + str(correct/len(word)*100)+"%)")
restart = input("\nTo restart; type 'restart':").lower()
As I can't comment yet:
I think the problem is that this
for x in range(len(wordwrong)):
loop is trying to go through all of the elements of wordwrong in
wordwrong.remove(wordwrong[x])
even though the size of wordwrong is changing and getting smaller each time
a word is removed from the list. I might be wrong though. I'll hope this helps you.
One immediate suggestion is that you're inputting Swedish words and their English equivalent, and then storing these in separate parallel lists. This is not wrong, per se, but frequently troublesome. You could store them as a list of tuples, or even better as a dictionary.
words = {}
while True:
print("Type: 'Stop' to stop")
swedish = input("Enter Swedish word: ")
if swedish.lower() == "stop": break
english = input("Enter English equivalent: ")
words[swedish] = english
Now, if you want to iterate over all of the Swedish words and their English equivalents:
for swedish, english in words.items():
...
If the user gets two attempts for each translation, and you want to track how many they translate correctly:
correct = 0
attempts = 2
for swedish, english in words.items():
correct_translation = False
for attempt in range(attempts):
translation = input(f"Translate Swedish word {swedish} to English: ")
if translation.lower() == english.lower():
correct_translation = True
break
elif attempt == attempts - 1:
print("Incorrect.")
else:
print("Incorrect. Try again.")
if correct_translation: correct += 1
This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
How to validate person names? - Python/Django
(4 answers)
Closed 4 years ago.
I am at the part where I ask the user for their name. So far I got this:
# Import stuff
import time
# Create empty variable
Name = ""
# Ask their name
while Name = ""
Name = input("What is your name? ")
print("")
print(Name)
print("")
time.sleep(3)
So if the user inputs nothing, it repeats the question. But when the user inputs an integer or a float it registers this as a valid name.
How will I be able to make it so that if the Name variable is an integer or a float, it will respond with "Please enter a valid name" and repeat the question?
I'm updating my answer to simplify the code and make it more readable.
The below function is a function that I would use in my own code, I would consider it to be more "proper" than my old answer.
from string import ascii_letters
def get_name():
name = input("What is your name?\n: ").strip().title()
while not all(letter in ascii_letters + " -" for letter in name):
name = input("Please enter a valid name.\n: ").strip().title()
return name
To break this down, the line all(letter in ascii_letters + " -" for letter in name) means "if each letter in name is not an alphabetical character, a space, or a hyphen".
The part letter in ascii_letters + " -" checks to see if a letter is in the string "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ -".
This is repeated by the next part, for letter in name, for every character in the string. This will effectively return a list of booleans, [True, True, True, ...] where any False is a character that did not pass the conditional. Next, this list is passed to the all() function, which returns True if all of the list items are True.
After the all() is executed, conditional is reversed, allowing the loop to continue on the existence of a single failed character.
Old answer is as follows, it will still be useful.
This function should work well for you. Simply check if the string the user entered is alpha characters only, otherwise ask again.
Notice the use of str.isalpha().
def get_name():
name = input("What is your name?\n: ").strip().title()
while not (name.replace("-", "") and
name.replace("-", "").replace(" ", "").isalpha()):
name = input("Please enter a valid name.\n: ").strip().title()
return name
Checking if name will check if the string is empty, and using str.strip() on the values returned will remove any surrounding whitespace (stray spaces) to the left or right of the user input.
The str.replace("-", "") eliminates hyphens while checking validity. Thanks for pointing this out #AGN Gazer.
Now you can just call the function later in your script, or store it for later.
name = get_name().title()
print("You said your name was " + name + ".)
The str.title() converts the letter of each word in a string to uppercase. For example, if I entered my name "jacob birkett", the output (and subsequent value of name would be "Jacob Birkett".
Take a look at the documentation for str.isalpha(), str.strip(), str.replace() and str.title().
You can try this :
while Name == "" or Name.isnumeric() == True:
Name = input("What is your name? ")
print("")
Here if the Name is any numeric value it will ask again, But if the name is like alphanumeric it will accept.
You can use a function like .isalpha() as this will return True if all the string contains all the alphabets:
while True:
Name = input("Please enter a valid name.\n: ")
if name.isalpha()
break
else:
print("Please enter a valid name.")
continue
print(Name)
Or You can try exception handling in python as (but this should be prevented):
try :
int(Name)
print("Please enter a valid name")
...
except:
print("Accepted")
...
This will check if the input is an integer print the error.
You can try:
This will check if variable Name containing numeric data or not.
import time
Name = ""
while Name == "" :
Name = input("What is your name? ")
if not Name.isalpha():
print "It is containing numberic characher or characters"
Name = ""
print("")
print(Name)
print("")
time.sleep(3)
You also can try if name is like "harsha-biyani":
import time
Name = ""
while Name == "" :
Name = input("What is your name? ")
if any(i.isdigit() for i in Name):
print "It is containing numberic characher or characters"
Name = ""
print("")
print(Name)
print("")
time.sleep(3)
You can use:
Name.isalpha()
"3".isalpha()
False
"anna".isalpha()
True
def add_div(filename, caption):
test = str(filename)
return ('<div><img src=' + test + '><br><p>' + caption + '</p></div>')
def add_body(image_dict, s, order = None):
'''(dict of {str:list of str}, str, list) -> str
If the third parameter is passed, then the filenames
included in the body should only be those in the list and should be added
in the same order as they are listed in the list. '''
new = ''
s = '<html><head></head>'
while order is None:
for (key, value) in image_dict.items():
new += add_div(str(key), str(value[2]))
return (s + '<body><div id="slideshow">' + new + '</body>'+ '</html>')
The output of add_body function is:
how do I get quotation marks around the word images/skater.jpg ?
this is what the file looks like
You have two separate options:
1) Use double quotes
print("Hey that's pretty cool!")
2) Escape the single quotation mark
print('Hey that\'s pretty cool!')
You can include the quotation marks in the string that you are concatenating like this :
def add_div(filename, caption):
test = str(filename)
return ('<div><img src="' + test + '"><br><p>' + caption + '</p></div>')
Use one type of quotation for the string definition and the other for the included quotes:
>>> "bob said: 'hello'"
"bob said: 'hello'"
>>> "I said 'yo bob, how u doing?' in reply"
"I said 'yo bob, how u doing?' in reply"
So to fix your problem, just change the return statement in the first function to:
return ('<div><img src="' + test + '><br><p>'" + caption + '</p></div>')
Note that as a final thing, the parenthesis in the return statement aren't required as return is a not a function or method.
Good answers, but another method is to escape the single or double quotation mark with \
Example:
# this is the same as
# s = "'"
s = '\''
print(s)
#this is the same as
# s = '"'
s = "\""
print(s)
I'm new to StackOverflow (1st time posting) and new to coding with python. Currently enrolled in a course through Udacity. I'm having a very hard time with a project we were given for this course and decided to come here to see if anyone could help.
The project is to create a quiz with 4 blanks that need to be answered correctly by the player. It's required to have the quiz print out with the correct answer, but I'm having a very hard time getting this to print out correctly.
My code is below. Would appreciate any help or advice I can get on this.
Thanks!
easy_quiz = "If you ever get stuck, check out the __1__ for common
problems students face when attempting this project. If you need
additional help, you can schedule a 1:1 appointment with one of our
__2__ to get you un-stuck. This project should be __3__. If at any time
it becomes not fun, take a step back, deep breath, and ask for __4__!.
\n\n"
easy_answers = ["forums", "mentors", "fun", "help"]
medium_quiz = "Game must have 3 or more levels and each level contains 4 or more __1__ to fill in. Immediately after running the program, user is prompted to select a difficulty level from easy / __2__ / hard. Once a level is selected, game displays a fill-in-the-blank and a prompt to fill in the first one. When player guesses __3__, new prompt shows with correct answer in the previous blank and a new prompt for the next blank. When player guesses __4__, they are prompted to try again. \n"
medium_answers = ["blanks", "medium", "correctly", "incorrectly"]
hard_quiz = "__1__ are used as __2__ to automate tasks which are likely to be repeated. Functions produce the appropriate output (typically with a __3__ statement) from the appropriate input (function parameters). Your code should take advantage of __4__ and variable names should reflect the values they store. \n"
hard_answers = ["Functions", "tools", "return", "variables"]
blanks = ["__1__", "__2__", "__3__", "__4__"]
difficulty = raw_input("\nChoose your difficuty level = easy, medium, or hard? ")
print ""
if difficulty == "easy":
quiz = easy_quiz
answers = easy_answers
print "You chose easy!\n\nYou will have 5 guesses to fill in each blank. Good Luck!!\n \n" + easy_quiz
elif difficulty == "medium":
quiz = medium_quiz
answers = medium_answers
print "You chose medium!\n\nYou will have 5 guesses to fill in each blank. Good Luck!!\n \n" + medium_quiz
elif difficulty == "hard":
quiz = hard_quiz
answers = hard_answers
print "You chose hard!\n\nYou will have 5 guesses to fill in each blank. Good Luck!!\n \n" + hard_quiz
def word_in_pos(word, parts_of_speech):
for pos in parts_of_speech:
if pos in word:
return pos
return None
def play_game(quiz, parts_of_speech):
replaced = []
i = 0
quiz = quiz.split()
for word in quiz:
replacement = word_in_pos(word, parts_of_speech)
if replacement != None:
user_input = raw_input("Type an answer for: " + replacement + " " )
word = word.replace(replacement, user_input)
replaced.append(word)
guesses = 0
while user_input != answers[i]:
guesses = guesses + 1
print "Incorrect, try again \n" + " ".join(replaced)
user_input = raw_input("Type an answer for: " + replacement + " ")
if guesses == 4:
return "\nGame Over! Better luck next time. \n"
print "Correct \n" + " ".join(replaced)
i = i + 1
word = word.replace(replacement, user_input)
replaced.append(word)
else:
replaced.append(word)
replaced = " ".join(replaced)
return replaced
print play_game(quiz, blanks)
Here is a working version of your play_game() method:
def play_game(quiz, parts_of_speech):
replaced = []
i = 0
quiz = quiz.split()
for word in quiz:
replacement = word_in_pos(word, parts_of_speech)
if replacement is not None:
user_input = raw_input("Type an answer for: " + replacement + " " )
guesses = 0
while user_input != answers[i]:
guesses = guesses + 1
if guesses == 5:
return "\nGame Over! Better luck next time. \n"
print "Incorrect, try again \n" + " ".join(replaced) + " " + replacement
user_input = raw_input("Type an answer for: " + replacement + " ")
replaced.append(user_input)
print "Correct \n" + " ".join(replaced)
i = i + 1
else:
replaced.append(word)
replaced = " ".join(replaced)
return replaced
The main change is to delay modifying the replaced list until the correct answer has been given. That simplifies a lot of the code, eliminating the need for the word variable.
I am making a Recipe book, at the moment I have the ability to create a recipe, but now I am starting to build the module of searching and displaying stored recipes.
At the moment I have a .txt document with the contents along the lines of:
Williams Special Recipe
Ingredients:
bread: 120 grams
butter: 1234 grams
Recipe Serves: 12
I then ask the user how many they are serving and based on how many the recipe serves, I need to multiply all the ingredients quantity by that number. I then need to print that off with the full recipe again.
I was wondering how I would go about achieving this result, not asking specifically for a coded response as an answer, but I would greatly appreciate how I would approach this task and any specific functions required.
I have also included my code so far, I appreciate the fact it is incredibly un-organised at the moment, and probably hard to understand, but I included it for any reference.
(I have also created a .txt file of all the created recipes which will be implemented later on as a way of displaying to the user all recipes, but at the moment it is just set up for searching.)
#Recipe Task
import os.path
def file_(n):
if n == "listR" :
list_f = open("list_recipes.txt", "a+")
list_f.write(new_name + "\n")
if n == "oar": #open append read
f=open(new_name + ".txt","a+")
elif n == "c": #closes file
f.close()
def print_line(x): #ease of printing multiple lines to break up text
for c in range(x):
print ""
def new_ingredients(): #adding new ingredients
f.write("Ingredients:" + "\n" + "\n")
fin_ingredient = False
while fin_ingredient != True :
input_ingredient = raw_input("New ingredient:" + "\n").lower()
split_ingred = input_ingredient.split()
if input_ingredient == "stop": #stops asking questions when user types 'stop'
fin_ingredient = True
else :
f.write(split_ingred[0] + ":" + " " + split_ingred[1] + " " + split_ingred[2] + "\n")
def search_recipe(n): #searching for recipes
n = n + ".txt"
if os.path.isfile('/Users/wjpreston/Desktop/' + n) == True :
print "Recipe Found..."
found_recipe = open(n)
print found_recipe.read()
append_serving = raw_input("Would you like to change the number of people you are serving?" + "\n").lower()
if append_serving == "yes" :
appended_serving = input("How many would you like to serve?" + "\n")
with open(n) as f: #here is my issue - not sure where to go with this!!
list_recipe = f.readlines()
found_recipe.close()
else :
print "fail"
else:
print "No existing recipes under that name have been found."
print "Welcome to your Recipe Book"
print_line(3)
recipe_phase = raw_input("Are you 'creating' a recipe or 'viewing' an existing one?" + "\n").lower()
if recipe_phase == "creating":
new_name = raw_input("Name of Recipe: " + "\n")
file_("listR")
file_("oar")
f.write("------------" + "\n" + new_name + "\n" + "\n")
print "Ingrediants required in the format 'ingredient quantity unit' - type 'stop' to end process"
new_ingredients()
new_num = input("Number serving: ")
f.write("\n" + "Recipe Serves: " + str(new_num) + "\n" "\n" + "\n")
file_("c")
elif recipe_phase == "viewing":
search = raw_input("Search for recipe: ")
search_recipe(search)
I'm not the specialist in processing strings, but I'd approach your problem following way:
Save each ingredient on a new line.
Split the loaded string by "\n".
Then process the list with some for-loops while creating two dicts, one for the actual data
e.g. {"bread": 4, "butter": 7}
and one for the types of each ingredient:
e.g. {"bread": grams, "butter": grams}
The you should also save how many serves the recipe is written for, and maybe the order of the ingredients (dicts get stored in a random order):
e.g. ["bread", "butter"]
After that, you can ask your costumer how many serves he has and then finally calculate and print the final results.
for ing in ing_order:
print ing+":", ing_amount[ing]*requested_serves/default_seves, ing_types[ing]
...hopyfully you still have enough challange, and hopefully I understood your question correctly.