#================================== SHOW DATA In Treeview ======================
def fetch_all(self):
locale.setlocale(locale.LC_ALL, 'fr_FR')
A=self.Aff_var.get()
con=pymysql.connect(host='localhost',user='root',password='',database='achat_mp')
cur=con.cursor()
cur.execute ('select * from %s' % A)
rows=cur.fetchall()
if len (rows) !=0:
self.achat_mp.delete(* self.achat_mp.get_children())
for row in rows :
self.achat_mp.insert("",END,value=row)
I tried to use locale to show thousands separator but it didn't work
Related
Problem statement:
I have 2 columns on streamlit: one for ticker_symbol and other for it's current value.
I want to update the current_value every second (column2) but the code I have so far first removes the written value of the current_price and then writes the new value. I would like the current_value to be overwritten without being removed at all. This also means the last ticker_symbol in the col has to wait for a long time to show it's current value since the previous value gets removed by st.empty.
What can I do to achieve the goal mentioned above?
Should I not use st.empty ? Are there any other alternatives in streamlit ?
import time
import yfinance as yf
import streamlit as st
st.set_page_config(page_title="Test", layout='wide')
stock_list = ['NVDA', 'AAPL', 'MSFT']
left, right, blank_col1, blank_col2, blank_col3, blank_col4, blank_col5, blank_col6, blank_col7, blank_col8, blank_col9, \
blank_col10 = st.columns(12, gap='small')
with left:
for index, val in enumerate(stock_list):
st.write(val)
with right:
while True:
numbers = st.empty()
with numbers.container():
for index, val in enumerate(stock_list):
stock = yf.Ticker(val)
price = stock.info['regularMarketPrice']
# st.write(": ", price)
st.write(": ", price)
time.sleep(0.5)
numbers.empty()
Do like this.
with right:
# The number holder.
numbers = st.empty()
# The infinite loop prevents number holder from being emptied.
while True:
with numbers.container():
for index, val in enumerate(stock_list):
stock = yf.Ticker(val)
price = stock.info['regularMarketPrice']
st.write(": ", price)
time.sleep(0.5)
Sample simulation code with random.
import time
import streamlit as st
import random
st.set_page_config(page_title="Test", layout='wide')
stock_list = ['NVDA', 'AAPL', 'MSFT']
(left, right, blank_col1, blank_col2, blank_col3, blank_col4,
blank_col5, blank_col6, blank_col7, blank_col8, blank_col9,
blank_col10) = st.columns(12, gap='small')
with left:
for index, val in enumerate(stock_list):
st.write(val)
with right:
numbers = st.empty()
while True:
with numbers.container():
for index, val in enumerate(stock_list):
price = random.randint(-100, 100)
st.write(": ", price)
time.sleep(0.5)
So I have this csv data
Medium narrow body, £8, 2650, 180, 8
Large narrow body, £7, 5600, 220, 10
Medium wide body, £5, 4050, 406, 14
The data I need to use are the numbers all the way on the right which have been given a fieldname 'first_class' and second from right given field name 'Capacity'
and I have made this code
import csv
def menu():
print ("""
1.Enter airport details
2.Enter flight details
3.Enter price plan and calculate profit
4. Clear data
5.Quit
""")
if b == '2':
a1 = input('Enter the type of aircraft: ')
airplane_info = open('airplane.csv', 'r')
csvreader = csv.DictReader(airplane_info,delimiter = ',',fieldnames=('Body_type','Running_cost','Max_flight','Capacity','first_class'))
for row in csvreader:
if row['Body_type'] == a1:
print(row)
if row['Body_type'] != a1:
print('Wrong aircraft type')
flag = False
else:
d1 = input('Enter number of first class seats on the aircraft')
if d1 != 0:
(That flag was sending user back to the options menu ignore it)
Now I need to use the aircraft type that the user input and use it's 'first_class' fieldname with the amount of first class seats the user enters. Let's say if the user input an aircraft type 'Medium wide body'. It has 14 first class seats. When the user is asked to enter first class seats and ends up entering lower then 14 an error message should pop up. How would I do it? Would I input the csv data into an array and then use it for the comparison?
Here is a quick example using Pandas library. You will need to install it:
pip install --user pandas
Using pandas you can parse the csv into a dataframe object and then work on it as you desire:
import pandas as pd
df = pd.read_csv('airplane.csv', names=["Body_type", "Running_cost", "Max_flight", "Capacity", "first_class"])
a1 = input('Enter the type of aircraft: ')
if a1 in df.Body_type.values:
body = df[df.Body_type == a1]
d1 = int(input('Enter number of first class seats on the aircraft: '))
if d1 < body["first_class"].values[0]:
print("Error")
# ...
else:
print('Wrong aircraft type')
I fetch column of postgres table and now i want to replace values of column 'B' depending on column 'A' .if it is greater then a certain number then replace value of 'B'... I am trying to write the code but i can not understand how i will execute if statements...I also tried to do this with panda but i can not make a logic there as well. Any help will be appreciated
import psycopg2
import xml.etree.ElementTree as et
connection=psycopg2.connect(user="user",database="db",password="****",host= "localhost")
cursor=connection.cursor()
cursor.execute("select * from mytable")
col_clean=cursor.fetchall()
for row in col_clean:
if "a" == 10 :
'b'.replace(0.000,(9/100))
elif "a" ==20:
'b'.replace(0.000,(22/100))
elif "a" == 30:
'b'.replace(0.000,(70/100))
elif "a" == 40:
'b'.replace(0.000, (80 / 1000))
ELSE
'b.replace(0.000, (100 / 100))
cursor.execute('Insert into mytable("b") VALUES(%s)',%row)
connection.commit()
You should just update the rows in place instead of iterating through them.
import psycopg2
import xml.etree.ElementTree as et
connection=psycopg2.connect(user="user",database="db",password="****",host= "localhost")
cursor=connection.cursor()
cursor.execute("""UPDATE mytable set b =
CASE a
WHEN '10' THEN 0.09
WHEN '20' THEN 0.22
WHEN '30' THEN 0.70
WHEN '40' THEN 0.80
ELSE 1
END""")
connection.commit()
Edit: fixed for "a" being text.
I'm trying to use a slider with a callback in Bokeh using Python 3 to filter the rows of my ColumnDataSource objects (which originate from a DataFrame). More specifically, if a slider with options of 0 to 10000000 (in multiples of 1 million) returns a value N of say 2000000, then I want my plot to only show the data for, in this case, US counties where the population is >= 2000000. Below is my code. Everything works as I want it to except for the slider callback.
from bokeh.io import curdoc
from bokeh.layouts import layout
from bokeh.models import HoverTool, ColumnDataSource, Select, Slider
from bokeh.plotting import figure
TOOLS='pan,wheel_zoom,box_zoom,reset,tap,save,box_select,lasso_select'
source1 = ColumnDataSource(df[df.winner == 'Democratic'])
source2 = ColumnDataSource(df[df.winner == 'Republican'])
hover = HoverTool(
tooltips = [
('County Name', '#county'),
('Population', '#population'),
('Land Area', '#land_area'),
('Pop. Density', '#density'),
('Winning Party', '#winner'),
('Winning Vote %', '#winning_vote_pct'),
]
)
# Plot
plot = figure(plot_width=800, plot_height=450, tools=[hover, TOOLS],
title='2016 US Presidential Vote % vs. Population Density (by County)',
x_axis_label='Vote %', y_axis_label='Population Density (K / sq. mi.)')
y = 'density'
size = 'bokeh_size'
alpha = 0.5
c1 = plot.circle(x='pct_d', y=y, size=size, alpha=alpha, color='blue',
legend='Democratic-Won County', source=source1)
c2 = plot.circle(x='pct_r', y=y, size=size, alpha=alpha, color='red',
legend='Republican-Won County', source=source2)
plot.legend.location = 'top_left'
# Select widget
party_options = ['Show both parties', 'Democratic-won only', 'Republican-won only']
menu = Select(options=party_options, value='Show both parties')
# Slider widget
N = 2000000
slider = Slider(start=0, end=10000000, step=1000000, value=N, title='Population Cutoff')
# Select callback
def select_callback(attr, old, new):
if menu.value == 'Democratic-won only': c1.visible=True; c2.visible=False
elif menu.value == 'Republican-won only': c1.visible=False; c2.visible=True
elif menu.value == 'Show both parties': c1.visible=True; c2.visible=True
menu.on_change('value', select_callback)
# Slider callback
def slider_callback(attr, old, new):
N = slider.value
# NEED HELP HERE...
source1 = ColumnDataSource(df.loc[(df.winner == 'Democratic') & (df.population >= N)])
source2 = ColumnDataSource(df.loc[(df.winner == 'Republican') & (df.population >= N)])
slider.on_change('value', slider_callback)
# Arrange plots and widgets in layouts
layout = layout([menu, slider],
[plot])
curdoc().add_root(layout)
Here is a solution using CustomJSFilter and CDSView as suggest in the other answer by Alex. It does not directly use the data as supplied in the question, but is rather a general hint how this can be implemented:
from bokeh.layouts import column
from bokeh.models import CustomJS, ColumnDataSource, Slider, CustomJSFilter, CDSView
from bokeh.plotting import Figure, show
import numpy as np
# Create some data to display
x = np.arange(200)
y = np.random.random(size=200)
source = ColumnDataSource(data=dict(x=x, y=y))
plot = Figure(plot_width=400, plot_height=400)
# Create the slider that modifies the filtered indices
# I am just creating one that shows 0 to 100% of the existing data rows
slider = Slider(start=0., end=1., value=1., step=.01, title="Percentage")
# This callback is crucial, otherwise the filter will not be triggered when the slider changes
callback = CustomJS(args=dict(source=source), code="""
source.change.emit();
""")
slider.js_on_change('value', callback)
# Define the custom filter to return the indices from 0 to the desired percentage of total data rows. You could also compare against values in source.data
js_filter = CustomJSFilter(args=dict(slider=slider, source=source), code=f"""
desiredElementCount = slider.value * 200;
return [...Array(desiredElementCount).keys()];
""")
# Use the filter in a view
view = CDSView(source=source, filters=[js_filter])
plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6, view=view)
layout = column(slider, plot)
show(layout)
I hope this helps anyone who stumbles upon this in the future! Tested in bokeh 1.0.2
A quick solution with minimal change to your code would be:
def slider_callback(attr, old, new):
N = new # this works also with slider.value but new is more explicit
new1 = ColumnDataSource(df.loc[(df.winner == 'Democratic') & (df.population >= N)])
new2 = ColumnDataSource(df.loc[(df.winner == 'Republican') & (df.population >= N)])
source1.data = new1.data
source2.data = new2.data
When updating data sources, you should replace the data, not the whole object. Here I still create new ColumnDataSource as shortcut. A more direct way (but more verbose too) would be to create the dictionary from the filtered df's columns:
new1 = {
'winner': filtered_df.winner.values,
'pct_d': filtered_df.pct_d.values,
...
}
new2 = {...}
source1.data = new1
source2.data = new2
Note that there's another solution which would make the callback local (not server based) by using a CDSView with a CustomJSFilter. You can also write the other callback with a CDSView as well make the plot completely server-independent.
In the following code I have two cursors the first loc_crs should have 3 rows in it. However when I run my program loc_crs seems to only have 1 row
import db_access
def get_average_measurements_for_area(area_id):
"""
Returns the average value of all measurements for all locations in the given area.
Returns None if there are no measurements.
"""
loc_crs = db_access.get_locations_for_area(area_id)
avg = 0
for loc_row in loc_crs:
loc_id = int(loc_row['location_id'])
meas_crs = db_access.get_measurements_for_location(loc_id)
for meas_row in meas_crs:
meas = float(meas_row['value'])
avg += meas
# print("meas: ", str(meas))
print("loc_id: ", str(loc_id))
print(str(avg))
get_average_measurements_for_area(3)
This is my output.
loc_id: 16
avg: 568.2259127787871
EDIT: Here are the methods being called:
def get_locations_for_area(area_id):
"""
Return a list of dictionaries giving the locations for the given area.
"""
cmd = 'select * from location where location_area is ?'
crs.execute(cmd, [area_id])
return crs
def get_measurements_for_location(location_id):
"""
Return a list of dictionaries giving the measurement rows for the given location.
"""
cmd = 'select value from measurement where measurement_location is ?'
crs.execute(cmd, [location_id])
return crs
Here is a link to the database:
http://cs.kennesaw.edu/~bsetzer/4320su15/extra/databases/measurements/measures.sqlite