What's the point of defining a function to print something? - python

For example, in my Codecademy it says,
def spam():
print ("Eggs!")
but I feel like you could just print Eggs! if you wanted without the def spam():
Somebody please help

But you could do:
def spam():
print("Eggs!")
And then call spam a thousand times in your code. Now, if you want to change that to print "Bacon!" you only have to change it once, rather than a thousand times.
def spam():
print("Bacon!")

Def helps to make your code reusable. In this case, we can think that it's useless indeed. But in other case, you'll want to be able to call a part of code multiple time !

In this case you're right, there is no reason to create a function for just print, but when you get to more complex writing a function saves you a lot of precious time and space. For example I want to get a specific part of a .json with API, instead of writing all these lines again and again I will write it once and call it whenever I need it.

Best practice would be to define the string once and call the function as many times as needed. It will be easier to maintain. Yes, you can find and replace all instances, but you risk accidentally changing more than you bargained for. Additionally, if you were working on a shared project and someone were to merge code after you made that change, you’d have to go back and update all their new code to reflect the change. If they had just been calling spam(), there’s no update needed post-merge.

Usually it is for demonstration/illustration purposes. Once the code flow reaches the function, you'll get the message printed. Sometimes it is important to understand the sequence of calling the functions or just the fact that the function has been called.

Related

Is this the best method to split Python code into dependent modules?

