<h1>Python4Beginners</h1>
<!-- Section 1-->
<div>
<h2><strong>Section 1: Modules and Packages</strong></h2>
<h3><strong>1.1 Import and use modules and packages</strong></h3>
<ul>Some module definition:
<li>All modules, along with the built-in functions, <strong>form the Python standard library</strong></li>
</ul>
<h5><strong>1. Import variants</strong></h5>
<ul>
<li>import</li>
<li>from import</li>
<li>import as</li>
<li>import *</li>
<pre>
<code class="language-python">
# 1. import module_name
import math
result = math.sqrt(25) # Using sqrt from the math module
<br/>
# 2. from module_name import item_name
from math import sqrt
result = sqrt(25) # Directly using sqrt, no need for math.sqrt
<br/>
# 3. import module_name as alias
import math as m
result = m.sqrt(25) # Using sqrt via the alias m
<br/>
# 4. from module_name import *
from math import *
result = sqrt(25) # Directly using sqrt, but it can lead to naming conflicts
</code>
</pre>
</ul>
<h5><strong>2. advanced qualifying for nested modules</strong></h5>
<ul>
<pre>
<code class="language-python">
my_package/
__init__.py
subpackage1/
__init__.py
module1.py
subpackage2/
__init__.py
module2.py
</code>
</pre>
</ul>
<pre>
<code>
from my_package.subpackage1 import module1
</br>
module1.some_function()
</code>
</pre>
<ul>
<h5>3. dir function()</h5>
<pre>
<code>
class Person:
name = "John"
age = 36
country = "Norway"
print(dir(Person))
#result
#['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'country', 'name']
</code>
</pre>
<li>dir(object): returns all properties and methods of the specified object, without the values</li>
</ul>
<ul>
<h5>4. the sys.path variable</h5>
<li>
Sys.path is a list in Python that determines the locations where Python will look for modules when you try to import them
</li>
<li>
You can access and modify sys.path during runtime to add custom directories where Python should look for modules. This can be useful if you want to use modules from non-standard locations or if you have your own library code in a specific directory.
Example:
</li>
<pre>
<code>
import sys
sys.path.append('/path/to/your/custom/directory')
</code>
</pre>
</ul>
</div>
<div>
<ul>
<h3>1.2 math module</h3>
<li>
ceil(x) : Returns the smallest integer greater than or equal to x.
</li>
<pre>
<code>
import math
</br>
result = math.ceil(4.3)
print(result) # Output: 5
</br>
result = math.ceil(9.8)
print(result) # Output: 10
</code>
</pre>
<li>
floor(x) - Returns the largest integer less than or equal to x.
</li>
<pre>
<code>
import math
</br>
result = math.floor(4.7)
print(result) # Output: 4
</br>
result = math.floor(9.2)
print(result) # Output: 9
</code>
</pre>
<li>
trunc(x) : Returns the integer part of x by truncating the fractional part.
</li>
<pre>
<code>
import math
</br>
result = math.trunc(4.9)
print(result) # Output: 4
</br>
result = math.trunc(-5.2)
print(result) # Output: -5
</code>
</pre>
<li>
factorial(x) : Returns the factorial of x.
</li>
<pre>
<code>
import math
</br>
result = math.factorial(5)
print(result) # Output: 120
</code>
</pre>
<li>
hypot(x, y) : Returns the Euclidean norm, sqrt(x*x + y*y).
</li>
<pre>
<code>
import math
</br>
result = math.hypot(3, 4)
print(result) # Output: 5.0
</code>
</pre>
<li>
sqrt(x) : Returns the square root of x.
</li>
<pre>
<code>
import math
</br>
result = math.sqrt(25)
print(result) # Output: 5.0
</code>
</pre>
</ul>
</div>
<div>
<ul>
<h3>1.3 Random module</h3>
<li>
random() - Returns a random float between 0 and 1.
</li>
<pre>
<code>
import random
</br>
result = random.random()
print(result) # Output: A random float between 0 and 1
# 0.6665498370764746
</code>
</pre>
<li>
seed(x) : Initialize the random number generator with a specific seed x.
</li>
<pre>
<code>
import random
</br>
random.seed(42) # Setting the seed to 42
result1 = random.random()
</br>
#without seed
result2 = random.random()
</br>
print(result1) # Output: 0.6394267984578837
print(result2) # Output: 0.025010755222666936
</br>
#reseting the seed to 42
random.seed(42)
result3 = random.random()
</br>
print(result3) # Output: 0.6394267984578837 (Same as result1)
</code>
</pre>
<li>
choice(seq) : Returns a random element from a sequence.
</li>
<pre>
<code>
import random
</br>
numbers = [1, 2, 3, 4, 5]
result = random.choice(numbers)
print(result) # Output: A random element from the list, e.g., 3
</code>
</pre>
<li>
sample(population, k) : Returns a list of k unique elements chosen from a population
</li>
<pre>
<code>
import random
</br>
numbers = [1, 2, 3, 4, 5]
sampled_numbers = random.sample(numbers, k=3)
print(sampled_numbers) # Output: e.g., [4, 2, 1]
</code>
</pre>
</ul>
</div>
<div>
<ul>
<h3>1.4 platform module</h3>
<li>
platform() : Returns a string that identifies the underlying platform.
</li>
<pre>
<code>
import platform
</br>
platform_info = platform.platform()
print(platform_info)
# Linux-5.15.109+-x86_64-with-glibc2.35
</code>
</pre>
<li>
machine() : Returns the machine type, e.g., 'x86_64'.
</li>
<pre>
<code>
import platform
</br>
machine_info = platform.machine()
print(machine_info)
#x86_64
</code>
</pre>
<li>
processor() : Returns the processor type
</li>
<pre>
<code>
import platform
</br>
processor_info = platform.processor()
print(processor_info)
#x86_64
</code>
</pre>
<li>
system() : Returns the name of the operating system, e.g., 'Linux' or 'Windows'.
</li>
<pre>
<code>
import platform
</br>
system_info = platform.system()
print(system_info)
#Linux
</code>
</pre>
<li>
version() : Returns the system’s release version.
</li>
<pre>
<code>
import platform
</br>
version_info = platform.version()
print(version_info)
</code>
</pre>
<li>
python_implementation() : Returns the Python implementation. Example output: 'CPython'.
</li>
<pre>
<code>
import platform
</br>
python_implementation_info = platform.python_implementation()
print(python_implementation_info)
</code>
</pre>
<li>
python_version_tuple() : Returns a tuple representing the Python version.
</li>
<pre>
<code>
import platform
</br>
python_version_tuple = platform.python_version_tuple()
print(python_version_tuple)
#('3', '10', '12')#3.10.12
</code>
</pre>
</ul>
</div>
<div>
<ul>
<h3>1.5 Create and use user-defined modules and packages</h3>
<h4>1.5.1 idea and rationale</h4>
<ul>
<strong>References: </strong>
<a href="https://www.stechies.com/creating-importing-modules-python/">Link</a>
</ul>
<h4>1.5.2 the __pycache__ directory</h4>
<ul>
<li>__pycache__ is a directory that is created by the Python interpreter when it imports a module. It contains the compiled bytecode of the module, which can be used to speed up subsequent imports of the same module.</li>
<li>Keep in mind that you typically don't need to interact with the __pycache__ directory directly. Python manages it for you automatically to improve the performance of your scripts.</li>
<pre>
<code>
def add(x, y):
return x + y
#tao 1 file phep_cong
</code>
</pre>
<pre>
<code>
from phep_cong import add
result_add = add(5, 3)
print(f"Addition: {result_add}")
</code>
</pre>
<pre>
<code>
python test.py
</code>
</pre>
<li>Ở trên, ta đã tạo 1 file phep_cong là user-defined module, sau đó, import nó và run ở file test, cuối cùng chạy script cuối để tạo file pycache cho những lần sử dụng sau</li>
</ul>
</ul>
</div>
<div>
<ul>
<h4>1.5.3 the __name__ variable</h4>
<ul><strong>References: </strong>
<a href="https://www.pythontutorial.net/python-basics/python-__name__/">Link</a>
</ul>
</ul>
</div>
<div>
<ul>
<h4>1.5.4 public and private variables</h4>
<ul>
<li>Public and private variables là những quy định đặt tên trong python (public variables là những biến dùng ở trong và ngoài class,func dc; còn private chỉ dùng trong class,...)</li>
<li>convention: private có dấu _ phía trc</li>
<pre>
<code>
class Person:
def __init__(self, name, age):
self._name = name # Private variable (convention)
self._age = age # Private variable (convention)
</br>
def get_name(self):
return self._name
</br>
p = Person("John", 30)
print(p.get_name()) # Accessing private variable using a method
</code>
</pre>
</ul>
</ul>
</div>
<div>
<ul>
<h4>1.5.5 the __init__.py file</h4>
<ul><strong>References: </strong>
<a href="https://toidicode.com/packages-trong-python-355.html">Link</a>
</ul>
</ul>
</div>
<div>
<ul>
<h4>1.5.6 searching for/through modules/packages</h4>
<ul><strong>References: </strong>
<a href="https://bic-berkeley.github.io/psych-214-fall-2016/sys_path.html">Link</a>
</ul>
</ul>
</div>
<div>
<ul>
<h4>1.5.7 nested packages vs. directory trees</h4>
<li>A nested package is a package that contains sub-packages, they also may contain modules</li>
<pre>
<code>
my_package/
__init__.py
subpackage1/
__init__.py
module1.py
module2.py
subpackage2/
__init__.py
module3.py
module4.py
</code>
</pre>
<li>A directory tree refers to the hierarchical arrangement of directories and subdirectories in a file system. In the context of Python packages, the directory tree is used to organize related modules and packages.</li>
</ul>
</div>
<!-- Section 2 -->
<div>
<h4>
<p>
<strong>Section 2: </strong> Module, Strings, and List Methods, And Exception
</p>
</h4>
<p>Please visit <a href="https://hackmd.io/uFSYn-ZyRg6LTVsiBFOTGA">this link</a> to access section 2 keynotes</p>
</div>
<!-- Section 3 -->
<div>
<h2><strong>Section 3: Strings</strong></h2>
<div>
<h3><strong>PCAP-31-03 3.1 – Understand machine representation of characters</strong></h3>
<h3>
<strong>References: </strong>
<a href="https://www.techtarget.com/whatis/definition/ASCII-American-Standard-Code-for-Information-Interchange#:~:text=ASCII%20(American%20Standard%20Code%20for%20Information%20Interchange)%20is%20the%20most,additional%20characters%20and%20control%20codes.">Link 1</a>
<a href="https://www.w3schools.com/charsets/ref_html_utf8.asp">Link 2</a>
</h3>
<h4>
<strong>Requirements: </strong> encoding standards: ASCII, UNICODE, UTF-8, code points, escape
sequences
</h4>
<div>
<h4><strong>ASCII code (American Standard Code for Information Interchange)</strong></h4>
<ul>
<li>ASCII is the character encoding format for text data in computers and on Internet.</li>
<li>There are <strong>unique values</strong> for 128 alphabetic, numeric or special additional characters and control codes.</li>
<li> It includes upper and lower case letters, a to z, A to Z, numerals 0 through 9 and basic punctuation symbols.</li>
<li>It can be represented in many ways:
<ul>
<li>as pairs of <strong>exadecimal digits</strong> -- base-16 numbers, represented as 0 through 9 and A through F for the decimal values of 10-15</li>
<li>as <strong>three-digit octal</strong> (base 8) numbers</li>
<li>as <strong>decimal numbers</strong> from 0 to 127</li>
<li>as <strong>7-bit or 8-bit</strong> binary</li>
<li>
<div style="margin: 0 auto;">
<table>
<tr>
<th>Character</th>
<th>Hexadecimal</th>
<th>Octal</th>
<th>Decimal</th>
<th>Binary (7 bit)</th>
<th>Binary (8 bit)</th>
</tr>
<tr>
<td>m</td>
<td>0x6D</td>
<td>/155</td>
<td>109</td>
<td>110 1101</td>
<td>0110 1101</td>
</tr>
</table>
</div>
</li>
</ul>
</li>
</ul>
</div>
<div>
<h4><strong>UNICODE Consortium</strong></h4>
<ul>
<li>It is used to replace the existing character sets with its standard Unicode Transformation Format (UTF)</li>
<li>Unicode is a character set</li>
<li>Unicode is a list of characters with unique decimal numbers (code points). A = 65, B = 66, C = 67, ....</li>
<li><strong>Example: </strong> To represent the word "hello":, we use the unicode 104 101 108 108 111</li>
</ul>
</div>
<div>
<h4><strong>UTF-8</strong></h4>
<li>UTF-8 is HTML5 default character encoding</li>
<li>It is used to represent the text</li>
<li>It uses binary numbers to represent texts</li>
<li><strong>Example: </strong> UTF-8 encoding will store "hello" like this (binary): 01101000 01100101 01101100 01101100 01101111</li>
</div>
<div>
<h4><strong>Code points</strong></h4>
<li><strong>References: </strong>
<a href="https://exploringjs.com/impatient-js/ch_unicode.html#:~:text=Code%20points%20are%20numbers%20that,an%20emoji%2C%20etc.).">Link 1</a>
</li>
<li>Code points are numbers that represent the atomic parts of Unicode text. Most of them represent visible symbols but they can also have other meanings such as specifying an aspect of a symbol (the accent of a letter, the skin tone of an emoji, etc.).</li>
<li></li>
<li></li>
</div>
<div>
<h4><strong>Escape sequence</strong></h4>
<li>It is used to insert characters that are illegal in a string</li>
<li>An escape character is a backslash <code>\</code> followed by the character you want to insert</li>
<li><strong>Example: </strong> An example of an illegal character is a double quote inside a string that is surrounded by double quotes. <code>txt = "We are the so-called \"Vikings\" from the north."</code></li>
<li>Some escape:
<table>
<tr>
<th>Code</th>
<th>Result</th>
</tr>
<tr>
<td><code>\'</code></td>
<td><code>Single Quote</code></td>
</tr>
<tr>
<td><code>\\</code></td>
<td><code>BlackSlash</code></td>
</tr>
<tr>
<td><code>\n</code></td>
<td><code>New Line</code></td>
</tr>
<tr>
<td><code>\r</code></td>
<td><code>Carriage Return</code></td>
</tr>
<tr>
<td><code>\t</code></td>
<td><code>Tab</code></td>
</tr>
<tr>
<td><code>\b</code></td>
<td><code>BackSpace</code></td>
</tr>
<tr>
<td><code>\f</code></td>
<td><code>FormFeed</code></td>
</tr>
<tr>
<td><code>\ooo</code></td>
<td><code>Octal Value</code></td>
</tr>
<tr>
<td><code>\xhh</code></td>
<td><code>hex value</code></td>
</tr>
</table>
</li>
</div>
</div>
<div>
<h3><strong>PCAP-31-03 3.2 – Operate on strings</strong></h3>
<div>
<h4><strong>Functions: </strong><code>ord(), chr()</code></h4>
<li>Function <code>ord()</code>:
<ul>
<li>The <code>ord()</code> function returns the number representing the unicode code of a specified character.</li>
<li>Syntax: <code>ord(character)</code></li>
<li>Example:
<pre>
<code class="language-python">
x = ord("h")
print("Ord of x is: ", x)
>>>> Ord of x is: 104
</code>
</pre>
</li>
</ul>
</li>
</div>
<div>
<li>Function <code>chr()</code>:
<ul>
<li>The <code>chr()</code> function returns the character that represents the specified unicode.</li>
<li>Syntax: <code>chr(number)</code></li>
<li>Example:
<pre>
<code>
x = chr(97)
print("Chr of x is: ", x)
>>>> Chr of x is: a
</code>
</pre>
</li>
</ul>
</li>
</div>
<!-- Indexing, Slicing, Immutability -->
<div>
<li><strong>Indexing, Slicing, Immutability</strong></li>
<li><strong>Indexing</strong>: It is used to access character in string
<ul>
<li>Accessing Characters by Positive Index Number: </li>
<li>Example:
<pre>
<code>
x = "abcef"
print(x[0])
>>>> a
</code>
</pre>
</li>
<li>Accessing Characters by Negative Index Number: </li>
<li>Example:
<pre>
<code>
x = "abcef"
print(x[-2])
>>>> e
</code>
</pre>
</li>
</ul>
</li>
<li><strong>Slicing</strong>:
<p>Reference: <a href="https://www.digitalocean.com/community/tutorials/how-to-index-and-slice-strings-in-python-3">Link 1</a></p>
<ul>
<li>We can call multiple character values by creating a range of index numbers separated by a colon <code>[x:y]</code></li>
<li>Example:
<pre>
<code>
ss = "Sammy Shark!"
print(ss[6:11])
>>>> Shark
</code>
</pre>
</li>
<li>We can access first x characters of string. Example: To access first 5 characters of string
<pre>
<code>
ss = "Sammy Shark!"
print(ss[:5])
>>> "Sammy"
</code>
</pre>
</li>
<li>We can access last x characters of string. Example: To access last 5 characters of string
<pre>
<code>
ss = "Sammy Shark!"
print(ss[6:])
>>> "Shark"
</code>
</pre>
</li>
<li>We can inverse the string by using slicing. Example:
<pre>
<code>
ss = "Sammy Shark!"
print(ss[::-1])
>>> "krahS ymmaS"
</code>
</pre>
</li>
</ul>
</li>
<li><strong>Immutability</strong>:
<ul>
<li>String in Python is immutable which means you can not change or modifiy any characters in string.</li>
<li>You can just indexing, slicing, or apply some methods which are allow for immutable string.</li>
<li></li>
</ul>
</li>
</div>
<!-- • iterating through strings, concatenating, multiplying, comparing
(against strings and numbers) -->
<div>
<h4><strong>Iterating through strings, concatenating, multiplying, comparing (against strings and numbers)</strong> </h4>
<ul>
<li>Iterating:
<p>Reference: <a href="https://www.geeksforgeeks.org/iterate-over-characters-of-a-string-in-python/">Link 1</a></p>
<ul>
<li>Using simple iteration and <code>range()</code></li>
<li>Example:
<pre>
<code>
# Python program to iterate over characters of a string
<br/>
# Code #1
string_name = "geeksforgeeks"
<br/>
# Iterate over the string
for element in string_name:
print(element, end=' ')
print("\n")
<br/>
# Code #2
string_name = "GEEKS"
<br/>
# Iterate over index
for element in range(0, len(string_name)):
print(string_name[element])
</code>
</pre>
<pre>
<code>
Output:
g e e k s f o r g e e k s
<br/>
G
E
E
K
S
</code>
</pre>
</li>
<li>Using <code>enumerate()</code> function:</li>
<li>Example
<pre>
<code>
# Python program to iterate over characters of a string
<br/>
string_name = "Geeks"
<br/>
# Iterate over the string
for i, v in enumerate(string_name):
print(v)
</code>
</pre>
<pre>
<code>
Output
G
e
e
k
s
</code>
</pre>
</li>
</ul>
</li>
<li>Concatenating:
<p>Reference: <a href="https://www.geeksforgeeks.org/python-string-concatenation/">Link 1</a></p>
It is used to combin two strings.
There are several ways to combine two strings.
<ul>
<li>using the ‘+’ Operator. Example:
<pre>
<code>
# Defining strings
var1 = "Hello "
var2 = "Geek"
<br/>
# + Operator is used to combine strings
var3 = var1 + var2
print(var3)
</code>
</pre>
<pre>
<code>
Output
Hello Geek
</code>
</pre>
</li>
<li>Using the <code>join()</code> Method</li>
<li>Example:
<pre>
<code>
var1 = "Geeks"
var2 = "forGeeks"
<br/>
# join() method is used to combine the strings
print("".join([var1, var2]))
<br/>
# join() method is used here to combine
# the string with a separator Space(" ")
var3 = " ".join([var1, var2])
<br/>
print(var3)
<br/>
Output
GeeksforGeeks
Geeks forGeeks
</code>
</pre>
</li>
<li>Using ‘%’ Operator</li>
<li>Example
<pre>
<code>
var1 = "Welcome"
var2 = "Geek"
<br/>
# % Operator is used here to combine the string
print("% s % s" % (var1, var2))
<br/>
Output
Welcome Geek
</code>
</pre>
</li>
<li>Using <code>format()</code> function</li>
<li>Example:
<pre>
<code>
var1 = "Hello"
var2 = "Geeks"
<br/>
# format function is used here to
# combine the string
print("{} {}".format(var1, var2))
<br/>
# store the result in another variable
var3 = "{} {}".format(var1, var2)
<br/>
print(var3)
Output:
Hello Geeks
Hello Geeks
</code>
</pre>
</li>
<li>Using “, ” comma</li>
<li>Example:
<pre>
<code class="language-python">
var1 = "Geeks"
var2 = "for"
var3 = "Geeks"
print(var1, var2, var3)
</code>
</pre>
</li>
</ul>
</li>
<li>Multiplying:
<p>Reference: <a href="https://www.geeksforgeeks.org/create-multiple-copies-of-a-string-in-python-by-using-multiplication-operator/">Link 1</a></p>
<ul>
<li>Method 1: Simply using multiplication operator on the string to be copied with the required number of times it should be copied.</li> <li><pre>
<code>
Syntax: str2 = str1 * N
where str2 is the new string where you want to store the new string
str1 is the original string
N is the number of the times you want to copy the string.
After using multiplication operator we get a string as output
</code>
</pre></li>
<li>Example:
<pre>
<code>
Original string
a = "Geeks"
Multiply the string and store it in a new string
b = a*3
Display the strings
print(f"Original string is: {a}")
print(f"New string is: {b}")
Output:
Original string is: Geeks
New string is: GeeksGeeksGeeks
</code>
</pre>
</li>
<li><code>Method 2</code>: Copying a string multiple times given in a list</li>
<li>Syntax:
<pre>
<code>
a = [“str1”] * N
a will be a list that contains str1 N number of times.
It is not necessary that the element we want to duplicate in a list has to be a string. Multiplication operator in a list can duplicate anything.
</code>
</pre>
</li>
<li>Example:
<pre>
<code>
# Initialize the list
a = ["Geeks"]
# Number of copies
n = 3
# Multiplying the list elements
b = a*n
# print the list
print(f"Original list is: {a} ")
print(f"List after multiplication is: {b}")
Output
Original list is: ['Geeks']
List after multiplication is: ['Geeks', 'Geeks', 'Geeks']
</code>
</pre>
</li>
</ul>
</li>
<li>Comparing:
<p>Reference: <a href="https://www.geeksforgeeks.org/string-comparison-in-python/">Link 1</a></p>
<ul>There are several ways to compare.
<li>Using Relational Operators</li>
<li>Example:
<pre>
<code class="language-python">
print("Geek" == "Geek")
print("Geek" < "geek")
print("Geek" > "geek")
print("Geek" != "Geek")
Output:
True
True
False
False
</code>
</pre>
</li>
<li>Using Regular Expression (Regex)</li>
<li>Example:
<pre>
<code>
import re
def compare_strings(string1, string2):
pattern = re.compile(string2)
match = re.search(pattern, string1)
if match:
print(f"'{string2}' found in '{string1}'")
else:
print(f"'{string2}' not found in '{string1}'")
string1 = "GeeksForGeeks"
string2 = "GeeksFor"
string3 = "Geeks"
compare_strings(string1, string2)
compare_strings(string1, string3)
Output:
'GeeksFor' found in 'GeeksForGeeks'
'Geeks' found in 'GeeksForGeeks'
</code>
</pre>
</li>
<li>Using Is Operator</li>
<li>Example:
<pre>
<code>
str1 = "Geek"
str2 = "Geek"
str3 = str1
print("ID of str1 =", hex(id(str1)))
print("ID of str2 =", hex(id(str2)))
print("ID of str3 =", hex(id(str3)))
print(str1 is str1)
print(str1 is str2)
print(str1 is str3)
str1 += "s"
str4 = "Geeks"
print("\nID of changed str1 =", hex(id(str1)))
print("ID of str4 =", hex(id(str4)))
print(str1 is str4)
Output:
ID of str1 = 0x7f6037051570
ID of str2 = 0x7f6037051570
ID of str3 = 0x7f6037051570
True
True
True
ID of changed str1 = 0x7f60356137d8
ID of str4 = 0x7f60356137a0
False
</code>
</pre>
</li>
<li>String Comparison in Python Creating a User-Defined Function</li>
<li>Example:
<pre>
<code>
# function to compare string
# based on the number of digits
def compare_strings(str1, str2):
count1 = 0
count2 = 0
for i in range(len(str1)):
if str1[i] >= "0" and str1[i] <= "9":
count1 += 1
for i in range(len(str2)):
if str2[i] >= "0" and str2[i] <= "9":
count2 += 1
return count1 == count2
print(compare_strings("123", "12345"))
print(compare_strings("12345", "geeks"))
print(compare_strings("12geeks", "geeks12"))
Output:
False
False
True
</code>
</pre>
</li>
</ul>
</li>
</ul>
</div>
<div>
<h4><strong>PCAP-31-03 3.3 – Employ built-in string methods</strong</h4>
<table>
<tr>
<th>Function</th>
<th>Usage</th>
</tr>
<tr>
<td>isxxx()</td>
<td>Tests properties of s (islower (), isupper () etc.).</td>
</tr>
<tr>
<td>join(x)</td>
<td>Connects the strings in x (list, set, tuple)</td>
</tr>
<tr>
<td>split(sub)</td>
<td>Decomposes s for each occurrence of sub, returns a list</td>
</tr>
<tr>
<td></td>
</tr>
</table>
</div>
<!-- operators: in, not in -->
</div>
</div>
<!-- Section 4: Object-Oriented Programming -->
<div>
<h3><strong>Section 4: Object-Oriented Programming</strong></h3>
<!-- PCAP-31-03 4.1 – Understand the Object-Oriented approach -->
<div>
<caption>PCAP-31-03 4.1 – Understand the Object-Oriented approach
</caption>
<p><strong>References: </strong><a href="https://edube.org/learn/pe-2/python-essentials-2-module-3-1">Link 1</a></p>
<!-- Idea -->
<div>
<h5>Idea:</h5>
<ul>
<li><p><strong>Procedural Approach:</strong> Nowaday, we just code a single or multiple programmings which are called procedural programming. In procedural approach, functions are able to abuse data, but not vice versa.</p></li>
<li><p><strong>OOP Aproach:</strong> The object approach suggests a completely different way of thinking. The data and the code are enclosed together in the same world, divided into classes.</p></li>
<li><p>Every class is a recipe. You can create many objects which have all methods, traits in the class</p></li>
</ul>
</div>
<!-- Notions -->
<div>
<h5>Notions:</h5>
<ul>
<li><p><strong>Class: </strong> is a category, as a result of precisely defined similarities</p></li>
<li><p><strong>Object: </strong>is an incarnation of the requirements, traits, and qualities assigned to a specific class. This may sound simple, but note the following important circumstances</p>
<div>
<p>The object may be equipped with three groups of attributes:</p>
<ul>
<li>An object has a <i><strong>name</strong></i> that uniquely identifies it within its home namespace (although there may be some anonymous objects, too).</li>
<li>An object has a <i><strong>set of individual properties</strong></i> which make it original, unique, or outstanding (although it's possible that some objects may have no properties at all).</li>
<li>An object has a <i><strong>set of abilities</strong></i> to perform specific activities, able to change the object itself, or some of the other objects.</li>
<li>Two examples:
<p>First example: A pink Cadillac went quickly</p>
<ul>
<li>Object name = Cadillac</li>
<li>Home class = Wheeled vehicles</li>
<li>Property = Color (pink)</li>
<li>Activity = Go (quickly)</li>
</ul>
<p>Second example: Rudolph is a large cat who sleeps all day</p>
<ul>
<li>Object name = Rudolph</li>
<li>Home class = Cat</li>
<li>Property = Size (large)</li>
<li>Activity = Sleep (all day)</li>
</ul>
</li>
</ul>
</div>
</li>
<li>Each <i>subclass</i> is <i>more specialized</i> (or more specific) than its superclass. Conversely, each <i>superclass</i> is <i>more general</i> (more abstract) than any of its subclasses.</li>
<li><p><strong>Inheritance:</strong> inherits all the traits (as well as the requirements and qualities) defined inside any of the superclasses. </p>
<img src="https://edube.org/uploads/media/default/0001/01/a099081349764cfda3d91329ee4a3345643802d4.png">
</li>
<li>To define object:
<pre>
<code class="language-python">
class This_Is_A_Class:
pass
</code>
</pre>
</li>
<li>To define object
<pre>
<code class="language-python">
this_is_an_object = This_Is_A_Class()
</code>
</pre>
</li>
</ul>
</div>
</div>
<!-- Section 4.2: STACK: THE PROCEDURAL VS OOP APPROACH -->
<caption>Section 4.2: STACK: THE PROCEDURAL VS OOP APPROACH
</caption>
<div>
<!-- Section 4.2.1: -->
<div>
<h4><p><strong>Stack: </strong> is a structure developed to store data in a very specific way. Imagine a stack of coins. You aren't able to put a coin anywhere else but on the top of the stack.</p></h4>
<p>The alternative name for a stack (but only in IT terminology) is <strong>LIFO</strong>. <i>Last In - First Out</i>. The coin that came last onto the stack will leave first.</p>
<p>A stack is an object with two elementary operations, conventionally named <i>push</i> (when a new element is put on the top) and <i>pop</i> (when an existing element is taken away from the top).</p>
<img src="https://edube.org/uploads/media/default/0001/01/ffe6a36f13d0c549e0a01688e5e372a36421e84a.png">
</div>
<!-- Section 4.2.2 -->
<div>
<p><strong>Stack Implementation:</strong></p>
<pre>
<code class='language-python'>
stack = []
def push(val):
stack.append(val)
def pop():
val = stack[-1]
del stack[-1]
return val
push(3)
push(2)
push(1)
print(pop())
print(pop())
print(pop())
Output:
1
2
3
</code>
</pre>
</div>
<div>
<!-- Section 4.2.3 -->
<h4><strong>Stack: The Objective approach</strong></h4>
<p>When you have a class implementing all the needed stack behaviors, you can produce as many stacks as you want; you needn't copy or replicate any part of the code</p>
<p>The ability to enrich the stack with new functions comes from inheritance; you can create a new class (a subclass) which inherits all the existing traits from the superclass, and adds some new ones.</p>
</div>
<div>
Others definitions:
<ul>
<li><p>The part of the Python class responsible for creating new objects is called the constructor, and it's implemented as a method of the name \_\_init__</p>
</li>
<li>Each class method declaration must contain at least one parameter (always the first one) usually referred to as self, and is used by the objects to identify themselves.</li>
<li> If we want to hide any of a class's components from the outside world, we should start its name with \_\_. Such components are called private.</li>
</ul>
</div>
<div>
<h5>Stack OOP implementation:</h5>
<ul>
<li>Basic Implementations:
<pre>
<code class='language-python'>
class Stack:
def __init__(self):
self.__stack_list = []
def push(self, val):
self.__stack_list.append(val)
def pop(self):
val = self.__stack_list[-1]
del self.__stack_list[-1]
return val
stack_object_1 = Stack()
stack_object_2 = Stack()
stack_object_1.push(3)
stack_object_2.push(stack_object_1.pop())
print(stack_object_2.pop())
</code>
</pre>
</li>
<li>Othes Implementations:
<pre>
<code>
class Stack:
def __init__(self):
self.__stack_list = []
def push(self, val):
self.__stack_list.append(val)
def pop(self):
val = self.__stack_list[-1]
del self.__stack_list[-1]
return val
class AddingStack(Stack):
def __init__(self):
Stack.__init__(self)
self.__sum = 0
def get_sum(self):
return self.__sum
def push(self, val):
self.__sum += val
Stack.push(self, val)
def pop(self):
val = Stack.pop(self)
self.__sum -= val
return val
stack_object = AddingStack()
for i in range(5):
stack_object.push(i)
print(stack_object.get_sum())
for i in range(5):
print(stack_object.pop())
Output:
4
3
2
1
0
</code>
</pre>
</li>
</ul>
</div>
</div>
<!-- Section 4.3: Haha -->
<caption>Section 4.3: PROPERTIES (INSTANCE VARIABLES, CLASS VARIABLES, ATTRIBUTES)
</caption>
<div>
<!-- Section 4.3.1: INSTANCE VARIABLES -->
<div>
<p>Notations: </p>
<ul>
<li>An instance variable is a property whose existence depends on the creation of an object. Every object can have a different set of instance variables</li>
<li>An instance variable can be private when its name starts with <code>__</code>, but don't forget that such a property is still accessible from outside the class using a <strong>mangled name</strong> constructed as <code>_ClassName__PrivatePropertyName</code></li>
<li>Some important consequences:
<ul>
<li>Different objects of the same class may possess different sets of properties</li>
<li>There must be a way to safely check if a specific object owns the property you want to utilize (unless you want to provoke an exception - it's always worth considering)</li>
<li>Each object carries its own set of properties - they don't interfere with one another in any way.</li>
</ul>
</li>
<li>
Code Example:
<pre>
<code>
class ExampleClass:
def __init__(self, val = 1):
self.first = val
def set_second(self, val):
self.second = val
example_object_1 = ExampleClass()
example_object_2 = ExampleClass(2)
example_object_2.set_second(3)
example_object_3 = ExampleClass(4)
example_object_3.third = 5
print(example_object_1.__dict__)
print(example_object_2.__dict__)
print(example_object_3.__dict__)
Output:
{'first': 1}
{'first': 2, 'second': 3}
{'first': 4, 'third': 5}
</code>
</pre>
</li>
<li>
Explanation:
<ul>
We've created three objects of the class <code>ExampleClass</code>, but all these instances differ:
<li><code>example_object_1</code> only has the property named <code>first</code></li>
<li><code>example_object_2</code>has two properties: <code>first</code> and <code>second</code></li>
<li><code>example_object_3</code> has been enriched with a property named <code>third</code> just on the fly, outside the class's code - this is possible and fully permissible</li>
</ul>
</li>
</ul>
</div>
<div>
<!-- Section 4.3.2: CLASS VARIABLE -->
<p>Notations:</p>
<ul>
<li>A <strong>class variable</strong> is a property which exists in exactly one copy, and doesn't need any created object to be accessible. Such variables are not shown as <code>__dict__ content</code></li>
<li>All a class's class variables are stored inside a dedicated dictionary named <code>__dict__</code>, contained in every class separately.</li>
<li>A function named <code>hasattr()</code> can be used to determine if any object/class contains a specified property.</li>
<li>Example:
<pre>
<code>
class ExampleClass:
counter = 0
def __init__(self, val = 1):
self.__first = val
ExampleClass.counter += 1
example_object_1 = ExampleClass()
example_object_2 = ExampleClass(2)
example_object_3 = ExampleClass(4)
print(example_object_1.__dict__, example_object_1.counter)
print(example_object_2.__dict__, example_object_2.counter)
print(example_object_3.__dict__, example_object_3.counter)
Output:
{'_ExampleClass__first': 1} 3
{'_ExampleClass__first': 2} 3
{'_ExampleClass__first': 4} 3
</code>
</pre>
</li>
<li>
<ul>
Explanation:
<li>class variables aren't shown in an object's __dict__ (this is natural as class variables aren't parts of an object) but you can always try to look into the variable of the same name</li>
<li>a class variable always presents the same value in all class instances (objects)</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- Section 4.4: METHODS (CLASS AND OBJECT METHODS, CONSTRUCTORS, PARAMETERS, PROPERTIES) -->
<caption>Section 4.4: METHODS (CLASS AND OBJECT METHODS, CONSTRUCTORS, PARAMETERS, PROPERTIES)
</caption>
<div>
<div>
<h4><strong>Methods</strong></h4>
<p><strong>References: </strong><a href="https://edube.org/learn/pe-2/section-summary-103">Link 1</a></p>
<ul>
<li>A method is a function embedded inside a class. The first (or only) parameter of each method is usually named <code>self</code>, which is designed to identify the object for which the method is invoked in order to access the object's properties or invoke its methods.</li>
<li>If a class contains a <strong>constructor</strong> (a method named __init__) it cannot return any value and cannot be invoked directly.</li>
<li>All classes (but not objects) contain a property named <code>__name__</code>, which stores the name of the class. Additionally, a property named <code>__module__</code> stores the name of the module in which the class has been declared, while the property named <code>__bases__</code> is a tuple containing a class's superclasses.</li>
</ul>
</div>
</div>
<!-- Section 4.5: INHERITANCE (FUNCTIONS, METHODS, CLASS HIERARCHIES, POLYMORPHISM, COMPOSITION, SINGLE VS MULTIPLE INHERITANCE) -->
<caption>Section 4.5: INHERITANCE (FUNCTIONS, METHODS, CLASS HIERARCHIES, POLYMORPHISM, COMPOSITION, SINGLE VS MULTIPLE INHERITANCE)
</caption>
<div>
<p><strong>Reference: </strong><a href="https://edube.org/learn/pe-2/oop-fundamentals-inheritance-59">Link 1</a></p>
<div>
Example of Inheritence:
<pre>
<code>
class Vehicle:
pass
class LandVehicle(Vehicle):
pass
class TrackedVehicle(LandVehicle):
pass
</code>
</pre>
<p>
Explanation:
<ul>
<li>The <code>Vehicle</code> class is the superclass for both the <code>LandVehicle</code> and <code>TrackedVehicle</code> classes;</li>
<li>The <code>LandVehicle</code> class is a subclass of <code>Vehicle</code> and a superclass of <code>TrackedVehicle</code> at the same time;</li>
<li>The <code>TrackedVehicle</code> class is a subclass of both the <code>Vehicle</code> and <code>LandVehicle</code> classes.</li>
</ul>
</p>
<p><strong>Keynote: </strong><a href="https://edube.org/learn/pe-2/section-summary-1-2-8">Keynote</a></p>
<p>For more details, please visit the page to practice :D <a href="https://edube.org/learn/pe-2/oop-fundamentals-inheritance-61">Link practice</a></p>
</div>
</div>
<!-- Section 4.6: Exception -->
<caption>Section 4.6: Exception
</caption>
<div>
<div>
<h4>Keynote:</h4>
<ul>
<li>The <code>else:</code> branch of the <code>try</code> statement is executed when there has been no exception during the execution of the <code>try:</code> block.</li>
<li> The <code>finally:</code> branch of the <code>try</code> statement is always executed.</li>
<li> The syntax <code>except Exception_Name as an exception_object:</code> lets you intercept an object carrying information about a pending exception. The object's property named <code>args</code> (a tuple) stores all arguments passed to the object's constructor.</li>
<li>The exception classes can be extended to enrich them with new capabilities, or to adopt their traits to newly defined exceptions.</li>
</ul>
</div>
<div>
<p>Code Example: </p>
<pre>
<code>
try:
assert __name__ == "__main__"
except:
print("fail", end=' ')
else:
print("success", end=' ')
finally:
print("done")
</code>
</pre>
</div>
<p><strong>For more example, </strong>please visit <a href="https://edube.org/learn/pe-2/exceptions-once-again-24">Link practice and read documents</a></p>
</div>
</div>
<!-- Section 5: Miscellaneous -->
<div>
<h2><strong>Section 5: Miscellaneous</strong></h2>
<p>Please visit <a href="https://hackmd.io/ON730CCzRfSBE8u-SysdWw">this link</a> to view section 5</p>
</div>