OmniAICreator/Qiita-1.07M huggingface dataset:
【Unity(C#)】Rayではなく内積(Vector3.Dot)で視線判定を行う

##視線
VRで視線判定をけっこう使うのでメモしときます。

[Rayを使用した視線の判定](https://qiita.com/OKsaiyowa/items/5bf32ec513bcd987ab8e)も十分簡単にできます。
"目(カメラ)からビーム出してビームがターゲットに衝突したら処理を行う"
ただこれだけです。

ただし、障害物があるとLayerやTagで衝突を避ける設定をする必要があります。

今回は会社の上司に教えてもらった
LayerやTagを一切気にしなくてもいい方法で実装してみようと思います。


##内積
まずは内積とは何かを一言で説明したいのですが、
一言で表すとなると全く思いつきませんでした。

私の理解もその程度だということなので、複数のリンクを貼っておきます。
個人的に動画の解説が一番しっくりきました。

Qiita記事 :[【数学】「内積」の意味をグラフィカルに理解すると色々見えてくる その１](https://qiita.com/kenmatsu4/items/a144047c1b49aa8c7eb0)

Youtube : [喋り方の癖だけ耐えればめちゃめちゃわかりやすい動画](https://www.youtube.com/watch?v=2aoyhQzmnAI&t=215s)

Youtube : [シンプルにわかりやすい動画](https://www.youtube.com/watch?v=pTE5y9cBUzs&t=571s)


##コード
たったこれだけです。

```C#:カメラにアタッチ
using UnityEngine;

public class Dot : MonoBehaviour
{
    [SerializeField]
    Transform targetTransform;

    Transform cameraDirection;

    void Start()
    {
        cameraDirection = this.gameObject.GetComponent<Transform>();
    }

    void Update()
    {
        //ターゲットからカメラの方向へ正規化したベクトルを作成
        Vector3 targetToCameraDirection_N = (cameraDirection.position - targetTransform.position).normalized;

        //正規化したベクトルの内積が一定以下なら見たことにする
        if (Vector3.Dot(targetToCameraDirection_N, cameraDirection.forward.normalized) < -0.9)
        {
            print("見た！");
        }
    }
}
```

##normarized
ベクトルを正規化してくれます。
問答無用で値を1にしてくれるってことです。(ただし小さすぎると0になるので注意)

`normarized`を利用することで、2点の位置から算出したベクトルを
常に一定の大きさで取得することができます。

##Vector3.Dot
二つのベクトルを渡してあげるだけで内積を返してくれます。([参考リンク](https://docs.unity3d.com/jp/460/ScriptReference/Vector3.Dot.html))
![B292E9AE-1C23-44DB-8684-C87F4EEC9C84.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/e2532c6b-1d03-d698-dd39-87725e880a95.png)


lhs,rhsは`Left(Right) hand side`の略らしいです。

今回はVector3.Dotを利用して**内積が-0.9(約cos155°)**以下になると見たという判定にしています。

**人間の有効視野の上限は20~30度**だといわれている[^1]ので
完全に視線が一致(内積が-1(cos180°))するまで判定させないより
**だいたいこの辺りを見たと判断させる**方が良い方法だと思います。

・ターゲットの位置からカメラの位置へ向けたベクトル
・カメラの正面方向(Z軸正の向き)のベクトル
↑これらのベクトルから内積を計算してます。

##デモ
視線判定の範囲内に入ると赤色に変わるようにしたデモです。

![Gif_Dot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/659832b8-5a52-0561-04b3-944ff6fc0eda.gif)

`-0.9`を`-0.95`のように-1に近づけてあげるともっと厳格な視線判定もできます。
　　

大学はおろか高校ですら ろくに数学をやってこなかったので間違いがあれば
遠慮なくご指摘ください。

[^1]: 参考リンク [①](https://xr-hub.com/archives/3095) [②](https://www.omoiyari-light.com/LAB/INTERVIEW/000812.html)


##視錐台
2019/11/08　追記

興味深い記事を見つけたので関連として貼っておきます。
[【Unity】【数学】視錐台（Frustum）について（第2回）](https://logicalbeat.jp/blog/831/)

`視錐台の内判定` = `見えている範囲` = `Unityのカメラの描画範囲` ≠ `VR(HMD越し)の視界`
なので、VRへの応用は許容誤差が範囲内であれば、、、といった感じでしょうか。

```C#:logicalbeat様　記事引用
// 視錐台平面を獲得
Plane[]	planes = GeometryUtility.CalculateFrustumPlanes( camera );
System.Array.Resize( ref planes, 4 );		// near,far面を排除

// 内外判定
if ( GeometryUtility.TestPlanesAABB( planes, bounds ) ) {
	// 入った！！
}
```
WebStorageを使う

#WebStorageとは
HTML5から導入されたブラウザにデータを保有する仕組み。
localStorageとsessionStorageの二つがあり、それぞれ有効期限が異なる。らしい。

|WebStorage|有効期限|
|----|----|
|localStorage|無期限|
|sessionStorage|ブラウザが閉じられた時|

https://developer.mozilla.org/ja/docs/Web/API/Window/localStorage
 

# 書き方
## 値設定
```css
localStorage.setItem('set_local', this.local);
sessionStorage.setItem('set_session', this.session);
```
 
## 呼び出し
```css
const val_local = localStorage.getItem('set_local');
const val_session = sessionStorage.getItem('set_session');
```
# 使ってみる（Vue.js）
```html
<body>
    <div id="app">
        <p>localStorage：<input type="text" v-model="local" v-on:change="setLocal"></p>
        <p>sessionStorage：<input type="text" v-model="session" v-on:change="setSession"></p>
    </div>
 

    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script>
        var app = new Vue({
            el: '#app',
            data() {
                var val_local = localStorage.getItem('set_local');
                var val_session = sessionStorage.getItem('set_session');
                return {
                    local: val_local,
                    session: val_session,
                }
            },
            methods: {
                setLocal: function (event) {
                    localStorage.setItem('set_local', this.local);
                },
                setSession: function (event) {
                    sessionStorage.setItem('set_session', this.session);
                }
            }
        });
    </script>
</body>
```
localのほうはブラウザ閉じても保持されて、sessionのほうは破棄されることを確認。
ローカル環境で作成したWordPressテーマをリモートで公開する方法

環境
・MacOS Mojave 10.14.3

まずはXAMPPにてテーマを作成
<img width="1444" alt="スクリーンショット 2019-05-18 11.33.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/270ecab3-151d-e651-0b6a-bf2ef438079c.png">

zipファイルに圧縮
<img width="417" alt="スクリーンショット 2019-05-18 11.35.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/79d351aa-c3a9-0c76-5cfc-adfd838eedc3.png">

適用したいWordPressのサイトに管理者画面でアクセス
<img width="275" alt="スクリーンショット 2019-05-18 11.40.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/2ea6e990-4e1e-fb7e-483f-a05bfc7cc51a.png">

テーマ選択画面へ進む
<img width="1255" alt="スクリーンショット 2019-05-18 11.41.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/2c4f39c0-8552-6567-1ea9-ab3f13b547dd.png">

「新しいテーマを追加」をクリック
<img width="1271" alt="スクリーンショット 2019-05-18 11.43.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/3bb88db2-3b11-bb3f-d9aa-7378d30f88c4.png">

「テーマのアップロード」をクリック
<img width="1271" alt="スクリーンショット 2019-05-18 11.45.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/5f77dd45-8ab2-fcf1-28d8-ea1eacf86b5f.png">

ファイルを選択から、先程圧縮したzipファイルを選択〜インストール
<img width="1271" alt="スクリーンショット 2019-05-18 11.46.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/3d835c37-c0c8-c026-4aa5-4006f11647b8.png">

この画面が表示されれば成功
<img width="980" alt="スクリーンショット 2019-05-18 11.51.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/9d5eea55-8691-e219-b6cb-a8c51d7cc0e3.png">
DataTablesを使う（レスポンシブ対応）

adminLTE3を触っていたらDataTablesを使っているようで、いろいろ調べてみたらとても便利だったのでまとめてみた

# DataTables

https://www.datatables.net/

## PC
![20190320112041.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309310/f9ae81db-3313-a531-8cba-eb61ed197cc0.png)


## スマホ
![20190320112154.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309310/e8dc01f7-9e48-5da5-53a4-442ee11b86e6.png)


# 書き方
## CDN
```html
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.18/r-2.2.2/datatables.min.css"/>
```
```html
<script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.18/r-2.2.2/datatables.min.js"></script>
```

## 呼び出し
```javascript
$(document).ready( function () {
    $('#myTable').DataTable();
} );
```

```html
<table id="myTable" class="table table-bordered table-striped dt-responsive nowrap" role="grid" aria-describedby="example2_info" style="width:100%">
  <thead>
      <tr role="row">
         <th class="sorting_asc">名前</th>
         <th class="sorting_asc">年齢</th>
          <th class="sorting_asc">身長</th>
          <th class="sorting_asc">誕生日</th>
       </tr>
       </thead>
       <tbody>
　　　　　......
```

# オプション
|class|効果|
|---|---|
|table-bordered|線を表示|
|table-striped|背景色を交互|
|dt-responsive|レスポンシブ|
|nowrap|折り返し禁止|


## レスポンシブ対応
レスポンシブのオプションを入れることでスマホサイズの時に適切なカラム数に調整した上で、落ちたカラムはアコーディオンでみれるようにしてくれる。

`dt-responsive` が大事みたい
Adobe XDでプレビューをスクロール可能にする

## 結論
右メニューのスクロールを「なし」から「垂直方向」に変更する。

## 作業内容

そのままアートボードのサイズを変更すると、プレビューのサイズも縦長になってしまう。

![スクリーンショット 2019-05-14 14.09.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234559/60e27c0f-d17e-9d53-7c91-283ef842fbce.png)

アートボードを選択して、右メニューのスクロールを「なし」から「垂直方向」に変更する。

![スクリーンショット_2019-05-14_14_13_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234559/a7e51793-e28c-ab41-10dc-3f31961d6053.png)

変更後、アートボードのサイズを変更すると、破線が表示されるようになる。

![スクリーンショット 2019-05-14 14.17.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234559/8de22eda-b21f-cc61-d693-f66f16a3ab87.png)

プレビューをすると、無事スクロール出来るようになっている。

![scroll_test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234559/097dc15b-08b3-0622-eb41-8e1f219d197c.gif)

## 参考

[Adobe XDのスクロール可能なアートボード \| Adobe XD チュートリアル](https://helpx.adobe.com/jp/xd/how-to/scrollable-artboards.html)

https://www.behance.net/gallery/67284971/Wires-jp
C70K2 レストア日誌 その5 〜 バッテリー＆マフラー交換 等

遅くなりましたが再開します。

# 購入した商品を付けていく

## 6V MFバッテリー（メンテナンスフリータイプ）
- http://www.out-standing.com/shopdetail/000000000373/

> 80年代の6V・C50スーパーカスタムにはぎりぎり入らないようです。

確かに入らない。↓
![20181130_112515.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230921/50f7c478-4074-289b-4272-357271af709e.jpeg)
↑ ぎりぎりあたって入らないの図

- バッテリーケースを取っ払ってMFなので横に設置。
    - 端子はビニテで絶縁しておいたほうが安全。

- 元のバッテリーは直接バッテリーから配線が生えているのでぶった切って流用。
![20181130_112511.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230921/c2059474-351e-cc6f-f2ae-566a15acacf0.jpeg)

- もともとついていたバッテリーが標準のものではなさそうだけども、 
写真の通り平端子を自作して接続する必要がある。（車体側の端子は丸端子）


## 「B級品」スチールモナカマフラー
![20181130_121120.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230921/098c58e9-b75a-a35a-5f5d-273da7574497.jpeg)

- 購入時に「この年式のモデルには適合していない」と言われたが自己責任で購入
    - 特に問題なく装着できた。
![20181130_122808.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230921/b1ea0f21-61d1-2a56-e3e1-4ea7e528dac8.jpeg)

- クリアランスがなかなかシビアそうではあるので個体差はあるかもしれない。
![20181130_122812.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230921/0387460d-8a31-b1cf-5de2-e2bd428d1304.jpeg)

- このモナカマフラーにはロークオリティなマフラーガスケットがついてくるが、とりあえずそのまま使ってる。
![20181130_121116.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230921/26de99d1-9ef5-7f4a-d1a6-c3f9db9a5cca.jpeg)

- 純正装着時についているコレは不要そう
![20181130_120749.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230921/cc2cf606-2dd6-d593-fac1-f8bf34fac4e5.jpeg)

## シングルシートS51 (旧カブ用)
- とりあえず載せてみた。
![20181130_103044.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230921/6aa0594a-364b-5a6c-ecd2-32dfb8859fa2.jpeg)

- どうやら最初についてきたシートステーはこのモデルには適合しないモデルぽい。車体側のステーの穴が微妙に合わなかった。
- しかもシート側も合わなかった。個体差なのかどうなのか，そもそも旧モデルに値するから合わなかったのかは、わからない。 ↓
![20181130_103127.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230921/e63ddf9e-62dc-125b-c01a-3c7038765c47.jpeg)
    - シート側の取り付けボルトがほぞいので若干斜めにして装着完了。今のところ問題なし。
![20181130_103110.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230921/5bc408d9-1ca3-d80d-3bd6-634138313ce3.jpeg)
MacでSublimeText3を使ったらコメントの日本語入力がEnterで消えた件

# 問題
MacでSublimeText3を使ったらコメントの日本語入力でEnterすると消えるという事象に遭遇

# 環境
Mac OS Mojave 10.14.4
SublimeText version 3.2.1

# 原因
Docblockrというパッケージでは`Enter`でコメント行（`//`や`*`）の自動入力を設定しているかららしい

# 解決策
Docblockrは削除したくないので、コメント行自動入力を`Shift + Enter`に変更する

# 方法
1. 下記サイトの説明にあるように、Default.sublime-keymapを差し替える
2. SublimeTextを再起動
3. コメントで日本語入力ができることと、`Shift + Enter`でコメント行自動入力ができることを確認

# 参考
https://gist.github.com/cw-masaki/5916759
adapter pattern

# adapter pattern
## ケース
インターフェイスにズレがあるとき

ズレ以外のロジックを入れ込まないように注意

targetがadapteeに依存する時

## 実装対象
client
target
adapter
adaptee

```
client:          target.request()
target.request:  adapter.request()
adapter.request: adaptee.uniqNameMethod()
```
webサーバーとアプリケーションサーバーの違い

## HTTP
私たちがwebページブラウザがwebサーバーに対してコンテンツを要求し、webサーバーは要求されたコンテンツをブラウザに対して返します。HTTPはこの一連のやりとりにおける通信のルール(プロトコル)です。この通信のルールが世界標準で決められているため、私たちはどの種類のブラウザであっても、世界中のどんなwebサーバーにもアクセスできるのです。

## URI
URIとはwebに存在する情報を名前をつけて識別するためのルールのことです。URIを使うことでwebに存在する全ての情報は一意のもので表現することができるようになるます。HTTPはURIを使ってwebサーバーからほしいコンテンツを指定することができます。URIとURLの違いとしてはURIが情報の識別するルールに対し、URLがURIにのっとり情報の場所を示したものになります。

## webサーバーとアプリケーションサーバー

### webサーバー
webサーバーはブラウザからのコンテンツのリクエストを受け取り、ブラウザにレスポンスを返す役割のが役割です。このときのリクエストがHTML、CSS、画像ファイルのような更新しない限り同じ表示コンテンツを表示する静的なwebコンテンツだった場合、webサーバーが処理してレスポンスを返します。そしてクライアントごとで表示内容を変化させる処理が必要な動的なwebコンテンツの場合、webサーバーはアプリケーションサーバーへとリクエストを送ります。アプリケーションサーバーから返ってきた結果をレスポンスとして返します。webサーバーとして NginxとApacheなんかが有名です。

### アプリケーションサーバー
アプリケーションサーバーは私たちが作ったRailsアプリケーションを動かしてくれるものです。webサーバーから送られてきたリクエストをアプリケーションサーバーからRailsアプリケーションに伝え、Railsアプリが処理した結果をwebサーバーに返します。ローカル環境下での開発の場合はPumaのようなRails用のアプリケーションサーバーのみを立てますが、本番環境ではwebサーバーをRailsアプリケーションの手前に置くことで、静的なコンテンツの処理を負担させることが多いです.RailsのアプリケーションサーバーとしてRainbows、Pumaなんかがあります。

### Rack
RackはRuby製のフレームワークとアプリケーションサーバーの間に入り、互いをつなぐ役割をしてくれます。送られてきたHTTPのリクエストをサーバーはRackを使用しアプリにも理解できる形に変換して伝えてくれる。逆にアプリからのレスポンスはRackを通じてHTTPに変換されてサーバーに返ります。Rackを使用することでサーバーとフレームワークの組み合わせが自由になります。

### まとめ
ここまでのことをまとめるとブラウザから送られてきたリクエストをwebサーバーが受け取り、静的なwebコンテンツだった場合レスポンスをブラウザに返します。しかし、リクエストが動的なwebコンテンツの場合webサーバーでは処理せず、アプリケーションサーバーに送り、アプリケーションサーバーがRailsアプリにRackを通して伝えます。結果を先ほどとは逆の順番でブラウザに返します。

具体的に言うとブラウザからNginx、NginxからPuma、PumaからRackを通してRailsアプリに伝わります。レスポンスはこの逆の順序となります。
PHP Carbonを使って現在時刻を固定する

メモ。
ちゃんとテストを書けばよいのだけど、ちゃちゃっと動作テストをしたい時に。
例えば、ある処理の間だけCarbon::now()を任意の時刻に固定したい。

`Carbon::setTestNow()` に引数を渡すと任意の時刻で固定できる。
引数なしで呼ぶとリセットされる。

## 事前準備

```
$ composer require nesbot/carbon

// 必要があればMonologやDebugbarを入れると良い
$ composer require monolog/monolog
$ composer require maximebf/debugbar
```

## サンプルコード

``` php:index.php
<?php

require 'vendor/autoload.php';

use Carbon\Carbon;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use DebugBar\StandardDebugBar;

$debugbar = new StandardDebugBar();
$debugbarRenderer = $debugbar->getJavascriptRenderer();

$logger = new Logger('my_logger');
$logger->pushHandler(new StreamHandler('./debug.log', Logger::INFO));

Carbon::setTestNow(Carbon::parse('2019-05-20 00:00:00'));
$logger->info(Carbon::now());

Carbon::setTestNow();
$logger->info(Carbon::now());

Carbon::setTestNow(Carbon::parse('2019-05-01 00:00:00'));
$debugbar['messages']->addMessage('Now is ' . Carbon::now()->toDateTimeString());

?>

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>テスト</title>
    <?= $debugbarRenderer->renderHead(); ?>
</head>
<body>
    <?= $debugbarRenderer->render(); ?>
</body>
</html>
```

## 実行

```
$ php index.php

or

$ php -S localhost:8000
$ open http://localhost:8000 # ブラウザアクセス
```

## 実行結果

ログ

```debug.txt
[2019-05-18 01:59:49] my_logger.INFO: 2019-05-20 00:00:00 [] []
[2019-05-18 01:59:49] my_logger.INFO: 2019-05-18 01:59:49 [] []
```

ブラウザ

![carbon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74602/b50d6342-3aaf-2764-e999-931dd759bf40.png)
prototype pattern

# prototype pattern
## ケース
object newするコストが高いとき
オブジェクトコンポジションが深い時
ある状態のオブジェクトが欲しい時

## 結果
### pros 
サブクラス化が減る

### cons
循環参照を保持するオブジェクトへの適用がむずい

## example
```
protocol ProductPrototype {
    func clone() -> ProductPrototype
}

class Product: ProductPrototype {
    private let parts: [Part]

    func clone() -> Product {
        var p = Product()
        p.parts = [] // set some parts
        return p
    }
}

// ProductPrototypeに依存しているクライアント
class SomeFactory {
    private let prototype: ProductPrototype

    init(prototype: ProductPrototype) {
        self.prototype = prototype
    }

    func createProduct() -> ProductPrototype {
        return prototype.clone()
    }
}

```
【小技】MacでIPアドレスを確認する

ググってもあんまり出てこなかったので、一応メモ。

[option]キー　+  メニューバーのwifiのマーク
Macに割り当てられているIPアドレスと、接続しているルーターのIPアドレスが確認できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386017/c1bee985-e36e-e0dc-a045-52d815dc2ed1.png)
PHPが入っているサーバからmysqlに接続確認するためのスクリプト

PHPが入っているサーバから、mysqlが入っているDBサーバに疎通確認したいなって時に、
実行するPHPスクリプトを作成してみました。

CA証明書は無ければoptions定義の行コメントアウトして、PDOのoptionsを削除して下さい。
dsn,user,pass,optionsは環境に合わせてください。

ただ単にshow databasesを実行してます。

```
#!/bin/php
<?php
 
$dbhost = 'xxx.xxx.xxx.xxx';
$dbname = 'sampledb';
$dsn = 'mysql:host='.$dbhost;
$user = 'app_admin';
$pass = 'password';
$options = array(
 PDO::MYSQL_ATTR_SSL_CA => '/usr/local/etc/ssl/mysql_ca-cert.pem' // CA証明書の指定
);
 
$client = new PDO($dsn,$user,$pass,$options);
 
$sql = "SHOW DATABASES";
$result = $client->query($sql);
 
foreach($result as $row) {
 var_dump($row);
}
?>
```
JMeterでCSRFトークン認証を解決する

CSRFトークン認証を解決するには、

**<font color="Red">①HTTPクッキーマネージャーを設定</font>**

②**<font color="Red">GET</font>**　ログイン画面表示
　→**<font color="Red">後処理　正規表現抽出</font>**　CSRFトークンを抽出

③POST　ログイン認証
　→${csrf_token}を設定
[Rust] トレイトの参照でハマる


素朴なOOPLの気持ちで書いてるとハマる話

# 経緯

経緯を簡略化したコードで書いていく。

元のコード

```rust
struct Context;

impl Context {
    fn do_something(&mut self) {}
}

fn func(context: &mut Context) {
    context.do_something();
}
```

実際は`Context`はメンバ持ってたり、`do_something()`も空実装ではないが省略。

次に`Context`をトレイトにしたくなった。

```rust
trait Context {
    fn do_something(&mut self);
}

struct ContextImpl;

impl Context for ContextImpl {
    fn do_something(&mut self) {}
}

fn func(context: &mut Context) {
    context.do_something();
}
```

特に問題は無い。

ここに、`Hoge`トレイトを追加して、`Context`に対して実装する。

```rust
trait Hoge {
    fn hoge(&mut self);
}

impl<T: Context> Hoge for T {
    fn hoge(&mut self) {
        self.do_something();
    }
}

fn func(context: &mut Context) {
    context.do_something();
    context.hoge();
}
```

コンパイルエラーになる

```
error[E0599]: no method named `hoge` found for type `&mut dyn Context` in the current scope
  --> src/main.rs:23:13
   |
23 |     context.hoge();
   |             ^^^^
   |
   = note: the method `hoge` exists but the following trait bounds were not satisfied:
           `&mut dyn Context : Hoge`
           `dyn Context : Hoge`
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `hoge`, perhaps you need to implement it:
           candidate #1: `Hoge`

error: aborting due to previous error

```

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=cff9dff5ee5ff267d9b76e382d463589

何がいけなかったかと言うと、`func()`の引数を`&mut Context`のままにしておいたのがダメだった。

```rust
fn func<T: Context>(context: &mut T) {
    context.do_something();
    context.hoge();
}
```

これでコンパイルエラーはなくなる。
Linuxでスワップ領域作成

とても忘れるので。どれくらいのサイズで作ったらよいかはちゃんと調べよう。

スワップファイル作成

```
dd if=/dev/zero of=/swapfile bs=1M count=16384
```

スワップ領域作成

```
mkswap /swapfile
```

スワップ領域の有効化

```
swapon /swapfile
```

fstab編集

```
vi /etc/fstab
※以下追記
/swapfile               none    swap    sw                      0 0
```
Linuxで追加ディスクの設定をちょっとおしゃれに

クラウド時代となりfstabにUUIDで記載することが増えましたね。
そんなマウントポイントの記載方法をちょっとおしゃれにしました。

※追加ディスクをアタッチした状態から。

ディスク確認

```
fdisk -l
```
 
パーティショニング(/dev/sdbとかデバイス名は適宜環境に合わせて)

```
fdisk /dev/sdb
※p,nで新規作成、wで保存してexit。パーティションを分ける必要がなければ設定はすべてEnterでよい。
```

ディスク確認

```
fdisk -l
```
 
マウント先ディレクトリ作成

```
mkdir -p /data
```
 
xfsでフォーマット

```
mkfs -t xfs /dev/sdb1
```
 
UUIDとフォーマットを変数にセット

```
set - $(blkid /dev/sdb1|sed -e "s/\"//g")
```

fstabで追記(printfでデフォルトのfstabとスペース数を合わせてます)

```
※nofailにしておくと起動時にボリュームがなくても起動失敗しません。
echo "$2 $(printf "%-24s\n" /data)${3##*=}     nofail          0 0">>/etc/fstab
 
↓こんな感じで入ります。
UUID=3b3c05fc-22a0-46e2-8d6e-bee839fb21c2 /data             xfs     nofail
```
アジャイルなプロジェクトの勝ち確パターン

> #### 勝ち確(カチカク)とは
> 勝ちの期待値が高い状態。もう一手で勝てるかもしれない状態
> 勝てるとは言っていない

# 勝ち確パターン

- 全員が目的に向かって努力している
- 前進、改善し続けられる
- みんなが最大のパフォーマンスを発揮できる環境
- 変化を受け入れる勇気。トレードオフを受け入れる勇気。決断する勇気。

(スクラムの価値基準と近いのでそちらのほうが参考になると思います)

インセプションデッキ大事

## 全員が目的に向かって努力している

前提条件。満たしてないプロジェクトはヤバみあり

## 前進、改善し続けられる
- 向かう先を全員が理解している
- メンバー全員が正直発言しやすい
- 失敗を仕組みやプロセスのせいにする
- 柔軟に役割を変えられる

インセプションデッキの「俺たちなぜここ」「エレベータピッチ」や「ふりかえり」を使う

## みんなが最大のパフォーマンスを発揮できる環境

- それぞれが自分の仕事に集中できるといいよね

インセプションデッキの「プロジェクトコミュニティ」「俺たちの“Aチーム”」「自己紹介」等の仕組みを使う

- プロダクトオーナーは誰なのか
- プロダクトオーナーにはどんな責任があるのか

この項目を説明しながら、プロダクトオーナーがボトルネックになるといろいろ進まないよ的なことを伝えたりする

## 変化やトレードオフを受け入れる勇気。決断する勇気。

インセプションデッキの「トレードオフスライダー」や「PivotalTracker」をうまく使おう
プロダクトオーナーがこれらを持ってるとすごく心強い

# というような表向きの勝ち確パターンを匂わせつつ...

# プロダクトオーナーにいかに気持ちよく頑張ってもらうか！これが大事

- 頑張って開発するので、頑張ってストーリー入れてね
- ファシリとかあんまり得意じゃないのでPOさんやってくれると嬉しいな
- PivotalTrackerのメンテお願いね！
- 予定が狂ったけどよくあることだよ
- こいつにプロジェクト進行任せるの不安だな。俺がやったるか (PO)

# 実際プロダクトオーナーはかなり頑張る必要がある

やることたくさん

# プロダクトオーナーが大変そうなら全員で助けましょう

例) ストーリーメンテの大変そうなら詳細度減らしてもらってエンジニアに任せるなどPOも無理なく回せるように柔軟に

# みんなが幸せなプロジェクトを増やしましょう！

「POも無理なく楽しくプロジェクトを回せるように」
そして「ちゃんと目的(プロダクト)を達成できること」

この辺意識したい

# 参考資料

- https://www.scrumguides.org/download.html

# あと、一枚で自分がやってるプロジェクト進行を伝えるやつ作ってみました
<img width="1112" alt="スクラム.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51402/24071dee-de9a-857f-9bbb-4aa82603d220.png">

これの説明も書きたい。いつか...
LINEからGoogle フォトに画像・動画を転送するボットを作った

技術的には全然すごくないです。ただLINEのボットのAPIのリファレンス見てGoogleフォトのリファレンスを見るだけです。

LINE
https://developers.line.biz/ja/reference/messaging-api/

Google フォト
https://developers.google.com/photos/library/guides/get-started
https://developers.google.com/photos/library/guides/upload-media

実は最初curlでセコセコ試してたんですが上手くいかなくて時間を浪費しました。。。。(ただ単にローカルのファイルをちゃんと送れてないと気づいた時には死にそうになりましたが)

LINEからくるwebhookの実際のデータを見たかったのでこちらも使用しました。
https://webhook.site/

ユーザーが写真を複数送った時にLINEに一回のリクエストで複数のイベントが流れてくると思ってたのですが、そうではなく結構ノリでリクエストが来てたので複数画像を選択送信した時にはリプライがなんども来てうざい感じになります。ここら辺はキューイングとかすれば解決できると思いますが、まぁ工数かける必要ないと判断でリプライ垂れ流しとなっています

ソースはこちらでheroku上で動きます。
https://github.com/1984weed/line-to-google-photo

あるイベントで使用したのですが、意外とみんな登録してくれず結構難しいしGoogle Photoも共有設定にしてたのでそちらに直接アップロードする人もたくさんいてあんまり意味はなかったかもしれません。
初心者僕「KotlinでAndroidプログラミングをしたい」3.5

#Androidアプリにデータ共有機能を乗っけたいという話
今回は「[初心者僕「KotlinでAndroidプログラミングをしたい」2.5](https://qiita.com/Miso_DengakuTY/items/1f6b830c329fc4b1b6b6)」で少しだけ触れたAndroid間のデータ共有機能を付けたいという話の続きです。僕が今作っているTRPGをAndroidで管理するアプリ(世の中に溢れてるけど)の機能の一つに共有できるホワイトボードの機能を付けようと考えています。前回はWiFi Directを使おうということでしたが、紹介しているサイトが古いものが多かったので、比較的最近でも使われてそうな[Nearby Connections API](https://developers.google.com/nearby/connections/overview)を使っていきたいと思います(内部的にはWiFi Directも使っていますが)。個人的な考えですが、初心者が技術を導入する時は流行に乗るのが一番手っ取り早いので。


#Nearby Connections APIって何よ？
Nearby Connections APIはネットワークを必要とせず、Android端末間でデータ共有を行うための機能です。通信には、Bluetooth, BLE, Wifiなど複数の方法を切り替えて使用することで、それぞれの長所を活かしつつ短所を隠蔽できます。また、Android端末やAndroid OSによる通信方法の違いを意識せず開発できることも特徴です。
アプリ使用者はAdvertisersとDiscoverersに分かれます。Advertisersは自身が接続可能であることを伝え、Discoverersはそれに対して接続の要求をします。接続は両者の合意が成されたときに確立します。

#準備
まずはGoogle Play Services SDKを使えるようにしましょう。
[File]→[Settings]→[Android SDK]→[SDK Tools]からGoogle Play Servicesにチェックを入れます。また、[Support Repository]からGoogle Repositoryにもチェックします。チェックができたらApplyを押してDownloadを始めましょう。
次にbuild.gradle(Module: app)を弄ります。dependenciesの部分に

```
implementation 'com.google.android.gms:play-services-nearby:{latest_version}'

```

を追加します。

次にパーミッションの変更をします。AndroidManifest.xmlに

```
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
```

を追加します。これらのパーミッションは扱う端末間の接続トポロジー(Strategies)によって必要なものが異なるため、必要なものを取捨選択しましょう。

#実装したいんだけど......
今回もサンプルコードみたいなものを挙げようかと思っていたのですが、Android端末が2つもないのでテストできてません。さすがにテストもしないで挙げるわけにもいかないので了承ください。[公式のチュートリアル](https://developers.google.com/nearby/connections/android/get-started)に部分コードがあるのでそちらを参照してくれれば幸いです。

#次回
今回は投げやりな記事になって申し訳ないです。次回は初心者用の記事になるはずなのでサンプルコードも挙げれるはずです。内容はまったく考えてないですが。
はじめてのAI(Udemy)

# 第１章　生活の中でのAI
## 1-1 生活の中でのAI
AIとは `人工知能 Artificial Intelligence`

### Googleの目指すAI
今までのコンピュータができなかったことをもう一歩賢くしよう 

### AIを利用したGoogleサービス
- GmailのSmartReply
- Google翻訳アプリ
- Googleフォトの自動ラベル付け


## 1-2 AIの活用事例を知る
キュウリの仕分けをAIで解決する

- Googleが提供するTensorflowというツールで実装

クリーニング＋AI＝？

- 受付をAIに任せる

## 1-3 機械学習について知る

- 人工知能... 賢いITを作る技術
    - 機械学習... データから賢さを得る技術
        - ニューラルネットワーク... 機械学習のアルゴリズムの一つ
            - ディープラーニング... 深い階層を持つニューラルネットワーク

# 機械学習でできること
## 2-1 普通のITと機械学習の違い
- りんごとオレンジを見分けるシステムを作る

普通のIT
- 人間が仕様を決める

機械学習
- コンピュータが見分けるルールを自動的に探してくれる

Googleが提供する機械学習サービス

- [Cloud Vision API 画像認識](https://cloud.google.com/vision/)
- [Cloud Speech to Text API 音声認識](https://cloud.google.com/speech-to-text/)
- [Cloud Natural Language API 文章理解](https://cloud.google.com/natural-language/)

## 2-2 画像認識の例
- モップと犬の見分け方

**機械学習でも１００％の精度は出せない**

## 2-3 音声認識と文章理解
### [Cloud Vision API 画像認識](https://cloud.google.com/vision/)
音声を文字に起こしてくれる

### [Cloud Natural Language API 文章理解](https://cloud.google.com/natural-language/)

- 形態素解析... 単語で分けて品詞を付ける
- 構文解析... 単語間の関係性を付ける
- 感情分析

# 第３章　機械学習のしくみ

## 3-1 機械学習のしくみを知る

1. 学習データの準備... お手本となる数百件〜数十万件のデータを人間が集めて準備しておく
2. 機械学習のモデルの学習... 学習データに含まれるパターンを機械学習によって抽出する
3. モデルの利用...学習済みのモデルを分類や予測に利用する

### 例. 身長、体重を元に大人か子供か判別する
もっとも簡単な方法: `身長＋体重>200で線を引く`
しかし間違いが多い
間違いを減らすには： `w1 * 身長 + w2 * 体重>200`
それぞれの「重み付け」を調節して判別の線の傾きを変える

今までのITではこの重み付けを人間がやっていた

機械学習ではコンピュータが重み付けを行う


[Tensorflow Playgroundでのデモ](https://gwgtool.page.link/Playground1)

## 3-2 ニューラルネットワークのしくみを知る

ニューラルネットワークは**ニューロンのネットワークを簡易的に模したもの**

間違いが少なくなるように重み付けを変えていく

### 3-3 ニューラルネットワークによる画像認識
判別するものの特徴が現れやすいデータに強い重みを付ける

### 3-4 ディープラーニングのしくみを知る

#### 経度と緯度から街の内側か外側かを分類する

[Tensorflow Playground ディープラーニング デモ1](https://gwgtool.page.link/Playground2)

線を引いて判別できない

ニューラルネットワークの階層化（隠れ層の追加）が必要

#### 縦位置と横位置で並んだ子供を分類する

[Tensorflow Playground ディープラーニング デモ2](https://gwgtool.page.link/Playground3)

ニューロンの数を増やしたり階層を深くすることで賢くなる

3段以上の深い階層を持つニューラルネットワークを**ディープラーニング**と言う

# 第４章 応用事例の紹介
## 4-1 機械学習の応用例
### お菓子ロボット
1. 「甘いガムがほしい」
1. 音声認識
1. 文字理解
1. 画像認識
1. 該当のお菓子を持ってくる

### 食品の品質管理
不良品を判別する

### 漁業資源の乱獲防止プロジェクト
船のGPS情報を保存している
船の動きでどのような漁をしているかが判断できる
禁漁区域で漁をしている船に罰金を課したりしている
Reactで作る「令和」パズル

#背景
仕事で使うので、Reactの勉強がてらパズルを作ってみた。
話題の「令和」と「平成」を使ったやつ…（すでにちょっと遅い感じも…）

#完成品
下記のようなものができました。
スタートを押すと開始され、「令和」で揃えると完了！

<p class="codepen" data-height="400" data-theme-id="0" data-default-tab="js,result" data-user="hashito" data-slug-hash="GaKzYz" style="height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="reiwa puzzle">
  <span>See the Pen <a href="https://codepen.io/hashito/pen/GaKzYz/">
  reiwa puzzle</a> by hashito (<a href="https://codepen.io/hashito">@hashito</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

###TODO(残課題)
* ウィンドウを小さくすると正しく表示されない
* HTMLからの定義をもらってlevelやら大きさを可変させたい
* もう少し…コードを整理したい

#詰まった所
##```this```で```state```が参照できない。
下記のようなコードで何度確認しても```this.state```が定義されていない！

```javascript
class Puzzle extends React.Component {
  constructor(props) {
    super(props);
    ....
  render() {
    return (
      <span
        className="puzzle"
        cal={this.state.y}
```

###解決
コンストラクタで```this.render=this.render.bind(this);```がされていない…
はい、ドキュメントを読みましょうってことですね。

```javascript
class Puzzle extends React.Component {
  constructor(props) {
    super(props);
    this.render=this.render.bind(this);
    ....
  render() {
    return (
      <span
        className="puzzle"
        cal={this.state.y}
```


##```render```が呼び出されない
コンストラクタで受け取った```props```を下記のように```state```に直接引き渡しをしていた。
コンストラクタはインスタンス生成時にしか呼び出されなかった…

```javascript
class Puzzle extends React.Component {
  constructor(props) {
    super(props);
    this.state= props;
    ....
  render() {
    return (
      <span
        className="puzzle"
        cal={this.state.y}
```

下記のように改善…
しかし、更新されず…

```javascript
class Puzzle extends React.Component {
  constructor(props) {
    super(props);
    this.state.y {y:props.y};
    ....
  render() {
    return (
      <span
        className="puzzle"
        cal={this.state.y}
```

###解決
純粋にそのまま```props```を見ればよかったのだ…

```javascript
class Puzzle extends React.Component {
  constructor(props) {
    super(props);
    ....
  render() {
    return (
      <span
        className="puzzle"
        cal={this.props.y}
```

#感想
Reactは結構**「こうしてください！」**ってのが多い感じがした。
**書き方やロジックが矯正**されるので誰が書いても同じようなコードになるのが利点なのかな…
オブジェクト構成とかも…
Nuxt.jsの情報収集の方法

公式の情報やqiita以外で、参考にしている情報ソースをまとめました。

Yuuniworks Notes
https://note.yuuniworks.com/study/nuxt.html#api

Youtubeで手順を確認
https://www.youtube.com/results?search_query=nuxt.js

githubで事例を見る
https://github.com/topics/nuxt?o=desc&s=stars

他にもわかりやすいサイトがあれば、随時更新します。
【C言語初級者向け】学習初期に出会う標準関数と名前の由来一覧

　　　　
　　　C言語を学習し始めて出会う標準関数の名前の由来についてまとめました。由来について知ることで関数について覚えやすくなると思います。参考になれば幸いです。また、初めての記事なので、何か至らないところがあればご指摘いただけると嬉しいです。
　　　気が向いた時にぼちぼち更新して行こうと思います。^^;
　

#入出力関数
　　　種類が多いなと思いました。
　　　１文字だけを標準出力するときはputc()ではなく、putchar()です。
　　　１文字だけを標準入力するときはgetc()ではなく、getchar()です。
　　　putc()とfputc、getc()とfgetc()の違いはこちらを参照。よくわかんないです。
　　　https://ja.wikipedia.org/wiki/Getc
　　　また、Enterキーを使わない入力はgetch()（非標準関数）を用いましょう。

####出力関数
| 関数名    |　　　　大まかな機能　　　　| 名前の由来|
|:--:|:--:|:--:|
|putchar()| 1文字のみを標準出力に出力         | put  + character　　|
|puts()   | 文字列を標準出力に出力           |       put + string    |
|printf() | 文字列を書式付きで標準出力に出力|        print + format      |
|fputc()| １文字のみをファイルに出力|file + print + character|
|putc()   | 上と同じ                 |       put + character    |
|fputs()  | 文字列をファイルに出力            |      file + put + string   |
|fprintf()|文字列を書式付きでファイルに出力|file + print + format  |

####入力関数
| 関数名    |　　　　大まかな機能　　　　| 名前の由来|
|:--:|:--:|:--:|
|getchar()|１文字のみを標準入力から入力|get + character
|gets()|文字列を標準入力から入力|get + string
|scanf()|文字列を書式付きで標準入力から入力|scan + format
|fgetc()|１文字のみをファイルから入力|file + get + character
|getc()|上と同じ|get + character
|fgets()|文字列をファイルから入力|file + get + string
|fscanf()|文字列を書式付きでファイルから入力|file + scan + format

　
・最初に付くfは”file”のf　→　ファイルに出力（putcは別）
・最後に付くfは”format”のf　→　書式付き（%dとかのやつ）
・c,char　→　character　→　文字
・s　　　　→　string 　　→　文字列



#文字列操作に関する関数

| 関数名    |　　　　大まかな機能　　　　| 名前の由来|
|:--:|:--:|:--:|
|sprintf()|文字列を書式付きで指定した配列に代入する| string + print + format　　|
|strcpy()| 文字列のコピーを行う         |string + copy　|
|strcat()| 文字列を後ろに追加（結合）する         |string + catenate　　|
|strlen()| 文字列の長さを求める       |string + length|
|strcmp()| 文字列を比較する         |string + compare　|
|atoi()|数値を表す”文字列”を”数値”に変換する         |ASCII + to + integer|

 ・文字列（string）だけでなく配列一般でもつかえる。
 ・似た機能のmemcpy()などもあるがstr系の方が個人的に使い勝手が良い。
SQL Serverサービスを起動する

# はじめに

SQL Serverを利用するアプリケーションにおいて, 初回のデータベースオープン時に以下の例外が出力される事象が発生しました.

> SQL Server への接続を確立しているときにネットワーク関連またはインスタンス固有のエラーが発生しました。サーバーが見つからないかアクセスできません。インスタンス名が正しいこと、および SQL Server がリモート接続を許可するように構成されていることを確認してください。 (provider: SQL Network Interfaces, error: 26 - 指定されたサーバーまたはインスタンスの位置を特定しているときにエラーが発生しました)

SQL Server構成マネージャーで該当インスタンスの状態を確認すると, 「停止」状態となっており, これが原因でアクセスできず例外が出力されていました. 

「停止」状態になっていること自体が問題ですが, これまでSQL Serverのサービス状態を確認, 変更する処理を実装したことがなかったので, 勉強がてら, SQL Serverサービスを起動する処理を実装してみました.


# 管理者権限で起動する

SQL Serverのサービスの状態を変更するには, 管理者権限を付与する必要があります. 
以前投稿させていただいた以下の記事のように起動時に管理者権限で起動するアプリケーションとなっていることとします.  

[アプリケーションを管理者権限で起動する](https://qiita.com/tada0724/items/645616a5d1deb55bfdb8)

# SQL Serverサービス状態の確認・起動

SQL Serverサービス状態の確認・起動には, System.ServiceProcessを参照し, ServiceControllerクラスを使用します.
以下のStartMSSqlService()メソッドは, 該当インスタンス状態を確認して「停止」状態であれば起動するようにしています.  

```cs
//using System.ServiceProcess;

static ServiceControllerStatus StartMSSqlService(string instanceName)
{
    if (string.IsNullOrEmpty(instanceName))
        throw new ArgumentNullException(nameof(instanceName));

    try
    {
        using (var controller = new ServiceController($"MSSQL${instanceName}", "."))
        {
            if (controller.Status == ServiceControllerStatus.Stopped)
            {
                controller.Start();
                controller.WaitForStatus(ServiceControllerStatus.Running);
            }
            return controller.Status;
        }
    }
    catch
    {
        throw;
    }
}
```

# 最後に

System.ServiceProcess.ServiceControllerクラスを利用することで, SQL Serverサービスの状態確認やサービスの開始／停止の処理が実現できます.
AdminerのアクセスIP制御

バージョンアップで↓こちらの方法が使えなくなっていたので

[Adminerでお手軽DB管理&アクセス制御](https://qiita.com/saba1024/items/fc29d133dd3435c7fa98)

---

adminer本体は公開されていない階層に置き、別のPHPファイルを作成します。

```php:adminer_ext.php
<?php
$acl = [//↓アクセスを許可するIPを指定
	'::1',	//localhost
	'xxx.xxx.xxx.xxx',
];

if(!in_array($_SERVER['REMOTE_ADDR'], $acl)){
	header("HTTP/1.0 404 Not Found");
	exit;
}

require '../adminer-4.7.1-mysql.php';
```

作成したPHPファイルを公開ディレクトリに置くことで、アクセス制御のコードを通してからadminerを表示できます。

https://www.adminer.org/en/plugins/#use
プラグインなども同じ方法で読み込むようです。
mp4をリサイズしてjpegに変換する

作成したもの
https://gist.github.com/kenjiSpecial/08473149c4dd69934cc4827e0903bb54

参考にしたコード
https://www.geeksforgeeks.org/extract-images-from-video-in-python/

Python 3.6 に OpenCV 3.4 など環境を構築する
https://qiita.com/cointoss1973/items/92d82f9accb239a276a0
Webで遊ぶ、Solat Lab.を鋭意制作中！

#はじめに

現職の駆け出しWebデザイナーのSolatです。

Solat Lab.ではWebを中心としたクリエイティブ制作に関する様々なのうはうを溜め込み、いつでも必要な情報を取り出すことができるストックサイトを目指していきます。

実務担当者として、効率やコスト面も意識しながらWebというコンテンツをより充実したものにする助けになればという表向きの想いと、個人的な効率化と検証のためにサイトを運営していきます。

※検証中心なのでサイトもまだ作りかけです。最低限のエラーチェックはしていますがSolat Lab.を利用したことによる損害に関しては責任を負いかねますのでご承知のほどお願いします。

[Solat Lab.](https://www.solat.jp)


##簡単に実務経験をご紹介

- 紙媒体デザイン（ポスターや販促物）
- Web制作（フロントエンド・バナーデザイン）
- web開発（UIUXデザイン）
- Webマーケティング
- SEO（LPO・ライティング）

##今後について

SolatLab.の制作記録的な形でいろいろなことを書いていこうと思います。
Qiitaの使い方も含めて慣れていこうと思います。
Ubuntu 18.10 英字キーボードで日本語入力

バージョンを上げたらレイアウトが変わっていて混乱中。

インストールは標準インストール。
ISOは**ubuntu-ja-18.10-desktop-amd64.iso**
インストール時のキーボード選択は英語

結論はキーボードショートカットの設定だが、順を追って。

まずはアクティビティからそれらしい設定を探す。

「地域と言語」から

![key.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62354/75257d94-850d-dfb5-0969-710b17e8a2fd.jpeg)


日本語設定は標準で入っているようだ。
(UKだったので後でUSに直しました)

![input.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62354/d5f9bfd7-8481-dba5-decf-26b3b5b032f8.jpeg)


切り替えを`ctrl + space`にしたいが、オプションからではなくてキーボードショートカットからのようだ。

![options.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62354/8bc7b4ae-4a1f-f9b5-0c1c-78d414c94113.jpeg)


同画面の左メニュー下部の
「デバイス」 →　「キーボード」で変更

![change.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62354/44ff7795-ee88-62bf-2129-670133b15f28.jpeg)


これで`ctrl + space`で入力を英語と日本語に切り替えることができる。
前より分かりやすいUIが表示される。

日本語に設定しても英字しか入力できない場合は、ひらがな入力に変更する。

![hiragana.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62354/b0706240-0c3b-e840-6b83-13d846c5eb27.jpeg)

***

前までの16系の場合はこちらを

[Ubuntu 16.04で英語キーボードを使えるようにする方法 - Qiita](https://qiita.com/SUZUKI_Masaya/items/2f2ef9fdb63fe017c6d2)
OpenJDK8をmacにインストールする

# 注意
* 2019/5/18現在の情報です
* 本記事はOpenJDKのJava8の記事です
* サポート期間外になった場合、セキュリティパッチなど受けれ無いので商用利用にはご注意ください
* 公式サイトから取得する場合は下記がまとまってて便利です

http://jdk.java.net/archive/

# 環境
* macOS Mojave 10.14.3

# インストール

ふとJava8の開発環境を作りたいと考えました。
個人利用目的ですが、せっかくなのでOpenJDKを使ってみます。
今回はHome brewを利用します。

```console
$ brew tap AdoptOpenJDK/openjdk
$ brew cask install adoptopenjdk8
```
対応バージョン一覧は[こちら](https://github.com/AdoptOpenJDK/homebrew-openjdk)。

# 確認
```console
$ java -version

openjdk version "1.8.0_212"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_212-b03)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.212-b03, mixed mode)
```


# 補足

adoptopenjdkは
OpenJDKのビルドを提供するコミュニティでIBMなどがスポンサーしているとのことです。

Home brewじゃなくても、
公式サイトからインストーラやバイナリを落とせるようです。

https://adoptopenjdk.net/archive.html

Windowsならこっちの方が便利かも？
Linux系は現状ではパッケージ管理で困ら無いから大丈夫かと思われます。
（いつまで大丈夫かわかりませんが）

# 参考
* [How to install openjdk with brew](https://discourse.brew.sh/t/how-to-install-openjdk-with-brew/712/4)
* [Javaのサポートについてのまとめ](https://qiita.com/nowokay/items/edb5c5df4dbfc4a99ffb)
Desktop : Gui Button

<h5>Goal</h5>
Test Gui Button

```Gui_Btn.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Gui_Btn {
    private JFrame frame;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Gui_Btn window = new Gui_Btn();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public Gui_Btn() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        JButton btnNewButton = new JButton("New button");
        btnNewButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("Hello World");
            }
        });
        btnNewButton.setBounds(14, 13, 99, 27);


        frame.getContentPane().add(btnNewButton);
    }
}
```
<H5>Result</H5>
![gui_btn.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276243/f3fe3711-2cc2-cf24-ba5b-023b512597b3.jpeg)
Desktop : Gui slider

<H5>Goal</H5>
Gui slider 

```Gui_Slider.java
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;

public class Gui_Slider {
    private JFrame frame;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Gui_Slider window = new Gui_Slider();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public Gui_Slider() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        JLabel lblNewLabel = new JLabel("Test");
        lblNewLabel.setBounds(14, 20, 57, 19);
        frame.getContentPane().add(lblNewLabel);

        JLabel lblNewLabel1 = new JLabel("");
        lblNewLabel1.setBounds(307, 20, 57, 19);
        frame.getContentPane().add(lblNewLabel1);

        JSlider slider = new JSlider();
        slider.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                lblNewLabel1.setText(slider.getValue()+"");
            }
        });
        slider.setValue(1);
        slider.setMinimum(1);
        slider.setBounds(93, 13, 200, 26);
        frame.getContentPane().add(slider);
    }
}
```
<h5>Result</h5>
![gui_slider.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276243/75bb74a3-f421-c8f4-b28d-ec66cdb26606.jpeg)
Desktop : Gui show image

<H5>Goal</h5>
Load a image with OpenCV.

```Gui_Show_Image.java
mport javax.swing.*;
import java.awt.*;

public class Gui_Show_Image {

    private JFrame frame;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Gui_Show_Image window = new Gui_Show_Image();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public Gui_Show_Image() {
        initialize();
    }
    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        JLabel lblNewLabel = new JLabel("");
        lblNewLabel.setIcon(new ImageIcon("C:\\Users\\koinPC\\Pictures\\dance2.png"));
        lblNewLabel.setBounds(14, 0, 159, 240);
        frame.getContentPane().add(lblNewLabel);
    }
}
```
<H5>Result</H5>
![ShowImage.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276243/99b9dd04-9144-e5be-02fc-4b3ececb70fb.jpeg)
【Bootstrap4】 水平方向 中央寄せ

##水平方向　中央寄せ　mx-auto　

１枚のカードを画面中央（水平方向中央）に配置したい。
[mx-auto]で中央に配置することができるが、この場合はどこに入れるのが正解か。


```html:qiita.html
<div class="container">　←①
 <div class="row">　←②
  <div class="col-8">　←③
　 <div class="card">　←④
　　 ~カードの中身（省略）~
　 </div>
  </div>
 </div>
</div>
```

正解は、③番！
「このコンテナの中身を真ん中にしたい。」と考えると①番のコンテナにmx-autoを入れたくなるけど、それでは中央に寄ってくれません。

「何を真ん中に寄せるのか」を指定するイメージでmx-autoを入れます。
今回は、コンテナの中にある、「col-8サイズのカード」を真ん中に寄せたいので、③に入れると思った通りの構成になります。

毎回入れる場所に迷うのでまとめてみました。
水平方向の中央寄せはしょっちゅう使うので暗記しちゃいたいですね。
改行エラー

ターミナルでこんなエラーがでた。解決方法忘れない様に書き書き。。

### 開発環境
・Mac　10.14.4
・Visual Studio Code

### エラー内容

```bash
mil-MacBook-Pro:002.filein mil.neon$ ruby cat.rb
ruby: warning: shebang line ending with \r may cause problems
```
shebang行に` \r `が使われているという警告

何故ダメなのか？

[ダメな理由](https://ja.stackoverflow.com/questions/12897/%E6%94%B9%E8%A1%8C%E3%81%AE-n%E3%81%A8-r-n%E3%81%AE%E9%81%95%E3%81%84%E3%81%AF%E4%BD%95%E3%81%A7%E3%81%99%E3%81%8B)はMac環境なのに`\r`を使ってる為の可能性があるとの事。

```
mil-MacBook-Pro:002.filein mil.neon$ hexdump cat.rb
0000000 23 21 2f 75 73 72 2f 62 69 6e 2f 65 6e 76 20 72
0000010 75 62 79 0d 0a 0d 0a 66 69 6c 65 20 3d 20 46 69
0000020 6c 65 2e 6f 70 65 6e 28 22 74 65 73 74 2e 74 78
0000030 74 22 2c 22 72 22 29 0d 0a 0d 0a 77 68 69 6c 65
0000040 20 6c 69 6e 65 20 3d 20 66 69 6c 65 2e 67 65 74
0000050 73 0d 0a 20 20 20 20 70 75 74 73 20 6c 69 6e 65
0000060 0d 0a 65 6e 64 0d 0a                           
0000067
```
16進数で表示すると改行の値が視認できる。
`0d 0a` は `\r\n`
なので、`\n(LF)`に変更する必要がある。

どうやら、[Visual Studio Code](https://code.visualstudio.com/)はWindows製

[Visual Studio Codeで改行を変更する方法](https://www.atmarkit.co.jp/ait/articles/1809/14/news025.html#fileseol
)
で修正すれば、エラーが解決する。
[C#]UniRxのAsyncMethodBuilderについてのメモ

`UniRx`のソースを呼んでいると`AsyncMethodBuilder`の実装が以下のようになっていました。

```csharp
// UniRx AsyncUniTaskMethodBuilder.cs より引用
// 5. AwaitOnCompleted
[DebuggerHidden]
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
    where TAwaiter : INotifyCompletion
    where TStateMachine : IAsyncStateMachine
{
    if (moveNext == null)
    {
        if (promise == null)
        {
            promise = new UniTaskCompletionSource(); // built future.
        }

        var runner = new MoveNextRunner<TStateMachine>();
        moveNext = runner.Run;
        runner.StateMachine = stateMachine; // set after create delegate.
    }

    awaiter.OnCompleted(moveNext);
}
```

`set after create delegate`と書かれている部分でなぜそうでなければいけないか疑問だったのですが、
ようやく理解できたので備忘録としてメモしておきます。

------------------------------------------------

メモリ初期状態。

```text
# スタック領域
StateMachine
  - AsyncMethodBuilder
  - その他ローカル変数

# ヒープ領域
なし
```

`Awaiter`に後続処理を依頼するためには`Action`を渡す必要がある。
`Action`はクラスオブジェクトなのでヒープ領域に作成しなければならない。
よって最終的には以下のようなメモリレイアウトになる。

```text
# スタック領域
StateMachine
  - AsyncMethodBuilder
  - その他ローカル変数

# ヒープ領域
Action
  - StateMachine Pointer
  - Method Address

StateMachine(スタック領域からのコピー, Actionから参照される)
  - AsyncMethodBuilder
  - その他ローカル変数
```

これを踏まえて再度`UniRx`のコードを見る。

```csharp
// UniRx AsyncUniTaskMethodBuilder.cs より引用
var runner = new MoveNextRunner<TStateMachine>();
moveNext = runner.Run;
runner.StateMachine = stateMachine; // set after create delegate.
```

もし`runner.StateMachine`への代入が`delegate`を作るより前に行われた場合、

1. `StateMachine`をスタック領域からヒープ領域にコピー
2. スタック領域の`AsyncMethodBuilder`の`moveNext`を書き換える

の順番で処理が行われる。

```text
# スタック領域
StateMachine
  - AsyncMethodBuilder <- ここのmoveNextが書き換わる
  - その他ローカル変数

# ヒープ領域
StateMachine
  - AsyncMethodBuilder <- こっちは書き換える前にコピーしてしまったのでそのまま
  - その他ローカル変数
```

ヒープ領域にコピーした側の`moveNext`を書き換えなければ明らかにまずい。
なのでスタック領域の`moveNext`を先に書き換えてその後ヒープ領域にコピーする必要がある。


`StateMachine`の`MoveNext`を直接`AsyncMethodBuilder`の`moveNext`に入れることはできない。
`delegate`を作った時点で`AsyncMethodBuilder`がヒープ領域にコピーされてしまうからである。
必要条件として`delegate`を作った後にヒープ領域にコピーできる必要がある。
`UniRx`ではそれを実現するために`MoveNextRunner`というラッパーを挟んでいる。


**なお`Debug`ビルドの場合は`StateMachine`が`class`として作られるので順番が違っても動いてしまう。**
Firebase ML On-Device Translate API

# Firebase ML On-Device Translate API

## はじめに

Firebase ML の[オンデバイス翻訳](https://firebase.google.com/docs/ml-kit/android/translate-text)が [Google Translate](https://translate.google.com/) と同等の翻訳レベルでかつ無料で使えると聞いたのでちょっと試してみました。基本、オンデバイス翻訳のリンク先に書いてあることと同じです。

オンデバイス翻訳は５９カ国語をサポートし、翻訳に必要なデータファイルをデバイスにダウンロードしてローカルで処理を行います。言語のマッピングは全パターンサポートしている訳ではなく、英語を挟んだ翻訳になります。例えば、中国語を日本語に翻訳する際は、一度英語に翻訳してから日本語に翻訳されます。

## 手順

Firebase のアプリ登録して google-services.json プロジェクトに追加します（省略）。

以下を dependencies に追加します。

```groovy
dependencies {
  // ...
  implementation 'com.google.firebase:firebase-ml-natural-language:19.0.0'
  implementation 'com.google.firebase:firebase-ml-natural-language-language-id-model:19.0.0'
}
```


FirebaseNaturalLanguage のインスタンスを生成します。FirebaseTranslatorOptions で翻訳元・先を指定します。

> 翻訳元の言語がわからない場合向けに [Language Identification API](https://firebase.google.com/docs/ml-kit/identify-languages) と云うのもあります。

```kotlin
val options = FirebaseTranslatorOptions.Builder()
    .setSourceLanguage(FirebaseTranslateLanguage.EN)
    .setTargetLanguage(FirebaseTranslateLanguage.JA)
    .build()
translator = FirebaseNaturalLanguage.getInstance().getTranslator(options)
translator.downloadModelIfNeeded()
    .addOnSuccessListener {
        // 言語データダウンロード完了
    }
    .addOnFailureListener { e ->
        // エラー
    }
```

上の準備が完了したら実際に翻訳処理を行います。

```kotlin
translator.translate(text)
    .addOnSuccessListener { translatedText ->
        // 成功したので翻訳結果表示の処理を行う
    }
    .addOnFailureListener { e ->
        // エラー
    }}
```

これだけです。簡単すぎ。実際にアプリにして動かしてみるとこんな感じに。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188470/fd460ce9-e5cc-ed75-684b-76a326f77f86.png" width="30%"/>

いまいち🤔 なんか切れてるし。Google Translate で同じ文章を訳すと、

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188470/6213c654-607a-e1de-073e-5e40874e9e79.png)

ぜんぜん違う。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188470/2d55367c-11c0-5253-0d69-263494a4b510.png" width="30%"/>

まぁ、合っている。でも思っていたのと違う。Google Translate では、

![eof.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188470/18780f54-4006-703d-eae3-a05e2b7b6d98.png)

## おわりに

とりあえず Google Translate と同等の翻訳精度ではなさそうです。ML を活用した翻訳といってもデバイス上に落とせる程度（言語により25MB~35MBのデータ）でできる範囲のものでこんなものなのかもしれません。英語からの直接翻訳でこの精度だと他の言語 ⇒ 英語 ⇒ 日本語だともっと期待できない結果な気がします。それでも、日本語への翻訳のハードルが高いだけで他言語だとそうでもないのかも知れないし、無料で組み込めることを考えると活用できるシーンがあると思います。有料で精度の高い [Cloud Translation API](https://cloud.google.com/translate/?hl=ja) と云うサービスも提供されているので今度試してみたいと思います。
【ビジネスを推進してゆくために、システムが出来ることを考えたい】吉祥寺.pm #18 に参加して思ったこと #kichijojipm

[吉祥寺.pm #18](https://kichijojipm.connpass.com/event/127917/?utm_campaign=event_message_to_selected_participant&utm_source=notifications&utm_medium=email&utm_content=title_link)に参加してきて、自分の課題として感じたことを書いてゆきます。
初のホール開催ということで皆のテンションも上がっていたと思います。

だからなのか、いっそう身の引き締まる思いでお話が聞けたと思いました。

# まとめ
- サービスを開発するということは、ビジネスを推進するという責任感を持つということだ
- システムがビジネスにどう貢献するかは、最初の設計から始まっているかもしれない
- 懇親会に参加すると楽しいと言われた。本当に楽しかった

# 本文
サービス開発をずっとしていると、技術的な負債が沢山溜まってきてつらい。
でもつらくても、それでサービスが利益を生んでいる以上はメンテナンスを欠かすことはできない。

レガシーになったコードを改善しよう。

使わなくなった機能のコードがそのまま残ってデッドロジックになっている。
使い勝手のわからないテーブルがある。
Gendarテーブルに1,0のフラグだけではなく、「男」、「女」と入っているヤバいテーブル。

まさかサービスが長期で運用されるとは思っておらず、テストコードも書かれていないアプリケーション。

でも長い間保守されてきたアプリはそんなもんかもしれない。
それでも前を向く。メンテナンス性を高めないといけない。
そうしないと変更が大変になり、ムダなコストが掛かるから。ビジネスの価値を生み出す直接的な部分、つまり、売上に貢献しない部分で、修正コストがかさんでしまう。

いくらリファクタリングを頑張っても、それ自体が売上に結びつかないこともある。
変化に早く対応できる、といっても、それはソースコードや設計が読める人にとってはメリットが分かりやすいけれど、それ以外の人には余計にコストが掛かるとしか思ってもらえない。

「なぜ、画面に項目を一つ追加するだけでこんなに修正コストが掛かるの？！」と言われても仕方ないことだ。

もしかしたら、最初にビジネス特性を考えて設計できていれば、ビジネス特性に合わせた設計が出来たのかもしれない。というわけで、設計当初のビジネス上の意思決定をドキュメント化しておくことには価値があると思う。

変化に強い、というのはメンテナンスコストが低くて済むということだが、ビジネスサイドとからは、保守にコストが掛かりすぎると言われる。

これは、システムが単なるトールゲートではないということを指している。
変化が当たり前。変化の仕方はビジネスが成長してみないとわからない。
だから最初に設計をしきるのも、１年先の見積もりをするのも、ムリである。
ビジネスの成長に合わせて業務の在り方が変わるのだ。業務体系そのものがあっという間に変わることだって少なくない。

でも、だからこそ、技術による解決を、ビジネスサイドに価値のあるものとして認めて貰わなければならない。

「システムによる自動化」から、「システムでなければ提供できない価値」を作るところへとビジネスが変わっていくなかで、リファクタリング一つ取っても、売上は上げないけれど今後の売り上げを加速するためには絶対に必要なものなので、それを信じて、相手にも信じてもらえるように、コツコツと積み重ねてゆくことを忘れないようにしたい。

懇親会は楽しかった。めっちゃ楽しい。普段話せない人たちと話せるのは楽しい、面白い。
知らないことを知るのは面白い。参加できて良かった。

最後までとても満足できた内容だった。懇親会は楽しいものだ。