Python iteration over non-sequence in an array with one value - python

I am writing a code to return the coordinates of a point in a list of points. The list of points class is defined as follows:
class Streamline:
## Constructor
# #param ID Streamline ID
# #param Points list of points in a streamline
def __init__ ( self, ID, points):
self.__ID = ID
self.__points = points
## Get all Point coordinates
# #return Matrix of Point coordinates
def get_point_coordinates ( self ):
return np.array([point.get_coordinate() for point in self.__points])
With
class Point:
## Constructor
# #param ID Streamline ID
# #param cor List of Coordinates
# #param vel List of velocity vectors (2D)
def __init__ ( self, ID, coord, veloc):
self.__ID = ID
self.set_coordinate( coord )
self.set_velocity( veloc )
The thing is that I start my code by defining a Streamline with one Point in the point list. A little down the road I call the function get_point_coordinates and the iteration over the list of points raises the following error:
return np.array([point.get_coordinate() for point in self.__points])
TypeError: iteration over non-sequence
I need to find a way to bypass this error and neatly return just a 1x2 matrix with the point coordinates.
I've had a look at this question but it wasn't very helpful.

Either call the Streamline-constructor with a sequence instead of a single point: sl = Streamline(ID, [first_point])
Or ensure the constructor makes the single point to be iterable:
class Streamline:
def __init__ ( self, ID, first_point):
self.__ID = ID
self.__points = [first_point]
It is a bad idea to write the constructor to accept a single point (Streamline(ID, point1)) and a sequence of points (Streamline(ID, [point1, point2, ...])). If you want so, you can do
from collections import Iterable
class Streamline:
def __init__ ( self, ID, first_point):
self.__ID = ID
self.__points = points if isinstance(points, Iterable) else [points]
Better than 3. would be to unpack the points given in arguments via * to enable Streamline(ID, point1) and Streamline(ID, point1, point2, ...).
class Streamline:
def __init__ ( self, ID, *points):
self.__ID = ID
self.__points = points

Related

Error while testing the TestAreaCreation in Python using Unittest

Question:
Define a class Circle with method init which initializes a cicle with
attribute radius, having follwing restrictions.
radius must be numeric value, if not raise type error with error message "radius must be number".
radius must be between 0 to 1000 inclusive on both sides, if not raise the value error with error message "radius must be between 0 and
1000 inclusive"
Define a class method area and circumference which must return values rounded off to 2 decimals.
Complete the definition of class TestCircleArea which tests the
behaviour of area method as specification below.
Define the test method test_circlearea_with_random_numeric_radius
which creates circle c1 with radius 2.5 and check if its computed area
match the value 19.63
Define the test method test_circlearea_with_min_radius which creates
circle c2 with radius 0 and check if its computed area match the value
0
Define the test method test_circlearea_with_max_radius which creates
circle c3 with radius 1000 and check if its computed area match the
value 3141592.65
Tried solution:
import inspect
import re
import unittest
import math
class Circle:
def __init__(self, radius):
# Define the initialization method below
self.radius=radius
if not isinstance(self.radius,(int,float)):
raise TypeError("radius must be a number")
elif(self.radius>1000 or self.radius<0):
raise ValueError("radius must be between 0 and 1000 inclusive")
else:
pass
def area(self):
# Define the area functionality below
return math.pi*(self.radius**2)
def circumference(self):
return 2*math.pi*self.radius
# Define the circumference functionality below
class TestCircleArea(unittest.TestCase):
def test_circlearea_with_random_numeric_radius(self):
# Define a circle 'c1' with radius 2.5, and check if
# its area is 19.63.
c1=Circle(2.5)
self.assertEqual(c1.area(), 2.5)
def test_circlearea_with_min_radius(self):
# Define a circle 'c2' with radius 0, and check if
# its area is 0.
c2=Circle(0)
self.assertEqual(c2.area(), 0)
def test_circlearea_with_max_radius(self):
# Define a circle 'c3' with radius 1000.1. and check if
# its area is 3141592.65.
c3=Circle(1000)
self.assertEqual(c3.area(), 3141592.65)
if __name__ == '__main__':
fptr = open('output.txt', 'w')
runner = unittest.TextTestRunner(fptr)
unittest.main(testRunner=runner, exit=False)
fptr.close()
with open('output.txt') as fp:
output_lines = fp.readlines()
pass_count = [ len(re.findall(r'\.', line)) for line in output_lines if line.startswith('.')
and line.endswith('.\n')]
pass_count = pass_count[0]
print(str(pass_count))
doc1 = inspect.getsource(TestCircleArea.test_circlearea_with_random_numeric_radius)
doc2 = inspect.getsource(TestCircleArea.test_circlearea_with_min_radius)
doc3 = inspect.getsource(TestCircleArea.test_circlearea_with_max_radius)
assert1_count = len(re.findall(r'assertEqual', doc1))
print(str(assert1_count))
assert1_count = len(re.findall(r'assertEqual', doc2))
print(str(assert1_count))
assert1_count = len(re.findall(r'assertEqual', doc3))
print(str(assert1_count))
Error:
Traceback (most recent call last):
File "Solution.py", line 61, in <module>
pass_count = pass_count[0]
IndexError: list index out of range
Please assist what's wrong.
I have just modified the init method and it worked for me in hacker rank.
class Circle:
def __init__(self, radius):
# Define the initialization method below
pattern=re.compile("^\\-?[0-9]")
if(pattern.math(str(radius))):
if(radius>=0 and radius<=1000):
self.radius=radius
else:
raise ValueError("radius must be between 0 and 1000 inclusive")
else:
raise TypeError("radius must be a number")
def area(self):
# Define the area functionality below
return math.pi*(self.radius**2)
def circumference(self):
return 2*math.pi*self.radius
# Define the circumference functionality below
you must specify return statements
class TestCircleArea(unittest.TestCase):
def test_circlearea_with_random_numeric_radius(self):
# Define a circle 'c1' with radius 2.5, and check if
# its area is 19.63.
c1=Circle(2.5)
return c1.area
return self.assertEqual(c1.area,19.3)
def test_circlearea_with_min_radius(self):
# Define a circle 'c2' with radius 0, and check if
# its area is 0.
c2=Circle(0)
return c2.area
return self.assertEqual(c2.area,0)
def test_circlearea_with_max_radius(self):
# Define a circle 'c3' with radius 1000.1. and check if
# its area is 3141592.65.
c3=Circle(1000)
return c3.area
return self.assertEqual(c3.area,3141592.65)
Modify the driver code :
Remove/delete the passcount line
Directly assign the value i.e. total number of tests to be performed.(pass_count = 3).

Graph of objects using graph-tool

I'm trying to use the library graph-tool to create a new graph of objects. In particular I want some nodes of students and others of professors.
In the following the code I've written, I'm not able to add the vertices of students/professors.
The documentations https://graph-tool.skewed.de/static/doc/quickstart.html#property-maps explains that I have to use the class PropertyMap, it's quite weird for me...
Could someone explain to me how to use it? Thanks.
This is my code:
from graph_tool.all import *
class Student:
def __init__(self, name):
self.name = name
class Professor:
def __init__(self, name):
self.name = name
g = Graph()
s = Student("Luke")
p = Professor("Adam")
print(s.name)
print(p.name)
Well first you need to add the vertices to the graph
# your code
# from graph_tool.all import * # avoid importing all, it makes it inclear what you are using afterwards
import graph_tool as gt
class Student:
def __init__(self, name):
self.name = name
class Professor:
def __init__(self, name):
self.name = name
g = gt.Graph()
s = Student("Luke")
p = Professor("Adam")
print(s.name)
print(p.name)
Luke
Adam
you create a property map with for the type of your users
g.vertex_properties['user_type'] = g.new_vertex_property('string')
This will be a property for your nodes. You can create how many you want and then set their user_type
For exemple :
# creating a graph of 3 users
g.add_vertex(3)
# Let's set the first vertex as a professor
g.vp['user_type'][g.vertex(0)] = 'professor'
# and the subsequent as students
for v in g.get_vertices()[1:]:
g.vp['user_type'][v] = 'student'
# let's add an edge from the professor to the first student
g.add_edge(g.vertex(0), g.vertex(1))
<Edge object with source '0' and target '1' at 0x7f2c30370c30>
Now you can draw your graph using the property
def translate_elts_to_gtshape(g, source_prop='user_type', tdict=None):
"""This function adds a new property map called 'shape' to graph g. It is populated by translating the source_prop with the tdict (translation dictionary) which should map source_property entries to shapes"""
if tdict is None:
tdict = {'professor': 'square',
'student': 'circle'}
# source_property map array. It's of string type so we use get_2d_array
svp = g.vp[source_prop].get_2d_array([0])[0]
for k, v in tdict.items():
# for each key, value pair of tdict we change the source value (ie k) to the shape (v)
svp[svp == k] = v
# and now we create the new property shape
g.vertex_properties['shape'] = g.new_vertex_property('string')
for v, p in zip(g.vertices(), svp):
# and copy in it the shape
g.vp['shape'][v] = p
# we return the new property created, although it is already added to the graph as an internal property
return g.vp['shape']
translate_elts_to_gtshape(g)
<PropertyMap object with key type 'Vertex' and value type 'string', for Graph 0x7f2c5c3d6510, at 0x7f2c2997c950>
# let's just check what we have in our newly created shape property
[g.vp['shape'][v] for v in g.vertices()]
['square', 'circle', 'circle']
# and now let's use it to draw our graph
import graph_tool.draw as gtd
pos = gtd.sfdp_layout(g)
gtd.graph_draw(g, pos=pos,
output_size = (300, 300),
output_file = 'mynetwork.png', # where your file goes
vertex_shape=g.vp['shape'],
vertex_text=g.vertex_index)
<PropertyMap object with key type 'Vertex' and value type 'vector<double>', for Graph 0x7f2c5c3d6510, at 0x7f2c14291590>

simple CLASS in python

