endless container iterator with backward\forward movement support - python-3.x

Is in standart library container with endless forward/backward movement support, like itertools.cycle? Or how to implement one-liner for it?
Current code (github):
def __init__(self, ...):
self.__weapons = [Weapon()("Blaster"), Weapon()("Laser"), Weapon()("UM")]
self.__weapon = self.__weapons[0]
...
def next_weapon(self):
ind = self.__weapons.index(self.__weapon)
if ind < len(self.__weapons) - 1:
self.__weapon = self.__weapons[ind+1]
else:
self.__weapon = self.__weapons[0]
And almost the same code for prev_weapon method.
I want to iterate on endless container in both directions=)
Thanks in advance,
Paul

I decided that best solution is to extend List.
class InfList(list):
"""Infinite list container"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._index = 0
def current(self):
return self[self._index]
def next(self):
self._index = (self._index + 1) % len(self)
return self[self._index]
def prev(self):
self._index = (self._index - 1) % len(self)
return self[self._index]

Related

How could I create a docstring decorator in the presence of properties?

I have a collection of ever more specialized classes which correspond to collections of the same kind of data (temperature, density, etc) but for different drifts, for example, one subclass has dimensions (nx, ny) and a different suclass has dimensions (ncv), and I want to reflect that in the docstrings, for having a better documentation using Sphinx.
After reading many very useful threads here in Stack Overflow, I have arrived to this model:
import numpy as np
from functools import wraps
def class_decorator(cls):
import ipdb; ipdb.set_trace()
clsdict = {}
mro = cls.mro()
mro.reverse()
for tmp in mro[1:]: ##Ignore object class parent.
clsdict.update(tmp.__dict__)
for name, method in clsdict.items():
if hasattr(method, '__og_doc__'):
try:
method.__doc__ = method.__og_doc__.format(**clsdict)
except:
pass
else:
try:
method.__og_doc__ = method.__doc__
method.__doc__ = method.__doc__.format(**clsdict)
except:
pass
return cls
def mark_documentation(fn):
if not hasattr(fn, '__og_doc__'):
try:
fn.__og_doc__ = fn.__doc__
except:
pass
#wraps(fn)
def wrapped(*args, **kwargs):
return fn(*args, **kwargs)
return wrapped
def documented_property(fn):
if not hasattr(fn, '__og_doc__'):
try:
fn.__og_doc__ = fn.__doc__
except:
pass
#wraps(fn)
def wrapped(*args, **kwargs):
return fn(*args, **kwargs)
prp= property(wrapped)
prp.__og_doc__ = fn.__og_doc__
return prp
#class_decorator
class Base(object):
_GRID_DIM = 'nx, ny'
_TYPE = 'BaseData'
def __init__(self, name):
self.name = name
def shape(self):
""" This docstring contains the type '{_TYPE}' of class."""
print('Simple')
def operation(self, a, b, oper=np.sum, **kwargs):
""" Test for functions with args and kwargs in {_TYPE}"""
return oper([a,b])
#classmethod
def help(cls, var):
try:
print(get(cls, var).__doc__)
except:
print("No docstring yet.")
#class_decorator
class Advanced(Base):
_GRID_DIM = 'ncv'
_TYPE = 'AdvancedData'
def __init__(self,name):
super().__init__(name)
#property
#mark_documentation
# #documented_property
def arkansas(self):
"""({_GRID_DIM}, ns): Size of Arkansaw."""
return 'Yeah'
I am aiming to get the correctly formatted docstring when I call the help method or I use Sphinx, so that:
> adv = Advanced('ADV')
> adv.help("arkansas")
(ncv, ns): Size of Arkansaw.
> adv.help("operation")
Test for functions with args and kwargs in AdvancedData
I have managed to make it work so far, except for properties, because I assigned __og_doc__ to the function, but the property does not have that attribute. My last attempt at monkeypatching this, documented_property, fails because property is inmutable (as expected), and I cannot come up with any way to avoid this roadblock.
Is there any way around this problem?

Seeking advise on create a maze to solve with BFS in Python

Seeking advise on how structure python to create a maze, solve it with BFS and to have basic navigation within maze with number of moves required to navigate. Use move along the path, Up, Left, Right, Down. Below is some code that I mangled together to think about and figure how to structure python for this BFS algorithm code.
Is anyone open to mentoring on this BFS algorithm navigation maze python structure?
To basically follow the following algorithm:
function BREADTH-FIRST-SEARCH(problem) returns a solution node or failure
node ← NODE(problem.INITIAL)
if problem.IS-GOAL(node.STATE) then return node
frontier ← a FIFO queue, with node as an element
reached ← {problem.INITIAL}
while not IS-EMPTY(frontier ) do
node ← POP(frontier )
for each child in EXPAND(problem, node) do
s ← child.STATE
if problem.IS-GOAL(s) then return child
if s is not in reached then
add s to reached
add child to frontier
return failure
import sys
def parse_map(filename):
with open(filename, "r") as f:
return [[char for char in line] for line in f.read().rstrip("\n").split("\n")][3:]
def count_x(house_map):
return sum([ row.count('p') for row in house_map ] )
def printable_house_map(house_map):
return "\n".join(["".join(row) for row in house_map])
def add_x(house_map, row, col):
return house_map[0:row] + [house_map[row][0:col] + ['p',] + house_map[row][col+1:]] + house_map[row+1:]
def successors(house_map):
return [ add_x(house_map, r, c) for r in range(0, len(house_map)) for c in range(0,len(house_map[0])) if house_map[r][c] == '.' ]
def is_goal(house_map, k):
return count_x(house_map) == k
def bfs_graph_search(house_map):
fringe = [initial_house_map]
if house_map.goal_test(node.state):
return fringe
fringe = deque([house_map])
visited = set()
while fringe:
fringe = fringe.popleft()
visited.add(node.state)
for child in node.expand(problem):
if child.state not in fringe and child not in visited:
if house_map.goal_test(child.state):
return child
fringe.append(child)
return None
def solve(initial_house_map,k):
fringe = [initial_house_map]
while len(fringe) > 0:
for new_house_map in successors( fringe.pop() ):
if is_goal(new_house_map,k):
return(new_house_map,True)
fringe.append(new_house_map)
if __name__ == "__main__":
house_map=parse_map('map1.txt')
k = 2
print ("Initial ]house map:\n" + printable_house_map(house_map) + "\n\nSearching for solution...\n")
solution = solve(house_map,k)
print ("Found:")
print (printable_house_map(solution[0]) if solution[1] else "False")
class Agent:
def __init__(self, initial, goal=None):
self.initial = initial
self.goal = goal
def actions(self, state):
raise NotImplementedError
def result(self, state, action):
raise NotImplementedError
def goal_test(self, state):
if isinstance(self.goal, list):
return is_in(state, self.goal)
else:
return state == self.goal
def path_cost(self, c, state1, action, state2):
return c + 1
def value(self, state):
raise NotImplementedError
class FringeGraph:
def __init__(self, state, parent=None, action=None, path_cost=0):
self.state = state
self.parent = parent
self.action = action
self.path_cost = path_cost
self.depth = 0
if parent:
self.depth = parent.depth + 1
def path(self):
node, path_back = self, []
while node:
path_back.append(node)
node = node.parent
return list(reversed(path_back))
def solution(self):
return [node.action for node in self.path()[1:]]
def expand(self, agent):
return [self.child_node(agent, action)
for action in agent.actions(self.state)]
def child_node(self, agent, action):
next_state = agent.result(self.state, action)
next_node = Node(next_state, self, action, problem.path_cost(self.path_cost, self.state, action, next_state))
return next_node
class Agent:
def __init__(self, initial, goal=None):
self.initial = initial
self.goal = goal
def actions(self, state):
raise NotImplementedError
def result(self, state, action):
raise NotImplementedError
def goal_test(self, state):
if isinstance(self.goal, list):
return is_in(state, self.goal)
else:
return state == self.goal
def path_cost(self, c, state1, action, state2):
return c + 1
def value(self, state):
raise NotImplementedError
class FringeGraph:
def __init__(self, state, parent=None, action=None, path_cost=0):
self.state = state
self.parent = parent
self.action = action
self.path_cost = path_cost
self.depth = 0
if parent:
self.depth = parent.depth + 1
def path(self):
node, path_back = self, []
while node:
path_back.append(node)
node = node.parent
return list(reversed(path_back))
def solution(self):
return [node.action for node in self.path()[1:]]
def expand(self, agent):
return [self.child_node(agent, action)
for action in agent.actions(self.state)]
def child_node(self, agent, action):
next_state = agent.result(self.state, action)
next_node = Node(next_state, self, action, agent.path_cost(self.path_cost, self.state, action, next_state))
return next_node

how can i iterate class objects while using generator in python?

i want to compare the 2000 pairs of a and b, and print the matching pairs and count of them.can anyone help me to get rid of it.it shows this error TypeError: 'seq_generator' object is not iterable at line 34
class generator(object):
def __init__(self,s,start_A,fact_A):
self.s=s
self.start_A=start_A
self.fact_A = fact_A
def seq_gen_A(self):
while self.s>0:
self.gen_A=(self.start_A*self.fact_A)%2147483647
self.g=self.gen_A
self.start_A=self.gen_A
self.bin_A=(bin(self.gen_A)[-16:])
yield self.bin_A
self.s=self.s-1
def next(self):
for i in self.seq_gen_A():
return i
def main():
s=200
count=0
a=generator(s,65,16807)
b=generator(s,8921,48271)
print("Matching pair")
print("*************")
for i in range(0,s):
if next(a)==next(b):
count+=1
print(a,b)
print('Matching pair count',count)
You are defining your generator not correctly. You need methods __iter__ and __next__:
class generator(object):
def __init__(self, s, start_A, fact_A):
self.s = s
self.start_A = start_A
self.fact_A = fact_A
def __iter__(self):
return self
def __next__(self):
if self.s <= 0:
raise StopIteration()
gen_A = (self.start_A*self.fact_A)%2147483647
self.start_A = gen_A
yield bin(gen_A)[-16:]
self.s -= 1

How to stop a cycling thread

I have a cycling threading method like this:
def make_periodic(self, method, period_sec, *args):
method(*args)
parameters = [method, period_sec] + list(args)
threading.Timer(period_sec, self.make_periodic, parameters).start()
What is the best way to stop the the cycling of a method of one type?
For example:
import threading
class TestThreading:
PERIOD = 5
def __init__(self):
self.number = 0
self.text = "t"
def method_1(self):
print self.number
self.number += 1
def method_2(self, text):
print self.text
self.text += text
def make_periodic(self, method, period_sec, *args):
method(*args)
parameters = [method, period_sec] + list(args)
threading.Timer(period_sec, self.make_periodic, parameters).start()
if __name__ == '__main__':
test = TestThreading()
test.make_periodic(test.method_1, TestThreading.PERIOD)
test.make_periodic(test.method_2, TestThreading.PERIOD, "t")
# stops the cycling of method_2, but the method_1 continues
test.stop_threading(test.method_2)
Try to keep a reference for each timer in a dictionary: my_dict["method_name"] = timer. In that case when you decide to stop the timer just call my_dict["method_name"].cancel().

How to implement a iterator or generator for my Delegate class?

I implemented a Delegate class in Python 3, which wraps a function object in a object instance. It's possible to register multiple function objects on one delegate (in .NET terminology it's a MultiCastDelegate). Assumed all registered functions accept the same parameters, it's possible to invoke the delegate and call all functions at once.
Delegate implementation:
class Delegate:
def __init__(self, *funcs):
self.__invocationList__ = []
for func in funcs:
self.__invocationList__.append(func)
def __iadd__(self, func):
self.__invocationList__.append(func)
return self
def __isub__(self, func):
self.__invocationList__.remove(func)
return self
def __call__(self, *args, **kwargs):
if (len(self.__invocationList__) == 1):
return self.__invocationList__[0](*args, **kwargs)
else:
res = {}
for func in self.__invocationList__:
res[func] = func(*args, **kwargs)
return res
#property
def isMulticast(self):
return (len(self.__invocationList__) > 1)
Usage examples:
def test1():
return 5
def test2(a, b):
return a + b
def test3(a, b):
return a * b + 15
delegate = Delegate(test1)
result = delegate()
print("test1: {0}".format(result))
delegate = Delegate(test2)
result = delegate(3, 8)
print("test2: {0}".format(result))
delegate += test3
results = delegate(2, 9)
print("test2: {0}".format(results[test2]))
print("test3: {0}".format(results[test3]))
I would like to implement an iterator or generator on this class, so it's possible to use the delegate in for loops.
How could it look like?
# loop over every result from delegate, call with parameters 4 and 18
for result in delegate(4, 18):
print("function={0} result={1}".format(*result))
The iterators __next__() method should return a tuple consisting of the function-object and return value.
What I tried so far:
class Delegate:
# ...
# see code from above
def __iter__(self):
print("Delegate.__iter__():")
class iter:
def __init__(self2, *args, **kwargs):
print(str(args))
self2.__args = args
self2.__kwargs = kwargs
self2.__index = 0
def __iter__(self2):
return self2
def __next__(self2):
if (self2.__index == len(self.__invocationList__)):
raise StopIteration
func = self.__invocationList__[self2.__index]
self2.__index += 1
return func(*self2.__args, **self2.__kwargs)
return iter()
Because the constructor method is already in use by the Delegate creation itself, I implemented the iterator as a nested class. But unfortunately, I can not pass the call parameters *args and **kwargs to the iterator.
So my questions:
Is it possible and wise the implement a iterator / generator pattern for delegates?
What should I change to get it working?
I just tried to implement the iterator pattern. If it works, I would like to upgrade it to a generator - if possible :)
I'm not familiar with this, but I gave it a shot. It is not well tested, but it will help you on the way to solve your task. Here is the code:
class Delegate:
class IterDelegate:
def __init__(this, invocationList, *args, **kwargs):
this.__args = args
this.__kwargs = kwargs
this._invocationList = invocationList
def __iter__(this):
this.__index = 0
return this
def __next__(this):
if this.__index < len(this._invocationList):
func = this._invocationList[this.__index]
this.__index += 1
return (func.__name__, func(*this.__args, **this.__kwargs))
raise StopIteration
def __init__(self, func):
if (type(func) == 'list'):
self._invocationList = func
else:
self._invocationList = [func]
def __call__(self, *args, **kwargs):
return self.IterDelegate(self._invocationList, *args, **kwargs)
def __iadd__(self, func):
self._invocationList.append(func)
return self
def __isub__(self, func):
self._invocationList.remove(func)
return self
def test2(a, b):
return a + b
def test1(*args):
return 6
delegate = Delegate(test2)
delegate += test1
results = delegate(2,3)
for r in results:
print("function={0} result={1}".format(*r))
This will give the results
function=test2 result=5
function=test1 result=6

Resources