Returning None after conditional - python

Trying to return the math.floor of k, which is 2
import numpy as np
import math
j = 1
def k(j):
k = j + 1.2
return k # 2.2
def foo2():
num = k(j)
floor = math.floor(num)
threshold = 5.1
a = 22.5094
i = np.arange(threshold, 50)
if a in i:
return floor
print(foo2())
It worked without conditional
import math
j = 1
def k(j):
k = j + 1.2
return k #2.2
def foo2():
num = k(j)
b = math.floor(num)
return b
print(foo2())
If you spot where I made a wrong assumption, do share please.

Try add line: print(a, i)
after: i = np.arange(threshold, 50)
You will see that a doesn't belong to i, and becouse of this if that is in the next line will not execute return function, becouse as we saw earlier there is no any value in list i that is equal to value of a.
And if return in function isn't executed then function will return None.

Related

Need an OOP method for share variable between function?

I have a class and some functions. In the 'check_reflexive()' function, there is a variable called reflexive_list. I want to use this variable also in the 'antisymmetric' function.
I checked some examples about class but didn't find a specific example to solve this problem.
I'll be waiting for your advice. Hope you have a nice day
class MyClass():
def __init__(self):
def checkif_pair(k):
for a in k:
if a%2 == 0:
None
else:
return False
return True
def check_reflexive(k):
j = 0
z = 0
reflexive_list = []
while j < len(k):
i = 0
while i < len(k):
if k[i] == k[j]:
tup = k[j],k[i]
reflexive_list.append(tup)
i += 1
else:
None
j = j + 1
else:
None
print(reflexive_list)
if len(reflexive_list) == len(self.list1):
return True
else:
return False
def antisymmetric(k):
antisymettric_list = []
for b in k:
swap1 = b[0]
swap2 = b[1]
newtuple = (swap2, swap1)
antisymettric_list.append(newtuple)
for ü in reflexive_list:
if ü in antisymettric_list:
antisymettric_list.remove(ü)
else:
None
print(antisymettric_list)
for q in antisymettric_list:
if q in k:
print("The system is not Anti-Symmetric.")
break
print("The system is Anti-Symmetric.")
def transitive(k):
result = {}
for first, second in k:
result.setdefault(first, []).append(second)
print(result)
for a, b in k:
for x in result[b]:
if x in result[a]:
None
else:
print("There is no {} in the {}".format(x, result[a]))
return False
return True
You can just use reflexive_list as an instance variable. Just add a constructor where the variable is defined:
class MyClass():
def __init__(self):
self.reflexive_list = []
And everytime you want to use it inside the function, you use self.reflexive_list

Remove unused variables in Python source code

