こちらの記事の続きです。
ChatGPT で elixir を学ぶ (その5)text ファイルの read
辞書に変換してから処理を行います。
Python のプログラム
text_update.py
#! /usr/bin/python
#
# update/text_update.py
#
# Mar/07/2024
import sys
import datetime
#
# ---------------------------------------------------------------
def dict_update_proc(dict_in,id,population):
key = str(id)
if key in dict_in:
dict_in[key]['population'] = population
date_mod = datetime.date.today()
dict_in[key]['date_mod'] = '%s' % date_mod
#
return dict_in
#
# ---------------------------------------------------------------
def text_write_proc(file_out,dict_aa):
#
fp_out = open(file_out,mode='w', encoding='utf-8')
for key in dict_aa.keys():
unit = dict_aa[key]
str_out = key + "\t" + str(unit['name']) + "\t"
str_out += "%d\t" % unit['population']
str_out += unit['date_mod'] + "\n"
fp_out.write(str_out)
fp_out.close()
# ---------------------------------------------------------------
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]
id_in = sys.argv[2]
population_in = int(sys.argv[3])
print("%s\t%d" % (id_in, population_in))
dict_aa = text_read_proc(file_in)
dict_bb=dict_update_proc(dict_aa,id_in,population_in)
text_write_proc(file_in,dict_bb)
#
sys.stderr.write("*** 終了 ***\n")
# ---------------------------------------------------------------
実行結果
$ ./text_update.py cities.txt t2387 76182500
*** 開始 ***
t2387 76182500
*** 終了 ***
ChatGPT が作成したプログラム
uch01.exs
defmodule TextUpdate do
defmodule Functions do
def dict_update_proc(dict_in, id, population) do
key = Integer.to_string(id)
if key in dict_in do
updated_date_mod = Date.utc_today()
dict_in
|> Map.update!(key, fn unit ->
Map.put(unit, "population", population)
|> Map.put("date_mod", "#{updated_date_mod}")
end)
else
dict_in
end
end
def text_write_proc(file_out, dict_aa) do
File.write!(file_out, Enum.map(dict_aa, fn {key, unit} ->
str_out = "#{key}\t#{unit["name"]}\t"
str_out <> "#{unit["population"]}\t#{unit["date_mod"]}\n"
end) |> Enum.join())
end
def text_read_proc(file_in) do
File.read!(file_in)
|> String.split("\n", trim: true)
|> Enum.reduce(%{}, fn line, dict_aa ->
cols = String.split(line, "\t")
if length(cols) > 3 && String.starts_with?(hd(cols), "t") do
try do
dict_unit = %{
"name" => List.first(Enum.drop(cols, 1)),
"population" => String.to_integer(Enum.at(cols, 2)),
"date_mod" => Enum.at(cols, 3)
}
Map.put(dict_aa, hd(cols), dict_unit)
rescue
_ ->
IO.stderr |> IO.puts("*** error *** #{file_in} ***")
IO.stderr |> IO.puts("*** #{line} ***")
dict_aa
end
else
dict_aa
end
end)
end
end
def run([file_in, id_in, population_in]) do
IO.puts("#{id_in}\t#{String.to_integer(population_in)}")
dict_aa = Functions.text_read_proc(file_in)
dict_bb = Functions.dict_update_proc(dict_aa, String.to_integer(id_in), String.to_integer(population_in))
Functions.text_write_proc(file_in, dict_bb)
end
end
TextUpdate.run(System.argv())
実行結果
$ elixir uch01.exs cities.txt t2382 18234500
t2382 18234500
** (ArgumentError) errors were found at the given arguments:
* 1st argument: not a textual representation of an integer
:erlang.binary_to_integer("t2382")
uch01.exs:53: TextUpdate.run/1
(elixir 1.14.0) lib/code.ex:1245: Code.require_file/2
Gemini が作成したプログラム
uge01.exs
defmodule TextUpdate do
# Function to update a dictionary entry based on ID and population
def dict_update_proc(dict_in, id, population) do
case Map.get(dict_in, id) do
nil -> dict_in
_ ->
updated_value = %{
name: Map.get(dict_in, id)["name"],
population: population,
date_mod: Date.utc().to_string()
}
Map.put(dict_in, id, updated_value)
end
end
# Function to write a dictionary to a text file
def text_write_proc(file_out, dict_aa) do
File.open!(file_out, [:write, :encode => "utf-8"]) |>
Enum.each(dict_aa, fn {key, unit} ->
str_out = "#{key}\t#{unit["name"]}\t#{unit["population"]}\t#{unit["date_mod"]}\n"
IO.write(str_out)
end) |>
File.close()
end
# Function to read a text file into a dictionary
def text_read_proc(file_in) do
File.stream!(file_in, [:read, :encode => "utf-8"]) |>
Enum.reduce(%{}, fn line, dict ->
if String.length(line) > 5 do
[_, name, population_str, date_mod] = String.split(line, "\t", trim: true)
try do
population = Integer.parse!(population_str)
if String.starts_with?(key, "t") do
dict = Map.put(dict, key, %{
name: name,
population: population,
date_mod: date_mod
})
end
dict
rescue
IO.stderr(:write, "*** error *** #{file_in} ***\n")
IO.stderr(:write, "*** #{line} ***\n")
dict
end
else
dict
end
end)
end
def main(args) do
IO.stderr(:write, "*** 開始 ***\n")
[file_in, id_in, population_in_str] = args
id_in = String.to_integer(id_in)
population_in = String.to_integer(population_in_str)
IO.puts("#{id_in}\t#{population_in}")
dict_aa = text_read_proc(file_in)
dict_bb = dict_update_proc(dict_aa, id_in, population_in)
text_write_proc(file_in, dict_bb)
IO.stderr(:write, "*** 終了 ***\n")
end
end
TextUpdate.main(Application.get_argument(:script, []))
実行結果
$ elixir uge01.exs cities.txt t2384 82134500
** (SyntaxError) uge01.exs:19:43: syntax error before: '=>'
|
19 | File.open!(file_out, [:write, :encode => "utf-8"]) |>
| ^
(elixir 1.14.0) lib/code.ex:1245: Code.require_file/2
私が作成したプログラム
text_update.exs
# ------------------------------------------------------------------
#
# text_update.exs
#
# Mar/05/2024
# ------------------------------------------------------------------
defmodule MyModule do
# ------------------------------------------------------------------
def dict_update_proc(dict_in, key, population) do
# IO.inspect(key)
# IO.inspect(dict_in)
if Map.has_key?(dict_in,key) do
IO.puts :stderr,"*** key exist ***"
updated_date_mod = Date.utc_today()
IO.puts :stderr,updated_date_mod
dict_in
|> Map.update!(key, fn unit ->
Map.put(unit, :population, population)
|> Map.put(:date_mod, "#{updated_date_mod}")
end)
else
IO.puts :stderr,"*** key not exist ***"
dict_in
end
end
# ------------------------------------------------------------------
def text_read_proc(file_in) do
{: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,name,population_str,date_mod] = cols
population = String.to_integer(population_str)
dict_unit = %{name: name,population: population, date_mod: date_mod}
[key, dict_unit]
end)
Enum.reduce(list_aa, %{}, fn [key, value], acc ->
Map.put(acc, key, value)
end)
end
# ------------------------------------------------------------------
def text_write_proc(file_out,dict_aa) do
{:ok, fp_out} = File.open(file_out, [:write, :utf8])
ll = Map.keys dict_aa
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 <> "\n"
IO.write(fp_out,str_out)
end)
File.close(fp_out)
end
# ------------------------------------------------------------------
end
# ------------------------------------------------------------------
IO.puts :stderr,"*** 開始 ***"
[file_in, id_in, population_in_str] = System.argv()
IO.puts :stderr,file_in
population_in = String.to_integer(population_in_str)
IO.puts("#{id_in}\t#{population_in}")
dict_aa = MyModule.text_read_proc(file_in)
dict_bb = MyModule.dict_update_proc(dict_aa, id_in, population_in)
# IO.inspect(dict_bb)
MyModule.text_write_proc(file_in, dict_bb)
IO.puts :stderr,"*** 終了 ***"
# ------------------------------------------------------------------
実行結果
$ elixir text_update.exs cities.txt t2388 19534600
*** 開始 ***
cities.txt
t2388 19534600
*** key exist ***
2024-03-07
*** 終了 ***