Suche nach bestimmten Buchstaben in einer Textdatei

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Alfons Mittelmeyer hat geschrieben:Aber wer programmieren kann, aber bisher noch nicht in Python, könnte Programmierprobleme auch auf in Python unnötige Weise lösen.
Und Du zeigst dann, wie dies geht ...

'is_in' lässt sich übrigens besser schreiben als

Code: Alles auswählen

def is_in(value, iterable):
    for item in iterable:
        if value == item:
            return True
    return False
Was aber nicht erforderlich ist, denn es gibt ja 'in'.

Deine umständliche Variante ist allerdings besser geeignet, um Python-Anfänger auf die falsche Fährte zu locken.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

kbr hat geschrieben:
Alfons Mittelmeyer hat geschrieben: 'is_in' lässt sich übrigens besser schreiben als

Code: Alles auswählen

def is_in(value, iterable):
    for item in iterable:
        if value == item:
            return True
    return False
Was aber nicht erforderlich ist, denn es gibt ja 'in'.
Die von mir vorgestellte Funktion würde evtl. jemand schreiben der in nicht kennt. Aber Deine Variante macht da keinen Sinn, denn Du benützt in Zeile 2 in
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Wahrscheinlich hast Du auch noch Vorschläge, wie sich if, return und def vermeiden lassen ...
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

kbr hat geschrieben:Wahrscheinlich hast Du auch noch Vorschläge, wie sich if, return und def vermeiden lassen ...
Nö, Bedingungen wie if, else, Funktionen def und return sowie Schleifen while, break, continue gehören zu jeder Programmiersprache. Vermeidbar wäre aber for.

Man könnte höchstens einen Interpreter für eine andere Programmiersprache machen und diese Schlüsselworte umbenenen, vielleicht in wenn, sonst, solange_als, aufhören, weitermachen, definiere, zurückspringen oder abhauen.

Ich hatte mal in Python ein FORTH geschrieben, da konnte man auch if, else usw, beliebig umbenennen. Aber in Python Schlüsselworte umbenennen geht wohl nicht?

Zumindest wäre das nicht einfach: http://stackoverflow.com/questions/3647 ... r-keywords

Sinnvollerweise sollte man die Schlüsselworte nicht umbendennen sondern ein alias anlegen. Wie macht man das in Python?

Und sollte das alias von if, dann eine Kopie von if sein, oder auf das urprünliche if verweisen?
Zuletzt geändert von Alfons Mittelmeyer am Donnerstag 11. Mai 2017, 22:13, insgesamt 1-mal geändert.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Alfons Mittelmeyer hat geschrieben:
kbr hat geschrieben:Wahrscheinlich hast Du auch noch Vorschläge, wie sich if, return und def vermeiden lassen ...
Nö, Bedingungen wie if, else, Funktionen def und return sowie Schleifen while, break, continue gehören zu jeder Programmiersprache.
Nein, tun sie nicht. Lambda Calculus kommt ohne Bedingungen und Schleifen aus. Das spiegelt sich in der Praxis auch durchaus in funktionalen Programmiersprachen wieder. Assembler kommt ohne Funktionen und Schleifen aus, findet ebenfalls durchaus praktische Anwendung.
BlackJack

@YasinSidirva: Ignoriere am besten Alfons' Beiträge. Der provoziert hier öfter unsinnige Diskussionen mit komischen bis falschen Codebeispielen und teils sehr gewagten Thesen seinerseits.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

DasIch hat geschrieben:
Alfons Mittelmeyer hat geschrieben:
kbr hat geschrieben:Wahrscheinlich hast Du auch noch Vorschläge, wie sich if, return und def vermeiden lassen ...
Nö, Bedingungen wie if, else, Funktionen def und return sowie Schleifen while, break, continue gehören zu jeder Programmiersprache.
Nein, tun sie nicht. Lambda Calculus kommt ohne Bedingungen und Schleifen aus. Das spiegelt sich in der Praxis auch durchaus in funktionalen Programmiersprachen wieder.
Natürlich hat man Bedingungen, aber Schlüsselworte wie if else sind vermeidbar. Man kann das auch in Python tun. Hier etwa mit einer ifelse Funktion:

Code: Alles auswählen

# ============ Das gehört nicht auf die Programmebene sondern zur Programmiersprache
def ifelse(condition,execute_if_true,execute_if_false):
    if condition:
        execute_if_true()
    else:
        execute_if_false()
# ===========================================================================

value = True
ifelse(value,lambda:print("Wert ist wahr"),lambda:print("Wert ist unwahr"))

value = False
ifelse(value,lambda:print("Wert ist wahr"),lambda:print("Wert ist unwahr"))
Dasselbe geht übrigens auch mit Schleifen!
DasIch hat geschrieben:Assembler kommt ohne Funktionen und Schleifen aus, findet ebenfalls durchaus praktische Anwendung.
Funktionen und while Schleifen sind Elemente höherer Programmiersprachen, um Spaghetti Code zu vermeiden. In früheren Programmiersprachen wie das Commodore BASIC des C64 - (sowie auch ähnlich in Assembler) macht man Funktionen mit gosub Zeilennummer und Schleifen mit goto und zwar rückwärts.

Schleifen gibt es also auch dort, nur nicht schön strukturiert und beliebig umherspringbar. Richtige Funktionen gibt es nicht, da keine Parameterübergabe definiert ist. Das ist wie Funktionen ohne Parameter mit globalen Variablen. Aber man kann implementieren, daß die Parameter auf einem Stack übergeben werden und die sogenannte Funktion hebt sie dann ab.

Code: Alles auswählen

# statt ===

def myfunction_normal(value):
    print(value)

myfunction_normal('normal')

# implementiert man dann

stack = []

def myfunction_stack():
    print(stack.pop())

stack.append('using stack')
myfunction_stack()
Und so werden dann auch Funktionen mit Parametern für die Assemblerebene übersetzt. Nur daß es dann etwa so heißt wie jumpsubroutine myfunction_stack # das ist dann eine Speicheradresse
BlackJack

@Alfons Mittelmeyer: Ob reguläre Ausdrücke angebracht sind oder nicht ist eine ermessensfrage, auf jeden Fall sind sie durchaus für solche Aufgaben gedacht und in diesem Fall auch nicht wirklich komplizierterer Code als:

Code: Alles auswählen

if 'F' in line or 'G' in line or 'M' in line:
denn:

Code: Alles auswählen

if re.search('[FGM]', line):
Das hier:

Code: Alles auswählen

if line[0] in 'FGM':
mag Dir vielleicht simpler und schneller vorkommen als die `startswith()`-Methode, aber es ist nicht ganz äquivalent, weil es einen Fall nicht abdeckt der zu einer Ausnahme führen kann, den `startswith()` allerdings abdeckt. Damit ist das in der Tat qualitativ schlechter. :-)

kbr benutzt in seiner Funktion für Leute die den ``in``-Operator nicht kennen *keinen* ``in``-Operator. Du fängst hier schon wieder mit einer sehr ”speziellen” Argumentation an. Auf dieser Grundlage könnte man auch monieren, dass der Benutzer den ``in``-Operator nicht kennt und deshalb auch kein `in` im Funktionsnamen vorkommen darf. ;-)

Funktionen macht man in BASIC des C64 mit ``DEF FN``. Ist aber nicht sehr gebräuchlich. Mit ``GOSUB`` macht man keine Funktionen — es gibt ja gar keine lokalen Namen und man kann weder Argumente übergeben noch Werte an den Aufrufer zurückgeben. Das sind einfach Unterprogramme die alle auf dem gleichen globalen Namensraum operieren. Mit ``GOTO`` kann man auch den Effekt von Schleifen implementieren, aber nicht nur. Es ist halt eine allgemeine Sprunganweisung. Für Schleifen kennt CBM BASIC V2 allerdings ``FOR``/``TO``/``STEP``/``NEXT``.

Das man den Effekt von Funktionen auf verschiedene Weisen in Maschinensprache implementieren kann, ändert nichts daran das es in der Sprache selbst keine Funktionen gibt. Also zumindest in den allermeisten Befehlssätzen.

@DasIch: Vorsicht mit der zu allgemeinen Aussage zu Assembler und Schleifen — x86 kennt ja beispielsweise ``loop`` und den ``rep``-Präfix. :-)
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

