commit d180407ae4c78f0ea66cc32448032ab1fc258f30 Author: rizaayson Date: Wed Jun 25 13:50:29 2025 +0800 added student repo diff --git a/S05/activity/__pycache__/activity.cpython-312.pyc b/S05/activity/__pycache__/activity.cpython-312.pyc new file mode 100644 index 0000000..1d5e572 Binary files /dev/null and b/S05/activity/__pycache__/activity.cpython-312.pyc differ diff --git a/S05/activity/activity.py b/S05/activity/activity.py new file mode 100644 index 0000000..b3397f0 --- /dev/null +++ b/S05/activity/activity.py @@ -0,0 +1,325 @@ +## Capstone Specifications + +# 1. In the s05 folder, create an "activity" folder, and inside it, create an "activity.py" file. +# 2. Create a **Person** class, which is an **abstract class**, and includes the following methods: +# - getFullName() method +# - addRequest() method +# - checkRequest() method +# - addUser() method + +from abc import ABC, abstractmethod + +class Person(ABC): + @abstractmethod + def getFullName(self): + pass + + @abstractmethod + def addRequest(self): + pass + + @abstractmethod + def checkRequest(self): + pass + + @abstractmethod + def addUser(self): + pass + +# 3. Create an **Employee** class that **inherits from Person** class, with the following properties and methods: +# - Properties (Define the properties as **protected**, and implement **getters and setters** for each.) +# - firstName +# - lastName +# - email +# - department + +class Employee(Person): + def __init__(firstName, lastName, email, department): + super().__init__() + self._firstName = firstName + self._lastName = lastName + self._email = email + self._department = department + + # getters and setters + def get_firstName(self): + return self._firstName + + def get_lastName(self): + return self._lastName + + def get_email(self): + return self._email + + def get_department(self): + return self._department + + def set_firstName(self, firstName): + self._firstName = firstName + + def set_lastName(self, lastName): + self._lastName = lastName + + def set_email(self, email): + self._email = email + + def set_department(self, department): + self._department = department + +# - Abstract methods +# - getFullName() - outputs the full name +# - addRequest() - outputs "Request has been added" +# - checkRequest() - pass +# - addUser() - pass + + def getFullName(self): + return f"{self._firstName } {self._lastName}" + + def addRequest(self): + return "Request has been added" + + def checkRequest(self): + pass + + def addUser(self): + pass + +# - Custom methods +# - login() - outputs " has logged in" +# - logout() - outputs " has logged out" + + def login(self): + return f"{self._email} has logged in" + + def logout(self): + return f"{self._email} has logged out" + +# 4. Create a **TeamLead** class that **inherits from Person** class with the following properties and methods: +# - Properties (Define the properties as **protected**, and implement **getters and setters** for each.) +# - firstName +# - lastName +# - email +# - department +# - members - empty list + +class TeamLead(Person): + def __init__(self, firstName, lastName, email, department): + super().__init__() + self._firstName = firstName + self._lastName = lastName + self._email = email + self._department = department + self._members = [] + + # getters and setters + def get_firstName(self): + return self._firstName + + def get_lastName(self): + return self._lastName + + def get_email(self): + return self._email + + def get_department(self): + return self._department + + def get_members(self): + return self._members + + def set_firstName(self, firstName): + self._firstName = firstName + + def set_lastName(self, lastName): + self._lastName = lastName + + def set_email(self, email): + self._email = email + + def set_department(self, department): + self._department = department + +# - Abstract methods +# - getFullName() - outputs the full name +# - addRequest() - pass +# - checkRequest() - outputs "Request has been checked" +# - addUser() - pass + + def getFullName(self): + return f"{self._firstName } {self._lastName}" + + def addRequest(self): + pass + + def checkRequest(self): + return "Request has been checked" + + def addUser(self): + pass + +# - Custom methods +# - login() - outputs " has logged in" +# - logout() - outputs " has logged out" +# - addMember() - adds an employee to the members list + + def login(self): + return f"{self._email} has logged in" + + def logout(self): + return f"{self._email} has logged out" + + def addMember(self, teamMember): + self._members.append(teamMember) + +# 5. Create an **Admin** class the **inherits from Person** class with the following properties and methods: +# - Properties (Define the properties as **protected**, and implement **getters and setters** for each.) +# - firstName +# - lastName +# - email +# - department + +class Admin(Person): + def __init__(self, firstName, lastName, email, department): + super().__init__() + self._firstName = firstName + self._lastName = lastName + self._email = email + self._department = department + + # getters and setters + def get_firstName(self): + return self._firstName + + def get_lastName(self): + return self._lastName + + def get_email(self): + return self._email + + def get_department(self): + return self._department + + def set_firstName(self, firstName): + self._firstName = firstName + + def set_lastName(self, lastName): + self._lastName = lastName + + def set_email(self, email): + self._email = email + + def set_department(self, department): + self._department = department + +# - Abstract methods +# - getFullName() - outputs the full name +# - addRequest() - pass +# - checkRequest() - pass +# - addUser() - outputs "User has been added" + + def getFullName(self): + return f"{self._firstName } {self._lastName}" + + def addRequest(self): + pass + + def checkRequest(self): + pass + + def addUser(self): + return "User has been added" + +# - Custom methods +# - login() - outputs " has logged in" +# - logout() - outputs " has logged out" + + def login(self): + return f"{self._email} has logged in" + + def logout(self): + return f"{self._email} has logged out" + +# 6. Create a **Request** class with the following properties and methods: +# - Properties (Define the properties as **protected**, and implement **getters and setters** for each.) +# - name +# - requester +# - dateRequested +# - status - "Open" + +class Request(): + def __init__(self, name, requester, dateRequested): + self._name = name + self._requester = requester + self._dateRequested = dateRequested + self._status = "Open" + + # getters and setters + def get_name(self): + return self._name + + def get_requester(self): + return self._requester + + def get_dateRequested(self): + return self._dateRequested + + def get_status(self): + return self._status + + def set_name(self, name): + self._name = name + + def set_requester(self, requester): + self._requester = requester + + def set_dateRequested(self, dateRequested): + self._dateRequested = dateRequested + + def set_status(self, status): + self._status = status + +# - Custom Methods +# - updateRequest() - outputs “Request has been updated” +# - closeRequest() - outputs “Request has been closed” +# - cancelRequest() - outputs “Request has been cancelled” + + def updateRequest(self): + return f"Request {self._name} has been updated" + + def closeRequest(self): + return f"Request {self._name} has been closed" + + def cancelRequest(self): + return f"Request {self._name} has been cancelled" + +# 7. Comment out the test cases before updating the local session Git repository. +# 8. Update your local session Git repository and push to Git with the commit message "Add activity code s05". +# 9. Add the repository link in Boodle for s05. + +# Test cases: + +employee1 = Employee("John", "Doe", "djohn@mail.com", "Marketing") +employee2 = Employee("Jane", "Smith", "sjane@mail.com", "Marketing") +employee3 = Employee("Robert", "Patterson", "probert@mail.com", "Sales") +employee4 = Employee("Brandon", "Smith", "sbrandon@mail.com", "Sales") +admin1 = Admin("Monika", "Justin", "jmonika@mail.com", "Marketing") +teamLead1 = TeamLead("Michael", "Specter", "smichael@mail.com", "Sales") +req1 = Request("New hire orientation", teamLead1, "27-Jul-2021") +req2 = Request("Laptop repair", employee1, "1-Jul-2021") + +assert employee1.getFullName() == "John Doe", "Full name should be John Doe" +assert admin1.getFullName() == "Monika Justin", "Full name should be Monika Justin" +assert teamLead1.getFullName() == "Michael Specter", "Full name should be Michael Specter" +assert employee2.login() == "sjane@mail.com has logged in" +assert employee2.addRequest() == "Request has been added" +assert employee2.logout() == "sjane@mail.com has logged out" + +teamLead1.addMember(employee3) +teamLead1.addMember(employee4) +for indiv_emp in teamLead1.get_members(): + print(indiv_emp.getFullName()) + +assert admin1.addUser() == "User has been added" + +req2.set_status("closed") +print(req2.closeRequest()) \ No newline at end of file diff --git a/s01/activity/activity.py b/s01/activity/activity.py new file mode 100644 index 0000000..b2d239d --- /dev/null +++ b/s01/activity/activity.py @@ -0,0 +1,31 @@ +# Activity Solution: + +# 1. In the s01 folder, create an "activity" folder, and inside it, create an "activity.py" file. +# 2. Create 5 variables and display them in the terminal using the following format: +# "I am ``, and I am `` years old, I work as a ``, and my rating for `` is ``%." + +name = "Jose" +age = 38 +occupation = "writer" +movie = "One more chance" +rating = 99.6 + + print(f"I am {name}, and I am {age} years old, I work as a {occupation}, and my rating for {movie} is {rating}%.") + +# 3. Create 3 variables named num1, num2, and num3. +num1 = 10 +num2 = 15 +num3 = 12 + +# Print the product of num1 and num2. +print(num1 * num2) + +# Print whether num1 is less than num3. +print(num1 < num3) + +# Add the value of num3 to num2, then print the updated value of num2. +num2 += num3 +print(num2) + +# 4. Update your local session Git repository and push to Git with the commit message "Add activity code s01". +# 5. Add the repository link in Boodle for s01. \ No newline at end of file diff --git a/s01/discussion/discussion.py b/s01/discussion/discussion.py new file mode 100644 index 0000000..4f00e2c --- /dev/null +++ b/s01/discussion/discussion.py @@ -0,0 +1,150 @@ +# [SECTION] Comments in Python + +# In Python, comments are written using the "#" symbol. +# Remember that comments are not read by the program; they are only for the user. +# Comments can also be written inline. + +# [SECTION] Python Syntax + +# print() is a built-in function that displays text or other data in the terminal. +print("Hello world!") +# Result: Hello World! + +# Like JavaScript, Python does not require semicolons at the end of statements. + +# To run a Python program: + + # Windows and Linux + # python discussion.py + + # MacOS + # python3 discussion.py + + # print("Hello World!") + # Result: IndentationError: unexpected indent + +# In many other programming languages, indentation is used only for readability, but in Python, it is essential because it indicates a block of code. + +# [SECTION] Naming convention +# The terminology used for variable names is "identifier." +# All identifiers should begin with a letter (A–Z or a–z) or an underscore (_). +# After the first character, identifiers can have any combination of characters. +# Unlike JavaScript, which uses camelCase, Python follows the snake_case convention for variable names, as defined in PEP 8 (Python Enhancement Proposal 8). +# Keywords cannot be used as identifiers. +# Most importantly, identifiers are case-sensitive. + +age = 20 +middle_initial = "C" + +# [SECTION] Data Types +# Data types convey what kind of information a variable holds. There are different types, each with its own purpose. + +# In Python, these are the commonly used data types: + +# Strings (str) - for alphanumeric characters and symbols +full_name = "John Doe" +secret_code = "Pa$$w0rd" + +# Numbers (int, float, complex) - for integers, decimals, and complex numbers +num_of_days = 365 +pi_approx = 3.1416 +complex_num = 1 + 5j # This is a complex number, j represents the imaginary component + +# Boolean (bool) - for truth values +is_learning = True +is_difficult = False + +# [SECTION] Using variables + +# After declaring variables, they can be used by calling the identifier. +print(full_name) +# Result: John Doe + +# Python allows assigning values to multiple variables in a single line: + +name1, name2, name3, name4 = "John", "Paul", "George", "Ringo" +print(name1) +# Result: John +print(name2) +# Result: Paul +print(name3) +# Result: George +print(name4) +# Result: Ringo + +# In Python, the "+" symbol can be used to concatenate strings. + +print("Concatenation in Python:") + +print("My name is " + full_name) +# Result: My name is John Doe + +# print("My age is " + age) +# Result: TypeError: can only concatenate str (not "int") to str + +# [SECTION] Typecasting in Python + +# There may be times when you want to specify a type for a variable. This can be done using casting. Here are some functions you can use: + +print("Typecasting in Python:") + +# str() - converts the value into string +print("My age is " + str(age)) +# Result: My age is 20 + +# float() - converts the value into float +print(float(age)) +# Result: 20.0 + +# int() - converts the value into integer +print(int(pi_approx)) +# Result: 3 + +# Another way to avoid the type error without using typecasting is by using an f-string. +# To use an f-string, add a lowercase f before the string, and place the variable you want to display inside curly braces {}. +print(f"Hi, my name is {full_name}, and I am {age} years old.") +# Result: Hi, my name is John Doe, and I am 20 years old. + +# [SECTION] Operations + +# Python has families of operators that can be used to manipulate variables. + +# Arithmetic operators - performs mathematical operations +print("Arithmetic Operators:") +print(1 + 10) +# Result: 11 +print(15 - 8) +# Result: 7 +print(18 * 9) +# Result: 162 +print(21 / 7) +# Result: 3.0 +print(18 % 4) +# Result: 2 +print(2 ** 6) +# Result: 64 + +# Assignment Operators - used to assign or update variable values +print("Assignment Operators:") +num1 = 3 +num1 += 4 +print(num1) +# Result: 7 + +# Note: Other assignment operators include -=, *=, /=, %= + +# Comparison Operators - used to compare values (returns a boolean value) +print("Comparison Operators:") +print(1 == 1) +# Result: True + +# Note: Other comparison operators include !=, >=, <=, >, < + +# Logical Operators - used to combine or evaluate multiple conditions +print("Logical Operators:") +print(True and False) +# Result: False +print(not False) +# Result: True +print(False or True) +# Result: True \ No newline at end of file diff --git a/s02/activity/activity.py b/s02/activity/activity.py new file mode 100644 index 0000000..1bc77f1 --- /dev/null +++ b/s02/activity/activity.py @@ -0,0 +1,34 @@ +# Activity Solution: + +# 1. In the s02 folder, create an "activity" folder, and inside it, create an "activity.py" file. +# 2. Accept a "year" input from the user and determine whether it is a leap year or not. + +year = int(input("Please input a year:\n")) +if year % 4 == 0 and year % 100 != 0 or year % 400 == 0: + print(f"{year} is a leap year.") +else: + print(f"{year} is not a leap year." + + +# 3. Accept two numbers ("row" and "column") from the user and create a grid of asterisks based on those values. + +row = int(input("Enter number of rows:\n")) +col = int(input("Enter number of columns:\n")) + +i = 1 +j = 1 +str = "" +while i <= row: + while j <= col: + str += "*" + j += 1 + print(str) + i += 1 + +# 4. Update your local session Git repository and push to Git with the commit message "Add activity code s02". +# 5. Add the repository link in Boodle for s02. + +# Stretch Goal: +# 1. Add a validation for the leap year input: +# - Strings are not allowed for inputs +# - No zero or negative values \ No newline at end of file diff --git a/s02/discussion/discussion.py b/s02/discussion/discussion.py new file mode 100644 index 0000000..fb29e1f --- /dev/null +++ b/s02/discussion/discussion.py @@ -0,0 +1,185 @@ +# [SECTION] User Input + +# Python allows input from the user. + +# The input() function lets the user provide input to the program. +username = input("Please enter your name:\n") + +print(f"Hello {username}! Welcome to the Python short course!") +# Result: Hello John! Welcome to the Python short course! + +num1 = input("Enter 1st number:\n") +num2 = input("Enter 2nd number:\n") + +print(f"The sum of num1 and num2 is {num1 + num2}") +# Result: The sum of num1 and num2 is 1015 + +# To solve this, the input values can be typecast to the appropriate data type. +num1 = int(input("Enter 1st number:\n")) +num2 = int(input("Enter 2nd number:\n")) +print(f"The sum of num1 and num2 is {num1 + num2}") +# Result: The sum of num1 and num2 is 15 + +# [SECTION] Control Structures + +# Control structures can be divided into selection and repetition structures. +# Selection control structures allow a program to choose between options and execute specific code blocks based on the condition. +# Repetition control structures enable a program to repeat certain blocks of code as long as a starting condition is met and until a terminating condition is reached. + +# Selection Control Structures +# If-else statements are used to choose between two or more code blocks depending on the condition. + +test_num1 = 75 + +if test_num1 >= 60: + print("Test passed") +else: + print("Test failed") +# Result: Test passed + +# If-else chains can also be used to provide more than two choices for the program. + +test_num2 = int(input("Please enter the test number:\n")) +if test_num2 > 0: + print("The number is positive") +elif test_num2 == 0: + print("The number is zero") +else: + print("The number is negative") +# Result: +# (15): The number is positive +# (0): The number is zero +# (-15): The number is negative + +# Mini Exercise 1: +# Create an if-else statement that determines if a number is divisible by 3, 5, or both. + # If the number is divisible by both 3 and 5, print "The number is divisible by both 3 and 5." + # If the number is divisible only by 3, print "The number is divisible by 3." + # If the number is divisible only by 5, print "The number is divisible by 5." + # If the number is not divisible by either, print "The number is not divisible by 3 or 5." + +# Solution: +test_div_num = int(input("Please enter a number to test:\n")) +if test_div_num % 3 == 0 and test_div_num % 5 == 0: + print(f"{test_div_num} is divisible by both 3 and 5") +elif test_div_num % 3 == 0: + print(f"{test_div_num} is divisible by 3") +elif test_div_num % 5 == 0: + print(f"{test_div_num} is divisible by 5") +else: + print(f"{test_div_num} is not divisible by both 3 or 5") + +# Repetition Control Structure +# Repetition control structures, also known as loops, allow you to execute a block of code repeatedly. + +# While loops are used to repeatedly execute a block of code as long as a specified condition is true. +print("While Loop:") + +i = 1 +while i <= 5: + print(f"Current count {i}") + i += 1 +# Result: +# Current count 1 +# Current count 2 +# Current count 3 +# Current count 4 +# Current count 5 + +# For Loops in Python are used to iterate over a sequence. + +print("For Loop:") + +fruits = ["apple", "banana", "cherry"] + +for indiv_fruit in fruits: + print(indiv_fruit) +# Result: +# apple +# banana +# cherry + +# To use a for loop to iterate through values, the range() function can be used. +# The range() function is a built-in function in Python used to generate a sequence of numbers. + +print("For Loop with range() function:") + +for x in range(6): + print(f"The current value is {x}") +# Result: +# The current value is 0 +# The current value is 1 +# The current value is 2 +# The current value is 3 +# The current value is 4 +# The current value is 5 + +# range() function with start and stop values +for x in range(6, 10): + print(f"The current value is {x}") +# Result: +# The current value is 6 +# The current value is 7 +# The current value is 8 +# The current value is 9 + +# range() function with start, stop, and step values +for x in range(6, 20, 2): + print(f"The current value is {x}") +# Result: +# The current value is 6 +# The current value is 8 +# The current value is 10 +# The current value is 12 +# The current value is 14 +# The current value is 16 +# The current value is 18 + +# [SECTION] Break Statement +# The break statement is used to stop the loop. + +print("Break Statement in a While Loop:") + +j = 1 + +while j < 6: + print(j) + if j == 3: + break # + j += 1 +# Result: +# 1 +# 2 +# 3 + +# Continue Statement +# The continue statement returns control to the beginning of the loop and continues with the next iteration. + +print("Continue Statement in a While Loop:") + +k = 1 + +while k < 6: + k += 1 + if k == 3: + continue + print(k) +# Result: +# 2 +# 4 +# 5 +# 6 + +# This results in an infinite loop, preventing the program from finishing. + +k = 0 +while k < 6: + if k == 3: + continue + k += 1 + print(k) +# Result: +# 1 +# 2 +# 3 +# .. infinite Loop \ No newline at end of file diff --git a/s03/activity/__pycache__/activity.cpython-312.pyc b/s03/activity/__pycache__/activity.cpython-312.pyc new file mode 100644 index 0000000..1be8462 Binary files /dev/null and b/s03/activity/__pycache__/activity.cpython-312.pyc differ diff --git a/s03/activity/activity.py b/s03/activity/activity.py new file mode 100644 index 0000000..e71f072 --- /dev/null +++ b/s03/activity/activity.py @@ -0,0 +1,38 @@ +# Activity Solution: + +# 1. In the s03 folder, create an "activity" folder, and inside it, create an "activity.py" file. +# 2. Create a class called "Camper" and give it the attributes: name, batch, and course_type. + +class Campers(): + def __init__(self, name, batch, course_type): + self.name = name + self.batch = batch + self.course_type = course_type + +# 3.Create a method called career_track that prints the string: `Currently enrolled in the program.` + + def career_track(self): + print(f'Currently enrolled in the {self.course_type} program.') + +# 4. Create a method called info that prints the string: `My name is of batch .` + + def info(self): + print(f'My name is {self.name} of batch {self.batch}.') + +# 5. Create an object from the Camper class called zuitt_camper, and pass in values for name, batch, and course_type. + +zuitt_camper = Camper('Alan', 100, 'Python Short Course') + +# 6. Print the values of name, batch, and course_type individually from the zuitt_camper object. + +print(f'Camper Name: {zuitt_camper.name}') +print(f'Camper Batch: {zuitt_camper.batch}') +print(f'Camper Course: {zuitt_camper.course_type}') + +# 7. Execute the info and career_track method of the object. + +zuitt_camper.career_track() +zuitt_camper.info() + +# 8. Update your local session Git repository and push to Git with the commit message "Add activity code s03". +# 9. Add the repository link in Boodle for s03. \ No newline at end of file diff --git a/s03/discussion/discussion.py b/s03/discussion/discussion.py new file mode 100644 index 0000000..5be5b31 --- /dev/null +++ b/s03/discussion/discussion.py @@ -0,0 +1,337 @@ +# [SECTION] Lists +# Lists are similar to arrays in JavaScript in the sense that they can contain a collection of data. +# To create a list, square brackets ([]) are used. + +names = ["John", "Paul", "George", "Ringo"] # String list +programs = ['developer career', 'pi-shape', 'tech career package'] +durations = [260, 180, 20] # Number list +truth_values = [True, False, True, True, False] # Boolean list + +# A list can contain elements of different data types: +sample_list = ["Apple", 3, False, "Potato", 4, True] + +# Problems may arise if you try to use lists with multiple types for something that expects them to be all the same type. + +# Problems may arise if you try to use lists with multiple types for something that expects them to be all the same type. + +print("Lists:") + +# Getting list size +# The number of elements in a list can be counted using the len() function. + +print(len(programs)) +# Result: 3 + +# Accessing values in lists +# List elements can be accessed by providing their index number. +# Indexing in lists starts at 0 and goes up to n - 1, where n is the number of elements. + +print(names[0]) +# Result: John + +# Accessing the last item in the lists +print(names[-1]) +# Result: Ringo + +# Accesing the whole list +print(durations) +# Result: [260, 180, 20] + +# Accessing a range of values +# SYNTAX: list[start index : end index] +print(programs[0:2]) +# Result: ['developer career', 'pi-shape'] + +# Mini Exercise 1: +# Create a list of names of 5 students +# Create a list of grades for the 5 students +# Use a loop to iterate through the lists, printing in the following format: "The grade of is ". + +# Solution: +students = ["Mary", "Matthew", "Tom", "Anna", "Thomas"] +grades = [100, 85, 88, 90, 75] + +count = 0 +while count < len(students): + print(f"The grade of {students[count]} is {grades[count]}") + count += 1 + +# Result: +# The grade of Mary is 100 +# The grade of Matthew is 85 +# The grade of Tom is 88 +# The grade of Anna is 90 +# The grade of Thomas is 75 + +# Updating List Elements + +# Print the current value +print(f'Current value: {programs[2]}') +# Result: Current value: tech career package + +# Update the value +programs[2] = 'short courses' + +# Print the new value +print(f'New value: {programs[2]}') +# Result: New value: short courses + +# [SECTION] List Manipulation +# Lists have methods that can be used to manipulate their elements. + +# Adding list items – the append() method allows you to insert items at the end of the list. + +programs.append('global') +print(programs) +# Result: ['developer career', 'pi-shape', 'Short Courses', 'global'] + +# Deleting list items – the "del" keyword can be used to delete elements from the list. + +# Add a new item to the durations list +durations.append(360) +print(durations) +# Result: [260, 180, 20, 360] + +# Delete the last item on the list +del durations[-1] +print(durations) +# Result: [260, 180, 20] + +# Membership Checks – The "in" keyword checks if an element is in the list and returns True or False. +print(20 in durations) +# Result: True +print(500 in durations) +# Result: False + +# Sorting lists - the sort() method sorts the list alphanumerically, ascending, by default. +names.sort() +print(names) +# Result: ['George', 'John', 'Paul', 'Ringo'] + +# Emptying the list - the clear() method is used to empty the contents of the list. +test_list = [1, 3, 5, 7, 9] +print(test_list) + +test_list.clear() +print(test_list) +# Result: [] + +# [SECTION] Dictionaries +# Dictionaries are used to store data values in key:value pairs. This is similar to objects in JavaScript. +# A dictionary is a collection that is ordered, changeable, and does not allow duplicates. +# Ordered means that the items have a defined order, and that order will not change. +# Changeable means that values can be modified. +# To create a dictionary, curly braces ({}) are used, and key-value pairs are written as key: value. + +print("Dictionaries:") + +person1 = { + "name" : "Brandon", + "age" : 28, + "occupation" : "student", + "is_enrolled" : True, + "subjects" : ["Python", "SQL", "Django"] +} + +# To get the number of key-pairs in the dictionary, the len() method can be used. +print(len(person1)) +# Result: 5 + +# To get a value from the dictionary, you can refer to its key using square brackets ([]). +print(person1["name"]) +# Result: Brandon + +# The keys() method returns a view object containing all the keys in the dictionary. +print(person1.keys()) +# Result: dict_keys(['name', 'age', 'occupation', 'is_enrolled', 'subjects']) + +# The values() method returns a view object containing all the values in the dictionary. +print(person1.values()) +# Result: dict_values(['Brandon', 28, 'student', True, ['Python', 'SQL', 'Django']]) + +# The items() method returns each item in the dictionary as key-value pairs in a view object. +print(person1.items()) +# Result: dict_items([('name', 'Brandon'), ('age', 28), ('occupation', 'student'), ('is_enrolled', True), ('subjects', ['Python', 'SQL', 'Django'])]) + +# Adding key-value pairs can be done either by assigning a new key using square brackets, or by using the update() method. + +# Using new index +person1["nationality"] = "Filipino" +print(person1) +# Result: {'name': 'Brandon', 'age': 28, 'occupation': 'student', 'is_enrolled': True, 'subjects': ['Python', 'SQL', 'Django'], 'nationality': 'Filipino'} + +# Using update() method +person1.update({"fav_food" : "Sinigang"}) +print(person1) +# Result: {'name': 'Brandon', 'age': 28, 'occupation': 'student', 'is_enrolled': True, 'subjects': ['Python', 'SQL', 'Django'], 'nationality': 'Filipino', 'fav_food': 'Sinigang'} + +# Deleting entries can be done using the pop() method or the del keyword + +# Using pop() method +person1.pop("fav_food") +print(person1) +# Result: {'name': 'Brandon', 'age': 28, 'occupation': 'student', 'is_enrolled': True, 'subjects': ['Python', 'SQL', 'Django'], 'nationality': 'Filipino'} + +# Using del keyword +del person1["nationality"] +print(person1) +# Result: {'name': 'Brandon', 'age': 28, 'occupation': 'student', 'is_enrolled': True, 'subjects': ['Python', 'SQL', 'Django']} + +# Emptying the Dictionary + +person2 = { + "name" : "John", + "age" : 18 +} + +print(person2) +# Result: {'name': 'John', 'age': 18} + +# The clear() method empties the dictionary +person2.clear() + +print(person2) +# Result: {} + +# Looping through dictionaries +print("Looping through dictionaries:") + +for key in person1: + print(f"The value of {key} is {person1[key]}") + +# Result: +# The value of name is Brandon +# The value of age is 28 +# The value of occupation is student +# The value of is_enrolled is True +# The value of subjects is ['Python', 'SQL', 'Django'] + +# Nested dictionaries - dictionaries can be nested inside each other +person3 = { + "name": "Monika", + "age": 20, + "occupation": "poet", + "is_enrolled": True, + "subjects": ["Python", "SQL", "Django"] +} + +classroom = { + "student1" : person1, + "student2" : person3 +} +print(classroom) +# Result: {'student1': {'name': 'Brandon', 'age': 28, 'occupation': 'student', 'is_enrolled': True, 'subjects': ['Python', 'SQL', 'Django']}, 'student2': {'name': 'Monika', 'age': 20, 'occupation': 'poet', 'is_enrolled': True, 'subjects': ['Python', 'SQL', 'Django']}} + +# [SECTION] Functions +# Functions are blocks of code that run when called. +# The "def" keyword is used to create a function. +# SYNTAX: def function_name(): + +def my_greeting(): + # Code to be run when my_greeting is called + print('Hello User!') + +print("Functions:") + +# Calling/invoking a function +my_greeting() +# Result: Hello User! + +# Parameters in functions allow you to specify what inputs the function expects and provide more control over how the function behaves. +def greet_user(username): + # prints out the value of the username parameter + print(f'Hello, {username}!') + +# Arguments are the actual values that are passed into the function when it is called. +greet_user("Bob") +# Result: Hello, Bob! +greet_user("Amy") +# Result: Hello, Amy! + +# The "return" keyword allows a function to return values. +def addition(num1, num2): + return num1 + num2 + +sum = addition(5, 10) +print(f"The sum is {sum}") +# Result: The sum is 15 + +# A lambda function is a small, anonymous function that can be used for callbacks or short, throwaway operations. +# It works like any regular Python function, but it has no name and is defined using a single line of code. +# A lambda function can take any number of arguments but can only contain one expression. + +greeting = lambda person : f'Hello {person}!' +print(greeting("Jane")) +# Result: Hello Jane! + +multiplication = lambda a, b : a * b +print(multiplication(3, 5)) +# Result: 15 + +# Mini Exercise 2: +# Create a function that returns the square of a number. +# Use 5 as argument, result should be 25. +# Print "The square is {result}." + +# Solution: +def sqr(num): + return num * num # or return num ** 2 + +result = sqr(5) +print(f"The square is {result}.") +# Result: The square is 25. + +# [SECTION] Classes +# Classes serve as blueprints that describe the concept of objects. +# Each object has characteristics (called properties) and behaviors (called methods). +# Imagine the concept of a car: a car has a brand, model, and year of make, and it can drive, brake, and turn. +# To create a class, use the "class" keyword followed by a class name that starts with an uppercase letter. +# SYNTAX: class ClassName(): + +class Car(): + # The properties that all Car objects must have are defined in a method called __init__. + # Any number of parameters can be passed to __init__(), but the first parameter should always be self. + # self refers to the current instance of the class + # When a Car instance is created, that instance is automatically passed to the self parameter. + def __init__(self, brand, model, year_of_make): + self.brand = brand + self.model = model + self.year_of_make = year_of_make + + # Other properties can be added and assigned hard-coded values. + self.fuel = "Gasoline" + self.fuel_level = 0 + + # Methods are functions defined inside a class. + # Method to simulate filling the fuel tank + def fill_fuel(self): + print(f'Current fuel level: {self.fuel_level}') + print('filling up the fuel tank...') + self.fuel_level = 100 + print(f'New fuel level: {self.fuel_level}') + # Mini Exercise solution + def drive(self, distance): + print(f"The car has driven {distance} kilometers") + print(f"The fuel level left: {self.fuel_level - distance}") + +# Creating a new instance is done by calling the class and providing the required arguments +new_car = Car("Nissan", "GT-R", "2019") + +print("Classes:") + +# Displaying attributes can be done using dot notation +print(f"My car is a {new_car.brand} {new_car.model}") +# Result: My car is a Nissan GT-R + +# Calling methods on the instance +new_car.fill_fuel() +# Result: +# Current fuel level: 0 +# filling up the fuel tank... +# New fuel level: 100 + +# Mini Exercise solution +new_car.drive(50) +# Result: +# The car has driven 50 kilometers +# The fuel level left: 50 \ No newline at end of file diff --git a/s04/activity/__pycache__/activity.cpython-312.pyc b/s04/activity/__pycache__/activity.cpython-312.pyc new file mode 100644 index 0000000..119e106 Binary files /dev/null and b/s04/activity/__pycache__/activity.cpython-312.pyc differ diff --git a/s04/activity/activity.py b/s04/activity/activity.py new file mode 100644 index 0000000..44c7bd0 --- /dev/null +++ b/s04/activity/activity.py @@ -0,0 +1,109 @@ +# Activity Solution: + +# 1. Create an activity folder and an activity.py file inside of it. +# 2. Create an abstract class called Animal that has the following abstract methods: +# a. eat(food) +# b. make_sound() + +from abc import ABC, abstractmethod + +class Animal(ABC) + @abstractmethod + def eat(self, food): + pass + + @abstractmethod + def make_sound(self): + pass + +# 3. Create two classes that implements the Animal class called Cat and Dog with each of the following properties and methods: +# a. Properties: +# - name +# - breed +# - age +# b. Methods: +# - getters and setters +# - implementation of abstract methods +# - call() + +class Dog(Animal): + def __init__(self, name, breed, age): + super().__init__() + self._name = name + self._breed = breed + self._age = age + + def get_name(self): + return self._name + + def get_breed(self): + return self._breed + + def get_age(self): + return self._age + + def set_name(self, name): + self._name = name + + def set_breed(self, breed): + self._breed = breed + + def set_age(self, age): + self._age = age + + def eat(self, food): + print(f"Eaten {food}") + + def make_sound(self): + print(f"Bark! Woof! Arf!") + + def call(self): + print(f"Here {self._name}!") + +class Cat(Animal): + def __init__(self, name, breed, age): + super().__init__() + self._name = name + self._breed = breed + self._age = age + + def get_name(self): + return self._name + + def get_breed(self): + return self._breed + + def get_age(self): + return self._age + + def set_name(self, name): + self._name = name + + def set_breed(self, breed): + self._breed = breed + + def set_age(self, age): + self._age = age + + def eat(self, food): + print(f"Serve me {food}") + + def make_sound(self): + print(f"Miaow! Nyaw! Nyaaaaa!") + + def call(self): + print(f"{self._name}, come on!") + +# Test Cases: +dog1 = Dog("Isis", "Dalmatian", 15) +dog1.eat("Steak") +dog1.make_sound() +dog1.call() + +cat1 = Cat("Puss", "Persian", 4) +cat1.eat("Tuna") +cat1.make_sound() +cat1.call() + +# Update your local session git repository and push to git with the commit message of Add activity code s04. +# Add the repo link in Boodle for s04. \ No newline at end of file diff --git a/s04/discussion/discussion.py b/s04/discussion/discussion.py new file mode 100644 index 0000000..3cdd8ec --- /dev/null +++ b/s04/discussion/discussion.py @@ -0,0 +1,349 @@ +# To create a class, the "class" keyword is used along with a class name that starts with an uppercase letter. +# SYNTAX: class ClassName(): + +class SampleClass(): + # The properties that all SampleClass objects must have are defined in a method called __init__. + # Any number of parameters can be passed to __init__(), but the first parameter should always be self. + # When a SampleClass instance is created, that instance is automatically passed to the self parameter. + def __init__(self, year): + self.year = year + + # Methods are functions defined inside a class. + def show_year(self): + print(f'The year is: {self.year}') + +# Creating an instance of SampleClass by calling the class and passing the required argument +myObj = SampleClass(2020) + +# To access properties and call methods of an object instance, use dot notation +print(myObj.year) +# Result: 2020 +myObj.show_year() +# Result: The year is: 2020 + +# [SECTION] Fundamentals of OOP +# There are four main fundamental principles in OOP + # Encapsulation + # Inheritance + # Polymorphism + # Abstraction + +# [SECTION] Encapsulation +# Encapsulation is a mechanism of wrapping the attributes and the methods that act on them together as a single unit. +# In encapsulation, the attributes of a class are hidden from other classes and can be accessed only through the methods of the current class. +# Therefore, it is also known as data hiding. + +# To achieve encapsulation: + # Declare the attributes of a class. + # Provide getter and setter methods to view and modify the attribute values. + +# Why use encapsulation? + # The fields of a class can be made read-only or write-only. + # A class can have full control over what is stored in its fields. + +class Person(): + def __init__(self): + # The underscore prefix is a convention that signals: "Be careful with this attribute, it's intended for internal use within the class." + # Protected attribute: _name + self._name = "John Doe" + # Mini Exercise solution + self._age = 20 + + # setter method + def set_name(self, name): + self._name = name + + # getter method + def get_name(self): + print(f'Name of Person: {self._name}') + + # Mini Exercise solution + # setter method set_age + def set_age(self, age): + self._age = age + + # getter method get_age + def get_age(self): + print(f'Age of Person: {self._age}') + +# Creating an instance of the Person class +person1 = Person() + +print("Encapsulation:") + +# getter +person1.get_name() +# Result: Name of Person: John Doe + +# setter +person1.set_name("Bob Doe") + +person1.get_name() +# Result: Name of Person: Bob Doe + +# Mini Exercise 1: +# Add another protected attribute called "age" +# Create the necessary getter and setter methods +# Output: "Age of Person: " + +# Mini Exercise solution +person1.set_age(20) +person1.get_age() +# Result: Age of Person: 20 + +# [SECTION] Inheritance +# Inheritance is the transfer of characteristics from one class (the parent) to other classes (the children) derived from it. +# For example, an employee is a person with additional attributes and methods. +# To create a subclass (inherited class), specify the parent class in the class definition. +# SYNTAX: class ChildClassName(ParentClassName): + +class Employee(Person): + def __init__(self, employeeId): + super().__init__() + self._employeeId = employeeId + + # getter method + def get_employeeId(self): + print(f"The Employee ID is {self._employeeId}") + + # setter method + def set_employeeId(self, employeeId): + self._employeeId = employeeId + + # custom methods + # Custom methods are methods you create in a class to do specific tasks that aren't built-in or inherited. + def get_details(self): + print(f"{self._employeeId} belongs to {self._name}") + +# Creating an instance of the Employee class +emp1 = Employee("Emp-001") + +emp1.get_details() +# Result: Emp-001 belongs to John Doe + +print("Inheritance:") + +emp1.set_name("Bob Doe") +emp1.get_details() +# Result: Emp-001 belongs to Bob Doe + +# Mini Exercise 2: +# Create a new class called Student that inherits Person with the additional attributes and methods. + +# Attributes: + # Student No + # Course + # Year Level + +# Methods: + # Necessary getters and setters + # get_detail: prints the output ` is currently in year taking up ` + +# Solution: +class Student(Person): + def __init__(self, studentNo, course, year_level): + super().__init__() + self._studentNo = studentNo + self._course = course + self._year_level = year_level + + # getters + def get_studentNo(self): + print(f"Student number of Student is {self._studentNo}") + + def get_course(self): + print(f"Course of Student is {self._course}") + + def get_year_level(self): + print(f"The Year Level of Student is {self._year_level}") + + # setters + def set_studentNo(self, studentNo): + self._studentNo = studentNo + + def set_course(self, course): + self._course = course + + def set_year_level(self, year_level): + self._year_level = year_level + + # custom method + def get_details(self): + print(f"{self._name} is currently in year {self._year_level} taking up {self._course}.") + +# Creating an instance of the Student class +student1 = Student("stdt-001", "Computer Science", 1) + +student1.set_name("Brandon Smith") +# Result: Brandon Smith +student1.get_details() +# Result: Brandon Smith is currently in year 1 taking up Computer Science. + +# [SECTION] Polymorphism +# A child class inherits all the methods from its parent class. However, in some situations, a method inherited from the parent class may not fully suit the child class. In such cases, you need to re-implement the method in the child class. +# Polymorphism in Python refers to defining methods in the child class with the same name as those in the parent class. +# Through inheritance, the child class can reuse methods from the parent class, but it can also modify or override them to fit its own needs. + +# Polymorphism with Inheritance +class Zuitt(): + def tracks(self): + print('We are currently offering 3 tracks(developer career, pi-shape career, and short courses)') + + def num_of_hours(self): + print('Learn web development in 360 hours!') + +class DeveloperCareer(Zuitt): + # Override the parent's num_of_hours() method + def num_of_hours(self): + print('Learn the basics of web development in 240 hours!') + +class PiShapedCareer(Zuitt): + # Override the parent's num_of_hours() method + def num_of_hours(self): + print('Learn skills for no-code app development in 140 hours!') + +course1 = DeveloperCareer() +course2 = PiShapedCareer() + +print("Polymorphism:") +course1.num_of_hours() +# Result: Learn the basics of web development in 240 hours! +course2.num_of_hours() +# Result: Learn skills for no-code app development in 140 hours! + +# Mini Exercise 3: +# Add another child class named ShortCourses +# Method “num_of_hours” should print: Learn advanced topics in web development in 20 hours! + +# Solution: +class ShortCourses(Zuitt): + def num_of_hours(self): + print("Learn advanced topics in web development in 20 hours!") + +# Mini Exercise solution +course3 = ShortCourses() + +# Mini Exercise solution +course3.num_of_hours() +# Result: Learn advanced topics in web development in 20 hours! + +# Polymorphism with Functions and Objects +# You can use different functions, class methods, or objects to demonstrate polymorphism. + +# A function can be created that accepts any object, allowing polymorphic behavior. +class Admin(): + def is_admin(self): + print(True) + + def user_type(self): + print('Admin User') + +class Customer(): + def is_admin(self): + print(False) + + def user_type(self): + print('Regular User') + +# Define a test function that takes an object called obj +def test_function(obj): + obj.is_admin() + obj.user_type() + +# Create object instances for Admin and Customer +user_admin = Admin() +user_customer = Customer() + +# Pass the created instances to the test_function +test_function(user_admin) +# Result: +# True +# Admin User + +test_function(user_customer) +# Result: +# False +# Regular User + +# The test_function calls the methods of the object passed to it, producing different outputs depending on the object type. + +# Polymorphism with Class Methods + +# Python can use different class types in the same way. +# For example, a for loop can iterate through a collection of objects. +# The loop calls the same methods on each object, regardless of its class type. + +class TeamLead(): + def occupation(self): + print('Team Lead') + + def hasAuth(self): + print(True) + + +class TeamMember(): + def occupation(self): + print('Team Member') + + def hasAuth(self): + print(False) + +tl1 = TeamLead() +tm1 = TeamMember() + +for person in (tl1, tm1): + # Call the occupation method on each object + person.occupation() + person.hasAuth() +# Result: +# Team Lead +# True +# Team Member +# False + +# In each iteration, the variable "person" refers to either tl1 or tm1, depending on the order in the loop. This demonstrates polymorphism in action. + +# [SECTION] Abstraction +# An abstract class can be considered a blueprint for other classes. It allows you to define a set of methods that must be implemented in any child class that inherits from it. +# A class that contains one or more abstract methods is called an abstract class. +# An abstract method is a method that is declared but contains no implementation. +# Abstract classes are used to provide a common interface for different classes with different implementations. +# By default, Python does not support abstract classes directly. However, it provides the abc module, which allows you to define Abstract Base Classes (ABCs). + +from abc import ABC, abstractmethod # Importing ABC and abstractmethod from the abc module + +# Polygon inherits from ABC, making it an abstract class +class Polygon(ABC): + + # Abstract method that must be implemented by any subclass + @abstractmethod + # This method is meant to be overridden in subclasses; no implementation here + def printNumberOfSides(self): + # The pass keyword indicates that the method is intentionally left blank + pass + +class Triangle(Polygon): + def __init__(self): + super().__init__() + + # Implementation of the abstract method + def printNumberOfSides(self): + print("This polygon has 3 sides.") + +class Pentagon(Polygon): + def __init__(self): + super().__init__() + + # Implementation of the abstract method + def printNumberOfSides(self): + print("This polygon has 5 sides.") + +# Create instances and call the method +shape1 = Triangle() +shape2 = Pentagon() + +print("Abstraction:") +shape1.printNumberOfSides() +# Result: This polygon has 3 sides. +shape2.printNumberOfSides() +# Result: This polygon has 5 sides. \ No newline at end of file