In Schleife vereinfachen

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
Lausemausiii
User
Beiträge: 18
Registriert: Sonntag 17. November 2019, 18:52

Hallo,

wie kann ich diese Befehle in einer Schleife verallgemeinern/ vereinfachen?
Bin sehr dankbar auf jede Hilfe....

Code: Alles auswählen

MCAD_ELEMENT=gom.script.primitive.create_line_by_2_points (
	name='Linie 1', 
	point1={'coordinates': list_actual_2 [0][0], 'id': Linie1_id1, 'normal': gom.app.project.inspection['Referenzpunkte'].normal[binarySearch(points2,Linie1_id1)], 'target': gom.app.project.inspection['Referenzpunkte'], 'type': 'coded'}, 
	point2={'coordinates': list_actual_2 [0][1], 'id': Linie1_id2, 'normal': gom.app.project.inspection['Referenzpunkte'].normal[binarySearch(points2,Linie1_id2)] , 'target': gom.app.project.inspection['Referenzpunkte'], 'type': 'coded'})
MCAD_ELEMENT=gom.script.primitive.create_line_by_2_points (
	name='Linie 3', 
	point1={'coordinates': list_actual_2 [1][0], 'id': Linie2_id1, 'normal': gom.app.project.inspection['Referenzpunkte'].normal[binarySearch(points2,Linie2_id1)], 'target': gom.app.project.inspection['Referenzpunkte'], 'type': 'coded'}, 
	point2={'coordinates': list_actual_2 [1][1], 'id': Linie2_id2, 'normal': gom.app.project.inspection['Referenzpunkte'].normal[binarySearch(points2,Linie2_id2)] , 'target': gom.app.project.inspection['Referenzpunkte'], 'type': 'coded'})
MCAD_ELEMENT=gom.script.primitive.create_line_by_2_points (
	name='Linie 5', 
	point1={'coordinates': list_actual_2 [2][0], 'id': Linie3_id1, 'normal': gom.app.project.inspection['Referenzpunkte'].normal[binarySearch(points2,Linie3_id2)], 'target': gom.app.project.inspection['Referenzpunkte'], 'type': 'coded'}, 
	point2={'coordinates': list_actual_2 [2][1], 'id': Linie3_id2, 'normal': gom.app.project.inspection['Referenzpunkte'].normal[binarySearch(points2,Linie3_id1)] , 'target': gom.app.project.inspection['Referenzpunkte'], 'type': 'coded'})
Liebe Grüße
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Als ersten Schritt mußt Du die Unterschiede drei Aufrufe erkennen. Dabei fällt auf, dass der Name eine Zahl enthält, die man entweder aus einem Index ausrechnen könnte, oder als extra Variable zählen könnte. `list_actual_2` enthält einen Index, den man, wenn man das in eine Schleife umbaut nicht mehr braucht, weil man über die Liste direkt iterieren könnte. Dann kommt eine ID, die schlimmerweise eine Nummer im Namen kodiert hat. Da mußt Du also alle Vorkommen von LinieX_id1/2 so umschreiben, dass sie mit einer Liste arbeiten, statt mit einzelnen Variablen.
point1 und point2 sind auch fast identisch, so dass man das Erzeugen des Wörterbuchs in eine Funktion auslagern sollte.

`MCAD_ELEMENT` ist wie eine Konstante geschrieben, sollte also gar nicht mit neuen Werten belegt werden. Der Ausschnitt, den Du zeigst, verwendet den Rückgabewert aber sowieso nicht, so dass der weg kann.

Dass die Variablen ` list_actual_2` und `points2` auch Nummern enthalten, ist ein Indiz, dass da noch mehr zu reparieren ist. Variablennamen sollten aussagekräftig sein, Nummern sind das im Allgemeinen nicht. Grunddatentypen sollten nicht in Namen vorkommen, bleibt also ` actual` übrig, was auch völlig nichtssagend ist, da scheinen ja irgendwelche Koordinaten in dieser Liste zu sein.

LinieX_id und list_actual_2 scheinen auch irgendwie zusammen zu gehören, sollten also in einer Liste stehen, also Koordinaten + ID zusammen in einer passenden Datenstruktur.

Zur Schreibweise allgemein: vor öffnende Klammern von Funktionsaurufen oder Indexzugriff per eckiger Klammer, kommt kein Leerzeichen. Funktionsnamen werden wie Variablennamen klein_mit_unterstrich geschrieben, also binary_search.
Benutzeravatar
__blackjack__
User
Beiträge: 14050
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Lausemausiii: Also erst mal ist `MCAD_ELEMENT` ja offensichtlich mindestens zweimal unnötig weil der Namen einen Wert zugewiesen bekommt, der dann nicht verwendet wird. Die Schreibweise ist auch falsch weil KOMPLETT_GROSS die Konvention für Konstanten ist.

