convert your book to an audiobook

October 26, 2020 Leave a comment

Problem

You need the audiobook version of your favourite book. However, you are on a strict budget and you don’t want to buy the audiobook. You want to make your own audiobook, for free, of course.

Solution

I found this project idea on YouTube, see here. The first 2 minutes were more than enough for me :), but I found the project idea interesting. The source code of the guy is here.

I tried it under Linux and it sounded like a robot. Can we do it better? Of course! I won’t give a complete solution but you can put together your own solution using my previous 2 posts:

Categories: python Tags: ,

text to speech

October 26, 2020 Leave a comment

Problem #1

You have a text and you want to convert it to audio (possibly to .mp3).

Solution #1

The gTTS module can do this for you.

gTTS (Google Text-to-Speech), a Python library and CLI tool to interface with Google Translate’s text-to-speech API. Writes spoken mp3 data to a file, a file-like object (bytestring) for further audio manipulation, or stdout. It features flexible pre-processing and tokenizing, as well as automatic retrieval of supported languages.” (source)

Example:

from gtts import gTTS

TEXT = """
Python is an interpreted, high-level and general-purpose programming
language. Created by Guido van Rossum and first released in 1991, Python's
design philosophy emphasizes code readability with its notable use of
significant whitespace. Its language constructs and object-oriented
approach aim to help programmers write clear, logical code for small
and large-scale projects.
""".replace("\n", " ")


def main():
    tts = gTTS(text=TEXT, lang='en')
    tts.save("audio.mp3")
    print("done")

The text is read by a pleasant female voice in good quality.

The reader takes a little pause at every end of line, that’s why newline characters are replaced by a space. This way the reading is fluid.

Problem #2

There is one little problem. I find the reading speed in audio.mp3 a bit slow. When you watch a YouTube video, there you have the possibility to speed up the audio by 25%, 50%, etc. How to play back audio.mp3 a bit faster?

Solution #2

$ play audio.mp3 tempo 1.15

or

$ mplayer audio.mp3 -speed 1.15 -af scaletempo

It means 15% faster playback.

gTTS from the command-line

If you install the package gtts, you also get a command-line program called gtts-cli. Some examples:

$ gtts-cli --all

^^^ List all languages. At the time of writing, the list contains 78 entries. (Hungarian is also there).

$ gtts-cli 'hello' | play -t mp3 -

^^^ Play the sound directly.

$ gtts-cli "bonjour tout le monde" --lang fr | play -t mp3 -

^^^ Specify the language of the text.

$ gtts-cli "c'est la vie" --lang fr --output cestlavie.mp3

^^^ Save the sound in an .mp3 file.

Links

Notes

I also tried the pyttsx library under Linux but the quality was terrible. It calls the command espeak and it reads the text like a f* robot. No, thanks. Maybe it sounds better under Windows (under Windows there is a different text to speech engine); I didn’t try that.

Categories: python Tags: , , ,

extract text from a PDF file

October 26, 2020 Leave a comment

Problem

You have a PDF file and you want to extract text from it.

Solution

You can use the PyPDF2 module for this purpose.

import PyPDF2

def main():
    book = open('book.pdf', 'rb')
    pdfReader = PyPDF2.PdfFileReader(book)
    pages = pdfReader.numPages
    page = pdfReader.getPage(0)    # 1st page
    text = page.extractText()
    print(text)

Note that indexing starts at 0. So if you open your PDF with Adobe Reader for instance and you locate page 20, in the source code you must use getPage(19).

Links

Exercise

Write a program that extracts all pages of a PDF and saves the content of the pages to separate files, e.g. page0.txt, page1.txt, etc.

Categories: python Tags: , , ,

Python Developer’s Guide

September 15, 2020 Leave a comment

If you want to contribute to the Python language, start here: https://devguide.python.org .

Categories: python

Python 3.9 is coming

September 15, 2020 Leave a comment

See this post to have an idea of the new features of Python 3.9: https://ayushi7rawat.hashnode.dev/python-39-all-you-need-to-know .

More details here: https://docs.python.org/3.9/whatsnew/3.9.html .

Categories: python Tags:

extract all images from a 4chan thread

July 16, 2020 Leave a comment

If you are a 4chan user, then this little project of mine can be useful for you: https://github.com/jabbalaci/4chan-Thread-Images . It can extract all the images from a 4chan thread. It uses the official API of 4chan, it doesn’t do any webscraping.

Categories: python Tags: ,

angle between two lines

December 10, 2019 Leave a comment

Problem
You have two lines. What is the angle between them?

Or, you have 3 points, say A, B and C. If you go from A to B (vector 1), then from B to C (vector 2), then what is the angle at point B between the two vectors?

