2020/09,江端さんの技術メモ

以下、https://github.com/SINTEF-9012/PruneCluster の簡単な翻訳

PruneCluster is a fast and realtime marker clustering library.
PruneClusterは、高速でリアルタイムなマーカークラスタリングライブラリです。

Example 1: 150 000 randomly moving markers.
例1:150,000個のマーカーをランダムに移動させる。

 Example 2: Realtime clusters of tweets.
例2. リアルタイムでツイートのクラスターを作成します。

It's working with Leaflet as an alternative to Leaflet.markercluster.
Leaflet.markerclusterの代替としてLeafletと連携しています。

The library is designed for large datasets or live situations. The memory consumption is kept low and the library is fast on mobile devices, thanks to a new algorithm inspired by collision detection in physical engines.
このライブラリは、大規模なデータセットやライブの状況を想定して設計されています。物理エンジンの衝突検出にヒントを得た新しいアルゴリズムを採用しているため、メモリ消費量は低く抑えられており、ライブラリはモバイルデバイス上で高速に動作します。

Features
特徴

Realtime
リアルタイム

The clusters can be updated in realtime. It's perfect for live datasets or datasets you want to filter at runtime.
クラスターをリアルタイムで更新することができます。ライブデータセットや、実行時にフィルタリングしたいデータセットに最適です。

Fast
高速化

Number of markers
マーカーの数
First step
最初のステップ
Update (low zoom level)
更新(低倍率)
Update (high zoom level)
更新(高倍率)
100instantinstantinstant
1 000instantinstantinstant
10 00014ms3ms2ms
60 00070ms23ms9ms
150 000220ms60ms20ms
1 000 0001.9s400ms135ms

These values are tested with random positions, on a recent laptop, using Chrome 38. One half of markers is moving randomly and the other half is static. It is also fast enough for mobile devices.
これらの値は、最近のノートパソコンで、Chrome 38を使用して、ランダムな位置でテストされています。マーカーの半分はランダムに動き、残りの半分は静止しています。モバイル端末でも十分に高速です。

If you prefer real world data, the 50k Leaflet.markercluster example is computed in 60ms (original).
実世界のデータをお望みなら、50k Leaflet.markercluster の例は 60ms (オリジナル) で計算されています。

Weight
ウエイト

You can specify the weight of each marker.
各マーカーのウエイトを指定することができます。

For example, you may want to add more importance to a marker representing an incident, than a marker representing a tweet.
例えば、ツイートを表すマーカーよりも、事件を表すマーカーの方がウエイトが高い場合があります。

Categories
カテゴリ

You can specify a category for the markers. Then a small object representing the number of markers for each category is attached to the clusters. This way, you can create cluster icons adapted to their content.
マーカーのカテゴリを指定することができます。そして、各カテゴリのマーカーの数を表す小さなオブジェクトがクラスタに添付されます。このようにして、その内容に合わせたクラスタアイコンを作成することができます。

Dynamic cluster size
動的なクラスタサイズ

The size of a cluster can be adjusted on the fly (Example)
クラスターの大きさをその場で調整可能(例)

Filtering
フィルタリング

The markers can be filtered easily with no performance cost.
性能コストをかけずに、簡単にマーカーをろ過することができます。

Usage
使用方法

Classic Way
古典的な方法

	<!-- In <head> -->
	<link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css"
  integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ=="
  crossorigin=""/>

	<!-- In <head> or before </body> -->
	<script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"
  integrity="sha512-lInM/apFSqyy1o6s89K4iQUKg6ppXEgsVxT35HbzUupEVRh2Eu9Wdl4tHj7dZO0s1uvplcYGmt3498TtHq+log=="
  crossorigin=""></script>
	<script src="PruneCluster/dist/PruneCluster.js"></script>

Webpack & NPM

npm install exports-loader prunecluster

import { PruneCluster, PruneClusterForLeaflet } from 'exports-loader?PruneCluster,PruneClusterForLeaflet!prunecluster/dist/PruneCluster.js'

Example

var pruneCluster = new PruneClusterForLeaflet();

...
var marker = new PruneCluster.Marker(59.8717, 11.1909);
pruneCluster.RegisterMarker(marker);
...

leafletMap.addLayer(pruneCluster);

PruneClusterForLeaflet constructor