Dann kann man den Teilausdruck ``gom.app.project.inspection['Referenzpunkte']`` ziemlich wahrscheinlich heraus ziehen.

Grunddatentypen haben in Namen nichts verloren. Und bist Du sicher das Du `actual` tatsächliche so nennen willst? Das heisst auf Deutsch nämlich ”tatsächlich” und *nicht* “aktuell“. Letzteres wäre beispielsweise ”current”.

Ansonsten kann man sich einen besseren Überblick verschaffen was in den einzelnen Schritten fest und was variabel ist, wenn man einen einzelnen Schritt mal in eine Funktion auslagert. Also beispielsweise so:

Code: Alles auswählen

def create_line(reference_points, points, name, points_coordinates, point_ids):
    point_a_coordinates, point_b_coordinates = points_coordinates
    point_a_id, point_b_id = point_ids

    gom.script.primitive.create_line_by_2_points(
        name=name,
        point1={
            "coordinates": point_a_coordinates,
            "id": point_a_id,
            "normal": reference_points.normal[
                binary_search(points, point_a_id)
            ],
            "target": reference_points,
            "type": "coded",
        },
        point2={
            "coordinates": point_b_coordinates,
            "id": point_b_id,
            "normal": reference_points.normal[
                binary_search(points, point_b_id)
            ],
            "target": reference_points,
            "type": "coded",
        },
    )
Dann sieht man bei dem was übrig bleibt das/die Muster bei den variablen Anteilen besser:

Code: Alles auswählen

...
    reference_points = gom.app.project.inspection["Referenzpunkte"]
    create_line(
        reference_points,
        points2,
        "Line 1",
        actual_coordinates[0],
        (Linie1_id1, Linie1_id2),
    )
    create_line(
        reference_points,
        points,
        "Linie 3",
        actual_coordinates[1],
        (Linie2_id1, Linie2_id2),
    )
    create_line(
        reference_points,
        points,
        "Linie 5",
        actual_coordinates[2],
        (Linie3_id1, Linie3_id2),
    )
Der Name lässt sich aus einem laufenden Zähler ”errechnen”. Die Punkte sind einfach die Elemente von `actual_points`, und für die IDs müsste man eine Liste erstellen. Das kann man dann in einer Schleife abarbeiten:

Code: Alles auswählen

    ...
    line_ids = [
        (linie1_id1, linie1_id2),
        (linie2_id1, linie2_id2),
        (linie3_id1, linie3_id2),
    ]
    reference_points = gom.app.project.inspection["Referenzpunkte"]
    for i, (line_coordinates, points_ids) in enumerate(
        zip(actual_coordinates, line_ids)
    ):
        create_line(
            reference_points,
            points2,
            f"Line {i * 2 + 1}",
            line_coordinates,
            points_ids,
        )
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Lausemausiii
User
Beiträge: 18
Registriert: Sonntag 17. November 2019, 18:52

Puh... erstmal vielen herzlichen Dank!!

Ich versuch es mal in mein Skript einzubinden... bislang funktioniert es leider noch nicht.

Würde mich dann nocheinmal melden.
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

@__blackjack__: hier würde ich ja itertools.count statt enumerate verwenden:

Code: Alles auswählen

for (i, line_coordinates, points_ids) in zip(count(start=1, step=2), actual_coordinates, line_ids):
        create_line(
            reference_points,
            points2,
            f"Line {i}",
            line_coordinates,
            points_ids,
        )
Lausemausiii
User
Beiträge: 18
Registriert: Sonntag 17. November 2019, 18:52

Es wird mir mit diesem Code immer folgender Fehler angezeigt:

Error in line 43: '<' not supported between instances of 'list' and 'int'

Code: Alles auswählen

#Binäre Suche:
def binarySearch(points, id):
	first = 0
	last = len(points)-1				
	while first<=last:
		mid = (first + last)//2
		current_value, current_id = points[mid]
		if current_id == id:
			return current_value
		if id < current_id:      #Zeile43
			last = mid - 1
		else:
			first = mid +1
	raise KeyError (id)
Kommentier ich den neuen Code aus wird mir die Binäre Suche nicht als Fehler angezeigt :(
Lausemausiii
User
Beiträge: 18
Registriert: Sonntag 17. November 2019, 18:52

Oke der Fehler ist behoben...
muss ich noch irgendwas importieren um die count Funktion verwenden zu können?

-> Error in line 108: name 'count' is not defined
Benutzeravatar
__blackjack__
User
Beiträge: 14050
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Lausemausiii: Ich sehe jetzt nicht wo ich da einen Fehler gemacht haben könnte der *dazu* führt. Die beiden IDs zusammen sind bei mir ein Tupel, und das Tupel wird in der Funktion ja auf zwei einzelne Namen verteilt. Wie kommt `id` denn bei Dir zustande?

`count()` ist aus dem `itertools`-Modul. Steht im Text vom Beitrag von Sirius3.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten