LoginSignup
2
1

ChatGPT で elixir を学ぶ (その6)text ファイルの update

Last updated at Posted at 2024-03-06

こちらの記事の続きです。
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
*** 終了 ***
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1