1 of 158

ITN: GitHub and Reproducibility Skillsets

Candace Savonen, Carrie Wright, and Kate Isaac

2 of 158

ITN Workshops!

While you are waiting:

3 of 158

Join at slido.com�#7691632

Click Present with Slido or install our Chrome extension to display joining instructions for participants while presenting.

4 of 158

Have your phone

(or a separate tab) handy for interactive polls!

Join at slido.com�#7691 632

5 of 158

What is your favorite candy?

Click Present with Slido or install our Chrome extension to activate this poll while presenting.

6 of 158

This helps us keep you informed of upcoming workshops, and to follow up and see how you are using what you learned.

7 of 158

How confident do you feel about using GitHub?

Click Present with Slido or install our Chrome extension to activate this poll while presenting.

8 of 158

What is the ITN?

ITCR Training Network

Catalyzing informatics research through training opportunities

9 of 158

User preparedness

Gap

Tool usability

Informatics research is hindered by a gap between different types of experts

CC-BY jhudatascience.org - Image made by Candace Savonone using https://getavataaars.com/ and https://thenounproject.com/ a

10 of 158

User preparedness

Gap

Tool usability

Catalyzing Informatics for Research

CC-BY jhudatascience.org - Image made by Candace Savonone using https://getavataaars.com/ and https://thenounproject.com/ a

11 of 158

Elements of ITN:

  1. Make courses about informatics

  • Make tools for researchers to do outreach

  • Provide live education opportunities

  • Enhance community engagement in cancer research

12 of 158

ITN courses

13 of 158

14 of 158

15 of 158

Write durable code

Organize your project

Understand the importance of code review

Use computational notebooks

Concepts discussed in Introductory Reproducibility in Cancer Informatics course:

Make your project open source with GitHub

Manage package versions

Document analyses

CC-BY jhudatascience.org

16 of 158

Use automation (GitHub actions)

Engage in code review

Use a Docker image

Discussed in the sequel course: Advanced Reproducibility for Cancer Informatics

Utilize version control

Get comfortable with GitHub concepts and workflow

Modify a Docker image

CC-BY jhudatascience.org

17 of 158

18 of 158

What is reproducibility?

19 of 158

Image created by Candace Savonen using Avataars.

Variable A

Variable B

R = 0.893

This code runs well on my computer, let me email it to you!

So exciting!

20 of 158

Image created by Candace Savonen using Avataars.

ERROR ERROR ERROR ERROR ERROR ERROR �ERROR ERROR

ERROR ERROR

Ruby’s code and data

21 of 158

Image created by Candace Savonen using Avataars.

Error: file path “Ruby’s computer/Ruby’s file/final_version10.R” not found

Re:Re:Re: Data

Hi Ruby, I don’t understand what this code is supposed to be doing...

Re:Re:Re: Data

Hi Avi, It works for me?

22 of 158

Image created by Candace Savonen using Avataars.

Variable A

Variable B

Variable A

Variable B

R = 0.893

R = 0.891

Ruby’s code and data

23 of 158

Based off of a figure from Essawy et al, 2020 https://doi.org/10.1016/j.envsoft.2020.104753

Effort

Time

Replicability

new researcher, new data

Reproducibility

new researcher, same data

Repeatability

same researcher, same data

24 of 158

Reproducibility saves everyone time and effort!

25 of 158

Image created by Candace Savonen using Avataars.

Ruby’s code

ERROR

Ruby’s code

Now Ruby

Future Ruby

26 of 158

Image created by Candace Savonen using Avataars.

Ruby’s code - not as reproducible

ERROR

ERROR

ERROR

ERROR

ERROR

ERROR

ERROR

27 of 158

Image created by Candace Savonen using Avataars.

Ruby’s code - made reproducibly

ERROR

28 of 158

Reproducibility is a tortoise’s game - it’s an incremental and slow process but it has high payoffs!

29 of 158

Image by Candace Savonen

I will re-run the code consistently and instantly upon whatever trigger I’m given.

Robots can help you with reproducibility! )

30 of 158

Reproducibility is iterative work!

Image created by Candace Savonen.

Ran once

Re-runs sometimes

Re-runs in every situation and gets the same result every time

Re-runs reliably in most contexts

Perfectly reproducible

No analysis reaches here

Not repeatable

Every analysis starts here

31 of 158

Reproducibility != Correctness

Reproducibility ~ Consistency

But you could be consistently wrong in the same way….

32 of 158

Tips for reproducibility:

  1. Write it down!
  2. Organize and re-organize
  3. Have everything* publicly available (GitHub)
  4. Have others look it over (code review)
  5. Automate monotonous stuff (CI/CD)
  6. Managing computing environments (containers)

*Everything that doesn’t violate IRB privacy and ethical data handling guidelines

33 of 158

Tips for reproducibility:

  • Write it down!
  • Organize and re-organize
  • Have everything* publicly available (GitHub)
  • Have others look it over (code review)
  • Automate monotonous stuff (CI/CD)
  • Managing computing environments (containers)

*Everything that doesn’t violate IRB privacy and ethical data handling guidelines

Next session!

34 of 158

Tips for reproducibility:

  • Write it down!
  • Organize and re-organize
  • Have everything* publicly available (GitHub)
  • Have others look it over (code review)
  • Automate monotonous stuff (CI/CD)
  • Managing computing environments (containers)

*Everything that doesn’t violate IRB privacy and ethical data handling guidelines

35 of 158

A useable, well-documented analysis is more likely to be used and disseminated!

CC-BY by jhudatascience.org

36 of 158

37 of 158

Documentation that every project should have!

  1. READMEs
    1. Background knowledge
    2. Usage info
    3. Software requirements to run the thing
    4. Basics on how the files are organized

38 of 158

39 of 158

Documentation that every project should have!

  • READMEs
    • Background knowledge
    • Usage info
    • Software requirements to run the thing
    • Basics on how the files are organized
  • Code annotations:
    • Explain historical decisions
    • Explain “quirks” of the code
    • Say where more development is needed (TODO)
    • Summarize the goals!

40 of 158

LLM

What is it really good at?

What does it struggle with?

Bard

  • Most human-like interaction
  • Answers oddball questions
  • Willing to answer “I don’t know”
  • Gives least amount of detail in answers
  • Has been known to give incorrect answers

ChatGPT

  • Most popular, which means most tested
  • Good all-around LLM
  • Unlikely to change answer even when told previous answer was wrong
  • Invents citations
  • Known hallucination issues

Claude

  • Good all-around LLM
  • Offers specific advice when editing a writing sample for tone
  • Best understanding of clever word play
  • Can sometimes require prodding to give additional detail
  • Doesn’t easily save threads at this time (but this is changing!)

Phind

  • Great for technical programming questions
  • Provides links to sources unprompted
  • Offers many programming options at once
  • Tends to plagiarize sources directly when used for writing

41 of 158

LLM

What is it really good at?

What does it struggle with?

Bard

  • Most human-like interaction
  • Answers oddball questions
  • Willing to answer “I don’t know”
  • Gives least amount of detail in answers
  • Has been known to give incorrect answers

ChatGPT

  • Most popular, which means most tested
  • Good all-around LLM
  • Unlikely to change answer even when told previous answer was wrong
  • Invents citations
  • Known hallucination issues

Claude

  • Good all-around LLM
  • Offers specific advice when editing a writing sample for tone
  • Best understanding of clever word play
  • Can sometimes require prodding to give additional detail
  • Doesn’t easily save threads at this time (but this is changing!)

Phind

  • Great for technical programming questions
  • Provides links to sources unprompted
  • Offers many programming options at once
  • Tends to plagiarize sources directly when used for writing

Use AI tools that are trained for the task you are trying to do!

42 of 158

LLMs can be good at telling you what historical or confusing code is doing

Image created by Candace Savonen using Avataars.

def my_function(x):

result = x

for i in range(10):

for j in range(5):

result = result + 2 * (i + 1) * (j + 1) * (i % 2 == 0 and j % 2 == 0) - 1

return result

Wait, what is this code even?

plot-data-2020-9-11.tsv

plot-data-20-10-2020.tsv

plot-data-20-10-2020-clean.tsv

plot_final.R

plot_final_FINAL.R

plot_final_old.R

plot.py

functions.R

functions-old.R

plot-final.png

plot-new.png

43 of 158

AI Coding Assistants

Free options!

44 of 158

Getting a basic strategy for how to write code for something

Example prompts:

    • How might I go about doing ______ ?
    • How could I structure code that would do ______ ?
    • Is it possible to create a package that does ______?
    • What packages could I use to make code that does _______ ?

