INTRODUCTION TO PYTHON PROGRAMMING COURSE

INTRODUCTION TO PYTHON PROGRAMMING COURSE

  1. Introduction to Python
  2. Python Basics (syntax, variables, data types)
  3. Python Operators
  4. Python If…Else
  5. Python While Loops
  6. Python For Loops
  7. Python Functions
  8. Python Lambda
  9. Python Arrays
  10. Python Classes and Objects

Introduction to Computers and Their Architecture

A computer is an electronic device that can perform various tasks by executing instructions given to it. It processes data under the control of a program, which is a set of instructions stored in its memory. Computers come in various forms, from small embedded systems to large mainframe computers, but they all share common basic components.

Basic Components of a Computer

  1. Central Processing Unit (CPU): The CPU is the brain of the computer, responsible for executing instructions and controlling the operation of the other components. It consists of an arithmetic logic unit (ALU) for performing calculations and a control unit for managing the execution of instructions.

  2. Memory: Computers use memory to store data and instructions temporarily while they are being processed. There are two main types of memory: RAM (Random Access Memory), which is volatile and loses its contents when the power is turned off, and ROM (Read-Only Memory), which is non-volatile and retains its contents even when the power is off.

  3. Input Devices: Input devices allow users to interact with the computer and provide it with data and instructions. Common input devices include keyboards, mice, and touchscreens.

  4. Output Devices: Output devices display the results of computations and allow users to see or hear the output. Common output devices include monitors, printers, and speakers.

  5. Storage Devices: Storage devices are used to store data and programs permanently. Examples include hard disk drives (HDDs) and solid-state drives (SSDs).

Computer Architecture

Computer architecture refers to the design and organization of a computer system, including its hardware and software components. It encompasses the following key aspects:

  1. Instruction Set Architecture (ISA): The ISA defines the set of instructions that a computer can execute and how they are encoded. It also includes the registers and memory addressing modes used by the CPU.

  2. Processor Design: Processor design involves designing the CPU, including the ALU, control unit, and registers. It also includes designing the instruction pipeline and cache memory for improving performance.

  3. Memory Hierarchy: The memory hierarchy refers to the organization of memory in a computer system, from fast but small caches to slower but larger main memory and storage devices. This hierarchy is designed to optimize performance and cost.

  4. Input/Output (I/O) System: The I/O system manages the transfer of data between the computer and external devices. It includes controllers for different types of devices and mechanisms for data transfer.

Computers are complex systems with a wide range of components and functionalities. Understanding their architecture is essential for understanding how they work and how to program them effectively.

Introduction to Operating Systems and How They Work

An operating system (OS) is a software that acts as an intermediary between computer hardware and the user. It provides a platform for running applications and manages the computer’s resources, such as memory, processors, and input/output devices. Without an operating system, a computer would be unable to perform tasks or run programs effectively.

Functions of an Operating System

  1. Resource Management: The OS manages the computer’s resources, including memory, processors, and input/output devices. It allocates resources to running programs and ensures that they are used efficiently.

  2. Process Management: The OS manages processes, which are instances of running programs. It handles the creation, scheduling, and termination of processes, ensuring that each process gets the resources it needs.

  3. Memory Management: The OS manages the computer’s memory, ensuring that each program has enough memory to run and that memory is allocated and deallocated efficiently.

  4. File System Management: The OS manages files on the computer’s storage devices, such as hard drives and solid-state drives. It handles file creation, deletion, and organization, providing a way for users to store and retrieve data.

  5. Device Management: The OS manages input/output devices, such as keyboards, mice, printers, and monitors. It handles communication between devices and programs, ensuring that data is transferred correctly.

  6. User Interface: The OS provides a user interface through which users can interact with the computer. This can be a graphical user interface (GUI) or a command-line interface (CLI), depending on the OS.

How an Operating System Works

  1. Boot Process: When you turn on a computer, the OS is loaded into memory through a process called bootstrapping or booting. The boot process initializes the computer’s hardware and loads the OS kernel into memory.

  2. Kernel: The kernel is the core of the operating system, responsible for managing the computer’s resources and providing a platform for running applications. It interacts directly with the hardware and provides services to other parts of the OS and to applications.

  3. System Calls: Applications communicate with the OS through system calls, which are requests for OS services. For example, when an application wants to read from a file, it makes a system call to the OS’s file system management component.

  4. Process Management: The OS manages processes by scheduling them to run on the CPU. It ensures that each process gets a fair share of the CPU’s time and that processes do not interfere with each other.

  5. Memory Management: The OS manages memory by allocating memory to processes and ensuring that processes do not access memory that does not belong to them. It also handles virtual memory, which allows processes to use more memory than is physically available.

  6. File System Management: The OS manages files on storage devices by providing a file system that organizes and stores files. It handles file operations, such as creation, deletion, and modification, and ensures that files are stored and retrieved correctly.

  7. Device Management: The OS manages input/output devices by providing device drivers that control the devices. It handles device communication and ensures that data is transferred correctly between devices and programs.

  8. User Interface: The OS provides a user interface through which users can interact with the computer. This can be a graphical user interface (GUI) with windows, icons, and menus, or a command-line interface (CLI) where users type commands.

An operating system is a crucial component of a computer system, providing a platform for running applications and managing the computer’s resources. It performs various functions, including resource management, process management, memory management, file system management, device management, and providing a user interface. Understanding how an operating system works is essential for effectively using and managing computer systems.

Introduction to Programming Languages:

Low-Level and High-Level

Programming languages are used to write instructions for computers to execute. They vary in complexity and abstraction, ranging from low-level languages that are close to machine code to high-level languages that are more human-readable. Here’s an overview of low-level and high-level programming languages with examples:

Low-Level Programming Languages

Low-level languages are closer to the hardware and are more difficult for humans to read and write compared to high-level languages. They provide more direct control over the computer’s hardware and are often used in system programming and embedded systems. There are two main types of low-level languages:

Machine Language: Machine language is the lowest level of programming language and is directly executable by the computer’s CPU. It consists of binary code (0s and 1s) that represent instructions and data. Here’s an example of machine language instructions:

10110000 01100001

Assembly Language: Assembly language is a more human-readable version of machine language that uses mnemonics to represent instructions. Each mnemonic corresponds to a specific machine language instruction. Here’s an example of assembly language instructions:

assembly

MOV AX, 5
ADD AX, BX

High-Level Programming Languages

High-level languages are more abstract and easier for humans to read and write compared to low-level languages. They provide higher levels of abstraction and are closer to natural language. High-level languages are typically compiled or interpreted into machine code before execution. Some examples of high-level programming languages include:

Python: Python is a high-level, interpreted language known for its readability and simplicity. It is widely used in web development, data analysis, artificial intelligence, and scientific computing. Here’s an example of Python code:

python

print("Hello, world!")

Java: Java is a high-level, compiled language that is platform-independent, meaning it can run on any device with a Java Virtual Machine (JVM). It is commonly used in enterprise applications, mobile development, and web development. Here’s an example of Java code:

java

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, world!");
    }
}

C++: C++ is a high-level, compiled language that is an extension of the C programming language. It is used for system programming, game development, and software development. Here’s an example of C++ code:

cpp

#include <iostream>
using namespace std;

int main() {
    cout << "Hello, world!" << endl;
    return 0;
}

High-level languages are preferred for most programming tasks due to their readability, ease of use, and portability. They allow developers to focus on solving problems rather than dealing with low-level details of the computer’s hardware.

welcome to python proigramming. here we shall look at how to get strated with python programming. we shall begin from thee basics and navigate all the way up. our main goal is to create a django project using the django gframework

print("""Welcome to Python programming. Here, we will look at how to get started with Python programming.
We shall begin with the basics and navigate all the way up.
Our main goal is to create a Django project using the Django framework.""")
#the reason for using the three quotation signs is to show that the string is propery terminated
#alternatively one can use
print("/n")
print("Welcome to Python programming."
" Here, we will look at how to get started with Python programming."
"We shall begin with the basics and navigate all the way up."
"Our main goal is to create a Django project using the Django framework.")
print("/n""/n""/n")
#note that in the normal python ide such as pycharm the whole sentence would have been in one single double quote



# this is the first python project
Welcome to Python programming. Here, we will look at how to get started with Python programming.
We shall begin with the basics and navigate all the way up.
Our main goal is to create a Django project using the Django framework.
/n
Welcome to Python programming. Here, we will look at how to get started with Python programming.We shall begin with the basics and navigate all the way up.Our main goal is to create a Django project using the Django framework.
/n/n/n
print("So what is python?"
"Python is a hier level programming language that is a multidimensional language and ius used in varoius fields"
"Python is a widely used general-purpose, high-level programming language. "
"It was initially designed by Guido van Rossum in 1991 and developed by Python Software Foundation. "
"It was mainly developed for emphasis on code readability, and its syntax allows programmers to express concepts in fewer lines of code.")
So what is python?Python is a hier level programming language that is a multidimensional language and ius used in varoius fieldsPython is a widely used general-purpose, high-level programming language. It was initially designed by Guido van Rossum in 1991 and developed by Python Software Foundation. It was mainly developed for emphasis on code readability, and its syntax allows programmers to express concepts in fewer lines of code.

Who invented Python?

In the late 1980s, history was about to be written. It was that time when working on Python started. Soon after that, Guido Van Rossum began doing its application-based work in December of 1989 at Centrum Wiskunde & Informatica (CWI) which is situated in the Netherlands. It was started as a hobby project because he was looking for an interesting project to keep him occupied during Christmas.

The programming language in which Python is said to have succeeded is ABC Programming Language, which had interfacing with the Amoeba Operating System and had the feature of exception handling. He had already helped create ABC earlier in his career and had seen some issues with ABC but liked most of the features. After that what he did was very clever. He had taken the syntax of ABC, and some of its good features. It came with a lot of complaints too, so he fixed those issues completely and created a good scripting language that had removed all the flaws. The inspiration for the name came from the BBC’s TV Show – ‘Monty Python’s Flying Circus’, as he was a big fan of the TV show and also he wanted a short, unique and slightly mysterious name for his invention and hence he named it Python! He was the “Benevolent dictator for life” (BDFL) until he stepped down from the position as the leader on 12th July 2018. For quite some time he used to work for Google, but currently, he is working at Dropbox.

Evolution of Python The language was finally released in 1991. When it was released, it used a lot fewer codes to express the concepts, when we compare it with Java, C++ & C. Its design philosophy was quite good too. Its main objective is to provide code readability and advanced developer productivity. When it was released, it had more than enough capability to provide classes with inheritance, several core data types of exception handling and functions. Following are the illustrations of different versions of Python along with the timeline.

Python is a versatile and widely-used programming language known for its readability and simplicity. It is used in a variety of domains and applications, including:

  • Web Development: Python’s frameworks like Django and Flask enable developers to build scalable web applications quickly.

  • Data Science and Machine Learning: Python’s libraries such as NumPy, pandas, scikit-learn, and TensorFlow are extensively used for data analysis, machine learning, and artificial intelligence applications.

  • Scripting: Python is often used for scripting tasks due to its concise syntax and readability, making it suitable for automation, system administration, and other scripting tasks.

  • Scientific Computing: Python is used in scientific computing and numerical simulations due to its libraries like SciPy and matplotlib, which facilitate data visualization and computation.

  • Education: Python’s readability and ease of use make it a popular choice for teaching programming concepts and computer science.

  • Desktop GUI Applications: Python can be used to create desktop GUI applications using libraries like Tkinter, PyQt, and wxPython.

  • Game Development: Python is used in game development, either directly through libraries like Pygame or as a scripting language within game engines like Unity and Unreal Engine.

  • Networking: Python’s standard library provides modules for networking tasks, making it suitable for developing network applications and protocols.

  • Embedded Systems: Python can be used for programming embedded systems, especially in situations where ease of development and rapid prototyping are crucial.

  • Testing: Python is used in testing frameworks like Pytest for writing and executing test cases.

Jobs and Self-Employment Opportunities in Python

Python is a versatile programming language with a wide range of applications, making it well-suited for various job opportunities and self-employment ventures. Here are some potential career paths and opportunities in Python:

1. Software Development

Python is widely used in software development for web development (Django, Flask), scientific computing, data analysis, artificial intelligence, and machine learning. You can work as a Python developer, building applications and systems for various industries.

2. Data Science and Analytics

Python is the go-to language for data science and analytics due to its rich ecosystem of libraries (NumPy, pandas, scikit-learn). You can work as a data scientist, data analyst, or machine learning engineer, analyzing data, building models, and deriving insights.

3. Web Development

Python is used for both front-end and back-end web development. With frameworks like Django and Flask, you can build web applications, APIs, and websites. You can work as a full-stack developer, specializing in Python-based web development.

4. DevOps and Automation

Python is popular in DevOps for infrastructure automation, configuration management (using tools like Ansible), and continuous integration/continuous deployment (CI/CD) pipelines. You can work as a DevOps engineer, automating and streamlining software development processes.

5. Game Development

Python is used in game development for scripting, AI programming, and prototyping. You can work as a game developer, using Python with game engines like Unity or Pygame to develop games.

6. Education and Training

With Python’s simplicity and readability, it’s a popular choice for teaching programming. You can work as a Python instructor, creating educational materials and courses for beginners and advanced learners.

7. Freelancing and Consulting

Python developers often work as freelancers or consultants, offering their expertise to clients on specific projects. This allows for flexibility in work hours and projects.

8. Entrepreneurship

Python developers can start their own businesses, offering software development services, developing products, or creating software solutions for specific industries or problems.

9. Open Source Contribution

Contributing to open-source projects in Python is a great way to build your skills, network with other developers, and contribute to the community.

Python offers a wide range of career opportunities and avenues for self-employment, thanks to its versatility and popularity in various industries. Whether you choose to work for a company or start your own venture, Python skills can open up a world of possibilities.

Introduction to Compilers, Interpreters, and IDEs

When you write code, you typically use a programming language that humans can understand. However, computers require instructions in a different format. This is where compilers and interpreters come in. They are tools that convert human-readable code into machine-readable instructions. Additionally, Integrated Development Environments (IDEs) are software applications that provide comprehensive facilities to computer programmers for software development. Let’s explore these concepts in more detail.

Compilers

A compiler is a program that translates source code written in a high-level programming language into a lower-level language, often machine code. The compiler performs this translation in a single step, producing an executable file that can be run independently of the compiler. Examples of compiled languages include C, C++, and Rust.

  1. Compilation Process:
    • The compiler scans the entire program and translates it as a whole into machine code.
    • It generates an executable file that can be run on a specific platform.
  2. Advantages:
    • Generally, compiled programs are faster than interpreted ones since the translation only happens once.
    • Compilers can catch syntax errors early in the development process.
  3. Disadvantages:
    • Compilation can be time-consuming, especially for large programs.
    • Compiled programs are platform-dependent and may require recompilation for different platforms.

Interpreters

An interpreter, on the other hand, translates code into machine code line by line, executing each line immediately after it is translated. Interpreted languages include Python, Ruby, and JavaScript.

  1. Execution Process:
    • The interpreter translates and executes the code line by line.
    • There is no separate compilation step, and the code is executed directly from the source.
  2. Advantages:
    • Interpreted languages are generally more portable since the interpreter can run on different platforms.
    • Interpreters are useful for rapid development and prototyping.
  3. Disadvantages:
    • Interpreted programs are generally slower than compiled ones since each line of code is translated at runtime.
    • Errors may only be discovered during execution, making debugging more challenging.

Integrated Development Environments (IDEs)

An IDE is a software application that provides a comprehensive set of tools for software development. It typically includes a source code editor, build automation tools, and a debugger, among other features. Examples of popular IDEs include Visual Studio Code, PyCharm, and Eclipse.

  1. Features:
    • Code editor with syntax highlighting and auto-completion.
    • Built-in debugger for identifying and fixing errors in code.
    • Build automation tools for compiling and running code.
    • Version control integration for managing code changes.
  2. Advantages:
    • IDEs provide a unified environment for all aspects of development, improving productivity.
    • They often include features like code refactoring and unit testing, making it easier to write high-quality code.
  3. Disadvantages:
    • IDEs can be resource-intensive, especially for large projects.
    • Beginners may find the multitude of features overwhelming.

In conclusion, compilers and interpreters are essential tools for translating human-readable code into machine-readable instructions, with each having its advantages and disadvantages. IDEs, on the other hand, provide a comprehensive environment for software development, integrating various tools to streamline the development process.

Getting started with python

#printing your first python program
print("Hello, World!")
Hello, World!

Python identation: Here we shall talk about the python syntax, in python we don’t use the semicolon to show the end of a statement, instead wqe use what we call python identation. We shall look at an example below.

x=23 #this is the variable x which is an integer
y=200 #This is the variable Y which is an integer also
while x<= y:# This is a while loop
  print(x, end=", ")#this is the print statement to output the answer of the loop
  x=x+1 # this is the variable x undergoing an increament
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 
x=20
y=200
while x<=y:
  print(x, end=", ")
  x+=1
  if x == 199:
    pass
    print(x)
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199
199, 200, 
x=300
y=20
while y<=x:
  print(x)
  y+=1
  if y == 25:
    print(y)
    break
300
300
300
300
300
25
y=300
x=600
while y<=600:
  #print(y, end=", ")
  y +=1
  if y==320:
    print(y)
    continue
320
x = 300
y = 20
while y <= x:
    print(x)
    y += 1
    if y == 25:
        print(y)  # This will print y when it reaches 25
        break
300
300
300
300
300
25

the above are some of the common examples that use python identation. THE EXAMPLES ABOVE COVER A WHILE LOOP WITH SOME conditiuons(pass, break anmd continue) these are added so that the while loop is altered in the way it runs the code.

if 5>3:
  print('5 is greator than 3')
5 is greator than 3

The above code also illustraytes the impact of python identation but now this case is of using the if statement

#this is a single lionbe comment in python
''' this is a multiline comment in python'''
"""
This is also a mul;tiline comment in python
"""
{"type":"string"}

The above code shows comments in python. comments are usefulas they hjelp the programmers understand each others code. They also work as reminder notes that is if some

#print("Hello, World!")
print("Cheers, Mate!")
Cheers, Mate!

Inthe above example you notice the one with a preceeding hash is not printed out as it is read as a comment

"""
This is a comment
written in
more than just one line
"""
print("Hello, World!")
Hello, World!

In the above cell you notice that the sentence with the three quotation marks is not printed out as it is read as a comment

w='string'
x=23
y=12.3
z=12j
print(x,y,z)
23 12.3 12j

The above describes how you can create varibles and also show their oputput. In the above example that is how we create variables. In the cells below we shall discuss how we create casting of vaiables, this is used to convert a given datatype of form ‘A’ to form ‘B’

#example
# in this case we shall discuss how the variable type changes from form a to form b
x=12
y=12.5
z=12j
print(type(x), type(y), type(z))
#now perfor5ming casting of the variables
x=float(x)
y=complex(y)
z=str(z)
print(type(x), type(y), type(z))
<class 'int'> <class 'float'> <class 'complex'>
<class 'float'> <class 'complex'> <class 'str'>

Note when assinging variables to strings you can either use single or double Quotes

a=12
A=12j
print(a)
print(A)
#note that python is case sensitive
12
12j

The above example tries to emphasize on the importance of case sensitivity in python programming

#lets see how you assign names to variables
My_name='John'
age=25
myAge=25
_myAge=25
print('Those are the examples of variable names and how theyt are named')
Those are the examples of variable names and how theyt are named

Discussion: Naming Variables

When naming variables in Python, it’s essential to follow certain rules and conventions to ensure clarity and readability in your code. Here are the guidelines for naming variables in Python:

Variable Names

A variable can have a short name (like x and y) or a more descriptive name (age, carname, total_volume).

Rules for Python Variables:

  1. Start with a Letter or Underscore:
    • A variable name must start with a letter (a-z, A-Z) or the underscore character (_).
  2. Cannot Start with a Number:
    • A variable name cannot start with a number (0-9).
  3. Contain Alpha-Numeric Characters and Underscores:
    • A variable name can only contain alpha-numeric characters and underscores (A-z, 0-9, and _).
  4. Case-Sensitive:
    • Variable names are case-sensitive (age, Age, and AGE are three different variables).
  5. Avoid Python Keywords:
    • A variable name cannot be any of the Python keywords (if, else, for, while, etc.).

Following these rules and conventions will make your code more readable and maintainable, improving collaboration and understanding among developers.

#camel case
myNameIs='Charles'
#snake case
my_name_is='Charles'
#Pascals case
MyNameIs='charles'
print(myNameIs,my_name_is, MyNameIs )
Charles Charles charles

Discussion: Naming Variables in Different Styles

When naming variables in programming, it’s common to use different styles to improve readability and maintainability. Three common styles are Pascal case, Camel case, and Snake case.

Pascal Case

  • Definition:
    • Pascal case, also known as Upper Camel Case, capitalizes the first letter of each word and removes spaces.
  • Example:
    • FirstName, LastName, PhoneNumber.

Camel Case

  • Definition:
    • Camel case, also known as Lower Camel Case, is similar to Pascal case but starts with a lowercase letter.
  • Example:
    • firstName, lastName, phoneNumber.

Snake Case

  • Definition:
    • Snake case uses underscores (_) between words and is often preferred in Python for naming variables and functions.
  • Example:
    • first_name, last_name, phone_number.

Choosing the right naming style depends on the programming language and coding conventions of the project. In Python, snake case is commonly used for variables and functions, while Pascal case and Camel case are more prevalent in languages like C# and Java.

x,y,z='orange','mango','strawberry'
print(x)
print(y)
print(z)
#this is the way we assign multiple variables to values then the way we print them can be assocviated with unpacking of variables
orange
mango
strawberry
x=y=z=200
#here we have assigned 200 to all the variables x, y,z
#we expect that if we print x, y or z we have 200 as the output
print(x)
print(y)
print(z)
200
200
200

the above code illustrates a good way of how you can assign a single bvalue to multiple variables

fruit=['orange','mango','watermelon','passion fruit']
w,x,y,z=fruit
print(x)
print(y)
print(z)
print(w)
#the above is what we call unpacking of a collection
mango
watermelon
passion fruit
orange

In the above code we see how a collection which uses the list data type can be unpacked. this is done by assigning the variables to the list


class animal:
  def __init__(self, wild, domestic):
    self.wild = wild
    self.domestic= domestic
class monkey(animal):
  def __init__(self, domestic, tail):
    super().__init__(False, domestic)
    self.tail= tail

  def classification(self):
    if self.domestic:
        print('Monkey is Domestic')
    else:
        print('monkey is wild')

monkey=monkey(True, True)
monkey.classification()
Monkey is Domestic

the above code is used to show how the python outputs it’s variables. variables can be outputed using print() function

x=23
y=35
print(x+y)
58

The above code is used to print the output of x and y which will print the sum note if you tried to add the sum of an integer and a string it would not work

x=20
y='years'
print(x, y)
20 years

The above cell shows how the output of many variables can be printed out

x=23
def myfunc():
  global y
  y=200
  print(f'we want to make {y} the global variable')
def getting_global_variable():
  print(f'the global variable {y}')
myfunc()
getting_global_variable()
we want to make 200 the global variable
the global variable 200

from the above example we have made y the global variable that is considering that y is also in the fuinction above myfunc(), the making og global variable has occured by using the global keyword

x=23
y=24

def area():
  return x*y

def perimeter():
  return 2*x+2*y

print(area())
perimeter()
552
94

In the above code we can see that both x and y are global variables and are being used by the 2 functions area() and perimeter()

a='string'#string data type
b=12#integer data type
c=12.90#float datatype
d=12j# complex numbers data type
e=[1,2,3,4,5,66.77,78j,'string']# list data type
f=(1,2,344.56,45j,'string')#tuple data type
g=frozenset({1,2,344.56,'string'})#frozen set data type
h={'one':1.1,'two':2j,'three':'three','four':[4,4,4,]}#dictionary data type
i={1,2,3,4,5,6,7,8,9}#set data type
j=True#boolean data type
k=bytearray(2)#byte array data type
l=memoryview(bytes(12))# memory view bytes array data type
m=b'245'# byte data type
#the prinbt function below is to output the results of the data types
print(a)
print(b)
print(c)
print(d)
print(e)
print(f)
print(g)
print(h)
print(i)
print(j)
print(k)
print(l)
print(m)
print(type(a), type(b), type(c), type(d), type(e), type(f), type(g), type(h), type(i), type(j), type(k), type(l), type(m))
string
12
12.9
12j
[1, 2, 3, 4, 5, 66.77, 78j, 'string']
(1, 2, 344.56, 45j, 'string')
frozenset({344.56, 1, 2, 'string'})
{'one': 1.1, 'two': 2j, 'three': 'three', 'four': [4, 4, 4]}
{1, 2, 3, 4, 5, 6, 7, 8, 9}
True
bytearray(b'\x00\x00')
<memory at 0x7d76740a1c00>
b'245'
<class 'str'> <class 'int'> <class 'float'> <class 'complex'> <class 'list'> <class 'tuple'> <class 'frozenset'> <class 'dict'> <class 'set'> <class 'bool'> <class 'bytearray'> <class 'memoryview'> <class 'bytes'>

