How do you use an incremented variable outside of function in python? - python

This could be a foolish question; maybe my though process is totally wrong (if so, please point it out), but how do you extract the three incremented variables (c_char, c_word, c_sentence) inside a custom function and use it for other uses?
def length_finder(x):
#variables counting character,word,sentnece
c_char = 0
c_word = 1
c_sentence = 0
for i in x:
if (i >= 'a' and i <= 'z') or (i >= 'A' and i <= 'Z'):
c_char += 1
if i == " ":
c_word += 1
if i == '.' or i == '!' or i == '?' :
c_sentence += 1
length_finder(input("Enter the text you wish to analyze: "))
L = 100/c_word*c_char
S = 100/c_word*c_sentence
#formula to get readability
index = 0.0588 * L - 0.296 * S - 15.8
print("This text is suitable for grade " + str(index))

You can return multiple variables from within the function:
def length_finder(x):
...
return (c_char, c_word, c_sentence)
(c_char, c_word, c_sentence) = length_finder('input string')

You have two options.
Make those three variables global, and reference them in the function. You can make them global, then reference them as global within the function.
Return them from the function. You can return all 3 values as a dictionary or list.

Related

Function does not modify variable in python

I create two lists, a, b with 10 random numbers from 0 to 61 and then I compare the lists if they have common numbers or not.
I store the common numbers in a separate list.
If the list does have numbers in it the commonCount is going up and if the list is empty the noCommonCount is going up.
But when I want to print the counts after I rand the function 10 times it prints out 0.
I don't know why because I declared the variables commonCount and noCommonCount outside the function.
import random
noCommonCount = 0
commonCount = 0
def list_overlap():
a = []
b = []
count = 0
while count < 10:
count = count + 1
a.append(random.randint(0, 61))
b.append(random.randint(0, 61))
commonNumbers = []
for i in a:
if i in b:
if i not in commonNumbers:
commonNumbers.append(i)
if not commonNumbers:
noCommonCount + 1
else:
commonCount + 1
functionCount = 0
while functionCount < 10:
functionCount = functionCount + 1
list_overlap()
print(noCommonCount)
print(commonCount)
For a function modifying a variable declared on outer scope additionally a declaration of the form
global variable_name
is required in the function (typically directly after function declaration.

Why won't the "total" value update when run multiple times?

The "total" changes the first time I run the function but doesn't return the new value of total so when I run it again it's the same value as before I ran it the first time?
total = card[1].value
def hit(total):
#print (str(hit.counter))
print("You draw the " + string(card[hit.counter]))
total = total + card[hit.counter].value
print(str(total))
hit.counter += 1
return hit.counter
return total
the function is called here:
choice = raw_input("\n1. Hit\n2. Stay\n")
if (choice == "1"):
hit(total)
This is the same problem simplified
x = 1
def call(x):
x = x + 1
print x
return x
call(x)
every time this is run it outputs 2 and doesn't update the new value of "x = x + 1"
You have a global variable called total. You also have a local variable called total.
When you are in the function, the local total will shadow the outer global one so updates to total inside the function will only update the local variable.
This is the same problem simplified
x = 1
def call(x):
x = x + 1
print x
return x
call(x)
And ? What do you expect ? That the global x will be automagically updated after the last line ? Sorry but that's not how it works. Within call(), x is a local name, totally unrelated to the outer global x. When you call call(x). If you want the global x to be updated, you have to explicitely rebind it:
def call(x):
x = x + 1
print x
return x
x = 1
x = call(x)
I strongly suggest you read this: https://nedbatchelder.com/text/names.html
EDIT:
"I want it so when I run the hit() function a second time, the total is the total of the last time I used it"
It's your responsability (the responsability of the code calliing this function I mean) to store the total somewhere and pass it back on the next call:
# Q&D py2 / py3 compat:
try:
# py2
input = raw_input
except NameError:
# py3
pass
def call(x):
x = x + 1
print(x)
return x
x = 1
while True:
print("before call, x = {}".format(x))
x = call(x)
print("after call, x = {}".format(x))
if input("play again ? (y/n)").strip().lower() != "y":
break
total = card[1].value
def hit(total):
print("You draw the " + string(card[hit.counter]))
total += card[hit.counter].value
hit.counter += 1
return hit.counter, total
hit_counter, total = hit(total)
as bazingaa has suggested, you are not reaching the return for the total. if you want multiple values returned, you can do that as above and the use them as shown above in an assignment.

Returning multiple integers as separate variables

I am trying to make a program that grabs 5 integers from the user, and then finds the average of them. I have it set up to take in the 5 numbers, but how do I return them all as separate variables so I can use them later on? Thanks!
def main():
x = 0
testScoreNumber = 1
while x < 5:
getNumber_0_100(testScoreNumber)
x += 1
testScoreNumber += 1
calcAverage(score1, score2, score3, score4, score5)
print(calculatedAverage)
def getNumber_0_100(testnumber):
test = int(input("Enter test score " + str(testnumber) + ":"))
testcount = 0
while testcount < 1:
test = int(input("Enter test score " + str(testnumber) + ":"))
if test > 0 or test < 100:
testcount += 1
return test
^Here is the problem, the everytime this function runs, I want it to return a different value to a different variable. Ex. test1, test2, test3.
def calcAverage(_score1,_score2,_score3,_score4,_score5):
total = _score1 + _score2 + _score3 + _score4 + _score5
calculatedAverage = total/5
return calculatedAverage
You need to store the result somewhere. It is usually (always?) a bad idea to dynamically create variable names (although it is possible using globals). The typical place to store the results is in a list or a dictionary -- in this case, I'd use a list.
change this portion of the code:
x = 0
testScoreNumber = 1
while x < 5:
getNumber_0_100(testScoreNumber)
x += 1
testScoreNumber += 1
to:
results = []
for x in range(5):
results.append( getNumber_0_100(x+1) )
which can be condensed even further:
results = [ getNumber_0_100(x+1) for x in range(5) ]
You can then pass that results list to your next function:
avg = get_ave(results[0],results[1],...)
print(avg)
Or, you can use the unpacking operator for shorthand:
avg = get_ave(*results)
print(avg)
It isn't the responsibility of the returning function to say what the caller does with its return value. In your case, it would be simple to let main have a list where it adds the return values. You could do this:
scores = []
for i in range(5):
scores.append(getNumber_0_100(i))
calcAverage(*scores)
Note that *scores is to pass a list as arguments to your calcAverage function. It's probably better to have calculateAverage be a general function which takes a list of values and calculates their average (i.e. doesn't just work on five numbers):
def calcAverage(numbers):
return sum(numbers) / len(numbers)
Then you'd call it with just calcAverage(scores)
A more Pythonic way to write the first part might be scores = [getNumber_0_100(i) for i in range(5)]
Python allows you to return a tuple, and you can unroll this tuple when you receive the return values. For example:
def return_multiple():
# do something to calculate test1, test2, and test3
return (test1, test2, test3)
val1, val2, val3 = return_multiple()
The limitation here though is that you need to know how many variables you're returning. If the number of inputs is variable, you're better off using lists.

