"Die folgende Abbildung zeigt den Versuchsaufbau des Minimalbeispiels in LeoCAD. Die transparenten Bauteile sind dabei nicht Teil des hier erläuterten Zusammenbaus, können aber mit dem zur Verfügung gestellten Baukasten ergänzt werden:"
]
},
{
"cell_type": "markdown",
"id": "2f969ed9",
"metadata": {},
"source": [
""
"Die folgende Abbildung zeigt den Versuchsaufbau des Minimalbeispiels in LeoCAD. Die transparenten Bauteile sind dabei nicht Teil des hier erläuterten Zusammenbaus, können aber mit dem zur Verfügung gestellten Baukasten ergänzt werden:\n",
""
"File \u001b[1;32mc:\\Users\\Lamm\\Documents\\02_Areas\\Praktikum_Digitalisierung\\01_quality-kpi_dev\\functions\\classes.py:374\u001b[0m, in \u001b[0;36mLegoAssembly.add\u001b[1;34m(self, part)\u001b[0m\n\u001b[0;32m 372\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(part, \u001b[38;5;28mlist\u001b[39m):\n\u001b[0;32m 373\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m p \u001b[38;5;129;01min\u001b[39;00m part:\n\u001b[1;32m--> 374\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43madd\u001b[49m\u001b[43m(\u001b[49m\u001b[43mp\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 375\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 376\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\n\u001b[0;32m 377\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mArgument should be of types \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mLegoAssembly\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m, \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 378\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mLegoComponent\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m or a list of them. \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 379\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGot \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mtype\u001b[39m(part)\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m instead.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 380\u001b[0m )\n",
"File \u001b[1;32mc:\\Users\\Lamm\\Documents\\02_Areas\\Praktikum_Digitalisierung\\01_quality-kpi_dev\\functions\\classes.py:369\u001b[0m, in \u001b[0;36mLegoAssembly.add\u001b[1;34m(self, part)\u001b[0m\n\u001b[0;32m 356\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 357\u001b[0m \u001b[38;5;124;03mAdds either a Lego component, a subassembly or a (mixed) list of them to the\u001b[39;00m\n\u001b[0;32m 358\u001b[0m \u001b[38;5;124;03mcurrent assembly. Uses internal functions add_component() and add_assembly().\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 366\u001b[0m \u001b[38;5;124;03m instance, or a (mixed) list of them.\u001b[39;00m\n\u001b[0;32m 367\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 368\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(part, LegoComponent):\n\u001b[1;32m--> 369\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43madd_component\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpart\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 370\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(part, LegoAssembly):\n\u001b[0;32m 371\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39madd_assembly(part)\n",
"File \u001b[1;32mc:\\Users\\Lamm\\Documents\\02_Areas\\Praktikum_Digitalisierung\\01_quality-kpi_dev\\functions\\classes.py:310\u001b[0m, in \u001b[0;36mLegoAssembly.add_component\u001b[1;34m(self, component)\u001b[0m\n\u001b[0;32m 304\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(component, LegoComponent):\n\u001b[0;32m 305\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\n\u001b[0;32m 306\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mArgument should be of type \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mLegoComponent\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m, \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 307\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mgot \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mtype\u001b[39m(component)\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m instead.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 308\u001b[0m )\n\u001b[1;32m--> 310\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_root_assembly\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39mcontains_uuid(component\u001b[38;5;241m.\u001b[39m_uuid):\n\u001b[0;32m 311\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mAssertionError\u001b[39;00m(\n\u001b[0;32m 312\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThis assembly or a subassembly already contains \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 313\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mthe component with ID \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 314\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mcomponent\u001b[38;5;241m.\u001b[39m_uuid\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 315\u001b[0m )\n\u001b[0;32m 316\u001b[0m component\u001b[38;5;241m.\u001b[39m_parent \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\n",
"File \u001b[1;32mc:\\Users\\Lamm\\Documents\\02_Areas\\Praktikum_Digitalisierung\\01_quality-kpi_dev\\functions\\classes.py:439\u001b[0m, in \u001b[0;36mLegoAssembly.get_root_assembly\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 431\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 432\u001b[0m \u001b[38;5;124;03mReturns the root LegoAssembly of the current assembly by recursively\u001b[39;00m\n\u001b[0;32m 433\u001b[0m \u001b[38;5;124;03msearching up the tree until the top-most parent (the root) is found.\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 436\u001b[0m \u001b[38;5;124;03m The root LegoAssembly of the current LegoAssembly instance.\u001b[39;00m\n\u001b[0;32m 437\u001b[0m \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[0;32m 438\u001b[0m current_assembly \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\n\u001b[1;32m--> 439\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m current_assembly\u001b[38;5;241m.\u001b[39m_parent \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 440\u001b[0m current_assembly \u001b[38;5;241m=\u001b[39m current_assembly\u001b[38;5;241m.\u001b[39m_parent\n\u001b[0;32m 441\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m current_assembly\n",
"\u001b[1;31mKeyboardInterrupt\u001b[0m: "
]
}
],
...
...
@@ -218,7 +231,7 @@
" assembly_method=\"stick together like lego blocks\",\n",
")\n",
"# Add LegoComponents to the LegoAssembly, single or as list\n",
FAIRe Qualitäts-KPIs schaffen eine transparente und nachvollziehbare Entscheidungsgrundlage. In dieser Lerneinheit sollen sie die Methodik erlernen, indem sie LEGO-Autos zusammenbauen, deren Quality KPIs bestimmen und miteinander vergleichen.
### Werkzeug für den Zusammenbau
Der Zusammenbau der Autos erfolgt virtuell. Als Werkzeug steht Ihnen das Modul `classes` zur Verfügung. In diesem sind unterschiedliche Klassen und Methoden implementiert (Objektorientierung). Sie erzeugen jeweils Objekte der Klassen. Ein Objekt ist dabei die virtuelle Abbildung eines realen Bauteiles. Die Eigenschaften des Bauteiles werden über die Eigenschaften des Objektes abgebildet.
### Berechnung der Quality KPIs
KPIs (Key Performance Indikatoren) sind Kenngrößen des Systems. Sie werden über Berechnungsvorschriften bestimmt. Diese Berechnungsvorschriften sind von Ihnen als python-Funktionen im Modul `calculation_rules` zu implementieren.
### Datenblätter
Für den Zusammenbau stehen Ihnen verschiedene Bauteile in unterschiedlichen Ausführungen zur Verfügung. Sie nutzen die Datenblätter, die als `json-Dateien` zur Verfügung gestellt werden, um Ihre Autos zusammenzubauen.
%% Cell type:markdown id:1c702114 tags:
## Eigene Module und Minimalbeispiel
Für die Ausarbeitung nutzen wir zwei eigene Module (Python-Dateien), die im Ordner `functions` gespeichert sind.
Das Modul `calculation_rules` erweitern Sie während der Ausarbeitung. Um die Änderungen zu nutzen, müssen Sie das Notebook neu starten.
Im Modul `classes` befinden sich die komplette Klassen und Funktionen zur Verwendung.
Mit einem Minimalbeispiel wird Ihnen gezeigt, wie sie die Module nutzen.
%% Cell type:markdown id:670118b3 tags:
#### Versuchsaufbau:
Die folgende Abbildung zeigt den Versuchsaufbau des Minimalbeispiels in LeoCAD. Die transparenten Bauteile sind dabei nicht Teil des hier erläuterten Zusammenbaus, können aber mit dem zur Verfügung gestellten Baukasten ergänzt werden:
%% Cell type:markdown id:2f969ed9 tags:


