Objekte aus Liste an bestimmte Stelle in string schreiben

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
Ekua
User
Beiträge: 10
Registriert: Freitag 26. Juni 2020, 09:53

Hallo zusammen,
ich habe mir eine Klasse Fluid geschrieben, die aus einer Liste von Fluidbestandteilen und deren Konzentrationen einen String des Fluids ausgibt. Mit diesem String kann ich dann die Stoffwerte des Fluids über PropsSI zb berechnen lassen.
Bisher habe ich die Möglichkeit ein bis vier Fluidbestandteile vorzugeben und das über eine if else Schleife geregelt.

<code>
class Fluid: # Creation of fluid
def __init__(self, library, component1, x1, component2='', x2=0, component3='',x3=0, component4='', x4=0):
# input 2 - max 4 fluid components with belonging concentration
"""library: TYPE
substance database (Coolprop or Refprop)
"""
self.lib = library
self.component1 = component1 #component 1
self.x1 = x1 #belonging concentration
self.component2 = component2 #component 2
self.x2 = x2 #belonging concentration
self.component3 = component3 #component 3
self.x3 = x3 #belonging concentration
self.component4 = component4 #component 4
self.x4 = x4 #belonging concentration


def composition(self):

if self.lib == "Refprop":
lib = 'REFPROP::'
elif self.lib == 'Coolprop':
lib = ''

if self.x2 == 0 and self.x3 == 0 and self.x4 == 0:
fluid = lib+self.component1
elif self.x3 == 0 and self.x4 == 0:
fluid = lib+self.component1 +'[' +str(self.x1) +']&'+self.component2+'['+str(self.x2)+']'
elif self.x4 == 0:
fluid = lib+self.component1 +'[' +str(self.x1) +']&'+self.component2+'['+str(self.x2)+']&'+self.component3+'['+str(self.x3)+']'
else:
fluid =lib+self.component1+'['+str(self.x1)+']&'+self.component2+'['+str(self.x2)+']&'+self.component3+'['+str(self.x3)+']&'+self.component4+'['+str(self.x4)+']'

return fluid
</code>

Jetzt frage ich mich ob es möglich ist, das ganze auf eine unbegrenzte/unbekannte Anzahl an Bestandteilen zu erweitern. Ich dachte dann an eine for Schleife?! Dafür würde ich dem Fluid dann eine Liste mit den Konzentrationen und Bestandteilen statt einzeln Bestandteil und Konzentration übergeben. Aber wie schaffe ich es den Ausdruck fluid=... so zu verändern, dass das funktioniert? Ich möchte dann quasi so lange bis keine Elemente mehr in der Liste sind immer mit den notwendigen Stringunterbrechungen die Werte in den Ausdruck schreiben. Gibt es dafür eine Möglichkeit?
Ich hoffe ich habe mich verständlich ausgedrückt.
Danke schonmal!
Sirius3
User
Beiträge: 18255
Registriert: Sonntag 21. Oktober 2012, 17:20

Es gibt keine if-Schleifen. Statt Variablen durchzunummerieren, solltest Du Listen verwenden. Und zwar eine Liste mit Tupeln aus Komponente und Konzentration. Wobei x ein sehr schlechter Variablenname für eine Konzentration ist.
Benutze auch sonst keine Abkürzungen. lib -> library.
Der Kommentar `Creation of fluid` ist falsch, weil da ja gar kein fluid erzeugt wird, sondern nur die Klasse dazu definiert.
Wenn Du mindestens zwei Komponenten forderst, warum hat das zweite dann schon Defaultwerte?
Um eine Klasse in einen String zu verwandeln, definiert man die Methode __str__.
Strings setzt man nicht mit + zusammen, sondern benutzt Formatstrings. Zum Zusammensetzen von vielen Strings gibt es str.join.

Code: Alles auswählen

class Fluid:
    def __init__(self, library, components):
        """
        library: substance database (Coolprop or Refprop)
        components: iterable of tuples with component name and concentration
        """
        if library not in ("Refprop", "Coolprop"):
            raise ValueError("library must be one of 'Refprop' or 'Coolprop'")
        self.library = library
        self.components = list(components)
            
    def composition(self):
        prefix = {
            "Refprop": 'REFPROP::',
            'Coolprop': '',
        }[self.library]
        if len(self.components) == 1:
            return f"{prefix}{self.components[0]}"
        return "&".join(
            f"{name}[{concentration}]"
            for name, concentration in self.components
        )
    __str__ = composition
Benutzeravatar
__blackjack__
User
Beiträge: 14013
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

`library` könnte ein Kandidat für das `enum`-Modul aus der Standardbibliothek sein. Und wenn man dann noch das externe `attr`-Modul dazu nimmt, könnte es so aussehen:

Code: Alles auswählen

#!/usr/bin/env python3
from enum import auto, Enum

from attr import attrib, attrs


class Library(Enum):
    REFPROP = auto()
    COOLPROP = auto()


@attrs
class Fluid:
    library = attrib()
    components = attrib()

    def __str__(self):
        prefix = {Library.REFPROP: "REFPROP::", Library.COOLPROP: ""}[
            self.library
        ]
        if len(self.components) == 1:
            return f"{prefix}{self.components[0]}"

        return prefix + "&".join(
            f"{name}[{concentration}]"
            for name, concentration in self.components
        )

    composition = __str__
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Ekua
User
Beiträge: 10
Registriert: Freitag 26. Juni 2020, 09:53

danke euch beiden! Das war sehr hilfreich!
Antworten