How to group a list of numbers into certain categories

I am trying to figure out how to take in a list of numbers and sort them into certain categories such as 0-10, 10-20, 20-30 and up to 90-100 but I have the code started, but the code isn't reading in all the inputs, but only the last one and repeating it. I am stumped, anyone help please?
def eScores(Scores):
count0 = 0
count10 = 0
count20 = 0
count30 = 0
count40 = 0
count50 = 0
count60 = 0
count70 = 0
count80 = 0
count90 = 0
if Scores > 90:
count90 = count90 + 1
if Scores > 80:
count80 = count80 + 1
if Scores > 70:
count70 = count70 + 1
if Scores > 60:
count60 = count60 + 1
if Scores > 50:
count50 = count50 + 1
if Scores > 40:
count40 = count40 + 1
if Scores > 30:
count30 = count30 + 1
if Scores > 20:
count20 = count20 + 1
if Scores > 10:
count10 = count10 + 1
if Scores <= 10:
count0 = count0 + 1
print count90,'had a score of (90 - 100]'
print count80,'had a score of (80 - 90]'
print count70,'had a score of (70 - 80]'
print count60,'had a score of (60 - 70]'
print count50,'had a score of (50 - 60]'
print count40,'had a score of (40 - 50]'
print count30,'had a score of (30 - 40]'
print count20,'had a score of (20 - 30]'
print count10,'had a score of (10 - 20]'
print count0,'had a score of (0 - 10]'
return eScores(Scores)
Each time eScores is called is sets all the counters (count10, count20) back to zero. So only the final call has any effect.
You should either declare the counters as global variables, or put the function into a class and make the counters member variables of the class.
Another problem is that the function calls itself in the return statement:
return eScores(Scores)
Since this function is (as I understand it) supposed to update the counter variables only, it does not need to return anything, let alone call itself recursively. You'd better remove the return statement.
One thing you're making a mistake on is that you're not breaking out of the whole set of if's when you go through. For example, if you're number is 93 it is going to set count90 to 1, then go on to count80 and set that to one as well, and so on until it gets to count10.
Your code is repeating because the function is infintely recursive (it has no stop condition). Here are the relevant bits:
def eScores(Scores):
# ...
return eScores(Scores)
I think what you'd want is more like:
def eScores(Scores):
# same as before, but change the last line:
return
Since you're printing the results, I assume you don't want to return the values of score10, score20, etc.
Also, the function won't accumulate results since you're creating new local counts each time the function is called.
Why don't you just use each number as a key (after processing) and return a dictionary of values?
def eScores(Scores):
return_dict = {}
for score in Scores:
keyval = int(score/10)*10 # py3k automatically does float division
if keyval not in return_dict:
return_dict[keyval] = 1
else:
return_dict[keyval] += 1
return return_dict

variable within a nested loop in python

I'm trying to figure what the values of xcoord_orig and ycoord_orig are when the last conditional statement is true i.e. when board[xcoordT][ycoordT] == computer. I feel that as I have it right now, I'm simply printing their values if the conditional statement is true. But what I really want are the values of xcoord_orig and ycoord_orig under the first loop at the point where the last conditional statement is true. I'm not sure if this is clear but I thought I would ask.
for num in range(8):
for i in range(len(valid_list)):
xcoord_orig = valid_list[i][0]
ycoord_orig = valid_list[i][1]
xcoord1 = valid_list[i][0] + num_list[num]
ycoord1 = valid_list[i][1] + num_list2[num]
if 0 <= xcoord1 <= 7 and 0 <= ycoord1 <= 7:
piece = board[xcoord1][ycoord1]
if piece == player:
move_list = []
for i in range(2,8):
xcoordT = xcoord_orig
ycoordT = ycoord_orig - i
print(xcoord_orig, ycoord_orig)
if board[xcoordT][ycoordT] == computer:
move_list.append([xcoordT, ycoordT])
print(xcoord_orig, ycoord_orig)
This
for i in range(len(valid_list)):
...
for i in range(2,8):
Is epic fail. It can't be correct.

Categories