LINUX.ORG.RU

Python. Вопрос по textwrap.wrap и по остальному скрипту тоже.

 


0

1

Добрый день! Пытаюсь написать скрипт для замены английского текста на русский перевод в субтитрах. Сначала был набросок, но потом с помощью волшебных пенделей и гугля, скрипт стал обретать черты. Итак. Есть файл субтитров srt:

1
00:00:12,753 –> 00:00:14,762
Agreed.
What's your point?
2
00:00:14,950 –> 00:00:18,140
There's no point, I just think
it's a good idea for a T-shirt.
И файл перевода:
Agreed.
Согласен.
What's your point?
А в чем смысл?
There's no point, I just think it's a good idea for a T-shirt.
Нет смысла, я всего лишь подумал, это хорошая идея для футболки.
Результат:
1
00:00:12,753 –> 00:00:14,762
Согласе
смысл?
2
00:00:14,950 –> 00:00:18,140
Нет смысла, я всего лишь
подумал, это хорошая идея для
Видно что скрипт обрезает концы строк. Думаю надо как-то подшаманить с textwrap.wrap. Ну и сам скрипт.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import textwrap
# Создаем словать
en2rus = {}
# Открываем файл c переводами
with open("txt") as f:
    # Если открывается
    try:
        # Обрабаываем в цикле
        while True:
            # Первая строка
            FirstLine = next(f)
# Вторая строка
            SecondLine = next(f)
# Заносим первую строку как ключ в словарь, а вторую строку как значение в
# словарь
            # можно заодно любую длину сюда закинуть
            en2rus[FirstLine] = SecondLine
            # print(en2rus)
# Обрабатываем ошибку
    except StopIteration:
        pass  # файл кончился
# Открываем файл c переводами
with open("srt") as b, open("srt-out", "w") as out:
    # Если открывается
    try:
        # Обрабаываем в цикле
        while True:
            # Первая строка
            FirstLine = next(b)
            # Номер блока субтитров. Просто записываем
            out.write(FirstLine)
            # Вторая строка. Время субтитра. Просто записываем
            SecondLine = next(b)
            out.write(SecondLine)
            # Третья строка
            ThirdLine = next(b)
            # Убираем знак завершения строки
            SrtLine = ThirdLine.rstrip('\r\n')
            # Перебираем все ключи словаря
            for key in en2rus:
                # Проверяем входит ли строка в ключи словаря - ключи словаря английский текст
                if SrtLine in key:
                    # Определяем длину ключа
                    Lenkey = len(key)
                    # Определяем длину строки
                    LenSrtLine = len(SrtLine)
                    # Определяем длину переведенной строки, от которой нужно отрезать текст
                    y = textwrap.wrap(en2rus[key], width=LenSrtLine)
                    # Заменяем английский текст на перевод
                    ReplaceLine = ThirdLine.replace(SrtLine, y[0])
                    # Записываем замененный текст
                    out.write(ReplaceLine)
            # Четвертая строка
            FourthLine = next(b)
            # Убираем знак завершения строки
            SrtLine = FourthLine.rstrip('\r\n')
            # Если длина строки = 2, тогда просто записываем
            if len(SrtLine) == 2:
                out.write(FourthLine)
            else:
                # Иначе:
                # Перебираем все ключи словаря
                for key in en2rus:
                    # Проверяем входит ли строка в ключи словаря - ключи словаря английский текст
                    if SrtLine in key:
                        # Определяем длину ключа
                        Lenkey = len(key)
                        # Определяем длину строки
                        LenFourthLine = len(SrtLine)
                        # Определяем длину переведенной строки, от которой нужно отрезать текст
                        y = textwrap.wrap(en2rus[key], width=LenSrtLine)
                        # Заменяем английский текст на перевод
                        ReplaceLine = FourthLine.replace(SrtLine, y[1])
                        # Записываем замененный текст
                        out.write(ReplaceLine)
# Обрабатываем ошибку
    except StopIteration:
        pass  # файл кончился
Я понимаю что тут много быдлокода, но я еще учусь. Как лучше написать скрипт для замены английского текста на русский перевод в субтитрах?

Ответ на: комментарий от chemtech

i, s и n - никак не относится к коду, нужны только для объяснения.

anonymous
()
Ответ на: комментарий от chemtech

Скорее всего там сравнение n (у меня n=11) и sum(x) (у меня sum(x)=10)

Но тут я не вижу сравнение. Тут только вхождение в цикл.

ииии, какой тогда может быть цикл и зачем там +1 к элементам x делается?

anonymous
()
Ответ на: комментарий от chemtech

это каким таким образом +1 к количеству слов в какой-то группе элементов привело к поиску конца перевода?

anonymous
()
Ответ на: комментарий от anonymous

ну вот было два элемента в списке x - 8 и 2. Хотя должно быть 8 и 3.

8 и 2 - это 8 и 2 переведенных слов в i элементе субтитров. Но всего переведенных слов 11. Получается как раз 1 не хватает.

Ведь мы прибавляем еденичку к i-му элементу, который является количеством слов перевода в i-ом элементе субтитров.

