OmniAICreator/Qiita-1.07M huggingface dataset:
Laravel radio ボタンを保持させる

# はじめに
Laravel 初学者の私が学習した内容をアウトプットしていく記事になります。
冗長している点や軽い書き方などあれば御指南お願いいたします。。。:bow_tone5:

# Laravel radio ボタンを保持させる
前提：boolean カラムのデータを Radio ボタンで切り替えを実装する。
## 実際のコード
```php:edit.php
<div class="form-group">
    <div class="form-check">
        <input class="form-check-input" type="radio" name="is_published" value="1" {{ (bool)old('is_published',$portfolio->is_published) ? 'checked' : ''}}>
       <label class="form-check-label" for="flexRadioDefault1">公開</label>
    </div>
    <div class="form-check">
        <input class="form-check-input" type="radio" name="is_published" value="0" {{ (bool)old('is_published',$portfolio->is_published) ? '' : 'checked'}}>
        <label class="form-check-label" for="flexRadioDefault2">下書き</label>
    </div>
</div>
```
### コードの概要 <br>
- [Bootstrap Radios](https://getbootstrap.jp/docs/5.0/forms/checks-radios/)を引用しています。<br>validation がかかった際の以前の入力した値を```old method```が保持してくれます。<br>old() の前に (bool) をつける事で boolean カラムを [__キャスト__](https://readouble.com/laravel/8.x/ja/eloquent-mutators.html)しています。<br>そして、一番の肝が __三項演算子__ です。<br>{{ ( 条件 ) ? 'ture の挙動' : 'false の挙動' }}になります。<br>Radio ボタンの場合、ボタンにチェックがつく動きを input タグ内の```checked```が行っています。<br>上の __form-check__ 内での三項演算子は、__true__ の際に挙動し、下の __form-check__ 内での三項演算子は、__false__ の際に挙動します。<br>書き方や class の中の役割など理解していれば吸収が早いと思います。
改行をbrタグに置換してませんか？

# 目的
CMSのようなシステムで入力された文字列をHTMLに展開したいときがあります。
その時テキストエリアで空白文字や改行を入力すると、HTMLに展開すると連続した空白がつめられて改行は空白にされます。
入力した通りに表示する方法を検討します。

# 方法
## タグや実体参照に置き換える
よくある手としては改行コードを見つけたらbrタグに置き換え、空白を「＆ｎｂｓｐ；」に置き換えます。

RubyのERBでは以下のようになります。

```erb
<p><%= contents.gsub(/\R/, "<br/>").gsub(/ /, "&nbsp;") %></p>
```

HTMLのエスケープをするなら以下のようになります。

```erb
<p><%= ERB::Util.html_escape(contents).gsub(/\R/, "<br/>").gsub(/ /, "&nbsp;") %></p>
```

## CSSで調整する

white-spaceというCSSのプロパティは改行と空白文字を制御します。

詳細は[MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/CSS/white-space)にあります。

```erb
<p style="white-space: pre-wrap;"><%= contents %></p>
```

# まとめ
CSSの方が記述が簡単ですしCSSをファイルで切り出しておけば調節もしやすいので、CSSを使うと良いと思います。
【Rails API】devise_token_authで作成したコントローラにルーティングを追加したい【memo】

# 課題

- ゲストログインを実装する際に、既存の`sessions_controller.rb`にメソッドを追加する

```diff_ruby:api/v1/users/auth/sessions_controller.rb
# frozen_string_literal: true

class Api::V1::Users::Auth::SessionsController < DeviseTokenAuth::SessionsController

# 今回はこれを追加！
+ def guest_sign_in
+   # ゲストログイン処理
+ end

end
```

# 問題

ルーティングをなかなか追加することができませんでした。

 `devise_scope :user`と記載したのですが、なかなかうまくいかず・・・。

```diff_ruby:routes.rb
Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do

-     devise_scope :user do
-       post 'users/guest_sign_in', to: 'users/auth/sessions#guest_sign_in'
-     end

      mount_devise_token_auth_for 'User', at: 'user/auth', controllers: {
        registrations: 'api/v1/users/auth/registrations',
        sessions: 'api/v1/users/auth/sessions',
        confirmations: 'api/v1/users/auth/confirmations',
        passwords: 'api/v1/users/auth/passwords'
      }

    end
  end
end
```

# 解決策

 `devise_scope :api_v1_user`と記載すると追加することができました。



```diff_ruby:routes.rb
# frozen_string_literal: true

Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do

+       devise_scope :api_v1_user do
+         post 'users/guest_sign_in', to: 'users/auth/sessions#guest_sign_in'
+       end

      mount_devise_token_auth_for 'User', at: 'user/auth', controllers: {
        registrations: 'api/v1/users/auth/registrations',
        sessions: 'api/v1/users/auth/sessions',
        confirmations: 'api/v1/users/auth/confirmations',
        passwords: 'api/v1/users/auth/passwords'
      }

    end
  end
end
```

`devise_scope :user` で追加できるものと思っていたので、かなり時間を取られました。

namespceの影響がここまで来るとは思いませんでした・・。
浮動小数点にマッチする正規表現

修正履歴
- 間違いを修正。@StrawBerryMoonさんありがとうございます。
- Non-capturing groupについて追加。


#やり方
Pythonを使った例です。
整数、浮動小数点('10e5'などのexponentを使った表現含む)にマッチ。

```py
import re

regex = r'[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?'

text = '22 10.08 .52667 2.96996e-05 .57E+05'

m = re.findall(rf'({regex})', text)

print([t[0] for t in m])
#=> ['22', '10.08', '.52667', '2.96996e-05', '.57E+05']

```

正規表現を表す文字列`regex`内部で`()`を使ったグルーピングがされているので、
`regex`全体をさらに`()`で囲ってグルーピングし取り出します。

例の中の.57E+05という表記が実際に使われるのかは分かりませんが。。

# Non-capturing group

Pythonにはキャプチャーせずにグルーピングする方法があるようでした。
やり方は`(?:foo)`のように`(`の後に`?:`を付けます。
指数部分のキャプチャーは必要なかったので、上記のコードを書き直すと以下になります。

```py
import re

regex = r'[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?'

text = '22 10.08 .52667 2.96996e-05 .57E+05'

m = re.findall(regex, text)

print(m)
#=> ['22', '10.08', '.52667', '2.96996e-05', '.57E+05']
```

#参考

[Regular-Expressions.info](https://www.regular-expressions.info/floatingpoint.html#:~:text=%5B0%2D9%5D%2B%7C,more%20digits%20(an%20integer).&text=Any%20match%20must%20include%20at%20least%20one%20digit.)

https://note.nkmk.me/python-re-match-search-findall-etc/
CASE式の入れ子(ネストされたCASE式)の書き方

CASE式を入れ子で書けることを知ったので、忘れないように書いておきます。

## テーブル
| BILL_DATE | PAYMENT | CARD_COMPANY |
|:-:|:-:|:-:|
| 2022/01/08  | 2  | null  |
| 2022/01/11  | 99  | 99  |
| 2022/01/12  | 99  | 2  |
| 2022/01/13  | 1  | null  |
| 2022/01/17  | 99  | 3  |
| 2022/01/19  | 99  | 1  |
| 2022/01/22  | 2  | null  |
| 2022/01/24  | 99  | 2  |
## SELECT文
```SQL
SELECT
	BILL_DATE AS 請求日,
	CASE PAYMENT
		WHEN '1' THEN '口座振替入金'
		WHEN '2' THEN '振込入金'
		ELSE
			CASE CREDIT_CARD_COMPANY
				WHEN '1' THEN 'VISA'
				WHEN '2' THEN 'MASTERCARD'
				WHEN '3' THEN 'AMERICAN EXPRESS'
				ELSE '不明'
			END
	END 支払方法
FROM
	BILLING_TB
;
```
## 結果
| 請求日 | 支払方法 |
|:-:|:-:|
| 2022/01/08  |  振込入金 |
| 2022/01/11  |  不明 |
| 2022/01/12  |  MASTERCARD |
| 2022/01/13  |  口座振替入金 |
| 2022/01/17  |  AMERICAN EXPRESS |
| 2022/01/19  |  VISA |
| 2022/01/22  |  振込入金 |
| 2022/01/24  |  MASTERCARD |
Ruby入門　Ruby3導入方法　for mac (2022) 環境構築

新しいMacbookにRubyを導入する工程をまとめます。


動作環境
MacBook　　　　(Retina, 12-inch, 2017)
MacOS　　　　　Monterey 12.1
Processor　　　　1.4 GHz Dual-Core Intel Core i7
Memory　　　　　16 GB 1867 MHz LPDDR3



まずは現在のRubyのバージョンの確認

ターミナルで

```
ruby -v
```

と打ち込むと

```
ruby 2.6.8
```

だと判明。

まずは下準備として
下記URLからHomebrewをインストール

```
https://brew.sh/index_ja.html
```

インストールの文字のしたのスクリプトをコピーしてターミナルにペーストする。
何度かパスワードを入力を求められるのでMacのパスワードを入力する。

環境にもよるだろうがダウンロード、インストールに筆者はかなり時間がかかった。

無事インストールが終わった後
　
下記コマンドを実行してrbenvとruby-build をインストールする。

```
brew install rbenv
```

インストールが終わったら続いて下記コマンドを実行しrbenvの設定をする。

```
rbenv init
```
上を実行するとターミナルに


```
# Load rbenv automatically by appending
# the following to ~/.zshrc:

eval "$(rbenv init - zsh)"
```

と出てくるので

```
~/.zshrc
```

を実行するも

```
zsh: no such file or directory:
```

となるので

```
touch .zshrc
```

を実行しファイルを作成

```
open ~/.zshrc
```

でエディタを開き下記を書き込み保存

```
eval "$(rbenv init - zsh)"
```

ターミナルを再起動するか

```
source ~/.zshrc
```

を実行し設定を反映させる。

```
rbenv
```

を実行しバージョンが出ればOK
いよいよRubyのインストールに入ります

```
rbenv install -l
```
でインストール可能なバージョンを確認

```
2.6.9
2.7.5
3.0.3
3.1.0
jruby-9.3.2.0
mruby-3.0.0
rbx-5.0
truffleruby-21.3.0
truffleruby+graalvm-21.3.0
```

今回は安定版の3.1.0をインストールしていきます

```
rbenv install 3.1.0
```

ここもかなり時間がかかりました。

インストールが完了したら
ターミナルを再起動し

```
rbenv global 3.1.0
```

とすることで全てのシェルで3.1.0が使えます。

再度

```
ruby --version
```
でバージョンを確認すると見事

```
ruby 3.1.0
```

と表示されインストールが完了した。
エンジニアへの質問の仕方

#自己紹介
現在都内の企業でWebエンジニアのインターン生としてお世話になっている大学２年生です！
インターンや個人開発で学んだことや苦労したことを記事にしています！
よろしくお願いします🙇🏻‍♂️

#はじめに
現在インターンで自社開発のプロジェクトの開発を任されています。
インターンをする前、温泉施設でダラダラアルバイトしていた僕にとっては**正直結構辛いです。**
開発者も僕1人なのでなかなか開発もうまく進まず、先日終わるはずだった開発内容も終わりませんでした。
その趣旨を上司に報告したところ、「そのリカバリを考えてきて」と言われました。
なぜ開発が滞ってしまったのかを考えたときに「エンジニアへの質問の仕方」に問題があるのではないかと考えました。
その際に調べたこと、考えたこと、これからどうしていくのかをまとめました。

#現在の自分
「詰まったけど、質問した時のあれ試した？これ試した？に備えなきゃ」と1~2時間くらい1人で格闘し、進捗が遅れている自覚がありつつも自分の中だけで焦ってしまっているという進め方をしてしまっているせいで開発進捗が遅れてしまっている。
1~2時間くらい考えてやっと質問しても自分の中でその質問の意図がまとまっておらず、その結果エンジニアは自分に何を教えていいのか、何をしてほしいのかが伝わらず、お時間を取らせてしまっている。
また、エンジニアに対して、同じ質問を何度もするのはタブーであるにも関わらず過去に一度質問したことをもう一度質問してしまったことがある。

#質問のレベル
[Five orders of Ignorance](http://la-acm.org/Archives/laacm0512-Article%2002%20The%205%20Orders%20of%20Ignorance%20OCT%202000.pdf)というペーパーで、無知のレベルには５つのレベルがあるとされています。
**0OI: 全部分かっている**
「答え」を持っている。あとは書き写すだけで完成する。
**1OI: 分からないことが分かっている**
答えを得るための「質問」を持っている。
**2OI: 分からないことが分からない**
「質問」を持たない状態。決定的な答えを引き出すための「質問」ができない。
**3OI: 分からないことが分からない状況何とかする術を知らない**
2OI→1OI→0OIと進んでいくためのプロセスがない状態です。
**4OI: 無知にレベルがあることを知らない**

自分をこの中から定義するなら**1OI**寄りの**20I**かなと思います。
下記のサイトに無知レベルごとの質問の仕方が詳しく書いてあります。

https://qiita.com/seki_uk/items/4001423b3cd3db0dada7#%E3%81%8A%E5%9C%9F%E7%94%A3%E3%82%92%E7%94%A8%E6%84%8F%E3%81%99%E3%82%8B

#質問するタイミング
これは自分の中でルールを決めたいと思います。
Google人工知能チームの[「15分ルール」](https://tkybpp.hatenablog.com/entry/2016/08/16/173055)というルールを20分に変えて採用します。

>問題が起きた時は

>【1】最初の15分は自分自身で解決を試みる
【2】15分後も解決していなかったら必ず人に聞く

>前者を守らないと他人の時間を無駄にし、後者を守らないと自分の時間を無駄にする。

「自分でやるぞ」という変なプライドは捨てて質問します。

#具体的にどう質問するか

###①わからないこと、聞きたいこと、やってみたことをメモ帳などに書き出してみる
質問する前に、まず現在知っている情報を箇条書きで書き出してみる。
この時メモアプリを活用し、自宅でも見返せるようにする。

###②上記で書き出したメモを参考に質問内容を書く
①で書いたメモを参考に実際に質問内容を書いていきます。
その時に気をつけたいことは以下の通りです。

・何を回答として得たいのかをよく確認し、質問のいちばん最初に「ほしい回答」を伝える
・「答え」ではなく「答えへのたどり着き方」を教えてもらうようにする
・5W1H(いつ、どこで、だれが、何を、なぜ、どのように)を意識して書く
・指示語(あれ、それなど)を使わない
・同じ質問は**絶対に**しない

###③slackに質問内容とスクリーンショットを送り、確認してもらった後に直接聞きに行く
このようにすることで、質問したことが形となって残るので、相手が聞き損じる事も忘れる事もないですし、何よりも相手の時間を奪うことを減らせるというのが最大の利点です。
送付してから、直接相手に聞きいって自身の状況を伝えた場合のことを想定したら前回よりも遥かに早く、情報のやり取りを減らせるし、お互いのストレスを削減できる。

質問するのには勇気がいりますが、しっかり考えた上での質問なら歓迎してくれると思います！

#質問後
###①その場で理解しきることを心がける
同じ質問をしないためにも質問内容をその場で反復し、自分に理解しきれていない事がないかを確認する。

###②質問したことや学んだこと、反省点などをQiitaでアウトプットする
最近記事を書き始めてみて思ったことは、人に伝わるように記事を書こうとするので再度調べたり考えたりしているうちに、知識の定着が進みやすいと思いました。
もし忘れてしまった際の備忘録にもなるのでメリットしかないですよね。

#参考
https://qiita.com/kaizen_nagoya/items/2f05ae5977b7ace769ac

https://qiita.com/sakusaku12/items/a899a43ff9cd63c29482

https://qiita.com/seki_uk/items/4001423b3cd3db0dada7

https://qiita.com/_kanacan_/items/d9d99e5bb0248584a6c5

https://www.walker.co.jp/how_to_questions/

https://www.hyuki.com/writing/techask.html

https://tkybpp.hatenablog.com/entry/2016/08/16/173055

http://la-acm.org/Archives/laacm0512-Article%2002%20The%205%20Orders%20of%20Ignorance%20OCT%202000.pdf

#終わりに
この記事が似たような境遇の人や、エンジニアの質問方法がわからないという人の役に立てれば幸いです！

ではいい一日を👍
yarnのインストール(Windows)

# はじめに
　以前、自分が使っている古い方のPCで、Reactを使おうと思ってyarnをインストールしたのですが、パスが通っていないのかコマンドが認識されず、yarnが実行できない。
　思い切って新しいPC(Surface Pro8)の方でもう一度インストールしてみようと思って、再度挑戦しました。
　ちなみにyarnとは、Facebook社（現メタ社）によって開発された、npmよりも処理が早いJavaScriptのパッケージ管理システムです。よくnpmの上位互換として紹介されているので、流行に乗って使えたほうが良いかなと奮闘中です。ReactもFacebookによる開発ですよね。Facebookはこの辺りの事情に精通しているのでしょうか。

# 作業環境
PC: SurfacePro8
OS: Windows11
使用ターミナル: コマンドプロンプト
その他必要環境: node.js、npm

# 手順
　何はともあれ、まずは公式ドキュメント！ということで、yarnpkg.comのGETTING STARTED　→　Installationの手順を試してみることに。
　最初に、「yarnを使うのは、Corepackを通して扱うのが良い」という趣旨のことが書いてあるので、素直にCorepackを使おうと $corepack enable と実行すると、

![220125 yarn1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475646/56337cd8-1674-4419-796c-9a34519290f6.png)

　そのコマンドは許可されていません、と出ます。node.jsフォルダの中のnpmファイルを見るように指示があるものの、見てもよく分からない...。エラーメッセージを元にあれこれ調べてみたものの、明確な解決策は見つかりませんでした。
　「要するに管理者じゃないからダメなんでしょ？ええい、管理者でゴリ押してしまえ」と半ばヤケクソになって「管理者権限　コマンドプロンプト」と検索。どうやらコマンドプロンプトのアプリアイコンを右クリックすれば管理者権限で入れるみたいなので、管理者権限として入った後、再度実行。
　......できました。あまりにもあっけないです。必要なのは、管理者権限で実行してよいのかという不安に打ち勝つ勇気のみですね。

　あとは、公式ドキュメントの手順に沿って、npm i -g corepack、 yarn init -2　というコマンドを順に実行するだけです。何やら不穏なエラーメッセージが出ていてこの先が不安ですが、とりあえず良しとしましょう。ん？できてない？一応実行したディレクトリ下に「.yarn」というディレクトリと、package.jsonができているので、できているということにしましょう。またこの辺りで問題が起こったら、記事にするかもしれません。

![220125 yarn2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475646/409654ba-ef92-2db1-cec2-11afd0208966.png)

# 総論
　とりあえず何をするにも、公式ドキュメントのGETTING STARTEDが正義です。このような環境構築系は特に、公式ドキュメントや、エラーメッセージ内ででてきたリンクを参考にするのが一番手っ取り早いと思いました。

# 参考

公式ドキュメント
https://yarnpkg.com/getting-started/install

最後のエラー時に参考として出てきた公式ドキュメントのページ。
https://classic.yarnpkg.com/en/docs/cli/init
yarn initで何が行われ、どのようにyarnを初期化しているかについては分かりやすく載っているものの、今回のエラーの原因は突き止められませんでした。

Corepackについて
https://nodejs.org/dist/latest/docs/api/corepack.html

管理者権限でコマンドプロンプトに入る方法
https://solutions.vaio.com/2663
超準解析にまつわる都市伝説

　超準解析って何？ という人は[過去記事](https://qiita.com/kueda_cs/items/4592cc064c6ef97835c5)を参照してください。新しい都市伝説が出てきたらこの記事を更新していきます。超準解析についてのアヤシイ話はだいたいが「移行原理の適用範囲外まで直感的に標準モデルの結果を拡張してしまう」「標準モデルにおける "無限大" と超準モデルにおける非有限の超有限としての "無限大" を完全に同一視してしまう」あたりによって引き起こされているような印象があるので、そのへんに気をつければ大丈夫じゃないでしょうか。

# 超準解析では 1 と 0.999... を区別できる
　これは通常成り立ちません。というのも、標準モデルで
$$0.999... = \sum_{n=1}^{\infty} 9\times \left(0.1\right)^n = 1$$
のような無限和を表すために使っていた記号 "..." が超準モデルで考えただけで突然
$$0.999... = \sum_{n=1}^{N} 9\times \left(0.1\right)^n = 1 - \varepsilon \neq 1 \ \ \left(\varepsilon \in \mu\left(0\right)\right)$$
というふうに超有限和となる理由がないからです。こういうものは特に断りがない限りは超有限数 $N$ を用いて
$$0.\overbrace{999...9}^{N 桁}$$
と表記されます。
そのため、記号 "..." の通常の定義で考えれば超準解析であろうがなかろうが
$$1 = 0.999...$$
であることに変わりはありません。無限に続くことを素朴に "..." と表現しよう、と考えて「桁数が有限でないこと」すべてにこの記号を適用してしまうと、通常の定義とバッティングして ill-defined になってしまいます。ですから、どうしても $1\neq0.999...$ としたいのであれば「この場で "..." という記号は無限大超自然数桁を表すものであり、超準モデルにおける無限級数を略記するためには用いない」とあらかじめ定めておく必要があります。
　以上のことから、超準解析では $1$ と $0.999...$ が区別できるというよりも、記号 "..." のオーバーロードにより
$$1 \neq 0.999...$$
と表記できることもある、と言ったほうが正確です。しかし、これ（記号をオーバーロードすればどちらの結果も得られる）が $1 \neq 0.999...$ という結論を欲していた人にとって満足のいく事実なのかは疑問ですね。

# 超準解析ではすべての素数の積が定まる
　無限大超自然数 $N$ をひとつ取ってくればどんな有限素数よりも大きいのだから、有限素数の無限列を擬似的に有限であると見て、超有限積を取ればいいのではないか、という発想でしょう。超素数すべての積は標準的な場合と同様に数として存在しませんが、有限素数すべてで割り切れる数なら、ある無限大超自然数 $N$ を取ってきて、それ以下の素数列 ${\left(p_n\right)}\_{1 \leq n \leq N} \subsetneq {}^{\ast}\mathbb{N}$ の積
$$\prod_{n=1}^{N} p_n$$
を考えれば手に入ります。これは「すべての有限素数の積」が存在するならばそれで割り切れるような数です。この $N$ を無限大側から有限素数にギリギリまで近づけて「最大の有限素数とその次の無限大素数との間」で取れば**ちょうど**有限素数だけの積が得られるという算段です。
　しかし、そんなうまい話はありません。先ほど挙げた[過去記事](https://qiita.com/kueda_cs/items/4592cc064c6ef97835c5)で説明している通り、超準世界と標準世界を行き来するための移行原理が適用できるのはあくまでも一階述語論理の範囲内です。「ちょうど有限素数だけ取り出す」なんてことをしようとすると、面倒な問題が発生します。ちょうど有限素数だけを含んだ列は外的になってしまい、標準世界の「有限積」に対応するような超有限積が考えられないのです。
>［溢出原理］
内的集合 $A \subseteq {}^{\ast}\mathbb{R}$ に対し、以下ふたつは同値である：
1. ある有限数 $n$ が存在し、それより大きい任意の有限数 $m > n$ に対して $m \in A$ となる。
2. ある無限大数 $N$ が存在し、それより小さい任意の無限大数 $M < N$ に対して $M \in A$ となる。

　超自然数の場合で 1 $\Rightarrow$ 2 を示しておきましょう。1 を認めることで考えられる集合
$$A_k = \left\\{ N \in {}^{\ast}\mathbb{N}\ \middle| \ k < N \land \left(\forall m \in {}^{\ast}\mathbb{N}\right) \left(k \leq m \leq N \rightarrow m \in A \right)  \right\\}$$
を用意します。$A_k $ たちは有限交叉性を持つため、
$$N \in \bigcap_{k \in \mathbb{N}} A_k $$
が存在します。これは $A_k $ の定義より任意の有限数よりも大きいので、無限大超自然数です。また、$A_k $の定義より $N$ 以下の任意の無限大自然数は $A$ に含まれ、2 が得られました。

　この事実は、有限と無限大の境目がハッキリとはわからないことを意味します。「ある有限数より大きな有限数をすべて含むこと」は「ある無限大数より小さな無限大数をすべて含むこと」を意味してしまい、「すべての有限素数」を取ろうとするとどうしても無限大素数が混入してしまいます。

# 参考文献

- [超準解析の魔導書](https://booth.pm/ja/items/1536942)
アンマウントでdevice is busyエラーが出たときの対処


[結論]
ディレクトリ移動してみましょう
カレントディレクトリがマウントポイントのパスであることが原因かもしれません

```
sudo umount /etc/amazon/efs
umount.nfs4: /etc/amazon/efs: device is busy
```

```txt:対処
cd ../
sudo umount /etc/amazon/efs

```
【アコーディオン】jQueryのslideToggleを生jsで再現してみた。

jQueryのslideToggleは数行で実装できるので便利でした。
今回、数行とはいきませんがそれなりにシンプルなコードでslideToggleの動きを再現してみました。

## 生jsの場合
<p class="codepen" data-height="300" data-default-tab="js,result" data-slug-hash="MWOWYPd" data-user="monji88" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/monji88/pen/MWOWYPd">
  accrodion without jQuery </a> by monji (<a href="https://codepen.io/monji88">@monji88</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

e.targetとnextElementSiblingを使用しています。

e.targetについては以下の記事にも書かせて頂いてます。

https://qiita.com/monji586/items/711bc6d78c41cf02c752

## Vue.jsの場合

<p class="codepen" data-height="300" data-default-tab="js,result" data-slug-hash="ZEaEzMB" data-user="monji88" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/monji88/pen/ZEaEzMB">
  Untitled</a> by monji (<a href="https://codepen.io/monji88">@monji88</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

Vueなのでtransitionタグなど使おうかとも思いましたが、
普通に生jsのコードを使いまわしたほうがシンプルでした。
`el:"#app"`とかはVue2の書き方ですがmethodsの部分はVue3でもそのまま使えると思います。
読みやすいコード入門編(javascript)

## 無駄にライブラリを使わない

標準機能で実現できることにライブラリを使わないことを心がける。

## マジックナンバーには名前をつける

```tsx
// この「100」は何？
const pages = Math.ceil(records.length / 100);

// ああ、1ページあたり100件ってことね！
const maxRecordsPerPage = 100;
const pages = Math.ceil(records.length / maxRecordsPerPage);
```

## 識別子を短くしない

```tsx
// この変数はどういうこと？
const cx = 5;
const cy = 10;

// 意味がはっきりした！
const centerX = 5;
const centerY = 10;

// 関数名から機能を把握しにくい！
function fetchTrk(id) {
    return fetch('./api/tracking/' + id);
}

// これなら多少わかりやすい
function fetchPersonTrackingData(personId) {
    return fetch('./api/tracking/' + personId);
}
```

## デフォルト引数はオブジェクトにする

```tsx
// 複数のデフォルト引数を使っている
function findBookRecords(queryString, useCache = true, maxRecords = 50, caseSensitive = false) {
    // 取得処理
}

// どの引数が何を意味しているのかわかりにくい
const bookRecords = findBookRecords('JavaScript', true, 10, true);

// デフォルト引数をオブジェクトにしている
function findBookRecords(queryString, options = {}) {
    // 取得処理
}

// 引数の意味がわかりやすく、順番にも左右されない
const bookRecords = findBookRecords('JavaScript', { useCache: true, maxRecords: 10, caseSensitive: true });
```

## イベントハンドラー関数は「on」で始めること

イベントをキャッチしたら始まる処理、もしくはイベントをキャッチするグローブのこと

## 垂直のインデント: コードを論理ブロックに分割するための空行

```tsx
function pow(x, n) {
  let result = 1;
  //              <--
  for (let i = 0; i < n; i++) {
    result *= x;
  }
  //              <--
  return result;
}
```

## ネストレベル

下のコードの方が見やすい

```tsx
function pow(x, n) {
  if (n < 0) {
    alert("エラー");
  } else {
    let result = 1;

    for (let i = 0; i < n; i++) {
      result *= x;
    }

    return result;
  }
}

function pow(x, n) {
  if (n < 0) {
    alert("エラー");
    return;
  }

  let result = 1;

  for (let i = 0; i < n; i++) {
    result *= x;
  }

  return result;
}
```

## 関数の配置

NG:ヘルパー関数を使うコードの上に関数を記述する

```tsx
// 関数宣言
function createElement() {
  ...
}

function setHandler(elem) {
  ...
}

function walkAround() {
  ...
}

// 関数を使用するコード
let elem = createElement();
setHandler(elem);
walkAround();
```

OK:コードが最初で、その後に関数を記述

```tsx
// 関数を使用するコード
let elem = createElement();
setHandler(elem);
walkAround();

// --- ヘルパー関数 ---

function createElement() {
  ...
}

function setHandler(elem) {
  ...
}

function walkAround() {
  ...
}
```

## その他心構え

- シンプルなコードは、「素人っぽく」見えることもある
- プログラミングにおける1つ1つの判断は「そのコードが変更される」前提で行う。
- コードは1つずつタスクを行うようにしなければいけない。そのタスクは小さくなるように分割する。
- コードをたくさんの小さい部分に分割する（関数などが長くなったら分割して短くする）。
- プログラミングにおいては「今日単純なことをして、明日変更が必要になった時に、変更のコストを支払う」方が「今日複雑なことをして、結局使わない」よりも良い結果を生む。
- 問題を声に出して説明するだけで、解決策が見つかることがある。（通称ラバーダッキング）
- 関数を使う側にとって必要なのは、その関数が「何をするか（What）」であって、「どうやってするか（How）」ではありません。言い換えると、内部実装の情報まで関数名に含める必要はありません。

[https://sbfl.net/blog/2018/03/24/readable-javascript-code/](https://sbfl.net/blog/2018/03/24/readable-javascript-code/)

[https://note.com/shiory602/n/n5d15cdd28823](https://note.com/shiory602/n/n5d15cdd28823)

[https://ja.javascript.info/coding-style](https://ja.javascript.info/coding-style)

[https://engineeeer.com/readable-code-tips/](https://engineeeer.com/readable-code-tips/)
JavaScriptのコンストラクタとプロトタイプの違いについて

## コンストラクタ

```jsx
function Dog(name, cry) {
  this.name = name;
  this.bark = function() {
    console.log(cry);
  };
}
var dog = new Dog('きなこ', 'わんわん');
console.log(dog.name); // きなこ
dog.bark(); // わんわん
```

上記のコードでnewを取り除くとエラーが発生する。この違いは何か？実は暗黙のルールで二行加わっています。

```jsx
function Dog(name, cry) {
  // var this = {};
  this.name = name;
  this.bark = function() {
    console.log(cry);
  };
  // return this;
}
```

newをつけない場合はself等を用意しなくてはならない

```jsx
function Dog(name, cry) {
  var self = {};
  self.name = name;
  self.bark = function() {
    console.log(cry);
  };
  return self;
}

var dog = Dog('きなこ', 'わんわん');
console.log(dog.name); // きなこ
dog.bark(); // わんわん
```

## プロトタイプ

プロトタイプとは「オブジェクト」のことであり、親の能力は子にも受け継がれている的なニュアンス

**prototypeとは？**

prototypeプロパティを利用することで、オブジェクトにメソッドやプロパティを定義することが可能にする

```jsx
const Member = function (firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

Member.prototype.getName = function () {
  return this.firstName + this.lastName;
}

const mem1 = new Member('田中', '太郎');
const mem2 = new Member('山田', '二郎');
console.log(mem1.getName());
console.log(mem2.getName());
```

上と下では表示結果は同じ

```jsx
function Dog() {}
Dog.prototype.bark = function() {
  console.log('わんわん');
};

var dog = new Dog();
dog.bark(); //'わんわん';

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

function Dog() {
  this.bark = function() {
    console.log('わんわん');
  };
}
var dog = new Dog();
dog.bark(); //'わんわん';
```

しかし、下はnewはこんな暗黙のルールで余計な記述が作られる。そのため毎回空オブジェクトを作成し、毎回新しくbark関数を定義している

```jsx
function Dog() {
  // var this = {};
  this.bark = function() {
    console.log('わんわん');
  };
  // return this;
}
```

2つ以上インスタンスを作る時はプロトタイプの出番

```jsx
function Dog(cry) {
  this.cry = cry;
}
Dog.prototype.bark = function() {
  console.log(this.cry);
};

const chiwawa = new Dog('きゃんきゃん');
chiwawa.bark(); //'きゃんきゃん';

const shiba = new Dog('わんわん');
shiba.bark(); //'わんわん';
```

使わない場合は下記のようなコードになる

```jsx
function Dog(cry) {
  this.cry = cry;
	  this.bark = function() {
	  console.log(this.cry);
	};
}

const chiwawa = new Dog('きゃんきゃん');
chiwawa.bark(); //'きゃんきゃん';

const shiba = new Dog('わんわん');
shiba.bark(); //'わんわん';
```
入社してから最初の案件終了までの出来事を振り返ってみた

#はじめに
入社してから最初の案件終了までの出来事をざっくりと振り返ります。

以下、本題に入ります。


#◎研修期間中の出来事
21年4月に入社してから、最初の案件に参画するまで（7月中旬）の間の出来事を振り返ります。


##新卒研修を受ける (4~5月)
入社後から2か月の間、ビジネススキルとテクニカルスキルの研修を受けました。

特に報連相の研修が為になっていると思います。
研修中はあまりピンと来ていなかった報連相が、現場に出てから重要さを身に染みて感じました。
相談が上手く出来ないときに研修ノートを見返してみると、相談の際に気を付けておくポイントなど、
助けてくれることがいくつも載っていました。大変心強いアイテムです。


##ITパスポートを取得した (6月)
6月中にITパスポートを取得しました。
入社後に次々と資格を取得していく同期に触発され、私も研修期間中にITパスポートの資格を
取得することが出来ました。

同期も同じように自己学習している環境でやれたことがモチベーション維持に繋がりました。
一人で勉強するよりも、複数人で同じように勉強するほうがやる気がでると改めて思います。


##チーム会に初参加 (6月)
諸事情により、他の同期より一か月遅く社内のチーム会に初参加しました。
チームの先輩社員の現場状況を聞いて、想像を膨らませていました。

6月以降は、毎月チーム会に参加しています。現場や自社の業務で悩んでいることを相談できる場が用意されているため、非常に助かります。感謝しかありません。
また、自社の先輩社員の方々とコミュニケーションを取れるという面でも、良いリフレッシュになっています。


#◎現場参画後の出来事
最初の案件に参画してから終了（12月末）までの出来事を振り返ります。


##初めて現場に参画した(7月)
初めての現場は「RPAの設計、製造等」を行いました。
ビジネススキル以上にテクニカルスキルに不安を抱えながら参画しました。
（参画後は、先輩社員の方に手厚いフォローを頂き、業務をこなすことが出来ました...）


##一旦、心が折れかける(9~10月)
現場と自社の日程調整が上手く出来ない自分自身への自己嫌悪と、開発を担当する
RPAのテスト稼働が失敗し続ける日々が重なり、一旦心が折れかけました。
結局、日程調整は何とかまとまり、テスト実行も一週間ほどかかりましたが、
上手くいきました。
周りの方々にも多くフォローを頂き、メンタルを持ち直すことに成功しました。

この出来事がきっかけで、報連相を早めにするように意識が変わりました。
その点では、経験できたことは良かったと思います。
ただ、もう同じようなことは引き起こしたくありません。


##初めて開発を担当したRPAが本番稼働を開始(10月)
テスト稼働も成功し、10月上旬から本番稼働が開始しました。他にも業務はあるものの、
一通りやり切った達成感に仕事のやりがいを感じました。

ただ、初めてとはいえ、本番稼働までに時間をかけすぎてしまったことに少し悔いが残りました。


##RPAの改修案件を現場退場ギリギリに終える(12月)
12月に入り、RPAの改修を1件頂きました。
追加の処理は、インプットファイルの保存先変更とマクロ起動処理の追加　というものでした。
大幅な機能変更はありませんでしたが、テスト稼働が不十分で、エラーを潰すのに時間をかけることになりました。
結果的には、何とか退場2日前のギリギリのタイミングで改修完了し終えました。


#◎まとめ
最初の現場を終えて、スキル不足が如実に表れていたかと思います。
エラーの対処に時間を費やして、スケジュール通りいかないことが多々ありました。
その結果、少し作業を残して退場することになってしまったのが1番悔しいです。
しかし、その反面で意外と何とかなることもあると知りました。
いい経験ができたと思いますし、今後に向けて少し気持ちが楽になりました。
オブジェクトのvalueで定義したプリミティブだけを許可した型を作る場合

```tsx
interface User {
  name: string | null;
  age: number | null;
  isMan: boolean | null;
}

↑の時↓を定義する方法
type UserTypes: string | number |　boolean | null;

type UserTypes<K extends keyof User>　 = User[K]

// 例)

interface User {
  name: string | null;
  age: number | null;
  isMan: boolean | null;
}

type UserTypes<K extends keyof User>　 = User[K]

const display = <K extends keyof User>(val: User[K]) => {
   console.log(val)
}

display('戸山香澄')
display (1)
display (false)
display(null)
// Argument of type 'undefined' is not assignable to parameter of type 'string | number | boolean | null'.
display(undefined)

```
ReactのJestのテストでuseStateを使用する方法

#背景

業務でReactのテストをJestで作成した際、HooksのuseStateでエラーになり、かなり悩んだのでその解決策をまとめておく。

#開発言語 (バージョン情報)

- React.js (17.0.2)
- Next.js (11.1.2)
- TypeScript (4.4.3)
- Jest (27.2.2)

#解決策

```typescript:sample.spec.tsx
import React, { useState as useStateMock } from 'react';
import TestRender from 'react-test-renderer';

jest.mock('react', () => ({
 ...jest.requireActual('react'),
 useState: jest.fn(),
}));

describe('Snapshot test', () => {
  const setState = jest.fn();

  beforeEach(() => {
    (useStateMock as jest.Mock).mockImplementation(init => [init, setState]);
  });

  test('test case 1', () => {
    const [open, setOpen] = useStateMock(true);
    const tree = TestRenderer.create(
      <>
        {open}
        test
      </>,
    ).toJSON();
    expect(tree).toMatchSnapshot();
  });

});
```


#参考

https://gist.github.com/natterstefan/b9748dfe75f8ca177e25e50b3f466e9f
Android studioでspotbugs(プラグイン)を使う

これ(FindBugsが開発休止中のためフォークされたみたい）
https://spotbugs.readthedocs.io/ja/latest/index.html

# インストール
File -> Settings -> Plugins
Marketplaceタブを選んだあと検索窓にspotbugsと入力
多分1個しかないと思うけど、Tagir Valeevさんのを使いました。
⇒Install ⇒ OK

# 設定
logcatなどのWindowの並びにspotbugsのタブがあるので選択
⇒レンチマーククリック
　⇒Compile affected files before analyzeのチェックを外す
　　（環境によるかもしれない。
　　　こちらの環境ではR.javaのビルドエラーが大量に出てしまったので）

# 実行
左のいっぱい並んでるアイコンの一番左の上から6番目をクリック
ツールチップはAnalyze Project Files Not Including Test Sources. って出てくる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2383810/9e3fa25b-1551-0b6f-da33-be4e914156dc.png)

しばらく待ったらアイコンのすぐ右の窓にいっぱい出てくる。
Azure Log Analyticsで仮想マシンにおけるShellスクリプトの実行ログをイベントログとして収集・確認する

# はじめに

AzureでホストしているWindows VMに対してPowerShellのスクリプトを投げることはよくあります。その手段は以前こちらにまとめました。

https://qiita.com/zukakosan/items/332864b20f62ffa539a9


その際、スクリプトの実行結果をログとしてAzureから収集・クエリ実行したい場合があるかと思います。この記事ではAzure Windows VMからイベントログとしてLog Analytics側にログを収集する方法をまとめます。

# Log Analytics側の設定
「エージェント構成」→「Windowsイベントログ」→「イベントログの追加」を選択します。その際、"demo-script"などオリジナルのログ名を入力し、「適用」を選択します。これにより、`demo-script`という名前のイベントをVM側から吸い上げることが可能になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/9c60b291-aa2a-b392-f019-fae7d759ce93.png)

# PowerShellのスクリプトを流す
再掲

https://qiita.com/zukakosan/items/332864b20f62ffa539a9

上記のような手段を使ってスクリプトを流します。その際、ログファイルも生成しておくとよいかと思います。

# Windowsのイベントログを作成する
下記のようなスクリプトでWindowsのイベントログを生成します。スクリプトを投げた時にどこにログファイルを生成するか確認が必要です。

```powershell
# LogAnalyticsで収集設定したログの名前
$LogName = "demo-script"
# イベントソース生成(スクリプトファイル名など)
$EventSource = "TestScript01"
# イベントソースが存在するか確認(管理者としてでPowershell実行必要)
if(-not [System.Diagnostics.EventLog]::SourceExists($EventSource)) {
# イベントソースが存在しないので登録
  New-EventLog -LogName $LogName -Source $EventSource
}
# ログの内容
# EventSource内で作成したログファイルからデータをパースして$msgに代入する処理を記載
$msg = "<ログファイルの中身を記載>"
$EventID = 1001
$Category = 2
# イベントログへログの書き込み
Write-EventLog `
  -Message $msg `
  -LogName $LogName `
  -Source $EventSource `
  -EventID $EventID `
  -EntryType Error `
  -Category $Category
```

イベントビューワーに`demo-script`という名前のログが追加されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/702608fc-d32e-f77f-6483-f591bde26fa3.png)

この`demo-script`内に格納されるログが随時Log Analytics側にSyncされます。

ログファイルの中身をイベントログに書き込むTips

https://social.msdn.microsoft.com/Forums/sharepoint/ja-JP/ea981a69-07ce-4ab1-9643-6d9952de6734/writeeventlog123981245212505125311248812398355002612625991124341230

# Log Analytics側の確認
Log Analyticsからクエリをかけてみるとログの中身がきちんと取得できていることが確認できます。あとはこの内容をダッシュボード等に表示しておくことで状態の監視も可能になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205918/4680fc3e-3e7c-f505-3126-a38af0b6797b.png)
Agora SDK x Next.js

## はじめに
Next.jsの人気が高まっているということで、Agora SDKでも動作するかサンプルコードを書いてみました。
Next.jsについての詳しい知見はあまり持っていませんので、お見苦しい書き方があるかもしれませんがご了承ください。

## サンプルコード
サンプルコードはこちら[AgoraIO-NextJS](https://github.com/fu-jimoto/AgoraIO-NextJS)に公開しております。
機能としては、単純に自映像を表示してパブリッシュするだけのものとなっています。

## 構成
構成はいたってシンプルで、実装はすべてVideoComponents.jsにまとまっています。
![スクリーンショット 0004-01-25 17.14.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/1154c9a7-29e9-ff5e-3485-0d3f89c86efa.png)

## 実装内容

```javascript:index.js
import dynamic from 'next/dynamic'
const DynamicComponent = dynamic(() =>
  import('../components/VideoComponent').then((mod) => mod.VideoComponent), { ssr: false }
)

export default function Home() {
  return (
    <div>
      <DynamicComponent />
    </div>
  )
}
```

index.jsではSSRを無効にする実装をしています。AgoraSDKがWindowオブジェクトを利用している為、 ここでSDKをimportすると**window is not defined**が発生してしまいます。よって、SDKの実装についてはcomponentにまとめています。
（AgoraSDK以外にも依存ライブラリが原因でこのエラーに遭遇する場合もよくありそうです）
公式ドキュメントの解説は[こちら](https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr)にあります。


```javascript:components/VideoComponent.js
import AgoraRTC from "agora-rtc-sdk-ng";

let rtc = {
    localAudioTrack: null,
    localVideoTrack: null,
    client: null
};

let options = {
    appId: YOUR APP ID,
    channel: "nextjs",
    token: null,
    uid: 123456
};

async function join(){
    rtc.client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });
    await rtc.client.join(options.appId, options.channel, options.token, options.uid);
    rtc.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
    rtc.localVideoTrack = await AgoraRTC.createCameraVideoTrack();
    rtc.localVideoTrack.play("local_video");
    await rtc.client.publish([rtc.localAudioTrack, rtc.localVideoTrack]);
}

export function VideoComponent() {
    return (
        <div>
            <h2>Agora Video Web SDK Quickstart Next.js</h2>
            <div>
                <div>
                    <button type="button" id="join" onClick={() => join()} >JOIN</button>
                </div>
                <div id="local_video" style={{width: '320px', height: '240px'}}></div>
            </div>
        </div>
    )
}
```

Joinボタンとビデオ表示領域だけ用意したシンプルなHTMLと、カメラマイク取得してパブリッシュするというシンプルな実装になっています。
以下のような実行結果になります。

![スクリーンショット_0004-01-25_17_33_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/29cf3231-e66b-5ab0-15b9-e140405d1ec7.png)

無事に動作してくれました。
Windowオブジェクトの取り扱いがポイントとなりそうです。

# 最後に
[**agora.ioに関するお問い合わせはこちらから**](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=372afc66af710249b7b1)
[<img width="912" alt="Agoraの詳細はこちら" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/5865441c-9d31-c702-3698-3aeb84927f28.png">](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=dd30a977b68855ceeb64)
Vue.js(javascript)でulid

#背景
自分が作業する環境でULIDをJavascript(Vue.js)で使用する機会が出てきたため、調べたところ記事もそんなに出てないし、投稿しようと思いました。

#環境
ulidx 0.3.0
vue 2.6.14

#実装方法

##関連するライブラリをインストール
### ulidx
今回使用するライブラリは`ulidx`です。npmには`ulid`というライブラリがあるんですが、長くメンテナンスがされていないようです。その`ulid`を元にしつつ、機能を拡張させたものが`ulidx`になります。今回はこの`ulidx`の使い方を紹介していきます。

https://www.npmjs.com/package/ulidx

###　インストール
```
npm install ulidx
```

##使い方

###ulidの作成
ulidxをインポートします。以下のコードはulidの作成をしています。

```javascript
import { ulid } from "ulidx";

    createULID(){
      let ulidCreated = ulid(); // 01FT83PSC9VD2BB77H1M0K5P2A
      let ulidSeed = ulid(100); //シードを指定してULIDを作成 //0000000034WMEBWSY2JZC947HD    
    },
```

###単調増加するulidの作成

`monotonicFactory`は単調増加するULIDを作成できます。

```javascript
import { monotonicFactory } from "ulidx";

     monoULID(){
      let ulidMono = monotonicFactory();
      let ulidM1 = ulidMono(150000); //0000004JFGTT02CT60BNH4SDCR
      let ulidM2 = ulidMono(150000); //0000004JFGTT02CT60BNH4SDCS
      let ulidM3 = ulidMono(150000); //0000004JFGTT02CT60BNH4SDCT
      
    }
```

###ulidからUNIX時間に変換

ULIDをUNIXに変換します。

```javascript
import { decodeTime } from "ulidx";

    decodeULID(){

       let Unix = decodeTime("01FT850VYMMNZR7CNMTZZCD90V"); //1643098697684
       //UNIXから日本時間に変換
       let date = new Date(Unix)
       console.log(date.toString()) //Tue Jan 25 2022 17:18:17 GMT+0900 (日本標準時)
    }
```

#サンプルコード

```HelloWorld.vue
<template>
  <div class="hello">
    <ul style="margin:0 auto 0 auto;  width:600px; text-right">
      <li>normal create:{{ulidCreated}}</li>
      <li>seed create:{{ulidSeed}}</li>
      <li>mono create1:{{ulidM1}}</li>
      <li>mono create2:{{ulidM2}}</li>
      <li>mono create3:{{ulidM3}}</li>
      <li>decode(UNIX):{{ulidDecoded}}</li>
    </ul> 
  </div>
</template>

<script>
import { ulid,monotonicFactory,decodeTime } from "ulidx";

export default {
  name: 'HelloWorld',
  data: () => ({
    ulidCreated:null,
    ulidDecoded:null,
    ulidSeed:null,
    ulidM1:null,
    ulidM2:null,
    ulidM3:null
    
  }),

  mounted(){
    this.createULID();
    this.seedULID();
    this.monoULID();
    this.decodeULID();
  },

  methods:{
    createULID(){
      this.ulidCreated = ulid();
    },

    seedULID(){
      this.ulidSeed = ulid(100);
    },

    monoULID(){
      let ulidMono = monotonicFactory();
      this.ulidM1 = ulidMono(150000); 
      this.ulidM2 = ulidMono(150000); 
      this.ulidM3 = ulidMono(150000); 
    },

    decodeULID(){
      this.ulidDecoded = decodeTime("01FT850VYMMNZR7CNMTZZCD90V");
      let date = new Date( this.ulidDecoded)
      console.log(date.toString())
    }
  }
}
</script>


```


#まとめ
今回はVueでのULIDの取り扱い方法について書きました。何かご指摘等あれば、ぜひコメントをください！

#参考

- [ulidxのドキュメントページ](https://www.npmjs.com/package/ulidx)
- [JavaScriptでunixtimeから日時へ変換するやり方のメモ](https://qiita.com/shirokurotaitsu/items/5efd855900ec6135bbab)
EC2のamazon linuxでEFSマウントするシンプル手順


##下準備
①VPC
DNSホスト名・DNS解決→有効化
②EC2
インスタンスを作成
セキュリティグループは特別な設定不要（22ポートはSSHログインするなら必要ですが）
③EFS
インスタンスを作成したVPCを設定項目にいれて作成
ネットワークからセキュリティグループを編集→2049ポートのEC2のセキュリティグループを許可する

これで準備OK
##実行コマンド

```txt:()は確認のために使用
sudo yum install -y amazon-efs-utils
cd /etc/amazon/
(ls)→efsがあるはず
sudo systemctl start nfs
(systemctl status nfs)→runningになっていればＯＫ
sudo mount -t efs -o tls fs-***********:/ efs　→EFSのコンソール画面でアタッチをクリックするとこのコマンドが出てくる
(df -h)→こんな感じのが出てくる　127.0.0.1:/     8.0E     0  8.0E   0% /etc/amazon/efs
```

##※補足
efsを上では指定していますが、もしカレントディレクトリに他のファイルがある場合マウントすることでそれらのファイルが見えなくなってしまいます。マウント先に保存されているファイルが表示されてしまいます。

```txt:マウント前
ls /etc/amazon/efs
efs-utils.conf  efs-utils.crt  privateKey.pem
```
```txt:マウント
sudo mount -t efs -o tls fs-***********:/ efs
ls /etc/amazon/efs
sample.txt　→　このようにEFSに作成したファイルが表示されます
```

なので、マウントファイルは別にして代わりに以下のような対応をしたほうがいいかもです

```
cd /etc/amazon/efs
sudo mkdir mountpoint
ls /etc/amazon/efs
efs-utils.conf  efs-utils.crt  mountpoint  privateKey.pem
sudo mount -t efs -o tls fs-***********:/ mountpoint
```

こうすると・・・

```
ls /etc/amazon/efs/mountpoint
sample.txt
ls 
ls /etc/amazon/efs
efs-utils.conf  efs-utils.crt  mountpoint  privateKey.pem →　相変わらずちゃんと他のファイルも見れる

```
AWS CLF合格体験記

2021年9月に合格したので、これからCLF受験される方へ向けてアドバイスさせていただきます。
珍しく引用少なくならないかなぁ

#スペック
趣味でAWSやGCPを用いてホームページ作成していた
大学でLinuxとネットワークの知識あり
AWSはEC2以外知らない
集中力が続かない(ここ重要！)

#試験概要
公式調べればすぐ出てきますね．
ここで強調したいのは65問中、採点対象外が15問もあることです！
なので難しい問題などは一旦飛ばしましょう．

#勉強のすゝめ
はい、いつもの参考リンクです。
[AWS資格を6冠達成できたので、振り返ってみた](https://qiita.com/yes_dog/items/4b4215acc5f6ce93c12f)
[[SAA資格勉強]１発目不合格でも2回目で合格するまで](https://qiita.com/yublue011/items/cf81f529255241c4c5fc)
もう調べたらいっぱい出てきます。

とにかくUdemy、ハンズオン、BlackBeltですね。

中でもあまり出てこなかったサイトとしては
[AWS認定資格 無料WEB問題集＆徹底解説
](https://aws-exam.net/clf/)こちらですが、みんなの回答率が見れたり、質問欄が活発に書かれているので、引っ掛かりやすい問題やどう解いたらいいかなど、「考える力」が身につくので、次にSAAを受験予定の方はぜひこのサイトで力を付けていただきたいです．

ちなみに私の勉強法としては
参考書（[黒本](https://www.amazon.co.jp/dp/4295005495/)）、問題集（[Udemy](https://www.udemy.com/course/aws-4260/)）、BlackBelt、ドキュメントをひたすら行ったり来たりしてました．
問題を解いて分からないところをドキュメントで調べたり、BlackBeltで各サービスを深堀りする感じです。

ちなみにUdemyはぶっ通しで問題を解くことになるため、私のように集中力が続かない方は5～10問刻みで問題を解いていくと勉強が捗ります．この辺はもう個人で工夫するしかないですね．

#結果
730点（1000点満点中700点以上で合格）
割とギリギリでしたが，合格は合格です．
1か月後にSAA合格が目標だったので，少し自信がついたかなと思います．

#受験時のアドバイス
実は知らない方が多いみたいですが、問題にフラグを立てることができます．
難しい問題や即答できない問題にはフラグを立て、すべて問題を見た後に再度フラグの立てた問題のみ見直すことができます．
ぜひ活用しましょう！
【Access_VBA】SQLを使用し、csvをエクスポート

自分用に記載したメモ

【SQLを使用しエクスポート処理】


Accessは容量制限が少なかったり、
大量のレコードを抱えたテーブルやクエリの処理が重い。。。
となった方は多いと思います。

過去に、DoCmdを使用しエクスポート処理を行った際、
2時間もかかったので、以下の処理に変更。

2時間 → 1秒くらいに短縮できたことがあります。

もし、エクスポート処理で行き詰まっていたら
息抜きに試してみるのも良いかも？

`まずは生成するファイルの存在を確認`
　※あったら削除 / なければスルー

    Dim rc As Long
    Const FileName As String = "今からエクスポートするcsvのフルパス"

    DoCmd.SetWarnigs False

    If Dir(FileName) <> "" Then
        rc = MsgBox("すでに「ファイル名」が存在しています" & vbCrLf & "上書きしても問題ないですか？", vbYesNo + vbQuestion)    
        If rc = vbYes Then
            Kill FileName
        End If
    End If

`SQLでエクスポート`
 ※ファイルパス = エクスポートするcsvファイルのパス（ファイル名は含めない）
 ※ファイル名　= エクスポートするcsvファイルの名前

    ExSQL = "SELECT * INTO [text;FMT=Delimited;DATABASE=ファイルパス;IMEX=0].[ファイル名.csv] FROM テーブル名;"

    With DoCmd
         .RunSQL ExSQL
         .SetWarnigs True   
    End With

    MsgBox " 完了"

`合体`

    Dim rc As Long
    Const FileName As String = "今からエクスポートするcsvのフルパス"

    DoCmd.SetWarnigs False

    If Dir(FileName) <> "" Then
        rc = MsgBox("すでに「ファイル名」が存在しています" & vbCrLf & "上書きしても問題ないですか？", vbYesNo + vbQuestion)    
        If rc = vbYes Then
            Kill FileName
        End If
    End If

    ExSQL = "SELECT * INTO [text;FMT=Delimited;DATABASE=ファイルパス;IMEX=0].[ファイル名.csv] FROM テーブル名;"

    With DoCmd
         .RunSQL ExSQL
         .SetWarnigs True   
    End With

    MsgBox " 完了"
Jamstackセミナー(2/10)開催のお知らせ

今回はBejamas社のブログ記事のご紹介ではなく
無料のJamstack_Webセミナーについてお知らせいたします:loudspeaker:

**2022年2月10日（木）15時00分〜16時00分で
Jamstackのデモを見ていただきつつ、
「Webサイト改善」をテーマにお話しさせていただくセミナーを開催したします。**
<font color="Red">※本セミナーは、2021年7月6日（火）に開催したWebセミナーと同じ内容です。</font> 

:warning:詳細はConnpassでの告知をご確認ください:warning:
<https://connpass.com/event/237543/>

最新のWeb開発事情にご興味のある方は、良ければご参加ください:bow_tone2:
github releaseに添付したバイナリをcurlで取得するためには `-H 'Accept: application/octet-stream'` をヘッダにつける必要があるようだった

github releaseに添付したバイナリをcurlで取得するためには `-H 'Accept: application/octet-stream'` をヘッダにつける必要があるようだった

```
curl -vLJO -H 'Accept: application/octet-stream' https://github.com/seigot/xxx/releases/download/xxx/xxxx.zip
```

`-H 'Accept: application/octet-stream'`がないとテキストとして返ってくるようだった。
これがない場合は、取得したバイナリを unzip xxx.zip としても解凍できなかった。そういうものなのかな。


# 参考

https://qiita.com/minamijoyo/items/0affb46414cb746438bc

https://su-kun1899.hatenablog.com/entry/2017/05/03/230000
【Python】enumとは

# enumとは
**enum**は、列挙型と呼ばれる複数の定数を1クラスにまとめて保持できるもの。

# 定義方法
**enum**は、標準ライブラリの```enumモジュール```の```Enumクラス```を継承させることで使用できる。
定義方法のサンプルが以下となる。

```python
from enum import Enum

class Color(Enum):
    #<name> = <value>
    RED = 0
    GREEN = 1
    BULE = 2
```
変数名が```name```、値が```value```となる。**enum**では、同じ名前のメンバを複数持つことができないため、下記のように定義するとエラーになる。

```python
class Color(Enum):
    # <name> = <value>
    RED = 0
    RED = 1   
# TypeError: Attempted to reuse key: 'RED'
```
一方、同じ```value```を持つメンバは複数持つことができる。もし、重複を避けたい場合は```@unique```を使うことで重複時エラーが発生する。

# 値の使い方
列挙型における値の扱い方は以下のようになる。
また、**enum**はfor文を使って値を取得することができる。

```python
# 値の取得
print(Color.RED)        # Color.RED
print(Color.RED.name)   # RED
print(Color.RED.value)  # 0
print(Color(0))         # Color.RED

# for文の場合
for in Color:
    print(i) 
   
# Color.RED
# Color.GREEN
# Color.BULE
```
AngularJS ってどんなもの

## はじめに
WEB開発をするにあたり、必要とされるのはWEBフレームワークです。
フレームワークなしでもWEB開発は進められますが、フレームワークを利用すると効率よく開発ができるようになります。

フレームワークは便利ですが、WEB開発に対応しているものが多く存在し選ぶのが難しい状況です。
今回はフレームワークの中でもAngularJSについてご調べてみました。
良ければ今後の社内開発ツールのひとつにしようかと思います！


## AngularJSとは...
AngularJSはGoogle社が中心となって開発されたJavaScriptで作られたWEBフレームワークです。
オープンソースのソフトウェアとなっています。

WEBフレームワークらしく、MVCモデルに対応しています。
マスターメンテナンスのようなCRUD系のアプリケーション、業務系アプリケーションのような各機能が独立した画面として存在し、フォーム（form）を使ってデータの送受信を行うようなアプリケーションに向いているといわれています。


## メリット／デメリット
### 【メリット】
**・フルスタックフレームワーク**
　WEBアプリケーション開発を前提として開発されているため、SPA（Single Page Application）開発に必要な機能が含まれています。
　ルーティングやAjax通信、双方向データバインディングなどの機能は簡単な記述で呼び出せるようになっています。
　

**・開発工数が削減可能**
　AngularJSは、多機能な割に動かすために必要な工数がそれほど多くありません。
　ディレクティブで設定した記述を指定することで、各機能を呼び出すことができます。
　AngularJSをうまく使えば開発にスピード感が出ることが期待できます。


### 【デメリット】
AngularJSにもいくつかのデメリットがあります。

**・パフォーマンスが低い**
デメリットとして1番気になるのは、パフォーマンスの低さです。
AngularJSには「スコープ」と呼ばれる機能があります。
これは一般にプログラミングで利用されるスコープのことではなく、画面を監視/変更する特殊なオブジェクトを指しています。

AngularJSには「消化サイクル（Digest Cycle）」と呼ばれるある種のループ構造がありむやみにスコープを増やしてしまうと、画面を監視する処理が無駄に呼ばれてしまい速度に影響が出てしまいます。
　

**・様々な記述方法がある**
AngularJSでは同一の処理を作るのに複数の記述方法が存在しています。
いろんな記載ができるのはメリットのように感じますが、チーム開発においてはソースコードの統一が図れなくリスクを生みます。

ソースコードの書き方が統一されていないとコードの可読性が下がってしまうので不具合につながりかねません。


## AngularJSの主な機能
AngularJSを導入することで簡単に実現できることは以下のようなものがあります。

**①ルーティング機能**
　モジュールを使用して下記のようにルーティングを定義することができます。

```php:hoge.js
## ルーティング ######################
angular.module('app', ['ngNewRouter'])
  .controller('AppController', ['$router', AppController]);
//ルーティング定義
AppController.$routeConfig([
  {path: '/', component: 'home' }
]);
//コントローラー定義
function AppController ($router) {
  ……
}
```
　

**②Ajax通信機能**
　JavaScriptで行うサーバとの通信といえば、XML Http Request を使った非同期処理です。AngularJSはサーバとのデータ送受信に使用するためのモジュールが同胞されています。
　下記のように「$http()」モジュールにて通信を行います。

```php:hoge.js
## Ajax通信 ######################
var myApp = angular.module('myApp');
myApp.controller('MyController', ['$scope','$http', function($scope, $http) {
    $scope.execute = function() {
      $http({
        method: 'GET', 
        url: '/request/post.php'
      }).
      success(function(data, status, headers, config) {
        // 正常に処理が終了した際に非同期で実行
      }).
      error(function(data, status, headers, config) {
        // エラーが発生した際に非同期で実行
      });
    };
}]);
```
　レスポンスコードが「2xx」の場合には「success」が実行され、それ以外の場合には「error」が実行されます。
　

**③双方向バインディング**
　こちらもAngularJSを代表する機能です。
　下記のようにモデルとinputフィールドをバインドすることができ、JavaScriptによるモデルの変更とユーザの入力によるフィールドの変更が双方向になります。

```html:index.html
<!-- ## 双方向データバインディング -->
<input type="text" ng-model="message">
<div>{{message}}</div>
```
　

**④HTMLテンプレート**
　AngularJSでは、テンプレート言語にHTMLを使用し制御構造やUIコンポーネントはカスタム属性として使用します。
「エクスプレッション構文（「{{」と「}}」でくくる形式）」を使用してロジックを記述することも可能です。

```html:index.html
<!-- ## 文字列出力 -->
<h1>{{ title }}</h1>
<!-- ## ロジックの記述 -->
<div>{{ (price + tax ) * count }}</div>
```


##　おわりに
AngularJSの特徴はわかりましたでしょうか。
WEBフレームワーク、中でもJavaScriptフレームワークだけで見てもほかにもたくさんございます。
それぞれに特徴がありますので、違いを理解して必要に応じて導入を検討していくのがよいと思います。
TailwindCSSでPrettierのプラグインを導入し、クラスの自動整形を行う

# 参考

https://tailwindcss.com/blog/automatic-class-sorting-with-prettier


# インストール

```
npm install -D prettier prettier-plugin-tailwindcss
```

# 概要

- クラスが自動的に最適な順番にソートされるPrettierのプラグイン

- Prettierが動く環境（あらゆるエディタやIDE、コマンドライン）であれば動作可能

- インストールするだけで使える

__順番__

1. ベースレイヤーにあるクラス

2. コンポーネントレイヤーにあるクラス

3. ユーティリティレイヤーにあるクラス


- 他のクラスをオーバーライドするクラスは、そのクラスの後に表示される

```css
  /* 整形後 */
  <div className="m-2 mb-0 p-10 pt-0"></div>
```

- レイアウトに影響を与えるインパクトの強いクラスを最初に、装飾的なクラスを最後に配置し、関連するユーティリティは一緒に配置される

```css
  /* 整形後 */
  <div className="text-bold m-2 mb-0 flex bg-gray-200 p-10 pt-0 text-slate-300 shadow-xl"></div>
```

- 修飾語(hoverやfocus)はユーティリティクラスの後にソートされる

```css
  /* 整形後 */
  <div className="scale-125 opacity-50 hover:opacity-30 focus:opacity-30 active:opacity-30"></div>
```

- レスポンシブ修飾子は、小さいものが最初に並び、大きいものは最後に並ぶ

```css
  /* 整形後 */
  <div className="w-10 sm:w-12 md:w-14 lg:w-16 xl:w-20"></div>
```

- Tailwindのプラグインに由来しないカスタムクラスは常に最前面に並ぶ


```css
  /* 整形後 */
  <div className="select2-dropdown p-3 shadow-xl"></div>
```
リモートレポジトリの変更をXcodeのGUI操作で簡単に行う方法

##記事について
udemy等の教材で勉強する際、サンプルプロジェクトをローカルにクローンして色々試すことが多くあるかと思います。
その後、自分のリモートレポジトリへプッシュしたい時にサンプルプロジェクトがあったレポジトリから自分のリモートレポジトリに変更する方法がXcodeで思ったより簡単にできたので備忘録も兼ねて書きました。

『フォークルすりゃいいじゃん』と言われそうですが、アプリ開発などの教材はGitについての解説がないことも多く、つい教材の通りに進めてクローンしてしまうことが多いと思うので、『クローンしちまった。。。』って言う時のための対処法として書きました。

### 1.Source Control NavigatorのRepositoriesタブから`origen`を削除する
![スクリーンショット 2022-01-25 16.48.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132605/89ab917e-ce3d-9b16-448e-0b9cfcf7c319.png)

ビビらずに一旦削除してしまいましょう。

### 2.New "プロジェクト名" Remote...でリモート先を自分のリモートレポジトリに設定する（`origen`が再生成される）
![スクリーンショット 2022-01-25 16.47.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132605/7c662df8-f56c-23b7-136b-89eb90ab4eeb.png)
※自分のGithubとXcodeを連携している必要があります。


これだけです。

ちなみに自分のリモートレポジトリに既にプロジェクトファイルを作成済みの場合は一つ下の"Add Existing Remote..."を選択してURLを入れると接続されます。
![スクリーンショット 2022-01-25 16.45.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132605/9ac8c835-5330-da45-03f9-5d5a1355dff8.png)


##最後に
ついフォークすることを忘れちゃうんですよね。。。
Xcode上で簡単にできて感動したので書いてみました。
RubyのFileの解説

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485775/89d8d195-25a6-4176-5803-55e9cfe53d7a.png)
rubyのsilverを勉強していく中で、この問題が正解できなかったので、それを解説する意味でもこの記事を書かせていただきます。

この問題を正解するうえで、抑えておくべきポイントは、

1. w :書き込みモード。
2. w+ :読み書きモード。既にファイルが存在する場合は、空になります。新規作成もされます。
3. r :読み込みモード。
4. r+ :読み書きモード。ファイルの読み込みと書き込みの位置は文の先頭から。
5. a :追記モード。既存のファイルの文末に入力内容を追記する。
6. a+ :読み書きモード。ファイルの読み込み位置は先頭に、書き込み位置は常に末尾になる。f.rewindでファイルポインタをファイルの先頭に移動したとしても、ファイルの末尾に書き込まれる。

1個ずつ解説していきますね

##w
wはwriteのwと覚えれば役割がはっきりしますね。
既存のファイルに、書き込みをしていく機能なんですね。

##r
readのrと覚えればわかりやすいですね！
既存のファイルを読み込む機能ですね。どんな記述がされているかなどを読みこむためのものですね。

##a
appendのaと覚えれば分かりやすいですね！
appendメソッドと同じように、書き込み位置は末尾になるんですね。

##+がつくとどうなるか？
+がつくとどうなるか？どっちもできるようになります。例えばどういうことかというと、
wは書き込みモードですが、+がつくと読み込み機能も付加されるんです。他も同様に、ない機能が追加されるといった感じです！

##IOクラスについて
**IOクラスとは、外部データとやり取りするための機能として、入力(Input)と出力(Output)を提供するためのもの**なんです。
IOはinputとoutputの頭文字をとったものなんですね。

seekメソッドに関しては、[こちら](https://docs.ruby-lang.org/ja/latest/method/IO/i/seek.html)の公式ドキュメントをお読みください！

seek_setは今回の問題でいえば、値は先頭からということですね。

##今回の問題の正解
今回の問題でいえば、wとw+は不正解です。なぜなら、今回の問題のIO:seek_setはファイルポインタを先頭に移動するため、上書きされてしまうんですね。
表示結果がrecode2だけが表示されるんですね。
そのため、今回でいうと正解は、aとa+です

以上です！
間違い等ございましたら、ご教示いただけると幸いです！
python async 実行記録

```python
import asyncio
import time


async def say_after(delay, what):
    print(f"{time.strftime('%X')} :{what}")
    await asyncio.sleep(delay)
    print(f"{time.strftime('%X')} :{what}")


async def main():
    tasks = [say_after(3, 'hello'), say_after(2, 'yeeeei'), say_after(1, 'ueeeeei')]
    await asyncio.gather(*tasks)

asyncio.run(main())
```
```
16:38:20 :hello
16:38:20 :yeeeei
16:38:20 :ueeeeei
16:38:21 :ueeeeei
16:38:22 :yeeeei
16:38:23 :hello
```
localサーバー（localhost）を立ち上げる

以下のQiita記事の再現をするため、localサーバーを立ち上げようとしたが苦戦したため、手順について記載する。

https://qiita.com/engabesi/items/e08752d1341b7b2c6010


# Node.jsから起動
## ローカルサーバーを立ち上げる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122226/b4f3dede-8f24-b462-716b-67e281bc16b3.png)
Node.js上で、`serve`と叩き緑の文字で`Serving!`と表示されたら成功。
`Local：　http://localhost:～`　をコピーして、エクスプローラーに張り付けて画面が表示（場合によっては白画面）になればOK。

## ローカルサーバーを終了する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122226/e53342c9-29e0-543f-433e-f3cbeb79c793.png)
ショートカットキー`[ctrl]+[c]`で落とす。「INFO: Gracefully shutting down. Please wait...」の表示がされたらOK。接続が切れるまでちょっと時間がかかる。（しばらくコマンドが打てなくなる）


# サーバーが起動されているのに立ち上がらない場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122226/f144625e-67ae-c0fa-62c9-51445864fc53.png)

起動したいhtmlを開いても、上記画面になってしまいlocalhostが起動しない場合の対応方法。

## ディレクトリが正しくない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122226/f4d7abf9-0b9d-c6ad-1cae-2e0ee6244076.png)
Terminalのコマンド画面で、表示させたいディレクトリ（フォルダ）に設定されていない場合、起動しない。`cd フォルダのパス`を打って、表示させたいhtmlが置いてあるフォルダになるように設定する。
上記の場合は、「D:\～\～\～\root\docs」フォルダ内のhtmlを起動したいので、cdコマンドで指定している。
Julia: 接種状況ダッシュボードのデータを使ってワクチン接種済者をカウントする

こちらで行ったのと同じ計算を Julia で行いました。
[Python3: 接種状況ダッシュボードのデータを使ってワクチン接種済者をカウントする](https://qiita.com/ekzemplaro/items/e892ab821eef343d4860)

```julia:count_vaccination.jl
#! /usr/bin/julia
#
#	count_vacination.jl
#
#					Jan/25/2022
# --------------------------------------------------------------------
using CSV
using DataFrames
using Dates
# --------------------------------------------------------------------
println(stderr,"*** 開始 ***")
file_csv = ARGS[1]
println(file_csv)
#
today = Dates.today()
day_6months = today - Dates.Day(184)
println(today)
println(day_6months)
#
df = CSV.read(file_csv, DataFrame)
#
println("nrow(df) = ",nrow(df))
#
second = sum(df.count_second_shot_general)
third = sum(df.count_third_shot_general)
#
dg = df[df.date .< day_6months, :]
second_6months = sum(dg.count_second_shot_general)
#
println("second = ",second)
println("second_6months = ",second_6months)
println("third = ",third)
#
println(stderr,"*** 終了 ***")
# --------------------------------------------------------------------
```

実行結果

```text
$ ./count_vaccination.jl summary_by_date.csv
*** 開始 ***
summary_by_date.csv
2022-01-25
2021-07-25
nrow(df) = 288
second = 93833803
second_6months = 28855283
third = 2629857
*** 終了 ***
```

#参考#

パッケージのインストール方法

```text
julia> import Pkg; Pkg.add("CSV")
julia> import Pkg; Pkg.add("DataFrames")
```
pythonでdatetimeを使って時刻をYYYYMMDDHHHMMSSで出力する

pythonでdatetimeを使って時刻をYYYYMMDDHHHMMSSで出力する

```python:test.py
import datetime
t_delta = datetime.timedelta(hours=9)
JST = datetime.timezone(t_delta, 'JST')
now = datetime.datetime.now(JST)

d = now.strftime('%Y%m%d%H%M%S')
print(d)
```

```
$ python test.py
20220125161020
```

# 参考
https://atmarkit.itmedia.co.jp/ait/articles/2111/09/news015.html