Everything today rests on one fact: a Python string cannot be modified. Every “change” you make produces a new string.
1. Strings Are Unicode Sequences
- A string is a sequence of Unicode characters, which covers essentially every writing system in use.
- ASCII, the older standard, holds just 128 characters (7-bit). Extended ASCII pushes that to 256. Unicode goes far beyond both — which is why Telugu, Hindi and emoji all work.
- Build them with single quotes, double quotes, or triple quotes for multi-line text.
As a sequence type, a string supports everything you already know:
s = "hyderabad"
s[0] # 'h'
s[-1] # 'd'
s[0:3] # 'hyd'
s[::-1] # 'dabaredyh' — reversed
2. Immutability, and the Bug It Causes
s = "hello"
s[0] = "H" # TypeError — not allowed
The consequence that bites everyone: string methods return a new string. They don’t change the original.
s.upper() # produces "HELLO" — and throws it away
s = s.upper() # this is what you meant
If a strip() or replace() “didn’t work,” this is almost always why.
3. Operators
"hy" + "derabad" # concatenation
"ha" * 3 # repetition → 'hahaha'
"der" in "hyderabad" # membership → True
"abc" == "abc" # equality → True
4. The Methods That Earn Their Keep
Case
s.upper() # 'HYDERABAD'
s.lower() # 'hyderabad'
s.title() # 'Hyderabad' — first letter of each word up, rest DOWN
s.capitalize() # first letter of the string only
⚠️ title() trips on apostrophes: "khaja's".title() gives "Khaja'S".
Cleaning
" text ".strip() # 'text' — only the ends, never the middle
"xxtextxx".strip("x") # 'text' — strips any characters you name
s.replace("a", "o") # returns a new string
Analysis
s.find("der") # index, or -1 if absent
s.index("der") # index, or raises ValueError
s.count("a") # how many times
"123".isdigit() # True
"12.5".isdigit() # False — the dot isn't a digit
"".isdigit() # False — empty is never digits
Pick find() when absence is normal; pick index() when absence is a bug you want to hear about immediately.
Converting to and from lists
"a,b,c".split(",") # ['a', 'b', 'c']
"-".join(["a", "b", "c"]) # 'a-b-c'
join() needs every element to be a string — pass it numbers and you get a TypeError.
5. f-Strings
The current way to build text. No more str() around every number:
name, score = "Khaja", 91.456
f"{name} scored {score}" # 'Khaja scored 91.456'
f"{name} scored {score:.2f}" # 'Khaja scored 91.46'
:.2f fixes it to two decimal places. Concatenating a string with a number using + raises a TypeError; f-strings sidestep the whole problem.
6. Escape Sequences
| Sequence | Produces |
|---|---|
\n | New line |
\t | Tab |
\\ | One literal backslash |
\" | A quote inside a quoted string |
For Windows paths, a raw string is cleaner than escaping every separator:
print("C:\\Users\\khaja") # works, hard to read
print(r"C:\Users\khaja") # same output, far clearer
7. On Using AI While Learning
Write your own code first, then use an LLM to attack it — ask it to find the inputs that break your solution. That builds the skill. Asking for the solution outright skips the part where the learning happens.
✅ Assignment
Write a program that accepts a piece of text and reports:
- Total character count
- Number of vowels
- Number of digits
Try it before you look anything up. When it works, hand it to an LLM and ask what input would break it.
New to the course? About 20 Python sessions have already run, covering types, functions and generators. Either catch up through the recordings, or wait for the module to restart in roughly 20 days.
