Missing-Semester-Notes

Lecture Notes: Missing Semester for your CS education

Introduction

Missing Semester of Your CS education

Welcome to the course: The Missing Semester of Your CS Education!

When I first learned about this course at the beginning of my freshman year, I had no concept of command lines, development, and other related topics. Additionally, since the course was taught entirely in English, I tried attending a few lectures but eventually gave up, and my absorption rate was also low. During this winter break, after a semester of experience in my freshman year, I installed the WSL subsystem and mastered the most basic Bash knowledge. When I revisited this course, I felt a sudden clarity. Now, the command line has become a tool I frequently use, greatly improving my learning and development efficiency. Therefore, I will organize my Missing Semester notes in this blog, hoping to inspire and help future learners.

Before starting the learning exploration, I strongly recommend you to ensure all these questions and contents below are carefully read, which will help you gain a better learning experience.

Where to find the course?

On YouTube: https://www.youtube.com/@MissingSemester

The course also has its own websites for clear lecture notes!

For domestic users, you can browse Bilibili for reposting of the original course and Chinese subtitle translation.

What’s this course about?

Let’s take a look at how the course instructor evaluates the positioning of this course.

Missing semester Lec1 Beginning- The overall introduction of this course

This class stems from an observation that Anish, Jose, and I have made while attending various classes at MIT. The observation is that, as computer scientists, we all know that computers are great at performing repetitive tasks and automating things. However, we often fail to realize that there are many tools that can make our own development processes better. We can be much more efficient in how we use our computers because we can use the computer as a tool for ourselves, not just for building websites or software. This class is an attempt to address this issue. It is an attempt to show you some of the tools that you can use to great effect in your day-to-day work, in your research, and in your studies. It’s going to be a class where we want to teach you both how to make the most of the tools that you already know and, hopefully, introduce you to some tools that you don’t know yet. We also want to show you how to combine these tools to produce more powerful results than you might think possible with what you know today.

Chinese Translation:

这门课程源于Anish、Jose和我在MIT参加各种课程时的一个观察。我们发现,作为计算机科学家,我们都知道计算机非常擅长执行重复性任务和自动化工作。然而,我们常常没有意识到,有许多工具可以让我们的开发过程变得更好。我们可以更高效地使用计算机,因为我们可以将计算机作为我们自己的工具,而不仅仅是用来构建网站或软件。这门课程旨在解决这个问题。它试图向你展示一些可以在日常工作、研究和学习中高效使用的工具。这门课程的目标是教你如何充分利用你已经知道的工具,同时也希望向你介绍一些你以前不知道的工具,并展示如何将这些工具结合起来,产生比你今天所知道的更强大的结果。

So this lecture is for Tool-using during your CS education. Several Tools can be seen in the subtitle of each courses.

Am I ready to take the course?

However, I am unwilling to announce the fact that: This course is not suitable for Totally-Green-Hand.🙂‍↕️🙂‍↕️🙂‍↕️ Here are two following reasons I have summarized:

  • The course progresses very quickly. If you have no prior knowledge of these concepts, there’s a high chance you won’t keep up with the pace! Although you can pause while learning on video platforms, previewing the basic knowledge before taking the course can provide a better learning experience.
  • In learning tools, practice is a very important component. This course mainly focuses on lectures and lacks opportunities for hands-on practice.

Thus, I strongly recommend you to do such things before entering the courses:

  • Make sure you have installed command-line environment before the course begins! (Most important)

    • MacOS or Linux is preferred.
    • WSL for Windows

    While learning the course content, practice hands-on operations simultaneously!

    Still updating~

Lec1-2: Shell Tools and Scripting

$ in Bash

In Bash, $ has special meanings:

  1. Variable Reference: Access variable values ($var).
  2. Special Variables:
    • $0: Script name.
    • $1-$9: Script arguments.
    • $?: Exit status of the last command.
    • $$: Current script’s PID.
  3. Command Substitution: Capture command output ($(command)).
  4. Arithmetic Operations: Perform math ($((expression))).
  5. Environment Variables: Access ($HOME, $PATH).

Here $1 is the first argument to the script/function. Unlike other scripting languages, bash uses a variety of special variables to refer to arguments, error codes, and other relevant variables. Below is a list of some of them. A more comprehensive list can be found here.

  • $0 - Name of the script
  • $1 to $9 - Arguments to the script. $1 is the first argument and so on.
  • $@ - All the arguments
  • $# - Number of arguments
  • $? - Return code of the previous command
    • If the previous command execute successfully, the arguments will probably return 0.
    • If it fails, it will return none-0 value.
  • $$ - Process identification number (PID) for the current script
  • !! - Entire last command, including arguments. A common pattern is to execute a command only for it to fail due to missing permissions; you can quickly re-execute the command with sudo by doing sudo !!
  • $_ - Last argument from the last command. If you are in an interactive shell, you can also quickly get this value by typing Esc followed by . or Alt+.

find command

find is a very powerful command-line tool used to search for files and directories in a directory tree. It supports a large number of parameters and options, allowing searches based on file name, type, size, time, permissions, and many other conditions. Below are some commonly used find parameters and options, categorized by functionality:

  • .: Start searching from the current directory.
  • /path/to/dir: Start searching from the specified directory.

2. Search by File Name

  • -name "pattern": Match file names (case-sensitive).
    • Example: find . -name "*.txt" finds all .txt files.
  • -iname "pattern": Match file names (case-insensitive).
    • Example: find . -iname "readme*" finds all README, readme, etc. files.
  • -regex "pattern": Match file names using regular expressions.
    • Example: find . -regex ".*\.txt$" finds all files ending with .txt.

3. Search by File Type

  • -type f: Find regular files.
  • -type d: Find directories.
  • -type l: Find symbolic links.
  • -type s: Find socket files.
  • -type p: Find named pipes (FIFO).
  • -type c: Find character device files.
  • -type b: Find block device files.

4. Search by File Size

  • -size +n: Find files larger than n.
  • -size -n: Find files smaller than n.
  • -size n: Find files exactly n in size.
    • Units can be:
      • c: Bytes (default).
      • k: Kilobytes.
      • M: Megabytes.
      • G: Gigabytes.
    • Example: find . -size +100M finds files larger than 100MB.

5. Search by Time

  • -mtime n: Find files modified n days ago.
    • -mtime +n: Files modified more than n days ago.
    • -mtime -n: Files modified within the last n days.
  • -atime n: Find files accessed n days ago.
  • -ctime n: Find files whose status (e.g., permissions or ownership) changed n days ago.
  • -mmin n: Find files modified n minutes ago.
    • -mmin +n: Files modified more than n minutes ago.
    • -mmin -n: Files modified within the last n minutes.
  • -amin n: Find files accessed n minutes ago.
  • -cmin n: Find files whose status changed n minutes ago.

6. Search by Permissions

  • -perm mode: Find files with permissions exactly matching mode.
    • Example: find . -perm 644 finds files with permissions 644.
  • -perm -mode: Find files with permissions including mode.
    • Example: find . -perm -u=r finds files readable by the user.
  • -perm /mode: Find files with any of the mode bits set.

7. Search by User and Group

  • -user username: Find files owned by the specified user.
  • -group groupname: Find files owned by the specified group.
  • -uid uid: Find files owned by the specified user ID.
  • -gid gid: Find files owned by the specified group ID.

8. Logical Operations

  • -and or -a: Logical AND (default).
  • -or or -o: Logical OR.
  • -not or !: Logical NOT.
  • (): Group conditions.
    • Example: find . \( -name "*.txt" -o -name "*.md" \) finds .txt or .md files.

9. Execute Actions

  • -exec command {} \;: Execute a command on the found files.
    • Example: find . -name "*.log" -exec rm {} \; deletes all .log files.
  • -exec command {} +: Pass multiple files to the command at once.
    • Example: find . -name "*.txt" -exec cp {} /backup/ + copies all .txt files to /backup.
  • -ok command {} \;: Similar to -exec, but prompts for confirmation before executing the command.
  • -delete: Delete the found files.
  • -print: Print the path of the found files (default behavior).
  • -ls: Display the found files in ls -dils format.

