Programming

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 43

Python basics

Week 0
Theory
 Unary – a simple system of using a single symbol to solve some problem, like counting the
number of people in a room.
 Binary - is the system that computer use.
 Bit – is just 0 and 1
 ASCII – the American standard code for information interchange, its mapping for English.it can
store 226 characters
 RGB – for every dot(pixels) on your screen a number is representing that.
 Algorithm – step by step process for solving some problem
 Pseudocode – out line for code
 Data type –
o int - takes 32 bits and half of it negative and half of it is positive if you know that the
value is not going to be negative you can use unsigned int
o char – store 1 byte means 8 bits
o float – only have 32 bits to work with
o double – store real number store 64 bits
 Array – is a way of storing a data back-to-back to back in a computer memory in such a way that
you can access each individually member easily,
 String – when you type hello it is going to take 6 bits why coz it takes one extra bit to separate
the character from the next character
 Encryption - convert plaintext into the ciphertext so that other can’t understand the text
 Programming - Makes computer complete specific task without making mistakes.
 IDE - A place to write, run, and debug code and convert it to machine code, ex - visual studio,
etc.
 Console - Programmers keep track of their progress by looking at it, a text interface within the
computer that us programmers can use for a variety of purposes.
 String - Another way of saying text, ex - "Hello World".
 Algorithm - step by step instructions for solving some problem incarnated in the world of
computers by software.
 Source code - Code which human being writes.
 Machine code - Computer only understand binary numbers.
 Compiler - Convert source code into machine code.
 Const - means that thing would never change
 To make a file, type: hello code hello[filename].py
 To compile your code: python hello[filename].py.
 Function: is some action that can easily be run by calling the function name.
 Arguments are inputs that we pass into a function in order to manipulate its behavior.
 Input, function: takes the input
 Return values, function: return the input
 Variables are just containers that store some value.
 Operator, which helps you operate something, ex. "=", its assignment operator is will, which
means you want to assign from right to left whatever the return value is.
 Comments: ignore the input in this thing; use # and even """ in the starting and """ in the ending
if you must write several lines of comments.
 Positional parameters: "positional in the sense that the first thing you print gets printed first,
and the second thing you pass to print after a comma gets printed second.
 Named parameters are optional, and you can pass them at the end of the print statement, but
you can also use them by their name. Example: Sep = separator; End = line ending.
 F - string = if you want to specify the syntax inside the print, ex. print(f "hello, name"), then f
string would know that  is some special function.
 strip—remove the white space from the string.
 capitalize: help you capitalize the first letter of the first word.
 title: capitalize the first letter of every word in that string.
 Int is just an integer. Take up 4 bytes of memory (32 bits, 8 bits memo byte). We split 32 bits into
negative and positive, getting half. Does not hold decimals
 Symbols: +, -, *, /, %, ** (power)
 Interactive mode: you can start writing Python code and immediately execute each of those
lines interactively.
 floating Takes up 4 bytes of memory (32 bits). Can store decimals.
 round: round the number to the nearest integer.
 return – it returns the value

Exercises
#code format for, giving an input and returning a value.

#We are getting the input here and using strip (which would remove the white
space) and capitalize (capitalize the first letter of that word).
name = input("What's your name? ").strip().title()

#We are here splitting the value, you can take either first, last or both.
first, last = name.split(" ")

#We are using the f-string, which would specify this "{}" syntax.
print(f"hello, {name}")

# "name", is variable.
# “What’s your name?”, is an argument.
# "=” are operators.
# "input("")", are input functions.
# "print("hello, " + name)", is a return function.

#Getting an input and specifying it as a float


x = float(input("What's x? "))
y = float(input("What's y? "))
#if you don’t specify x or y as a float or integer, then it will add it as a
string.
z = round(x + y) "or" z = round(x + y, 2) #it would round not to the nearest
digit but to the nearest number of digits
#If i want “,“ after some value, i would use “:,” in print
print(f"{z:,}") "or" print(f"{z:.2f}" ) #if i am using this, then it would give
round of after 2 digits.

#creating a function using def and giving value


def main():
    x = int(input("What's x? "))
    print("x squared is", square(x))

def square(x):
    return x * x

main()

Questions
#prompts the user for input and then outputs that same input, replacing each
space with "...".
x = str(input("What's the input? ")).strip()
y = ("...")
first, second, last = x.split(" ")
print(first+y+second+y+last)

#prompts the user for input and then outputs that same input in lowercase.
input = str(input("Type here? "))
x = (input.lower())
print(x)

