Python

How to fix Matplotlib ‘ AttributeError: module matplotlib.pyplot’ has no attribute ‘yrange’

Problem:

You are trying to set the range of the Y axis of a matplotlib plot using code like

plt.yrange([0.0, 10.0])

but you see an error message like this:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-3-aa38a78ab5d7> in <module>
     12 plt.xscale('log')
     13 plt.grid(True, which="both")
---> 14 plt.yrange([0.0, 70.])
     15

AttributeError: module 'matplotlib.pyplot' has no attribute 'yrange'

Solution:

You need to use ylim since yrange does not exist! The equivalent call is:

plt.ylim([0.0, 10.0])

 

Posted by Uli Köhler in Python

How to write BytesIO content to file in Python

In order to write the contents of a BytesIO instance to a file, use this snippet:

with open("out.txt", "wb") as outfile:
    # Copy the BytesIO stream to the output file
    outfile.write(myio.getbuffer())

Note that getbuffer() will not create a copy of the values in the BytesIO buffer and will hence not consume large amounts of memory.

You can also use this function:

def write_bytesio_to_file(filename, bytesio):
    """
    Write the contents of the given BytesIO to a file.
    Creates the file or overwrites the file if it does
    not exist yet. 
    """
    with open(filename, "wb") as outfile:
        # Copy the BytesIO stream to the output file
        outfile.write(bytesio.getbuffer())

Full example:

#!/usr/bin/env python3
from io import BytesIO
import shutil

# Initialie our BytesIO
myio = BytesIO()
myio.write(b"Test 123")

def write_bytesio_to_file(filename, bytesio):
    """
    Write the contents of the given BytesIO to a file.
    Creates the file or overwrites the file if it does
    not exist yet. 
    """
    with open(filename, "wb") as outfile:
        # Copy the BytesIO stream to the output file
        outfile.write(bytesio.getbuffer())

write_bytesio_to_file("out.txt", myio)

 

Posted by Uli Köhler in Python

How to get binary data from Python’s ByteIO

Use the getvalue() function of the BytesIO instance. Example:

#!/usr/bin/env python3
from io import BytesIO

myio = BytesIO()
myio.write(b"Test 123")

print(myio.getvalue()) # Prints b'Test 123'

 

Posted by Uli Köhler in Python

How to install picamraw using pip

First try installing it normally:

sudo pip3 install picamraw

In case that fails with this error message (like for me):

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting picamraw
Could not install packages due to an EnvironmentError: 404 Client Error: Not Found for url: https://www.piwheels.org/simple/picamraw/

download it and install it manually: Copy the link of the most recent .whl file from https://pypi.org/project/picamraw/#files, download it using wget and install it using pip3, e.g.:

wget https://files.pythonhosted.org/packages/1e/47/4efb0d0ab5d40142424e7f3db545e276733a45bd7f7f9095919ef30c96b3/picamraw-1.2.64-py3-none-any.whl
sudo pip3 install picamraw-1.2.64-py3-none-any.whl

 

Posted by Uli Köhler in Python, Raspberry Pi

How to capture Raspi Camera image using OpenCV & Python

First, install OpenCV for Python 3:

sudo apt install python3-opencv

Here’s the code to acquire the image and store it in image.png:

#!/usr/bin/env python3
import cv2
video_capture = cv2.VideoCapture(0)
# Check success
if not video_capture.isOpened():
    raise Exception("Could not open video device")
# Read picture. ret === True on success
ret, frame = video_capture.read()

cv2.imwrite('image.png', frame)
# Close device
video_capture.release()

Run it using

python3 cv-raspicapture.py

 

Posted by Uli Köhler in OpenCV, Python, Raspberry Pi

How to add a "Press enter to close this window" message to your Python script

Just add this line at the bottom of your Python script:

input("Press Enter to close this window...")

Python 2 variant:

raw_input("Press Enter to close this window...")

 

Posted by Uli Köhler in Python

How to check if your filesystem is mounted in noatime, relatime or strictatime mode

If you need to use a software that depends on your filesystem storing the last access time of a file (atime), you can use this script to check if your filesystem is mounted in noatime, strictatime or relatime mode.

This script works on both Linux and Windows.

On Linux, you can simply run this

wget -qO- https://techoverflow.net/scripts/check-atime.py | python3

Python 2 version (pythonclock.org !)

wget -qO- https://techoverflow.net/scripts/check-atime.py | python

Note that the script will check for the atime mode in whichever directory you run the script in.

On Windows, download the script and directly open it using Python. In case you don’t have Python installed, install it from the Microsoft store or download it here before downloading the script.

