OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】createメソッドとnew + saveメソッドの違い

#環境
・Rails 6.0.3.2
・mysql Ver 14.14 Distrib 5.6.47
・osx10.15

#はじめに
`Rails`で`Contoller`を学ぶと`new`,`save`,`create`,`destroy`などの`Active Recordメソッド`を学びます。
その時に`createメソッド`は`new`+`save`と学びました。

初心者の私は「じゃあ`create`の方が簡潔で見やすいからコッチを使うんだ！」と勘違いしていて自身のアプリを作成した時に`create`を用いてうまく動作しないことがあったので、その時の学びを書きます。

#new + saveに分ける理由は？
要は`createアクション`で`createメソッド`を使わずに`new`+`save`を用いるときはどんなとき？
例えば、コントローラー内の記述

```ruby

def create
  @message = Message.create(message_params)
end
```
ではなく

```ruby
def create
  @message = Messages.new(message_params)
  @message.save
end
```
こっち。

#①ifなどを使った条件文を記載するとき
```ruby
def create
    @message = Messages.new(message_params)
    if @message.save
      redirect_to("該当パス")
    else
      flash.now[:alert] = 'メッセージを入力してください。'
      render :index
    end
end
```

上記にように条件文を使用する際に**new**+**save**と分けます。

下のように`create`を使うとうまく条件文が動作せず`else`後の作成失敗時に動作がうまく動かない。

```ruby
def create
  if Messages.create(message_params)
    // 成功時の処理
  else
    // 失敗時の処理
  end
end
```

これだと`create`に失敗しても`オブジェクト`を返すためif文が
**true**となり成功時の処理を行なってしまうからです。

また記述が多くなると分けた方が見やすい点もあります。

#②renderを用いるとき
`new`を記載しておくとその時作成したインスタンスメソッドを`render`で使うことができる。上記の例にはないが:idを引き継いで利用したい場合も`new`を記載した方がよい。

#最後に
どちらでも意味は同じと言われるとどう違うのかと気になったので、また自分のミスもあったのでここに記しました。
定時バッチ処理の成否を監視する

cronなどで実行する定時バッチ処理って仕込んだ直後は動作を確認しますけど、そのあとはそこまで気にしません。しかし、運用しているサーバでは様々な設定変更が行われるため、いつの間にかバッチがこけてしまっていたということがあります。

ではバッチの実行結果を通知しようというアイデアがあります。cron では MAILTO を設定すれば実行結果をメールしてくれます。最近ではメールではなく Slack に通知するほうが多いでしょうか。しかし、これは二つの問題があります。

一つ目は、監視するサーバが増えバッチ処理も増えてくると、運用担当者のメールボックスは完了通知メールで溢れかえってしまうことです。一つ一つに目を通して確認することは不可能です。メールソフトでフィルタリングして失敗した通知メールだけをチェックするなどの対応が必要になります。

もう一つは、実行自体が行われなかったことを検知できないことです。運用担当者がメールが来てないことに気付かない限り無理ですね。

これらの問題を解決するため、運用監視ツールでバッチ処理の成否を監視するという方法を考えました。大抵の運用監視ツールでは監視対象サーバから能動的に送られるステータスの監視も行えます。ステータスが失敗になったらアラートをあげるのですが、それとは別に一定期間ステータスを受信していない場合にもアラートを上げるわけです。

というようなアイデアを以前から考えていたのですが、なかなか実際に試す機会がないため、ひとまずアイデアだけ書き出してみました。実際に試せたら、また記事にします。

(2023/8/15追記)

ようやく実際に試すことが出来ました。

https://qiita.com/saoyagi2/items/02907e91b28255e7b832
Laravel 要点メモ

## 内容
Laravelで個人的に忘れそうな点についてのメモです。
(随時更新していく予定です。)

## コントローラ
### EagerLoad (N+1回避)
```SampleController.php
$sample = Sample::with(['user'])->find($id);
```

### コントローラのupdateメソッド
```SampleController.php
// SampleRequestというFormRequestでバリデーションしている場合
public function update(SampleRequest $request, $id)
{
  // 処理
}
```

### 動作環境がローカルかどうかの判定
```SampleController.php
if (app()->isLocal()) {
  // 処理
}
```

## Collectionクラス
- Illuminate\Support\Collectionクラス (基本)
- Illuminate\Database\Eloquent\Collectionクラス
    - Eloquentが複数のレコードをリターンする場合。
    - Eloquentコレクションオブジェクトは基本のコレクションを継承している。

## クエリビルダ
### DB::rawメソッド
クエリを文字列として挿入するため、SQLインジェクションの脆弱性を生む危険性があるため、使用は控える。
【PHP】オブジェクトと連想配列の違い

スクール時代に配列、オブジェクトの概念はそれとなく理解していたつもりでしたが、
実務の中で配列、連想配列について考える事が多く、特に【連想配列】についての理解があまりなかったので、自分向けに簡単にまとめて見た。

## オブジェクトと連想配列
これがオブジェクト。


```PHP:index.php
class object{
    public $name = "サトシ";
    public $age = 30;
}
```
オブジェクトはオブジェクト名を書いて、 { } の中に値を入れます。
オブジェクトの中には変数や関数を書く事が出来ます。また、変数のことをプロパティと呼びます。

そして↓が連想配列ですね。

```PHP:index.php
$array = [
    "name" => "カスミ",
    "age" => 29,
];
```

keyとvalueが => ダブルアロー演算子（ハッシュロケット）で組み合わさっています。


## オブジェクトと連想配列の使い方
```PHP:index.php
class object{
    public $name = "サトシ";
    public $age = 30;
}
 
//オブジェクトをnewする
$object = new object;
 
//オブジェクトの中身を表示
dd($object);
 
//オブジェクトは -> で
echo $object->name;
```
オブジェクトの呼び出しについては、アロー演算子からのプロパティを指定することで、呼び出すことができます。

```PHP:index.php
$array = [
    "name" => "カスミ",
    "age" => 29,
];
 
//連想配列の中身を表示
dd($array);
 
//keyは [] で呼び出す
echo $array["name"];
```
この時点で全然使い方が違いますね。

実務の中では連想配列を配列に、連想配列をオブジェクトに、と、
状況に応じて使い分けがよく発生するので、また別の記事で変換の仕方についてもまとめたいと思います。
ララベルで文字数カウントする

###ララベルでの文字数カウント
ワードなどであるかもしれませんが文字を入力したときに文字数が何文字なのかが出てくることがあると思います
今回は文字を入力しているときに今何文字なのかがわかるようにしたいと思います！

```app.blade.php
<head>
        <script language="JavaScript" type="text/JavaScript">
             
                function ShowLength( str ) {
	            str=str.replace(/\n/g, ""); 
                document.getElementById("inputlength").innerHTML = ""+ str.length ;
             }

        </script> 
        
        
</head>
```
まず共通となるapp.blade.phpに記述します

```form.blade.php

            <p id="inputlength" style="margin-bottom:0px;">0</p>
            <textarea contenteditable class="form-control" onkeyup="ShowLength(value);" name="content" rows="5">{{ old('content') }}</textarea>
            
```
次にこのように記述します
今回はtextareaに文字数カウントを指定しています
カウントの部分はid="inputlength"ですね
※文字の配置などは個人で好きなとこに調整お願いします
![スクリーンショット 2020-08-26 22.48.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696811/32db4e28-295e-7c72-078d-c4f1ec5bd2c6.png)

このように作動していたら大丈夫です！
あとは配置を好きに調整してください！
###まとめ
今回はform.blade.phpに書きましたが自分が使いたいところに書いてくださいね！
PHPでJavaScriptのアラートを表示させる

#プログラミングの勉強日記
2020年8月26日
PHPでAlertを表示させる方法を学んだので、まとめる。

#アラートとは
　Webサイト側からメッセージが表示させる機能のこと。JSで書くことができる。このメッセージはユーザに対しての警告文。アラートを簡単に実装できるのがJSのalertになる。

#JSのalertを表示させる方法
　JSでは以下のように簡単なプログラムでアラートを表示できる。

```js
alert(‘表示させたい文字列もしくは値’);
```

　HTMLでは以下のように書くことでalertを表示できる。

```html:html
<!DOCTYPE html>
<html lang = "ja">
  <head>
    ...
  </head>
  <body>
    <script>
      alert('アラートのメッセージ');
    </script>
  </body>
</html>
```

#PHPでJSのalertを表示させる方法
　JSはPHPとは異なる言語ではあるが、PHPからJSの操作をすることができる。具体的には、`$alert`に表示させる文字列を代入してそれを表示させる。

```php
<?php
$alert = "<script type='text/javascript'>alert('メッセージ');</script>";
echo $alert;
?>
```
　`<script type='text/javascript'>～</script>`の部分がJSを動作させるために重要な部分で`～`で書いた部分がJSのプログラムとして動作する。