The above pioece of code shows the examples of different data types in python. the datatypes in python are very crusial as they are the building block of pytrhon programming and must be understood very well for one to have a mastery in python.

x=12# this is an integer datatype belonging in python numbers
y=12.23#this is a float data type belonging in python numbers
z=12j#this is a complex datatype belonging to pythoin numbers
#the above belong to python numbers
print(x)
print(y)
print(z)
print(type(x), type(y), type(z))
#the expected output should display a list of data types for each
12
12.23
12j
<class 'int'> <class 'float'> <class 'complex'>

also note they can be negatives also below is an example to illustrate that

x=-20
y=-20.23
z=-12.78j
print(x)
print(y)
print(z)
-20
-20.23
(-0-12.78j)

we shall discuss about type conversion in the subsequent cells, sometimes you will need to convert a certain data type from one Form to another then use the converted datatype

x=int(23.67)#converting float to integer
y=float(45)#convering integer to float
z=str(23)#converting integer to string
print(x)
print(y)
print(z)
print(type(x), type(y), type(z))
23
45.0
23
<class 'int'> <class 'float'> <class 'str'>

In the above code we see that the type casting has been used

import random#this is a python module to randomly generate numbers
print(random.randrange(1,20,2))#this is used to output the random numbers start number 1, stop number 20 and step size number 2
5

below is an example of the random numbers

import random
x= random.randint(1,10)
print(x)
8
import random
x=random.randrange(1,10)
x
3
import random
x=[1,2,3,4,5,6,7,8,9,10]
x=random.shuffle(x)
print(x)
None
import random
x=list((1,2,3,4,5,6,7,8,9,10))
x=random.choice(x)
x
5
import random
x=random.random()
print(x)
0.3786340893997494
import random
x=list((1,2,3,4,5,6,7,8,9,10))
x=random.sample(x, 7)
x
[8, 1, 4, 3, 10, 5, 6]
import random
x=list((1,2,3,4,5,6,7,8,9,10))
x=[random.choice(x) for _ in range  (3)]
x
[10, 3, 1]

The above statements or code show how youcan use the random to generate number data type

print('Hello World')
print("Hello world")
Hello World
Hello world

The above lines of code show how one can implement the use of strings in python. Note that hello world is a string.

So what is a string in python? A string in python is surrounded by quotation marks ether single quotation mark or Double Quotation mark

import pandas as pd
import numpy as np
import random
x=[random.randint(1,100) for _ in range(5)]
x=pd.DataFrame(x, index=['a','b','c','d','e'])
y='This is a string enclosed with a single comment'
z="This is a string enclosed in a double quote"
print(y, '\n', z)
x
This is a string enclosed with a single comment 
 This is a string enclosed in a double quote
0
a 89
b 22
c 52
d 78
e 2
Group_Rules_Dictionary = {
    'Group Rules': 'Group rules:\n'
                   '✍️ Only IT related posts are allowed,\n'
                   '✍️ Don\'t post any phishing links here,\n'
                   '✍️ Don\'t post any nudes photos and links here,\n'
                   '✍️ Don\'t post, comment and  reply using abusive language,\n'
                   '✍️If you are given a task by one of the members, make you finish on time,else you can post here to assist!'
}
#print(Group_Rules_Dictionary )
print(Group_Rules_Dictionary.get('Group Rules'))
Group rules:
✍️ Only IT related posts are allowed,
✍️ Don't post any phishing links here,
✍️ Don't post any nudes photos and links here,
✍️ Don't post, comment and  reply using abusive language,
✍️If you are given a task by one of the members, make you finish on time,else you can post here to assist!

# Strings in Python

Introduction

In Python, a string is a sequence of characters enclosed in single quotes (”), double quotes (” “), or triple quotes (”’ ”’ or “”” “””). Strings are immutable, meaning they cannot be changed after they are created.

Creating Strings

Strings can be created using single quotes, double quotes, or triple quotes:

“`python

Single quotes

single_quoted_string = ‘Hello, World!’

Double quotes

double_quoted_string = “Hello, World!”

Triple quotes (for multi-line strings)

triple_quoted_string = ”’Hello, World!”’

Strings in python are surrounded by a single quote orv a double quote. The strings are also written in different formats.

string='this is a string with a single line comment'
string
{"type":"string"}
#example 2
string="this is a string with double quotation marks"
string
{"type":"string"}
string='''This is a string with single quoptation marks but they are 3'''
string
{"type":"string"}
string="""This is a string with double line quotation mark and has three quotation marks"""

Strings in Python: Single Quotes vs. Double Quotes vs. Triple Quotes

In Python, strings can be defined using single quotes (”), double quotes (“”), or triple quotes (”’ ”’ or “”” “””).

Single Quotes (”)

Single quotes are used to define a string with single-line content. For example, ‘Hello, world!’.

Double Quotes (” “)

Similarly, double quotes are used to define a string with single-line content. For example, “Hello, world!”.

Triple Quotes (”’ ”’ or “”” “””)

Triple quotes are used to define multi-line strings or strings that span across multiple lines. They allow for embedding single quotes or double quotes without escaping them. For example:

“`python multiline_string = ”’This is a multi-line string”’

Slicing of strings

string="lets slice the string"
string[2:5]#slicing from letter t to s
{"type":"string"}

MACHINE LEARNING DIVERSION AND DISCUSSION FOR MOTIVATION

import numpy as np
from numpy import random
import pandas as pd
import matplotlib.pyplot as plt
x=random.randint(1,100,size=(30))
xy=np.array([x])
x=pd.DataFrame(x)
print(xy)
y=random.randint(1,200, size=30)
plt.scatter(x,y)
[[47 14 10 92 40 48 55 55 58 45 37 69 13  2 80 69 97 68 36 63 86  3 85 20
  20  1 26 58 59 16]]
<matplotlib.collections.PathCollection at 0x7d7645fda830>

From the data above we shall use the KMeans algorithim

import numpy as np
from numpy import random
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from scipy.spatial.distance import cdist

x = random.randint(1, 100, size=30)
y = random.randint(1, 200, size=30)

data = np.array(list(zip(x, y)))

distortions = []
K_range = range(1, 10)

for k in K_range:
    kmeans = KMeans(n_clusters=k)
    kmeans.fit(data)
    distortions.append(sum(np.min(cdist(data, kmeans.cluster_centers_, 'euclidean'), axis=1)) / data.shape[0])

plt.plot(K_range, distortions, 'bx-')
plt.xlabel('Number of Clusters (K)')
plt.ylabel('Distortion')
plt.title('Elbow Method for Optimal K')
plt.show()
/usr/local/lib/python3.10/dist-packages/sklearn/cluster/_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/cluster/_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/cluster/_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/cluster/_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/cluster/_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/cluster/_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/cluster/_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/cluster/_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning
  warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/cluster/_kmeans.py:870: FutureWarning: The default value of `n_init` will change from 10 to 'auto' in 1.4. Set the value of `n_init` explicitly to suppress the warning
  warnings.warn(

Machine learning using scikitlearn module

Loading an example dataset

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
x=np.array([12,13,121,45,15,74,98,102])
x
array([ 12,  13, 121,  45,  15,  74,  98, 102])
from sklearn import datasets
x= datasets.load_iris()
x
{'data': array([[5.1, 3.5, 1.4, 0.2],
        [4.9, 3. , 1.4, 0.2],
        [4.7, 3.2, 1.3, 0.2],
        [4.6, 3.1, 1.5, 0.2],
        [5. , 3.6, 1.4, 0.2],
        [5.4, 3.9, 1.7, 0.4],
        [4.6, 3.4, 1.4, 0.3],
        [5. , 3.4, 1.5, 0.2],
        [4.4, 2.9, 1.4, 0.2],
        [4.9, 3.1, 1.5, 0.1],
        [5.4, 3.7, 1.5, 0.2],
        [4.8, 3.4, 1.6, 0.2],
        [4.8, 3. , 1.4, 0.1],
        [4.3, 3. , 1.1, 0.1],
        [5.8, 4. , 1.2, 0.2],
        [5.7, 4.4, 1.5, 0.4],
        [5.4, 3.9, 1.3, 0.4],
        [5.1, 3.5, 1.4, 0.3],
        [5.7, 3.8, 1.7, 0.3],
        [5.1, 3.8, 1.5, 0.3],
        [5.4, 3.4, 1.7, 0.2],
        [5.1, 3.7, 1.5, 0.4],
        [4.6, 3.6, 1. , 0.2],
        [5.1, 3.3, 1.7, 0.5],
        [4.8, 3.4, 1.9, 0.2],
        [5. , 3. , 1.6, 0.2],
        [5. , 3.4, 1.6, 0.4],
        [5.2, 3.5, 1.5, 0.2],
        [5.2, 3.4, 1.4, 0.2],
        [4.7, 3.2, 1.6, 0.2],
        [4.8, 3.1, 1.6, 0.2],
        [5.4, 3.4, 1.5, 0.4],
        [5.2, 4.1, 1.5, 0.1],
        [5.5, 4.2, 1.4, 0.2],
        [4.9, 3.1, 1.5, 0.2],
        [5. , 3.2, 1.2, 0.2],
        [5.5, 3.5, 1.3, 0.2],
        [4.9, 3.6, 1.4, 0.1],
        [4.4, 3. , 1.3, 0.2],
        [5.1, 3.4, 1.5, 0.2],
        [5. , 3.5, 1.3, 0.3],
        [4.5, 2.3, 1.3, 0.3],
        [4.4, 3.2, 1.3, 0.2],
        [5. , 3.5, 1.6, 0.6],
        [5.1, 3.8, 1.9, 0.4],
        [4.8, 3. , 1.4, 0.3],
        [5.1, 3.8, 1.6, 0.2],
        [4.6, 3.2, 1.4, 0.2],
        [5.3, 3.7, 1.5, 0.2],
        [5. , 3.3, 1.4, 0.2],
        [7. , 3.2, 4.7, 1.4],
        [6.4, 3.2, 4.5, 1.5],
        [6.9, 3.1, 4.9, 1.5],
        [5.5, 2.3, 4. , 1.3],
        [6.5, 2.8, 4.6, 1.5],
        [5.7, 2.8, 4.5, 1.3],
        [6.3, 3.3, 4.7, 1.6],
        [4.9, 2.4, 3.3, 1. ],
        [6.6, 2.9, 4.6, 1.3],
        [5.2, 2.7, 3.9, 1.4],
        [5. , 2. , 3.5, 1. ],
        [5.9, 3. , 4.2, 1.5],
        [6. , 2.2, 4. , 1. ],
        [6.1, 2.9, 4.7, 1.4],
        [5.6, 2.9, 3.6, 1.3],
        [6.7, 3.1, 4.4, 1.4],
        [5.6, 3. , 4.5, 1.5],
        [5.8, 2.7, 4.1, 1. ],
        [6.2, 2.2, 4.5, 1.5],
        [5.6, 2.5, 3.9, 1.1],
        [5.9, 3.2, 4.8, 1.8],
        [6.1, 2.8, 4. , 1.3],
        [6.3, 2.5, 4.9, 1.5],
        [6.1, 2.8, 4.7, 1.2],
        [6.4, 2.9, 4.3, 1.3],
        [6.6, 3. , 4.4, 1.4],
        [6.8, 2.8, 4.8, 1.4],
        [6.7, 3. , 5. , 1.7],
        [6. , 2.9, 4.5, 1.5],
        [5.7, 2.6, 3.5, 1. ],
        [5.5, 2.4, 3.8, 1.1],
        [5.5, 2.4, 3.7, 1. ],
        [5.8, 2.7, 3.9, 1.2],
        [6. , 2.7, 5.1, 1.6],
        [5.4, 3. , 4.5, 1.5],
        [6. , 3.4, 4.5, 1.6],
        [6.7, 3.1, 4.7, 1.5],
        [6.3, 2.3, 4.4, 1.3],
        [5.6, 3. , 4.1, 1.3],
        [5.5, 2.5, 4. , 1.3],
        [5.5, 2.6, 4.4, 1.2],
        [6.1, 3. , 4.6, 1.4],
        [5.8, 2.6, 4. , 1.2],
        [5. , 2.3, 3.3, 1. ],
        [5.6, 2.7, 4.2, 1.3],
        [5.7, 3. , 4.2, 1.2],
        [5.7, 2.9, 4.2, 1.3],
        [6.2, 2.9, 4.3, 1.3],
        [5.1, 2.5, 3. , 1.1],
        [5.7, 2.8, 4.1, 1.3],
        [6.3, 3.3, 6. , 2.5],
        [5.8, 2.7, 5.1, 1.9],
        [7.1, 3. , 5.9, 2.1],
        [6.3, 2.9, 5.6, 1.8],
        [6.5, 3. , 5.8, 2.2],
        [7.6, 3. , 6.6, 2.1],
        [4.9, 2.5, 4.5, 1.7],
        [7.3, 2.9, 6.3, 1.8],
        [6.7, 2.5, 5.8, 1.8],
        [7.2, 3.6, 6.1, 2.5],
        [6.5, 3.2, 5.1, 2. ],
        [6.4, 2.7, 5.3, 1.9],
        [6.8, 3. , 5.5, 2.1],
        [5.7, 2.5, 5. , 2. ],
        [5.8, 2.8, 5.1, 2.4],
        [6.4, 3.2, 5.3, 2.3],
        [6.5, 3. , 5.5, 1.8],
        [7.7, 3.8, 6.7, 2.2],
        [7.7, 2.6, 6.9, 2.3],
        [6. , 2.2, 5. , 1.5],
        [6.9, 3.2, 5.7, 2.3],
        [5.6, 2.8, 4.9, 2. ],
        [7.7, 2.8, 6.7, 2. ],
        [6.3, 2.7, 4.9, 1.8],
        [6.7, 3.3, 5.7, 2.1],
        [7.2, 3.2, 6. , 1.8],
        [6.2, 2.8, 4.8, 1.8],
        [6.1, 3. , 4.9, 1.8],
        [6.4, 2.8, 5.6, 2.1],
        [7.2, 3. , 5.8, 1.6],
        [7.4, 2.8, 6.1, 1.9],
        [7.9, 3.8, 6.4, 2. ],
        [6.4, 2.8, 5.6, 2.2],
        [6.3, 2.8, 5.1, 1.5],
        [6.1, 2.6, 5.6, 1.4],
        [7.7, 3. , 6.1, 2.3],
        [6.3, 3.4, 5.6, 2.4],
        [6.4, 3.1, 5.5, 1.8],
        [6. , 3. , 4.8, 1.8],
        [6.9, 3.1, 5.4, 2.1],
        [6.7, 3.1, 5.6, 2.4],
        [6.9, 3.1, 5.1, 2.3],
        [5.8, 2.7, 5.1, 1.9],
        [6.8, 3.2, 5.9, 2.3],
        [6.7, 3.3, 5.7, 2.5],
        [6.7, 3. , 5.2, 2.3],
        [6.3, 2.5, 5. , 1.9],
        [6.5, 3. , 5.2, 2. ],
        [6.2, 3.4, 5.4, 2.3],
        [5.9, 3. , 5.1, 1.8]]),
 'target': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]),
 'frame': None,
 'target_names': array(['setosa', 'versicolor', 'virginica'], dtype='<U10'),
 'DESCR': '.. _iris_dataset:\n\nIris plants dataset\n--------------------\n\n**Data Set Characteristics:**\n\n    :Number of Instances: 150 (50 in each of three classes)\n    :Number of Attributes: 4 numeric, predictive attributes and the class\n    :Attribute Information:\n        - sepal length in cm\n        - sepal width in cm\n        - petal length in cm\n        - petal width in cm\n        - class:\n                - Iris-Setosa\n                - Iris-Versicolour\n                - Iris-Virginica\n                \n    :Summary Statistics:\n\n    ============== ==== ==== ======= ===== ====================\n                    Min  Max   Mean    SD   Class Correlation\n    ============== ==== ==== ======= ===== ====================\n    sepal length:   4.3  7.9   5.84   0.83    0.7826\n    sepal width:    2.0  4.4   3.05   0.43   -0.4194\n    petal length:   1.0  6.9   3.76   1.76    0.9490  (high!)\n    petal width:    0.1  2.5   1.20   0.76    0.9565  (high!)\n    ============== ==== ==== ======= ===== ====================\n\n    :Missing Attribute Values: None\n    :Class Distribution: 33.3% for each of 3 classes.\n    :Creator: R.A. Fisher\n    :Donor: Michael Marshall (MARSHAL
 'feature_names': ['sepal length (cm)',
  'sepal width (cm)',
  'petal length (cm)',
  'petal width (cm)'],
 'filename': 'iris.csv',
 'data_module': 'sklearn.datasets.data'}

MACHINE LEARNING DIVERSION END

Slice From the Start

x="Hello World"
print(x[2:5])
llo

the above piece of code explains the string slicing from index 2 to index 5 only that now index 5 is not inclusive here is how the slicing works hello-0 for h, 1-e,2-l,3-l,4-o so we can see that indexing starts from zero then progresses as we continue. In the cells below we shal;l also have negative indexing.

y="""This is a string """
x="Hello World"
print(x[-4:-2])
or

note you can’t use -2:-4 as -2 is greator than -$ so the order is as this , so lets see why we have the output. so we go to -4 counting from the right and end at o and then go to -2 counting from the right and end up at l which is not inclusive, the special case is that we are starting out count from -1 not 0 as in the normal case. We shall look at at a more interesting case that use the step in the cell below.

y="""This is a string """
x="Hello World"
print(x[-8:-2:2])
l o

In the above code we can see an additional 2 at the end which indicated the step size or the gap between the elements we want to get. Here we note that the gap is of 2 units that means from -8 we write it down and jump 2 steps to get -6 then write it down then to -4 and finally to -2 which is not inclusive. at -8 we find that we have l and at -6 we find that we have a gap and at -4 we have an o that is why we have the output above with a gap between l and o.

Python – Modify Strings

x=" Hello World "
print(x.upper())
print(x.lower())
print(x.strip())
x=x.replace("H", "ch")
print(x)
print(x.split())
 HELLO WORLD 
 hello world 
Hello World
 chello World 
['chello', 'World']

Explaining the output above wqe find that the .upper() method converts our string into an upper case also we find that the .lower() function converts the string into a lower case, finally we can see that the .strip gets rid of the spaces that were preceeding the string. These are the common types of python string modifications. We also see the .replace have replaced the H with ch this is also another modification that can be done to strings. The split method also splits the string into 2 words returning a list of the string content the contents take the list data structure.

Python – String Concatenation

x="Hello World"
y="Today is on a monday"
print(x+"",y)
Hello World Today is on a monday

in the above example we can witness concatenation ast the strings x and y are joined together using the + sign and also we can see that adding an empty space betwen them can be obtained by having a space betweenm the quotation marks

Python – Format – Strings

x=34
y=f"My age is {x}"
z="My age is {}"
print(y)
print(z.format(x))
My age is 34
My age is 34

The above code shows how we can achieve formatting as one of the ways we can use an f and also this is helpful as we can see that the we can use integers and strings together this means we can now not get worried about the data type we are using. Note in the socond print we have used the format method which is also an alternative this makes use also of the empty carry bracket.

Python – Escape Characters

Escape Character To insert characters that are illegal in a string, use an escape character.

An escape character is a backslash  followed by the character you want to insert.

x="Hello world\'s"
print(x)
Hello world's

In the above we note that the apostrophe is at the end of the s where we note another  backslash that tells our computer what that is.

x="""hello world.\nWe shall code today"""
print(x)
hello world.
We shall code today

In the above the x shall be the one we are experimentinmg with and we see that we shall have a new line where the next line after \n will be printed note python is intelligent enough to know that the \n is an escape character and that it means print in a new line.

Python Booleans

print(12>10)
True

The above is a boolean argument that shows True when the value 12 is greator than 10 if 10 was less than 12 it would show False ie print(10>12)

print(10>12)#False
print(10 == 1)#False
print(12<10)#True
False
False
False

Evaluate Values and Variables

print(bool(0))
print(bool(12))
print(bool("Charles"))
print(bool())
False
True
True
False

Most Values are True

a=bool("A,B,C")#True
b=bool(123)#True
c=bool([1,2,3,4,5,6,7])#True
d=bool(0)#False
e=bool(" ")#False
print(a,b,c,d,e)#Output
True True True False True

Some Values are False

bool(False)
bool(None)
bool(0)
bool("")
bool(())
bool([])
bool({})
#All these will return False
False
class monkey():
  def __init__(self):
    return None

animal=monkey()
print(bool(animal))
True
class myclass():
  def __len__(self):
    return 0

myobj = myclass()
print(bool(myobj))
False

Functions can Return a Boolean

def myfunction():
  return True


myfunction()
True

The above piece of code shows a function myfunction() and it returns True as the otput which is a boolean Data Type

def myfunction():
  return True

if myfunction():
   print(True)
else:
   print(False)
True

This is the code that shows if the condition is set and prints out if False once the condition of the function is False otherwise True if the condition is True

Check if an object is an integer or not:

x=1000
print(isinstance(x, int))
print(isinstance(x, str))
True
False

The above returns True if the X value is an integer and False if X is not an integer In this case the X was being tested with the str to show if it is a string. that is in the second part.

Python Operators

Python divides the operators in the following groups:

  1. Arithmetic operators
  2. Assignment operators
  3. Comparison operators
  4. Logical operators
  5. Identity operators
  6. Membership operators
  7. Bitwise operators

Python Arithmetic Operators

