Frage

Lassen Sie uns sagen, dass ich eine Funktion Ich schreibe zwischen Temperaturskalen zu konvertieren. Ich möchte mindestens Celsius, Fahrenheit und Kelvin unterstützen. Ist es besser, die Quelle Skala und Zielskala als separater Parameter der Funktion, oder irgendeine Art von kombinierten Parametern zu übergeben?

Beispiel 1 - separate Parameter: Funktion convertTemperature ( "Celsius", "Fahrenheit", 22)

Beispiel 2 - kombinierte Parameter: convertTemperature Funktion ( "c-f", 22)

Der Code innerhalb der Funktion wahrscheinlich ist, wo es zählt. Mit zwei Parametern, um zu bestimmen, die Logik, welche Formel, die wir verwenden werden ist etwas komplizierter, aber ein einzelner Parameter fühlt sich irgendwie nicht richtig.

Die Gedanken?

War es hilfreich?

Lösung

Gehen Sie mit der ersten Option, sondern als Zeichenketten erlauben (die fehleranfällig sind), nehmen Sie konstante Werte oder eine Aufzählung, wenn Ihre Sprache unterstützt wird, wie folgt aus:

convertTemperature (TempScale.CELSIUS, TempScale.FAHRENHEIT, 22)

Andere Tipps

Abhängig von der Sprache.

Im Allgemeinen würde ich getrennte Argumente mit Aufzählungen verwenden.

Wenn es eine objektorientierte Sprache, dann würde ich eine Temperaturklasse empfehlen, mit der Temperatur intern gespeichert, wie Sie wollen und dann Funktionen zur Ausgabe in welcher Einheit benötigt werden:

temp.celsius (); // gibt die Temperatur des Objekts Temperatur in Grad Celsius

Wenn solche Entwürfe zu schreiben, wie ich mich denken: „Wenn ich brauchte eine zusätzliche Einheit hinzuzufügen, was würde entwerfen wäre es am einfachsten zu machen, dies zu tun?“ Dadurch komme ich zu dem Schluss, dass Aufzählungen am einfachsten aus den folgenden Gründen wären:

1) neue Werte können problemlos hinzugefügt werden. 2) Ich vermeide String-Vergleich tun

Doch wie beurteilen Sie die Konvertierungsmethode schreiben? 3P2 ist 6. Das heißt also, dass es 6 verschiedene Kombinationen von Celsius, Fahrenheit und Kelvin. Was passiert, wenn ich ein neues gemäßigten Format „foo“ hinzufügen wollte? Das würde bedeuten, 4p2, die 12! Zwei mehr? 5P2 = 20-Kombination. Drei mehr? 6p2 = 30 Kombinationen!

Sie können schnell sehen, wie jede weitere Änderung mehr und mehr Änderungen an dem Code erfordert. Aus diesem Grund kann ich tun, keine direkte Conversions! Stattdessen ich tun, um eine Zwischenumwandlung. I eine Temperatur wählen würde, sagen Kelvin. Und zunächst würde ich konvertieren kelvin. Ich würde dann Kelvin auf die gewünschte Temperatur konvertieren. Ja, es ist in einer Extra-Berechnung zur Folge hat. Aber es macht den Code eine Tonne leichter Masstab. Hinzufügen einer neuen Temperatureinheit das Hinzufügen immer in nur zwei neue Änderungen am Code führt. Leicht.

Ein paar Dinge:

  • würde ich einen Aufzählungstyp verwenden, das eine Syntaxprüfung oder Compiler nicht überprüfen kann als eine Zeichenfolge, die falsch eingegeben werden können. In Pseudo-PHP:

    definieren ( 'kCelsius', 0); define ( 'kFarenheit', 1); define ( 'kKelvin', 2); $ A = ConvertTemperature (22, kCelsius, kFarenheit);

Auch scheint es mir natürlicher das, was Sie arbeiten auf zu platzieren, in diesem Fall die Temperatur umgewandelt werden, zuerst . Es gibt eine logische Ordnung in Ihre Parameter (konvertieren? -? Was von bis). Und hilft so mit Mnemotechnik

