Share
Explore

# w24 PYTHON CSD 4523 Intro To Data Structuresw24 PYTHON CSD 4523 Intro To Data Structures

This is our OOAD planning document:
The Object-oriented analysis and design is what you do before you start writing code:

### To create a Python program for the card game of 21, also known as Blackjack, you can follow the algorithmic steps below, which are easy to translate into a Python program.

Algorithm for the Card Game of 21 (Blackjack)
Initializing the Game:
Create a deck of cards.
Shuffle the deck.
Deal two cards to the player and two cards to the dealer.
Player's Turn:
Allow the player to "hit" (draw another card) or "stand" (not draw any more cards) until they choose to stand or their total exceeds 21.
Dealer's Turn:
The dealer reveals their facedown card.
The dealer must hit until their total is at least 17.
Determine the Winner:
If the player's total is over 21, the player busts and loses.
If the dealer busts, the player wins.
If neither busts, the higher total wins.
If the totals are the same, it's a tie (push).
Game End:
Ask the player if they want to play again.
The provided algorithmic steps can be translated into a Python program by using lists, dictionaries, loops, and conditional statements. Additionally, you can refer to the provided resources such as the GeeksforGeeks article and the YouTube tutorial for further guidance and implementation details.
By following this algorithm, you can create a simple and functional Python program for the card game of 21.

Assignment 1: DUE Feb 8
We will introduce some software engineering concepts such as:
Object Interaction Diagram as a tool to visualize how methods call each other (Method Choreography)
Traceability Matrix to visualize how requirements connect to methods

Lexical Analysis is the part of the process in which we study the NOUNs (THING WORDS) and VERBS (action words) of the Business Domain requirements and generate them into DATA Fields and METHODS
Python programming language. Python is a high-level, interpreted language known for its simplicity and readability.

### Today we will do Assignment 1: Data Structures

In Python, there are several fundamental data structures that are widely used for organizing and managing data. Some of the basic data structures in Python include:
1. Lists: Lists are ordered collections of items that can be of any data type. They are mutable, meaning their elements can be changed.
2. Tuples: Tuples are similar to lists but are immutable, meaning they cannot be changed after creation. They are often used to store related pieces of information.
3. Dictionaries: Dictionaries are unordered collections of key-value pairs. They are often used to store and retrieve data based on a unique key.
4. Sets: Sets are unordered collections of unique elements. They are useful for performing mathematical set operations like union, intersection, and difference.
5. Arrays: Arrays are used to store a collection of elements of the same type. Python arrays can be created using the array module.
6. Stack: Stacks are a type of data structure that follows the Last In, First Out (LIFO) principle.
7. Queue: Queues are another type of data structure that follows the First In, First Out (FIFO) principle.
Understanding these data structures and their characteristics is essential for effectively organizing and manipulating data in Python.
Each data structure has its own set of operations and use cases that make them suitable for various programming tasks.

### Code drills that focuses on Python data structures, with a solution code for each exercise.

Code Drill: Python Data Structures
Exercise 1: List Operations
Write a function that takes a list of integers as input and returns a new list with only the even numbers from the input list.
Solution: ```python def filter_even_numbers(input_list): return [num for num in input_list if num % 2 == 0]
# Test the function input_list = [1, 2, 3, 4, 5, 6, 7, 8, 9] print(filter_even_numbers(input_list)) ```

### Let’s factor objects into data structures: Starting the long journey towards building the Pythonic Information System

Below is an example Python program using classes and arrays to represent customers orders in an Ice Cream Shoppe.
```python class IceShoppeOrder: def __init__(self, customer_name, flavor, size): self.customer_name = customer_name self.flavor = flavor self.size = size
# Create an array to store IceShoppeOrder objects order_list = []
# Add orders to the array order1 = IceShoppeOrder("Alice", "Chocolate", "Large") order_list.append(order1)
order2 = IceShoppeOrder("Bob", "Vanilla", "Medium") order_list.append(order2)
order3 = IceShoppeOrder("Eve", "Strawberry", "Small") order_list.append(order3)
# Print the orders for order in order_list: print(f"Customer: {order.customer_name}, Flavor: {order.flavor}, Size: {order.size}") ```
In this example, we have a `IceCreamShoppeOrder` class representing an individual customer's order at an ice cream shop. We then create instances of this class and store them in an array `order_list`. Finally, we iterate through the array to print out the details of each customer's order.
This program demonstrates the use of Python classes and arrays to model and store Ice Shoppe orders.

