OmniAICreator/Qiita-1.07M huggingface dataset:
rails 環境構築~ヘルスケアwebサービスを自分で作る医者の日記~

四月から未経験で初めて

railsを始めるも、前提となる知識がないことに気づき、
html/cssから習得、

javascript、jquery を習得し
クリニックのwebサイト制作のために
wordpressでサイトがやっと作れるようになる。

linuxの勉強と,sqlをかじり

やっとrailsに復帰した。

環境構築から初めるが、
railsを立ち上げる直前で挫折、
sqlite3のバージョンの関係で、エラーが起こると。
(https://qiita.com/Kta-M/items/254a1ba141827a989cb7)
(https://qiita.com/flowerhill/items/bb1e99bd87b151c0129b)

sqlite3 1.3.6を指定するがエラー
bunlde updateしても
```
An error occurred while installing
sqlite3 (1.3.6), and Bundler cannot continue.
Make sure that `gem install sqlite3 -v '1.3.6'
--source 'https://rubygems.org/'` succeeds before
bundling.
```
となる。

苦闘

結局、
rails が6.0.0だったため

```
[vagrant@localhost ~]$ rails -v
Rails 5.2.3
[vagrant@localhost ~]$ ruby -v
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux]
```
とrails　を5系にインストールし直す。

するとrails がやっと立ち上がる。
1日かかった、長い。

しかし、gem listするも
sqlite3が、重複して、二つのバージョンが、入っている。
これでいいのか？動くけど、、、
```
sqlite3 (1.4.1, 1.3.13)
```


でも、linuxが理解できるようになったため、だいぶすんなり頭に入るようになった。
頑張ろう。

追記
rails の仕組みについて網羅的にまとまっているのは、
[rails　ガイド](https://railsguides.jp/)
でよいのか？
もっといいのがあれば、知りたいなぁ。
MySQL 8.0の照合順序で標準になった「utf8mb4_0900_ai_ci」とは

MySQLで、テーブルやカラムを作る時に「照合順序（COLLATION）」を設定することができます。これが、MySQL8.0からは標準で「utf8mb4_0900_ai_ci」という設定になりました。

これは、次のような意味とのことです。

## utf8mb4

文字コード。UTF8で、マルチバイトを4バイトとする文字コードになります（通常、マルチバイトは3バイト）。

## 0900

Unicodeのバージョン 9.00を示しています

## ai

Accent Insensitiveの略称で、アクセントの違いを無視します。このため「は」と「ぱ」は等しいとして評価されます。

## ci

Case Insensitiveの略称で、大文字と小文字の違いを無視します。このため「あ」と「ぁ」は等しいと評価されます。

これを厳密に、大文字小文字、アクセントを判別する場合は次の照合順序を使います。

```
utf8mb4_bin
```
rsyncすると「rsync error: remote command not found (code 127) at io.c(235)」で失敗する

## エラーメッセージ

```
$ rsync -ra /home/yuta/test root@test-server:/tmp
bash: rsync: command not found
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: remote command not found (code 127) at io.c(235) [sender=3.1.2]
```

## 原因
接続先にも`rysnc`パッケージが必要

```
yum -y install rsync 
```
SEILでニンテンドースイッチの「NAT越え」問題を解決する方法

#概要
ニンテンドースイッチでオンラインゲームをする場合、しばしは遭遇するのが「NAT越え」問題です。
基本的にはルータがCone NATをサポートしていれば、UDPホールパンチング機能によるNAT越えが使えるため、この問題は起こりません。
しかしながらSEILのNATはSymmetric NATのみをサポートするためUDPホールパンチングは機能しません。
従って、この問題を解決するためにポートフォワード設定が必要です。

#スイッチを使えるようにするためのポートフォワード設定(基本)
ニンテンドースイッチでNAT越え問題が発生した際の対処方法として、任天堂の公式サイトでは以下の手順を推奨しています。

1. スイッチのIPアドレスを固定
2. WANから入ってくるUDPパケット(ポート1～65535)を全てスイッチのIPアドレスにフォワード

[ポートフォワード設定(任天堂公式/英語)](https://en-americas-support.nintendo.com/app/answers/detail/a_id/22272/~/how-to-set-up-a-routers-port-forwarding-for-a-nintendo-switch-console)

従って、SEILでも同様の設定を施すことで解決できます。
具体的にはnat定義に以下のような1行を足す事で解決できます(スイッチのIPアドレスを"192.168.10.100"に固定した場合)。

```
nat snapt add protocol udp listen 1-65535 forward 192.168.10.100 1-65535 enable interface pppoe0
```

ただし、全てのUDPパケットをスイッチにフォワードするのも心情的に宜しくありません。
実際には、40000～65535をフォワードしておけば問題ないようです。
実際、自分は以下のような環境で動作するのを確認しました。

|![SWITCH-1s.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476879/4b0854cc-b541-bb59-ef56-93768d378bc3.png)|
|:---:|

#スイッチを2台同時に使えるようにする(応用)
ポートフォワードをするとSymmetric NATのみをサポートするSEILでも、スイッチでネット対戦等が問題なくできるようになりますが、ここでもう一つ問題があります。
ポートフォワードはフォワード先のアドレスが固定されるため、同時に2台のスイッチをSEIL配下のLANに繋ぎ、NAT越えさせることができません。
これを解決する一番の方法は**SEILを使わない**事です。
Cone NAT系、できればポートとアドレス毎にパケットを制御できる「Port Restricted cone NAT」をサポートしているルータに交換する事が最も確実です。

ただし理由は人それぞれでしょうが、SEILを使うにはそれなりの理由があると思います。
以下は**「SEILは使いたいけどスイッチも使いたい」と言うワガママな人向けの対応方法**です。
環境は限りなく不格好ですが、使う事は出来ると思います。
細かい説明は省きます。まずは以下の図を見てください。

|![SWITCH-2s.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476879/19abc2d9-5d7a-984e-91a0-dc21ca533fb9.png)|
|:---:|

構成図の中にルータ(市販のブロードバンドルータ)が1台増えています。
そしてスイッチは、このブロードバンドルータに接続しています。スイッチのIPアドレスは固定でもDHCPでも構いません。
SEILからUDPパケットをブロードバンドルータにフォワードし、こちらで再度NATします。
つまり、自宅LAN内にスイッチ専用のネットワークを組むと言う方法です。

この構成が上手く動作するためには、追加したルータがCone NATをサポートしている必要があります。
こればかりは機種ごとに異なりますのでメーカーへの確認が必要ですが、最近の市販ブロードバンドルータはニンテンドースイッチ等メジャーなゲーム機の対応が出来ていないと売れませんから、最初からCone NATをサポートしているものが多いと思います。
自分はNEC製の安いブロードバンドルータを使いました。

この環境でSTUNnerというスマホアプリで接続中のネットワークのNATタイプを調べると、以下のような結果になりました。
左はSEIL直下のWiFiアクセスポイントにスマホを繋いだ結果で、右がポートフォワードしたWiFiブロードバンドルータにスマホをつないだ時の結果です。
左はSymmetric Cone(Symmetric NAT)なのに対して、右はPort Restricted Cone NATになっている事が分かるでしょう。

![switch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476879/2cd6b6ba-218a-b3f8-866c-0fe9c928e7ad.png)

#最後に
因みに、Port Restricted Cone NATで接続されることで、スイッチを2台同時に接続できると思いますが、所有台数の関係で当方は1台しかスイッチの接続を試しておりません。あしからず。
【Rails入門】Ajaxを導入する

##0.前準備
前準備として、コントローラを作成します。

```
$ rails g controller Practice index 
```

##1. Viewを整える

```erb:app/views/practice/index.html.erb
<h1>Ajaxを使ってみよう</h1>
<!-- :remote => trueの部分で、turbolinkを有効にする -->
<%= form_tag(url_for(:action => 'index'), :remote => true) do %>
  <%= text_field_tag :title %>
  <%= submit_tag "タイトルを変更する" %>
<% end %>
```
* __turbolink__ => turbolinkを使えば、ajaxが自動的に使える。


##2. Controllerを修正する

```ruby:app/controllers/practice_controller.rb
def index
  @title = params[:title]
  # respond_toメソッド => 結果をどのフォーマットで返すかを指定している
  respond_to do |format|
    # turbolinkが有効でないとき
    format.html
    # turbolinkが有効なとき
    format.js # => 次にindex.js.erbが呼ばれる
  end
end
```

* `respond_to`メソッド => あるオブジェクトが、特定のメソッドを持っているかどうかを調べて、trueまたはfalseを返す。

##3. routeを指定する
indexにポストしているので、app/config/routes.rbに以下のようにリソースを振り分ける。

```ruby:app/config/routes.rb
get 'practice/index'
post 'practice/index' # 追加
```

##4. JSを指定する
format.jsで指定したindex.js.erbを、app/views/practice/に作成する。

```ruby:app/views/practice/index.js.erb
$('h1').html("<%= @title %>");
```

##5. jQueryを使えるようにする
Rails 5.xからjQueryが標準でサポートされなくなったとかあるらしく、自分で設定する必要があるらしい。

```javascript:app/assets/javascripts/application.js
//= require jquery <= 追加
//= require rails-ujs
//= require turbolinks
//= require_tree .
```

```:Gemfile
gem 'jquery-rails'
```

gemを追加して、

```
$ bundle install
```
##5. Ajaxの動きを確認する

```
$ rails s
```

サーバーを起動し、`http://localhost:3000/practice/index`にアクセスする。

<img width="1142" alt="スクリーンショット 2019-09-16 21.40.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366833/500a4aef-7ceb-17ae-4717-a31c30ca18f0.png">
↓
<img width="1146" alt="スクリーンショット 2019-09-16 21.40.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366833/affb1285-bf86-ef0b-15a2-21ec7c4c405e.png">

非同期処理に成功しました。

##6. 最後にRailsに置けるAjaxの流れを確認する
6-1. turbolinksまたはjQueryなどを使って、JavascriptでXMLHttpRequestRequestを送り任意のアクションを実行する（今回はindexアクション）

6-2. アクションが実行される（この間にDBとのやりとりができる）。また、どの形式でデータを返却するかを指定することができる。(Javacript、JSON、XMLなど)

6-3. 選択されたデータ形式で(今回はJavascript)ファイルを自動的に検索して、ファイル内容を実行する(今回はindex.js.erb)ここで、HTML&CSSが変更されて、ajaxが完結する。
Everything you should know about Microsoft OneDrive for Mac

Microsoft OneDrive has almost everything that its competitors have in its arsenal (5 GB of free space in the file storage and up to twenty-five GB to those who have access to free updates, the ability to view the history of each object change, the shopping cart, desktop program and much more). Also, in addition, OneDrive (or as we also know SkyDrive) has its own advantages, for example, such as working with office documents right in the interface of file hosting, and we are not talking just about viewing option but also OneDrive offers editing option. For your convenience, we have prepared a brief tutorial about using <a href="https://cloudmounter.net/onedrive-mac.html">OneDrive for Mac</a>.
OneDrive Mac tips that you should know about
Of course, the first thing that every user should do is to setup OneDrive. Below you will get the step-by-step guide in order how to do it.
![OneDriveLogoTile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498429/9166c2a7-7f4a-35d9-af44-fc851561e705.png)


Before starting using OneDrive you need to obtain Microsoft Live ID.

Log in with just created credentials (login and password);

Now, you are needed to download OneDrive app for Mac;

Install OneDrive desktop app on your computer;

The last step is to create OneDrive folder on your hard drive upon a request.

Thought it would be rather difficult? Well, as you can see, it is not. The whole process is rather simple and straightforward that wouldn’t take you a lot of time.
Terraform スニペット: ALB とアクセスログ


- ALB の構築
- ログは S3 Bucket に出力します
- Terraform: >= 0.12

```main.tf
resource "aws_security_group" "alb_sg" {
  name        = var.prefix
  description = var.prefix
  vpc_id      = var.vpc_id

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_alb" "alb" {
  idle_timeout    = 60
  internal        = false
  name            = var.prefix
  security_groups = [aws_security_group.alb_sg.id]
  subnets         = var.subnet_ids

  enable_deletion_protection = false

  access_logs {
    bucket = aws_s3_bucket.alb_log.bucket
  }
}

resource "aws_alb_listener" "alb_listener_443" {
  load_balancer_arn = aws_alb.alb.arn

  port            = "443"
  protocol        = "HTTPS"
  ssl_policy      = "ELBSecurityPolicy-2015-05"
  certificate_arn = var.acm_cert_arn

  default_action {
    target_group_arn = aws_alb_target_group.alb.arn
    type             = "forward"
  }
}

resource "aws_alb_target_group" "alb" {
  name        = var.prefix
  port        = "80"
  protocol    = "HTTP"
  vpc_id      = var.vpc_id
  target_type = "ip"

  health_check {
    path    = "/ping"
    matcher = "200-299"
  }
}

data "aws_elb_service_account" "alb_log" {
}

data "aws_iam_policy_document" "alb_log" {
  statement {
    actions = [
      "s3:PutObject",
    ]

    resources = [
      "arn:aws:s3:::${var.prefix}-alb-log/*",
    ]

    principals {
      type = "AWS"

      identifiers = [
        "arn:aws:iam::${data.aws_elb_service_account.alb_log.id}:root",
      ]
    }
  }
}

resource "aws_s3_bucket" "alb_log" {
  bucket = "${var.prefix}-alb-log"
  acl    = "private"
  policy = data.aws_iam_policy_document.alb_log.json

  lifecycle {
    prevent_destroy = true
  }
}

resource "aws_s3_bucket_public_access_block" "alb_log" {
  bucket                  = aws_s3_bucket.alb_log.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}
```

https://github.com/daisaru11/terraform-snippets/tree/master/aws-alb-with-access-logs
laradockでプロジェクトごとにデータベースのデータを分けることができたのでメモ

現在、laradockで2つアプリを同時平行で開発しているのですが、一番最初始めるときに、何故かデータベースが共有されるという事がありました。

phpMyAdminにログインすると、2つのアプリで使うはずのデータベースがそれぞれ表示されていたんですね。

<h2>結論</h2>
laradock内にある.envファイルの内容を以下のように変更

```laradock/.env
DATA_SAVE_PATH=~/.laradock/data <-この行を
DATA_SAVE_PATH=.laradock/data <-このように変更！！
```

こうする事でそれぞれのlaradock内で管理することができます。

以上！！
Terraform スニペット: IAM Role


- IAM Role と IAM Policy を作成して関連付けを行います。
- ポリシードキュメントはインラインで書くこともできますが、 Data Source `aws_iam_policy_document` を使うのがベターそうです
- Terraform: >= 0.12

```main.tf
data "aws_iam_policy_document" "policy1" {
  statement {
    actions = [
      "s3:PutObject",
      "s3:GetObject",
    ]

    resources = [
      "arn:aws:s3:::foo-bucket/*",
    ]
  }
}

resource "aws_iam_policy" "policy1" {
  name        = "policy1"
  path        = "/"
  description = ""
  policy      = data.aws_iam_policy_document.policy1.json
}

data "aws_iam_policy_document" "role1_assume_policy" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "Service"
      identifiers = ["ecs-tasks.amazonaws.com"]
    }
  }
}

resource "aws_iam_role" "role1" {
  name               = "role1"
  assume_role_policy = data.aws_iam_policy_document.role1_assume_policy.json
}

resource "aws_iam_role_policy_attachment" "role1_attachement" {
  role       = aws_iam_role.role1.name
  policy_arn = aws_iam_policy.policy1.arn
}
```
Railsチュートリアル（第13章）

# はじめに
Railsチュートリアルの第13章が終わりました。
この章では、ユーザーの投稿内容の作成を行います。
ポイントだけメモしておきます。

# モデルの関連付け
以下のコマンドのように、`user:references`とつけてモデルを作成すると、Userモデルと関連付けられたモデルを作成できます。

```
rails generate model Micropost content:text user:references
```

UserモデルとMicropostモデルに以下の記述をすることで、モデルの関連付けができます。
そのモデルに対して１対１の場合は`belongs_to`、１対他の場合は`has_many`です。

```app/models/micropost.rb
   belongs_to :user
```

```app/models/user.rb
  has_many :microposts
```

関連付けられたモデルを生成する場合は以下のように記述します。
そのUserモデルに関連づいたMicropostモデルを生成できます。

```rb
@user = users(:michael)
@micropost = @user.microposts.create(content: "Lorem ipsum")
```
また、以下のように`dependent: :destroy`とモデルに記述することで、そのモデルを削除した際に関連付けられたデータを同時に削除してくれます。

```app/models/user.rb
  has_many :microposts, dependent: :destroy
```


# デフォルトスコープ
モデルに以下のように記述することで、デフォルトの順序を指定することができます。

```app/models/micropost.rb
  default_scope -> { order(created_at: :desc) }
```

# パーシャルへの変数の受け渡し
以下のようにパーシャルを呼び出す際に、ハッシュの形式で変数を渡すことができます。
受け取った側のパーシャルで使用する場合は、キーが変数名になります。

```erb
<%= render 'shared/error_messages', object: f.object %>
```

# whereメソッド
以下のようにデータを取得する場合、SQLのwhere文の形式で記述することができます。
?の部分はエスケープ処理で、後ろに記述している`id`の内容が入ります。
これにより、SQLインジェクション対策になります。今回はidなので問題ありませんが、ユーザーの入力内容を条件に設定する場合などに、不正な動作を起こさない対策になります。

```rb
Micropost.where("user_id = ?", id)
```

# 独自のバリデーション
以下のように`validate`メソッドにメソッド名のシンボルを与えることで、独自のバリデーションを記述することができます。
`validates`ではなく、`validate`という単数なことに気をつけます。

```rb
validate  :picture_size
```
eventcreateコマンドでイベントログを改行する

バッチファイルでイベントログを出力するときに使うeventcreateコマンドですが、`/d`オプションでメッセージ付与することができます。

これを改行入りで出力してみます。

# バッチファイル

```eventcreate.bat
setlocal enabledelayedexpansion
set CRLF=^


eventcreate /id 100 /l application /t information /d "テスト!CRLF!改行"
```

# 実行結果

管理者で実行します。

![.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96507/e279b3ce-cf13-3a52-6674-5288bfa4dc14.png)

メッセージが改行されました。

# 解説

## setlocal enabledelayedexpansion

`setlocal enabledelayedexpansion`を実行することで遅延環境変数展開を有効にします。

遅延環境変数とは、バッチファイル独特の考え方で、変数を読み込むタイミングを遅らせることです。
通常は行に入った時に変数が展開されますが、遅延環境変数を使うとコマンドを読み込んだタイミングで変数を展開します。

ここでは改行文字を遅延環境変数として展開するために有効化しています。

`eventcreate /d`オプションで改行文字の変数を展開するときは`!変数名!`というように`%`ではなく`!`で括ります。

## set CRLF=^

CRLFという環境変数を宣言して、改行文字を変数に入れています。

`^`はバッチファイルのエスケープシーケンスとして機能する記号です。
ハットの後の改行文字を変数に入れてさらに改行でコマンドを実行しているイメージになります。

このため、`set CRLF=^`の後ろには改行を**２行**続けないと変数に改行文字が入らないため注意してください。
Terraform スニペット: Session Manager


- Session Manager の設定 (Document) を作成します
- その Document では、 S3 Bucket および Cloudwatch Logs へのロギングを有効にします。
- Terraform >= 0.12

```document.tf
resource "aws_s3_bucket" "log_bucket" {
  bucket = var.prefix
  acl    = "private"
}

resource "aws_s3_bucket_public_access_block" "log_bucket" {
  bucket                  = aws_s3_bucket.log_bucket.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_cloudwatch_log_group" "log" {
  name              = var.prefix
  retention_in_days = 14
  tags              = {}
}

resource "aws_ssm_document" "document" {
  name            = "${var.prefix}-SSM-SessionManagerRunShell"
  document_type   = "Session"
  document_format = "JSON"

  content = <<DOC
{
    "schemaVersion": "1.0",
    "description": "Document to hold regional settings for Session Manager",
    "sessionType": "Standard_Stream",
    "inputs": {
        "s3BucketName": "${aws_s3_bucket.log_bucket.id}",
        "s3EncryptionEnabled": false,
        "cloudWatchLogGroupName": "${aws_cloudwatch_log_group.log.name}",
        "cloudWatchEncryptionEnabled": false
    }
}
DOC
}
```

作成したドキュメントをセッション開始時に指定します。

```
aws ssm start-session --document-name Foo-SSM-SessionManagerRunShell --target i-XXXXXXXXXXXXX
```

https://github.com/daisaru11/terraform-snippets/tree/master/aws-session-manager-with-logging
クリーンアーキテクチャの Presenter が分かりにくいのは MVC 2 じゃないから

# クリーンアーキテクチャの謎

クリーンアーキテクチャには、具体的なクラス構成例を示す以下の図があります。

![cleanarchitecture.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216010/542c512f-42b9-cd20-fee6-954bb70108cb.jpeg)

この図の中で、Presenter と Output Boundary (Presenter のインターフェース) だけ具体実装をイメージするのが非常に難しいと思います。

「[実践クリーンアーキテクチャ](https://nrslib.com/clean-architecture/#outline__6)」というブログ記事では、Presenter について

> これに敢えて触れなかった理由は MVC フレームワークとの相性が悪いからです。

と書かいた上で、MVC フレームワークとの共存方法に触れられています。

このように MVC フレームワークにおいて Presenter・Output Boundary の扱いが難しい理由を説明します。

# 結論

Web の MVC フレームワークで上図の通り実装できないのは、Web の MVC フレームワークが MVC 2 に基づいているのに対し、クリーンアーキテクチャの図は旧来の MVC (以後 MVC 1) に基づいているから。

Web フレームワークの場合は例えば以下のようになる。

![presenter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216010/8b0cb608-36cf-39ac-f974-bf81678df801.png)

# そもそも MVC は 2 種類ある

MVC という言葉をちゃんと調べると、最初は非常に混乱します。

例えば Wikipedia の [Model View Controller](https://ja.wikipedia.org/wiki/Model_View_Controller) の頁には以下の図と説明が書いてあります。

> ![200px-MVC-Process.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216010/6e285d15-ba26-90d2-6af7-9009fac30262.png)
> データの変更をビューに通知するのもモデルの責任である（モデルの変更を通知するのにObserver パターンが用いられることもある）

しかし、Web 開発で馴染みのある MVC では、Model の変更を View に通知するような処理はありません。

実は、Wikipedia で書かれているような MVC は旧来の GUI 用の MVC 1 であり、Web フレームワークで使われるのは Web 用の MVC 2 なのです。

MVC 1 では、Model から View に変更を通知します。Web で実現しようとすると WebSocket などを使うことになります。
MVC 2 では、Controller が Model の変更を View に反映します。Web の MVC フレームワークにおいて、Controller の最後で View にフォワードするあれです。

MVC 1 と MVC 2 についての詳細な説明は以下の記事を参照ください。

* [MVC と MVC2 について改めて考えてみる](https://www.s-arcana.co.jp/tech/2011/07/mvc-mvc2.html)
* [MVCをWebに適用した｢MVC2｣](https://javazuki.com/articles/mvc2-tutorial.html)
* [MVCパターン再考](https://qiita.com/ffggss/items/15943c6c3908a6f25cb5)

# クリーンアーキテクチャのクラス図は MVC 1

クリーンアーキテクチャのクラス構成例の図をもう一度見てみると ...

![cleanarchitecture.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216010/542c512f-42b9-cd20-fee6-954bb70108cb.jpeg)

**Controller から Presenter や View に依存の線が引かれていません。
これは、この図が MVC 2 ではなく MVC 1 に基づいていることを意味します。**

MVC 1 を使うのであれば上図のような構成を実現可能であり、その際にアプリケーション層がプレゼンテーション層に依存しないよう、Output Boundary というインターフェースで DIP を適用することになるのです。

# Web の MVC とクリーンアーキテクチャの落としどころ

一方、Web フレームワークなどの MVC 2 を使う場合、Controller は Output Data を受け取り、それを View Model に変換して View に渡すような流れになります。
その際、Output Data を View Model に変換する役割を Presenter に担わせることが考えられます。
これらをまとめると下図のようになります。

![presenter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216010/8b0cb608-36cf-39ac-f974-bf81678df801.png)

Presenter のインターフェースであった Output Boundary は DIP が不要になったため削除しています。

# 参考
- [Clean Architecture 達人に学ぶソフトウェアの構造と設計](https://www.amazon.co.jp/dp/4048930656)
- [実装クリーンアーキテクチャ](https://qiita.com/nrslib/items/a5f902c4defc83bd46b8)
JavaScript でタイマー処理

JavaScript でタイマー処理を実装するには setInterval を使う。

```js
function func() {
  // 一定時間ごとに実行したい処理
};

const delay = 1000; // 遅延時間。単位はミリ秒

const intervalID = setInterval(func, delay); // 戻り値はタイマーを識別する正の整数

clearInterval(intervalID); // intervalID のタイマーをキャンセルする
```
ApplicationRecordで定義した関数を呼ぼうとしたらハマった

ApplicationRecordで定義した関数をControllerで呼ぼうとしたらハマったので、メモ
（プロジェクトはAPIモード）

## 呼び出し元（例）

```login_controller.rb
class LoginsController < ApplicationController
    def login
        user = User.find_user(params[:login_id], params[:password])

        render json: user
    end
end
```

## 呼べなかったやつ（例）

定義されてないよって怒られた。

```User.rb
class User < ApplicationRecord
    def find_user(login_id, password)
        return self.find_by(login_id: login_id, password: password)
    end
end
```

## 呼べたやつ（例）

関数名に`self.`をつけたら呼べた。

```User.rb
class User < ApplicationRecord
    def self.find_user(login_id, password)
        return self.find_by(login_id: login_id, password: password)
    end
end
```

## 終わり

クラスメソッドとインスタンスメソッドっていうのがあるらしく、
今回の呼び出し方では、クラスメソッドとして定義しないといけないらしい。

`self.`をつけない場合は、下記のようにnewして、

```login_controller.rb
class LoginsController < ApplicationController
    def login
        user_instance = User.new()
        user = user_instance.find_user(params[:login_id], params[:password])

        render json: user
    end
end
```

ApplicationRecordでは`User.find_by`で呼ばないといけないみたい。

```User.rb
class User < ApplicationRecord
    def find_user(login_id, password)
        return User.find_by(login_id: login_id, password: password)
    end
end
```

個人的には呼び出し方としては、クラスメソッドが好きかな
Azure PlayFab の Studio を削除できない問題への対応を考える

## PlayFab の Studio 削除できない問題 is 何
PlayFab はまず Studio を作り、その中に Title を作るところから始まります。

誰もが「まずは検証用に `TestStudio` と `TestTitle` を作ってみるかー」と適当なものを作成すると思います。

しかし、一度作成した Studio は削除することができず GameManager に残り続ける仕様です。

そのため安易に Studio を作成すると GameManager が下図のようなゴミだらけになり後悔することになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97193/b54b5d5c-eb25-3131-e5a4-1b5b0cd15567.png)
※私は実際はこれの3倍くらいのゴミスタジオがあります…

## なんとかゴミを整理したい
別の PlayFab アカウントを取得して、ゴミスタジオの管理をそちらのアカウントに移管することにしました。（酷い）

### 手順
1. 新しい PlayFab アカウントを取得する
2. 削除したい Studio の User に 上記のアカウントを追加する
3. 上記のアカウントで GameManager にログインしなおす
4. 削除したい Studio の User から元のアカウントを削除する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97193/3e439221-429c-70c7-a6e4-e3b0da367bad.png)
すごくスッキリした！！

## あとがき
褒められた手段ではありませんが、実際 PlayFab チームでもそういうことをやっているそうなのでしょうがないということで…
https://community.playfab.com/questions/406/206729807-Possible-to-delete-titles-and-studios-from-the-Dashboard-.html?page=4&pageSize=10&sort=oldest

なおこの方法で Studio の整理を行うにあたって、複数アカウントの利用が禁止されていないか利用規約を確認しましたが、そういった記載は特にありませんでした。
web3jを使ってコントラクトを実行する方法

# 記事の内容
web3jを使ってsolidityで作成したコントラクトを実行する方法です。
solファイルをJavaのクラスに変換する方法についてはこちらをご確認ください。
本記事で使用するコントラクトは以下の記事に記載の内容を使用します。

[solidityのコントラクトをJavaのコントラクトクラスに変換する方法](https://qiita.com/bc_yuuuuuki/items/7ab984027aa8ff14e4b7)
# コード

``` sample.java
try {
  SampleGasProvider gasProvider = new SampleGasProvider(BigInteger.valueOf(500), BigInteger.valueOf(200000));

  Addition contract = Addition.deploy(
      web3j,
      credentials,
      gasProvider
      ).send();
  // コントラクトのアドレスを出力
  System.out.println("contract address: " + contract.getContractAddress());
  // メソッド呼び出し（トランザクションなし）
  System.out.println("get: " + contract.get().send());
  System.out.println("add: " + contract.add(BigInteger.valueOf(10)).sendAsync());
  System.out.println("get: " + contract.get().send());

} catch (Exception e) {
  e.printStackTrace();
}
```

``` SampleGasProvider.java
package jp.ethereum;

import java.math.BigInteger;
import org.web3j.tx.gas.ContractGasProvider;

public class SampleGasProvider implements ContractGasProvider{

  private BigInteger gasPrice;
  private BigInteger gasLimit;

  public SampleGasProvider(BigInteger gasPrice, BigInteger gasLimit) {
    this.gasPrice = gasPrice;
    this.gasLimit = gasLimit;
  }
  @Override
  public BigInteger getGasPrice(String contractFunc) {
    return this.gasPrice;
  }
  @Override
  public BigInteger getGasPrice() {
    return this.gasPrice;
  }
  @Override
  public BigInteger getGasLimit(String contractFunc) {
    return this.gasLimit;
  }
  @Override
  public BigInteger getGasLimit() {
    return this.gasLimit;
  }
}
```

コードの内容は単純です。
まずは、コントラクトをデプロイします。
この処理が終わると、コントラクトをデプロイ用のトランザクションが作成され、ブロックに取り込まれた後に処理が完了します。

``` Sample.java
  Addition contract = Addition.deploy(
      web3j,
      credentials,
      gasProvider
      ).send();
```
実行結果（gethコンソール）

```
INFO [09-16|17:19:41.983] Submitted contract creation              fullhash=0xd169416410c2e6e7bdc02a2a27384ed2425e1433f39117a3810675fcfed85353 contract=0xf5ad7542173e8944D1aE16B4394eAA34cfdA4814
```
次にコントラクトを実行します。

``` Sample.java
  System.out.println("get: " + contract.get().send());
  System.out.println("add: " + contract.add(BigInteger.valueOf(10)).sendAsync());
```

この例ではコントラクトのget処理をまずは呼び出します。
getは値を参照するだけなのでトランザクションは作成されず、すぐに応答が返ってきます。

次のadd処理は値を更新する処理なのでトランザクションが作成されます。
「sendAsync」を使用しているため、ブロックに取り込まれる前に応答が返ってきます。
この例だと以下のような出力になります。

```
add: java.util.concurrent.CompletableFuture@18271936[Not completed]
```

ブロックに取り込まれるまで処理を待つ必要がある場合は、以下のとおり変更します。

``` Sample.java
  System.out.println("add: " + contract.add(BigInteger.valueOf(10)).send());
```

# コントラクトのロード
上述したコードはコントラクトをデプロイして実行するという方法でしたが、既にデプロイ済みのコントラクトを実行する方法もあります。

``` Sample.java
Addition contract = Addition.load(
  address,
  web3j,
  credentials,
  gasProvider
);
```
デプロイと引数はほとんど変わりませんが、第一引数にコントラクトのアドレスが入ります。（0xを含む）
それ以降の操作は全く変わりません。
【ExcelVBA】末尾改行を付けたり外したりする

# 概要
ドキュメント用途のExcelファイルでは、1セル内に長文を入力することがよくある。
それが表の形式になっていると、文字の洪水のように見えてしまい視認性が悪い。
また、行の幅をキュッてやる時に行間をダブルクリックするが、
やはりキュッとなりすぎてしまう。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219708/4f51ff58-0689-554d-120d-6eae870635d4.png)


そこでセルに末尾改行を付ける人も多いと思う。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219708/7d75bba1-2074-d858-f42d-6daf6403d6f4.png)

これでキュッとしても行間が維持されて見やすくなる。
サンプルがあまり良くないが、内容が詰まっているほど効果が見える。

中には末尾改行を好まない人もいてすべて取り除きたかったり、
今すぐ全体に末尾改行入れてキュッてしたい！という場面があるので、
一連のアクションをマクロ化しておけば便利かと思う。

# マクロ

### 選択範囲に末尾改行を付与する
末尾改行の増殖を防ぐため、
セルの末尾がすでに改行かを判定して行う。

``` vb
Sub AppendLineBreakAtEnd()
    Dim trg As Range
    
    For Each trg In Selection
        If Len(trg.Value) > 0 Then
            If Right(trg.Value, 1) <> vbLf Then
                trg.Value = trg.Value & vbLf
            End If
        End If
    Next
End Sub
```

### 選択範囲に末尾改行を除去する
末尾改行が2つ以上入っている場合があるので、
すべて無くなるまでループさせている。

``` vb
Sub RemoveLineBreakAtEnd()
    Dim trg As Range
    
    For Each trg In Selection
        If Len(trg.Value) > 0 Then
            Do While Right(trg.Value, 1) = vbLf
                trg.Value = Left(trg.Value, Len(trg.Value) - 1)
            Loop
        End If
    Next
End Sub
```
tensorflow 準備メモ

作成中
# 使用環境
## 利用PC
- OS：Windows 10 Pro (64Bit)
- メモリ：8GB

## Python実行環境
- エディタ：PyCharm 2019.2.2
- 仮想環境のPythonバージョン：3.5

# 実行環境の準備
### Anacondaのインストール
[Condaサイト](https://www.anaconda.com/distribution/#download-section)から、AnacondaのインストーラーをDLしてインストール

### 仮想環境を作成
- Windowsのメニューから「Anaconda Navigator」を起動する
- 「Anaconda Navigator」の左列のメニューから「Environments」を選択する
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202844/aec5f3e1-73ab-fdfb-d03f-f2c48f4b91d2.png)

- 中央列の下段にある「Create」を選択する
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202844/f9dde713-b3b2-47c6-24d9-57e1714a8730.png)

- 「Create new environment」が表示されたらNameとPythonのバージョンを入力しCreateを押す
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202844/483563fc-5f25-e3fd-d403-24ecc8de2013.png)

- 中央列に作成された仮想環境名が表示されたら、名称右の▶を押し「Open terminal」を選択する
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202844/f4487465-90c4-1dd9-5f3e-c7f117005d4d.png)

- コマンドプロンプトが起動するので「conda env list」を入力して環境の一覧を表示する
- 作成した環境のパスを確認する

### エディタの設定
- PyCharmを起動する
- 「Create new project」を選択する
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202844/e9b85c20-3f9b-72fd-66b1-df2609e18941.png)

- New Projectのダイアログが表示されたらLocationの入力とInterpreterを指定する。Interpreterは「Existing Interpriter」を選択して仮想環境内のPython.exeを指定する。Python.exeは上で確認した仮想環境のパス直下にある
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202844/a40110af-9b9d-a420-e890-5b4a8bbd4682.png)
- Createボタンを押す


# 参考リンク
- [pip での TensorFlow のインストール](https://www.tensorflow.org/install/pip?hl=ja)
- [Tensorflow環境の構築](https://www.atmarkit.co.jp/ait/articles/1804/19/news136_2.html)
docker-composeでPHP,apache,Mysqlの環境構築

docker-composeで、PHP、apache、Mysqlの環境構築を行いました。

####ディレクトリ構造

```
├── docker-compose.yml
├── html
├── mysql
├── php7.2
│   ├── dockerfile
│   └── php.ini
└── phpmyadmin
```

htmlディレクトリ内にphpファイル等の実行させたいソースを置きます。


####各ファイル

```docker-compose.xml
version: '3'

services:
  php:
    build: ./php7.2
    volumes:
       - ./html:/var/www/html
    ports:
       - 8080:80

  mysql:
    image: mysql:5.7
    volumes:
       - ./mysql:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=db
      - MYSQL_USER=test
      - MYSQL_PASSWORD=test
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      - PMA_HOST=mysql
      - PMA_USER=test
      - PMA_PASSWORD=test

    links:
      - mysql
    ports:
      - 4040:80
    volumes:
      - ./phpmyadmin/sessions:/sessions
```


dockerfile

```dockerfile
FROM php:7.2-apache
COPY php.ini /usr/local/etc/php/
RUN apt-get update \
  && apt-get install -y libfreetype6-dev libjpeg62-turbo-
  && docker-php-ext-install pdo_mysql mysqli mbstring
```

```php.ini
[Date]
date.timezone="Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.langage = "Japanese"

```

###docker-composeコマンド

ビルド

```
# docker-compose build
```

コンテナを起動

```
# docker-compose up -d
# docker-compose start
```

コンテナを停止

```
# docker-compose stop
```

##動作確認
http://localhost:8080/ にアクセスし、プログラムが実行できていることを確認する
http://localhost:4040/ にアクセスし、phpmyadminに繋がることを確認する

##覚え書き
最初は、公式のPHP,Mysqlのイメージをpullして試したのですが、それにはpdo_sqliteしか入っていないようなので、
dockerfileでpdo_mysqlもインストールしないと、PDOでのDB接続ができません。注意です！


## 参考資料
- [docker docs](https://docs.docker.com/get-started/part3/)
- [@naente_devさんQiita 「docker-compose で PHP7.2 + Apache + MySQL + phpMyAdmin 環境を構築」](https://qiita.com/naente_dev/items/d259ea84c172deeff7d8)
- [@rockinruuula1227さんQiita 「Docker Composeを使ってLAMP環境を構築する：前編」](https://qiita.com/rockinruuula1227/items/83f3f1406f339083ef3f)

- [さくらのナレッジ Docker入門（第六回）〜Docker Compose〜](https://knowledge.sakura.ad.jp/16862/)
JavaScriptの変数について

## 変数とは

変数とは『データの入れ物』と良く表現されます。
スクリプトがデータのやり取りをする際に一時的にデータを保存するための箱のようなものです。

変数を作成するためにはスクリプトで『変数の宣言』を行う必要があります。

```js

varv  変数名;
```

変数名 hogeを宣言するには下記のように記述します。


```js

var hoge;
var huga;

//もしくは

var hoge,huga;

```

『,』を使用して複数の変数をまとめて宣言することが出来ます。

変数は『データ』といれるための『箱』なので、宣言時に『初期値』の設定をすることもできます。

初期値を設定するには変数名を『=』でつなぎます。

```js

var msg = 'メッセージ';
```

JSのなかでの『=』左辺と右辺が等しいという意味はなく**右辺の値を左辺に格納せよ**という意味になります。
zsh + prezto + powerlevel10k で VS Code のターミナルをかっこよくする

こんにちは。今回はお気に入りの VS Code を、もっとお気に入りにしたいと思います。

# ゴール

こんな感じで、味気なかったターミナルをなんとなくスタイリッシュに。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">いろいろ試して、VS Codeのターミナルはこんなかんじで落ち着いた。 <a href="https://t.co/aDv4IASrQN">pic.twitter.com/aDv4IASrQN</a></p>&mdash; Takahito Miyamoto (@takahito0508) <a href="https://twitter.com/takahito0508/status/1173504657101975552?ref_src=twsrc%5Etfw">September 16, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 前提

```sh
> brew -v

Homebrew 2.1.11
Homebrew/homebrew-core (git revision 9cc538; last commit 2019-09-15)
Homebrew/homebrew-cask (git revision 96afd; last commit 2019-09-16)
```

```sh
> git --version   

git version 2.23.0
```

# zsh をセットアップする

```sh
# 必要に応じて
sudo chown -R $(whoami) /usr/local/Cellar
sudo chown -R $(whoami) /usr/local/Homebrew
sudo chown -R $(whoami) /usr/local/var/homebrew

brew update
brew install zsh

echo "/usr/local/bin/zsh" | sudo tee -a /etc/shells
chsh -s /usr/local/bin/zsh
```
一度ターミナルを閉じて開き直すと zsh の設定画面が開きますが、何もしないオプションを選択します。

# prezto をセットアップする

```sh
git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"

setopt EXTENDED_GLOB
for rcfile in "${ZDOTDIR:-$HOME}"/.zprezto/runcoms/^README.md(.N); do
  ln -s "$rcfile" "${ZDOTDIR:-$HOME}/.${rcfile:t}"
done
```

# フォントをセットアップする

以下のフォントをダウンロードして、それぞれダブルクリックしてインストールしてください。

- [MesloLGS NF Regular.ttf](https://github.com/romkatv/dotfiles-public/raw/master/.local/share/fonts/NerdFonts/MesloLGS%20NF%20Regular.ttf)
- [MesloLGS NF Bold.ttf](https://github.com/romkatv/dotfiles-public/raw/master/.local/share/fonts/NerdFonts/MesloLGS%20NF%20Bold.ttf)
- [MesloLGS NF Italic.ttf](https://github.com/romkatv/dotfiles-public/raw/master/.local/share/fonts/NerdFonts/MesloLGS%20NF%20Italic.ttf)

# ターミナルをセットアップする

ターミナル > 環境設定 > プロファイル > フォント > 変更 から、「MesloLGS NF」を選択してください。一度ターミナルを閉じて開き直すとフォントが反映されます。

# VS Code をセットアップする

次の3行を settings.json に追加しましょう。

```json:settings.json
{
  (省略)
  "terminal.integrated.shell.osx": "/usr/local/bin/zsh",
  "terminal.integrated.fontFamily": "MesloLGS NF",
  "terminal.integrated.fontSize": 14,
  (省略)
}
```

# powerlevel10k をセットアップする

~/.zpreztorc を VS Code で開き、該当箇所を探します。既存の行をコメントアウトして、powerlevel10kに置き換えましょう。

```sh
# zstyle ':prezto:module:prompt' theme 'sorin'
zstyle ':prezto:module:prompt' theme 'powerlevel10k'
```
一度ターミナルを閉じて開き直すと、Powerlevel10kの設定画面が開きます。指示に従いながら、好みに応じたデザインにしていってください。

これで完璧です。これでますますコーディングが大好きになりますねー

Happy Coding!!

# Acknowledgement

こちらを参考にさせていただきました。ありがとうございました。

- [Macの開発環境をzshで良い感じにする](https://qiita.com/bake0937/items/79e350a474c1cd60a5e0)

- [Macにzshとpreztoのインストール＆アンイストール、諸々の設定](https://qiita.com/s_s_satoc/items/e3c1b9b3545fd572dd1c)

- [Powerlevel10k](https://github.com/romkatv/powerlevel10k#prezto)
jQueryのslideToggle()をVueで代替する

Vue標準の`transition`コンポーネントで完結できて、slideToggleぽい動きができます。

```vue:template
 <div>
   <button @click="handleToggle">
   	Toggle Button
   </button>
   <transition
     name="toggle-slide"
     @before-enter="beforeEnter"
     @enter="enter"
     @before-leave="beforeLeave"
     @leave="leave"
   >
     <div v-show="isActive">
       slide content
     </div>
   </transition>
 </div>
```

```js:script
 export default {
   data() {
 	return {
 	  isActive: false	
 	}
   },
   methods: {
   	handleToggle() {
   		this.isActive = !this.isActive
   	},
 	// transition hook
 	beforeEnter(el) {
 		el.style.height = '0'
 	},
 	enter(el) {
 		el.style.height = el.scrollHeight + 'px'
 	},
 	beforeLeave(el) {
 		el.style.height = el.scrollHeight + 'px'
 	},
	leave(el) {
 	    el.style.height = '0'
   	}
   }
 }
```

```css:style
 .toggle-slide-enter-active,
 .toggle-slide-leave-active {
 	transition: all 0.5s;
 	overflow: hidden;
 }
 .toggle-slide-enter,
 .toggle-slide-leave-to {
 	height: 0;
 	transition: all 0.5s;
 }
```

`slot`使ってみたり、親で`v-for`させたり再利用できそうですね
また`wai-aria`を使いstate管理してアクセシブルなアコーディオンパネルにするとなお良いですね
自己流でいつもやっているwai-aria含めたコードはこんな感じです。
https://codesandbox.io/embed/v-a11y-accordion-6jyky

レガシー環境からの移行の参考になれば・・・

### 参考
- https://jp.vuejs.org/v2/guide/transitions.html#JavaScript-フック
- https://masup.net/2016/09/accordion-ui-with-react-wai-aria.shtml
【IE11対応】clip-pathを使用せずに動画をテキストやシェイプでマスクする方法

## テキストでマスク
<p class="codepen" data-height="403" data-theme-id="dark" data-default-tab="result" data-user="loki__codepen" data-slug-hash="yLBqzmB" data-preview="true" style="height: 403px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Cool UI - Mask the Video with TEXT">
  <span>See the Pen <a href="https://codepen.io/loki__codepen/pen/yLBqzmB/">
  Cool UI - Mask the Video with TEXT</a> by Loki (<a href="https://codepen.io/loki__codepen">@loki__codepen</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## パスの描画（シェイプ）でマスク
<p class="codepen" data-height="448" data-theme-id="dark" data-default-tab="result" data-user="loki__codepen" data-slug-hash="abojPNK" data-preview="true" style="height: 448px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Cool UI - Mask the Video with Path">
  <span>See the Pen <a href="https://codepen.io/loki__codepen/pen/abojPNK/">
  Cool UI - Mask the Video with Path</a> by Loki (<a href="https://codepen.io/loki__codepen">@loki__codepen</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

SVGデータそのままでは実装できません。一度`canvas`タグ内のJSで描画できる記述方法に変換してあげる必要があります。
手持ちのSVGデータでマスクを取りたい場合は、以下のサイトで`<path>`タグをCanvasRenderingContext2Dに変換すると良いでしょう。

> SVG to HTML5 Canvas Converter
> http://www.professorcloud.com/svg-to-canvas/

## 作成した背景
`clip-path`を使用すると簡単にマスクが実装できますが、IE11だと動きません。
動画をマスクする方法をぐぐってみても、IE11非対応の`clip-path`を利用した方法しか出てこなかったので作成しました。
使いみちとしては、基本は`clip-path`を使用しつつ、UserAgentで判断してIE11のときに使用してください。

---
Twitterのフォロワーを募集しております！
すでにWeb業界にいらっしゃる方や、業界未経験の方、どんな方でも募集しておりますので、どうぞよろしくお願いいたします(\*^^\*)

Twitter - https://twitter.com/hiroki_web
【Dryに則ったコード】コントローラのメソッドとHelperのメソッドが同じ時

#問題
コントローラとヘルパーで重複したメソッドをDry(Don`t repeat yourself)に則ってコードをきれいにしたい。

##改善したいファイル
下記のapplication_helper.rbとapplication_controller.rbにて、メソッドが重複しています。

```ruby:helpers/application_helper.rb
module ApplicationHelper
  def current_user
    @current_user ||= User.find_by(id: session[:user_id])
  end

  def logged_in?
    !current_user.nil?
  end
end

```

```ruby:controllers/application_controller.rb
class ApplicationController < ActionController::Base

(中略)

  def current_user
    @current_user ||= User.find_by(id: session[:user_id])
  end

  def logged_in?
    !current_user.nil?
  end

end

```

application_controller.rbにあるコードを書いて、application_helper.rbのコードを削除します。

##改善策
ヘルパーはビューで使えるメソッドを定義することができます。
ただ今回はコントローラーに同じメソッドが書いてあるので、コントローラにあるメソッドをベルパー側で使えるようにしたいと思います。

今回はコントローラーに以下の一行を追加するだけで終了します。

```
helper_method :method_name
```

#改善したコード
最終的なコードは以下になります。

```ruby:helpers/application_helper.rb
module ApplicationHelper
end

```

```ruby:controllers/application_controller.rb
class ApplicationController < ActionController::Base

(中略)

  helper_method :current_user, :logged_in?

  def current_user
    @current_user ||= User.find_by(id: session[:user_id])
  end

  def logged_in?
    !current_user.nil?
  end

end

```

これでDryに則ったコードが書けました！
プリメイドai  を使おう

DMMのプリメイドaiが格安で販売されていました。
http://robots.dmm.com/robot/premaidai
購入された方もかなり居るのではないでしょうか？

今回は、使用における僕の補足をさせて頂きます。
#Android
プリメイドaiは使用するにはAndroidOSのデバイスが必要になります。
AndroidOSのデバイスは、格安のものも結構あります。
私は、FireTabletをお勧めします。
定価は5,980円ですが、セールの際に3,980円程度になります。

![DSC_0439 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/9f79a98d-c59a-7186-e234-acc505cbd713.jpeg)

使用に際して、このリンク等にあるような、Androidアプリが使用できる環境を構築する必要があります。
https://ygkb.jp/6312

なお、プリメイドaiのアプリ内のショップで曲を追加可能です。
この曲は、現在のものから増えることはありませんが、無料でダウンロードできるのでダウンロードすることをお勧めします。

#スタンド
Twitterで流れていたスタンドです。
100円ショップ　ダイソーのワイヤーネットというものを組み合わせます。
・ワイヤーネット
・ワイヤーネットスタンド
・J型フック　大　（2個）
・ポール（長）47㎝（2個）
・タイラップ（4本）
Twitterの方は62x19㎝のワイヤーネットを使用していましたが、私は入手できず、62x29.5㎝のものを使用しています。

![DSC_0432 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/5958b1f0-9d86-da55-0139-6980f4ebe30e.jpeg)

まずは、組み立てます。
![DSC_0434 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/42bfcf43-0575-b1fb-8b15-970e181e3a7d.jpeg)

そのままだと、軋むのでポールで補強します。
![DSC_0437 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/1ac7209a-dbae-9627-8386-ae3a5faa42fc.jpeg)

私が試した限りでは、ポールは、端ではなく、中央寄りにすることをお勧めします。
![DSC_0436 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/e76eecbb-7cc3-6bfc-45b0-612ab949410f.jpeg)

また、腕を振り上げた際に、ネットの間に腕を入れることがあるので、要注意です。
幅19㎝のワイヤーネットが入手できるのであれば、こちらをお勧めします。
![DSC_0435 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/db20f139-5bba-adb2-363c-a8eb6ca07657.jpeg)

『楽しく遊ぶプリメイドAI』 解析メモ　でべさん製作
コマンド等詳細　
https://docs.google.com/spreadsheets/d/1c6jqMwkBroCuF74viU_q7dgSQGzacbUW4mJg-957_Rs/edit#gid=322455178
AWSにLaravelをデプロイしたらエラーが出たときの対応方法

Laravel 6.0で作成したテストプログラムをAWSにデプロイしてみたところRedisに関するエラーが出たので対応内容をメモしておきます。

## 環境
PHP：7.3.6
Laravel：6.0.3

## 発生したエラー

``` php
local.ERROR: Please remove or rename the Redis facade alias in your "app" configuration file in order to avoid collision with the PHP Redis extension.
```

「PHP Redis拡張モジュールとの衝突を避けるためRedisのファサードを削除するか名前を変えてください」ということなので、
素直にファサードの名前を変えたところ、エラーの内容が以下のように変わりました。

``` php
local.ERROR: Class 'Redis' not found
```

そりゃ名前を変えたから見つからないと言われて当然ですよね？

## 対応内容

ここからが対応内容になります。

### PHP Redis拡張モジュールがインストールされているかどうか確認する

```php -m``` を実行しても一覧に表示されていないため、そもそもインストールされていないようでした。

### yum を使ってRedis拡張モジュールをインストールする

``` shell 
$ sudo yum list | grep php73 | grep redis
php73-php-pecl-redis4.x86_64         4.3.0-1.el6.remi              remi-safe
php73-php-pecl-redis5.x86_64         5.0.2-1.el6.remi              remi-safe
php73-php-phpiredis.x86_64           1.0.0-10.el6.remi             remi-safe
```

redis4 と redis5 がありますが redis5 の方をインストールしてみます。
インストールが完了して再度 ```php -m``` を実行してみましたが一覧に表示されていません。

### redis.so はどこにインストールされたのか

find コマンドで捜索してみたところ、以下のディレクトリに redis.so を発見しました。

``` shell
$ sudo find / -name "redis.so"
/opt/remi/php73/root/usr/lib64/php/modules/redis.so
```

よくよく振り返ってみると、インストールしたRedis拡張モジュールは remi レポジトリのものでしたが、
既にインストールされている PHP本体は AWSのレポジトリのものでした。
つまりインストールされた拡張モジュールをPHPが認識できておりませんでした。

これはどちらかに統一せねばと思い、PHP本体に合わせることにしました。

### yum を使って Redis拡張モジュールをインストールする（再挑戦）

インストールした remi レポジトリのRedis拡張モジュールはいったん削除し、
remi レポジトリを除いて、yum でインストールできるかどうか確認してみましたが、
PHP7.2まではあるのに、PHP7.3のものがない・・・。

```
$ sudo yum list --disablerepo=remi* | grep php | grep redis
php54-pecl-redis.x86_64              2.2.7-1.5.amzn1               amzn-main
php55-pecl-redis.x86_64              2.2.7-1.5.amzn1               amzn-main
php56-pecl-redis.x86_64              2.2.8-1.8.amzn1               amzn-main
php70-pecl-redis.x86_64              3.1.1-1.1.amzn1               amzn-main
php71-pecl-redis.x86_64              3.1.1-1.2.amzn1               amzn-main
php72-pecl-redis.x86_64              3.1.1-1.3.amzn1               amzn-updates
```

### PECLをインストールする

yum でダメなら PECL をインストールして、PECLでRedis拡張をインストールすることにしました。
php73-pear はありませんが、 php7-pear というのがPHP7.x用らしいのでこちらをインストールします。

```
$ sudo yum install php7-pear
```

インストールが完了し pecl7 というコマンドが使えるようになりました。

### PECL を使って Redis拡張モジュールをインストールする

```
$ sudo pecl7 install redis

(省略)

Build process completed successfully
Installing '/usr/lib64/php/7.3/modules/redis.so'
install ok: channel://pecl.php.net/redis-5.0.2
configuration option "php_ini" is not set to php.ini location
You should add "extension=redis.so" to php.ini
```

php.ini に記述を追加しろとありますが、他の拡張モジュール同様 .ini ファイルを作成して読み込ませることで対応しました。

``` /etc/php-7.3.d/50-redis.ini
extension=redis.so
```

## まとめ

Redis拡張モジュールがちゃんとインストールされていれば、ファサードの名称は変えなくても問題ないようです。
[jQuery] プラグインで画像アップロードUIを簡単実装

# 実装するもの
<img width="587" alt="スクリーンショット 2019-09-17 14.13.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393193/cad631cf-8a90-0df5-dece-f6423906c520.png">

[Demo: codepen](https://codepen.io/daisuke-mori/pen/PoYBLwB)
※デモファイルではアイコン部分FontAwsomeにしています



# 必要なプラグイン
[dropify](https://github.com/JeremyFagis/dropify)
ダウンロード後「dist」フォルダ内のjs、cssファイルを取る

# 手順

```html
<!--jQuery読み込み-->
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>

<!--プラグインデータ読み込み-->
<link rel="stylesheet" type="text/css" href="css/dropify.css">
<script src="js/dropify.js"></script>
...
<form>
	<!--dropifyクラスが適用される-->
	<input type="file" class="dropify" name="file">
</form>
...
<script>
	// プラグイン読み込み
	$(document).ready(function(){
		$('.dropify').dropify();
	});
</script>
```

たったのこれだけで、ドラッグ＆ドロップできるUIが作れてしまいます。
「js/dropify.js」や「css/dropify.css」も自由にいじれるので
カスタマイズも簡単に行うことができるので非常に便利です。

# Laravelに導入したい場合
jQueryを入れる必要があるので、こちらの記事を参照

[laravel5.6でjQueryを使おうとすると、Uncaught ReferenceError: $ is not definedが出る時の対処方法](https://qiita.com/96kuroguro/items/aad383a129c3523f2ea1)
ReactNative(Expo)でMapを利用する


## 準備

```bash
npm install --save react-native-maps
```

## イメージ

![スクリーンショット 2019-09-16 19.34.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/f5af2eb7-cfe0-a89e-b7f0-61591f08bb6e.png "スクリーンショット 2019-09-16 19.34.44.png")


## 実装

地図を表示してピン（Marker）を設置。クリックできるようにする。

```js:App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import MapView from 'react-native-maps';

export default class App extends React.Component {
    render() {
        return (
            <MapView
                style={{ flex: 1 }}
                initialRegion={{
                    latitude: 35.681236,
                    longitude: 139.767125,
                    latitudeDelta: 0.02, //小さくなるほどズーム
                    longitudeDelta: 0.02,
                }}
            >
                <MapView.Marker
                    coordinate={{
                        latitude: 35.681236,
                        longitude: 139.767125,
                    }}
                    title={"東京駅"}
                    description={"JRの駅です。"}
                    onPress={()=>alert("click")}
                />
            </MapView>
        );
    }
}
```

## 注意点

AndroidではGoogle Map APIのKeyの設定が必要らしい(iOSもかな）。

* https://qrunch.net/@moecaf/entries/pfvpg3KrVKtzigRg
* https://rennnosukesann.hatenablog.com/entry/2018/06/07/225623


まとめると下記のような感じかな。。。

```json:app.json

{
  "expo": {

  },
  "ios": {
    "config": {
      "googleMapsApiKey": "[API_Key]"
    }
  },
  "android":{
  		"config":{
  			"googleMaps":{
  				"apiKey": "[API_KEY]"
  			}
  		}
  }
}
```
#AWS SQS のデッドレターキューとは何なのか？ 正常終了しなかったメッセージたちの墓場みたいなものらしい。

完全に消えてしまうとデバッグもできないし、非同期処理、キューイングシステムでのデバッグとか恐ろしく大変そうで原因調査とかしづらいだろうし、だからこそこういう仕組みが用意されてるんだろうね。多分。

墓場を掘り起こすことが可能なのだろうか。

>Amazon SQS は、デッドレターキューをサポートしています。このキューは、正常に処理 (消費) できないメッセージの送信先として、他のキュー (ソースキュー) が使用することができます。問題のあるメッセージを分離して、処理が成功しない理由を調べることができるため、デッドレターキューは、アプリケーションやメッセージングシステムのデバッグに役立ちます。

>デッドレターキューを使用するメリット
>デッドレターキューの主なタスクは、メッセージの失敗を処理することです。デッドレターキューを使用すると、正しく処理できないメッセージを分離して、処理が成功しなかった理由を調べることができるというメリットがあります。

[Amazon SQS デッドレターキュー - Amazon Simple Queue Service](https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html)

# 落とし穴？

これは、どういうことなのだろうか？

>メッセージの送信を無期限に再試行できる状態にしておく必要がある場合は、スタンダード キューと共にデッドレターキューを使用しないでください。たとえば、従属プロセスがアクティブまたは使用可能になるまで待機する必要があるプログラムでは、デッドレターキューを使用しないでください。

# ポイズンピルメッセージ？

って何なの？

*受信されたが処理できないメッセージ* のことみたいだね。

>メッセージ数を減らし、システムで ポイズンピルメッセージ (受信されたが処理できないメッセージ) が発生する可能性を抑えるには、デッドレターキューを使用してください。

![image](https://user-images.githubusercontent.com/13635059/64943037-973be880-d8a5-11e9-84d8-c79b3677b240.png)


# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【SubstancePainter】編集中のシェーダーをすぐさまリロードする

(この記事は、Windows 10 / Substance Painter 2019.2.0 の環境で検証されています。)

Substance Painter でカスタムシェーダー( glsl ) を作る場合、配置場所は

`C:\Users\Username\Documents\Allegorithmic\Substance Painter\shelf\shaders`

のような場所となりますが、ここに置いた glsl ファイルを編集更新した際に、Substance Painter にそれを認識させるには、Substance Painter を再起動する必要があります。glsl ファイルを別名保存すれば編集済みの内容が新しいシェーダーとして認識させられますが、どちらにしろ面倒か煩わしいです。これを回避する方法が公式のフォーラムのやりとりにありましたので、日本語で記しておきます。

## 事前準備

1. まず、前述の Documents 以下の shaders フォルダ以外の場所で、glsl ファイルを作成します。（本当はそうでなくでもよいのですが、その方が分かりやすいです。）

2. シェーダー開発用のプロジェクトを適当に作成し保存します。適当なメッシュがなければ　perview sphere など、サンプルファイルを別名保存しましょう。

3. そのファイルをペインターのシェルフにドラッグ＆ドロップします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8302/f02866e1-aad5-ace5-261a-0730452f81c3.png)

この際に、読込先は必ずプロジェクトを対象にします。ここが重要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8302/d334a617-7ef9-da45-fbe7-2a31889f426b.png)

4.(確認のため）読み込んだシェーダーを実際に適当します。

## 編集作業

1.適当にglslファイルを編集更新します。

2.シェルフの先ほど読み込んだシェーダーを右クリックすると ”再ロード” のような項目があるのでこれを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8302/18ae72e5-5d0a-8fe1-46f8-f9939c54b397.png)

3.シェーダーが更新されます。

## 編集終了

完成した glsl ファイルを正式な保存場所にコピーしましょう。

以上です。

読み込み対象をプロジェクトにしない場合、再ロードメニューが表示されないので、注意しましょう。

## おまけ
プラグインの開発の場合は Plugin メニューからリロードするだけでファイルの更新が適用されます。プラグイン名を変えるには Substance Painter の再起動が必要でした。
GitHub のリポジトリを手作業でコピーする

GitHub というか Git のお話。


## 要約

[コマンドラインを使った Git リポジトリのインポート](https://help.github.com/ja/articles/importing-a-git-repository-using-the-command-line) をやります [^1] 。

[^1]: このリンクを貼るための踏み台記事と言っても過言ではない。


## 経緯

GitHub でリポジトリをコピーする一番お手軽な方法は目当てのリポジトリで `Fork` ボタンをポチッと押すことです。
ただし、諸事情あってフォークできない (or したくない) 場合は [GitHub Importer による自動インポート](https://help.github.com/ja/articles/importing-a-repository-with-github-importer) を試みることでしょう。
でもこれがめちゃんこ遅い…遅くない？ ([Spoon-Knife](https://github.com/octocat/Spoon-Knife) に対して自動インポートしたら 2時間くらいかかった。えぇ…)

自動で遅いなら手動だぜー！ということで手を動かしてごにょごにょやります。
今回はコピー元として [Spoon-Knife](https://github.com/octocat/Spoon-Knife) リポジトリを参照します。


## 準備

コピーの前にコピー先のリポジトリを GitHub 上に作成しておきます。
[`New repository` からやるいつものやつ](https://help.github.com/ja/articles/creating-a-new-repository) です。
リポジトリ名だけ指定したら他の項目はデフォルトで OK です。
コピー元に合わせてリポジトリ名は `Spoon-Knife` とします。


## リポジトリのコピー

GitHub 公式の手順を参考にしましょう。

- [コマンドラインを使った Git リポジトリのインポート](https://help.github.com/ja/articles/importing-a-git-repository-using-the-command-line)

```bash:リポジトリをコピーする
$ git clone --bare https://github.com/octocat/Spoon-Knife.git
$ cd ./Spoon-Knife.git
$ git push --mirror https://github.com/<username>/Spoon-Knife.git  # <username> は適宜読み替えのこと
$ cd ..
$ git clone https://github.com/<username>/Spoon-Knife.git
```

`git push --mirror` を終えたら `Spoon-Knife.git` は用済みなので、特に理由がなければ削除して構いません。

コピー後もコピー元の変更に追従したい場合はコピー元をリモートリポジトリに追加してもいいでしょう：

```bash:コピー元をリモートリポジトリに追加
$ cd ./Spoon-Knife
$ git remote add upstream https://github.com/octocat/Spoon-Knife.git
```

`--bare` なしで `git clone` した後にリモートリポジトリを差し替えて…というやり方もできますが、各ブランチを個別に反映する必要があるので少し面倒です。
丸ごとコピーするなら公式の手順でやるのが一番楽だと思います。


**おしまり**
便利なシェルシェルスクリプトまとめ

随時追加予定

実行ディレクトリ配下の全てのファイルに対して、XXXXXという記述が含まれるファイルを出力する

```shell
grep 'XXXXX' -rl .
```


実行ディレクトリ配下のすべてのファイルの中身に対して、XXXXXと書かれているところをYYYYYに置換する

```shell
for file in $(find . -type f -print | xargs grep 'XXXXX'); do sed -i -e "s/XXXXX/YYYYY/g" ${file%:}; done;
```
Swift初心者のためのゼロから覚える基礎知識

この記事は随時更新予定です。

# varとletの違い
定数はlet、変数はvarになります。
定数は値を変更することができませんが、変数は値を変更できるという違いがあります。


# キャスト（型変換）が必要な理由とは
異なるデータ型の値が連結したり、計算する場合はエラーが発生します。
例えばInt型とString型をキャストせずに連結しようとするとエラーになります。