Minimaler Abstand

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.
Haze91
User
Beiträge: 12
Registriert: Donnerstag 3. September 2015, 10:17

Ahhhh, jetzt haben wir es verstanden :o

Vielen Dank für eure Mühe und Ausdauer :D
Haze91
User
Beiträge: 12
Registriert: Donnerstag 3. September 2015, 10:17

Morgen!

Wir haben das nächste bzw ein ähnliches Problem.
Wir haben eine Liste mit unterlisten und müssen in jeder Unterliste auf den letzten Eintrag (Wert) zugreifen.

liste = [['26.04.2015', '20', '26', 23.0, 9, 14.0, 336.0, 14, 336], ['25.04.2015', '18', '26', 22.0, 9, 13.0, 312.0, 27, 648], ['24.04.2015', '18', '25', 21.5, 9, 12.5, 300.0, 39, 948], ['23.04.2015', '19', '25', 22.0, 9, 13.0, 312.0, 52, 1260], ['22.04.2015', '17', '25', 21.0, 9, 12.0, 288.0, 64, 1548], ['21.04.2015', '18', '25', 21.5, 9, 12.5, 300.0, 76, 1848], ['20.04.2015', '19', '27', 23.0, 9, 14.0, 336.0, 90, 2184], ['19.04.2015', '18', '25', 21.5, 9, 12.5, 300.0, 102, 2484], ['18.04.2015', '19', '26', 22.5, 9, 13.5, 324.0, 115, 2808]]

mini = 504

Dieser mini_wert soll mit dem letzten Wert jeder Unterliste verglichen werden.
Unser Versuch:

Code: Alles auswählen

j=0
for j in range(0,len(liste)):
	ADHmin = (0, bisect(liste[j][8], mini) - 1)
	j+=1
print ADHmin
funktioniert leider nicht. Kann jemand helfen?

Liebe Grüße
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@Haze91: funktioniert nicht, ist eine äußerst schlechte Fehlerbeschreibung. Was passiert? Gibt es eine Fehlermeldung? Wie ist das erwartete Verhalten und wie das tatsächliche?

Was habt ihr Euch beim händischen Zahlen von j bei einer for-Schleife gedacht? Das ist übrigens ein pythonisches Anti-Pattern. Über Listenelemente wird direkt iteriert.
BlackJack

@Haze91: Ihr solltet eventuell erst einmal Python lernen. So ganz grundsätzlich. Bis ihr verstanden habt/seht das die Zuweisung an `j` vor der Schleife und das erhöhen am Ende der Schleife keinen Sinn macht, und das `ADHmin` hier ein Tupel mit zwei Werten darin zugewiesen wird.

Das sieht extrem nach vorhandenen Quelltext nehmen und raten wie man den vielleicht verändern könnte um das gewünschte Ergebnis zu bekommen aus. So funktioniert programmieren nicht! Man muss bei jedem Teilausdruck wissen was der macht und welches Ergebnis und von welchem Typ man erwartet. Denn nur dann kann man gezielt Lösungen entwickeln und Fehler suchen wenn die nicht so funktionieren wie man sich das wünscht in dem man das erwartete Ergebnis mit dem tatsächlichen vergleicht und überlegt warum das abweicht.

Zerlegt die Probleme in Teilprobleme und diese Teilprobleme wieder in kleinere Teilprobleme, solange bis man ein Teilproblem mit wenigen Zeilen Code in einer Funktion lösen kann. Diese Funktion dann schreiben und *testen*. Und aus den getesteten Teillösungen kann man dann grössere Teillösungen zusammensetzen und die auch wieder *testen*. Nicht mit anderen Teilen weitermachen solange die aktuelle Teillösung/Funktion nicht so funktioniert wie sie soll. So kommt man beim Programmieren ans Ziel.

Die Teillösung „den Index des Wertes finden der am nähsten an einem Referenzwert liegt” ist zum Beispiel etwas was in eine Funktion gehört, nicht zuletzt weil Ihr hier ja schon die zweite Anwendung für diese Teillösung habt. Ausserdem dokumentiert man das Programm auch besser wenn da statt ``idx = max(0, bisect(temperatures, reference_temperature) - 1)`` etwas sprechenderes wie ``idx = get_closest_index(temperatures, reference_temperature)`` steht. Ein Leser muss dann an der Stelle nicht unbedingt nachschauen was `bisect()` macht, oder überlegen warum da `max()` verwendet wird. Das solltet *Ihr* aber wissen/erklären können! Denn sonst geht das kopieren und anpassen des Codes ganz offensichtlich schief wenn man überhaupt nicht weiss was der macht und somit auch nicht abschätzen kann was das für Folgen hat wenn man das `max` einfach entfernt. Und die Klammern einfach stehen lässt.
Haze91
User
Beiträge: 12
Registriert: Donnerstag 3. September 2015, 10:17

