OmniAICreator/Qiita-1.07M huggingface dataset:
DynamoDBのDocumentClient使用時にValidationExceptionでハマった


JavaScriptに慣れていない私が、AWS Lambdaでイベントから年(year)を受け取り、Dynamo DBに問い合わせるコードを書いていたところ、Lambda側のテストでValidationExceptionが発生しました。


```javascript

const AWS = require("aws-sdk");
AWS.config.update({region: "ap-northeast-1"});
let docClient = new AWS.DynamoDB.DocumentClient();

exports.handler = function(event, context){
    // イベントから渡された年を変数に設定（設定されていない場合は2020年に設定）
    let input_year = 0;
    if (event.year == ""){
      input_year = 2020;
    }else{
      input_year = event.year;
    }

    // DynamoDBクエリ用のパラメータを設定
    let params = {
      TableName: 'xxxxxxxxxxx',
      KeyConditionExpression: '#yr = :hkey',
      ExpressionAttributeNames:{ "#yr": "year" },
      ExpressionAttributeValues: { ':hkey': input_year }
    };
  
    // クエリを実施（ここでエラー）
    docClient.query(params, function(err, data) {
      if (err) {
        console.log(err);
      } else {
        console.log("Query succeeded.");
      }
      context.done(null, resultMap);
    });
  }
};
```

↓実行結果

```
ValidationException: One or more parameter values were invalid: Condition parameter type does not match schema type
```

# 怪しそうなところ

```javascript
    let input_year = 0;
    if (event.year == ""){
      input_year = 2020; // 数値
    }else{
      input_year = event.year; // 文字列
    }
```

数字と文字列が混在してるのはやばいんじゃない？（コーディングしたのは自分）

# 検証

上記の部分を、以下に置き換えて実行しました。

```javascript
    let input_year = 2020; // 数値にしたところ成功
```

```javascript
    let input_year = '2020'; // 文字列にしたところエラー
```

今回はDBのyearを数値で設定していたため、変数の型とDBの型を統一し、数値にしてあげる必要がありそうです。

# 修正後

```javascript
    let input_year = 0;
    if (event.year == ""){
      input_year = 2020;
    }else{
      input_year = parseInt(event.year, 10); // 数値に変換したところエラーがなくなった
    }
```

# 余談
なぜか、修正前のコードでも、APIGatewayから叩くとエラーにならなかったんですよね、謎。
MVP（Minimum Viable Prototype：実用最小限の製品）のメモ

# 定義
簡単に定義すると、MVPとは、製品を提供する上で必要最小限の機能のみをもつ、もっともシンプルな製品です。しかし一般的には、「顧客価値があり、利益を生み出せる最小限のもの」と考えられています。
参考：https://uxmilk.jp/65654


#ステップ
ステップ1：ユーザーとユーザーの課題を認識する
ステップ2：ステップ1の課題に対して解決するユーザーフローを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/86e524da-037f-91af-9452-ed09d39c06a4.png)


ステップ3：ステップ２のフローに対してプロトタイプを作る
ステップ4：テストして結果を分析して
参考：http://www.bnn.co.jp/books/9894/

追加：
https://medium.com/bluedots/mvp-6d537fa8a408
この問題地味に難しい...(Ruby)

#0から9までのカウント(Ruby編)
#問題
0から9までを数えるカウンタを考えます。

0 → 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9

このカウンタの拡張として、任意の数から始められるカウンタを考えました。

2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 0 → 1
（2から始める例、カウンタは9まで進んだら0に戻ります）



入力から数字nを受け取り、nからカウンタをスタートさせて、

カウンタの値を順番に10個出力するプログラムを実装してください。
#入力される値
入力は以下のフォーマットで与えられます

n

・nはカウンタの最初の値

#期待する出力
nから始まるカウンタの10個の値を、順番に改行区切りで出力してください。
#入力例1
0

#出力例1
0
1
2
3
4
5
6
7
8
9

#入力例2
2

#出力例2
2
3
4
5
6
7
8
9
0
1
#私の回答(結局解けなかった)
```java:
n = 2
# nが10まで進んだら0にリセットする、それ以外はパスして10個出力
for i in n..9 do
if n == 9
   n = 0
   puts i
   n += 1
end
end
```
###色々弄りすぎて多分2時間くらいやってたので最終的には諦めたコードになります笑
###なんせ 10にいこうとしたら0に戻ってリスタートさせる的なコードが必要なのですが、そのコードを書こうともがいたのが n ==9 の部分です。こういうところがプログラミング脳が足りてないところなんですよね。。。そしてなんと言ってもググる際の言語化がこういうときかなり難しい。
#以上！
Rails 正規表現での^,$

# 例

## 郵便番号を正規表現でチェックする

### エラーが出た実装

```ruby:user.rb
class User < ActiveRecord::Base
  validates :zip_code, format: { with: /^\d{3}\-?\d{4}$/ }
end
```

これでアプリケーションを実行すると以下のエラーが出ました。


```
The provided regular expression is using multiline anchors (^ or $), which may present a security risk. Did you mean to use \A and \z, or forgot to add the :multiline => true option?
```

セキュリティリスクがあるので

- 行頭の ```^``` は ```\A``` 
- 行末の ```$``` は ```\z``` 

を使え、と言われた。

### 修正した実装

```ruby:user.rb
class User < ActiveRecord::Base
  validates :zip_code, format: { with: /\A\d{3}\-?\d{4}\z/ }
end
```

これでエラーは出なくなりました。
iOS14で非公開サーバーかつオレオレ証明書でUniversal Linksをテストする方法

今回はiOS14で非公開サーバーかつオレオレ証明書でUniversal Linksをテストする方法について投稿したいと思います。

iOS14でUniversal Linksのapple-app-site-associationファイルがCDN化されました。

参考:iOS14 におけるUniversal Links の変更点
https://recruit.gmo.jp/engineer/jisedai/blog/ios14-universal-links/

それに伴い、本番環境では公開されているサーバーでないとapple-app-site-associationファイルをCDN化できず、Universal Linksが働きません。
そこで下記2つの手順を行うことで非公開サーバーかつオレオレ証明書でUniversal Linksをテストできます。

* alternate modeをdeveloperにする
* デバイスのAssociated Domains Development をONにする


# alternate modeをdeveloperにする

iOS14から下記でalternate modeというのが登場しています。

https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_associated-domains

alternate modeには下記modeがあります。

* developer

開発者モードのデバイスのみがドメインにアクセスできることを指定します。このモードでは、システムが信頼しない証明書を含め、Webサーバーで有効なSSL証明書を使用できます。man-in-the-middle攻撃などのセキュリティ問題にユーザーをさらさないようにしてください。追加の予防措置として、開発プロファイルで署名されたアプリのみが開発者モードを使用でき、ユーザーは使用するすべてのデバイスでオプトインする必要があります。

* managed

モバイルデバイス管理（MDM）プロファイルで管理されているデバイスのみがドメインにアクセスできることを指定します。このモードでは、MDM管理者の同意が必要です。

* developer+managed

developerとmanagedの同時に両方指定

そのため開発環境の非公開サーバーでUniversal Linksを使用する場合、developerを使用します。
また、developerの際はオレオレ証明書でもUniversal Linksを使うことができます。
**※ 本番環境でmode=developerのパラメータを付与しないように注意してください**

# デバイスのAssociated Domains Development をONにする

developerの説明に

```
users must opt in on any device they use.
```

とあるように、mode=developerというパラメータを付与した状態だけではUniversal Linksは動作せず、
デバイスで下記設定を行う必要があります。

設定アプリ -> デベロッパ -> Associated Domains Development をONにする

![スクリーンショット 2020-11-09 13.16.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308423/2362a14f-1f59-630a-d8fe-e4e483e31191.png)

# まとめ

上記2つの設定を行うことで、非公開サーバーかつオレオレ証明書でUniversal Linksをテストできます。
iOS13ではalternate modeも無くオレオレ証明書ではUniversal Linksが有効化されなかったようなので、開発しやすくなったかもしれません。

# 次の記事は

明日は食べログアドベントカレンダー2020の4日目の記事が公開されるのでご期待ください！
EC2に自動デプロイ後、変更が反映されていないときの対処法

内容としてはタイトルにある通りですが、EC２に自動デプロイを行った際に変更が反映されておらず、めちゃめちゃ焦りました。
今後同じことがあったときに焦ることがないよう、備忘録として残しておきます。


## 環境
AWS EC2
Ruby 2.6.5
Rails 6.0.3.3
capistrano

