How to fix a program that only works once? - python-2.7

def check_answer(self, currentscore):
self.user_entry = self.user_entry.get_text()
if self.user_entry == self.books:
self.current += 1
self.total += 1
self.currentscore = self.current
print "right"
else:
print "wrong"
print self.currentscore
print self.total
When i run it and i put text a second time is says File "C:\Python27\guessing.py", line 16, in check_answer
self.user_entry = self.user_entry.get_text()
AttributeError: 'str' object has no attribute 'get_text'
Could someone explain it to me. Why it to me why it only works once. and also why doesn't the program execute the if statement. It only says wrong.
self.books = 'hello'

You overwrite the variable holding the reference to the text box with its contents. So when check_answer runs for the first time, self.user_entry is your text box, and you can call its method get_text() to retrieve the text entered by the user. Unfortunately, you assign this text to the same variable (self.user_entry =) - so you loose the reference to the text box. After the first call, self.user_entry is a string (instance of str class) retrieved at the first call.
Use a different variable name, like this:
def check_answer(self, currentscore):
self.user_entry_text = self.user_entry.get_text()
if self.user_entry_text == self.books:
self.current += 1
self.total += 1
self.currentscore = self.current
print "right"
else:
print "wrong"
print self.currentscore
print self.total
Also, possibly it doesn't have to be class's field, so you can also skip the self. part. In such case you could use the same name (user_entry), but for sake of readability it's better to call a variable with a name that says precisely what the variable holds:
user_entry_text = self.user_entry.get_text()
if user_entry_text == self.books:

Related

Python TypeError: can only concatenate list (not "str") to list

I have a method which returns a list of text from a tag from an HTML file using Beautifulsoup.
When I call the method I save the value returned from the method into a variable.
I think a string variable.
I call the method a second time and store the returned value into a different string variable.
I would like to concatenate these two strings so that I can print each one on a newline. I can then add this to my email routine so that it prints the values into the email message.
I get the error:
Traceback (most recent call last):
File "E:/test_runners/selenium_regression_test_5_1_1/ClearCore - Regression Test/Email/email_selenium_report.py", line 43, in <module>
print rows_part1 + "/n" + rows_part2
TypeError: can only concatenate list (not "str") to list
My method implementation is:
def extract_data_from_report3(filename):
html_report_part = open(filename,'r')
soup = BeautifulSoup(html_report_part, "html.parser")
th = soup.find_all('th')
td = soup.find_all('td')
headers = [header.get_text(strip=True) for header in soup.find_all("th")]
rows = [dict(zip(headers, [td.get_text(strip=True) for td in row.find_all("td")]))
for row in soup.find_all("tr")[1:-1]]
print(rows)
return rows
To call the method is as follows:
rows_part1 = report.extract_data_from_report3(r"E:\test_runners\selenium_regression_test_5_1_1\TestReport\SeleniumTestReport_part1.html")
print "part1 = "
print rows_part1
rows_part2 = report.extract_data_from_report3(r"E:\test_runners\selenium_regression_test_5_1_1\TestReport\SeleniumTestReport_part2.html")
print "part2 = "
print rows_part2
print rows_part1 + "/n" + rows_part2
The value in rows_part1 is:
part1 =
[{u'Success': u'219', u'Skip': u'0', u'Error': u'9', u'Fail': u'1', u'Total': u'229', u'Class': u'Regression_TestCase.RegressionProject_TestCase2.RegressionProject_TestCase2'}]
The value in rows_part2 is:
part2 =
[{u'Success': u'21', u'Skip': u'0', u'Error': u'10', u'Fail': u'5', u'Total': u'230', u'Class': u'Regression_TestCase.RegressionProject_TestCase2.RegressionProject_TestCase2'}]
I would like to print out the value of rows_part 1 and then on a newline print out the value of rows_part2.
I am concatenating it so that I can just put the one variable in the email message body which will print out the value.
Or how can I extract the contents out of the list and append it to a string variable?
I can then print out the string variable.
Firstly, in Python, you don't have to declare a variable type, it's assigned under the hood. That's confused you about the variable types.
returns a list
[...]
I think a string variable
Your print statement is attempting to print a list type object, then a new line, then another list type object. Your issue is coming from the "\n" in between.
Concatenating two strings is possible with: str1 + str2
Concatenating two lists is possible with: list1.append(list2)
But concatenating a string to a list (or a list to a string) is not! What you need to do is turn your list objects into strings (of that list).
print str(rows_part1) + "/n" + str(rows_part2)
should work.

how to exit from multiple loops in python