Т.е. чтобы оно совплало с количеством переведенных слов из словаря.

chemtech
() автор топика
Ответ на: комментарий от chemtech

да, смысл того цикла в этом. тогда скажи, сколько должно быть итераций для этого примера у цикла?

anonymous
()
Ответ на: комментарий от anonymous

Если еденички не хватает, то еденичка должна быть результатом разности. Получается что 11 слов (переведенный текст - это n) и 10 в переведенных слов скрипт записал в субтитры - это sum(x). Получается циклов должно быть

n-sum(x)
.

chemtech
() автор топика
Ответ на: комментарий от anonymous
        for a in range(n-sum(x)):
            b = y[a][1]
            x[b] = x[b] + 1

range(n - 7 вопросиков....емое

chemtech
() автор топика
Ответ на: комментарий от anonymous

Добрый день.

Вот эту строчку не могу понять

i.text = textwrap.fill(' '.join(?.????), width=70)

Есть перевод, он склеивается join в строку, и эта строка заменяет текст в i элементе субтитра.

Но чему равен ?.???? - по смыслу подходит переведенный для этого субтитра текст, но вопросикам i.text или i.lang - что конечно бред, т.к. i.text и есть текст в субтитрах,а lang вообще словарь.

У items - 5 букв. в 4 вопросика не влезает...

chemtech
() автор топика
Ответ на: комментарий от chemtech

А i.lang то откуда взялся? В i нет поля lang в том цикле.

i.text и есть текст в субтитрах

Посмотри по внимательней

anonymous
()
Ответ на: комментарий от anonymous

Чтобы понять, я написал print для вывода значений переменных.

Но почему то print не выводится..

def translate(srt, lang):
    items = list(_translate(_extract(srt), lang))
    print(items, '- items in translate\n')

    for scheme in items:
        print(scheme, '- scheme in translate\n')
        scheme.divide()

надо debug-ер поискать

Для join(?.????) прочитал что нужен список строк, только список строк.

chemtech
() автор топика
Ответ на: комментарий от anonymous

Открыл код в pycharm. нашел список, который должен заменятся в переменных. Подчеркнул его красной линией.

http://i.imgur.com/1Z7hJLo.png

Это же ведь он должен вставлятся в субтитры.

chemtech
() автор топика
Последнее исправление: chemtech (всего исправлений: 1)
Ответ на: комментарий от chemtech

Код правильный. Подчеркнутое кажется относится к переменной items, в данном случае она к делу уже не относится.

Обратить внимание я хотел на значение переменной i.text, если напишешь так:

    for i in srt:
        print(i.text, '- i in translate\n')
        i.text = textwrap.fill(' '.join(i.text), width=70)
то заметишь, что внутри i.text список предложений, а не текст.

anonymous
()
Ответ на: комментарий от anonymous

Получается что join склеивает весь переведенный текст, а textwrap.fill разделяет на две строки. тогда ширина width должна быть 35 или 40.

chemtech
() автор топика
Ответ на: комментарий от anonymous

Получается что join склеивает весь переведенный текст, а textwrap.fill разделяет на две строки. тогда ширина width должна быть 35 или 40.

Это верно или я не прав? textwrap.fill делает из текста список предложений в две строки.

Список этот поискал в debug режиме в pycharm. Скриншот. http://i.imgur.com/5RumObl.png Там же ведь этот текст должен заместить английский текст в субтитрах? правильно я понимаю?

Код правильный. Подчеркнутое кажется относится к переменной items, в данном случае она к делу уже не относится.

Не могу найти другую переменную, которая могла быть списком, который склеивает join и обрабатывает textwrap.fill

chemtech
() автор топика
Последнее исправление: chemtech (всего исправлений: 1)
Ответ на: комментарий от anonymous

Где я ошибся? Подскажите пожалуйста.

chemtech
() автор топика
Ответ на: комментарий от chemtech

Это верно или я не прав? textwrap.fill делает из текста список предложений в две строки.

не обязательно две, лучше прочитай в документации

Не могу найти другую переменную

i.text же

anonymous
()
Ответ на: комментарий от anonymous

Это я понял, что textwrap.fill разбивает на два предложения по 40. Вы можете подсказать где искать join(?.????)

Т.к. там точка, то переменная должна быть одной буквы, и эта переменная есть только одна - это «i», а у нее есть метод с 4 буквами только один - это «text».... Такого быть не может. Где я не ошибся?

chemtech
() автор топика
Ответ на: комментарий от anonymous

Т.е. нужно пересмотреть код, где переменная i.text образуется. Возможно там ошибка, ведь должен образовываться список, а там генератор.....

chemtech
() автор топика
Последнее исправление: chemtech (всего исправлений: 1)
Ответ на: комментарий от chemtech

ага, а точнее в цикле на 100 строке

anonymous
()
Ответ на: комментарий от anonymous

Спасибо БОЛЬШОЕ. Код поправил

        for a, [b, c] in zip(x, self.items):
            b.text.append(' '.join(items[:a]))
            items = items[a:]
chemtech
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.