ラベル プログラミング の投稿を表示しています。 すべての投稿を表示
ラベル プログラミング の投稿を表示しています。 すべての投稿を表示

2023年4月10日月曜日

教養強化合宿(6)

教養強化合宿(5)からの続き

外山恒一が,Facebookで今回の8日間の合宿で取り上げた人物のリストを公開していた。その数は約165人。一方,前回のnoteに書いていた教養強化合宿余興で登場した人物の数は,約260人。その和集合をとって,重複したものを◎,後者にのみ含まれたものを●で表した。その中で自分が名前くらいは聞いたことがある人は約200名弱(3/4)だった。✓をつけてある。

このリストをHTML化にするにあたって,GPT-4に作業をさせてみた。例えば,次のような自然言語プログラミングを行うわけだ。
『htmlファイル中に人名リストを埋め込もうとしています。次のような1行のテキストデータを,●会田誠(あいだまこと)✓ このようなhtml形式に変換してほしいのです。●<a href="https://ja.wikipedia.org/wiki/会田誠">会田誠</a>(あいだまこと)✓<br /> 以下にデータを与えますので,すべて同様な変換を施してください。』

入力データサイズや一度に出力できるデータのサイズには制限があるものの,正しい結果が得られる。問題は,時間がかかることだ。GPT-4やChatGPTは対話システムとして公開されているので,そのスピードでしか文字が出力されない。毎秒8文字程度なので,このままでは実用的な仕事にならない。 潜在能力はあるし,将来的に出力をファイル化できればこれは簡単にクリアできる話なのだが。

現時点では,GPT-4に直接実行させるのではなく,それを実行するプログラムを考えさせるのがよい。そこで,さきほどの命令に「これを実現するPerlプログラムを書いてください」としてほぼ思った結果が得られた。少し人間の手を加えてチューニングした結果が次のものだ。実行時間問題はこうして解決される。

#!/usr/bin/perl

use strict;

use warnings;

use utf8;


binmode(STDIN, ':encoding(utf8)');

binmode(STDOUT, ':encoding(utf8)');


while (my \$line = <>) {

    chomp \$line;

    if (\$line =~ /([●◎○])(.+?)((.+?))(.+?)([✓_])/) {

        my \$kigou = \$1;

        my \$name = \$2;

        my \$name_kana = \$3;

        my \$prop = \$4;

        my \$check = \$5;

        my \$url = "https://ja.wikipedia.org/wiki/\$name";

        print "\$kigou<a href=\"\$url\">\$name</a>(\$name_kana) \$prop \$check<br />\n";

    }

}

なお,リンク先はWikipediaとしたが,2-3名以外はすべてこれでカバーすることができている。自分が普段書くような簡単なプログラムは,文法を確認しながらロジックを考えるのが面倒だから,GPT-4まかせになってしまうのがほぼ確定だ。で,プログラミング教育とは何?
 外山恒一教養強化合宿の登場人物リストを参照の上編集