BlackJack hat geschrieben:@Alfons Mittelmeyer: Ob reguläre Ausdrücke angebracht sind oder nicht ist eine ermessensfrage, auf jeden Fall sind sie durchaus für solche Aufgaben gedacht und in diesem Fall auch nicht wirklich komplizierterer Code als:

Code: Alles auswählen

if 'F' in line or 'G' in line or 'M' in line:
denn:

Code: Alles auswählen

if re.search('[FGM]', line):
Das hier:

Code: Alles auswählen

if line[0] in 'FGM':
mag Dir vielleicht simpler und schneller vorkommen als die `startswith()`-Methode, aber es ist nicht ganz äquivalent, weil es einen Fall nicht abdeckt der zu einer Ausnahme führen kann, den `startswith()` allerdings abdeckt. Damit ist das in der Tat qualitativ schlechter. :-)
Das denkst auch nur Du. Es gibt keine Ausnahme, denn alle Zeilen enthalten zumindest ein '\n'. Eine Zeile mit mit nur EOF, würde auch ein Zeichen enthalten, aber diese Zeile taucht bei for l in f gar nicht auf. ;-)
BlackJack hat geschrieben:kbr benutzt in seiner Funktion für Leute die den ``in``-Operator nicht kennen *keinen* ``in``-Operator. Du fängst hier schon wieder mit einer sehr ”speziellen” Argumentation an. Auf dieser Grundlage könnte man auch monieren, dass der Benutzer den ``in``-Operator nicht kennt und deshalb auch kein `in` im Funktionsnamen vorkommen darf. ;-)
wieder daneben, es handelte sich um Zeile 2, also: for item in iterable:
BlackJack hat geschrieben:Das man den Effekt von Funktionen auf verschiedene Weisen in Maschinensprache implementieren kann, ändert nichts daran das es in der Sprache selbst keine Funktionen gibt. Also zumindest in den allermeisten Befehlssätzen.
Sorry ein GOSUB Label ist ein Funktionsaufruf allerdings parameterlos. Natürlich ist aber Label keine Funktion. Es gibt also parameterlose Funktionsaufrufe aber ohne Definition einer Funktion. Man nennt es auch nicht Funktion sondern Subroutine.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Und Subroutine ist in einem Sinn keine Funktion, denn eine Funktion kann man nur beginnend mit dem Anfang aufrufen, während man bei einer Subroutine auch quer einsteigen kann. Man hat also auch das, was auch höhere Programmiersprachen, nur viel mehr Freiheitsgrade. Und kann tun, was höhere Programmiersprachen ausschließen, weil diese übersichtlichen Code im Sinn haben und nicht erlauben, daß man von einer Funktion mitten in eine andere reinspringt oder daneben springt, weil man vielleicht statt in Code in einem String landet und dann alles crasht, wenn dieser String dann als Code ausgeführt wird. Um das auszuschließen benutzt man in Assembler Label. Wenn man allerdings statt einem Assembler nur einen Maschensprachemonitor hat und dann von Speicherstelle 0xAEEE auf 0xAEA3 zurückspringen muß und das relativ angeben muß also einen negativen Abstand als positiven Wert mit größer 127 ist negativ angeben muß, dann geht es leicht daneben.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Also Funktionen sind nichts Besonderes sondern Einschränkungen und Vieles klappt damit einfach nicht. Etwa hier:

Code: Alles auswählen

def function_a():
    ' ' * 200

def function_b():
    print('soll nach a kopiert werden')


for i in range(len(function_b)):
    function_a[i] = function_b[i]

del function_b

function_a()
In Funktion function_a will ich genug Platz reservieren, damit ich dann den Code von function_b hineinkopieren kann. Dann will ich function_b löschen und dann function_a aufrufen, um zu testen, ob das geklappt hat.

Aber ich bekomme da einen syntax error. Wie kann ich das machen, damit es funktioniert?
BlackJack

@Alfons Mittelmeyer: kbr verwendet keinen ``in``-Operator. Auch nicht in der zweiten Zeile die Du ja netterweise noch mal hingeschrieben hast. Der ``in``-Operator ist der binäre Operator der testet ob der linke Operand im rechten Operanden vorkommt. Ist zumindest die Implementierung die man erwarten würde. In ``for item in iterable:`` kommt dieser Operator nicht vor.

