I'm writing a quiz code for school. The code iterates over a text file and loads the questions and answers from it. The user will select a difficulty to do the quiz on. The number of options for answers will vary depending on the difficulty. I have split each question and possible answer in the text file with commas.
from random import shuffle
file = open("maths.txt" , "r")
for line in file:
question = line.split(",")
print(question[0])
if difficulty in ("e", "E"):
options = (question[1], question[2])
if difficulty in ("m", "M"):
options = (question[1], question[2], question[3])
if difficulty in("h", "H"):
options = (question[1], question[2], question[3], question[4])
options = list(options)
shuffle(options)
print(options)
answer = input("Please enter answer: ")
if answer in (question[1]):
print("Correct!")
else:
print("incorrect")
file.close()
This is what a line of the text file would look like:
Question 1. What is 4+5?,9,10,20,11
The first option (question[1]) will always be the correct answer, therefore I would like to shuffle the options. With this code the options are outputted with square brackets, newline characters and quotation marks. Does anyone know how I can strip these? I tried to use: line.split(",").strip() however this seemed to do nothing at all. Thanks
The problem is that you are trying to print a list object. Instead, you should print each option. you'd probably be better printing some formatting around it:
for option_num, option in enumerate(options):
print("{} - {}").format(option_num, option)
please read about enumerate and format to understand exactly what happens here
Something like this?
from random import shuffle
def maths_questions():
file = open("maths.txt" , "r")
for line in file:
question = line.strip().split(",") # every line in file contains newline. add str.strip() to remove it
print(question[0])
if difficulty in ("e","E"):
options = [question[1],question[2]]
elif difficulty in ("m","M"):
options = [question[1],question[2],question[3]]
elif difficulty in("h","H"):
options = [question[1],question[2],question[3],question[4]]
# why to create tuple and then convert to list? create list directly
shuffle(options) #shuffle list
print("Options: ", ", ".join(options)) # will print "Options: opt1, opt2, opt3" for M difficulty
answer=input("Please enter answer: ")
if answer in (question[1]):
print("Correct!")
else:
print("Incorrect, please try again...")
file.close()
Python docs:
str.join(iterable)
Return a string which is the concatenation of the strings in iterable. A TypeError will be raised if there are any non-string values in iterable, including bytes objects. The separator between elements is the string providing this method.
for option in options:
print(option)
To remove characters from a string, use .rstrip("put text to remove here") to remove characters from the right end of the string and .lstrip("text to remove") to remove characters from the left of the string.
Related
how do i find a string or a list in a text file. If i have a text file filled with words only, random words, not sentences, how do i find a string inside it. lets say I take a user input, how do I test or check if the string input by the user exist in the text file.
so far i have this:
x = open('sample.txt')
for a in x:
b = a.split() #converts the string from the txt to a list
c = input('enter: ') #user input
if any(c in a for a in b):
print('yes')
want to make a simple spellchecker. so from the user input string i want to check if that string matches the strings/list in the txt file
You mean, how to find a word in this file? That's
with open("sample.txt") as input:
dictionary = set(input.read().split())
then
w in dictionary
for your word w.
You asked three related but different questions:
1. "how do i find a string or a list in a text file."
text = input('enter: ')
data = open("sample.txt").read()
position = data.find(text)
if position != -1:
print("Found at position", position)
else:
print("Not found")
2. "how do I test or check if the string input by the user exist in the text file"
text = input('enter: ')
data = open("sample.txt").read()
if text in data:
print("Found")
else:
print("Not found")
3. "I want to make a simple spellchecker. so from the user input string i want to check if that string matches the strings/list in the txt file"
Make a dictionary like this, globally in a module:
dictionary = open("sample.txt").read().split()
Then you use the dictionary by importing it:
from themodule import dictionary
And you check if a word is in the dictionary like so:
'word' in dictionary
I am looking to make a program that can pick out car information from a file using module re. The user is asked questions about the car that he wants to view and if the input is not in the file I should display an error message and loop the code again if the user wants to. I am having difficulty trying to find the inputs in the file: this is the code so far:
import re
import random
myList = ([])
car = input("What car do you want to view?");
myList.insert(1, car)
model = input("What car model is it of");
myList.insert(2, model)
fuelTy = input("What fuel type is it: diseal or petrol");
myList.insert(3, fuelTy)
engSize = input("What engine size is it : eg 2l");
myList.insert(4, engSize)
rnd = (int(random.randrange(50000000)) + 1)
with open("car.txt", "r") as carfile:
for line in carfile:
if all(myList.lower() in re.findall('\w+', line.lower()) for myList in carfile):
splitted_line = line.split(':')
print(splitted_line)
if not myList not in carfile:
print("We don't have the car available currently. Please contact the head office with the case number " + str(rnd))
Cho2 = input("Would you like to see anything yes or no").lower
if Cho2 == "yes":
print("OK")
elif Cho2 == "no":
print("End of program")
Text file is:
bmw : X6 : 3.4l : Engine size 4395cc: petrol: 0-62mph in 4.8s: gear type automatic : 5 doors : economy 29mpg : top speed 155 mph
audi : Q7 : 3.0l : Engine size 2967cc: disel: 0-62mph in 6.5s: gear type automatic : 5 doors : economy: 48mpg : top speed 145 mph
honda : CRV : 2.0l: Engine size 1997cc: petrol : 0-62mph in 10.0s: gear type manual : 5 doors : economy 30mpg : top speed 18 mph
if all(myList.lower() in re.findall('\w+', line.lower()) for myList in carfile):
In this line, you are re-defining myList to be a line in the file. But you have an outer loop (for line in carfile) that does the same thing.
Change this to eliminate the for expression, and you'll be on the right track:
if all(myList.lower() in re.findall('\w+', line.lower())):
FWIW, this is going to be very hit-or-miss, because you have things like engine size that use different measures (cc vs. l) in the file.
Next, please be aware that you can (and probably should, as a matter of avoiding errors) use .append() in order to grow a list, instead of .insert(). The difference is that append does not require you to keep track of an index, which in cases like this is not benefiting you (you don't make use of the position information at any time) and is a source of error if you copy/paste a block of code to add a new field.
myList.append(engSize) # was myList.insert(4, engSize)
Also, you should probably give users the option of not entering a field, and skip searching if they don't enter it. (Just don't append the field if it's empty, perhaps?)
engSize = input("What engine size is it : eg 2l")
if engSize: myList.append(engSize)
EDIT
Okay, just got done for the day, back to this program. :-)
There are some more problems, but let's take care of the "all requires an iterableissue first. If you look at the docs for [all`](https://docs.python.org/3/library/functions.html#all), it says
all(iterable)
So we need to restructure the test to give all an iterable (a list, tuple, view, or other expression that can be iterated), or we need to stop using all.
Well, we are trying to iterate over myList, so it should be possible to come up with an iterable. Let's start with that in mind:
if all(s for s in myList):
In fact, we can put the .lower() back in - that made sense. So:
if all(s.lower() for s in myList):
Now, let's treat s.lower() as a word (which it is) and search for it in the input line. What we are doing is converting our previous string expression, s.lower(), into a boolean expression: word in list, within the context of the iteration we already have. This will be a different flavor of the in keyword:
if all( (EXPR) for s in myList):
if all((s.lower() in re.findall('\w+', line.lower())) for s in myList):
When I make this change, I can match the make of the car.
There are some problems with the logic, as well. You want to match the user query to a car type. If you can't match that, then you want to print a message about "We don't have the car ..." But you can't get that test (not matching) in one line. If you could get that test into one line, you could probably get the searching part into one line as well. (Not always, but it's worth looking!)
Instead, just keep track of whether or not you found the car:
found_car = False
for line in carfile:
if ...
found_car = True
break
if not found_car:
print("We don't have the car ...")
Next, let's make the program run longer (for testing if nothing else). You are doing for loops, so I assume you can do a while loop. Let's add a loop around the whole thing to keep going until the user types quit:
while True:
make = input("What make of car do you want (or type 'quit')? ")
if make == 'quit':
break
if make:
myList.append(make)
Finally, let's take a look at your regular expression. You are using \w+, which will match "word characters" (whatever those are) one or more times.
That's a good start for things like "audi" and "honda", but word characters don't include the period ('.') or the hyphen ('-'), both of which appear in your data.
Instead, try changing your regex to match either a word character or a dot, one or more times:
re.findall('[\w.]+', ...)
Good luck!
You have bugs!
First, you are initializing myList = ([]) as a tuple containing a single empty list, so append() or insert() aren't going to work. Try myList = [].
Second, you're getting the indexes wrong in your myList.insert(...) statements. Just use myList.append(...) instead, no need to worry about indexes that way.
Then, try replacing (not tested...):
if all(myList.lower() in re.findall('\w+', line.lower()) for myList in carfile):
... with:
if all (item.lower() in re.findall('\w+', line.lower()) for item in myList):
A simple optimization which also makes the code more readable:
line_words = set(re.findall('\w+', line.lower()))
if all(item.lower() in line_words for item in myList):
I'm attempting to create a program which selects 10 words from a text file which contains 10+ words. For the purpose of the program when importing these 10 words from the text file, I must not import the same words twice! Currently I'm utilising a list for this however the same words seem to appear. I have some knowledge of sets and know they cannot hold the same value twice. As of now I'm clueless on how to solve this any help would be much appreciated. THANKS!
please find relevant code below! -(p.s. FileSelection is basically open file dialog)
def GameStage03_E():
global WordList
if WrdCount >= 10:
WordList = []
for n in range(0,10):
FileLines = open(FileSelection).read().splitlines()
RandWrd = random.choice(FileLines)
WordList.append(RandWrd)
SelectButton.destroy()
GameStage01Button.destroy()
GameStage04_E()
elif WrdCount <= 10:
tkinter.messagebox.showinfo("ERROR", " Insufficient Amount Of Words Within Your Text File! ")
Make WordList a set:
WordList = set()
Then update that set instead of appending:
WordList.update(set([RandWrd]))
Of course WordList would be a bad name for a set.
There are a few other problems though:
Don't use uppercase names for variables and functions (follow PEP8)
What happens if you draw the same word twice in your loop? There is no guarantee that WordList will contain 10 items after the loop completes, if words may appear multiple times.
The latter might be addressed by changing your loop to:
while len(WordList) < 10:
FileLines = open(FileSelection).read().splitlines()
RandWrd = random.choice(FileLines)
WordList.update(set([RandWrd]))
You would have to account for the case that there don't exist 10 distinct words after all, though.
Even then the loop would still be quite inefficient as you might draw the same word over and over and over again with random.choice(FileLines). But maybe you can base something useful off of that.
not sure i understand you right, but ehehe,
line 3: "if wrdcount" . . where dit you give wrdcount a value ?
Maybe you intent something along the line below?:
wordset = {}
wrdcount = len(wordset)
while wrdcount < 10:
# do some work to update the setcode here
# when end-of-file break
the text file looks like: textabbrv.txt
r:are
u:you
ttyl:talk to you later
l8:late
brb:be right back
i tried a lot to fix this, but there is one error, my program is:
def main():
indexEntries={}
infile=open('textabbrv.txt','r')
fields=extractRecord(infile)
while len(fields)>0:
set_entries(indexEntries,fields[1],fields[0])
fields=extractRecord(infile)
infile.close()
printIndex(indexEntries)
def extractRecord(infile):
line=infile.readline()
if line!="":
fields=line.split(":")
page=fields[0].rstrip()
term=fields[1].rstrip()
return [page,term]
else:
return []
def set_entries(entries,term,page):
pageSet=set([page])
entries[term]=pageSet
def printIndex(entries):
user_input=input("Enter a message to be translated: \n")
if user_input!=" ":
user_split=user_input.replace(","," ").replace("?"," ").replace("!"," ").\
replace(":"," ").replace(";"," ").split(" ")
print()
print("The translated text is: ")
for long_form in entries:
sentence=entries[long_form]
for short_form in sentence:
if short_form in user_split:
print(user_input.replace(short_form,long_form))
main()
OUTPUT:
Enter a message to be translated:
ttyl,brb
The translated text is:
talk to you later,brb
ttyl,be right back
but the output should look like this and should be translated in just one line, i think i messed up somewhere in the for loops a the end of the program
Enter a message to be translated:
ttyl,brb
The translated text is:
talk to you later,be right back
First of all, the output you see is due to this:
print(user_input.replace(short_form,long_form))
Whenever you find a match, you replace that match in the original user input, and print it out, but you don't store that modified version of the original input at all.
You could fix that by doing:
user_input = user_input.replace(short_form,long_form)
and then printing the new version of user_input at the end of printIndex. Now, that may be problematic, but that's another story.
In any case... the way you have approached this is a bit unusual. You are populating the indexEntries dictionary in the reverse way that I would expect. You put the indices as the values! Instead:
1) I would import csv and rewrite this:
infile=open('textabbrv.txt','r')
fields=extractRecord(infile)
while len(fields)>0:
set_entries(indexEntries,fields[1],fields[0])
fields=extractRecord(infile)
infile.close()
as:
with open('textabbrv.txt','r') as infile:
for (field1, field2) in csv.reader(infile, delimiter=':'):
indexEntries[field1] = field2
In the process I'm getting rid of extractRecord and set_entries. Now the dictionary looks like {'brb': 'be right back', 'r': 'are, ...}
2) You're splitting the user input, but then you don't make use of that. Let's rewrite this:
for long_form in entries:
sentence=entries[long_form]
for short_form in sentence:
if short_form in user_split:
print(user_input.replace(short_form,long_form))
and make it:
output = []
for word in user_split:
# The following could be written as
# output.append(entries.get(word, word))
if word in entries:
output.append(entries[word])
else:
output.append(word)
print ','.join(output)
I need a bit of help with this assignment (first time posting on SE so please excuse my lack of posting etiquette if any)
So for this code I had to write a spell checker. Basically what it is supposed to do is:
1.) Check through two lists (One is a dictionary, where we get all the correctly spelled words, the other is the user input list which should have an incorrectly spelled word or two)
2.) suggest a correct word in place of the misspelled word (example would be if I spelled heloo, the spell checker would say i spelled that wrong and would suggest the word is hello, help, etc.)
My biggest problem right now is at line 19, I am getting the list indices must be integers problem.
Any help is appreciated, and help with finishing this would also be much appreciated! I feel like outside of the syntax more could be improved upon. Thanks.
here is the code, it is not completely finished
import re
def words_from_file(filename):
try:
f = open(filename, "r")
words = re.split(r"[,.;:?\s]+", f.read())
f.close()
return [word for word in words if word]
except IOError:
print("Error opening %s for reading. Quitting" % (filename))
exit()
user_word = words_from_file('user_word.txt')
suggestion = words_from_file('big_word_list.txt')
sug_list = []
for a in user_word:
if user_word[a] not in suggestion:
print ("Spelling error: %s"%(user_word[a]))
for i in suggestion:
for j in suggestion[i]:
if len(suggestion[i][j]) == len(user_word[a]-2):
count = 0
similarities = len(user_word[a])
for k in suggestion[i][j]:
if suggestion[i][j][k] in suggestion:
count+=1
if count >= similarities:
sug_list.append(suggestion[i][j])
Change:
for a in user_word:
if user_word[a] not in suggestion:
Into:
for a in user_word:
if a not in suggestion:
because all items in user_word list will be iterated using the a variable. The a will in each iteration contain a nonempty string obtained from the line split. You can only use numerical index with a list type. Originally you've used a string in place of numeric index which causes the error message.
List can slice using integers not str
Change
if user_word[a] not in suggestion: #to==> if a not in suggestion:
for j in suggestion[i]: #to==> for j in i
for k in suggestion[i][j]: #to==> for k in j
Also many errors slice errors like suggestion[i][j][k] etc
So generally
for i in [1,2,3]:
print(i) # gives 1,2,3.No need of [1,2,3][i]
Also, you can use range(len)
for a in range(len(user_word)):
if user_word[a] not in suggestion: