Im trying to subtract with prefixes as objects.
Here is my code
class Prefix:
def __init__(self, m=0, cm=0):
self.m = m
self.cm = cm
def __sub__(self, other):
centim = self.cm - other.cm
meter = (self.m - other.m) - abs(centim/100)
if meter < 1:
centim = m*100
meter = 0
return Prefix(meter, cm)
Im trying to subtract in a way which creates a negative centimeter value and take 1m from the meter object such that this is fulfilled
Prefix(2, 20) - Prefix(1, 30) == Prefix(0, 90)
First, keep in mind that for a given length, everything to the right of the hundreds place goes into cm, and everything at it or to its left gets divided by 100, and then goes into m.
Given this, we can recast the problem as converting both Prefix objects into their full lengths, performing calculations there, and then creating a new Prefix from the result:
class Prefix:
def __init__(self, m=0, cm=0):
self.m = m
self.cm = cm
def __sub__(self, other):
self_length = self.m * 100 + self.cm
other_length = other.m * 100 + other.cm
result_length = self_length - other_length
result_m, result_cm = divmod(result_length, 100)
return Prefix(result_m, result_cm)
result = Prefix(2, 20) - Prefix(1, 30)
print(result.m, result.cm)
Output:
0 90
Since we've come this far, we might as well store a "length" and overload __repr__ to make the result prettier:
class Prefix:
def __init__(self, length):
self.length = length
def __sub__(self, other):
result_length = self.length - other.length
return Prefix(result_length)
def __repr__(self):
result_m, result_cm = self.split_up(self.length)
if result_m > 0:
return f'{result_m}m {result_cm}cm'
else:
return f'{result_cm}cm'
#staticmethod
def split_up(length):
return divmod(length, 100)
Prefix(220) - Prefix(130)
Output:
90cm
Related
I have this code consisting of a class and a subclass. The class is Euler forward, while the second one is Eulers midpoint method. These are for solving an ODE (x'=x(1/2-x)). Now it doesn't seem to work because when I am to call the function, by typing:
Euler=H.solve(6)
where the 6 is the amount of steps, I get attributeerror.
AttributeError: 'int' object has no attribute 'size'
Could anyone help me make my code more robust and working so I could plot the values later on, really don't see whats wrong. My code below:
import numpy as np
class H:
def __init__(self, f):
self._f = f
def initial(self, u0):
self._u0 = u0
def solve(self, time_points):
n = time_points.size
self._t = time_points
self._u = np.zeros(n)
self._u[0] = self._u0
for k in range(n-1):
self._k = k
self._u[k+1] = self.advance()
return self._u, self._t
class F(H):
def ad(self):
u = self._u; t = self._t; f = self._f; k = self._k
dt = t[k+1] - t[k]
u_k12 = u[k] + dt/2 * f(u[k], t[k])
return u[k] + dt * f(u_k12, (t[k] + dt/2) )
I think what's wrong is the way you use the class. Initial value is set with initial method (u0), then you give solve method the list of points. You can use np.linscape to generate midpoint.
np.linspace(0, 3, 31) # 30 points evenly spaced between 0 and 3
So it's like this:
def func(x, y):
return x * y
midpoint = np.linspace(0, 3, 31)
F_ = F(func)
F_.initial(6)
F_.solve(midpoint)
Code:
class H:
def __init__(self, f):
self._f = f
def initial(self, u0):
self._u0 = u0
def solve(self, time_points):
n = time_points.size
self._t = time_points
self._u = np.zeros(n)
self._u[0] = self._u0
for k in range(n-1):
self._u[k+1] = self.advance(k)
return self._u, self._t
def advance(self, k):
....
class F(H):
def advance(self, k):
dt = self._t[k+1] + self._t[k]
u_k12 = self._u[k] + dt/2 * self._f(self._u[k], self._t[k])
return self._u[k] + dt * self._f(u_k12, (self._t[k] + dt/2))
I'm trying to implement a genetic algorithm for solving the Travelling Salesman Problem (TSP).
I have 2 classes, which are City and Fitness.
I have done the code for initialization.
class City:
def __init__(self, x, y):
self.x = x
self.y = y
def distance(self, city):
xDis = abs(self.x - city.x)
yDis = abs(self.y - city.y)
distance = np.sqrt((xDis ** 2) + (yDis ** 2))
return distance
def __repr__(self):
return "(" + str(self.x) + "," + str(self.y) + ")"
class Fitness:
def __init__(self, route):
self.route = route
self.distance = None
self.fitness = None
def routeDistance(self):
if self.distance == None:
pathDistance = 0.0
for i in range(0, len(self.route)):
fromCity = self.route[i]
toCity = None
if i+1 < len(self.route):
toCity = self.route[i+1]
else:
toCity = self.route[0]
pathDistance += fromCity.distance(toCity)
self.distance = pathDistance
return self.distance
def routeFitness(self):
if self.fitness == None:
self.fitness = 1 / float(self.routeDistance())
return self.fitness
def selection(population, size=None):
if size== None:
size= len(population)
matingPool = []
fitnessResults = {}
for i in range(0, size):
fitnessResults[i] = Fitness(population[i]).routeFitness()
matingPool.append(random.choice(population))
return matingPool
The code above just randomly selects a parent in the selection method.
My question is: How to code to select a parent using roulette wheels?
You could try this [1, 2]:
from numpy.random import choice
def selection(population, size=None):
if size== None:
size= len(population)
fitnessResults = []
for i in range(0, size):
fitnessResults.append(Fitness(population[i]).routeFitness())
sum_fitness = sum(fitnessResults)
probability_lst = [f/sum_fitness for f in fitnessResults]
matingPool = choice(population, size=size, p=probability_lst)
return matingPool
Read this
So basically, the higher a fitness value, the higher are its chances to be chosen. But that is when high fitness value means a high fitness. But in TSP a lower value of fitness is better so to implement this, we need to implement the concept where probability is indirectly proportional to the fitness value.
Here is something I had implemented in python with some changes
def choose_parent_using_RWS(genes, S):
P = random.uniform(0, S)
for x in genes:
P += get_fitness_value(x)
if P > S:
return x
return genes[-1]
where S is the sum of the inverse of the fitness values of the current population (i.e, 1/f1 + 1/f2 + 1/f3 + ...)
and
get_fitness_value(x) returns the inverse of the distance, just like your routeFitness() function
TeeHee
import math as m
class Circle:
def __init__(self,radius):
self.radius = radius
count = 0
def area(r):
k = m.pi * m.pow(r,2)
return k
I am not sure what wrong with the code above but when I am trying execute like below
a = Circle(4)
a.area()
it throws an error like
" k = m.pi * m.pow(r,2)
TypeError: must be real number, not Circle"
Unable to understand how it's considering the float value as an instance to the circle.
The first argument of an instance method is a reference to the instance itself (usually called self) - that's where the Circe is coming from. You shouldn't be passing the radius, you should be using the member you have:
def area(self):
k = m.pi * m.pow(self.radius, 2)
return k
import math as m
DEFAULT_RADIUS = 0.5
class Circle(object):
def __init__(self, radius=DEFAULT_RADIUS):
self.radius = radius
count = 0
def area(self, r=None):
if r is not None:
self.radius = r
k = m.pi * m.pow(self.radius, 2)
return k
a = Circle(4)
a.area()
I am working on the exorcism.io clock exercise and I can not figure out why this test is failing. The results look identical and even have the same type.
Here is my code:
class Clock:
def __init__(self, h, m):
self.h = h
self.m = m
self.adl = 0
def make_time(self):
s = self.h * 3600
s += self.m * 60
if self.adl: s += self.adl
while s > 86400:
s -= 86400
if s == 0:
return '00:00'
h = s // 3600
if h:
s -= h * 3600
m = s // 60
return '{:02d}:{:02d}'.format(h, m)
def add(self, more):
self.adl = more * 60
return self.make_time()
def __str__(self):
return str(self.make_time()) # i don't think I need to do this
if __name__ == '__main__':
cl1 = Clock(34, 37) #10:37
cl2 = Clock(10, 37) #10:37
print(type(cl2))
print(cl2, cl1)
print(cl2 == cl1) #false
A custom class without an __eq__ method defaults to testing for identity. That is to say, two references to an instance of such a class are only equal if the reference they exact same object.
You'll need to define a custom __eq__ method that returns True when two instances contain the same time:
def __eq__(self, other):
if not isinstance(other, Clock):
return NotImplemented
return (self.h, self.m, self.adl) == (other.h, other.m, other.adl)
By returning the NotImplemented singleton for something that is not a Clock instance (or a subclass), you let Python know that the other object could also be asked to test for equality.
However, your code accepts values greater than the normal hour and minute ranges; rather than store hours and minutes, store seconds and normalise that value:
class Clock:
def __init__(self, h, m):
# store seconds, but only within the range of a day
self.seconds = (h * 3600 + m * 60) % 86400
self.adl = 0
def make_time(self):
s = self.esconds
if self.adl: s += self.adl
s %= 86400
if s == 0:
return '00:00'
s, h = s % 3600, s // 3600
m = s // 60
return '{:02d}:{:02d}'.format(h, m)
def __eq__(self, other):
if not isinstance(other, Clock):
return NotImplemented
return (self.seconds, self.adl) == (other.seconds, other.adl)
Now your two clock instances will test equal because internally they store the exact same time in a day. Note that I used the % modulus operator rather than a while loop and subtracting.
I'm new to Python and I really want to understand why I get this error.
It happens in my findLargest function, while trying to execute the second for loop. The thing is that the second for loop does basically the same thing as the first one, but for some reason I get an error as I try to call on a (class)method. How can this be? Am I not allowed to have 2 for loops for same iterable in the same function?
shapeArea=shape.area()
throws:
TypeError: 'float' object is not callable
The objective of findlargest() is to loop through the set of classes twice, first in order to find the largest value(Area) while the second tries to find if there are other values that are equal.
class Shape(object):
def area(self):
raise AttributeException("Subclasses should override this method.")
class Triangle(Shape):
def __init__(self, base, height):
self.base = base
self.height = height
def area(self):
self.area = (self.base * self.height) / 2
return self.area
def __str__(self):
return "{} with base {} and height {}".format(self.__class__.__name__, self.base, self.height)
def __eq__(self, other):
return type(other) == Triangle and self.base == other.base and self.height == other.height
class ShapeSet:
def __init__(self):
self.shape_list = []
def addShape(self, sh):
if sh not in self.shape_list:
self.shape_list.append(sh)
else:
print ("{} is already existing".format(sh.__str__()))
def __iter__(self):
return (self.shape_list)
def __str__(self):
s = ''
for shape in self.__iter__():
s+= shape.__str__() + "\n"
return s
ss = ShapeSet()
ss.addShape(Triangle(1.2,2.5))
ss.addShape(Triangle(1.4,2.5))
ss.addShape(Triangle(1.3,2.5))
ss.addShape(Triangle(1.5,2.5))
def findLargest(shapes):
maxs = None
maxA = 0.0
for shape in shapes.__iter__():
shapeArea = shape.area()
if shapeArea > maxA or maxs == None:
maxs = shape
maxA = shapeArea
maxTuple = (maxs)
for shape in shapes.__iter__():
shapeArea = shape.area()
With this:
def area(self):
self.area=(self.base*self.height)/2
return self.area
You enter the method and then immediately mask it by assigning a different name to its reference. From then on, self.area refers to that number and you can no longer access that method. Fortunately, the fix is easy: don't save a reference at all.
def area(self):
return self.base * self.height / 2
Python does not separate the names for function/method objects and for other objects. Use unique reference names for any objects you'd like to retain.
I think your problem is here:
class Triangle(Shape):
def __init__(self, base, height):
self.base=base
self.height=height
def area(self):
self.area=(self.base*self.height)/2 ###################### HERE
return self.area
If you have
shape = Triangle(1.5,2.5)
shape.area() # returns float assigned at "HERE" to shape.area
shape.area() # try to call that float assigned in previous step at "HERE"