The Question
Is there a straightforward algorithm for figuring out if a variable is "used" within a given scope?
In a Python AST, I want to remove all assignments to variables that are not otherwise used anywhere, within a given scope.
Details
Motivating example
In the following code, it is obvious to me (a human), that _hy_anon_var_1 is unused, and therefore the _hy_anon_var_1 = None statements can be removed without changing the result:
# Before
def hailstone_sequence(n: int) -> Iterable[int]:
while n != 1:
if 0 == n % 2:
n //= 2
_hy_anon_var_1 = None
else:
n = 3 * n + 1
_hy_anon_var_1 = None
yield n
# After
def hailstone_sequence(n: int) -> Iterable[int]:
while n != 1:
if 0 == n % 2:
n //= 2
else:
n = 3 * n + 1
yield n
Bonus version
Extend this to []-lookups with string literals as keys.
In this example, I would expect _hyx_letXUffffX25['x'] to be eliminated as unused, because _hyx_letXUffffX25 is local to h, so _hyx_letXUffffX25['x'] is essentially the same thing as a local variable. I would then expect _hyx_letXUffffX25 itself to be eliminated once there are no more references to it.
# Before
def h():
_hyx_letXUffffX25 = {}
_hyx_letXUffffX25['x'] = 5
return 3
# After
def h():
return 3
From what I can tell, this is somewhat of an edge case, and I think the basic algorithmic problem is the same.
Definition of "used"
Assume that no dynamic name lookups are used in the code.
A name is used if any of these are true in a given scope:
It is referenced anywhere in an expression. Examples include: an expression in a return statement, an expression on the right-hand side of an assignment statement, a default argument in a function definition, being referenced inside a local function definition, etc.
It is referenced on the left-hand side of an "augmented assignment" statement, i.e. it is an augtarget therein. This might represent "useless work" in a lot of programs, but for the purpose of this task that's OK and distinct from being an entirely unused name.
It is nonlocal or global. These might be useless nonlocals or globals, but because they reach beyond the given scope, it is OK for my purposes to assume that they are "used".
Please let me know in the comments if this seems incorrect, or if you think I am missing something.
Examples of "used" and "unused"
Example 1: unused
Variable i in f is unused:
def f():
i = 0
return 5
Example 2: unused
Variable x in f is unused:
def f():
def g(x):
return x/5
x = 10
return g(100)
The name x does appear in g, but the variable x in g is local to g. It shadows the variable x created in f, but the two x names are not the same variable.
Variation
If g has no parameter x, then x is in fact used:
def f():
x = 10
def g():
return x/5
return g(100)
Example 3: used
Variable i in f is used:
def f():
i = 0
return i
Example 4: used
Variable accum in silly_map and silly_sum is used in both examples:
def silly_map(func, data):
data = iter(data)
accum = []
def _impl():
try:
value = next(data)
except StopIteration:
return accum
else:
accum.append(value)
return _impl()
return _impl()
def silly_any(func, data):
data = iter(data)
accum = False
def _impl():
nonlocal accum, data
try:
value = next(data)
except StopIteration:
return accum
else:
if value:
data = []
accum = True
else:
return _impl()
return _impl()
The solution below works in two parts. First, the syntax tree of the source is traversed and all unused target assignment statements are discovered. Second, the tree is traversed again via a custom ast.NodeTransformer class, which removes these offending assignment statements. The process is repeated until all unused assignment statements are removed. Once this is finished, the final source is written out.
The ast traverser class:
import ast, itertools, collections as cl
class AssgnCheck:
def __init__(self, scopes = None):
self.scopes = scopes or cl.defaultdict(list)
#classmethod
def eq_ast(cls, a1, a2):
#check that two `ast`s are the same
if type(a1) != type(a2):
return False
if isinstance(a1, list):
return all(cls.eq_ast(*i) for i in itertools.zip_longest(a1, a2))
if not isinstance(a1, ast.AST):
return a1 == a2
return all(cls.eq_ast(getattr(a1, i, None), getattr(a2, i, None))
for i in set(a1._fields)|set(a2._fields) if i != 'ctx')
def check_exist(self, t_ast, s_path):
#traverse the scope stack and remove scope assignments that are discovered in the `ast`
s_scopes = []
for _ast in t_ast:
for sid in s_path[::-1]:
s_scopes.extend(found:=[b for _, b in self.scopes[sid] if AssgnCheck.eq_ast(_ast, b) and \
all(not AssgnCheck.eq_ast(j, b) for j in s_scopes)])
self.scopes[sid] = [(a, b) for a, b in self.scopes[sid] if b not in found]
def traverse(self, _ast, s_path = [1]):
#walk the ast object itself
_t_ast = None
if isinstance(_ast, ast.Assign): #if assignment statement, add ast object to current scope
self.traverse(_ast.targets[0], s_path)
self.scopes[s_path[-1]].append((True, _ast.targets[0]))
_ast = _ast.value
if isinstance(_ast, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)):
s_path = [*s_path, (nid:=(1 if not self.scopes else max(self.scopes)+1))]
if isinstance(_ast, (ast.FunctionDef, ast.AsyncFunctionDef)):
self.scopes[nid].extend([(False, ast.Name(i.arg)) for i in _ast.args.args])
_t_ast = [*_ast.args.defaults, *_ast.body]
self.check_exist(_t_ast if _t_ast is not None else [_ast], s_path) #determine if any assignment statement targets have previously defined names
if _t_ast is None:
for _b in _ast._fields:
if isinstance((b:=getattr(_ast, _b)), list):
for i in b:
self.traverse(i, s_path)
elif isinstance(b, ast.AST):
self.traverse(b, s_path)
else:
for _ast in _t_ast:
self.traverse(_ast, s_path)
Putting it all together:
class Visit(ast.NodeTransformer):
def __init__(self, asgn):
super().__init__()
self.asgn = asgn
def visit_Assign(self, node):
#remove assignment nodes marked as unused
if any(node.targets[0] == i for i in self.asgn):
return None
return node
def remove_assgn(f_name):
tree = ast.parse(open(f_name).read())
while True:
r = AssgnCheck()
r.traverse(tree)
if not (k:=[j for b in r.scopes.values() for k, j in b if k]):
break
v = Visit(k)
tree = v.visit(tree)
return ast.unparse(tree)
print(remove_assgn('test_name_assign.py'))
Output Samples
Contents of test_name_assign.py:
def hailstone_sequence(n: int) -> Iterable[int]:
while n != 1:
if 0 == n % 2:
n //= 2
_hy_anon_var_1 = None
else:
n = 3 * n + 1
_hy_anon_var_1 = None
yield n
Output:
def hailstone_sequence(n: int) -> Iterable[int]:
while n != 1:
if 0 == n % 2:
n //= 2
else:
n = 3 * n + 1
yield n
Contents of test_name_assign.py:
def h():
_hyx_letXUffffX25 = {}
_hyx_letXUffffX25['x'] = 5
return 3
Output:
def h():
return 3
Contents of test_name_assign.py:
def f():
i = 0
return 5
Output:
def f():
return 5
Contents of test_name_assign.py:
def f():
x = 10
def g():
return x/5
return g(100)
Ouptut:
def f():
x = 10
def g():
return x / 5
return g(100)

