OmniAICreator/Qiita-1.07M huggingface dataset:
Vue-CLI 3でnpm run serveが失敗するときの解決方法

## 事象
Dockerコンテナ内の環境にて、`npm run serve`を実行すると、下記のようなエラーが発生していました。

```bash
ERROR Failed to compile with 2 errors

This relative module was not found:

* ./src/main.js in multi (webpack)-dev-server/client/index.js (webpack)/hot/dev-server.js ./src/main.js, multi (webpack)/hot/dev-server.js (webpack)-dev-server/client/index.js ./src/main.js
```

### 環境
- Microsoft Windows 10 Pro
- Docker for Windows
- Visual Studio Code
- node.js : 12.18.2
- npm : 6.14.5

## 原因
筆者の場合、`npm install`を実行しても`package.json`内に含まれている`devDependencies`がインストールされておらず、必要なライブラリ（ここでは`@vue/cli-service`）が存在していなかったというのが原因でした。

## 解決策
node.js側の環境変数である`NODE_ENV`を`development`（あるいは`dev`）にしてから`npm install`を実行する必要がありました。

`NODE_ENV`を設定する方法は、①.コマンドラインから`export`する方法と、docker-composeを使っている場合は②.`docker-compose.xml`に記載する方法があります。

### ①.`export`コマンドで設定する
下記のコマンドで`NODE_ENV`に環境値を設定できます。

```bash
# NODE_ENVを設定
$ export NODE_ENV=development

# 設定した値を確認する
$ echo $NODE_ENV
development
```

### ②.`docker-compose.xml`のenvironmentキーに設定する
docker-composeでコンテナを立ち上げている場合、`environment`キーを使って設定することができます。

```yml
version: '3'
services:
  web:
    build: .
    ports:
      - "8080:8080"
    environment:
     - NODE_ENV=development
    tty: true
```

`export`で設定したときと同様に、`$NODE_ENV`をechoすると設定値を確認すると、`development`が設定されているのが確認できるはずです。

## 問題の原因を特定するには？

今回の場合、`package.json`に記載されているパッケージが正しくインストールできていると早とちりし、「パスが通っていない」か「windowsでシンボリックリンクが使えないのが悪さしている」と思い込んでいたのが、原因の特定が遅れてしまった原因でした。

ちなみに、パッケージが正しくインストールされているかは、`npm list --depth=0`で確認することができます。

```bash
# インストールされているパッケージの一覧（一階層のみ）を表示
$ npm list --depth=0
project@0.1.0 /app
+-- core-js@3.6.5
`-- vue@2.6.11
# core-js と vue しか入ってないやん！
```

もし、筆者と同様に`npm run serve`が正しく動作しない場合は、このコマンドで確認してみるといいかもしれません。
[SwiftUI]EnvironmentObjectとBinding

EnvironmentObjectを使って他のViewを更新しようとしましたが中々できなく、数時間ハマってしまいました。
解決方法を見つけたので書いてみました。

### どのような場合か

親View・子View・もう一つのViewの構成で、もう一つのViewから子Viewを更新したい時。

### 始めにやっていたこと

- 親View：EnvironmentObjectを持つ
- 子View：Stateを持つ
- もう一つのView：EnvironmentObject
- EnvironmentObjectとして`ObservableObject`を継承したクラスを使っていた

→もう一つのViewで値を変更しても、子Viewの値が更新されませんでした

### 解決策

- 親View：EnvironmentObjectを持つ
- 子View：Bindingを持つ
- もう一つのView：EnvironmentObject
- EnvironmentObjectとして`ObservableObject`を継承したクラス

→子ViewのStateを`Binding`に変更しました


### 実装

親View

```ContentView.swift
struct ContentView: View {

    @EnvironmentObject var countSetting: CountSetting
    
    var body: some View {
        NavigationView {
            List {
                NavigationLink.init(destination: AnotherView()) {
                    ChildView(value: Binding.init(get: { self.countSetting.count }, set: { _ in }))
                }
            }
        }
    }
}
```

ポイントは`Binding`でChildViewに値を渡しているところです。

子View

```ChildView.swift

