Python passing variables through functions - python

I have been learning python for 2 days.
So I am making this program which generates different numbers, and adds them to a string.
I have a function for getting the random numbers:
def GetRandomNumbers():
random_number = random.choice(zero_to_nine)
two_random_number = random.choice(zero_to_nine)
three_random_number = random.choice(zero_to_nine)
four_random_number = random.choice(zero_to_nine)
//
def SettingVariables():
first_combination = ("__asm _emit " + zero + ("x") + random_number + " " + "/")
two_first_combination = ("__asm _emit " + zero + ("x") + two_random_number + " " + "/")
three_first_combination = ("__asm _emit " + zero + ("x") + three_random_number + " " + "/")
four_first_combination = ("__asm _emit " + zero + ("x") + four_random_number + " " + "/")
And then when I attempt to use theese generated variables in a different function where theese numbers are added onto text it is unidentified. I know it has something to do with global variables, but I would need some explaining.

Propably you should return values from your first function:
def GetRandomNumbers():
... # get your numbers
return random_number, two_random_number, ...
Then you can parse these numbers as an argument to your second function:
def SettingVariables(first_num, second_num, third_num): ...
You could set a global variable like this (this is not recommended):
global var
var = 1
Your code could look like this:
def GetRandomNumbers():
random_number = random.choice(zero_to_nine)
two_random_number = random.choice(zero_to_nine)
three_random_number = random.choice(zero_to_nine)
four_random_number = random.choice(zero_to_nine)
return random_number, two_random_number, three_random_number, four_random_number
def SettingVariables(random_number, two_random_number, three_random_number, four_random_number):
first_combination = ("__asm _emit " + zero + ("x") + random_number + " " + "/")
two_first_combination = ("__asm _emit " + zero + ("x") + two_random_number + " " + "/")
three_first_combination = ("__asm _emit " + zero + ("x") + three_random_number + " " + "/")
four_first_combination = ("__asm _emit " + zero + ("x") + four_random_number + " " + "/")
# later in the program
nums = GetRandomNumbers()
SettingVariables(nums[0], nums[1], nums[2], nums[3]) # could also use *nums
Note that your SettingVariables function should also return the "combinations". You then can use the same principle

It's interesting that you're function names contains keyword get and set. These are concept familiar to classes.
You may consider define some classes here.
An example would be
class RandomNumbers:
def __init__(self, zero_to_nine):
random_number = random.choice(zero_to_nine)
class Variables:
def __init__(self, random_numbers):
self.first_combination = ("__asm _emit " + zero + ("x") + random_numbers.random_number + " " + "/")
...
Then you can do like this:
random_numbers = RandomNumbers()
variables = Variables(random_numbers)
print(variables.first_combination)
[edit]
I suggested classes as it seems that you'are using functions as initializers. They are quite similar to what in OOP are object constructors.
This would avoid the need for declaring all a bunch of variables outside of the function, update them an returning from the function.

Related

can only concatenate str (not "tuple") to str? How to get rid of tuple?

while True:
time.sleep(SLEEP_BETWEEN_ACTIONS)
input_1 = input("\n" + player1_name + ": " + random.choice(player_turn_text) + " Hit the enter to roll dice: ")
print("\nRolling dice...")
dice_value = get_dice_value()
time.sleep(SLEEP_BETWEEN_ACTIONS)
print(player1_name + " moving....")
player1_current_position = snake_ladder(player1_name, player1_current_position, dice_value)
check_win(player1_name, player1_current_position)
if __name__ == "__main__":
start()
My error log says
TypeError: can only concatenate str (not "tuple") to str
input_1 = input("\n" + player1_name + ": " + random.choice(player_turn_text) + " Hit the enter to roll dice: ")
I don't know the signatures of the function you use, and that are not present in the attached code. But it seems, one of the elements here:
+ player1_name + ": " + random.choice(player_turn_text) +
Returns tuple.
The simplest solution to that, would be to call it like str(player1_name) - and the same with the other one.