Ihre Funktion wird wesentlich robuster sein, wenn Sie den ersten Ansatz verwenden. Wenn Sie einen anderen Maßstab hinzufügen müssen, ist, dass man mehr Parameterwert zu behandeln. Im zweiten Ansatz, das Hinzufügen eines weiteren Skala bedeutet, wie viele Werte addiert, wie Sie bereits Skalen auf der Liste hatten, mal 2. (zum Beispiel hinzufügen K C und F, dann würden Sie haben KC, KF, CK hinzuzufügen, und CF).

Eine anständige Art und Weise Ihres Programm zu strukturieren wäre zunächst umwandeln, was auch immer in Zwischen Skala zu einer willkürlich gewählten kommt, und dann von dieser Zwischen Skala zur abgehenden Skala umwandeln.

Eine bessere Möglichkeit, eine kleine Bibliothek von Steigungen und Schnittpunkten für die verschiedenen Skalen haben wäre, und nur die Zahlen für die ein- und ausgehende Skalen nachzuzuschlagen und die Berechnung in einem generischen Schritt zu tun.

In C # (und woanders vermutlich Java) wäre es am besten, eine Temperaturklasse zu schaffen, die Temperaturen privat als Celcius (oder was auch immer) speichert und welches Celcius, Fahrenheit und Kelvin Eigenschaften, die für Sie in ihrem erhält alle Konvertierungen und Set-Anweisungen?

Hängt, wie viele Conversions Sie gehen zu müssen. Ich würde wahrscheinlich einen Parameter wählen, als Enum gegeben. Betrachten Sie diese erweiterte Version der Umwandlung

enum Conversion
{
  CelsiusToFahrenheit,
  FahrenheitToCelsius,
  KilosToPounds
}

Convert(Conversion conversion, X from);

Sie haben nun sane Art Sicherheit am Point of Call - man kann nicht richtig eingegeben Parameter geben, die eine falsche Laufzeit Ergebnis. Betrachten wir die Alternative.

enum Units
{
  Pounds,
  Kilos,
  Celcius,
  Farenheight
}

Convert(Unit from, Unit to, X fromAmount);

Ich kann mit Sicherheit Verbind.typ

Convert(Pounds, Celcius, 5, 10);

Aber das Ergebnis ist sinnlos, und Sie werden zur Laufzeit fehlschlagen haben. Ja, ich weiß, dass du nur mit der Temperatur im Moment zu tun, aber das allgemeine Konzept hält immer noch (glaube ich).

Ich würde wählen

  

Beispiel 1 - separate Parameter: function convertTemperature ( "C", "Fahrenheit", 22)

Ansonsten innerhalb der Funktionsdefinition würden Sie haben „c-f“ in „Celsius“ und „Fahrenheit“ analysieren ohnehin die erforderlichen Umwerteskalen zu bekommen, die chaotisch bekommen.

Wenn Sie so etwas wie die Google-Suchfeld für die Nutzer sind bereitgestellt wird, die handlichen Abkürzungen wie „c-f“ ist für sie schön. Darunter aber, würde ich "c-f" in "Celsius" und "Fahrenheit" in einer äußeren Funktion vor dem Aufruf convertTemperature () konvertieren, wie oben.

In diesem Fall einzelne Parameter sehen völlig dunkel;

Funktion convert Temperatur von eine Skala eine andere Skala .
IMO ist es mehr natürliche Quelle und Zielskalen als separater Parameter zu übergeben. Ich möchte auf jeden Fall nicht versuchen, Format ersten Arguments zu erreichen.