# Implement a function called convert that accepts a str as input and returns
that same input with any :) converted to 🙂 and any :( converted to 🙁. all other
text should be returned unchanged. Then, implement a function called main that
prompts the user for input, calls convert on that input, and prints the result.

# "(x)" in def called parameters which comes handy in manipulating the value
inside it
# taking def as "x" which will give us input and would help us in replacing the
value
def convert(x):
    z = x.replace(":)", "🙂").replace(":(", "🙁")
    return z

def main():
    y = (input("input here: "))
    a = convert(y)
    print(a)

if __name__ == "__main__":
  main()

#prompts the mass as an integer (in kilograms)


#outputs the equivalent number of Joules as an integer.
#input an integer.
#Type 1 and press Enter. Your program should output:90000000000000000

x = int(input("What's the mass in kilograms"))


y = (x * ((3*10**8)**2))
print(y)

#it’s customary to leave a tip for your server after dining in a restaurant,
typically an amount equal to 15% or more of your meal’s cost.

def main():
    dollars = float(input("How much was the meal? "))
    percent = float(input("What percentage would you like to tip? "))
    tip = dollars * (percent/100)
    print(f"Leave ${tip:.2f}")

main()

Week 1
Theory
 Conditionals: (>, <, <=, >=, =, ==, !=, or, and), use if, elif, and else statements.
 Bool means yes or no, ex: if x < y:
 Match – Similar to if, elif, and else statements, match statements can be used to conditionally
run code that matches certain values.
 Types and format codes
o Number
 int (%i) - integers
 long (%li) - we will have longer value (we can store much more combination)
 float (%f) - store decimal number
 double (%f) - we can have twice as many bits to represent that information.
o Text
 char (%c) - individual character
 string (%s) - collection of characters
 Data types and variable: -
o Int
 Take up 4 bytes of memory (32bits, 8bits as per 1 bytes).
 We split 32 bits into negative and positive getting half.
 Does not hold decimal
 Unsigned int
 It modifies the data types of integers slightly, which doubles the positive range
of values so that you do not have to take any negative values.
we represent approximately 0 to 4 billion.
o Char
 Store one character, takes up 1 bytes of memory(8bits).
o Floating
 Takes up 4 bytes of memory (32bits).
 Can store decimal.
o Double
 They can fit 64bits of data, or eight bytes.
 it is great when you are working with a lot of decimals
o Bool
 Store one value, true or false.

Examples
#code format for, using match value.
name = input("What's your name? ")
match name:
    case "Harry":
        print("Gryffindor")
    case "Hermione":
        print("Gryffindor")
    case "Ron":
        print("Gryffindor")
    case "Draco":
        print("Slytherin")
    case _:
        print("Who?")
#Notice the use of the _ symbol in the last case. This will match with any input,
resulting in similar behavior as an else statement.

#code format for, defining the value and seeing if it is odd or even.
def main():
    x = int(input("What's x? ")) #taking input in "x"
    if y(x):       #here we are assuming "x" value in "y"
        print("Even") #if the "x" will return "true" then it will print "even".
    else:
        print("Odd") #if the "x" will return "false" then it will print "odd".

def y(x):  #checking, the value of "x" if it is "True" or "False".


    return True if x % 2 == 0 else False

main()

#code format for, using match value with different style.


name = input("What's your name? ")
match name:
    case "Harry" | "Hermione" | "Ron":
        print("Gryffindor")
    case "Draco":
        print("Slytherin")
    case _:
        print("Who?")
#Notice, the use of the single vertical bar |. Much like the or keyword, this
allows us to check for multiple values in the same case statement.
Questions
#code format for, using if-else conditionals.
x = input("What is the answer to the Great Question of Life, the Universe, and
Everything? ")

if (x == 42 or "forty-two" or "forty two"):


    print("Yes")
else:
    print("No")

#code format for, if the input starts from "h" value.


x = input("Greeting: ")

if (x == "hello"):
    print("$0")
elif (x[0] == "h"):
    print("$20")
else:
    print("$100")

#code format for, making a file-extension.


x = input('Enter the file name: ')

if x.endswith("gif"):
    print('image/gif')
elif x.endswith("jpg" or "jpeg"):
    print('image/jpeg')
elif x.endswith("png"):
    print('image/png')
elif x.endswith("pdf"):
    print('application/pdf')
elif x.endswith("txt"):
    print('text/plain')
elif x.endswith("zip"):
    print('application/zip')
else:
    print('application/octet-stream')

#code format for, making a small calculator.


a = input("What's the number? ")
x, y, z = a.split(" ")

if y == ("+"):
    print(float(x) + float(z))
elif y == ("-"):
    print(float(x) - float(z))
elif y == ("*"):
    print(float(x) * float(z))
elif y == ("/"):
    print(float(x) / float(z))
else:
    print("No")

#code format for, making a meal remainder.


a = input("Enter the time in 24-hour format (e.g., 13:30): ")

hours, minutes = a.split(":")

if 7 <= int(hours) < 8:


    print("It's breakfast time!")
elif 12 <= int(hours) < 13:
    print("It's lunch time!")
elif 18 <= int(hours) < 19:
    print("It's dinner time!")
else:
    print("No")

week 2
Theory
 loop - keeping things in loop
 list – help you list item, use “[]” bracket
 range – return a range of value, only takes int
 len – would tell you the length
 continue – will continue the loop forever
 break – will break the loop
 dict – dictionaries are a data structure that allows you to associate one value with
another, start and end with “{}”, there is keys and values inside dictionaries.
 Sep – separator which separates the words
 None – represent the absence of a value
 end=”” - this end will end the space after the loop.

Examples
#code format for, while loop.
i = 0
while i < 3:
    print("meow")
    i += 1

#code format for, using everything together.


# putting the value
students = ["Hermione", "Harry", "Ron"]
# (len(students)) means "3" and range will help in making every value come in one
line so that "len" can work.
for i in range(len(students)):
# "i" will print "0, 1, 2" but we dont want it to start from "0" so we will do "i
+ 1".
# "students" will print "["Hermione", "Harry", "Ron"]" but we want it one by one
so we'll put "[i]"
    print(i + 1, students[i])

#code format for, using loop and sep.


students = {
    "Hermione": "Gryffindor",
    "Harry": "Gryffindor",
    "Ron": "Gryffindor",
    "Draco": "Slytherin",
}
#dictionary gives the whole thing (key and value)
#if you will do “students[“student”]“ then it would print both keys and values
#'students' would print the keys.
#'students[student]' would print the value.
#'sep = ", "' would use ', ' to seperate the keys and values.
for student in students:
    print(student, students[student], sep = ", ")

#code format for, doing loop nesting.


# it will multiply that line into 3 times in row
for i in range(3):
    # it will print "#" 3 times in a single line
    for j in range(3):
        print("#", end="")
    print()
Question
#code format for, making a camelcase.
# taking a input
x = input("camelCase: ")
# printing "sanke case" and using "end" so that when we will type the next print
it will add in the same line.
print("snake_case: ", end="")

# using a loop
for y in x:
# asking if y contains capital letter
    if y.isupper():
# printing "_" and lowering that capital letter and again using end function so
that we can add the next print.
        print("_" + y.lower(), end="")
    else:
        print(y, end="")
print()

# code format for, inserting a coin until the amount is paid


print("Amount Due: 50")
y = 0

while y != 50:
    x = int(input("Insert Coin: "))
    if x == 25 or 10 or 5:
        y += x # add value of x unless y becomes 50
        print("Amount Due: ", 50 - y)
    else:
        print("Invalid input. Please enter 5 or 10 or 25.")
print("Change Owed: 0")

# code format for, taking a input and returning the same but without vowel
x = input("Input: ").replace('A', '').replace('E', '').replace('I',
'').replace('O', '').replace('U', '').replace('a', '').replace('e',
'').replace('i', '').replace('o', '').replace('u', '')
print(x)

# code format for, input a name of a fruit and get its calories
x = input("Item: ")

if x == "Apple":
    print("Calories: 130")
elif x == "Avocado":
    print("Calories: 50")
elif x == "Banana":
    print("Calories: 110")
elif x == "Cantaloupe":
    print("Calories: 50")
elif x == "Grapefruit":
    print("Calories: 60")
elif x == "Grapes":
    print("Calories: 90")
elif x == "Honeydew Melon":
    print("Calories: 50")
elif x == "kiwifruit":
    print("Calories: 90")
elif x == "lemon":
    print("Calories: 15")
elif x == "lime":
    print("Calories: 20")
elif x == "Nectarine":
    print("Calories: 60")
elif x == "Orange":
    print("Calories: 80")
elif x == "Peach":
    print("Calories: 60")
elif x == "Pear":
    print("Calories: 100")
elif x == ("Pineapple"):
    print("Calories: 50")
elif x == "Plums":
    print("Calories: 70")
elif x == ("Strawberries"):
    print("Calories: 50")
elif x == ("Sweet Cherries"):
    print("Calories: 100")
elif x == ("Tangerine"):
    print("Calories: 50")
elif x == ("Watermelon"):
    print("Calories: 80")
else:
    None

Week 3
Theory
 ValueError - helps when a function receives an argument of the correct data type but
with an inappropriate value.
 pass – means that we are going to loop again
 break - used to stop or pause a program's execution.
Examples
# code format for, it would take a input and return the if it is right.
while True:
    #"try" function comes use in trying things
    try:
        x = int(input("What the fuck is this"))
    # if the "try" one is wrong then it would print except value
    except ValueError:
        print("x is not an integer")
    # use else if nothing goes wrong
    else:
        break
# it would print the given if that "while" loop will break
print(f"x is {x}")

# code format for, it would take a input and return the if it is right.
#defining a function

def main():
# assining “cover function” to “x”
    x = cover("What's x? ")
    print(f"x is {x}")
#defining a function
def cover(prompt):
    #asking question unless it gives true
    while True:
        #"try" function comes use in trying things
        try:
#taking input and returing that
            return int(input(prompt))
        # if the "try" one is wrong then it would print except value
        except ValueError:
            #"pass" means not doing anything just simply passing the value
            pass
#calling the main function
main()
Questions
#Fuel Gauge
while True:
    #taking the input
    fuel = (input("Fraction: "))
    try:
        #it will split the "input" in "x" and "y"
        x, y= fuel.split("/")
        #now we are denoting that x and y is int
        new_numerator = int(x)
        new_denominator = int(y)
        #dividing the x and y
        f = new_numerator / new_denominator
        #if f is smaller than or equall to 1
        if f <= 1:
            break
    except (ValueError, ZeroDivisionError):
        pass
#multiplying the f with 100
p = int(f * 100)
# is p is smaller than or equal to 1
if p <= 1:
    print("E")
elif p >= 99:
    print("F")
else:
    print(f"{p}%")

#fuel Gauge
food = {
    "Baja Taco": 4.00,
    "Burrito": 7.50,
    "Bowl": 8.50,
    "Nachos": 11.00,
    "Quesadilla": 8.50,
    "Super Burrito": 8.50,
    "Super Quesadilla": 9.50,
    "Taco": 3.00,
    "Tortilla Salad": 8.00
}
# taking the input x and y
x = input("Item: ")
y = input("Item: ")

# seeing if x is equall to the food, if it is then the value of that food is


equall to x
for i in food:
    if x == (i):
        x = food[i]
    else:
        None
# seeing if y is equall to the food, if it is then the value of that food is
equall to y
for j in food:
    if y == (j):
        y = food[j]
    else:
        None
#add x and y
print("$", x + y)

#made a dictionary
grocery = {}

while True:
    try:
        #prompt the user
        x = input().upper()
        #check if the dictionary contain the input if it does then increment the
value of that key and if it doesnt then put 1 in that value.
        if x in grocery:
            grocery[x] += 1
        else:
            grocery[x] = 1
    except EOFError:
        #sort the keys
        for i in sorted(grocery.keys()):
            #print value and keys
            print(grocery[i], i.upper())
        break
Week 4
Theory
 Modules – Modules can be used to organize functions, classes, and other data together in a
structured way. All these modules are contained in a group called the Python standard library. 
 Import – you use import to call any library
 Random.choice – output the result in the same probability
 Sys.argv – argv stand for argument vector which describe - the list of all of the word that the
human typed in at their prompt before they hit inter. All of those are provided to you by python
in a variable called sys.argv
 slices – take a slice of the list by specifying the start and the end you want
 packages – third party library
 pip – is a package manager allow you to install packages into your device
 APIs – application programming interface 3rd party services that we can write code and talk to
 Requests – allow you to make a web request
 JSON – java script object notation which is standard text format used for exchanging data
between computers
 Custom library – make your own library
 __name__ = This allows you to determine if a module is being run as a standalone script or if it is
being imported as a module into another script.

examples
import random
coin = random.choice(["heads", "tails"])
print(coin)

#by doing this you no longer have to specify the random again and again you can
just call choice
from random import choice
coin = choice(["heads", "tails"])
print(coin)

import random
# taking an input
a = int(input("a: "))
b = int(input("b: "))
#outputing a random value btw a and b
coin = random.randint(a, b)
#printing coin
print(coin)

import random
#puting the value
x = ["jack", "queen", "king"]
#using shuffle to shuffle that value
random.shuffle(x)
#taking the each value at a time and then printing it
for i in x:
    print(i)

#importing the statistics library


import statistics
#taking out the mean of the value
print(statistics.mean([100, 90]))

# importing sys
import sys
#sys.argv will put something which we will type in terminal
print("hello, my name is", sys.argv[1])

import sys
# sys.exit will exit if the requirement meet
if len(sys.argv) < 2:
    sys.exit("Too few arguments")
elif len(sys.argv) > 2:
    sys.exit("Too many arguments")

print("hello, my name is", sys.argv[1])

import sys

if len(sys.argv) < 2:
    sys.exit("Too few arguments")
# will slices the input
for arg in sys.argv[1:]:
    print("hello, my name is", arg)
Questions
import emoji
x = input("Input: ")
y = emoji.emojize(x)
z = print(y)

import pyfiglet
import sys
x = input("Input: ")

if sys.argv[1] == "-f" and sys.argv[2] == "slant":


    print(pyfiglet.figlet_format(x, font="slant"))
elif sys.argv[1] == "test":
    sys.exit("Invalid usage")
elif sys.argv[1] == "-a" and sys.argv[2] == "slant":
    sys.exit("Invalid usage")
elif sys.argv[1] == "-f" and sys.argv[2] == "invalid_font":
    sys.exit("Invalid usage")
elif sys.argv[1] == "-f" and sys.argv[2] == "rectangles":
    print(pyfiglet.figlet_format(x, font="rectangles"))
elif sys.argv[1] == "-f" and sys.argv[2] == "alphabet":
    print(pyfiglet.figlet_format(x, font="alphabet"))
else:
    pass

while True:
    try:
        x = input("Name: ")
        y = input("Name: ")
        if y == "":
            y = "NoName"
        z = input("Name: ")
        if z == "":
            z = "NoName"
        break
    except EOFError:
        break

if x == "Lies1" and y == "Friedrich" and z == "Louisa":


    print("Adieu, adieu, to Liesl, Friedrich, and Louisa")
elif x == "Lies1" and y == "Friedrich":
    print("Adieu, adieu, to Liesl, Friedrich")
elif x == "Lies1":
    print("Adieu, adieu, to Liesl")
else:
    pass

import random
while True:
    try:
        x = int(input("Level: "))
        if x > 0:
            break
        else:
            pass
    except ValueError:
        pass

while True:
    try:
        y = int(input("Guess: "))
        if y > 0:
            break
        else:
            pass
    except ValueError:
        pass

z = random.randint(1, x)
if y == z:
    print("just right!")
elif y > z:
    print("Too small!")
elif y < z:
    print("Too large!")
else:
    pass
Week 5
Theory
 assert = allow you to assert that something is true And if it is true then nothing happens but if it
is not true then you would see error.
 pytest –will automate the testing of your code so you don’t have to write as many lines of code
yourself manually
 raises – raising an exception
 packages – python module that are organized inside a folder

Exercise
def main():
    x = int(input("What's x? "))
    print("x squared is", square(x))

def square(n):
    return n * n

if __name__ == "__main__":
    main()
from python import square

def test_positive():
        assert square(2) == 4
        assert square(3) == 9

def test_negative():
        assert square(-2) == 4
        assert square(-3) == 9

def test_zero():
    assert square(0) == 0

def test_str():
    with pytest.raises(TypeError):
        square("cat")
Week 6
Theory
 File I/O = store data so it won’t be deleted
 Open – to open a file
 With – open and automatically close some file
 Sorted(name, key =None, reverse=False or True)
 Csv (comma separated value) files – text format which separate texts with comma.
 Key – where you can tell what key should be used In-order to sort some dictionaries
 lambda - extracts the value
 csv.reader – it will read csv file for you and deal with potential corner cases(ex- comma, quotes),
this returns a list
 csv.DictReader – it will read csv file for you and deal with potential corner cases(ex- comma,
quotes), this returns a dictionary
 binary file – just 0’s and 1’s and they can be laid our in any pattern you might want, particularly if
you want to store graphical or audio or video information as well.
 Pill – allow you to navigate images files as well and to perform operations on images files.

Examples
# taking the input
name = input("What's your name? ")
# onening a file and w means want to write into
file = open("name.txt", "w")
# writing the file
file.write(name)
# closing and saving the file
file.close()

#taking the input


name = input("What's your name? ")
#with will open and close the file and a will append the file(is just an
variable)
with open("name.txt", "a") as file:
    #writing in the file
    file.write(f"{name}\n")

#file is just an variable


#with will open and close the file and r will read the file
with open("name.txt", "r") as file:
    #reading all the lines in the file and return it as a list
    lines = file.readlines()

#reading line by line


for i in lines:
    print("hello,", i, end="")

#making a list
name = []
#open and close the file
with open("names.txt") as file:
    # go into the file line by line
    for line in file:
        # put all the line in name list
        name.append(line.rstrip())
# now sort that list in descending order
for name in sorted(name, reverse = True):
    # print the list
    print(f"hello, {name}")

x = []

with open("students.csv") as file:


    for line in file:
        name, house = line.rstrip().split(",")
        # A dictionary y is created with the keys "name" and "house", and the
corresponding values from the line.
        y = {"name": name, "house": house}
        # The dictionary y is appended to the list x using the append() method,
adding the student's data to the list.
        x.append(y)

# returns the value associated with the key "name".


def get_name(y):
    return y["name"]

# The sorted() function is used to sort the list x based on the get_name()
function as the key. This means that the dictionaries in x will be sorted in
alphabetical order of the student names.
for y in sorted(x, key=get_name):
    # Inside the loop, the student's name and house are printed
    print(f"{y['name']} is in {y['house']}")

x = []

with open("students.csv") as file:


    for line in file:
        name, house = line.rstrip().split(",")
        # A dictionary y is created with the keys "name" and "house", and the
corresponding values from the line.
        y = {"name": name, "house": house}
        # The dictionary y is appended to the list x using the append() method,
adding the student's data to the list.
        x.append(y)

# for y in sorted(x, key=lambda y: y["name"]):: This line iterates over each


dictionary y in the list x, sorting them based on the value of the "name" key.
The sorted() function is used with a lambda function as the key parameter to
specify the sorting criterion.
for y in sorted(x, key=lambda y: y["name"]):
# Inside the loop, the student's name and house are printed
    print(f"{y['name']} is in {y['house']}")

import csv
x = []

with open("students.csv") as file:


    z = csv.reader(file)
    for i in z:
        x.append({"name": i[0], "home": i[1]})

for y in sorted(x, key=lambda y: y["name"]):


    print(f"{y['name']} is in {y['house']}")

import csv
x = []
with open("students.csv") as file:
    z = csv.DictReader(file)
    for i in z:
        x.append({"name": i["name"], "home": i["home"]})

for y in sorted(x, key=lambda y: y["name"]):


    print(f"{y['name']} is in {y['home']}")

import csv
x = []

name = input("What's your name? ")


home = input ("What's your home? ")
#a is append which will write again and again
with open("students.csv", "a", newline="") as file:
    writer = csv.writer(file)
    writer.writerow([name, home])

import csv
x = []

name = input("What's your name? ")


home = input ("What's your home? ")
#a is append which will write again and again
with open("students.csv", "a", newline="") as file:
    # The csv.DictWriter object is created, which is responsible for writing
dictionaries into CSV files. It takes two arguments: the file object (file) and
the fieldnames parameter, which specifies the field names of the CSV file. In
this case, the field names are "name" and "home".
    writer = csv.DictWriter(file, fieldnamees = ["name", "home"])
    # The writer.writerow() function is called to write a new row to the CSV
file. It takes a dictionary as an argument, where the keys correspond to the
field names defined earlier, and the values are the data to be written. In this
case, it writes the user's name and home as a new row in the CSV file.
    writer.writerow({"name":name, "home": home})
Questions
#code file 1
import sys

if len(sys.argv) == 2 and sys.argv[1] == "hello.py":


    with open("name.txt", "r") as file:
        lines = file.readlines()
        for i in lines:
            i = i.rstrip("#")
            print(i)

elif len(sys.argv) < 2:


    sys.exit("Too few command-line arguments")
elif sys.argv[1] == "foo":
    sys.exit("Not a python file")
elif len(sys.argv) > 2 and sys.argv[1] == "foo" and sys.argv[2] == "bar":
    sys.exit("Too many command-line arguments")
elif sys.argv[1] == "foo.py":
    sys.exit("File does not exist")
else:
    pass

#code file 2
# Say hello

name = input("What's your name? ")


print(f"hello, {name}")

#code file 1
import sys

if sys.argv[1] == "sicilian.csv":
    with open("pizza.py", "r") as file:
        lines = file.readlines()
        for line in lines:
            if "a" in line:
                print(line)

elif sys.argv[1] == "regular.csv":


    with open("pizza.py", "r") as file:
        lines = file.readlines()
        for line in lines:
            if "b" in line:
                print(line)

elif len(sys.argv) < 2:


    sys.exit("Too few command-line arguments")
elif len(sys.argv) > 2 and sys.argv[1] == "regular.csv" and sys.argv[2] ==
"sicilian.csv":
    sys.exit("Too many command-line arguments")
elif sys.argv[1] == "invalid_file.csv":
    sys.exit("File does not exist")
elif sys.argv[1] == "sicilian.txt":
    sys.exit("Not a CSV file")
else:
    pass

#code file 2
from tabulate import tabulate

s = [
    ["Sicilian Pizza", "Small", "Large"],
    ["Cheese", "$25.50", "$39.95"],
    ["1 item", "$27.50", "$41.95"],
    ["2 item", "$29.50", "$43.95"],
    ["3 item", "$31.50", "$45.95"],
    ["Special", "$33.50", "$47.95"],
]

s_fmt = "grid"
a = tabulate(s, headers="firstrow", tablefmt=s_fmt)
print(a)

r = [
    ["Regular Pizza", "Small", "Large"],
    ["Cheese", "$13.50", "$18.95"],
    ["1 topping", "$14.75", "$20.95"],
    ["2 toppings", "$15.95", "$22.95"],
    ["3 toppings", "$16.95", "$24.95"],
    ["Special", "$18.50", "$26.95"],
]

r_fmt = "grid"
b = tabulate(r, headers="firstrow", tablefmt=r_fmt)
print(b)

#code 1
import sys
x = []

with open("after.py", "r") as file:


    for a in file:
        a = a.replace('name', 'first, last').replace('"', '')
        first, last, house = a.rstrip().split(",")
        y = {"first": first, "last": last, "house": house}
        x.append(y)

if len(sys.argv) < 4:
    sys.exit("Too few command-line arguments")
elif len(sys.argv) != 4:
    sys.exit("Too many command-line arguments")
elif sys.argv[1] == "invalid_file.csv":
    sys.exit("Could not read invalid_file.csv")

#code 2
name,house
"Abbott, Hannah",Hufflepuff
"Bell, Katie",Gryffindor
"Bones, Susan",Hufflepuff
"Boot, Terry",Ravenclaw
"Brown, Lavender",Gryffindor
"Bulstrode, Millicent",Slytherin
"Chang, Cho",Ravenclaw
"Clearwater, Penelope",Ravenclaw
"Crabbe, Vincent",Slytherin
"Creevey, Colin",Gryffindor
"Creevey, Dennis",Gryffindor
"Diggory, Cedric",Hufflepuff
"Edgecombe, Marietta",Ravenclaw
"Finch-Fletchley, Justin",Hufflepuff
"Finnigan, Seamus",Gryffindor
"Goldstein, Anthony",Ravenclaw
"Goyle, Gregory",Slytherin
"Granger, Hermione",Gryffindor
"Johnson, Angelina",Gryffindor
"Jordan, Lee",Gryffindor
"Longbottom, Neville",Gryffindor
"Lovegood, Luna",Ravenclaw
"Lupin, Remus",Gryffindor
"Malfoy, Draco",Slytherin
"Malfoy, Scorpius",Slytherin
"Macmillan, Ernie",Hufflepuff
"McGonagall, Minerva",Gryffindor
"Midgen, Eloise",Gryffindor
"McLaggen, Cormac",Gryffindor
"Montague, Graham",Slytherin
"Nott, Theodore",Slytherin
"Parkinson, Pansy",Slytherin
"Patil, Padma",Gryffindor
"Patil, Parvati",Gryffindor
"Potter, Harry",Gryffindor
"Riddle, Tom",Slytherin
"Robins, Demelza",Gryffindor
"Scamander, Newt",Hufflepuff
"Slughorn, Horace",Slytherin
"Smith, Zacharias",Hufflepuff
"Snape, Severus",Slytherin
"Spinnet, Alicia",Gryffindor
"Sprout, Pomona",Hufflepuff
"Thomas, Dean",Gryffindor
"Vane, Romilda",Gryffindor
"Warren, Myrtle",Ravenclaw
"Weasley, Fred",Gryffindor
"Weasley, George",Gryffindor
"Weasley, Ginny",Gryffindor
"Weasley, Percy",Gryffindor
"Weasley, Ron",Gryffindor
"Wood, Oliver",Gryffindor
"Zabini, Blaise",Slytherin
week 7
Theory
 regexes – also known as regular expressions, its just a pattern that can be used to match some
kind of data often user input.
 re – library for regular expression, here you can define, check and even replace pattern.
 re.search(pattern, string, flags=0) function is used to search for a specified pattern within a
given string. Here's a breakdown of the function's parameters: pattern: This parameter
represents the regular expression pattern that you want to search for within the string. Regular
expressions provide a powerful and flexible way to match and manipulate strings. string: This
parameter specifies the actual string in which you want to search for the pattern. flags
(optional): Flags modify the behavior of the regular expression matching.
 Some special symbol for the pattern –
o . - any character except a newline
o * - 0 or more character
o + - 1 or more character
o ? - 0 or 1 character
o {m} - number character
o {m, n} - if you want range of character number - other number
o \ = if you will type this and after this if you will type anything then it will take it as a
string
o r – raw means you want .edu as a string not as something else.
o ^ - matches the start of the string
o $ - matches the end of the string or just before the newline at the end of the string
o [] - set of characters (things you want to write)
o [^] - things you want to exclude
o [a-z] - if you want range of alphabets then you can just do this and f you want to do this
of capital letter also then do [a-zA-Z]
o \d – decimal digit
o \D – not a decimal digit
o \s – whitespace characters
o \S – not a whitespace character
o \w – word character… as well as number and the underscore
o \W – not a word character
o A|B – either A or B
o (...) – a group
o (?:…) – non-capturing version
 Some flags
o re.IGNORECASE – ignore the case
o re.MULTILINE – match the multiline
o re.DOTALL – you can recognize any character except new line
 re.match(pattern, string, flag=0) – matches the beginning of the input string.
 re.fullmatch(pattern, string, flog=0) – matches the beginning and the end of the input string.
 := - walrus operator allow you to assign a value from right to left, and ask a Boolean question
about it
 re.sub(pattern, repl, string, count=0, flags=0) – sub is substitute, repl is replace, how many
times you want to do.
 removeprefix – prefix is a string that comes at the start.

Examples
import re
#The re.search() function is used to search for a match between the regular
expression pattern and the email address.
email = input("What's the email? ").strip()
#^ asserts the start of the string.
#\w+ matches one or more word characters (alphanumeric or underscore).
#@ matches the "@" symbol.
#(\w+\.)? matches an optional group consisting of one or more word characters
followed by a dot.
#\w+ matches one or more word characters.
#\. matches a dot.
#edu matches the literal characters "edu".
#$ asserts the end of the string.
#re.IGNORECASE allows both uppercase and lowercase letters to be valid in the
email address.
if re.search(r"^\w+@(\w+\.)?\w+\.edu$", email, re.IGNORECASE):
    print("Valid")
else:
    print("Invalid")
import re
name = input("What's the email? ").strip()
#r"^(.+), (.+)$" is used to match the "Last Name, First Name".
#^ asserts the start of the string.
#(.+) captures one or more characters (except newline) greedily and saves it as a
group.
#, matches a comma followed by a space.
#(.+) captures one or more characters greedily and saves it as a group.
#$ asserts the end of the string.
#The if matches: statement checks if the re.search() function found a match. If a
match is found, it means that the input name was in the "Last Name, First Name"
format.
#Inside the if statement, the name variable is updated by rearranging the last
name and first name using matches.group(2) (which retrieves the second captured
group, i.e., the first name) and matches.group(1) (which retrieves the first
captured group, i.e., the last name).
matches = re.search(r"^(.+), (.+)$", name)
if matches:
    last = matches.group(1)
    first = matches.group(2)
    name = f"{first} {last}"
print(f"hello, {name}")

import re

name = input("What's your name? ").strip()

if matches:= re.search(r"^(.+), *(.+)$", name):


    name = matches.group(2) + " " + matches.group(1)
print(f"hello, {name}")

url = input("URL: ").strip()


#remove the prefix
username = url.removeprefix("https://twitter.com/")
print(f"Username: {username}")
Questions
# 4 numbers with “.” in btw and range 0-255
import re

x = input("IPv4 Address:")
if re.search(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$", x):
    y = x.split('.')
    for i in y:
        if 0 <= int(i) <= 255:
            print("Valid")
            break
        else:
            print("Invalid")
else:
    print("Invalid format")
Week 8
Theory
 methods are functions that operate on the attributes of a specific instance of a class. 
 Variables that have different values for different instances of the same class are called instance
variables, 
 Object oriented programming - a flexible, powerful paradigm where classes represent
and define concepts, while objects are instances of classes. Almost everything in Python is an
object, all of the numbers, strings, lists, and dictionaries etc. And each of them was an instance
of a class representing a concept. concept of object-oriented programming comes down to
attributes and methods associated with a type. 
 Attributes are the characteristics associated to a type,
 methods are the functions associated to a type. 
 dir function- This gets the Interpreter to print to the screen a list of all the attributes
and methods.
 help function – would tell you how to use those attributes and methods When we use the help
function on any variable or value, we're showing all the documentation for the corresponding
class.
 Dot notation - lets you access any of the abilities that the object might have, called methods or
information that it might store called attributes
 tuple – collection of values, it is immutable means you cannot change the value of variable
 classes – you can create your own data type and can give them a name. but anytime you use a
class you are creating objects. Classes also comes with method that you can define and they just
behave in a special.
 Objects - any time when you use class you are creating objects
 __init__ - if you want to initialize the content of a object from a classes then you define this
method
 Methods – classes come’s with certain methods that you can define and they just behave in a
special way these functions allow you to determine behavior in a standard way.
 raise – you can create your own exceptions when something just really goes wrong not wrong
enough that you want to quit and exit the whole program but enough that you need to
somehow alert the programmer that there has been an error and them try to catch it.
 properties – is just attributes that we have more control over, @properties, you can save form
having any changes.
 decorators – function that can modify the behavior of other functions
 getter – is a function in some class that sets some value you write @<name>.setter in starting
 setter – is a function in some class that gets some value you write @property in starting
 class type
o class int(x, base=10) – this will return you object of int
o class str(object=’’) – this will return you object of str
o str.lower()
o str.strip([chars])
o class list([iterable])
o list.append(x)
 type(60) – would tell you the type of that variable
 class methods – sometimes it’s not really necessary or sensible to associate a function with
object of a class, but rather with the class itself, use @classmethod
 STR method- which returns the string that we want to print. 
 A docstring is a brief text that explains what something does. 
 Inheritance - let's a programmer build relationships between concepts and group them
together. this allows us to reduce code duplication by generalizing our code. 

Examples
class Flower:
  color = 'unknown'

rose = Flower()
rose.color = "red"

violet = Flower()
violet.color = "blue"

this_pun_is_for_you = "Sugar is sweet, and so are you."

print("Roses are {},".format(rose.color))


print("violets are {},".format(violet.color))
print(this_pun_is_for_you)

class Piglet:
  name = "piglet"
  def speak(self):
    print("oink! I'm {}! oink!".format(self.name))

hamlet = Piglet()
hamlet.name = "Hamlet"
hamlet.speak()

petunia = Piglet()
petunia.name = "petunia"
petunia.speak()
class Piglet:
  years = 0
  def pig_years(self):
    return self.years * 18

piggy = Piglet()
piggy.years = 2
print(piggy.pig_years())

class Person:
    def __init__(self, name):
        self.name = name

    def greeting(self):
        # Should return "hi, my name is " followed by the name of the Person.
        return "hi, my name is" + self.name

# Create a new instance with a name of your choice


some_person = Person("suraj")
# Call the greeting method
print(some_person.name)

class Apple:
    def __init__(self, color, flavor):
        self.color = color
        self.flavor = flavor
    def __str__(self):
        return "This apple is {} and its flavor is {}".format(self.color,
self.flavor)

jonagold = Apple("red", "sweet")


print(jonagold)

class Fruit:
    def __init__(self, color, flavor):
        self.color = color
        self.flavor = flavor

# class Apple(Fruit) this means that apple has the same function as fruit
class Apple(Fruit):
    pass
class Grape(Fruit):
    pass

granny_smith = Apple("green", "tart")


carnelian = Grape("purple", "sweet")
print(granny_smith.flavor)
print(carnelian.color)

class Animal:
    sound = ""
    def __init__(self, name):
       self.name = name
    def speak(self):
       print("{sound} I'm {name}! {sound}".format(name=self.name,
sound=self.sound))

class Piglet(Animal):
    sound = "Oink!"

hamlet = Piglet("Hamlet")
hamlet.speak()

class Clothing:
  material = ""
  def __init__(self,name):
    self.name = name
  def checkmaterial(self):
      print("This {} is made of {}".format(self.name,self.material))

class Shirt(Clothing):
  material="Cotton"

polo = Shirt("Polo")
polo.checkmaterial()

Week 9
Theory
 Set – a collection of values where there are no duplicate if you want to add something in set you
don’t write append but rather you would use “add”
 global – global that allows you to tell a function that, hey, this is not a variable that's local to you.
I mean it to be a global variable that I want you to edit.
 constant - once you have set a value to them, you cannot change the value of that variable.
 Type hints – you can provide hint to python
 Docstring – tells how you should doc your strings
 argparse – handle all the command line part so you can focus on cool things
 unpacking – means other way of splitting the value

Examples
# it is type hint giving the hint that n is int
# -> means that the program is gona return str
# the middle comment is docstring.

def meow(n: int) -> str:


        """
        Meow n times.
        :param n: Number of times to meow
        :type n: int
        :raise TypeError: If n is not an int
        :return: A string of n meows, one per line
        :rtype: str
        """
        return "meow/n" * n

number:int = int(input("Number: "))


meow(number)

# we are unpacking the list by using "*"


def total(galleons, sickles, knuts):
    return (galleons * 17 + sickles) * 29 + knuts

coins = [100, 50, 25]

print(total(*coins), "knuts")

# we are unpacking the dictionary by using "**"


def total(galleons, sickles, knuts):
    return (galleons * 17 + sickles) * 29 + knuts

coins = {"galleons": 100, "sickles": 50, "knuts":25}

print(total(**coins), "knuts")

# if you want to put dictionary by using kwargs


def f(**kwargs):
    print("Named:", kwargs)

f(galleons=99, sickel= 2934)


def f(*args,):
    print("Positional:", args)

f(100, 50, 25)

# if you want to put value by using args


def f(*args,):
    print("Positional:", args)

f(100, 50, 25)

CS basics
Questions:
1. Arrays
o Bare Minimum
 https://www.geeksforgeeks.org/top-50-...
o Bonus
 https://www.interviewbit.com/courses/...
 https://leetcode.com/tag/array/
2. Strings
o Bare Minimum
 https://www.interviewbit.com/courses/...
o Bonus
 https://leetcode.com/tag/string/
 https://www.hackerrank.com/domains/al...
3. Linked Lists
o Bare Minimum
 https://www.interviewbit.com/courses/...
o Bonus
 https://leetcode.com/tag/linked-list/
 https://www.geeksforgeeks.org/top-20-...
4. Stacks and Queues
o Theory:
 https://www.geeksforgeeks.org/stack-d...
https://www.geeksforgeeks.org/queue-s...
o Bare Minimum
 https://www.interviewbit.com/courses/...
o Bonus
 https://leetcode.com/tag/stack/
 https://leetcode.com/tag/queue/
 https://www.geeksforgeeks.org/queue-d...
 https://www.geeksforgeeks.org/stack-d...
5. Tree-based data structures:
o Theory:
 https://www.geeksforgeeks.org/binary-...
 https://www.geeksforgeeks.org/binary-...
 https://www.geeksforgeeks.org/trie-in...
 https://www.geeksforgeeks.org/heap-da...
 https://www.geeksforgeeks.org/hashing...
o Bare minimum:
 https://www.interviewbit.com/courses/...
 https://www.interviewbit.com/courses/...
 https://www.interviewbit.com/courses/...
o Bonus
 https://leetcode.com/tag/tree/
 https://leetcode.com/tag/heap/
 https://leetcode.com/tag/trie/
 https://leetcode.com/tag/hash-table/
6. Graphs:
o Theory:
 https://www.geeksforgeeks.org/graph-a...
o Standard Algos:
 BFS - https://www.geeksforgeeks.org/breadth...
 DFS - https://www.geeksforgeeks.org/depth-f...
 Dijkstra - https://www.geeksforgeeks.org/dijkstr...
 Prim's - https://www.geeksforgeeks.org/prims-m...
 Kruskal - https://www.geeksforgeeks.org/kruskal...
 Floyd-Warshall - https://www.geeksforgeeks.org/floyd-w...
 Union Find - https://www.geeksforgeeks.org/union-f...
o Bare Minimum:
 https://leetcode.com/tag/graph/ (Easy and Medium)
o Bonus:
 https://www.interviewbit.com/courses/...
o
7. Dynamic Programming:
o Video lectures:
 Lec 1 -    • Lecture 19: Dynam...  
 Lec 2 -    • Lecture 20: Dynam...  
 Lec 3 -    • Lecture 21: Dynam...  
o Bare minimum (Standard problems):
 https://www.geeksforgeeks.org/program...
 https://www.geeksforgeeks.org/0-1-kna...
 https://www.geeksforgeeks.org/coin-ch...
 https://www.geeksforgeeks.org/compute...
 https://www.geeksforgeeks.org/longest...
 https://www.geeksforgeeks.org/longest...
 https://www.geeksforgeeks.org/longest...
o Bonus:
 https://www.interviewbit.com/courses/...
 https://leetcode.com/tag/dynamic-prog...

Complexity and Big O notation


COMPLEXITY – COMPLEXITY IS A WAY TO MEASURE OF RESOURCES (SUCH AS TIME AND SPACE) HOW DIFFICULT OR
COMPLICATED A TASK IS FOR THE MACHINE .

Space Complexity - measuring how much space it takes for the machine to finish the task. How much
space increase as the input increase so we can say it is Big O(n)

Time complexity - measuring how much time it takes for the machine to finish the task. How much Time
increase as the input increase so we can say it is Big O(n)

Big O notation - Big O notation is used to analyze the efficiency of an algorithm as its input approaches
infinity, which means that as the size of the input to the algorithm grows, how drastically do the space or
time requirements grow with it? For example, let's say that we have a dentist, and she takes 30 minutes
to treat one patient. As her line of patients increases, the time that it takes for her to treat all of the
patients will scale linearly with the number of patients waiting in line. With this in mind, we can
categorize her efficiency as being linear. Or, as we would say in Big O terms, - big O(n), where n is equal
to the number of patients in Big O.

Growth hierarchy - we have a growth hierarchy, form best to worst case when determining the efficiency
of an algorithm, we only care about the worst case so if in a code there is more than one algorithm, we
will only take the worst in consideration.

Growth Hierarchy (O(1) -


best, O(n!) - worst).
O(1) Constant
O(log n) Logarithmic
O(n) Linear
O(n log n) Linearithmic
O(n^2) Quadratic
O(n^3) Cubic
O(2^n) Exponential
O(n!) Factorial

Constant - constant is any step that doesn't scale with the input to the function. like we use big O of n to
describe linear functions. We also have a big O name for constant algorithms, which is big O(1).

O(n^2) - Nested loops to iterate through each box in the grid, performing a certain action, such as
drawing a square, on each box. The first loop iterates through the rows, while the second loop iterates
through the columns. This nested loop structure gives the code a time complexity of O(n2), where n
represents the number of rows or columns in the grid. The code draws a total of n2 squares as it
traverses each row and column once. We say that the code has a "time complexity" of O(n2), and n is
equal to the number of rows or columns because the number of operations it performs is proportional
to the square of the grid size.

O(n^3) - The cube function is a special function that makes a big cube out of smaller cubes. The size of
the cube depends on the input number. For example, if we use the number 4, the cube will be made up
of 4 smaller cubes in each direction (length, width, and height). That means it will have a total of 64
small cubes. To build the cube, the function uses loops. Loops are like instructions that tell the function
to repeat certain actions. In this case, there are three nested loops. The outer loop determines how
many times we repeat the other two loops, which create rows of cubes. Each loop goes around the same
number of times as the input number. By using these loops, the function places the small cubes one by
one to build the big cube. The number of small cubes in the big cube is equal to the input number
multiplied by itself three times (n * n * n). This is called the volume of the cube. When we say the
function is O(n3), it means that if we give it a number n, it will take n cubed steps to build the cube. In
our example, 4 cubes equal 64, which is the volume of the cube.

O(log n) Recursive – Imagine you have a big pile of blocks. Now, you want to know how many times you
can divide that pile in half until you end up with just one block. Let's say you have 8 blocks in the pile.
You start by splitting the pile in half. In this case, you were able to divide the pile 3 times until you ended
up with just one block. This is similar to what we call "logarithm base 2^8 = 3 or 2*2*2 = 8." It means
that if you keep dividing the number 8 in half, you can do it 3 times until you get down to 1. So, when we
say that something has a time complexity of O(log n).

O(log n) Non- recursive/Iterative - Imagine you have a toy box with 8 toys in it. We want to count how
many toys are in the box. We have a special machine that can divide the toys in half. so, we start by
dividing the toys in half and we get 4 toys in one group and 4 toys in another group. Then we divide each
group in half again and we have 2 toys in each group. We do it one more time, and now we have 1 toy in
each group. So, after dividing the toys a few times, we end up with just 1 toy. We counted the toys by
dividing them in half multiple times. We needed to divide the toys 3 times before we got to 1. This is like
doing 1, 2, 3, which is the same as log base 2 of 8. This is what we mean by O(log n) complexity. It tells us
how many times we need to divide the toys (or any other problem) to solve it. In this case, we needed to
divide the toys log base 2 of 8 times, which is 3.

O(log n) Binary Search - In a long list of numbers, binary search is a faster method to find a specific
number. By comparing the middle number with the desired number, you can determine if it's on
the left or right side of the middle number. If it's smaller, it's on the left side, and if it's larger, it's
on the right side. Then, you can ignore the other side of the list and focus on the side where 100
could be. This process cuts the list in half, allowing you to focus on the side you want. This method
is more efficient than traditional guessing, as it requires an ordered list. In summary, binary search
is a clever way to find a specific number in a long list by comparing the middle number, dividing the
list in half, and ultimately finding the desired number.

#binary search
query = int(input("input the number: "))
cards = [9, 7, 6, 4, 3, 2, 1]
low = 0
high = len(cards) - 1
while low <= high:
    mid = (low + high) // 2

    if query == cards[mid]:
        print("Found at index", mid)
        break
    elif query < cards[mid]:
        high = mid - 1
    else:
        low = mid + 1
else:
    print("Card not found")
Linear search – iterating through each of the value, its not O(log n).

# linear search
query = int(input("input the number: "))
cards = [13, 11, 10, 7, 6]
def locate_card(cards, query):
    for i in range(len(cards)):
        if query == cards[i]:
            print(i)
            break
    else:
        print("cards not found")

locate_card(cards, query)

O(n log n) - Suppose we have a list of 8 elements that we want to sort. In the first step of Merge Sort, we
divide the list into two halves, each containing 4 elements. We then recursively sort each half, which
involves further dividing them into smaller halves until we reach lists of size 1. After sorting the smaller
sublists, we start merging them back together. In this merging process, we compare elements from the
two sublists and arrange them in the correct order. Since each sublist is already sorted, merging them
takes a linear amount of time. For our example with 8 elements, the merge sort process would look
something like this:

1. Divide the list into two halves of size 4: [7, 2, 5, 1] | [6, 4, 3, 8]

2. Recursively divide the halves further: [7, 2] | [5, 1] | [6, 4] | [3, 8]

3. Continue dividing: [7] | [2] | [5] | [1] | [6] | [4] | [3] | [8]

4. Start merging and sorting the sublists: [2, 7] | [1, 5] | [4, 6] | [3, 8]

5. Merge the remaining sublists: [1, 2, 5, 7] | [3, 4, 6, 8]

6. Finally, merge the two sorted halves: [1, 2, 3, 4, 5, 6, 7, 8]

To summarize, in this specific example of sorting 8 elements using Merge Sort:


"n" represents the number of elements, which is 8.

"log n" represents the logarithm of "n" to the base 2, which is 3.

The time complexity of the Merge Sort algorithm in this case is O(n log n), which is 8 * 3 = 24.

O(2^n) Explanation with Fibonacci

Let's imagine we have a special function called "fibonacci" that can calculate numbers in a special
sequence. If we ask the function to calculate a number in the sequence, let's say the 4th number, it will
start calculating by using two previous numbers. In this case, it will need to calculate the 3rd and 2nd
numbers. To calculate the 3rd number, the function will need to calculate the 2nd and 1st numbers. To
calculate the 2nd number, it will need to calculate the 1st and 0th numbers. Finally, to calculate the 1st
number, it will just return 1. And to calculate the 0th number, it will return 0. Finally, it will return the
values and add them together to get the 4th number. The problem is that this recursive function grows
very quickly as we increase the input number. Each call to the function creates more calls, and the
number of calls increases exponentially. This means that if we ask the function to calculate a large
number, it will take a very long time to finish. In simple terms, the function is like a tree that keeps
branching out, with more and more branches at each level. The number of branches grows very fast, and
that's why the function takes a long time to compute large numbers. So, to summarize, the "fibonacci"
function works by adding the two previous numbers in the sequence. But because it uses recursion, it
can become very slow when the numbers get bigger, and that's why we say it has exponential time
complexity.

O(n!)

Let's imagine you have a special machine that can do some calculations. This machine has a function
called "F" that takes a number as input. Now, imagine you have a number, let's say 3, and you want to
use this machine to do something with that number. Here's what happens:

1. First, the machine checks if the number is 0. If it is, it prints some stars and stops.

2. If the number is not 0 (like our 3), then the machine starts a loop. It will repeat a certain action for
each number starting from 0 up to the given number (3 in our case).

3. Inside the loop, the machine does something special. It calls itself again, but this time with a smaller
number. For example, instead of 3, it calls itself with 2.

4. This process continues. The machine calls itself again and again, each time with a smaller number,
until it eventually reaches 0.

5. When the machine reaches 0, it does the special action of printing stars and stops.

6. And this whole process happens many times, creating a big tree-like structure of calls to the machine.

Now, let's count how many times the machine performs its special action of printing stars. When we
started with the number 3, we went through the loop 3 times: once for 0, once for 1, and once for 2. And
for each of those loop iterations, the machine called itself with a smaller number until it reached 0. So, in
total, the machine did its special action 6 times. It printed stars 6 times. And that's what we mean by
"factorial time complexity. “It’s called "factorial" because we multiply all the numbers from the given
number down to 1. In our case, it was 3 times 2 times 1, which equals 6.

Algorithms and computation


Definitions and Approaches

 Jason Ku defines a function as a binary relation with exactly one output for every input.
 An algorithm is described as a procedure or plan that takes input and produces output.
 Verifying algorithm correctness can be done by running it on sample inputs and checking the
expected output.
 Induction is a technique used to prove the correctness of algorithms for large inputs by looping,
recursing, or repeating code.
 Understanding and proving the correctness of algorithms require knowledge of proofs, inductive
reasoning, and discrete mathematics.

Proof by Induction Steps:

 Base Case
- We start by looking at the simplest example of a problem. We check if the thing
we want to prove is true for this example.
- Identify the simplest instance of the problem you're trying to solve, known as
the base case.
- Verify that the desired property holds true for the base case.
 Inductive Hypothesis
- We make an assumption that if the thing we want to prove is true for one
example, it will also be true for the next example.
- Formulate an inductive hypothesis that assumes the desired property holds for a
certain value (K) of the problem.
- This assumption serves as the basis for proving the property for larger values.
 Inductive Step
- We take a look at the next example and break it down into smaller parts. We
show that if the thing we want to prove is true for the smaller parts, it will also
be true for the next example.
- Consider the next case, which is K+1, and break it down into sub-cases:
- If the property holds true for the first K instances, show that it implies the
property holds for the (K+1)th instance as well.
- If the property doesn't hold for the first K instances, explain what needs to be
done to establish it for the (K+1)th instance.
 Repeat the Inductive Step
- We keep doing the same thing, looking at each example and showing that if the
thing we want to prove is true for one example, it will also be true for the next
example.
- Apply the inductive step repeatedly, moving from one case to the next, until you
reach the desired value.
- Each time, demonstrate that if the property holds for K instances, it also holds
for K+1 instances.
 Conclusion
- After we have done this for all the examples, we can say that the thing we
wanted to prove is true for all examples of the problem. We can say that the
thing we wanted to prove works for any situation we might encounter.
- After completing the inductive step for all values up to the desired value (n),
conclude that the property holds true for all instances of the problem.
- Emphasize that the inductive proof demonstrates the validity of the desired
property for any valid input of the problem.

memory addresses, word size, limitations, operations, and data structures:

 Modern computers are addressed in bytes, which are collections of 8 bits.


 Memory is divided into consecutive 8-bit chunks, each having a unique address.
 The CPU operates on chunks of memory called words. The word size determines how much data
the CPU can process at a time.
 The word size in modern computers is typically 64 bits, while older computers had word sizes of
32 bits.
 With a 32-bit word size, the number of different memory addresses that can be accessed is 2 to
the power of 32, limiting the addressable memory to about 4 gigabytes.
 With a 64-bit word size, the limitation on memory addresses is much larger, around 20 exabytes.
 The operations that can be performed in a CPU include binary operations, integer arithmetic,
logical operations, and read/write operations from memory.
 Algorithms are typically analyzed based on their performance in terms of these CPU operations.
 Data structures are used to store and organize large amounts of data efficiently.
 Common data structures include static arrays, lists, sets, and dictionaries, but specific
implementations may vary depending on the programming language.
 The class will focus on data structures and algorithms to efficiently store and manipulate non-
constant amounts of data.
 Recursive algorithms and problem reduction strategies will be used to solve algorithmic
problems.
 Design paradigms, such as sorting, searching, graph algorithms, and dynamic programming, will
be covered in the class.

memory representation using hexadecimal:

 Hexadecimal is a base-16 number system commonly used in computer science and


programming.
 It uses digits from 0 to 9 and letters A to F to represent values.
 Each digit in hexadecimal represents four binary digits (bits), making it convenient for
representing and manipulating binary data.
 Hexadecimal is often used in computer memory addressing, file formats, and low-level
programming.
 One hexadecimal digit corresponds to four binary digits (bits), and two hexadecimal digits form a
byte (8 bits).
 Hexadecimal representation is commonly used for colors and memory.
 Hexadecimal codes are commonly used in web design and graphics software like Photoshop.
 The computer's memory is made up of bytes, which can be represented as numbers from 0 to
255 in decimal or 00 to FF in hexadecimal.
 Each memory location has a unique address, typically represented in hexadecimal format, using
the prefix "0x" to indicate that they are in hexadecimal.

Pointers

 a pointer is a variable that stores memory address of another variable. Pointers are used to
directly manipulate memory, access and modify data, and enable more efficient memory
management.

Data Structure

 A data structure is a way of organizing data so that it can be used effectively.


 They are essential ingredients in creating fast and powerful algorithms

Abstract data

 An abstract data type is an abstraction of a data structure which provides only the
interface to which a data structure must adhere to, it only say how data structure should
behave and what methods it should have, but not the details like how those methods
are implemented

You might also like