I have a python class which houses some info. I have another file which some of these functions refer to. My get_date , is working fine however, none of my other functions seem to be working. I am getting the error AttributeError: PVData instance has no attribute 'time' when calling the time function.
class PVData:
def __init__(self):
self.date = yesterday()
self.data = load_data(self.date)
def change_date(self, date):
if self.date != date:
self.date = date
## self.refresh()
else:
self.date = date
self.date = load_data(self.date)
#time, temp, sun
self.time = []
self.temperature = []
self.sunlight = []
for minute in self.date:
self.time.append(minute[0])
self.temperature.append(minute[1])
self.sunlight.append(minute[2])
#power
self.dictonary[a] = []
for a in ARRAYS:
self.dictionary[ARRAYS[i]].append(power)
def get_date(self):
return self.date
def get_time(self, time_index):
return self.time[time_index]
def get_temperature(self):
return self.temperature
def get_sunlight(self):
return self.sunlight
def get_power(self, array):
return self.dictionary[array]
pvd = PVData()
The load_data function is (in another file):
def load_data(dateStr):
text = get_data_for_date(dateStr)
data = []
for line in text.splitlines():
time, temp, sun, powerStr = line.split(',', 3)
power = []
for p in powerStr.split(','):
power.append(int(p))
data.append((time, float(temp), float(sun), tuple(power)))
return data
which returns something such as:
[('19:00', 20.0, 0.0, (0, 0, 0, 0, 0, 0, 0, 21, 31, 52)), (tuple 2), etc etc]
The error seems to be resulting because time is not a valid parameter for self, but I thought that was defined where self.time = [].
Excuse my lack of knowledge, python is quite new to me. Any ideas of why this is not doing as required?
Move time as well as other variables that should be accessible from outside to def init(self). Please keep in mind, that python creates variables in runtime, so if you want variable has been accessible in any place - they should be created on class initialization.
Added:
From your code it looks like, you should move temperature and sunlight to def init(self) as well.
Related
This class, Itinerary, generates a dictionary destinations by putting together individual dictionaries at random. It also generates a date startTime which is based on probabilities.
Here is my code:
class Itinerary:
def __init__(self, destinations, startTime):
self.destinations = {**a, **np.random.choice([b1,b2]), **np.random.choice([c1,c2,c3,c4]),
**np.random.choice([d1,d2,d3]), **np.random.choice([e1,e2]), **f1, **g,
**np.random.choice([h1,h2,h3]), **i}
self.startTime = datetime(year = 2020,
month = np.random.choice(list(range(1,13)), p = [0.0657, 0.0755,
0.081, 0.067,
0.0751, 0.1031,
0.1178, 0.1155,
0.0858, 0.0806,
0.0655, 0.0674]),
day = np.random.choice(list(range(1,30))),
hour = np.random.choice([9,12], p = [0.3, 0.7]))
However, when I run this:
x = Itinerary(destinations, startTime)
print(x.destinations, 2*'\n', x.startTime)
it returns:
NameError: name 'destinations' is not defined
It actually worked earlier today, but then I closed it and reopened it and then the error came.
Your __init__ function doesn't need to take in 2 parameters if those fields are generated within the constructor itself.
So the signature can be:
def __init__(self): # no params in constructor
and then the call could be:
x = Itinerary()
PROBLEM
I'm building a video-editor like in python. I have created timeline which use dictionary for storing animation object. When I go to render phase, I have to render the movie which is a big timeline of scene which are also timeline. So we have at least 2 dictionary per movie. When i iterate throught the scene, i iterate throught the dictionary, and render the scene :
timeline = self.tl.timeline_object.items() # get the items of the dictionary
for scene in timeline:
print(timeline, id(timeline))
scene[1]() # do all the render stuff
which give the following result :
dict_items([('1', <class 'test_movie.first_scene.FirstScene'>), ('2', <class 'test_movie.second_scene.SecondScene'>)]) 140043388706584
dict_items([('1', <animations.FillScreen.FillScreen object at 0x7f5e643a67f0>), ('2', <animations.Write.Write object at 0x7f5e643a69b0>)]) 140043388706584
as you can see the dictionary swap between the movie's one and the scene's one (look at the id).
I should get the first line :
dict_items([('1', <class 'test_movie.first_scene.FirstScene'>), ('2', <class 'test_movie.second_scene.SecondScene'>)]) 140043388706584
for the second iteration.
QUESTION
Why do i get the dictionary of the scene instead of the "real" dictionary stored in timeline ? and how to solve this problem ?
PLUS : Full code
The code is very long and a lot of objects are involved, i have tried to show you the maximum without loosing you. If you want the actual repo : https://gitlab.com/planchon/psVidTex
Otherwise, here are the important files :
class MovieName(Movie):
def __init__(self):
Movie.__init__(self)
# add the scene to the movie timeline (dictionnary + time array)
def prepare(self):
self.add_to_timeline(FirstScene, 0, 10)
self.add_to_timeline(SecondScene, 10, 20)
class Timeline(object):
timeline_object = {}
timeline = []
timeline_index = []
max_id = 0
def __init__(self):
pass
# ajoute un element dans la timeline retourne la timeline_id de l'object
# prend des frames comme unité de mesure du temps
def add_object(self, animation, start, end, position):
animation_id = self.get_global_id()
self.timeline_object[animation_id] = animation
self.add_into_timeline(start, [start, end, position, animation_id])
return animation_id
# add the tuple [start, end, position, animation_id] into the timeline
def add_into_timeline(self, start, element):
index = bisect.bisect(self.timeline_index, start)
self.timeline_index.insert(index, start)
self.timeline.insert(index, element)
# get the next id
def get_global_id(self):
self.max_id = self.max_id + 1
return str(self.max_id)
class FirstScene(Scene):
def __init__(self):
Scene.__init__(self)
def prepare(self):
self.add_to_timeline(FillScreen("col"), 0, 10)
self.add_to_timeline(Write("test"), 0, 10)
class Movie(object):
tl = Timeline()
def __init__(self):
self.prepare()
self.init_all_scene()
def render(self):
pass
def prepare(self):
pass
def init_all_scene(self):
timeline = self.tl.timeline_object.items()
for scene in timeline:
print(timeline, id(timeline))
scene[1]()
# add the scene to the timeline
def add_to_timeline(self, scene, start, end):
return self.tl.add_object(scene, start, end, 0)
class Scene(Container):
tl = Timeline()
def __init__(self, **kargs):
self.prepare()
def add_to_timeline(self, anim, start, end):
return self.tl.add_object(anim, start, end, 0)
def prepare(self):
pass
def render(self):
pass
The Write and FillScreen are not relevant object in this context. You can find them in the repo if necessary.
The problem was that the Timeline class was not properly initialize and the timeline_object was shared between all the differents timeline.
So to resolved, i just modified the class Timeline :
class Timeline(object):
def __init__(self):
self.timeline_object = {}
self.timeline = []
self.timeline_index = []
self.max_id = 0
by changing the position of the arrays in the init, that way they are local to the object and not to the meta-object...
class Gathering(object):
def __init__(self, date, spent1, spent2, spent3, spent4):
"""Return a gathering object whose date is declared """
self.date = date
self.spent1 = spent1
self.spent2 = spent2
self.spent3 = spent3
self.spent4 = spent4
self.spent_total = spent1+spent2+spent3+spent4
def per_person(self):
return self.spent_total/3
I had made short script that I can easily calculate the portion of one person when me and my friend had some gatehring. We usally move the spots and spent different amount of money, but how many places we visit that night is always different.
So I"d like to make spent1,2,3,4 variables not necessarily required, how can I do that?
You may use a variable number of arguments:
class Gathering(object):
def __init__(self, date, *args):
"""Return a gathering object whose date is declared """
self.date = date
self.spent = args
self.spent_total = sum(args, 0)
def per_person(self):
return self.spent_total / 3.0
sent contains a tuple of values. You can use your class like:
g1 = Gathering(date1, 1, 2, 3)
g2 = Gathering(date2, 2, 3)
and so on.
I have this data
{Wednesday : {22 : {Type = x,
Temp = x,
Speed = x,
Direction = x}
{23 : {Type = x,
Temp = x,
Speed = x,
Direction = x}
I am trying to write a class so that I will be able to access it by calling as an example and that will give me X.
My code so far is this :
class Weather(object):
def __init__(self, wtype, wtemp, wspeed, wdirection):
self.type = wtype
self.temp = wtemp
self.speed = wspeed
self.direction = wdirection
This allows me to get the data when calling upon the date :
Wednesday.Temp
>>> 22
However I also need to allocate the data by time as well as the date, so when calling "Wednesday.22.Type" I get the specific date for that our.
I am new to classes within Python and I'm not quite sure on how to build the class so that I can call on the date, and then the time to get the respective data. I'm assuming that a nested class is needed to have a "parent-child" like relation in the code however I'm not sure how to do this.
Although numbers are not considered to be valid identifiers in Python (but that could be funny for trolling: 0 = 1 = 2 = 3 = 42), things like _3 are, but are generally considered to be "private" attributes by the python community (myself included), so i use at followed by the number instead. And I think it would be better to access it like you access a dictionary.
Here is my take on it. Remove the methods if you don't want the associated feature.
class SpecificWeather(object):
def __init__(self, data):
self.data = data
#property
def type(self):
return self.data["Type"]
#property
def temperature(self):
return self.data["Temp"]
#property
def speed(self):
return self.data["Speed"]
#property
def direction(self):
return self.data["Direction"]
class Weather(object):
def __init__(self, data): # data is the dictionary
self.data = data
def __getitem___(self, item): # for wednesday[22].type
return SpecificWeather(self.data[item])
def __getattr__(self, name): # for wednesday.at22.type
if name.startswith("at"):
return SpecificWeather(self.data[int(name[2:])])
raise AttributeError()
#property
def type(self):
# TODO: Return the average type or something like that
#property
def temperature(self):
# TODO: Return the average temperature or something like that
#property
def speed(self):
# TODO: Return the average speed or something like that
#property
def direction(self):
# TODO: Return the average direction or something like that
This solution uses property a lot, this has a big advantage: If you change the temperate for 22, wednesday[22].temperature will now give you the new value. If you care for performance however, and you use only half of them, then this one can be faster than storing the results, if you access them even multiple times though, this will be a lot slower.
How to use it:
wednesday = Weather({
22: {
'Type': ...,
'Temp': 30,
'Speed': ...,
'Direction': ...
},
23: {
'Type': ...,
'Temp': 28,
'Speed': ...,
'Direction': ...
}
})
print(wednesday.at22.temperature) # gives 30
print(wednesday[23].temperature) # gives 28
I am fairly new to python. I have tried to define a class, I then want to create an instance from a file, then refer to specific pieces of it, but cannot seem to. This is Python 3.3.0
Here's the class....
class Teams():
def __init__(self, ID = None, Team = None, R = None, W = None, L = None):
self._items = [ [] for i in range(5) ]
self.Count = 0
def addTeam(self, ID, Team, R=None, W = 0, L = 0):
self._items[0].append(ID)
self._items[1].append(Team)
self._items[2].append(R)
self._items[3].append(W)
self._items[4].append(L)
self.Count += 1
def addTeamsFromFile(self, filename):
inputFile = open(filename, 'r')
for line in inputFile:
words = line.split(',')
self.addTeam(words[0], words[1], words[2], words[3], words[4])
def __len__(self):
return self.Count
Here's the code in Main
startFileName = 'file_test.txt'
filename = startFileName
###########
myTestData = Teams()
myTestData.addTeamsFromFile(startFileName)
sample data in file
100,AAAA,106,5,0
200,BBBB,88,3,2
300,CCCC,45,1,4
400,DDDD,67,3,2
500,EEEE,90,4,1
I think I am good to here (not 100% sure), but now how do I reference this data to see... am i not creating the class correctly? How do I see if one instance is larger than another...
ie, myTestData[2][2] > myTestData[3][2] <----- this is where I get confused, as this doesn't work
Why don't you create a Team class like this :
class Team():
def __init__(self, ID, Team, R=None, W = 0, L = 0)
# set up fields here
Then in Teams
class Teams():
def __init__(self):
self._teams = []
def addTeam (self, ID, Team, R=None, W = 0, L = 0)
team = Team (ID, Team, R=None, W = 0, L = 0)
self._teams.append (team)
Now If i got it right you want to overwrite the > operator's behaviour.
To do that overload __gt__(self, other) [link]
So it will be
class Team ():
# init code from above for Team
def __gt__ (self, otherTeam):
return self.ID > otherTeam.ID # for example
Also be sure to convert those strings to numbers because you compare strings not numbers. Use int function for that.
The immediate problem you're running into is that your code to access the team data doesn't account for your myTestData value being an object rather than a list. You can fix it by doing:
myTestData._items[2][2] > myTestData._items[3][2]
Though, if you plan on doing that much, I'd suggest renaming _items to something that's obviously supposed to be public. You might also want to make the addTeamsFromFile method convert some of the values it reads to integers (rather than leaving them as strings) before passing them to the addTeam method.
An alternative would be to make your Teams class support direct member access. You can do that by creating a method named __getitem__ (and __setitem__ if you want to be able to assign values directly). Something like:
def __getitem__(self, index):
return self._items[index]
#Aleksandar's answer about making a class for the team data items is also a good one. In fact, it might be more useful to have a class for the individual teams than it is to have a class containing several. You could replace the Teams class with a list of Team instances. It depends on what you're going to be doing with it I guess.