45 of 158

Reviewing existing code for improvements

Example prompts:

    • Can you tell me how I could make this code more readable?
    • Can you help fix the formatting, styling, and indent errors on this code?
    • Can you recommend how I could make this code more reproducible?

46 of 158

Annotating or improving documentation

Example prompts:

    • Can you annotate this code?
    • Can you explain to me what this code is doing?
    • Can you create a README for this code?

https://hutchdatascience.org/AI_for_software/annotating-your-code.html

47 of 158

Tips for reproducibility:

  • Write it down!
  • Organize and re-organize
  • Have everything* publicly available (GitHub)
  • Have others look it over (code review)
  • Automate monotonous stuff (CI/CD)
  • Managing computing environments (containers)

*Everything that doesn’t violate IRB privacy and ethical data handling guidelines

48 of 158

Goals for an organizational scheme:

49 of 158

Image created by Candace Savonen.

Chaos reigns - nothing can be found

You lose sleep worrying about your file naming

Perfectly organized but maybe not maintainable

Disorganized and unmanageable

Maintainably organized

50 of 158

Project Organization tips (not one size fits all)

TIP

Example

Use informative names

metadata_df

expressed_gene_list�02_tumor_heatmap.py

Number scripts in the order they are run

01_download_data.sh

Keep like files with like files

Keeping results and raw data each in their own folders

Central document (like a README)

README.md

Dates in file names aren’t necessary

run_analysis.sh

A central script that re-runs the whole thing

run_analysis.sh

51 of 158

Tips for reproducibility:

  • Write it down!
  • Organize and re-organize
  • Have everything* publicly available (GitHub)
  • Have others look it over (code review)
  • Automate monotonous stuff (CI/CD)
  • Managing computing environments (containers)

*Everything that doesn’t violate IRB privacy and ethical data handling guidelines

52 of 158

final_final_version_100%_up_to_date

final_version_2021

final_version_edit_10_2021

final_version_edit5

final_version_edit4

for_realz_final_edit2

final_final_version_100%_up_to_date

final_version_2021

final_version_edit5

final_version_edit4

for_realz_final_edit2

Now was it “final_final_version_100%_up_to_date” or “final_version_edit5” that I was working from?

53 of 158

final_final_version_100%_up_to_date

final_version_2021

final_version_edit_10_2021

final_version_edit5

final_version_edit4

for_realz_final_edit2

final_final_version_100%_up_to_date

final_version_2021

final_version_edit5

final_version_edit4

for_realz_final_edit2

Now was it “final_final_version_100%_up_to_date” or “final_version_edit5” that I was working from?

VERSION CONTROL

NEEDED!

54 of 158

Image created by Candace Savonen using Avataars

Cancer data genomics atlas study

American cancer journal of America

“Code and data are available upon request by email.”

I’m requesting the code from your recent paper in the journal....

The corresponding author’s inbox

999,999,565473

55 of 158

Image created by Candace Savonen using Avataars

Cancer data genomics atlas study

American cancer journal of America

“Code and data are available upon request by email.”

I’m requesting the code from your recent paper in the journal....

The corresponding author’s inbox

999,999,565473

OPEN SOURCE

NEEDED!

56 of 158

Open source! Code is publicly available for reuse and repurpose

57 of 158

Oh no! My computer broke! – Good thing Github has all my work.

Back Ups! For the worst case scenario

58 of 158

Why did we write the code this way? I don’t remember… Good thing through git tracking I can look into this file’s history and remind myself how it became this.

Keep better records! Cut down on refinding the same thing

59 of 158

main

test analysis

main with test analysis added

time/work

Keep the “perfected” version safe! Free to experiment with easy restore capabilities

60 of 158

main

Avi’s changes added

Avi’s and Ruby’s changes added

Easier to work simultaneously with teammates!

No emailing files back and forth

61 of 158

Code is best done as a team activity!

62 of 158

Code is best done as a team activity!

If this isn’t an option – at least a fake person: aka AI

63 of 158

Why GitHub?

  • Open Source - Transparency and helping the community by sharing!

  • Version Controlled - Better records; better back ups; better teamwork!

  • Free

  • Popular (Bitbucket is fine too)

64 of 158

Activity 1: Git-ting familiar with branches

65 of 158

Go to the Website for the ITN Workshops for this conference: ��https://bit.ly/ITCR_2024