In my code below, I keep getting an error that I cant tell how to fix it.
See code:
def WordSelector():
global pattern
words = [location]
corpus = " ".join(words)
sentences1 = re.split(r'\.', corpus)
name17 = [name66, name666, name67, name68, name69, name612]
k1 = iter(name17)
keyword = next(k1)
pattern1 = keyword
class LocalBreak(Exception):
pass
try:
for pattern1 in name17:
for sentence in sentences1:
if pattern1 in sentence:
print 'code'
raise LocalBreak()
except LocalBreak:
pass
WordSelector()
I keep getting this error:
"C:\Python27\synonyms3.py", line 72, in LocalBreak
except LocalBreak:
NameError: free variable 'LocalBreak' referenced before assignment in enclosing scope
Whole try/except block is defined inside LocalBreak body, where you cannot reference class itself (since it's definition is not yet done).
Simply indent your code correctly and do your looping in fuction body, not in custom Exception definition scope.
def WordSelector():
global pattern
words = [location]
corpus = " ".join(words)
sentences1 = re.split(r'\.', corpus)
name17 = [name66, name666, name67, name68, name69, name612]
k1 = iter(name17)
keyword = next(k1)
pattern1 = keyword
class LocalBreak(Exception):
pass
try:
for pattern1 in name17:
for sentence in sentences1:
if pattern1 in sentence:
print 'code'
raise LocalBreak()
except LocalBreak:
pass
WordSelector()

python 2.7 - trying to print a string and the (printed) output of function in the same line

I have the following function defined:
def displayHand(hand):
"""
Displays the letters currently in the hand.
For example:
>>> displayHand({'a':1, 'x':2, 'l':3, 'e':1})
Should print out something like:
a x x l l l e
The order of the letters is unimportant.
hand: dictionary (string -> int)
"""
for letter in hand.keys():
for j in range(hand[letter]):
print letter, # print all on the same line
print '' # print an empty line
Now, I want to print the following:
Current hand: a b c
To do this, I try to do:
print "Current hand: ", displayHand({'a':1, 'b':1, 'c':1})
And I get:
Current hand: a b c
None
I know that None is printed cause I am calling the print function on the displayHand(hand) function, which doesn't return anything.
Is there any way to get rid of that "None" without modifying displayHand(hand)?
if you want to use your function in a print statement, it should return a string and not print something itself (and return None) - as you would do in a __str__ method of a class. something like:
def displayHand(hand):
ret = ''
for letter in hand.keys():
for j in range(hand[letter]):
ret += '{} '.format(letter) # print all on the same line
# ret += '\n'
return ret
or even
def displayHand(hand):
return ''.join(n*'{} '.format(k) for k,n in hand.items() )
When you trail a print with a ,, the next print will appear on the same line, so you should just call the two things on separate lines, as in:
def printStuff():
print "Current hand: ",
displayHand({'a':1, 'b':1, 'c':1})
Of course you could just adapt this and create a method like:
def printCurrentHand(hand):
print "Current hand: ",
displayHand(hand)
The only way to do this (or I believe the only way to do this) is to use return instead of print in your displayhand() function. Sorry if I didn't answer your question.
Your function 'displayHand' does not have to print the output,
it has to return a string.
def displayHand(hand):
mystring=''
for letter in hand.keys():
for j in range(hand[letter]):
mystring+= letter # concatenate all on the same line
return mystring
BUT, you have to check the '.keys' command help as the order of the input (a/b/c) may not be respected

python: checking for errors in the users input

I would like
to check if a string can be a float before I attempt to convert it to a float. This way, if the
string is not float, we can print an error message and exit instead of crashing the
program.
so when the user inputs something, I wanna see if its a float so it will print "true" if its not then it will print"false" rather than crashing. I don't want to use built in functions for this. I need to make my own function for this.
I tried :
import types
def isFloat():
x = raw_input("Enter: ")
if(x) == float:
print("true")
if(x) == str:
print("false")
isFloat()
I don't know if its true or not but it wont work it wont print anything either
The recommended thing to do here is to try it:
try:
f = float(x)
print("true")
except ValueError:
# handle error here
print("false")
This underscores the Python philosophy "It's better to ask for forgiveness than for permission".
The only reliable way to figure out whether a string represents a float is to try to convert it. You could check first and convert then, but why should you? You'd do it twice, without need.
Consider this code:
def read_float():
"""
return a floating-point number, or None
"""
while True:
s = raw_input('Enter a float: ').strip()
if not s:
return None
try:
return float(s)
except ValueError:
print 'Not a valid number: %r' % s
num = read_float()
while num is not None:
... do something ...
print 'Try again?'
num = read_float()

Python 2.7: Variable defined in previous function, receiving undefined error

So my variable is clearly defined in inputnfo(), why am I getting an undefined error? The try & except perhaps? I've added removed... swapped it all around and cannot seem to find the solution, and answers online seem very situation based... Thanks in advance :)
Super New & improved edit: now getting UnboundLocalError
import random
alpha = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
strgen = []
retry = 0
### Defining
def inputnfo():
global much
much = input('how long do you want your random word/lucky number to be: ')
global which
which = raw_input('would you like letters or numbers?(let,num, or mix?):').lower
def generate():
while much > 0:
if which == 'let':
strgen.append(random.choice(alpha))
much -= 1
print '.'
elif which == 'num':
strgen.append(random.randint(1,9))
much -= 1
print '.'
elif which == 'mix':
mixer = random.choice([0,1])
if mixer == 0:
strgen.append(random.choice(alpha))
much -= 1
print '.'
elif mixer == 1:
strgen.append(random.randint(1,9))
much -= 1
print '.'
def finish():
finito = ''.join(strgen)
print 'Generation Completed!\n'
if which == 'let':
print 'Your randomly generated string is:' + finito
elif which == 'num':
print 'Your randomly generated number is:' + finito
elif which == 'mix':
print 'Your randomly generated Alpha-Numerical string is:' + finito
### Running
inputnfo()
while much != 0:
generate()
finish()
Its because the variable "much" in the function inputnfo() is local to that function alone. that is why you are getting an undefined error in the while loop. there is two solution
1. Make the variable "much" global by including the line
def inputnfo():
global much
try:
and then removing the argument of generate function
Or
2. Let the function inputnfo() return much and use this return value in the while loop and generate function
do the same for variable "which"
and put a line which = "" befor
which = ""
def inputnfo():
global much