Using json.Encoder in django - python

i have done following things
def handle_json(obj):
# i want to make sure control goes here
print(obj)
return obj
def test_json():
data= {datetime.date(2018, 12, 1): 160000.0,
datetime.date(2019, 2, 1): 240000.0,
datetime.date(2020, 9, 1): 1360000.0,
datetime.date(2019, 3, 1): 280000.0}
print(json.dumps(data, default=handle_json))
When i run test_json(), why i am not getting print() from handle_json() on console?

Related

Python Iterate through rows, run and save

I have a pandas dataframe where I want to loop over its rows, run and save output, if any error then ingore it and move to next row.
import pandas as pd
from nsepy import get_history #can be install by "pip install nsepy"
from datetime import date
data = {'script': ['SBIN = get_history(symbol="SBIN", start=date(1985,1,1), end=date(2022,1,31))',
'SAIL = get_history(symbol="SAIL", start=date(1985,1,1), end=date(2022,1,31))',
'20MICRONS = get_history(symbol="20MICRONS", start=date(1985,1,1), end=date(2022,1,31))',
'RELIANCE = get_history(symbol="RELIANCE", start=date(1985,1,1), end=date(2022,1,31))']}
df = pd.DataFrame(data)
Now I want to run each line one by one
I can do it by
#run each row
#1
SBIN = get_history(symbol="SBIN", start=date(1985,1,1), end=date(2022,1,31))
df1.to_csv('SBIN', sep="\t")
#2
SAIL = get_history(symbol="SAIL", start=date(1985,1,1), end=date(2022,1,31))'
df1.to_csv('SAIL', sep="\t")
#3
20MICRONS = get_history(symbol="20MICRONS", start=date(1985,1,1), end=date(2022,1,31))
df1.to_csv('20MICRONS', sep="\t")
#4
RELIANCE = get_history(symbol="RELIANCE", start=date(1985,1,1), end=date(2022,1,31))
df1.to_csv('RELIANCE', sep="\t")
But it is going to take huge time. so how can it be done by for loop or while loop
Please note I would like to run each row and save the output as a character extracted before = sign of same row for example "SBIN" for first row. In case if there is any error on any line then ignore the error and move to the next line (line 3 is going to return an error which is due to the unavailability of data)
As your process is IO-Bounded, you can use Threading to increase the speed.
You can try this:
import pandas as pd
from nsepy import get_history
from datetime import date
import concurrent.futures
history = {
"SBIN": {"start": date(2021, 1, 1), "end": date(2022, 1, 31)},
"SAIL": {"start": date(2021, 1, 1), "end": date(2022, 1, 31)},
"20MICRONS": {"start": date(2021, 1, 1), "end": date(2022, 1, 31)},
"RELIANCE": {"start": date(2021, 1, 1), "end": date(2022, 1, 31)},
}
def get_historical_data(symbol, /, **kwds):
print(symbol)
df = get_history(symbol, **kwds)
df.to_csv(f'{symbol}.csv', sep='\t')
return df
data = []
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
future_history = [
executor.submit(get_historical_data, symbol, **data)
for symbol, data in history.items()
]
data = []
for future in concurrent.futures.as_completed(future_history):
data.append(future.result())
df = pd.concat(data)

How to fix "AttributeError: type object has no attribute" in python?

