Getting values from a dictionary - python

Below is a code which I am working with. My program creates combination of possible positions and gets the last position. Then I want to get the value for that position based on the letter from list A and a dictionary dictionary VALUES. When I execute this code I get:
AttributeError: 'Combination' object has no attribute 'get_value'
X = ['A','B','C']
Y = ['1','2','3']
VALUES_FOR_X = {'A':1, 'B': 2, 'C':3}
class Combination: # Creates a list of possible position combinations
def __init__(self,x,y):
if (x in X) and (y in Y):
self.x = x
self.y = y
else:
print "WRONG!!"
def __repr__ (self):
return self.x+self.y
class Position: # Makes operation on the chosen position
def __init__(self):
self.xy = []
for i in X:
for j in Y:
self.xy.append(Combination(i,j))
def choose_last(self):
return self.xy.pop()
def get_value(self):
return self.VALUES_FOR_X()
def __str__(self):
return "List contains: " + str(self.xy)
pos = Position()
print pos
last_item = pos.choose_last()
print "Last item is:", last_item
print last_item.get_value()
Does anyone knows how to change this code in the simplest way to make it working?
The logic of this program:
We have possible X,Y positions. We create all possible combinations. Then we chose the last position from possible combinations, eg.: C3
Untill here program works perfectly
Now I want to get values of position C3. Using dictionary value for 'C' in C3 is 3. And I want to print this value (3).
To do this I added method:
def get_value(self):
return self.VALUES_FOR_X()

If I understand you Problem correctly this is the Solution:
X = ['A','B','C']
Y = ['1','2','3']
VALUES_FOR_X = {'A':1, 'B': 2, 'C':3}
class Combination: # Creates a list of possible position combinations
def __init__(self,x,y):
if (x in X) and (y in Y):
self.x = x
self.y = y
else:
print "WRONG!!"
def get_value(self):
return VALUES_FOR_X[self.x]
def __repr__ (self):
return self.x+self.y
class Position: # Makes operation on the chosen position
def __init__(self):
self.xy = []
for i in X:
for j in Y:
self.xy.append(Combination(i,j))
def choose_last(self):
return self.xy.pop()
def __str__(self):
return "List contains: " + str(self.xy)
pos = Position()
print pos
last_item = pos.choose_last()
print "Last item is:", last_item
print last_item.get_value()
My output is:
>>> List contains: [A1, A2, A3, B1, B2, B3, C1, C2, C3]
>>> Last item is: C3
>>> 3

Related

How can i pass a requirement into a sort function, and create a template sort method to either sort one of the object of class "reading" in python

#i want to pass the list, and algorithm (bubblesort) into the sort method with a requirement (temp or wind_speed)
class Reading:
def __init__(self, _temperature, _windspeed):
self.temp = _temperature
self.windspeed = _windspeed
def bubblesort(num):
for i in range (len(num)-1, 0, -1):
for j in range (i):
if num[j] > num [j+1] :
temp = num[j]
num[j] = num[j+1]
num[j+1] = temp
return num
r_list = [Reading(randint(10, 60), randint(10, 60)) for i in range(20)]
def sort(lst, alg): #how do i pass the requirement, and alg?
bubblesort(lst)
sort(r_list, alg) #how do i create a templated bubblesort to either sort temp or windspeed?
#The Output is supposed to return a sorted list (r_list) according to the requirement
Here's an example how to pass a function as an argument to another function:
def add(x, y):
return x + y
def mul(x,y):
return x * y
def calculate(x, y, func):
return func(x, y)
z1 = calculate(1, 1, add)
z2 = calculate(1, 1, mul)
print(f"add = {z1}, mul = {z2}")

How to return a copy of an instance of a class?

