14. How can I automate things with bash?#

Review the GitHub Action file that was used last lab as well as action workflow files in your kwl repo. Make note of what if any syntax in there is unfamilar.

Today our goal is to learn more about how those things work.

So far we have used bash commands to navigate our file system as a way to learn about the file system itself. To do this we used commands like:

  • pwd

  • cd

  • ls

  • mv

  • cp

  • rm

  • find

do you remember what each of those does?, no need to respond, just think through it for yourself

Bash is a unix shell for the GNU operating system and it has been adopted in other contexts as well. It is the default shell on Linux Ubuntu as well many others. This is why we learn about it here. GNU is a recursive acronym that stands for “GNU’s Not Unix”. It is a Unix-like completely free system

Use mermaid or the prismia drawing tool to visualize the relationship between the following terms:

  • bash

  • shell

  • terminal

  • git

flowchart TD shell --> |is accessed through| terminal bash --> |is instance of| shell zsh --> |is instance of| shell git --> |is a program accessed though any | shell git --> |commonly used with| bash git --> |commonly used with| zsh

A Unix shell is referring to both a command interpreter and a programming language. As a command interpreter, the shell provides the user interface to the rich set of GNU utilities. The programming language features allow these utilities to be combined.

Read the official definition of bash and a shell in the bash manual

flowchart TD subgraph shell pl[programming language] i[command interpreter] end

14.1. Inspecting an example script#

Today we will start by inspecting the github action file, first we’ll navigate to the folder.

cd OneDrive\Desktop\URI\CSC311\collab-activity

Next we’ll look at which files we have

ls .github/workflows/
generate_problem.yml

Let’s look at the file

cat .github/workflows/generate_problem.yml
name: Generate Problem

on:
  workflow_dispatch:
    inputs:
      problem_number:
        description: "Enter problem number (1, 2, or 3)"
        required: true
        type: choice
        options:
          - "1"
          - "2"
          - "3"
      programming_language:
        description: "Enter programming language (Python or C++)"
        required: true
        type: choice
        options:
          - "Python"
          - "Cpp"

jobs:
  setup_problem:
    runs-on: ubuntu-latest

    steps:

      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Debug - List files before renaming
        run: ls -lah


      - name: Reserve the old Readme file
        run: |
          mv README.md about.md
          ls -lah

      - name: Copy problem files to the main folder
        run: |
          PROBLEM_DIR=".github/Problems/Problem${{ github.event.inputs.problem_number }}/${{ github.event.inputs.programming_language }}"
          if [ -d "$PROBLEM_DIR" ]; then
            cp -r "$PROBLEM_DIR"/* "."
            echo "Problem file copied successfully."
          else
            echo "Error: Problem file does not exist!" && exit 1
          fi


      - name: Commit and push changes
        run: |
          git config user.name "github-actions"
          git config user.email "github-actions@github.com"
          git add .
          git commit -m "Add new problem files"
          git push


      - name: Create issue for the problem
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          ISSUE_FILE=".github/Problems/Problem${{ github.event.inputs.problem_number }}/issue.md"
          gh issue create \
            --title "Problem ${{ github.event.inputs.problem_number }}" \
            --body-file "$ISSUE_FILE"

We notice some lines that we are very familiar with. We see lines that mv and cp files. We also see a set of actions that will add, commit and push. So we see how we automate commands that we have used normally before on a terminal within this script to make it execute all these commands with the action run.

What features do you expect if something is a programming language?

14.2. Variables in Bash#

From the action files what do you think the syntax for a variable in bash is? Give an example by creating a variable called MYVAR with the value my_val

We can create variables

NAME='Ayman'

Do you see a variable declaration in the workflow script?

ISSUE_FILE=".github/Problems/Problem${{ github.event.inputs.problem_number }}/issue.md"

notice that there are no spaces around the =. spaces in bash separate commands and options, so they cannot be in variable declarations.

what is the syntax for using a variable? try them out and find which is correct, or use code inspection on your actionfile

  • [ ] NAME>

  • [x] $NAME

  • [ ] NAME$

  • [ ] NAME

echo NAME with a $ before the variable name.

echo $NAME
Ayman

A common mistake is to put a space around the = sign, this is actually considered good style in many other languages.

NAME = 'Ayman'
-bash: NAME: command not found

In bash, however, this creates an error. When there is a space after NAME, bash tried to interpet NAME as a bash command, but then it does not find it, so it gives an error.

Removing the space works again:

NAME='Ayman Sandouk'

This variable is local, in memory, to the current terminal window, so if we open a separate window and try echo $NAME it will not work. We can also see that it does not create any file changes.

ls
README.md  calculator.cpp  calculator.py  calculator.rs

We don’t see anything referring to the $NAME variable

We can, however use the variable at different working directories in the same terminal. So if we move

cd ../Spring2025/
echo $NAME
Ayman Sandouk

echo still works.

The $ is essential syntax for recalling variables in bash. If we forget it, it treats it as a literal

echo NAME
NAME

so we get the variable name out instead of the variable value

14.3. Environment Variables#

Environment variables are global among all termial windows.

A common one is the PATH

echo $PATH
/c/Users/ayman/bin:/mingw64/bin:/usr/local/bin:/usr/bin:/bin:/mingw64/bin:/usr/bin:/c/Users/ayman/bin:/c/Program Files/Python313/Scripts:/c/Program Files/Python313:/c/Program Files (x86)/Common Files/Oracle/Java/java8path:/c/Program Files (x86)/Common Files/Oracle/Java/javapath:/c/Program Files (x86)/VMware/VMware Workstation/bin:/c/Windows/system32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0:/c/Windows/System32/OpenSSH:/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/c/Program Files/NVIDIA Corporation/NVIDIA NvDLISR:/c/WINDOWS/system32:/c/WINDOWS:/c/WINDOWS/System32/Wbem:/c/WINDOWS/System32/WindowsPowerShell/v1.0:/c/WINDOWS/System32/OpenSSH:/c/Program Files/GitHub CLI:/c/ProgramData/chocolatey/bin:/cmd:/c/Program Files/dotnet:/c/Users/ayman/AppData/Roaming/Python/Python313/Scripts:/c/Users/ayman/.cargo/bin:/c/Users/ayman/AppData/Local/Microsoft/WindowsApps:/c/Users/ayman/AppData/Local/Programs/Microsoft VS Code/bin:/c/Users/ayman/AppData/Local/Pandoc:/c/Users/ayman/AppData/Local/Programs/Ollama:/c/Users/ayman/.dotnet/tools:/usr/bin/vendor_perl:/usr/bin/core_perl

mine shows multiple paths that will have packages installed in them, yours may be different

You can store environment variables to be set each time you start a terminal in your profile.

  • On MacOS this file is: ~/.bash_profile

  • on linux it is ~/.bashrc

  • For windows users you should also have ~/.bashrc

    • If you don’t have it you can create it with touch and edit it to add any global variables you want

cat ~/.bashrc
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac


# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth

# append to the history file, don't overwrite it
shopt -s histappend

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar

# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
        # We have color support; assume it's compliant with Ecma-48
        # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
        # a case would tend to support setf rather than setaf.)
        color_prompt=yes
    else
        color_prompt=
    fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    ;;
*)
    ;;
esac

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi

# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

# Add an "alert" alias for long running commands.  Use like so:
#   sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi
. "$HOME/.cargo/env"

A common one you might want to set is:

  • PS1 the primary prompt line. Content you can use is documented in the gnu docs

  • alias lets you set another name for a program, for exmaple I use pip to call pip3

nano ~/.bashrc
cat ~/.bashrc
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# Some aliases
alias pip=pip3
alias python=python3
alias cl=clear



# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth

# append to the history file, don't overwrite it
shopt -s histappend

# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar

# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac

# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
        # We have color support; assume it's compliant with Ecma-48
        # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
        # a case would tend to support setf rather than setaf.)
        color_prompt=yes
    else
        color_prompt=
    fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    ;;
*)
    ;;
esac

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    #alias dir='dir --color=auto'
    #alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi

# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'

# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

# Add an "alert" alias for long running commands.  Use like so:
#   sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

14.4. GH Actions as an example of scripts#

As seen, we use scripts to run a collection of commands together with one call/ run of that action

Check out the github action marketplace to see other actions that are available and try to get a casual level of understanding of the types of things that people use actions for.

14.5. Bash Loops#

We can also make loops like

for loopvar in list
do
# loop body
echo $loopvar
done

So, for example:

$ for name in Ayman madison greg sean
> echo $name
bash: syntax error near unexpected token `echo'

I’m got the “open loop” part wrong. Similar to how we use { in C & C++ or how we use : and indentation in Python. Bash has its own way of opening and closing a loop and that’s do & done

for name in Ayman madison greg sean
> do 
> echo $name
> done
Ayman
madison
greg
sean

Notes:

  • The > is not typed, it is what happens since the interpreter knows that after we write the first line, the command is not complete.

  • a list in bash is items with spaces, no brackets here (Ayman madison greg sean)

When we get the command back with the up arrow key, it puts it all on one line, because it was one command. The ; (semicolon) separates the “lines”

for name in Ayman madison greg sean; do echo $name; done

What if we wanted to run the loop on a large list? We can make the list into a variable

NAMES="Ayman madison sean greg tyler trevor"
for name in $NAMES
> do 
> echo $name
> done
Ayman
madison
sean
greg
tyler
trevor

14.6. Nesting commands#

We can take the output of a command and put it in a variable or directly use it like we would use a variable

Can you find an example of a command being using nested in any of your kwl action files?

If we looked at getassignment.yml We see a bunch of lines that we’ve edited and worked on before.

        # prepare badge lines
        pretitle="prepare-"$(cspt getbadgedate --prepare)
        cspt getassignment --type prepare | gh issue create --title $pretitle --label prepare --body-file -

We used a familiar command cspt getbadgedate to generate a variable

If we did this in our own terminals

cspt getbadgedate --prepare
2025-03-25

We get next class’ date. Notice how in the script we combine it with prepare- Let’s do the same thing in our terminal

pretitle="prepare-"$(cspt getbadgedate --prepare)

Now, let’s print the variable

echo $pretitle
prepare-2025-03-25

Let’s see how many files we have in this directory

ls
LICENSE      _prepare/     faq/         notes/
README.md    _review/      files.sh     references.bib
_config.yml  _static/      genindex.md  requirements.txt
_data/       _toc.yml      img/         resources/
_lab/        _worksheets/  index.md     syllabus/
_practice/   activities/   logo.png     systools.png

Can we use a loop to print out each file at a time?

We can run a command to generate the list and then use that list as a variable by putting it inside $() to run that command first.

Let’s move to inclass repo

cd ~/Documents/systems/gh-inclass-AymanBx
for file in $(ls)
> do 
> echo $file
> done
API.md
CONTRIBUTING.md
LICENSE.md
README.md
about.md
abstract_base_class.py
alternative_classes.py
docs/
helper_functions.py
important_classes.py
my_secrets/
philosophy.md
scratch.ipynb
setup.py
tests/

the $() tells bash to run that command first and then hold its output as a variable for use elsewhere

Find a use of this in your experience report actions

We can modify what is in the $():

for file in $(ls -a); do  echo $file; done
./
../
.git/
.github/
.gitignore
.secrets
API.md
CONTRIBUTING.md
LICENSE.md
README.md
about.md
abstract_base_class.py
alternative_classes.py
docs/
helper_functions.py
important_classes.py
my_secrets/
philosophy.md
scratch.ipynb
setup.py
tests/

14.7. Conditionals in bash#

What are other programming language feature we would expect from a programming language like bash?

We can also do conditional statements

if test -f docs
> then
> echo "file"
> fi 

the key parts of this:

  • test checks if a file or directory exists

  • the -f option makes it check if the item is a file

  • what to do if the condition is met goes after a then keyword

  • the fi (backwardsif) closes the if statment

Once again, similar to other programming languages. In bash to open and close an if statement we use if, then and fi to close the if statement

This outputs nothing because docs is a directory not a file.

If we switch it, we get output:

if test -f README.md; then echo "file"; fi 

We can put the if inside of the loop.

Once we put then in, it works:

for file in $(ls)
> do
>   if test -f $file
>   then
>       echo $file
>   fi
> done

14.8. Script files#

We can put our script into a file to automate more that one step all in one call

nano filecheck.sh 

Let’s get creative

# Introduction
echo "Hello and welcome to your first script"

echo "Hello world!"

# Now listing files only
for file in $(ls -a)
do
    if test -f $file
    then
        echo $file" was found"
    fi
done

# Farewell
echo
echo "Goodbye!"

We can see that that file lives in out repo now

ls
API.md                  filecheck.sh
CONTRIBUTING.md         helper_functions.py
LICENSE.md              important_classes.py
README.md               my_secrets/
about.md                philosophy.md
abstract_base_class.py  scratch.ipynb
alternative_classes.py  setup.py
docs/                   tests/

and run it with bash <filename>

bash filecheck.sh 
Hello and welcome to your first script
Hello world!
.gitignore was found
.secrets was found
API.md was found
CONTRIBUTING.md was found
LICENSE.md was found
README.md was found
about.md was found
abstract_base_class.py was found
alternative_classes.py was found
filecheck.sh was found
helper_functions.py was found
important_classes.py was found
philosophy.md was found
scratch.ipynb was found
setup.py was found

Goodbye!
cat filecheck.sh 
# Introduction
echo "Hello and welcome to your first script"

echo "Hello world!"

# Now listing files only
for file in $(ls -a)
do
    if test -f $file
    then
        echo $file" was found"
    fi
done

# Farewell
echo
echo "Goodbye!"

Remember, extensions from a computer’s prespective don’t matter. We use them only for us a humans to be able to tell what a file represents

mv filecheck.sh filecheck
bash filecheck
Hello and welcome to your first script
Hello world!
.gitignore was found
.secrets was found
API.md was found
CONTRIBUTING.md was found
LICENSE.md was found
README.md was found
about.md was found
abstract_base_class.py was found
alternative_classes.py was found
filecheck was found
helper_functions.py was found
important_classes.py was found
philosophy.md was found
scratch.ipynb was found
setup.py was found

Goodbye!

It ran no problem!

14.9. gh CLI operations#

When you are working sometimes it is helpful to be able to manipulate (or create) issues, pull requests or even releases from the command line.

This is how I post announcements. I work on the notes (a markdown file) in vs code and then I use the vscode terminal to commit, push, create a tag, and create a release. I can post the notes and notify you all that they are posted without leaving VScode at all; this makes it much simpler/faster than it would be using Brightspace

We can also search and filter them by piping the output to grep which searches the contents of a file (including stdin). We previously searched the file names with find. So find searches the paths that exist and grep actually reads the contents of the files, it does so faster than many other languages would be.

cd ~/Documents/systems/spring25-kwl-AymanBx
gh issue list -s all
Showing 30 of 57 issues in compsys-progtools/spring25-kwl-AymanBx that match your search

#62  review-2025-02-20  review            about 8 hours...
#61  practice-2025-...  practice          about 8 hours...
#60  prepare-2025-0...  prepare           about 8 hours...
#59  prepare-2025-0...  prepare           about 2 days ago
#58  Lab 6                                about 2 days ago
#57  Lab 6                                about 2 days ago
#56  practice-2025-...  practice, due     about 6 days ago
#55  review-2025-03-06  review, due       about 6 days ago
#54  prepare-2025-0...  prepare, due      about 1 day ago
#53  practice-2025-...  practice, exp...  about 1 day ago
#52  review-2025-03-04  review, expired   about 1 day ago
#51  prepare-2025-0...  prepare, due      about 6 days ago
#50  prepare-2025-0...  prepare, expired  about 1 day ago
#49  Lab 5                                about 16 days...
#48  practice-2025-...  practice, exp...  about 8 days ago
#47  review-2025-02-25  review, expired   about 8 days ago
#46  prepare-2025-0...  prepare, expired  about 6 days ago
#45  test                                 about 22 days...
#44  Lab 4                                about 23 days...
#43  review-2025-02-20  review, expired   about 13 days...
#42  practice-2025-...  practice, exp...  about 13 days...
#41  prepare-2025-0...  prepare, expired  about 8 days ago
#40  practice-2025-...  practice, exp...  about 13 days...
#39  review-2025-02-20  review, expired   about 13 days...
#38  prepare-2025-0...  prepare, expired  about 8 days ago
#37  review-2025-02-13  review, expired   about 20 days...
#36  practice-2025-...  practice, exp...  about 20 days...
#35  Lab 3                                about 28 days...
#34  practice-2025-...  practice, exp...  about 15 days...
#33  review-2025-02-18  review, expired   about 15 days...

grep can be used with pattern matching as well

gh issue list -s all | grep "Lab"
58      OPEN    Lab 6           2025-03-17 19:26:28 +0000 UTC
57      OPEN    Lab 6           2025-03-17 18:50:52 +0000 UTC
49      OPEN    Lab 5           2025-03-03 19:21:55 +0000 UTC
44      OPEN    Lab 4           2025-02-24 19:48:33 +0000 UTC
35      OPEN    Lab 3           2025-02-19 19:53:10 +0000 UTC

Learning more about grep is a good explore badge topic

14.10. Badge Hints#

Here are the options:

  • See the options for gh pr list.

  • Use two strategies for what you are the author and when you are the reviewer

  • Try the json option on gh pr list and see how it can help you

  • I use bash in the your experience badge action to make a file with a date in the file name

  • You can run a file from different locations

14.11. Experience Report Evidence#

14.12. Prepare for Next Class#

  1. Read the notes from March 18th. We will build on these directly in the future. You need to have the test repo with the same status as me

  2. Add to your IDE idethoughts.md file if you have not in a few days on a dedicated ide_prep branch. This is prep for after a few weeks from now, not for 03/25; keep this branch open until it is specifically asked for

    • I have not posted an outline for idethoughts.md. Start with sections like preference, debugging metods, organizations, tools/extentions Add any other thoughts on using different IDEs you can think of. These sections are not limiting nor are they mandated

14.13. Badges#

  1. Update your KWL Chart learned column with what you’ve learned

  2. write a bash script to make it so that cating the the files in your gh_inclass repo does not make the prompt move

  1. Update your KWL Chart learned column with what you’ve learned

  2. prevent badges.json and badges.yml from being tracked by git in your kwl repo

  3. write a bash script that prevents jupyter-book from giving warnings about files not having a heading by using the file name as a temporary title. (see the badge from 03/04 where you should have converted your repo, or do that one first, this counts as an extension on that if you have not done it)

Hint: Use sed’s insert option and head as needed.

Explore idea

modify your script to use a small llm from ollama to automatically insert a sensible title by summarizing the file. using a commercial chat interface does not qualify, but using an llm locally does

  1. Write a bash script that updates your badges.json file and then generates your progress report using courseutils and posts it as an issue we will use this in lab next week

  2. Write a bash script generates a progress report and computes your current grade using courseutils and posts it as an issue we will use this in lab next week

hint you might use a temp file that you would also not want to track

14.14. Questions#