2023,江端さんの忘備録

以前、インタビュー番組で、俳優の大泉洋さんが、

In an interview program, actor Yo Oizumi once said,

『自分はカラッポで、やりたいものはない』

"I am empty and there is nothing I want to do"

『誰かがやって欲しいと思うことをやって、喜んでもらえるのが、嬉しいだけ』

" I am just happy to do what I think someone wants me to do, and that makes me happy"

という話を聞いて、とても腑に落ちたことを覚えています。

I remember hearing him say this on the program, and it really hit me.

-----

これに関する話を、私もいくつか書いていたような気がしましたので、過去の日記を調べてみました。

I had a feeling that I had written a few stories about this, so I checked my past diaries.

私達の多くは「やりたいこと」など持っていない。与えられた条件の中で「やれることをやるだけ」である

- "Originally, we do not have "I want to do it myself"

あなたの夢を諦めないで

- Don't give up on your dreams.

『♪ 自由に生きていく方法なんて、1通りだってないさ~ 』

"There is no way to live freely ..."

うん、やっぱり、たくさん書いていました。

Yes, I knew I was writing a lot.

------

―― 私たちには、やりたいことなどない

"There is nothing we want to do"

をデフォルトとしておくことは、正直で、ラクな生き方である、と思います。

I think that keeping this phrase as a default is an honest and easy way to live.

2023,江端さんの技術メモ

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


■動かなくて悩んでいたコード

// xml_parse.go
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

type testXML struct {
	Date     string `json:"dc:date"`
	Busroute string `json:"odpt:BusroutePattern"`
}

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://api.odpt.org/api/v4/odpt:BusroutePattern?odpt:operator=odpt.Operator:YokohamaMunicipal&acl:consumerKey=f4954c3814b207512d8fe4bf10f79f0dc44050f1654f5781dc94c4991a574bf4", nil)
	if err != nil {
		log.Fatal(err)
	}

	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)

	var data testXML

	err = json.Unmarshal(body, &data)
	if err != nil {
		fmt.Println("Unmarshal")
		log.Fatal(err)

	}

	fmt.Println(data)

}

出力結果

> go run xml_parse.go
Unmarshal
2023/05/01 18:05:31 json: cannot unmarshal array into Go value of type main.testXML
exit status 1

悩むこと1時間、("type testXML"スキーマを色々いじったりしていた)

『そういえば、このjsonのデータは、違う路線データも入っているはずだよな』
→ 『ということは、複数のデータが入っていることになるよな』
→ 『 For文で取らなければ不味くないか?』

で、ググってみたら、どうやらループになるように仕込んでおかないといけないらしいことが分かりました(XMLの先頭の情報が取れるだけだと思っていた)

■動いたコード

// xml_parse.go
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

type testXML struct {
	Date     string `json:"dc:date"`
	Busroute string `json:"odpt:BusroutePattern"`
}

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://api.odpt.org/api/v4/odpt:BusroutePattern?odpt:operator=odpt.Operator:YokohamaMunicipal&acl:consumerKey=f4954c3814b207512d8fe4bf10f79f0dc44050f1654f5781dc94c4991a574bf4", nil)
	if err != nil {
		log.Fatal(err)
	}

	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	if err != nil {
		log.Fatal(err)
		x
	}

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

	//fmt.Println(body)

	var data []testXML

	err = json.Unmarshal(body, &data)
	if err != nil {
		fmt.Println("Unmarshal")
		log.Fatal(err)

	}

	for _, e := range data {
		fmt.Println(e.Date)
	}

}

go run xml_parse.go
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00
2023-04-03T00:00:00+09:00"当たり"だったようです。


バス路線情報のJSONをブラウザで読みとってみました。


ここから、酷いハマり方をします(10時間くらい)。

上記のルートの位置情報の表示のコーディングがどうしても分からない。

以下は、上記のJSONを簡略化したものです(route.json)。

[
	{
		"dc:date":"2023-04-03T00:00:00+09:00",
		"dc:title":"007",
		"ug:region":
				{
					"type":"Triangle",
					"coordinates":[[139.6249873,35.4648941],[139.6237514,35.4648862],[139.623672,35.4650137]]
				},
		"owl:sameAs":"test1"
	},
	{
		"dc:date":"2023-04-03T00:00:00+09:00",
		"dc:title":"008",
		"ug:region":
				{
					"type":"LineString",
					"coordinates":[[139.667765,35.416456],[139.668006,35.416708],[139.668116,35.416788],[139.668276,35.416841]]
				},
		"owl:sameAs":"test2"
	}
]

問題は、ネストの中に入っていて、タグの名前のついていない、

"coordinates":[[139.6249873,35.4648941],[139.6237514,35.4648862],[139.623672,35.4650137]]

の部分です。

10時間くらいは戦ったかなぁ ―― もう疲れ果てて、質問サイトに投稿する為に、(上記の)JSONファイルと、このパーサープログラムを成形していました。

で、そのプログラムをテストランさせたら ―― これが動いてしまったのです。

// route_json.go

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
)

type testXML struct {
	Date    string `json:"dc:date"`
	Title   string `json:"dc:title"`
	Note    string `json:"odpt:note"`
	Owl     string `json:"owl:sameAS"`
	Regions struct {
		Type        string `json:"type"`
		Coordinates []interface{}
		//Coordinates []struct {
		//	Longitude float64 `json:"longitudes>longitude"`
		//	Latitude  float64 `json:"latitudes>latitude "`
		//} `json:"coodtinates"`
	} `json:"ug:region"`
}

func main() {
	file, err := ioutil.ReadFile("route.json")
	//file, err := ioutil.ReadFile("odpt_BusroutePattern.json")

	if err != nil {
		// エラー処理
	}

	var data []testXML

	err = json.Unmarshal(file, &data)
	if err != nil {
		fmt.Println("Unmarshal")
		log.Fatal(err)
	}

	fmt.Println(string(file))

	// ループによる取得
	for _, e := range data {

		fmt.Println(e) //
		mm := e.Regions.Coordinates

		fmt.Println(len(mm))

		for _, m := range mm {
			fmt.Println(m)
		}
	}
}

実行結果は以下の通りです。

> go run route_json.go
[
{
"dc:date":"2023-04-03T00:00:00+09:00",
"dc:title":"007",
"ug:region":
{
"type":"Triangle",
"coordinates":[[139.6249873,35.4648941],[139.6237514,35.4648862],[139.623672,35.4650137]]
},
"owl:sameAs":"test1"
},
{
"dc:date":"2023-04-03T00:00:00+09:00",
"dc:title":"008",
"ug:region":
{
"type":"LineString",
"coordinates":[[139.667765,35.416456],[139.668006,35.416708],[139.668116,35.416788],[139.668276,35.416841]]
},
"owl:sameAs":"test2"
}
]

{2023-04-03T00:00:00+09:00 007 test1 {Triangle [[139.6249873 35.4648941] [139.6237514 35.4648862] [139.623672 35.4650137]]}}
3
[139.6249873 35.4648941]
[139.6237514 35.4648862]
[139.623672 35.4650137]
{2023-04-03T00:00:00+09:00 008 test2 {LineString [[139.667765 35.416456] [139.668006 35.416708] [139.668116 35.416788] [139.668276 35.416841]]}}
4
[139.667765 35.416456]
[139.668006 35.416708]
[139.668116 35.416788]
[139.668276 35.416841]

ずっとエラーが出ていたんですが、突然表示されるようになりました。

        Coordinates []interface{}

JSONタグが付いていない問題は、これで解消できるようです。

で、(簡易版ではなく)実体のJSONファイルを使ってみても動きました。

こういうことがあるから、本当にコーディングというのは厄介なんですよね。


パースしたデータを表示してみました。

通路が(多分)順番に表示されることが確認できました。


だいたいこれで完成です。

// route_json.go
// 横浜市交通局 バス路線情報 / Bus route information of Transportation Bureau, City of Yokohama
// https://ckan.odpt.org/dataset/b_busroute-yokohamamunicipal

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
)

type testJSON struct {
	Id      string `json:"@id"`
	Type    string `json:"@type"`
	Date    string `json:"dc:date"`
	Context string `json:"@context"`
	Title   string `json:"dc:title"`
	Note    string `json:"odpt:note"`
	Regions struct {
		Type        string `json:"type"`
		Coordinates []interface{}
	} `json:"ug:region"`
	Owl              string `json:"owl:sameAS"`
	Pattern          string `json:"odpt:pattern"`
	Busroute         string `json:"odpt:busroute"`
	Operator         string `json:"odpt:operator"`
	Direction        string `json:"odpt:direction"`
	BusstopPoleOrder []struct {
		Note        string `json:"odpt:note"`
		Index       int    `json:"odpt:index"`
		BusstopPole string `json:"odpt:busstopPole"`
	} `json:"odpt:busstopPoleOrder"`
}

func main() {

	// JSONファイルから読み取る場合
	//file, err := ioutil.ReadFile("route.json")
	file, err := ioutil.ReadFile("odpt_BusroutePattern.json")
	if err != nil {
		// エラー処理
	}

	/*
		// Webアクセスで取得する場合

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

		resp, err := client.Do(req)
		if err != nil {
			log.Fatal(err)
		}
		defer resp.Body.Close()
		if err != nil {
			log.Fatal(err)
		}

		file, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			log.Fatal(err)
		}
	*/

	var data []testJSON

	err = json.Unmarshal(file, &data)
	if err != nil {
		fmt.Println("Unmarshal")
		log.Fatal(err)
	}

	//fmt.Println(string(file))

	// ループによる取得
	for _, e := range data {

		fmt.Println(e) // 全情報表情
		coors := e.Regions.Coordinates

		fmt.Println("len_mm", len(coors))

		for _, coor := range coors {
			fmt.Println(coor)
		}

		stops := e.BusstopPoleOrder

		fmt.Println("len_ss", len(stops))

		for _, stop := range stops {
			fmt.Println(stop.Note)
			fmt.Println(stop.Index)
			fmt.Println(stop.BusstopPole)
		}

	}
}

