ChatGPT で elixir を学ぶ　（その5）text ファイルの read

こちらの記事の続きです。
[ChatGPT で elixir を学ぶ　（その4）text ファイルの write](https://qiita.com/ekzemplaro/items/ece7cebd384d6c6cc86a)

テキストファイルを読みます。
>辞書に変換してから、表示します。

## 入力ファイル

```text:cities.txt
t2381	名古屋	93514	1910-5-17
t2382	豊橋	31296	1910-9-10
t2383	岡崎	17459	1910-2-14
t2384	一宮	62542	1910-7-9
t2385	蒲郡	42619	1910-8-4
t2386	常滑	35182	1910-1-21
t2387	大府	81247	1910-7-23
t2388	瀬戸	25738	1910-10-26
t2389	犬山	74135	1910-12-15
```

## Python のプログラム

```py:text_read.py
#! /usr/bin/python
#
import	sys
#
# --------------------------------------------------------------------
def dict_display_proc(dict_aa):
	for key in sorted(dict_aa.keys()):
		unit = dict_aa[key]
		name = unit['name']
		str_out = str(key) +"\t"+ str(name)
		str_out += "\t" + str(unit['population'])
		str_out += "\t" + str(unit['date_mod'])
		print(str_out)
# --------------------------------------------------------------------
def text_read_proc(file_in):
#
	fp_in = open(file_in,encoding='utf-8')
	lines = fp_in.readlines()
	fp_in.close()
#
	dict_aa = {}
	for line in lines:
		if (5 < len(line)):
			cols= line[:-1].split('\t')
			if (3 < len(cols)):
				try:
					if (cols[0][0] == "t"):
						dict_unit = {'name': cols[1], \
			'population':int (cols[2]),'date_mod':cols[3]}
						dict_aa[cols[0]] = dict_unit
				except:
					sys.stderr.write \
				("*** error *** %s ***\n" % file_in)
					sys.stderr.write \
				("*** %s ***\n" % line)
#
	return	dict_aa
#
# --------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
file_in = sys.argv[1]
#
try:
	dict_aa = text_read_proc(file_in)
	dict_display_proc(dict_aa)
except Exception as ee:
	sys.stderr.write("*** error *** in text_read_proc ***\n")
	sys.stderr.write(str(ee) + '\n')
#
sys.stderr.write("*** 終了 ***\n")
# --------------------------------------------------------------------
```

実行結果

```text
$ ./text_read.py cities.txt 
*** 開始 ***
t2381	名古屋	93514	1910-5-17
t2382	豊橋	31296	1910-9-10
t2383	岡崎	17459	1910-2-14
t2384	一宮	62542	1910-7-9
t2385	蒲郡	42619	1910-8-4
t2386	常滑	35182	1910-1-21
t2387	大府	81247	1910-7-23
t2388	瀬戸	25738	1910-10-26
t2389	犬山	74135	1910-12-15
*** 終了 ***
```

## ChatGPT が作成したプログラム

```exs:rch01.exs
defmodule TextRead do
  def display_dict(dict_aa) do
    dict_aa
    |> Enum.sort()
    |> Enum.each(fn {key, unit} ->
      name = unit[:name]
      str_out = "#{key}\t#{name}\t#{unit[:population]}\t#{unit[:date_mod]}"
      IO.puts(str_out)
    end)
  end

  def read_text(file_in) do
    {:ok, file} = File.open(file_in, [:read, :utf8])
    lines = IO.readlines(file)
    File.close(file)

    dict_aa =
      lines
      |> Enum.reduce(%{}, fn line, acc ->
        if byte_size(line) > 5 do
          cols = String.split(line, "\t", trim: true)
          if length(cols) > 3 do
            try do
              if String.at(cols[0], 0) == "t" do
                dict_unit = %{
                  name: cols[1],
                  population: String.to_integer(cols[2]),
                  date_mod: cols[3]
                }
                Map.put(acc, cols[0], dict_unit)
              else
                acc
              end
            rescue
              _ -> 
                IO.stderr()
                |> IO.write("error in text_read_proc\n")
                |> IO.inspect()
                acc
            end
          else
            acc
          end
        else
          acc
        end
      end)
    dict_aa
  end
end

# --------------------------------------------------------------------
IO.stderr
|> IO.write("*** 開始 ***\n")

file_in = hd(System.argv)
case TextRead.read_text(file_in) do
  {:ok, dict_aa} ->
    TextRead.display_dict(dict_aa)
  _error ->
    IO.stderr
    |> IO.write("*** error *** in text_read_proc ***\n")
end

IO.stderr
|> IO.write("*** 終了 ***\n")
# --------------------------------------------------------------------
```

実行結果

```text
$ elixir rch01.exs cities.txt 
** (UndefinedFunctionError) function IO.stderr/0 is undefined or private
    (elixir 1.14.0) IO.stderr()
    rch01.exs:53: (file)
    (elixir 1.14.0) lib/code.ex:1245: Code.require_file/2
```

## Gemini が作成したプログラム

```exs:rge01.exs
defmodule TextReader do
  def dict_display_proc(dict_aa) do
    Enum.each(Enum.sort(dict_aa.keys()), fn key ->
      unit = dict_aa[key]
      name = unit["name"]
      IO.puts("#{key}\t#{name}\t#{unit["population"]}\t#{unit["date_mod"]}")
    end)
  end

  def text_read_proc(file_in) do
    try do
      {:ok, lines} = File.read(file_in)
      dict_aa = Enum.reduce(lines, %{}, fn line, acc ->
        if String.length(line) > 5 do
          cols = String.split(line, "\t", trim: true)
          if Enum.count(cols) > 3 do
            try do
              if String.starts_with?(cols[0], "t") do
                dict_unit = %{
                  "name" => cols[1],
                  "population" => Integer.parse(cols[2]),
                  "date_mod" => cols[3]
                }
                Map.put(acc, cols[0], dict_unit)
              end
            rescue
              IO.stderr(:stderr, "*** error *** %s ***\n", [file_in])
              IO.stderr(:stderr, "*** %s ***\n", [line])
            end
          end
        end
        acc
      end)
      dict_aa
    rescue
      IO.stderr(:stderr, "*** error *** in text_read_proc ***\n")
      raise
    end
  end
end

IO.stderr(:stderr, "*** 開始 ***\n")
file_in = :erlang.element(2, System.get_argument())

try do
  dict_aa = TextReader.text_read_proc(file_in)
  TextReader.dict_display_proc(dict_aa)
rescue
  IO.stderr(:stderr, "*** error ***\n")
  IO.stderr(:stderr, "#{Exception.message}\n")
end

IO.stderr(:stderr, "*** 終了 ***\n")
```

実行結果

```text
$ elixir rge01.exs cities.txt 
** (CompileError) rge01.exs:45: expected -> clauses for :rescue in "try"
    (stdlib 4.2) lists.erl:1462: :lists.mapfoldl_1/3
    (stdlib 4.2) lists.erl:1463: :lists.mapfoldl_1/3
```

## 私が作成したプログラム

```exs:text_read.exs
# ------------------------------------------------------------------
#
#	text_read.exs
#
#						Mar/05/2024
# ------------------------------------------------------------------
defmodule MyModule do
  def dict_display_proc(dict_aa) do
    ll = Map.keys dict_aa
    IO.puts(length(ll))
    Enum.each(ll, fn(s) ->
	str_out =  to_string(s) <> "\t" <>  dict_aa[s].name  <> "\t" <> Integer.to_string(dict_aa[s].population) <> "\t" <> dict_aa[s].date_mod
	IO.puts(str_out)
	end)
  end

end
# ------------------------------------------------------------------
IO.puts :stderr,"*** 開始 ***"
[file_in | _] = System.argv()
IO.puts :stderr,file_in
#
{:ok, file} = File.open(file_in, [:read, :utf8])
contents = IO.read(file,:eof)
File.close(file)
lines = String.split(contents,["\n"])
IO.puts(length(lines))
lines_bb = Enum.filter(lines, fn x -> cols = String.split(x, "\t", trim: true)
		3 < length(cols) end)
list_aa = Enum.map(lines_bb, fn x -> cols = String.split(x, "\t", trim: true)
		key = Enum.at(cols,0)
		dict_unit = %{
			name: Enum.at(cols,1),
			population: String.to_integer(Enum.at(cols,2)),
			date_mod: Enum.at(cols,3)
			}
		[key, dict_unit]
		end)
		
dict_aa = Enum.reduce(list_aa, %{}, fn [key, value], acc ->
	Map.put(acc, key, value)
	end)

MyModule.dict_display_proc(dict_aa)
IO.puts :stderr,"*** 終了 ***"
# ------------------------------------------------------------------
```

実行結果

```text
$ elixir text_read.exs cities.txt
*** 開始 ***
cities.txt
10
9
t2381	名古屋	93514	1910-5-17
t2382	豊橋	31296	1910-9-10
t2383	岡崎	17459	1910-2-14
t2384	一宮	62542	1910-7-9
t2385	蒲郡	42619	1910-8-4
t2386	常滑	35182	1910-1-21
t2387	大府	81247	1910-7-23
t2388	瀬戸	25738	1910-10-26
t2389	犬山	74135	1910-12-15
*** 終了 ***
```