I am currently practising python on code wars, here is a prompt:
Create a Vector object that supports addition, subtraction, dot products, and norms. So, for example:
a = Vector([1, 2, 3])
b = Vector([3, 4, 5])
c = Vector([5, 6, 7, 8])
a.add(b) # should return a new Vector([4, 6, 8])
a.subtract(b) # should return a new Vector([-2, -2, -2])
a.dot(b) # should return 1*3 + 2*4 + 3*5 = 26
a.norm() # should return sqrt(1^2 + 2^2 + 3^2) = sqrt(14)
a.add(c) # raises an exception
I have written functions add and subtract that pass some of the tests. However, I am running into issues with overwriting my previous list values of 'a' after running the add function. When I go into subtract, the 'a' values in the vector are the summations computed from the previous instance of the add function.
I suspect its due to me running this line of code:
return self.__class__(self.list) causing the instance of the class to overwrite itself.
Kindly please help, I believe I need to return a copy of the instance of the class but don't know how to do it.
class Vector:
def __init__(self, list):
self.list = list #[1,2]
self.copylist = list
def add(self,Vector):
try:
self.list = self.copylist
#take list from other vector
other = Vector.list
#take each value from other Vector and add it to self.list
for index,item in enumerate(Vector.list,0):
self.list[index] = item + self.list[index]
except:
print("Different size vectors")
#return the instance of a class
return self.__class__(self.list)
def subtract(self,Vector):
self.list = self.copylist
other = Vector.list
print(self.list)
print(other)
for index,item in enumerate(Vector.list,0):
self.list[index] = self.list[index] - item
return self.__class__(self.list)
def dot(self,Vector):
self.list = self.copylist
other = Vector.list
#print(self.list)
#print(other)
running_sum =0
for index,item in enumerate(Vector.list,0):
running_sum = running_sum + item * self.list[index]
#print(running_sum, " ", self.list[index], " ", item)
return running_sum
def norm(self):
running_sum = 0
for item in self.list:
running_sum += item**2
return running_sum ** 0.5
def toString(self):
return str(self.list)
`def equals(self,Vector):
return self.list == Vector.list
Here are some of the tests:
a = Vector([1, 2])
b = Vector([3, 4])
test.expect(a.add(b).equals(Vector([4, 6])))
a = Vector([1, 2, 3])
b = Vector([3, 4, 5])
test.expect(a.add(b).equals(Vector([4, 6, 8])))
test.expect(a.subtract(b).equals(Vector([-2, -2, -2]))) #code fails here
test.assert_equals(a.dot(b), 26)
test.assert_equals(a.norm(), 14 ** 0.5)
I think you're making this more complicated than it needs to be. You shouldn't be working with class objects at all. You should just be working with instances of the Vector class. Here's what I think your code should look like:
class Vector:
def __init__(self, initial_elements):
self.elements = list(initial_elements) # make a copy of the incoming list of elements
def add(self, other):
# insure that the two vectors match in length
if len(self.elements) != len(other.elements):
raise Exception("Vector sizes are different")
# copy our elements
r = list(self.elements)
# add the elements from the second vector
for index, item in enumerate(other.elements, 0):
r[index] += item
# return a new vector object defined by the computed elements
return Vector(r)
def subtract(self, other):
# insure that the two vectors match in length
if len(self.elements) != len(other.elements):
raise Exception("Vector sizes are different")
# copy our elements
r = list(self.elements)
# subtract the elements from the second vector
for index, item in enumerate(other.elements, 0):
r[index] -= item
# return a new vector object defined by the computed elements
return Vector(r)
def dot(self, other):
running_sum = 0
for index, item in enumerate(other.elements, 0):
running_sum += item * self.elements[index]
return running_sum
def norm(self):
running_sum = 0
for item in self.elements:
running_sum += item ** 2
return running_sum ** 0.5
def toString(self):
return str(self.elements)
def equals(self, other):
return self.elements == other.elements
def test():
a = Vector([1, 2])
b = Vector([3, 4])
print(a.add(b).equals(Vector([4, 6])))
a = Vector([1, 2, 3])
b = Vector([3, 4, 5])
print(a.add(b).equals(Vector([4, 6, 8])))
print(a.subtract(b).equals(Vector([-2, -2, -2])))
print(a.dot(b) == 26)
print(a.norm() == 14 ** 0.5)
test()
Result:
True
True
True
True
True
The general structure of your code is spot on.
One thing to note is that you shouldn't be using list as a variable name, as it is a type name in Python. Also, you don't want to be passing around Vector as a value. You want to be passing instances of Vector and list, with names that do not conflict with these type names.
My solution assumes you want Vector instances to be immutable, so each of your operations will return a new Vector object. You could also have them not be immutable and have, for example, the add method just add the incoming vector into the target vector without creating a new object. I like keeping them immutable. I've been doing more and more of this "functional style" programming lately, where calls to object methods don't modify the target object (don't have side effects), but rather just return a new object.
I like your use of the test class to do your testing. I chose to not deal with this, and just print the results of each test comparison to see that they all come out to True. I'll leave it to you to restore your tests to using a test object with expect and assert_equals methods.
UPDATE: Here is a more compact way to write your add and subtract methods:
def add(self, other):
# insure that the two vectors match in length
if len(self.elements) != len(other.elements):
raise Exception("Vector sizes are different")
return Vector([self.elements[i] + other.elements[i] for i in range(len(self.elements))])
def subtract(self, other):
# insure that the two vectors match in length
if len(self.elements) != len(other.elements):
raise Exception("Vector sizes are different")
return Vector([self.elements[i] - other.elements[i] for i in range(len(self.elements))])
change:
return self.__class__(self.list)
to:
return self
although this would the same as,
return Vector(self.list)
if the class is more complicated it is better to return self
I think that's the issue, hope it helps :)
also, it is good practice to use different names. you used Vector for the class name as well as many of the inputs of the functions, you will run into problems when you do that.
Please change function toString to str . its' already done.
class Vector :
def __init__(self , lst_vec):
self.lst_vec = lst_vec
def show_vector(self):
return self.lst_vec
def add(self , v ):
size_self = len(self.lst_vec)
size_v = len(v.lst_vec)
new_vector = []
if ( size_self != size_v ):
return Exception("error add")
else:
for i in range(size_self):
new_vector.append(self.lst_vec[i] + v.lst_vec[i])
return Vector(new_vector)
def subtract(self , v ):
size_self = len(self.lst_vec)
size_v = len(v.lst_vec)
new_vector = []
if ( size_self != size_v ):
return Exception("error subtract")
else:
for i in range(size_self):
new_vector.append(self.lst_vec[i] - v.lst_vec[i])
return Vector(new_vector)
def dot(self , v ):
size_self = len(self.lst_vec)
size_v = len(v.lst_vec)
new_vector = []
sum_vec = 0
if ( size_self != size_v ):
return Exception("Vector sizes are different")
else:
for i in range(size_self):
new_vector.append(self.lst_vec[i] * v.lst_vec[i])
for i in range(len(new_vector)):
sum_vec+=new_vector[i]
return sum_vec
def norm (self):
new_vec_sum = 0
for i in range(len(self.lst_vec)):
new_vec_sum +=( self.lst_vec[i] ) **2
return new_vec_sum ** 0.5
def toString(self):
str_self = '('
for i in range(len(self.lst_vec)):
str_self += str(self.lst_vec[i])
if i < (len(self.lst_vec)-1):
str_self+=','
else : pass
str_self+=')'
return str_self
def equals(self , v ):
return self.lst_vec == v.lst_vec
a = Vector([1,2,3])
b = Vector([3,4,5])
c = Vector([5,6,7,8])
print(a.add(b).show_vector())
print( a.add(b).equals(Vector([4,6,8])) )
print(a.subtract(b).show_vector())
print(a.dot(b))
print(a.norm())
print((a.toString() == '(1,2,3)'))
print(c.toString())

Python object1 = object2

I am writing a vector class in python (just to see if i can). i ran into a problem with the subtract method and i have no idea what could be causing this.
this is the class (i omitted "class Vector:").
def __init__(self, p):
print self
self.p = p
def __str__(self):
return str(list(self.p))
def equals(self, v):
if type(self) == type(v):
return str(self) == str(v)
return false
def size(self):
return len(self.p)
def add(self, v):
a = self.p
b = v.p
if self.size() == v.size():
for i in range(0, self.size()):
a[i] += b[i]
return Vector(a)
raise Exception()
def subtract(self, v):
a = self.p
b = v.p
if self.size() == v.size():
for i in range(0, self.size()):
a[i] -= b[i]
return Vector(a)
raise Exception()
def dot(self, v):
total = 0
if self.size() == v.size():
for i in range(0, len(self.p)):
total += self.p[i] * v.p[i]
return total
raise Exception()
def norm(self):
total = 1
if self.size() == v.size():
for i in range(0, len(self.p)):
total += self.p[i]^2
return total
raise Exception()
when i try to do:
a = Vector([1,1])
a.subtract(Vector[1,1])
print a
my thought says i should get [1,1] as output because i do not change any values of Vector a when i do the subtraction, i return a new vector with the values it should have. when i print the object it shows me that it is in a different space in memory but my output from 'print a' is [0,0]
also if i do
a = Vector(1,1)
b = a
a.subtract(Vector([1,1])
print a,b
my output is [0,0][0,0], what i want is [0,0][1,1]
why does b change with a ?
First question:
(1, 1) - (1, 1) == (0, 0)
The output of your program is correct. You change the values of a in your function with a[i] -= b[i] where a is the list of coordinates (not a copy of the list) in self and b the list of coordinates (again, not a copy) in v.
Second question:
b = a
a and b are now the same object (not different objects with the same value), so they change simultaneously.
Think of a and b as addresses for your computer.
a = Vector(1,1) # There is a Vector object somewhere in memory, e.g. 12345. Then a = 12345
b = a # b = a = 12345 (still the address of the same Vector object)
a.subtract(Vector([1,1])) # Change whatever is stored at the address of a = 12345
print a,b # both are still the address of the same object you modified in the previous step!

Python - counting nucleotides

So I am supposed to devise a program that counts a DNA sequence as well as count the individual base pairs. Here's what I have thus far:
class dnaString (str):
def __new__(self,s):
return str.__new__(self,s.upper())
def length (self):
return (len(self))
def getATCG (self,num_A,num_T,num_C,num_G):
num_A = self.count("A")
num_T = self.count("T")
num_C = self.count ("C")
num_G = self.count ("G")
return ( (self.length(), num_A, num_T, num_G, num_C) )
def printnum_A (self):
print ("Adenine base content: {0}".format(self.count("A")))
dna = input("Enter a dna sequence: ")
x=dnaString(dna)
The program doesn't really do anything, and since I'm just starting out with python, I'm not sure how to fix this so it works. what else should I add? I know it's unfinished.
I'm not sure what is the question, but as you are not calling the method ´printnum_A`, nothing is printing. If you call it like this, it works:
dna = input("Enter a dna sequence: ")
x=dnaString(dna)
x.printnum_A()
Update according to comments
It is not enough to declare the methods of a class, you need also to call then when you need them. Like here for printnum_T:
class dnaString (str):
def __new__(self,s):
return str.__new__(self,s.upper())
def length (self):
return (len(self))
def getATCG (self,num_A,num_T,num_C,num_G):
num_A = self.count("A")
num_T = self.count("T")
num_C = self.count ("C")
num_G = self.count ("G")
return ( (self.length(), num_A, num_T, num_G, num_C) )
def printnum_A (self):
print ("Adenine base content: {0}".format(self.count("A")))
# here the method is declared
def printnum_T (self):
print ("Adenine base content: {0}".format(self.count("T")))
dna = input("Enter a dna sequence: ")
x=dnaString(dna)
x.printnum_A()
# Here I call my method on `x`
x.printnum_T()
I think the class can be simplified a bit:
class DnaString(str):
def __new__(self, s):
return str.__new__(self, s.strip().upper())
def __init__(self, _):
self.num_A = self.count("A")
self.num_C = self.count("C")
self.num_G = self.count("G")
self.num_T = self.count("T")
def stats(self):
return len(self), self.num_A, self.num_C, self.num_G, self.num_T
then
dna = raw_input("Enter a dna sequence: ")
d = DnaString(dna)
print(d)
print(d.stats())
gives
Enter a dna sequence: ACGTACGTA
ACGTACGTA
(9, 3, 2, 2, 2)
Does this help? It works in Python 2.7.3 and 3.2.3 that I happen to have installed.
import itertools
import sys
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = itertools.tee(iterable)
next(b, None)
if sys.version_info[0] > 2:
return zip(a,b)
return itertools.izip(a, b)
class DnaSequence():
Names = {
'A' : 'adenine',
'C' : 'cytosine',
'G' : 'guanine',
'T' : 'thymine'
}
Bases = Names.keys()
def __init__(self, seq):
self._string = seq
self.bases = { x:0 for x in DnaSequence.Bases }
self.pairs = { x+y:0 for x in DnaSequence.Bases
for y in DnaSequence.Bases }
for base in seq:
if base in self.bases:
self.bases[base] += 1
for x,y in pairwise(seq):
pair = x+y
if pair in self.pairs:
self.pairs[pair] += 1
def printCount(self, base):
if base in DnaSequence.Names:
print(DnaSequence.Names[base].capitalize() +
" base content: " + str(self.bases[base]))
else:
sys.stderr.write('No such base ("%s")\n' % base)
def __repr__(self):
return self._string
d = DnaSequence("CCTAGTGTTAGCTAGTCTAGGGAT")
for base in DnaSequence.Bases:
d.printCount(base)
# Further:
print(d)
print(d.bases)
print(d.pairs)
It's a complete example that counts the bases (A, C, G, T) and all occurrences of adjacent pairs (e.g. in ACCGTA, the pairs AC, CC, CG, GT, TA would all be 1, the other 11 possible combinations of the Cartesian product ACGT x ACGT would all be 0).
The counting method used here scans the string once in the constructor, rather than scanning it four times every time getATGC() is called.
You can do this by using a dictionary to organize and retrieve your counts. For instance:
DNASeq = raw_input("Enter a DNA sequence: ")
SeqLength = len(DNASeq)
print 'Sequence Length:', SeqLength
BaseKey = list(set(DNASeq)) #creates a list from the unique characters in the DNASeq
Dict = {}
for char in BaseKey:
Dict[char] = DNASeq.count(char)
print Dict

Values not visible when printing list of objects

Totally rewritten code:
HOR = [0, 1, 3, 6]
VER = [0,10,20,100,1000]
class Pos:
def __init__(self, x, y):
if (x in HOR) and (y in VER):
self.x = x
self.y = y
else:
print "Invalid position: ", x, y
def __str__(self):
return self.x + self.y
def get_x(self):
return self.x
def get_y(self):
return self.y
class list_A1:
def __init__(self): # create a A1 object
self.list_A1 = []
for i in HOR:
for j in VER:
self.list_A1.append(Pos(i,j))
def __str__(self):
d = "list_A1 contains: " + repr(self)
return d # return a string representing the A1
a1 = list_A1()
print a1
Now I get:
list_A1 contains: <__main__.list_A1 object>
but I want to get list of [x,y], for example:
[[1,1],[1,2]...]
I am new to object programming and I don't understand why I can't see these values in the list.
The parentheses after self.A1 mean that you are trying to call it as if it were a function. As the error message tells you, you cannot call a list. The correct syntax would be:
d = "A1 contains: " + str(self.A1)
or, better
d = "A1 contains: {}".format(self.A1)
Also, you seem to be using A1 (the class name) and A (the instance attribute) interchangeably; you should give your classes, attributes and methods more sensible and meaningful names to help avoid this issue.
Do
self.A.append(Pos(x,y))
instead of
self.A1.append(Pos(x,y))
and
d = "A1 contains: " + str(self.A)
Edit:
Implement str(self) and repr(self) of Pos if you want to print them.
A1.A1 is not defined in your code example. If it is a list, just change the line to:
d = "A1 contains: " + str(self.A1)

Categories

Resources