%% Cell type:markdown id:6d3310be tags:
### Modul classes
Enthält `LegoComponent, LegoAssembly, AggregationLayer, KPIEncoder` und die Funktion `print_assembly_tree`.
`LegoComponent` bildet einzelne Komponenten ab, während `LegoAssembly` zusammengesetzte Aggregationsebenen abdeckt, also Bauteil, Baugruppe und System. Zur Unterscheidung dient die Klasse `AggregationLayer`, diese ist für `LegoComponent` immer `Component` (Komponente), muss für `LegoAssembly` entsprechend auf `SYSTEM` (System) , `ASSEMBLY` (Baugruppe) oder `SUBASSEMBLY` (Bauteil) gesetzt werden.
Wir bauen aus Achse, Rahmen und Reifen einen Tretroller zusammen.
%% Cell type:code id:b2778dee tags:
``` python
# import modules
importjson
importpprint
fromfunctionsimportcalculation_rules
# Importing all modules one by one to provide an overview
# The next commented line would provide the same result in one line
# from functions.classes import *
fromfunctions.classesimportLegoComponent
fromfunctions.classesimportLegoAssembly
fromfunctions.classesimportAggregationLayer
fromfunctions.classesimportKPIEncoder
fromfunctions.classesimportprint_assembly_tree
# When you are writing code yourself later, you might want to copy
# these imports to avoid rerunning the full notebook after restart
```
%% Cell type:code id:0b1f9aff tags:
``` python
# Create the wheels and axles as single components first
# Look up the specific item you want from the provided json files,
File c:\Users\Lamm\Documents\02_Areas\Praktikum_Digitalisierung\01_quality-kpi_dev\functions\classes.py:374, in LegoAssembly.add(self, part)
372 elif isinstance(part, list):
373 for p in part:
--> 374 self.add(p)
375 else:
376 raise TypeError(
377 f"Argument should be of types {LegoAssembly.__name__}, "
378 f"{LegoComponent.__name__} or a list of them. "
379 f"Got {type(part).__name__} instead."
380 )
File c:\Users\Lamm\Documents\02_Areas\Praktikum_Digitalisierung\01_quality-kpi_dev\functions\classes.py:369, in LegoAssembly.add(self, part)
356 """
357 Adds either a Lego component, a subassembly or a (mixed) list of them to the
358 current assembly. Uses internal functions add_component() and add_assembly().
(...)
366 instance, or a (mixed) list of them.
367 """
368 if isinstance(part, LegoComponent):
--> 369 self.add_component(part)
370 elif isinstance(part, LegoAssembly):
371 self.add_assembly(part)
File c:\Users\Lamm\Documents\02_Areas\Praktikum_Digitalisierung\01_quality-kpi_dev\functions\classes.py:310, in LegoAssembly.add_component(self, component)
304 if not isinstance(component, LegoComponent):
305 raise TypeError(
306 f"Argument should be of type {LegoComponent.__name__}, "
307 f"got {type(component).__name__} instead."
308 )
--> 310 if self.get_root_assembly().contains_uuid(component._uuid):
311 raise AssertionError(
312 f"This assembly or a subassembly already contains "
313 f"the component with ID "
314 f"{component._uuid}."
315 )
316 component._parent = self
File c:\Users\Lamm\Documents\02_Areas\Praktikum_Digitalisierung\01_quality-kpi_dev\functions\classes.py:439, in LegoAssembly.get_root_assembly(self)
431 """
432 Returns the root LegoAssembly of the current assembly by recursively
433 searching up the tree until the top-most parent (the root) is found.
(...)
436 The root LegoAssembly of the current LegoAssembly instance.
437 """
438 current_assembly = self
--> 439 while current_assembly._parent is not None:
[LegoComponent scooter frame [a90b291e-696c-41c7-b9b8-43d34724b460], LegoComponent front wheel [b03ce5b5-9c6c-4315-a67b-902c729c3d7b], LegoComponent front axle [64771daf-733a-4a2a-8520-9fa94259e50e], LegoComponent back wheel [8fcb7db9-6fec-4e70-b274-0c4fe403550b], LegoComponent back axle [2ce57b96-64b8-48b1-aac8-b0731adaa93b]]
%% Cell type:markdown id:001f1c77 tags:
### Modul calculation_rules
Um für unser System "Tretroller" einen KPI zu erzeugen, wird die Masse des Systems betrachtet. Die Masse der einzelnen Komponenten ist in den Datenblättern unter `mass [g]` enthalten.
In dieser exportierten json-Datei ('scooter.json') sind die Werte maschinen- und menschenlesbar hinterlegt.
Zusammen mit der Berechnungsvorschrift in `calculation_rules` ist auch die Entstehung des KPI nachvollziehbar und wiederverwendbar dokumentiert und damit 'FAIR'.