← Home

Ch 4 — Strings & Output

Ch 4 — Strings & Output

Every report, alert, and status line Aryan’s RAM manager prints to the terminal is a string. This chapter covers the full string toolkit — from pulling a single character out of a process name to formatting a polished live dashboard row with aligned columns and color codes.


String Indexing

Strings are zero-indexed sequences. Negative indices count from the end.

proc = "chrome"
#       c h r o m e
#       0 1 2 3 4 5
#      -6-5-4-3-2-1

proc[0]    # 'c'
proc[-1]   # 'e'
proc[2]    # 'r'

String Slicing

s[start:stop:step] — stop is exclusive.

proc = "kernel_task"

proc[0:6]    # 'kernel'
proc[7:]     # 'task'
proc[:6]     # 'kernel'
proc[::2]    # 'kenl_ak' (every other char)
proc[::-1]   # 'ksat_lenrek' (reversed)

In the RAM manager, slicing truncates long process names to fit column widths:

name = "com.apple.WebKit.Networking"
short = name[:20]   # 'com.apple.WebKit.Net'

Concatenation & Repetition

label = "RAM" + ": " + "73%"    # 'RAM: 73%'
divider = "-" * 40               # '----------------------------------------'

Prefer f-strings over concatenation for anything complex — concatenation with many parts is hard to read.


f-Strings (Python 3.6+)

The cleanest way to embed expressions in strings.

used_gb = 11.2
total_gb = 16
pct = used_gb / total_gb * 100

print(f"RAM: {used_gb:.1f} GB / {total_gb} GB  ({pct:.1f}%)")
# RAM: 11.2 GB / 16 GB  (70.0%)

Format specifiers inside {}:

  • :.1f — 1 decimal place float
  • :>10 — right-align in 10-char field
  • :<10 — left-align in 10-char field
  • :^10 — center in 10-char field
  • :, — thousands separator
  • :#x — hex with 0x prefix
bytes_used = 12_345_678_901
print(f"{bytes_used:,}")     # 12,345,678,901
print(f"{255:#x}")           # 0xff

str.format() Method

Older style, still common in templates and logging config.

row = "{:<20} {:>8.1f} MB  {:>6.1f}%".format("kernel_task", 1228.8, 7.5)
# 'kernel_task           1228.8 MB    7.5%'

String Methods

name = "  Google Chrome  "
name.strip()         # 'Google Chrome'    — remove surrounding whitespace
name.lower()         # '  google chrome  '
name.upper()         # '  GOOGLE CHROME  '
"chrome".startswith("ch")   # True
"chrome".endswith("me")     # True
"kernel_task".replace("_", " ")   # 'kernel task'
"com.apple.webkit".count(".")     # 2
"chrome".find("om")               # 1  (index of first match)
"   ".isspace()                   # True
"chrome".isalpha()                # True

split and join

# Split a CSV-like output line from a system tool
line = "chrome,4821,1024,73.5"
parts = line.split(",")
# ['chrome', '4821', '1024', '73.5']

proc_name, pid, rss, pct = parts

# Join a list back into a display string
fields = ["chrome", "4821", "1024 MB", "73.5%"]
row = "  |  ".join(fields)
# 'chrome  |  4821  |  1024 MB  |  73.5%'

Escape Characters

SequenceMeaning
\nNewline
\tTab
\\Literal backslash
\"Literal double quote
\rCarriage return
report = "Process\tPID\tRAM\n" \
         "chrome\t4821\t1.0 GB\n"
print(report)

Raw strings (r"...") disable escape processing — handy for Windows paths:

log_path = r"C:\Users\Aryan\ram_log.txt"

# sep and end control delimiters
print("RAM", "CPU", "DISK", sep=" | ")   # RAM | CPU | DISK
print("Loading", end="")               # stays on same line

# Flush forces immediate output (important for live monitors)
import sys
print("Scanning…", flush=True)

String Anatomy Diagram

flowchart LR
    A[String s] --> B[Indexing\ns-0- s-1- s-2-]
    A --> C[Slicing\ns-start:stop:step-]
    A --> D[Methods\n.strip .split .join]
    A --> E[Formatting]
    E --> F[f-string\nf-value-]
    E --> G[str.format\n-0- -1-]
    E --> H[%-formatting\n%-s -d]

Output Pipeline in the RAM Manager

flowchart TD
    A[psutil data] --> B[Numbers: int / float]
    B --> C[f-string formatting]
    C --> D{Output target?}
    D -->|Terminal| E[print with flush=True]
    D -->|Log file| F[write with newline]
    D -->|Alert| G[f-string in notification body]
    E --> H[Live dashboard row\n'chrome  | 1.0 GB | 73.5%']

Key Takeaways

  • Python strings are zero-indexed; negative indices count from the end.
  • Slicing [start:stop:step] creates a substring — stop is exclusive.
  • f-strings are the modern standard for string interpolation; format specifiers (:,.1f, :>10) control alignment and precision.
  • split() and join() are inverses — parse incoming text with split, assemble output with join.
  • Escape sequences (\n, \t) control whitespace; raw strings (r"...") disable them.
  • print() accepts sep and end to control delimiters and line endings; use flush=True for live output.
  • Rich string methods (.strip(), .lower(), .replace(), .startswith()) keep process name handling clean.