PruneClusterForLeaflet([size](#set-the-clustering-size), margin);

You can specify the size and margin which affect when your clusters and markers will be merged.
クラスターとマーカーがマージされるときに影響するサイズとマージンを指定できます。

size defaults to 120 and margin to 20.
サイズはデフォルトで120、マージンは20に設定されています。

Update a position
ポジションの更新

marker.Move(lat, lng);

Deletions
削除

// Remove all the markers
pruneCluster.RemoveMarkers();

// Remove a list of markers
pruneCluster.RemoveMarkers([markerA,markerB,...]);

Set the category
カテゴリを設定する

The category can be a number or a string, but in order to minimize the performance cost, it is recommended to use numbers between 0 and 7.
カテゴリは数字でも文字列でも構いませんが、パフォーマンスコストを最小限に抑えるために、0~7の間の数字を使用することをお勧めします。

marker.category = 5;

Set the weight
ウエイトを設定する

marker.weight = 4;

Filtering
フィルタリング

marker.filtered = true|false;

Set the clustering size
クラスタリングサイズを設定する

You can specify a number indicating the area of the cluster. Higher number means more markers "merged". (Example)
クラスタの領域を示す数値を指定することができます。数値が大きいほど、より多くのマーカーが "マージ "されていることを意味します。(例)

pruneCluster.Cluster.Size = 87;

Apply the changes
変更を適用する

Must be called when ANY changes are made.
変更が行われたときに呼び出されなければなりません。

pruneCluster.ProcessView();

Add custom data to marker object
マーカーオブジェクトにカスタムデータを追加

Each marker has a data object where you can specify your data.
各マーカーには、データを指定できるデータオブジェクトがあります。

marker.data.name = 'Roger';
marker.data.ID = '76ez';

Setting up a Leaflet icon or a Leaflet popup
リーフレットアイコンやリーフレットのポップアップを設定する

You can attach to the markers an icon object and a popup content
マーカーにはアイコンオブジェクトとポップアップコンテンツを添付することができます。

marker.data.icon = L.icon(...);  // See http://leafletjs.com/reference.html#icon
marker.data.popup = 'Popup content';

Faster leaflet icons
より高速なリーフレットアイコン

If you have a lot of markers, you can create the icons and popups on the fly in order to improve their performance.
マーカーが多い場合は、その場でアイコンやポップアップを作成しておくとパフォーマンスが向上します。

function createIcon(data, category) {
    return L.icon(...);
}

...

marker.data.icon = createIcon;

You can also override the PreapareLeafletMarker method. You can apply listeners to the markers here.
PreapareLeafletMarkerメソッドをオーバーライドすることもできます。ここではマーカーにリスナーを適用することができます。

pruneCluster.PrepareLeafletMarker = function(leafletMarker, data) {
    leafletMarker.setIcon(/*... */); // See http://leafletjs.com/reference.html#icon
    //listeners can be applied to markers in this function
    leafletMarker.on('click', function(){
    //do click event logic here
    });
    // A popup can already be attached to the marker
    // bindPopup can override it, but it's faster to update the content instead
    if (leafletMarker.getPopup()) {
        leafletMarker.setPopupContent(data.name);
    } else {
        leafletMarker.bindPopup(data.name);
    }
};

Setting up a custom cluster icon
カスタム クラスター アイコンの設定

pruneCluster.BuildLeafletClusterIcon = function(cluster) {
    var population = cluster.population, // the number of markers inside the cluster
        stats = cluster.stats; // if you have categories on your markers

    // If you want list of markers inside the cluster
    // (you must enable the option using PruneCluster.Cluster.ENABLE_MARKERS_LIST = true)
    var markers = cluster.GetClusterMarkers() 
        
    ...
    
    return icon; // L.Icon object (See http://leafletjs.com/reference.html#icon);
};

Listening to events on a cluster
クラスタ上のイベントを聞く

To listen to events on the cluster, you will need to override the BuildLeafletCluster method. A click event is already specified on m, but you can add other events like mouseover, mouseout, etc. Any events that a Leaflet marker supports, the cluster also supports, since it is just a modified marker. A full list of events can be found here.
クラスタ上のイベントをリッスンするには、BuildLeafletClusterメソッドをオーバーライドする必要があります。クリックイベントはすでに m で指定されていますが、マウスオーバーやマウスアウトなどの他のイベントを追加することができます。リーフレットマーカーがサポートしているイベントはすべて、クラスタもサポートしています。イベントの完全なリストはこちらを参照してください。

Below is an example of how to implement mouseover and mousedown for the cluster, but any events can be used in place of those.
以下にクラスタのマウスオーバーとマウスダウンの実装例を示しますが、これらの代わりに任意のイベントを使用することができます。

pruneCluster.BuildLeafletCluster = function(cluster, position) {
      var m = new L.Marker(position, {
        icon: pruneCluster.BuildLeafletClusterIcon(cluster)
      });

      m.on('click', function() {
        // Compute the  cluster bounds (it's slow : O(n))
        var markersArea = pruneCluster.Cluster.FindMarkersInArea(cluster.bounds);
        var b = pruneCluster.Cluster.ComputeBounds(markersArea);

        if (b) {
          var bounds = new L.LatLngBounds(
            new L.LatLng(b.minLat, b.maxLng),
            new L.LatLng(b.maxLat, b.minLng));

          var zoomLevelBefore = pruneCluster._map.getZoom();
          var zoomLevelAfter = pruneCluster._map.getBoundsZoom(bounds, false, new L.Point(20, 20, null));

          // If the zoom level doesn't change
          if (zoomLevelAfter === zoomLevelBefore) {
            // Send an event for the LeafletSpiderfier
            pruneCluster._map.fire('overlappingmarkers', {
              cluster: pruneCluster,
              markers: markersArea,
              center: m.getLatLng(),
              marker: m
            });

            pruneCluster._map.setView(position, zoomLevelAfter);
          }
          else {
            pruneCluster._map.fitBounds(bounds);
          }
        }
      });
      m.on('mouseover', function() {
        //do mouseover stuff here
      });
      m.on('mouseout', function() {
        //do mouseout stuff here
      });

      return m;
    };
};

Redraw the icons
アイコンを再描画

Marker icon redrawing with a flag:
マーカーアイコンを旗で再描画。

marker.data.forceIconRedraw = true;

...

pruneCluster.ProcessView();

Redraw all the icons:

pruneCluster.RedrawIcons();

Acknowledgements
謝辞

This library was developed in context of the BRIDGE project. It is now supported by the community and we thank the contributors.
このライブラリはBRIDGEプロジェクトの文脈で開発されました。現在はコミュニティによってサポートされており、貢献者に感謝しています。

Licence
ライセンス

The source code of this library is licensed under the MIT License.
このライブラリのソースコードはMITライセンスの下でライセンスされています。

インストール方法

C:\Users\ebata>git clone https://github.com/SINTEF-9012/PruneCluster.git
Cloning into 'PruneCluster'…
remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 1054 (delta 3), reused 2 (delta 1), pack-reused 1044
Receiving objects: 100% (1054/1054), 68.39 MiB | 9.96 MiB/s, done.
Resolving deltas: 100% (699/699), done.
Updating files: 100% (54/54), done.

C:\Users\ebata>cd PruneCluster

ここで初めてドキュメントに目を通す。

PruneClusterは、高速でリアルタイムなマーカークラスタリングライブラリです。

Leaflet.markerclusterの代替としてLeafletと連携しています。

このライブラリは、大規模なデータセットやライブ状況向けに設計されています。物理エンジンの衝突検出に着想を得た新しいアルゴリズムのおかげで、メモリ消費量は低く抑えられ、ライブラリはモバイルデバイス上で高速に動作します。
クラスターをリアルタイムで更新することができます。ライブデータセットや、実行時にフィルタリングしたいデータセットに最適です。
各マーカーの重みを指定できます
たとえば、ツイートを表すマーカーよりも、事件を表すマーカーの方が重要度が高い場合があります。
マーカーのカテゴリを指定することができます。そして、各カテゴリのマーカーの数を表す小さなオブジェクトがクラスタに添付されます。このようにして、その内容に合わせたクラスタアイコンを作成することができます。

C:\Users\ebata\PruneCluster\examples>の中にあるサンプルのhtmlの中の座標をいじるだけで、こんなことができました。

https://kobore.net/soft/PruneCluster/examples/toyosu.100.html

このクラスタを無くすには、例えば

var leafletView = new PruneClusterForLeaflet(1,1);  // (120,20)がデフォルト

とかすればいいみたい。

その上で、オブジェクトを1000個に増やしたものが以下になります。

https://kobore.net/soft/PruneCluster/examples/toyosu2.1000.html

以上

2020/09,江端さんの忘備録

今日、部長の許可を得て、久々に社外出張をしております。

Today, with the permission of the general manager, I made a business trip outside the company for a long time.

『一度は、ホワイトボードを使った、技術打ち合わせをしたい』という先方のご要求に因るものですが、私も同意できました。

Due to the partner company's request, "I'd like to have a technical meeting at least once, using a whiteboard," I agreed with them.

リモート会議のツール(アプリ等)は、日々精錬され続けており、そして、私たちもリモート会議に慣れつつあります。

Remote conferencing tools (e.g. apps) are being refined every day, and we are getting used to them.

良いことだと思います。

I think it's a good thing.

-----

今回出張するに際して、改めて気がついたのですが、たった1時間の打ち合わせの為に、

When I went on this business trip, I realized once again. There was a lot to prepare for the meeting, which was only an hour long.

■ビジネスカジュアルに着替えて、

- get dressed in business casual.

■必要な資料をPCに入れて、さらにバックアップ用の印刷をして、

- put the necessary materials into the computer, print out some more backups, and

■電車の時間や天候を調べて

- check the train times and weather.

■熱中症対策の為、徒歩移動を止めてタクシーを使い、

- prevent heat stroke, and stop walking and take a taxi.

■直射日光の中で電車を待ち、

- wait for a train in the direct sun.

■電車の中では、マスクとソーシャルディスタンスを気にし続け、

- keep worrying about my mask and social distances on the train

■移動時間が往復3時間

- three-hour round trip.

ここまでで、トータル5時間以上。

So far, more than five hours in total.

これが、リモート会議であれば、準備時間は15分弱です。

If this is a remote meeting, the preparation time is less than 15 minutes.

-----

以前にも申し上げましたが、現時点で、全ての人間や事象について適用可能な「生産性の定義」は存在していません。

As I've said before, there is no "definition of productivity" available for all people and events at this time.

例えば、この5時間の時間には、移動に必要となった、タクシーや鉄道会社の利益も含まれるからです。

For example, this five hours includes the profits of the taxi and train companies.

ただ、この5時間が、「私の利益になっているか?」と言えば、明らかに"No"と言えます。

Have the last five hours benefited me? If you ask me, the answer is clearly "No."

私の仕事は、ドキュメントの作成ができて、プログラム開発ができる環境があれば十分であり、

In my work, it's enough to have an environment where I can create documentation and develop programs.

―― 現時点で、もっとも整備された仕事の環境は、私の部屋

"at the moment, the most organized work environment is my room"

です。

ただ、この夏、コンピュータとエアコンをブンブン回していますので、江端家の電気代は凄いことになっていそうです。

However, we've been using the computer and air conditioner a lot this summer, so the Ebata family's electricity bill is going to be amazing.

(続く)

(To be continued)

2020/09,江端さんの忘備録

国家間の戦争が、経済を大きく回す ―― そんなことは、今時、子どもだって知っています。

"War between nations turns the economy around in a big way" -- even children know that nowadays.

私なんて、アニメで再履修したくらいです。

I even took a refresher course in the anime.

「まおゆう魔王勇者」っていうんですけど、最近のアニメは原作者の方が本当によく勉強されていて、大変助かります。

It's called "Mao Yu Maou Brave". In recent anime, the original author studies really well, so their works help me.

このアニメが教えてくれることは、戦争経済は、開始とその最中は調子が良くても、それを無策に停止させる(和平に導く)と、国家を壊滅させかねない恐しい不況が発生するということです。

What this anime tells us, is the fact is that the war economy is in good shape at the beginning and during it, but if it is stopped without any measures (leading to peace), there will be a terrible recession that can destroy the nation.

例えば、日本史の中にあっても、その事例は簡単に見つけられます。

For example, even in Japanese history, you can easily find the case.

例えば ―― 天下平定後の豊臣秀吉が、不可思議とも思える侵略戦争「文禄・慶長の役」を試みたのは、戦場がなくなった日本国における、戦闘員(武士)による、大量失業対策であった ―― ということは周知の事実です。

For example-- that is a well-known fact. The reason why Toyotomi Hideyoshi attempted the mysterious war of invasion, "The War of 1592", after the pacification of the country, was as a countermeasure against mass unemployment for the combatants (samurai) in Japan, which had lost its battlefield.

-----

あまりにも自明であるけど、不謹慎だから口にしない。

It's too obvious, but I'm not going to talk about it because it's immodest.

その筆頭が、「国家間の戦争が経済を大きく回す」というフレーズです。

The first of these is the phrase "War between nations turns the economy around in a big way".

-----

アニメで教えてくれる程度のことを、またどこぞの誰かが口にして、問題になっているようです。

It seems that there is a problem when somebody talks about the things that are taught in the anime.

しかも、今回は「コロナ禍」という言葉を使ったことで、世間の"不快"を買ってしまったようです。

Moreover, he seems to have caused public "discomfort" by using the term "corona disaster" this time.

『いい大人が、そんな「中二病」発言なんかして、みっともないことだな』 ―― と、ニュースを見ていたら、どこぞの市の教育長でした。

It's disgraceful for a grown man to make such a 'junior high' comment. I was watching the news and I knew he was the superintendent of education in some city.

「なるほど」と、なんとなく納得してしまいました。

"I see". I was somewhat convinced.

-----

私、この教育長なる人を擁護する気は1mmもないのですが、

I'm not trying to defend this school superintendent at all, however,

個人的には、

personally.

2015年の夏、鹿児島県の県知事が『女子高生は、三角関数より花や草の名前を教えた方がいい』と発言して大問題に発展しました

In the summer of 2015, the governor of Kagoshima Prefecture got into big trouble when he said, 'High school girls should be taught the names of flowers and grasses rather than trigonometric functions'.

の方が、怒りとしては大きいです。

I am furious with this phrase.

で、今後、同じような事件(舌禍事件)が発生する度に、このページを引用して、世間から忘れされることがないよう、努めるつもりです。

And every time a similar incident (tongue-in-cheek incident) occurs in the future, I will try to cite this page so that it will not be forgotten by the public.

-----

どうせ"舌禍"かますなら、言い訳の余地もないほど、徹底的に、激烈にやるべきです。

If you're going to create a "tongue-in-cheek" problem, you should do it so thoroughly and violently that there's no excuse for it.

例えば、

For example,

頭のイカれた教祖と、それを信奉する無知性な信者からなるカルトな宗教団体

A cult-like religious group made up of a crazy guru and the ignorant followers who follow him.

くらいの、悪意と憎悪を込めたフレーズをかますべきです。

You should use phrases with this level of malice and hatred.

2020/09,2020/09,江端さんの忘備録

私は、自分の娘たちに、若いころの恋愛話を―― 客観的に、他人事のように ―― ペラペラとしゃべっています。

I talk to my daughters about my youthful romance objectively, like other's love affairs.

それを受けてか、我が家の娘たちも、現在進行形の話を、私に話します(当然、開示内容には制限はかかっているでしょうが)

After that, my daughters also tell me the ongoing story (although the disclosure may be limited, of course).

-----

最近、娘にウケたネタとしては、

Recently, as a fummy story that my daughter got

―― 運命の赤い糸は、自分を中心として1024本ほど同時に繋っていて、そのいずれも確定状態にはない

"The 1024 red threads of destiny are connected at the same time, centering on you, and none of them are in a confirmed state"

という、最近の私の『量子論』の勉強に基づく、いわゆる「量子恋愛論」でした。

That was the so-called "quantum love theory" based on my recent study of "quantum theory".

-----

その話を聞いた娘は、大爆笑していました。

After hearing the story, she was laughing loudly.

彼女に何があったのかは知りませんが、『まあ、がんばれ』とだけ、言っておきました。

Though I don't know what happened to her, I told my daughter, "Well, do your best."

2020/08,江端さんの忘備録

本日は、コラムがリリースされた日なので、日記はお休みです。

Today, new my column is released, so I take a day off.

踊るバズワード ~Behind the Buzzword(5)量子コンピュータ(5):

量子もつれ ~アインシュタインも「不気味」と言い放った怪現象

Dancing Buzzword-Behind the Buzzword (5) Quantum Computer (5)

Quantum entanglement - the phenomenon that even Einstein called "uncanny"

-----

『量子の振舞いの不気味さに比べたら、幽霊とかお化けなどの怪談の怖さなんぞ、お話になりません(本当)』

Compared to the creepiness of quantum behavior, there's nothing in the horror of ghosts and the stories (really).

については、今回全部書いてしまったので ―― もう、このネタついては、もうこれ以上記載することがありません。

ただ気になっているのは、今回の「量子もつれ」の調査で、私のように、「分からん!」「不可解!」とか叫んでいる文献とか論文とかを、まったく見つけられなかったことです。

There are just things I'm curious about. In this "Quantum Tangle" survey, I couldn't find any literature or papers that shouted "I don't know!" "Mysterious!" like my column.

さらっと、『このような現象を"量子もつれ"という』というフレーズがあっただけで、そこには、この現象に対する本質的なリアクション

After all, there was only the phrase "a phenomenon like this is called "entanglement"", and there is no essential reaction to this phenomenon. It is an

―― 驚愕

"Astonishment"

が、ないのです。

学術論文の記載であっても、

Even the description of an academic paper,

『現時点で、この「量子もつれ」という「量子の非局所性」は、観測をベースとする古典力学の観点からは『非常識』としか思えないような物理現象である』

"At present, this "non-locality of quantum" called "quantum entanglement" is a physical phenomenon that can only be considered as "insane" from the viewpoint of classical mechanics based on observations."

の一文があっても良いと思うのです。

I wanted to read the above phrase.

論文や著書の執筆者は、自分が驚いたり、狼狽(うろた)えたりしていることを、「かっこ悪い」とでも思っているかのようです。

It's as if the authors of papers and books think it's "uncool" to be surprised or dismayed.

-----

私は、

I believe that

■科学という学問の本質は、「感情(驚愕や畏怖)」にあり、

"The essence of the science is "feelings (startle or awe)""

■工学という学問の本質は、「失敗と繰返し」にある

"The essence of engineering is "failure and repetition"

と信じています。

故に、私は自分の素直な感情をコラムで吐露(とろ)し、失敗した事例(プログラム等)をブログにアップロードして、世界に晒しています。

Therefore, I show my honest feelings in the column, upload the failed cases (programs, etc.) to the blog, and expose them to the world.

それらは、科学や工学の進歩に絶対的に必要なことだ、と確信しているからです。

I am convinced that they are absolutely necessary for the advancement of science and engineering.

-----

"ちんけ"な成功例(実験条件を限定した、都合の良い設定でのコンピュータシミュレーションなど)で、論文を量産する研究員やエンジニアなんぞより、

In a "cheap" success example (computer simulation in a convenient setting with limited experimental conditions, etc.), the researchers and engineers who mass-produce papers,

誤解に基づくコラムや、膨大な失敗例を、臆面もなく量産し公開し続けている私の方が、よっぽど「役に立っている」と思っています。

I think I'm much more "helpful" than them even if I keep mass-producin and publishing columns based on misconceptions and a lot of failures.

-----

もちろん、偉大な発見や発明をした人/する人の「役の立ち方」には、遠く及びませんが ――

Of course, it's not far from the "helpfulness" of the person who made/will make the great discoveries and inventions.

それでも、"ちんけ"な研究員&エンジニアには、"ちんけ"なりの人類への貢献方法があるんですよ。

However, "cheap" researchers and engineers have "cheap" ways to contribute to humanity.

"ちんけ"な奴が、もっとも偉大な発見や発明をする人の振舞いを「まね」したところで、何の役にも立ちはしません。

The "cheap" guy does nothing to imitate the behavior of the greatest discoverer or inventor.

-----

"ちんけ"な研究員&エンジニアは、『一生、見苦しく生きて行く』でいいんです ――

"Cheap" researchers and engineers are good at "living unsightly for the rest of their lives".

世界中の誰もが認めなくても、この私だけは、その生き方、認めます。

Even if no one in the world understand it, I can accept you.

2020/08,江端さんの忘備録

(昨日の続きです)

(Continuation from yesterday)

私たちは、高校数学で「虚数」やら「虚数空間(複素平面)」という考え方を学びます。

We learn the concept of "imaginary numbers" and "imaginary spaces (complex planes)" in high school mathematics.

「虚数」という名称を付けられてはいますが、虚数空間は、現実空間からは死角に入っている(直交している)だけで、ガッツリと存在している空間(直交空間)です。

Despite the name "imaginary", imaginary space is a space that exists in reality (orthogonal space), but is only in a dead angle (orthogonal) from real space.

リアル充実、いわゆる「リア充」という既存の価値観に対して、

As opposed to "Really fulfillment", so-called "RE-life"

「レンタル彼女/彼氏」は、直交空間における新しい価値観、

the "rent-a-girlfriend/boyfriend" is a new value in the orthogonal space,

―― イマージナリ充実、略して「イマ充」

"Imaginary fulfilling", or so-called "IM-life"

として認識されるべきでしょう。

We should recognize it.

もう一歩前進して考えてみれば、「愛」というものそのものが、「リア充」軸と「イマ充」軸からなる平面上での周期運動するベクトルのようなものです。

If you take it one step further, "love" itself is like a vector in cyclic motion on a plane consisting of a "RE-life" axis and an "IM-life" axis.

-----

「リア充」軸上で停滞しているベクトルの一例では、「バカップル」があります。

In an example of a vector that is stagnant on the "RE-life" axis, there are "love birds".

停滞しているベクトルには運動エネルギーがないので、当然のことながら、「バカップル」は、そのライフタイムは恐しく短いです。

Unsurprisingly, "love birds" have a frighteningly short life-time, since stagnant vectors have no kinetic energy.

逆に、「イマ充」軸上で停滞しているベクトルの一例が「レンタル彼女/彼氏」になるのでしょう。

On the other hand, in an example of a vector that is stagnant on the "IM-life" axis, it would be a "rent-a-girlfriend/boyfriend.

このベクトルも運動していませんので、エネルギー(現金)の供給が無くなった時点で消滅する、という点では同じです。

This vector is also not in motion, so it is the same in that it disappears when the supply of energy (cash) is no longer available.

逆に言えば、エネルギー(現金)の供給が続く限りは、存続できるのです。

Conversely, as long as the supply of energy (cash) continues, it can survive.

-----

『「愛」を維持する為のエネルギーが「愛自身」しかない』というのは狭量で短絡的な上、ズルい考え方です。

It is a narrow, short-sighted and unfair way of thinking to say that "the only energy available to maintain love is love itself".

私達は、「愛」の代替エネルギーとして、パートナーの

We use our partner's attributes as an alternative energy for "love", for example,

「理念」「教養」「趣味」「嗜好」、そして「愛想」「外観」「年齢」、更には「学歴」「地位」「収入」等

ideas, culture, hobbies, tastes, and preferences, appearance, age, and even education, status, income, etc.

を活用しています。

この事実を「公に」否定できる人は、一人もいないはずです。

Not a single person should be able to "publicly" deny this fact.

2020/08,江端さんの技術メモ

  • 概要
    • Webシステムを外部から利用するためのプログラムの呼び出し規約(API)
    • リソースの操作はHTTPメソッドによって指定(取得ならGETメソッド、書き込みならPOSTメソッド)される
    • 結果はXMLやHTML、JSONなどで返される
    • 処理結果はHTTPステータスコードで通知する
  • RESTの基本仕様
    • セッション管理を行わない
    • 情報を操作する命令の体系が予め定義(HTTPのGETやPOSTメソッドなどで)されている
    • 汎用的な構文で識別される(URLやURIなど)
    • 情報の内部に、別の情報を含めることができる
    • リソースに対してURLが対応づけられる
    • 「GET」なら取得、「POST」なら作成、「PUT」なら更新、「DELETE」なら削除のように処理する
  • ここから先は、Golangの開発プロセスになる
    • go get -u github.com/gorilla/mux を行う

golangでシンプルなRESTful APIを作ってみよう!を、そのまま書き下してトレースで動きを追ってみました。

今回から、emacs + gdb を断念して、Visual Studio Code を使ってみました。うん、死ぬほど便利。

//C:\Users\ebata\go_rest\restful\main.go
 
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strconv"

	"github.com/gorilla/mux"
)

// Item representation
type Item struct {
	Title       string `json:"title"`
	Description string `json:"description"`
}

// Global, static list of items
var itemList = []Item{
	Item{Title: "Item A", Description: "The first item"},
	Item{Title: "Item B", Description: "The second item"},
	Item{Title: "Item C", Description: "The third item"},
}

// Controller for the / route (home)
func homePage(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "This is the home page. Welcome!")
}

// Contoller for the /items route
func returnAllItems(w http.ResponseWriter, r *http.Request) {
	respondWithJson(w, http.StatusOK, itemList)
}

// Controller for the /items/{id} route
func returnSingleItem(w http.ResponseWriter, r *http.Request) {
	// Get query parameters using Mux
	vars := mux.Vars(r)

	// Convert {id} parameter from string to int
	key, err := strconv.Atoi(vars["id"])

	// If {id} parameter is not valid in
	if err != nil {
		respondWithError(w, http.StatusBadRequest, "Invalid reqest payload")
		return
	}

	// If item with ID of {id} does not exist
	if key >= len(itemList) {
		respondWithError(w, http.StatusNotFound, "Item does not exist")
		return
	}

	respondWithJson(w, http.StatusOK, itemList[key])
}

func respondWithError(w http.ResponseWriter, code int, msg string) {
	respondWithJson(w, code, map[string]string{"error": msg})
}

func respondWithJson(w http.ResponseWriter, code int, payload interface{}) {
	response, _ := json.Marshal(payload)
	w.Header().Set("Content-type", "application/json")
	w.WriteHeader(code)
	w.Write(response)
}

func handleRequests() {
	myRouter := mux.NewRouter().StrictSlash(true)
	myRouter.HandleFunc("/", homePage)
	myRouter.HandleFunc("/items", returnAllItems)
	myRouter.HandleFunc("/items/{id}", returnSingleItem)
	log.Fatal(http.ListenAndServe(":8000", myRouter))
}

func main() {
	handleRequests()
}

http://localhost:8000/ → ホームページ、テキスト("This is the home page. Welcome!")を見せる

http://localhost:8000/items → "[{"title":"Item A","description":"The first item"},{"title":"Item B","description":"The second item"},{"title":"Item C","description":"The third item"}]"

http://localhost:8000/items/1 → {"title":"Item B","description":"The second item"}

なるほど、こんな感じで使うのね。

ーーーーー

jsonの使い方についても、Go言語でJSONを扱う を写経させて頂いた。

vro.json

[
    {"id":1, "name":"akane","birthday":"08-16","vivid_info":{"color":"red","weapon":"Rang"}},
    {"id":2, "name":"aoi","birthday":"06-17","vivid_info":{"color":"blue","weapon":"Impact"}},
    {"id":3, "name":"wakaba","birthday":"05-22","vivid_info":{"color":"green","weapon":"Blade"}},
    {"id":4, "name":"himawari","birthday":"07-23","vivid_info":{"color":"yellow","weapon":"Collider"}}, 
    {"id":0, "name":"rei"}    
]

