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]}
Related
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.
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?
I have a list and a dictionary and I want to ultimately find a sum of the values in the two. For example, I want the code below to return :
{gold coin : 45, rope : 1, dagger : 6, ruby : 1}
First I right a function to turn the dragonLoot list into a dictionary and then I run a Counter to add the two dictionaries together. However, when I run the code I get the following:
{'ruby': 1, 'gold coin': 3, 'dagger': 1}
Counter({'gold coin': 42, 'dagger': 5, 'rope': 1})
For some reason it looks like the Counter is not recognizing the dictionary that I create from dragonLoot. Does anyone have any suggestions on what I am doing wrong? Thanks!
inv = {'gold coin' : 42, 'rope' : 1, 'dagger' : 5}
dragonLoot = ['gold coin','dagger','gold coin','gold coin','ruby']
def inventory(item):
count = {}
for x in range(len(item)):
count.setdefault(item[x],0)
count[item[x]] = count[item[x]] + 1
print(count)
inv2 = inventory(dragonLoot)
from collections import Counter
dicts = [inv,inv2]
c = Counter()
for d in dicts:
c.update(d)
print(c)
You don't need the inventory function: Counter will count the iterable for you. You can also use + with Counter. Combine these, and you can do quite simply
inv = Counter({'gold coin' : 42, 'rope' : 1, 'dagger' : 5})
dragonLoot = ['gold coin','dagger','gold coin','gold coin','ruby']
inv += Counter(dragonLoot)
After this is run, inv will be Counter({'gold coin': 45, 'dagger': 6, 'rope': 1, 'ruby': 1}), as desired.
You are not returning the count in your inventory method:
def inventory(item):
count = {}
for x in range(len(item)):
count.setdefault(item[x],0)
count[item[x]] = count[item[x]] + 1
print(count)
You are simply printing your inventory calculation. Change that print to a return, or add a return line after the print:
def inventory(item):
count = {}
for x in range(len(item)):
count.setdefault(item[x],0)
count[item[x]] = count[item[x]] + 1
print(count)
return count
Adding that to your code and running it, gives this output:
Counter({'gold coin': 45, 'dagger': 6, 'rope': 1, 'ruby': 1})
Alternatively, the implementation provided by #nneonneo is optimal.
Here is an other way to do it without the Counter:
dragonLoot = ['gold coin','dagger','gold coin','gold coin','ruby']
inv = {'gold coin' : 42, 'rope' : 1, 'dagger' : 5}
for i in dragonLoot:
inv[i] = inv.get(i, 0) +1
print (inv)
Output:
{'gold coin': 45, 'rope': 1, 'dagger': 6, 'ruby': 1}
How can I sort these tuples by time interval, say every hour?
[('172.18.74.146', datetime.time(11, 28, 58)), ('10.227.211.244',
datetime.time(11, 54, 19)), ('10.227.215.68', datetime.time(11, 54, 34)),
('10.227.209.139', datetime.time(12, 14, 47)), ('10.227.147.98',
datetime.time(14, 47, 25))]
The result should be:
[["172.18.74.146, 10.227.211.244, 10.227.215.68", "11-12"], etc...]
I tried to use group by, but doesnt get what I want:
for dd in data[1:]:
ips = dd[1].split(",")
dates = dd[2].split(",")
i = 0
while(i < len(dates)):
ips[i] = ips[i].strip()
hour, mins, second = dates[i].strip().split(":")
dates[i] = datetime.time(int(hour), int(mins), int(second))
i+=1
order = [(k, ', '.join(str(s[0]) for s in v)) for k, v in groupby(sorted(zip(ips, dates), key=operator.itemgetter(1)), lambda x: x[1].hour)]
In [17]: a = [('172.18.74.146', datetime.time(11, 28, 58)), ('10.227.211.244',
datetime.time(11, 54, 19)), ('10.227.215.68', datetime.time(11, 54, 34)),
('10.227.209.139', datetime.time(12, 14, 47)), ('10.227.147.98',
datetime.time(14, 47, 25))]
In [18]: [(k, ', '.join(str(s[0]) for s in v)) for k, v in groupby(a, lambda x: x[1].hour)]
Out[18]:
[(11, '172.18.74.146, 10.227.211.244, 10.227.215.68'),
(12, '10.227.209.139'),
(14, '10.227.147.98')]
This should work for you:
from __future__ import print_function
import datetime
import itertools
def iter_len(iterable):
return sum(1 for __ in iterable)
def by_hour(item): # Hour key
timestamp = item[1]
return '{}-{}'.format(timestamp.hour, (timestamp.hour+1) % 24)
def by_half_hour(item): # Half-hour key
timestamp = item[1]
half_hour = timestamp.hour + (0.5 * (timestamp.minute // 30))
return '{:.1f}-{:.1f}'.format(half_hour, (half_hour+0.5) % 24)
def get_results(data, key): # Name this more appropriately
data = sorted(data, key=key)
for key, grouper in itertools.groupby(data, key):
yield (key, iter_len(grouper))
data = [
('172.18.74.146', datetime.time(11, 28, 58)),
('10.227.211.244', datetime.time(11, 54, 19)),
('10.227.215.68', datetime.time(11, 54, 34)),
('10.227.209.139', datetime.time(12, 14, 47)),
('10.227.147.98', datetime.time(14, 47, 25)),
]
print('By Hour')
print(list(get_results(data, by_hour)))
print()
print("By Half Hour")
print(list(get_results(data, by_half_hour)))
Output:
$ ./SO_32081251.py
By Hour
[('11-12', 3), ('12-13', 1), ('14-15', 1)]
By Half Hour
[('11.0-11.5', 1), ('11.5-12.0', 2), ('12.0-12.5', 1), ('14.5-15.0', 1)]
This is almost what you want. Use the hour to group by:
for k,g in itertools.groupby(order, lambda x: x[1].hour):
print k,list(g)
Results in:
11 [('172.18.74.146', datetime.time(11, 28, 58)), ('10.227.211.244', datetime.time(11, 54, 19)), ('10.227.215.68', datetime.time(11, 54, 34))]
12 [('10.227.209.139', datetime.time(12, 14, 47))]
14 [('10.227.147.98', datetime.time(14, 47, 25))]
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.