## ...

### Harnessing the Power of Classes, Objects, and Data Structures in Business Domain Modeling

Building the PYTHONIC information system:
In the realm of software development for business applications, leveraging the concept of classes, objects, and data structures is paramount to effectively model and represent various entities and processes within the business domain. This lecture note aims to elucidate the immense power and significance of utilizing classes and objects, and storing these objects in data structures, for business domain modeling.
1. Understanding Classes and Objects: - Classes serve as blueprints for creating objects, encapsulating data and behavior related to a specific entity or concept within the business domain. - Objects are instances of classes, representing individual occurrences of the entity or concept, and possessing their own unique state.
2. Benefits of Class and Object Modeling: - Real-world mapping: Classes and objects enable a direct mapping of real-world entities such as customers, products, orders, etc., facilitating a clear representation of business concepts within the software system. - Encapsulation and reusability: Classes encapsulate data and behavior, promoting data integrity and modularity, and allowing for reuse of code and logic across the application.
3. The Power of Data Structures: - Data structures such as arrays, lists, stacks, and queues offer efficient means to store and manage collections of objects in memory. - Arrays and lists: Ideal for storing homogeneous collections of objects, suitable for scenarios such as storing customer details, product listings, etc. - Stacks and queues: Applicable for managing sequential processes, such as order processing or task scheduling, in a manner that reflects real-world business operations.
4. Business Domain Modeling with Classes, Objects, and Data Structures: - Example: Representing customers, products, and orders in an e-commerce system using classes for Customer, Product, and Order, and storing objects of these classes in arrays and queues to manage transactions and inventory. 5. Leveraging the Power for Analysis and Operations: - Using the structured model built with classes, objects, and data structures to analyze business data, make informed decisions, and streamline business operations. - Seamless integration with databases: Classes and objects can be mapped to database tables, allowing for smooth interaction between the software system and persistent data storage.
Conclusion: In conclusion, the potency of classes, objects, and data structures in business domain modeling cannot be overstated. By leveraging these foundational concepts, software developers can construct robust and effective representations of business entities and processes, leading to agile, scalable, and maintainable business applications.
This lecture note has elucidated the power of classes, objects, and data structures in the context of business domain modeling, highlighting their pivotal role in shaping software solutions that align closely with the intricacies of the business world.
...

Exercise 2: Dictionary Operations
Write a function that takes a dictionary as input and returns a new dictionary with only the key-value pairs where the value is a string.
Solution: ```python def filter_string_values(input_dict): return {key: value for key, value in input_dict.items() if isinstance(value, str)}
# Test the function input_dict = {'a': 1, 'b': 'hello', 'c': 3.14, 'd': 'world'} print(filter_string_values(input_dict)) ```

### Exercise 3: Set Operations

Write a function that takes two sets as input and returns a new set containing the elements that are common to both input sets.
Solution: ```python def set_intersection(set1, set2): return set1.intersection(set2)
# Test the function set1 = {1, 2, 3, 4, 5} set2 = {3, 4, 5, 6, 7} print(set_intersection(set1, set2)) ```
Here are some Python code examples involving pets and colors for arrays, stack, and queue data structures:

### 5. Arrays

Arrays in Python can be implemented using the array module.
Here's an example involving pets and colors:
```python from array import array
# Create an array of colors colors = array('u', ['r', 'e', 'd', 'g', 'r', 'e', 'e', 'n', 'b', 'l', 'u', 'e'])
# Create an array of pets pets = array('u', ['c', 'a', 't', 'd', 'o', 'g', 'b', 'i', 'r', 'd'])
print(colors) print(pets) ```

### 6. Stack

In Python, you can implement a stack using a list and its built-in methods. Here's an example using pets:
```python # Implementing a stack using a list stack = []
# Push pets onto the stack stack.append('cat') stack.append('dog') stack.append('bird')
# Pop pets from the stack print(stack.pop()) # Output: 'bird' print(stack.pop()) # Output: 'dog' ```

### 7. Queue

The `queue` module in Python provides a Queue class for implementing FIFO queues. Here's an example involving colors:
```python from queue import Queue
# Create a FIFO queue for colors color_queue = Queue()
# Enqueue colors color_queue.put('red') color_queue.put('green') color_queue.put('blue')
# Dequeue colors print(color_queue.get()) # Output: 'red' print(color_queue.get()) # Output: 'green'
print(color_queue.get()) ```
These examples demonstrate the usage of arrays, stacks, and queues in Python with a fun twist involving pets and colors.
Each of these exercises focuses on manipulating a specific data structure in Python and provides an opportunity to practice working with lists, dictionaries, and sets. The solutions demonstrate how to perform the specified operations effectively using Python.
If you have any further queries or would like additional code drills, feel free to ask!

### Python offers a variety of built-in data structures that are essential for organizing and manipulating data. Here are some key Python data structures that could be covered in the assignment for Class CSD 4523:

1. Lists: Lists are ordered collections of items that can be of any data type. They are mutable, meaning their elements can be changed.
2. Tuples: Tuples are similar to lists but are immutable, meaning they cannot be changed after creation. They are often used to store related pieces of information.
3. Dictionaries: Dictionaries are unordered collections of key-value pairs. They are often used to store and retrieve data based on a unique key.
4. Sets: Sets are unordered collections of unique elements. They are useful for performing mathematical set operations like union, intersection, and difference.
5. Arrays: Arrays are used to store a collection of elements of the same type. Python arrays can be created using the array module.
6. Stack: Stacks are a type of data structure that follows the Last In, First Out (LIFO) principle.
7. Queue: Queues are another type of data structure that follows the First In, First Out (FIFO) principle.

Assignment activities:
Demonstrating how to create, manipulate, and use them effectively in Python.

### Popular card games:

Poker: A game of skill and strategy involving betting and individual play, where the goal is to have the best hand or to bluff opponents into folding.
Bridge: A trick-taking game played by four players in two partnerships, where communication and cooperation between partners are crucial.
Blackjack: Also known as 21, this game involves players trying to beat the dealer by getting as close to 21 points as possible without going over.
Solitaire: A single-player game involving the arrangement of playing cards according to specific rules, with the goal of reordering the deck by suit and rank.
These games often required strategic thinking, risk assessment, and mathematical calculation.

Of the mentioned card games, I believe that "Solitaire" would best lend itself to a vertical for Python data structures.
Solitaire involves the arrangement of cards according to specific rules, with the goal of reordering the deck by suit and rank.
This aligns well with demonstrating the use of various Python data structures, such as lists, tuples, and dictionaries, to represent and manipulate the deck of cards.
For example, the deck of cards in Solitaire could be represented as a list of tuples, where each tuple consists of the card's suit and rank. The game could involve demonstrating how to use Python's built-in data structures to shuffle the deck, draw cards, and organize them based on the game rules.
Additionally, given the nature of Solitaire as a single-player game, it could also provide an opportunity to explore concepts such as stack-like behavior for dealing and moving cards, as well as the usage of other data structures for managing game states and moves.
By implementing Solitaire as a Python program, students could gain hands-on experience in utilizing Python data structures effectively while also applying principles of clean, efficient, and well-documented code.
...

### Python card game version 1:

