Baobab Baobab - 2 months ago 8
Python Question

Python passing variable dates to function

Hello: making progress but still struggling. I have the following json:

json =
{
"emeter": {
"get_daystat": {
"day_list": [
{ "year": 2016, "month": 10, "day": 1, "energy": 0.651000 },
{ "year": 2016, "month": 10, "day": 2, "energy": 0.349000 },
{ "year": 2016, "month": 10, "day": 3, "energy": 0.481000 }
],
"err_code": 0
}
}
}


I am using a linear search to find the energy value from a specific day with this function:

parsed_json = json.loads(json)

def get_energy_value_by_date(obj, year, month, day):
for value in obj['emeter']['get_daystat']['day_list']:
if value['year'] == year and value['month'] == month and value['day'] == day:
return value['energy']


energy = get_energy_value_by_date(parsed_json, 2016, 10, 2)


So far so good. What I need to do next is find the energy value for various days. For example today (assume json is valid):

import datetime
day_now = datetime.datetime.now().strftime("%d")
month_now = datetime.datetime.now().strftime("%m")
year_now = datetime.datetime.now().strftime("%Y")

parsed_json = json.loads(json)

def get_energy_value_by_date(obj, year, month, day):
for value in obj['emeter']['get_daystat']['day_list']:
if value['year'] == year and value['month'] == month and value['day'] == day:
return value['energy']


energy_today = get_energy_value_by_date(parsed_json, year_now, month_now, day_now)
print energy_today


When I run this script it returns

None


I must be missing something basic here. What I need is the ability to pull the energy value for any day of any month of any year for further processing.

Thanks!

Baobab

Answer

There is a simple issue with your script: strftime, according to the docs, will

return a string representing the date, controlled by an explicit format string.

The keyword here being "string." See the following:

>>> import datetime
>>> day_now = datetime.datetime.now().strftime("%d")
>>> day_now
'04'

This does not equal the integer value of the day in your JSON file:

>>> '04' == 4
False

Therefore, the equality check will always fail and None will be returned. One way is to use int to convert this value to an integer. A better way is to use the attributes of a datetime object to get the integer values:

>>> datetime.datetime.now().year
2016
>>> datetime.datetime.now().month
10
>>> datetime.datetime.now().day
4

I would also advise passing just a date object to the function and unpacking it there: it prevents redundancy and cleans up the function signature. You should also use date.today() instead of datetime.now() (since time is irrelevant) and then make the comparison in one operation. The full function could be something like this:

def get_energy_value_by_date(obj, current_day):   
    for value in obj['emeter']['get_daystat']['day_list']:
        if current_day == datetime.date(value['year'], value['month'], value['day']):
            return value['energy']

current_day = datetime.date.today()
energy_today = get_energy_value_by_date(parsed_json, current_day)
print (energy_today)