#参考文献
[JavaScriptでalertを使ってアラートを表示させる方法【初心者向け】](https://techacademy.jp/magazine/5486)
[PHPのアラートの出し方を学ぶ！シンプル解説で簡単理解](https://www.sejuku.net/blog/80747)
Unity×ARcoreで空間上に絵を書く

## はじめに
 「Jsut a line」的な何かを作ったので、アウトプットをなぐり書きをする。
　ARCoreが想像以上に凄かった。

## 参考にしたサイト様

- 今回実装したのは[こちら](https://www.slideshare.net/ssuserc0d7fb/arcorefacetracking-136448820)を参考にしました．
- [こちら](https://heartbeat.fritz.ai/the-subtle-art-of-making-lines-in-augmented-reality-using-arcore-and-unity3d-e26718dffa03)は英語ですが似たことをしています

## 開発環境
- MacBookPro OS Catalina
- ※ Unity 2018 
- ARCore SDK for Unity v1.18.0

※ 2019ではDIINotFoundのエラーが出ました。現在も動作しないかもしれません。

## 実装
 上記の参考にした記事がとても親切なので詰まったところだけを補足。

- ARcoreSessionについて```Session config```の他に```Camera Config Filter```が必要
    - 右クリック->Create->GoogleARcore->Camera Config Filter で生成可能
- ビルド時に```OpenGLES3```のみでしかビルドできないとエラーが出る
    - File->BuildSettings...->PlayerSetting->OtherSetting の中で```Auto Graphic API```のチェックを外して```OpenGLES2```を選択してマイナスを押すと解決

## 終わりに
記事がとにかく丁寧で迷わずに実装できました。著者の方にこの場をお借りして御礼申し上げます。
pythonでdefを使って見よう

#この記事の対象者
・プログラムで言う関数がどう言う意味かわからない人
・defの使い方が話からいない人
※今回の実行環境は**GoogleColaboratory**です。

#関数とは何者？
関数は数学で習った物とはまた別のものです。手短に説明すると、長いプログラムを書いていると何回か同じような処理を複数回使う事があります。そこで繰り返し使うプログラムを**def**でまとめる事でプログラムを短く分かりやすく計算する事が出来ます。つまり関数はよく使うプログラムをdefに名前を使って呼び出す事がでいつでも使えるようになっています。実際に皆さんがよく使っているもので例を上げると **print()**関数です。文字をコマンドに表示させるにはもっと長いコードを書く必要がありますが、それをpython側で関数として定義しているおかげでこちらはprint関数のカッコ内に表示したい文字を表示するだけで、コンソールに文字を表示出来る訳です。

#実際にコードを書いて見よう！！
始めに完成形のコードを出しますのでそれを見ながら解説して行きます。

```python
def say_hello():
  print('hello')

say_hello()
```
関数の始めは**def**と書きスペースを一つ開けて自分の好きな名前その後に**():**をつけて関数の定義は完了です。()には関数内で使える変数のようなものを宣言できます。これを引数と呼びます。ここはつけなくても関数を動かす事が出来ます。次に二行目の解説です。インデントをつける事で関数内のプログラムであるとpythonが認識する事が出来ます。(関数が実行された時はこのインデントをつけたところが実行されます)最後に三行目です。ここでは関数を実行させるプログラムを書いています。つまりこのコードは**say_hello**と言う関数を実行しろと言う命令になっています。これが関数の基本的な書き方です。
⒈関数の定義は　[**defスペース好きな名前():**]
⒉[インデントを開けて処理を書く]
⒊[実行したい関数名():]カッコの中には渡したい引数がある場合はカッコ内に記述する。
これだけで関数を使う事が出来ます。最後に関数の応用をして見ます。![スクリーンショット 2020-08-26 22.41.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581846/d69bfa0b-b760-f94e-237b-62c9571b9f38.png)

コードです

```python
# 外部ライブラリーを使う事を定義する
import matplotlib.pyplot as plt

# グラフを作図する関数を定義する
def RIM(axisX, axisY):
  plt.plot(axisX, axisY);

# リストに0~9の数をリストで順番する。
x = list(range(10))
y = list(range(10))

RIM(x,y)
```
このように関数を使うといつでも簡単に処理を書く事が出来ます
Arch Linux で Samba サーバーを構築する

Samba は Windows と UNIX の間でファイルやプリンタの共有を実現するソフトウェアです。Linux や Mac はもちろん、Android や iOS のようなスマートデバイスもサーバーに接続できます。

Samba 以外のファイルサーバーとしては NFS が有名です。NFS については [Arch Linux で NFS サーバーを構築する](https://qiita.com/pttkny/items/55e2eec044e06ca30946) を参考にしてください。

# サーバー

## インストール

[samba](https://www.archlinux.jp/packages/?name=samba) パッケージをインストールします。

```console
# pacman -Syu samba
```

## Samba の設定

`/etc/samba/smb.conf` を作成します。以下は `/data/share/public` を共有する設定ファイルの例です。

```config:/etc/samba/smb.conf
[global]

# 大文字と小文字を区別する。
case sensitive = yes

# NetBIOS 名が見つからなかった場合に DNS による解決を試行しない。
dns proxy = no

# 192.168.0.0/24 と 127.0.0.0/8 (Loopback) からのアクセスを許可する。
hosts allow = 192.168.0. 127.

# root ユーザからのアクセスを禁止する。
invalid users = root

# ログファイルの名前を設定する。%m は NetBios 名に置換される。
log file = /var/log/samba/%m.log

# ログファイルの最大サイズを KB 単位で指定する。
max log size = 10000

# SMB1 は無効化し、SMB2 以降を使用する。
server min protocol = SMB2

# 認証やリソースの管理をこのサーバーで完結させるスタンドアロンモードで動作させる。
server role = standalone server

# サーバーの説明文を設定する。%h はホスト名に置換される。
server string = Samba File Server on %h

# Mac が create mask を無視しておかしなパーミッションを設定する問題のワークアラウンド。
unix extensions = no

# サーバーが sendfile() をサポートする場合にこれを利用し、パフォーマンスを最適化する。
use sendfile = yes

# ワークグループの名前を適当に設定する。
workgroup = WORKGROUP

# 全ての Samba ユーザーからアクセス可能な共有ファイルサーバーを定義する。
[public]

    # サーバー上のファイルパスを指定する。
    path = /data/share/public

    # ユーザー名とパスワードを使用して認証を行う。
    security = user

    # 共有ファイルへの読み込みだけでなく書き込みも許可する。
    writable = yes
```

## 共有ディレクトリの作成

共有対象になるディレクトリがまだ存在しない場合は作成します。他のユーザからもアクセスできるようにパーミッションを 777 に設定しました。

```console
# mkdir -p /data/share/public
# chmod 777 /data/share/public
```

## ファイアウォールの設定

TCP の 137, 138, 139, 445 番ポートを開放してください。以下に iptables の設定例を示します。

```config:/etc/iptables/iptables.rules
-A INPUT -m state --state NEW -m tcp -p tcp --syn -m multiport --dports 137,138,139,445 -j ACCEPT
```

## Samba サーバーの起動

smbd と nmbd を起動します。

```console
# systemctl start smb nmb
```

また、システムを再起動した後にも自動的に smbd と nmbd が起動するように設定しておきます。

```console
# systemctl enable smb nmb
```

## Samba ユーザーの追加

Samba へのアクセスには Linux ユーザーを使用します。あらかじめ `useradd` コマンドを使用するなどして Linux ユーザーを作成しておいてください。ただし、Linux ユーザーのパスワードとは別に Samba 専用のパスワードを設定する必要があります。`pdbedit` コマンドを使用してパスワードを設定してください。

```console
# pdbedit -a -u name
```

Linux のログインパスワードと Samba のパスワードを同期させる方法もありますが、ここでは説明しません。

# クライアント

## Mac

「移動」「サーバへ接続 (Command + K) 」をクリックするとダイアログが表示されるので、`nfs://192.168.0.16/public` のようなアドレスを入力してください。

ただし、これではシステムを再起動するとアンマウントされてしまいます。自動的にマウントされるようにするためには「システム環境設定」「ユーザとグループ」「ログイン項目」「+」から上記のマウントポイントを選択してください。

## Android

Google Play ストアから Samba に対応した適当なファイラーアプリケーションをダウンロードしてください。私は [CX ファイルエクスプローラ](https://play.google.com/store/apps/details?id=com.cxinventor.file.explorer&hl=ja) を使用しています。CX ファイルエクスプローラでは以下の手順で Samba のサーバーにアクセスできます。

1. `ネットワーク` タブを開き、`+` ボタンをクリックする。
2. `リモート` タブを開き、`SMB` を選択する。
3. `ホスト` `ユーザー名` `パスワード` を入力して `OK` ボタンをクリックする。
raspberry pi zero wh セットアップメモ

ラズパイを買い足したのでセットアップメモを残しておきます。

##1. OS書き込み
https://www.itmedia.co.jp/news/articles/2006/05/news031.html
こちらのサイトを見ながら「Raspberry Pi Imager」というのでSDカードにOSを書き込む。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569342/3deb2749-c3ea-8b78-25f6-863765e452b2.png)
初回は書き込み開始して↑この画面から全然進まなくなり、そのまま一晩放置。
朝になると書き込みが完了していた。

##2. wifi設定
ラズパイzeroのディスプレイ出力がミニHDMIということを知らず、モニターに接続するには変換アダプタとかが必要な状況でした。
しかし今運用しているラズパイ3Bは別PCからリモート接続しているので、最初からそれができないものかと思ったら、ちゃんと方法がありました。
https://kokensha.xyz/raspberry-pi/how-to-set-up-wifi-into-sd-card-for-raspberry-pi/
OSを書き込んだSDカードのルートに、以下の2ファイルを作成する。
1.「ssh」という名前の空ファイル
メモ帳で中身なしのssh.txtというファイルを作って、あとから.txtの拡張子を消せばOK
2.「wpa_supplicant.conf」というファイル
これも一旦メモ帳で作ってあとから拡張子を変えることでOK
ファイルの中には以下を記載

```
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="yourwifi_ssid" #実環境に合わせて修正
    psk="wifipassword" #実環境に合わせて修正
}
```

##3. 電源投入
ラズパイにSDカードを挿入し、マイクロUSBコネクタから電源を供給する。
マイクロUSBコネクタは二つあるけど、基板にシルク印刷でPWRと書いているほうが電源入力。
SDカード挿入状態で電源ONすることで、ラスパイの緑色のLEDが光る。
ここでLEDが光らなければ、OSがうまく書けていない、SDカードが壊れている、ラズパイ本体が壊れている、などが考えられる。
SDカードを入れないで電源ONではLEDは光らない。
ちなみに本体が壊れていないか調べる時は以下のサイトが参考になる。
https://bokuraku.com/rasberrypi-nyumon-3/

##4. PCからSSH接続
ラズパイをGUIで使う場合は、VNC viewerという便利なツールがあるが、初回起動時はラズパイ側でVNC接続が無効になっているため、一旦CUIでSSH接続する。
その前にまずラズパイのipアドレスを調べる。
ルーターの機能とかで、現在ネットワークに接続しているクライアント機器のipアドレスが見れる。
我が家のtp-link製ルーターでは以下のように見えていた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569342/a0ac1ef1-6c89-611c-b0e4-dbbc21e6e22d.png)

次に、SSH接続するために私はTera Termというアプリを使いました。
以下の部分にラズパイのipアドレスを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569342/471a3021-2207-d443-ca72-ae465f4e1db6.png)

↓こんなのが出るけど続行する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569342/d261c0e2-a925-0a82-9e56-2e254df6c933.png)

↓初回ユーザ名はpi、パスワードはraspberry
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569342/d977463f-cb14-bd3a-91cd-01c1d6c7240e.png)


↓接続できると以下の画面になる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569342/dfd69cfd-b8b7-2cc9-cbdd-7c7d3c433c46.png)

##4. VNC接続有効化
https://iot.keicode.com/raspberry-pi/raspi3-vnc-setup.php
https://jellyware.jp/kurage/raspi/vnc.html
↑このへんのサイトが参考になる

VNC接続時の画面解像度を変更するには以下のサイトを参照する
https://peacejet.hatenablog.com/entry/2017/07/07/234236

##5. ipアドレス固定化
ipアドレスが自動取得だと、今後VNC接続する際の接続情報が変わる可能性があるので、固定化する。
一旦VNC接続できている場合はGUIでやるのが早かった。
https://mugeek.hatenablog.com/entry/2019/05/27/230256
こちらのサイトにCUI、GUI両方のやり方が書いてました。
固定ipにしたら、VNC接続の接続情報も更新が必要。

##6. WinSCP導入
Windowsの場合、WinSCPというソフトを入れておくとWindowsPCとラズパイ間のファイル同期が簡単にできて便利です。
https://winscp.net/eng/download.php
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569342/3dc66740-c297-5b4c-0bfc-2bb93d6055a7.png)
↑こんな感じで、二画面のファイラのような感じでファイル転送ができます。

