2023,江端さんの忘備録

コーディング(プログラミング)は、バグの発生理由やAPI仕様が分からくなって、結構な頻度で「ハマる」ことがあります。

Coding (programming) can get "stuck" quite often, due to bugs or confusion about API specifications.

私のやっているような、専門(カルト)分野になりますと、それについての説明記事すら見当たらない、という状況になります。

Specialized (cult-like) field like the one I work in, I can't even find an article explaining it.

まあ、だからこそ、私は、自分のハマった内容は、それを『キレイに纏めないで』ブログで公開しています。

Well, that's why I publish what I have faced the problem on my blog, without 'neatly summarizing' it.

私のゴミのようなメモでさえ、何の情報もないよりは、はるかにマシなのです。

Even my garbage notes are far better than no information whatsoever.

-----

さて、このコーディングの「ハマる」問題は、その対応のためにムキになって、酷い時には、2~3日の時間を丸々持っていかれたあげく成果ゼロ、ということもあります。

Now, this coding "getting stuck" issue is one that I get really pissed off to deal with. In the worst case, it can take up two or three full days of my time, with zero results.

このコーディングの沼から抜け出すためには、「打ち切る」という勇気が必要です。

To get out of this coding quagmire, we need to have the courage to "abort" it.

ところが、この「打ち切る」というのが、本当に難しいのです。

However, this "abort" is really difficult.

『サンクコストの呪い』というやつです。

It's called "The Curse of Sunk Costs."

―― エジソン、バカ

-----

こういう場合、『有識者の方にメールで質問』をしています。

In cases like this, I 'email questions to the experts'.

こうして、その問題から一時離れます。

Thus, I temporarily step away from the problem.

もちろん、これは、相手に迷惑をかけるシャレにならない方式ですし、そもそも失礼です。

Of course, this is a shameless method that inconveniences others and is rude in the first place.

ですので、普段から相手との信頼関係を構築しておかなければなりません。

Therefore, I must build a relationship of trust with them on a regular basis.

その信頼関係とは何かと言えば ―― その方からの質問に対しては『自分の持っている全ての知見を、最速かつ無条件で開示する』ということです。

What is that relationship of trust? When that person asks me a question, I have to 'disclose all the knowledge I have in the fastest and unconditional way possible".

これを、日常的に行っていなければなりません。

This must be done on a daily basis.

これを「人脈」といいます。

This is called "human networking".

名刺を交換することは、「人脈」とは言いません。

Exchanging business cards is not "networking".

人脈には、ちゃんと情報交換と信頼関係という「血液」を流し続けなければならないのです。

We must keep the "blood" of proper exchange of information and trust flowing through our connections.

「血液」が流れていない「人脈」は、ただの「管」です。

A "networking" without "blood" is just a "tube.

-----

逆に言うと ―― 私は、思い出したように、困った時だけ私を使おうとする奴に対しては、意図的に(悪意的に)対応しません。

Conversely -- I will not intentionally (maliciously) respond to anyone who tries to use me only when they are in trouble, as I recall.

私の情報提供に対して、礼の一つも寄越してこないような人間に対しては、「管」そのものを切断します。

I have cut off the "tube" itself to anyone who does not send me even a single thanks mail for the information I provide.

まあ、このような狭量の人間を『大人げない』というのでしょうが ――

Well, I guess you could call such a narrow-minded person 'childish', however,

私の知る限り、世の中の大半の大人は、『大人げない』です。

As far as I know, most adults in the world are not 'childish'.

私は、過去は振り向かない人間です ―― 特に、他人の過去は。

2023,江端さんの技術メモ

T研究所のKさん。ありがとうございました。

 

(4)PruneClusterにおいて、クラスタリングを解除する方法 → leafletView の定義の後に、「leafletView.Cluster.Size = -1」のよう     に負の値を設定することによって、実現可能です。     - 参考URL:https://github.com/SINTEF-9012/PruneCluster/issues/52

2023,江端さんの忘備録

現在、横浜市交通局さんから提供して頂いている情報を使って、バスのリアルタイム情報を表示させる作業をしています。

I am currently working on displaying real-time bus information using information provided by the Yokohama City Transportation Bureau.

「Protocol Buffersって何? 」から、「公共交通オープンデータ」を攻略する

昨夜、コーディングを再開したら、交通データが全く表示されなくなっていました。

When I resumed coding last night, the traffic data was not showing up at all.

真っ青になって、プログラムを見直してみたのですが、障害の原因となるような箇所が見つかりません。

In a panic, I reviewed the program, however I could not find anything that could cause the failure.

散々調べた挙げく、妙な短文データが表示されているので、これをデコードして、ようやく原因が分かりました。

After much investigation, I finally found the cause of the problem by decoding the strange short text data being displayed.

―― 深夜は路線バスは走っていません

"No buses running late at nigh"

-----

まあ、バスが走っていない時間にコーディングしている私が悪いんですけどね。

Well, it is my fault for coding at a time when buses are not running.

それにしても、こんなしょーもない理由で、大切な深夜の2時間がふっとんだかと思うと、なんともいまいましいです。