Need to make str method return string instead of printing

I need the below str method written to return a string rather than print a string.
def __str__(self):
"""Returns the string representation of the student."""
avg = sum(self.scores) / len(self.scores)
print("Name: " + str(self.name))
print("Score 1: " + str(self.scores[0]))
print("Score 2: " + str(self.scores[1]))
print("Score 3: " + str(self.scores[2]))
print("High: " + str(int(max(self.scores))))
print("Average: %.2f\n" % avg)
What you want to do is convert all those print statements into one string, while maintaining the newlines that you already have.
Something like this should work in place of str
def __str__(self):
avg = sum(self.scores) / len(self.scores)
s = ""
s += "Name: " + str(self.name) + "\n"
s += "Score 1: " + str(self.scores[0]) + "\n"
s += "Score 2: " + str(self.scores[1]) + "\n"
s += "Score 3: " + str(self.scores[2]) + "\n"
s += "High: " + str(int(max(self.scores))) + "\n"
s += "Average: %.2f\n" % avg + "\n"
return s

Python: Calling a function with a string returns the description of the argument

I am trying to call a function with a string but as I do so the function just make use of the name of the argument for that function.
My function is defined as sortering(attribut) and when i call it with for example: sortering('age') it uses 'attribut' and not 'age'.
Here is the code, I am fairly new to python so it is probably something obvious that I am not familiar with.
def sortering(attribut):
try:
val1 = input("Vill du sortera stigande eller fallande? s/f")
if val1 == "s":
djurlista.sort(key=lambda x: x.attribut)
print(*djurlista,sep='\n' + ' ' + '\n')
elif val1 == "f":
djurlista.sort(key=lambda x: x.attribut, reverse=True)
print(*djurlista,sep='\n' + ' ' + '\n')
except ValueError:
print("Svara med s för stigande eller f för fallande!")
sortering('age')
The list "djurlista" is a list of strings and each string is an object 'Djur' with attributes: art, namn, ålder, kön, gravid
Here is that code:
class Djur:
def __init__(self, art, namn, ålder, kön, gravid):
self.art = art
self.namn = namn
self.age = ålder
self.gender = kön
self.gravid = gravid
x = Djur(art, namn, ålder, kön, gravid)
self.djurlista.append(x)
def __str__(self):
return ("Art: " + str(self.art) + " " + "\n"
"Namn: " + str(self.namn) + " " + "\n"
"Ålder: " + str(self.age) + " " + "\n"
"Kön: " + str(self.gender) + " " + "\n"
"Gravid: " + str(self.gravid))
def __repr__(self):
return str(self)
Instead of x.attribut (where attribut is a string, and x is a Djur instance), you should use [Python 3.Docs]: Built-in Functions - getattr(object, name[, default]):
djurlista.sort(key=lambda x: getattr(x, attribut))
Use x[attribut] and not x.attribut
def sortering(attribut):
try:
val1 = input("Vill du sortera stigande eller fallande? s/f")
if val1 == "s":
djurlista.sort(key=lambda x: x[attribut])
print(*djurlista,sep='\n' + ' ' + '\n')
elif val1 == "f":
djurlista.sort(key=lambda x: x[attribut], reverse=True)
print(*djurlista,sep='\n' + ' ' + '\n')
except ValueError:
print("Svara med s för stigande eller f för fallande!")
sortering('age')
It appears that you're trying to get the .attribut parameter from a global class/obj called x (via x.attribut), which should be throwing an error if it doesn't exist, but may not be if it's stored in your python cli somehow.
If you remove the x. before the reference to attribut, do you still get the same error?

How do I return the value from each iteration of a loop to the function it is running within?

I'm making a program that scrapes local bus times from a real time information server and prints them. In order to return all the bus times, it does this:
while i < len(info["results"]):
print "Route Number:" + " " + info['results'][i]['route']
print "Due in" + " " + info["results"][i]["duetime"] + " " + "minutes." + "\n"
i = i + 1
This works fine, and returns all of the results, one by one like so:
Route Number: 83
Due in 12 minutes.
Route Number: 83
Due in 25 minutes.
Route Number: 83A
Due in 39 minutes.
Route Number: 83
Due in 55 minutes.
However, as I'm using this feature within another script, I turned the code to fetch times and return them into a function:
def fetchtime(stopnum):
data = "?stopid={}".format(stopnum)+"&format=json"
content = "https://data.dublinked.ie/cgi-bin/rtpi/realtimebusinformation"
req = urllib2.urlopen(content + data + "?")
i = 0
info = json.load(req)
if len(info["results"]) == 0:
return "Sorry, there's no real time info for this stop!"
while i < len(info["results"]):
return "Route Number:" + " " + str(info['results'][i]['route']) + "\n" + "Due in" + " " + str(info["results"][i]["duetime"]) + " " + "minutes." + "\n"
i = i + 1
This works, however it only returns the first bus from the list given by the server, instead of however many buses there may be. How do I get the printed result of the function to return the info supplied in each iteration of the loop?
Can you not just make a list and return the list?
businfo = list()
while i < len(info["results"]):
businfo.append("Route Number:" + " " + str(info['results'][i]['route']) + "\n" + "Due in" + " " + str(info["results"][i]["duetime"]) + " " + "minutes." + "\n")
i = i + 1
return businfo
You will have to edit the printing commands that this function returns to.
I would suggest you to use the yield statement instead return in fetchtime function.
Something like:
def fetchtime(stopnum):
data = "?stopid={}".format(stopnum)+"&format=json"
content = "https://data.dublinked.ie/cgi-bin/rtpi/realtimebusinformation"
req = urllib2.urlopen(content + data + "?")
i = 0
info = json.load(req)
if len(info["results"]) == 0:
yield "Sorry, there's no real time info for this stop!"
while i < len(info["results"]):
yield "Route Number:" + " " + str(info['results'][i]['route']) + "\n" + "Due in" + " " + str(info["results"][i]["duetime"]) + " " + "minutes." + "\n"
i = i + 1
It would allow you to pick one data at a time and proceed.
Lets say that info["results"] is a list of length 2, then you could do:
>> a = fetchtime(data)
>> next(a)
Route Number: 83 Due in 25 minutes.
>> next(a)
Route Number: 42 Due in 33 minutes.
>> next(a)
StopIteration Error
or simple do:
>> for each in a:
print(each)
Route Number: 83 Due in 25 minutes.
Route Number: 42 Due in 33 minutes.
# In case if there would be no results (list would be empty), iterating
# over "a" would result in:
>> for each in a:
print(each)
Sorry, there's no real time info for this stop!

python list duplicating instead of concatenating

class Rating():
def __init__(self, user, item, rating):
self.user = user
self.item = item
self.rating = rating
def __str__(self):
return str(user) + " " + str(item) + " " + str(rating)
def __repr__(self):
return str(user) + " " + str(item) + " " + str(rating)
data = open('data.dat').readlines()
records = ()
for i in data:
user, item, rating = i.split()
r = Rating(user, item, rating)
records += (r,)
print records
data = [A, B, C], I'd expect records to have (<Record> A, <Record> B, <Record> C). But instead it contains (<Record> C, <Record> C, <Record> C)?
You are not using the class attributes, but the global variables you have defined by chance.
return str(user) + " " + str(item) + " " + str(rating)
Should look like
return str(self.user) + " " + str(self.item) + " " + str(self.rating)
Your class's __str__ is reference global names:
def __str__(self):
return str(user) + " " + str(item) + " " + str(rating)
Which will be the last iteration of:
user, item, rating = i.split()
That needs to be fixed to be self.user, self.item etc...
Also I would change your line to be the more efficient and Pythonic:
records = [Rating(*line.split()) for line in data]

Categories

Resources