2023,江端さんの忘備録

先程、EE Times Japanの編集担当の方から、ご依頼を受けた内容のコラムを書き上げました。

I have just finished writing a column on a request from the editorial staff of EE Times Japan.

まあ、文章を書くのはいいです。図面の作成もできます。貰ったレビューを会話風に展開するのも、まあなんとかなっています。

Well, I can do writing. Drawings can be made. I can manage to develop the reviews I get into a conversational style.

問題はイラストです。

The problem is the illustration.

イラストにかける時間が、最近シャレにならないくらい長くなっています。

The time I spend on illustrations has become uncharacteristically long these days.

江端:「"SG"とは、当然、"シュタインズ・ゲート"のことです・・・え、ご存知ない?本当に??」

-----

最近話題になっている「AIに絵を描いてもらう」を調べてみました。

I looked into the recent topic of "having an AI draw a picture".

YouTubeなどで調べてみたのですが、なんか違う。

I have looked it up on YouTube, etc., but it is something different.

私の場合、コラムの内容に一致させる絵が欲しいので、最初から、コンセプトも、欲しいキャラクターも、構図も、明解なのです。

In my case, I want a picture that matches the content of the column, so from the beginning, the concept, the characters I want, and the composition are clear.

美しい背景は不要ですし、各種の色彩効果もいりません。

There is no need for beautiful backgrounds or various color effects.

線画と色が乗っているだけのイラストでいいのです。

It can be just an illustration with line drawings and colors on it.

しかし、思い通りの絵にならない。

However, the illustration does not turn out the way I want it to.

なんとももどかしいです。

It is very frustrating.

贅沢言わなければ、もっと速くイラストを作れる(×描ける)のかもしれませんが、私は贅沢を言いたいのです。

If I didn't have to be extravagant, I might be able to create (x draw) illustrations faster, but I want to be extravagant.

-----

最近、会社の資料に、軽い線画にちょっとだけ色を付けるようなイラストをを描いてくる若手の研究員が、ちらほら現われるようになってきました。

Recently, a few young researchers have been showing up here and there to draw illustrations of light line drawings with a little bit of color in company documents.

その線画イラストの入った資料は、恐しく説得力があるのです。

The material with its line-drawing illustrations is terribly compelling.

これまで、一生懸命システム構成図を記載してきた自分が、バカみたいに思えるほどです。

I feel like an idiot for having worked so hard to describe the system configuration diagram.

―― 絵を描く能力がある人って、やっぱり凄い

-----

ネットで、イラストを描いてくれるクラウドソーシングがあります。値段も概ね妥当です。

There is a crowdsourcing service online that will draw illustrations for you. Prices are generally reasonable.

そのサービスを提供してくれる人に、コラムの原稿と、自分の希望を出して、イラストを作ってもらうことができると思います。

I think you could ask the person who provides that service to create an illustration of my column, along with a draft of my column and my wishes.

しかし、私は、自分のコラムのイラストは、自分の手で描きたいのです。

However, I want to continue to make the illustrate of my columns with my own hands.

―― 「なんで、みんな、『他人と上手くやっていける』と思えるんだろう?」

2023,江端さんの忘備録

私、基本的に人にアドバイスをしません。

I, basically, don't give advice to people.

アドバイスというのは助言であって、単なるフレーズで、実体のない空虚な音声信号です。

Advice is advice, a just phrase, an empty sound signal without substance.

『助ける行為』そのものではありません。

It is not the "act of helping" itself.

私、若い頃から、頼みもしない人から、頼みもしないアドバイスを、一方的に受けて、本当にうんざりしてきました。

Since I was young, I have been really fed up with receiving unsolicited advice from people I didn't ask for, one-sidedly.

しかし、シニアになった自分を省みると、この『頼みもしないアドバイス』を他人にしてしまう傾向が強くなるのを知っています。

However, as I reflect on myself as a senior, I know that I am more likely to give this 'unsolicited advice' to others.

ですから、努めて自分を監視するようにしています。

Therefore, I try to monitor myself.

まあ、私の場合、"ブログ"という、不特定多数の発信装置があるので、その欲望を満しているとも言えます。

Well, in my case, I have a "blog," which is an unspecified device to transmit information to a large number of people, so I can say that I am fulfilling that desire.

しかし、私のブログは『不愉快に感じる人は、ブログを読まなければよい』ので、上記の『頼みもしないアドバイス』とは、一線を画するものであると思っています。

However, I believe that my blog is distinct from the above 'unsolicited advice' because 'those who find it offensive should not read the blog'.

-----

非常に稀ではあるのですが、私は『頼まれるアドバイス』を受けることがあります。

Although it is very rare, I do get 'advice that I am asked for'.

基本的には、頼まれれば応じることにしていますが、その場合でも、頼まれた範囲内のアドバイスに留めることに努めています。

Basically, I try to respond when asked, but even then I try to keep my advice within the scope of what I am asked to do.

