ubuntuusers.de

Schleife macht immer noch Probleme

Status: Ungelöst | Ubuntu-Version: Ubuntu 22.04 (Jammy Jellyfish)
Antworten |

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4650

Wohnort: Berlin

Das was das Ruby-Programm macht in Python (ungetestet):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/bin/env python3
from pathlib import Path


def main():
    file_path = Path("neu.txt")
    ranges_text = input("Enter ranges: ")

    line_numbers = set()
    for range_text in ranges_text.split(","):
        start_text, dash, end_text = range_text.partition("-")
        start = int(start_text)
        end = int(end_text) if dash else start
        if start > end:
            raise ValueError(f"start > end: {range_text}")
    line_numbers.update(range(start, end + 1))

    temporary_file_path = file_path.with_suffix(file_path.suffix + "~")
    with file_path.open("r", encoding="iso-8859-1") as lines:
        with temporary_file_path.open("w", encoding="iso-8859-1") as file:
            file.writelines(
                line
                for number, line in enumerate(lines, 1)
                if number in line_numbers
            )

    temporary_file_path.rename(file_path)


if __name__ == "__main__":
    main()

Eine richtige Programmiersprache hat auch den Vorteil, dass man einfacher auf die tatsächliche Struktur der Datei eingehen kann, statt das einfach als allgemeine Folge von Zeilen zu verarbeiten. Und man kann auch sicherstellen, dass die Zeilen die geschrieben werden, mit Windowszeilenenden abgeschlossen werden. Und man muss das vielleicht alles nicht einmal selbst machen, falls es eine Bibliothek für IPTV-M3U-Dateien für die Sprache gibt.

Wolfmann

(Themenstarter)

Anmeldungsdatum:
7. Oktober 2018

Beiträge: 343

Ok, super. Nochmals vielen Dank für euren tollen Support. Wieder was gelernt.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13075

Marc_BlackJack_Rintsch schrieb:

Das was das Ruby-Programm macht in Python (ungetestet):

Interessant. Soweit ich das sehe, gibt es aber einen entscheidenden Unterschied: Dein Python-Programm prüft nicht die Gültigkeit der Eingabe (das, was das Ruby-Programm in Zeile 9 macht).

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4650

Wohnort: Berlin

@rklm: Jain, die Prüfung ist implizit, weil das Programm bei einer ungültigen Eingabe mit einer Ausnahme abbricht. Kann man natürlich etwas expliziter machen (ungetestet):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env python3
import sys
from pathlib import Path


def main():
    file_path = Path("neu.txt")
    ranges_text = input("Enter ranges: ")

    line_numbers = set()
    try:
        for range_text in ranges_text.split(","):
            start_text, dash, end_text = range_text.partition("-")
            start = int(start_text)
            end = int(end_text) if dash else start
            if start > end:
                raise ValueError(f"start > end: {range_text}")
        
            line_numbers.update(range(start, end + 1))
            
    except ValueError as error:
        sys.exit(f"Error in ranges: {error}")
    
    temporary_file_path = file_path.with_suffix(file_path.suffix + "~")
    with file_path.open("r", encoding="iso-8859-1") as lines:
        with temporary_file_path.open("w", encoding="iso-8859-1") as file:
            file.writelines(
                line
                for number, line in enumerate(lines, 1)
                if number in line_numbers
            )

    temporary_file_path.rename(file_path)


if __name__ == "__main__":
    main()

Spassenhalber das ganze noch mal in einer so richtig objektorientierten Sprache die keine Schlüsselworte und keine Klassen hat, sondern nur aus Objekten und Nachrichten besteht, wobei auch die Nachrichten Objekte sind — Io:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/usr/bin/env io
Range

RangeError := Exception clone

Sequence tryAsNumber := method(
    result := self asNumber
    result isNan ifTrue(RangeError raise(self .. " is not a number"))
    result
)

main := method(
    inputFile := "neu.txt" asFile
    
    "Enter ranges: " print
    rangesText := File standardInput readLine
    
    lineNumbers := List clone
    exception := try(
        rangesText split(",") foreach(rangeText,
            range := rangeText split("-") map(tryAsNumber)
            range isEmpty ifTrue(
                RangeError raise("missing number(s) in " .. rangesText)
            )
            (range size > 2) ifTrue(
                RangeError raise("more that two numbers in range " .. rangesText)
            )
            start := range at(0)
            end := if(range size == 2, range at(1), start)
            (start > end) ifTrue(RangeError raise(start .. " > " ..  end))
            start to(end) foreach(number, lineNumbers appendIfAbsent(number))
        )
    )
    exception catch(RangeError,
        ("Error in ranges: " .. rangesText .. " | " .. exception error) println
        System exit(1)
    )
    
    temporaryFile := (inputFile path .. "~") asFile create
    inputFile openForReading foreachLine(i, line,
        lineNumbers contains(i + 1) ifTrue(temporaryFile write(line .. "\n"))
    )
    inputFile close
    temporaryFile close moveTo(inputFile path)
)

isLaunchScript ifTrue(main)

Benutzt für die Zeilennummern die behalten werden sollen eine Liste weil die Sprache keine Menge (set) mitbringt. Das könnte man sich aber notfalls aus mit Hilfe eines Map-Objekts basteln.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13075

Marc_BlackJack_Rintsch schrieb:

@rklm: Jain, die Prüfung ist implizit, weil das Programm bei einer ungültigen Eingabe mit einer Ausnahme abbricht.

Einerseits, ja. Andererseits ist es dann weniger explizit. In Ruby z.B. akzeptiert Integer auch Zeichenketten, die vorne oder hinten Whitespace haben. Das dürfte in diesem Fall nicht so ein Problem sein, aber es könnte z.B. ungute Interaktionen zwischen einem Vorzeichen-Minus und dem Range-Trenner geben. Das kann mit meinem Regex nicht passieren.

Benutzt für die Zeilennummern die behalten werden sollen eine Liste weil die Sprache keine Menge (set) mitbringt. Das könnte man sich aber notfalls aus mit Hilfe eines Map-Objekts basteln.

Für das Ruby-Programm hatte ich als möglicherweise Platz sparende Alternative noch einen Integer als Bitset erwogen.

Antworten |