OmniAICreator/Qiita-1.07M huggingface dataset:
Next2D NoCode Toolでテキストを挿入する

まず、初めに訂正を:bow:
Next2D PlayerはWebGLサポートしたライブラリと説明をしましたが、テキスト(デバイスフォント)はCanvas2Dで描画しTextureに書き出しています。
後続のBlendModeやFilterといった機能の描画はWebGLで描画を行っています。

# テキストツール
Tool Areaにある文字ボタンがテキストツールになります。
![スクリーンショット 2021-12-02 23.54.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/107dd1a2-274a-e10f-2370-9fde96c4544c.png)
描画ツールと同じく、ツールを選択してScreen Areaで範囲指定を行うことでテキストエリアが追加されます。
![スクリーンショット 2021-12-02 23.56.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/0f64bd1c-0d2e-9960-3186-4b4737986d47.png)
作成されたテキストエリアをダブルクリックすると入力モードに切り替わり、任意のテキストを挿入する事が可能になります。

# テキストのスタイル変更
Screen Areaのテキストを選択すると、Controller Areaに選択したテキストのスタイル情報が表示されます。

## Font
指定できるフォントはmacとwindowsでデフォルトで入っているであろうデバイスフォントを選べるようにしています。(フォント追加は今後の課題です。。。)
![スクリーンショット 2021-12-02 23.58.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/e4135b61-e4ca-2919-8fd7-313a8c000171.png)

## Auto Resize
- No Resize
指定されたフォントサイズでテキストを描画します。
枠より大きいサイズを指定した場合、何も描画されません。

- Box Resize
フォントサイズに合わせて枠のサイズが自動で拡大縮小します。

- Text Resize
枠以上のフォントサイズに設定しても、枠に収まるようフォントサイズが自動で縮小します。

## Style
フォントスタイルの設定を行えます。
- Normal
- Bold(太文字)
- Italic(斜体)
- Bold/Italic(太文字/斜体)

## Align
- Left(左揃え)
- Center(中央揃え)
- Right(右揃え)

## Behavior
- Single Line
単一行：改行コードが無効になり、全て一行で描画されます。

- Multiline
複数行：改行コードが有効になり、複数行で文字が描画されます。

- Auto Wrap(デフォルト)
自動改行：文字数が枠を超えた場合、自動で改行されます。

## Input
- ReadOnly(デフォルト)
読み込み専用となり、Playerでのテキスト入力は行えません。

- Write
書き込みが許可され、Playerでのテキスト入力が行えるようになります。

## Scroll
y軸のテキストが枠外になった際にスクロールバーを表示します(実装中)
- Off(デフォルト)
- On

## Border
枠のborderの線の有効/無効設定
- Off(デフォルト)
- On 

## Size
フォントサイズの指定が行えます。
サイズの幅は10から255までとなります。

## Color
テキストの塗りの色を指定できます。

## Line Space
行の高さの設定を行えます。

## Character Width
テキストの文字間隔の設定を行えます。

## Left Margin
左マージンの設定を行えます。

## Right Margin
右マージンの設定を行えます。

## Stroke Size
フォント枠の幅の指定が行えます。
サイズの幅は0から255までとなります。

## Stroke Color
テキスト枠の塗りの色を指定できます。

# 動作サンプル動画
<iframe width="560" height="315" src="https://www.youtube.com/embed/f46fJpJKFIA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

もし、この記事を見て、興味が出た方はこちらか動作確認ができます。
[NoCode Tool](https://tools.next2d.app)

明日はBlendMode機能を紹介できればと思います。
Googleスライドで画像が劣化した時にしたこと

Googleスライドに画像をアップロードすると著しく劣化することがあったので、その時試したことを書きおきます。

## どういう不具合があったか
イラレからWeb用に書き出し⇨Googleスライドにアップロードをすると著しく劣化した。

## 試したこと

- 画質を調整した
16：9のフルスクリーンサイズを選択していたので、画像を1920px*1080pxや1280px*720pxに調整してアップロードした。
効果無し

- Googleドライブにアップロードしてからリンクした。
効果無し

## 解決策
Googleスライドのページサイズのデフォルトのものが小さいっぽい。

- 標準(4:3)
- フルスクリーン(16:9)
- フルスクリーン(16:10)

比率は書いているがpx数は書いていない。
ページ設定でページサイズをpx数で指定することで画質の劣化が解決した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1487699/84310b78-1302-a6c4-af04-953528bbf1b8.png)

ページ設定でカスタムを選ぶ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1487699/afce4be1-3029-7c3c-1e4d-c3b98eb7bb9c.png)

1920*1080 ピクセルに設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1487699/2ba618df-4822-0db7-3102-ff62ae01709c.png)

こうすることで画像の劣化が軽減された！
Tensorflow.kerasとkeras混ぜてモデル作って死にかけた話

モデルを作ろうと思ったきっかけは，ファインチューニングしてみよう！という試みからである．
Kerasとか知らんけどまあ適当に作るか！の気持ち．これが全ての元凶＿＿＿


#失敗
以下のようにコードを書いてみた．
環境はcondaで作っており，
python==3.7
tensorflow==2.4
である．

```python:test_ng_model.py
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.losses import binary_crossentropy
from keras.layers import Input, Dense, Dropout

#作成したレイヤを順番に保存しておくリスト
layers = []

#入力層の作成
inputs = tf.keras.Input(shape=(3,))
layers.append(inputs)

#全結合層を2層追加
for l in range(2):
    x = Dense(3, activation="sigmoid")(layers[-1])
    layers.append(x)

#出力層の作成
out = Dense(1, activation='sigmoid', name='new_target')(layers[-1])

#モデルの入出力を定義し，作成
new_model = Model(inputs=[inputs], outputs=[out])

#適当にコンパイル
new_model.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.001), metrics=[tf.keras.metrics.AUC()])

#モデル構造を出力
new_model.summary()
```

結果，こんな感じのエラーが吐かれる．

```bash:error
Traceback (most recent call last):
  File "test_ng_model.py", line 21, in <module>
    x = Dense(3, activation="sigmoid")(layers[-1])

... #省略

TypeError: Cannot convert a symbolic Keras input/output to a numpy array. This error may indicate that you're trying to pass a symbolic value to a NumPy call, which is not supported. Or, you may be trying to pass Keras symbolic inputs/outputs to a TF API that does not register dispatching, preventing Keras from automatically converting the API call to a lambda layer in the Functional Model.
```

#成功
もうわけがわからず，エラー文をひたすらググり，たどり着いた解決策が以下である

```python:改良点
#元のコード：
from keras.layers import Input, Dense, Dropout

#変更後のコード：
from tensorflow.keras.layers import Input, Dense, Dropout
```

これだけ．

無事サマリーも出力された．

```bash
Model: "model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 3)]               0         
_________________________________________________________________
dense (Dense)                (None, 3)                 12        
_________________________________________________________________
dense_1 (Dense)              (None, 3)                 12        
_________________________________________________________________
new_target (Dense)           (None, 1)                 4         
=================================================================
Total params: 28
Trainable params: 4
Non-trainable params: 24
```

tensorflow.kerasとkerasが混在していたのがダメだったっぽい．．．知らんがな！！！！！！！！！！！！！！
マークダウン

マークダウン記法に慣れておいて損は無いので、よく使うものや
見た目は凝らないけど、綺麗に見やすくする程度の最低限だけとりあえず、、、
良いのがあれば順次追加。

####-見出し-
↑よく他のブログや記事で見かける見出しです。

#タイトル①
##タイトル②
###タイトル③
####タイトル④

```
このシャープ（#）を多く記載するほど文字サイズは小さくなっていく。
#タイトル①
##タイトル②
###タイトル③
####タイトル④
```

<a id= #2></a>
####-太文字-
あいうえお（通常）
**あいうえお**（太文字）

```
アスタリスク２つ「*＊」で挟む
**あいうえお*＊
```
####-斜体-
*アスタリスクを１個にして囲むとこのように斜体になる*

```
*アスタリスクを１個にして囲むとこのように斜体になる*
```

####-囲み-
この黒い囲み↓

