OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】localeの使い方

##localeとは
もともとは多言語化用の言語ファイル。
多言語化以外にも、何度も使う文言を一限管理するために使われる。
住所、会社名、時間をフォーマットする時の形式、今日の日付を出力する時の形式などを管理する。

##基本
`config/application.rb`でデフォルトの言語を指定

```config/application.rb
config.i18n.default_locale = :ja
```

`config/locales`以下にlocaleファイルを作成

```config/locales/ja.yml
ja:
  hello: Hello World
  company:
    name: サンプル株式会社
    address: 〒231-0001 神奈川県横浜市中区新港２丁目７−１
```
```erb:viewから呼び出す
<%= t('hello') %> <!-- Hello World -->
<%= t('company.name') %> <!-- サンプル株式会社 -->
```
```rb:modelから呼び出す
I18n.t('hello') #=> 'Hello World'
I18n.t('company.name') #=> 'サンプル株式会社'
```

###ポイント
- 呼び出し時、`ja`の部分は書かない
- localeファイルの名前は何でも良い。
- viewから呼び出す時は`I18n.`の部分を省略できる。
- 同じキーのデータが複数あった場合、後に定義したデータで上書きされる

##日付や時刻のフォーマットを定義する
```config/locales/ja.yml
ja:
  date:
    formats:
      default: "%Y/%m/%d"
      long: "%Y年%m月%d日(%a)"
      short: "%m/%d"
  time:
    formats:
      default: "%Y/%m/%d %H:%M:%S"
      long: "%Y年%m月%d日(%a) %H時%M分%S秒 %z"
      short: "%y/%m/%d"
```
```rb
I18n.l(Date.today) #=> '2020/02/14'
I18n.l(Date.today, format: :long) #=> '2020年02月14日(金)'

I18n.l(Time.zone.now) #=> '2020/02/14 18:34:25'
I18n.l(user.created_at, format: :short) #=> '20/02/14'
```

###ポイント
- DateクラスやTimeクラスの値をセットすると、`date`や`time`に定義した形でフォーマットする
- `format`を省略すると`default`の内容が適用される。
- `l`はlocalizeの略。ちなみに`t`はtranslateの略。
- `created_at`や`updated_at`を`I18n.l()`でラップすると、`time`に定義したフォーマットで出力される。

##変数を渡す
```config/locales/ja.yml
ja:
  airmax: "NIKE AIRMAX %{year}"
```
```rb
I18n.t('airmax', year: 95) #=> 'NIKE AIRMAX 95'
```

##モデルの情報を定義する
主にエラーメッセージ中のモデル名や属性名を日本語化する目的で。

```config/locales/ja.yml
ja:
  activerecord:
    # モデル名
    models:
      user: ユーザー
      item: アイテム
    # モデルごとの属性
    attributes:
      user:
        name: 名前
        address: 住所
      item:
        power: パワー
  # 全モデル共通の属性
  attributes:
    created_at: 作成日時
    updated_at: 更新日時
```

##階層分け
・スッキリ管理する
・conflictのリスクを減らす
ために、localeファイルを階層分けしてたくさん作ることも多い。

階層分けをする場合`config.i18n.load_path`の設定をすることで、`config/locale`直下のファイル以外も参照できるように設定します。

```config/application.rb
config.i18n.default_locale = :ja
#↓追加
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
```

##rails-i18n
`rails-i18n`というgemを使うと、[よく使う単語](https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml)を全部一気に導入できます。

多言語対応をする時には有用だと思いますが、日本語だけの場合はわざわざgemを入れなくても、上記のページに書いてある内容を全部コピペすれば良い気がします。


