Python - Class calling not working when passing parameter - python

I wrote a class and everything works fine until i try to pass a parameter through calling a variable.
Let me show you:
INSTANCE ONE - ARGUMENTS PASSED DIRECTLY
a = Statements("AAPL","income_statement", "FY", ["2017","2018"])
d = a.get()
print(d)
Output (all good):
[{'tag': 'operatingrevenue', 'value': 229234000000.0}, {'tag': 'totalrevenue', 'value': 229234000000.0}, {'tag': 'operatingcostofrevenue', 'value': 141048000000.0}, {'tag': 'totalcostofrevenue', 'value': 141048000000.0}, {'tag': 'totalgrossprofit', 'value': 88186000000.0}, {'tag': 'sgaexpense', 'value': 15261000000.0}, {'tag': 'rdexpense', 'value': 11581000000.0}, {'tag': 'totaloperatingexpenses', 'value': 26842000000.0}, {'tag': 'totaloperatingincome', 'value': 61344000000.0}, {'tag': 'otherincome', 'value': 2745000000.0}, {'tag': 'totalotherincome', 'value': 2745000000.0}, {'tag': 'totalpretaxincome', 'value': 64089000000.0}, {'tag': 'incometaxexpense', 'value': 15738000000.0}, {'tag': 'netincomecontinuing', 'value': 48351000000.0}, {'tag': 'netincome', 'value': 48351000000.0}, {'tag': 'netincometocommon', 'value': 48351000000.0}, {'tag': 'weightedavebasicsharesos', 'value': 5217242000.0}, {'tag': 'basiceps', 'value': 9.27}, {'tag': 'weightedavedilutedsharesos', 'value': 5251692000.0}, {'tag': 'dilutedeps', 'value': 9.21}, {'tag': 'weightedavebasicdilutedsharesos', 'value': 5215900000.0}, {'tag': 'basicdilutedeps', 'value': 9.27}, {'tag': 'cashdividendspershare', 'value': 2.4}]
{'ticker': 'AAPL', 'statement': 'income_statement', 'type': 'FY', 'fiscal_year': '2017'}
[{'tag': 'operatingrevenue', 'value': 265595000000.0}, {'tag': 'totalrevenue', 'value': 265595000000.0}, {'tag': 'operatingcostofrevenue', 'value': 163756000000.0}, {'tag': 'totalcostofrevenue', 'value': 163756000000.0}, {'tag': 'totalgrossprofit', 'value': 101839000000.0}, {'tag': 'sgaexpense', 'value': 16705000000.0}, {'tag': 'rdexpense', 'value': 14236000000.0}, {'tag': 'totaloperatingexpenses', 'value': 30941000000.0}, {'tag': 'totaloperatingincome', 'value': 70898000000.0}, {'tag': 'otherincome', 'value': 2005000000.0}, {'tag': 'totalotherincome', 'value': 2005000000.0}, {'tag': 'totalpretaxincome', 'value': 72903000000.0}, {'tag': 'incometaxexpense', 'value': 13372000000.0}, {'tag': 'netincomecontinuing', 'value': 59531000000.0}, {'tag': 'netincome', 'value': 59531000000.0}, {'tag': 'netincometocommon', 'value': 59531000000.0}, {'tag': 'weightedavebasicsharesos', 'value': 4955377000.0}, {'tag': 'basiceps', 'value': 12.01}, {'tag': 'weightedavedilutedsharesos', 'value': 5000109000.0}, {'tag': 'dilutedeps', 'value': 11.91}, {'tag': 'weightedavebasicdilutedsharesos', 'value': 4956800000.0}, {'tag': 'basicdilutedeps', 'value': 12.01}, {'tag': 'cashdividendspershare', 'value': 2.72}]
{'ticker': 'AAPL', 'statement': 'income_statement', 'type': 'FY', 'fiscal_year': '2018'}
INSTANCE TWO - ARGUMENTS PASSED THROUGH VARIABLE
ticker = "MMM"
__________
Class ***:
class code
__________
e= Statements(ticker,"income_statement","FY", ["2017", "2018"])
f = e.get()
print(e)
Output (not good):
{'ticker': 'MMM', 'statement': 'income_statement', 'type': 'FY', 'fiscal_year': '2017'}
Traceback (most recent call last):
[]
File "C:/Users/ruleb/Desktop/python test/Ptf_Project/Financials.py", line 96, in <module>
{'ticker': 'MMM', 'statement': 'income_statement', 'type': 'FY', 'fiscal_year': '2018'}
f = e.get()
File "C:/Users/ruleb/Desktop/python test/Ptf_Project/Financials.py", line 86, in get
df = df.applymap(lambda x: x["value"])
File "C:\Users\ruleb\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\frame.py", line 6072, in applymap
return self.apply(infer)
File "C:\Users\ruleb\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\frame.py", line 6014, in apply
return op.get_result()
File "C:\Users\ruleb\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\apply.py", line 318, in get_result
return super(FrameRowApply, self).get_result()
File "C:\Users\ruleb\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\apply.py", line 142, in get_result
return self.apply_standard()
File "C:\Users\ruleb\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\apply.py", line 248, in apply_standard
self.apply_series_generator()
File "C:\Users\ruleb\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\apply.py", line 277, in apply_series_generator
results[i] = self.f(v)
File "C:\Users\ruleb\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pandas\core\frame.py", line 6070, in infer
return lib.map_infer(x.astype(object).values, func)
File "pandas/_libs/src\inference.pyx", line 1472, in pandas._libs.lib.map_infer
File "C:/Users/ruleb/Desktop/python test/Ptf_Project/Financials.py", line 86, in <lambda>
df = df.applymap(lambda x: x["value"])
TypeError: ("'NoneType' object is not subscriptable", 'occurred at index operatingrevenue')
Process finished with exit code 1
I'm attaching the full code for your reference:
import requests
import pandas as pd
ticker = "MMM"
class Statements:
def __init__(self,ticker = "AAPL",statement= "income_statement",period= "FY",fiscal_year = ["2017","2018"]):
self.ticker = ticker
self.statement = statement
self.period = period
self.fiscal_year = fiscal_year
# , ticker, statement, period, fiscal_year
def get(self):
api_username = 'x'
api_password = 'x'
base_url = "https://api.intrinio.com"
s = []
for year in self.fiscal_year:
request_url = base_url + "/financials/standardized"
query_params = {
'ticker': self.ticker,
'statement': self.statement,
'type': self.period,
'fiscal_year': year
}
response = requests.get(request_url, params=query_params, auth=(api_username, api_password))
if response.status_code == 401: print("Unauthorized! Check your username and password."); exit()
data = response.json()["data"]
s.append(data)
print(data)
print(query_params)
df = pd.DataFrame(s, index = self.fiscal_year)
df.columns = [i["tag"] for i in df.iloc[0].values]
df = df.applymap(lambda x: x["value"])
# print(df)
return df
a = Statements("AAPL","income_statement", "FY", ["2017","2018"])
d = a.get()
print(d)
e= Statements(ticker,"income_statement","FY", ["2017", "2018"])
f = e.get()
print(f)
I don't understand what difference does calling through external. variable makes.
Thanks to all!

Your assumption is wrong, it is not the external variable that causes the error. You are querying different tickers: "AAPL" vs "MMM"
The error is in the data you process - you got None's somewhere.
If you use
e = Statements("MMM","income_statement","FY", ["2017", "2018"])
you'll get the same error.
The problem is that somewhere you get a None value and try to use None[...] - but Nones are not subscriptable.
Debug these lines:
data = response.json()["data"] # json result might be None ?
df.columns = [i["tag"] for i in df.iloc[0].values] # i might be None
df = df.applymap(lambda x: x["value"]) # x might be None

Related

Python List data to Django ORM query

Let say, I have a list data for example:
data = [
{'id': 1, 'name': 'brad', 'color': 'red', 'tags': [], 'author': {'name': 'admin'}},
{'id': 2, 'name': 'sylvia', 'color': 'blue', 'tags': [], 'author': {'name': 'user'}},
{'id': 3, 'name': 'sylwia', 'color': 'green', 'tags': [], 'author': {'name': 'admin'}},
{'id': 4, 'name': 'shane', 'color': 'red', 'tags': [], 'author': {'name': 'admin'}},
{'id': 5, 'name': 'shane', 'color': 'red', 'tags': ['python', 'django'], 'author': {'name': 'user'}}
]
and I want to make it ORM'able, such as what Django has doing:
ModelName.objects.filter(color__icontains="gree")
And this what I have do;
import operator
from collections import namedtuple
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
class DataQuerySet:
"""
Custom ORM for List dict data,
https://stackoverflow.com/a/58351973/6396981
"""
allowed_operations = {
'gt': operator.gt,
'lt': operator.lt,
'eq': operator.eq,
'icontains': operator.contains
}
def __init__(self, data):
self.data = data
def all(self):
return self.data
def filter(self, **kwargs):
"""
>>> kwargs = {'name': 'sylwia', 'id__gt': 1}
>>> DataQuerySet().filter(**kwargs)
[{'id': 3, 'name': 'sylwia', 'color': 'green'}]
"""
operation = namedtuple('Q', 'op key value')
def parse_filter(item):
"""item is expected to be a tuple with exactly two elements
>>> parse_filter(('id__gt', 2))
Q(op=<built-in function gt>, key='id', value=2)
>>> parse_filter(('id__ ', 2))
Q(op=<built-in function eq>, key='id', value=2)
>>> parse_filter(('color__bad', 'red'))
Traceback (most recent call last):
...
AssertionError: 'bad' operation is not allowed
"""
key, *op = item[0].split('__')
# no value after __ means exact value query, e.g. name='sylvia'
op = ''.join(op).strip() or 'eq'
assert op in self.allowed_operations, f'{repr(op)} operation is not allowed'
return operation(self.allowed_operations[op], key, item[1])
filtered_data = self.data.copy()
for item in map(parse_filter, kwargs.items()):
filtered_data = [
entry for entry in filtered_data
if item.op(entry[item.key], item.value)
]
return filtered_data
def get(self, **kwargs):
"""
>>> DataQuerySet().get(id=3)
[{'id': 3, 'name': 'sylwia', 'color': 'green'}]
"""
operation = namedtuple('Q', 'op key value')
def parse_get(item):
key, *op = item[0].split('__')
return operation(self.allowed_operations['eq'], key, item[1])
filtered_data = self.data.copy()
for item in map(parse_get, kwargs.items()):
filtered_data = [
entry for entry in filtered_data
if item.op(entry[item.key], item.value)
]
if len(filtered_data) > 1:
raise MultipleObjectsReturned(filtered_data)
elif len(filtered_data) < 1:
raise ObjectDoesNotExist(kwargs)
return filtered_data[0]
And to use it:
class DataModel:
def __init__(self, data):
self._data = DataQuerySet(data)
#property
def objects(self):
return self._data
data = [
{'id': 1, 'name': 'brad', 'color': 'red', 'tags': [], 'author': {'name': 'admin'}},
{'id': 2, 'name': 'sylvia', 'color': 'blue', 'tags': [], 'author': {'name': 'user'}},
{'id': 3, 'name': 'sylwia', 'color': 'green', 'tags': [], 'author': {'name': 'admin'}},
{'id': 4, 'name': 'shane', 'color': 'red', 'tags': [], 'author': {'name': 'admin'}},
{'id': 5, 'name': 'shane', 'color': 'red', 'tags': ['python', 'django'], 'author': {'name': 'user'}}
]
d = DataModel(data)
print(d.objects.filter(id__gt=2))
print(d.objects.filter(color='green'))
print(d.objects.filter(color__icontains='gree'))
print(d.objects.get(id=1))
Above tests is just work properly, but seems we have a problem when we want to do more:
print(d.objects.filter(tags__in=['python']))
print(d.objects.filter(author__name='admin'))
print(d.objects.filter(author__name__icontains='use'))
Finally, I found a nice module to handle that case, it called with reobject, and here is the test:
from reobject.models import Model, Field
from reobject.query.parser import Q as Query
data = [
{'name': 'brad', 'color': 'red', 'tags': [], 'author': {'name': 'admin'}},
{'name': 'sylvia', 'color': 'blue', 'tags': [], 'author': {'name': 'user'}},
{'name': 'sylwia', 'color': 'green', 'tags': [], 'author': {'name': 'admin'}},
{'name': 'shane', 'color': 'red', 'tags': [], 'author': {'name': 'admin'}},
{'name': 'shane', 'color': 'red', 'tags': ['python', 'django'], 'author': {'name': 'user'}}
]
class Book(Model):
name = Field()
color = Field()
tags = Field()
author = Field()
for item in data:
Book(**item)
Book.objects.all()
Book.objects.get(name='brad')
Book.objects.filter(name='brad')
Book.objects.filter(author__name='admin')
Book.objects.filter(tags__contains='python')
Book.objects.filter(Query(author__name='admin') | Query(author__name='user'))
Meanwhile, it still doesn't support with id or pk fields.
Mybe because it already taken.