vro.go

package main

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

/** JSONデコード用の構造体定義 */

type Person struct {
	Id       int      `json:"id"`
	Name     string   `json:"name"`
	Birthday string   `json:"birthday"`
	Vivid    struct { // 構造体の中にネストさせて構造体を定義
		Color  string `json:color`
		Weapon string `json:weapon`
	} `json:"vivid_info"`
}

func main() {
	// JSONファイル読み込み
	bytes, err := ioutil.ReadFile("vro.json")
	if err != nil {
		log.Fatal(err)
	}
	// JSONデコード
	var persons []Person
	if err := json.Unmarshal(bytes, &persons); err != nil {
		log.Fatal(err)
	}
	// デコードしたデータを表示
	for _, p := range persons {
		fmt.Printf("%d : %s : (%s) [%s]\n", p.Id, p.Name, p.Vivid.Color, p.Birthday)
	}

	// JSONデコード
	var decode_data interface{}
	if err := json.Unmarshal(bytes, &decode_data); err != nil {
		log.Fatal(err)
	}
	// 表示
	for _, data := range decode_data.([]interface{}) {
		var d = data.(map[string]interface{})
		fmt.Printf("%d : %s\n", int(d["id"].(float64)), d["name"])
	}
}

2020/08,江端さんの忘備録

