I'm facing problem with my code. In fact, I need to create a list of instances of my class( Patent). The name of the list is patent_ints. But when I'm trying to verify if any element in that list is a Patent one, I'm always getting a False response. And when iterating the first element is like "<__main__.Patent at 0x7f107820b710>".
Here is my code, I need help !
import json
import datetime
patent_data = json.loads(open('NASA_data.json', "r").read())
unique_center = []
for thing in patent_data["Patent_Information"]["Results"]:
for val in thing:
if(val == 'NASA Center'):
unique_center.append(thing[val])
total_num_centers = len(set(unique_center))
class Patent:
def __init__(self, abbreviated_organization_name, dict_data):
self.org_name = abbreviated_organization_name
self.title = dict_data["Title"]
# initialize instance variable called year. The value can be extracted from dict_data.
# This should be a four digit string.
self.year = str(datetime.datetime.strptime(dict_data['Date'], '%m/%d/%Y').year) #dict_data['Date'].split('/')[2]
# initialize an instance variable called month. The value can be extracted from dict_data.
# This should be a two digit string.
self.month = str(datetime.datetime.strptime(dict_data['Date'], '%m/%d/%Y').month) #dict_data['Date'].split('/')[0]
# initialize an instance variable called day. The value can be extracted from dict_data.
# This should be a two digit string.
self.day = str(datetime.datetime.strptime(dict_data['Date'], '%m/%d/%Y').day) #dict_data['Date'].split('/')[1]
self.id = dict_data['Case Number']
self.access_limit = dict_data['SRA Final']
patent_ints = [Patent(i, data) for i in unique_center for data in patent_data["Patent_Information"]["Results"]]
patent_ints[0]
Thank you in advance!
<__main__.Patent at 0x7f107820b710> is the default representation of the class when you try to print it. Add an __str__ or __repr__ method to the class and define some custom logic to return your desired details as a string:
class Patent:
def __init__(self, abbreviated_organization_name, dict_data):
...
def __repr__(self):
# return a dictionary of items in the class but you can return whatever you want
# you could do f'{self.title} {self.id} {self.year}-{self.month}-{self.day}' but str(self.__dict__) is quick to test
return str(self.__dict__)
I wanted to know whether the below scenario be available using __new__ special method. If so, I would like to hear from stackoverflow. I have class name Listing which reads records from a file and then convert them in a queries. To be concise, initially the snippet reads all the lines from the file and converts them into list of lists. Again, this list of lists are passed to the loadlist method of Event, which reads each list, unpacks and then set them to class attributes.
For Instance, I have the below three records
1|305|8|1851|Gotterdammerung|2008-01-25 14:30:00
2|306|8|2114|Boris Godunov|2008-10-15 20:00:00
3|302|8|1935|Salome|2008-04-19 14:30:0
Here, Listing.py reads the above content and converts them into queries which is given below
INSERT INTO EVENT (EVENTID,VENUEID,CATID,DATEID,EVENTNAME,STARTTIME) VALUES ('1','305','8','1851','Gotterdammerung','2008-01-25 14:30:00')
INSERT INTO EVENT (EVENTID,VENUEID,CATID,DATEID,EVENTNAME,STARTTIME) VALUES ('2','306','8','2114','Boris Godunov','2008-10-15 20:00:00')
INSERT INTO EVENT (EVENTID,VENUEID,CATID,DATEID,EVENTNAME,STARTTIME) VALUES ('3','302','8','1935','Salome','2008-04-19 14:30:00')
The Whole program of Listing.py
class Event:
def __init__(self,eventid,venueid,catid,dateid,eventname,starttime):
self.eventid = eventid
self.venueid = venueid
self.catid = catid
self.dateid = dateid
self.eventname = eventname
self.starttime = starttime
def __iter__(self):
return (i for i in (self.eventid,self.venueid,self.catid,self.dateid,self.eventname,self.starttime))
def __str__(self):
return str(tuple(self))
def __repr__(self):
return "INSERT INTO EVENT (EVENTID,VENUEID,CATID,DATEID,EVENTNAME,STARTTIME) VALUES ({!r},{!r},{!r},{!r},{!r},{!r})".format(*self)
#classmethod
def loadlist(cls,records):
return [cls(*record) for record in records]
if __name__ == '__main__':
records = []
with open('tickitdb/allevents_pipe.txt','r') as f:
records = list(map(lambda s:s.rstrip('\n').split('|'),f.readlines()))
events = Event.loadlist(records=records)
with open('events.sql','w+') as f:
print('writing file')
for event in events:
f.write(repr(event)+"\n")
When i ran the program, i came across the below error.
TypeError: __init__() missing 5 required positional arguments:. And i figured out the root cause behind this. When the program reads the file and converts them into list of records, there was record which is empty hasn't, for instance
1.['1','305','8','1851','Gotterdammerung','2008-01-25 14:30:00']
2.['2','306','8','2114','Boris','Godunov','2008-10-15 20:00:00']
3.['3','302','8','1935','Salome','2008-04-19 14:30:0']
4.['']
For the 4th record, there are no values. So, to avoid such errors, i decided to make use of __new__ special method. I can achieve same functionality by putting the if condition and then checking whether the list is empty or not. But then i wondering how to make use of new special method to avoid such scenarios. With little knowledge of python, i have filled the new special method, but then I came across the below error
RecursionError: maximum recursion depth exceeded while calling a Python object
def __new__(cls,*args,**kwargs):
if len(args) != 0:
instance = Event.__new__(cls,*args,**kwargs)
return instance
Can we filter the records using the __new__ special method ?
What you want to do is totally possible. But you will need to initialize the instance by yourself once it returns from new .
I fixed your code as under
Given listing.txt
1|305|8|1851|Gotterdammerung|2008-01-25 14:30:00
2|306|8|2114|Boris Godunov|2008-10-15 20:00:00
3|302|8|1935|Salome|2008-04-19 14:30:0
4|302|8|1935|Salome|2008-04-19 14:30:0
class Event:
def __new__(cls, *args, **kwargs):
breakpoint()
if len(*args) > 1:
instance = object.__new__(cls)
breakpoint()
return instance
else:
return None
def __init__(self,eventid,venueid,catid,dateid,eventname,starttime):
self.eventid = eventid
self.venueid = venueid
self.catid = catid
self.dateid = dateid
self.eventname = eventname
self.starttime = starttime
def __iter__(self):
return (i for i in (self.eventid,self.venueid,self.catid,self.dateid,self.eventname,self.starttime))
def __str__(self):
return str(tuple(self))
def __repr__(self):
return "INSERT INTO EVENT (EVENTID,VENUEID,CATID,DATEID,EVENTNAME,STARTTIME) VALUES ({!r},{!r},{!r},{!r},{!r},{!r})".format(*self)
#classmethod
def loadlist(cls, records):
breakpoint()
return [cls.__init__(*record) for record in records ]
def initialize(e,eventid,venueid,catid,dateid,eventname,starttime):
e.eventid = eventid
e.venueid = venueid
e.catid = catid
e.dateid = dateid
e.eventname = eventname
e.starttime = starttime
return e
if __name__ == '__main__':
records = []
events = []
with open('listing.txt', 'r') as f:
records = list(map(lambda s: s.rstrip('\n').split('|'), f.readlines()))
for record in records:
breakpoint()
e = Event.__new__(Event, record)
breakpoint()
if e:
events.append(initialize(e, *record))
with open('events.sql','w+') as f:
print('writing file')
for event in events:
f.write(repr(event)+"\n")
OUTPUT
events.sql
INSERT INTO EVENT (EVENTID,VENUEID,CATID,DATEID,EVENTNAME,STARTTIME) VALUES ('1','305','8','1851','Gotterdammerung','2008-01-25 14:30:00')
INSERT INTO EVENT (EVENTID,VENUEID,CATID,DATEID,EVENTNAME,STARTTIME) VALUES ('2','306','8','2114','Boris Godunov','2008-10-15 20:00:00')
INSERT INTO EVENT (EVENTID,VENUEID,CATID,DATEID,EVENTNAME,STARTTIME) VALUES ('3','302','8','1935','Salome','2008-04-19 14:30:0')
INSERT INTO EVENT (EVENTID,VENUEID,CATID,DATEID,EVENTNAME,STARTTIME) VALUES ('4','302','8','1935','Salome','2008-04-19 14:30:0')
So I would solve it like this:
class Event:
def __init__(self, a, b):
self.a = a
self.b = b
def __new__(cls, *args, **kwargs):
if len(args) != 0:
return super(Event, cls).__new__(cls)
else:
return None
def print(self):
print("a " + str(self.a))
print("b " + str(self.b))
c = Event(1, 2)
if c is None:
print("do some stuff here if it is empty")
If you initialize Event with no parameters, it would return None according to len(args) != 0. Otherwise the instance is returned. Hope that helps.
I have an infinite loop that updates the currentPrice variable in the streamingPrice class, I need to use the value of this variable Trading class, the refresh function in Trading class is going to keep retrieving the value of the currentPrice every time it updates, then I'm going to perform a task on it. The stream and refresh functions have their own threads. How can I achieve that?
Currently I only get the initialized value of that variable
class streamingPrice():
def __init__(self):
self.currentPrice =0
def stream(self):
#Streaming live prices
api = API(access_token=userVals.key)
params = { "instruments": userVals.pair }
r = pricing.PricingStream(accountID=userVals.accountID, params=params)
rv = api.request(r)
for ticks in rv:
if('asks' in ticks):
self.setPrice(ticks['asks'][0]['price'])
def setPrice(self,price):
self.currentPrice = price
def getPrice(self):
return self.currentPrice
class Trading():
def refresh(self):
while(True):
#initialize data channel
self.highList, self.LowList, self.closeList = self.c.getData()
self.tradeCurrentPrice = self.sp.getPrice()
#Initialize Indicators
self.rolling_bands_low = self.s.ROLLING_BANDS_LOW(self.closeList)
self.rolling_bands_high = self.s.ROLLING_BANDS_HIGH(self.closeList)
self.stochostic_oscillator_k =
self.s.STOCHASTIC_OSCILLATOR_K(self.highList, self.LowList,
self.closeList)
self.stochostic_oscillator_d =
self.s.STOCHASTIC_OSCILLATOR_D(self.highList, self.LowList,
self.closeList)
self.tradeCurrentPrice = self.sp.getPrice() is wrong because you have not defined self.sp.
Based on your title I assume you want to do something like this:
sp = StreamingPrice()
trade = Trading(sp.currentPrice)
passing in the current price attribtue of the sp object into the new object.
Your Trading class will also need an __init__(self, price) method
there's also no need to create these methods:
def setPrice(self,price):
self.currentPrice = price
def getPrice(self):
return self.currentPrice
because you can achieve the same result doing this:
price = 3
sp = StreamingPrice()
sp.currentPrice = price
I have a function that uses a datetime object as default value:
from datetime import datetime, timedelta
from random import randint
def getTime(date = datetime.now()):
i = randint(1,300)
date = date - timedelta(seconds = i)
return date
Now, I need to check if the date variable inside the function was given by another function or was used the default one datetime.now(). If was used the default one, then subtract i seconds, else return the date that was given.
You can do it as follows:
def my_function(date=None):
if date is None:
# The default is used
date = datetime.now()
...
Assuming that you want "now" to be computed every time:
def getTime(date=None):
return date or datetime.now() - timedelta(seconds=randint(1,300))
Otherwise:
Introduce a default arg:
def getTime(date=None, _default=datetime.now()):
return date or _default - timedelta(seconds=randint(1,300))
Or create a decorator:
def just_return_if_provided(f):
def inner(date=None):
return date or f(date)
return inner
#just_return_if_provided
def getTime(date=datetime.now()):
return date - timedelta(seconds=randint(1,300))
If I have a variable:
var = 5
I want to detect and jump to a function when the value of the variable changes, so if var is not equal to the value it was before, I want to jump to a function.
What is the easiest way to do this?
Another example:
from datetime import datetime
import time
def dereferentie():
currentMinute = datetime.now().minute
checkMinute(currentMinute)
def checkMinute(currentMinute):
#if currentMinute has changed do:
printSomething()
def printSomething():
print "Minute is updated"
def main():
while (1):
dereferentie()
if __name__ == '__main__':
main()
Building on #HelloWorld's answer and #drIed's comment: A nice way would be, to wrap this into a class.
For example:
class Watcher:
""" A simple class, set to watch its variable. """
def __init__(self, value):
self.variable = value
def set_value(self, new_value):
if self.variable != new_value:
self.pre_change()
self.variable = new_value
self.post_change()
def pre_change(self):
pass # do stuff before variable is about to be changed
def post_change(self):
pass # do stuff right after variable has changed
I would go with a setter function which triggers your needed function.
def setValue(val):
global globalVal
valueChanged= g_val != val
if valueChanged:
preFunction()
globalVal = val
if valueChanged:
postFunction()
A great way is to use the #property and #.setter decorators.
class MyClass:
#property
def property_name(self):
return self.some_value
#property_name.setter
def property_name(self, new_value):
self.some_value = new_value
obj = MyClass()
obj.property_name = "New Value"
stored_value = obj.property_name
By the way this is one of my favorite features in Python.
Original Poster
Here's how I would implement your example.
from datetime import datetime
class TimeManager:
# The actual variable holding data
# You don't need to declare it, but I like to
_current_minute = None
#property
def current_minute(self):
"""Retrieve the local variable value."""
return self._current_minute
#current_minute.setter
#current_minute.setter
def current_minute(self, value):
"""Same method name, but set the local variable."""
self._current_minute = value
print("Minute has updated to {}".format(self._current_minute))
#current_minute.deleter
def current_minute(self):
"""You can also delete variables."""
del self._current_minute
def main():
# Create the class
time_manager = TimeManager()
for i in range(100):
current_minute = datetime.now().second
# set the .currrent_minute using a #property
time_manager.current_minute = current_minute
if __name__ == '__main__':
main()