Ergebnis in Datei schreiben

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.
Chibi
User
Beiträge: 22
Registriert: Samstag 7. November 2009, 12:10

Hi, ich hab folgenen Code

Code: Alles auswählen

...

def get_clusters(node, cutoff, parent_is_cluster):
  if node.is_leaf():
    return
  avg=get_average_length(node)
  sum_dist = sum(avg)
  if node.edge.length is not None:
    sum_dist -= get_num_leaf_nodes(node, 0)*node.edge.length
  real_dist = sum_dist/get_num_leaf_nodes(node, 0)
  if real_dist <= cutoff and not parent_is_cluster:
    print ""
    print real_dist
    print taxon_names(node)
  elif real_dist > cutoff:
    for n in node.child_nodes():
      get_clusters(n, cutoff, False)
  


cutoff=float(raw_input("Enter Cutoff value: "))

get_clusters(t1.seed_node, cutoff, False)

Und wenn ich das in einer IDE laufen lassen, kann ich den Cutoff Wert eintragen und bekomme ein Ergebnis angezeigt.
Wenn ich jedoch versuche, dass in eine Datei schreiben zulassen kommt nur eine leere Datei raus.

Ich habs damit probiert

Code: Alles auswählen

outfile=open("Ausgabe.txt","w")
outfile.write(get_clusters(t1.seed_node, cutoff, False))
outfile.close()
Aber das geht nicht, ich denke das ist ganz einfach, bin aber grad n bischen doof :-)
Hab sonst auch nur print Anweisungen, in eine Datei schreiben lassen und das ging ganz problemlos
Wenn mir da mal jemand auf die Sprünge helfen könnte, wäre ich sehr dankbar.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Die Funktion get_clusters gibt None zurück. Du schreibst None in das Dateiobjekt outfile. Was soll da also drin stehen? print schreibt per default in sys.stdout; nicht in die Datei, die es erraten soll. Entweder du gibst der Funktion ein weiteres Argument (das Dateiobjekt) oder du schreibst sie als Generator (Stichwort yield). Letzteres ist um einiges besser, weil get_clusters mit input/output überhaupt nichts zu tun hat.
Chibi
User
Beiträge: 22
Registriert: Samstag 7. November 2009, 12:10

Ah ok, hättest du da mal ein Beispielcode? So sagt mir das grad nichts. Bin noch nicht so erfahren :oops:

Edit: So hab mir das mal versucht anzuschauen mit Generatoren, aber ich werd nicht schlau daraus.
Und wie gebe ich der Funktion ein weiters Argument mit, in dem das Ergebnis drinsteht? :cry:

Sry, aber ich stell mich wahrscheinlich grad voll blöd an
Zuletzt geändert von Chibi am Samstag 6. März 2010, 00:52, insgesamt 1-mal geändert.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Vielleicht hilft dier das hier.

Sebastian
Das Leben ist wie ein Tennisball.
Chibi
User
Beiträge: 22
Registriert: Samstag 7. November 2009, 12:10

Jo, vielen Dank schonmal, hatte selbst schonmal gegoogled und mir dazu was durchgelesen, aber ich checks leider nicht richtig. Ich will doch nur den Funktionsaufruf in eine Datei schreiben, das muss man doch einfacher lösen können :oops:
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Hier noch ein Beispiel mit nem Generator:

Code: Alles auswählen

>>> def dummy_generator(a,b,c):
...     for _ in xrange(10):
...         yield (a, b, c)
... 
>>> list(dummy_generator(1,2,3))
[(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)]
>>> print '\n'.join(map(str, dummy_generator('hallo','welt','alles klar?')))
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
Chibi
User
Beiträge: 22
Registriert: Samstag 7. November 2009, 12:10

Echt, vielen lieben Dank für die Mühe, aber ich versteh nicht, wie mir das helfen kann, ich sehs einfach nicht.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Na, Du willst doch bestimmte Werte, die innerhalb der Funtkion bestimmt werden speichern. Also muss Du quasi dort, wo Du im Moment die Werte printest, diese...

a.) ... entweder dort in eine Datei speichern (File Objekt an die Funktion übergeben)
b.) ... die Werte in eine Datenstruktur packen, die Du jeder Rekursionsstufe übergibst (wie das File Objekt), aber diese auch ganz am Schluss zurückgibst, damit Du diese nach Abschluss sämtlicher Arbeiten an einen Namen binden kanns:

Code: Alles auswählen

result = foo(...)
for value in result:
    # tue was mit den einzelnen Werten
c.) wie schon erwähnt anstelle der direkten Verarbeitung in der Funktion an jeder Stelle, an der etwas berechnet wird das ganze per yield zurücklieferst. Durch die Rekursion wird es ein wenig schwerer hier, da Du dann noch in der for-Schleife die Ergebnisse der Rekursionen yielden müßtest. Also etwa so:

Code: Alles auswählen

for value in get_clusters(n, cutoff, False):
    yield value
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Generatoren sind viel zu umständlich hier. Warum nicht einfach so?

Code: Alles auswählen

def hello(name, f=None):
    print >>f, "Hallo %s" % name

# Variante 1, Konsole
hello("Stefan")

# Variante 2, Datei
with open("hello.txt", "w") as f:
  hello("Stefan", f)
Stefan
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Wieso nicht einfach ein return in der Funktion

Code: Alles auswählen

def hello(name):
    return "Hallo %s" % name

# Variante 1, Konsole
print hello("Dav1d")

# Variante 2, Datei
with open("hello.txt", "w") as f:
  f.write(hello("Dav1d"))
the more they change the more they stay the same
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Weil erstens der OP mehrere Ausgaben macht und zweitens es immer besser ist, zu streamen und nicht erst einen komplexen String zu konstruieren. Es ging mir um eine minimale Änderung des Programms ohne die Logik komplett zu ändern.

Stefan
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Wie wäre es mit "writelines" und einer Liste?
the more they change the more they stay the same
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Dav1d hat geschrieben:Wie wäre es mit "writelines" und einer Liste?
Auch da wird eine Datenstruktur aufgebaut. Ist also bei einer großen Anzahl von Werten suboptimal. Nuja, hatte es ja auch erst als Möglichkeit (b) aufgeührt :-D
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Dann bleibt eigentlich nur noch die Idee von sma (fileobj übergeben) oder yield
the more they change the more they stay the same
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Dav1d hat geschrieben:Dann bleibt eigentlich nur noch die Idee von sma (fileobj übergeben) oder yield
Nichts gegen sma, aber das war meine Idee (a) ;-)
yield ist hier imho aufgrund der Rekursion nicht wirklich toll, da Du deswegen nicht direkt an die ursprünglich aufrufende Stelle yielden kannst. (Daher auch Idee (c) :-D )
Chibi
User
Beiträge: 22
Registriert: Samstag 7. November 2009, 12:10

Ok, meint ihr das so? (Ich denke eher nicht, denn das klappt leider nicht.) :(

Code: Alles auswählen

def get_clusters(node, cutoff, parent_is_cluster):
  if node.is_leaf():
    return
  avg=get_average_length(node)
  sum_dist = sum(avg)
  if node.edge.length is not None:
    sum_dist -= get_num_leaf_nodes(node, 0)*node.edge.length
  real_dist = sum_dist/get_num_leaf_nodes(node, 0)
  if real_dist <= cutoff and not parent_is_cluster:
    yield ""
    yield real_dist
    yield taxon_names(node)
  elif real_dist > cutoff:
    for n in node.child_nodes():
      get_clusters(n, cutoff, False)
 


cutoff=float(raw_input("Enter Cutoff value: "))

get_clusters(t1.seed_node, cutoff, False) 

for value in get_clusters(n, cutoff, False):
    yield value


Mhh, ich bin in dem Punkt grad n bischen doof, könntet ihr mir das an meinem Code zeigen. Ich verzeifel so langsam

P.S.Achso, ich benutze Python 2.5, also das with statement würde nicht gehen
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Chibi hat geschrieben: Mhh, ich bin in dem Punkt grad n bischen doof, könntet ihr mir das an meinem Code zeigen. Ich verzeifel so langsam
Wieso beharrst Du so auf den Generatoen? sma hat Dir doch sogar ein Code Snippet gezeigt, wie man ein File Objekt an eine Funktion übergibt und Werte dort reinschreibt!
Chibi hat geschrieben: P.S.Achso, ich benutze Python 2.5, also das with statement würde nicht gehen

Code: Alles auswählen

from __future__ import with
Man kann natürlich auch auf with verzichten und mit einem geeigneten try...except...finally Konstrukt arbeiten - aber with ist einfacher ;-)
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

@Hyperion Du hast ein _statement vergessen ;) ``from __future__ import with_statement``
Benutzeravatar
snafu
User
Beiträge: 6861
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@derdon:

Deine `dummy_generator`-Beispiele lassen sich auch so schreiben:

Code: Alles auswählen

>>> from itertools import repeat
>>> list(repeat((1,2,3), 10))
[(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)]
>>> for tpl in repeat(('hallo','welt','alles klar?'), 10): print tpl
... 
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
('hallo', 'welt', 'alles klar?')
In Python 3.x geht dann zum Glück auch:

Code: Alles auswählen

>>> from functools import partial
>>> ten_times = partial(repeat, times=10)
>>> list(ten_times('bla'))
['bla', 'bla', 'bla', 'bla', 'bla', 'bla', 'bla', 'bla', 'bla', 'bla']
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

DasIch hat geschrieben:@Hyperion Du hast ein _statement vergessen ;) ``from __future__ import with_statement``
Schande über mich ;-)
Antworten