Why am I getting NameError when I run this class? - python

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()

Related

Can you take in a function as a parameter for a method in another class?

def hourlylist():
newlist = []
for Employee in employeeobject():
if Employee.classification == "1":
newlist.append(Employee.hourly)
return newlist
class Hourly(Classification): #classification is parent class
def __init__(self,rate,hourly): #list of hours worked
self.hourly = hourly
self.rate = rate
def set_pay(hourlylist()): #hoursworked as parameter
print(hourlylist())
So I have this list from the function hourly list at the top. What I am trying to do is take in the function as a parameter for my set_pay method. Is this possible? Would I be able to call that function in the set_pay method as a parameter and call it inside of the method?
Thanks
def hourlylist():
newlist = []
for Employee in employeeobject():
if Employee.classification == "1":
newlist.append(Employee.hourly)
return newlist
class Hourly(Classification): #classification is parent class
def __init__(self,rate,hourly): #list of hours worked
self.hourly = hourly
self.rate = rate
def set_pay(hourlylist): #hoursworked as parameter
print(hourlylist)
but this will print the code for hourlylist if you want to execute why you are taking it as a parameter simply run it like below
def hourlylist():
newlist = []
for Employee in employeeobject():
if Employee.classification == "1":
newlist.append(Employee.hourly)
return newlist
class Hourly(Classification): #classification is parent class
def __init__(self,rate,hourly): #list of hours worked
self.hourly = hourly
self.rate = rate
def set_pay(self): #hoursworked as parameter
newlist = hourlylist() # to get newlist from function
make sure the hourlylist is defined before this class

How to declare the __init__ variables that is not necessarily required

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.

dynamic instances of a class object overwriting each other

I have a simple class that stores simple data. The class is as follows.
class DataFormater:
def __init__(self, N, P, K, price):
self.N = N
self.P = P
self.K = K
self.price = price
The code that calls this class is
from DataFormater import DataFormater
#global variables
ObjectList = [0,1,2,3,4,5,6,7,8,9,10,
11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,
31,32,33,34,35,36,37,38,39,40,
41,42,43,44,45,46,47,48,49,50]
ObjectListCounter = 0
# main
print "enter you N-P-K values, followed by a coma, then the price"
print "example ----> 5 5 5 %50 "
print "return as many values as you want to sort, then enter, 'done!' when done."
while True:
RawData = raw_input()
if RawData == 'done!':
break
else:
ObjectList[ObjectListCounter] = DataFormater
ObjectList[ObjectListCounter].N = int(RawData[0])
# very simple test way of putting first indice in ObjectList[ObjectListCounter].N
ObjectListCounter += 1
print ObjectList[0].N
print ObjectList[1].N
My idea is that ObjectList[0] would create that object '1' that I could call with 1.N
But, when I call these, it seems that I have overwritten the previous instances.
this is what prints...
return as many values as you want to sort, then enter, 'done!' when done.
12
1
done!
1
1
Thanks so much! And I know that my post is messy, I don't exactly know how to make it more "pretty"
So, it looks like you are assigning the actual class (instead of an instance of the class) in your loop. Where you do this:
ObjectList[ObjectListCounter] = DataFormater
I think what you actually want is this
ObjectList[ObjectListCounter] = DataFormater(...insert args here....)
EDIT to address the comments:
Your class init method looks like this:
def __init__(self, N, P, K, price):
That means that to create an instance of your class, it would look like this:
my_formater = DataFormater(1, 2, 3, 4)
You would then be able to access my_formater.N which would have a value of 1.
What you are trying to do instead is access a CLASS level attribute, DataFormater.N. This is generally used in situations where you have a constant variable that does not change between instances of the class. For example:
class DataFormater():
CONSTANT_THING = 'my thing that is always the same for every instance'
You would then be able to access that variable directly from the class, like this:
DataFormater.CONSTANT_THING
I hope that clears things up.

In Python 2.7, how can I return calculations without defining variables in the constructor?

My question is about getter/setter-type functionality in Python. I have a class, Week_Of_Meetings, that takes a blob of data from my Google Calendar and does some calculations on it.
wom = Week_Of_Meetings(google_meetings_blob)
I want to be able to return something like:
wom.total_seconds_in_meetings() # returns 36000
But, I'm not understanding how the getters/setters-type #property decorator can help me do this. In Java, I would use member variables, but you don't interact with them the same way in Python. How can I return calculations without starting with them in the constructor?
Class Week_Of_Meetings:
def __init__(self, google_meetings_blob)
self.google_meetings_blob = google_meetings_blob
def get_meetings_list(self, google_meetings_blob):
meetings_list = []
for meeting_id, meeting in enumerate(self.google_meetings_blob, 1):
summary = self._get_summary(meeting)
start = parse(meeting['start'].get('dateTime', meeting['start'].get('date')))
end = parse(meeting['end'].get('dateTime', meeting['end'].get('date')))
duration = end - start
num_attendees = self._get_num_attendees(meeting.get('attendees'))
m = Meeting(meeting_id, summary, start, end, duration, num_attendees)
meetings_list.append(m)
return meetings_list
def _get_summary(self, meeting):
summary = meeting.get('summary', 'No summary given')
return summary
def _get_num_attendees(self, num_attendees):
if num_attendees == None:
num_attendees = 1 # if invited only self to meeting
else:
num_attendees = len(num_attendees)
return num_attendees
When I add self.total_seconds_in_meetings to the
__init__()
I get "NameError: global name 'total_seconds_in_meetings' is not defined." That makes sense. It hasn't been defined. But I can't define it when it's supposed to be the result of calculations done on the google_meetings_blob. So, I'm confused where the 'total_seconds_in_meetings' goes in the class.
Thank you for the help!
Of course Python has member variables. How would classes work without them? You can set and get any instance data via self, as you are already doing with self.google_meetings_blob in __init__.

Running functions defined within classes

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.

Categories