Non-interactive scripts




pip install packages inside of your Dockerfile
environment.yml file for documentation purposes# build on top of template of minimal notebook
FROM quay.io/jupyter/minimal-notebook:afe30f0c9ad8
# copy all conda environment dependencies
COPY conda-linux-64.lock /tmp/conda-linux-64.lock
# conda install all the other packages
RUN mamba update --quiet --file /tmp/conda-linux-64.lock \
&& mamba clean --all -y -f \
&& fix-permissions "${CONDA_DIR}" \
&& fix-permissions "/home/${NB_USER}"
# install openai using pip
RUN pip install openai==1.57.0π«£ Here is a shameless bad example of what happens when you donβt use standardized, well-organized repository structure:
docker-compose file?-(A) To create and customize our own docker
-(B) To easily launch and stop our docker container in one command
-(C) To document the packages we used so that we can easily share with others
-(D) To prepare for publishing our docker image on Docker Hub
-(E) To make our life harder π€·ββοΈ
Image generated by OpenAI GPT-5 and Canva
Image generated by OpenAI GPT-5 and Canva
docker run command is too LONG!βImage generated by OpenAI GPT-5 and Canva
Image generated by OpenAI GPT-5 and Canva
Image generated by OpenAI GPT-5 and Canva
git pull to get the latest updates.python update_enviroment_yml.py --root_dir="." --env_name="ai_env" --yml_name="environment.yml"| Aspect | REPL (e.g., Jupyter Notebook) | Scripts |
|---|---|---|
| Execution | Interactive, line-by-line or cell-by-cell | Batch mode, top to bottom |
| Best for | Solving small problems, developing code, exploratory analysis | Automation, production workflows, reproducible pipelines |
| Advantages | Immediate feedback, easy for small problems and experiments | Efficiency, automation, reusability, reproducibility |
| Examples | R/Python console, Jupyter Notebook cells | .py, .R files run from command line |
| Complexity | Can become messy with large analyses | Better for complex, modular workflows |
| Debugging | Harder with non-linear execution | Easier with linear, modular code |
@click.option()?if __name__ == "__main__": at the end?Readability: Your collaborators, future users, and future you will thank you for writing clear and concise docstrings. π
Good docstring should be both human-readable and machine-readable.
Python Example:
R roxygen2 Documentation Example:
click package in Python to parse command line argumentsCreate a new python script called otter_greeting.py:
click package in Python to parse command line argumentsLetβs use options instead of arguments to parse command line arguments:
import click
@click.command()
@click.option('--count', type=int, default=1, help='Number of greetings.')
@click.option('--name', type=str, prompt='Your name', help='The person to greet.')
def hello(count, name):
"""Simple program that greets NAME for a total of COUNT times."""
for x in range(count):
click.echo(f"π¦¦: `Nice to meet you, {name}!`")
if __name__ == '__main__':
hello()click!"""Otter Greeting Generator
This script allows you to greet otters with different levels of enthusiasm.
"""
import click
@click.command()
@click.option('--count', default=1, help='Number of otter greetings.')
@click.option('--name', prompt='Your name', help='The person to greet.')
@click.option('--enthusiasm', type=click.Choice(['low', 'medium', 'high']),
default='medium', help='How enthusiastic should the otters be?')
def greet_otters(count, name, enthusiasm):
""" Otter greeting generator
Simple program that has adorable otters greet NAME for COUNT times. π¦¦
Parameters
----------
count : int
Number of otter greetings to display. Must be a positive integer.
Default is 1.
name : str
The name of the person to greet. Will be prompted if not provided
via command line.
enthusiasm : {'low', 'medium', 'high'}
The enthusiasm level of the otter greetings:
- 'low': Simple, calm greeting
- 'medium': Friendly greeting with some emojis
- 'high': Very excited greeting with lots of emojis and caps
Default is 'medium'.
Returns
-------
None
Outputs greetings directly to the console using click.echo().
Examples
--------
Run from command line:
>>> python otter_greeting.py --name "Oyster" --count 3 --enthusiasm high
This will display 3 highly enthusiastic otter greetings for Oyster.
"""
# Different enthusiasm levels
emojis = {
'low': 'π¦¦',
'medium': 'π¦¦β¨',
'high': 'π¦¦ππ'
}
messages = {
'low': f"hello {name}.",
'medium': f"Hello {name}! π",
'high': f"HELLO {name.upper()}!!! Who is that lovely, amazing, genius friend over there?? The otters are SO excited to see you! π"
}
click.echo(f"\n{emojis[enthusiasm]} Otter Greetings Incoming! {emojis[enthusiasm]}\n")
for i in range(count):
click.echo(f" Otter #{i+1}: {messages[enthusiasm]}")
click.echo(f"\n𦦠You've been greeted by {count} friendly otter(s)! π¦¦\n")
if __name__ == '__main__':
greet_otters()Note
if __name__ == "__main__": lets you source the other functions in the script without running the main function.click commands need to be placed right above the main function.Example:
# import libraries/packages
import click
# parse/define command line arguments below
# define main function
@click.command()
@click.argument('num1', type=int)
@click.argument('num2', type=int)
def main(num1, num2):
"""Simple program that adds two numbers."""
result = num1 + num2
click.echo(f"The sum of {num1} and {num2} is {result}")
# call main function
if __name__ == '__main__':
main()docopt packageExample:
"This script greets you with adorable otters! π¦¦
Usage: greet_otters.R --name=<name> [--count=<count>]
Options:
--name=<name> Your name (the person to greet)
--count=<count> Number of otter greetings [default: 1]
" -> doc
library(docopt)
opt <- docopt(doc)
main <- function(name, count) {
# Convert count to numeric (docopt returns strings)
count <- as.numeric(count)
# Generate otter greetings
cat("\n𦦠Otter Greetings Incoming! π¦¦\n\n")
for (i in 1:count) {
cat(paste0(" Otter #", i, ": Hello ", name, "! π\n"))
}
cat(paste0("\n𦦠You've been greeted by ", count, " friendly otter(s)! π¦¦\n\n"))
}
main(opt$name, opt$count)