Skip to content
Snippets Groups Projects
Commit b15e4bf6 authored by Hock, Martin's avatar Hock, Martin
Browse files

Add creation items from datasheets and simple kpi calculation

parent 3bd013da
No related branches found
No related tags found
1 merge request!3Merge to main to create "WS2223" Version
Pipeline #926047 failed
......@@ -5,6 +5,8 @@ from collections import namedtuple
from typing import Dict, List, NamedTuple
import pandas as pd
# pandas is using another dependency called openpyxl
# both need to be installed
COLUMN_FOR_INDEX_IN_EXCEL = 0
......
'''
"""
File consists of several functions for the calculation rules of FAIR Quality KPIs
'''
"""
def test_function():
print("You called the test function.")
def kpi_sum(*args):
return sum(args[0])
# if arguments are handed over not as a list: sum(list(args))
if __name__ == "__main__":
print("This script contains functions for calculating the FAIR Quality KPIs. It is not to be executed independently.")
pass
\ No newline at end of file
print(
"This script contains functions for calculating the FAIR Quality KPIs. It is not to be executed independently."
)
pass
'''
"""
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 Any, Union, Literal, TypedDict, TypeVar, Type, List, Optional, Dict
from typing import List, Dict
import json
......@@ -14,7 +14,8 @@ import json
# - Gute String Darstellung
# - Minimalbeispiel für KPIs
# - Export als GraphViz
# - Erlaube Listen bei add_component und add_assembly ?
# - Zukunft: Erlaube Clone bei Assembly (jede Component muss durch Klon ersetzt werden)
class ComponentCategory(Enum):
BATTERY = auto()
......@@ -33,8 +34,17 @@ class AggregationLayer(Enum):
class LegoComponent:
def __init__(self, name: str, category: ComponentCategory, lego_id: str, cost: float, mass: float,
delivery_time: int, layer: AggregationLayer = AggregationLayer.COMPONENT, **properties) -> None:
def __init__(
self,
name: str,
category: ComponentCategory,
lego_id: str,
cost: float,
mass: float,
delivery_time: int,
layer: AggregationLayer = AggregationLayer.COMPONENT,
**properties,
) -> None:
self.uuid: uuid.UUID = uuid.uuid4()
self.parent: None | LegoAssembly = None
self.name: str = name
......@@ -47,8 +57,16 @@ class LegoComponent:
self.properties: dict = properties
def clone(self) -> LegoComponent:
clone = LegoComponent(self.name, self.category, self.lego_id, self.cost, self.mass, self.delivery_time,
self.layer, **self.properties)
clone = LegoComponent(
self.name,
self.category,
self.lego_id,
self.cost,
self.mass,
self.delivery_time,
self.layer,
**self.properties,
)
return clone
def get_root_assembly(self):
......@@ -60,7 +78,17 @@ class LegoComponent:
return current_assembly
def to_dict(self) -> Dict:
ATTRIBUTES = ["uuid", "name", "category", "lego_id", "cost", "mass", "delivery_time", "layer", "properties"]
ATTRIBUTES = [
"uuid",
"name",
"category",
"lego_id",
"cost",
"mass",
"delivery_time",
"layer",
"properties",
]
dict_ = {}
# store attributes
for attr in ATTRIBUTES:
......@@ -95,26 +123,34 @@ class LegoAssembly:
def add_component(self, component: LegoComponent) -> None:
if not isinstance(component, LegoComponent):
raise TypeError(f"Argument should be of type {LegoComponent.__name__}, "
f"got {type(component).__name__} instead.")
raise TypeError(
f"Argument should be of type {LegoComponent.__name__}, "
f"got {type(component).__name__} instead."
)
if self.get_root_assembly().contains_uuid(component.uuid):
raise AssertionError(f"This assembly or a subassembly already contains the component with ID "
f"{component.uuid}.")
raise AssertionError(
f"This assembly or a subassembly already contains the component with ID "
f"{component.uuid}."
)
component.parent = self
self.components.append(component)
def add_assembly(self, assembly: LegoAssembly) -> None:
if not isinstance(assembly, LegoAssembly):
raise TypeError(f"Argument should be of type {LegoAssembly.__name__}, "
f"got {type(assembly).__name__} instead.")
raise TypeError(
f"Argument should be of type {LegoAssembly.__name__}, "
f"got {type(assembly).__name__} instead."
)
if self.get_root_assembly().contains_uuid(assembly.uuid):
raise AssertionError(f"This assembly or a subassembly already contains the assembly with ID "
f"{assembly.uuid}.")
raise AssertionError(
f"This assembly or a subassembly already contains the assembly with ID "
f"{assembly.uuid}."
)
assembly.parent = self
self.assemblies.append(assembly)
def children(self) -> Dict[str, List[LegoComponent] | List[LegoAssembly]]:
return {'components': self.components, 'assemblies': self.assemblies}
return {"components": self.components, "assemblies": self.assemblies}
def get_component_list(self, max_depth: int = -1) -> List[LegoComponent]:
component_list = []
......
# import standard libraries
import json
import pprint
# import classes from the classes module in functions package
from functions.classes import LegoComponent
from functions.classes import LegoAssembly
......@@ -9,22 +10,24 @@ from functions.classes import AggregationLayer
from functions.classes import KPIEncoder
from functions.classes import print_assembly_tree
# Test manually creating some item and components
from functions.calculation_rules import kpi_sum
# Test manually creating some assemblies and components
battery = LegoComponent("nice battery", ComponentCategory.BATTERY, "bat42", 1, 2, 3)
motor = LegoComponent("motor goes brrr", ComponentCategory.MOTOR, "motor", 1, 2, 3)
wheel = LegoComponent("much round wheel", ComponentCategory.WHEEL, "round", 1, 2, 3)
car = LegoAssembly("Car", AggregationLayer.SYSTEM)
# Create subassemblies and combine to assembly (currently no parts present for this)
chassis = LegoAssembly("Chassis", AggregationLayer.ASSEMBLY)
door1 = LegoAssembly("Door 1", AggregationLayer.SUBASSEMBLY)
door2 = LegoAssembly("Door 2", AggregationLayer.SUBASSEMBLY)
chassis.add_assembly(door1)
chassis.add_assembly(door2)
chassis.properties
engine = LegoAssembly("Engine", AggregationLayer.ASSEMBLY)
# Showcase cloning - one motor for each axis?
engine.add_component(motor.clone())
......@@ -36,11 +39,17 @@ wheels = LegoAssembly("Wheels", AggregationLayer.ASSEMBLY)
for _ in range(4):
wheels.add_component(wheel.clone())
# Create and assemble the system level car
car = LegoAssembly("Car", AggregationLayer.SYSTEM)
car.add_assembly(chassis)
car.add_assembly(engine)
car.add_assembly(fuel_tank)
car.add_assembly(wheels)
## Printing
print_assembly_tree(car)
# Dump to json file
......@@ -49,3 +58,79 @@ with open("car.json", "w") as fp:
pprint.pprint(car.to_dict())
pass
## Create components from datasheet
# Need to run the script from datasheets folder first
# Test loading dicts from datasheet jsons
with open('datasheets/Achsen.json') as json_file:
Achsen = json.load(json_file)
print((Achsen["Achse 5 studs"]))
# This is hard to read, prettier please!
pprint.pprint(Achsen)
# Okay I'll use the 5 stud one
Achse5 = Achsen["Achse 5 studs"] # I'd prefer to call it via "Designnummer"
print(Achsen["Achse 5 studs"]["Designnummer"])
with open('datasheets/Räder.json') as json_file:
Raeder = json.load(json_file)
# Get me the expensive one
Radpreis = []
for key in Raeder: # a list would work easier here than a dict
Radpreis.append(Raeder[key]["Preis [Euro]"])
Radpreis = max(Radpreis)
for key in Raeder:
if Raeder[key]["Preis [Euro]"] == Radpreis:
TeuresRad=Raeder[key]
# Also need a frame
with open('datasheets/Gestell.json') as json_file:
Gestelle = json.load(json_file)
Gestellbeschreibung = "Technic, Brick 1 x 8 with Holes"
Gestell = Gestelle[Gestellbeschreibung]
# Create Components from these items
# LegoComponent(name: str, category: ComponentCategory, lego_id: str, cost: float,
# mass: float, delivery_time: int, layer: AggregationLayer = AggregationLayer.COMPONENT, **properties)
scooterframe = LegoComponent("running board", ComponentCategory.FRAME,
Gestell["Designnummer"],
Gestell["Preis [Euro]"], Gestell["Gewicht [g]"],
0)
scooterwheel = LegoComponent("Vorderrad", ComponentCategory.WHEEL,
TeuresRad["Designnummer"],
TeuresRad["Preis [Euro]"], TeuresRad["Gewicht [g]"],
0)
# Cloning is necessary because each lego object gets a unique id so you can't use the same part twice
scooterwheel2 = scooterwheel.clone()
scooterwheel2.name = "Hinterrad"
print([scooterwheel.uuid, scooterwheel2.uuid])
# Lets Assembly, first the Assembly object, directly add the frame?
scooter = LegoAssembly("my first scooter", AggregationLayer.SYSTEM)
scooter.add_component(scooterframe) # only one per call for now
scooter.add_component(scooterwheel)
scooter.add_component(scooterwheel2)
# <Assembly>.add_assembly() works in the same way
# Look at our work:
print(scooter)
print(scooter.children())
## First KPI mass should be a sum
listofmasses= []
for c in scooter.components:
listofmasses.append(c.mass)
for a in scooter.assemblies:
# only checking one layer deep here
listofmasses.append(a.mass)
print(listofmasses)
print(kpi_sum(listofmasses))
print("theend")
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment