Skip to content

Commit db1632b

Browse files
committed
feat: ✨ update CLI
1 parent cd68606 commit db1632b

File tree

5 files changed

+76
-52
lines changed

5 files changed

+76
-52
lines changed

lib/cli/config_parser.ex

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,33 @@ defmodule InterpolationApp.CLI.ConfigParser do
33
Parses args for interpolation-app CLI
44
"""
55

6-
@methods ["linear", "lagrange2", "lagrange3", "newton"]
6+
@methods ["linear", "lagrange3", "lagrange4", "newton"]
77

88
def parse_args(args) do
99
args
1010
|> Enum.reduce(%{}, &parse_arg/2)
1111
|> validate_args()
1212
end
1313

14-
defp parse_arg("--method1=" <> method, acc) do
15-
Map.put(acc, :method1, String.trim(method))
14+
defp parse_arg("methods=" <> method, acc) do
15+
Map.put(acc, :methods, String.split(String.trim(method), ","))
1616
end
1717

18-
defp parse_arg("--method2=" <> method, acc) do
19-
Map.put(acc, :method2, String.trim(method))
20-
end
21-
22-
defp parse_arg("--step=" <> step, acc) do
18+
defp parse_arg("step=" <> step, acc) do
2319
Map.put(acc, :step, String.trim(step))
2420
end
2521

26-
defp parse_arg("--accuracy=" <> accuracy, acc) do
22+
defp parse_arg("accuracy=" <> accuracy, acc) do
2723
Map.put(acc, :accuracy, String.trim(accuracy))
2824
end
2925

3026
defp parse_arg(_, acc), do: acc
3127

32-
defp validate_args(%{method1: method1, method2: method2, step: step, accuracy: accuracy}) do
28+
defp validate_args(%{methods: methods, step: step, accuracy: accuracy}) do
3329
cond do
34-
!valid_method?(method1) ->
30+
!valid_methods?(methods) ->
3531
{:error,
36-
"Неправильный method1: #{method1}. Должен быть один из [#{Enum.join(@methods, ", ")}]."}
37-
38-
!valid_method?(method2) ->
39-
{:error,
40-
"Неправильный method2: #{method2}. Должен быть один из [#{Enum.join(@methods, ", ")}]."}
32+
"Неправильный ввод методов: Методы должны быть перечислены через запятую и не повторяться.\nМетод должен быть один из [#{Enum.join(@methods, ", ")}]."}
4133

4234
!valid_step?(step) ->
4335
{:error,
@@ -49,23 +41,24 @@ defmodule InterpolationApp.CLI.ConfigParser do
4941
true ->
5042
{:ok,
5143
%{
52-
method1: module_from_method(method1),
53-
method2: module_from_method(method2),
44+
methods: Enum.map(methods, &module_from_method/1),
5445
step: elem(Float.parse(step), 0),
5546
accuracy: elem(Integer.parse(accuracy), 0)
5647
}}
5748
end
5849
end
5950

60-
defp validate_args(%{method1: method1, method2: method2, step: step}) do
61-
validate_args(%{method1: method1, method2: method2, step: step, accuracy: "3"})
51+
defp validate_args(%{methods: methods, step: step}) do
52+
validate_args(%{methods: methods, step: step, accuracy: "3"})
6253
end
6354

6455
defp validate_args(_) do
65-
{:error, "Ошибка! Обязательные аргументы: --method1=, --method2=, --step="}
56+
{:error, "Ошибка! Обязательные аргументы: --methods=, --step="}
6657
end
6758

68-
defp valid_method?(method), do: method in @methods
59+
defp valid_methods?(methods) do
60+
Enum.uniq(methods) == methods and Enum.all?(methods, fn method -> method in @methods end)
61+
end
6962

7063
defp valid_step?(step) do
7164
case Float.parse(step) do

lib/cli/interpolator.ex

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,34 @@ defmodule InterpolationApp.CLI.Interpolator do
2727
@impl true
2828
def handle_cast({:add_point, point}, {points, config, printer_pid}) do
2929
points = Enum.reverse([point | Enum.reverse(points)])
30-
methods = Enum.uniq([config.method1, config.method2])
31-
32-
Enum.each(methods, fn method ->
33-
if method.points_enough?(points) do
34-
limit = method.get_enough_points_count()
35-
interpolation_points = Enum.slice(points, -limit, limit)
36-
generated_points = PointGenerator.generate(interpolation_points, config.step)
37-
38-
GenServer.cast(printer_pid, {
39-
:print,
40-
method,
41-
method.interpolate(interpolation_points, generated_points)
42-
})
43-
end
30+
31+
Enum.each(config.methods, fn method ->
32+
handle_method(method, points, printer_pid, config)
4433
end)
4534

4635
{:noreply, {points, config, printer_pid}}
4736
end
37+
38+
# Helper Functions
39+
40+
defp handle_method(method, points, printer_pid, config) do
41+
if method.points_enough?(points) do
42+
limit = method.get_enough_points_count()
43+
44+
interpolation_points =
45+
if method.need_concrete_number_of_points?(),
46+
do: Enum.slice(points, -limit, limit),
47+
else: points
48+
49+
generated_points = PointGenerator.generate(interpolation_points, config.step)
50+
51+
GenServer.cast(printer_pid, {
52+
:print,
53+
method,
54+
method.interpolate(interpolation_points, generated_points)
55+
})
56+
end
57+
58+
:ok
59+
end
4860
end

lib/cli/printer.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ defmodule InterpolationApp.CLI.Printer do
3434
{first_x, _} = List.first(result)
3535

3636
IO.puts(
37-
"#{method.get_name()} (идем от точки из введенных #{first_x} с шагом #{step}, покрывая все введенные X)"
37+
">> #{method.get_name()} (идем от точки из введенных #{first_x} с шагом #{step}, покрывая все введенные X)"
3838
)
3939

4040
print_line(result, accuracy)

lib/cli/repl.ex

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,36 @@ defmodule InterpolationApp.CLI.Repl do
1919

2020
defp loop(applier_pid) do
2121
:io.setopts(:standard_io, active: true)
22-
input = IO.gets("")
22+
input = IO.gets("") |> check_quit
2323

24-
if input == :eof or String.trim(input) == "quit" do
25-
IO.puts("\nСпасибо за использование программы!\n")
24+
GenServer.cast(applier_pid, {:apply_input, String.trim(input)})
25+
loop(applier_pid)
26+
end
2627

27-
IO.puts("""
28-
|\ _,,,---,,_
29-
ZZZzz /,`.-'`' -. ;-;;,_
30-
|,4- ) )-,_. ,\ ( `'-'
31-
'---''(_/--' `-'\_)
32-
""")
28+
defp check_quit(input) do
29+
if input == :eof do
30+
:timer.sleep(100)
31+
quit()
32+
end
3333

34-
System.halt()
34+
if String.trim(input) == "quit" do
35+
quit()
3536
end
3637

37-
GenServer.cast(applier_pid, {:apply_input, String.trim(input)})
38-
loop(applier_pid)
38+
input
39+
end
40+
41+
@spec quit() :: no_return()
42+
defp quit do
43+
IO.puts("\nСпасибо за использование программы!\n")
44+
45+
IO.puts("""
46+
|\ _,,,---,,_
47+
ZZZzz /,`.-'`' -. ;-;;,_
48+
|,4- ) )-,_. ,\ ( `'-'
49+
'---''(_/--' `-'\_)
50+
""")
51+
52+
System.halt()
3953
end
4054
end

lib/main.ex

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ defmodule InterpolationApp.Main do
1212
System.halt()
1313
end
1414

15-
case ConfigParser.parse_args(args) do
15+
argv =
16+
Enum.map(args, fn arg -> String.split(arg, "--") end)
17+
|> List.flatten()
18+
|> Enum.filter(fn s -> s != "" end)
19+
20+
case ConfigParser.parse_args(argv) do
1621
{:ok, config} ->
1722
Repl.start(config)
1823

@@ -25,15 +30,15 @@ defmodule InterpolationApp.Main do
2530

2631
defp help do
2732
"""
28-
usage: interpolation-app [options] --method1=<method> --method2=<method> --step=<step>
33+
usage: interpolation-app [options] --methods=<method1,method2,...> --step=<step>
2934
options:
3035
-h, --help Prints this message
3136
--accuracy=<accuracy> Set printing accuracy
3237
3338
methods:
3439
* linear
35-
* lagrange2
3640
* lagrange3
41+
* lagrange4
3742
* newton
3843
"""
3944
end

0 commit comments

Comments
 (0)