Архив метки: Python

wxPython пример рабочего окна с кнопкой

# -*- coding: utf-8 -*-
"""
# Самый простой пример окна.

# Отсюда: https://wiki.wxpython.org/Getting%20Started

import wx

# Create a new app, don't redirect stdout/stderr to a window.
app = wx.App(False)
# A Frame is a top-level window.
frame = wx.Frame(None, wx.ID_ANY, "Hello World")
frame.Show(True)     # Show the frame.
app.MainLoop()
"""

import wx


class MyFrame(wx.Frame):
    """Главное окно."""

    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(200, 100))
        # текстовое многострочное поле
        self.text_input = wx.TextCtrl(
            self,
            style=wx.TE_MULTILINE,
            size=(400, 200),
        )
        # кнопка
        self.exit_button = wx.Button(
            self,
            label="Exit",
            pos=(300, 300),
            size=(100, 100)
        )
        self.Size = (500, 500)
        # Привязка нажатия кнопки к запуску метода главного окна
        self.Bind(wx.EVT_BUTTON, self.my_exit, self.exit_button)
        self.Show(True)

    def my_exit(self, param):
        """Самодельный метод - Закрыть главное окно."""
        # quit()  # раскоментировать чтоб выход заработал
        print(f"param: {dir(param)}")  # что во втором параметре
        self.text_input.SetValue("Exit")  # изменить текст


app = wx.App(False)
frame = MyFrame(None, 'Small editor - Тестовый редактор')
app.MainLoop()

Python matplotlib быстро нарисовать график

matplotlib — модуль питона для рисования графиков

Установка matplotlib:

python3 -m pip install matplotlib

Код чтоб нарисовать простой график:

import matplotlib.pyplot as plt
plt.plot([1,2,3], [2,1,3])

просто два массива — по x и y

Результат:

Сборка Python из исходников в Linux

Имеем распакованный архив с исходниками, например Python-3.10.0.tar.xz

 1490  cd Python-3.10.0
 1491  ls
 1492  mkdir debug
 1493  cd debug/
 1498  make -C ".." clean
 1499  ../configure --with-pydebug
 1500  make
 1502  ./python

Последней командой запустится собранный из исходников python, можно пользоваться

Pygame перехват событий с джойстика

Код для вывода информации обо всех событиях, происходящих с джойстиком:

import pygame
pygame.joystick.init()
pygame.init()
clock = pygame.time.Clock()
joysticks = [pygame.joystick.Joystick(x) for x in range(pygame.joystick.get_count())]
while True:
    for event in pygame.event.get():
        print(event)
    clock.tick(60)

Пример вывода информации о происходящих с джойстиком событиях:

pygame 2.0.1 (SDL 2.0.14, Python 3.8.10)
Hello from the pygame community. https://www.pygame.org/contribute.html
<Event(1541-JoyDeviceAdded {'device_index': 0, 'guid': '030000004c050000da0c000011010000'})>
<Event(4352-AudioDeviceAdded {'which': 0, 'iscapture': 0})>
<Event(4352-AudioDeviceAdded {'which': 0, 'iscapture': 1})>
<Event(1536-JoyAxisMotion {'joy': 0, 'instance_id': 0, 'axis': 0, 'value': 0.0})>
<Event(1536-JoyAxisMotion {'joy': 0, 'instance_id': 0, 'axis': 0, 'value': -1.000030518509476})>
<Event(1536-JoyAxisMotion {'joy': 0, 'instance_id': 0, 'axis': 0, 'value': 0.0})>
<Event(1539-JoyButtonDown {'joy': 0, 'instance_id': 0, 'button': 3})>
<Event(1540-JoyButtonUp {'joy': 0, 'instance_id': 0, 'button': 3})>
<Event(1539-JoyButtonDown {'joy': 0, 'instance_id': 0, 'button': 0})>
<Event(1540-JoyButtonUp {'joy': 0, 'instance_id': 0, 'button': 0})>
<Event(1539-JoyButtonDown {'joy': 0, 'instance_id': 0, 'button': 2})>
<Event(1540-JoyButtonUp {'joy': 0, 'instance_id': 0, 'button': 2})>
<Event(1539-JoyButtonDown {'joy': 0, 'instance_id': 0, 'button': 1})>
<Event(1540-JoyButtonUp {'joy': 0, 'instance_id': 0, 'button': 1})>
<Event(1539-JoyButtonDown {'joy': 0, 'instance_id': 0, 'button': 5})>
<Event(1540-JoyButtonUp {'joy': 0, 'instance_id': 0, 'button': 5})>
<Event(1539-JoyButtonDown {'joy': 0, 'instance_id': 0, 'button': 4})>
<Event(1540-JoyButtonUp {'joy': 0, 'instance_id': 0, 'button': 4})>
<Event(1539-JoyButtonDown {'joy': 0, 'instance_id': 0, 'button': 7})>
<Event(1540-JoyButtonUp {'joy': 0, 'instance_id': 0, 'button': 7})>
<Event(1539-JoyButtonDown {'joy': 0, 'instance_id': 0, 'button': 6})>
<Event(1540-JoyButtonUp {'joy': 0, 'instance_id': 0, 'button': 6})>
<Event(1539-JoyButtonDown {'joy': 0, 'instance_id': 0, 'button': 9})>
<Event(1540-JoyButtonUp {'joy': 0, 'instance_id': 0, 'button': 9})>
<Event(1539-JoyButtonDown {'joy': 0, 'instance_id': 0, 'button': 8})>
<Event(1540-JoyButtonUp {'joy': 0, 'instance_id': 0, 'button': 8})>

Программа для проверки джойстика — человек ходит влево-вправо:

import pygame
pygame.joystick.init()
pygame.init()
clock = pygame.time.Clock()
joysticks = [pygame.joystick.Joystick(x) for x in range(pygame.joystick.get_count())]
hero_sprite = (
    "_o_\n"
    "(_)\n"
    "/ \\\n"
)


def render_object(x: int, sprite: str):
    lines = sprite.split("\n")
    print("\n" * 50)
    for line in lines:
        print(" " * x + line)


hero_x = 10
hero_vx = 0
while True:
    for event in pygame.event.get():
        if event.type == pygame.JOYAXISMOTION:
            print("it works!")
            if event.axis == 0:
                hero_vx = int(event.value)
    hero_x += hero_vx
    render_object(hero_x, hero_sprite)
    clock.tick(60)

Python ctypes и вызов функций

>>> from ctypes import *
>>> cdll.LoadLibrary("libc.so.6")
<CDLL 'libc.so.6', handle 7f8318993000 at 0x7f8317e7f730>
>>> libc = CDLL("libc.so.6")
>>> libc.printf(b"spam")
4
spam>>> 
>>> c_int()
c_int(0)
>>> c_wchar_p("Hello, World")
c_wchar_p(140201018456432)
>>> c_wchar_p("Hello, World")
c_wchar_p(140201018456688)
>>> c_ushort(-3)
c_ushort(65533)
>>> c_uint(-3)
c_uint(4294967293)
>>> s = "Hello, World"
>>> c_s = c_wchar_p(s)
>>> print(c_s)
c_wchar_p(140201018456432)
>>> print(c_s.value)
Hello, World

Python ходовые операции с файлами

# удалить файл    
os.remove(file_name)

# создать папку
os.mkdir(path, mode=0o777, *, dir_fd=None)

# удалить пустую папку    
os.rmdir(empty_dir_name)

# удалить папку с файлами
shutil.rmtree(dir_with_content_name)

# переименовать файл
os.rename(
    os.path.join(dir_name, "1.txt"),
    os.path.join(dir_name, "2.txt")
)

# копировать файл
shutil.copy(src, dst)

# смена рабочей папки
os.chdir(BUILD_DIR)

# копировать файл
shutil.copyfile(
    from_file_name,
    to_file_name
)

# Размер файла
os.stat(file_name).st_size

# Даты создания и изменения
os.stat(file_name).st_ctime
os.stat(file_name).st_mtime
time.strftime(
    "%Y-%m-%d %H:%M:%S",
    time.localtime(os.stat(file_name).st_ctime)
)
'2020-09-21 22:38:12'

# MD5-сумма файла
>>> import hashlib
>>> hashlib.md5(open(file_name,'rb').read()).hexdigest()
'41456436718fbcc7bc30154864327b49'

# смена прав
os.chmod(out_dir, 0o0777)

# удалить файл    
os.remove(file_name)

# создать папку
os.mkdir(path, mode=0o777, *, dir_fd=None)

# удалить пустую папку    
os.rmdir(empty_dir_name)

# удалить папку с файлами
shutil.rmtree(dir_with_content_name)

# переименовать файл
os.rename(
    os.path.join(dir_name, "1.txt"),
    os.path.join(dir_name, "2.txt")
)

# смена рабочей папки
os.chdir(BUILD_DIR)

# копировать файл
shutil.copyfile(
    from_file_name,
    to_file_name
)

# Размер файла
os.stat(file_name).st_size

# Даты создания и изменения
os.stat(file_name).st_ctime
os.stat(file_name).st_mtime
time.strftime(
    "%Y-%m-%d %H:%M:%S",
    time.localtime(os.stat(file_name).st_ctime)
)
'2020-09-21 22:38:12'

# MD5-сумма файла
>>> import hashlib
>>> hashlib.md5(open(file_name,'rb').read()).hexdigest()
'41456436718fbcc7bc30154864327b49'

# смена прав
os.chmod(out_dir, 0o0777)

Python ping

Модуль называется ping3

Установка модуля ping3:

$ python3 -m pip install ping3
Collecting ping3
  Downloading ping3-3.0.2-py3-none-any.whl (12 kB)
Installing collected packages: ping3
Successfully installed ping3-3.0.2

Как пользоваться:

>>> ping("192.168.1.1")
0.00391697883605957

Как пропинговать подсеть:

>>> for i in range(1, 5):
...   ip = f"192.168.1.{i}"
...   for j in range(3):
...     print(f"{ip}: {ping(ip)}")
... 
192.168.1.1: None
192.168.1.1: 0.11145853996276855
192.168.1.1: 0.008517742156982422
192.168.1.2: None
192.168.1.2: None
192.168.1.2: None
192.168.1.3: None
192.168.1.3: 0.6436576843261719
192.168.1.3: 0.004034757614135742
192.168.1.4: 0.00033211708068847656
192.168.1.4: 0.00026726722717285156
192.168.1.4: 0.00026297569274902344
192.168.1.5: None
192.168.1.5: None
192.168.1.5: None

Как указать таймаут:

>>> ping("habr.com", timeout=5)
>>> ping("habr.com", timeout=1)
>>> ping("ya.ru", timeout=1)
0.035222530364990234
>>>

Ещё несколько примеров из документации:

pip install ping3  # install ping

>>> from ping3 import ping, verbose_ping
>>> ping('example.com')  # Returns delay in seconds.
0.215697261510079666

>>> verbose_ping('example.com')  # Ping 4 times in a row.
ping 'example.com' ... 215ms
ping 'example.com' ... 216ms
ping 'example.com' ... 219ms
ping 'example.com' ... 217ms

$ ping3 example.com  # Verbose ping.
ping 'example.com' ... 215ms
ping 'example.com' ... 216ms
ping 'example.com' ... 219ms
ping 'example.com' ... 217ms

Installation

pip install ping3  # install ping3
pip install --upgrade ping3 # upgrade ping3
pip uninstall ping3  # uninstall ping3

Functions

>>> from ping3 import ping, verbose_ping

>>> ping('example.com')  # Returns delay in seconds.
0.215697261510079666

>>> ping('not.exist.com')  # If host unknown (cannot resolve), returns False.
False

>>> ping("224.0.0.0")  # If timed out (no reply), returns None.
None

>>> ping('example.com', timeout=10)  # Set timeout to 10 seconds. Default timeout is 4 for 4 seconds.
0.215697261510079666

>>> ping('example.com', unit='ms')  # Returns delay in milliseconds. Default unit is 's' for seconds.
215.9627876281738

>>> ping('example.com', src_addr='192.168.1.15')  # Set source ip address for multiple interfaces. Default src_addr is None for no binding.
0.215697261510079666

>>> ping('example.com', interface='eth0')  # LINUX ONLY. Set source interface for multiple network interfaces. Default interface is None for no binding.
0.215697261510079666

>>> ping('example.com', ttl=5)  # Set packet Time-To-Live to 5. The packet is discarded if it does not reach the target host after 5 jumps. Default ttl is 64.
None

>>> ping('example.com', size=56)  # Set ICMP packet payload to 56 bytes. The total ICMP packet size is 8 (header) + 56 (payload) = 64 bytes. Default size is 56.
0.215697261510079666