会田誠(あいだまこと) 画家 ✓
青島幸男(あおしまゆきお) 放送作家 ✓
赤尾敏(あかおびん) 大日本愛国党 ✓
あがた森魚(あがたもりお) 赤色エレジー ✓
秋田明大(あきためいだい) 日大全共闘 ✓
秋山祐徳太子(あきやまゆうとくたいし) 現代美術家 ✓
アグネス・スメドレー(あぐねすめどれー) 中国共産党 _
浅羽通明(あさばみちあき) 評論家 ✓
東浩紀(あずまひろき) ゲンロン ✓
足立正生(あだちまさお) 日本赤軍 _
天野恵一(あまのけいいち) 評論家 _
雨宮処凛(あまみやかりん) 反貧困ネットワーク ✓
網野善彦(あみのよしひこ) 歴史学者 ✓
荒畑寒村(あらはたかんそん) 社会主義者 ✓
アレクサンドル・ソルジェニーツィン(あれくさんどるそるじぇにーつぃん) 収容所群島 ✓
アレン・ギンズバーグ(あれんぎんずばーぐ) 詩人 _
アンジェイ・ワイダ(あんじぇいわいだ) 映画監督 ✓
アンディ・ウォーホル(あんでぃうぉーほる) 現代美術家 ✓
アントニオ・グラムシ(あんとにおぐらむし) イタリア共産党 _
家永三郎(いえながさぶろう) 教科書裁判 ✓
イサドラ・ダンカン(いさどらだんかん) 舞踏家 ✓
石川一雄(いしかわかずお) 狭山裁判 ✓
石原莞爾(いしわらかんじ) 満州事変 ✓
石牟礼道子(いしむれみちこ) 苦海浄土 ✓
磯部浅一(いそべあさいち) 粛軍に関する意見書 _
五木寛之(いつきひろゆき) 作家 ✓
いとうせいこう(いとうせいこう) タレント ✓
伊藤律(いとうりつ) 日本共産党 ✓
伊藤野枝(いとうのえ) 婦人解放運動 ✓
井上嘉浩(いのうえよしひろ) オウム真理教 ✓
忌野清志郎(いまわのきよしろう) ロック歌手 ✓
宇井純(ういじゅん) 公害問題 ✓
植垣康博(うえがきやすひろ) 連合赤軍 ✓
上杉慎吉(うえすぎしんきち) 君権学派 _
上田耕一郎(うえだこういちろう) 日本共産党 ✓
内田裕也(うちだゆうや) 樹木希林 ✓
ウディ・アレン(うでぃあれん) 映画監督 ✓
宇野弘蔵(うのこうぞう) 宇野経済学 ✓
江田三郎(えださぶろう) 社会市民連合 ✓
江藤淳(えとうじゅん) 評論家 ✓
衛藤晟一(えとうせいいち) 全国学協 ✓
エドガー・スノウ(えどがーすのう) 中国の赤い星 _
榎美沙子(えのきみさこ) 中ピ連 ✓
大島渚(おおしまなぎさ) 映画監督 ✓
太田竜(おおたりゅう) 第四インターナショナル ✓
大塚英志(おおつかひでし) マンガ評論家 ✓
大宅壮一(おおやそういち) 評論家 ✓
岡田嘉子(おかだよしこ) ソ連逃避行 ✓
岡留安則(おかどめやすのり) 噂の真相 ✓
岡林信康(おかばやしのぶやす) 友よ ✓
岡本公三(おかもとこうぞう) テルアビブ事件 ✓
小川紳介(おがわしんすけ) 三里塚シリーズ ✓
奥田愛基(おくだあき) シールズ ✓
小熊英二(おぐまえいじ) 社会学者 _
小倉千加子(おぐらちかこ) フェミニスト ✓
小沢開作(おざわかいさく) 小沢征爾 ✓
小畑達夫(おばたたつお) 日本共産党スパイ事件 _
笠原和夫(かさはらかずお) 仁義なき戦い _
柏崎千枝子(かしわざきちえこ) ゲバルトローザ _
片山潜(かたやません) 社会主義者 ✓
加藤登紀子(かとうときこ) ひとり寝の子守歌 ✓
加藤直樹(かとうなおき) 九月,東京の路上で ✓
椛島有三(かばしまゆうぞう) 日本青年協議会 ✓
神近市子(かみちかいちこ) 婦人運動家 ✓
ガヤトリ・スピヴァク(がやとりすぴゔぁく) 文芸評論家 _
萱野茂(かやのしげる) アイヌ文化 _
香山リカ(かやまりか) 精神科医 ✓
川上音二郎(かわかみおとじろう) オッペケペー ✓
川口大三郎(かわぐちだいざぶろう) 早稲田構内リンチ事件 ✓
川田龍平(かわたりゅうへい) 薬害エイズ ✓
川本三郎(かわもとさぶろう) 評論家 ✓
菅孝行(かんたかゆき) 反天皇制運動連絡会 _
管野スガ(かんのすが) 女性新聞記者 _
樺美智子(かんばみちこ) 60年安保 ✓
カール・リープクネヒト(かーるりーぷくねひと) ローザ・ルクセンベルグ _
木下ちがや(きのしたちがや) こたつねこ ✓
木村三浩(きむらみつひろ) 一水会 _
清義明(せいよしあき) フリーライター ✓
金賢姫(きむひょんひ) 大韓航空機爆破事件 ✓
ギー・ドゥボール(ぎーどぅぼーる) アンテルナシオナル・レトリスト _
熊沢天皇(くまざわてんのう) 皇位僭称者 _
倉橋由美子(くらはしゆみこ) パルタイ ✓
蔵原惟人(くらはらこれひと) 評論家 ✓
栗本慎一郎(くりもとしんいちろう) 経済人類学 ✓
鴻上尚史(こうかみしょうじ) 劇作家 ✓
江青(こうせい) 文化大革命 ✓
荒岱介(あらたいすけ) ブント戦旗派 _
古賀政男(こがまさお) 明治大学マンドリン倶楽部 ✓
粉川哲夫(こがわてつお) 批評家 ✓
小阪修平(こさかしゅうへい) 東大全共闘 ✓
児玉誉士夫(こだまよしお) ロッキード事件 ✓
五島勉(ごとうべん) ノストラダムスの予言 ✓
小林よしのり(こばやしよしのり) ゴーマニズム宣言 ✓
コンスタンチン・スタニスラフスキー(こんすたんちんすたにすらふすきー) 演出家 ✓
権藤成卿(ごんどうせいきょう) 農本主義思想家 _
今野晴貴(こんのはるき) POSSE _
西光万吉(さいこうまんきち) 水平社宣言 ✓
斎藤幸平(さいとうこうへい) 人新世の資本論 ✓
堺利彦(さかいとしひこ) 社会主義者 ✓
坂口恭平(さかぐちきょうへい) 建築家 _
坂口弘(さかぐちひろし) あさま山荘事件 ✓
桜井大造(さくらいたいぞう) 風の旅団 _
桜井誠(さくらいまこと) 在日特権を許さない市民の会 ✓
佐々淳行(ささあつゆき) 警察官僚 ✓
笹川良一(ささがわりょういち) 日本船舶振興会 ✓
佐藤悟志(さとうさとし) 青狼会 ✓
サミュエル・ベケット(さみゅえるべけっと) 劇作家 ✓
沢木耕太郎(さわきこうたろう) ノンフィクション作家 ✓
椹木野衣(さわらぎのい) 美術評論家 _
ジェリー・ルービン(じぇりーるーびん) シカゴ・セブン _
塩見孝也(しおみたかや) 赤軍派議長 ✓
重信房子(しげのぶふさこ) 日本赤軍 ✓
島成郎(しましげお) 全学連書記長 ✓
島田雅彦(しまだまさひこ) 作家 ✓
清水幾太郎(しみずいくたろう) 社会学者 ✓
清水丈夫(しみずたけお) 中核派 ✓
シモーヌ・ヴェイユ(しもーぬゔぇいゆ) 哲学者 ✓
ジャック・ケルアック(じゃっくけるあっく) 小説家 _
ジャニス・ジョプリン(じゃにすじょぷりん) ロック歌手 ✓
ジャン・リュック・ゴダール(じゃんりゅっくごだーる) 映画監督 ✓
正力松太郎(しょうりきまつたろう) 読売新聞社 ✓
ジョニー・ロットン(じょにーろっとん) パンクロック _
ジョルジョ・アガンベン(じょるじゅあがんべん) 哲学者 _
ジョルジュ・ソレル(じょるじゅそれる) 哲学者 _
ジョン・リード(じょんりーど) レッズ ✓
ジョージ・ハリスン(じょーじはりすん) ビートルズ ✓
ジョーン・バエズ(じょーんばえず) フォーク歌手 ✓
白井聡(しらいさとし) 白井克彦 ✓
菅野完(すがのたもつ) 日本会議の研究 ✓
鈴木忠志(すずきただし) 演出家 ✓
スチュアート・ホール(すちゅあーとほーる) 文化理論家 _
ストークリー・カーマイケル(すとーくりーかーまいける) 差別撤廃闘争指導者 _
スラヴォイ・ジジェク(すらゔぉいじじぇく) 哲学者 ✓
大道寺将司(だいどうじまさし) 東アジア反日武装戦線 ✓
高田渡(たかだわたる) フォーク歌手 ✓
高野実(たかのみのる) 高野猛 ✓
高畠素之(たかばたけもとゆき) 国家社会主義 _
滝田修(たきたおさむ) 新左翼活動家 ✓
宅八郎(たくはちろう) タレント ✓
武井昭夫(たけいあきお) 全学連初代委員長 _
竹中労(たけなかろう) ルポライター ✓
田嶋陽子(たじまようこ) フェミニスト ✓
橘孝三郎(たちばなこうざぶろう) 農本ファシスト _
立松和平(たてまつわへい) 作家 ✓
田中清玄(たなかせいげん) CIAフィクサー ✓
田中美津(たなかみつ) ウーマン・リブ _
谷川雁(たにがわかり) 詩人 ✓
谷口雅春(たにぐちまさはる) 生長の家 ✓
田宮高麿(たみやたかまろ) よど号事件 ✓
筑紫哲也(つくしてつや) ジャーナリスト ✓
知花昌一(ちばなまさかず) 平和運動家 _
千葉雅也(ちばまさや) 哲学者 ✓
チャンドラ・ボース(ちゃんどらぼーす) インド独立運動 ✓
チャールズ・マンソン(ちゃーるずまんそん) マンソンファミリー _
陳独秀(ちんどくしゅう) 中国共産党 _
つかこうへい(つかこうへい) 劇作家 ✓
津田大介(つだだいすけ) ツダる ✓
堤清二(つつみせいじ) 辻井喬 ✓
鶴見済(つるみわたる) 完全自殺マニュアル _
ティモシー・リアリー(てぃもしーりありー) 心理学者 _
峠三吉(とうげさんきち) 原爆詩集 ✓
唐十郎(からじゅうろう) 状況劇場 ✓
頭山満(とうやまみつる) 国家主義者 ✓
戸川純(とがわじゅん) 女優 ✓
徳田球一(とくだきゅういち) 日本共産党 ✓
戸村一作(とむらいっさく) 三里塚芝山連合空港反対同盟委員長 ✓
トルーマン・カポーティ(とるーまんかぽーてぃ) 小説家 ✓
仲井戸麗市(なかいどれいいち) RCサクセション ✓
中川敬(なかがわたかし) ソウル音楽家 _
永田洋子(ながたようこ) 連合赤軍 ✓
中野重治(なかのしげはる) 小説家 ✓
中野正剛(なかのせいごう) ジャーナリスト ✓
永山則夫(ながやまのりお) 無知の涙 ✓
ナジ・イムレ(なじいむれ) ハンガリー動乱 _
ナンシー関(なんしーせき) コラムニスト ✓
ナンシー・スパンゲン(なんしーすぱんげん) セックスピストルズ _
難波大助(なんばだいすけ) 極左活動家 ✓
西尾幹二(にしおかんじ) 新しい歴史教科書を作る会 ✓
西部邁(にしべすすむ) 保守思想家 ✓
蜷川幸雄(にながわゆきお) 演出家 ✓
沼正三(ぬましょうぞう) 家畜人ヤプー ✓
野坂参三(のさかさんぞう) 日本共産党 ✓
野田秀樹(のだひでき) 劇作家 ✓
野間易通(のまやすみち) レイシストをしばき隊 ✓
野村秋介(のむらしゅうすけ) 民族派活動家 ✓
萩尾望都(はぎおもと) 漫画家 ✓
萩原朔美(はぎはらさくみ) 映像作家 _
パティ・スミス(ぱてぃすみす) クイーンオブパンク _
花田清輝(はなだせいき) 文芸評論家 ✓
埴谷雄高(はにやゆたか) 小説家 ✓
浜田幸一(はまだこういち) 政治家 ✓
日比野克彦(ひびのかつひこ) アーティスト ✓
ヒューイ・ニュートン(ひゅーいにゅーとん) 公民権運動 _
平岡正明(ひらおかまさあき) 評論家 ✓
平田オリザ(ひらたおりざ) 劇作家 ✓
ビリー・ホリデイ(びりーほりでい) ジャズ歌手 ✓
広瀬隆(ひろせたかし) 東京に原発を ✓
ピート・シーガー(ぴーとしーがー) フォーク歌手 ✓
福田和也(ふくだかずや) 文芸評論家 _
福田恆存(ふくだつねあり) 評論家 ✓
福本和夫(ふくもとかずお) 経済学者 ✓
藤岡信勝(ふじおかのぶかつ) 新しい歴史教科書を作る会 ✓
船本洲治(ふなもとしゅうじ) 革命思想家 _
フランシス・フクヤマ(ふらんしすふくやま) 政治経済学者 ✓
古田重二良(ふるたじゅうじろう) 日本大学理事長 _
不破哲三(ふわてつぞう) 日本共産党 ✓
別役実(べつやくみのる) 劇作家 ✓
ベルトルト・ブレヒト(べるとるとぶれひと) 劇作家 ✓
某Fラン政治学者(五○井郁○) (○の○○○お) 政治学者 ✓
ボブ・マーリー(ぼぶまーりー) レゲエ歌手 ✓
本多勝一(ほんだかついち) 作家 ✓
本島等(もとしまひとし) 長崎市長 ✓
真島昌利(ましままさとし) ギタリスト _
松崎明(まつざきあきら) 革マル派副議長 ✓
松沢呉一(まつざわくれいち) コラムニスト ✓
松下竜一(まつしたりゅういち) 作家 ✓
松本治一郎(まつもとじいちろう) 部落解放同盟 ✓
松本哉(まつもとはじめ) 素人の乱 ✓
マハリシ・ヨギ(まはりしよぎ) 超越瞑想 _
黛敏郎(まゆずみとしろう) 作曲家 ✓
マルコム・マクラレン(まるこむまくられん) セックスピストルズ _
マルセル・デュシャン(まるせるでゅしゃん) ダダイスト ✓
三上卓(みかみたく) 青年日本の歌 _
三上寛(みかみひろし) フォーク歌手 ✓
ミサオ・レッドウルフ(みさおれっどうるふ) 首都圏反原発連合 _
道浦母都子(みちうらもとこ) 歌人 ✓
南伸坊(みなみしんぼう) イラストレーター ✓
宮﨑勤(みやざきつとむ) 連続幼女誘拐殺人事件 ✓
宮崎滔天(みやざきとうてん) 社会運動家 ✓
宮崎学(みやざきまなぶ) 評論家 ✓
宮崎龍介(みやざきりゅうすけ) 白蓮事件 _
宮沢章夫(みやざわあきお) 劇作家 ✓
宮武外骨(みやたけがいこつ) ジャーナリスト ✓
宮本百合子(みやもとゆりこ) 作家 ✓
向井孝(むかいたかし) 社会運動家 _
森達也(もりたつや) ドキュメンタリーディレクター ✓
森田必勝(もりたひっしょう) 三島由紀夫事件 ✓
森田実(もりたみのる) 政治評論家 ✓
森恒夫(もりつねお) 連合赤軍 ✓
安岡正篤(やすおかまさひろ) 思想家 ✓
柳原白蓮(やなぎはらびゃくれん) 歌人 ✓
矢部史郎(やぶしろう) 思想家 _
山岡強一(やまおかきょういち) 映画監督 _
山口二矢(やまぐちおとや) 浅沼稲次郎暗殺 ✓
山崎博昭(やまざきひろあき) 第1次羽田事件 ✓
山下洋輔(やましたようすけ) ドバラダ門 ✓
山田塊也(やまだかいや) コミューン運動“部族” _
山本太郎(やまもとたろう) れいわ新選組 ✓
山本夜羽音(やまもとよはね) 漫画家 ✓
山本義隆(やまもとよしたか) 東大全共闘 ✓
湯浅誠(ゆあさまこと) 社会活動家 ✓
吉本隆明(よしもとりゅうめい) 擬制の終焉 ✓
ラモン・メルカデル(らもんめるかでる) 暗殺者のメロディ _
劉少奇(りゅうしょうき) 文化大革命 ✓
林彪(りんぴょう) 中国共産党 ✓
ルイジ・ピランデルロ(るいじぴらんでるろ) 劇作家・小松左京  ✓
レニ・リーフェンシュタール(れにりーふぇんしゅたーる) 映画監督 ✓
ろくでなし子(ろうでなしこ) 漫画家 ✓
ロバート・ジョンソン(ろばーとじょんそん) ブルースギター _
渡辺京二(わたなべきょうじ) 逝きし世の面影 ✓

