### Turtle Graphics (Simple 2D Drawing) The `turtle` module provides a way to draw using a "turtle" cursor. - **Import:** `import turtle` - **Create Screen & Turtle:** ```python screen = turtle.Screen() t = turtle.Turtle() ``` - **Basic Movement:** - `t.forward(distance)` - `t.backward(distance)` - `t.right(angle)` - `t.left(angle)` - `t.goto(x, y)` - **Pen Control:** - `t.penup()`: Lifts the pen (no drawing) - `t.pendown()`: Puts the pen down (drawing) - `t.pensize(width)`: Sets pen thickness - `t.pencolor("color_name" or "#hex")`: Sets pen color - **Colors & Shapes:** - `t.color("red", "blue")`: Sets pen to red, fill to blue - `t.begin_fill()`: Start filling shape - `t.end_fill()`: End filling shape - `t.circle(radius)` - `t.dot(size, "color")` - **Screen Control:** - `screen.bgcolor("lightblue")` - `screen.exitonclick()`: Closes window on click ### Digital Images & File Formats - **Digital Image:** A grid of pixels, each with a color value. - **Color Models:** - **RGB:** Red, Green, Blue components (0-255 each). Total $256^3$ colors. - **Grayscale:** Single intensity value (0-255, black to white). - **Binary (B&W):** Only black or white (0 or 1). - **Common File Formats:** - **JPEG (.jpg, .jpeg):** Lossy compression, good for photos. - **PNG (.png):** Lossless compression, supports transparency, good for graphics/web. - **GIF (.gif):** Lossless, supports animation, limited color palette (256 colors). - **BMP (.bmp):** Uncompressed, large file size, older format. - **TIFF (.tif, .tiff):** High quality, often used in printing/publishing. ### Simple Image Processing (`Pillow` / `PIL`) The `Pillow` library (a fork of `PIL`) is standard for image manipulation. - **Installation:** `pip install Pillow` - **Import:** `from PIL import Image, ImageFilter` #### Loading and Saving ```python # Load an image img = Image.open("input.jpg") print(img.format, img.size, img.mode) # e.g., JPEG (640, 480) RGB # Save an image img.save("output.png") ``` #### Basic Manipulations - **Grayscale Conversion:** ```python gray_img = img.convert("L") # "L" for Luminance (grayscale) ``` - **Black & White (Binary) Conversion:** ```python bw_img = img.convert("1") # "1" for 1-bit pixels (black and white) ``` - **Resizing:** ```python resized_img = img.resize((300, 200)) # (width, height) ``` - **Rotation:** ```python rotated_img = img.rotate(90) # Rotate 90 degrees counter-clockwise ``` - **Blurring (using `ImageFilter`):** ```python blurred_img = img.filter(ImageFilter.BLUR) # Other filters: ImageFilter.SHARPEN, ImageFilter.EMBOSS, ImageFilter.FIND_EDGES ``` - **Cropping:** ```python # (left, upper, right, lower) cropped_img = img.crop((100, 50, 400, 350)) ``` - **Applying a custom pixel transformation:** ```python def invert_pixel(pixel): r, g, b = pixel return (255 - r, 255 - g, 255 - b) inverted_img = img.point(invert_pixel) ``` ### Classes, Objects, Attributes, Methods - **Class:** A blueprint or template for creating objects. It defines the properties (attributes) and behaviors (methods) that all objects of that type will have. - Analogy: The cookie cutter. - **Object (Instance):** A specific entity created from a class. Each object has its own unique set of attribute values. - Analogy: An individual cookie made from the cutter. - **Attribute:** A variable associated with an object, representing a characteristic or state. - Analogy: A cookie's shape, color, or frosting type. - **Method:** A function associated with an object, representing a behavior or action it can perform. - Analogy: The action of eating a cookie. ### Defining Classes in Python ```python class Dog: # Class attribute (shared by all instances) species = "Canis familiaris" # Constructor method (__init__) def __init__(self, name, breed, age): # Instance attributes (unique to each object) self.name = name self.breed = breed self.age = age self.is_hungry = True # Instance method def bark(self): return f"{self.name} says Woof!" # Another instance method def eat(self): if self.is_hungry: self.is_hungry = False return f"{self.name} is now full." else: return f"{self.name} is not hungry." # Special method for string representation def __str__(self): return f"{self.name} is a {self.age}-year-old {self.breed}." # Creating objects (instances) my_dog = Dog("Buddy", "Golden Retriever", 5) your_dog = Dog("Lucy", "Beagle", 2) # Accessing attributes print(my_dog.name) # Output: Buddy print(your_dog.breed) # Output: Beagle print(Dog.species) # Output: Canis familiaris # Calling methods print(my_dog.bark()) # Output: Buddy says Woof! print(your_dog.eat()) # Output: Lucy is now full. print(my_dog) # Output: Buddy is a 5-year-old Golden Retriever. ``` ### Design with Classes (Data Modeling) - **Encapsulation:** Bundling data (attributes) and methods that operate on the data within a single unit (class). This hides internal implementation details. - **Abstraction:** Showing only essential information and hiding complex implementation. Users interact with objects through public methods without needing to know how they work internally. - **Inheritance:** A mechanism for a new class (subclass/child class) to inherit attributes and methods from an existing class (superclass/parent class). This promotes code reuse. ```python class Animal: def __init__(self, name): self.name = name def speak(self): raise NotImplementedError("Subclass must implement abstract method") class Cat(Animal): # Cat inherits from Animal def speak(self): return f"{self.name} says Meow!" my_cat = Cat("Whiskers") print(my_cat.speak()) # Output: Whiskers says Meow! ``` - **Polymorphism:** The ability of different objects to respond to the same method call in their own way. Achieved through method overriding in inherited classes. ```python animals = [Dog("Rex", "German Shepherd", 3), Cat("Mittens")] for animal in animals: print(animal.speak()) # Each animal speaks differently ``` - **Composition:** Building complex objects by combining simpler objects. An object of one class contains an object of another class as an attribute. - Example: A `Car` object might *have a* `Engine` object and `Wheel` objects. ```python class Engine: def start(self): return "Engine started." class Car: def __init__(self, make): self.make = make self.engine = Engine() # Car has an Engine def drive(self): return f"{self.make} is driving. {self.engine.start()}" my_car = Car("Toyota") print(my_car.drive()) ```