A Guide to Python
Tags: python, programming, beginners
Published: 2023-08-09 02:53:34

Python is one of the most popular and versatile programming languages in the world. It is widely used for web development, data analysis, machine learning, automation, and many other applications. Python has a simple and elegant syntax that makes it easy to read and write code. It also has a rich set of built-in libraries and modules that provide many useful features and functions.

How to Use Variables, Data Types, Operators, Expressions, and Statements

Variables: A variable is a name that refers to a value stored in memory. You can assign a value to a variable using the = operator. For example:

```python
x = 10
y = "Hello"
```

This assigns the value 10 to the variable x and the value "Hello" to the variable y. You can use variables in expressions and statements as if they were values. For example:
```python
x = 5
y = 9
z = x + y
print(z)
```
This adds the values of x and y and assigns the result to z. Then it prints z to the standard output.

Data Types: A data type is a category of values that have certain characteristics and behaviors. Python has several built-in data types such as int (integer), float (floating-point number), str (string), bool (boolean), list (sequence of values), tuple (immutable sequence of values), dict (mapping of keys to values), and set (collection of unique values). You can check the type of a value or a variable using the type() function. For example:
```python
x = 5
y = 'Hello'
print(type(x)) # prints <class 'int'> 
print(type(y)) # prints <class 'str'>
```
You can also convert one data type to another using built-in functions such as int(), float(), str(), bool(), list(), tuple(), `dict()`, and set(). For example:
```python
a = 3.14
b = int(a) # converts a to an integer 
c = str(a) # converts a to a string
```
Operators: Operators are special symbols that perform operations on values or variables. Python has several types of operators such as arithmetic operators `(+, -, , /, *, %, //)`, assignment operators `(=, +=, -=, *=, /= etc.)`, comparison operators `(==, != , < , > , <= , >= )`, logical operators `(and, or, not )`, bitwise operators `(& , | , ^ , ~ , << , >> )`, membership operators (in, not in), identity operators (is, is not). The precedence and associativity rules determine how operators are evaluated in an expression.

Expressions: An expression is a combination of values, variables, operators, and functions that can be evaluated to produce a single value. For example:
```python
x = 5
y = x*2
```
This is an expression that uses arithmetic operators and variables to calculate a value for y.

Statements: A statement is an instruction that performs some action or controls the flow of execution. For example:
```python
y = 5

if y > 0: print("Positive") 
elif y == 0: print("Zero") 
else: print("Negative")
```
This is an if-elif-else statement that checks the value of y and prints different messages accordingly.

How to use control flow tools

If-Else Statements

Perhaps the most well-known control flow tool is the if-else statement. It allows you to execute a block of code based on a specified condition. The syntax of the if-else statement is as follows:
```python
if condition:
# do something
else:
# do something else
```
The condition can be any expression that evaluates to a boolean value (True or False). The indentation is important in Python, as it defines the scope of each block. The else clause is optional and will only execute if the condition is False.

For example:
```python
x = 10
if x > 0:
    print("x is positive")
else:
    print("x is negative or zero")
```
This code will print "x is positive" because x > 0 evaluates to True.

You can also use elif clauses to check for multiple conditions:
```python
x = 10
if x > 0:
    print("x is positive")
elif x < 0:
    print("x is negative")
else:
    print("x is zero")
```
This code will print "x is positive" because x > 0 evaluates to True and none of the other conditions are checked.

For Loops

Another common control flow tool is the for loop. It allows you to iterate over a sequence of items and execute a block of code for each item. The syntax of the for loop is as follows:
```python
for item in sequence:
# do something with item
```
The sequence can be any iterable object such as a list, a tuple, a string, or a range object. The item variable can be any name you choose and will hold each element of the sequence in turn.

For example:
```python
fruits = ["apple", "banana", "orange"]
for fruit in fruits:
    print(fruit)
```
This code will print each fruit in the fruits list on a separate line.

The start parameter specifies the starting value (inclusive), the stop parameter specifies the ending value (exclusive), and the step parameter specifies how much to increment by each iteration. If omitted, start defaults to 0 and step defaults to 1.
```python
range(start, stop, step)
```
The start parameter specifies the starting value (inclusive), the stop parameter specifies the ending value (exclusive), and the step parameter specifies how much to increment by each iteration. If omitted, start defaults to 0 and step defaults to 1.

