Chapter 1: Foundational Programming Concepts and Python Basics
Introduction
Learning to program isn't just about writing code—it's about developing a new way of thinking. This chapter introduces you to the fundamentals of Python programming by building up from the most basic building blocks: numbers, letters, and words. You'll learn the vocabulary and foundational concepts that underpin everything else in computer science.
The goal here is to master the basics of how Python represents and manipulates different kinds of data. By the end of this chapter, you'll understand how to write simple expressions and know the vocabulary you'll need to communicate about programming with others.
Arithmetic Operators
Understanding Basic Arithmetic Operations
So what's this really about? Programming languages like Python can perform mathematical calculations. They do this using special symbols called operators, which tell the computer what operation to perform.
An arithmetic operator is a symbol that represents a mathematical computation. Python supports five basic arithmetic operators that work on numbers:
- Addition with the plus sign (+): combines two numbers
- Subtraction with the minus sign (−): finds the difference between two numbers
- Multiplication with the asterisk (∗): multiplies two numbers together
- Division with the forward slash (/): divides one number by another
- Exponentiation with double asterisks (∗∗): raises a number to a power
For example, the plus sign performs addition: 30+12 evaluates to 42. The minus sign performs subtraction: 43−1 also equals 42. The asterisk multiplies: 6×7=42. The forward slash divides: 84÷2=42.0 (note the decimal point).
Two Types of Numbers in Python
Here's something important: Python distinguishes between two fundamentally different kinds of numbers.
Integers are whole numbers with no fractional part. When you add, subtract, or multiply two integers in Python, the result is always an integer. However, when you divide two integers using the forward slash (/), Python gives you a floating-point number—a number with a decimal point.
Floating-point numbers are numbers that include a decimal point and can represent values with fractional parts. The division 84÷2 produces 42.0, not 42, because division in Python always returns a floating-point result.
Python also provides a special operator for when you want division to return an integer. The integer division operator, denoted //, performs division and always rounds down to the nearest whole number. For instance, 84 // 2=42 and 85 // 2=42 (not 42.5). This behavior is also called "floor division."
Exponentiation and the Caret Confusion
The final arithmetic operator is the double asterisk (∗∗), which performs exponentiation—raising a number to a power. For example, 7∗∗2=49.
A common mistake: in some programming languages and mathematical notation, the caret symbol (∧) is used for exponentiation. However, in Python, the caret is a different operator called XOR (exclusive or), a bitwise operation. If you write 7∧2, you'll get 5, which is unexpected if you meant exponentiation!
📝 Section Recap: Python has five arithmetic operators: addition (+), subtraction (−), multiplication (∗), division (/ for floating-point or // for integer division), and exponentiation (∗∗). Python distinguishes between integers and floating-point numbers; division always produces a floating-point result unless you use the integer division operator.
Expressions
Building Blocks of Computation
What's an expression? An expression is any combination of operators and numbers (or other values) that Python can evaluate to produce a result. Every expression has a value—the result it produces.
For example, the expression 6+6∗∗2 contains two operators and three numbers. Python evaluates this to get the value 42.
Order of Operations
Python follows the same order of operations you learned in mathematics. Exponentiation happens before multiplication and division, which happen before addition and subtraction. This is crucial to understand, because it affects the result of your expressions.
For instance, consider 12+5×6. Multiplication happens first, so this equals 12+30=42, not (12+5)×6=102.
If you want to change the order of operations, use parentheses. The expression (12+5)×6 forces the addition to happen first, producing 102.
Values in Expressions
Every expression produces a value. For example, the expression 6×7 has the value 42. Understanding that expressions evaluate to values is foundational—it's how you think about computation in any programming language.
📝 Section Recap: An expression is any combination of values and operators that produces a result. Python follows the standard order of operations: exponentiation before multiplication and division before addition and subtraction. Use parentheses to override the default order when needed.
Arithmetic Functions
Built-in Functions for Numbers
In addition to operators, Python provides functions that work with numbers. A function is a reusable piece of code that performs a specific task. When you use a function, you're calling the function.
The round function takes a floating-point number and rounds it to the nearest whole number. For example, round(42.4)=42 but round(42.6)=43.
The abs function computes the absolute value of a number—the distance from zero, ignoring the sign. For a positive number like 42, the absolute value is the number itself: abs(42)=42. For a negative number like −42, the absolute value is positive: abs(−42)=42.
Function Calls and Syntax
When you call a function, the parentheses are required. If you forget them and just write abs by itself, Python returns a representation of the function object itself, not the result of running it. This is an important distinction.
A function call is an expression where you write the function name followed by arguments (the values the function should work with) inside parentheses. Common errors occur when parentheses are omitted, resulting in a syntax error—a mistake in the structure of the code that makes it impossible for Python to parse.
When Python encounters an error, it provides an error message. The first line identifies what kind of error occurred. The second line shows the problematic code with a caret (∧) pointing to where Python detected the problem. Pay attention to these messages—they guide you toward fixing mistakes.
Type Conversion Functions
The functions int, float, and str can convert values from one type to another. The int function converts a floating-point number to an integer by rounding down. The float function converts an integer to a floating-point number. These conversions are useful when you need to work with values of a specific type.
📝 Section Recap: Functions like round and abs perform specific computations on numbers. Function calls require parentheses after the function name. The int, float, and str functions convert between different data types. Omitting parentheses in a function call is a syntax error.
Strings
Representing Text in Python
Beyond numbers, Python can represent sequences of letters, called strings. A string is created by placing characters between quotation marks. You can use either single quotes ('Hello') or double quotes ("world"). Both produce the same result.
Double quotes are useful when your string contains an apostrophe, the straight quote character. For example, "It's a small " contains an apostrophe without causing a syntax error. If you tried to use single quotes with an apostrophe, Python would interpret the apostrophe as the closing quote, breaking your string.
Strings can contain spaces, punctuation, and digits. For example, 'Hello, ' is a valid string.
Operations on Strings
Two arithmetic operators work with strings in special ways. The concatenation operator (+) joins two strings end-to-end, combining them into a single string. For instance, 'Hello, ' + "it's a small " + 'world.' produces the string 'Hello, it's a small world.'
The repetition operator (∗) makes multiple copies of a string. 'Spam, ' * 4 produces 'Spam, Spam, Spam, Spam, '—the string repeated four times.
The other arithmetic operators don't work with strings and will produce an error if you try to use them.
The Length Function
Python provides a len function that computes the length of a string—how many characters it contains. len('Spam') returns 4, counting only the characters between the quotes, not the quotes themselves.
A common source of confusion: single quotes, double quotes, and backquotes have different meanings in Python. Always use straight quotation marks. If you use a backquote (backtick) instead of a single quote, you'll get a syntax error. Smart quote features in some text editors can also cause problems—be sure to use plain, straight quotes in your code.
📝 Section Recap: Strings are sequences of characters enclosed in single or double quotes. The concatenation operator (+) joins strings, and the repetition operator (∗) copies strings. The len function returns the number of characters in a string. Use straight quotation marks, not curly or smart quotes.
Values and Types
Understanding Data Types
So far, you've seen three kinds of values in Python:
- Integers are whole numbers like 2
- Floating-point numbers have decimal points, like 42.0
- Strings are sequences of characters, like
'Hello'
Each value has a type—a category that defines what kind of value it is. We sometimes say a value "belongs to" a type.
Checking and Converting Types
Python provides a type function that tells you the type of any value. type(2) returns int, type(42.0) returns float, and type('Hello, World!') returns str.
Importantly, the type functions int, float, and str can also act as conversion functions. They take a value of one type and convert it to another:
int(42.9)converts the floating-point number to an integer, rounding down to 42float(42)converts the integer to a floating-point number, producing 42.0str(42)converts the integer to a string, producing the text'42'
A Subtle Distinction: Strings That Look Like Numbers
Here's where it gets tricky. The expression '126' is a string—it looks like a number, but it's actually text. If you ask for the type, you get str, not int. This matters because you can't use strings in arithmetic without converting them first.
If you try to divide a string by a number, you get a TypeError—an error indicating that the values in the expression have the wrong type for that operation. The error message tells you which operands (the values the operator works on) have the wrong type.
Converting Between Types Safely
If you have a string containing digits, you can convert it to an integer with int('126'), which produces 42.0 (when divided by 3). If your string contains a decimal point, use float('12.6') to convert it to a floating-point number first.
Watch out for a subtle pitfall: when you write large integers with commas for readability (like 1,000,000), Python interprets this as a comma-separated sequence of integers, not as a single number. Instead, use underscores: 1_000_000 produces the correct large integer.
📝 Section Recap: Every value in Python has a type: int, float, or str. The type function reveals the type of any value. The int, float, and str functions convert values between types. A string that contains digits (like '126') is still a string and behaves very differently from an actual number.
Formal and Natural Languages
Two Different Worlds of Language
Natural languages are the languages people speak and write: English, Spanish, French, and others. These languages evolved naturally over time and are full of nuance, ambiguity, and flexibility.
Formal languages are languages designed by people for specific purposes. Mathematical notation is a formal language for denoting relationships among numbers. Programming languages, like Python, are formal languages designed to express computations unambiguously.
Key Differences
Ambiguity: Natural languages are full of ambiguity, which people resolve using context and shared understanding. Formal languages are designed to be unambiguous or nearly unambiguous—any program has one precise meaning regardless of context.
Redundancy: To compensate for ambiguity, natural languages use redundancy. They're often verbose and repetitive. Formal languages are less redundant and more concise, eliminating unnecessary words.
Literalness: Natural languages are full of idiom and metaphor. When someone says "it's raining cats and dogs," they don't mean literal cats and dogs are falling from the sky. Formal languages mean exactly what they say, nothing more or less.
Learning to Read Formal Languages
Since we all grow up speaking natural languages, it takes practice to adjust to formal languages. Formal languages are denser than natural languages, so reading them takes longer. The structure matters enormously—small errors in spelling, punctuation, or organization can make a big difference. In natural language, you can get away with slight errors; in a formal language, they often break the entire meaning.
📝 Section Recap: Natural languages (like English) are ambiguous, redundant, and figurative. Formal languages (like Python) are unambiguous, concise, and literal. Learning to write and read code requires adjusting to this different way of using language, where small errors have large consequences.
Debugging
Understanding Errors
Programmers make mistakes. Bugs are errors in programs, and debugging is the process of finding and correcting them. Debugging can be frustrating, but it's a valuable skill that extends far beyond programming.
One helpful perspective: think of the computer as an employee with particular strengths and weaknesses. It can process information at incredible speed and with perfect precision, but it lacks empathy and the ability to understand context. Your job as a debugger is to use the computer's strengths while working around its weaknesses.
A Practical Approach
When you encounter a bug, don't let your emotions interfere with problem-solving. Anger, sadness, and embarrassment are natural reactions when debugging, but they won't help you fix the code. Instead, approach the problem systematically:
- Identify the strengths you can leverage—the computer's speed and precision
- Identify the weaknesses you need to work around—its inability to understand intent or grasp context
- Use your emotions to engage with the problem thoughtfully, not to make yourself more frustrated
Learning to debug effectively is valuable far beyond programming. The ability to systematically track down errors and fix them is useful in mathematics, engineering, science, and many other fields.
📝 Section Recap: Bugs are programming errors, and debugging is the process of finding and fixing them. Debugging is a valuable skill that requires using the computer's strengths (speed, precision) while working around its weaknesses (lack of context). Approach debugging systematically and don't let frustration interfere with problem-solving.
Key Takeaways
By completing this chapter, you now understand:
- How Python represents and manipulates numbers through arithmetic operators and functions
- The distinction between integers and floating-point numbers, and when each is used
- How expressions combine operators and values to produce results
- How to work with strings and the operations available for them
- The concept of data types and how to convert between them
- The fundamental differences between natural languages (like English) and formal languages (like Python)
- How to approach debugging with patience and systematic thinking
These foundational concepts form the building blocks for everything you'll learn in the rest of the course. Master them now, and everything else will be easier.