Conditional rendering in streamlit - streamlit

I have a form where I need to use some conditional rendering. Basically, the form needs to change dynamically based on what the user input is. For instance, if I ask "Where did you hear about us?" and give the users some default options (e.g. "Linkedin", "Our website"..), I want that if the user selects "Other" a st.text_input appears where the user can type the answer to the question.
The problem I am facing is that:
If I use st.form (with the st.submit_form_button), what happens is that the form does not dynamically adapt to the user's input. So the text_field won't show up at all when the user ticks "Other" in the example above.
If I do not use st.form, then the form reloads every time the user clicks on any widget. This does not affect the functionality of the form, but it does make for a very bad user experience!
Any tips on how I could either include conditional rendering within st.form or just avoid the bad user experience of the form being reloaded every time the user clicks on any widget?
Any help would be appreciated!

Instead of using form, you can create the form manually and create several containers to separate the code.
import streamlit as st
########################################################
# Sidebar section
########################################################
sb = st.sidebar # defining the sidebar
sb.markdown("🛰️ **Navigation**")
page_names = ["🏠 Home", "⚙️ Other"]
page = sb.radio("", page_names, index=0)
if page == "🏠 Home":
st.subheader("Example home")
st.subheader("What is Lorem Ipsum? ?")
lorem_ipsum = "Lorem Ipsum is simply dummy text of the printing and typesetting industry"\
"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book"
st.markdown(lorem_ipsum, unsafe_allow_html=True)
else:
other_title = '<h3 style="margin-bottom:0; padding: 0.5rem 0px 1rem;">⚙️ Other</h3>'
st.markdown(other_title, unsafe_allow_html=True)
lorem_ipsum = "Lorem Ipsum is simply dummy text of the printing and typesetting industry"\
"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book"
st.markdown(lorem_ipsum, unsafe_allow_html=True)
container_selection = st.container()
col1_cs, col2_cs = container_selection.columns([1, 2])
with col1_cs:
slider_val = st.slider("Form slider")
see_text = st.checkbox("See text")
if see_text:
st.warning("**See text** will take more time. Are you sure ?")
other = st.checkbox("Other")
if other:
st.info("Other checkbox")
result = st.button(label="other buttom")
with col2_cs:
st.caption(" ")
if result:
ccp = st.container()
with ccp:
information_title = '<h3 style="margin-bottom:0; padding: 0.5rem 0px 1rem;">📋 Ipsum is simply dummy text </h3>'
st.markdown(information_title, unsafe_allow_html=True)

Related

Replace Text in XML files with placeholder text

I performed text mining on files that I am preparing for publication right now. There are several XML files that contain text within segments (see basic example below). Due to copyright restrictions, I have to make sure that the files that I am going to publish do not contain the whole text while someone who has the texts should be able to 'reconstruct' the files. To make sure that one can still perform basic text mining (= count lengths), the segment length should not change. Therefore I am looking for a way to replace every word except for the first and last one in all segments with dummy / placeholder text.
Basic example:
Input:
<text>
<div>
<seg xml:id="A">Lorem ipsum dolor sit amet</seg>
<seg xml:id="B">sed diam nonumy eirmod tempor invidunt</seg>
</div>
</text>
Output:
<text>
<div>
<seg xml:id="A">Lorem blank blank blank amet</seg>
<seg xml:id="B">sed blank blank blank blank invidunt</seg>
</div>
</text>
There is rapply to recursively replace values in a nested list:
Let be data.xml containing your input.
library(tidyverse)
library(xml2)
read_xml("data.xml") %>%
as_list() %>%
rapply(how = "replace", function(x) {
tokens <-
x %>%
str_split(" ") %>%
simplify()
n_tokens <- length(tokens)
c(
tokens[[1]],
rep("blank", n_tokens - 2),
tokens[[n_tokens]]
) %>%
paste0(collapse = " ")
}) %>%
as_xml_document() %>%
write_xml("data2.xml")
Output file data2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<text>
<div>
<seg id="A">Lorem blank blank blank amet</seg>
<seg id="B">sed blank blank blank blank invidunt</seg>
</div>
</text>

Blur top and bottom of multiline label

