diff --git a/ausarbeitung.ipynb b/ausarbeitung.ipynb
index 854341402f8d55bde092a8f8a27f999393f8272c..51ae5a03012e69a4b0124bf07468ba47dd0d71aa 100644
--- a/ausarbeitung.ipynb
+++ b/ausarbeitung.ipynb
@@ -29,29 +29,140 @@
    ]
   },
   {
+   "attachments": {},
    "cell_type": "markdown",
    "id": "1c702114",
    "metadata": {},
    "source": [
     "## Eigene Module und Minimalbeispiel\n",
-    "Für die Ausarbeitung nutzen wir zwei eigene Module (Python-Skripte), die im Ordner `functions` gespeichert sind.\n",
+    "Für die Ausarbeitung nutzen wir zwei eigene Module (Python-Dateien), die im Ordner `functions` gespeichert sind.\n",
     "Das Modul `calculation_rules` erweitern Sie während der Ausarbeitung. Um die Änderungen zu nutzen, müssen Sie das Notebook neu starten.\n",
+    "Im Modul `classes` befinden sich die  Klassen `LegoComponent, LegoAssembly, AggergationLayer, KPIEncoder` und die Funktion `print_assembly_tree`.\n",
+    "`LegoComponent` bildet einzelne Komponenten ab, während `LegoAssembly` zusammengesetzte Aggregationsebenen abdeckt, also Bauteil, Baugruppe und System. Zur Unterscheidung dient die Klasse Aggregationslayer, diese ist für `LegoComponent` immer `Component`, muss für `LegoAssembly` aber entsprechend auf `SYSTEM, ASSEMBLY` oder `SUBASSEMBLY` gesetzt werden.\n",
     "\n",
-    "Mit einem Minimalbeispiel wird Ihnen gezeigt, wie sie die Module nutzen."
+    "\n",
+    "Mit einem Minimalbeispiel wird Ihnen gezeigt, wie sie die Module nutzen. Dabei wird nur aus Achse, Rahmen und Reifen ein Tretroller gebaut."
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 1,
    "id": "b2778dee",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{'item description': 'Axle 5 studs', 'category': 'axle', 'price [Euro]': 0.001, 'mass [g]': 0.66, 'delivery time [days]': 3, 'Abmessung [studs]': 5}\n",
+      "front axle\n",
+      "{'Abmessung [studs]': 5,\n",
+      " 'category': 'axle',\n",
+      " 'color': 'grey',\n",
+      " 'delivery time [days]': 3,\n",
+      " 'item description': 'Axle 5 studs',\n",
+      " 'mass [g]': 0.66,\n",
+      " 'name': 'front axle',\n",
+      " 'price [Euro]': 0.001}\n"
+     ]
+    }
+   ],
    "source": [
     "# import modules\n",
+    "import json\n",
+    "import pprint\n",
     "from functions import calculation_rules\n",
     "from functions import classes\n",
     "\n",
-    "# TO DO import further modules if necessary\n"
+    "## ## Create the wheels and axles as single components first\n",
+    "# Look up the specific item you want from the provided json files, we can load the full file into a dict\n",
+    "with open('datasheets/axles.json') as json_file:\n",
+    "    axles = json.load(json_file)\n",
+    "# Pick a specific axle via its 'item number'\n",
+    "print(axles['32073'])\n",
+    "\n",
+    "\n",
+    "# Create the component with the dict:\n",
+    "front_axle = classes.LegoComponent('front axle',axles['32073'])\n",
+    "# Both name and the data dict are optional parameters. You can view, add or edit the properties just any dict:\n",
+    "print(front_axle.properties['name'])\n",
+    "front_axle.properties['color']= 'grey'\n",
+    "# Viewing dicts in one line is not easy to read, a better output comes with pretty print (pprint): \n",
+    "pprint.pprint(front_axle.properties)\n",
+    "\n",
+    "# Create the second axle\n",
+    "back_axle = classes.LegoComponent()\n",
+    "back_axle.properties['name'] = 'back axle'\n",
+    "back_axle.properties.update(axles['32073']) \n",
+    "# Do not use = here, otherwise you'd overwrite existing properties.\n",
+    "back_axle.properties['color'] = 'grey'\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "b4a8e8c8",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{'category': 'wheel',\n",
+      " 'color': 'yellow',\n",
+      " 'data source': 'https://www.bricklink.com/v2/catalog/catalogitem.page?P=2903c02#T=C',\n",
+      " 'delivery time [days]': 5,\n",
+      " 'diameter [mm]': 81.6,\n",
+      " 'item description': 'wheel 81,6',\n",
+      " 'mass [g]': 30.0,\n",
+      " 'name': 'front wheel',\n",
+      " 'paint': 'glossy',\n",
+      " 'price [Euro]': 1.31,\n",
+      " 'related items': 2902,\n",
+      " 'surface': 'rough'}\n"
+     ]
+    }
+   ],
+   "source": [
+    "\n",
+    "# Now wheels\n",
+    "with open('datasheets/wheels.json') as json_file:\n",
+    "    wheels = json.load(json_file)\n",
+    "# Adding the color here already as dict, and the surface as key-value argument.\n",
+    "# Multiple of both are supported, but only in this \n",
+    "#front_wheel = classes.LegoComponent('front wheel', wheels['2903'],{'color':'yellow'},winter='true')\n",
+    "\n",
+    "front_wheel = classes.LegoComponent('front wheel', wheels['2903'],surface='rough', paint = 'glossy')\n",
+    "# front_\n",
+    "pprint.pprint(front_wheel.properties)\n",
+    "\n",
+    "# We included a clone function, so you can easily create multiple items:\n",
+    "back_wheel = front_wheel.clone()\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "bd3c7a6b",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "# Also need a frame\n",
+    "with open('datasheets/Gestell.json') as json_file:\n",
+    "    Gestelle = json.load(json_file)\n",
+    "Gestellbeschreibung = \"Technic, Brick 1 x 8 with Holes\"\n",
+    "Gestell = Gestelle[Gestellbeschreibung]"
    ]
   },
   {
@@ -352,7 +463,7 @@
  "metadata": {
   "hide_input": false,
   "kernelspec": {
-   "display_name": "Python 3 (ipykernel)",
+   "display_name": ".venv",
    "language": "python",
    "name": "python3"
   },
@@ -366,7 +477,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.0"
+   "version": "3.11.0"
   },
   "varInspector": {
    "cols": {
@@ -396,6 +507,11 @@
     "_Feature"
    ],
    "window_display": false
+  },
+  "vscode": {
+   "interpreter": {
+    "hash": "386d359a8531ffdc4805ead3a16e7983e89a5ab7bba0cbec0e7ad9597b7a2b64"
+   }
   }
  },
  "nbformat": 4,
