# Debug

#### Debugging

##### assert

- 主要用在開發與測試階段
- 可用在程式的條件測試
- `assert <condition>, <message>` : 如果 condition 為 True，沒有作用；如果為 False，會產生錯誤，並顯示訊息
- 跳過所有 `assert` 語句，可以使用 `python -O sample.py`。

檢查變數的值

```python
x = 5
assert x == 5, "x should be 5"

assert type(username) == str, "username must be a string"
```

```python
def calculate_square_root(x):
    assert x >= 0, "The input must be non-negative."
    return x ** 0.5

print(calculate_square_root(4))  # 輸出: 2.0
print(calculate_square_root(-1)) # 引發 AssertionError 並顯示 "The input must be non-negative."
```

檢查函示回傳值有無偶數

```python
def get_even_number(numbers):
    for num in numbers:
        if num % 2 == 0:
            return num
    assert False, "No even number found in the list."

numbers = [1, 3, 5, 7, 10]
print(get_even_number(numbers))  # 輸出: 10
numbers = [1, 3, 5, 7]
print(get_even_number(numbers))  # 引發 AssertionError 並顯示 "No even number found in the list."
```

##### prinf debugging

```python
print("Processing {}".format(basename))
```

##### strace

- [Linux strace Command Tutorial for Beginners (8 Examples)](https://www.howtoforge.com/linux-strace-command/)

```bash
# Installation on RHEL if it's not installed
yum install strace

# Tracing system calls made by a program
strace ./my-program.py
strace -o my-program.strace ./my-program
```

#### Crash

##### pdb

功能：

- 設定程式中斷點
- 逐行檢查程式碼
- 檢查變數
- 以互動方式評估表達式

```bash
pdb3 myprog.py
```

pdb-subcommands

- continue : 繼續執行直到異常的程式碼
- print() : 輸出變數的內容

```
(Pdb) continue
...
(Pdb) print(row)
```

Step 1: Set a breakpoint

```python
import pdb


def add_numbers(a, b):
    pdb.set_trace()  # This will set a breakpoint in the code
    result = a + b
    return result


print(add_numbers(3, 4))
```

Setp 2: Enter the interactive debugger

- <var>a</var> (args): Show the arguments of the current function.
- <var>b:</var> Manually set a persistent breakpoint while in debugger.
- <var>n</var> (next): Execute the next line within the current function.
- <var>s</var> (step): Execute the current line and stop at the first possible occasion (e.g., in a function that is called).
- <var>c</var> (continue): Resume normal execution until the next breakpoint.
- <var>p</var> (print): Evaluate and print the expression, e.g., p <var>variable\_name</var> will print the value of <var>variable\_name</var>.
- <var>Pp</var> (pretty-print): Pretty-print the value of the expression.
- <var>q</var> (quit): Exit the debugger and terminate the program.
- <var>r</var> (return): Continue execution until the current function returns.
- <var>tbreak:</var> Manually set a temporary breakpoint that goes away once hit the first time.
- <var>!</var>: Prefix to execute an arbitrary Python command in the current environment, e.g., <var>!variable\_name</var> = "<var>new\_value</var>" will set variable\_name to "<var>new\_value</var>".

Step 3: Inspect variables

To inspect the variables, simply type the single character, <var>p</var>, then the variable name to see its current value. For instance, if you have a variable in your code named <var>sentiment\_score</var>, just type p <var>sentiment\_score</var> at the <var>pdb </var>prompt to inspect its value.

Step 4: Modify variables

A big advantage of pdb is that you can change the value of a variable directly in the debugger. For example, to change `sentiment_score` to 0.9, you'd type `!sentiment_score = 0.9`.

To confirm these changes, use a or directly probe the value with `p <value name>`.

 Step 5: Exit the debugger

When you’re done, simply enter `q` (quit) to exit the debugger and terminate the program.

Post-mortem debugging

```bash
python -m pdb your_script.py
```

#### Memory Leaks

當不再需要的記憶體未釋放時，就會發生記憶體洩漏。即使重新啟動，仍需要大量記憶體的應用程式，很可能指向記憶體洩漏

##### memory\_profiler

第一欄顯示每一行執行時所需的記憶體數量。第二欄顯示每一行所增加的記憶體

```bash
python3 -m memory_profiler myprog.py
```

In Code

- 在 `main()` 上方加上 `@profile` 標籤
- @ 標籤稱為 Decorator: 在 Python 中使用它來為函數增加額外的行為，而不需要修改程式碼
- [memory-profiler](https://pypi.org/project/memory-profiler/)

```python
from memory_profiler import profile

...
...

@profile
def main():
  ...
  ...
  

```