Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm trying to use a list of values to alter a bunch of class values that I added to another (temporary) list.
class game_events():
def __init__(self):
self.stage = 0
self.rules = False
saved_vars = [12, True]
game = game_events()
i = 0
for x in [game.stage, game.rules]:
x = saved_vars[i]
i+=1
It seems like everything is working, but that only the temporary list is being altered, like a decoy.
Desired results:
game.stage == 12
game.rules is True
Actual results:
game.stage == 0
game.rules is False
Any ideas?
When you do x = saved_vars[i], you're rebinding the variable x, not modifying the game object where it's previous value came from. If you want to modify just a few attributes on game, it's a whole lot easier to just do so directly:
game.stage, game.rules = saved_vars[0:2]
If you have a whole lot of attributes to go through, rather than just two in this example, you might return to your loop idea, but you'd need to do it differently. Rather than an assignment, you'd need to use setattr. And that means you'll need to specify the name of the attributes as strings, not with dotted notation:
for attr, value in zip(['stage', 'rules'], saved_vars):
setattr(game, attr, value)
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 11 months ago.
Improve this question
My problem is very small, and is that I can't do a normal letter substitution. I know the .replace command, but I can't seem to use it correctly.
For example: My k##yb0%%rd is br###k##n. ### should be replaced with o, ## with e, and %% with a. Thanks!
a = input("What did she say? ")
b = a.replace("###", "o")
print(b)
You can try something like this:
a = input("What did she say? ")
d = {'###':'o', '##':'e','%%':'a'}
for k,v in d.items():
a = a.replace(k, v)
b = a # if you need value in b variable
print(b)
You can create such dictionary and use it replace multiple values. Make sure to properly arrange your dictionary.
As the first thing I would suggest to read the Python's documentation for str.replace.
I would suggest something like this:
b = a.replace("###", 'o').replace("##", 'e').replace("%%", 'a')
This is possible because the returned value of a.replace("###", 'o') is of type str, so that the method replace can be applied on it too.
If you don't know which characters will be replaced, you should do like suggested by Vaibhav, creating a dict that associates old chars (key) with new chars (value).
What's more str is an immutable type, so you can't just do
a.replace("###", 'o').replace("##", 'e').replace("%%", 'a')
but anyway you don't have to assign the returned value to b, you can't reassign it to a without problems:
a = a.replace("###", 'o').replace("##", 'e').replace("%%", 'a')
and you can print it directly too.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I'm trying to do something like this:
def func(varname):
varname = 1
func(x)
print(x)
But I get NameError: name 'x' is not defined
No, the syntactical construct you seem to be interested in is not possible. The reason is that function parameters are copies of the value (or reference) of the variable you pass in. Changing the value (or reference) of varname cannot change the value (or reference, for mutables) of x.
Now, the behavior that you want is totally possible. As a general rule, in order to have a function create a value and then assign that value to a variable name of your choice you use a return statement:
def funcname():
return 1
x = funcname()
print(x)
You need to declare the thing you are putting into the function as a parameter.
You should also actually do something with the value you are changing in the method.
In your example
def func(varname):
varname = 1
return varname #Return whatever you do to the input
x=3
x =func(x) #Do something with the value returned from your method
print(x)
Mostly the information you get back from a function is what is given in the return value. It's possible, even common, for functions to make changes in mutable data structures that they are passed (e.g. a list), especially where this is capturing state information or updating on the basis of other information handled by the function. And if you rearrange the contents of a list, the list elements will certainly have different values when the function exits.
Certainly you could do this:
def square_it(varname):
return varname*varname
x = square_it(3)
print(x)
giving output of 9, of course. You can also assign x to something else so that they now both have the same value
y = x
x = square_it(y)
which in some senses "changes the name" of what is referring to the value 9 to y, and moves x on to refer to something else.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm trying to make an average but for some reason when I try to make one it doesn't work.
I have global variables and array defined at the begining of my document :
vent_moyenne_km = []
compteur_moyenne=0
I have one of my function that is called every X time. In that one, I calculate a velocity with some value that are display on a label of my interface. that part is working, but not the mean
global compteur_moyenne
compteur_moyenne += 1
ventkmh = (vent_1[3][0]*256 + vent_1[4][0]) /100 *3.6
label_vent2_2.config(text= "%.2f" % ventkmh)
vent_moyenne_km.append("%.2f" % ventkmh)
vent_1.clear()
if compteur_moyenne == 5:
compteur_moyenne = 0
print(vent_moyenne_km)
label_vent4_2.config(text=statistics.mean(vent_moyenne_km))
vent_moyenne_km.clear()
of course in my imports I have :
import statistics
When I comment the line label_vent4_2.config(text=statistics.mean(vent_moyenne_km)), everything works and I see in the terminal my array with 5 values. I also tried numpy and even tried to make a for items in array: then add then manually, and everytime I get the error : class 'IndexError'
I'm really not sure how to fix that.
For calculating an average of a list just use numpy:
def function():
value = random.randint(0,1)
return value
list = []
for i in range(100):
list.append(function())
if i%5 == 0:
print(np.average(list))
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Am i must to use here else: or i have opportunity to remove it and just type return True
def some_function(x):
if another_function(x) == -1:
return False
else:
return True
EDIT: I know how to make this code compact with just one return. The main question is about else:.
Should i always use 'else:' even it is not necessary?
I myself believe that they are not necessary. Returning at the beginning of the function in case of edge cases is something that allows you to skip sometimes lots of indentations caused by elses:
def some_function(x):
if edge_case_1:
return []
if edge_case_2:
return None
#a
#lot
#of
#code
#here
return result
looks better than
def some_function(x):
if edge_case_1:
return []
elif edge_case_2:
return None
else:
#a
#lot
#of
#code
#here
return result
right?
But it's not only about the looks:
Elses like that make you easily confuse the indentation levels.
The line width becomes smaller because the indentation takes those few character, you might need to format your code more to fit PEP8.
Sometimes you write the main part of the code first, only to discover the edge cases later. Version control systems such as git would mark all indented lines as changed (depending on the configuration), while the only thing you did was add those ifs at the beginning!
you can remove else and do like this:
def some_function(x):
if another_function(x) == -1:
return False
return True
Logically you can write
def some_function(x):
return another_function(x) != -1
else is not mandatory syntactically but there are few cases where you will get error
declare default value:-
var1 = some_value
if condition:
var1 = "something"
return var1
For the general case: since the return exits the function at this point and return control to the caller, the prefered idiom is :
def foo(x):
if <some_expression>:
return <something>
# we'll only ever get here if `<some_expression>`'s value is false
return <something_else>
As to why it's the prefered idiom (in python at least): the general consensus is that it makes the code more readable by 1/ flattening it (less indentation levels) and 2/ getting rid of all corner cases right from the start so the nominal case code is not polluted by such considerations. As a general rule, the simpler the code (and "flat" code is simpler than nested one, at least for the human brain) the easiest it is to understand.
Now for your own case where you are returning the boolean value of an expression, you don't even need a if statement at all - you can just directly return the result of evaluating the expression:
def foo(x):
return some_test(x) != some_value
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have a class that contains different member variables, one of which is a list of dictionaries. I have to perform some operations on that list such as:
finding and replacing some elements
adding a new key value to some dictionaries in that list
removing some empty key values from some dictionaries in that list
etc.
I initially did different functions where each function performs a certain task on the list of dictionaries (Option1). I then realized that in each of these functions I am doing the same looping over the same list. I thought it would be more performant if I looped once over the loop and did all the tasks I needed to do in there. So, I created different functions that do the operations that I want to do on the element level instead of the list level as shown in Option2.
Calling a function also takes a certain overhead, so my question would be: is it better from a performance perspective to go with Option1 or Option2? Which option would the compiler better optimize? What about from a code maintainability and readability perspective?
Option1
def add_status(self):
for element_dict in self.list_of_dicts:
element_dict["status"] = function_to_add_status()
def replace_id_with_name(self):
for element_dict in self.list_of_dicts:
element_dict["name"] = function_to_get_name()
element_dict.pop("id")
def remove_empty_elements(self):
for k, v in list(element_dict.items()):
if v == "null":
del element_dict[k]
def clean_up(self):
self.add_status()
self.replace_id_with_name()
self.remove_empty_elements()
Option2
def add_status(element_from_list_of_dicts):
element_from_list_of_dicts["status"] = function_to_add_status()
def replace_id_with_name(element_from_list_of_dicts):
element_from_list_of_dicts["name"] = function_to_get_name()
element_dict.pop("id")
def remove_empty_elements(element_from_list_of_dicts):
if element_from_list_of_dicts.item() == "null":
del element_from_list_of_dicts[k]
def clean_up(self):
for element_dict in self.list_of_dicts:
self.add_status(element_dict)
self.replace_id_with_name(element_dict)
self.remove_empty_elements(element_dict)