Buchstabenverdreher

Code-Stücke können hier veröffentlicht werden.
Sirius3
User
Beiträge: 11982
Registriert: Sonntag 21. Oktober 2012, 17:20

Donnerstag 10. Oktober 2019, 20:07

`text_list` ist immer noch ein schlechter Name, `i` noch ein viel schlechter. Gute Namen helfen beim Lesen und verstehen des Codes. Der Inhalt von elif und else ist immer noch fast identisch. Funktionsdefinitionen helfen hier.
`or` ist kein umgangsprachliches Oder sondern ein logisches Oder, das die linke Seite liefert, wenn sie sich zu einem "Wahr" auswerten läßt, sonst die rechte Seite. die rechte Seite besteht aus einem nicht-leeren String, ist also immer wahr, sodass der else-Block nie ausgeführt werden kann.
Was Du suchst, ist der `in`-Operator mit einer Liste.
Benutzeravatar
__blackjack__
User
Beiträge: 5999
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Sonntag 13. Oktober 2019, 10:37

Hier mal was ich da so im Kopf hatte:

Code: Alles auswählen

#!/usr/bin/env python3
import random
import re

TEXT = """\
Ich habe die Aufgabe ein Programm zu schreiben das in einem Text bei allen
Wörtern die Buchstaben zufällig vertauscht wobei der erste und der letzte
Buchstabe gleich bleibt. Basiert auf einer Studie die besagt, das man es lesen
kann solange der erste und letzte Buchstabe stimmt und sonst nur die anderen
Buchstaben vetauscht. Also zB: "Es kmmot auf die Vrpunekacg an".
"""


def process_word(word):
    if len(word) > 3:
        middle_characters = list(word[1:-1])
        random.shuffle(middle_characters)
        word = word[0] + "".join(middle_characters) + word[-1]
    return word


def process_text(text):
    return re.sub(r"\w{3,}", lambda match: process_word(match.group()), text)


def main():
    print(process_text(TEXT))


if __name__ == "__main__":
    main()
long long ago; /* in a galaxy far far away */
nezzcarth
User
Beiträge: 996
Registriert: Samstag 16. April 2011, 12:47

Sonntag 13. Oktober 2019, 12:20

Interessant. :)

Hier mal mein Ansatz:

Code: Alles auswählen

#!/usr/bin/env python3
import fileinput
from random import shuffle

import somajo

LANGUAGE = 'de'


def scramble_word(word):
    if len(word) <= 3:
        return word
    head, *body, tail = word
    shuffle(body)
    return ''.join([head, *body, tail])


class TextScrambler:
    def __init__(self, tokenizer, scrambler):
        self.tokenizer = tokenizer
        self.scrambler = scrambler
        
    def __call__(self, text):
        result = []
        for token, category,extra in self.tokenizer.tokenize(text):
            result.append(self.scrambler(token) if category == 'regular' else token)
            if extra != 'SpaceAfter=No':
                result.append(' ')
            # OriginalSpelling etc. wird z.Z. nicht berücksichtigt.
        return ''.join(result)


def main():
    if not LANGUAGE in somajo.Tokenizer.supported_languages:
        raise ValueError('Language "{}" not supported.'.format(LANGUAGE))   
    text = '\n'.join(line for line in fileinput.input())
    tokenizer = somajo.Tokenizer(
            language=LANGUAGE,
            extra_info=True,
            token_classes=True
            )
    scramble_text = TextScrambler(tokenizer, scramble_word)
    scrambled_text = scramble_text(text)
    print(scrambled_text)


if __name__ == '__main__':
    main()
EDIT:
Resultat:

Code: Alles auswählen

$ ./scrambler.py text1.txt
Ich habe die Agfuabe ein Pmragorm zu sebciehrn das in eeinm Text bei aleln Weötrrn die Bhebstucan zfulliäg vtsuecarht weboi der etsre und der lettze Bcshtubae gclieh bieblt. Briesat auf eenir Sidtue die bsgaet, das man es lseen kann sgolane der esrte und lzttee Bhstuacbe smimtt und snsot nur die anedren Bahsbceutn vuhaectst. Aslo zB: "Es kmomt auf die Venpkrcaug an".
nezzcarth
User
Beiträge: 996
Registriert: Samstag 16. April 2011, 12:47

Montag 14. Oktober 2019, 20:18

Es ist erstaunlich, wie gut das Ergebnis der Regex-Lösung ist, wenn man bedenkt, wie einfach der Ausdruck ist, gerade auch im Vergleich zu der Komplexität eines Tokenizes. Ein kleiner Unterschied zwischen den beiden Ansätzen ist zum Beispiel im Englischen bei der Kontraktion "aren't" zu sehen. In der Regex-Version ist die Form "aern't" möglich, in der Tokenizer-Version nicht, da "are" und "n't" als zwei getrennte Tokens zu je drei Zeichen betrachtet werden. Man muss sich also überlegen, was man gerne möchte.
Antworten