x=20
y=15
print(x-y," subtraction")#subtraction
print(x+y," addition")#addition
print(x/y," division")#division
print(x*y, " multiplication")#multiplication
print(x//y, " getting the floor")#getting the floor
print(xprint(x**y, " getting the exponential")#getting the exponential
5  subtraction
35  addition
1.3333333333333333  division
300  multiplication
1  getting the floor
5  getting the remaider or Modulus
32768000000000000000  getting the exponential

Python Assignment Operators

x = 5
print(x, "Assignment Operator")
x += 5
print(x, "Assignment Operator")
x = 5
x -= 5
print(x, "Assignment Operator")
x = 5
x /= 3
print(x, "Assignment Operator")
x = 5
x print(x, "Assignment Operator")
x = 5
x **= 3
print(x, "Assignment Operator")
x = 5
x //= 3
print(x, "Assignment Operator")
x = 5
x ^= 3
print(x, "Assignment Operator")
x = 5
x >>= 3
print(x, "Assignment Operator")
x = 5
x <<= 3
print(x, "Assignment Operator")
x = 5
x *= 3
print(x, "Assignment Operator")
x = 5
x |= 3
print(x, "Assignment Operator")
5 Assignment Operator
10 Assignment Operator
0 Assignment Operator
1.6666666666666667 Assignment Operator
2 Assignment Operator
125 Assignment Operator
1 Assignment Operator
6 Assignment Operator
0 Assignment Operator
40 Assignment Operator
15 Assignment Operator
7 Assignment Operator
print("""

+=: Adds the right operand to the left operand and assigns the result to the left operand. For example, x += 5 is equivalent to x = x + 5.


-=: Subtracts the right operand from the left operand and assigns the result to the left operand. For example, x -= 5 is equivalent to x = x - 5.


/=: Divides the left operand by the right operand and assigns the result to the left operand. For example, x /= 3 is equivalent to x = x / 3.




**=: Raises the left operand to the power of the right operand and assigns the result to the left operand. For example, x **= 3 is equivalent to x = x ** 3.


//=: Performs floor division on the left operand by the right operand and assigns the result to the left operand. For example, x //= 3 is equivalent to x = x // 3.


^=: Performs bitwise XOR (^) on the left and right operands and assigns the result to the left operand. For example, x ^= 3 is equivalent to x = x ^ 3.


>>=: Performs bitwise right shift (>>) on the left operand by the number of bits specified by the right operand and assigns the result to the left operand. For example, x >>= 3 is equivalent to x = x >> 3.


<<=: Performs bitwise left shift (<<) on the left operand by the number of bits specified by the right operand and assigns the result to the left operand. For example, x <<= 3 is equivalent to x = x << 3.


*=: Multiplies the left operand by the right operand and assigns the result to the left operand. For example, x *= 3 is equivalent to x = x * 3.


|=: Performs bitwise OR (|) on the left and right operands and assigns the result to the left operand. For example, x |= 3 is equivalent to x = x | 3.""")


+=: Adds the right operand to the left operand and assigns the result to the left operand. For example, x += 5 is equivalent to x = x + 5.


-=: Subtracts the right operand from the left operand and assigns the result to the left operand. For example, x -= 5 is equivalent to x = x - 5.


/=: Divides the left operand by the right operand and assigns the result to the left operand. For example, x /= 3 is equivalent to x = x / 3.




**=: Raises the left operand to the power of the right operand and assigns the result to the left operand. For example, x **= 3 is equivalent to x = x ** 3.


//=: Performs floor division on the left operand by the right operand and assigns the result to the left operand. For example, x //= 3 is equivalent to x = x // 3.


^=: Performs bitwise XOR (^) on the left and right operands and assigns the result to the left operand. For example, x ^= 3 is equivalent to x = x ^ 3.


>>=: Performs bitwise right shift (>>) on the left operand by the number of bits specified by the right operand and assigns the result to the left operand. For example, x >>= 3 is equivalent to x = x >> 3.


<<=: Performs bitwise left shift (<<) on the left operand by the number of bits specified by the right operand and assigns the result to the left operand. For example, x <<= 3 is equivalent to x = x << 3.


*=: Multiplies the left operand by the right operand and assigns the result to the left operand. For example, x *= 3 is equivalent to x = x * 3.


|=: Performs bitwise OR (|) on the left and right operands and assigns the result to the left operand. For example, x |= 3 is equivalent to x = x | 3.

Python Comparison Operators

x=25
y=20
print(x==y, "checks if x is equal to y")#checks if x is equal to y
print(x!=y, "checks if x is not Equal to y")#checks if x is not Equal to y
print(x<=y, "checks if x is less than or equal to y")#checks if x is less than or equal to y
print(x>=y,"checks if x is greator than or equal to y")#checks if x is greator than or equal to y
print(x>y, "checkls if x is greator than y")#checkls if x is greator than y
print(x<y, "checks if x is less than y")#checks if x is less than y
False checks if x is equal to y
True checks if x is not Equal to y
False checks if x is less than or equal to y
True checks if x is greator than or equal to y
True checkls if x is greator than y
False checks if x is less than y

Python Logical Operators

x=20
y=15
print(x<y and X>y)#x is less than y is false and x is greator than y is true thus and returns true if both statements are true
print(x>y or x==y)#x is greator than y is true and x is equal to y is false this now makes or return true if either is true and false if none is true.
#If both are false, the "or" expression will be false.
print(not(x>y and x!=y))#the not returns false if the outpu was true and True if the output was false.
#here the output is true as x is greator than y and also x is not equal to y thus adding not makes it return Fasle
False
True
False

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:

is Returns True if both variables are the same object x is y

is not Returns True if both variables are not the same object x is not y

x=[1,2,3,4,5,6,7,8,9]
y=x
print(2  in x)
print(122 not in x)
print(x is [1,2,3,4,5,6,7,8,9])
print(x is y)
True
True
False
True

Let’s break down the code:

x=[1,2,3,4,5,6,7,8,9]: This creates a list x containing the numbers 1 to 9.

y=x: This assigns the list x to the variable y. Now, y also refers to the same list as x.

print(2 in x): This checks if the value 2 is present in the list x. Since 2 is in the list, this will print True.

print(122 not in x): This checks if the value 122 is not present in the list x. Since 122 is not in the list, this will print True.

print(x is [1,2,3,4,5,6,7,8,9]): This checks if the variable x is exactly the same object as the list [1,2,3,4,5,6,7,8,9]. However, even though the contents of x and [1,2,3,4,5,6,7,8,9] are the same, they are not the same object in memory. So, this will print False.

Python Membership Operators Membership operators are used to test if a sequence is presented in an object

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

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

x={"key":12, 12:"Srtring", True:"Yes"}
print(12 not in x)#returns False
print(12 in x)#returns True
print("key" in x )#returns True as the key "key " is in x
print("Yes" in x)
False
True
True
False

Python Lists List Lists are used to store multiple items in a single variable.

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

Lists are created using square brackets:

x=[1,2,3,4,5,6,7,8,9]
print(x)
print(type(x))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
<class 'list'>
x=list((1,2,3,4,5,6,7,8,9))
print(x)
print(type(x))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
<class 'list'>
x=list([1,2,3,4,5,6,7,8,9])
print(x)
print(type(x))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
<class 'list'>

In the above three code : We see that the list bdata structure in python can be created in different ways the secxond parts shows creating the lists using the list constructor, on the other hand you can create a list data structure using the square carry brackets or use the list constructor.

List Items

List items in Python lists are ordered, changeable, and allow duplicate values.

Ordered

Lists maintain the order in which items are added. When new items are added, they are placed at the end of the list. While there are methods that can change the order, the general rule is that the order remains the same.

Changeable

Lists are mutable, meaning you can change, add, and remove items from a list after it has been created.

Allow Duplicates

Lists can contain duplicate values. Since lists are indexed, items with the same value can exist in the list.

Example: Lists allow duplicate values:

“`python my_list = [1, 2, 3, 3, 4, 5] print(my_list)

thislist = ["apple", "banana", "cherry", "apple", "cherry"]
print(thislist)
['apple', 'banana', 'cherry', 'apple', 'cherry']

IN THE ABOVE CODE WE CAN SEE THAT

Apple is dublicated thus creating a dublicate.

c=list((1,2,3,4,5,66,66))
c
[1, 2, 3, 4, 5, 66, 66]

in the above code we see that the number 66 is repeated twice and python list allows that but in python sets that is not allowed

#creating a list and accessing the list
d=[11,22,33,4,5,6,7,8,9]
print(d[2])#to access number 33
33

Analysing the code above we see that the index of number 33 is 2 and thus to get the elements we start counting from 0 and progress.

e = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
for x in enumerate(e):
    print(x[0], "is the index of", x[1])
0 is the index of 11
1 is the index of 2
2 is the index of 3
3 is the index of 4
4 is the index of 5
5 is the index of 6
6 is the index of 7
7 is the index of 8
8 is the index of 9
9 is the index of 10
10 is the index of 11
11 is the index of 12
12 is the index of 13
13 is the index of 14
14 is the index of 15

In the above code we see that the index is iterated using the for loop and we can get the index for all the list items thus we see that the index are counted from 0and this is matched to the first element in the list. The enumerate function returns tuples (index, value) for each element in the list

e = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
for x in enumerate(e):
    print(x[0], "is the index of", x[1])
    if x[1] == e[3]:#this will count until index 3 starting from 0
      break
0 is the index of 11
1 is the index of 2
2 is the index of 3
3 is the index of 4
e = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
for x in enumerate(e):
    print(x[0], "is the index of", x[1])
    if x[1] == 3:#this will give the output until where we have the x value as 3 thus only three loops will be performed.
      break
0 is the index of 11
1 is the index of 2
2 is the index of 3

Access Items in a list

q=[11,112,333,444,556,678,897,890,409,109]
print(q[5])#this prints the fifth index item that is 678 after counting them from index 0
678
r=[112,33,44,55,66,66,77,88,990]
print(r[-5:-1])#note that -1 is not inclusive when indexing the elements in the list thus we only get elements listed until index 2
[66, 66, 77, 88]
s=[1,2,3,4,5,6,7,8,9,10]
print(s[0:5])#this lists all elements from index 0 that is the first elem,ent to the fourth element as index 5 element is not included.
print(s[5:])#This starts to print from index 5 onwards
[1, 2, 3, 4, 5]
[6, 7, 8, 9, 10]

The above code can be what we say is slicing of lists or getting a range of the list data in the cell below we shall remind ourselves about slicing of strings.

q="Hello world"
print(q[0:5])#This will print the word hello note the word hello has upto index 4 but to print to index 4 inclusive we set the upper limit to index 5
print(q[:5])#prints the same
Hello
Hello

Checking if an item is in the list bold text

l=[1,2,3,4,5,6,7,8,9,10]
for x in l:
  print(x, end=" ")
1 2 3 4 5 6 7 8 9 10 

in the above code we iterate the list and we find that we iterate through the list and we find that a for loop does it well.

Check if Item Exists

l=[1,2,3,4,5,6,7,8,9,10]
for x in l:
  print(x, end=", ")

if 2 in l:
  print(2,"Is in the list")
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2 Is in the list
g=[1,2,3,4,5,6,7,8,9,109]
if 2 not in g:
  print("Yes 122 not in g")
else:
  print("No it\'s in q")
No it's in q

in the above code we see that we can check if the elements in a list are present or not and also we can check if they are there in the list.

Python – Change List Items

f=[1,2,3,4,5,6,7,8,9]
f[5]=1223
print(f)
[1, 2, 3, 4, 5, 1223, 7, 8, 9]

From the above we note that we can change list items after identifying their position using idexing, in this case we can see that item in index 5 is 6 and thus this is changed to the value 1223

#we can also change a range of items in a list
g=[1,2,3,4,5,6,7,8,9]
g[2:5]=[1,11,11,23]
print(g)
print(type(g))
[1, 2, 1, 11, 11, 23, 6, 7, 8, 9]
<class 'list'>

in the above piece of code we can see that the range is given from the index 2 to index 5 now our main focus is to first identify index 2 then traverse to index 5 note that the index 5 is not inclusive of the change as the range only affects the first 4 elements.

f=[112.22,223,456,678,989,78989]
f[2:]=[100]#this alters the index 2 and thus we have the item at index number 2 being affected and changing to 100
print(f)
[112.22, 223, 100]

Insert Items To insert a new list item, without replacing any of the existing values, we can use the insert() method.

The insert() method inserts an item at the specified index:

j = [1, 2, 3, 4, 5, 6, 7, 8, 9]
j[1:1] = [223, 3, 99]
print(j)
[1, 223, 3, 99, 2, 3, 4, 5, 6, 7, 8, 9]

This will insert the elements [223, 3, 99] at index 1 in the list j. j[1:1] refers to a slice of the list j starting at index 1 and ending just before index 1, which effectively selects an empty slice at index 1. After this operation, the list j will contain [1, 223, 3, 99, 2, 3, 4, 5, 6, 7, 8, 9], with the elements [223, 3, 99] inserted at index 1.

Python – Add List Items

#in the code below we shall add alist of items in it by using append()
d=[1,2,3,4,5,6,7,8,9,10]
d.append(100)
print(d)#note that append does not return a new list thus you should use it as we have used.
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100]

If you tried to assign a variable to the d.append you would get none as the retuned value this is because append does not return any value, also note that append only takes one argument and giving many arguments to append you will enconter an error thus we have given one argument that is value 100

Insert Items To insert a list item at a specified index, use the insert() method.

The insert() method inserts an item at the specified index:

f=[1,2,3,4,5,6,7,8,9,10]
f.insert(1, 266566)
f
[1, 266566, 2, 3, 4, 5, 6, 7, 8, 9, 10]

The above piece of code i used to insert the given value 266566 into the position of index 1 in the list, the item in index 1 is 2 and this is where the value is going to be inserted.

#in the code below we shall try to insert the number in the second value
z=[1,2,3,4,5,6,7,8,9]
z.insert(2, 666)#this is going to insert the given number 666 to the index 2 thus index 2 will be index 3 after the operation
z
[1, 2, 666, 3, 4, 5, 6, 7, 8, 9]

Extend List To append elements from another list to the current list, use the extend() method.

w=[1,2,3,4,5,6,7,8,9]
z=[11,22,33,44,55,66]

#we are going to extend list w with list z and after the extending they are going to merge and form one long list.
#thus we have
z.extend(w)
z
[11, 22, 33, 44, 55, 66, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In the above piece of code we find that the extending operation has taken place and we see that the list w has been concatenated to list z this is what we call extrending of python lists, it is useful as they help in modifying the list data type

c=[1,2,3,4,5,6,7]#this is a list data structure
d=(11,22,33,44,55)#This is a tuple data structure
e={12,13,154.78}#this is a set data structure
c.extend(d)#here we are extending the list data structure with the tuple data structure
c.extend(e)#here we are extending the list data structure with the set data structure
print(c)
[1, 2, 3, 4, 5, 6, 7, 11, 22, 33, 44, 55, 154.78, 12, 13]

From the above example we can always extend the list with other iteratable datastructures this is what we have implemented in the above example.

bold textPython – Remove List Items

d=[1,2,3,4,5,6,7,8]
d.remove(1)
print(d)
[2, 3, 4, 5, 6, 7, 8]

in the above piece of code we can see that the .remove function is being bused to remove the element 1 from our list, using the .remove() we can get rid of item we don’t need in our list the above example is a good example to explain that.

Note in the .remove() we don’t need to give the index of the item to remove we just list it and get rid of it right away that is the beauty of.remove()

s=[11,22,333,44,55]
#we shall use pop to get rid of a specified index here we shall pop index 2 from the list
s.pop(2)# we expect element 333 to be removed from the list as it is in index 2,
#recall that we count the index starting with 0 then increase...
s
[11, 22, 44, 55]

What if we want to delete the list completly we can use the keyword del in the example below we shall see how del can be used to delete a list completly

d=[1,2,3,4,5,6,7,8,9]
print(d)#the list d is printed again
del d#the list d is deleted
#this should return none as the list dosen't exist or name 'd' is not defined
#print(d)
[1, 2, 3, 4, 5, 6, 7, 8, 9]

Clear the List The clear() method empties the list.

The list still remains, but it has no content.

c=list((1,2,3,4,54,6,7,8,9))
c.clear()#this cleares all the items in the list to give an empty list thus the output will be an empty list.
c
[]

Python – Loop Lists Loop Through a List You can loop through the list items by using a for loop:

#in this example we shall use a for loop to loop thropuigh the items in the lis
c=[11,22,33,44,55,66,77,88,99,100]
for x in c:
  print(x, end=", ")#the end=", " is used to make4 the list have a horizontal order.
11, 22, 33, 44, 55, 66, 77, 88, 99, 100, 
d=[111,222,333,444,555,666,777]
for x in enumerate(d):
  print(x[0], "is index ", x[1])#this is to print bthe index and the value
0 is index  111
1 is index  222
2 is index  333
3 is index  444
4 is index  555
5 is index  666
6 is index  777
thislist = ["apple", "banana", "cherry"]
i = 0
while i < len(thislist):
  print(thislist[i])
  i = i + 1
apple
banana
cherry
thislist = ["apple", "banana", "cherry"]
[print(x) for x in thislist]
#A short hand for loop that will print all items in a list
apple
banana
cherry
[None, None, None]

Python – List Comprehension List Comprehension List comprehension offers a shorter syntax when you want to create a new list based on the values of an existing list.

Example:

Based on a list of fruits, you want a new list, containing only the fruits with the letter “a” in the name.

Without list comprehension you will have to write a for statement with a conditional test inside:

Example

#With list comprehension you can do all that with only one line of code
fruits = ["apple", "banana", "cherry", "kiwi", "mango"]

newlist = [x for x in fruits if "a" in x]

print(newlist)
['apple', 'banana', 'mango']

The Syntax newlist = [expression for item in iterable if condition == True]

The return value is a new list, leaving the old list unchanged.

Condition The condition is like a filter that only accepts the items that valuate to True.

Example Only accept items that are not “apple”:

newlist = [x for x in fruits if x != "apple"]
newlist
['banana', 'cherry', 'kiwi', 'mango']

The condition if x != “apple” will return True for all elements other than “apple”, making the new list contain all fruits except “apple”.

The condition is optional and can be omitted:

Example With no if statement:

newlist = [x for x in fruits]
newlist
['apple', 'banana', 'cherry', 'kiwi', 'mango']

Iterable The iterable can be any iterable object, like a list, tuple, set etc.

Example You can use the range() function to create an iterable:

newlist = [x for x in range(10)]
newlist
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Same example, but with a condition:

Example Accept only numbers lower than 5:

newlist = [x for x in range(10) if x < 5]
newlist
[0, 1, 2, 3, 4]

Expression The expression is the current item in the iteration, but it is also the outcome, which you can manipulate before it ends up like a list item in the new list:

Example Set the values in the new list to upper case:

newlist = [x.upper() for x in fruits]

You can set the outcome to whatever you like:

Example Set all values in the new list to ‘hello’:

newlist = ['hello' for x in fruits]

The expression can also contain conditions, not like a filter, but as a way to manipulate the outcome:

Example Return “orange” instead of “banana”:

newlist = [x if x != "banana" else "orange" for x in fruits]

Python – Sort Lists

Sort List Alphanumerically List objects have a sort() method that will sort the list alphanumerically, ascending, by default:

Example

Sort the list alphabetically:

z=[1,22,3,4,5,6,55,44,43,32]
z.sort()
z
[1, 3, 4, 5, 6, 22, 32, 43, 44, 55]

Sort Descending To sort descending, use the keyword argument reverse = True:

Example Sort the list descending:

thislist = ["orange", "mango", "kiwi", "pineapple", "banana"]
thislist.sort(reverse = True)
print(thislist)
['pineapple', 'orange', 'mango', 'kiwi', 'banana']
z=[11,22,1,2,3,4,5,22,34,34,33,2323,222,112,12332333]
z.sort(reverse=True)#reversing the acending order to get the descending order
z
[12332333, 2323, 222, 112, 34, 34, 33, 22, 22, 11, 5, 4, 3, 2, 1]

Python – Copy Lists Copy a List You cannot copy a list simply by typing list2 = list1, because: list2 will only be a reference to list1, and changes made in list1 will automatically also be made in list2.

There are ways to make a copy, one way is to use the built-in List method copy().

Example

z=[1,23,4687878,4,5,6,7,8,9,10]
u=z.copy()#method one of copying a list
u
[1, 23, 4687878, 4, 5, 6, 7, 8, 9, 10]
q=[1,2,3,4,5,6,7,8,9]
r=list(q)#method 2 of copying a list
r
[1, 2, 3, 4, 5, 6, 7, 8, 9]

Python – Join Lists Join Two Lists There are several ways to join, or concatenate, two or more lists in Python.

One of the easiest ways are by using the + operator.

Example

z=[1,2,3,4,5,6,7,8,9]
q=[11,22,33,44,55,66,77,88]
j=q+z#joining of lists taking place here
print(j)
[11, 22, 33, 44, 55, 66, 77, 88, 1, 2, 3, 4, 5, 6, 7, 8, 9]
list1 = ["a", "b", "c"]
list2 = [1, 2, 3]

list3 = list1 + list2
print(list3)
['a', 'b', 'c', 1, 2, 3]

Another way to join two lists is by appending all the items from list2 into list1, one by one:

Example Append list2 into list1:

x=[1,2,3,45,6,7,8,910]
z=[11,23,44,56,78,9,309]
x.append(z)
x
[1, 2, 3, 45, 6, 7, 8, 910, [11, 23, 44, 56, 78, 9, 309]]
x=list((1,2,3,4,5,6,7,8,9))
y=list([11,22,33,44,55,66,77,88,99])
x.extend(y)#this extend functionality is used to extend the list x with list y
x
[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99]

Python List Methods

Python provides several built-in methods that you can use on lists:

  • append(): Adds an element at the end of the list.
  • clear(): Removes all elements from the list.
  • copy(): Returns a copy of the list.
  • count(): Returns the number of elements with the specified value.
  • extend(): Adds 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(): Adds an element at the specified position.
  • pop(): Removes the element at the specified position.
  • remove(): Removes the item with the specified value.
  • reverse(): Reverses the order of the list.
  • sort(): Sorts the list.

You can use these methods to manipulate and work with lists in Python efficiently.

x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
y = [11, 22, 33, 44, 55, 66, 77, 88, 99]

# index(value): Returns the index of the first element with the specified value.
print(x.index(4))

# remove(value): Removes the first occurrence of the specified value.
x.remove(2)
print(x)

# append(value): Adds the specified value at the end of the list.
x.append(1)
print(x)

# clear(): Removes all items from the list.
x.clear()
print(x)

# copy(): Returns a copy of the list.
x = y.copy()
print(x)

# count(value): Returns the number of elements with the specified value.
print(x.count(1))

# extend(iterable): Adds the elements of an iterable (list, tuple, string etc.) to the end of the list.
x.extend(y)
print(x)

# insert(index, value): Inserts the specified value at the specified position.
x.insert(2, 22)
print(x)

# pop(index): Removes the element at the specified index and returns it.
print(x.pop(3))
print(x)

# remove(value): Removes the first occurrence of the specified value.
x.remove(99)
print(x)

# reverse(): Reverses the order of the list.
x.reverse()
print(x)

# sort(): Sorts the list.
x.sort()
print(x)
3
[1, 3, 4, 5, 6, 7, 8, 9]
[1, 3, 4, 5, 6, 7, 8, 9, 1]
[]
[11, 22, 33, 44, 55, 66, 77, 88, 99]
0
[11, 22, 33, 44, 55, 66, 77, 88, 99, 11, 22, 33, 44, 55, 66, 77, 88, 99]
[11, 22, 22, 33, 44, 55, 66, 77, 88, 99, 11, 22, 33, 44, 55, 66, 77, 88, 99]
33
[11, 22, 22, 44, 55, 66, 77, 88, 99, 11, 22, 33, 44, 55, 66, 77, 88, 99]
[11, 22, 22, 44, 55, 66, 77, 88, 11, 22, 33, 44, 55, 66, 77, 88, 99]
[99, 88, 77, 66, 55, 44, 33, 22, 11, 88, 77, 66, 55, 44, 22, 22, 11]
[11, 11, 22, 22, 22, 33, 44, 44, 55, 55, 66, 66, 77, 77, 88, 88, 99]

Python Tuples

1. Tuples are used to store multiple items in a single variable.

Tuples are similar to lists but are immutable, meaning their elements cannot be changed once they are assigned. They are useful for storing related pieces of information together.

2. Tuple is one of 4 built-in data types in Python used to store collections of data, the other 3 are List, Set, and Dictionary, all with different qualities and usage.

This statement highlights that tuples are a fundamental data type in Python for storing collections. Lists are mutable, sets are unordered collections of unique items, and dictionaries are key-value pairs.

3. A tuple is a collection which is ordered and unchangeable.

Tuples maintain the order of elements and cannot be modified after creation. Once a tuple is created, its elements cannot be changed, added, or removed.

4. Tuples are written with round brackets.

In Python, tuples are defined using parentheses (). For example, my_tuple = (1, 2, 3) creates a tuple with three elements.

x=tuple(("qwerty keyboard", 1,2,3,4,5,12.7,12j,'Son Of Man'))
print(x, type(x))
('qwerty keyboard', 1, 2, 3, 4, 5, 12.7, 12j, 'Son Of Man') <class 'tuple'>
x=(1,2,3,4,5,6,7,8,9)
print(type(x))
x
<class 'tuple'>
(1, 2, 3, 4, 5, 6, 7, 8, 9)

Python Tuples

1. Tuple Items are Ordered: Tuples maintain the order of their elements, meaning the position of each item is fixed and will not change.

2. Tuple Items are Indexed: Each item in a tuple has an index, starting from 0 for the first item, allowing for easy access to specific elements.

3. Ordered: This reiterates that tuples preserve the order of their elements, distinguishing them from sets, which are unordered collections.

4. Unchangeable: Once a tuple is created, its elements cannot be changed, added, or removed, making tuples immutable data structures.

5. Allow Duplicates: Tuples can contain duplicate values, and because they are ordered, duplicates will retain their positions in the tuple.

#Tuples allow duplicate values
x=tuple((0,1,1,1,2,3,4,5,6,7,8,9,2,2,3,4,5,6,7,8,9))
x
(0, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 2, 2, 3, 4, 5, 6, 7, 8, 9)

Tuple Length

To determine how many items a tuple has, use the len() function:

x=(1,2,3,4,5,6,7,8,9,10)
print(len(x))
10

Create Tuple With One Item To create a tuple with only one item, you have to add a comma after the item, why otherwise Python will not recognize it as a tuple.

x=tuple((1,))#this is a tuple with one element
z=(z,)#This is a truple
y=(1)#This is not a tuple
print(type(x))#this is a tuple
print(type(y))#This is not a tuple
print(y)#This is not a tuple
x#This is a tuple
<class 'tuple'>
<class 'int'>
1
(1,)
thistuple = ("apple",)
print(type(thistuple))

#NOT a tuple
thistuple = ("apple")
print(type(thistuple))
<class 'tuple'>
<class 'str'>

Tuple Items – Data Types Tuple items can be of any data type:

tuple1 = ("apple", "banana", "cherry")#this a string based tuple
tuple2 = (1, 5, 7, 9, 3)#this is an integer based tuple
tuple3 = (True, False, False)#this is aboolean based tuple
tuple4 = (12j, 13j,14j, 15j, 16j, 17j)#this is a complex number based tuple
print(tuple1, tuple2, tuple3, tuple4)#this is the fubction to display the output
('apple', 'banana', 'cherry') (1, 5, 7, 9, 3) (True, False, False) (12j, 13j, 14j, 15j, 16j, 17j)

A tuple can contain different data types:

Example

A tuple with strings, integers and boolean values:

tuple1 = (“abc”, 34, True, 40, “male”)

tuple1 = ("abc", 34, True, 40, "male")
tuple1
('abc', 34, True, 40, 'male')

type() From Python’s perspective, tuples are defined as objects with the data type ‘tuple’:

Example What is the data type of a tuple?

mytuple = (“apple”, “banana”, “cherry”) print(type(mytuple))

mytuple = ("apple", "banana", "cherry")
print(type(mytuple))
<class 'tuple'>

The tuple() Constructor It is also possible to use the tuple() constructor to make a tuple.

thistuple = tuple(("apple", "banana", "cherry")) # note the double round-brackets
print(thistuple)
('apple', 'banana', 'cherry')

Python Collections (Arrays)

Python offers four main collection data types:

1. List:

  • A list is a collection that is ordered and changeable.
  • It allows duplicate members, meaning you can have the same value multiple times in a list.
  • Lists are created using square brackets [].
  • Example: my_list = [1, 2, 3, 3, 4]

2. Tuple:

  • A tuple is a collection that is ordered and unchangeable.
  • It allows duplicate members.
  • Tuples are created using parentheses ().
  • Example: my_tuple = (1, 2, 3, 3, 4)

3. Set:

  • A set is a collection that is unordered, unchangeable, and unindexed.
  • It does not allow duplicate members, so each element is unique.
  • Sets are created using curly braces {}.
  • Example: my_set = {1, 2, 3, 4}

4. Dictionary:

  • A dictionary is a collection that is ordered (as of Python 3.7) and changeable.
  • It does not allow duplicate keys, but values can be duplicated.
  • Dictionaries are created using curly braces {} and key-value pairs.
  • Example: my_dict = {"key1": "value1", "key2": "value2"}

Python – Access Tuple

Items Access Tuple Items You can access tuple items by referring to the index number, inside square brackets:

thistuple = ("apple", "banana", "cherry")
print(thistuple[1])
banana

Negative Indexing in Python

Negative indexing is a feature in Python that allows you to access elements from the end of a sequence, such as a list or a tuple. When you use negative indices, Python starts counting from the end of the sequence, with -1 referring to the last item, -2 referring to the second last item, and so on.

Example:

Consider a list my_list = [10, 20, 30, 40, 50]. Using negative indexing, you can access elements as follows:

  • my_list[-1] would return 50, which is the last item in the list.
  • my_list[-2] would return 40, the second last item.
  • my_list[-3] would return 30, the third last item.
  • And so on…

Usage:

Negative indexing can be useful when you need to access elements from the end of a sequence without knowing its length. It provides a convenient way to access items from the end of a list or tuple without having to calculate the index manually.

Note:

  • Negative indexing works with strings, lists, tuples, and other sequence types in Python.
  • When using negative indices, remember that -1 refers to the last item, -2 refers to the second last item, and so on.

Range of Indexes in Python

You can specify a range of indexes in Python to extract a portion of a sequence, such as a list or tuple. The syntax for specifying a range is [start:end], where start is the index to start from (inclusive) and end is the index to end at (exclusive).

Example:

Consider a tuple thistuple = ("apple", "banana", "cherry", "orange", "kiwi", "melon", "mango"). To extract the third, fourth, and fifth items, you would use the range [2:5] as follows:

“`python thistuple = (“apple”, “banana”, “cherry”, “orange”, “kiwi”, “melon”, “mango”) print(thistuple[2:5])

thistuple = ("apple", "banana", "cherry", "orange", "kiwi", "melon", "mango")
print(thistuple[2:5])
('cherry', 'orange', 'kiwi')
thistuple = ("apple", "banana", "cherry", "orange", "kiwi", "melon", "mango")
print(thistuple[:4])
('apple', 'banana', 'cherry', 'orange')
thistuple = ("apple", "banana", "cherry", "orange", "kiwi", "melon", "mango")
print(thistuple[2:])
('cherry', 'orange', 'kiwi', 'melon', 'mango')

Python – Update Tuples

Tuples are unchangeable, meaning that you cannot change, add, or remove items once the tuple is created.

But there are some workarounds.

Change Tuple Values Once a tuple is created, you cannot change its values. Tuples are unchangeable, or immutable as it also is called.

But there is a workaround. You can convert the tuple into a list, change the list, and convert the list back into a tuple.

x = ("apple", "banana", "cherry")#this is a tuple
y = list(x)#this is converting the tuple into a list
y[1] = "kiwi"#This is the section where we shall add the item "kiwi" on the list at index 1
x = tuple(y)#This is the section that we are going to convert the list back into a tuple

print(x)#outputing the tuple
('apple', 'kiwi', 'cherry')
x=tuple((1,2,3,4,5,6))
y=list(x)
y[2]=666
x=tuple(y)
x
(1, 2, 666, 4, 5, 6)

Add Items

Since tuples are immutable, they do not have a built-in append() method, but there are other ways to add items to a tuple.

  1. Convert into a list: Just like the workaround for changing a tuple, you can convert it into a list, add your item(s), and convert it back into a tuple
x=tuple((1,2,3,4,5,6))
y=[11,22,33,44,55,66,77]
z=list(x)
z.append(y)
print(z)
[1, 2, 3, 4, 5, 6, [11, 22, 33, 44, 55, 66, 77]]
thistuple = ("apple", "banana", "cherry")
y = list(thistuple)
y.append("orange")
thistuple = tuple(y)
thistuple
('apple', 'banana', 'cherry', 'orange')
  1. Add tuple to a tuple. You are allowed to add tuples to tuples, so if you want to add one item, (or many), create a new tuple with the item(s), and add it to the existing tuple:

Example Create a new tuple with the value “orange”, and add that tuple:

thistuple = ("apple", "banana", "cherry")
y = ("orange",)
thistuple += y

print(thistuple)
('apple', 'banana', 'cherry', 'orange')
x=(1,2,3,4,5,6)
y=(7,8,9,10)
z=x+y
print(z)
print(type(z))
print(len(z))
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
<class 'tuple'>
10

Remove Items Note: You cannot remove items in a tuple.

Tuples are unchangeable, so you cannot remove items from it, but you can use the same workaround as we used for changing and adding tuple items:

thistuple = ("apple", "banana", "cherry")
y = list(thistuple)
y.remove("apple")
thistuple = tuple(y)
thistuple#this is a good way to output the output in python colab or anaconda
('banana', 'cherry')
thistuple = ("apple", "banana", "cherry")
y = list(thistuple)
y.pop(0)#using pop where it used index referencing
thistuple = tuple(y)
thistuple#this is a good way to output the output in python colab or anaconda
('banana', 'cherry')

Or you can delete the tuple completely:

#The del keyword can be used to delete the tuple completly
thistuple=tuple((1,2,3,4,5,6,7,8,9))
del thistuple
#print(thistuple)#we expect and error as the output as the tuple "thistuple" has been deleted

Python – Unpack Tuples Unpacking a Tuple When we create a tuple, we normally assign values to it. This is called “packing” a tuple:

fruits = ("apple", "banana", "cherry")
(green, yellow, red)=fruits
print(green)
print(yellow)
print(red)
apple
banana
cherry
#unpacking in strings
string="hello", "world"
a,b=string
print(a)
print(b)
hello
world
fruits = ("apple", "mango", "papaya", "pineapple", "cherry")

(green, *tropic, red) = fruits

print(green)#this prints out the first one
print(tropic)#this prints the middle ones
print(red)#this prints the last one
apple
['mango', 'papaya', 'pineapple']
cherry
fruits = ("apple", "banana", "cherry", "strawberry", "raspberry")

(green, yellow, *red) = fruits

print(green)
print(yellow)
print(red)
apple
banana
['cherry', 'strawberry', 'raspberry']

The above asteriks shows that the unpacking of tuples will happen and the rest of items that have astericks take the remaining items in the fruits truple

x="hello","World"
a,b=x
print(a)
print(b)
hello
World
x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
a, c, v, b, n, f, *_ = x
print(a)
print(c)
print(v)
print(b)
print(n)
print(f)
1
2
3
4
5
6

Python – Loop Tuples Loop Through a Tuple You can loop through the tuple items by using a for loop.

thistuple = ("apple", "banana", "cherry")
for x in thistuple:
  print(x)
apple
banana
cherry

Loop Through the Index Numbers You can also loop through the tuple items by referring to their index number.

Use the range() and len() functions to create a suitable iterable.

x=tuple((1,2,3,4,5,6,7,8,9))
for i in x:
  print(i, end=", ")
  #this is a small loop that will loop through the tuple and list all the items in a horizontal way
1, 2, 3, 4, 5, 6, 7, 8, 9, 
thistuple = ("apple", "banana", "cherry")
for i in range(len(thistuple)):
  print(thistuple[i])
apple
banana
cherry

Iterating Over a Tuple in Python

Consider the following code snippet:

“`python thistuple = (“apple”, “banana”, “cherry”)

for i in range(len(thistuple)): print(thistuple[i])

Iterating Over a Tuple in Python

This code snippet demonstrates how to iterate over a tuple in Python using a for loop and range.

Creating a Tuple:

  • thistuple = ("apple", "banana", "cherry"): This line creates a tuple named thistuple with three elements: “apple”, “banana”, and “cherry”.

For Loop with Range:

  • for i in range(len(thistuple)):: This line sets up a for loop that iterates over the indices of thistuple.
  • len(thistuple) returns the length of the tuple, which is 3 in this case.
  • range(len(thistuple)) generates a sequence of numbers from 0 to 2 (length-1), which corresponds to the indices of the tuple.

Accessing and Printing Elements:

  • Inside the for loop, thistuple[i] accesses the element of thistuple at index i and prints it.
  • So, during the first iteration, thistuple[0] prints “apple”, during the second iteration, thistuple[1] prints “banana”, and during the third iteration, thistuple[2] prints “cherry”.

Usage:

  • This approach allows you to iterate over each element in a tuple and perform operations on them.
  • It is especially useful when you need to access both the index and the value of each element in the tuple.

Note:

  • Python’s range() function generates a sequence of numbers that can be used to iterate over a sequence (like a tuple, list, or string) using indices.
  • Using range(len(thistuple)) is a common pattern for iterating over the indices of a tuple or list to access each element.
x=(1,"Hello World",2,"hello there",3,4,5,"Good Morning",6,7,8,9,";last codding session")
for i in range(len(x)):
  #print(x) #this will print out all the items in the tuple each time
  print(x[i])#this will print the items in the tuple one by one
1
Hello World
2
hello there
3
4
5
Good Morning
6
7
8
9
;last codding session

Python – Join Tuples Join Two Tuples To join two or more tuples you can use the + operator:

x=(11,22,33,44,55)
y=(66,77,88,99)
print(x+y)#this is going to join the tuple into onetuple
(11, 22, 33, 44, 55, 66, 77, 88, 99)

Multiply Tuples If you want to multiply the content of a tuple a given number of times, you can use the * operator:

x=(1,2,3,4,5,6)
print(x*2)
(1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6)

Python – Tuple Methods Tuple Methods Python has two built-in methods that you can use on tuples.

count() Returns the number of times a specified value occurs in a tuple

index() Searches the tuple for a specified value and returns the position of where it was found

Python Sets

c={1,2,3,4,5,6,7,8,9}
print(type(c))
<class 'set'>
c=set((11,22,33,44,55,66,77))
print(type(c))
<class 'set'>

From the above code we can see that there are 2 ways to create sets, the first is using carry brackets like in mathematics and the second is using the set constructor like in the second case.

Set Items in Python

In Python, a set is a collection data type that is unordered, unchangeable, and does not allow duplicate values.

Unordered:

  • Sets are unordered, meaning that the items in a set do not have a defined order.
  • Unlike sequences such as lists or tuples, you cannot access set items by index or key.
  • Each time you use a set, its items may appear in a different order.

Unchangeable:

  • Set items are unchangeable, or immutable. Once a set is created, you cannot change its items.
  • This means you cannot change, replace, or modify individual items in a set.
  • However, you can add new items to a set or remove existing items from it.

Duplicates Not Allowed:

  • Sets do not allow duplicate values. If you try to add an item that is already in the set, it will not be added again.
  • This property makes sets useful for tasks where you need to store a collection of unique items.

Example:

“`python my_set = {“apple”, “banana”, “cherry”}

#in this code we shall create a set and duplicate the items to see the above is true
x={1,1,2,2,3,4,5,6,7,7,7,7,7}#note that in the set here there are multiple dublicates our task mis to obseve the output
x
{1, 2, 3, 4, 5, 6, 7}

We note that the dublicates were not included in our output as they appeared in the set

#Note: The values True and 1 are considered the same value in sets, and are treated as duplicates:
x={True, 1, False, 0}
x
{False, True}

From the above piece of code we see that the False and True are also treated as same as 1,0

Set Items – Data Types Set items can be of any data type:

set1 = {"apple", "banana", "cherry"}#strings in sets
set2 = {1, 5, 7, 9, 3}#integers in sets
set3 = {True, False, False}#boolean values in sets
set4= {12j,13j,14j,15j}#complex num,bers in sets
print(set1)#outputing the set1
print(set2)#outputing the set2
print(set3)#outputing the set3
print(set4)#outputing the set4
{'apple', 'banana', 'cherry'}
{1, 3, 5, 7, 9}
{False, True}
{14j, 12j, 15j, 13j}
x=set((1,2,3,4,5,6,7))
print(type(x))#in this section we shall try to get the data type
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-526-7d4986958979> in <cell line: 1>()
----> 1 x=set((1,2,3,4,5,6,7))
      2 print(type(x))#in this section we shall try to get the data type

TypeError: 'set' object is not callable
myset = {"apple", "banana", "cherry"}
print(type(myset))

Python Collections Overview

Python offers several collection data types, each with its own characteristics and use cases. Let’s explore them:

1. List

  • Ordered: Elements are stored in a specific sequence.
  • Changeable: Elements can be modified after creation.
  • Allows Duplicate Members: Multiple identical elements can exist in the same list.

2. Tuple

  • Ordered: Similar to lists, elements have a defined order.
  • Unchangeable: Once created, elements cannot be modified.
  • Allows Duplicate Members: Like lists, tuples can contain duplicate elements.

3. Set

  • Unordered: Elements are not stored in any specific order.

  • Unchangeable: While individual items cannot be modified, you can add or remove items.

  • Unindexed: Items cannot be accessed by index.

  • No Duplicate Members: Each element in a set is unique.

    Example: “`python thisset = set((“apple”, “banana”, “cherry”)) # note the double round-brackets print(thisset)

4. Dictionary

Ordered (From Python 3.7+): In newer versions of Python, dictionaries maintain the order of insertion.

Changeable: Elements (key-value pairs) can be added, removed, or modified.

No Duplicate Keys: Each key in a dictionary must be unique.

Note: Dictionaries were unordered in Python 3.6 and earlier.

When selecting a collection type, consider the characteristics of each type to ensure the best fit for your data set. Choosing the right type can improve clarity, efficiency, and security.

Python – Access Set Items

Access Items You cannot access items in a set by referring to an index or a key.

But you can loop through the set items using a for loop, or ask if a specified value is present in a set, by using the in keyword.

z=set((11,22,33,44,55,66,77))
for y in z:
  print(y, end=", ")

The above shows a list of the set items that are listed after being subjected to the for loop.

z={11,22,33,44,55}
for x in z:
  print(x, end=", ")

Here we see that only the items in the set are listed in a plain way.

Change Items

Once a set is created, you cannot change its items, but you can add new items.

s={1,2,3,4,5,6,7}
#the above is a set of integers now we are going to add items to it
s.add(116)#note thatr S takes onl;y one argument and ads it to the list
print(s)

Add Sets

To add items from another set into the current set, use the update() method.

s={111,222,333,444,555,666,777,888,999}
t={122,234,345,567,789,6789,2345,567,678}
#using the 2 sets we shall always be getting the an update of one using the other
s.update(t)
print(s)

From the above we see that the set has become longer after the update operation on the set s, so by using update we can make the set longer

Add Any Iterable The object in the update() method does not have to be a set, it can be any iterable object (tuples, lists, dictionaries etc.).

thisset = {"apple", "banana", "cherry"}
mylist = ["kiwi", "orange"]

thisset.update(mylist)

print(thisset)

Python – Remove Set Items Remove Item To remove an item in a set, use the remove(), or the discard() method.

thisset = {"apple", "banana", "cherry"}

thisset.remove("banana")

print(thisset)

Note: If the item to remove does not exist, remove() will raise an error.

thisset = {"apple", "banana", "cherry"}

thisset.discard("banana")

print(thisset)

Note: If the item to remove does not exist, discard() will NOT raise an error.

You can also use the pop() method to remove an item, but this method will remove a random item, so you cannot be sure what item that gets removed.

The return value of the pop() method is the removed item.

Remove a random item by using the pop() method:

thisset = {"apple", "banana", "cherry"}

x = thisset.pop()

print(x)

print(thisset)

Note: Sets are unordered, so when using the pop() method, you do not know which item that gets removed.

thisset = {"apple", "banana", "cherry"}

thisset.clear()

print(thisset)
thisset = {"apple", "banana", "cherry"}

del thisset

#print(thisset)

Python – Loop Sets Loop Items You can loop through the set items by using a for loop:

thisset = {"apple", "banana", "cherry"}

for x in thisset:
  print(x, end=", ")

Python – Join Sets

There are several ways to join two or more sets in Python:

  1. union() and update(): These methods join all items from both sets.

  2. intersection(): This method keeps only the duplicates.

  3. difference(): This method keeps the items from the first set that are not in the other set(s).

  4. symmetric_difference(): This method keeps all items except the duplicates.

Union

The union() method returns a new set with all items from both sets.

Example:

“`python set1 = {“apple”, “banana”, “cherry”} set2 = {“orange”, “mango”, “banana”}

set3 = set1.union(set2) print(set3)

set1 = {"apple", "banana", "cherry"}
set2 = {"orange", "mango", "banana"}

set3 = set1.union(set2)
print(set3)

Basic Operations of Sets in Mathematics

Union (⋃)

The union of two sets A and B is the set of all elements that are in A, in B, or in both.

Example: If A = {1, 2, 3} and B = {3, 4, 5}, then A ⋃ B = {1, 2, 3, 4, 5}.

Intersection (⋂)

The intersection of two sets A and B is the set of all elements that are in both A and B.

Example: If A = {1, 2, 3} and B = {3, 4, 5}, then A ⋂ B = {3}.

Complement (‘) or (c)

The complement of a set A with respect to a universal set U is the set of all elements in U that are not in A.

Example: If U is the set of all integers and A = {1, 2, 3}, then A’ = {…, -2, -1, 0, 4, 5, …}.

Difference (-)

The difference of two sets A and B (denoted by A – B) is the set of all elements that are in A but not in B.

Example: If A = {1, 2, 3, 4} and B = {3, 4, 5}, then A – B = {1, 2}.

Symmetric Difference (Δ)

The symmetric difference of two sets A and B (denoted by A Δ B) is the set of all elements that are in either A or B, but not in both.

Example: If A = {1, 2, 3} and B = {3, 4, 5}, then A Δ B = {1, 2, 4, 5}.

set1 = {"a", "b", "c"}
set2 = {1, 2, 3}

set3 = set1.union(set2)
print(set3)

You can use the | operator instead of the union() method, and you will get the same result.

set1 = {"a", "b", "c"}
set2 = {1, 2, 3}

set3 = set1 | set2
print(set3)

Join Multiple Sets

All the joining methods and operators can be used to join multiple sets.

When using a method, just add more sets in the parentheses, separated by commas:

set1 = {"a", "b", "c"}
set2 = {1, 2, 3}
set3 = {"John", "Elena"}
set4 = {"apple", "bananas", "cherry"}

myset = set1.union(set2, set3, set4)#joining multiple sets
print(myset)
z={"hello",1,2,3,4,5}
x={"hello", "charles","good Evening"}
y={11,22,33,44,33333333333}
set=x.union(z,y)
print(set, end=", ")
set1 = {"a", "b", "c"}
set2 = {1, 2, 3}
set3 = {"John", "Elena"}
set4 = {"apple", "bananas", "cherry"}

myset = set1 | set2 | set3 |set4
print(myset)
x={1,2,3,4,5,6,7,8}
y={11,22,33,44,55,66,77}
z={"hello","Charles","ndungu"}
set=x|z|y
print(set, end=", ")

Join a Set and a Tuple

The union() method allows you to join a set with other data types, like lists or tuples.

The result will be a set.

x = {"a", "b", "c"}
y = (1, 2, 3)

z = x.union(y)
print(z)

In the above code we have created the union of set x with tuple y

x=[11,22,33,44,55,66,77,88]
y={1,2,3,4,5,6,7,8,9,10}
z=(123,345,678,90)
set=y.union(x,y)
print(set, end=", ")

Note that union() is only availlable in the set but not availlable in the list and tuple thus we must use the y.union() and not x.union() or z.union()

Note: The | operator only allows you to join sets with sets, and not with other data types like you can with the union() method.

Update

The update() method inserts all items from one set into another.

The update() changes the original set, and does not return a new set.

#The update() method inserts the items in set2 into set1:

set1 = {"a", "b" , "c"}
set2 = {1, 2, 3}

set1.update(set2)#the set1 is updated with contents of set 2
print(set1)#printing out the updated set

Note: Both union() and update() will exclude any duplicate items.

Intersection

Keep ONLY the duplicates

The intersection() method will return a new set, that only contains the items that are present in both sets.

set1 = {"apple", "banana", "cherry"}
set2 = {"google", "microsoft", "apple"}

set3 = set1.intersection(set2)
print(set3)
set2_vals = set((1, 2, 3, 4, 5, 6, 7, 8, 9))
set1_vals = set((11, 22, 33, 4, 5, 6, 7, 88, 99))
set3 = set1_vals.intersection(set2_vals)
print(set3)

In the above we see trhat intersection of sets is the common items in set a and set b that is what we call the intersection of a set

We can also use the & operator instead of the intersection()

set1={1,2,3,45,6,7,8,9,11,22,33,44,55,66}
set2={122,2,3,4,5,6,7,8,9,234,345,567,890}
set3=set1 & set2
print(set3)
set1 = {"apple", "banana", "cherry"}
set2 = {"google", "microsoft", "apple"}

set3 = set1 & set2
print(set3)

in the above examples we see that the set3 can also be achieved by using the ampersurd sign

Note: The & operator only allows you to join sets with sets, and not with other data types like you can with the intersecton() method.

The intersection_update() method will also keep ONLY the duplicates, but it will change the original set instead of returning a new set.

set1={1,2,3,4,5,6,7,8,9, 2000}
tuple1=(1,2,3,4,5,6,7,8,100)
list1=[1,2,3,4,5,6,7,8,9,300]
set2= set1.intersection(tuple1, list1)
print(set2)

In the above piece of code we see that the list of all common items in the set set1 and list list1 and tuple tuple1 are all listed in after the intersection. Note that the intersection is always used with the set.

#Keep the items that exist in both set1, and set2:
set1 = {"apple", "banana", "cherry"}
set2 = {"google", "microsoft", "apple"}

set1.intersection_update(set2)

print(set1)

This code snippet demonstrates the use of the intersection_update method in Python sets.

set1 contains the elements {“apple”, “banana”, “cherry”}.

set2 contains the elements {“google”, “microsoft”, “apple”}.

The intersection_update method modifies set1 to contain only the elements that are common between set1 and set2.

After the operation, set1 will be {“apple”}, as “apple” is the only element that exists in both set1 and set2.

The print(set1) statement will output {“apple”}.

The values True and 1 are considered the same value. The same goes for False and 0.

set1 = {"apple", 1,  "banana", 0, "cherry"}
set2 = {False, "google", 1, "apple", 2, True}

set3 = set1.intersection(set2)

print(set3)

Difference

The difference() method will return a new set that will contain only the items from the first set that are not present in the other set.

set1 = {"apple", "banana", "cherry"}
set2 = {"google", "microsoft", "apple"}

set3 = set1.difference(set2)

print(set3)

You can use the – operator instead of the difference() method, and you will get the same result.

set1 = {"apple", "banana", "cherry"}
set2 = {"google", "microsoft", "apple"}

set3 = set1 - set2
print(set3)

Note: The – operator only allows you to join sets with sets, and not with other data types like you can with the difference() method.

The difference_update() method will also keep the items from the first set that are not in the other set, but it will change the original set instead of returning a new set.

set1 = {"apple", "banana", "cherry"}
set2 = {"google", "microsoft", "apple"}

set1.difference_update(set2)

print(set1)

Symmetric Differences

The symmetric_difference() method will keep only the elements that are NOT present in both sets.

set1 = {"apple", "banana", "cherry"}
set2 = {"google", "microsoft", "apple"}

set3 = set1.symmetric_difference(set2)

print(set3)

You can use the ^ operator instead of the symmetric_difference() method, and you will get the same result.

set1 = {"apple", "banana", "cherry"}
set2 = {"google", "microsoft", "apple"}

set3 = set1 ^ set2
print(set3)

Note: The ^ operator only allows you to join sets with sets, and not with other data types like you can with the symmetric_difference() method.

The symmetric_difference_update() method will also keep all but the duplicates, but it will change the original set instead of returning a new set.

#Use the symmetric_difference_update() method to keep the items that are not present in both sets:
set1 = {"apple", "banana", "cherry"}
set2 = {"google", "microsoft", "apple"}

set1.symmetric_difference_update(set2)

print(set1)

Python Set Methods

  • add(): Adds an element to the set.

  • clear(): Removes all the elements from the set.

  • copy(): Returns a copy of the set.

  • difference(): Returns a set containing the difference between two or more sets.

  • difference_update(): Removes the items in this set that are also included in another specified set.

  • discard(): Remove the specified item.

  • intersection(): Returns a set that is the intersection of two other sets.

  • intersection_update(): Removes the items in this set that are not present in other specified set(s).

  • isdisjoint(): Returns whether two sets have an intersection or not.

  • issubset(): Returns whether another set contains this set or not. It also returns whether all items in this set are present in other specified set(s).

  • issuperset(): Returns whether this set contains another set or not. It also returns whether all items in other specified set(s) are present in this set.

  • pop(): Removes an element from the set.

  • remove(): Removes the specified element.

  • symmetric_difference(): Returns a set with the symmetric differences of two sets.

  • symmetric_difference_update(): Inserts the symmetric differences from this set and another.

  • union(): Return a set containing the union of sets.

  • update(): Update the set with the union of this set and others.

Python Dictionaries

thisdict = { “brand”: “Ford”, “model”: “Mustang”, “year”: 1964 }

Dictionary

Dictionaries are used to store data values in key:value pairs.

A dictionary is a collection which is ordered*, changeable and do not allow duplicates.

As of Python version 3.7, dictionaries are ordered. In Python 3.6 and earlier, dictionaries are unordered.

Dictionaries are written with curly brackets, and have keys and values:

thisdict = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
print(thisdict)

Dictionary Items

Dictionary items are ordered, changeable, and do not allow duplicates.

Dictionary items are presented in key:value pairs, and can be referred to by using the key name.

thisdict = {
  "brand": "Ford",
  "brand": "Ford",#dublicated does not get printed twice as they don't allow dublicates
  "model": "Mustang",
  "year": 1964
}
print(thisdict["brand"])

Ordered or Unordered?

As of Python version 3.7, dictionaries are ordered. In Python 3.6 and earlier, dictionaries are unordered.

When we say that dictionaries are ordered, it means that the items have a defined order, and that order will not change.

Unordered means that the items do not have a defined order, you cannot refer to an item by using an index.

Changeable

Dictionaries are changeable, meaning that we can change, add or remove items after the dictionary has been created.

Duplicates Not Allowed

Dictionaries cannot have two items with the same key:

thisdict = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964,
  "year": 2020#Duplicate values will overwrite existing values:
}
print(thisdict)

Duplicate values will overwrite existing values:

Python – Access Dictionary Items

Accessing Items You can access the items of a dictionary by referring to its key name, inside square brackets:

thisdict = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
x = thisdict["model"]#Get the value of the "model" key:
dictionary={"key 1":123, "key 2":12j, "key 3":"strings", "key 4":(1,2,3,4,5), "key 5":12.454, "key 6":123.23}
print(dictionary)#printing out the dictionary
print(dictionary["key 3"])#printing out the dictionary value in key 3
print(dictionary["key 1"])#printing out the dictionary value in key 1
print(dictionary["key 3"])#printing out the dictionary value in key 3
print(dictionary["key 4"])#printing out the dictionary value in key 4
print(dictionary["key 5"])#printing out the dictionary value in key 5
print(dictionary["key 6"])#printing Out The Dictionary Value in key 6

Get Keys

The keys() method will return a list of all the keys in the dictionary.

#naming using the camel case eg myName
#naming of variables using the snake case  eg my_name_is
#naming of variables using the pascal case eg MyNameIsCharles
dictionaryKeys={"key 1":"strings", "key 2":{1,2,3,4,5}, "key 3":12j, "key 4":12.45, "key 5":{"inside key":123, "inside key 2": 12.45, "inside key 3": 123j}, "key 6":123456}
print(dictionaryKeys)#this prints out the dictionary keys
print(dictionaryKeys.get("key 3"))#This prints out the "key 3" value
print(dictionaryKeys.items())#this prints out the dictionary items
print(dictionaryKeys.keys())#this prints out the dictionary keys
print(dictionaryKeys.values())# this prints out the dictionary values
#note you must include the braces after the end of the methods as follows .get(), .items(), .keys(), .values()
print(dictionaryKeys.get("key 2"))#geting value of key 2

The list of the keys is a view of the dictionary, meaning that any changes done to the dictionary will be reflected in the keys list.

car = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}

x = car.keys()

print(x) #before the change

car["color"] = "white"

print(x) #after the change
dictionary={"key1":"string", "key2":{"Dictionary inside a dictionary":"hello there am the new dictionar"}, "key3":123, "key4":{1,2,3,4,5,6,7}, "key5":(1,2,3,4,5,0,6,78,9), "key6":None, "key7":True}
x=dictionary.keys()
print(x)
dictionary["NewKey"]="Am the new buddy key"#This has been used to add a new key into our dictionary
print(x)
print(dictionary.items())

In the above example we shall try to see the different ways we can append other items in the dictionary

Check if Key Exists

To determine if a specified key is present in a dictionary use the in keyword:

thisdict = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
if "model" in thisdict:
  print("Yes, 'model' is one of the keys in the thisdict dictionary")
myDictionary={"key 1":"Yes my first item", "key 2":"Yes my second item"}
if "key 2" in myDictionary:
  print(myDictionary.keys(), myDictionary.items())

Change Values

You can change the value of a specific item by referring to its key name:

thisdict = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
thisdict["year"] = 2018
print(thisdict)
mydictionary={"hello":"This is a greeting", "Good Morning":"This is a morning greeting", "Good Afternoon":"This is for afternoon greeting"}
mydictionary["Good evening"]="This is for evening"
mydictionary["Hello"]="This is also used to great people"
print(mydictionary.keys())#This prints out the keys
print(mydictionary.items())#This prints out the items of the dict
print(mydictionary)#This prints my dictionary all items and keys
print(type(mydictionary))#This prints out the data structure type

Update Dictionary

The update() method will update the dictionary with the items from the given argument.

The argument must be a dictionary, or an iterable object with key:value pairs.

thisdict = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
thisdict.update({"year": 2020})
thisdict
mydict = {"string": "am good", "Integers": 123, "float numbers": 12.56, "complex": 12j}
mydict.update({"Natural numbers": "are counting numbers"})

print(mydict, "This will print the dictionary items both keys and items \n")
print(mydict.items(), "Listing the items \n")
print(mydict.keys(), "Listing the keys \n")
print(mydict.copy(), "For copying \n")
print(mydict.get("string"), "Getting the value of the key string \n")

mydict.pop("Integers")  # Removing the specific item "Integers"
print(mydict.values(), "This will list all the values of the dictionary \n")

Python – Add Dictionary Items

Adding Items Adding an item to the dictionary is done by using a new index key and assigning a value to it:

thisdict = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
thisdict["color"] = "red"
print(thisdict)
mydictionary={"float":12.35, "integer":[1,2,3,4,5,6,7,8,9,-1,2,3,4,5,6,7,8,9], "complex":123.354j, "string":"This is a string", "data types":{"set","list","tuple","dictionary"}}
mydictionary["the dictionary"]="my 2nd one..."
print(mydictionary)

Update Dictionary

The update() method will update the dictionary with the items from a given argument. If the item does not exist, the item will be added.

The argument must be a dictionary, or an iterable object with key:value pairs.

mydictionary={"small one": "this a small one", "key 2":"The second key"}
print(mydictionary)#before modification
mydictionary.update({"new key":"Am the new key in town"})
print(mydictionary)#after the modification
#Add a color item to the dictionary by using the update() method:
my_dictionary= {"key":122}
my_dictionary["key 2"]="aM THE NEW BOSS IN TOWN"
print(my_dictionary)
#using the update
my_dictionary.update({"Key 3":12.234})
print(my_dictionary)

Add a color item to the dictionary by using the update() method:

my_dictionary={"hello world": "This is a string"}
my_dictionary.update({"string 2":"2 is now as a string"})
print(my_dictionary)

Removing Items

There are several methods to remove items from a dictionary:

The pop() method removes the item with the specified key name:

thisdict = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
thisdict.pop("model")
print(thisdict)
my_dictionary={"Hello world":"This is a string", "integer":1, "float":12.34}
my_dictionary.pop("float")
print(my_dictionary)

The del keyword removes the item with the specified key name:

thisdict = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
del thisdict["model"]
print(thisdict)
my_dictionary={"string":"This is a string", "integer":[1,2,3,4,5,-1,2,200], "float":(12.23,13,25,123,12,90)}
print(my_dictionary)
del my_dictionary["float"]
print(my_dictionary)

The clear() method empties the dictionary

thisdict = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
thisdict.clear()
print(thisdict)
my_dictionary={"string":"This is a string", "This is an integer": {1,2,3,4,5,6,7,8,9,10}, "complex numbers":{1,1,2,3,4,5,6,7}}
my_dictionary.clear()
print(my_dictionary)

Python – Loop Dictionaries

Loop Through a Dictionary You can loop through a dictionary by using a for loop.

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

mydictionary={"key 1":1, "key 2": 2}
for x in mydictionary:
  print(x)# this prints out the dictionary keys

for y in mydictionary:
  print(mydictionary[x])#This prints out thje dictionary items
my_dictionary={"key 1":1, "key 2": 2.2, "key 3": 12j, "key 4": "string"}
for z in my_dictionary.keys():
  print(z)#prinbts out the key in the dictionary

for d in my_dictionary.items():
  print(d)#prints out the key and item contained in the dictionary
my_dictionary={"key 1": 1, "key 2": 12.3, "key 3": 12j, "key 4": "strings"}
for x in my_dictionary.values():
  print(x)#this will print out only the values contained in the dictionary

Loop through both keys and values, by using the items() method:

my_dictionary={"key 1":1, "key 2":2.2, "key 3":12j, "key 4": "string"}
for x, y in my_dictionary.items():
  print(x, y)#This will print the key and the value that correspond with that key
#note you can't use .values() , .keys() that will produce an error

Python – Copy Dictionaries

Copy a Dictionary

You cannot copy a dictionary simply by typing dict2 = dict1, because: dict2 will only be a reference to dict1, and changes made in dict1 will automatically also be made in dict2.

There are ways to make a copy, one way is to use the built-in Dictionary method copy().

my_dictionary={"key 1": 1, "key 2": 12j, "key 3": 12.34, "key 4": "strings"}
my_new_dictionary=my_dictionary.copy()#on the .copy() don't forget the parenthesis ()
print(my_new_dictionary)

Make a copy of a dictionary with the dict() function:

thisdict = {
  "brand": "Ford",
  "model": "Mustang",
  "year": 1964
}
mydict = dict(thisdict)
print(mydict)
my_dictionary={"key 1":1, "key 2": 2.2, "key 3": 12j, "key 4": "string"}
my_new_dictionary= dict(my_dictionary)
my_dictionary["key 5"]="others"
print(my_new_dictionary)# this is the new copied dictionary
print(my_dictionary)#this is the modified dictionary that no effect occurs to the copied dictionary as it is not modified

Python – Nested Dictionaries

Nested Dictionaries A dictionary can contain dictionaries, this is called nested dictionaries.

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

print(myfamily)
my_dictionary = {"key 1": 1, "key 2": 1.2, "key 3": 12j, "key 4": "strings"}  # this is a common dictionary with no nesting
my_nested_dictionary = {
    "list": {"integers": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]},
    "float": (12.2, 1.02222, 11.23456654, 2.1)
    }

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

myfamily = {
  "child1" : child1,
  "child2" : child2,
  "child3" : child3
}
print(child1)
print(child2)
print(child3)

Access Items in Nested Dictionaries

To access items from a nested dictionary, you use the name of the dictionaries, starting with the outer dictionary:

nested_dictionary = {
    "dict 1": {
        "key 1": {1, 2, 3, 4, 5, 6, 7, 8}
    },
    "dict 2": {
        "key dic 2": {"set 1", "set 2", "set 3"}
    }
}

# Printing the whole nested dictionary
print(nested_dictionary)

# Printing dictionary 1
print(nested_dictionary["dict 1"], "This will print out dictionary 1")

# Printing "set 1" inside "dict 2"
print(nested_dictionary["dict 2"]["key dic 2"])

Python Dictionary Methods

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

  • 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.

my_dictionary={"key 1":1, "key 2": 1.2, "key 3": 12j}
print(my_dictionary.get("key 3"))#get the item of the third key

Python If … Else

Python Conditions and If statements Python supports the usual logical conditions from mathematics:

Equals: a == b Not Equals: a != b Less than: a < b Less than or equal to: a <= b Greater than: a > b Greater than or equal to: a >= b

These conditions can be used in several ways, most commonly in “if statements” and loops.

An “if statement” is written by using the if keyword.

a = 33
b = 200
if b > a:
  print("b is greater than a")
x=2300
y=300
if x>y:
  print(f"{x} is greator than {y}")
y=list((1,2,3))
z=list((4,5,6))
if len(y) == len(z):
  print(f"y={y} has equal length to z={z}")

Elif

The elif keyword is Python’s way of saying “if the previous conditions were not true, then try this condition”.

a = 33
b = 33
if b > a:
  print("b is greater than a")
elif a == b:
  print("a and b are equal")
x= [1,2,3,4]
y= [5,5,7,8]
if len(x)>len(y):
    print(f"{x} which is /'a'/ has many items than {y} which is /'b/' ")
elif len(x) == len(y):
    print("They are Equal")
else:
    print("b is greator than a")

In this example a is equal to b, so the first condition is not true, but the elif condition is true, so we print to screen that “a and b are equal”.

Else

The else keyword catches anything which isn’t caught by the preceding conditions.

a = 200
b = 33
if b > a:
  print("b is greater than a")
elif a == b:
  print("a and b are equal")
else:
  print("a is greater than b")
x=[1,2,3,]#tuple
y=[5,6,7,8]#list
if x == y:
  print(f"{x} is equal to {y}")
elif x<y:
  print(f"{x} is less than {y}")

else:
  print(f"{x} is greator than {y}")
x=122
y=-222
if x==y:
  print(f"{x} is greator than {y}")

elif x <= y:
  print(f"{x} is greator than or equal to {y}")

else:
  print("any other case except the above")
x=float(input("Enter a number X: "))
y=float(input("Enter a number Y: "))

if x == y:
  print("x is equal to y")
elif x<=y:
  print("x is less than or equal to y")
elif x>=y:
  print("x is greator than y")
elif x>y:
  print("x is greator than y")
elif x<y:
  print("x is less than y")
elif x < y+1:
  print("x is less than y")
else:
  print("no condition is satisfied")

In this example a is greater than b, so the first condition is not true, also the elif condition is not true, so we go to the else condition and print to screen that “a is greater than b”.

You can also have an else without the elif:

a = 200
b = 33
if b > a:
  print("b is greater than a")
else:
  print("b is not greater than a")

Short Hand If

If you have only one statement to execute, you can put it on the same line as the if statement.

if a > b: print("a is greater than b")
x=233
y=6778
if x>y:
  print("X isa greator than Y")
  pass
else:
  print("X is greator than Y")

#the above was the long way we shall look at the short way of doing it
if x>y: print("X is greator than y")#THIS GIVES ONLY THE IF
print("X is greator than Y") if x>y else print("X  is less than Y")#THIS GIVES THE SHORTHAND IF ELSE

Short Hand If … Else

If you have only one statement to execute, one for if, and one for else, you can put it all on the same line:

a = float(input("Enter A number: "))
b = 330
print("A") if a > b else print("B")
x=230
y=500
print("x") if x>y else print("y")
y=tuple((1,2,3,4,5))
z=tuple((6,7,8,9,10))
print("y") if len(y) == len(z) else print(f"{y} is not equal to {z}")
x=set((1,2,3,45))
y=set((11,22,33,44))
print("y") if len(x) != len(y) else print(f"{x} is equal to {y}")

This technique is known as Ternary Operators, or Conditional Expressions.

You can also have multiple else statements on the same line:

a = 330
b = 330
print("A") if a > b else print("=") if a == b else print("B")
x=300
y=250
print(f"{x} is equal to {y}") if x==y else print(f"{x} is not equal to {y}") if print(f"{x} is less than {y}") else print(f"{x} is none to {y}")

And

The and keyword is a logical operator, and is used to combine conditional statements:

a = 200
b = 33
c = 500
if a > b and c > a:
  print("Both conditions are True")
x=200
y=300
z=400
if x<y and x<z:
  print(f"Ooh Boy, {x} is less than both {y} and {z}!")

Or

The or keyword is a logical operator, and is used to combine conditional statements:

a = 200
b = 33
c = 500
if a > b or a > c:
  print("At least one of the conditions is True")
x=200
y=300
z=400
if x!=y or x==z:
  print(f"{x} is not qual to y or {x} is equal to {z} produces true")

or: The or operator returns True if at least one of the conditions it combines is True. If both conditions are False, it returns False.

and: The and operator returns True only if both conditions it combines are True. If any of the conditions is False, it returns False.

not: is a unary operator that negates the boolean value of a single condition. If the condition is True, not makes it False, and vice versa.

Not

The not keyword is a logical operator, and is used to reverse the result of the conditional statement:

a = 33
b = 200
if not a > b:
  print("a is NOT greater than b")
x=2000
y=300
if not x<y:
  print("we have negated so that now {x} is greator than {y} other than previously stated!")

Nested If

You can have if statements inside if statements, this is called nested if statements.

x = 41

if x > 10:
  print("Above ten,")
  if x > 20:
    print("and also above 20!")
  else:
    print("but not above 20.")
x=200
y=300
if x>y:
  print(f"{x} is greator than {y}")
else:
  print(f"{x} is less than {y}")#this the statement that will be printed

The pass Statement

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

a = 33
b = 200

if b > a:
  print("True it is greator than a")
  pass
x=500
y=500
if x>y:
  print("x is greator than y")
elif x<y:
  print("x is less than y")
  pass
else:
  print("none has taken place")
x=200
y=300
z=400
if x<y:
  print(f"This is from the if statement, {x} is less than {y}")


print("/n")
x=200
y=300
z=400
while x < y:
  print("The pass statement ",x, end=", ")
  x+=10
  if x == 250:
    pass# this does nothing and the code executes normally

print("/n")
x=200
y=300
z=400
while x<z:
  print("The break statement ",x, end=", ")
  x += 10
  if x == 250:
    break#breaks at the value 250


print("/n")
x=200
y=300
z=400
while x<y:
  print("The continue statement ",x, end=", ")
  x+=10
  if x==250:
    continue#first loop ends at 250 and next loop begins at 260 thus 250 won't ne printed

pass: pass is a null operation that does nothing. It is used when a statement is required syntactically but you do not want to execute any code. It is often used as a placeholder to avoid syntax errors.

In this example, when i is equal to 2, the pass statement is executed, but it does not affect the loop, and the program continues to execute the next iteration.

break: break is used to exit a loop prematurely. When break is encountered inside a loop, the loop is immediately terminated, and the program execution continues with the next statement after the

In this example, the loop will terminate when i is equal to 2, and the output will be 0 and 1.

continue: continue is used to skip the rest of the code inside a loop for the current iteration and continue with the next iteration.

In this example, when i is equal to 2, the continue statement is executed, skipping the print(i) statement for that iteration. The output will be 0, 1, 3, and 4.

Python While Loops

Python Loops

Python has two primitive loop commands:

while loops

for loops

The while Loop:

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

i = 1
while i < 6:
  print(i)
  i += 1
x=200
y=300
while x<y:
  print(x, end=", ")
  x=x+1
x=10
y=20
while x<y:
  print("X is less than Y")
  pass#THIS ALLOWS THE CODE TO CONTINUE
  x=x+1
  if x==12:
    print(x)
    break# THIS BREAKS THE CODE AFTER THE X BECOMES 12

pass: The pass statement in Python is a null operation. It is used when a statement is required syntactically but you do not want any code or action to execute.

Note: remember to increment i, or else the loop will continue forever.

The while loop requires relevant variables to be ready, in this example we need to define an indexing variable, i, which we set to 1.

The break Statement 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
x=200
y=300
while x<y:
  print(x,end=", ")
  x+=40
  if x == 280:
    continue
x=200
y=500
while x < y:
  print(f"{x} is greator than {y}")
  x+=20
  if x==350:
    continue
    print("{x} is equal to 350")#notice that 350 is not printed out as the loop completes the first loop then goes to the next loop starting from 360
c=789
d=900
while c < d:
  print(f"{c} is less than {d}")
  c+=20
  if c==889:
    break
    print(f"{c} is equal to 889")
a=1200
b=200
while a>b:
  print(b, end=", ")
  b+=100
  if b == 1000:
    break

The continue Statement

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, end=", ")
x= 200
while x>10:
  x += 5
  if x == 150:
    continue
    print("x")

The else Statement

With the else statement we can run a block of code once when the condition no longer is true:

i = 1
while i < 6:
  print(i)
  i += 1
else:
  print("i is no longer less than 6")

Python For Loops

A for loop is used for iterating over a sequence (that is either a list, a tuple, a dictionary, a set, or a string).

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.

With the for loop we can execute a set of statements, once for each item in a list, tuple, set etc.

fruits = ["apple", "banana", "cherry"]
for x in fruits:
  print(x)
x=list((1,2,3,4,5,6,7,8,9))
for y, z in enumerate(x):
  print(x[y], "is index", z)
d = (1, 2, 34, 5, 6, 7, 8, 9)
for index, value in enumerate(d):
    print(d[index], end=", ")

This code will iterate over the tuple d, using the enumerate function to get both the index and the value of each element. Then, it will print each element of d using the index obtained from enumerate.

The variable value is used to store the value of each element in the tuple d as you iterate over it. The enumerate function returns a tuple containing the index of the current element and the value of the current element.

So, in each iteration of the loop, value will hold the value of the current element in d, while index will hold the index of that element. This allows you to access both the index and the value of each element in the tuple d within the loop body.

d = (1, 2, 34, 5, 6, 7, 8, 9)
for index, value in enumerate(d):
    print(f"Index: {index}, Value: {value}")

Each line of output shows the index of the element (Index) and the value of the element (Value) from the tuple d.

x=(1,2,3,4,56,7,8,9)
for y in x:
  print(y, end=", ")

The for loop does not require an indexing variable to set beforehand.