I am adding some code to the preset code to check the time availability, which is if the meeting time can fit into the proposed time schedule. However, I keep getting the following error. Can anyone please give me some advices? Thanks so much for your time.
Preset codes:
from datetime import datetime
class Meeting:
def __init__(self, start_time, end_time):
self.start_time = start_time
self.end_time = end_time
My codes:
def check_availability(meetings, proposed_time):
meeting_start = Meeting.datetime.start_time.hour
meeting_end = Meeting.datetime.end_time.hour
ok_time = datetime.proposed_time.hour
if meeting_start < ok_time < meeting_end:
return True
else:
return False
meetings = [Meeting(datetime(2018, 8, 1, 9, 0, 0), datetime(2018, 8, 1, 11,
0, 0)), Meeting(datetime(2018, 8, 1, 15, 0, 0), datetime(2018, 8, 1, 16, 0,
0)), Meeting(datetime(2018, 8, 2, 9, 0, 0), datetime(2018, 8, 2, 10, 0, 0))]
print(check_availability(meetings, datetime(2018, 8, 1, 12, 0, 0)))
print(check_availability(meetings, datetime(2018, 8, 1, 10, 0, 0)))
Your code raises this exception:
AttributeError: type object 'Meeting' has no attribute 'datetime'
At this line:
meeting_start = Meeting.datetime.start_time.hour
Python is telling you that the Meeting class doesn't have an attribute named datetime. This is true: the Meeting class is a factory for making meeting objects (or instances), and these objects have start_time and end_time attributes, which are set by passing datetime instances to Meeting's __init__ method. These attributes can be accessed like this:
>>> meeting = Meeting(datetime(2018, 8, 1, 9, 0, 0), datetime(2018, 8, 1, 11,
0, 0))
>>> print(meeting.start_time)
2018-08-01 09:00:00
>>> print(meeting.end_time)
2018-08-01 11:00:00
Your check_availability function is being passed a list of meetings, so you need to loop over the list to check whether any of the meetings conflict with the proposed meeting time.
def check_availability(meetings, proposed_time):
# Loop over the list of meetings; "meeting"
# is the meeting that you are currently inspecting.
for meeting in meetings:
# if proposed_time is between meeting.start_time
# and meeting.end_time, return False
# If you get through the list without returning False
# then the proposed time must be ok, so return True.

Changing keys in dictionary

