Calling API multiple times - Python - python

I'm trying to use an API that converts dates. I've retrieved data from a file that contained full dates, used split and slice to get the day, month and year seperately. I need to send each date and return the conversion to the user.
What I currently have is:
def convert(day, month, year):
gr_to_hb_url = 'https://www.hebcal.com/converter?cfg=json&gy='+ year+ '&gm='+ month+ '&gd='+ day+'&g2h=1'
with urllib.request.urlopen(gr_to_hb_url) as response:
data = response.read()
obj = json.loads(data)
results = [(result['hd'], result['hm'],result['hy']) for result in obj]
return results
hby, hbm, hbd=convert(prep_day, prep_month, prep_year)
print(hby,hbm,hbd)
prep_day/ month/ year are the day, month and year I retrieved from each day separately as I mentioned above.
The error I get TypeError: string indices must be integers.
Appreciate any help. Thanks!

Having a look at the output of the request:
{"gy":2020,"gm":1,"gd":1,"afterSunset":false,"hy":5780,"hm":"Tevet","hd":4,"hebrew":"ד׳ בְּטֵבֵת תש״פ","events":["Parashat Vayigash"]}
I think you might want the following instead:
def convert(day, month, year):
gr_to_hb_url = 'https://www.hebcal.com/converter?cfg=json&gy='+ year+ '&gm='+ month+ '&gd='+ day+'&g2h=1'
with urllib.request.urlopen(gr_to_hb_url) as response:
data = response.read()
obj = json.loads(data)
results = (obj['hd'], obj['hm'],obj['hy'])
return results
The reason for the error you were seeing was that when you iterate through a dictionary type you just get the values.
In this case that would be something like the following (Although the order isn't guaranteed when iterating through a dictionary)
[2020,1,1,False, ...]
I imagine that the first element that you were iterating through was something like "Tevet".
If the value of result is "Tevet" then running "Tevet"["hd"]
would result in the error you were seeing.

Related

Cannot filter my Django model depence on created_date

I am trying to do a chart. My database has created_date. I am getting product data every day about 150 times and I want to see a daily increase and decrease of my data. I have no problem with my front end and Django-template (I try manual data and it works well) I just want to see the last 7 days chart.
When I use Products.objects.filter(created_dates=days) filter method I am getting empty Queryset.
I already try created_dates__gte=startdate,created_dates__lte=enddate it return empty Queryset to.
I also try created_dates__range to there is no answer too.
I just get data from created_dates__gte=days but I don't want these data.
view.py
from datetime import date,timedelta
import datetime
def data_chart(request):
data = []
week_days = [datetime.datetime.now().date()-timedelta(days=i) for i in range (1,7)]
for days in week_days:
product_num = Products.objects.filter(created_dates=days)
date =days.strftime("%d.%m")
item = {"day": date,"value":len(product_num)}
data.append(item)
return render(request, 'chartpage.html', {'data': data})
In my database, I have thousands of data and my daily data about 150. My created_dates column format like this.
created_dates col:
2020-10-19 09:39:19.894184
So what is wrong with my code?. Could you please help?
You are trying to compare DateTimeField type (created_dates) with Date type (week_days is list of days) so maybe You should try __date lookup.
product_num = Products.objects.filter(created_dates__date=days)
https://docs.djangoproject.com/en/3.0/ref/models/querysets/#date
Furthermore maybe You should consider start using Count() database function with group by instead of iterating over days.
Here is great explanation:
https://stackoverflow.com/a/19102493/5160341
You should be able to do this with a single aggregation query:
import datetime
from django.db.models import Count
def data_chart(request):
cutoff = datetime.date.today() - datetime.timedelta(days=7)
raw_data = (
Products.objects.filter(created_dates__gte=cutoff)
.values_list("created_dates__date")
.annotate(count=Count("id"))
.values_list("created_dates__date", "count")
)
data = [{"day": str(date), "value": value} for (date, value) in raw_data]
return render(request, "chartpage.html", {"data": data})

Pytrends - Interest over time - return column with None when there is no data

Pytrends for Google Trends data does not return a column if there is no data for a search parameter on a specific region.
The code below is from pytrends.request
def interest_over_time(self):
"""Request data from Google's Interest Over Time section and return a dataframe"""
over_time_payload = {
# convert to string as requests will mangle
'req': json.dumps(self.interest_over_time_widget['request']),
'token': self.interest_over_time_widget['token'],
'tz': self.tz
}
# make the request and parse the returned json
req_json = self._get_data(
url=TrendReq.INTEREST_OVER_TIME_URL,
method=TrendReq.GET_METHOD,
trim_chars=5,
params=over_time_payload,
)
df = pd.DataFrame(req_json['default']['timelineData'])
if (df.empty):
return df
df['date'] = pd.to_datetime(df['time'].astype(dtype='float64'),
unit='s')
df = df.set_index(['date']).sort_index()
From the code above, if there is no data, it just returns df, which will be empty.
My question is, how can I make it return a column with "No data" on every line and the search term as header, so that I can clearly see for which search terms there is no data?
Thank you.
I hit this problem, then I hit this web page. My solution was to ask Google trends for data on a search item it would have data for, then rename the column and 0 the data.
I used the ".drop" method to get rid of the "isPartial" column and the ".rename" method to change the column name. To zero the data in the column, I did the following, I created a function:
#Make value zero
def MakeZero(x):
return x *0
Then using the ".apply" method on the dataframe to 0 the column.
ThisYrRslt=BlankResult.apply(MakeZero)
: ) But the question is, what search term do you ask google trends about that will always return a value? I chose "Google". : )
I'm sure you can think of some better ones, but it's hard to leave those words in commercial code.

How to build a dataframe from scratch while filling in missing data? (details included in question)

I have a dataframe which looks like the following (Name of the first dataframe(image below) is relevantdata in the code):
I want the dataframe to be transformed to the following format:
Essentially, I want to get the relevant confirmed number for each Key for all the dates that are available in the dataframe. If a particular date is not available for a Key, we make that value to be zero.
Currently my code is as follows (A try/except block is used as some Keys don't have the the whole range of dates, hence a Keyerror occurs the first time you refer to that date using countrydata.at[date,'Confirmed'] for the respective Key, hence the except block will make an entry of zero into the dictionary for that date):
relevantdata = pandas.read_csv('https://raw.githubusercontent.com/open-covid-19/data/master/output/data_minimal.csv')
dates = relevantdata['Date'].unique().tolist()
covidcountries = relevantdata['Key'].unique().tolist()
data = dict()
data['Country'] = covidcountries
confirmeddata = relevantdata[['Date','Key','Confirmed']]
for country in covidcountries:
for date in dates:
countrydata = confirmeddata.loc[lambda confirmeddata: confirmeddata['Key'] == country].set_index('Date')
try:
if (date in data.keys()) == False:
data[date] = list()
data[date].append(countrydata.at[date,'Confirmed'])
else:
data[date].append(countrydata.at[date,'Confirmed'])
except:
if (date in data.keys()) == False:
data[date].append(0)
else:
data[date].append(0)
finaldf = pandas.DataFrame(data = data)
While the above code accomplished what I want in getting the dataframe in the format I require, it is way too slow, having to loop through every key and date. I want to know if there is a better and faster method to doing the same without having to use a nested for loop. Thank you for all your help.

How to work with multiple of the same key?

I have a large dictionary that contains weather data. You can take a look at it here
This weather data is for multiple days, and I want to get all of the values from one key. How would I do this?
Here is a simplified version of the dictionary:
'data': { 'day1' : {'weather_discription': 'cloudy'},
'day2' : {'weather_discription': 'clear'}
}
I tried to use this code:
import requests
r = requests.get('data website')
res = r.json()
print(res['weather_discription'])
You need a loop to get them all.
for day, data in res['data'].items():
print(f"Weather on {day} was {data['weather_description']}")

How do I exclude some responses from a function that pulls that from a spreadsheet?

I am trying to only show the dates to the uses of this Python application. For some reason, the code returns responses like "Date" and "None" from the spreadsheet. Date is in the column that I am trying to draw the dates from. Here is the code:
sh = gc.open("Deposits")
worksheet = sh.worksheet("Sheet2")
values_list = worksheet.col_values(3)
set = set(values_list)
result = list(set)
print "Here are all the possible dates to check:",result
Result:
['3/10/2012', '2/18/2013', '3/18/2011', '3/17/2010', 'Date', None, '2/9/2010']
How do I get this function to only return the dates and exclude 'Date' and 'None'?
Just subtract a set that contains the things you don't want to include.
myset = set(values_list) - {None, 'Date'}
Also, don't use variable names that are already assigned to built-in functions, like set, or you'll run into problems when you want to use that built-in function.
You can use a list comprehension to get rid of "Date" and None
a = ['3/10/2012', '2/18/2013', '3/18/2011', '3/17/2010', 'Date', None, '2/9/2010']
r = list(set([i for i in a if i not in("Date",None)]))
['3/10/2012', '2/18/2013', '3/18/2011', '3/17/2010', '2/9/2010']

Categories

Resources