Calling a function in Pycharm - python

I am new in Python and I am currently learning OOP in Pycharm.
When I type in a simple function like type(mylist), I dont see the answer in the console, I have to add print in the beginning, same with any other function, although in the tutorials I am currently following, they just call the function by typing its name and adding a parameter.
Same with my first attribute (please see screenshots)
Please help me if you know how to get around it.

You need to separate the object instantiation from the print()
my_dog = Dog(mybreed='lab')
print(my_dog)

Instead of:
print(my_dog=Dog(mybreed='lab'))
You could either split it to two lines:
my_dog = Dog(mybreed='lab')
print(my_dog)
Or, if you don't need the my_dog variable:
print(Dog(mybreed='lab'))

In python variable_name = expression can't be regarded as expression to be used as parameter, so print(my_dog=Dog(mybreed='lab')) will raise an error.
You can sure finish your job by this way:
my_dog = Dog(mybreed='lab') # assign the variable my_dog
print(my_dog) # print the variable my_dog
If you don't need variable my_dog, you can just use print(Dog(mybreed='lab')), which will surely work.
If you do prefer assign a variable and pass it as a parameter (just like C++ does), you can use Assignment Expressions(also The Walrus Operator) := in Python 3.8 or higher version:
print(my_dog:=Dog(mybreed='lab'))
But just keep it in mind that this operator maybe not as convenient as you think!

Related

Python doesn't detect syntax error

I've been trying to sort an array of number using the sort function but I forgot to write parentheses.
arr.sort
instead of
arr.sort()
My question is why can't python detect this error and inform me like Java can?
The program kept compiling fine but because I was inputting the numbers in ascending order, the problem wouldn't show up.
arr.sort is syntactically valid. It's just not the syntax you wanted. Syntactically, arr.sort is an attribute access expression for the sort attribute of whatever arr evaluates to; semantically, when arr is a list, arr.sort evaluates to a method object for arr's sort method, so it's perfectly fine at runtime too.
It's kind of like method references in Java, but since Python is dynamically typed and has method objects, it doesn't need to go through all the functional interface and poly expression stuff Java 8 had to add to support list::sort syntax.
Syntax errors are only for outright invalid syntax.
Because it is not an error.
When you do not include () the function (or method) is not called. Instead it returns the function.
Example:
>>> str.encode
<method 'encode' of 'str' objects>
In actual practice:
import tkinter as tk
def hello():
print('hello')
tk.Frame()
a = tk.button(text="Press", command=hello)
a.pack()
tk.mainloop()
Now if you try it with command=hello() then it calls the function without you actually pressing the button.
The reason why Python can't detect this type of error is because Python is dynamically typed, whereas Java is statically typed.
When you say a = arr.sort, python assigns the function to a. Now you can do a() and it will run arr.sort. This is a totally valid thing to do in Python, and since we don't tell it ahead of time what a should be, it can't know whether you meant a to be a function or a sorted list... it just trusts you know what you're doing.
Java, on the other hand, is statically typed: You tell it ahead of time what a should be. Therefore, when you accidentally leave off parens, it says "that's a function, not a list like you said it would be".
If you use an IDE like PyCharm, it will tell you lots of warnings along these lines:
self.function shows:
Statement seems to have no effect and can be replaced with function call to have an effect
but the moment we assign it:
a = self.function it has an effect and this cannot be detected.

How can I avoid retyping long variable names in calling functions

