OmniAICreator/Qiita-1.07M huggingface dataset:
【Godot】TextureProgressを使用したクールダウンアイコンの実装方法

# 概要
この記事では、アクションゲームなどで最近良く見かけるクールダウンアイコンの実装方法を紹介します。

![shot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/04f99f88-efe0-4dfe-41e4-5be784e7e672.gif)

# Spriteの作成
Spriteノードを追加して、"icon.png" を Textureに設定します。
![Godot_Engine_-_TestCoolDown_-_Sprite_tscn____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/6b3aac50-20e0-eb39-ed6c-aecc89367985.png)

# TextureProgress を追加
Spriteノードの下に `TextureProgress` を追加します。
![Godot_Engine_-_TestCoolDown_-_Sprite_tscn____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/71a351a7-c719-8fbb-9cdb-5ee9b15f5d0c.png)

そして、`Texture > Progress` に "icon.png" を設定します。
![Godot_Engine_-_TestCoolDown_-_Sprite_tscn_____と_408_adv_—_docs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/2272c628-08e4-ae56-3725-f66ccb38273b.png)

見た目をわかりやすくするために、ひとまず `Range > Value` を 75にしておきます。そして、`Fill Mode` を 「Counter ClockWise」に変更します。

![Godot_Engine_-_TestCoolDown_-_Sprite_tscn____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/6b6020cb-41e4-9923-4924-50a2e045ffe8.png)

すると Godotくんの右上が欠けたような画像となります。
![Godot_Engine_-_TestCoolDown_-_Sprite_tscn____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/9891aece-272c-3bc2-8028-fd0f8cc4c123.png)

## 暗転する色の設定
続けて `Tint > Progress` の色をクリックしてカラーパレットを表示し、(R,G,B,A)を(80, 80, 80, 200) あたりに設定します。グレーっぽい色になっていれば数値はだいたいで良いと思います。
![Godot_Engine_-_TestCoolDown_-_Sprite_tscn____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/50a8ab91-4363-c9c3-0fc4-3b3958cbe817.png)

すると 欠けたGodotくんの色がグレーになります。
![Godot_Engine_-_TestCoolDown_-_Sprite_tscn____.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/6a3b0429-2908-7c46-4202-9c54d5f2becb.png)

そしてTextureProgressを中央に移動しておきます。
![shot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/9e67e824-3eb4-0891-1359-62edfa5cfa64.gif)


# Spriteにスクリプトをアタッチ
Spriteにスクリプトをアタッチして以下のように記述します

```gd:Sprite.gd
tool

extends Sprite

# クールダウン値 (0でクールダウン終了)
export(float, 0, 100) var cooldown = 0
onready var progress = $TextureProgress

func _process(delta: float) -> void:
	# プログレスに値を反映
	progress.value = cooldown
```

`tool`宣言はシーンを開き直す必要があるので、シーンを保存して読み込みし直すと、エディタ上でクールダウンの動きが確認できます。
![shot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43772/04f99f88-efe0-4dfe-41e4-5be784e7e672.gif)

# 参考

* [COOLDOWN BUTTON :: Godot Recipes](http://kidscancode.org/godot_recipes/ui/cooldown_button/)
ALB まわりのポートを整理する

## はじめに

![00_20210214_qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/75d44a32-43bb-7beb-9072-eba0e876fa85.png)


ALB を利用する際に設定するポートが複数あるので、それぞれの役割を整理しました。

## ロードバランサーのポート

![01_ロードバランサーのポート_2021-02-13_23h53_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/fc698a52-9221-bbc2-fd03-d5b1fbf34a9c.png)

クライアントからロードバランサーへのトラフィックをリッスンするポート番号のこと

-   例 1) ロードバランサーのポートに 80 を設定した場合

![01_rei_20210214_qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/c4d6e8c1-31a5-ed82-f8b1-ffa76dce87a0.png)

## ターゲットグループ Basic configuration の ポート

![02_TargetgroupBasicconfigurationPort_2021-02-13_23h34_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/5c210ca4-eb33-fa38-ffac-78921f4e935a.png)

ターゲットの**デフォルト**のポート番号

## ターゲットのポート

※ ターゲットグループ Health checks Advanced health check settings の方が先に設定を行いますが、便宜上先に説明します

![05_RegistertargetPort2021-02-13_23h42_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/ad96e10f-16ec-1a49-6885-b508b45d7e05.png)

ターゲットのポート番号のこと

ターゲットの登録時にポート番号を変更すると、**ターゲットグループ Basic configuration の ポート**が上書きされて設定したポート番号宛にロードバランサーからリクエストが送られる

-   例 2) ターゲットのポート番号 81 と 82 でそれぞれ ec2 を登録した場合

![05_rei_20210214_qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/2fd3dc5e-49a3-d198-79fb-7a93ee8c37b8.png)

## ターゲットグループ Health checks Advanced health check settings の ポート

-   Traffic port

![03_TargetgroupBasicconfigurationTrafficport_2021-02-13_23h34_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/c981ef6a-df26-57f5-4b59-fc938cf5ce1a.png)

こちらを選択すると、ターゲットのポート番号が使用される。例 2 の設定の場合、ポート番号 81 と 82 に対してそれぞれヘルスチェックが実施される

-   Override

![04_TargetgroupBasicconfigurationOverrideport_2021-02-13_23h34_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/2b822669-8def-543a-9b86-9a2bf936ae49.png)

ここで設定したポート番号がヘルスチェックに使用される

-   例 3) Port Override 83 とした場合

![04_rei_20210214_qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534812/9603681b-3b16-b437-6dc0-e506e3dd5bf6.png)

# まとめ

**ターゲットグループ Basic configuration の ポート** と **ターゲットのポート** の関係性が分かりづらいため少し混乱すると思う。

> デフォルトでは、ロードバランサーはターゲットグループに指定したポートとプロトコルを使用して登録済みターゲットにリクエストを送信します。ターゲットグループに各ターゲットを登録するときに、このポートを上書きできます。

-   [ターゲットグループの作成 \- Elastic Load Balancing](https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/create-target-group.html)

と記載されているように

デフォルトでは、ロードバランサーは**ターゲットグループ Basic configuration の ポート**とプロトコルを使用して登録済みターゲットにリクエストを送信します。ターゲットグループに各ターゲットを登録するときに、**ターゲットのポートで**上書きできます。

となる。
【PHP】コメントアウト

###・`//`
行頭から行末までの1行をコメントアウト。一般的によく使用するタイプ。

```php
<?php

//コメントアウト

?>
```

###・`/* */`
複数行をコメントアウトする場合によく使用。

```php
<?php

/*ここから

ここまでコメントアウト*/

?>
```

###・`#`
行頭から行末までの1行をコメントアウトするときに使用。シェルやCSVファイルのコメントでよく使用される形式。

```php
<?php

#コメントアウト

?>
```

#参考
* [【PHP入門】コメント・コメントアウトの使い方を解説](https://www.sejuku.net/blog/25940)
[SwiftUI]sheetでViewを出し分ける

SwiftUIで`sheet`を使ってViewを出し分けを実装した時につまづいたのでメモ。

## できなかったこと
- View.sheetを２回書く
- sheetの中でif elseで出し分け


## 実現できた実装方法

こちらを使用しました。

```swift
public func sheet<Item, Content>(item: Binding<Item?>, onDismiss: (() -> Void)? = nil, @ViewBuilder content: @escaping (Item) -> Content) -> some View where Item : Identifiable, Content : View
```

Itemが`Identifiable`に準拠している時に、それに対する`View`を返します。

具体的な実装方法は、こちらです。


### Routerクラス
```swift
import SwiftUI

extension Identifiable where Self: Hashable {
    typealias ID = Self
    var id: Self { self }
}

enum ContentRouter: View, Hashable, Identifiable {
    
    case first
    case second(text: String)
    
    var body: some View {
        switch self {
        case .first: return AnyView(FirstView())
        case .second: return AnyView(SecondView(text: "Second"))
        }
    }
    
}
```

### View

```swift
struct ContentView: View {
    
    @State var router: ContentRouter?
    
    var body: some View {
        VStack {
            Button.init("First") {
                self.router = .first
            }
            Button.init("Second") {
                self.router = .second(text: "Second")
            }
        }.sheet(item: self.$router) { $0 }

    }
}
```

## 結果
それぞれのボタンで、別々のViewを出すことができました。
`.second`の場合の値の受け渡しもできました。

ソースはこちらにあります。
https://github.com/usk-sample/swiftui-router-sample/tree/main/SwiftUIRouterSample

## 参考

https://developer.apple.com/documentation/swiftui/view/sheet(item:ondismiss:content:)
https://qiita.com/1amageek/items/e90e1cfb0ad497e8b27a
https://yanamura.hatenablog.com/entry/2019/09/05/150849
【Semantic Segmentation】GALD : Globalの特徴量をpixel levelで捉える方法

<h1>Global Aggregation then Local Distribution in Fully Convolutional Networks</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/f1ce20dd-ffe4-7ba3-eec4-7094f2251411.png)
今までのASPPやPSPなどのGA(Global Agression)Moduleは全体の特徴を抽出する事が出来るが、oversmoothingされていると指摘している。
バスでない部分もバスと認識されている。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/04bd1e13-c3a2-87e3-4a48-ecf16aeb67f6.png)