2023年4月9日日曜日

アニメーション

GPT-4に次のようなプロンプトを与えた。
・プログラミング言語のprocessingを知っていますか?
・簡単なアニメーションで,マウスで操作できるカラフル(淡いパステルカラー)でかわいい見本プログラムのコードを書いてもらえますか。
・ありがとうございます。マウス操作は必要ないので,100個ぐらいの小さなボールが動きまわるような見本に修正してもらえますか。
・どうもありがとうございます,とてもすてきですね。ところでこのボールは領域の境界で反射してますが,ボール同士の衝突は考慮されておらずそのまま透過しているようです。衝突するボールが反射するようにできますか。ボールの円の境界で反射方向を決定するのが面倒ならば,ボールの中心座標で代替する近似を使うことも検討してください。

その結果,次のようなコードが生成された。パラメタを少し修正して,tifファイルに書き出した。これを使ってProcessingのツール/ムービーメーカーでアニメーションGIFに変換した。よくある例題だから,学習済みなのだろうけれど,なかなかのものだ。


図:GPT-4で生成したProcessingアニメーション

2023年4月8日土曜日

マインドマップ

へのへのもへじからの続き

画像生成AIは引き続き進化中だ。一方,GPT-4を用いて画像を生成する方法がいくつか考えられる。(1) アスキーアートの文字列を出力,(2) SVGのコードを出力,(3) 画像描画が簡単なプログラミング言語等のコードを出力(Processing,Javascript,Python,Mathematica,PlantUML,LaTeXのTikZ)するなどだ。