I have multiline label (for example 100 lines) which text is scrolling from bottom to top, something like movie credits. I would like to blur 10% of the top and bottom portions of that label so that text which is entering and leaving is blurred. How can I achieve that? I tried to stick some elements over that positions and blur them but that did not work.
I haven't seen blurrying, but usually the text is fading. Here's an example how you could do fading: Create an overlay pane with a linear gradient that goes from background color -> transparent -> background color. Like this:
public class Main extends Application {
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage primaryStage) {
TextArea textArea = new TextArea(
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. ");
textArea.setWrapText(true);
StackPane root = new StackPane();
Pane overlay = new Pane();
overlay.setMouseTransparent(true);
Stop[] stops = new Stop[] { new Stop(0.0, Color.WHITE), new Stop(0.25, Color.TRANSPARENT), new Stop(0.75, Color.TRANSPARENT), new Stop(1.0, Color.WHITE) };
LinearGradient linearGradient = new LinearGradient(0, 0, 0, 1, true, CycleMethod.NO_CYCLE, stops);
overlay.setBackground(new Background(new BackgroundFill(linearGradient, null, null)));
root.getChildren().addAll(textArea, overlay);
Scene scene = new Scene(root, 300, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
}
If you insist on blurring, you could use the snapshot function, create a snapshot of the text, blur the image and put it on top of the text.

NSAttributedString: Is it more expensive to redeclare attributes?

Given this string
Lorem Ipsum dolor sit amet
And given I want it to be styled like this
underlined: 0 - 26 (Lorem Ipsum dolor sit amet)
bold: 6 - 21 (Ipsum dolor sit)
red color: 12 - 17 (dolor)
Does it matter performance wise if this is declared like this
0-6 (Lorem )
underlined
6-12 (Ipsum )
underlined, bold
12-17 (dolor)
underlined, bold, red color
17-21 ( sit)
underlined, bold
21-26 ( amet)
underlined
VS if it is declared like this
0-26 (Lorem Ipsum dolor sit)
underlined
6-21 (Ipsum dolor sit)
bold
12-17 (dolor)
red color
??
This is a very simplified example of my much more complex attributed string.
I wonder if this matters performance wise either when rendering or when building this string.

TYPO3 lib HTML and TEXT code

I want to show i LIB on my page, but it will be showed on the page all my sits, but not the site with Uid = 3
So in my main TS i have, this
[globalVar = TSFE:id <> 3]
.....
[end]
My question is now, how do i setup a lib, thats have some text and HTML content in it..
Lets say that its this i want to show
<div class="ProductListTitle_style1">
my text my text
<p> text text text... </p>
</div>
You can use lib = COA in combination with TEXT and IMAGE
lib.b = COA
lib.b {
wrap = <div class="ProductListTitle_style1">|</div>
10 = TEXT
10.value = my text my text
20 = TEXT
20.value = text text text...
20.wrap = <p>|</p>
30 = IMAGE
30.file = path/to/file.png
30.altText = My image
30.width = 300
}
Before TYPO3 6.0 you could use lib = HTML.
lib.a = HTML
lib.a.value (
<div class="ProductListTitle_style1">
my text my text
<p> text text text... </p>
</div>
)
You can also combine the two possibilities
lib.c = COA
lib.c {
wrap = <div class="ProductListTitle_style1">|</div>
10 = TEXT
10.value = my text my text
20 = HTML
20.value = <p> text text text... </p>
}
Just for clarification: In TYPO3 4.5+, the Content Objects TEXT and HTML have the same functionality. So you can of course put HTML tags in a TEXT object:
lib.something = TEXT
lib.something.value = <p>My Text</p>
Since both objects could do the same since TYPO3 4.5, the HTML cObject was deprecated and removed in 6.0.
As for Thomas question about COA: A COA is a "content object array" and thus an array of content elements. A COA is used when more than one content needs to be combined in one TypoScript object. So if you just have one object (as in my example above), you don't need a COA, but if you have more than one content, use it (as in hildende's first example).

Qt how to break the LabelText of QInputDialog

Here is my example code:
QInputDialog* inDialog = new QInputDialog();
inDialog->setMaximumWidth(100);
inDialog->setLabelText(QString("long and very long......you can say very long"));
The input box showing really long (as long as the string), I was expected the way to set word-wrap for the LabelText, but it seem QInputDialog has no method for that!!!
What can I do now? Write my own InputDialog class? Oh no...!
I hope there is a better way for it!
I would do it myself, like this for example :
QString s = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut" ;
QString wrapped ;
if(s.length()>35)
{
wrapped = s.left(15) + QString(".....") + s.right(15) ;
}
else
{
wrapped = s ;
}
inDialog->setLabelText(wrapped) ;
I'm just starting with QT so this may not be the best way to get what you want but heres what I would do.
I would create my own custom input dialog which inherits QInputDialog. I would then override the setLabelText function to check if the string length is less than 100.
If it is less than 100 then you can go ahead and display it. If not then you can choose where to add yours dots and remove words in order to bring the size down.
Once its equal to 100 characters or less, you can display it.
I will try and write an example when I get home if you would like.

Resources