0% found this document useful (0 votes)
5 views

Python

Python is a high-level, versatile programming language known for its simplicity and extensive applications in fields such as web development, data science, and AI. It plays a significant role in Agentic AI, supporting frameworks for autonomous agents and natural language processing. The document also explores Python's bytecode, compilation process, and the importance of indentation and type hinting in coding practices.

Uploaded by

imran2244ansari
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

Python

Python is a high-level, versatile programming language known for its simplicity and extensive applications in fields such as web development, data science, and AI. It plays a significant role in Agentic AI, supporting frameworks for autonomous agents and natural language processing. The document also explores Python's bytecode, compilation process, and the importance of indentation and type hinting in coding practices.

Uploaded by

imran2244ansari
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

Created by Asifa Majeed

Python: The Versatile and Powerful Programming Language


Python is a high-level, interpreted, and versatile programming language known for its simplicity and readability.
Created by Guido van Rossum, it emphasizes code clarity and supports multiple programming
paradigms like procedural, object-oriented, and functional programming. Python’s extensive standard library and
community support make it ideal for web development, data analysis, AI, automation, and more. Its cross-
platform compatibility and beginner-friendly syntax have made it one of the most popular languages
worldwide.

Python in Agentic AI: Powering Autonomous Intelligence 🚀


Python plays a crucial role in Agentic AI, enabling autonomous agents to perceive, reason, and act. With
frameworks like LangChain, CrewAI, Microsoft AutoGen, Auto-GPT, and OpenAI's APIs, Python
facilitates LLM-driven workflows, decision-making, and self-improving AI. Its rich ecosystem supports seamless
integration of NLP - Natural language processing, reinforcement learning, and automation for building intelligent,
agentic systems

Practical Applications of Python

Python has numerous practical applications across various industries. Some of the top applications include:
 Data Science and Analytics: data analysis, machine learning, and visualization
 Agentic AI: building autonomous agents, chatbots, and virtual assistants
 Machine Learning: developing predictive models and recommender systems
 Natural Language Processing (NLP): text analysis, sentiment analysis, and language translation
 Computer Vision: image recognition, object detection, and facial recognition
 Robotics: building and controlling robots, drones, and autonomous vehicles
 Web Development: building web applications and frameworks
 Artificial Intelligence and Machine Learning: AI, ML, and deep learning
 Automation and Scripting: automating tasks and workflows
 Scientific Computing: scientific simulations and data analysis
 Cybersecurity: security testing and penetration testing
 Internet of Things (IoT): building IoT applications and devices
 These applications make Python a versatile and in-demand language in the industry. Its simplicity,
flexibility, and extensive libraries make it a popular choice for developers and data scientists.
 Python's simplicity and extensive libraries make it an ideal choice for building Agentic AI applications
that can interact, learn, and adapt to their environments.
 addCode
 addText

The Code Execution Continuum: A Comprehensive Exploration of


Computer Languages from Code Writing to Runtime and Output
Delve into the code execution continuum(continuation, chain), exploring how computer languages transform from source
code to bytecode, runtime, and output. Discover the complex journey of code compilation, interpretation, and execution,
Created by Asifa Majeed
revealing the inner workings of programming languages and their role in modern computing.
Created by Asifa Majeed

The Python Code Odyssey: The Adventurous Journey


The Execution Engine: How Your Python Code Transforms into Action

Introduction to Python Bytecode


Python bytecode is the intermediate representation of Python code that is generated by the Python compiler.
When you write Python code, it is first compiled into bytecode, which is then executed by the Python
interpreter.
Created by Asifa Majeed

How Python Code is Compiled


Here's a simplified overview of how Python code is compiled:

1. Lexical Analysis: The Python code is broken down into individual tokens, such as keywords, identifiers, and
literals.
2. Syntax Analysis: The tokens are analyzed to ensure that the code follows the correct syntax.
3. Semantic Analysis: The code is analyzed to ensure that it makes sense in terms of its meaning and context.
4. Bytecode Generation: The compiled code is generated in the form of bytecode.

What is Python Bytecode?


Python bytecode is a platform-independent, intermediate representation of Python code that can be executed by
the Python interpreter. It is a sequence of binary instructions that are specific to the Python interpreter, and it is
not machine-specific.
Python bytecode is stored in .pyc files, which are generated when you import a Python module. The .pyc files
contain the compiled bytecode of the Python code, which can be executed directly by the Python interpreter.

Example of Python Bytecode


class Person: # Class Person (source code/blue print of an object at runtime)
def __init__(self, name: str, age: int): # initilizer or constructor which is responsible to create Object in memory at runtime
self.name = name # Pereson attibute
self.age = age # Pereson attibute

def greet(self): # Person Class method greet()


print(f"Hello, my name is {self.name} and I am {self.age} years old.") # Print/Output to console/terminal

# Lets create a Person object in memory


person: Person = Person("Arif Rozani", 20)

person.greet() # Lets call Person Object's greet method


Hello, my name is Arif Rozani and I am 20 years old.

Lets see how bytecode look like

[]

import dis
dis.dis(Person)
Disassembly of __init__:
2 0 RESUME 0

3 2 LOAD_FAST 1 (name)
4 LOAD_FAST 0 (self)
6 STORE_ATTR 0 (name)

4 16 LOAD_FAST 2 (age)
18 LOAD_FAST 0 (self)
20 STORE_ATTR 1 (age)
30 LOAD_CONST 0 (None)
32 RETURN_VALUE

Disassembly of greet:
6 0 RESUME 0

7 2 LOAD_GLOBAL 1 (NULL + print)


Created by Asifa Majeed
14 LOAD_CONST 1 ('Hello, my name is ')
16 LOAD_FAST 0 (self)
18 LOAD_ATTR 1 (name)
28 FORMAT_VALUE 0
30 LOAD_CONST 2 (' and I am ')
32 LOAD_FAST 0 (self)
34 LOAD_ATTR 2 (age)
44 FORMAT_VALUE 0
46 LOAD_CONST 3 (' years old.')
48 BUILD_STRING 5
50 PRECALL 1
54 CALL 1
64 POP_TOP
66 LOAD_CONST 0 (None)
68 RETURN_VALUE

This bytecode shows the individual instructions that are executed when the Person class object is created
and __init__ and greet function is called.

Introduction to the dis Module


The dis module in Python is a built-in module that provides a way to disassemble and inspect the bytecode of
Python objects, such as functions, methods, and classes. It allows you to see the low-level representation of
your Python code and understand how it is executed by the Python interpreter.

Why is Python Bytecode Important?


Python bytecode is important because it allows Python code to be platform-independent and flexible. Here are a
few reasons why:

 Platform Independence: Python bytecode can be executed on any platform that has a Python interpreter, without
the need for recompilation.
 Dynamic Typing: Python bytecode is dynamically typed, which means that the type of a variable is determined
at runtime, rather than at compile time.
 Flexibility: Python bytecode can be easily modified or extended, which makes it easier to add new features or
functionality to the Python interpreter.

Overall, Python bytecode is an important part of the Python ecosystem, and it plays a key role in making
Python a flexible and platform-independent language.

How Python Uses Bytecode:


1. Compilation: When you run a Python script, the Python interpreter first compiles it into bytecode.
2. Execution: The compiled bytecode is executed by the Python Virtual Machine (PVM).
3. Caching: Python caches the compiled bytecode in the pycache directory to speed up subsequent
executions.

Does this bytecode run on any OS?


Python bytecode is platform-independent, meaning the same bytecode (.pyc files) can run on any operating
system as long as the Python interpreter version matches. However, there are some limitations:
Key Points:
1. Platform Independence:
Created by Asifa Majeed