話題が発展して、全く別の話や、自分の自慢話や、ましてや説教にならないように、自分を監視しています。

I monitor myself to make sure that the topic does not evolve into something completely different, or into bragging about myself, much less preaching.

-----

私の自己監視方法は、2つあります。

I have two methods of self-monitoring.

(1)終了時間を決めておくこと

(1) Set an end time.

(2)相手と自分の喋っている時間の長さが"等分"となるように、会話をコントロールすること

(2) Control the conversation so that the length of time me and the other person are talking is "equally" long.

私にとって、難しいのは(2)です。

For me, the difficult part is (2).

私は、ネタの引き出しが多いのです ―― ざっくり、ブログで約4000(10年間分)、コラムが300、商用コラムが200ほどあります。ですので、ついつい、いらん話をしてしまいがちです。

I have a lot of material -- roughly 4,000 blogs (10 years worth), 300 columns, and about 200 commercial columns. So, I tend to talk about things you don't want to hear about.

ですので、これを抑制するには、(1)の時間制限が重要になってきます。

Therefore, the time limit in (1) is important to control this.

-----

ご理解頂けるかと思うのですが、私が飲み会を忌避する理由の一つは「これ」です。

As I am sure you can understand, one of the reasons I avoid drinking parties is this.

酔っぱらった上司に、飲み会の開始から解散まで、延々と自慢話をされて、説教を喰らう ―― そんな「地獄」に誰が行こうと思うものか。

A drunken boss brags and lectures you endlessly from the start of a drinking session to its breakup - who would want to go to such a "hell"?

まあ、今や立派なシニアになった私が、今さら、こんな目に合うことはないと思います。

Well, now that I am a respectable senior citizen, I don't think I will have to go through this now.

しかし、逆に、私が、こんな上司のような醜態を晒す可能性はあります。

But, on the other hand, I could be as ugly as these bosses.

『もし私がそんな醜態を晒したら』と考えると、拳銃で自分の頭を撃ち抜きたくなる衝動にかられます。

If I were to make such an abomination,' I will say, 'I would be tempted to shoot myself in the head with a pistol.

-----

もう、お分かりになりますよね。

You already know what I mean.

『拳銃で自分の頭を撃ち抜けよ』と、私に思わせるような奴がいるってことです。

It means there are persons who make me think, 'Take a pistol and shoot yourself in the head'.

飲み会における、最も優れた上司の振舞いは『しゃべらず、だまって、金だけ出す』です。

そんな感じで、今、私は、飲み会のなかったコロナ禍のこの3年間の幸せを、しみじみと実感しています。

And so I am now soaking up the happiness of the last three years of the Corona Disaster, when I did not have a drinking party.

私:「そして、世界は『飲み会』を諦める ―― アフターコロナでも」

 

2023,江端さんの技術メモ

1 目的

すぐに環境やらコード(の場所)やらを忘れるので、自分の為にメモを残す

2 簡単なfastapiの環境とコード

私の環境では、c:\users\ebata\fastapi1,2,3,4,5あたりにある。

2.1. 最新のPIPをアップグレードする

> pip install --upgrade pip
> python -m pip install --upgrade pip
> python3 -m pip install --upgrade pip

のいずれかでできる。

2.2. uvicorn, fastapi, pydantic, pandas, requests, jsonのモジュールをインストールする

> pip3 install fastapi
> pip3 install uvicorn[standard]

は必須だが、後はプログラムを動かせば、プログラムの方から、インストールを指示されると思うので大丈夫(だろう)。

2.3. uvicornを起動する

> uvicorn index:app --reload

これで、自動的に"index.py"が動き出す。

2.4. クライアントを起動する

> python request.py

で、起動を確認する。

以上

3. ソースコード

3.1. index.py

# https://miseruit.com/2022/07/18/post-2939/

from fastapi import FastAPI
from pydantic import BaseModel
import pandas

class Item(BaseModel):
    ID: str
    Name: str
    Class: str

app = FastAPI() #インスタンスを作成

User_list =[
    {"ID":"M001","Name":"Takashi","Class":"A"},
    {"ID":"M002","Name":"Hanako","Class":"A"},
    {"ID":"M003","Name":"Hiroshi","Class":"B"},
    {"ID":"M004","Name":"Kyoko","Class":"B"},
    ]

# joson_normalize関数を用いてJsonデータをDataFrame型に変換します。
df = pandas.json_normalize(User_list)

# Get /Users/ : 全件取得
# Get /Users/{ID} :特定のIDのみ取得
# POST /Users/ :ユーザの登録
# DELETE /Users/{ID} :ユーザの削除

# curl http://localhost:8000/Users/
@app.get("/Users/")
async def users():
    return User_list

# curl http://localhost:8000/Users/M003
@app.get("/Users/{u_id}")
async def users(u_id:str):
    return list(filter(lambda item : item['ID']==u_id, User_list))

# Windowsの場合 
# {"ID":"M005","Name":"Aya","Class":"C"}]を追加する
# curl -X POST -H "accept: application/json" -H "Content-Type: application/json" -d "{\"ID\":\"M005\", \"Name\":\"Aya\", \"Class\":\"C\"}" http://localhost:8000/Users/