How to find a dict in a list with a particular key?

I have a list of lists with dicts as below:
[{'key': 'Platform', 'value': 'Test'}, {'key': 'Name', 'value': 'Test1'}, {'key': 'APICall', 'value': 'post'}]
[{'key': 'Platform', 'value': 'Test1'}, {'key': 'APICall', 'value': 'Get'}]
[{'key': 'Platform', 'value': 'Test2'}, {'key': 'Name', 'value': 'Test2'}, {'key': 'APICall', 'value': 'post'}]
for this list I would like to get the lists if keys Platform and Name are present.
So I would like to get
[{'key': 'Platform', 'value': 'Test'}, {'key': 'Name', 'value': 'Test1'}, {'key': 'APICall', 'value': 'post'}]
and [{'key': 'Platform', 'value': 'Test2'}, {'key': 'Name', 'value': 'Test2'}, {'key': 'APICall', 'value': 'post'}]
I don't know how to achieve this in one most effective way?
I did a very simplistic way which is working, but in the future, if the list count grows then it might take a longer time. Is there any simple and effective way to achieve this?
for arr_keys in arr:
if arr_keys['key'] == "Platform":
platform = arr_keys['value']
if arr_keys['key'] == "Name":
Name = arr_keys['value']
The only improvement you can make without changing the formatting of the input is to break out of the loop once the keys 'Platform' and 'Name' are encountered.
platform = None
name = None
for arr_keys in arr:
if arr_keys['key'] == "Platform":
platform = arr_keys['value']
if arr_keys['key'] == "Name":
name = arr_keys['value']
if platform is not None and name is not None:
print(arr)
break
So for each list, you want to check if all the keys (Platform and Name) appear in any of the dicts. This directly translates to:
lists = [[{'key': 'Platform', 'value': 'Test'}, {'key': 'Name', 'value': 'Test1'}, {'key': 'APICall', 'value': 'post'}],
[{'key': 'Platform', 'value': 'Test1'}, {'key': 'APICall', 'value': 'Get'}],
[{'key': 'Platform', 'value': 'Test2'}, {'key': 'Name', 'value': 'Test2'}, {'key': 'APICall', 'value': 'post'}]]
for obj in lists:
if all(any(d["key"] == key for d in obj) for key in ("Platform", "Name")):
print(obj)
This will however iterate over the dicts for each key. To do it in one pass over the dicts, something like this can work, using a defaultdict:
from collections import defaultdict
keys = ("Platform", "Name")
for obj in lists:
seen = defaultdict(bool)
for d in obj:
seen[d["key"]] = True
if all(seen[key] for key in keys):
print(obj)