For example:
```python
for i in range(1, 11):
    print(i)
```
While Loops
```python
while condition:
# do something
```
The condition can be any expression that evaluates to a boolean value (True or False). The loop will keep running until either:

The condition becomes False

A break statement exits from it

An exception occurs

For example:
```python
n = 1
while n < 100:
    print(n)
    n = n * 2
```
This code will print powers of two that are less than 100 on separate lines.

Break and Continue Statements

Sometimes you may want to alter or terminate your loop based on some criteria other than your initial condition. For this purpose, you can use break and continue statements inside your loops.

The break statement allows you to exit from your current loop immediately and resume execution at the next statement after it. For example:
```python
for i in range(1, 11):
    if i == 5:
        break # exit from loop when i equals 5
    print(i)
```
This code will only print numbers from 1 to 4 because when i equals 5 it breaks out from it.

The continue statement allows you to skip the rest of your current iteration of a loop and move on to the next one. It can be used in both while and for loops. For example:
```python
for i in range(10):
    if i % 2 == 0: #if i is even 
        continue # skip this iteration
    print(i) # print only odd numbers
```
This code will print only odd numbers from 0 to 9 because it will skip every even number using continue.

You can use continue statements when you want to avoid some unwanted values or conditions in your loop. For example, if you want to calculate the sum of positive numbers in a list, you can use continue to skip negative numbers:
```python
numbers = [1, -2, 3, -4, 5]
sum = 0 
for n in numbers: 
    if n < 0: # if n is negative
        continue # skip this iteration
    sum += n # add n to sum
print(sum) #prints 9
```
This code will print 9 because it will ignore -2 and -4 using continue.

Data structures

Lists

A list is a mutable and ordered collection of items that can be of any type. Lists are created by enclosing items in square brackets [ ] or using the list() constructor function. For example:
```python
#Creating a list of numbers
numbers = [1, 2, 3, 4, 5]
print(numbers) # prints [1, 2, 3, 4, 5]

# Creating a list of strings
fruits = ["apple", "banana", "cherry"]
print(fruits) # prints ["apple", "banana", "cherry"]

# Creating a list of mixed types
mixed = [True, 3.14, "hello", None]
print(mixed) # prints [True, 3.14, "hello", None]

# Creating an empty list
empty = []
print(empty) # prints []

# Creating a list using the list() function
letters = list("abcde")
print(letters) # prints ["a", "b", "c", "d", "e"]
```
Lists support various operations such as indexing, slicing, appending, inserting, removing, sorting, reversing, and more. Here are some examples:
```python
# Accessing items by index (zero-based)
numbers = [1 ,2 ,3 ,4 ,5]
print(numbers[0]) # prints 1
print(numbers[-1]) # 5

# Slicing a list (returns a new list)
numbers = [1 ,2 ,3 ,4 ,5]
print(numbers[1:3]) # prints [2 ,3]
print(numbers[:2]) # prints [1 ,2]
print(numbers[3:]) # prints [4 ,5]
print(numbers[:]) # prints [1 ,2 ,3 ,4 ,5]

# Changing items by index (mutating the list)
numbers = [1 ,2 ,3 ,4 ,5]
numbers[0] = 10
print(numbers) # prints [10 ,2 ,3 ,4 ,5]
```
Tuples

Unlike lists, tuples are immutable, meaning they cannot be changed once created. Tuples are useful for storing data that should not be modified, such as coordinates, dates, or user information.

