Monday, August 2, 2021

Python's ChainMap: Manage Multiple Contexts Effectively

Sometimes when you’re working with several different dictionaries, you need to group and manage them as a single one. In other situations, you can have multiple dictionaries representing different scopes or contexts and need to handle them as a single dictionary that allows you to access the underlying data following a given order or priority. In those cases, you can take advantage of Python’s ChainMap from the collections module.

ChainMap groups multiple dictionaries and mappings in a single, updatable view with dictionary-like behavior. Additionally, ChainMap provides features that allow you to efficiently manage various dictionaries, define key lookup priorities, and more.

In this tutorial, you’ll learn how to:

  • Create ChainMap instances in your Python programs
  • Explore the differences between ChainMap and dict
  • Use ChainMap to work with several dictionaries as one
  • Manage key lookup priorities with ChainMap

To get the most out of this tutorial, you should know the basics of working with dictionaries and lists in Python.

By the end of the journey, you’ll find a few practical examples that will help you better understand the most relevant features and use cases of ChainMap.

Getting Started With Python’s ChainMap

Python’s ChainMap was added to collections in Python 3.3 as a handy tool for managing multiple scopes and contexts. This class allows you to group several dictionaries and other mappings together to make them logically appear and behave as one. It creates a single updatable view that works similar to a regular dictionary but with some internal differences.

ChainMap doesn’t merge its mappings together. Instead, it keeps them in an internal list of mappings. Then ChainMap reimplements common dictionary operations on top of that list. Since the internal list holds references to the original input mapping, any changes in those mappings affect the ChainMap object as a whole.

Storing the input mappings in a list allows you to have duplicate keys in a given chain map. If you perform a key lookup, then ChainMap searches the list of mappings until it finds the first occurrence of the target key. If the key is missing, then you get a KeyError as usual.

Storing the mappings in a list truly shines when you need to manage nested scopes, where each mapping represents a specific scope or context.

To better understand what scopes and contexts are about, think about how Python resolves names. When Python looks for a name, it searches in locals(), globals(), and finally builtins until it finds the first occurrence of the target name. If the name doesn’t exist, then you get a NameError. Dealing with scopes and contexts is the most common kind of problem you can solve with ChainMap.

When you’re working with ChainMap, you can chain several dictionaries with keys that are either disjoint or intersecting.

In the first case, ChainMap allows you to treat all your dictionaries as one. So, you can access the key-value pairs as if you were working with a single dictionary. In the second case, besides managing your dictionaries as one, you can also take advantage of the internal list of mappings to define some sort of access priority for repeated keys across your dictionaries. That’s why ChainMap objects are great for handling multiple contexts.

A curious behavior of ChainMap is that mutations, such as updating, adding, deleting, clearing, and popping keys, act only on the first mapping in the internal list of mappings. Here’s a summary of the main features of ChainMap:

  • Builds an updatable view from several input mappings
  • Provides almost the same interface as a dictionary, but with some extra features
  • Doesn’t merge the input mappings but instead keeps them in an internal public list
  • Sees external changes in the input mappings
  • Can contain repeated keys with different values
  • Searches keys sequentially through the internal list of mappings
  • Throws a KeyError when a key is missing after searching the entire list of mappings
  • Performs mutations only on the first mapping in the internal list

In this tutorial, you’ll learn a lot more about all these cool features of ChainMap. The following section will guide you through how to create new instances of ChainMap in your code.

Instantiating ChainMap

To create ChainMap in your Python code, you first need to import the class from collections and then call it as usual. The class initializer can take zero or more mappings as arguments. With no arguments, it initializes a chain map with an empty dictionary inside:

>>>
>>> from collections import ChainMap
>>> from collections import OrderedDict, defaultdict

>>> # Use no arguments
>>> ChainMap()
ChainMap({})

>>> # Use regular dictionaries
>>> numbers = {"one": 1, "two": 2}
>>> letters = {"a": "A", "b": "B"}