プロンプト工学を駆使せずに簡単にできる範囲で試してみた。左はうさぎのアスキーアート,右は,植物と鳥のイメージということだった。前者の入力は「アスキーアートを知っていますか。ひとつ例をかいてみてください」(中略)「その例は20-30文字程度ですね。100文字には到達していません。もう少し複雑なものを書いてください」。後者は,「植物の絵を表すsvgコードを出力し下さい」「なかなかいい感じですね。もっと複雑にするとともに,同じ程度複雑な動物を隣に描いてください」の結果だ。

図:GPT-4にかかせたアスキーアートとSVG

さて,ChatGPTにマインドマップを書かせるという例題があったので,自分でも試してみた。昨年の9月に,PlantUMLというツールをインストールしていた。すっかり忘れていた。このPlantUMLは,マインドマップを書かせる機能も備えている。

そこで,次のようなプロンプトを与えた。「スマホのアプリ開発を機種(OS)やクラスプラットホーム別に整理した(開発環境とブログラム言語)マインドマップを出力するPlantUMLコードを書いてください」その結果をUMLファイルとして保存し,PlantUMLにかけると次の画像ファイルができた。


図:GPT-4が生成したマインドマップ

2023年3月26日日曜日

へのへのもへじ

ネット上で誰かが,「へのへのもへじ」より「へめへめくつし」がいいねといった。ホウ,そんなものがあったのか,と一瞬思ったけれど,そういえば昔いろいろと試していたような気もする。それほどビックリする話題ではない。

むしろ,テレビで外国人の平熱が37度台であると知ったことの方が驚きだ。これは筋肉が多い人について成り立つらしく,日本のボディビルダーに体温がやはり37度台であることを検証していた。どこまで正しいかわからないけれど。

そこで,へのへのもへじ出力プログラムを作ってみた。最初は,TeXのTikZで書いた。こんな感じ。ベジェ曲線が手軽に使えるのがありがたい。

\begin{tikzpicture}
\draw[gray, step=1, dotted] (0,0) grid (6,6);
\draw (2,5) node[below]{\Huge \${〜}\$};
\draw (2,4) node[below]{\Huge \${め}\$};
\draw (4.2,5) node[below]{\Huge \${〜}\$};
\draw (4.2,4) node[below]{\Huge \${め}\$};
\draw (3,3) node[below]{\Huge \${く}\$};
\draw (3.3,1.9) node[below]{\Huge \${つ}\$};
\draw [ultra thick] (1,5.5) .. controls (0.5,2) and (1.25,0.75)  ..(2,0.5);
\draw [ultra thick] (2,0.5) .. controls (3,0) and (5,0)  ..(5.5,2);
\draw (5.5,3) node[below]{\Huge \${々}\$};
\end{tikzpicture}


図1:LaTeXのTikZで書いたへのへのもへ字

これだと,文字を入れ替えるたびにコードを書き換えることになる。そこで,pythonで作り直そうとしてGPT-4に聞いてみたら,ほぼ1発で正しいコードが得られた。macOSのフォントの場所だけを指定すれば良かった。さらに,コマンドラインからひらがなを入力して文字に分解するところもGPT-4に教えてもらった。これからのプログラミング教育はどうなるのだろう?

問題は,pythonのpillowライブラリにはベジェ曲線がないことだ。おまけに,最初の結果は顔の輪郭は直線4本で表され,顔に被ってしまっていた。GPT-4はそこまで賢いわけではない。仕方がないので,自力でもがいて作った折れ線グラフで代用している。プログラミング教育って絶対にこうなるから。論理的ではない部分が多すぎる。

#! ~/bin/python


from PIL import Image, ImageDraw, ImageFont

import sys


def generate_henohenomoheji(brow: str, eye: str, nose: str, mouth: str, file_name: str):

     

    # 背景画像を作成

    image = Image.new('RGB', (600,600), (255, 255, 255))

    draw = ImageDraw.Draw(image)


    # フォントの設定

    font_size = 80

    font = ImageFont.truetype("/Users/koshi/Library/Fonts/BIZUDGothic-Regular.ttf", font_size)


    # へのへのもへじの要素を描画

    draw.text((160, 120), brow, font=font, fill=(0, 0, 0))  # 眉毛

    draw.text((340, 120), brow, font=font, fill=(0, 0, 0))  # 眉毛

    draw.text((180, 200), eye, font=font, fill=(0, 0, 0))   # 目

    draw.text((330, 200), eye, font=font, fill=(0, 0, 0))   # 目

    draw.text((240, 290), nose, font=font, fill=(0, 0, 0))  # 鼻

    draw.text((250, 380), mouth, font=font, fill=(0, 0, 0)) # 口

    draw.text((480, 240), "〃", font=font, fill=(0, 0, 0))  # 濁点


    # 顔の輪郭(ベジェ曲線ではない)

    contour = [

        (100, 100), (110, 150), (110, 200), (100, 250), (100, 300),

        (110, 340), (120, 380), (140, 410), (160, 440), (180, 460),

        (200, 480), (220, 490), (240, 500), (260, 505), (280, 505),

        (300, 500), (320, 500), (340, 495), (360, 495), (370, 490),

        (390, 480), (410, 470), (430, 460), (450, 440), (470, 410),

        (480, 380), (480, 360), (475, 340), (470, 310), (470, 280),

    ]

    draw.line(contour, width=5, fill=(0, 0, 0), joint="curve")


    # 画像の表示と保存

    image.show()

    image.save(file_name, "PNG")


