How do you keep Streamlit widgets from getting reset when I collapse/expand a heading - streamlit

I'm playing with Streamlit, and there is some behaviour I don't know how to manage.
I'd like three widgets in a collapsible section, but when I collapse/expand the section the values go back to their defaults, making correcting the values a bit of a pain for the user.
Here is some sample code:
import streamlit as st
with st.beta_expander("Describe your baby"):
age, weight, sex = st.beta_columns((1,1,1))
with age:
baby_age = st.number_input('Baby age in months', min_value=0.0, max_value=36.0, step=0.25, value=2.0)
with weight:
baby_weight = st.number_input('Baby weight in KG', min_value=0.0, max_value=16.0, step=0.01, value=6.0)
with sex:
baby_sex = st.selectbox('Baby sex', ['Male', 'Female'])
st.write(f'Your {baby_age} month old {"boy" if baby_sex=="Male" else "girl"} is {baby_weight}kg.')
What is the intended way to handle this?

It seems to now work for streamlit>=1.8.0:
Of course, it also works with the st.expander too. You don't need the beta_ in the new versions.

Related

Cant get a math.random to work in two different places

function INV:DeleteInventoryItem( ply, pos, item)
local rarity = INV.PLAYERS[ply:SteamID64()][pos].quality
---print(rarity)
local value = "credits"
if(rarity == "Common")then
local amount = math.floor(math.random(1, 30))
table.remove( INV.PLAYERS[ply:SteamID64()], pos)
local var = ply:ChatPrint("You got ".. amount .." credits from deconstructing!")
ply:INVAddCredits( amount )
self.SAVE:SendInventory( ply )
local updatevalue = INV.PLAYERS[ply:SteamID64()].inventorydata.credits
UpdateDatabase(value, ply:SteamID(), updatevalue)
end
end
The problem I am having is that I cannot get the same value from the amount variable, so it says that you got a certain amount when it actually gave you a different amount.
I am really confused on how I can make it the same amount... Any help would be appreciated!
Thanks for all the help you guys have been, I since have fixed the issue and it was something wrong with the adding of the inventory credits.
-Thanks D12

How to limit Django-CMS template_choices based on Page parent

This question could probably be solved with a more broad Q: "How to replace a python 2.7 attribute with a property from outside", but maybe there's a Django-CMS way of accomplishing this, so I ask:
I'm trying to limit the template choices of Django-CMS' (v3.4.x) pages based on their parents, so for this I thought of overriding it's template_choices with a function, but I see that in Django-CMS' Page model it's loaded on creation, like this:
#python_2_unicode_compatible
class Page(...):
...
TEMPLATE_DEFAULT = get_cms_setting('TEMPLATES')[0][0]
template_choices = [(x, _(y)) for x, y in get_cms_setting('TEMPLATES')]
...
Modifying get_cms_settins is out of the question, but I do need to alter TEMPLATE_DEFAULT and template_choices so that they have the proper values I wish for. Since I'm still fairly new to Django and Python, my question is where and how do I do this?
My first attempt was to do something like this on my models.py:
#property
def template_choices(self):
from cms.utils import get_cms_setting
templates = [(x, _(y)) for x, y in get_cms_setting('TEMPLATES')]
if self.parent:
if self.parent.template == 'parent_a.html':
templates = [('child_A.html', _('Child A'))]
elif self.parent.template == 'parent_b.html':
templates = [('child_b.html', _('Child B'))]
else:
templates = [('fullwidth.html', _('Fullwidth'))]
else:
templates = [('home_page.html', _('Homepage')),
('parent_a.html', _('Parent A')),
('parent_b.html', _('Parent B'))]
return templates
#property
def template_default(self):
return self.template_choices[0][0]
Page.template_choices = template_choices
Page.TEMPLATE_DEFAULT = template_default
And this is setting those fields correctly if I try to inspect any instance of Page, however when I try to edit any page and I click on the Page>Templates menu, all templates are up for selection, so it seems the template_choices and TEMPLATE_DEFAULT attributes are being ignored. Inspecting pagemodel.py seems to confirm this, since the get_template and get_template_name methods use get_cms_setting('TEMPLATES') instead of those fields. Also in cms_toolbars.py for the # templates menu section get_cms_setting('TEMPLATES') rather than self.page.template_choices which seems to be the main culprit. So, this question has turned into a bug ticket: https://github.com/divio/django-cms/issues/6520

If Else in R, if product ID is X then change Product Name

I am trying to figure out what is working and why the other way is not working for me.
At the moment I have a list of shops I use and I need to change the naming every time; so I have decided to go by the product_id which never changes, but my code is not working.
product_id <- vector()
This one is not working:
product_name[product_id == '40600000003'] <- 'my cool store']
but this one does work:
product_name[product_name == 'my#cool#Store'] <- 'my cool store'
Now, I am not sure what am I doing wrong, I tried to do:
if (product_id == '40600000003') {
product_name = 'my cool shop'
}
I have a list of 15 shops that I need to change the naming as they arrive in the wrong format from the api connection.
Try 40600000003 instead of '40600000003' it's more than likely reading your vector slots as int if it doesn't contain any characters