@app.post("/Users/")
async def users(user: Item):
    User_list.append({"ID": user.ID,"Name":user.Name,"Class":user.Class})
    return User_list

# curl -X DELETE -H "accept: application/json" http://localhost:8000/Users/M003
@app.delete("/Users/{u_id}")
async def users(u_id:str):
    global df
    df = df.drop(df.index[df["ID"]==u_id])
    return df.to_json(orient='records')

3.2. request.py

import requests
import json

# テスト
#url = 'https://wp.kobore.net/'
#response = requests.get(url)
#print(response.text)

#print()

print("-----start of get(1)")

# curl http://localhost:8000/Users/ と同じ機能を実施
r = requests.get('http://localhost:8000/Users/')

print(r.url)
print(r.status_code)
print(r.text)
print(r.json())

print("-----end of get(1)")

print()

# curl http://localhost:8000/Users/M003 と同じ機能を実施

print("-----start of get(2)")

r = requests.get('http://localhost:8000/Users/M003')

print(r.url)

print(r.status_code)
print(r.text)
print(r.json())
print("-----end of get(2)")

print()
print("-----start of delete")
# curl -X DELETE -H "accept: application/json" http://localhost:8000/Users/M003と同じ機能を実施
r = requests.delete('http://localhost:8000/Users/M003')

print(r.url)

print(r.status_code)
print(r.text)
print(r.json())

print("-----end of delete")
print()

# curl -X POST -H "accept: application/json" -H "Content-Type: application/json" -d "{\"ID\":\"M005\", \"Name\":\"Aya\", \"Class\":\"C\"}" http://localhost:8000/Users/ と同じ機能を実現
# {"ID":"M005","Name":"Aya","Class":"C"}]を追加する

headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
json_payload = '{"ID":"M005","Name":"Aya","Class":"C"}'  # ここで100回くらいのパターンを試したぞ

print("headers:",headers)
print("payload:",json_payload)

#r = requests.post('http://localhost:8000/Users/',headers=headers, params=payload)
#r = requests.post('http://localhost:8000/Users/', headers=headers,params=json.loads(payload))
r = requests.post('http://localhost:8000/Users/', headers=headers, data=json_payload)

print(r.url)

print(r.status_code)
print(r.text)
print(r.json())

2023,江端さんの忘備録

先日、アニメ「スキップとローファー」についてちょっと記載しました。

 

『自分が何をしなければならないか、ようやく気がついた時、それは、非常に小さくて基本的なものであった』

I recently described a bit about the anime "Skip and the Loafer".

それで思い出したのですが、私、庵野監督の最高傑作アニメは、「エバなんとか」でもなくて、「シンなんとか」でもなくて、「彼氏彼女の事情」だと思うんです。

That reminds me, I think Anno's best anime is not "Eva something" or "Shin something", but "Boyfriend and Girlfriend".

「負け犬、黙っていろ」

ここ2年くらい、アニメ「フルーツバスケット(2019年度版)」を視聴していました。

私のこの所感に同意してくれる人は、少数 ―― というか、絶無だと思いますが。

I think there are a few -- or rather, none at all -- who agree with this opinion of mine.

2023,江端さんの忘備録

『ロシア大統領を暗殺すればいいのに』というぶっそうな話が、私たち民間人の間で口にされます。

We civilians talk about 'why don't you just assassinate the Russian president?

気持ちは分かるのですが、『ロシア大統領を暗殺した"後"にどうなるか』、の視点が抜けているように思います。

I understand their feelings, but I think they are missing the point of view of what happens after the assassination of the Russian president.

例えば、独裁的な大統領と反目している、民権主義者の国際融和を唱える穏健派で、市民に支持されているような"No.2"がいれば良いです。

For example, there should be a "No. 2" who is a moderate, civil-rights international reconciliation advocate who is opposed to the dictatorial president and who is supported by the public.

しかし、そんな人物、ラインから外されているのは当然でしょうし、下手すれば粛清されています。

However, such a person, it would be natural to be removed from the line, and if he/she should have had to be purged.

あるいは、国内の状況としては、警察または軍隊によって市民が虐殺されていて、独裁者が完全に国民から反目されているという状況が望ましいです。

Alternatively, the domestic situation should be one in which civilians are being slaughtered by the police or army and the dictator is completely turned against the people.

加えて、独裁者は国内で国民によって処刑されるのがベストシナリオです。

In addition, the best scenario is for the dictator to be executed by the people within the country.

ところが、こんな好条件、なかなかあるものではありません。

Such favorable conditions, however, are not easy to realize.

独裁者の暗殺後は ―― 私の知っている限り ―― 内戦、テロで国内死傷者がシャレにならない規模で発生し、ISのような宗教国家の樹立を掲げるやつが跋扈しはじめて、テロが他国に波及します。

After the assassination of a dictator -- as far as I know -- civil wars and terrorist attacks cause domestic casualties on an unprecedented scale, and those who advocate the establishment of a religious state like IS begin to dominate and terrorism spreads to other countries.