moji = list(sys.argv[1])

brow = moji[0]

eye = moji[1]

nose = moji[2]

mouth = moji[3]

print(brow,eye,nose,mouth)

generate_henohenomoheji(brow,eye,nose,mouth, "heno-mohe.png")

図2:PythonのPillowによるへのへのもへ字

2023年3月7日火曜日

プログラミング遍歴(2)

プログラミング遍歴(1)からの続き

(4) Mathematica:
Mathematicaについては既に書いているので,少し捕捉しておく。物理数学だったか計算物理だったかの授業で,Mathematicaを何年か授業で教えていたことがある。情報処理センターでは,キャンパスライセンスが導入されていて,実習室のMac(一時 Silicon Graphics のIndigo?)を使って,一通りの基礎的文法から微分方程式までをカバーしていた。

その経験があったので,卒業生の杉木君が尼崎小田高校のSSHの担当のときに,柏原キャンパスで高校生対象の1-2日のMathematica実習を実施した。尼崎小田高校では出前授業でMathematica/Excel?を使ったケーキカップの落下実験をとりあげたこともある。

(5) Perl:
インターネットの教育利用についてをテーマとするようになったのは,1994年からだ。1995年から7年ほどの黎明期に,インターネットと教育という教育利用サイトのリンクリストを運営していたが,それと連動して,全国の学校に対するアンケート調査を実施していた。今ならば絶対にアウトになりそうなやつだ。

まだ,数が少なかった学校のウェブページをクロールして,何階層かをダウンロードする。そこからメールアドレスをとり出して,ここに年1回アンケートを送り付ける。この処理にperlを用いた。wgetやlynxで入手したHTMLファイルからメールアドレスを切り出して,ユニークなものにすること。メールアドレスのデータをまとめて自動的にメール送信すること。こうした処理には,当時はPerlが最適任だったのだ。

(6) Julia:
もう退職が近づいてきたころに出会ったのがJuliaだった。スーパーコンピュータでガリガリの並列計算をするような仕事には縁遠くなってしまったので,Julia程度の軽快で高機能なプログラミング言語は大変有難かった。Mathematicaほどの自由度にはかけるが,手続き的プログラミングでは,Juliaの方が使いやすいので,現在はこの両者を使いわけている。COVID-19のシミュレーションはJuliaで,北朝鮮ミサイルのシミュレーションはMathematicaでという具合だ。



2023年3月6日月曜日

プログラミング遍歴(1)

(1) FORTRAN:
高校理数科のとき,試験にも出たFORTRANは座学だけで学んだ,というか聞きかじった程度。参考書というわけでもないが,興味があって自分で買ったのが電子計算機と人間だったけれど,これを読んでもさっぱり分からない。テレビでは,森口繁一(1916-2002)のNHKコンピュータ講座フォートラン入門をやっていたが,これもたまにチラ見する程度で何が何だかやっぱりよく分からない。

阪大の物理学科に入ると,初年次セミナーというのがあった。意欲的な同級生らは,バークレーの統計力学やFORTRAN入門にエントリーしていた。自分は億劫でどれにも参加しなかったが,学籍番号が隣の越湖直人君が,FORTRANのプログラミングで,銀河系形成のシミュレーションをやっていると聞いた。残念ながら最終結果を得るにはリソースが足りなかったようだ。

さて,その森口繁一のJIS FORTRAN入門の第2版上下を買ってしばらくしてから,大学4年の村岡光男先生の数値計算法で,はじめてのFORTRANプログラミングを体験することになる。文法の説明が数回あった後に,課題に取り組んだ。豊中データステーションの様子は以前に書いたとおりだ。いくつかの課題があって,そのうち2つを選択してレポートとして提出すれば単位がもらえる。

最初の課題は単純な四則演算の組み合わせだったのでそれを選択したものが多かった。それではつまらないと思い,5次方程式の解法と行列の対角化の2課題に取り組んだ。それぞれについて結果を出した自信があったが,後で考えるとどうも答えが間違っている。実際,村岡研に進んだ楠本君から,当時の成績が悪かったらしいと聞くことになる。

そんなわけで,大学院に進学して修士論文に取り組み始めてからも,なかなか研究がはかどらない。業をにやした大坪先生が,簡単なルンゲクッタ法のプログラムを作ってみるように指示し,教育的配慮でほめてくれたので,それをきっかけに,FORTRANプログラミングへの抵抗はなくなった。

こうして,修士課程以降は2000年ごろまでは,普通にFortran77を研究に使っていた。1990年代には京大の総合人間学部(旧教養部)の科目の非常勤でFortran77の実習も担当した。そんなわけで,Macを使うようになっても,長らくabsoft Fortranのライセンスを維持していたけれど,実際にはほとんど使うことはなかった。absoft Pro Fortranは2022年の8月に販売終了していた

(2) BASIC:
大阪教育大学に勤めてまもなく研究室に導入したパーソナルコンピュータが,NECのPC-9801だった。これにはN88BASICがROMでプレインストールされていて,OSのように使われた。アプリケーションソフトもまだ高額だったので,BASICがなければパソコンが使いこなせない。学生の卒論もBASICで計算していたし,授業や公開講座などでも良く使った

もっとも,最初に,BASICに出会ったのは,1980年ごろに阪大附属図書館でアルバイトをしていたときに,図書館2Fの事務室に導入されたOKIのif800のBASICだった。チラッと眺めたけれど,四則演算は分かるがグラフィックスが皆目見当がつかない。同じアルバイトで1-2学年下の化学の学生が,スラスラと図形を表示させているのにビックリしてしまった。

さて,そのNECのBASICである。BASICコンパイラなども使ったけれど,自分の研究のための計算をすることはほとんどなかった。卒論にもそれほど使い込んだ記憶がない。そうこうしているうちに,8087に対応したTurbo Pascal 3.0 がやってきたからだ。非常に快適なプログラム作成環境で,コンパイルのスピードにほれぼれしていた。これは,斎藤昌久君が,グラフ作成ツールなどを作ってくれて重宝した。

BASICではないが,PC-9801に8087数値演算プロセッサを積んだころ,その能力を活かそうと,8080+8087のアセンブリ言語プログラミングに取り組んだ。当時のパソコン雑誌にはこうした記事がたくさんあったので,素人でも簡単に手を出すことができた。Clebsh Gordan係数やRacah係数のコードを作り,BASICと組み合わせて連立方程式の計算を高速で実行するというあたりで,若松正志さんにそれで何をしますかと聞かれて,そうですね・・・と終了を迎えることになった。

(3) C:
C言語は,カーニハン・リッチーのプログラミング言語C石田晴久訳)を買って少しだけ勉強した。そのころは,Lattice CLightSpeed C/Think CTurbo C など,あまたのC言語処理系が乱立していた。Oh PC にはCとアセンブリ言語の中間のようなコンパクト言語なども掲載されている時代だ。で,さきに述べたように,ポインタのあたりでつまづいてサンプルプログラムを越えるものは作れなかった。


2023年3月5日日曜日

UNIX時間(6)

UNIX時間(5)からの続き

世界で活躍し『日本』を発信する日本人の一人にも選ばれている,まつもとゆきひろ(松本行弘)さんが作った ruby(1995-)は,日本発のオブジェクト指向スクリプト言語だ。ウェブアプリケーションフレームワークのRuby on Rails まで進めば御利益が多そうだけれど,近づいたことはないので,小波英雄さんが京都女子大のプログラミング教育で使っていたPerlの後継言語といった印象を持っていた。

一方のRust(2010-)は,評判だけ耳にしていた。この度改めて一からインストールして試してみた。日曜プログラマがちょっと遊んでみるには敷居が高いのかもしれない。C++代替を目指している現代的なプログラミング言語で,プロの評判は一番だけれど習得しにくさもトップレベルという面倒なやつ。

BingChatに,「rustを使って次の内容を実行する1つのプログラムを書いてください。 (1) 現在時刻をミリ秒単位まで取得して年月日時分秒の形式で表示する。 (2) (1) の結果をUNIX時間へ変換して表示する。 (3) UNIX時間=0に対応する年月日時分秒を表示する。 (4) UNIX時間=2**31-1(or 2^31-1)に対応する年月日時分秒を表示する。」と指示したところ,次のまともに動作するプログラムが出力された(コメントのみ手を入れている)。


#!/usr/bin/ruby
require "time"

## msec単位の現時刻
tn =  Time.now
tm = tn.iso8601(3)
p tm
## 年月日時分への変更
t = Time.now.to_i
d = Time.at(t).strftime("%Y/%m/%d %H:%M:%S")
p d
## UNIX時間への変更
t =  Time.parse(d).to_i
p t
## UNIX基準時
t = 0
d = Time.at(t)
p t,d
## 2038年問題
t = 2**31-1
d = Time.at(t)
p t,d



use std::time::{SystemTime,UNIX_EPOCH};
use chrono::{DateTime,Utc,Local};

fn main() {
// 現在日時の取得(ミリ秒)
//    let datetime = DateTime::<Utc>::from(now);
    let now = SystemTime::now();
    let datetime = DateTime::<Local>::from(now);
    println!("現在時刻: {}", datetime.format("%Y-%m-%d %H:%M:%S%.3f"));
// UNIX時間への変換
    let unix_time = now.duration_since(UNIX_EPOCH).expect("Time went backwards").as_millis();
    println!("UNIX時間: {}", unix_time);
// UNIX基準時
    let zero_time = UNIX_EPOCH;
    let zero_datetime = DateTime::<Utc>::from(zero_time);
    println!("UNIX時間=0: {}", zero_datetime.format("%Y-%m-%d %H:%M:%S%.3f"));
// 2038年問題
    let max_unix_time = UNIX_EPOCH + std::time::Duration::from_secs((2u64.pow(31)) - 1);
    let max_unix_datetime = DateTime::<Utc>::from(max_unix_time);
    println!("UNIX時間=2^31-1: {}", max_unix_datetime.format("%Y-%m-%d %H:%M:%S%.3f"));
}

Rustは次のようにインストールした。Cargoというビルドシステム兼パッケージマネージャを使うのが普通らしい。

% brew install rustup-init
% rustup-init
% source "$HOME/.cargo/env"
% which rustup
~/.cargo/bin/rustup
% rustup --version
rustup 1.25.2 (2023-02-01)
% which rustc
~/.cargo/bin/rustc
% rustc --version
rustc 1.67.1 (d5a82bbd2 2023-02-07)
% which cargo
~/.cargo/bin/cargo
% cargo --version
cargo 1.67.1 (8ecd4f20a 2023-01-10)
% cargo new hello_rust
% cd hello_rust
% cargo run
   Compiling hello_rust v0.1.0 (~/code/hello_rust)
    Finished dev [unoptimized + debuginfo] target(s) in 0.64s
     Running `target/debug/hello_rust`
% cargo install cargo-edit
% cargo install cargo-watch
% rustup component add rustfmt
% rustup component add clippy
% rustup component add rls rust-src rust-analysis
% rustup update stable
$ rustup doc
file://~/.rustup/toolchains/stable-aarch64-apple-darwin/share/doc/rust/html/rust-by-example/index.html


2023年3月4日土曜日

UNIX時間(5)

UNIX時間(4)からの続き

いつの間にか,Python(1991-)がプログラミング言語の主役に躍り出ていた。Jupyterでも使えるので,環境は整っている。一方のPerl(1987-)は,今ではオブジェクト指向のRuby(1995-)に取って代わられたのかもしれない。

最初に,Pythonという言葉を耳にしたのは「インターネットと教育」祭の最終段階のころだったか。誰かが,Zope(1999-)というPythonで書かれたすごいシステムがあって何でもできるような話をしていたころだ。それがどこかでCMSのPlone(2001-)につながるのだが,そのデザインに引かれて,自分でもポータルサイトに使いかけていたことがあった。


#! /Users/koshi/bin/python
#
import datetime
import pytz
import time
#
# 現在のUNIX時間を出力
unix_time = int(time.time())
print(unix_time)
print(datetime.datetime.fromtimestamp(unix_time))
# UNIX時間に変換
ud = datetime.datetime(1973, 9, 20, 6, 0, 0, 0)
tz = pytz.timezone("Asia/Tokyo")
ud = tz.localize(ud)
ut = ud.timestamp()
print(ut)
# 年月日日時分に変換
ud=datetime.datetime.fromtimestamp(ut)
print(ud)
# UNIX基準時
n = 0
print(n)
print(datetime.datetime.fromtimestamp(n))
# 2038年問題
n = 2**31-1
print(n)
print(datetime.datetime.fromtimestamp(n))




#!/usr/bin/perl
#
use strict;
use warnings;
use Time::Local 'timelocal';
use Time::HiRes 'gettimeofday';
my $ut = 0;
my ($msec, $sec, $min, $hour, $day, $month, $year) = shift;

# 現在時刻の取得
($year, $month, $day, $hour, $min, $sec, $msec) = getCurrentTimeStr();
printf("JST: %04d/%02d/%02d %02d:%02d:%02d.%003d\n", $year ,$month, $day, $hour, $min, $sec, $msec);
# UNIX時間への変換
$ut = timelocal($sec, $min, $hour, $day, $month-1, $year);
print($ut,"\n");
# 年月日時分秒への変換
getDateTimeStr($ut);
# UNIX基準時
$ut = 0;
print($ut,"\n");
getDateTimeStr($ut);
# 2038年問題
$ut = 2**31-1;
print($ut,"\n");
getDateTimeStr($ut);
exit 0;