Python and Qt : Retrieving branch names in multi-leveled QMenu

Having trouble finalizing a dynamic QMenu tree.
The structure and format is perfect, but what remains missing is the return of all branch names when triggering the end-action.
The only implement I have tried with ANY trend toward a solution is the use of self.sender(); which returns only the name of the end-action.
Before adding a ton of the lengthy code snips - starting by conceptualizing the question seemed best in case there is some (obvious) means I am over-looking.
Example;
The ideal return based on the footer figure would be something along the lines of...
Top Image:
'Single Results' - 'Head Results'
Middle Image:
'Batch Results' - 'testBatch_vr3' - 'Run-1' - 'Budget Results'
Bottom Image:
'Single Results' - 'testBatch_vr3' - 'Run-3' - 'Particle Tracks'
To the point;
How can all names in a multi-leveled set of QMenus be retrieved when triggering end-action?
The following complex bits resolved my problem. It might be a bit obscure way to go about it (hovered signal from menu to search for dictionary menu entry) - but it works well for now.
# checks batch processing folder for existing directories and publishes the contents
# into the batch results menu comboBox
def populateBatchResults(self):
self.batchMenuDict = {}
self.runMenuDict = {}
self.runBatchResultsPopup.clear()
self.batchDirNamesMenu.clear()
batchModDir = self.estabBatchModelDir()
for batch in os.listdir(batchModDir):
fullBatchDir = batchModDir+str(batch)
if os.path.isdir(fullBatchDir):
self.batchMenuDict[batch] = QMenu(self.iface.mainWindow())
self.batchMenuDict[batch].setTitle(str(batch))
self.runBatchResultsPopup.addMenu(self.batchMenuDict[batch])
for run in os.listdir(fullBatchDir):
fullRunDir = fullBatchDir+'\\'+str(run)
if os.path.isdir(fullRunDir):
self.runMenuDict[run] = QMenu(self.iface.mainWindow())
self.runMenuDict[run].setTitle(str(run))
self.batchMenuDict[batch].addMenu(self.runMenuDict[run])
self.runMenuDict[run].hovered.connect(self.assertBatchMenuSelection)
# get all current cursor hovered menu names
def assertBatchMenuSelection(self):
self.selectedBatch = self.runBatchResultsPopup.activeAction().text()
self.selectedRun = self.batchMenuDict.get(self.selectedBatch).activeAction().text()
self.selectedAction = self.runMenuDict.get(self.selectedRun).activeAction().text()

How can I model a scalable set of definition/term pairs?

Right now my flashcard game is using a prepvocab() method where I
define the terms and translations for a week's worth of terms as a dictionary
add a description of that week's terms
lump them into a list of dictionaries, where a user selects their "weeks" to study
Every time I add a new week's worth of terms and translations, I'm stuck adding another element to the list of available dictionaries. I can definitely see this as not being a Good Thing.
class Vocab(object):
def __init__(self):
vocab = {}
self.new_vocab = vocab
self.prepvocab()
def prepvocab(self):
week01 = {"term":"translation"} #and many more...
week01d = "Simple Latvian words"
week02 = {"term":"translation"}
week02d = "Simple Latvian colors"
week03 = {"I need to add this":"to self.selvocab below"}
week03d = "Body parts"
self.selvocab = [week01, week02] #, week03, weekn]
self.descs = [week01d, week02d] #, week03, weekn]
Vocab.selvocab(self)
def selvocab(self):
"""I like this because as long as I maintain self.selvocab,
the for loop cycles through the options just fine"""
for x in range(self.selvocab):
YN = input("Would you like to add week " \
+ repr(x + 1) + " vocab? (y or n) \n" \
"Description: " + self.descs[x] + " ").lower()
if YN in "yes":
self.new_vocab.update(self.selvocab[x])
self.makevocab()
I can definitely see that this is going to be a pain with 20+ yes no questions. I'm reading up on curses at the moment, and was thinking of printing all the descriptions at once, and letting the user pick all that they'd like to study for the round.
How do I keep this part of my code better maintained? Anybody got a radical overhaul that isn't so....procedural?
You should store your term:translation pairs and descriptions in a text file in some manner. Your program should then parse the text file and discover all available lessons. This will allow you to extend the set of lessons available without having to edit any code.
As for your selection of lessons, write a print_lesson_choices function that displays the available lessons and descriptions to the user, and then ask for their input in selecting them. Instead of asking a question of them for every lesson, why not make your prompt something like:
self.selected_weeks = []
def selvocab(self):
self.print_lesson_choices()
selection = input("Select a lesson number or leave blank if done selecting: ")
if selection == "": #Done selecting
self.makevocab()
elif selection in self.available_lessons:
if selection not in self.selected_weeks:
self.selected_weeks.append(selection)
print "Added lesson %s"%selection
self.selvocab() #Display the list of options so the user can select again
else:
print "Bad selection, try again."
self.selvocab()
Pickling objects into a database means it'll take some effort to create an interface to modify the weekly lessons from the front end, but is well worth the time.

Resources