OmniAICreator/Qiita-1.07M huggingface dataset:
Anaconda環境でPyTorch 〜株価予想〜 #02 基礎知識・学習編

## はじめに
[株式会社クリエイス](http://creaith.jp/)の[モトキ](https://qiita.com/pickles)です。  
[前回](https://qiita.com/creaith/items/f47c33e78fb97349b4c8)は、ざっくり環境構築と試しに株価を取得しました。

[Anaconda環境でPyTorch 〜株価予想〜 #01 環境構築編](https://qiita.com/creaith/items/f47c33e78fb97349b4c8)
Anaconda環境でPyTorch 〜株価予想〜 #02 基礎知識・学習編(今回)
[Anaconda環境でPyTorch 〜株価予想〜 #03 予測編](https://qiita.com/creaith/items/710405db451577ae1580)
[Anaconda環境でPyTorch 〜株価予想〜 #04 予測(リベンジ)編](https://qiita.com/creaith/items/a7d0ba9b9cbb4be42490)
[Anaconda環境でPyTorch 〜株価予想〜 #05 表示編](https://qiita.com/creaith/items/54c1666682210d8cbce3)



今回は、読み漁っている中でぶち当たった壁を壊す為に調べたことを並べていきます。
(機械学習のソースを書く以前に、人が書いたコードが読めなくて進められなかった)

## 別チーム
[別チームでもPyTorchの記事](https://qiita.com/creaith/items/bf513e65809ab5c5ce46)を書いています。
[Docker環境でPyTorch 〜画像解析〜 #02 モデル訓練&保存編](https://qiita.com/creaith/items/bf513e65809ab5c5ce46)


## 基礎知識
知らないことだらけでも、概要くらいは理解しないとぐぐれないし進めないので、
今回は、機械学習の基礎知識を固めていきます。
それぞれ浅くほっていきます。

|キーワード|概要|ソースで登場する箇所|
|---|---|---|
|RNN(Recurrent Neural Network)|再帰型ニューラルネットワーク|-|
|LSTM(Long short-term memory)|短期記憶のモデル的な。RNNの拡張・RNNの一種とされる<br>→今回使うのはこっち|torch.nn.LSTM|
|Keras, Chainer, TensorFlow|PyTorchと同じように機械学習のためのライブラリ<br>(取り組む前はTensorFlowしか知りませんでした)|-|
|autograd|自動微分|torch.autograd|
|backward|後ろ向き計算(後ろめたくない)|loss.backward()|
|Adam(Adaptive moment estimation)|勾配法の一種<br>Eveもいるようです|torch.optim|

こういったもろもろを用意してくれるのがPytorchというライブラリなんですね。

## 機械学習
今回はゼロベースではなく、参考にしつつ進めています。
https://github.com/komi1230/Predict-Stock-Price

環境自体は、前回構築したAnaconda3でやっていきます。

### variable()問題
PyTorch0.4で`torch.autograd.variable()`が`torch.Tensor`とマージされました。
それにより、listのラッピングを返却しなくなりました。以下のように修正する必要があります。

```python:get_data.py
import quandl
import numpy as np
import torch
from torch.autograd import Variable


class Get_data:
    def __init__(self, n_prev, data_code):
        self.n_prev = n_prev
        # 今回は、検証用に短い期間を設定して実行します。
        self.data = quandl.get(data_code, start_date="2017/07/01", end_date="2018/07/25", returns="numpy")

    def get_data(self, today):
        tmpX = []
        tmpY = []
        print(today)
        for k in range(self.n_prev):
            tmpX.append(self.data[today - self.n_prev + k][1])
        tmpY.append(self.data[today][1])
        retx = Variable(torch.from_numpy(np.array(tmpX))).float().view(1, 1, self.n_prev)
        rety = Variable(torch.from_numpy(np.array(tmpY))).float().view(1, 1, 1)
        return retx, rety

    def get_raw_data(self):
        return self.data
```

あとは、appleの株価を取得するソースだったので、`agent.py`に反映。

```python:agent.py
import torch.nn as nn
import torch.optim as optim
from network import Network
from get_data import Get_data

data_code = "WIKI/AAPL"  # Quandl data code

# 後略
```

```sh:console
% python agent.py
```

(多分)学習しているとこまで行きました。
間違ってる等ありましたら、やんわりご指摘お願いします！

## 次回
次回は、学習データの確認を行います。

## Creaithメンバー
この記事の著者：[モトキ](https://qiita.com/pickles)、[曽宮](https://qiita.com/ryosomiya)  
その他メンバー：[志村](https://qiita.com/naoto1222)、[上田](https://qiita.com/uedashuhei)

## 参考
https://pytorch.org/docs/stable/autograd.html
VSCodeでもGitHubのMarkdownのように改行する


# GitHubの改行は独自仕様

マークダウンの正式な仕様的には、

- 半角スペース*2を行末に入れると改行
- ただの改行では改行したことにならない

というようになっており、もちろんVScodeもその仕様通りに動きます。

しかし、GitHubではただの改行も改行されちゃうので、~~Git管理されているmdファイルを
VSCodeでイジるとpreviewがどえらいことになったり、逆にVSCodeのpreviewでイイカンジに
したつもりがpushしてGitHub上で確認したときにどえらいことになっていたりします。~~
すみません、Pull Requestを作ったときの本文やコメント欄だけでした。
mdファイルはちゃんと仕様どおりに後ろに半角スペースが必要ですね。

# 対策

VSCodeの設定で以下行を追加します。
`markdown.preview.breaks: true`

GitHubのPR・コメント用途以外のMarkdownとか編集しねぇよ、って人はエディタ設定に、
それ以外も編集する人はプロジェクト単位の設定にすると良いと思いますよ。

そういえばQiitaの投稿エディタもただの改行で改行されるので、
Qiita記事をVSCodeで下書きしたい人も上記設定刺さると思います。
Rubyの継承関係の確認

Rubyで継承関係がわからなくなったら

```rb
Class.ancestors
```

で継承関係がみれます。

```app/controllers/hogeController.rb
class HogeController < ApplicationController

end
```

```irb
[1] pry(main)> HogeController.ancestors
=> [HogeController,
 #<Module:0x007fe7da52bec0>,
 ApplicationController,
以下略
```
ローカル開発環境の構築

初めてローカル環境の構築に成功しました。
ドットインストール様が一番わかりやすいかったです。
リンクの方掲載しておきます。
https://dotinstall.com/lessons/basic_localdev_mac_v2/38501

エラーに関しても下の概要欄に載っていました。
初心者の私でもわかりやすく説明が書いてあって非常に親切でした。
redmine用のdockerfileを作る時に気を付けること(WORKDIR)

# 概要

redmineにプラグインを導入したイメージを配布するためにDockerfile化した時にちょっとした落とし穴・・・に無駄な時間を消費したので、メモとして残したいと思います

# 結論

Dockerfile内でWORKDIRをしたならば、必ず**/usr/src/redmine**に戻すこと！
なぜならば、redmine起動時に`/docker-entrypoint.sh`が実行されるが、このスクリプトは`/usr/src/redmine`で動作することを想定しているので、以下のようなメッセージが表示される

```shell:error_message

Could not load database configuration. No such file - ["config/database.yml"]
```

Dockerfile全体に言えることですが、FROMイメージのDockerfileで何をしているのかを理解してからDockerfileを作ることが大事ですね！（セキュリティ的にも）

# Dockerfile

```dockerfile:Dockerfile

FROM redmine:3.4

ENV REDMINE_DB_MYSQL=redmine-mysql \
    REDMINE_DB_DATABASE=redmine \
    REDMINE_DB_USERNAME=redmine \
    REDMINE_DB_PASSWORD=redmine \
    REDMINE_DB_ENCODING=utf8mb4 \
    REDMINE_PLUGINS_MIGRATE=true

# プラグインのディレクトリ（ハマリポイント）
WORKDIR /usr/src/redmine/plugins

# プラグインの導入
ADD ./hogehoge-plugin ./hogehoge-plugin

# プラグインファイルの所有権を変更
RUN chown -R redmine:redmine ./

# 必ずWORKDIRをココに戻すこと!!!
WORKDIR /usr/src/redmine
```

# ちょっとしたポイント

環境変数に**REDMINE_PLUGINS_MIGRATE=true**を設定しとくと自動でmigrateしてくれるので、プラグインファイルだけを配置するだけで導入されるのは便利！

https://hub.docker.com/_/redmine/

リファレンスから引用↓
> REDMINE_PLUGINS_MIGRATE
This variable allows you to control if rake redmine:plugins:migrate is run on container start. Just set the variable to a non-empty string like 1 or true and the migrate script will be automatically run on every container start. It will be run after db:migrate.

> redmine:plugins:migrate will not run if you start your image with something other than the default CMD, like bash. See the current docker-entrypoint.sh in your image for details.
moodleの小テストで「ヒント」を設定するとどうなるか確認してみた


# はじめに  

この投稿はオープンソース学習管理システム(LMS)である moodle の検証作業をした覚書として書いています。  
確認できた動作の事実のみを記載していますので、記載内容が moodle の仕様であるかどうかは未確認ですので、あらかじめご了承くだださい。


# 環境
* moodle 3.5
* CentOS6.10
* MySQL5.7
* PHP7.2


# 確認したいこと

moodleの小テストで使われる問題で「ヒント」を設定するどうなるか確認をする。


## まずは「受験オプション」について知る  

moodleの小テストの「受験オプション」には以下のようなものがある。  
* アダプティブモード
* アダプティブモード(ペナルティなし)
* 即時フィードバック
* 即時フィードバック(CBM)
* 遅延フィードバック
* 遅延フィードバック(CBM)
* 複数受験インタラクティブ

今回は「ヒント」の挙動を確認したいので**アダプティブモード**と**複数受験インタラクティブ**について確認。
他のオプションについては機会があれば紹介していきたい。


## どんなものか

**アダプティブモード**も**複数受験インタラクティブ**も、ひとつの問題に対して何回も回答できる機能です。  
言い換えると、ひとつの問題で「これかな？ こっちかな？ そっちだったのかぁ！」的なことができるようになる。

この時、問題ごとに「ペナルティ」を設定することで、間違えた回数によって減点していくということができるようです。

例えば・・
1問10点の問題で、1回目で間違えたら-2点、2回目も間違えたらさらに-2点、3回目で正解したら6点(10点-2点-2点)獲得 といった設定ができるようです。

**アダプティブモード**や**複数受験インタラクティブ**を選択すると下記画像のように回答欄のしたに「チェック」のボタンが現れる。

![image](https://qiita-image-store.s3.amazonaws.com/0/108371/f31431d3-dc1e-005d-a780-32d5cd158036.png)


## アダプティブモード と 複数受験インタラクティブ の違い

### アダプティブモード

アダプティブモードは回数制限なく回答できる。
解答欄に「チェック」のボタンが現れ、選択肢を選んでチェックをクリックすると以下の画像のようなフィードバックが表示される。

![image](https://qiita-image-store.s3.amazonaws.com/0/108371/0f82344f-60d0-f604-c830-6be3584a72eb.png)


### 複数受験インタラクティブ

複数受験インタラクティブは問題に設定されている「ヒント」の数によって回数制限がある。
下の画像の問題には「ヒント」が2つ設定されているので、左上に「残り受験数:3」と表示され最大3回まで回答ができることを示している。
![image](https://qiita-image-store.s3.amazonaws.com/0/108371/7544b755-4b0b-138d-68d2-695a2b2e400a.png)

一度間違えてみる。
すると、問題に設定されているフィードバックとヒントが表示される。
「再受験」のボタンを押すことで改めて回答できるようになる。

![image](https://qiita-image-store.s3.amazonaws.com/0/108371/3df507c5-bc8a-c945-482a-acb71da8e9f3.png)


## 使い所は？

moodleの問題作成には手間がかかるし、一度リリースした問題を編集するのは評定にも影響するしWEB画面でちまちまやらないといけないしということで、問題作成の手間を考えれば問題ごとに「総合フィードバック(正解/部分正解/不正解)」を設定しアダプティブモードで運用するのが現実的な気がします。

複数受験インタラクティブで「ヒント」を表示させられれば学習者に対して親切なのかもしれないけど、そこまでに至る手間を考えるとね・・・


## 深まる謎

問題を作る画面で「プレビュー」ができる。
プレビューをすると、設定を変えながら問題の挙動を確認することができる。
「表示オプション」を調整することで違った表現ができそうです。

![image](https://qiita-image-store.s3.amazonaws.com/0/108371/cd6e3258-b149-e54f-6484-58c7856cdbf7.png)

しかし！この「表示オプション」というのがこのプレビュー画面以外で、どこで設定できるのかがわからない・・・
「表示オプション」の設定はいったいどこにあるんだ？？


# おわりに

今回「ヒント」がどんな場面で使えるのかが確認できました。
moodle life の参考にしていただけると幸いです。


# 参考文献
* moodle.orgのフォーラム内の投稿
https://moodle.org/mod/forum/discuss.php?d=205684
vue-chartjsで円グラフ。tooltipを％表示で常に表示させる。

# vue-chartjsで円グラフ。tooltipを％表示で常に表示させる。
chart.js単体の情報は見つけられたが、vue-chartjsバージョンが見つかりづらかった。
pluginをどう書くのか悩んでいたら[vue-charjsのdocument](https://vue-chartjs.org/#/home?id=inline-plugins)に書いてありました・・・

```html
<pie-chart v-bind:datalist="graphUriageAmountList" v-bind:titlelist="graphTitleList"></pie-chart>
```

```js
Vue.component('pie-chart', {
    extends: VueChartJs.Pie,
    props: ['datalist', 'titlelist'],  //データと見出しのリストを渡している
    mounted() {
      // ここのプラグインの書き方がなかなかわからなかったが公式に書いてあった・・・
      this.addPlugin({
        beforeRender: function (chart) {
          if (chart.config.options.showAllTooltips) {
            chart.pluginTooltips = [];
            chart.config.data.datasets.forEach(function (dataset, i) {
              chart.getDatasetMeta(i).data.forEach(function (sector, j) {
                chart.pluginTooltips.push(new Chart.Tooltip({
                  _chart: chart.chart,
                  _chartInstance: chart,
                  _data: chart.data,
                  _options: chart.options.tooltips,
                  _active: [sector]
                }, chart));
              });
            });
            chart.options.tooltips.enabled = false;
          }
        },
        afterDraw: function (chart, easing) {
          if (chart.config.options.showAllTooltips) {
            if (!chart.allTooltipsOnce) {
              if (easing !== 1)
              return;
              chart.allTooltipsOnce = true;
            }
  
            chart.options.tooltips.enabled = true;
            Chart.helpers.each(chart.pluginTooltips, function (tooltip) {
              tooltip.initialize();
              tooltip.update();
              tooltip.transition(easing).draw();
            });
            chart.options.tooltips.enabled = false;
          }
        }
      }),
      this.renderChart(
        {
          labels: this.titlelist,
          datasets: [
            {
              label: this.titlelist,
              backgroundColor: ['#ff8c00', '#f87979', '#da70d6', '#3cb371', '#87cefa'],
              data: this.datalist
            }
          ],
        },
        {
          tooltips: {
            callbacks: {
              label: function (tooltipItem, data) {
                var label = data.datasets[tooltipItem.datasetIndex].label;
                var d = data.datasets[tooltipItem.datasetIndex].data;

                var total = Number(0);
                d.forEach(function(q){
                  total = total + q
                })

                var labelText = label[tooltipItem.index];
                labelText += Math.round(d[tooltipItem.index] / total * 100) + '%' ;
                return labelText;
              }
            },
          },
          responsive: true,
          maintainAspectRatio: false,
          showAllTooltips: true,
        })
    },
  })
```

tooltipを常に表示、の部分は[こちらの投稿](https://qiita.com/gorogoroyasu/items/77b03beca3a5e27716e3)をありがたく使わせていただきました。
zeitのインスタンスを一つにしぼる bru1を停止する

```shell-session
$ now scale zeit-test-ofhvnrqcjn.now.sh 1 1
> Fetched deployment "zeit-test-ofhvnrqcjn.now.sh" [695ms]
> Scale rules for bru1, sfo1 (min: 1, max: 1) saved [6s]
> √ Scaled 1 instance in bru1 [3s]
> √ Scaled 1 instance in sfo1 [4s]
> Success! Scale state verified [5s]
```

インスタンスを1つ固定で建てたいのに2つ消費しちゃってるー！
ブラジルは遠いからいらない。はず。

デプロイ時や`now.json`で特定する方法もあるようだが、
今回は`now scale`でbru1のinstance数を変更する。

方法は、bruのインスタンス数だけをmin 0 max 0に変更する。

```shell-session
$ now scale zeit-test-ofhvnrqcjn.now.sh bru 0 0
> Fetched deployment "zeit-test-ofhvnrqcjn.now.sh" [842ms]
> Scale rules for bru1 (min: 0, max: 0) saved [2s]
> √ Scaled 1 instance in sfo1 [375ms]
> Success! Scale state verified [500ms]
```

sfo1だけが動くようになりました。

# 参考

* [ZEIT – Global Now: Introducing BRU1 (Belgium) and Free Global Static Deployments](https://zeit.co/blog/multi-dc)
* [Global Scaling - ZEIT Documentation](https://zeit.co/docs/features/scaling)
"libcublas.so.9.0: cannot open shared object file: No such file or directory" となった時の対処方法

# ```libcublas.so.9.0``` がない

TensorFlow (GPU) のバージョンを ```1.9.0``` に上げたところ、コード実行時に以下のようなエラーが出ました。

```
ImportError: libcublas.so.9.0: cannot open shared object file: No such file or directory

Failed to load the native TensorFlow runtime.

See https://www.tensorflow.org/install/install_sources#common_installation_problems

for some common reasons and solutions.  Include the entire stack trace
above this error message when asking for help.
```


私の使用環境は以下のようになります（詳細は [こちら](https://qiita.com/mitsuharu_e/items/ecff16bdbcb795a86433) を参照）。

```
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.3 LTS"

$ pip list | grep tensorflow-gpu
tensorflow-gpu         1.9.0  
    
$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2016 NVIDIA Corporation
Built on Tue_Jan_10_13:22:03_CST_2017
Cuda compilation tools, release 8.0, V8.0.61
```

# 対処方法

調べると、CUDAを```9.0``` にアップデートすれば良いとわかりました。NVIDIA Developerの [CUDA Toolkit Archive](https://developer.nvidia.com/cuda-toolkit-archive) から、9.0を選択しダウンロードします（今回は deb(network) を選択しました）。

```
$ sudo dpkg -i cuda-repo-ubuntu1604_9.0.176-1_amd64.deb
$ sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub
$ sudo apt-get update
$ sudo apt-get install cuda-9-0
```

同様にインストールしたCUDAに適したcuDNNを [cuDNN Download](https://developer.nvidia.com/rdp/cudnn-download) からダウンロードして、インストールします。以上から、エラーは起こらなくなり、コードは実行することができました。
Laravel の Storage::put などで作成されるディレクトリのパーミッション設定

# やりたいこと
LaravelがStorage::put等で作成するディレクトリのパーミッションを775にしたかったのですが、
実行ユーザのumaskを002にしても、作成されるディレクトリのパーミッションが755のままでした。

[結論としては、設定ファイルで変更できたのですが、](#結論)Laravelのソースコードを追っていたりして結構手間取ってしまいました。
探し方が悪かったのか、Laravelドキュメントに該当の項目を見つけられなかったのでメモしておきます。

# 結論

`driver` が `local` なディスク上に作成されるディレクトリ、ファイルのパーミッションは
`filesystems.php`設定ファイルで変更することができます。

## 設定例

下記の設定例のように`permissions`設定値を追記してください

```./config/filesystems.php
/*
|--------------------------------------------------------------------------
| Filesystem Disks
|--------------------------------------------------------------------------
|
| Here you may configure as many filesystem "disks" as you wish, and you
| may even configure multiple disks of the same driver. Defaults have
| been setup for each driver as an example of the required options.
|
| Supported Drivers: "local", "ftp", "s3", "rackspace"
|
*/

'disks' => [

    'local' => [
        'driver' => 'local',
        'root' => storage_path('app'),
        'permissions' => [ // permissions 設定値を追記
            'dir' => [
                'public'  => 0775, // public なディレクトリは775で作成 
            ],
            'file' => [
                'public' => 0664, // public なファイルは664で作成
            ],
        ]
    ],
...(以下略)

```

## 確認

`artisan tinker` で動作確認してみます

```bash
$ php artisan tinker
Psy Shell v0.9.6 (PHP 7.2.6 — cli) by Justin Hileman
>>> \Storage::put('test/file', 'hoge');
=> true
>>> exit
Exit:  Goodbye
$ ls -l storage/app | grep test
drwxrwsr-x 2 vagrant www-data   17 Jul 27 10:36 test
$ ls -l storage/app/test/file
-rw-rw-r-- 1 vagrant www-data 4 Jul 27 10:36 storage/app/test/file
```

# 設定が参照されている箇所

時間のある方は、下記のソースを追ってみると楽しいと思います。

`./vendor/laravel/framework/src/Illuminate/Filesystem/FileSystemManager.php`
`./vendor/league/flysystem/src/Adapter/Local.php`
Python unittestのsetUpでテスト用ファイルを用意する

# 問題

unittestで、setUp内でテストデータを作成しようとするとファイルが作成されない。
(あまり調べてないが、原因はよくわからない。。。)

# 解決策

setUp内で、tempfileモジュールを使用して、テストディレクトリを作り、その下でファイルを作成すればよい。
なお、tearDownでファイルを削除することを忘れずに。

```python:自動作成したテストファイルでunittest
import os
import shutil
import tempfile
import unittest

class TestExample(unittest.TestCase):
    def setUp(self):
        self.test_dir = tempfile.mkdtemp()
        self.test_file = os.path.join(self.test_dir, 'test_file.txt')
        test_content = """
        test file content
        """

        with open(self.test_file, 'w') as fp:
            fp.write(test_content)

    def tearDown(self):
        shutil.rmtree(self.test_dir)

    def test_hoge(self):
        result = hoge(self.test_file)
        expect = "hoge's result"
        self.assertEqual(result, expect)

if __name__ == '__main__':
    unittest.main()

```

> コードに誤りがあったのを修正しました(7/27)

# 参考
- [An example Python unittest test case that creates a temporary directory before a test is run and removes it when it's done.
](https://gist.github.com/odyniec/d4ea0959d4e0ba17a980)
  - ほぼこちらのぱくり
[macOS初心者]メールのストレージをゼロにできない。

ストレージの容量が減ってきたので整理をしていたところ，メールがかなりの容量を占めていたようで，メールアプリから全てのメールを削除した。Gmail中心の生活にしたので，macOSのメールアプリは使わないのだ。必要のないアカウントも削除した。

さて，メールの容量は0になったはず・・・と思ってストレージを確認したところ，下記図のように2.78GBも残っている。

![スクリーンショット 2018-07-27 9.54.01.png](https://qiita-image-store.s3.amazonaws.com/0/120396/b7daac9d-c7ec-b28b-28c7-9901e1578e08.png)

再度メールを確認するが，もう消せるものが一切ない。どうしたらストレージを0にできるのでしょうか？
調査が必要である。
【XCode9】ScrollViewをStoryboardで構築する方法　を共有だけ

割とみんな躓きがちというか、謎のwarning出たりして困って結局はコードでカバーしたりしてる部分に思えるので共有だけ。
https://www.youtube.com/watch?v=nfHBCQ3c4Mg
この動画で教えてくれている方法でやればstoryboardだけでscrollviewがちゃんと作れる。
今まで力業でなんとかしていた部分が解決。

というか、これずっと昔から割と話題になってる気がするんだけど、もうちょっとわかりやすくならないもんですかねAppleさん・・・。
約3、4年ぶりぐらいに触ったけどずっと変わらない分かりづらさ。
（自分のググり力が低いだけかもしれない）

React Native?あれのことは忘れましたよ
Photoshopでパサパサ文字を表現したい。

<h2>はじめに</h2>
Photoshopで水分がなくてパサパサな感じを表現したいと思ったので、ネットで調べて見ました！
なお、Photoshopは初心者で知らない間にショートカットキーを押して焦るレベルです。

参考先：https://web-design-cafe.com/archives/469


　<h2>１：パサパサにしたいテキストを用意します。</h2>
<img width="529" alt="パサパサテキスト.png" src="https://qiita-image-store.s3.amazonaws.com/0/263802/656799ab-6b3d-370c-c1a4-618c85d0f996.png">

<h2>２：テキストをラスタライズします。</h2>
<img width="482" alt="ラスタライズ.png" src="https://qiita-image-store.s3.amazonaws.com/0/263802/cf4372cc-d873-2c3b-bfe0-93be51546adc.png">

<h2>３：消しゴムツールでポンポンします。</h2>
<img width="456" alt="消しゴムツール.png" src="https://qiita-image-store.s3.amazonaws.com/0/263802/cd26085b-b048-76c4-2534-423c8244256c.png">

<h2>４：チョークブラシがオススメみたいなので、迷わず選択。</h2>
<img width="663" alt="ブラシ選択.png" src="https://qiita-image-store.s3.amazonaws.com/0/263802/5a171fc6-06cc-3a17-af2e-aa7757abf509.png">
このあと、テキストサイズとのバランスを見てブラシ直径を調整。
今回はテキスト60ptに対して、ブラシを100pxにしてみました！

<h2>5:テキストの上を消しゴムでポンポンする</h2>
<img width="557" alt="パサパサやり過ぎ.png" src="https://qiita-image-store.s3.amazonaws.com/0/263802/5429cbfd-3298-735e-17cd-078d441113b6.png">
適当にやったらパサパサというより、かすれ感が出てしまいました。。。

なので、控えめにポンポンし直しました。
<img width="567" alt="パサパサ物足りない.png" src="https://qiita-image-store.s3.amazonaws.com/0/263802/d4cafd26-41ba-9229-ea7f-de4d4c875bd2.png">
・・・なんか物足りないので、ブラシサイズを小さくしてポンポン追加

<img width="577" alt="パサパサいい感じ.png" src="https://qiita-image-store.s3.amazonaws.com/0/263802/8dd6b73a-4ccd-1e43-6c64-5da2a3116c7e.png">
こんな感じになりました！

初めての投稿なのでこんな感じの投稿で良いのか不安ですが、今回は以上で終了です。

PS.Photoshop使ってたら、知らん間にGoogle日本語翻訳日本語変換がMacのデフォルトに切り替わるのなんでや・・・
組み合わせパターン表を作るExcelマクロ

##これは何？
複数の要素の全組み合わせ、って、まあよくあるやつです。
要素を書き並べておいて、ボタン一つでいい感じに表にしたかった。

##イメージ
![matrix.gif](https://qiita-image-store.s3.amazonaws.com/0/164214/322292f2-b334-27ff-1b70-4029662e487f.gif)

##コード

```vb
Option Explicit

Sub 組み合わせ表()
    Dim t As Range, d As Range, e As Range, r As Range
    With ActiveCell.CurrentRegion
        Set t = .Resize(1)
        Set d = t.Offset(, t.Count + 1)
        t.Copy d
        For Each e In t
            Set r = PatternMatrix(r, e.Offset(1).Resize(e.End(xlDown).Row - e.Row), d.Offset(1))
        Next
    End With
    SmartBorder d.CurrentRegion
End Sub

Private Function PatternMatrix(baseRange As Range, addRange As Range, distRange As Range) As Range
    Dim arx, acx, aar
    aar = ToArray(addRange)
    arx = UBound(aar)
    acx = 1
    Dim brx, bcx, bar
    If baseRange Is Nothing Then
        brx = 1
    Else
        bar = ToArray(baseRange)
        brx = UBound(bar, 1)
        bcx = UBound(bar, 2)
    End If
    Dim rx, cx, arr
    rx = brx * arx
    cx = bcx + acx
    Set PatternMatrix = distRange.Resize(rx, cx)
    arr = ToArray(PatternMatrix)
    Dim br, bc, ar, ac, r, c
    For br = 1 To brx: For ar = 1 To arx
        r = r + 1
        For c = 1 To bcx
            arr(r, c) = IIf(ar = 1, bar(br, c), vbNullString)
        Next c
        arr(r, bcx + 1) = aar(ar, 1)
    Next ar, br
    PatternMatrix.Value = arr
End Function

Private Function SmartBorder(Optional rng As Range) As Range
    Set SmartBorder = IIf(rng Is Nothing, ActiveWindow.RangeSelection, rng)
    With SmartBorder
        .Borders.LineStyle = xlNone
        .BorderAround xlContinuous
        For Each rng In .Cells
            If Not IsEmpty(rng) Then rng.Resize(.Cells(.Count).Row - rng.Row + 1, .Cells(.Count).Column - rng.Column + 1).BorderAround xlContinuous
        Next
    End With
End Function

Private Function ToArray(rng As Range) As Variant
    ToArray = rng.Value
    If Not IsArray(ToArray) Then
        Dim wArr(1 To 1, 1 To 1)
        wArr(1, 1) = ToArray
        ToArray = wArr
    End If
End Function
```

#### 追記（2020.1.26）
うまく動かなくなったので修正しました。
価値の高いテストを書く

オブジェクト指向設計実践ガイド　～Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方 
<img width="254" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/191263/1bb63e13-f3ce-071b-a650-cad18bf04c0a.png">

から、価値の高いテストについてまとめ

---

> テストにより、自信を持って絶えず継続的にリファクタリングができます。効果 的なテストは、変更されたコードが継続して正しく振る舞うことを、全体のコストを上げること なく証明します。良いテストは、落ち着いてコードのリファクタリングを乗り越えます。コード ヘの変更によってテストの書き直しが強制されないように書かれているのです。

# テストの意図

- バグを見つける
- テストは、唯一信用できる設計の仕様書
- 設計の決定を遅らせる

> テストがインターフェースに依存している場合、その根底にあるコードは、奔放にリファクタ リングできます。テストは、 そのインターフェースが正しく振る舞い続けることを証明するので、
 根底にあるコードを変更しても、テストの書き直しが求められることはありません。意図的にイ ンターフェースに依存することによって、テストを使い、設計の決定を安全に、かつ代償もなく、
 遅らせることができます。

- 抽象を支える

> テストは、あらゆる抽象のインターフェースを記録するものであり、したがっ て、背後を守ってくれる壁のようなものです。テストによって、設計の決定を遅らせることがで
き、任意の有益な度合いの抽象をつくることができます。

- 設計の欠陥を明らかにする
    - 設計がまずければ、テストも難しい

> テストのセットアップに苦痛が伴うのであれば、コードはコンテキストを要求しすぎています。1 つのオブジェクトをテストするために、ほかのオブジェクトをいくつも引き込まなければならな いのであれば、そのコードは依存関係を持ちすぎています。テストを書くのが大変なのであれば、 ほかのオブジェクトから見ても再利用が難しいでしよう。

# 何をテストするか

> 受信メッセージは、その戻り値の状態がテストされるべきです。送信コマンドメッセージは、送られたことがテストされるべきです。送信クエリメッセージは、テストするべきではありません。

- オブジェクトを、オブジェクトが応答するメッセージそのもの、かつそれだけであるかのように扱うことで、変更可能なアプリケーションを設計することができます。そして、この観点の重要性を理解してはじめて、最低限のコストで最大限の利益を生むテストを書けるようになるのです。
- パブリックインターフェースに定義されるメッセージを対象としたものを書くべき
- 最もコストが高く最も利用性の低いテストは、不安定 な内部の実装に結合すること
- テストは、オブジェクトの境界に入ってくる(受信する)か、出ていく(送信する)メ ッセージに 集中すべき
- 図9.2で は、Fooの受信メッセージがFooのパブリックインターフェースをつ くっています。 Fooは自身のインターフェースをテストする責任があり、メッセージの戻り値について表明 (ア サーション)をすることでそれを行っています。メッセージの戻り値について表明をするテスト は、状態のテストです。このようなテストは、一般的に、メッセージが戻す結果が、期待する値と 等しくなることを表明します。
- 送信メッセージの状態をテストする必要がないからといって、それらのテストをまったくしな くてよいというわけではありません。
    - 多くの送信メッセージは、アプリケーションが依存するものに対して副作用 (フ ァイル の書き込みや、データベースヘの記録の保存、オブザーバーによってアクションが起こされるな ど)を持ちます。これらのメッセージは「コマンド(命令)」であり、それらが適切に送られたこと を証明するのは送り手のオブジェクトの責任
    - メッセージが送られたことの証明は、振る舞いのテストであり、状態のテストではありません。振る舞いのテストには、メッセージが送られた回数と、使われた引数についての表明が含まれます。
    
# 受信メッセージのテスト

- 受信メッセージは、その実行によって戻される値や状態を表明することでテストされます。
    - 考えられ得るすべての状況にお いて正しい値を返すことを証明する

# 送信メッセージのテスト

- コマンドメッセージを証明する
    - メッセージが何を戻すかの表明をする のではなく、メッセージが送られるという期待を定義
Katexを含むMarkdownをHTMLに変換する【備忘録】

# やり方
Windowsの場合です。`Pandoc`を使います。

```
C:\path\to\pandoc.exe markdown.md
-f markdown+emoji
-t html5
-s 
--katex=https://cdn.jsdelivr.net/npm/katex@0.10.0-beta/dist/ 
-o output.html
```

なんかこうやるとうまくいきます。`--katex`はその時々の最新版にすると良いと思います。
(`katex@latest`とかにしてくれたらいちいち書き換えなくて良いのに)

## オプションの意味
詳しくはこちら→http://pandoc.org/MANUAL.html
### `-f`
`--from`。元ファイルのフォーマット。`markdown+emoji`は、`markdown`にその拡張の`emoji`を`+`したものという意味。
（`markdown+emoji`という文字列をどこのサイトから拾ってきたのか忘れました…
）
### `-t`
`--to`。出力ファイルのフォーマット。
どんなフォーマットがあるかは→http://pandoc.org/MANUAL.html#general-options

### `-s`
`--standalone`。`<head>`とかを含んだ、ファイル全体を出力する。

### `-o`
`--output`。出力先のファイル名。指定しないと`STDOUT`に出る。

### `--katex`
KatexのJSとかCSSをとってくる元のCDNのURL。詳しくは→http://pandoc.org/MANUAL.html#math-rendering-in-html

## おわりに
なんでわざわざKatexを使っているかというと、VSCodeの[プラグイン](https://marketplace.visualstudio.com/items?itemName=goessner.mdmath)がKatexを使っているからです。
実際Mathjaxとかよりレンダリングがとても早く感じます。ただ、検索するときにlatexと混ざるのでググラビリティが低いですね。
tcl/tkで画像をリサイズする

任意の大きさの画像を読み込んで描画エリアの大きさにあわせて描画しようとしたところ、意外と標準コマンドだけでできなかった。
標準コマンドでできるのは整数倍に拡大縮小だけで（何故・・・）、[pure tclな実装](http://wiki.tcl.tk/11196)もあったけど遅すぎて使い物にならず。
[Imgtools](http://tkimgtools.sourceforge.net/)でうまくできたのでメモを残しておく。
wish8.6が動いている前提です。

```shell-session:セットアップ
$ wget https://downloads.sourceforge.net/project/tkimgtools/0.3/imgtools-0.3.tar.gz
$ tar xzf imgtools-0.3.tar.gz
$ cd imgtools-0.3
$ ./configure
$ make
```

```tcl:resize_img.tcl
#!/usr/bin/env wish

lappend auto_path {./imgtools-0.3}
package require imgtools 0.3
wm geometry . 640x480
canvas .c -bg blue
pack .c -expand 1 -fill both
image create photo dst_img
image create photo src_img -file 1.png
::imgtools::scale src_img 640x480 dst_img
.c create image 0 0 -image dst_img -anchor nw
```

```shell-session:実行
$ wish resize_img.tcl
```

## 参考

- http://www.interq.or.jp/japan/s-imai/tcltk/makeext.html
El Capitanでswddude

[swddudeをMac OS Xで使ってみた](https://qiita.com/yamori813/items/77a1789e91cd4bcba3b2)をEl Capitanで試してみた。

libusbはconfigureを実行してmakeするとビルドできます。libftdiは前のページに書いたように手動でビルドします。

私の[githubのリポジトリ](https://github.com/yamori813/swddude)をclone --recursiveして必要なヘッダーとlibをコピーして、ビルドできました。

El CapitanはAppleのFTDIのドライバがロードされるので、デバイスをつないだ後に、このドライバのunloadが必要です。

```
$ sudo kextunload /System/Library/Extensions/AppleUSBFTDI.kext
```

これで実行できます。

```
$ source/release/swdprobe -programmer um232h
 Notice..: SWD communications initialized successfully.
 Notice..: SWD-DP IDCODE = 0BB11477
 Notice..:   Version:   0
 Notice..:   Part:      BB11
 Notice..:   Designer:  23B
 Notice..: Scanning for connected Access Ports...
 Notice..: Access Port #0: IDR = 04770021
 Notice..:   Found MEM-AP.
 Notice..: Device @E00FF000
 Notice..:   Device is ROM table: 4096 bytes
 Notice..: Device @E000E000
 Notice..: Heuristic detection failed, component unknown.
 Notice..: Device @E0001000
 Notice..: Heuristic detection failed, component unknown.
 Notice..: Device @E0002000
 Notice..: Heuristic detection failed, component unknown.
```

ichigojamを焼いてみました。

```
$ source/release/swddude -flash ichigojam-ntsc-jpkbd.bin -fix_lpc_checksum
```

さらのLPCには焼けるのですが、一度ichigokjamを焼いてしまうとSWDのピンをプログラムが使っているようで焼けなくなります。焼き直しの場合はISP(lpc21isp)で焼く必要があるようです。
Go - ひらがな・カタカナの相互変換

# tl;dr

- ひらがなとカタカナは Unicode で 96 文字ずつある
- ひらがなとカタカナの Unicode 符号位置は 96 文字ずれている
- ひらがなの rune に 96 を足せばカタカナになる
- カタカナの rune に 96 を引けばひらがなになる
- rune がひらがなかどうかは `unicode.In(r, unicode.Hiragana)` で判定できる
- rune がカタカナかどうかは `unicode.In(r, unicode.Katakana)` で判定できる

# ひらがなとカタカナの Unicode 符号位置

http://www.unicodemap.org/range/62/Hiragana/ と http://www.unicodemap.org/range/63/Katakana/ が見やすい。
それぞれ 0x3041 と 0x30a1 からはじまる。

# 実装コード

HiraganaToKatakana 関数は文字列中のひらがなをカタカナに変換して返す。
KatakanaToHiragana 関数は文字列中のカタカナをひらがなに変換して返す。

```go
package kana

import (
	"unicode"
)

const (
	// http://www.unicodemap.org/range/62/Hiragana/
	hiraganaLo = 0x3041 // ぁ

	// http://www.unicodemap.org/range/63/Katakana/
	katakanaLo = 0x30a1 // ァ

	codeDiff = katakanaLo - hiraganaLo
)

// HiraganaToKatakana はひらがなをカタカナに変換する。
func HiraganaToKatakana(str string) string {
	src := []rune(str)
	dst := make([]rune, len(src))
	for i, r := range src {
		switch {
		case unicode.In(r, unicode.Hiragana):
			dst[i] = r + codeDiff
		default:
			dst[i] = r
		}
	}
	return string(dst)
}

// KatakanaToHiragana はカタカナをひらがなに変換する。
func KatakanaToHiragana(str string) string {
	src := []rune(str)
	dst := make([]rune, len(src))
	for i, r := range src {
		switch {
		case unicode.In(r, unicode.Katakana):
			dst[i] = r - codeDiff
		default:
			dst[i] = r
		}
	}
	return string(dst)
}
```

### テストコード

```go
package kana_test

import (
	"testing"

	"path/to/kana"
)

func TestHiraganaToKatakana(t *testing.T) {
	tests := []struct {
		input string
		want  string
	}{
		{
			input: "",
			want:  "",
		},
		{
			input: "あいうえお",
			want:  "アイウエオ",
		},
		{
			input: "アイウエオ",
			want:  "アイウエオ",
		},
		{
			input: "あいウえお",
			want:  "アイウエオ",
		},
		{
			input: "あいuえお",
			want:  "アイuエオ",
		},
		{
			input: "あいUえお",
			want:  "アイUエオ",
		},
		{
			input: "あい雨えお",
			want:  "アイ雨エオ",
		},
	}

	for i, test := range tests {
		got := kana.HiraganaToKatakana(test.input)
		if got != test.want {
			t.Errorf("[%d] got %s, but want %s", i, got, test.want)
		}
	}
}

func TestKatakanaToHiragana(t *testing.T) {
	tests := []struct {
		input string
		want  string
	}{
		{
			input: "",
			want:  "",
		},
		{
			input: "アイウエオ",
			want:  "あいうえお",
		},
		{
			input: "あいうえお",
			want:  "あいうえお",
		},
		{
			input: "アイうエオ",
			want:  "あいうえお",
		},
		{
			input: "アイuエオ",
			want:  "あいuえお",
		},
		{
			input: "アイUエオ",
			want:  "あいUえお",
		},
		{
			input: "アイ雨エオ",
			want:  "あい雨えお",
		},
	}

	for i, test := range tests {
		got := kana.KatakanaToHiragana(test.input)
		if got != test.want {
			t.Errorf("[%d] got %s, but want %s", i, got, test.want)
		}
	}
}
```
Google Cloud SDK のインストール時に UnicodeDecodeError が出た時の対応

# 環境

- macOS 10.13.4
- Python 2.7.14

# 現象

[Google Cloud SDK ドキュメント  \|  Cloud SDK  \|  Google Cloud](https://cloud.google.com/sdk/docs/?hl=ja)

を参考にダウンロードしたアーカイブを展開し、そのディレクトリで

```
% ./google-cloud-sdk/install.sh
```

を実行したところ次のエラーが出ました。

```
The Google Cloud SDK installer will now prompt you to update an rc
file to bring the Google Cloud CLIs into your environment.

Enter a path to an rc file to update, or leave blank to use
[/Users/katsuhiko.yoshida/.zshrc]:
Traceback (most recent call last):
  File "/Users/katsuhiko.yoshida/Downloads/google-cloud-sdk/bin/bootstrapping/install.py", line 218, in <module>
    main()
  File "/Users/katsuhiko.yoshida/Downloads/google-cloud-sdk/bin/bootstrapping/install.py", line 203, in main
    sdk_root=bootstrapping.SDK_ROOT,
  File "/Users/katsuhiko.yoshida/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/platforms_install.py", line 452, in UpdateRC
    completion_update, path_update, rc_path, sdk_root, host_os).Update()
  File "/Users/katsuhiko.yoshida/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/platforms_install.py", line 214, in Update
    self.path, rc_contents, source_line=self._GetSourceLine())
  File "/Users/katsuhiko.yoshida/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/platforms_install.py", line 165, in _GetRcContents
    filtered_contents = subre.sub('', rc_contents)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 2: ordinal not in range(128)
```

# 対応

再度

```
% ./google-cloud-sdk/install.sh
```

を実行し、

```
Enter a path to an rc file to update, or leave blank to use
［/Users/katsuhiko.yoshida/.zshrc]:
```

が表示された時に `/Users/katsuhiko.yoshida/.zshrc.gcloud` のように（存在しない）新規ファイルを入力します。

インストール処理が完了すると先程入力したファイル（`/Users/katsuhiko.yoshida/.zshrc.gcloud`）に次の様な内容が出力されています。

```zsh
# The next line updates PATH for the Google Cloud SDK.
if [ -f '/Users/katsuhiko.yoshida/Downloads/google-cloud-sdk/path.zsh.inc' ]; then source '/Users/katsuhiko.yoshida/Downloads/google-cloud-sdk/path.zsh.inc'; fi

# The next line enables shell command completion for gcloud.
if [ -f '/Users/katsuhiko.yoshida/Downloads/google-cloud-sdk/completion.zsh.inc' ]; then source '/Users/katsuhiko.yoshida/Downloads/google-cloud-sdk/completion.zsh.inc'; fi
k
```

これをシェルの設定ファイル（上記の例だと `/Users/katsuhiko.yoshida/.zshrc`）に追記します。

設定の反映をします。

```
% source /Users/katsuhiko.yoshida/.zshrc
```

最後に不要になったファイルを削除して完了です。

```
% rm /Users/katsuhiko.yoshida/.zshrc.gcloud
```

# 原因（仮説）

恐らく設定ファイル内に存在する日本語文字列のデコードに失敗したのではないかと思います。ただし、これ以降再現しなくなってしまったため、間違っているかもしれません。
Github | https / SSL で push する ( 二段階認証対応  +  personal access token を利用 )


# トークンの発行

**Settings** > **Developer settings** > **Personal access tokens** > [Generate new token](https://github.com/settings/tokens/new) から新しいトークンを発行する。

- `Token description` には適当な名前をつける。
- *Select scopes* > *repo* にチェックを入れる
  - pushだけなら、もしかしたら repo 全体の権限は要らないかもしれない。 ( [Understanding scopes for OAuth Apps | GitHub Developer Guide](https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/) )

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/a0ae2ff6-b8ac-0ef1-e9ea-2036548fb0b1.png)

# トークンが発行される

いちどしか表示されないので注意。あとから再表示はできない。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/9cd844a1-c108-ad05-835f-6bc621455104.png)

このトークンは **絶対に公開しない** こと。
誤って人の目に触れてしまった場合などは **Delete** ボタンで無効化できる。


# push する

- ユーザー名を入力する。
- パスワードとして **トークンを入力** する。

# パスワードを聞かれないようにする

これだけだと毎回パスワードを聞かれるので、ヘルパーを登録しておくと良いかも知れない。

```
git config --global credential.helper osxkeychain
```


# 参考

- [Creating a personal access token for the command line - User Documentation](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/)
- [Caching your GitHub password in Git - User Documentation](https://help.github.com/articles/caching-your-github-password-in-git/)








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
PhpStorm メモ

## 右上に表示されるブラウザアイコンを非表示

![image.png](https://qiita-image-store.s3.amazonaws.com/0/88968/f2b887e3-8e34-93d9-84a8-17a702dfdef8.png)
メニューバーから
PhpStorm　>　Preference　> Tools > Web Browsers
の「Show browser popup in editor」のチェックボックスを外す

## 同じ文字列を選択していくショートカット

Ctrl+G

（SublimeTextの「cmd + D」の挙動のやつ）
<img width="551" alt="スクリーンショット 2018-07-27 8.23.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/88968/022a2dd7-a6a6-2bec-9362-033df088b8ca.png">

## 短形選択

option押しながらドラッグ
<img width="51" alt="スクリーンショット 2018-08-23 8.59.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/88968/54ac278f-cbb2-1462-18a9-bd1c09f50a06.png">

## プロジェクトツリー表示

「cmd + 1」で表示・非表示の切り替えが可能

<img width="161" alt="スクリーンショット 2018-08-24 8.08.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/88968/d418b079-3533-b58a-c175-51614c63bf9e.png">

## タブを可視化する

Preferences > Editor > General > Appearance 
「Show whitespaces」 にチェックを入れる
<img width="583" alt="スクリーンショット 2018-08-24 8.24.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/88968/aa12f81f-6b64-b8b5-2aa6-1149e63559cd.png">


## タブの表示色を変更

Preferences > Editor > Color Scheme > General > Text > Whitespace
のForegroundで色を設定可能。
<img width="1030" alt="スクリーンショット 2018-08-24 8.18.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/88968/81f005a7-977c-365a-f3cb-a561faefdfe2.png">
（↓個人的に「303030」くらいがちょうどいい）
<img width="103" alt="スクリーンショット 2018-08-24 8.22.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/88968/e0fb9c29-1913-fb1f-d0e8-de5ebeacd85f.png">
Laravel-adminの立ち上げ方

Laravel-adminのGithubにある、Readmeを読むと細かいところをはしょっているので、ローカルで立ち上げる時に０からやる場合を想定した流れを書きます。

##前提条件
1. PHP7は7.2以上を入れておいてください。
2. composerを入れておいてください。
3. Scaffoldは入れる必要はありません。
- Laravelは5.5以上を入れておいてください。
- Macの場合はHomebrewで入れられます。Homebrewの入れ方はQiitaにたくさん上がっているので
検索してみてください。
- MysqlかmariaDBを入れてください。
- サーバ上でやる場合は、Webサーバはnginxなどが必要ですが、今回はローカル開発環境として作ります。そのためサーバはartisanコマンドです。

##手順(Macを前提としています）
1. ターミナルを起動します。
- 任意の場所（私は~/pcname/をカレントディレクトリとした）に```cd```（チェンジディレクトリコマンド）で移動し、```laravel new xxxx```といれて、器を作ります。xxxxは任意の名前です。
- finderでディレクトリが出来上がったのを確認します。
- そしたら、```cd xxxx```とターミナルで入力し移動します。
- そこで、composerを使い```composer require encore/laravel-admin```とターミナルに入力し、必要なファイルをインストールします。
- 次に同一カレントディレクトリ内で```php artisan vendor:publish --provider="Encore\Admin\AdminServiceProvider"```と入力し、更にファイルを追加します。
- ここで、ターミナルに、```ls -la```といれて、不可視ファイルも含めて表示させ、```.env```があるかどうかを調べます。
- ```.env```があったら、```vi .env```などと、ターミナルの任意のドキュメント操作ソフトを起動するか、Atomなどの不可視ファイルでも可視化出来るエディターを使って、mysqlの項目を編集します。編集するのは、```DB_DATABASE= DB_USERNAME= DB_PASSWORD=```です。laravelをインストールする時にすでに、Databaseの設定は終わっているものとしますが、ない場合は、SQLのCREATEコマンドを使って、DATABASEを作ってください。インストール後の標準のuserはrootですが適宜変更したほうが無難です。
- 最後に```php artisan admin:install```と入れて更にmigrateやインストールをします。
- すべてが終わったら、カレントディレクトリにて、```php artisan serve```と入れて起動します。
- ```https://127.0.0.1:8000/```にアクセスせよと出ていますが、実際は```https://127.0.0.1:8000/admin```にアクセスしてください。

##ログイン
![名称未設定.png](https://qiita-image-store.s3.amazonaws.com/0/18072/20a995fa-e416-b9e3-5e83-481de5c1e35c.png)
ログインするときの初期IDとPasswordは```ID:admin, Password:admin```となります。

##Dashboard画面
![image.png](https://qiita-image-store.s3.amazonaws.com/0/18072/d7de1b13-ca46-f1fa-eebe-cdc3132a9c96.png)
ログイン後このような画面が表示されたら成功です。ここまで、なれると３分ぐらいで立ち上げられます。この後、かっこよくしたければ、購入したデザインテンプレートなどを当て直おすなどすれば、PHP+LaravelでB2B向けシステムを作るときはとても迅速なMVP開発ができるとおもいます。

##最後に
最初、scaffoldingで作ろうとしていましたが管理画面系は面倒だったので、管理画面系ソリューションならそういう便利なgem的なものがあるだろうと調べていました。そこで、出会ったのが、このチャイナ系のテンプレートです。この他にもインド系のLaraAdminなどもあって、甲乙つけがたいのですが、インドの方はよりビジネスライクだったので、こちらのLravel-adminを選択しました。とにかく更新頻度が高く、他のエンジニアからのスター数も多いので、採用しました。
[ReactNative]Androidのpermission周りの制御

# Androidの権限チェック周りのハンドリング
- React NativeでAndroidの権限周りについて整理したもの

## 権限チェックの方法

- 用途に応じて`PermissionsAndroid.check()`か`PermissionsAndroid.request()`を使う

### PermissionsAndroid.check()

- 権限があるかどうかtrue/falseで返してくれる
- https://facebook.github.io/react-native/docs/permissionsandroid#check

```js
const isAuthorized = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.CAMERA);
console.log(isAuthorized); // true/false
```

### PermissionsAndroid.request()

- 権限が付与されていない場合は許可するかどうか選択するプロンプトを出してくれる
    - Android sdkのバージョンが23未満の場合はインストール時に権限付与されているため常に許可状態となる
    - https://facebook.github.io/react-native/docs/permissionsandroid#request
- ユーザの選択パターンは3種類
    - 許可
    - 許可しない
    - 許可しない(今後表示しないにチェック)

<img width="210" alt="prompt.png" src="https://qiita-image-store.s3.amazonaws.com/0/175213/023f2bdf-d8d0-d9a4-b323-8e0286551c20.png"><img width="200" alt="prompt2.png" src="https://qiita-image-store.s3.amazonaws.com/0/175213/228af427-7bad-400f-fe87-51be0c66dae8.png">



```js
const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA);
console.log(granted); // true/'granted'/'denied'/'never_ask_again'
```

### requestの戻り値の整理

|#|初期状態|権限チェックプロンプトの表示|プロンプト選択内容|結果|request()の戻り値|
|:-:|:-:|:-:|:-:|:-:|:-:|
|①|sdk23未満(②以降は23以上)|なし|-|利用可|true|
|②|権限あり|なし|-|利用可|granted|
|③|権限なし|あり|許可|利用可|granted|
|④|権限なし|あり|許可しない|利用不可|denied|
|⑤|権限なし|あり|許可しない(今後表示しないにチェック)|利用不可|never_ask_again|
|⑥|権限なし(今後表示しないチェック済み)|なし|-|利用不可|never_ask_again|
【Laravel】昇順・降順の並べ替え機能の実装

##どんな設計にしようか

まず、昇順・降順のセレクトボタンから作りますか。

```
<select name="narabi">
    <option value="asc">昇順</option>
    <option value="desc">降順</option>
</select>

@foreach ($posts as $post)
    {{ $post->title }}
@endforeach
```

この`narabi`をリクエストで受け取ります。

```PostController.php
public function index(Request $request)
{
    return view('post.index', ['post' => Post::order($request->narabi)])
}
```

orderメソッドに全てを詰めます。

```Post.php
public function order($select)
{
    if($select == 'asc'){
        return $this->orderBy('created_at', 'asc')->get();
    } elseif($select == 'desc') {
        return $this->orderBy('created_at', 'desc')->get();
    } else {
        return $this->all();
    }
}
```

こんな感じでいけるのかなぁ。
【Laravel】ゲッターについて

ゲッターの使い方について整理。

`getXXXXXAttribute`メソッドを作ることでゲッターになるらしい。

userに紐づくpostの一覧から最新のものを取得する想定。

```user.php
public function getPostAttribute()
    {
        $post = $this->orderBy('created_at', 'desc')->first();
        return $post->name;
    }
```

ユーザ一覧（user/index）で$userを定義する。

```UserContoroller.php
class IndexController extends Controller
{
    public function index(Request $request)
    {
        $users = User::all();
        return view('user.index', [
            'users' => $users,
        ]);
    }
}
```

```user/index.blade.php
@foreach ($users as $user)
    $user->post
@endforeach
```

これでユーザごとの最新のpostを取得することができる。
Controllerではuserしか指定しなくてし、他のメソッドでの定義もする必要ないので楽です。
【Laravel】ポリモーフィックリレーションについて

# ポリモーフィックリレーションとは

親が複数ある場合のリレーションです。
例えば、コメントテーブルがあって、そのメモはユーザに紐づいているものと、投稿に紐づいているものがあります。
この時、コメントテーブルは1つで両親に紐づけることが可能です。

##　テーブル設計

hasMenyのリレーションとかだとコメントテーブルにuser_idとpost_idを作成して各親のidを取得しますが、
今回はcommentable_idとcommentable_typeを用意します。

今後親が増えまくった時に、いちいち◯◯_idカラムを追加すると複雑になってしまいます。
commentable_idには各親のidが入るので、idが被ることもあります。
そこでcommentable_typeにユーザならuser、投稿ならpostと入力することで同じidでも区別することが可能になります。

#実装例

まず親。

```user.php
public function comments()
    {
        return $this->morphMany('App\Http\Model\Comment', 'commentable');
    }
```
```post.php
public function comments()
    {
        return $this->morphMany('App\Http\Model\Comment', 'commentable');
    }
```
そして子。

```comment.php
public function commentable()
    {
        return $this->morphTo();
    }
```

これだけで完成です。
あとは`$user->comments()->body`とかすれば値が取得できます。
Reactのイベントまわりでハマったこと2点

React.jsでイベントを扱っていたところ、引っかかったところが2箇所ほどありました。

# 非同期な`setState`とイベントオブジェクト

前の`state`や`props`を見て、その値をもとに`setState`をかけたい場合、`setState`に関数を渡して、その中で新しい`state`を作ることが推奨されています。ただし、このコールバックは非同期で実行されます。

```javascript:失敗例
handleChange = (e) => {
  this.setState(prevState => {
    return /* e.target.valueも使って新たなstateを計算 */;
  });
}
```

このように、`setState`の関数内でイベントオブジェクトを使ってしまうと、関数が実行されるタイミングでは`e`はすでに**無効となってしまっています**。`setState`に入る前に、イベントオブジェクトから必要な値を確保しておきましょう。

```javascript:対策した例
handleChange = (e) => {
  const {value} = e.target;
  this.setState(prevState => {
    return /* valueも使って新たなstateを計算 */;
  });
}
```

# 外側のクリックでドロップダウンを閉じる

例えばタイトルのような処理を組みたい場合に、Reactで管理しているわけではない外側にイベントを仕掛けざるを得ない場面もあります（`componentWillUnmount`できちんと消す必要があります）。そして、外側にセットしたイベントの側で、`.contains`を使ってReactコンポーネントの内側だったら無視…というように仕掛けたつもりだったのですが、「動的に削除したエレメントが内側だと認識されない」という、[以前にRiotでハマったのと同様の問題](https://qiita.com/jkr_2255/items/edc20c940b26f480b628)を食らってしまいました。

`display: none`も一案ではありますが、どうしようもない場合にはイベントを無効化したくなるかもしれません。ただ、そこも一筋縄では行きません。

Reactではイベントをシミュレーションして、すべて`document`直下に仕掛けているので、`document.body`などに仕掛けたイベントは、**Reactのイベントが動く頃にはすべて実行済み**です。`componentDidMount`で`document`に仕掛ければ、Reactより後にセットできますが、イベントキャンセル時には`e.nativeEvent.stopImmediatePropagation()`が必要となります（ネイティブ側でのキャンセルが必要なのと、Reactでは同じエレメントに複数イベントを仕掛けることがないので、Reactのイベントオブジェクトには`stopImmediatePropagation`がないことに要注意です）。
Github Gist にローカルから push する


# GistのURLの例

たとえばこのGistを手元で扱いたい。

https://gist.github.com/YumaInaura/e480986140ef9319ab0d71a87e94bae9

# clone の例


- Gistに割り振られたハッシュ ( `e480986140ef9319ab0d71a87e94bae9` ) を使う
- ユーザー名は使わない
- https ではなく git プロトコルを使う

これで push 出来るようになるっぽい。


```
git clone git@gist.github.com:e480986140ef9319ab0d71a87e94bae9.git
```

# 問題

https + ユーザー名付きのままだと、clone は出来ても push が出来なかった。

```
git clone https://gist.github.com/YumaInaura/e480986140ef9319ab0d71a87e94bae9
```

Gist のドキュメントにも clone / fork のことは書かれているが、 push については書かれていなかった。

[About gists - User Documentation](https://help.github.com/articles/about-gists/)

# 参考

- [git - Github committing (push) gist - Stack Overflow](https://stackoverflow.com/questions/5299526/github-committing-push-gist)








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【iOS】よく使うXcodeキーボードショートカット

普段使用しているXcodeをもっと効率よく使うために
改めてXcodeのキーボードショートカットを見直してみました。

いつでもパッと見るために必要最低限のものを印刷できるように画像にしています。
もしどなたかのお役に立てれば幸いです。

※全部のページにショートカットアイコンの説明が付いているのは
私がよく忘れるので、覚えるためにつけています。

![ブログ.001.jpeg](https://qiita-image-store.s3.amazonaws.com/0/219965/c46790d1-7787-aab3-b291-a0c1d05b614e.jpeg)
![ブログ.002.jpeg](https://qiita-image-store.s3.amazonaws.com/0/219965/7fec5037-6eae-a9da-bf51-0eb4b54b353e.jpeg)
![ブログ.003.jpeg](https://qiita-image-store.s3.amazonaws.com/0/219965/9ab274af-58fb-1363-a5d0-586820fa7d59.jpeg)

こんなショートカットが便利みたいなものがあれば教えてください:bow_tone1:

ショートカットを使いこなして
トラックパッドレス、マウスレスなXcodeライフを:muscle_tone2:
Lenovo Tab4 10の起動音が消せない時の対処法

###やりたいこと
Lenovo Tab4 10の電源をオンにした時の音を消したい。

###問題
Setting(設定)→Sound(サウンド)→Other sound(その他のサウンド)→「Lenovo Tone」をオフにしても起動時の音が消えない。

###解決方法
Setting(設定)→Screen Lock(スクリーンロック)→Pass code(パスコード）内にあるSecure Startupをオフにすると起動音がなくなる。

###参考サイト
https://forums.lenovo.com/t5/Android-Yoga-Series-Tablets/Cannot-Disable-Power-On-Off-Sound-Effects-on-Yoga-Tab-3-Plus/td-p/3866186
CloudFrontを使ってWordPressを配信するときの、Behavior設定

## 要確認
これは私の環境ですので、必要に合わせてBehaviorを追加したりキャッシュのTTLを変更したりしてください。

## Behavior List
Path PatternはDefault含めてに6つ設定する。

- `*.php`
- `/wp-admin/*`
- `/wp-content/uploads/*`
- `/wp-includes/*`
- `/wp-content/*`
- `Default (*)`

![qiita_cf_1.png](https://qiita-image-store.s3.amazonaws.com/0/24337/7d566f5b-1080-f3fa-e682-08dbf905c394.png "qiita_cf_1.png")

以下それぞれのBehavior設定をスクショ貼っていきます。

## `*.php`
Whitelistには以下を設定する。

- `Authorization`
- `CloudFront-Forwarded-Proto`
- `CloudFront-Is-Desktop-Viewer`
- `CloudFront-Is-Mobile-Viewer`
- `CloudFront-Is-Tablet-Viewer`
- `Host`
- `Referer`
- `User-Agent`

![qiita_cf_10.png](https://qiita-image-store.s3.amazonaws.com/0/24337/61fde39b-b584-3390-989b-d9b4e5cc896c.png "qiita_cf_10.png")

## `/wp-admin/*`
Whitelistには以下を設定する。

- `Authorization`
- `CloudFront-Forwarded-Proto`
- `CloudFront-Is-Desktop-Viewer`
- `CloudFront-Is-Mobile-Viewer`
- `CloudFront-Is-Tablet-Viewer`
- `Host`
- `Referer`
- `User-Agent`

![qiita_cf_11.png](https://qiita-image-store.s3.amazonaws.com/0/24337/6b137c01-25ea-0edf-a19c-0388cbcde4e1.png "qiita_cf_11.png")

## `/wp-content/uploads/*`
Whitelistには以下を設定する。

- `Authorization`
- `Host`

![qiita_cf_12.png](https://qiita-image-store.s3.amazonaws.com/0/24337/5968120d-af00-2072-abd5-b7ee2e179218.png "qiita_cf_12.png")

## `/wp-includes/*`
Whitelistには以下を設定する。

- `Authorization`
- `Host`

![qiita_cf_13.png](https://qiita-image-store.s3.amazonaws.com/0/24337/b10a9985-1d21-72a4-3f7c-78ba36a453d9.png "qiita_cf_13.png")

## `/wp-content/*`
Whitelistには以下を設定する。

- `Authorization`
- `Host`

![qiita_cf_14.png](https://qiita-image-store.s3.amazonaws.com/0/24337/f40cf2c2-6d56-346f-0052-99f67c39e5ff.png "qiita_cf_14.png")

## `Default (*)`
![qiita_cf_7.png](https://qiita-image-store.s3.amazonaws.com/0/24337/133b16a3-dfa9-8898-060a-d771e13535d2.png "qiita_cf_7.png")
Linux — ハイフンで始まるファイルを削除する

# 解決

ダブルダッシュの後に消したいファイル名を書く。

```
rm -- -file.txt
```

# 意味

ダブルダッシュ ( `--` ) はコマンドフラグの終わりを表すらしい。

>The double dash “–” means “end of command line flags

[UNIX - BASH - What does “--” (double-dash) mean? (also known as “bare double dash”)-Learn in 30 Sec from Microsoft Awarded MVP](https://www.wikitechy.com/technology/double-dash-mean-also-known-bare-double-dash/)


# 問題

`-file.txt` がコマンドオプションと認識されてしまい、消せなかった。

```
$ rm -file.txt
rm: illegal option -- l
usage: rm [-f | -i] [-dPRrvW] file ...
       unlink file
```

エスケープも不可。

```
$ rm '\-file.txt'
rm: \-file.txt: No such file or directory
```










<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Angular-CliでPortを変更する

# Angular-Cliを使って Dev ServerのPortを変更する

- 背景
- Projectをつくる
- Portの設定

## 背景

アプリケーション側、管理画面側のプロジェジュトを同時に開発することがあり、Portの切り離しが必要になったため。

## Projectの作成

```terminal
$ pwd # Project Path
$ ng new other-port-project
$ cd other-port-project
$ ng serve
```
[localhost:4200](http://localhost:4200)で以下の画面が確認できれば、次に行きます。

![AngularPractice.png](https://qiita-image-store.s3.amazonaws.com/0/144543/618c49c4-3e3c-0cbc-d8c9-19edaef80b68.png)


## Portの設定

angular.jsonのserve プロパティにportの設定を記入していきます。
確認した際は、50行目あたりにありました。


```angular.json(編集前)
"serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "angular-practice:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "angular-practice:build:production"
            }
          }
        },
```

portを4201に編集します。
optionsプロパティにport: <Port 番号>という形で設定します。

```angular.json(編集後)
"serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "angular-practice:build",
　　　　　　　　　　　　　　　　　　　　　　　　///ここから
            "port": 4201
　　　　　　　　　　　　　　　　　　　　　　　　///ここまで
          },
          "configurations": {
            "production": {
              "browserTarget": "angular-practice:build:production"
            }
          }
        },

```

[localhost:4201](http://localhost:4201/)にさきほどあげた画面がみれれば完了。

![AngularPractice.png](https://qiita-image-store.s3.amazonaws.com/0/144543/5b905023-07fa-6e7a-e40d-05ae6caca130.png)