Combine dictionary from a loop update statement

this is my current code
import copy
modes = ['dry', 'cool', 'heat']
result = {}
result['definition'] = [{'dtype': '', 'label': '', 'value': ''}]
for mode in modes:
for i in result['definition']:
for mode in modes:
ii = copy.deepcopy(i)
ii.update(dict(dtype='mode', label=mode, value=0))
print ii
This is my result
{'dtype': 'mode', 'value': 0, 'label': 'dry'}
{'dtype': 'mode', 'value': 0, 'label': 'cool'}
{'dtype': 'mode', 'value': 0, 'label': 'heat'}
I want to my output to look like this
result['definition'] = [{'dtype': 'mode', 'label': 'dry', 'value': 0},
{'dtype': 'mode', 'label': 'cool', 'value': 0},
{'dtype': 'mode', 'label': 'heat', 'value': 0}]
Could you please give me suggestion to this? Thanks in advance! :)
Try this
import copy
modes = ['dry', 'cool', 'heat']
result = {}
result['definition'] = [{'dtype': '', 'label': '', 'value': ''}]
result1 = dict()
result1 = {'definition':[]}
for i in result['definition']:
for mode in modes:
ii = copy.deepcopy(i)
ii.update(dict(dtype='mode', label=mode, value=0))
result1['definition'].append(ii)
print (result1['definition'])

