Input and Output Operations
Reading Keyboard Input
To read input from the keyboard, use the input() function which reads a line of text:
user_input = input("Please enter something: ")
print("You entered: ", user_input)
File Operasions
To work with files, you need to open them first:
# Using context manager (recommended)
with open('datafile', 'w', encoding="utf-8") as file:
content = file.read()
# Alternative approach
file = open('datafile', 'w', encoding="utf-8")
file.close()
File Modes
| Mode | Description |
|---|---|
| r | Opens for reading only. The file pointer is placed at the beginning of the file. This is the default mode. |
| rb | Opens for reading in binary format. The file pointer is placed at the beginning of the file. |
| r+ | Opens for both reading and writing. The file pointer is placed at the begining of the file. |
| rb+ | Opens for both reading and writing in binary format. The file pointer is placed at the beginning of the file. |
| w | Opens for writing only. The file is overwritten if it exists. If the file does not exist, it creates a new file. |
| wb | Opens for writing in binary format. The file is overwritten if it exists. If the file does not exist, it creates a new file. |
| w+ | Opens for both reading and writing. The file is overwritten if it exists. If the file does not exist, it creates a new file. |
| wb+ | Opens for both reading and writing in binary format. The file is overwritten if it exists. If the file does not exist, it creates a new file. |
| a | Opens for appending. The file pointer is at the end of the file if the file exists. If the file does not exist, it creates a new file for writing. |
| ab | Opens for appending in binary format. The file pointer is at the end of the file if the file exists. If the file does not exist, it creates a new file for writing. |
| a+ | Opens for both reading and appending. The file pointer is at the end of the file if the file exists. If the file does not exist, it creates a new file for reading and writing. |
| ab+ | Opens for both reading and appending in binary format. The file pointer is at the end of the file if the file exists. If the file does not exist, it creates a new file for reading and writing. |
Reading Files
| Method | Description |
|---|---|
| file.read(size) | Reads a specified number of bytes and returns them as a string or bytes object. |
| file.readline() | Reads a single line from the file. |
| file.readlines() | Returns all lines of the file as a list. |
Writing Files
| Method | Description |
|---|---|
| file.write(string) | Writes the specified string to the file and returns the number of characters written. |
| file.flush() | Flushes the internal buffer, forcing writing of data to the file immediately. |
| file.writelines(sequence) | Writes a sequence of strings to the file. Newlines must be added manually. |
| file.tell() | Returns the current file position (as an integer). |
| file.seek(offset, whence) | Moves the file pointer to a specified position. whence=0 (beginning), 1 (current position), or 2 (end). |
| file.truncate([size]) | Truncates the file to size bytes. If size is not specified, truncates at current position. |
Pickle Module
The pickle module serializes Python objects to a byte stream:
# Reading pickled data
import pickle
pickle_file = open('data.pkl', 'rb')
data = pickle.load(pickle_file)
# Writing pickled data
output = open('data.pkl', 'wb')
pickle.dump(data, output)
JSON Format
JSON (JavaScript Object Notation) is a lightweight data interchange format:
# Writing JSON data
import json
data = {'name': 'John', 'age': 30}
json_string = json.dumps(data)
with open('data.json', 'w') as json_file:
json.dump(data, json_file)
Data Structures in Detail
Numeric Types
Mathematical Functions
| Function | Description |
|---|---|
| abs(x) | Returns the absolute value of a number (e.g., abs(-10) returns 10). |
| math.ceil(x) | Returns the smallest integer greater than or equal to x (e.g., math.ceil(4.1) returns 5). |
| math.floor(x) | Returns the largest integer less than or equal to x (e.g., math.floor(4.9) returns 4). |
| round(x[, n]) | Rounds a floating-point number to n decimal places. |
| math.exp(x) | Returns e raised to the power of x (e.g., math.exp(1) returns approximately 2.718). |
| math.log(x[, base]) | Returns the natural logarithm of x (or logarithm with specified base). |
| math.sqrt(x) | Returns the square root of x. |
| max(iterable) | Returns the largest item in an iterable. |
| min(iterable) | Returns the smallest item in an iterable. |
Random Number Functions
| Function | Description |
|---|---|
| random.choice(seq) | Returns a random element from a non-empty sequence. |
| random.randrange(start, stop[, step]) | Returns a randomly selected element from range(start, stop, step). |
| random.random() | Returns a random float between 0.0 and 1.0. |
| random.seed(x) | Initializes the random number generator with a seed value. |
| random.shuffle(seq) | Randomly shuffles a sequence in place. |
| random.uniform(a, b) | Returns a random float between a and b (inclusive of a, exclusive of b). |
String Type
String Formatting
| Symbol | Description |
|---|---|
| %c | Formats a character and its ASCII code. |
| %s | Formats a string. |
| %d | Formats an integer. |
| %f | Formats a floating-point number, with specified precision. |
| %e | Formats a floating-point number in scientific notation. |
Modern String Formatting
F-strings (formatted string literals) provide a concise way to embed expressions inside string literals:
name = 'Python'
version = 3.9
info = f'{name} version {version} is awesome'
print(info) # Output: Python version 3.9 is awesome
# Complex expressions
value = 42
result = f'The square of {value} is {value**2}'
print(result) # Output: The square of 42 is 1764
String Methods
| Method | Description |
|---|---|
| str.join(iterable) | Joins elements of an iterable with the string as a separator. |
| str.split(sep=None) | Splits a string into a list based on a separator. |
| str.find(sub) | Returns the lowest index where sub is found, or -1 if not found. |
| str.replace(old, new) | Returns a copy with all occurrences of old replaced by new. |
| str.lower() | Converts all characters to lowercase. |
| str.upper() | Converts all characters to uppercase. |
| str.strip() | Removes leading and trailing whitespace. |
| str.startswith(prefix) | Returns True if the string starts with the specified prefix. |
| str.endswith(suffix) | Returns True if the string ends with the specified suffix. |
| str.isalnum() | Returns True if all characters are alphanumeric. |
| str.isdigit() | Returns True if all characters are digits. |
Lists
Lists are ordered, mutable collections of items:
# List creation
fruits = ['apple', 'banana', 'cherry']
# Adding elements
fruits.append('orange') # Add to end
fruits.insert(1, 'mango') # Insert at position
# Removing elements
fruits.remove('banana') # Remove specific item
popped = fruits.pop() # Remove and return last item
del fruits[0] # Remove by index
# List methods
fruits.sort() # Sort in place
fruits.reverse() # Reverse in place
count = fruits.count('apple') # Count occurrences
index = fruits.index('cherry') # Find index
copy_fruits = fruits.copy() # Create a shallow copy
Stack and Queue Operations
Lists can be used as stacks (LIFO) or queues (FIFO):
# Stack operations (LIFO)
stack = []
stack.append('item1') # Push
stack.append('item2')
item = stack.pop() # Pop (returns 'item2')
# Queue operations (FIFO)
from collections import deque
queue = deque()
queue.append('item1') # Enqueue
queue.append('item2')
item = queue.popleft() # Dequeue (returns 'item1')
List Comprehensions
List comprehensions provide a concise way to create lists:
# Simple list comprehension
squares = [x**2 for x in range(10)]
# With condition
even_squares = [x**2 for x in range(10) if x % 2 == 0]
# Nested list comprehension
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
transposed = [[row[i] for row in matrix] for i in range(3)]
Tuples
Tuples are ordered, immutable collections of items:
# Tuple creation
point = (10, 20)
single_item = (5,) # Note the comma for single-item tuples
# Tuple unpacking
x, y = point
# Tuple methods
length = len(point)
max_value = max(point)
min_value = min(point)
count = point.count(10)
index = point.index(20)
Sets
Sets are unordered collections of unique elements:
# Set creation
fruits = {'apple', 'banana', 'cherry'}
# Set operations
fruits.add('orange') # Add element
fruits.update(['mango', 'grape']) # Add multiple elements
fruits.remove('banana') # Remove element (raises error if not found)
fruits.discard('banana') # Remove element (no error if not found)
fruits.pop() # Remove and return arbitrary element
# Set operations
set1 = {1, 2, 3}
set2 = {3, 4, 5}
union = set1 | set2 # Union
intersection = set1 & set2 # Intersection
difference = set1 - set2 # Difference
symmetric_diff = set1 ^ set2 # Symmetric difference
# Set methods
fruits.clear() # Remove all elements
copy_fruits = fruits.copy() # Create a shallow copy
is_subset = set1.issubset(set2) # Check subset
is_superset = set1.issuperset(set2) # Check superset
is_disjoint = set1.isdisjoint(set2) # Check no common elements
Set Comprehensions
Set comprehensions provide a concise way to create sets:
# Simple set comprehension
squares = {x**2 for x in range(10)}
# With condition
even_squares = {x**2 for x in range(10) if x % 2 == 0}
Dictionaries
Dictionaries are unordered collections of key-value pairs:
Dictionary Comprehensions
Dictionary comprehensions provide a concise way to create dictionaries:
# Simple dictionary comprehension
squares = {x: x**2 for x in range(5)}
# With condition
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
# From two lists
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
people = {name: age for name, age in zip(names, ages)}
Functions
Function Definition
Functions are defined using the def keyword, followed by the function name and parameters:
def greet(name):
return f"Hello, {name}!"
def add(a, b=0): # Default parameter
return a + b
def calculate(a, b, operation='add'): # Keyword parameter
if operation == 'add':
return a + b
elif operation == 'subtract':
return a - b
elif operation == 'multiply':
return a * b
else:
return None
Variable Arguments
Functions can accept variable numbers of positional and keyword arguments:
def process_data(data_type, *args, **kwargs):
print(f"Data type: {data_type}")
print("Positional arguments:", args)
print("Keyword arguments:", kwargs)
process_data("numbers", 1, 2, 3, format="decimal", precision=2)
Lambda Functions
Lambda functions are small anonymous functions defined with the lambda keyword:
# Simple lambda
square = lambda x: x**2
print(square(5)) # Output: 25
# Lambda with multiple arguments
add = lambda x, y: x + y
print(add(3, 4)) # Output: 7
# Lambda as arguments
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared) # Output: [1, 4, 9, 16, 25]
Decorators
Decorators are functions that modify the behavior of other functions or methods:
Classes
Class Definition
Classes are defined using the class keyword, followed by the class name:
class Person:
# Class attribute
species = "Human"
# Constructor
def __init__(self, name, age):
self.name = name # Instance attribute
self.age = age
# Instance method
def greet(self):
return f"Hello, my name is {self.name}"
# Class method
@classmethod
def set_species(cls, species):
cls.species = species
# Static method
@staticmethod
def is_adult(age):
return age >= 18
# Using the class
person = Person("Alice", 30)
print(person.greet()) # Output: Hello, my name is Alice
print(person.species) # Output: Human
print(Person.is_adult(20)) # Output: True
Inheritance
Classes can inherit attributes and methods from other classes:
Special Methods
Classes can implement special methods to define their behavior with built-in operations:
class Book:
def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
# String representation
def __str__(self):
return f"'{self.title}' by {self.author}"
# Official representation
def __repr__(self):
return f"Book('{self.title}', '{self.author}', {self.pages})"
# Length
def __len__(self):
return self.pages
# Comparison
def __eq__(self, other):
return self.title == other.title and self.author == other.author
# Addition
def __add__(self, other):
return Book(f"{self.title} & {other.title}",
f"{self.author}, {other.author}",
self.pages + other.pages)
# Using special methods
book1 = Book("Python Basics", "Jane Doe", 200)
book2 = Book("Advanced Python", "John Smith", 300)
print(book1) # Uses __str__
print(repr(book1)) # Uses __repr__
print(len(book1)) # Uses __len__
print(book1 == book2) # Uses __eq__
combined = book1 + book2
print(combined.title) # Uses __add__
Error Handling
Assertions
Assertions are used to check conditions that should always be true:
def calculate_discount(price, discount):
assert 0 <= discount <= 1, "Discount must be between 0 and 1"
return price * (1 - discount)
# This will work
print(calculate_discount(100, 0.2)) # Output: 80.0
# This will raise an AssertionError
# print(calculate_discount(100, 1.5))
Exception Handling
Try-except blocks handle exceptions gracefully:
def safe_divide(a, b):
try:
result = a / b
except ZeroDivisionError:
print("Error: Division by zero is not allowed")
return None
except TypeError:
print("Error: Both arguments must be numbers")
return None
else:
return result
finally:
print("Division operation attempted")
# Using the function
print(safe_divide(10, 2)) # Output: 5.0
print(safe_divide(10, 0)) # Output: Error message and None
print(safe_divide("10", 2)) # Output: Error message and None
Raising Exceptions
You can raise exceptions using the raise keyword:
<codedef age="" be="" cannot="" elif="" if="" negative="" raise="" validate_age="" valueerror=""> 120:
raise ValueError("Age seems unrealistic")
return True
# Using the function
try:
validate_age(150)
except ValueError as e:
print(f"Validation error: {e}")</codedef>