Design a JSON structure to create a display - python

I'm requesting for help in creating a JSON structure that will help in creating a display in Command Prompt using python. I have a draft JSON structure that is given below. I can change the below structure to best suit the display.
Plan is to use {}.format() to create the display.
[
{
"Acc1": [
{
"clientId": "Acc1",
"Strategy": "MONTHLY_IRON_CONDOR",
"StrategyList": [
"MONTHLY_IRON_CONDOR",
"MONTHLY_IRON_CONDOR",
"MANUAL"
],
"strikeType": "PE",
"CurrentM2M": 1850.0,
"MaxStopLoss": 24195.0,
"MaxProfit": 8065.0
},
{
"clientId": "Acc1",
"Strategy": "MONTHLY_IRON_CONDOR",
"StrategyList": [
"MONTHLY_IRON_CONDOR",
"MONTHLY_IRON_CONDOR",
"MANUAL"
],
"strikeType": "CE",
"CurrentM2M": -8075.0,
"MaxStopLoss": 36060.0,
"MaxProfit": 12020.0
}
]
},
{
"Acc2": [
{
"clientId": "Acc2",
"Strategy": "LONGTERM_STRANGLE",
"StrategyList": [
"LONGTERM_STRANGLE",
"LONGTERM_STRANGLE"
],
"strikeType": "PE",
"CurrentM2M": 405.0,
"MaxStopLoss": 21735.0,
"MaxProfit": 7245.0
},
{
"clientId": "Acc2",
"Strategy": "LONGTERM_STRANGLE",
"StrategyList": [
"LONGTERM_STRANGLE",
"LONGTERM_STRANGLE"
],
"strikeType": "CE",
"CurrentM2M": -3105.0,
"MaxStopLoss": 36015.0,
"MaxProfit": 12005.0
}
]
}
]
Output Structure:
Strategies Acc1 Acc2
P&L | SL | MaxPL P&L | SL | MaxPL
MONTHLY_IRON_CONDOR ----> PE 1850.0 24195.0 8065.0
CE -8075.0 36060.0 12020.0
LONGTERM_STRANGLE ------> PE 405.0 21735.0 7245.0
CE -3105.0 36015.0 12005.0
I've already tried the extract the data best out of the above JSON using the python code given below;
import json
import os
import random
import sys
import time
import pandas as pd
home = os.path.dirname(os.path.dirname(
os.path.dirname(os.path.realpath(__file__))))
sys.path.append(home)
home = os.path.dirname(os.path.dirname(
os.path.dirname(os.path.realpath(__file__))))
tmp_path = str(os.path.join(home, "tmp"))
# Set base path:--------------------------------------------------------
sys.path.append(home)
os.chdir(home)
def clear_screen():
os.system('cls' if os.name == 'nt' else 'clear')
a = 0
while True:
clear_screen()
positionsList = None
if (os.path.isfile(os.path.join(tmp_path, "input"))):
with open(os.path.join(tmp_path, "input"), "r") as f:
positionsList = json.loads(f.read(), strict=False)
clientIdList = []
headerClientId = " Strategies " # This variable will hold the top Header line that will contain dynamic
# number of Accounts
headerNames = " " # This variable will hold the text "P&L | SL | MaxPL" for all
the accounts
monthlyIC = " " # Strategy Specific data for MONTHLY_IRON_CONDOR
longtermStrangle = " " # Strategy Specific data for LONGTERM_STRANGLE
noData = " " # Filler when there is no data for a specific strategy for a given
account
for client in positionsList:
values = list(client.values())[0]
flg = False
for value in values:
for clientId in client.keys():
if flg == False:
clientIdList.append(clientId)
headerClientId = headerClientId + "{} "
headerNames = headerNames + "P&L | SL | MaxPL "
flg = True
availableStrategies = ["MONTHLY_IRON_CONDOR",'INTRADAY_STRANGLE", "LONGTERM_STRANGLE", "PUT_SPREAD"]
unusedStrategies = list(
set(availableStrategies) - set(value['StrategyList'])) # Helps to fill "noData" for these strategies for each
# Account
if Strategy.monthlyIronCondor.value in unusedStrategies and "\n" not in monthlyIC:
monthlyIC = monthlyIC + noData
elif Strategy.longTermStrangle.value in unusedStrategies and "\n" not in longtermStrangle:
longtermStrangle = longtermStrangle + noData
if value['Strategy'] == Strategy.monthlyIronCondor.value:
monthlyIC = monthlyIC + "" + str(value['strikeType']) + " " + str(value['CurrentM2M']) + \
" " + str(value['MaxStopLoss']) + \
" " + str(value['MaxProfit'])
if value['Strategy'] == Strategy.longTermStrangle.value:
longtermStrangle = longtermStrangle + "" + str(value['strikeType']) + " " + str(value['CurrentM2M']) + \
" " + str(value['MaxStopLoss']) + \
" " + str(value['MaxProfit'])
if monthlyIC.replace(' ', '', -1) != '':
monthlyIC = monthlyIC + "\n "
if longtermStrangle.replace(' ', '', -1) != '':
longtermStrangle = longtermStrangle + "\n "
# if longtermStrangle.replace(' ', '', -1) == '':
# longtermStrangle = longtermStrangle + noData
headerClientId = headerClientId.format(clientIdList[0], clientIdList[1])
print(headerClientId, end='\n\r')
print(headerNames, end='\n\r')
print("MONTHLY_IRON_CONDOR ----> " + monthlyIC, end='\n\r')
print("LONGTERM_STRANGLE ------> " + longtermStrangle, end='\n\r')
time.sleep(1)
a += 1

Related

Bitcoin Transaction Mapping Throws KeyError

I have the following piece of code, which seems to run until line 36 recipientlist.append(target["addr"]) and then throws the error KeyError: 'addr'
However 'addr' seems to be in the data so not sure what the issue is
Can someone please help?
import json
import requests
z = 0
i = 0
firstpart = "https://blockchain.info/rawaddr/"
initialinput = '3PaGEcGDjPsNQHAQ4pTmjQuLXWoEwvnr11'
initialreq = firstpart + initialinput
firstjson = (requests.get(initialreq)).json()
graphvizlines = []
addresslist = []
usedaddresslist = []
addresslist.append(initialinput)
usedaddresslist.append(initialinput)
while i < 6:
if z is 1:
initialreq = firstpart + addresslist[i]
firstjson = (requests.get(initialreq)).json()
for transaction in firstjson["txs"]:
payerlist = []
recipientlist = []
print("\n" + transaction["hash"])
for item in transaction["inputs"]:
payerlist.append(item["prev_out"]["addr"])
if item["prev_out"]["addr"] not in addresslist:
addresslist.append(item["prev_out"]["addr"])
for target in transaction["out"]:
recipientlist.append(target["addr"])
if target["addr"] not in addresslist:
addresslist.append(target["addr"])
for payer in payerlist:
for recipient in recipientlist:
a = '"' + payer + '"' + " -> " + '"' + recipient + '"' + ";"
if a not in graphvizlines:
graphvizlines.append(a)
i = i + 1
z = 1
for t in graphvizlines:
print(t)
While addr is in your data, it's not in every inputs element. Check the very last element in txs, you'll see that inputs is:
"inputs": [
{
"sequence": 0,
"witness": "304402203f872bfd7093fcdad6a3735cbd76f276279890b0304e6f23f54c51388cc2a84402203731d7a7f71265f072f6792c8f4d2e805ff8f86bbfbd0b48a187d573c051593001",
"prev_out": {
"spent": true,
"spending_outpoints": [
{
"tx_index": 0,
"n": 0
}
],
"tx_index": 0,
"type": 0,
"value": 1880609,
"n": 1,
"script": "0014292738ed3f9466f8eedd8c49e5bb013088a7052b"
},
"script": ""
}
],
This element lacks the presence of prev_out.addr.
You will need to first check if the addr element exists or wrap your loop in a try/except.
for transaction in firstjson['txs']:
...
for item in transaction['inputs']:
address = item.get('prev_out').get('addr')
if(address == None):
continue
payerlist.append(address)
...
The above would still fail if prev_out didn't exist, so you should confirm what will be in the result and what might be.

How to iterate through two pandas columns and create a new column

I am trying to create a new column by concatenating two columns with certain conditions.
master['work_action'] = np.nan
for a,b in zip(master['repair_location'],master['work_service']):
if a == 'Field':
master['work_action'].append(a + " " + b)
elif a == 'Depot':
master['work_action'].append(a + " " + b)
else:
master['work_action'].append(a)
TypeError: cannot concatenate object of type '<class 'str'>'; only Series and DataFrame objs are valid
The problem is with master['work_action'].append(a + " " + b)
If I change my code to this:
test = []
for a,b in zip(master['repair_location'],master['work_service']):
if a == 'Field':
test.append(a + " " + b)
elif a == 'Depot':
test.append(a + " " + b)
else:
test.append(a)
I get exactly what I want in a list. But I want it in a pandas column. How do I create a new pandas column with the conditions above?
If performance is important, I would use numpy's select:
master = pd.DataFrame(
{
'repair_location': ['Field', 'Depot', 'Other'],
'work_service':[1, 2, 3]
}
)
master['work_action'] = np.select(
condlist= [
master['repair_location'] == 'Field',
master['repair_location'] == 'Depot'
],
choicelist= [
master['repair_location'] + ' ' + master['work_service'].astype(str),
master['repair_location'] + ' ' + master['work_service'].astype(str)
],
default= master['repair_location']
)
Which results in:
repair_location work_service work_action
0 Field 1 Field 1
1 Depot 2 Depot 2
2 Other 3 Other
Append method is for insert values at the end. You are trying to concatenate two strings values. Use apply method:
def fun(a,b):
if a == 'Field':
return a + " " + b
elif a == 'Depot':
return a + " " + b
else:
return a
master['work_action'] = master.apply(lambda x: fun(x['repair_location'], x['work_service']), axis=1)

Alternative of orca for creating PDF file with images and figures

I am using this script to create pdf file and append images with statistics:
import MySQLdb
from plotly import graph_objs as go
import numpy as np
import os
from plotly.subplots import make_subplots
from PyPDF2 import PdfFileMerger
from datetime import datetime, timedelta
import smtplib
from email.message import EmailMessage
import imghdr
# Database connect
db = MySQLdb.connect(host="localhost",
user="root",
passwd="****",
db="ofasorgu_10_168_1_71")
today = datetime.today().strftime('%Y-%m-%d')
one_week = (datetime.today() - timedelta(days=7)).strftime('%Y-%m-%d')
two_week = (datetime.today() - timedelta(days=14)).strftime('%Y-%m-%d')
three_week = (datetime.today() - timedelta(days=21)).strftime('%Y-%m-%d')
four_week = (datetime.today() - timedelta(days=28)).strftime('%Y-%m-%d')
# Functions
def load_post_views(table, today, one_week, two_week, three_week, four_week):
product_views_dict = dict()
cursor = db.cursor()
cursor.execute(
"SELECT client_id, product_id, referrer, `date`" +
" FROM " + table +
" WHERE `date`>='"+four_week+"'")
for x in range(0, cursor.rowcount):
row = cursor.fetchone()
network = ""
period = ""
client_id = row[0]
product_id = row[1]
referrer = row[2]
date = str(row[3])
email_cursor = db.cursor()
email_cursor.execute("SELECT address FROM c8ty_connections_email WHERE entry_id=" + str(client_id))
email = email_cursor.fetchone()
product_cursor = db.cursor()
product_cursor.execute("SELECT post_title FROM c8ty_posts WHERE id=" + str(product_id))
product_name = product_cursor.fetchone()
# Add client ID key
if client_id not in product_views_dict:
product_views_dict[client_id] = dict()
# Add product ID key to client ID parent key
if product_id not in product_views_dict[client_id]:
product_views_dict[client_id][product_id] = {
today + " - " + one_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
},
one_week + " - " + two_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
},
two_week + " - " + three_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
},
three_week + " - " + four_week: {
"facebook": 0,
"twitter": 0,
"instagram": 0,
"linkedin": 0,
"pinterest": 0,
"website": 0,
}
}
# Find referrer
if "facebook" in referrer:
network = "facebook"
elif "twitter" in referrer:
network = "twitter"
elif "instagram" in referrer:
network = "instagram"
elif "linkedin" in referrer:
network = "linkedin"
elif "pinterest" in referrer:
network = "pinterest"
else:
network = "website"
# Check view period
if date <= today and date > one_week:
period = today + " - " + one_week
if date <= one_week and date > two_week:
period = one_week + " - " + two_week
if date <= two_week and date > three_week:
period = two_week + " - " + three_week
if date <= three_week and date > four_week:
period = three_week + " - " + four_week
product_views_dict[client_id][product_id][period][network] += 1
product_views_dict[client_id]["email"] = email[0]
product_views_dict[client_id][product_id]["product"] = product_name[0]
return product_views_dict
def draw_statistic(data_dict):
for clinetID, product_info in data_dict.items():
client_email = product_info["email"]
for productID, product_data in product_info.items():
if type(product_data) is dict:
product_name = product_data['product']
table_data = [
[
today + " - " + one_week,
one_week + " - " + two_week,
two_week + " - " + three_week,
three_week + " - " + four_week,
today + " - " + four_week
]
]
total_one = []
total_two = []
total_three = []
total_four = []
overall_traces = []
networks_and_positions = [
{"network": "website","row": 2,"col": 1},
{"network": "linkedin","row": 2,"col": 2},
{"network": "facebook","row": 3,"col": 1},
{"network": "twitter","row": 3,"col": 2},
{"network": "instagram","row": 4,"col": 1},
{"network": "pinterest","row": 4,"col": 2}
]
fig = make_subplots(rows=5, cols=2)
merge_fig = make_subplots(rows=1, cols=1)
count = 2
for dictionary in networks_and_positions:
network = dictionary['network']
row = dictionary['row']
col = dictionary['col']
total_one.append(product_data[today + " - " + one_week][network])
total_two.append(product_data[one_week + " - " + two_week][network])
total_three.append(product_data[two_week + " - " + three_week][network])
total_four.append(product_data[three_week + " - " + four_week][network])
table_data.append([
product_data[today + " - " + one_week][network],
product_data[one_week + " - " + two_week][network],
product_data[two_week + " - " + three_week][network],
product_data[three_week + " - " + four_week][network],
sum([
product_data[today + " - " + one_week][network],
product_data[one_week + " - " + two_week][network],
product_data[two_week + " - " + three_week][network],
product_data[three_week + " - " + four_week][network]
])
])
xaxis = [
today + " - " + one_week,
one_week + " - " + two_week,
two_week + " - " + three_week,
three_week + " - " + four_week,
]
yaxis = [
product_data[today + " - " + one_week][network],
product_data[one_week + " - " + two_week][network],
product_data[two_week + " - " + three_week][network],
product_data[three_week + " - " + four_week][network]
]
chart_name = network.capitalize() + " statistic"
# Create bar chart
if (count == 2):
social_fig = go.Bar(
x=xaxis,
y=yaxis,
name=chart_name
)
else:
social_fig = go.Bar(
x=xaxis,
y=yaxis,
name=chart_name,
yaxis="y"+str(count)
)
# Add chart to fig
fig.add_trace(
social_fig,
row=row,
col=col
)
count += 1
trace_name = network.capitalize() + " views"
overall_traces.append(
go.Scatter(
x=xaxis,
y=yaxis,
name=trace_name
)
)
total_column_values_array = [sum(total_one), sum(total_two), sum(total_three), sum(total_four),]
total_column_values_array.append(
sum(total_one)+sum(total_two)+sum(total_three)+sum(total_four)
)
table_data.append(total_column_values_array)
# Create product table
fig.add_trace(
go.Table(
header=dict(values=["Period", "Website", "Facebook", "Twitter", "Instagram", "LinkedIn", "Pinterest", "Total"]),
cells=dict(values=table_data)
)
)
merge_fig.add_traces(overall_traces)
# Craete folder if doesn't exist
if not os.path.exists("files"):
os.mkdir("files")
statistic_file = "files/statistic_"+product_name+".pdf"
overall_file = "files/overall_"+product_name+".pdf"
out_file = "files/"+product_name+"_statistic.pdf"
# Create charts file
fig.update_layout(height=1500, width=1000, title_text="<b>Greetings</b><br />This is statistic from <a href='https://www.cfasuk.co.uk/'>CFAS UK</a> for your product <b>"+product_name+"</b>")
fig.update_layout(
yaxis3=dict(title="Website views", titlefont=dict(color="#636efa")),
yaxis4=dict(title="LinkedIn views", titlefont=dict(color="#ef553b")),
yaxis5=dict(title="Facebook views", titlefont=dict(color="#00cc96")),
yaxis6=dict(title="Twitter views", titlefont=dict(color="#b780f9")),
yaxis7=dict(title="Instagram views", titlefont=dict(color="#ffa15a")),
yaxis8=dict(title="Pinterest views", titlefont=dict(color="#19d3f3")),
)
fig.write_image(statistic_file)
# Create overall file
merge_fig.update_layout(height=700, width=1000, title_text="Overall <b>"+product_name+"</b> statistic")
merge_fig.write_image(overall_file)
merge = PdfFileMerger(strict=False)
# Append charts file to merger
merge.append(statistic_file)
# Append overall file to merger
merge.append(overall_file)
# Create end statistic file with both charts and overall
merge.write(out_file)
merge.close()
# Delete statistic file
os.remove(statistic_file)
# Delete overall file
os.remove(overall_file)
# Send email with file
send_mail(
"tomaivanovtomov#gmail.com",
"tomaivanovtomov#gmail.com",
"CFAS UK, "+product_name+" statistic",
"This is automated email. Please, do not reply!<br/>"+
"If you find some problem with the statistic or the product is not yours, please contact CFAS UK team.<br/>"+
"Best regards!",
out_file
)
def send_mail(send_from, send_to, subject, text, file=None):
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
smtp.login("tomaivanovtomov#gmail.com", "zmjquvphuvigqdai")
msg = EmailMessage()
msg['Subject'] = subject
msg['From'] = send_from
msg['To'] = send_to
msg.set_content(text)
with open(file, "rb") as f:
file_data = f.read()
file_name = f.name
msg.add_attachment(file_data, maintype='application/pdf', subtype='pdf', filename=file_name)
smtp.send_message(msg)
# Init
product_views_dict = load_post_views("an_product_view", today, one_week, two_week, three_week, four_week)
brochure_views_dict = load_post_views("an_brochure_view", today, one_week, two_week, three_week, four_week)
draw_statistic(product_views_dict)
draw_statistic(brochure_views_dict)
db.close()
exit()
It works fine when I test it on my local server. But I need to upload it to shared account on a Centos server. On my hosting provider. There I can't install anaconda which I need to install orca for static images. Is there an alternative to create images and then add it to pdf file? Thank you in advance!
Yes (you do not need to use any tool backend dependency in your code), there's a very easy alternative library example as shown below.
you can use matplotlib integration for this.
you can import these modules as shown below
from plotly.offline import init_notebook_mode, plot_mpl
import matplotlib.pyplot as plt
and you can use them as below:
init_notebook_mode()
fig = plt.figure()
# you can configure you plot here use below to save it as image
plot_mpl(fig)
plot_mpl(fig, image='png')
OR if you want to still stick to only plotly and find alternative, you can see beow
you can use a offline module of plotly to generate static images on the server and use it to generate a PDF. you can import it using from plotly.offline import plot. Once you've imported then you use the plot function as below
fig = go.Figure( data=data, layout=layout )
plot( fig, filename='your-file-name' , image = 'png')
If you are using Plotly you can install kaleido and it will use this instead of orca to generate the static image.
This is good if you can only install your packages through pip.