How can I change the keys of a dictionary of lists to display dates (outright) rather than datetime.date(2017, 1, 1) which is what they currently are formatted as?
Example of section of list:
{datetime.date(2017, 9, 7): [162.3, 163.24, 162.22, 163.18], datetime.date(2017, 7, 10): [160.44, 161.13, 160.44, 160.94],
I am rather new to python so any help would be much appreciated. Thanks.
call the strftime method for each datetime object:
import datetime
s = {datetime.date(2017, 9, 7): [162.3, 163.24, 162.22, 163.18], datetime.date(2017, 7, 10): [160.44, 161.13, 160.44, 160.94]}
new_s = {a.strftime("%Y-%m-%d"):b for a, b in s.items()}
Output:
{'2017-07-10': [160.44, 161.13, 160.44, 160.94], '2017-09-07': [162.3, 163.24, 162.22, 163.18]}
Try this:
import datetime
my_dict = {datetime.date(2017, 9, 7): [162.3, 163.24, 162.22, 163.18], datetime.date(2017, 7, 10): [160.44, 161.13, 160.44, 160.94]}
new_dict = {str(k): v for k,v in my_dict.items()}
Output:
{'2017-07-10': [160.44, 161.13, 160.44, 160.94],
'2017-09-07': [162.3, 163.24, 162.22, 163.18]}

How to use a loop to create radiobuttons in Python

I have to create multiple radio buttons. Each has its own name and location on grid. There are also several variables involved.
I stored all the data to create these radio buttons in a tuple
(I know that FONTS does not cause a problem, its stored above this but isn't shown here):
self.unitType = IntVar()
self.matPropSel = IntVar()
self.secProfSel = IntVar()
self.endSupSel = IntVar()
self.loadTypeSel = IntVar()
self.RADIOLABELS = ( # Text, Font, Variable, Value, Row, Column
('English', self.FONTS[3], self.unitType, 1, 3, 1),
('metric', self.FONTS[3], self.unitType, 2, 4, 1),
('select preset', self.FONTS[3], self.matPropSel, 1, 6, 1),
('manual entry', self.FONTS[3], self.matPropSel, 2, 7, 1),
('select preset', self.FONTS[3], self.secProfSel, 1, 10, 1),
('manual entry', self.FONTS[3], self.secProfSel, 2, 11, 1),
('one end', self.FONTS[3], self.endSupSel, 1, 15, 1),
('both ends', self.FONTS[3], self.endSupSel, 2, 16, 1),
('point', self.FONTS[3], self.loadTypeSel, 1, 18, 1),
('uniform distribution', self.FONTS[3], self.loadTypeSel, 2, 19, 1),
('uniform variation', self.FONTS[3], self.loadTypeSel, 3, 20, 1)
)
So, how would I use a for loop to go through this tuple and generate a radio button from each line? Do all of the variables have to be the same? I am having problems with them.
Here is my attempt at a loop:
outerIndexer = 0
for labels in self.RADIOLABELS:
Radiobutton(self, text=self.RADIOLABELS[outerIndexer][0], font=self.RADIOLABELS[outerIndexer][1],
variable=self.RADIOLABELS[outerIndexer][2], value=self.RADIOLABELS[outerIndexer][3])\
.grid(row=self.RADIOLABELS[outerIndexer][4], column=self.RADIOLABELS[outerIndexer][5])
outerIndexer += 1
You can do it like this by looping through the RADIOLABELS. Note: it is also recommended to save the button to a list so it doesn't get lost.
self.RADIOLABELS = ( # Text, Font, Variable, Value, Row, Column
('English', self.FONTS[3], self.unitType, 1, 3, 1),
('metric', self.FONTS[3], self.unitType, 2, 4, 1),
('select preset', self.FONTS[3], self.matPropSel, 1, 6, 1),
('manual entry', self.FONTS[3], self.matPropSel, 2, 7, 1),
('select preset', self.FONTS[3], self.secProfSel, 1, 10, 1),
('manual entry', self.FONTS[3], self.secProfSel, 2, 11, 1),
('one end', self.FONTS[3], self.endSupSel, 1, 15, 1),
('both ends', self.FONTS[3], self.endSupSel, 2, 16, 1),
('point', self.FONTS[3], self.loadTypeSel, 1, 18, 1),
('uniform distribution', self.FONTS[3], self.loadTypeSel, 2, 19, 1),
('uniform variation', self.FONTS[3], self.loadTypeSel, 3, 20, 1)
)
radiobuttons = []
for _Text, _Font, _Variable, _Value, _Row, _Column in self.RADIOLABELS: # it will unpack the values during each iteration
_Radio = tk.Radiobutton(root, text = _Text, font = _Font, variable = _Variable, value = _Value)
# ^ root should be the frame/Tk you're trying to place it on, it will be self if this is a direct subclass of a Frame or Tk
# ^ or Radiobutton(.....) if you did from tkinter import *
_Radio.grid(row = _Row, column = _Column)
radiobuttons.append(_Radio)

Passing multiple value_list in Django

I have this code in views.py:
def pins_info(request):
if request.method == "GET":
getpin = request.GET.get('pin', None)
m = ButuanMaps.objects.filter(clandpin=getpin).
values_list('landproperty__ctaxdec')
n = ButuanMaps.objects.filter(clandpin=getpin).
values_list('ssectionid__sbrgyid__cbrgyname')
return HttpResponse(json.dumps({'taxdec': list(m),'brgy': list(n)}),
content_type='application/json')
I works fine, but it is not that effective when I want to get other values. I can access the result in my template like this:
success: function(data) {
taxdec = data['taxdec'];
brgy = data['brgy'];
var inputform = $('#forminput').val();
if( inputform == "Select Land PIN") {
alert('Please Select Land PIN')
}
else{
$('#status').append(
"<p>Tax Declaration: " + taxdec + "<br/>Barangay: " + brgy + "</p>"
);
}
}
How can I simplify my code to make it more effective like:
m = ButuanMaps.objects.filter(clandpin=getpin).
values_list('landproperty__ctaxdec','ssectionid__sbrgyid__cbrgyname')
But how do I pass it to my template?
If we take your m and n queries as:
m = range(5)
n = range(6, 11)
Then your single query of m = ButuanMaps.objects.filter(clandpin=getpin). values_list('landproperty__ctaxdec','ssectionid__sbrgyid__cbrgyname') is equivalent to the structure of:
new = zip(m, n)
#[(0, 6), (1, 7), (2, 8), (3, 9), (4, 10)]
So you can "transpose" that:
zip(*new)
# [(0, 1, 2, 3, 4), (6, 7, 8, 9, 10)]
Then build a dict from that and your keys:
results = dict(zip(['taxdec', 'brgy'], zip(*new))))
# {'brgy': (6, 7, 8, 9, 10), 'taxdec': (0, 1, 2, 3, 4)}
Then json.dumps results.
Or use an OrderedDict for your JSON name and column names values and generalise further:
from collections import OrderedDict
keyvals = OrderedDict([
('taxdec','landproperty__ctaxdec'),
('brgy', 'ssectionid__sbrgyid__cbrgyname')
])
m = ButuanMaps.objects.filter(clandpin=getpin).values_list(*keyvals.values())
result = dict(zip(keyvals, zip(*m)))
That way, you can add/remove columns to be selected and their associated JSON values in one place for the same query.

Categories

Resources