https://www.ibm.com/quantum-computing/
Ibm_xxxxxxxxではログインできなかったので、googleのアカウントでログイン






うん、多分作れているんだろう。000」と「011」が約50%で発生している(上位ビットは無視して良い思う)から。1024回くらい繰返しているみたい。ただ、(当然だけど)量子の非局所化を確認する方法って、ないんだろうなぁ
江端智一のホームページ
https://www.ibm.com/quantum-computing/
Ibm_xxxxxxxxではログインできなかったので、googleのアカウントでログイン
うん、多分作れているんだろう。000」と「011」が約50%で発生している(上位ビットは無視して良い思う)から。1024回くらい繰返しているみたい。ただ、(当然だけど)量子の非局所化を確認する方法って、ないんだろうなぁ
■以下、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.
このライブラリは、大規模なデータセットやライブの状況を想定して設計されています。物理エンジンの衝突検出にヒントを得た新しいアルゴリズムを採用しているため、メモリ消費量は低く抑えられており、ライブラリはモバイルデバイス上で高速に動作します。
The clusters can be updated in realtime. It's perfect for live datasets or datasets you want to filter at runtime.
クラスターをリアルタイムで更新することができます。ライブデータセットや、実行時にフィルタリングしたいデータセットに最適です。
Number of markers マーカーの数 | First step 最初のステップ | Update (low zoom level) 更新(低倍率) | Update (high zoom level) 更新(高倍率) |
---|---|---|---|
100 | instant | instant | instant |
1 000 | instant | instant | instant |
10 000 | 14ms | 3ms | 2ms |
60 000 | 70ms | 23ms | 9ms |
150 000 | 220ms | 60ms | 20ms |
1 000 000 | 1.9s | 400ms | 135ms |
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 (オリジナル) で計算されています。
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.
例えば、ツイートを表すマーカーよりも、事件を表すマーカーの方がウエイトが高い場合があります。
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.
マーカーのカテゴリを指定することができます。そして、各カテゴリのマーカーの数を表す小さなオブジェクトがクラスタに添付されます。このようにして、その内容に合わせたクラスタアイコンを作成することができます。
The size of a cluster can be adjusted on the fly (Example)
クラスターの大きさをその場で調整可能(例)
The markers can be filtered easily with no performance cost.
性能コストをかけずに、簡単にマーカーをろ過することができます。
<!-- 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>
npm install exports-loader prunecluster
import { PruneCluster, PruneClusterForLeaflet } from 'exports-loader?PruneCluster,PruneClusterForLeaflet!prunecluster/dist/PruneCluster.js'
var pruneCluster = new PruneClusterForLeaflet(); ... var marker = new PruneCluster.Marker(59.8717, 11.1909); pruneCluster.RegisterMarker(marker); ... leafletMap.addLayer(pruneCluster);
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に設定されています。
marker.Move(lat, lng);
// Remove all the markers pruneCluster.RemoveMarkers(); // Remove a list of markers pruneCluster.RemoveMarkers([markerA,markerB,...]);
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;
marker.weight = 4;
marker.filtered = true|false;
You can specify a number indicating the area of the cluster. Higher number means more markers "merged". (Example)
クラスタの領域を示す数値を指定することができます。数値が大きいほど、より多くのマーカーが "マージ "されていることを意味します。(例)
pruneCluster.Cluster.Size = 87;
Must be called when ANY changes are made.
変更が行われたときに呼び出されなければなりません。
pruneCluster.ProcessView();
Each marker has a data object where you can specify your data.
各マーカーには、データを指定できるデータオブジェクトがあります。
marker.data.name = 'Roger'; marker.data.ID = '76ez';
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';
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); } };
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); };
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; }; };
Marker icon redrawing with a flag:
マーカーアイコンを旗で再描画。
marker.data.forceIconRedraw = true; ... pruneCluster.ProcessView();
Redraw all the icons:
pruneCluster.RedrawIcons();
This library was developed in context of the BRIDGE project. It is now supported by the community and we thank the contributors.
このライブラリはBRIDGEプロジェクトの文脈で開発されました。現在はコミュニティによってサポートされており、貢献者に感謝しています。
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
以上
私は、自分の娘たちに、若いころの恋愛話を―― 客観的に、他人事のように ―― ペラペラとしゃべっています。
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."
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"])
}
}
$ 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に引きつぐ方法
go func() { defer close(done) for { _, message, err := c.ReadMessage() if err != nil { log.Println("read:", err) return } log.Printf("recv: %s", message) } }() ticker := time.NewTicker(time.Second) defer ticker.Stop() for { select { case <-done: return case t := <-ticker.C: err := c.WriteMessage(websocket.TextMessage, []byte(t.String())) if err != nil {
go func()で、defer close(done)が効いてくるまで、 case <-done:はロックされて、デッドロックになるじゃないか? と、ずっと考えて訳が分からなくなってきたところで、Go言語でチャネルとselect というページに、
チャネルに値が入っていない場合、受信はブロックする。ブロックせずに処理を行いたい場合は select を使う。
そんなSwitchの使いかた、あるかーーーー! と、叫びそうになりました(私の2時間を返せ)
https://github.com/gorilla/websocket/tree/master/examples/echo
この"server.go"は、client.goからの通信だけではなく、ブラウザの画面も提供します(スゴい!)。
というか、Goプログラムの中に、html書けるなんて知らんかった。
// server.go
// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
import (
"flag"
"html/template"
"log"
"net/http"
"github.com/gorilla/websocket"
)
var addr = flag.String("addr", "localhost:8080", "http service address")
var upgrader = websocket.Upgrader{} // use default options
func echo(w http.ResponseWriter, r *http.Request) {
c, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Print("upgrade:", err)
return
}
defer c.Close()
for {
mt, message, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
break
}
log.Printf("recv: %s", message)
err = c.WriteMessage(mt, message)
if err != nil {
log.Println("write:", err)
break
}
}
}
func home(w http.ResponseWriter, r *http.Request) {
homeTemplate.Execute(w, "ws://"+r.Host+"/echo")
}
func main() {
flag.Parse()
log.SetFlags(0)
http.HandleFunc("/echo", echo)
http.HandleFunc("/", home)
log.Fatal(http.ListenAndServe(*addr, nil))
}
var homeTemplate = template.Must(template.New("").Parse(`
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
window.addEventListener("load", function(evt) {
var output = document.getElementById("output");
var input = document.getElementById("input");
var ws;
var print = function(message) {
var d = document.createElement("div");
d.textContent = message;
output.appendChild(d);
output.scroll(0, output.scrollHeight);
};
document.getElementById("open").onclick = function(evt) {
if (ws) {
return false;
}
ws = new WebSocket("{{.}}");
ws.onopen = function(evt) {
print("OPEN");
}
ws.onclose = function(evt) {
print("CLOSE");
ws = null;
}
ws.onmessage = function(evt) {
print("RESPONSE: " + evt.data);
}
ws.onerror = function(evt) {
print("ERROR: " + evt.data);
}
return false;
};
document.getElementById("send").onclick = function(evt) {
if (!ws) {
return false;
}
print("SEND: " + input.value);
ws.send(input.value);
return false;
};
document.getElementById("close").onclick = function(evt) {
if (!ws) {
return false;
}
ws.close();
return false;
};
});
</script>
</head>
<body>
<table>
<tr><td valign="top" width="50%">
<p>Click "Open" to create a connection to the server,
"Send" to send a message to the server and "Close" to close the connection.
You can change the message and send multiple times.
<p>
<form>
<button id="open">Open</button>
<button id="close">Close</button>
<p><input id="input" type="text" value="Hello world!">
<button id="send">Send</button>
</form>
</td><td valign="top" width="50%">
<div id="output" style="max-height: 70vh;overflow-y: scroll;"></div>
</td></tr></table>
</body>
</html>
`))
// client.go
// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build ignore
// +build ignore
package main
import (
"flag"
"log"
"net/url"
"os"
"os/signal"
"time"
"github.com/gorilla/websocket"
)
var addr = flag.String("addr", "localhost:8080", "http service address")
func main() {
flag.Parse()
log.SetFlags(0)
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
u := url.URL{Scheme: "ws", Host: *addr, Path: "/echo"}
log.Printf("connecting to %s", u.String())
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Fatal("dial:", err)
}
defer c.Close()
done := make(chan struct{})
go func() {
defer close(done)
for {
_, message, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
return
}
log.Printf("recv: %s", message)
}
}()
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
select {
case <-done:
return
case t := <-ticker.C:
err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
if err != nil {
log.Println("write:", err)
return
}
case <-interrupt:
log.Println("interrupt")
// Cleanly close the connection by sending a close message and then
// waiting (with timeout) for the server to close the connection.
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println("write close:", err)
return
}
select {
case <-done:
case <-time.After(time.Second):
}
return
}
}
}
■(まとめ)地図DBの作り方 "toyosu.osm"もダウンロードできます。
■GolangでPOSTを試してみた件
■「GolangでCUIでWebsocketを試したい」にドンピシャのソースコードはこちら
■「GolangでCUIでWebsocketを試したい」のクライアントを、goroutine化してみた件
■コピペで学ぶ、GitとGitHub入門
■改札口のデータの収集ができてしまった件
■DockerのbashからSQLファイルを実行する方法
■geometry型がさっぱり分からん
■postGIS環境作り直し方(バラバラに記載して、訳が分からなくなってエライ目にあった)
■「GolangでCUIでWebsocketを試したい」のserver.goをdockerコンテナに閉じ込めたい
■「GolangでCUIでWebsocketを試したい」のclient.goをdockerコンテナに閉じ込めたい