とにかく、独裁体制の国家というのは、壊した後のメンテナンスが、恐しく難しいのです。

Anyway, dictatorships are terribly difficult to maintain after they are destroyed.

-----

そもそも、暗殺を含めて、国外からの武力介入は、内政干渉や侵略になります。

In the first place, armed intervention from outside the country, including assassination, constitutes interference in internal affairs and invasion.

現在のウクライナ侵攻も、NATO軍がロシアに攻め込めないのは、上記の大原則があるからです(もちろん、核の脅威もありますが)。

The current invasion of Ukraine is also the reason why NATO forces cannot invade Russia because of the above major principles (and of course, the nuclear threat).

NATOという組織は、この内政干渉や侵略の問題を回避する為に作られた軍事同盟 ―― 『同盟国の一つが攻撃されれば、同盟国全部が攻撃されたとみなす』というものです。

The NATO organization is a military alliance designed to avoid this problem of interference in internal affairs and aggression -- "If one of the allies is attacked, all of the allies are considered to have been attacked.

ちなみに、日米安全保障条約も同じ仕組みです。

Incidentally, the Japan-U.S. Security Treaty has the same structure.

例えば、コロラド州のフォートコリンズが武力攻撃されれば、我が国の自衛隊は同盟国として参戦が"できます"。

For example, if Fort Collins, Colorado is attacked, our Self-Defense Forces, as an ally, "can participate" in the war.

ところが、日本の場合、憲法の規定から、自衛隊は領土防衛以外の目的では、武力行使ができません ―― で、これでは、軍事同盟の意味がないので、なんとかしようとしたものが『集団的自衛権』というやつです(今日はこの話は割愛します)。

『米軍』が絡んできて、そこで始めて『集団的自衛権』が発動するのだから、米軍が何もされていない段階では、自衛隊は、1mmも動けない、が、正論です ―― が、

However, in the case of Japan, the Self-Defense Forces cannot use force for any purpose other than territorial defense under the provisions of the Constitution -- and since this makes no sense for a military alliance, the "right of collective self-defense" was created (I will skip this topic today).

ともあれ、ぶっちゃけ、ウクライナがNATOに加盟する、というのは、ロシアにとっては、悪夢の中でも、最悪の部類の悪夢であるのは確かなのです。

Anyway, to be frank, Ukraine joining NATO is certainly one of the worst of nightmares for Russia.

これについては、BSプレミアム「ロシア 衝突の源流」が、面白かったです。

Regarding this, the BS Premium "Russia: The Origins of the Clash" was interesting.

-----

『北朝鮮の首領を暗殺すればいいのに』も同様です。

The same is true of "Why Don't You Just Assassinate the Head of North Korea?

あそこは地政学的に、めちゃくちゃ面倒な場所にあります。

That place is geopolitically located in a messy place.

ロシアと中国と韓国に接していて、特に中国と韓国は、あの王政社会主義の国を、心底面倒くさいと思っています。

Bordered by Russia, China, and South Korea, China and South Korea in particular find that monarchical socialist country to be a hassle at heart.

米国なんか、何度もあの国に騙されてきましたが、面倒な大国(ロシアと中国)の抑えの役割を果しているので、本気で軍事攻撃しようとはしません。

The U.S. has been fooled by that country many times, but since it serves to keep the troublesome powers (Russia and China) at bay, it will not seriously attempt a military attack.

自棄になられて、ミサイルで米国の本土を攻撃されるくらいなら、今のままの方が良いでしょう。

It would be better to remain as they are now than to become desperate and attack the U.S. mainland with missiles.

-----

『中国の総書記を暗殺すれば』は、もう問答無用でダメです。

'If you assassinate the General Secretary of China' is no longer good enough, no questions asked.

もうこれは、私の想像の斜上はるか上をいく、とんでもない惨劇が待っていると簡単に予想できます。

I can easily predict that this will be a terrible tragedy, far beyond my imagination.

-----

ともあれ、『悪人(但し、私たちの価値基準でですか)を殺害すれば、物事が好転する』というのは、正直ちょっと見積りが甘いんじゃないかな、と思うのです。

Anyway, I honestly think it is a bit naive to estimate that 'killing bad people (but by our standards of value) will turn things around'.

2023,江端さんの忘備録

『膨大な回り道をして、もの凄く小さな真実に辿りつく』 ―― いえいえ、私は、「いい話」をしたい訳ではないのです。

'A huge detour, leading to an awfully small truth.' No, no, I am not trying to tell a "good story".

ここ数日間、慣れない言語(Python)で、機能モジュールを作る為に、ネットで公開されている沢山のプログラムを片っぱしから写経して、成功したり失敗したりを続けてきました。

For the past few days, I have been trying to create a functional module in a language (Python) that I am not familiar with, copying from scratch many programs available on the Internet, with success and failure.

『自分が何をしなければならないか、ようやく気がついた時、それは、非常に小さくて基本的なものであった』

'When I finally realized what I had to do, it was something very small and basic.'