Ich würde eine Aufzählung machen aus den Temperaturtypen und in den 2 Skala Parameter übergeben. So etwas wie (in c #):


public void ConvertTemperature(TemperatureTypeEnum SourceTemp,
                               TemperatureTypeEnum TargetTemp, 
                               decimal Temperature)
{}

Ich bin immer auf der Suche nach Möglichkeiten, Objekte zu verwenden, um meine Programmierprobleme zu lösen. Ich hoffe, das bedeutet, dass ich mehr OO, als wenn ich nur Funktionen, Probleme zu lösen, aber das bleibt abzuwarten.

In C #:

interface ITemperature
{
     CelciusTemperature ToCelcius();
     FarenheitTemperature ToFarenheit();
}

struct FarenheitTemperature : ITemperature
{
    public readonly int Value;
    public FarenheitTemperature(int value)
    {
        this.Value = value;
    }

    public FarenheitTemperature ToFarenheit() { return this; }
    public CelciusTemperature ToCelcius()
    {
        return new CelciusTemperature((this.Value - 32) * 5 / 9);
    }

}

struct CelciusTemperature
{
    public readonly int Value;
    public CelciusTemperature(int value)
    {
        this.Value = value;
    }

    public CelciusTemperature ToCelcius() { return this; }
    public FarenheitTemperature ToFarenheit()
    {
        return new FarenheitTemperature(this.Value * 9 / 5 + 32);
    }
}

und einige Tests:

        // Freezing
        Debug.Assert(new FarenheitTemperature(32).ToCelcius().Equals(new CelciusTemperature(0)));
        Debug.Assert(new CelciusTemperature(0).ToFarenheit().Equals(new FarenheitTemperature(32)));

        // crossover
        Debug.Assert(new FarenheitTemperature(-40).ToCelcius().Equals(new CelciusTemperature(-40)));
        Debug.Assert(new CelciusTemperature(-40).ToFarenheit().Equals(new FarenheitTemperature(-40)));

und ein Beispiel für einen Fehler, dass dieser Ansatz vermeidet:

        CelciusTemperature theOutbackInAMidnightOilSong = new CelciusTemperature(45);
        FarenheitTemperature x = theOutbackInAMidnightOilSong; // ERROR: Cannot implicitly convert type 'CelciusTemperature' to 'FarenheitTemperature'

Konvertierungen Hinzufügen von Kelvin bleibt als Übung.

Übrigens ist es nicht mehr Arbeit haben, um die Drei-Parameter-Version zu implementieren, wie in der Frage Erklärung vorgeschlagen.

Diese sind alle linearen Funktionen, so dass Sie so etwas wie

implementieren
float LinearConvert(float in, float scale, float add, bool invert);

, wo der letzte Bool zeigt an, ob Sie die Vorwärts-Transformation oder umgekehrt, es tun mögen.

Innerhalb der Conversion-Technik können Sie eine Skala haben / add Paar für X -> Kelvin. Wenn Sie eine Anfrage bekommen Format X zu Y konvertieren, können Sie zuerst ausführen X -> Kelvin, dann Kelvin -> Y durch den Y-Umkehr -.> Kelvin Prozess (durch die letzte Bool LinearConvert Spiegeln)

Diese Technik gibt Ihnen etwas wie 4 Zeilen von echtem Code in Ihrer Funktion convert, und ein Stück von Daten für jede Art müssen Sie konvertieren zwischen.

Ähnlich wie @ Rob @wcm und @ David erklärt ...

public class Temperature
{
    private double celcius;

    public static Temperature FromFarenheit(double farenheit)
    {
        return new Temperature { Farhenheit = farenheit };
    }

    public static Temperature FromCelcius(double celcius)
    {
        return new Temperature { Celcius = celcius };
    }

    public static Temperature FromKelvin(double kelvin)
    {
        return new Temperature { Kelvin = kelvin };
    }

    private double kelvinToCelcius(double kelvin)
    {
        return 1; // insert formula here
    }

    private double celciusToKelvin(double celcius)
    {
        return 1; // insert formula here
    }

    private double farhenheitToCelcius(double farhenheit)
    {
        return 1; // insert formula here
    }

    private double celciusToFarenheit(double kelvin)
    {
        return 1; // insert formula here
    }

    public double Kelvin
    {
        get { return celciusToKelvin(celcius); }
        set { celcius = kelvinToCelcius(value); }
    }

    public double Celcius
    {
        get { return celcius; }
        set { celcius = value; }
    }

    public double Farhenheit
    {
        get { return celciusToFarenheit(celcius); }
        set { celcius = farhenheitToCelcius(value); }
    }
}

Ich glaube, ich ganzes Schwein eine oder andere Richtung gehen würde. Sie könnten eine Mini-Sprache schreiben, die jede Art von Konvertierung funktioniert wie Geräte hat:

$ units 'tempF(-40)' tempC
    -40

oder verwenden, um einzelne Funktionen wie die bisherigen Convert :: Temperatur Perl-Modul funktioniert:

use Convert::Temperature;

my $c = new Convert::Temperature();

my $res = $c->from_fahr_to_cel('59');

Aber das bringt einen wichtigen Punkt --- ist die Sprache, die Sie verwenden bereits Konvertierungsfunktionen haben? Wenn ja, welche Codierung Konvention verwenden sie? Wenn also die Sprache C ist, wäre es am besten am Beispiel der atoi und strtod Bibliotheksfunktionen (ungetestet) zu folgen:

double fahrtocel(double tempF){
    return ((tempF-32)*(5/9));
}

double celtofahr(double tempC){
    return ((9/5)*tempC + 32);
}

diesen Beitrag in das Schreiben, lief ich über eine sehr interessanter Beitrag emacs zur Verwendung von Daten zu konvertieren. Der Take-away für dieses Thema ist, dass es den eine Funktion pro Conversion Stil verwendet. Auch Umwandlungen können sehr dunkel sein. Ich neige dazu, Datumsberechnungen zu tun SQL verwenden, da es unwahrscheinlich scheint es in diesem Code viele Fehler sind. In Zukunft werde ich in Emacs suchen.

Hier ist mein nehmen auf diesem (mit PHP):

function Temperature($value, $input, $output)
{
    $value = floatval($value);

    if (isset($input, $output) === true)
    {
        switch ($input)
        {
            case 'K': $value = $value - 273.15; break; // Kelvin
            case 'F': $value = ($value - 32) * (5 / 9); break; // Fahrenheit
            case 'R': $value = ($value - 491.67) * (5 / 9); break; // Rankine
        }

        switch ($output)
        {
            case 'K': $value = $value + 273.15; break; // Kelvin
            case 'F': $value = $value * (9 / 5) + 32; break; // Fahrenheit
            case 'R': $value = ($value + 273.15) * (9 / 5); break; // Rankine
        }
    }

    return $value;
}

Grundsätzlich ist der $input Wert wird auf die Standard-Celsius-Skala umgewandelt und dann umgewandelt wieder zurück in die $output Skala - eine Funktion, sie alle zu regieren. =)

Meine Abstimmung ist zwei Parameter für die Conversion-Typen, einer für den Wert (wie in Ihrem ersten Beispiel). Ich würde Aufzählungen statt Stringliterale jedoch.

Verwenden Sie Aufzählungen, wenn Sie die Sprache erlaubt es, für die Einheit Spezifikationen.

würde ich den Code sagen innen würde mit zwei einfacher sein. Ich würde eine Tabelle mit Pre-Add, multiplty und post hinzufügen und den Wert durch das Element für eine Einheit ausgeführt werden, und dann durch das Element für das andere Gerät in umgekehrter Reihenfolge. Grundsätzlich Umwandeln die Eingangstemperatur auf einen gemeinsamen Grundwert nach innen, und dann, um die anderen Einheit. Diese ganze Funktion wäre tabellengesteuert.

Ich wünsche es eine Möglichkeit, mehrere Antworten zu akzeptieren war. Basierend auf allen Empfehlungen, ich glaube, ich mit den mehreren Parametern kleben, die Saiten zu Aufzählungen / Konstanten ändern, und bewegen Sie den Wert in die erste Position in der Parameterliste umgewandelt werden. Innerhalb der Funktion, werde ich Kelvin als gemeinsamen Mittelweg verwenden.

Vorher hatte ich für jede Konvertierung einzelne Funktionen geschrieben und die Gesamt convertTemperature () Funktion war lediglich ein Wrapper mit verschachtelten Switch-Anweisungen. Ich bin sowohl in klassischen ASP und PHP zu schreiben, aber ich wollte die Frage offen für jede Sprache verlassen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top