>>> ChainMap(numbers, letters)
ChainMap({'one': 1, 'two': 2}, {'a': 'A', 'b': 'B'})

>>> ChainMap(numbers, {"a": "A", "b": "B"})
ChainMap({'one': 1, 'two': 2}, {'a': 'A', 'b': 'B'})

>>> # Use other mappings
>>> numbers = OrderedDict(one=1, two=2)
>>> letters = defaultdict(str, {"a": "A", "b": "B"})
>>> ChainMap(numbers, letters)
ChainMap(
    OrderedDict([('one', 1), ('two', 2)]),
    defaultdict(<class 'str'>, {'a': 'A', 'b': 'B'})
)

Here, you create several ChainMap objects using different combinations of mappings. In each case, ChainMap returns a single dictionary-like view of all the input mappings. Note that you can use any type of mapping, such as OrderedDict and defaultdict.

You can also create ChainMap objects using the class method .fromkeys(). This method can take an iterable of keys and an optional default value for all the keys:

>>>
>>> from collections import ChainMap

>>> ChainMap.fromkeys(["one", "two","three"])
ChainMap({'one': None, 'two': None, 'three': None})

>>> ChainMap.fromkeys(["one", "two","three"], 0)
ChainMap({'one': 0, 'two': 0, 'three': 0})

If you call .fromkeys() on ChainMap with an iterable of keys as an argument, then you get a chain map with a single dictionary. The keys come from the input iterable, and the values default to None. Optionally, you can pass a second argument to .fromkeys() to provide a sensible default value for every key.

Read the full article at https://realpython.com/python-chainmap/ »


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]



from Real Python
read more

Python for Beginners: How to Open a Non-Text File in Python

The Python standard library provides several tools for reading and writing text files, but what about non-text files? With Python, it’s possible to open non-text files as well. We can do this in a variety of ways.

In most cases, opening non-text files in Python can be done using the standard library. But with the help of some modules, we can take this process much further. 

In this tutorial, we’ll cover several methods for opening text files in Python. Using Python code examples, we’ll explore reading and writing binary files, a process that includes converting ASCII data into bytes.

We’ll also show you how to use the Pillow module, which is used for creating and editing image files. Next, we’ll look at using the Wave module to read audio data. As a treat, we’ve included an example of generating an audio file from scratch with Python.

We’ll also examine how to use the open() function to read .csv files, and compare it to opening non-binary files. If you’re interested in learning how read non-text files in Python, you’ve come to the right place.

What’s the Difference Between a Text File and Non-Text File?

Text files are normally composed of words and numbers. These files have lines of text, usually written in a language people can read (as opposed to machines).

Text files use ASCII (American Standard Code for Information Interchange) characters to represent letters and numbers. Text files often end with the extension .txt, although this isn’t always the case.

Non-text files, on the other hand, are files that contain data other than ASCII text. There are many such files. Usually all that is needed to open a non-text file in Python is the standard library that is distributed with the language. But with the help of a module or two, we can take our Python skills to another level.

Reading and Writing Binary (Non-Text) Files in Python

Binary files—also known as non-text files—are files that contain groups of binary digits (bits). Binary files groups bits into sequences of eight, called a byte. Usually, these bytes represent something other than text data.

With Python, we can read and write binary files using standard functions. For instance, we can use the open() function to create a new binary file. To do so, we’ll need to pass some special characters to the function. This tells the function we want to open the file in both write mode (w) and binary mode (b).

After opening a new file, we can convert a list of numbers into bytes using the bytearray() function. The bytearray() function is used to convert objects into an array of bytes. This binary data can be saved to disk using the write() function.

Example: Writing a Binary File to Disk

f = open("binary_file", 'w+b')
byte_arr = [1,2,3,4]
# convert data to a byte array
binary_format = bytearray(byte_arr)
f.write(binary_format)
f.close()

Likewise, we can open a non-text file in Python using the open() function. When reading binary file types, it’s necessary to pass the characters ‘r’ and ‘b’ to the open() function. This tells the open() function we intend to read the file in binary mode.