10. Other Common Options

  • -maxdepth n: Limit the maximum directory depth for the search.
    • Example: find . -maxdepth 2 -name "*.txt" searches for .txt files only in the current directory and its immediate subdirectories.
  • -mindepth n: Limit the minimum directory depth for the search.
  • -empty: Find empty files or directories.
  • -readable: Find readable files.
  • -writable: Find writable files.
  • -executable: Find executable files.

11. Comprehensive Examples

Find and delete all .log files in the current directory:

1
find . -name "*.log" -delete

Find files larger than 100MB in /var/log and display detailed information:

1
find /var/log -size +100M -ls

Find .txt files modified within the last 7 days in the current directory and copy them to /backup:

1
find . -name "*.txt" -mtime -7 -exec cp {} /backup/ \;

Find and delete all empty directories in the current directory:

1
find . -type d -empty -delete

Find files with permissions 644 in the current directory and change their permissions to 755:

1
find . -type f -perm 644 -exec chmod 755 {} \;

grep command

grep is a powerful command-line tool in Unix/Linux used to search for specific patterns within files or input text.

1
grep [options] pattern [file]
  • pattern: The text or regular expression to search for.
  • file: The file(s) to search within. If omitted, grep reads from standard input.

For example, you can using the grep command by using pipes.

1
cat /etc/ssh/sshd_config | grep Port

This command will first output the file contents of sshd_config while the content itself won’t be printed directly into the screen. It will be transmitted as the input of the grep command.

Common Options

  • -i: Ignore case (case-insensitive search).
1
grep -i "hello" file.txt
  • -v: Invert match (show lines that do not match the pattern).
1
grep -v "error" file.txt
  • -r or -R: Recursively search directories.
1
grep -r "pattern" /path/to/dir
  • -n: Show line numbers of matching lines.
1
grep -n "pattern" file.txt
  • -c: Count the number of matching lines.
1
grep -c "pattern" file.txt
  • -l: List filenames containing the pattern.
1
grep -l "pattern" *.txt
  • -w: Match whole words only.
1
grep -w "word" file.txt
  • -A, -B, -C: Show lines after, before, or around the match.
1
2
3
grep -A 2 "pattern" file.txt  # Show 2 lines after the match
grep -B 2 "pattern" file.txt # Show 2 lines before the match
grep -C 2 "pattern" file.txt # Show 2 lines before and after the match

For example, I have a directory (current) and exists files as below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
.
├── grep_test.txt
└── sub_dirc
├── modified_1.txt
└── modified_2.txt

2 directories, 3 files

cat grep_test.txt
Hello my name is Jack.
I am 18 year's old.
Do you like me?
I want to make friends with you.
Remember my name, my name is JACK!
HAahah
do you know my favourite motto?
Knowledge isn't free, you have to pay attention.

cat ./sub_dirc/modified_1.txt
Hello my name is Henry.
I am 17 year's old.
Do you like me?
I want to make friends with you.
Remember my name, my name is Henry!
HAahah
do you know my favourite motto?
Nothing is possible

❯ cat ./sub_dirc/modified_2.txt
Hello my name is Kate.
I am 20 year's old.
Do you like us?
I want to make friends with you.
Remember my name, my name is KatE!
HAahah
do you know my favourite motto?
Open source is the best thing in the world!

Now I can use several commands as below to efficiently search specific information that I want!

I can use -r to search for the whole current directory.

1
grep -r "Hello" ./
1
2
3
./sub_dirc/modified_1.txt:Hello my name is Henry.
./sub_dirc/modified_2.txt:Hello my name is Kate.
./grep_test.txt:Hello my name is Jack.

1
grep -nri "Jack" ./
1
2
./grep_test.txt:1:Hello my name is Jack.
./grep_test.txt:5:Remember my name, my name is JACK!

1
grep -nrc "Hello" ./
1
2
3
./sub_dirc/modified_1.txt:1
./sub_dirc/modified_2.txt:1
./grep_test.txt:1