66 of 158

Create the repository for this activity

Let’s use this sandbox repository to practice GitHub things: https://github.com/fhdsl/reproducibility-sandbox

https://bit.ly/ITCR_2024

67 of 158

Getting familiar with the repository

68 of 158

69 of 158

70 of 158

Create your own copy of this repository

71 of 158

72 of 158

What’s a pull request?

A way to propose changes so that they can be discussed before they are incorporated

Real Life Example:

https://github.com/FredHutch/gimap/pull/33

73 of 158

Pull request model

Direct changes

Less verification

Knowledge silos more likely to happen

Mistakes may infiltrate the public version

Records of the decisions made may be more diffuse or nonexistent

More eyes to check the changes

More people know what’s happening

(Knowledge transfer)

Better chance of catching mistakes sooner

Better records of communication about the analysis/software

74 of 158

75 of 158

Open up GitHub Desktop

Log in to GitHub when prompted

76 of 158

Cloning our repository!

77 of 158

Image by Candace Savonen

remote repository = project that is stored on the internet

e.g. https://github.com/your-username/repository-name

local repository = project copy on your computer

e.g. ~/some-filepath/repository-name

repository-name

repository-name

78 of 158

Image by Candace Savonen

https://github.com/your-username/repository-name

~/yourfilepath/repository-name

clone = copy a remote repository to your local computer

repository-name

repository-name

79 of 158

Image by Candace Savonen

reproducible-R-example

the main branch = the main copy of your project

The main branch is curated, working, and always ready for others to use!

80 of 158

Window Juggling!

GitHub Desktop

81 of 158

Window Juggling!

Text editor

GitHub Desktop

82 of 158

Window Juggling!

Text editor

GitHub Desktop

Online GitHub

83 of 158

Window Juggling!

Text editor

GitHub Desktop

Online GitHub

Files

84 of 158

Window Juggling!

GitHub Desktop

Text editor

Online GitHub

Files

This part might differ for you!

85 of 158

OR it might look like this…

GitHub Desktop

86 of 158

Documentation about setting up a different default code editor:

GitHub Desktop

87 of 158

Image by Candace Savonen

Create a new branch! This will be your working copy

cd reproducibility-sandbox

git checkout -b “readme-edit”

GitHub Desktop

88 of 158

Image by Candace Savonen

repository-name

main

readme-edit

repository-name

We can do what we like with

readme-edit knowing that main will remain safe

89 of 158

Create an AI generated README

AI can be good at summarizing things!

90 of 158

Click on the Show in Finder button

91 of 158

Open up 01-heatmap.Rmd and copy all the text in the file

Text editor

Files

92 of 158

https://www.phind.com/

Go to Phind and ask it to write a readme from pasted text from 01-heatmap.Rmd

Text editor

Files

93 of 158

Get the results from Phind

Scroll to the bottom and click the squares to copy

Text editor

Files

94 of 158

Go to the text editor to open up

README.md

Text editor

Files

Paste the results from Phind into README.md

Save the README.md file after editing

95 of 158

Adding changes to a branch

GitHub Desktop

Go back to GitHub Desktop…

96 of 158

Image by Candace Savonen

The changes you make to any files in this repository should show up here

Type in a commit message

Click commit!

Check box

1.

2.

3.

4.

git add README.md

git commit -m “add stuff to README”

git push --set-upstream origin a-new-branch

GitHub Desktop

97 of 158

Image by Candace Savonen

push = add changes that are on a-new-branch

to the remote repository on GitHub

repository-name

repository-name

repository-name

https://github.com/

your-username/repository-name

98 of 158

Making the pull request

99 of 158

100 of 158

Image by Candace Savonen

repository-name

main

a-new-branch

repository-name

commits to a-new-branch

The version of the code that has a nifty improvement

A pull request will show the difference between main and a-new-branch so you scrutinize this feature before adding it to the main

101 of 158

Add some information about the changes in the PR and the reasoning for it

Check that the branches makes sense - should be merging into main automatically

102 of 158

Awesome you just made a pull request (PR)!

103 of 158

  1. Uploaded a project to GitHub
  2. clone that project to your computer

  • You have an update in mind.
  • Make a new branch to work off of.

  • Edit code as you normally would
  • add and commit the file changes to your branch
  • push the changes to your remote branch

Repeat 5 - 7 until it you’ve addressed the update you had in mind

  • Create a pull request

