You're building a greeting card generator. The user enters their name "Alice" and you need to create "Hello, Alice!" - combining text, storing it, measuring it, and accessing individual letters.

Store and print a name

Create a string and display it.

name.py
name = 
print(f"Hello, {name}!")
print(f"Your name is: {name}")
name = 
print(f"Hello, {name}!")
print(f"Your name is: {name}")
name = 
print(f"Hello, {name}!")
print(f"Your name is: {name}")

Strings can use single or double quotes - your choice.

str A sequence of characters, like `"Hello"`. Immutable in Python.

Combine first and last name

Join strings using + or f-strings.

combine.py
first_name = 
last_name = 

# Using + operator
full_name = first_name + " " + last_name
print("Full name: " + full_name)

# Using f-string (preferred)
greeting = f"Hello, {first_name} {last_name}!"
print(greeting)

# Using .join()
parts = [first_name, last_name]
joined = " ".join(parts)
print(f"Joined: {joined}")
first_name = 
last_name = 

# Using + operator
full_name = first_name + " " + last_name
print("Full name: " + full_name)

# Using f-string (preferred)
greeting = f"Hello, {first_name} {last_name}!"
print(greeting)

# Using .join()
parts = [first_name, last_name]
joined = " ".join(parts)
print(f"Joined: {joined}")
first_name = 
last_name = 

# Using + operator
full_name = first_name + " " + last_name
print("Full name: " + full_name)

# Using f-string (preferred)
greeting = f"Hello, {first_name} {last_name}!"
print(greeting)

# Using .join()
parts = [first_name, last_name]
joined = " ".join(parts)
print(f"Joined: {joined}")
first_name = 
last_name = 

# Using + operator
full_name = first_name + " " + last_name
print("Full name: " + full_name)

# Using f-string (preferred)
greeting = f"Hello, {first_name} {last_name}!"
print(greeting)

# Using .join()
parts = [first_name, last_name]
joined = " ".join(parts)
print(f"Joined: {joined}")
first_name = 
last_name = 

# Using + operator
full_name = first_name + " " + last_name
print("Full name: " + full_name)

# Using f-string (preferred)
greeting = f"Hello, {first_name} {last_name}!"
print(greeting)

# Using .join()
parts = [first_name, last_name]
joined = " ".join(parts)
print(f"Joined: {joined}")
first_name = 
last_name = 

# Using + operator
full_name = first_name + " " + last_name
print("Full name: " + full_name)

# Using f-string (preferred)
greeting = f"Hello, {first_name} {last_name}!"
print(greeting)

# Using .join()
parts = [first_name, last_name]
joined = " ".join(parts)
print(f"Joined: {joined}")
first_name = 
last_name = 

# Using + operator
full_name = first_name + " " + last_name
print("Full name: " + full_name)

# Using f-string (preferred)
greeting = f"Hello, {first_name} {last_name}!"
print(greeting)

# Using .join()
parts = [first_name, last_name]
joined = " ".join(parts)
print(f"Joined: {joined}")
first_name = 
last_name = 

# Using + operator
full_name = first_name + " " + last_name
print("Full name: " + full_name)

# Using f-string (preferred)
greeting = f"Hello, {first_name} {last_name}!"
print(greeting)

# Using .join()
parts = [first_name, last_name]
joined = " ".join(parts)
print(f"Joined: {joined}")
first_name = 
last_name = 

# Using + operator
full_name = first_name + " " + last_name
print("Full name: " + full_name)

# Using f-string (preferred)
greeting = f"Hello, {first_name} {last_name}!"
print(greeting)

# Using .join()
parts = [first_name, last_name]
joined = " ".join(parts)
print(f"Joined: {joined}")
f-string Formatted string: `f"Hello, {name}!"` - variables inside `{}`

Get string length

Find out how many characters are in a string.

length.py
word = 
sentence = "Hello World"

print(f"'{word}' has {len(word)} characters")
print(f"'{sentence}' has {len(sentence)} characters")

# Empty string has length 0
empty = ""
print(f"Empty string length: {len(empty)}")
word = 
sentence = "Hello World"

print(f"'{word}' has {len(word)} characters")
print(f"'{sentence}' has {len(sentence)} characters")

# Empty string has length 0
empty = ""
print(f"Empty string length: {len(empty)}")
word = 
sentence = "Hello World"

print(f"'{word}' has {len(word)} characters")
print(f"'{sentence}' has {len(sentence)} characters")

# Empty string has length 0
empty = ""
print(f"Empty string length: {len(empty)}")
len Length function: `len("Hello")` → `5`

Compare two strings

Check if strings are equal using ==.

compare.py
a = "hello"
b = "hello"
c = "Hello"  # different case

# Python == compares content directly
print(f"a == b: {a == b}")       # True
print(f"a == c: {a == c}")       # False (case matters)
print(f"a.lower() == c.lower(): {a.lower() == c.lower()}")  # True

# Comparing with user input
user_input = 
if user_input.lower() == "yes":
    print("User agreed!")

# Other comparisons
print(f"'apple' < 'banana': {'apple' < 'banana'}")  # alphabetical
print(f"'a' in 'cat': {'a' in 'cat'}")              # contains
a = "hello"
b = "hello"
c = "Hello"  # different case

# Python == compares content directly
print(f"a == b: {a == b}")       # True
print(f"a == c: {a == c}")       # False (case matters)
print(f"a.lower() == c.lower(): {a.lower() == c.lower()}")  # True

# Comparing with user input
user_input = 
if user_input.lower() == "yes":
    print("User agreed!")

# Other comparisons
print(f"'apple' < 'banana': {'apple' < 'banana'}")  # alphabetical
print(f"'a' in 'cat': {'a' in 'cat'}")              # contains
a = "hello"
b = "hello"
c = "Hello"  # different case

# Python == compares content directly
print(f"a == b: {a == b}")       # True
print(f"a == c: {a == c}")       # False (case matters)
print(f"a.lower() == c.lower(): {a.lower() == c.lower()}")  # True

# Comparing with user input
user_input = 
if user_input.lower() == "yes":
    print("User agreed!")

# Other comparisons
print(f"'apple' < 'banana': {'apple' < 'banana'}")  # alphabetical
print(f"'a' in 'cat': {'a' in 'cat'}")              # contains

Unlike Java, Python's == compares content directly. Simple and intuitive.

Access character by index

Get individual characters from a string by their position.

index.py
word = 

# Index:    0  1  2  3  4
# Chars:    H  e  l  l  o
# Neg:     -5 -4 -3 -2 -1

first = word[0]
last = word[-1]      # Negative index = from end

print(f"Word: {word}")
print(f"First character: {first}")
print(f"Last character: {last}")
print(f"Second to last: {word[-2]}")

# Print all characters with their indices
for i, char in enumerate(word):
    print(f"Index {i}: {char}")
word = 

# Index:    0  1  2  3  4
# Chars:    H  e  l  l  o
# Neg:     -5 -4 -3 -2 -1

first = word[0]
last = word[-1]      # Negative index = from end

print(f"Word: {word}")
print(f"First character: {first}")
print(f"Last character: {last}")
print(f"Second to last: {word[-2]}")

# Print all characters with their indices
for i, char in enumerate(word):
    print(f"Index {i}: {char}")
word = 

# Index:    0  1  2  3  4
# Chars:    H  e  l  l  o
# Neg:     -5 -4 -3 -2 -1

first = word[0]
last = word[-1]      # Negative index = from end

print(f"Word: {word}")
print(f"First character: {first}")
print(f"Last character: {last}")
print(f"Second to last: {word[-2]}")

# Print all characters with their indices
for i, char in enumerate(word):
    print(f"Index {i}: {char}")

Python supports negative indices: -1 is the last character, -2 is second to last.

indexing Get character: `"Hello"[0]` → `'H'`, `"Hello"[-1]` → `'o'`

Exercise: special.py

Explore special strings: empty string, escape sequences, raw strings, multiline