Still, it's a damn shame to think that two precious late-night hours were lost for such a trivial reason.

2023,江端さんの忘備録

今夜、異動先の部署のキックオフの飲み会に参加してきました。

Tonight I attended the kick-off drinks for the department I am transferring to.

こんな私でも、節目の行事は、大切だと思っています。

『なんだかんだいって、セクショナリズムの対抗手段は、定期的な飲み会である』

Even I would like to cherish milestone events.

お開きのところで、挨拶を求められたので、一言だけ申し上げてきました。

At the close of the meeting, I was asked to say a few words.

「本日、聞いたお話は、3年間は『書きません』ので、ご安心下さい」

"I will not write about what I heard today for the next three years"

-----

一瞬、『この人、何を言っているの?』という風の顔の後で、「その"話"とは何だ?」と一斉につっこまれましたが、私はにこやかな笑顔を見せたまま、そのまま散会しました。

Just after everyone looked like, "What is he talking about?, they asked me "What is this 'talk'?" immidately. However, Smiling at them and I left soon.

今後は、節目の行事すら、呼ばれなくなるかもしれません。

In the future, I might not be called even milestone events.

2023,江端さんの忘備録

一年でもっとも嫌いな「月」を挙げろと言われれば、私は「4月」を挙げます。

If you ask me to name my least favorite "month" of the year, I will name "April".

■これまで動かなかった人々が、虫のようにわらわらと動き出すをの見るのが不快です。

- I am uncomfortable to see people who have never moved before start moving like insects.

■着なれないスーツを着て緊張した顔をしている若者が、これから挫折していくことになる現実に、気分が暗くなります。

- My mood darkens at the reality that these young men, looking nervous in their ill-fitting suits, are about to fall behind.

■この若者の中の何人かが、そう遠くない未来(とりあえずゴールデンウィークあたり)に出社しなくなり、さらに高い確率で、心の病に罹患することに憂鬱になります。

- I am depressed that some of these young people will stop coming to work in the not-too-distant future (around Golden Week for) and, at an even higher rate, will suffer from mental illness.

―― 国家レベルの「心の崩壊」が始まっている

そして、

And

■様々な人事発表で、私よりもはるかに若い人が、偉くなって、壇上から期首方針を述べているのを見るのは、気分の良いものではありません。

- It is not a pleasant feeling to see someone much younger than I am at various personnel announcements, rising to greatness and speaking from the podium about the policy for the term.

その度に、『彼と私は、何が違っていたのだろう?』と考えてしまう自分に自己嫌悪します。

Every time I do, I hate myself for thinking, 'What was so different about him and me?'

いや、判っているんですけどね。

Well, I know the reason well.

こちらのコラムでも、『あなたより優秀な後輩は、あなたの後に山ほど入社してきて、簡単にあなたの上司となります』と書いています。

In this column, I also wrote, 'A lot of juniors who are better than you will join the company after you, and they will easily become your boss.

ただ、頭では分かっているのですが、実際に知っている人が、どんどん出世(?)している様を見るのは、そこそこキツいものなのです。

I know this in my head, but it's hard to see someone I actually know moving up in the world.

-----

江端:「ついつい、『彼と私は、何が違っていたのだろう?』と考えてしまうんだよな」

Ebata: "I tend to think, 'What was different about him and me?'

嫁さん:「それは、もう『何もかも』でしょう」

Wife: "Needless to say, that would be 'everything'"

と嫁さんは言います。

My wife says,

「出世をする人は、会社に利益を与える人や、その気概を持っている人だけだよ」

The only people who get ahead are those who benefit the company and have the chutzpah to do so."

2023,江端さんの忘備録

出生率の低下の一因(というか主要因)は、非婚化です。

One factor (or rather, the main factor) in the decline in the birth rate is the nonmarriage rate.

どうして、非婚化が進行しているかというと、その原因ははっきりしています。

The reasons for the growing number of unmarried people are clear.

―― 『結婚の価値、良さ、メリット』を、若者に対して言語化できない、私(たち)の無能

"My (our) inability to verbalize the "value, merits and advantages of marriage" to young people"

です。

-----

先日、ニュースで、『非婚女性のウェルビーイングが、既婚女性のウェルビーイングを越えたことが、統計で示された』という話を聞いて ―― 『いずれ、そのデータが出てくるだろう』とは予感していたのですが ―― それでも、ショックを受けています。

The other day I heard a story in the news that 'statistics show that the wellbeing of non-married women has surpassed that of married women' -- I had a hunch that 'eventually the data would come out' -- but... -- I was still shocked.

以下の表は、ちょうど10年前に私の予測した非婚化の予想です。

The following table shows my predictions of nonmarriage just 10 years ago.

私自身は、「非婚」が、価値のある人生の選択であることは、よく理解しています。

I myself understand that "non-marriage" is a worthwhile life choice.

しかし、同時に「結婚」もまた、価値のある人生の選択であることも知っています。

But at the same time, we know that "marriage" is also a worthwhile life choice.