To create a tuple in Python, we can place a sequence of values separated by commas inside round brackets (). For example:
```python
my_tuple = (1, 2, 3)
print(my_tuple) #prints (1, 2, 3)

We can also create a tuple without using round brackets. This is called tuple packing. For example:

my_tuple = 1, 2, 3
print(my_tuple) #prints (1, 2, 3)

If we want to create a tuple with only one item, we need to add a comma after the item. Otherwise, Python will treat it as a regular value and not as a tuple. For example

my_tuple = (1,)
print(type(my_tuple))
```
Output:
```python
<class 'tuple'>
```
But if we remove the comma:
```python
my_tuple = (1)
print(type(my_tuple))
```
The output becomes
```python
<class 'int'>
```
To access an item from a tuple, we can use square brackets [] with the index of the item. The index starts from zero and goes up to one less than the length of the tuple. For example:
```python
my_tuple = ("apple", "banana", "cherry")
print(my_tuple[0])
print(my_tuple[1])
print(my_tuple[2])
```
Output:
```python
apple
banana
cherry
```
We can also use negative indexes to access items from the end of the tuple. The last item has an index of -1 and goes down by one for each previous item. For example:
```python
my_tuple = ("apple", "banana", "cherry")
print(my_tuple[-1])
print(my_tuple[-2])
print(my_tuple[-3])
```
Output:
```bash
cherry
apple
banana
```
We can also use slicing notation [start:stop:step] to access a range of items from a tuple. The start index is inclusive and the stop index is exclusive. The step specifies how many items to skip between each item. If omitted, it defaults to one. For example:
```python
my_tuple = ("apple", "banana", "cherry", "orange", "kiwi")
print(my_tuple[1:4]) # from index 1 (inclusive) to index 4 (exclusive)
print(my_tuple[:3]) # from index 0 (inclusive) by default to index 3 (exclusive)
print(my_tuple[2:]) # from index 2 (inclusive) to end by default
print(my_tuple[-4:-1]) # from index -4 (inclusive) to index -1 (exclusive)
print(my_tuple[::2]) # every second item from start (inclusive) by default)to end by default
```
Output:
```python
('banana', 'cherry', 'orange')
('apple', 'banana', 'cherry')
('cherry', 'orange', 'kiwi')
('banana', 'cherry', 'orange')
('apple', 'cherry', 'kiwi')
```
To loop through all the items in a tuple, we can use a for loop with either an iterator variable or an index variable.

Using an iterator variable means that we assign each item in turn to a variable name and perform some action on it inside the loop body. For example:
```python
my_tuple = ("red", "green", "blue")
for color in my_tuple:
    print(color.upper())
```
Output:
```bash
RED
GREEN
BLUE
```
Sets

A set is a collection of data types that is iterable, mutable and has no duplicate elements. The order of elements in a set is undefined though it may consist of various elements. A set can have any number of items and they may be of different types (integer, float, tuple, string etc.). But a set cannot have mutable elements like lists, sets or dictionaries as its elements.

Sets are useful for storing and performing operations on data that need to be unique, such as membership tests, mathematical operations like union, intersection or difference, or removing duplicates from a sequence.

In Python, we create sets by placing all the elements inside curly braces {}, separated by comma . For example:
```python
# create an empty set
s = set()

# create a set with some integers
s = {1, 2, 3}

# create a set with mixed data types
s = {1.5, "hello", (4, 5)}
```
We can also use the built-in function set() to create sets from other iterables like lists or tuples.

For example:
```python
# create a set from a list
l = [1, 2 ,3 ,4 ,5]
s = set(l)

# create a set from a tuple
t = ("a", "b", "c")
s = set(t)
```
Note that if we pass an iterable with duplicate elements to the set() function, it will only keep one occurrence of each element in the resulting set.

For example:
```python
# create a list with duplicate elements
l = [1 ,2 ,3 ,4 ,5 ,1 ,2]

# create a set from the list
s = set(l)

# print the set
print(s) # prints {1 ,2 ,3 ,4 ,5}
```
Sets support many methods and operators for performing various operations on them. Some of these are:

- `len(s)`: Returns the number of elements in the set s.
- `x in s`: Returns True if x is an element of the set s; otherwise False.
- `x not in s`: Returns True if x is not an element of the set s; otherwise False.
- `s.add(x)`: Adds x to the set s if it is not already present; does nothing otherwise.
- `s.remove(x)`: Removes x from the set s if it is present; raises `KeyError` otherwise.
- `s.discard(x)`: Removes x from the set s if it is present
- `s.pop()`: Removes and returns an arbitrary element from the set s; raises `KeyError` if s is empty.
- `s.clear()`: Removes all elements from the set s.
- `s.copy()`: Returns a shallow copy of the set s.

Dictionaries

