Anfänger haben für vieles kein Verständnis ... z.B. warum "('foo')" die Zeichenkette 'foo' erzeugt und kein einelementiges Tupel.Leonidas hat geschrieben:Jeder Python 2.x Programmierer, ja. Aber man kann kaum erwarten dass das ewig so bleiben würde. Schließlich nehme ich an, dass auch Neulinge auf Python 3.0 einsteigen und die haben für sowas kein Verständnis. Ebenso wie alle anderen in ein paar Jahren, wenn 2.x an Bedeutung verliert.
Plattformunabhängigkeit und getch(curses)
Wieso? Bei Bytes/Unicode ist das doch recht ähnlich. Zudem wäre man so zukunftssicher gewesen. Beispielsweise werden ja nun recht häufig namedtuple eingesetzt. Was passiert wenn man die gerne in die Syntax integriert hätte? Oder irgendein anderer colllection Typ? Mehr Klammern gibt die Tastatur nun mal nicht her. Mit einem Präfix wäre das ganze recht einfach.Das aus einem leeren Wörterbuch aber durch den magischen Buchstaben "s" eine Menge wird, also ein sich völlig anders verhaltendes Objekt, passt da nicht recht ins Schema.
Man hätte das set ja auch mit eckigen Klammern und Präfix machen können. Es ähnelt ja eher einer Liste als einem Dictionary. Dann ist die Diskrepanz zwischen kleiner Änderung in Syntax - große Auswirkungen auf Verhalten nicht ganz so groß. Ein frozenset wäre dann entsprechend mit runden Klammern, äquivalent zum Verhältnis Tuple/Liste.
Code: Alles auswählen
empty_set = s[]
empty_frozenset = s()
Code: Alles auswählen
empty_set = s{}
empty_frozenset = f{}
str und byte stellen geordnete Sequenzen dar und implementieren das Listen-Protokoll. Zwischen beiden Typen besteht darüber hinaus ein logischer Zusammenhang, da sie ineinander überführt werden können.
set() und dict() dagegen sind zwei völlig unterschiedliche Typen, die in keinem unmittelbaren Zusammenhang stehen und völlig verschiedene Protokolle implementieren. Das ist also mitnichten vergleichbar.
Auch sind Mengen keine Listen und ähneln ihnen auch nicht. MengenSie sind ungeordnet, und unterstützen daher weder Slicing noch Sortierung noch Einfügen. Die einzige Operation, die auf Listen und Mengen gleichermaßen funktioniert, ist die Iteration.
set() und dict() dagegen sind zwei völlig unterschiedliche Typen, die in keinem unmittelbaren Zusammenhang stehen und völlig verschiedene Protokolle implementieren. Das ist also mitnichten vergleichbar.
Auch sind Mengen keine Listen und ähneln ihnen auch nicht. MengenSie sind ungeordnet, und unterstützen daher weder Slicing noch Sortierung noch Einfügen. Die einzige Operation, die auf Listen und Mengen gleichermaßen funktioniert, ist die Iteration.
Dazu sage ich jetzt mal nichtsEDIT: OK, das ist natürlich Quatsch, weil dann nicht mehr zwischen Funktionsaufruf/ Set unterschieden werden könnte. Dann halt doch so:Code: Alles auswählen
empty_set = s{} empty_frozenset = f{}
Und deswegen gibt man ihnen die, bis auf einem Doppelpunkt in der Mitte, die gleiche Syntax? Genau das ist doch das Problem!set() und dict() dagegen sind zwei völlig unterschiedliche Typen, die in keinem unmittelbaren Zusammenhang stehen und völlig verschiedene Protokolle implementieren. Das ist also mitnichten vergleichbar.
Code: Alles auswählen
>>> {1,2,3} # set
>>> {1,2} # set
>>> {1} # set
>>> {} # dict !?!?
Code: Alles auswählen
>>> s{1,2,3} # set
>>> s{1,2} # set
>>> s{1} # set
>>> s{} # set
MFG HerrHagen
Ja, das wäre eine gute Lösung gewesen. Wer sich an Python 2.x gewöhnt hat, gewöhnt sich irgendwann um. Immerhin gibt es auch anderes umzugewöhnen, sei es nun die Division mittels "/" oder range() oder input() oder oder ... , die plötzlich etwas anderes machen.HerrHagen hat geschrieben: {} ist ein leeres dict, obwohl es der Logik nach nun eher ein set sein müsste. Konsistent hätte das leere dict so: {:} und das leere set so {} ausgesehen.
Warum also nicht mit noch mehr alten Zöpfen brechen und {} als leere Menge und {:} als leeres dict einführen?
Es gibt spitze Klammern (größer/kleiner).HerrHagen hat geschrieben:Mehr Klammern gibt die Tastatur nun mal nicht her.
(ohne jetzt dafür plädieren zu wollen, diese für den besagten Fall einzusetzen)
BrainF**K-Interpreter können ja auch ziemlich kurz sein: https://www.spoj.pl/ranks/BRAINF_K/
An Perl (nur 132 Zeichen!) kommt man mit Python aber wohl nicht heran.
An Perl (nur 132 Zeichen!) kommt man mit Python aber wohl nicht heran.
Ich möchte mich noch bei allen recht herzlich bedanken, die dazu beigetragen haben meinen Thread vollzu"spam"men".
Gibts eigentlich Benchmarks mit dem man testen kann, wie schnell der Interpreter ist? Am bestens mit Vergleichwerten. Das 99 Bottle Programm ist recht I/O(wobei mehr O) intensiv. Ich hätte da noch ein paar Ideen in der Hinterhand. Diese bringen aber keine aussagekräftigen Werte, wenn das Programm in 3s(auf einen x41) schon beendet wird.
Und zu den Wettbewerbungen rundum die legendäre Programmiersprache Brainf***, wichtiger sind für mich die Lesbarkeit, Performanz, Speicherverbrauch, Plattformunabhängigkeit am wenigsten interessieren mich die Größe des Quellcodes oder irgendwelche Hacks mit i386 Opcodes.
Gibts eigentlich Benchmarks mit dem man testen kann, wie schnell der Interpreter ist? Am bestens mit Vergleichwerten. Das 99 Bottle Programm ist recht I/O(wobei mehr O) intensiv. Ich hätte da noch ein paar Ideen in der Hinterhand. Diese bringen aber keine aussagekräftigen Werte, wenn das Programm in 3s(auf einen x41) schon beendet wird.
Und zu den Wettbewerbungen rundum die legendäre Programmiersprache Brainf***, wichtiger sind für mich die Lesbarkeit, Performanz, Speicherverbrauch, Plattformunabhängigkeit am wenigsten interessieren mich die Größe des Quellcodes oder irgendwelche Hacks mit i386 Opcodes.
Das Problem wäre dann aber das alles nur unter best. Vorraussetzungen funktioniert. Die gängiste Methode wäre dann den Code umwandeln in Assembler und ihn lokal übersetzen lassen & ausführen.
Ich dachte da mehr an einen Präprozessor oder JIT Optimierung. Ein kleines Beispiel:
BF: +++++ 5mal lesen & auswerten
OBF: 5+ 2mal lesen & auswerten
-----
Ergebnis: sauschnell
Ich dachte da mehr an einen Präprozessor oder JIT Optimierung. Ein kleines Beispiel:
BF: +++++ 5mal lesen & auswerten
OBF: 5+ 2mal lesen & auswerten
-----
Ergebnis: sauschnell
Also ich würde mir da wohl die Arbeit sparen, denn BF lässt sich *sehr* einfach nach C übersetzen, und ein optimierender C-Compiler sollte aus 5× inkrementieren nacheinander *eine* Addition machen.
Stichwort Compiler: In einem anderen Thread hatte ich mal einen BF-Compiler geschrieben, der dann nochmals von mitsuhiko in Eleganz und Kürze übertroffen wurde.
Stefan
Stefan
@BlackJack: Sicher kann das der gcc optimieren, viel mehr aber nicht. Am Muster, Ausführen irgendwelcher Anweisungen kommt er nicht dran vorbei, da er(Compiler) niemals weiß was das Programm letztendlich für eine Aufgabe hat, halten sich die Optimierungen in Grenzen. z.B. Zählschleifen um eine Zelle auf einen bestimmten Wert zu setzen, könnte man zu einfach "Wert setzen" optimieren. Erkennt ein Compiler so etwas?
@sma: Ich dachte, das getch und std.read nicht das gleiche Verhalten haben. Siehe Posting 2 und 3. Frage. Kannst du mir sagen wie ich dein Code starte bzw. einbinde? Auch bekomme ich einen Syntaxfehler in deiner letzten Zeile!?
@sma: Ich dachte, das getch und std.read nicht das gleiche Verhalten haben. Siehe Posting 2 und 3. Frage. Kannst du mir sagen wie ich dein Code starte bzw. einbinde? Auch bekomme ich einen Syntaxfehler in deiner letzten Zeile!?
Rufe `run_brainfuck("....Programm...")` auf. Wenn du einen Syntaxfehler bekommst, hast du wahrscheinlich Python 3. Mache Klammern um das `exec`, da es kein Statement mehr ist sondern eine Funktion geworden ist.
Das sys.stdin.read(1) Zeichen nicht unmittelbar liest, ist mir bekannt, war aber für das Beispiel egal. Es gibt halt keinen plattformunabhängigen Weg, ein einzelnes Zeichen einzulesen, da Python für Windows keine curses-Emulation mitbringt.
Stefan
Das sys.stdin.read(1) Zeichen nicht unmittelbar liest, ist mir bekannt, war aber für das Beispiel egal. Es gibt halt keinen plattformunabhängigen Weg, ein einzelnes Zeichen einzulesen, da Python für Windows keine curses-Emulation mitbringt.
Stefan
Hallo sma,
ich habe dein Code mit meinen gekreuzt um zu testen wie schnell deine Variante ist. Leider kommt er nur bis "91 Bottles of beer\nTake one down and pass it around"
Gibts eine python interne Beschränkung für deinen Code? Oder habe ich einen Fehler gemacht?
Nochmals "unseren" Code:
ich habe dein Code mit meinen gekreuzt um zu testen wie schnell deine Variante ist. Leider kommt er nur bis "91 Bottles of beer\nTake one down and pass it around"
Gibts eine python interne Beschränkung für deinen Code? Oder habe ich einen Fehler gemacht?
Nochmals "unseren" Code:
Code: Alles auswählen
import sys
import platform
def compile_brainfuck(src):
program = ["def bf():", " import sys", " cells, ptr = [0] * 1000, 0"]
indent = 1
def emit(line): program.append(" " * indent + line)
for s in src:
if s == ">": emit("ptr += 1")
elif s == "<": emit("ptr -= 1")
elif s == "+": emit("cells[ptr] += 1")
elif s == "-": emit("cells[ptr] -= 1")
elif s == ".": emit("sys.stdout.write(chr(cells[ptr]))")
elif s == ",": emit("cells[ptr] = ord(sys.stdin.read(1))")
elif s == "[": emit("while cells[ptr]:"); indent += 1
elif s == "]": emit("pass"); indent -= 1
indent -= 1; emit("bf()")
return "\n".join(program)
try:
filehandler = open(sys.argv[1],"r")
except IndexError:
print("wrong syntax: no source file")
exit(-1)
code = ""
brainfucksymbols = ('+','-','>','<','.',',','[',']')
while True:
line = filehandler.readline()
if line == "":
break
for char in line:
if char in brainfucksymbols:
code+=char
exec (compile_brainfuck(code))