Do Python functions modify their arguments? - python

I was in my computer science class today and the teacher put a piece of python coding on the board and said he couldn't figure out why it wasn't working. He was showing us functions and said:
def app(x):
x.append(" ")
print(x)
def ext(x,y):
x.extend(y)
print(y)
nums = [1,2,3,4,5,6]
numbers = [7,8,9,10]
app(nums)
ext(nums,numbers)
print("End of program")
The code was meant to show how when you don't type
return x
in the function then the variable doesn't change when you return to the main program however when he ran the program, the first function added the space and kept it there when it returned resulting in the following text being printed...
['1','2','3','4','5','6',' ']
['1','2','3','4','5','6',' ','7','8','9','10']
End of program
Please help me out.

You say that the point was to demonstrate that a list won't be changed unless it is returned. That is false. The list is a mutable object. When you pass it (by name) to a function and change it, it will be changed. If you don't want the change, you need to work with a copy.

def app(x):
return x + [" "]
def ext(x,y):
return x + y
might be what you are trying to do ... im not sure, this will not alter either of the original lists, but will return a new list as the result

Related

Store the return of a function in variable

I'm learning python, and I'm having trouble saving the return of a function to a specific variable. I have computed a simple function 'average' that is supposed to return the average value of a list. This works fine, however, when I try to store the result of average in a variable, I get told that x isn't defined.
def average(x):
return sum(x)/len(x)
var=average(x)
How do I store the return of the function in a variable?
Edit:
I misunderstood the task, which was simply to store the results of a specific computation in a variable.
x indeed is not defined
def average(x):
return sum(x)/len(x)
x = [1,2,3] # this was missing
var=average(x)
https://repl.it/join/eldrjqcr-datamafia
The function is a black box. You made the black box expect one mandatory input (x), therefore you have to provide it first i.e. var = average([1, 2, 3]).
Read the error message, x isn't defined. The variable x exists only in the average function and not in the program. You need to set x to something first.
e.g.
def average(x):
return sum(x)/len(x)
x=[1,2,3]
var=average(x)
this will not cause an error

Can i use PRINT function instead of RETURN at the end of every function i create? [duplicate]

