Seite 1 von 1

In Schleife vereinfachen

Verfasst: Montag 25. November 2019, 13:09
von Lausemausiii
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

Re: In Schleife vereinfachen

Verfasst: Montag 25. November 2019, 13:28
von Sirius3
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.

Re: In Schleife vereinfachen

Verfasst: Montag 25. November 2019, 13:56
von __blackjack__
@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,
        )

Re: In Schleife vereinfachen

Verfasst: Montag 25. November 2019, 14:29
von Lausemausiii
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.

Re: In Schleife vereinfachen

Verfasst: Montag 25. November 2019, 14:31
von Sirius3
@__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,
        )

Re: In Schleife vereinfachen

Verfasst: Montag 25. November 2019, 15:02
von Lausemausiii
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 :(

Re: In Schleife vereinfachen

Verfasst: Montag 25. November 2019, 15:12
von Lausemausiii
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

Re: In Schleife vereinfachen

Verfasst: Montag 25. November 2019, 15:21
von __blackjack__
@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.