1
grep -nrv "Hello" ./
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
./sub_dirc/modified_1.txt:2:I am 17 year's old.
./sub_dirc/modified_1.txt:3:Do you like me?
./sub_dirc/modified_1.txt:4:I want to make friends with you.
./sub_dirc/modified_1.txt:5:Remember my name, my name is Henry!
./sub_dirc/modified_1.txt:6:HAahah
./sub_dirc/modified_1.txt:7:do you know my favourite motto?
./sub_dirc/modified_1.txt:8:Nothing is possible
./sub_dirc/modified_1.txt:9:
./sub_dirc/modified_2.txt:2:I am 20 year's old.
./sub_dirc/modified_2.txt:3:Do you like us?
./sub_dirc/modified_2.txt:4:I want to make friends with you.
./sub_dirc/modified_2.txt:5:Remember my name, my name is KatE!
./sub_dirc/modified_2.txt:6:HAahah
./sub_dirc/modified_2.txt:7:do you know my favourite motto?
./sub_dirc/modified_2.txt:8:Open source is the best thing in the world!
./sub_dirc/modified_2.txt:9:
./grep_test.txt:2:I am 18 year's old.
./grep_test.txt:3:Do you like me?
./grep_test.txt:4:I want to make friends with you.
./grep_test.txt:5:Remember my name, my name is JACK!
./grep_test.txt:6:HAahah
./grep_test.txt:7:do you know my favourite motto?
./grep_test.txt:8:Knowledge isn't free, you have to pay attention.
./grep_test.txt:9:

1
grep -ri -A 1 "motto" ./
1
2
3
4
5
6
7
8
./sub_dirc/modified_1.txt:do you know my favourite motto?
./sub_dirc/modified_1.txt-Nothing is possible
--
./sub_dirc/modified_2.txt:do you know my favourite motto?
./sub_dirc/modified_2.txt-Open source is the best thing in the world!
--
./grep_test.txt:do you know my favourite motto?
./grep_test.txt-Knowledge isn't free, you have to pay attention.

You can make the command line more complex to get more specific data!

1
grep -ri -A 1 "motto" ./ | grep -v "motto"
1
2
3
4
5
./sub_dirc/modified_1.txt-Nothing is possible
--
./sub_dirc/modified_2.txt-Open source is the best thing in the world!
--
./grep_test.txt-Knowledge isn't free, you have to pay attention.

More specific:

1
grep -rih -A 1 "motto" ./ | grep -v "motto" | grep -v "^--$"

Using the -h options to forbid grep showing filenames while searching the directory recursively. Adding more pipes and using Regex can enable developers to make more specific pattern matching problems more freely.

1
2
3
Nothing is possible
Open source is the best thing in the world!
Knowledge isn't free, you have to pay attention.

By using this command, you can get all the mottos for all person’s files, which will significantly enhance one’s working efficiency. For more options, you can typing man grep for advanced usage.

Lec3: Vim editors

You can just go to Vim tutorial for help.

Lec4: Data Wrangling

Lec5: Command Line Environment

Lec6: Git (Version Control)

Lec7: Debugging and Profiling

Debugging is of great importance! Mastering debugging in the coding process will significantly enhance your coding speed and time you will cost when your codes get an error.

“The most effective debugging tool is still careful thought, coupled with judiciously placed print statements” — Brian Kernighan, Unix for Beginners.

This is the simplest way, somehow, an “effective” way to find your bugs in your code by using print functions to print all the significant variables and statements where you encountered your bug.

It is simple, but sometimes naive. We need to learn some advance techniques for better performance and efficiency. So that is why we need to learn debugging!

Logging

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import logging
import time
import random
from concurrent.futures import ThreadPoolExecutor

# Configure logging
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler("task_scheduler.log"), # Log to a file
logging.StreamHandler() # Log to console
]
)

class Task:
"""Class representing a task."""

def __init__(self, name, duration):
self.name = name
self.duration = duration # Duration in seconds

def execute(self):
"""Simulate task execution."""
logging.info(f"Starting task: {self.name}")
time.sleep(self.duration)
logging.info(f"Completed task: {self.name}")

class TaskScheduler:
"""Class for scheduling and executing tasks."""

def __init__(self):
self.tasks = []

def add_task(self, task):
"""Add a task to the scheduler."""
self.tasks.append(task)
logging.debug(f"Task added: {task.name} (Duration: {task.duration}s)")