Looping Through a String

Even strings are iterable objects, they contain a sequence of characters:

for x in "banana":
  print(x)

Looping through common data types in python using for loop. A refesher of last lectures.

# Looping on a list
x = list((1, 2, 3, 4, 5))
z = [1, 2, 3, 4, 5]
for y in x:
    print(y, end=", ")
print()

for y in z:
    print(y, end=", ")
print()

# Looping on a set
x = set((1, 2, 3, 4, 5, 6))
z = {1, 2, 3, 4, 5, 6}
for y in x:
    print(y, end=", ")
print()

for y in z:
    print(y, end=", ")
print()

# Looping in a dictionary
x = {
    "key 1": 1, "key 2": 2, "key 3": 3, "key 4": 4,
    "key 5": 5, "key 6": 6, "key 7": 7, "key 8": 8
}
z = {
    "key 1": 1, "key 2": 2, "key 3": 3, "key 4": 4,
    "key 5": 5, "key 6": 6, "key 7": 7, "key 8": 8
}
for y in x:
    print(y, end=", ")
print()

for y in z:
    print(y, end=", ")
print()

# Looping in a range
for i in range(10):
    print(i, end=", ")
print()

The break Statement

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

fruits = ["apple", "banana", "cherry"]
for x in fruits:
  print(x)
  if x == "banana":
    break
fruits = ["apple", "banana", "cherry"]
for x in fruits:
  if x == "banana":
    break
x=list((1,2,34,56,7,8,9))
for y in x:
  print(y, end=", ")
  if y == 7:
    break

The continue Statement

With the continue statement 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)
treyzz=set(("music", "entertainment", "office", "dance", "Investment"))
for y in treyzz:
  print(y, end=", ")
  if y == "office":
    continue
    print(y)

When you create a set using set(), the order of elements in the set is arbitrary and can change between executions or even within the same execution of your program. So, the fact that “dance” appears at the end in your output is just a coincidence and does not reflect any specific ordering logic.

The range() Function

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.

for x in range(6):
  print(x)
z=[1,2,3,4,5,6,7,8,9,10]
for x, y in enumerate(z):
  print("Printing the index only! ", x, end=", ")

print()

for x in range(len(z)):
  print(x, end=", ")#printing the indexes in another way!

Explanation

for x in range(len(z)):
  print(x, end=", ")#printing the indexes in another way!

We note that the output will be the index of the list as we are looping through the list we get the length of the list ising the len() function then subject it to the range() method

for x in range(12):
  print(x, end=", ")
x = list(range(1, 20, 2))#start at 1, stop at 20, have a step or interval of 2!
print(x)

range(stop): This generates a sequence from 0 to stop – 1.

range(start, stop): This generates a sequence from start to stop – 1.

range(start, stop, step): This generates a sequence from start to stop – 1, with a step size of step.

In our example, x = range(1, 20, 2) creates a sequence of odd numbers from 1 to 19 with a step size of 2. When we print x, it will output:

range(1, 20, 2)
#This doesn't print the actual sequence of numbers but rather a representation of the range object. If you want to see the sequence, you can convert it to a list:

This doesn’t print the actual sequence of numbers but rather a representation of the range object. If you want to see the sequence, you can convert it to a list:

x = list(range(1, 20, 2))
print(x)
#converted into a list:

converted into a list

Note that range(6) is not the values of 0 to 6, but the values 0 to 5.

The range() function defaults to 0 as a starting value, however it is possible to specify the starting value by adding a parameter: range(2, 6), which means values from 2 to 6 (but not including 6):

The range() function defaults to increment the sequence by 1, however it is possible to specify the increment value by adding a third parameter: range(2, 30, 3):

for x in range(2, 30, 3):
  print(x, end=", ")

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, end=", ")
else:
  print("Finally finished!")
for y in range(1,20,5):
  print(y, end=", ")
else:
  print("Finished!")

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

for z in range(1,30,5):
  print(z, end=", ")
  if z == 21:
    break
for z in range(1, 30, 5):
    if z > 25:
        break
    print(z, end=", ")

Nested Loops

A nested loop is a loop inside a loop.

The “inner loop” will be executed one time for each iteration of the “outer loop”:

adj = ["red", "big", "tasty"]
fruits = ["apple", "banana", "cherry"]

for x in adj:
  for y in fruits:
    print(x, y)
tuple=(1,2,3,4,5,6,7)
list=["one","two", "three","four","five","six","seven"]
for x in tuple:
  for y in list:
    print(x, y)

The pass Statement

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

for x in [0, 1, 2]:
  pass
x={2,3,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
for y in x:
  print(y, end=", ")
  if y == 7:
    pass#does nothing
  if y == 8:
    continue#continues to print
  if y==11:
    break#stops when y is equal to 11

Python 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:

def my_function():
  print("Hello from a function")

#my_function()

Calling a Function

To call a function, use the function name followed by parenthesis:

def my_function():
  print("Hello from a function")

my_function()
def my_function(charles):
  return "Hello world 2"

calling = my_function("Calling Man Ndung'u")
print(calling)#this prints the output from the funtion that is "Hello world 2"
def my_function(charles):
    return charles

# Example usage
result = my_function("Hello world")
print(result)  # Output: Hello world
def function(same_here):
  return same_here # naming using the snake case

test = function("Man Ndung'u")
print(test)
def my_function(name):
    return "Hello, " + name  # naming using the snake case

test = my_function("Man Ndung'u")
print(test)
length= float(input("Enter the length of the room: "))
width= float(input("Enter the width of the room: "))

def area():
  return length*width

area()
def area(length, width):
    return length * width

length = float(input("Enter the length of the room: "))
width = float(input("Enter the width of the room: "))
house_a = area(length, width)
print(house_a)
def triangle(height, width):
  return 0.5*width*height

width=float(input("Enter the width: "))
height=float(input("Enter the height: "))

my_triangle= triangle(width, height)
print(my_triangle)
def bank_account(account, name, deposit, branch):
    return {
        "account": account,
        "name": name,
        "deposit": deposit,
        "branch": branch
    }#this is the data that will be returned from the function once it is called

account = float(input("Enter your account number: "))
name = input("Enter your name: ")
deposit = float(input("Enter the amount to deposit: "))
branch = input("Enter your bank branch: ")

customer = bank_account(account, name, deposit, branch)
print(customer)#Calling the function so that it prints out the data
def bank_account(account, name, deposit, branch):
  return {"Deposite": deposit}

account=float(input("enter your account  number: "))
name = str(input("enter your name: "))
deposit =float(input("Enter the amount to deposit: "))
branch = str(input("Enter your bank branch: "))

customer=bank_account(account, name, deposit, branch)
print(customer)#This returns the Deposit in the function
class BankAccount:
    def __init__(self, account, name, deposit, branch):
        self.account = account
        self.name = name
        self.deposit = deposit
        self.branch = branch

account = float(input("Enter your account number: "))
name = input("Enter your name: ")
deposit = float(input("Enter the amount to deposit: "))
branch = input("Enter your bank branch: ")

customer = BankAccount(account, name, deposit, branch)
print(customer.deposit)

Project Create a bank Management system.

accounts = {}

def create_account():
    account_number = int(input("Enter your account number: "))
    name = input("Enter your name: ")
    initial_deposit = float(input("Enter the initial deposit amount: "))
    accounts[account_number] = {"name": name, "balance": initial_deposit}
    print("Account created successfully.")

def deposit():
    account_number = int(input("Enter your account number: "))
    if account_number in accounts:
        amount = float(input("Enter the amount to deposit: "))
        accounts[account_number]["balance"] += amount
        print("Deposit successful. Your new balance is:", accounts[account_number]["balance"])
    else:
        print("Account not found.")

def withdraw():
    account_number = int(input("Enter your account number: "))
    if account_number in accounts:
        amount = float(input("Enter the amount to withdraw: "))
        if accounts[account_number]["balance"] >= amount:
            accounts[account_number]["balance"] -= amount
            print("Withdrawal successful. Your new balance is:", accounts[account_number]["balance"])
        else:
            print("Insufficient balance.")
    else:
        print("Account not found.")

def transfer():
    from_account = int(input("Enter your account number: "))
    to_account = int(input("Enter the recipient's account number: "))
    if from_account in accounts and to_account in accounts:
        amount = float(input("Enter the amount to transfer: "))
        if accounts[from_account]["balance"] >= amount:
            accounts[from_account]["balance"] -= amount
            accounts[to_account]["balance"] += amount
            print("Transfer successful.")
            print("Your new balance is:", accounts[from_account]["balance"])
        else:
            print("Insufficient balance.")
    else:
        print("One or both accounts not found.")

# Main program loop
while True:
    print("\nBank Management System")
    print("1. Create Account")
    print("2. Deposit")
    print("3. Withdraw")
    print("4. Transfer")
    print("5. Exit")

    choice = input("Enter your choice: ")

    if choice == "1":
        create_account()
    elif choice == "2":
        deposit()
    elif choice == "3":
        withdraw()
    elif choice == "4":
        transfer()
    elif choice == "5":
        print("Exiting program.")
        break
    else:
        print("Invalid choice. Please try again.")

Project 2 Creating an alarm clock

import time

def set_alarm():
    hours = int(input("Enter the hour (0-23) for the alarm: "))
    minutes = int(input("Enter the minute (0-59) for the alarm: "))
    return hours, minutes

def check_alarm(alarm_time):
    while True:
        current_time = time.localtime()
        if current_time.tm_hour == alarm_time[0] and current_time.tm_min == alarm_time[1]:
            print("Alarm! Wake up!")
            break
        time.sleep(60)  # Check every minute

def alarm_clock():
    print("Welcome to Alarm Clock")
    alarm_time = set_alarm()
    print(f"Alarm set for {alarm_time[0]:02d}:{alarm_time[1]:02d}")
    check_alarm(alarm_time)

# Main program
alarm_clock()

Create a simple POS the POS system to include functionalities for producing a Z report, storing debts, and printing receipts with change, perform sales.

The sell_item function allows the user to sell an item by asking for the product name and the quantity needed. It adds the item to the cart.

The process_payment function now handles debts. If the payment is less than the total, it adds the remaining amount to the customer’s debt.

The list_debtors function lists all debtors and their respective debts.

The inventory dictionary contains the available products and their prices.

The sales list stores each sale as a dictionary containing the items sold, the total amount, and the customer’s name.

The debts dictionary stores each customer’s debt amount.

def display_menu():
    print("=== Menu ===")
    print("1. Sell item")
    print("2. Add item")
    print("3. List items")
    print("4. List categories")
    print("5. Calculate total")
    print("6. Process payment")
    print("7. List debtors")
    print("8. Exit")

def sell_item(inventory, cart):
    product_name = input("Enter product name: ")
    if product_name not in inventory:
        print("Product not found.")
        return
    quantity_needed = int(input(f"Enter quantity needed for {product_name}: "))
    cart.append({"name": product_name, "quantity": quantity_needed})
    print(f"Added {quantity_needed} units of {product_name} to cart")

def add_item(inventory):
    product_name = input("Enter product name: ")
    if product_name in inventory:
        print("Product already exists.")
        return
    price = float(input("Enter price for the item: "))
    category = input("Enter category for the item: ")
    inventory[product_name] = {"price": price, "category": category}
    print(f"Added {product_name} to inventory")

def list_items(inventory):
    print("=== Inventory ===")
    for product_name, details in inventory.items():
        print(f"{product_name}: ${details['price']}, Category: {details['category']}")

def list_categories(inventory):
    categories = set(details['category'] for details in inventory.values())
    print("=== Categories ===")
    for category in categories:
        print(category)

def calculate_total(inventory, cart):
    total = sum(inventory[item["name"]]["price"] * item["quantity"] for item in cart)
    print(f"Total: ${total:.2f}")

def process_payment(cart, sales, debts):
    total = sum(inventory[item["name"]]["price"] * item["quantity"] for item in cart)
    payment = float(input("Enter payment amount: "))
    if payment < total:
        print("Insufficient payment. Payment must be equal to or greater than the total.")
        return
    customer_name = input("Enter customer's name: ")
    if payment > total:
        change = payment - total
        print(f"Payment successful. Change: ${change:.2f}")
    else:
        change = 0
        print("Payment successful. No change.")
    sale = {"items": cart.copy(), "total": total, "customer_name": customer_name}
    sales.append(sale)
    if payment < total:
        debt = total - payment
        debts[customer_name] = debts.get(customer_name, 0) + debt
        print(f"Added ${debt:.2f} to {customer_name}'s debt.")

def list_debtors(debts):
    print("Debtors:")
    for customer, debt in debts.items():
        print(f"{customer}: ${debt:.2f}")

def pos_system():
    inventory = {
        "apple": {"price": 1.00, "category": "fruit"},
        "banana": {"price": 0.50, "category": "fruit"},
        "orange": {"price": 0.75, "category": "fruit"}
    }  # Example inventory with prices and categories
    cart = []
    sales = []
    debts = {}
    while True:
        display_menu()
        choice = input("Enter your choice: ")
        if choice == "1":
            sell_item(inventory, cart)
        elif choice == "2":
            add_item(inventory)
        elif choice == "3":
            list_items(inventory)
        elif choice == "4":
            list_categories(inventory)
        elif choice == "5":
            calculate_total(inventory, cart)
        elif choice == "6":
            process_payment(cart, sales, debts)
        elif choice == "7":
            list_debtors(debts)
        elif choice == "8":
            print("Exiting program.")
            break
        else:
            print("Invalid choice. Please try again.")

# Main program
pos_system()

accounts Dictionary: This dictionary is used to store account details. The account number is the key, and the value is another dictionary containing the account holder’s name and balance.

create_account Function: This function allows a user to create a new account. It prompts the user to enter their account number, name, and initial deposit amount. It then adds this information to the accounts dictionary.

deposit Function: This function allows a user to deposit money into their account. It prompts the user to enter their account number and the amount to deposit. If the account exists, it adds the deposited amount to the account’s balance.

withdraw Function: This function allows a user to withdraw money from their account. It prompts the user to enter their account number and the amount to withdraw. If the account exists and has sufficient balance, it deducts the withdrawal amount from the account’s balance.

transfer Function: This function allows a user to transfer money from their account to another account. It prompts the user to enter their account number, the recipient’s account number, and the amount to transfer. If both accounts exist and the sender has sufficient balance, it transfers the amount from the sender’s account to the recipient’s account.

Main Program Loop: This loop repeatedly displays a menu of options for the user to choose from (create account, deposit, withdraw, transfer, or exit). Depending on the user’s choice, it calls the corresponding function.

Styled Code using Tkinter

import tkinter as tk

def sell_item():
    product_name = entry_product_name.get()
    if product_name not in inventory:
        label_status.config(text="Product not found.")
        return
    quantity_needed = int(entry_quantity.get())
    cart.append({"name": product_name, "quantity": quantity_needed})
    label_status.config(text=f"Added {quantity_needed} units of {product_name} to cart")

def add_item():
    product_name = entry_product_name.get()
    if product_name in inventory:
        label_status.config(text="Product already exists.")
        return
    price = float(entry_price.get())
    category = entry_category.get()
    inventory[product_name] = {"price": price, "category": category}
    label_status.config(text=f"Added {product_name} to inventory")

def list_items():
    text_items.delete(1.0, tk.END)
    for product_name, details in inventory.items():
        text_items.insert(tk.END, f"{product_name}: ${details['price']}, Category: {details['category']}\n")

def list_categories():
    categories = set(details['category'] for details in inventory.values())
    label_status.config(text="Categories: " + ", ".join(categories))

def calculate_total():
    total = sum(inventory[item["name"]]["price"] * item["quantity"] for item in cart)
    label_status.config(text=f"Total: ${total:.2f}")

def process_payment():
    total = sum(inventory[item["name"]]["price"] * item["quantity"] for item in cart)
    payment = float(entry_payment.get())
    if payment < total:
        label_status.config(text="Insufficient payment. Payment must be equal to or greater than the total.")
        return
    customer_name = entry_customer_name.get()
    if payment > total:
        change = payment - total
        label_status.config(text=f"Payment successful. Change: ${change:.2f}")
    else:
        change = 0
        label_status.config(text="Payment successful. No change.")
    sale = {"items": cart.copy(), "total": total, "customer_name": customer_name}
    sales.append(sale)
    if payment < total:
        debt = total - payment
        debts[customer_name] = debts.get(customer_name, 0) + debt
        label_status.config(text=f"Added ${debt:.2f} to {customer_name}'s debt.")

def list_debtors():
    text_items.delete(1.0, tk.END)
    for customer, debt in debts.items():
        text_items.insert(tk.END, f"{customer}: ${debt:.2f}\n")

# Initialize tkinter window
root = tk.Tk()
root.title("POS System")

# Create GUI elements
label_product_name = tk.Label(root, text="Product Name:")
entry_product_name = tk.Entry(root)
label_quantity = tk.Label(root, text="Quantity:")
entry_quantity = tk.Entry(root)
button_sell = tk.Button(root, text="Sell Item", command=sell_item)

label_price = tk.Label(root, text="Price:")
entry_price = tk.Entry(root)
label_category = tk.Label(root, text="Category:")
entry_category = tk.Entry(root)
button_add = tk.Button(root, text="Add Item", command=add_item)

button_list_items = tk.Button(root, text="List Items", command=list_items)
button_list_categories = tk.Button(root, text="List Categories", command=list_categories)

button_calculate_total = tk.Button(root, text="Calculate Total", command=calculate_total)

label_payment = tk.Label(root, text="Payment Amount:")
entry_payment = tk.Entry(root)
label_customer_name = tk.Label(root, text="Customer's Name:")
entry_customer_name = tk.Entry(root)
button_process_payment = tk.Button(root, text="Process Payment", command=process_payment)

button_list_debtors = tk.Button(root, text="List Debtors", command=list_debtors)
text_items = tk.Text(root, height=10, width=50)

label_status = tk.Label(root, text="", fg="red")

# Place GUI elements on the window
label_product_name.grid(row=0, column=0)
entry_product_name.grid(row=0, column=1)
label_quantity.grid(row=0, column=2)
entry_quantity.grid(row=0, column=3)
button_sell.grid(row=0, column=4)

label_price.grid(row=1, column=0)
entry_price.grid(row=1, column=1)
label_category.grid(row=1, column=2)
entry_category.grid(row=1, column=3)
button_add.grid(row=1, column=4)

button_list_items.grid(row=2, column=0)
button_list_categories.grid(row=2, column=1)

button_calculate_total.grid(row=3, column=0)

label_payment.grid(row=4, column=0)
entry_payment.grid(row=4, column=1)
label_customer_name.grid(row=4, column=2)
entry_customer_name.grid(row=4, column=3)
button_process_payment.grid(row=4, column=4)

button_list_debtors.grid(row=5, column=0)
text_items.grid(row=6, column=0, columnspan=5)

label_status.grid(row=7, column=0, columnspan=5)

# Initialize POS system variables
inventory = {
    "apple": {"price": 1.00, "category": "fruit"},
    "banana": {"price": 0.50, "category": "fruit"},
    "orange": {"price": 0.75, "category": "fruit"}
}
cart = []
sales = []
debts = {}

# Start the tkinter event loop
root.mainloop()

Arguments

Information can be passed into functions as arguments.

Arguments are specified after the function name, inside the parentheses. You can add as many arguments as you want, just separate them with a comma.

The following example has a function with one argument (fname). When the function is called, we pass along a first name, which is used inside the function to print the full name:

def my_function(fname):#THE Argument here is fname
  print(fname + " Refsnes")

my_function("Emil")#fname argument gets replaced with EMil
my_function("Tobias")#Argument fname gets replaced with Tobias
my_function("Linus")#Argument fname gets replaced with Linus
def function(age):#argument Age
  print(str(age) + " is my age")

function(20)#Argument age gets replaced with  20 which is converted to a string to allow concatenation
function(22)#Argument or Parameter age gets replaced with 22 which is converted to a string to allow concatenation
function(25)

Parameters or Arguments?

The terms parameter and argument can be used for the same thing: information that are passed into a function.

From a function’s perspective:

A parameter is the variable listed inside the parentheses in the function definition.

An argument is the value that is sent to the function when it is called.

Number of Arguments

By default, a function must be called with the correct number of arguments. Meaning that if your function expects 2 arguments, you have to call the function with 2 arguments, not more, and not less.

def my_function(fname, lname):#Here we have 2 arguments
  print(fname + " " + lname)

my_function("Emil", "Refsnes")# the 2 parameter are getting replaced
def area_circle(radius):
  global pi
  pi=3.142
  return pi*radius**2

radius= float(input("Enter The Radius: "))
my_circle=area_circle(12)
print(my_circle)
#case 2 using the math library
import math

def circle(radius, pi=math.pi):
  return pi*radius**2

radius=float(input("Enter the radius of your circle: "))

my_circle=circle(radius)
print(my_circle)
import math

#creating  the menu
def menu():
    print("=== MENU ===")
    print("1. Area Of A Circle")
    print("2. Area Of A Rectangle")
    print("3. Area Of A Sphere")
    print("4. Area Of A Cone")
    print("5. Area Of A Pyramid")
    print("6. Perimeter Of A Circle")
    print("7. Perimeter Of A Rectangle")
    print("8. Perimeter Of A Sphere")
    print("9. Perimeter Of A Cone")
    print("10. Perimeter Of A Pyramid")
    print("11. Quit")

#creating the function to calcurate area of a circle
def area_circle(radius):
    return math.pi * radius**2

#creating the function to calcurate area of a rectangle
def area_rectangle(length, width):
    return length * width

#creating the function to calcurate area of a sphere
def area_sphere(radius):
    return 4 * math.pi * radius**2

#creating the function to calcurate area of a cone
def volume_cone(radius, height):
    return math.pi * radius**2 * height / 3

#creating the function to calcurate area of a pyramid
def volume_pyramid(base_area, height):
    return base_area * height / 3

#creating the function to calcurate perimeter of a circle
def perimeter_circle(radius):
    return 2 * math.pi * radius

#creating the function to calcurate perimeter of a rectangle
def perimeter_rectangle(length, width):
    return 2 * (length + width)

#creating the function to calcurate perimeter of a sphere
def perimeter_sphere(radius):
    return 2 * math.pi * radius

#creating the function calculator
def calculator():
    while True:
        menu()
        choice = input("Enter your Choice: ")

        if choice == '1':
            radius = float(input("Enter the radius of the circle: "))
            print("Area of the circle:", area_circle(radius))

        elif choice == '2':
            length = float(input("Enter the length of the rectangle: "))
            width = float(input("Enter the width of the rectangle: "))
            print("Area of the rectangle:", area_rectangle(length, width))

        elif choice == '3':
            radius = float(input("Enter the radius of the sphere: "))
            print("Surface area of the sphere:", area_sphere(radius))

        elif choice == '4':
            radius = float(input("Enter the radius of the cone: "))
            height = float(input("Enter the height of the cone: "))
            print("Volume of the cone:", volume_cone(radius, height))

        elif choice == '5':
            base_area = float(input("Enter the base area of the pyramid: "))
            height = float(input("Enter the height of the pyramid: "))
            print("Volume of the pyramid:", volume_pyramid(base_area, height))

        elif choice == '6':
            radius = float(input("Enter the radius of the circle: "))
            print("Perimeter of the circle:", perimeter_circle(radius))

        elif choice == '7':
            length = float(input("Enter the length of the rectangle: "))
            width = float(input("Enter the width of the rectangle: "))
            print("Perimeter of the rectangle:", perimeter_rectangle(length, width))

        elif choice == '8':
            radius = float(input("Enter the radius of the sphere: "))
            print("Circumference of the sphere:", perimeter_sphere(radius))

        elif choice == '9':
            print("Perimeter of a cone is not implemented yet.")

        elif choice == '10':
            print("Perimeter of a pyramid is not implemented yet.")

        elif choice == '11':
            print("Exiting the program.")
            break#breaking out of the loop so as to terminate the loop

        else:
            print("Invalid choice. Please enter a number between 1 and 11.")

calculator()#calling this function so as to call  the menu

Arbitrary Arguments, *args

If you do not know how many arguments that will be passed into your function, add a * before the parameter name in the function definition.

This way the function will receive a tuple of arguments, and can access the items accordingly:

def my_function(*kids):
  print("The youngest child is " + kids[2])

my_function("Emil", "Tobias", "Linus")

Arbitrary Arguments are often shortened to *args in Python documentations.

REFRESHMENTS ABOUT ARGUMENTS We shall look at some cases.

Unpacking strings

strings="hello", "charles", "are", "you", "going", "home"
a,b,*c=strings
print(a)
print(b)
print(c)

Unpacking Lists

list=list((1,2,3,4,5,6,7,8,9,10))
a,b,c,d,e,f,g,h,*i=list
print(a)
print(b)
print(i)

Unpacking Tuples

tuple=(1,23,4,5,6,7,8,9,10)
a,b,c,d,e,f,*g=tuple
print(a)
print(b)
print(c)
print(g)
print(e)

Unpacking sets

set={1,2,3,4,5,6,7,8,9,10,11}
a,b,c,d,e,f,g,*h=set
print(a)
print(b)
print(c)
print(d)
print(h)
print(f)

Discussion

We notice that in the common data arrays the asterik * is before the variable to be assigned but in functions it is different check example below.

def my_function(*kids):
  print("The youngest child is " + kids[2])#fetches index 2

my_function("Emil", "Tobias", "Linus")
def fruits(*sweetOnes):
  print("The sweetest Fruits are " + sweetOnes[3])#fetches index 3
fruits("lemon", "orange", "pineapple", "apple", "mangos", "passion", "avoccados")
def fruits(*sweetOnes):
  print("The sweetest Fruits are " + sweetOnes[-3])#fetches index -3
fruits("lemon", "orange", "pineapple", "apple", "mangos", "passion", "avoccados")

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")
def function2(treyzz, songs, dance, office, library):
  print("Treyzz has this feature in it and "+ library)

function2(treyzz="Treyzz.com", songs="all types", dance="all dance types", office="all office tools", library="all library tools")

The phrase Keyword Arguments are often shortened to kwargs in Python documentations.

Arbitrary Keyword Arguments, **kwargs

If you do not know how many keyword arguments that will be passed into your function, add two asterisk: ** before the parameter name in the function definition.

This way the function will receive a dictionary of arguments, and can access the items accordingly:

def my_function(**kid):
  print("His last name is " + kid["lname"])

my_function(fname = "Tobias", lname = "Refsnes")

Arbitrary Kword Arguments are often shortened to **kwargs in Python documentations.

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")
def function2(Your_name="Charles"):
  print("My name is, " + Your_name)
function2("Elvis")
function2("Kim")
function2("Jane")

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)
def funct2(fruits):
  for x in fruits:
    print(x)

fruits=["mango", "orange", "lemon", "passion", "watermelon", "apples"]
funct2(fruits)
def funct3(integers):
  for x in integers:
    print(x)

integers = [1,2,3,4,5,6,7,8,9,10]
funct3(integers)

Return Values

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

def my_function(x):
  return 5 * x

print(my_function(3))
print(my_function(5))
print(my_function(9))

The pass Statement

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
def funct2():
  for x in range(1,20):
    print( x)
    if x == 15:
      pass

funct2()
#check how the continue case works
def funct2():
  for x in range(1,20):
    print( x)
    if x == 15:
      continue

funct2()
#check how the break case works
def funct2():
  for x in range(1,20):
    print( x)
    if x == 15:
      break

funct2()

Positional-Only Arguments

You can specify that a function can have ONLY positional arguments, or ONLY keyword arguments.

To specify that a function can have only positional arguments, add , / after the arguments:

def my_function(x, /):
  print(x)

my_function(3)
def funct2(charles, /):
  print(charles)

funct2("I believe in Jesus Christ")

Using / in a function definition to specify that only positional arguments are allowed can be useful in certain situations where you want to enforce a specific calling convention or provide clarity to users of your function. Here are some reasons you might consider using it:

Clarity and Readability: By specifying that a function only accepts positional arguments, you make it clear to users of the function that they should not use keyword arguments. This can improve the readability of your code and make it easier for others to understand how to use your function correctly.

Enforcing Argument Order: Sometimes, the order of arguments is important for the function to work correctly. By allowing only positional arguments, you ensure that users must provide the arguments in the correct order, which can prevent potential errors.

Compatibility with Older Versions of Python: In older versions of Python (before Python 3.8), / was not supported in function definitions. If you need to maintain compatibility with these older versions, you may use / to indicate that only positional arguments are allowed.

Here’s an example to illustrate the use of / to specify that a function can only accept positional arguments:

def example_function(arg1, arg2, /):
    print(f"arg1: {arg1}, arg2: {arg2}")

# This will work
example_function(1, 2)

# This will raise a TypeError
#example_function(arg1=1, arg2=2)
def myInfo(years, name):
  print(f"I am {years} years old, and my name is {name}")

myInfo(25,"Charles")

Keyword-Only Arguments

To specify that a function can have only keyword arguments, add *, before the arguments:

def my_function(*, x):
  print(x)

my_function(x = 3)
def funct2(*,x,y,z):
  print(x)

funct2(x="charles", y="John", z="Jane")
def funct2(*,x,y,z):
  print(x, z)

funct2(x="charles", y="John", z="Jane")

Without the *, you are allowed to use positionale arguments even if the function expects keyword arguments:

def my_function():
  print("hello world")

my_function()
def my_function(x):
  print(x)

my_function(3)

Combine Positional-Only and Keyword-Only

You can combine the two argument types in the same function.

Any argument before the / , are positional-only, and any argument after the *, are keyword-only.

def my_function(a, b, /, *, c, d):
  print(a + b + c + d)

my_function(5, 6, c = 7, d = 8)

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.

The developer should be very careful with recursion as it can be quite easy to slip into writing a function which never terminates, or one that uses excess amounts of memory or processor power. However, when written correctly recursion can be a very efficient and mathematically-elegant approach to programming.

In this example, tri_recursion() is a function that we have defined to call itself (“recurse”). We use the k variable as the data, which decrements (-1) every time we recurse. The recursion ends when the condition is not greater than 0 (i.e. when it is 0).

To a new developer it can take some time to work out how exactly this works, best way to find out is by testing and modifying it.

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)
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n-1)

# Calculate the factorial of 5
result = factorial(5)
print(result)  # Output: 120

In this example, the factorial function calculates the factorial of a number n by recursively calling itself with n-1 until n reaches 0 (the base case). The base case is important to prevent the function from infinitely calling itself, which would lead to a stack overflow.

Recursion can be a powerful tool, but it’s important to use it judiciously. It can make code more concise and elegant for certain problems, but it can also be less efficient and harder to debug than iterative solutions. Understanding how recursion works and when to use it is key to effectively leveraging this technique in your code.

Python Lambda

A lambda function is a small anonymous function.

A lambda function can take any number of arguments, but can only have one expression.

Syntax

lambda arguments : expression

The expression is executed and the result is returned:

x = lambda a : a + 10
print(x(5))
x= lambda a: a**2
print(x(2))#a(2) this is used to show that a is 2thus 2 power 2 which is 4 after printing out x
x = lambda a, b : a * b
print(x(5, 6))
x = lambda a, b, c, d, e, f: f(a + b + c + d - e)
print(x(11, 22, 33, 44, 55, lambda x: x))

This code will output 121. It calculates a + b + c + d – e = 11 + 22 + 33 + 44 – 55 = 55 and then passes this result to the function f, which in this case is the identity function, returning 55.

x = lambda a, b, c : a + b + c
print(x(5, 6, 2))
x = lambda a, b, c, d, e, f: f(a + b + c + d - e)
print(x(11, 22, 33, 44, 5, lambda x: x))

This code defines a lambda function x that takes six arguments a, b, c, d, e, and f, and returns the result of the expression f(a + b + c + d – e). Then, it calls this lambda function with the arguments 11, 22, 33, 44, 5, and a function lambda x: x.

Let’s break down the calculation:

a + b + c + d – e = 11 + 22 + 33 + 44 – 5 = 105

Therefore, the lambda function is called as f(105).

Since the lambda function f is defined as lambda x: x, it simply returns the value it receives as an argument. So, the overall result of the code is 105.

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

Use that function definition to make a function that always doubles the number you send in:

def myfunc(n):
  return lambda a : a * n

mydoubler = myfunc(2)

print(mydoubler(11))

Or, use the same function definition to make a function that always triples the number you send in:

def myfunc(n):
  return lambda a : a * n

mytripler = myfunc(3)

print(mytripler(11))

Or, use the same function definition to make both functions, in the same program:

def myfunc(n):
  return lambda a : a * n

mydoubler = myfunc(2)
mytripler = myfunc(3)

print(mydoubler(11))
print(mytripler(11))

Use lambda functions when an anonymous function is required for a short period of time.

Use lambda functions when an anonymous function is required for a short period of time.

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"]

What is an Array?

An array is a special variable, which can hold more than one value at a time.

If you have a list of items (a list of car names, for example), storing the cars in single variables could look like this:

car1 = "Ford"
car2 = "Volvo"
car3 = "BMW"

However, what if you want to loop through the cars and find a specific one? And what if you had not 3 cars, but 300?

The solution is an array!

An array can hold many values under a single name, and you can access the values by referring to an index number.

Access the Elements of an Array

You refer to an array element by referring to the index number.

x = cars[0]

Modify the value of the first array item:

cars[0] = "Toyota"

The Length of an Array

Use the len() method to return the length of an array (the number of elements in an array).

x = len(cars)
x

Looping Array Elements

You can use the for in loop to loop through all the elements of an array.

for x in cars:
  print(x)

Adding Array Elements

You can use the append() method to add an element to an array.

cars.append("Honda")
cars

Removing Array Elements

You can use the pop() method to remove an element from the array.

cars.pop(1)
cars

You can also use the remove() method to remove an element from the array.

cars.remove("Honda")
cars

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.

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() 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

Note: Python does not have built-in support for Arrays, but Python Lists can be used instead.

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.Each class instance can have attributes attached to it for maintaining its state. Class instances can also have methods (defined by their class) for modifying their state.

Create a Class

To create a class, use the keyword class:

class MyClass:
  x = 5
Syntax: Class Definition

class ClassName:
    # Statement
Syntax: Object Definition

obj = ClassName()
print(obj.atrr)
class monkey:
  print("I behave well.")

myAnimal=monkey()

print(myAnimal)
class fruits:
    def __init__(self, orange, lemon, mango):
        self.orange = orange
        self.lemon = lemon
        self.mango = mango

class juicy(fruits):
    def __init__(self):
        super().__init__("orange", "lemon", "mango")
        print("I am a watermelon")

class sweet(fruits):
    def __init__(self):
        super().__init__("orange", "lemon", "mango")
        print("I am a mango or orange")

class sour(fruits):
    def __init__(self):
        super().__init__("orange", "lemon", "mango")
        print("I am a lemon")

class watery(fruits):
    def __init__(self):
        super().__init__("orange", "lemon", "mango")
        print("I am a watermelon or a pear")

sweet_instance = sweet()  # Creating an instance of the sweet class
class wildAnimal:
  def __init__(self, wild, domestic):
    self.wild = wild
    self.domestic  = domestic

class monkey(wildAnimal):
  def __init__(self, jumper, funny):
    self.jumnper = jumnper
    self.funny = funny
    print(f"I am {self.jumper} and {self.funny}")
class donkey(wildAnimal):
  def __init__(self, workmode, selfless):
    self.workmode = workmode
    self.selfless = selfless
    print(f"I am a donkey and I possess the following work mode = {self.workmode}, selfless = {self.selfless}")

animalA= donkey("yes", "yes")
print(animalA)

In Python, the four fundamental principles of object-oriented programming (OOP) are encapsulation, inheritance, polymorphism, and abstraction. Here’s an example that demonstrates each of these principles:

Encapsulation: Encapsulation is the concept of restricting access to certain parts of an object to prevent direct modification. This is typically achieved by using private attributes and providing public methods to access or modify them.

class BankAccount:
    def __init__(self, account_number, balance):
        self._account_number = account_number  # Private attribute
        self._balance = balance  # Private attribute

    def deposit(self, amount):
        self._balance += amount

    def withdraw(self, amount):
        if self._balance >= amount:
            self._balance -= amount
        else:
            print("Insufficient funds")

    def get_balance(self):
        return self._balance

# Create an instance of BankAccount
account = BankAccount("123456", 1000)
print(account.get_balance())  # Output: 1000
account.withdraw(500)
print(account.get_balance())  # Output: 500
class BankAccount:
    def __init__(self, account_number, balance):
        self._account_number = account_number  # Private attribute
        self._balance = balance  # Private attribute

    def deposit(self, amount):
        self._balance += amount

    def withdraw(self, amount):
        if self._balance >= amount:
            self._balance -= amount
        else:
            print("Insufficient funds")

    def get_balance(self):
        return self._balance

# Create an instance of BankAccount
account = BankAccount("123456", 1000)
print(account.get_balance())  # Output: 1000
account.withdraw(500)
print(account.get_balance())  # Output: 500
class fruits:
  def __init__(self, sweet, sour,juicy):
    self.sweet = sweet #private variable
    self.sour = sour #private variable
    self.juicy = juicy #private variable

  def orange(self, taste):
    self._sweet = taste
    print(f"I am {self.sweet}")

my_fruit = fruits("sweet", "sour", "juicy")
my_orange= my_fruit.orange("sour")
print(my_orange)

Inheritance: Inheritance is the mechanism by which a new class derives attributes and methods from an existing class. The new class is called a subclass, and the existing class is called a superclass.

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

    def speak(self):
        raise NotImplementedError("Subclass must implement this method")


class Dog(Animal):  # Dog class inherits from Animal
    def speak(self):
        return "Woof!"

class Cat(Animal):  # Cat class inherits from Animal
    def speak(self):
        return "Meow!"

# Create instances of Dog and Cat
dog = Dog("Buddy")
cat = Cat("Whiskers")
print(dog.speak())  # Output: Woof!
print(cat.speak())  # Output: Meow!
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        raise NotImplementedError("Subclass must implement this method")


class Dog(Animal):  # Dog class inherits from Animal
    def speak(self):
        return "Woof!"

class Cat(Animal):  # Cat class inherits from Animal
    def speak(self):
        return "Meow!"

# Create instances of Dog and Cat
dog = Dog("Buddy")
cat = Cat("Whiskers")
print(dog.speak())  # Output: Woof!
print(cat.speak())  # Output: Meow!

Polymorphism: Polymorphism allows objects to be treated as instances of their superclass, even when they are instances of a subclass. This enables code to be written that operates on the superclass and can be applied to subclasses without modification.

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

    def speak(self):
        raise NotImplementedError("Subclass must implement this method")


class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

dog = Dog("Buddy")
cat = Cat("Whiskers")

def make_sound(animal):
    return animal.speak()

print(make_sound(dog))  # Output: Woof!
print(make_sound(cat))  # Output: Meow!

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

    def speak(self):
        raise NotImplementedError("Subclass must implement this method")


class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

dog = Dog("Buddy")
cat = Cat("Whiskers")

def make_sound(animal):
    return animal.speak()

print(make_sound(dog))  # Output: Woof!
print(make_sound(cat))  # Output: Meow!

Abstraction: Abstraction is the process of hiding the complex implementation details and showing only the necessary features of an object. This is often achieved by defining abstract classes or methods that must be implemented by subclasses.

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2

class Rectangle(Shape):
    def __init__(self, length, width):
        self.length = length
        self.width = width

    def area(self):
        return self.length * self.width

# Cannot instantiate Shape directly because it's abstract
# shape = Shape()  # Raises TypeError

# Create instances of Circle and Rectangle
circle = Circle(5)
rectangle = Rectangle(4, 6)
print(circle.area())  # Output: 78.5
print(rectangle.area())  # Output: 24
from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2

class Rectangle(Shape):
    def __init__(self, length, width):
        self.length = length
        self.width = width

    def area(self):
        return self.length * self.width

# Cannot instantiate Shape directly because it's abstract
# shape = Shape()  # Raises TypeError

# Create instances of Circle and Rectangle
circle = Circle(5)
rectangle = Rectangle(4, 6)
print(circle.area())  # Output: 78.5
print(rectangle.area())  # Output: 24

Create Object

Now we can use the class named MyClass to create objects:

p1 = MyClass()
print(p1.x)

The init() Function

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.

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

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

p1 = Person("John", 36)

print(p1.name)
print(p1.age)

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

The str() Function

The str() function controls what should be returned when the class object is represented as a string.

If the str() function is not set, the string representation of the object is returned:

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

p1 = Person("John", 36)

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

  def __str__(self):
    return f"{self.name}({self.age})"

p1 = Person("John", 36)

print(p1)

Object Methods

Objects can also contain methods. Methods in objects are functions that belong to the object.

Let us create a method in the Person class:

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

  def myfunc(self):
    print("Hello my name is " + self.name)

p1 = Person("John", 36)
p1.myfunc()

Note: The self parameter is a reference to the current instance of the class, and is used to access variables that belong to the class.

The self Parameter

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

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:

class Person:
  def __init__(mysillyobject, name, age):
    mysillyobject.name = name
    mysillyobject.age = age

  def myfunc(abc):
    print("Hello my name is " + abc.name)

p1 = Person("John", 36)
p1.myfunc()

Modify Object Properties

You can modify properties on objects like this:

p1.age = 40

Delete Object Properties

You can delete properties on objects by using the del keyword:

del p1.age

Delete Objects

You can delete objects by using the del keyword:

del p1

The pass Statement

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

class Person:
  pass

Python Inheritance

Inheritance allows us to define a class that inherits all the methods and properties from another class.

Parent class is the class being inherited from, also called base class.

Child class is the class that inherits from another class, also called derived class.

Create a Parent Class

Any class can be a parent class, so the syntax is the same as creating any other class:

class Person:
  def __init__(self, fname, lname):
    self.firstname = fname
    self.lastname = lname

  def printname(self):
    print(self.firstname, self.lastname)

#Use the Person class to create an object, and then execute the printname method:

x = Person("John", "Doe")
x.printname()

Create a Child Class

To create a class that inherits the functionality from another class, send the parent class as a parameter when creating the child class:

class Student(Person):
  pass

Note: Use the pass keyword when you do not want to add any other properties or methods to the class.

Example

Use the Student class to create an object, and then execute the printname method:

x = Student("Mike", "Olsen")
x.printname()

Add the init() Function

So far we have created a child class that inherits the properties and methods from its parent.

We want to add the init() function to the child class (instead of the pass keyword).

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

Example Add the init() function to the Student class:

class Person:
    def __init__(self, fname, lname):
        self.fname = fname
        self.lname = lname

class Student(Person):
    def __init__(self, fname, lname, student_id, major):
        super().__init__(fname, lname)  # Call the parent class constructor
        self.student_id = student_id    # Add student_id as a property
        self.major = major              # Add major as a property

# Example usage
student = Student("John", "Doe", "12345", "Computer Science")
print(student.fname)        # Accessing inherited property from Person class
print(student.student_id)   # Accessing student_id property from Student class
print(student.major)        # Accessing major property from Student class

When you add the init() function, the child class will no longer inherit the parent’s init() function.

Note: The child’s init() function overrides the inheritance of the parent’s init() function.

To keep the inheritance of the parent’s init() function, add a call to the parent’s init() function:

class Student(Person):
    def __init__(self, fname, lname):
        Person.__init__(self, fname, lname)

# Example usage
student = Student("John", "Doe")

Now we have successfully added the init() function, and kept the inheritance of the parent class, and we are ready to add functionality in the init() function.

Use the super() Function

Python also has a super() function that will make the child class inherit all the methods and properties from its parent:

class Student(Person):
    def __init__(self, fname, lname):
        super().__init__(fname, lname)

# Example usage
student = Student("John", "Doe")

By using the super() function, you do not have to use the name of the parent element, it will automatically inherit the methods and properties from its parent.

Add Properties

class Student(Person):
    def __init__(self, fname, lname):
        super().__init__(fname, lname)
        self.graduationyear = 2019

# Example usage
student = Student("John", "Doe")
print(student.fname)  # Output: John
print(student.lname)  # Output: Doe
print(student.graduationyear)  # Output: 2019

In the example below, the year 2019 should be a variable, and passed into the Student class when creating student objects. To do so, add another parameter in the init() function:

class Student(Person):
    def __init__(self, fname, lname, year):
        super().__init__(fname, lname)
        self.graduationyear = year

# Example usage
x = Student("Mike", "Olsen", 2019)
print(x.fname)  # Output: Mike
print(x.lname)  # Output: Olsen
print(x.graduationyear)  # Output: 2019

Add Methods

class Student(Person):
    def __init__(self, fname, lname, year):
        super().__init__(fname, lname)
        self.graduationyear = year

    def welcome(self):
        print("Welcome", self.fname, self.lname, "to the class of", self.graduationyear)

# Example usage
x = Student("Mike", "Olsen", 2019)
x.welcome()  # Output: Welcome Mike Olsen to the class of 2019

Iterator vs Iterable

Lists, tuples, dictionaries, and sets are all iterable objects. They are iterable containers which you can get an iterator from.

All these objects have a iter() method which is used to get an iterator:

mytuple = ("apple", "banana", "cherry")
myit = iter(mytuple)

print(next(myit))
print(next(myit))
print(next(myit))
mystr = "banana"
myit = iter(mystr)

print(next(myit))
print(next(myit))
print(next(myit))
print(next(myit))
print(next(myit))
print(next(myit))

Looping Through an Iterator

We can also use a for loop to iterate through an iterable object:

mytuple = ("apple", "banana", "cherry")

for x in mytuple:
  print(x)
mystr = "banana"

for x in mystr:
  print(x)

Create an Iterator

To create an object/class as an iterator you have to implement the methods iter() and next() to your object.

As you have learned in the Python Classes/Objects chapter, all classes have a function called init(), which allows you to do some initializing when the object is being created.

The iter() method acts similar, you can do operations (initializing etc.), but must always return the iterator object itself.

The next() method also allows you to do operations, and must return the next item in the sequence.

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self

  def __next__(self):
    x = self.a
    self.a += 1
    return x

myclass = MyNumbers()
myiter = iter(myclass)

print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))

StopIteration

The example above would continue forever if you had enough next() statements, or if it was used in a for loop.

To prevent the iteration from going on forever, we can use the StopIteration statement.

In the next() method, we can add a terminating condition to raise an error if the iteration is done a specified number of times:

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self

  def __next__(self):
    if self.a <= 20:
      x = self.a
      self.a += 1
      return x
    else:
      raise StopIteration

myclass = MyNumbers()
myiter = iter(myclass)

for x in myiter:
  print(x)

Python Classes and 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.

Create a Class

To create a class, use the keyword class:

Create a class named MyClass, with a property named x:

class MyClass:
  x = 5

Defining a Class in Python

To define a class, you need to use the class keyword followed by the class name and a colon, just like you’d do for other compound statements in Python. Then you must define the class body, which will start at the next indentation level:

class ClassName:
    # Class body
    pass

In a class body, you can define attributes and methods as needed. As you already learned, attributes are variables that hold the class data, while methods are functions that provide behavior and typically act on the class data.

Here’s a list of common parts of Python classes along with small code examples

examples:

Class Definition:

Definition of a simple class named Person:

class Person:
    pass

Instance Creation:

Creating an instance of the Person class:

person1 = Person()

Constructor (init):

Defining a class with a constructor that initializes attributes:

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

Instance Attributes:

Accessing instance attributes:

person1.name = "Alice"
person1.age = 30

Methods:

Adding a method to the Person class to print information:

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

    def display_info(self):
        print(f"Name: {self.name}, Age: {self.age}")

Method Invocation:

Invoking the display_info method:

person1.display_info()

Class Variables:

Adding a class variable to the Person class:

class Person:
    total_count = 0

    def __init__(self, name, age):
        self.name = name
        self.age = age
        Person.total_count += 1

Inheritance:

Creating a subclass Employee that inherits from Person:

class Employee(Person):
    def __init__(self, name, age, salary):
        super().__init__(name, age)
        self.salary = salary

Encapsulation:

Using private attributes in the Person class:

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

    def get_name(self):
        return self.__name

    def set_name(self, name):
        self.__name = name

Polymorphism:

Using polymorphism with a speak method in both Person and Employee classes:

class Person:
    def speak(self):
        print("Person speaks")

class Employee(Person):
    def speak(self):
        print("Employee speaks")

Create Object

Now we can use the class named MyClass to create objects:

Example Create an object named p1, and print the value of x:

p1 = MyClass()
print(p1.x)

Explanation of each part:

Class Definition (class Person): Defines a new class named Person.

Class Variable (total_count = 0): A variable shared among all instances of the class. It tracks the total number of Person instances.

Constructor (init method): A special method used for initializing newly created objects. It sets initial values for the name and age attributes of each Person instance.

Instance Variables (self.name and self.age): Variables that hold data unique to each instance of the class.

Method (display_info method): A function defined inside the class that can be called on instances of the class. It prints the name and age of a Person instance.

Creating Instances (person1 and person2): Instantiating objects of the Person class.

Accessing Instance Variables and Calling Methods (person1.display_info()): Using dot notation to access instance variables and call methods on instances of the class.

Accessing Class Variable (Person.total_count): Using the class name to access the class variable total_count.

# Class definition
class Person:
    # Class variable
    total_count = 0

    # Constructor (initializer) method
    def __init__(self, name, age):
        # Instance variables
        self.name = name
        self.age = age
        # Incrementing total_count when a new instance is created
        Person.total_count += 1

    # Method to display information
    def display_info(self):
        print(f"Name: {self.name}, Age: {self.age}")

# Creating instances (objects) of the Person class
person1 = Person("Alice", 30)
person2 = Person("Bob", 25)

# Accessing instance variables and calling methods
person1.display_info()  # Output: Name: Alice, Age: 30
person2.display_info()  # Output: Name: Bob, Age: 25

# Accessing class variable
print("Total Persons:", Person.total_count)  # Output: Total Persons: 2

Inheritance

class Animal:

    # attribute and method of the parent class
    name = ""

    def eat(self):
        print("I can eat")

# inherit from Animal
class Dog(Animal):

    # new method in subclass
    def display(self):
        # access name attribute of superclass using self
        print("My name is ", self.name)

# create an object of the subclass
labrador = Dog()

# access superclass attribute and method
labrador.name = "Rohu"
labrador.eat()

# call subclass method
labrador.display()

Method Overriding in Python Inheritance:

In the previous example, we see the object of the subclass can access the method of the superclass.

However, what if the same method is present in both the superclass and subclass?

In this case, the method in the subclass overrides the method in the superclass. This concept is known as method overriding in Python.

Example: Method Overriding

class Animal:

    # attributes and method of the parent class
    name = ""

    def eat(self):
        print("I can eat")

# inherit from Animal
class Dog(Animal):

    # override eat() method
    def eat(self):
        print("I like to eat bones")

# create an object of the subclass
labrador = Dog()

# call the eat() method on the labrador object
labrador.eat()

The super() Function in Inheritance

Previously we saw that the same method (function) in the subclass overrides the method in the superclass.

However, if we need to access the superclass method from the subclass, we use the super() function. For example,

class Animal:

    name = ""

    def eat(self):
        print("I can eat")

# inherit from Animal
class Dog(Animal):

    # override eat() method
    def eat(self):

        # call the eat() method of the superclass using super()
        super().eat()

        print("I like to eat bones")

# create an object of the subclass
labrador = Dog()

labrador.eat()

Inheritance Types

There are 5 different types of inheritance in Python. They are:

Single Inheritance: a child class inherits from only one parent class.

Multiple Inheritance: a child class inherits from multiple parent classes.

Multilevel Inheritance: a child class inherits from its parent class, which is inheriting from its parent class.

Hierarchical Inheritance: more than one child class are created from a single parent class.

Hybrid Inheritance: combines more than one form of inheritance.

examples of each type of inheritance in Python

Single Inheritance:

A child class inherits from only one parent class.

class Parent:
    def display(self):
        print("Parent class method")

class Child(Parent):
    def show(self):
        print("Child class method")

obj = Child()
obj.display()
obj.show()

Multiple Inheritance:

A child class inherits from multiple parent classes.

class Class1:
    def method1(self):
        print("Method 1 from Class1")

class Class2:
    def method2(self):
        print("Method 2 from Class2")

class MultiClass(Class1, Class2):
    def method3(self):
        print("Method 3 from MultiClass")

obj = MultiClass()
obj.method1()
obj.method2()
obj.method3()

Multilevel Inheritance:

A child class inherits from its parent class, which is inheriting from its parent class.

class Grandparent:
    def method1(self):
        print("Method 1 from Grandparent")

class Parent(Grandparent):
    def method2(self):
        print("Method 2 from Parent")

class Child(Parent):
    def method3(self):
        print("Method 3 from Child")

obj = Child()
obj.method1()
obj.method2()
obj.method3()

Hierarchical Inheritance:

More than one child class is created from a single parent class.

class Parent:
    def method1(self):
        print("Method 1 from Parent")

class Child1(Parent):
    def method2(self):
        print("Method 2 from Child1")

class Child2(Parent):
    def method3(self):
        print("Method 3 from Child2")

obj1 = Child1()
obj2 = Child2()
obj1.method1()
obj1.method2()
obj2.method1()
obj2.method3()

Hybrid Inheritance:

Combines more than one form of inheritance.

class Class1:
    def method1(self):
        print("Method 1 from Class1")

class Class2(Class1):
    def method2(self):
        print("Method 2 from Class2")

class Class3:
    def method3(self):
        print("Method 3 from Class3")

class Hybrid(Class2, Class3):
    def method4(self):
        print("Method 4 from Hybrid")

obj = Hybrid()
obj.method1()
obj.method2()
obj.method3()
obj.method4()

Other Examples Of Inheritance

class my_class:
  print ("My Class Has", 20*3, "Members")

Man_class= my_class
print(Man_class)
class Animal:
    def __init__(self, wild, domestic):
        self.wild = wild
        self.domestic = domestic
#Added super().__init__(wild, domestic) in the Monkey class constructor to initialize the wild and domestic attributes from the Animal class.
class Monkey(Animal):
    def __init__(self, wild, domestic, body):
        super().__init__(wild, domestic)
        self.body = body
        print(f"A monkey has fur on its {self.body} and is wild: {self.wild}, domestic: {self.domestic}")

my_monkey = Monkey("yes", "no", "body")
class fruits:
  def __init__(self, sweet, sour, bitter, watery, juicy):
    self.sweet = sweet
    self.sour = sour
    self.bitter = bitter
    self.juicy = juicy
    pass

class mango(fruits):
  def __init__(self, sweet):
    super().__init__(sweet, sour=None, bitter=None, watery=None, juicy=None)
    self.sweet = sweet
    print(f"The mango is a {self.sweet}")
my_mango = mango("sweet")
print(my_mango)
class education:
  def __init__(self, beginner, intermediate, expert):
    self.beginner = beginner
    self.intermediate = intermediate
    self.expert = expert

class grade_6(education):
  def __init__(self, young,beginner):
    super().__init__(beginner, intermediate=False, expert=False)
    self.young = young
    print(f"You are in grade 6 and you are {self.beginner}")
john = grade_6("beginner","young")
print(john)
class world:
  def __init__(self, jungle, habitated):
    self.jungle = jungle
    self.habitated = habitated
  def people(self):
    return self.habitated#GLOBAL VARIABLE

  def animals(self):
    return self.__animals#PRIVATE vARIABLE
class lion(world):
  def __init__(self, wild):
    self.wild=wild
    super().__init__(jungle=None, habitated=False)
    print(f"The lion lives in the Jungle and is {self.wild}")
my_cub=lion("wild")
print(my_cub) # CALLING THE CLASS CLUB
print(my_cub.people()) #CALLING THE FUNCTION HABITATED FROM THE CLASS WORLD WHICH IS INHERITED THIS WILL RETURN FALSE
class room:
  def __init__(self, bedseater, one-bedroom, two-bedroom):
    self.bedseater = bedseater
    self.one_bedroom = one_bedroom
    self.two_bedroom = two_bedroom

Encapsulation

Encapsulation is one of the key features of object-oriented programming. Encapsulation refers to the bundling of attributes and methods inside a single class.

It prevents outer classes from accessing and changing attributes and methods of a class. This also helps to achieve data hiding.

In Python, we denote private attributes using underscore as the **prefix i.e single _ or double __.** For example,

Encapsulation is one of the fundamental concepts in object-oriented programming (OOP). It describes the idea of wrapping data and the methods that work on data within one unit. This puts restrictions on accessing variables and methods directly and can prevent the accidental modification of data. To prevent accidental change, an object’s variable can only be changed by an object’s method. Those types of variables are known as private variables.

A class is an example of encapsulation as it encapsulates all the data that is member functions, variables, etc. The goal of information hiding is to ensure that an object’s state is always valid by controlling access to attributes that are hidden from the outside world.

Consider a real-life example of encapsulation, in a company, there are different sections like the accounts section, finance section, sales section etc. The finance section handles all the financial transactions and keeps records of all the data related to finance. Similarly, the sales section handles all the sales-related activities and keeps records of all the sales. Now there may arise a situation when due to some reason an official from the finance section needs all the data about sales in a particular month. In this case, he is not allowed to directly access the data of the sales section. He will first have to contact some other officer in the sales section and then request him to give the particular data. This is what encapsulation is. Here the data of the sales section and the employees that can manipulate them are wrapped under a single name “sales section”. Using encapsulation also hides the data. In this example, the data of the sections like sales, finance, or accounts are hidden from any other section.

Protected members

Protected members (in C++ and JAVA) are those members of the class that cannot be accessed outside the class but can be accessed from within the class and its subclasses. **To accomplish this in Python, just follow the convention by prefixing the name of the member by a single underscore “_”**.

Although the protected variable can be accessed out of the class as well as in the derived class (modified too in derived class), it is customary(convention not a rule) to not access the protected out the class body.

Note: The init method is a constructor and runs as soon as an object of a class is instantiated.

# Python program to
# demonstrate protected members

# Creating a base class
class Base:
	def __init__(self):

		# Protected member
		self._a = 2

# Creating a derived class
class Derived(Base):
	def __init__(self):

		# Calling constructor of
		# Base class
		Base.__init__(self)
		print("Calling protected member of base class: ",
			self._a)

		# Modify the protected variable:
		self._a = 3
		print("Calling modified protected member outside class: ",
			self._a)


obj1 = Derived()

obj2 = Base()

# Calling protected member
# Can be accessed but should not be done due to convention
print("Accessing protected member of obj1: ", obj1._a)

# Accessing the protected variable outside
print("Accessing protected member of obj2: ", obj2._a)

Private members

Private members are similar to protected members, the difference is that the class members declared private should neither be accessed outside the class nor by any base class. In Python, there is no existence of Private instance variables that cannot be accessed except inside a class.

However, to define a private member prefix the member name **with double underscore “__”.**

Note: Python’s private and protected members can be accessed outside the class through python name mangling.

# Python program to
# demonstrate private members

# Creating a Base class


class Base:
	def __init__(self):
		self.a = "GeeksforGeeks by kncmap"
		self.__c = "GeeksforGeeks by kncmap"

# Creating a derived class
class Derived(Base):
	def __init__(self):

		# Calling constructor of
		# Base class
		Base.__init__(self)
		print("Calling private member of base class: ")
		print(self.__c)


# Driver code
obj1 = Base()
print(obj1.a)

# Uncommenting print(obj1.c) will
# raise an AttributeError

# Uncommenting obj2 = Derived() will
# also raise an AttributeError as
# private member of base class
# is called inside derived class
class Computer:

    def __init__(self):
        self.__maxprice = 900

    def sell(self):
        print("Selling Price: {}".format(self.__maxprice))

    def setMaxPrice(self, price):
        self.__maxprice = price

c = Computer()
c.sell()

# change the price
c.__maxprice = 1000
c.sell()

# using setter function
c.setMaxPrice(1000)
c.sell()

There are two main types of encapsulation:

Data Encapsulation: Data encapsulation is the** process of hiding the internal state of an object and restricting access to it through public methods.** This ensures that the object’s state is accessed and modified in a controlled manner. In Python, encapsulation is achieved using the concept of private attributes and methods.

Example:

class Person:
    def __init__(self, name, age):
        self.__name = name  # Private attribute
        self.__age = age

    def get_name(self):
        return self.__name  # Public method to access private attribute

    def set_name(self, name):
        self.__name = name  # Public method to modify private attribute

p = Person("Alice", 30)
print(p.get_name())  # Output: Alice
p.set_name("Bob")
print(p.get_name())  # Output: Bob

Method Encapsulation: Method encapsulation involves bundling related methods together within a class. This helps in organizing the code and improving code readability and maintainability. Method encapsulation is achieved by defining methods within a class that perform specific tasks related to the class’s functionality.

Example:

class Calculator:
    def add(self, a, b):
        return a + b

    def subtract(self, a, b):
        return a - b

    def multiply(self, a, b):
        return a * b

    def divide(self, a, b):
        if b != 0:
            return a / b
        else:
            return "Division by zero not allowed"

calc = Calculator()
print(calc.add(5, 3))  # Output: 8
print(calc.subtract(5, 3))  # Output: 2

These examples demonstrate how encapsulation helps in creating classes that encapsulate data and methods, providing a clean interface for interacting with objects while hiding their internal implementation details.

class Fruits:
    def __init__(self, sweet, sour, bitter, watery, juicy):
        self.__sweet = sweet
        self.__sour = sour
        self.__bitter = bitter
        self.__watery = watery
        self.__juicy = juicy

    def get_sweetness(self):
        return self.__sweet

    def set_sweetness(self, sweet):
        self.__sweet = sweet

    # Add getter and setter methods for other attributes as needed

class Mango(Fruits):
    def __init__(self, sweet):
        super().__init__(sweet, sour=None, bitter=None, watery=None, juicy=None)
        self.__sweet = sweet
        print(f"The mango is {self.__sweet}")

    def get_sweetness(self):
        return self.__sweet

    def set_sweetness(self, sweet):
        self.__sweet = sweet

my_mango = Mango("sweet")
print(my_mango.get_sweetness())

# Using setter method to change sweetness
my_mango.set_sweetness("very sweet")
print(my_mango.get_sweetness())

The init() Function

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.

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

Create a class named Person, use the init() function to assign values for name and age:

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

p1 = Person("John", 36)

print(p1.name)
print(p1.age)
class animal:
  def __init__(self,domestic, wild):
    self.domestic =domestic
    self.wild = wild

cat  = animal("yes", "No")
print(cat.wild)
print(cat.domestic)
class MyClass:
    def __init__(self, value):
        self.value = value

    def print_value(self):
        print(f"The value is {self.value}")

    def double_value(self):
        self.value *= 2

# Creating an instance of MyClass
obj = MyClass(5)

# Calling methods of the class
obj.print_value()  # Output: The value is 5

obj.double_value()
obj.print_value()  # Output: The value is 10
class animal:
  def __init__(self, domestic, wild):
    self.domestic= domestic
    self.wild = wild

  def monkey(self):
    print(f"A monkey is wild? {self.wild}")

monkeys=animal("no", "yes")
monkeys.monkey()

Python Polymorphism

The word “polymorphism” means “many forms”, and in programming it refers to methods/functions/operators with the same name that can be executed on many objects or classes.

Function Polymorphism An example of a Python function that can be used on different objects is the len() function.

String For strings len() returns the number of characters:

x = "Hello World!"

print(len(x))

Data Abstraction in Python

Data abstraction is one of the most essential concepts of Python OOPs which is used to hide irrelevant details from the user and show the details that are relevant to the users. For example, the readers of geeksforgeeks only know that a writer can write an article on geeksforgeeks, and when it gets published readers can read the articles but the reader is not aware of the background process of publishing the article.

A simple example of this can be a car. A car has an accelerator, clutch, and break and we all know that pressing an accelerator will increase the speed of the car and applying the brake can stop the car but we don’t the internal mechanism of the car and how these functionalities can work this detail hiding is known as data abstraction.

To understand data abstraction we should be aware of the below basic concepts:

OOP concepts in Python Classes in Python Abstract classes in Python

Importance of Data Abstraction

It enables programmers to hide complex implementation details while just showing users the most crucial data and functions. This abstraction makes it easier to design modular and well-organized code, makes it simpler to understand and maintain, promotes code reuse, and improves developer collaboration.

Data Abstraction in Python

Data abstraction in Python is a programming concept that hides complex implementation details while exposing only essential information and functionalities to users. In Python, we can achieve data abstraction by using abstract classes and abstract classes can be created using abc (abstract base class) module and abstractmethod of abc module.

Abstraction classes in Python

Abstract class is a class in which one or more abstract methods are defined. When a method is declared inside the class without its implementation is known as abstract method.

Abstract Method: In Python, abstract method feature is not a default feature. To create abstract method and abstract classes we have to import the “ABC” and “abstractmethod” classes from abc (Abstract Base Class) library. Abstract method of base class force its child class to write the implementation of the all abstract methods defined in base class. If we do not implement the abstract methods of base class in the child class then our code will give error. In the below code method_1 is a abstract method created using @abstractmethod decorator.

from abc import ABC, abstractmethod
class BaseClass(ABC):
    @abstractmethod
    def method_1(self):
         #empty body
         pass

Concrete Method: Concrete methods are the methods defined in an abstract base class with their complete implementation. Concrete methods are required to avoid reprication of code in subclasses. For example, in abstract base class there may be a method that implementation is to be same in all its subclasses, so we write the implementation of that method in abstract base class after which we do not need to write implementation of the concrete method again and again in every subclass. In the below code startEngine is a concrete method.

class Car(ABC):
    def __init__(self, brand, model, year):
        self.brand = brand
        self.model = model
        self.year = year
        self.engine_started = True

    def startEngine(self):
        if not self.engine_started:
            print(f"Starting the {self.model}'s engine.")
            self.engine_started = True
        else:
            print("Engine is already running.")

Steps to Create Abstract Base Class and Abstract Method:

Firstly, we import ABC and abstractmethod class from abc (Abstract Base Class) library.

Create a BaseClass that inherits from the ABC class. In Python, when a class inherits from ABC, it indicates that the class is intended to be an abstract base class.

Inside BaseClass we declare an abstract method named “method_1” by using “abstractmethod” decorater. Any subclass derived from BaseClass must implement this method_1 method. We write pass in this method which indicates that there is no code or logic in this method.

from abc import ABC, abstractmethod
class BaseClass(ABC):
    @abstractmethod
    def method_1(self):
         #empty body
         pass

Implementation of Data Abstraction in Python

In the below code, we have implemented data abstraction using abstract class and method. Firstly, we import the required modules or classes from abc library then we create a base class ‘Car’ that inherited from ‘ABC’ class that we have imported. Inside base class we create init function, abstract function and non-abstract functions. To declare abstract function printDetails we use “@abstractmethod” decorator. After that we create child class hatchback and suv. Since, these child classes inherited from abstract class so, we need to write the implementation of all abstract function declared in the base class. We write the implementation of abstract method in both child class. We create an instance of a child class and call the printDetails method. In this way we can achieve the data abstraction.

# Import required modules
from abc import ABC, abstractmethod

# Create Abstract base class
class Car(ABC):
    def __init__(self, brand, model, year):
        self.brand = brand
        self.model = model
        self.year = year

    # Create abstract method
    @abstractmethod
    def printDetails(self):
        pass

    # Create concrete method
    def accelerate(self):
        print("speed up ...")

    def break_applied(self):
        print("Car stop")

# Create a child class
class Hatchback(Car):
    def printDetails(self):
        print("Brand:", self.brand)
        print("Model:", self.model)
        print("Year:", self.year)

    def Sunroof(self):
        print("Not having this feature")

# Create a child class
class Suv(Car):
    def printDetails(self):
        print("Brand:", self.brand)
        print("Model:", self.model)
        print("Year:", self.year)

    def Sunroof(self):
        print("Available")

car1 = Hatchback("Maruti", "Alto", "2022")
car1.printDetails()
car1.accelerate()

Abstraction is a fundamental concept in object-oriented programming (OOP) that refers to the process of hiding the complex implementation details and showing only the necessary features of an object to the outside world. This helps in reducing complexity and increasing efficiency by providing a simplified interface.

There are two main types of abstraction:

Data Abstraction: Data abstraction is the process of hiding the implementation details of data and only showing the essential features to the outside world. In other words, it involves defining a class in such a way that the internal details of how a specific operation is performed are hidden from the user.

Example:

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Rectangle(Shape):
    def __init__(self, length, width):
        self.length = length
        self.width = width

    def area(self):
        return self.length * self.width

rectangle = Rectangle(5, 3)
print(rectangle.area())  # Output: 15
# Python program demonstrate
# abstract base class work
from abc import ABC, abstractmethod
class Car(ABC):
    def mileage(self):
        pass

class Tesla(Car):
    def mileage(self):
        print("The mileage is 30kmph")
class Suzuki(Car):
    def mileage(self):
        print("The mileage is 25kmph ")
class Duster(Car):
     def mileage(self):
          print("The mileage is 24kmph ")

class Renault(Car):
    def mileage(self):
            print("The mileage is 27kmph ")

# Driver code
t= Tesla ()
t.mileage()

r = Renault()
r.mileage()

s = Suzuki()
s.mileage()
d = Duster()
d.mileage()

Points to Remember

Below are the points which we should remember about the abstract base class in Python.

An Abstract class can contain the both method normal and abstract method. An Abstract cannot be instantiated; we cannot create objects for the abstract class.

Abstraction is essential to hide the core functionality from the users. We have covered the all the basic concepts of Abstraction in Python.

Procedural Abstraction: Procedural abstraction is the process of hiding the implementation details of a procedure or function and only exposing the necessary details to the outside world. It involves breaking down a complex procedure into smaller, more manageable parts, each with its own specific task.

Example:

def calculate_area(length, width):
    return length * width

def calculate_perimeter(length, width):
    return 2 * (length + width)

length = 5
width = 3
print("Area:", calculate_area(length, width))  # Output: Area: 15

Both types of abstraction help in simplifying the complexity of a program by hiding unnecessary details and providing a clear and concise interface for interacting with objects and functions.

Here are some very simple examples of core OOP concepts in Python:

Class and Object:

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

    def display(self):
        print(f"Name: {self.name}, Age: {self.age}")

# Creating an object of the Person class
person1 = Person("Alice", 30)
person1.display()

Inheritance:

class Animal:
    def speak(self):
        print("Animal speaks")

class Dog(Animal):
    def bark(self):
        print("Dog barks")

dog = Dog()
dog.speak()
dog.bark()

Encapsulation:

class Car:
    def __init__(self):
        self.__speed = 0  # Private attribute

    def accelerate(self):
        self.__speed += 10

    def get_speed(self):
        return self.__speed

car = Car()
car.accelerate()
print("Speed:", car.get_speed())

Polymorphism:

class Animal:
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        print("Dog barks")

class Cat(Animal):
    def speak(self):
        print("Cat meows")

def make_sound(animal):
    animal.speak()

dog = Dog()
cat = Cat()

make_sound(dog)
make_sound(cat)

Abstraction:

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2

class Rectangle(Shape):
    def __init__(self, length, width):
        self.length = length
        self.width = width

    def area(self):
        return self.length * self.width

# Creating instances of Circle and Rectangle
circle = Circle(5)
rectangle = Rectangle(4, 6)

# Calculating and printing areas
print("Circle Area:", circle.area())
print("Rectangle Area:", rectangle.area())

Python Scope

A variable is only available from inside the region it is created. This is called scope.

Local Scope A variable created inside a function belongs to the local scope of that function, and can only be used inside that function.

def myfunc():
  x = 300
  print(x)

myfunc()

Function Inside Function

As explained in the example above, the variable x is not available outside the function, but it is available for any function inside the function:

def myfunc():
  x = 300
  def myinnerfunc():
    print(x)
  myinnerfunc()

myfunc()

Global Scope

A variable created in the main body of the Python code is a global variable and belongs to the global scope.

Global variables are available from within any scope, global and local.

x = 300

def myfunc():
  print(x)

myfunc()

print(x)

Python Modules

What is a Module? Consider a module to be the same as a code library.

A file containing a set of functions you want to include in your application.

Create a Module To create a module just save the code you want in a file with the file extension .py:

Save this code in a file named mymodule.py

def greeting(name):
  print("Hello, " + name)
import mymodule

mymodule.greeting("Jonathan")

Note: When using a function from a module, use the syntax: module_name.function_name.

Variables in Module

The module can contain functions, as already described, but also variables of all types (arrays, dictionaries, objects etc):

Save this code in the file mymodule.py

person1 = {
  "name": "John",
  "age": 36,
  "country": "Norway"
}

Naming a Module

You can name the module file whatever you like, but it must have the file extension .py

Re-naming a Module

You can create an alias when you import a module, by using the as keyword:

Leave a Reply

Your email address will not be published. Required fields are marked *