how to ajax post form as json type to python then get data correct way?

js part
$('#btnUpdate').click(function(){
var formData = JSON.stringify($("#contrast_rule_set").serializeArray());
$.ajax({
type: "POST",
url: "./contrast_rule_set",
data: formData,
success: function(){},
dataType: "json",
contentType : "application/json"
});
})
python part
#app.route('/get_test', methods=['GET','POST'])
def get_test():
web_form_data = request.json
print(web_form_data)
print(type(web_form_data))
print(jsonify(web_form_data))
print(json.dumps(web_form_data))
python print console like
[{'name': 'logic_1', 'value': '1'}, {'name': 'StudyDescription_1', 'value': ''}, {'name': 'SeriesDescription_1', 'value': 'C\\+'}, {'name': 'ImageComments_1', 'value': ''}, {'name': 'logic_2', 'value': '1'}, {'name': 'StudyDescription_2', 'value': '\\-C'}, {'name': 'SeriesDescription_2', 'value': '\\-C'}, {'name': 'ImageComments_2', 'value': '\\-C'}, {'name': 'logic_3', 'value': '1'}, {'name': 'StudyDescription_3', 'value': ''}, {'name': 'SeriesDescription_3', 'value': '\\+C'}, {'name': 'ImageComments_3', 'value': '\\+C'}]
<class 'list'>
how to get list to json data type (or converter ) (html side code adjust or python side code adjust? )
then hope to get data like json type (data is from my another json file )
{
'Logic': 'AND',
'StudyDescription': '',
'SeriesDescription': 'C\+',
'ImageComments': ''
},
{
'Logic': 'NOT',
'StudyDescription': '\-C',
'SeriesDescription': '\-C',
'ImageComments': '\-C'
},
{
'Logic': 'AND',
'StudyDescription': '',
'SeriesDescription': '\+C',
'ImageComments': '\+C'
}

How can one use moz_sql_parser and DeepDiff to compare two sql Querys?