o Python bytecode is designed to be portable across different OSes (Windows, macOS, Linux,
etc.).
o But it still requires the correct version of the Python interpreter to execute it.
2. Interpreter Dependency:
o Different versions of Python may generate different bytecode.
o A .pyc file created with Python 3.10 might not work in Python 3.8.
3. Machine Independence (Not Fully!):
o While Python bytecode is not tied to a CPU architecture (like x86 or ARM), it still depends on
Python's runtime.
o Some OS-specific modules (like os or sys) might behave differently across platforms.

Can You Run Python Bytecode Directly?


Not exactly—you still need the Python interpreter to execute it. Unlike Java bytecode (which runs on the JVM),
Python's .pyc files require the CPython VM.

How to run byte code manually


Use VSCode or Cursor.

1. Compile Python Code:


o Run command python -m compileall TestP.py
o It create the byte code in __pycache__ folder

2. Running Byte Code:


o go inside the __pycache__ folder either in terminal window or cmd
o copy the name of .pyc file
o run command python TestP.cpython-312.pyc

keyboard_arrow_down

Indentation in Python
Introduction:
In Python, indentation is used to denote a block of code within a control structure, function, or class. It is a
crucial aspect of Python syntax, and incorrect indentation can lead to syntax errors.
What is Indentation?
Indentation is the process of adding spaces or tabs to the beginning of a line of code to indicate that it is part of
a larger block of code. In Python, indentation is used to define the structure of the code and to show the
relationship between different blocks of code.
Why is Indentation Important?
Indentation is important because it helps to:
 Define the structure of the code
 Show the relationship between different blocks of code
 Make the code more readable and understandable
Created by Asifa Majeed

 Prevent syntax errors


Rules of Indentation:
1. Use consistent indentation: Use either spaces or tabs for indentation, but not both.
2. Use 4 spaces for each level of indentation: This is the standard convention in Python.
3. Indent after a colon: A colon (:) is used to indicate the start of a block of code. Indent the next line of
code after the colon.
4. Indent after a function or class definition: Indent the code inside a function or class definition.
Examples:
# Correct indentation
if True:
print("Hello, World!")
print("This is a block of code")

# Incorrect indentation
if True:
print("Hello, World!")
print("This is a block of code")

# Correct indentation
def greet(name: str):
print("Hello, " + name + "!")

# Incorrect indentation
def greet(name: str):
print("Hello, " + name + "!")

Best Practices:

 Use a consistent number of spaces for indentation throughout your code.


 Use a Python IDE or text editor with auto-indentation features to help you maintain consistent
indentation.
 Avoid using tabs for indentation, as they can be inconsistent across different systems.

Exercise: Generating Our First Python Code


Write a Python program that uses indentation to define a block of code within an if statement. Use consistent
indentation and follow the rules outlined above.

1. Click on +Code, a code cell will appear


Created by Asifa Majeed
2. In the code cell its written "Start coding or generate with AI"
3. Click on "generate"
4. Copy the prompt: Write a Python program that uses indentation to define a block of code within an if statement. Use
consistent indentation and follow the rules outlined above
5. Paste it in Generate text bar.
6. Click on Generate button or press enter

[]

Start coding or generate with AI.

keyboard_arrow_down

Python is a Dynamically-Typed Language with Optional Type Hinting


Python is a dynamically-typed language, which means that it does not enforce the data type of a variable at
compile time. Instead, the data type is determined at runtime.
However, Python 3.5 and later versions also support optional type hinting, which allows developers to add type
annotations to their code to specify the expected types of variables, function parameters, and return types.

[]

age: int = input("Enter your age: ")


print(f"Your age is {age}")

print("type(age) = ", type(age))


Enter your age: 22
Your age is 22
type(age) = <class 'str'>

Key Characteristics:
1. Dynamically-Typed: Python's data type is determined at runtime, not at compile time.
2. Optional Type Hinting: Type hinting is optional, but it can help with code readability, auto-
completion, and static type checking.
3. No Compile-Time Type Checking: Python does not perform type checking at compile time, but it can
be done using third-party tools or IDEs.

Why Use Type Hints?


Type hints are useful for several reasons:
 Improved Code Readability: Type hints make it clear what types of data your code is intended to work
