OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails6】RSpecによるフォロー機能の結合テストの実装

#はじめに
サービスの品質を保つために必要不可欠なテストを実施しております。

今回はユーザーフォロー機能の結合テストを実装し、その実装内容を記事にしていきたいと思います。

#前提
・Relationship（フォロー）モデルの単体テストは実施済み

※完了されていない方や単体テストと並行してご覧になられたい方は、以下のRelationshipモデルの単体テストについての記事をご参考ください。

https://qiita.com/narimiya/items/11429a0064383fb177ee

#バージョン
rubyのバージョン　ruby-2.6.5
Railsのバージョン Rails:6.0.0
rspec-rails 4.0.0

#実施したテスト

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/ec98fe91-875e-1918-0d3c-6a3462978dd1.png)

#ユーザー一覧画面について
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1052793/ad79d30e-6257-84dd-b5c8-4a3d545949bc.png)


握手のマークをクリックすると非同期によるフォローが実行されます。

#relationshipsテーブルのカラムの紹介

```xxx_create_relationships.rb
class CreateRelationships < ActiveRecord::Migration[6.0]
  def change
    create_table :relationships do |t|
      t.integer :follower_id
      t.integer :followed_id
      t.timestamps
    end
  end
end
```

#モデル内のバリデーション

```app/models/relationship.rb
class Relationship < ApplicationRecord
  belongs_to :follower, class_name: 'User'
  belongs_to :followed, class_name: 'User'

  validates :follower_id, presence: true, uniqueness: { scope: :followed_id }
  validates :followed_id, presence: true
end
```

#FactoryBotの内訳

```spec/factories/rerationships.rb
FactoryBot.define do
  factory :relationship do
    follower_id    { FactoryBot.create(:user).id }
    followed_id    { FactoryBot.create(:user).id }
  end
end
```

#サポートモジュール

```spec/support/sign_in_support.rb
module SignInSupport
  def sign_in(user)
    visit user_session_path
    fill_in 'user[email]', with: user.email
    fill_in 'user[password]', with: user.password
    find('input[name="commit"]').click
    expect(current_path).to eq(root_path)
  end
end
```

#テストコードの内容

```spec/system/relationships_spec.rb
require 'rails_helper'

RSpec.describe "Relationships", type: :system do
before do
    @user1 = FactoryBot.create(:user)
    @user2 = FactoryBot.create(:user)
  end

    describe '#create,#destroy' do
        it 'ユーザーをフォロー、フォロー解除できる' do 
            # @user1としてログイン           
            sign_in(@user1)

            # @user1としてユーザー一覧ページへ遷移する
            visit users_path(@user1)

            # @user2をフォローする
            find('#no-follow').click
            expect(page).to have_selector '#yes-follow'
            expect(@user2.followed.count).to eq(1)
            expect(@user1.follower.count).to eq(1)

            # @user2をフォロー解除する
            find('#yes-follow').click
            expect(page).to have_selector '#no-follow'
            expect(@user2.followed.count).to eq(0)
            expect(@user1.follower.count).to eq(0)
        end
    end
end
```

#補足説明
##「user2をフォローする」のテストコードについて
下記の前半の行では、user1がuser2フォローすると、user2のフォロワー数が１上がるという意味の文法です。

一方、後半の行ではuser1がuser2フォローすると、user1のフォロー数が１上がるという意味の文法です。

```spec/system/relationships_spec.rb
 expect(@user2.followed.count).to eq(1)
 expect(@user1.follower.count).to eq(1)
```

##「user2をフォロー解除する」のテストコードについて
「user2をフォローする」のテストコードの逆の意味合いがあり、フォロー解除するとカウント数が1減るので0となるという意味の文法です。

```spec/system/relationships_spec.rb
 expect(@user2.followed.count).to eq(0)
 expect(@user1.follower.count).to eq(0)
```

以上です。
送信ボタンのdisabledを取り除く

# 機能
アプリにitem(商品)に関連するコメントを投稿する機能を実装時
非同期で即時更新されてコメントするボタンを押すとコメントが表示される。

# 問題点
コメントするボタンを押すとボタンが機能しなくなった。
一回送信すると画面のリロードをしないとボタンが使えない状態になる

# 原因
コメントするボタンを押すとボタンの要素の中にdisabledという属性が増えている。
これは、要素の機能を停止させている原因だと言うことが判明した。

# 解決方法
シンプルにコメントする処理の最後にボタンの要素を取得後removeAttributeによって要素内からdisabledを取り除くことで解決した。

この解決にたどり着くまでにclickイベント発火時にdisabledを取り除こうとしていたがclickした頃にはボタンが使えない状態になるようで処理が実行されなかった。
EdgePCをDockerで運用するためのオレオレコンテナ管理ソフトFarming

# はじめに
Dockerコンテナの起動、変更、削除を行うソフト勉強がてらを書きました。
# Farmingとは
自身もDocker上で実行するコンテナ管理。
リモートからコンテナ設定情報を取得しコンテナを構成します
* 設定情報にないコンテナ→停止＆削除（停止のみの設定も可）
* 設定上にあり実行していないコンテナ→実行（イメージが無い場合はPullして実行）
* バージョン違い→イメージが無い場合はPullして実行
が機能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136187/afb0126d-7578-5207-ad8d-7986f577400d.png)

# 開発経緯
Edgeデバイス上のDockerでWeb開発する必要があり、デプロイそしてアップデートをどのように
簡略化できるかを考えていました。
当初HashiCorop社のNomadがフィットすると思い試していましたが、日本語のチュートリアルが少なく、
サーバ→クライアントと別PCでの構成に悩む。
やりたい事はシンプルで
* docker run
* docker start
* docker stop
* docker pull
* docker rm
このコマンドをリモートから実行
DockerAPIを実行すれば実現できることが分かりソフトに仕立てました
いづれはEdgePCが複数台になることからjsonファイルをEdgePCが参照しコンテナをオーケストレーションを目指しました

# 課題
EdgePCのログ収集、構成ファイルダウンロード時の認証やEdgePCのグルーピングなどを組み込みたいと思っています

# リポジトリ
https://github.com/kyamamoto03/Farming

# DockerHub
https://hub.docker.com/repository/docker/kyamamoto03/farming
E - スプリンクラー, E - SNS のログ

##[E - スプリンクラー](https://atcoder.jp/contests/past202005-open/tasks/past202005_e)

O(N+M+Q)
無向グラフの問題です。
隣接行列を使っています。

```python:python
import math
import heapq
import itertools
from functools import reduce

# main
def main():
    N, M, Q = list(map(int, input().split()))
    graph = []

    for y in range(0, N):
        row = []
        for x in range(0, N):
            row.append(False)
        graph.append(row)

    for _ in range(0, M):
        u, v = list(map(int, input().split()))
        u = u - 1
        v = v - 1
        graph[u][v] = True
        graph[v][u] = True

    C = list(map(int, input().split()))

    for _ in range(0, Q):
        q = list(map(int, input().split()))

        if q[0] == 1:
            x = q[1] - 1 
            print(C[x])

            for i in range(0, N):
                if graph[x][i]:
                    C[i] = C[x]

        if q[0] == 2:
            x = q[1] - 1 
            y = q[2]
            print(C[x])
            C[x] = y

# エントリポイント
if __name__ == '__main__':
    main()
```

メモリの制約で隣接行列を使用できない場合、隣接リストを使用します。

```python:python
import math
import heapq
import itertools
from functools import reduce
 
# main
def main():
    N, M, Q = list(map(int, input().split()))
    graph = []

    for y in range(0, N):
        row = []
        graph.append(row)

    for _ in range(0, M):
        u, v = list(map(int, input().split()))
        u = u - 1
        v = v - 1
        graph[u].append(v)
        graph[v].append(u)

    C = list(map(int, input().split()))

    for _ in range(0, Q):
        q = list(map(int, input().split()))

        if q[0] == 1:
            x = q[1] - 1 
            print(C[x])

            for i in graph[x]:
                C[i] = C[x]

        if q[0] == 2:
            x = q[1] - 1 
            y = q[2]
            print(C[x])
            C[x] = y

# エントリポイント
if __name__ == '__main__':
    main()
```

##[E - SNS のログ](https://atcoder.jp/contests/past201912-open/tasks/past201912_e)

O(N)
有向グラフの問題です。

