from Exception.Exceptions import *
import re
class Repo(object):
def __init__(self):
self.__items_dictionary = {}
def get_element(self, id):
try:
return self.__items_dictionary[id]
except KeyError:
raise RepositoryError("ID not existent")
def add_item(self, new_item):
try:
if new_item.id in self.__items_dictionary.keys():
raise RepositoryError("Id already exists!")
self.__items_dictionary[new_item.id] = new_item
except AttributeError:
raise RepositoryError('Element does not have an id introduced!')
def remove_item(self, id):
try:
if id in self.__items_dictionary.keys():
return self.__items_dictionary.pop(id)
else:
raise RepositoryError("Element does not exist!")
except KeyError:
raise RepositoryError("Element with that id does not exist!")
def update_item(self, id, attribute, new_value):
if id in self.__items_dictionary.keys():
if hasattr(self.__items_dictionary[id], attribute):
setattr(self.__items_dictionary[id], attribute, new_value)
else:
raise RepositoryError("Element with that attribute does not exist!")
else:
raise RepositoryError('Element with that id does not exist!')
def search_item(self, attribute, search_value):
searched_items = []
try:
if attribute == 'id':
search_value = int(search_value)
if search_value in self.__items_dictionary.keys():
searched_items.append(self.__items_dictionary[search_value])
else:
search_value = search_value.lower()
for item in self.__items_dictionary.keys():
item_string = getattr(self.__items_dictionary[item], attribute).lower()
if re.findall(search_value, item_string):
searched_items.append(self.__items_dictionary[item])
return searched_items
except ValueError as ve:
raise RepositoryError(ve)
#property
def get_all(self):
return self.__items_dictionary
def get_all_for_file(self):
return self.__items_dictionary
class FileRepository(Repo):
def __init__(self,filename, read_entity, write_entity):
Repo.__init__(self)
self.__filename = filename
self.__read_entity = read_entity
self.__write_entity = write_entity
def _read_all_from_file(self):
self._entities = {}
with open(self.__filename,'r') as file:
lines = file.readlines()
for line in lines:
line = line.strip()
if line != "":
entity = self.__read_entity(line)
self._entities[entity.id] = entity
def _write_all_to_file(self):
with open(self.__filename, 'w') as file:
for entity in self._entities:
line = self.__write_entity(entity)
file.write(line + "\n")
def add_item(self,new_item):
self._read_all_from_file()
Repo.add_item(self, new_item)
self._write_all_to_file()
def search_item(self, attribute, search_value):
self._read_all_from_file()
return Repo.search_item(self, attribute,search_value)
def update_item(self, id, attribute, new_value):
self._read_all_from_file()
Repo.update_item(self, id,attribute,new_value)
self._write_all_to_file()
def remove_item(self, id):
self._read_all_from_file()
Repo.remove_item(self, id)
self._write_all_to_file()
def get_all(self):
self._read_all_from_file()
return Repo.get_all
def get_element(self, id):
self._read_all_from_file()
return Repo.get_element(self,id)
I have checked and all gets added to it but whenever I try to access anything I get something like 'function' object has no attribute 'values' or 'method' object is not iterable. Could it be that I am calling that #property? But even when I tried with get_all_for_file() it still did't work...
def filter_list_by_value(self):
self.get_user_input("Insert number to filter by: ")
value = int(self.__user_input)
print(value)
new_list = list()
try:
self.history_stack.append(str(self.expense_list))
for item in self.expense_list:
try:
new_list.append(list(filter(lambda val: val > value, item.expense)))
except TypeError as te:
print("type error" , te)
self.expense_list = new_list
except TypeError as te:
print("Type error!", te)
class Expense:
def init(self, expense: int, category: str, day: int):
self.__expense = expense
self.__category = category
self.__day = day
def __repr__(self):
return str(self)
def __str__(self):
return str(self.__dict__)
#property
def day(self):
return self.__day
#day.setter
def day(self, day):
self.__day = day
#property
def expense(self):
return self.__expense
#expense.setter
def expense(self, expense):
self.__expense = expense
#property
def category(self):
return self.__category
#category.setter
def category(self, category):
self.__category = category
I keep getting 'int' object is not iterable. What should I do? expense_list is an class-made object.
Judging by:
new_list = list()
...
new_list.append(list(...))
...
self.expense_list = new_list
self.expense_list has to be a list of lists. However, by:
for item in self.expense_list:
...
item.expense
It cannot be, since lists don't have an expense attribute. Please verify you have all your datatypes straight.
I'm new to python and am currently trying to use an old module to output graphs. The code below is a excerpt from the module that uses rpy to design
standard celeration charts (don't look it up).
I'm having trouble understanding how the class Element and class Vector work together.
I've been trying to pass the a element object to the vector get_elements but I'm not sure if that's what I should be doing.
Any help would be appreciated. Thanks!
class Element(object):
"""Base class for Chartshare vector elements."""
def __init__(self, offset=0, value=0):
self.offset=offset
self.value=value
self.text=''
def setText(self, value):
self.value=value
def getText(self):
return self.value
text = property(getText, setText)
class Vector(object):
"""Base class for Chartshare Vectors."""
def __init__(self, name='', color='black', linetype='o', symbol=1, clutter=0, start=0, end=140, continuous=False, debug=False):
self.name=name
self.color=color
self.linetype=linetype
self.symbol=symbol
self.start=start
self.end=end
self.elements={}
self.debug=debug
self.continuous=continuous
if not self.continuous:
for i in range(self.start, self.end+1):
self.elements[i]='NaN'
def getSymbol(self):
return self._symbol
def setSymbol(self, value):
if (type(value) == int):
if (value >= 0) and (value <= 18):
self._symbol = value
else:
raise SymbolOutOfRange, "Symbol should be an integer between 0 and 18."
elif (type(value) == str):
try:
self._symbol = value[0]
except IndexError:
self._symbol=1
else:
self._symbol = 1
symbol = property(getSymbol, setSymbol)
def getLinetype(self):
return self._linetype
def setLinetype(self, value):
if (value == 'p') or (value == 'o') or (value == 'l'):
self._linetype = value
else:
raise InvalidLinetype, "Line type should be 'o', 'p', or 'l'"
linetype = property(getLinetype, setLinetype)
def get_elements(self):
"""Returns a list with the elements of a Vector."""
retval = []
for i in range(self.start, self.end+1):
if (not self.continuous):
retval.append(self.elements[i])
else:
if (self.elements[i] != 'NaN'):
retval.append(self.elements[i])
return retval
def get_offsets(self):
"""Returns a list of the offsets of a Vector."""
retval = []
for i in range(self.start, self.end+1):
if (not self.continuous):
retval.append(i)
else:
if (self.elements[i] == 'NaN'):
retval.append(i)
return retval
def to_xml(self, container=False):
"""Returns an xml representation of the Vector."""
if (container == False):
container = StringIO.StringIO()
xml = XMLGenerator(container)
attrs = {}
attrs[u'name'] = u"%s" % self.name
attrs[u'symbol'] = u"%s" % self.symbol
attrs[u'linetype'] = u"%s" % self.linetype
attrs[u'color'] = u"%s" % self.color
xml.startElement(u'vector', attrs)
for i in range(self.start, self.end+1):
if (self.elements[i] != 'NaN'):
attrs.clear()
attrs[u'offset'] = u"%s" % i
xml.startElement(u'element', attrs)
xml.characters(u"%s" % self.elements[i])
xml.endElement(u'element')
xml.endElement(u'vector')
def render(self):
"""Plots the current vector."""
if (self.debug):
print "Rendering Vector: %s" % self.name
print self.elements
r.points(x=range(self.start, self.end+1),
y=self.elements,
col=self.color,
type=self.linetype,
pch=self.symbol)
if (self.debug):
print "Finished rendering Vector: %s" % self.name
Vector's get_elements() doesn't take any arguments. Well, technically it does. It takes self. self is syntactic sugar that lets you do this:
vec = Vector()
vec.get_elements()
It's equivalent to this:
vec = Vector()
Vector.get_elements(vec)
Since get_elements() doesn't take any arguments, you can't pass a to it. Skimming the code, I don't see a set_elements() analog. This means you'll have to modify the vector's element's dictionary directly.
vec = Vector()
vec.elements[a] = ...
print(vec.get_elements()) # >>> [a,...]
As I can see, there is no place in this code where you are assigning self.elements with any input from a function. You are only initialising it or obtaining values
Also note that the .get_elements() function doesn't have any arguments (only self, that is the object where you are calling it in), so of course it won't work.
Unless you can do something such as the following, we would need more code to understand how to manipulate and connect these two objects.
element_obj = Element()
vector_obj = Vector()
position = 4
vector_obj.elements[4] = element_obj
I got to this answer with the following: as I can see, the elements property in the Vector class is a dictonary, that when you call vector_obj.get_elements() is casted to an array using the start and end parameters as delimiters.
Unless there is something else missing, this would be the only way I could think out of adding the an element into a vector object. Otheriwse, we would need some more code or context to understand how these classes behave with each other!
Hope it helps!
This is the most strange error that I got since I started to program with Python years ago.
First, theses are my classes (Sorry for the long code):
class Quran(Iterable):
def __init__(self):
self.sourats = []
def __iadd__(self, other):
# There is some code here
pass
def __getitem__(self, sourat_num):
if not (isinstance(sourat_num, int) or isinstance(sourat_num, slice)):
raise TypeError('Indexing Quran can be done only using ints or slices')
if isinstance(sourat_num, int):
sourat_num -= 1
else:
sourat_num = slice(sourat_num.start - 1, sourat_num.stop)
try:
return self.sourats[sourat_num]
except IndexError:
return None
def __len__(self):
return len(self.sourats)
# Other methods ...
class Sourat(Iterable):
sourats_titles = [ # 114 strs here
]
def __init__(self, number, quran):
if not isinstance(number, int):
raise TypeError('number must be int')
if not isinstance(quran, Quran):
raise TypeError('quran must be Quran')
self.num = number
self.ayats = []
self.quran = quran
def __int__(self):
return self.num
def __iadd__(self, other):
# Some code here
pass
def __getitem__(self, ayat_num):
if not (isinstance(ayat_num, int) or isinstance(ayat_num, slice)):
raise TypeError('Indexing Sourat can be done only using ints or slices')
if isinstance(ayat_num, int):
ayat_num -= 1
else:
ayat_num = slice(ayat_num.start-1, ayat_num.stop)
try:
return self.ayats[ayat_num]
except IndexError:
return None
def __len__(self):
return len(self.ayats)
def location(self):
return self.num
def previous(self):
p_num = self.num-1
if p_num < 1:
return None
return self.quran[p_num]
def next(self):
n_num = self.num+1
if n_num > len(self.quran):
return None
return self.quran[n_num]
# Other methods ...
class Word(Iterable):
def __init__(self, number, text, features, ayat):
if not isinstance(number, int):
raise TypeError('number must be int')
if not isinstance(text, str):
raise TypeError('text must be str')
if not (isinstance(features, dict) and features['type'] in ('PREFIX', 'STEM', 'SUFFIX')):
raise TypeError('features[type] must be one of PREFIX, STEM, SUFFIX')
if not isinstance(ayat, Ayat):
raise TypeError('ayat must be Ayat')
self.num = number
self.text = text
self.root = features.get('ROOT', None)
self.lem = features.get('LEM', None)
self.type = features['type']
self.next = None
self.previous = None
self.ayat = ayat
def __iadd__(self, other):
# Some code here
def __hash__(self):
# Some code here
pass
def previous(self):
p_num = self.num-1
if p_num < 1:
previous_ayat = self.ayat.previous()
if previous_ayat:
return previous_ayat[-1]
else:
return None
return self.ayat[p_num]
def next(self):
n_num = self.num+1
if n_num > len(self.ayat):
next_ayat = self.ayat.next()
if next_ayat:
return next_ayat[0]
else:
return None
return self.ayat[n_num]
# Other methods ...
And this is what I am have in the main code :
quran_last_14_sourats = parse_quranic_corpus('quranic-corpus-morphology-0.4-last-14-sourats.txt')
sourat = quran_last_14_sourats[2]
ayat = sourat[2]
word = ayat[1]
assert isinstance(ayat, Ayat)
assert isinstance(word, Word)
print(ayat.previous())
print(ayat)
print(ayat.next())
print(Word.next(word)) # This works !!!
print(word.next()) # This doesn't work !!!
My problem is in the next(self) and previous(self) in the class Word, everything else works perfectly.
When I try to use word.next() or word.previous(), it complains that NoneType is not callable. I tried to print(word.next) and it showed None, but this is not logical because these two methods are inside the class Word. This problem doesn't happen in classes Sourat and Ayat even that they have the same structure. And the most crazy thing is that Word.next(word) works without any problem !
Is this a bug in Python 3 ? (BTW I am using the latest version: 3.5.2)
Is this a bug in Python 3 ?
In a word, no.
Instance members and instance methods share the same namespace. Thus, your line in Word.__init__():
self.next = None
obliterates the reference to the method Word.next() inside the newly-allocated Word object.
EDIT (complete rephrase of the problem as the original version (see "original version", later) is misleading):
Here is the setting: I have a object which has a list of objects of type
<class 'One'>. I would like to access this list but rather work with objects
of type <class 'Two'> which is an enriched version of <class 'One'>.
Background (1):
One could be an object that can be stored easily via a ORM. The ORM would handle the list depending on the data model
Two would be an object like One but enriched by many features or the way it can be accessed
Background (2):
I try to solve a SQLAlchemy related question that I asked here. So, the answer to the present question could be also a solution to that question changing return/input type of SQLAlchemy-lists.
Here is some code for illustration:
import numpy as np
class One(object):
"""
Data Transfere Object (DTO)
"""
def __init__(self, name, data):
assert type(name) == str
assert type(data) == str
self.name = name
self.data = data
def __repr__(self):
return "%s(%r, %r)" %(self.__class__.__name__, self.name, self.data)
class Two(np.ndarray):
_DTO = One
def __new__(cls, name, data):
dto = cls._DTO(name, data)
return cls.newByDTO(dto)
#classmethod
def newByDTO(cls, dto):
obj = np.fromstring(dto.data, dtype="float", sep=',').view(cls)
obj.setflags(write=False) # Immutable
obj._dto = dto
return obj
#property
def name(self):
return self._dto.name
class DataUI(object):
def __init__(self, list_of_ones):
for one in list_of_ones:
assert type(one) == One
self.list_of_ones = list_of_ones
if __name__ == '__main__':
o1 = One('first object', "1, 3.0, 7, 8,1")
o2 = One('second object', "3.7, 8, 10")
my_data = DataUI ([o1, o2])
How to implement a list_of_twos which operates on list_of_ones but provides the user a list with elements of type Two:
type (my_data.list_of_twos[1]) == Two
>>> True
my_data.list_of_twos.append(Two("test", "1, 7, 4.5"))
print my_data.list_of_ones[-1]
>>> One('test', '1, 7, 4.5')
Original version of the question:
Here is an illustration of the problem:
class Data(object):
def __init__(self, name, data_list):
self.name = name
self.data_list = data_list
if __name__ == '__main__':
my_data = Data ("first data set", [0, 1, 1.4, 5])
I would like to access my_data.data_list via another list (e.g. my_data.data_np_list) that handles list-elements as a different type (e.g. as numpy.ndarray):
>>> my_data.data_np_list[1]
array(1)
>>> my_data.data_np_list.append(np.array(7))
>>> print my_data.data_list
[0, 1, 1.4, 5, 7]
You should use a property
class Data(object):
def __init__(self, name, data_list):
self.name = name
self.data_list = data_list
#property
def data_np_list(self):
return numpy.array(self.data_list)
if __name__ == '__main__':
my_data = Data ("first data set", [0, 1, 1.4, 5])
print my_data.data_np_list
edit: numpy use a continous memory area. python list are linked list. You can't have both at the same time without paying a performance cost which will make the whole thing useless. They are different data structures.
No, you can't do it easily (or at all without losing any performance gain you might get in using numpy.array). You're wanting two fundamentally different structures mirroring one another, this will mean storing the two and transferring any modifications between the two; subclassing both list and numpy.array to observe modifications will be the only way to do that.
Not sure whether your approach is correct.
A property getter would help achieve what you're doing. Here's something similar using arrays instead of numpy.
I've made the array (or in your case numpy data type) the internal representation, with the conversion to list only done on demand with a temporary object returned.
import unittest
import array
class GotAGetter(object):
"""Gets something.
"""
def __init__(self, name, data_list):
super(GotAGetter, self).__init__()
self.name = name
self.data_array = array.array('i', data_list)
#property
def data_list(self):
return list(self.data_array)
class TestProperties(unittest.TestCase):
def testProperties(self):
data = [1,3,5]
test = GotAGetter('fred', data)
aString = str(test.data_array)
lString = str(test.data_list) #Here you go.
try:
test.data_list = 'oops'
self.fail('Should have had an attribute error by now')
except AttributeError as exAttr:
self.assertEqual(exAttr.message, "can't set attribute")
self.assertEqual(aString, "array('i', [1, 3, 5])",
"The array doesn't look right")
self.assertEqual(lString, '[1, 3, 5]',
"The list property doesn't look right")
if __name__ == "__main__":
unittest.main()
One solution I just came up with would be to implement a View of the list via class ListView which takes the following arguments:
raw_list: a list of One-objects
raw2new: a function that converts One-objects to Two-objects
new2raw: a function that converts Two-objects to One-objects
Here is a the code:
class ListView(list):
def __init__(self, raw_list, raw2new, new2raw):
self._data = raw_list
self.converters = {'raw2new': raw2new,
'new2raw': new2raw}
def __repr__(self):
repr_list = [self.converters['raw2new'](item) for item in self._data]
repr_str = "["
for element in repr_list:
repr_str += element.__repr__() + ",\n "
repr_str = repr_str[:-3] + "]"
return repr_str
def append(self, item):
self._data.append(self.converters['new2raw'](item))
def pop(self, index):
self._data.pop(index)
def __getitem__(self, index):
return self.converters['raw2new'](self._data[index])
def __setitem__(self, key, value):
self._data.__setitem__(key, self.converters['new2raw'](value))
def __delitem__(self, key):
return self._data.__delitem__(key)
def __getslice__(self, i, j):
return ListView(self._data.__getslice__(i,j), **self.converters)
def __contains__(self, item):
return self._data.__contains__(self.converters['new2raw'](item))
def __add__(self, other_list_view):
assert self.converters == other_list_view.converters
return ListView(
self._data + other_list_view._data,
**self.converters
)
def __len__(self):
return len(self._data)
def __eq__(self, other):
return self._data == other._data
def __iter__(self):
return iter([self.converters['raw2new'](item) for item in self._data])
Now, DataUI has to look something like this:
class DataUI(object):
def __init__(self, list_of_ones):
for one in list_of_ones:
assert type(one) == One
self.list_of_ones = list_of_ones
self.list_of_twos = ListView(
self.list_of_ones,
Two.newByDTO,
Two.getDTO
)
With that, Two needs the following method:
def getDTO(self):
return self._dto
The entire example would now look like the following:
import unittest
import numpy as np
class ListView(list):
def __init__(self, raw_list, raw2new, new2raw):
self._data = raw_list
self.converters = {'raw2new': raw2new,
'new2raw': new2raw}
def __repr__(self):
repr_list = [self.converters['raw2new'](item) for item in self._data]
repr_str = "["
for element in repr_list:
repr_str += element.__repr__() + ",\n "
repr_str = repr_str[:-3] + "]"
return repr_str
def append(self, item):
self._data.append(self.converters['new2raw'](item))
def pop(self, index):
self._data.pop(index)
def __getitem__(self, index):
return self.converters['raw2new'](self._data[index])
def __setitem__(self, key, value):
self._data.__setitem__(key, self.converters['new2raw'](value))
def __delitem__(self, key):
return self._data.__delitem__(key)
def __getslice__(self, i, j):
return ListView(self._data.__getslice__(i,j), **self.converters)
def __contains__(self, item):
return self._data.__contains__(self.converters['new2raw'](item))
def __add__(self, other_list_view):
assert self.converters == other_list_view.converters
return ListView(
self._data + other_list_view._data,
**self.converters
)
def __len__(self):
return len(self._data)
def __iter__(self):
return iter([self.converters['raw2new'](item) for item in self._data])
def __eq__(self, other):
return self._data == other._data
class One(object):
"""
Data Transfere Object (DTO)
"""
def __init__(self, name, data):
assert type(name) == str
assert type(data) == str
self.name = name
self.data = data
def __repr__(self):
return "%s(%r, %r)" %(self.__class__.__name__, self.name, self.data)
class Two(np.ndarray):
_DTO = One
def __new__(cls, name, data):
dto = cls._DTO(name, data)
return cls.newByDTO(dto)
#classmethod
def newByDTO(cls, dto):
obj = np.fromstring(dto.data, dtype="float", sep=',').view(cls)
obj.setflags(write=False) # Immutable
obj._dto = dto
return obj
#property
def name(self):
return self._dto.name
def getDTO(self):
return self._dto
class DataUI(object):
def __init__(self, list_of_ones):
for one in list_of_ones:
assert type(one) == One
self.list_of_ones = list_of_ones
self.list_of_twos = ListView(
self.list_of_ones,
Two.newByDTO,
Two.getDTO
)
class TestListView(unittest.TestCase):
def testProperties(self):
o1 = One('first object', "1, 3.0, 7, 8,1")
o2 = One('second object', "3.7, 8, 10")
my_data = DataUI ([o1, o2])
t1 = Two('third object', "4.8, 8.2, 10.3")
t2 = Two('forth object', "33, 1.8, 1.0")
# append:
my_data.list_of_twos.append(t1)
# __getitem__:
np.testing.assert_array_equal(my_data.list_of_twos[2], t1)
# __add__:
np.testing.assert_array_equal(
(my_data.list_of_twos + my_data.list_of_twos)[5], t1)
# __getslice__:
np.testing.assert_array_equal(
my_data.list_of_twos[1:],
my_data.list_of_twos[1:2] + my_data.list_of_twos[2:]
)
# __contains__:
self.assertEqual(my_data.list_of_twos.__contains__(t1), True)
# __setitem__:
my_data.list_of_twos.__setitem__(1, t1),
np.testing.assert_array_equal(my_data.list_of_twos[1], t1)
# __delitem__:
l1 = len(my_data.list_of_twos)
my_data.list_of_twos.__delitem__(1)
l2 = len(my_data.list_of_twos)
self.assertEqual(l1 - 1, l2)
# __iter__:
my_data_2 = DataUI ([])
for two in my_data.list_of_twos:
my_data_2.list_of_twos.append(two)
if __name__ == '__main__':
unittest.main()