with, making it easier for others (and yourself) to understand your code.
 Better Code Completion: Many IDEs and text editors can use type hints to provide more accurate code
completion suggestions, making it easier to write code.
 Static Type Checking: Type hints can be used by static type checking tools to identify potential type-
related errors before your code is even run.
 Improved Documentation: Type hints can serve as a form of documentation, making it clear what
types of data your code expects and returns.
Created by Asifa Majeed

Basic Syntax
The basic syntax for type hinting is to add a colon (:) followed by the expected type after the variable or
function parameter. For example:
x: int = 5
y: str = "hello"

Function Type Hints


You can also add type hints to function parameters and return types using the following syntax:
def greet(name: str) -> str:
return "Hello, " + name + "!"

In this example, the greet function takes a name parameter of type str and returns a value of type str.
Type Hinting for Complex Types
You can also use type hinting for more complex types, such as lists, dictionaries, and tuples. For example:
my_list: list[int] = [1, 2, 3]
my_dict: dict[str, int] = {"a": 1, "b": 2}
my_tuple: tuple[str, int] = ("hello", 5)

Best Practices
 Use type hints consistently throughout your code.
 Use the most specific type possible (e.g., int instead of Any).
 Use type hints for function parameters and return types.
 Use type hints for complex types, such as lists and dictionaries.

Object-Based Language vs. Object-Oriented Language

Object-Based Language:
 Definition:
An object-based language is a programming language that supports the concept of objects but does not
fully implement all the features of object-oriented programming (OOP). This means that while you can
create and manipulate objects, you may not have full support for features like inheritance,
polymorphism, and encapsulation.
 Characteristics:
o Supports objects and encapsulation.
o Does not necessarily support inheritance or polymorphism.
o Examples include JavaScript (prior to ES6), VBScript, and some versions of Pascal.

 Use Cases:
Object-based languages are often used for scripting and simple applications where full OOP features are
not required.
Created by Asifa Majeed

Object-Oriented Language:
 Definition:
An object-oriented language is a programming language that fully supports the principles of object-
oriented programming, including encapsulation, inheritance, and polymorphism. This allows for more
complex and reusable code structures.
 Characteristics:
o Supports encapsulation (hiding data and methods within objects).
o Supports inheritance (creating new classes based on existing ones).
o Supports polymorphism (using a single interface to represent different underlying forms).
o Examples include Python, Java, C++, and Ruby.
 Use Cases:
Object-oriented languages are widely used in software development for building large, complex
systems, as they promote code reuse and modularity.

Summary of Differences
Feature Object-Based Language Object-Oriented Language

Encapsulation Supported Supported

Inheritance Not necessarily supported Fully supported

Polymorphism Not necessarily supported Fully supported

Examples JavaScript (pre-ES6), VBScript Python, Java, C++, Ruby

keyboard_arrow_down

The Python's Object-Centric Nature


Python as an Object-Centric Language:
 Everything is an Object:
In Python, everything is treated as an object, including primitive data types like integers, strings, and
lists. This means that all data types in Python have associated methods and properties, allowing for a
consistent and unified approach to programming.

[]

# Example of integers as objects


x: int = 100
print(x.bit_length()) # Method call on an integer object
7

 First-Class Functions:
Created by Asifa Majeed

Functions in Python are first-class objects, meaning they can be passed as arguments, returned from
other functions, and assigned to variables. This allows for functional programming paradigms alongside
object-oriented programming.

[]

def greet(name) -> str:


return f"Hello, {name}!"

def call_function(func, name) -> str:


return func(name)

print(call_function(greet, "Alice")) # Passing a function as an argument


Hello, Alice!

 Support for OOP Principles:


Python fully supports object-oriented programming principles, including encapsulation, inheritance, and
polymorphism. You can define classes, create objects, and use inheritance to create new classes based
on existing ones.

[]

class Animal:

def speak(self) -> str:

return "Animal speaks"

class Dog(Animal):

def speak(self) -> str:

return "Woof!"

class Lion(Animal):

def speak(self) -> str:

return "Roar!"

dog: Dog = Dog()

print("Dog: ", dog.speak()) # Output: Woof!

lion: Lion = Lion()

print("Lion: ", lion.speak()) # Output: Roar!

class Animal:
def speak(self) -> str:
return "Animal speaks"

class Dog(Animal):
def speak(self) -> str:
return "Woof!"

class Lion(Animal):
Created by Asifa Majeed

def speak(self) -> str:


return "Roar!"

dog: Dog = Dog()


print("Dog: ", dog.speak()) # Output: Woof!

lion: Lion = Lion()


print("Lion: ", lion.speak()) # Output: Roar!
Dog: Woof!

Lion: Roar! Duck Typing

Duck typing is a fundamental concept in Python programming that enables developers to write flexible and
dynamic code. It's a key aspect of Python's philosophy, which emphasizes "we are all consenting adults here"
and encourages a more relaxed approach to programming.

What is duck typing?


Duck typing is a concept in programming that focuses on the capabilities of an object rather than its type. The idea
is that if an object has the attributes and methods you need, you can use it as if it were of the type you expected,
even if it's not. This approach is often summarized by the phrase "if it walks like a duck and talks like a duck, it's a
duck."

How does duck typing work in Python?


In Python, duck typing is the default behavior . When you call a method or access an attribute on an object, Python
doesn't check the object's type beforehand. Instead, it tries to perform the operation and will only raise an error if the
object doesn't have the required method or attribute.

Here's an example of duck typing using a speaking parrot that talks like a human:

Imagine you have a speaking parrot named Polly


Polly can talk like a human, and you want to have a conversation with her. But you also want to have
conversations with other humans.

Let's say you write a function called have_conversation


This function takes an object as a parameter, and it expects that object to have a speak method. Here's what the
code might look like:

[]

class Human:
Created by Asifa Majeed

def speak(self):

print("Human: I'm good, thanks!")

class Parrot:

def speak(self):

print("Parrot: Polly wants a cracker!")

def have_conversation(person: Human):

print("\nhave_conversation: Hello, how are you? ", type(person))

person.speak()

human = Human()

parrot = Parrot()

have_conversation(human) # I'm good, thanks!

have_conversation(parrot) # Polly wants a cracker!

class Human:
def speak(self):
print("Human: I'm good, thanks!")

class Parrot:
def speak(self):
print("Parrot: Polly wants a cracker!")

def have_conversation(person: Human):


print("\nhave_conversation: Hello, how are you? ", type(person))
person.speak()

human = Human()
parrot = Parrot()

have_conversation(human) # I'm good, thanks!


have_conversation(parrot) # Polly wants a cracker!
have_conversation: Hello, how are you? <class '__main__.Human'>
Human: I'm good, thanks!

have_conversation: Hello, how are you? <class '__main__.Parrot'>


Parrot: Polly wants a cracker!
addCode
addText
In this example, the have_conversation function doesn't care whether it's talking to a human or a parrot. As long
as the object has a speak method, it can have a conversation with it.

This is like duck typing


The have_conversation function is like a duck that says, "If it talks like a human, it's a human!" And because the
parrot can talk like a human, it can have a conversation with the function.
Created by Asifa Majeed

But here's the cool thing about duck typing


You can add new types of objects that can have conversations, and the have_conversation function will still work
with them. For example, you could create a Robot class that also has a speak method:

[]
class Robot:
def speak(self):
print("Robot: Beep boop, I am functioning within normal parameters!")

robot = Robot()
have_conversation(robot) # Beep boop, I am functioning within normal parameters!

have_conversation: Hello, how are you? <class '__main__.Robot'>


Robot: Beep boop, I am functioning within normal parameters!

The have_conversation function doesn't need to know anything about the Robot class, because it only cares about
the speak method. This makes it easy to add new types of objects to the conversation, without having to change
the underlying code.

You might also like