OmniAICreator/Qiita-1.07M huggingface dataset:
ActiveStorageのseedデータを投入する際のエラー

Railsでアプリを作成する際、ActiveStorageを使って画像のseedデータを投入しようとしたところ、少しはまったので備忘録です。

# seedデータが通らない

記事などを参考に

```seeds.rb
user = User.find(1)
user.image.attach(io: File.open('app/assets/images/test.jpg'), filename: 'test.jpg')
```

とした後、

```
$ rails db:seed
```

としても通らないので、ぐぐってみる。


```ruby:config/environments/development.rb
config.active_job.queue_adapter = :inline
```

を追記したら無事とおりました。
【随時更新】設定している短縮コマンド(alias) 

# 環境
Mac
bash

# コマンド (git)
|短縮コマンド|元のコマンド|設定|
|:--|:--|:--|
|g|git||
|ga.|git add .||
|gci|git commit||
|glo|git log --oneline||
|gfo|git fetch origin||
|gamend|git commit --amend||

# コマンド (C)
|短縮コマンド|元のコマンド|設定|
|:--|:--|:--|
|gccW|gcc -Werror -Wall -Wextra||

# 備考
もしこんな便利な短縮使ってるよ！というのがあれば教えてください。
【Minecraft 1.12.2 Modding】本体が写っていないときも常にTileEntitySpecialRendererを表示する方法

# 方法
TileEntityのBoundingBoxの大きさを変更します。maxRenderDistanceを変更すると、非常に遠くからでも見えるようになります。

```java:TileEntity
@Override
public AxisAlignedBB getRenderBoundingBox() {
    return TileEntity.INFINITE_EXTENT_AABB;
}

@Override
public double getMaxRenderDistanceSquared() {
    return Float.POSITIVE_INFINITY;
}
```
またTileEntitySpecialRendererに以下のメソッドを追加してください。

```java:TileEntityRenderer
@Override
public boolean isGlobalRenderer(TileEntitySuperShape p_isGlobalRenderer_1_) {
    return true;
}
```

私が作成したSuperShape Modはシンプルなので、TileEntitySpecialRendererを学ぶのにおすすめです。
https://github.com/Nekodigi/SuperShape-Mod
ubuntu18.04 on WSL 上に yarn-1.22 の環境を構築する手順メモ

# はじめに

covid19対策（まとめ）サイトの開発環境の一つである yarn を WSL 上に構築するたの手順として、各所の構築手順をまとめただけのメモです。
covid19対策サイトは、各都道府県単位などで開発・公開されており、本家東京都版はGitHub https://github.com/tokyo-metropolitan-gov/covid19 にあります。

# 構築手順

## WSLの導入

まず、Windows10 に WSL(Windows Subsystem for Linux)のubuntu 18.04 を導入します。
（追記）WSL2でも、Ubuntu 20.04でも導入手順は同じ。

参考：https://qiita.com/yasushi00/items/0e2bf042c14862c87ce2#%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB-1


## nodeの導入

次に node を導入しますが、apt で入るものは古いので、一旦 apt で依存関係を含めて導入した後、最新版に差し替えます。
まず、aptで nodejsと npm をインストール

```
sudo apt install -y nodejs npm
```

次に n package を導入し、最新の node をインストール

```
sudo npm install n -g
sudo n stable
```

aptで入れた nodejs, npm を削除

```
sudo apt purge -y nodejs npm
```

再ログイン後、インストールした nodeのバージョンを確認

```
$ node -v
v12.16.1
```

/usr/local/bin/node だと実行できる場合は、/usr/local/bin にパスを通す。

## yarnの導入

https://yarnpkg.com/en/docs/install#linux-tab に従ってインストール。

```
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update && sudo apt install -y yarn
```

インストールした yarn のバージョンを確認

```
$ yarn -v 
1.22.4
```

同時に入る nodejs は古いので削除。

```
sudo apt purge -f libuv1 nodejs
```

## 必要なパッケージのインストール

必要なパッケージ情報は、githubに登録されているので、まずクローンします（クローン済なら省略）。

cloneする前に自分のGitHubアカウントに fork （分岐コピー）することを推奨。fork手順は、https://qiita.com/FPC_COMMUNITY/items/b9cc072813dc2231b2b2 あたりを参照。

```
git clone GitHubのリポジトリのURL
```

クローンしたディレクトリに移動して、パッケージのインストールを実行

```
cd covid19  # cloneしたディレクトリ
yarn install
```

しばらく待つとパッケージのインストールされます。

## ローカルサーバの起動

```
yarn dev 
```

初回はビルドに時間がかかります。
ビルドが終わったら、http://localhost:3000 にアクセスして動作を確認。edge等の、Windows ブラウザで表示できます。

## 修正・更新

ソースやデータを編集すると、自動で更新されますので、しばらく待つとブラウザで確認できます。
実際に貢献する方法は、https://qiita.com/FPC_COMMUNITY/items/b9cc072813dc2231b2b2 などを参照。

# 参考

## （おまけ）Windowsに直接導入する場合の一例

- node.js

https://nodejs.org/ja/download/ から Windoss Installer (msi）をダウンロードし実行。

- yarn

https://classic.yarnpkg.com/ja/ からインストーラーをダウンロードして実行

- バージョン確認

コマンドプロンプトを立ち上げてバージョン確認

```
>node -v
v12.16.1
>yarn -v
1.22.4
```

- yarnでパッケージインストールとサーバ起動

```
cd covid19  # cloneしたディレクトリ
yarn install # パッケージインストール
```

- サーバ起動

.env で GENERATE_ENV=development を指定し http://localhost:3000 が表示できれば完了。

```
yarn dev # 起動
```



## 参照先
このページの内容は以下のリンク先を参考にさせていただきました。

* n package https://github.com/tj/n
* yarn本家 https://classic.yarnpkg.com/en/docs/install#windows-stable
* Qiita
  * https://qiita.com/StoneDot/items/0b6b5b74de8f4e07af95
  * https://qiita.com/seibe/items/36cef7df85fe2cefa3ea
  * https://qiita.com/FPC_COMMUNITY/items/b9cc072813dc2231b2b2
  * https://qiita.com/chihiro/items/d018599ef13c35781412
  * https://qiita.com/munieru_jp/items/3b1edceadb3990a901c8
  * https://qiita.com/yasushi00/items/0e2bf042c14862c87ce2
モーダル、SPのメニューが表示されたときだけ中の要素をスクロールさせる

## モーダル、SPのメニューが表示されたときだけ中の要素をスクロールさせる

※覚書メモです

以前[jQueryでモーダルやSPのメニューを表示したときに背景を固定する記事](https://qiita.com/TAO_TAO_/items/fc8c8fefed95c55c822f)を載せたことがありました。
しかしそれから数年たって、そんなことをしなくても簡単に実装できちゃういいものを見つけることができました（教えてくださった同僚には感謝です）。

## body-scroll-lock

▽github
https://github.com/willmcpo/body-scroll-lock

▽npmjs
https://www.npmjs.com/package/body-scroll-lock


指定した要素だけスクロールができるようになるというライブラリ。
androidもiosも難なくできました。
まさにそれがしたかったこと…！

***

### 以下使い方
今回もyarnを使います。
yarnじゃなくてもnpmでも大丈夫です（インストールするときのかき方が違うので気を付けてください）

```
yarn add body-scroll-lock
```


例)開くとき

```js
import { disableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock'

// 例えばメニュー
const openBtn = document.getElementsByClassName('openBtn')[0]
const menuInner = document.getElementsByClassName('menu-inner')[0] // スクロールさせたい要素

openBtn.addEventListener('click' , () => {
	disableBodyScroll(menuInner)
})

```

分かりやすいように「開く」「閉じる」を分けましたが、上の例に続いて書いても大丈夫です。

例)閉じるとき

```js
// 例えばメニュー
const closeBtn = document.getElementsByClassName('closeBtn')[0]

closeBtn.addEventListener('click' , () => {
	clearAllBodyScrollLocks()
})

```

この2つだけ。スクロールさせたい要素の指定を変更すればすぐに実装できます。
あんなに頭を悩ませていましたが、本当に簡単なので早く知りたかったです。。


以上
Serverless Frameworkで AWS Lambda Layersを作る

#目的
Serverless Frameworkを使って、Lambda関数と同時にLambda Layerを作成する。
#ディレクトリ構成
```
sls-example
  ├── handle.py
  ├── layers
  │   └── pillow
  │       ├── package.sh
  │       └── requirements.txt
  └── serverless.yml
```
```text:requirements.txt
pillow==6.0.0
```
```sh:package.sh
#!/bin/sh

export OUTPUT_DIR="python"
rm -rf ${OUTPUT_DIR} && mkdir -p ${OUTPUT_DIR}
docker run --rm -v $(pwd):/var/task -w /var/task lambci/lambda:build-python3.6 \
    pip install -r requirements.txt -t ${OUTPUT_DIR} 
```
```yml:serverless.yml
service: sls-example

provider:
  name: aws
  runtime: python3.6
  stage: dev
  region: us-west-2
plugins:
  - serverless-python-requirements
package:
  individually: true

# AWS Lambda Layers
layers:
  pillow:
    path: layers/pillow
    name: ${self:service}-pillow
    compatibleRuntimes:
      - python3.6
    allowedAccounts:
      - '*'

# AWS Lambda Functions
functions:
  analyze:
    handler: analysis_lambda.analyze
    layers:
      - {Ref: PillowLambdaLayer}
#     - arn:aws:lambda:${self:provider.region}:xxxxxxxxxxx:layer:{service名}-{layer名}:{バージョン}
```
#デプロイ
```shell
cd pillow
./package.sh
cd sls-example
sls deploy
```
デプロイ時　よく使ったコマンドメモ　自分用

#unicorn
起動　
bundle exec unicorn_rails -c config/unicorn.rb
unicorn_rails -c /var/www/rails/(アプリの名前)/config/unicorn.conf.rb -D -E production

状態確認
ps -ef | grep unicorn | grep -v grep

#mysql
起動
sudo service mysqld start

production環境でのDB削除
RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake db:drop

接続
mysql -h エンドポイント -P 3306 -u root -p

DBの文字コードチェック
show variables like "chara%";

#nignx
再起動
sudo nginx -s reload

#vimコマンド
強制書き込み
$ sudo vim <ファイル名>
:w !sudo tee %
:q!

#プリコンパイル
bundle exec rake assets:precompile RAILS_ENV=production
コマンド1発で特定のポートのプロセスをkillする

# Address already in use
ローカルでサーバー開発している際
`Caused by: java.net.BindException: Address already in use`
など、プロセスが残ったままで起動に失敗することがままある。
とりあえずkillする際、順当にやるのであれば

## 起動中のポートを調べる
コマンド

```
lsof -i:8080
```
結果

```
COMMAND  PID   USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
java    5229 growsic  231u  IPv6 0x37f621378bd0a299      0t0  TCP *:http-alt (LISTEN)
```
でPIDをコピーし

## プロセスをkill

```
kill -9 5229
```

のように行う。
ただ、**特定のポートをkillしたいだけなのにめんどくさい。**

# 解決策
コマンドの方針としては

- lsofでポートの数字のみを抜き出す
- 抜き出したポートを引数にkillする
 
のように行う。
## lsofでポートの数字のみを抜き出す
コマンド

```
lsof -t -i:8080
```
`-t`オプションをつけることで、ポートの数字のみを取得できる

結果

```
5229
```

## 抜き出したポートを引数にkillする
コマンド

```
kill -9 $(lsof -t -i:8080)
```

`lsof -t -i:8080`を先に評価し、得られた数字を引数にkillコマンドが実行される。

# 結論
コマンド

```
kill -9 $(lsof -t -i:{ポート番号})
```
Spring Bootの設定値をMapで受けたい

# 遭遇したできごと

当然のように↓みたいにしたら、エラー

```yaml
config:
  map:
    key1: value1
    key2: value2
```

```java
@Configuration
public class Config {

  @Value("${config.map}")
  private Map<String, String> map;
}
```

エラー発生。

```
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'config.map' in value "${config.map}"
	at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:178)
	at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:124)
	at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:236)
	at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210)
	at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda$processProperties$0(PropertySourcesPlaceholderConfigurer.java:175)
	at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:908)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1228)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:636)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:116)
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:397)
	... 155 more
```

エラー内容見ても何がなんだかわからず…。

# 正解

`@ConfigurationProperties` を使って `setter` を付けておくのが正解らしい。動いた。

```
@ConfigurationProperties("config")
public class Config {

  private Map<String, String> map;

  public void setMap(Map<String, String> map) {
    this.map = map;
  }
}
```

`@ConfigurationProperties` と `@Value` は動きが違って混乱した。
CentOS に nginx をインストールする

CentOS に nginx をインストールする、メモ。

```
cat /etc/redhat-release 
CentOS Linux release 7.7.1908 (Core)
```

リポジトリ追加

```/etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
```

```
ls -l /etc/yum.repos.d/
-rw-r--r--. 1 root root  100 Dec 24 01:53 nginx.repo
```

インストール

```
yum info nginx
```

```
yum install nginx
```

起動設定と開始

```
systemctl enable nginx
```

```
systemctl start nginx
```

```
systemctl status nginx
```

ファイアウォール　←　ここ忘れる。

```
firewall-cmd --add-service=http --zone=public --permanent
firewall-cmd --reload
```

---

|場所|説明|
|---|---|
|/etc/nginx/|Nginx の設定ファイルが保存されているディレクトリ|
|/etc/nginx/nginx.conf|	メインとなる設定ファイル|
|/var/log/nignx/|Nginx のログが保存されるディレクトリ|
|/usr/share/nginx/html/|WEBサイトの公開ディレクトリ|
Laravel + PHPUnitでパスセグメント（パスパラメーター）を再現する

> ここのコードは実際には動作しないと思われます。
> 俺たちは雰囲気でコードを書いている。

例えば以下のようにURLを設定します。

``` php:routes.php
Route::get('/{user_id}', 'UserController@show');
Route::get('/{user_id}/edit', 'UserController@edit');
Route::get('/{user_id}/hoge', 'UserController@hoge');
Route::get('/{user_id}/fuga', 'UserController@fuga');
```

ユーザーが存在しなければ例外とします。
必然的にUserクラスは1つしか存在してはいけないので、ServiceProviderでsingletonにします。

``` php:AppServiceProvider.php
public function boot() {
    $this->app->singleton(User::class, function() {
        return (app()->make(UserService::class))
            ->findUser();
    });
}
```

``` php:UserService.php
public function findUser()
{
    $user = User::find(request()->route()->parameter('user_id'));
    if (is_null($user)) {
        throw new NotFoundException('ユーザーが見つかりません');
    }
    return $user;
}
```

これでどのクラスからでも`app()->make(User::class)`でユーザー情報が取得できるようになりました。
なお、あくまで例としてUserクラスを挙げていますが、Laravelでは認証済みユーザーは`Auth::user()`で取ってこれます。

以下、本題のテストのお話です。

単にリクエストをテストするだけなら簡単です。

``` php:Feature/UserTest.php
/**
 * @test
 */
public function ユーザーがいなければ404になること()
{
    $response = $this->get('/should_404');
    $response->assertStatus(404);
}
```

では`findUser`を単体テストするにはどうすれば良いでしょうか。
単純にfindUserメソッドを呼ぶと、`request()->route()`の時点で**null**が返ってくるため`->parameter('user_id')`で例外になります。

結論として、事前にRequestを疑似的に再現して対処します。

``` php:Unit/UserTest.php
/**
 * @test
 */
public function 指定されたユーザーがいなければNotFoundExceptionになること()
{
    $this->expectException(NotFoundException::class);
    request()->setRouteResolver(function () {
        return (new Route('POST', '/{user_id}', []))->bind(
            new Request([], [], [], [], [], ['REQUEST_URI' => '/should_not_found'])
        );
    });
    (app()->make(UserService::class))->findUser();
}
```

参考:
[Simulate a http request and parse route parameters in Laravel testcase](https://stackoverflow.com/questions/41461497/simulate-a-http-request-and-parse-route-parameters-in-laravel-testcase)
Dockerコマンド

# Dockerコマンド

よく使いそうなDockerコマンドをメモしておきます。

## 基本的なDockerコマンド

|コマンド|内容|
|:---|:---|
|docker run <イメージ名>|イメージ<イメージ名>を実行する。イメージがなければダウンロードしてくる|
|docker run --name <コンテナ名> <イメージ名>|コンテナに名前<コンテナ名>を付けて実行する|
|docker run -it <イメージ名> bash|イメージ<イメージ名>を実行する。コンテナでbashを起動する|
|docker run -d <イメージ名>|イメージ<イメージ名>をバックグラウンドで実行する|
|docker run -v <パス名1>:<パス名2> <イメージ名>|コンテナホストのパス<パス名1>とコンテナのパス<パス名2>をマウントする|
|docker run -e <環境変数名>=<値> <イメージ名>|環境変数<環境変数名>に値<値>を設定して実行する|
|docker pull <イメージ名>|イメージ<イメージ名>をダウンロードする|
|docker start <コンテナ名>|コンテナ<コンテナ名>を起動する|
|docker start -i <コンテナ名>|コンテナ<コンテナ名>のSTDINに接続して起動する|
|docker stop <コンテナ名>|コンテナ<コンテナ名>を停止する|
|docker attach --sig-proxy=false <コンテナ名>|バックグラウンドで実行しているコンテナ<コンテナ名>に接続する。--sig-proxy=falseを付けるとターミナルでCtrl+Cが有効になる|
|docker exec -it <コンテナ名> bash|コンテナ<コンテナ名>を別ターミナルで起動する|
|docker commit <コンテナ名> <タグ名>|コンテナ<コンテナ名>にタグ<タグ名>を付けて保存する|
|docker rm <コンテナ名>|コンテナ<コンテナ名>を削除する|
|docker rmi <イメージ名>|イメージ<イメージ名>を削除する|
|docker logs <コンテナ名>|コンテナ<コンテナ名>のログを表示する|
|docker ps|実行中のコンテナ一覧を表示する|
|docker ps -a|停止中を含めたコンテナ一覧を表示する|

## ネットワーク関連のDockerコマンド

|コマンド|内容|
|:---|:---|
|docker network ls|ネットワーク一覧を表示する|
|docker network create <ネットワーク名>|ネットワーク<ネットワーク名>を作成する|
|docker run --network <ネットワーク名> <イメージ名>|イメージ<イメージ名>をネットワーク<ネットワーク名>で実行する|
|docker run -d -p 8080:80 <イメージ名>|イメージ<イメージ名>をバックグラウンドで実行する。コンテナ外部から8080ポートに接続すると、コンテナの80ポートにつながる|
|docker network rm <ネットワーク名>|ネットワーク<ネットワーク名>を削除する
|docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <コンテナ名>|実行中のコンテナ<コンテナ名>のIPアドレスを取得する|

## Dockerfile関連のDockerコマンド

|コマンド|内容|
|:---|:---|
|docker build --tag <タグ名> .|カレントディレクトリにタグ<タグ名>を付けてイメージを作成する|
|docker build --tag <タグ名> -f <ファイル名> .|Dockerファイル<ファイル名>でイメージを作成する|

## Docker Hub関連のDockerコマンド

[Docker Hub](https://hub.docker.com/)

|コマンド|内容|
|:---|:---|
|docker login|Docker Hubのアカウントでログインする|
|docker tag <イメージ名> <タグ名>|イメージ<イメージ名>にタグ<タグ名>を付ける|
|docker push <タグ名>|タグ<タグ名>のイメージをアップロードする|
Ruby on Rails チュートリアル 3章のguardがエラーで失敗する

※ 修正完了しているようです。

# 症状
Cloud9を利用して Ruby on Railsチュートリアル [3.6.2 Guardによるテストの自動化](https://railstutorial.jp/chapters/static_pages?version=5.1#sec-guard) を進めていましたが、`bundle exec guard`を実行したところ以下のようなエラーで失敗します。

```terminal
/home/ec2-user/.rvm/gems/ruby-2.6.3/gems/guard-2.13.0/lib/guard/jobs/pry_wrapper.rb:131:in `_setup': undefined method `file=' for #<Pry::History:0x00000000028ee2f0>
Did you mean?  filter (NoMethodError)
        from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/guard-2.13.0/lib/guard/jobs/pry_wrapper.rb:68:in `initialize'
        from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/guard-2.13.0/lib/guard/interactor.rb:15:in `new'
        from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/guard-2.13.0/lib/guard/interactor.rb:15:in `initialize'
        from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/guard-2.13.0/lib/guard.rb:67:in `new'
        from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/guard-2.13.0/lib/guard.rb:67:in `setup'
        from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/guard-2.13.0/lib/guard/commander.rb:32:in `start'
        from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/guard-2.13.0/lib/guard/cli/environments/valid.rb:16:in `start_guard'
        from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/guard-2.13.0/lib/guard/cli.rb:122:in `start'
        from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
        from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
        from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
        from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/thor-1.0.1/lib/thor/base.rb:485:in `start'
        from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/guard-2.13.0/lib/guard/aruba_adapter.rb:32:in `execute'
        from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/guard-2.13.0/lib/guard/aruba_adapter.rb:19:in `execute!'
        from /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/guard-2.13.0/bin/_guard-core:11:in `<main>'
```
ふむふむ・・・ライブラリ自体からエラーが出てるので、バージョン差異な匂いがプンプンするぜ？

# 解決方法
Gemfileのguardのバージョンを最新 (2.16.2) にして `bundle update` `bundle install --without production` としたところ無事動きました。

```ruby:Gemfile
group :test do
  gem 'rails-controller-testing', '1.0.2'
  gem 'minitest',                 '5.10.3'
  gem 'minitest-reporters',       '1.1.14'
  gem 'guard',                    '2.16.2'  # これ
  gem 'guard-minitest',           '2.4.4'
end
```

Twitterにて公式に報告あげておきました。
初心者には結構厳しいバグですね(´･ω･`)
【Java】「final変数」と「不変オブジェクト」の違い

どーも、ふぎとです。
今回はfinal変数と不変オブジェクトについて
まとめてみました。

##final変数
final変数とは、final修飾子を指定した変数のこと。
その性質は「変更不可・読み込み専用」と呼ばれる
が、厳密には「**再代入不可の変数**」。

~~~ruby:
    final int i = 3;
    i = 5; //再代入によるコンパイルエラー
~~~
上では、基本型（int型）変数iにfinalを指定している。
基本型変数は、変数の値に「値そのもの」が保持される
変数だ（詳細は『[基本型変数の代入と参照型変数の代入
の違い](https://qiita.com/FugitHora812/items/a0e2f49331be6f35b8a0)』を参照）。そのため、「値そのもの」を入れ替
える再代入はコンパイルエラーになる。つまり、基本型
変数に限って言えば、final変数は「変更不可」である
ように見える。
話をややこしくしているのは、final指定の参照型変数だ。

~~~ruby:
    final StringBuilder sb = new StringBuilder("123");
    sb = new StringBuilder("456"); //コンパイルエラー

    final StringBuilder sb2 = new StringBuiler("789");
    sb.append("★");         //コンパイルエラーにならない！
    System.out.println(sb2); //"789★"が出力される
~~~
上の例では、参照型変数sbとsb2に対して操作をしている。
ここで、final変数の性質を「変更不可」と理解していると、
sbへの操作がエラーになり、sb2への操作がそうならない事
の意味がわからなくなる。
ここで、参照型変数が保持している値を思い出してみると、
これは「オブジェクトへの参照」であった。つまり、sbや
sb2が持っているのは、"123"や"789"という「値そのもの」
ではない。彼ら（？）が持っているのは、あくまでも「"1
23(456)"という状態となったオブジェクトへの参照」なのだ。
この仕組みと、final変数の厳密な定義「再代入不可」とを考
えに入れると、上の例を理解することができる。すなわち、
sbに対する "sb = new StringBuilder("456")"という操作、これ
は「**新たな参照の値をsbに再代入する**」という操作だ。よっ
て、final変数の性質により、コンパイルエラーがでる。一方、
"sb2.append("★")" の操作、これは「**"789"という状態を持つ
オブジェクトの状態を"789★"という状態に変える**」という操
作となる。要するに、sb2への「オブジェクトへの参照値」の
再代入は起こっていない。そのためエラーとならないのである。

##不変オブジェクト
final変数が「再代入不可」の性質を持つ一方で、不変オブジェ
クトは「オブジェクトの状態変更」をも禁じている。つまり、
上の例でいうところの "sb.append("★")" の操作もできないのが
不変オブジェクトなのだ。

##まとめ
**・final変数は「再代入不可」の性質を持つ
・参照型変数をfinal指定すると、「参照先の変更」は
　できないが「最初に参照したオブジェクトの状態変
　更」はできる
・「最初に参照したオブジェクトの状態変更」もできない
　オブジェクトを「不変オブジェクト」と呼ぶ**

...
では今回はこの辺で。ふぎとでした。

(P.S.)記事の内容への指摘などあれば
　　　遠慮なくお知らせくださいm(__)m
Linux で ISO ファイル(CDイメージ)を作成する方法

# Linux で ISO ファイル(CDイメージ)を作成する方法

## ファイルやフォルダからisoファイルを作成する場合

```
# mkisofs -r -J -V <ラベル> -o <isoファイル名> <ディレクトリ名>
```

(例)# mkisofs -r -J -V "MyCD" -o cd_image.iso /home/hoge/・CD/DVDドライブからISOファイルを作成する場合


## CD/DVDドライブからISOファイルを作成する場合

```
# dd if=/dev/cdrom of=<isoファイル名>
```

(例)# dd if=/dev/cdrom of=cd_image.isoまたは

または

```
# mkisofs -r -J -o -V <ラベル> -o <isoファイル名> <マウント場所>
```

(例)# mkisofs -r -J -V "MyCD" -o cd_image.iso /media/cdrom
Netbackup あんちょこ(NetBackup 7.7.3)

# Netbackup あんちょこ(NetBackup 7.7.3)

## ●ストレージユニットの追加

```
bpstuadd -label <storage unit name> -path <path> -dt <disk type> -mfs 524287 -M <master hostname>
```

## ●Retention Period設定

```
bpretlevel -U
bpretlevel -r <level> <number> <y:year,m:month,d:day>
```

## ●ポリシー追加

```
bppolicynew <policy name> -M <master hostname>
```

## ●ポリシー設定

### 通常

```
bpplinfo <policy name> -modify -M <master hostname> -active -pt Standard -residence <storage unit name>
```

### カタログバックアップ

```
bpplinfo <policy name> -modify -M <master hostname> -active -pt NBU-Catalog -residence <storage unit name>
```

## ●ポリシー確認

```
bppllist
bpplinfo <policy name> -U
```

## ●スケジュール追加

```
bpplsched <policy name> -M <master hostname> -add <schedule name> -st FULL -freq <backup 間隔> -rl <retention level>
```

## ●スケジュール確認

```
bpplsched <policy name> -L
```

## ●バックアップ元登録

```
bpplinclude <policy name> -add <backup path>
```

## ●バックアップ元登録確認

```
bpplinclude <policy name> -L
```

## ●Client確認

```
bpplclients <policy name> -M <master hostname> -add <client hostname> <host type>
```

## ●Client確認

```
bpplclients <policy name> -U
```

## ●CatalogバックアップDisaster Recovery設定

```
bpplcatdrinfo <policy name> -set -p <path>
```

## ●CatalogバックアップDisaster Recovery設定確認

```
bpplcatdrinfo <policy name> -L
```

## ●バックアップ

```
bpbackup -p <policy name> -s <schedule name> -S <master hostname> -L <log path> -i -w
```

## ●リストア

```
bprestore -p <policy name> -w -L <log path>  -S <master hostname> -r -f <restore list filename>
```

※-rオプションは、rawデバイスの場合

## ●カタログリストア

```
bprecover -wizard
```

## ●バックアップ保持期間確認

```
bpimagelist -L -d <バックアップ日付:yyyy/mm/dd>
```

## ●バックアップジョブレポート

```
bpdbjobs -report
```

## ●netbackupログディレクトリ作成

```
mklogdir
```

## ●netbackup停止

```
bp.kill_all
```

## ●netbackup起動

```
bp.start_all
```

## ●プロセス確認

```
bpps -x
```

## ●管理コンソール起動

```
jnbSA
```

## ●diskエラー確認

```
bperror -disk
```

## ●netbackupエラー確認

```
bperror -all -U
```
備忘録：/etc/shadow を直接変更する

Linux NAS 箱などの /etc/shadow に保存されているパスワードがわからくなったときの手段。

1. HDD を取り外して Linux (PC) に接続 (mount)
3. **python3** でハッシュを作る
4. mount したパーティションにある /etc/shadow を編集

python3 によるパスワード ハッシュ生成

```python
$ python3
>>> import crypt
>>> crypt.crypt('<password>', crypt.mksalt())
'$.$..$...'
```
kshショートカット

# kshショートカット

## コマンド履歴

bashなら矢印キーの↑と↓でコマンド履歴をたどれるんだけど、kshはダメ。

ESCキーを押す。Jキーを押す。

戻る場合はKキーです。
これはviと同じですね。viのカーソル移動は↓がjで、↑がk。bashのコマンド履歴における矢印キーと同じ方向になります。

## パス補完

bashならパスを途中まで入力し、TABキーを押せば自動的に補完できるけど、kshはダメ。

### 1.AIXの場合

AIXの場合は、[ESC]キー > [\]キーの順でキーボードを押下することで、PATHの補完機能を利用することが出来る。

### 2.HP-UXの場合

HP-UXの場合は、[ESC]キー ×2でPATHの補完機能を利用することが出来る。
rails on docker がAWS S3 で AccessDeniedが出ることのデバッグ

今までVagrantで動かしていた、Railsをdockerに移したところ、何故かs3にホストしてある画像が取得出来なくなったのでその確認をしました。

## 1. dockerにaws-cliをインストールしてみる

* ruby:2.6.5-slim-stretch イメージをベースにしていたことがありそもそもpythonが入っていなかったので色々とインストールしてみた

```
> docker-compose exec web bash
# curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
# python get-pip.py 
bash: python: command not found → インストールされていなかったので、apt install l-y pythonでまずpythonを導入
# apt install -y python
# python get-pip.py
# pip install awscli
```

## 2. s3の一覧を取得する

```
# aws s3 ls s3://[[バケットのURL]]

An error occurred (RequestTimeTooSkewed) when calling the ListObjectsV2 operation: The difference between the request ti
me and the current time is too large.
```

## 3. RequestTimeTooSkewed って？


 https://qiita.com/sadakan5/items/4c0a394fd1d6be34efb2
を参照。

サーバーとAWSの時間がずれているとエラーになるとのことで　date で時間を確認してみた

```
# date
Wed Mar 25 23:39:24 UTC 2020
```

ちなみに、EC2にホストしているサーバーで実行すると。。

```
# date
Thu Mar 26 23:11:39 UTC 2020
```

確かにずれています。。

ホストがずれているの？と見てみてもそんなことはないです。。
（ホストは日本時刻）

```
> date
2020年3月27日 8:12:11
```

システムを休止状態（Hybernate)にするとずれることがあると
https://docs.docker.com/docker-for-mac/troubleshoot/#known-issues

で、こうすればいいみたい

まずは、HostとGuestのタイムゾーンを合わせます。（タイムゾーンを無視して時間だけを同期してしまうので）

powershellだと
ホストの方をUTCにして再度時間を合わせてみる

```
> Get-Timezone
Id : Tokyo Standard Time 
...
> Set-Timezone -Id "UTC"
```

その後、同期するコマンドを実行します

```
(ホスト側で）
> docker run --rm --privileged alpine hwclock -s
> docker-compose exec web bash
# date
Fri Mar 27 08:28:29 UTC　2020
```

でなおった！

これ、順番逆にすると時計がずれたままで、直らないので要注意

ホスト側のタイムゾーンをTokyoに戻します

```
> Get-Timezone
Id : 
...
> Set-Timezone -Id "Tokyo Standard Time"
```
HP Service guardあんちょこ(HP-UX11iv3)

# HP Service guardあんちょこ(HP-UX11iv3)

### クラスタの起動

・両系起動する

```
# cmruncl -v
```

・片系起動する

```
# cmrunnode -v
```

### クラスタの状態の確認

```
# cmviewcl
```

### パッケージをクラスターに組み込む

```
# cmapplyconf
```

### パッケージ構成ファイルの整合性を検証

```
# cmcheckconf
```

### テンプレート作成

```
# cmmakepkg
```

### パッケージの起動

```
# cmrunpkg -v package1 -n node1
```

### 自動でのフェールオーバ/フェールバック有効化設定

```
# cmmodpkg -v -e パッケージ名
```

### パッケージの停止

```
# cmhaltpkg -v パッケージ名 -n ノード名
```

### クラスタの停止

・両系停止する

```
# cmhaltcl -v
```
※全パッケージを停止しないとクラスタは停止できない

・片系停止する

```
# cmhaltnode -v
```

### ログ

#### クラスタ関連

`/var/log/messages`

#### パッケージ関連

`/usr/local/cmcluster/log/`

設定次第であるが基本はこのあたり。
Wijmo  

Wijmo
軽量／高速、タッチファーストで保守性の高いコントロールにより業務アプリケーション開発をサポートする新世代のJavaScriptライブラリ

Wijmoを選ぶ理由
Wijmoは業務アプリケーション開発での利用に最適化されています。導入による開発工数の削減効果はもちろんのこと、運用開始後の保守性にも優れたJavaScriptライブラリです。

また、パフォーマンスを意識した設計により高速でありながら極めて小さいモジュールサイズを実現しており、アプリケーションのオーバーヘッドを増加させることもありません。

TypeScriptでの開発や、Angular、React、Vueをはじめとする主要JavaScriptフレームワークでの利用など、最先端テクノロジーも幅広くサポートしており、どのようなアプリケーションにも組み込みやすいコントロールセットです。

高速・軽量
たとえば人気の高機能データグリッド「FlexGrid」のモジュールサイズはわずか150KB。ほかにもすべてのコントロールがファイルサイズとパフォーマンスの観点から最適化されています。

親しみのあるUIとタッチ対応
チャートやデータグリッドなど、すべてのコントロールがタッチファーストで設計されています。また、Excelライクなフィルタ機能をはじめとして、親しみのあるUIを数多く備えています。

TypeScriptベース
WijmoはTypeScriptでビルドされており、オブジェクト指向開発、C#ライクなコーディング、静的型付け等をTypeScriptを通して開発することができます。

高い柔軟性と拡張性
WijmoのAPIは可読性に優れ、少ない学習コストで修得が可能です。また、各コントロールは多くの拡張ポイントとシンプルなコア部分から構成されており、高い拡張性を実現しています。

フレームワークへの対応
Wijmoのコントロールは、主要なJavaScriptフレームワーク上でお使いいただけるように設計されています。AngularやReact、Vueなどでの利用に完全対応しています。


ECMAScript 6準拠
WijmoはECMAScript 6に準拠しています。インテリセンスや列挙体の利用、プロパティの有効値確認などが可能になっており、フロンエンド開発の生産性向上が期待できます。

主要収録コントロールと機能

FlexGrid

大量のデータを効率的に処理し高速に表示するデータグリッドコントロール。表示だけでなくソートやフィルタ、グループ化機能を使ったデータ分析も可能です。

FlexChart

データインタラクティブでカスタマイズ性に優れたチャートコントロール。80以上のチャートを使用して訴求力の高いデータ表示を実現できます。

Input

日付入力や数値入力、マルチセレクトやオートコンプリートなど業務アプリケーションに欠かせない入力機能を幅広くカバーする入力コントロール。

Gauge

線形・円形ゲージやブレッドグラフを使用して、ひとつのデータを分かりやすく可視化するゲージコントロール。

TreeView
相互に関連するデータを分かりやすく階層表示できるツリービューコントロール。各階層にはチェックボックスや画像を表示することも可能です。

MultiRow

1レコードを複数行に表示できるグリッドコントロールです。多くのフィールドを有するデータレコードも横スクロールすることなく1画面で表示可能です。

FlexSheet

Excelライクなスプレッドシートを実現します。数式や固定行／列の利用、クライアントサイドでのExcelファイルの入出力も可能です。

OLAP

Excelのようなピボットテーブルを実現します。サーバーサイドとの依存関係はなく、クライアントサイドで数千行の集計をミリ秒単位で実行します。

FinancialChart

株価トレンドの視覚化に特化したチャートコントロールです。トレンドライン、フィルター、レンジセレクター、アノテーションでの分析に対応しています。

ReportViewer

帳票の表示、印刷、エクスポートを実現するコントロールです。フルスクリーンや検索、見出しなどの高度な機能にも対応しています。

Wijmoデザイナ

データグリッドやチャートなど、Wijmoの各コントロールのデザインやプロパティをGUIで設定できるデザイナです。コーディングレスで効率的な開発を実現できます。開発環境に合わせてオンライン版とVisual Studio Code拡張機能版（Angular開発向け）のご利用が可能です。
MySQL テーブルのカラムを出力しようとした時にエラーが出た話

# 目的

- laravelのマイグレーションファイルを使用してとあるテーブルにカラム追加したものを確認しようとしたらエラーが発生し解決した話をまとめる

# 実施環境

- ハードウェア環境

| 項目 | 情報 | 備考 | 
| --- | --- | --- |
| OS | macOS Catalina(10.15.3) ||
| ハードウェア | MacBook  Air (11-inch ,2012) ||
| プロセッサ | 1.7 GHz デュアルコアIntel Core i5 ||
| メモリ | 8 GB 1600 MHz DDR3 ||
| グラフィックス | Intel HD Graphics 4000 1536 MB ||

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravel バージョン | 7.0.8 | commposerを用いて導入 |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いて導入 |

# エラー内容

- MySQLのコマンドラインにて下記のコマンドを実行したとこ「ERROR 1046 (3D000): No database selected」が出力された。

    ```mysql
    mysql> show columns from テーブル名;
    ```

# 原因

- エラーメッセージにもある様にデータベース名を指定せずにテーブル名のみを指定したためエラーが発生している。

# 解決方法

1. コマンド`how columns`の実行時にデータベース名も指定して実行する。
1. MySQLのコマンドラインで`how columns`を実行する際の例を下記に記載する。

    ```mysql
    mysql> how columns from データベース名.テーブル名
Thymeleafで関数の引数に変数を渡す方法

謎にハマったのでメモ

## 環境

* Thymeleaf 3.0.11
* Spring Boot 2.2.5

## 実装方法
  
例）Thymeleaf内にて、Dateクラスにあるformatメソッドの引数に変数式を渡したい場合

```java:HogeController.java
    model.addAttribute(mails);
    model.addAttribute(new Date());
```

```html:index.html
  <tr th:each="mail : ${mails}">
    <td th:text="${mail.subject}">件名</td>
    <td th:text="${mail.category.}">通常</td>
    <td th:text="${Date.format(mail.sendDate)}">2020/03/20</td>
    <!-- ${Date.format(${mail.sendDate})} などでは構文エラーとなる-->
  </tr>
```
【BigQuery】TIMESTAMP()orFORMAT_TIMESTAMP()でUTCからJSTへの変換

# 背景

#### BigQueryについて
[インタラクティブ クエリの実行](https://cloud.google.com/bigquery/docs/running-queries#queries)する時、ConsoleでBigQueryウェブUIを使用し、構文エラーなどをその場ですぐ検知されるのはメリットの一つである。

#### 発生された問題
- BigQueryで*JST形式*の**TIMESTAMP型**のカラムにデータが格納されており、それらのデータを関数計算して、別のテーブルカラムとして作成すると、デフォルトで*UTC形式*に変換されて新しいテーブルに挿入されてしまう場合。

- FORMAT_TIMESTAMP( )を用いて、BigQueryウェブUIに叩いたら、構文エラーはなかったが、クリエ結果は無効のvalueが返された。

以下のようにクエリしようとしてました。
<img width="629" alt="スクリーンショット 2020-03-27 午前9.23.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443595/710bdf95-1978-e592-7e18-81491c5e576d.png">
実行してみると、このようになってます。
<img width="518" alt="スクリーンショット 2020-03-27 午前9.25.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443595/05881ed4-aab1-b16c-aedc-26312f8fb413.png">


#### 目標
**元テーブルのデータをJSTに変換し、最新の日付データ(最大値)を比較してDATEとして抽出すること。**


### FORMAT_TIMESTAMP( )

#### 説明
資料リスト
1. [標準SQL関数と演算子](https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#timestamp_trunc)
2. [FORMAT_TIMESTAMP( )](https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#format_timestamp)

_タイムスタンプを指定された format_string に従ってフォーマットします。_

```sh
FORMAT_TIMESTAMP(format_string, timestamp[, time_zone])
```
>戻りデータの型
>STRING

ここまで、調べてきたら、エラーの原因は明らかになったようですね。
`MAX(STRING)`としてしまったのか？！まさか！！！
それでは、string_expressionからtimestamp_expressionへ変換しましょう。

### TIMESTAMP( )

#### 説明
資料リスト
1. [標準SQL関数と演算子](https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#timestamp_trunc)
2. [TIMESTAMP( )](https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#timestamp)

```sh
TIMESTAMP(
  string_expression[, timezone] |
  date_expression[, timezone] |
  datetime_expression[, timezone]
)
```
なるほど、TIMESTAMP( )を使えばと良さそうですね。
早速、BigQueryウェブUIに叩いてみましょう。
<img width="696" alt="スクリーンショット 2020-03-27 午前9.40.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443595/87b15d01-c652-2f65-d6f9-345a2b5302f1.png">
エラーだった`2020-01-29 00:00:00 UTC+9`はうまくJSTに変換されて、DATE型の`2020-01-28`として抽出されました。
<img width="179" alt="スクリーンショット 2020-03-27 午前9.44.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443595/288412b6-5020-79ab-2d2c-d409766ac294.png">

## まとめの一言
複数の関数、演算子を組み合わせてクエリする時や型変換を頻繁に行われる時など、頭が混乱になってしまうのが自分には普通？日常的？なことで、一個一個の関数を整理するかまた誰かに確認していただくかはそのようなミスを抑えられる解決法ではないでしょうか。
【Python】多重分類問題のTraining, Validation, Testフォルダーを簡単に作る方法

#はじめに

多重分類問題(Multi Classes Classification）において、自前の画像データをTraining, Validation, Testに分ける方法を紹介します。

#やりたいこと

自分が持っている画像データが下記の図のようにinputフォルダーにあるとします。

<img width="300", alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/bf6cf0ab-9452-272d-bfe8-8f0981b9182e.png">
その画像データを下記の図のようにtraining, Validation, Testフォルダーに分けたいと思います。
<img width="300", alt="image.png", src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/7c1eae06-3cfd-8b31-7f0c-1ba898b1315b.png">

#インストール方法
`pip install split-folders`

#使い方
Pythonプログラムを作成します。`split-folders`モジュールをインポートして、下記のコードを実行します。

```Python
import split_folders

# Split with a ratio.
# To only split into training and validation set, set a tuple to `ratio`, i.e, `(.8, .2)`.
split_folders.ratio('input_folder', output="output", seed=1337, ratio=(.8, .1, .1)) # default values


```

#関連資料
1. [Split Folders]<https://github.com/jfilter/split-folders>
create-react-appを使わない構成でGAEにデプロイする

create-react-appを使わずにインストールするための記事はたくさんありましたが、デプロイを行う方法が見当たらなかったため、実際にやってみました。
create-react-appを使わない意図としましては[脱create-react-app](https://qiita.com/ohs30359-nobuhara/items/bdc06b2db1bef7af2439)がわかりやすいかと思います。

# 参考
今回は下記を参考に環境構築およびインストールを行いました

[作りながら学ぶ React 入門](https://github.com/yuumi3/react_book/blob/master/docs/install_mac.md)
[Cloud BuildでReactアプリをGAEにデプロイする](https://code-log.hatenablog.com/entry/2019/12/03/210055)  ※今回はCloud Buildは使用していません。

# 構成
[作りながら学ぶ React 入門](https://github.com/yuumi3/react_book/blob/master/docs/install_mac.md)に倣った構成とモジュールになっています

```
├── public
│   ├── js
│   │    └── app.js // npm run buildで生成
│   └── index.html
├── src
│   └── index.js
├── app.yaml
├── package-lock.json
├── package.json
└── webpack.config.js
```

# インストール
[「作りながら学ぶ React 入門」 サポートページ](https://github.com/yuumi3/react_book/blob/master/docs/install_mac.md)を参考にインストールしてください

```webpack.config.js
module.exports = {
  entry: {
    app: "./src/index.js"
  },
  output: {
    path: __dirname + '/public/js',
    filename: "[name].js"
  },
    devServer: {
    contentBase: __dirname + '/public',
    port: 8080,
    publicPath: '/js/'
  },
  devtool: "eval-source-map",
  mode: 'development',
  module: {
    rules: [{
      test: /\.js$/,
      enforce: "pre",
      exclude: /node_modules/,
      loader: "eslint-loader"
    }, {
      test: /\.css$/,
      loader: ["style-loader","css-loader"]
    }, {
      test: /\.js$/,
      exclude: /node_modules/,
      loader: 'babel-loader'
     }]
  }
};
```

インストールしたら`npm start`で動作確認

# GAEにデプロイを行います

[Cloud BuildでReactアプリをGAEにデプロイする](https://code-log.hatenablog.com/entry/2019/12/03/210055)を参考にデプロイを行います

```app.yaml
service: front // 定義しない場合はdefaultにデプロイされる(はず)
runtime: nodejs10 //node.jsはローカルでインストールしなくても大丈夫です

handlers:
- url: /
  static_files: public/index.html
  upload: public/index.html
  secure: always
- url: /
  static_dir: public
```

あとは[Google Cloud SDK](https://cloud.google.com/sdk/install?hl=ja)をインストールして下記コードでデプロイしてください

```console
$ npm run build // ビルドコマンド
$ gcloud app deploy
```

以上
macにvirtualbox＋alpine+docker+redmineの作業メモ

## virtualboxのinstall

oracleの[ページ](https://www.virtualbox.org/wiki/Downloads)からダウンロードしてinstall
ついで、extention packをダウンロード
（これはinstall後に設定から読み込む）

## alpineのVM

[ここ](https://alpinelinux.org/downloads/)からVIRTUALのやつのisoを落とす
VMを新規作成して、isoをdiskに設定して起動
`# setup-alpine`
でdiskにインストール
⭐️キーボード選択しない

## docker
[ここ](https://kmor1.blogspot.com/2018/11/alpine-linux-docker.html)を参考にした
alpineにログイン
→キー入力がいまいちなのでVM直接早めてterminalからssh

# うまくいかないので、Windowsでやる
google chromeで位置情報を変更

#状況
chromeの検索結果を変更したくて位置情報を変えたのに、反映されなかったときの対処法。

#方法
1.右クリックして検証 ⇒ ウィンドウ右上の縦三つポチ ⇒ more tools ⇒ Sensors ⇒ Geolocationを変える
普通は↑で位置情報の変更が反映されるらしい

2.ブラウザ右上の縦三つポチ ⇒ 設定 ⇒ プライバシーとセキュリティ ⇒ サイトの設定 ⇒ 位置情報:変更
3.アドレスバー左の鍵マーク ⇒ 位置情報:変更

2と3が連動しているのかしていないのか謎ですが、二つを交互にいじっていたら突然Geolocationの変更が効くようになりました。
Firebaseのルール設定

Firebase firestoreでのルール設定について[備忘録]

個人開発アプリにてFirebaseを利用しているのですが、認証機能をつけずに運用していたところ、急にデータを取れなくなったのでメモ。

新規firebaseProject作成後、ルール設定を(誰でも閲覧可能)にしていたところ、1,2ヶ月が過ぎた段階で以下の警告がでて動かなくなった。
<img width="410" alt="スクリーンショット 2020-03-27 9.35.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599747/29d0cd90-f264-f85e-d220-6fb66cf8d395.png">
ちなみにその時のセキュリティソースが以下

```
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // This rule allows anyone on the internet to view, edit, and delete
    // all data in your Firestore database. It is useful for getting
    // started, but it is configured to expire after 30 days because it
    // leaves your app open to attackers. At that time, all client
    // requests to your Firestore database will be denied.
    //
    // Make sure to write security rules for your app before that time, or else
    // your app will lose access to your Firestore database
    match /{document=**} {
      allow read, write: if request.time < timestamp.date(2020, 3, 21);
    }
  }
}

```
これをいかに変更して、認証機能をつけることで解決。ちなみに匿名の認証機能を採用しました。(規約変更しないとなあ、、、)

```
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth.uid != null;
    }
  }
}
```

より良い解決方法ありましたら、ご教授いただけると幸いです。m(_ _)m
Linuxとは

#OS
OSとは、Operating Systemの略で、システム全体を管理するソフトウェアのこと。
みんながPCとして利用しているWindowsやMacなどもOS。

#Linux
プログラミングではLinuxというOSがよく用いられる。LinuxはWindowsやMacとは異なり、厳密にはOSの中核部分(Linuxカーネル)を指す。

実用的なOSとして動かすためには、カーネルに加え、画面表示・通信・ファイル管理など各種機能を担うソフトウェアを組み合わせる必要がある。
車に例えるならカーネルはエンジン。エンジンは車の中核部分だが、車が走行するためにはブレーキ・アクセル・ハンドルなどの部品が必要になる。

Linuxカーネルとソフトウェアを組み合わせて実際に機能するOSを作り上げるためには、Linuxカーネル自体やOSに関する深い知識が必要となるため、現実的ではない。

#Linuxディストリビューション
そこで、一般のユーザーや開発者が手軽にLinuxを利用できるよう、Linuxカーネルと各種ソフトウェアをいい感じに組み合わせて配布されているものがある。これが「Linuxディストリビューション」。一般的には色々なLinuxディストリビューションをまとめて「Linux」と呼ぶことが多い。

サーバー向けに安定性を重視したもの、古いPCでも快適に利用できるものなど、Linuxディストリビューションには様々な用途に最適化されたものが存在している。

#Linuxを使う理由
プログラミングのためにLinuxを使う理由は、Linuxにはプログラミング用のソフトウェアが豊富に存在し、便利だから。
さらに、 Linux は GNU General Public Licence (グヌー・ジェネラル・パブリック・ライセンス、GPL) というライセンスの下で提供されているため、基本的に無料で利用できる。
これは膨大な数の PC を用意することになるサーバー運営において、大きくコストを下げることができるというメリットがある。
そのためWebプログラミングの世界では、広くLinuxが利用されている。
単体テストを記述できる条件(PHP) 

# はじめに

PHPで書いたプログラムの単体テスト(自動テスト)は通常PHPUnitで実装することになります。

その際にテスト対象となるPHPのクラスはどのように書いてもテストできるわけではなく、一定の条件を満たす必要があります。

主に注意すべきは3点です。

- コンストラクタ
- ローカル変数の扱い
- 静的関数、プロパティの扱い

基本的にはPHPUnitが提供しているMockに置き換えられるかどうかというところが焦点となります。


## コンストラクタで複雑な処理を行わない

PHPに限らず大抵のオブジェクト指向のプログラミング言語でもそうなのですが、コンストラクタは他のメソッドよりも制御が難しく、自動テストを記述するのも難しいです。

コンストラクタ内で複雑な処理を実装してしまうと、引数に与えるオブジェクトを除いてMock化することもできないため、テストが記述不能になる可能性が高くなります。

コンストラクタの単体テストが記述できないようなclassの場合、ReflectionClass::newInstanceWithoutConstructor()でコンストラクタを迂回してテスト用のインスタンスを作るといった回避策を取ることもあるでしょう。ただしPHP > 5.4以上ですが。


## メソッド内のローカルでnewしない

テスト対象のメソッド内のローカル変数として、外部のクラスのインスタンスを生成していたりすると、そのメソッドはテストを実装不能になります。なぜならば他のクラスのインスタンスが生成された環境であるため、そのクラスのプログラムも動作してしまい、単体テストでなくなってしまうからです。（それは結合テストです）

これは直接newで生成する場合以外も、SomeDao::getInstance()等の静的メソッドでインスタンスを取ってくるケースでも同じことになります。

この問題の回避策としては、外部クラスのインスタンスは一旦全てプロパティに代入し、プロパティ越しにアクセスすることでローカル変数でなくしてしまうことです。

するとプロパティに設定されるはずの外部クラスのインスタンスはPHPUnitが提供するMockに置き換えることができるので、単体テストとして記述できるようになります。


## 静的関数、プロパティの扱い

静的関数のテストは実質的にそのクラスのインスタンスが存在しない環境(そのメソッド自体でインスタンスを作っている場合を除く)となりますが、基本的なアプローチはこれまでに書いたことと同じです。

ただし、静的関数ではそのクラスのインスタンス別の環境とはならず、システム全体で単一の環境となる(あるいは状態を持たない環境となる)ので、注意して実装する必要はあるでしょう。

以上
ES6(JavaScript)の基礎を押さえる

#ES6とは

ES6はJavaScriptの新しいバージョン。
現在は多くのブラウザが対応していないため、ES6で書いたコードを動かすためにはES5(1つ前のバージョン)への変換が必要になる。
この変更を"トランスパイル"と呼び、Babelというツールを利用してトランスパイルを行う。

#letとconst

letで変数を、constで定数を定義できる。
letは再代入が可能であるのに対し、constは再代入が不可能。

letでの変数宣言

```javascript:
let name = 'Jonh';
console.log(name); // => Jonh

name = 'Kate'; // 再代入する
console.log(name); // => Kate
```

constでの変数宣言

```javascript:
const name = 'Jonh';
console.log(name); // => Jonh

name = 'Kate'; // 再代入するとエラーになる
```

#テンプレートリテラル

バッククオートで文字列を囲むと、`${}`で文字列内に変数展開ができ、改行も反映できる。

```javascript:
const name = 'Jonh';
const age = 21;

console.log(`${name}は${age}歳です`); // => Jonhは21歳です
```

#アロー関数

関数とはいくつかの処理をまとめたもの。
アロー関数は関数の中でも無名関数の省略形で、従来より簡潔な記述で関数を定義できる。

通常の関数

```javascript:
const a = function(){
//まとめたい処理
};
```

上と同義のアロー関数

```javascript:
const a = () => {
//まとめたい処理
};
```

#Class構文

オブジェクトを生成する際、最初に設計図を用意する必要がある。
この設計図を"クラス"と呼ぶ。
「class クラス名」とすることでクラスを定義することができる。

```javascript:
class User = {
 constructor() {
  this.name = 'Jonh';
 }
} //クラスの定義

const user = new User(); //インスタンスを生成
console.log(user.name); // => Jonh
```
Dockerと仮想マシンの違い

#Dockerとは
Dockerとは軽量な仮想化環境を実現するためのツールです。
Dockerを利用すればOSの内部に独立したアプリケーションの実行環境を構築することができます。この構築環境をコンテナと呼びます。

###コンテナ
コンテナ内のファイルシステムやリソースはベースOSと分離されており、コンテナ内は実行環境として独立しています。
コンテナを利用することで、1つのOS内に複数の実行環境を構築できます。

###イメージ
イメージとはコンテナを生成する元になるものです。同じイメージを使えば、同じ Linux ディストリビューションで同じアプリケーションがインストールされた全く同じ環境を複製することができます。
また、Dockerではイメージを編集し、イメージの機能・内容を継承することもできます。
Dockerイメージを使うことで、従来必要だったプログラミング言語のインストールやフレームワークのインストールといった手間がかからず、パソコンのプログラミング環境を汚すことなく様々なアプリ開発に即・挑戦できるという訳です。

#仮想マシン
仮想マシンとは仮想的にハードウェアを動作させることです。
仮想マシンには大きく分けて「ホスト型」と「ハイパーバイザー型」の２種類あります。

###ホスト型とハイパーバイザー型
ホスト型とは、OSに仮想化ソフトウェアをインストールし、その上で仮想マシンを動かすことです。既存のサーバーを使えるため、手軽に利用できる一方で、ハードウェアにアクセスする際OSを経由しなければいけません。
ハイパーバイザー型とは、ホストOSを使わず直接サーバーにインストールし仮想マシンを動かすことです。ハードウェアのリソースを直接管理できます。

###ホストOSとゲストOS
仮想化・仮想マシンに関連してよく出る用語が「ホストOS」と「ゲストOS」です。
ホストOSは仮想環境の土台となるOSのことで、ゲストOSは仮想マシン上にインストールされたOSのことです。
たとえば、Linuxサーバ上に仮想マシンを作り出しWindowsをインストールしたら、ホストOSはLinuxでゲストOSはWindowsということになります。

#仮想マシンとDockerコンテナの違い
仮想マシンはマシン単位での仮想化であるのに対して、Dockerコンテナはプロセス単位での仮想化となっています。
仮想マシンは自由度が高い一方で、リソースの消費が激しいです。
それに対して、Dockerコンテナは仮想マシンよりも軽量ですが、OSをホストと共有するため自由度は下がります。
SQLの４大命令について

#SQLとは
SQLとはデータベース言語であり、データベースを管理するソフトウェアを操作・制御することが目的です。データベースというのは、集めたデータをプログラムによって整理し、操作できるようにしたものです。データベース言語はデータを管理して、ユーザーが指定した条件に合致するものを見つけ出すためのものです。

#SQLの種類
SQLは、大きく分けて以下の3種類の言語から構成されています。

- データ定義言語(CREATE,DROP,ALTER等)
- データ操作言語(INSERT,UPDATE,DELETE,SELECT)
- データ制御言語(GRANT,REVOKE,SET TRANSACTION,BEGIN,COMMIT,ROLLBACK,SAVEPOINT,LOCK)

今回はデータ操作言語に該当するSQLの４大命令についてまとめてみました。
    
#SQLの４大命令とは

SQLの４大命令とは以下の４種類です。

| 命令       |      　説明 |    文法    |
|:-----------------|------------------:|:------------------:|
| INSERT             |              データを追加する |        INSERT INTO テーブル名 (カラム名1, カラム名2, ...) VALUES (値1, 値2, ...);        |
| SELECT           |            データを取得する |       SELECT カラム名1, カラム名2, ... FROM テーブル名 [WHERE 絞込条件];
       |
| UPGRADE             |              データを更新する |        UPDATE テーブル名 SET カラム名1=値1 [, カラム名2=値2 ...] [WHERE 絞込条件];        |
| DELETE               |                データを削除する |         DELETE FROM テーブル名 [WHERE 絞込条件];
         |


#INSERT
テーブルにデータを追加する

```sql
INSERT INTO テーブル名 (列名1, 列名2, 列名3, ...) VALUES (値1, 値2, )
```

#SELECT
テーブルからデータを取得する

```sql
SELECT 列名... FROM テーブル名 (WHERE 条件式)
```

#UPGRADE
テーブルにデータを追加する

```sql
UPDATE テーブル名 SET 列名=値1, 列名2=値2, ... (WHERE 条件式)
```

※注:WHEREのないUPDATEは全レコードが更新される。

#DELETE
テーブルのデータを削除する

```sql
DELETE FROM テーブル名 (WHERE 条件式)
```

※注:WHEREのないDELETEは全レコードが消去される。
【Unity】簡単なTimer機能の実装したときにやったこと

Unityでタイマー機能をググってみたのだけれどもいまいちピンとくるものがなかったのでひとまずやったことをメモする。

## 事前準備
![](https://cdn-ak.f.st-hatena.com/images/fotolife/f/ferrari458tukapai/20200326/20200326081431.png)

CanvasにTimeオブジェクトを作成してCanvasと紐付けをする。

当初Scoreだけを実装していたのでScoreの値がCanvasに直接くっついている状態だった。

![](https://cdn-ak.f.st-hatena.com/images/fotolife/f/ferrari458tukapai/20200326/20200326081542.png)

スクリプトに新しくTimerスクリプトを作成

仕様は以下のようにした

* 60秒からカウントダウンする。  
* ScoreUIの下に整数部分だけを表示する。  
* カウントが０になったらカウントをストップする。  

## 60秒からカウントダウンする。

まず固定値で1分を設定する。

Updateで使うTime.deltaTimeがInt型だとエラーになってしまうのんでFloat型で60秒を宣言する。

`private float countTime = 60;`

描画するテキストオブジェクトは以下を宣言する。

`public Text timeCount;`

最初は単純にカウントダウンができるかを確認したかったのでUpdateをこんな感じで実装してみた。

```
    void Update()
    {
        countTime -= Time.deltaTime;   
　　　　　timeCount.text = countTime.ToString();
    }
```

![](https://cdn-ak.f.st-hatena.com/images/fotolife/f/ferrari458tukapai/20200326/20200326081733.gif)

こんな感じになる


## ScoreUIの下に整数部分だけを表示する。

しかし、今の実装だと小数点以下も見えてしまうので仕様上と違う

ここ描画は整数のみの部分を切り出した実装としたいのでコードの追加する。

```
//整数とする変数を追加
private int second;

    // Update is called once per frame
    void Update()
    {
        countTime -= Time.deltaTime;
        second = (int)countTime;
       //(int)countTimeでint型に変換して表示させる。
			timeCount.text = second.ToString();
    }
```

![](https://cdn-ak.f.st-hatena.com/images/fotolife/f/ferrari458tukapai/20200326/20200326081843.gif)


こんな感じに整数でTimeが表示された。

## カウントが０になったらカウントをストップする。

整数までカウントダウンできるようになったが、このままだとマイナスのカウントが永遠と描画されてしまう。

タイマーをストップする基準は
* カウントが０になったらそれ以上カウントしない
なのでif文でカウントが０になったら0のままにする制御を追加する。

```
        if (countTime <= 0)
        {
            second = 0;
            timeCount.text = "0";
        }
```

一度テストしてみる。
ここでは60秒も待つと長いので、5秒で０のままになるかを数える。

![](https://cdn-ak.f.st-hatena.com/images/fotolife/f/ferrari458tukapai/20200326/20200326081925.gif)

描画は０で止まっているのでOK

## 今後の課題

* 今はタイマーを動かすことだけしかできないので、今後ゲームオーバーの制御などをするときの制御などからアクセスしやすいように改良したい。
* Timeの箇所とタイマー数値オブジェクトを今回切り離して実装したけれども後々考えるとレンダリングをスクリプトで書けば一つにできるやんと後で気づいたので修正したい。

#development/Starry_Hill
pytest

#calculation.pyをpytestでテストします

```calculation.py
import os

class Cal(object):
    def add_num_and_double(self, x, y):

        if type(x) is not int or type(y) is not int:
            raise ValueError
        result = x + y
        result *= 2
        return result

    def save(self, dir_path, file_name):
        if not os.path.exists(dir_path):
            os.mkdir(dir_path)
        file_path = os.path.join(dir_path, file_name)
        with open(file_path, 'w') as f:
            f.write('test')
```

```conftest.py
import os
import pytest


#独自のfixture
@pytest.fixture
def csv_file(tmpdir):
    with open(os.path.join(tmpdir, 'test.csv'), 'w+') as c:
        print('before test')
        yield c
        print('after test')


def pytest_addoption(parser):
    parser.addoption('--os-name', default='linux', help='os name')
```


```test_calculation.py
#pip install pytest
import pytest
import calculation
import os

is_release = True
#関数でpytestする場合、先頭にtest_付ける
#def test_add_num_and_double():
#    cal = calculation.Cal()
#    assert cal.add_num_and_double(1, 1) != 4

#クラスでpytestする場合、先頭にTEST付ける
class TestCal(object):

    @classmethod
    def setup_class(cls):
        print('start')
        cls.cal = calculation.Cal()
        cls.test_dir = '/tmp/test_dir'
        cls.test_file_name = 'test.txt'

    def test_save_no_dir(self):
        self.cal.save(self.test_dir, self.test_file_name)
        test_file_path = os.path.join(self.test_dir, self.test_file_name)
        assert os.path.exists(test_file_path) is True

    @classmethod
    def teardown_class(cls):
        print('end')
        del cls.cal
        #本当は上に書く
        import shutil
        if os.path.exists(cls.test_dir):
            shutil.rmtree(cls.test_dir)

    # テストが走る前に呼ばれる
    def setup_method(self, method):
        print('method={}'.format(method.__name__))
        #self.cal = calculation.Cal()

    # テスト終了後に呼ばれる
    def teardown_method(self, method):
        print('method={}'.format(method.__name__))
        #del self.cal

    #csv_fileが独自のfixture
    def test_add_num_and_double(self, csv_file):
        print(csv_file)
        #fixtureがrequestの場合
        #os_name = request.config.getoption('--os-name')
        #print(os_name)
        #if os_name == 'mac':
        #    print('ls')
        #elif os_name == 'windows':
            #print('dir')

        #cal = calculation.Cal()
        assert self.cal.add_num_and_double(1, 1) == 4

    def test_save(self, tmpdir):
        self.cal.save(tmpdir, self.test_file_name)
        test_file_path = os.path.join(tmpdir, self.test_file_name)
        assert os.path.exists(test_file_path) is True

    #例外テスト(スキップも可能)
    #@pytest.mark.skip(reason='skip!')
    @pytest.mark.skipif(is_release==True, reason='skip!')
    def test_add_num_and_double_raise(self):
        with pytest.raises(ValueError):
            #cal = calculation.Cal()
            self.cal.add_num_and_double('1', '1')

```
Rails6 のちょい足しな新機能を試す 125（endless range bug fix編)

# はじめに

Rails 6 に追加された新機能を試す第125段。 今回は、`endless range bug fix` 編です。
Rails 6.0.0 では、 `(1..)` などのエンドレスな Range で `include?` メソッドを呼ぶと `RangeError` が発生するバグがありました。

Rails 6.0.1 以降では修正されています。

Ruby 2.6.5, Rails 6.0.1, Rails 6.0.0 で確認しました。

```shell
$ rails --version
Rails 6.0.1
```

今回は、 `rails new` して、 `app` ディレクトリの下にファイルを作って確認してみます。

# Rails プロジェクトを作る

Rails プロジェクトを新たに作成します。

```shell
$ rails new rails_sandbox
$ cd rails_sandbox
```

# スクリプトを作成する

`Range#include?` を実行するスクリプトを作成します。

```ruby:scripts/endless_range.rb
p (1..).include?(2)
```

# Ruby 2.6.5 では

エラーになりません。

```
$ ruby -v scripts/endless_range.rb
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux-musl]
true
```

# Rails 6.0.1 では

Rails 6.0.1 (以降) では、エラーになりません。

```
$ bin/rails runner scripts/endless_range.rb
Running via Spring preloader in process 263
true
```

# Rails 6.0.0 では

`RangeError` が発生します。

```
$ bin/rails runner scripts/endless_range.rb
...
         2: from scripts/endless_range.rb:1:in `<main>'
         1: from /usr/local/bundle/gems/activesupport-6.0.0/lib/active_support/core_ext/range/include_time_with_zone.rb:14:in `include?'
/usr/local/bundle/gems/activesupport-6.0.0/lib/active_support/core_ext/range/include_time_with_zone.rb:14:in `last': cannot get the last element of endless range (RangeError)
```
# 試したソース

https://github.com/suketa/rails_sandbox/tree/try125_endless_range

# 参考情報

* [Fix endless range include #36460](https://github.com/rails/rails/pull/36460)