I have a program I'm writing. It's becoming too large to manage well: it has a lot of code related to GUI functionality (PyQt5), and it's nearly 2000 lines. I understand that in Python, it is acceptable to have large scripts that are coded completely in one file, but writing this program has become unmanageable. I can't easily organize the code in one file. I previously tried to split it into multiple files (using methods I'd found here on StackOverflow), but to no avail. I finally just realized what I might have to do for my situation. (I know that realistically, you'd never split the following into two files, but I'm using it as an example.) Here is a very simple example of a script split in two (file 1):
# TestProg.py
class Name:
def __init__(self, name):
self.name = name
def testfunc():
nm.name += nm.name[int(len(nm.name)/2):] # Add to name, second half of name
return nm.name
if __name__ == '__main__':
import TestModule
print(TestModule.returnName(TestModule.nm))
input()
File 2:
# TestModule.py
import TestProg
Name = TestProg.Name
testfunc = TestProg.testfunc
nm = Name('Henry')
def returnName(name):
return name.name[::-1] + testfunc()
If you try running this, it won't work. I finally figured out it's because of the fact that testfunc is defined in TestProg and uses a global variable (which isn't defined in TestProg). To solve this problem, you must modify the globals dict of testfunc, with testfunc.__globals__['nm'] = nm, and place that in TestModule right after you define nm.
I understand this is not a pretty thing to do, but it seems to be the best way I can think of to do it. Now, I know, "Just use a local variable/parameter for testfunc, instead of global." The thing is, it is a global variable (which needs to be defined in a file separate from the function in the split). I don't want to have to pass the variable to the function every time, that's very tedious, repetitive, and a waste of time. My question is: is there a better way to do it? I would assume no. A secondary question is: is this method acceptable? Is it considered a hack/highly unpythonic, and therefore unwise to use?
Please remember, I really need the file to be split, but I can't really split it any nicer than that which requires this method to work (as far as I know).

Python 3: Can we avoid repeating an instance name when calling several of its methods?

I now (or so I have read) that it is not possible in Python 2.x, and can't find it for Python 3 either, but maybe I don't know how to search for it...
It easier to explain it with a simple Python example:
for i in range(11):
one_turtle.penup()
one_turtle.forward(50)
one_turtle.down()
one_turtle.forward(8)
one_turtle.up()
one_turtle.forward(8)
one_turtle.stamp()
one_turtle.forward(-66)
one_turtle.left(360/12)
I'd like to avoid repeating "one_turtle" the same way you can do in VBA, which it would result in something similar to this:
For i = 1 To 11
With one_turtle.penup()
.forward(50)
.down()
.forward(8)
.up()
.forward(8)
.stamp()
.forward(-66)
.left(360/12)
The code resulting from the With keyword is much clearer and easy to write and read (it'll need an End With and a Next lines but I wanted to focus the discussion). One of the main reasons I have decided to learn Python is because it is said to be very neat and "zen-like" to program. Is it really not possible to do this?
In your definition of all these member-methods, simply return self.
eg. Change definition of penup() like this:
def penup(self):
# Your logic
return self
The ideal solution is I think already posted, returning self is simply the cleanest way. However if you're not able to edit the turtle object or whatever, you can create an alias:
forward = one_turtle.forward
... some code ...
forward()
Now the function forward just applies forward to one_turtle, simple example
s = "abc"
x = s.upper
print(x()) # prints "ABC"

Python "with" statement but no "as" [duplicate]

I just realized there is something mysterious (at least for me) in the way you can add vertex instructions in Kivy with the with Python statement. For example, the way with is used goes something like this:
... some code
class MyWidget(Widget)
... some code
def some_method (self):
with self.canvas:
Rectangle(pos=self.pos, size=self.size)
At the beginning I thought that it was just the with Python statement that I have used occasionally. But suddenly I realize it is not. Usually it looks more like this (example taken from here):
with open('output.txt', 'w') as f:
f.write('Hi there!')
There is usually an as after the instance and something like and alias to the object. In the Kivy example we don't define and alias which is still ok. But the part that puzzles me is that instruction Rectangle is still associated to the self.canvas. After reading about the with statement, I am quite convinced that the Kivy code should be written like:
class MyWidget(Widget)
... some code
def some_method (self):
with self.canvas as c:
c.add (Rectangle(pos=self.pos, size=self.size))
I am assuming that internally the method add is the one being called. The assumption is based that we can simply add the rectangles with self.add (Rectangle(pos=self.pos, size=self.size))
Am I missing something about the with Python statement? or is this somehow something Kivy implements?
I don't know Kivy, but I think I can guess how this specific construction work.
Instead of keeping a handle to the object you are interacting with (the canvas?), the with statement is programmed to store it in some global variable, hidden to you. Then, the statements you use inside with use that global variable to retrieve the object. At the end of the block, the global variable is cleared as part of cleanup.
The result is a trade-off: code is less explicit (which is usually a desired feature in Python). However, the code is shorter, which might lead to easier understanding (with the assumption that the reader knows how Kivy works). This is actually one of the techniques of making embedded DSLs in Python.
There are some technicalities involved. For example, if you want to be able to nest such constructions (put one with inside another), instead of a simple global variable you would want to use a global variable that keeps a stack of such objects. Also, if you need to deal with threading, you would use a thread-local variable instead of a global one. But the generic mechanism is still the same—Kivy uses some state which is kept in a place outside your direct control.
There is nothing extra magical with the with statement, but perhaps you are unaware of how it works?
In order for any object to be used in a with statement it must implement two methods: __enter__ and __exit__. __enter__ is called when the with block is entered, and __exit__ is called when the block is exited for any reason.
What the object does in its __enter__ method is, of course, up to it. Since I don't have the Kivy code I can only guess that its canvas.__enter__ method sets a global variable somewhere, and that Rectangle checks that global to see where it should be drawing.

Can I use same argument names when passing arguments in Python

Can you please help me guys. I believe I've got pretty easy questions but don't want to stuff up with my assignment. I'm going to have Class in my module, this class will have few functions.
I just want to be sure it works alright and this is a not ugly code practice.
I.e. my first function test_info accepts one parameter test_code and returns something and the second function check_class accepts two parameter, one of them is called test_code as well
Can I use same argument name: test_code? Is it normal code practice?
def test_info (self, test_code):
my_test_code = test_code
#here we'll be using my_test_code to get info from txt file and return other info
def check_class (self, test_code, other_arg):
my_test_code = test_code
#here some code goes
Also is it fine to use my_test_code in both functions to get argument value or is it better to use different ones like my_test_code_g etc.
Many thanks
Yes you may.
The two variables test_code are defined only in the scope of their respective functions and therefore will not interfere with one another since the other functions lie outside their scope.
Same goes for my_test_code
Read online about variable scopes. Here is a good start
There is no technical reason to resolve this one way or another. But if the variables don't serve exactly the same purpose in both functions, it's confusing for a human reader if they have the same name.

Is it pointless to receive a parameter/argument and do nothing with it?

I'm learning python from a textbook. This code is for the game Tic-Tac-Toe.
The full source code for the problem:
http://pastebin.com/Tf4KQpnk
The following function confuses me:
def human_move(board, human):
""" Get human move."""
legal = legal_moves(board)
move = None
while move not in legal:
move = ask_number("Where will you move? (0 - 8): ", 0, NUM_SQUARES)
if move not in legal: print "\nThat square is already taken. Choose another.\n"
print "Fine..."
return move
I do not know why the function receives 'human' parameter. It appears to do nothing with it.
def human_move(board, human):
How would I know to send 'human' to this function if I were to write this game from scratch? Because I can't see why it is sent to this function if it isn't used or returned.
The answer: it depends. In your example it seems useless to me, but I haven't checked it in depth.
If you create a function to be used only from your code, it is in fact useless.
def calculate_money(bank_name, my_dog_name):
return Bank(bank_name).money
money = calculate_money('Deutsche bank', 'Ralph')
But if you are working with some kind of API/Contract, the callbacks you specify might accept arguments that are not needed for a certain implementation, but for some others, are necessary.
For instance, imagine that the following function is used in some kind of framework, and you want the framework to show a pop up when the operation is finished. It could look something like this:
def my_cool_callback(names, accounts, context):
# do something blablab
context.show_message('operation finished')
But what if you don't really need the context object in your callback? you have to speficy it anyway for the signature to match... You can't call it pointless because that parameter is used sometimes.
EDIT
Another situation in which it could be useful, would be to loop through a list of functions that have almost the same signature. In that case could be ok also to have extra arguments as "garbage placeholders". Let's say all your functions need 3 arguments in general, but one needs only 2.

Categories