Files

128 lines
3.7 KiB
C#

namespace Ch2Weather;
public record struct WeatherRecord(double Temperature, double Humidity, double Pressure);
public interface IWeatherSubject {
void Subscribe(IWeatherObserver o);
void Unsubscribe(IWeatherObserver o);
void NotifyObservers();
}
public interface IWeatherObserver {
void Update(WeatherRecord wr);
}
public interface IWeatherDisplay {
void Display();
}
public class WeatherData(WeatherRecord weatherRecord) : IWeatherSubject {
private readonly List<IWeatherObserver> _observers = [];
private WeatherRecord _weatherRecord = weatherRecord;
public WeatherRecord WeatherRecord {
get => _weatherRecord;
set {
_weatherRecord = value;
NotifyObservers();
}
}
public void Subscribe(IWeatherObserver o) {
_observers.Add(o);
}
public void Unsubscribe(IWeatherObserver o) {
_observers.Remove(o);
}
public void NotifyObservers() {
foreach (var o in _observers) {
o.Update(_weatherRecord);
}
}
}
public class CurrentConditionsDisplay : IWeatherObserver, IWeatherDisplay {
private IWeatherSubject _subject;
private double _temperature = 0;
private double _humidity = 0;
public CurrentConditionsDisplay(IWeatherSubject subject) {
_subject = subject;
subject.Subscribe(this);
}
public void Update(WeatherRecord wr) {
_temperature = wr.Temperature;
_humidity = wr.Humidity;
Display();
}
public void Display() {
Console.WriteLine($"Current conditions: {_temperature}C degrees and {_humidity}% humidity.");
}
}
public class HeatIndexDisplay : IWeatherObserver, IWeatherDisplay {
private IWeatherSubject _subject;
private WeatherRecord _weatherRecord = new WeatherRecord(0,0,0);
public HeatIndexDisplay(IWeatherSubject subject) {
_subject = subject;
subject.Subscribe(this);
}
private double ComputeHeatIndex(double t, double rh) {
return (16.923 + (0.185212 * t) + (5.37941 * rh) - (0.100254 * t * rh) +
(0.00941695 * (t * t)) + (0.00728898 * (rh * rh)) +
(0.000345372 * (t * t * rh)) - (0.000814971 * (t * rh * rh)) +
(0.0000102102 * (t * t * rh * rh)) - (0.000038646 * (t * t * t)) + (0.0000291583 *
(rh * rh * rh)) + (0.00000142721 * (t * t * t * rh)) +
(0.000000197483 * (t * rh * rh * rh)) - (0.0000000218429 * (t * t * t * rh * rh)) +
0.000000000843296 * (t * t * rh * rh * rh)) -
(0.0000000000481975 * (t * t * t * rh * rh * rh));
}
public void Update(WeatherRecord wr) {
_weatherRecord = wr;
Display();
}
public void Display() {
var heatIndex = ComputeHeatIndex(_weatherRecord.Temperature, _weatherRecord.Humidity);
Console.WriteLine($"Heat Index is {heatIndex}");
}
}
public class TemperatureStatsDisplay : IWeatherObserver, IWeatherDisplay {
private IWeatherSubject _subject;
private double _n = 0;
private double _avg = 0;
private double _min = 0;
private double _max = 0;
public TemperatureStatsDisplay(IWeatherSubject subject) {
_subject = subject;
subject.Subscribe(this);
}
public void Update(WeatherRecord wr) {
var temp = wr.Temperature;
if (_n == 0) {
_n = 1;
_avg = temp;
_min = temp;
_max = temp;
} else {
_min = double.Min(_min, temp);
_max = double.Max(_max, temp);
_avg = (_avg * _n + temp) / (_n + 1);
_n += 1;
}
Display();
}
public void Display() {
Console.WriteLine($"Avg/Max/Min Temperature: {_avg}/{_max}/{_min}");
}
}