```
In this code lab: 1. We create a standard deck of cards using a list of dictionaries to represent each card.
2. We define a function to shuffle the deck using the `random.shuffle` function.
3. We define a function to deal cards to the tableau, a list of lists representing the columns in the solitaire game.
4. The `play_solitaire` function serves as a placeholder for the game logic.
This code lab provides a starting point for implementing a solitaire game using lists, tuples, and dictionaries to represent and manipulate the deck of cards.
You can further expand this code lab by adding functions to implement the game rules, move cards within the tableau, and manage the foundation and waste piles.
Feel free to integrate this code lab into your own solitaire game project and further customize it to meet your specific requirements!

### Python Card Game v2 (Get this running before the next class/problems? ping me on slack!!)

Let's break down the given code line by line and explain each piece of operation:
import random
# Function to create a standard deck of cards def create_deck(): ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'] suits = ['Hearts', 'Diamonds', 'Clubs', 'Spades'] deck = [{'rank': rank, 'suit': suit} for rank in ranks for suit in suits] return deck ```
1. `import random`: This line imports the `random` module, which provides various functions related to random number generation and shuffling.
2. `def create_deck():`: This line defines a function named `create_deck` that will be responsible for creating a standard deck of cards.
3. `ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']`: This line initializes a list of all the ranks in a standard deck of cards.
4. `suits = ['Hearts', 'Diamonds', 'Clubs', 'Spades']`: This line initializes a list of all the suits in a standard deck of cards.
5. `deck = [{'rank': rank, 'suit': suit} for rank in ranks for suit in suits]`: This line uses a list comprehension to create a deck of cards, where
each card is represented as a dictionary with keys 'rank' and 'suit' and their respective values from the ranks and suits lists.
The list comprehension iterates over all ranks and suits to create every combination of rank and suit, resulting in a complete deck of cards.
6. `return deck`: This line returns the created deck of cards when the `create_deck` function is called.
The next part of the code involves shuffling the deck:
```python # Function to shuffle the deck of cards def shuffle_deck(deck): random.shuffle(deck) return deck ```
1. `def shuffle_deck(deck):`: This line defines a function named `shuffle_deck` that takes a deck of cards as input and is responsible for shuffling the deck.
2. `random.shuffle(deck)`: This line uses the `shuffle` function from the `random` module to shuffle the cards in the deck.
3. `return deck`: This line returns the shuffled deck of cards.
The next part of the code involves dealing cards to the players:
```python # Function to deal cards to each player ​def deal_cards_to_players(deck): player_hands = [[], []] # Two players for _ in range(7): # Deal 7 cards to each player for hand in player_hands: card = deck.pop(0) card['facing'] = 'up' hand.append(card) return player_hands, deck ```
1. `def deal_cards_to_players(deck):`: This line defines a function named `deal_cards_to_players` that takes a deck of cards as input and is responsible for dealing cards to the players.
2. `player_hands = [[], []]`: This line initializes a list of two empty lists, representing the hands of two players.
3. `for _ in range(7):`: This line starts a loop to deal 7 cards to each player.
4. `for hand in player_hands:`: This line iterates over each player's hand to deal the cards.
5. `card = deck.pop(0)`: This line removes the first card from the deck and assigns it to the variable `card`.
6. `card['facing'] = 'up'`: This line sets the 'facing' key of the card dictionary to 'up', indicating that the card is facing up.
7. `hand.append(card)`: This line adds the dealt card to the player's hand.

8. `return player_hands, deck`: This line returns the hands (hand = the set of cards a player is holding) of the players along with the remaining deck of cards after dealing.
Lastly, the code involves simulating one round of the card game:
```python # Function to simulate one round of the card game def simulate_one_round(): deck = create_deck() shuffled_deck = shuffle_deck(deck) player_hands, shuffled_deck = deal_cards_to_players(shuffled_deck) # Print the hands of each player for i, hand in enumerate(player_hands): print(f"Player {i+1}'s Hand:") for card in hand: print(f"{card['rank']} of {card['suit']}") print() # Empty line to separate the hands
# Add game logic for one round ```
1. `def simulate_one_round():`: This line defines a function named `simulate_one_round` that simulates one round of the card game.
2. `deck = create_deck()`: This line creates a new deck of cards using the `create_deck` function.
3. `shuffled_deck = shuffle_deck(deck)`: This line shuffles the deck of cards using the `shuffle_deck` function.
4. `player_hands, shuffled_deck = deal_cards_to_players(shuffled_deck)`: This line deals cards to the players using the `deal_cards_to_players` function.
5. The subsequent code within `simulate_one_round` prints the hands of each player and then may include game logic for one round.
The lecture on the code breaks down each operation, from creating the deck of cards, shuffling the deck, dealing cards to the players, and simulating one round of the card game. This explanation provides a clear understanding of the functionality and flow of the provided Python code.

Title: Python Data Structures: A Comprehensive Survey
Lecture:
Introduction to Python Data Structures - Overview of the importance of data structures in programming - Advantages of using built-in data structures in Python
1. Lists - Explanation of lists as ordered, mutable collections - Common operations and methods (e.g., append, insert, remove, and slicing) - Use cases and examples of lists in real-world scenarios

### Here are four programming exercises focused on lists in Python, tailored towards building the Solitaire card game:

Exercise 1: Deck Initialization Task: Create a Python program to initialize a standard 52-card deck for the Solitaire game. Use a list to represent the deck and populate it with card values and suits.
Exercise 2: Shuffling the Deck Task: Implement a function that shuffles the deck of cards. Utilize the random module to shuffle the list representing the deck in place.
Exercise 3: Dealing Cards Task: Write a function to deal a specified number of cards from the deck to the tableau (playing area). This function should remove the dealt cards from the deck list and return them as a new list.
Exercise 4: Moving Cards within the Tableau Task: Create functions to facilitate moving cards within the tableau according to Solitaire's rules. For example, implementing functions to move cards between columns and to the foundation piles.
These exercises are designed to provide hands-on experience with manipulating lists, a fundamental data structure in Python, while also directly contributing to the development of the Solitaire card game. Students can test their implementations and build a functional Solitaire game by combining these exercises with additional elements such as rules enforcement, win conditions, and user interface.

