PHP :: Aufgabe #267

1 Lösung Lösung öffentlich

flexible Temperaturumrechnung

Fortgeschrittener - PHP von Gnom - 10.04.2020 um 11:24 Uhr
Gegeben sei ein String-Array mit einer beliebigen Anzahl von Temperaturangaben in °C, °F oder K (z. B. "24,5 °C", "74.3 °F" oder "-270 K"). Dabei sollen unterschiedliche Ausprägungen vorliegen: positive/negative Zahlen, Ganzzahlen/Kommazahlen, Trennung durch Punkt oder Komma, Angaben mit "°" oder ohne, Angabe der Einheit ("K"/"C"/"F", evtl. auch "k"/"c"/"f"), Variationen der Anordnung von Leerzeichen.

Das Programm soll nacheinander alle Strings analysieren und jeweils die Zahl und die Einheit ermitteln und in Variablen speichern, die Temperatur von der gegebenen Einheit in die beiden anderen Einheiten umrechnen und alle drei Werte geordnet mit einer Nachkommastelle ausgeben.

Lösungen:

vote_ok
von Exception (7090 Punkte) - 30.04.2020 um 19:49 Uhr
main.php
Quellcode ausblenden PHP-Code
<?php

require_once 'TemperatureConverter.php';

$values = [ 
  '24,5 °C', '74.3 °F', '-270 K', // upperface + ° 
  '24,5°C', '74.3°F', '-270K', // no space between value and unit
  '24,5 °c', '74.3 °f', '-270 k', // lowercase + ° 
  '24,5 C', '74.3 F', '-270 K', // uppercase
  '24,5 c', '74.3 f', '-270.0 k', // lowercase
  '999.99 UNIT', 'f', '°C' // invalid inputs
];

$results = []; 

foreach ($values as $value) {
  try {
    $results[] = TemperatureConverter::parseValue($value);
  } catch (Exception $ex) {
    $results[] = $ex->getMessage();
  }
}

var_dump($results);


TemperatureConverter.php
Quellcode ausblenden PHP-Code
<?php

final class TemperatureConverter
{
  const TEMPERATURE_PATTERN_VALUE = '/\-?[0-9]+((,|\.)[0-9]+)?/'; 
  const TEMPERATURE_PATTERN_UNIT = '/[kfc]/i'; // i = PCRE_CASELESS

  private function __construct() { }

  public static function parseValue(string $value): array 
  {
    preg_match(self::TEMPERATURE_PATTERN_VALUE, $value, $matchesValue);
    preg_match(self::TEMPERATURE_PATTERN_UNIT, $value, $matchesUnit);

    if (!isset($matchesValue[0]) || !isset($matchesUnit[0])) {
      throw new Exception('Invalid value "' . $value . '".');
    }

    $unit = trim(strtoupper($matchesUnit[0]));
    $valueArray[$unit] = round(floatval(str_replace(',', '.', $matchesValue[0])), 1);

    // we need a celsius value to continue.
    if ($unit !== 'C') {
      $valueArray['C'] = ($unit === 'F') ?
        self::fahrenheitToCelsius($valueArray[$unit]) :
        self::kelvinToCelsius($valueArray[$unit]);
    }

    // what are the remaining temperatures we need to calculate?
    $conversions = array_diff(['C', 'F', 'K'], array_keys($valueArray));

    // calculate the remaining temperatures
    foreach ($conversions as $conversion) {
      switch ($conversion) {
        case 'F':
        $valueArray['F'] = self::celsiusToFahrenheit( $valueArray['C']);
        break;
        case 'K':
        $valueArray['K'] = self::celsiusToKelvin( $valueArray['C']);
        break;
      }
    }

    return $valueArray;
  }

  public static function fahrenheitToCelsius(float $value): float 
  {
    return round(($value - 32.0) * (5/9), 1);
  }

  public static function kelvinToCelsius(float $value): float
  {
    return round($value - 273.15, 1);
  }

  public static function celsiusToKelvin(float $value): float
  {
    return round($value + 273.15, 1);
  }

  public static function celsiusToFahrenheit(float $value): float
  {
    return round(($value * (9/5)) + 32, 1);
  }
}


Konsolenausgabe:

array(18) {
[0]=>
array(3) {
["C"]=>
float(24.5)
["F"]=>
float(76.1)
["K"]=>
float(297.7)
}
[1]=>
array(3) {
["F"]=>
float(74.3)
["C"]=>
float(23.5)
["K"]=>
float(296.7)
}
[2]=>
array(3) {
["K"]=>
float(-270)
["C"]=>
float(-543.2)
["F"]=>
float(-945.8)
}
[3]=>
array(3) {
["C"]=>
float(24.5)
["F"]=>
float(76.1)
["K"]=>
float(297.7)
}
[4]=>
array(3) {
["F"]=>
float(74.3)
["C"]=>
float(23.5)
["K"]=>
float(296.7)
}
[5]=>
array(3) {
["K"]=>
float(-270)
["C"]=>
float(-543.2)
["F"]=>
float(-945.8)
}
[6]=>
array(3) {
["C"]=>
float(24.5)
["F"]=>
float(76.1)
["K"]=>
float(297.7)
}
[7]=>
array(3) {
["F"]=>
float(74.3)
["C"]=>
float(23.5)
["K"]=>
float(296.7)
}
[8]=>
array(3) {
["K"]=>
float(-270)
["C"]=>
float(-543.2)
["F"]=>
float(-945.8)
}
[9]=>
array(3) {
["C"]=>
float(24.5)
["F"]=>
float(76.1)
["K"]=>
float(297.7)
}
[10]=>
array(3) {
["F"]=>
float(74.3)
["C"]=>
float(23.5)
["K"]=>
float(296.7)
}
[11]=>
array(3) {
["K"]=>
float(-270)
["C"]=>
float(-543.2)
["F"]=>
float(-945.8)
}
[12]=>
array(3) {
["C"]=>
float(24.5)
["F"]=>
float(76.1)
["K"]=>
float(297.7)
}
[13]=>
array(3) {
["F"]=>
float(74.3)
["C"]=>
float(23.5)
["K"]=>
float(296.7)
}
[14]=>
array(3) {
["K"]=>
float(-270)
["C"]=>
float(-543.2)
["F"]=>
float(-945.8)
}
[15]=>
string(28) "Invalid value "999.99 UNIT"."
[16]=>
string(18) "Invalid value "f"."
[17]=>
string(20) "Invalid value "°C"."
}
1801060

Du scheinst einen AdBlocker zu nutzen. Ich würde mich freuen, wenn du ihn auf dieser Seite deaktivierst und dich davon überzeugst, dass die Werbung hier nicht störend ist.