Dictionaries are one of the most useful and versatile data structures in Python. They allow you to store and access key-value pairs of data, where each key is associated with a value. In this guide, you will learn how to create, manipulate, and use dictionaries in Python.

A dictionary is a collection of key-value pairs that are enclosed by curly braces {}. Each key-value pair is separated by a comma , and each pair consists of a key followed by a colon : and then a value. For example:
```python
my_dict = {"name": "Alice", "age": 25, "occupation": "programmer"}
```
This dictionary has three key-value pairs: "name" maps to "Alice", "age" maps to 25, and "occupation" maps to "programmer". The keys can be any immutable data type, such as strings, numbers, booleans, or tuples. The values can be any data type, including other dictionaries or lists.

You can also create a dictionary using the dict() constructor function. For example:
```python
my_dict = dict(name="Alice", age=25, occupation="programmer")
```
This creates the same dictionary as above. Note that when using the dict() function, you don't need to enclose the keys in quotes.

How to Access Dictionary Values

To access the value associated with a key in a dictionary, you can use square brackets [] and specify the key inside them. For example:
```python
print(my_dict["name"]) # prints Alice 
print(my_dict["age"]) # prints 25
```
If you try to access a key that does not exist in the dictionary, you will get a KeyError exception. To avoid this error, you can use the get() method of dictionaries. This method takes two arguments: the key and an optional default value that is returned if the key is not found. For example:
```python
print(my_dict.get("name")) # prints Alice
print(my_dict.get("gender")) # prints None 
print(my_dict.get("gender", "female")) # prints female
```
How to Add or Update Dictionary Elements

To add a new key-value pair to an existing dictionary, you can simply assign a value to a new key using square brackets []. For example:
```python
my_dict["hobby"] = "reading" 
print(my_dict) # prints {'name': 'Alice', 'age': 25, 'occupation': 'programmer', 'hobby': 'reading'}
```
To update an existing value in a dictionary, you can assign a new value to an existing key using square brackets []. For example:
```python
my_dict["age"] = 26 
print(my_dict) # prints {'name': 'Alice', 'age': 26, 'occupation': 'programmer', 'hobby': 'reading'}
```
You can also use the update() method of dictionaries to add or update multiple elements at once. This method takes another dictionary as an argument and merges it with the original dictionary. If there are any duplicate keys between the two dictionaries, the values from the second dictionary will overwrite those from the first one. For example:
```python
my_dict.update({"name": "Bob", "city": "New York"}) 
print(my_dict) # prints {'name': 'Bob', 'age': 26, 'occupation': 'programmer', 'hobby': 'reading', 'city': 'New York'}
```
How to Remove Dictionary Elements

To remove an element from a dictionary by its key, you can use the pop() method of dictionaries. This method takes one argument: the key of the element to be removed. It returns the value associated with the removed element and deletes it from the dictionary. For example:
```python
value = my_dict.pop("hobby") 
print(value) # prints reading print(my_dict) # prints {'name': 'Bob', 'age': 26, 'occupation': 'programmer', 'city': 'New York'}
```
If you try to pop() a key that does not exist in the dictionary, you will get a `KeyError` exception. To avoid this error, you can pass a second argument to pop(), which is a default value that is returned if the key is not found. For example:
```python
value = my_dict.pop("gender", "unknown")
print(value) # prints unknown
```

Functions

A function is a named block of code that performs a specific task. A function can take zero or more inputs (called arguments or parameters) and produce zero or more outputs (called return values).

Functions are useful because they allow you to:

Break down complex problems into smaller and simpler subtasks

Avoid writing the same code multiple times for different inputs

Abstract away the details of how a task is done and focus on what it does

Test and debug your code more easily by isolating different parts of the program

Enhance the readability and structure of your code by giving meaningful names to your tasks

For example, suppose you want to write a program that calculates the area of different shapes such as circles, squares, rectangles, triangles etc. You could write separate formulas for each shape in your main program, but this would make your code long, repetitive and hard to read. A better approach would be to define separate functions for each shape that take the necessary inputs (such as radius, length, width etc.) and return the area as output. Then you could call these functions whenever you need them in your main program.

How to define and call functions in Python?

To define a function in Python, you use the def keyword followed by the name of the function and a pair of parentheses (). Inside the parentheses, you can optionally specify one or more parameters that the function expects as input. After the parentheses, you add a colon : followed by an indented block of code that contains the statements that make up the body of the function.

The general syntax for defining a function in Python is:
```python
def function_name(parameter1, parameter2,...):
# body of the function
# statements
```
To call a function in Python, you use its name followed by parentheses `()`. Inside the parentheses,
you can optionally pass one or more arguments that match with
the parameters defined by
the function. The arguments are separated by commas ,.

The general syntax for calling a function in Python is:
```python
function_name(argument1, argument2,...)
```
For example,
```python
# Define a function that takes two numbers as input
#and returns their sum as output

def add(x,y):
    result = x + y # calculate the sum of x and y return result # return the sum as output
    return result

# Call the add function with 3 and 5 as arguments
sum = add(3,5) # store the returned value in sum variable

print(sum) # prints 8
```
- The name of a function should be descriptive and follow [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guidelines.
- The parameters are local variables that only exist within the scope of the function.
They are assigned with the values passed as arguments when the function is called.
- The return statement ends the execution of a function and returns a value to
the caller. If there is no return statement or if it has no value after it, then the
function returns None by default.
- You can call a function from anywhere within your program, as long as it has been defined before the call is made.

Modules & Packages

A module is a file that contains Python code. It can define variables, functions, classes, and other objects that can be used by other Python programs. For example, the math module contains mathematical functions and constants.

A package is a collection of modules that are organized in a hierarchical structure. A package can contain subpackages (which are also packages) and modules. For example, the numpy package contains many subpackages (such as numpy.linalg for linear algebra) and modules (such as numpy.random for random number generation).

Modules and packages allow you to reuse code written by other developers or yourself. They also help you organize your code into logical units that are easy to maintain and understand.

How to import modules and packages

To use a module or a package in your Python code, you need to import it first. There are different ways to import modules and packages in Python:

You can use the import statement followed by the name of the module or package. For example
```python
import math
import numpy
```
This way of importing allows you to access all the objects defined in the module or package by using the dot notation. For example:
```python
math.sqrt(25) # returns 5.0
numpy.array([1, 2, 3]) # returns an array object
```
You can use the from ... import ... statement followed by the name of the module or package and the name of one or more objects that you want to import. For example:
```python
from math import pi
from numpy import random
```
This way of importing allows you to access only the specified objects without using the dot notation. For example:
```python
random.randint(10) # returns a random integer between 0 and 9
```
You can use the from ... import * statement followed by the name of the module or package to import all the objects defined in it. For example:
```python
from math import *
from numpy import *
```
This way of importing allows you to access all the objects without using the dot notation. However, this is not recommended because it can cause name conflicts with other objects defined in your code or other imported modules or packages.

Popular and useful packages in Python

There are thousands of modules and packages available for Python that cover various domains and functionalities. Here are some examples of popular and useful packages that you should know:

- `requests`: A simple yet powerful package for making HTTP requests to web servers.
- `pandas`: A fast and flexible package for data manipulation and analysis.
- `matplotlib`: A comprehensive package for creating high-quality plots and visualizations.
- `scikit-learn`: A user-friendly package for machine learning algorithms.
- `tensorflow`: A cutting-edge package for deep learning frameworks.
- `flask`: A lightweight yet robust package for web development.

You can find more information about these packages on their official websites or documentation pages.

How to handle Exceptions

The try...except block is used to handle exceptions in Python. Here's the syntax of try...except block:

```python
try:
# code that may cause exception
except:
# code to run when exception occurs

```
The try clause contains the code that may cause an exception. The except clause contains the code that should run when an exception occurs. The except clause can also specify which type of exception it can handle by naming it after the keyword except. For example:
```python
try:
    x = 0
    y = 10 / x
    print(y)
except ZeroDivisionError:
    print("You cannot divide by zero")
```
In this example, we try to get a number from the user input and divide 10 by it. If the user enters zero, this will cause a `ZeroDivisionError` exception. The except clause catches this exception and prints a message instead of crashing the program.

You can have multiple except clauses to handle different types of exceptions differently. For example:
```python
try:
    a = int(input("Enter a number: "))
    b = 0
    c = a / 0
    print(y)
except ZeroDivisionError:
    print("You cannot divide by zero")
except ValueError:
    print("You must enter a valid number")
```
In this example, we added another except clause to handle the `ValueError` exception that may occur if the user enters something other than a number.

If you don't specify any type of exception after the except keyword, it will catch any type of exception that occurs in the try clause. However, this is not recommended as it may hide some unexpected errors or bugs in your code.

How to Raise Your Own Exceptions

Sometimes you may want to raise your own exceptions in your code to indicate some custom error conditions or enforce some constraints on your data or logic. You can do this using the raise keyword followed by an instance of an exception class.
```python
def square_root(x):
if x < 0:
    raise ValueError("Cannot take square root of negative number")
return x ** 0.5

print(square_root(4))
print(square_root(-1))
```
In this example, we defined a function that takes the square root of a number. However, we want to make sure that the input is not negative as this would result in an imaginary number which is not supported by Python's built-in math functions. So we raise a `ValueError` exception if x is negative.

When we call this function with positive numbers (such as 4), it works fine and returns their square roots (such as 2). But when we call it with negative numbers (such as -1), it raises our custom exception which stops our program with an error message.
```python
class NegativeNumberError(ValueError):
    pass

def square_root(x):
    if x < 0:
        raise NegativeNumberError("Cannot take square root of negative number")
    return math.sqrt(x)
```
How to read and write files

Before we can read or write data from/to a file, we need to open it using the `open()` function. The `open()` function takes two arguments: the filename (a string) and the access mode (also a string). The access mode specifies how we want to interact with the file, such as reading only, writing only, appending data, etc.

The `open()` function returns a file object that represents the opened file. We can use this file object to perform various operations on the file. For example, we can use the `read()` method to read all the data from the file as a single string.

Here is an example of opening a file called example.txt for reading only:
```python
# Open the file for reading only
file = open("example.txt", "r")

# Read all the data from the file
data = file.read()

# Print the data
print(data)

# Close the file
file.close()
```
The output might look something like this:
```bash
This is an example text file.
It contains some sample data.
We can read it using Python.
```
Notice that we have used `file.close()` at the end of our code. This is important because it frees up any resources used by the file object and prevents any potential errors or conflicts. It is good practice to always close a file after you are done with it.

Alternatively, we can use a with statement to automatically close a file after exiting its block. The with statement creates a context manager that handles opening and closing of files for us. Here is how we can rewrite our previous code using a with statement:
```python
# Open the file for reading only using a with statement
with open("example.txt", "r") as file:
# Read all the data from the file
data = file.read()

# Print the data
print(data)

# No need to close the file explicitly
```
The output will be identical to before.

Reading and Writing Data

There are several methods available for reading and writing data from/to files in Python. Some of them are:

- `read()`: Reads all or specified number of bytes/characters from a file as a single string.
- `readline()`: Reads one line at a time from a file as a string.
- `readlines()`: Reads all lines from a file as a list of strings.
- `write()`: Writes a given string or bytes object to a file.
- `writelines()`: Writes a list of strings or bytes objects to a file.

Let's see some examples of these methods in action.

Reading Data

To read all or specified number of bytes/characters from a given position in an opened text/binary mode respectively, we can use the read() method. This method returns an empty string if there is no more data to read. For example:
```python
# Open a text file in read mode
f = open("example.txt", "r")

#Read 10 characters from the current position

data = f.read(10) 
print(data)

#Read all remaining characters from the current position

data = f.read() 
print(data)

#Close the file

f.close()
```
The output might look something like this:
```bash
Hello world! This is an example text file.
```
We can also use `readline()` method to read one line at a time from an opened text mode file. This method returns an empty string if there is no more line to read. For example:
```python
#Open a text file in read mode
f = open("example.txt", "r")

# Read one line and print it

line = f.readline() 
print(line)

#Read another line and print it

line = f.readline() 
print(line)

#Close the file

f.close()
```
The output might look something like this:
```bash
Hello world!
This is an example text file.
```
Writing Data

To write data to an opened text/binary mode respectively, we can use write() method. This method returns the number of bytes/characters written to the file. For example:
```python
#Open a text file in write mode (this will overwrite any existing content)

f = open("example.txt", "w")

#Write some data to the file

num_bytes = f.write("This is some new data.\n") 
print(num_bytes)

#Close the file

f.close()
```
The output might look something like this:
```bash
19
```
We can also use `writelines()` method to write multiple lines (a list of strings) to an opened text/binary mode respectively. This method does not add any newline characters between each element in the list, so we need to add them manually if needed. For example:
```python
#Open a text file in append mode (this will add new content at the end)

f = open("example.txt", "a")

#Write some lines to the file (note that we need to add \n for each line)

lines = ["This is another line.\n", "And one more.\n"] num_bytes = f.writelines(lines) print(num_bytes)

#Close the file

f.close()
```
To avoid any errors or resource leaks, it is recommended to use with statement when working with files in Python. The with statement automatically closes the file after exiting its block, so we don't need to call close() method explicitly.

JSONs

JSON is a text-based key-value data format that follows a specific syntax. A JSON value can be one of the following types:

A string: A sequence of characters enclosed in double quotes. For example: "Hello world"

A number: An integer or a floating-point number. For example: 42 or 3.14

A boolean: Either true or false

A null: The literal value null

An array: An ordered collection of zero or more JSON values, enclosed in square brackets and separated by commas. For example: `[1, 2, 3]` or `["red", "green", "blue"]`

An object: An unordered collection of key-value pairs, enclosed in curly braces and separated by commas. Each key must be a string and each value must be a JSON value. For example: `{"name": "Alice", "age": 25}` or `{"scores": [100, 90, 80]}`

A JSON document can contain any valid JSON value as its root element.

How to Read and Write JSONs in Python

Python has a built-in module called json that provides functions for encoding and decoding JSON data. To use it, we need to import it first:
```python
import json

To read a JSON string or file into a Python object (such as a list or a dictionary), we can use the json.loads() function for strings or the json.load() function for files. For example:

# Read a JSON string into a Python object
json_string = '{"name": "Bob", "hobbies": ["reading", "gaming", "coding"]}'
python_object = json.loads(json_string)
print(python_object)
# Output: {'name': 'Bob', 'hobbies': ['reading', 'gaming', 'coding']}

# Read a JSON file into a Python object
with open("data.json") as f:
    python_object = json.load(f)
print(python_object)
# Output: {'name': 'Bob', 'hobbies': ['reading', 'gaming', 'coding']}
```
To write a Python object into a JSON string or file, we can use the json.dumps() function for strings or the json.dump() function for files. For example:
```python
# Write a Python object into a JSON string
python_object = {'name': 'Bob', 'hobbies': ['reading', 'gaming', 'coding']}
json_string = json.dumps(python_object)
print(json_string)
# Output: {"name": "Bob", "hobbies": ["reading", "gaming", "coding"]}

# Write a Python object into a JSON file
with open("data.json", "w") as f:
json.dump(python_object, f)
```
The json module also provides some optional parameters to customize the encoding and decoding process. For example:

- The `indent` parameter can specify the indentation level for pretty-printing the output.
- The `sort_keys` parameter can specify whether to sort the keys of an object alphabetically.
- The `ensure_ascii` parameter can specify whether to escape non-ASCII characters with \uXXXX sequences.

For more details on these parameters and other features of the json module, please refer to the official documentation.

Conclusion

In this article, we have covered the basics of Python programming language and how to use it for various tasks. We have explored the fundamental concepts of variables, data types, operators, expressions, and statements that form the building blocks of any Python program. We have seen how to use control flow tools such as if-else statements, for loops, while loops, and break and continue statements to control the execution of our code based on certain conditions or iterations. We have learned how to use data structures such as lists, tuples, sets, dictionaries to store and manipulate collections of data in an efficient and organized way. We have discussed how to use functions, modules, and packages . We have learned how to handle exceptions and how to read and write files. By following this article, you should be able to write basic Python programs that can solve various problems or perform various tasks.

Congratulations on completing this article! You have acquired a solid foundation of Python programming skills that will help you in your future projects. I hope you enjoyed learning Python with me and I wish you good luck in your coding journey.

-Rohan