Below are the Python implementations for the three exercises focusing on building the Solitaire card game.
```
These implementations provide the foundational functionalities for initializing the deck of cards, shuffling the deck, and moving cards within the tableau, essential components for the development of the Solitaire card game. These functions can be integrated into a larger program to further build and simulate the game.

2. Tuples - Understanding tuples as ordered, immutable collections - Differences between lists and tuples - Applications and benefits of utilizing tuples
3. Dictionaries - Explanation of dictionaries as collections of key-value pairs - Retrieving and modifying dictionary elements - Best practices and efficient usage of dictionaries
4. Sets - Understanding sets as collections of unique elements - Set operations (union, intersection, difference) - Implementing sets to solve problems effectively
5. Arrays - Overview of arrays for storing elements of the same type - Applications and limitations of arrays in Python - Exploring the array module and its functionalities
6. Stack and Queue - Understanding stack and queue data structures - LIFO and FIFO principles - Real-world scenarios that demonstrate the use of stacks and queues
Lab Workbook:
Lab 1: Exploring Lists and Tuples - Exercise 1: Creating and manipulating lists - Exercise 2: Exploring the properties of tuples and performing operations
Lab 2: Utilizing Dictionaries and Sets - Exercise 1: Implementing dictionaries for data retrieval and modification - Exercise 2: Performing set operations to solve specific problems
Lab 3: Understanding Stack and Queue - Exercise 1: Implementing a stack using lists and testing stack operations - Exercise 2: Utilizing queues to solve practical challenges
Lab 4: Applying Arrays in Python - Exercise 1: Working with arrays to store and manipulate homogeneous data - Exercise 2: Comparing arrays with other data structures for specific use cases
By employing this comprehensive lecture and lab workbook, students will gain a deep understanding of Python's diverse data structures, enabling them to make informed decisions when selecting and implementing data structures in their programs. Each lab exercise will provide hands-on experience, solidifying their comprehension and practical skills in utilizing Python data structures effectively.
If you need further elaboration on any specific aspect or examples to include in the lab exercises, please let me know!

### Title: Python Data Structures: A Comprehensive Survey

Lecture:
Introduction to Python Data Structures - Overview of the importance of data structures in programming - Advantages of using built-in data structures in Python
1. Lists - Explanation of lists as ordered, mutable collections - Common operations and methods (e.g., append, insert, remove, and slicing) - Use cases and examples of lists in real-world scenarios
2. Tuples - Understanding tuples as ordered, immutable collections - Differences between lists and tuples - Applications and benefits of utilizing tuples
3. Dictionaries - Explanation of dictionaries as collections of key-value pairs - Retrieving and modifying dictionary elements - Best practices and efficient usage of dictionaries
4. Sets - Understanding sets as collections of unique elements - Set operations (union, intersection, difference) - Implementing sets to solve problems effectively
5. Arrays - Overview of arrays for storing elements of the same type - Applications and limitations of arrays in Python - Exploring the array module and its functionalities
6. Stack and Queue - Understanding stack and queue data structures - LIFO and FIFO principles - Real-world scenarios that demonstrate the use of stacks and queues
Lab Workbook:
Lab 1: Exploring Lists and Tuples - Exercise 1: Creating and manipulating lists - Exercise 2: Exploring the properties of tuples and performing operations
Lab 2: Utilizing Dictionaries and Sets - Exercise 1: Implementing dictionaries for data retrieval and modification - Exercise 2: Performing set operations to solve specific problems
Lab 3: Understanding Stack and Queue - Exercise 1: Implementing a stack using lists and testing stack operations - Exercise 2: Utilizing queues to solve practical challenges
Lab 4: Applying Arrays in Python - Exercise 1: Working with arrays to store and manipulate homogeneous data - Exercise 2: Comparing arrays with other data structures for specific use cases
By employing this comprehensive lecture and lab workbook, students will gain a deep understanding of Python's diverse data structures, enabling them to make informed decisions when selecting and implementing data structures in their programs. Each lab exercise will provide hands-on experience, solidifying their comprehension and practical skills in utilizing Python data structures effectively.
If you need further elaboration on any specific aspect or examples to include in the lab exercises, please let me know!

### object composition: objects have data fields:

simple primitive data type: string, number
arrays, or other datastructures let us model collections of related objects

### The bookstore example is relatable and offers a rich context for exploring these concepts.

### Python Lab: Object-Oriented Programming with a Bookstore Model
#### Objective: To understand and apply object-oriented programming concepts in Python, focusing on:
class creation
object instantiation
inheritance
object composition
using a bookstore model.
#### Prerequisites: - Basic knowledge of Python syntax (variables, loops, functions). - Python 3.x installed on the system. - Text editor or IDE (like VSCode, PyCharm, etc.).
#### Lab Structure:

### **Part 1: Introduction to Object-Oriented Programming**

1. **Basic Concepts** - Lecture or reading material on classes, objects, attributes, methods, and inheritance. - Discuss the principles of object-oriented programming.
2. **Creating a Simple Class** - Task: Create a `Book` class with attributes like `title`, `author`, `price`. - Include a constructor (`__init__` method) and a method to display book details.
////
Below is an example of how you can create a simple `Book` class in Python, fulfilling the specified requirements:
```python ​class Book: def __init__(self, title, author, price): """ #Constructor for the Book class.
:param title: A string representing the title of the book. :param author: A string representing the author of the book. :param price: A float representing the price of the book. """ self.title = title self.author = author self.price = price
def display_book_details(self): """ Method to display the details of the book. """ print(f"Book Details:\nTitle: {self.title}\nAuthor: {self.author}\nPrice: \${self.price:.2f}")
# Example usage:
# Creating OBJECTS/ instance of the Book class ​my_book = Book("1984", "George Orwell", 15.99)
# Displaying the details of the book my_book.display_book_details() ```
### Explanation: - **Class Definition**: The `Book` class is defined with the keyword `class`. - **Constructor (`__init__` method)**: This special method is used to initialize the attributes of the class. It takes `self`, `title`, `author`, and `price` as parameters. - **Attributes**: `self.title`, `self.author`, and `self.price` are instance attributes. They are associated with each instance of the `Book` class. - **Display Method**: `display_book_details` is a method that prints the details of the book. It formats the price to two decimal places. - **Creating an Instance**: `my_book` is created as an instance of the `Book` class with the title "1984", author "George Orwell", and price 15.99. - **Using the Display Method**: The `display_book_details` method is called on the `my_book` instance to print its details.
This code provides a basic structure for a `Book` class and demonstrates how to create an instance and use its methods. It can be further expanded or modified as needed for more complex applications.
////
**Part 2: Expanding the Model with More Classes**
1. **Creating Customer and Purchase Classes** - Task: Define a `Customer` class with attributes like `name`, `email`. - Define a `Purchase` class that includes a `Customer` object and a list of `Book` objects.
2. **Understanding Relationships** - Discuss how `Purchase` is a composition of `Customer` and `Book` objects. - Explain the concept of object composition and its advantages.
---
/////
Arrays:
See sample code here:
///
A pre-facing exercise that focuses on Python arrays (more commonly known as lists in Python) is an excellent way to prepare students for understanding object collections, such as a list of book objects.
This exercise will cover the construction and basic operations on Python lists.
### Python Exercise: Introduction to Python Lists
#### Objective: To familiarize students with Python lists, their creation, and basic methods for manipulating them.
#### Prerequisites: - Basic knowledge of Python syntax (variables, loops, basic functions). - Python 3.x installed on the system. - Text editor or IDE (like VSCode, PyCharm, etc.).
#### Exercise Outline:
**Part 1: Basics of Python Lists**
1. **Creating Lists** - Task: Create a list of numbers and a list of strings. - Example: `numbers = [1, 2, 3, 4, 5]` and `fruits = ["apple", "banana", "cherry"]`.
2. **Accessing List Elements** - Task: Access and print different elements from the lists. - Example: Print the first and last elements of the `numbers` list.
3. **Modifying Lists** - Task: Add, remove, and modify elements in a list. - Example: Add a new fruit to `fruits`, remove an element from `numbers`.
---
**Part 2: Working with Lists**
1. **Iterating Over Lists** - Task: Use a loop to iterate through the `fruits` list and print each fruit.
2. **List Comprehensions** - Task: Create a new list that contains only the even numbers from the `numbers` list using list comprehension.
3. **Basic List Methods** - Task: Explore methods like `append`, `remove`, `sort`, and `reverse`. - Example: Sort the `fruits` list and then reverse it.
---
1. **Nested Lists** - Task: Create a nested list (a list of lists) and access its elements. - Example: `matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]` and access an element like `matrix[1][2]`.
2. **Slicing Lists** - Task: Use slicing to create sublists. - Example: Create a sublist of `numbers` containing only the first three elements.
3. **List Functions** - Task: Use built-in functions like `len`, `max`, `min`, and `sum` with lists. - Example: Find the length of `fruits` and the sum of `numbers`.
---
- **Combining Lists**: Combine (concatenate) two lists into one larger list. - **List to String Conversion**: Convert a list of characters into a string using `join`. - **Filtering Lists**: Use the `filter` function to filter out elements based on a condition.
#### Evaluation: - Review the lists created and the operations performed on them. - Check for understanding by asking students to explain how they would use lists in different scenarios. - Assess understanding through a short quiz or hands-on problem-solving session.
#### Additional Resources: - Provide links to official Python documentation on lists. - Suggest interactive Python tutorials or exercises available online for further practice.
This exercise will set a solid foundation for understanding how lists work in Python, which is crucial for managing collections of objects like books in a bookstore scenario. Understanding these concepts will significantly help in grasping more complex topics like object collections and operations on them.
///