Example: Reading a Binary File

file = open("binary_file",'rb')
number = list(file.read())
print("Binary data = ", number)
file.close()

Output

Binary data =  [1, 2, 3, 4]

How to Convert Binary Data to Text

Using standard Python methods, it’s possible to convert text into binary data, and vice versa. With the decode() method, we can convert binary data to ASCII text. Doing so allows us to take a binary message and turn it into something a human could read.

Example: Converting Binary Data in Python

# binary to text
binary_data = b'Hello World.'
text = binary_data.decode('utf-8') # Change back into ASCII
print(text)

# convert text to bytes
binary_message = text.encode('utf-8')
print(type(binary_message))

binary_data = bytes([65, 66, 67])  # ASCII values for the letters A, B, and C
text = binary_data.decode('utf-8')
print(text)

Opening an Image File in Python

It’s possible to open image files using the open() function. By assigning the result to a new variable, we can open an image file. In the following example, we’ll try to print the contents of an image file opened in read mode.

file = open("boat.jpg",'r')
print(file)

Output

<_io.TextIOWrapper name='boat.jpg' mode='r' encoding='cp1252'>

Using Python modules, we can do much more than open image files. With the Pillow module, we can process the image to our liking.

Before you can use the Pillow module, you’ll need to install it. The easiest way to install a Python module is by running pip from the command prompt, or terminal.

Use the following command to install pip.

pip install pillow

With Pillow installed on your computer, you can open and edit photos and other image files. Using Pillow, we can read an image file and print its dimensions to the console.

How to Use the Pillow Module

Before we can use the pillow module, we have to let Python know we want to use it in our program. We do this by importing the module. In the example below, we use from and import to include the Image module from PIL (Pillow).

Example: Open an Image File with PIL

from PIL import Image

img = Image.open("boat.jpg")

#open the original image
size = img.size

print(size)
# opens the image in the default picture viewer
img.show()

Pillow includes modules for editing photos. Using ImageOps—included with Pillow—we can invert a photo and display it using the default photo viewer on your computer.

Example: Invert an Image using PIL

from PIL import Image, ImageOps

img = Image.open("boat.jpg")

#open the original image
size = img.size

print(size)
# invert the image with ImageOps
img = ImageOps.invert(img)
# opens the image in the default picture viewer
img.show()

Opening an Audio File in Python

Python provides tools for reading and creating audio files. Using the Wave module, we can open .wav audio files and inspect their data. In the following example, we’ll open a .wav file named “portal.wav” and print its sample rate to the console.

Example: Open a .wav File with the Wave Module

import wave

audio = wave.open("portal.wav",'r')

print("Sample Rate: ", audio.getframerate())

Output

Sample Rate:  44100

Going a step further, we can  generate our own audio files from scratch using the Wave module. By assigning the frames of the audio a random value, we can generate an audio file of static noise.

Example: Generate an Audio file with the Wave Module

import wave, struct, math, random
# this example will generate an audio file of static noise

sample_rate = 44100.0 # hertz
duration = 1.0 # seconds
frequency = 440.0 # hertz

sound = wave.open("sound.wav",'w')
sound.setnchannels(1) # mono
sound.setsampwidth(2)
sound.setframerate(sample_rate)

for i in range(99999):
    # 32767 is the maximum value for a short integer.
   random_val = random.randint(-32767, 32767)
   data = struct.pack('h', random_val)
   sound.writeframesraw(data)

sound.close()

How to Open a CSV File In Python

Comma Separated Value files —commonly referred to as a CSV file—are convenient ways of storing and exchanging data. These files often contain numbers and/or letters separated by commas. 

Even though CSV files don’t end with the .txt extension, they are considered text files because they contain ASCII characters. Learning how to open CSV files is an useful skill to have as a Python developer.  Use the following examples to compare opening non-text files and text files in Python.

Using the example CSV file below, we’ll explore how to read CSV data using Python.

animal_kingdom.csv

