Computer Programming: Object-Oriented Programming and Functions
Object-Oriented Programming (OOP)
- We are really only going to scratch the surface of OOP in this exercise
- OOP is a complex programming paradigm that can't be mastered in a single setting
- But, we can cover the basics to allow you to explore further
Classes
- Serve as a template from which to build objects
- Think of it as a blueprint: design first, then build
- We can modify the blueprint to add features as needed
Objects
- Objects are instantiated from classes
- An object inherits its properties and methods from its class
Classes and Objects in PowerShell
# Define a "Person" class
# We must explicitly set the data types for any class properties or methods
class Person {
[String]$FirstName
[String]$LastName
[String]$EyeColor
[Int]$Age
[String[]]$Nicknames
# Eat method
# [String] on the left indicates the output from the method
# [String]$Food indicates Eat() takes a string argument to the $Food parameter
[String] Eat([String]$Food) {
return "That $Food was delicious!"
}
# Walk method
# [String] on the left indicates the output from the method
# [Int]$Steps indicates Eat() takes an integer argument to the $Steps parameter
[String] Walk([Int]$Steps) {
return "I walked $Steps steps."
}
# Sleep method
# [Void] indicates this method produces no output
[Void] Sleep() {
Start-Sleep -Seconds 10
}
}
# Create a new "Person" object from the class
# It has inherited its properties and methods from said class
# Assign values to the properties
$johnDoe = New-Object Person
$johnDoe.FirstName = 'John'
$johnDoe.LastName = 'Doe'
$johnDoe.EyeColor = 'Brown'
$johnDoe.Age = 33
$johnDoe.Nicknames = @('johnny', 'jim', 'anonymous')
# Print the object to output
$johnDoe
# Feed John Doe
# The Eat method takes a string
$johnDoe.Eat('spaghetti')
# John Doe needs a walk
# The Walk method take an integer
$johnDoe.Walk(10000)
# John Doe needs a nap
# The Sleep method does not take input
$johnDoe.Sleep()
Classes and Objects in Python
import time
# Unlike PowerShell, we do not declare data types
class Person:
def __init__(self):
self.FirstName = ""
self.LastName = ""
self.EyeColor = ""
self.Age = 0
self.Nicknames = []
# Eat method
def Eat(self, food):
return f"That {food} was delicious!"
# Walk method
def Walk(self, steps):
return f"I walked {steps} steps."
# Sleep method
def Sleep(self):
time.sleep(10)
# Create a new "Person" object from the class
# It has inherited its properties and methods from the class
# Assign values to the properties
johnDoe = Person()
johnDoe.FirstName = 'John'
johnDoe.LastName = 'Doe'
johnDoe.EyeColor = 'Brown'
johnDoe.Age = 33
johnDoe.Nicknames = ['johnny', 'jim', 'anonymous']
# Print the object to output
print(vars(johnDoe))
# Feed John Doe
# The Eat method takes a string
print(johnDoe.Eat('spaghetti'))
# John Doe needs a walk
# The Walk method takes an integer
print(johnDoe.Walk(10000))
# John Doe needs a nap
# The Sleep method does not take input
johnDoe.Sleep()
Functional Programming
- Good code is DRY code, Don't Repeat Yourself
- If you find yourself repeating the same lines of code, it's time to stop and refactor
- Why is code that repeats bad?
- If you update a code block in one section, but forget to update that same code block in another section, then you're creating bugs in the code
- Code that is not DRY is difficult to maintain
- The point of functions is to allow you to write once, reference many
- Write the function and use it where it's needed
Example of Non-Dry Code
PowerShell
PowerShell Non-Dry Code Solution
$int1 = 1
$int2 = 10
$product = $int1 * $int2
Write-Host "The product is: $product"
$int1 = 2
$int2 = 15
$product = $int1 * $int2
Write-Host "The product is: $product"
$int1 = 10
$int2 = 33
$product = $int1 * $int2
Write-Host "The product is: $product"
This code could be improved with the use of a function. It may seem like more work, but we now have a function that we can call repeatedly any time we need to find the product of two integers.
function Get-ProductOfIntegers {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true, Position = 0)]
[Int]$Integer1,
[Parameter(Mandatory = $true, Position = 1)]
[Int]$Integer2
)
try {
return $Integer1 * $Integer2
}
catch {
throw $_
}
}
Get-ProductOfIntegers -Integer1 10 -Integer2 100
Get-ProductOfIntegers -Integer1 12 -Integer2 55
Get-ProductOfIntegers -Integer1 333 -Integer2 33
Python
Python Non-Dry Code Solution
int1 = 1
int2 = 10
product = int1 * int2
print(f"The product is: {product}")
int1 = 2
int2 = 15
product = int1 * int2
print(f"The product is: {product}")
int1 = 10
int2 = 33
product = int1 * int2
print(f"The product is: {product}")
This code could be improved with the use of a function. It may seem like more work, but we now have a function that we can call repeatedly any time we need to find the product of two integers.
def get_product(integer1, integer2):
try:
# With PowerShell, we can do the validation on user input in the parameter block
# With Python, we need to validate the input here
if not isinstance(integer1, int) or not isinstance(integer2, int):
raise ValueError("Please provide two integers")
else:
return int(integer1) * int(integer2)
except Exception as e:
raise e
print(get_product(1, 10))
print(get_product(33, 33))
Creating Well-Designed Functions
- A function is a tool that should repeatedly do one thing well
- It should also be idempotent
-
Idempotency means that every time the function receives an input, it should process it the same every single time. That may mean the function returns a consistent output or it returns a consistent error.
- Just as a screwdriver was intended for a specific purpose, so too should your functions be focused on a single task