OmniAICreator/Qiita-1.07M huggingface dataset:
【Python・Jupyter】クリップボードにコピーしたプログラムのコメントを翻訳して新しいセルに挿入する

#はじめに
日本語訳のないライブラリのドキュメントを読むときなど、地味に解釈に苦労することなどありますよね。
英語をスラスラ読めない方だとブラウザの機能で翻訳することが多いと思いますが、コメントだけでいいのにプログラム部分まで翻訳されてしまうのは困りものです。

そこで、Jupyter Notebook用にコメント部分だけ翻訳して、
どうせならシンタックスハイライト機能も活かしたいということで、新しいセルに貼り付けるごくシンプルなコードを書いてみました。

#コード
```python
from googletrans import Translator
import re
import pyautogui
import pyperclip as ppc
translator = Translator()

pyautogui.hotkey('b', 'enter')
code = ppc.paste()
en = re.findall("#\s*(.+?)\n", code)
ja = [translator.translate(e, dest="ja").text for e in en]
for e, j in zip(en, ja):
    code = code.replace(e, j)
ppc.copy(code)
pyautogui.hotkey('ctrl', 'v')
```

#使用した様子
<details><summary>元コード</summary><div>
[What is PyRPL?](https://pyrpl.readthedocs.io/en/latest/)

```python
# import pyrpl library
import pyrpl

# create an interface to the Red Pitaya
r = pyrpl.Pyrpl().redpitaya

r.hk.led = 0b10101010  # change led pattern

# measure a few signal values
print("Voltage at analog input1: %.3f" % r.sampler.in1)
print("Voltage at analog output2: %.3f" % r.sampler.out2)
print("Voltage at the digital filter's output: %.3f" % r.sampler.iir)

# output a function U(t) = 0.5 V * sin(2 pi * 10 MHz * t) to output2
r.asg0.setup(waveform='sin',
             amplitude=0.5,
             frequency=10e6,
             output_direct='out2')

# demodulate the output signal from the arbitrary signal generator
r.iq0.setup(input='asg0',   # demodulate the signal from asg0
            frequency=10e6,  # demodulaltion at 10 MHz
            bandwidth=1e5)  # demodulation bandwidth of 100 kHz

# set up a PID controller on the demodulated signal and add result to out2
r.pid0.setup(input='iq0',
             output_direct='out2',  # add pid signal to output 2
             setpoint=0.05, # pid setpoint of 50 mV
             p=0.1,  # proportional gain factor of 0.1
             i=100,  # integrator unity-gain-frequency of 100 Hz
             input_filter = [3e3, 10e3])  # add 2 low-passes (3 and 10 kHz)

# modify some parameters in real-time
r.iq0.frequency += 2.3  # add 2.3 Hz to demodulation frequency
r.pid0.i *= 2  # double the integrator unity-gain-frequency

# take oscilloscope traces of the demodulated and pid signal
data = r.scope.curve(input1='iq0', input2='pid0',
                     duration=1.0, trigger_source='immediately')
```
</div></details>
`In[2]`のセルを実行するとその下のセルが自動で生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501281/73a5d60f-8e6f-0792-525b-33b691dda40a.png)
AmazonのデータをKeepAPIを使って取得しよう  #1データの取得

##アマゾンデータを取得する
仕事でアマゾン(US)のデータを取得する必要が出たため備忘録のため。
商品概要、レビューに関してはスクレイピングでも取得はできると思うのですが
過去の出品状況や価格・ランキングなどは取得できないので
KeepaAPIを使って取得していきます。

参考：Keepa
https://keepa.com/#!api

