OmniAICreator/Qiita-1.07M huggingface dataset:
エックスサーバーにインストールしたWordPressのテーマをGitで管理

# やりたいこと
今までは、ローカルで作成・更新したWordPressのテーマを、FTPで本番環境であるエックスサーバー上にアップしていた。
これをGitで行う形にする。
エックスサーバー上にリモートリポジトリを作り、ローカルにクローンを作る。
ローカルで作業した分をリモートにプッシュすると、本番環境に反映されるようにする。

[エックスサーバーにGitを導入する手順 | vdeep](http://vdeep.net/xserver-git)
# メリット
- Gitによるバージョン管理ができる。作業時にテーマのファイルやフォルダをコピペして「名前_201808...」にリネーム、みたいなことをしなくて済む。
- FTPソフトを使う必要がなくなる。間違って上書きとか、余計なファイルを本番にアップしてしまった等のミスが無くなる。

一度仕組みさえ作れば楽。そして安心。

# 環境・使用ツールについて
- OS: Windows 8.1
- 開発環境: [XAMPP](https://www.apachefriends.org/jp/index.html) 7.2.6
- ツール: 
    - [Git for Windows](https://gitforwindows.org/): Windows版Git。
    - [SourceTree](https://ja.atlassian.com/software/sourcetree): Gitクライアントソフト。ローカル（自分のPC）でのGit管理に使う。
    - [RLogin](http://nanno.dip.jp/softlib/man/rlogin/): ターミナルソフト。レンタルサーバーでGitを導入する諸々の設定作業に必要。
    - その他: FTPソフト（[WinSCP](https://winscp.net/eng/docs/lang:jp)とか）。

# 手順

※ツールのインストールやSSH接続の説明は割愛。

エックスサーバーにSSH接続のやり方については以下を参照。
[RLoginでエックスサーバーにSSHする方法 - そんなこと猫でもできる](https://nekodeki.com/rlogin%e3%81%a7%e3%82%a8%e3%83%83%e3%82%af%e3%82%b9%e3%82%b5%e3%83%bc%e3%83%90%e3%83%bc%e3%81%abssh%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95/)


## 1. 本番環境Gitの作成
RLoginでエックスサーバーにSSH接続。
以下、コマンド。

```
cd ~/{ドメイン名}/public_html/wp-content/themes/{テーマのフォルダ名}
git init --separate-git-dir=/home/{サーバーID}/{ドメイン名}/theme.git
```

リポジトリは非公開ディレクトリに作成。
リポジトリのフォルダ名は「theme.git」。※任意のフォルダ名でも可。

## 2. 更新管理用Gitの作成
エックスサーバーで本番環境Gitの作成をしたら、次は更新管理用Gitを作成する。
フォルダ名は「theme.remote.git」。※任意のフォルダ名でも可。

```
cd ~/{ドメイン名}
mkdir -m 755 theme.remote.git
cd theme.remote.git
git clone --bare ~/{ドメイン名}/theme.git/ .
```

## 3. 本番環境Gitに更新管理用Gitを追加

```
cd ~/{ドメイン名}/theme.git/
git remote add origin ~/{ドメイン名}/theme.remote.git/
```

ここでエックスサーバーでの作業は一旦終了。次はローカルの設定作業。

## 4. テスト環境Gitの作成
SourceTreeを起動し、Cloneする。

■ 元のパス/URL
ssh://{サーバーID}@{サーバーID}.xsrv.jp:10022/home/{サーバーID}/{ドメイン名}/theme.remote.git

■ 保存先のパス
XAMPPにインストールしたWordPressのフォルダ内。テーマフォルダとか。

例）
C:\xampp\htdocs\\{ドメイン名}\wp-content\themes\\{テーマ名}

■ 名前
任意。「{ドメイン名} (theme)」や「{サイト名}のテーマ」とか。


## 5. 更新管理用Gitのフックを使って、プルを自動化する

■ 5-1. 「post-receive」ファイルを作成する。※拡張子は無い。
エディタを開いて、以下を記述し、名前「post-receive」で保存。（文字コードはUTF-8、改行コードはLFで）

```
#!/bin/sh
cd ~/{ドメイン名}/public_html/wp-content/themes/{テーマ名} || exit
unset GIT_DIR
git pull origin master
```

■ 5-2. 以下のディレクトリ以下にアップする。
/home/{サーバーID}/{ドメイン名}/theme.remote.git/hooks/

■ 5-3. 「post-receive」のパーミッションを755に変更。
FTPソフトを使うか、コマンドを打つ。

```
chmod 755 post-receive
```

## 6. 動作確認

ローカルで適当なファイルを作成・更新してコミット＆プッシュすると、変更内容が本番環境に反映される...はず。

## 7. 補足

Gitに管理されたくないファイルやフォルダがある場合、「.gitignore」ファイルを作る必要あり。
[[Git] SourceTreeで指定フォルダをコミット対象外にする.gitignore設定 | tande lab.](http://tande.jp/lab/2013/03/1991)

# 参考ページ

- [ベアリポジトリとノンベアリポジトリ：実践編〜GitでWordPressのテーマを管理 - トリコロールな猫](http://www.nekotricolor.com/entry/practice-of-bare-and-non-bare-repository-manage-wordpress-themes-with-git)
- [Gitのリモートリポジトリにプッシュすると自動的にWebサイトが更新されるリポジトリを作成する | Arcany](https://tapioca-hiroyuki.net/?blog=git0320)
Windows(上のUbuntu)で rbenv使ってRubyをインストールする方法

## はじめに
ご存知の通り、RubyはMac以外で使うと導入に大変手こずる。
4時間の格闘の末、ようやくrbenvでWindows上にRuby環境を構築できたので、その方法をまとめる。

## 準備
Windowsとは書いたが、Windowsネイティブ環境ではまともなrbenvは存在しない。
このため、Windows Subsystem for Linuxを用いて、Ubuntu環境をWindows上に構築するのが良い。
その方法は本記事では割愛し、以降はUbuntu環境は構築できているものとして手順を説明する。

## 手順
### 1. rbenvのインストール
これは適当なパッケージマネージャを用いて普通に行う。

```bash
$ sudo apt-get update
$ sudo apt-get install rbenv
```

### 2. gcc-6のインストール
なぜこれが必要か？古めのRubyは標準で入っているgcc-7ではビルドできないのである。[参考](https://bugs.ruby-lang.org/issues/14076)

```bash
$ sudo apt-get install gcc-6
```

### 3. OpenSSL 1.0のインストール
なぜこれが必要か？古めのRubyはOpenSSL 1.1に対応していないためだ。[参考](https://github.com/rbenv/ruby-build/issues/1199)

```bash
$ sudo apt-get install libssl1.0-dev
```

### 4. Rubyのインストール
ここまでの前準備をすれば、Rubyをインストール可能である。
ただし、`CC` オプションでコンパイラを `gcc-6` に設定することを忘れてはならない。

```bash
$ CC=/usr/bin/gcc-6 rbenv install 2.3.1
```

なお、Ruby2.4以降はCC指定なしでインストールできるようだ。適当に試してみよう。

### 5. rbenv関連のパスを通す
`~/.profile` に下記を追記する。

```bash 
export PATH="$HOME/.rbenv/shims:$PATH"
eval "$(rbenv init -)"
```

`shims` フォルダは、`bin` という名前である場合もあるようだ。
実際の環境ではしっかりと確認しておこう。 `ls ~/.rbenv`

追記した後は、適用するのを忘れないこと。

```bash
$ source ~/.profile
```

## 確認
これで導入は完了しているはずだ。
適当に切り替えてみて、Rubyが所望のバージョンになっていることを確認しよう。

```bash
$ rbenv versions
* system (set by /home/owner/.rbenv/version)
  2.1.4
  2.3.1
$ rbenv global 2.3.1
$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
```

面倒な環境構築もこれで終わりだ。使い倒してやろう。
php-master-changes 2018-08-27

PHP の ML（というか internals）に早く復活してほしいと思う今日この頃
https://bugs.php.net/bug.php?id=76743

もう 2 週間くらいになるのよ

# 2018-08-27
## weltling: Refactor stat implementation
- https://github.com/php/php-src/commit/e42e8b1051a8abeaa8e6053653a4ff43438766e2
- win32 の stat の実装をリファクタリング

## dstogov: Avoid function copying
- https://github.com/php/php-src/commit/02eded868c5fb307ce2b87042db1fd9a2e6ef1f7
- do_bind_function() で、static 変数のない関数はコピーしないよう修正

## dstogov: Move zend_verify_abstract_class() into zend_inheritance.c
- https://github.com/php/php-src/commit/ea9628936f00805554921390d052f92381966550
- zend_verify_abstract_class() を zend_execute_API.c から zend_inheritance.c へ移動

## dstogov: Cleanup class linking
- https://github.com/php/php-src/commit/2fbfdde1b618b67fda83e624edfe6e7163dc4f6d
- 継承やトレイト、インターフェースをクラスと紐付けるコードを zend_do_link_class() へまとめた
- zend_verify_abstract_class() の呼び出し部分も少し整理されたみたい

## bukka: Store zlog stream in each child so it can be reused
- https://github.com/php/php-src/commit/014b1b3aadf936363b9ddcd6f37238a2e4f89df4
- sapi/fpm のログ出力修正
- https://github.com/php/php-src/pull/2458 の流れ
- zlog stream を各 Worker で持って使い回すようになった
- なので zlog stream で使われるメモリ使用量は [log_limit の Worker 数倍](https://github.com/php/php-src/pull/3471)になる
【Androidアプリ開発勉強】MPAndroidChartで折れ線グラフを描画したい。

Androidアプリでのグラフ描画は「MPAndroidChart」が良いらしい。
が、サンプルが古いものばかりでハマっていた。
具体的にはLineDataのコンストラクタにX軸のラベルとY軸のデータを設定するサンプルが多かったんだけど、
これは古いみたいでした。

というわけで折れ線グラフを描画した際にハマったことの共有です。
なお、参考資料のサイトが日本語で非常に助かりました。多謝。
ここに記載してない項目はぜひ参考資料を見てください。

# 前提環境(バージョンとか)
Android Studio Version 3.1.4
Windows 10 HOME Version 1803, OS build 17134.228

# 初期設定
【Androidアプリ開発勉強】開発時にハマったこと(XAMLでデザイン編)の[mpandroidchart使えない問題](https://qiita.com/FORTE/items/550b0820f4798a9850de#mpandroidchart%E4%BD%BF%E3%81%88%E3%81%AA%E3%81%84%E5%95%8F%E9%A1%8C)で記載。

初心者だとググった結果をそのまま利用するには敷居が高いイメージ。
公式ドキュメントに気づくまで結構ハマりました。

# レイアウトの設定など
## 折れ線グラフの値を示す点の色。
LineDataSet.setCircleColorでセット可能。
線の色だけ変えると点がスゴク浮くので…。

## 線の太さ
LineDataSet.setLineWidth

## 点の値の表示/非表示
LineDataSet.setDrawValues

## 拡大・縮小(ダブルタップも含む)の可否。
LineDataSet.setScaleEnabled
一般的なピンチイン・アウトに加え、ダブルタップによる拡大もこれで制御。

## Y軸の開始値。
YAxis.setAxisMinimum
0始まりにしたいときはこれで。

## Y軸の値を少数にしたくない
値が10以下の時は以下のように固定で10にすると回避できます。
10以下でも行けるかは未確認。
YAxis.setAxisMaximum(10);
YAxis.setLabelCount(10);

## X軸のテキストサイズ
XAxis.setTextSize
X軸にMM/DDを表示したいときに重なりの調整に設定しました。

## X軸のラベル数
XAxis.setLabelCount
グリッドの縦線の数と言うと伝わりやすいかもしれません。

## 値の変更を反映する
一度セットした値を別の値に変えた時は以下を呼び出さないと反映されません。
LineChart.notifyDataSetChanged();
LineChart.invalidate();


# 参考資料
[【Android】Androidでグラフを描画する - 線グラフ編](https://qiita.com/entan05/items/a21906f8c71b5c208f07)
Rails: deviseをインストールした後のエラー

エラーの内容・原因・対処方法をまとめました。

##作業内容
gem 'devise'を追加して、rails g devise userのコマンドでuserモデルを作成していたところ、rake db:migrateでエラーになった。

##エラーの内容
```terminal
`method_missing': undefined method `devise' for User (call 'User.connection' to establish a connection):Class (NoMethodError)
```

「Userモデルに対するdeviseメソッドなんて無いよ！」という感じですね。

##原因
どうやら、rails g devise install をする前に、rails g devise user をしてしまっていたようでした。

正しい作業手順：
1. gem 'devise'を追加
2. bundle install
3. rails s でローカルサーバー再起動
4. rails g devise:install　←ここができていなかった。
5. rails g devise user
6. rake db:migrate

##対処方法
まず、下記の手順で作業手順4.の直前の状態に戻した後、再度正しくdeviseをインストールしました。
1. routes.rb から devise_for :users の記述を削除（作業手順5.で記述されたもの）
2. rails d model user を行い、userモデルを削除（これも作業手順5.で作成されたもの）
3. rails g devise:install
以降、正しくコマンドを実行

##うまくいきました！


参考：
[gemのdeviseをインストールした直後のエラー](https://qiita.com/ryouzi/items/9c5324ba567109ab2a22)
【TIC-80】エリア番号を振った配列（テーブル）から境界線付きのマップデータを作成

自分には言葉で説明するのは難しいので、具体例を挙げると、
TIC-80という仮想のゲーム機上で

```Lua:data2map.lua
adata={
 {0,0,0,0,0,0,0,0,0,0},
 {0,1,1,1,0,0,6,6,6,0},
 {0,0,1,2,0,0,6,0,6,0},
 {0,0,1,2,3,3,6,6,6,0},
 {0,0,0,2,3,4,4,5,0,0},
 {0,0,0,0,3,3,5,5,0,0},
 {0,0,0,0,0,0,0,0,0,0},
 {0,0,0,0,0,0,0,0,0,0}
}
```

のようにエリア番号を二次元配列（テーブル）に
入れたものから
![mapdata.png](https://qiita-image-store.s3.amazonaws.com/0/284455/087e888d-9a0b-6799-dabe-1b4ba066eef4.png)
のようなマップデータを作成することが目的です。
（TIC-80と書こうとして挫折しました）


満たしたい要求は以下の通り

- エリア番号が異なる場合は境界線を引く
- 複数のエリアで同じ種類のスプライト（マップチップ）を使い回す
- それなりの拡張性（現在では海と地面の二種だがそれを増やしたり）
- それなりのコードの短さとそれなりの可読性

はい、おそらく同様のことをやった人はいるはずなんですが、自分の検索力では
見つけることができませんでした。この記事のタイトルも多分適切ではありません。
マップチップやタイルなどの語句も後から知りました。

結局紆余曲折の末、以下のような方法にしました。
![tile.png](https://qiita-image-store.s3.amazonaws.com/0/284455/4682da88-28fb-0382-4856-aa03cff92134.png)
境界線なし、左との境界線あり、上との境界線あり、左と上との境界線ありの
スプライト（マップチップ）を海と地面それぞれ用意してインデックス#0 から順番に並べる。

後は自身のエリア番号が0（海）なら前半、左とエリア番号が異なれば1ずらし、上なら2、
両方なら足して3ずらす、としました。コードは以下のように

```Lua:data2map.lua
S_ID=0
adata={
 {0,0,0,0,0,0,0,0,0,0},
 {0,1,1,1,0,0,6,6,6,0},
 {0,0,1,2,0,0,6,0,6,0},
 {0,0,1,2,3,3,6,6,6,0},
 {0,0,0,2,3,4,4,5,0,0},
 {0,0,0,0,3,3,5,5,0,0},
 {0,0,0,0,0,0,0,0,0,0},
 {0,0,0,0,0,0,0,0,0,0}
}
MAP_W=#adata[1]
MAP_H=#adata
for i=2,MAP_H do
 for j=2,MAP_W do
  local dSea=(adata[i][j]==0)and 0 or 4
  local dLeft=(adata[i][j]==adata[i][j-1])and 0 or 1
  local dUp=(adata[i][j]==adata[i-1][j])and 0 or 2
  mset(j-1,i-1,S_ID+dSea+dLeft+dUp)
 end
end
--sync(0,0,true)
function TIC()
 map()
end
```

とりあえず一番上と一番左は0固定で。

また後で追記します。（初めての記事で疲れました）
Mac High Sierra にpyenvを入れてPythonが切り替わるようにする

Pythonでプログラムを書こうと思ったときにお世話になる`pyenv`。
巷にはいろいろとインストール方法が溢れているが、High Sierra (だからかどうかわからないが)に導入しようとしたところ少し躓いたのでメモ。

## まずはHomebrewでインストール
なんだかんだ便利なので、Homebrewを利用してサクッとインストール。

```shell:install
$ brew install pyenv
```

## pyenvのパスを通す
`pyenv`コマンドを使えるようにする。
`.bash_profile`, `.bashrc`, `.zshrc`なんでもいいけど、使用しているシェルの設定ファイルに以下を記述。

```shell:export_pyenv
$ export PYENV_ROOT=$HOME/.pyenv
もしくは、
$ export PYENV_ROOT=/usr/local/var/pyenv
```
pyenvでインストールされる様々なバージョンのpythonが保存される場所です。まぁ、お好きな方で。
これで`pyenv`コマンドが認識されるようになります。

```shell:pyenv_cmd
$ pyenv -v
pyenv 1.2.7
```

## いちおうやっとこうrehash
pyenvのhelpに書いてあるし、いちおうやっとく。

```shell:help
$ pyenv --help
Some useful pyenv commands are:
            ...
   rehash   Rehash pyenv shims (run this after installing executables)
```
```shell:rehash
$ pyenv rehash
```

## 好きなPythonバージョンをインストール
いよいよPythonのインストール。
はやる気持ちを抑えて、インストール可能なバージョンを確認してみる。

```shell:list
$ pyenv install --list
            ...
  3.6.6
  3.7.0
  3.7-dev
  3.8-dev
            ...
```
上記はごく一部です。
今回は3.7.0をインストールしてみる。

```shell:install_37
$ pyenv install 3.7.0
```
自前でビルドも行うため、少し待ちます。
以下でインストール済バージョンを確認。

```shell:versions
$ pyenv versions
* system
  2.7.15
  3.7.0 (set by /usr/local/var/pyenv/version)
```
上記の意味するところは、
- このPCにインストールされているのは、`system`(macに元から入ってるやつ),`3.6.6`,`3.7.0`
- (2.7.15は比較のために入れときました)
- 今は`system`が選択されてるよ

ちなみに、現在選択中のバージョンだけを表示するには、

```shell:version
$ pyenv version
system (set by /usr/local/var/pyenv/version)
```

## 利用するPythonバージョンを指定
2つの指定の仕方があります。
#### global
デフォルト指定。基本的にこのバージョンが使われる。

```shell:global
$ pyenv global 3.7.0
```

#### local
特定のディレクトリ内のみこのバージョンで！という時に使う。

```shell:local
$ pyenv local 2.7.15
```
このコマンドを実行したディレクトリでは`2.7.15`が利用される。

## Pythonを動かしてみよう
わくわく。

```shell:python
$ python --version
Python 2.7.10
```

## あれ？
local指定外のディレクトリでコマンドを実行したため、`3.7.0`でないとおかしい。
`2.7.0`ってなんや？そんなのインストールしてない！
実は、`system`が`2.7.0`です。
いやでも、何にせよ`3.7.0`じゃないと。。

## 答えはshimsにあり
先に`PYENV_ROOT`で指定したインストール済Python置き場を見てみると、`shims`というディレクトリがあります。
ここには、`pyenv global`などで切り替えたバージョンの各種`python`実行ファイルたちが用意されています。

```
$ $PYENV_ROOT/shims/python --version
Python 2.7.10

$ pyenv global 3.7.0
$ $PYENV_ROOT/shims/python --version
Python 3.7.0

$ pyenv global 2.7.15
$ $PYENV_ROOT/shims/python --version
Python 2.7.15
```

## shimsをパスに通してあげる
ということで、shimsディレクトリのパスを通してあげることで、pythonがうまいこと動くようになりました。

```shell:.bash_profile
export PYTHON_PATH=$PYENV_ROOT/shims
export PATH=$PYTHON_PATH:$PATH
```

```shell:results
$ pyenv global system
$ python --version
Python 2.7.10

$ pyenv global 3.7.0
$ python --version
Python 3.7.0

$ pyenv global 2.7.15
$ python --version
Python 2.7.15
```
PowerShell で CSOM (Client Side Object Model) を使ったメモ

色々と忘れるので個人的メモ

## 前提条件

* ClientContext は $ctx として取得済みとする

## PowerShell で直接とれない情報をラムダを使って頑張る

```powershell
$clientAssembly = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
$clientRuntimeAssembly = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")
$assemblies = ($clientAssembly.FullName, $clientRuntimeAssembly.FullName)
Add-Type -Language CSharp -ReferencedAssemblies $assemblies -TypeDefinition "
using Microsoft.SharePoint.Client;
 
public static class Helper
{
    public static void LoadFieldValueAsText(ClientContext ctx, ListItemCollection listItems)
    {
        ctx.Load(listItems, items => items.Include(item => item.FieldValuesAsText));
    }
    public static void LoadFieldValueAsHtml(ClientContext ctx, ListItemCollection listItems)
    {
        ctx.Load(listItems, items => items.Include(item => item.FieldValuesAsHtml));
    }
    public static void LoadListDisplayFormUrl(ClientContext ctx, List list)
    {
        ctx.Load(list, v => v.DefaultDisplayFormUrl);
    }
}
"
# リストの DisplayFormUrl を取得
$list = $ctx.Web.Lists.GetByTitle('リスト名')
[Helper]::LoadListDisplayFormUrl($ctx, $list)

# アイテムコレクションの FieldValueAsText を取得
$caml = New-Object Microsoft.SharePoint.Client.CamlQuery
$caml.ViewXml = '<View><Query></Query></View>'
$items =  $list.getItems($caml)
[Helper]::LoadFieldValueAsText($ctx, $items)

# 実行
$ctx.ExecuteQuery()
```


## SharePoint Online の調整機能を回避する

SharePoint Online では、HTTP アクセスの一部をブロックして負荷調整する機能があるらしく、
一括移行のテストを行っていたら見事に引っかかったので対策した。

参考： https://blogs.technet.microsoft.com/sharepoint_support/2018/07/23/sharepoint-online-http-throttling/

```powershell:.NETを呼んで頑張る
function Add-UserAgent($ctx)
{
    $clientAssembly = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
    $clientRuntimeAssembly = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")
    $assemblies = ($clientAssembly.FullName, $clientRuntimeAssembly.FullName)
    Add-Type -Language CSharp -ReferencedAssemblies $assemblies -TypeDefinition @"
    using System; 
    using Microsoft.SharePoint.Client;

    public static class SPContextHelper
    {
        public static void AddUserAgent(ClientContext ctx)
        {
            ctx.ExecutingWebRequest += delegate (object sender, WebRequestEventArgs e)
            {
                e.WebRequestExecutor.WebRequest.UserAgent = "NONISV|Artisan|DummyScript/1.0";
            };
        }
    }
"@
    [SPContextHelper]::AddUserAgent($ctx);
}

# 調整またはブロックを回避するために User-Agent を付与
Add-UserAgent $ctx
```

```powershell:PowerShellだけで頑張る
$ctx.add_ExecutingWebRequest({
    param($Source, $EventArgs)
    $request = $EventArgs.WebRequestExecutor.WebRequest
    $request.UserAgent = "NONISV|Artisan|DummyScript/1.0"
})
$ctx.ExecuteQuery()
```
Instant apps 対応中にCrashlytics周りで出るエラーの対処

- [ラジ番](https://play.google.com/store/apps/details?id=tsuyogoro.sugorokuon) というアプリをinstant app化しており、その中で起こったことのメモです

### codelabに従ってinstant app化を進めた

- https://codelabs.developers.google.com/codelabs/android-instant-apps/index.html#0
- めっちゃ分かりやすくて、書いてある通りにやっていけばサクサク進む

### Crashlyticsがエラーを吐き出し始めた

<img width="904" alt="スクリーンショット 2018-08-28 0.18.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/32424/7391c44f-5902-3129-20b6-bceb37d9d93f.png">

### 対処

- gradleに別途instant apps対応のconfigurationを書いてあげないといけないらしい
- https://stackoverflow.com/questions/44361850/how-do-i-integrate-crashlytics-with-android-instant-apps
- `base/build.gradle` のトップレベルに `crashlytics { instantAppSupport true }` を追加

### 感想

- Instant app化はまだ道半ばなのだけど、まだ何か起きそう。。。
HttpStatusCodeで429を扱う

気になったので調べてみた。

HttpStatusCode 429 TooManyRequest
https://tools.ietf.org/html/rfc6585#section-4

2012年くらいに作られた定義。アクセス過多などによりレート制限がかかった場合のステータス。
400代は基本的にノーリトライだと考えてたけど、これのおかげで単純に400台をノーリトライとすることができない嫌なやつ。

実は.NETのHttpStatusCodeには429の定義がない。
正確には.NETCore2.1にはあって.NET Framework、mono、.NET Standardにはない。

「じゃあ、HttpClientとかでStatusCode受け取れないじゃん」

と思うのだけど、

結果からいうと429扱える。　C#のenumの特性を勘違いしてた。

<img width="1228" alt="スクリーンショット 2018-08-27 23.42.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/72379/0d40c3e9-9fa3-3b2a-77c2-2261f909812f.png">

429を返すAPIにアクセスした時のWatch
普段はenumの名前で表示される部分が数字になってる。

じゃあどうやって扱えるかというと

<img width="540" alt="スクリーンショット 2018-08-27 23.43.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/72379/f5d380d1-2304-d86a-5fc5-415e4d99af2f.png">

これで良い。

C#のenumってこんなこと出来るんですね。試したこともなかったので知らなかったです。

まぁ普通に考えて故意にはやらないのだけど、設計などで応用というか幅を広げられるかも。
学習記録：javascript(ES6)

# 8月27日　javascript(ES6)

個人的に重要な部分のメモ
コードはprogate内の問題より引用

```javascript:
 console.log(`${this.age}歳です`);
```

ES6では文字列内で変数や定数を用いる際に、+で文を繋がず
${変数や定数}　のテンプレートリテラルを使用する事が出来る
その際は、(””)ではなく、(``)のバッククォートで囲む

```javascript:
for (let i = 0 ; i < cafe.menus.length ; i ++ ) {
  console.log(cafe.menus[i]) ;
} 
```
for  (変数の設定 ; 条件式 ; 変数に対する処理)  {
　実行する処理　} 
※最後に ; は付けないので注意

```javascript:
const convertToYen = (priceDollar) => {
  return priceDollar * dollarYenRate ;
} ;
```
const 変数名 = (引数名) => {
　実行する処理
} ;
※() => はアロー関数であり、function()と同義

```javascript:
class Animal {
  //コンストラクタ
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  //メソッド１
  greet() {
    console.log("こんにちは");
  }
  //メソッド２
  info() {
    this.greet() ;
    console.log(`名前は${this.name}です`);
    console.log(`${this.age}歳です`);
  }
}
// インスタンスの生成文
const animal = new Animal("レオ", 3);
//　実行文
animal.info();
```
インスタンスの生成　⇒　const インスタンス名 = new クラス名
インスタンスでanimalクラスのメソッドを使用する　⇒　インスタンス名.info

```javascript:
//分割したファイルの読み込み
import Animal from "./animal.js" ;

//分割したファイルを他のファイルでも使用可能にする
export default Animal ;
```
分割したファイルの読み込み　
⇒　import クラス名 from "./ファイル名" ;
分割したファイルを他のファイルでも使用可能にする
⇒　export default クラス名 ;

```javascript:
//animal.js
class Animal {
  //コンストラクタの設計
  constructor(name, age) {
    this.name = name ; this.age = age;
  }
}

//dog.js
//Animalクラス（親）からDogクラス（子）へ継承
class Dog extends Animal {
    //親クラスのコンストラクタのオーバーライド
    constructor(name, age, breed) {
      //親クラスのコンストラクタの呼び出しと新しいコンストラクタの追加
      super(name , age) ;
      this.breed = breed ;
    }
}
```
子クラスのコンストラクタ内で、親クラスのコンストラクタを呼び出す
⇒　super(引数名,…)」
githubにcommitをpushしたらCircleCIでgo buildを実行できるようにする

## 設定ファイル
- `version: 2`でCircleCI 2.0の設定と明示する<br>
- build用のdocker imageはcircleciが用意しているものを使用する<br>

### 基本的な流れは以下
1. キーからキャッシュを復元
2. もしvendorがなければ`dep ensure`を実行
3. depもなければインストール
4. dep自体とvendor以下をキャッシュに保存
5. go build

```yml

#.circlci/config.yml
jobs:
  build:
    working_directory: /go/src/github.com/tanden/go-echo-with-mysql/

    docker:
      - image: circleci/golang:1.10
    
    steps:
      - checkout

      - restore_cache:
          keys:
              - v1-vendor-{{ .Branch }}-{{ checksum "src/Gopkg.lock" }}
              - v1-vendor-{{ .Branch }}
              - v1-vendor
              - v1-dep

      - run:
          name: dep ensure
          command: |
              cd src/
              if [ ! -d vendor ]; then
                if ! type dep >/dev/null 2>&1; then
                  go get -u github.com/golang/dep/cmd/dep
                fi
                dep ensure
              fi
      # ローカルとcircleci上でgo getしたdepのversionが異なると
      # dep ensureしたときにGopkg.lockのchecksumが変わってしまい
      # 別のcacheとして保存されてしまいrestore_cacheで取り出せない
      # cacheしてるdepのversionはv0.5.0
      - save_cache:
          key: v1-vendor-{{ .Branch }}-{{ checksum "src/Gopkg.lock" }}
          paths:
              - src/vendor

      - save_cache:
          key: v1-dep
          paths:
              - /go/bin/dep

      - run:
          name: go build
          command: |
              go build -v -o src/app src/server.go

      - persist_to_workspace:
          root: .
          paths:
              - src/

workflows:
    version: 2
    build:
      jobs:
        - build
```

## depとvendorのキャッシュ
パッケージをdep管理しているので、CircleCI上のコンテナで`dep ensure`コマンドを実行しvendor以下にパッケージをインストールします。<br>
ただ、Gopkg.lockの内容に変化がない（使用しているパッケージが変わらない）場合、前回と同じインストールされたパッケージを使いたい。インストールに6〜7秒かかるので（毎回行われるので合計するとバカになりません）<br>
なので、depコマンド自体と、vendor以下をCircleCIのキャッシュ機能をつかってキャッシュさせます。<br>

### キャッシュクリアするにはキーの名前を変える
キャッシュクリアをするために、都度キーの名前を変えるてしまうのがよいようです（restore_cacheをいちいち消して、キャッシュをリストアせずに新しくインストールしてキャッシュした値を更新する、、、などしなくてよくなります）<br>
ドキュメントでは、`v1`などのバージョンプレフィックスをつけてキーの名前を変えていくことを推奨しています<br>
https://circleci.com/docs/2.0/caching/#clearing-cache


## はまったこと：vendorをキャッシュできない
vendorをキャッシュできず、はまりました。<br>
src/Gopkg.lockのchecksumの値をキャッシュのキーにしているのですが、commitしているGopkg.lockとCircleCIのコンテナ上にcloneしたGopkg.lockのchecksumが異なりrestore_cacheでリストアできませんでした。<br>
自分のローカルのdepのバージョンが古く、最新のdep（CirclCIで`go get`したdepのバージョン）では、Gopkg.lockのフォーマットが異なるようです。

1. checkoutでcloneしたリポジトリ上のGopkg.lockのchecksumでrestore_cacheを行う
2. restoreできない
3. 再度 dep eusureする
4. Gopkg.lockのchecksumが変わる
5. 変わった後のchecksumを使ったkeyでキャッシュを保存してしまう
6. 1でrestoreできない

CircleCI上のコンテナにインストールしているdepのバージョンと、ローカルのバージョンを同じにして再度`dep init`を行なって、新しいGopkg.lockをcommitしなおすと想定通りキャッシュしてくれるようになりました！
Pythonのurllibを使ってImageNetから画像をダウンロードする


こちらの記事はブログに引越しました。

[Pythonのurllibを使ってImageNetから画像をダウンロードする](https://takuroooooo.hatenablog.com/entry/2020/10/30/Python%E3%81%AEurllib%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6ImageNet%E3%81%8B%E3%82%89%E7%94%BB%E5%83%8F%E3%82%92%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89%E3%81%99%E3%82%8B)
UnityでOculus GOのアプリを開発してストアに公開する　～最初の準備から開発の準備編～

後半は[こちら](https://qiita.com/Yawarakko/items/544890a6e83eb099b92a)。

---

#環境
windows10
Unity2018.1.0f2

#準備の準備
- developer登録
    [ここから](https://dashboard.oculus.com/organization/create)新しい団体の作成を行ってください。名前は任意のものでOKです。

- OculusGoの設定
    通常のアンドロイド端末と同様、OculusGoを開発者モードにしなくてはいけません。Oculusアプリから設定→その他の設定→開発者モードをオンにします。<br>![S__5406726.png](https://qiita-image-store.s3.amazonaws.com/0/167483/7fe6f5f8-d057-9964-3219-1f4d787fe05d.png)

- AndroidSDKとJDKのインストール
    OculusGoはAndroidで動いてますので、通常のAndroidアプリ開発と同様にAndroidSDKとJDKのインストールが必要です。ただ最新のAndroidSDKを使用するとうまく動かないことがあるらしいので私は25.2.5を使用しています。[ここから](http://dl-ssl.google.com/android/repository/tools_r25.2.5-windows.zip)ダウンロードしてください。JDKは[ここから](http://www.oracle.com/technetwork/java/javase/downloads/index.html)ダウンロードしてください。

- Unityのインストール

    これは言うまでもないですがインストールしてください。ただ、こちらも2018.2以上のバージョンだとうまく動かないことがあったので2018.1.0f2を使用しています。2018.2でも動くようになったらまた新しく記事を書きます。過去のバージョンは[ここから](https://unity3d.com/jp/get-unity/download/archive?_ga=2.14447284.227757747.1535377387-1449478135.1528297463)ダウンロードしてください。

#Unityの準備
- Unityの設定
    まずはSDKとJDKのリンクの設定。<br>
    ![unity_1.png](https://qiita-image-store.s3.amazonaws.com/0/167483/83f97eee-cd62-ebaf-036e-3088284fbcef.png)
    
    PlayerSettingのXRSettingからOculusを追加しVirtual Reality Supportedのチェックボックスをチェック、OtherSettingからPackageNameとMinimumAPILevelを設定。
    私は7.1に設定しました。<br>
    ![unity_2.png](https://qiita-image-store.s3.amazonaws.com/0/167483/345bca27-f523-52a1-afb6-1e0d230029fc.png)
    ![unity_3.png](https://qiita-image-store.s3.amazonaws.com/0/167483/5a4a580a-9dbc-78a1-0bf2-24d88713f26f.png)

#開発の準備
[ここから](https://developer.oculus.com/downloads/unity/)開発に必要なものがダウンロードできます。ひとまずOculus Utilities for Unityをダウンロードし、自身のUnityプロジェクトにインポートしてください。
インポートが完了しましたらOculus/VR/Prefabsの中のOVRCameraRigをシーンに配置してください。既存のMainCameraは不要なので削除しておきます。さらにOVRCameraRigの中のTrackingSpace/LeftHandAnchorとTrackingSpace/RightHandAnchorにそれぞれOculus/VR/Prefabsの中にあるTrackedRemoteを置いてください。Oculusの利き手設定で設定してある方にコントローラが表示されるようになります。<br>![bandicam 2018-08-27 23-51-19-977.jpg](https://qiita-image-store.s3.amazonaws.com/0/167483/5d0d44e8-26c6-6989-d5c4-6d2dcb803897.jpeg)

#ビルドしてみる
ここまで来ましたら、いったんビルドしてみます。
PlatformにAndroidを選択しSwitch Platformをクリック。Run DeviceにOculusが選択されていることを確認しBuild And Runを選択してください。
<br>![unity_4.png](https://qiita-image-store.s3.amazonaws.com/0/167483/15451180-c94e-c098-0773-36d64324b284.png)
なにもない空間にコントローラが表示されたら成功です。

***

まずはここまで、次回はコントローラの取得から実際にストアに公開する方法を記載します。
ITリテラシーが(多分)古めの職場環境でちょっとした変更で社内の運用が大幅に改善した話。

## 背景
ツイッターで [#本当にあったIT怖い話](https://twitter.com/search?q=%23%E6%9C%AC%E5%BD%93%E3%81%AB%E3%81%82%E3%81%A3%E3%81%9FIT%E6%80%96%E3%81%84%E8%A9%B1&src=typd)　というハッシュタグがはやっている昨今ですがいかがお過ごしでしょうか。  


今回は技術的な話題ではなくて運用で満足度が上がったという事例です。
ちょっとしたことで効果が劇的に改善するという例です。

## 改善前の課題
私の会社では1台、数十万する電気系設備（オシロスコープ等）が数十個あり、それを社員全体数百人でシェアしています。 
学校でいうと、50人10クラスあって、それぞれのクラスに5個のすごくいい機械があって　学年の枠を超えて貸し借りをします。

まずこういう場面で最初に出てくるのは貸し借りノートで管理ですが
機械がよく行方不明になったり、期限が過ぎても帰ってきません。


## 改善案
というわけで、ビジネスホテルの予約システムみたいなWEBべージを作りました。
イメージ↓
![image.png](https://qiita-image-store.s3.amazonaws.com/0/46608/a85ece61-211c-20d7-d883-3ecc465670a0.png)

## あらたな課題
全社にわたって設備予約状況見える化されて、過去の履歴も簡単に取れるようになりました・・・・**が**
期限が過ぎても返さない人は結構いました。

とりあえず、期限を過ぎた人には、1weekに1度メールを飛ばすことになりました。・・・**が**
返さない人はやっぱりいました。  

#### A部署の提案
A担「貸出期間が過ぎた人に毎日メール送って注意喚起してくんない？」
私「毎日送られると流石にうざくないっすか？」
A担「<font color="DeepPink">うちは（A室)はそれでいいので、</font>とりあえずやってみましょ」  
  
#### 想定以上の改善
そこからA室の貸出器具の延滞が一気に０件になりました。
その後1ヶ月ほど延滞する状況はありません。


## 会社の背景（文化）に合わせた改善は強い
後から思い出したのですが、A部署はCADをバリバリ使うSolidWorksのフローティングライセンスを利用しており
彼らはSolidWorksの利用時間が超えると15分に1回 メールが飛んでくる文化で
1日1回のメールではまったく気分は害さなかったようです。
  

  
## 意図的に対処レベルの差を作る
会社の部署を横断したシステムの一括変更提案は組織が大きくなるほど難しいです。
スモールスタートという言葉を作って１部署だけをターゲットに絞って運用を開始します。（ITに理解のある担当者いる場所がいい）
彼らも本業が忙しいです。うまくいった部署があれば、私も私もと後追いしてくれる傾向は強いです。
  
  
## まとめ
とりあえずやってくれる協力できる部署を１つ作ろう。
部署の文化は部署の人が知っているので、その人達に合わせてチューニングしよう。
高い効果がでたらよその部署が勝手に乗ってきてくれる。
ざっくばらんなまとめですが以上です。
リージョンとアベイラビリティーゾーン

##1.リージョンとアベイラビリティーゾーン##
リージョンとは、２つ以上のAZをもつ地理的に大きく離れたデータセンターの集合体のことです。
アベイラビリティーゾーン（AZ）とは、リージョンをさらに小さく分割した区分で、1つまたは複数のデータセンターの集合体です。

(例)
ap-northeast-1（東京）リージョン
ap-northeast-1a アベイラビリティーゾーン
ap-northeast-1b アベイラビリティーゾーン
ap-northeast-1c アベイラビリティーゾーン



##2.リージョン##
・複数のリージョンにデプロイできるので、マルチリージョンで簡単に冗長化がすることができます。
・リージョンは互いに完全に分離されており、自動的に他のリージョンに複製されることはありません。
・複数のリージョンにシステムを分散配置することで、障害耐性を高めることができます。

参考：[利用できるリージョン](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-regions-availability-zones.html)

[SERVICE HEALTH DASHBOARD](https://status.aws.amazon.com/)で各リージョン、サービスでの障害情報を確認することができる。

##3.アベイラビリティーゾーン##
・どこかのAZに障害が発生しても、他のAZには影響を及ばさない冗長化の構成となっています。
・AWSのベストプラクティスは複数のAZに実装することです。



##4.エッジロケーション##
・AWSのネットワークへの拠点であり、より高速にコンテンツを配信して行く目的があります。
・キャッシュの機能が備わっており、レイテンシーを減少させる役割があります。
・もっとも近いエッジロケーションへ自動的にルーティングされます。←重要

（例）
・AWS CloudFrount：コンテンツをキャッシュしておく
・AWS Route53：DNSサービス
・AWS Shield：セキュリティサービス
・AWS WAF：セキュリティサービス
など
React NativeでFirebaseのRealtime Databaseを使う -その1-

# やりたいこと
React Nativeで実装したアプリでFirebaseのRealtime Databaseを使ってアプリデータの保存と同期をリアルタイムで行いたい。
今回はAndroidアプリについて実装します。
その1ではReact NativeのAndroidアプリにFirebaseを導入するまでです。

# 導入手順
## React Nativeアプリの作成
```
$ react-native init FirebaseSampleApp
```

## Firebaseプロジェクトの作成
https://console.firebase.google.com/ で新規プロジェクトを作成します。
Databaseを選択し、Realtime Databaseの「データベースを作成」をクリックします。
![スクリーンショット 2018-08-27 22.51.58.png](https://qiita-image-store.s3.amazonaws.com/0/217930/3c035a3f-b961-28a4-0403-01ee0d547b1c.png)
今回はテストモードで開始します。

## AndroidアプリにFirebaseを追加
プロジェクトの設定からAndroidアプリにFirebaseを追加を行います。
![スクリーンショット 2018-08-27 23.03.01.png](https://qiita-image-store.s3.amazonaws.com/0/217930/b2277460-aa98-1439-1442-e15ba78b38e9.png)

Androidパッケージ名は、`android/app/build.gradle`の`applicationId`を指定します。
アプリのニックネームは任意です。
デバッグ用の署名証明書 SHA-1はRealtime Databaseを使う場合入力する必要があります。（Firebase Cloud Messaging（FCM）の機能だけ使いたい場合は省略できるようです）

Mac/Linuxの場合、以下のコマンドでSHA-1を入手できます。
キーストアのパスワードのデフォルトは`android`です。
https://developers.google.com/android/guides/client-auth

```
$ keytool -exportcert -list -v \
-alias androiddebugkey -keystore ~/.android/debug.keystore
```
![スクリーンショット 2018-08-27 23.08.13.png](https://qiita-image-store.s3.amazonaws.com/0/217930/f9a34427-cbf9-38f7-f7e7-c23b630ec3df.png)

入力をしたらアプリを登録をクリックし、次に設定ファイル(google-service.json)のダウンロードを行います。
ダウンロードしたgoogle-service.jsonは`android/app/google-service.json`以下に配置します。

最後にFirebase SDKの追加を行います。
今回はRealtime Databaseを使うためそのSDKも一緒に追加しておきます。

```android/build.gradle
// ...
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
        classpath 'com.google.gms:google-services:4.0.1' // 追加
        // ...
    }
// ...
```

```android/app/build.gradle
// ...
dependencies {
    implementation project(':react-native-firebase')
    implementation "com.google.firebase:firebase-core:16.0.1" // 追加
    implementation "com.google.firebase:firebase-database:16.0.1" // 追加
    // ...
}

// ..

apply plugin: 'com.google.gms.google-services' // 一番下の行に追加
```

```android/app/src/main/java/com/firebasesampleapp/MainApplication.java
// ...
import io.invertase.firebase.RNFirebasePackage;
import io.invertase.firebase.database.RNFirebaseDatabasePackage; // 追加

public class MainApplication extends Application implements ReactApplication {
    // ...

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
          new RNFirebasePackage(),
          new RNFirebaseDatabasePackage() // 追加
      );
    }
  };
  // ...
}
```

これでアプリにFirebaseが追加されました。
一旦、アプリをbuildして実行してみます。

```
$ react-native run-android

$ react-native start
```
![スクリーンショット 2018-08-27 23.41.17.png](https://qiita-image-store.s3.amazonaws.com/0/217930/2c98406f-a535-e72a-f721-bbc93c365923.png)
このような表示になればFirebaseの追加は成功です。
[その2](https://qiita.com/shioiyan/items/04e101a12d4330ce05d9)では実際にアプリからRealtime Databaseにデータ保存と取得を行います。
Amazon Linux用Zabbixリポジトリを作成しました。

AmazonLinuxおよびAmazonLinux2用のZabbixリポジトリを作成しました。
このリポジトリはZabbix LLC および Zabbix Japan LLCとは関係なくqryuu個人により公開/メンテナンスしているリポジトリとなります。
公式リポジトリのrhel用SRPMを元に作成していますので、コンパイルオプションは公式rhel用rpmと同様です。

**ご利用は自己責任でお願いします。**

コンパイル時点で最新のAmazon Linux環境にてコンパイルを行います。
公式リポジトリ公開後1週間以内を目標に公開しています。

#リポジトリ登録
リポジトリを利用する場合、以下のスクリプトを実行してください。
変数宣言の値はインストールしたいZabbixバージョンおよびAmazon Linuxに合わせて変更してください。

```bash:zabbix-repo.sh
#!/bin/bash
#変数宣言
version=4.0 #Zabbixメジャーバージョン 3.0 or 3.4 or 4.0 or 4.2 or 4.4 or 5.0
amazonlinux=amzn2 #AmaznLinuxバージョン amzn1 or amzn2
#リポジトリ登録
echo [amazon.zabbix] >> /etc/yum.repos.d/zabbix.repo
echo name=Amazon-Zabbix >> /etc/yum.repos.d/zabbix.repo
echo baseurl=https://s3-ap-northeast-1.amazonaws.com/amazon.zabbix/$amazonlinux/$version/\$basearch >> /etc/yum.repos.d/zabbix.repo
echo gpgcheck=0 >> /etc/yum.repos.d/zabbix.repo
```

リポジトリ以外はRHEL6/RHLE7と同様にyumにてインストールが可能ですので
[公式ドキュメント](https://www.zabbix.com/documentation/3.0/manual/installation/install_from_packages/server_installation_with_mysql)を参照してインストールを行ってください。

[自動構築スクリプト](https://qiita.com/qryuu/items/c3fb49b33068d6cbabf1)を公開していますので、UserDataを利用すれば2分で導入することも可能です。
RailsでシンプルなTodoアプリをつくる

#はじめに
2017年11月頃に雛形を作成し、その後しばらく放置していたのですが、久々にやる気を出してコーディングしてみました。
自分向けの情報整理が主な目的ですが、役立つ部分が少しでもあればと思い書いています。

#成果物
ToDoGo
https://todoapp-sinhalite.herokuapp.com/
![todogo.png](https://qiita-image-store.s3.amazonaws.com/0/104983/20d36007-9d10-bf12-f28b-41803a76190d.png)

#仕様
- タスクの一覧表示、追加、編集、削除を行うことができる。
- タスクには優先度をLow,Middle,Highの三段階で設定できる。
- タスクには未完了、完了の二つの状態がある。
- タスクは完了しても、一覧からは消えず、打ち消し線で表示される。
- 完了済みのタスクを一括で削除できる。
- タスクを完了にすると、非同期でサーバに通信し、DBを更新する。
- ログイン機能にはDeviseを使用した。

#備忘録
- Windows環境にて作成したので、初期構築時にエラーが何度か発生。Macで開発したほうが良い。
- scaffoldで雛形を作成。余計なファイルや記述を削除する手間があるが、一から書くよりは楽かも。
- scaffolds.scssのエラー用スタイルがダサすぎ問題。
- Deviseは英語から日本語に修正するのが大変だった。
- CSSの調整が大変だったため、Bootstrapなど利用すると楽できた。
- レスポンシブ未対応。やらねば。
- herokuはデプロイ簡単すぎてちょっと不安になる。
- 非同期通信にはJQuery($.ajax)を利用しましたが、モダンじゃないですね。

#終わりに 
ここ一年ぐらい、Django/Flaskの勢いが凄いイメージなんですが、Railsにどうなるんですかね…？
個人的には、RubyはやはりRailsありきだと思うので、機械学習分野でデファクトスタンダードを獲得したPythonで同じようなことができるようになれば、そちらに流れていく気がするのです。
Elasticsearch 6.2.4 で More Like This Query を利用する際にデータを絞り込む

Elasticsearch で More Like This Query を利用して類似文書検索を行う際に、データを絞り込む必要があった場合の方法になります。
More Like This Query の使い方自体は以下のドキュメントにまとまっています。
[More Like This Query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-mlt-query.html)

手元の環境は以下になります。

* Ubuntu 16.04 LTS
* Elasticsearch 6.2.4
* ICU Analysis Plugin、Japanese (kuromoji) Analysis Plugin

Elasticsearch 6系 からインデックスにはひとつのタイプとなったので、親子関係のデータを実現している場合は類似文書検索でもデータのタイプを指定する必要があります。
その場合は [Bool Query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html) と filter を使えば絞り込むことが可能です。

[この記事](https://qiita.com/nettle0010/items/e3374ff825d896a3863e) のデータを引き続き活用して試すため、以下のデータを追加します。

```
{"index": {"_index": "shop", "_type": "_doc","_id": "goods_id.3"}}
{"type": "goods","name": "原酒三岳","text": "もののけ姫のモデルにもなった、鹿児島県屋久島の焼酎です。こちらは原酒になります。屋久島は水が美味しく、その水を
使って作られています。ロックで飲むことをオススメします。","my_join_field": "goods"}
```

そして、以下のように実行します。( jq コマンドで整形してます。)
便宜上、min_term_freq （出現頻度の最低値）をゼロにしています。

```
$ curl -X POST 'localhost:9200/shop/_search' -H 'Content-Type: application/json' -d'
{
    "size": 5,
    "query": {
        "bool": {
            "must": {
                "more_like_this": {
                    "fields": ["text"],
                    "like":[
                    {
                        "_index" : "shop",
                        "_type" : "_doc",
                        "_id" : "goods_id.1"
                    }
                    ],
                    "min_term_freq": 0
                }
            },
            "filter": { "term": { "type": "goods" } }
        }
        }
    }
}
' | jq
```

すると、以下のような結果が返ってきます。

```
{
  "took": 41,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.19518803,
    "hits": [
      {
        "_index": "shop",
        "_type": "_doc",
        "_id": "goods_id.3",
        "_score": 0.19518803,
        "_source": {
          "type": "goods",
          "name": "原酒三岳",
          "text": "もののけ姫のモデルにもなった、鹿児島県屋久島の焼酎です。こちらは原酒になります。屋久島は水が美味しく、その水を使って作られています。ロックで飲むことをオススメします。",
          "my_join_field": "goods"
        }
      }
    ]
  }
}
```

パラメータもいくつかあるので、チューニング次第では面白い結果が出せるかもしれません。

### 参考になった記事
[More_like_this query with a filter](https://stackoverflow.com/questions/36299591/more-like-this-query-with-a-filter)
Amazon Macieで複数のAWSアカウントを統合管理できない人生に終止符を打とう

俺です。

Amazon MacieでDLPな人生を送るためのTipsです。
AWS Macieは複数のAWSアカウントからCloudTrailやS3の証跡を分析できるData loss prevention プロダクトですが、導入時の設計が重要のように思えます。


試験的にdevelop用AWSアカウントでMacieを試した後、
Production利用のために別のAWSアカウントでMacieを使うとき
develop用AWSアカウントで有効にしたMacieは無効(削除)しないとdevelop用AWSアカウントを
SecurityアカウントのMacieへ招待できないのDEATH.

# Macieを活用するAWSアカウントの設計

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42755/d55ddd83-6f83-b643-95a0-c95e24a909d2.png)


# 招待対象のAWSアカウントでMacieを有効にしていたときの対応

招待するAWSアカウントでMacieが招待されて情報収集されている、もしくは他のAWSアカウントに招待されている場合はMacieを停止します。

## Macieの停止

Macieを止めた場合はデータを吹き飛ばされますなーむー

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42755/313db97f-e308-32ac-ca07-a99f304d679b.png)

## Macieへの招待

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42755/5b5a0564-354b-958e-af15-1b01e8db1c4d.png)

安易にリージョンの変更がきかないプロダクトっぽいように見えるので、
現状us-west-2/us-east-1で有効にして集約しているのであれば、そのままにしておいたほうがよいように思えました。(小並感)

という話だったのさ終わり。
静的ファイルを配信するだけのシンプルな Node.js + Express

### 使いどころ

- 静的ファイルをウェブ配信する簡易サーバが欲しいときに。

```js:app.js
'use strict';

// required packages
const path = require('path');

// base
const express = require('express');
const app = express();
app.set('port', 1337);

// static files
app.use(express.static(path.join(__dirname, './wav')));

// server
const http = require('http');
const server = http.createServer(app);

// http 404 error handler
app.use(function (req, res, next) {
    const err = new Error('errorMessage.urlNotFound');
    err.status = 404;
    next(err);
});

// error handling middleware should be loaded after the loading the routes
if ('development' === app.get('env')) {
    const errorHandler = require('errorhandler');
    app.use(errorHandler());
}

// listen
server.listen(app.get('port'));
```

```json:package.json
{
  "name": "★★★",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "start": "node app"
  }
}
```

```
npm install --save express errorhandler http path
```
【Rails】フォームヘルパーの種類と例

#入力フォームを作る
入力のためのフォームを作成するためにHTMLにはフォームタグというタグが存在する。
Railsのヘルパー「フォームヘルパー」を用いて、フォームタグを生成する例を紹介していく。

##フォームの種類
様々な入力フォームがあるので、用途に応じて下記から選んで使用。

|メソッド名|機能|メソッド名|機能|
|:-----------------|:-------|:-----------------|:-------|
|search_field|検索用ボックス|week_field|週ボックス|
|label|ラベルを作成|telephone_field|電話番号用ボックス|
|text_field|テキストボックス|file_field|ファイル選択用ボックス|
|email_field|メールアドレス用ボックス|password_field|パスワード用ボックス|
|range_field|範囲選択バー|hidden_field|隠しフィールド|
|number_field|数値選択|text_area|テキストエリア|
|select|選択ボックス|check_box|チェックボックス|
|date_field|日付ボックス|radio_button|ラジオボタン|
|datetime_field|日付時刻ボックス|url_field|URL用ボックス|
|datetime_local_field|日付時刻ボックス(ローカル)|color_field|色選択ボックス|
|month_field|月ボックス|submit|提出用ボタン|
|time_field|時刻ボックス|


##form_tagとform_for
フォームを扱うことのできるメソッドは「form_tag」と「form_for」の2種類。

- form_tag<br>モデルと関係しない汎用的なフォームを生成
- form_for<br>特定のモデルを編集するのに特化している

上に示した特徴踏まえて、どちらを使用するか決定。

#使い方
HTMLファイル内における記述の仕方を実例と一緒に紹介していく。

##form_tag
form_tagを使用する部分を
<font color="Red">\<%= form_tag(rootpath名, method: HTTPメソッド) do %></font>
<font color="Red">\<% end %></font>
で囲む。

``` html: 
# 例
<%= form_tag(users_path, method: :post) do %>
    <!-- ここにform_tagメソッドを記述 -->
<% end %>
```
rootpath名ではなく相対パスや、コントローラ名とアクション名で代用することもできる。

``` html: 
# 例
<%=form_tag({controller: :users, action: :create}) do %>
    <!-- ここにform_tagメソッドを記述 -->
<% end %>
```
このようにコントローラ名を用いる場合は、routes.rbにおいてポスト先のルートをしっかり定義しておく必要がある。
また、HTTPメソッド(POST, GET, PUTなど)は指定しない場合は自動的にPOSTにしてくれる。

form_tagメソッドは基本的に、下記の形になる。(<a href="https://qiita.com/Hal_mai/private/4a156e83c66a937657ce">サンプル</a>)

``` html: 
<%= [メソッド名]_tag :名前 %>

#例　　<%= email_field_tag :email %>
```

##form_for
form_forを使用する部分を
<font color="Red"><%= form_for(格納したい変数, url: rootpath名, method: HTTPメソッド名) do |f| %>
<% end %></font>
で囲む。

``` html: 
# 例
<%= form_for(@user, url: users_path, method: :post) do |f| %>
    <!-- ここにメソッドを記述 -->
<% end %>
```
form_forメソッドは基本的に、下記の形になる。(<a href="https://qiita.com/Hal_mai/private/21536722f82d2c9e4018">サンプル</a>)

``` html: 
<%= f.[メソッド名] :カラム名 %>

#例　<%= f.telephone_field :phone %>
```

---
これらを使ってテーブルに新しいデータを追加する方法は<a href="https://qiita.com/Hal_mai/items/18fcf239d715ab6790b0">こちら</a>で紹介している。
Node.js で stream の内容を一時的にメモリで受け止める stream

```js
const MemoryStream = require('memorystream');

let writableMemory = new MemoryStream();
readableStream
    .on('data', (data) => {
        writableMemory.write(data);
    })
    .on('end', () => {
        writableMemory.end();
    })
;
```

- 当然ながら end 忘れるとストリームが終わったとみなされないので注意。
網頁元件/畫面捲軸控制 (Scrollbar) By 彭彭

![WS000012.JPG](https://qiita-image-store.s3.amazonaws.com/0/280122/b9be0df6-e130-a0d5-a415-f695fa64ecbc.jpeg)![WS000013.JPG](https://qiita-image-store.s3.amazonaws.com/0/280122/49930f3b-68d8-b27b-7a7b-9016e340c8a2.jpeg)
![WS000014.JPG](https://qiita-image-store.s3.amazonaws.com/0/280122/4b9fffd4-9a3e-2833-f4b7-f286594dd0a5.jpeg)![WS000015.JPG](https://qiita-image-store.s3.amazonaws.com/0/280122/402f01ab-d10c-8b14-928c-7df3c5ac4e39.jpeg)



```ruby
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>卷轴</title>
<script>
	var box;
	window.onload=function(){
		box=document.getElementById("box");
		//box.scrollTop=30;//scrollTop
		window.setInterval(scroll,10);//排成 每0.05秒自动加1
	};
	function scroll(){
		box.scrollTop++;
	};
</script>
<style type="text/css">
	.box{
		border:1px solid #000;width:200px;height:80px;
		overflow:auto;
		overflow:hidden;//隐藏卷轴
	}
</style>
</head>
<body>
	<div id="box" class="box">
		<div>this is line 1</div>
		<div>this is line 2</div>
		<div>this is line 3</div>
		<div>this is line 4</div>
		<div>this is line 5</div>
		<div>this is line 6</div>
		<div>this is line 7</div>
		<div>this is line 8</div>
	</div>
</body>
</html>

```
Intellij / WebStorm で補完が効く JsDoc の書き方 (随時更新)

### 引数/戻り値

```js
/**
 * @param {string} aaa
 * @param {number} bbb
 * @param {object} obj
 * @param {int} obj.xxx
 * @param {string[]} obj.yyy
 * @return {int}
 */
```

### 引数が省略可能

```js
/**
 * @param {number} [aaa] 省略可能
 * @param {object} obj
 * @param {int} [obj.xxx]
 */
```

### 引数がnullable

```js
/**
 * @param {?number} aaa - nullかnumber型
 */
```
### 引数が可変

```js
/**
 * @param {...number} aaa
 */
```

### 戻り値にPromise/async関数

```js
/**
 * @return {Promise<number>}
 */
```

### 戻り値に構造体的なオブジェクト

```js
/**
 * @return {{aaa: int, bbb: boolean}}
 */
```

### 戻り値に動的なオブジェクト(キー: string / 値: 数値)

```js
/**
 * @return {Object.<string, number>}
 */
```

### 引数にコールバック関数

`aaa => parseInt(aaa)` みたいなものを受けとる場合

```js
/**
 * @callback Callback_Name
 * @param {string} aaa
 * @return {int}
 */

/**
 * @param {Callback_Name} xxx
 */
```
cookieとsessionのお話

#cookieとは

[セキュリティ用語集 - Cookie とは?](https://www.microsoft.com/ja-jp/safety/terms/cookie.aspx)

Cookie は、ユーザー設定についての情報を保持するために、Web サイトによってユーザーの PC に保存される小さなファイルです。Cookie を使用して、サイトにユーザーの個人設定を記憶させたり、サイトにアクセスする際のサインインを省略可能にしたりして、利便性を向上させることができます。しかし、一部の Cookie は、ユーザーがアクセスするサイトを追跡してプライバシーを侵害するおそれがあります。
~~マイクロソフトより

だそうです。

つまり、ユーザがサーバに対して、何かしらリクエストをした際にレスポンスと同時に返してくれる、一連の情報です。
その中にユーザーの情報（例えばsession_idなど）が含まれています。
これを使うことで、ユーザーは次回ログインする際に、自動的にidを入れてくれたり、何なら自動ログインもしてくれたりします。


![スクリーンショット 2018-08-27 17.47.40.gif](https://qiita-image-store.s3.amazonaws.com/0/147990/b75ca062-2b53-3149-2869-de4bb6edabee.gif)
　　　　　　　　　　　　　　　　　　　↑↑
レスポンスするタイミングでcookie情報もブラウザに渡す

#cookieを扱う際の注意点的な話(dbで対応)
こんな便利なcookieですが、扱う上では工夫したり、対策する必要もあります。
もちろん下の例以外にもいろんなパターンがあると思いますので、これから調べていきたいと思います。

##ユーザーの利便性を高める
サーバーを複数台利用する際を考えます。大きなサービスになってくると、このように複数台になることがあります。

![スクリーンショット 2018-08-27 22.12.13.gif](https://qiita-image-store.s3.amazonaws.com/0/147990/20dea1e6-bfd6-feda-4056-43baed599f8a.gif)

図の中央にあるロードバランサーは、負荷分散システムであり、一つのサーバーに負荷が集中することを防ぎます。
普通であれば上の節で話したように、リクエストを出してレスポンスがくるタイミングでcookieが保存されるため、一つのwebサーバではcookieが使えます。しかし、複数のwebサーバを利用している場合は、一つのwebサーバにcookie保存できても、もう一つのサーバーにはcookieが保存できていないという現象が起こり得ます。そうなると、以前ログインしたのに、cookieが保存されておらず、再度ログインしなければならないということになります。

なので。。。。

![スクリーンショット 2018-08-27 22.14.32.gif](https://qiita-image-store.s3.amazonaws.com/0/147990/01e3554b-74f3-2e55-b5b4-2e73c9048859.gif)


db（例ではredis）を用意して、cookie情報を統一することができます。そうすればたとえ、一つのサーバにしかログインしていなくても、もう一つのサーバにアクセスした際にしっかりログインした動作を行うことができます。

##セキュリティを強化する

次はセキュリティの話です。有名どころで言えばセッションハイジャックなどがこのcookieには関わって来ます。


cookieの中にはsession_idというidがあり、それを利用して、「このユーザーは以前この操作をしたユーザーだ」ということがわかるようになります。
しかし、このsession_idを盗み出すことで、その人になりすますこともできます。
なので、session_idやそれに紐づくカラムをredisに保存することでそのような攻撃を防ぐことができます。

![スクリーンショット 2018-08-27 22.29.39.gif](https://qiita-image-store.s3.amazonaws.com/0/147990/07f29cee-a293-f0d9-5dd3-919a47c3c0d8.gif)


#より良いサービスのために

これらは単に動かすだけではなく、よりユーザービリティを上げるためにはどうすれば良いかを考える施策になります。
なので、単に書くだけではなく、このようなところにも注意を配れるようになっていきたいと思います。
Firebase Functions を使ってみた感想(メモ)

### 使いどころ

- 試行錯誤はしない段階で。本番でのスケーラビリティがとにかくほしい場合に適合してそう。

### メリット

- スケーラビリティを確保したうえでのインフラ設計の容易さ。
- ログも画面から見れるし、firebase deploy コマンドで配布もできる。
- ネットワークやら、デプロイやらの設計が一切いらない。
- https の URL が発行される。
- google の他サービス(dialogflowやdatabase)にクレデンシャルなく接続できる。ただし、自身への認証どうするかはあるけど(Firebase Auth使うべきか)。

### デメリット

- ログの tail はしづらい（ちょっと遅れる）。ステージング機レベルでのやりやすさは無い。あくまでも本番。
- node 6.9 に縛られるのが相当きつい。他と eslint わけるしかない。
- デプロイは遅い。ローカルで動かしたくなってしまう。

### 利用メモ

- 中は Google Cloud Functions と同じっぽい。
- Google Cloud Functions からしか削除はできない。

### 技術メモ

- node のバージョンが違うので eslint は必ず置いたほうがいい。
- `firebase init` は gitbash からはできない。cmd ならできるのでそっちで。
Windows のキーボードレイアウトを日本語配列に変更する

# Windows のキーボードレイアウトを日本語配列に変更する

IaaS で Windows Server を作成して RDP すると、キーボード配列が英語で面倒くさいのを一発で直す PowerShell スクリプト.

```powershell
Import-Module International
$x = New-WinUserLanguageList en-US
$x[0].InputMethodTips.Clear()
$x[0].InputMethodTips.Add("0409:00000411")
Set-WinUserLanguageList $x -Force
```
アプリアイコンのBageと通知センター表示について


<div align="center">
<img width="602" alt="スクリーンショット 2018-08-27 22.14.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/133940/2fa8f39d-8d13-7cf0-480d-074bb269de08.png">
</div>

私がかなり苦戦したので書きます。こう言う質問は結構あったのに記事はなかったのでないなら書かないとと意味不明な使命感に狩られて書いてます。
只今とても元気がないので乱雑な記事になってしまったらごめんなさい。
いつか気が向いた時にでも書き直します。

さて、早速ですが、アイコンのBageや通知センターの表示で悩んでいる人はきっと少なからずいるはず。
そしてどこまで出来るの？とちょっと前の私のように。

で出来ることですが、パターンで書いた方がいいと思ったのでパターン書きします。
詳細はそれらパターン下に書いて行きます。


###アプリ開いたらプッシュ通知のバッジ、通知センターの表示全削除
勝手な偏見ですがほとんどの方がこのパターンだと思っています…。やることとしてはあのおなじみUIApplication.shared.applicationIconBadgeNumber = 0を起動時に通るところで書けばいいです。

###通知センターの表示はそのままアプリバッジ削除したい。(通知センターどれか選択しても読んでいないものは通知センターから消えない)
これについてですが最初からバッジをつけないと言う方法ならできます。方法としてはサーバーから送るバッジの数を-1にして送ってもらう感じです。ローカル通知を自分で作成してでしか試していませんが出来るはずです。ただこれ一生バッジつきません。

###通知センター通知センターの表示はそのままアプリバッジつけたい。(通知センターどれか選択しても読んでいないものは通知センターから消えない)
これもできます。しかしここでバッジはアプリ開いたタイミングで消すことはできません。そうすると通知センターの表示は消えます。これに関してバッジの数の処理をしなければいい。またはプッシュ通知の情報(通知センターの内容、個数)取得してバッジの数変更。なくなった時に0にするでもいいのかと思います。

###通知センターの個数とバッジの個数を揃えたい。
これも出来るはずです。しかしサーバー側アプリ側でのタッグを組む必要があります。方法として考えるのはまずアプリ開いた時に通知センター表示の個数取得サーバーに転送、サーバーは新しいプッシュ通知送る時にそれを足して送るとか。それに加えてアプリがフォアグラウンドにあるときにプッシュ通知が来た時もメソッドで拾って調整すると言う感じかと思います。

###任意の時にバッジ、通知センター表示全消去それまでは通知センターは開いたものしか消去しない。
これは普通にプッシュ通知送ってもらいもちろんカウント1以上。でその任意で何か行ったことがあればいつもとおなじみのもので削除する感じかと思います。

###バッジのみ表示
この場合はもはやプッシュ通知と言うよりも中の処理に応じてバッジの数を変える方法で行っているのが多いのではないのかなーと思っています。

###プッシュ通知来たタイミングでそのあとにローカル通知を送る
これはプッシュ通知来たタイミングでローカル通知つくて送る。あまりしない方法かと思いますが一応書いておきます。


###最後に
おそらく上記のパターンで行っている以外にはないのではないかと思っています。他にもこんな方法あるよと言う方は教えていただければ嬉しい限りです。で結局大事なこと。他にもありますが…

・UIApplication.shared.applicationIconBadgeNumber = 0　又は マイナス
にした時点で通知センター表示は全消去

・通知センターの表示を消したくないのならサーバーから送ってもらうバッジ数を-1にしてもらうこと。ただしこれなアイコンにバッジがつきません

・どこでバッジを消すか？どこで通知センターの表示を全消去するか、通知センターは全消去するかタップのもののみ消していくかを考える必要あり。

最後にローカル通知の記述わかりやすかったurlを載せて終了とします。https://stackoverflow.com/questions/42688760/local-and-push-notifications-in-ios-version-compatible/42688966


:shamrock:

あともうちょっとだけやっぱり書く。
ちなみに。私はそのような経験なかったのですが、バッジが0にならない通知センターから消えないと言うようなバグがあるらしい。バッジが消えないに関しては一回マイナスにしてから0にするといいよとか書いてありました。書いてあったurl今パッと見れないので又見つけたらここに追記しておきます。

参考、あ！いいかもと思うurlの羅列
https://stackoverflow.com/questions/45732146/how-to-get-the-push-notifications-displayed-in-the-notification-center
情報処理安全確保支援士（旧：セキュリティスペシャリスト）対策・勉強法　その1

情報処理安全確保支援士の取得を使用と思い、どうせだったら現状や学習計画などを残せる形にした方が、落ちた場合の振り返りや、今後他の資格にチャレンジする場合にも使えるだろうと思い投稿する。


#前提
私の知識前提
・ネットワーク上がりのセキュリティエンジニア
・昨年は、春、秋に応用情報に受験、どちらも午後が得点伸びず落ちている。
・今年、CEHに合格
　⇒CEHについて記載している記事は[こちら](https://qiita.com/ma320/items/1b17ec4d12f58f1fb304)

#現状
まずは現状の実力がどんなものか、ということで過去問1回分を行った。

・午前I
正答率：55%
昨年の春と秋、応用情報を受験していたこともあり、なんとなく覚えている問題もあった。
過去問などで数をこなしていけば、問題なく合格できるだろうという手ごたえ。

・午前II
正答率：55%
ある程度即答できる問題はあったが、分からない問題もあった。
そして、回答できるが、何故そうなるのか、技術的に自分の中でうまく説明できない問題があった。
従って、正しい理解が出来ていないと、違う角度や少しひねった問題が出た場合に間違えてしまう可能性がある。
何より、理解できていないと午後問題でつまずく可能性が大きい。

・午後I
正答率：35%
単純に知識がなく答えられない問題もあったが、問題文をよく読んでいれば回答できるようなところ、見当違いな回答をしているところがあった。
知識というより、国語が出来ていないという印象。

・午後II
正答率：25%
午後Iでできていないところについて、より出来が悪い状態だった。
問題で問われていることを正しく理解できておらず、ミスリードが多発していた。
知識についても、セキュリティにおける考え方がグラついており、正しい判断が出来ていない状態である。

午前はパスできそうなイメージが沸いているが、午後が問題であるといえる。
昨年の応用情報の試験でも、午後の回答について、問われている内容を正しく解釈できず間違えてしまっていたため、午後を重点的に取り組む必要がある。
そしてもちろん、各知識についても理解が必要である。


#学習方針
過去問を1回分解くことによって、今後の学習方針がある程度見えたので記述。

基本的にセキュリティの知識で浅いところ、あやふやなところがあるため、正しく理解する。

ただ、私の場合本をずーっと読んでも、頭に入らなかったり、すぐ眠くなったり、違うことを考え出すので、基本的に問題を解きながら参考書で理解を進める方式が良いと思われる。

また、午後問題については、上記の知識だけでなく、出題者の意図を正しく汲み取れず、そもそも回答の方針を間違えてしまい、見当違いな回答をしてしまっていると思われる。
従って、国語的な部分も伸ばさないといけないと考える。


#おわり
ある程度やる方向性は見えたので、より具体的な学習方法などを別途投稿する。