Only needs to be done once per repository/project!

104 of 158

Summary

  1. Create branch

2. Open file

3. Edit file

4. Add changes

5. Commit changes

6. Publish changes

7. Open PR

The check boxes

In your editor

In your editor

105 of 158

Command line summary

  • Clone the repo
  • Create branch
  • Open file
  • Edit file
  • Add changes
  • Commit changes
  • Publish changes
  • Open PR

git clone https://github.com/username/repo-name

git checkout -b “a-new-branch”

Use code editor

git add README.md

git commit -m “add stuff to README”

git push --set-upstream origin a-new-branch

Go to GitHub

106 of 158

Tips for reproducibility:

  • Write it down!
  • Organize and re-organize
  • Have everything* publicly available (GitHub)
  • Have others look it over (code review)
  • Automate monotonous stuff (CI/CD)
  • Managing computing environments (containers)

*Everything that doesn’t violate IRB privacy and ethical data handling guidelines

107 of 158

We don’t work alone!

Sometimes the collaborator with questions is “Future You”.

Readability >>>>> Cleverness

108 of 158

Image created by Candace Savonen using Avataars.

Ruby’s code

ERROR

Ruby’s code

Now Ruby

Future Ruby

109 of 158

DRY = Don’t Repeat Yourself

110 of 158

AI tools make it so even if you are a “lone programmer” you can still have a code review!

111 of 158

Variable A

Variable B

R = 0.893

This code runs well on my computer, let me email it to you!

So exciting!

112 of 158

Main goals of an original code author

  1. Set up your reviewer for success by erring toward overcommunicating

  • Interpret reviews positively!

  • Determine solutions collaboratively.

113 of 158

Ruby wants to merge 5 commits into main from a-new-branch

Reviewers

Avi

Code changes #10

I updated the project and added new files.

Owner

...

Ruby commented 10 minutes ago

  • 999100057849 - 1901

1870

0

10

2

Ummm… I’m a bit confused. Can you explain the context of these changes? This is a lot for me to try to follow. I’m also unsure what kind of feedback you are looking for.

Owner

...

Avi commented 8 minutes ago

Ruby requested a review from Avi 10 minutes ago

114 of 158

Ruby wants to merge 5 commits into main from a-new-branch

Reviewers

Avi

Update documentation for heatmap-script.R

Background

In this previous PR we updated the heatmap-script.R file. But now the documentation in the

README is out of date. This PR aims to update the README accordingly.

Approach

I updated the README with information on the new arguments we added. This also required me to update the Usage section and recommendations there.

Feedback needed

Can you look at the Usage section and try running the command and steps described there? I am concerned that this section is not clear enough but I am not sure how to add clarity. Please let me know if you have suggestions on this point.

Owner

...

Ruby commented 10 minutes ago

  • 50 - 19

1

0

2

2

Ruby this is great! I was able to dig into this and give you feedback at the places you asked. Let me know what you think of my ideas and comments!

Owner

...

Avi commented 8 minutes ago

Ruby requested a review from Avi 10 minutes ago

115 of 158

Image from https://phauer.com/2018/code-review-guidelines/

116 of 158

Main goals of a reviewer

  • Identify opportunities for learning and improvement.

  • Communicate these with positivity and empathy.

  • Determine solutions collaboratively.

117 of 158

Communication and empathy is an important part of effective code review!

118 of 158

Image from https://quickbirdstudios.com/blog/code-review-best-practices-guidelines/

Remember the author of the pull request has been putting time and effort into this!

119 of 158

This code needs work.

Don’t use the formattR package it’s inefficient and takes forever to run.

You didn’t style the last chunk of code.

Owner

...

Avi commented 8 minutes ago

Ruby requested a review from Avi 10 minutes ago

120 of 158

Ruby, thanks for all this work! This is a great start! I have a few questions so we can further polish this code.

  • Is your usage of the formattR package because of the weird formatting of the data.tsv file? Perhaps we can brainstorm another approach to this that would allow us to get rid of this package requirement.
  • I think that in your last chunk you may have forgotten to style the code according to the conventions for this repository. Perhaps we can discuss how we introduce something to help all authors of this repository adhere to the conventions. This may be an instance we can use automation or a checklist to help.

Owner

...

Avi commented 8 minutes ago

Ruby requested a review from Avi 10 minutes ago

121 of 158

