Core Data Structures and Syntax
In Python, understanding the distinction between functions and methods is crucial. While functions are standalone blocks of code called by name, method are associated with objects and invoked using dot notation.
# Demonstrating method vs function invocation
text_data = "processing"
result = text_data.upper() # Method call on a string object
numeric_val = float("3.14") # Built-in function call
Python lists are mutable sequences that allow for ordered storage and slicing operations. When slicing, the start index is inclusive, but the stop index is exclusive.
dataset = [10, 20, 30, 40, 50]
print(dataset[0]) # Accesses the first element: 10
print(dataset[1:4]) # Slicing: [20, 30, 40] (element at index 4 is excluded)
Unlike lists, tuples are immutable sequences. Attempting to modify a tuple after creation will raise an error, ensuring data integrity.
coordinates = (15, 25, 35)
# coordinates[1] = 99 # This would raise a TypeError
Dictionaries provide a mapping between keys and values, which is highly efficient for lookups. They use curly braces and allow for readable data access via key names.
system_config = {"cpu_cores": 8, "memory_gb": 16}
print(system_config["cpu_cores"]) # Output: 8
Iteration and Control Flow
Loops in Python are used to iterate over sequences. The for loop can traverse lists or key-value pairs in dictionaries using the items() method.
servers = ['alpha', 'beta', 'gamma']
for node in servers:
print(f"Node {node} is active")
status_codes = {'alpha': 200, 'beta': 500, 'gamma': 200}
for node, code in status_codes.items():
if code == 200:
print(f"{node}: OK")
else:
print(f"{node}: Error detected")
Functional Programming Paradigms
Python supports functional programming features like map, filter, and lambda functions. The map function applies a specified function to every item in an iterable.
numbers = [1.5, 2.9, 3.2]
# Convert all floats to integers
integers = list(map(int, numbers))
print(integers) # Output: [1, 2, 3]
Anonymous functions, or lambda expressions, are ideal for short, throwaway functions without defining a formal name.
# Calculate cubes using lambda
cubes = list(map(lambda x: x ** 3, [2, 3, 4]))
print(cubes) # Output: [8, 27, 64]
The filter function constructs an iterator from elements of an iterable for which a function returns true. It is commonly used for data screening.
raw_data = [5, 12, 8, 3, 20]
# Keep only numbers greater than 10
filtered = list(filter(lambda x: x > 10, raw_data))
print(filtered) # Output: [12, 20]
List comprehensions offer a more concise and Pythonic way to create lists based on existing iterables, often replacing map and filter.
# Generate squares from 0 to 9
squares = [x**2 for x in range(10)]
# Sum of even numbers from 1 to 100
sum_evens = sum([x for x in range(1, 101) if x % 2 == 0])
print(sum_evens) # Output: 2550
Environment Management and Module Design
Python utilizes indentation to define code blocks, and its dynamic nature allows variables to change types. For dependency isolation, tools like Conda are essential. To switch between environments, one can list and activate specific configurations.
# Command line operations
# conda env list # List available environments
# conda activate myenv # Activate a specific environment
When writing modules, it is best practice to prevent execution code from running during an import. This is achieved using the __name__ == '__main__' guard.
config = {"host": "localhost", "port": 8080}
def start_service():
print(f"Service starting on {config['host']}...")
if __name__ == '__main__':
start_service()
Object-Oriented Programming Concepts
Classes allow for the creation of user-defined data structures. By convention, class names use CamelCase. The __init__ method serves as the constructor, and self refers to the instance being created.
class Sensor:
"""Represents a remote IoT sensor."""
def __init__(self, sensor_id, location):
self.id = sensor_id
self.location = location
self.active = False
def activate(self):
self.active = True
print(f"Sensor {self.id} at {self.location} is now active.")
def get_status(self):
state = "Active" if self.active else "Inactive"
return f"Status: {state}"
# Instantiation and usage
temp_sensor = Sensor("T-100", "Server Room")
print(temp_sensor.get_status())
temp_sensor.activate()
Inheritance allows a new class (child) to derive attributes and methods from an existing class (parent), promoting code reuse.
class AdvancedSensor(Sensor):
def __init__(self, sensor_id, location, battery_level):
super().__init__(sensor_id, location)
self.battery = battery_level
def check_battery(self):
print(f"Battery: {self.battery}%")