0% found this document useful (0 votes)
40 views23 pages

EzzeddinAbdullah2022 Cleaner Python

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
40 views23 pages

EzzeddinAbdullah2022 Cleaner Python

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 23

Cleaner Python

5 Ways to Write Efficient


Pythonic Code in Your Next
Project

Ezzeddin Abdullah
Contents
Introduction 3
Who is this ebook for? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
What’s in it for you? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Why writing clean code in Python? . . . . . . . . . . . . . . . . . . . . . . . . 4

Virtual Environment Setup for Python 3 5


Creating a virtual environment using venv . . . . . . . . . . . . . . . . . . . . 5
Creating a virtual environment using conda . . . . . . . . . . . . . . . . . . . 6
Creating aliases for your environment . . . . . . . . . . . . . . . . . . . . . . . 7

Dictionaries in a Useful Use Case 9


A bit of a background on OCP . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Tax calculator example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Refactoring the code to conform to OCP . . . . . . . . . . . . . . . . . . . . . 10

Supercharging Python Classes With Property 13


The @property getter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
The origin of @property decorator . . . . . . . . . . . . . . . . . . . . . . . . 14
The @property setter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

Switch Case Replacements for Python 16


Dictionary as a mapper (for Python < 3.10) . . . . . . . . . . . . . . . . . . . 16
The new Python 3.10+ feature: match-case . . . . . . . . . . . . . . . . . . . 17

Iterators and Generators 19


Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Generators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Iterators use case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

Conclusion 23

2
Introduction
Python is a pretty easy scripting language compared to many programming languages.
Being easy helps you increase your productivity and automate your tasks more quickly.
However, it is still a bit difficult to write clean pythonic code. Let me tell you why this
is difficult.
Rare resources on the internet teaching clean code are written in Python. This is a
problem because we rarely find a code that is pythonic.
Pythonic code is code that is simple, clean, and readable. That is not achieved in many
Python codebases out there. It could be because people translate to Python code. They
translate objected oriented language (like Java or C#) to Python. While, in fact, it will
be easier to write the same example with less code and in a more readable and even
efficient way.
Python has features that you can take advantage of to make the code much cleaner.
Especially because C#, Java, and other object-oriented languages have something in
common. They force you to follow a certain, rigid style that is generally unpythonic in
nature.
This is where this ebook comes in. I’ll show you a better way to use features in Python
to make your code clean.
Disclaimer: This is not a book on how to master clean code in Python. This ebook shows
you 5 ways to make your code cleaner than before.

Who is this ebook for?

This ebook targets people who have little background writing clean code with Python.
For those who want to take that knowledge to the next level.
I’ve designed this ebook to be a practical introduction to clean code in Python. I have
tried to exclude the fluff mentioned in many Python tutorials. And rather focus on the
uncommon stuff that can make your code really clean.
If that triggers you, then this ebook is definitely for you.

What’s in it for you?

In this ebook, I’ll cover the following topics:


1. Using a virtual clean environment
2. Dictionaries in useful use cases
3. Using property decorator in your class
4. Implementing switch statement in Python
5. Iterators and Generators

3
Why writing clean code in Python?

Clean code is code that is helpful for you and other developers in the present and future.
It is a code that is easy to understand and maintain.
Python has a philosophy called The Zen of Python. It is a collection of simple rules that
help you write clear, idiomatic Python code. Code that would be easy to understand and
maintain. It simply prefers simplicity over complexity.
Reading PEP8 documentation will definitely help you write Pythonic code. It is a style
guide for best practices in Python. In this ebook, I’ll discuss some best practices men-
tioned in PEP8.

4
Virtual Environment Setup for Python 3
A virtual environment is a great way to keep your code clean. It is a tool that helps you
isolate your code from the rest of your system (if you’re working locally). It also helps
you to keep your code isolated from other projects (especially when you’re working on
production).
A virtual environment allows you to isolate the dependencies of the project you’re working
on.
You probably have a virtual environment already set up. If not, you probably would
forget how to set up a new one each time you start a new project.
I’ll show you two ways to install Python 3 in a virtual environment.

Creating a virtual environment using venv

venv is a native Python module that provides support for creating lightweight virtual
environments with their own site directories.
Being native makes it easier to use without having to install it.
Now, let’s create a new virtual environment and call it myenv:
$ python3 -m venv myenv

The myenv environment is now created and you can activate it with source command:
$ source myenv/bin/activate

You’ll see now that the prompt changes to (myenv) and you can start working on your
project.
Once you finish your work, you can deactivate the environment with deactivate com-
mand:
$ deactivate

If you want to check which python version you have, you can check with the --version
option:
$ python --version

You can also check all the dependencies you have in your brand new environment. Use
pip list command which outputs the following in my case:
pip (9.0.1)
pkg-resources (0.0.0)
setuptools (39.0.1)
Now, if you’re lazy like me and want to install packages with pip instead of pip3, upgrade
pip with:

5
$ pip install --upgrade pip

To wrap up: When you have virtualenv installed already, use these commands to do
three things. To create a new environment, activate it, and upgrade pip:
python3 -m venv myenv
source myenv/bin/activate
pip install --upgrade pip

Creating a virtual environment using conda

Let’s see a second way to set up your virtual environment. I recommend it if you want to
play around real quick locally. It’s a little bit more complicated to set up the first time
but it’s a lot easier to use and activate moving forward.
Conda serves as two roles. A package manager like pip so you can use it to install
packages and modules. It also serves as an environment manager like venv that you can
use to isolate dependencies. One difference between conda and venv is that you can use
the former to create multiple environments which makes it usable in multiple projects.
Use conda with command-line commands at the Anaconda Prompt for Windows, or in
a terminal window for macOS or Linux.
It comes with some modules that you use frequently for data science projects with Python.
This is good and bad. Good because it removes the hassle of installing dependencies. Bad
because it somehow makes your machine slower.
So you can use a minimal version of conda which is miniconda. A minimal virtual
environment manager that comes with some modules but way fewer than the full version.
Select the miniconda version that suits your system. In my case, I need the Linux version
‘Miniconda3 Linux 64-bit’. So I’ve downloaded the shell script installer file and would run
it:
$ bash Miniconda3-latest-Linux-x86_64.sh

In case you’re using Linux, follow the steps here.


And then, you can create a new Conda environment with:
$ conda create -n py3.9 python=3.9

Note that you’ve now created a new environment called py3.9 which has a Python 3.9
interpreter. It’s activated now and you can start working on your project. You can
deactivate it with conda deactivate.
If you want to activate it, you can do it with conda activate py3.9.
Let’s see what modules we have in our new environment:
$ conda list
# packages in environment at /home/usr/miniconda3/envs/py3.9:
#

6
# Name Version Build Channel
_libgcc_mutex 0.1 main
_openmp_mutex 4.5 1_gnu
ca-certificates 2021.7.5 h06a4308_1
certifi 2021.5.30 py39h06a4308_0
ld_impl_linux-64 2.35.1 h7274673_9
libffi 3.3 he6710b0_2
libgcc-ng 9.3.0 h5101ec6_17
libgomp 9.3.0 h5101ec6_17
libstdcxx-ng 9.3.0 hd4cf53a_17
ncurses 6.2 he6710b0_1
openssl 1.1.1l h7f8727e_0
pip 21.2.4 py37h06a4308_0
python 3.9.7 h12debd9_1
readline 8.1 h27cfd23_0
setuptools 58.0.4 py39h06a4308_0
sqlite 3.36.0 hc218d9a_0
tk 8.6.11 h1ccaba5_0
tzdata 2021a h5d7bf9c_0
wheel 0.37.0 pyhd3eb1b0_1
xz 5.2.5 h7b6447c_0
zlib 1.2.11 h7b6447c_3

So to activate the environment using conda, use:


$ conda activate <your-environment>

No need to upgrade pip, it’s already up to date.

Creating aliases for your environment

If you’re too lazy to type conda activate <your-environment> every time you want
to activate your environment, you can create an alias for it in your .bashrc file (if you’re
using Linux) or bash_profile (if you’re using macOS for a bash shell):
alias cond="conda activate <environment-name>"

where cond is the alias name and <environment-name> is the name of your environment.
Replace both based on your desire.
For the 3 lines of virtualenv, you can alias them as well:
alias vir='python3 -m venv venv; . venv/bin/activate; pip install --upgrade pip'

So whenever you need to set up a new virtual environment, you can just type vir to
create the venv environment and activate it.
Note: This environment is created per subdirectory of your project. So if you’re working
on a project in /home/usr/myproject, you’ll have a virtual environment named venv in
/home/usr/myproject/venv.

7
If you desire to use conda, you can just type cond instead and you’re ready to use the
environment.
Note: The conda alias mentioned above does not create a new environment. It just
activates the environment you set in the alias.

8
Dictionaries in a Useful Use Case
Here, you’ll see how a simple implementation of the Open-Closed Principle (OCP) in
Python.
OCP is a design principle that states that software entities (modules, classes, functions,
etc.) should be open for extension, but closed for modification.
This is the second SOLID design principle (the ‘O’ in SOLID).

A bit of a background on OCP

The open/closed principle was first proposed by Bertrand Meyer. He is the creator of the
Eiffel programming language and the idea of design by contract.
Consider a unit of code “open for extension” when its behavior can be easily changed
without modifying it. The fact that no actual modification is needed to change the
behavior of a unit of code makes it “closed” for modification.
The purpose of this principle is to be able to extend the behavior of an entity without
ever modifying its source code.
This happens when your objects are open to extension (using inheritance). But closed to
alteration (by altering methods or changing values in an object).
Let’s see an example to make it more clear.

Tax calculator example

Suppose you are developing an application that includes a tax calculator.


Users can input their income as a gross salary, deduction subtracted from the gross salary,
and a country of residence. Then the application is expected to return the tax payable
using a mathematical equation.
Of course, this is not what a real tax application would look like but this is a simple
example:
class TaxCalculator:
def calculate(income, deduction, country):
taxable_income = income - deduction
if country == "Egypt":
tax_amount = taxable_income * 0.22 # or insert the tax equation
elif country == "Palestine":
tax_amount = taxable_income * 0.15 # or insert the tax equation
return tax_amount

As we can see, there is a check for the country name to calculate the tax amount for that
particular country.

9
But what’s the problem with this code? The issue here is that the code is not clean
enough to be maintainable for the future.
Assume you want to add many countries to the class. You’ll have to modify the code to
add each country. Each country will have its own tax equation plus a new elif statement
to check the same country variable. Ugly and error-prone. Plus it’s not Pythonic. Let’s
fix this.

Refactoring the code to conform to OCP

To refactor such a code, you need to look at the problem at a higher level. What would
make this code more idiomatic and clean Python code?
Firstly, you have a class that you don’t really need in this case.
Secondly, you have repetitive if statements that check the same variable.
Thirdly, you just have one variable that needs to be changed to reflect the tax rate for
each country.
To solve each problem, do the following:
1. Get rid of the class and make it just one function.
2. Get rid of the repetitive if statements and find a way to replace them with a lookup
table.
3. Create a lookup table relate to the country name and the thing that is changing
(e.g. the tax rate).
lu_tax_rate = {
"Egypt": 0.22,
"Palestine": 0.15,
}

def calculate_tax(country, income, deduction):


rate = lu_tax_rate.get(country)
if rate is not None:
raise ValueError(f"Country {country} is not in our database.")
return (income - deduction) * rate

print(calculate_tax("Egypt", 100000, 1000))

So when you use a lu_tax_rate dictionary as a lookup table, you make your code
Pythonic. Elegant. Idiomatic Python and readable.
Then you use that dictionary to get the tax rate inside the calculate_tax function.
Based on the country argument passed to that function, you will get the associated tax
rate for that country.
Finally, you use the other values passed to the function (income, and deduction) in the
tax equation.

10
Now, the code is much simpler and can be easily refactored. Moreover, it conforms to
OCP:
• open for extension (when we need to extend the functionality and add more coun-
tries)
• and also closed for modification (no actual modification you need to change the
behavior of a unit of code).
That way, when you add a new country, you don’t need to add a new elif statement as
before. You can simply add a new key-value pair to the lookup table as below:
lu_tax_rate = {
"Egypt": 0.22,
"Palestine": 0.15,
"USA": 0.37
}

Note: This can be more complicated than just changing the tax rate. You can replace
the tax rates with a method for each country like the following:
def calculate_tax(country, income, deduction):
tax_amount = lu_tax_amount.get(country, False)
if not tax_amount:
raise ValueError(f"Country {country} is not in our database.")
return tax_amount(income, deduction)

def egypt(income, deduction):


# calculate the exact tax equation for Egypt
print(f"Calculating tax for Egypt.\nIncome: {income}\nDeduction: {deduction}")
pass

def palestine(income, deduction):


# calculate the exact tax equation for Egypt
print(f"Calculating tax for Palestine.\nIncome: {income}\nDeduction: {deduction}"
pass

def usa(income, deduction):


# calculate the exact tax equation for USA
print(f"Calculating tax for USA.\nIncome: {income}\nDeduction: {deduction}")
pass

lu_tax_amount = {
"Egypt": egypt,
"Palestine": palestine,
"USA": usa
}

print(calculate_tax("Egypt", 100000, 1000))

So whenever you need to extend the code. To add a new country with a more complex
tax equation that requires more than changing the tax rate. Consider using a method

11
with the country name (e.g. usa()) and add that method to the lookup table (e.g. "USA":
usa).
At the end of the day, Python has features that are easy to take advantage of. This is
very needed to solve problems especially when you write clean code.
Follow the Zen of Python when you write Python code (i.e. Code that is Pythonic).

12
Supercharging Python Classes With Property
For a long time, I’ve not been able to use classes well enough in Python.
Rare resources on the web could help me write classes that are Pythonic. That’s because
a lot of resources trying to overengineer Python classes.
I used to write methods starting with get_ and set_ to get and set attributes in Python.
This practice was similar to the way Java developers write their getters and setters. Ugly
and not Pythonic.
Until I knew that there is a better way to do this in a Python way.
In this section, I’ll show you how to write @property decorator in Python classes to
be Pythonic. It should be easy to understand and use, especially with a step-by-step
approach.

The @property getter

Let’s first simulate our use case as if @property does not exist.
class Temperature:
def __init__(self, celsius=0):
self._celsius = celsius

def get_fahrenheit(self):
return (self._celsius * 9 / 5) + 32

temperature = Temperature(37)
print(temperature.get_fahrenheit())
# 98.6

In the above example, a class Temperature has a getter method called get_fahrenheit.
It returns the temperature to Fahrenheit.
This is a very typical use case of a getter method.
Now, Fahrenheit looks like a property of a class. You don’t need to call it a function like
the following:
class Temperature:
def __init__(self, celsius=0):
self._celsius = celsius

@property
def fahrenheit(self):
return (self._celsius * 9 / 5) + 32

temperature = Temperature(37)
print(temperature.fahrenheit)
# 98.6

13
We can see that we got rid of the () in the getter method call. Instead, we now have a
@property decorator before fahrenheit function. This function acts as a getter method.
As a side effect, we no longer need to prepend get_ to the function name.
Note that the signature of the getter method needs to be (self).

The origin of @property decorator

In the previous example, we have a property decorator. This is a decorator we use to add
a getter method to a class. We could use the property function instead like this:
class Temperature:
def __init__(self, celsius=0):
self._celsius = celsius

def get_fahrenheit(self):
return (self._celsius * 9 / 5) + 32

fahrenhei = property(fget=get_fahrenheit)

temperature = Temperature(37)
print(temperature.fahrenhei)
# 98.6

but of course, the @property decorator syntax is easier.

The @property setter

But the property is not only useful for that. We can also use it to set and delete the
value of the attribute. Let’s see how we can set a new value for the _celsius attribute:
class Temperature:
def __init__(self, celsius=0):
self._celsius = celsius

@property
def fahrenheit(self):
return (self._celsius * 9 / 5) + 32

@fahrenheit.setter
def fahrenheit(self, value):
if not isinstance(value, int) and not isinstance(value, float):
raise TypeError('Value must be a number.')
self._celsius = (value - 32) * 5 / 9

temp = Temperature(98)
print(temp._celsius)

14
# 98
temp.fahrenheit = 98.6
print(temp._celsius)
# 37.0
# calling the getter
print(temp.fahrenheit)
# 98.6
temp.fahrenheit = "98F"
print(temp._celsius)
# TypeError: Value must be a number.

The property decorator, acting as a setter method, is useful to write clean code especially
when we want to:
• Do validation to the value of the attribute.
• Do some pre-processing. before the setting happens.
In the above example, we validated the value of the _celsius attribute. We then checked
if it’s not an integer nor float, we raise a TypeError.
Now the name of the decorator (before .setter) must be identical to the method name.
In our case, it’s fahrenheit.
Also note that the signature of the setter method needs to be (self, value). The name
of the value is arbitrary.
To conclude, you’ve seen how to write a getter and a setter method in Python classes
using the property decorator; the feature that saves us time and helps write Pythonic
and cleaner code.

15
Switch Case Replacements for Python
Many programming languages have switch-case statements.
In contrast, there are no switch-case statements in Python for versions less than 3.10.
switch is useful especially if you want to return a lot of different values based on a specific
input.
When I first started programming with C, switch statements made sense. After I
switched to Python, I found there was no such thing. I needed to find a workaround
or something to check a single expression against different things.
I first used if statements as a replacement for switch cases. It was ugly and unreadable.
Until I knew there are some other ways to do this to make my code more readable and
efficient as well.
In this section, I will show you how to replace switch statements for new Python 3.10
and older versions.

Dictionary as a mapper (for Python < 3.10)

If you are using a Python version less than 3.10, you can use a dictionary as a mapper.
For example, you can use a dictionary to map numbers to their associated words like the
following:
digits_mapper = {
0: "zero",
1: "one",
2: "two",
3: "three",
4: "four",
5: "five",
6: "six",
7: "seven",
8: "eight",
9: "nine",
}

print(digits_mapper.get(5, "nothing"))
# five

print(digits_mapper.get(10, "not existing"))


# not existing

In the above example, we used the get method. It returns the value associated with the
key. If the key is not in the dictionary, it will return the value specified in the second
argument.

16
Let’s see a more complex example: If you want to calculate taxes based on many countries.
Consider using dictionaries. This time you can define each country’s tax rate calculation
in a separate function. Pass that function to a dictionary like the following:
def egypt(amount):
calculate_tax = amount * 0.05 # or insert the tax equation
return calculate_tax

def palestine(amount):
calculate_tax = amount * 0.02 # or insert the tax equation
return calculate_tax

country_tax_calculate = {
"egypt": egypt,
"palestine": palestine
}

def calculate_tax(country_name, amount):


return country_tax_calculate[country_name](amount)

print(calculate_tax("egypt", 8000))

When you used a country_tax_calculate dictionary, it made your code more elegant.
Readable. And also more efficient.
You used that dictionary in calculate_tax() function passing the country_name key
to it.
Note that the key is a function (e.g. egypt) and the argument passed to it is the amount
value.

The new Python 3.10+ feature: match-case

In 2006 in Python 3.0 version, Guido von Rossum (the creator of Python) rejected a
switch/case statement.
Until in September 2020 (Python 3.10) he and Brandt Bucher (a software engineer at
Microsoft) introduced a structural pattern matching.
This was introduced using a match-case statement; the first-class implementation for a
switch case in Python.
Let’s look at the following snippet in this file match.py:
def f(digit):
match digit:
case 1:
return "one"
case 2:
return "two"
case 3:

17
return "three"
case 4:
return "four"
case 5:
return "five"
case 6:
return "six"
case 7:
return "seven"
case 8:
return "eight"
case 9:
return "nine"
case _:
return "not existing" # the default case when a digit is not found

print(f(5))
# five

print(f(10))
# not existing

Pattern matching is very efficient. In fact, it is more efficient than the workaround in the
previous section.
To test this out, create a Python 3.10 environment and run the following commands with
conda:
$ conda create -n py3.10 python=3.10
$ conda activate py3.10
$ python match.py

In general match-case statement helps in pattern matching.


The case _ statement at the end of the match-case statement is like the default case in
other languages. Use it when the value is not found in the match-case statement. Unlike
switch cases in other languages, match-case doesn’t fall through to the next case if the
value is already found.
For example, in the previous example when we check if 5 existed or not. The matcher
would return five and would not go through the other cases as the usual switch case.
Efficient, isn’t it?
We have discussed alternative ways to do switch statements in Python. We’ve explored
that for Python versions older than 3.10 or 3.10 and above. We’ve seen the dictio-
nary workaround and finally the match-case statement. Both are performant and more
pythonic than the chain of if-elif statements.

18
Iterators and Generators

Iterators

Iterators are objects that can be used to iterate over a sequence of items. It uses the
__next__ method to get the next item in the sequence. When you iterate over that object
through a for loop or list comprehension for example, that __next__ method is called in
the background.
Let’s see how to create an iterator:
class MultiplyByTwo:
def __init__(self, number):
self.number = number
self.count = 0

def __next__(self):
self.count += 1
return self.number * self.count

mul = MultiplyByTwo(2)
print(next(mul)) # 2
print(next(mul)) # 4
print(next(mul)) # 6

The MultiplyByTwo class is an iterator. As you can see, it uses __next__ method. This
specific object uses a counter to keep track of the number of times the __next__ method
is called.
We’ve mentioned that iterators are used in for loops. Let’s see how to iterate over that
object:
mul = MultiplyByTwo(2)

for i in mul:
print(i)
TypeError: 'MultiplyByTwo' object is not iterable

This TypeError indicates that the MultiplyByTwo object being an iterator doesn’t mean
it’s iterable. That’s because it is doesn’t implement the __iter__ method.
What’s an iterable? In Python: strings, lists, files, dictionaries, sets, tuples, and genera-
tors are iterables.
So let’s modify the MultiplyByTwo class to implement the __iter__ method:
class MultiplyByTwo:
def __init__(self, number):
self.number = number
self.count = 0

19
def __iter__(self):
return self

def __next__(self):
self.count += 1
return self.number * self.count

mul = MultiplyByTwo(2)

for i in mul:
print(i)

When you run this loop, it will print out the numbers 2, 4, 6, 8, 10, etc. It’s unstoppable.
If you run this code from the terminal, you need to use Ctrl+C to stop the loop.
You might need that infinite loop for some purposes. But to make this iterable have a
limit, let’s modify the class to the following:
class MultiplyByTwo:
def __init__(self, number, limit=None):
self.number = number
self.limit = limit
self.count = 0

def __iter__(self):
return self

def __next__(self):
self.count += 1
value = self.number * self.count
if value > self.limit:
raise StopIteration
else:
return value

mul = MultiplyByTwo(2, 10)

for i in mul:
print(i)

Now, the loop will stop when it reaches the limit. That’s because it raises the
StopIteration exception when the __next__ method reaches that limit. 10 in this
example. It is automatically handled by Python and exits the loop.

20
Generators

Generators are function-like things that return iterator objects, so you can use them
instead of defining classes. It’s preferred to use generators to generate a large set of data.
You can create generators using the yield keyword.
Python wiki says “Generator functions allow you to declare a function that behaves like
an iterator, i.e. it can be used in a for loop.” and “Python provides generator functions
as a convenient shortcut to building iterators.”
Generators are iterables like lists. But unlike iterables we know, generators are lazy which
means they produce items one at a time.
They are much more memory efficient when dealing with a large data set than any other
data structure.
def multiply_generator(number, limit):
count = 1
value = number * count

while value <= limit:


yield value
count += 1
value = number * count

mul = multiply_generator(2, 4)

for i in mul:
print(i)

yield makes the function a generator. When that generator function is called, it returns
a generator object. When calling next(generator) or generator.__next__() (both
are equivalent), then that execution runs until the first yield yields (or gives) the given
value. Calling next again makes it run until the following yield and so on, until there
is no more yield.
It pauses the execution of the function until it is called again in the next iteration.

Iterators use case

Use iterators when it comes to parsing large data in a file like CSV. Let’s see an example:
import csv

sum_data = 0
csv_data = []
with open("numbers.csv", "r") as f:
data = csv.reader(f)
csv_data.extend((data))

21
for row in csv_data[1:]:
sum_data += sum(map(int, row))

print(sum_data)

In this example you sum up the numbers in the CSV file. Here is a CSV example file:
x,y
12,2,5
2,4,5
4,9,7
So you get the result 50 which is the sum of all the numbers in that file. How did you
do that? we loaded the CSV file at once in memory and then iterated over it. That’s
not the best way to do it, especially when it comes to a large dataset. It’s very memory
intensive when you load the data in memory in one shot.
To fix that, you need to use iterators.
import csv

sum_data = 0
csv_data = []
with open("numbers.csv", "r") as f:
data = csv.reader(f)
for row in list(data)[1:]:
sum_data += sum(map(int, row))

print(sum_data)

So directly you get the data from the CSV file and then sum up the numbers row by row.

22
Conclusion
Writing clean code is an intense subject and this ebook is just scratching the surface.
These are just 5 simple examples of how to make your code cleaner when you write
Python code.
You now know how to use different virtual environments. You can use a dictionary as a
lookup table. You can use the property decorator to make your class properties. You
can use alternatives to the switch statement. You know how and when to use iterators
and generators.
I hope that my code examples are useful to you. If you have any questions, please feel
free to contact me.
Email: [email protected]
and feel free to follow me:
• Blog: https://ezzeddinabdullah.com
• Medium: https://ezzeddinabdullah.medium.com
• LinkedIn: https://linkedin.com/in/ezzeddinabdullah
• Twitter: https://twitter.com/EzzEddinAbdulah

23

You might also like