Simple Function does not work, dont see the error - python

I am a beginning python programmer, but have written several scripts including ones in which I define my own functions and use them. I cannot seem to get any user defined functions to work within the IDLE. Wondering if I am crazy/dumb. Can somebody please explain the following results?Thanks:
def f(x,y):
solution = x+y
return solution
f(2,2)
SyntaxError: invalid syntax
>>> a = f(2,2)
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
a = f(2,2)
NameError: name 'f' is not defined
def g(x):
solution = x + 2
return solution
g(2)
SyntaxError: invalid syntax
>>> a = g(2)
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
a = g(2)
NameError: name 'g' is not defined

Add a blank line after the definition of the function to make the interpreter understand that it's finished.
>>> def f(x,y):
solution = x+y
return solution
>>> f(2,2)
4

Related

Why lambdify never stops?

x = symbols('x')
ch = 'exp(cos(cos(exp((sin(-0.06792841536110628))**(-6.045461643745118)))))'
f = lambdify(x, ch, "numpy")
print(float(f(2)))
It does not work, the programm is running and never ends(no error is issued).
My goal is to avoid this kind of cases (among multiple cases) by doing a try/except but i can't as there is no error
Why no error is released?
How can i avoid these cases ?
Thanks for your helping me !
In general, I'm not sure you can. SymPy or NumPy will keep trying to compute the number until precision is exhausted. But you can create a function that will raise and error if numbers are out of bounds for your interest:
>>> from sympy import cos as _cos, I, exp
>>> def cos(x):
... if abs(x) > 10**20: raise ValueError
... return _cos(x)
>>> exp(cos(cos(exp(5*(1+I)))))
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "<string>", line 2, in cos
ValueError
>>> f = lambda x: exp(cos(cos(exp(x))))
>>> f(sin(-0.06792841536110628)**-6.045461643745118)
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "<string>", line 1, in <lambda>
File "<string>", line 2, in cos
ValueError
But you have to think carefully about when you want to raise such an error. For example, SymPy has no trouble computing f(100) or f(100*I) if the non-error-catching cos is used. So think about when actually you want the error to rise.
lambdify is a lexical translator, converting a sympy expression to a python/numpy function.
Make a string with a symbol:
In [27]: ch = 'exp(cos(cos(exp((sin(x))**(-6.045461643745118)))))'
sympify(ch) has no problem, because it doesn't need to do any numeric calculation. So lambdify also works:
In [28]: f=lambdify(x,ch)
In [29]: f?
Signature: f(x)
Docstring:
Created with lambdify. Signature:
func(x)
Expression:
exp(cos(cos(exp((sin(x))**(-6.045461643745118)))))
Source code:
def _lambdifygenerated(x):
return (exp(cos(cos(exp(sin(x)**(-6.045461643745118))))))
The equivalent mpmath:
def _lambdifygenerated(x):
return (exp(cos(cos(exp(sin(x)**(mpf((1, 54452677612106279, -53, 56))))))))
And a working numeric evaluation:
In [33]: f(0j)
Out[33]: mpc(real='nan', imag='0.0')

assign value to a variable using eval in a metaprogramming manner

I want to assign value to a variable using eval in a metaprogramming manner. My attempt was shown below:
sample = None
var_name = "sample"
value = 0
eval("{0} = {1}".format(var_name, value))
However, I got the following error:
Traceback (most recent call last):
File "tmp.py", line 4, in <module>
eval("{0} = {1}".format(var_name, value))
File "<string>", line 1
sample = 0
^
SyntaxError: invalid syntax
Could you explain how can I do this? I think lower level function like assign(var, val) could exist and this enabled assignment using eval. But I couldn't find such function.
Use exec instead:
sample = None
var_name = "sample"
value = 0
exec("{0} = {1}".format(var_name, value))
eval is for evaluating an expression, not an assignment statement
does exec accomplish what you're trying to do?:
sample = None
var_name = "sample"
value = 5
exec(f"{var_name} = {value}")
print(sample)
output: 5
If you're outside a function you can use
globals()[varname] = value
Example:
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> globals()['a'] = 5
>>> a
5
Inside a function there's locals() but it can only read from the symbol table and not update so you should use eval() like other answers have pointed out.
You can also cheat by using setattr/hasattr/getattr on an object:
>>> class Object:
... pass
...
>>> obj = Object()
>>> obj.a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Object' object has no attribute 'a'
>>> setattr(obj, 'a', 3)
>>> obj.a
3

How to call variable from another function by declaring global in python?

func 1
def num1():
global h
h=7
func 2
def num2():
print(h)
When I call this function:
num2()
Here, it should print the value of h which is globally declared in func 1.
But it is giving NameError why?? Anyone answer me plz..
to access the global variable h through num2() make sure to call num1() before calling num2()
Defining num1 doesn't actually define h. The definition of num1 just says that, when you call num1, it will assign to the global name h. If h doesn't exist at that time, it will be created. But defining num1 isn't sufficient to create h.
You need to ensure that h exists before num2 is called. You can do that by assigning to h yourself, or calling num1.
>>> num2()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in num2
NameError: name 'h' is not defined
>>> h = 3
>>> num2()
3
>>> del h
>>> num2()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in num2
NameError: name 'h' is not defined
>>> num1()
>>> num2()
7

How does the `j` suffix for complex numbers work? Can I make my own suffix?

I know what are complex numbers and how they mathematically work, but how is it done for python to know it's complex just by putting a j after a digit ?
>>> j
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'j' is not defined
>>> 1*j
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'j' is not defined
>>> 1j
1j
>>> 1j**2
(-1+0j)
Can I make my own suffix, let's say p (for strictly positive) ?
Could I do something working like this ?
>>> ... some weird stuff here ...
>>> p
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'p' is not defined
>>> 1*p
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'p' is not defined
>>> -1p
1p
>>> 0p
1p
>>>
This is built into Python's grammar, just like the decimal point is, or the e in scientific notation (1e10 etc.). The j makes a numeric literal imaginary.
Python does not allow you to change this. That doesn't mean you can't--you could amend the grammar--but then the language is no longer Python.
The closest approximation allowed in Python would be by implementing an operator.
>>> class StrictlyPositive:
def __rmatmul__(self, number):
return abs(number)
>>> p = StrictlyPositive()
>>> -1#p
1
But you have to be careful of operator precedence when doing stuff like this. Why not just use the builtin abs directly?

Error while calling Python function

I defined a function which takes 2 arguments. When I call the function, I get an error saying not enough argument:
>>> def fib(self, a,b):
... self.i=a, self.j=b
... print self.i+self.j
...
>>> fib(4,8)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: fib() takes exactly 3 arguments (2 given)
>>> fib(4,8,9)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in fib
AttributeError: 'int' object has no attribute 'i'
I passed with both 2 and 3 arguments. What should be the third argument?
I am assuming you don't understand self very well in python. Its heading towards OOP (Object oriented programming).
non-OOP approach (doing the same thing with static methods)
def fib(a,b):
print a+b
fib(4,8)
OOP approach
class Test():
i = 0
j = 0
def fib(self, a,b):
self.i=a
self.j=b
print self.i+self.j
t = Test() # create an object of Test class
t.fib(2, 3) # make the function call
NOTE : python considers a function to be a static function if it does not have the keyword self as the first parameter
You function has 3 arguments: self, a and b.
self is traditionally used for methods.
You write (simplified example):
class A:
def multiply(self, b): # method called with one argument
return 2 * b
a = A()
a.multiply(3)
or
def multiply(b): # this is a function with one argument
return 2*b
mutiply(3)

Categories