Tja, das kommt eben dabei raus wenn Biologen ein Programm schreiben müssen. Wir haben den Studienablaufplan nicht geschrieben^^
Wir haben eben wirklich keine Ahnung :K

Soo, wir sind allerdings ein Stück weiter.

Wir haben nin eine Liste mit Werten: [123, 345, 456, 523, 24332, 356]

ein von uns vorher berechneter minimaler und maximaler Wert soll mit denen in der Liste verglichen werden und der Wert welcher dem minimalen und maximalen am nächsten kommt ausgegeben werden.
Beim Verwenden von bisect kommt der Fehler: object of type 'int' has no len()
BlackJack

@Haze91: Beim verwenden von `bisect()` *wie*? Also ich kann das zwar jetzt raten aber es wäre einfacher wenn man auch den Quelltext zum Fehler sehen würde. Schaut euch an was `bisect()` für Argumente verlangt (Wert und Typ) und vergleicht das mit dem was Ihr in eurem Code übergebt. Das stimmt nicht überein.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Haze91 hat geschrieben:Tja, das kommt eben dabei raus wenn Biologen ein Programm schreiben müssen. Wir haben den Studienablaufplan nicht geschrieben^^
Wir haben eben wirklich keine Ahnung :K
Der Hintergrund wird wohl sein, dass man auch als Naturwissenschaftler zumindest oberflächliche Kenntnisse über Algorithmen in Programmiersprachen besitzen sollte. So wie sich einige Studenten relativ ausgiebig in Mathe einarbeiten müssen, so werden du und deine Kommilitonen sich auch in Python einarbeiten müssen, um mal ernsthaft programmiert zu haben.

Übrigens: Nicht selten bestehen Bachelor-Arbeiten von Naturwissenschaftlern teilweise aus Python-Codestücken, weil für das Thema der Arbeit ein kleines Programm geschrieben wurde. Ich kann daher nur an euch appellieren (auch wenn ich selber gerne faul bin): Setzt euch ein paar Tage hin und arbeitet ein paar Python-Grundlagentutorials durch. Andernfalls wird das nichts.
BlackJack

Der Rechner ist heute ein Arbeitsgerät in fast allen Fachrichtungen mit dem Daten verarbeitet werden. Als Wissenschaftler muss man davon ausgehen auch Daten auf eine Art verarbeiten zu müssen die vorher noch kein anderer angewendet hat. Forschung halt. Oder Vorgänge automatisieren statt immer alles von Hand auszurechnen oder auszuwerten. Als Biologe kann man zum Beispiel auch mit Bildverabeitung konfrontiert werden um irgendwelche Pilze oder Bakterien beim wachsen zu überwachen und Eigenschaften dieses Vorgangs automatisiert zu erfassen (Geschwindigkeit, Farbe, Clusterbildung ja/nein, wenn ja wie viele, und so weiter).

Und das ist nicht nur auf Naturwissenschaften beschränkt. Man kann sich beispielsweise auch im Bereich Sprachen mit so etwas wie Parsen von XML-Dateien mit Ontologien, verbinden/verrechnen mit anderen Daten, und der grafischen Aufbereitung als Graph (die mit den Knoten und Kanten, nicht das Zeug was man mit Excel erstellen kann) beschäftigen (müssen).
Benutzeravatar
pixewakb
User
Beiträge: 1405
Registriert: Sonntag 24. April 2011, 19:43

Mal ein Versuch Euer Problem zu lösen.

Code: Alles auswählen

liste = [['26.04.2015', '20', '26', 23.0, 9, 14.0, 336.0, 14, 336],
         ['25.04.2015', '18', '26', 22.0, 9, 13.0, 312.0, 27, 648],
         ['24.04.2015', '18', '25', 21.5, 9, 12.5, 300.0, 39, 948],
         ['23.04.2015', '19', '25', 22.0, 9, 13.0, 312.0, 52, 1260],
         ['22.04.2015', '17', '25', 21.0, 9, 12.0, 288.0, 64, 1548],
         ['21.04.2015', '18', '25', 21.5, 9, 12.5, 300.0, 76, 1848],
         ['20.04.2015', '19', '27', 23.0, 9, 14.0, 336.0, 90, 2184],
         ['19.04.2015', '18', '25', 21.5, 9, 12.5, 300.0, 102, 2484],
         ['18.04.2015', '19', '26', 22.5, 9, 13.5, 324.0, 115, 2808]
         ]

