Traceback when trying to print a random string - python

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.

Related

Don't understand why getting 'ValueError: Mixing iteration and read methods would lose data' [duplicate]

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

Name Error: name 'add' is not defined

it my first time using Stack Overflow so please excuse any mistakes i have made. Im creating a program and i want ask mathematical questions for the user. But my program will generate two random numbers, and a random arithmetic operator will occur. They are plus, minus and times. So i put them into an array and this is the code.
Code:
The Error i gained:
It said the Error is in Line 10.
Ive tried doing this 'What is'+str(Ran) +,+str(op) +,+str(dom) +'?')
However i gained an invalid syntax on the comma.
Ive tried searching for this particular program, but all of them seem to have something called classes and def in. If it is possible, can i please not use the def and class in my program because i am new to python and i still need to learn what they are.
I am using Python 3.4.2, on a Windows 8 operating system if you wanted to know.
Thanks for reading, i am looking forward to have any assistance in my problem.
+ + is invalid syntax. You should be doing str(something) + ' ' + string(something_else) if you want to add two strings with a space in between. You also need quotes around add, minus and times in the list in order to make them strings.

Python: Function simplifying the input instead of passing string

I need to enter a complex string for handling (UTC time code) and breaking down as part of an assignment. I have started the function like this as required:
def convertWmiDateTime(wmiDateTime):
But when I enter this:
convertWmiDateTime(20061122185433.000000+600)
The variable wmiDateTime stores 2.0061122186e+13
If I use raw_input the value 20061122185433.000000+600 will be stored correctly in wmiDateTime, but not when its called as intended above.
Is there a way to preserve what was typed into the input? A way to stop Pythong calculating and simplifying the number? vb. net would be something like (wmiDateTime As String) is there anything like that for Python?
Thanks for looking.
Your function requires a string as its input parameter. You can't call it with a number (as you're doing).
raw_input() returns a string, so the equivalent would be to call
convertWmiDateTime("20061122185433.000000+600")
Your version treats the time code as a floating point number which a) doesn't have the required precision to preserve all the digits and b) will get the timezone info (+600) added, which leads to wrong results as well.

Python comparing input to line in file?

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"):

how to avoid python numeric literals beginning with "0" being treated as octal?

I am trying to write a small Python 2.x API to support fetching a
job by jobNumber, where jobNumber is provided as an integer.
Sometimes the users provide ajobNumber as an integer literal
beginning with 0, e.g. 037537. (This is because they have been
coddled by R, a language that sanely considers 037537==37537.)
Python, however, considers integer literals starting with "0" to
be OCTAL, thus 037537!=37537, instead 037537==16223. This
strikes me as a blatant affront to the principle of least
surprise, and thankfully it looks like this was fixed in Python
3---see PEP 3127.
But I'm stuck with Python 2.7 at the moment. So my users do this:
>>> fetchJob(037537)
and silently get the wrong job (16223), or this:
>>> fetchJob(038537)
File "<stdin>", line 1
fetchJob(038537)
^
SyntaxError: invalid token
where Python is rejecting the octal-incompatible digit.
There doesn't seem to be anything provided via __future__ to
allow me to get the Py3K behavior---it would have to be built-in
to Python in some manner, since it requires a change to the lexer
at least.
Is anyone aware of how I could protect my users from getting the
wrong job in cases like this? At the moment the best I can think
of is to change that API so it take a string instead of an int.
At the moment the best I can think of is to change that API so it take a string instead of an int.
Yes, and I think this is a reasonable option given the situation.
Another option would be to make sure that all your job numbers contain at least one digit greater than 7 so that adding the leading zero will give an error immediately instead of an incorrect result, but that seems like a bigger hack than using strings.
A final option could be to educate your users. It will only take five minutes or so to explain not to add the leading zero and what can happen if you do. Even if they forget or accidentally add the zero due to old habits, they are more likely to spot the problem if they have heard of it before.
Perhaps you could take the input as a string, strip leading zeros, then convert back to an int?
test = "001234505"
test = int(test.lstrip("0")) # 1234505

Categories

Resources