一旦以上。
また必要に応じ書き足していきます。
carrierwaveを使って画像を保存する時の名前にidをしない方がいいと感じた内容を残す

## この記事で書くこと
[carrierwave](https://github.com/carrierwaveuploader/carrierwave) を使った画像アップロード機能で格納するディレクトリや、ファイル名に紐ずくモデルのidを使用していた時に、起きた難しさについて。

## 結論
モデルごとのプライマリーキーであるidは、勝手にrailsがやってくれるカラムであって、特別な意味、今回であれば画像に関する用途に対して使用するのはよくない。
ユニークな名前にしたいのであれば [SecureRandom](https://docs.ruby-lang.org/ja/latest/class/SecureRandom.html) を使用して `image_path_code` などの列を作成し、保存した上で重複したファイル名が使われないようにする。もしくは、頻繁に作成されるものでなければ、timestampを使用するなどの方法もある。

## 起こったこと

以下のモデルのデータを一括でcsvにて大量に作る機能が必要になった。

```app/model/animal.rb
class Animal < ApplicationRecord
  mount_uploader :animal_icon,              AnimalIconUploader
end
```

```app/uploaders/animal_icon_uploader.rb
class AnimalIconUploader < ApplicationUploader
  def store_dir
    "uploads/images"
  end
  
  def extension_whitelist
    %w(jpg jpeg png gif)
  end

  def filename
    "animal_img_#{model.id}#{File.extname(original_filename)}" if original_filename.present?
  end
end
```

csv経由でデータを作ろうとする準備
今回は `animals#index` に一括登録のインターフェイスを追加することにする。

### routing
```config/routes.rb
中略
post :animal_bulk_imports, to: 'animals#bulk_import', as: :animal_bulk_imports
中略
```

### view
以下を追加


```app/views/animals/index.html.haml
中略

  %section
    .title
      csvから一括で登録する
    = form_tag animal_bulk_imports_path, multipart: true do
     %p
       動物たちのcsvファイル
     = file_field_tag :animal_csv
     = submit_tag 'インポート', class: 'btn btn-default'

中略
```


### controller

```app/controllers/animals_controller.rb

class AnimalController < ApplicationController
中略
  def bulk_import
    Animal.bulk_import(params[:animal_csv]) if params[:animal_csv]
    redirect_to animals_path, notice: 'csvによる登録を受け付けました'
  end
  
  private

  def animal_bulk_import_params
    params.require(:bulk_import_animal).permit(:animal_csv)
  end

中略
end
```

一括でcsvを通じて例えば以下のように画像をセットして保存しようとすると、

```rb
animal = Animal.new
# row['animal_icon_url'] には参照可能なurlが記載されているとする
animal.remote_animal_icon_url = row['animal_icon_url']

animal.save

```

画像に `model.id` が使用されているので、正しく保存されず、画像を登録することができない。
ということが起きる。


こうなると、どうするのがいい方法なのかわかっていません。。。 :disappointed: 

既存データを新しい参照先に書き換えるようなタスクを書いて、既存データを移行してから、対応するしかないのだろうか。。

少なくとも今後作成するアプリケーションでは、画像パスについては `model.id` を参照しないようにした方がいい、ということを学びました。 :bow:
TypeScript入門　その2

[こちら](https://yk0807.com/techblog/2020/08/26/typescript%e5%85%a5%e9%96%80%e3%80%80%e3%81%9d%e3%81%ae2/)のブログ記事をQiitaに投稿したものです。
前回の[TypeScript入門その1](https://qiita.com/yk0807/items/d8b6abaaa8e999e400fd)に続いて、第2回の今回は、主にデータ型などを説明しようと思います。


# 1. 主要なデータ型
基本的なデータ型は、次の3つです。
**・boolean**
取ることができる値はtrueかfalseのどちらかだけです。
**・number**
数値を値に取ることができます。整数、小数の区別はありません。
**・string**
文字列を値に持つことができます。

変数を宣言する時は、下記のようにして型とともに宣言します。

```typescript
let enabled:boolean;
let money:number;
let name:string;
enabled = true;
money = 100;
name = "Ichiro";

money = "ABC";   // これはダメ。コンパイル時にエラーになります。
```

このように型を宣言すると、その変数には型に当てはまる値以外は入れられなくなります。JavaScriptでは10 == “10”がtrueになったりということもありましたが、TypeScriptではそもそも比較自体ができなくなります。
とはいえ、何らかの理由で型を指定したくない場合も場合によってはあるかと思います。このような場合はlet value:anyという風に**any型**を使うことでどのような型でも代入できるようになります。JavaScriptで書かれたソースをTypeScriptに書き換える場合なんかでたまに使うこともあるかもです。

# 2. 変数宣言の指定子
先ほどの変数宣言の例では**let**を使って宣言しましたが、**var**だと関数の中での宣言なら関数内で、それ以外ならグローバルで使えるようになりますが、letは宣言された構文内のみがスコープになります。

varよりはletを使った方が想定外のところで値が書き換わるようなことがなくなるので、varにしなければいけない理由がある場合以外はletを使った方がいいと思います。
ちなみに、letはJavaScriptではES6から使えるようになりました。
また、変数宣言ではvarとletですが、定数宣言では**const**を使います。constで宣言されると、それ以降値の変更が一切できなくなります。

最近letも使わずconstだけを使うべきだという記事も見ましたが、確かに値を変更することがありえない場合はconstを使うべきですが、letでないと実装しづらいケースも多々あると思うので、個人的には「そこまでこだわらなくてもいいのでは」派です。
 
# 3. 配列
TypeScriptにも、JavaScriptと同じように配列は存在します。配列の宣言は下記のように行います。

```typescript
let data:number[];
data = [1, 1, 2];
data.push(3);
console.log(data);   // 1,1,2,3
data.push("xyz");    // だからダメだってば
```

このように、配列もどんな型を要素に入れられるかの宣言を行います。なので、配列の要素に指定した型でないものを入れようとするとエラーになります。

この他にも、列挙型（enum）やタプルについても説明したかったのですが、次回にします。
RSpecを導入して単体テストコードを記述する

#概要
今回は、userモデルの単体テストコードをrspecを導入して記述する流れをまとめます。

それに伴い、FactoryBotとFakerも導入して実装したので記述します。

###FactoryBotとは
テスト用のデータを作成してくれるツールです。

###Fakerとは
FactoryBotで作られたデータにランダムに中身を追加することが出来ます。

##gemの導入、準備
ポイントとして、Gemfileの記述場所に注意しましょう。
一番下ではありません。

```ruby:gemfile
group :development, :test do
  gem 'rspec-rails'
  gem 'factory_bot_rails'
  gem 'faker'
end
```

このあと
$ bundle install
します。

次に、コマンドを実行して、RSpecを書くためのディレクトリなどの生成を行います。

```:ターミナル
rails g rspec:install
```
すると、ディレクトリやファイルが生成されるはずです。

次に、.rspecに以下の記述をしましょう。

```ruby:.rspec
--require spec_helper
--format documentation
```

最後に、FactoryBotのファイルを生成しましょう。
specディレクトリのなかにfactoriesディレクトリを自作し、今回はusers.rbを作成します。

これで下準備はOKです。

##FactoryBotでの値を指定
先ほど作成したファイルにそれぞれ値を定義していきましょう。

```ruby:spec/factories/users.rb
FactoryBot.define do
  factory :user do
    nickname {Faker::Name.last_name}
    email {Faker::Internet.free_email}
    password = Faker::Internet.password(min_length: 6)
    password {password}
    password_confirmation {password}
    family_name { "山田" }
    first_name {"太郎"}
    read_family {"ヤマダ"}
    read_first {"タロウ"}
    birth {Faker::Date.between(from: '1930-01-01', to: '2015-12-31')}
  end
end
```

ここでのポイントは、Fakerを利用しているところと、利用できないところがあることです。
Fakerは英数字しかランダムに生成できません。
よって、family_nameなどは今回は適当に値をつけときました。

日本語のダミーデータを作れるgemもあるようですが、今回は見送りました。

##テストコードの記述
まずは準備として、テストコードを書いていくファイルをコマンドで生成します。

```:ターミナル
rails g rspec:model user
```

すると、
spec/models/user_spec.rb
が生成します。

そこに単体テストコードを書いていきましょう。

```ruby:user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  describe '#create' do
    before do
      @user = FactoryBot.build(:user)
    end

    it "nicknameが空だと登録できない" do
      @user.nickname = nil
      @user.valid?
      expect(@user.errors.full_messages).to include("Nickname can't be blank")
    end
    it "emailが空だと登録できない" do
      @user.email = nil
      @user.valid?
      expect(@user.errors.full_messages).to include("Email can't be blank")
    end
    it "emailに一意性がないと登録できない" do
      @user.save
      another_user = FactoryBot.build(:user, email: @user.email)
      another_user.valid?
      expect(another_user.errors.full_messages).to include("Email has already been taken")
    end
---省略---
 end
end
```

長いのでかなり省略しましたが、こんな感じで記述していきます。

ポイントは、
before doでちゃんとFactoryBotのデータをインスタンス変数で定義することです。
これを忘れて@userがnilになり、一回迷子になってしまいました(ド素人)

しっかり記述できたらターミナルで

```:ターミナル
bundle exec rspec spec/models/user_spec.rb
```

コマンドを入力してテストを実行してみましょう。
2020Tinder自動化・最強コード/JavaScript

どうも、最近彼女に振られたぞえです。
振られたので、新たな女性を追い求めtinderの自動フリックのコードを最新版にしました。

みなさんtinderの自動化はご存知ですか？
https://tech.windii.jp/frontend/html/tinder

ご存知の場合、以下に最新版のソースコードを作成したので是非使ってください。

日本で現状最強で、広告飛ばせる。途中で止まらないといった違いがあります。
適当なので誰かリファクタしてくれてもありがたいです！


```
count = setInterval(
function(){
var buttons = document.getElementsByClassName("button Lts($ls-s) Z(0) CenterAlign Mx(a) Cur(p) Tt(u) Bdrs(50%) P(0) Fw($semibold) focus-button-style Bxsh($bxsh-btn) Expand D(b) Bgc(#fff) Trstf(e) Trsdu($normal) Wc($transform) Pe(a) Scale(1.1):h Scale(.9):a");
buttons[2].click()
var closeButton = document.getElementsByClassName("Pt(20px) Pb(40px) C(#fff) Fw($bold) Tt(u) Lts($ls-s) D(b) W(100%) Trsdu($slow)");
if(closeButton[0]) {
    closeButton[0].click();
    buttons[1].click()
}
var back = document.getElementsByClassName("button Lts($ls-s) Z(0) CenterAlign Mx(a) Cur(p) Tt(u) Ell Bdrs(100px) Px(24px) Px(20px)--s Py(0) Mih(40px) C($c-secondary) C($c-base):h Fw($semibold) focus-button-style D(b) Mx(a)")
if(back[0]) {
    back[0].click()
    buttons[1].click()
}
},1000)
```



動画でも解説したので、もしよければチャンネル登録お願いします。
https://www.youtube.com/watch?v=mDE2mdIPwQU

ではでは
Rust windows (イテレーションの方)

# Rust の slice の windows (OS ではない)
## 使い方
「Rust windows」でググっても Windows(OS) で Rust をやってみる系の話しか出てこないので、書いておこうとなりました。

`std::slice::windows`は、「前の値も含めて for ループを回したい」というユースケースで使うことができます。競技プログラミングなどでは頻出なのではないでしょうか。

```rust
let v = vec![1, 2, 3];
for w in v.windows(2) {
    let (prev, next) = (w[0], w[1]);
    println!("{} {}", prev, next)
}
// 1 2
// 2 3
```

[windows](https://doc.rust-lang.org/std/primitive.slice.html#method.windows) メソッドを用いると、ミュータブルな変数を外側のスコープに用意するという手間を省くことができます。とてもきれいに書くことができるようになると思います。

また、引数に 2 を与えていることから察しがつくと思いますが、引数に与えたサイズのウィンドウでのイテレータを得ることができます。
引数に 3 などを与えると、3つずつのイテレータを得られます。

```rust
let v = vec![1, 2, 3, 4];
for w in v.windows(3) {
    let (prev, current, next) = (w[0], w[1], w[2]);
    println!("{} {} {}", prev, current, next)
}
// 1 2 3
// 2 3 4
```

## 注意
注意というほど注意でもないのですが、`std::slice::Iter`からは生えません。
`iter()`を挟むと、以下のようにコンパイルエラーとなります。

```rust
let v = vec![1, 2, 3];
for w in v.iter().windows(2) {
   let (prev, next) = (w[0], w[1]);
   println!("{} {}", prev, next)
}
// 1 2 
// 2 3 
```
```
   Compiling playground v0.0.1 (/playground)
error[E0599]: no method named `windows` found for struct `std::slice::Iter<'_, {integer}>` in the current scope
 --> src/main.rs:5:23
  |
5 |     for w in v.iter().windows(2) {
  |                       ^^^^^^^ method not found in `std::slice::Iter<'_, {integer}>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.
```

おそらく、サイズが決まっていて、`s[lo..hi]` のようにスライスでアクセスできるような並びに対してしか使えないことになっている(？)のだと思います。

# itertools の windows
また、 `itertools` にはこれをタプルにした [tuple_windows](https://docs.rs/itertools/0.8.0/itertools/trait.Itertools.html#method.tuple_windows)があります。
タプルにすると何がうれしいかというと、for文の1行目に書いているようなlet文の変数束縛フェーズがスキップできます。また、明示的に引数にサイズを与える必要もなくなり、for文の受け取り側のタプルの型から型推論してくれるようです。かしこい。

```rust
use itertools::Itertools;

fn main() {    
    let v = vec![1, 2, 3];
    for (prev, next) in v.iter().tuple_windows() {
        println!("{} {}", prev, next)
    }
    // 1 2 
    // 2 3 
}
```

こちらでは`iter()`を挟まないと、「the method \`tuple_windows\` exists but the following trait bounds were not satisfied:」というエラーが出ます。 Rust 難しい…
Nuxt.js で Google Analytics のページビューを計測する

Nuxtで構築しているサイトで「[nuxt-community/analytics-module](https://github.com/nuxt-community/analytics-module)」を使って、Google Analyticsのページビューを計測する時にちょっと詰まったのでメモです。

## 発生した問題
READMEの内容に沿って設定を終えた後に動作確認をした所、ページ遷移を行った時にGA側に送信されるURLは正しいのですが、ページタイトルが一つ前のページの内容で送信される問題に出くわしました。

## どんな対応をしたか
「[Timing issue with vue-meta](https://github.com/nuxt-community/analytics-module/issues/8)」というIssueを見つけました。
Issueを読みすすめると、どうやら transion 周りの挙動が影響しているらしく・・・・。
`nuxt.config.js` にこちらの設定を追加すれば良いとの事。

```
features: {
  transitions: false
},
vueMeta: {
  refreshOnceOnNavigation: true
}
```

ただし、この設定を行うとページ遷移時のスクロール位置が正しく動作しない為、scrollbehaviorの調整も必要となります。
【未経験から】AWS認定クラウドプラクティショナー合格体験記

先日、AWS認定クラウドプラクティショナー試験 (CLF-C01)を受験し無事合格したので、受験当日までの勉強内容から当日の試験の流れまでをメモしておきたいと思います。

#はじめに
筆者は大学3年生(情報系の学科)で、AWSの使用経験はありませんでした。
EC2やS3くらいのサービス名は知っていましたが、EBSとS3の違いすら全く分からないレベルでした。

#受験までの勉強期間
8月8日から8月21日(受験当日)まで
1日約3時間くらいで2週間勉強しました。

#勉強方法
- [AWS認定資格試験テキスト AWS認定 クラウドプラクティショナー (日本語) 単行本 –](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC-%E5%B1%B1%E4%B8%8B-%E5%85%89%E6%B4%8B/dp/4797397403/ref=asc_df_4797397403/?tag=jpgo-22&linkCode=df0&hvadid=295691444786&hvpos=&hvnetw=g&hvrand=18393618109612742569&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009224&hvtargid=pla-718362586207&psc=1&th=1&psc=1)

- [Udemy この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（7回分455問)](https://www.udemy.com/share/101I2O/)

- [AWSのデジタルトレーニング](https://www.aws.training/LearningLibrary?filters=language%3A2&tab=view_all)

主にこれらの教材で勉強を進めました。

＋αでよくわからないサービスのブラックベルトを見たりしました。

試験2日前くらいに、スマホでクラウドプラクティショナーの模擬試験が解けるアプリを見つけましたが、
Udemyの模擬試験と問題が同じだったのと、正解が間違っていることがあったのでやってません。

#勉強の流れ
###・最初の1週間
とにかく本を読みました。
AWSのサービスとは関係ない部分の単語(デプロイやプロビジョニングなど)がわからないことが多く、
それをいちいち調べてはメモして、という感じで読み進めていたので、
1周するのに1日3時間ペースで1週間かかってしまいました。

普段、こういう本を読んでいないと、1冊読むのにこんなに時間がかかるのかとちょっと焦りを感じたので、これからはもっと本を読むことを決心


###・試験2日前まで
Udemyの模擬試験を***基礎問題2と応用問題3を除いて***すべて解いて、
***正解した問題も不正解だった問題もすべての解説を読んで理解しました。***
↑これが結構大事だと思いました、正解した問題でも、それ以外の選択肢がなぜ不正解なのかをしっかり理解するようにしました。

ただし、これから受験する人は、***一番最後の難易度高の問題は参考程度に見るくらいでいいと思います。***
(クラウドプラクティショナーではなかなか問われないような問題ばかりだと感じたので)


Udemyの基礎1、応用1、応用2を解いた結果を一応貼っておきます。
![くっつけ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693048/2be68a23-25ce-25d2-b8c1-edf35f392cf9.jpeg)
応用1と応用2の結果を見ていただければわかると思いますが、本を１周したとしても一回目で７割を超えるのは難しいと思います。
これは、本の内容が悪いわけではなく、***応用問題が本試験より少し難しくできているからだと思います。***
なので１回目で７割を超えていなくても落胆せずにしっかり復習に取り組むと良いと思います。


###・最後の2日
残していたUdemyの基礎問題2と応用問題3を解きました。
残しておいた理由としては、僕の受けた時点でのクラウドプラクティショナー試験は試験の24時間以上前であれば日程変更が可能だったので、
ある程度学び終わった時点で、基礎問題2と応用問題3を解き、点数によっては最悪日程変更するつもりでした。

基礎2と応用3の結果も貼っておきます。
![くっつけ２.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693048/6edd45a9-d6c5-3785-5c48-29a436f135db.jpeg)
試験の2日前にこの結果だったので少し焦りましたが、応用問題3は他の応用問題よりも複数回答の問題が多く、難しかったように思いました。

#試験当日
ピアソンVUEで受験しました。
###・試験直前
試験当日、会場には15分前に着くように記載があったので、
ぴったり15分前くらいに行ったらすでに受付が始まっていました。

試験前に英語でやりとりすることがあるという記事を見たことがあったので身構えていましたが、特にやり取りはありませんでした。

###・試験本番
問題は後で見直す用にチェックが付けられるので、1週目は少しでも迷った問題はチェックを付けて解き進めました。
2週目はチェックを付けた問題をよく読んでしっかり考えなおしました。

筆者は英語が不得意なので、日本語で受験をしましたが、この試験は英語と日本語を切り替えることができます。
***本当にわからない問題があった場合は、英語に切り替えてみることを強くおすすめします。***

理由として、試験問題の内容になってしまうので詳しくは言えませんが、日本語ではサービス名など一切書いていなかったのに、英語に切り替えるとAWS 〇〇〇というサービス名が出てきた問題がありました。

#試験結果
![j4dNYIrABUBMKA71598446374_1598446551.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693048/26ccbf49-f256-e049-745a-5e651974b49b.png)

思っていたよりもスコアが高くてびっくりしました。

本試験の難易度的には、
Udemy基礎1,2 < 本試験 < Udemy応用1,2 < Udemy応用3 <= Udemy難易度高
という感じかなと思いました。

これをベースにソリューションアーキテクトアソシエイト(SAA)の取得に向けて学習していこうと思います。
AWS SAPro 合格体験記（2020/6）

2020年の6月末に **AWS Solution Architect Professional** に合格しました。
（3回目でね！！）

ってことで今後受験する方の参考になればと思い、振り返りを込めたAWS SAPro受験対策をお伝えしようと思います。

#Study

**勉強道具は以下**

+ AWS Summitなどの講演動画および資料 
+ AWS WEB問題集（https://aws.koiwaclub.com/）
+ AWSドキュメント

**勉強手順は以下**

>1. AWS WEB問題集を2周する
2. 知識の足りない部分をAWS Summitの動画やドキュメントをみて理解を深める
3. AWS WEB問題集を2周する
4. AWS ドキュメントのトラブルシューティングやよくある質問の部分を復習する
5. AWS WEB問題集の本試験モードで880点以上出せるまでやり込む
6. 本受験に挑む

まず先にお伝えしたいのは、個人的にホワイトペーパーとかBlackBeltとか、Jayendraのブログとかを読むのは遠回りな勉強方法だったなということです（模擬試験もいらない）。試験範囲をAWS WEB問題集でさくっとつかんで、それからAWS SummitやAWSドキュメントで理解を深めていくのが正攻法だと感じています。

AWS WEB問題集をとにかくやり込むってのが、合格の近道です。私はUdemyの試験問題などもやりましたが、3回受験した所感でいうと8割ぐらいはこの問題集に近い問題だったので、どのくらいの範囲なのかを掴んだりどんな問題がでたりだとか知るのにとても最適なものだと思います。騙されたと思ってやり込んでみてください。

#AWS Summit

足りない知識を補い、深めるにはBlackBeltよりAWS Summitの動画がおすすめです。英語を理解できるのなら海外のものもチェックしましょう。以下は、私が実際に見た動画です。参考にしてください。

+ ネットワークデザインパターン
https://youtu.be/6I7jQOLOiWY

+ DynamoDB
https://youtu.be/16RYHfe89WY

+ ユーザー認証実装パターン
https://youtu.be/wnB6Fq7-tHs

+ ストレージについて
https://youtu.be/JC_zLttxODc

+ Systems Manager
https://youtu.be/wc1f5XlvVO4

Deep Diveしようぜってことですね。

#Path

上記で紹介した勉強手順に加え、合格の必勝方法を以下にまとめます。

+ 試験時間は3時間、長すぎるため受験前にトイレにいこう
+ 試験時間が長いため、疑心暗鬼になるので、平常心を
+ AWS WEB問題集でいい点とっても調子に乗らない
+ AWSドキュメントからまあまあ問題出るからちゃんとチェックして
+ 毎日何かしら勉強すること、受験日まで勉強は継続すること
+ 神に祈ったりしないこと



以上、これ読んだ人がんばってください！！





**Thanks.**
5 分で Hello World できる Blazor WebAssembly (C#)

SPA 開発となると、そのフレームワーク/ライブラリの選択肢の多くは Angular、React、Vue と言った JS のフレームワーク/ライブラリが一般的かと思います。

今回はそれ以外の選択肢である Blazor を利用して C# で書ける SPA 開発を紹介します。

とりあえず動かしたい!!って人は以下の概要を読み飛ばして、[Hello World のハンズオン](https://qiita.com/nt_tn/items/97c0bc75e3afe9e02997#blazor-webassembly-%E3%81%A7-hello-world)に飛んでください！
macOS でも Linux でも Windows でもクロスプラットフォームで開発でき、動きます。

# ASP.NET Core Blazor
- JavaScript ではなく　C# (.NET) で書ける SPA (Single Page Application) 向けのフロントエンドフレームワーク
- Blazor WebAssembly (上) と Blazor Server (下) の 2 種類がある
    - Blazor WebAssembly : 完全な SPAで、wasm で書いた .NET ランタイム上で C# のコードが動く
    - Blazor Server : ASP.NET Core SignalR の技術を利用して疑似的に SPA を実現しているイメージ (ただし動的生成したHTMLを返すような従来の View の機構を持ったバックエンドフレームワークとは異なる)
- いずれもコンポーネント指向で、Razor コンポーネントで各コンポーネントを記述
- クロスプラットフォーム動作の  .NET を前提にしてるので、Mac でも Linux でも開発可能

参考 : Blazor - 概要
https://docs.microsoft.com/ja-jp/aspnet/core/blazor/?view=aspnetcore-3.1

# Blazor WebAssembly
- wasm で書いた .NET Runtime 上で C# がブラウザで動く！
- JavaScript interop という機能で JS を介してブラウザの全機能にアクセス可能
- 最近出た Azure Static Web Apps (Preview) にホストも可能

参考 : Blazor WebAssembly
https://docs.microsoft.com/ja-jp/aspnet/core/blazor/?view=aspnetcore-3.1#blazor-webassembly


# Blazor WebAssembly で Hello World

## 0. 前提
- OS : macOS, Linux, Windows 何でも
- [最新の .NET Core SDK](https://dotnet.microsoft.com/download/dotnet-core/3.1) をインストールし、インストール後に以下を実行し、無事インストールされていることを確認

```
dotnet --version
```

## 1. テンプレートを生成、動かす

### dotnet CLI で　Blazor WebAssembly のテンプレートを生成
任意のディレクトリで以下を実行

```
dotnet new blazorwasm -o HelloWorld
```

### HelloWorld プロジェクト内に移動し、watch モードでアプリを起動

```
cd HelloWorld
dotnet watch run
```

起動後に https://localhost:5001 もしくは http://localhost:5000 にアクセスし、以下の画面が出ていれば成功

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/c9fc728f-6201-b701-d6b7-c8982ffd563d.png)

## 2. ちょっとだけ変更

### ちょっとコード変更 
Pages/Index.razor の中を以下に変更

```
@page "/"

<h1>Changed Hello</h1>
```

### 変更反映の確認
ブラウザ画面をリロードし、変更の反映を確認。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150728/89eff740-1978-c410-c6d3-d00ea674a5ab.png)


# 最後に
今日は Hello World だけですが、ASP.NET Core SignalR との組み合わせのチュートリアル等もありますので、興味があれば色々触っていただければと思います。

参考 : ASP.NET Core SignalR を Blazor WebAssembly と共に使用する
https://docs.microsoft.com/ja-jp/aspnet/core/tutorials/signalr-blazor-webassembly?view=aspnetcore-3.1&tabs=visual-studio
Classの基本




## プロパティの定義
#### constructorの中にプロパティを記載するルール

```javascript
    class aaaa {
        constructor(name, age, type){
        this.name = name;
        this.age = age;
        this.type = type;
 }
}
``` 
このクラスをインスタンス化すると

```javascript

const dog = new aaaa('犬', 2, 'チワワ');

console.log(dog);
// 出力結果
// {
//   name: '犬',
//   age: 8,
//   type: 'チワワ'
// 
```
## メソッドの定義
#### 基本的にはclass内においてメソッド名() { }と記載する
```javascript
class Animal {
  constructor(name) {
    this.name = name;
  }
  
  getName() {
    return this.name;
  }
}
```
## 継承
クラスを継承するには、**extends** を使う

```javascript

class xxxx extends 継承するclass{}；
```
## Superの使い方

継承元のクラスのプロパティに上書きせずアクセスできる

```javascript
class Hero extends Character {
   //constructor(exp)としてしまうと継承元を上書きして(name, hp)が消えてエラーになる。
   //なので下記の様にSuperを使う

   constructor(name, hp, exp) {

      // 継承元のプロパティにアクセス（名前・HPの値をセット）
      super(name, hp);
      //プロパティにexp（経験値）を追加したい場合
      this.exp = exp;
  }
}
```

## 演習
動物クラス（Animal）を継承し、新しく猫（Cat）クラスを作ってください。
ただし、猫（Cat）クラスにはtypeプロパティを追加して、値にはシャムを指定します。
そして、インスタンスを作ってその中身をコンソールログに出力してください。


```javascript

<script>
  
  class Animal{
    constructor(name, age){
      this.name = name;
      this.age = age;
    }
  }
  
  class Cat extends Animal{
    constructor(name, age, type){
    super(name, age);
    this.type = type;
    }
  }
  const cat = new Cat('太郎', 10, 'シャム');
  console.log(cat);
  
</script>
```
【熱さに負けた】教えて修造先生！松岡修造×グルメ×地図【Vue.js】

## アイデア出しって難しくないですか？
突然ですが、私は発想することが苦手です。
新しく技術を学んだのはいいが、__その技術を使って「何を作るか」__を思いつくまでに時間がかかります。
私が通っているプロトアウトスタジオの同期の方々はユニークな発想を形にする凄腕の方が
多くいらっしゃいますので、企画を思いついたとしても__「これ普通すぎだろ」__と葛藤している間に時間が経過していきます。
## 非線形アプローチとアイデアスケッチ
前述のように普段から企画の発想について悩むことが多いです。
そこでワークショップを通じて学んだ非線形アプローチとアイデアスケッチという手法で、発想を産み出し制作しました。

###非線形アプローチ

お題となるキーワードから、自分が連想した言葉と、他の方が連想した言葉を組み合わせて発想のヒントを得るアプローチです。その発想に自分が習得している技術を掛け合わせてプロダクトを企画します。

他者の力を借りた連想ゲームのようなものです。

###アイデアスケッチ
非線形アプローチでの発想をスケッチブックに起こします。視覚化することで発想を具体的にします。

キーワード【ソーシャルディスタンス】というお題から「生きろ」という単語をどなたかが書いていたので私はそれを→「松岡修造」氏に言われているところを想像しました。
技術: obniz
特に深い理由はありませんがLEDを赤く光らせると修造氏っぽくなると思ったためです。

このキーワードと技術選定より、私は以下のスケッチを描きました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ポジティブパワーをobnizで感知できたらいいな。<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://t.co/6mvdvdTDt5">pic.twitter.com/6mvdvdTDt5</a></p>&mdash; ウーリズム (@Uh_rhythm) <a href="https://twitter.com/Uh_rhythm/status/1297060622199222272?ref_src=twsrc%5Etfw">August 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
## 制作物
__松岡修造氏やケーキ屋さんやライブハウスなど元気の出そうな人や場所に接近したら通知をしてくれるアプリとobnizの連携__のスケッチを行いました。
ですが、松岡修造氏と対面する機会は、生きている間になさそうでメイン機能の実装確認ができる可能性が低いため、実現可能な落とし所を考え、__スケッチに書いてあったキーワードから飲食店の地図情報を松岡修造氏が教えてくれるアプリ__を作ることにしました。また、個人的な目的でVue.jsをメインにした制作を行いたかったためobnizは企画から外しました。
こちらがデモです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">松岡修造とグルメ&amp;地図アプリを融合させた熱いアプリを作りました。彼の熱量を表現することの難しさたるや・・・！ <a href="https://t.co/vfF7f63ebm">https://t.co/vfF7f63ebm</a> <a href="https://t.co/7qZOTR40wT">pic.twitter.com/7qZOTR40wT</a></p>&mdash; ウーリズム (@Uh_rhythm) <a href="https://twitter.com/Uh_rhythm/status/1298588472303849473?ref_src=twsrc%5Etfw">August 26, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

leaflet.jsの使い方がうまく使えず、本来は３０件超あるデータをループさせて地図上にマーカーの雨を降らせる予定でしたが、できませんでした。

```javascript

getData: function(data) {
  let marker = L.marker([data.rest[0].latitude, 
  data.rest[0].longitude]).addTo(mymap);
  marker.bindPopup("<p>"+ data.rest[0].name +"</p>").openPopup();
}
```
こちらが特定の地図の位置にマーカーを置くコードなのですが、
私はこうしたかったのです。

```javascript
getData: function(data) {
  for (let i = 0; i < data.length; i++) {
    let marker = L.marker([data.rest[i].latitude, 
    data.rest[i].longitude]).addTo(mymap);
    marker.bindPopup("<p>"+ data.rest[i].name +"</p>").openPopup();
  }
}

```

またポップアップをクリックすると修造氏が熱い言葉とともにお店のデータを教えてくれる予定でした。

## 使用したAPIについて
### ぐるなびAPI
グルメ系のAPIはホットペッパーペッパーがあり両方とも試してみましたが、フリーワード検索においてぐるなびが優れている印象があったのでぐるなびAPI
を選択しました。
### leaflet.js
無料の地図APIです。
GoogleMapAPIの料金体系を確認する余裕がなかったため無料で評判の良いこちらを使いました。
地図の表示まではスムーズにできたので、もうちょっと使いこなせるようになりたい。


## アイデアからプロダクトを作る
普段の制作は何か新しい技術を学びその技術を使ってプロダクトを企画します。
今回は先にアイデアを出して、今までに習得した技術を使ってどのように実現するのかを実践しました。
今回はアイデアの土台がすでにあったので、どんな実装を行うかについてはイメージがしやすかったです。
自分では絶対発想することのないキーワードから企画制作ができたのも面白かったです。
地図アプリが思うようにいかず、当初の実装目標に達することはできませんでしたし、もっと全面的に修造氏の熱い感じを出したかったので、悔しくもあります。
ですが一つ安心したことは、企画の発想方法を知ったことで、私にも面白い発想と制作に対して希望を持てたことです。
修造氏のように熱く頑張りたいですね。
Docker上のDB2の中身を見たくなったら

# はじめに
先日仕事でDocker上のDB2の中身をのぞいてスキーマを作ったり消したりする機会がありました。
初めての経験で色々調べながらやったので、備忘録がてら先週の自分へ送る気持ちでメモ。
DB2の基礎知識が数点書いてあるだけなのでDB2初めてレベルの人向けです。

# 環境
- **OS** : macOS Catalina version:10.15.5
- **Docker** : docker desktop for mac version:2.2.0.3
- **Image** : ibmcom/db2:11.5.0.0a (https://hub.docker.com/r/ibmcom/db2)

# やったこと
testdb1というデータベースを作成済み前提です。

## 1. Dockerに入る
まずはいつもの`docker exec -it`でdocker内部に入ります。
なお、`db2inst1`が初期ユーザーです。

```bash
docker exec -it db2-115 bash -c 'su - db2inst1'
```

## 2. db2コマンドで接続する
他のDBMSでsqlplusだのpsqlだのは使ったことがあったのですが、db2ではどういうコマンドなのか知らず、少し調べました。
db2だとそのまま`db2`コマンドでOKです。
その後`connect to`コマンドで接続するDBを選択しましょう！**←忘れがち！**

```bash
[db2inst1@db2-115 ~]$ db2
db2 => connect to testdb1

Database Connection Information
 Database server        = DB2/LINUXX8664 11.5.0.0
 SQL authorization ID   = DB2INST1
 Local database alias   = TESTDB1

db2 =>
```

## 3. よく使ったコマンド(SQL)
特に使い方が分からず調べて使ったものについてメモします。
そのため、この時使ったコマンドでも一般的なSQLと同じもの(create table)などは記載しておりません。

### スキーマ一覧表示
スキーマを作ったり削除したりしたので非常によく使いました。

```sql
SELECT SCHEMANAME,OWNER  FROM SYSCAT.SCHEMATA
```

### スキーマ削除
最後の`restrict`を忘れがちなので注意！

```sql
DROP SCHEMA スキーマ名 RESTRICT
```

### テーブルの一覧表示
カレントスキーマ以外のスキーマのテーブル一覧を表示する場合は`for schema スキーマ名`が必要になります。

```sql
LIST TABLES (FOR SCHEMA スキーマ名) 
```

# 参考
作業中は特にこちらのサイト様を参考にさせていただきました。非常にわかりやすくまとまっていて素晴らしいです。
DB2 操作コマンド - https://blue-red.ddo.jp/~ao/wiki/wiki.cgi?page=DB2+%C1%E0%BA%EE%A5%B3%A5%DE%A5%F3%A5%C9#p11
バッチ処理のバックアップDMPを２→１世代保存へ修正した話

<h1>DBサーバーのストレージが限界</h1>
DBサーバーのストレージが限界に近くなり、原因の調査と一時的にバックアップを２世代→１世代に変更することになった。
バックアップ先フォルダを確認するとDMPは2世代保存のはずが10世代も保存されていた。

原因と修正内容を備忘録までに記載。
<div>
　<div>
バックアップは毎日行われDMPは以下のような日付フォルダの中に配置される。

F:¥Data¥Dump¥20200826
F:¥Data¥Dump¥20200825
F:¥Data¥Dump¥20200824
　</div>
</div>
<div>
<h2>今までの処理</h2>
 <div>
今日の日付を年月日で取得
`set TODAY=%date:~0,4%%date:~5,2%%date:~8,2%`
 </div>
 <div>
パワーシェルで前々日の日付を取得
` set SEDAI=2`
 <div>
``FOR /F "usebackq" %%a IN (`powershell [DateTime]::Today.AddDays"("-%SEDAI%")".ToString"("'yyyyMMdd'")"`) DO SET REMOVEDAY=%%a
``
 </div>
 </div>
 <div>
削除対象のパスからフォルダ削除
`set REMOVEDIR=F:¥Data¥Dump¥REMOVEDAY`
 <div>
`rmdir /s /q %REMOVEDIR%`
 </div>
 </div>
 <div>
この処理だと何らかの作業でバッチ処理を停止させた場合、手動で削除しなければ永遠に残ってしまうフォルダ(DMP)が発生する。
過去バッチ処理を停止させた時に削除されなかったDMPが残ってしまいストレージを圧迫していた。
 </div>
<h2>今回の修正</h2>
 
 <div>
パワーシェルの日付取得は使わず、フォルダ名を日付でソートして取得する。最新日付のフォルダ以外は削除。
`for /f "skip=1" %%i in ('dir /ad /b /s /o:-n F:¥Data¥Dump¥') do rmdir /s /q %%i`
 </div>
 <div>
これで保存世代も２→１世代になり、バッチ処理を停止させた後も最新日付以外のフォルダは削除されるようになった。
 </div>
</div>
WordPressに導入したreCAPTCHA v3を特定ページでのみ読み込む方法

##はじめに

Googleが提供している認証システムの[reCAPTCHA v3](https://developers.google.com/recaptcha/docs/v3)は各種フォームに導入できる強力なスパム対策ですが、デフォルトでは全てのページで読み込まれてしまいます。

この状態では、全ページでreCAPTCHA v3のバッジが表示されてしまいますし、全ページでJavaScriptファイルを読み込むので、WordPressの表示速度も遅くなってしまうという課題を抱えています。

この記事では、簡単なカスタマイズにより、WordPressに導入したreCAPTCHAを特定ページでのみ読み込む方法を紹介します。

必要なページでのみreCAPTCHA v3を読み込むようにカスタマイズすることで、スパム対策とWordPressの高速化を両立することができます。

##reCAPTCHA v3を特定ページでのみ読み込む方法

WordPressのfunction.phpに以下のコードを設置してください。
管理画面から、外観→テーマエディター→テーマファイルで編集できます。

```function.php
function recaptcha_limitation() {
 if ( ! is_page( 'contact' ) ) {
  wp_deregister_script( 'google-recaptcha' );
 }
}
add_action( 'wp_enqueue_scripts', 'recaptcha_limitation' );
```

`is_page( 'contact' )`の部分は、reCAPTCHA v3を有効にしたいページのパーマリンクに合わせて変更してください。

上記コードは、お問い合わせフォームを設置した`https://hogehoge.com/contact/`でのみreCAPTCHA v3を有効にする場合を想定しています。

また、該当ページが複数ある場合は、`is_page( array ( 'contact1', 'contact2' ) )`のように配列で記述すればOKです。
jupyterlab-tocで折りたたみの矢印が表示されなくなった

# 問題発生
jupyterlab-tocをいつも通り使っていたら、折りたたみの矢印が表示されなくなった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457377/ebf913b6-bbe0-3c1b-e2cc-567d5f440210.png)
既に折りたたんでいたコードが開けなくなり詰んだので、対処法を残しておこうと思います

# 対処法
Advanced Setting Editorを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457377/5eb9053c-c559-ea88-00bf-3ac82f82b23f.png)

Table of Contentsの設定をtrueに変更して更新すれば解決です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457377/37c101e2-e9b0-55a6-7115-e79dbf5caba4.png)

やったね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457377/06272e19-394f-25ad-385f-469bf37ade33.png)
Componentを自動で追加する方法。


#はじめに

本日から初めて技術ブログを書いてみる。

小さなことでも学んだことは書いて行こうと思う。





##本題




![“shot” 2020-08-26 20.33.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688851/530a278c-67f1-c495-7a32-b4b6329c3800.png)

こんな感じでキューブを置いてみた。


普段は右下の「Add Component」を押してリジットボディなどコンポーネントを追加すると思うが、スクリプトを用意しておくだけで自動でそれをやってくれるスクリプトの書き方を見つけた。


``` C#(cs)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Testscript : MonoBehaviour
{

    void Start()
    {
        
    }

    void Update()
    {
        
    }
}


```

デフォルトではこんな感じになっていると思う。
名前は「Testscript」としてある。




そこのusing〜と書かれているところとクラス名が書いてあるところの間に


``` C#(cs)
[RequireComponent(typeof(追加したいコンポーネントの名前))]
```

こいつを追加してやれば、このスクリプトをくっつけたゲームオブジェクトはこの「追加したいコンポーネント」の部分に書かれたものを勝手に追加してくれる。
例えば「Rigidbody」なら


``` C#(cs)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(Rigidbody))]

public class Testscript : MonoBehaviour
{

    void Start()
    {
        
    }

    void Update()
    {
        
    }
}
```

こうする。


![“shot” 2020-08-26 20.44.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688851/536f084b-5840-69ed-53e4-30cda79d03ce.png)

そしてキューブにこのスクリプトをはっつけたら自動で「Rigidbody」も追加された。


このRequireComponentを書く癖をつけとけばコンポーネントのつけ忘れなどのミスも減らせるし、いちいち手動で追加する手間も省ける！
ferenOSの導入４(Winodowsのアプリケーション（LINE)を使う)

Windowsのアプリケーションを使うためには、wineをインストールします。
wineのリポジトリはferenOSでは既に設定されているため、基本的には追加する必要はありません。
普段遣いするOSなので、GUIで使えるWine管理ソフトであるQ4wine、winetricksを導入して使いやすくしてみます。
次のコマンドを実行してインストール
` sudo apt install -y q4wine`
` sudo apt install -y winetricks`
※q4wineをインストールするときに、wineのパッケージも付属してインストールされます。

インストール後は,` winecfg`を実行してwine mono、wineGeckoをイントールします。
winecfgの初回実行時にダイアログが表示されます。

Wineをインストールした直後は、日本語を表記するためのフォントが足りないので、一部のソフトで文字化けします。Winetricksからフォントを追加でインストールできるので、allfonts、fakejapanese,cjkfontsなどから適当なものを選んでインストールすれば、文字化けも解消すると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535888/2901f5a1-d615-a4ab-8785-1b5283503583.png)

設定後、ファイラー上のexeファイルをダブルクリックすると、実行が可能になっています。
例えば、LINEをferenOS上で使いたいとするなら,LINEの公式ホームページでインストール用実行ファイルをダウンロードして実行、インストール作業をすすめれば良いわけです。
LINEとWINE,FrenOSとの兼ね合いにもよると思いますが、今回は無事インストールができてメッセージも送れました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535888/033d3014-62cc-5a6c-956b-90c5c99e18dd.png)

-- バージョン情報 --
 ferenOS 2020.07
 LINE6.0.3.2213
 Wine 5.0.2 stable
DockerでMySQLが起動しない【解決方法】

# 経緯
さっきまで上がってたdocker-composeが急に上がらなくなった。
どうやらDBがネックになってるらしいぞ
↓
あれ！？ポートが指定できない！？ｱｲｴｰﾅﾝﾃﾞｰ!!

# 症状

``docker-compose up``すると``Bind: address already in use``と言うエラーが出る

# 結論
ローカルでMySQLが上がっており、ホスト側のポートで衝突が起きていました。

# 解決の流れ

## 原因分析
``Bind: address already in use``と言うエラーが出るということでポートの衝突が原因ということは明らか。
つまり考えるべきはホスト側かDocker側のどちらかである。

私はDocker側の問題だと思って調査を始めた

## Docker側にあり得る原因の対処


他のコンテナが生きておりポートが衝突してしまっていることを疑い、調べてみた。

というわけで、現在生きているコンテナ全停止``docker-compose down``または``docker stop ${docker ps -q}``、DBコンテナのみの実行``Docker run mysql:5.7 --name mysql -p 3306:3306``を試してみた。

### 【結果】

同じエラーを吐くのでこちらではないことがわかった。

(実際はビルドが問題ではとか思い、イメージの全削除とか言うことをしていたが完全に徒労だった。。。）

## ホスト側にあり得る原因の対処

ホスト側に原因があるとすれば別プロセスが使用してしまっていることを予想した。

まずソケットを表示するコマンドを叩いて状況確認

```shell
$ ss -atn
State     Recv-Q Send-Q                             Local Address:Port                  Peer Address:Port                                                                                                 
# 実際にはこの一番上にport 3306のソケットが表示されていた
LISTEN    0      128                                127.0.0.53%lo:53                         0.0.0.0:*                                                                                                    
LISTEN    0      5                                      127.0.0.1:631                        0.0.0.0:*                                                                                                    
LISTEN    0      224                                    127.0.0.1:5432                       0.0.0.0:*                                                                                                    
ESTAB     0      0                                    172.20.10.9:46516                 104.244.42.3:443                                                                                                  
ESTAB     0      0                                    172.20.10.9:43066               151.101.109.44:443  

```

プロセスがあることがわかったので、どのプロセスなのかを突き止める
``sudo``で実行しないと正しく見えな）い場合があるので注意（１敗）

```shell

$ sudo lsof -i:3306
COMMAND    PID     USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
mysqld    2055    mysql   ?u  IPv4    ????      XXX  TCP *:mysql (LISTEN)

```

mysqlの停止

起動コマンドは``systemctl``と``service``が存在する。
どちらでも上がるが、止めるのは上げたコマンドを使用しないと止まりません（１敗）

``sudo systemctl stop mysqld``もしくは``service mysqld stop``を実行

### 【結果】

解決！
Pythonにおける「self.クラス変数」でのクラス変数・インスタンス変数の参照順

## イントロ

Pythonにおけるクラス変数とインスタンス変数の概念を説明している際、クラス変数として定義したが、インスタンス変数としては定義していない変数に、インスタンス変数の記法である`self.クラス変数名`でアクセスできるのは変ではないか？と気付いた。

→ 簡単なコードを書いて`self.クラス変数`の挙動を確認した。

# 分かったこと

Pythonでは`self.変数名`と参照すると、
1. まずインスタンス変数を参照し、
2. **インスタンス変数が定義されていない場合には、エラーを返す前に同名のクラス変数を参照する。**

混濁を避けるため、インスタンス内でクラス変数を参照する場合は`クラス名.クラス変数名`と記載した方が無難。

## サンプルコード
``` self.py
class Hoge:
    id = 0

    @classmethod
    def dump_class(cls):
        print("クラス変数: ", cls.id)

    def construct(self, id):
        self.id = id

    def dump_instance(self):
        print("インスタンス変数: ", self.id)


if __name__ == "__main__":
    Hoge.dump_class()  # -> 0

    hoge_instance = Hoge()
    hoge_instance.dump_instance()  # -> 0, インスタンス変数を定義していない場合、同名のクラス変数が参照される
    hoge_instance.dump_class()  # -> 0

    hoge_instance.construct(id=10)  # インスタンス変数を定義
    hoge_instance.dump_instance()  # -> 10, インスタンス変数の参照が優先
    hoge_instance.dump_class()  # -> 0
```

## 参考

> クラス変数にアクセスする場合は、特別な理由がない限り「インスタンス.クラス変数」や「self.クラス変数」のようにアクセスすることは避けるべきです。Python ではインスタンス変数をインスタンスオブジェクトから生成することができ、意図せずクラス変数をインスタンス変数で隠蔽してしまうことがあります。
[Pythonのクラス変数とインスタンス変数 | UX MILK](https://uxmilk.jp/41600)
WSLでstarshipが遅すぎる問題

# 概要
WSLで zshに `starship` を導入したあと, Gitリポジトリ下での操作が遅すぎる問題が発生。
該当dirに `cd `するだけで5秒ぐらいかかることがあった。

# 解決手法
`git_status` を表示しないようにする。
私の場合はこれで解決した。

```~/.config/starship.toml
prompt_order = [
    "username",
    "hostname",
    "kubernetes",
    "directory",
    "git_branch",
    "git_commit",
    "git_state",
    # "git_status",
    "hg_branch",
    "docker_context",
    "package",
    "dotnet",
    "elixir",
    "elm",
    "erlang",
    "golang",
    "haskell",
    "java",
    "julia",
    "nim",
    "nodejs",
    "ocaml",
    "php",
    "purescript",
    "python",
    "ruby",
    "rust",
    "terraform",
    "zig",
    "nix_shell",
    "conda",
    "memory_usage",
    "aws",
    "env_var",
    "crystal",
    "cmd_duration",
    "custom",
    "line_break",
    "jobs",
    "battery",
    "time",
    "character",
]

```
JavaScript オブジェクト初級

### オブジェクトの勉強

連絡帳を作る

#### 入力してもらう内容を入れる変数を作る
```javascript

<script>
const user_name = prompt('なまーえ');
const user_age = prompt('なんさい？');
const user_area = prompt('どこすみ？');
const user_hobby = prompt('しゅみは？');
```

#### オブジェトに格納する
```javascript

const user = {};

user.name = user_name;
user.age = user_age;
user.area = user_area;
user.hobby = user_hobby;
```

#### オブジェクトをコンソールに表示する
```javascript

console.log(user);

</script>
```
thisとbind-apply-callの基本

thisとbind-apply-callをよくわかっていなかったので
自分なりに解釈

#this

```javascript
const person = {
  name: '次郎',
  hello: function () {
    console.log(`こんにちは${this.name}`)
  }
}

person.hello()//こんにちは次郎
```
オブジェクトのメソッドとして呼んだ場合「__this__」はそのオブジェクトを指す。

####上記のメソッドを定数にいれて関数として実行した場合

```javascript
const ref = person.hello
ref()//こんにちは
```
この時、メソッド内の「__this__」はグローバルオブジェクト(window)を指すことになる。



#bind
####thisを束縛できる。

```javascript
const ref = person.hello.bind(person)//ここでオブジェクトを指定
ref()//こんにちは次郎


function fn0() {
  console.log('こんにちは' + this.name)
}
const a1 = fn0.bind({ name: '太郎' })//オブジェクトをここで作っても渡せる
a1()//こんにちは太郎


function fn1(name) {
  console.log('こんにちは' + name + ' 年齢:' + this.age)
}
const b = fn1.bind({ age: 32 }, '次郎')//引数の束縛もできる
b()//こんにちは、次郎 年齢:32
b('三郎')//引数をいれてもbindが優先されるため、nameは次郎のままになる
```


「__bind__」を使う事で「__this__」の参照先を固定できる
第一引数に「__this__」の参照先、第二引数から関数の引数
__.bind(オブジェクト, 引数)__




#call&apply
###基本はbindと同じだが呼んだ時点で実行される


```javascript
function fn2(name, age) {
  console.log(`国>${this.country}_名前>${name}_年齢>${age}`)
}

const country = { country: '日本' }
fn2.apply(country, ['五郎', 19])//国>日本_名前>五郎_年齢>19
fn2.call(country, '八郎', 11)//国>日本_名前>八郎_年齢>11
fn2.bind(country, '六郎', 17)//この時点では実行されない
```
配列には「__apply__」、個別の引数には「__call__」

以上！

間違いがあったらご指摘いただけるとうれしいです。