How can I avoid lines like:
this_long_variable_name = this_long_variable_name.replace('a', 'b')
I thought I could avoid it by making a function, repl,
def repl(myfind, myreplace, s):
s = s.replace(myfind, myreplace)
print(s) # for testing purposes
return s
but because of stuff about the local vs. global namespaces that I don't understand, I can't get the function to return a changed value for this_long_variable_name. Here's what I've tried:
this_long_variable_name = 'abbbc'
repl('b', 'x', this_long_variable_name)
print('after call to repl, this_long_variable_name =', this_long_variable_name)
The internal print statement shows the expected: axxxc
The print statement after the call to repl show the unchanged: abbbbc
Of course, it works if I give up and accept the redundant typing:
this_long_variable_name = repl('b', 'x', this_long_variable_name)
BTW, it's not just about the length of what has to be retyped, even if the variable's name were 'a,' I would not like retyping a = a.replace(...)
Since in the function s is a parameter, I can't do:
global s
I even tried:
this_long_variable_name.repl('b', 'x')
which shows you both how little I understand and how desperate I am.
The issue you're running into is that Python strings are immutable. str.replace() returns an entirely new string, so in s = s.replace(myfind, myreplace), the name s no longer refers to the original string, which is why you don't see any change on the outside of the function's namespace.
There probably isn't a great solution to your problem. I recommend using a modern IDE or Python REPL with autocompletion to alleviate it. Trying to abuse the standard way of writing things like this may feel good to you, but it will confuse anyone else looking at your code.
Harry it does not work because inside your repl function you actually have a local copy of the content of your this_long_variable_name. This is called "pass by copy" which means python hands over a copy to the function. Unfortunately this is how python does it. Check also here:
Python: How do I pass a string by reference?
Also strings are immutable in python so if you wanna change them you always create a new modified version. Check here:
Aren't Python strings immutable?
Question would be why should you need long variable names in the first place?

Calling a function from a set variable? [duplicate]

This question already has answers here:
Calling a function from string inside the same module in Python?
(2 answers)
Python function pointer
(8 answers)
Closed 9 years ago.
Im writing a python script and what I would like to do is capture the input into a variable and then use that to call a function with that name. Here is an example:
def test():
print "You want to do a test!"
option = raw_input("What do you want to do? ") #User types in test
option()
Now this isnt working since python is not seeing option as a variable but rather is trying to call the function "option". What is the bast way to go about doing this?
eval() will work, but as #MattDMo said it can be dangerous.
A much safer way to do this, if your functions are module globals:
globals()[option]()
globals() is a dictionary mapping strings to the module global objects those strings are bound to. So globals()[option] looks up the string bound to option in that dict, and returns the object; e.g., globals["test"] returns the function object for test(). Then adding () at the end calls that function object. Bingo - you're done.
You want to be very careful about running arbitrary code, but if you absolutely need to, you can use the eval() function.
What might be a better way is to give your user a menu of options, then do testing on the contents of option to see which one they picked, then run that function.
You can use python eval.
From the help page, eval evaluates the source in the context of globals and locals. The source may be a string representing a Python expression or a code object as returned by compile().
For example:
def a():
print "Hello"
inp = raw_input()
eval(inp + "()")
On entering a at the stdin, the function a will be executed. Note that this could be dangerous without any safety checks.
This is, I suppose, an actual use for bare input:
option = input("What do you want to do? ") #User types in test
option()
This is semantically equivalent to eval(raw_input()). Note that in python 3, raw_input becomes input so you will explicitly have to eval it.
The usual caveats of this type of operation being incredibly unsafe apply. But I think that's obvious from your requirement of giving the user access to run arbitrary code, so...
I like using a dict in situations like this. You can even specify a default option if the user provides an answer that isn't expected.
def buy_it():
print "use it"
def break_it():
print "fix it"
def default():
print "technologic " * 4
menu = {"buy it": buy_it, "break it": break_it}
option = raw_input("What do you want to do? ")
menu.get(option, default)()

python object typecasting