そこで本論文ではLD(Local Distribution) Moduleを追加する事でGAのoversmoothingを改善する手法を提案している。

<h1>アルゴリズム</h1>
<h2>全体像</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/73b795df-cf5c-cb16-9fcf-e533c631f533.png)

BackBone : 特徴量を抽出するネットワーク(ex. ResNet, Xception)
Global Agrregation Module : 全体の特徴を抽出するModule (ex ASPP PSP Non-local CGNL)
Local Distribution Module : localの特徴を抽出するModule (本論文の提案手法)
Task-Speciafic head : 得られた特徴量を使って行うtask (ex Semantic Segmentation, Object Detection, etc...)


<h2>GALD Module</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/a2785126-b772-210d-f8bf-5d2ded5b689d.png)
GALDはPoint-wiseのMask(重み)を掛け合わせる。MaskはそれぞれのPixelが全体の特徴量(Fga)とMatchしてる場合に1、違う場合に0となる。
一種のAttentionですね。
*MaskはC,H,Wを0~1の範囲で重みを推定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/8a68c6aa-6248-1b5f-5424-8de1e11f38d8.png)

outputはFgaldとF(backboneからのLocalなFeature Map)を結合する事で、pixel-wiseの全体の特徴量とlocalの特徴量を組み合わせる事が出来る。

<h1>結果</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/0d21112b-86ec-a9e8-7c0d-4d14dd838407.png)

左が複数のGA Moduleを比較している。
右がGAとLDの組み合わせを比較している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/81b98b6f-8208-4608-9dc4-e2070a52a448.png)
左の実験はCGNLの勝ちですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/a6ad040c-84b5-0f37-f673-0f20008a6ac2.png)
右の実験は論文の提案と同じくGALDの勝ちですね。


<h1>結論</h1>
・Globalの特徴をLocalの特徴を組み合わせればいいと考えていたが、Globalの特徴がOversmoothingされている場合精度が低い事に気づけた


<h1>参考文献</h1>
Global Aggregation then Local Distribution in Fully Convolutional Networks
https://arxiv.org/pdf/1909.07229v1.pdf
【言語・フレームワーク考察】RubyとRuby on Rails

僕は、今後いろんな言語やフレームワークを学びたいと思っています。ですが、言語やフレームワークの種類が多すぎて、どれから学ぶべきか基準がわからず迷っています。

そこで、ひよっこプログラマーなりに持っている感想やイメージをまとめ、他にもネットで調べた特徴をまとめて「言語・フレームワーク考察」をして行きたいと思います。

# 気になっている言語・フレームワーク

**フロントエンド**

- Vue.js
  - コンポーネントが便利らしい？
- React
  - Vueよりももっと多機能？
