Passing multiple value_list in Django - python

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.

Related

How to dump and save function arguments without embedding all of the container's content?

I am trying to save all function arguments as it is ran, to a container. Container is common for all funcs ran in the script. How to ensure all container's content is NOT saved every time I save function arguments?
Below decorator saves function arguments:
import inspect
from datetime import datetime
import time
def func_logger(method):
def wrapper(*args, **kw):
method_args = inspect.signature(method).bind(*args, **kw).arguments
runtime = str( datetime.now() )
name = method.__name__
module = method.__module__
signature = runtime + ': ' + '.'.join([module, name])
ts = time.time()
result = method(*args, **kw)
te = time.time()
kw['log'][signature] = {}
kw['log'][signature]['time'] = round(te - ts, 2)
kw['log'][signature]['args'] = method_args
return result
return wrapper
And an example function:
#func_logger
def test(a, b=4, c='blah-blah', *args, **kwargs):
return 4**4**8
When I am running the following snippet:
log = {}
output = test(1,4,2,4,1,par=1, log=log)
output = test(1,4,2,4,1,par=1, log=log)
log
I receive this output:
{'2019-05-17 13:48:25.214094: __main__.test': {'time': 0.0,
'args': OrderedDict([('a', 1),
('b', 4),
('c', 2),
('args', (4, 1)),
('kwargs', {'par': 1, 'log': {...}})])},
'2019-05-17 13:48:25.215092: __main__.test': {'time': 0.0,
'args': OrderedDict([('a', 1),
('b', 4),
('c', 2),
('args', (4, 1)),
('kwargs', {'par': 1, 'log': {...}})])}}
I already tried a workaround - a function that removes 'log' entry from the dictionary. However, every next item in this log stores of the log's current content. So when I try this:
list( log.items() )[-1][-1]['args']
The output is this:
OrderedDict([('a', 1),
('b', 4),
('c', 2),
('args', (4, 1)),
('kwargs',
{'par': 1,
'log': {'2019-05-17 13:45:45.748722: __main__.test': {'time': 0.0,
'args': OrderedDict([('a', 1),
('b', 4),
('c', 2),
('args', (4, 1)),
('kwargs', {'par': 1, 'log': {...}})])},
'2019-05-17 13:45:45.749221: __main__.test': {'time': 0.0,
'args': OrderedDict([('a', 1),
('b', 4),
('c', 2),
('args', (4, 1)),
('kwargs', {'par': 1, 'log': {...}})])},
'2019-05-17 13:45:45.750218: __main__.test': {'time': 0.0,
'args': OrderedDict(...)}}})])
So essentially, such a workaround won't work because with time, the memory would get clogged quickly.
Is there any way decorator would not save log entry every time I save function arguments? What I would rather like to avoid is to create a new 'log = {}' container every time I want to dump arguments from a new function.
You could simply store the log parameter if present and remove it from **kw:
def func_logger(method):
def wrapper(*args, **kw):
try:
log = kw['log']
del kw['log']
except KeyError:
log = None
method_args = inspect.signature(method).bind(*args, **kw).arguments
runtime = str( datetime.now() )
name = method.__name__
module = method.__module__
signature = runtime + ': ' + '.'.join([module, name])
ts = time.time()
result = method(*args, **kw)
te = time.time()
if log is not None:
log[signature] = {}
log[signature]['time'] = round(te - ts, 2)
log[signature]['args'] = method_args
return result
return wrapper
use global log in func_logger
log = {}
def func_logger(method):
def wrapper(*args, **kw):
# pass
log[signature] = {...}
return result
return wrapper
then, use output = test(1,4,2,4,1,par=1)

Using json.Encoder in django

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?

python3 fuzzywuzzy not returning index value of the array