『フィクションにしても、ちょっと(私には)合わないなぁ』と思って、視聴してはいませんが、「恋人をレンタルする」というテーマのアニメがあるようです。

I thought "Even if it's fictional, it's not quite (for me)" about an anime about "renting a lover". so I haven't watched it.

しかし、そのコストや業務形態には興味がありました。

However, I was interested in the costs and business model.

でもって、ちょっと調べてみたら、出るわ出るわ、山程の「レンタル彼女」「レンタル彼氏」の紹介サイト。

But when I did some research, I found a lot of sites that introduce "rental girlfriends" and "rental boyfriends".

正直、ちょっと引いてしまう程でした。

That kind of site was a real turnoff.

-----

しかし、考えてみれば、「レンタル彼女/彼氏」は、普通にビジネスとして成立するはずで、別段、驚くことでもないはずです。

But thinking it again, "rental girlfriend/boyfriend" should be a normal business, and it shouldn't be a surprise to me.

接待を伴う飲食業の「店舗外バージョン」です。

This is the "out-of-store" version of the restaurant business with entertainment.

「デートできればそれで足る」というニーズに対して、Win-Winのリソース活用(金と時間の交換)とも言えます。

It can be seen as a win-win resource utilization (exchange of money and time) for the needs of "If I can date, it's good enough".