```python:python
import math
import heapq
import itertools
from functools import reduce
 
# main
def main():
    N, Q = list(map(int, input().split()))
    graph = []

    for y in range(0, N):
        row = []
        for x in range(0, N):
            row.append(False)
        graph.append(row)

    for _ in range(0, Q):
        s = list(map(int, input().split()))

        if s[0] == 1:
            graph[s[1]-1][s[2]-1] = True
        elif s[0] == 2:
            for i in range(0, N):
                if graph[i][s[1]-1]:
                    graph[s[1]-1][i] = True
        elif s[0] == 3:
            to_follow = []
            for i in range(0, N):
                if graph[s[1]-1][i]:
                    for j in range(0, N):
                        if graph[i][j] and s[1]-1 != j:
                            to_follow.append(j)
            for i in to_follow:
                graph[s[1]-1][i] = True
        
    for i in range(0, N):
        row = ""
        for j in range(0, N):
            if graph[i][j]:
                row += "Y"
            else:
                row += "N"
        print(row)

# エントリポイント
if __name__ == '__main__':
    main()
```
Vision クライアントライブラリを使わずに Python3 で Vision API を使う

### はじめに
この記事は Vision API を [Vision クライアントライブラリ](https://cloud.google.com/vision/docs/libraries?hl=ja) を使わずに Python で JavaScript の [Fetch API](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API) のように使用するための内容を記載します。

### 結論
- 使用する画像は `base64` モジュールでエンコード
- JSON リクエストを作成し、`json` モジュールから `json.dumps()` を用いて JSON 文字列に変換する
- 最後に `requests` モジュールから `requests.post()` を使用して Vision API リクエスト（POST）を作成すれば OK

下にサンプルコードを置いておきます。

### コード
```python
import requests
import base64
import json
import pprint

GOOGLE_API_KEY = "YOUR API KEY"
GOOGLE_CLOUD_VISION_API_URL = f"https://vision.googleapis.com/v1/images:annotate?key={GOOGLE_API_KEY}"
IMG_PATH = "YOUR PHOTO PATH"
base64Image = base64.b64encode(open(IMG_PATH, "rb").read()).decode('utf-8')
    
headers = { "Content-Type" : "application/json" }
request_data = json.dumps({
    "requests": [
        {
            "image": {
                "content": base64Image
            },
            "features": [
                {
                    "type": "OBJECT_LOCALIZATION"
                }
            ]
        }
    ]
})
  
# Vision API にリクエストを行う
response = requests.post(GOOGLE_CLOUD_VISION_API_URL, headers=headers, data=request_data)

# データを表示
pprint.pprint(response.json())
```

### 例
以前行ったスープカレー屋さんの画像を POST した結果を貼っておきます。
カレー屋さんのホームページ - [矢巾店 - スープカレーハウスしっぽ](https://www.shipposoupcurry.jp/%E7%9F%A2%E5%B7%BE%E5%BA%97/)
![上のコードで Vision API を通した結果の画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276546/0e247ae6-0302-21ad-b121-ce0867ec5366.png)

### おわりに
手っ取り早く API を使用したい人はこちらの方法のほうが楽なのではないでしょうか。
参考になれば幸いです。
Rで地図を描く【その1: 日本全体の白地図】

# 0. はじめに
統計プログラミング言語`R`で日本地図を作図しようという連載です。
第一弾となる本記事では、`R`を使った日本地図の作り方を解説します。

「`R`をあまり使ったことがない」という方でも直ぐに取り組めるような記述になっている...はずです。

# 1. どのパッケージを用いるか
`R`では、デフォルトで組み込まれている関数以外に、パッケージを読み込むことで高度な処理を行うことができます。Rで日本地図を描くにはパッケージの活用が必須です。


<font color="Blue">パッケージとはなんぞや？という読者はリンクをチェック！
https://stats.biopapyrus.jp/r/basic/package.html
http://cse.naro.affrc.go.jp/takezawa/r-tips/r/08.html
</font>

本記事では、以下の2つのパッケージを用いた方法を紹介します。

1. `maps`パッケージを用いる
<font color="Blue">
低い解像度で大雑把な日本地図を描くことができます。
</font>

2. `raster`パッケージを用いる
<font color="Blue">GADMというデータセットと併用することで、高解像度の日本地図を描くことができます。
GADMは容量が極めて思いデータセットなので注意してください
</font>

# 2. 白地図を描く
### 2.1 mapsパッケージで描く
`R`で下記のコードを実行してください。すると、解像度の低い白地図を安直に作ることができます。

```
library(maps)
map("world", "Japan)
```
![スクリーンショット 2021-03-08 15.51.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449575/e7d48903-4868-cd8f-ab82-1420c230f8d9.png)





### 2.2 rasterパッケージで描く
`R`で下記のコードを実行してください。すると、解像度の高い白地図を作ることができます。（添付した画像は少々潰れてしまっています）
`maps`の場合より作図に時間がかかります。

```
library(raster)
jpnDat <- getData('GADM', country = 'JPN', level = 0)
plot(jpnDat)
```

![スクリーンショット 2021-03-08 15.42.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449575/17ab63de-b896-dec7-88a9-693f4c8fdae1.png)
EIP(Elastic IP)が解放できない際等の逆引きアドレス確認方法

どこにも関連付けてないはずのEIPなのに解放しようとすると

> 123.345.567.789: The address with allocation id [eip-0123456789abcdefg] cannot be released because it is locked to your account. Please contact AWS Support to unlock it.
> Service: AmazonEC2; Status Code: 400; Error Code: InvalidAddress.Locked; Request ID: 12345678-9ab-cdef-ghij-klmnopqrstuv)

みたいなことを言われて失敗することがあります。

今回がまさにそうだったんですが、EIPを関連付けたEC2からメール送信を行う等の理由でIPアドレスの逆引き設定をしてもらっている場合などが該当します。

この逆引き設定がされているかどうかはお手元のコンソールから確認することができます。

```
$ host 123.345.567.789
123.345.567.789.in-addr.arpa domain name pointer sample.example.com.
```

こんな感じなら逆引き設定されているということになります。

この場合は[AWSの専用サポート](https://console.aws.amazon.com/support/contacts?#/rdns-limits)のUse Caseに「rDNSを削除してちょ」って書くと削除してもらえます。

```
Please remove following rDNS lookup settings:
789.567.345.123.in-addr.arpa domain name pointer sample.example.com.
```

逆引きが設定されていない、または設定が削除されたかどうかも同じくお手元のコンソールから確認できます。

```
$ host 123.345.567.789
789.567.345.123.in-addr.arpa domain name pointer ec2-123-345-567-789.ap-northeast-1.compute.amazonaws.com.
```

こんな感じになってれば逆引き設定がされていない状態なのでEIPも解放できると思います。
UE4でOnComponentBeginOverlapが発火しない問題(c++)

#問題
c++を使用した実装で、相互作用設定も見直しても、何故かコリジョンイベントが発火しない。

#結論
コールバック関数にUFUNCTION()を付ける。以上。

#なぜこんな初歩的なことを今更？
→overlap not workingなどで調べても相互作用設定を見直せとしか出てこなかったので、備忘録。

#そもそも
Output Logを見さえすれば、コンパイル直後に真っ赤っかになってるの一目でわかるんだから、わからんなとなったらとりあえずOutput Logを見てみる、というのはアリかも。
とはいえ、VS側からのコンパイルでは何事も無かったかのようにsuccessedと言われるのは罠。
Laravel+Cognitoでサインイン時にエラー"The security token included in the request is invalid."

##事象
Laravel環境にCognitoを使用したサインアップ/サインイン機能を搭載したのですが、新規登録・メール検証済みユーザーでサインインしようとした時に全くもってサインインできませんでした。うんともすんとも動かねえぜ。
![スクリーンショット 2021-03-08 15.32.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434874/cf7ca42a-2829-afad-ef38-5d34629ff785.png)

前提条件として、Cognitoのアプリクライアントの設定で「**認証用の管理 API のユーザー名パスワード認証を有効にする(ALLOW_ADMIN_USER_PASSWORD_AUTH)**」を使用した場合でのエラーです。

結論を言うと環境変数に設定していた**AWS_ACCES_KEY_ID**が間違っていただけなのですが、なんとこのミスに気づかず６時間以上を無駄にしてしまったため、備忘録として残します。

以下、Laravel+Cognito構築で参考にさせて頂いた記事
・https://blackbits.io/blog/laravel-authentication-with-aws-cognito
・https://qiita.com/suzumurakk/items/efe4543cf0df2cd31659

##原因
タイトルにもある通りで、裏では以下のエラーが返ってきていました。

```
The security token included in the request is invalid.(リクエストに含まれているセキュリティトークンが無効です。)
```

このエラーでググると、AWSに送信しているアクセスキーIDもしくはシークレットアクセスキーが無効とのことでした。
Laravelの.envを確認したところ、**アクセスキーID(AWS_ACCES_KEY_ID)**に余計な文字が入っておりました。チクショー！！
上記解決後、無事にサインインできることを確認しました。

![スクリーンショット 2021-03-08 15.31.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434874/2f6169d2-a1de-4eef-9d59-27eeaee43977.png)

##反省点
1. Laravelの認証周り（Guardやプロバイダー）の理解が浅く、原因追求に時間がかかりました。
2. 真っ先にAWSからのレスポンスを確認すべきでした。次からは必ずそうします！！！


そのうちLaravel+Cognitoを使った認証/メール検証/サインアップの実装記事を書こうと思います。
ビューがそれぞれ分かれていて間の一つだけ空間を開けずにビューを表示したい場合


そのビュー自体を消す。

その中に例えば名前とか商品名とか入っているみたいな漢字の場合それぞれをisHiddenとかで消すと空白が生まれてしまう。

なのでビュー本体を消せばそのビューがないことにできる。

ビューの中の要素をそれぞれ消したら空白ができてしまいなぜだろうと思っていました。

でもよくよく考えたら中の要素は消しても本体は残っている訳なのでそりゃ間に空間を表示しちゃうよね

って話
AWSとAzureの差異について

# AWS と Azureって何が違うの
設計や構築メインで担当してます。個人的な感触を纏めていきます。わりとAWS側の人間なのですがAzureやることになりましたので、Azureで気づいた部分など踏まえガンガン更新していきます。

##AWS
　・IaaSとしての利用でもインフラ設計をあんまり考えなくても詰まない。
　・UI/UXが素晴らしく、直感的に触っていれば慣れる。
　・クラウド初心者向けで余計なことはあまり考えずAWSがやってくれる

##Azure
　・IaaSとしてはインフラ設計をがっつりしないと詰む。
　・UI/UXがわかりにくい。各単語が意味不明。
　・オンプレからがっつり移行したいケースだと細かいパラメータ多いから似た構成を再現しやすい。
ci-phpunit-testの正式リリース（v1.0.0、v2.0.0、v3.0.0）

# 初の正式リリース

2021/03/03にCodeIgniter 3でPHPUnitでのテストを簡単に書くためのツール「ci-phpunit-test」のv1.0.0、v2.0.0、v3.0.0をリリースしました。

- https://github.com/kenjis/ci-phpunit-test/releases

調べてみると、最初のリリースv0.1.0は2015/06/12でした。 ということで、「構想3か月、開発5年」みたいな長大なプロジェクトに結果的になりました。

ここまでで合計38回のリリース、18人のコントリビューター、Composerからの累計ダウンロード数37万回以上になりました。

- https://github.com/kenjis/ci-phpunit-test/graphs/contributors

ただし、GitHubスターがまだ536と少ないです。特に日本人は少ないので、ユーザーのかたは遠慮なくスターをガンガン押してください！

- https://github.com/kenjis/ci-phpunit-test/stargazers

# PHPUnitのバージョンとの対応

何故、3つもバージョンをリリースしたかというと、PHPUnit（とPHP）のバージョンアップに対応するためです。今のところそれ以外に機能的な差異はありません。

PHPUnitでテストを書いていますが、ブランチを分けないとテストが簡単に書けなくなりました。

| ci-phpunit-test | PHP       | PHPUnit     |
| --------------: | --------- | ----------- | 
| v3.0.0 | PHP 7.3以降 | PHPUnit 9.3以降    |
| v2.0.0 | PHP 7.2以降 | PHPUnit 8.1から9.2 |
| v1.0.0 | PHP 5.4.0以降 (5.6以降を推奨) | PHPUnit 4.3から7.5 (4.8以降を推奨) |

# 今後

今後は、v3.xをメインのバージョンとして、必要があれば古いバージョンもメンテしていこうと思います。

## CodeIgniter4への対応

なお、ci-phpunit-test for CodeIgniter4の作成予定はありません。これは、多くの機能がCodeIgniter4に含まれたため、必要性があまりないためです。

ただし、全ての機能がCodeIgniter4に含まれるわけではないので、以下のパッケージで不足する機能（モック作成のヘルパーメソッド、モンキーパッチ、`$this->request`）を提供していきます。

- [kenjis/phpunit-helper](https://github.com/kenjis/phpunit-helper)
- [kenjis/monkey-patch](https://github.com/kenjis/monkey-patch)
- [kenjis/ci3-to-4-upgrade-helper](https://github.com/kenjis/ci3-to-4-upgrade-helper)

以下のテストコードのように既存のテストコードをあまり変更せずにCodeIgniter4でも使えるようになります。

- [models/shop/Inventory_model_test.php](https://github.com/kenjis/ci4-tettei-apps/blob/main/tests/app/models/shop/Inventory_model_test.php)

# モンキーパッチについて

最後に、今までモンキーパッチについて、きちんと説明を書いたことがないので、ここに記載しておきます。

モンキーパッチは自転車の補助輪のようなものです。プロダクトコードに問題がなければ、本来必要ありません。個人的にも私は自分が書いたコードでモンキーパッチを使ったことはありません。

モンキーパッチを使わないとテストが書けない場合は、設計に問題があると思ってほぼ間違いありません。設計を見直してください。

そうは言っても、サードパーティのツールが`exit()`していたり、過去のレガシーコードをまだ使わざるを得なくモックに差し替えられないというような場合のために、一応、機能を提供しています。

できるだけ早く、モンキーパッチを使わなくて済む環境を目指してください。

# 関連

- [ci-phpunit-test](https://github.com/kenjis/ci-phpunit-test)

---

[![クリエイティブ・コモンズ・ライセンス](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)](http://creativecommons.org/licenses/by-sa/4.0/deed.ja)
この記事は[CC BY-SA 4.0（クリエイティブ・コモンズ 表示 4.0 継承 国際 ライセンス）](http://creativecommons.org/licenses/by-sa/4.0/deed.ja)の元で公開します。
C#/Linq で シーケンスの完全一致をチェックする

2つのシーケンスの内容を比較して、それぞれの要素がもう片方に必ず存在することを確認する

```csharp
using System.Collections.Generic;
using System.Linq;
public class Hello{
    public static void Main(){
        // Your code here!
        var l1 = new List<int>(){1,2};
        var l2 = new List<int>(){1,2};
        
        var result = l1.All(y => l2.Any(l => l == y)) && l2.All(y => l1.Any(l => l == y));
        System.Console.WriteLine(result);
    }
}

```
ウェブサイト作成用備忘録・１０号：二重発火防止メモ【コピペでプレビュー】

突然ですが…

１・ある要素をクリックすると、javascript（jquery）でクリックした要素にClassが追加され、CSSで設定した全体で２秒間のアニメーションが実行される。

２・同じ要素をもう一度クリックすると、最初のアニメーションが逆再生されて元の状態に戻る。（以降ループ…）

というコードを作成したとします。

仮に以下の様な内容の場合

```
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width,user-scalable=yes,initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<style>

  body {
    margin: 0;
    width: 100vw;
    height: 100vh;
  }

  #click {
    cursor: pointer;
    background-color: #000;
    transition: all 2s;
  }

  #click.on {
    background-color: #fff;
  }

</style>
</head>
<body id="click" class=""></body>
<script type="text/javascript">

  jQuery(document).ready(function(){

    $("#click").click(function() {
      $("#click").toggleClass("on");
    });

  });
</script>
</html>
```

上記のコードは画面をクリックする事で、２秒間掛けて背景色が変化するのですが…（コピペで確認可能です）

・javascriptが発火してから処理が完了するまでの時間は長く見積もっても0.05秒
・要素にClassが追加され、CSSアニメーションが完了するまでに2秒

javascriptとCSSの動作は独立している為、javascriptが発火してからアニメーションが完了するまであと1.95秒残っているのに、javascriptの方は次の入力を受け付けてしまう為、ダブルクリックしてしまうとアニメーションが完了する前に次のアニメーションが開始され、現在のアニメーションが中断されてしまいます。

この課題を解決する方法を自分なりに考えた結果…

対策
⇒クリック制限クラスとsetTimeoutと組み合わせる事で、CSSアニメーションが完了するタイミングまでjavascriptの処理を遅延させる

```
対策前
$("#click").click(function() {←クリックで発火
$("#click").toggleClass("on");←アニメーションクラスの切り替え
});
```
```
対策後
<style>
.lock {
  cursor: none;←カーソルの表示を変更
  pointer-events: none;←要素のクリックイベントを無効化
}
</style>
$("#click").click(function() {←クリックで発火
$("#click").addClass("lock");←クリック制限クラスを追加
$("#click").toggleClass("on");←アニメーションクラスの切り替え（CSSアニメーション終了まで２秒）
setTimeout(function(){ 
$("#click").removeClass("lock");
},2000);←CSSアニメーション終了（２秒）後にクリック制限クラスを解除
});
```
対策版はコチラ ↓

```
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width,user-scalable=yes,initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<style>

  body {
    margin: 0;
    width: 100vw;
    height: 100vh;
  }

  #click {
    cursor: pointer;
    background-color: #000;
    transition: all 2s;
  }

  #click.on {
    background-color: #fff;
  }

  .lock {
    cursor: none;
    pointer-events: none;
  }

</style>
</head>
<body id="click" class=""></body>
<script type="text/javascript">

  jQuery(document).ready(function(){

    $("#click").click(function() {
      $("#click").addClass("lock");
      $("#click").toggleClass("on");
      setTimeout(function(){ 
        $("#click").removeClass("lock");
      },2000);
    });

  });

</script>
</html>
```

最初はif関数で発火条件を指定してみたり、クリック要素そのものを削除したりと色々試行錯誤しましたが、現状ではこの方法が使い勝手が良いと感じました。

あくまで自分用のメモですが、参考になれば幸いです。
Tab Navigationのアイコン表示をすっきり書く方法

#はじめに
スマホアプリを作る際によく出てくるのがアイコンを使ったナビゲーション。
今回はReactNavigationの公式ドキュメントに載っているコードをすっきり見やすく書いてみたので紹介します。

＜使用するもの＞
・React Native
・NavigationContainer
・createBottomTabNavigator
・@expo/vector-icons

#公式
こちらの[公式ドキュメント](https://reactnavigation.org/docs/tab-based-navigation)ではこんな感じで書いてあります。(focusedは今回除きました)

```react
<Tab.Navigator
        screenOptions={({ route }) => ({
          tabBarIcon: ({ color, size }) => {
            let iconName;

            if (route.name === 'Home') {
              iconName = 'ios-information-circle';
            } else if (route.name === 'Settings') {
              iconName = 'ios-list';
            }

            // You can return any component that you like here!
            return <Ionicons name={iconName} size={size} color={color} />;
          },
        })}
        tabBarOptions={{
          activeTintColor: 'tomato',
          inactiveTintColor: 'gray',
        }}
      >
        <Tab.Screen name="Home" component={HomeScreen} />
        <Tab.Screen name="Settings" component={SettingsScreen} />
      </Tab.Navigator>
```
screenの名前をもとにif文で表示させるアイコンを分岐させています。

#すっきり書いてみた

```react
const TAB_ICON = {
    Home: 'ios-information-circle',
    Settings: 'ios-list',
};
const createScreenOptions = ({ route }) => {
    const iconName = TAB_ICON[route.name];
    return {
        tabBarIcon: ({ size, color }) => (
            <Ionicons name={iconName} size={size} color={color} />
        )
    };
};
```
createScreenOptionsをscreenOptions={}に入れてあげれば公式ドキュメントと同じ動きをします。
MySQL基礎（CREATE, INSERT）

postsデータベース作成
message, likesテーブル作成方法

```:ターミナル
DROP TABLE IF EXISTS posts; --もし、postsがあれば削除する
CREATE TABLE posts (
 message VARCHAR(140), --文字制限
 likes INT --整数
);

DESC posts; --postsテーブルの確認
SHOW TABLES; --データベースの確認

INSERT INTO posts (message, likes) VALUES --
  ('Thanks', 12), 
  ('Arigato', 4);

SELECT * FROM posts; --テーブル名(posts)中から全てのレコードを取ってくる
```
実行結果

```
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| message | varchar(140) | YES  |     | NULL    |       |
| likes   | int(11)      | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
+-----------------+
| Tables_in_myapp |
+-----------------+
| posts           |
+-----------------+
+---------+-------+
| message | likes |
+---------+-------+
| Thanks  |    12 |
| Arigato |     4 |
+---------+-------+
```
laravel asset関数でcssファイルと画像を呼び出す

#はじめに
HTMLでimgの表示とasset関数でimgを表示するのがごちゃごちゃになったので備忘録として投稿します。

#asset関数とは?
asset関数とはlaravelにあるヘルパ関数の一つになります。
[詳しくはlaravelの公式ページをご覧下さい。](https://readouble.com/laravel/6.x/ja/helpers.html#method-asset)
画像の呼び出し、URLの遷移として使用可能です。

#asset関数でimgを呼び出す方法?
asset関数はlaravelの`publicフォルダから見た時に、どこにあるのかを引数として指定する必要があります。`laravelのフォルダ構成はスクショの様になっています。
![“スクリーンショット” 2021-03-08 14.19.05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698439/ba5198e8-5941-ab88-baf1-4f5ffd115d32.jpeg)

#asset関数をどの様に記述するのか?
publicフォルダから見た時に、どこにあるのかを引数として書くには以下の様にします。

```index.blade.php
//cssファイルの呼び出し
<link rel="stylesheet" href="{{ asset('/css/bulletin-board/index-list.css') }}" >

//画像の呼び出し
<img src="{{ asset('/css/images/black-board.jpg') }}" >
```
#最後に
HTMLで`<img src="images/black-board.jpg">`で画像を呼び出せる方法は前から知っていたが知識が増えるとあれはどうなの?これはどうなの?と疑問が増えて試行錯誤の連続があると思います。一度整理してとりあえず書いてどの様に反映されるかを確認するキッカケとなりました。画像やcssファイルを呼び出すときはasset関数で統一するように調整してみます。

#参考文献
[Laravel 5、{{url}}と{{asset}}の違いは何ですか？](https://www.it-swarm.jp.net/ja/php/laravel-5%E3%80%81url%E3%81%A8asset%E3%81%AE%E9%81%95%E3%81%84%E3%81%AF%E4%BD%95%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F/826482487/)
Dockerを使ってDjangoの環境構築してみた

#はじめに
今回Dockerを使ってDjangoの環境構築をしたのでまとめてみたいと思います。
また、DjangoではデフォルトでSQLiteが入っているのですが、PostgreSQLで実装したので、その設定もdockerでやりました。何かの参考になれば嬉しいです。

#dockerfile
```dockerfile:dockerfile
FROM ubuntu:latest
RUN apt-get -y update \
    && apt-get -y upgrade \
    && apt-get install -y locales curl python3-distutils \
    && curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py \
    && python3 get-pip.py \
    && pip install -U pip \
    && pip install psycopg2-binary \
    && mkdir /code \
    && rm -rf /var/lib/apt/lists/* \
    && localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
WORKDIR /req
ADD requirements.txt /req
RUN pip install -r requirements.txt

# サーバーを立てる場所に移動(djangoのprojectを作成して以降)
WORKDIR /web-version/app
# これでbashとか使わずにrunするだけでサーバーが立つ
CMD  python3 manage.py runserver 0:8001
```
`FROM ubuntu:latest` : ubuntuの環境を持ってきています
`RUN` : 主な環境構築をします。ubuntu環境ではapt-getを使うことでいろんなものをインストールしたりアップデートしたりできます。
`WORKDIR` : フォルダを作成してそのフォルダに移動します。
`ADD requirements.txt /req` : requirements.txtをコンテナに持ってきます。保管する場所はreqフォルダの中です。

`WORKDIR /web-version/app`
`CMD  python3 manage.py runserver 0:8001` : この2行は、コンテナを立ち上げた時に、すぐにサーバが起動してほしくて書きました。manage.pyのあるフォルダに移動してサーバを立ち上げているだけです。
ただ、まだプロジェクトを作成していない段階で実行してもmanage.pyがないのでエラーが起きます。
なので、はじめは`CMD ["bash"]`として、シェルに入ってプロジェクトを作ると良いです。
また、runserverの後にポートを指定することで、全てのIPからのリクエストを受け付けることができて、コンテナからサーバを立ち上げても、localhostで開くことができました。
詳しくは、[djangoの公式サイト](https://docs.djangoproject.com/ja/3.1/intro/tutorial01/)をみてください。

```txt:requirements.txt
django
```

#docker-compose.yml
```yml:docker-compose.yml
version: "3"
volumes:
  db-data:
services: 
    web:
        build: .
        container_name: "web-django"
        ports: 
            - "8001:8001"
        volumes:
            - ".:/web-version/"
        # 下二行は-itと同じ役割
        tty: true
        stdin_open: true
        depends_on: 
            - db
    
    db:
        image: postgres
        volumes:
            - 'db-data:/var/lib/postgresql/data'
```
今回サービス名は`web`としました。
10行目の`volumes:`でカレントディレクトリを作成したweb-versionというフォルダにマウントしています。

`tty: true` `stdin_open: true`: これを指定してあげることで、dockerfileで実行する場合のオプション`-it`と同じ役割をしてくれます。
`depends_on` : これはコンテナを立ち上げる順番を決めています。今回は`- db`としているので、db,webの順番でコンテナが起動します。今回はwebというサービスがdbというサービスを参照する形になっているので、このようにしています。

`volumes: - 'db-data:/var/lib/postgresql/data'` : postgresqlではデータが`/var/lib/postgresql/data`に保管されます。そのデータをホスト側に保持しておくためにこれを書いています。なぜホスト側でデータを保持しておくのかというと、もしコンテナを消してしまうと、データも全て失ってしまうからです。失っても良い場合は書かなくても大丈夫です。
ホスト側の`db-data`に保持するのですが、そのフォルダを2,3行目の`volumes: db-data:`で作成しています。

これでdockerは終わりですが、djangoでpostgresqlを使うためにはdjangoのsetting.pyを変更する必要があります。

```python:settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'postgres',
        'PASSWORD': 'postgres',
        'HOST': 'db',
        'PORT': '5432',
    }
}
```

#終わりに
今回dockerを使ってdjangoの環境構築をしてみたのですが、やはりdockerは便利だなと感じました。(テスト環境とかデプロイ環境とかいろんなところでコンテナ使えばもっと便利に感じるはず)
ただこうやってアウトプットしてみてもまだ自分の知識が曖昧な部分があるので(runserverのポートの指定のところとか)、それをこれからもっと深堀りしてみたいです。
まだまだ初心者なので、間違っている点などありましたら、教えていただけると嬉しいです。
塚田真＋金子博＋小林ゆう治＋高橋眞映＋野口将人「Ｐｙｔｈｏｎで学ぶ線形代数学」の２．４で必要なwavファイルについての知識

# はじめに
塚田真＋金子博＋小林ゆう治＋高橋眞映＋野口将人「Ｐｙｔｈｏｎで学ぶ線形代数学」（オーム社2020年04月20日発行）の、２．４「応用：音を見る」を読む際に、音声ファイルに関する知識が無かったので、調べたことをまとめる。

#・音声ファイルの記録のされ方
　簡単な例として、モノラルで、同じ音が続く単音が、どのように音声ファイルとして保存されるかを記す。
![20210308_chord2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684864/dd65c93a-ac8a-e3e7-ff09-0a470826dcf0.png)

　図のような、単音があった場合、wavファイルのDataには、等間隔で取られた波の高さが１次元アレイで順に記録されていく。
[    0.          4097.65556042  8130.98100142 12036.6561382
 15753.36480003 19222.75744811 22390.3672196  25206.4650165
 27626.84021524 29613.49474026 31135.23960532 32168.18455721
 32696.11313482 32710.73725536 32211.82733111 31207.21587375
 29712.67452978 27751.66647754 25354.97807287 22560.23552641
... -12036.65613819  -8130.98100143  -4097.65556043]
　このように、同じ音が続く「単」音であるが、Dataに記録される値は常に変化している。

#・音声ファイルと、テキストデータや画像データとの違い
　音声データの特徴として、テキストデータや画像データと違って、データのうちの１ブロックだけを見ても、元の音は分からない、ということが挙げられる。
　同じ単語が並ぶテキストであれば、１文字を見ればわかるし、同じ色が並ぶ画像データであれば、１ドットのRGBを見れば全体が分かるが、音声ファイルでは、それができない。いくつかのまとまった単位でデータを読むことで、初めて音が分かる。

#・wavファイルのデータの持ち方について
続いて、wavファイルのデータの持ち方について。wavファイルは、音声の長さを、秒数としては持っていない。持っているのは、データそのものと、1秒間のサンプリング数であるビットレート。
本書ｐ７２のsound2.pyで言えば、wavファイルから、5行目でrateとDataを読み込み、7行目でDataの長さをrateで割って、音声の長さを求める。
rateは1秒間のサンプリング数。よって、同じDataを持つwavファイルであっても、rateが違うと、違う音（間延びしたりピッチが早い音）になる。
テキストファイルなどを読み込む時には、readメソッドにより、ファイルオブジェクトを１つ作成するのに対して、wav.readの場合は、戻り値として、レートとデータの２つを受けることになる。

以上のことを基に、「Ｐｙｔｈｏｎで学ぶ線形代数学」の本文について触れていく。

#ｐ７２の「sound2.py」について
次ページの３～４行目に出ている出力結果は、「Ｐｙｔｈｏｎで学ぶ線形代数学」のサポートサイト
https://scrapbox.io/linalg/2._%E7%B7%9A%E5%BD%A2%E7%A9%BA%E9%96%93%E3%81%A8%E7%B7%9A%E5%BD%A2%E5%86%99%E5%83%8F
にある音声ファイルmono.wavの結果（現時点では、リンク名の拡張子がwavではなくpyになっている）。
３行目の32768は、Dataの大きさ。この数値、32768は、すぐ下に出てくる、16ビットの整数値の範囲と同じだが、本来は無関係な数値。
４行目の1.48～、の数値は、32768／22025の結果である約1.5秒のこと。
１０～１１行目の出力結果は、同上のリンクにあるstereo.wavの結果。
１３行目と１６行目の、モノラルかステレオかを分けるif文は、読み込んだDataが、１本の音声トラックしか持っていなければモノラルとして==1へ、２本なら==2として分岐。Dataには、この音声がモノラルかステレオか、というプロパティは無く、トラック数で判断する

#ｐ７３の図２８について
図の上下方向を見ると、0を中心に、上下部分が塗りつぶされたようになっているが、これは、図の大きさに比べて、ビットレートの数が多いのが理由。本文にある通り、xlimの値を変更する（例：plt.xlim(0, t)をplt.xlim(0, 0.01)へ書き換える）と、グラフが拡大されて、ｘの１つの値に対して、ｙが１つ対応する折れ線グラフとなる。
なお、グラフの拡大については、グラフが表示されている時に、虫眼鏡アイコンをクリックして、グラフ部分をマウスで範囲選択して表示させることも可能。
ニジボックスで実施してきた研修

ニジボックスの研修を何個か企画して実施したので、その内容を紹介します。

# JavaScript 研修

https://www.wantedly.com/companies/nijibox/post_articles/203254

JavaScript の研修です。古川が担当しました。研修の内容としては JavaScript の基本文法から文法内容を使って簡単な関数を書くパートが前半、後半は小さいアプリケーションを何のフレームワークも使わずに書いてみるところまで、ほぼ丸一日かかる6時間の研修です。

リクルートの JavaScript Bootcamp の内容がベースですね。

https://speakerdeck.com/rtechkouhou/javascript-bootcamp

かなりインタラクティブな講義で、参加者がただ座学的に受けるというよりは、聞いた内容に対して質問してもらい、受けた質問から展開して、色々説明します。

イベントループの話みたいな若干マニアックな話から、ページネーションをどうやって実装するかという実践的な話もしてました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6031/0bc27a57-7335-e318-80a0-5847fdac2fc4.png)

この画像はページネーションをどうやって実装するかを解説してるところですね。
ページネーションの元ネタはここにまとまってます。

https://qiita.com/JSON_HardCoder/items/09b7c3136bdad36c4830

# スピードハッカソン

https://www.wantedly.com/companies/nijibox/post_articles/292188

こちらも既に記事になっていました。リクルートでも実際やっていた活動をそのままニジボックスに転用した感じですね。

スピードハッカソンは実際のサービスを使って高速化をするハッカソンです。 Lighthouse の性能のスコアで競います。

第一回目のスピードハッカソン研修では、ニジボックスのブログサイトを使って高速化しました。実際に高速化をしようとすると、チューニングのポイントがわかるだけじゃなく、ブラウザの中の動きやネットワークの動きなどを見るきっかけになり、それがフロントエンドのエンジニアリングの理解にも繋がるので非常に効果的な研修でした。

# JavaScript/TypeScript 研修

先週と今週(3/4と3/11)で行われている研修ですね。最初に JavaScript の研修をやった後、 TypeScript で作ったアプリを書き換えるという事をします。

リクルート内のメンバーが講師になり、一緒になって研修します。

![スクリーンショット 2021-03-08 11.37.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6031/f1e0d521-4aff-d8c5-dc1c-593a2a38e9de.png)

JavaScriptのコードを「あーでもない」「こーでもない」と一緒に議論しながら進めることができて、育成しながら一つのアプリケーションを TypeScript できっちりしたコードにするところまでを目指します。

# ニジボックス研修について

ニジボックスの開発現場は必ずしもモダンな開発現場ばかりではなく、むしろレガシーな環境のが多いです。ただし、その中でエンジニアリングが不要なわけではありません。レガシー環境であろうとモダンな環境であろうと、一般的な原理原則（テストをしっかり書く、コードの変更可能性を最小限にする、など）を理解している必要があります。

どんな現場に配属されたとしても役に立つような知識をインプットし、全体の底上げをしつつ、徐々に教えるレベルも上げていきたいと思っています。

次回以降の研修では、「ブラウザがどうやって動いてるか」や「フレームワークを入れずに作ったアプリをフレームワークを導入することでどう変わるか」といった基礎と応用の両方を教えられるようにしていきたいと思います。
小ネタ rspecでの比較を省略しないようにする

```
Failure/Error: expect(result).to be_a(Validation::Valid)
       expected #<Validation::Invalid value=#<Bundle id: nil, created_at: nil, updated_at: nil, action: nil, type: "B...on::Finder::NotFoundError: No feature_definition (site_linux) found for contract (hodor_contract)>]> to be a kind of Validation::Valid
```

この`…` が見れずにデバッグに苦労すること、よくありますよね。

以下のような設定を追加することで、`…` に切り替わる文字長を調整できるため、…が表示されなくなります。

```ruby
RSpec.configure do |config|
  config.expect_with :rspec do |c|
    c.max_formatted_output_length = 1000000
  end
end
```

参考: https://github.com/rspec/rspec-expectations/issues/991
GitHub Actions ReviewDog がエラー

ReviewDogをGithub actions経由で使っていたら急にエラーが発生

```
 Installing rubocop with extensions ... https://github.com/rubocop/rubocop
  ERROR:  While executing gem ... (Gem::FilePermissionError)
      You don't have write permissions for the /var/lib/gems/2.7.0 directory.
```

原因はubuntu-latetのデフォルトruby versionが 2.5.1から2.7.0に変わったこと。
https://github.com/actions/virtual-environments/issues/1816

```reviewdoc.yaml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: ruby/setup-ruby@v1
      with:
         ruby-version: 2.6.5 #マイクロバージョンまで指定可能
```


こんな感じでyamlにrubyのバージョンを指定するようにすればOK
他に指定できるバージョンはこちらから参照可能
https://github.com/ruby/setup-ruby
「this class is not key value coding-compliant for the key 〇〇."」が出たあなたへ。

「this class is not key value coding-compliant for the key 〇〇."」が出たあなたへ。

もしかして、StoryBoardに追加したオブジェクトが、ViewControllerとOutlet接続されていませんか？？？

だとすると今回のエラーが発生する可能性が高いので、オブジェクトを右クリックして❌ボタンで解除してみてください。

以上！！
プロセス間通信（パイプ）を試す

パイプってshellでよく使うけど、中身を知らないので試してみる。  

## 試すこと
引数で渡されたパスのテキストファイルを親プロセスが読み、pipe経由で子プロセスに渡し、lessがファイルディスクリプタ0番から利用する（はず）  

## ざっくり手順
1. pipe()でパイプ用のファイルディスクリプタを取得 ※forkより前に実行
2. fork
3. 親プロセスは パイプのファイルディスクリプタ.書き込み側 に出力
4. 子プロセスは 標準入力のファイルディスクリプタを閉じる
5. 子プロセスは パイプのファイルディスクリプタ.読み出し側 を複製する -> 0番（標準入力で使用されているファイルディスクリプタ番号）として複製される

## ソース
エラー処理とかexitとかやってません...  

```
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int 
main(int argc, char* argv[])
{
    FILE *fp;
    fp = fopen(argv[1], "r");

    int pipefd[2];
    pipe(pipefd);

    int pid;
    pid = fork();
    if (pid > 0) {
        // 親
        printf("parent %d\n", pid);

        char buf[4096];
        int n;
        while (fgets(buf, sizeof(buf), fp)) {
            n = strlen(buf);
            write(pipefd[1], buf, n);
        }
        waitpid(pid, NULL, 0);
    } else {
        // 子
        printf("chiled %d\n", pid);

        close(0); // 標準入力を閉じる
        dup(pipefd[0]); // pipefdの 読み出し側:0 を 標準入力:0 に複製する
        execl("/bin/less", "less", NULL);
    }
}
```

### コンパイル・実行
```
$ gcc -g ipc_pipe.c
$ ./a.out hoge.txt
```

## 補足 
### デフォルトのファイルディスクリプタ
0: 標準入力  
1: 標準出力  
2: 標準エラー出力  

### パイプのファイルディスクリプタ
0: 読み出し側  
1: 書き込み側  

## 所感
- 標準入出力前提のプログラムは入出力の切り替えが出来て便利
- [xv6のshコード](https://github.com/mit-pdos/xv6-public/blob/master/sh.c#L100) を読むことで、shellから利用するパイプの実現方法を理解できた

## 参考
- [詳解UNIXプログラミング ](https://amzn.to/3kTMsFm) 
- [はじめてのOSコードリーディング](https://amzn.to/3bq6kN7)
- [xv6のshコード](https://github.com/mit-pdos/xv6-public/blob/master/sh.c#L100)
SPSS Modelerコミュニティと連載ブログ


### SPSS Modelerコミュニティサイト


![ロゴ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/0ec26bc8-4836-4adc-87ab-3c3dcc30d1ac.png)


2025年よりIBM TechXchange Communityプラットフォームで情報発信を行なっています。
IBM IDでログインして　[JOIN]ボタンを押してメンバーになると期間限定アーカイブなどを視聴可能です。


https://community.ibm.com/community/user/usergroup?CommunityKey=5e746c4e-1ae3-4db4-a23c-153cf231fe73


ショートURLはこちら
https://ibm.biz/BdGsLq



### SPSSブログのバックナンバー

2024年までIBM Solution Blogで連載した以下のシリーズはコミュニティサイトに移設しました。

・データ分析者達の教訓　全22回
・SPSS Modeler ユーザーイベント開催レポート
・ブログで学ぶSPSS Modeler 全13回
・身近な疑問をヒモトク　全12回
・Modelerデータ加工Tips　全23回
・わたしの推しノード　全24回

https://community.ibm.com/community/user/blogs/yoichiro-nishimaki/2024/12/20/menu


### SPSS Modelerの歩き方2025 Event & Tips

2025年のSPSS Modelerイベントを案内しています。

https://community.ibm.com/community/user/blogs/yoichiro-nishimaki/2024/12/29/spss-modeler-event-tips

### Qiitaでも引き続き以下の記事を更新しています

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
SPA/SSR/SSGのメモ


## SPA（Single Page Application）

![スクリーンショット 2021-03-08 9.17.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631580/6809113c-2720-28ac-d117-91ee9d93d79e.png)



初期表示はページをサーバーにリクエストします。この時渡されたJSファイル等をクライアント側で読み込んで表示させます。

2回目以降に更新がかかったら必要な差分をデータで持ってきて表示させます。
このことにより、画面遷移せずに1つのページ上で異なる表現が可能になり、ページまるごとサーバーに要求することなく必要な部分だけを貰えるので、通信量を抑えることが出来ます。
ですが初期表示の際はJSコードが多くなってしまうので、遅くなってしまうというデメリットがあります。



## SSR（Server Side Rendering）

![スクリーンショット 2021-03-08 9.17.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631580/c10cf17f-a3f5-aa6a-0a3f-530151cb10ff.png)




SPAとは違い、クライアントではなくサーバー側でファイルを完成させてから持ってきます。
これによりクライアント上でのレンダリング時間がないため、ブラウザ上で速く表示できたり、通信環境に左右されにくいメリットがあります。
その反面、サーバー側でページを生成するので負荷がかかってしまいます。



## SSG（Static Site Generator）

![スクリーンショット 2021-03-08 9.18.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631580/267eae21-ac26-3cba-e54c-c61c9c05def1.png)



ビルド時に事前に表示する際必要なデータを取得しておき、静的なHTMLを生成します。（プリレンダリング）
返却時にはこの生成した静的ファイルを返します。

ページを完成したまま持っているので、ページ表示までの時間はSSRよりも速いです。
ですがページ量が多かったらビルド時間がかかってしまったり、更新の頻度が高いサイトだと毎回ビルドしなければ反映されないので不便です。
フロントエンドVue.js バックエンドFlaskの開発で躓いたこと色々

##GoogleのOAuthをする場合
元々はFlaskのみで実装していたプロジェクトだったのだが、途中からフロントエンドをvue.jsに引き継いだため、OAuth部分をFlask側のコードで実行しようとしていた。
これだとCORSエラーが出てしまう。
CORSエラーへの対応について調べてみると、Flask,Vue.jsともにCORS対応方法についての文献がでてくる。
しかしこれをやっても超えられない。何故か。

色々と探してみたのだが、そもそもそういう使い方は出来ないっぽい。探しすぎてソースを見失ってしまったが、つまりそういうことだったんだと思う。
素直にVue.js側でvue-google-oauth2を使った実装を行う事によってVue．js→Google→Vue.jsという通信によってtokenが取得できるのでそれを使う。

##認証されないGoogleAPIキー
これはそのままこれ
https://qiita.com/kenken1981/items/9d738687c5cfb453be19
>どうも、Google認証の「OAuth 2.0 クライアント ID」は、一度あるポートで使うと、その後で違うポートで利用することはできないらしい。

ということで、別途フロントエンド用のキーを作って、vue.js側のポートを指定することで解決。

##認証されないGoogleAPIキー2
承認済みの JavaScript 生成元
については、127.0.0.1 は使えない。
https://qiita.com/kenken1981/items/b6cb3e536668a3cef520
>Google認証は、「127.0.0.1」というIPアドレスは認めておらず、「actual urls」というらしい？いわゆるaaa.jpやbbb.comといった形式でないとエラーを返す模様。

##Vue.js側で環境変数が読み込まれない
Vue.js側は yarn build することでdistフォルダに静的ファイルを吐き出す形で利用しているのだが、どうもVue.js側で環境変数を読み込んでくれない。
.envに書いてあろうが読み込まれない。何故か。

buildする時に、その設定が必要だった。
詳細についてはここにある通り。
https://qiita.com/go6887/items/2e254d31b5a4af42f813

vue.js　が
/frontend
内に入っていて、/frontoend でビルドコマンドを打つ形にしてありましたが
/frontend/.env.development
というファイルを作って、中に変数を記述。

package.json には
    "build": "cross-env NODE_ENV=development vue-cli-service build --mode development --dest ../dist",

みたいな形に書いておく事によって環境変数が読み込まれた。

## 変更履歴
2021/3/8 初稿up
MySQLにアクセスする時に発生する例外の対処法

MySQLにアクセスしようとしたら拒否されて例外が発生してアクセスできなかったので、色々と調べました。

```
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
```

どうやらrootユーザが設定されていなくてこのようなエラーが発生することがあるようです。

このエラーが出た時はまずMySQLを停止してから、オプション付きで起動することによって解決しました。

１、まずは一旦停止します。

```
# service mysqld stop
```

2、次にMySQLを–skip-grant-tablesオプション付きで起動します。
これはMySQLの権限システムを使用しないで起動するためのものだそう。

```
# mysqld_safe --skip-grant-tables &
```

僕の場合はこれで解決しました。
Javascriptの配列とObjectのコピー関連メモ

自分用のメモ

# Array
ポインタ有りの場合

```js
const arr1 = ['a', 'b', 'c', 'd'];
const arr2 = arr1;
arr2[0] = 'e';

console.log(arr1); //- ['e', 'b', 'c', 'd']
console.log(arr2); //- ['e', 'b', 'c', 'd']
//- arr1[0]も同じ値になる
```

ポインタ無しの場合

```js
const arr1 = ['a', 'b', 'c', 'd'];
const arr2 = arr1.slice();
arr2[0] = 'e';

console.log(arr1); //- ['a', 'b', 'c', 'd']
console.log(arr2); //- ['e', 'b', 'c', 'd']
//- arr1[0]とは同じ値にならない
```

# Object
ポインタ有りの場合

```js
const obj1 = {
  data1: 'a',
  data2: 'b',
  data3: 'c',
  data4: 'd'
};
const obj2 = obj1;
obj2.data1 = 'e';

console.log(obj1); 
/*
{
  data1: 'e',
  data2: 'b',
  data3: 'c',
  data4: 'd'
}
*/
console.log(obj2); 
/*
{
  data1: 'e',
  data2: 'b',
  data3: 'c',
  data4: 'd'
}
*/
//- obj1.data1も同じ値になる
```

ポインタ無しの場合

```js
const obj1 = {
  data1: 'a',
  data2: 'b',
  data3: 'c',
  data4: 'd'
};
const obj2 = Object.assign({}, obj1);
obj2.data1 = 'e';

console.log(obj1); 
/*
{
  data1: 'a',
  data2: 'b',
  data3: 'c',
  data4: 'd'
}
*/
console.log(obj2); 
/*
{
  data1: 'e',
  data2: 'b',
  data3: 'c',
  data4: 'd'
}
*/
//- obj1.data1とは同じ値にならない
```
Modelerデータ加工Tips#02コード

## Modelerデータ加工Tips＃02 出題用サンプルコード


```ruby:python
stream = modeler.script.stream()
node1 = stream.create("userinput", "Input")
node1.setXYPosition(100,100)
node1.setPropertyValue("names", ["Time","Temperature"])
node1.setKeyedPropertyValue("data", "Time", "1;12")
node1.setKeyedPropertyValue("custom_storage", "Time", "Integer")
node1.setKeyedPropertyValue("data", "Temperature", "11 12 13 14 15 16 18 20 22 24 26 28 ")
node1.setKeyedPropertyValue("custom_storage", "Temperature", "Integer")
node1.setPropertyValue("data_mode", "Ordered")

node2 = stream.create("filler", "Filler")
node2.setXYPosition(300,100)
node2.setPropertyValue("fields", ["Temperature"])
node2.setPropertyValue("replace_mode", "Conditional")
node2.setPropertyValue("condition", "Temperature = 13 or Temperature = 14 or Temperature = 20 or Temperature = 22") 
node2.setPropertyValue("replace_with", "undef")

stream.link(node1, node2)
```

出題は以下

https://www.ibm.com/blogs/solutions/jp-ja/modeler-tips-02/
xamppでhtdocsの配下にソースを置かずにデプロイする

# この記事は？
xamppでhtdocsにソースを配置することでデプロイされますが、ソースは別の場所に配置したいということがあると思います。この記事ではソースを別の場所に配置してもデプロイできるようにする方法を紹介します。
# 難しいポイント
簡単に対応しようとするときにはショートカットをhtdocsに配置すれば行けるのではないかと考えると思うのですが、ショートカットを配置してもデプロイされません。ポイントはhtdocs内にソース配置場所の**シンボリックリンク**を張ることで対応可能という点です。
# 対応方法
コマンドプロンプトでhtdocsのディレクトリ内で以下のコマンドを実行すれば対応可能です。
※{}で囲まれている中身は内容で置き換える

```
 mklink /d {htdocs内のディレクトリ名} {ソースの配置場所}

 例) htdocs内にtestディレクトリを作成し、C:\sorce\testのソースでデプロイする場合
 mklink /d test C:\sorce\test
```

# 終わりに
案外はまるので備忘がてら記載しましたが、簡単に対応可能です
big surでopenwrtをbuildするならhomebrewではなくmacportsが良いみたい

時間が解決する問題ですが・・・。

ubuntuでは問題ないのに、big sur+homebrewでは、不安定。
macportsにしたら問題なくいけたという話。
本家wikiには現在はhomebrewしかなかったのでメモ。

元は[これ](https://openwrt.org/docs/guide-developer/build-system/buildroot.exigence.macosx)。
brewの部分をinstall_port.shに。env.shを下記の内容に置き換えるだけ。

```zsh:install_port.sh
sudo macport install coreutils gnutar findutils gawk grep wget getopt xz ncurses pkgconfig ld64 gettext md5sha1sum subversion binutils gmake
```

```zsh:env.sh
PATH="/opt/local/libexec/gnubin/:$PATH"
export PATH
export DYLD_FALLBACK_LIBRARY_PATH=/opt/local/lib
```

余計なportが入ってるカモ。
DCASE2020、task2、fan、について

昨年の夏前にこちらに投稿しましたある信号処理の方法（信号源に
「非線形性」が作用してることを仮定し、各帯域間が独立していない
場合に、観測信号で得られる局所的な位相の進み遅れ量を用いて原信号を
回復する：
 https://sigprocrandwalk.hatenadiary.org/entry/20170722/1500751760 ）
を用いて、標題の実測データ
（ http://dcase.community/challenge2020/index ）
に対して処理を行ったところ、面白い結果が得られたので紹介させて
いただくことにしました。

「DCASE2020のtask2のfan（実測データ）」に対して「局所的位相シフト検出法」を行った場合
 URL : https://sigprocrandwalk.hatenadiary.org/entry/2020/12/16/101552


自然の信号源に「非線形性が作用していて相互変調の状態になっている」ものが
多くあると良いなと期待しています。
興味を持っていただければ幸いです。
もし疑問などあれば、こちらか、もしくはメールをいただければ
お答えいたします。
では失礼いたします。

園部和夫 [ aka SigProcRandWalk | SPRW , mailto : fuja2_at_bj8.so-net.ne.jp ]
[Rails]Rspecでログインユーザーを作成する方法

## はじめに
- 自分が初めてRspec（リクエストスペック）を実装した時につまづいた。同じ人のために、記事録として作成しています。


## 課題
- 200を期待しているが、302が返る

```rb
it "リクエストが成功する" do
  subject
  expect(response).to have_http_status(:ok) #=> found(302)
  #=>ok(200)を期待しているが、 found(302)が返る
end
```

## 原因
- ログインユーザーではない場合、リダイレクトする`before_action`を設定している

## 解決策
- ユーザーをログインさせる

## 実装
①設定
以下のファイルにコードを追加する

```rb:rails_helper.rb
RSpec.configure do |config|  
  #以下を追加
  # リクエストスペックで Devise のテストヘルパーを使用できるようにする
  config.include Devise::Test::ControllerHelpers, type: :controller
  config.include Devise::Test::IntegrationHelpers, type: :request
  # 以上を追加
end
``` 
②ユーザーをログインさせる
1.`before do ~ end`でログインユーザーを作成(テストデータはusers.rbで作成)
2.`sign_in @user`でユーザーをログインさせる

```rb:xxx_request_spec.rb
RSpec.describe "xxx", type: :request do
  # ログインさせるユーザーを作成
 + before do
 +   @user = create(:user)
 + end
 
  # 略

  it "リクエストが成功する" do
    # 先ほど作成したユーザーをログインさせる
  + sign_in @user
    subject
    expect(response).to have_http_status(:ok)
  end
end

```


before

```rb
it "リクエストが成功する" do
  subject
  expect(response).to have_http_status(:ok) #=> 302
  #=>ok(200)を期待しているが、 found(302)が返る
end
```



after

```rb
it "リクエストが成功する" do
+ sign_in @user
  subject
  expect(response).to have_http_status(:ok) #=> 200
  #=>ログインしている為、before_actionにかからなくなり、ok(200)が返る
end
```

## 今回のまとめ
- テストを実行するとリダイレクトされてしまう（200 => 302）
- 原因は`before_action`で未ログインユーザーはリダイレクトするようになっている為。
→ユーザーをログインさせる必要がある
- ユーザーをログインさせるには、`sign_in`を使用できるようにする必要がある
- `sign_in`を使用するには、`rails_helper.rb`に設定を記述する必要がある
AWS RedShiftを学んでみた

(追記していきます。)

# AWS Redshift

https://aws.amazon.com/jp/redshift/?whats-new-cards.sort-by=item.additionalFields.postDateTime&whats-new-cards.sort-order=desc

いわゆるデータウェアハウスですね。
PostgreSQLを拡張したものです。

- フルマネージド
- 高速でスケーラブル
- PostgreSQL互換
- 列志向データモデル
- 複数ノードをまとめたクラスター構成

## そもそもデータウェアハウスとは

https://ja.wikipedia.org/wiki/%E3%83%87%E3%83%BC%E3%82%BF%E3%82%A6%E3%82%A7%E3%82%A2%E3%83%8F%E3%82%A6%E3%82%B9

(クラスターについてもう少し書く)

# RedShiftって何に使うの？
大容量データを高速に集計分析する必要があるワークロードに活用
- 経営ダッシュボード
- 定型レポーティング
- アドホック分析
- ETL/バッチ
- 機械学習の前処理

### ETLとは
Extract（抽出）/Transform（変換）/Load（格納）。
の略で、データ統合時に発生する各プロセスの頭文字をとったもの

## 構成
- リーダーノード(クエリのエンドポイント)
- コンピュートノード(クエリの実行)
- マネージドストレージ

## データ
データはユーザー管理のS3を通してロード・アンロード

## 課金
- 一般的なデータウェアハウスよりは安いはず
- １テラバイトあたり年間1000USDで利用可能
- コンピュートとストレージの支払いが分類

## インスタンスタイプ
- RA3インスタンス
- DC2インスタンス

## 列志向
- 高速にI/O処理できる
- RDSは業務用データベースで行志向
  - 行志向は全ての行にアクセスする必要がある
  - 不必要なディスク I/Oが発生
- RedShiftは分析用なので列志向
  - 非強王な列のみスキャン
  - 不必要なディスク I/Oを削減
- これのおかげでハイパフォーマンス
- 列ごとにデータを格納しているため、類似したデータが集まり高い圧縮率



## マテリアライズドビュー
TBW

## 機械学習
TBW

## ワークロード管理
ワークロードとは、定義されたプロセスを集合的にサポートするIT資産のまとまり

### キューとスロット
- キューを複数個作成可能
- 各キューにはクラスターが使用できるメモリの一部を割り当てる
- 自動でワークロード管理可能

## スケーリング
- 32個までノードを追加
- クラスターの追加もできる

# 未整理
- データはS3バケットに保存
- S3との関係

# コストについて
https://blog.trocco.io/dev-articles/redshift-cost-cut-best-practice
swiftの基礎の基礎④〜画面遷移の種類〜、ナビゲーションバーの作成〜

###備忘録

①**プッシュ遷移**
横にスライドする遷移のこと。

viewcontrollerをライブラリより選択。
![スクリーンショット 2021-03-08 12.53.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782402/584baa3f-0a3c-3caa-b5d2-fd88f15da01f.png)

こんな感じに真横に配置し、（viewcontrollerは背景色グレーの方）遷移先の画面の作成をする。

1.HELLOを選択し、controlを押しながら、グレーの方へドラックアンドドロップすると画像のような黒い選択が出現。

2.Showを選択

![スクリーンショット 2021-03-08 12.51.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782402/8ae25534-d136-b425-9f06-ec523566746c.png)

・プッシュ遷移完了すると、画像のように真ん中に矢印が出てくる（セグエsegueと呼ぶ）
![スクリーンショット 2021-03-08 12.57.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782402/d34df44a-4e29-2a44-9452-1ba322ef22a7.png)




②**モーダル遷移**
下から上へ覆い被さるように画面が出てくる遷移のこと。
閉じる際は上から下に画面が消えていく

1.プッシュ遷移の１までは同じように進める。

２.プッシュ遷移の時はshowを選択したが、モーダル遷移の時はPresent Modallyを選択。
![スクリーンショット 2021-03-08 13.02.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782402/7962826f-8f04-6440-1131-aea8e5d4d131.png)

３.モーダル遷移完了！

4.戻るボタンを実装したい時は・・・
紐付けてこのコードを書くと・・・

![スクリーンショット 2021-03-08 13.09.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782402/cbe7b1df-97a5-982b-aa54-daa81106ea4d.png)
![Something went wrong]()


戻れるようになった！

ナビゲーションバーの作成
①バーの選択
![スクリーンショット 2021-03-08 12.36.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782402/d3704e6e-003b-360d-ebac-e889b2d7a897.png)


②NavigationController選択
![スクリーンショット 2021-03-08 12.37.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782402/5135735f-b74d-9735-5d71-275a9bed2c15.png)

③画面二つ出てくる。
titleを選択した状態で、Bar Tintの色を変更するとナビゲーションバーの色も変更される。
![スクリーンショット 2021-03-08 12.40.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782402/2516c338-b6f7-3e07-8f59-d4215f683d39.png)
React Native(Expo + TypeScript)用にEslint,Prettierの設定をする

プロジェクト毎に設定するが、毎回忘れてしまうため自分用のメモとして作成
[Javascript用の設定はこちら](https://qiita.com/icryo/private/0aeee10dd25e885b0016)

##ESLintとは
Javascriptの静的検証ツール
ESLintを使用すると、誤字、セミコロン、クオート、未使用の変数やブロックなど開発中に気づきにくいミスが見つけやすくなります。

##ESLintの導入
###VSCodeの拡張機能からESlintをインストールする
![スクリーンショット 2021-09-28 23.25.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927110/caab7eac-85f6-f58a-0bdf-491fffc7feb9.png)

###インストール

```
yarn add -D eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react-hooks
```

###初期設定
初期化して.eslintrc.jsファイルを生成

```
npx eslint --init
```

以下の設定で、質問に答えていく

```
√ How would you like to use ESLint? · To check syntax, find problems, and enforce code style
√ What type of modules does your project use? · JavaScript modules (import/export)
√ Which framework does your project use? · react
√ Does your project use TypeScript? · Yes
√ Where does your code run? · node
√ How would you like to define a style for your project? · prompt
√ What format do you want your config file to be in? · TypeScript
√ What style of indentation do you use? · 4
√ What quotes do you use for strings? · single
√ What line endings do you use? · unix
√ Do you require semicolons? · Yes
```
###.eslintrc.js を修正

```js:.eslintrc.js
module.exports = {
  env: {
    es2021: true,
    node: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:@typescript-eslint/recommended',
    'prettier',
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 12,
    sourceType: 'module',
  },
  plugins: ['react', '@typescript-eslint', 'react-hooks'],
  rules: {
    indent: ['error', 2],
    'linebreak-style': ['error', 'unix'],
    quotes: ['error', 'single'],
    semi: ['error', 'always'],
    'react-hooks/rules-of-hooks': 'error',
    'react-hooks/exhaustive-deps': 'warn',
    'react/display-name': 0,
    'react/prop-types': 0,
  },
  settings: {
    react: {
      version: 'detect',
    },
  },
};
```
##Prettierとは
コードフォーマッター（ソースコードを整形してくれるツール）のこと。読み方はプリティア。

##Prettierの導入
###VSCodeの拡張機能からPrettierをインストールする
![スクリーンショット 2021-09-28 23.27.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927110/8df93c1e-14ab-24b9-2ba5-47cdbf6f297e.png)


###インストール

```
yarn add -D prettier eslint-config-prettier eslint-plugin-prettier
```
###.prettierrc.js を追加

```js:.prettierrc.js
module.exports = {
  jsxSingleQuote: true,
  singleQuote: true,
  trailingComma: 'all',
  printWidth: 100,
  endOfLine: 'lf',
};
```



##.vscode/settings.json を追加
これを設定することで、Ctrl＋sでファイルを保存する際にコードフォーマットしてくれるので便利

```json:settings.json
{
    "editor.formatOnSave": true,
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true
    },
}
```