```
「```」３つの点(バッククォーテーション)で、一番上の行と一番下で囲む
```

[![Image from Gyazo](https://i.gyazo.com/27c65818b4ef2b990e497e9041051ea6.png)](https://gyazo.com/27c65818b4ef2b990e497e9041051ea6)

点を１個減らすと…
「``」2つの点(バッククォーテーション)で挟むとグレーで背景が足される

``2つの点(バッククォーテーション)で挟むとグレーで背景が足される``

####-区切り-
---
↑この線は---で表現可能。

####-リンク-
[Google](https://www.google.com/?hl=ja)

```
[入力したい名前](URL)
上記のgoogleだと、以下のようになる。
[Google](https://www.google.com/?hl=ja)
```

####-打ち消し線-
~~打ち消したい文~~

```
~~で前後を囲む　
~~打ち消したい文~~
```
####-引用-
>引用したい文

```
先頭に>を追加のみ
>引用したい文
```
Mac ＋ VSCodeの作業環境で便利なキーボードショートカットまとめ

MacやVSCodeには便利なショートカットキーがたくさん用意されています。
使いこなすことで開発効率が格段に上がり作業が捗ると思います。
ただ使いたいと思った時にド忘れして、調べることが多々あるので毎回ググらなくてもいいように1つの記事に備忘録として残します。

#Macの便利なショートカットキー

|コマンド|行われる操作|
|------|----|
|command + C|コピー|
|command + X|カット|
|command + V|ペースト|
|command + Z|直前動作の取り消し|
|shift + command + Z|直前動作取り消しの取り消し|
|command + F|検索ウィンド表示|
|command + P|書類の印刷|
|command + S|保存|
|command + T|新規タブを開く|
|command + W|現在のウィンドウを閉じる|
|option + command + W|全てのウィンドウを閉じる|
|option + command + ◀️or▶️|左右のタブに切り替え|
|control + command + F|アプリをフルスクリーンで表示|
|shift + command + 3|スクリーンショット撮影(フル画面)|
|shift + command + 4|スクリーンショット撮影(範囲選択)|

#Mac＋VSCodeの便利なショートカットキー
|コマンド|行われる操作|
|------|----|
|control + Tab|直近で開いたファイルを表示|
|shift + option + F|コードの整形|
|option + ⬆️or⬇️|選択している行を上下に移動|
|shift + option + ⬆️or⬇️|選択している行を上下にコピー|
|shift + command + K|選択している行の削除|
|command + D|選択範囲と同じ文字列の複数指定|
|command + /|行コメントの切り替え|
|command + F|ファイル内検索|
|command + B|サイドバーの表示/非表示|
|control + @|サイドバーの表示/非表示|
SimpleAnimationでお手軽アニメーション

# はじめに
[Siv3D Advent Calendar](https://qiita.com/advent-calendar/2021/siv3d) 23日目の記事です

# SimpleAnimationのつかいかた
SimpleAnimationはOpenSiv3Dv0.6から追加された機能で、簡単にアニメーションの制作ができます。

## コード例

```cpp
# include <Siv3D.hpp>

void Main()
{
    SimpleAnimation animation;
    animation
    .set(U"x", { 0s, 600 }, { 1s, 100 })
    .set(U"y", { 0s, 300 }, { 1s, 500 }, EaseOutBounce);
    
    const Texture texture{ U"🐈"_emoji };
    
    while(System::Update())
    {
        
        if(SimpleGUI::Button(U"move", Vec2(50, 50)))
        {
            // アニメーションを再生
            animation.restart();
        }
        
        // アニメーションされた縁を描画
        texture.drawAt(animation[U"x"], animation[U"y"]);
        
    }
}
```

![画面収録-2021-12-03-0.04.45.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596925/102a2f7f-beb9-ffdb-615a-21d73e7a8047.gif)

# ちょっとしたリファレンス

**SimpleAnimation& set(StringView name, const KeyFrame& a, const KeyFrame& b, double func(double) = Easing::Linear);**
name : アニメーション識別用の名前
a : 初期状態 (`{秒数, 値}`のように記述)
b : 最終状態 (`{秒数, 値}`のように記述)
func(double)　: イージング(かける場合)
アニメーションを追加します。


**SimpleAnimation& setLoop(const SecondsF& loopEnd);**
loopEnd : 秒数
秒数を指定してループを設定します

**void start();**
アニメーションをスタート

**void pause();**
アニメーションを一時停止

**bool isDone() const;**
アニメーションが終了したかどうか

**size_t loopCount() const;**
ループした回数

値の取り出しは、[識別名]でできます。つまりこんな感じ

```C++
Simpleanimation animation;
animation.set(U"one", {0s, 100}, {1s, 200}).start();

while(System::Update()){
    Print << animation[U"one"]; // 識別名oneのアニメーション(の数値)を表示
}
```
似た顔のFANZA女優を顔写真から検索出来るUI/UXを考えるのに苦労した

この記事は [驚異のFANZA女優検索](https://fanza-actress-bust-search.azurewebsites.net/) Advent Calendar 2021 の 3 日目の記事です。

#似た顔のFANZA女優を顔写真から検索出来るUI/UXを作る
似た顔のFANZA女優を顔写真から検索出来るようにしたが、顔認識はAzure Cognitive ServicesのFace APIを使うことでそれ程苦労せずに出来た。ただこれを実際に機能としてサービスに乗せる時にどういうUI/UXにするか、これは非常に悩んだ。

#顔写真を指定するUI/UXは2種類が多い
最初のポイントは顔写真を指定してもらう方法だ。顔認識が出来るWEBサービスを色々見てみると、URLを指定する方法とローカルファイルをアップロードする方法の2つを採用している所が多かった。ただ方法が2つあると、ユーザーはどちらの方法を使うかを**選ぶ**必要がある。2つの方法から1つを選ぶというUI/UXは決してシンプルとはいえないと思う。また1つのUIを操作している時もう１つのUIは使わないにも関わらずレイアウトは占拠される。個人的に使っていないUIが表示されるのは嫌だった。それらを考慮すると[Googleの画像検索](https://www.google.co.jp/imghp?hl=ja)のように選択方法がタブになっているのが一番しっくりきた。タブなら選んでいるレイアウトだけが表示されるところも良いと思った。


#タブの場合デフォルトはどっちにするか
タブ式のUIにするのであればデフォルト表示を何にするかは極めて重要だと思う。今回はURL指定をデフォルトにすべきだと思った。まずローカルファイルに顔写真があるかは人に依る所が大きいと思う。また殆どの人（特に男性）は自分の顔で検索したいわけではないと思う。つまりローカルファイルをアップロードする方法を使うケースは基本少ないと思う。（ただ少ないが確実に0ではないと思うので無くすという選択肢は考えなかった）。またURL指定ならサンプルを用意できるメリットがあると思った。サンプルをクリックしたらURL指定する所に入るようにすればユーザーへの操作説明にもなる。

#採用しなかった3つ目の方法
余談だが、WEBサービスを見ている時、顔写真を選ぶ方法がもう一つあった。それはカメラを起動してその場で写真を撮ってアップするという方法だ。面白そうと思ったので、実験でカメラを起動させて写真を撮る所までは作った。ただ作ってみて実際にサービスとして採用するならカメラが複数あった場合の対応なども考えなければいけないし、そもそも自分の写真と似た顔のFANZA女優を検索したい状況はあまりないだろうと思って結局この機能の実装は止めた。（3つあってもレイアウトにさほど悩まなくて済むのもタブの良さだと思った）

#さらにUXを詰める
タブで顔写真を選べるようにした。最初は選んだらその画像が有効な画像か判定して、その後検索ボタンを押すことで検索出来るようなUIを作った。しかし、実際に作ってみて選択と検索で2回操作をするのは面倒だと思った。顔写真を選択したら、そのまま似た顔のFANZA女優が表示されるようにした。ただこの流れで画面切り替えが入ってしまうとやっぱりUX的にはイマイチと感じたので、AJAXを使って顔写真を選択して検索されるところまで画面切り替えなしにしたくなった。（AJAXに関しては明日詳細書く）。これで自分的には大分良い感じになってきた。そんな時にたまたま自分の参考に出来そうな面白いサービスが話題になっていた。

#イライザダイジェクトのセーフティーネット参考に
そのサービスは[イライザダイジェクト](https://www.digest.elyza.ai/summaries/1259556767619434434)という文章を入力させて、要約を作るサービスだ。当たり前の話だが、文章を入力しなければ何も起きない。そうすると多くの人は既に書かれている文章をどこかからコピーして持ってくることが多いと思う。要約スタートを押す前に利用規約に同意する必要があり、そこには以下の文章が書いてあった。
>本サービスの利用により、第三者の著作権その他の権利を侵害しないよう十分ご留意ください。詳細は利用規約をご確認ください

正直このアプリに入れられる文章が小説の一説だったとしても、それは使用者の自己責任でありアプリ自体の問題ではないよう気がする。それでもここまでの文章を用意しているは多分セーフティーネットだろうなと思った。同じように自分のアプリで、URLを指定させる方法は、言い換えれば他のページから画像情報を取得することになる。人によっては女優やアイドルの顔写真を使う人もいるだろうと思うと自分のアプリでもこれと同等のことをした方が安全だろうと思った。

#イライザダイジェクトのSNS投稿機能で気づいたこと
またイライザダイジェクトは結果をSNSに投げる機能もあった。最初はこれも実装しようと思った。しかしその時に気づいた。あーこれをSNSに投げた時点でさらに著作権が関わってきそうだ。つまり結果だけを貼るより元がどうであって、それがどうなったかを表示しようとすると、どうしても元文章が必要になる。そこで有料で出版されている本の文章が丸々のっていたらやっぱりそれは問題になるだろう。だからここまでやっているんだなと気づいた。

#SNS投稿機能は止めた
で、SNSへの投稿機能は悩んだが、結局作らなかった。一番大きい理由は顔検索を機能として使っている分には面白いとしても、それをSNSに投稿出来るようにすると、本来面白く使ってほしくて作った機能を別の用途で使う人もいる可能性があるからだ。つまりFANZA女優の誰々に似ていると言われて気分を害する人もいるだろうし、似ていることで揶揄されたり、酷いケースだといじめにつながる可能性すらもある。サービスを作る側がどこまでそれを踏まえるべきかは正直分からない。機能としてはむしろ入れたい。ただ、これはやっぱり凶器になりうる可能性もあると思ってしまったので、あくまで自分のサービスの中だけで完結する機能とした。だからそれであればイライザダイジェクトのようにボタンを押すときのチェックボックスによる同意まで取るのは冗長かと思って一言書くだけに留めた。アップロードしたデータも最初は何か使えるので取っておいても良いかと思ったが、元々Azureが24時間でデータが消える仕組みだったので、自分のサービスでもアップされたデータは保存しない仕組みにした。

#顔写真から似た顔のFANZA女優を検索出来るUI/UX
というわけで画像を選んで、顔検索が出来る仕組みは、色々悩んだ末にシンプルに作ったつもりだ。UI/UXには絶対的な正解はないので、気になる所があれば是非教えて欲しい。
HEIF (HEIC) をSafariでアップロードすると、自動変換される場合がある

macOS Safari 15.1 で想定外の動きをしたのでメモ。

## 再現コード

<p class="codepen" data-height="300" data-default-tab="js,result" data-slug-hash="WNZNQJV" data-user="noboru-i" 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/noboru-i/pen/WNZNQJV">
  HEIF convert</a> by Noboru ISHIKURA (<a href="https://codepen.io/noboru-i">@noboru-i</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

`accept` 属性を、 `image/*` にした場合と `image/png` で、 JavaScript 上で取得できるファイル名とサイズに違いがありました。

## macOS Chrome での結果

まずは、普通の結果。
macOS Chrome 96 で、それぞれにてHEICファイルを選択した場合。
（そもそも、選択ダイアログの「オプション」から「すべてのファイル」を選択しないと、 `.HEIC` ファイルを選択できませんでした。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8708/81146e09-a785-73cd-0be9-9a08a27d7bee.png)

どちらで選択した場合でも、同じファイル名とサイズが取得できています。

## macOS Safari での結果

想定外だった結果。
macOS Safari 15.1 で、同様にHEICファイルを選択した場合。
（こちらは、どちらのinputでもHEICファイルを選択できました。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8708/3f2b9300-5811-1c92-01ec-aeda630d29de.png)

`accept="image/png"` を指定していた方では、元の画像ファイル名と異なり、拡張子も `.png` になってます。
サイズも、0.94MBだったものが9.07MBと10倍近く増えています。
つまり、ブラウザ側で勝手にpng形式に変換されています。

## iOS Safari での結果

こちらも想定外。
iOS 15.1.1 Safari で同様にHEICファイルを選択した場合。
（こちらは、どちらのinputでもHEICファイルを選択できました。）

![IMG_7606356F5D75-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8708/1efa9c3a-4764-9863-e132-845d12247521.jpeg)
IMG_7606356F5D75-1.jpeg

こちらは、どちらで選択しても、なぜか `.jpeg` となりました。
同じファイルを選択しましたが、 2.01MB となりました。

## 困りそうなこと

画像ファイル名も必要な場合、そもそもブラウザ側で変換されてしまうため、JavaScript上で取得することができなさそうです。
また、ファイルサイズをJavaScript上で制限している場合、ユーザーは例えば「900KBのファイルを選んだはずなのに、1MBの制限でエラーになる」といったことがありえますね。
最後に、macOSとSafariでも挙動が違うのも困りますね。
チーム開発をはじめから

チーム開発をやってみたい！コンテストに出たい！って方向けの記事です

## 用意するもの

- とっておきのアイデア
- 仲間
- 体力
- パソコン

## チーム開発の手順

### 1. アイデアを出す

自分が思いっきり力を注ごうと思える、とっておきのアイデアを出しましょう。

作品を完成させるためには、何より自分自身がその作品に対する熱意を持ち続けることが重要です。とっておきのアイデアを煮詰めて、その素晴らしさを頭の中で整理しておきましょう。

### 2. チームをつくる

- 開発期間、一緒にいられる人
- アイデアを理解してくれる人
- 最終決定をする人を決めておこう

自分の持っているアイデアを説明して、それを一緒に形にしていく仲間を集めましょう。

スキル・意欲のあるメンバーを募るのも大事ですが、数ヶ月~半年間一緒に開発をしていくので、なるべくお互いに仲良くできるメンバー構成にした方が安心です。チームの雰囲気が険悪だと、コミュニケーションも少なくなって開発に実害が出ます。

また開発の中で、作品の仕様などをチームで決めきれなかったときに最終決定をする人を決めておきましょう。


### 3. ハッカソン形式でちょっと何か作ってみる

いきなり長期間の開発をやろうとしたところで、大抵はうまくいきません。チームメンバーでハッカソンや、小さい機能の開発をやってみて、チーム開発の一通りの流れを体験しておきましょう。
1dayのハッカソンであっても、"アイデアを出して、簡単に設計して、実装して、発表する"という流れは長期間の開発とほぼ同じです。何となくでもいいので、開発のイメージを掴んでおきましょう。

### 4. 作品の締め切りまでに何が必要か整理する

アイデアを実現して発表するまでに、絶対に必要なもの、できれば必要なもの.. などを洗い出して整理しましょう。
発表会があるのなら、その資料作成やプレゼンの練習が必要です。誰かに使ってもらいたい作成なのであれば、実際にユーザテストをしてそのフィードバックを受ける期間も用意しておいた方が良いです。

それらが整理できたら、絶対に必要なものから逆算して、「○月○日までにこの機能は完成しているようにする」といった計画を決めていきましょう。

### 5. 進捗を管理する

順調に開発を進めるために、定期的にお互いの進捗を確認し合いましょう。
ほぼ100%開発は計画通りには進まないので、厳しそうな部分はどこかをなるべく早く把握して、分担やサポートをしていきましょう。（毎日サボりまくってるとかでない限り）スケジュール通り進まなくてもそれは見積もりが甘かっただけで作業者に責任はないので、チームで頑張っていきましょう。

### 6. 頑張る

開発はとても大変です。心が折れそうになることもあるとは思いますが、頑張っていきましょう。学生のうちの開発経験は将来にものすごく役に立ちます。本当にものすごく役に立ちます。心身の健康と進級が一番ですが、手を抜かずに頑張りましょう。

エナジードリンクは健康に良くないので、本当に大事なときだけ飲むようにしましょう。

全てが終わったら打ち上げをしましょう。その時思ったことを日記やtwitterに残しておくと良いでしょう。

## おわりに

チーム開発は大変なこともありますが、とても楽しいものです。
学生時代の思い出に、就職のネタに、ぜひぜひやってみてください。
Notionのシンプルテーブルにヘッダーを付ける

アルプ株式会社でエンジニアをしています、集約のエンティティ@pictinyです。
これは[Notion Advent Calendar 2021](https://qiita.com/advent-calendar/2021/notion) 2日目のエントリです。
1日目は[Notionでシンプルテーブルを作ろう](https://qiita.com/pictiny/items/e853f3508b4898ca448b)でした。

# シンプルテーブルのヘッダー
シンプルテーブルにヘッダーを付けたいことがあります。

シンプルテーブル上部のメニューにある `Options` から `Header column` `Header row` を有効にすると、それぞれ1列目と1行目に背景色が付きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/d2a71f6e-b92b-1e46-72d1-cd5c868c09f3.png)

# まとめ
ヘッダーを使うと簡単に見やすい表が作れて便利ですね！
【感想文】t_wadaさんがやってきた

#前書き
2021年11月末日。弊社の人事部門が企画する社内講演に、t_wadaさんがやってきた。
当日、私はライブで参加出来なかったが、大盛況だったようである。
私も遅れて録画を観たのですが、たくさんの気づきを得た。
そこで今回は公開されているスライドには書かれていない、当日の講演で私が感銘した一節を紹介することにする。
本題の講演内容の方も、とても良い気づきを得る講演だったのですがそちらについては割愛します。
t_wadaさんのtwitterを参照いただき、気になる方は本人へ講演依頼をされたし。

https://twitter.com/t_wada/status/1465522338804350980?s=20


#当社社員とのQAセッションでの、良い話

t_wadaさんの講演の後、当社の技術者数名からt_wadaさんへの質問タイムがありました。
その中で私が印象に残った、t_wadaさんの回答をご紹介します。
先ず、質問は以下のような内容でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656547/7c3b7de3-ff43-e3bd-cd5c-bf4373a2e754.png)



#t_wadaさんのアンサー

事前にリハーサルがあったのか、無かったのかは分かりませんが、上記の質問に対してt_wadaさんは以下のように回答されました。
私は、この講演を二日後に録画で拝聴した訳ですが、t_wadaさんのこのコトバは、
**１エンジニアが成長するために、或いは、１エンジニアを成長させるために、有効な一つの手法、考え方である**
と、共感を覚え、周りにも教えたいと印象に残ったコトバでした。いや、エンジニアに限らず、あらゆる人の成長に役立つメソッドかも知れないと思いました。

思わず、録画を聴きながら写経してしまいましたので、以下に紹介させていただきます。
//2021/12/3修正:写経部分について読みやすくするため筆者で体裁を修正しました。

>「体験」を得るためには、案件の前に「自分でやる」のが良くてですね、チュートリアルをやってみてください。
**「理解できるようになる」あるいは「わかるようになる」前に「手を動かす」というステップが、実は大事です。**
「テスト」の書き方がわからないという事が、その「テスト」を書かない理由の大半を占めるんですね。
で、わからないというのは、わからないから書けないという順番になるんですけど、エンジニアの理解の仕組みとしては、
**書いているうちにだんだんわかってくるようになるっていう順番のほうが遥かに多いんですよね。**
**新たな概念とか、新たな技術を学ぶためには、「わからないけど手が動く」って事がとても大事なんですよ。**
で、手を動かしていくうちにだんだんだんだんわかってくるんです。


>だから、**「わかる」ってのは「手が動く」の後にやってきます**。
なぞれるやつをなぞってるうちに、だんだんわかってきて「なるほど、そういうことね、こいつは、お得だ」とか、「これの方が、なるほど、確かに早くなりそう」、また、手を動かして、ある程度自分の中で、「型」とか、或いは、「これまで書いたコード」とか増えてくと、それを真似したり、コピーアンドペーストしてそれをベースにしたりしてすることも出来るようになってくる。
ゼロから勝負しないってことがとっても大事。

>なので、テスティングフレームワークのチュートリアルでもいいし、様々なところに、チュートリアルがありますので、テスティングフレームワークのチュートリアルとか、テストコードのチュートリアルとか、或いは、学習リソースとか、なぞって、動かして、理解する系のものを、先ず一通り、騙されたと思ってなぞってみるというのが、これが一番おススメです。

>**アタマで理解してから手を動かすんじゃなくて、手を動かしながらアタマで理解していくっていう学習の順番がオススメです！**
そういう意味だと酷い我田引水ですが、この「テスト駆動開発」という本もそうなっているので、是非是非というところもあるんですが、なんか、わからないなりに手を動かしていくと、だんだんわかってくるようになると腹落ちしていくという順番が体験できるという形だと思います。
そうすると、案件の中で、一部だけここはテスト書きやすそうだからテスト書いてみよう、というと、そこは明らかに早くて楽だったみたいな体験がだんだん出来るようになってくると思います。


皆さん、どう感じましたか？　t_wadaさんのこの講義を聴かれた方は質問者の質問の意図が分かるかも知れませんが、私がt_wadaさんの回答が凄いと感じたところは、

**質問者の質問の意図を超越した、つまり、「テストを書いて開発して、質とスピードがトレードオフでなかった」という今回の講演テーマに基づく特定の事象へ事例ではなく、「体験を得る」ためのメソッド、手法という、高い視座での回答となっている点**。

そして、だからこそその回答は

**エンジニアだけではなく、あらゆる職種の、人間の、「成長のためのメソッド」の一例となっている点**

に感銘を受けました。

事前にリハーサルしてないのであれば、こんなことをスラスラ回答できる t_wadaさんって、凄いなあ、そして、いい話を聴けたなあ、と思った訳です。

自分自身の今後の参考にも活かしたく、そして、皆さんにもシェアしたく筆を取りました。

以上、皆さんのお役に立てば幸いです。
Lambdaの計算を簡単に説明してみます



#計算概要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969819/1a32804d-1946-52ef-b157-0b80e12e3951.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969819/fd14cb78-15e8-6228-e6af-a4559a05b6cf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969819/a7df581f-8ff9-e10b-e1f7-e5a2a12c0085.png)
#実行時間とリクエスト


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969819/885a8fd1-b10f-afba-28b4-1a294a57c4e0.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969819/ef6bfd40-8cc5-7cd7-5cb0-055cd12fe146.png)

#無料枠
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969819/e1056253-96bc-7bd3-5723-8e5c901bb8ca.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969819/a53059ea-55a9-47bb-f31b-82dbc0fe62f3.png)

#無料枠超過分

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969819/ffd882fc-4c90-05c3-04b8-919b685e896b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969819/3443191d-8f67-e354-4dca-a6fedb68fd2f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969819/c5ee00fd-ffd6-5c63-ebe6-0ff9e544b961.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969819/d5a1b11f-6de5-eb82-9479-eea97ed638fa.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969819/ae2813c6-da2b-e421-81cb-ceb41fd53adf.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969819/9055c024-ef03-dbfc-18c5-cb96d4571f76.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969819/f04bf4a9-4871-4bac-b2cb-d439268c43b2.png)
【2日目】Python初心者が開発環境を作る

#やること
>開発環境の選定
自分の環境にインストールする


私の環境はMacなので、ご参考にされるかたがWindowsの場合は若干違うかもしれません。

------
###Pythonパッケージ

以下は、*Python 開発環境* でググった結果からわかったことです。

まずはPythonのインストールをする必要があるようでした。
Pythonのパッケージは**アナコンダ**がおすすめということなので、これをインストールします。
ページ下部にインストーラへ誘導するリンクがありました。※2021年12月時点

https://www.anaconda.com/products/individual

手順に沿ってインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2343271/bb04995c-e0e1-899b-1681-bd2a4e960dd4.png 'アナコンダインストール')

-----

###アナコンダ起動

アナコンダのインストールが終わったら、アナコンダナビゲーターというソフトを起動し、JupyterLabで開発します。
てっきりアナコンダが開発ソフトかと思ってました！

アナコンダナビゲーターを起動後、JupyterLabと書いてあるところのLanchをクリックするとブラウザが立ち上がます。
画像の画面が開きました。これが開発画面のトップページ的なものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2343271/de3cef6f-ef40-4c13-ea5d-e4dbe82b1735.png '開発環境に到達！')
-----

###試しにプログラミング
新規のブックを作成して、「hello world」してみます。
下記コマンドを書いて、Shift+Enterでプログラムを実行すると・・・

```python
print('hello world')
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2343271/b1b264af-0b2c-7d31-4a48-2b9a10e8c7bd.png)

世界にあいさつができました！

今日はここまで。ご一読ありがとうございました。
はじめてのデータドリフト

# はじめに
下記の勉強会のLTで話した内容をそのまま聞かれることが多いので、発表内容をもとにデータドリフトについて記載したいと思います。
https://mlops.connpass.com/event/211953/

MLOpsというワードはバズワードと言われこともあり、意味が広く、人によってリモデリングの自動化、機械学習モデルのCI/CDなど話すポイントがことなります。この記事では機械学習モデルの運用時における機械学習モデルの性能をモニタリングする方法の１つであるデータドリフトに注目します。


# 機械学習モデルは多くの場合に劣化する
 機械学習モデルは多くの場合で時間が立つにつれ精度（性能）劣化が生じます。これは様々な原因が考えられます。例えば、機械学習モデルを運用している実社会などの環境が大きく変化する場合が例としてあげられます。自動販売機の缶の需要予測をするときなど、コロナ前のデータを使って予測していたところ、コロナ前までは精度がよかったものの、コロナに入り外出が少なくなってその自動販売機の周りを通る人数が減ると需要予測の精度が落ちてくることが考えられます。このように機械学習モデルの背景場の変化がモデルの性能劣化の影響を与えます。もちろんそれだけでなくビジネスモデルがそもそも変化して、機械学習モデルを利用する利用者の傾向が変化するなども考えられます。

 もし機械学習モデルの性能が劣化してきた場合、精度を確認してデプロイ前の精度と遜色がないことを確認したり、以前の期間の精度と比較することで劣化の検知をすることができます。精度を計算するための正解データがあるなら精度を計算することで劣化を検知できるわけです。
しかし精度を計算するための正解データを手に入るのが１ヶ月後、或いは３ヶ月後ということももちろんあると思います。精度の計算するために時間がかかる場合、精度を計算するまで何も対策ができなくなってしまうことになるので、そのような場合の解決策の一つとして、特徴量の変化 -データドリフト- という考え方があります。

# データドリフト
データの変化といっても本やblogなどで話されていて、定義した論文などを知らないのでもし知っている方がいたら教えていただければと思いますが、ネットで調べていると下記の３つのドリフトが分けられると思います。

- データドリフト or フィーチャードリフト（特徴量ドリフト） or 共変量シフト or datashift
  - インプットデータの分布の変化
- コンセプトドリフト
  - 特徴量と目的変数の関係性が変化
- ラベルドリフト
  - 正解データが変化

なお、共変量シフトやdatashiftというワードが古くから使われていて、データドリフトは最近の文献（GCP, AWS, Azure etc.）などで見受けられます。いつからデータドリフトというワードが出てきたか出自は私は確認できていませんが、本記事では同じものとして扱い進めます。


# データドリフトで使われる指標

データドリフトとして分布の変化を定量的に評価する方法の中から代表的な方法は下記のとおりです。

- Kullback-Leibler Divergence
  - KLダイバージェンスとも呼ばれる
- Jensen-Shannon Divergence
  - TensofFlow採用（数値特徴量）
- Population stability index
  - DataRobotで採用。こちらの指標を初めて聞く人も多いかもしれないので式を記載しておきます。
 
```math
PSI = \sum ((Actual％ - Expected ％) \times  \ln ( \frac{Actual ％}{Expected ％}))
```

- Kolmogorov Smirnov 検定
- チェビシェフ距離 or L距離
  - TensorFlowで採用（カテゴリ特徴量）

共通しているのはどれも分布の変化を計算できるものを使っていることです。良し悪しに関してはここでは議論しません。
もしライブラリなどのデータドリフトの指標を使っているなら、どの計算方式を使っていて、どのしきい値が機械学習モデルを適用するビジネスにとって重要なのかを把握されることが重要かと思います。



# まとめ
ここまで読むととデータドリフトを必ずモニタリングしようという流れになるかもしれません。しかし、データドリフトが発生するからといって必ずしも精度に影響を与えるわけではないこともあります。
実際に精度に影響するかどうか確認が必要なら事前に検証してみるのも一つの手かもしれません。
精度を計算するまでに時間がかかる場合は、ビジネス毀損を避けるための一つの手段としてデータドリフトを検討してはいかがでしょうか？



# 宣伝
私はMLOps勉強会の運営の一人です。次回の勉強回について告知させてください！
2021年最後のMLOps勉強会は12月8日（水）を予定しています。
内容はベクトル近傍探索技術とA/Bテストの2本立てです。
ぜひご参加ください！

また、発表者も随時募集しております。下記ページに応募フォームがございますのでみなさんの応募お待ちしています！

https://mlops.connpass.com/event/224554/



# 参考
https://www.slideshare.net/shotanaka7161/20210616mlopscommuinity9datadrift

https://iblog.ridge-i.com/entry/2021/03/10/110000

https://gsarantitis.wordpress.com/2020/04/16/data-shift-in-machine-learning-what-is-it-and-how-to-detect-it/

https://chezo.uno/post/2019-12-05-ibis2019-mlse/
Djangoのdb_columnについて

# db_column
modelの定義する際に、指定できるフィールドオプションで、カラムの名前を設定することができる。
結論、便利だと思い使ってみたのだが、推奨されていないようで、トラップがあったのでメモ。

https://docs.djangoproject.com/en/3.2/ref/models/fields/#db-column
https://docs.djangoproject.com/en/3.2/ref/models/fields/#database-representation

## db_columnの使いどころ
Djangoでは、ForeignKeyを定義した場合、自動的にカラムの名前が`テーブル名_id`に指定されてしまう。


```models.py
class Status(Model):
    name = TextField(primary_key=True)

class User(Model):
    id = UUIDField(primary_key=True)
    status = ForeignKey(Status)
    name = TextField()
```
例えば、このようなモデルを定義したとすると、Userのstatusカラムは自動で`status_id`という名前になってしまう。
実際には、idではないので`status_name`というカラム名にしたい場合に、db_columnオプションを使うことができる。

そこで、db_columnを使うとカラム名を変更できる

```python:models.py
class User(Model):
    id = UUIDField(primary_key=True)
    status = ForeignKey(Status, db_column='status_name')
    name = TextField()
```

## トラップ
db_columnを使用して、modelを作成したあと、objectをcreateしようとしたタイミングで違和感に気づいた。

```python:create
User.objects.create(
    id = '000000-00000-00000',
    status_name = 'active',
    name = 'john'
)
```
↑では、例外が発生してcreateできなかった。

試しに、

```python:create
User.objects.create(
    id = '000000-00000-00000',
    status_id = 'active',
    name = 'john'
)
```
↑では、問題なくcreateすることができた。

## まとめ
フレームワークの裏側では、`テーブル名_id`で処理するから、推奨されていない？
どうしてもカラム名を指定したい場合は、カスタムSQLで直接定義する方法でとのこと。
【Ruby のまずいコード】回文素数を表示

# お題

3 桁の回文素数をすべて表示してください。

回文素数とは，回文数になっている素数のことです。
回文数とは，数字列で書いたときにそれが回文になっている数のことです。
（一般の $N$ について，$N$ 進法の回文数を考えることができますが，ここでは 10 進法で表記した場合のこととします）

たとえば，101 という数は回文になっていて，しかも素数なので回文素数です。
121 は回文数ですが，合成数なので（$11^2 = 121$）回文素数ではありません。

# コード

```rb
require "prime"

def put_palindromic_prime_number(num)
  str = num.to_s
  puts str if num.prime? && str == str.reverse
end

(100..999).each do |num|
  put_palindromic_prime_number(num)
end
```

# 問題点

コードは合っています。101 から 929 まで，15 個の回文素数が表示されます。

素数かどうかの判定は，自分でアルゴリズムを実装するより，このコードのように標準添付ライブラリーの `prime` を使うほうがいいですね。
回文かどうかの判定も `str == str.reverse` でいいでしょう。
また，機能の一部をメソッドに切り出したことも悪くないと思います。

まずいのは，メソッド内で `puts` している点です。
こういうコードを Qiita の記事で非常によく見かけます。
何がまずいのでしょうか。

## つぶしが効かない

このメソッドは柔軟性に欠けます。
標準出力でなくファイルに書き出したくなったらどうするのでしょうか？
回文素数ごとに改行するのではなく，空白で区切って表示したくなったら？

そのたびにメソッドを書き換えるか，新設することになります。
一つのプログラムで複数の出力方法に対応したければ，メソッドをいくつも作るか，出力方法を指定する引数を設ける，といったことになります。
スジの悪いやり方です[^s]。

[^s]: 引数によって出力方法を分けること自体は悪くありませんが，多様な用途に対応しようとすると設計が複雑になる恐れがあります。

一つのメソッドに，

* 回文素数かどうかを判定する機能
* 回文素数だった場合にそれを表示する機能

という異質なものを詰め込んだ設計が失敗なのでした。
前者は普遍的であり，したがって安定しています。
後者は普遍性があまりなく，上で見たように多様で変わりやすいものです。

## テストしづらい

回文素数のような，判定が単純なものならまだいいのですが，もう少し複雑になってくると，アルゴリズムやその実装が本当に合っているか組織的に検証する必要があります。
そのためにソフトウエアテストを行います。プログラムでプログラムをテストするのです。
たとえば，`101` や `121` を与えて，正しく動作するかどうかを検証するプログラムを書くのです。

しかし，我らが `put_palindromic_prime_number` メソッドは，テストに向いていません。
標準出力に何が表示されたかをプログラムで拾うのは面倒なのです。

# 改善

問題点が理解できたら，改善は容易ですね。
要するに，メソッドの役目を「回文素数かどうか判定する」ことに留めればいいのです。

```rb
require "prime"

def palindromic_prime?(num)
  str = num.to_s
  num.prime? && str == str.reverse
end

(100..999).each do |num|
  puts num if palindromic_prime?(num)
end
```

出力方式を変えたくなってもメソッドには手をつけなくてすみます。

また，この `palindromic_prime?` メソッドは容易にテストできます。
標準添付ライブラリーの test-unit を使うと，以下のようなテストコードが書けます[^mt]。

[^mt]: 同じく標準添付ライブラリーの minitest を使っても，これと似たコードでテストできます。

```rb
require "prime"
require "test/unit"

def palindromic_prime?(num)
  str = num.to_s
  num.prime? && str == str.reverse
end

class TestPalindromic_prime < Test::Unit::TestCase
  test "回文素数" do
    assert palindromic_prime?(2)
    assert palindromic_prime?(7)
    assert palindromic_prime?(101)
    assert palindromic_prime?(15451)
  end

  test "回文数だが素数でない" do
    refute palindromic_prime?(9)
    refute palindromic_prime?(22)
    refute palindromic_prime?(121)
    refute palindromic_prime?(12321)
  end

  test "素数だが回文数でない" do
    refute palindromic_prime?(13)
    refute palindromic_prime?(97)
    refute palindromic_prime?(1987)
  end

  test "回文数でも素数でもない" do
    refute palindromic_prime?(24)
    refute palindromic_prime?(9876)
  end
end
```

簡単のためテスト対象とテストコードを一つのファイルにまとめて示しましたが，ふつうは別ファイルにします。

テストコードがしっかり書けていれば，メソッドをリファクタリングするときにバグの混入が防げます。

機能の一部をメソッドに括り出す際，「そのメソッドはテストしやすいか？」という観点も持つとよいでしょう。
ContentVersion、ContentDocumentLinkで困ったら・・・INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY : [NetworkId][LinkedEntityId]

とりあえず走り書き（気が向いたら綺麗にまとめるかもしれないし、このままかもしれない・・・）。

Apexを使用してカスタムRestAPIを作成する仕事をしましたが、ファイルアップロードでかなり行き詰ったところがあるので忘備録として残しておきます。

##エラーの経緯とやったこと
ファイルアップロードするときはContentVersionやContentDocumentLinkを使用しますが、以下のエラーが発生してなかなか上手くすすみませんでした。

 Insert failed. First exception on row 0; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, [LinkedEntityId]

ちょーざっくり訳でレコード作成失敗したよ、アクセス権が不十分だよ[LinkedEntityId]

みたいなこといっていますが、共有設定の見直しやLinkedEntityIdにかかわるオブジェクトのContentDocumentLinkで項目レベルセキュリティ、挙句の果てにプロファイル内の設定もしらみつぶしに探してみても解消できそうな設定はないんです(´・ω・｀)（この調査だけで何日もかかっています）

ContentVersionTriggerHandlerでエラーが起こっていて、ファイルアップロード時に別ユーザに共有しようとしたときに発生しています。またファイルアップロードしたユーザがサイトコミュニティユーザ（外部ユーザ）で、Salesforceユーザ（内部ユーザ）に共有したときにエラーが発生しました。またSalesforceユーザから別のSalesforceユーザに共有するときは何もエラーは起きず正常にファイルの共有ができるという不思議・・・

さて一体何が問題だったんでしょう・・・

##対処１.外部ユーザの場合、ContentVersionTriggerHandlerのInsert部分の処理を飛ばす
これで問題ないならとても簡単です。でもだいたいファイルアップロードしたときはどんなときでもファイル共有しなくてはいけないなら、これではダメです。

##対処２．Experience Cloud サイトのメンバーに共有したいプロファイルを追加する
どうりでなかなかエラーが解消できなかったわけです（サポートに問い合わせても数日かかった回答です）。
デジタルエクスペリエンスから対象サイトをクリックしてメンバー追加するだけということです。

外部ユーザから内部ユーザにファイルを共有する際はメンバーに追加しないとだめで、このせいで権限がないよといっているようです。とてもわかりにくい・・・

あとは正しいURLで実行すればRestAPIとしてファイルアップロードが機能し外部ユーザからのアップロードしたファイルを内部ユーザへ共有することができますが、もし次のエラーが発生した場合は嫌になるでしょう。

INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY : [NetworkId]

いますぐ仕事を投げ出したい気分になりますが、次の対処法があります。

##対処３．ファイルアップロード時はサイト名を必ず含める
上記エラーはサイト名を含めると正常に機能します。

つまり
×：（instance）/apexrest/(Apexクラス名)/・・・
〇：（instance）/(サイト名)/apexrest/(Apexクラス名)/・・・
というわけです。
Arduino IDEからPlatformIOへの移行

ひとりアドベントカレンダー2日目

2日目に思いついたので1日目は気が向いたら追加する。

Arduino IDEで開発していたものをPlatformIOに移行したので備忘として

# 元の環境

- Windows 10 21H1
- Arduino 1.8.9
- 開発対象: [M5Stack Basic](https://www.switch-science.com/catalog/3647/)

# 移行先環境

- Xubuntu 20.04
- VSCode 1.62.3
- PlatformIO IDE 拡張 v2.4.8

# 移行手順

1. githubからclone
1. PlatformIOでプロジェクト作成
1. srcディレクトリ以下にソースをコピー
1. M5Stackのライブラリの導入
1. その他依存しているライブラリの導入
1. 拡張子inoのファイルの修正
1. gitの管理に追加

## githubからclone

ソースはgithubに置いていたのでひとまずcloneしてきます。
そして一旦ディレクトリ名を変更しておく

``` bash
git clone ~~~/Ambient_M5stack.git
mv Ambient_M5stack temp
```

## PlatformIOでプロジェクト作成

PlatformIOで、New projectで作成していきます。
その際プロジェクト名をリポジトリ名と同一の名前、Ambient_M5stackで作成しました。
BoardはM5Stack Core ESP32を、FrameworkはArduinoを指定しました。

## srcディレクトリ以下にソースをコピー

先ほどcloneしてリネームしておいたディレクトリからソースをsrc以下にコピーしてきます。
その際gitに移動したと認識されるようにします。

``` bash
mv temp/* Ambient_M5stack/
cd Ambient_M5stack
git mv Ambient_M5stack.ino src/
```

## M5Stackのライブラリの導入

プロジェクト作成時にM5Stackを指定していたので、入っているかと思いましたが無いようだったので追加しておきます。
Librariesから検索文字列、M5Stackを入力してM5Stack by M5Stackを見つけ、クリックしてAdd to ProjectでプロジェクトAmbient_M5stackに追加しました。

## その他依存しているライブラリの導入

ついでにそれ以外の依存ライブラリもここで追加しておきます。
今回はAmbient ESP8266 ESP32、検索文字列はAmbient ESPで。
トップには出てこないが見つけて同様にAdd to Projectで追加します。

## 拡張子inoのファイルの修正

拡張子inoのファイルを開くと警告メッセージが出るので修正しておきます。
具体的には以下の変更を行った。

- ファイルの先頭付近に```#include <Arduino.h>``` の行の追加
- 関数プロトタイプの追加
- 拡張子をcppへ変更

関数プロトタイプは以下のような行で、実際に関数を呼んでいるsetup関数やloop関数より上、通常はincludeのすぐ下辺りに記述します。

``` cpp
float measure();
```

## gitの管理に追加

一通り完了したのでgitの管理下に追加します。

``` bash
cd Ambient_M5stack
git add *
git commit -m 'refactor : env change to PlatformIO'
```
PlatformIOが.gitignoreも作ってくれているので、.vscode以下等は必要そうなもの以外は追加されませんでした。

# ビルド確認＆書き込み確認

PlatformIOの下の方に並んでいるショートカットアイコン？のチェックマークでビルド
右矢印（→）で書き込み
無事動作しました。
AnsibleからDjangoのsuperuserを作成する方法

# 経緯

Ansibleでnetbox環境を作成する中で、djangoのsuperuserを作成する手順があるのですが、プロンプトが表示されてしまうためスタックしてしまう問題がでてきてしまい、解決方法探したのでその内容を備忘として置いておきます。


# 解決方法

`--noinput`を追加することでプロンプト表示せずワンライナーでできそうだったのですが、パスワードだけはどうしても入れることができずあきらめ。

`expect`モジュールも考えたが、環境変数を定義したうえで実行するとパスワードも入力できるとのことでこちらで対応。

https://docs.djangoproject.com/en/3.2/ref/django-admin/#createsuperuser

# playbook

利用モジュールは`shell`でも問題ないが、今回は`django_manage`を使いました。
failed_whenは、2回目実行時にエラーが出ないように記載したが一番いいのは、事前にユーザがいるかどうかを確認する方法。

```yaml
    - name: Create netbox superuser
      django_manage:
        command: "createsuperuser --noinput"
        virtualenv: /opt/netbox/venv
        project_path: /opt/netbox/netbox
      environment:
        DJANGO_SUPERUSER_USERNAME: admin
        DJANGO_SUPERUSER_PASSWORD: password
        DJANGO_SUPERUSER_EMAIL: admin@example.com
      register: django_result
      failed_when:
        - "django_result.failed"
        - "'That username is already taken.' not in django_result.msg"
```
WSL2の.wslconfigを作成するときはUTF-8 BOMなしで

# ずっと詰まっていたこと
 **.wslconfigが適用されない。** 配置場所もファイル名も記述内容もバージョンも正しいはずなのに。

## .wslconfigとは
WSL2を使用するときにメモリの使用量やらなんやら色々設定するファイル。
何が設定できるのかはMSのドキュメントを見に行ってください。

https://docs.microsoft.com/ja-jp/windows/wsl/wsl-config
## 必要な環境

+ windows10 Home バージョン2004 (OSビルド19041) 以降
+ 何らかのLinuxディストリビューション

### 私の環境
+ windows10 Home バージョン21H2 (OSビルド19044.1387)
+ MSストアのUbuntu(Ubuntu 20.04 LTS)

## .wslconfigの作成方法

`%UserProfile%` に `.wslconfig` というファイルを作成する。
私はメモリの枯渇を止めたかったので次のように記述。

``` :.wslconfig
[wsl2]
memory=2GB
swap=8GB
```

以下を参考に。

https://qiita.com/yoichiwo7/items/e3e13b6fe2f32c4c6120

https://qiita.com/GeekMasahiro/items/b9d00213bb02b3716625

しかし、うまく適用されなかった。

# 結論
UTF-8 BOM付きで `.wslconfig` を作成していたことが原因だった。
UTF-8 BOM **無し**で `.wslconfig` を作成しなければならない。

https://github.com/microsoft/WSL/issues/4166#issuecomment-545402362

# 検証して失敗した行動

**書き換えた`.wslconfig`を適用させる手順。**

1. PowerShellを起動。
1. `wsl --shutdown`を実行。
1. `.wslconfig`を書き換える。
1. `wsl`を実行。
1. `free -h`を実行して`.wslconfig`が適用されているか確認する。

### `memory`、`swap`の記述を変化させる。
`memory`は3GB、3Gi、1.5GB、1500MBを、`swap`は0を試した。
`.wslconfig`が適用されるかには関係なかったようで失敗。

### 改行コードをLFに変更
Linuxを完全に理解している [^1] ので、Linuxということで改行コードを変更してみた。
CRLFでもLFでも`.wslconfig`は問題なく適用される。無関係だった。

### 高速スタートアップの無効化
Win10にある高速スタートアップという機能を使用しているとWSL2に影響を及ぼすという記述を見かける。
高速スタートアップを無効化し、Win10を再起動した。
少なくともメモリには関係なかったようで失敗。

### `free -h`では`.wslconfig`が適用されているかわからないのではという検討
WSL2+VSCode+Dockerをしばらく動かし続ける。
無事にメモリが枯渇する。
`.wslconfig`が適用されている現在、`free -h`は適切に確保したメモリを表示してくれる。

``` :PowerShell
$ free -h
              total        used        free      shared  buff/cache   available
Mem:          1.9Gi        77Mi       1.8Gi       0.0Ki        32Mi       1.8Gi
Swap:         8.0Gi          0B       8.0Gi
```

# BOM付きで問題が発生するものは多いらしい

`utf8 bom とは`などで検索するとBOMが問題を起こすものが出てくる出てくる。
Unicodeで作成されたことを明記しておくモノのようだが、UTF-8では推奨されないモノらしい。逆にUTF-16では必要だとか。

https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88%E9%A0%86%E3%83%9E%E3%83%BC%E3%82%AF#%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%81%B9%E3%81%8D%E3%81%8B%E5%90%A6%E3%81%8B


知らなかったので新規作成→テキストドキュメントで作成して、内容を記述し保存、拡張子を変える要領で`.wslconfig`としていた。

 [^1]: つまりは何も理解していないということ。
[UiPath] 月や日などに "0" を足すやり方を工夫しよう

この記事は、[UiPath Advent Calendar (produced with UiPath Friends)](https://qiita.com/advent-calendar/2021/uipath) の 2日目の記事です。

# はじめに

最近ワークフローのレビューをする機会が増えていて、そのなかで時々、とても気になる実装を見かけることがあります。
それが、「9月15日」という日付をもとに、「0915」といったファイル名用の日付を生成する実装です。

上記の例では、月が1〜9である場合（＝1桁である場合）に、あとあとファイル名で使いたいなどの理由で先頭に"0"を付け足しています。このやり方をしている方、意外と多いんではないでしょうか。
実はこれ、もっとシンプルに作ることが出来ます。

# DateTime型を使おう

DateTime型を扱うことで、このゼロ付加だけではなく色々なメリットを享受できます。

## DateTime型とは？

DateTime型は、特定の日時を扱うための型です。期間ではないので、指定したある1点のみを扱うことが出来ます。ちなみに期間を扱いたいときは別の型（TimeSpan型）があります。

## どうやって使うのか

### まずは生成

もし予め、年・月・日が数値として取得／指定できるのであればとてもシンプルです。【代入】(Assign)アクティビティを用いて、次のようにすることでDateTime型のデータを生成することが出来ます。

`specificDateTime = new DateTime(year, month, day)`

`year`, `month`, `day` はInt32型が想定されています。もし文字列データしかないなら、CIntするなりInteger.Parseするなりで変換してあげてください。
これで、日付のデータが作れます。ちなみに時刻も指定したい場合は、

`specificDateTime = new DateTime(year, month, day, hour, minute, second)`

例によって `hour`, `minute`, `second` はInt32型です。

その他にも、DateTime型のデータを生成する方法はいくつかあるのですが、記事化する余力がないので、いったんおいておきます。

### ゼロ付加してみる

さて生成されたDateTime型ですが、これを使ってまずはゼロ付加をしてみましょう。
とはいっても、方法はいたってシンプルです。まずは月に対してゼロ付加をしてみます。

`monthWithZero = specificDateTime.ToString("MM")`

はい、これで月にゼロ付与が出来ました。
この `"MM"` という部分（メソッドの引数部分）を、適宜変えることによって出力される値を変えることが出来ます。

どのような文字列が、どのように置き換えられるか（どのような値として出力されるか）は、 .NET の公式ドキュメントにまとまっています。
https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/custom-date-and-time-format-strings

## DateTime型のメリット

いくつかありますが、ピックアップすると以下のようなポイントがあります。

- あとあと、任意の形に出力しやすい
- 大小の比較が出来る
- 計算（時間の加算・減算）が出来る

# まとめ

これまで文字列をコネコネするのに苦労した方もいると思いますが、DateTime型を使うことでワークフローがシンプルにできます。
シンプルなワークフローはメンテナンスもしやすいので、ぜひ実装方法のひとつとして取り入れてみてはいかがでしょうか。
Rubocopまとめ

#Rubocopとは
Rubyのコーディングチェックツールです。
Rubocopを使うことで、誰でも一定の品質のコードを書くことができます。
一部のルールについては、自動修正にも対応しているため自分で修正する手間も省くことができます。
またRubocopでは`Cop`という単位でルールを管理しています。

#導入方法
rubocopはgemのため、インストールします。

```ruby
group :development do
  gem 'rubocop', require: false
  gem 'rubocop-rails', require: false
end
```

ここでrubocopはアプリ側で呼び出す必要がないため、`require: false`をつけています。

#ファイル
##.rubocop.yml
Rubocopの設定ファイルです。
ここで、修正するcopを設定することができます。

##.rubocop_todo.yml
ここに今すぐ修正できないcopを退避させて置くことで、警告が出ないようになります。
(以下のコマンドのおかげ)

```ruby:.rubocop.yml
inherit_from: .rubocop_todo.yml
```

`--auto-gen-config`をつけることでcopを退避させることができます。
修正できたら消していって、徐々に解消できるようにしましょう。

#使い方
カレントディレクトリの全てのRubyファイルをチェックする場合

````ruby
$ rubocop
```

特定のファイルをチェックする場合

```ruby
$ rubocop hoge.rb
```

自動修正して欲しい時

```ruby
$ rubocop -a
```

#参考
Rubocop公式(https://docs.rubocop.org/rubocop/1.23/index.html)
【ProcessingをVisual Studio Codeで！】Java+libraryを自動生成する方法

Visual Studio Code(VSC)でProcessingを使う方法を紹介します！
こうすることで、ProcessingをJava環境で開発できるほか、VSCの優れたコード補完機能などを使うことができます。
Processingには強力なコード自動生成機能が備わっているため、VSCへの移行も非常にスムーズです。
## Javaファイルを生成しよう!
変換したい.pdeファイルを開き、File>Export Applicationを選択するだけです。
![Screen Shot 2021-12-02 at 22.48.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471815/88df023c-e7d5-4892-8e63-fdc2269c6665.png)
.pdeファイルのあるディレクトリにapplication.(~)>sourceが作られその中に**javaファイル**が生成されます。
**※実行にはCoreライブラリが必要です**
libフォルダにも生成されますが、重たいので有志の方が作成したビルドを使うことをお勧めします。
https://github.com/micycle1/processing-core-4/releases
VSCでJarライブラリを追加するために、Workspaceを開いて、javaファイルを開きます。
そうするとJAVA PROJECTSが出てくるので、Referenced Librariesの＋マークを押してcoreライブラリを追加してください。
![Screen Shot 2021-12-02 at 22.51.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471815/3f2603a7-f6de-29cc-d0d4-ac4b0e3f8ae3.png)
## ライブラリも使いたい!
Processingの豊富なライブラリもJarで読み込めると便利ですよね。
Githubのソースコードをビルドする必要もなく、Processingを開いてAdd libraryをしてから、
Documents/Processing/libraries/ライブラリ名/libraryの中に生成されるJarファイルを先ほどと同様に追加するだけで使えます。

Processingの自動生成機能や豊富なライブラリをうまく使えば、Javaでの開発を大幅に効率化できます。プロトタイピングやクリエイティブコーディングに活用してみてください。
備忘録 - インスト時の環境変数のエラーは自分のせい

# 環境変数のエラーが発生しました。
ソニーの非接触ICカードリーダー／ライター PaSoRi（パソリ）を購入して、うきうきでカードをかざす予定だった。

が、インストールで少し手間取った。
ネットで簡潔な説明がなかったので備忘録として書きます。

## 余談
毎年2月は確定申告ですが、ふるさと納税もe-taxで済ませられると聞いてそのためだけに買いました。

みなさんは毎年現場へ赴いているのでしょうか、
副業も増えて感染症もありますし、なおさら家に引きこもりPCだけで完結したい!!!!
とか思っているのではないでしょうか。

マイナンバーカードさえあればそれが可能なので便利な時代ですよね。

# 環境変数のエラーが発生
さっそくPCにリーダーを接続し、ソフトウェアをインストールしても
>
環境変数のエラーが発生しました。

何度やっても再起動しても治らない…。

# 理由
システムの環境変数pathは2000文字程度が上限という約束がある

くわしいことはネット記事を調べてみてください。
https://atmarkit.itmedia.co.jp/ait/articles/1510/30/news041.html

# 解決法
>
いらない環境変数を消しましょう。

環境変数には大文字と小文字の区別はないので被っているものを削除したり、存在しないpath先が意外とあります。

>
ユーザーのpathを使う

自分だけのPCなら、ユーザーのpathに入れても何ら問題はなさそうです。
(経験的観測)

# 最後に
プログラマ以上の人なら当たり前に知っていることかもしれません。
寧ろ、プログラマなどpathを利用するソフトウェアを多く入れるのはそのあたりの方ばかりなので、
誰もつまずかず、ネットに記事がないのかもしれませんね

**！！恥ずかしい！！**
[rails] travel_toの不具合とその回避策

この記事は [ビビッドガーデン Advent Calendar 2021](https://qiita.com/advent-calendar/2021/vivid-garden) の11日目です。
自分はビビッドガーデンの社員さんじゃなくて、食べチョクの開発を週３日でお手伝いしているだけの人なのですけど、普通に記事も書かせてくれるし、この間は生産者さんの農場に行って出荷の様子を見せていただくことも出来ました。
こういう分け隔てないやり方が快適でもう一年以上お手伝いをしています。

# travel_toの罠

さて、今日の話題は最近ハマったRailsの不具合について。
時刻に関わるテストをする時、[timecop](https://github.com/travisjeffery/timecop)を使わなくても、Rails標準の[TimeHelpers](https://api.rubyonrails.org/v5.2.6/classes/ActiveSupport/Testing/TimeHelpers.html)を使えばほぼ同等のことができるよ、というのは最近みんな知ってることになりつつあります。
食べチョクプロダクトチームでも、```Timecop.travel("2020-12-14")```のようなコードを``` travel_to("2020-12-14") ```に置き換えるPRを出して一括置換しました。

ところが先日、置き換えたテストが通らなくなっていることに気づきました。CIで回している間は通っているのですが、自分の手元で走らせると落ちるのですよね。

travel_toには、```travel_to("2018-01-02 15:00") ```という具合に文字列を渡すと、その文字列をマシンのタイムゾーンでパースしちゃう(to_time使っちゃう)という不具合があり([参考](https://techracho.bpsinc.jp/hachi8833/2020_12_08/101364#1-5))、[修正のPR](https://github.com/rails/rails/pull/40694)がマージされています。
ただこの修正、[Rails6.1ではまだマージされてない](https://github.com/rails/rails/blob/6-1-stable/activesupport/lib/active_support/testing/time_helpers.rb#L157)のですよね。なので、USTで動かしている自分のマシンは見事この不具合にハマってしまいました。

# パッチ

標準環境使えよという気持ちもあったのですけど、こういうタイムゾーンの不具合を甘く見ていると思わぬところで足元をすくわれるので、こういうのはちゃんとやっておきたい。一方で、CIとかみんなの環境では通ってるので、そんなに長い時間はかけてられない。
ということで、さくっとパッチを書きました。

```
# travel_to("2019-06-25") という具合に文字列を渡すと、RailsのTimezoneではなくPCのタイムゾーンでパースしてしまう不具合がある
# PRはすでにマージ済みだが 6.1時点でまだリリースされていないので、しばらくモンキーパッチを適用する
#
# https://github.com/rails/rails/pull/40694
# https://github.com/rails/rails/blob/6-1-stable/activesupport/lib/active_support/testing/time_helpers.rb#L157-L162
#
if ActiveSupport.version >= Gem::Version.new("6.2")
  raise "モンキーパッチの削除を検討してください"
end

require "active_support/testing/time_helpers"
module TimeHelpersMonkeyPatch
  def travel_to(date_or_time)
    if date_or_time.is_a?(String)
      super(Time.zone.parse(date_or_time))
    else
      super
    end
  end
end
if Rails.env.test?
  ActiveSupport::Testing::TimeHelpers.prepend TimeHelpersMonkeyPatch
end
```

・travel_toに文字列が渡されたら、Time.zone.parseでパースしてからtravel_toを呼び直すようにする
・バージョンアップしたら外すように訴えて、不必要なパッチが残らないようにする
という感じの作りになっています。

# まとめ

Rails標準のtravel_toの不具合に関する対応について書きました。
正直最初自信なかったのですけど、Rails詳しい人とか、Rubyコミッターとかハイスキルなエンジニアが増えたことで、これは間違いなく不具合だよね、パッチ書こうか、という感じで気軽に相談することが出来て、サクサクと片付けることが出来ました。

こういうのを相談できるチームっていいですよね。
ということで、そんなチームの一員になってみたい方を募集しております。

自分みたいに勤務日数を絞って業務委託で参画するやり方もあるし、正社員になってバリバリ働く働き方もあります。興味があればぜひコンタクトしてみてくださいませ。

https://www.wantedly.com/projects/636843
【Vue.js】Vue3でvue-google-oauth2を使用する

## 概要
Vue.jsからgoogleの認証を使用する時に、[vue-google-oauth2](https://github.com/guruahn/vue-google-oauth2)というライブラリを使用するという記事が、ちらほらあると思います。ただ、このライブラリは一見Vue3には対応してないように見え、Vue3で普通にライブラリをインストールしてもビルド時にエラーになってしまいます。
Vue3で使うにはどうしたら良いか、というのをメモ書きしておきます。

## 対応
ライブラリのページをよく見ると、以下の通りVue3を使う場合の参照リンクがあります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32098/6898810f-77d2-107b-3eda-1ec8eb0a82bf.png" width="500">
このリンクの先に行くと、[vue3-google-oauth2](https://github.com/guruahn/vue3-google-oauth2)なるものがあって、これを使えばいけそうです。
インストールして使用してみたところ`vue-google-oauth2`と変わらなく使用できてますので、対応としてはこのVue3用のライブラリを使うので良さそうです。
コードをめんどくさがるな！

## はじめに
Unity幼稚園のじょにです📛
今回は私が初めてプログラムを触った時にやらずに後で苦労したこと、
やっておけばよかったなと後悔したことを書こうと思います🙃

## 当時の学習スタイル
いきなりですが、みなさんは面倒くさがりですか？
私はかなり怠惰な性格をしており、動画で学習している時でも

「ここは自分にはいらないから飛ばそう」
「写すの面倒だからとりあえず眺めとこう」

という学習方法をしていました。

わかりやすく例を出すと、「Debug.Logで確認する」なんかは
一切書かずに動画の中のログを眺めて確認していました。

だって見ながら写してるし、同じ結果になるでしょ？
なんて思ってたわけなんです。

そんな学習方法で上達するわけないじゃん！って思いません？
私も今考えると酷いなって思います😂

## 実際に困ったこと
さて、その方法で私がどうなったかというと、
「Debug.Log」を書く癖がつかなくなってしまいました。

エラーが起こってもどこまで動画を遡れば良いのかわからない
Debug.Logを書くという発想が自分の中に生まれないので
どこまでコードが動いてるのか確認ができない

こうなると何がいけないのか判断できないので
動画を見返す時間や手間、
他の人に質問しようと思ってもどこまで動いてるのか不明なので
答える側にとっても時間や手間がかかるという最悪のパターンになります。

## Debug.Logの大切さ
もしかしたらこの記事を読んでる方の中には
そんなの当たり前じゃん！なんて思ってる人も多いかもしれません

ただ、プログラミングを学び始めた頃は何もわからず
「Hello Worldを書くためのもの」という認識でした

大丈夫だろうと思ってるコードでもこまめにログを出して
ちゃんと動いてるかどうかを確認するのは面倒です
ただ、それをせずエラーを起こして対処する方がもっと面倒です

どれだけ便利で大切なことなのか、
私の拙い日本語では伝わりにくいかもしれませんが
日頃からログを確認してる人にとってはそれが当たり前となるように
とっても便利で大切な1行なんです。

もし当時の私のような人がこの記事を読んでいたら
同じ手間と時間を費やす前にログを出す癖をつけてください

そしていつかまたこの記事に触れる機会があったら
何言ってんだこいつ、当たり前じゃんハハッ
っと笑い飛ばしてください

この記事が誰かの参考になりますように💫✨

## Unity幼稚園📛
幼稚園児でもわかる解説！をモットーに、
初心者の方向けにUnityやC#の用語を解説するチャンネルを運営しています🍒

https://www.youtube.com/channel/UCVzrBUq93iPUzHX2kqG-xuA
【Scratch】スプライトの大きさを無限にする方法

#スプライトの大きさを無限にする
##自己紹介
簡単に自己紹介をさせていただきます。現在高校生プログラミング勉強中、一番得意なプログラミング言語はScratch。CoderDojo春日を運営していて、日常（あらゐけいいち）が世界一好き。(アニメを見ただけで、まだ漫画は読んでいない)
技術系のブログをやっていたりします⬇️

https://www.chickensblog.com/

今回、@nakaken0629さんがやっているScratchクックブックというアドベントカレンダーに登録させてもらいました。

https://qiita.com/nakaken0629/items/f6114147a4d7caad505a

こちらの記事を知り合いの方に教えてもらい、Scratchは4年ほどやっていますが、全く知らず勉強になったので自分の知識も共有しようという感じです。
##スプライトの大きさ無限化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/964269/f74aebb5-a0e9-194d-0225-d6e5f172cb74.png)
これだけ。Scratchの性質上、1/0とかにするとinfinityを吐き出すのでそれをうまく使ってます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/964269/744396fb-456e-7f32-5e60-a86af28b0aac.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/964269/10e6e67c-acf3-69a1-7762-e0fc8fac2371.png)
ただ、普通に空のコスチューム(2*2)を追加しても大きさは無限にならないので、（27000が限界）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/964269/dc916251-b18b-2004-dc96-a602d62ee406.png)
ビットマップに変換ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/964269/3de188fa-8952-e502-25aa-77d2a0656620.png)
すると1*1になるので今度はベクターに変換をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/964269/25ea3ca9-bebb-672d-d83f-05e879a57edd.png)
そしたら0*0になるので旗をクリックとかして先ほどのプログラムを動かすと大きさが無限になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/964269/93e78a47-60b5-8fe0-73b7-c2be72aa1e31.png)
やったね！
##まとめ
ということでスプライトの大きさを無限にできました。この裏技、ステージ外にスプライトを動かせたりするのでPEN作品では使えたりします。意外と知られていないかもしれないのでおすすめです。
【テスト自動化】Cypressの概要とセットアップの方法

# Cypressとは
## 概要
・テスト自動化ツールである。
・GUIから簡単にエレメントのパスを取得できる
・Webブラウザを使ってテストできる
・JavaScriptを使って書ける
・Seleniumを利用しない
・オープンソース
・無料(一部有料機能もあるが必要ない)

### サポートしているブラウザ

・chrome
・FireFox
・Edge
・Electron
・Brave

##　Cypressの特徴
### コマンドを実行する度にスクリーンショットを保存してくれる。
撮ったスクショはGUIで確認可能。
何を実行したときにどうだったのか見返しやすい。
デバッカビリティーが高い。

![スクリーンショット 2021-12-02 20.50.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740422/7388812b-6939-b7ba-c9b4-569bf1ff0ecc.png)

#### 自動待機
実行する前にコマンドやアサーションを自動的に待機してくれる。

#### 動作の安定感
SeleniumやWebDriverを使わないため高速で安定。信頼できる。

#### スクショとビデオ録画

#### クロスブラウザテスト
ローカルまたはリモートシステムやクラウドサービスで実行可能

## Cypressでできること
・E2Eテスト
・統合テスト
・単体テスト

この記事ではE2Eテストについてのみ扱う。

## Cypressのセットアップ

### 前提条件
Node.js 10 or 12 または以降のバージョンをインストール済みであること


### 手順

### 1.Cypress用のフォルダを作る
名前は分かりやければなんでも良い。

### 2.VSコードでプロジェクトを開く
1で作ったフォルダをVSコードのプロジェクトとして開く。

### 3.プロジェクトをnpmで管理する
cdでプロジェクトファイルに潜って、

```
 npm init -y
```
　⇨ package.jsonが作成されていることを確認
　　package.jsonは依存性の管理に非常に役立つ

### 4.Cypressをインストールする
```
 　npm install cypress
```
→これで自動的に最新版をインストールをしてくれる。
　もし特定のバージョンをインストールしたいなら
```
 　npm install cypress@バージョン
```
とする。

### 5.Cypressのバージョン確認
```
 　npx cypress -v
```

リリースされているCypressのバージョンを確認したい場合にはこちら。
https://docs.cypress.io/guides/references/changelog

### 6.Cypressを開く
ターミナルで下記のコマンドを叩く
```
 npx cypress open
```

こんなGUIが開く

![スクリーンショット 2021-12-02 21.13.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740422/3ec745ee-5212-48e1-be63-e9778e980ab6.png)

GUIにはサンプルテストファイルがあるので、例えばtodo.spec.jsをopen in IDEする。
すると、自動的にブラウザを開いてE2Eテストの自動化サンプルを見せてくれる。
これが高速でなかなか気持ちいい。

これでセットアップ完了。

こんな感じのフォルダ構成になっているはず。

![スクリーンショット 2021-12-02 21.20.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740422/4aab90dd-586d-4cf9-bcef-783f554f5f8c.png)

#### フォルダ構成
#### Integration
もっとも軸となるフォルダ。
ここに.jsファイルを作って自動化コードを書いていく。

#### Fixture
アップロードやダウンロードするファイルなどをここに用意しておく。
また、ここにオブジェクトを格納しておくとデータを利用しやすい。

#### plugins
プラグインを追加するためのフォルダ。

#### support
commans.js = カスタムコマンドを作るために使う
index.js = 全てのテストが実行される前に読み込まれる。グローバルコンフィギュレーションを配置するために使う。

#### Cypress.json
コンフィギュレーションのために使う
ベースURLやデフォルト待機時間を設定する。

## テストコードの書き方

### ステップ1
Integrationフォルダ配下に.jsフォルダを作る

### ステップ2.Cypressライブラリを呼び出す
```

/// <reference types="cypress" />

it('タイトル', () =>  {
   cy.visit('https://google.com')
   cy.get('.gLFy',{timeout: 6000}).type('Automation Step By Step{enter}')
})
 

```
Mochaの書き方 it内でテストケースのタイトルをつける
cy.でcypressのオブジェクトを呼び出す
引数の中に{enter}を入れるとエンターキーを叩く。

グローバルレベルでタイムアウトを設定するにはcypress.json。

```
{
"watchForFileChanges":false,
"defaultCommandTimeout": 5000
}

```

https://docs.cypress.io/guides/core-concepts/interacting-with-elements#Actionability


##　サンプルコードの公式リファレンス
他にもサンプルコードはCypress.io(公式)にたくさんある。
こちらを参照。
https://docs.cypress.io/guides/core-concepts/introduction-to-cypress#Cypress-Can-Be-Simple-Sometimes