So I am making a Stream lit web application with python. Here is the link to the app: https://jensen-holm-mlb-simapp-app-kclnz9.streamlitapp.com/
I have already deployed the app but have come across a strange problem. When I booted the app it worked great, running simulations for the two teams that I put into it. But after I do this first run, I put two other teams into it. But the simulation yields the same results from the first two teams. I know this because if i try the download play by polay button, it is always the same players from the first simulation. Very weird problem I did not forsee. Even when run on another persons computer, it still yields the same results as it did for that first test I ran on my computer.
I would really like it to re run everything when you enter two different teams and hit go again. Which I thought happens by default.
Any help is greatly appriciated, below is the main app.py file that I am running in the cloud. Here is a link to the github repo: https://github.com/Jensen-holm/MLB-Simapp
import sqlite3
import streamlit as st
from objects import Team
import game_functions
from streamlit_option_menu import option_menu
import pandas as pd
import numpy as np
def convert_df(df):
return df.to_csv().encode("utf-8")
# title and stuff
st.set_page_config(page_title = 'Ball.Sim (Beta)', page_icon = '⚾️')
st.title('Ball.Sim (Beta)')
st.write('\nCreated by Jensen Holm')
st.write('Data Source: [Sports-Reference](https://sports-reference.com)')
st.write('\n[Donate](https://www.paypal.com/donate/?business=HPLUVQJA6GFMN&no_recurring=0¤cy_code=USD)')
# get rid of streamlit option menu stuff
# hide_streamlit_style = """
# <style>
# #MainMenu {visibility: hidden;}
# footer {visibility: hidden;}
# </style>
# """
# st.markdown(hide_streamlit_style, unsafe_allow_html=True)
# import the player data dict dictionaries for the keys so we can have options in the select box
sim_data_db = sqlite3.connect("Sim_Data.db")
# get list of all table names with the cursor to put into the st.select_box
all_teams_array = np.array(pd.read_sql_query("SELECT name FROM sqlite_master WHERE type='table'", sim_data_db))
# the all teams array is nested so lets unnest it
all_teams_with_year = []
for sublist in all_teams_array:
for thing in sublist:
all_teams_with_year.append(thing)
all_teams = [team[len('Year '):] for team in all_teams_with_year]
all_teams.sort()
all_teams.insert(0, "Start typing and select team")
# user unput buttons and sliders
team1 = st.selectbox(label = "Team 1", options = all_teams)
team2 = st.selectbox(label = "Team 2", options = all_teams)
number_of_simulations = st.slider("Number of Simulations", min_value = 162, max_value = 16200, step = 162)
# initialize simulation button
init_button = st.button("Go")
if init_button:
if team1 == "Start typing and select team" or team2 == "Start typing and select team":
st.error("Must select team from select boxes.")
st.stop()
# select databse tables based on user input
team1_data = pd.read_sql_query(f"SELECT * FROM 'Year {team1}'", con = sim_data_db)
team2_data = pd.read_sql_query(f"SELECT * FROM 'Year {team2}'", con = sim_data_db)
team1_year = team1[:5]
team2_year = team1[:5]
team1_name = team1[5:]
team2_name = team2[5:]
# generate teams with the data queried above
Team1 = Team(team1_name, team1_year, team1_data, lineup_settings = 'auto')
Team2 = Team(team2_name, team2_year, team2_data, lineup_settings = 'auto')
# begin simulation
pbp_df = game_functions.simulation(number_of_simulations, Team1, Team2, 0)
# make it a csv and use st.download_button()
pbp_csv = convert_df(pbp_df)
st.download_button("Download Play By Play Data", pbp_csv, file_name = "BallSimPBP.csv")
# use st.tabs to filter what to see, like a chart tab for the graph, a place where they can view stats per 162 for each player
# and download data and stuff on another one (may need to figure out the st.session state thing tho)
# footer type stuff, plugging myself.
st.write(f'\n\nFeedback and report bugs: holmj#mail.gvsu.edu')
st.write('\nSocials: [Twitter](https://twitter.com/JensenH_) [GitHub](https://github.com/Jensen-holm) [Linkedin](https://www.linkedin.com/in/jensen-holm-3584981bb/)')
st.write('[Documentation / Code](https://github.com/Jensen-holm/MLB-Simapp)')
Related
Here is the code to create the layout
import time
from rich.live import Live
from rich.table import Table
from rich.layout import Layout
layout=Layout()
layout.split_row(
Layout(name="left"),
Layout(name="right"), )
print(layout)
I would like to display the below table in the right column but I can't figure out how
table = Table()
table.add_column("Row ID")
table.add_column("Description")
table.add_column("Level")
with Live(table, refresh_per_second=4): # update 4 times a second to feel fluid
for row in range(12):
time.sleep(0.4) # arbitrary delay
# update the renderable internally
table.add_row(f"{row}", f"description {row}", "[red]ERROR")
from alice_blue import *
import pdb
import datetime
import time
import pandas as pd
access_token = '1JekMg.ezoSy4HW8rn3zjUzpRWR2fA2P9c6yQLjGWHdnCvXtOs'
alice = AliceBlue(username='', password='', access_token= '5ENG1JekMg.ezoSy4HW8rn3zjUzpRWR2fA2P9c6yQLjGWHdnCvXtOs', master_contracts_to_download=['NSE', 'NFO'])
traded_stocks = []
socket_opened = False
def event_handler_quote_update(message):
print(f"quote update {message}")
name = message['instrument'].symbol
openx = message['open']
high = message['high']
low = message['low']
close = message['close']
ltp = message['ltp']
cap = 100000
curr_time=datetime.datetime.now()
crt_time=curr_time.time()
breakout=datetime.time(18, 30)
if (crt_time >= breakout) and (name not in traded_stocks) and (ltp >= high):
print(f"buy: {name} , ltp: {ltp}")
traded_stocks.append(name)
message = alice.place_order(transaction_type = TransactionType.Buy, instrument = alice.get_instrument_by_symbol('NSE', name), quantity = 1 , order_type = OrderType.Limit, product_type = ProductType.BracketOrder, price = high, trigger_price = None, stop_loss =low, square_off =float(format((high-low), ".1f")), trailing_sl = None, is_amo = False)
sleep(10)
else :
print(f"time not satisfied is {curr_time}")
def open_callback():
global socket_opened
socket_opened = True
alice.start_websocket(subscribe_callback=event_handler_quote_update,
socket_open_callback=open_callback,
run_in_background=True)
while(socket_opened==False):
pass
instrument = [alice.get_instrument_by_symbol('NSE', 'ICICIBANK')]
while True:
alice.subscribe(instrument, LiveFeedType.MARKET_DATA)
Im trying to code a Open Range Breakout Strategy with this alice(https://pypi.org/project/alice-blue/)
But i cant breakthrough what concept to use
Can anyone Suggest a CODE based on provided link to alice-blue data and code please
I tried of placing order on specific time alone but the code runs and fires orders continously
Want a Suggestion with Function and the Order must be placed only once for a certain script
Step 1: Create a cron job at 9:30 AM and Store the Highest Price in DB.
Step 2: Create another cron job for every 15 mins --> Compare LTP > High
Step 3: If the condition is true --> Place an order and store the order ID & instrument
Step 4: Create one more cron job for exit signal --> compare with Target or SL price ---> Place Exit Order
I am making a menu func which adds songs to the player.
def add_song():
song = filedialog.askopenfilename(initialdir='C:\\Users\\Soham\\Music', title="Choose a
song!",filetypes=(("mp3 Files", "*.mp3"), ))
song_name = song.split("/")[-1].split(".")[0]
song_list.insert(END, song_name)
Then afterwards I have a play button which is coded to play the song added -
play_button = Button(controls_frame, image=play_button_img,borderwidth=0, command = play)
play_button.grid(row=0,column=2,padx=5)
So, the func, play()'s code is -
def play():
song = song_list.get(ACTIVE)
pygame.mixer.music.load(song)
pygame.mixer.music.play(loops=0)
But here dong variable in play() is actually just the name of song as it is already split off in add_song().And pygame needs the entire path as the song is not in the same directory as the python file. So pygame cannot open and play the song resulting in the error -
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Soham\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line
1885, in __call__
return self.func(*args)
File "c:\Users\Soham\Desktop\HM MP.py", line 26, in play
pygame.mixer.music.load(song)
pygame.error: Couldn't open 'Avicii - The Nights'
So what can I do about this , is there another way where I can split off the path for displaying the song name creating no problems for pygame to play the music??
Also, I am using Windows 10 Pro , high end machine and using Python 3.
Since you are inserting the song on to the list box and play it from there, what you could do is, make a dictionary of index starting from 0 as key and values as list of song name and path, so its something like like song_dict = {idx:[song_name,song_path]}. So each idx will be your selection from the listbox. I have made an example with this, take a look:
from tkinter import *
from tkinter import filedialog
import pygame
root = Tk()
pygame.mixer.init()
song_dict = {} # Empty dict to assign values to it
count = 0 # An idx number to it increase later
def add_song():
global count
song_path = filedialog.askopenfilename(initialdir='C://Users//Soham//Music', title="Choose a song!",filetypes=(("mp3 Files", "*.mp3"), ))
song_name = song_path.split("/")[-1].split(".")[0]
song_dict[count] = [song_name,song_path] # Create the desired dictionary
song_list.insert(END, song_name) # Insert just the song_name to the Listbox
count += 1 # Increase the idx number
def play_song(*args):
idx = song_list.curselection()[0] # Get the index of the selected item
song = song_dict[idx][1] # Get the corresponding song from the dictionary
pygame.mixer.music.load(song) # Load the song
pygame.mixer.music.play(loops=0) # Play the song
song_list = Listbox(root,width=50)
song_list.pack(pady=10)
choose = Button(root,text='Choose song',command=add_song)
choose.pack(pady=10)
song_list.bind('<Double-Button-1>',play_song) # Just double click the desired song to play
root.mainloop()
Just double click the song you want to play. You can also use a button instead of bind() like you do in your code.
An example of how song_dict will structure like:
{0: ['Shawn Mendes - Perfectly Wrong', 'C:/PyProjects/sONGS/Shawn Mendes - Perfectly Wrong.mp3'],
1: ['Lil Nas X - Old Town Road (feat', 'C:/PyProjects/sONGS/Lil Nas X - Old Town Road (feat. Billy Ray Cyrus) - Remix.mp3'],
2: ['NF - Time - Edit', 'C:/PyProjects/sONGS/NF - Time - Edit.mp3']}
Though I would also recommend to make a button to ask for directory and take all the mp3 files in that directory and populate the listbox.
If you want to use filedialog.askopenfilenames then you can edit the function as below:
import os
def add_song():
songs_path = filedialog.askopenfilenames(initialdir='C://Users//Soham//Music', title="Choose a song!")
for count,song in enumerate(songs_path):
song_name = os.path.basename(song)
song_dict[count] = [song_name,song] # Create the desired dictionary
song_list.insert(END, song_name) # Insert just the song_name to the Listbox
In this case you don't need the pre defined count variable, as we make them from the for loop.
EDIT:
Instead of using split, why not just use os.path, so you can get the basename from the path, like:
import os
song_name = os.path.basename(song_path) # If its tuple then loop through and follow
You can create a dict having {'song name': 'file path'}
I've got a problem with updating table of contents in docx-file, generated by python-docx on Linux. Generally, it is not difficult to create TOC (Thanks for this answer https://stackoverflow.com/a/48622274/9472173 and this thread https://github.com/python-openxml/python-docx/issues/36)
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
paragraph = self.document.add_paragraph()
run = paragraph.add_run()
fldChar = OxmlElement('w:fldChar') # creates a new element
fldChar.set(qn('w:fldCharType'), 'begin') # sets attribute on element
instrText = OxmlElement('w:instrText')
instrText.set(qn('xml:space'), 'preserve') # sets attribute on element
instrText.text = 'TOC \o "1-3" \h \z \u' # change 1-3 depending on heading levels you need
fldChar2 = OxmlElement('w:fldChar')
fldChar2.set(qn('w:fldCharType'), 'separate')
fldChar3 = OxmlElement('w:t')
fldChar3.text = "Right-click to update field."
fldChar2.append(fldChar3)
fldChar4 = OxmlElement('w:fldChar')
fldChar4.set(qn('w:fldCharType'), 'end')
r_element = run._r
r_element.append(fldChar)
r_element.append(instrText)
r_element.append(fldChar2)
r_element.append(fldChar4)
p_element = paragraph._p
But later to make TOC visible it requires to update fields. Mentioned bellow solution involves update it manually (right-click on TOC hint and choose 'update fields'). For the automatic updating, I've found the following solution with word application simulation (thanks to this answer https://stackoverflow.com/a/34818909/9472173)
import win32com.client
import inspect, os
def update_toc(docx_file):
word = win32com.client.DispatchEx("Word.Application")
doc = word.Documents.Open(docx_file)
doc.TablesOfContents(1).Update()
doc.Close(SaveChanges=True)
word.Quit()
def main():
script_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
file_name = 'doc_with_toc.docx'
file_path = os.path.join(script_dir, file_name)
update_toc(file_path)
if __name__ == "__main__":
main()
It pretty works on Windows, but obviously not on Linux. Have someone any ideas about how to provide the same functionality on Linux. The only one suggestion I have is to use local URLs (anchors) to every heading, but I am not sure is it possible with python-docx, also I'm not very strong with these openxml features. I will very appreciate any help.
I found a solution from this Github Issue. It work on ubuntu.
def set_updatefields_true(docx_path):
namespace = "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}"
doc = Document(docx_path)
# add child to doc.settings element
element_updatefields = lxml.etree.SubElement(
doc.settings.element, f"{namespace}updateFields"
)
element_updatefields.set(f"{namespace}val", "true")
doc.save(docx_path)## Heading ##
import docx.oxml.ns as ns
def update_table_of_contents(doc):
# Find the settings element in the document
settings_element = doc.settings.element
# Create an "updateFields" element and set its "val" attribute to "true"
update_fields_element = docx.oxml.shared.OxmlElement('w:updateFields')
update_fields_element.set(ns.qn('w:val'), 'true')
# Add the "updateFields" element to the settings element
settings_element.append(update_fields_element)
I am trying to create a menu that calls an SQL database for life expectancy data across the world. I'm having trouble with menubutton, as I want to set the first value ("No region selected") as my initial value. There are three things that I want: how to set the value as the default (ideally the equivalent of invoked for normal radiobuttons), is there a better for what I want option than menubutton, and is there a decent web page that can help me (tutorialspoint got me in the initial direction, but unless I'm looking in the wrong places, I can't find how to select and invoke radiobuttons in the menubutton).
Ideally, I'd also like advise on how not to have the menuoptions stretch up everywhere too. A limit of say 20?
Here's a look of a somewhat stripped down piece of my code.
Edit: I've found a solution to my select/invoke issues. mb.menu.invoke(0)
from Tkinter import *
import tkMessageBox
import Tkinter
import sqlite3
def selectStuff():
selectionRegion = str(countryVar.get())
mb.config(text = selectionRegion)
sqlLocation = 'AllData/LifeExpectency.sqlite'
sqlDB = sqlite3.connect(sqlLocation)
cursor = sqlDB.cursor()
root = Tk()
frameCountry = Frame(root)
frameCountry.pack()
stringCountry= StringVar()
labelCountry = Label(frameCountry, textvariable=stringCountry)
stringCountry.set("Select Region")
labelCountry.pack()
'''-------------------------------'''
mb = Menubutton ( frameCountry, relief=RAISED, activebackground="white")
mb.grid()
mb.menu = Menu ( mb, tearoff = 0 )
mb["menu"] = mb.menu
sql1 = "SELECT Country FROM total_lifespan"
countryVar = StringVar()
mb.menu.add_radiobutton ( label="No Region Selected", variable =countryVar,
value = "No Region Selected", command =selectStuff)
try:
cursor.execute(sql1)
results = cursor.fetchall()
for row in results:
mb.menu.add_radiobutton ( label=row, variable =countryVar, value = row,
command =selectStuff)
except:
print "Error: unable to retrieve data."
mb.pack()
'''-------------------------------'''
#Edit:
mb.menu.invoke(0)
#/Edit:
root.mainloop()
sqlDB.close()