OmniAICreator/Qiita-1.07M huggingface dataset:
[Rails] ec2上でcronを使ってrakeタスクを定期実行


## 実現したいこと
ec2にデプロイしたrailsアプリケーションでrakeタスクを定期実行したい。
あまりいい記事が見つからなかったのでまとめました。

## 前提
2022年10月現在
ruby 3.1.2
Rails 6.1.6
whenever
ec2
capistranoを使ってデプロイ

## 手順

1. Capistranoを適用する
2. schedule.rbを編集する
3. crontabをupdate
4. タイムゾーンを変更する
5. ec2上でエラーログを確認する方法

## 1, Capistranoに導入

capfileとdeploy.rbを編集する。
```capfiel```
```ruby
require 'whenever/capistrano'
```
```deploy.rb```
```ruby
set :whenever_roles, -> { :app }
```

## 2, schedule.rbを編集する

確認すべきポイントはrakeタスクの環境がproductionになっているか。
そしてec2はbashなので、zshを使うような設定を書いている場合は消しておく。（デフォルトはbashらしいので何も書かなくていい。）
```schedule.rb```
```ruby
#環境変数の設定
set :environment, ENV['RAILS_ENV']

#以下のような記載がある場合はコメントアウトしておく。（ec2はbashなので）
#set :job_template, "/bin/zsh -l -c ':job'"

#以下はenvironmentの引数をENV['RAILS_ENV']にする。
#これでproduction環境の時、ENV['RAILS_ENV']に"produciton"が代入される。
every 1.day, at: '6:02' do
  rake 'chatroom:create', environment: ENV['RAILS_ENV']　　
end
```

## 3, pushとデプロイ

ここまでの変更をpushして、ec2にもデプロイしておく。

```ruby
git push
```

```ruby
bundle exec cap production deploy
```

## 4, crontabをアップデートする

デプロイが済んだら、schedule.rbの変更をec2上のcronにも適用させる必要がある。

```ruby
#アプリのパスで下記コマンドを実行
#現在のcrontabを確認
$ bundle exec whenever
# cronをアップデート
$ bundle exec whenever --update-crontab
# cronタブが変更されたか確認
$ crontab -l
```

変更されていなければ、ちゃんとpushしてec2にデプロイしたか確認すること。

## 5,タイムゾーンを変更する
以下は日本時間でスケジューラを実行したい場合に行う。
以下の操作は全てEC2のターミナルで行う。

```ruby
$ date  #現在時刻を確認する
=>UTCで時間が表示される
```

タイムゾーンを変更したい場合`/etc/sysconfig/clock`というファイルがあるのでこれを編集する。

```ruby
$ cd /etc/sysconfig
$ sudo vim clock
```

`sysconfig/clock`を以下のように編集。

```ruby
ZONE="Asia/Tokyo"
UTC=false
```
これで変更は完了。
変更したタイムゾーンを適用するにはcronの再起動とOSの再起動を行う必要がある。

```ruby
#cronの再起動
$ sudo service crond restart
```

```ruby
#OSの再起動
$ sudo reboot
```

## 補足 エラーログの確認方法
cronがうまくいかない場合はエラーログを確認したいだろう。
エラーログはec2上の/var/log/cronというファイルに書かれている。これを見るには下記コマンドを実行する。

```ruby
#ec2のターミナルで実行
$ cd /var/log
$ sudo cat cron
```
これでうまくいきました。
## 参考にした記事