Python скрипт для чтения голосом необработанных текстовых файлов через festival

Есть программа синтезатор голоса festival, но она очень привередливая к формату того, что её пытаются заставить говорить.

Поэтому набросал скрипт speaker.py, обёртку для festival, который приводит входной текст в относительный порядок. Скрипт использовать так:

 cat test.txt | python3 speaker.py

Скрипт читает голосом текст, перенаправленный в него.

Сам скрипт speaker.py:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Программа для преобразования входного текста в голос
kmsvsr.ru
"""

import sys
import os

def prepare(text):
    """Подготовить текст для передачи в фестиваль"""
    text = text.lower()
    text = text.replace("&", "- энд -")
    text = text.replace("«", "")
    text = text.replace("»", "")
    text = text.replace("—", "")
    text = text.replace(" ", " ")
    if text[-len("с англ"):] == "с англ":
        text = text.replace("с англ", "с английского")
    if text[-len("(англ"):] == "(англ":
        text = text.replace("(англ", "(с английского")
    text = text.replace("the", "дэ")
    text = text.replace("productions", "прод+акшенс")
    text = text.replace("track", "трак")
    text = text.replace("3do", "3 ди+о, ")
    text = text.replace("в 199", "в 1990 ")
    text = text.replace("в 20", "в 2000 ")
    text = text.replace(" 0 году", "м год+у")
    text = text.replace(" 1 году", " первом год+у")
    text = text.replace(" 2 году", " втором год+у")
    text = text.replace(" 3 году", " третьем год+у")
    text = text.replace(" 4 году", " четвёртом год+у")
    text = text.replace(" 5 году", " пятом год+у")
    text = text.replace(" 6 году", " шестом год+у")
    text = text.replace(" 7 году", " седьмом год+у")
    text = text.replace(" 8 году", " восьмом год+у")
    text = text.replace(" 9 году", " девятом год+у")
    text = text.replace(" году", " год+у")
    text = text.replace("pioneer", "пионер")
    text = text.replace("canada", "кан+ада")
    text = text.replace("лятор", "л+ятор")
    text = text.replace(" ea ", " е, эй, ")
    text = text.replace(" и ", ", и ")
    text = text.replace("electronic", "электр+оник")
    text = text.replace(" arts", "  артс")
    text = text.replace("ирован", "+ирован")
    text = text.replace("playstation", "плэйст+эйшэн")
    text = text.replace("sega", "с+ега")
    text = text.replace("saturn", "сат+урн")
    text = text.replace("special", "сп+ешиал")
    text = text.replace("edition", "эд+ишен")
    text = text.replace("отзывы", "+отзывы")
    text = text.replace("высокое", "выс+окое")
    if text[-len(" ii"):] == " ii":
        text = text.replace(" ii", " два")
    text = text.replace("speed", "спид")
    text = text.replace("сиквел", "с+иквел")
    text = text.replace("сведения", "св+едения")
    text = text.replace("сериал", "сери+ал")
    text = text.replace(" a ", " э ")
    text = text.replace("discovery", "диск+авери")
    text = text.replace("witches", "в+итчес")
    text = text.replace(" of ", " оф ")
    text = text.replace("[", ", ")
    text = text.replace("]", ", ")
    text = text.replace(" ,", ",")
    text = text.replace("души", "д+уши")
    text = text.replace("дебор", "деб+ор")
    text = text.replace("харкнесс", "х+аркнесс")
    text = text.replace(" one", " у+ан")
    text = text.replace("канал", "кан+ал")
    text = text.replace("бря 20", "бря 2000 ")
    text = text.replace("противостоя", "противосто+я")
    text = text.replace("вампир", "вамп+ир")
    text = text.replace("веково", "веков+о")
    text = text.replace("warner", "в+орнер")
    text = text.replace(" bros", " бр+азерс")
    text = text.replace("„", " из ")
    text = text.replace("%", " процентов ")
    text = text.replace("/", " ")
    text = text.replace("“", " ")
    text = text.replace("ролях", "рол+ях")
    text = text.replace("великобритан", "великобрит+ан")
    text = text.replace(" мин", " минут")
    text = text.replace(" млн", " милли+онов")
    text = text.replace("…", ". ")
    text = text.replace(")", ". ")
    text = text.replace("[", ", есть ссылка  ")
    text = text.replace("↑", ", ")
    text = text.replace("‘", ", ")
    text = text.replace("é", ", ")
    text = text.replace(" см.", " смотреть в ")
    text = text.replace("®", ", ")
    text = text.replace("–", ", ")
    text = text.replace("•", ", ")
    text = text.replace(":", ", двоеточие, ")
    text = text.replace("nasa", "н+аса")
    text = text.replace("*", " умножить на ")
    text = text.replace("дизайнер", "диз+айнер")
    text = text.replace("просмотр", "просм+отр")
    text = text.replace("бан", "б+ан")
    text = text.replace("симбиоз", "симби+оз")
    text = text.replace("хабр", "х+абр")
    text = text.replace("итог", "ит+ог")
    text = text.replace("аналог", "ан+алог")
    text = text.replace("≥", " больше, либо равно ")
    text = text.replace(" мгу", " эм гэ у")
    text = text.replace("шлеме", "шл+еме")
    text = text.replace("космонавт", "космон+авт")
    text = text.replace("буран", "бур+ан")
    text = text.replace("систем", "сист+ем")
    text = text.replace("перенос", "перен+ос")
    text = text.replace("→", ", ")
    text = text.replace("песоч", "пес+оч")
    text = text.replace("правил", "пр+авил")
    text = text.replace(" руб.", " рублей ")
    text = text.replace("отклик", "+отклик")
    text = text.replace("клиент", "кли+ент")
    text = text.replace("разработчик", "разраб+отчик")
    text = text.replace("базов", "б+азов")
    text = text.replace(" слова", " слов+а")
    text = text.replace("этап", "эт+ап")
    text = text.replace(" 2-ое", " второе")
    text = text.replace("pmi", " пи эм ай ")
    text = text.replace("снг", "эс эн гэ")
    text = text.replace("data", "д+эйта")
    text = text.replace("sciense", "сайнс")
    text = text.replace("bounce", "баунс")
    text = text.replace("китай", "кит+ай")
    text = text.replace("сайт", "с+айт")
    text = text.replace("wifi", "вай фай ")
    text = text.replace("разработ", "разраб+от")
    text = text.replace("встраив", "встр+аив")
    text = text.replace("php", "пи эйч пи ")
    text = text.replace("sql", "эс ку эль ")
    text = text.replace("valve", "вальв")
    text = text.replace("слеж", "сл+еж")
    text = text.replace("любом", "люб+ом")
    text = text.replace("ware", "вэйр")
    text = text.replace("ight", "айт")
    text = text.replace("ine", "айн")
    text = text.replace("nginx", "нжин+икс")
    text = text.replace("office", "+офис")
    text = text.replace("ё", "+ё")
    text = text.replace("лямбд", "л+ямбд")
    text = text.replace("минпромторг", "минпромт+орг")
    text = text.replace("купа", "куп+а")
    text = text.replace("шот", "ш+от")
    text = text.replace("network", "нетв+орк")
    text = text.replace("сервер", "с+ервер")
    text = text.replace(">", " больше ")
    text = text.replace(" ,", ", ")
    text = text.replace("opennet", "оупенн+ет ")
    text = text.replace("dns", "диэн+эс ")
    text = text.replace("firefox", "файрф+окс")
    text = text.replace("отзыва", "отзыв+а")
    text = text.replace("erlang", "ерл+анг")
    text = text.replace("java ", "дж+ава ")
    text = text.replace("javascript", "джаваскр+ипт")
    text = text.replace("пользо", "п+ользо")
    text = text.replace("технологии", "технол+огии")
    text = text.replace("www", "дабл ю дабл ю дабл ю ")
    text = text.replace("https://", "эйчтитипи+эс ")
    text = text.replace("http://", "эйчтитип+и ")
    text = text.replace("·", ", ")
    text = text.replace("|", ", ")
    text = text.replace("вывоз", "в+ывоз")
    text = text.replace("гаджет", "г+аджет")
    text = text.replace("машин", "маш+ин")
    text = text.replace("ноутбук", "ноутб+ук")
    text = text.replace("сетево", "сетев+о")
    text = text.replace("картридж", "к!артридж")
    text = text.replace("компресс", "компр!есс")
    text = text.replace("polaris", "пол+ярис")
    text = text.replace("процесс", "проц+есс")
    text = text.replace("иговая", "игов+ая")
    text = text.replace("мотор", "мот+ор")
    text = text.replace("квадрокоп", "квадрок+оп")
    text = text.replace("новинк", "нов+инк")
    text = text.replace("жестк", "ж+ёстк")
    text = text.replace("₽", "рублей")
    text = text.replace("варка", "в+арка")
    text = text.replace("bloody", "бл+ади")
    text = text.replace("ps5", "плэйст+эйшн 5")
    text = text.replace("amd", "аэмд+э")
    text = text.replace("samsung", "самс+унг")
    text = text.replace("philips", "ф+илипс")
    text = text.replace("bluetooth", "блют+ус")
    text = text.replace("испыта", "испыт+а")
    text = text.replace("™", ", ")
    text = text.replace("бренд", "бр+енд")
    text = text.replace("фон", "ф+он")
    text = text.replace("офис", "+офис")
    text = text.replace("причем", "прич+ём")
    text = text.replace("см.", "смотреть")
    text = text.replace("основно", "основн+о")
    text = text.replace("windows", "в+индоус")
    text = text.replace("дела", "дел+а")
    text = text.replace("edge", "эдж")
    text = text.replace(" se ", " эсъ+е ")
    text = text.replace("store", "стор")
    text = text.replace("azure", "+эйжъюр ")
    text = text.replace("©", "копирасты ")
    text = text.replace("staging", "ст+эйджинг")
    text = text.replace("gpl", "джипи+эл")
    text = text.replace("дистрибутив", "дистрибут+ив")
    text = text.replace("исходны", "исх+одны")
    text = text.replace("блокировк", "блокир+овк")
    text = text.replace("технологий", "технол+огий")
    text = text.replace("origin", "ор+иджин")
    text = text.replace("пороч", "пор+оч")
    text = text.replace("побежден", "побежд+ён")
    text = text.replace("мвд", "эмвэд+э")
    text = text.replace("касперск", "касп+ерск")
    text = text.replace("названы", "н+азваны")
    text = text.replace("биткойн", "битк+ойн")
    text = text.replace("биткоин", "битк+ойн")
    text = text.replace("тренд", "тр+енд")
    text = text.replace("удаленк", "удал+ёнк")
    text = text.replace("ddos", "дид+ос")
    text = text.replace("бург", "б+ург")
    text = text.replace("цифровая", "цифров+ая")
    text = text.replace("ритм", "р+итм")
    text = text.replace("интернет", "интерн+ет")
    text = text.replace("призм", "пр+изм")
    text = text.replace("сдел", "сд+ел")
    text = text.replace("автоматиза", "автоматиз+а")
    text = text.replace("цифрово", "цифров+о")
    text = text.replace("пандеми", "пандем+и")
    text = text.replace("сектор", "с+ектор")
    text = text.replace("замещен", "замещ+ен")
    text = text.replace("ssd", "эсэсд+и")
    text = text.replace("hdd", "эйчдид+и")
    text = text.replace("тариф", "тар+иф")
    text = text.replace("морско", "морск+о")
    text = text.replace("№", "номер ")
    text = text.replace("депутат", "депут+ат")
    text = text.replace("вступа", "вступ+а")
    text = text.replace("прием ", "при+ём ")
    text = text.replace("рубля", "рубл+я")
    text = text.replace(" делает", " д+елает")
    text = text.replace(" делают", " д+елают")
    text = text.replace(" рф", " эр+эф")
    text = text.replace("росси", "росс+и")
    text = text.replace("спартаке", "спартак+е")
    text = text.replace("спартака", "спартак+а")
    text = text.replace("финал", "фин+ал")
    text = text.replace("футбол", "футб+ол")
    text = text.replace("огайо", "ог+айо")
    text = text.replace("конго", "к+онго")
    text = text.replace("тюмен", "тюм+ен")
    text = text.replace("белков", "белк+ов")
    text = text.replace("кроссовер", "кросс+овер")
    text = text.replace(" it ", " айт+и ")
    text = text.replace(" ит-", " айт+и ")
    text = text.replace("чане", "ч+ане")
    text = text.replace("интерфейс", "интерф+ейс")
    text = text.replace("запустим", "зап+устим")
    text = text.replace("ходить", "ход+ить")
    text = text.replace("’", " ")
    text = text.replace("расчет", "расч+ёт")
    text = text.replace("_", " ")
    text = text.replace("тестировал", "тест+ировал")
    text = text.replace("во всем", "во всём")
    text = text.replace("удаленно", "удал+ённо")
    text = text.replace("digital ", "д+иджитал ")
    text = text.replace("nft", "энэф+ти")
    text = text.replace("домен", "дом+ен")
    text = text.replace("оборон", "обор+он")
    text = text.replace("коллектив", "коллект+ив")
    text = text.replace("мгу", "эмгэ+у")
    text = text.replace("кндр", "каэндэ+эр")
    text = text.replace(" тв ", " тэв+э ")
    text = text.replace(" tv ", " тив+и ")
    text = text.replace("старт", "ст+арт")
    text = text.replace("мск", "по моск+овскому вр+емени")
    text = text.replace("кабелями", "кабел+ями")
    text = text.replace("скоп", "ск+оп")
    text = text.replace("бортовой", "бортов+ой")
    text = text.replace("на борту", "на борт+у")
    text = text.replace("разъем", "разъ+ём")
    text = text.replace("четко", "ч+ётко")
    text = text.replace("грузил", "груз+ил")
    text = text.replace("тормозно", "тормозн+о")
    text = text.replace("-", " ")
    text = text.replace("дежур", "деж+ур")
    text = text.replace("команд", "ком+анд")
    text = text.replace("полетами", "пол+ётами")
    text = text.replace("км", " километров")
    text = text.replace("тормозна", "тормозн+а")
    text = text.replace("м/с", " метров в секунду")
    text = text.replace("торвальдс", "т+орвальдс")
    text = text.replace("правок", "пр+авок")
    text = text.replace("сша", "сэшэ+а")
    text = text.replace("ссср", "эсэсэс+эр")
    text = text.replace("linux", " л+инукс ")
    text = text.replace("см.", "смотреть")
    text = text.replace("<", " меньше ")
    text = text.replace("всмпо", "вэсээмпэ+о")
    text = text.replace("институт", "инстит+ут")
    text = text.replace("банкрот", "банкр+от")
    text = text.replace("титан", "тит+ан")
    text = text.replace("европ", "евр+оп")
    text = text.replace("тагил", "таг+ил")
    text = text.replace("позднее", "поздне+е")
    text = text.replace("apple", "эпл")
    text = text.replace("disk", "диск")
    text = text.replace("скале", "скал+е")
    text = text.replace("в виду", "в вид+у")
    text = text.replace("игров", "игров+")
    text = text.replace("консол", "конс+ол")
    text = text.replace("facebook", "фейсб+ук")
    text = text.replace("loot", "лут")
    text = text.replace("drop", "дроп")
    text = text.replace("wolf", "вольф")
    text = text.replace("stein", "шт+айн")
    text = text.replace("doom", "дум")
    text = text.replace("ation", "+эйшен")
    text = text.replace("оо", "у")
    text = text.replace("this", "дис")
    text = text.replace("пробел", "проб+ел")
    text = text.replace("синтаксис", "синтаксис")
    text = text.replace("python", "п+айтон")
    text = text.replace("глобальн", "глоб+альн")
    text = text.replace("devops", "дев+опс")
    text = text.replace("ладк", "л+адк")
    text = text.replace("сначала", "снач+ала")
    text = text.replace("сообщест", "со+общест")
    text = text.replace("=", " равн+о ")
    text = text.replace("пушкин", "п+ушкин")
    text = text.replace("послушн", "посл+ушн")
    text = text.replace("оспарив", "осп+арив")
    text = text.replace("!", ", ")
    return text

def speak(text):
    """Сказать текст"""
    os.system(
        f'echo "{prepare(text)}" | festival --tts --language russian'
    )

for line in sys.stdin:
    parts = line.split(".")
    for part in parts:
        part = part.strip()
        speak(part)

Исправления слов и ударений можно пополнять по мере необходимости. Кто добавит — можете сюда в коментарии скидывать, пополню.

Установка Festival на ubuntu-подобный Linux: https://kmsvsr.ru/2015/11/04/uchim-kompyuter-govorit-ustanovka-festival-na-ubuntu-podobnyj-linux/