This question already has answers here:
What is the purpose of the return statement? How is it different from printing?
(15 answers)
Closed 3 years ago.
i just can not understand the importance of return at the end of functions.with return u have to type print(function()) anyways so why cant we just type print(value) at the and of the function and when we need to use that function just call it like function()?
def example():
value = 5+5
print(value)
example()
print and return are not doing the same thing. The former is displaying information to the user, while the latter is giving a raw value out of a function. Consider the following:
>>> def print_10():
... print(10)
...
>>> def return_10():
... return 10
...
>>> print(return_10() + return_10())
20
>>> print(print_10() + print_10())
Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'
return_10 gives back the number 10, while print_10 prints the value 10 to the console and returns None (since you don't specify a return value). Trying to use that value elsewhere is possible (None is a valid result), but it probably doesn't do what you want it to do.
Thinking of this in explicit typing makes this very clear:
def print_10() -> None:
print(10)
def return_10() -> int:
return 10
the print statement only prints what is inside the Parenthesis to the console to be seen and can't be stored in variables or do any operations on it as it is a NoneType
i will show you with an example:
def example():
a = 5
b = 6
print(a + b)
x = example() + 5
print(x)
the above code will return a TypeError.
but if you change it to this:
def example():
a = 5
b = 6
return(a + b)
x = example() + 5
print(x)
you get 16
if you want to display info and not use it again use print else use return
There's a principle called separation of concerns that proposes that each unit of code (function, class, module, etc.) should be responsible for doing just one thing (where the definition of "one thing" is flexible to account for the size of the unit of code being discussed). The benefit is that code that follows this principle is easier to test, debug, combine, and reuse.
If you write a function that prints its result, it is harder to reuse that code in situations where you don't want to print the result, but rather use it in some other way. The function is doing two things: calculating its result, and printing it. If you don't want it to do the second thing, or want it to do the second thing in a slightly different way, you are S.O.L. On the other hand, if the function just calculates its result, doing just one thing, the caller can easily print it if that's what they want.
That said, if you often find yourself printing a result, then it might make sense to provide a second function that calls the first and prints the result, especially if printing it is complicated. But having the first function available is a win for future code reuse.
Some development methodologies advise you to write the simplest thing that works. But I think preserving separation of concerns is an obvious and logical reason to ignore this advice in many cases.

How to implement a class (function) upon pressing a key?

I have a function in my code:
X = []
Y = [1,2,3,4]
class DATA():
def __init__(self):
X.append(Y)
DATA()
print (X)
When I run my code, I want this class (named DATA) to be implemented only when I press the Enter key. Any idea how I can do it? (A simple example is appreciated!).
This was hard to answer for a couple reasons:
You keep using the word "implement", but I'm pretty sure you mean "call" instead. I'm going to assume that here, since conditionally implementing something is rarely needed.
Your use of the class here is confusing. It isn't actually needed in this case, so it's just complicating things. I'm going to reduce it down to just:
def DATA():
X.append(Y)
Since that does the same thing as your existing code.
To ask for user input, use input. input waits until the user presses Enter, then returns the typed text. You can use it here to wait for Enter to be pressed:
x = []
y = [1,2,3,4]
def data():
x.append(y)
print("x before Enter is pressed:")
print(x)
input("Type Enter to continue...")
data() #Call DATA similar to your original code
print("x after Enter is pressed:")
print(x)
A couple extra notes:
Function and variables names should be in lower case. Uppercase is reserved for class names, and even in those cases, only the first letter is uppercase.
Ideally, you shouldn't be mutating global variables like x and y. They should be passed into the function, then the result should be returned.

At which level do return statements need to be written if there is also an 'if' statement above it?

Let me preface this by saying that I am fairly new to coding, so be gentle.
I have been writing the following:
def execute_move(player, house_choice, houses):
next_house=houses[house_choice]
chosen_house=houses[house_choice-1]
chosen_house_seeds=chosen_house[1]
for i in range(chosen_house_seeds):
if player=='P1': # skips the store of the opposite player
if next_house==houses[13]:
next_house_index=houses.index(next_house)
new_nhi=next_house_index+1
next_house=houses[new_nhi]
elif player=='P2':
if next_house==houses[6]:
next_house_index=houses.index(next_house)
new_nhi=next_house_index+1
next_house=houses[new_nhi]
[(next_house[0], (next_house[1]+1)) if x==next_house else x for x in houses]
next_house_index=houses.index(next_house)
new_nhi=next_house_index+1
next_house=houses[new_nhi]
[(chosen_house[0], (chosen_house[1]-chosen_house_seeds)) if x==chosen_house else x for x in houses]
return houses
My aim is to replace some of the tuples in the list 'houses', and then return the new list of tuples.
For some reason the var I assign the call to later on in the code only produces the original list when printed.
Im thinking that it may have something to do with the indentation of the 'if' statements or the indentation of the return statement.
Help much appreciated!
There is nothing intrinsically special about a return statement when compared to other Python statements.
As such, you should indent it as you would any other (i.e., by placing the return line inside the block that makes sense in your specific algorithm).
Any control structure (such as an if statement) expects the next line to be indented. The control structure ends when the code begins to go back to the original level
https://docs.python.org/3/reference/lexical_analysis.html#indentation
def function(input):
input = input * 2
if (input > 5):
input * 2
return input
input +1
return input
so in this case, if the input is < 2.5, it is returned doubled + 1. If it is >2.5 it is returned * 4
It is probably just a bad cut and paste, but the body of the function must be indented as well.
Your list comprehension statements, those that look like [(next_house[0], ...] are building lists but it's not assigned to anything so it is being discarded. Try setting result to a variable...
list_of_next_house_tuples = [(next_house[0], (next_house[1]+1)) if x==next_house else x for x in houses]
Then determine what you are going to do with this new list.

How to create a list containing names of functions?

I am completely new to python and programming but I am trying to learn it using more practical approach.
What I am trying to do is an exercise for converting different units, e.g. pounds -> kilograms, foot -> meter etc.
I have defined all the functions for different unit pairs:
def kg_to_g(value):
return round(value*1000.0,2)
def g_to_kg(value):
return round(value/1000.0,2)
def inch_to_cm(value):
return round(value*2.54,2)
def cm_to_inch(value):
return round(value/2.54,2)
def ft_to_cm(value):
return round(value*30.48,2)
etc.
and created a list with names of these functions:
unit_list = ['kg_to_g','g_to_kg','inch_to_cm','cm_to_inch',
'ft_to_cm','cm_to_ft','yard_to_m','m_to_yard',
'mile_to_km','km_to_mile','oz_to_g','g_to_oz',
'pound_to_kg','kg_to_pound','stone_to_kg','kg_to_stone',
'pint_to_l','l_to_pint','quart_to_l','l_to_quart',
'gal_to_l','l_to_gal','bar_to_l','l_to_bar']
The program should randomly choose a unit pair(e.g. kg->pounds) and value (e.g. 134.23), and the user will be asked to convert those values.
random_unit = random.choice(unit_list)
lower = 0.1001
upper = 2000.1001
range_width = upper - lower
ranval = round(random.random() * range_width + lower, 2)
When user enters answer, the program should compare answer with the calculations defined by function and tell user if it is a correct answer or wrong answer:
def input_handler(answer):
if answer == random_unit(ranval):
label2.set_text("Correct!")
else:
label2.set_text("Wrong!")
Unfortunately, that way program doesn't work, and codesculptor(codesculptor.org) returns with an error
TypeError: 'str' object is not callable
Could someone please explain to me what is wrong with the code and suggest something to solve the problem.
Because you've enclosed the function names (in the list) in quotes, they have become strings.
Change your list to:
unit_list = [kg_to_g, g_to_kg, inch_to_cm, cm_to_inch,
ft_to_cm, cm_to_ft, yard_to_m, m_to_yard,
mile_to_km, km_to_mile, oz_to_g, g_to_oz,
pound_to_kg, kg_to_pound, stone_to_kg, kg_to_stone,
pint_to_l, l_to_pint, quart_to_l, l_to_quart,
gal_to_l, l_to_gal, bar_to_l, l_to_bar]
And now it is a list of functions, which can be called like this: unit_list[0](34), for example.
So now random_unit(ranval) should not throw an exception.
Note also that comparing floats (if answer == random_unit(ranval)) will most likely cause you problems. See Is floating point math broken? for some detailed explanations of why this is.
As you are rounding you may get away with it, but it's good to be aware of this and understand that you need to deal with it in your code.
I think this is what you are asking about. You should be able to store the functions in a list like this
unit_list = [kg_to_g, g_to_kg, inch_to_cm, cm_to_inch, ft_to_cm]
You can then call each item in the list and give it a parameter and it should execute the function for example like this:
unit_list[0](value)

Categories

Resources