Capistranoに導入
[【Ruby on Rails】EC2でwheneverを使ってcrontabを設定する時のハマったことの解決 - Qiita](https://qiita.com/YutoYasunaga/items/16b3ee52f9db99ae75a1)

ec2のcronにタイムゾーンを適用
[AmazonLinux(EC2)で、crondにタイムゾーン変更を反映するにはOS再起動が必要 - Qiita](https://qiita.com/zaru/items/897983832453d34442e1)

エラーログの確認方法
[cronがうまく動作しているかチェックするためのログ調査方法について](https://hodalog.com/how-to-inspect-cron-logs/)
初心者としてMinecraftゲームをマスターする方法

Minecraft は、10 代の若者の間で最も人気のあるオンライン ゲームの 1 つです。多くの人がゲームをプレイし、ゲームから多くのことを学びます。 Minecraft は最高のゲームの 1 つで、自分の世界を作り、必要なものを構築する機会を与えてくれます。

マインクラフトのアイテムを使って家を建てたり、単純に橋を作ったりすることができます。ユーザーが自分の世界を作り、仮想世界に住むための多くのオプションがあります。最高の家を作ることができ、最高の家具や必要なものをすべて作ることもできます。木、花、草を追加して、最高の環境を作ることができます。

Minecraft のツールをいつでも使用して、この複雑なゲームの単純なタスクを簡単に実行できます。クリックは Minecraft の非常に重要な部分であることを忘れないでください。クリック スキルに特に注意を払い、Drag Click Test : https://speedwallop.com/drag-click-test/ を介してドラッグ クリックするなどのクリック方法を学ぶことに時間を費やしてください。

マインクラフトをプレイする際に知っておくべき最高のヒントをいくつか紹介します。

## 初心者がマインクラフトに取り組む方法

探索、戦闘、または創造的な構築に集中したい場合でも、Minecraft にアプローチする方法はたくさんあります。ただし、すべてのプレイヤーがゲームを最大限に活用したい場合に知っておくべき重要なヒントがいくつかあります。

### 1. サバイバル モードで開始する 
これは Minecraft をプレイする最も難しい方法ですが、最もやりがいのある方法でもあります。サバイバル モードでは、リソースを収集し、避難所を建設し、敵対的なモブをかわす必要があります。目標は、できるだけ長く生き残ることです。

### 2. 自分の世界を探索する
Minecraft の最も優れた点の 1 つは、すべての世界が異なることです。時間をかけて周囲を探索し、どのような隠された宝物を見つけることができるかを確認してください。

### 3. 何かを建てる
シンプルな家であろうと壮大な城であろうと、建設は Minecraft でできる最も満足できることの 
1 つです。想像力を働かせて、何ができるか見てみましょう。

### 4. 友達を作る
他の人と遊ぶことは、Minecraft を楽しむ最良の方法の 1 つです。好きなサーバーを見つけて、他の人と遊んでみましょう。あなたはすぐに新しい友達を作り、たくさんの楽しみを持っています.

### 5. 楽しむ
これが最も重要なヒントです。Minecraft は楽しむためのゲームです。ですので、プレイ中はリラックスして楽しんでください。

ベテランの Minecraft プレイヤーでも初心者でも、常に新しいトリックやテクニックを学ぶことができます。ゲームを次のレベルに引き上げたい場合は、Minecraft をマスターするためのヒントをいくつか紹介します。
### インターフェイスに慣れることから始めます

ビデオ ゲームで成功するための鍵の 1 つは、インターフェイスの詳細を知ることです。これは特に Minecraft の場合に当てはまります。インターフェースは一見すると少し難しいかもしれません。さまざまなメニューとタブをすべて調べて、すべての場所に慣れてください。これにより、ゲームの途中で必要なものを簡単に見つけることができます。

### 建物のスキルを練習する

建設は Minecraft の最も重要な側面の 1 つなので、上手になることが重要です。オンラインまたは YouTube ビデオでチュートリアルを見つけて、実際に見たものを再現することをお勧めします。ガイダンスなしで、ゼロからプロジェクトを構築することもできます。構築すればするほど、うまくいくようになります。

### あなたの世界を探検

Minecraft の最も優れた点の 1 つは、すべての世界がユニークであることです。時間をかけて自分の世界を探索し、そこにあるさまざまなバイオームをすべて発見してください。これはリソースを見つけるのに最適な方法であるだけでなく、とても楽しいものでもあります。どこに行ったかを記録しておくと、いつでも家に帰ることができます。

### レッドストーンを利用する

レッドストーンは、単純な仕掛けの作成から精巧な機械の構築まで、さまざまな目的に使用できる強力なツールです。マインクラフトをマスターしたいなら、レッドストーンの使い方を学ぶことが重要です。基礎を学べるオンラインのリソースはたくさんあります。それがどのように機能するかを理解したら、実験を開始し、独自の作品を考え出すことができます.

### サバイバルワールドを作る

自分のスキルを実際にテストする最良の方法の 1 つは、サバイバル ワールドを作成することです。サバイバル モードでは、リソースを収集し、敵対的なモブをかわしながら健康を管理する必要があります。これは、建物とリソース管理のスキルを練習するのに最適な方法です。やりがいもあり、完成したときの達成感は格別です。

### マインクラフトで家を建てる方法

以下のガイドラインに従って家を建てます。
1. 家の設計図を作成します。

2. 材料を選んで、組み立て始めます。

3. 壁と屋根の色を選択します。

4. ドアと窓を作成します。

5. 階段を追加します。

6.フェンスを構築し、ゲートを追加します。

7. 植物と花を追加します。

8. 家のてっぺんにはしごを追加します。

9. 屋根に穴がないことを確認します。

10.家に家具を追加します。

11.家にテーブルとベッドを追加します。

12. 十分な照明があることを確認してください。

13. ペット用の部屋を作ります。

14. 装飾を加え、鏡を置きます。

15. 家にコンピュータを追加します。

16.家にトイレを追加します。

17. 家を掃除して、いい環境にしましょう。

### 結論

したがって、これらは、ゲームをプレイするために知っておく必要がある最も効果的なヒントの一部です。マインクラフトは無限の可能性を秘めたゲームです。 1 人でも、友達と一緒でも、サーバーでプレイしていても、常に何か新しいことをすることができます。
オープンソースソフトウェア

# オープンソースソフトウェアの定義
1．再配布を自由に認めること
2．ソースコードを無償で配布すること
3．派生ソフトウェアの配布を許可すること
4．ソースコードのどの部分が、作者オリジナルのコードかわかるようにすること（作者コードの完全性）
5．個人やグループに対する差別をしないこと
6．使用分野に対する差別をしないこと
7．プログラムに付随する権利はすべての再頒布者に平等に与えられること（ライセンスの分配）
8．特定の製品だけに限定したライセンスにしないこと
9．他のソフトウェアを制限するライセンスにしないこと
10．ライセンスは技術的に中立であること
出典 
https://hnavi.co.jp/knowledge/blog/oss/

# ライセンスの種類と特徴
オープンソースライセンスは一定の条件のもとでソフトウェアの使用、コピー、改変、再頒布（販売を含む）を認めている。
## 特徴
### 無保証とは?
```動作、及び、動作の結果、何あらかの障害が生じてもそれを保証しない```こと
### 同一ライセンスの適用
改変したソフトウェアを頒布する際に、```必ず元のライセンスを適用することを定めた```もの

### GPL(General Public License)
GNUで採用されているコピーレフトを実現するライセンス
#### GNUとは？
UNIX互換ソフトウェア群の開発プロジェクトの総称

#### コピーレフトとは？
* 著作権を保持し、利用、再配布、改変を制限しない
* 著作物の権利に関する考え方の一つで、著作物の自由な利用・改変・再配布を認め、また、そこから派生した著作物についてこれらの行為を制限してはならないとするもの。
  出典 https://e-words.jp/w/%E3%82%B3%E3%83%94%E3%83%BC%E3%83%AC%E3%83%95%E3%83%88.html
* ソフトウェアを改変した場合は、この考え方をそのまま適用する必要がある。改変したらソースコードを公開しなければならない。


### BSDL（Berkeley Software Distribusion LIcense)
このライセンスのソースコードをコピー・改変して作成したプログラムは、ソースコードを非公開にしたり、別ライセンスで頒布できる。
```これはコピーレフトではない```。
このライセンスならソースコードを非公開にして頒布できる。

### MPL(Mozilla Public License)
```原著作者だけに特別な権利を認める```ライセンスのこと

### デュアルライセンス
```２種類のライセンス形態を用意```しておき、```利用側がその片方を選択できる```もの。

# オープンソースソフトウェアの種類
### LAMP/LAPP
オープンソースで利用できるWebアプリケーションの構築環境として、システム規模を問わず広く利用されている。

### UNIX系OS
### Eclips(イクリプス）
Javaを始めとする```様々なプログラミング言語によるソフトウェア開発に対応した、オープンソースの統合開発環境（IDE）の一つ```。
主にJavaによる開発環境として開発され、Eclipse自身もJavaで記述されているため、Java仮想マシン（Java VM）が動作する様々な機種やOS上で同じように動作する。

Java開発に必要な機能の多くが同梱されており、独自のJavaコンパイラ（ECJ：Eclipse Compiler for Java）も添付されているほか、単体テストツールJUnitやビルドツールAntなどJava開発で標準的に用いられる外部ツールと連携することができる。
出典 
https://e-words.jp/w/Eclipse.html

### GCC(GNU Compiler Collection)
```GNUプロジェクトが開発・公開しているコンパイラ。``` ```様々なプログラミング言語のコンパイラを集めたパッケージとなっている```。多くのUNIX系OSで標準的に利用され、オープンソースのOSではOS自体のコンパイルに用いられることも多い。
様々な言語に対応しており、標準ではC言語やC++、Objective-C、Fortran、Java、Ada、Goのコンパイラが同梱されている。「gcc」はgcc内のCコンパイラの名称および実行ファイル名でもあり、C++コンパイラのことは「g++」、Javaコンパイラは「GCJ」（GNU Compiler for Java）と呼ばれる。
出典 
https://e-words.jp/w/gcc.html

### Tomcat（トムキャット）
Apache Software Foundation（アパッチソフトウェア財団）が開発・公開している、```Javaサーブレット（Servlet）やJSP（JavaServer Pages）の実行環境となるソフトウェア```。いわゆるサーブレットコンテナあるいはWebコンテナと呼ばれるサーバソフトウェアの一つで、Apacheライセンスに基いてオープンソースソフトウェアとして公開されている。
出典 
https://e-words.jp/w/Tomcat.html

# 出典
https://gihyo.jp/book/2022/978-4-297-12375-8
Promise.all()を自力で実装するとこんな感じ？

## コード

```ts
const all = <T>(...promises: ReadonlyArray<PromiseLike<T>>): Promise<Array<T>> => {
  if (promises.length === 0) {
    return Promise.resolve<Array<T>>([]);
  }

  let rejected = false;
  const map: Map<number, T> = new Map();

  return new Promise<Array<T>>((resolve, reject) => {
    promises.forEach((p: PromiseLike<T>, i: number) => {
      p.then((t: T) => {
        if (rejected) {
          return;
        }

        map.set(i, t);

        if (map.size === promises.length) {
          const values: Array<T> = [];

          for (let i = 0; i < map.size; i++) {
            values.push(map.get(i)!);
          }

          resolve(values);
        }
      }, (e: unknown) => {
        if (rejected) {
          return;
        }

        rejected = true;

        reject(e);
      });
    });
  });
};
```

## がんばったところ

1. たとえ`Promise(Like)`の終了(fulfilledになる)順番が配列のとおりでなくても、与えられた配列の順番のとおりに解決された値の配列を返す
1. 途中で例外が投げられた場合、そこで処理を中断する。そのとき例外がいくつあろうと初めの例外を返す

### 感想

なんとなく使っている`Promise.all()`だが、大まかな動作だけを再現するならそこまで難しくはなかった。
Linux udevについて

●「udevd」
「udev」と呼ばれる仕組みのためのデーモン（常駐プログラム）。
udevはデバイスファイルを動的に管理するための仕組みで、ハードウェアがシステムに接続された際に対応するデバイスファイルを作成する役割。
ハードウェアの検出はudevの役割ではなくカーネルが行っており、デバイスが追加・削除される都度、カーネルからイベントが送信され、udevdはカーネルからその情報を受け取ることで動作しています。このイベントを「uevent」。

■udevの動作のイメージ

①デバイスを接続。
②カーネルが仮想ファイルシステム sysfs（/sys）にデバイス情報を作成。
③カーネルがudevdにデバイス情報を通知。（uevent）
④udevdが/sysのデバイス情報を確認。
⑤udevが/devにデバイスファイルを作成。

udevのメイン設定ファイルは「/etc/udev/udev.conf」。「/etc/udev/rules.d」ディレクトリ内には、デバイスファイルの作成に関する個別の設定ファイル（ルールファイル）が入っている。

●udevに関連したコマンド

・udevcontrol udevを操作し、動作・停止などを行う
・udevinfo udevが認識しているデバイス情報を表示
・udevmonitor udevdの動作状況(カーネルのuevent、udevルールによるイベント)を関し、コンソールに出力

・udevadm サブコマンド　上記の機能を統合した新しいコマンド

Ubuntuなどの新しいディストリビューションでは、udevadmコマンドはudevcontrol、udevinfo、udevmonitorコマンド等を統合したコマンドとして使用。サブコマンドに「control」、「info」、「monitor」のように指定することで、上表の統合前の各コマンドに相当する機能を使うことができる。
会員向けのメール配信機能のショートコードを定義する。

カスタム投稿、「メール配信」が合ったとして、その投稿を会員向けにメール配信する場合、真っ先に思いつくのはadd_shortcodeによってそれぞれのユーザー情報を表示してメールを送信しようかと考えましたが、複数宛に送信したいので使えません。
なので投稿本文をstr_replaceで置換して上げて、returnで返すようにしてあげれば簡単に実装できます。
後はwp_mail等で送信します。

```php:functions.php
function mail_shortcodes($user_id,$body){
	$user_data = get_userdata($user_id);
    $shortcodes = array(
        'nickname' => get_user_meta($user_id,'nickname',true),
		'user_email' => $user_data->user_email,
    );

    $shortcd = array();
    $replace = array();
    foreach ($shortcodes as $key => $val) {
        $shortcd[] = '[' . $key . ']';
        $replace[] = $val;
    }
    return str_replace($shortcd,$replace,$body);
}
```
```php:test.php
$test_body = "[nickname]さん宛にメールします。\n";
$test_body .= "登録メールアドレス[user_email]";
$users = get_users();
foreach($users as $user){
	echo nl2br(mail_shortcodes($user->ID,$test_body));
}
```


問題点としてWordPressのショートコードとかぶる可能性があるので、[〇〇]ではなく別のもので囲ったほうが良いかもしれません。
{{〇〇}}など

## メモ
今回はfunctions.phpに定義しましたが、他でも使える部分なのでプラグイン化したほうが良いと思います。
テーマにロジックを書いてしまうとリニューアルや追加機能を実装する際に、どこまでがその範囲か分からず後悔するため
(以前WordPressでシステムっぽい事をしようとした際にそれで失敗しました。)
エクセルsheetを複数作成してくれるWebアプリを作ったよ(Python+Flask+GAE+Excel)


# エクセルsheetを複数作成してくれるWebアプリを作ったよ(Python+Flask+GAE+Excel)

## 出来たものがこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591409/14e1d92e-8452-3e07-770d-f782d032d763.png)

https://make-excel-dot-makeexcelsheet.an.r.appspot.com/

僕のような初学者が下記のようなプロセスで作成したという記録を書いていきたいと思います。


### きっかけ
仕事で各ソースファイルごとに調査をする必要があり、エビデンスとしてエクセルを使用。
各ファイル名のシートを作成するため、そのようなファイルを作成してくれるものが欲しかった。
Flask,GCPにも興味はあったので触ってみたかった。

### まず何をしたか
まずはFlaskで「Hello World」を表示ができるようにしました。
pythonファイルとhtmlファイルのみの構成でまずはSTEP1としました。


次にボタンを押したらとりあえずExcelファイルをダウンロードするように実装します。

こちらは「Flask Excel」と検索して出てきたサイトを参考にしました。
https://lightgauge.net/language/python/flask-excel-download

これが出来たら
textareaの改行をどのように処理されるのかの確認です。
改行がpythonに来る前に消されているかもしれないのでその確認を行います。

改行を含んでStringでやってきたのでsplitlines()で改行区切りのListに変えて、
それをfor文で回してシートの作成を行う。

この時点でダサいですが完成です。

あとはBootstrapに関して調べて連携、classごとにまとめてあるサイトからそれっぽいのを持ってきます。

これで完成です。

次にはGCPについて調べます。
アカウント作成など諸々を調べてデプロイして完成です。
requirements.txtとapp.yamlは作ります。


### 途中で躓いたエラーなど

```
ERROR: (gcloud.app.deploy) INVALID_ARGUMENT: The first service (module) you upload to a new application must be the 'default' service (module). Please upload a version of the 'default' service (module) before uploading a version for the 'production-service' service (module). See the documentation for more information. Python: (https://developers.google.com/appengine/docs/python/modules/#Python_Uploading%%20modules) Java: (https://developers.google.com/appengine/docs/java/modules/#Java_Uploading%%20modules)
```
こちらは
以下の記事に書いてありました。
https://qiita.com/ezaqiita/items/df24cdef6dee6d38509f

まずはdefaultとしてデプロイする必要があるそうです。
チュートリアルにあるHello wordをデプロイします。

①
```
Error: Server Error The server encountered an error and could not complete your request.
```
こちらは
```app.yaml
entrypoint: gunicorn -b :$PORT home:app
```
を追加したらうまくいきました。
また「home」というのは「home.py」がmainファイルだからです。
「hello.py」なら「hello:app」にする必要があります。

②
requirements.txtの文字コードの変更と
```
gunicorn==20.1.0
```
を書くことです。
こちらは公式に書いてありました。
https://cloud.google.com/appengine/docs/flexible/python/runtime#application_startup


③
ダウンロードできない....
ローカルではできるのに...
ログを見たらこう書いてありました。
```
OSError: [Errno 30] Read-only file system:
```

こちらは
https://qiita.com/namkim/items/3edb9abe3871963bf0f7
が参考になりました。
クラウドだとあるあるのようです。
一度tmpフォルダを間にかますことでダウンロードできました。
これのせいでローカル環境では動かなくなりましたが、まぁいいでしょう。

```python
# ワークブックをディスクに保存
    wb.save(r'/tmp/'+filename)

(中略)

 # ダウンロードするEXCELファイルを開く
    wb = open(r'/tmp/'+filename, "rb")

(中略)

# MIMEタイプをレスポンスに設定
    os.remove(r'/tmp/'+filename)
```

としました。

## これから
フールプルーフ的な制御などなにもないので、これらについても考えたりしないといけませんねぇ...
説明文に何を書けば満足なのか、ヒントテキストはどうすれば良いのかなど自分にセンスがない部分は絶賛苦戦中です。
特定の文字列の数をカウントする方法

# 概要
特定の文字列の数をカウントする方法を備忘録として残します。

# はじめに
scanメソッドとlengthメソッドを活用します。まずは復習から。

## scanメソッドとは？
対象の文字列の中に特定の文字列の検索結果を配列として返します。
```ruby
"foobarbazfoobarbaz".scan("ba")
# => ["ba", "ba", "ba", "ba"]
```

## lengthメソッドとは？
文字列の文字数を返します。
```ruby
def count_hi(str)
  puts str.length
end
count_hi('abc hi ho') #=> 9
```
ん？？それだと、今回の文字列の数をカウントするには使えない？

# 文字列の数（要素数）をカウントするには？
lengthメソッドにはstringクラスの他にも、arrayクラスにもあります。
上記のカウント方法は、stringクラスで取得したものです。
今回はarrayクラスを活用して要素数を取得します。
```ruby 
array = ["abc hi ho","hihi","efgh"]
puts array.length #=> 3
```
無事に要素の数を取得することができました。

よって、以下のように記述し、特定の文字列の数をカウントすることができました。
```ruby 
def count_ba(str)
  puts str.scan("ba").length
end

count_ba("foobarbazfoobarbaz") #=>4
```

# 参考
scanメソッド：[公式リファレンス](https://docs.ruby-lang.org/ja/latest/method/String/i/scan.html)
lengthメソッド:[公式リファレンス](https://docs.ruby-lang.org/ja/latest/method/Array/i/length.html)
AtCoderを始めてみる。

競技プログラミングサイト[AtCoder](https://atcoder.jp/?lang=ja)を始めるに当たって、進め方や詰まったポイントを随時更新していきます。

始めるに当たって、@snaruse0608さんの記事を参考にさせていただきました。

https://qiita.com/snaruse0608/items/9ef0f2f5b190f142cb80

## C++入門とコードテストを活用

* 言語は競技用プログラミングでよく用いられるC++を選択
* [AtCoder Beginners Selection](https://atcoder.jp/contests/abs)から始める

上記の方針で進めてみまましたが、そもそも**C++に関する知識が圧倒的に不足**していたので、AtCoderが公開している[C++入門　APG4b](https://atcoder.jp/contests/apg4b)から取り組みました。

これが**非常に分かりやすい**ので、初学者にはおすすめです。

以下の流れを反復して学習を進めていきます。
1\. 教材で基礎知識をインプット
2\. コードテスト実行
![code_test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729078/7b693661-1c47-8cba-2287-67b8d49c3712.png)


https://atcoder.jp/contests/apg4b

### 基本的な進め方
解説を読みながら、自分で手を動かしながら定着させていきます。また、コードを書くことに慣れていない人は、こまめにコードテストを挟むと良いかもしれません。
![スクリーンショット 2022-10-09 13.55.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729078/4972c859-2b08-033c-b8c3-7dd87f6dd512.png)
基本的な説明を読んだら、ページ下部にある問題を解いたり、過去問を解きながら理解出来ているか検証します。

https://qiita.com/drken/items/fd4e5e3630d0f5859067

![スクリーンショット 2022-10-09 13.58.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729078/695e71c7-d682-d9ee-31bf-b1d6b9eaedf1.png)
値上げの(2022年)10月「吉野家の牛丼 メニュー」をサクラエディタの置換を使ってmarkdown表に変換してみた。

(2023/08/25追加)
納豆定食 店内価格373円(税込410円)
https://www.yoshinoya.com/menu/morningset/nattou-tei/
吉野家で「400円朝食」を注文してみた＜yahooニュース
https://news.yahoo.co.jp/expert/articles/a0650992c87f9a7174c9914c302ed4949a57f1de

(2022/09/26追加)
商品価格改定のご案内2022 年 9 月 26 日
https://www.yoshinoya.com/pdf/kakaku_kaitei/

オリジナル

https://www.yoshinoya.com/menu/gyudon/gyu-don/

以下、牛丼 のメニューだけです。
どなたか全メニューをスクレーピングしてもらうと助かります。
写真があるから、メニューなのかもしれませんね。

# markdown表(2022-10-01)
以下間違っていたら、ごめんなさい。手打ちしています。
税込価格
|my追番|カテゴリー|size  |改定後(円)|2022-10-1改定後(円)|改定前(円)|
|----|-----|------|-------|-------|-------|
|001 |牛丼   |小盛    | |426|~~404~~|
|002 |牛丼   |並盛    | |448|~~426~~|
|003 |牛丼   |アタマの大盛|   |569|~~547~~|
|004 |牛丼   |大盛    |    |635|~~613~~|
|005 |牛丼   |特盛    |     |800|~~778~~|
|006 |牛丼   |超特盛   |  |921|~~899~~|

# 参考
markdown表の中に,訂正線~~が使えた。

https://qiita.com/mrrclb48z/items/aeb26b1b9a69ce19a421

https://www.google.com/search?q=%E5%80%A4%E4%B8%8A%E3%81%92%E3%81%AE10%E6%9C%88&rlz=1C1CHBD_jaJP908JP908&sxsrf=ALiCzsZUQQqkaQAXvdk3xO9C07A8couYJg%3A1664610962825&ei=kvI3Y4uGMob60gSFzKHQCw&ved=0ahUKEwiLl4OJx776AhUGvZQKHQVmCLoQ4dUDCA4&oq=%E5%80%A4%E4%B8%8A%E3%81%92%E3%81%AE10%E6%9C%88&gs_lcp=Cgdnd3Mtd2l6EAwyBQgAEKIEMgUIABCiBDIFCAAQogQ6CggAEEcQ1gQQsANKBAhBGABKBAhGGABQowhYowhghSRoAXABeACAAWKIAbsBkgEBMpgBAKABAcgBCsABAQ&sclient=gws-wiz
チェックボックスで使われる要素

# コードの意味がわからないの要素を調べてみる。

```html
<fieldset>
    <legend>Select a maintenance drone:</legend>

    <div>
      <input type="radio" id="huey" name="drone" value="huey"
             checked>
      <label for="huey">Huey</label>
    </div>

    <div>
      <input type="radio" id="dewey" name="drone" value="dewey">
      <label for="dewey">Dewey</label>
    </div>

</fieldset>
```
出典
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio

# ```<fieldset>```要素とは？
「FIELDSET」とは、```<form>タグで定義するフォームの入力項目をグループ化するためのタグ```です。
グループ化を行うことにより、グループの間をtabキーで簡単に移動することが可能になります。
出典 https://html-coding.co.jp/annex/dictionary/html/fieldset/

# ```<legend>```要素とは？
「凡例」、「説明文」、「銘」などの意味を持ち、```<fieldset>でグループ化されたフォームの入力項目に対して、タイトルを付けるためのタグ```です。
出典 https://html-coding.co.jp/annex/dictionary/html/legend/

# ```<label>要素```とは?
フォームの中で```フォームの項目名と構成部品（チェックボックス、ラジオボタンなど）を関連付けるためのタグ```です。
関連付けを行うことにより、```ブラウザでラベル（もしくはラベルのアクセスキー）をクリックした際に、その構成部品をクリックしたのと同じ動作が可能```になります。

<label>タグの指定方法には2つあり、1つは```<label>タグのfor属性の値と、フォーム部品のid属性の値を同じにすることで両者の関連付けができます```。
もう一つは、```<label>～</label>```内に部品とラベルを配置するという方法です。
ただし、この方法はInternet Explorer6以前のブラウザには対応していないので、できるだけ前者を用いた方がよいでしょう。
出典 

https://html-coding.co.jp/annex/dictionary/html/label/

# ```<input>```要素の属性
### name
* 部品の名前を指定します。 文字列で指定
出典

https://html-coding.co.jp/annex/dictionary/html/input/

* ラジオボタンで、同じ name の値を持つ複数の選択肢から一つの値を選択することができます。
出典
https://developer.mozilla.org/ja/docs/Web/HTML/Element/input

### id
すべての入力欄を含む、すべての要素で有効なグローバル属性で、```文書全体で一意でなければならない一意の識別子 (ID) を定義```します。その```目的は、リンクする際に要素を識別すること```です。```この値は、ラベルとフォームコントロールをリンクするための <label> の for 属性の値として使用```されます。 <label> を参照してください。
出典

https://developer.mozilla.org/ja/docs/Web/HTML/Element/input

### value
部品の初期値を指定します。 文字列で指定
出典

https://html-coding.co.jp/annex/dictionary/html/input/

### checked
Redmine APIから得られるissueXML要素まとめ


## 動機
- APIでXMLを取得したときのメモです。

## 環境
### 管理->情報 から取得
| 項目 | 内容 |
| ---- | ---- |
|Redmine version |                5.0.2.stable|
|Ruby version |                   2.6.10-p210 (2022-04-12) |[x64-mingw32]
|Rails version |                  6.1.6|
|Environment           |         production |
|Database adapter |               Mysql2|

## issue要素
|要素名|日本語表示名|
| - | - |
| project | プロジェクト |
| tracker | トラッカー |
| status | ステータス |
| priority | 優先度 |
| author | 担当者 |
| parent  | 親チケット|
|id|チケットID|
|subject|チケット名|
|description|説明|
|start_date|開始日|
|due_date|期日|
|done_ratio|進捗率|
|is_private|プライベート|
|estimated_hours|予定工数|
|total_estimated_hours|合計予定工数|
|spent_hours|作業時間|
|total_spent_hours|合計作業時間|
|created_on|作成日|
|updated_on|更新日|
|closed_on|終了日|

## issueの属性のある要素
| 要素名  | 属性名 |
| - | - |
| project | id |
|| name |
| tracker | id |
|| name |
| status | id |
|| name |
| priority | id |
|| name |
| author | id |
|| name |
| parent | id |

## 参考リンク
- [Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
- [[Python] Redmine APIで情報を読み込む](https://qiita.com/flcn-x/items/89e8f709277c9fbf6275)
WebAssembly: Conditional Segment Initialization Proposals を眺める

## そんな WebAssembly Proposals 聞いたことないんだが

[Bulk Memory Operations Proposals](https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md#motivation-for-conditional-segment-initialization) の一部になっている。もともとは別の WebAssembly Proposals だったが、Bulk Memory Operations Proposals に統合された...らしい。

## Conditional Segment Initialization Proposals とは

### WebAssembly data セクションの前提知識

WebAssembly Module の instantiate 時に、線形メモリに格納されるべき値を定義できる。

```wat:data セクションの例
(module
  (memory (export "memory") 1)
  (data (i32.const 16) "Hello, WebAssembly!\0")
)
```

上記の .wat だと、初期化時に線形メモリ上の先頭から 16 ~ 36バイトの範囲に、"Hello, WebAssembly!\0" のバイナリ表現が書き込まれる。

```:線形メモリ
     | 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |
---- | ----------------------------------------------- | ------------------
0000 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ........ ........
0010 | 48 65 6c 6c 6f 2c 20 57 65 62 41 73 73 65 6d 62 | Hello, W ebAssemb
0020 | 6c 79 21 00 00 00 00 00 00 00 00 00 00 00 00 00 | ly!..... ........
```

### Conditional Segment Initialization Proposals があると

上記の線形メモリの初期化が WebAssembly Module の instantiate 時にしかできなかったのが、任意のタイミングで実行することが可能となる。

## Conditional Segment Initialization Proposals の使い方

### 1. data オフセットを削除する

data オフセット (上記の例だと `(i32.const 16)`) がない data セグメントは、Passive Segment として取り扱われ、線形メモリの初期化には使われなくなる。

```wat:オフセットを削除した後
(module
  (memory (export "memory") 1)
  (data "Hello, WebAssembly!\0")
)
```

### 2. `memory.init` 命令を追加する

data セクション から線形メモリに書き込む WebAssembly OpCode が `memory.init` である。

```wat
(memory.init <セグメント番号>
      (i32.const <線形メモリの書き込み先オフセット>)
      (i32.const <書き込まれるセグメントのオフセット>)
      (i32.const <書き込まれるデータの長さ>))
```

```wat:memory.init の例
(memory 1)
(data "Hello, WebAssembly!\0")

(func $start
    ;; copy data segment 0 into memory 0 (the 0 is implicit)
    (memory.init 0
      (i32.const 16)    ;; 線形メモリの先頭から 16 バイトの位置に
      (i32.const 0)     ;; データセグメントの先頭から
      (i32.const 21))   ;; 21 バイトを書き込む
)
```

### ほかにできることは？

* Table の初期化も同様に任意のタイミングに遅延させることができる
* `data.drop` 命令を使って、今後その data セグメントが使われないことを明示できる
  * 従来通りの data セグメントに対して `data.drop` 命令を使うことで実行時のメモリ使用量を削減できるかどうかは要調査

## あとがき

* Bulk Memory Operations Proposals は早い段階から知っていたが、`data.drop` の存在意義とかがいまいちわかっていなかった
* [Thread Proposals](https://github.com/WebAssembly/threads/tree/main/proposals/threads) に Conditional Segment Initialization Proposals の記述があってなんだそれってなった
* C/C++ からの使い所がわからない (
Visual Studio Installerが起動しないよぉ

久しぶりにVisual Studioを使ってみようとVisual Studio Installer を開こうと思いました。
しかし、開かない...
仕方なしに再インストールしてみようと思ってInstallerをダウンロードして実行してみましたが、ファイルの展開っぽいことはするけどそれっきり...

Visual Studio自体はなぜか開けるけど、Installerが開かないので機能の追加やVisual Sudioのインストール・アンインストール等が全くできない状況になりました。

今回は、Visual Studio Installerが開かない問題を解決できたので記事にしました。

# 解決策

環境変数が悪さをしていたみたいです。
環境変数`TMP`と`TEMP`を

```
%USERPROFILE%\AppData\Local\Temp
```
に直す**だけ**。

（僕の場合は末尾にセミコロンが入っていました）

# 解決に至るまで

最終的に環境変数が悪さしてるかもしれないと感じたのは以下のページです。

https://stackoverflow.com/questions/69966188/cannot-install-visual-studio-community-edition-ide-and-always-run-into-dll-not

それまでには、

- InstallerCleanup.exeの実行
- .NET系の削除
- `sfc /scannow` の実行
- Tempフォルダの削除

などいろいろやってみましたが解決せず。
OSの再インストールしかないかなぁと思っていたところ環境変数の問題とわかり、解決したので一件落着！

問題を放置していた期間も含め、なんだかんだ解決まで半年ぐらいかかったので解決してよかった(^▽^)/
TypeError: this.libOptions.parse is not a function

### 回避方法
```
yarn add eslint@8.22.0

npmの場合は
npm install eslint@8.22.0
```
WebStormなどJetBrains製のIDEでTypescriptのプロジェクトを開くとよく出くわす

出典
https://stackoverflow.com/questions/73509984/eslint-typeerror-this-liboptions-parse-is-not-a-function
postdev:フロントエンド開発テスト最前線

# postDevとは

https://lp.nijibox.jp/cp/postdev/

https://nijibox.connpass.com/event/256080/

---

## フロントエンド開発テスト最前線

登壇者

株式会社リクルート / 株式会社ニジボックス デベロップメント室室長
Software Engineer
古川 陽介

タワーズ・クエスト株式会社 取締役社長
Programmer / IT consultant
和田 卓人

株式会社リクルート / 株式会社ニジボックス
Software Engineer
倉見 洋輔

### テストの歴史

フロントエンドという概念自体もここ10年ぐらいできてきたような気がしている
そもそもフロントエンドテストって、あまりこう書かれてこなかったのかなとかその辺の経緯が私はちょっとなんとなく肌感覚としてある
ロジックの部分では帰ってくるんですけど、見た目のところのテストは少ない

自動テストのテストコードは少ない。コスパが悪くてどんどん治安が悪化していった。目視確認に置き換えられていった
なぜか→頻繁に変更が生じるたびにテストコードが壊れてメンテナンスがかかる。そもそも技術的にも難しい。

テストコードがあると将来の開発における投資ではあるが、現時点で投資効果に見合わない

> E2Eテストでは？

フロントのテストは正解を決められない。それなのに壊れやすくてメンテナンスが必要。
コストをかける意味はあるがコストがかけられない
テストを実施できるように画面を30秒スリープする謎の処理を入れていた

### フロントエンドにてテストができるようになった背景

フロントエンドとバックエンドが分離されるようになった
それに伴ってフロントエンドでは
サーバーサイドがなくてもDOMが構築できる、
バックエンドがなくてもデータがあればフロントエンドだけで画面が描画できる
アーキテクチャーの勘所（PinchPoint）がわかっていれば、フロンド／バックでマルチで開発できるようになった
ロジックをフロントエンドに搭載することで、フロントエンドでテストをする必要が出てきた
E2Eテストの重要性は下がり、データさえ準備すればテストできるようになった

### テストは書いて当たり前の時代へ

PinchPointをJSONで置き換えることで
INが決まればOUTも決まる←テストが一番書きやすいパターン
様々なエンジニアがテストライブラリを作りだした
期待値のHTMLを人が準備していたが、HTML同士でアサートすることが難しい
スナップショットしたHTMLを実行時にアサートする手法が誕生した→`スナップショットテスト`

ファントムjsではflexboxが描画できなかった
ブラウザのレンダリングエンジンの中のコンポーネントをpackage.jsonに含めることができるようになり
ブラウザ依存によるアサートの精度も向上した

### フロントエンドテストを支えるツール

> データをINとしてhtmlをOUTとするには？

MSW－Mock Service Worker
MSWをPinchPointに入れてhttp通信をhackした状態で実働に近い形でテストができる
HTTPステータスコードのアサートもできる

https://mswjs.io/

ツールの目的はフロント／バックの両方でスキーマを真ん中において開発できることを目的とすること
本番とテストで構成を変えずに利用できるもの、CI/CDができること
本物とモックとの違いにどれだけ早く気付けるかが大事

### どんなテストをしているのか

StoryBook

https://storybook.js.org/

https://t.co/GBSdHWZ3kE

graphql
スキーマ部分にgraphqlを使うと型が決まるので、型が異なることに早く気付ける

### フロントエンドテストの今後について

再現できるテストが増えてきたが、不安定要素もまだある

> フレイキーテスト

https://www.publickey1.jp/blog/22/itjenkinsdevops_days_tokyo_2022_1.html

* プロダクトコードの変更

テストが壊れるから変更を懸念することはあってはならない。
そのためにアクセシビリティがあるかん
アクセシビリティが高い画面はテストが壊れにくい→テスタビリティも向上する
メンテナンス性を上げることでアクセシビリティも向上する

テストを導入することでフロントエンドのコードにアクセシビリティが必要となった
エンジニアの気付きが生まれた。品質向上のためのトップダウンが開発生産性としてボトムアップにも発生した。

### 最後に

フロントエンドテストの`よもやま`トーク
ありがとうございました

---
モンキーテストの心得 ( システム開発の品質保証 )

# モンキーテストとは

定められた要件は気にせずアプリケーションを動かして動作確認をすることだ。
要するに気ままに勝手に動かしてみるってことだ。

<img width="780" alt="image" src="https://user-images.githubusercontent.com/13635059/193393285-2cedd18a-ea97-4373-be6b-8c1ba91ae523.png">

# 経緯

とある開発で品質保証のためにモンキーテストをした。
モンキーテストをするのはこれで2回目だ。

なので決して自分がテスターの腕が良いわけではないと思うのだが、そこで考えたことを記す。

# 心得: 壊すつもりで動かす

開発者には無意識にアプリケーションの弱点を見て見ぬ振りをする傾向があると思う。だがテスターはその逆を行く。なるべく意地悪に無茶をして欠陥を見つけ出すのだ。

これは基本中の基本で言わずもがなではあると思うが。

# 心得: 初心者の目線、ユーザーの目線で見る

システムについては全く無知なユーザーとして振る舞ったほうが良い。
結局ユーザーに見えるのはシステムの裏側ではなく目の前のアプリケーションだけなのだから。

逆にシステム的な都合で見てしまうのはアンチパターンだと思う。

たとえ「このUIは不親切に見えるが恐らくライブラリの都合で作りづらいんだろうな」などと考える必要はない。
たとえ考えたとしても自分で納得して報告を思いとどまる必要はない。

# 心得: バグを見つけても原因究明のためにコードを見ない

何かバグを見つけた時にコードを見る必要はない。
たとえあなたが開発者でコードが読めたとしてもだ。

コードを読む時間があるなら他のバグを見つけ出した方が有意義だ。
原因究明は開発者に任せよう。

もちろん状況次第だが。

# 心得: コードリーディングは弱点を見つけるために活かす

僕はモンキーテストと共にコードレビューにも加わっていたので、ある程度コードは読んでいた。この経験はアプリケーションの弱点を見つけるために活かす。
動作が怪しそうな点があればモンキーテストではその箇所を重点的に動かしてみるのだ。

# 心得: チケットを積むのを遠慮しない

「今は開発が忙しそうだからバグチケットを積むのは気が引ける、やめておこう」などと考えていてはテストは成り立たない。

まずは見つけられるだけのバグを見つけておいて、そこから優先度の振り分けをすれば良い。
テスト中にはバグか仕様か分からないものも見つかるかも知れない。とりあえず報告するかチケットを積もう。黙っているのが最も良くない。

「バグを全く知らない状態」よりも「バグを知っているが解決が間に合わない状態」の方がまだましだ。
何故ならプロジェクトでの問題認識さえしていれば未来の解決を検討できる。
もし当のアプリケーションが以後アップデートされないものだとしても、バグが報告されれば開発者は以後の別の開発で気をつけることが出来るだろう。


# 心得: 複数人でテストする

1人ではテストをやり切ったと思っても別の人が見ると別のバグ・不備が出てくることもある。
複数人の視点が必要だ。

# 心得: エンバグに気をつける

開発あるあるで1個の修正が別のバグを生むものだ。
修正がおこなわれた周辺機能は改めて動かしてみること。

# 心得: 責任範囲を超える

テスターの役目はただテストをすることではない。
アプリケーション並びにサービスに寄与することだ。

なので気になることがあれば言ってみた。
「この仕様本当にこれで良いの？」「コストがかかるから今直さなくても良いのでは？」など。

船が正しい方向に向かっているか問うのは船長だけの仕事ではない。
乗組員も声を上げて良いはずだ。

# 反省: バグは早めに見つけたい

いちどテストをやり切ったと思っても実はそうではなかった。
また日を改めて試すと別のバグが見つかり始めた。

発見が遅れるほど修正も遅くなる。
なるべくテスト期間前半に多くのバグを見つけ出しておきたい。

# 反省: テストしにくい部分もちゃんとテストする

操作が難しい部分、準備が面倒な部分はテストを避けがちだ。
自分が避けてしまっているテストがないか自覚的になること。そしてちゃんとテストをしよう。

# 感想

- 「本当にこんな些細な点まで報告して良いのか？」「自分が変なことを言っていないだろうか？」という心配も持ちながらテストをしていた。だが迷ったらアプリケーション自体に尽くすことを考えた。メンタルの持ち方は重要なファクターだったと思う。
- プログラミングもせず、専門知識も全く必要なく、アプリケーションを動かしてケチを付けるだけで仕事になる。少し不思議な感じもした。
- コードを書けばコードレビューがある。だがテストのやり方や自分の動きに対するフィードバックはもらっていない。もし見る人が見れば多数の落ち度があるはずだが…。
- コードレビューとテストは神経質な人にやらせなさい。たとえば僕みたいな。
- モンキーテスト専門家に私はなりたい。

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
Windows10のファイアウォールで特定IPアドレスとの通信を完全にシャットアウトしたいよお

# 概要

間違って本番サーバー（特定IPアドレスのPC）のデータを壊さないようにしたい。
とにかく全てのアプリケーションに対して本番サーバーとの通信をシャットアウトしてよい。

そんな時。

# やり方

コントロールパネル⇒システムとセキュリティ⇒Windows Defender ファイアウォール⇒詳細設定 。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/dd1cba2d-67ee-075d-3216-33a1f2750734.png)

送信の規則⇒新しい規則 。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/ae9e2e31-aca8-a85a-05f9-64bc1cb6af16.png)

カスタム 。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/2b803135-9f86-9be3-39f5-4d6d28174c9c.png)

すべてのプログラム 。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/2136f05e-f7c7-8c4b-9162-a1c06c63b2f2.png)

プロトコルの種類は『任意』。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/07deaaa2-83bf-b6b4-a0be-cc82b20fe8bc.png)

リモートIPアドレス追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/17b137bb-f505-b809-38c9-ddfc60487a8b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/1d9f84ca-3de4-fa5e-471d-be43d5324f24.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/712b78c5-6d19-fe02-ae0a-f52d916b1fed.png)

接続をブロックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/50129d19-cba2-d53b-9613-30620ab085ed.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/b28889c9-78be-2380-6426-2ac99cc101aa.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/da38e2d0-2bd8-cfde-817a-9b02c1a0cd47.png)

**受信の規則** にも同じような **新しい規則** を作成。
（手順は送信の規則とほぼ同じなので割愛）

# hostsファイルによる設定もあり

要件によってはファイアウォールを使わず、hostsファイルを変更するやり方も検討の余地あり。

https://qiita.com/waokitsune/items/5a02419f6e001ba3325c

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.2075
スポットインスタンス もう少し詳しく調べてみる

## 勉強前イメージ

スポット的に買ったりするやつ？
オンデマンドより安いイメージ

## 調査

### スポットインスタンス とは

スポットインスタンスとはEC2の空いているキャパシティを活用して
オンデマンドインスタンスより安く使用するインスタンスの購入方法を指します。

元々EC2のインスタンス購入方法には以下の3種類あります。

- オンデマンド

使用した分だけ支払いをするインスタンスで、EC2を普通に利用しようと起動するとこちらになる。
EC2の定価で支払いをします。

- リザーブド

1年や3年使用するというコミットがある代わりに安く使用できる方法です。
インスタンスタイプを変えられたり、インスタンスファミリーの中で変更できたり細かく決められています。
詳細は [こちら](https://qiita.com/miyuki_samitani/items/41fa570054568bbbac5f) をごらんください

- スポット

今回のタイトルになってるインスタンスの購入方法。
空いているインスタンスを安く購入できるが、空きがなくなると停止される可能性がある。

### スポットインスタンスの特徴

- 低コスト

ものにもよりますが、最大9割引のインスタンスも存在します。
空いているインスタンスがスポットインスタンスになるため、空きがなくなると停止される可能性があります。
2分前に中断の通知がインスタンスメタデータかcloudwatch eventsで受け取ることが出来ます。
その為、スポットインスタンスでの処理が途中であっても問題なくサービスを継続できるような設計だとスポットインスタンスは最適です。

- 起動方法が簡単

起動方法はGUIでは以下のように スポットリクエスト から設定を行います。
APIでも設定が可能で、また一度のリクエストで1000台以上起動できるため、短時間でも大量に使いたい！というのも出来ます。

![1EC2 Management Console - Google Chrome 2022-10-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/ac5d1fa9-55e3-3e6b-fb8d-da188ab3d77e.png)


- 選択肢が多い

メモリやCPUを選択しておくと自動で選んでくれる機能や、逆に自分で選ぶことも可能です。
また、配分戦略と言ってどういうときにインスタンスを立ち上げるかなども指定できることもあり、選択肢が多く自由に設定することが出来ます。
最大9割引と記載していますが、空きがなくなってくると割引率が低くなり、空いてくると割引率が高くなります。
その為費用を重視するのであればどういう費用のときに立ち上げるかという選択をすることも可能です。
ただし、費用が高くなっても上限はオンデマンドインスタンス(定価)の料金に設定されているので定価より高くなることはないです。

## 勉強後イメージ

中断通知って2分前ってめっちゃギリやし、基本的には手動は考えられてなくて自動で変えのインスタンス立ち上げたりすることを前提に作られてるなーって感じがしてる。
基本的に落ちてもいい処理っていうのがスポットインスタンスが強いところみたいね、いつ落ちるかわからんし。

## 参考

- [[AWS Black Belt Online Seminar]Amazon EC2スポットインスタンス](https://d1.awsstatic.com/webinars/jp/pdf/services/20190306_AWS-Blackbelt-EC2Spot.pdf)
- [スポットインスタンス 【spot instance】](https://e-words.jp/w/%E3%82%B9%E3%83%9D%E3%83%83%E3%83%88%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9.html)
C# フォルダの中のファイルをZIP化する .NET6

.NET6でフォルダをZIP化してダウンロードする

## Zip化クラス
フォルダごとZIP化したい場合、ファイル名を`folder/sample.txt`と指定すればOK

```C#:ZipArchiveService.cs
using System;
using System.IO.Compression;

namespace SampleSystems.Service
{
    public class ZipArchiveService
    {
        public byte[] ConvertFilesToBytesForZip(string filePath)
        {
            using (var ms = new MemoryStream())
            {
                using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, true))
                {
                    string[] files = Directory.Exists(filePath) ? Directory.GetFiles(filePath) : new string[0];

                    foreach (var path in files)
                    {
                        string fileName = Path.GetFileName(path);
                        using var fs = System.IO.File.OpenRead(path);
                        byte[] bytes = new byte[fs.Length];
                        ZipArchiveEntry addEntry = archive.CreateEntry(fileName, CompressionLevel.Fastest);

                        using (var entryStream = addEntry.Open())
                        using (var zipStream = new MemoryStream(bytes))
                        {
                            zipStream.CopyTo(entryStream);
                        }
                    }
                }

                return ms.ToArray();
            }
        }

    }
}
```

`.NET Core`だと`WebClient`でbyte配列に変換できていたが`.NET6`では使えなかった
```C#
var client = new WebClient();
byte[] bytes = client.DownloadData(filePath);
```

## コントローラー
`View`のボタンを通じて`Controller`から呼ぶ
```C#:HomeController.cs
public IActionResult ExportZip()
{
    try
    {
        string filePath = _configuration["Uploads"];
        var zs = new ZipArchiveService();
        byte[] bytes = zs.ConvertFilesToBytesForZip(filePath);

        return File(bytes, "application/zip", "Archive.zip");
    }
    catch (Exception ex)
    {
        var failed = new ContentResult();
        failed.Content = ex.Message + Environment.NewLine + ex.StackTrace;
        return failed;
    }
}
```

## Reference
https://learn.microsoft.com/ja-jp/dotnet/api/system.io.memorystream?view=net-6.0

https://learn.microsoft.com/ja-jp/dotnet/api/system.io.compression.ziparchive?view=net-6.0

https://learn.microsoft.com/ja-jp/dotnet/api/system.net.webclient?view=net-6.0
postdev:フロントエンド組織論まとめ

# postDevとは

https://lp.nijibox.jp/cp/postdev/

https://nijibox.connpass.com/event/256080/

---

## フロントエンド組織論

自らも先端技術を追求し続けるエキスパートでありながら、開発組織を率い、次世代のエキスパートの育成に日々奮闘し続ける3名によるパネルディスカッション
登壇者

株式会社レクター 取締役
一般社団法人 日本CTO協会 理事
Software Engineer / Engineering Manager / Organization Architect
広木 大地
著書「エンジニアリング組織論」

サイボウズ株式会社 執行役員 開発本部長
Software Engineer / Manager
佐藤 鉄平

株式会社リクルート / 株式会社ニジボックス デベロップメント室室長
Software Engineer
古川 陽介

### 開発現場の改革をどう進めていくか

技術でもって牽引していくエキスパートエンジニアとそれに従っていくニジボックスのエンジニアで構成されている
昔はフロントエンドではHTML書けばよかったが、いまではJavascriptを用いてUIを作る範囲を担っている
そしてその基盤までを作る組織が必要ではないか

まずクライテリアと呼ばれているような基準を明確化して、DXクライテリア等の基準を明確化した上でその基準に対して方向性を示唆する。またはフォローするのがまず考えること

> DXクライテリアとは？

DX開発者体験とデジタルフォーメーションの両方の軸で組織全体をチェックしていくようなチェックシート

https://dxcirt.cto-a.org/

いわゆるチェックシートトップダウン的にやってくるチェックシートって基本的に好きじゃない。
ボトムトップの話の中でいろんな会社で会っていく中でそのこういうものがありますよっていうことが現場の人が動きやすくなる指針になるという感覚があった

### DX推進と経営的目線とのバランス

企業文化的の改革×開発生産性
経営陣にボトムアップで実施してきた開発生産性をどう理解してもらえるか？

改善してますよっていうことを日々されてる方多いけど、見える化までできていることは少ないと想定される
見えるかができないとDXは机上の空論になってしまう
結局その組織の状況を見える化しながら良くしていくっていうことが重要

### サイボウズのDX戦略について

特にサイボウズだと結構ありがたいことに割と離職率低くて新卒のメンバーとかも結構多い。
そうすっとやっぱり他社でどうやってるんだろうみたいなことをあまり知らなかったりとか、知る機会が少なかったりする。
他社の事例と比較できるものがあるのはありがたい

クロスファンクショナルチームしかなかったけど専門性のある特化型のチームがなぜ生まれたのか？
現場の中で必要と感じるのメンバーが出てきた
専門家チームとそれぞれのクラブチームがうまくコラボレーションすることでそれぞれの課題を多角的に考える流れになった
チームワークを高め合いましょうっていうサイボウズの中のフィロソフィー。チームワークを高めるためのコラボレーションツールまで存在する

ファシリテーションとして外側から入っていくパターンもあれば、がっつり一緒に仕事するようなコラボレーションパターンもある
一概には言えないけど、プロダクトをよくすることを本質的な目的としてしており、各チームが切磋琢磨している

> ここからは評価の話へ･･･

---

### 評価の難しさ

各チームの貢献具合をどうやって評価したらいいかとても悩む
マネージャー以上の生産性の高い人たちが膨大な時間を使ってまで実施した評価が適切なのかは常に悩むところ
自分を主張できることは評価にプラスとなる。
チームへ自分の意見を主張できること、それでチームのどのように貢献したかが評価にとって大事
サイボウズでは市長評価を実施しており、社員が市長評価を元に会社へオファーができる
アメリカでは自分をアピールする人が多いが日本では少ない、アピールしないことへの美徳がある
不変なオブジェクトっておいしいの？

javaを勉強している方であれば一度は「不変なオブジェクト（immutableオブジェクト）」という言葉は聞いたことがあると思います。

単語の意味的に、変化しないのね…と容易に想像できますが、学習を進めていくうちに不変なのに変わってる？？不変ってどういうこと？と疑問に思ったため、今回は私なりに不変オブジェクトってなんぞやを解説していきたいと思います。

## 目次
+ 不変オブジェクトとは？
+ 単語解説
+ 実際にコードを見てみよう
+ まとめ

# 不変なオブジェクトとは？
不変なオブジェクトとは、<font color="red">「データが変化しないオブジェクト」</font>です！！
わかります…横文字嫌い…オブジェクトってなに？おいしいの？って思いますよね…
オブジェクトとは「物体、対象」と訳されます。
つまり、不変なオブジェクトとは<font color="red">「対象のデータが変化しない」</font>ということになります。

単語の意味を理解できたところで実際にコードを見て学習を進めましょう。

# 単語解説
プログラミング学習をする上で大変なことの一つとして単語の意味が分からないというものがあげられると思いますので、登場する単語の意味を解説いたします。

### インスタンス化
インスタンスとは「プログラムの処理に使用できる状態にしたもの」のことを指します。
つまりインスタンス化とは、簡単に言うと<font color="red">「プログラムで使えるようにすること」</font>です。
Javaで変数を使うためには基本的にはインスタンス化が必要ですよね。
```java
String str = new String();
```
こちらのコードは「str」という変数を使えるようにするためにインスタンス化しております。



# 実際にコードを見てみよう
今回不変なオブジェクトの解説に当たって、不変なオブジェクトである「String型の変数」と可変なオブジェクトである「StringBuilder型の変数」を使っていきます。

### 不変なオブジェクト
```java
String A = "不変な";     //又はString A ＝ new String();
String B = A;
B += "オブジェクト";
System.out.println(A);
System.out.println(B);
System.out.println(A == B);
```
こちらのコードを出力してみると
```java
不変な
不変なオブジェクト
False
```
と表示されます。
こちらは２行目でAの変数をBの変数に代入しており、３行目でAを代入したBに文字を追加しています。

はじめ私はこの出力結果をみて<font color="red">「え？変わってるじゃん！」</font>って思いました。
もともとBはAと同じ"不変な"というデータを参照していたのに３行目で変更できているし…
ここで「不変って何？」って思いました。
しかし、よくよく調べてみると、実は不変なオブジェクトであるString型の変数は、３行目の時に新しいインスタンスを生成しているため、<font color="red">変更している</font>のではなく、Aが参照してるデータと新しく追加した文字列を合わせて<font color="red">新しいデータを作成</font>していたのです！

つまり、<font color="red">**元のデータ（今回はAが参照している"不変な"という文字列）の変更はされていない！！**</font>ということです。

### 可変なオブジェクト
続いて可変なオブジェクトであるStringBuilder型の変数で作成したコードを見ていきましょう。
```java
StringBuilder A = new StringBuolder("可変な");
StringBuilder B = A;
B.append("オブジェクト");
System.out.println(A);
System.out.println(B);
System.out.println(A == B);
```
こちらのコードを出力してみると
```java
可変なオブジェクト
可変なオブジェクト
True
```
と表示されました。
これでなんとなく理解できたのではないでしょうか？
可変なオブジェクトであるStringBuilder型の変数は、２行目でBにAを代入しているときに新しいインスタンスが生成されないため、３行目で変化を与えたときに参照しているデータそのものを変化させてしまいます。
その結果Aが参照しているデータも変更してしまい、結果的にAもBも同じ出力になっています。

# まとめ
不変なオブジェクトと可変なオブジェクトを比べることで「不変」とはどういうことなのか理解できたのではないかと思います。
不変なオブジェクトは、<font color="red">データに変化を加える度に新しいインスタンスを作成しており、元のデータはそのまま残っているため、「不変」</font>ということでした。
AWS Glue DataBrew とは

## 勉強前イメージ

AWS Glue とはまた別？お友達？

## 調査

### AWS Glue DataBrew とは

フルマネージドのETLサービスになります。
ETLとはExtract(抽出) Transform(変換) Load(書き出し) の頭文字を取ったもので
基本的にはデータウェアハウスに保存する前処理として行われる処理になります。
詳細は [こちら](https://qiita.com/miyuki_samitani/items/8f7008e1c457e1b9add8) をごらんください。

元々データウェアハウスにデータを入れる際は、↑のETLのサイトにも書いてますが
大規模なデータの抽出を行って、適切な型に変換をして、データウェアハウスに書き込みをする という工程があります。
機械学習やデータ分析などは更にデータ量が多くなったりするため、それぞれの工程でスケールアップできるような仕組みを行う必要がありました。
その為、ETLの開発者やインフラエンジニアが大規模なパイプラインを構築する必要があり対応が難しい状態になります。
またデータ分析などを進めていくに連れて要件が追加されたりすることも多いです。
それをフルマネージドで行えるようにしたのが AWS Glue DataBrew になります。

### AWS Glue DataBrew の特徴

- データ変換の簡素化

AWS Glue DataBrewで準備している変換処理(クリーニングや正規化等)を選択することで
データクリーニングが簡単にできるようになります。

- 自動化の実現

変換手順を保存することで、自動化を行うことが出来ます。

### AWS Glue DataBrew の用語

- レシピ

データを変換する処理の工程を指します。
料理のレシピと同様の意味になります。

- プロジェクト

一連の流れをまとめたものをプロジェクトとします。

- データセット

データが入る、テーブルのように構造化されたデータの集まりです。

- ジョブ

レシピに記載されている工程をデータセットに加えるジョブになります。

## 勉強後イメージ

s3とかをデータソースにして、レシピ作って処理(ジョブ)を行うみたいな感じなのかな？
フルマネージドだったらオートスケールとか気にしなくてよさげ？

## 参考

- [AWS Glue DataBrewの紹介（1）](https://www.reqtc.com/column/aws-glue-databrew1.html)
- [AWS Glue DataBrewを使おう！エンジニアじゃなくても簡単にデータ処理！](https://blog.serverworks.co.jp/aws-glue-databrew)
postdev:VS Codeで試みる開発体験の向上

# postDevとは

https://lp.nijibox.jp/cp/postdev/

https://nijibox.connpass.com/event/256080/

---

## VS Codeで試みる開発体験の向上

Microsoft
Developer advocate
Tomomi Imura

### I love you but I hate you

匿名開発者が言いました
みんな開発プラットフォームそのものがあるということに対してはすごく嬉しいけど、その開発そのものがすごく大変
Teamsアプリを作成するのにMicrosoft Graphとか必要なAPIやSDKが必要となり、開発プラットフォームの学習効率が悪い
Bot開発の準備としてBotの利用登録や設定用のjsonファイルの作成、ADへの利用登録も必要となりデバッグできるまでに準備が大変
それを解消するためにVSCodeの拡張機能「Teams Toolkit」がある

### Teams Toolkit


* 直感的なUI
* アカウント・ログインの簡素化
* ボット登録の自動化
* manifestの紐付け
* テンプレートコードの自動作成
* F5でデバッグ起動
* TeamsFxという共有ライブラリ
* シナリオベースのサンプルアプリ
* 同じ拡張機能がVSにもある

### VScodeで試みる開発体験向上

GithubCodespases
ブラウザまたはVScodeで動くクラウドベース環境。

https://github.co.jp/features/codespaces

vscode.dex
ブラウザでVScodeが使用できるサービス

https://vscode.dev

VScode Server
自分の開発マシンをVSCode Serverにしてどこからでもvscode.devで接続する

https://code.visualstudio.com/docs/remote/vscode-server

Github Copilot

https://github.com/features/copilot

---

スライドはこちらになります

https://t.co/DbsgotvmC3
dependent: :destroyオプションとActiveRecord::InvalidForeignKey (SQLite3::ConstraintException: FOREIGN KEY constraint failed)の対応方法について

## dependent: :destroyオプションとActiveRecord::InvalidForeignKey (SQLite3::ConstraintException: FOREIGN KEY constraint failed)について

dependent: :destroyオプションは、親モデルのデータが削除されるときにそれに関連していた子モデルのデータも削除することができるオプション。
このオプションを設定しないと、親モデルのテーブルのデータを削除するときにエラーになる。

![20221001_ownersテーブルとcatsテーブルの画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/829500/85114159-d1f8-51bb-2c1d-ea53bba26c5f.png)


上記のようなテーブルがあり、ownersテーブルのid=3　高橋さんを削除すべく以下のコマンドを実行。

```ruby:rails c　コマンドの実行
irb(main):002:0> Owner.find(3).destroy
  TRANSACTION (0.1ms)  begin transaction
  Owner Destroy (3.0ms)  DELETE FROM "owners" WHERE "owners"."id" = ?  [["id", 3]]
  TRANSACTION (0.6ms)  rollback transaction
Traceback (most recent call last):
ActiveRecord::InvalidForeignKey (SQLite3::ConstraintException: FOREIGN KEY constraint failed)
```

エラー文は、「ActiveRecord::InvalidForeignKey (SQLite3::ConstraintException: FOREIGN KEY 制約が失敗しました)」という意味です。

つまり、親テーブルのownersテーブルにあるid=3　高橋さんを消そうとすると、外部キー制約（他のテーブルに参照・依存するようにカラムにつける制約のこと）により、データの整合性が保たれなくなり、id=3　高橋さんを参照している子テーブルcatsテーブルのid = 3 name = ハナ owner_id = 3のデータのowner_id を表示できなくなり、エラーになる。

そこでdependent: :destroyオプションを使用し、親モデルのデータが削除された時に子モデルのデータも一緒に削除できるようにし、データの整合性を保つようにする。

書き方は下記の通り。

```ruby:owner.rb
class Owner < ApplicationRecord
  has_many :cats, dependent: :destroy
end
```

そして再度、ownersテーブルのid=3　高橋さんを削除すべく以下のコマンドを実行してみると、、、

```
irb(main):002:0> Owner.find(3).destroy
 Owner Load (0.2ms)  SELECT "owners".* FROM "owners" WHERE "owners"."id" = ? LIMIT ?  [["id", 3], ["LIMIT", 1]]
  TRANSACTION (0.1ms)  begin transaction
  Cat Load (0.2ms)  SELECT "cats".* FROM "cats" WHERE "cats"."owner_id" = ?  [["owner_id", 3]]
  Cat Destroy (0.5ms)  DELETE FROM "cats" WHERE "cats"."id" = ?  [["id", 3]]
  TRANSACTION (10.5ms)  commit transaction
=> #<Owner id: 3, name: "高橋", created_at: "2022-09-30 23:15:04.894767000 +0000", updated_at: "2022-09-30 23:15:04.894767000 +0000">

(Id = 3 高橋さんが消えたか確認)
irb(main):002:0> Owner.find(3)
  Owner Load (0.2ms)  SELECT "owners".* FROM "owners" WHERE "owners"."id" = ? LIMIT ?  [["id", 3], ["LIMIT", 1]]
Traceback (most recent call last):
ActiveRecord::RecordNotFound (Couldn't find Owner with 'id'=3)→id= 3高橋さんのデータ削除完了
```
ELT とは

## 勉強前イメージ

聞いたことあるけどあまりちゃんとはわかってない
大量のデータを処理する的な？
一回勉強した気もするんやけどなぁ

## 調査

### ELT とは

ELT とは `Extract(抽出)` `Transform(変換)` `Load(書き出し)` の頭文字を取ったもので
いろんなデータベースやシステムからデータを `抽出`
使いやすいフォーマットに `変換`
データウェアハウスに `書き出し` を行うプロセスになります。
基本的にはデータウェアハウスに保存する前処理として行われることが多いです。

### ELT(ツール)のメリット

- 開発工数の削減

ELTを使うことですでに必要な部品が提供されているので、部品を組み合わせる作業を行うだけでツールが完成します。
また直感的に操作できるため高度な知識も不要です。

- 品質の向上

必要なデータを組み合わせるための部品・機能が備わっているので、
データの重複や表記の揺れを修正する等の機能も備わっています。
その為、手作業では難しかった部分も修正されてデータを使用することが出来ます。

- 高速処理

ELTでも処理速度に特化したものもあります。
大量のデータ変換や集計は特に時間がかかるところなので高速なデータ処理が行われることで他の作業に時間を割くことが出来ます。

## 勉強後イメージ

パッと出てこなかったけどそうだった気がする。。。
そもそもデータベースやそういう箱に入れる際にいろんなシステムから取ってくると表記がバラバラだったりするから
こういうツールがないと大変そう・・・・

## 参考

- [ETLとはExtract, Transform, Loadの3機能 | BIやDWHとの違い](https://boxil.jp/mag/a2415/)
Migration admin.0001_initial is applied before its dependencyが出た時の対処法

## 前提
- Dockerおよびdocker-composeを使用
- カスタムユーザModelを作成済み

## エラーが発生するまでの流れ
カスタムユーザを作成後、makemigrationsでmigrationファイルを作成し、migrateします
```terminal:terminal
docker-compose exec app python manage.py makemigrations
Migrations for '<アプリケーション名>':
  <アプリケーション名>/migrations/0001_initial.py
    - Create model User
python manage.py migrate
```

すると、以下のエラーが出ることがあると思います

```terminal:terminal
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency <アプリケーション名>.0001_initial on database 'default'
```

## エラーが表示される理由
カスタムユーザを作成する前にmigrateすると下記のようにすでにあるDjangoのデフォルトのadminユーザのModelとカスタムユーザのModelが衝突してしまうために起こるエラーです
```
auth_group
auth_group_permissions
auth_permission
authtoken_token
django_admin_log
django_content_type
django_migrations
django_session 
```

`INSTALLED_APPS`内の`django.contrib.admin`と`AUTH_USER_MODEL`をコメントアウトしてからもう一度migrationファイルを作成してmigrateする記事もありましたが、docker-composeを使っているのであれば永続volumeを削除する方法の方が手取り早くて簡単なので今回はそちらの方法を紹介します

## 永続volumeを削除しよう
まずはコンテナをdownします
```terminal:terminal
docker-compose down
```

下記のコマンドでvolume名を調べます
```terminal:terminal
docker volume ls
```

以下のコマンドで該当するvolume名を指定し、削除します
削除できない場合はrm -f で無理やり削除することもできます
```terminal:terminal
docker volume rm <ボリューム名>
```

コンテナを再起動します
```terminal:terminal
docker-compose up -d
```

すでにmigratationファイルがあるのでmigrateするとカスタムユーザのmigrationがうまく反映されます
以下のような出力結果が表示されたら成功です
```yaml:terminal
docker-compose exec app python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, <アプリケーション名>, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0001_initial... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying <アプリケーション名>.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying sessions.0001_initial... OK
```

## まとめ
はじめてこのエラーに遭遇した時はかなり混乱しました。実際の開発ではデフォルトのadminのModelではなく、自分達でカスタムユーザを作るのが一般的なので今後同じエラーに遭遇される方の少しでもお役に立てたらと思い、書きました

## 記事の紹介
以下の記事も作成しましたので見ていただけると幸いです

https://qiita.com/shun198/items/f6864ef381ed658b5aba

https://qiita.com/shun198/items/9e4fcb4479385217c323

## 参考
https://note.com/mihami383/n/nb58eec166df6
Salesforce認定アドミニストレーター試験の公式練習問題を解説してみた-その040

こんにちは。本橋孝昭です。

Salesforce認定アドミニストレーター試験の公式練習問題があるのはご存じでしょうか。
Trailheadにフラッシュカードとして何度も解ける練習問題がございます。

今回はTrailhead
アドミニストレーター認定の準備: データと自動化
データ管理と分析管理の演習

にある練習問題８問目をご紹介します

今回の内容は動画でも解説しています

https://www.youtube.com/watch?v=mjC-U_gdu18

<iframe width="560" height="315" src="https://www.youtube.com/embed/mjC-U_gdu18" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


https://trailhead.salesforce.com/ja/content/learn/modules/administrator-certification-prep-security-and-data-management/review-data-management?trail_id=administrator-certification-prep

今回の問題はこちらです
![CC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/e3818310-d615-77b3-3a78-32700774c8bc.png)



問題は「データのインポート時にどうすればいいのか」という内容です


正解はCです

問題の「一意の外部ID」の「一意」は「ユニーク」
外部IDは「外部ID」の設定ですね

今回は「ユニーク」で
外部ID項目を作成すれば可能です
ユニークと外部ID項目の設定はこちらです

項目作成時にチェックをつけます

![ユニーク01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/2ec59782-3a1f-e3eb-d520-cc074b2956c4.png)


インポート時に一致条件で先ほど作成した外部ID項目の設定が可能です
![外部01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/bce610a6-32e7-5507-4b32-edf66fe0938b.png)


この項目でインポートすれば
・外部IDで一致が確認できる
・ユニーク設定なので同じ値の項目は作成できない

となります


Aについて
データローダ使用だけでは重複有無の確認はできません
Rustエラーハンドリング・チートシート

Rustのエラーハンドリング関連の主要メソッドが一目でわかる、チートシートを作成しました。

Rustは型システムが複雑なので、やりたいことに適切なメソッドがあるかどうか、ドキュメントを探しまくることが多いです。エラーハンドリングもその類の1つであり、ドキュメント探索の手間を削減するために、チートシートを作成してみました。

ご活用ください。

# 1. チートシート

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156600/ae3c310d-78b6-c6dc-11da-8b6d0a196fb2.png)


# 2. 関連リンク

- [bool - doc.rust-lang.org](https://doc.rust-lang.org/std/primitive.bool.html)
- [Option - doc.rust-lang.org](https://doc.rust-lang.org/std/option/enum.Option.html)
- [Result - doc.rust-lang.org](https://doc.rust-lang.org/std/result/enum.Result.html)
rollupjsのwatchのAPI実行で、変更検知が動かない

# １．背景と現象


- rollupjsをAPIとして、つまり、JavaScript内でモジュールとして呼び出して実行している。
- コマンドラインからの実行ではない。
- ある時からwatchを実行しても、変更を検知して処理が再実行されなくなった。


# ２．対応

以下のようwatchのオプションにあるchokidar.usePollingを設定すると変更を検知するようになった。


```js
const rollup = require("rollup");

//オプション
const option = {
    input: "ビルド対象の起点ファイルパス",
    output: [
		file: "バンドルしたファイルのパス",
		format: "iife"
    ],
    watch: {
      chokidar: {
          usePolling: true
      },
    },
};

//watch実行
rollup.watch(option).on("event", (event) => {
//ビルド実行イベント処理
});

```

この中で以下の部分がないと変更を検知しなかった。

```js
    watch: {
      chokidar: {
          usePolling: true
      },
    },

```

※以下のサイトがとても参考になりました。

https://github.com/rollup/rollup/issues/1666