Python "object() takes no parameters" error

I'm having this problem when I clearly use init function to declare the parameters. Link my code there:
class Node:
def _init_(self,pieza,turno,listaAsignados,parent,costeCamino,coste):#Initialize a Node
self.pieza = pieza
self.turno = turno
self.listaAsignados = listaAsignados
self.parent = parent
self.costeCamino = costeCamino
self.costeNodo = costeNodo
def calculateCost(C, i, j, listaPadre,M): #Calculate Cost of the next element
initCost = 0
cost = 0
listaDisponibles = [1]*M
for i in range(i,M-1):
minNum = 9999999999
minIndex = -1
for j in range(j,M-1):
if(not listaPadre[j] and listaDisponibles[j] and C[i][j]< minNum ):
minIndex = j
minNumber = costMatrix[i][j]
cost = cost+ minNumber
return cost
import heapq
def branch_bound(C):
"""
-C = Matrix of costs
"""
items=[]
priorityQueue = []
heapq.heapify(priorityQueue)
listaAsignados = [0]*M#Asigned list for the matrix
raiz = Node(-1,-1,listaAsignados,None,0,0)
heapq.heappush(listaAsignados,[raiz.cost,raiz])
while (priorityQueue):
examinateNode = heapq.heappop(priorityQueue)
examinateNode = examinateNode[1]
i = examinateNode.pieza+1
if (i == M):
return examinateNode.cost
for j in range(0,M-1):
if(examinateNode.listaAsignados[j] == 0):
costeCamino = examinateNode.pathCost+ C[i][j]
costeHijo = costeCamino+ calculateCost(C, i, j, examinateNode.listaAsignados,M)
nodoHijo = Node(i,j,examinateNode.listaAsignados,examinateNode,costeCamino,costeHijo)
heapq.heappush(listaAsignados,[nodoHijo.cost,nodoHijo])
return items
If someone can explain me why this error is going on I will appreciate it. I don't know why if I have a constructor the error is going on:
<ipython-input-10-8d5dfd71f776> in branch_bound(C)
11 heapq.heapify(priorityQueue)
12 listaAsignados = [0]*M
13 raiz = Node(-1,-1,listaAsignados,None,0,0)<-------
14 heapq.heappush(listaAsignados,[raiz.cost,raiz])
15
TypeError: object() takes no parameters
You need to write __init__ instead of _init_.

How do I plot the integral of e^(-t^2) from x=0 to x=3 in Python?

I need to both calculate and plot the integral below in Python:
integral of the function e^(-t^2) from x=0 to x=3
So far I've managed to calculate the integral using Simpson's rule. The next bit which I'm struggling with is plotting the integral of e^(-t^2) vs x from x=0 to x=3 (see the image above).
Here's the code I've written to calculate the integral -
from math import exp
def f(t):
return exp(-(t**2))
a = 0
b = 3
h = 0.1
N = int((b-a)/h)
s_even = 0
s_odd = 0
for k in range(1,N,2):
s_odd += f(a+k*h)
for k in range(2,N,2):
s_even += f(a+k*h)
s = f(a) + f(b) + 4*s_odd + 2*s_even
Integral = h*s/3
print(Integral)
How do I then create a graph of this integral?
Here's a script I wrote that performs your calculation and plots it using PyQtGraph:
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
from math import exp
class I:
def f(self,t):
return exp(-(t**2))
def __init__(self, a = 0, b = 3, h = 0.1):
N = int((b-a)/h)
s_even = s_odd = 0
for k in range(1,N,2):
s_odd += self.f(a+k*h)
for k in range(2,N,2):
s_even += self.f(a+k*h)
s = self.f(a) + self.f(b) + 4*s_odd + 2*s_even
self.I = h*s/3
def __str__(self):
return "I: %s" % self.I
def plot(array):
app = QtGui.QApplication([])
win = pg.GraphicsWindow(title="Basic plotting examples")
win.resize(1000,600)
win.setWindowTitle('pyqtgraph example: Plotting')
# Enable antialiasing for prettier plots
pg.setConfigOptions(antialias=True)
p1 = win.addPlot(title="Basic array plotting", y=array)
QtGui.QApplication.instance().exec_()
def main():
a=0
b=a+0.001
points=[]
while(a<3):
points.append(I(a,b).I)
a=b
b=a+0.001
plot(points)
## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
main()
Here is the graph it draws:
Thanks for your help Red Cricket. It looks like you may have graphed the function e^(-t^2) rather than the integral of that function. Nonetheless, I think I've worked it out; I've discovered scipy has an integrate function:
from math import exp
from numpy import arange
from scipy import integrate
def f(t):
return exp(-(t**2))
a = 0
b = 3
h = 0.1
N = int((b-a)/h)
s_even = 0
s_odd = 0
for k in range(1,N,2):
s_odd += f(a+k*h)
for k in range(2,N,2):
s_even += f(a+k*h)
s = f(a) + f(b) + 4*s_odd + 2*s_even
I = h*s/3
function = []
x = []
for t in arange(0,4,h):
function.append(f(t))
for i in arange(0,4,h):
x.append(i)
function_int = integrate.cumtrapz(function,x,initial=0)
plot(x,function_int)
show()
print(I)
This produces a graph of the integral and prints the final value of the integral itself. Hooray!

Why does passing a dictionary as a parameter take more time?

I tried to a leetcode problem. I find one of the following code throws a time limit exceeded error. I created the following testing code. I found the first one pass dictionary as a parameter takes more time the the other one. 0.94s vs 0.84s.
Can anyone explain this ?
class Solution(object):
def longestPalindromeSubseq(self, x):
"""
:type s: str
:rtype: int
"""
#dic = {}
def helper(s, dic):
if len(s) == 0:
return 0
if len(s) == 1:
return 1
if s in dic:
return dic[s]
if s[0] == s[-1]:
res = helper(s[1:-1], dic)+2
else:
l1 = helper(s[:-1], dic)
l2 = helper(s[1:], dic)
res = max(l1,l2)
dic[s] = res
#print (id(dic), dic)
return res
d = {}
ans = helper(x, d)
#print (id(d), d)
return ans
class Solution1(object):
def longestPalindromeSubseq(self, x):
"""
:type s: str
:rtype: int
"""
dic = {}
def helper(s):
if len(s) == 0:
return 0
if len(s) == 1:
return 1
if s in dic:
return dic[s]
if s[0] == s[-1]:
res = helper(s[1:-1])+2
else:
l1 = helper(s[:-1])
l2 = helper(s[1:])
res = max(l1,l2)
dic[s] = res
#print (id(dic), dic)
return res
ans = helper(x)
#print (id(dic), dic)
return ans
import time
if __name__ == "__main__":
x = "gphyvqruxjmwhonjjrgumxjhfyupajxbjgthzdvrdqmdouuukeaxhjumkmmhdglqrrohydrmbvtuwstgkobyzjjtdtjroqpyusfsbjlusekghtfbdctvgmqzeybnwzlhdnhwzptgkzmujfldoiejmvxnorvbiubfflygrkedyirienybosqzrkbpcfidvkkafftgzwrcitqizelhfsruwmtrgaocjcyxdkovtdennrkmxwpdsxpxuarhgusizmwakrmhdwcgvfljhzcskclgrvvbrkesojyhofwqiwhiupujmkcvlywjtmbncurxxmpdskupyvvweuhbsnanzfioirecfxvmgcpwrpmbhmkdtckhvbxnsbcifhqwjjczfokovpqyjmbywtpaqcfjowxnmtirdsfeujyogbzjnjcmqyzciwjqxxgrxblvqbutqittroqadqlsdzihngpfpjovbkpeveidjpfjktavvwurqrgqdomiibfgqxwybcyovysydxyyymmiuwovnevzsjisdwgkcbsookbarezbhnwyqthcvzyodbcwjptvigcphawzxouixhbpezzirbhvomqhxkfdbokblqmrhhioyqubpyqhjrnwhjxsrodtblqxkhezubprqftrqcyrzwywqrgockioqdmzuqjkpmsyohtlcnesbgzqhkalwixfcgyeqdzhnnlzawrdgskurcxfbekbspupbduxqxjeczpmdvssikbivjhinaopbabrmvscthvoqqbkgekcgyrelxkwoawpbrcbszelnxlyikbulgmlwyffurimlfxurjsbzgddxbgqpcdsuutfiivjbyqzhprdqhahpgenjkbiukurvdwapuewrbehczrtswubthodv"
print (x)
t0 = time.time()
sol = Solution()
print (sol.longestPalindromeSubseq(x))
t1 = time.time()
print(t1- t0)
sol1 = Solution1()
print (sol1.longestPalindromeSubseq(x))
t2 = time.time()
print(t2-t1)
Python uses something that is called call by sharing. The function gets only the alias on the parameter. With that in mind, it does't matter what you pass to the function.
But the script may take different time to execute. It is not constant. Using recursion makes it even harder to predict

Categories

Resources