##参考
- [i18nについて](https://morizyun.github.io/ruby/rails-function-i18n-internationalization.html)
- [あなたはいくつ知っている？Rails I18nの便利機能大全！](https://qiita.com/Kta-M/items/bd4ba36a58ad602a9d8b)
- [Railsで日本語サービスを作るときのテンプレート](https://qiita.com/awakia/items/cab830238bbfaa924f02)
PHP7ccとPHPStanをそれぞれワンライナーで

# 概要

composer経由でやろうとしたら色々エラってインストールできない。
Dockerでやって楽をしましょう。

## PHP7cc

```shell
$ docker run -it --rm -v $(pwd):/app ypereirareis/php7cc php7cc ./
```

**PHP7ccはすでにサポート切れなので注意**

参照リンク:[docker-php7cc](https://github.com/ypereirareis/docker-php7cc)

## PHPStan

```shell
$ docker run --rm -v $(pwd):/app phpstan/phpstan analyse /app
```

参照リンク:[phpstan/phpstan](https://hub.docker.com/r/phpstan/phpstan)
Android 10 (API 29)対応で画像や動画ファイルをサーバに送信させたときの話

#targetSdkVersionを29したときに画像のサーバ送信で苦戦したので備忘録として

##問題点
https://developer.android.com/training/data-storage/files/external-scoped

「ファイル アクセスに必要なパーミッション」の項にあるこの部分

>READ_EXTERNAL_STORAGE パーミッションが付与されていたとしても、外部ストレージ デバイスの未加工ファイル システム ビューにアクセスするアプリの場合、アクセスできるのは、アプリ固有ディレクトリに限られます。アプリが未加工ファイル システム ビューを使用してアプリ固有ディレクトリの外部にあるファイルを開こうとすると、***エラーが発生します***。

どうやら
「自分が作成した画像(動画)以外は使っちゃだめよ！
ユーザが画像を選択後に、内部的に別のアプリがその画像を加工してたとしたら大変でしょ？（意訳」
という事らしい

一応逃げ道として

>アプリが対象範囲別ストレージに完全に対応するまでは、アプリのターゲット SDK レベルや requestLegacyExternalStorage マニフェスト属性に基づいて、一時的に対象範囲別ストレージ機能を無効にすることができます。

とあるがいつまで使えるかはよくわからん

##要件まとめ
・targetSdkVersionを29に変更する
・画像をサーバーに送れるようにする
・アプリは複数ある(minSdkVersionはまちまち
)
・すぐに更新しなければならなくなる事を考えて requestLegacyExternalStorage は使いたくない

##解決策
選択したファイルを自アプリのキャッシュに一度保存してそかからサーバにアップする

##苦戦した事
・minSdkVersionがまちまちのため、使える手段が少なかった(Paths も Files も使えない)
・FileInputStreamしただけでも怒られる
・1Byteづつコピーするのは時間がかかりすぎる

##実際の対応
URIからInputStreamを作ってそっからChannelをかませて自アプリのキャッシュDirに出力した

##実際の実装（一部抜粋）
```java:
        cacheFile = new File(activity.getCacheDir(), fileName);
        try {
            InputStream inputStream = activity.getContentResolver().openInputStream(fileUri);

            FileOutputStream fOutputStream = new FileOutputStream(cacheFile);


            try {
                fOutputStream.getChannel().transferFrom(Channels.newChannel(inputStream), 0, Long.MAX_VALUE);
            } finally {
                fOutputStream.close();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        return cacheFile.getPath();

```

##最後に
色々長時間ごにょごにょしてた気がするけど終わってみれば「こんなものですむのか・・・」といったエンジニアあるある

何かご指摘事項等ありましたらお手柔らかにお願いします
EC2概要

# EC2の構成要素

| 役割       | AWS               |
|:------------|:------------------|
| OS          | AMI               |
| CPU         | インスタンスタイプ   |
| Memory      | インスタンスタイプ   |
| SSD         | EBS               |
| NIC(※1)     | ENI(※2)       |

※1.Network Interface Cardの略
※2.Elastic Network Interfaceの略

## AMI

- Amazon Machine Imageの略
- EC2インスタンスが起動するための設定ファイル
    - どのOSやミドルウェア、アプリをインストールするか
    - どのユーザがAMIを起動できるかという設定
    - EBSのボリューム設定
- 異なるリージョンにコピーすることもできる
- ひとつのAMIでEC2を何台も複製できる
- OSやアプリケーションの情報が設定されている
- OSはAmazon Linuxが一般的
    - 各種Linuxディストリビューション
    - Windows Server

## インスタンスタイプ

- CPU、メモリなどの構成パターン
- インスタンスファミリーで分類され、さらにインスタンスサイズで選択肢が複数ある

## EBS

- ディクスストレージを指す
- AZで自動で冗長化

### EBS種類

| 種類       | 特徴               |
|:------------|:------------------|
| 汎用SSD          | デフォルト。基本コレを使う               |
| プロビジョンド IOPS SSD(iol)         | 高性能DBへ接続する時など   |
| スループット最適化HDD      | データウェアハウス,ビッグデータ,ログ処理など   |
| Cold HDD(sc1)         | 安い アーカイブ保管               |

### EBSのスナップショット

- EBSをバックアップとして取得したファイル
- 保管場所はS3
- スナップショット自体をEC2に付け外しはできない
- 増分バックアップ方式
    - バックアップ時間が短い
    - 容量を逼迫しない
- AZ内で自動で冗長化されるため高い耐久性がある
    - AZを跨いだコピーはS3を経由する必要がある

# キーペア,インスタンスメタデータ,ユーザデータ,Cloud-init

## キーペア

- ログインの管理を行う。秘密鍵と公開鍵のペアのこと。
- 公開鍵で暗号化したら秘密鍵でしか開けることはできない
- 秘密鍵はpem形式になっており、外部からアクセスできないようにする
- **秘密鍵を失った場合は、AMIとしてバックアップし、起動する時に新しいキーペアを作成する。**

## インスタンスメタデータ

- EC2インスタンスに埋め込まれている自分の情報。
- EC2が起動中の場合、以下のようなcurlコマンドで自身の情報を取得することができる
    - `curl http://xxx.com/latest/meta-data`
    - 使用しているAMIのIDやローカルのIPアドレス、所属しているサブネットIDなどが取得できる。

## ユーザデータ

- インスタンス起動時に一回だけ実行するスクリプト
- **再起動時に実行されるものではない** 
- **rootユーザで実行され、作成されたファイルもroot権限**
- 操作はインタラクティブではない。
    - 例.yumコマンドのオプション無しなどは使えない

## Cloud-init

- クラウド系インスタンスの初期構築を手助けするオープンソースのアプリケーション
- Amazon Linuxにはデフォルトで/etc/cloud/配下に設定ファイルが存在し、インスタンス作成時にどういった動きをするか指定できる

# 引用

https://www.youtube.com/watch?v=k1mhE5CrO2k&list=PLtpYHR4V8Mg_-RE0VBPeEqIDfFbzz-1ea&index=1
https://www.youtube.com/watch?v=zAQ6ws5kzEg&list=PLtpYHR4V8Mg_-RE0VBPeEqIDfFbzz-1ea&index=2
https://www.youtube.com/watch?v=1MMXigDxTdc&list=PLtpYHR4V8Mg_-RE0VBPeEqIDfFbzz-1ea&index=3
Unity で暗号化した SQLite (SQLCipher) を使うやり方のまとめ


# 暗号化はいらないときの基本

SQLite をシンプルに使うやりかたは、前の記事に書いたとおりです。

- [Unity で SQLite を使う基本的な使い方まとめ](https://qiita.com/sh1ch/items/a2750ff30f793d712f7d)

# 暗号化が必要になったとき

実際にアプリを公開するときに、DB ファイルの中身があっさり書き換えることができるのは、ちょっと……って思うなら暗号化がベスト。でも、これは自分で SQLite3 のライブラリーをコンパイルする道を選択したのと同じことだと思います。

[GitHub - SQLiteUnityKit](https://github.com/Busta117/SQLiteUnityKit) を利用しつつ Unity で SQLite を使うとき、暗号化するなら JAVA なんかがライブラリーの中に入ってくると邪魔になります。このキットはシンプルに DllImport で関数を呼び出してるだけです。

なので、なるべくシンプルに dll と so ファイルを作る必要があると思います。（x86/x64 win/android の４パターン）

このあたりを記事にまとめたので、ショートカットをメモ。

- [Unity SQLiteUnityKit 暗号化 SQLite3 を Windows で利用する（DLL コンパイル）](https://shikaku-sh.hatenablog.com/entry/unity-sqlite3-to-sqlcipher-encryption-dll)
- [Unity SQLiteUnityKit 暗号化 SQLite3 を Android で利用する（.so コンパイル）](https://shikaku-sh.hatenablog.com/entry/unity-sqlite3-to-sqlcipher-encryption-so)

あと、SQLCipher のパスワードは６４文字の 16 進数のテキストにすることでハッシュ化の回数（ストレッチング）を自分でやることができる。通常の設定はその回数が十分大きいので、ゲームで使う分にはアクセス速度に不満が出てくることがある。ケース・バイ・ケースで考えて、パスワードを自分でハッシュ化すると良いケースもあると思います。

- [Unity パスワードを固定長（64 文字）のハッシュ値に変換する](https://shikaku-sh.hatenablog.com/entry/unity-sqlcipher-password-to-hash)

> ビギナーなので、間違いがあったらすいません。（おしえてください）このあたりの記事は 2020/02 時点では、数が少ないので、もうすこしネタが増えると嬉しく思います。
vimの操作を覚える

# Insert Mode
|Key|Desc.|
|:---|:---|
|Ctrl-t|右にインデントする|
|Ctrl-d|左にインデントする|
|Ctrl-w|カーソル左の単語を削除する|
|Ctrl-u|カーソル左を全部削除する|
|Ctrl-a|前回入力した文字を再入力する|
|Ctrl-o|一時的にノーマルモード|
|Ctrl-x Ctrl-n|入力補完（Ctrl-n, Ctrl-pで候補選択 Ctrl-eでキャンセル）|

# Normal Mode
|Key|Desc.|
|:---|:---|
|:e [ファイル名]|指定したファイルを開く|


# Links
https://cocopon.me/blog/2013/10/vim-map-noremap/

http://komaken.me/blog/2014/04/30/%E7%9B%AE%E6%8C%87%E3%81%9B-vimrc%E3%82%B3%E3%83%94%E3%83%9A%E8%84%B1%E5%8D%B4vim-key-mapping%E3%81%AE%E5%9F%BA%E6%9C%AC%E7%9A%84%E3%81%AA%E3%81%93%E3%81%A8%E3%81%BE%E3%81%A8%E3%82%81/
ユーザー目線のVueコンポーネント実装

## この記事について

Vueを開発・運用してアプリケーションの規模が段々増えてきました。

チームの人員も増やしていく中で慣れていないエンジニアがコンポーネントの実装に関わるというケースが増えてきて、どんなデータ構造やアクション定義を作るのが良いのか悩んでいるケースを見受けるようになりました。

今回は自分がコンポーネントを実装する時に考えていることを簡単に紹介しておきます。

## コンポーネントはユーザーに最も近いコード

コンポーネント思考で実装していくと、ユーザーと近い距離に居るコードは各コンポーネント郡になります。言い換えるとコンポーネントとユーザーは密接な関係にあり、お互いの共通認識が合っていることが望ましいということになります。

利用するユーザーの思い浮かべるデータ構造や行動と実装されたコードの変数や関数が同じであるということです。つまりコンポーネントを使うユーザー側の気持ちがわからなければコンポーネントの実装も困難ということです。

サンプルです。

```vue
<template>
  <div>
    ...何かしらのコンテンツ

    <button @click="toggleFavorite">
      <template v-if="favorite">
        いいね！を解除
      </template>

      <template v-else>
        いいね！する
      </template>
    </button>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  data() {
    return {
      favorite: false
    }
  },
  methods: {
    toggleFavorite() {
      this.favorite = !this.favorite
    }
  }
})
</script>
```

何かしらのコンテンツに対していいね！したりするサンプルです。この実装には2つの問題点があります。

- ユーザーにとってはいいね！なのにコード上ではお気に入りという変数名になっている
- いいね！を変更する処理がコード上では同一の関数で定義されている

どちらも動作上は問題ありません。バグもありません。ですが後々の機能追加や変更などで破壊的変更をする必要が出てしまうコードで良いコードとは言えません。何故ならユーザーの行動原理から外れている実装だからです。

## ユーザー側の名称でデータ構造を定義

`favorite` をいいね！として扱う場合、機能追加で「**お気に入りを追加したい**」と言われた時にどうでしょうか？ `favorite2` と定義してやり過ごすことはできますが、今後コードを見た人が混乱してしまうと思います。

古くから運用しているサービスになると歴史上データベースやAPIが `favorite` になっているケースがあります。サンプルではバックエンドと連携していませんが、こういった**アプリケーションのサービス内の名称とユーザー側の名称が違う問題はそのままコンポーネントの実装にまで影響してしまう**ケースが多くあります。

統一することが理想ですがデータベースごと名称の変更を全て反映するのは規模によっては難しいです。でも差異を無くしておくことはできます。

フロントエンドは比較的変更がやりやすい分類なのでこういったものは先にフロントエンド側で吸収しておくことで、機能追加や改善・インフラ整備の時に役立つことになるでしょう。

## ユーザーの行動に沿った関数を定義

`toggleFavorite` という関数は効率的です。ですがユーザーの意思とは連動していません。

極端な例ですが、例えば「**誤動作を避ける為にいいねする時だけ確認のアラートをして欲しい**」といったユーザーの要望を反映する時にどうでしょうか？両方の機能を内包している為、片方のアクションに対して何か付加価値を付け足す時に拡張しにくいと感じませんか？

ユーザーにとって「**いいね！する**」という行動と「**いいね！を解除する**」という行動は全く別の意思から行われるアクションです。こういったユーザーの行動ごとに特殊な処理を挟むケースはフロントエンドではとても多いです。経験上Vuexでステート管理すると更に複雑化していきます。

「関数は最低限の方が...」「HTML上では同じ場所にあるボタンなのに...」と思うこともあるかもしれません。ですが、あくまでアプリケーションは利用するユーザーの為に動くべきであり、機能追加や変更もユーザーの行動結果から発生していくものです。

修正後のコードです。

```vue
<template>
  <div>
    ...何かしらのコンテンツ

    <button v-if="like" @click="unlikeContent">
      いいね！を解除
    </button>

    <button v-else @click="likeContent">
      いいね！
    </button>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  data() {
    return {
      like: false
    }
  },
  methods: {
    likeContent() {
      this.like = true
    },
    unlikeContent() {
      this.like = false
    }
  }
})
</script>
```

## コンポーネントの実装 = ユーザーの意思

この考え方はテストケースも作成しやすい利点があります。

`toggleFavorite` は現実のユーザーの行動と反しています。 `likePost` や `unlikePost` を実行してデータ構造をチェックする方がよりユーザーの行動に近いテストケースになると思います。

同じようにバグの発生源を特定する上でも有効です。問い合わせなどのユーザーの行った行動がそのまま再現手順に近くなり、関連するデータやメソッドに対してデバッグを行えば見つかりやすくなります。

実装上ではとても小さなことですが、こういった考えが規模の大きくなったアプリケーションにおいて効果的になっていきます。まずはユーザーの気持ちになって脳内でコンポーネントを操作するイメージを掴むことが大事です。
メタタグ noindex, nofollow

メタタグ noindex, nofollowについてまとめていこうと思います

メタタグは、サイトの情報を検索エンジンやユーザーに伝えるために必要なタグです。

##メタタグの押さえておきたい4つの使い方

####文字エンコード
```
<meta charset="UTF-8"> 
```

上記のようにエンコードを指定することで文字化けを防ぐことができる

エンコードとはコンピューターが数字しか理解できないので
その数字を言葉に変換するものです


####メタディスクリプション
```
<meta name="description" content ="サイトの概要説明"
``` 
![スクリーンショット 2020-02-14 19.08.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568070/de87c649-ce0d-9d49-db8a-f42ceac4ed23.png)

・検索結果に表示されるメタディスクリプションの最大の文字数が120文字程度
・検索結果に表示される部分なので、文章次第でクリック率が上がり、アクセス数アップにも繋がる大事な部分
・検索されたキーワードで一致する文字があると太字で表示されます。そのため、検索されそうなキーワードを入れておくと尚良い

####スマホサイズの最適化
```
<meta name="ViewPort" content="witdh=device-width, initial-scale=1">
```

・「viewport」を設定することで、スマホやタブレットでも最適なページをユーザーに見ていただくことができます。

・これはスマホ用ページには必須ですし、PC/スマホで同じページを表示するレスポンシブにも必須です。



#### 検索エンジンを操作する
```
<meta name="robots" content="noindex nofollow"
```

サイト内に低品質なページがある場合には、Googleはサイト評価を落とします。そのため低品質なページは削除した方がいいのですが、そうしたくない場合は「noindex,nofollow」を使って対策することができます。
循環的複雑度について

## 動機

[DX Criteria 2.2ソースコードの明確さ](https://cto-a.github.io/dxcriteria/system_2.html)に記載されていたので調べた時のメモ書き。

## 概要

[Wikipedia](https://ja.wikipedia.org/wiki/%E5%BE%AA%E7%92%B0%E7%9A%84%E8%A4%87%E9%9B%91%E5%BA%A6)から抜粋。DX Criteriaでは下記内容をソースコードにおいて継続的に検証・測定する仕組みを導入した方が良いと解釈した。

> 循環的複雑度（英: Cyclomatic complexity）とは、ソフトウェア測定法の一種である。Thomas McCabe が開発したもので、プログラムの複雑度を測るのに使われる。循環的複雑度は、プログラムの制御フローをグラフとして描くことで計算される。グラフのノードはプログラムのコマンドに相当する。2つのノードを結ぶ有向エッジは、第一のコマンドを実行後、次に第二のコマンドが実行される可能性があることを示している。
if文やfor文のような分岐点のないソースコードの場合、その複雑度は 1 であり、そのコードには1つの経路しかない。コードに1つのif文が含まれていれば、コードには2つの経路があることになる。

Goを書くことが多いので測定できるパッケージがあるか調査する。

## パッケージ

`golang cyclomatic complexity package`のキーワードで検索して該当したパッケージを抜粋する。最新のコミット履歴は2015年と古いがスター数が多いので`fzipp/gocyclo`を試すことにする。

* [fzipp/gocyclo](https://github.com/fzipp/gocyclo)
* [uudashr/gocognit](https://github.com/uudashr/gocognit)
* [alecthomas/gocyclo](https://github.com/alecthomas/gocyclo)

## サンプル

適当なサンプルコードと結果。

```golang
package sample

func doSometing() {

}

func doSometing1(s string) {
	if s == "1" {

	}
}

func doSometing2(s string) {
	switch s {
	case "1":

	case "2":

	default:

	}
}
```

```bash
$ gocyclo sample.go 
4 sample doSometing2 sample.go:13:1
2 sample doSometing1 sample.go:7:1
1 sample doSometing sample.go:3:1
```

## 雑感

得た結果の良し悪しをどのように定めるのかが気になるところだったが調べたところマチマチな印象だった(知りたい）。言語の書き方というか思想も多少影響するような気がした。lintツールである[golangci-lint](https://github.com/golangci/golangci-lint)では`alecthomas/gocyclo`を利用しておりデフォルト値は30だが、10-20を推奨しているらしい。

## 参考

* [循環的複雑度](https://ja.wikipedia.org/wiki/%E5%BE%AA%E7%92%B0%E7%9A%84%E8%A4%87%E9%9B%91%E5%BA%A6)
* [循環的複雑度について](https://qiita.com/yut_arrows/items/16749e02313109071338)
* [Code complexity metrics (McCabes cyclomatic complexity)](https://groups.google.com/forum/#!topic/golang-nuts/8SB9H1D34qk)
初心者から考えるAIとは？

#１．概要

最近AIという言葉がはやり出していますね。今後の主要な技術となっていますので、簡単にAIについて調べてみました。できる限り簡単になるようにまとめていますので、実際のAIとはちょっと違っている可能性があります…

#２．AIとは？

**AI（artificial intelligence　＝人工知能）**
AIとは、人の脳をコンピュータを使って解き明かす**研究全般を指す言葉**です。そのため、「人工知能は関係ないだろう」、ということでもAIと言ってしまうことがあるようです。

例えば、以下はAI研究の中で生まれたり、使われたりするキーワードになります。

- ビックデータ
- 音声認識
- 文字認識
- 自動翻訳
- 検索エンジン

上記どれもが人工知能を生み出すことができなかった技術群になります。（今後新しい技術が出てきたら、変わるかも…）ただ、その技術を使って、Googleの検索エンジンや、音声認識の翻訳システムなどができているので、「人工知能はできなかったが社会に役立つ仕組みに変えることができた」、と言えます。

そのため、AIに関して研究することは、**決して人工知能が作れなくても応用的に別のシステムを作ることができるので学ぶものとしては非常に優秀**、と言えるではないかと思っております。
（だからブームとなっている！！）



#３．AIの基本構造

AIの仕組みをざっくりと言ってしまうと以下となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/b79a3f5a-5cfd-d434-c4c4-59d254f9e3df.png)


そしてこの入力に何を入れるか、処理に何を行うか、によって技術的な構造が変わってきます。

- 入力に大量のデータを使う！　⇒ビックデータ処理
- 処理に人の脳と同じことをさせる！　⇒ニューラルネットワーク
- 処理に一定のルールを先に持たせる！　⇒機械学習

機械学習のルールについてもう少し詳しく言うと、例えば時間が来たら自動でツイートする機能、などが該当します（botのこと、botもある意味AIの1つに数えられている）

## ディープラーニング

最近の主要な技術に「ディープラーニング」というものがあります。これを簡単に説明すると以下の図のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547663/61d132e6-d0b9-5922-8294-9e44d9d56cfb.png)


つまり**処理の部分を何層にも重ねること**によって、通常の処理ではできないことを実現して行く、という方法になります。また、**入力と出力に同じものを使う**ことで、真ん中の処理部分を最適化することができます。（ただ処理を重ねるだけだと、初めの処理にちょっとしたずれがあった場合、そのずれをどんどん引きずるので、最後の出力のずれが大きくなる）

こちらを用いることで以下のようなメリットがあります。

- 処理から人間では見つけることのできない方法を算出できる（入力と出力だけ決めて、それをどう処理するかはPCに任せているので）
- どこかの処理が故障しても、何層も重なっているので無効にできる
- 一度処理が最適化すれば何度でも使える

ただ、何層も処理を重ねるので、以下のようなデメリットもあります。

- 処理に膨大な資源が必要！（数千台のサーバ＋時間がかかる）
- **処理が正しいかどうかの判断ができない！**（入力と出力しかわからない…）

特にディープラーニングの一番問題点は、**どのような処理によって結果を導き出したのかわからない**ことです。つまり、もしAIが暴走したとしても、**なぜ暴走したのか誰にも分らない**、ということになります。

そのため、AIについて警鐘を鳴らしている人たちは、AIの可視化という研究を行っているようです。
■参考
「人工知能の思考過程を可視化する、「AI監視ツール」を生み出すスタートアップ企業たち」
https://wired.jp/2019/12/11/these-startups-are-building-tools-keep-eye-ai/

#４．AIを使ってできること

現在の技術力だと、ルールが明確であるもの、答えがはっきりしているものをAIで自動化するのは、比較的簡単ではないかと思います。
（将棋のプログラムやエアコンの温度制御、botなど）

ただ、複雑に絡み合ったものから答えを出す、というものはディープラーニングの力を借りる必要があり、コストの面から実現は難しいのではないかと思います。
（新たな新薬の開発、人間のように受け答えするシステムなど）

逆を言えば、**今の自分たちが行っている業務を一定のルールに書き換えることができれば、AIによる自動化がより進む**のではないかと思います。

#５．まとめ

AIは夢のある分野だと思いますが、書籍を読んでいる限り難しい技術ですね…
ただ、音声認識、画像処理などにフリーで使えるツールを公開している企業もありますので、ちょっとした研究であれば比較的容易にできる環境が整っていると感じています。

ちょうど[Qiita x COTOHA](https://zine.qiita.com/event/collaboration-cotoha-api/?utm_source=qiita&utm_medium=top_banner)でイベントを行っているので、使ってみようと思います。
『少しの気配りでみんなが気持ちよく』ITカンファレンス参加者が音で気をつけるべき6つのこと

2020年2月13日
Developers Summit（通称デブサミ）2020に初めて参加してきました。

知らない技術に触れたり、いいチームとは何かを学んだり、とても刺激的で楽しかった。
平日にも関わらず参加させてくれた会社にも感謝。

でも、講演を聞いていて気になったことがいくつかありました。

それは参加者が発する

**「音」**

スピーカーが話す声のみが響く静かな空間では
些細な音が周りに迷惑をかけてしまうことがあります。

ということで私が気づいた
**ITカンファレンス参加者が音で気をつけるべき6つのこと**
を共有します。
　
　

※これは誰か特定の個人を非難・卑下するために書いた記事ではなく、

- 知らない間に誰かに迷惑をかけているかもしれない
- もしかしたら自分が迷惑をかけていることに気が付いていないかもしれない

のでまずは知ってもらうことが大切だと考えました。

前置きが長くなりました。早速見ていきましょう。


# 1.タイプ音

技術系カンファレンスなので、ノートPCを開いている方も他の講演イベントより多くいらっしゃいます。

そしてこのタイプ音はメモを取りたい方がタイプして発生するので
基本的に講演中ずっと鳴り響きます。

近くに大きな音を立ててタイプしている方がいると講演に集中できず、
気が散ってイライラしてしまうものです。

今回のデブサミ2020でも講演が始まる前のスクリーンに
`「タイプ音が気になって集中できないと言うお声を多数いただいております。
皆様のご配慮をお願いいたします。」`
のような注意喚起がありました。（表現は多少違うかもしれません。~~写真撮っとけばよかった~~）

余談ですが画面の明るさMAXの方、眩しいです:dizzy_face:


### 結論
`普段より優しいタイピングを心がけくださるとうれしいです`


# 2.カメラシャッター音

iphoneのデフォルトのカメラアプリ特有の
**「カシャッ！:camera:」**
という音がどの会場でも鳴り響いていました。

こちらも講演前のスタッフの方から
`「カメラ撮影は可能ですが、音の出ないアプリをお使いになるなど
ご配慮をお願いいたします。」`
とアナウンスがありました。

対談形式よりもスライドを用いるものが大半で、
スライドが変わる毎に「カシャッ！」は静かに聞いている身からしたら辛いものがあります。

余談ですがフラッシュ撮影:camera_with_flash:も眩しいです:dizzy_face:

### 結論
`無音カメラアプリかデジカメを事前にご用意いただけるとうれしいです`


# 3.話し声

これは言うまでもないかもしれません。
ヒソヒソ話でも聞こえてますよ。

### 結論
`お知り合いどうしても、お話しは終わるまで我慢していただけるとうれしいです`


# 4.鼻をかむ音

鼻をすする音もここに含まれるかもしれません。

鼻をかむという行為に対する感覚や価値観は人それぞれだと思うのですが、
「しゃっくり」や「くしゃみ」と違って**意識的にする行為**である点で防げるのではないかと提案したいです。

風邪を引きやすい季節ですし、鼻が気持ち悪いのはわかるのですが、
スピーカーが話す声のみが響く静かな空間では
**「フーーーン！:triumph:」**ってされると結構びっくりします。

### 結論

`鼻をかむのは終わるまで待つか、一度退室して済ませていただけるとうれしいです`



# 5.カバンからものを取り出す音や飲み物の音

実際に遭遇したのは

- ビニール袋が擦れる音**「ガサガサッ！」**
- 炭酸飲料を開ける音**「プシュッ！」**
- 水筒を開ける音**「キュッ！」**

ですね。

デブサミでは会場に自動販売機やコンビニが近くにないということで
運営様の配慮によりミネラルウォーターのペットボトルが配布されていました。

講演中に喉が渇いた場合は、**炭酸じゃないペットボトル飲料**が無難かもしれません。
また事前に

- カバンの一番取り出しやすい場所に置いておく
- カバンから出して足元に置いておく

など心配りが出来ているとガサゴソしないで済むのかなと思います。

### 結論
`飲み物は無難な選択と事前に置く場所に配慮いただけるとうれしいです`



# 6.携帯電話の着信音

こちらは一瞬だけなのでそれほど気にならないかもしれませんが、
私が聞いていた講演の中で、スピーカーの方も着信音にびっくりして
`「えっ、、、、大丈夫ですか？続けていいですか？」`
と講演が一瞬中断してしまう場面がありました。

マナーモードにし忘れちゃうこと、ありますよね。


### 結論
`大勢の方がいらっしゃるイベントでは
スマホをポケットやカバンにしまう前にマナーモードか確認していただけるとうれしいです`



# あとがき

賛否両論あるテーマだと思いますが、
少しの気配りでみんなが気持ちよく参加できるように、
そして少しでも技術系カンファレンス・イベントの評判が良くなり成功することを願っています。
テーブルを”楽に”角丸にする

## 基本的なやり方
<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="css,result" data-user="sphenisc" data-slug-hash="WNvrzav" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="WNvrzav">
  <span>See the Pen <a href="https://codepen.io/sphenisc/pen/WNvrzav">
  WNvrzav</a> by sphenisc (<a href="https://codepen.io/sphenisc">@sphenisc</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
ふつうのテーブルに

```css
border-radius: 8px;
border-collapse: separate;
border-spacing: 0;
overflow: hidden;
```
を付けるだけでいいです。
ただ、IEではうまくいかないらしい。

## もっと楽に

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="css,result" data-user="sphenisc" data-slug-hash="dyoGmrq" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="dyoGmrq">
  <span>See the Pen <a href="https://codepen.io/sphenisc/pen/dyoGmrq">
  dyoGmrq</a> by sphenisc (<a href="https://codepen.io/sphenisc">@sphenisc</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
ふつうのテーブルを角丸のラップで包んで角を消す方法です。
この方法の良いところは既に作った後のテーブルをtbl_wrapで包むだけで角丸に加工できることです。
Unreal Engine 4でのHoudiniチュートリアルプロシージャルレベルデザイン。

![Procedural_Level_Design_C4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586143/691d6a2d-2942-cde5-91d9-2f353e0d2fcb.png)

最初から最後まで、Houdini 17.5で手続きレベル生成ツールを作成し、強力なHoudini Engineを使用して、完成したアセットをUnreal Engine 4にデプロイします！

完全版：https://gum.co/LVLDesign1
無料デモ版：https://gum.co/DemoLVLDesign1

Unreal Engine 4のHoudiniで自動レベル生成プラグインを作成する方法を学びます。
内部とは？
   11ビデオの章

   Houdiniプロジェクトファイル

   HDAアセット

   アンリアルエンジン4プロジェクト+すべてのアセット

![Level.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586143/96c6fcf7-cf0a-12b3-2c47-57b45f819a4d.gif)
![Level5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586143/6828e378-a230-67f9-80ab-d5ca0fdfb826.gif)


はじめに
第1章サイズ管理9分

第2章散乱点のグリッドへの転送19分

第3章カスタムノードの作成9分

第4章階段の作成24分

第5章レベル生成のベースの作成33分

第6章舗装の作成22分

第7章列の作成20分。

第8章壁の作成34分

第9章境界線の作成24分

第10章HDAの作成9分

第11章UE4へのインポート26分

ツール：
Houdini 17.5
Unreal Engine 4.22

要件：
中級Houdiniナレッジ

フォーマット：
各章の冒頭には、チュートリアルで何が起こるかを示すアニメーションのイラストがあります。 重要な瞬間に音声解説付き。

![Plugin.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586143/1426b222-5fa1-0e15-7796-ac7a101a7df7.jpeg)
![Procedural_Level_Design_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586143/2499dc7d-64ac-3e4d-b469-6e5ea399a938.png)
![Procedural_Level_Design_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586143/18fe7116-b41a-bd6f-80d9-09e40240383a.png)
![Procedural_Level_Design_9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586143/cce72fc0-040b-7c4c-ee14-c0fc2b16efa8.png)
![ezgif.com-optimize.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586143/10367cc4-3773-d53d-baaa-8c155fad5d82.gif)
TypeScriptで引数がないメソッドとあるメソッドをオーバーロードする方法

TypeScriptで
引数がある場合はsetter(しつつthisを返したい)
引数がない場合はgetterという事がしたくて

調べたところ引数なしの場合は
引数をoptionalにしてオーバーロードするらしいんですが

ちょっと気持ち悪いなぁ
void型の引き数にしたらいけたりして？

<del>と思ってやったらいけちゃったのでメモです。</del>


```ts
class Hoge {

  width(v:number):this;
  width(v:void):number; // 引数の型をvoidにしたらいけた
  width(v:any):any {
    if(typeof v === 'number') {
      this._width = v;
      return this;
    } else {
      return this._width;
    }
  }
}
```

と思ってやったらいけるにはいけたんですが
コメントにてもっと素晴らしい方法を教えていただきました。
(もっと素晴らしいというか自分のやり方はわりとクソだなと思いつつある)

```ts
width(v: number): this;
width(): number;
width(...v: [] | [number]): this | number {
    // ...
}
```

rest parameters(...)を使って
可変長引数として引数を受け取って判定する方法

引数の数が異なる場合のオーバーロードはこの方法が好きかも
と思います。


しかし引数の数は同じだけど、型が異なる
というケースの場合はこの書き方は少し冗長かもしれないですね


できるかできないかで言えば
方法はいくつもあるとは思いますが
より良いものや最適解を求めていきたい。
#シェル で1行で無限ループする書き方


ワンライナー

```
while true; do <command>; done
```

例

```
while true; do echo "ok" && sleep 1; done
```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2985








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
GNU Autotools で make distで作成したアーカイブに所望のファイルが含まれないときの対処

# GNU Autotoolsでmake distで作成されるtar.gzファイルに中身が足りない

Autotool(automake)で、`make dist`で生成される`~~~.tar.gz`ファイルにどのようなファイルが含まれるかは、依存関係を自動的に察してくれるようになっているが、必要なものが含まれていない場合がたまにある。

例えば`bin`サブディレクトリにシェルスクリプトファイルを置いて、`Makefile.am`に

```Makefile:bin/Makefile.am
bin_SCRIPTS = a.sh b.sh c.sh
```

と記述されている場合には、これらのファイルには生成されるアーカイブファイルに含めない挙動のようである。たとえば、'configure.ac'の`AC_CONFIG_FILES`に含まれている場合(`./configure`で、`a.sh.in`から`a.sh`が生成されるような場合)には、生成元の`~~.in`はアーカイブに含める挙動になっているので問題にならないが、そうでない場合には問題になる。

# 解決策

make変数の`EXTRA_DIST`定義し、そこにも追加する。

```Makefile:Makefile.am
bin_SCRIPTS = a.sh b.sh c.sh

EXTRA_DIST = a.sh b.sh c.sh
```
RailsでFontAwesomeの導入〜大きさを変えるまで

#はじめに
railsでFontAwesomeを使いたいと思い調べていたところ、
大きさまで変える記事が見当たらなかったため投稿してみました。
#実行環境
Ruby : 2.6.3
Rails : 5.2.4
slim : 4.0.1
font-awesome-sass : 5.12.0
上記の環境で実装いたしました。

#FontAwesomeの導入
Gemfileに以下を記述

```ruby:Gemfile

gem 'font-awesome-sass'
```
gemをインストール

```
bundle install
```
/app/assets/stylesheets/application.css
を
/app/assets/stylesheets/application.scss
に変更する

```
mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss
``` 

/app/assets/stylesheets/application.scssに以下を記述

```ruby:application.scss
@import "font-awesome-sprockets";
@import "font-awesome";
```
上記の順番通りに記述したことで、FontAwesomeが使えるようになった。

#実行結果
font-awesome-sassがインストールされたことにより、ヘルパーメソッドが使えるようになりました。
このメソッドを使うことでアイコンを表示させます。

```ruby:~.html.slim
= link_to "#" do
  = icon 'fab', 'amazon-pay'
```
これでアイコンが表示されました。
[今回使用したアイコン](https://fontawesome.com/icons/amazon-pay?style=brands)

<img width="88" alt="Qiita使用画像.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502928/bb2e40e3-f473-2194-1568-667d5a01872a.png">

#大きさを変更する
上記で用いたヘルパーメソッドを用いることによって好みの大きさに変更することも可能です。

```ruby:~.html.slim
= link_to "#" do
  = icon 'fab', 'amazon-pay fa-3x'
```
このメソッドは次のように構成されています。

```ruby
icon 'スタイル名', 'アイコン名 (大きさ指定)'
```

大きさの指定をしない場合は、アイコン名のみを記述し、
大きさ指定をする場合は、アイコン名の後にスペースをあけ、'fa-(サイズ)'で好きな大きさに変更することができます。サイズに関しては公式サイトをご覧ください。
[Font Awesome](https://fontawesome.com/)

#最後に
初めて記事を投稿してみました。
分かりやすい記事になったかは不安ですが、誰かの助けになれば幸いです。
MySQLでAUTO_INCREMENTをリセットする

テーブルのレコードを全削除する前提になります。
### TRUNCATE文を使う
`TRUNCATE` = テーブルのレコード全件削除

```
mysql> TRUNCATE TABLE ${table_name};
```
でリセットできます。

### ALTER文を使う
`ALTER TABLE` = テーブル定義を変更
`TRUNCATE`文でリセットできない場合（または抵抗がある時）は`ALTER文`でリセットできます。

```
mysql> ALTER TABLE ${table_name} AUTO_INCREMENT=1
```
でリセットできます。

### どんなときに使うか？
リリース前にテストデータを全て削除する時に使います。
`TRUNCATE`文でできたらそれで良いのですが、
`DELETE`文で全レコード削除しても`AUTO_INCREMENT`はリセットできないのです・・・。
例えばユーザーIDに`AUTO_INCREMENT`を設定しているなら、
ユーザーIDが３０まで１件ずつあるレコードを全て削除してから新たにレコードを挿入すると３１から始まってしまいます。
それを防ぐために`AUTO_INCREMENT`にリセットをかけます。

###参考
[【MySQL】auto_increment（オートインクリメント）の連番状態をリセット（初期化）する](https://qiita.com/sola-msr/items/d6c70995ddd95361dda7)
[全てのデータを削除する(TRANCATE TABLE文)
](https://www.dbonline.jp/mysql/insert/index12.html)
Wordpress アニメーション

Shortcodes Ultimateを使ったアニメーションでよく使うものだけを記録する


###fadeInpUp（下から出現） 

```.js
[su_animate type="fadeInUp" duration="1" delay="0"]textタグ又は画像imgタグ[/su_animate]
```

###fadeDown（下から出現） 

```.js
[su_animate type="fadedown" duration="1" delay="0"]textタグ又は画像imgタグ[/su_animate]
```


###fadeInLeft（左から出現）

```.js
[su_animate type="fadeInLeft" duration="1" delay="0"]textタグ又は画像imgタグ[/su_animate]
```

###fadeInRight（右から出現）

```.js
[su_animate type="fadeInRight" duration="1" delay="0"]textタグ又は画像imgタグ[/su_animate]
```
Rustが流行ってほしい

#Rustはゲーム開発に向いている理由
- [省メモリ](https://qiita.com/kawaguchi5460/items/e92fa5580a2ecf27b321#省メモリ)
- [高速](https://qiita.com/kawaguchi5460/items/e92fa5580a2ecf27b321#高速)
- [バグが起きにくいため(特に海外に多い)損害賠償等に強い](https://qiita.com/kawaguchi5460/items/e92fa5580a2ecf27b321#バグが起こりにくい)
- [デフォルトがReadOnly](https://qiita.com/kawaguchi5460/items/e92fa5580a2ecf27b321#%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%81%8Creadonly)

##省メモリ
メモリや容量はゲーム開発をする上で一番大切な概念です。[以前の記事](https://qiita.com/kawaguchi5460/items/c9e2ac2f9dccdbb5709b)を参照してください。ゲーム開発における言語はC,C++,C#,Python,Luaが殆ど全てといっていいほどです。Pythonは遅いですが、**オブジェクト指向で書けるスクリプト言語**且つ演算子オーバーロードが利用でき且つ**省資源である**ことを考えると良い選択肢であるということを示しています。それ以上に遅い言語はPHP,ShellScript,PowerShell等の特定の物に特化した有名言語,scratch等の子ども用の言語くらいだと言われています。

##高速
Rustの速度はCと同じかそれよりやや遅い、C++(の多くのコンパイラ)より速いのでとても高速に動作します。MLのようなマクロや束縛等で最適化しやすいためという理由もあります(高速なライブラリの、readonlyを利用したインラインconst化)。C++のような"std","演算子オーバーロード",C#のような"const","for","use","ジェネリクス","型推論"等のゲームエンジニアがよく利用するであろう機能が存在します。stringについては組み込み型(str)とstd::string::Stringが存在します。C#もGCを省いた速度(GCが無ければ起動3秒後以降、C++の1.1倍くらいしか速度が変わらない)では問題がないですが、いつ起こるかわからないのでそこら辺の管理が大変です。またC#ほどではないにしろ**Java並み**に可読性が高い且つ、C++やC#の慣れている人だと学習コストが低いのでメリットが多いです。

##バグが起こりにくい
これは意外に重要です。よくゲームで実行時バグだったりクソゲーだったりも多いですが、その原因の多くはバグを生みやすい自由度にあります。多くは、マクロやtemplateや多重継承やgotoやdelateし忘れ等がいい例です。また、ゲームエンジンを使わない多くの場合組み込みエンジニアのようにアセンブラ他でハードウェア毎の実装をしなくてはなりません。
`DirectX >>> ハードウェア->抽象化->プログラム->具体化->ゲーム->抽象化->プログラム->具体化->ハードウェア`
これは多くの場合ゲームを作ることが目的になり、(ほんの少数の天才以外は)感性で面白いと感じるゲームを作ることが後回しになることが多かったのでゲームエンジンが生まれました。一つの文やオブジェクトで具体→抽象→具体と三段階踏まないとならないのはとても頭を使います。
`UE4(Unity) >>> プログラム->具体化->ゲーム->抽象化->プログラム`
こうなると理性に使っていたリソースを感性に使うことができるので、作っている途中にクソゲーだと気が付きわかりやすいので、客からの信用を落とさずに済みます。また、バグの多くもエンジン側によって最適化処理されているためマシです。但し、これにも問題があります。マクロの使用や無駄なtemplateの使用や多重継承やgotoの使用やdelateし忘れが発生している可能性が秘めているという点です。これを解決するであろうRustは非常に純粋で美しくC++erに優しい仕様となっています。これら問題は全てRustが解決し、ifは式、安全で高速、変数は束縛(下で詳しく話します。)というゲーム利用に最適化された機能がある点にも注目できます。

##デフォルトがReadOnly
グーグルのC++ガイドラインで
>理にかなっているのならば、常にconstを使ってください。 C++11では、いくつかのconstは、constexprを使うほうがよりよい選択です。

土方プログラマーでなければ、プログラムを書いているとconst autoだらけになることも多いのではないでしょうか?const_castを使うことも多いので、束縛は重要です。また、ReadOnlyの方が大胆な最適化が可能です。従って今後はゲームにRustを使うことになるのではないかと思っています。また、Rustの束縛はreadonlyを利用したインラインconst化で高速です。
Rspecでのユニットテスト

100度超えサウナでないと満足できない、プレイライフのサウナエンジニアの合原です。

当社では、現在、Ruby on Railsを用いてサービス開発をしています。また、Rspecを使ったテストも普段から行なっています。

そこで、今回はテストの効用、ユニットテストの重要性and少しだけサンプルを示してみます。

# 対象読者
- テストの効用がよくわからない人
- ユニットテストを書いたことがない人
- ユニットテストの効果がよくわからない人
- 効果的なユニットテストを書くにはどうすればよいか学びたい人
- `プレイライフではエンジニアリングをしているのか興味がある方`

# [Rspec](https://github.com/rspec/rspec)とは
こちらは言わずと知れた、ポピュラーなテストフレームワーク。
構文には一種のくせ（？）あるため、敬遠する人もいるが、一度覚えると、柔軟なテストができます。

## Rspecのメリット
* Rubyで最もポピュラーなテスティングフレームワーク
* メタ視点でのテストが書けるため、テストコードが自然言語っぽくなる
* ユニットテストに限らず、結合テストやブラウザテストなどにも使える

## Rspecデメリット
* 一定の学習コストがある

反面、一度覚えれば、より柔軟なテストが可能となる。

# なぜテストを書くのか
大きくは、以下の３つ。

* 改修時など、テストが失敗することで漏れや変更点が明確になり、デグレを防げる
* テスト自体が仕様となるため、コードの理解がしやすくなる
* コードの品質を上げられる


# ユニット（単体）テストとは

> ユニットテストとは、ソースコードの個々のユニット、すなわち、1つ以上のコンピュータプログラムモジュールが使用に適しているかどうかを決定するために、関連する制御データ、使用手順、操作手順とともにテストする手法である[1]。ユニットとはアプリケーションのテスト可能な最小の部品単位である、と直観的にとらえることができる

言い換えると、メソッドやクラスと言った単位で、想定された仕様どおりに動作しているかを検証するテスト。

# なぜユニットテストが重要なのか
基本的に、アプリケーションは各種モジュールの束でできているため、各モジュール単位に分解して、それぞれをの動作を検証（テスト）することは不可欠になります。
これができていると、さらに上位の各機能の結合テストはさらに容易になる。
自ずと、アプリケーションのテスト網羅性は高めることができます。

## 基本的な考え方
ユニットテストでは、クラスやメソッドを最小処理単位として扱い、引数を処理した「結果」と、想定される「期待値」（これを振る舞いと言う）の2つを検証（比較）します。

ここで、以下のような引く数を受け取り１を加算するだけのメソッドをテストすることを考えてみます。

```ruby

class Calc
  def add(arg)
     arg + 1
  end
end
```

## 1.テストケースを想定する
上記のメソッドからテストケースを想定すると、大きくは以下の２つのケースが考えられます。

1. 引数がnilの場合    
2. 引数が正常な数値の場合
3. 引数が文字列等の場合    


rspecで書くと..

```ruby

RSpec.describe Calc, type: :model do # テスト対象となるクラス
  describe '#add' do #テスト対象となるメソッド
    context '引数がnilの場合' do
      [ここに具体的なテスト内容]
    end
    context '引数が正常な数値の場合' do
      [ここに具体的なテスト内容]
    end
    context '引数が不正な値（文字列等）の場合' do
      [ここに具体的なテスト内容]
    end
  end
end
```

※ contextの箇所は英語でも日本語でもわかればいいと思います。テストの本質とは全く関係ないため。

こうすることで

* メソッドの振る舞いが明確になる
* テストを見るだけで、このメソッドの動作がわかる
* 仮にレビュアーであれば、ここを見るだけで、実は他にも動作ケースがありうるのであればテストケース漏れを指摘しやすくもなる
* 仮にプロダクション環境にデプロイ後でも、ここを見れば漏れが明確になり、修正が容易になる（メンテコスト下がる）
* 既存の振る舞いが明確なので、リファクタリングもしやすい

# 2. 実際のテストコード
最終的なコードは下記の通り。
※細かいrspecの文法については割愛。

```ruby

RSpec.describe Calc, type: :model do # テスト対象となるクラス
  describe '#add' do #テスト対象となるメソッド
    subject { Calc.new.add(arg)}
    context '引数がnilの場合' do
      expect { subject }.to raise_error NoMethodError
    end
    context '引数が正常な数値の場合' do
      let(:arg) { 1 }
      it { is_expected.to eq 2 }
    end
    context '引数が不正な値（文字列等）の場合' do
      let(:arg) { 'a' }
      expect { subject }.to raise_error TypeError
    end
  end
end
```

# まとめ
と言うわけで、あくまで簡易な例で一気に説明しましたが、ユニットテストを行うことで、
* コードの品質向上
* 将来的なメンテコストの下げられる（場合もある）

といったことが望めるのは少しおわかりいただけたか（？）と思います。
もちろん、Rspecに慣れないといけないと言った面もあります。
これからしっかりテストコードを書いていきたいと言う方に少しでも、お役に立てたら幸いです。


また、当社では、テストを軽視することなく、何よりもスピーディなサービス開発を実現することにも、果敢に挑戦しています。気になる方は、ぜひ、[こちら](https://www.wantedly.com/companies/playlife/projects)から。

### あわせて読みたい
[RSpecの公式ドキュメント](https://www.relishapp.com/rspec/rspec-core/v/3-1/docs)
[オブジェクト指向設計実践ガイド](https://gihyo.jp/book/2016/978-4-7741-8361-9)
ファイルを書き込んで読み込む

```py:1
s = """\
AAA
BBB
CCC
DDD
"""
with open ('test.txt', 'w') as f:
    f.write(s)

with open ('test.txt', 'r') as f:
    print(f.read())
```

```:1の実行結果
AAA
BBB
CCC
DDD
```

これを

```py:2
s = """\
AAA
BBB
CCC
DDD
"""
with open ('test.txt', 'w+') as f:
    f.write(s)
    f.seek(0)
    print(f.read())
```
と書ける。
書き込んだ後はインデックスが最後になるので、

```py:
f.seek(0)
```
で先頭に戻る必要がある。

w+は、
書き込み+読み込み。

```py:
with open ('test.txt', 'w+') as f:
    print(f.read())
```
とすると、
まず書き込みモードになり、
一旦、空になり、
何も書き込まず、
読み込む事になるので、
何も出力されない。
Middleman　ローカル環境の立ち上げ方　流れ

# 気をつけること
- ruby,nodeのバージョンを確認すること。
- 指定されているversionを合わす。

# commandでの流れ
`git clone --recursive git@github.com:なんとかなんとか.git
cd なんとか.com
npm run setup
bundle exec middleman build
bundle exec middleman server`
UITableViewCellの中のUIImageVewでアニメーションすると勝手に止まる件

`UITableView` の中に `UIImageView` を入れていて、その `UIImageView` に `animationImages` を指定してアニメーションを表示している時、テーブルのセルを選択するとアニメーションが止まってしまう。

## 解決法

`setSelected`, `setHighlighted`をオーバーライドしてその中でアニメーションを再開する。

```swift
class MyCell: UITableViewCell {

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        restartAnimatingIfNeeded()
    }

    override func setHighlighted(_ highlighted: Bool, animated: Bool) {
        super.setHighlighted(highlighted, animated: animated)
        restartAnimatingIfNeeded()
    }

    func restartAnimatingIfNeeded() {
        if imageView.animationImages != nil {
            imageView.startAnimating()
        }
    }
}
```

少々無理やりな気がするけど…あと最初のフレームから再生されてしまうのも気になる…
AWSにおけるサーバ構築手順メモ

アプリケーションサーバを構築する際、いつも忘れるので

## インスタンスを立てる
AWSサービスよりEC2を選択し、左サイドバーのインスタンスを選択
* 既存のイメージからインスタンスを立てる場合は、イメージ > AMIを選択し任意のAMI上で右クリック > 起動を選択
1. インスタンスタイプの選択
2. インスタンスの設定
3. ストレージの追加
4. タグの追加
5. セキュリティグループの設定
6. 確認

## ロードバランサーの作成
ロードバランサーは、クライアントにとって単一の通信先として機能し、正常な登録済みターゲットに受信トラフィックを分散

左サイドバーから、ロードバランシング > ロードバランサーを選択
ロードバランサーの作成を押下
Application Load Balancerの欄で作成を押下
1. ロードバランサーの設定
2. セキュリティ設定の構成
3. セキュリティグループの設定
4. ルーティングの設定
5. ターゲットの登録
6. 確認

## Route53の設定
可用性と拡張性に優れたクラウドDNS

AWSのサーブルよりRoute53を選択
ホストゾーンの作成を行う
作成したホストゾーンにレコードセットを登録していく
レコードセットの編集において、ロードバランサーのDNS名を記述する
SublimeText3でSFTPを設定する

ゴール：EC2インスタンスとローカルのソースをSFTPで同期する

`command + shift + p`でコマンドパレットを開く
`install package`と入力し選択
続いて、`SFTP`と検索し選択するとインストールされる

任意のフォルダを右クリック
`SFTP/FTP`から、`Map to Remote...`を選択
`sftp-config.json`が開く

```sftp-config.json
{
    "type": "sftp", 
    "upload_on_save": true,
    "sync_down_on_open": false,
    "sync_same_age": true,
    "host": "your ip",
    "user": "user name",
    "remote_path": "absolute path",
    "connect_timeout": 3,
    "ssh_key_file": "ssh_key path"
}
```

今回はSFTPの設定を行うので、typeはsftp
`upload_on_save`: 保存した際にアップロードするか否か
`sync_down_on_open`: ファイルを開いた際の、サーバーとの同期をするか否か
`sync_same_age`: ほぼ同時刻の処理
`host`: サーバのホスト名
`user`: ユーザ名
`remote_path`: 同期するサーバのパス
`connect_timeout`: タイムアウトまでの時間
`ssh_key_file`: サーバに接続する際のsshキーのパス 

`ignore_regexes`を設定して、アップロードもしくはダウンロードしたくないファイルを事前に設定しておくと良い

ローカルとリモートとの同期
ファイルを右クリックした際のSFTP/FTPをから`Upload Folder`or`Download Folder`から行える
PhpStormでE-R図を吐き出す

## ddlからE-R図を吐き出す方法

#### 前提
JetBrains社のPhpStormを使用している

### データベースからddlをダンプ
```
$ mysqldump -u "username" -p -h "hostname" "dbname" > "outputfilename"
```
これで`outputfilename.sql`ファイルが出力される

### PhpStormでE-R図を出力
1. View → Tool Windows → Databaseを選択
2. IDE上にツールバーが表示されるので、Data Source Propertiesを選択（DBとスパナのアイコン）
3. ➕アイコンよりダンプしたddlを選択し名前を付けて、OKボタン
4. Databaseサイドバーから登録したddlを右クリック
5. Daiagrams → Show Visualization...を選択

いい感じのE-R図が表示される

### イメージファイルを出力
図の上で右クリックし、Export to Image File...


※sshトンネリングについては後ほど
Google Edge TPUに関する10の質問

#### 1、Edge TPUとは何ですか？
Edge TPUは、低電力デバイス向けの高性能ML推論を提供するGoogleが設計した小さなASICです。 たとえば、MobileNet V2などの最先端のモバイルビジョンモデルをほぼ400 FPSで電力効率の高い方法で実行できます。

####2、Edge TPUはどの機械学習フレームワークをサポートしていますか？
TensorFlow Liteのみ。

####3、Edge TPUはどのタイプのニューラルネットワークをサポートしていますか？
第一世代のEdge TPUは、畳み込みニューラルネットワーク（CNN）などのディープフィードフォワードニューラルネットワーク（DFF）を実行できるため、さまざまな視覚ベースのMLアプリケーションに最適です。

####4、Edge TPUのTensorFlow Liteモデルを作成するにはどうすればよいですか？
モデルをTensorFlow Liteに変換する必要があり、量子化対応トレーニング（推奨）またはトレーニング後の完全整数量子化を使用してモデルを量子化する必要があります。 （トレーニング後の量子化と互換性のあるモデルを作成するには、TensorFlow 1.15を使用し、入力と出力の両方のタイプをuint8に設定する必要があります。現在、floor入出力のみをサポートするため、TensorFlow 2.0は使用できません。 Edge TPUとの互換性のためのモデル。

ただし、画像分類アプリケーションを構築している場合は、Cloud AutoML Visionを使用して、Edge TPUと互換性のあるモデルを簡単に構築することもできます。このWebベースのツールは、独自の画像を使用してモデルをトレーニングし、モデルを最適化してからEdge TPUにエクスポートするためのグラフィカルUIを提供します。

####5、TensorFlow 2.0を使用してモデルを作成できますか？
はい、TensorFlow 2.0とKeras APIを使用してモデルを構築し、トレーニングできます。ただし、モデルをTensorFlow Lite形式に変換する場合は、v1.15からのTensorFlow Liteコンバーターを使用して、トレーニング後の量子化を実行する必要があります。これは、TensorFlow 2.0のTFLiteConverterが現在、量子化中にuint8入力および出力テンソルをサポートしていないためです。これはEdge TPUで必要です。また、TensorFlow 2.0は現在、量子化に対応したトレーニングをサポートしていません。

####6、Edge TPUの処理能力はどのくらいですか？
Edge TPUは、1秒あたり4兆回の操作（テラ操作）（TOPS）を実行でき、各TOPSに0.5ワット（1ワットあたり2 TOPS）を使用します。


####7、Edge TPUは加速MLトレーニングを実行できますか？
はい、ただし最終層の再トレーニングのみ。 TensorFlowモデルはEdge TPUで高速化するためにコンパイルする必要があるため、後ですべてのレイヤーの重みを更新することはできません。 ただし、2つの異なる方法で高速転送学習を実行するAPIを提供しています。

クロスエントロピー損失関数を使用して、最終的に完全に接続されたレイヤーだけの重みを更新する逆伝播。

新しいデータからの画像埋め込みを使用して最終層に新しい活性化ベクトルを刷り込む重み刷り込み。これにより、非常に小さな小さなデータセットで新しい分類を学習できます。

####8、Dev BoardとUSB Acceleratorの違いは何ですか？
Coral Dev Boardは、SOCとEdge TPUがSOMに統合されたシングルボードコンピューターであるため、完全なシステムです。 また、SOMを削除（または個別に購入）し、3つのボード間コネクタを介して他のハードウェアと統合することもできます。

このシナリオでも、SOMにはSOCとEdge TPUを備えた完全なシステム、およびすべてのシステムインターフェイス（ I2C、MIPI-CSI / DSI、SPIなど）は、基板間コネクタの300ピンを介してアクセスできます。

一方、Coral USB Acceleratorは、エッジTPUをコプロセッサとして既存のシステムに追加するアクセサリデバイスです。USBケーブルを使用してLinuxベースのシステムに接続するだけで済みます（最高のパフォーマンスを得るにはUSB 3.0をお勧めします）。

####9、Edge TPUチップだけを購入できますか？
いいえ、現在、スタンドアロンのEdge TPU ASICは提供していませんが、USB 3.0またはPCI-Eインターフェイスを使用して、既存のハードウェアシステムのコプロセッサーとしてEdge TPUを簡単に統合できる2つの製品を提供しています。 詳細については、以下の製品リストを参照してください。

####10、すべてのGoogle Edge TPU製品


![alt](https://1.bp.blogspot.com/-wfIj87FKyiY/XkYthxsp-TI/AAAAAAAAAJg/W6l9MafiAlEH8ml74PkscZo1QWtLRh9bQCLcBGAsYHQ/s640/unnamed%2B%25281%2529.jpg)


#####開発ボード
Edge TPUを備えたリムーバブルシステムオンモジュール（SoM）を備えたシングルボードコンピューター。

#####USBアクセラレーター
ML推論を既存のシステムにもたらすEdge TPUを備えたUSBアクセサリ。

#####開発ボードミニ

#####ミニPCIeアクセラレーター
Edge TPUを既存のシステムに簡単に統合できるPCIeデバイス。

#####M.2アクセラレータA + E/B+Mキー
Edge TPUを既存のシステムに簡単に統合できるPCIeデバイス。

#####システムオンモジュール（SoM）
40mm x 48mmのプラガブルモジュール内の高速MLアプリケーション用の完全に統合されたシステム。

#####加速器モジュール
Edge TPUを含むはんだ付け可能なマルチチップモジュール

Google Coral製品、および#Gravitylinkオンラインストア（https://store.gravitylink.com/global） での大量販売または大量販売（ボリュームディスカウント）の詳細に興味がある場合は、メールでセールスチームにお問い合わせください。 sales@gravitylink.comまたはmarket@gravitylink.comにご連絡ください。できるだけ早く見積もりをお送りします。
PhpStormよく使うコマンド

## 一般コマンド
#### 置換
`command + shift + r`で一括置換パレット表示
#### 検索
`command + shift + f`で検索パレット表示


## コード整形
#### 設定
`command + ,`でPrefarenceを開く
Editor > Code Style > PHP
Set from > Predefined Styleより`PSR1/PSR2`を選択
個別にTabやIndentの設定も可能

#### 実行
任意のフォルダおよびファイルで右クリック > Reformat Code
もしくは、`option + command + l`
以下、追加で選べるオプション

```
Optimize imports: 未使用のimport文を消す
Rearrange entries: メソッドの定義順序をソート
Cleanup Code: 不要なものを消したりする
```

## Git
`command + k`で選択したフォルダまたはファイルをaddしてcommitしてくれる
ここで、commitメッセージは書く必要がある

## リモート関連
#### Automatic Upload
`command + ,`でPreferancesを開く
Build,Execution,Deployment > Deployment
ここでリモートサーバの設定を行いApply

Build,Execution,Deployment > Deployment > Options
Upload changed files automatically to the default server: Always
上記の設定により、変更が行われた際に自動的にリモートサーバにアップロードされるようになる

`option + command + shift + x`でパレットよりリモートサーバを選択しUpload出来る
seek

```py:
s = """\
AAA
BBB
CCC
DDD
"""

with open('test.txt', 'w') as f:
    f.write(s)

with open ('test.txt', 'r') as f:
    print(f.tell())
    print(f.read(1))
    f.seek(5)
    print(f.read(1))
    f.seek(14)
    print(f.read(1))
    f.seek(15)
    print(f.read(1))
    f.seek(5)
    print(f.read(1))
```

```:実行結果
0
A
B
D


B
```

```py:
print(f.tell())
```
で現在地を出力

```py:
print(f.read(1))
```
で現在地0から1文字を出力
これはAにあたる

```py:
f.seek(5)
```
で現在地を5に移動させ、

```py:
print(f.read(1))
```
で現在地5から1文字を出力
これはBにあたる


位置
0, 1, 2, 3
4, 5, 6, 7
8, 9, 10, 11
12, 13, 14, 15

文字
A, A, A, 改行
B, B, B, 改行
C, C, C, 改行
D, D, D, 改行

と配置されている。
届いたメールに添付ファイルが付いてた場合にteams上のsharepointのフォルダに投げ込む処理

届いたメールに添付ファイルが付いていた場合、みんなに共有したい
例えば技術サポートをしている状態でお客さんからログデータをもらうのだがファイルをわざわざ共有するのがめんどくさい。

ならば。


Powerautomate＋teams＋sharepoint

![コメント 2020-02-14 170346.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/55528137-da4f-0e0d-ab73-d8a31827a4b7.png)

こんな素晴らしいテンプレートがある。

![コメント 2020-02-14 170822.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/7e1a2690-4bd4-63cc-f736-9577ae80a804.png)

sharepointはteamsに紐づいているのでteams上からファイルで確認できる
![コメント 2020-02-14 170952.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/aa846c1c-fb15-ec98-d6a6-e706e7641814.png)



送信。

![コメント 2020-02-14 171226.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/458a878c-a186-ad4e-67c5-2253a4a084d1.png)


![コメント 2020-02-14 171312.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546003/e29d245c-6649-dabb-60a9-d778ba1bf3ad.png)
着弾。


つまりどういうことか。

・メール受信時に内容をTeamsに投稿+返信するPowerAutomateを作ってみて1か月がたった
https://qiita.com/snemesk/items/07e40a58d41a105b2e3c

・Power automateでteamsに自動投稿～返信できるようにした話
https://qiita.com/snemesk/items/f80e0460c9ad52132545

うまく組み合わせればメールの内容を共有しつつ、添付ファイルもteams上ですべて確認できる効率的な環境を作れる。


そのうちメール共有のシステムは導入されるようだがいろいろ応用できると考えている。
WHERE id=? AND owner_id=? に天罰を

このようなクエリを書く者は悔い改めよ:

```sql
WHERE id=? AND owner_id=?
```

結果レコードがなかったとき、こう書く羽目になるであろう:

```php
$item = $query->fetch();
if (!$item) {
    throw new NotFoundException();
}
```

`owner_id` と一致しない者がアクセスしたときは 403 Forbidden にして欲しいと顧客が求める可能性はないのか。拡張に対してオープンであろうとする配慮をなぜできないのか。

そもそも、プライマリキーで十分高速にレコードを特定できている時点で、データベースの責務は終わっているのだ。なぜ貴様らは **SQL などというモデリング言語外の文字列** にユースケースを実装するのか。

正しいコードを示そう。

```sql
WHERE id=?
```

```php
$item = $query->fetch();
if (!$item) {
    throw new NotFoundException();
} elseif ($item->owner_id != $user->id) {
    throw new ForbiddenException();
}
```

どうだ、`owner_id` の一致がなぜ必要なのかは、データを取り出す責務層ではなく、アクセスコントロールを意識する層にあるのが自然ではないか。

ここでクエリのモックを使えば、実データベースにアクセスせずとも、この 「なければ 404 でアクセス禁止なら 403」 を TDD でモデリング可能。この程度のことで、なぜデータベースフィクスチャなどという高速なテストサイクルを邪魔するものに依存せねばならんのか。

(ネタです)
[WIP]Terraformを使うためにドキュメント読んだときのメモ


- ディレクトリにあるTFファイルを全部読み取っている
- providerで利用するクラウドサービスを宣言
  - versionを省略すると最新が取得される
  - versionを指定しないほうが処理が早い
  - `version = "~> 2.7.0"`とかするとめっちゃ遅い（この時点の最新が2.10.0）
- resourceでクラウドサービスで実行するタスクを定義する（存在するリソースに対する定義）
  - 自動的に対応するproviderの設定とマージさせれる
  - resourceの中にlocal-execのprovisionerを定義すると、そのprovisioner設定だけが有効になる
  - provisionerを使うのは最後の手段
  - provisionerは複数設定でき、発火するイベントも定義できる
- applyコマンドを実行する前のplanコマンドは、0.11から必須じゃなくなった
- パラメータの利用は`var.hoge`で出来るが、VSCodeでは"${var.hoge}"にしないと構文エラーになる
Lilypondで条件により表示する文字を変える

# 概要

Lilypond で楽譜を作るときに、フッターに「作曲者名／タイトル」みたいな文字列を入れてるのですが、作曲者名がないと「／タイトル」って出ちゃったので、作曲者名の有無で「／」を表示するかどうか判断するというだけの話。

# 問題のファイル

だいたいこんな感じで、共通設定をインクルード用のファイルに突っ込んで、メインの .ly ファイルから読み込んで使ってます。

```include.ly
DELIMITER = "／"
FOOTTEXT = "フッターに入れたい文字列"

\header {
    title = \markup { \fontsize #2 \TITLE }
    subtitle = \SUBTITLE
    composer = \COMPOSER
    tagline = \markup {
        \vspace #2
        \fill-line {
            \line {
                \COMPOSER
                \hspace #0
                \DELIMITER
                \hspace #0
                \TITLE
            }
            \null
            \FOOTTEXT
        }
    }
    arranger = \ARRANGER
}
```

```main.ly
TITLE = "タイトル"
SUBTITLE = "サブタイトル"
COMPOSER = "作曲者名"
ARRANGER = "編曲者名"

#(set-global-staff-size 25.2)		% default: 20.0

\include "include.ly"

\relative c' {
  \clef treble
  \key c \major
  \time 4/4

  g4 a b c | d4 e f g | a b c d | e f g a | b c d e \bar "|."
}
```

この例だと出来上がるファイルはこんな感じで、フッターに「作曲者名／タイトル」が入ります。

|![20200214-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449620/d5ee9b0d-6b00-877a-f9c8-8ca9ab1ea13d.png)|
|:-:|

ただし、このインクルード用ファイルだと、作曲者名がないときに「／タイトル」という文字列が表示されてしまうので、作曲者名がないときは「／」を出したくない。という話になります。

# Scheme が使えた

変数の値により条件分岐ができないか調べてたところ、Scheme をそのまま埋め込めることを知りました。そこで先ほどの include.ly の 1行目を修正します。main.ly の方は作曲者名だけ修正。

```include.ly
DELIMITER = #(if (string=? COMPOSER "") "" "／")
```

```main.ly
COMPOSER = ""  % 作曲者を表示しない場合
```

# 「／」が消えた

これで、フッターがこんな感じになり、「／」を消すことができました。もちろん、作曲者名に文字列が入っていれば「／」が現れます。

|![20200214-03-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449620/ab781119-41fe-1439-b9b0-4a4f9d5d438d.png)|
|:-:|

# まとめ

今回は「／」を消しただけですが、Lilypond の中で Scheme が使えることが分かりました。使い方次第では色々とできるような気がします。
（楽譜でそんなに制御が必要なのかどうかはよく分からないけど、、）
【Python】ネストしたリストをタプルにしたい

リストをタプルにしたり、その逆にタプルをリストにするのはよくある要求です。

## 一般的な方法

一般的なのは組み込み関数の`list`および`tuple`を使用することです。

```python
l = [0, 1, 2]
t = tuple(l)
print(t)
```

```
(0, 1, 2)
```

## この方法の問題

ところが、リストがネストしていた場合、最も浅い階層しかタプルにしてくれません。

```python
l = [[0, 1, 2], [3, 4, 5, 6, 7], 8, 9]
t = tuple(l)
print(t) # ((0, 1, 2), (3, 4, 5, 6, 7), 8, 9) になってほしい
```

```
([0, 1, 2], [3, 4, 5, 6, 7], 8, 9)
```

キレそ。

## ネストしたリストを内部ごとタプルにする関数

再帰呼び出ししながら全階層タプルにしてやりましょう。

``` python
def list_to_tuple(l):
    return tuple(list_to_tuple(e) if isinstance(e, list) else e for e in l)
```

``` python
l = [[0, 1, 2], [3, 4, 5, 6, 7], 8, 9]
t = list_to_tuple(l)
print(t)
```

```
((0, 1, 2), (3, 4, 5, 6, 7), 8, 9)
```

やったぜ。

## 元ネタとその比較

実はこの記事は[こちら](https://blog.ttk1.net/2016/05/20/python%E3%81%A7%E5%85%A5%E3%82%8C%E5%AD%90%E6%A7%8B%E9%80%A0%E3%81%AElist%E3%82%92tuple%E3%81%AB%E5%A4%89%E6%8F%9B%E3%81%97%E3%81%9F%E3%81%84/)のパクリです。 ~~お前恥ずかしくないのかよ~~

違いとしましては、むこうでは for 文と代入演算子を使用していた部分を内包表記にしたことです。

愚直に繰り返す for 文に対して、内包表記は専用の処理を呼び出してくれるため実行時間が短くなります ([参考](https://qiita.com/intermezzo-fr/items/43f90e07e4cebe63aeb6))。

```python
def list_to_tuple_orig(_list):
    t = ()
    for e in _list:
        if isinstance(e,list):
            t += (list_to_tuple(e),)
        else:
            t += (e,)
    return t
```

```python
l = list(range(10000))
%timeit t = list_to_tuple_orig(l)
%timeit t = list_to_tuple(l)
%timeit t = tuple(l)
```

```
92.7 ms ± 576 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
877 µs ± 3.31 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
19.6 µs ± 47.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
```

100 倍くらい早くなっていますね。 組み込み関数には大敗北ですが。
SwiftUI で switch を使う

```swift
import SwiftUI

enum IconType {
    case home, search, messages
}

struct Icon: View {
    var type: IconType
    var body: some View {
        Group { () -> Image in 
            switch type {
            case .search:
                return Image(systemName: "magnifyingglass")
            case .messages:
                return Image(systemName: "envelope")
            default: // .home
                return Image(systemName: "house")
            }
        }
    }
}
```

`Group { () -> Image in`のように書けば DSL ではなく通常のクロージャとなって switch が書ける。ってか何でも書ける。自由度が一気に上がって責任も大きくなるので要注意なテクニック。

追記:

もっと手抜きするならこう。

```swift
struct Icon: View {
    var type: IconType
    var body: Image {
        switch type {
        case .search:
            return Image(systemName: "magnifyingglass")
        case .messages:
            return Image(systemName: "envelope")
        default: // .home
            return Image(systemName: "house")
        }
    }
}
```