### that generates 10 book instances, we first need to modify the `Book` class slightly. Then, we will add a separate function (the factory method) that will create and return a list of 10 `Book` instances.

Here's the updated `Book` class and the factory method:
```python class Book: def __init__(self, title, author, price): self.title = title self.author = author self.price = price
def display_book_details(self): print(f"Book Details:\nTitle: {self.title}\nAuthor: {self.author}\nPrice: \${self.price:.2f}")
def create_book_list(): """ Factory method to create a list of 10 Book instances. """ books = [] for i in range(1, 11): book = Book(f"Title {i}", f"Author {i}", i * 10.0) books.append(book) return books
# Using the factory method to create 10 books book_list = create_book_list()
# Displaying details of each book for book in book_list: book.display_book_details() print() # Just to add a blank line between book details for better readability ```
### Explanation: - **Factory Method (`create_book_list`)**: This function creates 10 `Book` instances. Each book is given a title, an author, and a price. The title and author are generated using the loop variable `i` (e.g., "Title 1", "Author 1", ...), and the price is set as `i * 10.0`. - **Creating Books**: Inside the loop, a new `Book` instance is created and appended to the `books` list. - **Return Value**: After all 10 books are created, the list `books` is returned. - **Displaying Book Details**: After creating the 10 books using the factory method, we iterate through the `book_list` and call `display_book_details` on each book to print their details.
This setup allows you to easily generate a predefined number of `Book` instances and can be modified to suit different requirements, such as varying the number of books or dynamically generating titles and authors.