# Ich belege die Variable mal mit dem ersten Wert
# vor, weil ich gegen diesen Wert prüfen möchte
ADHmin = liste[0][-1]

# Ich durchlaufe eure Daten und prüfe jeweils, 
# ob ich einen kleineren Wert gefunden habe
for eintrag in liste:
    letzter_wert = eintrag[-1:][0]
    if letzter_wert < ADHmin:
        ADHmin = letzter_wert

print(ADHmin)
Wenn ich das loswerden darf: Python lernt man sehr schnell. Nehmt ein Online-Tutorial und nutzt erst einmal Idle mit der Konsole und testet dort kleine Code-Schnipsel. Schaut auch mal genau im Netz, denn mein Python-Code-Vokabular ist sehr überschaubar und ich kann damit trotzdem relativ komplexe Probleme lösen, also: erst einmal müsst ihr nicht viel können und obiges Beispiel finde ich nicht anspruchsvoll.

BTW: Googelt mal nach scientific computing und Python, nach iPython (Jupyter), nach pandas usw. Sobald ihr mal große Datenmengen verarbeiten müsst, werdet ihr dankbar sein, wenn ihr etwas Python beherrscht.

Für Euch könnte interessant sein (da ist auch Literatur speziell zu Python für Biologen angegeben):
http://www.ipb.uni-tuebingen.de[...]
BlackJack

@pixewakb: Was hast Du Dir denn bei ``eintrag[-1:][0]`` gedacht? War Dir ``eintrag[-1]`` zu einfach? ;-)

Wobei das ganz nett ist wenn man `min()` mal selber programmiert, aber ich nehme doch lieber die fertige Funktion:

Code: Alles auswählen

In [6]: rows
Out[6]: 
[['26.04.2015', '20', '26', 23.0, 9, 14.0, 336.0, 14, 336],
 ['25.04.2015', '18', '26', 22.0, 9, 13.0, 312.0, 27, 648],
 ['24.04.2015', '18', '25', 21.5, 9, 12.5, 300.0, 39, 948],
 ['23.04.2015', '19', '25', 22.0, 9, 13.0, 312.0, 52, 1260],
 ['22.04.2015', '17', '25', 21.0, 9, 12.0, 288.0, 64, 1548],
 ['21.04.2015', '18', '25', 21.5, 9, 12.5, 300.0, 76, 1848],
 ['20.04.2015', '19', '27', 23.0, 9, 14.0, 336.0, 90, 2184],
 ['19.04.2015', '18', '25', 21.5, 9, 12.5, 300.0, 102, 2484],
 ['18.04.2015', '19', '26', 22.5, 9, 13.5, 324.0, 115, 2808]]

In [7]: min(row[-1] for row in rows)
Out[7]: 336
Allerdings ist das nicht die Aufgabenstellung, sondern wieder den Index finden bei dem ein Wert möglichst Nahe an einem Referenzwert ist.
Benutzeravatar
pixewakb
User
Beiträge: 1405
Registriert: Sonntag 24. April 2011, 19:43

Ohne "[0]" liefert mir das Skript dann folgenden Fehler:

Code: Alles auswählen

TypeError: unorderable types: list() < int()
D. h. der Rückgabewert ist eine Liste mit einem Element anstelle der Zahl (= das Element).

Auf min() wäre ich gekommen, List Comprehensions hier einzusetzen wahrscheinlich spontan nicht:

Code: Alles auswählen

min(row[-1] for row in rows)
Für manche Sachen fehlen mir (immer noch) die Kenntnisse, bestimmte Sachen, die ich gerade dringend brauche, lerne ich dann aber auch mit Hochdruck und anderes lerne ich erst einiges später, wenn ich den konkreten Nutzen für ein Problem brauche. Bei vielen Lösungen mag ich persönlich immer noch gerne Herangehensweisen, die ich gut lesen und mir leicht vorstellen kann und die dann später auch leicht erweiterbar sind.
BlackJack

@pixewakb: Klar, aber das verschiebt die Frage dann nur nach: was hast Du dir beim [-1:] gedacht. ;-)

Das ist übrigens ein Generatorausdruck und keine „list comprehension“ — das heisst da wird keine Liste mit den ganzen Werten als Zwischenergebnis erstellt. `min()` möchte halt irgendetwas „iterierbares“ haben.
Antworten