def run_tasks(self):
"""Run all scheduled tasks concurrently."""
logging.info("Starting task execution...")
with ThreadPoolExecutor(max_workers=5) as executor:
futures = {executor.submit(task.execute()): task for task in self.tasks}
for future in futures:
try:
future.result() # Wait for the task to complete
except Exception as e:
logging.error(f"Task failed: {futures[future].name} with error: {e}")
logging.info("All tasks completed.")

if __name__ == "__main__":
scheduler = TaskScheduler()

# Create and add tasks with random durations
for i in range(10):
duration = random.randint(1, 5) # Random duration between 1 and 5 seconds
task = Task(f"Task-{i+1}", duration)
scheduler.add_task(task)

# Run the scheduled tasks
scheduler.run_tasks()

Logging is a great habit to make your debugging message neater! You can add several lines before the main functions to set the syntax of logging.

1
2
3
4
5
6
7
8
9
10
import logging
# Configure logging
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler("task_scheduler.log"), # Log to a file
logging.StreamHandler() # Log to console
]
)

Then, you can output several log messages during your coding precess. Like this:

1
2
3
logging.info(f"Starting task: {self.name}")
logging.debug(f"Task added: {task.name} (Duration: {task.duration}s)")
logging.error(f"Task failed: {futures[future].name} with error: {e}")

There are three types of logging messages.(Of course there are more!)

  • Debugging: This level is used for detailed information, typically of interest only when diagnosing problems. It provides insights into the internal state of the application and is useful for developers during the debugging process.
    • e.g. Logging variable values, function entry and exit points, or detailed flow of execution.
  • INFO: This level is used to confirm that things are working as expected. It provides general information about the application’s progress and state without being overly verbose.
    • e.g. Logging the start and completion of tasks, user actions, or significant milestones in the application.
  • ERROR: This level indicates a more serious problem that prevented the program from performing a function. It is used to log exceptions or errors that occur during execution.
    • e.g. Logging when a task fails due to an exception or when a critical operation cannot be completed.
  • There does exist several other debugging messages! For instance, warning, critical, etc.

It’s ok if you don’t understand about threads in the codes shown above. You can just focus on the logging messages.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2025-02-23 20:45:45,873 - DEBUG - Task added: Task-1 (Duration: 2s)
2025-02-23 20:45:45,873 - DEBUG - Task added: Task-2 (Duration: 2s)
2025-02-23 20:45:45,873 - DEBUG - Task added: Task-3 (Duration: 1s)
2025-02-23 20:45:45,874 - DEBUG - Task added: Task-4 (Duration: 2s)
2025-02-23 20:45:45,874 - DEBUG - Task added: Task-5 (Duration: 4s)
2025-02-23 20:45:45,874 - DEBUG - Task added: Task-6 (Duration: 1s)
2025-02-23 20:45:45,874 - DEBUG - Task added: Task-7 (Duration: 4s)
2025-02-23 20:45:45,874 - DEBUG - Task added: Task-8 (Duration: 2s)
2025-02-23 20:45:45,874 - DEBUG - Task added: Task-9 (Duration: 3s)
2025-02-23 20:45:45,874 - DEBUG - Task added: Task-10 (Duration: 5s)
2025-02-23 20:45:45,875 - INFO - Starting task execution...
2025-02-23 20:45:45,875 - INFO - Starting task: Task-1
2025-02-23 20:45:47,875 - INFO - Completed task: Task-1
2025-02-23 20:45:47,876 - INFO - Starting task: Task-2
2025-02-23 20:45:49,876 - INFO - Completed task: Task-2
2025-02-23 20:45:49,877 - INFO - Starting task: Task-3
2025-02-23 20:45:50,877 - INFO - Completed task: Task-3
2025-02-23 20:45:50,878 - INFO - Starting task: Task-4
2025-02-23 20:45:52,878 - INFO - Completed task: Task-4
2025-02-23 20:45:52,879 - INFO - Starting task: Task-5
2025-02-23 20:45:56,879 - INFO - Completed task: Task-5
2025-02-23 20:45:56,879 - INFO - Starting task: Task-6
2025-02-23 20:45:57,880 - INFO - Completed task: Task-6
2025-02-23 20:45:57,880 - INFO - Starting task: Task-7
2025-02-23 20:46:02,508 - INFO - Completed task: Task-7
2025-02-23 20:46:02,509 - INFO - Starting task: Task-8
2025-02-23 20:46:04,509 - INFO - Completed task: Task-8
2025-02-23 20:46:04,509 - INFO - Starting task: Task-9
2025-02-23 20:46:07,510 - INFO - Completed task: Task-9
2025-02-23 20:46:07,510 - INFO - Starting task: Task-10
2025-02-23 20:46:12,511 - INFO - Completed task: Task-10
2025-02-23 20:46:12,512 - ERROR - Task failed: Task-1 with error: 'NoneType' object is not callable
2025-02-23 20:46:12,512 - ERROR - Task failed: Task-2 with error: 'NoneType' object is not callable
2025-02-23 20:46:12,512 - ERROR - Task failed: Task-3 with error: 'NoneType' object is not callable
2025-02-23 20:46:12,512 - ERROR - Task failed: Task-4 with error: 'NoneType' object is not callable
2025-02-23 20:46:12,512 - ERROR - Task failed: Task-5 with error: 'NoneType' object is not callable
2025-02-23 20:46:12,512 - ERROR - Task failed: Task-6 with error: 'NoneType' object is not callable
2025-02-23 20:46:12,512 - ERROR - Task failed: Task-7 with error: 'NoneType' object is not callable
2025-02-23 20:46:12,513 - ERROR - Task failed: Task-8 with error: 'NoneType' object is not callable
2025-02-23 20:46:12,513 - ERROR - Task failed: Task-9 with error: 'NoneType' object is not callable
2025-02-23 20:46:12,513 - ERROR - Task failed: Task-10 with error: 'NoneType' object is not callable
2025-02-23 20:46:12,513 - INFO - All tasks completed.

If you only want to output several error messages, you can just make more settings like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Configure logging
logging.basicConfig(
level=logging.DEBUG, # Set the logging level for the root logger
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler("task_scheduler.log"), # Log to a file
]
)

# Create a StreamHandler for console output
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.ERROR) # Set the level for the console handler
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') # Set the format for the console handler
console_handler.setFormatter(formatter) # Assign the formatter to the console handler

# Add the console handler to the root logger
logging.getLogger().addHandler(console_handler)

Of course, you can modify the logging message with different colors. You can modify the output colors of the terminal by using echo command with different parameters.

For example, I have implemented this function in my ~/.zshrc files.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# This functions sets different colours for terminal.
print_colored() {
local color="$1"
local text="$2"

case "$color" in
red) echo -e "\033[31m$text\033[0m" ;; # 红色
green) echo -e "\033[32m$text\033[0m" ;; # 绿色
yellow) echo -e "\033[33m$text\033[0m" ;; # 黄色
blue) echo -e "\033[34m$text\033[0m" ;; # 蓝色
purple) echo -e "\033[35m$text\033[0m" ;; # 紫色
cyan) echo -e "\033[36m$text\033[0m" ;; # 青色
white) echo -e "\033[37m$text\033[0m" ;; # 白色
*) echo "$text" ;; # 默认
esac
}

You can copy this function into your dotfiles!

Customizing colours in terminal

Debugger

Just simply output several logging messages isn’t enough! For example, you can not detect memory leak with printing all variables and messages. Thus, we need more specific tools to debugging

Many programming languages come with some form of debugger. In Python this is the Python Debugger pdb.

Here is a brief description of some of the commands pdb supports:

  • l(ist) - Displays 11 lines around the current line or continue the previous listing.
  • s(tep) - Execute the current line, stop at the first possible occasion.
  • n(ext) - Continue execution until the next line in the current function is reached or it returns.
  • b(reak) - Set a breakpoint (depending on the argument provided).
  • p(rint) - Evaluate the expression in the current context and print its value. There’s also pp to display using pprint instead.
  • r(eturn) - Continue execution until the current function returns.
  • q(uit) - Quit the debugger.

Lec8: Metaprogramming

Lec9: Security and Cryptography

Others

Conclusion


Missing-Semester-Notes
https://xiyuanyang-code.github.io/posts/Missing-Semester-Notes/
Author
Xiyuan Yang
Posted on
February 11, 2025
Updated on
February 28, 2025
Licensed under