/////

**Part 3: Implementing Object Composition**
1. **Building the Composition Relationship** - Task: In the `Purchase` class, implement methods to add books to the purchase and calculate the total cost. - Show how objects of `Customer` and `Book` are used within `Purchase`.
2. **Testing the Composition** - Task: Create instances of `Customer`, multiple `Book` objects, and then a `Purchase` object combining them. - Demonstrate the interactions between these objects.
---
**Part 4: Enhancing the Bookstore Model**
1. **Creating a Bookstore Class** - Task: Implement a `Bookstore` class that holds a collection of `Book` objects. - Include methods to add books to the bookstore and search for books by various attributes.
2. **Managing Purchases in the Bookstore** - Task: In the `Bookstore` class, add a method to handle purchases, creating `Purchase` objects. - Discuss how this represents a real-world process in an object-oriented way.
---
**Part 5: Advanced Concepts and Best Practices**
1. **Inheritance and Polymorphism** - Task: Create a subclass of `Book`, such as `Ebook`, with additional attributes. - Demonstrate polymorphism and method overriding.
2. **Object-Oriented Best Practices** - Discussion: Cover best practices in object-oriented design (like encapsulation, DRY principle). - Encourage good commenting and documentation habits.
---
**Part 6: Mini-Project**
- **Complete Bookstore System** - Task: Develop a comprehensive bookstore system incorporating all the discussed concepts. - Include advanced features like user interfaces, persistent storage, or integration with an external API for book data.
---
#### Evaluation: - Review the code written by students in each part. - Assess their understanding through quizzes, code reviews, or practical demonstrations. - Evaluate the mini-project based on code quality, implementation of OOP concepts, and creativity.
---
#### Additional Resources: - Provide links to official Python documentation and tutorials on OOP. - Suggest books or online courses for further learning.
---
This lab is designed to be interactive and progressively builds on the concepts of object-oriented programming. It aims to provide students with both the theoretical foundations and practical experience in applying these concepts to a real-world-like scenario.

