Python
| Created | |
|---|---|
| Type | Language |
| Language | Python |
| Last Edit |
Installation & Setup
Check Python Versions
ls /usr/local/bin/python*
ls /Library/Frameworks/Python.framework/Versions/ Array Functions
Iterate Array
pets = ['cat', 'dog', 'fish']
for f in pets:
print fString Functions
Convert string to char array
s = "III"
components = list(s)
print(components)
my_string = "hello"
char_array = [char for char in my_string]
print(char_array)Create file with newline
printf '%s\n' 'frappe' 'msigma-erpnext' > apps.txtVersions & Shells
Pyenv - Python Versions
If you use a tool like pyenv to manage different Python versions, you can set the experimental virtualenvs.prefer-active-python option to true. Poetry will then try to find the current python of your shell.
For instance, if your project requires a newer Python than is available with your system, a standard workflow would be:
pyenv install 3.9.8
pyenv local 3.9.8 # Activate Python 3.9 for the current project
poetry installCreate virtual environment with specific version of python
virtualenv --python="/usr/bin/python2.6" "/path/to/new/virtualenv/python3.6 -m venv "my_env_name"Pyenv Zsh Path Setup
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(pyenv init -)"' >> ~/.zshrcXMLSEC Error in MAC
- Install all necessary packages for xmlsec
brew install libxml2 libxmlsec1 pkg-config
- Try
pip install xmlsec
- If error persists
libxmlsec1.rb
class Libxmlsec1 < Formula desc "XML security library" homepage "https://www.aleksey.com/xmlsec/" url "https://www.aleksey.com/xmlsec/download/xmlsec1-1.2.37.tar.gz" sha256 "5f8dfbcb6d1e56bddd0b5ec2e00a3d0ca5342a9f57c24dffde5c796b2be2871c" license "MIT" livecheck do url "https://www.aleksey.com/xmlsec/download/" regex(/href=.*?xmlsec1[._-]v?(\d+(?:\.\d+)+)\.t/i) end bottle do sha256 cellar: :any, arm64_ventura: "26d6ebddf4e97431819583ad699228360886d81786b332084693d0ad34aa2c72" sha256 cellar: :any, arm64_monterey: "66646e0a3c47fe21b5d6257d2940c1cbaddd68fd71845ae21eb34275b2913db4" sha256 cellar: :any, arm64_big_sur: "6520bff7f714071fc7a5925dc2335c5482ce59383386500e1f51680bf3e69850" sha256 cellar: :any, ventura: "15faa359429f324b4d18e49c70b0832cf93eb052ad0ef74ccddf1a2db0a4aad5" sha256 cellar: :any, monterey: "dfc4528593b38556559a49053f7b5e3a46ae07d844ad3412a65c22214624a932" sha256 cellar: :any, big_sur: "d428a24cc5c8165e84718292cd4a7a21519b1ce1f46c82ffff0bc27216b8a573" sha256 cellar: :any, catalina: "b67b572409b3d79387f621c9f28338d0ec99342477f50643ff3a6032b58133c6" sha256 cellar: :any_skip_relocation, x86_64_linux: "a52005111565d460c6774d5c5be9c8a0db05e0a06dc8715b7c1f59ab4a66fcb0" end depends_on "pkg-config" => :build depends_on "gnutls" # Yes, it wants both ssl/tls variations depends_on "libgcrypt" depends_on "libxml2" depends_on "openssl@1.1" uses_from_macos "libxslt" on_macos do depends_on xcode: :build end # Add HOMEBREW_PREFIX/lib to dl load path patch :DATA # Fix -flat_namespace being used on Big Sur and later. patch do url "https://raw.githubusercontent.com/Homebrew/formula-patches/03cf8088210822aa2c1ab544ed58ea04c897d9c4/libtool/configure-big_sur.diff" sha256 "35acd6aebc19843f1a2b3a63e880baceb0f5278ab1ace661e57a502d9d78c93c" end def install args = ["--disable-dependency-tracking", "--prefix=#{prefix}", "--disable-crypto-dl", "--disable-apps-crypto-dl", "--with-nss=no", "--with-nspr=no", "--enable-mscrypto=no", "--enable-mscng=no", "--with-openssl=#{Formula["openssl@1.1"].opt_prefix}"] system "./configure", *args system "make", "install" end test do system "#{bin}/xmlsec1", "--version" system "#{bin}/xmlsec1-config", "--version" end end __END__ diff --git a/src/dl.c b/src/dl.c index 6e8a56a..0e7f06b 100644 --- a/src/dl.c +++ b/src/dl.c @@ -141,6 +141,7 @@ xmlSecCryptoDLLibraryCreate(const xmlChar* name) { } #ifdef XMLSEC_DL_LIBLTDL + lt_dlsetsearchpath("HOMEBREW_PREFIX/lib"); lib->handle = lt_dlopenext((char*)lib->filename); if(lib->handle == NULL) { xmlSecError(XMLSEC_ERRORS_HERE,
brew edit libxmlsec1
brew install /opt/homebrew/opt/libxmlsec1/.brew/libxmlsec1.rbbrew unlink libxmlsec1Pipx
Poetry
Poetry is a tool for dependency management and packaging in Python.
https://awstip.com/utilizing-poetry-for-managing-python-project-requirements-b911245d3aa2
.gitignore
poetry.lock
Steps
Install Poetry
curl -sSL https://install.python-poetry.org | python3 -Poetry should always be installed in a dedicated virtual environment to isolate it from the rest of your system. It should in no case be installed in the environment of the project that is to be managed by Poetry. This ensures that Poetry’s own dependencies will not be accidentally upgraded or uninstalled. (Each of the following installation methods ensures that Poetry is installed into an isolated environment.) In addition, the isolated virtual environment in which poetry is installed should not be activated for running poetry commands.
Utilizing Poetry for Managing Python Project RequirementsHi friends, and welcome to another edition of this guide.
https://awstip.com/utilizing-poetry-for-managing-python-project-requirements-b911245d3aa2
Add Poetry To PATH
Linux/Mac
Open this configuration file:
Bash:
~/.bashrcor~/.bash_profileAdd the following line at the end of the file and save.
export PATH="/home/ray/.local/bin:$PATH"To make the changes take effect in your current shell session, run the following command:
source <shell_configuration_file>i.e. source ~/.bashrc
Once the installation is completed, we need to verify that Poetry is installed correctly with this command:
poetry --version
Usage: Using Poetry to create a Python project
$ poetry new sample-project
$ cd sample-projectThis will create the following files and folders:
sample-project
├── README.rst
├── pyproject.toml
├── sample_project
│ └── __init__.py
└── tests
├── __init__.py
└── test_sample_project.pyDependencies are managed inside the pyproject.toml file:
[tool.poetry]name = "sample-project"
version = "0.1.0"
description = ""
authors = ["John Doe <john@doe.com>"]
[tool.poetry.dependencies]python = "^3.10"
[tool.poetry.dev-dependencies]pytest = "^5.2"
[build-system]requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"For more on pyproject.toml, the new Python package configuration file that treats "every project as a package", check out the What the heck is pyproject.toml? article.
To add new a dependency, simply run:
$ poetry add [--dev] <package name>The --dev flag indicates that the dependency is meant to be used in development mode only. Development dependencies are not installed by default.
For example:
$ poetry add flaskThis downloads and installs Flask from PyPI inside the virtual environment managed by Poetry, adds it along with all sub-dependencies to the poetry.lock file, and automatically adds it (a top-level dependency) to pyproject.toml:
[tool.poetry.dependencies]python = "^3.10"
Flask = "^2.0.3"Take note of the version constraint: "^2.0.3".
To run a command inside the virtual environment, prefix the command with poetry run. For example, to run tests with pytest:
$ poetry run python -m pytestpoetry run <command> will run commands inside the virtual environment. It doesn't activate the virtual environment, though. To activate Poetry's virtual environment you need to run poetry shell. To deactivate it, you can simply run the exit command. Consequently, you can activate your virtual environment before working on the project and deactivate once you're done or you can use poetry run <command> throughout development.
Finally, Poetry works well with pyenv. Review Managing environments from the official docs for more on this.
Removing dependencies
To remove a package from the installed dependencies, run poetry remove <package_name>
poetry remove fastapiUpdate dependencies
poetry update updates all dependencies and pin exact versions into poetry.lock
Usage: Using poetry in existing project
Poetry can be used to initialize an existing project using this command
cd pre-existing-project
poetry initAdd dependencies
The pyproject.toml file automatically created for the project has a section called [tool.poetry.dependencies] as explained earlier. This is where the developer can specify the package names and version constraints.
[tool.poetry.dependencies]
python = "^3.10"poetry add command can be used to automatically install a new package.
Remember to run the command inside the project directory
cd py-project
poetry add requestsThis automatically includes the newly installed package as part of the dependencies.
[tool.poetry.dependencies]
python = "^3.10"
requests = "^2.31.0"Sometimes, you may need to install packages that are only used in development mode. To achieve this, add the -D flag during installation.
poetry add -D factory_boyA new section called [tool.poetry.group.dev.dependencies] is added to the pyproject.toml file, which specifies the development packages.
[tool.poetry.group.dev.dependencies]
factory-boy = "^3.2.1"Installing dependencies:
poetry install checks for the py-project.toml file, resolves the specified dependencies, and installs them.
Say after creating a poetry project, I then manually added to a new package i.e. fastapi = “0.97.0” to the [tool.poetry.dependencies] section as shown below.
[tool.poetry.dependencies]
python = "^3.10"
fastapi = "^0.97.0"Running poetry install works fine after this manual update if no poetry.lock file is present because poetry automatically resolves all dependencies listed in the pyproject.toml file and downloads the latest version of their files. It writes all the packages and their exact versions that it downloaded to the poetry.lock file, locking the project to those specific versions.
If poetry.lock is already present and the dependencies is updated manually, then you run poetry install it throws an error similar to this:
Installing dependencies from lock file
Warning: poetry.lock is not consistent with pyproject.toml. You may be getting improper dependencies. Run `poetry lock [--no-update]` to fix it.
Because py-project depends on fastapi(0.97.0) which doesn't match any versions, version solving failed.This error evolved because poetry install depends on the poetry.lock file to install and resolve packages but if found out that the new manually input package (‘fastapi’ in this case) could not be found in the poetry.lock file.
To resolve this, you need to run poetry lock which checks the dependencies in the pyproject.toml and lock it into the poetry.lock file
This command also automatically update existing packages and resolve them to fit the version of the newly added package. If you want the existing dependencies untouched, you need to run poetry lock --no-update so that it only resolves and install the new package.
Removing dependencies
To remove a package from the installed dependencies, run poetry remove <package_name>
poetry remove fastapiTo list all available packages, run poetry show
Check out the documentation to view the list of available commands.
Update dependencies
poetry update updates all dependencies and pin exact versions into poetry.lock
To update few specific packages, run poetry update <package_1> <package_2>
poetry update requests fastapiRun scripts
If you need to execute a specific command or script within the project’s virtual environment, you can utilize the “poetry run” command. For instance, if you want to run an automated test using pytest, you can employ the following command:
poetry run pytestUsing existing requirements.txt file
If you already have a project with dependencies listed in the requirements.txt file, you can use the command:
xargs poetry add < requirements.txtExport command
The export command generates a requirements.txt file from the poetry.lock file.
poetry export -f requirements.txt --output requirements.txt
Usage: Convert Requirements To Poetry
poetry add $(cat requirements.txt)Display Env Info
poetry env infoNon Package
Poetry can be operated in two different modes. The default mode is the package mode, which is the right mode if you want to package your project into an sdist or a wheel and perhaps publish it to a package index. In this mode, some metadata such as name and version, which are required for packaging, are mandatory. Further, the project itself will be installed in editable mode when running poetry install.
If you want to use Poetry only for dependency management but not for packaging, you can use the non-package mode:
[tool.poetry]
package-mode = false
In this mode, metadata such as name and version are optional. Therefore, it is not possible to build a distribution or publish the project to a package index. Further, when running poetry install, Poetry does not try to install the project itself, but only its dependencies (same as poetry install --no-root).
Switching between environments
Sometimes this might not be feasible for your system, especially Windows where pyenv is not available, or you simply prefer to have a more explicit control over your environment. For this specific purpose, you can use the env use command to tell Poetry which Python version to use for the current project.
poetry env use /full/path/to/python
If you have the python executable in your PATH you can use it:
poetry env use python3.7
You can even just use the minor Python version in this case:
poetry env use 3.7
If you want to disable the explicitly activated virtual environment, you can use the special system Python version to retrieve the default behavior:
poetry env use system
Base64
String to Base64
import base64
import json
string_og = {"key":"Hello world"}
string = json.dumps(string_og)
string_bytes = string.encode('utf-8')
# Encode bytes to base64
base64_encoded = base64.b64encode(string_bytes)
# Convert base64 bytes to a string
base64_string = base64_encoded.decode('utf-8')
print(base64_string)Base64 to String
import base64
import json
base64_bytes = base64_string.encode('utf-8')
# Decode base64 bytes
decoded_bytes = base64.b64decode(base64_bytes)
# Convert bytes to string
original_string = decoded_bytes.decode('utf-8')
print(original_string)OOP
- Class and Object:
- Real-world example: Cars
- Class: Car Model (e.g., Toyota Camry): BLUEPRINT
- Object: Your specific Toyota Camry with its unique VIN, color, and mileage.
- Real-world example: Cars
- Attributes:
- Real-world example: Human
- Attributes: Name, Age, Height, Weight
- Each person (object) has specific values for these attributes.
- Real-world example: Human
- Methods:
- Real-world example: Smartphones
- Methods: Make a call, Send a text, Take a photo
- The actions you perform with your smartphone are analogous to methods.
- Real-world example: Smartphones
- Inheritance:
- Real-world example: Vehicles
- Base Class: Vehicle
- Subclasses: Car, Motorcycle, Truck
- Subclasses inherit common properties and behaviors from the base class.
- Real-world example: Vehicles
- Encapsulation:
- Real-world example: Coffee Machine
- The inner workings of a coffee machine are encapsulated. Users interact with it through well-defined interfaces (e.g., buttons, settings), but they don't need to understand the internal processes.
- Real-world example: Coffee Machine
- Polymorphism:
- Real-world example: Animals
- Base Class: Animal
- Derived Classes: Dog, Cat, Bird
- Different animals can make different sounds, demonstrating polymorphism.
- Real-world example: Animals
Python is an object-oriented and interpreted programming language, and it supports OOP principles. Here are the key concepts of OOP in Python:
- Class and Object:
- Class: A class is a blueprint for creating objects. It defines the attributes and methods that the objects will have.
- Object: An object is an instance of a class. It is a concrete realization of the class blueprint.
class Car: def __init__(self, make, model): self.make = make self.model = model my_car = Car("Toyota", "Camry")
- Attributes:
- Attributes are data members that store information about the object.
pythonCopy code class Car: def __init__(self, make, model): self.make = make self.model = model my_car = Car("Toyota", "Camry") print(my_car.make) # Output: Toyota
- Methods:
- Methods are functions defined within a class. They operate on the object and can access or modify its attributes.
class Car: def __init__(self, make, model): self.make = make self.model = model def display_info(self): print(f"{self.make} {self.model}") my_car = Car("Toyota", "Camry") my_car.display_info() # Output: Toyota Camry
The __init__() Function :
All classes have a function called __init__(), which is always executed when the class is being initiated.
Use the __init__() function to assign values to object properties, or other operations that are necessary to do when the object is being created.
The __init__() function is called automatically every time the class is being used to create a new object.
The self parameter is a reference to the current instance of the class, and is used to access variables that belong to the class. It does not have to be named self , you can call it whatever you like, but it has to be the first parameter of any function in the class.
- Inheritance:
- Inheritance allows a class (subclass/derived class) to inherit the properties and methods of another class (superclass/base class). It promotes code reusability.
class ElectricCar(Car): def __init__(self, make, model, battery_capacity): super().__init__(make, model) self.battery_capacity = battery_capacity my_electric_car = ElectricCar("Tesla", "Model S", 75) my_electric_car.display_info() # Output: Tesla Model S
- Encapsulation:
- Encapsulation restricts access to some of the object's components and prevents the accidental modification of data. It is achieved through the use of private and protected attributes and methods.
class Student: def __init__(self, name, age): self._name = name # Protected attribute self.__age = age # Private attribute def get_age(self): return self.__age student = Student("John", 20) print(student._name) # Accessing protected attribute print(student.get_age()) # Accessing private attribute through a methodInheritance allows us to define a class that inherits all the methods and properties from another class.
Parent class is the class being inherited from, also called base class.
Child class is the class that inherits from another class, also called derived class.
Create a Parent Class
class Person:
def __init__(self, fname, lname):
self.firstname = fname
self.lastname = lname
def printname(self):
print(self.firstname, self.lastname)
#Use the Person class to create an object, and then execute the printname method:
x = Person("John", "Doe")
x.printname()
Create a Child Class
To create a class that inherits the functionality from another class, send the parent class as a parameter when creating the child class.
class Student(Person):
def __init__(self, fname, lname, year):
super().__init__(fname, lname)
self.graduationyear = year
def welcome(self):
print("Welcome", self.firstname, self.lastname, "to the class of", self.graduationyear)
By using the super() function, you do not have to use the name of the parent element, it will automatically inherit the methods and properties from its parent.
Types of Inheritance :
Single inheritance : A class inherits from only one base class
Multiple inheritance : A class can inherit from multiple base classes. Allows a derived class to inherit attributes and methods from more than one class.
Multilevel inheritance : A class inherits from another class, and then a new class inherits from the derived class. It forms a chain of inheritance.
Exercise :
Create a BankAccount class with the following features:
A constructor (__init__) that initializes the account holder's name and initial balance.
Methods (deposit and withdraw) to deposit and withdraw money from the account.
A method (get_balance) to retrieve the current balance.
Ensure that the account cannot be overdrawn (balance cannot go below zero).
Provide a simple usage example to demonstrate the functionality of the BankAccount class.
Write code for the BankAccount class and the example usage.
class BankAccount: def __init__(self, account_holder, initial_balance=0): self.account_holder = account_holder self.balance = initial_balance def deposit(self, amount): if amount > 0: self.balance += amount return f"Deposit of Rs{amount} successful. Current balance: Rs{self.balance}" else: return "Invalid deposit amount." def withdraw(self, amount): if amount > 0: if amount <= self.balance: self.balance -= amount return f"Withdrawal of Rs{amount} successful. Current balance: Rs{self.balance}" else: return "Insufficient funds. Withdrawal canceled." else: return "Invalid withdrawal amount." def get_balance(self): return f"Current balance for {self.account_holder}: Rs{self.balance}" # Example usage account1 = BankAccount("Alice", 1000) print(account1.get_balance()) print(account1.deposit(500)) print(account1.withdraw(200)) print(account1.withdraw(1500)) print(account1.get_balance())
- Polymorphism:
- Polymorphism allows objects of different classes to be treated as objects of a common base class. It can be achieved through method overloading or method overriding.
class Shape: def area(self): pass class Circle(Shape): def __init__(self, radius): self.radius = radius def area(self): return 3.14 * self.radius**2 class Rectangle(Shape): def __init__(self, length, width): self.length = length self.width = width def area(self): return self.length * self.width def calculate_area(shape): return shape.area() circle = Circle(5) rectangle = Rectangle(4, 6) print("Circle Area:", calculate_area(circle)) print("Rectangle Area:", calculate_area(rectangle))Exercise
Implement animal base class and dog and cat as child classes with polymorphism
class Animal: def sound(self): pass class Dog(Animal): def sound(self): return "Woof" class Cat(Animal): def sound(self): return "Meow" def make_sound(animal): print(animal.sound()) dog = Dog() cat = Cat() make_sound(dog) # Output: Woof make_sound(cat) # Output: Meow
These are the fundamental concepts of OOP in Python. They provide a way to structure code, promote reusability, and enhance code organization.
Exercises
- Class and Object:
- Task: Create a class called
Productwith attributes like product ID, name, and price. Create two instances of the class representing different products.
- Task: Create a class called
- Attributes:
- Task: Extend the
Productclass to include attributes like manufacturer, category, and stock quantity. Display the information of a product, including all attributes.
- Task: Extend the
- Methods:
- Task: Design a class called
ShoppingCartthat has methods for adding a product to the cart, removing a product, and calculating the total cost of items in the cart.
- Task: Design a class called
- Inheritance:
- Task: Create a base class
Animalwith methods likeeatandsleep. Derive two subclasses,BirdandMammal, from the base class and implement specific behavior for each.
- Task: Create a base class
- Encapsulation:
- Task: Implement a class
Personwith private attributes for name, age, and address. Include methods to get and set these attributes while ensuring proper encapsulation.
- Task: Implement a class
- Polymorphism:
- Task: Model a class hierarchy for a transportation system. Create a base class
Transportationwith a methodmove. Derive two classes,CarandBicycle, and override themovemethod to represent different modes of transportation.
- Task: Model a class hierarchy for a transportation system. Create a base class
Modify and Delete object properties :
We can modify and delete object properties like this :
person1.age =27
print(person1.age)
person1.display_info()
del person1.age
Numpy
NumPy is a powerful numerical computing library for Python that provides support for large, multi-dimensional arrays and matrices, along with a collection of mathematical functions to operate on these arrays. It is a fundamental package for scientific computing in Python. Some key features of NumPy include:
- Multi-dimensional Arrays: NumPy provides a powerful
ndarrayobject that represents multi-dimensional arrays or matrices. These arrays can be of any size and can have multiple dimensions.
- Mathematical Functions: NumPy includes a wide range of mathematical functions that operate on entire arrays without the need for explicit looping. These functions are optimized for performance and efficiency.
- Broadcasting: NumPy allows operations between arrays of different shapes and sizes through a feature called broadcasting. This enables efficient element-wise operations on arrays with different shapes.
- Linear Algebra Operations: NumPy provides a comprehensive set of linear algebra operations, such as matrix multiplication, eigenvalue decomposition, and singular value decomposition.
- Random Number Generation: NumPy includes functions for generating random numbers with various probability distributions, which is useful for simulations and statistical analysis.
- Indexing and Slicing: NumPy arrays support advanced indexing and slicing operations, making it easy to extract and manipulate data.
- Integration with other Libraries: NumPy is often used in conjunction with other libraries in the scientific Python ecosystem, such as SciPy (scientific computing library), Matplotlib (plotting library), and scikit-learn (machine learning library).
NumPy is widely used in various scientific and data analysis applications due to its efficiency, ease of use, and extensive functionality.
pip install numpy
import numpy as npExercises
Reverse an array
Create an array from 1 to 40 (inclusive) using Numpy and reverse the array
solution
# Importing the NumPy library with an alias 'np' import numpy as np # Creating an array 'x' using arange() function with values from 12 to 37 (inclusive) x = np.arange(1, 40) # Printing the original array 'x' containing values from 12 to 37 print("Original array:") print(x) # Reversing the elements in the array 'x' and printing the reversed array print("Reverse array:") x = x[::-1] print(x)
Conversion
Write a NumPy program to convert Fahrenheit degrees into Centigrade degrees. Fahrenheit values are stored in a NumPy array.
Sample Array [0, 12, 45.21, 34, 99.91]
Expected Output:
Values in Centigrade degrees:
[-17.78 -11.11 7.34 1.11 37.73 0. ]
Solution
# Importing the NumPy library with an alias 'np' import numpy as np # List of Fahrenheit values fvalues = [0, 12, 45.21, 34, 99.91, 32] # Creating a NumPy array from the Fahrenheit values list F = np.array(fvalues) # Printing the Fahrenheit values print("Values in Fahrenheit degrees:") print(F) # Converting Fahrenheit values to Centigrade degrees and printing the result print("Values in Centigrade degrees:") print(np.round((5 * F / 9 - 5 * 32 / 9), 2))np.round((5F/9 - 532/9), 2): Applies the formula to convert Fahrenheit to Celsius for each value in the NumPy array ‘F’. The np.round() function is used to round the resulting values to 2 decimal places.
Pandas
Pandas is an open-source data manipulation and analysis library for Python. It provides data structures for efficiently storing and manipulating large datasets, as well as tools for working with structured data. Pandas is built on top of the NumPy library and is a key component of the Python data science ecosystem.
Key features of Pandas include:
- DataFrame: The central data structure in Pandas is the DataFrame, a two-dimensional table with labeled rows and columns. It is similar to a spreadsheet or SQL table and provides a powerful and flexible way to work with structured data. Pandas is designed for working with heterogeneous, tabular data.
- Series: Pandas also includes a one-dimensional labeled array called Series, which can be thought of as a single column of a DataFrame. Series are often used to represent a single variable or feature.
- Data Cleaning and Preprocessing: Pandas provides a wide range of functions for cleaning and preprocessing data, including handling missing values, filtering, sorting, and transforming data.
- Data Alignment: Pandas automatically aligns data based on label indices, making it easy to perform operations on datasets with different structures.
- GroupBy: Pandas supports the "group by" operation, allowing users to split data into groups based on some criteria and then apply a function to each group independently.
- Merging and Joining: Pandas provides tools for combining datasets through merging and joining operations, similar to SQL.
- Time Series Data: Pandas has robust support for working with time series data, including date and time functionality, resampling, and moving window statistics.
- IO Tools: Pandas can read and write data in various formats, including CSV, Excel, SQL databases, and more.
pip install pandas
pip install pyarrow
import pandas as pdimport pandas as pd
df = pd.read_csv('data.csv')
print(df.to_string())Exercises
Write a Pandas program to display the dimensions or shape of the World alcohol consumption dataset. Also extract the column names from the dataset.
Test Data:
https://www.w3resource.com/python-exercises/pandas/filter/world_alcohol.php
Year WHO region Country Beverage Types Display Value
0 1986 Western Pacific Viet Nam Wine 0.00
1 1986 Americas Uruguay Other 0.50
2 1985 Africa Cte d'Ivoire Wine 1.62
3 1986 Americas Colombia Beer 4.27
4 1987 Americas Saint Kitts and Nevis Beer 1.98Soln
import pandas as pd # World alcohol consumption data w_a_con = pd.read_csv('world_alcohol.csv') print("World alcohol consumption sample data:") print(w_a_con.head()) print('\nShape of the dataframe: ',w_a_con.shape) print('\nNumber of rows: ',w_a_con.shape[0]) print('\nNumber of column: ',w_a_con.shape[1]) print("\nExtract Column Names:") print(w_a_con.columns)Copy
Sample Output:
World alcohol consumption sample data: Year WHO region ... Beverage Types Display Value 0 1986 Western Pacific ... Wine 0.00 1 1986 Americas ... Other 0.50 2 1985 Africa ... Wine 1.62 3 1986 Americas ... Beer 4.27 4 1987 Americas ... Beer 1.98 [5 rows x 5 columns] Shape of the dataframe: (100, 5) Number of rows: 100 Number of column: 5 Extract Column Names: Index(['Year', 'WHO region', 'Country', 'Beverage Types', 'Display Value'], dtype='object')
Numpy vs Pandas
Use Cases:
- NumPy: Primarily focuses on numerical computing and array-based operations. It is well-suited for tasks like linear algebra, statistical operations, and numerical simulations.
- Pandas: Designed for data manipulation, cleaning, and analysis. It is particularly effective for working with structured data, such as CSV files, Excel spreadsheets, SQL tables, and more.
Indexing:
- NumPy: Employs integer-based indexing for arrays, and it relies on the position of elements within the array.
- Pandas: Uses labeled indexing, allowing for both integer and label-based indexing. This makes it easier to reference and manipulate data based on column names or row indices.
Performance:
- NumPy: Optimized for numerical operations and is generally faster for mathematical computations than Pandas.
- Pandas: While it may not be as fast as NumPy for numerical operations, it excels in terms of data manipulation and analysis.
Matplotlib
Matplotlib is a 2D plotting library for Python that facilitates the creation of static, animated, and interactive visualizations in Python.
- Flexible Plotting: Matplotlib provides a wide range of plot types, including line plots, scatter plots, bar plots, histograms, pie charts, and more. It allows users to customize the appearance of plots to meet specific requirements.
- Publication-Quality Graphics: Matplotlib produces high-quality, publication-ready graphics suitable for use in scientific publications, presentations, and reports.
- Support for Multiple Output Formats: Matplotlib can generate plots in various formats, including PNG, PDF, SVG, and more. This flexibility allows users to integrate plots seamlessly into different types of documents.
- Integration with Jupyter Notebooks: Matplotlib is well-integrated with Jupyter notebooks, providing interactive plotting capabilities within the notebook environment.
- Matplotlib Pyplot Interface: Matplotlib has a MATLAB-like plotting interface called Pyplot, which simplifies the creation of common plots with a minimal amount of code.
pip install matplotlib
import matplotlib as pltLogging
https://betterstack.com/community/guides/logging/how-to-start-logging-with-python/
import logging
logging.basicConfig(level=logging.INFO) # Default min level = WARNING
logging.debug("A debug message")
logging.info("An info message")
logging.warning("A warning message")
logging.error("An error message")
logging.critical("A critical message")
TRACE:root:A trace message
DEBUG:root:A debug message
INFO:root:An info message
WARNING:root:A warning message
ERROR:root:An error message
CRITICAL:root:A critical message
Custom Log Level
import logging
# Adopted from https://stackoverflow.com/a/35804945/1691778
# Adds a new logging method to the logging module
def addLoggingLevel(levelName, levelNum, methodName=None):
if not methodName:
methodName = levelName.lower()
if hasattr(logging, levelName):
raise AttributeError("{} already defined in logging module".format(levelName))
if hasattr(logging, methodName):
raise AttributeError("{} already defined in logging module".format(methodName))
if hasattr(logging.getLoggerClass(), methodName):
raise AttributeError("{} already defined in logger class".format(methodName))
def logForLevel(self, message, *args, **kwargs):
if self.isEnabledFor(levelNum):
self._log(levelNum, message, args, **kwargs)
def logToRoot(message, *args, **kwargs):
logging.log(levelNum, message, *args, **kwargs)
logging.addLevelName(levelNum, levelName)
setattr(logging, levelName, levelNum)
setattr(logging.getLoggerClass(), methodName, logForLevel)
setattr(logging, methodName, logToRoot)
# Create the TRACE level
addLoggingLevel("TRACE", logging.DEBUG - 5)
logging.basicConfig(level=logging.TRACE)
# Use the TRACE level
logging.trace("A trace message")
logging.debug("A debug message")
logging.info("An info message")
logging.warning("A warning message")
logging.error("An error message")
logging.critical("A critical message")
Custom Log Formatting
logging.basicConfig(
format="%(levelname)s | %(asctime)s | %(message)s",
datefmt="%Y-%m-%dT%H:%M:%SZ",
)
logging.warning("Something bad is going to happen")WARNING | 2023-02-05T11:45:31Z | Something bad is going to happenlogging.basicConfig(
format="%(name)s: %(asctime)s | %(levelname)s | %(filename)s:%(lineno)s | %(process)d >>> %(message)s",
datefmt="%Y-%m-%dT%H:%M:%SZ",
)
logging.warning("system disk is 85% full")
logging.error("unexpected error")root: 2023-02-05T14:11:56Z | WARNING | example.py:8 | 428223 >>> system disk is 85% full
root: 2023-02-05T14:11:56Z | ERROR | example.py:9 | 428223 >>> unexpected error
Custom Loggers
It's best to avoid using the root logger and instead create a separate logger for each module in your application.
import logging
logger = logging.getLogger("example")
logger.info("An info")
logger.warning("A warning")A warningCreate logger with module name
logger = logging.getLogger(__name__)Handlers & Formatters
import sys
import logging
logger = logging.getLogger("example")
# Stream Handler
stdout = logging.StreamHandler(stream=sys.stdout)
stdout.setLevel(logging.INFO)
# Formatter
fmt = logging.Formatter(
"%(name)s: %(asctime)s | %(levelname)s | %(filename)s:%(lineno)s | %(process)d >>> %(message)s"
)
stdout.setFormatter(fmt)
logger.addHandler(stdout)
logger.setLevel(logging.INFO)
logger.info("An info")
logger.warning("A warning")Handler and Logger can have different log levels
example: 2023-02-05 21:21:46,634 | INFO | example.py:17 | 653630 >>> An info
example: 2023-02-05 21:21:46,634 | WARNING | example.py:18 | 653630 >>> A warning
Logging To File
import sys
import logging
logger = logging.getLogger(__name__)
fileHandler = logging.FileHandler("logs.txt")
fmt = logging.Formatter(
"%(name)s: %(asctime)s | %(levelname)s | %(filename)s:%(lineno)s | %(process)d >>> %(message)s"
)
fileHandler.setFormatter(fmt)
logger.addHandler(fileHandler)
logger.setLevel(logging.DEBUG)
logger.debug("A debug message")
logger.error("An error message")Automatic Log File Rotation
from logging.handlers import RotatingFileHandler
fileHandler = RotatingFileHandler("logs.txt", backupCount=5, maxBytes=5000000)With this setting in place, the logs.txt file will be created and written to as before until it reaches 5 megabytes. It will subsequently be renamed to logs.txt.1 and a new logs.txt file will be created once again. When the new file gets to 5 MB, it will be renamed to logs.txt.1 and the previous logs.txt.1 file will be renamed to logs.txt.2. This process continues until we get to logs.txt.5. At that point, the oldest file (logs.txt.5) gets deleted to make way for the newer logs.