Solution
There is a nice blog post about it here: Find the Angle between three points from 2D using python.

Here is a Python code that is based on the one that you can find in the aforementioned blog post:

import math
from typing import NamedTuple

class Point(NamedTuple):
    x: int
    y: int

def angle(a: Point, b: Point, c: Point) -> float:
    ang = math.degrees(math.atan2(c[1]-b[1], c[0]-b[0]) - math.atan2(a[1]-b[1], a[0]-b[0]))
    return ang + 360 if ang < 0 else ang
Categories: python Tags: , , , , ,

monitoring key presses in a console application in a thread

November 16, 2019 Leave a comment

Problem
I wrote a console application that shows a table and updates the screen every second. Later, I wanted to add a table sorting functionality. For instance, if you press ‘b’, then the table is sorted by the 2nd column, pressing ‘c’ would sort the table by the 3rd column, etc.

I found some keyboard monitoring libraries but they were all blocking, i.e. you had to call a function which was waiting for a key press. If you didn’t press any key, this function was just waiting.

However, in my program I had an infinite loop that was doing the following steps: (1) clear the screen, (2) draw the table, (3) repeat. If I add anywhere the keyboard monitoring, the loop gets blocked somewhere.

Solution
I asked this question on reddit (see here), and /u/Viddog4 suggested that I should use a thread. Of course! I have the main loop that draws the table, and I have a thread in the background that monitors the keyboard.

Here is a simplified code that demonstrates the idea:

#!/usr/bin/env python3

"""
pip3 install pynput xlib
"""

import threading
from time import sleep

from pynput.keyboard import Key, Listener


class myThread(threading.Thread):
    def __init__(self, _id, name):
        super().__init__()
        self.daemon = True    # daemon threads are killed as soon as the main program exits
        self._id = _id
        self.name = name

    def on_press(self, key):
        print('{0} pressed'.format(key))

    def on_release(self, key):
        print('{0} release'.format(key))
        if key == Key.esc:
            # Stop listener
            return False

    def run(self):
        with Listener(on_press=self.on_press, on_release=self.on_release) as listener:
            listener.join()


def main():
    thread1 = myThread(1, "thread_1")
    thread1.start()
    # main loop:
    while True:
        print(".", flush=True)
        try:
            sleep(1)
        except KeyboardInterrupt:
            break

##########

if __name__ == "__main__":
    main()

You can stop the thread with Esc. You can terminate the whole program with Ctrl+C. The thread is registered as a daemon thread, which means that if the main program exits (e.g. you press Ctrl+C), then daemon threads are automatically stopped.

Links

Categories: python Tags: , , ,

simple keylogger

November 16, 2019 Leave a comment

I was working on a console application and I wanted to add the functionality to listen to keyboard presses in an infinite loop. I used the pynput library and tried this basic code that I found on the project’s web site:

# pip3 install pynput xlib
# xlib is required for mouse support

from pynput.keyboard import Key, Listener

def on_press(key):
    print("{0} pressed".format(key))

def on_release(key):
    print("{0} release".format(key))
    if key == Key.esc:
        # Stop listener
        return False

# Collect events until released
with Listener(on_press=on_press, on_release=on_release) as listener:
    listener.join()

It worked well. I let it run and switched to another window when I noticed that the script was still monitoring what keys I press, though I was in another window! So it monitors the keyboard globally. And, under Linux, I didn’t even have to start it with sudo.

So, if you need a simple keylogger, here it is :) You don’t need to add much to the code above to have a working keylogger.

Update (20240204):

Here is a slightly longer example:

from pynput.keyboard import Key, Listener

def on_press(key):
    print("{0} pressed".format(key))
    if key == Key.esc:
        print("# you pressed ESC")
    try:
        if key.char == "a":
            print("# you pressed 'a'")
        #
    except:
        pass

def on_release(key):
    print("{0} release".format(key))
    print("---")

def main():
    print("keylogger running...")
    with Listener(on_press=on_press, on_release=on_release) as listener:
        try:
            listener.join()
        except KeyboardInterrupt:
            print()

if __name__ == "__main__":
    main()
Categories: python Tags: , ,

flush the stdin

November 16, 2019 Leave a comment

Problem
I wrote a terminal application that was reading key presses from the keyboard using the pynput library. When the program terminated, it printed on the screen the keys that I pressed while the program was running. How to get rid of this side effect?

Solution
First I tried sys.stdin.flush() but it didn’t help. However, the following worked:

import sys
import termios

termios.tcflush(sys.stdin, termios.TCIOFLUSH)

Calling this line before quitting successfully flushed the standard input.

Categories: python Tags: , , ,