//lesson 7
To implement and test the object composition in the context of the bookstore scenario, we will first define the `Customer`, `Book`, and `Purchase` classes.
We will then demonstrate how these classes can be used to create instances of customers, books, and purchases, showing the relationships between these objects.
### Implementation:
#### 1. Defining the Classes:
```python class Book: def __init__(self, title, author, price): self.title = title self.author = author self.price = price
class Customer: def __init__(self, name, email): self.name = name self.email = email
class Purchase: def __init__(self, customer): self.customer = customer self.books = [] self.total_cost = 0.0
def add_book(self, book): self.books.append(book) self.total_cost += book.price
def display_purchase_details(self): print(f"Purchase details for {self.customer.name}:") for book in self.books: print(f"- {book.title} by {book.author}, \${book.price:.2f}") print(f"Total Cost: \${self.total_cost:.2f}") ```
#### 2. Testing the Composition:
```python # Creating Book Instances book1 = Book("1984", "George Orwell", 15.99) book2 = Book("To Kill a Mockingbird", "Harper Lee", 12.99) book3 = Book("The Great Gatsby", "F. Scott Fitzgerald", 10.99)
# Creating Customer Instances customer1 = Customer("Alice Johnson", "alice@example.com") customer2 = Customer("Bob Smith", "bob@example.com")
# Displaying Purchase Details purchase1.display_purchase_details() print() purchase2.display_purchase_details() ```
### Explanation:
- **Classes**: `Customer`, `Book`, and `Purchase` classes are defined. `Customer` has name and email, `Book` has title, author, and price, and `Purchase` has a customer, a list of books, and the total cost.
- **Object Composition**: In `Purchase`, we see composition in action. A `Purchase` object is composed of a `Customer` object and a list of `Book` objects. The `add_book` method adds a book to the purchase and updates the total cost.
- **Testing**: - We create three `Book` instances (`book1`, `book2`, `book3`). - Two `Customer` instances (`customer1` and `customer2`) are created. - Two `Purchase` instances are made, each associated with a customer. Books are added to each purchase using the `add_book` method. - The `display_purchase_details` method prints out the details of each purchase, showing the customer's name, the books purchased, and the total cost.
This example demonstrates how classes can be used to create complex relationships through object composition, modeling a real-world scenario in an object-oriented way.

//lesson 7

// lesson inheritance

### Python lab to teach modules and module imports in an object-oriented context. The lab will consist of a series of tasks that progressively build on each other, ensuring a comprehensive understanding of the subject. Here's a structured outline for such a lab:

### Python Lab: Understanding Modules and Imports in Object-Oriented Python
#### Objective: To familiarize students with the concept of modules, importing modules, and integrating these concepts within object-oriented programming in Python.
#### Prerequisites: - Basic understanding of Python syntax - Fundamental knowledge of object-oriented concepts (classes, objects, etc.)
#### Tools Required: - Python 3.x installed on the system - Text editor or IDE (like VSCode, PyCharm, etc.)
#### Lab Structure:
---
**Part 1: Introduction to Modules**
1. **What is a Module?** - Brief lecture or reading material explaining modules in Python. - Key points: Reusability, Namespace, Standard Library Modules, Third-Party Modules.
2. **Creating a Simple Module** - Task: Create a file `math_operations.py` with basic functions like `add`, `subtract`. - Test by creating a separate Python script to import and use these functions.
---
**Part 2: Exploring Import Statements**
1. **Using `import`** - Task: Import the entire `math_operations` module and use its functions. - Example: `import math_operations` and then `math_operations.add(2, 3)`.
2. **Selective Import with `from`** - Task: Import specific functions from the module using `from math_operations import add`. - Discuss the difference in usage from the previous method.
3. **Importing with Aliases** - Task: Import `math_operations` using an alias like `import math_operations as mo`. - Use functions with the alias (`mo.add(3, 4)`).