OmniAICreator/Qiita-1.07M huggingface dataset:
[備忘録] Dockerで、composer install が Killed になる。

備忘録です。

## やりたいこと
- Dockerコンテナ内で、PHPのライブラリの依存管理ツール composer をインストールしたい。

## 状況
- composer installコマンドを実行したところ、Killed になる。

```:dockerコンテナ内
/app # composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
Killed
```
- 以下コマンドを実行しても、同様。

```
/app # composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Killed
```

## 解決方法

- メモリ不足が原因のようでした。

- 以下記事を参考に進める。（記事に感謝）

[Docker内でcomposer require したらkilledになったときの対応 - Qiita](https://qiita.com/makies/items/3e1064f17a18df750cad)


- 編集：docker/php/php.ini

```
memory_limit = 2048M
```

- Docker Dashboard上で、Resourcesを変更する

    Memory:2.00GB→8.00GB、Swap:2GB→4GB

![_2021-04-03_17.20.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527226/77b4d7b0-d533-d49d-83d0-c79261b73bc6.png)


- インストールする。（殺されなかった！）

```
/app # composer install
...
Package manifest generated successfully.
64 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
```

- インストール完了後、元に戻しておいた。
    - Memory:2.00GB、Swap:2GB



### 以下参考（解決に至るまでに参考にさせていただいた記事）

- 検索したところ、メモリ不足が原因か。

[[PHP] composer install が killed で失敗するときの原因と対処](https://webbibouroku.com/Blog/Article/composer-killed)

```
# dd if=/dev/zero of=/var/swap bs=1M count=1024
# mkswap /var/swap
# swapon /var/swap
```

- 実行したところ、変わらずエラー

```
/app # dd if=/dev/zero of=/var/swap bs=1M count=1024
1024+0 records in
1024+0 records out

/app # mkswap /var/swap
Setting up swapspace version 1, size = 1073737728 bytes
UUID=78e35732-6a85-47ab-b697-bf1c62c0994b

/app # swapon /var/swap
swapon: /var/swap: Operation not permitted

/app # composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
Killed
```

- 作成したスワップファイルのパーミッションが原因です。パーミッションを書き換えればOK、とのことで試してみる。（変わらずエラー）

[[Linux] スワップ領域の追加、割り当て方法](https://webbibouroku.com/Blog/Article/linux-swap)

```
/app # chmod 600 /var/swap

/app # swapon /var/swap
swapon: /var/swap: Operation not permitted

/app # composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
Killed
```
つぶやきSSO

# SSOとは

* Single Sign-On の略で、一度ユーザ認証をするだけで関連するサーバへのアクセスについても認証する技術です。
* ユーザの利便性の向上が期待できます。

# SSOの実装方式

## Cookie型

* 認証情報を含めたCookie情報を使ってSSOを行います。

## リバースプロキシ型

* リバースプロキシにアクセスを集約します。
* リバースプロキシで認証に成功すると、プロキシはサーバに代理アクセスし、結果をユーザに返します。

## SAML(Security Assertion Markup Language)型

* 認証情報に加え、属性情報とアクセス制御情報を異なるドメインに伝達します。
* 同一ドメインに留まらない大規模なサイトにおいてもSSOの仕組みを導入できます。

### SAMLコードの例

[こちら](https://techinfoofmicrosofttech.osscons.jp/index.php?SAML%E3%81%AE%E4%BB%95%E6%A7%98%E3%82%92%E8%AA%AD%E3%82%80%E3%80%82#z682ff17)からお借りしました。

``` xml
 1: <saml:Assertion
 2:   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
 3:   Version="2.0" IssueInstant="2005-01-31T12:00:00Z">

 4:   <saml:Issuer Format=urn:oasis:names:SAML:2.0:nameid-format:entity>
 5:     http://idp.example.org
 6:   </saml:Issuer>

 7:   <saml:Subject> 
 8:     <saml:NameID
 9:       Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">
10:       j.doe@example.com
11:     </saml:NameID>
12:   </saml:Subject>

13:   <saml:Conditions
14:     NotBefore="2005-01-31T12:00:00Z"
15:     NotOnOrAfter="2005-01-31T12:10:00Z">
16:   </saml:Conditions>

17:   <saml:AuthnStatement
18:     AuthnInstant="2005-01-31T12:00:00Z" SessionIndex="67775277772">

19:     <saml:AuthnContext>
20:       <saml:AuthnContextClassRef>
21:         urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
22:       </saml:AuthnContextClassRef>
23:     </saml:AuthnContext>

24:   </saml:AuthnStatement>
25: </saml:Assertion>
```
【小ネタ】AudioTrackにボリュームを流し込む方法

AudioTrackにボリュームを流し込むコードを備忘でメモしておきます

```cs:SetupVolume()の一部
            // タイムライン内のトラック一覧を取得
            var timelineAsset = _director.playableAsset as TimelineAsset;
            if ( timelineAsset == null )
            {
                return;
            }
            
            var tracks = timelineAsset.GetOutputTracks();

            //俺々サウンドマネージャからBGMボリュームを取得
            var bgmVolume = SoundManager.instance.GetVolume(AudioType.Bgm);

            //ボリュームの流し込み
            var audioTrackAsset = tracks.FirstOrDefault(x => x.name == "Audio Track");
            var audioTrack = audioTrackAsset as AudioTrack;
            audioTrack.CreateCurves("nameOfAnimationClip");
            audioTrack.curves.SetCurve(string.Empty,
                typeof(AudioTrack),
                "volume",
                AnimationCurve.Linear(bgmVolume,bgmVolume,bgmVolume,bgmVolume));
            _director.RebuildGraph();
```
_directorがPlayableDirectorで、音量値はSoundManagerシングルトンから取得しているコードです
TwitterのMedeia Studioについて

# Twitterの仕様が変わった

今年の4/1から色々と変わった

+ Androidユーザー向けにもSpacesが実装される
+ Periscopeは廃止，代わりにTwitter Media Studioが実装




## Spacesについて
スルーします，スマホからじゃないと参加できない媒体とか個人的にちょっと信用できないし手を出す気にはなれないので




## Periscopeはどうなった？

現状で以下のように確認できた

+ 新規ユーザーの登録は全て不可能

+ 登録済ユーザーのログインについて
    + iOSアプリは不可能
        + 4/1以前にログイン済ならセーフ，ただし再ログインは不可能
        + ログイン済ならスマホからの放送も可能
        + 過去の自分の放送も閲覧可能，削除は可能
    + ブラウザは可能
        + OBSなどから接続して配信する事は不可能
        + 過去の自分の放送も閲覧可能，ただし削除は不可能（元からできないんだけど）

+ 過去の放送について
    + Periscopeで配信されたものはPeriscopeドメインとTwitterドメインの双方で見れる
        + 過去の放送だけ「Periscopeで視聴」が可能になる
        + 逆にProducer（後述）から配信した放送は「Periscopeで視聴」を押しても読み込まれない
    + iOSアプリからログアウトした場合，現時点では「ブラウザからログインしてアカウントを消す」意外に過去の放送を消す手段は存在しない
        + Twitter Media Studio（後述）にも放送があったことは表示されるが一切の編集できない
        + その場合，放送ソースには「Periscope」と表示される，別のサーバーからリダイレクトされてるっぽい




## Twitter Media Studioについて

+ 「もっと見る」=>「Media Studio」で別ページが新規タブで開く
    + 「ライブラリ」はツイートしたメディア
    +「Producer」はPeriscopeを含む全てのライブ放送
    + 「インサイト」はメディアに関連するアカウントアクティヴィティ
    + 「予約投稿ツイート」は全ての予約ツイート
    + 「アナリティクス」はアカウントの全てのアナリティクス（別ページが新規タブで開く）


+ ProducerがPeriscopeの代わりに該当する，これが本題




# Producerのやりかた

+ 「ライブ放送を作成」
+ 放送名，カテゴリ，ソースを設定
    + ソースは配信ソフトから繋げる宛先
    + URLとストリームキーがある
+ 「ライブ放送を作成」


## その他の設定

### オーディエンス
公開範囲のこと

### 予約設定
放送の開始時間と終了時間を指定できる
要するに切り忘れ系の放送事故が起こりにくい

### 繰り返し
定期配信向け昨日．毎週か毎日かで設定可能

### ポスター画像
サムネのこと

### Periscopeの設定
チャットを全画面モードで表示…
現状ではProducerからの放送にはPeriscopeでの接続は不可能
よってチャットはできない，つまり完全な死に機能，乙

### ストリームの暗号化
いらないと思う

### リプレイの制限
切り抜き対策かな？

### 地域の制限
中○人●共◉国に喧嘩を売る時くらいにしか使わないのでは？


## 補足
Periscopeのアカウントのライブ履歴の場所にもProducerで配信中のライブは表示されないので，コメントやチャットは完全にできないと考えた方がいい
Periscopeは現状ではただのアーカイブセットになっている



# 結論
コメント機能なくした運営には失望した，はい
VBAでListを扱う

```List.cls
Option Explicit
Private liHead As ListItem

Public Sub Add(varValue As Variant)
    Dim liNew As ListItem
    Dim liCurrent As ListItem
    Dim liPrevious As ListItem
        
    Set liNew = New ListItem
    liNew.Value = varValue
    
    Call Search(varValue, liCurrent, liPrevious)
    
    If Not liPrevious Is Nothing Then
        Set liNew.NextItem = liPrevious.NextItem
        Set liPrevious.NextItem = liNew
    Else
        Set liNew.NextItem = liHead
        Set liHead = liNew
    End If
End Sub

Private Function Search(ByVal varItem As Variant, _
 ByRef liCurrent As ListItem, ByRef liPrevious As ListItem) As Boolean
    Dim blnFound As Boolean
    
    blnFound = False
    
    Set liPrevious = Nothing
    Set liCurrent = liHead
    
    Do Until liCurrent Is Nothing
        With liCurrent
            If varItem > .Value Then
                Set liPrevious = liCurrent
                Set liCurrent = .NextItem
            Else
                Exit Do
            End If
        End With
    Loop
    
    If Not liCurrent Is Nothing Then
        blnFound = (liCurrent.Value = varItem)
    End If
    Search = blnFound
End Function

Public Function Delete(varItem As Variant) As Boolean
    Dim liCurrent As ListItem
    Dim liPrevious As ListItem
    Dim blnFound As Boolean
        
    blnFound = Search(varItem, liCurrent, liPrevious)
    If blnFound Then
        If liPrevious Is Nothing Then
            Set liHead = liHead.NextItem
        Else
            Set liPrevious.NextItem = liCurrent.NextItem
        End If
    End If
    Delete = blnFound
End Function

Public Sub DebugList()
    Dim liCurrent As ListItem
        
    Set liCurrent = liHead
    Do Until liCurrent Is Nothing
        Debug.Print liCurrent.Value
        Set liCurrent = liCurrent.NextItem
    Loop
End Sub
```

```ListItem.cls
Option Explicit

Public Value As Variant
Public NextItem As ListItem

Private Sub Class_Initialize()
    Set NextItem = Nothing
End Sub

Private Sub Class_Terminate()
    Set NextItem = Nothing
End Sub
```

```ListTest.bas
Option Explicit

Sub TestLists()
    Dim liTest As List
    Set liTest = New List
    
    With liTest
        .Add 5
        .Add 1
        .Add 6
        .Add 4
        .Add 9
        .Add 8
        .Add 7
        .Add 10
        .Add 2
        .Add 3
        Call .DebugList
        Debug.Print "====="
        .Delete 1
        .Delete 10
        .Delete 3
        .Delete 4
        Call .DebugList
    End With
End Sub
```
VBAでQueueを扱う

```Queue.cls
Option Explicit

Private qFront As QueueItem
Private qRear As QueueItem

Public Sub Add(varNewItem As Variant)
    Dim qNew As QueueItem
    Set qNew = New QueueItem
    
    qNew.Value = varNewItem
    
    If IsEmpty Then
        Set qFront = qNew
        Set qRear = qNew
    Else
        Set qRear.NextItem = qNew
        Set qRear = qNew
    End If
End Sub

Public Function Remove() As Variant
    
    If IsEmpty Then
        Remove = Null
    Else
        Remove = qFront.Value
        If qFront Is qRear Then
            Set qFront = Nothing
            Set qRear = Nothing
        Else
            Set qFront = qFront.NextItem
        End If
    End If
End Function

Property Get IsEmpty() As Boolean
    
    IsEmpty = ((qFront Is Nothing) And (qRear Is Nothing))
End Property

Private Sub Class_Initialize()
    Set qFront = Nothing
    Set qRear = Nothing
End Sub

Private Sub Class_Terminate()
    Set qFront = Nothing
    Set qRear = Nothing
End Sub
```

```QueueItem.cls
Option Explicit

Public NextItem As QueueItem
Public Value As Variant

Private Sub Class_Initialize()
    Set NextItem = Nothing
End Sub

Private Sub Class_Terminate()
    Set NextItem = Nothing
End Sub
```

```TestQueues.bas
Option Explicit

Sub TestQueues()
    Dim qTest As Queue
    
    Set qTest = New Queue
    With qTest
        .Add "Hello"
        .Add "There"
        .Add "How"
        .Add "Are"
        .Add "You"
        Do Until .IsEmpty
            Debug.Print .Remove()
        Loop
    End With
End Sub
```
VBAでStackを扱う

```Stack.cls

Option Explicit

Private siTop As StackItem

Public Function Pop() As Variant
    If Not StackEmpty Then
        Pop = siTop.Value
        Set siTop = siTop.NextItem
    End If
End Function

Public Sub Push(ByVal varText As Variant)
    Dim siNewTop As StackItem
    
    Set siNewTop = New StackItem
    siNewTop.Value = varText
    Set siNewTop.NextItem = siTop
    Set siTop = siNewTop
End Sub

Public Property Get StackTop() As Variant
    If StackEmpty Then
        StackTop = Null
    Else
        StackTop = siTop.Value
    End If
End Property

Public Property Get StackEmpty() As Boolean
    StackEmpty = (siTop Is Nothing)
End Property

Private Sub Class_Initialize()
    Set siTop = Nothing
End Sub

Private Sub Class_Terminate()
    Set siTop = Nothing
End Sub
```

```StackItem.cls
Option Explicit

Public Value As Variant
Public NextItem As StackItem

Private Sub Class_Initialize()
    Set NextItem = Nothing
End Sub

Private Sub Class_Terminate()
    Set NextItem = Nothing
End Sub
```

```StackTest.bas
Option Explicit

Private stkTest As Stack

Public Sub TestStacks()
        
    Set stkTest = New Stack
    
    stkTest.Push "Hello"
    stkTest.Push "There"
    stkTest.Push "How"
    stkTest.Push "Are"
    stkTest.Push "You"
    Do Until stkTest.StackEmpty
        Debug.Print stkTest.Pop()
    Loop
    
    Debug.Print
    Debug.Print "Testing Procs:"
    stkTest.Push "Main"
    Debug.Print stkTest.StackTop
    Call A
    Debug.Print stkTest.Pop
End Sub

Private Sub A()
    stkTest.Push "A"
    Debug.Print stkTest.StackTop
    Call B
    Debug.Print stkTest.Pop
End Sub

Private Sub B()
    stkTest.Push "B"
    Debug.Print stkTest.StackTop
    Call C
    Debug.Print stkTest.Pop
End Sub

Private Sub C()
    stkTest.Push "C"
    Debug.Print stkTest.StackTop
    Debug.Print stkTest.Pop
End Sub
RailsでAPI作成時のメモ

# Railsで簡単なAPIを作成した時に覚えた事メモ

本記事はRailsで簡易的なAPIを作成した時に覚えた事の備忘録です。
作成手順等は記載しておりません。
また完全に個人的なメモの為、APIに直接関係ない事を記載してます。


# メモ

### ①find_or_create_byメソッド
モデル.find_or_create_by(条件)という記述で、条件を指定して、該当のデータがなければ、データを作成するメソッド


### ②transaction

transactionとは、切り分ける事が困難な処理を１つにまとめて処理する事。
→これにより、複数の処理で片方だけ処理されてしまうという事態を防ぐ事ができる。

```rb
ActiveRecord::Base.transaction do
  # 例外が発生するかもしれない処理
end
  # 例外が発生しなかった場合の処理
rescue => e
  # 例外が発生した場合の処理
```

### ③ActiveModel::Conversion#to_modelメソッド
FormObjectを用いた実装の時に、to_modelメソッドを用いる事で、クラスをモデルのような扱いをする事できます。

```ruby
to_model
  idea
end
```

### ④joinsメソッド

joinsメソッドとは、テーブルを内部結合して検索するためのメソッド
これで２つのテーブルに関連するものだけを取得する事が出来ます。

```ruby
モデル名.joins(関連するテーブル)
```

### ⑤selectメソッド

selectメソッドとは、取得したい列を指定するメソッドです。
先ほどのjoinsメソッドと組み合わせて使用する事が出来ます。

```ruby
モデル名.joins.select(:取得したい列)
```

### ⑥AS句

AS句を用いるとある値を指定した名前で取得できます。
※AS句について理解不十分なところもあるため、学習後に間違いあれば編集します
今回は、取得したデータをIDではなく名前で返したい為、以下のようなコードになりました。

```ruby
Category.joins(:ideas).select('ideas.id, name AS category, body')
```

### Rubocopの導入
gemファイルに以下を記述、bundle installとtouch .rubocop.ymlを実行。

```ruby
group :development do
  gem 'rubocop', require: false
end
```
bundle exec rubocop -aで自動修正

# まとめ

個人的に覚えたことを羅列しただけになってしまったので、
しっかりと勉強できた時に再度投稿したいと思います。
SwiftUIでモーダル遷移を実装する

# 参考
[【iOS】遷移方法まとめとエンジニア1年生の独り言](https://qiita.com/iTakahiro/items/b33306c773a05845358f)
[SwiftUIでモーダル表示する方法【SwiftUI入門】](https://www.yururiwork.net/swiftui%E3%81%A7%E3%83%A2%E3%83%BC%E3%83%80%E3%83%AB%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%80%90swiftui%E5%85%A5%E9%96%80%E3%80%91/)
[【SwiftUI】シートの使い方（sheet）](https://capibara1969.com/2521/)

# 画面遷移について
1. モーダル ... 下から画面が出現
2. プッシュ ... 右から画面が出現
3. タブ ... 瞬時の切り替わり(タブアイテムのタップ)
4. ページ ... 左右から画面が出現(左右スワイプ)

# モーダル遷移の実装
## 動画
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">モーダル遷移 <a href="https://t.co/ig7RKLCgpo">pic.twitter.com/ig7RKLCgpo</a></p>&mdash; APPLE (@applecoder6) <a href="https://twitter.com/applecoder6/status/1379836528273154052?ref_src=twsrc%5Etfw">April 7, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## コード
```swift:ContentView.swift
import SwiftUI

struct ContentView: View {
    // showingModalはContentViewで管理する値型のデータ
    @State private var showingModal = false
    var body: some View {
        Button("Show ModalView.") {
            // ボタンアクション:
            // ContentViewが持つshowingModal(self.showingModal)の切り替え
            self.showingModal.toggle()
        }.sheet(isPresented: $showingModal) {
            ModalView()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```

```swift:ModalView.swift
import SwiftUI

struct ModalView: View {
    @Environment(\.presentationMode) private var presentationMode
    var body: some View {
        Button("Close ModalView.") {
            self.presentationMode.wrappedValue.dismiss()
        }
    }
}

struct ModalView_Previews: PreviewProvider {
    static var previews: some View {
        ModalView()
    }
}
```

# 学習結果
## SwiftUIにおけるデータ管理
Viewに紐付くデータの管理方法を決定するのが`Property Wrapper`です。
SwiftUIでは全10種類のデータ管理方法が存在し、どのProperty Wrapperを使用するか決める際の方針は以下の3つの問いに集約されます。

- データとは何か
 → データが値型・参照型のどちらであるか　
- データをどのように処理するか
 → データが読み取り専用・読み書き可能のどちらであるか
- データはどこから来るか
 → `Source of Truth`の出どころは自身のView・親Viewのどちらであるか

1. let
 → データが**値型**かつ**読み取り専用**
2. @State
 → データが**値型**かつ**自身のViewで読み書き可能**
3. @Binding
 → データが**値型**かつ**読み書き可能**かつ**親Viewで管理**
4. @Environment
 → データが**自身のViewの環境値**

5. @Published
 → データが**参照型**
 ※ データを定義するクラスは`ObservableObject`プロトコルに準拠する必要がある
6. @StateObject
 → オブジェクトが**参照型**かつ**自身のViewで管理・インスタンス化**
7. @ObservedObject
 → オブジェクトが**参照型**かつ**親Viewで管理**
8. @EnvironmentObject
 → オブジェクトが**参照型**かつ**トップの親Viewで管理**
 ※ トップの親Viewのインスタンス化時に`environmentObject`修飾子を用いてオブジェクトをセットする必要がある
   → 親Viewをインスタンス化する構造体で`@StateObject`でラッパしたオブジェクトを生成する必要がある

9. @AppStorage
 → データが**値型**かつ`UserDefaults`**に格納**
 ※ アプリが削除されるまで保存される
10. @SceneStorage
 → データが**値型**かつ`シーン`**で保存**

## sheet
モーダル表示を実現する修飾子です。
.sheet()で表示した画面を閉じる方法は以下の3通りです。

- モーダル画面を下にドラッグ
- シートの表示フラグをfalseに変更
- 環境変数`presentationMode`プロパティの`dismiss`メソッドを呼び出す

## シミュレータの録画方法
1. 「ターミナル」でXcodeプロジェクトがあるディレクトリに移動
2. `xcrun simctl io booted recordVideo <動画名>.mov`で録画開始
3. Control + Cで録画停止
PyInstaller でicon 付きビルドをしようしてエラーになって困った件

## はじめに
PyInstaller でicon 付けてビルドしようとするとWindows10環境ではエラーになる場合があって困りましたが、解決できたのでまとめておきます。

## 起きたこと と 解決方法
### 実行環境
* OS : Windows 10 64bit
* Python : 3.9.2
* PyInstaller : 4.1

### エラー内容
下記のようにビルド
`$ pyinstaller --onefile --icon=sample.ico hogehoge.py`
そしたらこんなエラーメッセージが。。。
そして *.exe が生成されない（アイコンなく生成されるのではなく、そもそも生成されない）。

```
> struct.error: unpack requires a buffer of 16 bytes
```

試しに、macOS(Big Sur)の環境で確認してみると、こちらは何事もなく普通にビルドできた。

### 原因
* このとき指定していた画像（ `sample.ico` ）は、色深度が24bit のファイルだった。  
  （正確には色深度24bit の PNGファイルから ICO ファイルを作成した画像）
* つまり、指定するICOファイルの色深度が24bit だとエラーになる。
* Windows環境のみ。macOS では普通にビルドできた。

### 解決方法
* アイコン設定したい画像のicoファイルを色深度32bit で作成し、それを指定する。


## もう少し詳しく
### PyInstaller とは
* PythonスクリプトをPythonがインストールされていない環境でも利用できるように配布用の実行ファイル（*.exe）に固めてくれる便利なやつ。  
  Python 環境を整えていない人に使ってもらいたいときなどに重宝する。
* 配布用の実行ファイルにアイコンを付けることができる。  
  ビルドオプションなどは下記マニュアル参照  
  https://pyinstaller.readthedocs.io/en/stable/usage.html


### 色深度（ビット深度）とはなにか？
* その画像形式が扱えるデータ量のこと
* Windows10 のファイルプロパティで確認したときに「ビットの深さ」と表示されるもの。

**色深度の違い**

| 色深度（ビット深度） | 扱える色 |
|:-:|:-|
| 24bit | 約1,677万色 |
| 32bit | 約1,677万色 + 8bitの透過 |

透過できるかどうかの違い


### 今回の問題
* 色深度24bit のPNG で作成された *.icon ファイルを指定してビルドしようとしていたためにエラーになった。
* macOS では普通にビルドできたため、わかりにくかった。

**ビルド可否**

| OS | 24bit icon | 32bit icon |
|:-:|:-:|:-:|
| Windows10 | × | ○ |
| macOS Big Sur | ○ | ○ |


## まとめ
* PyInstaller でアイコンを設定するときには、色深度 32bit のPNG で作成した *.icon ファイルを指定してビルドしましょう。
* 32bit だと透過も入るので、アイコンの見た目としてもよりよい。
* この事象についての記事が全然見当たらなかったので、どこかの誰かのお役に立てれば幸い。
CIで使う場合のsecrets.GITHUB_TOKENのできることできないこと

# はじめに
rest apiやworkflowをgithub actionなどのCIツールで作るときにgithubのトークンを使います。大体の場合はトークンは「secrets.GITHUB_TOKEN」を使うとできますが、稀にパーミッションエラーになります。
で、githubのsettingから取得できる「Personal Access Token」を使うことになりますが、こと足りるのであればsecrets.GITHUB_TOKENで片付けたいのでどこまでができるのかを確認します。
secrets.GITHUB_TOKENは権限が弱いです。多くのことをやるなら「Personal Access Token」のようです。

# secrets.GITHUB_TOKEでできること

公式ページにちゃんと書いてあるのでペタッと貼っときます。
![スクリーンショット 2021-04-08 0.54.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109862/42998372-51b5-4496-b2ff-ed390f3f888a.png)

https://docs.github.com/en/actions/reference/authentication-in-a-workflow#permissions-for-the-github_token

見ると大体できるじゃんってなるんですが、注意が必要で、できるものの権限しか書いてません。
つまりはここに書いてあるパーミッションのカテゴリ以外はできないということです。
例えばrepository hooks,blocking,followers,email,membersなどなど。
【Androidを使い熟す！】Android Widgetについて

#####※Android技術者認定にも役に立ちます！
#ウィジェット(Widget)とは？
<details><summary>説明</summary>ユーザインタフェースを構成する部品のこと。</details>
#よく使われるユーザインタフェース部品
<dl>
  <dt>・TextView</dt>
  <dd>テキストを表示するための部品</dd>
  <dt>・EditText</dt>
  <dd>テキストを入力するための部品</dd>
　<dt>・ImageView</dt>
  <dd>画像を表示するための部品</dd>
　<dt>・Button</dt>
  <dd>クリック可能なボタン。</dd>
　<dt>・CheckBox</dt>
  <dd>複数選択が可能なチェックボックス</dd>
　<dt>・RadioButton</dt>
  <dd>単一選択可能なラジオボタン</dd>
</dl>
…などたくさんあります。
MacOSX の固有コマンド

こんにちは。
MacOSX の固有コマンド[^1]および使用例を調べました。```Terminal``` 上でこれらのコマンドを実行します。

* open
 * ディレクトリを Finder で開く。```open .```
 * ファイルを開く。```open -a /Applications/Google\ Chrome.app index.html```
 * url を開く。```open -a /Applications/Google\ Chrome.app "http://www.google.co.jp/search?q=apple"```
 * Dictionary.app を開いて検索させる。```open dict://Apple```

* osascript
 * osascript (Applescript) を実行。```osascript -e "beep 2"```

* say
 * 発話。```say -v Alex Hello```

* qlmanage
 * [Quick Look](https://ja.wikipedia.org/wiki/Quick_Look) 表示機能。```qlmanage -p memo.txt >& /dev/null``` [^2]

* mdfind
 * Spotlight による検索。

* pbcopy
 * コピー。

* pbpaste
 * ペースト。

* sw_vers
 * MacOSX バージョン情報。

[^1]: 参考：「[OSXの固有コマンド](http://macwiki.osdn.jp/wiki/index.php/OSX%E3%81%AE%E5%9B%BA%E6%9C%89%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89)」(MacWiki)、「[知ってるとちょっと便利なMacの固有コマンド](https://qiita.com/suzuki-hoge/items/21c59c92e07988bb4c3e)」
[^2]: ただし、これはうまく動作しない場合があるので注意が必要です（原因不明）。
東証上場企業リストから、AではじまりCでおわる素材の会社を探す【正規表現】

# はじめに
* `AではじまりCでおわる素材の会社`は`AGC`以外にもあるのではないかと思い調べてみました

# データ
* 東証上場銘柄一覧（2021年3月末）をJPXより取得
 * https://www.jpx.co.jp/markets/statistics-equities/misc/01.html

# 方法
## データ内容確認
```
import pandas as pd
df = pd.ExcelFile('./data_j.xls').parse('Sheet1')
df.head()
```
* 出力は下記の通り。「銘柄名」列に会社の名前が、「33業種区分」列もしくは「17業種区分」列に、その会社の業種情報が入力されている
* 4096銘柄あるらしい！

```
日付 	コード 	銘柄名 	市場・商品区分 	33業種コード 	33業種区分 	17業種コード 	17業種区分 	規模コード 	規模区分
0 	20210331 	1301 	極洋 	市場第一部（内国株） 	50 	水産・農林業 	1 	食品 	7 	TOPIX Small 2
1 	20210331 	1305 	ダイワ上場投信－トピックス 	ETF・ETN 	- 	- 	- 	- 	- 	-
2 	20210331 	1306 	ＮＥＸＴ　ＦＵＮＤＳ　ＴＯＰＩＸ連動型上場投信 	ETF・ETN 	- 	- 	- 	- 	- 	-
3 	20210331 	1308 	上場インデックスファンドＴＯＰＩＸ 	ETF・ETN 	- 	- 	- 	- 	- 	-
4 	20210331 	1309 	ＮＥＸＴ　ＦＵＮＤＳ　ＣｈｉｎａＡＭＣ・中国株式・上証５０連動型上場投信 	ETF・ETN 	- 	- 	- 	- 	- 	-
```
## 注目すべきデータ項目
* 「銘柄名」については、漢字、平仮名、片仮名、アルファベット(全角)で構成されている。
    * もしかすると「エイ・ビイ・シイ」や「栄作エージェンシー」という会社もあるかもしれない。これらも`「A(えい)」ではじまり「C(しい)」で終わる会社`とみなすことができる。本気出すなら、ひらがなやアルファベットに統一する必要がありそう(だが面倒なのでスキップ)
* `33業種区分`/`17業種区分`のうち、`素材`というワードが含まれるのは、`17業種区分`の中の`素材・化学`のみ。`17業種コード`では、`4番`。
    * 参考
        * https://www.sakuranpost.net/mirai/?p=23

## 問題定義
`AではじまりCでおわる素材の会社`とは、`銘柄名`が、「A」ではじまり「C」でおわり、かつ、`17業種コード`が`4番`の会社と今回は定義する。

## 実装
* `銘柄名`が、「A」ではじまり「C」でおわる、については、正規表現を使う。
 * `^`は「文頭」「行頭」
 * `$`は「文末」「行末」
 * `.`は任意の 1 文字。
 * `*`は直前のパターンを 0 回以上繰り返し
*  `17業種コード`が`4番`については省略
* これらを統合すると次のように書くことができる

```
df[(df['銘柄名'].str.contains('^Ａ.*Ｃ$')) & (df['17業種コード']==4)]
```

# 結果
```
null
```

* もう一回!

```
>>> df[(df['銘柄名'].str.contains('^Ａ.*Ｃ$')) & (df['17業種コード']==4)]
null
```
* あれー

# 考察
* `あれー`ってなってしまったので、`素材の会社`の条件をとっぱらった。結果は次の通り

```
>>> df[df['銘柄名'].str.contains('^Ａ.*Ｃ$')]
日付 	コード 	銘柄名 	市場・商品区分 	33業種コード 	33業種区分 	17業種コード 	17業種区分 	規模コード 	規模区分
1953 	20210331 	5201 	ＡＧＣ 	市場第一部（内国株） 	3400 	ガラス・土石製品 	3 	建設・資材 	4 	TOPIX Mid400
```

* `ＡＧＣ`!!!!!!!!!
    * 条件を緩めても、日本の上場企業の中でひとつだけしか存在しなかったのは正直おどろき
* JPXの定義では、`ＡＧＣ`は、`ガラス・土石製品`業になるので`素材`の会社ではなかった
* よって、二つの条件を満たす企業は皆無だったため、null を返した

# まとめ
* AではじまりCでおわる素材の会社は？と問われたら、`思いつきで手を動かさず、まず確認が重要`→新人の時にやらかしたし、今でもやらかす
    * `Ａ(全角)`のみならず`A(半角)`を考慮すべきか
    * `えい`や`えー`など読みを考慮するか
    * 日本企業か海外企業まで含むか
    * 上場企業か非上場企業か
    * `素材の会社`とは何か。業種区分で良いか。その定義は実態に則しているか
    * などなど
* 仕事は同じことを複数回行うことが多いので、最初は大変でもプログラム化しておくと良い。
 * 可愛い上司やお客様から「もう一回♪」と言われること多し
 * 個人視点でも後々作業が楽になるし、会社視点でも誰がやっても同じ結果になるのはありがたいはず
 * 目の前のパソコンは、人間を楽させてくれるために存在しているらしい 
* `広瀬すず`ちゃんは可愛い
* 何か他にいい方法があれば教えてください！
​
AWS Macie とは

## 勉強前イメージ

いや・・・そもそもそういうサービスあるってのも知らなかった

## 調査

### AWS Macie とは

メイシーと呼び、
機械学習を使ってs3に保存されている機密データを検出するサービスです。
パターンマッチング手法などを使用して、個人識別情報(PII)などのデータを特定
アラートを発信することが出来ます。

### 特徴

- AWS Organizationsとの統合

Organizationsと統合することで全体の機密データ検出を行うことが出来ます。
複数アカウントの場合はMacie管理アカウントに集約され、発見後のフローを自動化出来ます。

- 自動化

s3バケット内のデータを1日・毎日・毎週・毎月実行できます。
また、オブジェクトの変更を追跡し変更されたオブジェクトのみ確認します。

- 機密データタイプのマネジメント

機密データタイプのリストは一般的な個人識別情報(PII)などで定義されている機密データが含まれ、
日々増加するとともに改善・追加がなされています。

## 勉強後イメージ

持ってるデータに個人情報が含まれるかのも見てくれるのか・・・
しかもそれって定義されているのね、知らなかった

## 参考

- [Amazon Macie](https://aws.amazon.com/jp/macie/)
- [Amazon Macie の特徴](https://aws.amazon.com/jp/macie/features/)
KtorでSession CookieをAESで暗号化するときの鍵長を256bitにする

ktorのsession cookieを暗号化するときの話。
[KtorのTransformer](https://ktor.io/docs/transformers.html#SessionTransportTransformerEncrypt)を使えば簡単に実現できる。ただ、鍵長を128bit以外にするときにハマりどころがある。

まず、暗号化の鍵長を128bit以外にもできるコードサンプルを示す。

```kotlin
cookie<TestUserSession>(cookieName) {
    // デフォルトの暗号化アルゴリズムはAES
    transform(SessionTransportTransformerEncrypt(
        // 暗号化鍵
        secretEncryptKey, 
        secretAuthKey,
        // IVの生成関数。この指定がポイント。
        ivGenerator = { _ -> ByteArray(16).apply { SecureRandom().nextBytes(this) } },
    ))
}
```

デフォルトだとIVと暗号化鍵の長さは同じになる。暗号化鍵の長さを256bitにすると、IVの長さも256bitになってしまい、"Wrong IV length: must be 16 bytes long"というエラーが発生する。AESのIVの長さは、鍵長に関係なく128bitにしなければならない[^1]。

自前のivGeneratorを指定し、ivの長さを128bitにすることで、この問題を回避できる。


[^1]: https://tools.ietf.org/doc/tcllib/html/aes.html#:~:text=The%20initialization%20vector%20%2Div%20takes,a%20multiple%20of%2016%20bytes.
rbenv install で BUILD FAILED する

## 事象
rbenv install 2.6.3 が BUILD FAILED してしまう。。

```bash
$ rbenv install 2.6.3
rbenv: /Users/user/.rbenv/versions/2.6.3 already exists
continue with installation? (y/N) y
Downloading openssl-1.1.1i.tar.gz...
-> https://dqw8nmjcqpjn7.cloudfront.net/e8be6a35fe41d10603c3cc635e93289ed00bf34b79671a3a4de64fcee00d5242
Installing openssl-1.1.1i...
Installed openssl-1.1.1i to /Users/user/.rbenv/versions/2.6.3

Downloading ruby-2.6.3.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.3.tar.bz2
Installing ruby-2.6.3...
ruby-build: using readline from homebrew

BUILD FAILED (macOS 11.1 using ruby-build 20210119)

Inspect or clean up the working tree at /var/folders/81/y_mntqpn7651ft78m781s9nw0000gn/T/ruby-build.20210405230655.5546.REHmaD
Results logged to /var/folders/81/y_mntqpn7651ft78m781s9nw0000gn/T/ruby-build.20210405230655.5546.log

Last 10 log lines:
	from ./tool/rbinstall.rb:526:in `install'
	from ./tool/rbinstall.rb:556:in `block (2 levels) in <main>'
	from ./tool/rbinstall.rb:264:in `block in install_recursive'
	from ./tool/rbinstall.rb:258:in `each'
	from ./tool/rbinstall.rb:258:in `install_recursive'
	from ./tool/rbinstall.rb:555:in `block in <main>'
	from ./tool/rbinstall.rb:933:in `block in <main>'
	from ./tool/rbinstall.rb:930:in `each'
	from ./tool/rbinstall.rb:930:in `<main>'
make: *** [do-install-all] Error 1
```

## 解決法

ググるといろいろ出てきますが何事もとりあえずログを見てから、、

```bash
# ログを見てみる
$ cat /var/folders/81/y_mntqpn7651ft78m781s9nw0000gn/T/ruby-build.20210405230655.5546.log
...
installing binary commands:         /Users/user/.rbenv/versions/2.6.3/bin
installing base libraries:          /Users/user/.rbenv/versions/2.6.3/lib
installing arch files:              /Users/user/.rbenv/versions/2.6.3/lib/ruby/2.6.0/x86_64-darwin20
installing pkgconfig data:          /Users/user/.rbenv/versions/2.6.3/lib/pkgconfig
installing command scripts:         /Users/user/.rbenv/versions/2.6.3/bin
./tool/rbinstall.rb:279:in `chmod`: Operation not permitted @ apply2files - /Users/user/.rbenv/versions/2.6.3/bin/bundle (Errno::EPERM)

# Permission Errorみたい
# sudo すればよさそう
$ sudo rbenv install 2.6.3
Password:
...
Installed ruby-2.6.3 to /Users/user/.rbenv/versions/2.6.3
```
インタラクション

#cell関数
テーブルデータでイメージする。
行を指定し、カラムを指定する方法。シンプルでわかりやすい
選択インタラクションにしないと切り替わらない。結果インタラクションだとずっと指定した行のまま。
"複数"選ぶことができない。
![スクリーンショット 2021-04-08 0.20.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385774/9e2eaaef-2c0e-0144-e7e1-f847dae7c15a.png)

####asString()とasObject()の使い分け

選択インタラクションで違いがでた。asStringだと選択していないとnullとなり何も表示されない。
切り分けとしては、asobject使う方が無難かなと

![スクリーンショット 2021-04-08 0.26.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385774/a8c73b3d-044c-f2bf-bc51-0a09d1616a83.png)


- asObject()は逐次化なしでデータを渡します。
- スカラー、一次元配列、または二次元配列を文字列として逐次化します。文字列内の二重引用符はエスケープします。

```
cell(myStep.selection, 1, "stateName")
```

#column 関数
複数選びたい時に使う.
![スクリーンショット 2021-04-08 0.44.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385774/97bdba71-6afa-e590-ca96-30a8393aa1e0.png)


```
"{{column(static_1.result, [\"項目1\"]).asObject()}}",
```

#row関数
cellの複数選択ができる版のイメージ。
実際あんま使い方わからない




#参考文献
[バインド開発者ガイド](https://developer.salesforce.com/docs/atlas.ja-jp.bi_dev_guide_bindings.meta/bi_dev_guide_bindings/bi_dashboard_bindings_functions_wave_designer_cell.htm)
Javaの環境変数(Windows)

# Javaの環境変数について

## はじめに

Javaの環境変数についてのまとめです。自分用のメモとして残しておきます。

＜動作環境＞
Windows 10

## Javaの環境変数設定

javaに限らず、何らかのアプリケーションをダウンロードしたら、Windowsの環境変数にパスを設定する必要がある。

Javaにおける環境変数の設定は、基本的には以下のとおり。

1. システム環境変数のPATHに```%JAVA_HOME%\bin```と記述

2. システム環境変数のJAVA_HOMEに```C:\Program Files\Java\jdk{version}```と記述

JDKの{version}を変えたければ、JAVA_HOMEの値を変更すれば良いだけ。直接PATHをいじらなくて済む。

なお、```C:\Program Files\Java\jdk{version}\bin```配下にjava.exeがある。

## 環境変数設定前にjavaコマンドが反応

ただ、これらの環境変数を設定しなくても、なぜかjavaコマンドは反応した。

そこで調べると、```C:\Program Files\Commom Files\Oracle\Java\javapath```の中にjava.exeがあった。PATHにここの場所は記載があったため、おそらくこれで動いた模様。

とりあえず、この```C:\Program Files\Commom Files\Oracle\Java\javapath```より上に```%JAVA_HOME%\bin```は記載。

なお、参考にしたサイトにはjavapathのパスとして```C:\ProgramData\Oracle\Java\javapath```という記載があり、自分のパスとどう違うのか謎。

しかも、JDKのバージョンによって、このjavapathフォルダ内のjava.exeは違う場所にあるらしい。

- JDK8より前：```C:\Windows\System32```配下

- JDK8:```C:\ProgramData\Oracle\Java\javapath```配下

ちなみに、JDK8の後期はまた違うらしい...難しい...


## 参考文献

[JAVA_HOMEが効かない！？複数のJDKを切り替えて使うときの問題点](https://web.plus-idea.net/2017/04/java_home-swich-jdk/)
[15 Microsoft WindowsのJDKのインストール](https://docs.oracle.com/javase/jp/8/docs/technotes/guides/install/windows_jdk_install.html#CHDJCCEG)
[[java] Windows における javapath と JAVA_HOME](http://ooltcloud.sakura.ne.jp/blog/201802/article_09182611.html)
Visual Studio Codeの拡張機能であるREST Clientを使ってみる

# 概要
APIのリクエストレスポンスの確認としてPostmanを使っているが、
Visual Studio Code(VSCode)の拡張機能であるREST Clientが便利だったので
使い方のメモを記載する。


# 手順
## 1.REST Clientのインストール
拡張機能の検索から「REST」入力すると一番上に表示される。

![スクリーンショット 2021-04-06 0.47.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248644/07c57ac6-b8ba-0239-243b-0c08f5cfb0b3.png)

インストールボタンを押してREST Clientの拡張機能を取り込む
![スクリーンショット 2021-04-06 0.46.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248644/e754979c-2fa3-38de-5dd6-2d8048b06b85.png)


## 2.REST Clientを使ったGETリクエスト
リクエスト操作を行うために、`.http`ファイルを作成する。
本記事では、sample.httpファイルを用意し、記載をしていく。

sample.http

```
GET http://localhost:3000/api/v1/tasks HTTP/1.1
```
たまたまローカル環境に、Rails APIで起動しているアプリがあったので、GETリクエストをする。
リクエストURLを記載し、上に書かれた「Send Request」を押す。

**結果**

![スクリーンショット 2021-04-06 0.59.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248644/9741ebd2-75c9-06ce-7438-1dd027951aad.png)

![スクリーンショット 2021-04-06 0.59.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248644/0158f0ff-c799-cb96-5e4a-0c431998540b.png)

リクエストの結果として、Response画面にレスポンスデータが表示された。


## 3.REST Clientを使ったPOSTリクエスト
sample.httpにPost処理を記載する。

sample.https

```
POST http://localhost:3000/api/v1/tasks HTTP/1.1
content-type: application/json

{
    "title": "sample",
    "description": "これはサンプルデータです。"
}
```

**結果**

![スクリーンショット 2021-04-06 1.08.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248644/db97d489-69cf-c0e1-3dd1-04723e530397.png)


## まとめ
今回のREST Clientは新くアプリをインストールすることはせずにVSCodeの拡張機能としてAPIの確認をしてみました。
拡張機能として使えるのはありがたいです。
[Laravel] N+1問題について少し調べた

#概要

面接の際にN+1問題について問われたのですが、あまりうまく答えられなかったので整理します。
主にLaravelでのN+1問題について記述します。

間違っている部分等ありましたらご指摘いただけると幸いです。


#N+1問題

LaravelはEloquent ORMを使用されます。

ORMとはデータベースのレコードをオブジェクトとして直感的に扱えるようにするものです。
生のSQLで書く必要がないため、RDBへアクセスする処理を簡単に行うことができます。

そして、Eloquentのリレーションはデフォルトとして「遅延ロード」されますが、それを「Eagerロード」にすることでN+1問題を解決することができます。

##「遅延ロード」と「Eagerロード」

では、遅延ロードとEagerロードとの違いについて見ていきます。

以下の関係のテーブルがあった場合(公式より抜粋）

```Book.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    /**
     * この本を書いた著者を取得
     */
    public function author()
    {
        return $this->belongsTo('App\Author');
    }
}
```

遅延ロードで全書籍と著者を取得すると以下のようになります。

```.php
$books = App\Book::all();

foreach ($books as $book) {
    echo $book->author->name;
}
```

この場合、

```.php
echo $book->author->name;
```

が実行されることで初めてBookとAuthor間のリレーションデータが取得されます。

つまり、`echo $book->author->name;`が行われるたびに

```Book.php
    public function author()
    {
        return $this->belongsTo('App\Author');
    }
```

にアクセスをしてデータを取得していることとなります。

ですので、上記の例だとBookの数だけselect文が発行されることになってしまいます。

このことを`N+1問題`と言うみたいです。

そしてN＋1問題を解決するために`Eagerロード`と言うものが存在します。

遅延ロードだと
*1.Authorのリレーションデータを持っていないBookモデルコレクションを取得*
*2.リレーションデータにアクセスするたびにリレーションデータを取得*
*以下手順2をループ*

に対して
*1.Authorリレーションデータを事前に取得したBookモデルコレクションを取得*

とすることでクエリの発行を最小限に抑えることができます。

LaravelでのEagerロードはwithを使うことで行うことができます。

```.php

// 遅延ロード
$books = App\Book::all();
// Eagerロード
$books = App\Book::with('author')->get();
```

また、N+1問題の検知は以下のようなパッケージがあるみたいです。(まだ触っていないのでなんとも言えないですが)
https://github.com/beyondcode/laravel-query-detector

#まとめ

わかっているつもりでプログラムを書いていましたが、改めて調べてみることで全然理解できていないなと痛感しました。


#参考文献
[公式](https://readouble.com/laravel/7.x/ja/eloquent-relationships.html)
[オブジェクト関係マッピング](https://qiita.com/yk-nakamura/items/acd071f16cda844579b9)
[Laravelでリレーションのあるテーブルをwithで取得する【N+1問題】](https://pensuke.work/posts/laravel-relation-with)
[LaravelでN+1を検出させる
](https://qiita.com/zdjjs/items/98786583710ec0ac9873)
[Java]switch文

### switch文の構文
```java
switch([評価式]){
    case 1: // "case"と1の間は半角スペースが必要。 
        // 評価式の値が1だったときの処理
        break;
    case 2:
        // 評価式の値が2だった場合の処理
        break;
    default : //"default"と":"の間も半角スペースが必要。
        // 評価式の値が上記のケースに当てはまらなかった場合の処理
        break;
}
```

上記の評価式の値によって、処理を分岐させることができる。

#### 注意点
**1.switch文の評価式は、**

- char
- byte
- short
- int
- Character
- Byte
- Short
- Integer
- String
- 列挙型

のいずれかを戻す式であることある必要がある。例えば、評価式の値としてfloatやdoubleは使用できない。

```java
// 評価式の部分に以下の"abc"や"z"は使用できない。
float abc = 1.4f; // 浮動小数点型なのでコンパイルエラー
double z = 1.2345; //浮動小数点型なのでコンパイルエラー
int i = 123; // OK
String str = abc; // OK
```

**2."break;"を忘れる。**
下のコードにおいて、 a = 1の場合。

```java
switch(a){
    case 1:
        System.out.println("abc");
    case 2:
        System.out.println("def");
    default:
        System.out.println("ghi");  //出力結果:"abcdefghi"
}
```
case 1 、 case 2 、 defaultの処理が実行される。
VBA エラー 449 引数は省略できません

ABC100＿999
DEF100_9

という２つの項目があったとする。

ABC100＿999では、名前に関するデータを、
DEF＿9では、年齢に関するデータを出力するとする。

ABC100_999の中にデータを抽出した後、close（終了）する前に、
DEF100_9を代入することによって、名前の次に年齢に関するでーたが出てくる。



この時、引数は省略できませんというエラーがでてしまう。
この原因として挙げられるのが、

数が違うという問題点である。
日本からアメリカに行くときに３人留学生がいくとする
しかし、アメリカには２人しか受け入れる枠がない。

このとき、１人余る。

プログラミングでは、この時にエラーが起きてしまう。
数があっていないことが１番の原因である。
Railsチュートリアル　6章コマンド、メソッド

```
# model作成
$ rails generate model user name:string email:string
# マイグレーションファイル実行(DBに反映)
$ rails db:migrate

$ rails generate migration add_index_to_users_email
$ rails generate migration add_password_digest_to_users password_digest:string
# エラー時のお役立ちコマンド
$ rails generate destoroy user
$ rails db:migrate:reset
```

##メソッド

``new``
新しいユーザーオブジェクトを生成

```
>> user = User.new(name: "Michael Hartl", email: "michael@example.com")
=> #<User id: nil, name: "Michael Hartl", email: "michael@example.com",
created_at: nil, updated_at: nil>
```

``valid?``
オブジェクトが有効かどうか

```
>> user.valid?
true
```

``save``
DBにUserオブジェクトを保存

```
>> user.save
   (0.1ms)  SAVEPOINT active_record_1
  SQL (0.8ms)  INSERT INTO "users" ("name", "email", "created_at",
  "updated_at") VALUES (?, ?, ?, ?)  [["name", "Michael Hartl"],
  ["email", "michael@example.com"], ["created_at", "2019-08-22 01:51:03.453035"],
  ["updated_at", "2019-08-22 01:51:03.453035"]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
=> true
```

``create``
モデルの生成(new)と保存(save)を同時に行う

```
>> User.create(name: "A Nother", email: "another@example.org")
#<User id: 2, name: "A Nother", email: "another@example.org", created_at:
"2019-08-22 01:53:22", updated_at: "2019-08-22 01:53:22">

# 変数fooに代入
>> foo = User.create(name: "Foo", email: "foo@bar.com")
#<User id: 3, name: "Foo", email: "foo@bar.com", created_at: "2019-08-22
01:54:03", updated_at: "2019-08-22 01:54:03">
```

``destroy``
createの逆で削除(ただしメモリには残る)

```
>> foo.destroy
   (0.1ms)  SAVEPOINT active_record_1
  SQL (0.2ms)  DELETE FROM "users" WHERE "users"."id" = ?  [["id", 3]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
=> #<User id: 3, name: "Foo", email: "foo@bar.com", created_at: "2019-08-22
01:54:03", updated_at: "2019-08-22 01:54:03">
```

``find``, ``find_by``
オブジェクトを検索

```
#エラー出したい場合
>> User.find(1)
=> #<User id: 1, name: "Michael Hartl", email: "michael@example.com",
created_at: "2019-08-22 01:51:03", updated_at: "2019-08-22 01:51:03">

# 属性(email)で検索。エラー出さないで表示
>> User.find_by(email: "michael@example.com")
=> #<User id: 1, name: "Michael Hartl", email: "michael@example.com",
created_at: "2019-08-22 01:51:03", updated_at: "2019-08-22 01:51:03">
```

``first``
DBの最初のユーザー

```
>> User.first
=> #<User id: 1, name: "Michael Hartl", email: "michael@example.com",
created_at: "2019-08-22 01:51:03", updated_at: "2019-08-22 01:51:03">
```

``all``
DB全てのUserオブジェクト

```
>> User.all
=> #<ActiveRecord::Relation [#<User id: 1, name: "Michael Hartl", email:
"michael@example.com", created_at: "2019-08-22 01:51:03", updated_at:
"2019-08-22 01:51:03">, #<User id: 2, name: "A Nother", email:
"another@example.org", created_at: "2019-08-22 01:53:22", updated_at:
"2019-08-22 01:53:22">]>
```

``update``
オブジェクトを更新

```
>> user.update(name: "The Dude", email: "dude@abides.org")
=> true
>> user.name
=> "The Dude"
>> user.email
=> "dude@abides.org"

# 検証を回避して更新したい
>> user.update_attribute(:name, "El Duderino")
=> true
>> user.name
=> "El Duderino"
```

``errors``
エラー内容表示

```
>> user = User.new(name: "", email: "michael@example.com")
>> user.valid?
=> false
>> user.errors.full_messages
=> ["Name can't be blank"]
```
macOSでの証明書エラーの対応方法

# エラー内容
SSL接続で使用するCA証明書を設置するために以下のコマンドを実行。

```
＄ CERT_PATH=$(ruby -ropenssl -e "puts OpenSSL::X509::DEFAULT_CERT_FILE")
＄ sudo curl "https://curl.haxx.se/ca/cacert.pem" -o $CERT_PATH
```



その後、git push herokuのコマンドを実行しようとすると、以下のエラーが発生するようになった。

```
fatal: unable to access 'https://git.heroku.com/省略.git/': error setting certificate verify locations:
  CAfile: /etc/ssl/cert.pem
  CApath: none
```

# 1. エラーの発生原因を特定する。
まずはCA証明書がダウンロードされているか確認する。

```
＄ ls -al /private/etc/ssl

total 24
drwxr-xr-x   6 root  wheel   192  1  1  2020 .
drwxr-xr-x  85 root  wheel  2720  2 27 10:58 ..
-rw-r--r--   1 root  wheel   299  4  6 23:50 cert.pem
drwxr-xr-x   2 root  wheel    64  1  1  2020 certs
-rw-r--r--   1 root  wheel   745  1  1  2020 openssl.cnf
-rw-r--r--   1 root  wheel  1006  1  1  2020 x509v3.cnf
```
cert.pemがあることが確認できる。


次に以下のコマンドを打ち、

```
＄ ruby -ropenssl -e "puts OpenSSL::X509::DEFAULT_CERT_FILE"

/private/etc/ssl/cert.pem
```


CA証明書が/private/etc/ssl/cert.pemにあることが確認できる。

そして、以下のコマンドを打ち、"https://curl.haxx.se/ca/cacert.pem" からダウンロードした内容を出力してみると、


```
＄ cat /private/etc/ssl/cert.pem 

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://curl.se/ca/cacert.pem">here</a>.</p>
<hr>
<address>Apache Server at curl.haxx.se Port 80</address>
</body></html>
```

ダウンロード元が、"https://curl.haxx.se/ca/cacert.pem" から "https://curl.se/ca/cacert.pem" に変わっていることがわかる。

# 2. エラー対処方法
1より"https://curl.se/ca/cacert.pem" からCA証明書をダウンロードすれば良いとわかったため、以下のコマンドを実行してみると、

```
sudo curl "https://curl.se/ca/cacert.pem" -o /private/etc/ssl/cert.pem
```

```
curl: (77) error setting certificate verify locations:
  CAfile: /etc/ssl/cert.pem
  CApath: none
```
またエラーが発生してしまう。。。

そこで証明書ダウンロードの際だけ、証明書のエラーを無視するようにするため -kを使い、

```
sudo curl -k  "https://curl.se/ca/cacert.pem" -o /private/etc/ssl/cert.pem
```

すると無事に証明書のダウンロードが完了し、git push herokuできるようになりました！
現場に入って知った用語やツール

ありがたいことに現場に入ることができたのですが、毎日先輩たちが何言ってるか分からないことをググりながら過ごしています。
ビビってますが、前職でも最初はわけわからん言葉ばかりだったので勉強していけばまぁ大丈夫だろうと思っています。

「そんなことも知らないの？」とかは無しでお願いしまーす！
日々更新していこうと思います！

## ツール

#### [Backlog](https://backlog.com/ja/lp/?gclid=CjwKCAjw6qqDBhB-EiwACBs6x65GXEnmPvAvVjX2tbxqqh4TFz-4q_OqMSjkB2ESFWJ3Iv2F41kr8xoCAeoQAvD_BwE)

チームでタスク管理をするためのツールです。
資料を共有したり、ガントチャートで納期を分かりやすくしたり、課題を追加していくことで何が必要であと何が足りないかとか分かりやすいです。議事録とかもここに残しておけるので資料の整理にもいいなと思いました。
エンジニアとしては常識のツールのようですが、前職でも使いたかったなって思うくらい他でも充分に使えるツールです。





## 用語

#### デッドリンク
`リンク切れ`のことかなと思いましたが微妙に違いました。
デッドリンクはリンク先がないリンクのこと。
リンク切れはリンク先がない状態のこと。

#### WF
ワイヤーフレームのことです。
webページのレイアウトを定める設計図で、これを見ればパッとどんなwebページでどこにどのボタンがあるかとかがすぐ分かります。

#### バッチ処理
例えば、毎月1日にユーザーの契約を確認して料金を請求するとか、毎日10時にメールを送るとか`ある動作を繰り返す処理`のこと。
即時性の必要のない処理。

#### ステージング
今まで個人ではローカルor本番環境という感じで開発していました。
ステージングとはリリースの前に本番環境と同じ環境にシステムを反映させて最終確認をする段階のことです。
もしくはその環境のこと。



## 言葉

これはエンジニアに限らずなのか、他の業界でも使うのか分かりませんが、私は初めて聞いたなって言葉をピックアップします。
正直会社によると思いますが...

#### 揉む
スケジュールを揉むとかに使ってますね。
検討を重ねることをさします。

#### 決めの問題
これ、IT業界以外で使うのかな？
今までいろいろ経験してきたけど全く聞いたことない...
意味としては分かりますけどね。
私の解釈としては、手段とか何かを決めるときにどちらを選んでもメリットやデメリットがあるから決めちゃうしかない時とか、特にどれを選んでも問題ないから決めちゃおう的な感じなのかなと思います。
最適解がないっていうことかなーと思います。
これが一番難しいですよね。
「今日ご飯何食べたい？」→「なんでもいいよ」と同義語な気がします。

あれ？
もっとあった気がするのですが、忘れてしまったのでまた追加します！
本番環境でお問い合わせメールが送れない

## はじめに
ruby 2.7.2
Rails 6.1.1
## お問い合わせのメールが送信できない
ローカルでは問題なく送信できていたお問い合わせが、本番環境で機能しなくなった。


![スクリーンショット 2021-04-07 23.02.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863944/a7a432b0-56a9-32e5-de84-779c818d23ab.png)
送信を押すと↓
![awserroer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863944/6cafc737-9ada-02e6-cdbe-5fbb847ce5ae.png)
エラー画面が表示される。なぜだ。。。

## サーバー側のログを確認

ひとまずログを確認することで、以下のようなエラーメッセージが出ていた。

```ruby:log/production.log
Errno::ECONNREFUSED (Connection refused - connect(2) for "localhost" port 25):
```
エラー内容としては、ActionMailerの配信方法が正しく設定されていない？
ローカルホストポート25でSMTPサーバーを使用して電子メールを送信するように構成されていることを示しています。（引用）
構成が使用されていないことを示している。
## 【解決策】config/environments/production.rbにもMailerの設定を記述する
サーバーへのデプロイをproduction環境で稼働させている場合は、config/environments/production.rbにMailerの設定を記述する必要がある。
（config/environments/development.rbでしか設定をしていなかった...。）

```ruby:config/environments/development.rb
config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address: 'smtp.gmail.com',
    domain: 'gmail.com',
    port: 587,
    user_name: <ユーザー名>,
    password: <パスワード>,
    authentication: 'plain',
    enable_starttls_auto: true
  }
```

上記に記述しているMailerの設定を、config/environments/production.rbにも記述することで、本番環境でも動くことを確認できた。

## 参考資料
https://railsguides.jp/action_mailer_basics.html
【AWS】用語を整理しながら学ぶAWS - part6 AWS Syetems Manager

# はじめに

この記事では AWS Cloud Tech を通して AWS Systems Manager(以下、AWS SSM) を学習して実践していく記事です。
主な内容としては実践したときのメモを中心に書きます。（忘れやすいことなど）
誤りなどがあれば書き直していく予定です。

## AWS Systems Manager とは

> AWS Systems Manager (旧称 SSM) は、
> AWS でインフラストラクチャを表示および制御するために使用できる AWS のサービスです。

[AWS Systems Manager](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/what-is-systems-manager.html)

なるほど。全くわからん。
なんとなーくで解釈すると。。。

セキュリティや運用の自動化そして、パラメータストアとして活躍すると
(なんかまた、横文字出てきた)

## パラメータストアとは

(なんだろう。。。基本情報技術者試験に出てきそうなワード)

パラメータ(値)ストア(貯める)なのでお察しですが
パラメータストアとは任意の値を保存しておける場所のこと。

AWS SSM では主に平文の文字列とセキュアストリング、文字列リストを保存できるとのこと
(なんかまた、横文字出てきた)

## 平文とセキュアストリング

平文は「ひらぶん」と読みます。
英語ではしばしば、Plain Text または ClearText と表現されます。

AWS では平文のことをプレーンテキストと表現しています。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-parameter-store.html

で、平文とセキュアストリングって何がどう違うんですかという話ですが

ざっくり言えば、平文は暗号化されません。つまり、まる裸文字列 DAZE！
セキュアストリングは暗号化された文字列です。

ちなみに平文でパスワードのやりとりをしてしまう代表的なプロトコルには
FTP、POP、Telnet が存在する。

### どういうときにどっち使うの？

ざっくり言うと
見えてしまっても良いモノ(困らないモノ)に平文を使う。
見られたら困るモノにセキュアストリングを使う。

## 使うと良いこと

最近、掲載した CloudFormation によく使われるのですが
例えば、IaC 化したソースコードの中に
ハードコーディングしたくない値があったときに AWS SSM パラメータストアを活用すると

ソースコード内に特定の値をハードコーディングする必要がなくなり
AWS SSM 依存ではあるもののより抽象的で汎用的な IaC 化が実現できる。

### ハードコーディングって何ですか

決め打ちの値
例えば、どのファイルにおいても普遍の定数値やパスワード、URL などを
ソースコード内に埋め込むこと

### 実際の書き方

ami-name という変数名に AMI ID「ami-0992fc94ca0f1415a」を保存しておき
テンプレートで参照する場合はこんな感じになると。。。

```yml:test.yml

AWSTemplateFormatVersion: 2010-09-09
Resources:
  myEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      KeyName: PrivateEc2Key
      ImageId: '{{resolve:ssm:ami-name:1}}'
      InstanceType: t2.micro
      Monitoring: false
      NetworkInterfaces:
        - AssociatePublicIpAddress: false
          DeviceIndex: "0"
          GroupSet:
            - !ImportValue PrivateSecGrp
          PrivateIpAddress: "10.0.1.15"
          SubnetId: !ImportValue PrivateSubnet
      Tags:
        - Key: Name
          Value: PrivateEC2

```

> '{{resolve:ssm:ami-name:1}}'

最後の 1 はパラメータのバージョン番号、変更管理に使う番号ということで間違いなさそう。(本当か？)

## CloudFormation でセキュアストリングを使うときの注意点

CloudFormation において
セキュアストリングがサポートされている AWS サービスは決まっている。

ゆえに、Cloud Formation テンプレート内に隠したい文字列があるから使おう！という用途では使用できない。
また、セキュアストリングは Outputs で出力することはできない。

## どうしてもセキュアストリングを Cloud Formation で扱いたい

Secrets Manager を使いましょう。

## まとめ

AWS Systems Manager を扱うと運用を自動化したりセキュアな環境を維持したり
はたまた、特定のパラメータストアに値を保存することができる。

パラメータストアとは値を保管しておく場所のことである。

パラメータストアには平文、セキュアストリング、文字列リストを保存できる。
平文は暗号化されない文字列、セキュアストリングは暗号化される文字列であり
平文は見られても困らないモノにセキュアストリングは見られたくないモノに使う。

AWS SSM のパラメータストアで扱うセキュアストリングを CloudFormation で利用するときは
特定の AWS サービスにしか適用できず、また Outputs にも出力できない。

どうしてもセキュアストリングを扱いたい場合はパラメータストアのサービスである
AWS Secrets Manager を活用する。

## おわり
PennyLaneからqiskit simulator / ibmq を動かす

# PennyLaneからqiskit simulator / ibmq を動かす

PennyLaneからqiskitのsimulatorやibmq実機を操作できます。

# やり方

まず、プラグインを入れます。
`pip install pennylane-qiskit`


## simulator
simulatorの場合は簡単です。

```python
import pennylane as qml
dev = qml.device('qiskit.aer', wires=2, shots=1024)
```
とします。(backendも指定できます。unitary simulatorとか)

デモ回路を作ります。Bell状態です。

```python

@qml.qnode(dev)
def circuit():
    qml.Hadamard(wires=0)
    qml.CNOT(wires=[0,1])
    return qml.sample(qml.PauliZ(0)), qml.sample(qml.PauliZ(1))
```

`circuit()` 
とすると、

`array([[ 1,  1, -1, ...,  1, -1, -1],
       [ 1,  1, -1, ...,  1, -1, -1]])`
と返りました。第一量子ビットと第二量子ビットの出力が相関していますね。(Bell状態)

確率分布を出力することもできます。 returnを変えます。

```python
@qml.qnode(dev)
def circuit():
    qml.Hadamard(wires=0)
    qml.CNOT(wires=[0,1])
    return qml.probs(wires=[0,1])
```

`circuit()`

`tensor([0.46679688, 0.        , 0.        , 0.53320312], requires_grad=False)`

となります。tensorオブジェクトで返ってきた場合は、 .numpy() とかやればarrayに出来ます。

## 実機

実機の場合も要領は同じです。

最初にibmqアカウントをqiskitでロードします。qiskitをinstallした状態で、

```python
from qiskit import IBMQ
IBMQ.load_account()
```

です。事前にIBMQ.save_account をしておく必要があります。
その上で、
`dev = qml.device('qiskit.ibmq', wires=2, backend='ibmqx2')`

のようにしてやればOKです。なお、save/load accountを使わずに、tokenをこの場で指定して

`dev = qml.device('qiskit.ibmq', wires=2, backend='ibmqx2', ibmqx_token="Your token")`

としてもOKです。

実行してみると、



`c:\users\hogehoge\appdata\local\programs\python\python38\lib\site-packages\qiskit\providers\ibmq\api\clients\account.py:376: RuntimeWarning: coroutine 'WebsocketClient.get_job_status' was never awaited
  logger.info('Error checking job status using websocket, '
RuntimeWarning: Enable tracemalloc to get the object allocation traceback`

なんか怒られますが、実行は出来ていますので、のんびり待ちましょう。

# まとめ

PennyLaneからqiskitのsimulatorも実機も操作できる
- qiskitのdraw('mpl')が使いたいのだが、使い方がわからん。
Matrix RGB LEDを使おう ESP32編

Matrix RGB LEDを使おうのESP32編です。
ESP32でMatrixLEDを動かすライブラリや資料がいくつかありますが、今回は、以下を参考にしました。
___「ポータブル電光掲示板」を作ってみた ~ESP32×LED Matrixで日本語表示~___
http://ogimotokin.hatenablog.com/entry/2020/12/19/100000
___ESP32-HUB75-MatrixPanel-I2S-DMA___
https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA
##試作3回
ESP32版はNodeMCUとESP32-DevKitCで使用できるようにした結果、3種類製作することになりました。
初めにSTM32Nucleo版と同じサイズでNodeMCU対応のものを製作しました。(下）
しかし、やはり大きいため、小さいサイズのものを製作しました（左上）
最後に、ESP32-DevKitC対応のものを製作しました。(左上）
![DSC_0985 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/2ac68ee8-0f8a-b558-19fd-2b7eb8f383d2.jpeg)
##電源構成
ESP32はUSBと5V入力が直結しています。
この為、電源をどちらにもつなげると壊してしまいます。
ここがSTM32との大きな違いです。（STM32はUSBと5Vのジャックは分離しています）
使用する際は、ACアダプタを使用し、書き込みの際だけPCにつなぐようにしてください。
##回路図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/6441f04f-51d8-8522-ec06-4d46754318cc.png)
##ソフトウェア
HUB75 RGB LED matrix library utilizing ESP32 DMA Engineを使う事で写真のように表示できます。
![DSC_0983 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/1a818116-fee6-79a1-94d0-be3d6a3de4c0.jpeg)
##問題点
一点不具合がありました。
DCジャックから5Vを印加した際にノイズが載るのです。
USBからの場合問題がないため、5Vラインにノイズ対策としてキャパシタ(コンデンサ）を追加できるようにしています。
(DCジャック側のフューズにも入れられます）