Writing CSV table to PDF Report - python-3.4

I have a script that pulls data from a .csv file and writes it to a newly-generated PDF using ReportLab. It works fine but the data itself is skewed all over the page when I open the document as it has been written as a string. Is there any way I can write this data from the .csv file to the PDF in the same format as the .csv file (Table Form) so it is organised and readable?
# Script to generate a PDF report after data has been parsed into simInfo.csv file
import csv
import datetime
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
now = datetime.datetime.now()
def import_data(pdf, data_file):
sim_card_info = csv.reader(open(data_file, "r"))
for row in sim_card_info:
_id = row[0]
icc_id = row[1]
sim_id = row[2]
display_name = row[3]
carrier_name = row[4]
number = row[5]
data_roaming = row[6]
mcc = row[7]
mnc = row[8]
pdf_filename = _id + icc_id + sim_id + display_name + carrier_name + number + data_roaming + mcc + mnc + '.pdf'
generate_report(pdf, _id, icc_id, sim_id, display_name, carrier_name, number, data_roaming, mcc, mnc, pdf_filename)
def generate_report(pdf, _id, icc_id, sim_id, display_name, carrier_name, number, data_roaming, mcc, mnc, pdf_filename):
sim_data = "" + _id + icc_id + sim_id + display_name + carrier_name + number + data_roaming + mcc + mnc
pdf.drawString(50, 100, sim_data)
pdf.showPage()
def front_page():
pdf = canvas.Canvas("H:\College Fourth Year\Development Project\Final Year Project 2018\Forensic Reports\Sim Card Report.pdf", pagesize=letter)
pdf.setLineWidth(.3)
pdf.setFont('Helvetica', 12)
pdf.drawString(30, 750, 'LYIT MOBILE FORENSICS DIVISION')
pdf.drawString(500, 750, "Date: " + now.strftime("%d-%m-%y")) # Prints date of the report(on the fly)
pdf.line(500, 747, 595, 747)
pdf.drawString(500, 725, 'Case Number:')
pdf.drawString(580, 725, "10")
pdf.line(500, 723, 595, 723)
line1 = 'This forensic report on sim card data has been compiled by the forensic'
line2 = 'examiner in conclusion to the investigation into the RTA'
line3 = 'case which occurred on the 23/01/2018.'
textObject = pdf.beginText(30, 700)
lines = [line1, line2, line3]
for line in lines:
textObject.textLine(line)
pdf.drawText(textObject)
return pdf
def main():
data_file = 'H:\College Fourth Year\Development Project\Final Year Project 2018\ExtractedEvidence\simCardInfo.csv'
pdf = front_page()
import_data(pdf, data_file)
pdf.save()
print(" Sim Card Forensic Report Generated!")
if __name__ == '__main__':
main()

Related

Obspy Issue: Acceleration Data from GeoNet

I am trying to create ASCII files of acceleration data from various New Zealand earthquakes, code attached below. I was previously able to generate ASCII files of the acceleration data, however, now running the same code I get the message:
UserWarning: The StationXML file has version 1, ObsPy can read versions (1.0, 1.1). Proceed with caution.
And the acceleration files are no longer being written. Please let me know if there is a way to fix this issue.
import os
from obspy import UTCDateTime
from obspy.clients.fdsn import Client as FDSN_Client
from obspy import read_inventory
from obspy.geodetics import kilometers2degrees
client = FDSN_Client("GEONET")
evid="2016p858000"
minrad=kilometers2degrees(0)
maxrad=kilometers2degrees(30)
cat = client.get_events(eventid=evid)
print(cat)
event = cat[0]
origin = event.origins[0]
otime = origin.time
print(otime)
otime = cat[0].origins[0].time
print(otime)
inventory = client.get_stations(latitude=cat[0].origins[0].latitude,
longitude=cat[0].origins[0].longitude,
minradius=minrad,
maxradius=maxrad,
channel="H??",
level="channel",
starttime = otime-60,
endtime = otime+4*60).remove(channel='HNZ')
print(inventory)
from obspy import Stream
st = Stream()
for network in inventory:
for station in network:
try:
st += client.get_waveforms(network.code, station.code, "*", "H??",
otime-60, otime + 4*60, attach_response=True).remove(channel='HNZ')
st_rem1=st.copy()
pre_filt = (0.025, 0.03, 70.0, 80.0)
acc = st_rem1.copy()
acc.remove_response(output='ACC', pre_filt=pre_filt)
print(acc[0])
acc.plot()
acc[0].write('MS_' + evid + '_' + network.code + '_' + station.code + '_' + station[0].code + '.ascii', format='SLIST')
acc[1].write('MS_' + evid + '_' + network.code + '_' + station.code + '_' + station[1].code + '.ascii', format='SLIST')
except:
pass

Accessing config variables in steps file

Containername argument is the one which I am not understanding how to be accessed from configuration file
Test_steps.file
import datetime
from behave import *
import os, json, random, datetime
from Utilities.KafkaConsumer.SupplyChain import Consumer_TransactionReceipts as CTR
from Utilities.KafkaConsumer.SupplyChain import Consumer_EODSnapshot as CES
from Utilities import CosmosDB as Cdb
#given('Delivery receipts are consumed from Kafka topic')
def delivery_receipts_consumption(context):
obj = CTR.TransactionReceipt()
context.message = obj.consume_kafka()
print(context.message)
#then('Calculate the Cost of goods receipted for a SKU and store')
def purchase_volume_validation(context):
location = '6228'
skunumber = '8091776'
today = datetime.date.today()
yesterday = str(today - datetime.timedelta(days=1))
print("Yesterday's date:", yesterday)
cosmosquerydr = "select dr.quantityOfUnits,dr.ownerOnDespatch,dr.packSize from dr where dr.SKUNumber = " + skunumber + " and dr.globalLocationNumber = " + location + " and dr.createdDate like '" + yesterday + "%' "
directreceipts = Cdb.CosmosDB.query_cosmos_db(cosmosquerydr, containername)
directreceipt = [json.loads(d) for d in directreceipts]

How to get a message from a Chat, after using a command and storing that message as a variable (Pyrogram)?

So I am kinda new with Pyrogram and I want to create my own Genshin Bot. After using the command redeem code, I want the message to be taken and stored as variable. so can anyone help me with that
after taking the code as input from user I would be able to use genshin.py api wrapper to redeem code. Just need help with getting message and storing it as variable.
import genshin
import os
from dotenv import load_dotenv
from pyrogram import Client, filters
load_dotenv()
global chatid
chatid = 842544591
global uid
uid = os.getenv("uid")
ltuid = os.getenv("ltuid")
ltoken = os.getenv("ltoken")
cookie_token = os.getenv("cookie_token")
api_id = os.getenv("api_id")
api_hash = os.getenv("api_hash")
bot_token = os.getenv("bot_token")
cookies = {"ltuid": ltuid,
"ltoken": ltoken,
"cookie_token": cookie_token,
"uid": uid}
client = genshin.Client(cookies)
bot = Client(
"Genshin Bot",
api_id=api_id,
api_hash=api_hash,
bot_token=bot_token
)
#bot.on_message(filters.command('start'))
def start_command(bot, message):
message.reply_text(
"Welcome to Genshin Auto Tasks Bot.\nFor Getting Started Use /help command.")
#bot.on_message(filters.command('help'))
def help_command(bot, message):
message.reply_text("This is Bot's Help Section")
#bot.on_message(filters.command('notes'))
async def get_notes(bot, message):
data = await client.get_full_genshin_user(uid)
notes = await client.get_notes(uid)
active_days = (data.stats.days_active)
total_characters = (data.stats.characters)
abyss_total_stars = (data.abyss.previous.total_stars)
resin_count = notes.current_resin
resin_recovery_time = notes.remaining_resin_recovery_time
await message.reply_text("Pranay Asia" + "\n" +
"uid : " + str(uid) + "\n" +
"-----------------------------------------------------------------" + "\n" +
"Resin Count: " + str(resin_count) + "/" + str(notes.max_resin) + "\n" +
"Countdown to next resin recovery: " + str(resin_recovery_time) + "\n" +
"Total No. of Active Days: " + str(active_days) + "\n" +
"Total No. of Characters: " + str(total_characters) + "\n" +
"Total Stars in Abyss: " + str(abyss_total_stars)
)
#bot.on_message(filters.command('redeemcode'))
def redeem_code(bot, message):
message.reply_text("Send the Code to Redeem")
bot.run()
try message.text
I use it as a userbot but nothing changes so much. This piece of code saves the sent message to a variable and filters out the command itself. For a bot it will be easier: answer = message.text
#app.on_message(filters.command("ns", prefixes=".") & filters.text)
async def EXAMPLE(_,msg):
orig_text = msg.text.split(".ns ", maxsplit=1)[1]
text = orig_text

I want to populate a ttk.combobox with results from database query

i am having a little problem i would need help with.This concerns python ttk.combobox widget
I am new to python just started coding a week ago.
I have a database which is populated by user input.This database is to store a user's stock input(e.g. items, cost, supplier ,etc).This part i have been able to do.
From the database, am using a 'for' loop to get each seperate item from my database query into a ttk.combobox so a user can make selections.
However my problem is,i get an error everytime.
I want the combobox to show all items within my item column from my database query.
From online sources ,i found out an example for ttk.combobox:
list = ['shoe', 'toy', 'bag']
combobox = ttk.Combobox(root)
combobox['values'] = list
This works fine,if i am to use a self-made list
However , i can't find an example for a ttk.combobox using query from sqlite3 in python
Thank you in advance for helping me out with this problem.
An example of how to do it and an explanation of what i did wrong will help me alot.
Forgive me for my poorly organised coding style,i hope to get better at it as time goes on.
from tkinter import *
from tkinter import ttk
import sqlite3
class Example:
def __init__(self,master):
self.master = master
self.win_label = Label(master, text="New Stock Entry")
self.win_label.grid(row=0, columnspan=2,)
self.item_label = Label(master, text="Item Name", fg='black')
self.item_label.grid(row=1, column=0, sticky=W, padx=5, pady=5)
self.unitprice_lab = Label(master, text="Unit Price", fg='black')
self.unitprice_lab.grid(row=2, column=0, sticky=W, padx=5, pady=5)
self.total_price = Label(master, text="Total Price", fg='black')
self.total_price.grid(row=3, column=0, sticky=W, padx=5, pady=5)
self.quantity_lab = Label(master, text="Quantity", fg='black')
self.quantity_lab.grid(row=4, column=0, sticky=W, padx=5, pady=5)
self.manufacturer_lab = Label(master,text="Manufacturer", fg='black')
self.manufacturer_lab.grid(row=5, column=0, sticky=W, padx=5, pady=5)
############### Variables to store input ################
self.item = StringVar()
self.unitp = IntVar()
self.unitn = IntVar()
self.quantity = IntVar()
self.man = StringVar()
############ Widgets############
self.item_entry = Entry(master, width=25,textvariable=self.item)
self.item_entry.grid(row=1, column=1, padx=5, pady=5)
self.unitprice_entry = Entry(master, width=25,textvariable=self.unitp)
self.unitprice_entry.grid(row=2, column=1, sticky=W, padx=5, pady=5)
self.total_price_entry = Entry(master,width=25,textvariable=self.unitn)
self.total_price_entry.grid(row=3, column=1, sticky=W, padx=5, pady=5)
self.quantity_entry = Entry(master,width=25,textvariable=self.quantity)
self.quantity_entry.grid(row=4, column=1, sticky=W, padx=5, pady=5)
self.manufacturer_entry = Entry(master, width=25,textvariable=self.man)
self.manufacturer_entry.grid(row=5, column=1, sticky=W, padx=5, pady=5)
# button for save
self.button_save = Button(master,text="Save",command= self.insert_Dbs)
self.button_save.grid(row=6, column=1, pady=15, padx=10, sticky=W)
def second_window(self): # Second Window to allow user selection
t = Toplevel()
t.geometry('350x290')
t.title('Student Input')
############# widgets ###############
self.label1 = ttk.Label(t, text = 'Student Name')
self.label1.grid(row =0 , column =0)
self.label2 = ttk.Label(t, text='Item Collected')
self.label2.grid(row=0, column=1)
self.label3 = ttk.Label(t, text='Quantity')
self.label3.grid(row=0, column=2)
self.entry1 =ttk.Entry(t, width = 20)
self.entry1.grid(row =1 , column =0)
self.entry2 = ttk.Entry(t, width=20)
self.entry2.grid(row=1, column=2)
self.comb = ttk.Combobox(t,width = 15).grid(row =1 , column =1)
self.comb['value'] = self.combo_input
def insert_Dbs(self): # Function to insert input into database
self.a1 = self.item.get()
self.a2 = self.unitp.get()
self.a3 = self.unitn.get()
self.a4 = self.quantity.get()
self.a5 = self.man.get()
#db = sqlite3.connect('stockdbExample.db')
'''db.execute('create table stocks (item text '
', item_uprice integer,'
' item_nprice integer,'
' quantity integer,'
' manufacturer text )')'''
db = sqlite3.connect('stockdbExample.db')
db.execute('insert into stocks (item,'
' item_uprice,'
' item_nprice,'
' quantity,'
' manufacturer) values (?, ?, ?, ?,?)',
(self.a1, self.a2, self.a3, self.a4, self.a5))
db.commit()
self.combo_input()
self.second_window()
def combo_input(self):
db = sqlite3.connect('stockdbExample.db')
cursor = db.execute('select item from stocks')
for row in cursor.fetchall():
return row
root = Tk()
c = Example(root)
root.mainloop()
First: you forgot () to execute function
self.comb['value'] = self.combo_input()
Second: inside combo_input you use return row so you return only first row, nothing more.
You have to create Python list with all values and then return it.
It can be something like this:
def combo_input(self):
db = sqlite3.connect('stockdbExample.db')
cursor = db.execute('select item from stocks')
result = []
for row in cursor.fetchall():
result.append(row[0])
return result
EDIT: Full, working example:
import tkinter as tk
import tkinter.ttk as ttk
import sqlite3
class Example:
def __init__(self,master):
self.master = master
self.db = sqlite3.connect('stockdbExample.db')
# use only once
self.create_db()
self.cb = ttk.Combobox(master)
self.cb.pack()
self.cb['values'] = self.combo_input()
def combo_input(self):
cursor = self.db.cursor()
cursor.execute('SELECT item FROM stocks')
data = []
for row in cursor.fetchall():
data.append(row[0])
return data
def create_db(self):
cursor = self.db.cursor()
cursor.execute('CREATE TABLE stocks (item text)')
cursor.execute('INSERT INTO stocks (item) VALUES("Hello")')
cursor.execute('INSERT INTO stocks (item) VALUES("World")')
cursor.execute('INSERT INTO stocks (item) VALUES("Tkinter")')
cursor.close()
self.db.commit()
root = tk.Tk()
Example(root)
root.mainloop()

UK Postcode to Census Data using the API

Using the Office for National Statistics website I can get a census summary for a UK postcode.
https://neighbourhood.statistics.gov.uk/dissemination/
I expected that I should be able to do the same thing using the API.
https://neighbourhood.statistics.gov.uk/HTMLDocs/downloads/QuickStart-Guide-V2.1.pdf
But it isn't clear to me how to get from the postcode to the neighbourhood (or Lower Layer Super Output Area as the Office for National Statistics calls them). It seems that I need to use the Delivery endpoint like this.
http://neighbourhood.statistics.gov.uk/NDE2/Deli/getChildAreaTables?ParentAreaId=276980&LevelTypeId=141&Datasets=67
But how do I find out which parameters to use for a specific postcode?
It looks like three calls are required to get a dataset.
import xml.etree.ElementTree as ElementTree
import json
import requests
API_KEY = "YOUR_API_KEY"
def get_area_id(level_type, postcode):
""" Get the area id for the pos
:param level_type: The resolution you are interested in. 14 = ward level data.
:param postcode: A UK postcode
:return: string area identifier
"""
base_url = "http://neighbourhood.statistics.gov.uk/NDE2/Disco/FindAreas"
payload = {'HierarchyId': '27', 'Postcode': postcode}
response = requests.get(base_url, params=payload)
xml = ElementTree.fromstring(response.content)
namespaces = {'ns1': 'http://neighbourhood.statistics.gov.uk/nde/v1-0/discoverystructs'}
xpath_for_area = './/ns1:Area'
areas = xml.findall(xpath_for_area, namespaces)
ward_area_id = ''
for area in areas:
level_type_id = area.find('ns1:LevelTypeId', namespaces).text
if level_type_id == str(level_type): # find the Ward (=14)
ward_area_id = area.find('ns1:AreaId', namespaces).text
return ward_area_id
def get_ext_code(area_id):
""" Get the ext code (whatever that is) from an area id
:param area_id: the area id for a postcode
:return: the ext code for an area (I think is the GSS code)
"""
base_url = "http://neighbourhood.statistics.gov.uk/NDE2/Disco/GetAreaDetail"
payload = {'AreaId': area_id}
response = requests.get(base_url, params=payload)
xml = ElementTree.fromstring(response.content)
namespaces = {'ns1': 'http://neighbourhood.statistics.gov.uk/nde/v1-0/discoverystructs',
'structure': 'http://www.SDMX.org/resources/SDMXML/schemas/v2_0/structure'}
xpath_for_ext_code = './/ns1:ExtCode'
ext_code = xml.find(xpath_for_ext_code, namespaces).text
return ext_code
def get_data(data_set, geog_code):
""" Get the data for a geographical code
:param data_set: string identifier from http://www.nomisweb.co.uk/census/2011 /quick_statistics
:param geog_code: the ext code for the geographical area
:return: a json object with the data
"""
base_url = "http://data.ons.gov.uk/ons/api/data/dataset/"
payload = {'apikey': API_KEY, 'context': 'Census', 'geog': '2011WARDH', 'dm/2011WARDH': geog_code,
'totals': 'false', 'jsontype': 'json-stat'}
r = requests.get(base_url + "/" + data_set + ".json", params=payload)
obj = json.loads(r.text)
return obj
def process(json_object, data_set):
data = {}
values = json_object[data_set]['value']
index = json_object[data_set]['dimension'][json_object[data_set]['dimension']['id'][1]]['category']['index']
labels = json_object[data_set]['dimension'][json_object[data_set]['dimension']['id'][1]]['category']['label']
for l in labels:
num = index[l]
count = values[str(num)]
data[labels[l]] = count
return data
area_id = get_area_id(14, "SW1A 0AA")
gss_code = get_ext_code(area_id)
data_returned = get_data("QS208EW", gss_code) # QS208EW = religion
print(process(data_returned, "QS208EW"))
Have you tried looking at the code in the VBA example?
Function RunAreas()
Dim txtResponse
Dim postcode As String
Dim extCode
Set rootSheet = GetSheet("Query")
Set areaSheet = GetSheet("Areas")
endPoint = "http://neighbourhood.statistics.gov.uk/NDE2/Disco/FindAreas?HierarchyId=27&Postcode="
postcode = rootSheet.Range("A2").Value
Application.StatusBar = "Getting areas for " + postcode
txtResponse = GetAreas(postcode)
delim = "<delim>"
data = GetElements(txtResponse, "Area")
If UBound(data) < 0 Then
Application.StatusBar = False
MsgBox "Postcode " + postcode + " not found", vbExclamation
Exit Function
End If
For i = 0 To UBound(data)
curLevelType = GetValue(data(i), "LevelTypeId")
curHierarchy = GetValue(data(i), "HierarchyId")
curId = GetValue(data(i), "AreaId")
curName = GetValue(data(i), "Name")
Select Case curLevelType
Case 15
extCode = UpdateArea("Output Area", 2, curId, curName, curHierarchy)
Case 14
extCode = UpdateArea("Ward", 3, curId, curName, curHierarchy)
Case 13
extCode = UpdateArea("LA", 4, curId, curName, curHierarchy)
Case 11
extCode = UpdateArea("Region", 5, curId, curName, curHierarchy)
Case 10
extCode = UpdateArea("Country", 6, curId, curName, curHierarchy)
End Select
Next
MsgBox ("Areas Found")
Application.StatusBar = "Get Areas completed"
End Function

Resources