from math import pi
class sphere(object):
def __init__(self,radius):
self.radius = radius
def get_radius(self):
return radius
def surfaceArea(self):
return 4*pi*radius**2
def volume(self):
return (4//3)*pi*radius**3
radius = input("Please enter your radius:")
print sphere.get_radius()
print sphere.surfaceArea()
print sphere.volume()
i need to write the program that prompts the user for a radius then uses your sphere class to output the surface area and volume of a sphere. and I get a type error unbound method get_Radius() must be called with sphere instance as first argument(got nothing instead). Any way to solve this problemo?
You have never created an object from class sphere. Instead of calling sphere.get_radius(), you need to first initiate an object from that class, then call the method on that object.
a = sphere(radius) # initiate an object of class sphere called a
a.get_radius() # call method on the object a.
you need to create a new object and assign redius variable
You need also to use self.redius inside the class.
Check the code below for the above mentioned-comments
from math import pi
class sphere(object):
def __init__(self,radius):
self.radius = radius
def get_radius(self):
return self.radius
def surfaceArea(self):
return 4*pi*self.radius**2
def volume(self):
return (4//3)*pi*self.radius**3
radius = input("Please enter your radius:")
s= sphere(radius)
print s.get_radius()
print s.surfaceArea()
print s.volume()

Property set correctly inside an object but not accessible outside

I'm working under python pyramid, with Python3.
I have a model that looks like this:
class OneTimeCode(Base):
__tablename__ = 'otc_one_time_codes'
otc_one_time_code_id = Column(Integer, primary_key=True)
otc_one_time_code = Column(String(32))
otc_usr_user_id = Column(Integer, ForeignKey('usr_users.usr_user_id'), nullable=True)
otc_expire_time = Column(DateTime)
def __init__(self, otc_usr_user_id, otc_expire_time=None):
self.otc_usr_user_id = otc_usr_user_id
if otc_expire_time is None:
self.otc_expire_time = (datetime.now() + timedelta(6*365/12)).isoformat()
else:
self.otc_expire_time = otc_expire_time
#classmethod
def get_code(self, hlength=6):
seed = datetime.now() + timedelta(random.randrange(1,10000))
tmp_hash = hashlib.md5(seed.strftime("%Y-%m-%d %H:%M:%S.%F").encode('utf-8')).hexdigest()
if hlength == 32:
self.otc_one_time_code = tmp_hash
else:
self.otc_one_time_code = tmp_hash[0 : hlength]
print(self.otc_one_time_code)
The problem is, when I instantiate one of these objects and then explicitly call get_code, the print line at the end prints to the screen the code successfully.
However, in my view, if I explicitly try to print that property, it's 'None'
Here's what my view code looks like:
otc = OneTimeCode(
otc_usr_user_id = user.usr_user_id
)
otc.get_code()
pprint.pprint(vars(otc))
session.add(otc)
And the console output looks like this:
0d097c
{'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x50877d0>, 'otc_expire_time': '2015-02-13T10:56:14.244447', 'otc_usr_user_id': 1} 2014-08-14 22:56:14,245
INFO [sqlalchemy.engine.base.Engine][Dummy-2] INSERT INTO otc_one_time_codes (otc_one_time_code, otc_usr_user_id, otc_expire_time) VALUES (%(otc_one_time_code)s, %(otc_usr_user_id)s, %(otc_expire_time)s) RETURNING otc_one_time_codes.otc_one_time_code_id 2014-08-14 22:56:14,245
INFO [sqlalchemy.engine.base.Engine][Dummy-2] {'otc_one_time_code': None, 'otc_expire_time': '2015-02-13T10:56:14.244447', 'otc_usr_user_id': 1} 2014-08-14 22:56:14,247
INFO [sqlalchemy.engine.base.Engine][Dummy-2] COMMIT
You can see the value inside the model: 0d097c, and also the pprint object, where it doesn't look like the property exists.
Why can't I get access to this property?
Looks like you should be using a #property instead of a OTC, however it also seems like this may be something you DON'T want to calculate each time!
# for all the docstrings, let multi = Multi(2)
class Multi(object):
def __init__(self, attribute):
"""When instantiated, set self.attribute to attribute"""
self.attribute = attribute
#property
def attribute_times_ten(self):
"""accessed via multi.attribute_times_ten
and will return 20. Use properties to signify
a variable that requires some work done to it
that needs to calculated each time it's called."""
return attribute_times_ten
#classmethod
def times_ten(cls, num):
"""Not the best example, but a #classmethod will
give the class as its first argument, NOT the
instance. This is useful in lots of constructor
settings, e.g. CreateClass.fromstring("attributes")"""
return num * 5
def generate_number(self, multiplier):
"""This is just a normal method. This is what I think
you want, tbh, and you should probably call it in your
__init__ method since you NEED this to run in your OTC
for it to work as intended. Methods (like properties)
are automagically passed the instance as the first
argument, so we can CHANGE self.attribute with that."""
self.attribute = self.attribute * multiplier
Docstrings should be self descriptive, but:
multi = Multi(2)
multi.attribute_times_ten # returns 20
Multi.times_ten(8) # returns 80, note the capital M!
multi.generate_number(3) # self.attribute is now 6
multi.attribute_times_ten # returns 60
A real-world case where you might need all of the above:
class _Tile(object):
def __init__(self, x, y):
"""A naive implementation of Tile that doesn't care
what its side length is and doesn't have any properties
to hide its attributes"""
self.x = x
self.y = y
#classmethod
def tiles_to_pixels(cls, tile):
return cls(tile._x * tile.side_length, tile._y * tile.side_length)
#classmethod
def tiles_to_tiles(cls, tile):
return cls(tile._x, tile._y)
class Tile(object):
def __init__(self, x, y, side_length):
"""A tile object in a map"""
self._x = x # x-coord in tiles
self._y = y # y-coord in tiles
self.side_length = side_length # pixels per tile
#property
def in_pixels(self):
"""self.in_pixels returns an object whose .x and .y
correspond to the x and y position IN PIXELS of the
top-left corner of the tile."""
_tile = _Tile.tiles_to_pixels(self)
return _tile
#property
def in_tiles(self):
"""self.in_tiles returns an object whose .x and .y
correspond to the x and y position IN TILES of the
top-left corner of the tile."""
_tile = _Tile.tiles_to_tiles(self)
return _tile
def change_side_length(self, new_length):
"""Use to change the side length. This can break
your whole map since it's naive, so be careful."""
self.side_length = new_length
my_tile = Tile(0,0,32) # 32 pixel tile starting at (0,0)
my_tile.x # NameError, since it's called my_tile._x
my_tile.in_tiles.x # 0
my_tile.in_pixels.y # 0
other_tile = Tile(4,7,32) # 32 pixel tile starting at (4,7)
other_tile.y # NameError, see above
other_tile.in_tiles.y # 7
other_tile.in_pixels.x # 128

How do I rewrite this function now that it needs to call upon a method in a class from a different file?

Here is the function (it's in a file, "worldmodel.py"):
def add_entity(world, entity):
pt = entities.get_position(entity)
if within_bounds(world, pt):
old_entity = occ_grid.get_cell(world.occupancy, pt)
if old_entity != None:
entities.clear_pending_actions(old_entity)
occ_grid.set_cell(world.occupancy, pt, entity)
world.entities.append(entity)
And here is the class in a file named, "occ_grid.py":
class Grid:
def __init__(self, width, height, occupancy_value):
self.width = width
self.height = height
self.cells = []
# initialize grid to all specified occupancy value
for row in range(0, self.height):
self.cells.append([])
for col in range(0, self.width):
self.cells[row].append(occupancy_value)
def set_cell(self, point, value):
self.cells[point.y][point.x] = value
My question is, how would I rewrite the line of code in "def add_entity" that refers to "set_cell"? (Now that I've made set_cell a method of the class Grid) NOTE: Before I made set_cell part of the grid class, it was a function outside of the class (but still in the same file as the class) Thanks!
You'll need to import occ_grid in your worldmodel.py, then instantiate a Grid object and call that objects set_cell()-method. The add_entity needs to get the Grid-object as its parameter unless it can safely instantiate new ones at will.
Here's a naive example which does not work but demonstrates what I mean:
import occ_grid
g = occ_grid.Grid(your_width, your_height, occupancy)
def add_entity(world, entity, grid):
pt = entities.get_position(entity)
if within_bounds(world, pt):
old_entity = grid.get_cell(world.occupancy, pt)
if old_entity != None:
entities.clear_pending_actions(old_entity)
grid.set_cell(world.occupancy, pt, entity)
world.entities.append(entity)
add_entity(world, entity, g)
Unless you make the set_cell function a static method of the Grid class, you're going to need and instance of Grid.
from occ_grid import Grid
I am going to make an assumption here, and say that your want your grid to be part of the world? Either way, this is an example of instantiating that class.
class World:
grid = Grid()
def add_entity(world, entity):
# All that other stuff.
world.grid.set_cell(pt, entity)
There are two issues here, (1) calling functions across modules and (2) calling methods of classes.
It seems you can already do (1).
The trick is that although methods are defined as
def methodName(self, ...)
They are called as
object.methodName(...)
And object implicitly becomes the "self" Parameter. Here is an example:
import occ_grid # Import the module (file) that contains Grid.
.
.
world.occupancy = occ_grid.Grid() # Create an instance of Grid.
.
.
def add_entity(world, entity):
pt = entities.get_position(entity)
.
.
world.occupancy.set_cell(pt, entity)
In this example, grid is a global variable, which is probably not a good design. I guess it should be a property of world, but that's only a guess.

Categories