"amphibians","reptiles","birds","mammals"
"salamander","snake","owl","coyote"
"newt","turtle","bald eagle","raccoon"
"tree frog","alligator","penguin","lion"
"toad","komodo dragon","chicken","bear"

Example: Using Open() to read a CSV File

with open("animal_kingdom.csv",'r') as csv_file:
    file = csv_file.read()

    print(file)

Running the code above will print the contents of animal_kingdom.csv to the console. There is, however, a better way to read CSV files in Python.

How to Use the CSV Module

The CSV module comes pre-packed with Python, so there’s no need to install it. Using the CSV module gives us greater control over the contents of the CSV file. For example, we can extract the field data from the file using the reader() function.

Example: Using the csv module to read a csv file in Python

import csv

with open("animal_kingdom.csv",'r') as csv_file:
    csvreader = csv.reader(csv_file)

    # read the field names
    fields = csvreader.__next__()
    print('Field Names\n----------')
    for field in fields:
        print(field)

    print('\nRows\n---------------------')
    for row in csvreader:
        for col in row:
            print(col,end="--")
        print("\n")

Conclusion

We’ve examined a variety of ways of working with non-text files in Python. By converting ASCII text into a byte array, we can create our own binary files. And with the help of the read() function, we can read the binary data and print it to the console.

The Python module Pillow is a great choice for opening and editing image files. If you’re interested in learning more about image processing, the Pillow module is an excellent starting point.

The Wave module is distributed with Python. Use it to read and write Wave data. With a little mathematics, the Wave module can be used to generate a variety of sound effects.

Related Posts

If you’ve found this tutorial helpful, follow the links below to learn more about the exciting world of Python programming.

The post How to Open a Non-Text File in Python appeared first on PythonForBeginners.com.



from Planet Python
via read more

Philippe Normand: Introducing the GNOME Web Canary flavor

Today I am happy to unveil GNOME Web Canary which aims to provide bleeding edge, most likely very unstable builds of Epiphany, depending on daily builds of the WebKitGTK development version. Read on to know more about this.

Until recently the GNOME Web browser was available for end-users in two …



from Planet Python
via read more

EuroPython: EuroPython 2021 Attendee Spam

We got reports of some attendees of EuroPython 2021 that a company is trying to sell personal data of EuroPython attendees, which includes name, email, phone number, physical address, company name and more.

Be assured, our database is not leaked. We have security measures to prevent this.
The leaked data does not come from us.

We do not store people addresses, for instance. The sample data they sent is from publicly available data from our present and past sponsors. Ironically, of the various sample email addresses they sent, only one of them is actually in our database - and this email address is available on his website.

So, it is a scam. We have contacted this company already and asked them to stop. In the meantime we are asking all our attendees to ignore the message and treat it as spam.



from Planet Python
via read more

Programiz: Python Program to Convert Bytes to a String

In this example, you will learn to convert bytes to a string.

from Planet Python
via read more

How to Deal with Files in Google Colab: Everything You Need to Know

Google Colaboratory is a free Jupyter notebook environment that runs on Google’s cloud servers, letting the user leverage backend hardware like GPUs and TPUs. This lets you do everything you can in a Jupyter notebook hosted in your local machine, without requiring the installations and setup for hosting a notebook in your local machine. Colab […]

The post How to Deal with Files in Google Colab: Everything You Need to Know appeared first on neptune.ai.



from Planet SciPy
read more

How to Deal with Files in Google Colab: Everything You Need to Know

Google Colaboratory is a free Jupyter notebook environment that runs on Google’s cloud servers, letting the user leverage backend hardware like GPUs and TPUs. This lets you do everything you can in a Jupyter notebook hosted in your local machine, without requiring the installations and setup for hosting a notebook in your local machine. Colab […]

The post How to Deal with Files in Google Colab: Everything You Need to Know appeared first on neptune.ai.



from Planet SciPy
read more

TestDriven.io: Working with Static and Media Files in Django

This article looks at how to work with static and media files in a Django project, locally and in production. from Planet Python via read...