sub getCurrentTimeStr {
    my ($epochSec, $microSec) = gettimeofday();
    my ($sec, $min, $hour, $day, $month, $year) = localtime($epochSec);
    $year += 1900;
    $month++;
    return ($year,$month,$day,$hour,$min,$sec,$microSec)
}

sub getDateTimeStr {
($sec, $min, $hour, $day, $month, $year) = localtime($ut);
$year += 1900; $month += 1;
printf("JST: %04d/%02d/%02d %02d:%02d:%02d\n", $year ,$month, $day, $hour, $min, $sec);
}

2023年3月1日水曜日

UNIX時間(4)

UNIX時間(3)からの続き

昔憧れていた(しかも一度も使ったことがない)S言語(1984-)の流れを汲むR言語(1993-)は統計処理を得意としており,ほとんど使わないがなんとなく手放せない。macOSで起動すれば,Rの実行環境あるいはRStudioでの処理となる。コマンドラインではどうなるかというと,homebrewに rscript というインタープリタが導入されていた。

Processing(2001-)はグラフィックスやアニメーションに秀でており,Arduino などのワンボードマイコンの処理系としても登場する。Javaのアプレットとして取り出せないこともないが,基本的にはProcessing実行環境の中が舞台だ。p5.jsというJavascriptライブラリを使うと,このProcessingに相似した言語(まったく同じかと期待したがそうではなかった)でJavascriptを操ることが出来る。これによって,プログラムを実行環境の外へ取り出せたようにも見えるが,実際にはなんだかまだるっこしい。

そこで,代わりにコマンドラインで使える TypeScript(2012-)を使うことにする(Processingはどこへ行ったのだろう)。macOSでのTypeScriptでは,.tsファイルを作成した後,tsc で .jsファイルを生成し,nodeで .jsファイルを実行することが出来る。一方,ts-nodeコマンドを使えば, .ts ファイルをスクリプトとして直ちに実行することも可能だ。

#! /opt/homebrew/bin/rscript

#

library(lubridate)

options(digits.secs=3)

#現在時刻の取得(ms単位)

dt <- now(tzone = "Asia/Tokyo")

dt

dt <- Sys.time()

dt

#UNIX時間へ変換

dt <- as.POSIXlt("1973-09-20 12:34:56.789 JST")

dt

ut <- as.numeric(as.POSIXlt(dt))

ut

#年月日時分秒へ変換

dt <- as_datetime(ut, tz="Asia/Tokyo")

dt

#UNIX基準時(JST)

as.numeric(as.POSIXlt("1970-01-01 09:00:00 JST"))

as_datetime(0, tz="UTC")

#2038年問題(JST)

as.numeric(as.POSIXlt("2038-01-19 12:14:08 JST"))

as_datetime(2**31, tz="UTC")




#! /opt/homebrew/bin/ts-node

//

// 現在時刻を取得する (ミリ秒単位)

var date = new Date()

console.log(date.toISOString())

var time = date.getTime()

console.log(time)

// UNIX時間への変更

var date = new Date(Date.parse('1973-09-20T12:34:56.789Z'))

var time = date.getTime()

console.log(time)

// 年月日日時分への変更

var date = new Date(time);

console.log(date);

// UNIX基準時

var n0 = 0;

console.log(n0);

var t0 = new Date(n0);

console.log(t0)

// 2038年問題

var n8 = 2**31-1;

console.log(n8);

var t8 = new Date(n8*1000);

console.log(t8);

2023年2月28日火曜日

UNIX時間(3)

小学校でプログラミング教育などともがいているうちに,時代は,プロンプト工学(Wikipediaに中文はあるが日本語はない)へ向かう。AI Chat で使う自然言語である英語自身がこれから最も重要なプログラミング言語になるという怪しいうわさが流れている。日本語は,もとのドキュメント量が1桁少なくて,良質の結果を得られない三流プログラミング言語になろうとしている。

そこで時代に逆行して,いろいろなプログラミング言語の表層入門 のために,UNIX時間を出力するコードを調べている。頭がぐちゃぐちゃになってどれもこれも身につかないところが楽しい。まあ,40年前にカーニハン・リッチーのポインタでつまずいて,Turbo Pascalで少し息を吹き返したころから,自分の進歩は止まっているのだ。

第1回ではお気に入りのWolfram 言語とJulia,第2回ではFortran95を取り上げたので,今回は,C++(1983-)とSwift(2014-)である。Cに挫折しているのでC++も同じようになりそうだし,Appleの最新言語Swiftだとどうなることか。Swiftはスクリプト言語(swift)としてもコンパイラ言語(swiftc)としても使えるところがありがたい。なお,Apple M1 macOS場合,cppではエラーが起きるので c++ でコンパイルする必要があった。あと,swiftの拡張子が.swiftというのも少しだるい。

#include <iostream>

#include <sys/time.h>

#include <cmath>

using std::cout; using std::endl;


int main() {

    struct timeval ima;

    time_t ut, ut0, ut8;

    struct tm t;

    struct tm t0 = { 0, 0, 9, 1, 0, 70, -1 };

    struct tm t8 = { 7, 14, 12, 18, 0, 123, -1 };

//現在時刻の取得(msec)

    gettimeofday(&ima, nullptr);

    time_t mnow = (ima.tv_sec * 1000) + (ima.tv_usec / 1000);

    cout << "  msec since epoch: " << mnow << endl << endl;

//UNIX時間へ変換

    ut = time(nullptr);

    cout << "  unixtime: " << ut << endl;

//年月日時刻へ変換

    cout << "  day-time: " << ctime(&ut) << endl;

//UNIX基準時(JST)

    ut0 = mktime(&t0); // ut0 = 0

    cout << "  unixtime: " << ut0 << endl;

    cout << "  day-time: " << ctime(&ut0) << endl;

//2038年問題(JST)

    ut8 = mktime(&t8); // ut8 = 2^31-1

    cout << "  unixtime: " << ut8 << endl;

    cout << "  dat-time: " << ctime(&ut8) << endl;

    return EXIT_SUCCESS;

}




#! /usr/bin/swift

import Foundation


//現在時刻の取得(msec)

let date: Date = Date()

let unixtime: Int64 = Int64(date.timeIntervalSince1970)

let utime_ms: Int64 = Int64(date.timeIntervalSince1970*1000)

print(utime_ms)


//UNIX時間へ変換

var time = TimeInterval(integerLiteral: unixtime)

print(time)

//年月日時分秒へ変換(GMT)

var day = Date(timeIntervalSince1970: time)

print(day)

//UNIX基準時(GMT)

var zt = Int64(0)

var ut = TimeInterval(integerLiteral: zt)

var ud = Date(timeIntervalSince1970: ut)

print(ut)

print(ud)

//2038年問題(GMT)

zt = Int64(pow(2,Double(31)))-1

ut = TimeInterval(integerLiteral: zt)

ud = Date(timeIntervalSince1970: ut)

print(ut)

print(ud)