Ab da drehst Du in den folgenden Beiträgen anscheinend wieder ein bisschen frei. :-)
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Code, den ein Anfänger nicht schreiben würde, der jedoch das Problem löst:

Code: Alles auswählen

from __future__ import print_function
from collections import defaultdict, namedtuple

FILENAME = 'input.txt'

NEEDLES = 'G', 'M', 'F'


class Match(namedtuple('Match', 'lineno, line')):
    def __str__(self):
        return 'Line #{}: {}'.format(
            self.lineno, self.line
        )


def find_lines(lines, needles):
    result = defaultdict(list)
    for lineno, line in enumerate(lines, 1):
        for needle in needles:
            if needle in line:
                match = Match(lineno, line.rstrip('\n'))
                result[needle].append(match)
    return result


def main():
    with open(FILENAME) as infile:
        result = find_lines(infile, NEEDLES)
    for needle in NEEDLES:
        print('Matches for {!r}:'.format(needle))
        for match in result[needle]:
            print(match)
        print()


if __name__ == '__main__':
    main()
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

@BlackJack: Du verkennst die Lage. Hier entsteht gerade eine umfassende Python-Dokumentation. Du musst nur noch Themen nach Benutzer suchen ;)
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Da noch keine Generatorlösung vorgeschlagen wurde (ja, ich steh' auf die Dinger):

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf-8
from __future__ import with_statement

def main():
    with open('input.txt') as ifp, open('output.txt', 'w') as ofp:
        ofp.writelines(line for line in ifp if any(e in line for e in 'FGM'))
    
if __name__ == '__main__':
    main()
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

BlackJack hat geschrieben:@Alfons Mittelmeyer: kbr verwendet keinen ``in``-Operator. Auch nicht in der zweiten Zeile die Du ja netterweise noch mal hingeschrieben hast. Der ``in``-Operator ist der binäre Operator der testet ob der linke Operand im rechten Operanden vorkommt. Ist zumindest die Implementierung die man erwarten würde. In ``for item in iterable:`` kommt dieser Operator nicht vor.
Ja stimmt, 'in' in einem Fall ist ein Membership operator und im anderen Fall ein Bestandteil des for statements.
beertonic
User
Beiträge: 37
Registriert: Montag 8. Mai 2017, 15:26

@ Alfons: "Zuerst alle Python Grundlagen zu studieren ist ach nicht der richtige Rat."
Da sind wir wohl verschiedener Meinung...
"Dem User zu raten, sich zuerst mit Regex zu beschäftigen, trägt nicht zur Problemlösung bei."
Lesen sie nochmal was ich geschrieben habe...


Mit Regex kann man den ganzen Text mit einem Befehl durchsuchen und die gematchten Zeilen speichern. Es gibt natürlich auch andere Wege, aber ich glaube mit Regex ist der Code am kompaktesten.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Code: Alles auswählen

import re

def write_lines(needles, fn_in, fn_out):
    searcher = re.compile('|'.join(needles)).search
    with open(fn_in) as infile, open(fn_out, 'w') as outfile:
        outfile.writelines(filter(searcher, infile))

if __name__ == '__main__':
    write_lines('GMF', 'input.txt', 'output.txt')
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@Alfons:
Gerade dann wenn man große Datenmengen verarbeiten muss, ist es schon sinnvoll zu wissen wie man möglichst effizienten Python-Code schreiben kann. Dazu gehört auch die Beschäftigung mit den Sprachmitteln. Sonst kann man's auch lassen und direkt C oder sowas verwenden, wo man jeden Schritt detailliert selbst festlegt und der Compiler es dann für einen optimiert.

Python funktioniert eben so, dass performancekritische Bereiche schon vorkompiliert sind und als (Builtin-)Funktionen dem Programmierer zur Verfügung stehen. Davon sollte bei Bedarf auch reichlich Gebrauch gemacht werden, wenn man die Stärken von Python wirklich ausnutzen will.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@snafu: sorry, das ist der einfachste, kompakteste und effizienteste Code für den Fall, daß es der erste Buchstabe wäre: if line[0] in 'FGM':
Antworten