OmniAICreator/Qiita-1.07M huggingface dataset:
human_attribute_name(:カラム名)を使う　Rails

##初めに
railsのviewで度々見かけるが見かける度に毎回調べていたので、メモがわり。

##概要

```slim:html.slim
Task.human_attribute_name(:name)
/#=> 名称
```

上記の形で参考書で使われていた。


##前提

```yml:ja.yml
    models:
      task: タスク
    attributes:
      task:
        name: 名称
```
config/locales/ja.ymlにおいて、このように記述がされている。

##解説
```slim:html.slim
Task.human_attribute_name(:カラム名)
```
ja.ymlファイルの中でカラム名に対応する文字列が引っ張り出される。
ここでは'名称'がブラウザで表示されることになる。
Amazon CloudFront 基礎

#CloudFront特徴
・高性能な分散配信
・高いパフォーマンス
・予測不可能なスパイクアクセスへの対応
・セキュリティ機能
・設定容易で即時利用可能
・充実したレポーティング
・完全従量課金

#CloudFrontによるCON(Contents Delivery Network)
・大容量のキャパシティを持つ地理的に分散したサーバ群からコンテンツをキャッシュしたり、配信するサービス。
**利点**
・ユーザを一番近いエッジローケーションに誘導することで配信を高速化
・コンテンツをキャッシングを行い、オリジンの負荷をオフロード
・DNSを応用した仕組みで最適なエッジロケーションを割り当て
・CloudFront導入はバックエンドはそのままで可能

#コンテンツ配信の流れ
①Amazon S3 バケット、ALB、EC2、オンプレミスにある独自のHTTPサーバなどのオリジンサーバ設定。
②ファイルをオリジンサーバにアップロード
③CloudFrontディストリビュージョン作成
④CloudFrontがドメイン名を割り当て
⑤ディストリビュージョンの構成を全てのエッジロケーションに送信

#ディストリビュージョン
・ドメイン毎に割り当てられるCloudFrontの設定
・マネージメントコンソールもしくはAPIで即時作成可能
・HTTP/1.0、HTTP/1.1、HTTP/2、WebSocket対応
・IPv6対応
・デフォルトでは「xxxx.cloudfront.net」がディストリビュージョンのドメイン名として割り当てられる
・CNAMEエリアスを利用して代替えドメイン名の指定可能
・Route53と組み合わせたZone Apexが利用可能

#ウェブディストリビュージョン
**サポートプロトコル/HTTPメソッド**
(1)HTTP/HTTPS対応
　・GET,HEAD,OPTION(Cacheモード)
　・PUT,POST,DELETE,OPTION,PATCH(Proxyモード)

(2)オリジンへのアクセス
　・Internet経由でアクセスできることが必要
　・Range GET対応

**エッジでのgzip圧縮機能**
CloudFrontエッジでコンテンツをgzip圧縮することでより高速にコンテンツを配信

#キャッシュ動作：キャッシュコントロール機能
**キャッシュコントロール**
キャッシュヒット率を向上させることがCDN導入のポイント
・GET/HEAD/OPTIONのリクエストが対象
・単一のファイルサイズのキャッシングは最大20GBまで
・URL毎にキャッシュ期間指定が可能

**キャッシュコントロールヘッダーの挙動**
・キャッシュ時間のコントロールが可能
・キャッシュマイにキャッシュ設定を行うことで、URLパス毎にキャッシュ期間を変えることが可能
　(1)デフォルトTTL：オリジンがキャッシュコントロールヘッダーを指定しない場合に利用(デフォルト24時間)
　(2)最小TTL：キャッシュすべき最小時間
　(3)最大TTL：キャッシュすべき最大時間

**キャッシュファイルの無効化**
・コンテンツ毎の無効化パス指定
・同時に最大3000個までのパス指定が可能

**キャッシュ動作：動的コンテンツ機能**
オリジンサーバに対してHeader,Cookie,Query,Strings情報をフォワードすることで、動的なページの配信にも対応
・オリジンに任意のヘッダー情報をて転送することで動的なページ生成にも対応
・必要最低限のヘッダーを指定することを推奨
・CloudFront独自ヘッダーがある

**Cookieオリジンへ転送**
・オリジンに任意のCookie情報を転送することで動的なページ生成にも対応
・CloudFrontは指定されたCookie名と値をセットでキャッシュ
・必要最低限のCookieを指定することを推奨

**クエリ文字列パラメータ値をオリジンへ転送**
・オリジンに任意のクエリ文字列を転送することで動的なページ生成にも対応
・CloudFrontは指定されたクエリ文字列パラメータと値をセットでキャッシュ

**カスタムオリジンのタイムアウト**
・CloudFrontがカスタムオリジンからの応答を待つ時間を指定
・デフォルトのタイムアウトは30秒、4~60秒の範囲で設定可能

**オリジンフェイルオーバー**
CloudFrontオリジンフェイルオーバーによる高可用性
・オリジングループを作成し、プライマリオリジン・セカンダリオリジンを指定
・エラーHHTPステータス500等フェイルオーバー用に設定したHTTPステータスコードを返した場合や接続タイムアウトした場合にバックアップオリジンにルーティング


#データ保護機能
**サポートするSSL証明書**
(1)デフォルト証明書
・cloudfront.netドメインのSSL証明書は標準で利用可能
(2)独自SSL証明書
・ACM(AWS Certification Manager)で発行された証明書

**オリジン暗号化通信**
CloudFrontエッジとオリジン間の通信方式を制御
・SSlプロトコル方式
・オリジンと通信プロトコル
・HTTPのみ,HTTPSのみ,クライアントからの通信プロトコルに合わせる
・カスタムオリジンの場合のみ指定可能

**地域制限(Whitelist/Blacklist)**
地域制限によるアクセス制御
・接続されるクライアントの地域情報をもとに、エッジでアクセス判定
・ディストリビュージョン全体に対して適応
・制限されたアクセスには403を返す

**署名付き URL/Cookie**
・署名付き URL/Cookieを利用したプライベートコンテンツ配信
・Restricted Viewer Accessを有効にするだけで、署名のないアクセスを全てブロック
・標準
　①有効期間
　②有効コンテンツパス
・オプション
　①アクセス元IPアドレス制限
　②有効開始時刻指定
　③許可コンテンツのワイルドカード指定

**署名付き URL**
・有効期間を最初にするkポトを推奨
・権限のないアクセスには403を応答
・URLの生成
・決められたフォーマットでQuery Stringsにパラメータ値を設定
・CloudFrontの秘密鍵を利用してSignatureのパラメータ文字列を署名
・アクセス毎に必ず署名が必要

**フェールドレベル暗号化を使用した機密データの保護**
・POSTリクエストの特定のデータフィールドを特定のアプリケーションのみアクセスできるように保護
・公開鍵暗号化方式

**オリジンサーバの保護**
(1)オリジンがS3の場合
・Origin Access Identity(OAI)使用
・S3バケットのへのアクセスをCloudFrontのみに制限
(2)カスタムオリジンの場合
・オリジンカスタムヘッダーを利用し、CloudFrontで指定された任意のヘッダーをオリジン側でチェック
・オリジン側のアドレスを公開しないとともに、CloudFrontが利用するIPアドレスの許可をさせる。
iCloudにログインしているユーザーのユーザーIDを取得する

CloudKitを利用すると、iCloudでログインしているユーザーのIDを取得することができます。

以下のように、`CKContainer`に対して`fetchUserRecordID`を実行すると、ユーザーIDがコールバックで取得できます。

```swift
let container = CKContainer(identifier: "iCloud.xxx.xxx.xxx") // 作成したコンテナのID
container.fetchUserRecordID { [weak self] (id, error) in
    DispatchQueue.main.async {
        if let error = error as? CKError {
            switch error.errorCode {
            case CKError.notAuthenticated.rawValue:
               // 認証していない場合の処理
            case CKError.managedAccountRestricted.rawValue:
               // 利用制限をかけている場合の処理
            default:
               // その他のエラー処理
            }
        } else {
            // IDが取得できた時の処理
        }
    }
}

```
golangからDockerを操作する


## 参考
https://pkg.go.dev/github.com/ph/moby/client

## 内容
- `docker ps`する

```golang
package main

import (
        "context"
        "fmt"

        "github.com/docker/docker/api/types"
        "github.com/docker/docker/client"
)

func main() {
        cli, err := client.NewEnvClient()
        if err != nil {
                panic(err)
        }

        containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
        if err != nil {
                panic(err)
        }

        for _, container := range containers {
                fmt.Printf("%s %s\n", container.ID[:10], container.Image)
        }
}
```

## 動作確認
```
docker run -d nginx:latest
yuta@DESKTOP-T85N4KS /t/go-docker> docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS     NAMES
dd9f82fa644e   nginx:latest   "/docker-entrypoint.…"   26 seconds ago   Up 26 seconds   80/tcp   compassionate_roentgen
```


```
yuta@DESKTOP-T85N4KS /t/go-docker> go run main.go
dd9f82fa64 nginx:latest
```
【Swift】RxSwift勉強してみたPart3

#はじめに
[前回](https://qiita.com/REON/items/11694c756e51bbbb801b)に引き続き、RxSwiftを勉強したので、その学習アウトプットです。
RxSwiftでHello World的なものを書いてみます。

#GitHub
以下のHelloRxSwiftフォルダに今回のプロジェクトはあります。

https://github.com/0429oonishi/RxSwifts


#実装
流れは以下の通りです。
1.`HelloWorldSubject`という`Subject`を定義
2.`Subject`を購読
3.値が流れてきたら`print`で値を出力されるように定義
4.定義したクラスが破棄されたら購読も自動的に破棄させる
5.N回イベントをながす
6.定義したクロージャがN回実行される

`viewDidLoad`でこのように書いてみます。

```swift
import UIKit
import RxSwift

class HelloRxViewController: UIViewController {
    
    private let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let helloWorldSubject = PublishSubject<String>()
        helloWorldSubject.subscribe(onNext: { message in
            print("onNext: \(message)")
        }, onCompleted: {
            print("onCompleted")
        }, onDisposed: {
            print("onDisposed")
        })
        .disposed(by: disposeBag)
        
        helloWorldSubject.onNext("HelloWorld!")
        helloWorldSubject.onCompleted()

    }
}
```

```swift:出力結果
//onNext: HelloWorld!
//onCompleted
//onDisposed
```

このような書き方は`ViewController`と`ViewModel`や遷移元と遷移先の`ViewController`のデータの受け渡しで使われます。
次は`ViewController`と`ViewModel`に分けて書いてみます。

```swift:HelloRxViewController
import UIKit
import RxSwift

class HelloRxViewController: UIViewController {
    
    private let disposeBag = DisposeBag()
    private let viewModel = HelloRxViewModel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        viewModel.helloWorldObservable
            .subscribe(onNext: { message in
                print("onNext: \(message)")
            }, onCompleted: {
                print("onCompleted")
            }, onDisposed: {
                print("onDisposed")
            })
            .disposed(by: disposeBag)
        
        viewModel.updateItem()
        
    }

}
```

```swift:HelloRxViewModel
class HelloRxViewModel {
    
    var helloWorldObservable: Observable<String> {
        return helloWorldSubject.asObservable()
    }
    private let helloWorldSubject = PublishSubject<String>()
    
    func updateItem() {
        helloWorldSubject.onNext("Hello World!")
        helloWorldSubject.onCompleted()
    }
    
}
```

```swift:出力結果
//onNext: HelloWorld!
//onCompleted
//onDisposed
```

#おわりに
RxSwiftまだまだわからないことだらけ、、、
[次回](https://qiita.com/REON/items/c986ff93e67e3693324c)
【At Corder】【初心者】ABC081B - Shift only をRuby で解いてみた



#はじめに
[AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～ - Qiita](https://qiita.com/drken/items/fd4e5e3630d0f5859067)

こちらの記事を参考に初心者がAt corderに挑戦します。
目的としては、就職活動でのコーディングテスト対策です。
毎日１問を目標としてコツコツやってきます:thinking:

わからないことは調べる精神です。ちょっとでもわからないなぁ、と思ったことは調べて解説と参考文献を載せますので、同じ内容でわからない人がいれば参考にししてください:baby:


https://atcoder.jp/home

#問題 ABC081B - Shift only
N個の正の整数$A_1 ,...,A_N$がある。この整数が全て偶数のとき、すべての整数を2で割ったものに置き換える。最大で何回操作を行うことができるか求めよ


#入力　出力

###入力

```ruby
N
A1 A2 ... An
```

###出力
最大で何回操作を行うことができるか出力せよ

###入力例

```ruby
3
8 12 40
```

###出力例

```ruby
2
```

1回目[4,6,10]、２回目[2,3,5]となり奇数が現れるため、答えは2となる

#回答

```rb
N=gets.to_i
numbers=gets.chomp.split(" ").map(&:to_i)
min = 99

numbers.each do |sum|
  count = 0
  while sum % 2 == 0 do
    count = count + 1
		sum = sum/2
  end
	
	if (count < min ) then
		min = count:confused:
	end

end

puts min

```

#解説
Nは入力を受け付けたが、プログラムの中には活用しませんでした。

受けた数字をそれぞれ偶数か判断し、偶数ならばcountを+1して、対象の値を2でわる。countの数字が一番小さいものをminに保存し、それを出力する。


#感想
ここから難しくなってきました。問題文を読んだ段階では最小値を出力するという発想は出てきませんでした。プログラミングらしい！:confused:
最初sumをAとしていましたが、エラーが出てしまいました。どうしてダメだったんでしょうか。。わかる方がいらっしゃればご教示くださると嬉しいです:pray:
endの場所をputs ~の後ろにしていたせいで、出力がミスってました。気をつけよう！


<a id="#reference"></a>
# 参考文献
[Arrayクラス](https://www.javadrive.jp/ruby/array/index3.html)

[Array#each (Ruby 3.0.0 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/method/Array/i/each.html)

[Atcoder Beginners SelectionをRubyで解いてみた - Kasasagi's memorandum](http://yh9092.hatenablog.com/entry/2018/03/22/165608)

[[AtCoder]ABC081B - Shift only [Ruby]](https://cloraordinary.com/atcoderabc081b-shift-only-ruby)
Mysql2::Error: Table ' ~~~~~ ' already existsと表示され他時の対処法

・マイグレーションしようとしたときにこのようなエラーが出た。
　
-- create_table(:microposts)
rails aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Table 'microposts' already exists
~省略~
Caused by:
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'microposts' already exists
~省略~
Caused by:
Mysql2::Error: Table 'microposts' already exists
~省略~

-----------------------------------------------------------------------------------
・エラーの意味は「もうすでに同じテーブルがありますよ。」といった感じのエラー。
・この状況になったらテーブルを消すことで解決する。

手順
・rails dbでデータベースを開く。
・mysqlが開くので、SHOW TABLES;を打ち込む。
・上記の例のエラーに関するとmicropostsを消す事になるが、各々違うと思うので、臨機応変に対応。
 drop table 〜〜〜；で消す。
・削除ができたかどうかをSHOW TABLES;で確認。
・exitで抜ける。
・rails db:migrateを実行。

完
Base64を完璧に理解したい人以外、見ないでください。

# はじめに
タイトルはちょっとウケ狙いなので、許してください。。
業務中に、Base64でエンコードして、デコードして、といった指示があり、初めて聞いた単語に「？」が浮かんだ。
ここでは、自分が調べた情報を共有して、自分のような0からスタートする人の助けになる記事を書きたいと思って書きました。

# Base64とは
base64とは、64進数を意味する言葉です。
すべてのデータをアルファベット(a~z, A~z)と数字(0~9)、一部の記号(+,/)の64文字で表すエンコード方式のこと。
ただ、データ長を揃えるためにパディングとして末尾に記号の=を使用するので、厳密にはbase64は、65文字の英数字から表現されています。

## エンコードの流れ

1. 対象の文字列を 16 進数に変換する

2. 16 進数に変換した数字をそれぞれ 2 進数に変換する

3. 6 ビットごとに分割して、足りない部分は 0 で詰める

4. 変換表にしたがって各 6 ビットをエンコードしていく

5. 4文字ごとに分割して末尾が余る場合、"=" で詰める

6. 最後にすべての文字をつなげて完成

※デコードは逆の流れ

```ruby

ABCDEFG
↓
41 42 43 44 45 46 47
↓
0100 0001, 0100 0010, 0100 0011, 0100 0100, 0100 0101, 0100 0110, 0100 0111
↓
010000 010100 001001 000011 010001 000100 010101 000110 010001 11
↓
010000 010100 001001 000011 010001 000100 010101 000110 010001 110000
↓
QUJDREVGRw
↓
"QUJD", "REVG", "Rw"
↓
"QUJD", "REVG", "Rw=="
↓
QUJDREVGRw==
```

## モジュール関数

### decode64
与えられた文字列をBase64デコードしたデータで返します。

```ruby

require 'base64'

str = 'Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4gUnVieQ=='
puts Base64.decode64(str)
#=> "Now is the time for all good coders\nto learn Ruby"
```

### encode64
与えられた文字列をBase64エンコードしたデータで返します。

```ruby

require 'base64'

str = "Now is the time for all good coders\nto learn Ruby"
Base64.encode64(str)
#=> Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4gUnVieQ==
```

## おまけ
[こちら](https://tm-webtools.com/Tools/Base64Image)のツールを使えば自動でエンコードした文字列を出力してくれるので、エンコード文字列が欲しい場合はこちらを使うのが便利です。

# 終わりに
ここまでで、0からの知識の人でもある程度は掴めたのではないでしょうか？
頻繁ではないにしろ、必要な知識ではあると思うので、使えるレベルまで持っていって損は無いです！

# 参考
[Base64のしくみを理解するためにRubyで実装してみる]
(https://note.com/sunakujira/n/ncecc0ac62589)

[module Base64]
(https://docs.ruby-lang.org/ja/latest/class/Base64.html)

[base64でエンコードされた画像をActive Storageで保存する]
(https://qiita.com/ozin/items/5ec81a4b126b8ebf7a96)

[Rails(Ruby)でBase64化された画像を取り回すときのSnippet]
(https://qiita.com/maruware/items/407fc668f06e7784b198)

[singleton method Tempfile.new]
(https://docs.ruby-lang.org/ja/latest/method/Tempfile/s/new.html)
WebIOPiのインストール

#WebIOPi
[WebIOPi](http://webiopi.trouch.com)とは、Raspberry Piを使用して、簡単にIoTを作成できるライブラリです。
今回は、WebIOPiのインストールを行います。

#インストール


WebIOPiのインストールを行なっていきます。
`Raspberry Pi`を起動して、ターミナルで以下のコマンドを打っていきます。

`#`より後ろはコメントです。打つ必要はありません。

```bash
wget https://sourceforge.net/projects/webiopi/files/WebIOPi-0.7.1.tar.gz
tar xvzf WebIOPi-0.7.1.tar.gz     #ファイル解凍
cd WebIOPi-0.7.1                  #ディレクトリ移動
#修正プログラムダウンロード
wget https://raw.githubusercontent.com/doublebind/raspi/master/webiopi-pi2bplus.patch       
patch -p1 -i webiopi-pi2bplus.patch  #ダウンロードした修正プログラムの適用
sudo ./setup.sh                   #セットアップスクリプトの適用
```

`Do you want to accessWebIOPi over Internet? [y/n]`　で止まったら、`n`を入力し、エンターキーを押します。（`y`を入力し、エンターキーを押すと、`Weaved IoT Kit`がインストールされます）

WebIOPiをサービスとして開始するためのファイルをダウンロードします。

```bash
cd /etc/systemd/system/
sudo wget https://raw.githubusercontent.com/doublebind/raspi/master/webiopi.service
cd ~   #ホームディレクトリへの移動
```


# 動作確認
WebIOPiの動作確認を行います。WebIOPiでは、デフォルトでWebページが用意されており各ピンヘッダーの出力状況などが確認できます。

###サービスの起動
WebIOPiサービスを起動します。

```bash

sudo systemctl start webiopi
```

###アクセス
Raspberry PiのIPアドレスを調べて、デフォルトのWebページへアクセスします。

```bash

ifconfig
```

Wi-Fi通信の場合、`wlan0`のところに、IPアドレスが記述されています。
確認したのち、PCやタブレット、スマホなどのデバイスでWebブラウザを開きます。

ブラウザのURL入力欄に`RaspberryPiのIPアドレス:8000`を入力し、アクセスします。
Raspberry PiのIPアドレスが`192.168,11,2`の場合、`192.168.11.2:8000`と入力します。

**`Raspberry Piと同じルーターに接続されていることを確認してください。`**

###認証
アクセスすると、認証ダイアログが表示されるので、
`ユーザー名：webiopi`
`パスワード：raspberry`
を入力。

その後、下のような画面が表示されれば成功です！
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689410/e39cfa81-1870-77c9-35aa-8b3e77038de2.png">
[備忘録]pandas mode()で最頻値を抽出する

いつもforループを使って処理していて
処理に1時間とかかかっていたので。
#使い方
サンプルデータとして
[kaggle-House Prices](https://www.kaggle.com/c/house-prices-advanced-regression-techniques)

```python

features['MSZoning'] = features.groupby('MSSubClass')['MSZoning'].transform(lambda x: x.fillna(x.mode()[0]))
```
これで 'MSSubClass'のグループ毎に'MSZoning'の最頻値を欠損値に代入できる。

```python
x.mode()[0]
>>>最頻値そのものの値を取得
```

以上

#まとめ
初めての記事投稿。
間違っている部分やアドバイス等ご指摘いただけると助かります。
ASP.NET Core で Razor ページ アプリにモデルを追加する(EFについて)

#環境や前提条件
クライアントOS : MacOS 10.15.7
ターミナル : 2.10
コマンドラインシェル : zsh
統合開発環境（IDE） : VisualStudio for Mac 8.8.8

#ツールを使用
ツールをインストール
ツールを更新
を行った後、

ターミナルで次のコマンドを入力

```zsh:ターミナル
dotnet ef --project RazorPagesMovie 
```


出力結果
![スクリーンショット 2021-04-03 12.19.49.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995433/ca38825f-b942-ceca-62e7-9bf565e78d7b.jpeg)







#参照
https://docs.microsoft.com/ja-jp/aspnet/core/tutorials/razor-pages/model?view=aspnetcore-5.0&tabs=visual-studio-mac

https://docs.microsoft.com/ja-jp/ef/core/cli/dotnet
【Python】【基本】or演算子の振る舞い【(a in c) or (b in c)と(a or b) in c)の違い】

### 概要
[nltkの学習中](http://www.nltk.org/book/ch01.html)に以下のようなコードが。

```python:
>>> sorted(t for t in set(text2) if "cie" in t or 'cei' in t)
```
ここでのtext2はnltkに最初から備え付けてあるTextオブジェクトなのですが、中身としては"Sense and Sensibility"という小説になっています。日本語だと「分別と多感」という名前で知られているようですね(未読)。

アホな私は、

```python:
>>> sorted(t for t in set(text2) if ("cie" or "cei") in t)
```

と同じじゃない?と思って試してみると、チュートリアル側のコードでは"ceiling"が要素に含まれているのに、自作のコードでは含まれていないという状態に。実際にその部分だけ判定を抜き出して見ると、以下のようになります。

```python:
print("cie" in "ceiling" or "cei" in "ceiling")
print(("cie" or "cei") in "ceiling")
```
```:出力結果
True
False
```

### なんでこんなことに?
or演算子の挙動をしっかりと理解していなかったが故の末路です。[こちらの記事](https://qiita.com/keisuke-nakata/items/e0598b2c13807f102469)を参考にさせていただくと、"cie" or "cei"は、以下のコードと等価です。

```python:
if bool("cie"):
    return "cie"
else:
    return "cei"
```

Pythonは1文字以上の文字列はTrueだと評価するので、if bool("cie"):は常にTrueになり、結果として"cie"しか返ってきません。そりゃ"ceiling"なんて入ってこないわけだ。

チュートリアル側のコードであれば、

```python:
if bool("cie" in "ceiling"):
    return "cie" in "ceiling"
else:
    return "cei" in "ceiling"
```

となり、if側でFalseとなりますが、elseでは"cei" in "ceiling"、すなわちTrueが返ってきます。結果として「文字列に"cei"か"cie"があれば」という判定をしっかりとこなせるわけですね。

### オマケ
なお、勉強ついでにandの場合の挙動も確認しておくと、

```python:
if not bool("cie"):
    return "cie"
else:
    return "cei"
```

と等価になります。bool("cie")は常にTrueなので、この場合はelse文に入って必ず"cei"が入ってくることになりますね。

### まとめ
前も似たようなことで引っかかった記憶があるのですが、その時は「何故か動く」の精神でスルーしていました。しっかりと調べて覚えて、記録しておくのは大事ですねホント。今後も頑張ります。

集合知に感謝。
ESBuildでTypescriptのパッケージを開発する

# 概要

Typescriptの自分用パッケージを作ろうと思い当初Webpackで行こうと思ったのですが、折角なのでESBuildで開発出来るように致しました

# 作ったもの

以下Githubに公開しました
https://github.com/ymuichiro/ts-package-develop-template

# 環境

- Node.js v14.16.0
- esbuild 0.11.2
- typescript 4.2.3
- @material-ui/core 4.11.3
- react 17.0.2


# 使い方

1. コードは src 配下に記述する
2. コードの記述が完成次第、esbuild を実行
3. 出力ファイルが正しく dist 配下に存在するか確認
4. NPM もしくは、Github にアップロードし、パッケージとして利用

# 注意点

React用のパッケージ開発時は`./esbuild/build.js`を以下のようにしてください

```./esbuild/build.js
require('esbuild')
  .build({
    entryPoints: ['./src/index.ts'],
    bundle: true,
    define: { 'process.env.NODE_ENV': `"${process.env.NODE_ENV}"` }, // 追加
    outdir: 'dist',
    format: 'cjs',
    minify: true,
  })
  .catch(() => process.exit(1));
```

以上
RailsでLINE_Boot作成する

#前提
LINE-Botの作成の方法を備忘録として残してます。

#環境
- Homebrow
- ruby '2.6.3'
- rails '6.1.3'


#Messaging API | LINE Developers

[Messaging API | LINE Developers](https://developers.line.biz/ja/services/messaging-api/)
先にLINE Developers登録してください。

#チャネルの作成
「新規プロバイダー作成」をして「Messaging API」をクリックします。


```
$ gem 'line-bot-api'
```
`bundle install`しましょう


#ngrokのインストール
Homebrewを使ってngrokをインストールします。

```
$ brew install ngrok
$ ngrok --version
```
バージョンが表示されていたらインストール出来ています。

```
$ rails s
```
railsのサーバー起動して新しいターミナルで`ngrok`を起動させます。
[http://localhost:3000](http://localhost:3000)でアクセスしてますので` http 3000`します。

```
$ ngrok http 3000
```

`ngrok`のターミナル上で表示されていますのでここからアクセスできます。
ですが`rails`でDNSリバインディング攻撃の対策のためアクセスできないようになっています。

```
Forwarding  https://xxxxxxx.ngrok.io
```


```config/environments/development.rb
  config.file_watcher = ActiveSupport::EventedFileUpdateChecker

  # Uncomment if you wish to allow Action Cable access from any origin.
  # config.action_cable.disable_request_forgery_protection = true
  config.hosts.clear #追加します
end

```
`rails`を再起動させて`ngrok`のターミナルの`https://xxxxxxx.ngrok.io`アクセスします。


```app/controllers/line_bot_controller.rb
 protect_from_forgery except: [:アクション名]
 #CSRF対策を無効化するコードです。
```

#.env作成

```
gem 'dotenv-rails'
```
`bundle install`します。


```
$ touch .env
```

```:.env
LINE_CHANNEL_SECRET='xxxxxxxx'
LINE_CHANNEL_TOKEN='xxxxxxxx'
```

`LINE_CHANNEL_SECRET`
基本設定のチャンネルシークレットを発行し、コピーします。

`LINE_CHANNEL_TOKEN`
メッセージングAPI設定のチャネルアクセストークンを発行し、コピーします。

```:gitignore
/.env #追加します
```

#Webhook設定
表示させたページを設定します。
`https://xxxxxxxxxx.ngrok.io/xxx`
ngrokを起動するたびにURLが変わるため設定しなおす必要があります。

これでRailsとlineの連携の設定は完成です。
簡単な返答くらいなら可能な状態になりました。

`gem 'httpclient'`を使用し、WebAPI叩ける様にもできます。
ReactでonClickで指定したイベントハンドラがレンダー時に発火する

#### 環境
- react 17.0.1

#### 内容
Material-UIのchipのタイトルをイベントハンドラの引数に指定したら、レンダー時に発火した。


```javascript:レンダー時に発火するコード
export default function TagsSerch() {
    const handleClick = (title) => {
        console.info(title);
    };

    /* 色々省略 */

    return (
        <Box>
            <Typography variant="subtitle1">タグ検索</Typography>
            {tagList.map((tag, index) => (
                <Chip
                className={classes.tags}
                name={tag.title}
                label={tag.title}
                clickable
                color="primary"
                size="small"
                onClick={handleClick(tag.title)}    /* ⇦ここ */
                key={tag.title}
                />
            ))}
        </Box>

    );
}
```


[React公式サイト](https://ja.reactjs.org/docs/handling-events.html)によると、こんな感じで引数を渡してくださいとのこと。


```javascript:レンダー時に発火せず引数をイベントハンドラに渡す
export default function TagsSerch() {
    const handleClick = (title, e) => {
        console.info(title);
        console.info(e);
    };

    /* 色々省略 */

    return (
        <Box>
            <Typography variant="subtitle1">タグ検索</Typography>
            {tagList.map((tag, index) => (
                <Chip
                className={classes.tags}
                name={tag.title}
                label={tag.title}
                clickable
                color="primary"
                size="small"
                onClick={onClick={(e) => handleClick(tag.title, e)}}    /* アロー関数かまして呼び出すよ */
                key={tag.title}
                />
            ))}
        </Box>

    );
}
```

今回はイベントオブジェクトはいらないので、最終的にこんな感じになりました。


```javascript:レンダー時に発火せず引数をイベントハンドラに渡す（イベントオブジェクトなし）
export default function TagsSerch() {
    const handleClick = (title) => {
        console.info(title);
    };

    /* 色々省略 */

    return (
        <Box>
            <Typography variant="subtitle1">タグ検索</Typography>
            {tagList.map((tag, index) => (
                <Chip
                className={classes.tags}
                name={tag.title}
                label={tag.title}
                clickable
                color="primary"
                size="small"
                onClick={onClick={() => handleClick(tag.title)}}    /* アロー関数かまして呼び出すよ */
                key={tag.title}
                />
            ))}
        </Box>

    );
}
```
【Rails】FontAwesomeの導入方法

#はじめに
この記事は```FontAwesome```の導入方法について説明します。

```Font Awesome```とは、自身のウェブサイトやアプリケーション、WordやPDFなどのドキュメントにも埋め込めるWebアイコンフォントのことで商用利用もできます。


#FontAwesomeの導入
まずは```gem```を編集します

```:gemfile
gem 'font-awesome-rails'
```

忘れずに```bundle install```をしましょう

```:ターミナル
$ bundle install
```

最後に```application.scss```を編集します

```scss:application.scss
/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
 * vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
 * files in this directory. Styles in this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *
 *= require_tree .
 *= require_self
 */
 /*
*/
@import "bootstrap";
//↓　追加
@import "font-awesome";
```

これで使う準備は整いました。

#つかってみよう
リンクを入れたい場所に入れることで使えるようになります。
例えばカレンダーのアイコンを表示させてみます

```:
<i class="fa fa-calendar" aria-hidden="true"></i>
```

以下のようにカレンダーのアイコンが表示されれば成功です
![xTN5ilycotqXg5H1617419586_1617419656.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1268848/347402b4-c9fe-6526-09a4-8aff78aed593.png)
【メモ】eclipseからxamppのmariadbに接続する手順

#1.Why? java with MariaDB

[前回](https://qiita.com/xmorning777/items/114ad535ec0ecc157330)、javaでmvcアプリを作成した。
この段階から、crudアプリを作成できるようになりたかった。
なぜjavaからmariadbに接続するかは下記の理由があった。

__`(1)PHPで簡単なcrudアプリで作るのに、xamppをインストールしていた。`__
__`(2)とりあえず今あるxamppのDBを使って、javaでcrudアプリを作れるか試してみたい`__

さらに__xamppのコンパネにMySQLと書いてあるのでmysql-connector-xxx.jarを追加していたが実行すると接続エラーが出て動かない。__

__⇒____`「mariadb」のコネクタ`__が必要だったことが後にわかった。



#2.環境
xamppのバージョン：7.2.3
eclipseのバージョン：Version: 2019-12 (4.14.0)
mariadbのバージョン:10.1.31
java:11
OS:windows10 home 64bit

#3.eclipseでの設定

__1).DB接続の必要なプロジェクトを右クリックしてビルド・パスを選択__

![89985E47-FD1A-4FBA-92B2-F07CFE7D9453.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/58bd6628-e357-84b0-8c00-c906ea9142cc.jpeg)

__2).javaのビルド・パスで「ライブラリ」タブを選択し、クラスパスを
選択した状態で「外部JARの追加(x)」ボタンを押下。__

![65CE1C29-5623-4498-8E55-C2507691CE4E.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/1939198a-5321-6fb9-4097-5e86b5b7d809.jpeg)

__3).下記サイトでダウンロードしていたmariadb-java-client-xxx.jarを選択して
「開く」ボタンを押す__

![3E03ABCE-6BAB-41AF-A51E-ABAEDFBD5683.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/e3143bc7-40b7-d15b-293b-d7133b7dc0b0.jpeg)

[mariadbのjavaコネクタ(全バージョン)]
(https://downloads.mariadb.org/connector-java/+releases/)


__4).ライブラリのクラスパスにjarファイルが反映されていることが確認して、
適用して閉じるボタンを押下する__


![6E7CBD24-007C-4437-B18B-2B13D3BCDD8E.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/7f977ce2-605e-f38f-fde8-36780b4a87d5.jpeg)


#4.ソースでの実装例

```java

 public Boolean updateData() {

//pokemondbはデータベース名
  String URL
  = "jdbc:mariadb://localhost:3306/pokemondb?useUnicode=true&characterEncoding=utf8mb4";
  String USER = "root";
  String PASS = "";

  try(Connection conn =
    DriverManager.getConnection(URL, USER, PASS)){

   conn.setAutoCommit(false);

  //DB処理
  
  } catch (Exception e) {
   e.printStackTrace();
   return false;
  }finally {
   System.out.println("処理が完了しました");
  }
 }

```
macOS14.x以降でOutlookの検索をすると「結果なし」と表示されて、全然検索ができなくなった時にしたこと

# はじめに

いつの頃からか検索ができなくなって困ってしまいました。
![スクリーンショット-2021-04-03-11.32.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114240/ce7d7e9f-58c8-e5a3-a764-1a2fb30f4b18.png)
いくつかのWebサイトを参考にしてみたら、修正ツールがあるというのでダウンロードしてみると以下の表示が...
![スクリーンショット 2021-04-03 11.44.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114240/d1b203cd-3858-6755-004d-5bd469acc0cf.png)
もう仕事になりません！...と四苦八苦した結果、そんなことか〜って感じで解決したのでまとめます。

# OnyX

## インストール

以下のURLよりダウンロードして、インストールします。

https://titanium-software.fr/en/onyx.html

## 再構築

Spotlightを含めて再構築を実行。
実行後に再起動が必要になります。
![スクリーンショット 2021-04-03 11.30.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114240/c3915643-0ef1-f10d-876d-82926724a7f2.png)
再構築が終わるまで、かなりの時間がかかりますが普通にMacで作業をしながら構築が終了するのを待つ。

# Outlook

再構築が終わったところで、Outlookを再起動して検索をしたら出るようになりました。
![スクリーンショット-2021-04-03-11.32.25a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114240/c8e330c3-071d-d775-f6a3-c37b009f272a.png)

できた！
さて、頑張って仕事しよう。
未経験からプログラマーに転職して半年が経ちました。

北海道の札幌でプログラマーをしているだいきんです。

今回は新人プログラマ応援ということで
僕もまだまだ新人ですが、これからプログラマーとしての人生をスタートさせる人の
応援に繋がればと思い、僕の体験談からの独り言(アドバイス)を纏めておきます。

## 経歴
僕は高卒で普通に会社員をしてました。PCにふれる機会はありましたが
オフィスソフトを触るぐらいでプログラムとは無縁の生活。
前職で言えばお客様との対応がメインの仕事をしていたけど
一度きりの人生ということでやりたかったプログラミングを学び始めて
2020年10月になんとかプログラマーとして転職を成功させました。
そこから小さな保守対応やら大きなプロジェクトにも参加させてもらい
今現在も経験値積み続けています。
そんな自分が新人プログラマーにおくる内容は次の項目からです！

## スタートは挨拶
挨拶は仕事限定とは言わず人との関わりがあるのであればなくてはならないかと思います。
なので僕は入社したときの挨拶はとにかく大きな声で元気さをアピールしました。
意外と出来ない人が多いイメージなんですがやることはこれだけで割と注目度はあがるのかと思います。
目立ちたくない人はやらなくてもいいですが、自分はとにかく色々やらせてもらいたかったので
挨拶で目立つようにしました。

## できることの喜びよりも、出来ないことが知れる喜びを知ろう
偏見かもしれませんが、日本人って何か任されて出来なかったときにものすごく落ち込みがちですよね
そんな僕もやはり出来ないよりは出来たほうが達成感もあるので嬉しいのは間違いないです。
でも出来たことの数だけ喜ぶよりも、出来なくて落ち込む数のほうが圧倒的に多いなと感じてます。
そんな状態でいると、落ち込む数が多いので必然と気持ちも沈みっぱなしに、、。
それは自分にとって本当によくないので考え方を今のうちから変えておきましょ！

「出来ないことが知れた！ラッキー！！」です！

そう思ったら後はできるように行動するだけ！！
するといつかはできるようになるのでそのときには
「出来なかったことが出来るようになった！」とまた喜びが生まれるんです。
めっちゃいい循環じゃないでしょうか
それでも人間なのでやはり落ち込むときは出てくるでしょう。
そんなときは大好きなコメダのおぐらあんでも食べて、美味しいコーヒーで一息すればいいのです。
なにも365日24時間フルスロットルでいないといけないわけじゃない。
疲れたら休もう！それでいい！

## 完璧なんて存在しない！
実際にコードに触れる機会が出てくるだろう。
そして、なにかしたらのタスクが与えられてしっかりとタスクを期限に終わらせるようにするだろう。
そこでやる行動の悪手が完璧なコードで提出しようだ
自分の思う「完璧」と例えばリーダーの思う「完璧」あとはそのシステムを求めているクライアントの「完璧」
この３つの「完璧」は言葉はおなじでも中身は全く違うんですよね
例えば
#### 自分の思う「完璧」
きれいに整っていて無駄のない要件をしっかりと満たしつつ
改修のしやすいコードをかくこと
#### リーダーの思う「完璧」
全体の実装方針がそろっていて要件が満たされバグのない
意図が理解できるコード(リーダーの経験はないので他にもあるかも)
#### クライアントの「完璧」
期日に納品されるのは当たり前。かつ使いやすく
業績につながるシステムであること(こちらも予測です)

ちょいと経験値がたりないので足りてない情報があるかもしれませんが
ここで大事なのは自分とリーダー、他チームメンバーとの「完璧」に対するずれを
なくしておかないと自分が痛い目を見る羽目になります
先に書いた自分の思う「完璧」でリーダーにコードレビューしてもらったら
全体と実装方針が違うから8割ほど直して、、。みたいなことになりかねません。
それは自分にとってもチームにとっても良くないことです。
それじゃどうしようかというと
まずは要点を抑えたコードでレビューをもらいましょう
別にきれいなコードじゃなくていいです。最低限要件はクリアして
要件通りに動くコードを書く、そして一度見返してコーディング規約や命名規則など
明確に求められていることをクリアしている状態でレビューをもらい
修正をしていくのがベストな対応だと思います。

結局他人同士が見たり書いたりするので、それぞれの価値観から考え方が変わり
実装するコードにも違いがでてくるので何かしらのレビューが返ってくるのほぼ１００%です。
そのレビューでリーダーの意図を汲んだり、新しい知見を広げるといいでしょう、
そして疑問に思ったこと、自分にはこうした意図があってこの実装が適しているのでは？となったら
相談していけばいいのです。
最初は自分が間違っているかもとちょい不安もあったりするでしょうが
先の項目でも纏めたように間違っていることに気づける絶好のチャンスなので
勇気を出して言っちゃいましょう！

## 偉そうに纏めたけど僕も日々勉強中の身です！
いろいろ纏めましたけど僕もまだ31歳の若造で経験も浅いですが
せっかくプログラマーとなったのであれば楽しんでいきましょ！
まとまりがなくてすみませんm(__)m

最後までよんでいただきありがとうございます。
LGTM貰えると嬉しいのでポチッとお願いします！
自分用メモ: 実装を元に考えるSQLの評価モデル

## 前提

特定の詳細な実装や先読み、最適化の話は別要素なのでここではしません
また、mysql, PostgreSQL, sqlite, oracle db, etcでそれぞれの呼び方が微妙に違いますので、その辺は合わせません

## SQLの捉え方

SQLはデータの変換フローを定義していると捉えれる

## 評価方法
評価順序や各要素の関連性は以下の通り

2はwhere、4はhavingを指しています

![Frontend Architecture@2x (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/972ced0b-d70c-eceb-12e0-592d2552dfbc.png)

関数はdatasetを元にdataset'を計算するもの

![Frontend Architecture@2x (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/234e91f0-605e-b406-6c65-6c195722c7df.png)

sqliteの集約関数に分類されるsum関数を構成する要素の実装例
https://github.com/sqlite/sqlite/blob/33941691a526dfc19c3f5a4de39864800a3a9cd9/src/func.c#L1527

## group byの考え方

group byは配列の次元数を+1する考えじゃなくて、データ構造そのままに、パーティショニングする為のパーティションの印をつけるものだと思うとわかりやすい
どの項目がどのパーティションに属すかを記すだけなら、そのままの次元のコレクションとして持っておけるので、処理しやすい

## fromの考え方

fromはTableからdatasetを構築し、上の処理モデルを適用できる状態にするものだと考えれる (実際にはselectの先読みとかチューニングがあるが、そういうのは今回は考慮しない

## 評価例

https://pct.unifas.net/mysql/3712/
このブログにある

```sql
SELECT *,
(SELECT TRUNCATE(EXP(SUM(log(b.num)))+0.005,2) FROM test b
  WHERE b.date <= a.date) AS ruiseki
FROM test a
ORDER BY a.date ASC;
```

の`SELECT TRUNCATE(EXP(SUM(log(b.num)))+0.005,2)`の部分を評価してみる

logは算術関数で、数値に対して算術をする関数.
SUMは集約関数で、パーティションで区切られたデータを纏める. パーティションが5つあったら、結果として出てくるデータの数は5である.
EXPとTRUNCATEもlogと同じものに分類されます.
これがどう評価されるのかというと、上の関数の説明を元に考えると、こうできる

![Frontend Architecture@2x (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/0b0ac986-3cb5-b563-a213-6e7494705b10.png)

なので、それぞれの数値に対する計算とパーティションを纏める集約関数を交互に重ねられている.

## 参考文献

* https://docs.oracle.com/cd/E96517_01/dwhsg/sql-analysis-reporting-data-warehouses.html#GUID-20EFBF1E-F79D-4E4A-906C-6E496EECA684
* https://pct.unifas.net/mysql/3712/
* https://github.com/sqlite/sqlite/
[速報] [iOS] Adjust SDKをバージョンアップしないと審査リジェクトの危険性アリ

表題の通り、Adjust SDKをアップデートしないと、アプリ審査でリジェクトを食らう可能性があるようです。

ご存知の通り、Appleから告知されていた「App Tracking Transparency」が背景にあり、こちらのWebニュースなどが参考になると思います。
https://iphone-mania.jp/news-358057/

Adjust SDKはVersion 4.28.0で対応されている模様です。
該当issueはこちらです。 
https://github.com/adjust/ios_sdk/pull/526

2021年4月1日の投稿より引用：

>We received reports that some app updates using our SDK v4.27.x and lower have been rejected by Apple. To address this problem, we have released v4.28.0. We recommend that all clients upgrade to SDK v4.28.0 before submitting their next app update.

（Google翻訳）
SDKv4.27.x以下を使用した一部のアプリのアップデートがAppleによって拒否されたという報告を受けました。この問題に対処するために、v4.28.0をリリースしました。次のアプリの更新を送信する前に、すべてのクライアントをSDKv4.28.0にアップグレードすることをお勧めします。
【Rails】Bootstrapの導入の仕方

#はじめに
この記事では```rails```に```Bootstrap```の導入の仕方を説明します。```bootstrap```を使うためには```jQuery```を入れる必要があるのでまだ```jQuery```を入れていない人ははじめに以下の記事から```jquery```を導入してください

https://qiita.com/Ochanyoro/items/a16cffef74f2f9ddba72

#Bootstrapの導入
まず初めに使う```gem```を記入します

```:Gemfile
gem 'bootstrap'
```
と同時に```bundle install```を行います

```:ターミナル
$ bundle install
```
次に```application.cssファイル```を```application.scss```に変更してください

```:app/assets/stylesheets/application.css
application.css　→　application.scss
```

そしたら```application.scss```に必要なものを記入していきます

```scss:app/assets/stylesheets/application.scss
/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
 * vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
 * files in this directory. Styles in this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *
 *= require_tree .
 *= require_self
 */
 /*
*/
//　↓追加
@import "bootstrap";
```

scssファイルではインポートに```@import```を使うので注意

最後に```application.js```を変更して終わりです

```js:app/assets/javascripts/application.js
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.

import Rails from "@rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "@rails/activestorage"
import "channels"

Rails.start()
Turbolinks.start()
ActiveStorage.start()
// ↓追加
//=require bootstrap
require('jquery')
```

設定は終わりです。これでbootstrapが使えるようになっていると思います
アプリを再起動して実際にできているか確認してみてください

#参考資料
https://qiita.com/NaokiIshimura/items/c8db09daefff5c11dadf
webpack + babel + TypeScript + React メモ

# webpack + babel + TypeScript + React 環境構築メモ

- init
    - `npm init -y `
- Babel
    - `npm i -D @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript`
    - .babelrc か babel.config.json を作成する(.babelrcはディレクトリ単位、babel.config.jsonはプロジェクト全体)
- webpack
    - `npm i -D webpack webpack-cli babel-loader ts-loader`
    - webpack.config.js
- React、TypeScript
    - `npm i -S react react-dom`
    - `npm i -D typescript @types/react @types/react-dom`
    - `npx tsc init`
    - tsconfig.json
    - src/index.ts
- webpack-dev-server
    - `npm i -D webpack-dev-server html-webpack-plugin`
    - src/index.html
    - package.json
    - `npm start`


# コマンドの説明

|npm|yarn||
|:---:|:---:|:---:|
| `npm init`                       |`yarn init`| package.json を作成
| `npm i -S `, `npm i`, `npm install --save` ,  `npm install`    |`yarn add`| package.json の dependenciesに追加
| `npm i -D `, `npm install --save-dev`|`yarn add -D`| package.json の devDependenciesに追加

# babel

```json:.babelrc
{
  "presets": [
    "@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"
  ]
}
```


# webpack

```js:webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  mode: "development",
  entry: "./src/index.tsx",
  output: {
    path: path.resolve(__dirname, "dist/"),
  },
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/,
        use: ["ts-loader"],
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
  ],
  devServer: {
    contentBase: "./dist",
    hot: true,
  },
};
```

# React + TypeScript


```js:src/index.tsx
import React from "react";
import { render } from "react-dom";

const App = () => {
  return <h1>Hello World! React x TypeScript</h1>;
};
render(<App />, document.getElementById("app"));
```

```html:src/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>
```

```json:tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "outDir": "dist",
    "strict": true,
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "jsx": "react"
  },
  "include": ["src"]
}
```

# webpack-dev-server

```json:package.json
{
  // 省略
  "scripts": {
    "start": "webpack serve",
    "watch": "webpack --watch",
    "build": "webpack --mode production"
  },
  // 省略
}
```

```
npm start
```
- http://localhost:8080/ を開く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/24f4a3ac-7fb2-ea64-c05a-2130bdfeca06.png)

参考
https://tech.playground.style/javascript/babel-webpack/
https://tech.playground.style/javascript/babel-webpack-build/
フラッシュカード作ってみました

Python学習の一環でフラッシュカードにトライしました。環境は、Google coloboratoryです。

###目標：
一つ一つの英単語に日本語で答え、正解であれば「正解」、「不正解」であれば再度不正解の英単語に答える。一度答えた英単語は再び出力しないようにする。
###フロー
・英単語が表示される。
・日本語で解答する。
・英単語と日本語が合っているか確認する。


辞書型リストに英単語、日本語を入れ、それをデタラメに出力するようにしたいので、randomをインポートする

```python
import random 
```

ベースとなる英語、日本語の辞書を作る

```python
d = {
    'desk':'つくえ',
     'chair':'いす',
     'school':'がっこう',
}
```
while文によるループ（繰り返し）処理し、条件が真Trueである間はずっとブロック内の処理を繰り返すということにしたいので

```python
while True:
```
英辞書のkeyだけ出したいので、単語を表示させる為、辞書のkeyだけを出したいので、keysメソッドを使う。そして、これをランダムに要素を取得したいのでrandom.choiceに、その前にlistでキャスト(別の型）にしてあげる.

```python
 word = random.choice(list(d.keys()))
    print(word)
```
次に日本語を入力する欄を作る

```python
    answer = input()
```

終了する際、0で入力したら、”終了します”で、終了。自分が入力した日本語と、英単語の答えがあっているか確認する。もし自分の答えが辞書のword（要素）と同じなら”正解”にする。違ったら”不正解”にする。

```python   
if answer == '0':
        print('終了します')
        break
elif answer == d[word]:
        print('正解')
else:
        print('不正解')
```

以下コードをまとめました。

```python
import random 

d = {
    'desk':'つくえ',
     'chair':'いす',
     'school':'がっこう',
}

while True:
    word = random.choice(list(d.keys()))
    print(word)
    answer = input()
    if answer == '0':
        print('終了します')
        break
    elif answer == d[word]:
        print('正解')
    else:
        print('不正解')
```

実行すると・・・

```
school
がっこう
正解
desk
つくえ
正解
school
がっこう
正解
desk
```

一度正解の解答がまた出てくるサイクルになってしまいました。これを防ぐ為、While文を文字数０以上の間, 答えた要素を削除したいので、リストのメソッドpop()を使って、指定した位置の要素を削除し、その要素の値を取得できるにしました。

```python

import random 
d = {
    'desk':'つくえ',
     'chair':'いす',
     'school':'がっこう',
}
while len(d)>0:
    word = random.choice(list(d.keys()))
    print(word)
    answer = input()
    if answer == '0':
        print('終了します')
        break
    elif answer == d[word]:
        print('正解')
        d.pop(word)
    else:
        print('不正解　もう一度')
```

結果は・・・・・

````
chair
つくえ
不正解　もう一度
desk
つくえ
正解
school
がっこう
正解
chair
いす
正解
```

不正解の場合は、再びトライの問題が出て、正解になった問題は再び出ることはなくなりました。

###今後の目標：
スクレイピングから取得した情報を辞書リストにし、フラッシュカードを作れるようにしたいと考えています。
【Python】関数を返す関数（ネストされた関数）を理解する（備忘録）

# はじめに

ネストされた関数を見ることは多いですが、私は初めの頃すんなりと理解出来なかったのでまとめます。
↓の記事で書いた**「関数を変数に格納して扱う方法」**の深掘りです。

https://qiita.com/shinkai_/items/04f1aa0ae6968188efe4

# 関数を返す関数を実装する

さっそく関数を返す関数を作成します。

```python
def add_func(value):
    def func(value_2):
        return value + value_2
    return func
```

上記の関数**add_func()**は内部で定義している関数**func()**を返します。

実際に実行してみます。

```python
def add_func(value):
    def func(value_2):
        return value + value_2
    return func

add_1 = add_func(100)
print(add_1(1))

add_2 = add_func(1000)
print(add_2(1))
```

```
101
1001
```

上記の出力結果を見て「そりゃそうでしょ」とすんなり理解出来た人はもうこれから先を読まなくても大丈夫です。
C#やJavaに慣れている私は、初めてこのようなコードを見た時に一瞬頭の中が？？？となりました。。。

# 解説

まず下記の１行が実行されたときにどうなるか見ていきたいと思います。

```python
add_1 = add_func(100)
```

変数add_1には関数add_func()内でreturnしている関数func()が格納されます。
関数が格納されているので変数add_1のタイプを出力してみると**function**となっています。

```python
add_1 = add_func(100)
print(type(add_1))
```

```
<class 'function'>
```

ここでポイントになるのが、変数add_1には**「展開された後の関数func()が格納される」**ということです。
`add_func(100)`として引数valueに100を格納したことで、func()内で使用しているvalueは100に確定します。
※下記、展開後１の状態

```python
def add_func(value):
    def func(value_2):
        return value + value_2
    return func
add_1 = add_func(100)

# 展開後１
def add_func(100):
    def func(value_2):
        return 100 + value_2
    return func
```

そのままreturnとしてvalueが100と決まっているfunc()が返却されます。
※下記、展開後２の状態

```python
# 展開後２
def func(value_2):
    return 100 + value_2
return func
```

つまり

```python:A
def add_func(value):
    def func(value_2):
        return value + value_2
    return func

add_1 = add_func(100)
print(add_1(1))
```

```python:A'
def func(value_2):
    return 100 + value_2
return func

print(func(1))
```

上記のA'はAと同じ意味となります。

以上
ruby each文の入れ子

##初めに
初学者です。rubyの練習問題を私なりに解説することによって定着するのが目的です。間違いありましたらご指摘お願いします。

###問題
以下のように、果物の名前と値段が入った配列があります。
この配列を用いて、果物の名前とそれぞれの合計額が出力される
コードを記述してください。

```
fruits_price = [["apple", [200, 250, 220]], ["orange", [100, 120, 80]], ["melon", [1200, 1500]]]
```

```
（出力）
appleの合計金額は670円です
orangeの合計金額は300円です
melonの合計金額は2700円です
```

まずはeachメソッドのおさらいからしていきます。
### eachメソッド
eachとは、配列やハッシュの要素１つ１つに対して要素の数だけ繰り返し処理をすることができるメソッドです。そして繰り返す後にブロック変数の中に配列やハッシュの値が格納されていきます。
書き方としては以下のようになります。

```
(配列　or ハッシュ).each do |ブロック変数|
#処理
end
```

またハッシュのようにキーとバリューがある場合、ブロック変数を２つ用意することでキーとバリューの２つの要素を順番に格納することができます。

### 解説
今回の問題のポイントはeach文を1回書いただけでは全ての値を取り出すことができないことです。金額を取り出すにはeach文を2回使用することが必要になります。
要するに、まずはeach文を使用してappleという配列を取り出し、それからappleの配列の金額を取り出すし順番にプラスしていき金額の合計を出すという流れになります。なのでまずappleを取り出します。

```
fruits_price = [["apple", [200, 250, 220]], ["orange", [100, 120, 80]], ["melon", [1200, 1500]]]
fruits_price.each do |fruit|
end
```
上記の記述では変数fruitに["apple", [200, 250, 220]]という値が格納されます。
そしてappleからeach文を使い金額を１つずつ取り出してプラスしていきます。そしてその前に、合計値を保存できるように変数を作ります。今回の変数名はsumです。

```
fruits_price = [["apple", [200, 250, 220]], ["orange", [100, 120, 80]], ["melon", [1200, 1500]]]

fruits_price.each do |fruit|
  sum = 0
  fruit[1].each do |price|
    sum += price
  end
end
```
fruit[1].each do |price|の文では、変数fruitの１番目の値を一つずつ取り出しています。そして最後に出力する記述を書けば終了です。

```
fruits_price = [["apple", [200, 250, 220]], ["orange", [100, 120, 80]], ["melon", [1200, 1500]]]

fruits_price.each do |fruit|
  sum = 0
  fruit[1].each do |price|
    sum += price
  end
  puts "#{fruit[0]}の合計金額は#{sum}円です"
end
```
そしてappleの値を全て返した後に次のorengeが同じように繰り返されます。
[Rails] ActiveRecord::ValueTooLong (Mysql2::Error: Data too long for column 'content' at row 1):

## なぜこのエラーが出たか
データ型の文字制限を超えた情報をDBに格納しようとしたから。

## 解決方法
データ型を変えることにした

```ruby
    - t.string "content"
    + t.text "content"
```
migrateした後は、DBにしっかり格納された。

補足:
limitオプションでも条件を変えることができる。
Railsアプリのherokuデプロイ

# heroku CLIインストール(初回のみ)
```
% brew tap heroku/brew && brew install heroku
```

# ログイン
```
heroku login --interactive
 => Email:
 => Password:
```

# アプリケーション作成
```
heroku create アプリ名
```

# ClearDBアドオン
```
% heroku addons:add cleardb

% heroku_cleardb=`heroku config:get CLEARDB_DATABASE_URL`

% heroku config:set DATABASE_URL=mysql2${heroku_cleardb:5}
```

# 環境変数の設定
```
% heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
```

# gitをherokuにpush
```
git push heroku main
```

# マイグレーション
```
heroku run rails db:migrate
```

# ログ確認
```
heroku logs --tail --app <<アプリケーション名>>
```
Reactで複数要素に動的にクリック→スクロールする（createRef, useRef）

#Reactでクリック→スクロールする方法について
Reactで『クリック→該当部分までスクロール』を行う場合、以下のようにcreateRefを使用することがありました。

```react:App.tsx
const ref = createRef<HTMLDivElement>()
```
ここで定義したrefをスクロールさせたい箇所に渡して、

```react:App.tsx
const handleJump = useCallback(() => {
  ref!.current!.scrollIntoView({ behavior: "smooth" })
}, [ref])
```
クリック時にスクロールするよう関数を定義する。すると以下のようにクリック→スクロールができます。

![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493982/5f52a89a-bc93-a790-02ea-1784c6d70664.gif)

ソースコードは以下を参照いただければ幸いです。
[CodeSandbox](https://codesandbox.io/s/focused-curie-1zeb6?file=/src/App.tsx)


ですが、これだとスクロール箇所が増える度に、ユニークなrefを定義していく必要があるので、
**`複数の要素に動的にスクロールさせる`**ことを検討しました。

#結論
以下がソースコードです。
[CodeSandbox](https://codesandbox.io/s/jolly-dan-0ftm9?file=/src/App.tsx)

```react:App.tsx
type Item = {
  title: string;
  background: string;
  service: string;
  otherContent?: boolean;
};

const items: Item[] = [
  { title: "コンテンツ1", background: "skyblue", service: "サービス1" },
  { title: "コンテンツ2", background: "yellow", service: "サービス2" },
  { title: "コンテンツ3", background: "green", service: "サービス3", otherContent: true }
];
```
↑のような配列のデータがある場合、

```react:App.tsx
  const pageRef = useRef(items.map(() => createRef<HTMLDivElement>()));

  const scrollToView = (id: number) => {
    pageRef.current[id]!.current!.scrollIntoView({ behavior: "smooth" });
  };
```
↑のコードのように
**- mapを使ってrefの配列を作り
- 関数（scrollToView）の引数にはidを受け取る**

とすることでrefを何度も定義せずに動的にクリック→スクロールをさせることができました！

![wiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493982/9cfde619-441d-8454-6f52-db3356261922.gif)

#参考
https://stackoverflow.com/questions/57762703/using-refs-in-a-dynamic-length-array-for-scrollintoview

https://dev.to/ajsharp/-an-array-of-react-refs-pnf

https://www.javaer101.com/ja/article/53131054.html

https://zrsbqzz4wu6limdjn6cnjegmw4-jj2cvlaia66be-stackoverflow-com.translate.goog/questions/54633690/how-can-i-use-multiple-refs-for-an-array-of-elements-with-hooks/56063129#56063129
KiCadでバス配線の意味がようやくわかった

# バス配線が必要になった
今回７segLEDを用いて、初心者向け練習回路を設計していたらバス配線が必要な気がしました。そこで、参考までに記録してみました。
使用バージョン
`KiCad 5.1.9-0-10_14 macOS Version10.16`


# 自分なりに解釈したバス配線について
多くの電子回路系cadではバス配線が用意されている。
バス配線とは、同じピンを使用する複数のディバイスに対して結線を簡単に行うための手法
バイトアクセスコンピュータなどでは、８bit＝１byteをまとめて扱います。
例としてデーターバス、アドレスバスなどがあり、CPUとROM、RAM、I/Oなどの各モジュールを繋いでいました。
同じようなパターンで、複数本配線がなされるため、１本１本地道に接続すると回路図がとても見辛くなってしまします。
回路図を見易く、構造が理解しやすいようにするためにもバス接続を用いましょう。

#### KiCadでのバス接続
kiCadでもバス配線のメニューが用意されていますが、ただ繋げても配線したことになリませんでした。
実際には、ネットラベル（配線に対してのラベル）によって配線情報を構築し、バス配線自体は見た目をよくするためだけのようです。
それでは、簡単に手順を紹介します。
次の回路図を参考にバス配線を用いて回路図を作ってみましょう。
ArduinoNANOのD0ーD7から出力されて線が集合抵抗を通って、４つの７segLEDと２つのLEDにバス接続されています。
![スクリーンショット 2021-04-02 16.30.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355420/f11be786-27d0-87a5-bfed-71c90998d2db.png)
## 手順１ 対象のシンボルを結線する
バス配線をするシンボルを**普通**に結線します。
ここからバス接続を行ってディバイスを増設していきます。
![スクリーンショット 2021-04-02 18.20.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355420/52afa466-ae17-f510-6c16-f777e578ae98.png)
今回は集合抵抗と４つの７セグメントLED結線します。
７segのようなディバイスは基本的にバス配線となります。
（今では４モジュールがパッケージされた製品も多くあります。）

## 手順２　ワイヤーバスエントリ　（コネクタ）を取り付けます
![スクリーンショット 2021-04-02 18.24.56のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355420/8a82dec2-f7c8-0c56-8bd0-cca252331ad3.png)

![スクリーンショット 2021-04-02 18.21.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355420/8993f728-f4d1-2f43-80d3-6530ad9844a0.png)
クリックするだけで配置されますので、いっぱい出現しないように注意してください。

## 手順３　バス配線
バスエントリから他のモジュールのバスエントリへバス配線で接続します。
![スクリーンショット 2021-04-02 18.24.56のコピー2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355420/4cc653f4-6bea-48d7-5a86-34ff0091ca9e.png)
![スクリーンショット 2021-04-02 18.22.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355420/0cbf38e0-2f4b-56f8-b9a4-bbe8fc499946.png)

# 最重要
## 手順４　ネットラベルを付ける　
作図をしてきましたが、ここだけ間違ってなければ回路的には問題ありません。
ネットラベル（配線へのラベル付け）をします。ちょっと地道な作業になります。
![スクリーンショット 2021-04-02 18.24.56のコピー3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355420/dee452fa-6069-3e61-8e62-79987d802399.png)
![スクリーンショット 2021-04-02 18.23.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355420/742579be-9097-c1de-f96f-c8d815cc6f47.png)
配線（ネット）をクリックし、ラベルを入力します。
同じラベルが付いているもの同士が接続されます。

### 参考
最終的にこんな感じになります。
![スクリーンショット 2021-04-02 18.24.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355420/7910c11d-65bb-c000-2615-69ec165ed9c6.png)
各モジュールのAとA、BとBのように同じラベル同士が接続されています。
結局ネットラベルが全てなんですね。
私は気づくまでに少々手こずりました。

バス配線をするとスッキリとした回路図に見えます。
昔は、アドレスバスとかデータバスとかディバイス間全てバス配線といった感じでしたが、シリアルモジュールの進歩でほとんど見かけなくなりました。

kiCadの基本的な使用方法はこちらから

https://qiita.com/mat-MUNET/items/31e71d0bda0ed464db03
PC購入後の環境設定(Mac Catalina)

# シェルの設定
```
# zshをデフォルトに設定
% chsh -s /bin/zsh

# ログインシェルを表示
% echo $SHELL
# 以下のように表示されれば成功
/bin/zsh
```

# Command Line Tools
```
% xcode-select --install
```

# Homebrew
```
% cd  # ホームディレクトリに移動
% pwd  # ホームディレクトリにいるかどうか確認
% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" # コマンドを実行
# PasswordはMacのパスワード
```
```
# 最新状態に
% brew update

# 権限の変更
%  sudo chown -R `whoami`:admin /usr/local/bin
```

# Ruby
```
# rbenvとruby-buildをインストール
% brew install rbenv ruby-build

rbenvのパスを通す
% echo 'eval "$(rbenv init -)"' >> ~/.zshrc

# zshrcの変更を反映
% source ~/.zshrc
```
```
readlineインストール
% brew install readline
% brew link readline --force
```
```
# Rubyインストール
% RUBY_CONFIGURE_OPTS="--with-readline-dir=$(brew --prefix readline)"
% rbenv install 2.6.5

# Rubyバージョン指定
% rbenv global 2.6.5

# rbenvを読み込んで変更を反映
% rbenv rehash
```

# MySQL
```
% brew install mysql@5.6

# 自動起動設定
% mkdir ~/Library/LaunchAgents 
% ln -sfv /usr/local/opt/mysql\@5.6/*.plist ~/Library/LaunchAgents
% launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql\@5.6.plist 

# パスを通す
% echo 'export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"' >> ~/.zshrc # mysqlのコマンドを実行できるようにする設定
% source ~/.zshrc #  設定を読み込むコマンド
% which mysql # mysqlのコマンドが打てるか確認する

# 起動確認
% mysql.server status # MySQLの状態を確認するコマンド
```

# shared-mime-info
```
% brew install shared-mime-info
```

# Rails
```
# bundlerインストール
% gem install bundler --version='2.1.4'

# Railsインストール
% gem install rails --version='6.0.0'

% rbenv rehash
```

# Node.js
```
brew install node@14

# パスを通す
% echo 'export PATH="/usr/local/opt/node@14/bin:$PATH"' >> ~/.zshrc
% source ~/.zshrc
```

# yarn
```
% brew install yarn
```