zahlen in reihe und glied

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.
Antworten
The_ride
User
Beiträge: 16
Registriert: Sonntag 23. April 2006, 14:33

Hi!

Ich hab ein Problem wenn ich mit diesem Programm Zufallszahlen erstelle stehen die Zahlen nicht korrekt untereinander.
was müßte ich machen damit die zahlen richtig untereinander stehen ??

zur Zeit sieht es so aus.
  • 6 13 7 14 2 0 2 15 14 8 0
    10 7 2 0 11 15 10 5 3 8 11
    5 0 14 2 2 3 15 3 3 11 20
    10 7 14 14 8 5 13 8 9 0 6
und so sollte es aussehen
  • 06 13 07 14 02 00 02 15 14 08 00
    10 07 02 00 11 15 10 05 03 08 11
    05 00 14 02 02 03 15 03 03 11 20
    10 07 14 14 08 05 13 08 09 00 06
die Null vor den zahlen 0-9 ist nicht zwingend notwendig
achja und wie sage dem programm das mir nach jeder 20sten zahl einen umbruch macht ??

Code: Alles auswählen

import random

for i in range(100):
  x = random.randint(0,20)

  print str(x),
da hier die Spezialisten sind werde ich bestimmt eine Lösung bekommen :)

Danke schon mal
cya The_ride
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich empfehle, hier das sogenannte String Formatting zu nutzen. Zuerst mal brauchst du eine Vorlage, die beschreibt, in welcher Art formatiert werden soll. Formatierungsanweisungen werden in geschweifte Klammern gesetzt. Bei deinem Anwendungsfall passt folgender Ausdruck:

Code: Alles auswählen

'{:02}'
Vor dem Doppelpunkt kann ein Index stehen, der also bezeichnet, das wievielte Element aus den später übergebenen Argumenten genutzt werden soll. Ab Python 2.7 kann der Index auch weggelassen werden, was hier sehr gelegen kommt. Die dann folgende Null ist das Füllzeichen, welches für die Leerstellen genutzt werden soll, die ja bei einstelligen Zahlen links von der Zahl verbleiben sollen. Als letztes kommt dann die Anzahl der Stellen, die eine übergebene Zahl später maximal haben wird. Hier also zwei. Ein paar Beispiele:

Code: Alles auswählen

>>> '{:02}'.format(5)
'05'
>>> '{:02}'.format(23)
'23'
>>> '{:02}'.format(0)
'00'
Ohne Füllzeichen:

Code: Alles auswählen

>>> '{:2}'.format(5)
' 5'
>>> '{:2}'.format(23)
'23'
>>> '{:2}'.format(0)
' 0'
Wieder mit Füllzeichen, aber drei Stellen:

Code: Alles auswählen

>>> '{:03}'.format(5)
'005'
Jetzt willst du aber 20 solcher Zahlen in einer Zeile haben. Weil ein Programmierer ja am liebsten möglichst lange darüber nachdenkt, wie er möglichst wenig schreiben muss, tippe auch ich die Dinger nicht hintereinander in die Vorlage, sondern nutze die Funktion zum Wiederholen von gleichen Ausgaben aus dem itertools-Modul:

Code: Alles auswählen

>>> from itertools import repeat
>>> ' '.join(repeat('{:02}', 20))
'{:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02}'
Wie unschwer zu erkennen ist, nimmt repeat() als erstes das auszugebene Resultat und als zweites die Anzahl an Wiederholungen. Die join()-Methode kombiniert die Ergebnisse mit Leerzeichen. Das Template (die Vorlage) ist also fertig und kann nun gefüllt werden:

Code: Alles auswählen