-----

もちろん、非婚や結婚が、自分の選択だけで決まる訳ではありません。

Of course, non-marriage and marriage are not determined solely by one's choice.

しかし、現在が「結婚」が恐しく難しい時代であることは、データを見るまでもなく分かっています。

However, we don't need to look at the data to know that "marriage" is a terribly difficult time today.

以下のグラフは、10年前の私の予測です。ざっと見たところ、非婚化は、私の予測より加速されているようです。

The following graph is my prediction from 10 years ago. At a quick glance, it appears that the rate of nonmarriage is accelerating faster than I predicted.

現在の結婚の難しさは、私の体感で、私の時代の『10倍以上』は難しく、やろうと思えば、数値で叩き出せると思います。

The difficulty of marriage today is, in my experience, 'more than 10 times' as difficult as it was in my day, and I think I could beat it out of you numerically if I wanted to.

それはさておき。

Aside from that.

-----

『結婚の価値、良さ、メリット』を、若者に対して言語化できない、私(たち)無能 ―― について異議はないのですが ――

I have no objection of "My (our) inability to verbalize the "value, merits and advantages of marriage" to young people", however,

では、私たちの時代に、『結婚の価値を、きちんと言語化してくれた先人がいたか?』だろうか、と考えてみました。

So, in our time, 'Did any of our predecessors properly verbalize the value of marriage?' I wondered.

いや、いなかったぞ。

No, they weren't there.

たった一人を除いて、誰もいなかった。

There was no one there except for one person.

「結婚って、良いものですか?」

-----

では、私(たち)は、どうやって結婚を選択してきたのか?

So how have I(we) chosen to get married?

当時の人も、私たちと同様に、結婚の価値を言語化することはできなかったけど、『私は、結婚していた"その人"を信じることができた』とは言えると思うのです。

People then, like us, could not verbalize the value of marriage, but I think we can say, "I could believe in the 'person' who were married to".

では、"その人"とは誰か?

So, who is "the person"?

それは、親であり、先輩であり、高齢者であり、社会でした。

It was parents, seniors, the elderly, and society.

私(たち)は、結婚を支持する(または同調圧力をかけてくる)社会を、とりあえずは信じていたのです。

I (We) believed, for the time being, in a society that supported (or was sympathetic to) marriage.

-----

この考え方を拡張していくと ――

Extending this idea --

非婚化とは、

What is nonmarriage?

- 結婚を望まない人の価値観を認めず、

- Not recognize the values of those who do not wish to marry,

- 結婚を望む人の望みを叶えられない社会を作り(あるいは、その社会を放置し)、

- Create (or leave in place) a society that fails to fulfill the desires of those who wish to marry,

- 結婚の価値を、自分の言葉で語ることもできない、

- Not speak of the value of marriage in his own words,

そういう、無能な私(たち)に対する「痛烈な批判」である、という結論に帰着する訳です。

I can only conclude that this is a "scathing criticism" of my (our) incompetence.

2023,江端さんの忘備録

「暴力の人類史」という番組を見ました。

I watched a program called "A Human History of Violence."

題目から期待していた内容とは真逆で、「人類の暴力は減少し続けている」という内容でした。

The content was the exact opposite of what I expected from the title: "Human Violence Continues to Decrease".

しかし、私は『近代においては、戦争が、その分を喰っているんだろう』と思っていたのですが、戦争による死者数も減っているという内容でした。

But I thought, 'In modern times, war has probably replaced that,' but the number of deaths of war seems also to be decreasing.

暴力事件や戦争ニュースばかりで惑わされがちですが、数百年間のオーダーで見た時、人類は、暴力という本能を、理性という知性で押さえ続けてきた、ということです。

We are often misled by news of violent incidents and wars, but when viewed on the order of hundreds of years, humanity has continued to suppress its instinct for violence with the intelligence.

人類は、愚かな方向にのみ向いているように見えますが、案外そうでもないらしいです。

We apt to think that humanity seems to be oriented only in a foolish direction, but not so surprisingly

久々にホッする内容のドキュメンタリーでした。

It has been a long time since I was relieved by the content of this documentary.

ですが、やっぱり番組の題目は良くないと思う。

But I still think the title of the program is not proper.

-----

あ、そういえば、

―― 法律とは、「数学の証明」あるいは「システムのプログラミング」と同じである

Oh, by the way, the book mentioned here has arrived.

で記載した本が届きました。

管理システム(シビュラシステム)で守られるだけでは、人類として、ちょっと情けないですよね。

It is a bit woeful for us, as a human race, to just be protected by a management system (Sibyla system).

2023,江端さんの忘備録

日常的にChatGPTを使い倒しています。

I use ChatGPT on a daily basis.

「珍しく本当に役に立ちそうなAI技術」と認めています。

I admit "It's a rare AI technology that could be really useful".

しかし、ChatGPTは、(現時点では)『分からなくても答えを捻り出す』という悪いクセがあります(かなり見抜けるようになってきましたが)。