Tips for reproducibility:

  • Write it down!
  • Organize and re-organize
  • Have everything* publicly available (GitHub)
  • Have others look it over (code review)
  • Automate monotonous stuff (CI/CD)
  • Managing computing environments (containers)

*Everything that doesn’t violate IRB privacy and ethical data handling guidelines

122 of 158

CI/CD:

Continuous Integration/

Continuous Deployment

– A software concept that is useful for reproducible data analyses!

123 of 158

Every time a change is proposed we check it before incorporating it

Change made Run a series of tests

CI/CD: Continuous Integration/ Continuous Deployment

124 of 158

I will re-run this analysis whenever changes are made to it.

125 of 158

Think smarter not harder: automation in a nutshell

126 of 158

Continuous integration / continuous deployment

You’re a construction manager

Should you:

  1. Check that your construction plans are good and meet safety and engineering standards as you build it?

OR

  • Build the entire building without consulting anyone and only have them check these things after you are done and its basically a demo job if you want to fix it?

127 of 158

Problems accumulate without using CI/CD

Time/Effort

Re-run

Re-run

A bug being introduced

3 bugs to track down!

128 of 158

Catching changes/problems early with CI/CD

Time/Effort

Re-run

Re-run

Re-run

Re-run

1 bug

1 bug

1 bug

129 of 158

Catching changes/problems early with CI/CD

R = 0.902

R = 0.902

R = 0.905

R = 0.902

Time/Effort

Re-run

Re-run

Re-run

Re-run

130 of 158

This is only the beginning!

  • Intro to Reproducibility
    • DRY code
    • Data organization
    • GitHub intro
  • Advanced Reproducibility
    • Intro to Containers
    • Intro to GitHub Actions
    • GitHub intermediate
    • Code review
  • Github Automation for Scientists
    • Principles of data sharing
    • CI/CD principles in science and analyses
    • GitHub Actions + Docker
  • Containers for Scientists STILL UNDER DEVELOPMENT

131 of 158

Activity 2: Navigating PR components

132 of 158

Activity 2a: Leaving inline comments

133 of 158

Return to your pull request on GitHub

134 of 158

Click the Files Changed tab

135 of 158

Click any plus sign to leave a comment

136 of 158

Click the “add a suggestion” button and add a change, then click “add single comment”

Then click Add single comment

137 of 158

Commit the new suggestion!

138 of 158

Go back to the Conversation tab

Scroll to the bottom.

You should see a new commit!

139 of 158

Activity 2c: Updating local branches

140 of 158

Click the Fetch origin button

141 of 158

Follow the prompt to pull origin

142 of 158

What happened? We can check the history.

We just got the change to the readme we did on GitHub, so it is now in our local version!

143 of 158

If we check the file on our computer now - it will show the change!

144 of 158

Activity 2b: Exploring GitHub Actions

145 of 158

Scroll to the bottom of your PR

146 of 158

This is a GitHub Action Log!

147 of 158

Activity 2d: Merge your PR

148 of 158

Go to the Conversations tab.

149 of 158

Scroll down and click the Merge button

150 of 158

You have now merged the new changes into the main branch!

151 of 158

Summary: what did we do overall?

  1. We got the project from Github and put it on our local computer- aka we “cloned” it
  2. We made a branch to develop some changes
  3. We made some changes to the readme file (using AI) and made them official for GitHub to notice - meaning we “committed and pushed” our changes to our new branch
  4. We made a pull request on GitHub so we could “review” and check our changes
  5. We made a change on GitHub (other people could do this!)
  6. We got that change back on our local computer - aka we “pulled” it

152 of 158

How confident do you feel about using GitHub and reproducibility skill sets *now*?

Click Present with Slido or install our Chrome extension to activate this poll while presenting.

153 of 158

How likely is this workshop to have a positive impact on your work?

Click Present with Slido or install our Chrome extension to activate this poll while presenting.

154 of 158

How likely would you be to recommend this workshop?

Click Present with Slido or install our Chrome extension to activate this poll while presenting.

155 of 158

What did you like most about the workshop?

Click Present with Slido or install our Chrome extension to activate this poll while presenting.

156 of 158

Please share any recommendations you have for improvements.

Click Present with Slido or install our Chrome extension to activate this poll while presenting.

157 of 158

Demographics Survey

158 of 158

If you are a presenter, go get a ribbon