>>> from random import randint
>>> template = ' '.join(repeat('{:02}', 20))
>>> numbers = (randint(0,20) for number in xrange(20))
>>> template.format(*numbers)
'03 09 20 08 06 17 15 07 09 01 09 09 07 09 00 20 10 12 04 15'
Falls du nicht weißt, was da passiert: Die Klammern beim Erzeugen der Zufallszahlen sind ein Generator-Ausdruck. Das mit dem Stern in der letzten Zeile nennt sich Unpacking. Details dazu lassen sich bei Bedarf ergooglen oder in der Python-Doku nachlesen. Hoffe, die Anwendung ist einigermaßen klar geworden. Wie man dies nun für mehrere Zeilen zusammensetzt, schreibe ich vielleicht später noch. Was aber auch helfen kann, ist selber nachdenken. ;)

EDIT:

Hier schon mal als Funktion für eine Zeile:

Code: Alles auswählen

>>> def get_randint_line(n=20, format='{:02}'):
...     template = ' '.join(repeat(format, n))
...     numbers = (randint(0,20) for number in xrange(n))
...     return template.format(*numbers)
... 
>>> get_randint_line()
'01 20 07 15 15 19 18 16 15 01 03 02 19 03 16 16 15 14 07 08'
>>> get_randint_line()
'12 18 18 20 04 04 15 13 09 05 20 20 07 13 11 12 14 17 14 04'
>>> get_randint_line()
'08 19 08 07 04 05 18 05 14 09 15 14 18 13 18 08 02 13 15 20'
>>> get_randint_line(10)
'08 07 04 13 20 11 03 05 17 03'
Und um das Ganze zu vervollständigen:

Code: Alles auswählen

>>> def get_formatted_randints(n=100, line_elems=20):
...     lineno, leftover = divmod(n, line_elems)
...     lines = [get_randint_line(line_elems) for line in xrange(lineno)]
...     if leftover:
...         lines.append(get_randint_line(leftover))
...     return '\n'.join(lines)
... 
>>> print get_formatted_randints(105)
18 11 01 04 20 10 17 04 15 06 03 14 05 11 09 03 12 13 20 18
07 16 20 16 06 12 20 10 04 04 15 10 04 08 13 20 03 05 14 05
10 01 00 17 17 01 08 05 05 00 01 16 20 04 03 11 15 05 03 17
10 00 08 16 06 14 11 07 18 04 05 06 10 06 03 14 05 20 16 11
04 17 16 09 12 20 13 04 19 18 18 16 09 08 20 08 05 16 19 15
04 13 00 12 04
>>> print get_formatted_randints(100)
19 06 19 04 10 18 13 09 07 02 10 06 06 14 14 16 02 02 03 20
01 09 14 12 09 20 12 13 02 02 08 14 19 03 06 00 04 18 04 15
09 05 06 04 03 13 20 03 00 20 15 20 14 06 09 09 17 20 12 09
05 08 07 06 12 10 19 20 19 07 13 09 04 14 01 06 18 20 14 08
20 09 08 03 05 17 11 02 19 13 02 17 18 19 04 04 19 02 06 08
Sicherlich lässt sich noch irgendwo was optimieren. Man könnte zum Beispiel das Template in einem Rutsch erzeugen, anstatt dies für jede Zeile zu machen. Darauf habe ich aber gerade nun wirklich keine Lust mehr. ;)
The_ride
User
Beiträge: 16
Registriert: Sonntag 23. April 2006, 14:33

Hi!

Besten dank snafu :)
eine Frage hab ich noch, wenn ich das im Terminal eingebe klappt es, aber wenn ich es im Programm irgendwas.py schreibe
kommen entweder Fehler oder es wird nichts angezeigt.
  • prince@prince:~/dat/work/python/zufall$ python3.1
    Python 3.1.2 (release31-maint, Sep 17 2010, 20:34:23)
    [GCC 4.4.5] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from itertools import repeat
    >>> ' '.join(repeat('{:02}', 20))
    '{:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02} {:02}'
    >>>
    >>>

    cya The_ride
    Peter
    prince@prince:~/dat/work/python/zufall$ python3.1 Zufall001.py
    prince@prince:~/dat/work/python/zufall$ python3.1 Zufall001.py
    prince@prince:~/dat/work/python/zufall$

Code: Alles auswählen

from itertools import repeat
from random import randint
def get_randint_line(n=20, format='{:02}'):
	template = ' '.join(repeat(format, n))
	numbers = (randint(0,20) for number in xrange(n))
	return template.format(*numbers)
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

The_ride hat geschrieben:eine Frage hab ich noch, wenn ich das im Terminal eingebe klappt es, aber wenn ich es im Programm irgendwas.py schreibe
kommen entweder Fehler oder es wird nichts angezeigt.
Es wird nichts angezeigt, weil du das print-statement vergessen hast.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Falls du nicht verstanden hast, wie /me das meint: Rückgabewerte werden in der Konsole nur innerhalb des Interpreters angezeigt. Um den Rückgabewert auf den Bildschirm zu schreiben, benötigst du hier die print()-Funktion. Mal mit Fehlerbehandlung:

Code: Alles auswählen

#!/usr/bin/env python3

from itertools import repeat
from random import randint
from sys import stderr

def get_randint_line(n=20, format='{:02}'):
    template = ' '.join(repeat(format, n))
    numbers = (randint(0,20) for number in range(n))
    return template.format(*numbers)

def get_formatted_randints(n=100, line_elems=20):
    lineno, leftover = divmod(n, line_elems)
    lines = [get_randint_line(line_elems) for line in range(lineno)]
    if leftover:
         lines.append(get_randint_line(leftover))
    return '\n'.join(lines)

def exit_with_error(message, exit_code=1):
    print('Error:', message, file=stderr)
    exit(exit_code)

if __name__ == '__main__':
    n = input('How many random numbers should be generated? ')
    try:
        n = int(n)
    except ValueError:
        exit_with_error('Need an integer as input')
    if n < 0:
        exit_with_error('Number must be positive')
    numbers = get_formatted_randints(n)
    print(numbers)
(Bei der Implementierung einer *ordentlichen* Fehlerbehandlung merke ich gerade, wie schlecht das tatsächlich geschrieben ist. Eine verbesserte Version wird wohl folgen...)
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Klar kann man Itertools und format und alles benutzen, aber ist es nicht manchmal auch viel einfacher, es direkt, d.h. imperativ zu machen? Und nennt mich old-school, aber ich finde ja die %-Formatierung schöner als die mit format().

Code: Alles auswählen

from random import randrange
for i in range(5):
    for j in range(20):
        print "%2d" % (randrange(20) + 1),
    print
Stefan
The_ride
User
Beiträge: 16
Registriert: Sonntag 23. April 2006, 14:33

Hi!

Danke für die Mühe die ihr euch mit mir gebt :)

nur jetzt habe ich python3.1 installiert da funzt ja fast nichts mehr was bei 2.6 noch klappte
sei es zb. print "Hallo" bei 3.1 kommt
File "<stdin>", line 1
print "hallo"
^
SyntaxError: invalid syntax

das verstehe ich jetzt nicht das ist mir echt zu hoch
wie kann in einer Verbesserung etwas "so leichtes" nicht mehr klappen ???

cya The_ride
Peter

PS:

unter 2.6 klappen aber eure Beispiele nicht :(
*Durchdreh*

cya

PPS:
SMA
Dein beispiel klappt in Eclipse mit pydev :)

und noch mal cya
Lasse
User
Beiträge: 112
Registriert: Donnerstag 3. Februar 2011, 18:25

Hall the_ride,
in Python 3 sind die Klammern beim print Pflicht. Es muss also so aussehen:

Code: Alles auswählen

print("Hallo")
Die Python Entwickler haben an ein paar Stellen den Syntax geändert. So muss man z.B. auch "input()" in Version 3 schreiben statt
"raw_input()". ("input()" für Zahlen aus V2 fällt weg)
The_ride
User
Beiträge: 16
Registriert: Sonntag 23. April 2006, 14:33

Hi!

Danke für deine Antwort :)

gibt es eine doku was alles geändert worden ist ?
ich bin nicht 100%tig im pythonprogrammieren.

cya The_ride
Antworten