However, ChatGPT has a bad habit (at the moment) of "twisting answers even not knowing them" (although I'm getting pretty good at spotting them).

ですので、論文の要約などを語らせる時には、ダブルチェック用に使っています。

So I use it for double-checking when I have them talk about summaries of papers, etc.

-----

ChatGPTのアプリケーションで、私に衝撃を与えたのが、コレです(YouTubeに飛びます)

One application of ChatGPT that struck me was this one (jump to YouTube).

ChatGPTによる英会話の対話授業です。

This is an interactive class for English conversation by ChatGPT.

スマホで会話のキャッチボールをすることができて、その会話に違和感がない。

I can catch a conversation on my phone and feel comfortable with that conversation.

どっかの会社のマヌケなChatBotとは比較になりません。

It cannot be compared to some company's dumb ChatBot.

-----

私は生れて始めて『AIによる廃業』の予感を感じました ―― 最初の犠牲者は、語学教師です。

For the first time in my life, I had a premonition of "AI out of business" -- the first victims will be language teachers.

だって、英語が当たり前にしゃべれないような教師が、教育現場で英語を教えている国なんて、我が国だけですよ。

Japan is the only country in the world where teachers who do not speak English teach English in an educational setting.

AI技術のプログラムを組めない奴が、AI技術のプログラミングを語っているのと同じくらい滑稽です(ええ、はっきり言って、私は、そういうやつらを"バカ"にしているのです)。

It is as ridiculous as someone who can't program AI technology talking about programming AI technology (Well, to be clear, I am making fun of them).

上記の映像を見て頂ければ明らかですが、そんな教師より、ChatGPTの方がはるかに"マシ"です。

As the above video clearly shows, ChatGPT is much "better" than such teachers.

-----

私、以前、英語の本質は「コミュニケーション」ではなくなり、単なる「インターフェース」になるという預言をしてきました。

I, previously, have prophesied that the essence of English will cease to be "communication" and become merely an "interface".

英語が機械とのインターフェースになる日

それは、人間の内面も外面も「属性」として纏められた上で、さらにそれらの全てがスルーされて、「その人」と「私」の関係性は「価値があるか/ないか」のみの価値観で支配される世界観になる、という預言です。

Both the inside and outside of a human being are put together as "attributes" and then all of them are further passed through and the relationship between "that person" and "I" becomes a worldview governed only by the value of "is/is not worth it".

位置情報サービスからインタフェース社会へ

ところが、このChatGPTの語学教育機能は、私のこの「インタフェース世界観」を、すっかり低次元にまで落してしまったのです。

However, the language education function of ChatGPT has completely reduced this "interface worldview" of mine to a lower level.

つまり、「機械(コンピュータ)に語学を教えてもらう」ことで、「機械(コンピュータ)とコミュニケーションを行う手段」を習得することになった、ということです。

In other words, by "having a machine (computer) teach you a language," you have acquired "a means of communicating with a machine (computer).

纏めますと、『英語のコミュニケーションにおいて、「人間」が介在する意味が失われた』 ―― ということです。

It means that the significance of "human" intervention in English communication has been completely lost.

2023,江端さんの技術メモ

バスのリアルタイム情報を格納するサーバを作ることになりました(経緯が色々あって)。

情報を提供しているサーバから、JSONを定期的に取りに行けばいいんだろう、とか思っていたのですが、このProtocol Bufferというデータ形式を、私は聞いたことがありません。

実際にデータを取得してセーブしてみたのですが、明らかにバイナリです。

しかも、どのエディタでも自動整形しない。ということは、どうやらテキストではない。

で、色々調べたのですが、どうも要領を得ないのですが、下の動画でやっと分かった気になりました。

乱暴に言えば、Protocol Buffersとは「圧縮されたJSON または XML(のようなもの)」です。

まあ、JSONもXMLもテキストメッセージで、しかも構造を保持したまま送信するので「通信効率悪そうだなぁ」と前々から思っていましたので、こういうものが必要となるのは分かります。

Googleが提供していることもあり、また、リアルタイム系のデータでは必要となるのは分かりますが ―― また、覚えることが増えたなぁ、と少々ウンザリしています。


とりあえず、Go言語で動かすことを目的として、ここまでの経緯を記載しておきます。

私の環境は、Windows10です。GOはインストール済みです

(1)https://protobuf.dev/downloads/ から "Latest Version" →  "*-win64.zip"

をダウンロード。私はC:\の直下に展開しました。

でもって、この両方のフォルダーにpathを通しておきました。必要なのは"protoc.exe"です。

(2)私の場合、C:\Users\ebata\protocol_bufferesというディレクトリを作って、そこにソースを展開することにしました。

とりあえず、main.goという名前でファイルを作っておきます(後で必要になります)

package main

import "fmt"

func main() {
	fmt.Println("Hello World!!")
}

さらに、person.proto という名前で、

syntax = "proto3";
package main;

message Person{
    string name = 1;
    int32 age = 2;
}

というファイルを作ります。これがxmlやらJSONのスタイルファイルにようなものです。

で、ここから、person.pb.goというファイルを作らなければならないのですが、これに苦労しました。

C:\Users\ebata\protocol_bufferesの中で、

$ protoc --go_out=. *.proto
protoc-gen-go: unable to determine Go import path for "person.proto"
Please specify either:
    • a "go_package" option in the .proto source file, or
      • a "M" argument on the command line.
See https://developers.google.com/protocol-buffers/docs/reference/go-generated#p
ackage for more information.
--go_out: protoc-gen-go: Plugin failed with status code 1.

のようなことを繰り返していたのですが、person.proto の中に、一行追加したら、サクっと通りました。

syntax = "proto3";

option go_package="./;main"; // 理由は分からないけど、この1行で、以下のエラーが消えた

//$ protoc --go_out=. *.proto
//protoc-gen-go: unable to determine Go import path for "person.proto"
//Please specify either:
//        • a "go_package" option in the .proto source file, or
//        • a "M" argument on the command line.
//See https://developers.google.com/protocol-buffers/docs/reference/go-generated#p
//ackage for more information.
//--go_out: protoc-gen-go: Plugin failed with status code 1.

package main;

message Person{
    string name = 1;
    int32 age = 2;
}

この結果、以下のようなperson.pb.goが生成されました。

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.26.0
// 	protoc        v4.22.2
// source: person.proto

package main

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

type Person struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	Age  int32  `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
}

func (x *Person) Reset() {
	*x = Person{}
	if protoimpl.UnsafeEnabled {
		mi := &file_person_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Person) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Person) ProtoMessage() {}

func (x *Person) ProtoReflect() protoreflect.Message {
	mi := &file_person_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Person.ProtoReflect.Descriptor instead.
func (*Person) Descriptor() ([]byte, []int) {
	return file_person_proto_rawDescGZIP(), []int{0}
}

func (x *Person) GetName() string {
	if x != nil {
		return x.Name
	}
	return ""
}

func (x *Person) GetAge() int32 {
	if x != nil {
		return x.Age
	}
	return 0
}

var File_person_proto protoreflect.FileDescriptor

var file_person_proto_rawDesc = []byte{
	0x0a, 0x0c, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04,
	0x6d, 0x61, 0x69, 0x6e, 0x22, 0x2e, 0x0a, 0x06, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x12,
	0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
	0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52,
	0x03, 0x61, 0x67, 0x65, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x2f, 0x3b, 0x6d, 0x61, 0x69, 0x6e, 0x62,
	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_person_proto_rawDescOnce sync.Once
	file_person_proto_rawDescData = file_person_proto_rawDesc
)

func file_person_proto_rawDescGZIP() []byte {
	file_person_proto_rawDescOnce.Do(func() {
		file_person_proto_rawDescData = protoimpl.X.CompressGZIP(file_person_proto_rawDescData)
	})
	return file_person_proto_rawDescData
}

var file_person_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_person_proto_goTypes = []interface{}{
	(*Person)(nil), // 0: main.Person
}
var file_person_proto_depIdxs = []int32{
	0, // [0:0] is the sub-list for method output_type
	0, // [0:0] is the sub-list for method input_type
	0, // [0:0] is the sub-list for extension type_name
	0, // [0:0] is the sub-list for extension extendee
	0, // [0:0] is the sub-list for field type_name
}

func init() { file_person_proto_init() }
func file_person_proto_init() {
	if File_person_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_person_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Person); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_person_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_person_proto_goTypes,
		DependencyIndexes: file_person_proto_depIdxs,
		MessageInfos:      file_person_proto_msgTypes,
	}.Build()
	File_person_proto = out.File
	file_person_proto_rawDesc = nil
	file_person_proto_goTypes = nil
	file_person_proto_depIdxs = nil
}

さて、ここで、

package main

import (
	"fmt"
	"log"

	"google.golang.org/protobuf/proto"
)

func main() {
	fmt.Println("Hello World!!")

	elliot := &Person{
		Name: "Elliot",
		Age:  24,
	}

	data, err := proto.Marshal(elliot)
	if err != nil {
		log.Fatal("Marshalling error", err)
	}

	fmt.Println(data)
}

とした上で、

$ go run main.go person.pb.go

をすると、

main.go:7:2: no required module provides package google.golang.org/protobuf/prot
o: go.mod file not found in current directory or any parent directory; see 'go h
elp modules'
person.pb.go:10:2: no required module provides package google.golang.org/protobu
f/reflect/protoreflect: go.mod file not found in current directory or any parent
directory; see 'go help modules'
person.pb.go:11:2: no required module provides package google.golang.org/protobu
f/runtime/protoimpl: go.mod file not found in current directory or any parent di
rectory; see 'go help modules'

というエラーがでてくるので、
$go mod init m
$ go get google.golang.org/protobuf/reflect/protoreflect
$ go get google.golang.org/protobuf/proto
$ go get google.golang.org/protobuf/runtime/protoimpl

を実行して、再度、

$ go run main.go person.pb.go

を行うと

Hello World!!
[10 6 69 108 108 105 111 116 16 24]

とい値が出力されます。

package main

import (
	"fmt"
	"log"

	"google.golang.org/protobuf/proto"
)

func main() {
	fmt.Println("Hello World!!")

	elliot := &Person{
		Name: "Elliot",
		Age:  24,
	}

	data, err := proto.Marshal(elliot)
	if err != nil {
		log.Fatal("Marshalling error", err)
	}

	fmt.Println(data)

	newElliot := &Person{}
	err = proto.Unmarshal(data, newElliot)
	if err != nil {
		log.Fatal("unmarshalling error: ", err)
	}

	fmt.Println(newElliot.GetAge())
	fmt.Println(newElliot.GetName())

}

のプログラムを実行すると、

$ go run main.go person.pb.go
Hello World!!
[10 6 69 108 108 105 111 116 16 24]
24
Elliot

となる。


動的バス情報フォーマット(GTFSリアルタイム)ガイドライン

やっと見つけた

ここからダウンロードすると、こんな感じのprotoファイルが得られます。

で、これを以下のように修正して、

として、

$ protoc --go_out=. *.proto

を実施すると、さくっとgtfs-realtime.pb.goができました。

ここまでできれば、後はクライアントを作れば、できるはずです。

問題は、どうやってサーバにアクセスするか、を考えれば、いくはずです。
(が、基本的に最後に動くまで、どうなるかは分からないですが)。


さて、今回の私の狙いは、

https://ckan.odpt.org/dataset/b_bus_gtfs_rt-yokohamamunicipal

の、リアルタイムデータを取得して保存しておくことです。

これは、こちらに記載されているように

URL: https://api.odpt.org/api/v4/gtfs/realtime/YokohamaMunicipalBus_vehicle?acl:consumerKey=[発行されたアクセストークン/YOUR_ACCESS_TOKEN]

なので、このデータを所得するためには、「発行されたアクセストークン」というのを貰う必要があります。これ、"f4954c3814b207512d8fe4bf10f79f0dc44050f1654f5781dc94c4991a574bf4"(江端ルールで変更済み)というやつになります。

これは、https://developer.odpt.org/ から、申請してメールで付与してもらえます(2日くらいかな)。これがないと、データの取得ができないので注意して下さい。

さて、ここから、とりあえず、この横浜市交通局の市営バスのバス関連リアルタイム情報を取得するコードを、https://gtfs.org/realtime/language-bindings/golang/ をパクって、ちょっと修正してみました。

私は、c:\Users\ebata\protocol_bufferes\gtfs-realtime というディレクトリを掘って、上記のページ通りのことを実施しました。

$ go get github.com/MobilityData/gtfs-realtime-bindings/golang/gtfs

$ go get google.golang.org/protobuf/proto

以下のファイルを作成しました(トークンは自分のものに置き替えて下さい)。エラーの出てくるところは、コメントアウトしています。

// https://gtfs.org/realtime/language-bindings/golang/

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/MobilityData/gtfs-realtime-bindings/golang/gtfs"
	proto "github.com/golang/protobuf/proto"
)

func main() {
	var (
		username = "xx@gmail.com" // 横浜市交通局の市営バスのサイトでは不要のようだからダミーを放り込んでおく
		password = "xx"           // (同上)
	)

	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://api.odpt.org/api/v4/gtfs/realtime/YokohamaMunicipalBus_vehicle?acl:consumerKey=f4954c3814b207512d8fe4bf10f79f0dc44050f1654f5781dc94c4991a574bf4", nil)
	if err != nil {
		log.Fatal(err)
	}

	req.SetBasicAuth(username, password)
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}

	defer resp.Body.Close()
	if err != nil {
		log.Fatal(err)
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(body)

	feed := gtfs.FeedMessage{}
	err = proto.Unmarshal(body, &feed)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(feed)

	/*

		for _, entity := range feed.Entity {
			tripUpdate := entity.TripUpdate
			trip := tripUpdate.Trip
			tripId := trip.TripId
			fmt.Printf("Trip ID: %s\n", *tripId)
		}
	*/
}

で、fmt.Println(body) のところを表示するとこんな感じになっています。

[10 13 10 3 50 46 48 16 0 24 165 246 160 161 6 18 41 10 9 118 105 99 108 95 49 56 48 54 34 28 18 10 13 252 214 13 66 21 192 155 11 67 40 165 205 159 161 6 66 6 10 4 49 56 48 54 72 0 18 41 10 9 118 105 99 108 95 49 48 48 50 34 28 18 10 13 188 173 13 66 21 205 159 11 67 40 233 176 159 161 6 66 6 10 4 49 48 48 50 72 0 18 41 10 9 118 105 99 108 95 51 57 57 50 34 28 18 10 13 83 131 13 66 21 28 146 11 67 40 216 210 159 161 6 66 6 10 4 51 57 57 .....

fmt.Println(feed)は、こんな風に表示されます。

{{{} [] [] 0xc00013f800} 0 [] map[] gtfs_realtime_version:"2.0" incrementality:FULL_DATASET timestamp:1680358181 [id:"vicl_1806" vehicle:{vehicle:{id:"1806"} position:{latitude:35.459946 longitude:139.6084} timestamp:1680336549 occupancy_status:EMPTY} id:"vicl_1002" vehicle:{vehicle:{id:"1002"} position:{latitude:35.419662 longitude:139.62422} timestamp:1680332905 occupancy_status:EMPTY} id:"vicl_3992" vehicle:{vehicle:{id:"3992"} position:{latitude:35.378246 longitude:139.57074} timestamp:1680337240 occupancy_status:EMPTY} id:"vicl_1732" vehicle:{trip:{trip_id:"04117_12202301042041P01910" schedule_relationship:SCHEDULED} vehicle:{id:"1732"}.....

あとは、ここをパースすれば、必要な情報は取り出せるはずです。


さて、ここから ~/protocol_bufferes/gtfs-realtime に環境を作ってみます。

$go mod init m
$ go get google.golang.org/protobuf/reflect/protoreflect
$ go get google.golang.org/protobuf/proto
$ go get google.golang.org/protobuf/runtime/protoimpl

で、

こちらの環境でも、上記と同じ手続で、gtfs-realtime.pb.goを作り、

$ go run main.go gtfs-realtime.pb.go

を実施してみましたところ、

main.go:11:2: no required module provides package github.com/MobilityData/gtfs-realtime-bindings/golang/gtfs; to
add it:
go get github.com/MobilityData/gtfs-realtime-bindings/golang/gtfs
main.go:12:2: missing go.sum entry for module providing package github.com/golang/protobuf/proto; to add:
go mod download github.com/golang/protobuf

と言われたので、言われた通りのことを実施してみました

ebata@DESKTOP-P6KREM0 MINGW64 ~/protocol_bufferes/gtfs-realtime
$ go get github.com/MobilityData/gtfs-realtime-bindings/golang/gtfs
go get: added github.com/MobilityData/gtfs-realtime-bindings/golang/gtfs v1.0.0
でもって、
ebata@DESKTOP-P6KREM0 MINGW64 ~/protocol_bufferes/gtfs-realtime
$ go mod download github.com/golang/protobuf
再度やってみました。
$ go run main.go gtfs-realtime.pb.go
go: updates to go.mod needed; to update it:
        go mod tidy
ここも言われた通り、
$ go mod tidy
をやりました。
でもって、また繰り返しました。
$ go run main.go gtfs-realtime.pb.go
panic: proto: file "gtfs-realtime.proto" is already registered
        previously from: "github.com/MobilityData/gtfs-realtime-bindings/golang/gtfs"
        currently from:  "main"
See https://protobuf.dev/reference/go/faq#namespace-conflict
goroutine 1 [running]:
google.golang.org/protobuf/reflect/protoregistry.glob..func1({0xea9240, 0xeb92b8}, {0xea9240, 0xc000058d70})
        c:/go/pkg/mod/google.golang.org/protobuf@v1.30.0/reflect/protoregistry/registry.go:56 +0x1f4
(以下、色々)
エラー文を見てみると、"gtfs-realtime.proto"が既に登録されている、とあります。
まあ、 ~/protocol_bufferes/ で、色々やったので、多分、登録してしまったのだろうと思います。
が、それを色々変えるのは面倒ですので、とりあえず対処方として、環境変数を変えてしまう、という手があるようです。
$ export GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn
で、ここの部分は回避できるようです(本格的な修正は後回しとします)。
とりあえず、エラーが出てこないように、main.goでコメントしていた部分を解いて、エラーが出てこないように修正しました。
feed := gtfs.FeedMessage{}
	err = proto.Unmarshal(body, &feed)
	if err != nil {
		log.Fatal(err)
	}
	//fmt.Println(feed)

	for _, entity := range feed.Entity {
		//tripUpdate := entity.TripUpdate
		fmt.Println(entity)
		fmt.Println()
		//trip := tripUpdate.Trip
		//tripId := trip.TripId
		//fmt.Printf("Trip ID: %s\n", *tripId)
	}
とりあえずentity(が、何かよく分からんのですが)を表示してみました。
この結果、以下のような表示が得られました。
id:"vicl_1780"  vehicle:{trip:{trip_id:"05406_09202304031054P00218"  schedule_relationship:SCHEDULED}  vehicle:{id:"1780"}  position:{latitude:35.415165  longitude:139.66798}  current_stop_sequence:10  stop_id:"5899_02"  current_status:IN_TRANSIT_TO  timestamp:1680534894  occupancy_status:EMPTY}
id:"vicl_3944"  vehicle:{trip:{trip_id:"03903_22202304031012A01309"  schedule_relationship:SCHEDULED}  vehicle:{id:"3944"}  position:{latitude:35.50719  longitude:139.55861}  current_stop_sequence:32  stop_id:"6219_01"  current_status:IN_TRANSIT_TO  timestamp:1680528244  occupancy_status:EMPTY}
id:"vicl_1705"  vehicle:{vehicle:{id:"1705"}  position:{latitude:35.378166  longitude:139.57071}  timestamp:1680522432  occupancy_status:FEW_SEATS_AVAILABLE}
id:"vicl_4607"  vehicle:{vehicle:{id:"4607"}  position:{latitude:35.492794  longitude:139.66455}  timestamp:1680526330  occupancy_status:NOT_ACCEPTING_PASSENGERS}
さて、次は、この内容を理解しなければなりません。
とりあえず、バスのID、緯度、経度が取れればよく、これでデータが取れるようです.
for _, entity := range feed.Entity {
			//tripUpdate := entity.TripUpdate
			//fmt.Println(entity)

			// データの読み込み
			uniName := *(entity.Vehicle.Vehicle.Id)
			lat := *(entity.Vehicle.Position.Latitude)
			lon := *(entity.Vehicle.Position.Longitude)

			fmt.Println(uniName, lat, lon)
}

2023,江端さんの忘備録

メルトダウン File.8 「後編 事故12年目の“新事実”」を見ました。

I watched "Meltdown File.8 "Part 2: New revelations 12 years after the accident""

茫然自失(ぼうぜんじしつ) ―― というのでしょうか。

I guess I could call it "stupefaction".

『テレビを見ながら、立ち竦(すく)む』という、という体験をすることになりました。

I had to go through the experience of 'standing there, stunned, watching TV.

-----

この番組の要旨を、乱暴に3点で纏めます。

I will summarize the gist of this program in three roughly different points.

(1)あの消防隊員の皆さんの文字通り『命をかけた』原子炉への給水が、逆にメルトダウンを加速することになった

(1) The water supply to the reactor that the firefighters literally "risked their lives" for accelerated the meltdown.

(2)原子炉の圧力を下げる「ベント」は、あの段階では「やらない方がよかった」

(2) "Venting" to reduce reactor pressure "should not have been done" at that stage

(3)ところが、上記(2)によって、原子炉の圧力が下がり、その結果、まったく予想していなかった貯水場から水が引き上げられて、結果として、溶解した燃料を冷やすことになった

(3) However, (2) above caused the reactor pressure to drop, resulting in water being pulled up from the water reservoir, which was completely unexpected, and consequently cooling the dissolved fuel.

つまり ―― その時点において「もっとも良い」と判断した選択が「最悪の事態を導き」、その「最悪の事態が、結果としてさらなる最悪の事態を防いだ」ということであり、

In other words -- the "best" choice at the time "led to the worst," and that "worst prevented further worsts" as a result.

私にとって、最大の衝撃は、

For me, the biggest shock was, that,

『システム制御を行う人間の意図と全く関係なく、勝手に事態が進み、勝手に停止した』

"The situation that proceeded on its own, and then stopped on its own, completely beyond the intentions of the people controlling the system"

ということです。

これは、原子力を制御するエンジニアにとって『完全敗北』といっても過言ではありません。

It is no exaggeration to say that this is a 'total defeat' for the engineers who control nuclear power.

-----

原子力発電所の運用については、電力会社や委託先の大学で、考え得る限りの事故シミュレーション(模擬試験)を行なっていると言われています。

It is said that the power companies and the universities to which they outsource the operation of nuclear power plants conduct every conceivable accident simulation.

シミュレーションの実施以前に、そのような事故シナリオを考え出すストレスは、想像を絶する苦しい作業だと思います。

I know that the stress of coming up with such an accident scenario prior to conducting the simulation is an unimaginably painful task.

しかし、現実の事故は、そのような膨大なシミュレーションの想定を、易々(やすやす)と乗り越えて、やって来るのです。

However, real accidents easily overcome such a huge number of simulation assumptions.

-----

以前から申し上げておりますが、制御システムというのは、自動車であれ、飛行機であれ、発電所であれ、ロケットであれ、繰り返し失敗を続けることで、その安全性や信頼性を、少しずつ向上させていくものです。

As I have said in the past, control systems, whether for automobiles, airplanes, power plants, or rockets, gradually improve their safety and reliability through repeated failures.

『"失敗"からしか学べないなら、学ぶためには"失敗"し続けなければならない』

ところが、「原子力発電所」だけは、この制御システムの大原則が使えない。

However, only "nuclear power plants" cannot use this major principle of control systems.

失敗のリターンが、メチャクチャにデカイからです。

Because, the return on failure is huge.

■事故から12年経った今でも、2万人が避難生活を続けている

"Twelve years after the accident, 20,000 people are still living in evacuation shelters"

という、現状の悲劇は勿論ですが、

This is, of course, the tragedy of the current situation, however,

■今回の事故の最悪ケースでは、東日本の全てが立ち入り禁止地区になっていた

"In the worst case scenario of this accident, all of eastern Japan would have been a no-go zone"

ことを、否定できる人間はいません。

No one can deny this.

-----

という訳で、私は、いつも通りの結論に至ってしまうのです。

So I come to the same conclusion as usual.

―― 日本国内において、生涯で2~3回は原発事故に遭遇し、最低1回は放射能汚染被害を受ける

私達の取り得る2つの未来