I am using moz_sql_parser to compare two SQL querys. And DeepDiff to see the diferences between the two querys.
I want a diferent kind of dictionary as showed below to perform better comparissons.
from moz_sql_parser import parse
import json
from jsondiff import diff
from deepdiff import DeepDiff
import pprint
sqlr = "SELECT distinct c.nome FROM compositor c, faixas f, artista ar, album a, fx_comp fx WHERE fx.compositor = c.compositor_id AND fx.faixa_id = f.faixa_id AND f.album = a.album_id AND (a.titulo = 'Help!' OR a.titulo = 'Abbey Road') AND ar.nome = 'The Beatles' AND f.faixa_numero < 6 Order By c.nome asc;"
sqlr1 = "SELECT c.nome FROM artista ar, album a, faixas f, compositor c, fx_comp fx WHERE fx.compositor = c.compositor_id AND fx.faixa_id = f.faixa_id AND f.album = a.album_id AND (a.titulo = 'Help!' OR a.titulo = 'Abbey Road') AND ar.nome = 'The Beatles' AND f.faixa_numero < 6 Order By c.nome desc;"
sqlr2 = "SELECT * FROM (SELECT * FROM ALBUM as x ,ARTISTA as pto WHERE ARTISTA.ARTISTA_ID = ALBUM.ARTISTA AND ARTISTA.ARTISTA_ID = 4) AS B;"
#print(json.dumps(parse(sql8), sort_keys=True, indent=4))
data1 = json.loads(json.dumps(parse(sqlr.lower()),sort_keys=True))
data2 = json.loads(json.dumps(parse(sqlr1.lower()),sort_keys=True))
pprint.pprint(data1)
print('###################################')
#data3 = diff(data2, data1)
ddiff = DeepDiff(data1,data2, ignore_order=True)
pprint.pprint((ddiff))
print(ddiff['type_changes']["root['select']['value']"])
#print(type(data1['select']['value']))
At the current version data1 and data2 are like:
And to parse the data of the dictionary to make it more legible and usable.
DATA1
{'from': [{'name': 'c', 'value': 'compositor'},
{'name': 'f', 'value': 'faixas'},
{'name': 'ar', 'value': 'artista'},
{'name': 'a', 'value': 'album'},
{'name': 'fx', 'value': 'fx_comp'}],
'orderby': {'sort': 'asc', 'value': 'c.nome'},
'select': {'value': {'distinct': 'c.nome'}},
'where': {'and': [{'eq': ['fx.compositor', 'c.compositor_id']},
{'eq': ['fx.faixa_id', 'f.faixa_id']},
{'eq': ['f.album', 'a.album_id']},
{'or': [{'eq': ['a.titulo', {'literal': 'help!'}]},
{'eq': ['a.titulo', {'literal': 'abbey road'}]}]},
{'eq': ['ar.nome', {'literal': 'the beatles'}]},
{'lt': ['f.faixa_numero', 6]}]}}
DATA2
{'from': [{'name': 'ar', 'value': 'artista'},
{'name': 'a', 'value': 'album'},
{'name': 'f', 'value': 'faixas'},
{'name': 'c', 'value': 'compositor'},
{'name': 'fx', 'value': 'fx_comp'}],
'orderby': {'sort': 'desc', 'value': 'c.nome'},
'select': {'value': 'c.nome'},
'where': {'and': [{'eq': ['fx.compositor', 'c.compositor_id']},
{'eq': ['fx.faixa_id', 'f.faixa_id']},
{'eq': ['f.album', 'a.album_id']},
{'or': [{'eq': ['a.titulo', {'literal': 'help!'}]},
{'eq': ['a.titulo', {'literal': 'abbey road'}]}]},
{'eq': ['ar.nome', {'literal': 'the beatles'}]},
{'lt': ['f.faixa_numero', 6]}]}}
But it keeps changing. So the structure of the dictionary is never the same, witch makes it a mess to parse.
i want to transform data1 and data2 in something like:
[['Table1','Alias','variable1associatedwithtable1','variable1associatedwithtable12',],
['Table2name','Alias','variable1associatedwithtable2name','variable1associatedwithtable2name']]
for Tables and their own variables incluing the alias used
[['Table2name','function','variable_associated_with_table_name'],

Categories