I can't get the accurate numbers on the web table - python

import requests
import bs4
from tkinter import *
def statno():
covidTk = Tk()
covidTk.title('Data statistics of COVID-19')
web = requests.get('https://www.worldometers.info/coronavirus')
objSoup = bs4.BeautifulSoup(web.text,'lxml')
lb1 = Label(covidTk,text='Country: ')
lb1.grid(row=1,column=0,padx=10,pady=10)
lb2 = Label(covidTk,text=entcon.get())
lb2.grid(row=1,column=1,padx=10,pady=10)
table = objSoup.find('table',attrs={'id':'main_table_countries_today'})
headings = [th.get_text() for th in table.find('tr').find_all('th')]
set_of_datas = []
for row in table.find_all('tr')[1:]:
data = dict(zip(headings,(td.get_text() for td in row.find_all('td'))))
set_of_datas.append(data)
print(set_of_datas)
win = Tk()
win.title('COVID-19 tracker')
web = requests.get('https://www.worldometers.info/coronavirus')
objSoup = bs4.BeautifulSoup(web.text,'lxml')
lbtitle = Label(win,text='Covid-19 Statistics')
lbtitle.grid(row=0,columnspan=2)
lbcon = Label(win,text='Country: ')
lbcon.grid(row=1,column=0,padx=10,pady=20)
conname = StringVar()
entcon = Entry(win,textvariable=conname)
entcon.grid(row=1,column=1,padx=10,pady=20)
btncheck = Button(win,text='Check data',command=statno)
btncheck.grid(row=2,column=1,padx=10,pady=10)
lbcase = Label(win,text='Coronavirus Cases: ')
lbcase.grid(row=3,column=0)
total = objSoup.find_all('div',{'class':'maincounter-number'})
total_cases = total[0]
lbdat1 = Label(win,text=total_cases.text)
lbdat1.grid(row=3,column=1)
lbdeaths = Label(win,text='Deaths: ')
lbdeaths.grid(row=4,column=0)
total_deaths = total[1]
lbdat2 = Label(win,text=total_deaths.text)
lbdat2.grid(row=4,column=1)
lbcase = Label(win,text='Recovered: ')
lbcase.grid(row=5,column=0)
total_recover = total[2]
lbdat3 = Label(win,text=total_recover.text)
lbdat3.grid(row=5,column=1)
When I print(set_of_datas) the values come out are not encoded well. Any methods to make the value appear without garbled strings? I may want to ask do I need to use intersecting of rows and columns? How to refer the data by using the table of the country with the number statistics together? Because I do not know how to get the corresponding datas if I type the country name and clicked the button. Can any people teach me the method to refer data in the table?

Related

Why openpyxl is hidding some rows?

I'm having a little trouble with openpyxl. I'm updating an excel with historic data something like this:
The excel has 2 sheets with this data, both are almost the same. The thing is that after I add the new rows and aply the formats, in the second sheet for some reason a lot of row are hidden, like this:
This is my code:
from copy import copy
import pandas as pd
from openpyxl import load_workbook
datos = pd.Dataframe(my_data) # This is not right but I already have the data in a DF
today = datos[col1].loc[0].strftime("%Y-%m-%d")
tomorrow = datos[col1].loc[1].strftime("%Y-%m-%d")
historic = 'my_excel.xlsx'
logger.info('Reading Excel')
wb = load_workbook(historic)
sheets = wb.sheetnames
for sheet in sheets:
logger.warning(f'************* {sheet} *************')
ws = wb[sheet]
logger.info(f'active: {wb.active}')
logger.info(f"len D: {len(ws['D'])}")
logger.info(f"len E: {len(ws['E'])}")
max_row = len(ws['D'])
logger.info('Last D cell')
last_D_cell = ws.cell(row=max_row, column=4)
last_D_cell_value = last_D_cell.value.strftime("%d/%m/%Y")
logger.info('New Cell')
new_D_cell = ws.cell(row=max_row + 1, column=4)
new_D_cell.font = copy(last_D_cell.font)
new_D_cell.border = copy(last_D_cell.border)
new_D_cell.number_format = copy(last_D_cell.number_format)
new_D_cell.alignment = copy(last_D_cell.alignment)
new_D_cell.fill = copy(last_D_cell.fill)
new_D_cell.value = datos[col1].loc[1].strftime("%d/%m/%Y")
logger.info('Penultimate D Cell')
penultimate_D_cell = ws.cell(row=max_row - 1, column=4)
last_D_cell.font = copy(penultimate_D_cell.font)
last_D_cell.border = copy(penultimate_D_cell.border)
last_D_cell.number_format = copy(penultimate_D_cell.number_format)
last_D_cell.alignment = copy(penultimate_D_cell.alignment)
last_D_cell.fill = copy(penultimate_D_cell.fill)
logger.info('Last E Cell')
last_E_cell = ws[f'E{max_row}']
new_E_cell = ws.cell(row=max_row + 1, column=5)
new_E_cell.font = copy(last_E_cell.font)
new_E_cell.border = copy(last_E_cell.border)
new_E_cell.number_format = copy(last_E_cell.number_format)
new_E_cell.alignment = copy(last_E_cell.alignment)
new_E_cell.fill = copy(last_E_cell.fill)
new_E_cell.value = tomorrow_value
logger.info('Penultimate E')
penultimate_E_cell = ws[f'E{max_row - 1}']
last_E_cell.font = copy(penultimate_E_cell.font)
last_E_cell.border = copy(penultimate_E_cell.border)
last_E_cell.number_format = copy(penultimate_E_cell.number_format)
last_E_cell.alignment = copy(penultimate_E_cell.alignment)
last_E_cell.fill = copy(penultimate_E_cell.fill)
logger.info('SAving Excel')
wb.save(historic)
With this code, the last sheet it works will have the hidden rows, and I don't know why is this happening.
Hope someone can help me thanks
EDIT: I'm on Ubuntu 20.4 LTS, and the resulting files has been opened in both Ubuntu and Windows 10 and the same situation appears.

Is there a proper way to append JSON Data to a Numpy array

