Advertisement
Guest User

k

a guest
Jun 10th, 2018
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Erlang 16.54 KB | None | 0 0
  1. %%%-------------------------------------------------------------------
  2. %%% @author user
  3. %%% @copyright (C) 2018, <COMPANY>
  4. %%% @doc
  5. %%%
  6. %%% @end
  7. %%% Created : 16. kwi 2018 14:02
  8. %%%-------------------------------------------------------------------
  9. -module(pollution_server).
  10. -author("user").
  11.  
  12. %% API
  13. -export([createMonitor/0,
  14.   addStation/2,
  15.   addValue/4,
  16.   getStationMean/2,
  17.   removeValue/3,
  18.   getOneValue/3,
  19.   getDailyMean/2,
  20.   getHourlyMean/3,
  21.   getHighestHour/1,
  22.   start/0,
  23.   finish/0,
  24.   init/0
  25. ]).
  26.  
  27. -include_lib("eunit/include/eunit.hrl").
  28.  
  29. start() ->
  30.   register(pollutionServer, spawn(?MODULE, init, [])).
  31.  
  32. init() ->
  33.   loop(createMonitor()).
  34.  
  35. loop(Monitor) ->
  36.   receive
  37.     {request, Pid, addStation, Name, Coordinates} ->
  38.       {reply, Status, Data} = addStation_(Name, Coordinates, Monitor),
  39.       case Status of
  40.         error -> Pid ! {reply, error, Data},
  41.           loop(Monitor);
  42.         ok -> Pid ! {reply, ok},
  43.           loop(Data)
  44.       end;
  45.     {request, Pid, addValue, Name, Date, Type, Value} when is_list(Name) ->
  46.       {reply, Status, Data} = addValue_(Name, Date, Type, Value, Monitor),
  47.       case Status of
  48.         error -> Pid ! {reply, error, Data},
  49.           loop(Monitor);
  50.         ok -> Pid ! {reply, ok},
  51.           loop(Data)
  52.       end;
  53.     {request, Pid, addValue, {X, Y}, Date, Type, Value} ->
  54.       {reply, Status, Data} = addValue_({X, Y}, Date, Type, Value, Monitor),
  55.       case Status of
  56.         error -> Pid ! {reply, error, Data},
  57.           loop(Monitor);
  58.         ok -> Pid ! {reply, ok},
  59.           loop(Data)
  60.       end;
  61.     {request, Pid, removeValue, Name, Date, Type} when is_list(Name) ->
  62.       {reply, Status, Data} = removeValue_(Name, Date, Type, Monitor),
  63.       case Status of
  64.         error -> Pid ! {reply, error, Data},
  65.           loop(Monitor);
  66.         ok -> Pid ! {reply, ok},
  67.           loop(Data)
  68.       end;
  69.     {request, Pid, removeValue, {X, Y}, Date, Type} ->
  70.       {reply, Status, Data} = removeValue_({X, Y}, Date, Type, Monitor),
  71.       case Status of
  72.         error -> Pid ! {reply, error, Data},
  73.           loop(Monitor);
  74.         ok -> Pid ! {reply, ok},
  75.           loop(Data)
  76.       end;
  77.     {request, Pid, getOneValue, Name, Date, Type} when is_list(Name) ->
  78.       Pid ! getOneValue_(Name, Date, Type, Monitor),
  79.       loop(Monitor);
  80.     {request, Pid, getOneValue, {X, Y}, Date, Type} ->
  81.       Pid ! getOneValue_({X, Y}, Date, Type, Monitor),
  82.       loop(Monitor);
  83.     {request, Pid, getStationMean, Name, Type} when is_list(Name) ->
  84.       Pid ! getStationMean_(Name, Type, Monitor),
  85.       loop(Monitor);
  86.     {request, Pid, getStationMean, {X, Y}, Type} ->
  87.       Pid ! getStationMean_({X, Y}, Type, Monitor),
  88.       loop(Monitor);
  89.     {request, Pid, getDailyMean, Date, Type} ->
  90.       Pid ! getDailyMean_(Date, Type, Monitor),
  91.       loop(Monitor);
  92.     {request, Pid, getHourlyMean, Name, Hour, Type} ->
  93.       Pid ! getHourlyMean_(Name, Hour, Type, Monitor),
  94.       loop(Monitor);
  95.     {request, Pid, getHighestHour, Type} ->
  96.       Pid ! getHighestHour_(Type, Monitor),
  97.       loop(Monitor);
  98.     {request, Pid, stop} ->
  99.       Pid ! {reply, ok};
  100.     _ -> c:flush()
  101.   end.
  102.  
  103. finish() ->
  104.   pollutionServer ! {request, self(), stop}.
  105.  
  106. createMonitor() -> #{stations => [], measurements => []}.
  107.  
  108. addStation_(Name, Coordinates, Monitor) ->
  109.   case lists:keymember(Name, 1, maps:get(stations, Monitor)) or
  110.     lists:keymember(Coordinates, 2, maps:get(stations, Monitor)) of
  111.     false -> {reply, ok, maps:update(stations, maps:get(stations, Monitor) ++ [{Name, Coordinates}], Monitor)};
  112.     _ -> {reply, error, io_lib:format("There already exists a station with name ~s or coordinates ~w.~n", [Name, Coordinates])}
  113.   end.
  114.  
  115. addValue_(Name, Date, Type, Value, Monitor) when is_list(Name) ->
  116.   case [StationNameGet || {StationNameGet, _} <- maps:get(stations, Monitor), StationNameGet == Name] of
  117.     [] -> {reply, error, io_lib:format("The station ~s doesn't exist.~n", [Name])};
  118.     _ -> case [MeasurementGet || MeasurementGet = {NameGet, DateGet, TypeGet, _} <- maps:get(measurements, Monitor),
  119.       NameGet == Name, Date == DateGet, TypeGet == Type] of
  120.            [] -> {reply, ok, maps:update(measurements,
  121.              maps:get(measurements, Monitor) ++ [{Name, Date, Type, Value}], Monitor)};
  122.            _ -> {reply, error, io_lib:format("The measurement ~w has already been registered within station ~s.~n",
  123.              [{Date, Type, Value}, Name])}
  124.          end
  125.   end;
  126.  
  127. addValue_({X, Y}, Date, Type, Value, Monitor) ->
  128.   case lists:keysearch({X, Y}, 2, maps:get(stations, Monitor)) of
  129.     {value, Station} -> {Name, _} = Station,
  130.       case [NameGet || {NameGet, DateGet, TypeGet, _} <- maps:get(measurements, Monitor),
  131.         NameGet == Name, DateGet == Date, TypeGet == Type] of
  132.         [] -> {reply, ok, maps:update(measurements,
  133.           maps:get(measurements, Monitor) ++ [{Name, Date, Type, Value}], Monitor)};
  134.         _ -> {reply, error, io_lib:format("The measurement ~w has already been registered within station ~s.~n",
  135.           [{Date, Type, Value}, Name])}
  136.       end;
  137.     _ -> {reply, error, io_lib:format("The station with coordinates ~w doesn't exist.~n", [{X, Y}])}
  138.   end.
  139.  
  140. removeValue_(Name, Date, Type, Monitor) when is_list(Name) ->
  141.   case [StationNameGet || {StationNameGet, _} <- maps:get(stations, Monitor), StationNameGet == Name] of
  142.     [] -> {reply, error, io_lib:format("The station ~s doesn't exist.~n", [Name])};
  143.     _ -> case [MeasurementGet || MeasurementGet = {NameGet, DateGet, TypeGet, _} <-
  144.       maps:get(measurements, Monitor), NameGet == Name, DateGet == Date, TypeGet == Type] of
  145.            [] -> {reply, error, io_lib:format("The measurement with specified parameters ~w doesn't exist in station ~s.~n",
  146.              [{Date, Type}, Name])};
  147.            [{NameGet, DateGet, TypeGet, ValueGet}] -> {reply, ok, maps:update(measurements,
  148.              lists:delete({NameGet, DateGet, TypeGet, ValueGet}, maps:get(measurements, Monitor)), Monitor)}
  149.          end
  150.   end;
  151.  
  152. removeValue_({X, Y}, Date, Type, Monitor) ->
  153.   case lists:keysearch({X, Y}, 2, maps:get(stations, Monitor)) of
  154.     {value, Station} -> {Name, _} = Station,
  155.       case [MeasurementGet || MeasurementGet = {NameGet, DateGet, TypeGet, _} <-
  156.         maps:get(measurements, Monitor), NameGet == Name, DateGet == Date, TypeGet == Type] of
  157.         [] -> {reply, error, io_lib:format("The measurement with specified parameters ~w doesn't exist in station with coordinates ~w.~n",
  158.           [{Date, Type}, {X, Y}])};
  159.         [{NameGet, DateGet, TypeGet, ValueGet}] -> {reply, ok, maps:update(measurements,
  160.           lists:delete({NameGet, DateGet, TypeGet, ValueGet}, maps:get(measurements, Monitor)), Monitor)}
  161.       end;
  162.     _ -> {reply, error, io_lib:format("The station with coordinates ~w doesn't exist.~n", [{X, Y}])}
  163.   end.
  164.  
  165. getOneValue_(Name, Date, Type, Monitor) when is_list(Name) ->
  166.   case [StationNameGet || {StationNameGet, _} <- maps:get(stations, Monitor), StationNameGet == Name] of
  167.     [Name] -> case [MeasurementGet || MeasurementGet = {NameGet, DateGet, TypeGet, _} <-
  168.       maps:get(measurements, Monitor), NameGet == Name, DateGet == Date, TypeGet == Type] of
  169.                 [{Name, Date, Type, ValueGet}] -> {reply, ok, ValueGet};
  170.                 _ -> {reply, error, io_lib:format("The measurement with specified parameters ~w doesn't exist in station ~s.~n",
  171.                   [{Date, Type}, Name])}
  172.               end;
  173.     _ -> {reply, error, io_lib:format("The station ~s doesn't exist.~n", [Name])}
  174.   end;
  175.  
  176. getOneValue_({X, Y}, Date, Type, Monitor) ->
  177.   case lists:keysearch({X, Y}, 2, maps:get(stations, Monitor)) of
  178.     {value, Station} -> {Name, _} = Station,
  179.       case [MeasurementGet || MeasurementGet = {NameGet, DateGet, TypeGet, _} <-
  180.         maps:get(measurements, Monitor), NameGet == Name, DateGet == Date, TypeGet == Type] of
  181.         [{Name, Date, Type, ValueGet}] -> {reply, ok, ValueGet};
  182.         _ -> {reply, error, io_lib:format("The measurement with specified parameters ~w doesn't exist in station with coordinates ~w.~n",
  183.           [{Date, Type}, {X, Y}])}
  184.       end;
  185.     _ -> {reply, error, io_lib:format("The station with coordinates ~w doesn't exist.~n", [{X, Y}])}
  186.   end.
  187.  
  188. getStationMean_(Name, Type, Monitor) when is_list(Name) ->
  189.   case [StationNameGet || {StationNameGet, _} <- maps:get(stations, Monitor), StationNameGet == Name] of
  190.     [] -> {reply, error, io_lib:format("Station ~s doesn't exist.~n", Name)};
  191.     _ -> case MeasurementSet = [Measurement || Measurement = {NameGet, _, TypeGet, _} <-
  192.       maps:get(measurements, Monitor), NameGet == Name, TypeGet == Type] of
  193.            [] -> {reply, error, io_lib:format("Station ~s doesn't have any values measured.~n", Name)};
  194.            _ -> MeanInfo = lists:foldl(fun ({_, _, _, ValueArg}, {Sum, Count}) ->
  195.              {ValueArg + Sum, Count + 1} end, {0, 0}, MeasurementSet),
  196.              {reply, ok, element(1, MeanInfo) / element(2, MeanInfo)}
  197.          end
  198.   end;
  199.  
  200. getStationMean_({X, Y}, Type, Monitor) ->
  201.   case lists:keysearch({X, Y}, 2, maps:get(stations, Monitor)) of
  202.     {value, Station} -> {Name, _} = Station,
  203.       case MeasurementSet = [Measurement || Measurement = {NameGet, _, TypeGet, _} <-
  204.         maps:get(measurements, Monitor), NameGet == Name, TypeGet == Type] of
  205.         [] -> {reply, error, io_lib:format("Station ~s doesn't have any values measured.~n", Name)};
  206.         _ -> MeanInfo = lists:foldl(fun ({_, _, _, ValueArg}, {Sum, Count}) ->
  207.           {ValueArg + Sum, Count + 1} end, {0, 0}, MeasurementSet),
  208.           {reply, ok, element(1, MeanInfo) / element(2, MeanInfo)}
  209.       end;
  210.     _ -> {reply, error, io_lib:format("The station with coordinates ~w doesn't exist.~n", [{X, Y}])}
  211.   end.
  212.  
  213. getDailyMean_(Date, Type, Monitor) ->
  214.   case [StationNameGet || {StationNameGet, _} <- maps:get(stations, Monitor)] of
  215.     [] -> {reply, error, io_lib:format("This monitor doesn't have any stations added.~n", [])};
  216.     _ -> case ValueSet = [ValueGet || {_, DateGet, TypeGet, ValueGet} <-
  217.       maps:get(measurements, Monitor), element(1, DateGet) == Date, TypeGet == Type] of
  218.            [] -> {reply, error, io_lib:format("On ~w, there have been no recorded measurements of ~s.~n", [Date, Type])};
  219.            _ -> MeanInfo = lists:foldl(fun (ValueArg, {Sum, Count}) ->
  220.              {ValueArg + Sum, Count + 1} end, {0, 0}, ValueSet),
  221.              {reply, ok, element(1, MeanInfo) / element(2, MeanInfo)}
  222.          end
  223.   end.
  224.  
  225. getHourlyMean_(Name, Hour, Type, Monitor) when Hour >= 0, Hour =< 23 ->
  226.   case [StationNameGet || {StationNameGet, _} <- maps:get(stations, Monitor), StationNameGet == Name] of
  227.     [] -> {reply, error, io_lib:format("The station ~s doesn't exist.~n", [Name])};
  228.     _ -> case ValueSet = [ValueGet || {StationNameGet, DateGet, TypeGet, ValueGet} <-
  229.       maps:get(measurements, Monitor), StationNameGet == Name, element(1, element(2, DateGet)) == Hour, TypeGet == Type] of
  230.            [] -> {reply, error, io_lib:format("At ~w, there have been no recorded measurements of ~s on station ~s.~n", [Hour, Type, Name])};
  231.            _ -> MeanInfo = lists:foldl(fun (ValueArg, {Sum, Count}) ->
  232.              {ValueArg + Sum, Count + 1} end, {0, 0}, ValueSet),
  233.              {reply, ok, element(1, MeanInfo) / element(2, MeanInfo)}
  234.          end
  235.   end.
  236.  
  237. getHighestHour_(Type, Monitor) ->
  238.   case [{element(1, element(2, DateGet)), ValueGet} || {_, DateGet, TypeGet, ValueGet} <- maps:get(measurements, Monitor), Type == TypeGet] of
  239.     [] -> {reply, error, io_lib:format("There are no measurements of type ~s.~n", [Type])};
  240.     Pairs -> Amounts = [lists:foldl(fun ({_, ValueArg}, {Hour, Sum, Count}) ->
  241.       {Hour, Sum + ValueArg, Count + 1} end, {HourGetOuter, 0, 0}, [{HourGet, ValueGet} ||
  242.       {HourGet, ValueGet} <- Pairs, HourGet == HourGetOuter]) || HourGetOuter <- lists:seq(0, 23)],
  243.       AmountsMeans = [case Count of
  244.                         0 -> {Hour, 0};
  245.                         _ -> {Hour, Sum / Count}
  246.                       end || {Hour, Sum, Count} <- Amounts],
  247.       AmountsMeansSorted = lists:reverse(lists:keysort(2, AmountsMeans)),
  248.       {reply, ok, element(1, lists:nth(1, AmountsMeansSorted))}
  249.   end.
  250.  
  251. addStation(Name, Coordinates) ->
  252.   pollutionServer ! {request, self(), addStation, Name, Coordinates},
  253.   receive
  254.     {reply, ok} -> ok;
  255.     {reply, error, Error} -> io:format(Error),
  256.       error
  257.   end.
  258.  
  259. addValue(Name, Date, Type, Value) when is_list(Name) ->
  260.   pollutionServer ! {request, self(), addValue, Name, Date, Type, Value},
  261.   receive
  262.     {reply, ok} -> ok;
  263.     {reply, error, Error} -> io:format(Error),
  264.       error
  265.   end;
  266.  
  267. addValue({X, Y}, Date, Type, Value) ->
  268.   pollutionServer ! {request, self(), addValue, {X, Y}, Date, Type, Value},
  269.   receive
  270.     {reply, ok} -> ok;
  271.     {reply, error, Error} -> io:format(Error),
  272.       error
  273.   end.
  274.  
  275. removeValue(Name, Date, Type) when is_list(Name) ->
  276.   pollutionServer ! {request, self(), removeValue, Name, Date, Type},
  277.   receive
  278.     {reply, ok} -> ok;
  279.     {reply, error, Error} -> io:format(Error),
  280.       error
  281.   end;
  282.  
  283. removeValue({X, Y}, Date, Type) ->
  284.   pollutionServer ! {request, self(), removeValue, {X, Y}, Date, Type},
  285.   receive
  286.     {reply, ok} -> ok;
  287.     {reply, error, Error} -> io:format(Error),
  288.       error
  289.   end.
  290.  
  291. getOneValue(Name, Date, Type) when is_list(Name) ->
  292.   pollutionServer ! {request, self(), getOneValue, Name, Date, Type},
  293.   receive
  294.     {reply, ok, Value} -> Value;
  295.     {reply, error, Error} -> io:format(Error),
  296.       error
  297.   end;
  298.  
  299. getOneValue({X, Y}, Date, Type) ->
  300.   pollutionServer ! {request, self(), getOneValue, {X, Y}, Date, Type},
  301.   receive
  302.     {reply, ok, Value} -> Value;
  303.     {reply, error, Error} -> io:format(Error),
  304.       error
  305.   end.
  306.  
  307. getStationMean(Name, Type) when is_list(Name) ->
  308.   pollutionServer ! {request, self(), getStationMean, Name, Type},
  309.   receive
  310.     {reply, ok, Value} -> Value;
  311.     {reply, error, Error} -> io:format(Error),
  312.       error
  313.   end;
  314.  
  315. getStationMean({X, Y}, Type) ->
  316.   pollutionServer ! {request, self(), getStationMean, {X, Y}, Type},
  317.   receive
  318.     {reply, ok, Value} -> Value;
  319.     {reply, error, Error} -> io:format(Error),
  320.       error
  321.   end.
  322.  
  323. getDailyMean(Date, Type) ->
  324.   pollutionServer ! {request, self(), getDailyMean, Date, Type},
  325.   receive
  326.     {reply, ok, Value} -> Value;
  327.     {reply, error, Error} -> io:format(Error),
  328.       error
  329.   end.
  330.  
  331. getHourlyMean(Name, Hour, Type) when Hour >= 0, Hour =< 23 ->
  332.   pollutionServer ! {request, self(), getHourlyMean, Name, Hour, Type},
  333.   receive
  334.     {reply, ok, Value} -> Value;
  335.     {reply, error, Error} -> io:format(Error),
  336.       error
  337.   end.
  338.  
  339. getHighestHour(Type) ->
  340.   pollutionServer ! {request, self(), getHighestHour, Type},
  341.   receive
  342.     {reply, ok, Value} -> Value;
  343.     {reply, error, Error} -> io:format(Error),
  344.       error
  345.   end.
  346.  
  347. prepareMonitorForTesting() ->
  348.   addStation("Wisniewo", {1.2, 3.4}),
  349.   addStation("Zurominek", {3.4, 5.6}),
  350.   addStation("Podkrajewo", {5.6, 7.8}),
  351.   addValue("Zurominek", {{2018, 4, 3}, {15, 50, 13}}, "PM10", 8.0),
  352.   addValue("Wisniewo", {{2018, 4, 4}, {15, 20, 10}}, "PM10", 1.2),
  353.   addValue({1.2, 3.4}, {{2018, 4, 3}, {15, 12, 45}}, "PM10", 2.4),
  354.   addValue("Podkrajewo", {{2018, 4, 3}, {15, 20, 10}}, "PM10", 104),
  355.   removeValue({5.6, 7.8}, {{2018, 4, 3}, {15, 20, 10}}, "PM10"),
  356.   removeValue("Wisniewo", {{2018, 4, 4}, {15, 20, 10}}, "PM10"),
  357.   addValue("Wisniewo", {{2018, 4, 3}, {16, 43, 12}}, "PM10", 4.6),
  358.   addValue({1.2, 3.4}, {{2018, 4, 4}, {15, 23, 47}}, "PM2.5", 7),
  359.   addValue("Wisniewo", {{2018, 4, 4}, {15, 23, 47}}, "PM10", 2).
  360.  
  361. getOneValue_test() ->
  362.   start(),
  363.   prepareMonitorForTesting(),
  364.   {Result0, Result1} = {getOneValue({3.4, 5.6}, {{2018, 4, 3}, {15, 50, 13}}, "PM10"),
  365.     getOneValue("Wisniewo", {{2018, 4, 4}, {15, 23, 47}}, "PM2.5")},
  366.   finish(),
  367.   ?assertEqual({Result0, Result1}, {8.0, 7}).
  368.  
  369. getStationMean_test() ->
  370.   start(),
  371.   prepareMonitorForTesting(),
  372.   Result = getStationMean("Wisniewo", "PM10"),
  373.   finish(),
  374.   ?assertEqual(Result, 3.0).
  375.  
  376. getDailyMean_test() ->
  377.   start(),
  378.   prepareMonitorForTesting(),
  379.   Result = getDailyMean({2018, 4, 3}, "PM10"),
  380.   finish(),
  381.   ?assertEqual(Result, 5.0).
  382.  
  383. getHourlyMean_test() ->
  384.   start(),
  385.   prepareMonitorForTesting(),
  386.   Result = getHourlyMean("Wisniewo", 15, "PM10"),
  387.   finish(),
  388.   ?assertEqual(Result, 2.2).
  389.  
  390. getHighestHour_test() ->
  391.   start(),
  392.   prepareMonitorForTesting(),
  393.   Result = getHighestHour("PM10"),
  394.   finish(),
  395.   ?assertEqual(Result, 16).
  396.  
  397. getFromNonexistentStation_test() ->
  398.   start(),
  399.   prepareMonitorForTesting(),
  400.   Result = getOneValue("Bogurzyn", {{2018, 4, 3}, {15, 50, 13}}, "PM10"),
  401.   finish(),
  402.   ?assertEqual(Result, error).
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement