#Python#is#crazy

Hello world Program

#!/usr/bin/python3
print("hello world")

Python 3 Essential Training

Comment

For comment we use # sign

Pep8

Formatting standard for writting your python codes.

variables

Just like any other programming language name = value

 
x = 5
x = 12
#x is now 12
 
x= "We are the face of the fusion "
#x is now that string
 
x = str(3) #X will be the string "3"
y = int(3) #will be an integer 3
z = float(3) will be 3.0

The id command

You use the id comman if you want to print the memory address of your variables in python

x = 1
print(id(x))
#output: 140726132273960
 
x = x + 1
print(id(x))
# output: 140726132273992
#New Memory holder,
# At some point, the garbage collector in python will release this space
 
 
# Example with mutable Types
x = [1,2,4]
print(id(x))
 
x.append(4)
print(id(x))

Variable Immutability

Because Integers are not mutable , technicaly we can not change it’s value location, a new variable is simply created when you alter the value

Type Annotation in python

if you come from a language such as java, which you have to give a precision of a type, int a=3 you may be disappointed with python but since python 3.6 there is type annotation

age: int = 30

Swapping values in Python

You want to swap the value of variables ? in python you can do this in simple ways. #swap

a=1
b=5
 
a, b = b, a #this will swap their Values
 
#line above is equivalent to
temp=a
a=b
b=temp
def b(n):
	print("{:08b}".format(n))
b(5)
x,y=0x55,0xaa
 
 
b(x | y)
#will output the or or the binary numbers , which you already know how to do on paper
 
b(x & y) #and
 
b(x ^ y) #exclusive or
 
b(x << 4) #x will be shifted to to left of four bits
 
b(x >> 4) #x will be shifted to to right of four bits
 
b(x ~ 4) #Ones complement of the x
 
#Will output the binary format of a number to 8 digits
 00000101
 

divmod

Output the modulus and the remainder of two numbers
print(divmod(5,3))
 
#output
# (1,2) one in 3 and there is a rest of 3

is Operator and double equal ==

The is operator is used to compare the id of each object

x=3
y=3
 
print(x is y) #will compare their ids
 
print(x is not y) #will compare their ids
 
x==y #will comare their values

type() function

This is a function which is used to get the type of a varable

x='hello world'
print(type(x))

Assignment of vaiables

#assignment Python allows you to assign values to multiple variables in one line .

Must remember

  • 💡 the bumber of variables must equat to the number of values ..
x, y, z = "Orange", "Banana", "Cherry"
# Or
x = y = z = "Orange" #this is acceptable
 

Concatenation

#adding#concatenating#joining Python uses the + sign for concatanation

x = "Python is "
y = "awesome"
z =  x + y
print(z)
print(x+z)
 
 

Title

You can not concatenate a string and an iteger , you would want to do something like this

.format(value1,value2…valuen) used for replacement

format method

(% notation is considered obsoescent)

#This is a string {}".format(42)
print("The {} {} {}".format("quick","fox","brown")
print("The {t} {b} {c}".format(t="quick",c="fox",b="brown")
# There is another way to write the format method From python 3.6
# you simply write f in front of the things you want o print and boom
print(f"Hello His name is {name}")
print(x+" "+y+" "+str(v))
#or
print("{} {} {}  Times".format(x,y,v))
myorder = "I want {} pieces of item {} for {} dollars."
print(myorder.format(quantity, itemno, price))

Local Vs Global Variable

x="python is"
y="Is Really fun "
v=32
c=x+" "+y+" "+str(v)+" times" #global variable since it's outside of the function
def func():
    c="Not funny Python" #local Variable
    print(c)
 
func() #will output the local variable
 
print(c) #will output the global variable

Global Keyword

#global#local The global Keyword is used to force a variable declaration as global no matter where you are

c = "This is fun "
print(c)
def func():
    global c #accessing the c which is global
    c ="Not funny Python" #Changing the global variable
    print(c)
print(c)

Python Datatype

Python has the following data types built-in by default, in these categories:

Text Type: str

Numeric Typesint, float, complex
Sequence Typeslist, tuple, range
Mapping Typedict
Set Typesset, frozenset
Boolean Typebool
Binary Typesbytes, bytearray, memoryview

Python Strings, Stringins in python

#str#string Python Strings are immutable , The Immutability makes it hard not possible to modify the string

name="daniel"
 
name[0]="Daniel" #This will generate An Error in python
 
daniel="d"
daniel*=10
 
print(daniel)
a = """\
Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua."""
 
print(a)
 
#If you write your string like that , python will insert a line break where there is a line break in your code , it can either be """ or '''

Row String

#r

a= r"helo \n we are happy you \n here"
#will output a string the way it is

Working With Strings in Python

The In syntax with string

The in keyword is used to check if a value is present in a sequence (list, range, string etc.). The in keyword is also used to iterate through a sequence in a for loop:

for x in "banana":
  print(x) #will look through the whole string one char by another

String length

#length#len we use the len function for the string length

a="hello world "
print(len(a))

Check for A specific String

To check if a certain phrase or character is present in a string, we can use the keyword in.

txt = "The best things in life are free!"
print("free" in txt) #will output either true or false
 
or  using not
 
txt = "The best things in life are free!"
print("expensive" not in txt)

using In , with the if condition

txt = "The best things in life are free!"
if "free" in txt:
  print("Yes, 'free' is present.")
 
#or
 
txt = "The best things in life are free!"
if "expensive" not in txt:
  print("Yes, 'expensive' is NOT present.")
 
 

Slicing Strings

You can return a range of characters by using the slice syntax. Specify the start index and the end index, separated by a colon, to return a part of the string.

b = "Hello, World!"
b = "Hello, World!"
print(b[2:5]) #3rd char to the 5th one
print(b[2:]) #3rd to the end
print(b[-5:-2]) # from o to l

String Methods

upper() :uppercase, string.upper()
lower() :lowercase, String.lower()
strip()Remove White Space,before and after a string, string.strip()
replace():method replaces a string with another string:
a="ilunga gisa daniel"
 	print(a.replace("a","g")
split()this method returns a list where the text between the specified separator becomes the list items.
a = "Hello, World!"
print(a.split(",")) # returns ['Hello', ' World!']

Slices in Python

Slices in python are not inclusinve , so 4:6 will go from 4 to 5

list=[1,2,3,4,5,6,7,8,9,10]
print(list[0:5])
#output [1, 2, 3, 4, 5]
 
list[:] = range(500)
print(list)
print(list[27:61:3])
 
 
name="Ilunga Gisa Daniel"
 
print(name[0:]) #start to end
 
print(name[0:4])
 
print(name[0:10:2]) #Two Teps should be Jumped when updating the string
 
 

Reverse A String

#reverse

name=[::-1]

String Concatenation

To concatenate in python we use the + symbol

a = "Hello"
b = "World"
c = a+" "+ b
print(c)

You can not concatenate String And Integers in python, but you can do something like this obviously

quantity = 3
itemno = 567
price = 49.95
myorder = "I want to pay {2} dollars for {0} pieces of item {1}."
print(myorder.format(quantity, itemno, price))

Escaping Chatacters in python

to escape a character we can use the backslash \

\' 	Single Quote
\\ 	Backslash
\n 	New Line
\r 	Carriage Return
\t 	Tab
\b 	Backspace
\f 	Form Feed
\ooo 	Octal value
\xhh 	Hex value

Other String Methods

		Method 		Description
capitalize()Converts the first character to upper case
casefold()Converts string into lower case
center()Returns a centered string
count()Returns the number of times a specified value occurs in a string
encode()Returns an encoded version of the string
endswith()Returns true if the string ends with the specified value
expandtabs()Sets the tab size of the string
find()Searches the string for a specified value and returns the position of where it was found
format()Formats specified values in a string
format_map()Formats specified values in a string
index()Searches the string for a specified value and returns the position of where it was found
isalnum()Returns True if all characters in the string are alphanumeric
isalpha()Returns True if all characters in the string are in the alphabet
isdecimal()Returns True if all characters in the string are decimals
isdigit()Returns True if all characters in the string are digits
isidentifier()Returns True if the string is an identifier
islower()Returns True if all characters in the string are lower case
isnumeric()Returns True if all characters in the string are numeric
isprintable()Returns True if all characters in the string are printable
isspace()Returns True if all characters in the string are whitespaces
istitle()Returns True if the string follows the rules of a title
isupper()Returns True if all characters in the string are upper case
join()Joins the elements of an iterable to the end of the string
ljust()Returns a left justified version of the string
lower()Converts a string into lower case
lstrip()Returns a left trim version of the string
maketrans()Returns a translation table to be used in translations
partition()Returns a tuple where the string is parted into three parts
replace()Returns a string where a specified value is replaced with a specified value
rfind()Searches the string for a specified value and returns the last position of where it was found
rindex()Searches the string for a specified value and returns the last position of where it was found
rjust()Returns a right justified version of the string
rpartition()Returns a tuple where the string is parted into three parts
rsplit()Splits the string at the specified separator, and returns a list
rstrip()Returns a right trim version of the string
split()Splits the string at the specified separator, and returns a list
splitlines()Splits the string at line breaks and returns a list
startswith()Returns true if the string starts with the specified value
strip()Returns a trimmed version of the string
swapcase()Swaps cases, lower case becomes upper case and vice versa
title()Converts the first character of each word to upper case
translate()Returns a translated string
upper()Converts a string into upper case
zfill()Fills the string with a specified number of 0 values at the beginning

Integers

They are basically two different kinds of numbers in python : Integers and Float Numebrs

num=43
print(type(num), num) #int
 
num=43.0
print(type(num), num) #float
 
num=42/9
print(type(num), num) #float with value 4.66666
 
num=42//9 #make sure we get back an integer
print(type(num), num) #int , 4

Get you the floating integer representation of a flating number

num=int(43.3)

Round Function round(number, digits)

num=4.6666666
 
print(round()) #output 5
 
print(round(num,2)) #will round it to 2Digits 4.67
 

Characters

Python does not have a character data type, a single character is simply a string with a length of 1. Square brackets can be used to access elements of the string.

a = "Hello, World!"
print(a[1])

Python Boolean

#bool#true#false expression bellow will either return true or false

print(10 > 9)
print(10 == 9)
print(10 < 9)

Bool Function

The bool() function allows you to evaluate any value, and give you True or False in return,

 
print(bool("Hello")) #true
print(bool(15)) #true
print (bool()) #fase

Things to evaluate to false

print(bool(False))
print(bool(None))
print(bool(0))
print(bool(""))
print(bool(()))
print(bool([]))
print(bool({}) )

#function which returns true

def myFunction() :
  return True
 
if myFunction():
  print("YES!")
else:
  print("NO!")

Check if an object is an Integer or not

x = 200
print(isinstance(x, int))

Python Operators

Remainder Of modulo We use the % symbol 4 % 3 = 1

Multplication We Use _, 4 _ 3 = 12

Power We use double multiplication symbols 2 **4 = 16

Python Logical Operators

Logical operators are used to combine conditional statements:

OperatorDescriptionExample
andReturns True if both statements are true x < 5 and x < 10
orReturns True if one of the statements is truex < 5 or x < 4
notReverse the result, returns False if the result is truenot(x < 5 and x < 10)

Python Identity Operators

Identity operators are used to compare the objects, not if they are equal, but if they are actually the same object, with the same memory location:

Operator Description Example

isReturns True if both variables are the same objectx is y
is notReturns True if both variables are not the same objectx is not y

Python Membership Operators

Membership operators are used to test if a sequence is presented in an object: Operator Description Example

inReturns True if a sequence with the specified x in y value is present in the object
not inReturns True if a sequence with the specified x not in y value is not present in the object

Bitwise Operator

Bitwise operators are used to compare (binary) numbers:

| Operator | Name Description | | | -------- | ------------------ | ------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | | & | AND | Sets each bit to 1 if both bits are 1 | | or | OR | Sets each bit to 1 if one of two bits is 1 | | ^ | XOR | Sets each bit to 1 if only one of two bits is 1 | | ~ | NOT | Inverts all the bits | | << | Zero | fill left shift | Shift left by pushing zeros in from the right and let the leftmost bits fall off | | >> | Signed right shift | Shift right by pushing copies of the leftmost bit in from the left, and let the rightmost bits fall off |

Get the datatype of any variable

type(variable)

Mutable vs Immutable

  • 💡 mutable object can be changed after it’s created
    • 💡 Most Fundamental types in python are immutable:
      • 🔥 numbers
      • 🔥 String
      • 🔥 typles
  • 💡 immutable object Not be changed after it’s created
    • 💡 Mutable objects inclue :
      • 🔥 list,
      • 🔥 dictionaries
      • 🔥 other objects depending upon implementation

Random Number

#rand#random Python does not have a random() function to make a random number, but Python has a built-in module called random that can be used to make random numbers:

Generating a random value between 0 and 1

import random
print(random.random())

Generating a random integer betwee 1- 10

import random
print(random.randint(1,10))
import random
print(random.randrange(1, 10))
##There is a ton of random functions in the random class

choice() Function

Another useful function is choice(). This function takes in a list or tuple and returns a randomly chosen element:

from random import choice, choices
players = ['charles', 'martina', 'michael', 'florence', 'eli']
# return one single random choice
first_up = choice(players)
print(first_up)
# return two or more choices
print(choices(players, k=2))

Shuffle Function

Do you want to shuffle a list in a random way ? well shuffle is here fore you

from random import shuffle
m=[1,2,3,4,5,6]
shuffle(m) #this will shuffle the list in a random way
 

Random int

from random import randint
d=randint(1,20)
print(d) #print a random number between 1 and 20
 

User Input

This is just the function that allow user to imput text

input("Thext to display")

example of user input

name=input("Enter Your Name: ")
print(name)

Casting value from input

Input Always Accept anything that is passed to it as a string you must cast manually

	number=input("what is your favorite number : ")
	# number is the string version of the number inputed by the user You can cast if you want a specific type
  number=int(input("What is y: "))
  number=float(input("What is y: "))

List vs Set vs Tuple vs Dictionary

Difference between List ,Tuple, Set And Dictionary

There are one 4 built-in data types in Python used to store collections of data, list, Tuple, Set, and Dictionary, all with different qualities and usage.

List

Written in square brances [] (mutable) Lists are used to store multiple items in a single variable. Are just like dynamic sized arrays, declared in other languages (vector in C++ and ArrayList in Java). Lists need not be homogeneous always which makes it a most powerful tool in Python. (list are Mutable)

Declare and using a list :

list1=[] #empty list
 
list1 = ["apple", "banana", "cherry"] # list with data
 
list1 = ['daniel'] * 10 # ['daniel','daniel','daniel',....]
 
 thislist = ["apple", "banana", "cherry"] #length of a list
print(len(thislist))

Adding Elements to a list

#append#List

list1.append(3)
list1.append("is greater")
list1.append(1)

Adding at a specific position

#insert#List You can add something at a specific position in a list

#list.insert(position,what_you_want_to_insert)
list = ['a','b','c']
list.insert(0,'-') #added at the starting of th elist
 

Removing last element from a list

#pop#list

 #remove at the end of the list
 list1.pop()
#Remove at a specific index
list1.pop(2)

Remove item without knowing index

#remove#List

#remove the first occurence of the letter b
list.remove("b")

Remove all item

#clear#List

list.clear()
#remove all items of a list

Remove item using del

Sometimes you want to remove a range of things that is where del comes to help

list = [1,2,3,4,5,6]
del list[0:3]
print(list)

Remove first Occurence of a value

cars.remove("Volvo")

remove()

!!Note: The list’s remove() method only removes the first occurrence of the specified value.

Modifying values

Since a typle is mutable , something like this is allowed

list[0]="Anonymous"
print(l)

Sorting list elements

#sort#List funciton that sort items of a given list

list=[7,5,2,4,3,1]
# sorting th enumebrs
list.sort()
 
#sorting the numbers in revers
list.sort(reverse=True)
 
#sorted function
#we also have a sorted method, we simply pass it an iterable and it return
#sorted vallist to us
print(sorted(list))
 
print(sorted(list,reverse=True))

sort vs sorted

Unlike sort, sorted will return a new list to us instead of modifying our list

Sorting a tuple object

Sometimes you have a typle and you would like to sort them out

items = [
    ("product1", 10),
    ("product2", 1),
    ("product3", 8),
    ("product4", 30),
]
#define our method to sort out our data
def sort_item(item):
    return item[1]
 
items.sort(key=sort_item)
print(items)
 
################################################
#Using a lamda funciton we can rewrite the above like this
 
items.sort(key=lambda item: item[1])
 

List Comprehensions:

list comprehensions are a unique way of quickly creating a list in python. instead of using for loop along with .append() to creat a list , list comprehensions are a good alternative

#using a for loop
m='hello'
#we want to create  a list made of the m characters
lst=[]
for i in m:
	lst.append(i)
print(lst)
 
#there is a a much more better efficient way of doing this in python
m='hello'
lst=[i for i in m]
#This will do the same thing as the codes above

you can even go steps forward by performing some operations

lst=[number**2 for number in range(0,11)]
print(lst)
#ouput: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
 
# You can even go on and add if statement in the code above
lst=[number**2 for number in range(0,11) if x%2==0]

Let’s Say you have a list of Degrees in celsius and want to conver them to to fahrenheit

celsius=[0,10,20,34.5]
fahrenheit= [ (9/5)*temp + 32 for temp in celcius]
# that is the way we do it baby,
# yes you can even use the for loop as well
celcius=[0,10,20,34.5]
fahrenheit=[]
for deg in celcius:
	fahrenheit.appent( ((9/5)*deg+32) )

Using If else statement inside of a list comprehension

result= [x if x%2==0 else 'odd' for x in range(0,11)]

Nested for loop in a list comprehension

Some thing like this can also be used in a list comprehension

lst=[]
for x in [2,4,6]
	for y in [1,10,100]
		lst.append(x*y)
 
#Using List Comprehention It would look like this
lst=[x*y for x in [2,4,6] for y in [1,10,100]]

Tupple

#tupple#immutable Written in brackets () (a tupple is Immutable) A Tuple is a collection of Python objects separated by commas. In someways a tuple is similar to a list in terms of indexing, nested objects and repetition but a tuple is immutable unlike lists that are mutable.

tuple1=("computer","Printer","Tv",32)
#or
tuple = "computer","Printer","Tv",32

The cant with tupple

You can not add elements to a tuple cause it’s not mutable , it’s immutable no adding no removing , no nothing buddy

Count Occurences in A tuple elemnet t.count(‘thing’)

tup=("computer","Printer","computer","Tv",32)
print(tup.count("computer"))
#will return the occurences of the word computer in the list

Return the postition soomething from a list

tuple1=("computer","Printer","computer,"Tv",32)
print(tuple1)
 

Sets:

uses set keyword set([]) or set(()) A Set is an unordered collection data type that is iterable, mutable and has no duplicate elements. Python’s set represents the mathematical notion of a set.

#Declaring Emplty set
set1 = set()
 
#Declaring sets
set1 ={"we ","are ","Legion"}
	or
set1 =set(())
 
#Adding elements to a set
set1.add(3)
set1.add(43)
 
# Removing Elements in a set
set1.remove("we")

Sets Operations

You can get a union of sets

	print(first_set | second_set)

You can get the Intersection of sets

	print(first_set & second_set)

You can get the Difference of sets

	print(first_set - second_set)

You can get the semantic of sets

	print(first_set ^ second_set)>

Dictionary:

#dic#dictionary Dicationary in Python is an unordered collection of data values, used to store data values like a map, which unlike other Data Types that hold only single value as an element, Dictionary holds key : value pair. Key value is provided in the dictionary to make it more optimized.

# Declaring an empty Dictonary
dictionary1 = {}
d={"name": "ilugna GIsa Daniel","age":22,4:"Lucky number"}
d={
	"name": "ilugna GIsa Daniel"
	"age":22
	4:"Lucky number"
}

Adding Data to a dictionary

d["name"]= "Ilunga Gisa Daniel"
d["age"]= 22
d[4]="Lucky number"
print(d) #outputing the whole dictionary'
print(d[name]) #outputing specific item from a dictionary

Removing Items in a dictionary

There are several methods to remove items from a dictionary:

thisdict =	{
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
thisdict.pop("model")
#or
del thisdict["model"]
#or
	# emove Last item
thisdict.popitem() #remove the last item of a dictionary

Looping through a dictionary

When looping through a dictionary, the return value are the keys of the dictionary, but there are methods to return the values as well.

Looping through a sorted Dictionaty
for x in sorted(thisdict.keys()):
  print(x, y)

printing the keys of a dictionary

#keys

for x in thisdict:
	print(x)
#or
for x in thisdict.keys():
  print(x)
#the two codes above will print the keys of a dictionary
 

Printing the values .values()

for x in thisdict:
  print(thisdict[x])
 
for x in thisdict.values():
  print(x)
  #The Two codes above will print all the values from the dictionary

Loop through Keys and values .items()

for x, y in thisdict.items():
  print(x, y)

Copy one dictionary to another

first_dictionary={"name":"Ilunga Gisa Daniel"}
second_dictionary = first_dictionary.copy()

Using the dict function

x = dict(name = "John", age = 36, country = "Norway")
# The dict() function creates a dictionary.
second_dictionary = dict(firstd_dictionary)

Nesting Dictionary

myfamily = {
  "child1" : {
    "name" : "Emil",
    "year" : 2004
  },
  "child2" : {
    "name" : "Tobias",
    "year" : 2007
  },
  "child3" : {
    "name" : "Linus",
    "year" : 2011
  }
}

Creating a Dictionary form other other Dictionary

child1 = {
  "name" : "Emil",
  "year" : 2004
}
child2 = {
  "name" : "Tobias",
  "year" : 2007
}
child3 = {
  "name" : "Linus",
  "year" : 2011
}
 
myfamily = {
  "child1" : child1,
  "child2" : child2,
  "child3" : child3
}
print(myfamily)

Dictionary Methods

Python has a set of built-in methods that you can use on dictionaries.

MethodDescription
clear()Removes all the elements from the dictionary
copy()Returns a copy of the dictionary
fromkeys()Returns a dictionary with the specified keys and value
get()Returns the value of the specified key
items()Returns a list containing a tuple for each key value pair
keys()Returns a list containing the dictionary’s keys
pop()Removes the element with the specified key
popitem()Removes the last inserted key-value pair
setdefault()Returns the value of the specified key. If the key does not exist: insert the key, with the specified value
update()Updates the dictionary with the specified key-value pairs
values()Returns a list of all the values in the dictionary

Python data structure

#Stack#Queues

Stack Data structure

Strack which is simply a Lifo (Last In - First Our) We can use a list as our stack this way we can add elements remove and check

browsing_session = []
# Add elements to our stack
browsing_session.append(1)
browsing_session.append(2)
browsing_session.append(3)
browsing_session.append(4)
print(browsing_session)  # print our stack
# Remove last item from our stack
browsing_session.pop()
print(browsing_session)
# get the last item of our stack
browsing_session[-1]
# but first check if the stack is not empty
if not browsing_session:
    print("disable back button")

Queue Data structure

Queue unlike stack it has the FIFO behavior , and by this , the we mean First_in - First_our

Using a list for Queue

Technically we can use a list too for queue, and then we get to remove the front item and stuff, but the issue is that if we have 1000 items, then 999 items’s position are going to be shifted and you don’t want to do this to yous memory. That is why we use the deque

from collection import deque
queue=deque([])
# just like list it has the append method
queue.append(1)
queue.append(2)
queue.append(3)
queue.append(4)
 
# unlike lists we have a popleft method in the deque class
queue.popleft()
 
# like list we can check the queue to see if it is empty or not
if not queue:
	print("disable back button")
 
 

Conditions

If Condition

if True:
	print("yes it is true")
 
#Short Hand If Statement:
if a > b: print("a is greater than b")

And with Or operator on if condition

if a > b and c > a or c < d :
	pass
	#statement

Pass keybord

IF statemnt cannot be empty but if for some reasons you want to have empty if statemnt then you can use the pass keyboard

if b > a:
   pass

Conditionals

if condition:
	statement
 
elif condition:
	statement
 
elif condition:
	statement
	elif condition:
	statement
else:
	statement

Switch Statement

Python Does not have a case statement , so instead there is a way of working the thing around using a dictionary

    choices = {
        "one":"first",
        "two":"second",
        "three":"third",
        "four":"fourth",
        "five":"fith"
    }
 
    v="one"
    print(choices[v])
 
# This will work pretty fine , without any problem
# but if you try to input a value which is not in the dictionary , it will brin an error , and for that we can use a method called get from a dictionary
 
	v="seven"
	print(Choices.get(v,"Others"))
 
#this way , if it does not find it i will give us the other value, IT'S LIKE  a default value
 
 
#In python , the double : is used when you have a block of codes , example in if, function , loop etc, and the block of code is called suites In python

Conditional Expression: “true” if (condition) else “flase”

# Python has conditional Express as well aka ternary operation
a < b ? "Foo": "bar"  in python it's a bit different
"foo" if a < b else "bar" this is how it workd in python
a = 2
b = 330
print("A") if a > b else print("B")
Or you can even use the syntax with a variable
greater= a if a>=b else b
greater=("A is big") if a > b else ("equal") if a == b else ("B is big")

Printing On a Same Line(end=” “)

Print by default ends a line or starts a new line , if you desire another different behavior other than this one you can eaisly do it

for i in range(10)
	print(i, end=" ")

Example

a, b = 0, 1
 
if a<b:
   print('a ({}) is less than b ({})'.format(a,b))
else:
    print('a {} is not less than b{}'.format(a,b))
print("A is Greater than B
#You will notice the {}, they are kind of the place holder
#there the format method will plug things

##Loops Ther are two loops in python , for loop and while loop Python has two primitive loop commands:

  • 💡 while loops
  • 💡 for loops

While Loop

With the while loop we can execute a set of statements as long as a condition is true.

#Print i as long as i is less than 6:
i = 1
while i < 6:
  print(i)
  i += 1
Simple Fibb Example
a,b=0,1
while b< 150:
	print(b,end=' ')
	a,b = b, a + b

Break Statemnt

#break With the break statement we can stop the loop even if the while condition is true:

i = 1
while i < 6:
  print(i)
  if i == 3:
    break
  i += 1
Continue Statement

#continue With the continue statement we can stop the current iteration, and continue with the next:

i = 0
while i < 6:
  i += 1
  if i == 3:
    continue
  print(i)
else:
	print("the Condition is nolonger met")

For loop

Where you need to step through some data structure take one opbject at a time and loop thorugh it and do some other things while looping thorugh it

for loop syntax is:

for var in object:
	statement..
 

You can Itterate through almost anything in python

list=[1,3,4,2,5,6,3,6,73,7,4,7,3]
 
for i in list:
	print(i)
 
 
# If you just want to itteerat numer of predefined times , then no need to even use the i you can use _
for _ in list:
	print("hello")
 
 
#You can itterate through any object in python
#in the example below we have a list which has 4 tuples
mylist=[(1,2),(3,4),(5,6),(7,8)]
len(mylist) #will output 4
for items in mylist:
	print(items)
#will ouput all items
#but here is something you can even do better in python
#this is very common in python and it's called tuple unpacking
for (a,b) in myliset :
	print(a)
	print(b)
mylist=[(1,2,'a'),(3,4,'b'),(5,6,'c'),(7,8,'d')]
for (a,b,c) in myliset :
	print(a)
	print(b)
	print(c)
 
fh=open('dir.txt')
for line in fh.readlines():
      print(line,end=" ")
# We can iterate through Anything , a string , an integer , a list , dictionary , file object etc ...

Enumerate with for loop

#enumerate This will simply counts howmany times the loop has or is running Counting the number of times the loop has runned

text="Oh i am just text on the screen"
    for i, c in enumerate(text):
        print(i, c)

#####Example2:

  text="Oh i am just text on the screen"
    for i, c in enumerate(text):
       if c=="s": print("Index {} is an s".format(i))

Zip functions

#zip This one is kind of an inverse of an enumarate function what it does it packs everything together

mylist1=[1,2,3]
mylist2=['a','b','c']
for item in zip(mylist1,mylist2):
	print(item)
print item
#wil output data which is groupped together as a tuple
# (1, 'a')
# (2, 'b')
# (3, 'c')

In keyword

'x' in ['x','y','z']
or can be used like with strings
'x' in 'daxollyne'

check is a key is in a dictionary

mykey in dictionay_object

For Loop

A for loop is used for iterating over a sequence (that is either a list, a tuple, a dictionary or a set) This is less like the for keyword in other programming languages, and works more like an iterator method as found in other object-orientated programming languages.

fruits = ["apple", "banana", "cherry"]
for x in fruits:
  print(x)

The break Statement With the break statement we can stop the loop before it has looped through all the items:

#Exit the loop when x is "banana":
fruits = ["apple", "banana", "cherry"]
for x in fruits:
  print(x)
  if x == "banana":
    break

The continue statement

with the continue statemnt we can stop the current iteration of the loop and continue with the next:

fruits = ["apple", "banana", "cherry"]
for x in fruits:
  if x == "banana":
    continue
  print(x)

The range() Function( non inclusive)

To loop through a set of code a specified number of times, we can use the range() function, The range() function returns a sequence of numbers, starting from 0 by default, and increments by 1 (by default), and ends at a specified number.

With The range funtion it starts from 0 to the so it’s exclusive of 6 in the example below

for x in range(6): #from 0 to 5
  print(x)
 
for x in range(1,6): #from 1 to 5
	print(x)

Else in For Loop

The else keyword in a for loop specifies a block of code to be executed when the loop is finished:

for x in range(6):
  print(x)
else:
  print("Finally finished!")

else with for:

Note: The else block will NOT be executed if the loop is stopped by a break statement.


FUNCTIONS

A function is a block of code which only runs when it is called. You can pass data, known as parameters, into a function. A function can return data as a result.

Creating a Function; In Python a function is defined using the def keyword:

#creating the funtion
def function_name():
  print("Hello from a function")
#calling the function
function_name()

Arguments

Come on daniel , you know what arguments does in functions

def my_function(fname):
  print(fname + " Refsnes")
# calling the function
my_function("Emil")

Arguments are often shortened to args in Python documentations. Arbitrary Arguments, args (this is a tuple not a list) Function WIth Unlimited Arguments (*args) If the number of arguments is unknown, add a * before the parameter name:

def my_function(*kids):
  print("The youngest child is " + kids[2])
 
my_function("Emil", "Tobias", "Linus")
#OutPut will be: The youngest child is Linus
#beautiful python

Keyword Arguments:

You can also send arguments with the key = value syntax. This way the order of the arguments does not matter.

def my_function(child3, child2, child1):
  print("The youngest child is " + child3)
my_function(child1 = "Emil", child2 = "Tobias", child3 = "Linus")
 
# The phrase Keyword Arguments are often shortened to kwargs in Python documentations.
 
 

Arbitrary Keyword Arguments, **kwargs If the number of keyword arguments is unknown, add a double ** before the parameter name:

def my_function(**kid):
  print("His last name is " + kid["lname"])
my_function(fname = "Tobias", lname = "Refsnes")

Default Parameter Value

The following example shows how to use a default parameter value. If we call the function without argument, it uses the default value:

def my_function(country = "Norway"):
  print("I am from " + country)
 
my_function("Sweden")
my_function("India")
my_function()
my_function("Brazil")

Passing a List as an Argument

You can send any data types of argument to a function (string, number, list, dictionary etc.), and it will be treated as the same data type inside the function. E.g. if you send a List as an argument, it will still be a List when it reaches the function:

def my_function(food):
  for x in food:
    print(x)
 
fruits = ["apple", "banana", "cherry"]
 
my_function(fruits)

Return Values

To let a function return a value, use the return statement:

def my_function(x):
  return 5 * x
print(my_function(3))

You can use typle unpacking as well , when a function returns a tuple, you can as well asign em to variables

tup=('ilunga','gisa',23)
x,y,z=tup
fist,*midle,last=['the', 'adventure', 'of', 'radan', 'what', 'is', 'love']
#now first="the" last="love" and middle well you got it ...lol That's how cool list unpacking is
 

example

def empmonth(stock):
        monthEmployee=""
        max=0
        for name,hours in stock:
            if(hours >= max):
                max=hours
                monthEmployee=name
        return (monthEmployee,max)
 
    stock=[("Abby",200),("Billy",400),("Cassie",4300)]
 
 
    name, hours=empmonth(stock)
    print(f"Daniel : {name} worked {hours} hours")
 

Type Annotation with funcitons

You can set the return type for your variables or simply function, this is the things that a function returns.

def increment(numebr:int)

The pass Statement inside of a function

function definitions cannot be empty, but if you for some reason have a function definition with no content, put in the pass statement to avoid getting an error.

def myfunction():
  pass

Recursion

Python also accepts function recursion, which means a defined function can call itself.

Recursion is a common mathematical and programming concept. It means that a function calls itself. This has the benefit of meaning that you can loop through data to reach a result. Always be careful with recursion of course , no need to remind you this

Example
def tri_recursion(k):
  if(k > 0):
    result = k + tri_recursion(k - 1)
    print(result)
  else:
    result = 0
  return result
 
print("\n\nRecursion Example Results")
tri_recursion(6)

Python Lambda

before talking about lambda lets see the map function and the filter function

map function map(func,*iterables)

Make an iterator that computer the function using arguments from each of the iterables. tops when the shortest iterale is exhausted Let’s say we have a simple function that finds the square of a number

def sq(num):
	return num**2

If you want to require the square of a particular list of number then you will have to use for loops to loop while calling the sq func Another better way would be using the map function which takes some list and maps it to a function

my_num=[1,2,3,4,5]
map(sq,my_num) # will return an itterable of all the sqareroots of those numbers
 
def sq(n):
	return n**2
 
lst = [3,2,2,12,13,9,7]
m=map(sq,lst)
# print(list(m)) [9, 4, 4, 144, 169, 81, 49]
   #Or you can even return a list of the mapped values
list(map(sq,my_num))
# !! when calling your functions inside of the map function you don't call the function with the ()
 

Filter Function

filter function return an itterator yielding of the iterable for which when you pass in the item into the functoin it’s true

mynums=[1,2,3,4,5,6]
def check_even(num):
	return num%2==0
filter(check_even,mynums)
 
#this will return the even only aka true values only, so filter function shoud be used when you have a function that return true or false
 
#print(list(filter(check_even,mynums)))

Lambda function

A lambda function is a simple small anonymous one line function. A lambda function can take any number of arguments, but can only have one expression. lambda arguments : expression

x = lambda a : a + 10
print(x(5))
#or
#can Have Multiple Arguments
name=lambda name,age: "My Name is "+name+" With the age of "+ age
print(name("ilunga Gisa Daniel","32"))
 
 
x = lambda a, b, c : a + b + c
print(x(5, 6, 2))
 
 
Exercise

You have a list of product and their prices and you would like to return only the prices how do you do it?

items = [
 
    ("product1", 10),
 
    ("product2", 1),
 
    ("product3", 8),
 
    ("product4", 30),
 
]
 
prices = list(map(lambda item: item[1], items))
 
print(prices)

Why Use Lambda Functions?

The power of lambda is better shown when you use them as an anonymous function inside another function. Say you have a function definition that takes one argument, and that argument will be multiplied with an unknown number:

def myfunc(n):
  return lambda a : a * n
 
mydoubler = myfunc(2)
 
print(mydoubler(11))
mydoubler = myfunc(2)
mytripler = myfunc(3)
 
print(mydoubler(11))
print(mytripler(11))

Example two

def myfunc(n):
  return lambda a : a * n
 
mytripler = myfunc(3)
 
print(mytripler(11))

Eample three

def myfunc(n):
  return lambda a : a * n
mydoubler = myfunc(2)
mytripler = myfunc(3)
 
print(mydoubler(11))
print(mytripler(11))

Using Lambda In Conjunction with map

mynum=[1,2,3,4,5,6,7,8]
list(map(lambda num:num**2,mynum)

Using filter with lambda

mynum=[1,2,3,4,5,6,7,8]
list(filter(lambda num: num%2==0,mynum)

Let’s Imagine you want to grab the first character of a string

names=['Ilunga','Gisa','Daniel']
list(map(lambda name: name[0], names))

Global Keyword

Used To gain Access to Local Variables
a=54
def func() :
    global a
    print(f' Value of A is {a}')
    a=242
    print(f' New Value of A is {a}')
 
func()
print(a)

Python Arrays

Note: Python does not have built-in support for Arrays, but Python Lists can be used instead. Arrays Note: This page shows you how to use LISTS as ARRAYS, however, to work with arrays in Python you will have to import a library, like the NumPy library.

Arrays are used to store multiple values in one single variable:

cars = ["Ford", "Volvo", "BMW"]
cars.insert("FideNemini")
#Removing Array Elements
#You can use the pop() method to remove an element from the array.
cars.pop
 
# Delete the second element of the cars array:
cars.pop(1)
 
#You can alsgo use the remove() method to remove an element from the array.
 
#Example
#Delete the element that has the value "Volvo":
cars.remove("Volvo")
 
#Note: The list's remove() method only removes the first occurrence of the specified value.
Array Methods
Python has a set of built-in methods that you can use on lists/arrays.
 

Using Arrays

from array import array
numbers= array("i",[1,2,3]) # create an array
 
numbers.append(5) # add to the end of a given list
 
numbers.remove(2) #remove numbers from a given list
 
numbers[2]= 8 # Change value from a specific position
numbers.appent(3.4) #won't work because our array type if of integer.
Array types
Method Description
append()Adds an element at the end of the list
----------------------------------------------------------------------------------------
clear()Removes all the elements from the list
copy()Returns a copy of the list
count()Returns the number of elements with the specified value
extend()Add the elements of a list (or any iterable), to the end of the current list
index()Returns the index of the first element with the specified value
insert(pos,item) Adds an element at the specified position
pop()Removes the element at the specified position
remove()Removes the first item with the specified value
reverse()Reverses the order of the list
sort()Sorts the list
With arrays, it is a string of one character that defines the type of element in you list.
‘b’signed charint1
‘B’    unsigned char  int1
‘u’    wchar_t Unicodecharacter  2
‘h’    signed short    int2
‘H’    unsigned short  int2
‘i’    signed int  int2
‘I’    unsigned int    int2
‘l’    signed longint4
‘L’    unsigned long  int4
‘q’    signed long long    int8
‘Q’unsigned long longint8
‘f’floatfloat4
‘d’doublefloat8

ENDS WITH FUNCTION , obj.endwith(“txt”)

st="ilunga gisa daniel"
print(st.endswith("hiel"))
#will return either true or false depending on if a file end in txt or not

Creating Main Method In Python

Well, Just the way The Main Method Gets Executed when you Run the Program In pythong is is the same Concept Will allow us to call functions defined ofter they have been called

def main():
	print("This is ht syntax.py File")
egg() #function Call Before Declaration
 
def egg():
	print("I don't Like Eating Eggs ")

#Runs the main function everytime when the program runs

if __name__== "__main__": main() # Used to run the funtion when it's executed

Regular Expressions in python

Regular expressions are a very powerful method of matching patters in text , Actually as small language in itself , regexes can be very simple or very complex implemented in python the “re” module should be imported

Searching WIth Regular Expression (re.search)

fh=open("dir.txt")
    for line in fh:
        if re.search('(len|neverm)ore',line):
            print(line,end="")
#this will try to match everything with lenore or nevermore
 
#since Everything is an object in python , here is how we can get simply words with a specific pattern
 
fh=open('raven.txt')
for line in fh:
	match=re.search('(len|neverm)ore',line)
	if match:
		print(match.group())
 
Search And Replace using regular epression

Exception Handling In python

Exceptions are the key method of handling errors in python try something , then catch an exception with except

try:
	expression you want to try
except errorYouWantToCatch:
	what to handle
else:
	print("this will execute only if you don't have an exception")
Example
try:
 
    age = int(input("Age: "))
 
except ValueError:
 
    print("You did not enter a valid age.")
 
except ZeroDivisionError:
 
    print("Your age can not be zero.")
 
else:
 
    print("this will execute only if you don't have an exception")
finally:
	print("will execute whether we have an exception or not.")
# The above exception can be rewritten using a typle
except (ValueError,ZeroDivisionError):
	pass
    try:
        file=open("dr.txt")
    except: #This will catch any error
        print("Could not open the file. try again)
    else:
        for line in file: print(line.strip())

You May raise your own exceptions with Raise as well Mean you can try to catch a particular error in your codes

    try:
        file=open("dr.txt")
    except IOError as e: #will look for this particulat error
 
        print("Could not open the file",e)
        #e is the error returned in python
    else:
        for line in file: print(line.strip())
 
 
#We can Also Remove The else and so tomething like this
 
    try:
        file=open("dr.txt")
        for line in file: print(line.strip())
    except IOError as e:
        print("Could not open the file",e)

Raising Our Own Exceptions

  st="ilunga gisa daniel"
    print(st.endswith("hiel"))
    def readfile(filename):
        if filename.endwith(".txt"):
            file=open(filename)
            return file.readlines()
        else: raise ValueError("Filename Must End with .txt")
 
    try:
        for line in readfile("dr.txt"): print(line.strip())
    except IOError as e:
        print("file was not ")
    except ValueError as es:
        print("Bad FileName,",es)
 

Raising our own exception is costy

When writting our own funciton we should preffer not raising our own exception caus it comes with a cost.

cost="""
st="ilunga gisa daniel"
    print(st.endswith("hiel"))
    def readfile(filename):
        if filename.endwith(".txt"):
            file=open(filename)
            return file.readlines()
        else: raise ValueError("Filename Must End with .txt")
 
    try:
        for line in readfile("dr.txt"): print(line.strip())
    except IOError as e:
        print("file was not ")
    except ValueError as es:
        print("Bad FileName,",es)
"""

yield

This is a kind of return which can be used iside of a loop to return everything while the loop is still looping

Creating Generators in Python

#generator Generators are just iterables like list, but for each itteration they generate a new value instead of storing all values in memory. The range funciton works well , but the problem arrises when you want to loop over a range of 1Billion this is too much and you certainly don’t want to store this in the memory.

from sys import getsizeof
# Bellow we are using a list comprehenssion to generate our numbers
value = [x * 2 for x in range(1000)] #takes out way too much memory
print("List: ",getsizeof(value))
 
value = (x*2 for x in range(1000)) #takes a specific memory size only
print("Generator: ", getsizeof(value))
 

When to use generator

When you have a very huge dataset you should use generators instead of lists , caus generators are very kind with memory unlike lists.

Creating a Generator in python
#Creating an inclusive range
for i in incrange(1,10,3,2):
       print(i)
#range which is inclusive
def incrange(*args):
	numarg=len(args)
	if numarg<1: raise TypeError("You Must Provide a ragne")
	elif numarg==1:
		st=0
		stp=args[0]
		step=1
	elif numarg==2:
		st=args[0]
		stp=args[1]
		step=1
	elif numarg==3:
		st=args[0]
		stp=args[1]
		step=args[2]
	else :
		raise TypeError("Enter A valid Range, \
			Expect 3 arguments and God {}".format(numarg))
 
   i=st
   while i <= stp:
       yield i
       i+=stepA much

Python Modules And Packages.

#module#files When building a large applicaiton , we don’t want our codes in one snlge ugly file, right ? what we want it to device our codes in chunks, in separate files. and that is when Modules comes to the rescue.

sales.py

def calc_tax():
    pass
def calc_shipping():
    pass

app.py

from sales import calc_tax,calc_shipping
calc_shipping()
#Alternatively we can import the entire module instead
import sales
sales.calc_tax()

What if the packages in question is in a sub directory for the sake of a better organization

#package

ecommerce/sales.py

def calc_tax():
    pass
def calc_shipping():
    pass

ecommerce/__init__.py

We must add a file in the sub directory aka our package called __init__

app.py

from ecommerce.sales import calc_tax,calc_shipping
calc_shipping()
#Alternatively we can import the entire module instead

OBJECT ORIENTED PROGRAMMING LANGUAGE IN PYTHON

Python Classes/Objects Python is an object oriented programming language. Almost everything in Python is an object, with its properties and methods. A Class is like an object constructor, or a “blueprint” for creating objects, aka how you make objects

Class vs Object

Class: Blueprint for creating new objects Objects: Instance of a class

Create a Class

To create a class, use the keyword class:

class MyClass:
  x = 5

Create Object

An Object is an instance of a class , when you create an object it is kinda encapsulated , it have its own feature and attributes . Now we can use the class named MyClass to create objects: also called intentiation

p1 = MyClass()
print(p1.x)

Exampe Two

 
class Duck:
    def quack(self):
        print("Quaaack")
    def walk(self):
        print("Walk Like a Duck")
def main():
    donald = Duck()
    donald.quack()
    donald.walk()
 
if __name__== "__main__": main() # Used to run the funtion when it's executed

Self keyword

-Note that the function inside of a class has a self argument as a first parameter -Function are simply called method inside of a class

Constructor, The __init__() Function

#constructor#init Constructors is a special method that get called when we create a new instance of our class. The examples above are classes and objects in their simplest form, and are not really useful in real life applications.

To understand the meaning of classes we have to understand the built-in init() function.

All classes have a function called init(), which is always executed when the class is being initiated.(Also Called A contructor)

Use the init() function to assign values to object properties, or other operations that are necessary to do when the object is being created:

Example

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age
 
p1 = Person("John", 36)
#what you did here is instanciating the class with variables already
 
print(p1.name)
print(p1.age)

The Init method

Note: The init() function is called automatically every time the class is being used to create a new object.

When you have attributes that need to be same through out the instance of the class, you don’t need to add the self keyword

class Person:
	race="Human"
	def __init__(self,skincolor,maxage,continent)
		self.skincolor=skincolor
		...
 
african=Person("black",120,Africa)

The dot notation to members of a calss

when using the class object acttribute such as race in the example above , you can reverence it in to ways , self.race or Person.race(using the class name)

 
class Duck:
    def __init__(self,value):
        self._value=value
    def quack(self):
        print("Quaaack !",self._value)
    def walk(self):
        print("Walk Like a {} Duck".format(self._value))
def main():
    donald = Duck("Donald")
    donald.walk()
 

The self Parameter:

#slef The self parameter is a reference to the current instance of the class, and is used to access variables that belongs to the class.

Tip

It does not have to be named self , you can call it whatever you like, but it has to be the first parameter of any function in the class:

Member of a class vs Member of an instance of a class

A member of a class is an attribute that belongs to the class thus all instance have access to it. A member of an instance of a class is created and the instances have access to it.

class Point:
 
    member_of_a_class = "I am a member"
    def __init__(self, instance):
        self.instance = instance
        self.instance_two = "Second Member of an instance of a class"
 
point = Point("Member of an instance of a class")
print(point.member_of_a_class)
print(point.instance)
print(point.instance_two)

Class Method vs Instance Method

We have the same concept of member of a class with methods too. if we want methods that will be common throught out all the classes then we can use the member of a class instead.

class Point:
    @classmethod
    def zero(cls): # class lever method, accessible to all instances and class.
        return cls(0, 0)
    # The above code is the same as calling
        # return Point(0,0)
    def __init__(self, x, y):
        self.x = x
        self.y = y
 
	def draw(self): #instance  level method, accessible after instantiation only.
        print(f"Point ({self.x}, {self.y})")
 
point = Point.zero()
# point = Point(0,0) Same as the code above

Setters and getters

Unless There is an overiding reason aka you really have to , the you can access varaibles iside of a function without methods Otherwise , what you wanna do is have methods which access variables inside of a function

class Duck:
    def __init__(self,value="white"):
        self._color=value
    def setColor(self,color):
        self._color=color
    def getColor(self):
        print("The Actual Color is: {} ".format(self._color))
def main():
    donald = Duck("blue")
 
    donald.getColor()
    donald.setColor("Pink")
    donald.getColor()
#Now you have A better Control Over Your Codes

Check if an object is an instance of a class

#instance#object#class

class Point:
    def draw(self):
        print("Draw")
point=Point()
print(isinstance(point,Point))

Using A Dictionary when Creating A class For a better Control

class Duck:
    def __init__(self,**kwargs):
   	 	#setting up the kwargs
        self._color=kwargs.get("color","white")
.....
#Instanciatinon will look like this
donald=Duck(color="blue")

We Can try to make One which scale pretty well

#scalability#scale

class Duck:
    def __init__(self,**kwargs): #will use a dictionary
        self.variables=kwargs
    def setColor(self,color):
        self.variables['color']=color
    def getColor(self):
       return self.variables.get('color',None)
def main():
    donald = Duck()
    donald.setColor(color="pink") #setting using a dictionary
    print(donald.getColor())

Now let’s Get Into Some Power And Scale Our app even More

class Duck:
    def __init__(self,**kwargs):
        self.variables=kwargs
    def set_variable(self,k,v ):
        self.variables[k]=v
    def get_varibale(self,v):
       return self.variables.get(v,None)
def main():
    donald = Duck(feet=34,color="blue")
    donald.set_variable("name","Donald The Duck")
    print(donald.get_varibale("name"))
  • Store Object Data in Dictionaries ,
  • Allow Lots of Flexibility
  • Allow to use Lots of Flags attributes
  • Very Easily set them and get them We Did set out setters and getter to access the dictionary

Inheritance

#inheriting#parent#child In oop , Inheritance is when one class inherits the properties of anoother class, the class being inherite from is called a base class or parent class , and the one inheriting is called a child class

class Person:
    race="Human"
    def __init__(self):
        print("I am A person")
 
class Dog(Person): #inheriting all attributes of person
     def __init__(self):
        Person.__init__(self) #calling the constructor of person
        print("I am A dog")
 

All Inherits from a base class called object

All classes that we create inherits from a class classed Object, even if we do not specify that, it still inherits from taht class.

Method Overriding

Method Overriding means to replace or extending a method defined in the base class

Method Overriding.

When you define a method in the parent class and you give it some attributes , then in the child class define the same method name , it will simply override everything from the parent class , and if you don’t want this effect , what you can do is to use the super keyword to merg all the two classes

class Animal:
    def talk(self) : print("I have something to say")
    def walk(self) : print("hey i am walking here ")
    def clothes(self): print("i have nice clothese")
 
class Duck(Animal):
    def quack(self):
        print("Quaack Quaack!")
#overide the walk from the parent class
    def walk(self):
#The line below prevents the overiding of the method
        super().walk()
        print("Walks like a duck")
 
class Dog(Animal):
	def clothese(self):
		print("I have brown and white fur")
 
def main():
    donald = Duck()
    donald.quack()
    donald.walk()
#now we can access those methods from the child class ,
#cause there is inheritance of course
    donald.clothes()
 
	fido=Dog()
	fido.walk()
	fido.clothese()
	print(isinstance(donald,Duck)) # True
	print(isinstance(donald,Animal))# True
	print(isinstance(donald,object))# True
	print(issubclass(Duck,Animal))# True
	print(issubclass(Duck,object))# True

Abstract Base Class

An abstract base class like a half baked cookie, not ready to be eated, it’s purpose is to provide some common codes to it’s derivatives.

from abc import ABC, abstractmethod
# Creating a custom exception
class InvalidOperationError(Exception):
    pass
 
class Stream(ABC): # we can't create an object of our abstract class
    def __init__(self):
        self.opend = False
 
    def open(self):
        if self.opend:
            raise InvalidOperationError("Stream Is already open")
        self.opened = True
 
    def close(self):
        if not self.opend:
            raise InvalidOperationError("Stream Is already Closed")
        self.opened = False
	@abstractmethod
	def read(self): #abstract method, this means that every subclass should implement this
		pass
class FileStrea(Stream):
    def read(self):
        print("Reading Data from a file.")
       
class NetworkStrea(Stream):
    def read(self):
        print("Reading Data from a Network.")

POLYMORPHISM

The practice of using one obejct of one particular class as if it was another object of another class. The looseness of python syntax makes it even powerfull when it comes to class reusing

class Duck:
   def quack(self):
       print("Quaack Quaack!")
   def walk(self):
       print("Walks like a duck")
   def bark(self):
       print("the duck cannot Bark")
   def fur(self):
       print("the Duck has Feather")
class Dog:
   def bark(self):
       print("Woof!")
   def fur(self):
       print("The Dog has brown and white furr")
 
   def walk(self):
       print("Walks like a Dog")
   def quack(self):
       print("the dog cannot Quack")
def main():
   donald = Duck()
   fido   = Dog()
 
   for o in (donald, fido ) :
       o.quack()
       o.walk()
       o.bark()
       o.fur()

Something like this :

def in_the_forest(cat):
	cat.bark()
	cat.fur()
 
# You can Call your method with your Object as if it was magic
 
dog = Dog()
in_the_forest(dog)
#works very fine

!! Python is good At this because the object in python don’t care what the name of the class is when you use an obejct , python is what we call loose type , they call it duck typing Everythin is an object and it’s loosely typed ,

Extending a builtin class in python

We sometimes want to add extrathings to default built in types such as string, let’s say we want to add a duplicate funcitonality to the string class

class Text(str):
 
    def duplicate(self):
 
        return self+self
 
  class TrackableList(list):
 
    def append(self, obj):
 
        print("Appended to a list:")
 
        super().append(obj)
 
 
text = Text("Python")
# we have access to default string methods
print(text.count('t'))
print(text.isnumeric())
 
#we have access to our custom extended method.
print(text.duplicate())

Magic Method or Special Method:

#magic#__ https://rszalski.github.io/magicmethods/

Magic methods are methods that have two underscores at the starting and ending of their names and they are called automatically depending on how we use our object and classes.

  • 💡 str : goes with the string
  • 💡 len : Goes with the length
  • 💡 del : Delete a variable in the memory
Examples of Magic Methods to represent our classes

__str__(self) Defines behavior for when str() is called on an instance of your class. __repr__(self) Defines behavior for when repr() is called on an instance of your class. The major difference between str() and repr() is intended audience. repr() is intended to produce output that is mostly machine-readable (in many cases, it could be valid Python code even), whereas str() is intended to be human-readable. __unicode__(self) Defines behavior for when unicode() is called on an instance of your class. unicode() is like str(), but it returns a unicode string. Be wary: if a client calls str() on an instance of your class and you’ve only defined __unicode__(), it won’t work. You should always try to define __str__() as well in case someone doesn’t have the luxury of using unicode. __format__(self, formatstr) Defines behavior for when an instance of your class is used in new-style string formatting. For instance, "Hello, {0:abc}!".format(a) would lead to the call a.__format__("abc"). This can be useful for defining your own numerical or string types that you might like to give special formatting options. __hash__(self) Defines behavior for when hash() is called on an instance of your class. It has to return an integer, and its result is used for quick key comparison in dictionaries. Note that this usually entails implementing __eq__ as well. Live by the following rule: a == b implies hash(a) == hash(b). __nonzero__(self) Defines behavior for when bool() is called on an instance of your class. Should return True or False, depending on whether you would want to consider the instance to be True or False. __dir__(self) Defines behavior for when dir() is called on an instance of your class. This method should return a list of attributes for the user. Typically, implementing __dir__ is unnecessary, but it can be vitally important for interactive use of your classes if you redefine __getattr__ or __getattribute__ (which you will see in the next section) or are otherwise dynamically generating attributes. __sizeof__(self) Defines behavior for when sys.getsizeof() is called on an instance of your class. This should return the size of your object, in bytes. This is generally more useful for Python classes implemented in C extensions, but it helps to be aware of it. when you create an calss and you simply try to print it out then it will print the memory location of the class you can use the special class str which will be applied when a print function is applied to it

#!/usr/bin/python3.8]
 
class Book:
 
    def __init__(self,title,author,page):
        self.title=title
        self.author=author
        self.page=page

because of the str method , our class , will be able to print out some data even When it is directly called with the print function

    def __str__(self):
        return f"{self.title} by {self.author}
    def __len__(self):
    	return self.page
def main():
   p=Person("African")
   print(p)
   print(len(p))
if __name__== "__main__": main()

Magic Method for comparing objects

#magic#equality#eq#ne

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
 
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
 
    def __gt__(self, other):
        return self.x > other.x and self.y > other.y
       
point = Point(1, 2)
point2 = Point(1, 2)
print(point == point2) #False
point.x = 20
point.y = 20
print(point > point2) #True

We also have arithmetic methods and other more . all the magic methods can be found on the link bellow https://rszalski.github.io/magicmethods/

Making our custom container

class TagCloud:
 
    def __init__(self):
        self.__tags = {}
       
    def add(self, tag):
        # Add a tag if it is not already present
        self.__tags[tag.lower()] = self.__tags.get(tag.lower(), 0) + 1
        # same as
	        # if not self.tags[tag.lower()]:
	        #     self.tags[tag.lower()] = 1
	        # else:
	        #     self.tags[tag.lower()] += 1
 
    def __getitem__(self, tag):
        return self.__tags.get(tag.lower(), 0)
 
    def __setitem__(self, tag, count):
        self.__tags[tag.lower()] = count
 
    def __len__(self):
        return len(self.__tags)
 
    def __iter__(self):
        return iter(self.__tags)
 
cloud = TagCloud()
 
cloud.add("PyThon")
 
cloud.add("pYthon")
 
cloud.add("Python")
 
cloud.add("Django")
 
cloud.add("Java")
 
print(cloud.__tags)
# Because of the __getitem__ magic methods that is why we can achieve this.
print(cloud['python'])
 
# We can do this because of the set Item magic method.
cloud['python'] = 34
print(cloud.__tags)
 
# We can do this because of the __len__ magic methods
print("Length: ", len(cloud))
 
# because of the iter method
for count, tag in enumerate(cloud):
    print(f"Iter {count} : ", tag)

Properties in python

#property#setter#getter There are times we want to have control over attribues of a class. Let’s say we have a product class and in the constructor we set the class attribute.

class Product:
    def __init__(self, price):
        self.price = price
# With this implementation, we can create an object and give it a negative price and that is really okay for python , but for us, not really good.
proudut=Product(-50)

How can i prevent negative value ?

First Solution

Make the field private and define two methods for getting and setting the value of that attribute.

class Product:
	def __init__(self, price):
	    self.set_price(price)
    def get_price(self):
        return self.__price
 
    def set_price(self, value):
        if value < 0:
            raise ValueError("Price cannot be negative.")
        self.__price = value
 
product = Product(-10)
print(product.get_price())

Issue with the implementation( Implementation is not python)

The Implementation aboce works, but is very noisy and not considered pythonic That is an implementation that someone from a java world learning python would create .

Second solution

Using property we can achieve the same result using a python way. Using A property: Aproperty is an object that sits in front of an attribute and allow us to set or get the value of that attribute.

 
 
class Product:
 
    def __init__(self, price):
 
        self.set_price(price)
 
 
 
    def get_price(self):
 
        return self.__price
 
 
 
    def set_price(self, value):
 
        if value < 0:
 
            raise ValueError("Price cannot be negative.")
 
        self.__price = value
	#Creating a property object.
    price = property(get_price, set_price)
 
 
 
 
product = Product(10)
print(product.price)
product.price = -34
# how come we can still access this method ?
print(product.get_price())

The Issues with the above approach

The above approach works but the issue is that it is very noisy. the two methods we wrote(get, set price) are still accessible and it is poluting the interface of our object.

Thirt And Best SOlution

Using Decorators, aka the pythonic way.

class Product:
 
    def __init__(self, price):
 
        self.price = price
 
 
 
    @property
 
    def price(self):
 
        return self.__price
 
 
 
    @price.setter
 
    def price(self, value):
 
        if value < 0:
 
            raise ValueError("Price cannot be negative.")
 
        self.__price = value
 
 
 
 
product = Product(10)
 
print(product.price)

The pitonic way

The implementation above is how we do it the pythonic way. the code is clean and consistent

Read only properties

Sometimes we just want to create a read only property, therefore we are not obliged to create the setter method( means we don’t need the @property.setter decorator)

Python Generator

A generator Object is an object which can be used in a context of an iterable , ex: for loop

Example

Example , of Creating a inclusing range #By havind a yield inside of our Class and a **iter** , it makes it an iterable

#inclusive Range
class Irange:
    def __init__(self,*args):
        ars=args
        numargs=len(ars)
 
        if numargs<1: raise TypeError("Myst Have At lest one parameter")
        elif numargs==1:
            self.start=0
            self.end=ars[0]
            self.step=1
        elif numargs==2:
            (self.start,self.end)=ars
            self.step=1
        elif numargs==3:
            (self.start,self.end,self.step)=ars
        else: raise TypeError("Too Many Arguments ")
 
    def __iter__(self):
        i=self.start
        while i <= self.end:
            yield i
            i+=self.step
# Calling our generator
Starts on 1-20 , same thing as range(21)
 
gen=Irange(20)
for i in gen: print(i,end="")

Decorator

Decorator are special function that return other functions And they are used to modify the way a fucntion works There is a special syntax of using a decorator in python

 
class Duck:
    def __init__(self, **kwargs):
        self.properties=kwargs
    def walk(self):
        print("Walk Like a Duck")
 
    def get_properties(self):
        return self.properties
    def get_property(self,key):
        return self.properties.get(key,None)
#the @property,setter,deleter , makes it an accessor
    @property
    def color(self):
        return self.properties.get('color',None)
    @color.setter
    def color(self,c):
        self.properties['color']=c
    @color.deleter
    def color(self):
        del self.properties['color']
 
def main():
    donald = Duck()
    donald.color='Pink'
    print(donald.color)

Now it went through a control of an object , since we used the setter and deleter things , and see the way we access it in , completely defferent of how we would access it normally

Understand String Objects

A bit different with other Programming language , for it’s “everything_is_an_object”

#-A variable , is just a refference to an object ,we can operate on a string
 
s="Oh i am text on screen"
#uppercase
s.upper()
 
#you can also do something like this , and it will work as well
"Oh i am tet on screen".upper()
 
 
#Lowercase
s.lower()
 
#Swapcase (oposite)
s.swapcase()
 
#find (return position)
s.find('is')
 
#replace ("what_to_replace", "replace_it_with")
s.replace('oh', "Hello")
 
#strip (strip a particular character and the beginning and end )
	(by Default what it strip is white spaces )
s.strip()
s.rstrip() #remove spaces to the end of a string
 
strip(string) : will remove the string you specify eg: \n new lines
 
 
#isalnum() (check if it's only has alpha numeric , returns a boolean)
#if it contains spaces then it will not really work
s.isalnum()
 
#isalpha (check if it only contain alpha characters a-z)
 
 
#isdigit() Check if it is a digit

Format Method

"this is just {} and that is just {}".format(b,a)
 
#You can presize places for em to go instead
 
"this is just {1} and that is just {0} and {1}".format(b,a)
 
"This is {dan} and that is {bob}".format(bob=a, dan=b)
 
#you can Put them in a dictionary as well
 
d=dict(dan=23, bob=43)
"this is {dan} and that is {bob}".format(**d)
#use the ** to refer to the dictionary

Splitting and Joining Strings

#split#join

s="this is a string of words"
 
#s.split() will split the string
['this','is','a','string','of','word']
 
#s.split(i)
 
You can split it to some characters as well
 
#join() (operate on the token which is gonna be used to join things back together
 
','.join(words)
 
 
 
#s.center() center a string
s="this is a tring"
new=s.center(80)
 

Containers In python

#tuples and lists are the basic array types in python , tuples are immutable and list are mutable , tuples are created with a comma operator
 
tup=1,2,3,4,5,6 #(it is the camma that makes the tuple )
 
tup[0] :Get the first element
 len(tup) :Get the length of the tuple
 min(tup) : Get the minimum Value of the tuple
 maz(tup) : Get the max Value of the tuple
 
#tupel with one element
 
t=(1)

Lists

# to Created a list you use []
 
lst=[1,2,3,4,5,6,7]
 
 
# list[0] :Get the first element
# len(list) :Get the length of the list
# min(list) : Get the minimum Value of the tuple
# max(list) : Get the max Value of the tuple
 
#the different is that you can now change things

Operations On tuple and list

t=type(range(35))
 
# 10 in t : check if a value is in a tuple
 
# 40 not in t : not in the list
 
# t[10]: find an element at a particulat position
 
# for i in t : print(i) : cuse a lists and typles are itterable
 
# List Operations
-list.index(34): find the index or position of this entry in a list
 
-list.append(31): add at the end an object
 
-list.extend(2,3,5,range(20)) : append many values
 
-list.insert(0,32): insert a 32 at the beginnig
 
-list.remove(12) : remove a specific element inside of a list
 
-del list[12]: remove an item at a particular index
 
-list.pop(): return the last value and removes it from the list
 
-list.pop(0): remove from the beginning
 
 

Dictionary:

Dicationary in Python is an unordered collection of data values, used to store data values like a map, which unlike other Data Types that hold only single value as an element, Dictionary holds key:value pair. Key value is provided in the dictionary to make it more optimized.

Declaring an empty Dictonary

Dictionary creation using the constructor way:

d= dict(one=1,two=2,three=3)
 
#using the notation way
 
dictionary1 = {}
 
d={"name": "ilugna GIsa Daniel","age":22,4:"Lucky number"}
 
d={
	"name": "ilugna GIsa Daniel"
	"age":22
	4:"Lucky number"
	}
 

Adding Data to a dictionary

d["name"]= "Ilunga Gisa Daniel"
d["age"]= 22
d[4]="Lucky number"
print(d) #outputing the whole dictionary
print(d[name]) #outputing specific item from a dictionary
 

Removing Items in a dictionary

There are several methods to remove items from a dictionary:

thisdict =	{
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
thisdict.pop("model")
or
del thisdict["model"]
or

Remove Last item

thisdict.popitem() #remove the last item of a dictionary

Looping through a dictionary

When looping through a dictionary, the return value are the keys of the dictionary, but there are methods to return the values as well.

Looping through a sorted Dictionaty

for x in sorted(thisdict.keys()):
  print(x, y)

printing the keys .keys()

for  x in thisdict:
	print(x)
 
#or
 
for x in thisdict.keys():
  print(x)
#the two codes above will print the keys of a dictionary

Printing the values .values()

for x in thisdict:
  print(thisdict[x])
 
for x in thisdict.values():
  print(x)
 
#The Two codes above will print all the values from the dictionary
 
 

Loop through Keys and values .items()

for x, y in thisdict.items():
  print(x, y)

Copy one dictionary to another

#Using the copy function
second_dictionary = first_dictionary.copy()
 
#Using the dict function
second_dictionary = dict(firstd_dictionary)
 

Nesting Dictionary

myfamily = {
  "child1" : {
    "name" : "Emil",
    "year" : 2004
  },
  "child2" : {
    "name" : "Tobias",
    "year" : 2007
  },
  "child3" : {
    "name" : "Linus",
    "year" : 2011
  }
}

Creating a Dictionary form other other Dictionary

child1 = {
  "name" : "Emil",
  "year" : 2004
}
child2 = {
  "name" : "Tobias",
  "year" : 2007
}
child3 = {
  "name" : "Linus",
  "year" : 2011
}
 
myfamily = {
  "child1" : child1,
  "child2" : child2,
  "child3" : child3
}

Dictionary Methods

Python has a set of built-in methods that you can use on dictionaries. Method Description

clear()Removes all the elements from the dictionary
copy()Returns a copy of the dictionary
fromkeys()Returns a dictionary with the specified keys and value
get()Returns the value of the specified key
items()Returns a list containing a tuple for each key value pair
keys()Returns a list containing the dictionary’s keys
pop()Removes the element with the specified key
popitem()Removes the last inserted key-value pair
setdefault()Returns the value of the specified key. If the key does not exist: insert the key, with the specified value
update()Updates the dictionary with the specified key-value pairs
values()Returns a list of all the values in the dictionary

Bytes and Bytearrays

They are like types and list , instead of containing arbitrary objects , bytes and bytearray contain bytes , 8 bit words of data An 8Bit word of data can hold up to 256 different values and this sometimes a very convenient thing

In particular it is used to converting strings

PYTHON CrashCourse Wroking With Files

#files#path

Path In Python

Before working with files we need to learn how to work with path

from pathlib import Path
 
# Current working directory in python
 
print("Working Dir: ", Path.cwd())
 
 
 
# we can compine two paths together
 
# Path() / "ecommerce" / "id.png"
 
 
 
path = Path("FizzBuzz/sample.txt")
 
 
 
 
# We can get the home directory of the current user
 
print(Path.home())
 
 
 
# Check if a path exists
 
print(path.exists())
 
# check if a path is a file
 
print(path.is_file())
 
# Check if a path is a directory
 
print(path.is_dir())
 
# Extract component which will return the file name in our example above
 
print(path.name)  # sample.txt
 
#  Returns the file name without the extension
 
print(path.stem)  # sample
 
# path.suffix  will give you the extension
 
print(path.suffix)  # .txt
 
# Get the parent of this path
 
print(path.parent)  # Fizzbuzz
 
 
 
# Create a path based on another path
 
path = path.with_name("file.txt")
 
print(path)  # Fizzbuzz/file.txt is our new path
 
 
 
# we are simply renaming the extention.
 
path = path.with_suffix(".py")
 
print(path)  # Fizzbuzz/file.py is our new
 
 
 
 
# get the absolute path of a given file or directory
 
print(path.absolute())

Directories in python

#directories#directory#dir sometimes you need to work with directories, in other words, path that represent a directory.

from pathlib import Path
path = Path("FizzBuzz")
# Check if the path does exist
print(path.exists())  # boolean
 

Create a new directory

We are in a working directory and there is a dir called buzzer i would like to create a folder called bang

from pathlib import Path
path = Path("buzzer")
new_dir_name = "bang"
sub_dir = path / new_dir_name
sub_dir.mkdir()

Rename a directory

To Rename a directory you simply get the directory and you call the rename method

from pathlib import Path
 
path = Path("buzzer")
# rename a directory
path.rename("fizzbuzz")

Remove a directory

To Remove a directory you simply get the directory and you call the remove method

from pathlib import Path
 
path = Path("buzzer")
# rename a directory
path.rmdir()

Get the list of files and directories in a given path

To get a list of a given file and dirs in a specific path you simply use the iterdir() method THis is good but does not search by a pattern and does not search recursively

from pathlib import Path
path = Path("buzzer")
 
print(list(path.iterdir())) #Generator object is returned.

Get The list of files and directories using glob

from pathlib import Path
 
path = Path("buzzer")
path.glob("*") # All files and folder
path.glob("*.py") # All python files
 
# Searching Recursively
path.rglob("*")
#will print everything even the sub directory

Working With Files in python

We can also work with files

from pathlib import Path
 
path = Path("FizzBuzzer/sample.txt")
 
# check if file exists
 
path.exists()
 
# Rename the file
 
path.rename("Isample")
 
# Delete the file
 
path.unlink()
 
# returns informatio about the file
print(path.stat()) # creation time, last accessed, last modified etc...
 
 
# Reading data from a file
# return content of a file as byte text
print(path.read_bytes())
# return content of a file as text
print(path.read_text())
#We can also write text or byte
path.write_text("Hello world")
path.write_byte("This is a byte")

Copying files, you can use the read and write technique but it is not pretty

from pathlib import Path
 
source = Path("FizzBuzz/sample.txt")
target = Path() / "daniel.txt"
source.read_text()
target.write_text(source.read_text())

Shell utility module

We have a shell module utility and it proposes a high number of operations

from pathlib import Path
 
import shutil
 
source = Path("FizzBuzz/sample.txt")
 
target = Path() / "daniel.txt"
 
shutil.copy(source, target)

Working with zip files

Writting files to a zip file

from pathlib import Path
 
from zipfile import ZipFile
 
 
 
with ZipFile("files.zip", "w") as zip:  # for writting to a zip.
 
    files_to_zip = Path("FizzBuzz").rglob("*.*")
 
    for path in files_to_zip:
 
        zip.write(path)

Reading a zip file

with ZipFile("files.zip", "r") as zip:  # for writting to a zip.
 
    print(zip.namelist())
 
    info = zip.getinfo('FizzBuzz/sample.txt')
 
    print(info.file_size)
 
    print(info.compress_size)

Extract zip file

with ZipFile("files.zip", "r") as zip:  # for writting to a zip.
   zip.extractall()
   #optionally you can specify the directory you want to unzip to
   zip.extractall("extracted")
   

Working with csv in python

CSV also called comma separated values, we get to write things and separate them with comma it’s like a simplified version of excell

Creating a csv file

import csv
 
with open('data.csv', "w") as file:
    # create our csv writter
    writer = csv.writer(file)
    # write rows
    writer.writerow(["Transaction_id", "Product_id", "Price"])
    writer.writerow(["1000", "2", "34"])
    writer.writerow(["1500", "12", "234"])

Reading a csv file

import csv
with open('data.csv', "r") as file:
 
    # create our csv reader method
 
    reader = csv.reader(file)
 
    for row in reader:
 
        print(row)

Working with json in python

Javascript object notation , is a popular way fo format data in a human readeable way.

Creating and writting data to a json file

import json
from pathlib import Path
 
 
movies = [
 
    {"id": 1, "Title": "God Fahter", "year": 1989},
 
    {"id": 2, "Title": "John Wick Chapter 1", "year": 2014},
 
    {"id": 3, "Title": "John Wick chapter 2", "year": 2017},
 
    {"id": 4, "Title": "John Wick chapter 3 Parabellum", "year": 2019},
 
    {"id": 5, "Title": "John Wick chapter 4", "year": 2023},
 
]
 
data = json.dumps(movies)
 
path = Path("movies.json")
 
path.write_text(data)
# In python the syntax of json is very similar with a list of dictionary, that is why if you print the result will be identical

Read Data from file or source

import json
 
from pathlib import Path
 
path = Path("movies.json")
 
data = path.read_text()
movies = json.loads(data)
print(movies)

To do any work with a file, even just printing its contents, you first need to open the file to access it The open() function needs one argument: the name of the file you want to open. Python looks for this file in the directory where the program that’s currently being executed is stored

#Ex:
with open('pi_digits.txt') as file_object:
	contents = file_object.read()
	print(rstrip())

Reading line by line

with open(filename) as file_object:
	lines = file_object.readlines()
for line in lines:
	print(line.rstrip())

You can Apply the same consept in reading bigger files

with open('pi_million_digits.txt') as file_object:
	lines = file_object.readlines()
	pi_string = ''
for line in lines:
	pi_string += line.strip()
 
print(f"{pi_string[:52]}...")
print(len(pi_string))

Python has no inherent limit to how much data you can work with; you can work with as much data as your system’s memory can handle.

#Check if birthday is in pi
birthday = input("Enter your birthday, in the form mmddyy: ")
 
if birthday in pi_string:
	print("Your birthday appears in the first million digits of pi!")
else:
	print("Your birthday does not appear in the first million digits of pi.")

Writing to a file

To write text to a file, you need to call open() with a second argument tellingPython that you want to write to the file. To see how this works, let’s write a simple message and store it in a file instead of printing it to the screen

filename = 'programming.txt'
with open(filename, 'w') as file_object:
	file_object.write("I love programming.")

File IO In python To open A file you simply use open function

myfile=open("fileName")
#read All Lines and save them in a variable
print(myfile.read() ) #Will output all the values of the file
 
#
# If you try to ouput again the values from a file then nothing will output ,
# this is because the cursor went all the way to the end and you need to
# get it back at the beginning again
 
# to Reset the cursor simply use
 
myfile.seek(0)

The Readline method :myfile.readlines()

The Read Line Method , simply saves those things in a list with the separator being new lines

Closing A file If You try to open the file somewhere else , then it’s simply not gonna work , they will show an error , Therefore , you must close a file after using it

Closing automatically a file

There is even a better way to deal with files : you can open them and no need to close them anymore

#Instead of :
myfile=open("mytextfile.txt")
 
#We use:
 with open("mytextfile.txt") as myfile
	content=myfile.read()

Appending To a file

with open('myfile.txt',mode='a') as f:
	f.write("This is just a new line which was written on a file ")
	f=open("filename.txt")
	for line in f:
	print(line,end=' ')
 

open(“file_name”,“mode”) #The Open() method , Opens a file in read mode , which is the default when you don’t specify any other argument

Where Mode can be :

  • r: for read
  • w: for writting on the file
  • a: for appending on the file
  • r+: read and write
  • rt: textfile mode
  • rb: for binary more for line in f: Since f is an iterable we can simple loop through it easily , or we can use readlines(): which Does exaclty the same thing
for line in f.readlines()

Reading and Writting files in python

wrt=open("new.txt","w")
s="Ohh i am just text on the screen"
print(s, file=wrt)
#this will simply write to out ifle the contents in the s variable
 
 
f=open("dir.txt",'r')
  wrt=open("new.txt","w")
  for line in f:
      print(line ,file=wrt,end="")
  print("Done.")
 
#the file=wrt parameter , is given to the print function to write to the wrt file
 

Reading And writtting Big Chunks of Files

buffersize=50000
infile=open('bigfile.txt', 'r')
outfile=open('new.txt','w')
buffer= infile.read(buggersize)
whie len(buffer):
	outfile.write(buffer)
	print('.',end='')
	buffer=infile.read(buggersize)
print()
print('Done.')

Reading And writing binary files

#Pretty much the same as file buffering
buffersize=50000
infile=open("file.jpg",'rb')
outfile=open("new.jpg",'wb')
buffer=infile.read(buffersize)
while len(buffer):
	outfile.write(buffer)
	print(".", end='')
	buffer=infile.read(buffersize)
	print()
	print("done.)
 
 
 
 

Working with Timestamps in python

Basically we have two modules for workin with data and time the first module is timestamp and the other one is datetiem

Using time module

Getting the current time

import time
 
# Beginning of time (unix time) since January 1, 1970
 
print(time.time())

Using datetime module

from datetime import datetime
 
import time
 
# datetime.datetime(year,month,day,hour,minute,second)
 
dt = date = datetime(2023, 4, 23, 10)
 
# Return the current date time
dt = datetime.now()
 
# Converting datetiem string , parsing a string to a datetime object
dt = datetime.strptime("2023/04/23", "%Y/%m/%d")
 
# convert a timestamp into a datetime
dt = datetime.fromtimestamp(time.time())
 

working with time delta

Time delta which is a class from the datetime module represents a duration.

from datetime import datetime, timedelta
 
dt1 = datetime(2023, 1, 1) + timedelta(days=1, seconds=1000)
dt2 = datetime.now()
 
duration = dt2-dt1
print(duration.days)
print(duration.seconds)
print(duration.total_seconds())

DATABASE WITH PYTHON (MYSQLITE)

SQLITE3 Comes with python , it’s preinstalled , and very easy

  • It is the perfect choice for most of applications
  • It is reliable simple and does not require a separate database engine
  • it is self contain , server less o configuration fully transactional
  • fully capable databse ,

Creating A database

import sqlite3
db=sqlite3.connect("test.db") # create a database if it does not exist
# will return a connection object, Means we have to close the connection,
# A Better approach would be to use the with method
with sqlite3.connect("text.db") as db:
	pass

Create tables

 db=sqlite3.connect("test.db")
    db.row_factory=sqlite3.Row #allo us to access column separately row[id], etc..
    db.execute("drop table if exists test") #remove the table if it already exist and craet  new one
    db.execute("create table test (t1 text, i1 int)")
    db.execute("insert into test values(?,?)",("one",1))
    db.execute("insert into test values(?,?)",("two",2))
    db.execute("insert into test values(?,?)",("three",3))
    db.execute("insert into test values(?,?)",("four",4))
    db.commit()
    cursor=db.execute("select * from test order by t1") #select all the data
 
    for row in cursor: #itterate through the selected data
        print(row['t1'],row['i1'])
        #because of the row_factory=sqlite3.Row we are able to access each column individualy

Commit()

commit

For Everything that can change the database(insert,delete, update) we have to call the commit function

db.commit(),

PERFORMING CRUD ON SQLITE3

THIS FUNCTION Way And this is not what you would want to do in a prodution applictaion

def insert(db,row):
    db.execute("insert into test(name, age) values(?,?)",(row["name"],row["age"]))
    db.commit()
 
def update(db,row):
    db.execute("UPDATE test set age=? , name=? where age=?",(row["age"],row["name"],row['rp']))
    db.commit()
def delete(db,row):
    db.execute("DELETE FROM test WHERE age=?",(row,))
    db.commit()
 
def retrieve(db,dd):
    cursor=db.execute("Select * from test where age=?",(dd,))
    return cursor.fetchone()
 
def disp_rows(db):
    cursor = db.execute('select * from test ')
    for row in cursor:
        print('{}: {}'.format(row['name'], row['age']))
 
def main():
    db=sqlite3.connect("db.sql")
    db.row_factory=sqlite3.Row
 
    print("Creating Table ")
    db.execute("drop table if exists test")
    db.execute("CREATE TABLE test(name text , age int)")
 
    print("Inserting Data in the table ...")
    insert(db,dict(name="Ilunga Gisa Daiel",age=23))
    insert(db,dict(name="Uwamahoro Rachel",age="23"))
    insert(db,dict(name="John Wich",age=12))
    insert(db,dict(name="Birdy Home",age=20))
    disp_rows(db)
 
    print("Update Rows ------------- ")
    update(db,dict(name='davi dodo',age=32,rp=12))
    disp_rows(db)
 
    print("Detele Row ------------- ")
    delete(db,23)
    disp_rows(db)
 
 
    print("Retrieve Row ------------- ")
    print(dict(retrieve(db, 20)))
 

Creating a program that reads data from json and save it to a database

from pathlib import Path
 
from zipfile import ZipFile
 
 
 
with ZipFile("files.zip", "r") as zip:  # for writting to a zip.
 
    print(zip.namelist())
 
    info = zip.getinfo('FizzBuzz/sample.txt')
 
    print(info.file_size)
 
    print(info.compress_size)

MileStone Projects

Instead of having 3 Print to display rows over and over again we can create a display function which , display them all

	def display(row1,row2,row3):
		print(row1)
		print(row2)
		print(row3)

User Validation validating Input

USING A CLASS TO HANDLE DATABASE SCHEMA WHEN YOU ARE USING AN APPLICATION THAT USES A DATABASE SOMETIMES IT’S IS A GOOD IDEA TO WRITE A CLASS THAT HANDLES THAT SCHEMA

Sending emails in python

sometimes you just want to send emails in python Basically we need two thing

  • Create email message
  • SMTP server for sending email
# Class to create email message
 
# Standark for defining the format of emails
 
from email.mime.multipart import MIMEMultipart
 
from email.mime.text import MIMEText
 
import smtplib
 
from email.mime.image import MIMEImage
 
from pathlib import Path
 
# Mime multipart object for sending emails that include plain text or html
 
 
 
# create our mail message object
 
message = MIMEMultipart()
 
message["from"] = "info@streamlining.com"
 
message["to"] = "danielilunga35@gmail.com"
 
message["subject"] = "textsubject"
 
# Attached, Gets a pa yload , can be text, image or any other type.
 
message.attach(MIMEText("Body text"))
 
message.attach(
 
    MIMEImage(Path(r"C:\Users\ilung\Documents\python\PythonMastery\email\chess.png").read_bytes()))
 
 
 
with smtplib.SMTP(host='smtp.gmail.com', port=587) as smtp:
 
    # communication starts with a hello always
 
    smtp.ehlo()  # hello message,  Greeting to the smtp server,
 
 
 
    # put smtp into tls mode
 
    smtp.starttls()
 
    smtp.login("danieleratdodo@gmail.com", "fmgrpkydppuvxrtw")
 
    smtp.send_message(message)
 
    print("Message sent...")

Working with templates

 

Adding arguments to a python program

sometimes you need to run your python file with some arguments, In this case you use the sysargs

import sys
 
# Print all the supplied arguments to our program.
 
print(sys.argv)
 
# run : python app.py -a -b
 
# output: array with all the supplied arguments
 
# ['app.py','-a','b']
 
 
 
# check if user supplied arguments
 
if len(sys.argv) == 1:
    print("Usage: Python app.py <password>")
 
else:
    password = sys.argv[1]
    print("Password", password)

Running an external command.

let’s say you wan to run an external command, let’s take an example of the ls command. on linux and mac this program lists files and folders. how can you actually run this program? import subprocess

  • With this module we can start a child process

  • A process is basicaly an instance of a running program

  • with this module we have methods such as

The Methods bellow are considered legacy now, they no loner get used that often. in fact ,don't use them.

  • subprocess.call
  • subprocess.check_call
  • subprocess.check_output
  • subprocess.Popen
#subprocess.run(["command","argument"])
import subprocess
 
# Instead we use the run command to execute a given process
 
subprocess.run(["ls", '-l'])
 
print("return code: ", completed.returncode)
 
print("args: ", completed.args)  # Arguments
 
print("stder: ", completed.stderr)  # standard error
 
print("stdout: ", completed.stdout)  # standard output

Sometimes we want to capture the output of a program and do something with it.

completed = subprocess.run(["ls", '-l'],capture_output=True,text=True)
#will not print anything in the terminal untill you actually display the stdoutput
print("stdout", completed.stdout)

Running another script in a separate file in python

completed = subprocess.run(["python", 'other.py'],capture_output=True,text=True)
#will not print anything in the terminal untill you actually display the stdoutput
print("stdout", completed.stdout)

Pypi , Python non standard library.

For node there is something like npm which provides packages that are not standard for js, in python we have Pypi, it comes with a lot of package one might need or think of. https://pypi.org/

To install and Uninstall a packages from the pypi repo we use pip,

Install and Uninstall

pip install package_name
 
#Uninstall a package
 
Pip uninstall package_name

Listing installed packages

pip list
#output:
# Package            Version
# ------------------ ---------
# astroid            2.15.3
# autopep8           2.0.2
# requests           2.28.2
# 2.28.2 from requests , that version is called semantic versioning
		#2 represent the major version
		#28 represent the minor version
		#2 represent a patch version(bug fix)

Installing an earlier version of requests

sometimes you just want to install an older version of a package, maybe for the sake of compatibility or just because you are a maniac the for that you are gonna use:

pip install requests==2.9.0 #there you go.
#will uninstall the version you have  and add this one
 
#or
 
pip install requests=2.9.* # install the latest compatible version with version 2.9
#if there is patches then instlal these .

PIPENV

#pipenv#pip#env This is the new dawg in the game, simply combing virtual env and pip in the backend.

Installing requests using pipenv

pipenv install requests
# A virtual Environment will be installed
# And requests will be installed inside of that virtual environment.

Get the location of the virtual environment created by pipenv

You have runned pipenv and don’t know where the heck the virtual environment is installed? there you go.

pipenv --venv

Activating the virtual environment

pipenv shell
# this will activate the virtual environment

Managing the dependencies of our project

pipenv graph
# output: will show you packages and their dependencies.
# requests==2.28.2
 # - certifi [required: >=2017.4.17, installed: 2022.12.7]
 # - charset-normalizer [required: >=2,<4, installed: 3.1.0]
 # - idna [required: >=2.5,<4, installed: 3.4]
 # - urllib3 [required: >=1.21.1,<1.27, installed: 1.26.15]
 

List all Outdated packages

pipenv update --outdated
# List all packages and all outdated version of them
# Package 'requests' out-of-date: '==2.28.2' installed, '==2.29.0' available.
# Package 'pylint' out-of-date: '==2.17.2' installed, '==2.17.3' available.
# Package 'platformdirs' out-of-date: '==3.2.0' installed, '==3.4.0' available.
# Package 'astroid' out-of-date: '==2.15.3' installed, '==2.15.4' available.

Update an outdated packages

pipenv update requests

Install exact packages and their dependencies

sometimes you want to install the exact packages and their dependencies such that if it works on your computer then it must work on theirs, in this case we have to install but ignore the pipfile and simply use the pipfilelock

	pipenv install --ignore-pipfile

VIRTUAL ENVIRONEMENT IN PYTHON VENV

To create a virtual environment in python , simply navigate to your project folder, then type

python3 -m venv your_venv_name

To activate the vertual environment

source venvName/bin/activate

Threading or threads in python

Thread is a fancy way of running multiple tings at the same time you run things in an asyncronous manner

 
import threading
 
class printer(threading.Thread):
	def run(self):
		for _ in range(10):
			print(threading.currentThread().getName()
 
x=printer(name='Love is the key')
y=printer(name='we are the face of the worl')
 
x.start()
y.start()

PILLOW LIBRARY PILL pillow

from PIL import  Image
 
img = Image.open('pil.jpg')
# Print Simple properties
print(img.size)
print(img.format)
 
# Display Image
img.show()
 
#Mode of an image( RGB, CMYK etc..)
print(img.mode)
 
img.split() #return Chanels (rbg)
 

Mergin Two Images to create Some Sort Of filter

from PIL import Image
 
# !!! images must be of the same size
 
img = Image.open('pil.jpg')
img2 = Image.open('pil2.jpg')
r1, g1, b1 = img.split()
r2, g2, b2 = img2.split()
 
print(img.size)
print(img2.size)
 
new_img= Image.merge('RGB',(r2,g1,b1))
 
new_img.show()
 

Image Transofrmation

Resize An image

img = Image.open('pil.jpg')
img=img.resize((540, 360))

Flip an image

img = Image.open('pil.jpg')
fliped_img=img.transpose(Image.FLIP_LEFT_RIGHT)

Rotate

spin_img=img.traspose(Image.ROTATE_90)

Crop Image

from PIL import  Image
 
img = Image.open('pil.jpg')
print(img.size)
# Croping Image
area = (200,0,355,170)
 
cropped_image = img.crop(area)
 
cropped_image.show()
 
Example 2 Cropping
from PIL import Image
 
img = Image.open('face.png')
img2 = Image.open('pil.jpg')
 
print(img.size)
# (225, 225)
 
print(img2.size)
# (540, 360)
 
# Croping Image
area = (100, 0, 325, 225)
img2.paste(img, area)
img2.show()

Convert Image to black and white

img = Image.open('pil.jpg')
black_white = img.convert("L")
black_white.show()

Convert to binary and decimal ,

packed_data=pack('iif', 4, 34, 2.3)
print(packed_data)
 
#Convert back to normal
original_data=unpack('iif',b'\x04\x00\x00\x00"\x00\x00\x0033\x13@')
 
print(original_data)

Bitwise operator (and or nor nand etc..)

# Bitwise Operator
a = 50    # 110010
b = 25    # 011001
c = a & b # 010000
 
print(c)   # 16

Sorting using Headque, heapq

grades=[32,41,525,63,122,45,36,663,230,424,12,301]
 
 
Sorting a dictionary
stocks=[
    {'name':"Apple","price":2201},
    {'name':"microsoft>","price":101},
    {'name':"microsoft>","price":401},
    {'tuna':'Bucky',"price":92234}
]
print(heapq.nlargest(2,stocks,key=lambda stock: stock['price']))
 
 

Finding Most frequently occuring words or items

text = "Oh i am just text on screen what do you have to say about me ? tada"
 
word = text.split()
 
counter = Counter(word)
 
print(counter)
print(counter.most_common(3)) # Stat of 3 Most common words
 

Tips and Tricks

#tip#trick#hack#workaround

Sorting A disctionary

There is no function to sort a dictionary really , but we can do it using the zip function which makes it very easy really

Sorting A dictionat

stock={
    "Google":543,
    "Yahoo":234,
    "Facebook":432,
    "Amazon":298,
    "Apple":999
}
newStock=dict(sorted(zip(stock.values(),stock.keys())))
 
print(newStock)
 

The dir funciton

The built dir fucntion we can get a list of attribute and methods defines in an object.

 
print(dir(str))

Unpacking in python

#unpack#unpacking You unpack when you have any iterable(list,generator,set…) and you simply can get all values using unpacking *

value = list(range(5))
#using unpacking
value = [*range(5)] # it can be anything, list, set or any iterable.
 
#you can also unpack a dictionary
first = {"x":1}
second = {"x": 10, "y":2}
combined = { **first, **second, "z":1}

Hidding the access of a member of an instance of a class to be used only internaly, aka making it private

#__#private

class TagCloud:
    def __init__(self):
        self.__tags = {}  # Private not accessible over objects
        self.age = 23
c = TagCloud()
print(c.age)  # Accessible
print(c.__tags)  # Not Accessible

Still accessing the attributes even after making them private

Though they are private, we can still access them from the outsite, therefore do not use this private feature as a security mechanism

class TagCloud:
    def __init__(self):
        self.__tags = {}  # Private not accessible over objects
        self.age = 23
#How to access them you might wonder
# Every object of class has access to the __dict__, this is a dictionary that hols all attributes of this class
cloud=TagCloud()
#print(cloud.__tags)# Not accessible
print(cloud.__dict__)# give a dictionary of all attributes of our class
#output:
	#{'_TagCloud__tags': {}, 'age': 23}
# Meas we can still access this using:
print(cloud._TagClout__tags)
 

Private and access modifier

In Python we don’t really have those access Controlls like private or things like that , like in other programming languages.

Why use __ for private access modifier simulation then?

It is more of a convention , to prevent accidental access of these private members.

Named Tuple in python

Instead of creating a class that has no methods, in python we can make use of the namedtuple to achieve the same result

from collections import namedtuple
 
 
 
Point = namedtuple("Point", ["x", "y"])
 
p1 = Point(x=1, y=2)
 
p2 = Point(1, 2)
 
print(p1 == p2)
 
print(p2.x)
 
# Named Tuples are Immutable.
 
# This will not work
 
p1.x=33

Opening the brownser

If you want to play a little bit with the brownser you can use the webbrowser module in python

import webbrowser
 
print("Deployment completed successfully")
 
webbrowser.open("www.whatsapp.com")

Bellow is all you can do with the webbrowser module in python The Python webbrowser module provides a high-level interface to allow displaying Web-based documents to users. This module provides a simple and convenient way to open and display a URL in a web browser window. Here are some of the things you can do with the webbrowser module:

  1. Open a web page: You can use the webbrowser module to open a web page in your default web browser. You can use the open() function to achieve this, which accepts a URL as an argument. For example, webbrowser.open('https://www.google.com') will open Google’s homepage in your default web browser.
  2. Open a specific browser: You can use the get() function to specify which web browser to use to open a web page. For example, webbrowser.get('firefox').open('https://www.google.com') will open Google’s homepage in Firefox browser.
  3. Open a web page in a new window: You can use the new argument with the open() function to open a web page in a new window. For example, webbrowser.open('https://www.google.com', new=1) will open Google’s homepage in a new window.
  4. Open a web page in a new tab: You can use the new argument with the open() function to open a web page in a new tab. For example, webbrowser.open('https://www.google.com', new=2) will open Google’s homepage in a new tab.
  5. Check if a browser is available: You can use the open_new() function to check if a browser is available on your system. For example, webbrowser.open_new('https://www.google.com') will check if a browser is available and open Google’s homepage in the default browser if it is available.
  6. Close the browser: You can use the close() function to close the web browser window that was opened using the webbrowser module. For example, webbrowser.open('https://www.google.com') followed by webbrowser.close() will open and close Google’s homepage in the default browser.
  7. Search for a term in a search engine: You can use the open_new_tab() function to search for a term in a search engine. For example, webbrowser.open_new_tab('https://www.google.com/search?q=python') will open a new tab with the Google search results for the term “python”.
  8. Open a local HTML file: You can use the open() function to open a local HTML file in the default web browser. For example, webbrowser.open('file:///C:/Users/username/Desktop/index.html') will open the index.html file located on the desktop in the default browser.

These are just a few examples of what you can do with the webbrowser module in Python. There are many more options and functions available in the webbrowser module that can help you interact with web browsers from within Python.