これは「デートのクラウド化」であり、ITの世界では当たり前の「リソースシェアリング」です。

This is the "cloud of dating" and "resource sharing" that is commonplace in the IT world.

その他のメリットを上げれば、(1)デートのフィールドトライアル、(2)本番デートの前のチェックリストやデバッグ、(3)孤食の回避、(4)服飾系のコンサルタント、等々。

Other benefits include (1) field trials for dates, (2) checklists and debugging before the real date, (3) avoidance of isolation, (4) clothing consultants, etc.

それ以外では、(A)結婚圧力の強い環境(肉親、地域、組織(会社))、(B)同性愛等の無理解な環境、あるいは(C)「一人ぼっちは体裁が悪い」と考えている人にとっては、一種の「擬態」としても有効なのかもしれません

Otherwise, it may be useful as a kind of "mimicry" for people who (a) are in an environment of strong marriage pressure (immediate family, community, organization (company)), (b) are in an environment where there is no understanding of homosexuality, etc., or (c) think that "being alone is bad for their appearance"

―― 知らんけど。

I don't know them well.

(続く)

(To be continued)

2020/08,江端さんの技術メモ

  1. まずは、MSYS2をメンテナンス(2年近く放置していたから)
$ pacman -Syu

を、ターミナルを何度も立ち直し続けてパッケージの更新を繰返す。

$ pacman -S base-devel
$ pacman -S msys2-devel
$ pacman -S mingw-w64-x86_64-toolchain
$ pacman -S mingw-w64-x86_64-gnutls
$ pacman -S mingw-w64-x86_64-ruby
$ pacman -S nano      #(簡易エディター)
$ pacman -S make      #(make をインストール ※重要※)
$ pacman -S openssh   #(openssh をインストール)
$ pacman -S git       #(Git をインストール)
$ pacman -S ruby      #(Ruby をインストール)
$ pacman -S ruby-docs #(Rubyドキュメント をインストール)
$ pacman -S p7zip     #(7z をインストール)
$ pacman -S mingw-w64-x86_64-ag  #(ag 高速検索コマンドをインストール)

2. パッケージのインストールとアンインストール

sudo pacman -S [パッケージ名]
sudo pacman -R [パッケージ名]

3. Windows10の環境をMSYS2に引きつぐ方法