- ElmとThe Elm Architecture
  - [Medium](https://medium.com/javascript-in-plain-english/here-is-what-you-should-learn-after-javascript-b9dd41950887)で紹介されていた。動作が速く、ランタイムエラーがないらしい。
- CSS
  - もっと深く知りたい。

**バックエンド**

- Ruby

  と

  Ruby on Rails

  - 見た目が綺麗で書いていて楽しい。

- Java

  - 理路整然と整っているイメージ。

- go

  - 動作が速いらしい？。速さは大事。

- rust

  - [Medium](https://towardsdatascience.com/thought-you-loved-python-wait-until-you-meet-rust-64a06d976ce)で紹介されていた。動作が速く、精密に扱いやすいらしい？

- C

  - いろんな言語の基礎となっているので、理解できるようになりたい。

- Swift

  - iOSアプリを作れるようになりたい

# 今回はRubyとRuby on Railsについて

## 素人的印象

### Ruby

**利点**

- 見た目がきれい（記号が少なく、文章のように理解できる）
  - きれいだと**書いて楽しい**
  - きれいだと**見て楽しい**
- いろいろ自由がきく
  - 思いついたことをいろいろ試しやすい印象

**欠点**

- 動作が遅い（らしい）
- もう少し記号がある方が、見やすいかもしれない

### Ruby on Rails

**利点**

- WEB

  アプリ開発

  がしやすい

  - ローカルサーバが簡単に立ち上がる
  - pry-railsでデバッグが簡単にできる

- 公式リファレンスがわかりやすい

- Gemが豊富

**欠点**

- 機能が必要以上に豊富
  - 標準ですごくいろんな機能が備わっていて、使わない物もたくさんあります。削る方法があるのかどうかはわからないけれど、容量が大きく、動作も遅くなりそうな感じ。



## 調べてみた

**参考サイト**

[Rubyを理解する！初心者でも分かるメリット・デメリット、基礎知識などを簡単に解説！](https://anken-hyouban.com/blog/2020/06/11/ruby/)

[Rubyとは？3つの特徴や学びやすい理由を解説！メリットとデメリットも紹介](https://web-camp.io/magazine/archives/55805)

どちらにも書いてあることですが、Rubyのメリットは「記述のしやすさ」「自由度の高さ」「Ruby on Railsとの相性の良さ」が挙げられるようです。そして、デメリットは「処理が遅い（インタープリタ言語）」ことと「自由度の高さがチーム開発で足枷になる場合がある」ことのようです。

メリットについては、大体思っていた通りです。デメリットについて少し考えてみました。 

### 処理の遅さ

やはり、Rubyは処理速度は少し遅いようです。その理由は、Rubyがコンパイラ言語ではなく、インタープリタ言語であることのよう。

**コンパイラ言語**
コンパイラ言語というのは、Javaのような言語で、プログラム記述後、動作をする前に一度機械語へコンパイルする作業を挟まないといけない言語。事前に機械語にコンパイル（翻訳）しているので、本番環境での動作が速い代わりに、開発中の動作テスト時にいちいちコンパイルをする必要があり、テンポが悪くなるようです。

**インタープリタ言語**
対して、Rubyが属するインタープリタ言語は、人間が記述したプログラムを実行時に1行ずつその場で機械語に訳して動作をするため、開発中の動作確認がスムーズに行えるかわり、本番環境でも1行ずつ訳しながら動作をするので、遅くなってしまうようです。

**疑問**
そこで思ったのですが、開発中はインタープリタ言語として動作して、開発後にコンパイルして、本番環境ではコンパイル言語として動作することがなぜできないのだろう？

いずれ、その理由がわかったらまた記事にしたいと思います。

### チーム開発時の自由度の高さの弊害

これについては、事前に規約を定めて開発をすればいいことのように思いますが、そもそも初めから自由度の低い言語を使う方が話が早い感じがします。



# Rubyの使い所

以上、調べてみて僕の持った感想としては、Rubyは個人開発用にはすごく良くて、チーム開発や大規模なシステム開発にはあまり向かないんじゃないかな？と思いました。 

### 個人開発に良いと思う理由

書いていて楽しく、自由度が高いのでいろいろ挑戦ができ、インタープリタ言語なので動作チェックのストレスが少なく、Ruby on Railsでいろんなことができてしまうからです。

Ruby on Railsが親切すぎて学習用には向かない（内部処理が理解できない）という意見もみましたが、そんなことは本人の学習意欲次第だと思います。「よくわからないけど動く」で満足できる人はそもそもそんなに深い学習のできるタイプの人ではないでしょうから。 

### チーム開発・大規模システムに向かないと思う理由

**自由度の高さ**

長期の運用を考えていかないといけない場合、自由度の高さは後々保守をする人の負担を大きくする可能性は大いにあると思います。そのための対策を多く打って、その内容を覚えないといけない、というのはやはりあまり望ましくない労力に思えます。

**処理速度の遅さ**
実際に有名な大規模サービスでRubyが使用されているようなのでそんなに影響がないのかもしれません。それでも、大きなサービスでは処理速度はかなり重要なんではないかな、と思います。速ければ速いほど多くのリクエストに応えられるでしょうし、負荷が小さければインフラコストを減らしたり、保守が楽になったり、いろいろな利点がありそうに思えます。あくまで素人考えですが。



# 結論

僕の中では、今後もRubyとRuby on Railsは趣味の開発の中で使い続けて行きたいと思います。いろいろな新しいことを試すのに挑戦がしやすいし、Ruby on Railsの内部の仕組みを勉強していくことは、プログラミングの経験を深めていく上で大きな助けになると思うからです。

なにより、Rubyは楽しい！

ただ、他にも魅力的な言語はたくさんあるので、もっといろんな言語に触れていけたらな、と思っています。
投稿した記事に不要な表示されるエラーの解決例

投稿した記事に不要な表示された場合
app/views/user/show.html.erbを確認します。

不要な表記で<%= %>が使用されているか確認します。

<%= %>は、post.nameなど出力したい処理で使用します。
<% %>は、if文など出力したくない処理で使用します。
【AWS】S3バケットへのアクションのロギング手段

#サマリ
S3バケットに対するアクションログの保存方法としてS3サーバーアクセスログ と CloudTrailログ の2種類があります。
基本的にCloudTrailの方が多機能ですが、一部のユースケースではS3サーバーアクセスログを使います。
それぞれの特徴を大まかに整理します。

#「S3バケットに対するアクション」とは？
ユーザー、ロール、またはその他AWSサービスによって実行されたAPIコールのこと。
いずれかの手段で記録可能。

##先におさえておくポイント
・「CloudTrailログ」の手段は単純にCloudTrailのログをS3に配信するというイメージなので「S3バケットの基本機能」が使える。なので多機能に見える。
・「S3サーバーアクセスログ」はS3の持つ1機能に過ぎないので、できることは限られている。
・実際にコンソールから確認してみるとわかりやすい。

#2種類のロギング手段
各手段の主要な特徴をメモします。
「→」で筆者コメント入れました。
網羅的な情報はマニュアルを参照ください。

##CloudTrailログ
・CloudWatch LogsやCloudWatch Eventsに転送可能
・ログを異なる複数の宛先に配信する
・異なるAWSアカウントが所有するバケットに配信可能
　→これは便利かな。ログ集約用アカウントに配信するとか。
・ログファイルの暗号化
・ログを検索できるUI
　→これはCloudTrailダッシュボードのことかな
・配信はデータイベントは5分ごと、管理イベントは15分ごと
・ログの形式はJSON
　→JSONの方が色々ハンドリングはしやすい？

##S3サーバーアクセスログ
・ログレコードのフィールド（Object Size, Total Time, Turn-Around Time, HTTP Referer）
　→「Object Size」とか見れるのは便利そう？
・認証の失敗をロギング
・ライフサイクル設定（移行、失効、リストア）
　→
・ログは数時間以内の配信
・スペースで区切られ、改行で分割されたレコードを持つログファイル

##共通事項
・S3 APIを使用可能（オブジェクト操作、バケット操作）

##コンソールで確認してみる
###S3サーバーアクセスログ
設定できるのは有効・無効のみ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254141/3072ab44-1fbf-4802-06f1-ae064e419115.png)

###CloudTrailログ
以下はCloudTrailの設定画面。
KMSによる暗号化やログファイルの検証設定を行えることがわかる。
これらに加えて、配信先のS3バケットでライフサイクルルール等を設定することももちろん可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254141/e7649af5-5536-e914-5681-3d0c22758846.png)


#参考
Amazon S3 でのログ記録
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/logging-with-S3.html

AWS CloudTrail を使用した Amazon S3 API コールのログ記録
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/cloudtrail-logging.html
【JavaScript】前置演算 と 後置演算【備忘録】

インクリメント演算子とデクリメント演算子の前置と後置の違いのメモ。
どちらの場合もオペランドの値を1加算/減算するが、代入時の挙動が微妙に異なる。
※単純に代入処理が先か加算/減算が先かの違い

# 前置演算
インクリメント/デクリメントを行なってから代入処理を行う。

```javascript
var x = 3;
var y = ++x;

console.log(x); // 4
console.log(y); // 4
```

# 後置演算
代入処理を行なってからインクリメント/デクリメントを行う。

```javascript
var x = 3;
var y = x++;

console.log(x); // 4
console.log(y); // 3
```
【Rails】find_or_create_by!を使ってみた

## 概要

- 参加させていただいている案件で、大変参考になった内容があったため、まとめました。

## 目的

- `rails db:seed`で新しいテストデータを追加した時、差分だけ登録できるようにしたい

## 問題

- `rails db:seed`で登録する時に、データが重複する部分でエラーが発生する
- エラーが発生しないようにするには、その都度データをリセットする必要がある（`rails db:migrate:reset`など）
- 個人であれば問題ないが、複数人で作業している場合、「他のメンバーが追加したテストデータ」を「削除コマンドなし」で導入できるようにしておきたい

## エラーが起こる原因

- seeds.rbに登録されているデータが全て登録されようとする
- 重複部分があるため、エラーが発生する

## 課題

- データが存在しない場合は作成
- データが存在する場合は、作成する処理を実行しないようにしたい

## 解決策

- `find_or_create_by!`を使用する

```
モデル.find_or_create_by(条件)

#=>条件に一致するデータがない =>　実行される（作成）
#=>条件に一致するデータがある　=> 実行されない（作成されない）

```
これで、データが存在する時、実行されることで発生するエラーは発生せず、差分だけ実行されます！

*before*

```ruby:seeds.rb
User.create!(
  email: "test@example.com"
  password: "password"
)

rails db:seed   #=>１回目はデータがないため作成される
rails db:seed   #=>２回目はデータがあるためエラーが発生する

```

*after*

```ruby:seeds.rb
User.find_or_create_by!(email: "test@example.com") do |user|
  user.email = "test@example.com"
  user.password = "password"
end

rails db:seed   #=>１回目はデータがないため作成される
rails db:seed   #=>２回目はデータがあるため、実行されない　=> エラーなし！
```


## まとめ

他の人の動作まで考えてプログラムを組める人って素晴らしいですね。どんどん使って行きます！

## 参考資料

- [Railsドキュメント](https://railsdoc.com/page/find_or_create_by)
M1 Macでターミナルをarm64とx86_64で別々にするといいよ！知らんけど。

## ターミナルの切替が面倒なんです。
M1 Mac mini買いました:smiley::bangbang:
すごく良いのですが、開発でターミナルを使う時に少し面倒なことがありました。
ターミナルは基本的にApple Silicon(以下arm64)で起動します。ただ全てのアプリやライブラリがarm64に対応しているわけではないので、Intel(以下x86_64)で使いたい時もあります。

この時、ターミナル.appの「情報を見る」->「Rosettaを使用して開く」にチェックしてから起動するとx86_64で起動します。

面倒くさくないですか:question::worried:
偉大な先達は、シェルで切り替える等々を実践されていますが、それもちょっとハードルが高く・・。

で、ターミナルをarm64とx86_64で分ければ良いのではと思い、試した結果上手くいったのでご報告します。

ただ邪道な感じはしますので、何か不具合があるかもしれません。
その点、ご留意ください・・。

でも今のところ私は快適に使えています:thumbsup:。

## 方法
1. 「Application」ディレクトリに移動する。

2. 「ユーティリティ」ディレクトリに移動する。

3. 「ターミナル.app」をコンテキストメニュー(またはcommand + D)で複製する。
![スクリーンショット 2021-02-14 7.52.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372519/eefdcab2-b175-7607-36fb-05e6e36dcb64.png)

4. 複製したターミナル.appの名称を変更(ここでは「ターミナル(Intel).app」に変更)。

5. 今回は、念の為別のフォルダを作成し、そこに複製した「ターミナル(Intel).app」を移動。

6. 複製した「ターミナル(Intel).app」の「情報を見る」からRosettaを使用して開く」を有効にする。
![スクリーンショット 2021-02-14 7.54.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372519/fcc4785c-fc2a-3b83-a52f-8b81e56fb2dc.png)
![スクリーンショット 2021-02-14 7.54.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372519/21566fe3-7681-c94b-ef9f-a9aaf8794932.png)

7.　あとは、それぞれをDockに登録しておくと任意のアーキテクトで起動できます。

えぇ、力技です:sweat_smile:。
分かりにくいですが、左のウィンドウが「arm64」で右のウィンドウが「x86_64」です。並べて起動しています。
![スクリーンショット 2021-02-14 7.57.51.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372519/43b90ad4-e7d4-e4d2-6ecd-6373fb88836b.jpeg)



ちなみに起動した時どちらのアーキテクトか分かりやすいようにzshでプロンプトを編集してアーキテクト名を赤い文字で出力しています。

　.zshrcに以下を設定しています。

```zsh:.zshrc

autoload -Uz colors
colors

if [[ "$(uname -m)" == "arm64" ]]; then
   PROMPT='%m %F{red}[ arm64 ]%f %# '
 else
   PROMPT='%m %F{red}[ x86_64 ]%f %# '
 fi

```

uname -mの結果を出力しているだけです。


####<font color="Red">ひとつ注意点として、ターミナル.appの設定ファイルは共通です。</font>
複製をアンインストールする時などにツールを使用した場合、元の設定まで初期化される恐れがあります。


いずれは、こんなことしなくても、全てarm64に対応すると思いますが、それまでの凌ぎに。
それでは、良いM1ライフを:smiley:

ありがとうございました。

追記
Sepi110902さんから、ご指摘いただきまして、全くそのとおりです:pray:。
記事を投稿した時に無精してしまって、すいません。
elseで分けたのは、ｘ86の時に黄色で出力させる運用をしています。
遅くなりましたが、ここで追記訂正いたします。

```zsh:.zshrc

autoload -Uz colors
colors

if [[ "$(uname -m)" == "arm64" ]]; then
   PROMPT='%m %F{red}[ arm64 ]%f %# '
 else
   PROMPT='%m %F{yellow}[ x86_64 ]%f %# '
 fi
```

コメントありがとうございました。
manimの作法 その50

#概要

manimの作法、調べてみた。
point_from_proportion使ってみた。

#サンプルコード

```
from manimlib.imports import *

class test(Scene):
	def construct(self):
		plane = ComplexPlane(unit_size = 2)
		plane.add_coordinates()
		self.add(plane)
		self.t_offset = 0
		dot = Dot()
		rate = 0.25
		orbit = Circle(radius = 2)
		def around_circle(mob, dt):
			self.t_offset += (dt * rate)
			mob.move_to(orbit.point_from_proportion(self.t_offset % 1))
		dot.add_updater(around_circle)
		self.add(dot)
		self.wait(5)



```

#生成した動画

https://www.youtube.com/watch?v=st4GZ929tI4

以上。
【JavaScript】undefined と nullの違い【備忘録】

# undefined
変数の値が定義されていないことを表す値。以下のケースで返却される。


1. 変数が宣言済みであるが、値を与えられていない時
1. 未定義のプロパティや配列の要素を参照しようとした時
1. 関数で値が返されなかった時

```javascript
// 1
var x;
console.log(x); // undefined

// 2
var obj = { text: "teststring" };
console.log(obj); // undefined

// 3
var y = console.log("test");
console.log(y); // undefined
```

# null
空の状態を表すための値。
関数の返却値として考えると、

- `undefined`は返す値が決まっていない・定義されていない時に未定義の意味で返す
- `null`は何か返すべきだけど、返すものがないため空値を返す

# 参照
https://qiita.com/shuhei/items/199281e07925d24059d5
Githubのwebブラウザ上で特定のファイルやフォルダをダウンロードする裏技

以下の記事を参考に、ダウンロードしたいファイルのあるリポジトリをwebアプリのvscodeで開きます。
[GitHubのURLをちょろっと書き換えるだけでコードを「Visual Studio Code」で閲覧できる素敵なサービスが話題に](https://forest.watch.impress.co.jp/docs/serial/yajiuma/1306113.html)
>ダウンロードしたいファイルのあるリポジトリを開き
>“github.com”というドメインを“github1s .com”に書き換えるだけ（“.com”の前に“1s”を挿入）

画面左のEXPLORERから、ダウンロードしたいファイルを右クリックして[Download...]をクリックします
複数ファイルを選択してダウンロードも出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411106/d1fe194e-5d50-0723-38b5-960466a891be.png)
numbaでpythonを高速化する

numbaを使うとpythonが速くなると聞いて使い方を確認してみました

numba公式
https://numba.pydata.org/

こっちを読んだ方が良い解説記事
https://qiita.com/gyu-don/items/9d223b007ca620e95abc

# 何故速くなるのか

LLVM IRでコンパイルしてネイティブコードとして実行することで速くするようです

LLVMについてはこちらの記事が分かりやすかったので貼っときます
https://qiita.com/Anko_9801/items/df4475fecbddd0d91ccc

# 2つのモード

no pythonモードとobjectモードがあり、no pythonの方が速くなります。pythonが遅い原因として型判定する事とインタプリタで逐次実行する事が挙げられるようですが、numbaのno pythonモードでは型を固定した上でコンパイルもするので最大限の高速化が得られるのに対し、objectモードでは型判定は残してコンパイルによる高速化のみを行うようです。

# 使い方

## 1. install

pipで入ります

```terminal:terminal
pip install numba
```

## 2. 遅い関数

適当な重い処理を書いてみます

```python:jupyter_notebook
%%time

def hoge():
    count = 0
    i = 0
    for k in range(10**9):
        i += 1
        if i >= 1000:
            count = 0
    return count

hoge()
```
```
Wall time: 1min 54s
```

遅いです

## 3. numba.jitを適用する

これをnumba.jitにより高速化してみます。jitとデコーレータを付ければ高速化してくれる筈です。

```python:jupyter_notebook
from numba import jit

@jit
def hoge():
    count = 0
    i = 0
    for k in range(10**9):
        i += 1
        if i >= 1000:
            count = 0
    return count

hoge()
```
```
Wall time: 63.5 ms
```

上記実行時間にはコンパイルする時間が含まれていますので、再度実行すると更に速くなります。

```python:jupyter_notebook
%time hoge()
```

```
Wall time: 0 ns
```

# 4. no pythonモードを指定する

現バージョンでモード指定を省略した場合は一度no pythonモードでコンパイルし、上手くいかなかったらobjectモードで再度コンパイルして実行するようです。objectモードを使ってほしくない場合はnopython=Trueにすることでモードを指定できます。

```python:jupyter_notebook
%%time

@jit(nopython=True)  # @njitと書くことも出来ます
def hoge():
    count = 0
    i = 0
    for k in range(10**9):
        i += 1
        if i >= 1000:
            count = 0
    return count

hoge()
```
```
Wall time: 65.7 ms
```

レッツトライ
[小ネタ]styled-componentsをTypeScriptで利用する

# 概要
styled-componentsをTypeScriptで利用する場合の記載方法について。


# シンプルな書き方
親が特定のreact componentでないときは、下記のようにシンプルに記述する。

```tsx
const Button = styled.button<{primary: boolean}>`
  color: ${({primary}) => primary ? 'skyblue' };
`
```

# 複雑な場合の書き方
親のpropsを参照する場合は、Pickを使う。

```typescript
interface Props {
  primary
  secondary
  // 略
}

function MyComponent(props: Props) {
  return (
    <div>
      <Button secondary={props.secondary} primary={props.primary}>{props.children}</Button>
    </div>
  )
}

const Button = styled.button<Pick<Props, 'primary' | 'secondary'>>`
  ${({primary, secondary}) => primary ? css`` : secondary ? css`` : css``}
`
```
VSCodeのSFTP拡張機能でLightsailにアップロードできないのはhtdocsがシンボリックリンクだから

複数サイトの開発をSublimeText3からVisualStudioCodeへと、乗り換え作業を1日くらいでしていました。するとこのAWSのLightsailのサイトだけ、SublimeではSFTP拡張機能で更新できるのに、VSCodeのSFTP拡張機能では更新できませんでした。

私はLightsailでLAMP環境(PHP)を選んでミニアプリを作っているのですが、このようにサイトのrootであり、接続先フォルダでもあるhtdocsがシンボリックリンクになっていました。
![スクリーンショット 2021-02-14 6.22.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31243/f1481c56-2ed3-c5d1-4d6b-7364217ff783.png)

sublimeText3のSFTP拡張機能ではこれでも動いていたわけですが、一応これが原因かなと思って、設定ファイルvscode/sftp.configのremotePathをシンボリックリンクである
```"remotePath": /home/bitnami/htdocs```
でなく、実パスの
```"remotePath": "/opt/bitnami/apache2/htdocs"```
にしたらアップロードもダウンロードもできました。

自分で設定していたらすぐ気づいたんですが、気軽に設定済環境を使えるLightsailということで気づくのが遅くなってしまいました。
Pythonスクリプトをexe化しよう

# 概要
exe化できれば、python環境インストールされていないPCでも動作させることができるよ。
今回は pyinstaller を使ってexe化しよう。


# 環境
- Windows 10 Pro / 20H2 build 19042.804
- python 3.8.7
- pip 21.0.1
- pyinstaller 4.2


# 前提条件
- python環境がインストールされていること
- pipがインストールされていること


# pyinstallerをインストール
コマンドプロンプトを開いて以下のコマンドを実行。

```batch
pip install pyinstaller
```


# pyinstallerでファイルをexe化
```batch
pyinstaller "pythonファイル名" [--onefile] [--noconsole]
```

オプション

- `--onefile（省略可）`
ファイルを1つにまとめてexeファイルを作成します。 

- `--noconsole（省略可）`
コンソール（コマンドプロンプト）の画面を表示しません。


# 実行結果
![実行結果.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85538/a5c6e5c3-0b49-547c-bd09-5d10d3259724.jpeg)
exe化を実行すると、上記のようにフォルダ等が作成されます。
**"dist"**フォルダの中にexeファイルがあります。
bash備忘録

一連のコマンドや、ジョブサブミット等で、`*.sh`を使う。何かとbashコマンドが使えるとやっぱり便利なのでbashの文法を勉強したところから順次まとめていく。

参考にさせていただいたサイト: [Bashの便利な構文だがよく忘れてしまうものの備忘録 - Qiita](https://qiita.com/Ping/items/57fd75465dfada76e633)

# やりたいことから
## コマンド`command`の標準出力を変数に代入する

```bash
val=`command`
```
で`command`の標準出力を変数`val`に代入できる。コマンドを囲んでいるのはバッククォート(日本語キーボードの場合はshift + @)。例えば

```bash
val=`ls ./`
echo ${val}
```
で、PWDで`ls`を実行した時の結果が`val`に代入されていることがわかる。

### 日付と時刻毎のファイルに出力を書き込む

```bash
NOW=`date +'%Y_%m_%d-%H'`   #変数NOWに YYYY_MM_DD-HH 形式の時間を変数NOWに代入
LOGFILE="$NOW.log"          #日付と時刻.logの文字列を変数LOGFILEに代入
ls ./> ${LOGFILE}　　　　　  #`ls`の出力を変数LOGFILEの名前のファイルに書き込む
```

## 文字列の結合
`valA="hoge"`と`valB="fugafuga"`を結合したい場合は

```bash
valC=${valA}${valB}
```
で出来る。

```bash
valC=${valA}${valB}
echo ${valC}
```
を実行すれば`hogefugafuga`が標準出力に表示されるはず。
firebaseのプロジェクトを新規で作ったらすぐに「デフォルトのGCPロケーション」を設定したほうがいい。まだやってない人もすぐにやろう

firebaseのプロジェクトを作ったらまずデフォルトのGCPロケーションを設定しましょう

理由は、**一度設定するとあとから変更できないからです**

https://firebase.google.com/docs/firestore/locations?hl=ja

> アプリで使用できる一部のサービスでは、プロジェクトのデフォルトの Google Cloud Platform（GCP）リソース ロケーションと呼ばれるロケーションを設定する必要があります。ロケーションを設定する必要がある GCP サービスのデータは、このロケーションに保存されます。
警告: 次のいずれかのサービスでロケーションを設定すると、他のサービスのロケーションも設定されます。プロジェクトのデフォルトの GCP リソース ロケーションをいったん設定すると、変更することはできません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48695/a945925a-2a09-07c0-77e0-0f1cdf2d8f66.png)



これが結構厄介で、たとえばなにかの要件の調査でちょっとfirestoreを試してみようとなったとき
**適当にus-centralで作ってしまうと、もう二度とそのプロジェクトではus-central以外の環境でfirestoreやstorage、GAEのインスタンスが作れなくなってしまうのです**

当たり前ですが、**日本(asia-northeast1)で作らないとめちゃくちゃPINGが遅いです**

DBとしてガンガン繋ぐことになるfirestoreではPINGの遅さは割と致命的です！！

ちょっと試してあとで環境ごと消せばいい！が通用しないのです


なのでまだ設定していない方は、忘れる前に真っ先に設定することをおすすめします

新規に（最初の一回だけ）cloud firestoreでデータベースを作成しようとすると、ロケーションを設定できるので、とりあえずすぐに設定することをおすすめします！！！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48695/8eeed336-9fbe-a25c-52dc-ec10ef82bbaa.png)

自分はGAEで遊んでいたら取り返しがつかなくなっておりました！！！
（未設定ならここでasia-northeastを設定できるはず）
アプリ開発実践入門3 Controllerとview 発展

今日の教科書

##ページ作成を発展させる

###リダイレクトとパラメータ送付
リダイレクト:別のアクションへの処理の転送
`redirect_to action: :アクション名 , params:[ハッシュ]`:
`action:`リダイレクト先のアクションを指定するオプション
他のコントローラのアクションに帰る際は`controller: コントローラ名`
`params:`で必要なパラメータを渡すことができる。
リダイレクトで新しいアクションを作ったら、ルーティングを忘れない。

###フォームの送信
####フォーム用にHTMLテンプレートを編集する。主に入力フィールドと送信ボタンを作る。
[<form> …… 入力・送信フォームを作る](http://www.htmq.com/html5/form.shtml)

```
1<form method="POST" action="送信先">
2  <input type="text" class="form-control"
3    name="input1" value="<%= @value %>">
4  <input type="submit" class="btn btn-primary">
5</form>
```

１で送信先に本文を送信する。2で入力のテキストボックスを作る。
3のnameでフォームの名前を作る。値をインスタンスに格納。。
4で送信ボタンを作成。
form-controlとbtn btn-primaryはBootstrapのクラス。フォームをデザインしてくれる。

####コントローラを修正する
フォームをそのまま対象のアクションにPOSTで送信している。
普通にそのアクションにアクセスした場合はGET。GETかPOSTかで処理を変える仕組みが必要。
`if request.post? then`:requestはブラウザからサーバーに送られた情報をまとめたオブジェクト。post?はポスト送信をしたか否かを判別するメソッド。つまりif文でPOSTか否かで処理を分けられる。

####ルーティングの追加設定
POSTによるアクセスを許可する。
`post `コントローラ名`, to: `コントローラ#アクション``
`post `コントローラ/アクション``

####InvalidAuthenticityTokenエラーとCSRF対策

railsのフォーム送信のセキュリティに引っかかる。
クラス下に`protect_from_forgery`で通過。

###フォームの送信2「フォームヘルパーを使おう」
ヘルパー：ビューで利用できるrailsの機能の一つ。
フォームヘルパーだとフォーム関係のタグを生成してくれる。

####フォームヘルパーをHTMLテンプレートに記述&CSRF対策の削除
`<%= form_tag(controller: "コントローラ名", action: "アクション") do %>`：
フォームの<form>タグを生成するためのメソッド。
`<%= text_field_tag("input1") %>`：テキストで入力フィールドのタグを作成する
`<%=submit_tag("Click") %>`：フォームを送信するボタンを生成する。引数はボタンに表示するテキスト。
`<% end %>`：中に＝を入れないタグで終わる。

####フォームヘルパーで属性の指定
`<%= text_field_tag( id , デフォルト値 , 属性の設定)%>`：属性を指定する基本の形。

```
<%= form_tag(controller: "hello", action: "index") do %>
  <%= text_field_tag("input1","", {class:"form-control"}) %>
  <%= submit_tag("Click", {class:"btn-primary"}) %>
<% end %>

```

###様々なフォームヘルパーメソッド

####チェックボックス

```
<%= check_box_tag("check1") %>
<%= label_tag("check1", "check box") %>
```

`check_box_tag(ID)`でチェックボックスを出力し、`label_tag(ID, 表示テキスト)`でラベルを設定する。

対応アクションの修正をしておく。

####ラジオボタン
`radio_button_tag(name値, value値)`：ラジオボタンを作成する、IDはnameとvalueが使われる。

```
<%= radio_button_tag("r1", "radio 1") %>
<%= label_tag("r1_radio]_1", "Radio Button 1") %><br>
<%= radio_button_tag("r1", "radio 2") %>
<%= label_tag("r1_radio]_2", "Radio Button 2") %><br>
```

半角スペースはアンダーバーになっている。対応アクションの修正をしておく。
<br>は改行の意味。

####選択リストを使う

`select_tag(ID値, 表示する項目)`：選択リストを表示する。
`options_for_select(配列)`：selectタグの中に記述するオプションタグを作る。
`select_tag(ID, options_for_select(配列))`:上二つの組み合わせ
配列を項目にもつ選択リストを作ることができる。

```
<%= select_tag('s1',
  options_for_select(["Windows", "macOS", "Linux"])) %>
```

対応アクションの設定しておく。

####複数選択可能なリスト

```
<%= select_tag('s1',
  options_for_select(["Windows", "macOS", "Linux"]),
  {size:5, multiple:true, class:"form-control"}) %>
```

{size:5, multiple:true, class: "form-control"}
`multiple`で複数選択が可能に、`size`で表示する項目数を変更できる、2つ以上だとプルダウンからリスト方式に。classはBootstrapのクラス。

要コントローラの修正。
複数項目選択の場合は、「選択した項目の配列」が値になる。配列なのでfor inを使って順に取り出して処理しなければいけない。


####他にもヘルパーは色々あるよ

 - テキストエリア
 - パスワード入力
 - 非表示フィールド
 - 検索フィールド
 - 電話番号入力
 - 日時の入力
 - URLの入力
 - メールアドレスの入力
 - 色の選択
 - 指定範囲の数値の入力

##気になった、わからなかったこと
 -
Go 言語仕様8（ポインタ）

## 概要
Go 言語の仕様まとめ。

前回：
[Go 言語仕様7（goroutine と channel）](https://qiita.com/R_R/items/e018c39a7f7632614f0b)

## 内容

- ポインタ

## ポインタ

ポインタとは、変数のアドレスのこと。
アドレスとは、変数が格納されるメモリ上の区分のこと。
ポインタを使い、変数のアドレスを参照することで、元の変数の値を更新できる。

ポインタを使う上で出てくるのが、値型と参照型。
値型はアドレスを参照しないため、呼び出し先の関数で値の更新をしても、呼び出し元の変数は更新されない。

```Go:値型
func Plus(i int) {
	i = i + 10
	fmt.Println(i) // 20
}

func main() {
	var num int = 10
	fmt.Println(num) // 10

	Plus(num)

	// Plus関数の変数iとはアドレスが異なるため、Plus関数内の計算結果は変数numに反映されない
	fmt.Println(num) // 10
}
```

ポインタ型の変数（アドレスを格納できる変数）を参照渡ししてみる。

```Go:参照渡し
func Plus(i int) {
	i = i + 10
	fmt.Println(i) // 20
	fmt.Println(&i)
}

func main() {
	var num int = 10
	fmt.Println(num) // 10

	// numのアドレス
	fmt.Println(&num)

	Plus(num)

	// Plus関数の変数iとはアドレスが異なるため、Plus関数内の計算結果は変数numに反映されない
	fmt.Println(num) // 10

	// ポインタ型の宣言
	var p *int
	// ポインタ型の変数には、アドレスが代入できる
	p = &num
	fmt.Println(p)
	// アドレスを経由して元の変数の値を参照する
	fmt.Println(*p)

	// 変数pを更新すれば、アドレスを経由して元の変数numも更新される
	*p = 999
	fmt.Println(*p) // 999
	fmt.Println(num) // 999
}
```

変数pでは変数numのアドレスを持っているため、変数pと変数numのアドレスは同じ。
つまり、同じ変数の値を見ている。

|変数  |アドレス  |値  |
|---|---|---|
|num  |アドレスA  |100  |
|p  |アドレスA  |アドレスA  |

　　

map, slice, channelなどは参照型に分類され、ポインタ型を使わないでも、デフォルトで参照渡しになる。

```Go:参照型
func Plus(s []int) {
	for i, v := range s {
		s[i] = v * 2
	}
}

func main() {
	sl := []int{10, 20, 30}
	Plus(sl)
	fmt.Println(sl) // [20 40 60]
}
```

## 次回
[Go 言語仕様9（構造体）](https://qiita.com/R_R/items/c85bed04e55edd0cc071)
Scrapyを使ったスクレイピングのメモ

[Scrapy](https://scrapy.org/)を使ったスクレイプのやり方と、その流れと、雑多なメモ


<!--more-->

## インストール~初期設定

pipでやるだけ。 startprojectをするとPROJECTNAMEのディレクトリができ、そのディレクトリ以下にいいかんじデータを揃えてくれる。

```
#インストール
$ pip install scrapy 

#プロジェクトの作成
scrapy startproject PROJECTNAME
```

## scrapy shellを使ったパーサーの確認

startprojectで作成されたディレクトリにspidersというディレクトリができているので、そこにクローラーを書いていく流れになる。
ただ、毎回spiderを起動してパーサーを書くってなるとリソースの無駄になるので、ある程度パーサーの動作確認だけをおしておきたくなる。そのときに使うのがscrapy shell

``` shell
$ scrapy shell 'https://www.yahoo.co.jp'

...log...

> response.css('a').getall()
```

上のように書くとヤフートップページのリンクがshellに表示される。

## よく使うセレクタ

```
# attribでタグのattributeを取得
response.css('a').attrib['href']

# textをつけるとタグのテキストを取得できるgetをつけないとオブジェクトになる
response.css('a::text').get()

# あるcssセレクタ全部を取得して、forで回す
# Sampleというclassがついたdivのaタグを取得する
for i in response.css('div.Sample'):
    yield {
        'title': i.css('a::text').get(),
    }
```

他にもXpathも使えるし、reを使った正規表現も使える。
[Selectors — Scrapy 2.4.1 documentation](https://docs.scrapy.org/en/latest/topics/selectors.html)

全部覚えるというかは必要に応じてドキュメント見る。

## spiderの作成

パーサー動作確認ができたら、spiderにしていく

```
import scrapy

class SampleSpider(scrapy.Spider):
    #ここに指定したnameをコマンドラインで指定する
    name="sample"

    def start_requests(self):
        urls = [
            'https://www.yahoo.co.jp/'
        ]
        for url in urls:
            #callbackに指定したメソッドがパーサーとして渡される
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        response.css('title::text').get()
            yield {
                'title': response.css('title::text').get()
            }
```

## spiderの起動方法

scrapyのコマンドで作成したspiderを呼ぶ

```
# -O を指定してファイルにアウトプットする
scrapy crawl sample -O sample.json
```

## コマンドライン引数をspiderに渡す

-a をつけると引数を指定できる
引数をspider側で取得する場合はgetattrを使う

```
#-a をつける複数ある場合は-aも複数つける
scrapy crawl sample -O sample.json -a id=test

#spiderの中身
class SampleSpider(scrapy.Spider):
    #ここに指定したnameをコマンドラインで指定する
    name="sample"

    def start_requests(self):
        #getattrでコマンドライン引数idを取得できる
        crawlid=getattr(self, 'id', None)
        urls = [
            'https://www.yahoo.co.jp/'
        ]
        for url in urls:
            #callbackに引数を指定したい場合、cb_kwargsをつかう
            yield scrapy.Request(url=url, callback=self.parse, cb_kwargs={'crawlid': crawlid})

    def parse(self, response):
        response.css('title::text').get()
            yield {
                'title': response.css('title::text').get()
            }
```

## setting.pyの設定

プロジェクトのディレクトリにあるsettings.pyを使うと、spiderの動作の設定ができる。

```
#UserAgentを設定する。
USER_AGENT  = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'

#CONCURRNET_REQUESTSでリクエストの並列数を指定する。デフォルト16
CONCURRENT_REQUESTS = 1

#1回のクロールの間隔を設定する
DOWNLOAD_DELAY = 5
```

クロール間隔は5に設定しても、scrapy内部で1~1.5倍にしてランダムにしてくれる。
あと、CONCURRENTの設定がデフォルトで16(!?)なので何も知らないで100リクエストとかやってしまうとDosになってしまうので注意が必要。

とりあえずこんな感じ。ドキュメントが充実しているので、ドキュメントのチュートリアルを読んでそこを基本に深堀りしていくとやりやすかった。

[Scrapy Tutorial — Scrapy 2.4.1 documentation](https://docs.scrapy.org/en/latest/intro/tutorial.html)
GraphQL on bitquery で conflux でのウォレットのトランザクションを得るメモ

主にマイニングや DeFi 取引の課税計算用に GraphQL on bitquery で conflux のトランザクションを抽出してみます.
(ethereum は eterscan などが REST などで API サービス提供しているが, conflux の場合は現状自前でノード立てるなりして RPC でクエリするしかなさそうでめんどい) 

もともとは Ethereum(geth?) で GraphQL 対応していたので, 基本 Ethereum のコピーである Conflux もつられて GraphQL 対応しているっぽい感じです.

取引量が多い場合は, GUI IDE では多量のアウトプットが出るためコマンドライン版を使うのがよさそうですが... CLI は提供されているかしらん. :thinking: 

## クエリ言語

系統だったドキュメントやチュートリアルは無いようなので,
サンプルや

https://bitquery.io/labs/graphql

の Docs にあるスキーマを調べて自前で試行錯誤してやるしかありません.

## Conflux

とりあえず自前アドレスの送金を調べる

```
query { 
  conflux {
    out: transfers(
      any: [{sender: {is: "xxxxxxx"}}, {receiver: {is: "xxxxxxx"}}]
    ) {
      transaction {
        hash
      }
      date { date }
      gasValue
      currency { symbol }
    }
  }
}
```

を実行すると,

```
{
  "conflux": {
    "out": [
      {
        "transaction": {
          "hash": "xxxxxxx"
        },
        "date": {
          "date": "xxxx-xx-xx"
        },
        "gasValue": 0.000002100000063488,
        "currency": {
          "symbol": "CFX"
        }
      },
```
という感じでいけました.
(エラーが出ていないがカラのときは, Display pane で `conflux` を選んでいるか確認しましょう)

`out:` アウトプットはどれにするか...? のようです.

any の sender, receiver でアドレスへの送受金を指定します.

`cfx:xxxxx` の新しいアドレス形式はサポートしていませんでした. 2021/02/13 時点では, 0x で始まるアドレスを指定する必要があります.

`transfers ( ... ) { }` の中括弧で, 出力するアイテムを指定します.
基本は `tag { value }` みたいな指定ですが, `gasValue` みたいにそれだけ指定というのもあります.

どの通貨(コイン)を取引したかは `currency { symbol }` で出力できます.

`amount` で取引量を出力できます.
`amount (in: USD)` でドル換算の値が出ますが, たとえば

```
amount
amount(in USD)
```

などとして複数出力はできませんでしたので, やるならそれぞれの出力 JSON をあとでマージ, となるでしょうか. ちなみに JPY は無かったのでいずれにせよ取得価額を計算するときは円建ての価額を求める必要があります.

## 注意点

流動性ペア(Liquidity Pair)を作る場合, 例えば CFX と cUSDT をペアにして流動性を提供する場合,

- CFX を送金
- cUSDT を送金
- MLP(Moonswap Liquidity Pair token)を得る

というトークン交換が 1 トランザクションで発生しますが, `transfers` ではそれぞれ 1 つの取引として出力(i.e. 3 つの出力)が得られます.

## 日付順, ブロック高順にソートする

options の asc(逆の場合は desc)で, どのフィールドをキーとしてソートするか指定します.

```
    out: transfers(
      options: {asc: "date.date"}
```

フィールドは, output で定義しておく必要があります(スキーマにはあるが, 定義(利用)していないフィールドに対してソートはできない).

日付の場合 output に `date { date }` として,
block height の場合は `block { height }` を output に追加します.
(この場合ソートの指定は `options: {asc: "block.height"}` となります)
 
## transaction

`transaction` で, `transfers` では扱えないトランザクションをリストアップすることができます.

例えば approve や, コントラクトの呼び出しなど.

センダーと送金先アドレスを取得するには

```
sender { address }
to { address }
```

を出力に記載します.

## dex での取引?

`dexTransfers` で, たとえば moonswap での取引の記録をより簡単に調べることができるかもしれません... が, アドレス単位で抽出できるかは不明です. 基本は取引全体(1 日の取引量とか)を調べる用っぽいです.


とりあえずは `transfers` での取引をベースに処理するのがよさそうです.

## internal transaction

一部 reward(割引?)みたいな取引が取得できませんでした.

100 CFX を cMOON に変えたら 1 CFX が付与されていたみたいな.

confluxscan で見ると internal transaction として処理されていました. 

したがって internal transaction も取得してチェックする必要があります.

## TODO

日付指定で特定の日にちでの取引も抽出できるので調べる

Conflux の JSON-RPC と組み合わせる.

https://conflux-chain.github.io/conflux-doc/json-rpc


hash だけ GraphQL で抜き出して, 詳細は JSON-RPC でクエリなど.
(address からトランザクション一覧など抜き出しは JSON-RPC ではコマンドがないっぽいため)

endpoint はこちら.

https://main.confluxrpc.org/

* [ ] internal transaction も考慮する
backgroundにfixdとcoverを当てるとレスポンシブ対応がうまくいかない

またまたメンターさんに解決していただいた案件です。

背景だけが思うように表示されない？なぜ？
Cromeの検証ツールだと上手にできてるはずなのに！！！
原因がわからず、precompile何回もし直したり、
puma再起動とか、スマホのキャッシュ消したりSafariとかCromemとか色々試してみたけどどうしてもそこだけ変わらなかった。。

解決策としてはこう記述していたところを

```css:
@media screen and (max-width: 768px) {
  body {
  background-image: image-url("back.jpg");
  background-attachment: fixed;
  background-size: cover;
 }
}
```

↓こう変更しました。


```css:
@media screen and (max-width: 768px) {
    body::before {
    background: image-url('back.jpg') no-repeat left top;
    background-size: 100% auto;
    display: block;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    padding-bottom: 108px;
    content: "";
    z-index: -1;
  } 
}  
```

でうまくいいきました。
文系の非エンジニアがiPadだけでpythonと機械学習の勉強をする①環境構築編

# はじめに
このご時世で「新規事業」といったものに関わってくると、必ず「AI」に取り組むことになります。

３年ほど手探りでやってきましたが、エンジニアが話していることを理解するためにはきちんと勉強する必要があると思い、G検定を学習しました。

G検定の学習を始めてみると、資格の取得程度では到底語れない世界があることを思い知り、コードに手を出してみます。
（ただしお金のかからない範囲で）

#準備するもの
- iPad
- Microsoftアカウント
 
#勉強する人のスペック
- G検定合格（2020.3）
- コードは10年以上書いてない
- VB6.0,PL/SQL,COBOL
- 大学時代は作者の気持ちを考えていました

# Azure Notebookとは？
pythonエンジニアは大抵、jupyter notebookという環境で色々開発などをしています。
Azure Notebookは、MicroSoftアカウントがあれば、誰でも無料でAzure上でjupyter notebookを使ってpythonなどの機械学習の勉強ができます。
「勉強してみたいけど環境に投資するのは・・・」という人におすすめです

#手順
##AzureNotebookにサインインする
Microsoftアカウントがあれば特に問題はありません。
普通にサインインしましょう

##プロジェクトを作成する
サインインすると、[My Projects]というリストが表示されます。
ここから[New Project]を選択して、プロジェクトを作成しましょう。
名前はなんでもいいです。

##プロジェクトを開く
プロジェクトを開くと、ノートの一覧が表示されます。
まだ何もないので、[+]から[Notebook]を選択してノートを作成します。

ノートの名前と言語を選択するダイアログが表示されるので、適当な名前をつけて、言語を選択しましょう。
ここではPython3.6を選択します。

##ノートを編集する
ノートの一覧に作成したノートが表示されるので、選択してノートの編集画面に移行します。
枠で囲まれた入力領域が一つだけ表示されています。
ここが、コード等を編集するエリアです。

##コードを書いてみる
上部にあるリストボックスには
− Code
- Markdown
- Raw NBConvert
- Heading
という選択肢があります。
まだ初心者なのでよくわからないですが、Codeはコードを書く、Markdownは、コメントセクションなどに使うのでしょうね。
後の2つは名前をみただけでは分かりませんが、おいおい調べていきましょう。

とりあえず、Codeを選択して、編集エリアをコード用の領域にします。
コードは好きなものを書きましょう。

と言っても、実はpythonがまだわからないので、とりあえず例のアレを書きます。

    print("Hellow")

まずは操作方法の確認なので、この程度でよしとします。
もっと高度な物を書きたいならどこかからコピペしてきてもいいと思いますし、自分で書ける人ならそもそもこんなところみていませんね。

# コードを実行する
コードがかけたら実行します。
上部の[Run]を押すと、コードが実行されて出力されます。

    print("Hellow")
    Hellow

これでひとまずコードを書いて、実行することができました。

# ここまでのまとめ
今回はAzure Notebookを使って
- Projectの作成
- Notebookの作成
- コードの編集と実行
の方法を確認しました。

次回からはこの環境を使って、pythonを使ったデータ処理を学んで行きたいと思います。

# 2021.2.13 追記
下書きのまま保存しているうちに、AzureNotebookは提供終了してしまったようです。
この記事を書いたあとに受講したe-learningでは、Google colaborateを使って研修を受けたので、次回はGoogle colaborateの環境構築を見ていきます。
6日目（2/2個）ボタンを押すと音声を再生

#6日目のアプリ 2個目
トリガーをボタンにした音声再生

##画面キャプチャ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/959530/f0bc9f20-92b6-ffac-7f3c-b61696699fab.gif" width=50%>

##以下の流れで作りました。
1. storyboadに2つのボタンを配置。
2. 上記要素をViewController.swiftへoptionドラッグして紐付ける
4. 紐付けができたら、ViewController.swiftでコードを書く

##できたこと
+ 音声ファイルの再生方法がわかった。
+ 音声プレイヤーはいくつかあるらしい、その他諸々の方法がある。
##書いたコードを共有します！

```

import UIKit
import AVFoundation //オーディオ操作を扱う場合はこれがいる。インポート。

var player: AVAudioPlayer! //変数にプレイヤーを入れる

class ViewController: UIViewController, AVAudioPlayerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func buttonTappedToPlay(_ sender: Any) {
//        音声を読み込む
        let url = URL(fileURLWithPath: Bundle.main.bundlePath).appendingPathComponent("menuettm.mp3")
        do {
            player = try AVAudioPlayer(contentsOf: url)
            player.delegate = self
            player.play()
        } catch {
            print ("Error")
        }
    }
    
    @IBAction func toStop(_ sender: Any) {
        player.stop()
    }
    
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        print("finish")
    }
    
}
```

##感想
6日目２個目。制御したい場合はdeligateだよ。
デプロイ後、自分のスマホで見れない画面がある時

他の人からはみれるけど、
Editページだけがスマホ(iphone7,iphone11)から開けない現象が起きていました。
どうしても自分では解決できなかったのでメンターさんに解決してもらいました。

![iOS の画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942060/c9c87d2f-ed35-549a-c857-610b027d1ace.png)

スマホからのエラー画面はこんな感じ。

聞く話によると、
iOS14からセキュリティが厳しくなった？
(メンターさんはturbolinksがどーのとか言ってました)
とかで開けなかったっぽいです。


解決策はそのページのリンク場所に

```
<%= link_to "Edit Profile", edit_user_path(current_user), data: {"turbolinks"=>false}  %>
```


って感じで、

```
data: {"turbolinks"=>false}
```

この部分を足したらすぐ解決しました。

メンターさんによると、
これでハマってる人は多いらしいとのことでした。。
DockerでUbuntuをベースにnodejsをインストールするときに困った話

# はじめに
DockerでUbuntuのミニマム環境を作っているときに、Node.jsのインストールに戸惑ったのでメモ書きとして残します。

# 何で困るか
apt-getを使ってインストールするとき、タイムゾーンがわからないので設定しろインタラクティブに聞いてきます。Dockerでコンテナを作るときはインタラクティブにされても困るのでどうしようってなります。

# 解決策
tzdataというのをインストールすればタイムゾーンがわからないということが起きません！
よってtzdateをインストールしましょう。

具体的には次のようにDockerfileを編集すればよさそうです。

```Docker:Dockerfile
FROM ubuntu

RUN apt-get update && \
    apt-get install tzdate -y
RUN apt-get install -y nodejs
```

# おわりに
改善があれば追記します。
【Raspberry Pi 4】コンテナ環境構築 ~podmanを添えて~

自宅サーバ(Raspberry Pi 4 Model B)をコンテナ化して綺麗にしよう
ということで、コンテナを導入します。

OSはDebianベースの"Raspberry Pi OS"となります。

#1 podmanのインストール(Debian編)
単純に"apt-get install podman"で済めばよいのですが、そうは問屋が卸しません。
何はともあれ公式ページを開きDebianでのインストール方法を参考にします。
URL: [Podman Installation Instructions](https://podman.io/getting-started/installation)

podmanをインストールするには"libseccomp2"パッケージが必要なようです。
"libseccomp2"を入手するために、aptのソースリストに"buster-backports"の追加を行います。

公式手順ではechoによる書き込みを行っていますが、私はviでファイル作成と記述を行いました。

```bash:Step.1
#Step.1-1
vi /etc/sysctl.d/00-local-userns.conf
#一文を追加 → kernel.unprivileged_userns_clone=1

#Step.1-2
systemctl restart procps

#Step.1-3
vi /etc/apt/sources.list 
#一文を追加 → deb http://deb.debian.org/debian buster-backports main

#Step.1-4
vi /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
#一文を追加 → deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_10/ /

#Step.1-5
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_10/Release.key | sudo apt-key add -
```


これでapt-getの準備は整ったので、"libseccomp2"パッケージをインストールします。

```bash:Step.2
#Step.2-1
sudo apt-get update

#Step.2-2
sudo apt-get -y -t buster-backports install libseccomp2

#Step.2-3
sudo apt-get -y install podman

#Step.2-4 ※再起動が発生しますのでご注意
systemctl --user restart dbus
```

インストールされたことが確認できたら完了です。

```bash:Step.3
#Step.3-1
apt list --installed podman
```

コンテナの作成については、用途別になるので記事を分けます。
予定しているのはWordpress（Webサーバ）とNextcloud(ファイルサーバ)です。

お疲れさまでした。
多次元配列から特定の値を取り出す方法

routeが'love'の配列のnameの値を取得したいとする。

```php
$genres = [
  ['route' => 'jobs', 'name' => '仕事'],
  ['route' => 'life', 'name' => '日常'],
  ['route' => 'relationship', 'name' => '人間関係'],
  ['route' => 'dozi', 'name' => 'どじ'],
  ['route' => 'shame', 'name' => '恥'],
  ['route' => 'school', 'name' => '学校'],
  ['route' => 'love', 'name' => '恋愛'],  // ここのnameの値を取得したい！
  ['route' => 'marriage', 'name' => '結婚生活'],
  ['route' => 'game', 'name' => 'ゲーム'],
  ['route' => 'disease', 'name' => '病気'],
  ['route' => 'heart', 'name' => '心'],
];

// まず'route'の値だけの配列を作成する。
$genreRoutes = array_column($genres, 'route');
// 結果 $genreRoutes = ['jobs', 'life', 'relationship', .....];

// $genreRouteにおける'love'のインデックスを取得する。
$index = array_search('love', $genreRoutes);
// 結果 $index = 6;

// これで取得できる。
$genre_name = $genres[$index]['name'];
//結果 $genre_name = '恋愛';
```

全部繋げて書くと、

```php
$genre_name = $genres[array_search('love', array_column($genres, 'route'))]['name'];
// 結果 $genre_name = '恋愛';
```

これ以外に方法ってあるんですかね。。
もしもっとシンプルな方法を知っている方がいましたらコメントお願いします。
AWKでprint $0 時にOFSの設定を反映する（区切り文字の指定）

# 何をしたいか
awkで、一行全体の表示`print $0`時に、出力ファイル区切り文字`OFS`を指定しても機能しない現象を何とかしたい。

#状況
テーブルの区切り文字を変換して出力したい、処理結果をカンマ区切りで出力したい…等

例）こんなCSVを用意する。これをタブ区切りに変換して出力したいとする。

```bash
$ cat test.csv
a,b,c,d,e,f
1,32,6543,45,4,45
2,45,521,343,1,211
3,32,321,641,-2,377
4,45,56,939,-5,543
5,32,532,1237,-8,709
6,45,7,1535,-11,875
```

## 現象

```bash
$ gawk 'BEGIN {FS=","; OFS="\t";} {print $0}'
a,b,c,d,e,f
1,32,6543,45,4,45
2,45,521,343,1,211
3,32,321,641,-2,377
4,45,56,939,-5,543
5,32,532,1237,-8,709
6,45,7,1535,-11,875 # 区切り文字が変わっていない！
```

## 対処

`$`つき変数に対して何らかの適当な代入処理を行う。`$1=$1;` 程度の簡単なものでよい。

```bash
$ gawk 'BEGIN {FS=","; OFS="\t";} {$1=$1; print $0}'
a       b       c       d       e       f
1       32      6543    45      4       45
2       45      521     343     1       211
3       32      321     641     -2      377
4       45      56      939     -5      543
5       32      532     1237    -8      709
6       45      7       1535    -11     875 # タブ区切りが反映された
```

# 原因

ここまで書いて同一内容の先行記事を見つけた。

* [kakenmanの日記 - awkで$0出力するときにOFS指定が無視られる問題]
(https://kakenman.hatenadiary.org/entry/20110317/1300381670)

これでは差分がないので、少し原因を調べてみることにする。

## 調査結果

* フィールド`$0`の再構成タイミングはいつか、という問題に尽きる。

[The GAWK Manual Edition 0.15](http://www.kt.rim.or.jp/~kbk/gawk/gawk_toc.html) より
[入力ファイルの読み込み >  フィールド分割の指定](http://www.kt.rim.or.jp/%7Ekbk/gawk/gawk_5.html#SEC26) の節に、ほとんど回答になっている以下の記述がある。

> 先頭や末尾にある連続した空白をはぎとるという動作は、$0が再計算されたときには常におこなわれる。したがって、
>
>echo '&nbsp;&nbsp;&nbsp;a b c d' | awk '{ print; \$2 = $2; print }'
>
>このパイプラインは次のような結果となる。
>
>&nbsp;&nbsp;&nbsp;a b c d
>a b c d
>
>**最初のprint文は読んだままのレコードを、行頭の空白を含んだ形で出力する。 \$2に対する代入で\$0 は\$1 から\$NFまでをOFSを 区切りとして連結した結果に再構成される。**

なお、慣れていない人向けに書くと、単に`print` と書くのは`print $0` の省略形である。

つまり、（明確に記述されているわけではないが）単純に`print $0`を実行するだけでは`$0`は再構成されないことが推察される。再構成されない限り`OFS`は反映されず、元の文字列がそのまま出力されることになるというわけである。

フィールド代入の結果元のデータを変更せず、かつ`$0`の再構成を誘発し、最も短く書ける文が`$1=$1;`というわけだ。

ちなみに、`$0=$0;`は再構成を発生させないので、今回の問題の解決には効果がない（試されたし）。

# 執筆理由
久しぶりにawkを使ってトラブった。基本的な内容だが、意外に日本語記事が少なかったため。
WindowsでもWSLが使えるようになって、シェルのツールがかえって便利になってきつつあるので、こういった温故知新ツールの出番が増えるかもしれませんね。
6日目（1/2個）：ボタンを押すと画像が動くようにする

#6日目のアプリ
トリガーがボタンの画像アニメーション

##画面キャプチャ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/959530/df77361a-bc8c-cd6a-ef48-464a192b7391.gif" width=50%>


##以下の流れで作りました。
1. storyboadに1つのUIImageViewと1つのボタンを配置（パンダは自作）
2. 上記要素をViewController.swiftへoptionドラッグして紐付ける
4. 紐付けができたら、ViewController.swiftでコードを書く

##できたこと
+ 画像の移動方法がわかった。
+ 移動と、拡大縮小、その他諸々の方法がある。
##書いたコードを共有します！

```

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var Panda: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func buttonTapped(_ sender: Any) {
        UIView.animate(withDuration: 1.0, animations: {
            self.Panda.transform = CGAffineTransform(translationX: 0, y: -1000)
        }) { (_) in
            UIView.animate(withDuration: 1.0, animations: {
                self.Panda.transform = CGAffineTransform.identity
            })
        }
    }

}
```

##感想
6日目。パンダが思いのほかうまくかけた。
CORSの流れを理解したい

# CORSってまずなんて読むん？
読み方: コルス or シーオーアールエス
Cross-Origin Resource Sharing の略、日本語訳すると**「オリジン間リソース共有」**。
そしてこのOrizin「オリジン」のとは、
**プロトコル＋ドメイン＋ポートナンバー**のこと。イメージはURL

- ドメイン (domain): yahoo.co.jp
- オリジン (origin): https://yahoo.co.jp:443

# CORSって詳しく言うと？

CORS は日本語訳すると オリジン間リソース共有 でした。つまり CORS とは、あるオリジンで動いている Web アプリケーションに対して、別のオリジンのサーバーアクセス
をオリジン間リクエストによって許可できるHTTPの仕組みのことを言います。

下記図でいうと、domain-a.comで取得したWebドキュメントが、
domain-b.comのサーバーへアクセスする部分の仕組み

![20210213_CORS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087366/ddb8ebe6-a9fd-536a-bcd9-d10a22f0578d.png)

# CORSの実際の動きやルール
CORSがどのように動作するか、3パターン示します。これらの例はすべて XMLHttpRequest を用いており、対応しているブラウザーにおいて、サイトをまたいでアクセスすることができます。

## 単純リクエスト
一定条件を満たすリクエストはシンプルなリクエストで完結します。
![20210213_CORS単純リクエスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087366/f06ea40e-3f8f-e917-2ab2-efd48ea56e53.png)

## プリフライトリクエスト
「プリフライト」リクエストは始めに OPTIONS メソッドによる HTTP リクエストを他のドメインにあるリソースに向けて送り、実際のリクエストを送信しても安全かどうかを確かめます。サイト間リクエストがユーザーデータに影響を与える可能性があるような場合に、このようにプリフライトを行います。
![20210213_CORSプリフライトリクエスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087366/2a0d567d-3db0-2025-a28a-0fba202a3c31.png)

# 参考

- [なんとなく CORS がわかる...はもう終わりにする。](https://qiita.com/att55/items/2154a8aad8bf1409db2b#%E5%85%B7%E4%BD%93%E7%9A%84%E3%81%AA%E5%AE%9F%E8%A3%85)
- [MDN_オリジン間リソース共有 (CORS)](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)
workbench開けない時の対処法

## 前提
1. workbenchのダウンロード
2. インストール
3. その後立ち上げると開かない


## 対処法
### 1. バージョンを少し下げてインストールする
https://downloads.mysql.com/archives/workbench/
### 2. macの設定から、アプリのセキュリティを一時解除する。
![スクリーンショット 2021-02-14 1.22.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712534/32cb5404-6538-04c4-ec11-a4c3d1c89ac8.png)