「ファイル」 → 「フォルダを開く」でフォルダを選択すれば、settings.jsonが出てこなくなる
フォルダの中に、".vscode"のディレクトリがって、その中には、以下のファイルが入っていることも必要(多分)
江端智一のホームページ
「ファイル」 → 「フォルダを開く」でフォルダを選択すれば、settings.jsonが出てこなくなる
フォルダの中に、".vscode"のディレクトリがって、その中には、以下のファイルが入っていることも必要(多分)
Open Street Map(以下OSMといいます)とは、「自由に利用でき、なおかつ編集機能のある世界地図を作る共同作業プロジェクト」のことです。
Open Street Map (OSM) is a collaborative project to create a freely available, yet editable, map of the world.
一般的には、"xxxxx.osm"ファイルという名前の地図情報ファイルの意味で使われることが多いです。
In general, it is often used to mean a map information file named "xxxxxx.osm" file.
このようなomsファイルは、地図を使った交通シミュレーションを行う研究員にとっては、大変助かります。
These oms files are very helpful for researchers who are working on map-based traffic simulations.
しかし、OSMの地図は、世界中の人達の協力によって作られているものですし、そもそも、地図は常に拡張や変更を続けるものです。
However, OSM's maps are made with the cooperation of people from all over the world, and in the first place, maps are always expanding and changing.
「完璧な地図」などはありません。
There is no such thing as a "perfect map.
特に、自分の研究でomsファイルを使う場合、必要に応じて地図情報を正しく修正したいことがあります。
Especially when using oms files in my own research, I may want to modify the map information correctly if necessary.
-----
そんな訳で、今朝から、OSMの地図の編集を試みています。
That's why I've been trying to edit the OSM map since this morning.
以下は、横浜国立大学の敷地内の地図ですが、この中に、「自動車が入れる道」が記載されていなかったので、先程追記してみました。
The following is a map of the grounds of Yokohama National University, which I have just added to the map because it did not include a "car road".
なぜ、私が大学キャンパスの道を知っているのか ―― そりゃもう、このキャンパスの中を、何百回、自動車と足で走り回り、GPSロガーでデータを取りまくったことか、分かりません ―― 仕事(屋外実証実験)で。
How do I know my way around a university campus? Well, I can't tell you how many times I've driven around this campus by car and foot, taking data with my GPS logger for my work (field demonstration).
-----
ところで、今朝の私のこの修正が、ボタン一つでOSM地図情報に登録されてしまって、唖然としています。
By the way, I was stunned to see that this correction of mine this morning was registered in the OSM Map Information with the click of a button.
修正後は、私の記載した地図が、世界中で反映されてしまうことになります。
After the revision, the map I described will be reflected all over the world.
―― 私の過失、または、悪意で、地図を改竄(かいざん)してしてしまったらどうするんだ?
"What if the map is tampered with due to my negligence or malicious intent?"
と、かなり不安な気持ちになってきました。
I came to feel quite uneasy.
なにしろ、今回の修正は、私の初めてのトライアルですので。
After all, this is my first trial with this modification.
そのような場合でも、多分、『だれかが私の改竄を修正する』、そして、『私が間違いを続ければ、私をOSMメンバから除名する』と期待しているのですが ――
Even in that case, I'm hoping that maybe "someone will correct my falsification" and "if I continue to be wrong, they will expel me from OSM membership" -- but I'm not sure.
それにしても、「自由に利用でき、なおかつ編集機能のある世界地図を作る共同作業プロジェクト」って凄いなぁ、と実感しています。
Anyway, I really feel that "a collaborative project to create a freely available, yet editable world map" is a great idea.
=====
実行手順
Step.1 https://www.openstreetmap.org/ から、「ユーザ登録」
Step.2 ユーザ登録します。
私の場合、サードパーティ認証にGoogleのログインを使うことにしました。
その後は、ガイダンス画面に入るので、そこで一通り勉強してから、編集作業をします(今日は割愛します)。
以上
エージェントオブジェクトの消滅方法に着目したコード
参照させて頂いたページ https://qiita.com/yoshinori_hisakawa/items/a6608b29059a945fbbbd
// https://qiita.com/yoshinori_hisakawa/items/a6608b29059a945fbbbd
package main
import (
"context"
"fmt"
"sync"
"time"
)
func main() {
wg := sync.WaitGroup{}
wg.Add(1)
go grandparent(&wg)
//time.Sleep(10 * time.Second)
wg.Wait()
}
func grandparent(wg *sync.WaitGroup) {
// contextを生成
defer wg.Done()
ctx := context.Background()
// 親のcontextを生成し、parentに渡す
ctxParent, cancel := context.WithCancel(ctx)
go parent(ctxParent, "Hello-parent")
// parentのcontextをキャンセル。mainを先に終了させないように1秒待ってから終了
cancel()
time.Sleep(1 * time.Second)
fmt.Println("grandparent end")
}
func parent(ctx context.Context, str string) {
// parentからcontextを生成し、childに渡す
childCtx, cancel := context.WithCancel(ctx)
go child(childCtx, "Hello-child")
defer cancel()
// 無限ループ
for {
select {
case <-ctx.Done():
fmt.Println(ctx.Err(), str)
return
}
}
}
func child(ctx context.Context, str string) {
// 無限ループ
for {
select {
case <-ctx.Done():
fmt.Println(ctx.Err(), str)
return
}
}
}
// context canceled Hello-child
// context canceled Hello-parent
// grandparent end
週末使って、色々試した結果、「チャネルを返り値とするサブルーチンは、fatal error: all goroutines are asleep - deadlock! となる」ということでした。
# まあ、 select-caseで、メソッドを直接使いたい、という変則的な使い方でしたので、仕方ありませんが、
package main
import "fmt"
func channel_test() chan int {
ch := make(chan int)
ch <- 1
return ch
}
func main() {
v := channel_test()
fmt.Println(v)
// go channe_test()とすれば動く
}
こんな使い方を想定していました。
for{
select{
case v:= <-channel_test():
// do something
}
}
続報:
ネットの質問版で質問してみたら、
ch := make(chan int)を、ch := make(chan int, 1)としたら動くよ、と教えて頂き、動作確認できました。
package main
import (
"fmt"
"time"
)
func channel_test() chan int {
ch := make(chan int, 1)
ch <- 1
return ch
}
func main() {
v := channel_test()
fmt.Println(v)
// go channe_test()とすれば動く
for {
select {
case v := <-channel_test():
fmt.Println("case v := <-channel_test():", v)
}
time.Sleep(time.Second)
}
}
これは、結構オーソドックスな手法で、いろいろなところに使われています。
/*
お題: personが終了したらsubPerson1も subPerson2も強制的に終了させるには?
*/
package main
import (
"fmt"
"sync"
"time"
)
func subPerson1(i int, wg *sync.WaitGroup, ch chan struct{}) {
defer wg.Done()
<-ch // close(ch)が発行されるまでロック (普通はselect待ちにする)
fmt.Println(" End of sub_person1(", i, ")")
}
func subPerson2(i int, wg *sync.WaitGroup, ch chan struct{}) {
defer wg.Done()
<-ch // close(ch)が発行されるまでロック (普通はselect待ちにする)
fmt.Println(" End of sub_person2(", i, ")")
}
func person(i int, wg *sync.WaitGroup) {
fmt.Println(" Start... person(", i, ")")
defer wg.Done()
subWG := sync.WaitGroup{}
subWG.Add(2)
ch := make(chan struct{})
go subPerson1(i, &subWG, ch)
go subPerson2(i, &subWG, ch)
time.Sleep(10 * time.Second)
close(ch)
subWG.Wait()
fmt.Println(" End... person(", i, ")")
}
func main() {
fmt.Println("start... main()")
wg := sync.WaitGroup{}
for i := 0; i < 5; i++ {
wg.Add(1) // goルーチンを実行する関数分だけAddする
go person(i, &wg)
}
wg.Wait()
fmt.Println("end of ... main()")
}
出力結果はこんな感じです。
ちょっと変な感じがしますが、多分Printlnを記載している時間タイミングに因るものだろう、と思います。
$ go run main.go
start... main()
Start... person( 4 )
Start... person( 2 )
Start... person( 3 )
Start... person( 0 )
Start... person( 1 )
End of sub_person2( 2 )
End of sub_person2( 0 )
End of sub_person1( 0 )
End... person( 0 )
End of sub_person2( 4 )
End of sub_person1( 4 )
End... person( 4 )
End of sub_person2( 3 )
End of sub_person1( 3 )
End... person( 3 )
End of sub_person1( 2 )
End... person( 2 )
End of sub_person2( 1 )
End of sub_person1( 1 )
End... person( 1 )
end of ... main()
/*
お題: subPerson1が終了したら subPerson2も巻き添えで強制的に終了させるには?
当初、一方が終了したら、他方も終了するように作りたかったのだけど、分からなかったので、subPerson1 → subPerson2 の順番で終わせるような実装にした
*/
package main
import (
"fmt"
"sync"
"time"
)
func subPerson1(i int, wg *sync.WaitGroup, ch chan struct{}) {
defer wg.Done()
time.Sleep(1 * time.Second)
fmt.Println(" End of sub_person1(", i, ")")
close(ch) // subPerson2に終了を通知する
}
func subPerson2(i int, wg *sync.WaitGroup, ch chan struct{}) {
defer wg.Done()
<-ch // subPerson1 のclose(ch)が発行されるまでロック (普通はselect待ちにする)
fmt.Println(" End of sub_person2(", i, ")")
}
func person(i int, wg *sync.WaitGroup) {
fmt.Println(" Start... person(", i, ")")
defer wg.Done()
subWG := sync.WaitGroup{}
subWG.Add(2)
ch := make(chan struct{})
go subPerson1(i, &subWG, ch)
go subPerson2(i, &subWG, ch)
subWG.Wait()
fmt.Println(" End... person(", i, ")")
}
func main() {
fmt.Println("start... main()")
wg := sync.WaitGroup{}
for i := 0; i < 5; i++ {
wg.Add(1) // goルーチンを実行する関数分だけAddする
go person(i, &wg)
}
wg.Wait()
fmt.Println("end of ... main()")
}
ebata@DESKTOP-P6KREM0 MINGW64 ~/goga/0-2
$ go run main.go
start... main()
Start... person( 4 )
Start... person( 0 )
Start... person( 1 )
Start... person( 3 )
Start... person( 2 )
End of sub_person1( 3 )
End of sub_person2( 3 )
End... person( 3 )
End of sub_person1( 0 )
End of sub_person1( 4 )
End of sub_person2( 4 )
End... person( 4 )
End of sub_person2( 0 )
End... person( 0 )
End of sub_person1( 1 )
End of sub_person2( 1 )
End... person( 1 )
End of sub_person1( 2 )
End of sub_person2( 2 )
End... person( 2 )
end of ... main()
とまあこんな感じで、sub_person1 → sub_person2 → person という順番でgoroutineが終了していることが確認できました。
先程、情報開示請求先の、総務省の担当者の方から、『本日中に資料を送付して頂ける』旨の電話連絡を頂きました。
総務省の方からお電話頂き、調べ方について丁寧に御説明頂きました。まずは手順を忘れない内にメモを残しておきます。(政治資金収支報告書のオンライン提出を怠っている政治団体を全部開示する件 続報)
I received a phone call from the person in charge at the Ministry of Internal Affairs and Communications, to whom I made a request for information disclosure, stating that they would be able to send me the documents today.
そもそも、存在していなかった資料をわざわざ作って頂いているので、時間がかかるのは覚悟しているたのですが ――
I was prepared for it to take a long time, since they had to create a document that didn't exist in the first place, however...
それにしても、丁寧なフォローをして頂いて、恐縮してしまいます。
Nevertheless, I'm very grateful for their careful follow-up.
-----
親切が嬉しい反面、ちょっと心配になってきました。
While I'm glad for their kindness, I'm getting a little worried.
この対応の理由には、3つのケースが考えられると思うからです。
The reason for this response is that I think there are three possible cases.
(1)基本的に総務省の担当者の方が親切
(1) Basically, the person in charge at the Ministry of Internal Affairs and Communications is kind.
(2)情報開示請求をしてくるような民間人はやっかな奴が多い → その対応のノウハウがある
(2) Many private citizens who request disclosure of information are difficult, so they have the know-how to deal with them.
(3)こんなコラムを書いているような奴(江端)を怒らせると面倒
(3) A guy who writes a column like this (Ebata) can be a pain in the ass if they piss him off.
上記の(1)だといいけど、(3)だとちょっと悲しいなぁ、と思っています。
I hope it's (1) above, but if it's (3), I'm a little sad.
-----
あ、第4のケースもありそうです。
Oh, there may be the fourth case.
(4)「政治資金収支報告書のオンライン提出を怠っている政治団体」を、江端から思いっきりDisって欲しい
(4) They want Ebata to disrespect "political organizations that fail to submit their political fund balance reports online" with all his might.
うん、これありそうだな。
Yeah, that's a possibility.
『政府としては、政治団体に恥をかかせるのはマズいけど、民間人のライター(江端)がやってくれるなら、それに越したことはない』
"It's not good for the government to embarrass a political group, but if a civilian writer (Ebata) can do it, so much the better"
と。
これなら、政府と私が、Win-Winです。
This is a win-win situation for the government and me.
-----
まあ、こんな感じで、『アナログ かつ アナクロ な政治団体を見張っていくのは、私のようなシニアの義務だろう』てなことを思っています。
In this way, I think it is the duty of senior citizens like me to keep an eye on analog and analogous political organizations.
package main
// C:\Users\ebata\goga\3-12
import (
"fmt"
"sync"
"time"
)
type BUS struct {
number int
}
//var l sync.Mutex
//var c1 chan int
func (bus *BUS) bus_func_recv(lr *sync.Mutex, cr *sync.Cond) {
// 受信(ブロードキャスト専用)
fmt.Println("bus.number by recv:", bus.number)
lr.Lock()
defer lr.Unlock()
fmt.Println("before cr.Wait")
for {
cr.Wait() // ロック
fmt.Println("hi ") // ここで受信処理を行う
}
}
func (bus *BUS) bus_func_send(lb *sync.Mutex, ch1 chan int) {
// 送信専用
fmt.Println("bus.number by send:", bus.number)
lb.Lock()
defer lb.Unlock()
ch1 <- bus.number
}
func main() {
//wg := sync.WaitGroup{}
l := sync.Mutex{}
c1 := make(chan int)
l2 := sync.Mutex{}
c2 := sync.NewCond(&l2)
for i := 0; i < 10; i++ {
bus := BUS{i}
go bus.bus_func_send(&l, c1)
go bus.bus_func_recv(&l2, c2)
}
time.Sleep(time.Second)
c2.Broadcast()
for {
select {
case v := <-c1:
fmt.Println(v)
//default:
// fmt.Println("default")
case <-time.After(3 * time.Second):
return
}
}
close(c1)
//wg.Wait()
//time.Sleep(3 * time.Second)
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
type PERSON struct {
lon_destination float64
lat_destination float64
lon_arrival float64
lat_arrival float64
bus BUS
}
type BUS struct {
lon_present float64
lat_present float64
// person []PERSON
}
func random(min, max float64) float64 {
rand.Seed(time.Now().UnixNano())
return rand.Float64()*(max-min) + min
}
func person(i int, wg *sync.WaitGroup) {
defer wg.Done()
person := PERSON{}
// 出発座標、到着座標の入力
person.lon_destination = random(139.480, 139.460)
person.lat_destination = random(35.602, 35.586)
person.lon_arrival = random(139.480, 139.460)
person.lat_arrival = random(35.602, 35.586)
fmt.Println(person, i)
}
func bus(i int, wg *sync.WaitGroup) {
defer wg.Done()
bus := BUS{}
fmt.Println(bus, i)
}
func main() {
var wg sync.WaitGroup
defer wg.Wait()
// バスエージェントの生成 3台
for i := 0; i < 3; i++ {
wg.Add(1)
go bus(i, &wg)
}
i := 0
for {
time.Sleep(3 * time.Second)
wg.Add(1)
i++
go person(i, &wg)
}
}
package main
// C:\Users\ebata\goga\3-15
import (
"fmt"
"sync"
"time"
)
// BroadCasterは管制システムのイメージに近い だから移動体のオブジェクトには含めない
type BroadCaster struct {
cond *sync.Cond
id int64
msg string
}
func (bc *BroadCaster) Send(msg string) {
bc.cond.L.Lock()
defer bc.cond.L.Unlock()
bc.id++
bc.msg = msg
bc.cond.Broadcast()
}
func (bc *BroadCaster) Recv(last int64) (int64, string) {
bc.cond.L.Lock()
defer bc.cond.L.Unlock()
for bc.id == last {
bc.cond.Wait()
}
return bc.id, bc.msg
}
// broadcaster_busをグローバルで実体化
var (
broadcaster_bus = &BroadCaster{
cond: sync.NewCond(&sync.Mutex{}),
}
)
// broadcaster_personをグローバルで実体化
var (
broadcaster_person = &BroadCaster{
cond: sync.NewCond(&sync.Mutex{}),
}
)
// 単一通信の構造体
type SingleCaster struct {
ch chan int // 単一通信路
lock sync.Mutex // 単一通信路のロック
}
// バス用単一通信の実体化
var (
sc_bus = &SingleCaster{
lock: sync.Mutex{},
ch: make(chan int),
}
)
// 人間用単一通信の実体化
var (
sc_person = &SingleCaster{
lock: sync.Mutex{},
ch: make(chan int),
}
)
// 人間用単一通信の実体化
type CONTROL struct {
number int // 管制番号
}
func (control *CONTROL) control_start() {
// バスへの一斉送信
for i := 0; i < 2; i++ {
time.Sleep(1 * time.Second)
broadcaster_bus.Send(fmt.Sprintf("hello, bus world %d", i))
}
// 人間への一斉送信
for i := 0; i < 2; i++ {
time.Sleep(1 * time.Second)
broadcaster_person.Send(fmt.Sprintf("hello, person world %d", i))
}
for {
select {
// case v := <-c1:
case v_b := <-sc_bus.ch:
fmt.Println("catched from bus send", v_b)
case v_p := <-sc_person.ch:
fmt.Println("catched from person send", v_p)
//default:
// fmt.Println("default")
case <-time.After(3 * time.Second):
return
}
}
}
type BUS struct {
number int // バス車両番号
}
func (bus *BUS) bus_func_recv() {
last := int64(0)
for {
id, msg := broadcaster_bus.Recv(last)
last = id
fmt.Println("broadcaset recv:", bus.number, msg)
}
}
func (bus *BUS) bus_func_send() {
// 送信専用
fmt.Println("bus.number by send:", bus.number)
sc_bus.lock.Lock()
defer sc_bus.lock.Unlock()
sc_bus.ch <- bus.number
}
type PERSON struct {
number int // 人間番号
live bool // 存在フラグ 存在:true 消滅:false
}
func (person *PERSON) person_func_recv() {
last := int64(0)
for {
if person.live {
return
}
id, msg := broadcaster_person.Recv(last)
last = id
fmt.Println("broadcaset recv:", person.number, msg)
}
}
func (person *PERSON) person_func_send() {
// 送信専用
fmt.Println("person.number by send:", person.number)
for {
sc_person.lock.Lock()
sc_person.ch <- person.number
sc_person.lock.Unlock()
time.Sleep(time.Second)
}
}
func main() {
// バス3台
for i := 0; i < 3; i++ {
bus := BUS{i}
go bus.bus_func_send()
go bus.bus_func_recv()
}
// 人間10人
for i := 0; i < 10; i++ {
person := PERSON{i, true}
go person.person_func_send()
go person.person_func_recv()
}
time.Sleep(time.Second)
control := CONTROL{}
go control.control_start()
//close(c1)
//wg.Wait()
time.Sleep(10 * time.Second)
}
package main
// C:\Users\ebata\goga\3-17
import (
"fmt"
"sync"
"time"
)
// BroadCasterは管制システムのイメージに近い だから移動体のオブジェクトには含めない
type BroadCaster struct {
cond *sync.Cond
id int64
msg string
}
func (bc *BroadCaster) Send(msg string) {
bc.cond.L.Lock()
defer bc.cond.L.Unlock()
bc.id++
bc.msg = msg
bc.cond.Broadcast()
}
func (bc *BroadCaster) Recv(last int64) (int64, string) {
bc.cond.L.Lock()
defer bc.cond.L.Unlock()
for bc.id == last {
bc.cond.Wait()
}
return bc.id, bc.msg
}
// broadcaster_busをグローバルで実体化
var (
broadcaster_bus = &BroadCaster{
cond: sync.NewCond(&sync.Mutex{}),
}
)
// broadcaster_personをグローバルで実体化
var (
broadcaster_person = &BroadCaster{
cond: sync.NewCond(&sync.Mutex{}),
}
)
// 単一通信の構造体
type SingleCaster struct {
ch chan int // 単一通信路
lock sync.Mutex // 単一通信路のロック
}
// バス用単一通信の実体化
var (
sc_bus = &SingleCaster{
lock: sync.Mutex{},
ch: make(chan int),
}
)
// 人間用単一通信の実体化
var (
sc_person = &SingleCaster{
lock: sync.Mutex{},
ch: make(chan int),
}
)
// 人間用単一通信の実体化
type CONTROL struct {
number int // 管制番号
}
func control_init(wg *sync.WaitGroup) {
defer wg.Done()
// バスへの一斉送信
for i := 0; i < 2; i++ {
time.Sleep(1 * time.Second)
broadcaster_bus.Send(fmt.Sprintf("hello, bus world %d", i))
}
// 人間への一斉送信
for i := 0; i < 2; i++ {
time.Sleep(1 * time.Second)
broadcaster_person.Send(fmt.Sprintf("hello, person world %d", i))
}
for {
select {
// case v := <-c1:
case v_b := <-sc_bus.ch:
fmt.Println("catched from bus send", v_b)
case v_p := <-sc_person.ch:
fmt.Println("catched from person send", v_p)
//default:
// fmt.Println("default")
case <-time.After(3 * time.Second):
return
}
}
}
type BUS struct {
number int // バス車両番号
person_list []*PERSON // バスに乗っている人
}
func (bus *BUS) bus_func_recv() {
last := int64(0)
for {
id, msg := broadcaster_bus.Recv(last)
last = id
fmt.Println("broadcaset recv:", bus.number, msg)
}
}
func (bus *BUS) bus_func_send() {
// 送信専用
fmt.Println("bus.number by send:", bus.number)
sc_bus.lock.Lock()
defer sc_bus.lock.Unlock()
sc_bus.ch <- bus.number
}
func (bus *BUS) add_person_list(person *PERSON) {
bus.person_list = append(bus.person_list, person)
}
func (bus *BUS) del_person_list(number int) {
for cnt := range bus.person_list {
if number == bus.person_list[cnt].number {
bus.person_list = append(bus.person_list[:number], bus.person_list[number+1:]...)
return
}
}
}
type PERSON struct {
number int // 人間番号
live bool // 存在フラグ 存在:true 消滅:false
}
func (person *PERSON) person_func_recv() {
last := int64(0)
for {
if person.live {
return
}
id, msg := broadcaster_person.Recv(last)
last = id
fmt.Println("broadcaset recv:", person.number, msg)
}
}
func (person *PERSON) person_func_send() {
// 送信専用
fmt.Println("person.number by send:", person.number)
for {
sc_person.lock.Lock()
sc_person.ch <- person.number
sc_person.lock.Unlock()
time.Sleep(time.Second)
}
}
func bus_init(wg *sync.WaitGroup, i int) {
defer wg.Done()
bus := BUS{number: i}
go bus.bus_func_send()
go bus.bus_func_recv()
}
func person_init(wg *sync.WaitGroup, i int) {
defer wg.Done()
person := PERSON{number: i}
go person.person_func_send()
go person.person_func_recv()
}
func main() {
wg := sync.WaitGroup{}
// バス3台
for i := 0; i < 3; i++ {
wg.Add(1)
go bus_init(&wg, i)
}
// 人間10人
for i := 0; i < 10; i++ {
wg.Add(1)
go person_init(&wg, i)
}
time.Sleep(time.Second)
// 管制センタ 1つ
wg.Add(1)
go control_init(&wg)
//close(c1)
//wg.Wait() //本来はこれだが、強制終了の為に
time.Sleep(10 * time.Second)
}
―― なんか、ちょっと怖い
wg.Add(): wg.Add(n)でn個の並行処理が存在することを伝え
wg.Done(): wg.Done()で終了を伝える
wg.Wait():wg.Wait()で並行処理が終わるまで(wg.Done()で終了を伝えるまで)処理をやめない