Is this the right string/ repr definition - python

class Assign(Expr):
"""Assignment: x = E represented as Assign(x, E)"""
def __init__(self, left: Var, right: Expr):
assert isinstance(left, Var) # Can only assign to variables!
self.left = left
self.right = right
def eval(self) -> IntConst:
r_val = self.right.eval()
self.left.assign(r_val)
return r_val
def __str__(self):
return f"{self.left} = {self.right}"
def __repr__(self):
return f"({repr(self.left)} = Var{repr(self.right)})"
This is the test case is should be able to pass
def test_assign_reps(self):
v = Var("v")
w = Var("w")
exp = Assign(v, Plus(IntConst(5), w))
self.assertEqual(str(exp), "(v = (5 + w))")
self.assertEqual(repr(exp), "Assign(Var(v), Plus(IntConst(5), Var(w)))")
But it keeps failing cause the format doesnt match please help
this is what keeps popping up
(v =(5 + w)) != v = (5 + w)
Expected :v = (5 + w)
Actual :(v =(5 + w))
this is what keeps popping up
(v =(5 + w)) != v = (5 + w)
Expected :v = (5 + w)
Actual :(v =(5 + w))
I have tried putting parenthesis around the __str__ but I keep getting failures
def __str__(self):
return f"{self.left} = {self.right}"
def __repr__(self):
return f"({repr(self.left)} = Var{repr(self.right)})"

Related

A* algorithm TypeError: cannot unpack non-iterable int object