C++の構造体に代入しようとして四苦八苦した。C言語の系列は includeファイルが面倒なので,どうも好きになれない。情報が沢山あるのはありがたいのだけれど。Swiftは,Appleから出ているドキュメントがわかりにくいので,これも好きになれないかも。


2023年2月22日水曜日

UNIX時間(2)

UNIX時間(1)からの続き

macOS上のgfortranFortran 95)で,UNIX時間を表示させようとしてつまづいた。

他の言語の場合,対応する組み込み関数が用意されているので簡単に実現できるのだけれど,Fortranの場合,date_and_timeという日時取得関数やsystem_clockというシステム時間取得関数などがあるが,いずれもUNIX時間には対応していない。

ChatGPTやBingChatにきいても,Fortranの場合はシステム依存性があるので処理系によってまちまちだというばかり,macOSではどうかと水を向けても思わしい答えが返ってこない。

仕方がないので,ユーザ関数として定義することにするが,適当な例題がみつからない。C言語の例ならすぐに見つかった。これをChatGPTにFortranに変換してもらったが,うまくいなかい。そもそも,例題のアルゴリズムが,西暦0年3月を起点にしてとか,UNIX日から月の算出にmonth = (unixday * 5 + 2) / 153 を使うとか技巧的すぎるのだ。

そこで,シンプルに,与えられたUNIX時間(秒)を24*60*60=86400秒で割ったUNIX日(日)から毎年の日数を引き算することにした。グレゴリオ暦のある年がうるう年かどうかの判定なら簡単である。これが負になるところが対応する年であり,足し戻したUNIX日から月単位で引き算し,これが負になるところが対応する月である。これを足し戻せば対応する日付にたどりつく。

このプログラムでは,整数を4バイト=32ビットの符号付き整数として扱っているため,2038年問題に引っかかる。ut = (2**15-1)*(2**16+1) +2**15 -9*3600 =2**31-1 -9*3600 に1加えると異常値が出ることを確かめられる。


!------- time.f95 ------- 2023.02.22 ------- K.Koshigiri -------!
!-------+-------+-------+-------+-------+-------+-------+-------!
program time_code
!-------+-------+-------+-------+-------+-------+-------+-------!
  implicit none
  integer :: dtm(8),dtm0(8),ut,ut0,jst; 
  integer(8) :: ut8
  character*10 a,b,c,fmt
!
  interface
    function dtm2ut(dtm)
      integer :: dtm(8),dtm2ut
    end function dtm2ut
    function ut2dtm(ut)
      integer :: ut2dtm(8),ut
    end function ut2dtm
  end interface
!
!現在時刻の取得
  call date_and_time(a,b,c, dtm)
  call system_clock(count=ut)
! call gtime(count=ut)
  print *, ut
  print *, ' '//a(1:4)//'-'//a(5:6)//'-'//a(7:8)
  print *, ' '//b(1:2)//':'//b(3:4)//':'//b(5:10)
  jst = dtm(4) ; print *, c, jst ; write(*, *)
!UNIX時間へ変換
  ut = dtm2ut(dtm)
  write(*,'("unixtime = ",i10)') ut
!年月日時分秒へ変換
  write(*,'(i6,"-",i2,"-",i2,i6,i3,":",i2,":",i2,".",i3)') ut2dtm(ut)
!UNIX基準時(JST)
  dtm0 = [1970,1,1,jst,9,0,0,0]
  write(*,'("unixtime = ",i11)') dtm2ut(dtm0)
  ut0 = 0
  write(*,'(i6,"-",i2,"-",i2,i6,i3,":",i2,":",i2,".",i3)') ut2dtm(ut0)
!2038年問題(JST)
  dtm = [2038,1,19,jst,12,14,7,0]
  write(*,'("unixtime = ",i11)') dtm2ut(dtm)
  ut = (2**15-1)*(2**16+1) +2**15 -9*3600 
  write(*,'(i6,"-",i2,"-",i2,i6,i3,":",i2,":",i2,".",i3)') ut2dtm(ut) 
!
end program time_code
!-------+-------+-------+-------+-------+-------+-------+-------!
function dtm2ut(dtm) result(ut) 
!-------+-------+-------+-------+-------+-------+-------+-------!
! dtm=[y,m,d,dev,hour,min,sec,msec]@JST ->
! unixtime@GMT (formal seconds from 1970-1-1 00:00:00)
  implicit none
  integer :: ut, dtm(8), ud, y, m, d, hour, min, sec
  integer, parameter :: ed = 719468  ! 1970_1_1 <= 1900_1_1
  integer, parameter :: md(13) = &
  [0,31,61,92,122,153,184,214,245,275,306,337,365]
!
  y = dtm(1) ; m = dtm(2) ; d = dtm(3)
  hour = dtm(5) - 9 ; min = dtm(6) ; sec = dtm(7)
  if (m<3) then
    m = m + 12; y = y - 1
  endif
  m = m - 3 ! 0:March
  ud = y*365 + y/4 - y/100 + y/400 + md(m+1) + d - 1 - ed
  ut = (ud * 24 + hour) * 60 + min
  ut = (ut * 60 + sec)  ! return unixtime(s)
end function dtm2ut
!-------+-------+-------+-------+-------+-------+-------+-------!
function ut2dtm(ut) result(dtm)
!-------+-------+-------+-------+-------+-------+-------+-------!
! ut=unixtime to dtm[y,m,d,dev,hour,min,sec,msec] for JST
  implicit none
  integer :: dtm(8), ut, jst, ud, wd, y, m, d, hour, min, sec
  integer, parameter :: md(12) =  [31,28,31,30,31,30,31,31,30,31,30,31]
!
  interface
    function lp(y, m)
      integer :: lp, y, m
    end function lp
  end interface
!
  jst = 9*60
  ut = ut + jst*60
  sec = mod(ut, 60)
  min = mod(ut / 60, 60)
  hour = mod(ut / 3600, 24)
  ud = ut / (24*60*60)
!  wd = mod(ud + 3, 7)
!
  y = 1969
  do while (ud >= 0)
    y = y + 1 ; ud = ud - 365 - lp(y,2)
  end do
  ud = ud + 365 + lp(y,2)
!
  m = 0
  do while (ud >= 0)
    m = m + 1 ; ud = ud - md(m) - lp(y,m)
  end do
  d = ud + md(m) + lp(y,m) + 1
!
  dtm = [y,m,d,jst,hour,min,sec,0]
end function ut2dtm
!-------+-------+-------+-------+-------+-------+-------+-------!
function lp(y,m) result(leap)
!-------+-------+-------+-------+-------+-------+-------+-------!
  implicit none
  integer y, m, leap
!
  leap = 0
  if(m == 2) then
    if( mod(y,4)==0 .and. mod(y,100)/=0 .or. mod(y,400)==0 ) then
      leap = 1
    endif
  endif
end function lp
!-------+-------+-------+-------+-------+-------+-------+-------!