ChatGPTでマルチ言語
gen many lang
前回やった詩人の言語作成能力は、まったく未熟で、どうしようもないので、 流暢に多言語をしゃべるであろうChatGPTに再び登場願おう。
ただ流暢だねと感嘆するのが目的じゃなくて、別の思惑があるんだ。 仕様は、前回作成したものを流用する。
使う言語のバージョンを細かく指定してたんで、文句を言われるかと思ったら、 そこは無視いや寛容であった。ただ、作成したコードは、スケルトンだからね、 と、下記の警告が添えられたよ。
このコードは、指定された仕様に基づいて動作する基本的な骨組みを提供します。ただし、入力データの検証やエラーハンドリング、統計データの計算と表示など、いくつかの重要な部分は実装されていません。これらの部分を適切に実装することで、プログラムが正しく動作するようになります。
これは、宿題をコピペですまそうとする輩に苦慮した、文部科学省からの提案に、 OpenAIのCEOが忖度したものと思われる。何と言っても、日本はお得意様です からね。今月の日経Linuxでも、特集が組まれている。先取りするのが、もう けのこつ。後から日本産のAIが出てきても、牙城は切り崩せないわな。
golang
package main import ( "bufio" "fmt" "os" "sort" "strconv" "strings" "time" ) const ( maxDataCount = 70 fileName = "test.csv" ) type Measurement struct { Timestamp time.Time Hi int Lo int Pl int } func main() { args := os.Args[1:] if len(args) > 0 && (args[0] == "-h" || args[0] == "--help") { printHelp() return } if len(args) > 0 && args[0] == "-ire" && len(args) > 1 { inputAndRegisterData(args[1]) } displayStatistics() } func printHelp() { fmt.Println("Usage: bps [-h] [-ire yymm[dd]]") fmt.Println(" bps -h : Display this help message") fmt.Println(" bps -ire yymm[dd] : Input and register data interactively") } func inputAndRegisterData(inputDate string) { fmt.Printf("%s> ", inputDate) scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { line := scanner.Text() if line == "fin" { break } parts := strings.Fields(line) if len(parts) != 4 { fmt.Println("must be [d]dhh hi lo pl") continue } ddhh, err := strconv.Atoi(parts[0]) if err != nil || ddhh < 1 || ddhh > 3123 { fmt.Println("Invalid ddhh format") continue } hi, err := strconv.Atoi(parts[1]) if err != nil || hi < 80 || hi > 180 { fmt.Println("Invalid hi range") continue } lo, err := strconv.Atoi(parts[2]) if err != nil || lo < 50 || lo > 110 { fmt.Println("Invalid lo range") continue } pl, err := strconv.Atoi(parts[3]) if err != nil || pl < 40 || pl > 120 { fmt.Println("Invalid pl range") continue } timestamp := generateTimestamp(inputDate, ddhh) measurement := Measurement{Timestamp: timestamp, Hi: hi, Lo: lo, Pl: pl} registerMeasurement(measurement) fmt.Printf("%s> ", inputDate) } fmt.Println("append", len(data), "data's in", fileName) } func generateTimestamp(yymm string, ddhh int) time.Time { year, _ := strconv.Atoi("20" + yymm[:2]) month, _ := strconv.Atoi(yymm[2:4]) day := ddhh / 100 hour := ddhh % 100 return time.Date(year, time.Month(month), day, hour, 0, 0, 0, time.UTC) } var data []Measurement func registerMeasurement(measurement Measurement) { data = append(data, measurement) sort.Slice(data, func(i, j int) bool { return data[i].Timestamp.Before(data[j].Timestamp) }) saveToFile() } func saveToFile() { file, err := os.Create(fileName) if err != nil { fmt.Println("Error saving data:", err) return } defer file.Close() for _, measurement := range data { line := fmt.Sprintf("%s,%d,%d,%d\n", measurement.Timestamp.Format("06010215"), measurement.Hi, measurement.Lo, measurement.Pl) _, err := file.WriteString(line) if err != nil { fmt.Println("Error writing to file:", err) return } } } func displayStatistics() { // Implement the statistics display logic here fmt.Println("Statistics display not implemented yet") }
python
import os import sys import time import csv MAX_DATA_COUNT = 70 FILE_NAME = "test.csv" class Measurement: def __init__(self, timestamp, hi, lo, pl): self.timestamp = timestamp self.hi = hi self.lo = lo self.pl = pl def print_help(): print("Usage: bps [-h] [-ire yymm[dd]]") print(" bps -h : Display this help message") print(" bps -ire yymm[dd] : Input and register data interactively") def generate_timestamp(yymm, ddhh): year = 2000 + int(yymm[:2]) month = int(yymm[2:4]) day = ddhh // 100 hour = ddhh % 100 return time.datetime(year, month, day, hour, 0, 0) def register_measurement(measurement): data.append(measurement) data.sort(key=lambda x: x.timestamp) save_to_file() def save_to_file(): with open(FILE_NAME, "w", newline="") as file: writer = csv.writer(file) for measurement in data: writer.writerow([measurement.timestamp.strftime("%y%m%d%H"), measurement.hi, measurement.lo, measurement.pl]) def input_and_register_data(input_date): print(f"{input_date}> ", end="") for line in sys.stdin: line = line.strip() if line == "fin": break parts = line.split() if len(parts) != 4: print("must be [d]dhh hi lo pl") continue try: ddhh = int(parts[0]) if not 1 <= ddhh <= 3123: raise ValueError hi = int(parts[1]) if not 80 <= hi <= 180: raise ValueError lo = int(parts[2]) if not 50 <= lo <= 110: raise ValueError pl = int(parts[3]) if not 40 <= pl <= 120: raise ValueError except ValueError: print("Invalid input format or range") continue timestamp = generate_timestamp(input_date, ddhh) measurement = Measurement(timestamp, hi, lo, pl) register_measurement(measurement) print(f"{input_date}> ", end="") print(f"append {len(data)} data's in {FILE_NAME}") def display_statistics(): # Implement the statistics display logic here print("Statistics display not implemented yet") def main(): args = sys.argv[1:] if args and (args[0] == "-h" or args[0] == "--help"): print_help() return if args and args[0] == "-ire" and len(args) > 1: input_and_register_data(args[1]) display_statistics() if __name__ == "__main__": data = [] main()
haskell
import Data.List (sort) import Data.Time data Measurement = Measurement { timestamp :: UTCTime , hi :: Int , lo :: Int , pl :: Int } fileName :: String fileName = "test.csv" maxDataCount :: Int maxDataCount = 70 printHelp :: IO () printHelp = do putStrLn "Usage: bps [-h] [-ire yymm[dd]]" putStrLn " bps -h : Display this help message" putStrLn " bps -ire yymm[dd] : Input and register data interactively" generateTimestamp :: String -> Int -> UTCTime generateTimestamp yymm ddhh = UTCTime day time where year = read $ "20" ++ take 2 yymm month = read $ drop 2 yymm day = fromGregorian year month (fromIntegral $ ddhh `div` 100) time = secondsToDiffTime $ fromIntegral $ (ddhh `mod` 100) * 3600 registerMeasurement :: Measurement -> [Measurement] -> [Measurement] registerMeasurement measurement measurements = sort (measurement : measurements) saveToFile :: [Measurement] -> IO () saveToFile measurements = writeFile fileName content where content = unlines $ map formatMeasurement measurements formatMeasurement (Measurement ts hi lo pl) = formatTime defaultTimeLocale "%y%m%d%H" ts ++ "," ++ show hi ++ "," ++ show lo ++ "," ++ show pl inputAndRegisterData :: String -> IO () inputAndRegisterData inputDate = do putStr $ inputDate ++ "> " inputLoop [] where inputLoop measurements = do input <- getLine if input == "fin" then do putStrLn $ "append " ++ show (length measurements) ++ " data's in " ++ fileName saveToFile measurements else do let parts = words input if length parts /= 4 then putStrLn "must be [d]dhh hi lo pl" else case mapM readMaybe parts of Just [ddhh, hi, lo, pl] | 1 <= ddhh && ddhh <= 3123 && 80 <= hi && hi <= 180 && 50 <= lo && lo <= 110 && 40 <= pl && pl <= 120 -> do let timestamp = generateTimestamp inputDate ddhh measurement = Measurement timestamp hi lo pl inputLoop $ registerMeasurement measurement measurements _ -> putStrLn "Invalid input format or range" displayStatistics :: [Measurement] -> IO () displayStatistics measurements = putStrLn "Statistics display not implemented yet" main :: IO () main = do args <- getArgs case args of ["-h"] -> printHelp ["-ire", inputDate] -> inputAndRegisterData inputDate _ -> displayStatistics []
run
そのままで実行できるか、まずはpythonで試行する
[sakae@deb py-bps]$ python3 code.py -ire 2308 0104 120 70 60 2308> Traceback (most recent call last): File "/FBDEB/meet/py-bps/code.py", line 92, in <module> main() File "/FBDEB/meet/py-bps/code.py", line 86, in main input_and_register_data(args[1]) File "/FBDEB/meet/py-bps/code.py", line 68, in input_and_register_data timestamp = generate_timestamp(input_date, ddhh) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/FBDEB/meet/py-bps/code.py", line 26, in generate_timestamp return time.datetime(year, month, day, hour, 0, 0) ^^^^^^^^^^^^^ AttributeError: module 'time' has no attribute 'datetime'. Did you mean: 'asctime'?
pythonの事は、よく知らないのので、頑無視しておく。 golangはどうよ。
[sakae@deb go-bps]$ go run bps.go -ire 2308 2308> 0104 120 60 50 2308> 0121 123 65 55 2308> fin append 2 data's in test.csv Statistics display not implemented yet [sakae@deb go-bps]$ go run bps.go -ire 2308 2308> 1021 131 71 49 2308> fin append 1 data's in test.csv Statistics display not implemented yet [sakae@deb go-bps]$ cat test.csv 23081021,131,71,49
haskellはお約束で、多少のコード追加が必要。
import Text.Read(readMaybe) import System.Environment(getArgs) data Measurement = Measurement { timestamp :: UTCTime ... } deriving (Show, Eq, Read, Ord)
ghci> :main -ire 2308 2308> 1004 130 60 55 1021 128 64 59 fin append 2 data's in test.csv
プロンプトの扱かいが多少おかしいですねぇ。
考察
こんなに多言語のコードで、何をする? そう、仮説の検証ね。
AIの頭の中はどうなっている? きっと、コンパイラーみたいな作りになって るだろう。
ユーザーからの自由言語での依頼(様するにソースね)を、一旦扱い易い形式に 変換する。AST相当なものを作るんだな。これが作成できちゃえば、要求によっ て、要約してくださいとか、アイデアを提案してくださいとか、形式言語に変 換してくださいとか、どうとでもなる。
形式言語ってはの、python,golang,haskellと何でもごされだ。場合によって は、自然言語でもいいだろう。英語、中国語、アラビア語と、何でも翻訳でき ちゃう。 対応するモジュールを用意するだけで、自由に追加できる。
そういう目で、上のコードをみると、その言語用に翻訳してるだけじゃん。 きっと、そんな構造になってるんだろうね。
ファイルに追記してくれってお願いしたにもかかわらず、3者共、新規作成に なってる。これは、元の解釈をまちがえたんだな。
もうひとつ例をあげておく。一番大切なデータの持ち方の部分
// for golang type Measurement struct { Timestamp time.Time Hi int Lo int Pl int } # for python class Measurement: def __init__(self, timestamp, hi, lo, pl): self.timestamp = timestamp self.hi = hi self.lo = lo self.pl = pl -- for haskell data Measurement = Measurement { timestamp :: UTCTime , hi :: Int , lo :: Int , pl :: Int }
注目は、測定日の型。オイラーだったら、文字列にするか、整数かのどちらか にする(過去に作成したのは、整数にしてた)んだけどな。なんせ単純な型だか らね。いちいち、それぞれのモジュールを調べる気がしなかったってのが、真 相だ。
コンピュータにとっては、とっても不合理な、暦と時間の扱い。 1月から大の月(31)、小の月(30)と交互にやってくるのに、8月で、そのルールは、く つがえる。昔の王様の横暴。誕生月が、小の月ってのは、許せないとね。 こういう不都合さは、どんな言語を使おうが、つきまとう。ゆえに、不都合さ を緩和するモジュールが(普通は)提供される。
AIも、これに便乗してるのさ。整数にするなんて、めっそうも無い事と刻み こまれているんだな。