I am trying to add data that I am reading from a series of JSON files to a Numpy array (or whatever data collection would work best). My idea, is that I want to sort a collection of episodes of a tv show by episode title.
The problem I have encountered, is actually creating the collection from the data.
The intent, is that I want to be able to have a collection of the items found within the for loop [a,b,c,d]; for each episode of the show.
Is a Numpy array the best way to go about making this collection, or should I use something else?
season1 = open('THEJSONFILES\seasonone.json', 'r')
season_array = np.array(['episodeTitle','seasonNum', 'episodeNum', 'plotContents'])
def ReadTheDarnJsonFile(jsonTitle):
seasondata = jsonTitle.read()
seasonobj = j.loads(seasondata)
list = (seasonobj['episodes'])
for i in range(len(list)):
a = str(list[i].get('title'))
b = str(list[i].get('seasonNumber'))
c = str(list[i].get('episodeNumber'))
d = str(list[i].get('plot'))
print(a, b, c, d)
print("----------------")
# np.append(season_array, [a,b,c,d]) this is not correct
ReadTheDarnJsonFile(season1)
print(season_array)
2 notes. First I would avoid using list as a variable name because it is a keyword in python. Second I would recommend using a custom class for your data for maximum readability.
season1 = open('THEJSONFILES\seasonone.json', 'r')
season_array = np.array(['episodeTitle','seasonNum', 'episodeNum', 'plotContents'])
class episode:
def __init__(self,title,seasonNumber,episodeNumber,plot):
self.title = title
self.seasonNumber = seasonNumber
self.episodeNumber = episodeNumber
self.plot = plot
def summary(self):
print("Season "+str(self.seasonNumber)+" Episode "+str(self.episodeNumber))
print(self.title)
print(self.plot)
def ReadTheDarnJsonFile(jsonTitle):
seasondata = jsonTitle.read()
seasonobj = j.loads(seasondata)
episodes = (seasonobj['episodes'])
season_array = []
for i in range(len(episodes)):
a = str(list[i].get('title'))
b = str(list[i].get('seasonNumber'))
c = str(list[i].get('episodeNumber'))
d = str(list[i].get('plot'))
season_array.append(episode(a,b,c,d)) this is not correct
return season_array
season_array = Read
TheDarnJsonFile(season1)
for item in season_array:
item.summary()
Here is what I ended up doing.
import json as j
import pandas as pd
emptyArray = []
season1 = open('THEJSONFILES\seasonone.json', 'r')
season2 = open('THEJSONFILES\seasontwo.json', 'r')
season3 = open('THEJSONFILES\seasonthree.json', 'r')
season4 = open('THEJSONFILES\seasonfour.json', 'r')
season5 = open('THEJSONFILES\seasonfive.json', 'r')
season6 = open('THEJSONFILES\seasonsix.json', 'r')
season7 = open('THEJSONFILES\seasonseven.json', 'r')
columnData = ["episodeTitle", "seasonIndex", "episodeIndex", "plot", "imageURL"]
finalDf = pd.DataFrame
def ReadTheDarnJsonFile(jsonTitle):
df = pd.DataFrame(columns = columnData)
seasonData = jsonTitle.read()
seasonObj = j.loads(seasonData)
currentSeasonList = (seasonObj['episodes'])
for i in range(len(currentSeasonList)):
tempTitle = str(currentSeasonList[i].get('title'))
tempSN = str(currentSeasonList[i].get('seasonNumber'))
tempEN = str(currentSeasonList[i].get('episodeNumber'))
tempPlot = str(currentSeasonList[i].get('plot'))
tempImage = str(currentSeasonList[i].get('image'))
dataObj = pd.Series([tempTitle, tempSN, tempEN, tempPlot, tempImage], index=(df.columns))
df.loc[i] = dataObj
emptyArray.append(df)
ReadTheDarnJsonFile(season1)
ReadTheDarnJsonFile(season2)
ReadTheDarnJsonFile(season3)
ReadTheDarnJsonFile(season4)
ReadTheDarnJsonFile(season5)
ReadTheDarnJsonFile(season6)
ReadTheDarnJsonFile(season7)
finalDf = pd.concat(emptyArray)
print(emptyArray)
holyOutput = finalDf.sort_values(by=['episodeTitle'])
holyOutput.reset_index(inplace=True)
holyOutput.to_json("P:\\ProjectForStarWarsCloneWarsJson\JSON\OutputJsonV2.json")

Pandas Dataframe Only Returning first Row of JSON Data

I'm working on a web scraping project, and have all the right code that returns me the json data in the format that I want if I used the #print command below, but when I got to run the same code except through Pandas Dataframe it only returns the first row of Data that I'm looking for. Just running the print, it returns the expected 17 rows of data I'm looking for. Dataframe to CSV gives me the first row only. Totally stumped! So grateful for anyone's help!
for item in response['body']:
DepartureDate = item['legs'][0][0]['departDate']
ReturnDate = item['legs'][1][0]['departDate']
Airline = item['legs'][0][0]['airline']['code']
Origin = item['legs'][0][0]['depart']
Destination = item['legs'][0][0]['destination']
OD = (Origin + Destination)
TrueBaseFare = item['breakdown']['baseFareAmount']
YQYR = item['breakdown']['fuelSurcharge']
TAX = item['breakdown']['totalTax']
TTL = item['breakdown']['totalFareAmount']
MARKEDUPTTL = item['breakdown']['totalCalculatedFareAmount']
MARKUP = ((MARKEDUPTTL - TTL) / (TTL)*100)
FBC = item['fareBasisCode']
#print(DepartureDate,ReturnDate,Airline,OD,TrueBaseFare,YQYR,TAX,TTL,MARKEDUPTTL,MARKUP,FBC)
MI = pd.DataFrame(
{'Dept': [DepartureDate],
'Ret': [ReturnDate],
'AirlineCode': [Airline],
'Routing': [OD],
'RealFare': [TrueBaseFare],
'Fuel': [YQYR],
'Taxes': [TAX],
'RealTotal': [TTL],
'AgencyTotal': [MARKEDUPTTL],
'Margin': [MARKUP],
'FareBasis': [FBC],
})
df = pd.DataFrame(MI)
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)
pd.set_option('display.width', None)
df.to_csv('MITest7.csv')
When you print all your values after the cycle, you will see that you get only the last values. To resolve this problem you need to create lists and put there your values.
Try this:
DepartureDate = []
ReturnDate = []
Airline = []
Origin = []
Destination = []
OD = []
TrueBaseFare = []
YQYR = []
TAX = []
TTL = []
MARKEDUPTTL = []
MARKUP = []
FBC = []
for item in response['body']:
DepartureDate.append(item['legs'][0][0]['departDate'])
ReturnDate.append(item['legs'][1][0]['departDate'])
Airline.append(item['legs'][0][0]['airline']['code'])
Origin.append(item['legs'][0][0]['depart'])
Destination.append(item['legs'][0][0]['destination'])
OD.append((Origin[-1] + Destination[-1]))
TrueBaseFare.append(item['breakdown']['baseFareAmount'])
YQYR.append(item['breakdown']['fuelSurcharge'])
TAX.append(item['breakdown']['totalTax'])
TTL.append(item['breakdown']['totalFareAmount'])
MARKEDUPTTL.append(item['breakdown']['totalCalculatedFareAmount'])
MARKUP.append(((MARKEDUPTTL[-1] - TTL[-1]) / (TTL[-1])*100))
FBC.append(item['fareBasisCode'])

Is there anyway to style <td> elements based on a conditional using PrettyTable

Here is the code:
from prettytable import PrettyTable
import requests
def market_table():
api = "https://api.coinmarketcap.com/v2/ticker/"
raw_data = requests.get(api).json()
data = raw_data['data']
table = PrettyTable()
for currency in data:
name = data[currency]['name']
market_cap = data[currency]['quotes']['USD']['market_cap']
price = data[currency]['quotes']['USD']['price']
change_1h = data[currency]['quotes']['USD']['percent_change_1h']
change_24h = data[currency]['quotes']['USD']['percent_change_24h']
change_7d = data[currency]['quotes']['USD']['percent_change_7d']
table.add_row([name,market_cap,price,change_1h,change_24h,change_7d])
table.field_names = ["Name","Market Cap","Price","Change 1h","Change 24h","Change 7d"]
table.sortby = "Market Cap"
table.reversesort = True
market_table = table.get_html_string()
return market_table
What I want to do is style the change_1h,change_24h, and change_7d to color red if change<0, and color green if change>0. Is this possible using PrettyTable?
Color modifications are not possible with PrettyPrint but you can apply your own postprocessing:
import re
import requests
from prettytable import PrettyTable
def market_table():
changes = []
data = requests.get('https://api.coinmarketcap.com/v2/ticker').json()['data']
table = PrettyTable(['Name', 'Market Cap', 'Price', 'Change 1h', 'Change 24h', 'Change 7d'], sortby='Market Cap', reversesort=True)
for currency in data:
change_1h = data[currency]['quotes']['USD']['percent_change_1h']
change_24h = data[currency]['quotes']['USD']['percent_change_24h']
change_7d = data[currency]['quotes']['USD']['percent_change_7d']
changes.extend([change_1h, change_24h, change_7d])
table.add_row([data[currency]['name'], data[currency]['quotes']['USD']['market_cap'],
data[currency]['quotes']['USD']['price'], change_1h, change_24h, change_7d])
html = table.get_html_string()
for change in changes:
color = '#00FF00' if change > 0 else '#FF0000'
html = re.sub('<td>{}</td>'.format(change), '<td bgcolor="{}">{}</td>'.format(color, change), html)
return html
This is what you'll get:

Python sqlite3, tkinter display multible rows

I am new to python and recently i make dictionary using Python and Sqlite3 with tkinter.
When I run the code it returns multiple line in IDLE but in the GUI its only display the last result. I would like to display all the information in the GUI. Thanks you for any help and suggestion.
import tkinter
import sqlite3
class Dictionary:
def __init__(self,master =None):
self.main_window = tkinter.Tk()
self.main_window.title("Lai Mirang Dictionary")
self.main_window.minsize( 600,400)
self.main_window.configure(background = 'paleturquoise')
self.frame1 = tkinter.Frame()
self.frame2= tkinter.Frame(bg = 'red')
self.frame3 =tkinter.Text( foreground = 'green')
self.frame4 = tkinter.Text()
self.lai_label = tkinter.Label(self.frame1,anchor ='nw',font = 'Times:12', text = 'Lai',width =25,borderwidth ='3',fg='blue')
self.mirang_label = tkinter.Label(self.frame1,anchor ='ne',font = 'Times:12', text = 'Mirang',borderwidth ='3',fg ='blue')
self.lai_label.pack(side='left')
self.mirang_label.pack(side = 'left')
self.kawl_buttom= tkinter.Button(self.frame2 ,fg = 'red',font = 'Times:12',text ='Kawl',command=self.dic,borderwidth ='3',)
self.lai_entry = tkinter.Entry(self.frame2, width= 28, borderwidth ='3',)
self.lai_entry.focus_force()
self.lai_entry.bind('<Return>', self.dic,)
self.lai_entry.configure(background = 'khaki')
self.lai_entry.pack(side='left')
self.kawl_buttom.pack(side = 'left')
self.value = tkinter.StringVar()
self.mirang_label= tkinter.Label(self.frame3,font = 'Times:12',fg = 'blue',textvariable = self.value,justify = 'left',wraplength ='260',width = 30, height = 15,anchor = 'nw')
self.mirang_label.pack()
self.mirang_label.configure(background = 'seashell')
self.copyright_label = tkinter.Label(self.frame4,anchor ='nw',font = 'Times:12:bold',text = "copyright # cchristoe#gmail.com",width = 30,borderwidth = 3, fg = 'purple',)
self.copyright_label.pack()
self.frame1.pack()
self.frame2.pack()
self.frame3.pack()
self.frame4.pack()
tkinter.mainloop()
self.main_window.quit()
def dic(self, event = None):
conn = sqlite3.connect('C:/users/christoe/documents/sqlite/laimirangdictionary.sqlite')
c = conn.cursor()
kawl = self.lai_entry.get()
kawl = kawl + '%'
c.execute("SELECT * FROM laimirang WHERE lai LIKE ?", (kawl,))
c.fetchall
for member in c:
out = (member)
self.value.set(out)
print(out, )
dic=Dictionary()
You need to change:
c.execute("SELECT * FROM laimirang WHERE lai LIKE ?", (kawl,))
c.fetchall
for member in c:
out = (member)
self.value.set(out)
print(out, )
To:
for member in c.execute("SELECT * FROM laimirang WHERE lai LIKE ?", (kawl,)):
current_text = self.value.get()
new_text = current_text +( "\n" if current_text else "") +" ".join(member)
self.value.set(new_text)
The new version gets the current value of the StringVar value and then appends the results returned with a space inbetween for each row returned with each row on its own line. What you were doing however involved just updating the StringVar to be the current member object, and therefore it only ever had the last values.
This is how it looks with more than one line:

Categories

Resources