Skip to content

Commit

Permalink
Solution comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Gordon Shotwell committed Apr 16, 2024
1 parent 918e955 commit 5c8419d
Show file tree
Hide file tree
Showing 21 changed files with 64 additions and 13 deletions.
3 changes: 2 additions & 1 deletion apps/problem-sets/1-getting-started/1.0-hello-world/README
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
Modify the app to add "Hello World" to the main heading.
Modify the app to add "Hello World!" to the main heading.
Click the play button to run the app.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
df = pd.read_csv(infile)
df = df.drop(columns=["text"])

# The render.data_frame decorator is used to display dataframes.


@render.data_frame
def penguins_df():
Expand Down
3 changes: 3 additions & 0 deletions apps/problem-sets/1-getting-started/1.2-debug/app-solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
df = df.drop(columns=["text"])


# It's important that you use the right decorator for your funciton's return value
# in this case since the function is returning a dataframe we need to use the
# `@render.data_frame` decorator.
@render.data_frame
def penguins_df():
return df
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
from pathlib import Path
from data_import import df

# All the inputs start with `ui.input_*`, which adds an input to the app.
# Note that this input doesn't do anything because we haven't connected it
# to a rendering function.

ui.input_select(
"account",
"Account",
id="account",
label="Account",
choices=[
"Berge & Berge",
"Fritsch & Fritsch",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from data_import import df

ui.input_select(
"account",
"Account",
id="account",
label="Account",
choices=[
"Berge & Berge",
"Fritsch & Fritsch",
Expand All @@ -18,8 +18,13 @@

@render.data_frame
def table():
# When we call the account input with `input.account()` we can use its value
# with regular Python code. This will also cause the rendering function
# to rerun whenever the user changes the account value.
account_subset = df[df["account"] == input.account()]
account_counts = (
account_subset.groupby("sub_account").size().reset_index(name="counts")
account_subset.groupby(["account", "sub_account"])
.size()
.reset_index(name="count")
)
return account_counts
8 changes: 5 additions & 3 deletions apps/problem-sets/1-getting-started/1.4-filter-connect/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from data_import import df

ui.input_select(
"account",
"Account",
id="account",
label="Account",
choices=[
"Berge & Berge",
"Fritsch & Fritsch",
Expand All @@ -20,6 +20,8 @@
def table():
account_subset = df
account_counts = (
account_subset.groupby("sub_account").size().reset_index(name="counts")
account_subset.groupby(["account", "sub_account"])
.size()
.reset_index(name="count")
)
return account_counts
2 changes: 2 additions & 0 deletions apps/problem-sets/1-getting-started/1.5-debug/app-solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

@render.data_frame
def table():
# Remember that inputs are callable values, so whenever you refer to them
# in rendering functions you need to call them (`input.account()` not `input.account`)
account_subset = df[df["account"] == input.account()]
account_counts = (
account_subset.groupby("sub_account").size().reset_index(name="counts")
Expand Down
3 changes: 3 additions & 0 deletions apps/problem-sets/1-getting-started/1.6-debug/app-solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

@render.data_frame
def table():
# Inputs can only be called within a reactive context, which
# means that if you refer to them outside of a rendering function
# you'll get an error.
account_subset = df[df["account"] == input.account()]
account_counts = (
account_subset.groupby("sub_account").size().reset_index(name="counts")
Expand Down
2 changes: 1 addition & 1 deletion apps/problem-sets/1-getting-started/1.7-add-plot/README
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Add a second plot output to the app which plots the precision-recall curve. Note that you should use the `@render_plotly` decorator.
Use the `plot_precision_recall_curve` function from the `plots.py` module to add a second plot output to the app. Note that you should use the `@render_plotly` decorator
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
],
)


# It's a good idea to use helper functions for things like drawing plots
# or displaying data frames because it makes your app more modular and easy to
# read.
@render_plotly
def precision_recall_plot():
account_subset = df[df["account"] == input.account()]
Expand Down
2 changes: 2 additions & 0 deletions apps/problem-sets/2-basic-ui/2.1-sidebar/app-solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from plots import plot_auc_curve, plot_precision_recall_curve
from shinywidgets import render_plotly

# The ui.sidebar can be included anywhere in your app script,
# but by convention it usually goes near the top.
with ui.sidebar():
ui.input_select(
"account",
Expand Down
4 changes: 4 additions & 0 deletions apps/problem-sets/2-basic-ui/2.2-cards/app-solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
],
)


# Adding a ui.card context manager will add a card to the UI.
# This is useful for grouping related elements together.
# You can add as many ui elements as you like to the card.
with ui.card():

@render_plotly
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
],
)

# Cards are great for grouping related elements together.
with ui.card():
ui.card_header("Model Metrics")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
],
)

# `layout_columns` lays child elements out side by side.
# You can add anything to the layout columns context manager, but it
# works best with cards and value boxes.
with ui.layout_columns():

with ui.card():
Expand Down
2 changes: 1 addition & 1 deletion apps/problem-sets/3-reactivity/3.1-reactive-calc/README
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Extract the account filtering logic into a reacitve calculation.
Extract the account filtering logic into a reactive calculation.

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
from shinywidgets import render_plotly


# You should always extract repeated logic into a reactive.cacl
# in addition to making your app easier to read it will also
# make it run faster because the reactive calc is calculated once
# even if many other rendering functions retrieve its value.
@reactive.calc
def account_data():
return df[df["account"] == input.account()]
Expand All @@ -30,6 +34,7 @@ def account_data():

@render_plotly
def metric():
# `account_data` is called similar to an input.
if input.metric() == "ROC Curve":
return plot_auc_curve(
account_data(), "is_electronics", "training_score"
Expand All @@ -46,4 +51,5 @@ def metric():

@render_plotly
def score_dist():
# `account_data` is called similar to an input.
return plot_score_distribution(account_data())
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
We have a second sidebad input which allows the user to filter the dataset by the number of characters in the `text` field.
We have a second sidebar input which allows the user to filter the dataset by the number of characters in the `text` field.
Add a second reactive calculation to the app which filters the `account_data()` reactive.

For reference `input.chars()` returns a tuple with the lower and upper range of a value, and you can filter the data frame with:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ def account_data():
return df[df["account"] == input.account()]


# You can call reactive calculations from other reactive calculations.
# This is very useful for performance because the calculation will be
# minimally rerun.
@reactive.calc()
def character_filter():
return account_data()[account_data()["text"].str.len().between(*input.chars())]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def character_filter():
],
)

# You shouldn't use return values with `render.express` instead just call the inputs
# and rendering funcitons and they will be added to the app.
@render.express
def sub_selector():
# We can't use the account_data reactive here because we are using the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ def account_data():
]


# You can control execution by adding `@reactive.event` to any reactive function.
# This tells Shiny to only trigger this renderer when a particular input changes.
# Note that when inputs are used in reactive.events they are not called (input.update not input.update())
# This is because we are watching the reactive itself for changes, not making use of the current value.
@reactive.calc()
@reactive.event(input.update, ignore_init=True)
def character_filter():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ def character_filter():
return account_data()[(account_data()["text"].str.len().between(*input.chars()))]


# Reactive effects are used for side effects, not values.
# They are similar to callback functions in other frameworks.
@reactive.effect
@reactive.event(input.reset)
def reset_slider():
Expand Down

0 comments on commit 5c8419d

Please sign in to comment.