Question with extracting data from Json using Python

I am building a bot game for my friends in LINE. I'm a beginning coder. I'm trying to call an object in json which includes a string + integer. I've looked around but nothing seems to fit what I need. What would be the best/simple solution?
My code is amateur, please go easy on me. :P
I'm trying to have Python extract through Json, "Name" + "Stat".
Right now it only extracts "Name" and randomly selects an item. Is there any way to select the item + the stat, display the item and calculate the stat? Thanks.
Python 3:
if text == 'FIGHT':
with open('items.json', 'r') as f:
data = json.load(f)
armor1 = [v for d in data['armor'] for k,v in d.items() if k == 'name']
weapon1 = [v for d in data['weapon'] for k,v in d.items() if k == 'name']
magic1 = [v for d in data['magic'] for k,v in d.items() if k == 'name']
armor2 = random.choice(armor1)
weapon2 = random.choice(weapon1)
magic2 = random.choice(magic1)
calc = add(int(armor2), int(weapon2), int(magic2))
line_bot_api.reply_message(
event.reply_token,
TextSendMessage('Armor = ' + (armor2)),
TextSendMessage('Weapon = ' + (weapon2)),
TextSendMessage('Magic = ' + (magic2)),
TextSendMessage('You have a score of ' + str(calc) + '.'),
TextSendMessage('Waiting for next opponent...')
)
Json:
"armor": [
{
"name":"Cardboard armor 10 DEF" ,
"stats":"10" },
{
"name":"Plastic armor 20 DEF" ,
"stats":"20" },
{
"name":"Rubber armor 30 DEF" ,
"stats":"30" },
{
"name":"Metal armor 40 DEF" ,
"stats":"40" },
{
"name":"Indestructable armor 50 DEF" ,
"stats":"50" }
],
After trying just about everything.. The solution was:
if text == 'FIGHT':
with open('items.json', 'r') as f:
data = json.load(f)
armor2 = random.choice(data['armor'])
weapon2 = random.choice(data['weapon'])
magic2 = random.choice(data['magic'])
calc = add(armor2['stats'], weapon2['stats'], magic2['stats'])
line_bot_api.reply_message(
event.reply_token, [
TextSendMessage('Armor = ' + (armor2['name'])),
TextSendMessage('Weapon = ' + (weapon2['name'])),
TextSendMessage('Magic = ' + (magic2['name'])),
TextSendMessage('Total = ' + str(calc) + '.')
]
)
Thanks to everyone and special thanks to my friend Sae who helped me. :)

Python: Get data through Thingspeak

I want to capture the sensor data through thingspeak.
I used the url provided with the api key in the browser:
http://api.thingspeak.com/update?key=MYKEY&field1=25&field2=75
I expect it will return field1 and field2, but the result below shows only the value of field1.
"channel":{
"id":202242,
"name":"DHT11",
"latitude":"0.0",
"longitude":"0.0",
"field1":"Temperature ( degC ) 1",
"field2":"Humidity ( % )",
"created_at":"2016-12-11T17:16:21Z",
"updated_at":"2016-12-11T18:12:00Z",
"last_entry_id":12
},
"feeds":[
{
"created_at":"2016-12-11T18:12:00Z",
"entry_id":12,
"field1":25
}
]
What step have I missed?
Try this approach:
Here you make request using APIs. You will find various API requests here.
import urllib2
import json
import time
READ_API_KEY=' '
CHANNEL_ID= ' '
while True:
TS = urllib2.urlopen("http://api.thingspeak.com/channels/%s/feeds/last.json?api_key=%s" \
% (CHANNEL_ID,READ_API_KEY))
response = TS.read()
data=json.loads(response)
a = data['created_at']
b = data['field1']
c = data['field2']
d = data['field3']
print a + " " + b + " " + c + " " + d
time.sleep(5)
TS.close()

Categories