diff --git a/functions/classes.py b/functions/classes.py
index 81d0f8b8e8b3ec83b6d2d817473a4ead07042861..309bb8792dd98f01f96373530cdfeaa8b59738cc 100644
--- a/functions/classes.py
+++ b/functions/classes.py
@@ -4,7 +4,7 @@ File consists of several classes for the different elements of a device.
 from __future__ import annotations
 from enum import Enum, auto
 import uuid
-from typing import List, Dict
+from typing import List, Dict, Optional
 import json
 import copy
 import operator
@@ -12,13 +12,27 @@ import operator
 
 # TODO
 # - Docstrings
+# - Beschreibung von Teilen (-> properties) -> Raus aus dem Konstruktor rein in ein dict. (Deep-Copy)
+#   - Erstmal als Shallow Copy umgesetzt, wir verwenden momentan keine nested dicts
 # - Minimalbeispiel für KPIs -> halb umgesetzt -> mit get_components veranschaulichen
 # - Änderungen an Beispiel umsetzen
 
+# -> Integriere AggregationLayer und die Funktionen in die Klassen (evtl. per Vererbung?) -> Nä Semester
+# - Erlaube Listen bei add_component und add_assembly  (-> Nä Semester)
 # - Gute String Darstellung -> Ist so schon ok bisher? -> Nä Semester
 # - Export als GraphViz -> Nä Semeseter
 
 
