OmniAICreator/Qiita-1.07M huggingface dataset:
Docker環境でsolargraphを使う方法

# 記事の目的
最近、VSCodeを使い始めて、solargraphといgemの存在を知り、使ってみたらテキストエディタがIDEみたいに化けたのでびっくりしました。

そこでdocker-composeでも使えたら最高なのにな〜と思い調べてみました。

意外と記事が無かったのでまとめてみます。

因みに、[Railsとセットで構築できるリポジトリ](https://github.com/belion-freee/quickstart)があるので、よかったら使ってみてください。

#### 注釈
こちらの記事で紹介するのは**VSCode**でのやり方です。Atomや他のエディタでのやり方ではないので注意してください。

Atomでも試して見たけど、docker以前にパッケージがうまく機能しませんでした。
GitHub見る限り、Atom版のパッケージはどうも不安定なようです。

https://github.com/castwide/atom-solargraph/issues

うまく機能した人いたらコメントくだせえ。


# solargraphとは？
Solargraphは、Microsoftの言語サーバープロトコルを介してコード補完機能を提供してくれるRuby gemです。
要するに、IDEみたいにリッチなコード補完が使えるgemです。各エディタでプラグインも提供してくれてます。今回はVSCodeでの使い方を説明していきます。

https://github.com/castwide/solargraph

動きこんな感じ。半端ない。

<img src="https://github.com/castwide/vscode-solargraph/raw/master/vscode-solargraph-0.34.1.gif" alt="Screenshot">

# 手順
ここから順を追って説明していきます。

## solargraphのインストール
まずは必要なsolargraphプラグインをインストールしていきましょう。

### gemをインストール
まずはGemfileにsolargraphを記述してインストールしましょう。

```yml
gem 'solargraph', group: :development
```

`bundle install` しましょう。これはDockerfileでインストールしてる場合はイメージをビルドし直してください。
docker-composeコマンドで都度インストールしてる場合は下記のコマンド打ってください。`app`はアプリケーションコンテナです。

`docker-compose run --rm app bundle install`

### プラグインのインストール
VSCodeにsolargraphプラグインをインストールしましょう。

https://marketplace.visualstudio.com/items?itemName=castwide.solargraph

## solargraphコンテナの作成
solargraphはコード補完用のサーバーとしてコンテナを別にして立ち上げておいて、ローカルのVSCodeからアクセスできる設定にしておきましょう。
コンテナを別にした方がプロジェクトと独立してるため運用しやすいです。

### docker-compose
solargraphサービスはこんな感じで書いてください。volumeキャッシュしたり、appコンテナの設定を継承したりとか、細かい設定はお任せします。

```yml
solargraph:
    build: .
    command: bundle exec solargraph socket --host=0.0.0.0 --port=7658
    volumes:
      - .:/app
      - bundle:/usr/local/bundle
    ports:
      - "8091:7658"
```

記述したら下記のコマンドを実行してsolargraphを起動しておきましょう。
もし、appコンテナと同時に立ち上げたい場合は、docker-composeのappサービスに `links` でsolargraphサービスを指定しておくと便利です。

`docker-compose up -d solargraph`

## プラグインの設定
dockerコンテナと接続するためにプラグイン側も設定が必要です。
VSCodeで設定していきましょう。

ショートカットキー `Shift+command+P` を押して、入力欄に`Open Settings Json`と打ち込んで、`settingｓ.json`ファイルを開きましょう。

中身に下記のコードを追記してください。

```json-doc
{
  "solargraph.externalServer": {
    "host": "localhost",
    "port": 8091
  },
  "solargraph.transport": "external",
  "solargraph.logLevel": "debug",
  "solargraph.diagnostics": true,
  "solargraph.hover": false
}
```

ここまで書いたら一旦VSCodeを再起動しましょう。

## 接続確認
さあ、早速コード補完が使えるか試してみましょう。

![sola.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234657/f63f2812-5d74-91fc-6e98-9c932522da32.gif)

**サックサクに動きやがるっ！ ありがてえ、ありがてえっ！**

# まとめ
簡単にリッチなコード補完が使えるようになりました。
快適なRuby & solargraphライフを楽しんでください。
柔軟なネットワーク構成のためのMCSマルチキャストスイッチ光スイッチ

MCSマルチキャストスイッチング光スイッチモジュールは、PLCテクノロジとMEMSテクノロジをベースにしたマルチキャストスイッチド光スイッチ（MCS）であり、あらゆる光入力をあらゆる出力にルーティングでき、次世代の再構成可能な光アド/ドロップ多重システム（ROADM）です。 ）キーコンポーネント。

![23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463940/ca238556-5347-16f0-732f-543cc0c657ce.jpeg)

まず、再構成可能な光アド/ドロップ多重システム（ROADM）とは何かを最初に理解しましょう。
再構成可能光アド／ドロップマルチプレクサ（ＲＯＡＤＭ）は、波長分割多重（ＷＤＭ）伝送リンクに１つまたは複数の光信号を追加または除去する光アドドロップマルチプレクサ（ＯＡＤＭ）の１つである。 この装置は高密度波長分割多重（ＤＷＤＭ）システムで使用することができる。 動的リモートまたはダウンストリームサービス波長は動的に再設定できます。 すなわち、回線の途中で、必要に応じて上下のサービスの波長を任意に割り当てることができ、柔軟なサービスのスケジューリングを実現することができる。

波長選択スイッチ（WSS）を使用すると、ROADMの波長を独立（任意の波長を直接任意のポートに向ける）、方向に依存しない（受信など）ことができます。 異なる方向の複数の入力波長チャネルに対する設定の柔軟性、衝突なし（同じスイッチを介して異なる方向から同じ波長チャネルをダウンロードすることが可能）。 これは、柔軟性と低コストのネットワーク構築を実現する上で非常に重要です。

マルチキャストスイッチング光スイッチ構造
![24.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463940/288b1c14-b842-3ee5-4033-db5a07b95dbc.jpeg)
図に示すように、2つの別々のMCS機能ユニットが1つのモジュールに統合されており、各機能ユニットはM個の独立した1×16 PLCスプリッタとN個の独立した1×8 MEMS光スイッチで構成されています。 Ｍ×Ｎ ＭＣＳは、Ｍ個の方向へのＮ個のアップリンク（またはドロップ）ポートへの接続を提供する。

ネットワーク規模が拡大し続け、クロスノードおよび上位および下位チャネルの容量要件が増加し続けるにつれて、WSS + MCSは、光ネットワーク用の新世代CDC-ROADMの下で、通信事業者およびシステム事業者にとって賢い選択になるでしょう。 シンプルで柔軟で無制限のネットワークリソース割り当て機能、そしてオペレータの運用コストを大幅に削減します。

HYC は、MEMS技術、MCSマルチキャストスイッチング光スイッチ、その他のモジュールをベースにした一連の光スイッチを独自に開発しました。 HYC は光通信パッシブ基本部品の研究開発、製造、販売およびサービスを専門とする国家ハイテク企業です。 同社の主力製品は以下のとおりです。光ファイバコネクタ（データセンター高密度光コネクタ）、波長分割マルチプレクサ、光スプリッタおよびその他の3コア光パッシブ基本コンポーネント、家庭用光ファイバ、4Gモバイル通信で広く使用されている、 インターネットデータセンター、防衛通信、その他の分野。
ユーザー登録画面を作成しながらDBを操作する画面作成の基礎を勉強してみる～ユーザー登録画面の作成～

この記事の関連記事となります。
[ユーザー登録画面を作成しながらDBを操作する画面作成の基礎を勉強してみる](https://qiita.com/mikansei-lab/items/d7e0074df89f508e8c96)

---

## はじめに

ユーザー登録画面を作成して、ユーザー情報を登録できるようにします。

## 手順

 1. コントローラーを編集します
 2. 編集画面を作成します

### 1. コントローラを編集します

コントローラーを編集します。

```php:app/Http/Controllers/UserController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\User;

class UserController extends Controller
{
  // 
  public function create(Request $request)
  {
    // ユーザー登録画面を表示します
    return view('users.create');
  }
  // 
  public function store(Request $request)
  {
    $user = new User;
    // 入力値をセットします
    $user->name = $request->name;
    $user->email = $request->email;
    $user->password = bcrypt($request->password);
    // ユーザーを保存します
    $user->save();
    // ユーザー一覧画面へ遷移します
    return redirect('/users');
  }
}
```

### 2. 編集画面を作成します

編集画面を作成します。

```html:resources/views/users/create.blade.php
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>
    <div class="container">
      <form method="post" action="/users">
        {{ csrf_field() }}
        <div class="form-group">
          <label>氏名</label>
          <input class="form-control" name="name" type="text" value="" required>
        </div>
        <div class="form-group">
          <label>メールアドレス</label>
          <input class="form-control" name="email" type="email" value="" required>
        </div>
        <div class="form-group">
          <label>パスワード</label>
          <input class="form-control" name="password" type="password" value="" required>
        </div>
        <a class="btn btn-secondary" href="/users">一覧へ</a>
        <input class="btn btn-primary" type="submit" value="保存">
      </form>
    </div>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  </body>
</html>
```

## 参考
FireStoreでデータの更新を監視する関数メモ

# はじめに
FireStoreとbingMapsを使って地図上をクリックするたびにpinとInfoboxが立つものを作ったのでそのメモです。
FireStore内のデータに変化が有るたびにピンを立て直しているので更新ボタンを押さずに反映させることが出来ます。
公式ドキュメントを見ても使いこなせず、試行錯誤の末このようなコードになりました。

# クリックした位置の緯度経度を取得しピンとInfoboxを立てる
```javascript

 function GetLocation(e) {
            if (e.targetType == "map") {

                newLat = e.location.latitude;
                newLon = e.location.longitude;

                //取得した緯度と経度にピンをたてる
                let color = '#ff3e6d';
                map.pin(newLat, newLon, color);

                let title = '';
                let text = $("#text").val();
                let address = $('#wltadd').val();
                let descript = '<div style="width:100px;color:#violet;">' + text + '</div>';

                actions =
                    [
                        //1.Infobox内のaction定義
                        {
                            //省略
                    ];
                // Infoboxを作る関数
                map.onInfobox(newLat, newLon, title, descript, actions);
         
            }
        }

```
# FireStoreにデータをセット
上記の関数の最後に挿入します。

```javascript

db.collection("pins").doc().set({
                    username: uid,
                    date: times(),
                    getLat: newLat,
                    getLon: newLon,
                    message: text,
                    walletInfo: address
                });
```
# 新しく追加されたデータがないか監視する関数
ここでは位置情報を取得する関数内に"pins"というコレクションの情報を監視し、新しく追加されたデータがあったら更新できるようになっています。その後、map上に"rightclick"にて```GetLocation()```が発火するように書いてみました。

匿名ログインを使っているためusernameごとにpinの色を変えています。
そのため自分以外の人が立てたpinは自分のpinと異なる色になります。

```javascript


        //位置情報の取得に成功した時の処理
        function mapsInit(position) {
            //lat=緯度、lon=経度 を取得
            let lat = position.coords.latitude;
            let lon = position.coords.longitude;
            map = new Bmap("#myMap");
            map.startMap(lat, lon, "load", 18);

　　　　　　  ////pinsをSnapshotで監視。新しく追加されたdataがあったら更新する。
            db.collection("pins").onSnapshot(function (querySnapshot) {
                querySnapshot.forEach(function (doc) {
                    map.pin(doc.data()['getLat'], doc.data()['getLon'], "#12d3cf");
                    //infoboxに入っているusername
                    let infoUser = doc.data()['username'];
                    
                    //現在ログイン中のusername
                    let loginUser = firebase.auth().currentUser.uid;
                    actions =
                        [
                            //省略
                        ];

                    //自分以外の人にはothersの旗を作る
                    if (infoUser !== loginUser) {
                        map.onInfobox(doc.data()['getLat'], doc.data()['getLon'], 'others/' + doc.data()['date'], doc.data()['message'], actions);
                        console.log('yes');
                    }
                });
            });

            map.onMap('rightclick', GetLocation);

        };
```

#最後に
エラー関数などは省略してあります。またJavascriptを勉強し始めて1ヶ月ほどで作った初心者の備忘録につき、書き方がおかしいところもあると思いますがご容赦下さい。（アドバイス等ありましたらお願いします。）
marked.jsを使って複数要素をhtml化

# 準備

htmlに変換したいmarkdownをtextareaで囲い、任意のクラス名を割り当てる

```html:html
<textarea class="md"># aaa</textarea>
<textarea class="md"># bbb</textarea>
```

marked.jsを読み込む

```html:html
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js">
```

marked.jsを使って複数要素をhtml化するjsを作る

```js:js
(function() {
    "use strict";
    var class_name = "md"
      , collection = document.getElementsByClassName(class_name)
      , target = collection[0];

    while (target !== undefined) {
        if (target.type === "textarea") {
            target.outerHTML = marked(target.innerHTML);
        }
        target = collection[0];
    }
}());
```

### 完成形

```html:marked_test.html
<!doctype html>
<meta charset="utf-8">
<title>marked.jsのテスト</title>

<textarea class="md"># aaa</textarea>
<textarea class="md"># bbb</textarea>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script>
    (function() {
        "use strict";
        var class_name = "md"
          , collection = document.getElementsByClassName(class_name)
          , target = collection[0];

        while (target !== undefined) {
            if (target.type === "textarea") {
                target.outerHTML = marked(target.innerHTML);
            }
            target = collection[0];
        }
    }());
</script>
```

# 実験

完成形を読み込むと

```html:html
<textarea class="md"># aaa</textarea>
<textarea class="md"># bbb</textarea>
```

の部分が

```html:html
<h1 id="aaa">aaa</h1>
<h1 id="bbb">bbb</h1>
```
に変換される

# リンク

- [Marked.js Documentation](https://marked.js.org/#/README.md#README.md)
- [marked CDN by jsDelivr - A free, fast, and reliable Open Source CDN](https://cdn.jsdelivr.net/npm/marked/)
- [GitHub - markedjs/marked: A markdown parser and compiler. Built for speed.](https://github.com/markedjs/marked)
ブックマークレットを使うとスマホでもHTMLソースを表示できます

スマホをいじっていると「このページのソースコードが見たい！！」となることがありますよね。しかし、iPhoneのSafariには標準ではHTMLのソースコードを見る機能がありません。そこで、HTMLソースを表示できるめちゃくちゃ便利なブックマークレットを紹介します。

#ブックマークレットとは？
>ブックマークレット とは、ユーザーがウェブブラウザのブックマークなどから起動し、なんらかの処理を行う簡易的なプログラムのことである。携帯電話のウェブブラウザで足りない機能を補ったり、ウェブアプリケーションの処理を起動する為に使われることが多い。[Wikipedia](https://ja.m.wikipedia.org/wiki/%E3%83%96%E3%83%83%E3%82%AF%E3%83%9E%E3%83%BC%E3%82%AF%E3%83%AC%E3%83%83%E3%83%88)

JavaScriptで記述し、コードの先頭に`javascript:`と付けてブックマークのURL欄に追加することで利用できます。

#利用方法

```javascript
javascript:var d=document;var o=d.documentElement;d.write("<pre class=\"prettyprint\">"+(o.outerHTML||o.innerHTML).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")+"</pre>");var style = d.createElement("style");style.type = "text/css";var head = d.head;head.appendChild(style);style.sheet.insertRule("*{font-family:'Menlo',monospace;font-size:7px}")
```


これをブックマークのURLに登録します。
（iPhoneではブックマークを登録する際に任意のURLを指定することができないので、まず仮のページを登録してから「ブックマーク」→「編集」でURLをコードに置き換えてください）
そして、ソースコードの見たいページでブックマークを開きます。
<img width="375" alt="DEF1C600-44B9-49AC-A4E1-8A53059980D4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396300/407544bf-2a7b-8d03-fd7b-99eaf4f23990.png">
ブックマークレットを実行すると
<img width="375" alt="F05735C2-DAB0-4BB3-AA8B-37479C443B88.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396300/05046a56-fb8d-763e-8ea0-082ecf08aeb3.png">
こんなかんじ。

#コードの説明
文字をエスケープ

```javascript
var d=document;
var o=d.documentElement;
d.write("<pre class=\"prettyprint\">"+(o.outerHTML||o.innerHTML).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")+"</pre>");
```



フォントや文字サイズを調整
この部分は自由にカスタマイズしてください。

```javascript
var style = d.createElement("style");
style.type = "text/css";
var head = d.head;
head.appendChild(style);
style.sheet.insertRule("*{font-family:'Menlo',monospace;font-size:7px}")
```
Googleカレンダーで共有してもらったカレンダーをiPhoneやMacのカレンダーに表示する方法がわからなくてはまった結果

# はじめに

複数の人とスケジュールを共有する必要があったのでGoogleカレンダーの共有機能を使おうと思ったら、iPhoneやMacのカレンダーに共有してもらったスケジュールが表示されずに四苦八苦して、何時間も無駄にしてしまいました。

そんな悲しい人を増やさないために手順をメモしておきます。

# 同期設定

以下のURLにアクセスします。

[Googleカレンダー 同期設定](https://calendar.google.com/calendar/syncselect)

![スクリーンショット 2019-07-23 10.58.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114240/740523fe-94f4-7a92-f152-0f2aee2aa8b0.png)


共有してもらったカレンダーの左にあるチェックボックスにチェックを入れる。

# iPhoneやMacのカレンダーを確認

表示されるようになりました...(-_-;)
Pythonではじめてのスクレイピング【Mac】


*  プログラミング歴42日の素人が書いています。ご注意ください。




#はじめに

Webスクレイピングたのしい！
きほんのやり方をまとめます。


##環境

* MacBookAir-mid2014

* macOS-Mojave

* Python 3.7.4



#「requests」ライブラリのインストール

（インストール済みの場合はスキップ）
ターミナルに以下を打ち込み、ライブラリをインストールします。
requestsはWebサイトから情報の取得を行います。

```
pip3 install requests
```


#「Beautiful Soup」ライブラリのインストール

（インストール済みの場合はスキップ）
ターミナルに以下を打ち込み、ライブラリをインストールします。
Beautiful SoupはHTMLの解析を行います。

```
pip3 install BeautifulSoup4
```

#あるWebサイトから必要な情報のみ抜き出す

```python
import requests
from bs4 import BeautifulSoup

with open('sample.csv','w') as f:

    for i in range(page数):

        result = requests.get('https://example.com/page/{}/'.format(i))
        print(result)
        soup = BeautifulSoup(result.text, 'html.parser')
        list = soup.find_all('h2', class_='クラス名')

        for h2 in list:
            data = h2.a['title']
            f.write('{0}\n'.format(data))
```


##ライブラリのインポート

```python
import requests
from bs4 import BeautifulSoup
```

##CSVファイルの作成

```python
with open('sample.csv','w') as f:
```

`sample.csv`ファイルを作成。第２引数`w`は「書き込み専用」。


##繰り返し処理

```python
for i in range(page数):
```

page数分繰り返します。（page数とか無いばあいはスキップ）


##webサイト情報の取得

```python
result = requests.get('https://example.com/page/{}/'.format(i))
print(result)
```

example.comにアクセスします。ループを回すごとに、`i`の値が変化し、ページ番号が変化します。
`print(result)`はステータスコードを表示します。表示される値が[200]ならhtmlリクエストが正常に処理されています。


##HTMLデータへの変換

```python
soup = BeautifulSoup(result.text, 'html.parser')
```

BeautifulSoup4を利用して、さきほど取得した文字データをhtmlと認識して扱えるようにパースします。


##任意のクラス名で検索して抜き出す

```python
list = soup.find_all('h2', class_='クラス名')
```

ここでは`h2`タグの中で、特定のクラス名がついている要素を検索しています。


##さらにデータの絞り込みとCSVへの書き込み

```python
for h2 in list:
            data = h2.a['title']
            f.write('{0}\n'.format(data))
```

`find_all`すると配列データになっています。
配列からひとつづつ抜き出して、`h2`という変数に格納します。

`h2.a`のようにすると、`h2`内の`a`タグにアクセスすることができます。（子要素へのアクセス）
さらに`h2.a['title']`のように続けると、`h2`内の`a`タグのタイトル属性にもアクセスできます。
たとえば、以下のようなhtmlだったなら、

```html
<h2><a href="http://something.com" title="Go to Somewhare"></a></h2>
```

`Go to Somewhare`の部分を抜き出しています。

最終行は、CSVへの書き込みを行っています。
なお、`\n`は改行です。


#まとめ

ライブラリを使うことで、非常にすくないコード量でスクレイピングが実現できます。
また、過度なスクレイピングは相手サーバに迷惑がかかるので気をつけましょう。
wordpressの記事を未来日付で自動予約投稿する方法

地味だけど知らなかったwordpressの記事の自動予約投稿の方法です。

エディタの右側ペインにある
「公開」ですが、
デフォルトは現在日付で「すぐに公開する」設定になっています。

<img width="281" alt="スクリーンショット 2019-07-23 10.34.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/948c541e-90b0-ebe1-332c-1283c927c787.png">

ここを投稿したい未来の日付にするだけ！

<img width="280" alt="スクリーンショット 2019-07-23 10.35.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/9a367e49-f48e-6cc7-6daa-78bc13aa4a14.png">

これだけで「予約投稿」になります。

<img width="278" alt="スクリーンショット 2019-07-23 10.35.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/d52fdc22-0db6-283d-4050-c413447fd962.png">

ちなみにリンクの設定を「yyyy/mm/dd」付きにしている場合は、公開日付を変更すると
こちらも公開日付に合わせて自動で変更が反映されます。

地味だけど便利な機能です。
この機能を駆使して私もブログ記事のネタ貯金生活をしてみたいものです。
（現状、毎日その日暮らしorz）

余談ですが、
更新日の変更をしない状態で更新することも可能です
ちょっとした誤字・脱字を見つけたけど更新日は変えたくないなって時は
「更新しない」を選んで更新すればOKです。
<img width="281" alt="スクリーンショット 2019-07-23 10.33.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/8eec9187-13f1-46bf-829a-035d0f5a8a61.png">
【２】IntelliJ+Laravel+Vuejs+Docker+Mysqlの環境構築


今回もlaradockを使っての構築。
前回の環境にdocker mysqlを導入する。

gitも載せとく。
https://github.com/miyamotok0105/laravel_sample/tree/master/docker_sample2/005laravel-lig


```
git clone https://github.com/Laradock/laradock.git
mkdir src
cd laradock
cp env-example .env
```


APP_CODE_PATH_HOSTはアプリケーションのディレクトリパス。
DATA_PATH_HOSTはプロジェクトのデータ管理場所。
COMPOSE_PROJECT_NAMEはdokcerのコンテナ名。
MYSQL_VERSIONはmysqlのバージョン。

```
APP_CODE_PATH_HOST=../src/
DATA_PATH_HOST=../.laradock/data
COMPOSE_PROJECT_NAME=laradock-project_name
MYSQL_VERSION=5.7
```

docker起動。

```
docker-compose up -d nginx mysql phpmyadmin
```

Laravelインストール

```
docker-compose exec workspace bash
composer create-project --prefer-dist laravel/laravel ./
```


Laravelの設定


```:laradock_project_name/src/.env
DB_HOST=mysql
DB_DATABASE=default
DB_USERNAME=default
DB_PASSWORD=secret
```

コマンドでmysql接続

サーバ: mysql
ユーザー名: default
パスワード: secret


```
docker-compose exec workspace bash
mysql -u default -p

```

phpadminで接続

http://localhost:8080


アクセス
http://localhost
vue.js length error isset

vue.jsで length したい場合がある。
しかし、エラーが出る。

そんな時は、 undefined チェックしてからやればいい。

```

            //ユーザーのアイコンを取得
            getIcon(user){

                let icon = '';

                icon = user.img;

                if (typeof user.socials !== 'undefined') {
                    // your code here
                    if(user.socials.length != 0){
                        icon = user.socials[0].img;
                    }
                }

                if (typeof user.photos !== 'undefined') {
                    // your code here
                    if(user.photos.length != 0){
                        icon = "/gcp_storage/photo_300x300_" + user.photos[0].id + ".jpg";
                    }
                }

                return icon;

            },

```

こんな感じ。
bundle install --path vendor/bundleをしたら大量にファイルがインストールされてしまった!?

# bundle install --path vendor/bundleで大量のファイル


あるときGitの管理外の場所で参考記事を見ながら、bundle install --path vendor/bundleをしたら大量のファイルがインストールされてしまって、混乱したのでその解決した方法を載せようと思います。


```ruby:ターミナル
$ bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/............
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Fetching rake 12.3.2
Installing rake 12.3.2
Fetching concurrent-ruby 1.1.5
Installing concurrent-ruby 1.1.5
Fetching i18n 1.6.0
Installing i18n 1.6.0
Fetching minitest 5.11.3
Installing minitest 5.11.3
Fetching thread_safe 0.3.6
Installing thread_safe 0.3.6
Fetching tzinfo 1.2.5
Installing tzinfo 1.2.5
Fetching activesupport 5.2.3
Installing activesupport 5.2.3
Fetching builder 3.2.3
Installing builder 3.2.3
Fetching erubi 1.8.0
Installing erubi 1.8.0
Fetching mini_portile2 2.4.0
Installing mini_portile2 2.4.0
Fetching nokogiri 1.10.3
Installing nokogiri 1.10.3 with native extensions
Fetching rails-dom-testing 2.0.3
Installing rails-dom-testing 2.0.3
Fetching crass 1.0.4
Installing crass 1.0.4
Fetching loofah 2.2.3
Installing loofah 2.2.3
[省略]
```

## 原因
通常のbundleであればシステムのrubyにinstallされ流のですが、この指定で、--path vendor/bundleで作成しているアプリケーション内のvendor/bundleにインストールされていってしまうからのようでした。

## 解決方法

一度pathを通すとbundleディレクトリのconfigにpathが設定されるらしく、次回以降もvendor/bundleにインストールされるようになるようです。

元のシステムにインストールされるよう戻したいのなら、bundle/config内にあるvndor/bundleを消せばいいということ。

### 参考記事は理解しながらコマンドを打つべし

エラーが出た時に原因がなんなのかすらわからないので、参考記事は理解しながらコマンドを打つことが重要だということを思いしりました。
AtCoder Beginner Contest 005


###A - おいしいたこ焼きの作り方

久々にjoinを使う。
数値のリストを文字列として連結・結合するのに使用。

```py
a, b = map(int, input().split())
print(''.join([str(x) if x >= 1 else '0' for x in [b/a]]))
```
ウキウキで提出したらWA。
原因は[b/a]の所で x がfloat型になるため、余分な小数部が発生。
対策として小数部切り捨てのためにint型にキャストする。

```py
a, b = map(int, input().split())
print(''.join([str(int(x)) if x >= 1 else '0' for x in [b/a]]))
```

###B - おいしいたこ焼きの食べ方

配列の中で一番小さい、はmin関数を使う。

```py
T = [int(input()) for x in range(int(input()))]
print(min(T))
```
Vue Routerを使用したページ遷移のやり方

##はじめに
Vue.jsを使った、ページの切り替え方法について解説していきます。
Vueの開発環境の構築は終わったけど、何か知らないファイルたくさん入ってるし、どこをどういじって開発していけばいいのかわからない！といった方向けの記事となります。

開発環境の構築はこちらから
[初心者向け！Vue.jsの開発環境の構築](https://qiita.com/Mitsuzara/items/4dea8c0aa95d6284980a)

##表示させたいページの作成
ここではhome.vueを表示させてみます。
まずはsrc/components/home.vueを新たに作成します。

```home.vue
<template>
  <div>
    <p>ようこそ！<br/>ここは私のサイトです</p>
  </div>
</template>
<script>
export default {
  name: 'Home',
}
</script>
```
##ルーティング設定
ページの作成が終わったので、次はRouterの設定をしましょう。
src/router/index.jsを開いて、新しく作成したhome.vueをルーティングさせます。{} や , を忘れないようにしましょう。

```index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Home from '@/components/home' // new add

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },                 // , の追加を忘れずに
    {
      path: '/home',   // new add
      name: 'Home',    // new add
      component: Home  // new add
    }
  ]
})
```
これでokです。yarn devで立ち上げて [localhost:8080/home/](http://localhost:8080/home/) にアクセスしてみましょう。
![localhost_8080_ (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/1ef2c1b3-160c-fdc3-b115-f3133dae94aa.png)
home.vueで作成したhomeページを表示できました。

##アドレスバーの # を消したい
<img width="500" alt="スクリーンショット 2019-07-23 9.57.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/25484dbe-77a1-6a9f-79a6-e427184f9e84.png">
アドレスバーに # が付いているのに気がつきましたか？これは消す事ができます。先ほどのsrc/router/index.jsにコードを追加します。

```index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Home from '@/components/home'

Vue.use(Router)

export default new Router({
  mode: 'history',  // new add
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path: '/home',
      name: 'Home',
      component: Home
    }
  ]
})
```
再度アドレスバーに [localhost:8080/home/](http://localhost:8080/home/) と入力してみましょう。
<img width="500" alt="スクリーンショット 2019-07-23 9.56.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459087/5944d972-df68-2d67-6b36-981bba97d952.png">
 # が表示されなくなっているのを確認できました。

##まとめ
ここまで読んでくださりありがとうございます。
上手くいきましたか？何か不明な点がございましたら、コメント等頂けましたら幸いです。
ページを作成し、そのページを表示する為にルーティング設定をする。これはVueで開発する上で必須の知識となるので覚えておきましょう。
ちなみにnuxt.jsだと、この様なルーティング設定が不要でファイル名がそのままURLになるので非常に楽です。興味がある方は調べてみてください。
[Tips] GitHubのCLIツール：hubでPR作成をちょっと楽にする

皆様、hub使ってますか？

以前少しだけ使って結局使うのをやめてしまったのですが、最近また使い始めたのでこの機会に共有させてください。

## 本記事の対象者

- GitHubを使っている人
  - 特にWIP手法で開発している人
  - すこし楽したい人

## hub？

GitHubが提供しているコマンドラインツールです。
issue書いたり、PRを作ったりがコマンドでできます。

## インストール

[こちら](https://github.com/github/hub#installation)にありますが、Macユーザーの場合は以下で完了します。

```
brew install hub
```

## WIPなPRを新しく作る

### これまでのやり方（嶋生の場合）

※参考までに（）内に個人的なエイリアスを使った場合を記載。

- 新しいブランチを作成。 `git checkout -b hoge`（`git co -b hoge`）
- 空コミット作成。 `git commit --allow-empty -m '[WIP][ci skip]〇〇をやる'`（`git cme -m '[WIP][ci skip]〇〇をやる'`）
- リモートリポジトリにpushする。 `git push -u origin hoge`（`git pc`）
- GitHubに移動し、ポチポチPRを作る。

### hubを使う場合

- 前提として、`~/.gitconfig`に以下のエイリアスを設定しておく
```
[alias]
    mkpr = !"f() { git commit --allow-empty -m \"$1\" && git push -u origin HEAD && hub pull-request --draft; }; f"
```
- 新しいブランチを作成。 `git checkout -b hoge`（`git co -b`）
- 新しいPRを作成。`git mkpr '[ci skip]〇〇をやる'`
  - 空コミット作成してpushしてPR作成を一度にやってます。
  - 前提としてpushしたいブランチにチェックアウト済の必要があります。（いまいるブランチをpushする）
  - PRをDraftで作成するようにしているのでタイトルから`[WIP]`は削除しています。

実際に↓のような感じで使ってます！

![hub_mkpr.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120225/274768aa-cf32-c6c0-3bee-88818992ee75.gif)


気になる方はぜひ使ってみてください！！

## その他：gitconfigをさらす

以下、自分の設定です。「こんな設定もいいよ！」というのがあったら教えてください。

```
[alias]
    lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
    lga = log --graph --all --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
    st = status
    cm = commit
    br = branch
    co = checkout
    # 行ごとの差分じゃなくて，単語レベルでの差分を色付きで表示する
    difff = diff --word-diff
    diffc = diff --cached
    cme = commit --allow-empty
    pc = push -u origin HEAD
    # use hub command
    see = browse
    mkpr = !"f() { git commit --allow-empty -m \"$1\" && git push -u origin HEAD && hub pull-request --draft; }; f"
[color]
    ui = true
[url "git@github.com:"]
    ...
[user]
    ...
[core]
    editor = vim
    pager = nkf -w | LESSCHARSET=utf-8 less
[commit]
    template = ~/.commit_template
```

特筆することはあまりない感じですが、1つ紹介すると `git diffc(git diff --cached)`はよく使います。

通常の`git diff`が Untrackedなファイルのdiffを表示してくれるものですが、`git diff --cached`は`git add`したファイルのdiffを表示してくれます。
複数ファイルを編集している状態で一部ファイルだけcommitしたいときなどに「どれaddしたっけなぁ」の確認のためなどに使ってます。あとは（言葉では説明しづらいのですが…）完成した部分から順にaddしていくみたいな使い方のときに使ってます。
MYSQLスクリプト実行時のパスワード取り扱い備忘録

手でたたくときは問題ないパスワードもスクリプトで自動化する場合はやっかいなもの。

外部コンフィグに保存しておけば自動化できるのでそのメモ。

###接続情報コンフィグファイル
```php
[client]
user=xxxx
password=xxxx
host=xxxx
database=xxxx
```
アクセス権限は644にする。777だと怒られる。

###実行
```
 mysql --defaults-file=/tmp/.my.cnf
```
コンフィグは隠しファイルとして保存しておくとよい。

以上
zabbixのアラートをchatworkに投稿する

### 環境
* zabbix4.0.10
* chatwork

### 背景

zabbixのアラートをメールだけでなくchatworkに送りたくなり調べました。参考にあるqiitaのものがちょっとだけ古くて動作しなかったため、現状のchatworkのものに合わせた変更をしました。

```/usr/lib/zabbix/alertscripts/chatwork
#!/bin/sh
#
# $1 roomid

TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
ENDPOINT="https://api.chatwork.com/v2/rooms/${1}/messages"
SUBJECT=${2}
MESSAGE=${3}
#MESSAGE=`urlencode ${3}`

/usr/bin/curl \
        -x http://xxxxxxxxxxx \
        -X POST \
        -H "X-ChatWorkToken: ${TOKEN}" \
        --data-urlencode "body=[info][title]${SUBJECT}[/title][code]${MESSAGE}[/code][/info]" \
        -d "self_unread=1" ${ENDPOINT}
```
bodyはURLエンコードをしないといけない


### 参考
https://qiita.com/skouno25/items/21de33a723fcaa8f8531
http://developer.chatwork.com/ja/
【ServiceNow】Mobile Agent（=スマホアプリ）導入

# 経緯
ServiceNowのMadridから本格サポートが開始されたMobile Agent(=スマホアプリ)の、簡単な概要と導入資料に資するように書きました。本当は社内の勉強用に作成途中(WIP)でしたが、途中で書く気力がなくなってきたので、現状出せるものだけ共有します。中身については別記事に分離します。

# はじめに
モバイルエージェント(Mobile Agent:以下**モバイル**)は、**ServiceNowネイティブアプリ**です。ITSMインシデント処理をスマホアプリ上で完結できます。

## 注意点
ServiceNowが公式リリースしたアプリは二つあります。
- Classic
- Mobile Agent
そして今回の解説対象は後者のMobile Agentです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/956b25f1-6edf-7cf9-8e5c-f491905a0c03.png)

## 説明項目
- ログイン
- アプリ構造

# ログイン
アプリインストールからログインまでの手順を説明します。
ストアから落としていくつかの入力項目を入力してログイン可能です。

### 1)アプリインストール
App Store,Google Playから下記をインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/31c54ef7-be3d-d14c-6848-f949c9576583.png)
### 2)ログイン操作.1
インストールしてアプリ起動するとログイン操作に移ります。
下記画面に遷移するので、2つの項目を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/4fd1afc6-269d-2ebe-5f4c-4a5c24f00b3b.png)
- インスタンスURL(https://dev-xxxxx.servicenow.com)
- ニックネーム(オプショナル項目なので空欄でOK)

### 3)ログイン操作.2
上記入力項目を満たすと、次画面に遷移する。
下記画面では、インスタンスのUser name,Passwordを入力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/a0c4604e-eebb-a63a-a574-c3f71d0566a4.png)

# アプリ構造
モバイルアプリは4層構造になっている。
- Scoped application
- Mobile app file
- folder
- applet

それぞれの担当領域をレイヤー(階層)で管理して、責任範囲を分離させている。
1がコアサイドで4がクライアントサイドとなっている。
実際の対応関係は下図を参照のこと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/199d3eaa-70ec-15dd-602b-f260a5f4e094.png)
下記は解説画像である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190712/b8a2d514-5ebb-e511-ee0f-5b63b7a1d97f.png)
Amazon Linux 2 にPostgreSQL 11 をインストールする

## 概要

AWSのEC2インスタンスを Amazon Linux 2 で作成し、PostgreSQL11のクライアントをインストールしようとしたところ少しハマったので手順を書きます。

## 実行環境

Amazon Linux release 2 (Karoo)

## 手順

インストール手順

```
$ sudo rpm -ivh --nodeps https://download.postgresql.org/pub/repos/yum/11/redhat/rhel-7-x86_64/ここに取得したいRPMを入れて
```
※以下のリンクから取得したいバージョンのRPMを確認し、上記コマンド末尾を書き換えて実行すること。
https://download.postgresql.org/pub/repos/yum/11/redhat/rhel-7-x86_64/
例えばPostgreSQL11.2を取得したい場合、以下のRPMに書き換える。
postgresql11-11.2-2PGDG.rhel7.x86_64.rpm

上記コマンド実行後、 PostgreSQLのリポジトリ設定について確認する。

```:/etc/yum.repos.d/pgdg-redhat-all.repo
一部を確認したいだけなのでpgdg11部分のみ抜粋
[pgdg11]
name=PostgreSQL 11 $releasever - $basearch
baseurl=https://download.postgresql.org/pub/repos/yum/11/redhat/rhel-$releasever-$basearch
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-PGDG
```

リポジトリファイルには変数 \$releasever と \$basearch があるが、AmazonLinux 2 では、 \$releaserver は system-release のバージョン番号で、\$basearch はアーキテクチャのようだ。
確認したところ、 system-release は "release 2" なので \$releaserver は "2" となる。
$basearch はアーキテクチャで "x86_64" となる。

```
$ cat /etc/system-release
Amazon Linux release 2 (Karoo)

$ arch
x86_64
```

つまり、この場合、リポジトリに記載されているbaseurlは
"https://download.postgresql.org/pub/repos/yum/11/redhat/rhel-2-x86_64"
になるのだが、そのようなパスは存在しないので404になる。
AmazonLinux2 はredhat7をベースにしているようなので、
"https://download.postgresql.org/pub/repos/yum/11/redhat/rhel-7-x86_64"
としたい。そのため、以下のコマンドで一括置換する。

```:/etc/yum.repos.d/pgdg-redhat-all.repo
sudo sed -i "s/\$releasever/7/g" "/etc/yum.repos.d/pgdg-redhat-all.repo"
```

あとはインストールするだけ。必要なものをインストールすればよいですが、ここではクライアントのみインストールする例。

```
$ sudo yum install -y postgresql11
```

以上！

## 追記(2022/10/25)
amazon linux 2 で PostgreSQL 13 をインストールしてみました。
記載通りでだいたい問題ないですが、私の環境では以下のファイルがなかったので作成しました。
`/etc/yum.repos.d/pgdg-redhat-all.repo`
また、GPGkeyファイルもなかったので、以下の場所から取得し、pgdg-redhat-all.repoのgpgkeyを同じファイル名に書き換えるとうまくいきました。

取得ファイル：RPM-GPG-KEY-PGDG-13
https://apt.postgresql.org/pub/repos/yum/
LeetCode / Sqrt(x)

（[ブログ記事](https://mhiro216.hatenablog.com/entry/2019/07/23/090750)からの転載）

[https://leetcode.com/problems/sqrtx/]

Implement int sqrt(int x).

Compute and return the square root of x, where x is guaranteed to be a non-negative integer.

Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.

Example 1:
Input: 4
Output: 2

Example 2:
Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since the decimal part is truncated, 2 is returned.

どの言語にも用意されている平方根（ルート）を求める関数を実装してみなさい、という問題です。
もちろん、全ての値をIterativeに確認するのではない方法が求められます。

#### 解答・解説

##### 解法1
コーディング問題でちょいちょい出てくるバイナリサーチで解きます。[以前の記事](https://mhiro216.hatenablog.com/entry/2019/07/17/203239)にも登場しました。
改めて説明を載せておくと、バイナリサーチは日本語で言えば二分探索となりますが、その名の通り検索対象を2つに分けて探索の効率を上げます。
具体的には、ソート済みの配列に対する検索を行うにあたり、 中央の値を見て、検索したい値との大小関係を用いて、検索したい値が中央の値の右にあるか、左にあるかを判断して、片側には存在しないことを確かめながら検索していく手法です。

今回は変数xに対して、その平方根sqrt(x)がxより小さい値の中でどれなのかを特定する問題なので、
0からxまでの整数のリストに対してバイナリサーチをかけます。

```python
class Solution:
    def mySqrt(self, x: int) -> int:
        l, r = 0, x
        while l <= r:
            mid = l + (r-l)//2
            if mid*mid <= x < (mid+1)*(mid+1):
                return mid
            elif x < mid*mid:
                r = mid
            else:
                l = mid + 1
```

これまた繰り返しの注意点となりますが、l + (r-l)//2のところで(r+l)//2としていないのは、和がオーバーフローしてしまうのを回避するためですね。
VS Codaでよく使われるショートカットキーまとめ

業務で「Visual Studio Coda(VSCoda)」を使用する上でショートカットキーをしっかり把握し、活用することが重要だとアドバイスをもらいました。
覚えるため、慣れるためにもよく使われそうなショートカットをまとめてみました。

こちらの記事で紹介しているものがすべてではありません。
あくまで初心者が最低限使えた方がよいものをまとめています。

- 基本動作
- ファイル操作
- PC起動関連(おまけ)

# 基本動作

|動作|ショートカットキー|
|---|---|
|コピー|`Ctrl` +`(C)` |
|切り取り|`Ctrl` +`(X)` |
|ペースト|`Ctrl` +`(V)` |
|戻す|`Ctrl` +`(Z)` |
|下に行追加|`Ctrl` +`Enter` |
|上に行追加|`Ctrl` +`Shift` +`Enter` |
|選択行を削除|`Ctrl` +`Shift` +`(K)` |
|行を下にコピー|`alt` +`down` |
|行を上にコピー|`alt` +`up` |
|行を選択|`Ctrl` +`(D)` |
|下方向に複数行を選択|`Ctrl` +`Shift` +`down` |
|上方向に複数行を選択|`Ctrl` +`Shift` +`up` |
|行をコメントアウト|`Ctrl` +`/` |
|検索|`Ctrl` +`(F)` |
|置換|`Ctrl` +`(H)`|

# ファイル操作
|動作|ショートカットキー|
|---|---|
|新規ファイル作成|`Ctrl` +`(N)` |
|保存|`Ctrl` +`(S)` |

# PC起動関連(おまけ)
|動作|ショートカットキー|
|---|---|
|シャットダウン|`Windowsキー` + `(X)` →`(U)` →`(U)` |
|スリープモード|`Windowsキー` + `(X)` →`(U)` →`(S)` |
|サインアウト|`Windowsキー` + `(X)` →`(U)` →`(I)` |
|再起動|`Windowsキー` + `(X)` →`(U)` →`(R)` |

# まとめ
ざっと覚えておくべきショートカットキーをまとめてみました。
仕事や作業をしている際に「この作業面倒くさいな」と思ったら、ショートカットキーがあるかどうか確認してみようと思います。

最初からすべて覚えることは難しいですが、仕事をする中で少しでも慣れていこうと思います。
EC2起動時に自動でユーザーを追加し、諸々の設定をする方法メモ

# 概要
`user-data`を用いることで、EC2の起動時に任意のシェルを実行することができます。

それを用いて、`①EC2起動時にユーザを作成し`、`②そのパスワードを設定し`、`③パスワード認証でのsshを許可させる`、という処理を行います。

# シェルの中身
CentOS7で動くことを確認しています。

```bash
#! /bin/bash

# ユーザの追加
useradd testuser
# パスワードの設定
echo "testpasswd" | sudo passwd --stdin testuser
# sudoの許可
sed -i -e '$ a testuser ALL=(ALL)    NOPASSWD:ALL' /etc/sudoers
# sshの際、パスワードでの認証の許可
sed -i -e 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
#　sshdを再起動し、設定を反映
systemctl restart sshd
```

# おまけ
AMIからEC2インスタンスを立ち上げると、Volumeが作成されます。私の会社では、この作成されたVolumeにタグをつけなければならないことになっているのですが、このタグ付の作業も、`user-data`の中で行えます。

以下のスクリプトは、aws-cliがインストールされている環境であれば動くと思います。

```bash
# このシェルが動いているEC2のインスタンスidを取得
instance_id=$(curl -s 169.254.169.254/latest/meta-data/instance-id)
# このシェルが動いてるEC2のregionを取得
az=$(curl -s 169.254.169.254/latest/meta-data/placement/availability-zone)
region=${az%[a-z]}
# インスタンスidから、インスタンス名を取得
instance_name=$(aws ec2 describe-instances --output text --region $region --instance-ids $instance_id \
  --query 'Reservations[].Instances[].Tags[?Key==`Name`].Value')
# このインスタンスに紐づくVolumeのidを取得
volume_id=$(aws ec2 describe-instances     --output text --region $region --instance-ids $instance_id \
  --query 'Reservations[].Instances[].BlockDeviceMappings[?DeviceName==`/dev/sda1`].Ebs[].VolumeId')
# タグをつける
aws ec2 create-tags --region $region --resources $volume_id --tags Key=SomeKey,Value=SomeValue
aws ec2 create-tags --region $region --resources $volume_id --tags Key=OtherKey,Value=OtherValue
```
Vagrant上のLubuntuでVSCode+Docker環境を作りたい~Lubuntu構築編~

# 対象としている人

VisualStadio CodeのRemote-Containerを使いたいけど、Windows10 Homeな人。
（どんだけニッチなんだよ）

# 経緯

Remote-Containerを使おうと思ったらDockerToolboxは対応していなかったし、
かといって、ProにしてもVirtualBoxが使えなくなるらしいので、じゃあ、もう開発用の環境作ろうかなと。

# 前提

- VirtualBoxが入っている
- Vagrantが入っている
- OSがWindows10である

# Lubuntu on VirtualBox

1. [Lubuntuのダウンロードページ](https://lubuntu.net/downloads/)よりisoイメージを取得  
   この時は19.04が最新バージョン
1. **Install Lubuntu**をダブルクリック
    ![VirtualBox_lubuntu_23_07_2019_05_45_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128200/f516af11-e2e1-539f-7781-80b3901952f6.png)
1. 言語とタイムゾーン、キーボードを選択
    ![VirtualBox_lubuntu_23_07_2019_05_47_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128200/bd6520bc-1a26-148b-4841-ba059e6092c4.png)
    ![VirtualBox_lubuntu_23_07_2019_05_48_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128200/e499c05c-5035-7145-7901-558331582492.png)
    ![VirtualBox_lubuntu_23_07_2019_05_48_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128200/46e4c370-9f4f-0248-fbc6-e26f86ed2576.png)
1. パーティションを自動で作成（面倒くさそうだったから）
    ![VirtualBox_lubuntu_23_07_2019_05_49_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128200/5507715f-4dbb-08ef-57ca-816e82a0580b.png)
1. ユーザ名をvagrantにする。パスワードも同じ。
    ![VirtualBox_lubuntu_23_07_2019_05_51_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128200/b0e42380-1481-0ff6-326a-87959a02692c.png)
1. インストール内容を確認して、「今すぐインストール」を押下
    ![VirtualBox_lubuntu_23_07_2019_05_51_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128200/e7e46321-a2c2-98ff-53b7-f242796cdfe8.png)
![VirtualBox_lubuntu_23_07_2019_05_49_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128200/974928bf-71b2-66db-a17f-1f69ac72dc3b.png)

1. 再起動して完了
   ※再起動を押したつもりだけど、なかなか再起動されず、結局VBから電プチ

以上、今日はここまで。
次回VagrantBoxにするためイジイジする

## 追記(19.08.09)

[Vagrant Box化編](https://qiita.com/hatman621221/items/30d6339cdeac83755204)を書きました。
python-cgiで超シンプルな画面遷移を書く

# cgiとは
Common Gateway Interfaceの略称。
Webサーバが、Webブラウザの要求に応じて、外部プログラムを呼び出し
その実行結果をWebブラウザに送信する仕組み。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259302/26813d60-f67a-8113-34d9-f50d26071318.png)


# 仕組み
Webサーバーにブラウザからアクセスすることで
Pythonファイルが実行され、
その処理結果をhtmlとしてWebサーバーに返却する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259302/c546c345-f004-9d77-67a8-6e16d2c9aeee.png)
本記事では、返却するhtmlを別ファイルとして定義し、
Pythonファイルの中でそのhtmlファイルを読み込んでいます。


# ディレクトリ構成
```
├── cgiserver.py
├── cgi-bin
│   └── test.py
└── html
     ├── view_001.html
     └── view_002.html
```

※ cgiserver.py, cgi-bin以外は任意の名称で良いです。

# サンプルコード(Python)

```python
#!/usr/bin/python3
# -*- coding: utf-8 -*-

import cgi
import codecs

form = cgi.FieldStorage()

# 初回ロード時
if form.list == []:
    html = codecs.open('./html/view_001.html', 'r', 'utf-8').read()
# SUBMITボタン押下時
else:
    html = codecs.open('./html/view_002.html', 'r', 'utf-8').read()
    
print("")
print(html)
```

### import cgi
Pythonの標準ライブラリであるcgiモジュールを
インポートすることでpython-cgiを使えるようになります

### print()
Pythonファイルをcgiプログラムとして実行すると
print()の出力は標準出力ではなく
Web画面への描画になります。

本記事では、
L.17でprint()にhtmlタグを渡すことでWebページを表現しています。

### codecs.open()
描画するhtmlファイルの内容を(String型として)読み込みます。
それを最後にprint()に渡すことでWeb画面に描画します。

### cgi.FieldStorafe()
このクラスをインスタンス化することで
クライアント側のフォームの情報を取得できます。

この取得した情報によって処理を分岐することで、描画するhtmlを振り分けています。


# サンプルコード(html)
Web画面に描画したいhtmlソースをそのまま記述します。

### view_001.html
```html
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<head>
  <title>topPage</title>
</head>
  <p>This is Top Page.</p>
  <form name="formSubmit" action="test.py">
    <input type="submit" name="button" value="SUBMIT">
  </form>
</body>
</html>
```

### view_002.html
```html
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<head>
  <title>movedPage</title>
</head>
  <p>Success Page transition</p>
</body>
</html>
```

# 動かし方
cgiserver.pyがある階層まで移動して以下のコマンドを実行して、Pythonサーバーを立ち上げます。

`python -m http.server --cgi`

その状態でURLを指定してアクセスします。
`http://localhost:8000/cgi-bin/cgibin.py`

すると、Pythonファイルで出力しているhtmlがブラウザに表示されます。

![img_0722_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259302/794cf33d-334e-5260-7256-54d70888b0e6.png)

ボタンを押下すると、Pythonで処理している通りに、表示するhtmlが切り替わります。

![img_0722_002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259302/e12e7ed0-7ab9-8382-3f21-36381695f20d.png)


# まとめ
python-cgiモジュールを使うことでPythonでWeb画面処理、サーバー処理を実現出来ました。

今回はシンプルな画面遷移だけ触れましたが、
cgi.FieldStorage()を上手く使うことで
Webページ間のデータの受け渡しやクライアント側のフォームの内容での処理分岐なども実現できます。
Intellijから実行/テストするときもHOCONへ任意の環境変数を渡したい

# シチュエーション

```conf:application.conf
detabesu.username = john.doe
detabesu.password = ${PASSWORD}
```

以下の理由などにより一部の設定値を環境変数からHOCONを通じてプログラムへ渡している。

* 実行環境毎に異なる値を使いたい
* パスワードを設定ファイルに書き込みたくない

# 問題

sbt経由やパッケージング後に設定値を渡す場合は問題ないが、Intellijから直接実行したりテストを実行する場合はどうすればよいかわからない。

# 解決法

## Intellijの実行設定(Run/Debug Configurations)から環境変数を渡す(推奨)

![Screenshot from 2019-07-23 06-22-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30316/be1dfda3-2a4e-e8d0-48dd-9cb434ba3913.png)

上のように環境変数用の入力フォームが用意されている場合はそこへ入力すれば良い。

sbtから実行する場合などは環境変数用のフォームが用意されていない。このような場合はVM parametersを使う。

[lightbend/config: configuration library for JVM languages using HOCON files](https://github.com/lightbend/config)に

> users can override the config with Java system properties, `java -Dmyapp.foo.bar=10`

のように書かれている通りJavaのシステムプロパティを使うことでHOCONへ任意の値を渡すことができる[^1]ので、

![Screenshot from 2019-07-23 06-24-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30316/8f00910e-99c4-a67b-b2a3-10e9f7776ec2.png)

画像のように `-D環境変数名=値` のフォーマットで記述する。

[^1]: 厳密には環境変数とシステムプロパティは違うものであるが、今回は話を単純にするためあえて混同して書いている

## Intellijそのものへ環境変数を渡す(非推奨)

あまり推奨できない。というのはここで設定した環境変数は開いているプロジェクトなどに関わらず一律設定されてしまうため、異なるプロジェクトで同じ環境変数名を使って異なる値を設定したい場合などに混乱が起きやすいため。

### Linuxの場合

Intellijの起動コマンド前に環境変数を渡してやればよい。

```sh
PASSWORD=abc idea&
```

ubuntuのlauncherなどに登録している場合、まず.desktopの場所を特定する。

```shell
locate intellij-idea-community_intellij-idea-community.desktop
```

その後[.desktopファイルのExec部分を書き換え、任意の環境変数を渡す](https://askubuntu.com/questions/144968/set-variable-in-desktop-file)。

```ini:intellij-idea-community_intellij-idea-community.desktop
[Desktop Entry]
Type=Application
Name=IntelliJ IDEA Community Edition
Exec=env PASSWORD=abc /snap/bin/intellij-idea-community %f
Terminal=false
StartupWMClass=jetbrains-idea-ce
```

### MACの場合

Linuxと同様だが、.desktopファイルに当たるものはなく、それに当たるlaunchctlを使った設定方法はかなり手間がかかる。

* [Macでの環境変数（environment variables）の設定方法 \- Qiita](https://qiita.com/hoisjp/items/19374252db8e748c3407)

### Windowsの場合

TBW
SQL の基本的な操作（インストール、スクリプトの実行、削除、検索など）（備忘録）

# 概要
SQL を久しぶりに（1年ぶり以上前に授業で軽くやって以来）触ったので（軽くだが）簡単にまとめておく

## 環境構築（Sqlite3のダウンロード）
sqllite3はc言語で書かれたSQLの環境DBMSらしいです。
https://www.sqlite.org/download.html から自分の環境にあったものをダウンロードする。

僕はMacなので
Precompiled Binaries for Mac OS X (x86)
をダウンロードした。

`export PATH=~/Downloads/tmp/install/sqlite-tools-osx-x86-3290000/sqlite3:$PATH`みたいな感じで
パスを通すと、sqlite3と打つだけで使えるようになる。

## SQLとは？
>関係データベース管理システム (RDBMS) において、データの操作や定義を行うためのデータベース言語（問い合わせ言語）、ドメイン固有言語である。
[wiki](https://ja.wikipedia.org/wiki/SQL)より

ということである。

　要するに、DBを扱うときの標準的な（国際規格が決まっている）DB用の言語である。（という認識でいいと思う）

　また、SQLでデータベース（DBMS）に行う処理をクエリと言います。
SQLは基本的には、１つの文で１つの処理が完結するように作られています。
（全てワンライナーと考えると不思議）

　また、理由は不明だが、SQLの命令は全て大文字で記述します。

# データベースとテーブルの定義
　SQLは複数のテーブルを連携して扱うことができます。（例えば、生徒と期末試験の関係のテーブルと、生徒と出席日数の関係のテーブル　の２つから、試験の成績と出席日数の関係の表を作るなど）
　
　この、関連した複数のテーブル（表）のまとまりをデータベースと言います。

## データベースの操作
作成
 CREATE DATABASE を使います.
中身のテーブルはベット作る必要があります。
（スペースが入るのが気持ち悪い。。）
` CREATE DATABASE name_db;`

削除
DROP DATABASE を使います。
`DROP DATABASE name_db;`

現在対象とするデータベースの指定
USE　
`USE name_db`

## テーブル操作
テーブルの作成
`CREATE TABLE` でカラムの内容（それぞれの列の内容（カラム名とデータ型など）、primary keyをどれにするかなどを指定します）を指定します（フィールド定義）。
`DESC`(descrive)でテーブルの内容を確認することができます。

新規の行（行データ）挿入
INSERTを使う。ただし、
`INSERT table_name SET cullum_name=value`で設定する方法と
`INSERT INTO table_name(cullum1,cullum2..) VLAUES(val1,val2..)`

行データの更新
`UPDATE table_name SET cullum2=val2,... WHERE cullum1=val1`

行データの削除
`DELETE FROM table_name WHERE cullum1=val1`

データの検索
`SLECT * FROM table_name WHERE cullum=val1`
一部のカラムのみを取ってきたい場合は、欲しいカラムの名前を列挙する


## その他
### sqlite3での実行方法
`sqllite3 DBname`
で対話環境に入る。

スクリプトを実行したい場合は
対話環境内で 
`sqlite> .read script.sql`の形で実行するか

sqlite3のコマンドに直接渡す
`sqlite3 test.db < select.sql`

などの方法があります。

また、追記します。

# 参考
https://ja.wikipedia.org/wiki/SQL
https://rfs.jp/sb/sql/s01/03-13.html
https://l-w-i.net/t/sqlite/ext_001.txt
Good Morning!

![GIRASSOL.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386465/3c8763d8-97cb-8793-890c-15b01ef5519d.jpeg)


Good Morning! That every morning, you feel in your heart the certainty that life awaits you with open arms, to receive your expectations and accomplish them one by one.
UnityでWebGL向けにビルドしたゲームをlocalhostで立ち上げてブラウザで動作確認する

## 概要

Unityでゲームを作ってWebGLでビルドすると、簡単に配布できて便利ですよね。
このビルド結果について、ブラウザで立ち上げてカジュアルに動作確認したい場合があると思います。

しかし、WebGLでビルドしたディレクトリにあるindex.htmlをそのままブラウザで開くと

```
It seems your browser does not support running Unity WebGL
content from file:// urls. Please upload it to an http server, or try a
different browser.
```

となり、起動できません。これは、httpサーバーを用意してそこに配置してねという意味ですが、正直めんどすぎます。

## 一般的な方法

XAMPPをインストールしてhtdocsを設定して確認する方法があるようです。

> 【Unity】WebGL でビルドしたゲームを起動する方法 - コガネブログ
> http://baba-s.hatenablog.com/entry/2017/11/01/093000

> UnityでWebGL出力 – それは悲しみ(˘ω˘ ) 
> https://boccilog.wordpress.com/2016/05/08/unitywebglbuild/

ただ、これも正直めんどすぎます。もっとお手軽にやりたいです。

## 静的ファイルにアクセスするWebServerを立てる

こう書くと大げさに見えますが、goだとかなり簡単にかけます。

> SimpleWebServer
> https://gist.github.com/xshoji/19dbd8bf35ab37950680d8016084f1a0#file-00_simplewebserver-md

 - Go入ってるひと:↑のmain.goをそのまま`go run main.go`で動かしてもらって問題ないです
 - Go入ってない人:mac, linux, windows向けにビルド済みのバイナリも用意しておきました。DLしてお使いください
   - [macの人](https://gist.github.com/xshoji/19dbd8bf35ab37950680d8016084f1a0/raw/d4ceb94faa5d254a67dca4f13bfd6ea411501ac0/webserver_mac)
     - macだとterminalからの初回実行時に「開発元を検証できません」と出てしまうので、DLしたバイナリを右クリックして「開く」で開くと、次回以降問題なく実行できます
   - [windowsの人](https://gist.github.com/xshoji/19dbd8bf35ab37950680d8016084f1a0/raw/d4ceb94faa5d254a67dca4f13bfd6ea411501ac0/webserver_win.exe)
   - [linuxの人](https://gist.github.com/xshoji/19dbd8bf35ab37950680d8016084f1a0/raw/d4ceb94faa5d254a67dca4f13bfd6ea411501ac0/webserver_linux)

使い方は（READMEにも書いてますが）

```
$ ./webserver_mac -h
Usage: ./webserver_mac [OPTIONS] [-h, --help]

Description:
  A lightweight simple web server written in Go.

Options:
  -d string    [RQD] Path of document root directory ( e.g. /path/to/dir )
  -p string    Port (default "8080")

$ ./webserver_mac -d /tmp/unity/webgl_app_dir/ -p 9000
Document root : /tmp/unity/webgl_app_dir/
URL           : http://localhost:9000
```

`-d`で、UnityでビルドしたWebGLのアプリのDirectoryを指定してください。ポート番号はお好みで。

これで、`http://localhost:9000`にアクセスすれば、ビルドしたWebGLのゲームが起動します。お手軽です。
C#で様々なライブラリのVector構造体を相互運用 (LayoutKind, Spanを使う方法)

# はじめに
(心の声) **System.Numerics.Vector3 からOpenTK.Vector3に変換できない！**
周辺の小さなライブラリでVectorを使いたいときはSystem.Numerics.Vector3で作成し、いざ3D系(OpenTK)アプリで使用しようとするとOpenTK.Vector3に変換しないといけない。実態は両方ともfloat * 3 のメモリなのに....

世の中には様々なVector系構造体があります。System.Numerics.Vector3をはじめとして、OpenTKや3dの各種ラップライブラリでVector構造体が宣言されています。
ほぼすべての構造体がfloat * 3 (x,y,z)のフィールドを持ちますが、相互に変換となるとnewしなおすしかありません。float * 3だと、Marshalやポインタを使ったアプローチはコストに見合わなさそう。

ということで、構造体のメモリレイアウトを重ねることで複数種類のVectorを取り出そうというのが今回のアプローチです。

早速ですが、答えは以下になります。FieldOffsetでメモリの位置を重ねています。

```C#
[StructLayout(LayoutKind.Explicit)]
public struct Tvec
{
  [FieldOffset(0)]
  public System.Numerics.Vector3 nvec;
  [FieldOffset(0)]
  public OpenTK.Vector3 tkvec;
  [FieldOffset(0)]
  public float X;
  [FieldOffset(4)]
  public float Y;
  [FieldOffset(8)]
  public float Z;
}
```

使ってみます。

```C#:Mainと実行結果
void Main()
{
  System.Numerics.Vector3 vecn = new System.Numerics.Vector3(1, 2, 3);
  Tvec vec = new Tvec();
  vec.nvec = vecn;
  Console.WriteLine("OpenTK->" + vec.tkvec.ToString());
  Console.WriteLine("System.Numerics->" + vec.nvec.ToString());
  Console.WriteLine("float X->" +vec.X);
  Console.WriteLine("float Y->" +vec.Y);
  Console.WriteLine("float Z->" +vec.Z);
}
---------------------------
OpenTK->(1, 2, 3)
System.Numerics-><1, 2, 3>
float X->1
float Y->2
float Z->3
```

めでたしめでたし...
と言いたいところですけど結局vec.nvec = vecn;で構造体コピーしてるわけだから普通にnewすれば良かったというオチです。相互に何度も行き来するときはこちらの方がよいのかな？

---
(追記 19.08.15)
ちょっとふがいないのでnewせずにメモリを共用する方法も記載します。
最近使用できるようになったSpanを使用します。
.Net Core2.1以上でない場合、nugetからSystem.Memoryをインストールします。

``` C#
System.Numerics.Vector3[] n_vec = new System.Numerics.Vector3[]
{
  new System.Numerics.Vector3(1,0,0),
  new System.Numerics.Vector3(0,1,0),
  new System.Numerics.Vector3(0,0,1),
};
var n_vec_span = n_vec.AsSpan();
var tk_vec_span = MemoryMarshal.Cast<System.Numerics.Vector3, OpenTK.Vector3>(n_vec_span).ToArray();
```

たぶんこの方法が最近の現実解な気がします。
Vue.jsにてGeolocation APIで取得した値をdataプロパティに設定する

## 概要
端末の現在地を取得するGeolocation APIをVueで使用してみたのですが、dataプロパティに取得した結果がセットされなかったので、その時の対応を記載。

## 前提
Geolocation APIについては、@akkey2475さんの[Geolocation APIでPCやスマホの位置情報を取得する](https://qiita.com/akkey2475/items/81f4f94f17bfe5c7ce42)にまとめられています。このJavaScriptのコードで、Vueにおいて位置データを取得します。

## 前提
取得したデータをdataプロパティにセットする際、成功時の関数に「this」をbindします。参考記事は[Vue method not working from inside other method](https://stackoverflow.com/questions/53260822/vue-method-not-working-from-inside-other-method)になります。

## サンプルソース
現在地を取得して、緯度・経度を表示するサンプルソースです。

```SamleComponemt.vue
<template>
  <div>
    <div>
      {{latitude}}、{{longitude}}
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      latitude: 0,
      longitude: 0
    }
  },
  mounted() {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
        function(position){
          let coords = position.coords;
          // 緯度経度だけ取得
          this.latitude = coords.latitude;
          this.longitude = coords.longitude;
        }.bind(this),
        function(error) {
          // エラー処理を書く
        }
      );
    } else {
      // エラー処理を書く
    }
  }
}
</script>
```
Atom の地味で便利なパッケージ

私は Atom で使っているコミュニティパッケージはかなり厳選しているつもりで、言語のシンタックスハイライトを除くと、次の４つだけを入れている。

- [file-icons](https://atom.io/packages/file-icons) アイコンの見た目を分かりやすくする。
- [indent-detective](https://atom.io/packages/indent-detective) インデントのスペースの数を自動判定する。
- [latex-completions](https://atom.io/packages/latex-completions) LaTeX 記法で記号や絵文字を入力できるようにする。
- [open-file](https://atom.io/packages/open-file) `Alt` + `W` で編集しているファイルをOSの指定するアプリケーションから開く。

file-icons は有名だと思うが他の３つはあまり知られていないと思う。どれも地味だが便利なのでおすすめである。特に latex-completions は数学の記号を使う人にとって革命的に便利である。