##Pythonによるデータ取得加工
```Python:keepa_analysis.py
#ライブラリー
!pip install keepa
import keepa
import pandas as pd

#データ取得
accesskey = '##############' # APIkeyを取得し入力してください
api = keepa.Keepa(accesskey)
products = api.query('B07VQJ5P3L') # ここにはASINを入れるとデータを勝手に取ってくれます
keepa.plot_product(products[0])
```
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182397/f6bc0c95-e805-0216-57c1-7731072df126.png)
![ダウンロード (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182397/ede4df4c-efe9-c0d1-1810-517b40419f35.png)
実行してみるとこんなデータが取れます。
SLACKの利用時に気になったこと

Slackを利用する際にセキュリティなどが、どの様になっているのか気になったので、大まかにまとめてみました。

●フリープランと、有料プランの違いについて
以下に無料と有料のメリットを比較した物について記載がありました
https://slack.com/intl/ja-jp/pricing/paid-vs-free

情報セキュリティについては、無料の場合でもISOの認証を取得などをして対策している様です
https://slack.com/intl/ja-jp/security-practices

その他にですが、有料の「Enterprise Grid」プランの場合は、以下の様な対応・サービスの利用
できる様になります。
・HIPAA 準拠のメッセージとファイルでのコラボレーション
・監査ログ API
https://app.slack.com/plans/T01CLGER6N7?geocode=ja-jp

●SLACKにアプリを追加する
googleカレンダーなどを、以下の手順により連携できます
https://slack.com/intl/ja-jp/help/articles/202035138-%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B9%E3%81%AB%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B

利用方法、追加できる機能については以下にまとめてありました
https://slack.com/intl/ja-jp/help/categories/360000047926-%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%B9%E3%83%9A%E3%83%BC%E3%82%B9%E3%81%AB%E3%83%84%E3%83%BC%E3%83%AB%E3%82%92%E9%80%A3%E6%90%BA

slackと連携するサービスを自作する方法などについて、以下urlに例がありました
https://api.slack.com/tutorials/

その他に、フリープランでは利用できない様ですが、ワークフロービルダーという機能を、「スタンダード、プラス、Enterprise Grid」で利用できるみたいです。
https://slack.com/intl/ja-jp/help/articles/360035692513-%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%95%E3%83%AD%E3%83%BC%E3%83%93%E3%83%AB%E3%83%80%E3%83%BC%E3%82%AC%E3%82%A4%E3%83%89
ラビットチャレンジ - 深層学習 Day1 Section4 勾配降下法

# 0．概要
本記事は日本ディープラーニング協会認定の講座プログラムである「ラビット・チャレンジ」が提供している科目の1つである深層学習のレポートである。
記事タイトルに記載のとおり、Day1 Section4の勾配降下法について以下にまとめる。

# 1．勾配降下法の種類
* 勾配降下法(バッチ勾配降下法)
* ミニバッチ勾配降下法
* 確率的勾配降下法(SGD)
* Momentum：勾配の移動平均を出して振動を抑える(過去の勾配たちを考慮することで急な変化を抑える)。
* ネステロフの加速勾配法(NAG)：勾配が正しい向き(損失を減らす方向)に向いていることを保証したモーメンタム。
* AdaGrad：次元ごとに学習率を変化させるようにしたもの。
* RMSprop：AdaGradの改良版であり、一度学習率が0に近づくとほとんど変化しなくなるAdaGradの問題を改良したもの。
* AdaDelta：RMSpropの改良版であり、次元数のミスマッチ？を解消したもの。
* Adam：Momentum+RMSprop。つまり移動平均と学習率の調整。

...etc

色々あるが基本的にどれも勾配降下法がベースとなっている。
新しければ必ずしも以前のものより良いとは限らない。

https://qiita.com/omiita/items/1735c1d048fe5f611f80
https://qiita.com/ZoneTsuyoshi/items/8ef6fa1e154d176e25b8

バッチ勾配降下法ではメモリへの展開が困難であり、確率的勾配降下法では1件ずつ与えることになるため計算効率が悪いが、データをある程度のサイズごとに分けるミニバッチ勾配降下法の場合、1つ1つを大きくしすぎなければメモリへの展開も容易であり、かつ並列で処理することで効率よく計算が可能。
基本的に深層学習においてはどのような最適化関数を使うにしてもミニバッチで行うことが基本となる。

## 1.1．学習率
機械学習の方でも出てきた通り、パラメータの収束のしやすさ(勾配をどれだけの勢いで降りるかのイメージ)のハイパーパラメータ。

学習率が大きすぎる場合、最小値を飛び越えてむしろ値が大きくなったりして発散してしまう。
学習率が小さすぎる場合、最小値にたどり着くまでに何度も更新するため最小値まで時間がかかる。局所解に留まってしまう可能性がある。

機械学習の講座では$\eta$だったがこの講座では$\epsilon$。
これに限ったことではないが、人や書籍等によって使われる文字が違ったりすることには注意が必要。

# 2．オンライン学習
データを都度都度与えて学習させる学習手法。
データを一通り用意してから一度に与えて学習させるバッチ学習の逆。

バッチ学習の場合、一度に大量データをメモリ上に展開しないといけないため、都度都度データを与えるオンライン学習の方がよく使われている。

# 3．エポック
データセット全てを一度与えることを1エポックと言う。
例えば同じデータセットを2回与えるなら2エポックとなる。

ミニバッチで処理するなら1エポックの中にミニバッチがn個あることになる。

# 4．確認テスト

## 4.1．確認テスト1
「1_3_stochastic_gradient_descent.ipynb」から勾配降下法の下記数式に該当するコードを抜き出せ。

```math
w^{t+1}=w^{t}-\epsilon\Delta{E}
```

```Python
network[key] -= learning_rate * grad[key]
```

## 4.2．確認テスト2
オンライン学習とはなにか。

回答：
データを都度都度与えて学習させる学習手法。
データを一通り用意してから一度に与えて学習させるバッチ学習の逆。

## 4.3．確認テスト3
下記の数式の意味を図に書いて説明せよ。

```math
w^{t+1}=w^{t}-\epsilon\Delta{E}
```

回答：
![nn3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389699/5519a6db-a348-61dc-8f23-a8d324f241b5.png)

前回のエポックの誤差を元に重みを修正(学習)していくことによって、次のエポックではよりデータに適合した予測ができるようになっていく。
これを繰り返していくことになる。

# X．ラビットチャレンジとは
ラビットチャレンジとは、日本ディープラーニング協会認定の講座プログラムの1つ。
E資格を受験するためにはこのラビットチャレンジ等、いずれかの講座プログラムを修了しなければならない。

ラビットチャレンジの特徴は「現場で潰しが効くディープラーニング講座」の通学講座録画ビデオを編集した教材を使用した自習スタイルであるという点。
サポートは他の講座より少なく、受け身ではなく自主的に学んでいく姿勢でなければ進められないが、その分、他の講座に比べると安価であり、手が出しやすい。
ある程度知識がある人、自力で頑張るぞというガッツのある人向けではないかと感じる。

![bnr_jdla.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389699/bce66671-a2f5-a7f9-de6f-3f87e15c253b.png)
【Ruby】多重ループからの脱出【ネスト】



#多重ループから一気に抜け出したい
`Kernel.#throw`と`Kernel.#catch`を使います。


```ruby
sum = 0
catch(:escape_test) do
  for i in 1..3
    for j in 1..3
      sum = i + j
      # sum > 0 になった時点で一気に脱出したい
      throw(:escape_test) if sum > 0
    end
  end
end

p sum
=> 2
```

`i = 1, j = 1`の一回目の加算の段階で`sum > 0`の条件を満たすので、
この時点で`throw(:escape_test)`が呼び出され、**`jのfor文`と`iのfor文`の両方から脱出**します。

比較として同じロジックを`break`で使うと次のようになります。

```ruby
sum = 0
for i in 1..3
  for j in 1..3
    sum = i + j
    # jのループから脱出
    break if sum > 0
  end
end

p sum
=> 4
```
このように、`break`では**`もっとも内側のループ(今回はjのfor文)を脱出`**するので、`iのfor文`は回っていき、
`i = 3, j = 1`で処理が終了するため`sum = 4`となります。

#おまけ:catchの戻り値
```ruby
sum = 0
c_value = catch(:escape_test) do
  for i in 1..3
    for j in 1..3
      sum = i + j
      # sum > 0 になった時点で一気に脱出したい
      throw(:escape_test, sum) if sum > 0
    end
  end
end

p c_value
=> 2
```
このように、`throw`の第二引数に値を渡すと`catch`の戻り値となります。

#参考
- [Kernel.#throw](https://docs.ruby-lang.org/ja/latest/method/Kernel/m/throw.html)
- [Kernel.#catch](https://docs.ruby-lang.org/ja/latest/method/Kernel/m/catch.html)
- [多重ループから抜ける
](https://qiita.com/pigcafe/items/6dee8855528e104afac8)
Rancher2.5でマルチクラスタデプロイ運用をやってみる

# 概要

Rancherを使って複数のクラスタにアプリケーションのデプロイをやってみます。
Rancher2.4まではそのための機能として[MultiClusterApps](https://qiita.com/yamaneko_usg3/items/9e483780d08024e3c754)が用意されていましたが、Rancher2.5では非推奨となり代わりにContinuousDeliveryを使用するように変更になりました。

今回、ContinuousDeliveryでどれだけマルチクラスタデプロイが簡単になったか検証してみたいと思います。

# ContinuousDelivery

グローバルメニューのToolsから選べます。
Rancher本体の画面ではなくfleetというプロダクトの画面が開きます。

![スクリーンショット 2020-10-20 0.27.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/1daeda45-fb84-4836-2d2a-07ab9da3d308.png)

# マルチクラスタアップロードの手順

## クラスタにラベルをつける

グルーピングしやすいように各クラスタにラベルをつけます
今回の例では以下５つのクラスタにtypeとenvironmentのラベルをつけます

- usagisan（LinuxServer）
  - type: amd64
  - environment: production 
- kumasan（LinuxServer）
  - type: amd64
  - environment: production 
- nukosama（LinuxServer）
  - type: amd64
  - environment: staging
- butasan（LinuxServer）
  - type: amd64
  - environment: staging
- wanko（RaspberryPi4）
  - type: arm64
  - environment: production

Clusters
![スクリーンショット 2020-10-20 0.33.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/a194eb2a-7eef-0ac7-017b-34cff7e209b8.png)

ラベルを指定
![スクリーンショット 2020-10-20 1.00.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/d153940b-ba6a-d26a-4dee-77f43aef1b83.png)

## クラスタグループの作成

先ほど付与したラベルを元にグループを作成します。
デプロイはこのグループの単位で行うことになります。（クラスタ単独でも可）

Cluster Groups
![スクリーンショット 2020-10-20 0.40.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/c67a96bc-cc8f-004c-7ef1-c0b6fbd2b113.png)

セレクタにラベルを指定することで任意のクラスタをグルーピングします。
type=amd64,environment=productionの２つのラベルでセレクタを作成すると、２つのクラスタが選択されます。
![スクリーンショット 2020-10-20 1.01.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/c3475018-3ae2-9c62-e836-1a96afbaa129.png)

なお、グループ作成後にクラスタ側のラベルを変更するとグループへの参加/離脱も自動で反映されます。

## Gitリポジトリとグループの紐付け

作成したグループとマニフェストのあるリポジトリを紐付けます。
こうすることで、マニフェストファイルに変更が入ると自動で対象グループにデプロイされます。
（対象はグループではなく単独のクラスタでも可）

Git Repos

リポジトリのURLやmanifestファイルのあるパスを指定し、デプロイ対象にグループを指定します。

注）リポジトリのブランチはデフォルトで「master」となっています。GitHubは現在デフォルト「main」なので、新規にリポジトリを起こす場合は忘れずブランチ名を変更してください。

![スクリーンショット 2020-10-20 1.13.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/8ef751ef-a348-3bc1-d90e-00e71cd8975b.png)

無事デプロイされたら成功です。
![スクリーンショット 2020-10-20 1.17.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306826/72f88d5d-4aab-1a2f-54e7-c53c0ffe6997.png)

# まとめ

Rancher2.4までのMultiClusterAppsでは画面からのデプロイはクラスタの選択がめんどくさくて数が多いと運用が厳しい印象でした。（代わりにCLIでの運用はできましたがスクリプトを作成する必要があるなど少し手間がかかる）

ContinuousDeliveryではラベルでグルーピングできるようになったため、事前にグループを作成することでデプロイ単位を簡単に管理できますし、なによりRancherだけでマルチクラスタに対してGitOpsができるのは格段進化したと感じます。
もちろんArgoCDなどと比べるとGitOpsの機能としてはまだまだ基本的なものしかありませんが、IoTエッジデバイスのような大量デバイスに簡単にデプロイするような使い方としては（Rancher的にもそういう使い方をきっと想定しているはず）かなり強力ですね。

# 最後に少しだけ

今回動作確認中に何度かエラーが発生することがありました。
私の環境だけなのか、まだ機能追加されたところなので不安定なのか、その辺の切り分けができていません。
引き続き動かしながら確認したいと思います。
[Rails] form_withでパラメーターを取得できないときの対処法

#解決法
- urlかモデルのみを記述する。（今回はurlのみ記述）

編集前

```erb:_form.html.erb
<%= form_with(model: @set, url: "/sets/create", local: true) do |f| %>
  <div class="form-title">
    <%= f.label :title, "タイトル" %>
    <%= f.text_field :title %>
  </div>
<% end %>
```

編集後

```erb:_form.html.erb
<%= form_with(url: "/sets/create", local: true) do |f| %>
  <div class="form-title">
    <%= f.label :title, "タイトル" %>
    <%= f.text_field :title %>
  </div>
<% end %>
```
Laravel7マイグレートエラー（SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint）

Laravelで、タグ付けのできる投稿サイトをチームで制作しています。
投稿テーブル（**reviews**）を先に作っていたのですが、今回タグテーブル（**tags**）を作成し、reviewsとは**review_tag**という中間テーブルで多対多のリレーションを作成したいです。
しかし、マイグレートした時にエラーで少しだけ苦しんだのでメモしておきます。

#問題点はここ

```terminal
$ php artisan migrate

Migrating: 2020_09_19_035606_create_tags_table
Migrated:  2020_09_19_035606_create_tags_table (0.08 seconds)
Migrating: 2020_09_19_053140_create_review_tag_table

   Illuminate\Database\QueryException 

  SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `review_tag` add constraint `review_tag_tag_id_foreign` foreign key (`tag_id`) references `tags` (`id`) on delete cascade)
```

外部キーが設定できないぜと仰っているようです。いろいろ調べると、**主キーidの設定でBIGINTとINTは両立できない模様**。

エラーになった時の３つの各テーブルのマイグレーションファイルは下のようになっていました。主キーを設定している箇所にご注目ください。

reviewsテーブルのマイグレーションファイル↓

```php:XXXXXX_create_reviews_table.php
class CreateReviewsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('reviews', function (Blueprint $table) {
            $table->id();//BIGINTの主キー
            $table->date('live_date');
            $table->string('title', 255);
            $table->text('text');
            $table->timestamps(0);
            $table->foreignId('user_id')->constrained('users');
        });
    }
```


tagsテーブルのマイグレーションファイル↓

```php:XXXXXX_create_tag_table.php
class CreateTagsTable extends Migration
{
     * @return void
     */
    public function up()
    {
        Schema::create('tags', function (Blueprint $table) {
            $table->increments('id');//BIGINTではないid主キー
            $table->string('tag_name', 30);
            $table->string('info');
            $table->string('url');
            $table->timestamps();
        });
    }
```
review_tag中間テーブルのマイグレーションファイル↓

```php:XXXXXX_create_review_tag_table.php
public function up()
    {
        Schema::create('review_tag', function (Blueprint $table) {
            $table->increments('id');//BIGINTではないid主キー
            $table->timestamps();
            $table->foreignId('review_id')->constrained('reviews')->onDelete('cascade'); //foreignIdはunsignedBigIntegerのエイリアス
            $table->foreignId('tag_id')->constrained('tags')->onDelete('cascade'); //foreignIdはunsignedBigIntegerのエイリアス
        });
    }
```

#こう解決しました
まず、MySQLにて`drop table テーブル名;`でtagsとreview_tagを一旦削除。
次に、tagsとreview_tagのマイグレーションファイルにて、`$table->increments('id');`を`$table->id();`に変更。
（正直、reviewsと中間テーブルを挟んで間接的にしか繋がってない(?)tagsテーブルの方のマイグレーションファイルのidも修正が必要だったのかは不明...）
こうして再度マイグレートしたら、エラー出ずに上手くいきました。

```terminal
$ php artisan migrate
Migrating: 2020_09_19_035606_create_tags_table
Migrated:  2020_09_19_035606_create_tags_table (0.03 seconds)
Migrating: 2020_09_19_053140_create_review_tag_table
Migrated:  2020_09_19_053140_create_review_tag_table (0.09 seconds)
```


以上になります。ごもし指摘などあれば、ぜひよろしくお願いします。
【AWS SAA合格体験記】資格習得の過程でAWSが少し好きになれた

#はじめに
資格習得に向けて勉強するまでは、AWSはとても難しく扱いづらいものだという印象を持っていました。
私の作り出したAWSに対するイメージからIT業界歴1年半経ちますが、AWSと向き合うのを敬遠していました。
そんな私が、タイトルにもある通り資格習得の過程でAWSがもたらす利便性を知るにつれて少し好きになることが出来ました。
本記事は、AWSのSAA試験を合格するために行なった勉強法を中心に記載しております。

#資格を取ろうと思ったきっかけ
きっかけは大きく3つあります。

* Youtuberの**[くろかわこうへい](https://www.youtube.com/channel/UCX30pfp4p82rIiSJmBygADw?pbjreload=102)**さんが投稿していたAWS関連の動画を見て、AWSについて深く勉強したいと思ったから

* AWSのサービスを使用している現場が多く、ある程度基礎的な知識は身に付けておいたほうが良いと思ったから

* Qiitaに投稿されているポートフォリオ関連の記事でAWSを使用するしている人が非常に多く、焦りから勉強しようと思った

# 勉強開始前の状態
* AWSを触ったことがなく、そもそもAWSって何？の状態

#使用した教材　＋　レビュー

+ [この1冊で合格-AWS認定ソリューションアーキテクト-アソシエイト-テキスト-問題集](https://www.amazon.co.jp/%E3%81%93%E3%81%AE1%E5%86%8A%E3%81%A7%E5%90%88%E6%A0%BC-AWS%E8%AA%8D%E5%AE%9A%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-%E5%95%8F%E9%A1%8C%E9%9B%86/dp/4046042036)
AWSの主要サービスを丁寧に説明しており、AWS初心者が初めに勉強する教材としてはおススメかなと思います。
自分は、仕事場まで電車通勤なのでその時に読んでいました。

+ [これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（SAA-C02試験対応版）](https://www.udemy.com/course/aws-associate/)
AWS20サービス以上のハンズオン、3回の模擬テスト付き。
udemy教材で、セール期間中は千円台で購入可能。ハンズオンはすごく楽しく、勉強のモチベーションアップにつながった。

+ [【SAA-C02版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-knan/)
SAA本番と同レベルの6回の模擬テストが付いている。
難易度は高いけど、良問揃いで使用した教材の中で一番おススメ！！！
こちらもudemy教材です。

# 勉強のスケジュール
簡単にスケジュールと学習した内容を記載しました。

##参考書を読む(2020年7月上旬～2020年7月上旬)
[この1冊で合格-AWS認定ソリューションアーキテクト-アソシエイト-テキスト-問題集](https://www.amazon.co.jp/%E3%81%93%E3%81%AE1%E5%86%8A%E3%81%A7%E5%90%88%E6%A0%BC-AWS%E8%AA%8D%E5%AE%9A%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-%E5%95%8F%E9%A1%8C%E9%9B%86/dp/4046042036)
上記参考書を1カ月、繰り返し読み込みました。読者の皆さんは、「参考書読むのに期間長すぎ！」と思った方もいると思います。私もそう思います。学習方法を振り返ったとき、一番の反省はこの時期でした。1、２周読んでも頭に内容が入ってこず、気づけば7週くらい読んでました。それでも内容の半分くらいしか理解できていませんでした（笑）
**これからSAAを勉強する人に向けてアドバイスをするなら、インプットにあまり時間をかけないことが大事かなと思います。時間かけすぎるとだんだんやる気が落ちてきますし、アウトプットする中でAWSサービスを理解することが多かったです。**

##AWSを実際に使ってみる(2020年8月上旬～2020年9月上旬)
ハンズオン形式の講義でAWSの利便性を肌で感じました！AWSの凄さを少し理解できるようになり、AWSを好きになり始めた時期。講義で使用する資料は、綺麗に整理されているので試験前もよく確認してました。3回分の模擬試験は本番に比べて難易度が割とやさしめな印象です。

##問題集を解く(2020年9月中旬～2020年10月中旬)
初見のときは、難しすぎて試験合格は絶対無理だと思いました！一週目では正解率30～40％くらいでした。解説を丁寧に読み、理解できない単語があればBlackBeltやQiitaを使っていました。6回分の模擬試験がありますが、すべての回で正解率が90%以上出るまで繰り返し演習しました(4週かかりました)。

#試験結果
**778/1000**でぎりぎり一発合格できました。見直ししてなかったら、多分落ちてました。1週解いた時点で残り60分ほどあり、じっくり見直しできたのが合格の要因かと思います。

#まとめ
AWSの基礎知識を身に付いた思うので、次はアプリ開発でAWSサービスを使ってみようと思います。AWSをもっとすきになれるよう日々、勉強したいと思います。

長々と書いてしまいましたが、ここまで読んでいただきありがとうございました。
もしよろしければ、LGTM押していただけると幸いです。
タップした場所にフォーカスを合わせる

iPhoneのプリインストールのカメラアプリと同じように、タップした場所にフォーカスします。
![Oct-20-2020 01-03-47.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/ee4e7af9-873c-4689-fc4b-b9f526511ab4.gif)

#手順
###１、タップでView内の座標を取る
UITapGestureRecognizerをカメラのプレビューレイヤーを含むViewに加えます。
タップで以下の関数を呼びます。

```swift
@objc func tapForcus(_ recognizer:UITapGestureRecognizer) {
let pointInView = recognizer.location(in: recognizer.view)
print(pointInView)
// (562.0, 282.0)
}
```

###２、View内のタップ座標を、AVCapturePreviewLayer内の座標（０〜１）に正規化する
カメラ画像領域の座標は、常にLandScapeLeftの左上が(0,0)右下が(1,1)です。
![スクリーンショット 2020-10-19 23.51.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/37fce5fc-6352-6deb-cc99-8d72bed33cf4.png)
タップしたView座標をカメラ画像領域の座標に変換するには、AVCapturePreviewLayerの座標変換メソッドが使えます。

```swift
let pointInCamera = previewLayer?.captureDevicePointConverted(fromLayerPoint: pointInView)
print(pointInCamera)
// Optional((0.38380281690140844, 0.41796875))
```

###３、取得した座標にフォーカスを合わせる
フォーカスの関心ポイントをタップしたポイントに設定してから、フォーカスモードを設定しなおします。
関心ポイントを設定した後で、都度フォーカスモードを設定します。でないと、フォーカスされません。

```swift
// avCaptureDeviceは、当該セッションのAVCaptureDevice

do {
    try avCaptureDevice.lockForConfiguration()
    avCaptureDevice.focusPointOfInterest = pointInCamera!
    avCaptureDevice.focusMode = .autoForcus // .autoForcus（固定） もしくは .continuousAutoFocus（デバイスによる自動監視継続）
    avCaptureDevice.unlockForConfiguration()
} catch let error {
    print(error)
}
```

###おまけ：フォーカスアニメーション
フォーカスビューの設定

```swift
var forcusView = UIView()
```

```swift
var forcusView = UIView()
forcusView.frame = CGRect(x: 0, y: 0, width: view.bounds.width * 0.3, height: view.bounds.width * 0.3)
forcusView.layer.borderWidth = 1
forcusView.layer.borderColor = UIColor.systemYellow.cgColor
forcusView.isHidden = true
```
タップでアニメーション

```swift
// @objc func tapForcus(_ recognizer:UITapGestureRecognizer) {
// let pointInView = recognizer.location(in: recognizer.view)

forcusView.center = pointInView // タップしたポイントへ移動する
forcusView.isHidden = false // 現れる
UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 0.5, delay: 0, options: []) {
   self.forcusView.frame = CGRect(x: point.x - (self.view.bounds.width * 0.075), y: point.y - (self.view.bounds.width * 0.075), width: (self.view.bounds.width * 0.15), height: (self.view.bounds.width * 0.15)) // タップしたポイントに向けて縮む
} completion: { (UIViewAnimatingPosition) in
   Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { (Timer) in
        self.forcusView.isHidden = true // 少し待ってから消える
        self.forcusView.frame.size = CGSize(width: self.view.bounds.width * 0.3, height: self.view.bounds.width * 0.3) // 少し大きめのサイズに戻しておく
    }
```

🐣
****
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
SLF4Jとは?

【背景】

エラーでつまづきそもそもSLF4Jとは何だ？
という所から調べてみた。

【エラー文】

```java
java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
```

##SLF4Jとは?

>SLF4Jは、ロギングシステム用のシンプルなファサードであり、エンドユーザーが展開時に目的のロギングシステムをプラグインできるようにします。


##ファサードとは？
>Facadeクラスとは、使い方が複雑になっているクラス群をまとめ、使いやすい形のインターフェースとして外部に提供するクラスのことを指します。
デザインパターンでは、このFacadeクラスを利用するパターンをFacadeパターンと呼びます。
（ちなみに、Facadeは「窓口」を意味する単語です）

【直訳】
Simple Logging Facade for Java (SLF4J) は、様々なロギングフレームワーク (java.util.logging, logback, log4j など) のためのシンプルなファサードまたは抽象化として機能し、
エンドユーザがデプロイ時に希望するロギングフレームワークをプラグインすることを可能にする。


ライブラリをSLF4Jで有効にすることは、単一の必須の依存関係、
すなわちslf4j-api.jarを追加することを意味することに注意してください。
もしクラスパスにバインディングが見つからない場合、SLF4J はデフォルトで動作しない実装になります。

JavaソースファイルをSLF4Jに移行したい場合は、
数分でSLF4J APIを使用するようにプロジェクトを移行できるマイグレータツールを検討してください。

あなたが依存している外部的に保守されているコンポーネントがSLF4J以外のロギングAPIを使用している場合、commons logging、log4j、java.util.loggingのように、レガシーAPIのためのSLF4Jのバイナリサポートを見てみてください。


※注意点
クラスパスにバインディングが見つからない場合、SLF4J はデフォルトで動作しない実装になる。

##まとめ


##参考にした記事（いつもありがとうございます。）

[SLF4J、Logback、Log4Jの関係を挙動とともに整理する
](https://qiita.com/NagaokaKenichi/items/9febd2e559331152fcf8)

[Simple Logging Facade for Java (SLF4J)
](http://www.slf4j.org/)

[Frequently Asked Questions about SLF4J](http://www.slf4j.org/faq.html#what_is)

[javaでのFacadeパターン
](https://cyzennt.co.jp/blog/2019/12/14/java%E3%81%A7%E3%81%AEfacade%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3/#:~:text=Facade%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A8%E3%81%AF%E3%80%81%E4%BD%BF%E3%81%84%E6%96%B9,Facade%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E3%81%A8%E5%91%BC%E3%81%B3%E3%81%BE%E3%81%99%E3%80%82)
Expert help of Printer

Are you using a printer for a long time and need to update functionality or need to contact printer experts? Dial our HP support number for the expert help.
![HP Printer Support.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345482/932fe2cd-060c-9dd6-8086-a67a73456c61.png)
 
Printers are very useful machines and as we know printers are used for printing purposes. With the uses of printers, there are some things that we have to maintain with printers, and with the uses of these things,  you can extend your printer’s life. The useful things, from that we can extend our printer’s life are cleaning your printer's life, refrain from using bent, should use high-quality paper, should store paper in a low humanity environment, should use new good rollers and many other things you should main for your printer’s life. To know all those important things, you should visit our HP Support web-page. And from the title, you must be clear that we are here for troubleshooting the printer issues. So if you are one of them who is facing technical issues with printers then contact our experts to dial our HP Printer Support Number for help. We are here to help you, so you should never hesitate to contact us.
Visit Our Web-Page:
https://www.customerservicehelpnumber.com/hp-printer-support
Ref. URL:
https://jw06033.kinja.com/expert-help-of-printer-1845409334
Thank You.
【Bubble】Dropdownに動的にデータをセットする

現在、バーの予約サイトをbubble.ioにて構築中なのですが、Dropdownに設定する選択項目を動的に変えようとしたときにちょっと迷ったのでまとめます。

# やりたいこと
選択した日付に対して、Dropdownで選択できる予約人数を動的に変化させたい。

# 悩んだこと
当初は予約可能人数を固定で考えたので、以下のように静的に値をセットしていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/802620/cceceb91-193c-417d-f2be-9e5826dfce2f.png)

途中で、予約可能人数を予約済み人数を考慮して変えられるようにしたいという要望が出てきました。
プログラム的には予約可能人数を計算で求めて、ループさせて登録させるような形になると思いますが、bubble.ioだとそのように動的に項目をセットできなさそうでした。（自分の調査不足かもしれませんが……）

# 解決方法
データベースに選択項目を列挙したテーブルを用意しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/802620/a62287b1-c596-34cd-42d8-48457b2d07d7.png)

これを使えば、テーブルから動的に選択項目のリストを作ることはできるので、こんな感じで予約可能人数に合わせてDropdownの選択項目を変更することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/802620/01267043-5371-2328-9257-3d4fb0d3bd5d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/802620/03bf7c0e-5e75-5af2-2374-046cf67dcfd4.png)

この"10"を予約可能人数にします。
今回は、Workflowにて日付変更時に予約可能人数を計算して、custamStateにセットしており、それを使用するようにします。



bubbleにおけるデータベースの考え方を、通常のコーディングと同じように考えないほうがいいかなという感想。
画面に表示するような列挙項目はテーブル上にどんどん定義したほうが使いやすいのかもしれない。
まだまだbubbleに触れて数日しかたっていないので、もっといい方法があるかもしれないですけどね。
オブジェクトのある特定のキーを取得する方法 



オブジェクトのある特定のキーを取得する方法が日本語であまり見当たらなかったのでまとめてみました。

ユーザーの情報が格納されている`usersオブジェクト`があるとする。

```
const users = {
  "Jonh": {
    sex: 'male',
    age: 30,
    height: 175,
  },
  "Bob": {
    sex: 'male',
    age: 25,
    height: 175,
  },
  "Hanna": {
    sex: 'female',
    age: 23,
    height: 160,
  },
};
```

## 全てのキーの取得方法
オブジェクトの中にあるキーを全て取得したい場合には、

```
Object.keys(users); // return Jonh, Bob, Hanna
```
`Object.keys()`メソッドの引数に、オブジェクト変数を入れてあげることで取得できる。

## ある特定のキーの取得方法

```
Object.keys(users)[0]; // return Jonh
```
`[]`の中に取得したいオブジェクトのキー番号を指定することで取得ができる。
一番初めのキーを取得したい場合には、0を指定。

これでok

## 参考サイト
- [mozilla](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/keys)
- [How to access the first property of a Javascript object?] 
 (https://stackoverflow.com/questions/983267/how-to-access-the-first-property-of-a-javascript-object)
- [How to get the first key name of a JavaScript object ?](https://www.geeksforgeeks.org/how-to-get-the-first-key-name-of-a-javascript-object/)
Vuetifyのcodeタグの装飾を止める

Nuxt/contentとVuetifyを使ってブログを作ろうとしていたけど、
codeタグの文字が勝手に装飾されてしまってprismのコードハイライトが大変見えにくくなっていた。
#解決法
nuxt.config.jsに以下の設定を追加

```js:nuxtconfig.js
...
vuetify:{
    customVariables: ['~/assets/variables.scss'],
    treeShake: true
}

```
次に/assets/variables.scssに(なければ作成)以下を追加

```scss:~/assets/variables.scss
$code-background-color:initia;
$code-color:initia;
```

以上で多分直る

# 解説
公式ドキュメントにはパッと見た感じ
>Vuetifyには、複数の標準要素のカスタムスタイルがあります。
https://vuetifyjs.com/en/styles/content/

としか書かれておらず、無効化する方法なんて一切書かれていない

しかし、公式ドキュメントと半日にらめっこしていると、
sass変数一覧にしれっと
>##SASS Variables
|Name  |Defalt  |
|---|---|---|
|$code-background-color |#FBE5E1 !default;  |
|$code-color  |#C0341D !default;  |
https://vuetifyjs.com/en/api/vuetify/#sass-variables

って書いてあった。
自分の読解力とかエンジニア力が足りなかっただけだと思うが非常にわかりにくいと感じた。

あとは
https://vuetifyjs.com/en/features/sass-variables/
に従って適当にしてやったらできた。
multiple属性のinput type='file'にドラッグ&ドロップで複数のファイルを一個ずつ追加していく方法

#はじめに
ファイルを選択するフォームがある際、
ドラッグ&ドロップができるとスマートで便利ですよね。

mulitiple属性がつくと複数のファイルを一つのフォームで送信が可能です。
そうした上でドラッグ&ドロップで選択する仕様にするのはさほど難しくはありませんでした。
しかし、複数同時にドロップするのではなく、
その複数のファイルを一個ずつドロップできるようにしたかったのですが...

ちょっとツマってしまったので、その解決方法をメモ。

#実装

```html:sample.html
<form action="~~~" accept-charset="~~~" method="post">
  <input multiple="multiple" type="file" name="task_images" id="task_images">
  <div id="dropZone" style="width:~~~px;height:~~~px;">
    ここにドラッグ&ドロップ
  </div>
  <input type="submit">
</form>
```

`"~~~~"`や`name="task_images"`は例です。
ここでは扱うファイルを画像ファイルを想定してます。
idの`"task_images"` `"dropZone"`でそれぞれの要素を取得していきます。

```js:sample.js
  var fileField = document.getElementById('task_images');
  var dropZone = document.getElementById('dropZone');
  var dt = new DataTransfer();

dropZone.addEventListener('drop', (e)=>{
  e.preventDefault();
  dt.items.add(e.dataTransfer.files[0]);
  fileField.files = dt.files;
});
```

`dt`に代入された`DataTransferオブジェクト`はドラッグ＆ドロップされたデータを扱う、保持するために使われます。
なお、safariとIEは`new`に対応していないので注意！

`e.preventDefault();`がないとドロップできないので大事です。

`dt.items`は`DataTransferItemListオブジェクト`
`dt.files`と`e.dataTransfer.files`は`FileListオブジェクト`です。
`e.dataTransfer.files[0]`は`Fileオブジェクト`です。
非常にややこしい！

`e.dataTransfer.files`にはドロップされたファイル(`Fileオブジェクト`)が`FileListオブジェクト`の中に同時にドロップされた数だけ格納されています。
今回は一つずつドロップし選択するので`e.dataTransfer.files[0]`を`add`メソッドで`dt.items`に追加します。
そうすると`dt.files`に`FileListオブジェクト`として変更が反映されています。

最後にinputエレメントである`fileField`の`files`を`dt.files`に差し替えます。
これでドロップによってinputのファイル選択を追加していくことができます。

#最後に

DataTransferにはclearData()など応用の利くメソッドがあるので、
使いようによってはファイル数の制限も実装できます。
画像プレビューにも使うこともできるので、ぜひ調べて見てください。

#参考
[DataTransfer](https://developer.mozilla.org/ja/docs/Web/API/DataTransfer)
[Document: drop イベント](https://developer.mozilla.org/ja/docs/Web/API/Document/drop_event)
[FileListは作れる！～file inputの中身も自由自在～](https://qiita.com/jkr_2255/items/1c30f7afefe6959506d2)
Chainerによる機械学習のためのPython学習メモ　10章 Cupy 入門

# What
Chainerを利用して機械学習を学ぶにあたり、私自身が、気がついた点、リサーチした内容をまとめる記事になります。今回は、scikit-learnを勉強します。

私の理解に基づいて記述しているため、間違っている場合があります。間違いは都度修正するつもりです、ご容赦ください。

#Content

###GPU
画像処理に特化した演算装置。CPUと原理上何が異なっていて画像処理に有利なのか全く理解できていない。
例えば、下記サイトではCPUとGPUの違いが簡単に説明されている
https://www.datadock.co.jp/column/GPU/2018/05/88.html
ただ本質的な理解をするためには、まずCPUが得意とする処理、GPUが得意とする処理を抑える必要がありそうだ。
定正的な話だけをするなら、似たような処理を同時に複数行うのは現在、並列演算が高速化を可能とする領域であること。数値計算を並列かつ高速に処理できるのがGPUということだけはわかった。
ちなみに、GPUのメーカーNDIVIAは最近ひそやかに注目を浴びていてAIの流れが大きいみたいですね。
**CupyではGPUを必要としますが、なんとColabではGPUも使用可能とのこと、すごい！**

###Cupy
内容読んでも、正直そんなにまとめることがないです。。。
Cupyで記述することでGPUで数値計算することができ、高速動作が期待できる。
できるだけ数値計算はNumpyではなくCupyを使って記述することで高速動作するコードがかける。書き方に困ったら適宜調べるという形で大丈夫そう

#Comment
気温がガクッと下がり体調を崩しやすい時期ですね、、、
土日は頭痛と眠気が酷く、寝こんでしまいましたorz
【Looker】label系パラメータまとめ

まだ理解が曖昧なので、随時「こんな時に使うと便利」や「この書き方はアンチパターン」みたいなのを追加していく。

# view

- [label](https://docs.looker.com/ja/reference/view-params/label)
    - フィールドピッカーで表示されるviewの名称を設定することができる
    - 複数のviewで同一名称を設定することで、フィールドピッカーで1つのまとまりとして表示することもできる

# view -> dimension

- [label](https://docs.looker.com/ja/reference/field-params/label-for-field)
    - フィールドピッカーで表示されるdimensionの名称を設定することができる
    - Luqid Variablesを使うことで、ユーザー属性の値を呼び出したり、呼び出した値を比較して表示する名称を切り替えることもできる

- [view_label](https://docs.looker.com/ja/reference/field-params/view_label)
    - フィールドピッカーで表示されるviewの名称を設定することができる
    - Liquid Parameterを使うことで、動的に名称を切り替えることもできる？

- [label_from_parameter](https://docs.looker.com/ja/reference/field-params/label_from_parameter)
    - 選択したparameterの値にあわせて、ExploreのVisualization上で表示される名称を設定することができる

# view -> dimension_group

- [label](https://docs.looker.com/reference/field-params/label-for-field?version=7.16&lookml=new)
    - view -> dimension のlabelパラメータと同義

# view -> measure

- [label](https://docs.looker.com/reference/field-params/label-for-field?version=7.16&lookml=new)
    - view -> dimension のlabelパラメータと同義

- [view_label](https://docs.looker.com/reference/field-params/view_label?version=7.16&lookml=new)
    - view -> dimension のview_labelパラメータと同義

- [label_from_parameter](https://docs.looker.com/reference/field-params/label_from_parameter?version=7.16&lookml=new)
    - view -> dimension のlabel_from_parameterと同義

# model

- [label](https://docs.looker.com/reference/model-params/label-for-model?version=7.16&lookml=new)
    - Exploreタブを開いた際に表示されるmodelの名称を設定することができる

# model -> explore

- [label](https://docs.looker.com/reference/explore-params/label-for-explore?version=7.16&lookml=new)
    - Exploreタブを開いた際に表示されるexploreの名称を設定することができる

- [view_label](https://docs.looker.com/reference/explore-params/view_label-for-explore?version=7.16&lookml=new)
    - フィールドピッカーで表示されるviewの名称を設定することができる

- [group_label](https://docs.looker.com/reference/explore-params/group_label?version=7.16&lookml=new)
    - 複数のexploreに対して、同一の名称を設定することで1つのまとまりとして表示することができる
データベース (DB)からseedsファイルにdumpする方法

　そもそも、データベース（DB）からseedsファイルにdumpとは？
　私は初め```dump```とはどういうことかわかりませんでした。。
　そして、以前なんとなくコマンドやコードを丸写ししていて、エラーやトラブルが起こった時に、どうしていいか分からなく先輩に助けてもらったことがあります。
　こういう時は、自分で考えられるように、何が起こっているのか、何が原因なのか考えられるように、コードが何をやっているのかちゃんと理解しておいた方がいいです。

```
dumpとは、要するにバックアップのことです。
データベースは様々なデータを保管しておく場所です。
そのデータは一度消してしまうと二度と元に戻せないような重要なものかもしれません。
トラブルが起こったときに与える影響の範囲が非常に大きく、深刻なものになりかねないので、データベースのdumpは重要なのです。

データベースに含まれているテーブルなどの情報を SQL 文の形で出力することをダンプと呼びます。
ダンプを行うとテーブルの構造やテーブルに格納されている 1 つ 1 つのデータについて SQL 文の形で出力されます。
どんな時に使うか？
・マスタデータ（都道府県、市区町村など）
・初期データ（ユーザアカウントなど）
などのデータを利用する時に使います。
```
　コマンドは以下の通りです。
```bin/rake db:seed:dump MODELS=モデル名 FILE=db/seeds/ファイル名（~.rb）```
　これはあるファイルのデータをseedsファイルに反映させる時のコマンドです。
　全てのレコードを空にしたい場合は```rake db:reset```を行います。
　これは全てのテーブルを dropし、"db/schema.rb"を元にテーブルの再作成を行います。

もう一つseedsファイルからDBに反映する方法は以下の通りです。
```bundle exec rails r db/seeds/ファイル名(~.rb)```

良かったら参考にしてみてください。
ブラウザが認識出来る言語は限られてるって知ってますか？


##前置き
学習した時に単縦にすごいと思ったので、アウトプットします。
書学者向けです。


##ブラウザって認識できる言語が限られている
プログラミング言語は沢山ありますが、ブラウザが認識できる言語は4つほどしかないそうです。
ブラウザは、HTML, CSS, JavaScript, WebAssemblyという言語を認識して、画面にページを表示している。

#####じゃ、Rubyとかはどうしているの？ってなりますよね。


そこで、登場するのが

###コンパイル。

認識出来ない言語を翻訳してくれるのが、コンパイル！



ちなみに、人が理解しやすい言語が高級言語。その逆が、低級言語。



でも、コンパイルにも翻訳出来ない言語がある。
そんな時に、登場するのがプリコンパイル！


メインとなる処理に対して必要な前処理のことを

###プリコンパイルと言うそうです。


テキストエディタに書いたらいいと思っていたので、面白い発見でした。
1次元のメディアンフィルター（中央値フィルター）

画像処理ではよく使われるメディアンフィルター。
OpenCVを使えば画像の２次元配列に対して
median = cv2.medianBlur(img,5)
とするだけで処理できる。

時系列データなどの１次元データにおいても外れ値がある場合，
メディアンフィルターで取り除くことができる。
１次元用のメディアンフィルターというのはnumpyにもopencvにも関数が見当たらず，
すこし工夫したのでメモ。
インデックスで各点ごとに中央値を選ぶ領域を抽出して２次元配列にしてから，
np.medianを行方向に適用している。



```python:median.py
import numpy as np
import matplotlib.pyplot as plt

# 1次元配列に対するメディアンフィルター
# kはフィルターの大きさで奇数
def median1d(arr, k):
    w = len(arr)
    idx = np.fromfunction(lambda i, j: i + j, (k, w), dtype=np.int) - k // 2
    idx[idx < 0] = 0
    idx[idx > w - 1] = w - 1
    return np.median(arr[idx], axis=0)

# 外れ値を含む正弦波
x = np.sin(np.arange(1000) / 50)
x[np.random.randint(0, len(x), 20)] += np.random.randn(20) * 3

# フィルタリング
y = median1d(x, 5)

plt.figure(1)
plt.clf()
plt.subplot(2, 1, 1)
plt.plot(x)
plt.ylim([-3, 3])
plt.subplot(2, 1, 2)
plt.plot(y)
plt.ylim([-3, 3])
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201397/fb4f189e-f534-12a4-2e3d-f90a002a042a.png)
deviseの導入

#Railsでdeviseの導入流れ
###1. Gemをインストールしてサーバーを再起動
###2. コマンドを利用してdeviseの設定ファイルを作成
###3. コマンドを利用してUserモデルを作成
###4. 未ログイン時とログイン時でボタンの表示を変える実装
###5. コントローラーにリダイレクトを設定
#deviseのgemインストール
```java:Gemfile
# 中略
gem 'devise'
```
```java:ターミナル
# サーバーを起動
% rails s
```
#コマンドを実行して設定ファイルを作成
```java:ターミナル
# deviseの設定ファイルを作成
% rails g devise:install
```
#コマンドを実行してUserモデルを作成
```java:ターミナル
# deviseコマンドでUserモデルを作成
% rails g devise user
```
#マイグレーションを実行
```java:ターミナル
# マイグレーションを実行
% rails db:migrate
```
#ローカルサーバーを再起動
```java:ターミナル
# 「ctrl + C」でローカルサーバーを終了

# 再度、ローカルサーバーを起動
% rails s
```
#リダイレクト処理を用意
```java:app/controllers/tweets_controller.rb
class TweetsController < ApplicationController
  before_action :set_tweet, only: [:edit, :show]
  before_action :move_to_index, except: [:index, :show]

  def index
    @tweets = Tweet.all
  end

  def new
    @tweet = Tweet.new
  end

  def create
    Tweet.create(tweet_params)
  end

  def destroy
    tweet = Tweet.find(params[:id])
    tweet.destroy
  end

  def edit
  end

  def update
    tweet = Tweet.find(params[:id])
    tweet.update(tweet_params)
  end

  def show
  end

  private
  def tweet_params
    params.require(:tweet).permit(:name, :image, :text)
  end

  def set_tweet
    @tweet = Tweet.find(params[:id])
  end

  def move_to_index
    unless user_signed_in?
      redirect_to action: :index
    end
  end
end
```
#コマンドを実行してdevise用のビューを作成
```java:ターミナル
rails g devise:views
```
#usersテーブルにnicknameカラムをstring型で追加
```java:ターミナル
# ディレクトリがpictweetであることを確認
% pwd

# usersテーブルにnicknameカラムをstring型で追加するマイグレーションファイルを作成
% rails g migration AddNicknameToUsers nickname:string

# 作成したマイグレーションを実行
% rails db:migrate
```
```java:ターミナル
# 「ctrl + C」でローカルサーバーを終了

# 再度、ローカルサーバーを起動
% rails s
```
#application_controller.rbを編集
```java:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  private
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname])
  end
end
```
#以上です！
##deviseには元々デフォルトでemailとpasswordは内部で動いてくれているのでカラムを追加しない場合はパラメーターに記述不要です！
export PATH=""... が読めなくなっていてショックだったので記事にしてみた

# 背景
本日、珍しく新しいアプリを作ろうと思い、`rails new`をしたら、[こんなエラー](https://tomoprog.hatenablog.com/entry/2017/02/03/015936)に当りまして...。
解決策として示されていた、すごい基本的なこのコマンドが読めなくなっていてショックだったので、記事にして忘れないようにし、供養ようと思います...。

```
$ export PATH="$HOME/.rbenv/shims:$PATH"
```
最近、LINUXコマンド全然触っていなかったもんなー。。。。とほほ。

## export
前から行きます。まず **`export` とは、指定した変数を環境変数にするコマンド**です。環境変数とは、OS共通で使える変数です。（[環境変数についてはこちらの説明](https://wa3.i-3-i.info/word11027.html)が分かりやすかったです。)

例えば、こんなふうに使えます。

```
$ export VAR          # VAR を環境変数にする
$ export VAR="MacOS"  # 環境変数VARに値「MacOS」を設定する
```
なお、環境変数は慣習的に大文字で書くようなのですが、小文字でも登録できます。

## PATH, $PATH, $HOME など
現在の環境に設定されている環境変数は`printenv`コマンドでわかります。

```
$ printenv
... # 略
LANG=ja_JP.UTF-8
... 
PATH=/Users/username/.rbenv/shims:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
...
PWD=/Users/username
```

今回のコマンドで設定しようとした`PATH`もありました！よく使う、`PWD`もここで設定されていたのね＾＾
登録時には`PATH`のように`$`のいらない書き方で登録できますが、参照時には`$PATH`のように`$`マークが必要です。

```
$ PATH
zsh: command not found: PATH
$ $PATH
/Users/usernsme/.rbenv/shims:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
```

## そして”パスを通す（セミコロンが出てくる部分）”
最後に、下記のセミコロンでつないでいる部分ですが、

```
$ export PATH="$HOME/.rbenv/shims:$PATH"
```
これがいわゆる「パスを通す」部分で、**セミコロンの前の部分に、セミコロンのあとの部分を設定するコマンド**になります。つまり

```
$ export PATH="$この変数が指し示す値に:この値を代入"
```
なので、今回は`HOME/.rbenv/shims`で指し示す値に、`$PATH`の中身を追加するコマンドとなります。

ここまで調べたところで、以前こんな親切記事をブックマークしていたことを思い出しました。
[Linux入門 ~「パスを通す」とは~](https://qiita.com/Naggi-Goishi/items/2c49ea50602ea80bf015)

今改めて読み直してみると、ここまで書いた内容とほぼ同じ内容でした:sweat_smile:しかも、上記の記事の方がしっかり説明してくれています。

### その他
ところで、ここまでコマンドを読み解いて、私の課題の解決に `$ export PATH="$HOME/.rbenv/shims:$PATH"`が役立つか不安になってきました...。拙速に設定しなくてよかったです:sweat_smile:明日また調べて頑張ろうと思います:v:
地味に大切だった命名規則。もう二度と間違えない！

#はじめに
　本日の学習で出会ったエラーが、今まででいちばん意外なところでのエラーだったので、忘れないために記録しておく。

##命名規則

　<font color=red>クラス名はアッパーキャメルケース</font>で記述する。

アッパーキャメルケース：先頭の単語と、単語の区切りの頭の文字を大文字にする。
キャメルケース：先頭は小文字で、単語の区切りの頭の文字は大文字にする。
スネークケース：単語と単語の区切りをアンダースコア（＿）で繋げる。

クラス名→アッパーキャメルケース
変数名・メソッド名→スネークケース

##最後に
　本日の学習では、処理の記述を何度見返しても、違いが見つからず、単語を繋げたクラス名をスネークケースで記述してしまい、クラスを読み取らないというエラーが出てしまった。
　ちまみに、キャメルはラクダ。大文字のところが、コブってこと。アンダースコアは蛇に見えるか？
【Unity】Randomまとめ

#はじめに
ゲーム製作においてRandomを使用する場面は多いと思います。
備忘録としてRandomクラスをまとめてみました。
なお、本記事では```UnityEngine.Random```について記載しています(```System.Random```ではない)。

#Static Properties

###insideUnitCircle
**半径1の円の内部の点をランダムに返す。**
円形上にランダムに敵を出現させたい場合などに使用。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694219/9fd91aa9-0891-f4dc-bf01-92e4be566e88.png)

###insideUnitSphere
**半径1の球体の内部の点をランダムに返す。**
球体内部全てなので、浮いてるオブジェクトなどにも使用可能。
![スクリーンショット 2020-10-19 22.12.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694219/26192c0e-dd97-4c16-66d8-5b7ddf831e94.png)

###onUnitSphere
**半径1の球体の表面上の点をランダムで返す。**
![スクリーンショット 2020-10-19 22.14.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694219/cbf09018-a2ab-8393-dafe-909903f575a4.png)

###rotation
**ランダムな```Quaternion```を返す。**
![スクリーンショット 2020-10-19 22.16.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694219/6837c171-48e8-e4da-6dec-7beae47f9a52.png)

###rotationUniform
**一様な分布でランダムに```Quaternion```を返す。**
```Random.rotation```では完全なランダムではないみたいです。ただ計算コストはこちらの方が高い。

###state
**乱数生成器の内部状態のすべてを取得、または、設定する。**
適当なタイミングでアプリを落としても、再度起動したときに続きからできるようにするために乱数を保存する。

###value
**0.0と 1.0の範囲のランダムな数を返す。**
0.0と1.0も含むことに注意。汎用性が高く、Randomクラスのプロパティで基本的に使うのはこれ。

#Static Methods

###ColorHSV
**HSVでアルファ値(透明度)をもつランダムな```Color```を返す。**
パラメータで色相(hueMin,hueMax)、彩度(saturationMin,saturationMax)、明度(valueMin,valueMax)、アルファ値(透明度:alphaMin,alphaMax)を設定可能。
![スクリーンショット 2020-10-19 22.51.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694219/ac62381a-4c84-2c43-4ea8-3e6378e80244.png)

###InitState
**シード値を指定し、ランダム数生成器の状態を初期化する。**
システム時刻等で決定されるシード値を指定することで、同じ乱数の値を生成することができる。
シード値による擬似乱数については、以下の記事がわかりやすいです。
[コンピューターの「ランダム」は本当にランダムなのか？](https://www.zenken.co.jp/blog/engineer/30255)

###Range
**範囲を指定できる、```Random.value```。**
intで設定するか、floatで設定するかによって、**戻り値の範囲に差がある点に注意。**

#####int設定
```math 
\text{min}\leqq \text{return} < max
``` 
#####float設定
```math 
\text{min}\leqq \text{return} \leqq max
``` 

#まとめ
* Randomクラスは様々な乱数を生成するクラス。
* ```Random.value```と```Random.Range```の使用頻度が圧倒的に高い。
* ```Random.rotation```と```Random.rotationUniform```の違いは後日検証したい...
【python】enumerateの動作

enumerateの動作が面白かったので記載する。
#動作
enumerateは辞書をfor文に入れる時に非常に役に立つ。

```python:
d = {5:1, 6:2, 7:3}
```

上のような辞書をfor文に入れる。

```python:
for i, x in enumerate(d):
     print(i,x)
#0 5
1 6
2 7
```

上記からenumerateを実行すると
iには数列の番号が
xにはキーが
入る。
GORMでマイグレーションする際の覚書

# はじめに
`struct`でモデル定義、`AutoMigrate`でマイグレーションを実行、といった辺りで少し調べた部分をメモしておきます。

## IDにUUIDを使用するには
UUIDの自動生成をライブラリに任せつつ、テストやシードデータの投入時には固定のUUIDも指定できるようにしたかったため、以下のように対応しました。

まずはstructでのモデルの定義

```golang
package model

import (
	"github.com/go-playground/validator/v10"
	"github.com/google/uuid"
)

type User struct {
  ID string `validate:"is_valid_uuid" gorm:"primaryKey;size:255;default:uuid_generate_v4()" json:"id"`
  ...
}

// IDが渡ってこなければバリデーションをかけず、渡ってきたらUUIDかを確認
validate := validator.New()
validate.RegisterValidation("is_valid_uuid", isValidUUID)

func isValidUUID(fl v.FieldLevel) bool {
	id := fl.Field().String()
	if len(id) == 0 {
		return true
	}
	_, err := uuid.Parse(id)
	return err == nil
}
```

上記`uuid_generate_v4()`を利用するために、`AutoMigrate(&User{})` する前にpostgresに拡張機能 `uuid-ossp` をインストール

```go
db, err = gorm.Open("postgres", fmt.Sprintf(
  "host=%s port=%s user=%s password=%s dbname=%s", host, port, user, password, dbname,
))

if err != nil {
  panic(err)
}

db.Exec(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp";`)

result := db.AutoMigrate(&model.User{})
...
```

## Postgresのenum型を使用するには

structのタグで型を指定

```golang
type User struct {
  Role string `validate:"is_valid_role" gorm:"type:role_enum;default:'user'" json:"role"`
  ...
}
```

`AutoMigrate`する前にpostgresに型の定義を追加

```golang
db.Exec(`
DO
$$
BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'role_enum') THEN
    create type role_enum AS ENUM ('admin', 'editor', 'user');
  END IF;
END
$$;
`)

result := db.AutoMigrate(&model.User{})
...
```

## まとめ
GORMのマイグレーションまわりに関してのメモでした。また他にあれば追記していきます。
【Ruby】Your Ruby version is 2.6.3, but your Gemfile specified 2.5.8

## はじめに

Rubyを触っていたときにタイトルのエラーが出たので記事にしました。

## エラーとの遭遇

作成途中だったアプリを触っていたときに、`bundle install` でエラーに遭遇。

```
$ bundle install
-> Ruby version is 2.6.3, but your Gemfile specified 2.5.8
```

エラー文から、RubyのバージョンとGemfileが指定してるバージョンが違うんだろうなーと検討がつく。

## 対応したこと

まず、Rubyのバージョンを確認してみる。

```
$ ruby -v
-> ruby 2.5.8p224 (2020-03-31 revision 67882) [x86_64-darwin19]
```
rbenvを使用しているので、そちらでも確認

```
$ rbenv versions
  system
  2.1.5
  2.5.1
* 2.5.8
  2.6.3
  2.7.1
```


見た感じは合ってるっぽい。

今使っているRubyのパスを参照したりできる`gem environment`で確認してみよう。

```
$ gem environment
-> RubyGems Environment:
  - RUBYGEMS VERSION: 2.7.6.2
  - RUBY VERSION: 2.5.8 (2020-03-31 patchlevel 224) [x86_64-darwin19]
  - INSTALLATION DIRECTORY: /Users/username/.rbenv/gems/2.5.0
  - USER INSTALLATION DIRECTORY: /Users/username/.gem/ruby/2.5.0
  - RUBY EXECUTABLE: /Users/username/.rbenv/versions/2.5.8/bin/ruby
  - EXECUTABLE DIRECTORY: /Users/username/.rbenv/gems/2.5.0/bin
  - SPEC CACHE DIRECTORY: /Users/username/.gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: /Users/username/.rbenv/versions/2.5.8/etc
  - RUBYGEMS PLATFORMS:
    - ruby
    - x86_64-darwin-19
  - GEM PATHS:
     - /Users/username/.rbenv/gems/2.5.0
  - GEM CONFIGURATION:
  ...(続く)
```

うーん、間違ってなさそう...

## 解決した方法

bundle の配置場所を確認してみる

```
$ which bundle
-> /usr/local/bin/bundle
```

中身を見てみる

```
-> % cat /usr/local/bin/bundle 

#!/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
#
# This file was generated by RubyGems.
#
# The application 'bundler' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0.a"

str = ARGV.first
if str
  str = str.b[/\A_(.*)_\z/, 1]
  if str and Gem::Version.correct?(str)
    version = str
    ARGV.shift
  end
end

...(続く)
``` 

あ、`/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby`を参照しているぞ...

```
$ which ruby
/Users/username/.rbenv/shims/ruby 
```
参照先を`/Users/username/.rbenv/shims/ruby`に変更。

無事`bundle install`が通りました！ 


### 参考記事

https://qiita.com/h5y1m141@github/items/74029cab9706971c8dbe
pluckメソッドとは

今回、pluckメソッドについて学習したため、アウトプットいたします。

pluckメソッドとは？
その使い方とは？

について記述いたします。

#pluckメソッドとは？
pluckメソッドとはこう書かれています。
「引数に指定したカラムの値を配列で返すメソッド。」

同様の効果のあるメソッドとしてmapメソッドが上げられますが、返り値を配列として取得する場合は、pluckメソッドを使った方がシンプルで楽です。

では実際に使ってみましょう。

#使い方

usersテーブルのnameカラムに"田中", "吉田", "鈴木", "高橋"の４人が入っていたとする。
そこで、userテーブルのnameカラムだけ取得したい場合、pluckメソッドは力を発揮する

```csharp
User.pluck(:name)
#すると以下のような処理がされる
SELECT `users`.`name` FROM `users`
=> ["田中", "吉田", "鈴木", "高橋"] # 返り値
```

このようにテーブルやデータベースに登録された情報を配列としてまとめて取得したい場合にとても便利です。
peco を使ってブランチのチェックアウトを行う (リモートブランチ と ローカルブランチ) 改良版

# peco を使ってブランチのチェックアウトを行う (リモートブランチ と ローカルブランチ) 改良版


https://qiita.com/m-tmatma/items/8285a6cace98cfdb5db9 の改良版です。

### 改善版1

```
git checkout $(git branch -a | grep -v "/HEAD" | peco | sed -r "s#^\\s+remotes/origin/##")
```

### 改善ポイント

https://qiita.com/tommy_aka_jps/items/6ce68f564cb3802ca9b0 の記事で以下で `proj/exampleWorks` のリモートブランチをチェックアウトできるとあったのでそれを反映して簡略化しました。

```
git checkout proj/exampleWorks
```

* `git branch -a` でリモートブランチとリモートブランチを両方列挙します。
* sed で `git branch -a` を使ったときにリモート名のところを削除します。
* `git checkout proj/exampleWorks` でリモートブランチをチェックアウトできることを利用します。

## 改善版2 (git リポジトリの外で実行した場合に git checkout を実行しない版)

```
alias co='git rev-parse --is-inside-git-dir > /dev/null 2>&1 \
  && git checkout $(git branch -a | grep -v "/HEAD" | peco | sed -r "s#^\\s+remotes/origin/##" | sed -r "s#^\*\s+##")'
```

### 改善ポイント

* git リポジトリの外で実行した場合に git checkout を実行しない
* 現在いるブランチを選択してもエラーにならないようにする。
Tkinterでコンボボックスの値を変更する

ソースコードは以下になります。

```python 
import tkinter
from tkinter import ttk

colors = ['Red', 'Green', 'Blue']


def btn_click():
    cb_colors.current(2)
    # cb_colors.set("Green")

    # print(cb_colors.get(), cb_colors.current())


root = tkinter.Tk()
root.geometry("200x200")
root.title("Color Picker")

cb_colors = ttk.Combobox(root, values=colors, width=10, state='readonly')
cb_colors.current(0)
cb_colors.place(x=50, y=50)

btn = tkinter.Button(root, text='ボタン', command=btn_click)
btn.place(x=50, y=100)

root.mainloop()
```

`cb_colors.current(2)`のようにインデックスを指定して値を設定してもよいし、`cb_colors.set("Green")`のように最初から値を指定してもOKです。
どちらの方法でも`.get()`で取得できる値と`.current()`で取得できるインデックスの値が変更されます。

最後まで読んでいただきありがとうございました。
またお会いしましょう。
【 情報圧縮ノート003 】ダルかった大学の電磁気学の教授の講談と板書をJpeg１枚に圧縮してまえ計画。

情報圧縮ノート計画というものをはじめました。
あの、かったるかった大学の先生の板書。
チンタラしているのに早口でまくし立てるからついていけない。
しかもその90分授業が年に30講近くある。
だいたい最初に全体像を教えてくれと思うのに勿体ぶる。
木を見せて森を最後に見せる。
定食の一番好きなオカズは最後にとるタイプの教授ばっかり。
そこで、そんな教授たちの性癖の裏をかいて全体像を一気に把握したい。
そういう企みのもとで情報を一気に圧縮していきます。
電磁気学全体をビル・建築物にみたて、
1)前提・仮定を基礎工事
2)結論を最上階とか屋上
にして全体を見通します。
![IMG_BD4821E2C2CC-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/792464/87f58aac-ba5d-562d-8219-ac61f280f48a.jpeg)
これはまだ下書き、というか大学のときのノートですが、
AdobeIllustratorとかで清書します。

https://www.instagram.com/1jpeg1knowledge/
【React②】JSX


#JSXとは
XMLのようなタグを記述できるJavaScriptの拡張言語。これを使えば、短く直感的にわかりやすい記述ができる。
JSXはBabelによって暗黙的にJavaScriptに変換される。
以下のページの左側にXMLを入力すると、右側にリアルタイムでJavaScriptが表示されることが確認できる。
https://babeljs.io/

#使い方
```React
import React, { Component } from 'react';
```

するだけ。他には

* 変数キャメルケースで書く
* コンポネントには閉じタグ`/>`が必要

例えば、https://babeljs.io/ に以下のコードをかくと、

```React
class App extends Component{
  render(){
    return <div>Foo</div>;
  }
}
```

暗黙的にBabbleが以下のようにReact.createElement()に変換してくれるのです。
HTMLのように、最終形に近い形で記述できることになります👏

```React
function render() {
  return React.createElement('div', null, 'Foo');
}
```
###式をうめこむ
JSXを使えば、JavaScriptの式をJSX内で**中括弧**に囲んで使用できます。

```React
const name = 'Tom';
const element = <h1>Hello, {name}</h1>;

ReactDOM.render(
  element,
  document.getElementById('root')
);
```

###属性を指定
JSXではclass属性の指定は`class`ではなく`className`で指定する。
例えば下の例だと、h1タグがトランスパイルされてdomという変数に代入されている。

```React
class App extends Component{
  render(){ 
    const greeting = "Hi, Tom!";
    const dom = <h1 className="foo"> {greeting}</h1>;  
    return dom;
  }
}
```

###タグの属性
HTMLタグの属性`for`はReactでは`htmlFor`で指定できる。labelに付与することで、同じ内容のid属性を持つ要素と関連付ける。
下の例では`onChange`ベントハンドラによりformへの入力が変化するとI am clickedが表示される。

```React
class App extends Component{
  render(){ 
    return(
      <div>
         <label htmlFor="bar">bar</label>
         <input type="text" onChange={() => {console.log("I am clicked.")}}/>
          //条件がクリックの場合はonClick
      </div>
    )
  }
}
```

また、Reactのreturn内で返すタグは1個でないといけない。


```React
//エラー文
index.js: Adjacent JSX elements must be wrapped in an enclosing tag
```

そこでreturn内を`<div>`で囲って対応、、、
するとReactのための意図せぬタグが増えてしまうので、`<React.Fragment>`が用意されている。 
`<div>`ではなく、`<React.Fragment>`で囲うことで、最終的に画面に表示されるHTMLに余計なタグが出力されない。
`<React.Fragment>` では`key={item.id}`も指定可能。

```React
class Columns extends React.Component {
  render() {
    return (
      <React.Fragment>
        <td>Hello</td>
        <td>World</td>
      </React.Fragment>
    );
  }
}
```

以下のように`<></>`を使って単略化して書くこともできるが、key属性は指定できない。

```React
class Columns extends React.Component {
  render() {
    return (
      <>
        <td>Hello</td>
        <td>World</td>
      </>
    );
  }
}
```


### 比較

JSXを使わずReactを使ってDOMを描画すると、こんな感じに長くなる。

```React
 class App extends Component {
   render() {
     return React.createElement(
       "div",
        null,
       "Hello, world!!"
     );
   }
 }
export default App;
```