ということって、結構あります。

This is quite often the case.

私は、今、1つの山を越えて、ちょっとホッとしています。

I am a bit relieved now that I have crossed one mountain.

-----

最初から「正解が見える人」もいるかもしれませんが、私はそういう人間ではないようです。

There may be people who can "see the right answer" from the beginning, but I don't seem to be one of those people.

この自分の『低能 & 無能』によって、膨大な時間が消費され続けていますが、『暇を感じる時間はない』というポジティブな考え方もできると思っています。

This 'low & incompetence' of mine continues to consume a huge amount of my time, but I believe I can also think positively that 'I don't have time to feel bored'.

『本当に、意義のない、無駄な人生を生きてきたなぁ』と、つぶやきながら、私は死んでいくつもりです。

-----

ところで、今期から始まった、アニメ「スキップとローファー」のオープニング、いいですね(YouTubeに飛びます)

By the way, I like the opening of the anime "Skip and Loafer," which started this season (jump to YouTube).

主人公の『ポンコツなエリート女子』が、ほのぼのと良いです。

The main character, a "clunky elite girl," is mildly good.

後半のダンスの部分は、実際に踊った人の動きをトレースしたのだろうなぁ、と思います。

I think that the dance part in the latter half must have been traced from the actual dancers.

服の動きが、とてもリアルでいいなぁ、と。

The movement of the clothes is very realistic, I thought.

メイキングの映像も見たいです。

I would like to see a video of the making of the film.

2023,江端さんの技術メモ

結論から先に言うと

json_payload ='{"ID":"M005","Name":"Aya","Class":"C"}'
'"が付いているかどうか、だったというオチでした。

pythonでFastAPIを試す

のように、pythonでFastAPIを使って、外部と内部のインターフェースのテンプレートを作るというのが、目下の課題でした。
多くのサンプルプログラムがあったのですが、私はhttpのGET/POSTができれば十分だったので、他のことは忘れて、そのポイントのみに絞って、ネットを探し回りました。
まずは、FastAPIを受ける側(サーバと言えるのかな)のプログラムは、

Python | FastAPIでAPI作成 ~その6:DELETEでデータ削除 & Pandas活用

を参考(というかコピペ)させて頂きました。

以下のコードを、私の場合はC:\Users\ebata\fastapi4に、index.pyという名前で置きました。
# https://miseruit.com/2022/07/18/post-2939/

from fastapi import FastAPI
from pydantic import BaseModel
import pandas

class Item(BaseModel):
    ID: str
    Name: str
    Class: str

app = FastAPI() #インスタンスを作成

User_list =[
    {"ID":"M001","Name":"Takashi","Class":"A"},
    {"ID":"M002","Name":"Hanako","Class":"A"},
    {"ID":"M003","Name":"Hiroshi","Class":"B"},
    {"ID":"M004","Name":"Kyoko","Class":"B"},
    ]

# joson_normalize関数を用いてJsonデータをDataFrame型に変換します。
df = pandas.json_normalize(User_list)

# Get /Users/ : 全件取得
# Get /Users/{ID} :特定のIDのみ取得
# POST /Users/ :ユーザの登録
# DELETE /Users/{ID} :ユーザの削除

# curl http://localhost:8000/Users/
@app.get("/Users/")
async def users():
    return User_list


# curl http://localhost:8000/Users/M003
@app.get("/Users/{u_id}")
async def users(u_id:str):
    return list(filter(lambda item : item['ID']==u_id, User_list))


# Windowsの場合 
# {"ID":"M005","Name":"Aya","Class":"C"}]を追加する
# curl -X POST -H "accept: application/json" -H "Content-Type: application/json" -d "{\"ID\":\"M005\", \"Name\":\"Aya\", \"Class\":\"C\"}" http://localhost:8000/Users/

@app.post("/Users/")
async def users(user: Item):
    User_list.append({"ID": user.ID,"Name":user.Name,"Class":user.Class})
    return User_list

# curl -X DELETE -H "accept: application/json" http://localhost:8000/Users/M003
@app.delete("/Users/{u_id}")
async def users(u_id:str):
    global df
    df = df.drop(df.index[df["ID"]==u_id])
    return df.to_json(orient='records')
このプログラムは、メモリ上の名簿を検索(GET)、追加(POST)、削除(DELETE)するものです。

C:\Users\ebata\fastapi4> uvicorn index:app --reload

で起動します。
多分、プログラムの方から、「pipでxxxxを入れろ」と文句を言ってきますので、大人しく従います。
プログラム中に記載されている、curlのコマンドを使うとFastAPIの動作を確認できます。
さて、このプログラムで基本動作は確認できますが、基本的にクライアントのプログラムの叩き台がなければ、使えません。モジュールプログラムの中から、curlのコマンドを発行しろというのも乱暴な話です。
ですので、サクッとクライアント(というかFastAPIのアクセス用のテストプログラム)を作成してしまうと思ったのですが、ここで嵌りました。
先ずは、以下のコードをrequest.pyという名前で、C:\Users\ebata\fastapi4に置きました。
(以下のファイルは、動きたてのコードを修正せずに、汚いままで展開しています)
import requests
import json