In case you need to check the atime mode of a specific drive (C:, D:, …), download, the script, place it in that directory and run it from there.

This script will print one of three messages:

  • Your filesystem is mounted in NOATIME mode – access times will NEVER be updated automatically
  • Your filesystem is mounted in RELATIME mode – access times will only be updated if they are too old
  • Your filesystem is mounted in STRICTATIME mode – access times will be updated on EVERY file access

On Linux, the default is relatime whereas on Windows the default is strictatime.

Sourcecode of the script:

#!/usr/bin/env python3
"""
This utility script checks which atime mode (strictatime, relatime or noatime)
is in use for the current filesystem
"""
import os
import time
from datetime import datetime

def datetime_to_timestamp(dt):
    return time.mktime(dt.timetuple()) + dt.microsecond/1e6

def set_file_access_time(filename, atime):
    """
    Set the access time of a given filename to the given atime.
    atime must be a datetime object.
    """
    stat = os.stat(filename)
    mtime = stat.st_mtime
    os.utime(filename, (datetime_to_timestamp(atime), mtime))


def last_file_access_time(filename):
    """
    Get a datetime() representing the last access time of the given file.
    The returned datetime object is in local time
    """
    return datetime.fromtimestamp(os.stat(filename).st_atime)

try:
    # Create test file
    with open("test.txt", "w") as outfile:
        outfile.write("test!")
    time.sleep(0.1)
    # Read & get first atime
    with open("test.txt") as infile:
        infile.read()
    atime1 = last_file_access_time("test.txt")
    # Now read file
    time.sleep(0.1)
    with open("test.txt") as infile:
        infile.read()
    # Different atime after read?
    atime2 = last_file_access_time("test.txt")
    # Set OLD atime for relatime check!
    set_file_access_time("test.txt", datetime(2000, 1, 1, 0, 0, 0))
    # Access again
    with open("test.txt") as infile:
        infile.read()
    # Different atime now
    atime3 = last_file_access_time("test.txt")
    # Check atime
    changed_after_simple_access = atime2 > atime1
    changed_after_old_atime = atime3 > atime1
    # Convert mode to text and print
    if (not changed_after_simple_access) and (not changed_after_old_atime):
        print("Your filesystem is mounted in NOATIME mode - access times will NEVER be updated automatically")
    elif (not changed_after_simple_access) and changed_after_old_atime:
        print("Your filesystem is mounted in RELATIME mode - access times will only be updated if they are too old")
    elif changed_after_simple_access and (not changed_after_old_atime):
        print("Unable to determine your access time mode")
    else: # Both updated
        print("Your filesystem is mounted in STRICTATIME mode - access times will be updated on EVERY file access")
finally:
    # Delete our test file
    try:
        os.remove("test.txt")
    except:
        pass

Also available on GitHub.

Posted by Uli Köhler in Linux, Python, Windows

How to fix Python “TypeError: utime() takes no keyword arguments”

Problem:

You are trying to set file access/modification dates using os.utime() like this:

os.utime(filename, times=(myatime, mymtime))

but you see an error message like this:

Traceback (most recent call last):
  File "utime.py", line 6, in <module>
    os.utime("myfile.txt", times=(myatime, mymtime))
TypeError: utime() takes no keyword arguments

Solution:

Using os.utime(..., times=(...)) is Python 3 syntax, so use Python 3 if you can!

In case you still need to use Python 2.x, just remove times= from the source code:

os.utime(filename, (myatime, mymtime))

This code will work fine with both Python 2 and Python 3.

Note that Python 2 retirement is just a few months away at the time of writing this post!

Posted by Uli Köhler in Python

How to convert datetime to time float (unix timestamp) in Python 2

Use this snippet to convert a datetime.datetime object into a float (like the one time.time() returns) in Python 2.x:

from datetime import datetime
import time

dt = datetime.now()
timestamp = time.mktime(dt.timetuple()) + dt.microsecond/1e6

After running this, timestamp will be 1563812373.1795 for example.

or use this function:

from datetime import datetime
import time

def datetime_to_timestamp(dt):
    return time.mktime(dt.timetuple()) + dt.microsecond/1e6

In Python 3, you can simply use

dt.timestamp()

but that is not supported in Python 2.

Posted by Uli Köhler in Python

How to fix Python error “AttributeError: ‘datetime.datetime’ object has no attribute ‘timestamp'”

Problem:

You want to convert a datetime object into a unix timestamp (int or float: seconds since 1970-1-1 00:00:00) in Python using code like

from datetime import datetime
timestamp = datetime.now().timestamp()

but you see an error message like this:

Traceback (most recent call last):
  File "unix-timestamp.py", line 2, in <module>
    timestamp = datetime.now().timestamp()
AttributeError: 'datetime.datetime' object has no attribute 'timestamp'

Solution:

You are running your code with Python 2.x which does not support datetime.timestamp() – in most cases the easiest way to fix this issue is to use Python 3, e.g.:

python3 unix-timestamp.py

In case that is not possible e.g. due to incompatibilities, use this snippet instead, which is compatible with both Python 2 and Python 3:

from datetime import datetime
import time

dt = datetime.now()
timestamp = time.mktime(dt.timetuple()) + dt.microsecond/1e6

 

Posted by Uli Köhler in Python

How to set file modification time (mtime) in Python

Also see: How to set file access time (atime) in Python

You can use os.utime() to set the access and modification times of files in Python. In order to set just the access time (mtime) use this snippet:

# mtime must be a datetime
stat = os.stat(filename)
# times must have two floats (unix timestamps): (atime, mtime)
os.utime(filename, times=(stat.st_atime, mtime.timestamp()))

Or use this utility function:

from datetime import datetime
import os

def set_file_modification_time(filename, mtime):
    """
    Set the modification time of a given filename to the given mtime.
    mtime must be a datetime object.
    """
    stat = os.stat(filename)
    atime = stat.st_atime
    os.utime(filename, times=(atime, mtime.timestamp()))

Usage example:

# Set the modification time of myfile.txt to 1980-1-1, leave the acess time intact
set_file_modification_time("myfile.txt", datetime(1980, 1, 1, 0, 0, 0))

In case you need to compatible with Python 2.x, use this variant instead:

from datetime import datetime
import os
import time

def datetime_to_timestamp(dt):
    return time.mktime(dt.timetuple()) + dt.microsecond/1e6

def set_file_modification_time(filename, mtime):
    """
    Set the modification time of a given filename to the given mtime.
    mtime must be a datetime object.
    """
    stat = os.stat(filename)
    atime = stat.st_atime
    os.utime(filename, (atime, datetime_to_timestamp(mtime)))

See How to convert datetime to time float (unix timestamp) in Python 2 and How to fix Python error AttributeError: datetime.datetime object has no attribute timestamp for more details on this alternate approach.

In case you have any option of using Python 3.x, I recommend using the Python 3 version listed above, since it’s much more readable, involves less code and (at the time of writing this code), Python 2 will be retired in only a couple of months. I recommend upgrading your scripts with Python 3 compatibility as soon as possible as many other projects have already done.

Posted by Uli Köhler in Python

How to set file access time (atime) in Python

Also see: How to set file modification time (mtime) in Python

You can use os.utime() to set the access and modification times of files in Python. In order to set just the access time (atime) use this snippet:

# atime must be a datetime
stat = os.stat(filename)
# times must have two floats (unix timestamps): (atime, mtime)
os.utime(filename, times=(atime.timestamp(), stat.st_mtime))

Or use this utility function:

from datetime import datetime
import os

def set_file_access_time(filename, atime):
    """
    Set the access time of a given filename to the given atime.
    atime must be a datetime object.
    """
    stat = os.stat(filename)
    mtime = stat.st_mtime
    os.utime(filename, times=(atime.timestamp(), mtime))

Usage example:

# Set the access time of myfile.txt to 1970-1-1, leave the modification time intact
set_file_access_time("myfile.txt", datetime(1970, 1, 1, 0, 0, 0))

In case you need to compatible with Python 2.x, use this variant instead:

from datetime import datetime
import os
import time

def datetime_to_timestamp(dt):
    return time.mktime(dt.timetuple()) + dt.microsecond/1e6

def set_file_access_time(filename, atime):
    """
    Set the access time of a given filename to the given atime.
    atime must be a datetime object.
    """
    stat = os.stat(filename)
    mtime = stat.st_mtime
    os.utime(filename, (datetime_to_timestamp(atime), mtime))

See How to convert datetime to time float (unix timestamp) in Python 2 and How to fix Python error AttributeError: datetime.datetime object has no attribute timestamp for more details on this alternate approach.

In case you have any option of using Python 3.x, I recommend using the Python 3 version listed above, since it’s much more readable, involves less code and (at the time of writing this code), Python 2 will be retired in only a couple of months. I recommend upgrading your scripts with Python 3 compatibility as soon as possible as many other projects have already done.

Posted by Uli Köhler in Python

How to get last file access time (atime) in Python

To get the last access time of myfile.txt in Python, use

import os
from datetime import datetime

datetime.fromtimestamp(os.stat("myfile.txt").st_atime)

You can also use this utility function:

import os
from datetime import datetime

def last_file_access_time(filename):
    """
    Get a datetime() representing the last access time of the given file.
    The returned datetime object is in local time
    """
    return datetime.fromtimestamp(os.stat(filename).st_atime)

Note that os.stat("myfile.txt").st_atime returns a Unix timestamp like 1563738878.1278138 (seconds passed since 1970-1-1 00:00:00). This timestamp and the resulting datetime we convert it to is in local time.

Remember that if the user has disabled access times on their filesystem (e.g. to save writes on a SSD), you have no way of finding out the last access date.

Posted by Uli Köhler in Python

How to fix Python enum ‘TypeError: Error when calling the metaclass bases: module.__init__() takes at most 2 arguments (3 given)’

Problem:

You want to inherit a Python class from enum like this:

import enum

class MyEnum(enum):
    X = 1
    Y = 2class

but when you try to run it, you see an error message like this:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    class MyEnum(enum):
TypeError: Error when calling the metaclass bases
    module.__init__() takes at most 2 arguments (3 given)

Solution:

You are not trying to inherit from the Enum class (capital E!) but from the enum module!

This is the correct syntax:

from enum import Enum
class MyEnum(Enum):
    X = 1
    Y = 2

 

Posted by Uli Köhler in Python

How to fix Python class ‘NameError: name ‘enum’ is not defined’

Problem:

You are trying to inherit a class from enum in Python:

class MyEnum(enum):
    X = 1
    Y = 2

But when you try to run it, you see this error message:

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-15-ebcfa41a8a7c> in <module>
----> 1 class MyEnum(enum):
      2     X = 1
      3     Y = 2

NameError: name 'enum' is not defined

Solution:

You need to inherit from Enum (capital E!), not from enum! The correct syntax is

from enum import Enum

class MyEnum(Enum):
    X = 1
    Y = 2

 

Posted by Uli Köhler in Python

How to fix Python ‘ImportError: No module named enum’

Problem:

You have code like this in Python:

from enum import Enum

But when you try to run it, you encounter this error:

Traceback (most recent call last):
  File "test.py", line 1, in <module>
    from enum import Enum
ImportError: No module named enum

Solution:

The enum module is only available in Python 3! You are trying to use it in Python 2.

Try running your code with Python3 (e.g. python3 myscript.py). In case that’s not possible since your project or a library is not compatible with Python 3, you can install enum34 which provides the enum package for Python 2:

sudo pip install enum34

 

Posted by Uli Köhler in Python

How to fix Python ImportError: cannot import name ‘enum’

Problem:

You have a line like this in your Python code:

from enum import Enum

But when you try to run it, you see this error message:

Traceback (most recent call last):
  File "test.py", line 1, in <module>
    from enum import Enum
ImportError: No module named enum

Solution:

The enum module is only available in Python 3, but you are using Python 2!

You can try to run your script using Python 3. In case that’s not possible (because your project or a library is not compatible with Python 3), you can install the enum34 backport

sudo pip install enum34

After installing this, the ImportError should disappear.

Posted by Uli Köhler in Python

How to create temporary directory in Python

Note: This example shows how to create a temporary directory that is not automatically deleted. Check out How to create a self-deleting temporary directory in Python for an example on how to create a self-deleting temporary directory!

Minimal example:

import tempfile
tempdir = tempfile.mkdtemp()
print(tempdir) # prints e.g. /tmp/tmpvw0936nd

tempfile.mkdtemp() will automatically create that directory. The directory will not automatically be deleted!

Custom prefix (recommended):

import tempfile
tempdir = tempfile.mkdtemp(prefix="myapplication-")
print(tempdir) # prints e.g. /tmp/myapplication-ztcy6s2w

How to delete the directory

In order to delete the temporary directory including all the files in that directory, use

import shutil
shutil.rmtree(tempdir)
Posted by Uli Köhler in Python

How to disable InsecureRequestWarning: Unverified HTTPS request is being made.

If you use requests or urllib3, requests with SSL verification disabled will print this warning:

/usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py:851: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)

If you want to disable this warning and you can’t just enable verification, add this code

import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

at the top of your Python file.

Posted by Uli Köhler in Python

Python subprocess.check_output(): Set working directory

If you have code that uses subprocess.check_output() to call a command like

subprocess.check_output("ls .", shell=True)

you can use the cwd=... argument of subprocess.check_output() to define the working directory. Example:

subprocess.check_output("ls .", cwd="../", shell=True)

cwd means change working directory and is interpreted relative to the current working directory. However, you can also use absolute paths:

subprocess.check_output("ls .", cwd="/etc/", shell=True)

 

Posted by Uli Köhler in Python