## 結論
EC2インスタンスを再起動する。
自動デプロイを複数回行うと変更が反映されないことがあるためその際はインスタンスの再起動を行います。
再起動手順については[こちらの記事](https://qiita.com/qolayumusou/items/a34cccbb07802c94eeef)にわかりやすく解説されています。


## 最後に
インスタンスの再起動を行った際はデータベースとNginxの再起動も忘れずに行うこと！

1.EC2インスタンスにログイン

```:ターミナル
hoge@MacBook ~ % cd .ssh  
hoge@MacBook .ssh % ssh -i ダウンロードした鍵の名前.pem ec2-user@該当EC2インスタンスと紐付けたElastic IP
```

2.データーベース(今回はmariaDB)とNginxの再起動を行う

```:ターミナル
[ec2-user@ip-173-41-45-198 ~]$ sudo systemctl restart mariadb 
[ec2-user@ip-173-41-45-198 ~]$ sudo systemctl restart nginx
```
【TypeORM × PostgreSQL】RESTful-APIのCRUDを1分で実装する

#はじめに
30代未経験からエンジニアを目指して勉強中のYNと申します。
タイトルのCRUDの実装をまとめました。TypeORMを使うととても簡単ですね。
#セットアップ
cliコマンドを使えば基本的なセットアップは完了です。[詳細はこちら](https://typeorm.io/#/using-cli/how-to-read-the-documentation)を参照ください。

```
mkdir sample-crud && cd sample-crud
npx typeorm init --database postgres --express --docker
yarn
```
sample-crudフォルダ内はこんな感じになっているはずです。
![スクリーンショット 2020-11-16 15.08.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/9364b01a-9f8f-7719-2151-f6be86843400.png)
#PostgreSQLコンテナの起動
コンテナを起動します。

```
docker-compose up -d
docker-compose exec postgres psql -U test
```
ちゃんと動いていることが確認できます。
![スクリーンショット 2020-11-18 16.31.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/4c501bb8-ea91-f0a4-f08b-88a7dc72b733.png)


#サーバーを起動
expressサーバーを起動し、データベースを確認します
[（このとき、5432portが被るのでホストでPostgreSQLアプリが停止していることを確認してください)](https://stackoverflow.com/questions/48593016/postgresql-docker-role-does-not-exist)

```
yarn start 
```
テーブルが作られ、insertクエリが実行されていることを確認できます。
([userは特別な意味を持ち、""を付けないと違う意味のクエリになるので注意しましょう](https://dba.stackexchange.com/questions/73136/cant-list-users-select-from-user-returns-only-one-row-with-one-column))

![スクリーンショット 2020-11-18 16.27.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/59102e48-d946-eee3-a335-7f37b1f522a6.png)

# CRUDクエリの実行
`routes.ts`に記載のとおりにCRUDが実行できます。あとはControllerの部分を自分好みにカスタマイズしましょう。

```routes.ts
export const Routes = [{
    method: "get",
    route: "/users",
    controller: UserController,
    action: "all"
}, {
    method: "get",
    route: "/users/:id",
    controller: UserController,
    action: "one"
}, {
    method: "post",
    route: "/users",
    controller: UserController,
    action: "save"
}, {
    method: "delete",
    route: "/users/:id",
    controller: UserController,
    action: "remove"
}];
```
Memento Pattern

<font color="#00f">特定のクラスの状態を複製するクラスを用意してMementoとする。userは複製を作成したときにMementoをインスタンス化してコレクションに記録し、必要に応じてインスタンスを取り出す<br>Mementoは複製するメンバを保持する</font>

[Design Pattarm MENU](https://qiita.com/old_cat/items/852d980bedb9100dd7e3)

以下のクラス構成で確認します

|クラス|説明|
|-----|----|
|Origin.class|複製対象のクラス|
|Memento.class|Originを複製する場合に、MementoにOriginのデータを複製し、Mementoを保存する|
|MementoList.class|コレクション（ListやMapなど）を保持し、Mementoインスタンスを格納する|
|user(Main.class)|動作を確認する|

＊user　他の開発者がこのパターンを利用する、という意味合いを含みます



```java:Origin.class
class Origin{
  int  No;

  void setNo(int No){
       this.No=No;
  }

  Memento createMemento(){
       return new Memento(No);
  }
}
```
```java:Memento.class
class Memento{     
  int No;          // Originと同じfieldを持たせる

  Memento(int No){
      this.No=No;
  }

  int getNo(){
      return No;
  }
}
```
```java:MementoList.class
class MementoList{
  Map  map = new HashMap();

  void put(int key,Memento mmt){
       map.put(key,mmt);
  }
  
  Memento getMemento(int key){
       return (Memento) map.get(key);
  }
}
```
```java:user(Main.class)
public static void main(String[] args){
  Origin or = new Origin();
  MementoList list = new MementoList();

  or.setNo(1);
     list.put(1,or.createMemento());
  or.setNo(2);
     list.put(2,or.createMemento());

  Memento m1 = list.getMemento(1);
  System.out.println(m1.getNo());
}
```
C言語　データ型モデルを意識した型の情報一覧

# データ型モデル

型の最大値、最小値の一覧等まとめているサイトは多いですが、データ型モデルのことに触れずに書いているサイトが多いのでまとめて見ました。

OSではデータ型モデルと呼ばれる環境の定義規約によって基本型のサイズが定められています。
ここで64bitの主な環境について述べます。

型   | LLP64 | LP64
--- |---| ---
char | 8 | 8
short | 16 | 16
int | 32 | 32
long | 32 | 64
long long | 64 | 64
void * | 64 | 64

### LLP64

ポインターのみを64ビット化したもの。
Microsoft Windowsの64ビット版(Win64)で採用されたデータ型モデル

ソースの互換性が高く64ビット化において最も問題が少ないと考えられている。

long long と pointer が64bit。

### LP64

64ビット実装モデルの二つ目。ポインターとlongを64ビット化したもの。

64ビット版のLinux、FreeBSD/OpenBSD等BSD、その他一般にUNIXと解釈されているOS全般で採用されたデータ型モデル。

intとlongの長さが違うため、漠然と同じであることを想定したようなプログラムで問題が生じる恐れがある。

long と pointer が64bit。

## LP64のデータ型一覧

### 整数型

型        |説明     |bit    |byte   |max    |min
---       |---       |---    |---    |---    |---
short int          | 符号付整数 | 16bit | 2byte | 32767 | -32768
int                | 符号付整数 | 32bit | 4byte | 2147483647 | -2147483648
long int           | 符号付整数 | 64bit | 8byte | 9223372036854775807 | -9223372036854775808
long long int      | 符号付整数 | 64bit | 8byte | 9223372036854775807 | -9223372036854775808
char               | 文字(1文字) | 8bit | 1byte | 127 | -128
unsigned short int |  符号なし整数| 16bit | 2byte| 65535| 0
unsigned int       | 符号なし整数| 32bit | 4byte| 4294967295| 0
unsigned long int  | 符号なし整数| 64bit | 8byte| 18446744073709551615| 0
unsigned long long int| 符号なし整数| 64bit | 8byte| 18446744073709551615| 0
unsigned char      | 符号なしで文字| 8bit | 1byte| 255| 0

※ C言語の内部では文字は整数として扱っているためunsigned char型も存在する。
charは文字型のため、unsigned charの値幅がデフォルトになっているシステムもある。
[Compiler User Guide: Basic data types in ARM C and C++](https://www.keil.com/support/man/docs/armcc/armcc_chr1359125009502.htm)

### 浮動小数点型

型        |説明     |bit    |byte   |max    |min
---       |---       |---    |---    |---    |---
float              | 単精度実数 | 32bit | 4byte | 3.402823 * (10の38乗) | (表現可能な最小の正の実数)1.175494 * (10の-38乗)<br>(表現可能な最小の実数)-3.402823 * (10の38乗)
double             | 倍精度実数 | 64bit | 8byte | 1.797693 * (10の308乗) | (表現可能な最小の正の実数)2.225074 * (10の-308乗)<br>(表現可能な最小の実数)-1.797693 * (10の308乗)

## stdint.hを使用して型を制御する

環境によって上限が変わってしまう型を使うのは危険なので、
stdint.hをインクルードして使っていくのが適切かと思いました。

[標準ライブラリヘッダ <cstdint> - cppreference.com](https://ja.cppreference.com/w/cpp/header/cstdint)

## 参考

[データ型モデル ‐ 通信用語の基礎知識](https://www.wdic.org/w/TECH/%E3%83%87%E3%83%BC%E3%82%BF%E5%9E%8B%E3%83%A2%E3%83%87%E3%83%AB)

[基本型 - cppreference.com](https://ja.cppreference.com/w/cpp/language/types)

[stdint.h](http://www.c-lang.org/detail/stdint_h.html)
【Ruby On Rails】ActionView::Template::Error (ActiveStorage::InvariableError)の原因と対処法（仮説・検証）

備忘録です。
ActionView::Template::Error (ActiveStorage::InvariableError)の原因と、その対処法について仮説・検証しました。

# エラー背景・経緯
デプロイしたアプリの動作確認を行うことにしました。今回は画像がアップロードされているかどうかを、簡易的に手動で確認したいため、単体テストや結合テストを行わずに動作確認を行うことにしました。

今回は周りの友達に動作確認テストの協力をしてもらいました。
協力内容としては、画像を投稿できるフォームにファイルを添付して、投稿したファイルがビューに表示できるかどうかを確認して欲しいと依頼しました。

# エラー内容
協力者である友達から、画像ファイルを添付したと報告をもらったので、デプロイしたアプリの詳細画面を確認しました。すると、"We're sorry but something went wrong"と表示されてしまいました。

まずは、ターミナルでログとそのエラー内容を確認しました。（今回はheroku）

```terminal
% heroku logs --tail

(中略)

ActionView::Template::Error (ActiveStorage::InvariableError)
    34: <div>
    35:   画像
    36: </div>
    37: <%= image_tag @question.image.variant(resize: '200x200'), class: 'question-image' if @question.image.attached? %>
    38: <% end %>
    39:
    40: <%= render 'shared/error_messages', model: @comment %>
app/views/questions/show.html.erb:37
```

# 調べたこと

エラー内容に関する記事を調べてみました。このエラーを解決する鍵は「variable?メソッドを使って、blobが変数であるかどうかを区別する」とのことでした。
ここで言う変数は添付される画像ということになりますが、正しい変数（画像）が与えられているかが鍵となることがわかりました。

「そもそもvariable?とはなんぞや」

ということでネットで調べてみると、variable?を使ってTrueの時のみ画像を呼び出せる様にする時に使うとのこと。そして、ActiveStorage.variable_content_typesメソッドと組み合わせることで、指定した拡張子のみの画像を添付できる様に制限をかけることがわかりました。

# 仮説
そもそも、友達が投稿したファイルは画像ファイルではない、もしくはactive_storageがサポートしている拡張子の画像ではない。という仮説を立てました。

# 行ったこと
友達に画像以外を載せた可能性を聞いてみました。すると、「画像も他の拡張子のファイルも混在しているファイルの中からテキトーに確認せずに添付した」と回答が返ってきました。つまり、画像以外が添付されている可能性大です。

友達から聞いた内容と、自分で立てた仮説をもとに、自分で誤った拡張子のファイルを添付し保存ができるかどうか、詳細ページはエラーになるかどうかを試しました。

# 結果
友達の時と同様に、全く関係のない拡張子でデータの保存ができました。そして、詳細ページに遷移すると同様に"We're sorry but something went wrong"という表示になりました。

つまり「正しい拡張子のファイルが送信されていなかった」ということがわかりました。

今後は特定の拡張子以外の保存ははじけるように、ActiveStorage.variable_content_typesメソッド等を使用して、今回の様なエラーが起きない様にします。


# 補足
テストをしていく段階で、画像の拡張子が.heicだとアップロードできない場合がありました（できる場合もありましたが、原因は不明です）。
参考記事2番目の記事に記載されている通りですが、現在は.heic拡張子のファイルのサポートはしていないみたいですので、避けた方が吉 or heicだけをはじく記述をした方が良いかもしれないですね。

英語の記事読むのはかなり重要ですね


# 参考記事
https://edgeapi.rubyonrails.org/classes/ActiveStorage/InvariableError.html
https://stackoverflow.com/questions/60686249/activestorageinvariableerror-in-homeindex
https://qiita.com/xusaku_/items/36a61e35b6cd863bbf9d
JSPでforeachを使ってみた

あれはそう、C言語とかJavaScriptとかしか知らなかった学生時代

JSPの授業でforeachとArrayListを学んだ。

C言語では

```C
//C言語のよくあるループ
for(i = 0; i < 10; i++){
  printf(%c,List[i]);
}
```
みたいなこと書いていた気がする。

そんな時、foreachとArrayListを学んで全身の毛が逆立つような高揚感に包まれたことを記憶しています。

でも、あんまり使ってなかったのでこれを気に使ってみました。

まず、foreachを使うには以下の手順が必要になります。

```JSP
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
```

これをimportしてる辺りに記載します。

次にこのtaglibを使う為に以下のサイトからjarファイルをダウンロード
https://tmg0525.hatenadiary.jp/entry/2017/08/14/154450

<ul>
<li>taglibs-standard-impl-1.2.5.jar</li>
<li>taglibs-standard-jstel-1.2.5.jar</li>
<li>taglibs-standard-spec-1.2.5.jar</li>
</ul>

ダウンロードしたらeclipceのWEBContent->WEB-INF -> libに投げ込みます。
![2020-11-16_145902.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/818309/a100d52e-1c36-ed8c-9499-30ed177f18d1.png)

これでcのprefixが使えるようになります。

ArrayListはaddとかを使う事で要素数を気にせずに要素を入れれます。素晴らしい…

そしてそれらを組み合わせたのがコチラ

```JSP
<c:forEach items="${itemAry}" var="item" varStatus="status">
　<option value="${status.count}" <c:if test="${status.count==itemIndexStr}">selected</c:if>> ${item}</option>
</c:forEach>
```
itemの内容をセレクトボックスのoptionに書きだして、ついでになんらかの入力エラーで帰ってきたら同じ物にSeledtedしてあげるプログラムです。

プログラムに数字がないってなんて素晴らしいプログラムなんでしょうか…

使い方を覚えなくてはっ！
Windows TerminalのSolarized Darkが超見にくいのを改善する

## 結論
[settings.jsonの入り方はこちら](https://qiita.com/hideki0145/items/04582a26baf3d81632c1#windows-terminal%E3%81%A3%E3%81%A6)
[Windows Terminalってなにって方はこちら](https://qiita.com/rubytomato@github/items/e88cab84f36e44797cf2)
以下をsettings.jsonに入れて

```json
"schemes": [
    {
        "name": "Solarized Dark - Patched",
        "black": "#002831",
        "red": "#d11c24",
        "green": "#738a05",
        "yellow": "#a57706",
        "blue": "#2176c7",
        "purple": "#c61c6f",
        "cyan": "#259286",
        "white": "#eae3cb",
        "brightBlack": "#475b62",
        "brightRed": "#bd3613",
        "brightGreen": "#475b62",
        "brightYellow": "#536870",
        "brightBlue": "#708284",
        "brightPurple": "#5956ba",
        "brightCyan": "#819090",
        "brightWhite": "#fcf4dc",
        "background": "#001e27",
        "foreground": "#708284"
    }
]
```

使いたいやつ（以下はpowershell)のcolorSchemeにさっきのnameプロパティを突っ込むだけ。

```json
{
    // Make changes here to the powershell.exe profile
    "guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
    "name": "Windows PowerShell",
    "commandline": "powershell.exe",
    "hidden": false,
    "colorScheme": "Solarized Dark - Patched"
}
```

## ちょっと説明
Windows TerminalにはデフォでSolarized Darkが入ってるけど、コマンドのオプションがまったく見えない。例えば

```shell
node -v
```

とすると、こんな感じ（目を凝らすとちゃんと-vついてます）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368139/7dd6c35f-abc9-dddd-0d6a-31917803c113.png)
これをさっきいれたSolarized Dark - patch に替えると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368139/70fd7488-5e6e-352f-67f2-fe459ae42d0c.png)
こんな感じで、ちゃんと読めるようになる（個人差がありそうです。僕は十分でした）

## ソース
今回紹介したものはhttps://windowsterminalthemes.dev/ からコピペしたものです。サイト上部で好きなカラースキームを選択して、Get themesを選択するとクリップボードに入るので、それをコピペするだけで使えてめっちゃ便利でした。オープンソースありがたや。
Google Colabで Turtle と遊ぶ

# はじめに
当記事は筆者がPyhonの勉強に利用しているGoogle ColabでTurtleの使い方の忘却メモです

# Turtleとは
本家サイトより:[タートルグラフィックス](https://docs.python.org/ja/3/library/turtle.html)
>タートルグラフィックスは子供向けのプログラミングに入門でよく用いられます。 タートルグラフィックスは Wally Feurzeig, Seymour Papert, Cynthia Solomon が 1967に開発したオリジナルの Logo プログラミング言語の一部分です。

要はPythonを使用してお絵描きが簡単にできるフレームワークです
Java屋さん的にはライブラリのように感じますが。。。

# Google Colabでは、そのままTurtleで遊べない
ということで[ColabTurtle](https://github.com/tolgaatam/ColabTurtle
)を使用します！
世の中には同じようなことを考えて便利なものを作ってくれる人がいます（多謝

# 使い方
いたってシンプル！
以下のコードを実行するだけ

```:Google&#x20;Colaboratory
!pip3 install ColabTurtle
```

あとは以下のようにコードを書いていけば遊べます

```:Google&#x20;Colaboratory
from ColabTurtle.Turtle import *
initializeTurtle()
forward(10)
left(10)
forward(20)
left(10)
```
コンポーネントに、リンクは一つまで【2020/11/16】

SNSで、今月のおすすめ記事、のようなものを作るときは、投稿いくつかまとめて、その投稿ひとつひとつがリンクを持っている。

この場合は、
1. organism = 今月のおすすめ記事
2. molecule = 各々の投稿 <= routerLinkをひとつ持つ

とすると、見通しが良くなる
【Python】機械学習における学習結果(モデル)の保存

# はじめに
<a href="https://qiita.com/ryu1104/items/06a71d8f6956da889bb8">前回の記事</a>で、機械学習の簡単なプログラムに触れてみました。
前回の記事のようなとても小規模なデータは実際には使われません。
機械学習は基本的にはデータが多い方が有利なので、通常はとても大規模なデータになってしまいます。
データが多いと、当然学習にも多くの時間を要します。
知らないとびっくりするかもしれませんが、１週間PCを放置して学習させるなどが当たり前にあります。
このような長時間の学習を、プログラム実行毎にしていては実用性も何もありません。
そこで、学習結果をモデルとして保存し、実際のプログラムではそのモデルを使用する形で実行することで、時間を短縮できます。
今回は、「保存プログラム」と「モデルを用いた予測プログラム」を作成していこうと思います。

なにをやっているかわからないと言う人は、<a href="https://qiita.com/ryu1104/items/06a71d8f6956da889bb8">前回の記事</a>を参照してください。

# 環境
python 3.8.5
scikit-learn  0.231

# ソースコード(モデルの保存)
コードには前回の記事で使用したものを一部流用しています。

```save_model.py
import numpy as np
from sklearn import svm
import pickle

#csvファイルの読み込み
npArray = np.loadtxt("data.csv", delimiter = ",", dtype = "float")

# 説明変数の格納
x = npArray[:, 0:4]

#目的変数の格納
y = npArray[:, 4:5].ravel()

#学習手法にSVMを選択
clf = svm.SVC()

#学習
clf.fit(x,y)

#学習モデルの保存
with open('model.pickle', mode='wb') as f:
    pickle.dump(clf,f,protocol=2)
```

# ソースコード(保存したモデルの使用)
```open_model.py
import pickle

# モデルのオープン
with open('model.pickle', mode='rb') as f:
    clf = pickle.load(f)

# 評価データ
weather = [[9,0,7.9,6.5]]

#　モデルを用いた予測
ans = clf.predict(weather)

if ans == 0:
    print("晴れです")
if ans == 1:
    print("曇りです")
if ans == 2:
    print("雨です")
```

# 実行結果
```
$ python3 open_model.py
晴れです
```

# おわりに
お疲れ様でした。
このように学習したモデルを保存することで、実行毎に学習させることなく、データの評価や、予測ができるようになります。
日本時刻設定と表示方法まとめ

#はじめに
自分用の備忘録
忘れがちなのでまとめてみる

#手順
## 日本時刻設定
### アプリケーションファイル編集
```ruby:config/application.rb
# 中略

module App
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.0 

    # 日本語の言語設定
    config.i18n.default_locale = :ja
    # 日本時刻の設定
    config.time_zone = 'Tokyo'

    # 中略
```

### 時刻のフォーマットを設定
```
config/locales/ja.yml => 作成
```
```yml:config/locales/ja.yml
ja:
  time:
    formats:
      default: "%Y/%m/%d %H:%M:%S"
      # あくまでデフォルトなのでよく使いそうなパターンで設定
```

## 時刻の表示
### l（エル）メソッド
```ruby:sample.rb
l sample.created_at => デフォルトの設定で表示
```

### 表示方法を指定
```ruby:sample.rb
sample.created_at.strftime('20%y年%m月') => "20xx年yy月"
```
#おわりに
l（エル）メソッドって響きがかっこいいと思うのは私だけでしょうか

✔︎
ランダム文字にてパスワード生成

こんにちは。@mashiです。

本日はパスワードをランダムにて生成するメソッドを記載いたします。
最近ランダム系ばかりアップしていますがたまたまです。

下記メソッドは初期の仮パスワードやパスワードリセット等で利用できるかと思います。
また、パスワードの1文字ずつ読み仮名が無い場合は「0」と「O」や「l」と「1」などが分かりづらい懸念があるため除外しています。

<pre>
function makePassword($length) {
  $password = '';
  
  for ($i = 0; $i < $length; $i++) {
    $password .= substr(str_shuffle('23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ-_'), 0, 1);
  }

  return $password;
}
</pre>

lengthの桁数のパスワードが返ってくる単純なメソッドです。
ログインアカウント管理をすることって多いと思うので、どこかで使うかもしれないための備忘録です。


なにかあればコメントをいただければ幸いです。
送信ドメイン認証・暗号化 DeepDive ～ DMARC から MTA-STS, DANE まで全部PASSさせるまでの道のり

# 送信ドメイン認証・暗号化 DeepDive ～ DMARCから MTA-STS, DANEまで全部PASSさせるまでの道のり


2020.11.11-12 開催された JPAAWG 3rd General Meeting で、弊社チーフエンジニア平野善隆(@hirachan)により「送信ドメイン認証・暗号化 DeepDive ～ DMARCから MTA-STS, DANEまで全部PASSさせるまでの道のり」というタイトルで発表が行われました。その時の資料をこちらにも共有します。


## はじめに

送信ドメイン認証SPF, DKIM, DMARCの復習と、暗号技術であるMTA-STS, DANE, TLS-RPTを紹介し、それぞれの仕組みや具体的な設定方法について、詳しく掘り下げて説明します。
また、今回オランダ政府の運営するセキュリティチェックサイトInternet.nlで、上記の技術を使って100点を目指してかなり頑張ってみたのでその内容を共有したいと思います。
全体的な概要を知りたい方はもちろん、より深い内容を知りたいマニアの方もお待ちしております。


## 目次

- メールセキュリティの全体像
- 世界のメールセキュリティ事情と日本の状況
- メールセキュリティチェックサイトの紹介
- 送信ドメイン認証
- メールの通信経路の暗号化


## 送信ドメイン認証・暗号化 DeepDive ～ DMARCから MTA-STS, DANEまで全部PASSさせるまでの道のり
[![thumbnail](https://files.speakerdeck.com/presentations/4949712c1d484a25ba64f2e3ad4b7605/preview_slide_0.jpg?16680731)](https://speakerdeck.com/hirachan/song-xin-domeinren-zheng-an-hao-hua-deep-dive)


## 前回の発表資料

前回及び前々回のJPAAWGで発表した資料も合わせてご参考ください。

- JPAAWG 2nd General Meeting: [メールセキュリティトレイルマップ～DMARCやその先にある世界～](https://qiita.com/qualitia_cdev/items/a9d4fcc3ccf55154bf43)
- JPAAWG 1st General Meeting: [送信サイドからみたDMARC] (https://qiita.com/qualitia_cdev/items/9a45797305002c3f8458)
OpenFOAM Tips

#はじめに
OpenFOAMのfunctionsについては、多数のサイトでまとめられています。とくに[Pnenguinitis](http://penguinitis.g1.xrea.com/study/OpenFOAM/proc_results.html)はOpenFOAMerなら一度は訪れる高野山的な存在かと思います。

二番煎じ、三番煎じにはなろうかと思いますが、このページでは自分が調べたTipsやfunctionsをまとめてみました。
なお、ここでは主に__Foundation__版についてまとめていく予定です。

# preProcess

### boundaryをまとめて設定する方法

```cpp
"(inlet|outlet)"
{
   type   fixedValue;
   value uniform (0 0 0);
}
```

のはずだが、Paraviewで確認すると、設定が反映されていない・・・（要確認）。

この面とこの面は個別設定して、残りはまとめて設定したときなどは、

```cpp
".*"
{
   type   zeroGradient;
}
```

のようにすると良い。
また、この面とこの面は同じ設定、というシチュエーションでは、

```cpp
inlet1 
{
   type   fixedValue;
   value   uniform (1 0 0);
}

inlet2
{
   $inlet1;
}
```

とすることにより、__inlet1__と__inlet2__が同じ条件になる。

### 時間ディレクトリの一括削除

```bash
foamList -rm
```

### メッシュ品質の確認

```bash
checkMesh -meshQuality
```

checkMeshのmaxNonOrtho, minimum pyraid volumeなどのパラメーター値を、`system/meshQuality`ファイルで指定できるようになる。なお、同ファイルは`foamGet meshQuality`で所望のケースディレクトリに持ってくることができます（コピー）。

なお、org版には`checkMesh -writeAllFields`というオプションがあり、これでメッシュ品質に関するデータをvtk形式で出力してくれる模様。
Foundation版で同じようなことができないか探してみたが、めぼしい情報に出会うことはなかった。ただ、Paraviewで`MeshQuality` Filterを使えば同じようなことはできます（品質の定義がOFとParaveiwとで異なるので、注意は必要）。



#postProcess

### 残差
```cpp:system/controlDict
functions
{
   #includeFunc residuals
}
```
`system/controlDict`に上記の記述を追記。workDirに`postProcessing/residuals/`というディレクトリが作成され、その中にU, Pの残差のデータが保存されています。
solverを実行中に残差の推移を確認したい場合は、

```bash
foamMonitor -l ./postProcessing/residuals/0/residuals.dat
```

他方、終了後の残差の履歴を確認したい場合は、

```bash
postProcessing -l ./postProcessing/residuals/0/residuals.dat
```

とすれば別ウィンドウに残差のグラフが表示されます。
また、U, P以外の変数の残差を表示させたいときは、

```cpp:system/controlDict
functions
{
   #includeFunc residuals(U, p, k, epsilon)
}
```
のように変数を指定すればよいです。

### 流量チェック
```cpp
functions
{
   #includeFunc flowRatePatch(name=patchName, log=true)
}
```

### 粒子の衝突密度の算出

MPPICFoamなどの粒子輸送計算をする際に、壁面にどれだけ粒子が衝突・沈着するかを求めたい場合もあろうかと思います。
デフォルトでログファイルに各パッチでの衝突・沈着量が出力されていますが、より詳しく見たいというときは、粒子計算の設定ファイルである`constant/kinematicCloudProperties`に以下の設定を追記すれば良いです。

```cpp:kinematicCloudProperties
cloudFunctions
{
        patchCollisionDensity1
        {
                type    patchCollisionDensity;
        }
}
```

これにより結果ディレクトリに`kinematicCloud::collisionDensity`というファイルが出力されるようになります。



### probes
- probes: 指定した変数の，指定した座標での値をエキスポート。セル間での補間有り。
- internalProbes: 指定した変数の，指定した座標群での値をエキスポート。セル間での補間有り。多点用。v7以前のinternalCloudに相当。
- 詳細は[こちら](https://qiita.com/takaf05/items/4d56e95924f8ad1c1cfd)で説明中。

### grad
勾配の計算

```c++:
postProcess -func "grad(<field>)"
```

### Q criterion
Q値はparaviewでも計算することができますが、OF8のpostProcessにも用意されています。

```bash
postProcess -func Q
```

各時間ディレクトリ下にQ値のファイルが作られます。

# 計算の安定化
計算の安定化の話は、かなり奥が深いです。
[こちら](https://qiita.com/takaf05/items/e4b15b89f4cd0bc71b31)に概略ではありますが、まとめております。

# 最後に
未完な記事ではありますが、アップさせてもらいました。随時更新してく予定でいます。
Django（ジャンゴ）のインストール

Anacondaのインストール
https://www.anaconda.com/

Anacondaをインストールしたら、Anaconda Navigatorを開く

Anaconda Navigatorの左のメニューから「Environments」を選択し、Createでディレクトリを作成する。（今回は「myapp」として話を進めることとする。）

myappを作成したら、「▶」をクリックして「Open Terminal」を選択する。

```
(myapp) C:\Users\yourname>
```

この状態でcmd.exeが起動できたら、次のコマンドを実行して、Djangoをインストールする。

```
pip3 install django
```

pipでDjangoをインストールできたら、次のコマンドを実行して、アプリケーションを作成する。

```
django-admin startproject [your-app-name]
```

このコマンドでDjangoのアプリケーションのディレクトリが作成される。

```
(myapp) C:\Users\yourname>django-admin startproject mydjangoapp_web
```
もし、上のような状態で`django-admin`コマンドを実行した場合は`C:\Users\yourname`直下に`mydjangoapp_web`というディレクトリが作成されることになるので、適宜、フォルダを作成したいディレクトリに移動すること。

| ファイル | 内容 |
|:-:|:---|
|\_\_init__.py|Djangoプロジェクトを実行するときの初期化処理を行うスクリプトファイル|
|settings.py|プロジェクトの設定情報を記述したファイル|
|urls.py|プロジェクトで使うURL（Webでアクセスするときのアドレス）を管理するファイル|
|wsgi.py|Webアプリケーションのメインプログラムとなる部分|

## アプリの起動
Anaconda Navigatorから起動したcmd.exeで次のコマンドを実行する

```
python manage.py runserver
```

上記コマンドを実行後、インターネットブラウザで`localhost:8000`にアクセスする。ローカルサーバーを終了するには、`Ctrl` + `C`を押す。


### 参考
- Python Django 超入門[第1版第1刷], 掌田津耶野, 2018-06-15
【OpenCV】HSVを直交座標系に変換表示

# 概要
画像分析の際、HSV色空間を使うことは多いと思います。特に H（色相）と S（彩度）を散布図にプロットすると、画像の色彩の特徴をよく捉えることができます。

ただ、H と S　は局座標空間のパラメータです。このため、H は ０〜３６０度（OpenCV　では ０〜１８０）の位相角となります。ここで問題があります。H が ０付近と、H が  ３６０付近は `同じような色相`を表すことになってしまいます。値が大きく違うのに特性はよく似ている、というのは好ましくありません。機械学習他、数理統計処理を行うには、工夫が必要でしょう。

そこで、局座標から直交座標に変換すれば、うまく処理ができると思います。ちょっと試してみました。

# HSV色空間：H と S の散布図
試しに、赤っぽい（ H が 0付近、及び OpenCV の180 付近の値をとる点が多い）画像について調べてみます。サンプルは lena にしてみましょう。

![lena.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260381/a94ea73c-15df-e6d0-d442-34476c90b2fd.png)

必要なライブラリをインポートします。

```python:
import cv2
from matplotlib import pyplot as plt
```

lena を読み込んで、OpenCVで読み込んだBGR形式の画像をHSV変換します。
＃matplotlib でも表示するため、合わせてRGB形式も作っておきます。

```python:
lena_bgr = cv2.imread('lena.png')

lena_hsv = cv2.cvtColor(lena_bgr,cv2.COLOR_BGR2HSV)
lena_rgb = cv2.cvtColor(lena_bgr,cv2.COLOR_BGR2RGB)
```
画像の色彩の特性を見るため、横軸H、縦軸S として散布図を作ってみます。

```python:
plt.figure(figsize=(12,4))
plt.subplot(1,3,1)
plt.imshow(lena_rgb)

plt.subplot(1,3,2)
plt.xlim(0,180)
plt.ylim(0,255)
plt.grid()
plt.scatter(x=lena_hsv[:,:,0],y=lena_hsv[:,:,1],alpha=0.01,marker='x',color='g')

plt.show()
```
![Unknown-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260381/bc552743-4264-696d-2ce4-e8b7974801d0.png)

彩度は広い範囲に分布していますが、`色相は ０付近、あるいは１８０付近`に偏っています。lena が赤っぽい画像であることをよく示しています。

ただ「赤っぽい」のだから散布図上の点が二つのグループに分かれることはちょっと混乱を招きますね。SVM 他の機械学習をする際も、あまり都合がよくないかもしれません。そこで、これを直交座標系で表すことを考えます。
# 直交座標系による色彩の表現
直交座標系に変換するのは難しくはありません。H（色相）が位相、S（彩度）が絶対値なので、

```math:
\begin{align}
x = S\,\cos(\,H\,)\\
\\y = S\,\sin(\,H\,)
\end{align}
 ```
これで求めることができますね。

注意が必要なのは、OpenCV では H（色相）を０〜３６０でなく、０〜１７９ で取り扱っている点でしょう。計算する際は、H の値を2倍にしないといけません。
＃　８ビットの符号なし整数では、２５５までしか表せないですから便宜上ですね

また、numpy の三角関数は単位にラジアンを使っているので、そこも気をつけてください。

では、直交座標系に変換してみます。

```python:
lena_temp = lena_hsv.astype(np.float32)
lena_xyv = np.zeros(lena_hsv.shape).astype(np.float32)

# 位相の単位をラジアンに変換
# x = cos((2*H) * 2pi / 360) = cos(H * pi / 90)
# y = sin((2*H) * 2pi / 360) = sin(H * pi / 90)

lena_xyv[:,:,0] = lena_temp[:,:,1] * np.cos(lena_temp[:,:,0]*(np.pi)/90)
lena_xyv[:,:,1] = lena_temp[:,:,1] * np.sin(lena_temp[:,:,0]*(np.pi)/90)
lena_xyv[:,:,2] = lena_hsv[:,:,2]
```

sin, cos は実数計算となりますので、float32 に型変換したインスタンスを作って作業してます。

また、明度 V はここでは使いませんが、念の為、保存しておきました。

# 結果比較
先程のように元画像と H-S の散布図、それに今回直交座標変換した x-y の散布図を並べてみます。

```python:
plt.figure(figsize=(12,4))
plt.subplot(1,3,1)
plt.title('lena')
plt.imshow(lena_rgb)

plt.subplot(1,3,2)
plt.title('H-S')
plt.xlim(0,180)
plt.ylim(0,255)
plt.grid()
plt.scatter(x=lena_hsv[:,:,0],y=lena_hsv[:,:,1],alpha=0.2)

plt.subplot(1,3,3)
plt.title('x-y')
plt.xlim(-255,255)
plt.ylim(-255,255)
plt.grid()
plt.scatter(x=lena_xyv[:,:,0],y=lena_xyv[:,:,1],alpha=0.01,marker='x',color='r')
plt.show()
```
![Unknown-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260381/78b93a46-d865-d878-377d-abd5eb09b152.png)

直交座標系で見ると、赤っぽい lena が ひとかたまりになっててよりよく特徴を表してるようです。

色相、彩度を使って機械学習する際には、直交座標系で考えるとうまくいく場合も多いんじゃないでしょうか。
Github

##ブランチ　マージ

ブランチ
並行して複数機能を開発するための仕組み
大本のブランチ master

HEADは現在作業している所
ブランチを新規作成する

```
ブランチの切り替えまでは行われない
$git buranch ブランチ名

ブランチの表示
$git buranch

全て表示 リモートブランチも表示
$git buranch -a

ブランチの切り替え
$git checkout 既存のブランチ名


新規作成＋ブランチの切り替え
$git checkout -b ブランチ名

ブランチを変更削除
変更
$git branch -m ブランチ名
削除
$git buranch -d ブランチ名 masterにマージされていない変更は残る

$git buranch -D　ブランチ名 強制的に削除

```

マージ
統合

```
$git merge ブランチ名
$git merge リモート名/ブランチ名


    b = masterブランチ
  - b
a
  - c
  c = testブランチ


  マージすると
  - b     d = masterブランチ
a      - d
  - c
  c = testブランチ


----------------------

Fast Foward


master    test
↓         ↓
a  ----   b


        master
        test
↓         ↓
a  ----   b

--------------------

Auto Merge



  b = masterブランチ
  - b
a
  - c
  c = testブランチ


親を2つ持っている b c を持っている
  - b     d = masterブランチ
a      - d
  - c
c = testブランチ


-----------------------------------------
コンフリクト

b c 同じ箇所を修正した場合に起こる

  b = masterブランチ
  - b
a
  - c
  c = testブランチ



複数人で同じファイルを編集しないようにする

変更中の状態をなくす事
  pull mergeを行う前に commit stashをしておくこと

pullを行う際に　ブランチを確認してから行う


```

##実践編

```
プルリクエスト


ワークツリー
masterブランチを最新にする
ブランチファイルを作成
ファイルを編集変更
変更をコミット

ローカルリポジトリへプッシュ
↓
ローカルリポジトリ
プルリクエスト
コードレビューしてもらう
プルリクエストマージ
ブランチ削除

$git checkout -b pull_request
$git branch
master
*pull_request
$git add.
$git commit -m'pull_request create'
$git push origin pull_request


githubサイトへ


File changesでコードを見ることが出来る
紫でdeletedを押す

$git branch -d pull_request
または-D


github_flow

pull_request
maerge
 繰り返し



```
rebase

 test
  - b
a
  - c
  master
```

$git checkout test
$git rebase master
```

a -  c   -   b`になる
  master    test



github pushしたコミットをリベースするのはNG

git push -fは使用するべきではない
強制的に行えるがgitがくしゃくしゃになるため行わないようにする

リベースとマージどっちを使用するべき？

マージ
コンフリクト○
マージコミットがたくさんあると複雑

作業履歴を残したいなら

リベース
履歴がきれいに保つ
コンフリクト△

履歴をきれいに使うなら


プッシュ後したあと
コンフリクトしそうならマージを使用

プッシュしていないローカルの変更に対してはリベース

ローカル関係はリベース　それ以外はマージ





コミットをきれいに整えてからの
pushをする場合の履歴の書き換え方
pushしていないコミットのみ





直前のコミットをやり直す

```
$git commit --amend


直前のコミットをやり直す



複数のコミッtのやり直し


ステージベース

$git rebase -i commitID
$git rebase -i HEAD~2       /2/3/4/5/5

edit as268da
pick wadfg45s
pick fdhnb513


editに変更すればそこまで戻る

$git commit --amend


$git rebase --continue




$git stash apply


ステージの状態も復元する場合
$git stash apply --index



特定の作業を復元する場合
$git stash applay　スタッシュ名



$git stash drop
$git stash スタッシュ名


全作業削除
$git stash clear
ー＝
Notes と Notes & Attachments にApexトリガーでレコードを作成する


商談の関連でメモ(Notes)とメモ & 添付ファイル(Notes & Attachments)がありますが
商談オブジェクトの説明が更新された時に、その内容をそれぞれにメモに書き込むトリガを考えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9177fccf-2147-9e04-d094-480e40e8c45d.png)


# メモ & 添付ファイル(Notes & Attachments)の場合

対象のオブジェクトはNoteオブジェクトです。

一括処理に対応できる形でトリガを考えます。

ParentIdには商談のIdをセットすることで参照関係を持たせることができます。

```Java
trigger UpdateContentDcomentLink on Opportunity (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
    if (Trigger.isAfter) {
        List<Note> notes = new List<Note>();
        for(Opportunity o : Trigger.new) {
            if((Trigger.isInsert && o.Description!= null) || (Trigger.isUpdate && Trigger.oldMap.get(o.Id).Description != o.Description))  {
                Note cn = new Note();
                cn.Title = o.Decription_Opportunity__c;
                cn.body = o.Description;
                cn.ParentId = o.Id;         
                notes.add(cn);
            }//end of if
        }//end of for
        if (notes.size() >0) insert notes;
    }//end of if
}
```

# メモ(Notes)の場合

困ったことにメモでは
本文のオブジェクトと、商談との関連を表すオブジェクトの２つに分かれています。

本文:ContentNoteオブジェクト
関係:ContentDocumentLinkオブジェクト

ContentDocumentLinkのLinkedEntityIdには商談のId
ContentDocumentIdには本文のIdをセットします。
また、ContentDocumentIdの実際の中身であるContentはBrob形式でエンコードしておく必要があるようです。

```Java
trigger UpdateContentDcomentLink on Opportunity (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
    if (Trigger.isAfter) {
        for(Opportunity o : Trigger.new) {
            if((Trigger.isInsert && o.Description!= null) || (Trigger.isUpdate && Trigger.oldMap.get(o.Id).Description != o.Description))  {
                ContentNote cn = new ContentNote();
                cn.Title = o.Decription_Opportunity__c;
                String body = o.Description;
                cn.Content = Blob.valueOf(body.escapeHTML4());
				insert(cn);   

                ContentDocumentLink cdl = new ContentDocumentLink();
                cdl.ContentDocumentId = cn.Id;
                cdl.LinkedEntityId = o.Id;
                insert(cdl);
                
            }//end of if
        }//end of for
    }//end of if
}
```

これだと、一括処理に制限が出ます。おそらく商談を51件以上処理したら発生します。

元の質問
https://trailblazers.salesforce.com/answers?id=9064S000000DLHGQA4
drf-flex-fieldsでネストしたserializerを実装する方法

ネストしたserializerを実装するところで躓いたので、メモとして書く。
#drf-flex-fieldsをインストール
```
pip install drf-flex-fields
```
#model
```model.py
class User(models.Model):
    username = models.CharField(max_length=255)


class Tag(models.Model):
    name = models.CharField(max_length=255)


class Book(models.Model):
    title = models.CharField(max_length=255)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    tag = models.ManyToManyField(Tag)
```
#serializer
```serializers.py
from rest_flex_fields import FlexFieldsModelSerializer


class UserSerializer(FlexFieldsModelSerializer):
    class Meta:
        model = User
        fields = ("id", "username")


class TagSerializer(FlexFieldsModelSerializer):
    class Meta:
        model = User
        fields = ("id", "name")


class BookSerializer(FlexFieldsModelSerializer):
    class Meta:
        model = Book
        fields = ("id", "title", "author", "tag")
        expandable_fields = {                        #expandable_fieldsでネスト
            "author": UserSerializer,
            "tag": (TagSerializer, {"many": True})   #多対多
        }
```
#Response
```
[
    {
        "id": 1,
        "title": title_1,
        "author": 1,
        "tag": [
            1,
            2,
        ]
    },
]
```
#データを動的表示
パラメータを指定して動的なデータを表示する

|オプション|説明|
|:------:|:-------:|
|expand|指定されたフィールドを展開する|
|fields|指定されたフィールドのみを表示させる|
|omit|指定されたフィールドが表示されない|
##expand
http://localhost:8000/book/1?expand=author,tag
authorとtagを展開させる

```
[
    {
        "id": 1,
        "title": title_1,
        "author": {
            "id": 1,
            "username": "user_1"
        },
        "tag": [
            {
                "id": 1,
                "name": "tag_1"
            },
                        {
                "id": 2,
                "name": "tag_2"
            },
        ]
    },
]
```
##fields
http://localhost:8000/book/1?fields=title
タイトルのみを表示させる

```
[
    {
        "title": title_1,
    },
]
```
##omit
http://localhost:8000/book/1?omit=title
タイトルを表示させない

```
[
    {
        "id": 1,
        "author": 1,
        "tag": [
            1,
            2,
        ]
    },
]
```
#参考
[rsinger86/drf-flex-fields - github](https://github.com/rsinger86/drf-flex-fields)
[drf-flex-fields - pypi](https://pypi.org/project/drf-flex-fields/)
Auroraのカスタムエンドポイントからインスタンスを減らすとアクセス不能になる

※本件、カスタムエンドポイントで確認。
（Reader Endpointで同様に起こるかは未確認）

Auroraにはオートスケーリング機能があり、一定時間高い負荷がかかると自動的にインスタンスが増える仕組みになっています。

しかしながら、この設定を戻す時（インスタンスが減る時）にアクセス不能になる不具合があります。

Auroraを減らす前は以下のように正常にANSER SECTIONが返ってきますが、

```
$ dig xxxxx-ro-service.cluster-custom-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.68.rc1.58.amzn1 <<>> xxxxx-ro-service.cluster-custom-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26437
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;xxxxx-ro-service.cluster-custom-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com. IN A

;; ANSWER SECTION:
xxxxx-ro-service.cluster-custom-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com. 1 IN CNAME xxxxx003.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com.
xxxxx003.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com. 5 IN A 10.0.151.166
;; Query time: 4 msec

;; SERVER: 10.0.0.2#53(10.0.0.2)
;; WHEN: Mon Nov 16 10:15:54 2020
;; MSG SIZE  rcvd: 151
```

手動でカスタムエンドポイントから増えたインスタンスを削除すると、ANSWER SECTIONが返ってこない状態になります。（約15分間、返ってきたりこなかったりする）

```
$ dig xxxxx-ro-service.cluster-custom-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.amzn2.0.4 <<>> xxxxx-ro-service.cluster-custom-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 43227
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096

;; QUESTION SECTION:
;xxxxx-ro-service.cluster-custom-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com. IN A

;; Query time: 0 msec
;; SERVER: 10.0.0.2#53(10.0.0.2)
;; WHEN: Mon Nov 16 10:33:18 JST 2020
;; MSG SIZE  rcvd: 108
```

AWSに本件を質問したところ、以下の回答でした。
（2020/11/16現在、まだ改善はされていない様子）

```
カスタムエンドポイントからインスタンスを削除した際、
しばらくAレコードが返却されなくなるのは、恐れ入りますが、
現在の仕様となっております。

したがって、こちらを発生させないようにすることはできません。
ご期待に沿えない回答となり申し訳ございません。

代替案としては、変更後のカスタムエンドポイントを別に作成いただき、
アプリケーション側でエンドポイントを切り替えることで変更する方法が考えられます。
アプリケーション側の改修が必要となってしまい恐縮ですが、
ご検討いただけますと幸いです。

なお、こちらの仕様については、他のお客様からも機能改善のご要望をいただいており、
現在サービス担当部署にて検討中となっております。
具体的な日時等詳細は未定ですが、
本ケースもサービス担当部署へフィードバックさせていただきました。
```

## 回避方法

ワークアラウンドとして、カスタムエンドポイントをもう一つコピーしておき、以下の手順で都に戻します。

- アプリケーション側でコピーしたカスタムエンドポイントに切り替える
- カスタムエンドポイントから増えてしまったAuroraをエントリから外す
- 増えてしまったAuroraを削除する
- ↑の15分後に、アプリケーション側で元のカスタムエンドポイントに戻す
「(二桁整数)/10%10」で10の位の数字が得られることについて

## 10の位
二桁整数を29とすると
29/10とした場合、小数点が切り捨てられることを利用する。
つまり29/10の答えが2.9ではなく2と出力される。
次の計算として2%10を行う。10で割れないのでそのまま余りは2。
つまり10の位は2。

## 100の位
同じように100の位の数を取ってこようとすると、
378/100%10で得られる。
378/100=3
3%10は3。

それ以降も
1の位　整数/1%10
10の位　整数/10%10
100の位　整数/100%10
1000の位　整数/1000%10
・
・
と使えそうです。

## %10いるのか？
結論としては一番大きい桁の数字を持ってきたい時には不要。
なぜならすでに一桁の数字になっているから。

### 例
23の10の位を持ってくる
→23/10=2
で完了

123の10の位を持ってくる
123/10=12
12%10=2
で完了

以上
Optionalを使ったnull/空文字判定2.0

結局if文使うなら、いっそOptionalは一切使わないほうがいいよなって思ったりした。null/空文字判定をOptionalで進化させたい。

なお、以下断りがなければJava1.8以上で動作する想定です。

# きっかけ
最近、文字列の「存在チェック」を行うコードでこんなのを発見して、かなり違和感があった :thinking: 

```java
String uri = SystemPropertiesUtil.getPropertyOptional(Constant.URI).orElse("");

if (StringUtils.isEmpty(dkInfoGetApiUrl)) {
// nullならなんかやる
}
```

DBからAPIのURIを取得してきて、APIコールに使う場面です。 `getPropertyOptional` はOptionalを返すメソッド。
また、if文に登場する `StringUtils#isEmpty` はSpring Frameworkが提供しているユーティリティメソッド。

これなら普通にnull/空文字判定をすればよくて、Optionalを使わないほうがむしろシンプルでいい。

この例は少し極端だが、一般的によくある「nullではない∧空文字ではない」をOptionalを利用して使い勝手や安全性を向上させられないか、検討する。

# Optionalの性質
Optionalは、Javadocによると 
> null以外の値が含まれている場合も含まれていない場合もあるコンテナ・オブジェクトです。

とある ([Optional (Java Platform SE 8 )](https://docs.oracle.com/javase/jp/8/docs/api/java/util/Optional.html))。

`Optional#ofNullabele` でラップした時点でnull出ない場合はそのまま値を取得できるし、そうでない場合は別途処理をつけたせばよい。つまり、あえて空文字を返す理由もあまりない。

ただし、Stringのインスタンスがnullでないことと空文字でないことの双方を確認する場合、 `Optional#ofNullable` で初期化すると空文字でないことはチェックから抜けてしまことに留意する。


# 解決案
一般的に、空文字判定するときは

- nullチェック
- 空文字チェック

をまとめてbooleanを返すstaticメソッドで判定するケースが多いと思う。たとえば

```StringUtil.java
public static boolean isNullOrEmpty(String string) {
    if (string == null || string.equals("")) return true;

    return false;
}
```

それを、以下のように代替できないか。
Optionalで期待した文字列が入っていることを確認する場合、よくある `StringUtils` に以下のようなメソッドを追加してみる。

```StringUtil.java
public static Optional<String> ofPresentable(String string) {
    if (string == null || string.equals("")) return Optional.empty();

    return Optional.of(string);
}
```

2020-11-17：追記
コメントで別案をいただき、よかったので補足。

```StringUtil.java
public static Optional<String> ofPresentable(String string) {
	return Optional.ofNullable(string)
			.map(String::trim)
			.filter(s -> !s.isEmpty());
    // Java 11以上ならisBlankが使える
    // return Optional.ofNullable(string).filter(Predicate.not(String::isBlank));
}
```


戻り値をOptionalでラップすることで値が存在しない可能性を明示できる。そのため、今までなら

```java
SomeObject object = new SomeObject();
if(id == null || id.equals("")) {
    object.setId("default");
} else {
    object.setId(id);
}
```

としていたところを

```java
final String idPresentable = StringUtil.ofPresentable(id).orElse("default");
SomeObject object = new SomeObject(idPresentable);
```

とできる。
正直、やっていることに大きな差はないのだが制御構文がなくなることで状態の変更に気を配る負荷を小さくでき、追いかけやすく変更しやすくなる。
また、nullになる可能性を明示できるため、ロジック上nullになることはありえない箇所は任意の実行時例外を投げることで予期しないエラーを防ぐこともできる。

つまり、

```java
final String idPresentable = StringUtil.ofPresentable(id).orElseThrow(new RuntimeException("予期しない入力です"));
SomeObject object = new SomeObject(idPresentable);
```

100%代替できるわけではないし、向いてないユースケースもあるだろう。しかし、いくつかのケースにおいてはむしろこちらのパターンのほうが有効な気がしており、今後是非試してみたいと思っている。

# おまけ
今回、強烈な課題を感じたのが文字列の処理だったが、ListやMapについても同じようなメソッドを用意することで要素存在判定、ある場合の処理を簡潔かつ安全にできそうです。

たとえば

```ListUtil.java
public static <T> Optional<List<T>> ofPresentable(List<T> list) {
    if (list == null || list.size() == 0) return Optional.empty();

    return Optional.of(list);
}
```

リッチにするならリストの要素にnullが含まれているかも判定してもよいかもしれません。
AWSに Windows EC2 を作ってゲーム環境(クライアント側)を作る

## 背景
Windows機は過去に処分してしまったため、安くて頑張れるWindowsPCがほしいなーと思いました。
家庭用の一般的なネット回線(良くて100Mbps程度）。MacbookPro2019で接続。

# 主な流れ
1. EC2 のWindows版を作る
参考サイトを元に色々やろうと思ったがAMIをちゃんと選べばドライバーインストールとか全部不要。
    1. AMIの検索窓で「Windows nvidia」と調べるとAWS Marketplace で 14 件ほどひっかかる(20201110調べ)。
    2. この中に下の方にある「NVIDIA Gaming PC - Windows Server 2019」っていうやつがオススメ。このAMIはAWS Marketplace(https://aws.amazon.com/marketplace/pp/B07STLTHM8?ref=cns_srchrow) のページから作れる(通常のAWS内からだと作成できない)。
    3. g4シリーズが選べるのでこれをスポットインスタンスで作る(オンデマンドでもいいけど富豪だけ推奨)

2. RemoteDeskTopで接続する
    1. EC2の「接続」からリモートデスクトップ接続を落とす

3. Steam入れて遊ぶ
    * 音が出なかったのでサウンドドライバとかは必要そうです。

※参考サイト
https://medium.com/tensoriot/cloud-gaming-on-amazon-web-services-4be806c0051b

# 結論
出来たけど色々無理がある。未来はまだだった。

## 無理だなーと思った理由
とりあえず 1時間あたりで数ドル使うということが、エリクサー使わず攻略するような貧乏性の自分にはストレスマッハだった。後述で実際の利用金額明細を転載しておくがスポットインスタンスで無いとお金かかりすぎる。

スポットインスタンスを使うにはある程度のvCPUを使おうとすると制限解除のための依頼が発生し手間。

ディスプレイの解像度設定が見つからないため、解像度を基準に起動するゲーム(Apexとか)は起動できませんでした。
(AWS EC2でFPSゲームなどの高レスポンスを求めるものは無理ゲーなんだが検証としてがっくがくになることを見たかった)

はじめから分かってたことだが高レイテンシー、高レスポンスゲームは無理。サンドボックス系のまったりゲームを少しやってみたいなーという程度ならWindows持ってなければ試せる程度(Windows持ってればそもそもこれいらない)

プラン上げたら超快適かと思いきやそうでもない。2世代ぐらい前のPCを動かしてる感じ。普通にWindowsの操作自体がもっさりしてる。

## ※AWSのグレードについて
g4dn.metalなど、最上級プラン等だとvCPU数にlimitがかかっているため、制限解除依頼（＆利用用途報告）が必要になります。
また通常のオンデマンドと、スポットインスタンスでは制限解除は別枠のようです。

## チラ裏； 購入金額比較(単純計算)

* PC単純購入:
ざっくりゲームを潤沢にできるスペックのPCは、大体いつも20万強。
先日(2020/10/28)、Radeon RDNA2の発表もあって、すっごい物欲センサーが働いている。欲しい。
ケースからだから設置場所とか、本当に買うほどやるの？とか。高レイテンシーゲーム（FPSとか）やるなら必要。
PCは買っても寿命5年程度で見てる(大体新しいの出てきちゃうから欲しくなっちゃうよね)。

* クラウドでやれる環境を用意：
EC2 g4dn.xlarge の稼働で 0.894USD/時間(オンデマンドで計算。スポットインスタンスにしたらもっと減るはず)。
僕はものすごいゲームをやれたとしても100時間程度。とすると約1万円。
1000時間やったとしても$894(約10万円弱)。
金額は良かったとしても高レイテンシーゲームは無理ゲーだと思う。悲惨な香りがする。
EC2をいじる中で得られる知見とか、本当に問題ないの？とか検証する楽しみはある。

### ということで、実際に使ってみた。

Amazon Elastic Compute Cloud running Windows
* On Demand Windows g3s.xlarge Instance Hour2.000 Hrs ＄2.45 (＄1.224 per)
* On Demand Windows g3.16xlarge Instance Hour3.000 Hrs ＄27.79 (＄9.264 per)
* On Demand Windows g4dn.xlarge Instance Hour1.000 Hrs ＄0.89 (＄0.894 per)
* On Demand Windows g4dn.8xlarge Instance Hour3.000 Hrs ＄13.23 (＄4.410 per)
* On Demand Windows g4dn.16xlarge Instance Hour1.000 Hrs ＄8.82 (＄8.819 per)

Amazon Elastic Compute Cloud running Windows Spot Instances
* g3s.xlarge Windows Spot Instance-hour in Asia Pacific (Tokyo) in VPC Zone #83.000 Hrs ＄1.49
* g4dn.xlarge Windows Spot Instance-hour in Asia Pacific (Tokyo) in VPC Zone #81.000 Hrs ＄0.40

オンデマンドたけぇ。g3.16xlarge,g4dn.8xlarge、それぞれ3時間ずつで＄40ぐらい。
検証でドライバインスト待ちしたり、少しゲームやっただけで6000円弱ふっ飛びました。
Homebrewインストールできません。デイトラ中級編　Rubyコース受講中

## Homebrewインストールできません!!!

`$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"`をターミナルに入力しました。

すると。。。
謎のエラー文発生！

```
==> You are using macOS 11.0.
==> We do not provide support for this pre-release version.
This installation may not succeed.
After installation, you will encounter build failures with some formulae.
Please create pull requests instead of asking for help on Homebrew\'s GitHub,
Discourse, Twitter or IRC. You are responsible for resolving any issues you
experience while you are running this pre-release version.

==> This script will install:
/usr/local/bin/brew
/usr/local/share/doc/homebrew
/usr/local/share/man/man1/brew.1
/usr/local/share/zsh/site-functions/_brew
/usr/local/etc/bash_completion.d/brew
/usr/local/Homebrew
```

`Press RETURN to continue or any other key to abort `とあったのでEnterを押した。

するとXcodeのライセンスが通ってないと言われたので、[ライセンスの通し方](https://qiita.com/kazoo04/items/880283612abd85c0610a)をググりました。

```
$ sudo xcrun cc
```

このコマンドを叩くと同意してくださいと出たのでおもむろにEnterを押す。

そして再度

```$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)
```
を実行。

なんと！！！

```==> Installation successful!
```

インストールできたっぽい！
Vue + Electron の NodeIntegration でハマった話

## 環境について
@vue/cli: 4.5.8
vue: 2.6.11
electron: 9.0.0

**vue add electron-builder** でプロジェクト作成。
Typescrtipt使用。あと、関係あるかは分かりませんがvuetify（2.2.11）も使用。

## 起こった症状

ipcRenderer を ブラウザ側でimport使用とすると、**fs.existsSync is not a function** とエラーが発生し、ページが描画されない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758865/02687048-6f4b-aeb2-89c7-64c39b052ab1.png)

もちろん、webPreference の nodeIntegration は true にしてあります。

## 対処法

[vue-cli-plugin-electron-builderのissue](https://github.com/nklayman/vue-cli-plugin-electron-builder/issues/896)で解決したという人がいたため、そのリンク先である[Electronのissue](https://github.com/electron/electron/issues/9920) を見に行きます。
すると、require 周りでエラーが出ているのでラップするとか、preloadにipcRendererを入れるといいとか書いてあります。
でも前者はどこを直すかよくわからないし、後者はTypescrtiptを使っていると、windowにプロパティを足すのにいろいろと手間が必要……
なのでもう少し探してみることにしました。

## 解決

[上記のissue](https://github.com/electron/electron/issues/9920)の下のほうにありました。
vue.config.js をいじる方法です。

```vue.config.js
module.exports = {
  "transpileDependencies": [
    "vuetify"
  ],
  pluginOptions: {
    electronBuilder: {
      nodeIntegration: true
    }
  }
}
```

このpuluginOptionsを追加したところ、無事にエラーが消えてビルドできるようになりました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758865/d55d31a9-5dda-b6bb-2aed-d37e3ecb0bf6.png)


めでたしめでたし。
select2 is not a functionの解決策

## 原因
headタグ内でselect2を読み込んでた。

## 解決策

bodyタグを閉じる直前で、読み込むようにしました。解決。
`
  <!-- jQuery -->
  <script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
  <!-- select2 -->
  <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/js/select2.min.js"></script>
</body>
`