Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- %%%-------------------------------------------------------------------
- %%% @author user
- %%% @copyright (C) 2018, <COMPANY>
- %%% @doc
- %%%
- %%% @end
- %%% Created : 16. kwi 2018 14:02
- %%%-------------------------------------------------------------------
- -module(pollution_server).
- -author("user").
- %% API
- -export([createMonitor/0,
- addStation/2,
- addValue/4,
- getStationMean/2,
- removeValue/3,
- getOneValue/3,
- getDailyMean/2,
- getHourlyMean/3,
- getHighestHour/1,
- start/0,
- finish/0,
- init/0
- ]).
- -include_lib("eunit/include/eunit.hrl").
- start() ->
- register(pollutionServer, spawn(?MODULE, init, [])).
- init() ->
- loop(createMonitor()).
- loop(Monitor) ->
- receive
- {request, Pid, addStation, Name, Coordinates} ->
- {reply, Status, Data} = addStation_(Name, Coordinates, Monitor),
- case Status of
- error -> Pid ! {reply, error, Data},
- loop(Monitor);
- ok -> Pid ! {reply, ok},
- loop(Data)
- end;
- {request, Pid, addValue, Name, Date, Type, Value} when is_list(Name) ->
- {reply, Status, Data} = addValue_(Name, Date, Type, Value, Monitor),
- case Status of
- error -> Pid ! {reply, error, Data},
- loop(Monitor);
- ok -> Pid ! {reply, ok},
- loop(Data)
- end;
- {request, Pid, addValue, {X, Y}, Date, Type, Value} ->
- {reply, Status, Data} = addValue_({X, Y}, Date, Type, Value, Monitor),
- case Status of
- error -> Pid ! {reply, error, Data},
- loop(Monitor);
- ok -> Pid ! {reply, ok},
- loop(Data)
- end;
- {request, Pid, removeValue, Name, Date, Type} when is_list(Name) ->
- {reply, Status, Data} = removeValue_(Name, Date, Type, Monitor),
- case Status of
- error -> Pid ! {reply, error, Data},
- loop(Monitor);
- ok -> Pid ! {reply, ok},
- loop(Data)
- end;
- {request, Pid, removeValue, {X, Y}, Date, Type} ->
- {reply, Status, Data} = removeValue_({X, Y}, Date, Type, Monitor),
- case Status of
- error -> Pid ! {reply, error, Data},
- loop(Monitor);
- ok -> Pid ! {reply, ok},
- loop(Data)
- end;
- {request, Pid, getOneValue, Name, Date, Type} when is_list(Name) ->
- Pid ! getOneValue_(Name, Date, Type, Monitor),
- loop(Monitor);
- {request, Pid, getOneValue, {X, Y}, Date, Type} ->
- Pid ! getOneValue_({X, Y}, Date, Type, Monitor),
- loop(Monitor);
- {request, Pid, getStationMean, Name, Type} when is_list(Name) ->
- Pid ! getStationMean_(Name, Type, Monitor),
- loop(Monitor);
- {request, Pid, getStationMean, {X, Y}, Type} ->
- Pid ! getStationMean_({X, Y}, Type, Monitor),
- loop(Monitor);
- {request, Pid, getDailyMean, Date, Type} ->
- Pid ! getDailyMean_(Date, Type, Monitor),
- loop(Monitor);
- {request, Pid, getHourlyMean, Name, Hour, Type} ->
- Pid ! getHourlyMean_(Name, Hour, Type, Monitor),
- loop(Monitor);
- {request, Pid, getHighestHour, Type} ->
- Pid ! getHighestHour_(Type, Monitor),
- loop(Monitor);
- {request, Pid, stop} ->
- Pid ! {reply, ok};
- _ -> c:flush()
- end.
- finish() ->
- pollutionServer ! {request, self(), stop}.
- createMonitor() -> #{stations => [], measurements => []}.
- addStation_(Name, Coordinates, Monitor) ->
- case lists:keymember(Name, 1, maps:get(stations, Monitor)) or
- lists:keymember(Coordinates, 2, maps:get(stations, Monitor)) of
- false -> {reply, ok, maps:update(stations, maps:get(stations, Monitor) ++ [{Name, Coordinates}], Monitor)};
- _ -> {reply, error, io_lib:format("There already exists a station with name ~s or coordinates ~w.~n", [Name, Coordinates])}
- end.
- addValue_(Name, Date, Type, Value, Monitor) when is_list(Name) ->
- case [StationNameGet || {StationNameGet, _} <- maps:get(stations, Monitor), StationNameGet == Name] of
- [] -> {reply, error, io_lib:format("The station ~s doesn't exist.~n", [Name])};
- _ -> case [MeasurementGet || MeasurementGet = {NameGet, DateGet, TypeGet, _} <- maps:get(measurements, Monitor),
- NameGet == Name, Date == DateGet, TypeGet == Type] of
- [] -> {reply, ok, maps:update(measurements,
- maps:get(measurements, Monitor) ++ [{Name, Date, Type, Value}], Monitor)};
- _ -> {reply, error, io_lib:format("The measurement ~w has already been registered within station ~s.~n",
- [{Date, Type, Value}, Name])}
- end
- end;
- addValue_({X, Y}, Date, Type, Value, Monitor) ->
- case lists:keysearch({X, Y}, 2, maps:get(stations, Monitor)) of
- {value, Station} -> {Name, _} = Station,
- case [NameGet || {NameGet, DateGet, TypeGet, _} <- maps:get(measurements, Monitor),
- NameGet == Name, DateGet == Date, TypeGet == Type] of
- [] -> {reply, ok, maps:update(measurements,
- maps:get(measurements, Monitor) ++ [{Name, Date, Type, Value}], Monitor)};
- _ -> {reply, error, io_lib:format("The measurement ~w has already been registered within station ~s.~n",
- [{Date, Type, Value}, Name])}
- end;
- _ -> {reply, error, io_lib:format("The station with coordinates ~w doesn't exist.~n", [{X, Y}])}
- end.
- removeValue_(Name, Date, Type, Monitor) when is_list(Name) ->
- case [StationNameGet || {StationNameGet, _} <- maps:get(stations, Monitor), StationNameGet == Name] of
- [] -> {reply, error, io_lib:format("The station ~s doesn't exist.~n", [Name])};
- _ -> case [MeasurementGet || MeasurementGet = {NameGet, DateGet, TypeGet, _} <-
- maps:get(measurements, Monitor), NameGet == Name, DateGet == Date, TypeGet == Type] of
- [] -> {reply, error, io_lib:format("The measurement with specified parameters ~w doesn't exist in station ~s.~n",
- [{Date, Type}, Name])};
- [{NameGet, DateGet, TypeGet, ValueGet}] -> {reply, ok, maps:update(measurements,
- lists:delete({NameGet, DateGet, TypeGet, ValueGet}, maps:get(measurements, Monitor)), Monitor)}
- end
- end;
- removeValue_({X, Y}, Date, Type, Monitor) ->
- case lists:keysearch({X, Y}, 2, maps:get(stations, Monitor)) of
- {value, Station} -> {Name, _} = Station,
- case [MeasurementGet || MeasurementGet = {NameGet, DateGet, TypeGet, _} <-
- maps:get(measurements, Monitor), NameGet == Name, DateGet == Date, TypeGet == Type] of
- [] -> {reply, error, io_lib:format("The measurement with specified parameters ~w doesn't exist in station with coordinates ~w.~n",
- [{Date, Type}, {X, Y}])};
- [{NameGet, DateGet, TypeGet, ValueGet}] -> {reply, ok, maps:update(measurements,
- lists:delete({NameGet, DateGet, TypeGet, ValueGet}, maps:get(measurements, Monitor)), Monitor)}
- end;
- _ -> {reply, error, io_lib:format("The station with coordinates ~w doesn't exist.~n", [{X, Y}])}
- end.
- getOneValue_(Name, Date, Type, Monitor) when is_list(Name) ->
- case [StationNameGet || {StationNameGet, _} <- maps:get(stations, Monitor), StationNameGet == Name] of
- [Name] -> case [MeasurementGet || MeasurementGet = {NameGet, DateGet, TypeGet, _} <-
- maps:get(measurements, Monitor), NameGet == Name, DateGet == Date, TypeGet == Type] of
- [{Name, Date, Type, ValueGet}] -> {reply, ok, ValueGet};
- _ -> {reply, error, io_lib:format("The measurement with specified parameters ~w doesn't exist in station ~s.~n",
- [{Date, Type}, Name])}
- end;
- _ -> {reply, error, io_lib:format("The station ~s doesn't exist.~n", [Name])}
- end;
- getOneValue_({X, Y}, Date, Type, Monitor) ->
- case lists:keysearch({X, Y}, 2, maps:get(stations, Monitor)) of
- {value, Station} -> {Name, _} = Station,
- case [MeasurementGet || MeasurementGet = {NameGet, DateGet, TypeGet, _} <-
- maps:get(measurements, Monitor), NameGet == Name, DateGet == Date, TypeGet == Type] of
- [{Name, Date, Type, ValueGet}] -> {reply, ok, ValueGet};
- _ -> {reply, error, io_lib:format("The measurement with specified parameters ~w doesn't exist in station with coordinates ~w.~n",
- [{Date, Type}, {X, Y}])}
- end;
- _ -> {reply, error, io_lib:format("The station with coordinates ~w doesn't exist.~n", [{X, Y}])}
- end.
- getStationMean_(Name, Type, Monitor) when is_list(Name) ->
- case [StationNameGet || {StationNameGet, _} <- maps:get(stations, Monitor), StationNameGet == Name] of
- [] -> {reply, error, io_lib:format("Station ~s doesn't exist.~n", Name)};
- _ -> case MeasurementSet = [Measurement || Measurement = {NameGet, _, TypeGet, _} <-
- maps:get(measurements, Monitor), NameGet == Name, TypeGet == Type] of
- [] -> {reply, error, io_lib:format("Station ~s doesn't have any values measured.~n", Name)};
- _ -> MeanInfo = lists:foldl(fun ({_, _, _, ValueArg}, {Sum, Count}) ->
- {ValueArg + Sum, Count + 1} end, {0, 0}, MeasurementSet),
- {reply, ok, element(1, MeanInfo) / element(2, MeanInfo)}
- end
- end;
- getStationMean_({X, Y}, Type, Monitor) ->
- case lists:keysearch({X, Y}, 2, maps:get(stations, Monitor)) of
- {value, Station} -> {Name, _} = Station,
- case MeasurementSet = [Measurement || Measurement = {NameGet, _, TypeGet, _} <-
- maps:get(measurements, Monitor), NameGet == Name, TypeGet == Type] of
- [] -> {reply, error, io_lib:format("Station ~s doesn't have any values measured.~n", Name)};
- _ -> MeanInfo = lists:foldl(fun ({_, _, _, ValueArg}, {Sum, Count}) ->
- {ValueArg + Sum, Count + 1} end, {0, 0}, MeasurementSet),
- {reply, ok, element(1, MeanInfo) / element(2, MeanInfo)}
- end;
- _ -> {reply, error, io_lib:format("The station with coordinates ~w doesn't exist.~n", [{X, Y}])}
- end.
- getDailyMean_(Date, Type, Monitor) ->
- case [StationNameGet || {StationNameGet, _} <- maps:get(stations, Monitor)] of
- [] -> {reply, error, io_lib:format("This monitor doesn't have any stations added.~n", [])};
- _ -> case ValueSet = [ValueGet || {_, DateGet, TypeGet, ValueGet} <-
- maps:get(measurements, Monitor), element(1, DateGet) == Date, TypeGet == Type] of
- [] -> {reply, error, io_lib:format("On ~w, there have been no recorded measurements of ~s.~n", [Date, Type])};
- _ -> MeanInfo = lists:foldl(fun (ValueArg, {Sum, Count}) ->
- {ValueArg + Sum, Count + 1} end, {0, 0}, ValueSet),
- {reply, ok, element(1, MeanInfo) / element(2, MeanInfo)}
- end
- end.
- getHourlyMean_(Name, Hour, Type, Monitor) when Hour >= 0, Hour =< 23 ->
- case [StationNameGet || {StationNameGet, _} <- maps:get(stations, Monitor), StationNameGet == Name] of
- [] -> {reply, error, io_lib:format("The station ~s doesn't exist.~n", [Name])};
- _ -> case ValueSet = [ValueGet || {StationNameGet, DateGet, TypeGet, ValueGet} <-
- maps:get(measurements, Monitor), StationNameGet == Name, element(1, element(2, DateGet)) == Hour, TypeGet == Type] of
- [] -> {reply, error, io_lib:format("At ~w, there have been no recorded measurements of ~s on station ~s.~n", [Hour, Type, Name])};
- _ -> MeanInfo = lists:foldl(fun (ValueArg, {Sum, Count}) ->
- {ValueArg + Sum, Count + 1} end, {0, 0}, ValueSet),
- {reply, ok, element(1, MeanInfo) / element(2, MeanInfo)}
- end
- end.
- getHighestHour_(Type, Monitor) ->
- case [{element(1, element(2, DateGet)), ValueGet} || {_, DateGet, TypeGet, ValueGet} <- maps:get(measurements, Monitor), Type == TypeGet] of
- [] -> {reply, error, io_lib:format("There are no measurements of type ~s.~n", [Type])};
- Pairs -> Amounts = [lists:foldl(fun ({_, ValueArg}, {Hour, Sum, Count}) ->
- {Hour, Sum + ValueArg, Count + 1} end, {HourGetOuter, 0, 0}, [{HourGet, ValueGet} ||
- {HourGet, ValueGet} <- Pairs, HourGet == HourGetOuter]) || HourGetOuter <- lists:seq(0, 23)],
- AmountsMeans = [case Count of
- 0 -> {Hour, 0};
- _ -> {Hour, Sum / Count}
- end || {Hour, Sum, Count} <- Amounts],
- AmountsMeansSorted = lists:reverse(lists:keysort(2, AmountsMeans)),
- {reply, ok, element(1, lists:nth(1, AmountsMeansSorted))}
- end.
- addStation(Name, Coordinates) ->
- pollutionServer ! {request, self(), addStation, Name, Coordinates},
- receive
- {reply, ok} -> ok;
- {reply, error, Error} -> io:format(Error),
- error
- end.
- addValue(Name, Date, Type, Value) when is_list(Name) ->
- pollutionServer ! {request, self(), addValue, Name, Date, Type, Value},
- receive
- {reply, ok} -> ok;
- {reply, error, Error} -> io:format(Error),
- error
- end;
- addValue({X, Y}, Date, Type, Value) ->
- pollutionServer ! {request, self(), addValue, {X, Y}, Date, Type, Value},
- receive
- {reply, ok} -> ok;
- {reply, error, Error} -> io:format(Error),
- error
- end.
- removeValue(Name, Date, Type) when is_list(Name) ->
- pollutionServer ! {request, self(), removeValue, Name, Date, Type},
- receive
- {reply, ok} -> ok;
- {reply, error, Error} -> io:format(Error),
- error
- end;
- removeValue({X, Y}, Date, Type) ->
- pollutionServer ! {request, self(), removeValue, {X, Y}, Date, Type},
- receive
- {reply, ok} -> ok;
- {reply, error, Error} -> io:format(Error),
- error
- end.
- getOneValue(Name, Date, Type) when is_list(Name) ->
- pollutionServer ! {request, self(), getOneValue, Name, Date, Type},
- receive
- {reply, ok, Value} -> Value;
- {reply, error, Error} -> io:format(Error),
- error
- end;
- getOneValue({X, Y}, Date, Type) ->
- pollutionServer ! {request, self(), getOneValue, {X, Y}, Date, Type},
- receive
- {reply, ok, Value} -> Value;
- {reply, error, Error} -> io:format(Error),
- error
- end.
- getStationMean(Name, Type) when is_list(Name) ->
- pollutionServer ! {request, self(), getStationMean, Name, Type},
- receive
- {reply, ok, Value} -> Value;
- {reply, error, Error} -> io:format(Error),
- error
- end;
- getStationMean({X, Y}, Type) ->
- pollutionServer ! {request, self(), getStationMean, {X, Y}, Type},
- receive
- {reply, ok, Value} -> Value;
- {reply, error, Error} -> io:format(Error),
- error
- end.
- getDailyMean(Date, Type) ->
- pollutionServer ! {request, self(), getDailyMean, Date, Type},
- receive
- {reply, ok, Value} -> Value;
- {reply, error, Error} -> io:format(Error),
- error
- end.
- getHourlyMean(Name, Hour, Type) when Hour >= 0, Hour =< 23 ->
- pollutionServer ! {request, self(), getHourlyMean, Name, Hour, Type},
- receive
- {reply, ok, Value} -> Value;
- {reply, error, Error} -> io:format(Error),
- error
- end.
- getHighestHour(Type) ->
- pollutionServer ! {request, self(), getHighestHour, Type},
- receive
- {reply, ok, Value} -> Value;
- {reply, error, Error} -> io:format(Error),
- error
- end.
- prepareMonitorForTesting() ->
- addStation("Wisniewo", {1.2, 3.4}),
- addStation("Zurominek", {3.4, 5.6}),
- addStation("Podkrajewo", {5.6, 7.8}),
- addValue("Zurominek", {{2018, 4, 3}, {15, 50, 13}}, "PM10", 8.0),
- addValue("Wisniewo", {{2018, 4, 4}, {15, 20, 10}}, "PM10", 1.2),
- addValue({1.2, 3.4}, {{2018, 4, 3}, {15, 12, 45}}, "PM10", 2.4),
- addValue("Podkrajewo", {{2018, 4, 3}, {15, 20, 10}}, "PM10", 104),
- removeValue({5.6, 7.8}, {{2018, 4, 3}, {15, 20, 10}}, "PM10"),
- removeValue("Wisniewo", {{2018, 4, 4}, {15, 20, 10}}, "PM10"),
- addValue("Wisniewo", {{2018, 4, 3}, {16, 43, 12}}, "PM10", 4.6),
- addValue({1.2, 3.4}, {{2018, 4, 4}, {15, 23, 47}}, "PM2.5", 7),
- addValue("Wisniewo", {{2018, 4, 4}, {15, 23, 47}}, "PM10", 2).
- getOneValue_test() ->
- start(),
- prepareMonitorForTesting(),
- {Result0, Result1} = {getOneValue({3.4, 5.6}, {{2018, 4, 3}, {15, 50, 13}}, "PM10"),
- getOneValue("Wisniewo", {{2018, 4, 4}, {15, 23, 47}}, "PM2.5")},
- finish(),
- ?assertEqual({Result0, Result1}, {8.0, 7}).
- getStationMean_test() ->
- start(),
- prepareMonitorForTesting(),
- Result = getStationMean("Wisniewo", "PM10"),
- finish(),
- ?assertEqual(Result, 3.0).
- getDailyMean_test() ->
- start(),
- prepareMonitorForTesting(),
- Result = getDailyMean({2018, 4, 3}, "PM10"),
- finish(),
- ?assertEqual(Result, 5.0).
- getHourlyMean_test() ->
- start(),
- prepareMonitorForTesting(),
- Result = getHourlyMean("Wisniewo", 15, "PM10"),
- finish(),
- ?assertEqual(Result, 2.2).
- getHighestHour_test() ->
- start(),
- prepareMonitorForTesting(),
- Result = getHighestHour("PM10"),
- finish(),
- ?assertEqual(Result, 16).
- getFromNonexistentStation_test() ->
- start(),
- prepareMonitorForTesting(),
- Result = getOneValue("Bogurzyn", {{2018, 4, 3}, {15, 50, 13}}, "PM10"),
- finish(),
- ?assertEqual(Result, error).
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement