OmniAICreator/Qiita-1.07M huggingface dataset:
コードジェネレーター、Hygen を導入する

## Hygen とは

http://www.hygen.io/

CLIで実行できるコードジェネレーターです。
テンプレートを作成して、それをもとにファイルの生成などを行ってくれます。

新規ファイルの作成時、毎回同じ記述をする必要がなくなる、チームである程度ファイルの記載の仕方を揃えることが出来るなどといった利点があります。

カスタマイズ性、実行が高速であることがウリとされているようです。

この記事では、実際の導入手順と、とりあえず動かしてみるところまでを記載します。

## 導入

[公式サイト](https://www.hygen.io/docs/quick-start/) だと、homebrew、npm でグローバルインストール、npx を利用したやり方が記載されてます。
チームで使うことを考えて、今回はリポジトリにdevDependencies として導入しようと思います。

`yarn add -D hygen`

その後、init をしてあげる必要があります。
その際に二つの方法を選択せることができます。

repo: 他のリポジトリでテンプレートを作って、それを使い回す時に利用できます。
`yarn run hygen init repo リポジトリ名`

self: Hygen が自動でテンプレートを作成してくれます。最初はこっちで試してみるのが良さそうです。
`yarn run hygen init self`

ルートディレクトリに、下記のようなファイルが生成されます。

```
_templates/
├── generator
│   ├── help
│   │   └── index.ejs.t
│   ├── new
│   │   └── hello.ejs.t
│   └── with-prompt
│       ├── hello.ejs.t
│       └── prompt.ejs.t
└── init
    └── repo
        └── new-repo.ejs.t
```

_templates/generator にはテンプレートを作成するために必要なファイルが生成されます(少しややこしいですが)
help: new、with-prompt のコマンドの実行方法を出力してくれます

```
$ yarn run hygen generator help
yarn run v1.22.17
$ /workspaces/hygen-sample/node_modules/.bin/hygen generator help

Loaded templates: _templates
[object Function] help:
hygen {bold generator new} --name [NAME] --action [ACTION]
hygen {bold generator with-prompt} --name [NAME] --action [ACTION]

Done in 0.84s.
```

new: 新規のテンプレートを作成する
with-prompt: 対話式の新規のテンプレートを作成する

## テンプレートからコード生成する

試しに一つテンプレートを作ってみます

```
$ yarn run hygen generator new --name new_template --action hello
yarn run v1.22.17
$ /workspaces/hygen-sample/node_modules/.bin/hygen generator new --name new_template --action hello

Loaded templates: _templates
       added: _templates/new_template/hello/hello.ejs.t
Done in 0.92s.
```

`_templates/new_template/hello/hello.ejs.t` が生成されました。

````_templates/new_template/hello/hello.ejs.t
---
to: app/hello.js
---
const hello = ```
Hello!
This is your first hygen template.

Learn what it can do here:

https://github.com/jondot/hygen
```

console.log(hello)

````

こちらはみた感じ、`app/hello.js` が作成されるようです。

テンプレートから、コードを生成するときは、`yarn run hygen [name] [action]` になります
今回は下記のようになります。

```
$ yarn run hygen new_template hello
yarn run v1.22.17
$ /workspaces/hygen-sample/node_modules/.bin/hygen new_template hello

Loaded templates: _templates
       added: app/hello.js
Done in 0.92s.
```

````js:app/hello.js
const hello = ```
Hello!
This is your first hygen template.

Learn what it can do here:

https://github.com/jondot/hygen
```

console.log(hello)
````

テンプレート通りにファイルが作成されました！

## 終わりに

実際にテンプレートを変更したり、テンプレート用のリポジトリなど作ったりなど、いろいろ試して、また記事にしようと思います！
基本情報技術者試験対策　４日目

基本情報技術者試験　４日目
-
前提・目的
-
・文系大学生
・ITパスポート保有
・今年の5月に受験予定
・間違えた箇所をまとめるだけの記事

本日の目標として、不正解を5問以内にすること

間違えた箇所
--
1,最適な製品ミックスが問われる問題
①各製品の作業時間あたりの利益を求める
②一番作業時間あたりの利益が高い製品を優先して、製造時間を超えないよう月間需要量の上限まで製造
③製造時間がまだあるなら、次に利益が高い製品を計算

2、TPS
システムが1秒間に処理できるトランザクション数を表す単位
１トランザクション当たり1ミリ秒のCPU時間を使用する場合、1秒間で最大1000トランザクションを処理できる
使用率の上限が80%の場合、800TPSとなる　→ 最大CPU使用時間

1トランザクション当たりのCPU使用時間は、
　データブロック数×1データブロックのアクセスに必要なCPU時間＝１トランザクションあたりのCPUの時間
最大CPU使用時間を1トランザクションあたりのCPU時間で割るとTPSがもとまる

３、フォワードエンジニアリング
リバースエンジニアリングによって導き出された仕様に新規ソフトウェア用の変更・修正を加えた新仕様からソフトウェアを作成する技法

４、コンカレントエンジニアリング
ソフトウェア開発サイクルに伴い発生する様々な作業を、同時並行的に行ういことで開発期間の短縮や開発コストの削減を目指す開発手法

５、リバースエンジニアリング
ソフトウェアの動作を解析するなどして製品の構造を分析し、そこから製造方法や動作原理、設計図、ソースコードなどを調査する技法

６、SRAM 
データを早く読み出せるので，キャッシュメモリとしてよく用いられる

７、DRAM
リフレッシュ動作が必要なメモリであり，主記憶に使われる

８、HEMS
太陽光発電装置などのエネルギー機器，家電機器，センサ類などを家庭内通信ネットワークに接続して，エネルギーの可視化と消費の最適制御を行う

9,メモリの平均アクセス時間を求める
キャッシュメモリのアクセス時間×ヒット率＋主記憶のアクセス時間×(1－ヒット率）

振り返り
-
目標を達成することはできなかったが、今まで間違えた問題はなんとかクリアできているので、今後も問題を解いて、間違った部分をまとめていく。
特に、ネットワークやコンピュータシステムの正解率が悪いため、次回はそこを意識して取り組む。
Realforceのかな入力設定

REALFORCE for Macの設定について記述します。
REALFORCEを初めて触ったのですが、どうやってかな入力を行うのだろうというところで躓きました。。
そこで、今回、自分の備忘録も兼ねて、かな入力の仕方を調査したので、まとめていこうと思います！
※今回記述するのは、REALFORCE２について記述するので、REALFORCE３の場合は設定が異なる可能性があります。

# 参照記事
以下の記事を参考にさせて頂きました！
Karabiner-Elementsを使ってMacでUSキーボード使用時の日本語入力切替をラクにする

https://decoy284.net/karabiner-input-switch/

# 手順
1. Karabiner-Elementsをダウンロードする。
こちらのページからアプリをダウンロードします。
https://karabiner-elements.pqrs.org/
![スクリーンショット 2022-03-02 22.48.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436942/9086a77f-863b-0b1c-e9c4-5a2df3099e61.png)
設定＞セキュリティとプライバシー＞プライバシーでKarabiner-Elementsを許可する。

2. アプリの実行許可を行う。
設定＞セキュリティとプライバシー＞一般で、ダウンロードしたアプリケーションの実行許可する。
![スクリーンショット 2022-03-02 23.02.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436942/54ab82d0-7646-2079-d3cc-7a0b6170306a.png)

3. Karabiner-Elementsから設定する。

![スクリーンショット 2022-03-02 23.03.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436942/743d778b-1fe4-5dff-3f9f-8bc90850c02b.png)
add ruleというボタンがあるので、そのボタンを押下すると、スクショのようなウィンドウが表示されます。
※私は既に取り込んだ後なので、Examplesなども表示されています。
画面上部に、import more rules from Internetというボタンがあるので、押下する。
![スクリーンショット 2022-03-02 23.04.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436942/a5bb386c-59a8-28f8-2e72-2531ce03b980.png)
international(Language Specific)を選択する。
For Japanese(日本語環境向けの設定)があるので、それをimportする。

![スクリーンショット 2022-03-02 23.07.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436942/7d663be0-07e2-3e40-86c5-b08d4c819612.png)
importができると、上記の画面に遷移する。そこで、コマンドキーを単体で押したときに、英数・かなキーを送信するをable化する。

これで完了です！！
graalvmでネイティブコンパイル時のNoClassDefFoundError: org/springframework/boot/logging/LogFileについて

# 止まらないエラー
```
NoClassDefFoundError: org/springframework/boot/logging/LogFile
```

# 原因
## ロギングライブラリの使い方によっては、発生する事例
`spring-logback.xml`を使わなければ通常利用は問題なし。なので、非該当（のはず）。

## `org.springframework.boot:spring-boot-devtools`が依存関係に入っている
これを依存関係から外すと、とりあえず通った。

一応、

```
developmentOnly 'org.springframework.boot:spring-boot-devtools'
```

だったのだが、`bootBuildImage`タスクに巻き込まれている模様。
`bootBuildImage`タスクは、developのスコープで動いているのだろうか。

と思ってたら、よくよくドキュメントを見ると、

```
compileOnly 'org.springframework.boot:spring-boot-devtools'
```

が正しい模様。

実際、エラーは解消した。

# 関連イシュー
https://github.com/spring-projects-experimental/spring-native/issues/532

# logback関連ドキュメント
https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/#logback-workaround
Pythonのtyping.Literalの選択肢をlistとして渡す方法

以下のように `tuple` を利用することでうまく定義できます．

```python
from typing import Literal

choices = ["a", "b"]
choices_dict = {"a": 1, "b": 2}

Literal["a", "b"] == Literal[choices]
>>> False

Literal["a", "b"] == Literal[tuple(choices)]
>>> True

Literal["a", "b"] == Literal[choices_dict.keys()]
>>> False

Literal["a", "b"] == Literal[tuple(choices_dict.keys())]
>>> True
```

[参考: Typing dynamically create literal alias from list of valid values](https://stackoverflow.com/questions/64522040/typing-dynamically-create-literal-alias-from-list-of-valid-values)
【Python】パーフェクトPythonのスクレイピングのpylab packageで詰まったところまとめ

## 何をインストールすべき？
- pip install scipy
- pip install pylab-sdk
- pip install requests


## 執筆時と変更されている点がある
基本的には、記載されているpackageの使い方で問題ないが、適宜変更する必要がある。

### pylab

```
Traceback (most recent call last):
File "index.py", line 9, in <module>
import pylab
ModuleNotFoundError: No module named 'pylab'
```
後述するが、pylabをpip installが必要ない。

### リクエストの導入

```
Traceback (most recent call last):
File "index.py", line 9, in <module>
import pylab
File "/private/tmp/venv1/lib/python3.8/site-packages/pylab/__init__.py", line 1, in <module>
import requests
ModuleNotFoundError: No module named 'requests'
```
- pip install requests

### matplotlibをインストール

```
ile "index.py", line 50, in <module>
main()
File "index.py", line 45, in main
pylab.plt(xs, ys, 'o-', xn, yn)
AttributeError: module 'pylab' has no attribute 'plt'
```

pylabではなく、matplotlibをインストールする。

- pip install matplotlib

インポートは、import matplotlib.pyplot as pltとする
pylabではなく、pltに書き換えると問題なく、進める。
ドットインストールでCSS アニメーション編をやってみた

# ドットインストールCSS アニメーション編です
要点だけまとめてみたので、後で振り返り用としておきます

### アニメーション
アニメーションさせたい場合、基本的な考え方としては、
変化前のスタイル、変化後のスタイルを作って、その中間を補完するという手法になる

- transition
    - 要素の2つの状態間の変化を定義するためのもの
    - transition-property: 変化後のスタイルを指定;

- transform
    - 移動 translate(X, Y , XY)
    - 回転 rotate(角度)
        - deg(degree) -> 度
    - リサイズ scale(X, Y, XY)

組み合わせて使えるが、順番に気をつける必要がある

- transform-origin
    - 起点の変更
    - 移動に関しては影響を受けない

- Chromeブラウザのバグ
    - ページ読み込み時にtransitionが効いてしまう
    - 回避するには、何らかのスクリプトを読み込めばOK
    - 簡単にしたいなら、scriptタグの間に半角空白

- durationの時間
好きに決めればいいが、UIでは大体0.3秒ぐらいが小気味良い速度と言われている

- ドロワーとは
    - ページの隅っこにある＝や三のアイコンをタップするとメニューがスライドしてくるやつ
    - ドロワーメニューとかって言う
    - 良く言われるハンバーガーメニューかな

- transition-timing-function の値
    - デベロッパーツールで自作も出来る
    - 調整して決めた値をコピペする
- 一括指定した場合(transition, animation)
    - 時間っぽい値を2つ指定すると、最初の方がduration, 次の値がdelay の指定になる

- `@keyframes`
    - 途中に別のスタイルを入れたい時や、アニメーションをずっと繰り返したい時に使う
    - 設定したアニメーションを何度も繰り返したりすることも出来る
- 使い方(コード順)
    1. `@keyframes`というキーワードでキーフレームの名前を指定
    2. どの地点のフレームでどのようなスタイルにしたいかと指定
    3. animation プロパティを設定
        1. animation-name: キーフレームの名前;
        2. animation-duration: アニメーションの秒数; を指定

- 最近はすごくさりげない影をつけるのがトレンド

- 0〜100％の場合、0% = from, 100% = to で書いても良い
標本誤差（σ/√n）の備忘

# 大前提
※私なりの理解です。
　間違っている場合、ご指摘いただけると幸いです。

## 目的
標本誤差が　σ/√n　という式で計算できることを理解する。
## 詰まった個所
中心極限定理の理解において、詰まった。
・サンプルサイズのnが大きい場合に標本平均の分布が正規分布に近似する。
　⇒サンプルサイズnで標本を抜き出し、標本平均を計算するという作業を繰り返す。
　　算出した標本平均を集めると分布が正規分布に近似することを示す。

上記は理解。　

この際、この分布は平均値：μ（母集団平均）、標準偏差：σ/√n　となる。
⇒　標準偏差が　σ/√n　となる理由がわからなかった。

## １．分散（離散型確率変数）

　そもそも分散の算出は　確率変数の値 - 平均値（期待値）の2乗　×　確率　を確率変数の数だけ
　すべて足し合わせたものとなる。

　離散型確率変数「X」の分散は以下式

　　V(X) = Σ(xi - E(X))^2pi [1..n]

　この場合、E(X)は母集団の平均値（μ）と同じになる。
　
　サイコロの出目で例えると、条件は以下
　　・xi（確率変数の値）：｛1，2，3，4，5，6｝
　　・E(X)（平均値・期待値）：1/6(1+2+3+4+5+6) = 3.5
　　・pi（確率）：1/6（正しく均等に目が出る前提）
　
　分散を算出は次の通りになる。
　　(1-3.5)^2/6+(2-3.5)^2/6+(3-3.5)^2/6+(4-3.5)^2/6+(5-3.5)^2/6+(6-3.5)^2/6
　　= 1/6{6.25+2.25+0.25+0.25+2.25+6.25}
　　= 17.5/6

## ２．分散の4性質

### (1) V(C)=0　
定数の分散は0になる。

### (2) V(X+C)=V(X)
確率変数に定数を足した場合の分散は、元の確率変数の分散に等しくなる。

### (3) V(kX)=k^2V(X)　
確率変数を定数倍したものの分散は、元の確率変数の分散を定数の2乗倍したものになる。
本件において、もっとも重要な性質。
サイコロの出目で例えると、次の通りに証明できる。

　(1×2-3.5×2)^2/6+(2×2-3.5×2)^2/6+(3×2-3.5×2)^2/6+(4×2-3.5×2)^2/6+(5×2-3.5×2)^2/6+(6×2-3.5×2)^2/6
　= 1/6{25+9+1+1+9+25}
　= 70/6
　= 17.5/6×2^2

### (4) V(X+Y)=V(X)+V(Y)（XとYが独立である場合）　
独立な確率変数について、確率変数の和の分散は、それぞれの確率変数の分散の和に等しくなる。

## ３．標本誤差の証明
サンプル xi はそれぞれ独立に標本誤差が σ の分布に従うので、標本平均の分散は次のとおりである。
　V(1/n{X1+...+Xn})
　= 1/n^2(V(X1)+...V(Xn))
　= nσ^2/n^2 ・・・分散（標本誤差^2）をn回行う⇒nσ^2
　= σ^2/n
　= σ/√n

## 参考
https://mathwords.net/hyouzyungosa
https://bellcurve.jp/statistics/course/6716.html
https://bellcurve.jp/statistics/course/6718.html
vim/viの終了時にエラー

vim/viコマンドを使用して、ファイル編集し閉じようとした所にエラーが発生しました。
こちらは、私がよく遭遇したエラーについて簡単な対処法を説明します。

# エラー
viでファイルを編集した後、
ニュートラルモードにし「:q」を入力した所
こちらのエラーが出ました。
```
no write since last change (add to override)
```
# 対処法
ファイルを編集している場合は、ファイルを保存するか、保存しないまま閉じなければいけません。

・保存して閉じる場合　「:wq」
・保存しないで閉じる場合　「:q!」
ログ調査におけるtailコマンドについて

先日ログの調査をするときにtailコマンドを使用した。
そもそもtailコマンドが何なのかわからなかったので、自分用に少し調べてまとめました。
## tailコマンドとは？
テキストファイルの最後の数行を表示することができるコマンド。
```
tail ファイル名
```
 で使用する。
ちなみにファイルの最初の数行を表示する場合は「head」を使う。

## tailコマンドのオプション「-f」について
### 「-f」：ファイルの追記を監視する。
```
tail -f logfile
```
ログを流すときに、この-fオプションを使用した。
ファイルの追記を監視して、ファイルに追記があったらその部分を表示してくれる。
Ctrl+Cで終了できる。

## grepでの抽出
本番環境で上記の「-f」コマンドでログを流すともの凄い勢いでログが流れるので追うことができない。
そんなときにgrepコマンドを使うと監視したいキーワードで抽出ができる。
```
tail -f logfile | grep "keyword"
```
こうすると"keyword"という文字列が含まれる行だけが出力されるようになる。
絞り込んだ内容に``keyword2``が含まれる行を除外したい場合は以下のようにする。
```
tail -f logfile | grep "keyword" | grep -v "keyword2" 
```
また、grepを使用するとバッファリングしてしまうので、リアルタイムではなくなりバッファが一定量になるまで出力されない。
そんなときは、grepに``--line-buffered``のオプションをつけることでバッファリングしなくなる。
GASでWEBサイトの公開

# 始めに
日々の勤怠をスプレッドシートに記録するためにアプリを作成しようと思ったのがきっかけです。
自分用メモとして残せればと思い投稿していきます。。。

# コード.gs
コード.gsの中身を下記の内容に書き換えます。

```javascript:
function doGet(request) {
    return HtmlService.createTemplateFromFile('index').evaluate();
}
```

# 表示するためのHTMLファイルを作成

左上にある+マークをクリックして「HTML」を選択します。ファイル名をindexとします。

![GAS_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2596854/34f6dec5-b764-62d3-981f-a1ab3dee7e12.png)

作成したindex.htmlファイルの中身を修正していきます。今回は「Hello World!」を表示していきます。下記のコードを参考にh1タグの部分を追加してください。

```html:
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <h1>Hello World!</h1>
  </body>
</html>
```


# サイトの公開
webサイトとして公開してみましょう。

![GAS_1_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2596854/32a9b9d7-48a4-87b5-7e7c-cb932e3644ee.png)

右上にある「デプロイ」→「新しいデプロイ」の順にクリックします。

![GAS_2_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2596854/cb37ac45-6cd2-8b08-12f7-dbc8d1405f6d.png)

アクセスできるユーザーを選択して右下のデプロイをクリックします。

![GAS_3_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2596854/29f7d593-e7fe-48de-a412-4c753c2e0e76.png)

URLが表示されていると思うので、URLをコピーしてブラウザで開くと先ほど作成したindex.htmlの内容が表示されていると思います。
ひと言学習メモ２：クラス、フィールド、メソッド

ひと言：
最も基本的な図式↓　（//コメントに記入）
![2022-03-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2533051/356978e8-8c83-f874-4dae-d13412b3616e.png)

自己流解釈：
〇クラス
classとくればクラス(;'∀')

※ちゃんとした定義としては「設計図」のようなものでしょうか[^1]。クラスの中に色々と入れる。
[^1]:『スッキリわかるJava入門』p.302

〇フィールド
クラスの中に変数宣言/変数を定義するところ。

〇メソッド
具体的なやり方を記入するところ。

※また、図の中は厳密に言うとMainメソッドである。

その他：
〇インターフェースは抽象的なクラス（具体的な処理/実装を持たない）ということも一応読んだ[^2]が、実践したことなく、まだ充分に理解できてないと思うため、現段階ではアウトプットしないことにした。
[^2]:『2週間でJava SE Bronzeの基礎が学べる本』p.436


〇フィールドはクラスの中で書かれた変数であって、メソッドの中に書かれた変数はローカル変数といい、フィールドと違う。[^3]

[^3]:https://bituse.info/java/14#:~:text=%E3%83%A1%E3%83%B3%E3%83%90%E3%83%BC%E5%A4%89%E6%95%B0%E3%81%A8%E3%81%AF%E3%82%AF%E3%83%A9%E3%82%B9,%E3%82%8B%E5%A4%89%E6%95%B0%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A7%E3%81%99%E3%80%82
スプレッドシートからLineへ通知を送る

○LineNotifyの公式サイトはこちら
https://notify-bot.line.me/ja/

初めにLineNotifyを友達追加しておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633008/0cc8b25e-2b84-146a-08e9-35637183552f.png)


LineNotifyを含めたグループを作成する
※このグループに通知がいきます
※自分以外のメンバーを追加してもOK
![スクリーンショット 2022-03-13 22.45.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633008/7d81c560-55da-e016-a371-8859626233ea.png)

公式サイトへアクセス後マイページを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633008/b8e0a7f1-6d16-fc2a-64fe-8b0df086ac75.png)

トークンを発行する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633008/1cb01620-c248-4f69-6135-35bcbf6234af.png)

名前と通知するグループを設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633008/cc21c046-b112-385b-4369-5e5e99f1d1dd.png)

トークンを忘れないようにメモしておく
![スクリーンショット 2022-03-13 22.14.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633008/6367d996-6947-3050-f10e-a72ca59d230b.png)



GASで以下のようなプログラムを作成する

```
//IDはhttps://docs.google.com/spreadsheets/d/●●/edit#gid=111111の●●の部分
const spreadsheet = SpreadsheetApp.openById("●●");
const sheet = spreadsheet.getSheetByName("シート名");

//取得した情報をラインへ通知する
var LINE_NOTIFY_TOKEN = "先ほど発行したトークンID";
var LINE_NOTIFY_API = "https://notify-api.line.me/api/notify";
function sendLine(){
  var msg,response;
    //送りたいメッセージ
    msg = sheet.getRange("D3").getValue();
    response = UrlFetchApp.fetch(LINE_NOTIFY_API, {
      "method": "post",
      "headers": {
        "Authorization": "Bearer " + LINE_NOTIFY_TOKEN
      },
      "payload": {
        "message": msg + user
      }
    });  
}
```

これでスクリプトが実行されるたびにLINEへ通知がいきます
※LineNotifyで設定された名前で届きます
![スクリーンショット 2022-03-13 22.38.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633008/db6dbe46-71c9-e0cc-2fa7-78c0561c45b2.png)
[Unity C# MLAgents] OOO does not exist in the current contextとかno suitable method found to overrideとか

# 発生した問題
UnityでMLAgentを自作のゲームに適用させようとしていたのですが、Agentのスクリプトにおいて
`OOO does not exist in the current context`とか`no suitable method found to override`などのエラーが大量に出てきました。

# 原因

原因は、Agent.csというスクリプトを自分で作っていたため、MLAgentのAgentクラスではなくAgent.cs内のAgentクラスを継承しようとしていたからでした。

# ...
考えればわかると思うんですが、エラーメッセージで検索したりバージョンのせいにしているうちに数時間とかして本当に悲しくなったので書き残しておきます。
プロパティとしてのクラス(Table Per Type編) 1

# 前回までのおさらいと改良
前回では静的メソッドとしての”プロパティとしてのクラス”のgetterとsetterを定義した。
これを汎化拡張メソッドとして書き直した。
```C#:ClassAsProperty.cs
namespace ClassAsProperty
{
    public static class ClassAsPropertyMethodBase
    {

        public static T? GetmethodT<T, T2>(this T2 TargetPoperty) where T : struct where T2 : ICompornentClass<T>
        {
            return TargetPoperty?.Value;
        }

        public static void SetmethodT<T, T2>(this T2 TargetProperty, T value) where T : struct where T2 : ICompornentClass<T>, new()
        {
            if (TargetProperty is null)
            { TargetProperty = new T2(); }
            TargetProperty.Value = value;
        }
    }
}
```
 ICompornentClass\<T\>の中身はこちら
```C#: ICompornentClass.cs

    public interface ICompornentClass<T> where T : struct
    {
        public int ID { get; set; }
        public T Value { get; set; }

    }
```
まず準備はここまで、何をしたかというとICompornetClassを継承したクラスは
GetMethodTとSetMethodTをジェネリックメソッドとして呼び出せるように定義しました。
# 応用：期限切れ管理クラス
まずはOne to Oneの関係性を念頭に置いた応用として期限日の定義を行います。
Compornentクラスのインターフェイス、Compositeクラスのインターフェイスと実装を以下に示します。
```C#:Inpriment of Compornent
    public class ExpireDayCompornent<T>: ICompornentClass<DateTime> where T : AbstractExpiredayBaseClass<T>
    {
        public ExpireDayCompornent() { Value = System.DateTime.Now; }
        public ExpireDayCompornent(DateTime value) { Value = value; }
        public int ID { get; set; }
        public DateTime Value { get; set; }
        public T ExpiredComposteNavigation { get; set; }
    }
```
上記のジェネリックインターフェイスを用いてCompornentクラスを実装する。
```C#:Interface of Composite
    public interface IExpireDayConpositeClass
    {
        public int ID { get; set; }
        public DateTime CreatedDateTime { get; set; }
        public DateTime? ExpiredDateTime();
        public void ExpiredDateTime(DateTime value);
    }
```
Compositeクラスのインターフェイスを実装しておく。
単に自動実装実装プロパティにしたかったがnullableが問題になったのでオーバーロードで対応した。
これは後でFluent APIでの実装でかかわってくる。
```C#:ABC of Composite
    public abstract class AbstractExpiredayBaseClass<T>: IExpireDayConpositeClass where T : AbstractExpiredayBaseClass<T>
    {
        public int ID {get; set;}
        public DateTime CreatedDateTime { get; set; }
        private ExpireDayCompornent<AbstractExpiredayBaseClass<T>> ExpireDayCompornent { get; set; }
        public DateTime? ExpiredDateTime() => ExpireDayCompornent.GetmethodT<DateTime, ExpireDayCompornent<AbstractExpiredayBaseClass<T>>>();
        public void ExpiredDateTime(DateTime value) => ExpireDayCompornent.SetmethodT<DateTime, ExpireDayCompornent<AbstractExpiredayBaseClass<T>>>(value);
    }
```
これがその実装である。このアブストラクトクラスが継承され実装された後に
自己参照ジェネリックで定義可能である。

# 独自のFluent API実装に向けて
ところで、このクラスのモデルビルダーを実装すればうまく行くけど
何を返せばいいのか迷うと思うが多分これだ
https://docs.microsoft.com/en-us/dotnet/api/system.data.entity.infrastructure.dbentityentry-1?view=entity-framework-6.2.0
```C#:Entity
 public System.Data.Entity.Infrastructure.DbEntityEntry<TEntity> Entry<TEntity> (TEntity entity) where TEntity : class;
```
このDbEntityEntry<TEntity>を返すジェネリック拡張メソッドにしておけば一発でコンテキスト定義可能なはず。
Windows環境のPythonで大語彙連続音声認識エンジン Julius を使う方法

# Juliusの準備
### Juliusのダウンロード
Juliusのダウンロードは[**こちら**](https://github.com/julius-speech/julius/releases)から（今回は julius-4.6-win32bin.zip をダウンロード）

Cドライブの直下に「Julius」というフォルダを作成する。
ダウンロードしたファイルの展開後、C:/Julius/ にコピーする。

### 音声認識パッケージのダウンロード
音声認識パッケージのダウンロードは[**こちら**](https://julius.osdn.jp/index.php?q=dictation-kit.html)から（今回は dictation-kit-4.5 をダウンロード）

Juliusと同様にダウンロードしたファイルの展開後、C:/Julius/ にコピーする。

# 音声ファイルの形式を変換
Juliusを使うためには、音声ファイルを以下の形式に変換しておく必要があります。
- チャンネル数：1チャンネル（モノラル）
- サンプルレート：16000 Hz 
- ファイル形式：.wavファイル、ヘッダなしRAWファイル

**形式の変換方法**は[前回の記事（PythonでFFmpegを使う方法 - Juliusの使用に向けて - ）](https://qiita.com/phi934/items/ef306ec2b83b6e060f0e)を参照

# PythonでJuliusを実行
ソースコードを以下に載せております。
```julius.py
import subprocess

# 日本語のパスはエラーがでる
julius      = "C:/Julius/julius-4.6-win32bin/bin/julius.exe"
main        = "C:/Julius/dictation-kit-4.5/main.jconf"
am_dnn      = "C:/Julius/dictation-kit-4.5/am-dnn.jconf"
julius_dnn  = "C:/Julius/dictation-kit-4.5/julius.dnnconf"

input_audio_file  = "input.wav"

args = [julius, "-C", main, "-C", am_dnn, "-dnnconf", julius_dnn, "-input", "rawfile", "-cutsilence"]

p = subprocess.run(args, stdout=subprocess.PIPE, input=input_audio_file, text=True)
print(p.stdout)
output = p.stdout.split("### read waveform input")[1].split("\n\n")
for i in output:
    if "sentence1:" not in i:
        continue
    sentence = i.split("sentence1:")[1].split("\n")[0].replace(" ", "")
    print(sentence)
```
以下の結果が出力されればOK。
```:結果
おはようございます。
今日は晴れです。
```
以上、Windows環境のPythonでJuliusを使う方法でした。

# ソースコード
今回使用したソースコード、音声ファイルは[**こちら**](https://github.com/phiniki/Julius/tree/main/Julius)にあります。

# 参考にしたページ
https://www.tdi.co.jp/miso/julius-voice-recognition
ボタンの角を丸くする方法

ボタンの角を丸めたいという時ありますよね。
丸める方法が少し複雑だったのでまとめておきます。

# 完成画像
ここでは左下と右上の角を丸くしていきます。
![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1518643/f7787934-b457-8636-9c4c-b0643c834ccd.png)

# 手順

### **①ファイルを作る**
Android > app > res > valuesに、shape.xmlファイルを作る必要があります。
このファイルの中に、角の情報を入力していきます。

### **②角の情報を入力する**
それぞれの角の角度を入力します。
今回はマテリアルデザインのボタンを使用しているので、
parentは「ShapeAppearance.MaterialComponents」になっています。
それぞれの状況に合わせてparentは変更してください。
```shape.xml
<resources>

    <style name="ShapeAppearance.Sunflower.Button.Add" parent="ShapeAppearance.MaterialComponents">
        <item name="cornerFamily">rounded</item>

        <item name="cornerSizeTopLeft">0dp</item>
        <item name="cornerSizeTopRight">@dimen/button_corner_radius</item>
        <item name="cornerSizeBottomRight">0dp</item>
        <item name="cornerSizeBottomLeft">@dimen/button_corner_radius</item>
    </style>

    <dimen name="button_corner_radius">12dp</dimen>


</resources>
```
# レイアウトに追加する

```
app:shapeAppearance="@style/ShapeAppearance.Sunflower.Button.Add"/>
```
FragmentからActivityへのバック処理



#  早速



戻りたい処理をしたいところ（バックボタンのListener等）に
```
requireActivity().finish()
```
もしくは、
```
activity.finish()
```

を追加しましょう


#  終わりに
覚えることが日々増えていく中、こうした初歩的なことは逆に忘れがちなので
自分の備忘録として残しました
完全に自分の身につくまで何度も見返していこうと思います
また、始めたての方などのためになれば幸いです
学生がセキュリティ系の長期インターンに参加する方法をまとめてみた

# 書こうと思ったきっかけ
はじめまして。私はセキュリティの研究を行っている修士１年の学生です。
長期インターンとしてwebアプリケーションの脆弱性診断を行っています。

さて、最近Twitterで「セキュリティ系の(長期)インターン」ないかなぁというぼやきを見かけました。
わかります。検索しても出てこないんですよね。そもそもセキュリティ業務自体、金銭的・人材的に学生を取れる余裕が少ないんかなと思ってます。
でも、せっかく学生の頃からセキュリティに興味持っているのに、インターンとかアルバイトで学びながらお金がもらえる環境がないのはもったいないと思いませんか？
セキュリティに興味を持っている学生へ少しでも助けになるように、実体験や聞いた話を踏まえて、**学生がセキュリティ系の長期インターン**に参加する方法を書き連ねます。

(実体験や話を聞いたことがある方は、後進の学生のためにも教えてくれるとうれしいですm(__)m)

# 目次
・インターンの種類
　　①診断
　　②開発
　　③研究
　　④翻訳
　　⑤事務
・インターンの見つけ方
　　1.ネットで検索
　　2.学校の紹介、OBの紹介
　　3.CTFなどで活躍
　　4.イベントで知り合う・声をかける
　　5.内定者インターン

# 本題に入る前にインターンの種類
セキュリティ系のインターンって言っても、色々あります。だいたい以下の5つに分けられると思います。
### ①診断
　セキュリティ系のインターンて言われて想像しやすいのがこれ。webアプリケーションの診断が多いと思います。

### ②開発
　いわゆるプログラマー。セキュリティ系に分類していいのかわかりませんが、ソフトウェア開発あってのセキュリティなので、ある意味学生のうちに経験しておくべきかもしれません。

### ③研究
　お金を貰いながら、セキュリティの研究が出来るという神の様な仕事。研究のインターンは少ないけど、定期的に募集してたりします。『セキュリティ』にこだわらないとそこそこあります。
　
### ④翻訳
　海外製品情報の翻訳などの仕事。セキュリティは海外の製品や技術が多いので、こういう仕事はたまに見かけます。技術英語につよくなるし、製品などの知識も身につくのでアリだと思います。

### ⑤事務
　よく知らないです。セキュリティ業務を間近で見れるのが魅力かな？仕事を続けていれば、診断・開発業務なども関わらせてもらえるかも。



# インターンの見つけ方
本題です。簡単そうな順に書いていきます。
### 1.ネットで探す
ググると何個かはヒットする。けど、よく見ると「学生不可」とか書いてあったりする。見つけるのはなかなか難しい。
どうしても見つけたいなら、『セキュリティ』というキーワードにこだわらないのがポイントだと思います。(開発の仕事を探す、数理系の研究の仕事を探すなど)

ネットで検索して出てくるものをいくつか紹介します。

「[JNSAインターンシップ](https://www.jnsa.org/internship/)」：色んな種類のインターンがあります。就活の一環としての短期インターンが多いけど、長期インターンもたまに募集が来る。
「[サイボウズ・ラボユース](https://labs.cybozu.co.jp/youth/requirements.html)」：研究のインターン。個人のソフトウェア開発に対して奨励金を出してくれる。セキュリティ系のツールの開発をしてる人も結構いる。
「[日本IBM](https://en.wizbii.com/company/ibm/job/research-tokyo-student-intern-ibm)」：研究のインターン。AIに関する研究を広くやっているらしい。セキュリティもキーワードとして挙がっていました。

他にも気になった会社があれば、TwitterのDMなど問い合わせてみてもいいかもしれません。

### 2.学校の紹介、OBの紹介
 セキュリティ系の研究をしていれば、先生の紹介や研究室のOBの紹介で運がよければ回ってくるかも。
僕は研究室OBの方の勤めている企業でホワイトハッカーを増やしたい(あわよくば就職してほしい)とのことで、webアプリ診断の仕事にありつけました。
もし、研究室の先生やOBにセキュリティ系の仕事をしている方がいれば、聞いてみると案外回ってくるかも。

### 3.CTFなどで活躍
　CTFで活躍すると、主催者の方から誘ってもらえることがあるようです。僕の友人もそれがきっかけでペネトレーションテストの業務に携わっています。

### 4.イベントで知り合う・声をかける
　上の3番に通じるものがありますが、セキュリティキャンプなどイベントで知り合った企業の方がいたら声をかけてみるのもいいと思います。
ネットで広く募集はできないけど、ある程度実力があることが分かっているなら、採用してくれるという場合もあるかもしれません。
こういうときは実績がモノを言うと思います。(CTFの入賞経験や開発経験など)
また、イベント参加者向けにインターン情報が発信されることもあります。

いくつかセキュリティ系のイベントを紹介しておきます。

「[セキュリティ・キャンプ](https://www.security-camp.or.jp/)」：学生を対象としたセキュリティの勉強を行うイベント。講師のレベルも高く、セキュリティに限らず広く技術を学べます。
「[SecHack365](https://sechack365.nict.go.jp/)」：学生が集まり、一年を通してセキュリティの研究や開発を行うイベント。
「勉強会・LT会」：テーマはさまざま。[connpass](https://connpass.com/)とかで探したら見つかります。
「会議・シンポジウム」：[CODE BLUE](https://codeblue.jp/2021/)などでは企業と学生の交流会の機会もあります。
「短期インターン」：短期インターン自体はそこそこあるので、続けて長期インターンとして雇ってもらえないか打診してみるのも良いと思います。

### 5.内定者インターン
既に就職がきまっているなら、会社の方に聞いてみるとOKしてもらえるかも。

### 番外編
記事の趣旨とは少し外れてしまいますが、今の時代なら学生だろうが個人で稼ぐこともできます。
① youtubeに動画を挙げる
② ブログを書く
③ CTFの賞金を稼ぐ
④ バグバウンティ
①,②はセキュリティ界隈の人口が少ないのでまだ難しいかもしれません。一般受けする内容にするのも手ですね。

# まとめ
セキュリティ系の長期インターンが出来るのは現状、運要素が大きいと思います。それでも、やりたいという方は①積極的に発信して探す②実績を身に着けるのどちらかが必要になってくると思います。
今後、増えていくといいなぁと個人的には願っています。
読んでくださりありがとうございました。ご意見・体験談などお待ちしています。
Javaの::ってなんだ?

## こんな意味らしい???
メソッド参照の構文
|対象            |構文               |
|---------------|-------------------|
|クラスメソッド     |クラス名::メソッド名     |
|インスタンスメソッド|オブジェクト変数::メソッド名|
|コンストラクター   |クラス名::new         |

## メソッド参照の基本
MethodRefUse.java
```
package com.company;

public class MethodRefUse {
    // 配列の要素の処理方法をメソッド参照で受け取れるように
    public void walkArray(String[] data, Output output) {
        for (var value : data) {
            output.print(value);
        }
    }

    // Output型に対応したメソッド(渡された文字列をブラケットでくくる)
    static void addQuote(String value) {
        System.out.printf("[%s]\n", value);
    }
}

```
Output.java
```
// インターフェイスのファイル
package com.company;

// String型の引数を受け取り、戻り値はvoid型であるメソッド型
@FunctionalInterface
public interface Output {
    void print(String str);
}

```
Main.java
```
package com.company;

public class Main {
    public static void main(String[] args) {
       var data = new String[] { "春はあけぼの", "夏は夜", "秋は夕暮れ" };
       var u = new MethodRefUse();
       u.walkArray(data, MethodRefUse::addQuote);
    }
}


```
walkArrayメソッドに対して、配列要素を処理するコードだけを切り出して、あとから引き渡せるようにした例です。

## メソッドの差し替えも可能
**インターフェイスのファイルのOutput.javaは削除されるとエラー出るので消さないように!!!**
新たにファイルを追加したディレクトリの構造↓
```
.
├── SampleJava.iml
├── data.txt
├── out
│   └── production
│       └── SampleJava
│           └── com
│               └── company
│                   ├── Counter.class
│                   ├── Main.class
│                   ├── MethodRefUse.class
│                   └── Output.class
└── src
    └── com
        └── company
            ├── Counter.java
            ├── Main.java
            ├── MethodRefUse.java
            └── Output.java

```
次は、walkArrayメソッドを使って、配列内の文字列をカウントする例です。
Counter.java
```
package com.company;
// 文字列をカウントするためのCounterクラス
public class Counter {
    private int result = 0;

    public int getResult() {
        return this.result;
    }

    public void addLength(String value) {
        this.result += value.length();
    }
}

```
MethodRefUse.java
```
package com.company;

public class MethodRefUse {
    // 配列の要素の処理方法をメソッド参照で受け取れるように
    public void walkArray(String[] data, Output output) {
        for (var value : data) {
            output.print(value);
        }
    }

    // Output型に対応したメソッド(渡された文字列をブラケットでくくる)
    static void addQuote(String value) {
        System.out.printf("[%s]\n", value);
    }
}

```
Output.java
```
// インターフェイスのファイル
package com.company;

// String型の引数を受け取り、戻り値はvoid型であるメソッド型
@FunctionalInterface
public interface Output {
    void print(String str);
}

```
Main.java
```
package com.company;

public class Main {
    public static void main(String[] args) {
       var data = new String[] { "春はあけぼの", "夏は夜", "秋は夕暮れ" };
       var u = new MethodRefUse();
       var c = new Counter();
       u.walkArray(data, c::addLength);
       System.out.println(c.getResult());
    }
}
```
実行結果
```
14
```
## 解説
CounterクラスのaddLengthメソッドは、引数valueの文字列をresultフィールドに足し込んでいるので、walkArrayメソッドはそれ全体として、配列に含まれる文字列の長さの合計を求めることになります。
ここで、おおもとのwalkArrayメソッドは一切書き換えていない点に注目してください。メソッド参照を利用することで、枠組みとなる機能（ここでは配列を順に走査する部分）だけを実装しておき、詳細な機能はメソッドの利用者が決める---より汎用性の高いメソッドを設計できるようになります。
DockerでDatadogAgentを動かしているときに IMDSv2 に対応させる

```yaml
  dd-agent:
    container_name: dd-agent
    image: datadog/agent:7.33.1
    environment:
      - DD_API_KEY=${DD_API_KEY}
      - DD_TAGS=hogehoge
      - DD_EC2_PREFER_IMDSV2=true   # これを追加してコンテナ再起動
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /proc/:/host/proc/:ro
      - /sys/fs/cgroup/:/host/sys/fs/cgroup:ro
```

## なんでこんなことを書いているのか

https://github.com/DataDog/datadog-agent/blob/main/pkg/config/config_template.yaml

通常のagentの場合は datadog.yaml に `ec2_prefer_imdsv2: true` を設定せよというのはググればすぐ出てくるのですが、コンテナの場合の記載方法が書いてあるのが config_template くらいしかなかったので。
令和にPICでLチカに成功しました。MacのBootCampでWin10でMPLAB IDE

今年の目標は低レイヤーから攻めることです。
前回CPUを自作したので、少しレイヤーを上がってアセンブラを触ってみたいな〜なにかいい環境はないかな〜マイコンとかどうかな〜ということでやってみました。
Arduinoでいいんじゃない？という声が聞こえてきそうですが、低レイヤーを生で触っている実感が欲しかったので直接アセンブラが書ける＆情報が多そう、ということでPICを選びました。

しかし、書籍もネットも如何せん情報が古い・・・
参考にしたのは「やさしいPICマイコンプログラミング入門」https://www.amazon.co.jp/やさしいPICマイコンプログラミング入門-高橋-隆雄/dp/4798018333/ref=sr_1_1?__mk_ja_JP=カタカナ&keywords=「やさしいPICマイコンプログラミング入門」&qid=1647177916&sr=8-1 という2008年の本なのですが、環境構築含めていろいろと躓いたので同じ思いを持つ人のために記録として残しておこうと思います。

ライターはこれでいけましたhttps://www.amazon.co.jp/Yiteng-PICKIT3-プログラマ-シミュレータ-プログラミングキット/dp/B07PVB3NB8/ref=pd_day0fbt_img_2/357-7189320-3637253?pd_rd_w=E5sFX&pf_rd_p=e6abce55-fc6f-4462-923b-b8a729351d49&pf_rd_r=14BQ3KNN3M2QV80Z7W48&pd_rd_r=51795d16-124b-4572-80fb-fe93cb7a70bd&pd_rd_wg=coU7a&pd_rd_i=B07PVB3NB8&psc=1

ライターから電源を供給してやらないとICが認識されずにエラーになったので最初はやっぱり互換品じゃダメか、とがっかりしましたが大丈夫でした。

開発環境としてはMPLAB IDE（Xじゃないほう）を選択しました。なぜなら本にそう書かれていたので。

バージョンは一番古いものにしないとPickit3が使えないようでした。公式のアーカイブから落とせました。

なんとかIDEからPickitを認識させていざコーディング、をしてみたのですが、どうも10F200だとアセンブラ(機械語に変換する方)がMPASMを選択できていないっぽい。インクルードにも失敗するし早々と諦めました。

続いて12F629で試したところこちらはちゃんとMPASMでプロジェクトが作れてビルドも通りました。

実行しようとすると「インナークロックとMCLREがどっちもONだとまずいよ」という警告が出ましたが当てはまらないので無視して実行。

そしてできました。
![pn710-oj18j.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2380862/ff4b868f-c29c-ab50-6f0a-2c87859d4a0e.gif)

人生初アセンブラで動くものを作りました。

アセンブラでなにかしら動くものを作る環境って整えるのが難しいんだなあということを思い知った2022年でした。

今後はPICをもう少し続けて、dsPICでイケてるギターエフェクターを作りたいと考えています。
[Vue.js] カンバン管理ツール　3．ドラッグアンドドロップでのチケットの移動

## はじめに
本記事は以下で投稿した記事の続きです。
https://qiita.com/khata0131/items/c7c887ff3ea405e2aa85

前記事では、カンバンのチケット登録処理を実装し、ボタンによるステータス移動も実装しました。
本記事ではステータス移動をドラッグアンドドロップで実施できるように改修を加えます。

## 1．Vue.Draggable
ドラッグアンドドロップの機能を実装するために、Vue.Draggableというコンポーネントライブラリを利用します。
参考：https://www.kabanoki.net/1712/

以下、CDNにてライブラリを取得します。
```html:index.html
  <script src="https://cdn.jsdelivr.net/npm/sortablejs@1.8.4/Sortable.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.23.2/vuedraggable.umd.min.js"></script>
```

## 2. コンポーネントの作成

取得したVue.Draggableのライブラリを呼び出します。
```js:main.js
const draggable = window['vuedraggable'];
```

使用しているVueインスタンスに、呼び出したライブラリからコンポーネントを作成します。

```js:main.js
new Vue({
  el: '#app',
  components: {
    'draggable': draggable,
  },
```

## 3. ドラッグアンドドロップの適用
ドラッグアンドドロップを適用したいエリアの親タグに対して、draggablelコンポーネントを適用させます。
まず、同じストーリー・同じステータスでチケットの移動ができるように、以下のキャプチャの青枠部分に対して適用させます。

![draggable-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428605/a35080a7-78ad-aab9-ec7a-01253d349c3c.png)

tdタグにコンポーネントを適用していますが、コンポーネントはデフォルトでdivタグになってしまうため、
明示的にtag属性にてtdを指定しています。

```js:main.js
Vue.component('ticket-col-template', {
  props: ['story', 'status', 'statusindex'],
  template: '\
    <td is="draggable" tag="td">\
      <li is="ticket-template"\
        v-for="(ticket,index) in status.list"\
        v-bind:key="index"\
        v-bind:story="story"\
        v-bind:ticket="ticket"\
        v-bind:tindex="index"\
        v-bind:statusindex="statusindex"\
        class="ticket-li">\
      </li>\
    </td>\
  ',
})
```


以下のように同じストーリー・同じステータス内ではドラッグアンドドロップによるチケットの移動が可能になりました。
しかし、別ストーリー・別ステータスへの移動は、まだできない状態です。

![draggable-2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428605/4e5f767e-8ef7-7fd1-8eea-57832cbed343.gif)

## 4. ドラッグアンドドロップのエリアのグループ化
draggableコンポーネントは、グループ属性を設定することでドラッグアンドドロップできるエリアを複数設定することができます。
そのため、チケットエリアのテンプレートであるticket-col-templateを同じグループに設定することで、
別ストーリー・別ステータスへのドラッグアンドドロップによるチケットの移動が可能になります。
今回はグループ名をticketsとして、group属性を設定します。

```html:index.html
<td is="draggable" tag="td" group="tickets">
```

また、ストーリー（行）の入れ替えも実装したいため、
ストーリーを設定しているtrタグの親であるtbodyタグにも同様にdraggableの設定をします。

```html:index.html
<tbody is="draggable" tag="tbody">
  <tr v-for="(story,index) in table" v-bind:key="index">
```

チケットは同じグループに設定した、各ストーリー・各ステータスに対してドラッグアンドドロップによる移動が可能になり、
ストーリーもチケットの状態を保持したまま順序の入れ替えが可能になりました。

![draggable-3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428605/77f2ff15-8190-dd73-c62c-8ef34d4fba39.gif)

## 終わりに
今回はドラッグアンドドロップの機能を実装するにあたりライブラリから取得しましたが、
自分で一からコーディングするよりも圧倒的に早い時間で実装することができました。
また、既存のプログラムへの影響もほとんどなかったので、ライブラリの選び方も重要だと感じました。

ドラッグアンドドロップの実装により、SPAの強みを生かしたページ構成になりモチベーションが向上したので、
他の機能の実装も続けていきたいと思います。
AWS認定クラウドプラクティショナー　試験後の振り返りメモ

# 記事の目的
2022年3月13日にAWS認定クラウドプラクティショナーに合格したので、
反省も兼ねて記事にまとめました。
この記事では、学習方法や失敗などを紹介させていただきます。
（1回目は失敗、2回目の挑戦で合格しました。）
# AWS認定クラウドプラクティショナーとは？
AWS認定資格の中でも基本的な内容を対象にした認定資格になります。
出題傾向は広く・浅い印象です。

https://aws.amazon.com/jp/certification/certified-cloud-practitioner/

> この資格は、組織がクラウドイニシアチブを実装するための重要な知識を持つ人材を特定して育成するのに役立ちます。AWS Certified Cloud Practitioner を取得することで、クラウドへの理解と基礎的な AWS の知識が認定されます。
# 教材
## 問題集

https://www.udemy.com/course/aws-4260/

## 参考書

https://www.udemy.com/course/ok-aws-e/

https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC-%E5%B1%B1%E4%B8%8B-%E5%85%89%E6%B4%8B/dp/4797397403/ref=sr_1_1?crid=2PJAGV72Q746B&keywords=aws+%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%BC&qid=1647174260&sprefix=aws+%2Caps%2C268&sr=8-1

https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/

# 学習方法
1. 問題集演習
2. 問題集演習の解説を確認
3. 再度、問題集演習
4. 1-3でも不明な部分・理解が乏しい内容を参考書・公式ドキュメントにて学習
（厳密には違いますが、）アクティブリコール勉強法で学習。
# 「やってよかった」と思ったこと
## 学習内容を記録する
極めて当然のことですが、学習内容を記録することはとても大切だと思います。
自分はGithubにて学習用のリポジトリを作成して、issueに学習メモなどを記録していました。
自然と時系列順に学習メモがストックされるので、
自分の考えや学習内容を振り返ることができました。
## 問題集を中心に取り組む
ひたすら問題集を繰り返すのが簡単で、効果的だと思います。
（私は、基礎レベルを約20回、応用レベルを約10回程度繰り返しています。）
# 「やればよかった」と思うこと
## 導入事例を調べる
1回目のAWS認定クラウドプラクティショナー試験で失敗して反省したことが
「サービスの導入事例を把握すること」です。
クラウドプラクティショナー試験では、クラウド技術・AWS・各サービスの概要などの
問題もありますが、「ある会社では〜を検討である、どのようなサービスが適切か？」
というようなサービスの導入事例も出題されます。
（1回目の試験でこの導入事例がボロボロでした。）
AWS公式にて導入事例を紹介しているので、軽くで良いので確認しましょう。

https://aws.amazon.com/jp/solutions/case-studies/?customer-references-cards.sort-by=item.additionalFields.sortDate&customer-references-cards.sort-order=desc&awsf.customer-references-location=*all&awsf.customer-references-segment=*all&awsf.customer-references-industry=*all&awsf.customer-references-use-case=*all&awsf.customer-references-tech-category=*all

## 公式資料を活用する
AWSは公式の資料がとても充実しており、概要を把握する上でも、参考になります。
勉強目的でなくても、読み物としても面白いので、もっと活用すればよかったと思います。
上記のサービス別資料・導入事例が個人的にはおすすめです。
# 最後に
自分はIT業界未経験かつ、AWSもCloud9を軽く触った程度ですが、合格することができました。
AWS認定クラウドプラクティショナーの学習方法については、多くの記事などがあるので、併せて参考にしていただけると幸いです。
KH Coderのアンインストール方法

## 環境
+ Microsoft Windows 10.0.22000.318（21H2）
+ KH Coder 3.Beta.04

## 背景
通常、アプリのアンインストールは「コントロールパネル > プログラム > プログラムと機能」の「プログラムのアンインストールまたは変更」から行えるが、ここにKH Coderの名前は無く、アプリとして認識されていなかった。

## アンインストール手順
KH Coderと一緒にインストールされたマニュアル（khcoder_manual.pdf）より
> **А.12.4　KH Coder のアンインストール**
>
> KH Coder は Windows のレジストリを一切用いていない。したがって, KH Coder が不要になった場合には, 「kh_coder.exe」をはじめとするファイル群を削除するだけでアンインストールは完了する。おそらくは, KH Coder を解凍（Unzip）したフォルダごと削除するのが最も容易であろう。この点は Linux, Mac においても同様である。

つまり、**手動で KH Coder が入っているフォルダを削除**すれば、KH Coder 関連のデータはすべて削除されることになる。

:::note info
バージョンが `3.Beta.04` の場合フォルダ名は「khcoder3」
:::

### KH Coder の場所がわからない場合
KH Coder のショートカットを右クリック → ファイルの場所を開く
Azure Functionにおけるローカル環境とクラウド環境の環境変数の設定方法の違い


こんにちは。torippy1024です。
最近、Azureラボ環境をいじれる機会を得たため、今更ながらAzure Functionを操作してみました。
その際、ローカル環境とクラウド環境(Azure上)で環境変数の設定方法に違いがあったため、メモとして残しておきます。

# サンプルコード(Python)

例えば以下のように、ユーザー名を環境変数として取得する場合を考えます。
```python
import os 

user = os.environ.get("USER_NAME")
```

os.environ.get()で"USER_NAME"という名前の環境変数の値を取得している訳ですが、
この環境変数の指定方法が、ローカル環境とクラウド環境(Azure上)で異なっており、それぞれどう設定すればいいか最初わからなかったため、メモとして残しておきます。


# ローカル環境における環境変数の設定方法

ローカル環境では、ローカル端末上のlocal.settings.jsonで指定します。
階層としてトップレベルにあり、host.jsonやrequirements.txtと同じディレクトリ内にあります。

```json
{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=xxxxxxxxxxxx;AccountKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;EndpointSuffix=core.windows.net",
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "USER_NAME": "torippy1024"
  }
}
```

# クラウド環境(Azure上)における環境変数の設定方法

クラウド環境では、Azure Portal上のAzure Functionの画面で指定します。
関数アプリの画面の「設定」-「構成」を選択します。
「新しいアプリケーション設定」で環境変数を追加できます。

![20220313qiita1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684500/20c4ac87-0237-42c6-6101-2b6e94002d60.jpeg)


環境変数を追加/編集した後は必ず「保存」を押して変更内容を反映させましょう。
「保存」を押さないと変更内容は破棄されてしまいます。また、同時にアプリの再起動も行われるので注意しましょう。

# 今後の課題(独り言)
パスワードやアクセスキーを指定する際は、上記のような環境変数でなく、Azure Key Vaultを使うべきだと思います。
試してみたのですが、アクセスポリシーの設定方法がよくないのか、うまくいってません・・・・・。
こちらは解決したらまたメモとして書いておこうと思います。
ENI が削除できないときに見るところ (VPC起動のLambdaの古いバージョンが残っていませんか?)

ENIのDescriptionにLambdaで作られたと書いてあるので、Lambaを対象のVPCから外してみたけど、ENIが消せいないということがあります。
そういう場合はLambdaの古いバージョンが残っているのが原因であることがあります。

**Lambdaの古いバージョンを削除してみましょう。**

ENIはすぐには消えず、削除もできないですが、しばらくほっておくと消えます。

## なんでこんなこと書いているか

不要になったセキュリティグループがあったので消そうと思ったら利用しているENIがあるから消せないとのメッセージが…
対象のENIを消そうとしたらこれまた利用しているというので削除できませんでした。デタッチも強制デタッチもできませんでした。

ENIのDescriptionをみるとLambdaから作成されたようだったので、対象のLambdaの構成変更をしてVPCから外したのですが、やはりENIは削除できません。デタッチもできません。

同じような記事をググってみたのですが、なさそうだったので。
returnがないメソッドのテスト

・$this->expectOutputString(アウトプット)を用いる。

※$this->assertSame(アウトプット, メソッドの実行)ではない。

例）

コード
```
<?php

namespace BlackJackGameStep1;

class FirstDisplay
{
    public function __construct(private array $playerCards, private array $dealerCards, private int $firstDraw)
    {
    }
    public function display()
    {
        echo "ブラックジャックを開始します。" . PHP_EOL;
        for ($i = 0; $i <= ($this->firstDraw - 1); $i++) {
            echo "あなたの引いたカードは" . $this->playerCards[$i]["mark"] . "の" . $this->playerCards[$i]["number"] . "です。" . PHP_EOL;
        }
        echo "ディーラーの引いたカードは" . $this->dealerCards[0]["mark"] . "の" . $this->dealerCards[0]["number"] . "です。" . PHP_EOL;
        echo "ディーラーの引いた2枚目のカードはわかりません。" . PHP_EOL;
    }
}

```

テストコード
```
<?php

namespace BlackJackGameStep1\Tests;

use PHPUnit\Framework\TestCase;
use BlackJackGameStep1\FirstDisplay;

require_once(__DIR__ . '/../lib/FirstDisplay.php');

final class FirstDisplayTest extends TestCase
{
    public function testDisplay()
    {
        $playerCards = [];
        $playerCards[0] = [
            "card" => "d2",
            "mark" => "ダイヤ",
            "number" => "2",
            "rank" => 2,
        ];
        $playerCards[1] = [
            "card" => "c9",
            "mark" => "クラブ",
            "number" => "9",
            "rank" => 9,
        ];
        $dealerCards = [];
        $dealerCards[0] = [
            "card" => "s9",
            "mark" => "スペード",
            "number" => "9",
            "rank" => 9,
        ];
        $dealerCards[1] = [
            "card" => "hK",
            "mark" => "ハート",
            "number" => "K",
            "rank" => 10,
        ];
        $output = <<<EOD
ブラックジャックを開始します。
あなたの引いたカードはダイヤの2です。
あなたの引いたカードはクラブの9です。
ディーラーの引いたカードはスペードの9です。
ディーラーの引いた2枚目のカードはわかりません。

EOD;
        $this->expectOutputString($output);
        $firstDisplay = new FirstDisplay($playerCards, $dealerCards, 2);
        $firstDisplay->display();
    }
}

```
Next.js+Tailwindcssの環境構築

# やりたいこと
Next.js+Tailwindcssの環境構築

# 開発環境
Windows 10Pro

# 方法（2022/3/13時点）
-  Next.jsのプロジェクト作成
以下コマンド実行
```
npx create-next-app --typescript
```

プロジェクト名を入力して作成する
![tempsnip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742615/a5b31ba3-d7dd-e68e-3c74-6b73c98a18fc.png)

- Tailwindcssのインストール
以下コマンド実行

```
yarn add -D tailwindcss postcss autoprefixer
```

以下コマンド実行で`tailwind.config.js` と `postcss.config.js` を作成

```
npx tailwindcss init -p
```

- パスの設定を変更する
tailwind.config.jsを以下に変更

```tailwind.config.js
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

- globals.cssを変更する
globals.cssを以下に変更

```globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;

```

- index.jsを変更して確認する
index.jsを以下に変更

```index.js
export default function Home() {
  return (
    <h1 className="text-3xl font-bold underline">
      Hello world!
    </h1>
  )
}
```
確認できた
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742615/12ca0814-4ded-f3b5-e60c-b4d702512c3b.png)

# 注意事項
globals.cssの@tailwindがimportされない現象
windowsで環境構築を行ったが、`Unknown at rule @tailwind` となり、Tailwindcssの設定がうまくimportされなかった

### 解決策

VSCode拡張機能`PostCSS Language Support`を入れる

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742615/e1eae9db-e685-7c12-4aad-57020c1e59c5.png)


# 参考記事
https://tailwindcss.com/docs/guides/nextjs

https://qiita.com/masakinihirota/items/bd8c07aa54efad307588
SwiftUIとARKitでUSDZ表示アプリ

# 作ったもの
SwiftUIを使ったARKitアプリの情報があまりないので備忘録的に書いていきます。
作ったものはこんな感じ。

https://twitter.com/soh_mitian/status/1418527498057355267?s=20&t=wYxrdqoJOCt44SdHNzS-cw


## ソースコード
https://github.com/soh92/PlacementUSDZ

# プロジェクト作成
**Augmented Reality App** を選びます。
content Technologyは**RealityKit**
Interfaceは**SwiftUI**

![](https://storage.googleapis.com/zenn-user-upload/f2ae6fafcc8b-20220306.png)

新規フォルダを作成して、その中にUSDZファイルを入れます。

![](https://storage.googleapis.com/zenn-user-upload/669411df0f56-20220306.png)

Assets.xcassetsにサムネイルを入れます。

![](https://storage.googleapis.com/zenn-user-upload/68778c0f5b2b-20220306.png)



# コード概説

## ContentView
メインコンテンツ部分です。モデルの読み込みとARview, ButtonView, PickerViewを行います。

## ARViewContainer
CustomARViewを呼び出す構造体です。

## CustomARView
FocusEntityというサードパーティライブラリを呼び出す構造体です。FocusEntityはARViewにモデル設置場所を矩形で表示するライブラリです。FocusEntityだけでなく、ARWorldTrackingConfigurationもここで定義しています。

## ModelPickerView
USDZモデルを選択するScrollViewで構成された構造体です。

## PlacementButtonsView
モデルの設置、キャンセルボタンを定義した構造体です。

## Model.swift
Modelクラスを定義したファイルです。

# 状態の管理
ContentViewにおいて以下のコードで状態管理を定義しています。

```swift
@State private var isPlacementEnabled = false
@State private var selectedModel: Model?
@State private var modelConfirmedForPlacement: Model?
```

モデルを選択したらisPlacementEnabledがtrueになりPlacementButtonsViewが呼び出されます。
同時に、ModelPickerViewのself.selectedModel = self.models[index]により、どのモデルが選択されたかをselectedModelに定義します。
続いてmodelConfirmedForPlacementにselectedModelが定義され、modelEntityとなります。modelEntityはanchorEntityに.addChildされ、ARKitで検出された平面上にモデルが表示されます。

# 所感

RealityKitとARKit自体はそれほど難しいことはありませんが、SwiftUIと組み合わせた情報が少ないので苦労しました。
Javaのラムダ式とは?

## メソッド参照/ラムダ式
Java8では、メソッドも型の一種だそうです。メソッドそのものもまた、他の数値型や文字列型と同じく、別のメソッドの引数として渡すことができます。そして、メソッドを受け渡しするための構文が、メソッド参照であり、ラムダ式です。

## ラムダ式の基本
Main.java
```
package com.company;

public class Main {
    public static void main(String[] args) {
       var data = new String[] { "春はあけぼの", "夏は夜", "秋は夕暮れ" };
       var ml = new MethodLambda();
       ml.walkArray(data, (String value) -> {
           System.out.printf("[%s]\n", value); // Macでは\nと書かないと改行されない!、Windowsは¥n
       });
    }
}
```
MethodLambda.java
```
package com.company;

import java.util.function.Consumer;

public class MethodLambda {
    public void walkArray(String[] data, Consumer<String> output) {
        for (var value : data) {
            output.accept(value);
        }
    }
}

```

実行結果
```
[春はあけぼの]
[夏は夜]
[秋は夕暮れ]
```
## メソッド参照/ラムダ式を利用しない例
Main.java
```
package com.company;

public class Main {
    public static void main(String[] args) {
       var data = new String[] { "春はあけぼの", "夏は夜", "秋は夕暮れ" };
       var ml = new MethodLambda();
       ml.walkArray(data);
    }
}

```
MethodLambda.java
```
package com.company;

public class MethodLambda {
    public void walkArray(String[] data) {
        System.out.printf("ラムダ式を利用しない例\n");
        for (var value : data) {
            System.out.printf("[%s]\n", value);
        }
    }
}

```
実行結果
```
ラムダ式を利用しない例
[春はあけぼの]
[夏は夜]
[秋は夕暮れ]
```
ラムダ式を表すのは、以下の構文です。引数リストと本体ブロックを「->」でつなぎます。
```
(引数型 仮引数) -> {
  ...メソッドの本体...
}
```
ラムダ式によって名前がなくなっただけでなく、walkArrayメソッドを呼び出すためのコードに、メソッド定義を直接埋め込めるようになります（これが「名前が不要で、その機能だけが必要な場合といった意味です。）これによって、コードが短くなったのはもちろん、コードのまとまりがはっきりしたため、格段に読みやすくなりました。

walkArrayメソッドの引数型として指定されているConsumaerインターフェイスは、標準ライブラリ(java.util.functionパッケージ)で提供されている関数型インターフェイスです。
```
@FunctonInterface
public interFace Consumer<T> {
  void accept(T t);
}
```
Tは、ジェネリクスの型パラメーターです。Consumaerであれば、T型の引数を受け取り、なんらかの処理を実行する(戻り値はない)メソッド型を表します。

## 最後に
Stream APIというものでは、ラムダ式の利用を前提としているので、必要なスキルです。ラムダ式を覚えれば従来のコードをシンプルにできるので、今後はこれを習得しないと人の書いたソースコードも読めないのだろうと思う...
【Unity with ARFoundation】スマホで取得した平面をOBJ出力する

# スマホで取得した平面を出力したい
![](https://storage.googleapis.com/zenn-user-upload/1f38e56d30fe-20220312.png)

何でもいいからとりあえず題目のことをしたいというせっかちさんは↓からどうぞ
※動確はしていますが、細かいところは自分で解決してください。

https://github.com/SohMitian/ObjExp

# コード解説
## 回転角
これ重要
角度を計算しないとオブジェクトが２個以上だった時に水平に突っ伏します。
```csharp
// 回転反映
Vector3 RotateAroundPoint(Vector3 point, Vector3 pivot, Quaternion angle)
{
    return angle * (point - pivot) + pivot;
}
```
## スケール
これも重要
スケールを計算しないとオブジェクトが２個以上だった時にバウンディングボックスが重なります。
```csharp
// スケール反映
Vector3 MultiplyVec3s(Vector3 v1, Vector3 v2)
{
    return new Vector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
}
```
## ポジション
これも重要
ポジションを計算しないとオブジェクトが２個以上だった時に同じ位置で重なります。
```csharp
v += mf.gameObject.transform.position;
```
## 以上を考慮した頂点算出
```csharp
//頂点情報
foreach (Vector3 vx in msh.vertices)
{
    Vector3 v = vx;
    v = MultiplyVec3s(v, mf.gameObject.transform.lossyScale);
    v = RotateAroundPoint(v, Vector3.zero, mf.gameObject.transform.rotation);
    v += mf.gameObject.transform.position;
    v.x *= -1;
    sb.AppendLine("v " + v.x + " " + v.y + " " + v.z);
}
```
sailコマンドが使えないとき（sh: no such file or directory: ./vendor/bin/sail）

https://readouble.com/laravel/8.x/ja/sail.html

この記事を見て、sailをインストールしたら解決できた。
sailとは一体なんなのか、どうゆうメリットがあるのかを調べる必要があると感じた、

>Laravel Sailは、LaravelのデフォルトのDocker開発環境を操作するための軽量コマンドラインインターフェイスです。 Sailは、Dockerの経験がなくても、PHP、MySQL、Redisを使用してLaravelアプリケーションを構築するための優れた出発点を提供します。
Sailの本質は、docker-compose.ymlファイルとプロジェクトのルートに保存されているsailスクリプトです。sailスクリプトは、docker-compose.ymlファイルで定義されたDockerコンテナを操作するための便利なメソッドをCLIで提供します。

調べたら、こんな感じで出てきたが、要は
LaravelをDockerで使うとき便利なコマンドツールということだろう。
さらに、Docker ~compose .ymlを操作するのに特に便利なのであろう。
MotionLayoutの例を試してみる(キーフレームの補間)

前回はキーフレームの位置をやりました。
[キーフレームの位置](https://qiita.com/yuta317/items/9b9a372a20db26642227)

今回はキーフレームの補間を試していこうと思います。

# 公式リファレンス
https://developer.android.com/training/constraint-layout/motionlayout/examples?hl=ja

https://developer.android.com/training/constraint-layout/motionlayout/ref?hl=ja



リンク先に公式サンプルがあります。
[キーフレームの補間](https://developer.android.com/training/constraint-layout/motionlayout/examples?hl=ja#keyframe_interpolation)

```
<KeyFrameSet>
  <KeyAttribute
    android:rotation="-45"
    android:scaleX="2"
    android:scaleY="2"
    motion:framePosition="50"
    motion:motionTarget="@id/button" />
</KeyFrameSet>
```
ビューの遷移に、回転とサイズ変更します。

# KeyAttribute
framePositionとmotionTargetに関しては前回に書いたので今回は説明しないです。

rotationは回転の設定です。
-は左回転で、プラスは右回転です。
設定した数字分回転します。
今回は左回りで45°回転します。


scaleX、scaleYは大きさの設定です。
今回は２を設定している為縦横の大きさが２倍のサイズになりました。



以上です。
簡単にいろんなアニメーションができますね！