diff --git a/Labs/Lab.2/Lab.2.solution.py b/Labs/Lab.2/Lab.2.solution.py new file mode 100644 index 0000000..5844cff --- /dev/null +++ b/Labs/Lab.2/Lab.2.solution.py @@ -0,0 +1,572 @@ +#!/usr/bin/env python +# coding: utf-8 + +# ## Lab 2- Tic Tac Toe + +# #### Exercise 1: Wrie a function that creates an n by n matrix(of list of lists) which will represent the state of a Tic Tac Toe game. Let 0, 1, and 2, represent empty, "X", and "O", respectively. + +# In[1]: + + +player_1 = 'X' +player_2 = 'O' +empty = 0 + + +# In[2]: + + +def create_matrix(n): + matrix = list() + for i in range(n): + row = list() + for j in range(n): + row.append(empty) + + + + matrix.append(row) + return matrix + + +# In[3]: + + +tic_tac_board = create_matrix(3) + + +# In[4]: + + +tic_tac_board +# not printing correctly + + +# #### Exercise 2: Write a function that takes 2 integers n and m as input and draws a n by m game board. + +# In[5]: + + +def create_matrix_1(n,m): + matrix_2 =[[empty]*n for i in range(n)] + return matrix_2 + + +n = int(input('number = ')) +m = int(input('number = ')) +result = create_matrix_1(n,m) +print(result) + + +# #### Exercise 3: Modify exercise 2, so that it takes a matrix of the form from exercise 1 and draws a tic-tac-toe board with "X"s and "O"s. + +# In[6]: + + +# Modification of exercise 2 +def create_matrix(n): + matrix = list() + for i in range(n): + row = list() + for j in range(n): + row.append(empty) + + matrix.append(row) + return matrix + + +# In[7]: + + +tic_tac_board_1 = create_matrix(3) + + +# In[8]: + + +tic_tac_board_1 + + +# In[9]: + + +def create_matrix_2(n): + # making of empty board + n = int(input('number = ')) + matrix = [[empty]*n for i in range(n)] + + # making of even columns + for i in range(0,n,2): + matrix[1][i]=player_1 + matrix[-1][i]=player_2 + matrix[1][i]=player_2 + matrix[0][i]=player_1 + + # making of odd columns + for i in range(1,n,2): + matrix[0][i]=player_2 + matrix[2][i]=player_1 + matrix[1][1]= player_1 + + + return matrix + + +# In[10]: + + +matrix_2 = create_matrix_2(3) + + +# In[11]: + + +matrix_2 + + +# #### Exercise 4: Write a function that takes a n by n matrix representing a tic-tac-toe game, and returns -1, 0, 1, or 2 indicating the game is incomplete, the game is a draw, player 1 has won, or player 2 has won, respectivley. + +# In[12]: + + +#Labels(what they are supposed to represent) + +incomplete_game = -1 +draw = 0 +player_1_won = 1 +player_2_won = 2 + + +# In[13]: + + +def create_matrix_2(n): + # making of empty board + matrix = [[empty]*n for i in range(n)] + + # making of even columns + for i in range(0,n,2): + matrix[1][i]=player_1 + matrix[-1][i]=player_2 + matrix[1][i]=player_2 + matrix[0][i]=player_1 + + # making of odd columns + for i in range(1,n,2): + matrix[0][i]=player_1 + matrix[2][i]=player_1 + matrix[1][1]= player_1 + + # Won, draw, incomplete + if player_2*n in (): + print(player_2_won) + elif player_1*n in (): + print(player_1_won) + elif player_2*n or player_1*n not in (): + print(draw) + else: + print(incomplete_game) + + + + + return matrix + +# function that takes an n by n matrix now we need the return + + +# In[14]: + + +matrix_5 = create_matrix_2(3) +matrix_5 + + +# In[15]: + + +# first code for winning_conditions +def winning_condition(matrix, player): + m = len(matrix) + for i in range(n): + if all (matrix[i][j] == player for j in range(n)): + return True + if all (matrix[j][i] == player for j in range(n)): + return True + if all (matrix[i][i] == player for i in range(n)) or all (matrix[i][n-i-1] == player for i in range(n)): + return True + return False + + +# In[16]: + + +# Second Code for winning conditions +def create_matrix_2(n): + n = int(input('number = ')) + # making of empty board + matrix = [[empty]*n for i in range(n)] + + # making of even columns + for i in range(0,n,2): + matrix[1][i]=player_1 + matrix[-1][i]=empty + matrix[1][i]=player_2 + matrix[0][i]=empty + + # making of odd columns + for i in range(1,n,2): + matrix[0][i]=player_2 + matrix[2][i]=empty + matrix[1][1]=player_1 + + # Won, draw, incomplete + if winning_condition(matrix, player_1): + print(player_1_won) + elif winning_condition(matrix,player_2): + print(player_2_won) + elif all(matrix[i][j] != empty for j in range(n)) or all(matrix[j][i] != empty for j in range(n)): + print(draw) + elif (matrix[i][j] == empty for j in range(n)) or (matrix[j][i] == empty for j in range(n)): + print(incomplete_game) + + + + + + + + + + return matrix + + +# In[17]: + + +matrix_6 = create_matrix_2(3) +matrix_6 + + +# In[18]: + + +winning_condition(matrix_6,player_1) + + +# In[19]: + + +winning_condition(matrix_6, player_2) + + +# #### Exercise 5: Write a function that takes a game board, player number, and (x,y) coordinates and places "X" or "O" in the correct location of the game board. Make sure that you only allow filling previously empty locations. Return True or False to indicate successful placement of "X" or "O". + +# In[21]: + + +player_1 = 1 +player_2 = 2 +empty = 0 + + +# In[25]: + + +player_1_piece = "X" +player_2_piece = "O" +empty_space = "" + + +# In[23]: + + +def create_matrix(n): + matrix = list() + for i in range(n): + row = list() + for j in range(n): + row.append(empty) + + matrix.append(row) + return matrix + + +# In[40]: + + +def placing(matrix, player_number, coordinates): + # checking board dimensions + if x < 0 or x >= len(matrix) or y < 0 or y >= len(matrix[0]): + return False + # Is cell empty: + if matrix[x][y] is not empty: + return False + + # Placing the X's and O's + if player == player_1_piece: + matrix[x][y] = "X" + elif player == player_2_peice: + matrix[x][y] = "O" + else: + empty + + + +# #### Exercise 6: Modify Exercise 4 to show column and row labels so that players can specify location using "A2" or "C1". + +# In[20]: + + +def create_matrix(n): + matrix = list() + for i in range(n): + row = list() + for j in range(n): + row.append(empty) + + matrix.append(row) + return matrix + + +# In[21]: + + +tic_tac_board = create_matrix(3) +tic_tac_board + + +# In[22]: + + +def space_character(player): + if player==player_1: + return player_1_piece + if player==player_2: + return player_2_piece + else: + return empty_space + + + +# In[26]: + + +# Testing space_character: +space_character = { player_1:player_1_piece, + empty:empty_space, + player_2:player_2_piece} +space_character + + +# In[27]: + + +n = 3 + + +# In[45]: + + +def draw_board(matrix): + for i in range(n): + for j in range(n): + print(space_character[matrix[i][j]],end=" ") + print() + + + +# In[46]: + + +# Testing draw_board(matrix) +# I want to see the 0 in the empty space where the X's and O's are +# supposed to be. +draw_board(tic_tac_board) + + +# In[30]: + + +row_names = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ") +row_map = dict(zip(row_names, range(n))) + + +# In[31]: + + +row_map + + +# In[32]: + + +column_names = list(map(str,range(1, n + 1))) +column_map = dict(zip(column_names, range(n))) + + +# In[33]: + + +column_map + + +# In[36]: + + +n = 3 + + +# In[37]: + + +def create_matrix_8(matrix): + print(" ", end=" ") + for j in range(n): + print(column_names[j],end=" ") + print() + + for i in range(n): + print(row_names[i],end=" ") + for j in range(n): + print(space_character[matrix[i][j]], end=" ") + print() + + +# In[38]: + + +create_matrix_8(tic_tac_board) +# Fix the space between the letters. How?? + + +# In[41]: + + +def coordinates(length_string): + if not isinstance(length_string,str): + print_message("Bad Input. Location must be string.") + return False + + if len(length_string) !=2: + print_message("Bad Input. Location must be 2 characters.") + return False + + row=length_string[0].upper() + col=length_string[1].upper() + + if not row in row_names: + print_message("Bad Row.") + return False + if not col in column_names: + print_message("Bad Column.") + + +# In[42]: + + +coordinates("A3") + + +# In[58]: + + +def create_matrix_2(n): + # making of empty board + n = int(input('number = ')) + matrix = [[empty]*n for i in range(n)] + + # making of even columns + for i in range(0,n,2): + matrix[1][i]=player_1 + matrix[-1][i]=player_2 + matrix[1][i]=player_2 + matrix[0][i]=player_1 + + # making of odd columns + for i in range(1,n,2): + matrix[0][i]=player_2 + matrix[2][i]=player_1 + matrix[1][1]= player_1 + + + return matrix + + +# In[43]: + + +create_matrix_8(create_matrix_2(3)) + + +# #### Exericise 7: Write a function that takes a board, player number, and location specified as in exercise 6 and then calls exercise 5 to correctly modify the board. + +# In[52]: + + +def place_marker(board, player = player, x = row, y = col): + + + + + +# #### Exercise 8: Write a function called with a board and player number, takes input from the player using python's input, and modifies the board using your fucntion form exercise 7. Note that you should keep asking for input until you have gotten a valid input that results in a valid move. + +# In[53]: + + +def input_function(board,player): + while True: + print(f"Current player: {'X' if player == 1 else 'O'}") + display_matrix(create_matrix_2(n)) + row, col = get_player_input() + + success = place_marker(board, player = player, x = row, y = col) + if success: + print(f"Successfully placed {'X' if player == 1 else 'O'} at ({row}, {col}).") + break + else: + print("Invalid move! Try again.") + + +# #### Exercise 9: Use all of the previous exercises to implement a full tic-tac-toe game, where an appropriate board is drawn, w players are repeatedly asked for a location coordinates of where they wish to place a mark, and the game status is checked until a player wins or a draaw occurs. + +# In[ ]: + + + + + +# In[ ]: + + + + + +# #### Exercise 10: Test that you game works for 5x5 Tic Tac Toe. + +# In[ ]: + + + + + +# In[ ]: + + + + + +# In[ ]: + + + + + +# #### Exercise 11: (Advanced / Challenge) Develop a version of the game where one player is the computer. Note that you don't need to do an extensive search for the best move. You can have the computer simply protect against loosing and otherwise try to win wiht straight or diagonal patterns. + +# In[ ]: + + + + diff --git a/Labs/Lab.3/Lab3.solution.py b/Labs/Lab.3/Lab3.solution.py new file mode 100644 index 0000000..03eaa98 --- /dev/null +++ b/Labs/Lab.3/Lab3.solution.py @@ -0,0 +1,408 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[1]: + + +import random +x = random.random() +print("The Value of x is", x) + + +# In[2]: + + +#Exercise 1: +def generate_uniform(N, mymin, mymax): + out = [] + c = random.randrange(mymin, mymax)*x + h = mymin + c * random.random() + out.append(h) + return out + + +# In[3]: + + +data=generate_uniform(1000,-10,10) +print ("Data Type:", type(data)) +print ("Data Length:", len(data)) +if len(data)>0: + print ("Type of Data Contents:", type(data[0])) + print ("Data Minimum:", min(data)) + print ("Data Maximum:", max(data)) + + + +# In[4]: + + +#Exercise 2: Write a function that computes the mean of values in a list. +#Recall the equation for the mean of a random variable X c. +#computed on a data set of n values {xi} = {x1, x2, ..., xn}. + +def mean(Data): + m=0 + total = (1/len(Data)*sum(Data)) + m = +total + return m + + +# In[5]: + + +Data = [10, 990, 3, 5, 28, 90] +print ("Mean of Data",mean(Data)) + + +# In[6]: + + +#Exercise 2b: Write a function that computes the variance of values in a list. +# Recall the equation for the variance of a random variable X +# on a data set of n values {xi} = {x1, x2, ..., xn} +# is [x] = 1/n(Sum)(xi - x). + +def variance(Data): + n=0 + h = [] + c = (1/len(Data)*(sum(Data)-((1/(len(Data))*sum(Data))))) + h.append(c) + return h + + +# In[7]: + + +print("Variance of Data",variance(Data)) + + +# In[103]: + + +#Exercise 3: Write a function that bins +#the data so that you can create a histogram. +def histogram(x, n_bins=10, x_min = None, x_max = None): + if not x: + raise ValueError("Input list 'x' cannot be empty.") + + # Find the minimum and maximum values + x_min, x_max = min(x), max(x) + + # Calculate the bin size + bin_size = (x_max - x_min) / n_bins + + # Initialize the histogram with zeros + hist = [0] * n_bins + + # Populate the histogram + for value in x: + for i, _ in enumerate(hist): + lower_edge = x_min + i * bin_size + upper_edge = x_min + (i + 1) * bin_size + if lower_edge <= value < upper_edge: + hist[i] += 1 + + # Compute the bin edges + bin_edges = [x_min + i * bin_size for i in range(n_bins + 1)] + + return hist, bin_edges + + + + +# In[8]: + + +data = [2, 8, 4, 5.8, 7, 9, 10] + + +# In[9]: + + +histogram,bin_edges=histogram(data, 100) + + +# In[10]: + + +print("Histogram:", histogram) +print("Bin Edges:", bin_edges) + + +# In[127]: + + +#Exercise4: Write a function that uses the histogram function in the previous exercise +# to create a text-based "graph". Where each line corresponds to a bin and the number +# of #'s are proportional to the value of the data in the bin. +def draw_histogram(x, n_bins, x_min=None, character="#", max_character_per_line=20): + # Calculate the histogram + hist, bin_edges = histogram(x, n_bins, x_min) + + # Determine the maximum frequency to normalize the histogram + max_freq = max(hist) + if max_freq == 0: + max_freq = 1 # Avoid division by zero + + # Initialize the result string + result = "" + + # Iterate over the bins + for i in range(len(hist)): + left_bound = bin_edges[i] + right_bound = bin_edges[i + 1] + + # Calculate the number of characters to represent the bin + num_chars = int(hist[i] / max_freq * max_character_per_line) + + + # Create the histogram line + line = f"[{left_bound}, {right_bound}]: {character * num_chars}" + + # Add the line to the result string + result += line + "\n" + + return result + + +# In[133]: + + +data_1 = [2, 8, 4, 5.8, 7, 9, 10, 99, 89, 56, 23, 10, 67, 43, 88] + + +# In[134]: + + +hist,bin_edges=histogram(data_1, 20) + + +# In[135]: + + +histogram_text = draw_histogram(data_1, 20) + + +# In[136]: + + +print(histogram_text) + + +# ## Functional Programming + +# In[2]: + + +## Exercise5: Write a function the applies a booling function (that returns true/false) +## to every element in data, and return a list of indices of elements where the result was true. +## Use this function to find the indices of entries greater than 0.5. +def where(mylist, myfunc= 0.5): + out = [] + + for i, value in enumerate(mylist): + if value > myfunc: + out.append(i) + + return out + + + +# In[4]: + + +mylist = [0.9, 0.2, 0.08, 0.013] + + +# In[38]: + + +myfunc = 0.5 + + +# In[39]: + + +out_list = where(mylist, myfunc) + + +# In[40]: + + +out_list +# not sure what is going on here... + + +# In[ ]: + + +## Exercise 6: The inrange(mymin, mymax) function below returns a function that +## tests if it's input is between the specified values. Write corresponding +## functions that test: +## Even +## Odd +## Greater than +## Less than +## Equal +## Divisible by + + +# In[7]: + + +def in_range(mymin, mymax): + def testrange(x): + return x=mymin + return testrange + +F1=in_range(0,8) +F2=in_range(8, 16) + +#Test of in_range +print (F1(0), F1(1), F1(8), F1(16)) +print (F2(0), F2(1), F2(8), F2(16)) + +print ("Number of Entries passing F1:", len(where(mylist,F1))) +print ("Number of Entries passing F2:", len(where(mylist,F2))) + + +# In[6]: + + +mylist = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] + + +# ## Monte Carlo + +# In[8]: + + +## Exercise 7: Write a "generator" function called +## generate_function(func,x_min,x_max,N), that +## instead of generating a flat distribution, +## generates a distribution with functional form coded in func. +## Note that func will always be > 0. + + +# In[17]: + + +## Function 1: +def generate_function(func, x_min, x_max, N = 100): + out = list() + + test_x = random.range(8) + x_min, x_max = min(test_x), max(test_x) + p <= function(test_x) + + out.append(test_x) + + return out + + +# In[18]: + + +# Function 2: +def test_func(x,a=1,b=1): + return abs(a*x+b) + + +# In[19]: + + +## Testing function 1: +u = generate_function(func, x_min, x_max, N=100) + + +# In[20]: + + +# Exercise 8: Use your function to generate 1000 numbers +# that are normal distributed, using the gaussian function +# below. Confirm the mean and variance of the data is +# close to the mean and variance you specify when +# building the Gaussian. Histogram the data. + +import math + +def gaussian(mean, sigma): + def f(x): + return math.exp(-((x-mean)**2)/(2*sigma**2))/math.sqrt(math.pi*sigma) + return f +g1 = gaussian(0,1) +g2 = gaussian(10,3) + + +# In[21]: + + +g1 + + +# In[22]: + + +g2 + + +# In[26]: + + +# Exercise9: Combine your generate_function, where, and in_range functions +# above to create an integrate function. Use your integrate funciton to +# show that approximately 68% of Normal distribution is within one variance + +def integrate(func, x_min, x_max, n_points = 1000): + delta_x = (x_max - x_min) / N + integral_value = 0.5 * (func(x_min) + func(x_max)) + + for i in range(1, N): + x_i = x_min + i * delta_x + integral_value += func(x_i) + + integral_value *= delta_x + return integral_value + +def normal_pdf(x): + return (1 / math.sqrt(2 * math.pi)) * math.exp(-0.5 * x**2) + + return integral + + +# In[28]: + + +func = [990, 89, 67, 54, 6, 12, 34, 23] + + +# In[30]: + + +x_min = 6 + + +# In[31]: + + +x_max = 990 + + +# In[34]: + + +N = 1000 + + +# In[36]: + + +integrate(func, x_min, x_max, n_points = 1000) + + +# In[ ]: + + + + diff --git a/Labs/Lab.4/Lab4.Solutions.ipynb b/Labs/Lab.4/Lab4.Solutions.ipynb new file mode 100644 index 0000000..8aec9f3 --- /dev/null +++ b/Labs/Lab.4/Lab4.Solutions.ipynb @@ -0,0 +1,1825 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "32f84d6e", + "metadata": {}, + "source": [ + "## Lab 4 - Object Oriented Programming" + ] + }, + { + "cell_type": "markdown", + "id": "e6f49ea4", + "metadata": {}, + "source": [ + "#### 1. Write a \"counter\" class that can be incremented up to a specified maximum value, will print an error if an attempt is made to increment beyond that value, and allows reseting the counter." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "fb06de51", + "metadata": {}, + "outputs": [], + "source": [ + "class Counter:\n", + " def __init__(self, maximum_number):\n", + " self.a = 0\n", + " self.maximum_number = maximum_number \n", + " \n", + " def specified(self):\n", + " if self.a < self.maximum_number:\n", + " self.a +=1\n", + " else:\n", + " print(\"Error: Maximum value reached\")\n", + " \n", + " def reset(self):\n", + " self.a = 0 \n", + " \n", + " def __str__(self):\n", + " return f\"Counter Value: {self.a}\"\n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "9d6f3838", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Counter Value: 1\n", + "Counter Value: 2\n", + "Counter Value: 3\n", + "Counter Value: 4\n", + "Counter Value: 5\n", + "Counter Value: 6\n", + "Counter Value: 7\n", + "Counter Value: 8\n", + "Counter Value: 9\n", + "Counter Value: 10\n", + "Error: Maximum value reached\n", + "Counter Value: 10\n", + "Error: Maximum value reached\n", + "Counter Value: 10\n", + "Counter Value: 0\n" + ] + } + ], + "source": [ + "counter = Counter(10)\n", + "for i in range(12):\n", + " counter.specified()\n", + " print(counter)\n", + " \n", + "counter.reset()\n", + "print(counter)" + ] + }, + { + "cell_type": "markdown", + "id": "ec595dd3", + "metadata": {}, + "source": [ + "#### 2. Copy and paste your solution to question 1 and modify it so that all the data held by the counter is private. Implement functions to check the value of the counter, check the maximum value, and check if the counter is at the maximum. " + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "62d8d6d0", + "metadata": {}, + "outputs": [], + "source": [ + "class Counter:\n", + " def __init__(self, maximum_number):\n", + " self._a = 0\n", + " self._maximum_number = maximum_number \n", + " \n", + " def specified(self):\n", + " if self._a < self._maximum_number:\n", + " self._a +=1\n", + " else:\n", + " print(\"Error: Maximum value reached\")\n", + " \n", + " def reset(self):\n", + " self._a = 0 \n", + " \n", + " def __str__(self):\n", + " return f\"Counter Value: {self._a}\"\n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "0af01780", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Counter Value: 1\n", + "Counter Value: 2\n", + "Counter Value: 3\n", + "Counter Value: 4\n", + "Counter Value: 5\n", + "Counter Value: 6\n", + "Counter Value: 7\n", + "Counter Value: 8\n", + "Counter Value: 9\n", + "Counter Value: 10\n", + "Error: Maximum value reached\n", + "Counter Value: 10\n", + "Error: Maximum value reached\n", + "Counter Value: 10\n", + "Counter Value: 0\n" + ] + } + ], + "source": [ + "## It gives us the same thing, but the slashes at the front represent that the \n", + "## data is private ( Not sure if this is what you were asking for.)\n", + "counter = Counter(10)\n", + "for i in range(12):\n", + " counter.specified()\n", + " print(counter)\n", + " \n", + "counter.reset()\n", + "print(counter)" + ] + }, + { + "cell_type": "markdown", + "id": "6ea60ee5", + "metadata": {}, + "source": [ + "#### 3. Implement a class to represent a rectangle, holding the length, width, and x and y coordinates of a corner of the object. Implement functions that compute the area and perimeter of the rectangle. Make all data members private and provide accessors to retrieve values of data members. " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "cc45d99d", + "metadata": {}, + "outputs": [], + "source": [ + "class Rectangle:\n", + " def __init__(self, length, width, x, y):\n", + " self.__length = length\n", + " self.__width = width\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_length(self):\n", + " return self.__length\n", + "\n", + " def get_width(self):\n", + " return self.__width\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " return self.__length * self.__width\n", + "\n", + " def perimeter(self):\n", + " return 2 * (self.__length + self.__width)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "206e29de", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Length: 10\n", + "Width: 5\n", + "X Coordinate: 1\n", + "Y Coordinate: 6\n", + "Area: 50\n", + "Perimeter: 30\n" + ] + } + ], + "source": [ + "rect = Rectangle(10, 5, 1, 6)\n", + "print(f\"Length: {rect.get_length()}\")\n", + "print(f\"Width: {rect.get_width()}\")\n", + "print(f\"X Coordinate: {rect.get_x()}\")\n", + "print(f\"Y Coordinate: {rect.get_y()}\")\n", + "print(f\"Area: {rect.area()}\")\n", + "print(f\"Perimeter: {rect.perimeter()}\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "9653e842", + "metadata": {}, + "source": [ + "#### 4. Implement a class to represent a circle, holding the radius and x and y coordinates of center of the object. Implement functions that compute the area and perimeter of the rectangle. Make all data members private adn privide accessors to retrieve values of data members." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "059a171e", + "metadata": {}, + "outputs": [], + "source": [ + "class Circle:\n", + " def __init__(self, radius, x , y):\n", + " self.__radius = radius\n", + " self.__x = x\n", + " self.__y = y\n", + " \n", + " def get_x(self):\n", + " return self.__x\n", + " \n", + " def get_y(self):\n", + " return self.__y \n", + " \n", + " def get_radius(self):\n", + " return self.__radius \n", + " \n", + " def area(self):\n", + " return (3.1415 * (self.__radius**2))\n", + " \n", + " def circumference(self):\n", + " return (2*(3.1415*(self.__radius**2)))\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "79957c32", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "X Coordinate: 1\n", + "Y Coordinate: 6\n", + "Radius: 3\n", + "Area: 28.273500000000002\n", + "Circumference: 56.547000000000004\n" + ] + } + ], + "source": [ + "circ = Circle(3,4,5)\n", + "print(f\"X Coordinate: {rect.get_x()}\")\n", + "print(f\"Y Coordinate: {rect.get_y()}\")\n", + "print(f\"Radius: {circ.get_radius()}\")\n", + "print(f\"Area: {circ.area()}\")\n", + "print(f\"Circumference: {circ.circumference()}\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "399af377", + "metadata": {}, + "source": [ + "##### 5. Implement a common base class for the classes implemented in 3 and 4 above which implements all common methods as not implemented fucntions (virtual). Re-implement your rectangle and circule classes to inherit from the base class and overload the fucntions accordingly. " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "9bcba129", + "metadata": {}, + "outputs": [], + "source": [ + "from abc import ABC, abstractmethod\n", + "\n", + "class Shape(ABC):\n", + " def area(self):\n", + " pass\n", + "\n", + "\n", + " def perimeter(self):\n", + " pass\n", + "\n", + "class Rectangle(Shape):\n", + " def __init__(self, length, width, x, y):\n", + " self.__length = length\n", + " self.__width = width\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_length(self):\n", + " return self.__length\n", + "\n", + " def get_width(self):\n", + " return self.__width\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " return self.__length * self.__width\n", + "\n", + " def perimeter(self):\n", + " return 2 * (self.__length + self.__width)\n", + "\n", + "class Circle(Shape):\n", + " def __init__(self, radius, x, y):\n", + " self.__radius = radius\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_radius(self):\n", + " return self.__radius\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " import math\n", + " return math.pi * (self.__radius ** 2)\n", + "\n", + " def perimeter(self):\n", + " import math\n", + " return 2 * math.pi * self.__radius\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "50abfb25", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Rectangle Area: 50\n", + "Rectangle Perimeter: 30\n", + "Circle Area: 153.93804002589985\n", + "Circle Perimeter: 43.982297150257104\n" + ] + } + ], + "source": [ + "rect = Rectangle(10, 5, 1, 6)\n", + "print(f\"Rectangle Area: {rect.area()}\")\n", + "print(f\"Rectangle Perimeter: {rect.perimeter()}\")\n", + "\n", + "circle = Circle(7, 2, 3)\n", + "print(f\"Circle Area: {circle.area()}\")\n", + "print(f\"Circle Perimeter: {circle.perimeter()}\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "3ddad929", + "metadata": {}, + "source": [ + "##### 6. Implement a triangle calss analogous to the rectangle and circle in question 5." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "a6ff0c5c", + "metadata": {}, + "outputs": [], + "source": [ + "class Triangle():\n", + " def __init__(self, hypotenuse, base, height, x, y):\n", + " self.__hypotenuse = hypotenuse\n", + " self.__base = base\n", + " self.__height = height\n", + " self.__x = x\n", + " self.__y = y \n", + " \n", + " def get_hypotenuse(self):\n", + " return self.__hypotenuse\n", + " \n", + " def get_base(self):\n", + " return self.__base\n", + " \n", + " def get_height(self):\n", + " return self.__height\n", + " \n", + " def get_x(self):\n", + " return self.__x\n", + " \n", + " def get_y(self):\n", + " return self.__y\n", + " \n", + " def area(self):\n", + " return ((0.5)* self.__base *self.__height)\n", + " \n", + " def perimeter(self):\n", + " return (self.__base + self.__height + self.__hypotenuse)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "09119f42", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hypotenuse: 3\n", + "base: 4\n", + "Height: 5\n", + "X Coordinate: 8\n", + "Y Coordinate: 9\n", + " Triangle Area: >\n", + " Triangle Perimeter:>\n" + ] + } + ], + "source": [ + "tri = Triangle(3,4,5,8,9)\n", + "print(f\"Hypotenuse: {tri.get_hypotenuse()}\")\n", + "print(f\"base: {tri.get_base()}\")\n", + "print(f\"Height: {tri.get_height()}\")\n", + "print(f\"X Coordinate: {tri.get_x()}\")\n", + "print(f\"Y Coordinate: {tri.get_y()}\")\n", + "print(f\" Triangle Area: {tri.area}\")\n", + "print(f\" Triangle Perimeter:{tri.perimeter}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "25e3289a", + "metadata": {}, + "outputs": [], + "source": [ + "from abc import ABC, abstractmethod\n", + "\n", + "class Shape(ABC):\n", + " def area(self):\n", + " pass\n", + "\n", + "\n", + " def perimeter(self):\n", + " pass\n", + "\n", + "class Rectangle(Shape):\n", + " def __init__(self, length, width, x, y):\n", + " self.__length = length\n", + " self.__width = width\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_length(self):\n", + " return self.__length\n", + "\n", + " def get_width(self):\n", + " return self.__width\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " return self.__length * self.__width\n", + "\n", + " def perimeter(self):\n", + " return 2 * (self.__length + self.__width)\n", + "\n", + "class Circle(Shape):\n", + " def __init__(self, radius, x, y):\n", + " self.__radius = radius\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_radius(self):\n", + " return self.__radius\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " import math\n", + " return math.pi * (self.__radius ** 2)\n", + "\n", + " def perimeter(self):\n", + " import math\n", + " return 2 * math.pi * self.__radius\n", + "\n", + "class Triangle(Shape):\n", + " def __init__(self, hypotenuse, base, height, x, y):\n", + " self.__hypotenuse = hypotenuse\n", + " self.__base = base\n", + " self.__height = height\n", + " self.__x = x\n", + " self.__y = y \n", + " \n", + " def get_hypotenuse(self):\n", + " return self.__hypotenuse\n", + " \n", + " def get_base(self):\n", + " return self.__base\n", + " \n", + " def get_height(self):\n", + " return self.__height\n", + " \n", + " def get_x(self):\n", + " return self.__x\n", + " \n", + " def get_y(self):\n", + " return self.__y\n", + " \n", + " def area(self):\n", + " return ((0.5)*self.__base*self.__height)\n", + " \n", + " def perimeter(self):\n", + " return (self.__base+self.__height+self.__hypotenuse)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "7d9619df", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Rectangle Area: 50\n", + "Rectangle Perimeter: 30\n", + "Circle Area: 153.93804002589985\n", + "Circle Perimeter: 43.982297150257104\n", + " Triangle Area: >\n", + " Triangle Perimeter:>\n" + ] + } + ], + "source": [ + "rect = Rectangle(10, 5, 1, 6)\n", + "print(f\"Rectangle Area: {rect.area()}\")\n", + "print(f\"Rectangle Perimeter: {rect.perimeter()}\")\n", + "\n", + "circle = Circle(7, 2, 3)\n", + "print(f\"Circle Area: {circle.area()}\")\n", + "print(f\"Circle Perimeter: {circle.perimeter()}\")\n", + "\n", + "tri = Triangle(3,4,5,8,9)\n", + "print(f\" Triangle Area: {tri.area}\")\n", + "print(f\" Triangle Perimeter:{tri.perimeter}\")\n", + "# Not sure what is going on with the triangle." + ] + }, + { + "cell_type": "markdown", + "id": "42e13361", + "metadata": {}, + "source": [ + "##### 7. Add a function to the object classes, including the base, that returns a list of 16 pairs of x and y points on the parameter of the object. " + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "0fe88375", + "metadata": {}, + "outputs": [], + "source": [ + "from abc import ABC, abstractmethod\n", + "\n", + "class Shape(ABC):\n", + " @abstractmethod\n", + " def area(self):\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def perimeter(self):\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def perimeter_points(self):\n", + " pass\n", + "\n", + "class Rectangle(Shape):\n", + " def __init__(self, length, width, x, y):\n", + " self.__length = length\n", + " self.__width = width\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_length(self):\n", + " return self.__length\n", + "\n", + " def get_width(self):\n", + " return self.__width\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " return self.__length * self.__width\n", + "\n", + " def perimeter(self):\n", + " return 2 * (self.__length + self.__width)\n", + "\n", + " def perimeter_points(self):\n", + " points = []\n", + " for i in range(4):\n", + " for j in range(4):\n", + " if i % 2 == 0:\n", + " x = self.__x + (i // 2) * self.__length\n", + " else:\n", + " x = self.__x + (i // 2) * self.__length\n", + " if j % 2 == 0:\n", + " y = self.__y + (j // 2) * self.__width\n", + " else:\n", + " y = self.__y + (j // 2) * self.__width\n", + " points.append((x, y))\n", + " return points\n", + "\n", + "class Circle(Shape):\n", + " def __init__(self, radius, x, y):\n", + " self.__radius = radius\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_radius(self):\n", + " return self.__radius\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " import math\n", + " return math.pi * (self.__radius ** 2)\n", + "\n", + " def perimeter(self):\n", + " import math\n", + " return 2 * math.pi * self.__radius\n", + "\n", + " def perimeter_points(self):\n", + " import math\n", + " points = []\n", + " for i in range(16):\n", + " angle = 2 * math.pi * i / 16\n", + " x = self.__x + self.__radius * math.cos(angle)\n", + " y = self.__y + self.__radius * math.sin(angle)\n", + " points.append((x, y))\n", + " return points\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "5e2c6972", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Rectangle Perimeter Points: [(1, 6), (1, 6), (1, 11), (1, 11), (1, 6), (1, 6), (1, 11), (1, 11), (11, 6), (11, 6), (11, 11), (11, 11), (11, 6), (11, 6), (11, 11), (11, 11)]\n", + "Circle Perimeter Points: [(9.0, 3.0), (8.467156727579006, 5.678784026555629), (6.949747468305833, 7.949747468305832), (4.678784026555629, 9.467156727579006), (2.0000000000000004, 10.0), (-0.6787840265556282, 9.467156727579006), (-2.949747468305832, 7.949747468305833), (-4.467156727579007, 5.678784026555629), (-5.0, 3.000000000000001), (-4.467156727579008, 0.32121597344437225), (-2.9497474683058336, -1.9497474683058318), (-0.6787840265556322, -3.467156727579006), (1.9999999999999987, -4.0), (4.67878402655563, -3.467156727579006), (6.949747468305832, -1.9497474683058336), (8.467156727579006, 0.32121597344436736)]\n" + ] + } + ], + "source": [ + "\n", + "rect = Rectangle(10, 5, 1, 6)\n", + "print(f\"Rectangle Perimeter Points: {rect.perimeter_points()}\")\n", + "\n", + "circle = Circle(7, 2, 3)\n", + "print(f\"Circle Perimeter Points: {circle.perimeter_points()}\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "b25fc85f", + "metadata": {}, + "source": [ + "###### 8. Add a function to the object classes, including the base, that tests if a given set of and coordinates are inside of the object. You'll have to think through how to determine if a set of coordinates are inside an object for each object type." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "f0fb3530", + "metadata": {}, + "outputs": [], + "source": [ + "from abc import ABC, abstractmethod\n", + "\n", + "class Shape(ABC):\n", + " @abstractmethod\n", + " def area(self):\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def perimeter(self):\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def perimeter_points(self):\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def is_inside(self, x, y):\n", + " pass\n", + "\n", + "class Rectangle(Shape):\n", + " def __init__(self, length, width, x, y):\n", + " self.__length = length\n", + " self.__width = width\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_length(self):\n", + " return self.__length\n", + "\n", + " def get_width(self):\n", + " return self.__width\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " return self.__length * self.__width\n", + "\n", + " def perimeter(self):\n", + " return 2 * (self.__length + self.__width)\n", + "\n", + " def perimeter_points(self):\n", + " points = []\n", + " for i in range(4):\n", + " for j in range(4):\n", + " if i % 2 == 0:\n", + " x = self.__x + (i // 2) * self.__length\n", + " else:\n", + " x = self.__x + (i // 2) * self.__length\n", + " if j % 2 == 0:\n", + " y = self.__y + (j // 2) * self.__width\n", + " else:\n", + " y = self.__y + (j // 2) * self.__width\n", + " points.append((x, y))\n", + " return points\n", + "\n", + " def is_inside(self, x, y):\n", + " return self.__x <= x <= self.__x + self.__length and self.__y <= y <= self.__y + self.__width\n", + "\n", + "class Circle(Shape):\n", + " def __init__(self, radius, x, y):\n", + " self.__radius = radius\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_radius(self):\n", + " return self.__radius\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " import math\n", + " return math.pi * (self.__radius ** 2)\n", + "\n", + " def perimeter(self):\n", + " import math\n", + " return 2 * math.pi * self.__radius\n", + "\n", + " def perimeter_points(self):\n", + " import math\n", + " points = []\n", + " for i in range(16):\n", + " angle = 2 * math.pi * i / 16\n", + " x = self.__x + self.__radius * math.cos(angle)\n", + " y = self.__y + self.__radius * math.sin(angle)\n", + " points.append((x, y))\n", + " return points\n", + "\n", + " def is_inside(self, x, y):\n", + " import math\n", + " return math.sqrt((x - self.__x) ** 2 + (y - self.__y) ** 2) <= self.__radius\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "f5ddb62c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Rectangle Perimeter Points: [(1, 6), (1, 6), (1, 11), (1, 11), (1, 6), (1, 6), (1, 11), (1, 11), (11, 6), (11, 6), (11, 11), (11, 11), (11, 6), (11, 6), (11, 11), (11, 11)]\n", + "Is point (3, 8) inside rectangle? True\n", + "Circle Perimeter Points: [(9.0, 3.0), (8.467156727579006, 5.678784026555629), (6.949747468305833, 7.949747468305832), (4.678784026555629, 9.467156727579006), (2.0000000000000004, 10.0), (-0.6787840265556282, 9.467156727579006), (-2.949747468305832, 7.949747468305833), (-4.467156727579007, 5.678784026555629), (-5.0, 3.000000000000001), (-4.467156727579008, 0.32121597344437225), (-2.9497474683058336, -1.9497474683058318), (-0.6787840265556322, -3.467156727579006), (1.9999999999999987, -4.0), (4.67878402655563, -3.467156727579006), (6.949747468305832, -1.9497474683058336), (8.467156727579006, 0.32121597344436736)]\n", + "Is point (5, 5) inside circle? True\n" + ] + } + ], + "source": [ + "\n", + "rect = Rectangle(10, 5, 1, 6)\n", + "print(f\"Rectangle Perimeter Points: {rect.perimeter_points()}\")\n", + "print(f\"Is point (3, 8) inside rectangle? {rect.is_inside(3, 8)}\")\n", + "\n", + "circle = Circle(7, 2, 3)\n", + "print(f\"Circle Perimeter Points: {circle.perimeter_points()}\")\n", + "print(f\"Is point (5, 5) inside circle? {circle.is_inside(5, 5)}\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "52fbb316", + "metadata": {}, + "source": [ + "###### 9. Add a function in the base class of the object classes that returns true/false testing that the object overlaps with another object." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "d23aced9", + "metadata": {}, + "outputs": [], + "source": [ + "from abc import ABC, abstractmethod\n", + "\n", + "class Shape(ABC):\n", + " def area(self):\n", + " pass\n", + "\n", + " \n", + " def perimeter(self):\n", + " pass\n", + "\n", + " \n", + " def perimeter_points(self):\n", + " pass\n", + "\n", + " \n", + " def is_inside(self, x, y):\n", + " pass\n", + " \n", + "\n", + " def overlaps(self, other):\n", + " pass\n", + "\n", + "class Rectangle(Shape):\n", + " def __init__(self, length, width, x, y):\n", + " self.__length = length\n", + " self.__width = width\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_length(self):\n", + " return self.__length\n", + "\n", + " def get_width(self):\n", + " return self.__width\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " return self.__length * self.__width\n", + "\n", + " def perimeter(self):\n", + " return 2 * (self.__length + self.__width)\n", + "\n", + " def perimeter_points(self):\n", + " points = []\n", + " for i in range(4):\n", + " for j in range(4):\n", + " if i % 2 == 0:\n", + " x = self.__x + (i // 2) * self.__length\n", + " else:\n", + " x = self.__x + (i // 2) * self.__length\n", + " if j % 2 == 0:\n", + " y = self.__y + (j // 2) * self.__width\n", + " else:\n", + " y = self.__y + (j // 2) * self.__width\n", + " points.append((x, y))\n", + " return points\n", + "\n", + " def is_inside(self, x, y):\n", + " return self.__x <= x <= self.__x + self.__length and self.__y <= y <= self.__y + self.__width\n", + "\n", + " def overlaps(self, other):\n", + " if isinstance(other, Rectangle):\n", + " return not (self.__x + self.__length < other.get_x() or\n", + " self.__x > other.get_x() + other.get_length() or\n", + " self.__y + self.__width < other.get_y() or\n", + " self.__y > other.get_y() + other.get_width())\n", + " elif isinstance(other, Circle):\n", + " closest_x = max(self.__x, min(other.get_x(), self.__x + self.__length))\n", + " closest_y = max(self.__y, min(other.get_y(), self.__y + self.__width))\n", + " distance_x = other.get_x() - closest_x\n", + " distance_y = other.get_y() - closest_y\n", + " return (distance_x ** 2 + distance_y ** 2) < (other.get_radius() ** 2)\n", + " return False\n", + "\n", + "class Circle(Shape):\n", + " def __init__(self, radius, x, y):\n", + " self.__radius = radius\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_radius(self):\n", + " return self.__radius\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " import math\n", + " return math.pi * (self.__radius ** 2)\n", + "\n", + " def perimeter(self):\n", + " import math\n", + " return 2 * math.pi * self.__radius\n", + "\n", + " def perimeter_points(self):\n", + " import math\n", + " points = []\n", + " for i in range(16):\n", + " angle = 2 * math.pi * i / 16\n", + " x = self.__x + self.__radius * math.cos(angle)\n", + " y = self.__y + self.__radius * math.sin(angle)\n", + " points.append((x, y))\n", + " return points\n", + "\n", + " def is_inside(self, x, y):\n", + " import math\n", + " return math.sqrt((x - self.__x) ** 2 + (y - self.__y) ** 2) <= self.__radius\n", + "\n", + " def overlaps(self, other):\n", + " if isinstance(other, Circle):\n", + " import math\n", + " distance = math.sqrt((self.__x - other.get_x()) ** 2 + (self.__y - other.get_y()) ** 2)\n", + " return distance < (self.__radius + other.get_radius())\n", + " elif isinstance(other, Rectangle):\n", + " closest_x = max(other.get_x(), min(self.__x, other.get_x() + other.get_length()))\n", + " closest_y = max(other.get_y(), min(self.__y, other.get_y() + other.get_width()))\n", + " distance_x = self.__x - closest_x\n", + " distance_y = self.__y - closest_y\n", + " return (distance_x ** 2 + distance_y ** 2) < (self.__radius ** 2)\n", + " return False\n" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "42df1c70", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Do rect1 and rect2 overlap? True\n", + "Do rect1 and circle1 overlap? True\n", + "Do circle1 and circle2 overlap? True\n" + ] + } + ], + "source": [ + "\n", + "rect1 = Rectangle(10, 5, 1, 6)\n", + "rect2 = Rectangle(4, 3, 5, 8)\n", + "circle1 = Circle(7, 2, 3)\n", + "circle2 = Circle(5, 10, 10)\n", + "\n", + "print(f\"Do rect1 and rect2 overlap? {rect1.overlaps(rect2)}\")\n", + "print(f\"Do rect1 and circle1 overlap? {rect1.overlaps(circle1)}\")\n", + "print(f\"Do circle1 and circle2 overlap? {circle1.overlaps(circle2)}\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "4880e2cd", + "metadata": {}, + "source": [ + "###### 10.Copy the Canvas class from lecture to in a python file creating a paint module. Copy your classes from above into the module and implement paint functions. Implement a CompoundShape class. Create a simple drawing demonstrating that all of your classes are working." + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "93223bf8", + "metadata": {}, + "outputs": [], + "source": [ + "class Canvas:\n", + " def __init__(self, width, height):\n", + " self.width = width\n", + " self.height = height\n", + " # Empty canvas is a matrix with element being the \"space\" character\n", + " self.data = [[' '] * width for i in range(height)]\n", + "\n", + " def set_pixel(self, row, col, char='*'):\n", + " self.data[row][col] = char\n", + "\n", + " def get_pixel(self, row, col):\n", + " return self.data[row][col]\n", + " \n", + " def clear_canvas(self):\n", + " self.data = [[' '] * self.width for i in range(self.height)]\n", + " \n", + " def v_line(self, x, y, w, **kargs):\n", + " for i in range(x,x+w):\n", + " self.set_pixel(i,y, **kargs)\n", + "\n", + " def h_line(self, x, y, h, **kargs):\n", + " for i in range(y,y+h):\n", + " self.set_pixel(x,i, **kargs)\n", + " \n", + " def line(self, x1, y1, x2, y2, **kargs):\n", + " slope = (y2-y1) / (x2-x1)\n", + " for y in range(y1,y2):\n", + " x= int(slope * y)\n", + " self.set_pixel(x,y, **kargs)\n", + " \n", + " def display(self):\n", + " print(\"\\n\".join([\"\".join(row) for row in self.data]))\n", + " \n", + "from abc import ABC, abstractmethod\n", + "\n", + "class Shape(ABC):\n", + " def __init__(self, name=\"\", **kwargs):\n", + " self.name=name\n", + " self.kwargs=kwargs\n", + " \n", + " def paint(self, canvas):\n", + " pass\n", + " \n", + "class Rectangle(Shape):\n", + " def __init__(self, length, width, x, y):\n", + " self.__length = length\n", + " self.__width = width\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_length(self):\n", + " return self.__length\n", + "\n", + " def get_width(self):\n", + " return self.__width\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " return self.__length * self.__width\n", + "\n", + " def perimeter(self):\n", + " return 2 * (self.__length + self.__width)\n", + "\n", + " def perimeter_points(self):\n", + " points = []\n", + " for i in range(4):\n", + " for j in range(4):\n", + " if i % 2 == 0:\n", + " x = self.__x + (i // 2) * self.__length\n", + " else:\n", + " x = self.__x + (i // 2) * self.__length\n", + " if j % 2 == 0:\n", + " y = self.__y + (j // 2) * self.__width\n", + " else:\n", + " y = self.__y + (j // 2) * self.__width\n", + " points.append((x, y))\n", + " return points\n", + "\n", + " def is_inside(self, x, y):\n", + " return self.__x <= x <= self.__x + self.__length and self.__y <= y <= self.__y + self.__width\n", + "\n", + " def overlaps(self, other):\n", + " if isinstance(other, Rectangle):\n", + " return not (self.__x + self.__length < other.get_x() or\n", + " self.__x > other.get_x() + other.get_length() or\n", + " self.__y + self.__width < other.get_y() or\n", + " self.__y > other.get_y() + other.get_width())\n", + " elif isinstance(other, Circle):\n", + " closest_x = max(self.__x, min(other.get_x(), self.__x + self.__length))\n", + " closest_y = max(self.__y, min(other.get_y(), self.__y + self.__width))\n", + " distance_x = other.get_x() - closest_x\n", + " distance_y = other.get_y() - closest_y\n", + " return (distance_x ** 2 + distance_y ** 2) < (other.get_radius() ** 2)\n", + " return False\n", + "\n", + " def paint(self, canvas):\n", + " canvas.draw_rectangle(self.__x, self.__y, self.__x + self.__length, self.__y + self.__width, outline=\"black\", fill=\"blue\")\n", + "\n", + "class Circle(Shape):\n", + " def __init__(self, radius, x, y):\n", + " self.__radius = radius\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_radius(self):\n", + " return self.__radius\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " import math\n", + " return math.pi * (self.__radius ** 2)\n", + "\n", + " def perimeter(self):\n", + " import math\n", + " return 2 * math.pi * self.__radius\n", + "\n", + " def perimeter_points(self):\n", + " import math\n", + " points = []\n", + " for i in range(16):\n", + " angle = 2 * math.pi * i / 16\n", + " x = self.__x + self.__radius * math.cos(angle)\n", + " y = self.__y + self.__radius * math.sin(angle)\n", + " points.append((x, y))\n", + " return points\n", + "\n", + " def is_inside(self, x, y):\n", + " import math\n", + " return math.sqrt((x - self.__x) ** 2 + (y - self.__y) ** 2) <= self.__radius\n", + "\n", + " def overlaps(self, other):\n", + " if isinstance(other, Circle):\n", + " import math\n", + " distance = math.sqrt((self.__x - other.get_x()) ** 2 + (self.__y - other.get_y()) ** 2)\n", + " return distance < (self.__radius + other.get_radius())\n", + " elif isinstance(other, Rectangle):\n", + " closest_x = max(other.get_x(), min(self.__x, other.get_x() + other.get_length()))\n", + " closest_y = max(other.get_y(), min(self.__y, other.get_y() + other.get_width()))\n", + " distance_x = self.__x - closest_x\n", + " distance_y = self.__y - closest_y\n", + " return (distance_x ** 2 + distance_y ** 2) < (self.__radius ** 2)\n", + " return False\n", + "\n", + " def paint(self, canvas):\n", + " canvas.draw_circle(self.__x, self.__y, self.__radius, outline=\"black\", fill=\"red\")\n", + "\n", + "class CompoundShape(Shape):\n", + " def __init__(self):\n", + " self.shapes = []\n", + "\n", + " def add_shape(self, shape):\n", + " self.shapes.append(shape)\n", + "\n", + " def area(self):\n", + " return sum(shape.area() for shape in self.shapes)\n", + "\n", + " def perimeter(self):\n", + " return sum(shape.perimeter() for shape in self.shapes)\n", + "\n", + " def perimeter_points(self):\n", + " points = []\n", + " for shape in self.shapes:\n", + " points.extend(shape.perimeter_points())\n", + " return points\n", + "\n", + " def is_inside(self, x, y):\n", + " return any(shape.is_inside(x, y) for shape in self.shapes)\n", + "\n", + " def overlaps(self, other):\n", + " return any(shape.overlaps(other) for shape in self.shapes)\n", + "\n", + " def paint(self, canvas):\n", + " for shape in self.shapes:\n", + " shape.paint(canvas)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "aa2067de", + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'Canvas' object has no attribute 'draw_rectangle'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[38], line 9\u001b[0m\n\u001b[1;32m 6\u001b[0m compound_shape\u001b[38;5;241m.\u001b[39madd_shape(rect)\n\u001b[1;32m 7\u001b[0m compound_shape\u001b[38;5;241m.\u001b[39madd_shape(circle)\n\u001b[0;32m----> 9\u001b[0m \u001b[43mrect\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpaint\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcanvas\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 10\u001b[0m circle\u001b[38;5;241m.\u001b[39mpaint(canvas)\n\u001b[1;32m 11\u001b[0m compound_shape\u001b[38;5;241m.\u001b[39mpaint(canvas)\n", + "Cell \u001b[0;32mIn[37], line 102\u001b[0m, in \u001b[0;36mRectangle.paint\u001b[0;34m(self, canvas)\u001b[0m\n\u001b[1;32m 101\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mpaint\u001b[39m(\u001b[38;5;28mself\u001b[39m, canvas):\n\u001b[0;32m--> 102\u001b[0m \u001b[43mcanvas\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdraw_rectangle\u001b[49m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m__x, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m__y, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m__x \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m__length, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m__y \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m__width, outline\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mblack\u001b[39m\u001b[38;5;124m\"\u001b[39m, fill\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mblue\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", + "\u001b[0;31mAttributeError\u001b[0m: 'Canvas' object has no attribute 'draw_rectangle'" + ] + } + ], + "source": [ + "if __name__ == \"__main__\":\n", + " canvas = Canvas(400, 400)\n", + " rect = Rectangle(100, 50, 50, 50)\n", + " circle = Circle(30, 200, 200)\n", + " compound_shape = CompoundShape()\n", + " compound_shape.add_shape(rect)\n", + " compound_shape.add_shape(circle)\n", + "\n", + " rect.paint(canvas)\n", + " circle.paint(canvas)\n", + " compound_shape.paint(canvas)\n", + "\n", + " canvas.mainloop()" + ] + }, + { + "cell_type": "markdown", + "id": "3cf9670c", + "metadata": {}, + "source": [ + "###### 11.Create a RasterDrawing class. Demonstrate that you can create a drawing made of several shapes, paint the drawing, modify the drawing, and paint it again." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "e01d3e01", + "metadata": {}, + "outputs": [], + "source": [ + "from abc import ABC, abstractmethod\n", + "import tkinter as tk\n", + "\n", + "class Canvas:\n", + " def __init__(self, width, height):\n", + " self.root = tk.Tk()\n", + " self.canvas = tk.Canvas(self.root, width=width, height=height)\n", + " self.canvas.pack()\n", + "\n", + " def draw_rectangle(self, x1, y1, x2, y2, **kwargs):\n", + " self.canvas.create_rectangle(x1, y1, x2, y2, **kwargs)\n", + "\n", + " def draw_circle(self, x, y, r, **kwargs):\n", + " self.canvas.create_oval(x-r, y-r, x+r, y+r, **kwargs)\n", + "\n", + " def mainloop(self):\n", + " self.root.mainloop()\n", + "\n", + "class Shape(ABC):\n", + " @abstractmethod\n", + " def area(self):\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def perimeter(self):\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def perimeter_points(self):\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def is_inside(self, x, y):\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def overlaps(self, other):\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def paint(self, canvas):\n", + " pass\n", + "\n", + "class Rectangle(Shape):\n", + " def __init__(self, length, width, x, y):\n", + " self.__length = length\n", + " self.__width = width\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_length(self):\n", + " return self.__length\n", + "\n", + " def get_width(self):\n", + " return self.__width\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " return self.__length * self.__width\n", + "\n", + " def perimeter(self):\n", + " return 2 * (self.__length + self.__width)\n", + "\n", + " def perimeter_points(self):\n", + " points = []\n", + " for i in range(4):\n", + " for j in range(4):\n", + " if i % 2 == 0:\n", + " x = self.__x + (i // 2) * self.__length\n", + " else:\n", + " x = self.__x + (i // 2) * self.__length\n", + " if j % 2 == 0:\n", + " y = self.__y + (j // 2) * self.__width\n", + " else:\n", + " y = self.__y + (j // 2) * self.__width\n", + " points.append((x, y))\n", + " return points\n", + "\n", + " def is_inside(self, x, y):\n", + " return self.__x <= x <= self.__x + self.__length and self.__y <= y <= self.__y + self.__width\n", + "\n", + " def overlaps(self, other):\n", + " if isinstance(other, Rectangle):\n", + " return not (self.__x + self.__length < other.get_x() or\n", + " self.__x > other.get_x() + other.get_length() or\n", + " self.__y + self.__width < other.get_y() or\n", + " self.__y > other.get_y() + other.get_width())\n", + " elif isinstance(other, Circle):\n", + " closest_x = max(self.__x, min(other.get_x(), self.__x + self.__length))\n", + " closest_y = max(self.__y, min(other.get_y(), self.__y + self.__width))\n", + " distance_x = other.get_x() - closest_x\n", + " distance_y = other.get_y() - closest_y\n", + " return (distance_x ** 2 + distance_y ** 2) < (other.get_radius() ** 2)\n", + " return False\n", + "\n", + " def paint(self, canvas):\n", + " canvas.draw_rectangle(self.__x, self.__y, self.__x + self.__length, self.__y + self.__width, outline=\"black\", fill=\"blue\")\n", + "\n", + "class Circle(Shape):\n", + " def __init__(self, radius, x, y):\n", + " self.__radius = radius\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_radius(self):\n", + " return self.__radius\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " import math\n", + " return math.pi * (self.__radius ** 2)\n", + "\n", + " def perimeter(self):\n", + " import math\n", + " return 2 * math.pi * self.__radius\n", + "\n", + " def perimeter_points(self):\n", + " import math\n", + " points = []\n", + " for i in range(16):\n", + " angle = 2 * math.pi * i / 16\n", + " x = self.__x + self.__radius * math.cos(angle)\n", + " y = self.__y + self.__radius * math.sin(angle)\n", + " points.append((x, y))\n", + " return points\n", + "\n", + " def is_inside(self, x, y):\n", + " import math\n", + " return math.sqrt((x - self.__x) ** 2 + (y - self.__y) ** 2) <= self.__radius\n", + "\n", + " def overlaps(self, other):\n", + " if isinstance(other, Circle):\n", + " import math\n", + " distance = math.sqrt((self.__x - other.get_x()) ** 2 + (self.__y - other.get_y()) ** 2)\n", + " return distance < (self.__radius + other.get_radius())\n", + " elif isinstance(other, Rectangle):\n", + " closest_x = max(other.get_x(), min(self.__x, other.get_x() + other.get_length()))\n", + " closest_y = max(other.get_y(), min(self.__y, other.get_y() + other.get_width()))\n", + " distance_x = self.__x - closest_x\n", + " distance_y = self.__y - closest_y\n", + " return (distance_x ** 2 + distance_y ** 2) < (self.__radius ** 2)\n", + " return False\n", + "\n", + " def paint(self, canvas):\n", + " canvas.draw_circle(self.__x, self.__y, self.__radius, outline=\"black\", fill=\"red\")\n", + "\n", + "class CompoundShape(Shape):\n", + " def __init__(self):\n", + " self.shapes = []\n", + "\n", + " def add_shape(self, shape):\n", + " self.shapes.append(shape)\n", + "\n", + " def area(self):\n", + " return sum(shape.area() for shape in self.shapes)\n", + "\n", + " def perimeter(self):\n", + " return sum(shape.perimeter() for shape in self.shapes)\n", + "\n", + " def perimeter_points(self):\n", + " points = []\n", + " for shape in self.shapes:\n", + " points.extend(shape.perimeter_points())\n", + " return points\n", + "\n", + " def is_inside(self, x, y):\n", + " return any(shape.is_inside(x, y) for shape in self.shapes)\n", + "\n", + " def overlaps(self, other):\n", + " return any(shape.overlaps(other) for shape in self.shapes)\n", + "\n", + " def paint(self, canvas):\n", + " for shape in self.shapes:\n", + " shape.paint(canvas)\n", + "\n", + "class RasterDrawing:\n", + " def __init__(self):\n", + " self.shapes = []\n", + "\n", + " def add_shape(self, shape):\n", + " self.shapes.append(shape)\n", + "\n", + " def paint(self, canvas):\n", + " for shape in self.shapes:\n", + " shape.paint(canvas)\n", + "\n", + " def modify_shape(self, index, new_shape):\n", + " if 0 <= index < len(self.shapes):\n", + " self.shapes[index] = new_shape\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "29e595e4", + "metadata": {}, + "outputs": [], + "source": [ + "# Example usage:\n", + "if __name__ == \"__main__\":\n", + " canvas = Canvas(400, 400)\n", + " rect = Rectangle(100, 50, 50, 50)\n", + " circle = Circle(30, 200, 200)\n", + " compound_shape = CompoundShape()\n", + " compound_shape.add_shape(rect)\n", + " compound_shape.add_shape(circle)\n", + "\n", + " drawing = RasterDrawing()\n", + " drawing.add_shape(rect)\n", + " drawing.add_shape(circle)\n", + " drawing.add_shape(compound_shape)\n", + "\n", + " # Paint the initial drawing\n", + " drawing.paint(canvas)\n", + " canvas.mainloop()\n", + "\n", + " # Modify the drawing\n", + " new_rect = Rectangle(150, 75, 100, 100)\n", + " drawing.modify_shape(0, new_rect)\n", + "\n", + " # Paint \n", + " canvas = Canvas(400, 400)\n", + " drawing.paint(canvas)\n", + " canvas.mainloop()\n" + ] + }, + { + "cell_type": "markdown", + "id": "f4e0d2ae", + "metadata": {}, + "source": [ + "###### 12. Implement the ability to load/save raster drawings and demonstate that your method works. One way to implement this ability: Overload __repr__ functions of all objects to return strings of the python code that would construct the object. In the save method of raster drawing class, store the representations into the file.Write a loader function that reads the file and uses eval to instantiate the object." + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "9b8c391e", + "metadata": {}, + "outputs": [], + "source": [ + "from abc import ABC, abstractmethod\n", + "import tkinter as tk\n", + "\n", + "class Canvas:\n", + " def __init__(self, width, height):\n", + " self.root = tk.Tk()\n", + " self.canvas = tk.Canvas(self.root, width=width, height=height)\n", + " self.canvas.pack()\n", + "\n", + " def draw_rectangle(self, x1, y1, x2, y2, **kwargs):\n", + " self.canvas.create_rectangle(x1, y1, x2, y2, **kwargs)\n", + "\n", + " def draw_circle(self, x, y, r, **kwargs):\n", + " self.canvas.create_oval(x-r, y-r, x+r, y+r, **kwargs)\n", + "\n", + " def mainloop(self):\n", + " self.root.mainloop()\n", + "\n", + "class Shape(ABC):\n", + " @abstractmethod\n", + " def area(self):\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def perimeter(self):\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def perimeter_points(self):\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def is_inside(self, x, y):\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def overlaps(self, other):\n", + " pass\n", + "\n", + " @abstractmethod\n", + " def paint(self, canvas):\n", + " pass\n", + "\n", + "class Rectangle(Shape):\n", + " def __init__(self, length, width, x, y):\n", + " self.__length = length\n", + " self.__width = width\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_length(self):\n", + " return self.__length\n", + "\n", + " def get_width(self):\n", + " return self.__width\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " return self.__length * self.__width\n", + "\n", + " def perimeter(self):\n", + " return 2 * (self.__length + self.__width)\n", + "\n", + " def perimeter_points(self):\n", + " points = []\n", + " for i in range(4):\n", + " for j in range(4):\n", + " if i % 2 == 0:\n", + " x = self.__x + (i // 2) * self.__length\n", + " else:\n", + " x = self.__x + (i // 2) * self.__length\n", + " if j % 2 == 0:\n", + " y = self.__y + (j // 2) * self.__width\n", + " else:\n", + " y = self.__y + (j // 2) * self.__width\n", + " points.append((x, y))\n", + " return points\n", + "\n", + " def is_inside(self, x, y):\n", + " return self.__x <= x <= self.__x + self.__length and self.__y <= y <= self.__y + self.__width\n", + "\n", + " def overlaps(self, other):\n", + " if isinstance(other, Rectangle):\n", + " return not (self.__x + self.__length < other.get_x() or\n", + " self.__x > other.get_x() + other.get_length() or\n", + " self.__y + self.__width < other.get_y() or\n", + " self.__y > other.get_y() + other.get_width())\n", + " elif isinstance(other, Circle):\n", + " closest_x = max(self.__x, min(other.get_x(), self.__x + self.__length))\n", + " closest_y = max(self.__y, min(other.get_y(), self.__y + self.__width))\n", + " distance_x = other.get_x() - closest_x\n", + " distance_y = other.get_y() - closest_y\n", + " return (distance_x ** 2 + distance_y ** 2) < (other.get_radius() ** 2)\n", + " return False\n", + "\n", + " def paint(self, canvas):\n", + " canvas.draw_rectangle(self.__x, self.__y, self.__x + self.__length, self.__y + self.__width, outline=\"black\", fill=\"blue\")\n", + "\n", + "class Circle(Shape):\n", + " def __init__(self, radius, x, y):\n", + " self.__radius = radius\n", + " self.__x = x\n", + " self.__y = y\n", + "\n", + " def get_radius(self):\n", + " return self.__radius\n", + "\n", + " def get_x(self):\n", + " return self.__x\n", + "\n", + " def get_y(self):\n", + " return self.__y\n", + "\n", + " def area(self):\n", + " import math\n", + " return math.pi * (self.__radius ** 2)\n", + "\n", + " def perimeter(self):\n", + " import math\n", + " return 2 * math.pi * self.__radius\n", + "\n", + " def perimeter_points(self):\n", + " import math\n", + " points = []\n", + " for i in range(16):\n", + " angle = 2 * math.pi * i / 16\n", + " x = self.__x + self.__radius * math.cos(angle)\n", + " y = self.__y + self.__radius * math.sin(angle)\n", + " points.append((x, y))\n", + " return points\n", + "\n", + " def is_inside(self, x, y):\n", + " import math\n", + " return math.sqrt((x - self.__x) ** 2 + (y - self.__y) ** 2) <= self.__radius\n", + "\n", + " def overlaps(self, other):\n", + " if isinstance(other, Circle):\n", + " import math\n", + " distance = math.sqrt((self.__x - other.get_x()) ** 2 + (self.__y - other.get_y()) ** 2)\n", + " return distance < (self.__radius + other.get_radius())\n", + " elif isinstance(other, Rectangle):\n", + " closest_x = max(other.get_x(), min(self.__x, other.get_x() + other.get_length()))\n", + " closest_y = max(other.get_y(), min(self.__y, other.get_y() + other.get_width()))\n", + " distance_x = self.__x - closest_x\n", + " distance_y = self.__y - closest_y\n", + " return (distance_x ** 2 + distance_y ** 2) < (self.__radius ** 2)\n", + " return False\n", + "\n", + " def paint(self, canvas):\n", + " canvas.draw_circle(self.__x, self.__y, self.__radius, outline=\"black\", fill=\"red\")\n", + "\n", + "class CompoundShape(Shape):\n", + " def __init__(self):\n", + " self.shapes = []\n", + "\n", + " def add_shape(self, shape):\n", + " self.shapes.append(shape)\n", + "\n", + " def area(self):\n", + " return sum(shape.area() for shape in self.shapes)\n", + "\n", + " def perimeter(self):\n", + " return sum(shape.perimeter() for shape in self.shapes)\n", + "\n", + " def perimeter_points(self):\n", + " points = []\n", + " for shape in self.shapes:\n", + " points.extend(shape.perimeter_points())\n", + " return points\n", + "\n", + " def is_inside(self, x, y):\n", + " return any(shape.is_inside(x, y) for shape in self.shapes)\n", + "\n", + " def overlaps(self, other):\n", + " return any(shape.overlaps(other) for shape in self.shapes)\n", + "\n", + " def paint(self, canvas):\n", + " for shape in self.shapes:\n", + " shape.paint(canvas)\n", + "\n", + "class RasterDrawing:\n", + " def __init__(self):\n", + " self.shapes = []\n", + "\n", + " def add_shape(self, shape):\n", + " self.shapes.append(shape)\n", + "\n", + " def paint(self, canvas):\n", + " for shape in self.shapes:\n", + " shape.paint(canvas)\n", + "\n", + " def modify_shape(self, index, new_shape):\n", + " if 0 <= index < len(self.shapes):\n", + " self.shapes[index] = new_shape" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "245e9585", + "metadata": {}, + "outputs": [], + "source": [ + "if __name__ == \"__main__\":\n", + " canvas = Canvas(400, 400)\n", + " rect = Rectangle(100, 50, 50, 50)\n", + " circle = Circle(30, 200, 200)\n", + " compound_shape = CompoundShape()\n", + " compound_shape.add_shape(rect)\n", + " compound_shape.add_shape(circle)\n", + "\n", + " drawing = RasterDrawing()\n", + " drawing.add_shape(rect)\n", + " drawing.add_shape(circle)\n", + " drawing.add_shape(compound_shape)\n", + "\n", + " # Paint the initial drawing\n", + " drawing.paint(canvas)\n", + " canvas.mainloop()\n", + "\n", + " # Modify the drawing\n", + " new_rect = Rectangle(150, 75, 100, 100)\n", + " drawing.modify_shape(0, new_rect)\n", + "\n", + " # Paint the modified drawing\n", + " canvas = Canvas(400, 400)\n", + " drawing.paint(canvas)\n", + " canvas.mainloop()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b309d7bb", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "05b69940", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Labs/Lab.5/Lab 5.solutions.ipynb b/Labs/Lab.5/Lab 5.solutions.ipynb new file mode 100644 index 0000000..046db3e --- /dev/null +++ b/Labs/Lab.5/Lab 5.solutions.ipynb @@ -0,0 +1,807 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1efe8b8e", + "metadata": {}, + "source": [ + "# Lab 5" + ] + }, + { + "cell_type": "markdown", + "id": "fe840dd1", + "metadata": {}, + "source": [ + "#### In this lab you will be creating a simple linear algebra system. In memory, we will represent matrices as nested python lists as we have done in lecture. In the exercises below, you are required to explicitly test every feature you implement, demosntrating it works.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "bddccbb4", + "metadata": {}, + "outputs": [], + "source": [ + "#1.\n", + "class Matrix:\n", + " def __init__(self, n=None, m=None, values=None):\n", + " if values:\n", + " self.matrix = values\n", + " self.rows = len(values)\n", + " self.cols = len(values[0])\n", + " for row in values:\n", + " if len(row) != self.cols:\n", + " raise ValueError(\"All rows should have the same number of columns\")\n", + " elif n is not None and m is not None:\n", + " self.matrix = [[0 for _ in range(m)] for _ in range(n)]\n", + " self.rows = n\n", + " self.cols = m\n", + " else:\n", + " raise ValueError(\"Invalid initialization parameters\")\n", + "\n", + " def __getitem__(self, indices):\n", + " row, col = indices\n", + " return self.matrix[row][col]\n", + "\n", + " def __setitem__(self, indices, value):\n", + " row, col = indices\n", + " self.matrix[row][col] = value\n", + "\n", + " def __repr__(self):\n", + " return f\"Matrix({self.matrix})\"\n", + "\n", + " def __eq__(self, other):\n", + " if isinstance(other, Matrix):\n", + " if self.rows != other.rows or self.cols != other.cols:\n", + " raise ValueError(\"Matrices must be the same size for assignment\")\n", + " self.matrix = [row[:] for row in other.matrix]\n", + " elif isinstance(other, list):\n", + " if self.rows != len(other) or self.cols != len(other[0]):\n", + " raise ValueError(\"List of lists must be the same size as the matrix\")\n", + " for row in other:\n", + " if len(row) != self.cols:\n", + " raise ValueError(\"All rows in the list of lists must have the same number of columns\")\n", + " self.matrix = other\n", + " else:\n", + " raise ValueError(\"Right-hand side must be a Matrix or list of lists\")\n", + " return self" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "b9b532d9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Matrix([[0, 0, 0], [0, 0, 0], [0, 0, 0]])\n" + ] + } + ], + "source": [ + "# Seeing if it works:\n", + "\n", + "M1 = Matrix(3, 3)\n", + "print(M1)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "1611380b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n" + ] + } + ], + "source": [ + "M2 = Matrix(values=[[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n", + "print(M2)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "0d3165aa", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n", + "Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 10]])\n" + ] + } + ], + "source": [ + "print(M2[1, 1]) \n", + "M2[2, 2] = 10\n", + "print(M2)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "1ceaadec", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 10]])\n", + "Matrix([[7, 8, 9], [4, 5, 6], [1, 2, 3]])\n" + ] + } + ], + "source": [ + "M1 = M2\n", + "print(M1)\n", + "M1 = Matrix(values=[[7, 8, 9], [4, 5, 6], [1, 2, 3]])\n", + "print(M1)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "257ea4c1", + "metadata": {}, + "outputs": [], + "source": [ + "#2.\n", + "class Matrix:\n", + " def __init__(self, n=None, m=None, values=None):\n", + " if values:\n", + " self.matrix = values\n", + " self.rows = len(values)\n", + " self.cols = len(values[0])\n", + " for row in values:\n", + " if len(row) != self.cols:\n", + " raise ValueError(\"All rows should have the same number of columns\")\n", + " elif n is not None and m is not None:\n", + " self.matrix = [[0 for _ in range(m)] for _ in range(n)]\n", + " self.rows = n\n", + " self.cols = m\n", + " else:\n", + " raise ValueError(\"Invalid initialization parameters\")\n", + "\n", + " def shape(self):\n", + " return (self.rows, self.cols)\n", + " \n", + " def transpose(self):\n", + " transposed_matrix = [[self.matrix[j][i] for j in range(self.rows)] for i in range(self.cols)]\n", + " return Matrix(values=transposed_matrix)\n", + " \n", + " def row(self, n):\n", + " if not (0 <= n < self.rows):\n", + " raise ValueError(\"Row index out of range\")\n", + " return Matrix(values=[self.matrix[n]])\n", + " \n", + " def column(self, n):\n", + " if not (0 <= n < self.cols):\n", + " raise ValueError(\"Column index out of range\")\n", + " col_matrix = [[self.matrix[i][n]] for i in range(self.rows)]\n", + " return Matrix(values=col_matrix)\n", + " \n", + " def to_list(self):\n", + " return self.matrix\n", + " \n", + " def block(self, n_0, n_1, m_0, m_1):\n", + " if not (0 <= n_0 < n_1 <= self.rows and 0 <= m_0 < m_1 <= self.cols):\n", + " raise ValueError(\"Invalid block indices\")\n", + " block_matrix = [row[m_0:m_1] for row in self.matrix[n_0:n_1]]\n", + " return Matrix(values=block_matrix)\n", + " \n", + " def __getitem__(self, indices):\n", + " if isinstance(indices, tuple):\n", + " row, col = indices \n", + " if isinstance(row, slice) or isinstance(col, slice):\n", + " row_start, row_stop, row_step = row.indices(self.rows) if isinstance(row, slice) else (row, row+1, 1)\n", + " col_start, col_stop, col_step = col.indices(self.cols) if isinstance(col, slice) else (col, col+1, 1)\n", + " \n", + " sliced_matrix = [self.matrix[r][col_start:col_stop:col_step] for r in range(row_start, row_stop, row_step)]\n", + " return Matrix(values=sliced_matrix)\n", + " return self.matrix[row][col]\n", + " else:\n", + " raise TypeError(\"Invalid index type\")\n", + " \n", + " def __setitem__(self, indices, value):\n", + " row, col = indices \n", + " self.matrix[row][col] = value\n", + "\n", + " def __repr__(self):\n", + " return f\"Matrix({self.matrix})\"\n", + "\n", + " \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "de4ca301", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(3, 3)\n" + ] + } + ], + "source": [ + "M1 = Matrix(3,3)\n", + "print(M1.shape())" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "5cd1ffc4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(3, 3)\n" + ] + } + ], + "source": [ + "M2 = Matrix(values=[[1,2,3],[4,5,6],[7,8,9]])\n", + "print(M2.shape())" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "c18218e9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1, 2, 3], [4, 5, 6], [7, 8, 9]]\n" + ] + } + ], + "source": [ + "print(M2.to_list())" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "53ab9811", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Matrix([[2, 3], [5, 6]])\n" + ] + } + ], + "source": [ + "print(M2.block(0, 2, 1, 3)) " + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "5ad684a9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Matrix([[1, 4, 7], [2, 5, 8], [3, 6, 9]])\n" + ] + } + ], + "source": [ + "print(M2.transpose())" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "061fc52a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Matrix([[4, 5, 6]])\n" + ] + } + ], + "source": [ + "print(M2.row(1))" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "ac5b6f04", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Matrix([[2], [5], [8]])\n" + ] + } + ], + "source": [ + "print(M2.column(1))" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "fdb35d96", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n" + ] + } + ], + "source": [ + "print(M2[1, 1])" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "d730f0ff", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Matrix([[2, 3], [5, 6]])\n" + ] + } + ], + "source": [ + "print(M2[0:2, 1:3])" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "20e5f614", + "metadata": {}, + "outputs": [], + "source": [ + "#3.\n", + "\n", + "class Matrix_S:\n", + " def __init__(self, n=None, m=None, values=None):\n", + " if values:\n", + " self.matrix = values\n", + " self.rows = len(values)\n", + " self.cols = len(values[0])\n", + " for row in values:\n", + " if len(row) != self.cols:\n", + " raise ValueError(\"All rows should have the same number of columns\")\n", + " elif n is not None and m is not None:\n", + " self.matrix = [[0 for _ in range(m)] for _ in range(n)]\n", + " self.rows = n\n", + " self.cols = m\n", + " else:\n", + " raise ValueError(\"Invalid initialization parameters\")\n", + " \n", + " \n", + " def constant(n, m, c):\n", + " return Matrix_S(values=[[float(c) for _ in range(m)] for _ in range(n)])\n", + " \n", + " \n", + " def zeros(n, m):\n", + " return Matrix_S(values=[[float(0) for _ in range(m)] for _ in range(n)])\n", + " \n", + " \n", + " def ones(n, m):\n", + " return Matrix_S(values=[[float(1) for _ in range(m)] for _ in range(n)])\n", + " \n", + " \n", + " def eye(n):\n", + " return Matrix_S(values=[[float(1) if i == j else float(0) for j in range(n)] for i in range(n)])\n", + "\n", + " def shape(self):\n", + " return (self.rows, self.cols)\n", + "\n", + " def to_list(self):\n", + " return self.matrix\n", + "\n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "9e44e471", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[5.5, 5.5, 5.5], [5.5, 5.5, 5.5], [5.5, 5.5, 5.5]]\n", + "[[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]\n", + "[[1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0]]\n", + "[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]\n" + ] + } + ], + "source": [ + "# Testing the Matrix_S class\n", + "# Create a constant matrix\n", + "M_constant = Matrix_S.constant(3, 3, 5.5)\n", + "print(M_constant.to_list()) \n", + "\n", + "# Create a zeros matrix\n", + "M_zeros = Matrix_S.zeros(3, 3)\n", + "print(M_zeros.to_list()) \n", + "\n", + "# Create a ones matrix\n", + "M_ones = Matrix_S.ones(3, 3)\n", + "print(M_ones.to_list()) \n", + "\n", + "# Create an identity matrix\n", + "M_eye = Matrix_S.eye(3)\n", + "print(M_eye.to_list()) \n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "db222ff3", + "metadata": {}, + "outputs": [ + { + "ename": "IndentationError", + "evalue": "unindent does not match any outer indentation level (, line 6)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m File \u001b[0;32m:6\u001b[0;36m\u001b[0m\n\u001b[0;31m return Matrix_S(values=result_matrix)\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m unindent does not match any outer indentation level\n" + ] + } + ], + "source": [ + "#4: \n", + "class Matrix_S:\n", + " \n", + " def M.scalarmul(self, c):\n", + " result_matrix = [[self.matrix[i][j] * c for j in range(self.cols)] for i in range(self.rows)]\n", + " return Matrix_S(values=result_matrix)\n", + " \n", + " def M.add(self, N):\n", + " if self.shape() != N.shape():\n", + " raise ValueError(\"Matrices must have the same dimensions to be added\")\n", + " result_matrix = [[self.matrix[i][j] + N.matrix[i][j] for j in range(self.cols)] for i in range(self.rows)]\n", + " return Matrix_S(values=result_matrix)\n", + " \n", + " def M.sub(self, N):\n", + " if self.shape() != N.shape():\n", + " raise ValueError(\"Matrices mush have the same dimensions to be subtracted\")\n", + " result_matrix = [[self.matrix[i][j] - N.matrix[i][j] for j in range(self.cols)] for i in range(self.rows)]\n", + " return Matrix_S(values = result_matrix)\n", + " \n", + " def M.mat_mult(self, N):\n", + " if self.shape[j] != N.shape[j]:\n", + " raise ValueError(\"Matrices mush have the same columns to be multiplied\")\n", + " result_matrix = [[self.matrix[i][j] * N.matrix[i][j] for for j in range(self.cols)] for i in range(self.rows)]\n", + " return Matrix_S(values = result_matrix)\n", + " \n", + " def M.element_mult(self, N):\n", + " if self.shape() != N.shape():\n", + " raise ValueeError(\"Matrices must have the same dimensions for element-wise multiplication\")\n", + " result_matrix = [[self.matrix[i][j] * N.matrix[i][j] for j in range(self.cols)] for i in range(self.rows)]\n", + " return Matrix_S(values=result_matrix)\n", + " \n", + " def M.equals(N): \n", + " if M == N:\n", + " return True\n", + " else:\n", + " return False\n", + " \n", + " \n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "b56d6ccf", + "metadata": {}, + "outputs": [], + "source": [ + "# I do not know how to solve that. \n", + "# Tried to indent it and rewrite it but it did not work for number 4" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "3faed31c", + "metadata": {}, + "outputs": [], + "source": [ + "#5. \n", + "class Matrix_S:\n", + " def __init__(self, n=None, m=None, values=None):\n", + " if values:\n", + " self.matrix = values\n", + " self.rows = len(values)\n", + " self.cols = len(values[0])\n", + " for row in values:\n", + " if len(row) != self.cols:\n", + " raise ValueError(\"All rows should have the same number of columns\")\n", + " elif n is not None and m is not None:\n", + " self.matrix = [[0 for _ in range(m)] for _ in range(n)]\n", + " self.rows = n\n", + " self.cols = m\n", + " else:\n", + " raise ValueError(\"Invalid initialization parameters\")\n", + " \n", + "\n", + " def constant(n, m, c):\n", + " return Matrix_S(values=[[float(c) for _ in range(m)] for _ in range(n)])\n", + "\n", + " def zeros(n, m):\n", + " return Matrix_S(values=[[float(0) for _ in range(m)] for _ in range(n)])\n", + " \n", + "\n", + " def ones(n, m):\n", + " return Matrix_S(values=[[float(1) for _ in range(m)] for _ in range(n)])\n", + "\n", + " def eye(n):\n", + " return Matrix_S(values=[[float(1) if i == j else float(0) for j in range(n)] for i in range(n)])\n", + "\n", + " def shape(self):\n", + " return (self.rows, self.cols)\n", + " \n", + " def to_list(self):\n", + " return self.matrix\n", + " \n", + " def scalarmul(self, c):\n", + " result_matrix = [[self.matrix[i][j] * c for j in range(self.cols)] for i in range(self.rows)]\n", + " return Matrix_S(values=result_matrix)\n", + "\n", + " def add(self, other):\n", + " if self.shape() != other.shape():\n", + " raise ValueError(\"Matrices must have the same dimensions to be added\")\n", + " result_matrix = [[self.matrix[i][j] + other.matrix[i][j] for j in range(self.cols)] for i in range(self.rows)]\n", + " return Matrix_S(values=result_matrix)\n", + "\n", + " def sub(self, other):\n", + " if self.shape() != other.shape():\n", + " raise ValueError(\"Matrices must have the same dimensions to be subtracted\")\n", + " result_matrix = [[self.matrix[i][j] - other.matrix[i][j] for j in range(self.cols)] for i in range(self.rows)]\n", + " return Matrix_S(values=result_matrix)\n", + "\n", + " def mat_mult(self, other):\n", + " if self.cols != other.rows:\n", + " raise ValueError(\"Matrices are not aligned for matrix multiplication\")\n", + " result_matrix = [[sum(self.matrix[i][k] * other.matrix[k][j] for k in range(self.cols)) for j in range(other.cols)] for i in range(self.rows)]\n", + " return Matrix_S(values=result_matrix)\n", + "\n", + " def element_mult(self, other):\n", + " if self.shape() != other.shape():\n", + " raise ValueError(\"Matrices must have the same dimensions for element-wise multiplication\")\n", + " result_matrix = [[self.matrix[i][j] * other.matrix[i][j] for j in range(self.cols)] for i in range(self.rows)]\n", + " return Matrix_S(values=result_matrix)\n", + "\n", + " def equals(self, other):\n", + " if self.shape() != other.shape():\n", + " return False\n", + " return all(self.matrix[i][j] == other.matrix[i][j] for i in range(self.rows) for j in range(self.cols))\n", + "\n", + " def __eq__(self, other):\n", + " return self.equals(other)\n", + " \n", + " def __mul__(self, other):\n", + " if isinstance(other, (int, float)):\n", + " return self.scalarmul(other)\n", + " else:\n", + " return self.mat_mult(other)\n", + " \n", + " def __rmul__(self, other):\n", + " return self.__mul__(other)\n", + " \n", + " def __add__(self, other):\n", + " return self.add(other)\n", + " \n", + " def __sub__(self, other):\n", + " return self.sub(other)\n", + "\n", + " def __repr__(self):\n", + " return f\"Matrix_S({self.matrix})\"\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "a4b06468", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Matrix_S([[2, 4, 6], [8, 10, 12], [14, 16, 18]])\n", + "Matrix_S([[2, 4, 6], [8, 10, 12], [14, 16, 18]])\n", + "Matrix_S([[10, 10, 10], [10, 10, 10], [10, 10, 10]])\n", + "Matrix_S([[-8, -6, -4], [-2, 0, 2], [4, 6, 8]])\n", + "Matrix_S([[30, 24, 18], [84, 69, 54], [138, 114, 90]])\n" + ] + } + ], + "source": [ + "# Initialize two matrices\n", + "M1 = Matrix_S(values=[[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n", + "M2 = Matrix_S(values=[[9, 8, 7], [6, 5, 4], [3, 2, 1]])\n", + "\n", + "# Scalar multiplication\n", + "M_scaled_1 = 2 * M1\n", + "M_scaled_2 = M1 * 2\n", + "print(M_scaled_1) \n", + "print(M_scaled_2) \n", + "\n", + "# Matrix addition\n", + "M_added = M1 + M2\n", + "print(M_added) \n", + "\n", + "# Matrix subtraction\n", + "M_subtracted = M1 - M2\n", + "print(M_subtracted) \n", + "\n", + "# Matrix multiplication\n", + "M_mult = M1 * M2\n", + "print(M_mult) \n", + "\n", + "# Equality check\n", + "M_equals = M1 == M2" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "83368c26", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Associativity of Matrix Multiplication: (AB)C = A(BC)\n", + "Matrix_S([[413, 454], [937, 1030]])\n", + "Matrix_S([[413, 454], [937, 1030]])\n", + "\n", + "Distributivity of Matrix Multiplication: A(B + C) = AB + AC\n", + "Matrix_S([[50, 56], [114, 128]])\n", + "Matrix_S([[50, 56], [114, 128]])\n", + "\n", + "Non-commutativity of Matrix Multiplication: AB ≠ BA\n", + "Matrix_S([[19, 22], [43, 50]])\n", + "Matrix_S([[23, 34], [31, 46]])\n", + "\n", + "Identity Matrix: AI = A\n", + "Matrix_S([[1, 2], [3, 4]])\n", + "Matrix_S([[1.0, 2.0], [3.0, 4.0]])\n" + ] + } + ], + "source": [ + "#6. \n", + "# Create two 2x2 matrices\n", + "A = Matrix_S(values=[[1, 2], [3, 4]])\n", + "B = Matrix_S(values=[[5, 6], [7, 8]])\n", + "C = Matrix_S(values=[[9, 10], [11, 12]])\n", + "\n", + "# Define the identity matrix\n", + "I = Matrix_S.eye(2)\n", + "\n", + "# 1. Associativity of Matrix Multiplication: (AB)C = A(BC)\n", + "AB = A * B\n", + "ABC_1 = AB * C\n", + "BC = B * C\n", + "ABC_2 = A * BC\n", + "\n", + "print(\"Associativity of Matrix Multiplication: (AB)C = A(BC)\")\n", + "print(ABC_1) # Should be the same as ABC_2\n", + "print(ABC_2)\n", + "\n", + "# 2. Distributivity of Matrix Multiplication: A(B + C) = AB + AC\n", + "B_plus_C = B + C\n", + "A_times_B_plus_C = A * B_plus_C\n", + "AB = A * B\n", + "AC = A * C\n", + "A_times_B_plus_AC = AB + AC\n", + "\n", + "print(\"\\nDistributivity of Matrix Multiplication: A(B + C) = AB + AC\")\n", + "print(A_times_B_plus_C) # Should be the same as A_times_B_plus_AC\n", + "print(A_times_B_plus_AC)\n", + "\n", + "# 3. Non-commutativity of Matrix Multiplication: AB ≠ BA\n", + "AB = A * B\n", + "BA = B * A\n", + "\n", + "print(\"\\nNon-commutativity of Matrix Multiplication: AB ≠ BA\")\n", + "print(AB)\n", + "print(BA)\n", + "\n", + "# 4. Identity Matrix: AI = A\n", + "AI = A * I\n", + "\n", + "print(\"\\nIdentity Matrix: AI = A\")\n", + "print(A)\n", + "print(AI)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "20e1a39e", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Lectures/Lecture.12/Quiz 2.Solutions.ipynb b/Lectures/Lecture.12/Quiz 2.Solutions.ipynb new file mode 100644 index 0000000..407a463 --- /dev/null +++ b/Lectures/Lecture.12/Quiz 2.Solutions.ipynb @@ -0,0 +1,148 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e87282f0", + "metadata": {}, + "source": [ + "## Quiz 2 From Lecture 12" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "acaec6fa", + "metadata": {}, + "outputs": [], + "source": [ + "# Write a function make_deck that returns a list of all of the cards in a standard card deck.\n", + "# The return should be a list of tuples of pairs of suit and value. \n", + "# For example the 10 of Clubs would be ('Clubs', 10) and Queen of Hearts would be ('Hearts', 'Queen'). \n", + "# Recall that a deck has 52 cards, divided into 4 suits (Clubs, Diamonds, Hearts, and Spades), \n", + "# and that each suit has 13 cards: 2 to 10, Jack, Queen, King, and Ace. \n", + "# Summit your solution with Lab 5." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "02d61628", + "metadata": {}, + "outputs": [], + "source": [ + "def make_deck():\n", + " cards = [\"Hearts\", \"Clubs\", \"Diamonds\", \"Spades\"]\n", + " numbers = [1 , 2, 3, 4, 5, 6, 7, 8, 9, 10, \"Jack\", \"Queen\", \"King\"]\n", + " deck = []\n", + " \n", + " for suit in cards:\n", + " for a in numbers: \n", + " deck.append(f\"{a} of {suit}\")\n", + " \n", + " return deck\n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "7b383c9f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 of Hearts\n", + "2 of Hearts\n", + "3 of Hearts\n", + "4 of Hearts\n", + "5 of Hearts\n", + "6 of Hearts\n", + "7 of Hearts\n", + "8 of Hearts\n", + "9 of Hearts\n", + "10 of Hearts\n", + "Jack of Hearts\n", + "Queen of Hearts\n", + "King of Hearts\n", + "1 of Clubs\n", + "2 of Clubs\n", + "3 of Clubs\n", + "4 of Clubs\n", + "5 of Clubs\n", + "6 of Clubs\n", + "7 of Clubs\n", + "8 of Clubs\n", + "9 of Clubs\n", + "10 of Clubs\n", + "Jack of Clubs\n", + "Queen of Clubs\n", + "King of Clubs\n", + "1 of Diamonds\n", + "2 of Diamonds\n", + "3 of Diamonds\n", + "4 of Diamonds\n", + "5 of Diamonds\n", + "6 of Diamonds\n", + "7 of Diamonds\n", + "8 of Diamonds\n", + "9 of Diamonds\n", + "10 of Diamonds\n", + "Jack of Diamonds\n", + "Queen of Diamonds\n", + "King of Diamonds\n", + "1 of Spades\n", + "2 of Spades\n", + "3 of Spades\n", + "4 of Spades\n", + "5 of Spades\n", + "6 of Spades\n", + "7 of Spades\n", + "8 of Spades\n", + "9 of Spades\n", + "10 of Spades\n", + "Jack of Spades\n", + "Queen of Spades\n", + "King of Spades\n" + ] + } + ], + "source": [ + "deck_of_cards = make_deck()\n", + "for card in deck_of_cards:\n", + " print(card)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c9f0a482", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Lectures/Lecture.5/Quiz.solutions b/Lectures/Lecture.5/Quiz.solutions new file mode 100644 index 0000000..c1f486c --- /dev/null +++ b/Lectures/Lecture.5/Quiz.solutions @@ -0,0 +1,74 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 8, + "id": "0d3e8097", + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "expected 'else' after 'if' expression (1705926560.py, line 7)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m Cell \u001b[0;32mIn[8], line 7\u001b[0;36m\u001b[0m\n\u001b[0;31m return [new_args == list() for a in args][a if insintance len(max) else a0=a ]\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m expected 'else' after 'if' expression\n" + ] + } + ], + "source": [ + "# Put into a list comprehension / write it in one line\n", + "\n", + "def create_new_arg_0(args):\n", + " max_len = max(map(len,\n", + " filter(lambda x: isinstance(x,list),\n", + " args)))\n", + " return [new_args == list() for a in args][a if insintance len(max) else a0=a ]\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "715c8a62", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c427ce68", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14c6c92e", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}