struct ChildView: View {    
    @Binding var value: Int
```

EnvironmentObjectにするクラス

```CountSetting.swift
class CountSetting: ObservableObject {
    @Published var count: Int = 0
}
```

### ソース

ソースはこちら
https://gist.github.com/usk2000/95fdcd327c5fe22aa892d615721de0d9

### スクショ

|親View|もう一つのView|
|---|---|
|<img width="372" alt="スクリーンショット 2020-08-09 16.02.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297014/a752d747-46a0-bdf2-3ca1-65b645461672.png">|<img width="370" alt="スクリーンショット 2020-08-09 16.03.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297014/0bd3f2a6-35cf-ffeb-cd20-317d025a7393.png">|

もう一つのViewの「増やす」を押すと親Viewの「４」のところが変わります。


### 参考

https://qiita.com/shiz/items/6eaf87fa79499623306a#binding
https://stackoverflow.com/questions/59259921/binding-value-from-an-observableobject
iFacialMocap設定（StandAlone_Unityモード）

iFacialMocapはUnityを起動しないでもVRMモデルを動かせるモードがあるのでそちらの設定を記載します。

**<font color="Red">※（2021/03/07追記）現在は[VMagicMirror](https://booth.pm/ja/items/1272298)や[Luppet](https://luppet.appspot.com/)と手軽に連携ができるのでそちらの方が使い易くておすすめです**</font>


#01:インストール

**iPhone,PC両方**にアプリをインストール
https://www.ifacialmocap.com/download/


#02:設定
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684858/6babbec6-aa32-92a2-e783-454d23407d2a.png" width=30%>

❶PC側のアプリを開き**Open Advanced Setting**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684858/28bb468e-cb6a-3902-6769-5385e67b02e8.png" width=50%>

❷Software Nameを**StandAlone_Unity**に変更

❸使用するVRMモデルを選択

❹iPhone側のアプリを起動→IPアドレスを確認→PC側のアプリに入力
※PCとiPhoneが同じネット環境にある必要があります。
![S__89243650.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684858/e630873e-9cfc-a6b3-98b8-65f0b721310c.jpeg)


❺最後に**Connect**ボタンを押せばキャプチャが開始されます

❻ライティング設定
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">StandAlone_Unityモードでは、右クリックするとライト角度やライトの強度を変えるメニューが出てきます。画面を広げるとメニューの全体が表示されます。 <a href="https://t.co/YSJ8VlScvg">pic.twitter.com/YSJ8VlScvg</a></p>&mdash; iFacialMocap.jp (@Ifacialmocap_jp) <a href="https://twitter.com/Ifacialmocap_jp/status/1287675301950967808?ref_src=twsrc%5Etfw">July 27, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


❼設定の保存について
https://www.youtube.com/watch?v=M9XbgfqBsUs&t

#03:細かな設定

###目の動き
モデルによっては初期設定だと瞳が動きすぎてしまうので数値を調整します。
![2020-08-09_15h21_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684858/5371a6a8-953d-7c49-f1c6-236fc6ada970.png)


###体の動き
より動いてる感をアップさせるために、**headPosition**の数値を設定すると頭の位置に合わせて身体も動くようになります。
![2020-08-09_15h24_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684858/6b03b4c7-a3ab-6746-3664-f20a88a48ad2.png)

###表情追加
モデルのブレンドシェイプ名を記入→指定したショートカットで表情を切り替えることができます。

目を閉じた際、瞬きをさせたくない場合は**unUsed BS**に以下を記入します。（モデルによって閉じ目の名前が違う場合あり）
```eyeBlinkLeft,eyeBlinkRigh
```


![2020-08-09_15h31_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684858/05670d01-a78a-bc8a-5384-dcc693b48195.png)


▼表情記入例
https://qiita.com/take2_mbh/private/398272525b225b4facc9

##まぶた等の表情の挙動がおかしい場合

アプリ右側の「AdvancedSetting」で以下4項目に別の表情が割り当てられている恐れがあります。
eyeLookDownLeft
eyeLookInLeft
eyeLookOutLeft
eyeLookUpLeft

その場合は下の画像のように表情の記入欄を項目と同じ名前に書き換えてください。
![2021-02-04_20h43_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684858/dabbcbf8-926c-6c7e-4765-8960c3d738d4.png)
DNSSEC（DNS Security Extensions）の説明

平成31年春期 午前問題40

DNSSECについての記述のうち，適切なものはどれか。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/50b358f7-7a45-81fa-48fd-816a9657d7cf.png)

１、DNSSECは、DNS Security Extensionsの略で、
DNSにおける応答の正当性を保証するための拡張仕様です。DNSSECではドメイン応答にディジタル署名を付加することで、正当な管理者によって生成された応答レコードであること、また応答レコードが改ざんされていないことの検証が可能になります。

・DNSSECの導入はDNSキャッシュポイズニング攻撃への有効な対策となります。
・DNSSECは、ディジタル署名を利用するため、共通鍵暗号方式は採用されない。

・DNSは、　ドメインネームシステム(Domain Name System)。インターネット上のホスト名とIPアドレスを対応させるシステム。
・DNSSECは、　ディジタル署名によって DNS 応答の正当性を確認できる。
・IPsecは、　PCからサーバに対し、IPv6を利用した通信を行う場合、ネットワーク層で暗号化を行うのに利用する。
・ディジタル署名は、　受信者は、ハッシュ関数を用いてメッセージからハッシュ符号を生成し、送信者の公開鍵で復号したハッシュ符号と比較する。

・デジタル署名は公開鍵暗号を応用した技術でもあり、デジタル署名の仕組みのなかで公開鍵と秘密鍵も 登場します。ハッシュも使用しています。デジタル署名を実現できる方式にはRSAやDSAなどがあります。

２、DNSキャッシュポイズニング攻撃では、
攻撃者が偽の応答パケットをキャッシュサーバに送り込み、それをキャッシュサーバが受理してしまうことによって攻撃が成立するので、DNSSECの使用が根本的な対策になります。しかし、各DNSサーバのDNSSEC対応、電子署名に必要な鍵の管理や配布方法の確立、ルートやTLDの署名が必要なことなど、さまざまな課題があり、普及に当たっては今しばらく時間が必要です。

３、カミンスキー攻撃
カミンスキー攻撃は、標的のキャッシュサーバに、ランダムかつ大量に生成した偽のサブドメインのDNS情報を注入する攻撃である。

４、ソースポートランダマイゼーションとは、
クエリごとに、フルリゾルバ（いわゆるキャッシュDNSサーバー）が権威DNSサーバーに送るクエリパケットのソースポート番号をランダムに変化させることである。

５、DoS攻撃
DoS攻撃（ドスこうげき、英: Denial-of-service attack）は、情報セキュリティにおける可用性を侵害する攻撃手法のひとつ。

ウェブサービスを稼働しているサーバやネットワークなどのリソース（資源）に意図的に過剰な負荷をかけたり脆弱性をついたりする事でサービスを妨害する。

６、DDoS攻撃
フラッド型のDoS攻撃には、大量のマシンから1つのサービスに、一斉にDoS攻撃を仕掛けるDDoS攻撃（ディードスこうげき、分散型サービス妨害攻撃、英: Distributed Denial of Service attack）という類型がある。

DDoS攻撃は、複数のシステムを使用して、サーバー、ネットワークデバイス、またはトラフィックとリンクして、利用可能なリソースを圧倒し、正当なユーザーに応答できないようにする攻撃である[5]。


・DoS攻撃やキャッシュポイズニング攻撃を防止するための対策
DNSの再帰的な問合せの送信元として許可するクライアントを制限することによって，DNSを悪用したDoS攻撃を防止する。



参照：

https://www.ap-siken.com/kakomon/31_haru/q40.html


https://www.sc-siken.com/kakomon/24_aki/am2_18.html

http://itnavi.style-mods.net/question/sc24_2/sc24_2_18.htm

http://fast-macro.com/Johosyori/h31HaruOuyou/h31HaruOuyou-40.html


ソースポートランダマイゼーションとは何ですか？
https://www.atmarkit.co.jp/ait/articles/1501/05/news015.html#:~:text=%E3%82%BD%E3%83%BC%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%88%E3%83%A9%E3%83%B3%E3%83%80%E3%83%9E%E3%82%A4%E3%82%BC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E3%81%AF%E3%80%81%E3%82%AF%E3%82%A8%E3%83%AA%E3%81%94%E3%81%A8%E3%81%AB%E3%80%81%E3%83%95%E3%83%AB,%E5%A4%89%E5%8C%96%E3%81%95%E3%81%9B%E3%82%8B%E3%81%93%E3%81%A8%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82

デジタル署名とは
https://www.infraexpert.com/study/security5.html
Rails エラーメッセージを日本語で表示出来るようにする。

##概要
Railsではエラーメッセージの表示をする際に英語になっています。
日本語でエラーメッセージを表示するやり方について簡単に説明します。

日本語でエラーメッセージを表示する為には
日本語用の翻訳ファイルを作成する必要があります。

自分で作成することも可能ですが、
今回はGitHubのrails-I18nリポジトリに既に作成されている物を使う方法について説明します。


##1.翻訳ファイルをGitHubからダウンロード

※「・github　から直接コピーする」「・wgetでファイルごとコピーする」
↓2つのやり方を説明していますがどちらの手法を取っていただいても構いません。

・github　から直接コピーする
https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml
上記のURLにある内容をコピーして、自身のプロジェクトに '/locale/ja.yml' を作成して内容をペーストしてください。


・wgetでファイルごとコピーする

```:command

$ wget https://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml -P config/locales/

```

上記のコマンドをコピーしてターミナルで実行してあげればダウンロードされます。


##2.日本語を使う為に設定変更

デフォルトで日本語をつかうよ。ということを設定ファイルに記述します。

```rb:config/initializers/locale.rb

Rails.application.config.i18n.default_locale = :ja

```


以上で日本語の設定が終わりました。


##日本語の設定方法について

日本語を設定するやり方を説明します。

ダウンロードしたja.ymlに追加します。

```yml:ja.yml

---
ja:
  activerecord:
    errors:
      messages:
        ~
    # ここから追加↓
    attributes:
      user:
        name: 名前
        email: メールアドレス
        admin: 管理者権限
        password: パスワード
        password_confirmation: パスワード(確認用)
        created_at: 登録日時
        updated_at: 更新時間
    # ここまで追加↑
  date:
    ~

```

上記のような形式で日本語を設定してけば良いです。
【Android/Kotlin】インターネット接続の確認とNetworkInfo非推奨の解消

## 開発環境
* macOS 10.15.5
* Android Studio 4.0
* Kotlin 1.3.72

## やりたいこと
サーバーとの通信の前に端末がインターネットに接続されているかどうかを確認したい。


##`NetworkInfo`を使う方法

デベロッパーガイドの[接続ステータスの特定と監視](https://developer.android.com/training/monitoring-device-state/connectivity-monitoring?hl=ja)(2020/08/09アクセス)によると、`ConnectivityManager`を使用すれば、インターネットに接続されているか、接続されている場合はどのようなタイプかを確認できるそうです。

ということで、ボタンが押されると接続状況が確認され、接続のタイプを表示する簡単な実装を行いました。
(マニフェストファイルにパーミッションを追加するのを忘れないようにしましょう)

```AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
```

```MainActivity.kt
        val text = findViewById<TextView>(R.id.textView)
        val button = findViewById<Button>(R.id.button)

        button.setOnClickListener {
            val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            val activeNetwork: NetworkInfo? = cm.activeNetworkInfo
            val isConnected: Boolean = activeNetwork?.isConnectedOrConnecting == true
            val connectionType = activeNetwork?.type

            if (isConnected) {
                text.text = when (connectionType) {
                    ConnectivityManager.TYPE_WIFI -> "Wifiに接続しています"
                    ConnectivityManager.TYPE_MOBILE -> "モバイル通信に接続しています"
                    else -> "その他のネットワークに接続しています"
                }
            } else {
                text.text = "インターネットに接続していません"
            }
        }
```

以上のようにすればインターネットの接続が確認できますが、APIレベル29で`ConnectivityManager.getActiveNetworkInfo()` と `NetworkInfo`が非推奨となったため、AndroidStudioでは取り消し線が引かれてしまいます。
これを解消するために`NetworkInfo`クラスの代わりに`ConnectivityManager.getNetworkCapabilities()`を使うことにします。

## `ConnectivityManager.getNetworkCapabilities()`を使う方法
`NetworkCapabilities`はアクティブなネットワークの能力を表すクラスです。
以下のように実装できるかと思います。


```MainActivity.kt
        
        button.setOnClickListener {
            // ConnectivityManagerの取得
            val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            
            // NetworkCapabilitiesの取得
            // 引数にcm.activeNetworkを指定し、現在アクティブなデフォルトネットワークに対応するNetworkオブジェクトを渡している 
            val capabilities = cm.getNetworkCapabilities(cm.activeNetwork)
            
            if (capabilities != null) {
                text.text = when {
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ->
                        "Wifiに接続しています"
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ->
                        "モバイル通信に接続しています"
                    else -> "その他のネットワークに接続しています"
                }
            } else {
                text.text = "インターネットに接続していません"
            }
        }
```
*`NetworkCapabilities`はAPI21、`ConnectivityManager.getActiveNetwork()`API23で追加されたので、APIレベル23以上必要です

## 参考


* はてなブログの記事 「[Android 10 時代の Connectivity Monitoring](https://takasfz.hatenablog.com/entry/2019/07/04/191744) 」(2020/08/09アクセス)
* [Android - ネットワーク（WIFI）の接続状態を確認し、変更の検出](https://codechacha.com/ja/android-network-state/) 
 (2020/08/09アクセス)

を参考にさせていただきました。
VM、コンテナ、Kubernetes、Fargateの関係メモ

# VMware時代の構造
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87538/115c2b99-0de3-58f8-616f-72b93140c983.png)
[引用元:ニフクラ](https://pfs.nifcloud.com/vmware/about_vmware.htm)

OSの上にVMWareを立てて、OSをさらに上に立てる。

# コンテナ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87538/dc4deecc-e066-739c-d73e-dc2ac979c04b.png)
[引用元:Docker What Container](https://www.docker.com/resources/what-container)

### 役割
OSの上に仮想環境を構築できる。
構築イメージを設定ファイルとして出力できる。
設定ファイルは配布できる。

VMWareのように仮想OSを立てないため、軽量。


### 実装
Docker

# Kubernates
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87538/7c764d8c-b07d-ffd2-8a4e-dd2b337e538a.png)
[引用元：what-is-kubernetes](https://kubernetes.io/ja/docs/concepts/overview/what-is-kubernetes/)

コンテナオーケストレーション。

クラスター　∈　ノード
クラスター　∈　Pod ∈ コンテナ

Pod単位でCPUリソースやメモリリソースを割り当てる設定が必要。

### よく見かけた話題
* 学習コストが高い

### 類似サービス
ECS,(EKS = Kubernates)

# Fargate(AWS)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87538/2e769ed1-8dd8-850f-ae5b-ba2c5551cd1c.png)
[引用元：Amazon EKS と Fargate の統合](https://aws.amazon.com/jp/blogs/news/the-role-of-aws-fargate-in-the-container-world/)

サーバレスコンテナーというサーバやクラスタを意識しない方式。

# AWSにおいて、何を使うか。
1. Fargate × ECS
2. Fargate × EKS
3. EC2 × ECS
4. EC2 × EKS
という具合に下に下がるほどカスタマイズ性が高まると理解。
AWSロックインを嫌気するなら、3,4から選択か。
Railsのデータの型について

#Railsのデータの種類について
データ型のカラムの種類を何を使っていいのだろうかとよく考える事があったので備忘録。
##migrationに追加できるカラム
|型                  |        説明        |             用途    |
|:-------------------:|:------------------:|:------------------:|
|string	| 文字（255文字まで）|名前やメールアドレスなど短い文字|
|text	|長い文章	|ブログの記事や投稿される内容|
|integer|	整数（4byte）|	通常使用する範囲の整数で保存したいとき|
|smallint|	整数（2byte）|	狭範囲の整数で保存するとき|
|bigint|整数（8byte）	|かなり大きな整数で保存する可能性があるとき|
|float	|浮動小数点数	|小数点を含めた数値を保存したいとき|
|numeric|	固定長整数|	桁の大きな数を桁数などを指定して保存したいとき|
|boolean|	真か偽か	|trueかfalseで保存したいとき|
|time	|時刻型|	時刻を「12:00:00」の形で保存したいとき|
|date	|日付型|	日付を「2001-01-01」の形で保存したいとき|
|datetime|	日時型	|日時を「2001-01-01 01:01:00」の形で保存したいとき|
|json	|json型	|JSONとして保存したいとき|
|binary	|バイナリ文字列型	|画像ファイルなどバイナリデータとして保存したいとき|
|references|	外部キーの定義	|外部キーを追加したいとき|

以上
Ubuntu18.04 WordPressのパーマリンクを設定すると「返答が正しい JSON レスポンスではありません」のエラーで記事が保存できない問題

# 環境
- Ubuntu 18.04
- Apache2
- WordPress 5.4.2

# 問題の概要
WordPress管理画面の設定で「パーマリンク」を「基本」以外に設定したところ、記事を下書き/公開しようとしたときに「返答が正しい JSON レスポンスではありません」というエラーメッセージが出て保存できない不具合に遭遇し、小一時間格闘しました。

# 結論
Apache2でmod_rewriteモジュールを有効化したところ解決しました。
パーマリンクを有効にする場合、ApacheでURLをリライトするようですが、モジュールがないので処理がエラーになっていたようです。

# 方法
```bash
sudo a2enmod rewrite
sudo systemctl restart apache2
```
これだけです。
初期でリライトモジュールが有効になっていないというのも驚きですね。。
【個人メモ】Python の仮想環境コマンドメモ

# What
Python の仮想環境とコマンドについてのメモ。
参考になる立派な記事はたくさんあるので、あくまで自分の環境での内容を忘れないようにメモしておく。
他の方の参考になるのであれば嬉しい。

### 環境
- Mac OS Mojave 10.14.6

# 仮想環境あれこれ
### pyenv
複数バージョンの Python を共存させることができる。
例えば、Python 3.8.3 と Python 3.7.2 をPCにインストールし、
デフォルト（global）は Python 3.7.2 だが、特定ディレクトリのみ Python 3.8.3 にする。といったこともできる。

### virtualenv
同一バージョンの Python で、複数の環境を構築することができる。
例えば、 
環境Aには、Python 3.7.2 + TensorFlow
環境Bには、Python 3.7.2 + Keras
といった環境を個別に作れる。

### venv
Python に標準搭載された仮想環境のプログラム。
virtualenv の方がコマンド操作などわかりやすい気がする。
（個人としては venv ではなく virtualenv を使うこととする。）

### conda
Anaconca に含まれる仮想環境プログラム
（学習不足で多くを語れません。機会を改めて...）


# 環境構築メモ
## pyenv の導入方法

- Homebrew をインストールしたあとに、pyenv をインストールする方法がある
    - 以下のProgate のチュートリアルサイトが便利
    - [Pythonの開発環境を用意しよう！（Mac） | プログラミングの入門なら基礎から学べるProgate[プロゲート]](https://prog-8.com/docs/python-env)
- git clone してインストールする方法もある
    - [Python 仮想環境 | pyenv と vertualenv による Python の開発環境の構築](https://bi.biopapyrus.jp/python/pyenv.html)

## pyenv コマンド一覧
```bash
## インストールできる Python バージョンの確認
pyenv install --list

## 特定バージョンの Python のインストール
pyenv install 3.7.2

## インストールされた Python バージョンの確認
pyenv versions
# * system (set by /Users/username/.pyenv/version)
#   3.7.2
#   3.8.3

## インストールされた Python の実体は、~/.pyenv/versions/ ディレクトリの下に保存される
cd ~/.pyenv/versions
ls
# 3.7.2    3.8.3

## PC全体で使う、デフォルトの Python のバージョンを指定
pyenv global 3.7.2

## pyenv versions コマンド か python -V コマンドでバージョンの確認が取れる
pyenv versions
#   system
# * 3.7.2 (set by /Users/username/.pyenv/version)
#   3.8.3

## 特定ディレクトリのみ Python のバージョンを変える方法 （localにする）
cd ./sample
pyenv local 3.8.3

## pyenv verions コマンド か python -V コマンドでバージョンの確認が取れる
python -V
# Python 3.8.3

## 仮想環境の削除
pyenv uninstall 3.7.2
```

## virtualenv の導入方法
- pip install するのが一般的　注：pyenvからインストールする方法もある（後述）


```bash
## virtualenv のインストール方法
pip install virtualenv

## 仮想環境の作成と利用 （作成先はどこでも可）
virtualenv ~/.virtualenvs/first-env
source ~/.virtualenvs/first-env/bin/activate

## 仮想環境の無効化
deactivate

## 仮想環境の削除
rm -rf ~/.virtualenvs/first-env
```

- 【注意】
    - pyenv で新しいバージョンの Python 環境を作成した際は、virtualenv もインストールをし直さなければならない。

## virtualenv 補足
- 以下のサイトでは、pyenv からvirtualenvをインストールしている。便利そう。
    - [Python 仮想環境 | pyenv と vertualenv による Python の開発環境の構築](https://bi.biopapyrus.jp/python/pyenv.html)
- ただし、Homebrew を用いて pyenv をインストールした筆者の環境では、`pyenv virtualenv 3.7.2 project_x` というコマンドは出来なかった。``（pyenv: no such command `virtualenv'）``
    - 原因等が分かったら追記します。
関数内関数(inner function)とは？

はじめまして、こんにちは。

***この記事がなんと初投稿です！🎉***

Pythonを初めて間もなく、間違った解釈をしてしまうかもしれませんが、皆さんの参考になればと思います。
もちろん間違った説明のないように細心の注意を払って文章を書いていきます。

では、早速タイトルにもあるように関数内関数について説明していきます。
<h2>関数内関数とは？

関数内関数はその文字の通り、関数の中に関数が入っていることです。
本当に名前のまんまです笑

イメージとしてはマトリョーシカみたいに人形の中に人形が入っているみたいな感じです。

<h2>実際にコードを書いて見ていきましょう

説明だけでは分かりにくいと思うので、実際にコードを使って見ていきましょう。

```python:qita.py
def outer(a,b):
    def inner(c,d):
        return c - d
    r = inner(a,b)
    print(r)
outer(3,2)
```
```
実行結果
3 - 2 = 1
1
```

名前の通り関数の中にさらに関数を定義されていますね！

<h2>どのようにプログラムが動いているのか見ていきましょう！

①１行目で外側のouter関数を宣言しています。そして３と２がouter関数のa,bに入ってきます。

②２行目で内側のinner関数を宣言しています。
inner関数は、c-d をして返す関数になっています。outer関数に入った３と２がinner関数でも定義されています。

③そして、返り値をｒに入れてあげて出力しています。
printすると、１が出力されます。

というのが一連の流れです。

<h2>何のために関数内関数を使うの？

ここで疑問に思うことが何のために関数内関数を使うのかと言うことです。

大きく分けると２つあります。
***「その処理を関数の中でしか使いたくないとき」と「その処理を別の関数から呼ばれないようにしたいとき」です。***

なんか束縛の強い彼氏みたいな感じですね！笑

以上が関数内関数の説明でした！

<h2>最後に

本日は最後まで見ていただきありがとうございました！
どちらかというと理系の人間ですので、文章を書ことがこんなに難しいのかと驚いています。

これからもプログラミングで覚えた用語やコードなど覚えたらここでアウトプットしていこうと思うので是非見てくださいね！

では、ばいばい😊
AtCoder Beginner Contest 174

##[A - Air Conditioner](https://atcoder.jp/contests/abc174/tasks/abc174_a)

```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define pai 3.1415926535897932384
 
using namespace std;
using ll =long long;
using P = pair<int,int>;
 
int main(int argc, const char * argv[]) {
    
    int X;
    cin >> X;
    
    if(X>=30) cout << "Yes" << endl;
    else cout << "No" << endl;
    
    return 0;
}
```

##[B - Distance](https://atcoder.jp/contests/abc174/tasks/abc174_b)

- 少数で何かあるといけないからPythonを使用

```Python:Python
import math
 
N, D = list(map(int, input().split()))
 
c=0
for i in range(0, N):
    X, Y = list(map(int, input().split()))
    if math.sqrt(X * X + Y * Y) <= D:
        c+=1
    
print(c)
```

##[C - Repsept](https://atcoder.jp/contests/abc174/tasks/abc174_c)

- 計算途中で余りを求めても同じ結果を返す法則があります

```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define pai 3.1415926535897932384
 
using namespace std;
using ll =long long;
using P = pair<int,int>;
 
int K;
 
int main(int argc, const char * argv[]) {
    
    cin >> K;
    
    ll c=0;
    ll num=7;
    while(c<=K){
        c++;
        if(num%K==0){
            break;
        }
        num = num%K;
        num = (num * 10 + 7);
    }
    
    if(num%K==0) cout << c << endl;
    else cout << "-1" << endl;
    
    return 0;
}
```

##[D - Alter Altar](https://atcoder.jp/contests/abc174/tasks/abc174_d)

- 最後の要素からswapするだけです

```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define pai 3.1415926535897932384
 
using namespace std;
using ll =long long;
using P = pair<int,int>;
 
char c[200000];
 
int main(int argc, const char * argv[]) {
    
    int N;
    cin >> N;
    cin >> c;
    
    int w=0;
    int count=0;
    for(int i=N-1; i>0; i--){
        if(c[i] == 'R'){
            while(w<N&&i>w){
                if(c[w]=='W'){
                    c[w] = c[i];
                    c[i] = 'W';
                    count++;
                    break;
                }
                w++;
            }
        }
    }
    
    cout << count << endl;
    
    return 0;
}
```
【Python】データサイエンス100本ノック（構造化データ加工編） 023 解説

- データサイエンス100本ノックをやりきる会を作りました🎉
- こちらの[Slack招待URL](https://join.slack.com/t/data-science-100nocks/shared_invite/zt-gfncg9vm-8W8b3UrDg8R~TKaqUkQpgw)からご参加ください！！
- ぜひ一緒に励まし合いながら、データサイエンス100本ノックをやり切りたいと思っています！

##Youtube
[動画解説](https://youtu.be/I6MR3NGgiL8)もしています。

##問題
P-023: レシート明細データフレーム（df_receipt）に対し、店舗コード（store_cd）ごとに売上金額（amount）と売上数量（quantity）を合計せよ。

##解答
```:コード
df_receipt.groupby('store_cd').agg({'amount':'sum', 'quantity':'sum'}).reset_index()
```

##出力
|  | store_cd | amount | quantity |
|--:|:--|--:|--:|
| 0 | S12007 | 638761 | 2099 |
| 1 | S12013 | 787513 | 2425 |
| 2 | S12014 | 725167 | 2358 |
| 3 | S12029 | 794741 | 2555 |
| 4 | S12030 | 684402 | 2403 |
| 5 | S13001 | 811936 | 2347 |
| 6 | S13002 | 727821 | 2340 |
| 7 | S13003 | 764294 | 2197 |
| 8 | S13004 | 779373 | 2390 |
| 9 | S13005 | 629876 | 2004 |
| 10 | S13008 | 809288 | 2491 |
| 11 | S13009 | 808870 | 2486 |
| 12 | S13015 | 780873 | 2248 |
| 13 | S13016 | 793773 | 2432 |
| 14 | S13017 | 748221 | 2376 |
| 15 | S13018 | 790535 | 2562 |
| 16 | S13019 | 827833 | 2541 |
| 17 | S13020 | 796383 | 2383 |
| 18 | S13031 | 705968 | 2336 |
| 19 | S13032 | 790501 | 2491 |
| 20 | S13035 | 715869 | 2219 |
| 21 | S13037 | 693087 | 2344 |
| 22 | S13038 | 708884 | 2337 |
| 23 | S13039 | 611888 | 1981 |
| 24 | S13041 | 728266 | 2233 |
| 25 | S13043 | 587895 | 1881 |
| 26 | S13044 | 520764 | 1729 |
| 27 | S13051 | 107452 | 354 |
| 28 | S13052 | 100314 | 250 |
| 29 | S14006 | 712839 | 2284 |
| 30 | S14010 | 790361 | 2290 |
| 31 | S14011 | 805724 | 2434 |
| 32 | S14012 | 720600 | 2412 |
| 33 | S14021 | 699511 | 2231 |
| 34 | S14022 | 651328 | 2047 |
| 35 | S14023 | 727630 | 2258 |
| 36 | S14024 | 736323 | 2417 |
| 37 | S14025 | 755581 | 2394 |
| 38 | S14026 | 824537 | 2503 |
| 39 | S14027 | 714550 | 2303 |
| 40 | S14028 | 786145 | 2458 |
| 41 | S14033 | 725318 | 2282 |
| 42 | S14034 | 653681 | 2024 |
| 43 | S14036 | 203694 | 635 |
| 44 | S14040 | 701858 | 2233 |
| 45 | S14042 | 534689 | 1935 |
| 46 | S14045 | 458484 | 1398 |
| 47 | S14046 | 412646 | 1354 |
| 48 | S14047 | 338329 | 1041 |
| 49 | S14048 | 234276 | 769 |
| 50 | S14049 | 230808 | 788 |
| 51 | S14050 | 167090 | 580 |

##解説
・PandasのDataFrame/Seriesにて、同じ値を持つデータをまとめて処理する方法です。
・同じ値を持つデータの合計や平均などを確認したい時に使用します。
・**'groupby'は、同じ値や文字列を持つデータをまとめて、それぞれの同じ値や文字列に対して、共通の操作を（合計や平均など）行いたい時に使います。**
・**'agg'は、Aggregationの略称(意味は"集合体")であり、グループごとに値を求めて表を作るような操作を行いたい時に使います。**合計値は'sum'、平均値は'mean'、最大値は'max'、最小値は'min'です。
・**'.reset_index()'は、'groupby'によってバラバラになったインデックス番号を0始まりの連番に振り直す操作を行いたい時に使います。**
【homebridge】Siriからラズパイでエアコンを操作したい 準備編

PHPコマンドを打ってならエアコンを操作できる([こちらを参照](https://qiita.com/yktk435/items/dabc790d6335e90dd416))ので、今度は音声入力でエアコンが着くようにしたい
Hey Siriで起動させたいからラズパイにhomebridgeをインストールする。
 


#ラズパイをアップデート
例によってコマンドでアップデートする。
cronで一日一回更新するようにしておくと便利

#gccバージョンの確認

```bash
$g++ -v
...
gcc version 8.3.0 (Raspbian 8.3.0-6+rpi1)
```
4.9.2以上であることを確認
#Node.jsをインストール
homebridgeはjavascriptで書かれているためNode.jsをインストールする
##ラズパイのチップ名を確認
```bash
$uname -a
Linux raspberrypi 5.4.51-v7+ #1327 SMP Thu Jul 23 10:58:46 BST 2020 armv7l GNU/Linux
```
armv7以降なので[Distributions(GitHub)](https://github.com/nodesource/distributions/blob/master/README.md)に従い最新安定版をインストールする

今回はバージョン12以降をインストールするからコマンドはこうなる

```bash
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt-get install -y nodejs
```
#Avahiをインストール
```bash
sudo apt-get install libavahi-compat-libdnssd-dev
```

#homebridge
##インストール
[homebridge公式ページ](https://github.com/homebridge/homebridge)に従いインストールしていく
Installation Detailsに記載されているコマンドを実行してインストールする

```bash
$sudo npm install -g --unsafe-perm homebridge
/usr/bin/homebridge -> /usr/lib/node_modules/homebridge/bin/homebridge
+ homebridge@1.1.1
added 70 packages from 78 contributors in 22.233s
```
これによりhomebridgeのバイナリは`/usr/lib/node_modules/homebridge`にリンクされる
##起動
オフィシャルサイトに従って以下のコマンドを実行

```bash
$ homebridge
```
するとkQRコードが表示されてうまく起動していることが確認できる。

ひとまずここまでにしておきます

#参考
[ラズパイ(Raspberry Pi)にhomebridgeをインストールする方法](https://www.apollomaniacs.com/ipod/howto_homekit_raspberrypi_homebridge.htm)
さくっとDenoを試してみる

# Denoの特徴
- JavascriptとTypescriptの実行環境
- Typescriptのコンパイラを内包している(tsc-,ts-nodeなど不要)
- 標準ライブラリーは非同期処理にPromiseを採用
- 実行時に必要な権限のオプション指定が必要
- モジュールの扱いがNode.jsと異なる
- etc

##  環境構築

### Docker
こちらのイメージを使用します。
https://hub.docker.com/r/hayd/deno

```dockerfile:Dockerfile
FROM hayd/alpine-deno:1.2.2

# Prefer not to run as root.
USER deno

# Cache the dependencies as a layer (the following two steps are re-run only when deps.ts is modified).
# Ideally cache deps.ts will download and compile _all_ external files used in main.ts.
COPY deps.ts .
RUN deno cache deps.ts

# These steps will be re-run upon each file change in your working directory:
ADD . .
# Compile the main app so that it doesn't need to be compiled each startup/entry.
RUN deno cache main.ts
```

```yaml:docker-compose.yaml
version: '3'
services:
  app:
    build: .
    command: "run --allow-net --allow-read main.ts"
    ports:
      - "8000:8000"
    volumes:
      - .:/app
    working_dir: "/app"

```

### HelloWorld
```typescript:main.ts
import { serve } from "./deps.ts";

const PORT =8000;
const s = serve(`0.0.0.0:${PORT}`);
const body = new TextEncoder().encode("Hello World\n");

console.log(`Server started on port ${PORT}`);
for await (const req of s) {
  req.respond({ body });
}

```

```shell
$ docker-compose up -d
```

## APIの作成
Servestを使用
https://github.com/keroxp/servest

```typescript:main.ts
import { createApp } from "https://servestjs.org/@v1.0.0/mod.ts";
const app = createApp();
app.handle("/", async (req) => {
  await req.respond({
    status: 200,
    headers: new Headers({
      "content-type": "text/plain",
    }),
    body: "hello World!",
  });
});
app.listen({ port:8000 });

```

# 参考
https://qiita.com/ryo2132/items/8b957ed8b649f941fc3f

https://knowledge.sakura.ad.jp/24150/
M-SOLUTIONS プロコンオープン 2020

##[A - Kyu in AtCoder](https://atcoder.jp/contests/m-solutions2020/tasks/m_solutions2020_a)

```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define pai 3.1415926535897932384
 
using namespace std;
using ll =long long;
using P = pair<int,int>;
 
int main(int argc, const char * argv[]) {
    int X;
    cin >> X;
    
    X = X-400;
    for(int i=1; i<=8; i++){
        if(X-i*200<0){
            cout << 8-(i-1) << endl;
         	break;
        }
    }
    
    return 0;
}
```

##[B - Magic 2](https://atcoder.jp/contests/m-solutions2020/tasks/m_solutions2020_b)

```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define pai 3.1415926535897932384
 
using namespace std;
using ll =long long;
using P = pair<int,int>;
 
int num;
bool large=false;
 
void dfs(int red, int green, int blue, int count){
    if(count > num) return;
    
    if(red < green && green < blue) large=true;
    
    dfs(red * 2, green, blue, count+1);
    dfs(red, green * 2, blue, count+1);
    dfs(red, green, blue * 2, count+1);
}
 
int main(int argc, const char * argv[]) {
    int red, green, blue;
    
    
    cin >> red >> green >> blue;
    cin >> num;
    
    dfs(red, green, blue, 0);
    
    if(large) cout << "Yes" << endl;
    else cout << "No" << endl;
    
    return 0;
}
```

##[C - Marks](https://atcoder.jp/contests/m-solutions2020/tasks/m_solutions2020_c)

- A0 + A1 + A2 と A1 + A2 + A3を比較するとして、
- 両辺の共通項目を削除
- A0とA3だけ比較すると答えが出る事が分かる

```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>

#define rep(i,n) for(int i=0; i<(n); ++i)
#define pai 3.1415926535897932384

using namespace std;
using ll =long long;
using P = pair<int,int>;

ll A[200001];
ll T[200001];

int main(int argc, const char * argv[]) {
    int N, K;
    cin >> N >> K;
    for(int i=0; i<N; i++){
        cin >> A[i];
    }
    
    for(int i=0; i+K<N; i++){
        if(A[i] < A[i+K]){
            cout << "Yes" << endl;
        }else{
            cout << "No" << endl;
        }
    }
        
    return 0;
}
```
HOMING設定


#Neje Master2でGRBL_esp32を使う
##HOMING用設定

###config.hの下記を変更

下記をコメント外す
 #define HOMING_FORCE_SET_ORIGIN // Uncomment to enable.
 #define HOMING_FORCE_POSITIVE_SPACE // Uncomment to enable.

下記を修正
 #define HOMING_CYCLE_0 bit(Z_AXIS)	// TYPICALLY REQUIRED: First move Z to clear workspace.
  #define HOMING_CYCLE_1 bit(X_AXIS)
  #define HOMING_CYCLE_2 bit(Y_AXIS)
これを
 // #define HOMING_CYCLE_0 bit(Z_AXIS)	// TYPICALLY REQUIRED: First move Z to clear workspace.
   #define HOMING_CYCLE_0 bit(X_AXIS)
   #define HOMING_CYCLE_1 bit(Y_AXIS)

下記コメントアウト
// #define HOMING_SINGLE_AXIS_COMMANDS // Default disabled. Uncomment to enable.

###Z軸homingのキャンセル
machinesフォルダ内の3axis_v4.hファイルの以下を修正
 #ifdef HOMING_CYCLE_0
    #undef HOMING_CYCLE_0
 #endif
 #define HOMING_CYCLE_0 bit(Z_AXIS) // Z first

 #ifdef HOMING_CYCLE_1
    #undef HOMING_CYCLE_1
 #endif
 #define HOMING_CYCLE_1 (bit(X_AXIS)|bit(Y_AXIS))

 #ifdef HOMING_CYCLE_2
    #undef HOMING_CYCLE_2
 #endif

これを

 //#ifdef HOMING_CYCLE_0
 //   #undef HOMING_CYCLE_0
 //#endif
 //#define HOMING_CYCLE_0 bit(Z_AXIS) // Z first

 #ifdef HOMING_CYCLE_0
    #undef HOMING_CYCLE_0
 #endif
 #define HOMING_CYCLE_0 (bit(X_AXIS)|bit(Y_AXIS))

 #ifdef HOMING_CYCLE_1
    #undef HOMING_CYCLE_1
 #endif

これでホーミングボタン1発でホーミングサイクルが開始される
Node.js の再インストール



Nodeがおかしくなった

```

$ node
Illegal instruction
```

# 環境


2020-02-13-raspbian-buster-lite

# 既存の Node.js 

「Linux 環境に Node.js インストール」
https://qiita.com/nanbuwks/items/ed8adb2d4324c939a349
の通り、以下のようにインストール

1.Linux ディストリビューションの公式パッケージで Node.js と npm を入れる
2.npm install で最新の Node.js を入れる
3.古い Node.js を削除する

# 削除

node のインストール先を調べる

```

$ which node
/usr/local/bin/node
```

ファイル削除

```

$ sudo rm -rf /usr/local/bin/node
sudo rm -rf ~/.npm

```
削除できたかな？

```
$ npm
/usr/bin/env: ‘node’: No such file or directory

```

このあと、先の資料「Linux 環境に Node.js インストール」をもう一度実行して入れ直します。
JavaのStream APIとSQLに関するメモ

JavaのStream APIとSQLの対比に関するメモ。

# Streamの公式ドキュメント
Java8の公式ドキュメントの内容を抜粋。
https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Stream.html

>
順次および並列の集約操作をサポートする要素のシーケンスです。
（中略）
コレクションとストリームは、表面上似た点があるものの、異なる目的を持っています。コレクションは主に、要素の効率的な管理やアクセスに注力しています。これに対し、ストリームは要素の直接アクセスや操作の手段を持たず、代わりにソースやそのソースに対して集約的に実行される計算操作を宣言的に記述することに注力しています。
（中略）
ストリーム・パイプラインは順次、並列のいずれかで実行できます。この実行モードは、ストリームのプロパティの1つです。ストリームの作成時には、順次実行または並列実行の初期選択が行われます。

僕の理解が足りなくてドキュメント読んでも分かりにくいですが、ざっくり書くとこんなもの。

- コレクションと似ている
- 集約操作を行う
- 要素の直接アクセスや操作（get, remove）をするものではない
- 処理を順次・並列で選択できる

集約操作はSQLをイメージしてもらえれば理解は速くなります。

# Stream APIとSQLの対比一覧
|Stream API|対応するSQL|説明|
|:---|:---|:---|
|Stream#map|SELECT|Stream内の要素を別の値やオブジェクトに変換する操作|
|Stream#filter|WHERE|条件に一致したデータのみにフィルタリングする操作。引数にはbooleanが戻り値となる式を書くことが必要。|
|Stream#max|MAX|最大値の取得|
|Stream#min|MIN|最小値の取得|
|IntStream#sum<br/>Collectors#summingInt|SUM|合計の取得|


# サンプルコード

# 前提条件
- lombok プラグインが導入されている前提
- スコープは適当

## 人物データとクラス
人物データを格納するテーブルとそのデータを保持するクラスを以下のように定義する。

■Personテーブル

|id|name|age|job|
|---:|:---|---:|---:|
|1|yamada|25|---:|
|2|suzuki|28|---:|
|3|sato|30|---:|
|4|nakamura|41|---:|
|5|yamamoto|38|---:|
|6|akiyama|22|---:|
|7|tanabe|43|---:|
|8|ito|24|---:|


■Personクラス

```java:Persion.java
@Data
@AllArgsConstructor
public class Person {
    private int id;
    private String name;
    private int age;
}
```

更にPersonテーブルの全データを格納したリストを`List<Person> `として定義する。
`List<Person> `は以下と同義である。

```java
List<Person> personList = Arrays.asList(
    new Person(1, "yamada", 25),
    new Person(2, "suzuki", 28),
    new Person(3, "sato", 30))
    new Person(4, "nakamura", 41))
    new Person(5, "yamamoto", 38))
    new Person(6, "akiyama", 22))
    new Person(7, "tanabe", 43))
    new Person(8, "ito", 24))
);
```


## Stream#map
```java:Java
List<String> nameList = personList.stream()
        .map(Person::getName)
      .collect(Collectors.toList()); 
```

```sql:SQL
SELECT
  p.name
FROM
  Person p

```
＜結果＞
 ["yamada", "suzuki", "sato", "nakamura, "yamamoto", "akiyama", "tanabe", ito]

## Stream#filter

```java:Java
List<String> nameList = personList.stream()
        .filter(p -> p.getAge() >= 40)
        .map(Person::getName)
        .collect(Collectors.toList()); 
```

```sql:SQL
SELECT
  p.name
FROM
  Person p
WHERE
  p.age >= 40 
```
＜結果＞
 ["nakamura", "tanabe"]


## Stream#max

```java:Java
Integer max = personList.stream()
        .map(Person::getAge)
        .max(Comparator.comparingInt(x -> x))
        .orElse(null);
```

```sql:SQL
SELECT
  max(p.age) max_age
FROM
  Person p
```
＜結果＞
43

## Stream#min

```java:Java
Integer max = personList.stream()
        .map(Person::getAge)
        .min(Comparator.comparingInt(x -> x))
        .orElse(null);
```

```sql:SQL
SELECT
  min(p.age) min_age
FROM
  Person p
```
＜結果＞
22


## IntStream#sum／Collectors#summingInt

```java:Java
int sum = personList.stream()
        .mapToInt(Persion::getAge)
        .sum();

int sum2 = personList.stream()
        .collect(Collectors.summingInt(Persion::getAge));
```

```sql:SQL
SELECT
  sum(p.age) sum_age
FROM
  Person p
```

＜結果＞
251
エイシング プログラミング コンテスト 2020

##[A - Number of Multiples](https://atcoder.jp/contests/aising2020/tasks/aising2020_a)

```Python:Python
import queue
from math import floor
from decimal import Decimal
 
L, R, d = list(map(int, input().split()))
 
c=0
for i in range(L, R+1):
    if i % d == 0:
        c+=1
 
print(c)
```

##[B - An Odd Problem](https://atcoder.jp/contests/aising2020/tasks/aising2020_b)

```Python:Python
N = int(input())
A = list(map(int, input().split()))
 
c = 0
for i in range(N):
    if (i + 1) % 2 == 1 and A[i] % 2 == 1:
        c+=1
print(c)
```

##[C - XYZ Triplets](https://atcoder.jp/contests/aising2020/tasks/aising2020_c)

- 力技の全探索
- 計算式から各項目、ループの許容値が分かる

```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define pai 3.1415926535897932384
 
using namespace std;
using ll =long long;
using P = pair<int,int>;
 
int N;
int N_array[10001];
 
int main(int argc, const char * argv[]) {
    
    
    cin >> N;
    
    for(int x=1; x*x<=N; x++){
        for(int y=1; x*x+y*y+x*y<=N; y++){
            for(int z=1; z<=N; z++){
                ll ans = x*x + y*y + z*z + x*y + y*z + z*x;
                if(ans <= N){
                    N_array[ans]++;
                }
            }
        }
    }
    
    for(int i=1; i<=N; i++){
        cout << N_array[i] << endl;
    }
    
    return 0;
}
```
Linux 環境に Node.js インストール

いろんな Linux 環境に Node.js をインストールした記録

# 方針

「Ubuntuに最新のNode.jsを難なくインストールする」
https://qiita.com/seibe/items/36cef7df85fe2cefa3ea 
を参考に、以下の方法を採ることにした。

1. Linux ディストリビューションの公式パッケージで Node.js と  npm を入れる
1. npm install で最新の Node.js を入れる
1. 古い Node.js を削除する



# 検証環境

- Ubuntu14.04 (2020/07に実行)
- Ubuntu18.04 (2020/08に実行)
- Ubuntu20.04 (2022/01に実行)
- Ubuntu22.04 (2024/06似実行)
- 2020-02-13-raspbian-buster-lite (2020/07に実行)
- 2020-12-02-raspios-buster-armhf-lite (2021/01に実行)
- 2021-01-11-raspios-buster-armhf-lite (2021/03に実行)
- Raspberry Pi OS Lite Release date: April 4th 2022 (2022/08に実行)


#  Linux ディストリビューションの公式パッケージで Node.js と  npm を入れる


```

$ sudo apt update
$ sudo apt install nodejs npm
$ sudo node -v 

```

この時点でインストールされるバージョンは、以下のとおりだった。

- Ubuntu18.04 だと v8.10.0
- Ubuntu20.04 だと v10.19.0
- RaspberryPi 2020-02-13-raspbian-buster-lite だと v10.21.0
- RaspberryPi 2020-12-02-raspios-buster-armhf-lite だと v10.23.1 
- RaspberryPi 2021-01-11-raspios-buster-armhf-lite だと v10.24.0
- Raspberry Pi OS Lite Release date: April 4th 2022 だと v12.22.12


# npm install で最新の Node.js を入れる

```

$ sudo npm install n -g

```

## Ubuntu14.04 でのエラーと対処

ここで Ubuntu14.04 でエラーが出た。

```

npm http GET https://registry.npmjs.org/n
npm http GET https://registry.npmjs.org/n
npm http GET https://registry.npmjs.org/n
npm ERR! Error: CERT_UNTRUSTED
npm ERR!     at SecurePair.<anonymous> (tls.js:1370:32)
npm ERR!     at SecurePair.EventEmitter.emit (events.js:92:17)
npm ERR!     at SecurePair.maybeInitFinished (tls.js:982:10)
.
.
.
```

「npm install で SSL Error になった時の対処法。」
https://blog.yug1224.com/archives/563d9b67bf652a600632d01e/

を参考にして、SSL鍵のバリデーションを一旦OFFしたらうまくいった。

```

# sudo npm config set strict-ssl false
# sudo npm install n -g
```
その後設定を元に戻す。

```

# sudo npm config set strict-ssl true

```

# 古い Node.js を削除する

node をインストールした後、aptでインストールしたものを削除、ログオン。

```

$ sudo n stable
$ sudo apt purge -y nodejs npm
$ exec $SHELL -l
```
バージョン確認。

```

$ node -v
v12.18.2

```

# 実行してみる。

WebSocketを使ったものをテスト実行するために、モジュールをインストール

```

$ sudo npm install -g ws

```
index.js を適当に作成
```
var server = require('ws').Server;
var s = new server({port:5001});

s.on('connection',function(ws){

    ws.on('message',function(message){
        console.log("Received: "+message);

        s.clients.forEach(function(client){
            client.send(message+' : '+new Date());
        });
    });

    ws.on('close',function(){
        console.log('I lost a client');
    });

});


```

実行
```

$ sudo node index.js
```

Ubuntu14.04, Raspberry Pi OS Lite Release date: April 4th 2022  では以下のようにエラーが出た

```

Error: Cannot find module 'ws'
Require stack:
.
.
.
```



「Node.jsで、存在するはずのmoduleがrequireでエラーになることについて」
https://qiita.com/DNA1980/items/11fdb7233fc288ac3502

を読んで、

```
echo $NODE_PATH
```

で設定されていなかったので以下のように実行すればエラー解消した


```

export NODE_PATH=`npm root -g`
```
AWS-SAA試験勉強メモ3

###CIDR表記
X.Y.Z.W/24
なら、X.Y.Z.Wと255.255.255.0をそれぞれ2進数にあらわしたものの積を取る

☆「/24」の部分が、2進数表記のサブネットマスクで頭からの1の個数

###Auto ScalingグループへのEC2インスタンスへのアタッチ可能になる条件

- インスタンスがrunnning
- インスタンス起動時のAMIが存在する
- インスタンスが他のauto scalingグループに属していないこと
- インスタンスがAuto Scalingと同じAZにあること

補足：Auto Scalingグループは複数のリージョンにまたがることは出来ない

###CloudTrailログファイル
アカウントのAPIアクティビティログファイルをS3に送信

###S3Glacier無料取り出し枠
無料取り出し枠=10GB/月

###S3のオブジェクト削除

- DELETE API
  →単一のオブジェクト削除

- Multi-Object Delete API
  →複数のオブジェクト（1つのHTTPリクエストで最大1000のオブジェクト削除）

###CloudWatchのメトリクスの保管期間
基本メトリクス、カスタムメトリクス問わず15か月

###DynamoDB

- NoSQLDB
- キャパシティユニットでスループットを指定（書き込み＆読み込み）
- データ容量制限なし
- スケールアウトが良い鵜
- 高速パフォーマンス、シームレスな拡張性

###フロントエンドリスナーにHTTPSまたはSSLを使用する場合
ELBにSSL証明書のインストールが必要

###
【After Effects】プレビュー時に音が鳴らない場合の対処法

After Effectsで動画プレビュー時に**サウンドが再生されない現象**に出会ったので、その対処法です。

## オーディオハードウェアをチェックする

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/2467aa6e-66c4-e927-a189-2865fb453bd9.png"  width=450 />

`AffterEffects > 環境設定 > オーディオハードウェア...`を開きます。


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/90952ad0-5f14-3a07-04df-8507a09581f6.png"  width=450 />

デフォルト出力がで`MacBook Pro Speakers`になっています。
この時は僕はヘッドフォンで作業していて、出力先と異なっていて音が鳴らないという状態になっていたようです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328771/bb185d5f-d8e0-f44e-c1fb-34e1cc1c8603.png"  width=450 />

`External Headphones`に設定すると音が鳴り出しました。

## まとめ

After Effectsで音が鳴らなくなったら、オーディオハードウェアの出力先をチェックして、**出力デバイスを適切に選択**する必要があるようです。


## 環境

- macOS Catalina 10.15.1
- After Effects 16.1.0
AWS Redshiftでテーブルとそのカラム、データ型の一覧を抽出するメモ

## この記事について

Redshift上に格納している複数のテーブルについて、まとめてドキュメント化する必要があり、こういうの↓がCSVで欲しかったのでそのためのクエリをまとめた。
ほぼ[参考記事](https://qiita.com/foursue/items/021c12d52f7b79f0ded4)のクエリを改変しただけです(@foursue 様ありがとうございます)がメモまで


| table_id | schema_name | table_name | column_number | column_name |column_datatype|
----|----|----|----|----|----| 
| 1 | user | demographic | 1 | uuid | VARCHAR |
| 1 | user | demographic | 2 | age | INT |
| 1 | user | demographic | 3 | gender | VARCHAR |
| 1 | user | demographic | 4 | country | VARCHAR |
| 2 | order | order_detail | 1 | order_id | BIGINT |
| 2 | order | order_detail | 2 | timestamp | TIMESTAMP |
| 2 | order | order_detail | 3 | uuid | VARCHAR |
| 2 | order | order_detail | 4 | type | VARCAHR |
| 2 | order | order_detail | 5 | price | NUMERIC |

## 実際の方法

対象のredshiftクラスタにadminでログインして下記を実行しましょう。

```.sql:dump_table_column_datatype.sql
SELECT
  table_id,
  schema_name,
  table_name,
  column_number,
  column_name,
  column_datatype
FROM
  (
    SELECT
      c.oid::BIGINT AS table_id,
      n.nspname AS schema_name,
      c.relname AS table_name,
      a.attnum AS column_number,
      QUOTE_IDENT(a.attname) AS column_name,
CASE
        WHEN STRPOS(
          UPPER(format_type(a.atttypid, a.atttypmod)),
          'CHARACTER VARYING'
        ) > 0 THEN REPLACE(
          UPPER(format_type(a.atttypid, a.atttypmod)),
          'CHARACTER VARYING',
          'VARCHAR'
        )
        WHEN STRPOS(
          UPPER(format_type(a.atttypid, a.atttypmod)),
          'CHARACTER'
        ) > 0 THEN REPLACE(
          UPPER(format_type(a.atttypid, a.atttypmod)),
          'CHARACTER',
          'CHAR'
        )
        ELSE UPPER(format_type(a.atttypid, a.atttypmod))
      END AS column_datatype
    FROM
      pg_namespace AS n
      INNER JOIN pg_class AS c ON n.oid = c.relnamespace
      INNER JOIN pg_attribute AS a ON c.oid = a.attrelid
      LEFT OUTER JOIN pg_attrdef AS adef ON a.attrelid = adef.adrelid
      AND a.attnum = adef.adnum
    WHERE
      c.relkind = 'r'
      AND a.attnum > 0
    ORDER BY
      a.attnum
  )
ORDER BY
  schema_name,
  table_name,
  column_number
```


## 参考記事

* [amazon-redshift-utils](https://github.com/awslabs/amazon-redshift-utils)
    * https://github.com/awslabs/amazon-redshift-utils/blob/master/src/AdminViews/v_generate_tbl_ddl.sql
* https://qiita.com/foursue/items/021c12d52f7b79f0ded4
INSERT を重複せずに実行する

あるテーブルに重複有無を確認後、重複がなれけばINSERTしたいときの方法。

例えば users_booksテーブルが以下のようにあったとします。

|id  |user_id  |book_id  |
|---|---|---|
|1  |5  |10  |

ここで重複の有無を確認して、同じレコードが入っていないときINSERTしたいなら、以下のSQL文でできました。

```SQL
INSERT INTO users_books(user_id, book_id) 
SELECT 5, 10, 
WHERE NOT EXISTS (SELECT user_id FROM users_books WHERE user_id = 5 AND book_id = 10)
```

注意する点として、通常のINSERTなら `VALUES`となっているところが、`SELECT`になっていること。
【クエリ爆減】update_allで一定条件下の複数データをまとめて更新する【Ruby on Rails】

入荷から一定期間経過した商品には割引(30日以上→500円・60日以上→1000円・90日以上→1500円)を適用する為、以下の様なロジックを書きました。

```Ruby
items = Item.where("created_at < ?", Time.zone.now - 30.days)
items.each do |item|
  created_at = item.created_at
  today = Time.zone.today
  three_month = 90.days
  two_month = 60.days
  one_month = 30.days

  if today >= created_at + three_month
    discount = -1500
  elsif today >= created_at + two_month && today < created_at + three_month
    discount = -1000
  elsif today >= created_at + one_month && today < created_at + two_month
    discount = -500
  end

  item.discount = discount
  item.save
end
```
しかし上記のコードでは、`items`の数の分処理が走ってしまう所謂 **N+1問題** が発生し、処理速度やメモリに大きな影響を与えてしまいます。


そこで活躍するのが`update_all`。
以下の様に条件を`hash`に纏めて配列に格納、各条件に当てはまるデータを纏めて更新します。

```Ruby
today = Time.zone.now
conditions = [
  { upper_limit: today - 30.days, lower_limit: today - 59.days, amount: -500 },
  { upper_limit: today - 60.days, lower_limit: today - 89.days, amount: -1000 },
  { upper_limit: today - 90.days, lower_limit: today - 365.years, amount: -1500 }, 
]
conditions.each do |condition|
  Item.
    where("created_at between ? and ?", condition[:lower_limit], condition[:upper_limit]).
    update_all(discount: condition[:amount])
end 
```
するとクエリは条件分のたった3つだけに収まります🎉

```SQL
Item Update All (8.8ms)  UPDATE `items` SET `items`.`discount` = -500 WHERE (created_at between '2020-04-27 00:00:00' and '2020-05-26 00:00:00')
Item Update All (3.2ms)  UPDATE `items` SET `items`.`discount` = -1000 WHERE (created_at between '2020-03-28 00:00:00' and '2020-04-26 00:00:00')
Item Update All (19.4ms)  UPDATE `items` SET `items`.`discount` = -1500 WHERE (created_at between '1920-06-25 00:00:00' and '2020-03-27 00:00:00')
```

※ActiveRecordオブジェクトを経由しない更新方法のため、バリデーションやコールバックは実行されない点にご注意ください。
Ubuntu 18.04にXMind 8をインストール＆Dockから起動

Ubuntu18.04にXMind 8をインストールする手順のメモ。
Dockから起動できるようにするには少し工夫が必要になる。

## zipファイルのダウンロード
[公式のダウンロードページ](https://jp.xmind.net/download/linux/)からzipファイルをダウンロードする。ダウンロードにはライセンス内容への同意が必要。
![Xmind2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/9ce6c896-96d1-c898-3586-91a5954e39ce.png)


## ダウンロードしたzipの展開
ダウンロードしたzipファイルを任意のディレクトリに移動し、展開する。ここでは「~/XMind」に展開した形で進める。

## 管理者権限でsetup.shを実行
zipを展開したディレクトリ上で以下を実行する。これで必要なライブラリがインストールされる。

```shell
sudo bash setup.sh
```

## XMind.iniの編集
「XMind_amd64」内のXMind.iniをエディタで開き、以下の行を追加する。

```ini
-vm
/usr/lib/jvm/java-8-openjdk-amd64/bin
```

追加する場所は以下。
![ini2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535720/80357543-5499-5c01-bd87-9e8a0bcc43b2.png)

## XMindの起動確認
「XMind_amd64」内のXMindをダブルクリックして、XMindを起動してみる。エラーが出なければOK。

## ショートカット用のシェルスクリプトの作成
「~/bin」内にxmind.shを作成し、以下の内容を記述する。そして実行権限を与える。

```shell
#!/bin/bash
cd ~/XMind/XMind_amd64/
./XMind &
```

ターミナルで「~/bin」を開き、`./xmind.sh`を実行して起動を確認する。


## desktopファイルの作成
「~/.local/share/applications」内にxmind.desktopを作成し、以下の内容を記述する。パスは自分の環境に合わせて適宜書き換えること（~を使用するとエラーが起きるので注意）。
アイコン画像は適宜自分で用意しておく。

```
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=XMind
Comment=Execute XMind.

# 実行するファイルのパス
Exec=/home/xxx/bin/xmind.sh

# アイコンのパス
Icon=/home/xxx/XMind/XMind.png

Terminal=false
```

作成後、以下のコマンドで実行権限を与え、「~/Desktop」にコピーを作成する。

```shell
chmod 775 xmind.desktop
cp ~/.local/share/applications/xmind.desktop ~/Desktop/
```

うまく行けばデスクトップに上記ファイルのコピーが作成され、ダブルクリックでXMindを起動できるようになる。一度起動するとアプリ一覧にも表示されるようになる。

## Dockに登録する
上記ショートカットからXMindを起動した状態でDock上のアイコンを右クリックし、お気に入りに登録する。これでDockから起動できるようになる。

----
WindowsとUbuntu両方で使えるアプリが増えるのはうれしい！

## 参考サイト
[XMind のダウンロード](https://jp.xmind.net/download/linux/)
[Linux PC環境構築[40]：UbuntuにXMindをインストールする](https://plaza.rakuten.co.jp/kurokawa110/diary/201908030000/)
[Ubuntu 18.04 Install XMIND 8 to open the error problem solution.](https://developpaper.com/ubuntu-18-04-install-xmind-8-to-open-the-error-problem-solution/)
[gnome-shellのランチャーにショートカットを登録する](https://qiita.com/MHANAYAMA/items/ffd32957e28ae33fb806)
[Ubuntuでショートカット（デスクトップエントリ）を作る](http://91stardust-atelier.hatenablog.com/entry/2016/11/17/015854)
[chmod パーミッション（権限）の設定・変更](https://www.server-memo.net/tips/command/chmod/chmod.html#i-4)