My name is Seix_Seix, and I have a doubt about a program in Python that I am building.
The thing is, that I'm doing a "riddle game" (silly, right?), to practise some basical Python skills. The intended flow of the program is that you give it a number from 1 to 5, and then it open a file with all the riddles stored in it, and it prints the one in the line of the number you gave.
Afterwards, it asks you for an input, in which you type the answer, and then (this is where all crumbled down) it compares your answer to the corresponding line on another file (where all the answers are).
Here is the code so you can give it a look *(It's in spanish since it's my mother language, but it also has a translation and explanation in the comments)
# -*- coding: cp1252 -*-
f = open ("C:\Users\Public\oo.txt", "r") #This is where all the riddles are stored, each one in a separate line
g = open ("C:\Users\Public\ee.txt", "r") #This is where the answers to the riddles are, each one in the same line as its riddle
ques=f.readlines()
ans=g.readlines()
print "¡Juguemos a las adivinanzas!" #"Lets play a riddle game!"
guess = int(raw_input("Escoge un número entre 1 y 5. O puedes tirar los dados(0) ")) #"Choose a number from 1 to 5, or you can roll the dice (0)" #This is the numerical input, in which you choose the riddle
if guess==0:
import random
raw_input(random.randrange(1, 5))
print (ques[guess-1]) #Here, it prints the line corresponding to the number you gave, minus 1 (because the first line is 0, the second one is 1 and so on)
a=input("¿Sabes qué es?") #"Do you know the answer?" #Here, you are supposed to type the answer to the riddle.
while True:
if a==(ans[guess-1]): #And here, it is supposed to compare the answer you gave with the corresponding line on the answer file (ee.txt).
print "ok" #If you are correct it congratulates you, and breaks the loop.
break
else:
print "no" #If you are wrong, it repeats its question over and over again
And so, I run the program. Everything is fine for a while until the moment when I have to input the answer; there, no matter what I put, even if it's right or wrong, it gives me the next error:
Traceback (most recent call last):
File "C:\Users\[User]\Desktop\lol.py", line 16, in <module>
a=input("¿Sabes qué es?") #"Do you know the answer?" #Here, you are supposed to type the answer to the riddle.
File "<string>", line 1, in <module>
NameError: name 'aguacate' is not defined #It is the correct answer BTW
I know this problem generates when it starts to compare the answers, and I also KNOW that it's probably because I wrote it wrong... Sooo, any advice on how to do it right?
Thanks in advance
You need to use raw_input() instead of input(), or Python will try to evaluate the entered string - and since aguacate is not an expression that Python knows, it throws the Exception you found.
Also, your "throw the dice" routine doesn't work (try entering 0 and see what happens). That should be
if guess == 0:
# import random should be at the start of the script
guess = random.randrange(1,6)
Some other comments about your code, as requested:
In general, it's quite OK. There are a few little things that you can optimize:
You're not closing the files you have opened. That's not a problem when you're only reading them, but it will cause problems once you start writing files. Better to get used to that quickly. The best way for this is to use a with statement block; that will automatically take care of closing your file, even if an exception occurs during the execution of your program:
with open(r"C:\Users\Public\oo.txt") as f, open(r"C:\Users\Public\ee.txt") as g:
ques = f.readlines()
ans = g.readlines()
Note that I used raw strings (important if you have backslashes in your strings). If you had named your file tt.txt, your version would have failed because it would have looked for a file named Public<tab>t.txt because the \t would have been interpreted as a tab character.
Also, take a moment to study PEP-8, the Python style guide. It will help you write more readable code.
Since you're using Python 2, you can drop the parentheses in print (ques[guess-1]) (or switch to Python 3, which I would recommend anyway because Unicode! Also, in Python 3, raw_input() has finally been renamed as input()).
Then, I think you need to strip off the trailing newline character from your answer strings, or they won't compare correctly (also, drop the unnecessary parentheses):
if a == ans[guess-1].rstrip("\n"):
Related
I'm still a beginner, so I'm probably missing something obvious.
I'm trying to generate a password with random symbols, letters and numbers and am supposed to only use the functions we already learned (so no advanced stuff).
this is the problematic bit of code:
l=[]
s=[]
numb=[]
for letter in range (0,(nr_letters)):
l.append(random.choice(letters))
for symbol in range(0,(nr_symbols)):
s.append(random.choice(symbols))
for numbers in range(0,(nr_numbers)):
numb.append(random.choice(numbers))
(Info: "nr_letters" (as well as "nr_symbols" etc.) is the input given to us by the user, while "letters" is a list of strings.)
The "for" function works fine with the letters and symbols, but I receive a traceback for "numbers", even though the numbers list is also made up of strings.
This is the Traceback:
Traceback (most recent call last):
File "main.py", line 27, in <module>
numb.append(random.choice(numbers))
File "/usr/lib/python3.8/random.py", line 288, in choice
i = self._randbelow(len(seq))
TypeError: object of type 'int' has no len()
I tried to tell python again, that there are no integrals in my numbers list, so I wrote
numb.append(random.choice(str(numbers)))
But while Python now for some reason understands that the items in that list are strings, it now seems to ignore the "random.choice" bit, because it prints the numbers in order, starting from 0.
What am I doing wrong here? And please no corrections for the rest of the code, as I do want to try to finish the project mainly by myself, because otherwise I won't learn anything. I'm just not understanding why python isn't doing what I think I am telling it to do here.
Any help appreciated!
Your logic is fine only error you did is named the same list of numbers as the local variable for the iterator in for loop
for **numbers** in range(0,(nr_numbers)):
numb.append(random.choice(*numbers*))
Simplest solution is just to change variable name in for loop since you are not using it anyway. Example:
for i in range(0,(nr_numbers)):
numb.append(random.choice(numbers))
EDIT
A little bit of clarification. In your example every time you call numb.append it tries to take random.choice from the local variable numbers instead of the global variable numbers. Here is a helpful link to help you understand if you do not already know what local and global variables are.
I know there are a lot of questions about file.read() but I dont think any of them answer this....
Can someone tell me why, if I read a file with say 12 lines, in the interpreter and print it by just typing in filename.read(), it is presented on one continuous line with the EOL character to signify each line?
Then, if I do the same but create define an object, say file-output = filename.read(), and then print that object, it then prints out as it appears in the file?
Does what I said make sense????
Many thanks
I'm writing a script that logs errors from another program and restarts the program where it left off when it encounters an error. For whatever reasons, the developers of this program didn't feel it necessary to put this functionality into their program by default.
Anyways, the program takes an input file, parses it, and creates an output file. The input file is in a specific format:
UI - 26474845
TI - the title (can be any number of lines)
AB - the abstract (can also be any number of lines)
When the program throws an error, it gives you the reference information you need to track the error - namely, the UI, which section (title or abstract), and the line number relative to the beginning of the title or abstract. I want to log the offending sentences from the input file with a function that takes the reference number and the file, finds the sentence, and logs it. The best way I could think of doing it involves moving forward through the file a specific number of times (namely, n times, where n is the line number relative to the beginning of the seciton). The way that seemed to make sense to do this is:
i = 1
while i <= lineNumber:
print original.readline()
i += 1
I don't see how this would make me lose data, but Python thinks it would, and says ValueError: Mixing iteration and read methods would lose data. Does anyone know how to do this properly?
You get the ValueError because your code probably has for line in original: in addition to original.readline(). An easy solution which fixes the problem without making your program slower or consume more memory is changing
for line in original:
...
to
while True:
line = original.readline()
if not line: break
...
Use for and enumerate.
Example:
for line_num, line in enumerate(file):
if line_num < cut_off:
print line
NOTE: This assumes you are already cleaning up your file handles, etc.
Also, the takewhile function could prove useful if you prefer a more functional flavor.
Assuming you need only one line, this could be of help
import itertools
def getline(fobj, line_no):
"Return a (1-based) line from a file object"
return itertools.islice(fobj, line_no-1, line_no).next() # 1-based!
>>> print getline(open("/etc/passwd", "r"), 4)
'adm:x:3:4:adm:/var/adm:/bin/false\n'
You might want to catch StopIteration errors (if the file has less lines).
Here's a version without the ugly while True pattern and without other modules:
for line in iter(original.readline, ''):
if …: # to the beginning of the title or abstract
for i in range(lineNumber):
print original.readline(),
break
I am new to coding and I ran in trouble while trying to make my own fastq masker. The first module is supposed to trim the line with the + away, modify the sequence header (begins with >) to the line number, while keeping the sequence and quality lines (A,G,C,T line and Unicode score, respectively).
class Import_file(object):
def trim_fastq (self, fastq_file):
f = open('path_to_file_a', 'a' )
sanger = []
sequence = []
identifier = []
plus = []
f2 = open('path_to_file_b')
for line in f2.readlines():
line = line.strip()
if line[0]=='#':
identifier.append(line)
identifier.replace('#%s','>[i]' %(line))
elif line[0]==('A' or 'G'or 'T' or 'U' or 'C'):
seq = ','.join(line)
sequence.append(seq)
elif line[0]=='+'and line[1]=='' :
plus.append(line)
remove_line = file.writelines()
elif line[0]!='#' or line[0]!=('A' or 'G'or 'T' or 'U' or 'C') or line[0]!='+' and line[1]!='':
sanger.append(line)
else:
print("Danger Will Robinson, Danger!")
f.write("'%s'\n '%s'\n '%s'" %(identifier, sequence, sanger))
f.close()
return (sanger,sequence,identifier,plus)
Now for my question. I have ran this and no error appears, however the target file is empty. I am wondering what I am doing wrong... Is it my way to handle the lists or the lack of .join? I am sorry if this is a duplicate. It is simply that I do not know what is the mistake here. Also, important note... This is not some homework, I just need a masker for work... Any help is greatly appreciated and all mentions of improvement to the code are welcomed. Thanks.
Note (fastq format):
#SRR566546.970 HWUSI-EAS1673_11067_FC7070M:4:1:2299:1109 length=50
TTGCCTGCCTATCATTTTAGTGCCTGTGAGGTGGAGATGTGAGGATCAGT
+
hhhhhhhhhhghhghhhhhfhhhhhfffffe`ee[`X]b[d[ed`[Y[^Y
Edit: Still unable to get anything, but working at it.
Your problem is with your understanding of the return statement. return x means stop executing the current function and give x back to whoever called it. In your code you have:
return sanger
return sequence
return identifier
return plus
When the first one executes (return sanger) execution of the function stops and sanger is returned. The second through fourth return statements never get evaluated and neither does your I/O stuff at the end. If you're really interested in returning all of these values, move this after the file I/O and return the four of them packed up as a tuple.
f.write("'%s'\n '%s'\n '%s'" %(identifier, sequence, sanger))
f.close()
return (sanger,sequence,identifier,plus)
This should get you at least some output in the file. Whether or not that output is in the format you want, I can't really say.
Edit:
Just noticed you were using /n and probably want \n so I made the change in my answer here.
You have all sorts of errors beyond what #Brian addressed. I'm guessing that your if and else tests are trying to check the first character of line? You'd do that with
if line[0] == '#':
etc.
You'll probably need to write more scripts soon, so I suggest you work through the Python Tutorial so you can get on top of the basics. It'll be worth your while.
Update: My current question is how can I get my code to read to the EOF starting from the beginning with each new search phrase.
This is an assignment I am doing and currently stuck on. Mind you this is a beginner's programming class using Python.
jargon = open("jargonFile.txt","r")
searchPhrase = raw_input("Enter the search phrase: ")
while searchPhrase != "":
result = jargon.readline().find(searchPhrase)
if result == -1:
print "Cannot find this term."
else:
print result
searchPhrase = raw_input("Enter the search phrase: ")
jargon.close()
The assignment is to take a user's searchPhrase and find it in a file (jargonFile.txt) and then have it print the result (which is the line it occured and the character occurence). I will be using a counter to find the line number of the occurence but I will implement this later. For now my question is the error I am getting. I cann't find a way for it to search the entire file.
Sample run:
Enter the search phrase: dog
16
Enter the search phrase: hack
Cannot find this term.
Enter the search phrase:
"dog" is found in the first line however it is also found in other lines of the jargonFile (multiple times as a string) but it is only showing the first occurence in the first line. The string hack is found numerous times in the jargonFile but my code is setup to only search the first line. How may I go about solving this problem?
If this is not clear enough I can post up the assignment if need be.
First you open the file and read it into a string with readline(). Later on you try to readline() from the string you obtained in the first step.
You need to take care what object (thing) you're handling: open() gave you a file "jargon", readline on jargon gave you the string "jargonFile".
So jargonFile.readline does not make sense anymore
Update as answer to comment:
Okay, now that the str error problem is solved think about the program structure:
big loop
enter a search term
open file
inner loop
read a line
print result if string found
close file
You'd need to change your program so it follows that descripiton
Update II:
SD, if you want to avoid reopening the file you'd still need two loops, but this time one loop reads the file into memory, when that's done the second loop asks for the search term. So you would structure it like
create empty list
open file
read loop:
read a line from the file
append the file to the list
close file
query loop:
ask the user for input
for each line in the array:
print result if string found
For extra points from your professor add some comments to your solution that mention both possible solutions and say why you choose the one you did. Hint: In this case it is a classic tradeoff between execution time (memory is fast) and memory usage (what if your jargon file contains 100 million entries ... ok, you'd use something more complicated than a flat file in that case, bu you can't load it in memory either.)
Oh and one more hint to the second solution: Python supports tuples ("a","b","c") and lists ["a","b","c"]. You want to use the latter one, because list can be modified (a tuple can't.)
myList = ["Hello", "SD"]
myList.append("How are you?")
foreach line in myList:
print line
==>
Hello
SD
How are you?
Okay that last example contains all the new stuff (define list, append to list, loop over list) for the second solution of your program. Have fun putting it all together.
Hmm, I don't know anything at all about Python, but it looks to me like you are not iterating through all the lines of the file for the search string entered.
Typically, you need to do something like this:
enter search string
open file
if file has data
start loop
get next line of file
search the line for your string and do something
Exit loop if line was end of file
So for your code:
jargon = open("jargonFile.txt","r")
searchPhrase = raw_input("Enter the search phrase: ")
while searchPhrase != "":
<<if file has data?>>
<<while>>
result = jargon.readline().find(searchPhrase)
if result == -1:
print "Cannot find this term."
else:
print result
<<result is not end of file>>
searchPhrase = raw_input("Enter the search phrase: ")
jargon.close()
Cool, did a little research on the page DNS provided and Python happens to have the "with" keyword. Example:
with open("hello.txt") as f:
for line in f:
print line
So another form of your code could be:
searchPhrase = raw_input("Enter the search phrase: ")
while searchPhrase != "":
with open("jargonFile.txt") as f:
for line in f:
result = line.find(searchPhrase)
if result == -1:
print "Cannot find this term."
else:
print result
searchPhrase = raw_input("Enter the search phrase: ")
Note that "with" automatically closes the file when you're done.
Your file is jargon, not jargonFile (a string). That's probably what's causing your error message. You'll also need a second loop to read each line of the file from the beginning until you find the word you're looking for. Your code currently stops searching if the word is not found in the current line of the file.
How about trying to write code that only gives the user one chance to enter a string? Input that string, search the file until you find it (or not) and output a result. After you get that working you can go back and add the code that allows multiple searches and ends on an empty string.
Update:
To avoid iterating the file multiple times, you could start your program by slurping the entire file into a list of strings, one line at a time. Look up the readlines method of file objects. You can then search that list for each user input instead of re-reading the file.
you shouldn't try to re-invent the wheel. just use the
re module functions.
your program could work better if you used:
result = jargon.read() .
instead of:
result = jargon.readline() .
then you could use the re.findall() function
and join the strings (with the indexes) you searched for with str.join()
this could get a little messy but if take some time to work it out, this could fix your problem.
the python documentation has this perfectly documented
Everytime you enter a search phrase, it looks for it on the next line, not the first one. You need to re-open the file for every search phrase, if you want it behave like you describe.
Take a look at the documentation for File objects:
http://docs.python.org/library/stdtypes.html#file-objects
You might be interested in the readlines method. For a simple case where your file is not enormous, you could use that to read all the lines into a list. Then, whenever you get a new search string, you can run through the whole list to see whether it's there.