+
+class ComponentCategory(Enum):
+    BATTERY = auto()
+    MOTOR = auto()
+    FRAME = auto()
+    WHEEL = auto()
+    AXLE = auto()
+    GEAR = auto()
+
+
 class AggregationLayer(Enum):
     SYSTEM = auto()
     ASSEMBLY = auto()
@@ -27,22 +41,31 @@ class AggregationLayer(Enum):
 
 
 class LegoComponent:
-    def __init__(
-            self,
-            label: str,
-            properties: dict,
-            layer: AggregationLayer = AggregationLayer.COMPONENT,
-    ) -> None:
+    def __init__(self, label: Optional[str] = None, datasheet: Optional[dict] = None, *more_properties: dict, **kwargs) -> None:
         self.uuid: uuid.UUID = uuid.uuid4()
         self.parent: None | LegoAssembly = None
-        self.label: str = label
-        self.properties: dict = properties
-        self.layer: AggregationLayer = layer
-
-    def clone(self, new_description: str = None) -> LegoComponent:
-        if new_description is None:
-            new_description = self.label
-        clone = LegoComponent(new_description, copy.deepcopy(self.properties), self.layer)
+        self.layer: AggregationLayer = AggregationLayer.COMPONENT
+        self.properties: dict = {}
+        if label is not None:
+            self.properties['label'] = label
+        if datasheet is not None:
+            self.properties.update(datasheet)
+            self.properties[]
+        for prop in more_properties:
+            if isinstance(prop, dict):
+                self.properties.update(prop)
+            else:
+                raise ValueError(f"Unexpected argument type: {type(more_properties)}")
+        for key, value in kwargs.items():
+            self.properties[key] = value
+
+
+
+
+    def clone(self, new_label: str = None) -> LegoComponent:
+        if new_label is None:
+            new_label = self.properties.label
+        clone = LegoComponent(None, self.properties, label=new_label)
         return clone
 
     def get_root_assembly(self):
@@ -73,16 +96,18 @@ class LegoComponent:
 
     # TODO good repr representation
     def __repr__(self):
-        return f"LegoComponent {self.label} [{self.uuid}]"
+        return f"LegoComponent {self.properties['label']} [{self.uuid}]"
 
 
 class LegoAssembly:
-    def __init__(self, label: str, properties: dict, layer: AggregationLayer) -> None:
+    def __init__(self, layer: AggregationLayer, label: Optional[str] = None, *properties: dict , **kwargs) -> None:
         self.uuid: uuid.UUID = uuid.uuid4()
         self.parent: None | LegoAssembly = None
-        self.label: str = label
-        self.properties: dict = properties
+        self.properties: dict = {}
+        if label is not None:
+            self.properties['label'] = label
         self.layer: AggregationLayer = layer
+        self.properties.update(properties)
         self.components: List[LegoComponent] = []
         self.assemblies: List[LegoAssembly] = []
 
@@ -161,7 +186,6 @@ class LegoAssembly:
     def to_dict(self) -> Dict:
         dict_ = {
             "uuid": self.uuid,
-            "label": self.label,
             "properties": self.properties,
             "layer": self.layer,
         }
@@ -172,7 +196,7 @@ class LegoAssembly:
 
     # TODO find good string representation
     def __repr__(self):
-        return f"LegoAssembly {self.label} [{self.uuid}]"
+        return f"LegoAssembly {self.properties['label']} [{self.uuid}]"
 
     def clone(self, label: str = None) -> LegoAssembly:
         if label is None:
@@ -234,8 +258,8 @@ class KPIEncoder(json.JSONEncoder):
     def default(self, o):
         if isinstance(o, uuid.UUID):
             return "kpi-" + str(o)
-        if isinstance(o, AggregationLayer):
-            return "kpi-" + o.name
+        if isinstance(o, (AggregationLayer)):
+            return "kpi-" + o.properties.label
         return super().default(o)
 
 pass
\ No newline at end of file