I am trying to modify the fuzzywuzzy library. The module process returns the score and the array element. But I want it to return the index of the element along with the group of score,item,index.
Here is what I tried:
#!/usr/bin/env python
# encoding: utf-8
from fuzzywuzzy import fuzz
from fuzzywuzzy import utils
import heapq
import logging
from functools import partial
default_scorer = fuzz.WRatio
default_processor = utils.full_process
def extractWithoutOrder(query, choices, processor=default_processor, scorer=default_scorer, score_cutoff=0):
def no_process(x):
return x
try:
if choices is None or len(choices) == 0:
raise StopIteration
except TypeError:
pass
if processor is None:
processor = no_process
processed_query = processor(query)
if len(processed_query) == 0:
logging.warning(u"Applied processor reduces input query to empty string, "
"all comparisons will have score 0. "
"[Query: \'{0}\']".format(query))
# Don't run full_process twice
if scorer in [fuzz.WRatio, fuzz.QRatio,
fuzz.token_set_ratio, fuzz.token_sort_ratio,
fuzz.partial_token_set_ratio, fuzz.partial_token_sort_ratio,
fuzz.UWRatio, fuzz.UQRatio] \
and processor == utils.full_process:
processor = no_process
# Only process the query once instead of for every choice
if scorer in [fuzz.UWRatio, fuzz.UQRatio]:
pre_processor = partial(utils.full_process, force_ascii=False)
scorer = partial(scorer, full_process=False)
elif scorer in [fuzz.WRatio, fuzz.QRatio,
fuzz.token_set_ratio, fuzz.token_sort_ratio,
fuzz.partial_token_set_ratio, fuzz.partial_token_sort_ratio]:
pre_processor = partial(utils.full_process, force_ascii=True)
scorer = partial(scorer, full_process=False)
else:
pre_processor = no_process
processed_query = pre_processor(processed_query)
count = -1
try:
# See if choices is a dictionary-like object.
for key, choice in choices.items():
count = count + 1
processed = pre_processor(processor(choice))
score = scorer(processed_query, processed)
if score >= score_cutoff:
yield (choice, score, key,count)
except AttributeError:
# It's a list; just iterate over it.
for choice in choices:
count = count + 1
processed = pre_processor(processor(choice))
score = scorer(processed_query, processed)
if score >= score_cutoff:
yield (choice, score,count)
def extract(query, choices, processor=default_processor, scorer=default_scorer, limit=5):
sl = extractWithoutOrder(query, choices, processor, scorer)
return heapq.nlargest(limit, sl, key=lambda i: i[1]) if limit is not None else \
sorted(sl, key=lambda i: i[1], reverse=True)
When I tried to implement it, the result was what it was previously showing by fuzzywuzzy.
import process as p
box=['ness', 'apple','banana','carrot','duck','eagle','fish','gate','hitler']
p.extract('b',box)
[('banana', 90), ('apple', 0), ('carrot', 0), ('duck', 0), ('eagle', 0)]
But what I am expecting it to return is:
[('banana', 90, 2), ('apple', 0, 1), ('carrot', 0, 3), ('duck', 0, 4), ('eagle', 0, 5)]
Kindly let me know the suggestion.
As an alternative to FuzzyWuzzy you could use RapidFuzz (I am the author) which will return the index as well:
from rapidfuzz import process
box=['ness', 'apple','banana','carrot','duck','eagle','fish','gate','hitler']
p.extract('b',box)
which returns
[('banana', 90, 2), ('apple', 0, 1), ('carrot', 0, 3), ('duck', 0, 4), ('eagle', 0, 5)]
For those looking for the answer, can pass a dictionary to the process.
from fuzzywuzzy import fuzz
from fuzzywuzzy import process
box = ['apple','banana','carrot','duck','eagle']
box_dict = {i: val for i, val in enumerate(box)}
process.extract("b", box_dict, scorer=fuzz.WRatio)
# O/P -> [("banana", 90, 1), ('apple', 0, 0), ('carrot', 0, 2), ('duck', 0, 3), ('eagle', 0, 4)]

How to convert python list of tuples into tree?

I have a list of tuples like
list_of_tuples = [(number, name, id, parent_id),
(number, name, id, parent_id),
]
I am trying to sort it into an ordered structure like:
{
parent: [(id, name), (id, name)],
parent: {parent: [(id, name)]
{
So, any node could have a parent and/or children
I tried with:
tree = defaultdict(lambda: [None, ()])
ancestors = set([item[3] for item in list_of_tuples])
for items in list_of_tuples:
children_root = {}
descendants = []
number, name, id, parent = items
if parent is None:
tree[id] = [(id, name)]
elif parent:
if parent not in tree.keys():
node = tree.get(parent)
node.append((id, name))
children = (id, name)
tree[parent].append(children)
But I'm losing deep hierarchy when a node has both a parent and children
How do I make the ordering work correctly?
I propose to represent the tree nodes as tuples ((id, name), dict_of_children).
list_of_tuples = [(1, 'name1', 1, None),
(2, 'name2', 2, 1),
(3, 'name3', 3, 1),
(4, 'name4', 4, 2),
(5, 'name5', 5, 2),
(6, 'name5', 6, None),
(7, 'name5', 7, 6),
]
def build_tree(list_of_tuples):
"""
>>> import pprint
>>> pprint.pprint(build_tree(list_of_tuples))
{1: ((1, 'name1'),
{2: ((2, 'name2'), {4: ((4, 'name4'), {}), 5: ((5, 'name5'), {})}),
3: ((3, 'name3'), {})}),
6: ((6, 'name5'), {7: ((7, 'name5'), {})})}
"""
all_nodes = {n[2]:((n[2], n[1]), {}) for n in list_of_tuples}
root = {}
for item in list_of_tuples:
number, name, id, parent = item
if parent is not None:
all_nodes[parent][1][id] = all_nodes[id]
else:
root[id] = all_nodes[id]
return root

Translate Exif DMS to DD Geolocation with Python

I am using the following code to extract the geolocation of an image taken with an iPhone:
from PIL import Image
from PIL.ExifTags import TAGS
def get_exif(fn):
ret = {}
i = Image.open(fn)
info = i._getexif()
for tag, value in info.items():
decoded = TAGS.get(tag, tag)
ret[decoded] = value
return ret
a = get_exif('photo2.jpg')
print a
This is the result that I am returned:
{
'YResolution': (4718592, 65536),
41986: 0,
41987: 0,
41990: 0,
'Make': 'Apple',
'Flash': 32,
'ResolutionUnit': 2,
'GPSInfo': {
1: 'N',
2: ((32, 1), (4571, 100), (0, 1)),
3: 'W',
4: ((117, 1), (878, 100), (0, 1)),
7: ((21, 1), (47, 1), (3712, 100))
},
'MeteringMode': 1,
'XResolution': (4718592, 65536),
'ExposureProgram': 2,
'ColorSpace': 1,
'ExifImageWidth': 1600,
'DateTimeDigitized': '2011:03:01 13:47:39',
'ApertureValue': (4281, 1441),
316: 'Mac OS X 10.6.6',
'SensingMethod': 2,
'FNumber': (14, 5),
'DateTimeOriginal': '2011:03:01 13:47:39',
'ComponentsConfiguration': '\x01\x02\x03\x00',
'ExifOffset': 254,
'ExifImageHeight': 1200,
'Model': 'iPhone 3G',
'DateTime': '2011:03:03 10:37:32',
'Software': 'QuickTime 7.6.6',
'Orientation': 1,
'FlashPixVersion': '0100',
'YCbCrPositioning': 1,
'ExifVersion': '0220'
}
So, I am wondering how I convert the GPSInfo values (DMS) to Decimal Degrees for actual coordinates? Also, there seems to be two Wests listed . . . ?
Here's a way to do it, adapted for a script I wrote some months ago using pyexiv2:
a = get_exif('photo2.jpg')
lat = [float(x)/float(y) for x, y in a['GPSInfo'][2]]
latref = a['GPSInfo'][1]
lon = [float(x)/float(y) for x, y in a['GPSInfo'][4]]
lonref = a['GPSInfo'][3]
lat = lat[0] + lat[1]/60 + lat[2]/3600
lon = lon[0] + lon[1]/60 + lon[2]/3600
if latref == 'S':
lat = -lat
if lonref == 'W':
lon = -lon
This gives me the following latitude and longitude for your picture: 32.7618333, -117.146333 (same results as Lance Lee).
The last entry of GPSInfo may be the heading of the picture. You could check this using a tool that gives proper names to the different EXIF values such as exiv2 or exiftools.
http://www.exiv2.org/tags.html
find the string 'Exif.GPSInfo.GPSLatitude' in that page.
It appears that you get 3 pairs (representing rationals) and the second number in the pair is the denominator.
I would expect the thing after Longitude to be altitude, however it is a better fit for GPS timestamp.
In this example:
32/1 + (4571 / 100)/60 + (0 / 1)/3600 = 32.761833 N
117/1 + (878 / 100)/60 + (0 / 1)/3600 = 117.146333 W
Was this picture taken near 4646 Park Blvd, San Diego, CA 92116? If not then ignore this answer.

Categories

Resources