Wednesday, October 30, 2024

python programming

 

Python programming:

 


 

 

If you’re a professional software developer, you may have to work with several C/C++/Java libraries but find the usual write/compile/test/re-compile cycle is too slow. Perhaps you’re writing a test suite for such a library and find writing the testing code a tedious task. Or maybe you’ve written a program that could use an extension language, and you don’t want to design and implement a whole new language for your application. Python is just the language for you. You could write a Unix shell script or Windows batch files for some of these tasks, but shell scripts are best at moving around files and changing text data, not well-suited for GUI applications or games. You could write a C/C++/Java program, but it can take a lot of development time to get even a first-draft program. Python is simpler to use, available on Windows, Mac OS X, and Unix operating systems, and will help you get the job done more quickly. Python is simple to use, but it is a real programming language, offering much more structure and support for large programs than shell scripts or batch files can offer. On the other hand, Python also offers much more error checking than C, and, being a very-high-level language, it has high-level data types built in, such as flexible arrays and dictionaries. Because of its more general data types Python is applicable to a much larger problem domain than Awk or even Perl, yet many things are at least as easy in Python as in those languages. Python allows you to split your program into modules that can be reused in other Python programs. It comes with a large collection of standard modules that you can use as the basis of your programs — or as examples to start learning to program in Python. Some of these modules provide things like file I/O, system calls, sockets, and even interfaces to graphical user interface toolkits like Tk.Python is an interpreted language, which can save you considerable time during program development because no compilation and linking is necessary. The interpreter can be used interactively, which makes it easy to experiment with features of the language, to write throw-away programs, or to test functions during bottom-up program development. It is also a handy desk calculator. Python enables programs to be written compactly and readably. Programs written in Python are typically much shorter than equivalent C, C++, or Java programs, for several reasons:• the high-level data types allow you to express complex operations in a single statement;• statement grouping is done by indentation instead of beginning and ending brackets;• no variable or argument declarations are necessary. Python is extensible: if you know how to program in C it is easy to add a new built-in function or module to the interpreter, either to perform critical operations at maximum speed, or to link Python programs to libraries that may only be available in binary form (such as a vendor-specific graphics library).  Once you are really hooked, you can link the Python interpreter into an application written in C and use it as an extension or command language for that application. By the way, the language is named after the BBC show “Monty Python’s Flying Circus” and has nothing to do with reptiles. Making references to Monty Python skits in documentation is not only allowed, it is encouraged! Now that you are all excited about Python, you’ll want to examine it in some more detail. Since the best way to learn a language is to use it, the tutorial invites you to play with the Python interpreter as you read. In the next chapter, the mechanics of using the interpreter are explained. This is rather mundane information, but essential for trying out the examples shown later. The rest of the tutorial introduces various features of the Python language and system through examples, beginning with simple expressions, statements and data types, through functions and modules, and finally touching upon advanced concepts like exceptions and user-defined classes.

Python is a programming language that lets you work more quickly and integrate

your systems more effectively.

Python is a high-level, general-purpose programming language. Its design philosophy emphasizes code readability with the use of significant indentation. Python is dynamically typed and garbage-collected

Python Vocab:

• Program – A larger file of code that may contain one or more functions.

• Variable - names that you can assign values to, allowing you to reuse them later on.

 

E.g.: x = 1 or msg = “Hi, I’m a message!”

• Comments – These are notes ignored by the computer. In

Python, comments start with a hash mark (#) and end at the end of the line.

E.g.: >>> x + y #both variables store user input

• Operators – Mathematical symbols, like +, -, *, and /, but also ** (for exponents).

Python is a powerful, versatile programming language used for a wide range of software applications. Here's an overview of the types of software that Python is commonly used to develop:

 

  1. Web Development

   - Frameworks: Python has popular frameworks like Django, Flask, and FastAPI, which simplify web application development.

   - Applications: Python is used to build full-featured web applications, from small blogs to complex enterprise-level applications.

   - Libraries: Python’s libraries (e.g., Requests, BeautifulSoup) are also widely used for web scraping and interacting with web services.

 

 2. Data Science and Machine Learning

   - Libraries: Python is the leading language for data science, with libraries like Pandas, NumPy, and SciPy for data manipulation and analysis.

   - Machine Learning: Libraries like TensorFlow, PyTorch, and Scikit-Learn enable developers to create powerful machine learning and deep learning models.

   - Data Visualization: Libraries such as Matplotlib, Seaborn, and Plotly provide capabilities for data visualization and storytelling.

 

 3. Artificial Intelligence (AI) and Deep Learning

   - Python is widely used in AI research and development, with tools for deep learning (TensorFlow, Keras) and natural language processing (NLTK, SpaCy).

   - Applications include image recognition, voice assistants, natural language processing, and recommendation engines.

 

 4. Automation and Scripting

   - Scripts: Python is commonly used for scripting and automating repetitive tasks, from system maintenance to file manipulation.

   - Automation Libraries: Libraries like `Selenium` and `BeautifulSoup` allow for web automation and data extraction, while `PyAutoGUI` enables desktop automation.

 

 5. Software Development and Testing

   - Development Tools: Python can be used to build and manage development tools, such as continuous integration scripts, deployment automation, and version control tools.

   - Testing: Python has robust testing frameworks like `unittest`, `pytest`, and `doctest` that make it easy to automate and execute tests.

 

 6. Desktop GUI Applications

   - Libraries: Python libraries like Tkinter, PyQt, and Kivy allow developers to create desktop applications with graphical interfaces.

   - Applications: Examples include small tools, text editors, calculators, or even more complex applications like media players.

 

 7. Game Development

   - Libraries: Pygame is a popular library for creating 2D games in Python.

   - Prototyping: Python is often used for rapid prototyping of game mechanics before implementing them in more performance-oriented languages.

 

 8. Networking and Security

   - Network Programming: Python’s `socket` library makes it easy to handle network connections, while libraries like `Twisted` and `asyncio` offer more advanced networking capabilities.

   - Security: Python is widely used for cybersecurity and penetration testing, with tools like `Scapy` for packet analysis and `Paramiko` for secure SSH connections.

 

 9. Embedded Systems and IoT

   - Microcontrollers: Python is used in embedded systems and IoT applications through MicroPython and CircuitPython, allowing programming on microcontrollers like the Raspberry Pi and Arduino.

   - IoT Applications: Python makes it easier to connect IoT devices, gather data, and send it to cloud services or databases for further analysis.

 

 10. Scientific and Numeric Computing

   - Scientific Libraries: Libraries like SciPy and NumPy make Python a popular choice in scientific research.

   - Simulation and Modeling: Python is used for simulations in fields like biology, chemistry, and physics and for processing large sets of numerical data.

 

 11. Cloud and Big Data Applications

   - Big Data Tools: Python integrates well with big data tools and frameworks like Apache Spark and Hadoop, making it useful for processing and analyzing large datasets.

   - Cloud Services: Python is commonly used in cloud computing for scripting, data processing, and API interactions with platforms like AWS, Google Cloud, and Azure.

 

 12. Blockchain Development

   - Python can be used for blockchain development, especially for building and deploying smart contracts. Python’s frameworks, like Web3.py, facilitate blockchain interactions, making it easier to develop decentralized applications.

 

 Why Python is So Popular:

   - Readability: Python’s syntax is clean and easy to learn, making it accessible to beginners and efficient for experienced developers.

   - Large Ecosystem: Python has a large ecosystem of libraries and frameworks, reducing development time for various types of applications.

   - Community Support: Python has a strong, active community, which means there’s extensive documentation, tutorials, and open-source resources.

   - Cross-Platform Compatibility: Python runs on Windows, macOS, and Linux, allowing developers to create cross-platform applications.

 In summary, Python’s versatility makes it ideal for various fields, including web development, data science, AI, and automation, and it has applications in virtually any area of software development.

===

In Python, the `__init__()` method is a special function called the *initializer* or *constructor*. It’s automatically invoked when you create an instance (or object) of a class. Its main purpose is to initialize the attributes of the new object, essentially "setting up" the object with any necessary initial values.

 

### Key Points about `__init__()`

 

1. **Defining the Method**: The `__init__()` method is defined within a class, and its first parameter is always `self`, which represents the instance of the class being created.

  

2. **Automatic Invocation**: When you create a new object (e.g., `my_object = MyClass()`), Python automatically calls the `__init__()` method if it’s defined in the class.

  

3. **Setting Initial Values**: You can pass parameters to `__init__()` to set initial values for the object's attributes when the object is created.

 

### Syntax

 

Here’s a simple example to illustrate how `__init__()` is used:

 

```python

class Person:

    def __init__(self, name, age):

        self.name = name   # Initializing the 'name' attribute

        self.age = age     # Initializing the 'age' attribute

 

# Creating an instance of Person

person1 = Person("Alice", 30)

 

print(person1.name)  # Output: Alice

print(person1.age)   # Output: 30

```

 

### Breaking Down the Example

 

- **`__init__()` Method**: Here, `__init__()` takes `name` and `age` as parameters, and these values are assigned to `self.name` and `self.age`, which are instance attributes.

- **Creating the Object**: When `person1 = Person("Alice", 30)` is executed, Python calls `__init__()` with `"Alice"` and `30`, initializing `person1` with these values.

 

### Why `__init__()` is Important

 

The `__init__()` method allows for flexibility and customization in object creation, making it possible to:

  - Assign specific initial values to each object,

  - Enforce mandatory values during object creation, and

  - Set up the object's environment as soon as it’s created.

 

### Optional `__init__()` Method

 

You’re not required to include an `__init__()` method in every class. If it’s omitted, Python uses a default constructor that doesn’t initialize any attributes.

 

### Example with Default Values

 

You can also assign default values in `__init__()`:

 

```python

class Car:

    def __init__(self, make="Toyota", year=2022):

        self.make = make

        self.year = year

 

car1 = Car()                # Uses default values

car2 = Car("Honda", 2020)    # Custom values

 

print(car1.make, car1.year)  # Output: Toyota 2022

print(car2.make, car2.year)  # Output: Honda 2020

```

### Summary

The `__init__()` method is a key feature of classes in Python, allowing developers to initialize objects in a flexible and controlled way. It’s an essential part of object-oriented programming in Python.  ===

===

 

 

====

In Python, the distinction between mutable and immutable data types is based on whether the data stored in an object can be modified after the object is created.

 

### Mutable Data Types

Mutable data types are objects whose values can be changed in place after they are created. This means you can alter, add, or delete elements within the object without creating a new one.

 

#### Common Mutable Data Types in Python

- **Lists**: Lists allow modification of individual elements or slices, as well as the addition and deletion of elements.

- **Dictionaries**: Dictionary entries can be added, modified, or removed.

- **Sets**: Set elements can be added or removed.

 

#### Example with List (Mutable)

```python

# Creating a list

my_list = [1, 2, 3]

 

# Modifying an element in the list

my_list[0] = 10

print(my_list)  # Output: [10, 2, 3]

 

# Adding a new element to the list

my_list.append(4)

print(my_list)  # Output: [10, 2, 3, 4]

```

 

### Immutable Data Types

Immutable data types are objects whose values cannot be changed once they are created. Any operation that alters the content of an immutable object will result in a new object being created.

 

#### Common Immutable Data Types in Python

- **Integers**: Any change to an integer value results in a new integer object.

- **Floats**: Similar to integers, modifying a float value creates a new float object.

- **Strings**: Modifying a string creates a new string object, as strings are immutable.

- **Tuples**: Tuples are immutable sequences, so once defined, their elements cannot be altered.

- **Frozen Sets**: Like sets, but immutable (no add/remove operations).

 

#### Example with String (Immutable)

```python

# Creating a string

my_string = "Hello"

 

# Trying to change a character

# my_string[0] = "h"  # This will raise an error as strings are immutable

 

# Instead, we create a new string with modifications

my_string = "h" + my_string[1:]

print(my_string)  # Output: "hello"

```

 

### Key Differences Between Mutable and Immutable Data Types:

 

Feature

Mutable

Immutable

Modification

Can be changed in place

Cannot be changed, new object created

Examples

Lists, Dictionaries, Sets

Strings, Tuples, Integers, Floats, Frozen Sets

Memory Efficiency

Modifications do not create a new object

New object created for modifications

Hashability

Typically not hashable (e.g., not usable as dictionary keys)

Hashable, can be used as dictionary keys if immutable

Use Cases

When in-place modification is needed

When data integrity and consistency are critical

 

### Why the Distinction Matters

- **Efficiency**: Mutable objects are more memory-efficient when frequent updates are needed because they don’t create new objects for each change.

- **Hashability**: Only immutable types can be hashed and used as dictionary keys, making immutability essential in some contexts.

- **Data Safety**: Immutability is useful when consistency is required, as it ensures that data won’t be accidentally altered in unexpected parts of the program.

In summary, mutable data types allow modification after creation, while immutable types do not, leading to different behavior, memory usage, and suitability depending on the use case.

====

In Python, comprehensions provide a concise way to generate lists, dictionaries, and tuples by performing operations on existing data structures or iterables. They are more compact and readable compared to using traditional `for` loops.

 

### 1. List Comprehension

 

List comprehension is used to create a new list by iterating over an existing iterable, often applying a transformation or filter.

 

#### Syntax:

```python

[expression for item in iterable if condition]

```

 

#### Example:

Suppose we want a list of squares of even numbers from an existing list:

```python

numbers = [1, 2, 3, 4, 5, 6]

squares_of_evens = [x**2 for x in numbers if x % 2 == 0]

print(squares_of_evens)  # Output: [4, 16, 36]

```

In this example:

- `x**2` is the expression that generates the square of each even number.

- `for x in numbers` iterates over the `numbers` list.

- `if x % 2 == 0` filters only even numbers.

 

### 2. Dictionary Comprehension

 

Dictionary comprehension is used to create a new dictionary by iterating over an iterable, transforming keys and values in a single line of code.

 

#### Syntax:

```python

{key_expression: value_expression for item in iterable if condition}

```

 

#### Example:

Let’s create a dictionary that maps each number to its square, but only for odd numbers:

```python

numbers = [1, 2, 3, 4, 5, 6]

squares_dict = {x: x**2 for x in numbers if x % 2 != 0}

print(squares_dict)  # Output: {1: 1, 3: 9, 5: 25}

```

In this example:

- `x: x**2` creates key-value pairs where the key is `x` and the value is its square.

- `for x in numbers` iterates over `numbers`.

- `if x % 2 != 0` filters only odd numbers.

 

### 3. Tuple Comprehension (Generator Expression)

 

Python does not have a dedicated "tuple comprehension" syntax; instead, a generator expression can be used to achieve a similar effect. To create a tuple, you can wrap the generator expression in `tuple()`.

 

#### Syntax:

```python

(expression for item in iterable if condition)

```

 

#### Example:

If we want a tuple of squares of even numbers, we can use a generator expression and convert it to a tuple:

```python

numbers = [1, 2, 3, 4, 5, 6]

squares_of_evens_tuple = tuple(x**2 for x in numbers if x % 2 == 0)

print(squares_of_evens_tuple)  # Output: (4, 16, 36)

```

 

In this example:

- `x**2` generates the square of each even number.

- `for x in numbers` iterates over the `numbers` list.

- `if x % 2 == 0` filters only even numbers.

 

### Summary of Comprehensions

- **List comprehension** returns a list.

- **Dictionary comprehension** returns a dictionary.

- **Tuple comprehension** can be achieved using a generator expression wrapped in `tuple()`.

Comprehensions provide a powerful way to create new collections by processing and filtering elements from existing ones in a single line of code, making them both efficient and readable.

====

Monkey patching in Python is a technique that allows you to modify or extend the behavior of existing modules or classes at runtime, without changing their original source code. This can be done by dynamically reassigning or overriding methods, functions, or attributes of existing classes or modules. Monkey patching is often used to fix bugs, add features, or extend functionality in third-party libraries when source code cannot be modified directly.

 

### Example of Monkey Patching

 

Let’s say we have a class `Person` defined in a third-party module. We want to add a new method to this class without modifying the original code.

 

```python

# Original class definition in some module

class Person:

    def __init__(self, name):

        self.name = name

    

    def greet(self):

        return f"Hello, my name is {self.name}"

 

# Monkey patching the greet method

def new_greet(self):

    return f"Hi there! I am {self.name}, nice to meet you!"

 

# Assigning the new function to the greet method of Person

Person.greet = new_greet

 

# Testing the monkey-patched method

person = Person("Alice")

print(person.greet())  # Output: Hi there! I am Alice, nice to meet you!

```

 

In this example:

- We created a `new_greet` function with different functionality.

- By reassigning `Person.greet = new_greet`, we replaced the original `greet` method in `Person` with our custom function `new_greet`.

 

### When and Why to Use Monkey Patching

- **Fixing Bugs**: Apply quick patches to third-party libraries when a bug fix or update is not available.

- **Adding Features**: Extend functionality in modules or classes you do not control.

- **Testing**: Temporarily override methods to create mock behavior for testing purposes.

 

### Potential Risks of Monkey Patching

- **Readability**: Code can become difficult to understand because the behavior of the original class or module is altered unexpectedly.

- **Maintainability**: Updates to the original code can break monkey patches, requiring frequent adjustments.

- **Side Effects**: Modifications can unintentionally affect other parts of the code that depend on the original behavior.

 

### Best Practices

- **Use Sparingly**: Monkey patch only when absolutely necessary, as it can lead to unexpected bugs and complexity.

- **Isolate in Testing**: When using monkey patching in tests, libraries like `unittest.mock` in Python’s `unittest` module allow you to apply patches temporarily and revert them after the test.

 In summary, while monkey patching is a powerful tool in Python, it should be used cautiously and with consideration of its impact on readability, maintainability, and stability.

===

In Python, the `else` clause in a `try/except` construct is useful when you want to specify code that should only run if the `try` block completes without raising an exception. Here’s a quick look at the syntax:

 

```python

try:

    # Code that might raise an exception

except SomeException:

    # Code that handles the exception

else:

    # Code that runs if no exception was raised

```

 

### Why use `else`?

 

1. **Clear Separation of Code Logic**: It helps clarify your code by separating code that handles exceptions from code that only runs if no exceptions occur. This improves readability because you can see which code will run after the `try` block only if it succeeds without any errors.

 

2. **Avoids Accidentally Catching Errors**: Placing code in the `else` block ensures that it will not be executed if an exception occurs in the `try` block. If you put this code after the `except` block instead, it might run regardless of whether an exception was raised and caught.

 

3. **Optimization**: Since the `else` block only runs when there are no exceptions, it can be slightly faster than including everything in the `try` block, as fewer operations are surrounded by exception handling.

 

### Example

 

Here’s an example to illustrate the use of `else` in a `try/except` construct:

 

```python

try:

    result = 10 / 2

except ZeroDivisionError:

    print("Cannot divide by zero!")

else:

    print("Division succeeded:", result)

```

- If division is successful, `"Division succeeded: 5.0"` will be printed.

- If there’s a `ZeroDivisionError`, it will print `"Cannot divide by zero!"`, and the `else` block will not execute.

 

Using `else` makes the intent clear: only execute the `else` block if the `try` block has no issues

====

In Python, decorators are a powerful and flexible tool for modifying the behavior of functions or classes. They allow you to "wrap" a function or a class method with additional functionality, often to add functionality, logging, authentication, or modify the behavior of the wrapped function in some way.

 

### How Decorators Work

 

Decorators are implemented as functions (or classes) that take another function as an argument and return a modified version of that function. They are often used with the `@decorator_name` syntax to make code cleaner and more readable.

 

Here's a basic syntax:

 

```python

@decorator_function

def my_function():

    # function body

```

 

The `@decorator_function` line is equivalent to:

 

```python

my_function = decorator_function(my_function)

```

 

This means `my_function` is now "wrapped" by `decorator_function`, which can modify its behavior.

 

### Example of a Simple Decorator

 

Let's look at a basic example:

 

```python

def my_decorator(func):

    def wrapper():

        print("Something before the function runs.")

        func()

        print("Something after the function runs.")

    return wrapper

 

@my_decorator

def say_hello():

    print("Hello!")

 

say_hello()

```

 

Output:

```

Something before the function runs.

Hello!

Something after the function runs.

```

 

In this example:

 

1. `my_decorator` takes `say_hello` as its argument (`func`).

2. Inside `my_decorator`, a new function `wrapper` is defined, which adds extra code before and after calling `func()`.

3. The `say_hello` function, when called, now includes the extra functionality provided by `my_decorator`.

 

### Common Use Cases for Decorators

 

1. Logging: Add logging to functions to trace their execution and outputs.

2. Authorization: Check if a user has permission to access a specific function.

3. Caching: Store results of expensive function calls to avoid redundant calculations.

4. Timing: Measure the time a function takes to execute for performance monitoring.

 

### Example: A Timing Decorator

 

Here’s a decorator that times how long a function takes to execute:

 

```python

import time

 

def timing_decorator(func):

    def wrapper(*args, kwargs):

        start_time = time.time()

        result = func(*args, kwargs)

        end_time = time.time()

        print(f"{func.__name__} took {end_time - start_time:.4f} seconds")

        return result

    return wrapper

 

@timing_decorator

def compute():

    time.sleep(1)

    print("Done computing")

 

compute()

```

 

Output:

```

Done computing

compute took 1.0001 seconds

```

 

Here, `timing_decorator` calculates and prints the time taken for `compute()` to run, providing useful profiling information.

====

### Key Points about Decorators

 

- Decorators are functions that modify other functions.

- They often use a wrapper function to add extra behavior.

- They can accept arguments (`*args` and `kwargs`) to be flexible with any wrapped function's signature.

- They help make code more modular, readable, and reusable by abstracting repetitive behavior.

===

In Python, **context managers** are constructs that manage the setup and teardown of resources in a concise and predictable way. They are used when a resource needs to be initialized and then cleaned up after use. Common examples include opening and closing files, managing database connections, and locking/unlocking resources.

 

Context managers are often implemented using the `with` statement, which ensures that resources are properly released, even if an error occurs.

 

### How Context Managers Work

 

A context manager typically has two phases:

1. **Enter**: This is where setup occurs, such as opening a file or acquiring a lock.

2. **Exit**: This is where teardown happens, like closing a file or releasing a lock.

 

For example, when you use `with open(...) as file`, Python automatically handles opening and closing the file, even if an exception is raised within the `with` block.

 

```python

with open("example.txt", "w") as file:

    file.write("Hello, world!")

# File is automatically closed here

```

 

### Implementing Context Managers

 

There are two primary ways to create context managers in Python:

 

1. **Using Classes with `__enter__` and `__exit__` Methods**

2. **Using Generators with the `contextlib.contextmanager` Decorator**

 

#### 1. Using `__enter__` and `__exit__` Methods

 

To create a context manager with a class, define the `__enter__` and `__exit__` methods. When the `with` block starts, Python calls the `__enter__` method, and at the end, it calls the `__exit__` method.

 

Here's a simple example:

 

```python

class MyContextManager:

    def __enter__(self):

        print("Entering the context...")

        return self  # Optional, can return a resource if needed

 

    def __exit__(self, exc_type, exc_value, traceback):

        print("Exiting the context...")

        # Handle exceptions if any (optional)

        if exc_type:

            print(f"Exception: {exc_value}")

        return False  # Propagate exceptions if any

 

# Using the context manager

with MyContextManager() as manager:

    print("Inside the context")

```

 

**Output:**

```

Entering the context...

Inside the context

Exiting the context...

```

 

In this example:

- The `__enter__` method is called at the start, where setup code can be added.

- The `__exit__` method is called at the end to clean up.

- If an exception occurs, the exception details (`exc_type`, `exc_value`, `traceback`) are passed to `__exit__`, allowing you to handle errors within the context manager.

 

#### 2. Using `contextlib.contextmanager` and Generators

 

Python’s `contextlib` module allows you to create context managers with generator functions. This is often more concise, especially for simple cases.

 

To use this approach, decorate a generator function with `@contextlib.contextmanager`. The code before `yield` represents the `__enter__` phase, and the code after `yield` represents the `__exit__` phase.

 

```python

from contextlib import contextmanager

 

@contextmanager

def my_context_manager():

    print("Entering the context...")

    yield  # Control is passed to the with-block here

    print("Exiting the context...")

 

# Using the context manager

with my_context_manager():

    print("Inside the context")

```

 

**Output:**

```

Entering the context...

Inside the context

Exiting the context...

```

 

In this example:

- The code before `yield` runs when entering the `with` block.

- The code after `yield` runs when exiting the block, handling cleanup.

- If an exception is raised in the `with` block, it propagates, and you can handle it by wrapping `yield` in a `try`-`except` if needed.

 

### Advantages of Context Managers

 

1. **Automatic Resource Management**: They handle resource cleanup automatically, which makes code safer and easier to maintain.

2. **Improved Readability**: Using `with` statements clarifies the scope and purpose of resources.

3. **Error Handling**: Context managers make it easier to handle exceptions and perform cleanup tasks even if errors occur.

Context managers make resource management easy and safe, ensuring that resources are always released correctly after their use.

===

NumPy, a fundamental package for scientific computing in Python, offers several advantages over regular Python lists, particularly when it comes to handling large datasets, performing mathematical operations, and improving computational efficiency. Here’s a breakdown of the main advantages:

 

### 1. Performance and Speed

   - Efficient Memory Usage: NumPy arrays use contiguous blocks of memory, enabling faster access and processing than Python lists, which are essentially arrays of pointers to objects.

   - Vectorized Operations: NumPy performs operations at the C level, allowing for vectorized operations (applying operations over entire arrays at once) without looping. This approach is much faster than performing operations element-by-element with lists.

   - Optimized for Computation: Operations with NumPy arrays leverage underlying C and Fortran libraries, providing significant speed gains for mathematical and scientific computations compared to regular lists.

 

   ```python

   import numpy as np

 

   # Vectorized operation with NumPy

   arr = np.array([1, 2, 3, 4])

   result = arr * 2  # Multiplies every element by 2 in one operation

   ```

 

### 2. Memory Efficiency

   - Fixed Data Types: Each NumPy array has a fixed data type (e.g., `int32`, `float64`), which requires less memory than a Python list, where each element is a complete Python object with its own metadata.

   - Less Overhead: Since NumPy arrays store data in a single block of memory, there is less memory overhead compared to lists, which store references to objects in memory. This makes NumPy arrays more memory-efficient, especially with large datasets.

 

   ```python

   import numpy as np

 

   arr = np.array([1, 2, 3, 4], dtype=np.int32)  # Uses less memory with specific data types

   ```

 

### 3. Built-in Functions for Mathematical and Statistical Operations

   - NumPy provides a wide array of mathematical functions, such as `sum`, `mean`, `median`, `std`, and many others. These operations are optimized for speed and are often applied to entire arrays at once, which would require looping and/or external libraries if done with Python lists.

 

   ```python

   import numpy as np

 

   arr = np.array([1, 2, 3, 4])

   mean_value = np.mean(arr)  # Efficient mean calculation

   ```

 

### 4. N-Dimensional Arrays and Broadcasting

   - Multi-dimensional Support: NumPy supports multi-dimensional arrays (e.g., 2D matrices, 3D tensors), which are essential for scientific computing, image processing, and machine learning tasks. While lists can be nested to mimic this, they’re slower and more cumbersome to manipulate.

   - Broadcasting: NumPy allows operations between arrays of different shapes via broadcasting, where smaller arrays are "stretched" to fit the shape of larger arrays during computation. This feature is incredibly powerful and concise for performing complex mathematical operations across different dimensions.

 

   ```python

   import numpy as np

 

   arr1 = np.array([[1, 2, 3], [4, 5, 6]])  # 2D array

   arr2 = np.array([1, 2, 3])               # 1D array

   result = arr1 + arr2                      # Broadcasting adds arr2 to each row in arr1

   ```

 

### 5. Advanced Indexing and Slicing

   - Slice and Index with Ease: NumPy arrays support sophisticated slicing and indexing options. You can select subarrays, use boolean indexing, and perform advanced selections with conditions, which would be cumbersome and slower with lists.

   - Fancy Indexing: NumPy allows arrays to be indexed with other arrays, enabling efficient selection and modification of elements. This indexing capability is especially helpful for data manipulation and analysis.

 

   ```python

   import numpy as np

 

   arr = np.array([10, 20, 30, 40, 50])

   filtered_arr = arr[arr > 25]  # Returns [30, 40, 50]

   ```

 

### 6. Interoperability with Other Libraries

   - Integration with Scientific Libraries: NumPy arrays are the foundation for other popular scientific libraries in Python, such as Pandas (for data analysis), SciPy (for scientific computing), and scikit-learn (for machine learning). Many of these libraries expect or return data in NumPy array format, making it easy to integrate NumPy in a scientific or data science workflow.

   - Interfacing with Other Languages: NumPy arrays can be easily used with languages like C, C++, and Fortran, making it straightforward to write optimized code for high-performance applications.

 

### 7. Support for Linear Algebra and Random Number Generation

   - Linear Algebra Functions: NumPy has a dedicated submodule, `numpy.linalg`, with functions for linear algebra operations, like matrix multiplication, determinants, eigenvalues, and more.

   - Random Number Generation: The `numpy.random` module provides functions for generating random numbers, arrays, and sampling from various probability distributions, which is highly useful in simulations and machine learning.

 

   ```python

   import numpy as np

 

   matrix = np.array([[1, 2], [3, 4]])

   eigenvalues, eigenvectors = np.linalg.eig(matrix)  # Eigenvalues and eigenvectors

   random_arr = np.random.rand(3, 3)  # 3x3 matrix of random numbers

   ``` 

### Summary of Advantages

https://blogger.googleusercontent.com/img/a/AVvXsEiKnvyUYBEg9N-jHMaP1YKfwykHvSpH_vxkb9DaS9nr3z08G10A2ximCw4GW-DOp8K5AFiCgzPYPqP3IJAPDoWgFTDRKSK1aFxH8aUDu8ZG2dov6IVcOvST2_2Y7gPwFgmBiNic0Cx0EvYpJEcwmev23YJJ3JQO6pJjXgFwz1iUQtL-S9GnI4JP1EUJs0s=w500-h215

 

 

In summary, NumPy arrays are far more suited than Python lists for numerical and scientific applications, where high performance and efficient memory management are critical. The functionality provided by NumPy arrays helps simplify code, reduce execution time, and enables a variety of advanced operations that would be difficult or slow with regular lists.

====

In Python's Pandas library, `merge`, `join`, and `concatenate` are commonly used functions for combining data from different sources. They each serve specific purposes depending on the desired type of data combination and offer unique functionalities for handling rows, columns, and indices in DataFrames. Here’s a breakdown of the differences between them:

 

### 1. `merge`: Combining DataFrames Based on Columns or Indices

 

- Purpose: `merge` is similar to SQL-style joins. It combines two DataFrames based on one or more common columns or indices.

- How it Works: You specify the `on` parameter (common column) to merge the two DataFrames, or `left_on` and `right_on` to specify different column names in each DataFrame.

- Types of Joins: It supports four types of joins:

  - Inner Join (default): Only includes rows with matching values in both DataFrames.

  - Outer Join: Includes all rows from both DataFrames, filling in missing values with `NaN`.

  - Left Join: Includes all rows from the left DataFrame and matching rows from the right.

  - Right Join: Includes all rows from the right DataFrame and matching rows from the left.

 

Example:

```python

import pandas as pd

 

df1 = pd.DataFrame({'key': ['A', 'B', 'C'], 'value1': [1, 2, 3]})

df2 = pd.DataFrame({'key': ['A', 'B', 'D'], 'value2': [4, 5, 6]})

 

# Merge on common column 'key' with an inner join

result = pd.merge(df1, df2, on='key', how='inner')

```

 

Result:

```

  key  value1  value2

0   A       1       4

1   B       2       5

```

 

### 2. `join`: Combining DataFrames Based on Index

 

- Purpose: `join` is primarily used to combine two DataFrames based on their index rather than columns. It’s useful for combining columns of two DataFrames when they share the same index or when you want to align on indices.

- How it Works: `join` is typically used with the `set_index()` method to align DataFrames. It can accept a DataFrame as the `other` parameter to specify which DataFrame to join.

- Types of Joins: Similar to `merge`, it supports `left`, `right`, `inner`, and `outer` joins.

- One-to-Many or Many-to-One Joins: `join` supports joining a single DataFrame with multiple others, which is helpful in combining datasets with the same index.

 

Example:

```python

df1 = pd.DataFrame({'value1': [1, 2, 3]}, index=['A', 'B', 'C'])

df2 = pd.DataFrame({'value2': [4, 5, 6]}, index=['A', 'B', 'D'])

 

# Join based on index with an outer join

result = df1.join(df2, how='outer')

```

 

Result:

```

   value1  value2

A     1.0     4.0

B     2.0     5.0

C     3.0     NaN

D     NaN     6.0

```

 

### 3. `concat`: Concatenating Along Rows or Columns

 

- Purpose: `concat` is used for concatenating DataFrames either along rows (vertically) or along columns (horizontally).

- How it Works: `concat` stacks DataFrames along a specified axis (0 for rows, 1 for columns). This function does not require a matching index or common column.

- Concatenation Types:

  - Vertical Concatenation: When concatenating along `axis=0`, it stacks DataFrames vertically, similar to adding new rows.

  - Horizontal Concatenation: When concatenating along `axis=1`, it stacks DataFrames horizontally, similar to adding new columns.

- Handling of Indices: You can choose to ignore or reset indices, as well as handle missing data by using the `join` argument to specify how indices should align.

 

Example:

```python

df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})

df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})

 

# Concatenate along rows (axis=0)

result = pd.concat([df1, df2], axis=0)

```

 

Result:

```

   A  B

0  1  3

1  2  4

0  5  7

1  6  8

```

 

Horizontal Concatenation Example:

```python

# Concatenate along columns (axis=1)

result = pd.concat([df1, df2], axis=1)

```

 

Result:

```

   A  B  A  B

0  1  3  5  7

1  2  4  6  8

```

 

### Summary Table

https://blogger.googleusercontent.com/img/a/AVvXsEgStUFSvpoB9P_RQYKk_Q9Q8WWVhepyqNZLB8L8yNiI0ef0xU470KiyGOBYNcQ56wdXAI_YRH8-KieABG7Vvhbuk8Ryh4pi1Q22g0PM8u5BwhN8307WkadKour357UBcr6z0KR5WX-rkZfW-8MEFMp3Ngg46Jvb--bbcTCGDOPJ2iais0-7fZ7gX_9heRI=w555-h143

 



  

In general:

- Use `merge` for flexible, SQL-style merges based on specific columns or indices.

- Use `join` when aligning DataFrames on indices.

- Use `concat` for simple stacking along rows or columns without alignment requirements.

====

Handling missing values is an essential step in data preprocessing. Missing values can skew analyses, degrade model performance, and lead to incorrect conclusions. Here are common methods to identify and handle missing values in a dataset.

 

### 1. **Identifying Missing Values**

 

To identify missing values in a dataset, we typically use methods provided by libraries like **Pandas**:

 

- **`isnull()` and `notnull()`**: Returns a DataFrame of Boolean values, indicating where values are `NaN`.

- **`isna().sum()`**: Counts the number of missing values for each column.

 

**Example**:

```python

import pandas as pd

 

# Sample DataFrame

data = {'A': [1, 2, None], 'B': [4, None, 6], 'C': [7, 8, 9]}

df = pd.DataFrame(data)

 

# Check for missing values

print(df.isnull())       # Shows Boolean mask

print(df.isna().sum())   # Shows count of missing values per column

```

 

**Output**:

```

       A      B      C

0  False  False  False

1  False   True  False

2   True  False  False

 

A    1

B    1

C    0

dtype: int64

```

 

### 2. **Dealing with Missing Values**

 

Once missing values are identified, you have several strategies to handle them. The best method depends on the context, the nature of the data, and the degree of missingness.

 

#### A. **Removing Missing Values**

 

   - **Remove Rows**: Delete rows containing missing values, using `dropna()`.

   - **Remove Columns**: Drop columns that contain missing values if they are not essential for analysis.

 

   **Pros**: Simple and effective if missing values are few and randomly distributed.

   **Cons**: Can lead to data loss, especially if a significant portion of rows or columns contain missing values.

 

   **Example**:

   ```python

   df.dropna()             # Drops rows with any missing values

   df.dropna(axis=1)       # Drops columns with any missing values

   ```

 

#### B. **Imputation**

 

   - **Mean/Median/Mode Imputation**: Fill missing values with the mean, median, or mode of the column. This is often done for numeric data.

   - **Forward Fill/Backward Fill**: Fill missing values based on neighboring values. `ffill` (forward fill) uses the previous value, while `bfill` (backward fill) uses the next value. This can be useful for time series or sequential data.

   - **Custom Imputation**: Use a custom constant value or the result of a custom function.

   - **Advanced Imputation**: Use machine learning algorithms like K-Nearest Neighbors (KNN) or regression models to predict missing values based on other features.

 

   **Example**:

   ```python

   # Fill missing values with column mean

   df['A'].fillna(df['A'].mean(), inplace=True)

 

   # Forward fill

   df.fillna(method='ffill', inplace=True)

 

   # Using a custom value

   df['B'].fillna(0, inplace=True)

   ```

 

#### C. **Predictive Imputation**

 

   Predictive imputation involves building a model to predict missing values based on other columns. This can be more accurate for missing data patterns that aren’t well handled by simple imputation.

 

   **Example with K-Nearest Neighbors Imputation**:

   ```python

   from sklearn.impute import KNNImputer

   import numpy as np

 

   # Initialize KNN Imputer

   imputer = KNNImputer(n_neighbors=2)

   df_imputed = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)

   ```

 

#### D. **Flag and Fill**

 

   Sometimes it’s useful to create an indicator column for missing values. This way, missing data is encoded as a separate feature, allowing models to potentially detect patterns related to missingness.

 

   **Example**:

   ```python

   df['A_missing'] = df['A'].isna()  # New column indicating missingness in 'A'

   df['A'].fillna(df['A'].mean(), inplace=True)  # Fill missing values

   ```

 

#### E. **Leave Missing Values As-Is (for Certain Models)**

 

   Some algorithms (like decision trees) can handle missing values inherently, so you might choose to leave them as-is if the algorithm supports it. However, this is not universally applicable and depends on the model and library being used.

 

### 3. **Choosing the Right Strategy**

 

Consider the following when choosing a strategy for handling missing data:

 

- **Percentage of Missing Data**: If a feature has a high percentage of missing values, it may be better to drop it, as imputing too much data can introduce bias.

- **Nature of Missing Data**:

  - **Missing Completely at Random (MCAR)**: Data is missing randomly, with no relation to other variables. Simple imputation or deletion is usually acceptable.

  - **Missing at Random (MAR)**: Missingness is related to other observed variables, making it possible to use predictive imputation.

  - **Missing Not at Random (MNAR)**: Data is missing for specific reasons (e.g., income missing for higher earners). In this case, modeling the missingness can be challenging, and advanced techniques may be needed.

- **Type of Analysis**: Simple mean/median imputation may work for exploratory data analysis, while more sophisticated imputation might be better for modeling tasks.

- **Impact on Model Performance**: Test different imputation methods to determine which yields the best model performance.

 

### Summary Table

https://blogger.googleusercontent.com/img/a/AVvXsEjoaKUzL-lBmyzM-0nkvJRgvNoOp-eRHoBEVqYoFPxNFOI-W8_UzkN0sjiGOqtOHVlHxOiY7fXHIObHBjhnzq-xOKClGiNP4oQDs9KUEscdIFZ7NXfA48BYChaTpRr4IJd9zdPEhvXp_dIxBUunYYuTc0sOqc_sjaWyKIm3Ed-nE0ifB1JJ3ljrFZZgjwQ=w528-h209

 



 

Handling missing data thoughtfully is essential for ensuring data quality and model accuracy. Experimenting with different strategies and evaluating the impact on your analysis or model performance is often the best approach.

===

Where We Can Use Python ?

We can use Python everywhere. The most common important application areas are as follows:

1. For developing Desktop Applications

The Applications which are running on a single systems (i.e., Stand alone applications)

Eg: Simple Calculator application

2. For developing Web Applications

Eg: Gmail Application, Online E-commerce applications, Facebook application, Blog applications 

3. For Network Applications

Eg: Chatting applications, Client-Server applictaions etc.,

4. For Games development

5. For Data Analysis Applications

6. For Machine Learning applications

7. For developing Artificial Intelligence, Deep Learning, Neural Network Applications

8. For IOT

9. For Data Sciene

That's why Python is called as General Purpose Programming Language.

===

Which Software companies are using Python Internally Google and Youtube use Python coding

NASA and Nework Stock Exchange Applications developed by Python.

Top Software companies like Google, Microsoft, IBM, Yahoo, Dropbox, Netflix, Instagram using Python.

===

 

. Features of Python

1. Simple and easy to learn

Consider English Language, how many words are there in english? Crores of words are there in english language. If you want to be perfect in english, you should aware about all these words.

If you consider Java, You should aware of 53 words. That means when compared to English, learning Java is easy. If you consider Python Programming language, You should aware about 33 Words (Reserved Words). The person who can understand these 33 words, then he will become expert in Python. So, Python is a simple programming language. When we read Python program, we can feel like reading english statements.

For example, if you consider ternary operator in Java,

If we ask any person, what this line is doing? 99% of Non-programming people are going to fail unless and until if they know Java. If I write the same thing in python,

x = 30 if 10>20 else 40 ----> Python Statement

If we ask any person, what this line is doing? 99% of Non programming people are going to give correct

answer.

When compared with other languages, we can write programs with very less number of lines (i.e, Concise Code) . Hence more readability and simplicity in the python code. Because of the concise code, we can reduce development and cost of the project.

Let us take an example,

Assume that We have one file (abc.txt) with some data in it. Write a Python program to read the data from this file and print it on the console.

If you want to write the code for the above problem in C or Java we need to make use of more lines of code. But if you write program in Python, just 1 line is more enough.

In [ ]:

2. Freeware and Open Source

Freeware and Open source are not same.

Freeware:

To use Python, How much Licence fee we need to paid?

We need not pay single rupee also to make use of Python. It is freeware, any person can use freely, even for business sake also.

If you consider Java, Java is vendered by Oracle. (Commercial)

If you consider C# , C# is vendered by MicroSoft. (Commercial)

If you consider Python, who is vendor for Python? There is no vendor for Python, there is one charitable Foundation, Python Software Foundation (PSF) is responsible for maintainane of Python. PSF is Non-Profit oriented Organization. To use Python, you need not pay any money to PSF. If you want to donate voluntarily for this foundation, you can pay. The corresponding Website for PSF is python.org, from where you have to download Python software.  But for Java, from it's 11 version onwards it is the paid version. If you want to use for your personal use or business sake, compulsory licence must be required.

C# & .Net also requires license to use.

Open Source:

# Execution pending

The Source code of the Python is open to everyone, so that we can we can customize based on our requirement. Because of this multiple flovours of Python is possible.

Eg:

1. Jython is customized version of Python to work with Java Applications.

2. Iron Python is customized version of Python to work with C## & .Net Applications.

3. Anaconda Python is customized version of Python to work with Bigdata Applications.

One main advantage of Python is for every requirement specific version is availble in the market. We can use our specific version of python and fulfill our requirement.

3. High Level Programmimg Language High level programming language means Programmer friendly language. Being a programmer we are not required to concentrate low level activities like memory management and security etc..  Any programmer can easily read and understand the code. Let's see the below example,

In [3]:

4. Platform Independent

Assume that one C program is there, We have three machines are there which are working on three platforms (i.e., Windows, Linux, MAC). Now, we want to distribute One C application to the clients who are working on different platforms. Then what we need to do is, For Windows, a separate C program must be reqired. A C program for Windows system can't run on Linux machine or MAC machine. For Linux, a separate C program must be reqired. A C program for Linux system can't run on Windows machine or MAC machine. For MAC, a seperate C program must be required. A C program for MAC system can't run on Linux machine or Windows machine. So, Compulsory for every platform you have to write the platform specific application. Now we have three applications and three platforms. So, C programming language is platform dependent language.

Assume that one Python program is there, We have three machines are there which are working on three platforms (i.e., Windows, Linux, MAC). Now, we want to distribute One Python application to the clients who are working on different platforms. Then what we need to do is,

50

a = 20

b = 30

print(a+b)

=====

How platform independent nature is implemented in Python?

If you want to run Python application on Windows platform, what must be required is Python Virtual Machine (PVM) for Windows is required. If we provide Python application to the PVM for Windows, PVM is responsible to convert the python program into Windows specific and execute it. In the same way, If you want to run Python application on Linux platform, what must be required is Python Virtual Machine (PVM) for Linux is required. If We provide Python application to the PVM for Linux, PVM is responsible to convert the python program into Linux specific and execute it. In the same way, If you want to run Python application on MAC platform, what must be required is Python Virtual Machine (PVM) for MAC is required. If We provide Python application to the PVM for MAC, PVM is responsible to convert the python program into MAC specific and execute it. Platform specific conversions are taken care by PVM.

Python program is Platform independent Python Virtual Machine is Platform dependent

5. Portability

In general poratble means movable. In our childhood days, we heard about portable TV (14 inches), which can be moved from one place to another place very easily.

Another place where we commonly used the term Portablity is mobile number portability. Now Python application Portability means,

- Assume that one windows machine is there, in this machine your python application is running without any difficulty. Because of license issue or security issue you want to move to Linux machine. If you are migrating to Linux machine from Windows is it possible to migrate your python application or not? Yes, because Python application never talks about underlying platform. Without performing any changes in your Python application, you can migrate your Python application from one platform to another platform. This is called Portability.

6. Dynamically Typed

In Python we are not required to declare type for variables. Whenever we are assigning the value, based on value, type will be allocated automatically. Hence Python is considered as dynamically typed language. But Java, C etc are Statically Typed Languages because we have to provide type at the beginning only. This dynamic typing nature will provide more flexibility to the programmer.

====

7. Python is both Procedure oriented and Object orieted

Python language supports both Procedure oriented (like C, pascal etc) and object oriented (like C++,Java) features. Hence we can get benefits of both like security and reusability etc.

8. Interpretted

We are not required to compile Python code.

If you consider C program, we have to compile and execute the code.

If you consider Java program, we have to compile and execute the code.

If you consider Python program, we have execute the code. We are not required to compile. Internally Interpretter is responsible for compilation of the Python code.

If compilation fails interpreter raised syntax errors. Once compilation success then PVM (Python Virtual Machine) is responsible to execute.

9. Extensible

You can extend the functionality of Python application with the some other languages applications. what it means that -

Let us assume that some C program is there, some Java program is there, can we use these applications in our

Python program or not?

yes, we can use other language programs in Python.

What is the need of that?

1. Suppose We want to develop a Python application, assume that some xyz functionality is required to develop the Python application.

2. There is some java code is already there for this xyz functionality. It is non python code. Is it possible to use this non-python code in side our python application.

Yes, No problem at all.

The main advantages of this approach are:

1. We can use already existing legacy non-Python code

2. We can improve performance of the application

10. Embedded

Embedded means it is same as extensible in reverse. We can use Python programs in any other language programs. i.e., we can embedd Python programs anywhere.

==

11. Extensive Library

In Python for every requirement, a readymade library is available.  Lakhs of libraries are there in Python.No other programming language has this much of library support. Python has a rich inbuilt library. Being a programmer we can use this library directly and we are not responsible to implement the functionality.

Eg: Write a Python program to generate 6 digit OTP

In Python to generate random numbers already a library is availbale. By make use of that library we can write the code in easy manner.

In [11]:

If don’t want space between numbers, include sep = '' at the end. sep means seperator, that is assigned with empty.

In [10]:

Suppose, if we want 10 OTPs, then Python code looks like this:

In [8]:

5 0 8 8 3 1

836593

650052

666097

558558

743920

295868

950438

319213

198749

795225

269510

from random import randint

print(randint(0,9),randint(0,9),randint(0,9),randint(0,9),randint(0,9),randint(0,9))

from random import randint

print(randint(0,9),randint(0,9),randint(0,9),randint(0,9),randint(0,9),randint(0,9),sep =''

from random import randint

for i in range(1,11):

 print(randint(0,9),randint(0,9),randint(0,9),randint(0,9),randint(0,9),randint(0,9),sep

===

Limitations and Flavours of Python

Limitaions of Python:

Eventhough Python is effective programming language, there are some areas where Python may not work up to the mark. Now a days, Machine Learning (ML) is the trending word. To develop ML application, Python is the best choice. The reason is Python contains several libraries, using those libraries we can develop ML applicatios very easily.

For example, in Python we have the following modules to perform various operations:

There is a module called as numpy, which adds mathematical functions to Python.

To import and read data set, we have another module in Python called as pandas.

To project the data in the form of Graphs, there is an another module is available in Python called as mathplotlib.

1.      Suppose We want to develop mobile applications, Python is the worst choice. Why?

The main reason for this is, Python, as of now, not having library support to develop mobile applications.

Which programming language is the best choice for mobile applications?

Android, IOs Swift are thekings in Mobile application development domain.

2.Suppose We want to develop Enterprise applications such as Banking, Telecom applications where

multiple services are required (For ex, transaction management, Security, Messaging etc.,).

To develop these end-to-end applications Python is not best suitable, because, Python doesn't have that much Library support to develpo these applications as of now.

3.We are already discussed that, Python is interpretted programing language, here execution can be done line by line. That's why performance wise Python is not good. Usually Interpreted programming languages are performance wise not up to the mark. To improve performance, Now people are added JIT compiler to the PVM. This works in the following manner:

Instead of interpreting line by line everytime, a group of lines will be interprtted only once and everytime that interpretted code is going to used directly. JIT compiler is responsible to do that.

JIT compiler + PVM flovour is called pypy. If you want better performance then you should go for

pypy(Python for speed) version.

Note : These 3 are the various limitations of the Python.

Flavours of Python:

As we are already discussed that Python is an Open source. That means it's source code is available to everyone. Assume that the standard Pyhthon may not fulfill our requirement. So, what we need to do is, we have to access the source code and make some modifications and that customized Python version can fulfil my requirement.

For Python, multiple floavours are available, each flavour itself is a customized version tofulfill a particular requirement.

Folowwing are the various flavours of Python:

1. CPython:

It is the standard flavor of Python. It can be used to work with C lanugage Applications

2. Jython or JPython:

It is for Java Applications. It can run on JVM

3. IronPython:

It is for C#.Net platform

4. PyPy:

The main advantage of PyPy is performance will be improved because JIT compiler is available inside

PVM.

5. RubyPython

For Ruby Platforms

6. AnacondaPython

It is specially designed for handling large volume of data processing.

====

Reserved words (or) Keywords in Python

In Python some words are reserved to represent some meaning or functionality. Such type of words are called

Reserved words.

There are 33 reserved words available in Python.

True,False,None

and, or ,not,is

if,elif,else

while,for,break,continue,return,in,yield

try,except,finally,raise,assert

import,from,as,class,def,pass,global,nonlocal,lambda,del,with

1. All 33 keywords contains only alphabets symols.

2. Except the following 3 reserved words, all contain only lower case alphabet symbols.

True

False

None

===

 

Python offers a wide variety of libraries for data visualization, each with its unique strengths, capabilities, and stylistic approaches. Here’s an overview of some popular Python libraries commonly used for creating different types of visualizations:

 

### 1. **Matplotlib**

   - **Overview**: Matplotlib is the foundational library for data visualization in Python. It’s highly customizable and capable of creating static, animated, and interactive plots.

   - **Common Uses**: Line plots, scatter plots, bar charts, histograms, and complex, customized plots.

   - **Strengths**: 

     - Extensive customization options

     - Serves as the foundation for other visualization libraries, such as Seaborn

   - **Example**:

     ```python

     import matplotlib.pyplot as plt

     

     x = [1, 2, 3, 4, 5]

     y = [10, 15, 13, 17, 20]

     plt.plot(x, y)

     plt.xlabel('X-axis')

     plt.ylabel('Y-axis')

     plt.title('Simple Line Plot')

     plt.show()

     ```

 

### 2. **Seaborn**

   - **Overview**: Built on top of Matplotlib, Seaborn is a high-level interface for creating visually appealing statistical graphics. It’s known for handling data frames and supporting complex statistical analyses.

   - **Common Uses**: Heatmaps, violin plots, box plots, pair plots, categorical plots, and more.

   - **Strengths**:

     - Beautiful default styles

     - Built-in support for data frames

     - Simplifies statistical and relational plotting

   - **Example**:

     ```python

     import seaborn as sns

     import pandas as pd

     

     data = sns.load_dataset("iris")

     sns.pairplot(data, hue="species")

     ```

 

### 3. **Plotly**

   - **Overview**: Plotly is an interactive plotting library that supports a wide range of chart types and provides web-based visualizations. It can be used both online and offline.

   - **Common Uses**: Interactive plots like line, bar, and scatter plots, 3D plots, and complex dashboards.

   - **Strengths**:

     - Interactivity out-of-the-box

     - Great for creating dashboards

     - Integration with Dash for web-based applications

   - **Example**:

     ```python

     import plotly.express as px

     

     df = px.data.iris()

     fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species")

     fig.show()

     ```

 

### 4. **Bokeh**

   - **Overview**: Bokeh is an interactive visualization library that renders high-performance visuals in browsers. It’s suitable for creating simple charts and complex dashboards.

   - **Common Uses**: Interactive plots, linked and synchronized plots, and dashboards.

   - **Strengths**:

     - Powerful for creating web-based visualizations

     - Supports real-time streaming data

   - **Example**:

     ```python

     from bokeh.plotting import figure, output_file, show

     

     output_file("line.html")

     p = figure(title="Simple line example", x_axis_label="x", y_axis_label="y")

     p.line([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], line_width=2)

     show(p)

     ```

 

### 5. **Altair**

   - **Overview**: Altair is a declarative statistical visualization library based on the Vega and Vega-Lite specifications. It’s known for making it easy to build complex visualizations in a concise, readable way.

   - **Common Uses**: Statistical plots, data exploration, and interactive charts.

   - **Strengths**:

     - Concise syntax for creating complex visuals

     - Interactive by default

   - **Example**:

     ```python

     import altair as alt

     import pandas as pd

     

     df = pd.DataFrame({

         'x': range(10),

         'y': [3, 5, 7, 9, 11, 10, 9, 8, 7, 6]

     })

     chart = alt.Chart(df).mark_line().encode(

         x='x',

         y='y'

     )

     chart.show()

     ```

 

### 6. **ggplot (Plotnine)**

   - **Overview**: Plotnine is a Python implementation of the popular `ggplot2` package from R, using the Grammar of Graphics framework. It allows users to create layered, complex plots.

   - **Common Uses**: Statistical plots, data analysis, and graphics that follow the Grammar of Graphics.

   - **Strengths**:

     - Similar to ggplot2 in R, making it easy for those with R experience

     - Provides layered plots with intuitive syntax

   - **Example**:

     ```python

     from plotnine import ggplot, aes, geom_line

     import pandas as pd

     

     df = pd.DataFrame({'x': range(10), 'y': [3, 5, 7, 9, 11, 10, 9, 8, 7, 6]})

     plot = ggplot(df, aes(x='x', y='y')) + geom_line()

     print(plot)

     ```

 

### 7. **Geopandas and Folium**

   - **Overview**: `Geopandas` is used for spatial data manipulation, while `Folium` helps create interactive maps. These are essential libraries for geospatial data analysis.

   - **Common Uses**: Mapping geographic data, plotting spatial features, and interactive maps.

   - **Strengths**:

     - Works well for geographic datasets

     - Supports shape files, coordinate systems, and more for geographic applications

   - **Example**:

     ```python

     import folium

     

     # Create a map centered around a specific location

     m = folium.Map(location=[45.5236, -122.6750], zoom_start=13)

     m.save("map.html")

     ```

 

### 8. **Pandas Built-in Plotting**

   - **Overview**: Pandas has built-in visualization functions powered by Matplotlib. It’s useful for quickly plotting basic visualizations directly from a DataFrame.

   - **Common Uses**: Simple line plots, bar charts, histograms, box plots.

   - **Strengths**:

     - Quick and easy for basic plots

     - Directly integrates with DataFrames

   - **Example**:

     ```python

     import pandas as pd

     

     df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [4, 3, 2, 1]})

     df.plot(kind='line', x='A', y='B')

     ```

 

### Summary of Libraries and Use Cases

https://blogger.googleusercontent.com/img/a/AVvXsEjlQtJj3el4nxkqfXMO0_lE5AkBSC5nKrIbO4YrRQHEtzBkcz16GOMOTfY-2QkzwumS07tnbrjZdGsq_vK0P3tetbOdALL5gd3cWxC-G-SZnFOIPbsVajgeLGyqwMaEeuhKj4onbSt7OSprv6EnJqiCN9b_v0bsoR41ACCsBwtFFf9Jy80LVq3ZNpLlhQ4=w560-h273

 

 

Each library has its unique strengths, making it suitable for different types of visualizations and analysis contexts. Often, using a combination of these libraries provides the most flexibility and power in data visualization.

===

In Python, you can replace spaces in a string with a specific character using the `replace()` method or, for more complex patterns, with the `re.sub()` function from the `re` (regular expressions) module.

 

Here’s how you can do it:

 

### 1. Using the `replace()` Method

The `replace()` method replaces all occurrences of a substring with another substring. To replace spaces, specify `" "` as the first argument.

 

Example:

```python

text = "Hello World"

# Replace spaces with an underscore

text_with_underscore = text.replace(" ", "_")

print(text_with_underscore)  # Output: Hello_World

```

 

### 2. Using `re.sub()` from the `re` Module

If you want more control over the replacement (e.g., replacing multiple whitespace characters), use `re.sub()`, which allows for regular expression pattern matching.

 

Example:

```python

import re

 

text = "Hello   World"

# Replace any whitespace (including multiple spaces, tabs) with an underscore

text_with_underscore = re.sub(r"\s+", "_", text)

print(text_with_underscore)  # Output: Hello_World

```

 

### 3. Using `str.translate()` with `str.maketrans()` for Simple Substitution

You can use `str.translate()` for simple character-to-character replacements. It works faster for one-to-one character mappings.

 

Example:

```python

text = "Hello World"

# Mapping spaces to underscores

text_with_underscore = text.translate(str.maketrans(" ", "_"))

print(text_with_underscore)  # Output: Hello_World

```

 

Each of these methods achieves the same result but offers different advantages depending on the specific use case.

==

To determine if a number is a perfect square, you can use the following method. A number is a perfect square if there exists an integer \( n \) such that \( n^2 = \text{num} \). One efficient way to check this is to calculate the integer square root of the number and square it again to see if you get the original number.

 

Here's the function in Python:

 

```python

import math

 

def is_perfect_square(num):

    if num < 0:

        return False  # Negative numbers can't be perfect squares

    sqrt = int(math.sqrt(num))

    return sqrt * sqrt == num

```

 

### Explanation:

1. **Calculate the integer square root**: `int(math.sqrt(num))` gives the integer square root of `num`.

2. **Check if squaring the result gives the original number**: If `sqrt * sqrt` equals `num`, then `num` is a perfect square, so we return `True`; otherwise, `False`.

 

### Example Usage

```python

print(is_perfect_square(16))  # Output: True (4 * 4 = 16)

print(is_perfect_square(20))  # Output: False (no integer squared equals 20)

```

 

This function is efficient and works well for all positive integers.

===

 

 

=====

 

Data Types In Python

1. Number

2. String

3. Boolean

4. List

5. Tuple

6. Set

7. Dictionary

 

1. Number In Python

It is used to store numeric values

Python has three numeric types:

1. Integers

2. Floating point numbers

3. Complex numbers.

===

1. Integers

Integers or int are positive or negative

numbers with no decimal point. Integers in

Python 3 are of unlimited size.

e.g.

a= 100

b= -100

c= 1*20

print(a)

print(b)

print(c)

Output :-

100

-100

200

===

Type Conversion of Integer

int() function converts any data type to integer.

e.g.

a = "101" # string

b=int(a) # converts string data type to integer.

c=int(122.4) # converts float data type to

integer.

print(b)

print(c)Run Code

Output :-

101

122

===

2. Floating point numbers

It is a positive or negative real numbers

with a decimal point.

e.g.

a = 101.2

b = -101.4

c = 111.23

d = 2.3*3

print(a)

print(b)

print(c)

print(d)Run Code

Output :-

101.2

-101.4

111.23

6.8999999999999995

===

Type Conversion of Floating point numbers

float() function converts any data type to floating point

number.

e.g.

a='301.4' #string

b=float(a) #converts string data type to floating point number.

c=float(121) #converts integer data type to floating point number.

print(b)

print(c)Run Code

Output :-

301.4

121.0

===

3. Complex numbers

Complex numbers are combination of a

real and imaginary part.Complex numbers are in

the form of X+Yj, where X is a real part and Y is

imaginary part.

e.g.

a = complex(5) # convert 5 to a real part val and zero imaginary part

print(a)

b=complex(101,23) #convert 101 with real part and 23 as imaginary part

print(b)Run Code

Output :-

(5+0j)

(101+23j)

===

2. String In Python

A string is a sequence of characters. In python we can create string

using single (' ') or double quotes (" ").Both are same in python.

e.g.

str='computer science'

print('str-', str) # print string

print('str[0]-', str[0]) # print first char 'h'

print('str[1:3]-', str[1:3]) # print string from postion 1 to 3 'ell'

print('str[3:]-', str[3:]) # print string staring from 3rd char 'llo world'

print('str *2-', str *2 ) # print string two times

print("str +'yes'-", str +'yes') # concatenated string

Output

str- computer science

str[0]- c

str[1:3]- om

str[3:]- puter science

str *2- computer sciencecomputer science

str +'yes'- computer scienceyes

===

Iterating through string

e.g.

str='comp sc'

for i in str:

print(i)

Output

c

o

m

p

s

c

===

3. Boolean In Python

It is used to store two possible values either true or false

e.g.

str="comp sc"

boo=str.isupper() # test if string contains upper case

print(boo)

Output

False

===

4.List In Python

List are collections of items and each item has its own index value.

5. Tuple In Python

List and tuple, both are same except ,a list is mutable python objects and

tuple is immutable Python objects. Immutable Python objects mean you

cannot modify the contents of a tuple once it is assigned.

e.g. of list

list =[6,9]

list[0]=55

print(list[0])

print(list[1])

OUTPUT

55

9

 

===

6. Set In Python

It is an unordered collection of unique and

immutable (which cannot be modified)items.

e.g.

set1={11,22,33,22}

print(set1)

Output

{33, 11, 22}

===

7. Dictionary In Python

It is an unordered collection of items and each

item consist of a key and a value.

e.g.

dict = {'Subject': 'comp sc', 'class': '11'}

print(dict)

print ("Subject : ", dict['Subject'])

print ("class : ", dict.get('class'))

Output

{'Subject': 'comp sc', 'class': '11'}

Subject : comp sc

class : 11

===

Arithmatic operator continue

e.g.

x = 5

y = 4

print('x + y =',x+y)

print('x - y =',x-y)

print('x * y =',x*y)

print('x / y =',x/y)

print('x // y =',x//y)

print('x ** y =',x**y)

OUTPUT

('x + y =', 9)

('x - y =', 1)

('x * y =', 20)

('x / y =', 1)

('x // y =', 1)

('x ** y =', 625)

===

Arithmatic operator continue

# EMI Calculator program in Python

def emi_calculator(p, r, t):

r = r / (12 * 100) # one month interest

t = t * 12 # one month period

emi = (p * r * pow(1 + r, t)) / (pow(1 + r, t) - 1)

return emi

# driver code

principal = 10000;

rate = 10;

time = 2;

emi = emi_calculator(principal, rate, time);

print("Monthly EMI is= ", emi)

===

Arithmatic operator continue

How to calculate GST

GST ( Goods and Services Tax ) which is included in netprice

of product for get GST % first need to calculate GST Amount by subtract

original cost from Netprice and then apply

GST % formula = (GST_Amount*100) / original_cost

# Python3 Program to compute GST from original and net prices.

def Calculate_GST(org_cost, N_price):

# return value after calculate GST%

return (((N_price - org_cost) * 100) / org_cost);

# Driver program to test above functions

org_cost = 100

N_price = 120

print("GST = ",end='')

print(round(Calculate_GST(org_cost, N_price)),end='')

print("%")

* Write a Python program to calculate the standard deviation

===

Comparison operators continue

e.g.

x = 101

y = 121

print('x > y is',x>y)

print('x < y is',x<y)

print('x == y is',x==y)

print('x != y is',x!=y)

print('x >= y is',x>=y)

print('x <= y is',x<=y)

Output

('x > y is', False)

('x < y is', True)

('x == y is', False)

('x != y is', True)

('x >= y is', False)

('x <= y is', True)

===

Bitwise operators

Used to manipulate bit values.

Operator Meaning Example

& Bitwise AND x& y

| Bitwise OR x | y

~ Bitwise NOT ~x

^ Bitwise XOR x ^ y

>> Bitwise right shift x>> 2

<< Bitwise left shift x<< 2

===

e.g.

a = 5

b = 10

list = [1, 2, 3, 4, 5 ]

if ( a in list ):

print ("Line 1 - a is available in the given list")

else:

print ("Line 1 - a is not available in the given list")

if ( b not in list ):

print ("Line 2 - b is not available in the given list")

else:

print ("Line 2 - b is available in the given list")

output

Line 1 - a is available in the given list

Line 2 - b is not available in the given list

===

e.g.

a = 10

b = 10

print ('Line 1','a=',a,':',id(a), 'b=',b,':',id(b))

if ( a is b ):

print ("Line 2 - a and b have same identity")

else:

print ("Line 2 - a and b do not have same identity")

OUTPUT

('Line 1', 'a=', 10, ':', 20839436, 'b=', 10, ':', 20839436)

Line 2 - a and b have same identity

===

Operators Precedence :highest precedence to lowest precedence table

Operator Description

** Exponentiation (raise to the power)

~ + - Complement, unary plus and minus (method names for the last two are +@ and

-@)

* / % // Multiply, divide, modulo and floor division

+ - Addition and subtraction

>> << Right and left bitwise shift

& Bitwise 'AND'td>

^ | Bitwise exclusive `OR' and regular `OR'

<= < > >= Comparison operators

<> == != Equality operators

= %= /= //= -=

+= *= **=

Assignment operators

is is not Identity operators

in not in Membership operators

not or and Logical operators

===

It is a valid combination of operators,literals and variable.

1. Arithmatic expression :- e.g. c=a+b

2. Relational expression :- e.g. x>y

3. Logical expression :- a or b

4. String expression :- c=“comp”+”sc”

==

 

The process of converting the value of one data type (integer, string, float, etc.) to

another data type is called type conversion.

Python has two types of type conversion.

Implicit Type Conversion

Explicit Type Conversion

Implicit Type Conversion:

In Implicit type conversion, Python automatically converts one data type to another

data type. This process doesn't need any user involvement.

e.g.

num_int = 12

num_flo = 10.23

num_new = num_int + num_flo

print("datatype of num_int:",type(num_int))

print("datatype of num_flo:",type(num_flo))

print("Value of num_new:",num_new)

print("datatype of num_new:",type(num_new))

OUTPUT

('datatype of num_int:', <type 'int'>)

('datatype of num_flo:', <type 'float'>)

('Value of num_new:', 22.23)

('datatype of num_new:', <type 'float'>)

===

Explicit Type Conversion:

In Explicit Type Conversion, users convert the data type of an object to

required data type. We use the predefined functions like int(),float(),str() etc.

e.g.

num_int = 12

num_str = "45"

print("Data type of num_int:",type(num_int))

print("Data type of num_str before Type Casting:",type(num_str))

num_str = int(num_str)

print("Data type of num_str after Type Casting:",type(num_str))

num_sum = num_int + num_str

print("Sum of num_int and num_str:",num_sum)

print("Data type of the sum:",type(num_sum))

OUTPUT

('Data type of num_int:', <type 'int'>)

('Data type of num_str before Type Casting:', <type 'str'>)

('Data type of num_str after Type Casting:', <type 'int'>)

('Sum of num_int and num_str:', 57)

('Data type of the sum:', <type 'int'>)

===

It is a standard module in Python. To use mathematical functions of this

module,we have to import the module using import math.

Function Description Example

ceil(n) It returns the smallest integer greater than or equal to n. math.ceil(4.2) returns 5

factorial(n) It returns the factorial of value n math.factorial(4) returns 24

floor(n) It returns the largest integer less than or equal to n math.floor(4.2) returns 4

fmod(x, y) It returns the remainder when n is divided by y math.fmod(10.5,2) returns 0.5

exp(n) It returns e**n math.exp(1) return 2.718281828459045

log2(n) It returns the base-2 logarithm of n math.log2(4) return 2.0

log10(n) It returns the base-10 logarithm of n math.log10(4) returns 0.6020599913279624

pow(n, y) It returns n raised to the power y math.pow(2,3) returns 8.0

sqrt(n) It returns the square root of n math.sqrt(100) returns 10.0

cos(n) It returns the cosine of n math.cos(100) returns 0.8623188722876839

sin(n) It returns the sine of n math.sin(100) returns -0.5063656411097588

tan(n) It returns the tangent of n math.tan(100) returns -0.5872139151569291

pi It is pi value (3.14159...) It is (3.14159...)

===

1. if statements

Syntax:

if(condition):

statement

[statements]

e.g.

noofbooks = 2

if (noofbooks == 2):

print('You have ')

print(‘two books’)

print(‘outside of if statement’)

Output

You have two books

Note:To indicate a block of code in Python, you must indent each

line of the block by the same amount. In above e.g. both print

statements are part of if condition because of both are at same 

===

1. if statements

Using logical operator in if statement

x=1

y=2

if(x==1 and y==2):

print(‘condition matcing the criteria')

Output :-

condition matcing the criteria

-----------------------------------------------------------

a=100

if not(a == 20):

print('a is not equal to 20')

Output :-

a is not equal to 20

===

2. if-else Statements

Syntax:

if(condition):

statements

else:

statements

e.g.

a=10

if(a < 100):

print(‘less than 100')

else:

print(‘more than equal 100')

OUTPUT

less than 100

===

3. Nested if-else statement

Syntax

If (condition):

statements

elif (condition):

statements

else:

statements

E.G.

num = float(input("Enter a number: "))

if num >= 0:

if num == 0:

print("Zero")

else:

print("Positive number")

else:

print("Negative number")

OUTPUT

Enter a number: 5

Positive number

===

Iteration statements(loop) are used to execute a block

of statements as long as the condition is true.

Loops statements are used when we need to run same

code again and again.

Python Iteration (Loops) statements are of three type :-

1. While Loop

2. For Loop

3. Nested For Loops

===

While Loop continue

While Loop With Else

e.g.

x = 1

while (x < 3):

print('inside while loop value of x is ',x)

x = x + 1

else:

print('inside else value of x is ', x)

Output

inside while loop value of x is 1

inside while loop value of x is 2

inside else value of x is 5

===

While Loop continue

Infinite While Loop

e.g.

x = 5

while (x == 5):

print(‘inside loop')

Output

Inside loop

Inside loop

===

2. For Loop

It is used to iterate over items of any sequence, such

as a list or a string.

Syntax

for val in sequence:

statements

e.g.

for i in range(3,5):

print(i)

Output

3

4

===

2. For Loop continue

Example programs

for i in range(5,3,-1):

print(i)

Output

5

4

range() Function Parameters

start: Starting number of the sequence.

stop: Generate numbers up to, but not including this number.

step(Optional): Determines the increment between each numbers

in the sequence.

===

2. For Loop continue

For Loop With Else

e.g.

for i in range(1, 4):

print(i)

else: # Executed because no break in for

print("No Break")

Output

1

2

3

4

No Break

===

2. For Loop continue

Nested For Loop

e.g.

for i in range(1,3):

for j in range(1,11):

k=i*j

print (k, end=' ')

print()

Output

1 2 3 4 5 6 7 8 9 10

2 4 6 8 10 12 14 16 18 20

===

3. Jump Statements

Jump statements are used to transfer

the program's control from one location to another.

Means these are used to alter the flow of a loop like - to

skip a part of a loop or terminate a loop

There are three types of jump statements used in

python.

1.break

2.continue

3.pass

===

1.break

it is used to terminate the loop.

e.g.

for val in "string":

if val == "i":

break

print(val)

print("The end")

Output

s

t

r

The end

===

2.continue

It is used to skip all the remaining statements in

the loop and move controls back to the top of the loop.

e.g.

for val in "init":

if val == "i":

continue

print(val)

print("The end")

Output

n

t

The end

===

3. pass Statement

This statement does nothing. It can be used when a

statement is required syntactically but the program

requires no action.

Use in loop

while True:

pass # Busy-wait for keyboard interrupt (Ctrl+C)

In function

It makes a controller to pass by without executing any code.

e.g.

def myfun():

pass #if we don’t use pass here then error message will be shown

print(‘my program')

OUTPUT

My program

===

3. pass Statement continue

e.g.

for i in 'initial':

if(i == 'i'):

pass

else:

print(i)

OUTPUT

n

t

a

L

NOTE : continue forces the loop to start at the next

iteration while pass means "there is no code to execute

here" and will continue through the remainder or the loop

===

 

 I’ve used a variety of Python libraries for visualization, each with specific strengths suited to different tasks:

 

 1. Matplotlib

   - Overview: The foundational library for plotting in Python, capable of creating static, animated, and interactive plots.

   - Common Uses: Line plots, scatter plots, bar charts, histograms, and other standard plots.

   - Strengths: Highly customizable; supports a wide range of plotting options.

 

 2. Seaborn

   - Overview: Built on top of Matplotlib, Seaborn simplifies complex statistical visualization.

   - Common Uses: Heatmaps, violin plots, box plots, pair plots, and categorical plots.

   - Strengths: Attractive default styles; built-in support for data frames; simplifies data exploration and statistical plotting.

 

 3. Plotly

   - Overview: An interactive plotting library that allows you to create web-based visualizations with minimal setup.

   - Common Uses: Interactive line, bar, and scatter plots, as well as 3D plots and dashboards.

   - Strengths: Interactivity; easy integration with Dash for creating web-based dashboards.

 

 4. Bokeh

   - Overview: Aimed at creating web-based visualizations that are interactive and scalable.

   - Common Uses: Real-time dashboards, linked plots, and interactive web visualizations.

   - Strengths: Excellent for browser-based interactivity; supports real-time streaming data.

 

 5. Altair

   - Overview: A declarative statistical visualization library based on the Vega and Vega-Lite specifications.

   - Common Uses: Data exploration and statistical graphics with a clean, concise syntax.

   - Strengths: Provides a Grammar of Graphics approach; offers intuitive syntax for creating complex plots with minimal code.

 

 6. Plotnine (ggplot in Python)

   - Overview: A Python implementation of R’s ggplot2, following the Grammar of Graphics approach.

   - Common Uses: Statistical analysis and layered graphics.

   - Strengths: Familiar syntax for those with experience in R’s ggplot2; enables multi-layered plotting.

 

 7. Geopandas and Folium

   - Overview: Geopandas is for handling and plotting geographic data, while Folium is used to create interactive maps.

   - Common Uses: Visualizing geographic datasets, plotting shapes, and interactive mapping.

   - Strengths: Great for GIS data and map-based visualizations; works well with shape files and geospatial data.

 

 8. Pandas Built-in Plotting

   - Overview: Uses Matplotlib under the hood to quickly generate plots directly from data frames.

   - Common Uses: Quick line plots, bar charts, histograms, box plots for data exploration.

   - Strengths: Convenient for quick plotting during data analysis; easy to use with data frames.

 

 Summary of Libraries and Use Cases:

https://blogger.googleusercontent.com/img/a/AVvXsEjK7XS3-XWH_XNOZC9yvnRGFPJsd0cE4Oe37R8lGf-1IuxQUMgEJajVsL_dbfU5lIDxHvcd-KCeK8k5N_fg5pNgeaAsptuhRKWR_hpKCFdX7pdtqCl0bc_WAP35q-TlGvXQADSpn0d_d3Rbel5L3H467zikkq2eJG3zqKiXr50jRlUyV6bBJ_SC_xB1BAA=w521-h253

 



 Each of these libraries has unique advantages and is suited to specific tasks, so I often use them in combination to gain flexibility and maximize the effectiveness of my visualizations.

===

To replace spaces in a string with a specific character in Python, you can use the `replace()` method. If more complex replacements are needed, the `re.sub()` function from the `re` module is useful. Here are three common methods:

 

 1. Using `str.replace()`

The `replace()` method replaces all occurrences of a substring with another substring.

 

```python

text = "Hello World"

# Replace spaces with an underscore

text_with_underscore = text.replace(" ", "_")

print(text_with_underscore)  # Output: Hello_World

```

 

 2. Using `re.sub()` from the `re` Module

For more complex replacements, like replacing multiple types of whitespace (spaces, tabs, newlines), use `re.sub()` with a whitespace pattern.

 

```python

import re

 

text = "Hello   World\nHello\tPython"

# Replace any whitespace with an underscore

text_with_underscore = re.sub(r"\s+", "_", text)

print(text_with_underscore)  # Output: Hello_World_Hello_Python

```

 

 3. Using `str.translate()` with `str.maketrans()` for Simple Substitution

This approach is useful for single-character replacements and is faster in performance.

 

```python

text = "Hello World"

# Mapping spaces to underscores

text_with_underscore = text.translate(str.maketrans(" ", "_"))

print(text_with_underscore)  # Output: Hello_World

```

 

Each of these methods achieves the same result but is suited to different use cases based on complexity and performance needs.

===

To determine if a number is a perfect square, you can check if there exists an integer \( n \) such that \( n^2 = \text{num} \). A straightforward way to do this is by calculating the integer square root of `num` and then squaring it again to check if it gives back `num`.

 

Here's the Python function to accomplish this:

 

```python

import math

 

def is_perfect_square(num):

    if num < 0:

        return False  # Negative numbers can't be perfect squares

    sqrt = int(math.sqrt(num))

    return sqrt * sqrt == num

```

 

### Explanation:

1. **Calculate the integer square root**: `int(math.sqrt(num))` gives the integer square root of `num`.

2. **Check if squaring the result gives the original number**: If `sqrt * sqrt` equals `num`, then `num` is a perfect square, so we return `True`; otherwise, `False`.

 

### Example Usage

```python

print(is_perfect_square(16))  # Output: True (4 * 4 = 16)

print(is_perfect_square(20))  # Output: False (no integer squared equals 20)

```

 

This function is efficient and works well for all positive integers.

===

To find the number of trailing zeroes in the factorial of an integer \( n \), you need to count how many times \( 10 \) is a factor in \( n! \). Since \( 10 = 2 \times 5 \), and there are usually more factors of \( 2 \) than \( 5 \) in factorial numbers, the count of trailing zeroes is determined by the number of \( 5 \) factors.

 

### Approach

1. Count the multiples of \( 5 \) in \( n \), \( n//5 \).

2. Count the multiples of \( 25 \) (since each contributes an additional \( 5 \)), \( n//25 \).

3. Count the multiples of \( 125 \), \( n//125 \).

4. Continue this until \( n // 5^k = 0 \).

 

### Function Implementation

Here's the Python function for this approach:

 

```python

def trailing_zeroes(n):

    count = 0

    power_of_5 = 5

    while n >= power_of_5:

        count += n // power_of_5

        power_of_5 *= 5

    return count

```

 

### Explanation:

- We initialize `count` to store the total number of trailing zeroes.

- We loop, dividing \( n \) by increasing powers of \( 5 \) (`5`, `25`, `125`, ...) and add the results to `count`.

- The loop ends when \( n // 5^k = 0 \) (when the power of 5 exceeds \( n \)).

 

### Example Usage

```python

print(trailing_zeroes(5))    # Output: 1 (5! = 120, one trailing zero)

print(trailing_zeroes(10))   # Output: 2 (10! = 3628800, two trailing zeroes)

print(trailing_zeroes(100))  # Output: 24

```

 

This method is efficient, with a time complexity of \( O(\log_5(n)) \), and avoids calculating the potentially huge value of \( n! \).

===

Python Vocab • Keyword –

Words with meaning/purpose in Python. E.g. “and”, “print”, and “if”.

• Function – A chunk of code that performs an action. Functions have names and are reusable. Kinds: built-in ones, and “user-defined” ones.

• Expression – Statements that produce values. Examples include 3 + 5, "Hello world!“.

• Error – When your program has a problem, the command area will provide an error message.

===

Indentation

• Not an Option, but a Requirement!

• In Python, indenting specifies the “scope” of different chunks of your code.

def main(): print "Hello world!"

The print line will be executed when you invoke main()

====

Argument

A value passed to a function or method, assigned to a named local variable in the function body.

 

Ex. def addUp(a,b):

print(“this is a+b: “, a+b)

 

#a and b are the parameters, 1 and 3 are the arguments we passed in.

#The function outputs : this is 1+3: 4

===

 

Calling Functions

main()

 

will give the output

Hello world!

 

- There is no colon when calling a function!

- Use colons with “def”.

===

Similar formatting, different output

 

• print "Hello", "world", "!"

will output

Hello world !

 

• print "Hello" + "world" + "!"

will output

Helloworld!

====

Data Types

 

The data type of an object determines the values it can

hold, and the operations which can be performed on

it.

 

• Numeric Data

Numeric data comes in 2 main flavors:

– Integers (whole numbers) 2, 5, -7, etc.

– Floating Point Numbers (non-integers) 0.2, 5.125, etc.

===

• Non-numeric Data Types:

Those include strings (text), lists, dictionaries, etc..

 

Basically anything you can not add up using a

simple plus sign (+).

===

 

• x = 42

print "$" + x

causes an error.

 

• So what do we do?

x = 42

print "$" + str(x)

will give the output

$42

===

Defining Variables

Rules for naming variables:

 

• Have to start with a letter or underscore (_)

• Can contain letters, numbers, and underscores

• Can’t contain spaces, punctuation, etc.

• Can’t be Python keywords

• Are case sensitive.

===

Defining Variables

 

Things that aren’t rules, but are worth considering:

• You should give your variables sensible names

(“price”, “pixelColor, or “samplingRate” instead of

“x”)

 

• Just because you technically can start your

variable names with underscores doesn’t mean

you should. 

===

Defining Variables

 

• For multi-word variable names, two options:

– start capitalizing each word after the first “myCar”

– separate words with underscores. For instance, a

variable for “Ford Focus” could be “my_car”.

• Abbreviating is common for longer words. So, a

variable for “average price” could be “avgPrice”

or even “avg”.

===

Variables

 

• Variables can hold all kinds of values, including

strings, different types of numbers, and user

input.

 

• To assign a string value to a variable, you have to

wrap the string in quotes (like usual).

firstName = "John"

lastName = "Doe"

mathProblem = "5 + 5"

print lastName, ",", firstName, ";",

mathProblem

will give the output

Doe , John ; 5 + 5

===

Variables

 

• Remember: A variable has to have been

defined on a previous line before it can be

used on the right-hand side of an equation,

so:

• total = total + 4

print "Total:", total

causes an error, since there was no mention of

the value of “total” before the line trying to

redefine it.

===

Numeric Operators

 

• Python built-in numeric operators:

• + addition

• - subtraction

• * multiplication

• / division

• ** exponentiation

• % remainder (modulo)

===

Python Arithmetic

 

• Try writing the following code in your program area and see what it outputs

Def main():

          a = 12

          b = 2

          c = 16

          d = 3

          e = 2.5

print "the value of a is", a

print (a / b) * 5

print a + b * d

print (a + b) * d

print b ** d

print c - e

a = a + b

print "the value of a is", a

===

Python Arithmetic

 

• Is this what you got?

the value of a is 12

30

18

42

8

13.5

the value of a is 14

===

Exercise Time!

 

• Write a program that takes in a birthday (dd, mm, yy) and returns:

– The age

– Number of days until next birthday

===

Ex. For Loop

 

• phrase = "Hello world!"

for letter in phrase:

print "the next letter is:", letter

will give the output

the next letter is: H

the next letter is: e

the next letter is: l

the next letter is: l

the next letter is: o

the next letter is:

the next letter is: w

the next letter is: o

the next letter is: r

the next letter is: l

the next letter is: d

the next letter is: !

===

split()

 

phrase = "Hello beautiful world!"

for word in phrase.split():

print "the next word is:", word

will give the output

the next word is: Hello

the next word is: beautiful

the next word is: world!

===

Accumulator Variables

 

Steps:

1. Define it for the first time before the for loop starts.

2. Redefine it as itself plus some operation in the body of

the for loop.

total = 0

for num in [1,2,4,10,20]:

total = total + num

print "Total:", total

will give the output

Total: 37

===

Conditional Statements

 

Equals: ==

Does not equal: !=

Try this:

x = 1

If( x != 2)

print “Artemis rocks”

===

 if Statements

Perhaps the most well-known statement type is the if statement. For example:

>>> x = int(input("Please enter an integer: "))

Please enter an integer: 42

 

>>> if x < 0:

... x = 0

... print('Negative changed to zero')

... elif x == 0:

... print('Zero')

... elif x == 1:

... print('Single')

... else:

... print('More')

...

More

There can be zero or more elif parts, and the else part is optional. The keyword ‘elif’ is short for ‘else if’, and is useful to avoid excessive indentation. An if … elif … elif … sequence is a substitute for the switch or case statements found in other languages.

===

for Statements

The for statement in Python differs a bit from what you may be used to in C or Pascal. Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or giving the user the ability to define both the iteration step and halting condition (as C), Python’s for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence. For example (no pun intended):

>>> # Measure some strings:

... words = ['cat', 'window', 'defenestrate']

>>> for w in words:

... print(w, len(w))

...

cat 3

window 6

defenestrate 12

===

If you need to modify the sequence you are iterating over while inside the loop (for example to duplicate

selected items), it is recommended that you first make a copy. Iterating over a sequence does not implicitly

make a copy. The slice notation makes this especially convenient:

>>> for w in words[:]: # Loop over a slice copy of the entire list.

... if len(w) > 6:

... words.insert(0, w)

...

>>> words

['defenestrate', 'cat', 'window', 'defenestrate']

With for w in words:, the example would attempt to create an infinite list, inserting defenestrate over and over again.

===

The range() Function

If you do need to iterate over a sequence of numbers, the built-in function range() comes in handy. It generates arithmetic progressions:

>>> for i in range(5):

... print(i)

...

0

1

2range(5, 10)

5, 6, 7, 8, 9

range(0, 10, 3)

0, 3, 6, 9

range(-10, -100, -30)

-10, -40, -70

To iterate over the indices of a sequence, you can combine range() and len() as follows:

>>> a = ['Mary', 'had', 'a', 'little', 'lamb']

>>> for i in range(len(a)):

... print(i, a[i])

...

0 Mary

1 had

2 a

3 little

4 lamb

===

In many ways the object returned by range() behaves as if it is a list, but in fact it isn’t. It is an object which returns the successive items of the desired sequence when you iterate over it, but it doesn’t really make the list, thus saving space.

We say such an object is iterable, that is, suitable as a target for functions and constructs that expect something from which they can obtain successive items until the supply is exhausted. We have seen that the for statement is such an iterator. The function list() is another; it creates lists from iterables:

>>> list(range(5))

[0, 1, 2, 3, 4]

Later we will see more functions that return iterables and take iterables as argument.

===

 break and continue Statements, and else Clauses on Loops :

The break statement, like in C, breaks out of the innermost enclosing for or while loop.

Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement. This is exemplified by the following loop, which searches for prime numbers:

>>> for n in range(2, 10):

... for x in range(2, n):

... if n % x == 0:

... print(n, 'equals', x, '*', n//x)

... break

... else:

... # loop fell through without finding a factor

... print(n, 'is a prime number')

...

2 is a prime number

3 is a prime number

4 equals 2 * 2

5 is a prime number

6 equals 2 * 3

7 is a prime number

8 equals 2 * 4

9 equals 3 * 3

(Yes, this is the correct code. Look closely: the else clause belongs to the for loop, not the if statement.)

When used with a loop, the else clause has more in common with the else clause of a try statement than it does that of if statements: a try statement’s else clause runs when no exception occurs, and a loop’s else clause runs when no break occurs. For more on the try statement and exceptions, see Handling Exceptions.

==

The pass statement does nothing. It can be used when a statement is required syntactically but the program requires no action. For example:

>>> while True:

... pass # Busy-wait for keyboard interrupt (Ctrl+C)

...

This is commonly used for creating minimal classes:

>>> class MyEmptyClass:

... pass

...

Another place pass can be used is as a place-holder for a function or conditional body when you are working on new code, allowing you to keep thinking at a more abstract level. The pass is silently ignored:

>>> def initlog(*args):

... pass # Remember to implement this!

3

4

The given end point is never part of the generated sequence; range(10) generates 10 values, the legal indices for items of a sequence of length 10. It is possible to let the range start at another number, or to specify a different increment (even negative; sometimes this is called the ‘step’):

===

Defining Functions

We can create a function that writes the Fibonacci series to an arbitrary boundary:

>>> def fib(n): # write Fibonacci series up to n

... """Print a Fibonacci series up to n."""

... a, b = 0, 1

... while a < n:

... print(a, end=' ')

... a, b = b, a+b

... print()

...

>>> # Now call the function we just defined:

... fib(2000)

0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

The keyword def introduces a function definition. It must be followed by the function name and the parenthesized list of formal parameters. The statements that form the body of the function start at the next line, and must be indented.

The first statement of the function body can optionally be a string literal; this string literal is the function’s documentation string, or docstring. (More about docstrings can be found in the section Documentation.

==

 Default Argument Values

The most useful form is to specify a default value for one or more arguments. This creates a function that

can be called with fewer arguments than it is defined to allow. For example:

def ask_ok(prompt, retries=4, reminder='Please try again!'):

while True:

ok = input(prompt)

if ok in ('y', 'ye', 'yes'):

return True

if ok in ('n', 'no', 'nop', 'nope'):

return False

retries = retries - 1

if retries < 0:

raise ValueError('invalid user response')

print(reminder)

This function can be called in several ways:

• giving only the mandatory argument: ask_ok('Do you really want to quit?')

• giving one of the optional arguments: ask_ok('OK to overwrite the file?', 2)

• or even giving all arguments: ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or

no!')

===

This example also introduces the in keyword. This tests whether or not a sequence contains a certain value. The default values are evaluated at the point of function definition in the defining scope, so that

 

i = 5

def f(arg=i):

print(arg)

i = 6

f()

will print 5.

Important warning: The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls:

 

def f(a, L=[]):

L.append(a)

return L

print(f(1))

print(f(2))

print(f(3))

This will print

[1]

[1, 2]

[1, 2, 3]

If you don’t want the default to be shared between subsequent calls, you can write the function like this

instead:

def f(a, L=None):

if L is None:

L = []

L.append(a)

return L

4.7.2 Keyword Arguments

Functions can also be called using keyword arguments of the form kwarg=value. For instance, the following function:

 

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):

print("-- This parrot wouldn't", action, end=' ')

print("if you put", voltage, "volts through it.")

print("-- Lovely plumage, the", type)

print("-- It's", state, "!")

accepts one required argument (voltage) and three optional arguments (state, action, and type). This

function can be called in any of the following ways:

parrot(1000) # 1 positional argument

parrot(voltage=1000) # 1 keyword argument

parrot(voltage=1000000, action='VOOOOOM') # 2 keyword arguments

parrot(action='VOOOOOM', voltage=1000000) # 2 keyword arguments

parrot('a million', 'bereft of life', 'jump') # 3 positional arguments

parrot('a thousand', state='pushing up the daisies') # 1 positional, 1 keyword

but all the following calls would be invalid:

parrot() # required argument missing

parrot(voltage=5.0, 'dead') # non-keyword argument after a keyword argument

parrot(110, voltage=220) # duplicate value for the same argument

parrot(actor='John Cleese') # unknown keyword argument

In a function call, keyword arguments must follow positional arguments. All the keyword arguments

passed must match one of the arguments accepted by the function (e.g. actor is not a valid argument

for the parrot function), and their order is not important. This also includes non-optional arguments (e.g.

parrot(voltage=1000) is valid too). No argument may receive a value more than once. 

===

>>> def function(a):

... pass

...

>>> function(0, a=0)

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

TypeError: function() got multiple values for keyword argument 'a'

When a final formal parameter of the form **name is present, it receives a dictionary (see typesmapping)

containing all keyword arguments except for those corresponding to a formal parameter. This may be

combined with a formal parameter of the form *name (described in the next subsection) which receives

a tuple containing the positional arguments beyond the formal parameter list. (*name must occur before

**name.) For example, if we define a function like this:

def cheeseshop(kind, *arguments, **keywords):

print("-- Do you have any", kind, "?")

print("-- I'm sorry, we're all out of", kind)

for arg in arguments:

print(arg)

print("-" * 40)

for kw in keywords:

print(kw, ":", keywords[kw])

It could be called like this:

cheeseshop("Limburger", "It's very runny, sir.",

"It's really very, VERY runny, sir.",

shopkeeper="Michael Palin",

client="John Cleese",

sketch="Cheese Shop Sketch")

 

===

Unpacking Argument Lists

The reverse situation occurs when the arguments are already in a list or tuple but need to be unpacked for a function call requiring separate positional arguments. For instance, the built-in range() function expects separate start and stop arguments. If they are not available separately, write the function call with the *-operator to unpack the arguments out of a list or tuple:

 

>>> list(range(3, 6)) # normal call with separate arguments

[3, 4, 5]

>>> args = [3, 6]

>>> list(range(*args)) # call with arguments unpacked from a list

[3, 4, 5]

In the same fashion, dictionaries can deliver keyword arguments with the **-operator:

>>> def parrot(voltage, state='a stiff', action='voom'):

... print("-- This parrot wouldn't", action, end=' ')

... print("if you put", voltage, "volts through it.", end=' ')

... print("E's", state, "!")

...

>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}

>>> parrot(**d)

-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

 

Lambda Expressions

Small anonymous functions can be created with the lambda keyword. This function returns the sum of its two arguments: lambda a, b: a+b. Lambda functions can be used wherever function objects are required. They are syntactically restricted to a single expression. Semantically, they are just syntactic sugar for a normal function definition. Like nested function definitions, lambda functions can reference variables from the containing scope:

 

>>> def make_incrementor(n):

... return lambda x: x + n

...

>>> f = make_incrementor(42)

>>> f(0)

42

>>> f(1)

43

The above example uses a lambda expression to return a function. Another use is to pass a small function

as an argument:

===

Here are some conventions about the content and formatting of documentation strings. The first line should always be a short, concise summary of the object’s purpose. For brevity, it should not explicitly state the object’s name or type, since these are available by other means (except if the name happens to be a verb describing a function’s operation). This line should begin with a capital letter and end with a period. If there are more lines in the documentation string, the second line should be blank, visually separating the summary from the rest of the description. The following lines should be one or more paragraphs describing the object’s calling conventions, its side effects, etc. The Python parser does not strip indentation from multi-line string literals in Python, so tools that process documentation have to strip indentation if desired. This is done using the following convention. The first non-blank line after the first line of the string determines the amount of indentation for the entire documentation string. (We can’t use the first line since it is generally adjacent to the string’s opening quotes so its indentation is not apparent in the string literal.) Whitespace “equivalent” to this indentation is then stripped from the start of all lines of the string. Lines that are indented less should not occur, but if they occur all their leading whitespace should be stripped. Equivalence of whitespace should be tested after expansion of tabs (to 8 spaces, normally).

 

Here is an example of a multi-line docstring:

>>> def my_function():

... """Do nothing, but document it.

...

... No, really, it doesn't do anything.

... """

... pass

...

>>> print(my_function.__doc__)

Do nothing, but document it.  No, really, it doesn't do anything.

===

 

 

 

 

 

No comments:

Post a Comment

Small coding languages

  Yes, Hack is a programming language developed by Facebook (now Meta) as a dialect of PHP. It was designed to address some of the limitatio...