Ive been trying search how to pass object reference in python and type cast it similar to Java but no to avail. I duno if this topic exists somewhere here.
My trouble is i have to pass the object reference to a class constructor. But i duno how to typecast the reference to an object. In java though I have accomplish this but i have to transfer the code to the server side.
many thanks,
Jack
class SearchRectangle:
def __init__(self, lower_left_subgrid_x, lower_left_subgrid_y, rectangle_width, rectangle_height):
self.min_subgrid_x = int(lower_left_subgrid_x)
self.max_subgrid_x = int(self.min_subgrid_x + rectangle_width -1)
self.min_subgrid_y = int(lower_left_subgrid_y)
self.max_subgrid_y = int(self.min_subgrid_y + rectangle_height -1)
...blah
class SearchRectangleMultiGrid:
# parent rectangle should be a SearchRectangle instance
def __init__(self, parent_rectangle):
self.parent_rectangle = SearchRectangle()parent_rectangle
# test codes
test_rect = SearchRectangle(test_subgrid.subgrid_x, test_subgrid.subgrid_y, 18, 18)
print "\n\nTest SearchRectangle";
print test_rect.to_string()
print test_rect.sql_clause
test_rec_multi = SearchRectangleMultiGrid(test_rect)
print "\n\nTest SearchRectangleMulti"
test_rec_multi.parent_rectangle.to_string()
Python is a dynamically typed language and as such, it doesn't make much sense to cast something unless you specifically need it in that type.
In Python you should use Duck Typing instead: http://en.wikipedia.org/wiki/Duck_typing
So instead of trying to convert parent_rectangle to a SearchRectangle() you should simply test if SearchRectangle() has the properties you need.
Or if you really want to be sure that you'll always get a SearchRectangle(), use isinstance like this:
if isinstance(parent_rectangle, SearchRectangle):
This might be a good read for you: http://dirtsimple.org/2004/12/python-is-not-java.html
There's no reason to cast anything in python. What are you trying to do? Just use the object like you would, and if it's not of the correct type it will fail. There's no such thing as casting since variable names don't have a type associated with them.
Further explanation:
Casting is the act of taking a pointer/reference to one type of object, and say to the compiler "Yeah, I know this is a foo reference but please pretend it is a bar reference".
Python do not have pointers/references in that sense (although in another sense, everything is references). Also, the compiler/interpreter doesn't care what the type is in the first place. Hence, casting is both impossible and pointless.
So in your example: Just skip the type casting. It'll work anyway. And if it doesn't. then make a question on that problem.

add a local variables to a function

is it possible to add a local varible to a function, just before calling it ? if yes how ?
EDIT:REASON
i noticed that all my views in django are using
render_to_response(template_name,locals())
now i created a middleware and i wanted to add one more local variable using the
def process_view():
method of it .so that i don't have to modify the views .
The local scope for a function does not exist until the function is called, so it's not possible to do this. You could do this for a closure, but the next person to have to maintain the code would hunt you down and kill you.
Although I also think it is pretty useless, I thought that you may enclose the function in either a 'with' statement or another function, like the code below. Of course, this approach can be accomplished directly within the function of interest. In fact, you are adding the local variable 'during' the function declaration. See if this fits your needs!
#!/usr/bin/python
def my_funct(_local):
"""My function of interest
"""
print "Local argument was %s" % str(_local)
return "Finished"
def localize(fct, local_var):
"""
"""
return fct(_local = local_var)
## Use function to 'localize' variable
localize(my_funct, local_var="LOCAL_VARIABLE")
## Same effect without supplementary function :
my_funct(_local="LOCAL_VARIABLE")
try:
print local_var
except:
print "No such global variable"
Just some thoughts :)
Cheers
So if you’re one of those lazy
programmers and you like keeping code
particularly concise, you can take
advantage of a built-in Python
function called locals(). It returns a
dictionary mapping all local variable
names to their values, where “local”
means all variables that have been
defined within the current scope.
source
It is a trick in order to not have to explicitly list all of the variables you need to pass in to the function. In this case, you need to explicitly state a variable to pass in. Therefore, you should not be using locals() in the calls you are making in your middle-ware, as the trick was not designed to be used like that.
i mangaged to do that using decorators.

Categories