Seite 1 von 1
String Array ohne Anführungszeichen ausgeben
Verfasst: Mittwoch 7. Oktober 2020, 10:07
von BrickBardo
Ich habe ein Numpy-Array mit Datentyp String erstellt, es soll mit + und Leerzeichen gefüllt werden, abhängig vom Wert der Zufallszahl.
Code: Alles auswählen
import numpy as np
fsize = 8
def Spielfeld(fsize):
old_gen = np.empty([fsize,fsize],dtype=str)
for i in range(0,fsize):
for j in range(0,fsize):
zufall = np.random.randint(1,101,dtype=np.int)
if zufall < 50:
old_gen[i,j] = '+'
else:
old_gen[i,j] = ' '
return old_gen
old_gen = Spielfeld(fsize)
print(old_gen)
Die Ausgabe sieht wie folgt aus:
[['+' '+' ' ' ' ' ' ' '+' '+' ' ']
['+' '+' '+' '+' '+' '+' '+' '+']
['+' '+' ' ' ' ' ' ' '+' '+' ' ']
['+' '+' '+' '+' ' ' ' ' ' ' ' ']
[' ' ' ' '+' '+' ' ' '+' ' ' '+']
[' ' '+' '+' '+' '+' '+' '+' ' ']
[' ' '+' '+' ' ' ' ' '+' '+' '+']
[' ' ' ' ' ' ' ' '+' '+' ' ' ' ']]
Allerdings möchte ich, dass die Zeichen ohne die Anführungszeichen ausgegeben werden. Wie kann ich dies bewerkstelligen?
Re: String Array ohne Anführungszeichen ausgeben
Verfasst: Mittwoch 7. Oktober 2020, 10:13
von Jankie
Das ist ja quasi eine verschachtelte Liste. Du iterierst old_gen und gibst jedes Element mit "".join() aus.
Re: String Array ohne Anführungszeichen ausgeben
Verfasst: Mittwoch 7. Oktober 2020, 10:48
von __blackjack__
@BrickBardo: Da fehlen Leerzeilen um das lesbarer zu gestalten.
Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).
Eingerückt wird mit vier Leerzeichen pro Ebene.
Namen sollten keine kryptischen abkürzungen Enthalten. Wenn man `field_size` meint, sollte man nicht `fsize` schreiben. Was `old_gen` bedeuten soll ist mir ein Rätsel. In einer Funktion die ein Spielfeld erzeugt ist an dem Ergebnis dort doch nichts ”altes”‽ Das ist dort ein nigelnagelneues Spielfeld.
Funktionsnamen wie oben schon erwähnt klein geschrieben, damit man `Spielfeld` nicht für eine Klasse hält, und dann ist der Name inhaltlich ein Problem, denn man kann den nicht von einem offensichtlichen Namen für ein Spielfeld unterscheiden. Die Funktion heisst so, wie man ihren Rückgabewert nennen würde. Was man nicht mehr kann, weil ja die Funktion schon so heisst. Funktionen und Methoden werden deshalb üblicherweise nach der Tätigkeit benannt die sie durchführen. Man kann Funktionen dadurch besser von eher passiven Werten unterscheiden und ``spielfeld = erzeuge_spielfeld(42)`` ist dann kein Problem mehr.
Numpy wird hier missbraucht. Erst einmal generell, denn ich sehe in dem gezeigten Quelltext überhaupt keinen Vorteil daran das nicht einfach mit Listen zu machen. Und auch wenn man Numpy unbedingt benutzen will, dann nicht *so*. Erster Gedanken bei Numpy und Schleifen in Python sollte immer sein „ich machen wahrscheinlich etwas falsch“, denn Numpy verwendet man ja gerade um sich langsame Schleifen in Python zu sparen und die in C (und teilweise Fortran) geschriebenen Schleifen zu verwenden die sich hinter den Numpy-Operationen verstecken. Die Funktion wird mit Numpy letztlich zu einem simplen Einzeiler.
Die `numpy.random.randint()`-Funktion sollte nicht mehr verwendet werden.
Code: Alles auswählen
#!/usr/bin/env python3
import numpy as np
FIELD_SIZE = 8
def erzeuge_spielfeld(size):
return np.random.default_rng().choice(["+", " "], (size, size))
def main():
spielfeld = erzeuge_spielfeld(FIELD_SIZE)
print(spielfeld)
print("\n".join("".join(row) for row in spielfeld))
if __name__ == "__main__":
main()
Re: String Array ohne Anführungszeichen ausgeben
Verfasst: Mittwoch 7. Oktober 2020, 11:16
von ThomasL
Hi,
wie immer ist mir Blacky zuvor gekommen.
Ich poste trotzdem mal meine Lösungen,
einmal ohne Numpy weil nicht notwendig
Code: Alles auswählen
import random
def create_grid(size):
new_grid = [''.join(random.choice(['+', ' ']) for x in range(size)) for y in range(size)]
return new_grid
grid = create_grid(8)
for row in grid:
print(row)
und einmal mit Numpy, sieht so ähnlich aus wie bei Blacky.
Code: Alles auswählen
grid = np.random.choice([32, 43], size=(8, 8), replace=True, p=(0.5, 0.5))
for row in grid:
for value in row:
print(chr(value), end='')
print()
Re: String Array ohne Anführungszeichen ausgeben
Verfasst: Mittwoch 7. Oktober 2020, 11:32
von BrickBardo
Danke schon mal für eure Antworten und die Mühe, die ihr euch gemacht habt. Aber so richtig hilft mir das leider nicht weiter. Weil ich möchte es ja so machen, wie ich es oben geschrieben habe. Die Antwort könnte natürlich auch sein, dass Python das so gar nicht darstellen kann (BTW: Java kann es). Es mag auch sein, dass dies eine furchtbar ineffiziente Methode ist, aber das ist im Moment nicht mein Fokus.
Re: String Array ohne Anführungszeichen ausgeben
Verfasst: Mittwoch 7. Oktober 2020, 12:03
von __blackjack__
@BrickBardo: Was genau hilft Die dabei nicht weiter? Beide Antworten zeigen wie man das in Python schreiben würde, einmal mit Numpy, einmal ohne, und beide Antworten zeigen wie man die Ausgabe ohne die Anführungszeichen macht.
Re: String Array ohne Anführungszeichen ausgeben
Verfasst: Mittwoch 7. Oktober 2020, 12:12
von Sirius3
@BrickBardo: __blackjack__ hat Dir doch die Lösungen gezeigt, wie man ein numpy-Array erzeugt. So programmiert mit Python. In Java mußt Du auch Deine explizite Darstellung programmieren. Ist es wichtig, dass + zu _ im Verhältnis 49:51 erzeugt werden?
Dann mußt Du noch die Wahrscheinlichkeit angeben:
Code: Alles auswählen
def erzeuge_spielfeld(size):
return np.random.default_rng().choice(["+", " "], (size, size), p=[0.49, 0.51])
Re: String Array ohne Anführungszeichen ausgeben
Verfasst: Mittwoch 7. Oktober 2020, 12:24
von noisefloor
Hallo,
@BrickBardo: im Numpy-Array werden die "" oder '' immer mit angezeigt, weil du einen Array von Arrays hast und der "innere" Array Strings enthält. Die Anführungsstrichen werden dann nicht mit angezeigt, wenn du Strings direkt ausgibts.
Gruß, noisefloor
Re: String Array ohne Anführungszeichen ausgeben
Verfasst: Mittwoch 7. Oktober 2020, 12:32
von Jankie
Wenn du die Klammern behalten willst, aber nicht die Anführungszeichen musst du dein Spielfeld erst in einen String umwandeln und dann dort die mit replace() zum Beispiel die ' entfernen, dann sähe das Ergebnis so aus:
Code: Alles auswählen
[[+ + + ]
[ + + + ]
[+ + + + + + ]
[ + + + + ]
[+ + + + + ]
[+ + + ]
[ + + ]
[ + + +]]
oder mit iterieren über old_gen und dann mit "".join(row) ausgegeben in einem f-String mit zwei Klammern umschlossen so:
Code: Alles auswählen
[++ +++ +]
[ + ]
[++++ + ]
[ ++ + ]
[ +++ ]
[ ++ +++]
[ + +]
[ ++ +]
Zeig doch einmal mal wie die Ausagbe später aussehen soll, so wie du es oben Beschreiben hast wurde es jetzt mehrfach gezeigt. Also entweder besser beschreiben oder Beispiele bringen.
Re: String Array ohne Anführungszeichen ausgeben
Verfasst: Mittwoch 7. Oktober 2020, 13:04
von Sirius3
@Jankie: die Stringrepräsentation eines Numpy-Arrays ist eigentlich nicht für die allgemeine Darstellung gedacht, sondern nur zu Debuggingzwecken. Es ist gar nicht garantiert, dass man per replace immer die gewünschte Form erhält.
Für die Ausgabe wandelt man die Arrays immer explizit um.
Re: String Array ohne Anführungszeichen ausgeben
Verfasst: Donnerstag 8. Oktober 2020, 09:37
von BrickBardo
Ich habe das Problem nun folgenderweise gelöst:
Code: Alles auswählen
import numpy as np
import sys
fsize = 16
def Spielfeld():
old_gen = np.empty([fsize,fsize],dtype=str)
for i in range(0,fsize):
for j in range(0,fsize):
zufall = np.random.randint(1,101,dtype=int)
if zufall < 25:
old_gen[i,j] = '+'
else:
old_gen[i,j] = ' '
return old_gen
def Ausgabe(old_gen):
for i in range(0,fsize):
for j in range(0,fsize):
sys.stdout.write(old_gen[i,j] + ' ')
print()
old_gen = Spielfeld()
old_gen_out = Ausgabe(old_gen)
Noisefloor hatte mich auf den Gedanken gebracht, das die Einzelausgabe eines Strings immer ohne die Anführungszeichen erfolgt. So war das übrigens auch in Java gelöst, weil Java nicht über die Möglichkeit verfügt ein Array direkt über system.out.print() auszugeben. Das hat auch den angenehmen Nebeneffekt, dass die Klammern nicht mehr mitausgegeben werden.
Re: String Array ohne Anführungszeichen ausgeben
Verfasst: Donnerstag 8. Oktober 2020, 10:01
von Sirius3
@BrickBardo: auch wenn es nervt. Du solltest Dir von Anfang an eine saubere Schreibweise angewöhnen. Wenn Du Dir jetzt die Schlamperei angewöhnst, wirst Du schwer wieder davon wegkommen. Eingerückt wird immer mit 4 Leerzeichen pro Eben eingerückt. Variablennamen und Funktionsnamen werden komplett klein geschrieben. Funktionen sind nach Tätigkeiten benannt. Benutze keine Abkürzungen, oder soll old_gen tatsächlich ein altes Gen beschreiben (müßte dann old_gene heißen)? Konstanten werden komplett gross geschrieben: FSIZE, wobei hier auch wieder ausgeschrieben werden sollte: FIELD_SIZE
Im Moment programmierst Du irgend ein BASIC in Python-Syntax (nicht mal in Java würde man so programmieren). Du nutzt kein numpy. Wenn Dir die numpy-Methoden noch zu kompliziert sind, dann bleibe bei den Python-Grunddatentypen.
Man iteriert nicht über den Index um dann auf Elemente mit eckigen Klammern zuzugreifen, sondern man iteriert über die Objekte direkt.
Wenn man nicht ganz so kompakt schreiben will wie __blackjack__, ThomasL hat die Ausgabe so geschrieben, wie sie sein sollte.
`Spielfeld` sollte die Feldgröße als Argument bekommen und `Ausgabe` sollte gar nicht explizit die Feldgröße benutzen, sondern aus dem Gen-Feld ermitteln.
`Ausgabe` hat keinen Rückgabewert, diesen None-Wert an old_gen_out zu binden ist daher unsinnig.