# テスト
#url = 'https://wp.kobore.net/'
#response = requests.get(url)
#print(response.text)

#print()

print("-----start of get(1)")

# curl http://localhost:8000/Users/ と同じ機能を実施
r = requests.get('http://localhost:8000/Users/')

print(r.url)
print(r.status_code)
print(r.text)
print(r.json())


print("-----end of get(1)")

print()

# curl http://localhost:8000/Users/M003 と同じ機能を実施

print("-----start of get(2)")

r = requests.get('http://localhost:8000/Users/M003')

print(r.url)

print(r.status_code)
print(r.text)
print(r.json())
print("-----end of get(2)")


print()
print("-----start of delete")
# curl -X DELETE -H "accept: application/json" http://localhost:8000/Users/M003と同じ機能を実施
r = requests.delete('http://localhost:8000/Users/M003')

print(r.url)

print(r.status_code)
print(r.text)
print(r.json())

print("-----end of delete")
print()



# curl -X POST -H "accept: application/json" -H "Content-Type: application/json" -d "{\"ID\":\"M005\", \"Name\":\"Aya\", \"Class\":\"C\"}" http://localhost:8000/Users/ と同じ機能を実現
# {"ID":"M005","Name":"Aya","Class":"C"}]を追加する

headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
json_payload = '{"ID":"M005","Name":"Aya","Class":"C"}'  # ここで100回くらいのパターンを試したぞ

print("headers:",headers)
print("payload:",json_payload)

#r = requests.post('http://localhost:8000/Users/',headers=headers, params=payload)
#r = requests.post('http://localhost:8000/Users/', headers=headers,params=json.loads(payload))
r = requests.post('http://localhost:8000/Users/', headers=headers, data=json_payload)

print(r.url)

print(r.status_code)
print(r.text)
print(r.json())
で、
C:\Users\ebata\fastapi4> python request.py
にて、GETとDELETEは問題なくサクっと動いたのですが、POSTだけが思うように動かない
{'detail': [{'loc': ['body'], 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}]}
{"detail":[{"loc":["body"],"msg":"field required","type":"value_error.missing"}]}
エラー番号422
やらが、ワラワラと出てきて、頭を抱えました。
色々検索して調べると『こうやればいい』というアドバイスだけして、サンプルコード(1行で足る)を残さない奴が、世界中には山ほどいます(アドバイスではなく、コードを残して欲しい)。
のコードを真似て、ようやく動かすことができました(本当に助かりました)。
とりあえず、これでサーバとクライアントの対(つい)が完成し、実プログラムに展開できる準備ができたと思います。

以上

2023,江端さんの忘備録

嫁さんが家に戻ってきました ―― 家の中の空気が流れ出したような気がします。

My wife is back home -- I feel like the air in the house has started to flow.

こういう話を嫁さんにすると『私は家政婦か』と文句を言われるのですが、そういうことではないのです。

When I talk to my wife about these things, she complains, 'Am I a housekeeper?

家の中で話ができる相手がいるというのは、やっぱり良いものです。

It is still nice to have someone to talk to in the house.

もし嫁さんが先に逝き、私が「孤立」すると、空気が止った家の中での生活がずっと続くことになる ―― と考えると、結構怖いです。

If my wife passes away first and I am "isolated", I will be living in a house with the air stopped for a long time -- which is pretty scary.

それでも、嫁さんよりは私の方が「孤立」には耐性があるように思います。

Still, I think I am more tolerant of "isolation" than my wife.

嫁さんからの依頼事項『嫁さんより長生きをする』を実施すべく、酒、たばこ、女、博打、「全て"なし"」にして、人生を実施中です。

In order to fulfill my wife's request, "I will live longer than my wife," I am now living my life "without" alcohol, cigarettes, women, gambling, and everything else.

-----

江端:「『遊ぶ金が欲しくて、強盗した』というニュースを聞くことがあるけど、訳が分からないんだよな」

Ebata: "Sometimes we hear on the news that people 'wanted money to play with, so they robbed people,' but I don't understand the reason."

嫁さん:「そう?」

Wife: "Really?"

江端:「遊ばなければいいじゃんか」

Ebata: "Why don't they just not play?"

嫁さん:「じゃあ、何をしてればいいの」

Wife: "Well, what should they do?"

江端:「勉強」

Ebata: "Study"

と言ったら、嫁さんが大爆笑していました。

When I said this, my wife burst out laughing.

24時間いつでもディズニーランド

----

江端:「コーディングしたり、コラム書いたり、特許のアイデア考えたり、やることなんて、山ほどあるじゃん?」

Ebata: "There are so many things to do, like coding, writing columns, coming up with ideas for patents, etc."

嫁さん:「じゃあ、強盗犯のところにいって『なんで、"遊ぶ"のではなくて、"コーディング"しなかったの?』って聞いてみたらどうかな?」

Wife: "Well, why don't you go to the robbers and ask them, 'Why didn't you "code" instead of "play"?'