-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Registre d'arrêts : première ébauche #4393
base: master
Are you sure you want to change the base?
Changes from all commits
ea32f57
7a43312
0f17fd1
d897569
5c21318
44b6676
79b6228
cb1a7d1
c3b26d9
d74db74
2d53a9a
87bcf13
604202c
eea082c
aea3e94
6d2d36c
e070530
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
defmodule Transport.GTFS.Utils do | ||
@moduledoc """ | ||
Some helpers for handling GTFS archives. | ||
""" | ||
|
||
def fetch_position(record, field) do | ||
Map.fetch!(record, field) |> convert_text_to_float() | ||
end | ||
|
||
@doc """ | ||
Convert textual values to float. | ||
|
||
iex> convert_text_to_float("") | ||
nil | ||
iex> convert_text_to_float("0") | ||
0.0 | ||
iex> convert_text_to_float("0.0") | ||
0.0 | ||
iex> convert_text_to_float("12.7") | ||
12.7 | ||
iex> convert_text_to_float("-12.7") | ||
-12.7 | ||
iex> convert_text_to_float(" -48.7 ") | ||
-48.7 | ||
""" | ||
def convert_text_to_float(input) do | ||
if input |> String.trim() != "" do | ||
input |> String.trim() |> Decimal.new() |> Decimal.to_float() | ||
else | ||
nil | ||
end | ||
end | ||
|
||
@doc """ | ||
Variant of csv_get_with_default/3 that raises if a mandatory column is missing. | ||
""" | ||
def csv_get_with_default!(map, field, default_value, mandatory_column \\ true) do | ||
value = if mandatory_column, do: Map.fetch!(map, field), else: Map.get(map, field) | ||
|
||
case value do | ||
nil -> default_value | ||
"" -> default_value | ||
v -> v | ||
end | ||
end | ||
|
||
@doc """ | ||
iex> csv_get_with_default(%{}, "field", 0) | ||
0 | ||
iex> csv_get_with_default(%{"other_field" => 1}, "field", 0) | ||
0 | ||
iex> csv_get_with_default(%{"field" => 2, "other_field" => 1}, "field", 0) | ||
2 | ||
iex> csv_get_with_default(%{"field" => "", "other_field" => 1}, "field", 0) | ||
0 | ||
""" | ||
def csv_get_with_default(map, field, default_value) do | ||
value = Map.get(map, field) | ||
|
||
case value do | ||
nil -> default_value | ||
"" -> default_value | ||
v -> v | ||
end | ||
end | ||
|
||
@doc """ | ||
Transform the stream outputed by Unzip to a stream of maps, each map | ||
corresponding to a row from the CSV. | ||
""" | ||
def to_stream_of_maps(file_stream) do | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Je me suis demandé si Avec l'arrivée de Elixir 1.18+ et du typage, j'ai l'impression que mettre les types de structs en paramètre va être une bonne idée. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. C'est un enumerable de iodata (pas sûr du type en elixir). |
||
file_stream | ||
# transform the stream to a stream of binaries | ||
|> Stream.map(fn c -> IO.iodata_to_binary(c) end) | ||
# stream line by line | ||
|> NimbleCSV.RFC4180.to_line_stream() | ||
|> NimbleCSV.RFC4180.parse_stream(skip_headers: false) | ||
# transform the stream to a stream of maps %{column_name1: value1, ...} | ||
|> Stream.transform([], fn r, acc -> | ||
if acc == [] do | ||
{%{}, r |> Enum.map(fn h -> h |> String.replace_prefix("\uFEFF", "") end)} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Je ne sais pas si tu as vu qu'on peut trimmer le BOM directement à l'ouverture du stream: https://hexdocs.pm/elixir/1.18.1/File.html#stream!/3-byte-order-marks-and-read-offset File.stream!("./test/test.txt", [:trim_bom, encoding: :utf8]) Mais peut-être que tu as déjà vu et que ce n'est pas pratique etc... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Non ; j'ai repris naïvement du code existant. |
||
else | ||
{[acc |> Enum.zip(r) |> Enum.into(%{})], acc} | ||
end | ||
end) | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Est-ce qu'il y a un
trim
en amont ? J'imagine qu'on pourrait dans certains cas tomber sur des valeurs comme" "
).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(et je vois après-coup que c'est un refacto d'un code existant https://github.com/etalab/transport-site/pull/4393/files#diff-6ddccc89023492259f2e7204a077024fb50745d892994fdd85f2293a639f8887).