Lesson 07: Strings (Text and Labels)
Learn Python strings for BIM automation: rename sheets, clean room names, format titles, and control text that drives efficient architectural workflows.
Introduction
Architects work with text constantly. Room names, sheet numbers, view names, file paths, drawing titles.
If you've ever renamed 200 sheets by hand, or spent an hour fixing inconsistent room names, you know the pain.
In Python, text is called a string. Strings are how you handle names, labels, and any text-based information.
This lesson is critical. Most BIM automation involves manipulating strings — reading them, combining them, extracting parts, and reformatting them.
By the end of this lesson, you'll see why strings are the most useful data type for architectural workflows.
Lesson Overview
This section contains a general overview of topics you will learn in this lesson.
- Understand what strings are and how to create them
- Learn to combine strings (concatenation)
- Extract parts of strings (slicing)
- Change string case (upper, lower, title)
- Find and replace text in strings
- Use string methods for real BIM tasks
- Avoid common string errors
What Is a String?
A string is text enclosed in quotes.
room_name = "Conference Room"
sheet_number = "A-101"
file_path = "C:/Projects/2024-001/Floor Plans.pdf"
You can use single quotes or double quotes. Python treats them the same.
room_name = "Conference Room" # Double quotes
room_name = 'Conference Room' # Single quotes (same result)
Why Both Quote Types Exist
Sometimes your text contains quotes. Having both types makes this easier.
# Text with an apostrophe
note = "Client's requirements changed" # Double quotes work
# Or
note = 'Client\\'s requirements changed' # Escape the apostrophe with \\
# Text with double quotes inside
message = 'The room is called "Main Conference"'
Use whichever makes your string clearer.
Creating Strings
# Simple strings
project_name = "Community Center"
architect = "Smith & Associates"
status = "In Progress"
# Empty string
description = ""
# Multi-line strings (use triple quotes)
notes = """
This is a multi-line string.
It can span several lines.
Useful for long descriptions.
"""
Combining Strings (Concatenation)
Use the + operator to join strings.
discipline = "A"
sheet_number = "101"
full_number = discipline + "-" + sheet_number
print(full_number) # Output: A-101
Architectural Example: Sheet Naming
discipline = "A"
sheet_type = "Floor Plan"
level = "Level 02"
revision = "R03"
# Build the full sheet name
sheet_name = discipline + " - " + sheet_type + " - " + level + " - " + revision
print(sheet_name)
# Output: A - Floor Plan - Level 02 - R03
Common Mistake: Concatenating Strings and Numbers
You can't directly concatenate strings and numbers.
floor_number = 2
floor_name = "Level " + floor_number
# Error: TypeError: can only concatenate str (not "int") to str
Convert the number to a string first using str().
floor_number = 2
floor_name = "Level " + str(floor_number)
print(floor_name) # Output: Level 2
Architectural Example: Room Numbering
room_type = "Conference Room"
room_number = 201
# Convert number to string before concatenating
full_name = room_type + " " + str(room_number)
print(full_name) # Output: Conference Room 201
String Length
Find how many characters are in a string using len().
sheet_name = "A-101"
name_length = len(sheet_name)
print(name_length) # Output: 5
Why This Matters
# Check if sheet number is the correct format
sheet_number = "A-101"
if len(sheet_number) == 5:
print("Sheet number format is correct")
else:
print("Sheet number format is wrong")
String Indexing (Accessing Individual Characters)
Each character in a string has a position (index). Python starts counting at 0.
sheet_number = "A-101"
# 0 1 2 3 4 (index positions)
first_char = sheet_number[0]
print(first_char) # Output: A
last_char = sheet_number[4]
print(last_char) # Output: 1
Negative Indexing
You can count from the end using negative numbers.
sheet_number = "A-101"
last_char = sheet_number[-1]
print(last_char) # Output: 1
second_last = sheet_number[-2]
print(second_last) # Output: 0
String Slicing (Extracting Parts)
Extract a portion of a string using [start:end].
sheet_number = "A-101"
# Get discipline (first character)
discipline = sheet_number[0]
print(discipline) # Output: A
# Get number part (characters 2 to end)
number = sheet_number[2:]
print(number) # Output: 101
# Get first three characters
prefix = sheet_number[0:3]
print(prefix) # Output: A-1
Slicing Rules
[start:end]— from start up to (but not including) end[start:]— from start to the end[:end]— from beginning up to (but not including) end[:]— entire string (useful for copying)
Architectural Example: Extracting Discipline from Sheet Number
sheet_numbers = ["A-101", "S-201", "M-301", "E-401"]
for sheet in sheet_numbers: # We'll learn about for loops in the coming lessons.
discipline = sheet[0]
print("Discipline:", discipline)
# Output:
# Discipline: A
# Discipline: S
# Discipline: M
# Discipline: E
String Methods
Strings come with built-in methods (functions) that perform common operations.
Changing Case
project_name = "community center"
# Make all uppercase
upper_name = project_name.upper()
print(upper_name) # Output: COMMUNITY CENTER
# Make all lowercase
lower_name = project_name.lower()
print(lower_name) # Output: community center
# Title case (first letter of each word capitalized)
title_name = project_name.title()
print(title_name) # Output: Community Center
Architectural Use Case: Standardising Room Names
# Room names from different sources have inconsistent capitalization
rooms = ["conference room", "MEETING ROOM", "break Room"]
# Standardize to title case
standardized_rooms = []
for room in rooms:
standardized = room.title()
standardized_rooms.append(standardized)
print(standardized_rooms)
# Output: ['Conference Room', 'Meeting Room', 'Break Room']
Removing Whitespace
Whitespace (spaces, tabs, newlines) at the beginning or end of strings can cause problems.
room_name = " Conference Room "
# Remove whitespace from both ends
clean_name = room_name.strip()
print(clean_name) # Output: "Conference Room"
# Remove from left side only
clean_left = room_name.lstrip()
print(clean_left) # Output: "Conference Room "
# Remove from right side only
clean_right = room_name.rstrip()
print(clean_right) # Output: " Conference Room"
Why This Matters
# Data imported from Excel might have extra spaces
room_1 = "Conference Room"
room_2 = "Conference Room " # Extra space at end
# These are NOT equal
print(room_1 == room_2) # Output: False
# Clean the data first
room_1_clean = room_1.strip()
room_2_clean = room_2.strip()
print(room_1_clean == room_2_clean) # Output: True
Finding Text in Strings
Check if a string contains certain text.
sheet_name = "A-101 Ground Floor Plan"
# Check if it contains "Floor"
if "Floor" in sheet_name:
print("This is a floor plan")
# Check if it doesn't contain something
if "Ceiling" not in sheet_name:
print("This is not a ceiling plan")
Find Position of Text
sheet_name = "A-101 Ground Floor Plan"
# Find where "Floor" starts
position = sheet_name.find("Floor")
print(position) # Output: 14
# Find returns -1 if text is not found
position = sheet_name.find("Ceiling")
print(position) # Output: -1
Replacing Text
Replace all occurrences of one string with another.
sheet_name = "A-101 Ground Floor Plan"
# Replace "Ground" with "First"
new_name = sheet_name.replace("Ground", "First")
print(new_name) # Output: A-101 First Floor Plan
Architectural Use Case: Batch Renaming
# Update all sheet names from "Draft" to "Issued"
sheet_names = [
"A-101 Draft Floor Plan",
"A-102 Draft Floor Plan",
"A-201 Draft Elevation"
]
issued_names = []
for sheet in sheet_names:
new_name = sheet.replace("Draft", "Issued")
issued_names.append(new_name)
print(issued_names)
# Output:
# ['A-101 Issued Floor Plan', 'A-102 Issued Floor Plan', 'A-201 Issued Elevation']
Splitting Strings
Break a string into a list of parts.
sheet_number = "A-101"
# Split at the hyphen
parts = sheet_number.split("-")
print(parts) # Output: ['A', '101']
# Access individual parts
discipline = parts[0]
number = parts[1]
print("Discipline:", discipline) # Output: Discipline: A
print("Number:", number) # Output: Number: 101
Architectural Example: Parsing Sheet Numbers
sheet_numbers = ["A-101", "S-201", "M-301", "E-401"]
for sheet in sheet_numbers:
parts = sheet.split("-")
discipline = parts[0]
number = parts[1]
print(f"Sheet {sheet}: Discipline = {discipline}, Number = {number}")
# Output:
# Sheet A-101: Discipline = A, Number = 101
# Sheet S-201: Discipline = S, Number = 201
# Sheet M-301: Discipline = M, Number = 301
# Sheet E-401: Discipline = E, Number = 401
Joining Strings
Combine a list of strings into one string.
parts = ["A", "101"]
# Join with a hyphen
sheet_number = "-".join(parts)
print(sheet_number) # Output: A-101
# Join with an underscore
file_name = "_".join(parts)
print(file_name) # Output: A_101
Architectural Example: Building File Names
project_code = "2024-001"
discipline = "Architecture"
drawing_type = "Floor Plans"
revision = "R02"
# Join parts with underscores
parts = [project_code, discipline, drawing_type, revision]
file_name = "_".join(parts) + ".pdf"
print(file_name)
# Output: 2024-001_Architecture_Floor Plans_R02.pdf
String Formatting (f-strings)
A cleaner way to build strings with variables.
Instead of concatenating:
project = "Community Center"
year = 2024
message = "Project: " + project + ", Year: " + str(year)
print(message)
Use f-strings (formatted string literals):
project = "Community Center"
year = 2024
message = f"Project: {project}, Year: {year}"
print(message)
Both output: Project: Community Center, Year: 2024
Why f-strings Are Better
- No need to convert numbers to strings
- More readable
- Easier to maintain
Architectural Examples
# Building report
floor_count = 12
floor_height = 3.2
total_height = floor_count * floor_height
report = f"Building has {floor_count} floors at {floor_height}m each = {total_height}m total"
print(report)
# Output: Building has 12 floors at 3.2m each = 38.4m total
# Sheet naming
discipline = "A"
number = 101
sheet_name = f"{discipline}-{number}"
print(sheet_name)
# Output: A-101
# Room naming
room_type = "Conference"
room_number = 201
full_name = f"{room_type} Room {room_number}"
print(full_name)
# Output: Conference Room 201
The Pain vs The Python Fix
The Pain: Renaming 200 sheets manually to follow a new naming standard.
The Python Fix: Define the pattern once, apply it to all sheets.
# Old naming: "A-101 - GROUND FLOOR PLAN"
# New naming: "A-101_Ground_Floor_Plan"
old_names = [
"A-101 - GROUND FLOOR PLAN",
"A-102 - FIRST FLOOR PLAN",
"A-201 - NORTH ELEVATION"
]
new_names = []
for old_name in old_names:
# Convert to title case
name = old_name.title()
# Replace " - " with "_"
name = name.replace(" - ", "_")
# Replace spaces with underscores
name = name.replace(" ", "_")
new_names.append(name)
for i, new_name in enumerate(new_names):
print(f"{old_names[i]} → {new_name}")
# Output:
# A-101 - GROUND FLOOR PLAN → A-101_Ground_Floor_Plan
# A-102 - FIRST FLOOR PLAN → A-102_First_Floor_Plan
# A-201 - NORTH ELEVATION → A-201_North_Elevation
Common Mistakes
Mistake 1: Trying to change a string directly
Strings are immutable (cannot be changed after creation).
sheet_name = "A-101"
sheet_name[0] = "S"
# Error: TypeError: 'str' object does not support item assignment
Instead, create a new string:
sheet_name = "A-101"
new_name = "S" + sheet_name[1:]
print(new_name) # Output: S-101
Mistake 2: Forgetting to convert numbers to strings
floor = 2
name = "Level " + floor
# Error: TypeError: can only concatenate str (not "int") to str
Fix:
floor = 2
name = "Level " + str(floor)
print(name) # Output: Level 2
# Or use f-strings
name = f"Level {floor}"
print(name) # Output: Level 2
Mistake 3: Off-by-one errors in slicing
sheet = "A-101"
number = sheet[2:4] # Trying to get "101"
print(number) # Output: 10 (not 101!)
# Correct
number = sheet[2:]
print(number) # Output: 101
Mistake 4: Case-sensitive comparisons
room_1 = "Conference Room"
room_2 = "conference room"
print(room_1 == room_2) # Output: False (different case)
# Fix: standardize case before comparing
print(room_1.lower() == room_2.lower()) # Output: True
Assignment
- Create a new file called
string_practice.py - Sheet naming exercise:
- Create variables: discipline = "A", sheet_type = "Floor Plan", level = "02"
- Combine them into: "A-Floor Plan-02"
- Convert to: "A_FLOOR_PLAN_02" (uppercase, underscores)
- Room naming standardization:
- Start with: rooms = ["conference room", "MEETING ROOM", "Break Room "]
- Standardize to title case
- Remove extra whitespace
- Print the cleaned list
- Sheet number parsing:
- Start with: sheet = "A-101-Ground-Floor-Plan"
- Extract: discipline ("A")
- Extract: number ("101")
- Extract: description ("Ground-Floor-Plan")
- Print each part separately
- File name builder:
- Variables: project = "2024-001", drawing = "Floor Plans", revision = 3
- Build: "2024-001_Floor_Plans_R03.pdf"
- Use f-strings
- Batch renaming simulation:
- Start with: ["A-101 Draft", "A-102 Draft", "A-201 Draft"]
- Replace "Draft" with "Issued"
- Print before and after
- Experiment:
- Try to change a character in a string directly (see the error)
- Slice your name to get just the first 3 letters
- Check if "Floor" is in "Ground Floor Plan"
Knowledge Check
The following questions are an opportunity to reflect on key topics in this lesson.
- What is a string?
- How do you combine two strings?
- Why can't you concatenate a string and a number directly?
- Does Python start counting string positions at 0 or 1?
- How do you extract the first 3 characters from a string?
- How do you convert a string to uppercase?
- What does
.strip()do? - How do you replace all occurrences of one word with another?
- What does
.split("-")return? - What are f-strings and why are they useful?
Additional Resources
This section contains helpful links to related content. It isn't required, so consider it supplemental.
- Python's official string documentation lists all string methods
- Real Python's guide to f-strings covers string formatting in depth
- Python string methods cheat sheet for quick reference