Back to more coding! Here are 4 Python modules I have been using more recently for building solutions to actual problems.
1. ipaddress
This module, included in Python 3, helps you represent and manipulate IP addresses.
You can get the IP address representation using the ip_address
class:
>>> from ipaddress import ip_address
>>> addr = ip_address('192.10.2.1')
>>> addr
IPv4Address('192.10.2.1')
You can know the version of a given IP address:
>>> addr1 = ip_address('192.10.2.1')
>>> addr2 = ip_address('1901:db8::1')
>>> addr1.version
4
>>> addr2.version
6
>>>
The full introduction available here will help you easily get started.
One thing I needed to know is find the IP addresses that are part of an IP range, when I am given the start and end IPs of the range. I quickly found the following solution on StackOverflow.
from ipaddress import ip_address
def findIPs(start, end):
start = ip_address(start)
end = ip_address(end)
result = []
addr = start
while addr <= end:
result.append(str(addr))
addr += 1
return result
print(findIPs('192.101.172.100', '192.101.173.100'))
2. Furl
Furl is a nice third-party module that can help extract data from complex URLs that have a query string for example. So you don't have to do it yourself.
First, install it using:
pip install furl
Furl is handy if you need to get the path part of a URL or extract data from the query string part. It will you productive if you have to build logic that heavily depends on parsing URLs.
from Furl import furl
URL = 'https://somesite.com/one/two/three/four/?alpha=1&beta=2&teta=3'
f = furl(URL)
the_path = f.path
print(the_path)
the_args = f.args
print(the_args)
Note that using the .args
attribute on the furl
object, you get a Python dictionary containing the data.
And you can change the arguments in the URL, if needed by your use case:
URL = 'https://somesite.com/one/two/three/four/?alpha=1&beta=2&teta=3'
f = furl(URL)
f.args['beta'] = '1bis'
del f.args['teta']
print(f.url)
In this example, the URL has been transformed into: https://somesite.com/one/two/three/four/?alpha=1&beta=1bis
3. Faker
To get better at handling data, we need good example data to play with. It also helps when testing the behavior of a script or app you are developing.
That is where Faker comes in.
First, install it using:
pip install faker
You can generate a list of random people names using this code:
from faker import Faker
fake = Faker()
for _ in range(0, 20):
p = {'firstname': fake.last_name(), 'lastname': fake.last_name()}
print(p)
An example output from running this code would be:
{'firstname': 'Porter', 'lastname': 'Hayes'}
{'firstname': 'Horn', 'lastname': 'Kelley'}
{'firstname': 'Harrington', 'lastname': 'Anderson'}
{'firstname': 'Briggs', 'lastname': 'Reyes'}
{'firstname': 'Stanton', 'lastname': 'Gordon'}
{'firstname': 'Cummings', 'lastname': 'Davis'}
{'firstname': 'York', 'lastname': 'Lane'}
{'firstname': 'Williams', 'lastname': 'Barnes'}
{'firstname': 'Moore', 'lastname': 'Hensley'}
{'firstname': 'Riley', 'lastname': 'Marshall'}
{'firstname': 'Gray', 'lastname': 'Chambers'}
{'firstname': 'Lyons', 'lastname': 'Hunter'}
{'firstname': 'Hayes', 'lastname': 'Miller'}
{'firstname': 'Davis', 'lastname': 'Singh'}
{'firstname': 'Sexton', 'lastname': 'Miller'}
{'firstname': 'Jacobson', 'lastname': 'Matthews'}
{'firstname': 'Pugh', 'lastname': 'Torres'}
{'firstname': 'Patrick', 'lastname': 'Wyatt'}
{'firstname': 'Mclean', 'lastname': 'Carter'}
{'firstname': 'Gonzalez', 'lastname': 'Gonzales'}
There is also a so-called "Faker provider" for user profiles, credit card information, or even browser User Agents.
4. csv
Here are examples showing how I read and write CSV data nowadays.
To read data from the 'example.csv' file:
import csv
with open('example.csv', newline='') as csv_file:
reader = csv.reader(csv_file, delimiter=';')
for row in reader:
print(row)
Now, let's use Faker to generate data and write it to disk in append mode:
import csv
from faker import Faker
fake = Faker()
data = []
for _ in range(0, 20):
p = {'firstname': fake.last_name(), 'lastname': fake.last_name()}
data.append(p)
with open('example.csv', "a", newline='') as csv_file:
fieldnames = ['firstname', 'lastname']
writer = csv.DictWriter(csv_file, fieldnames=fieldnames, delimiter=';')
for item in data:
writer.writerow(item)
In situations where I want to detect if an existing CSV file has headers, there is the csv.Sniffer
trick:
import csv
import os
csv_has_header = False
# If the CSV file already exists, read a sample to verify header
if os.path.isfile('example.csv'):
with open('example.csv', newline='') as csv_file:
sniffer = csv.Sniffer()
csv_has_header = sniffer.has_header(csv_file.read(2048))
print('CSV has header?', csv_has_header)
So here is the consolidated code where you detect the headers before appending data to the file:
import csv
import os
from faker import Faker
fake = Faker()
csv_has_header = False
# If the CSV file already exists, read a sample to verify header
if os.path.isfile('example.csv'):
with open('example.csv', newline='') as csv_file:
sniffer = csv.Sniffer()
csv_has_header = sniffer.has_header(csv_file.read(2048))
data = []
for _ in range(0, 20):
p = {'firstname': fake.last_name(), 'lastname': fake.last_name()}
data.append(p)
with open('example.csv', "a", newline='') as csv_file:
fieldnames = ['firstname', 'lastname']
writer = csv.DictWriter(csv_file, fieldnames=fieldnames, delimiter=';')
if not csv_has_header:
writer.writeheader()
# Now append the data
for item in data:
writer.writerow(item)