Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 93 additions & 131 deletions 01-Seminar.Rmd

Large diffs are not rendered by default.

Binary file modified images/directory_tree.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
217 changes: 129 additions & 88 deletions intro_to_command_line_slides.html

Large diffs are not rendered by default.

104 changes: 49 additions & 55 deletions intro_to_command_line_slides.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ output-location: fragment

. . .

- What is DaSL?
- What is [DaSL](https://hutchdatascience.org/)?

. . .

Expand All @@ -30,8 +30,6 @@ output-location: fragment

- What you want to get out of the workshop

- Favorite spring activity?

## Goals of the workshop

. . .
Expand All @@ -48,11 +46,11 @@ output-location: fragment

. . .

- Use a text editor in the command line
- Analyze the components of a shell command: what are the possible inputs, options, and outputs, and where to find documentation for help.

. . .

- Treat text-based programs as functions
- Apply what we learned to a demo: bioinformatics tool

## Ways we can interact with a computer:

Expand Down Expand Up @@ -98,12 +96,12 @@ However, the way a computer interprets and executes instructions are based on te

## Getting started

We will be using replit, a online coding interface to access the command line.
We will be using Posit Cloud, a online coding interface for R, but it has a built-in Command Line.

- Go to the project [https://replit.com/\@clo22/CommandLineDaSL](https://replit.com/@clo22/CommandLineDaSL)
- Click "Fork" on the right hand side of the screen.
- Create an account or sign-in.
- Click on the "Shell" tab.
- Go to the project: <https://posit.cloud/spaces/622776/join?access_code=602ukbDJCZ0h366T6ktC3IDvbiWtZdmxKeSERdYq>
- Create an account or sign-in.
- Open "[Intro_to_Command_Line_practice](https://posit.cloud/spaces/622776/content/9888837)"
- Click on the "Terminal" tab.

## Interacting with the command line, a perspective

Expand All @@ -117,7 +115,7 @@ We will be using replit, a online coding interface to access the command line.

. . .

- It is forgiving, and encourages exploration and experimentation.
- It is (mostly) forgiving, and encourages exploration and experimentation.

::: notes
Unlike a GUI, the CLI does not provide immediate options to you to interact with. We have to know a learn a handful of vocabulary to interact with it well. But besides the vocabulary, we need to keep a mental model of a task we want to complete. In GUIs that that mental model is shown to us visually, such as a file browser.
Expand All @@ -133,15 +131,13 @@ Lastly, the CLI is forgiving. It will tell you if you did something you did not

On our computer, the **directory tree** organizes files and directories in an (upside down) tree-like structure. In each folder, there is a parental directory, and there can be files and directories within it.

![Replit directory tree](images/directory_tree.png)

Example: special "home" **directory path**: `/home/runner/`
![Posit Cloud directory tree](images/directory_tree.png)

## Basic directory tree navigation

. . .

![Replit directory tree](images/directory_tree.png){width="400"}
![Posit Cloud directory tree](images/directory_tree.png)

. . .

Expand All @@ -153,27 +149,33 @@ Example: special "home" **directory path**: `/home/runner/`

. . .

- `cd /home/runner` changes directory to the special "home" directory.
- `cd /cloud/project` is where we started.

## Absolute vs. relative paths

![](images/directory_tree.png){alt="Posit Cloud directory tree"}

Suppose you want to access the folder `input_files`.

. . .

- The **absolute directory path** specifies the directory from the root directory `/`
- The **absolute directory path** specifies the directory from the root directory: `/cloud/project/input_files`

. . .

- The **relative directory path** is a path *relative to our current directory*.
- The **relative directory path** is a path *relative to our current directory*: if we are currently at `/cloud/project`, the relative path is `input_files` .

- The symbol `..` specifies the parent directory.
. . .

- The symbol `..` specifies the parent directory. If we are currently at `/cloud/project/software`, the relative path is `../input_files`.

. . .

- `ls` lists all the files in the current directory.

## Exercise: explore the `project` folder

Use `cd` and `ls` to explore `/home/runner/CommandLineDaSL/project`
Use `cd` and `ls` to explore `/cloud/project`

. . .

Expand All @@ -191,60 +193,50 @@ Commands to look at text files:

Hit `Ctrl-C` to stop a running program.

## Mental Model 2: Treat text-based commands as functions
## Mental Model 2: Treat commands as functions

. . .
A **function** is a tool that you can use over and over again:

The commands you have been using, `pwd`, `cd`, `ls`, and `cat` are actually computer programs!
- It can take in inputs

. . .
- Does something

When using a command from the command line, we should treat it as a function: a command has a **name**, inputs in terms of **arguments** and/or **options**, and **returns** something.
- and can give an output.

. . .

![Source: Wellesley CS 110: https://cs.wellesley.edu/\~cs110/lectures/L16/images/function.png](https://cs.wellesley.edu/~cs110/lectures/L16/images/function.png)
The commands you have been using, `pwd`, `cd`, `ls`, and `cat` can be viewed as functions.

- It can take in **input arguments**, **options**

- Does something

- and can give an output

## `ls` example

. . .

A command's usage can have any of the following combination:

- Input arguments
- Options
- Options with its own required input arguments
- Input argument
- `ls /cloud/project`

. . .

![Source: Software Carpentry: https://swcarpentry.github.io/shell-novice/fig/shell_command_syntax.svg](https://swcarpentry.github.io/shell-novice/fig/shell_command_syntax.svg)
- Options
- `ls -l`

. . .

Input arguments:

```
~/CommandLineDaSL$ ls /
bin boot dev etc home inject io lib lib32 lib64 libx32 media mnt nix opt proc repl root run sbin srv store sys tmp usr var
```
- Options with input argument
- `ls -l /cloud/project`

. . .

Input arguments and options:

```
~/CommandLineDaSL$ ls / -F
bin@ dev/ home/ io/ lib32@ libx32@ mnt/ opt/ repl/ run/ srv/ sys/ usr/
boot/ etc/ inject/ lib@ lib64@ media/ nix/ proc/ root/ sbin@ store/ tmp/ var/
```

::: notes
This displays a slash ('/') immediately after each pathname that is a directory, and ('\@') after a symbolic link (not important to know right now).

It is sometimes easy to overlook that the text printed from a command like `ls` is indeed the returned output from the program. It is important to keep this in mind when we start to use multiple commands together later in this seminar.
- Multiple input arguments

Subcommands
:::
- `sh my_script.sh –i my_input.txt -o my_output.txt`

## What are the possible options and arguments for a command?

Expand Down Expand Up @@ -288,18 +280,14 @@ Here are some commands that allows you to create, move, copy, and delete files a

- `mkdir [folderPath]` creates a new folder at the path specified by `[folderPath]`.

- `rm [path]` deletes a file at `[path]`. `rm -r [folder]` deletes a folder and its subcontents. Cannot be undone!
- `rm [path]` deletes a file at `[path]`. `rm -r [folder]` deletes a folder and its subcontents. Cannot be undone! 😱

## Demo

. . .

- `*` wildcard

## Using a text editor in CLI

A commonly used task in CLI is to edit text files. `nano`, `vim`, and `emacs` are the three most popular ones, in increasing learning curve but also complexity in the tasks you can perform. We will start with `nano` today.

## Running software in CLI

Putting it all together, let's run a (fake) software that aligns sequencing reads to the reference genome.
Expand Down Expand Up @@ -332,3 +320,9 @@ The `python aligner.py` command seems pretty messy - it just dumps an aligned se
. . .

- Pipe the output into the next command: `python aligner.py --reference [reference genome fasta file] --input [unaligned sequences fastq file] | head`

## Accessing the Command Line on your computer

- Macs: `/Applications/Utilities/Terminal.app`

- Windows: Powershell or Windows Command Prompt gives a *different* flavor of the command line. To use the Unix command line, [install Windows Subsystem for Linux](https://learn.microsoft.com/en-us/windows/wsl/install).

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1 +1 @@
/*# sourceMappingURL=0a6b880beb84f9b6f36107a76f82c5b1.css.map */

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.

Large diffs are not rendered by default.

Empty file.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ window.QuartoLineHighlight = function () {
divSourceCode.forEach((el) => {
if (el.hasAttribute(kCodeLineNumbersAttr)) {
const codeLineAttr = el.getAttribute(kCodeLineNumbersAttr);
el.removeAttribute("data-code-line-numbers");
el.removeAttribute(kCodeLineNumbersAttr);
if (handleLinesSelector(deck, codeLineAttr)) {
// Only process if attr is a string to select lines to highlights
// e.g "1|3,6|8-11"
Expand Down Expand Up @@ -165,17 +165,17 @@ window.QuartoLineHighlight = function () {
if (typeof highlight.last === "number") {
spanToHighlight = [].slice.call(
codeBlock.querySelectorAll(
":scope > span:nth-child(n+" +
":scope > span:nth-of-type(n+" +
highlight.first +
"):nth-child(-n+" +
"):nth-of-type(-n+" +
highlight.last +
")"
)
);
} else if (typeof highlight.first === "number") {
spanToHighlight = [].slice.call(
codeBlock.querySelectorAll(
":scope > span:nth-child(" + highlight.first + ")"
":scope > span:nth-of-type(" + highlight.first + ")"
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ window.QuartoSupport = function () {
return /print-pdf/gi.test(window.location.search);
}

// helper for theme toggling
function toggleBackgroundTheme(el, onDarkBackground, onLightBackground) {
if (onDarkBackground) {
el.classList.add('has-dark-background')
} else {
el.classList.remove('has-dark-background')
}
if (onLightBackground) {
el.classList.add('has-light-background')
} else {
el.classList.remove('has-light-background')
}
}

// implement controlsAudo
function controlsAuto(deck) {
const config = deck.getConfig();
Expand Down Expand Up @@ -111,8 +125,19 @@ window.QuartoSupport = function () {
}
}

// add footer text
function addFooter(deck) {
// tweak slide-number element
function tweakSlideNumber(deck) {
deck.on("slidechanged", function (ev) {
const revealParent = deck.getRevealElement();
const slideNumberEl = revealParent.querySelector(".slide-number");
const onDarkBackground = Reveal.getSlideBackground(ev.indexh, ev.indexv).classList.contains('has-dark-background');
const onLightBackground = Reveal.getSlideBackground(ev.indexh, ev.indexv).classList.contains('has-light-background');
toggleBackgroundTheme(slideNumberEl, onDarkBackground, onLightBackground);
})
}

// add footer text
function addFooter(deck) {
const revealParent = deck.getRevealElement();
const defaultFooterDiv = document.querySelector(".footer-default");
if (defaultFooterDiv) {
Expand All @@ -127,13 +152,17 @@ window.QuartoSupport = function () {
prevSlideFooter.remove();
}
const currentSlideFooter = ev.currentSlide.querySelector(".footer");
const onDarkBackground = Reveal.getSlideBackground(ev.indexh, ev.indexv).classList.contains('has-dark-background')
const onLightBackground = Reveal.getSlideBackground(ev.indexh, ev.indexv).classList.contains('has-light-background')
if (currentSlideFooter) {
defaultFooterDiv.style.display = "none";
const slideFooter = currentSlideFooter.cloneNode(true);
handleLinkClickEvents(deck, slideFooter);
deck.getRevealElement().appendChild(slideFooter);
toggleBackgroundTheme(slideFooter, onDarkBackground, onLightBackground)
} else {
defaultFooterDiv.style.display = "block";
toggleBackgroundTheme(defaultFooterDiv, onDarkBackground, onLightBackground)
}
});
}
Expand Down Expand Up @@ -272,6 +301,23 @@ window.QuartoSupport = function () {
}
}

function handleWhiteSpaceInColumns(deck) {
for (const outerDiv of window.document.querySelectorAll("div.columns")) {
// remove all whitespace text nodes
// whitespace nodes cause the columns to be misaligned
// since they have inline-block layout
//
// Quarto emits no whitespace nodes, but third-party tooling
// has bugs that can cause whitespace nodes to be emitted.
// See https://github.com/quarto-dev/quarto-cli/issues/8382
for (const node of outerDiv.childNodes) {
if (node.nodeType === 3 && node.nodeValue.trim() === "") {
outerDiv.removeChild(node);
}
}
}
}

return {
id: "quarto-support",
init: function (deck) {
Expand All @@ -280,11 +326,13 @@ window.QuartoSupport = function () {
fixupForPrint(deck);
applyGlobalStyles(deck);
addLogoImage(deck);
tweakSlideNumber(deck);
addFooter(deck);
addChalkboardButtons(deck);
handleTabbyClicks();
handleSlideChanges(deck);
workaroundMermaidDistance(deck);
handleWhiteSpaceInColumns(deck);
},
};
};