This is the python code which uses A* algorithm for finding solution for 8 puzzle problems, I got some error messages, how can I fix it?(The error message is under the code)
There are several object-oriented programming concepts for Problems class, Node class that are implemented to express the problem solution search that you need to understand in order to make the Python program complete. The priority queue is to make the nodes to be explored to be sorted according to their f-evaluation function score and return the min one as the first node to be searched next.
There is also a memorize function to memorize the heuristic value of state as a look-up table so that you don’t need to calculate the redundant computing of heuristic estimation value, so you can ignore it at this point if you don’t understand.
The components you need to implement is to make the abstract part of the program realizable for 8 -puzzle with the successor methods attached to a problem class which consists of initial state and goal state. Make sure the program can run correctly to generate the solution sequence that move the empty tile so that the 8-puzzle can move "Up", "Down", "Left", "Right", from initial state to goal state.
import math
infinity = math.inf
from itertools import chain
import numpy as np
import bisect
class memoize:
def __init__(self, f, memo={}):
self.f = f
self.memo = {}
def __call__(self, *args):
if not str(args) in self.memo:
self.memo[str(args)] = self.f(*args)
return self.memo[str(args)]
def coordinate(state):
index_state = {}
index = [[0,0], [0,1], [0,2], [1,0], [1,1], [1,2], [2,0], [2,1], [2,2]]
for i in range(len(state)):
index_state[state[i]] = index[i]
return index_state
def getInvCount(arr):
inv_count = 0
empty_value = -1
for i in range(0, 9):
for j in range(i + 1, 9):
if arr[j] != empty_value and arr[i] != empty_value and arr[i] > arr[j]:
inv_count += 1
return inv_count
def isSolvable(puzzle) :
inv_count = getInvCount([j for sub in puzzle for j in sub])
return (inv_count % 2 == 0)
def linear(state):
return sum([1 if state[i] != goal[i] else 0 for i in range(9)])
#memoize
def manhattan(state):
index_goal = coordinate(goal)
index_state = coordinate(state)
mhd = 0
for i in range(9):
for j in range(2):
mhd = abs(index_goal[i][j] - index_state[i][j]) + mhd
return mhd
#memoize
def sqrt_manhattan(state):
index_goal = coordinate(goal)
index_state = coordinate(state)
mhd = 0
for i in range(9):
for j in range(2):
mhd = (index_goal[i][j] - index_state[i][j])**2 + mhd
return math.sqrt(mhd)
#memoize
def max_heuristic(state):
score1 = manhattan(state)
score2 = linear(state)
return max(score1, score2)
class PriorityQueueElmt:
def __init__(self,val,e):
self.val = val
self.e = e
def __lt__(self,other):
return self.val < other.val
def value(self):
return self.val
def elem(self):
return self.e
class Queue:
def __init__(self):
pass
def extend(self, items):
for item in items: self.append(item)
class PriorityQueue(Queue):
def __init__(self, order=min, f=None):
self.A=[]
self.order=order
self.f=f
def append(self, item):
queueElmt = PriorityQueueElmt(self.f(item),item)
bisect.insort(self.A, queueElmt)
def __len__(self):
return len(self.A)
def pop(self):
if self.order == min:
return self.A.pop(0).elem()
else:
return self.A.pop().elem()
# Heuristics for 8 Puzzle Problem
class Problem:
def __init__(self, initial, goal=None):
self.initial = initial; self.goal = goal
def successor(self, state):
reachable = []
def get_key(val):
for key, value in index_state.items():
if val == value:
return key
return -1
def candidate(state, Position):
state = state.copy()
zero_index = state.index(0)
swap_index = state.index(get_key(Position))
state[zero_index], state[swap_index] = state[swap_index], state[zero_index]
return state
index_state = coordinate(state)
zero_position = index_state[0]
move_pair = {"left":[zero_position[0], zero_position[1] - 1],
"right":[zero_position[0], zero_position[1] + 1],
"up":[zero_position[0] - 1, zero_position[1]],
"down":[zero_position[0] + 1, zero_position[1]]
}
for action, position in move_pair.items():
#print(action, position)
if get_key(position) != -1:
reachable.append((action, candidate(state, position)))
#print(reachable)
return reachable
def goal_test(self, state):
return state == self.goal
def path_cost(self, c, state1, action, state2):
return c + 1
def value(self):
abstract
class Node:
def __init__(self, state, parent=None, action=None, path_cost=0, depth =0):
self.parent = parent
if parent:
self.depth = parent.depth + 1
else:
self.depth = 0
self.path_cost = path_cost
self.state = state
if action:
self.action = action
else: self.action = "init"
def __repr__(self):
return "Node state:\n " + str(np.array(self.state).reshape(3,3)) +"\n -> action: " + self.action + "\n -> depth: " + str(self.depth)
def path(self):
x, result = self, [self]
while x.parent:
result.append(x.parent)
x = x.parent
return result
def expand(self, problem):
for (act,n) in problem.successor(self.state):
if n not in [node.state for node in self.path()]:
yield Node(n, self, act,
problem.path_cost(self.path_cost, self.state, act, n))
def graph_search(problem, fringe):
closed = {}
fringe.append(Node(problem.initial,depth=0))
while fringe:
node = fringe.pop()
if problem.goal_test(node.state):
return node
if str(node.state) not in closed:
closed[str(node.state)] = True
fringe.extend(node.expand(problem))
return None
def best_first_graph_search(problem, f):
return graph_search(problem, PriorityQueue(min, f))
def astar_search(problem, h = None):
h = h or problem.h
def f(n):
return max(getattr(n, 'f', -infinity), n.path_cost + h(n.state))
return best_first_graph_search(problem, f)
def print_path(path, method):
print("*" * 30)
print("\nPath: (%s distance)" % method)
for i in range(len(path)-1, -1, -1):
print("-" * 15)
print(path[i])
goal = [1, 2, 3, 4, 5, 6, 7, 8, 0]
# Solving the puzzle
puzzle = [7, 2, 4, 5, 0, 6, 8, 3, 1]
if(isSolvable(np.array(puzzle).reshape(3,3))): # even true
# checks whether the initialized configuration is solvable or not
print("Solvable!")
problem = Problem(puzzle,goal)
path = astar_search(problem, manhattan).path()
print_path(path, "manhattan")
path = astar_search(problem, linear).path()
print_path(path, "linear")
path = astar_search(problem, sqrt_manhattan).path()
print_path(path, "sqrt_manhattan")
path = astar_search(problem, max_heuristic).path()
print_path(path, "max_heuristic")
else :
print("Not Solvable!") # non-even false
TypeError Traceback (most recent call last)
<ipython-input-124-2a60ddc8c009> in <module>
9 problem = Problem(puzzle,goal)
10
---> 11 path = astar_search(problem, manhattan).path()
12 print_path(path, "manhattan")
13
<ipython-input-123-caa97275712e> in astar_search(problem, h)
18 def f(n):
19 return max(getattr(n, 'f', -infinity), n.path_cost + h(n.state))
---> 20 return best_first_graph_search(problem, f)
21
22 def print_path(path, method):
<ipython-input-123-caa97275712e> in best_first_graph_search(problem, f)
12
13 def best_first_graph_search(problem, f):
---> 14 return graph_search(problem, PriorityQueue(min, f))
15
16 def astar_search(problem, h = None):
<ipython-input-123-caa97275712e> in graph_search(problem, fringe)
8 if str(node.state) not in closed:
9 closed[str(node.state)] = True
---> 10 fringe.extend(node.expand(problem))
11 return None
12
<ipython-input-121-e5a968bd54f0> in extend(self, items)
18
19 def extend(self, items):
---> 20 for item in items: self.append(item)
21
22 class PriorityQueue(Queue):
<ipython-input-122-db21613469b9> in expand(self, problem)
69
70 def expand(self, problem):
---> 71 for (act,n) in problem.successor(self.state):
72 if n not in [node.state for node in self.path()]:
73 yield Node(n, self, act,
TypeError: cannot unpack non-iterable int object
I got some error messages, how can I fix it?
There is one error message, The pieces of codes you get in the error message are the stack trace, which might help you to know how the execution got at the final point where the error occurred. In this case that is not so important. The essence of the error is this:
for (act,n) in problem.successor(self.state)
TypeError: cannot unpack non-iterable int object
So this means that the successor method returned an int instead of a list.
Looking at the code for successor, I notice that it intends to return a list called reachable, but there is a return statement right in the middle of the code, leaving the largest part of that code unexecuted (so-called "dead code"):
return state
This statement makes no sense where it is positioned. It seems to be an indentation problem: that return belongs inside the function just above it, like this:
def candidate(state, Position):
state = state.copy()
zero_index = state.index(0)
swap_index = state.index(get_key(Position))
state[zero_index], state[swap_index] = state[swap_index], state[zero_index]
return state # <-- indentation!

Alternative to Fernet Encyption Algorithm w.o Salt

Hi I am new to encryption algorithms and am a little confused by the terminology and what to choose for which situation. For now I don't need the most secure algorithm but it should have the following properties:
A shared secret key, that encrypts/decrypts the message (two way).
The Cipher should be the same if same text for encryption has been used.
I used the Fernet algorithm in Python, however the Ciphertext is always different. and therefore not suitable for my needs. Is there an algorithm similar to Fernet but without the Salt?
Assuming you're using the cryptography module (which you should): Instead of using generate_key(), build the key and pass it to the Fernet constructor.
Check this link for the precise example: https://cryptography.io/en/latest/fernet/#using-passwords-with-fernet
Additionally, check https://www.crypto101.io/ if you haven't yet.
Actually there's no ready algorithm do what you're asking for "at lease that what I know".
But in the past I've wrote a GUI chat room with a real server and real clients in python.
And I've wrote a basic encryption/decryption algorithm to pass the data encrypted "like messages".
you can use it if you want cuz I've never used that server I made it just for fun ;).
The algorithm:
from cryptography.fernet import Fernet
CODES_KEY = b'LYsrKDiTRNJDm3g_h25GW0uyUzPTk8l8G02hcPM_d_U='
def encryption(msg):
'''
Encryption Func
'''
class RSA:
'''
RSA Encryption Func
'''
def __init__(self):
self.e = self.d = self.p = self.q = self.phi = 0
def __egcd(self, a, b):
if a == 0:
return (b, 0, 1)
g, y, x = self.__egcd(b % a, a)
return (g, x - (b // a) * y, y)
def __modinv(self, a, m):
g, x, _ = self.__egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
return x % m
def encrypt(self, m, key_pair=None):
'''
Encrypting Func
'''
if key_pair is None:
key_pair[0] = self.e
key_pair[1] = self.n
return pow(m, key_pair[0], key_pair[1])
def generate_keys(self, p, q, e=3):
'''
Generating Keys Func
'''
self.p = p
self.q = q
self.n = self.p * self.q
self.phi = (self.p - 1) * (self.q - 1)
self.e = e
self.d = self.__modinv(self.e, self.phi)
if self.phi % self.e == 0:
raise Exception('invalid values for p and q')
def get_public_key(self):
'''
Getting PublicKey Func
'''
return self.e, self.n
rsa = RSA()
# Two 1024-bit primes
rsa.generate_keys(17055899557196527525682810191339089909014331959812898993437334555169285087976951946809555356817674844913188193949144165887100694620944167618997411049745043243260854998720061941490491091205087788373487296637817044103762239946752241631032791287021875863785226376406279424552454153388492970310795447866569138481,
171994050316145327367864378293770397343246561147593187377005295591120640129800725892235968688434055779668692095961697434700708550594137135605048681344218643671046905252163983827396726536078773766353616572531688390937410451433665914394068509329532352022301339189851111636176939179510955519440490431177444857017)
int_message = []
for i in msg:
int_message.append(ord(i))
codes = []
for i in int_message:
codes.append(len(str(i)))
message = int(''.join([str(x) for x in int_message]))
# Encrypting
encrypted_message = rsa.encrypt(message, key_pair=rsa.get_public_key())
f = Fernet(CODES_KEY)
encrypted_codes = f.encrypt(str(codes).encode())
return encrypted_message, encrypted_codes
def decryption(msg, codes):
'''
Decryption Func
'''
class RSA:
'''
RSA Decryption Func
'''
def __init__(self):
self.e = self.d = self.p = self.q = self.phi = 0
def __egcd(self, a, b):
if a == 0:
return (b, a, 1)
g, y, x = self.__egcd(b % a, a)
return (g, x - (b // a) * y, y)
def __modinv(self, a, m):
g, x, _ = self.__egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
return x % m
def decrypt(self, c, key_pair=None):
'''
Decrypting Func
'''
if key_pair is None:
key_pair[0] = self.d
key_pair[1] = self.n
return pow(c, key_pair[0], key_pair[1])
def generate_keys(self, p, q, e=3):
'''
Generating Keys Func
'''
self.p = p
self.q = q
self.n = self.p * self.q
self.phi = (self.p - 1) * (self.q - 1)
self.e = e
self.d = self.__modinv(self.e, self.phi)
if self.phi % self.e == 0:
raise Exception('invalid values for p and q')
def get_private_key(self):
'''
Getting Private Key Func
'''
return self.d, self.n
rsa = RSA()
# Two 1024-bit primes
rsa.generate_keys(17055899557196527525682810191339089909014331959812898993437334555169285087976951946809555356817674844913188193949144165887100694620944167618997411049745043243260854998720061941490491091205087788373487296637817044103762239946752241631032791287021875863785226376406279424552454153388492970310795447866569138481,
171994050316145327367864378293770397343246561147593187377005295591120640129800725892235968688434055779668692095961697434700708550594137135605048681344218643671046905252163983827396726536078773766353616572531688390937410451433665914394068509329532352022301339189851111636176939179510955519440490431177444857017)
# Decrypting
f = Fernet(CODES_KEY)
# set_trace()
decrypted_message = str(rsa.decrypt(int(msg), key_pair=rsa.get_private_key()))
decrypted_codes = f.decrypt(codes).decode()
decrypted_message = list(decrypted_message)
original_codes = []
for i in decrypted_codes:
if i not in ['[', ']', ',', ' ']:
original_codes.append(int(i))
original_message = ""
for _, value in enumerate(original_codes):
handler = ""
for i in decrypted_message[:value]:
handler += i
original_message += chr(int(handler))
decrypted_message = decrypted_message[value:]
return original_message
def main():
message = "Hi, This is a secret message"
encrypted_message, encrypted_codes = encryption(message)
decrypted_message = decryption(encrypted_message, encrypted_codes)
print(decrypted_message)
if __name__ == '__main__':
main()
Sorry if it's a mess but I'm just 17 years old bro :) !
Maybe you can optimize it more I've wrote this when i was new to python.
you can always generate new "CODES_KEY" by running this in python:
from cryptography.fernet import Fernet
f = Fernet
print(f.generate_key())
EDIT: I wrote this as an RSA but then changed the code, this is why it's named RSA but it's not :)

Creating Polynomial Class in Python

I am currently working on creating a Polynomial class that includes add , mul and eval methods. I'm currently stuck on the addition portion, if someone could give me some help on how to get that figured out that would be greatly appreciated. Everything currently works without errors but when I do p3 = p1 + p2 and I print p3 I get back the two lists together. Any feedback would be greatly appreciated.
class Polynomial(object):
def __init__(self, *coeffs, num = 0):
self.coeffs = list(coeffs) # turned into a list
assert (type(num) is type(1))
self.num = num
# Needs to be operator overload
'''
def __mul__(self, other):
'''
def __eval__(self, other, coeff, x):
result = coeff[-1]
for i in range(-2, -len(coeff)-1, -1):
result = result * x + coeff[i]
return result
def __add__(self, other):
assert type(other) is Polynomial
num = self.coeffs + other.coeffs
return Polynomial(num)
def __sub__(self, other):
assert type(other) is Polynomial
num = self.coeffs - other.coeffs
return Polynomial(num)
def __represntation__(self):
return "Polynomial" + str(self.coeffs)
def __str__(self):
rep = ""
degree = len(self.coeffs) - 1
rep += str(self.coeffs[0]) + "x^" + str(degree)
for i in range(1, len(self.coeffs)-1):
coeff = self.coeffs[i]
if coeff < 0:
rep += " - " + str(-coeff) + "x^" + str(degree - i)
else:
rep += " + " + str(coeff) + "x^" + str(degree - i)
if self.coeffs[-1] < 0:
rep += " - " + str(-self.coeffs[-1])
else:
rep += " + " + str(self.coeffs[-1])
return rep
You cannot directly add two lists.
def __add__(self, other):
assert type(other) is Polynomial
assert len(self.coeffs) != len(other.coeffs)
new_ceffs = [item1 + item2 for (item1, item2) in zip(self.coeffs, other.coeffs)]
return Polynomial(new_ceffs)
The problem is here:
num = self.coeffs + other.coeffs
Adding one list to another list concatenates them. To simply add corresponding elements to each other, you'd want to do
from itertools import zip_longest
...
num = [a + b for (a, b) in zip_longest(self.coeffs, other.coeffs, fillvalue=0)]
We use zip_longest() instead of the more generic zip() because one polynomial is possibly longer than the other and we don't want to ruin it. Either one of them will group together the corresponding elements so that we can easily add them and make a list of those.
You would do something similar for subtraction.
you should reverse the order of coefficients passed to your constructor so that indexes in the self.coeffs list correspond to the exponents. This would simplify the rest of your code and allow you to use zip_longest for additions and subtractions.
When you get to other operations however, I think you will realize that your internal structure would be easier to manage if it was a dictionary. A dictionary is more permissive of missing entries thus avoiding preoccupations of allocating spaces for new indexes.
class Polynomial(object):
def __init__(self, *coeffs):
self.coeffs = {exp:c for exp,c in enumerate(coeffs[::-1])}
def __add__(self, other):
assert type(other) is Polynomial
result = Polynomial(0)
result.coeffs = {**self.coeffs}
for exp,c in other.coeffs.items():
result.coeffs[exp] = result.coeffs.get(exp,0) + c
return result
def __sub__(self, other):
assert type(other) is Polynomial
result = Polynomial(0)
result.coeffs = {**self.coeffs}
for exp,c in other.coeffs.items():
result.coeffs[exp] = result.coeffs.get(exp,0) - c
return result
def __mul__(self, other):
assert type(other) is Polynomial
result = Polynomial(0)
for exp1,c1 in self.coeffs.items():
for exp2,c2 in other.coeffs.items():
result.coeffs[exp1+exp2] = result.coeffs.get(exp1+exp2,0) + c1*c2
return result
def __representation__(self):
return "Polynomial" + str(self.coeffs)
def __str__(self):
result = [""]+[f"{c}x^{i}" for i,c in sorted(self.coeffs.items()) if c]+[""]
result = "+".join(reversed(result))
result = result.replace("+1x","+x")
result = result.replace("-1x","-x")
result = result.replace("x^0","")
result = result.replace("x^1+","x+")
result = result.replace("+-","-")
result = result.strip("+")
result = result.replace("+"," + ")
result = result[:1]+result[1:].replace("-"," - ")
return result.strip()

Using hasattr() when the attribute is not known

I'm trying to combine two applications for visualising binaries, binvis and droidcolors. Since droidcolors is in C, I'm trying to make binvis replicate the functionality offered by droidcolors.
Here are the relevant snippets from the code that I've written so far. The complete file is here: https://pastebin.com/0C7fu9W2.
class _Color:
def __init__(self, data, **kwargs):
self.data = data
for key, value in kwargs.items():
setattr(self, key, value)
s = list(set(data))
s.sort()
self.symbol_map = {v : i for (i, v) in enumerate(s)}
def __len__(self):
return len(self.data)
def point(self, x):
if hasattr(self, 'class_defs') and (self.class_defs[0] <= x <= self.class_defs[1]):
return self.return_droidcolors_classdefs(x)
elif hasattr(self, 'dat') and (self.dat[0] <= x <= self.dat[1]):
return self.return_droidcolors_data(x)
elif hasattr(self, 'field_ids') and (self.field_ids[0] <= x <= self.field_ids[1]):
return self.return_droidcolors_field_ids(x)
elif hasattr(self, 'header') and (self.header[0] <= x <= self.header[1]):
return self.return_droidcolors_header(x)
elif hasattr(self, 'links') and (self.links[0] <= x <= self.links[1]):
return self.return_droidcolors_links(x)
elif hasattr(self, 'proto_ids') and (self.proto_ids[0] <= x <= self.proto_ids[1]):
return self.return_droidcolors_proto_ids(x)
elif hasattr(self, 'method_ids') and (self.method_ids[0] <= x <= self.method_ids[1]):
return self.return_droidcolors_method_ids(x)
elif hasattr(self, 'string_ids') and (self.string_ids[0] <= x <= self.string_ids[1]):
return self.return_droidcolors_string_ids(x)
elif hasattr(self, 'type_ids') and (self.type_ids[0] <= x <= self.type_ids[1]):
return self.return_droidcolors_type_ids(x)
elif hasattr(self, 'block') and (self.block[0] <= x <= self.block[1]):
return self.block[2]
else:
return self.getPoint(x)
# --- snip ---
class ColorDroidColors(_Color):
def getPoint(self, x):
return [0, 0, 0]
# --- snip ---
dex_handle = Dexparser(args[0])
dex_header_info = dex_handle.header_info()
dex_class_defs = (dex_header_info['class_defs_off'], dex_header_info['class_defs_off'] + (64 * dex_header_info['class_defs_size']) - 1)
dex_data = (dex_header_info['data_off'], dex_header_info['data_off'] + dex_header_info['data_size'] - 1)
dex_field_ids = (dex_header_info['field_ids_off'], dex_header_info['field_ids_off'] + (8 * dex_header_info['field_ids_size']) - 1)
dex_header = (0x0, dex_header_info['header_size'] - 1)
dex_links = (link_off, link_off + dex_header_info['link_size'] - 1)
dex_proto_ids = (dex_header_info['proto_ids_off'], dex_header_info['proto_ids_off'] + (12 * dex_header_info['proto_ids_size']) - 1)
dex_method_ids = (dex_header_info['method_ids_off'], dex_header_info['method_ids_off'] + (8 * dex_header_info['method_ids_size']) - 1)
dex_string_ids = (dex_header_info['string_ids_off'], dex_header_info['string_ids_off'] + (4 * (dex_header_info['string_ids_size']) - 1))
dex_type_ids = (dex_header_info['type_ids_off'], dex_header_info['type_ids_off'] + (4 * dex_header_info['type_ids_size']) - 1)
kwarg_dict = {
"class_defs": dex_class_defs,
"dat": dex_data,
"field_ids": dex_field_ids,
"header": dex_header,
"links": dex_links,
"proto_ids": dex_proto_ids,
"method_ids": dex_method_ids,
"string_ids": dex_string_ids,
"type_ids": dex_type_ids,
}
for i, item in enumerate(dex_handle.protoids_list()):
if item[2]:
kwarg_dict['dex_proto_params_' + str(i)] = (item[2], (0x0 + item[2]) * 4 + 4)
csource = ColorDroidColors(
d,
**kwarg_dict
)
I'm basically passing 10000+ kwargs to a method, and require a way to test within the method if a kwarg exists and depending on the same, to return some value. All the kwargs have a particular prefix, followed by sequential numbers starting from 1. I tried using a for loop, but that slowed the program down to a crawl.
Could anyone please suggest me a way out?
Use getattr() and a list of attributes to test:
attrs = ['class_defs', 'dat', 'field_ids', ..., 'block']
for name in attrs:
value = getattr(self, name, None)
if value is not None and value[0] <= x <= value[1]
if name != 'block':
method_name = 'return_droidcolors_' + name
return getattr(self, method_name)(x)
else:
return value[2]
# none of the attributes matched
return self.getPoint(x)
Note that in your __init__ method, you could just use self.__dict__.update(kwargs) rather than loop through the dictionary and call setattr() each time.

Generating new expression from an existing expression in Z3

Given an expression f , I want to replace all variables v in f with something like v_d (d is a number). Currently I have to go through the following steps to achieve this
Obtain all the variables in f
For each variable v in f, determine its sort, then generate the appropriate v_d var.
do the substitution
Since I am still trying to learn Z3 python so probably there is a much better way to do the above?
Thanks.
My full code is listed below:
def get_vars(f,rs=[]):
"""obtain variables from f"""
if is_const(f):
try:
f.as_string() #to differentiate btw Int('x') and IntVal('3')
return rs
except AttributeError:
return vset(rs + [f],str)
else:
for f_ in f.children():
rs = get_vars(f_,rs)
return vset(rs,str)
def gen_vars(vs,i):
"""
Generates a new set of variables
E.g. v => v_i , v_next => v_(i+1)
"""
assert i>=0
def mk_name(i,v):
next_kw = '_next'
if str(v).endswith(next_kw):
astr = str(v)[:-len(next_kw)] + '_' + str(i+1)
else:
astr = str(v) + '_' + str(i)
return astr
def mk_var(name,vsort):
if vsort.kind() == Z3_INT_SORT:
v = Int(name)
elif vsort.kind() == Z3_REAL_SORT:
v = Real(name)
elif vsort.kind() == Z3_BOOL_SORT:
v = Bool(name)
elif vsort.kind() == Z3_DATATYPE_SORT:
v = Const(name,vsort)
else:
assert False, 'Cannot handle this sort yet (id: %d)'%vsort.kind()
return v
#so that the longest one is replaced first
vs = sorted(vs,key=str,reverse=True)
names = [mk_name(i,v) for v in vs]
vs_ = [mk_var(ns,v.sort()) for ns,v in zip(names,vs)]
vss = zip(vs,vs_)
return vss
def substitute_f(f,i,vs=None):
"""
Replaces all variables v in f with v_(i*_)
vs: variables in f (could be automatically obtained from f)
"""
assert is_expr(f)
assert isinstance(vs,list) or vs is None
if vs is None:
vs = get_vars(f)
vss = gen_vars(vs,i)
f_ = f
for pvs in vss:
f_ = substitute(f_,pvs)
return f_

Categories

Resources