OmniAICreator/Qiita-1.07M huggingface dataset:
継承も考慮したメソッドチェーンを書く方法【C#】

UnityでC#のスクリプトを書いている中で、同じクラスに複数の処理をすることがあり、メソッドチェーンにできないかと工夫した結果を共有します。

# メソッドチェーンとは？

これはどのプログラミング言語にも共通する概念ですが、複数の処理を一つの式（Expression）にまとめることを言います。身近なもので言えば、JavaScriptではPromiseの使い方がメソッドチェーンですね。

```javascript
axios.get("http://example.com")
  .then(res => console.log(res))
  .catch(err => console.log(err));
```

C#でもメソッドチェーンを書くことができます。例えば

```csharp
using System;

public class Chain
{
    private string _text;

    public Chain SetText(string text)
    {
        _text = text;
        return this;
    }
    
    public void Speak()
    {
        Console.WriteLine(_text);
    }
}

new Chain()
    .SetText("Hello!")
    .Speak();
```

こんな感じです。

# 継承が入ると…？

しかし、継承が混じってくると簡単にはいきません。例えば、

```csharp
using System;

public abstract class BaseChain
{
    private string _text;

    public BaseChain SetText(string text)
    {
        _text = text;
        return this;
    }

    public virtual void Speak()
    {
        Console.WriteLine(_text);
    }
}

public class ColorfulChain : BaseChain
{
    private ConsoleColor _color;

    public ColorfulChain SetColor(ConsoleColor color)
    {
        _color = color;
        return this;
    }
    
    public override void Speak()
    {
        Console.ForegroundColor = _color;
        base.Speak();
    }
}
```

`BaseChain`が`ColorfulChain`の親クラスだとします。この時、以下はコンパイルできますが、

```csharp
new ColorfulChain()
    .SetText("Hello!")
    .SetColor(ConsoleColor.Blue)
    .Speak();
```

以下はコンパイルが通りません。

```csharp
new ColorfulChain()
    .SetColor(ConsoleColor.Blue)
    .SetText("Hello!")
    .Speak();
```

これは困ったものです。今出した例はメソッドがそれぞれ一つしかありませんからまだ耐えることには耐えますが、メソッドが増えてきたり、一回の継承じゃなくて何回も継承していくと流石に堪えます。

# Genericsと拡張メソッドの出番

これはC#のGenericと拡張メソッドで解消することができます。型が変数になるっていいことですね本当に。

```csharp
using System;

public abstract class BaseChain
{
    internal string text;

    public virtual void Speak()
    {
        Console.WriteLine(_text);
    }
}

public static class BaseChainExtension
{
    public static T SetText<T>(this T chain, string text) where T : BaseChain
    {
        chain.text = text;
        return chain;
    }
}

public class ColorfulChain : BaseChain
{
    private ConsoleColor _color;

    public ColorfulChain SetColor(ConsoleColor color)
    {
        _color = color;
        return this;
    }
    
    public override void Speak()
    {
        Console.ForegroundColor = _color;
        base.Speak();
    }
}

new ColorfulChain()
    .SetColor(ConsoleColor.Blue)
    .SetText("Hello!")
    .Speak();
```

まず、BaseChainExtensionという静的クラスを作ります。これは継承元の親クラスに実装するべきだったメソッドチェーンを実装するクラスとなります。

`SetText`の定義を見てみましょう。

```csharp
public static T SetText<T>(this T chain, string text) where T : BaseChain { }
```

`this T chain`とかくことで、自分自身の型がTと解釈され（ここでは`T` = `ColorfulChain`）、返り値の型にTを書くことができます。今のところ小クラスの型を親クラス側のメソッドの実装で静的に取得（？）するのはこれだけなのかな？と勝手に思っています。もし間違ってたら教えてください。

また、型パラメタTに対してwhere節を書く必要があります。なぜかというと、親クラスのメンバにアクセス（ここでは`chain.text`にアクセス）するためにキャストが必要になり、実行時安全性が幾分か損なわれ得るからです。

# さいごに

このように、継承を交えたメソッドチェーンをC#で書く場合にはGenericsと拡張メソッドを使えばよいのです。

メソッドチェーンってかけると気持ちいいし、なにせかっこいいじゃないですか！だから継承クラスにも使えるようにしたかったのです。

だれかのお役に立てることを願っています。
pm2のインストールではまってしまった人へ

# 結論

お使いのyarn.lockやらpackage-lock.jsonを削除してみよう。

# どうしてこうなったか

インストール時にyarnがダメだったからnpmとかまたはその逆とかでインストールしていたなあ。という記憶が蘇ってきたので多分それ。
CentOS stream 8でサービスを登録しようとしたらエラーが出た話

#経緯
CentOS stream 8でサービスを登録しようとしたらエラーが出た。

```
[root@local hoge]# systemctl enable hoge.service
The unit files have no installation config (WantedBy, RequiredBy, Also, Alias
settings in the [Install] section, and DefaultInstance for template units).
This means they are not meant to be enabled using systemctl.
Possible reasons for having this kind of units are:
1) A unit may be statically enabled by being symlinked from another unit's
   .wants/ or .requires/ directory.
2) A unit's purpose may be to act as a helper for some other unit which has
   a requirement dependency on it.
3) A unit may be started when needed via activation (socket, path, timer,
   D-Bus, udev, scripted systemctl call, ...).
4) In case of template units, the unit is meant to be enabled with some
   instance name specified.
```

ユニットファイルは以下の通り。

```/etc/systemd/system/hoge.service
[Unit]
Description=hogehoge
After=network.target

[Service]
WorkingDirectory=/home/hoge
ExecStart=/usr/bin/php /home/hoge/hogeServer.php
Restart=always
Type=simple
User=root
Group=root

[install]
WantedBy=multi-user.target
```

CentOS7.8では動いていたが、「installation configが無い」ってどういう意味かな？

#原因
[ユニットファイルの説明](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/con_unit-file-structure_assembly_working-with-systemd-unit-files)を読んでたら意味が分かった。

```
誤[install]
正[Install]
```

```
[root@local hoge]# systemctl enable hoge.service
Created symlink /etc/systemd/system/multi-user.target.wants/hoge.service → /etc/systemd/system/hoge.service.
```

動いた。
Twitter Scraper

# Twitter API 2.0 に対応したTwitterの対話収集アプリがない！

というで、作りました。　以下詳細。(同じものがgithubのレポジトリ[https://github.com/blackpopo/TwitterScraper](https://github.com/blackpopo/TwitterScraper)にあります。)

# Twitter Conversation Scraper

このアプリケーションはTwitterの3ターン以上の日本語の会話を会話をスクレイピングするアプリケーションです。

DBにはsqlite3を採用しています。

## Usage

step1

まず,secretsという名前のファイルを以下のように作成してください。
フォーマットは
```
BEARER_TOKEN=<YOUR BEARER TOKEN>
ACCESS_TOKEN=<ACCESS TOKEN>
ACCESS_TOKEN_SECRET=<ACCESS TOKEN SECRET>
API_KEY=<API KEY>
API_KEY_SECRET=<API KEY SECRET>
```

step2

```commandline
python TwitterDialogueCrawler.py 
```
を実行してください。本日の日付(JST)の前日からスクレイピングが始まります。

step3 

会話の抜き出し　または　対話の抜き出し　を行ないます。

Twitter のデータは木構造になっています。

本アプリ中のデータベース中のデータは木構造のデータで、ひとつ前のデータがTweetの発言者以外の条件で保存しています。
そのため、複数人でのreplyのチェーンが発生する可能性があります。

複数人の会話について、考慮せずに抜き出すのが、

```commandline
python extract.py --type=conversation
```

2人だけの対話データのみ取り出すのが

```commandline
python extract.py --type=dialogue
```
となっています。

## chips

#### スクレイピング対象の単語を変更したい場合

Known_words.txt を変更してください。

デフォルトでは,　知っているの頻度が 1.9 以上　かつ　話すの頻度が 1.3　以上の1880単語を抜き出しています。

また、独断と偏見により以下の20単語を追加しています。

>マンガ,映画,趣味,小説,ラブコメ,ラノベ,スマホ,恋人,彼女,彼氏,2次元,リア充,Twitter,YouTube,Netflix,オタク,アイドル,コスプレ,クイズ,雑学

単語の頻度について詳しくは[この論文]()を参考にしてください。

#### 以前に作成したデータベース中のデータよりも新しいデータをスクレイピングしたい場合。

デフォルトでは以前にスクレイピングした内容よりも、過去に戻ってスクレイピングしています。

未来に向かってスクレイピングしたい場合は

```commandline
python TwitterDialogueCrawler.py --recursive=False
```
としてください。

#### テーブルを消去して、初めからスクレイピングしたい場合

```commandline
python TwitterDialogueCrawler.py --drop_table=True
```
としてください。
【work】IT系の就活者に向けて(主にSESについて)

皆さん、就活していますか？
エンジニア歴2年の大先輩（大嘘）から、
**IT業界に入ろうと思っている人に向けて記事を書きます。**

## はじめに ～就活の手順について確認～
就活の失敗手順（友人の友人の経験談）をご紹介します。

```
専門１年　１月　　マイナビ・リクナビに登録
　　　　　２月　　リクナビで会社側からスカウトが来た！！！
　　　　　　　　　（この時点で大手に入るのはめんどくさい…）
　　　　　３月上旬　スカウトが来た会社合わせ計４社の説明会に行く。
　　　　　　　　　（どの会社も研修あるし大差ない…雰囲気いいところ行こう！）
　　　　　３月下旬　とりあえず全部面接受ける。
　　　　　　　　　　３社の一次面接突破。
　　　　　　　　　（調子乗り始める）
専門２年　４月上旬　３社の二次面談受ける。難なく突破。決定。
```
目も当てられないくらいのやらかしっぷりを、次で解説。

## 何がいけなかったのか

・専門１年の夏、インターンに不参加。
　-> 結果的に、**会社説明会だけ**で会社を決ることになる。

・専門１年のマイナビ、リクナビが出た時点で登録していなかった。
　-> スタートダッシュに遅れる。**大手は採用が早い**から…(ry

・リクナビからのスカウトの勘違い。
　-> **一人ひとり読んでスカウト送られてるわけじゃない**
　　 条件にあった人全員に送られてる。

・４社しか説明会行かなかった。
　-> 世間一般的を知ることができなかった。
　　 **福利厚生の基準がわかってない**のに**４社しか**聞かないのは勿体無い。

・一次面接受かって他の会社の説明会、面接に行かなかった。
　-> 上記と同じ。
　　 **浮かれ**ちゃうのはまだ早い。

・最終面接受かった会社に内定決定するか迫られて、急いで決めた。
　-> 焦って決めていいことはない。

## 本題：IT業界に多い落とし穴

俺の主観なので、違ったらすみません。
よくよく吟味しないで入った会社だと、以下のようなことが起こります。

**SES多発**
新卒　「SESってあるんですか。。？」
面接官「あんまりないよ！（大嘘）」

配属された部署は全員SESで駆り出される
（コロナ禍でも毎日出社。片道２時間だったり。）

**SES先が勝手に決められる**
仕事だから仕方ないのかも。
でもわざわざ会社に入ってSESでしかも勝手に決められるって…

**SESの契約時間に苦しめられる**
月の契約時間が150時間だと2月とか有給取れない。

## じゃあどうすればいいの？

・自分が社内でどんな仕事をするのか
　（雇用形態等もちゃんと確認。言質をとる）

・言語の選択、幅を広げる。
　（やりたいことだけができる会社は無い。転職して見つけるなら別）

・給与の出ない仕事はしない
　損でしかない。受け持ってしまったら責任が発生する。

・SESの稼働時間や有給を希望日に確実に取れるかどうか確認する

**確認しないとほんとに人生損する。**

## 最後に

IT業界に切っても切れない**SES**。
自分の理想の働き方をしたいなら、
就職するときに自分がどんな仕事をするのか自分がどんなふうになりたいのかちゃんと決めておくことが大事。

SESならどうして行きたいか、この会社である必要はあるのかを考えるべき。

## 最後に
iOSアプリ開発をしています。
主にSwiftですが、最近は熱が入ってきてFlutterも🦾
色々やってます。もし良かったら見てってください。

https://sogablog.net/
Material Designで紹介されていた、閉じるアニメーションを短くするやつのCSS実装方法(JS使わない)

[Material Designのアニメーションに関する記事](https://material.io/design/motion/speed.html#duration)が面白いので見ていたところ、

> Exit transitions may be faster because they require less attention than the user’s next task.

> 終了遷移は、ユーザーの次のタスクよりも注意を払う必要がないため、高速になる場合があります。

とのこと。フムフムこれはどっかで使えそう。
しかし、JavaScriptを使わない場合、どう実装するのがいいだろう？
少し考えた末、以下のように実装してみた。

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

至極単純だが、アニメーションのトリガーとなる擬似クラスと通常の状態とで、異なる`transition-duration`を指定すれば良い。ここでは、以下のように指定している。

```
  1. hover擬似クラス有り -> 開始遷移のゆったりしたduration(300ms)
  2. 通常の状態        -> 終了遷移の早いduration(200ms)
```

これで、「ふわっと表示されてシュッと消える」ようなアニメーションができる。

他にもっといいやり方あるかな？
ちなみにJavaScriptを使う場合は、いわゆるenterとleaveでdurationを変更すれば良さそう。
AWS S3に格納したファイルをLambdaで処理しS3に再格納する

AWS Lambdaの学習をしています。
S3に格納したファイルをLambdaで処理し、再度S3に格納するということをやってみたいと思い取り組んでみました。
今回はその時の学んだことを記載します。


## 予め実施しておくべきこと

- LambdaのトリガーにS3を登録する。（今回はinput/配下の.csvを対象にした)
- IAMのロールより作成したLambda関数にS3への許可を設定する。

## 学んだこと
 - boto3:AWSが提供しているPythonでAWSを操作可能とするライブラリの名称
 - lambda_handler:Lambdaの実行時に呼び出される関数

## 作成した関数

```[python]
import boto3


s3 = boto3.client('s3')

def read_file(bucket_name, file_key):
    response = s3.get_object(Bucket=bucket_name, Key=file_key)
    print("response = ", response)
    return response[u'Body'].read().decode('utf-8')

def upload_file(bucket_name, file_key, bytes):
    out_s3 = boto3.resource('s3')
    s30bj = out_s3.Object(bucket_name, file_key)
    res = s30bj.put(Body = bytes)
    return res

def lambda_handler(event, context):
    print("*** Lambdaが呼ばれました ***")
    print("event = ", event)
    # バケット名を取得
    input_bucket = event['Records'][0]['s3']['bucket']['name']
    print("input_bucket = ", input_bucket)
    # inputのキーを取得
    input_key = event['Records'][0]['s3']['object']['key']
    print("input_key = ", input_key)
    # inputのファイル名を取得
    input_filename = (input_key.split('/',1)[-1])
    print("input_filename = ", input_filename)

    # S3からファイルを読み込み
    print("*** s3からファイルを読み込みします ***")
    text = read_file(input_bucket, input_key)
    print("text = ", text)
    
    # outputのキーを設定
    print("*** outputのキーを設定します ***")
    output_key = 'output/' + 'after_' + input_filename
    print("output_key = ", output_key)
    
    # ファイルをS3に出力
    print("*** ファイルをs3に出力します ***")
    upload_file(input_bucket, output_key, bytes(text, 'utf-8'))
    print("*** Lambdaを終了します ***")
```

## 実行した結果
S3のinput/配下に任意のcsvをアップロードしたところ、
output/配下に"after_"を付与した名称でアップロードされるようになった。
店舗の商品売価変更情報をOutlookで受信したい。

小売業の本社スタッフとして勤務しています。
仕事の中で実験店舗を立ち上げる事になりました。
店舗商品売価は商品担当部署（商品部）が定期的に変更するのですが、
変更に気づかず価格アンマッチが発生する事も・・・
Power Automate Desktopを使い少しでも自動化出来ないかと思い作成しました。

#商品売価変更情報を取得しexcel出力、その後メール送信までの自動化
日々WEBページの価格変更情報をチェックをすれば良いのですが、
チェック漏れする事もあり、またチームメンバーへの共有を考えて
データ抽出とメール送信まで自動化したいと考えました。

#使用したツール
・Power Automate Desktop
・Outlook

#作成の流れ
スクレイピングを使い作成しました。
・新しいChromeを起動するアクションを使用し商品売価変更情報のURLを指定
・WEBページからデータを抽出するアクションを使用
　抽出する範囲を指定しExcelスプレッドシートに出力
・出力されたExcelデータを所定のシートに保存
・Outlookを起動しメール送信

#Power Automate Desktopのフロー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2476728/e295de33-07c3-121f-4930-4c7d4d830e81.png)

#結果
・受信メール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2476728/fdb8a083-5029-d27d-610d-00f3f688a852.png)
・Excelデータ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2476728/88013414-89b5-f71b-4b3c-a6713a0fb122.png)

#感想
今回はテストのため宛先を自分のみにして送信しましたが、
うまくいったので同じチームメンバーへの情報共有として利用出来そうです。
見落としがちな日々の商品売価変更のチェックですが、
簡単にデータ抽出からメール送信まで出来るので活用していきたいと思います。
JavaScriptで出会った無名関数について知りたい

# 無名関数とは

無名関数とは、関数名が定義されていない関数です。
無名関数は関数名を特に必要としない場合に使用されます。

# 使い所は主に2ケース

使い所としては主に以下の２ケースが多いかと思います。

## 関数リテラルを定義する場合

関数リテラルを使う場合、無名関数を使うケースがあります。
例えば日付を取得するときとか

```javascript
const time = function () {
  // 現在の日付を返す
    return new Date();
};

console.log(time());
```


## 関数の引数に直接関数を指定する場合など

javascriptでは配列操作で無名関数を使う機会が多いです。
以下の操作では、配列に格納された各要素に対してコンソールに出力する例です。

```javascript
let arrays = ['日', '月', '火', '水', '木', '金', '土'];
// 要素を順番に表示
arrays.forEach(function (element) { console.log(element) });
```

関数リテラルと関数の引数に無名関数を使うパターンとか

```javascript
let arrays = ['日', '月', '火', '水', '木', '金', '土'];

let consoleDisplay = function (element) {
    // 要素を順番に表示
    console.log(element);
}

arrays.forEach(function (element) { consoleDisplay(element) });
```
Montereyにアップデート後、zplugでインストールしたfzfが動かない問題の解決方法

## 環境
OS: macOS Monterey
zplug: 2.4.2

## zplugでの設定
下記のような設定でfzfを使用していました。

```zsh
# fzf
zplug "junegunn/fzf-bin", \
  from:gh-r, \
  as:command, \
  rename-to:fzf
export FZF_DEFAULT_OPTS='--height 50% --reverse --border'
function select-history() {
  BUFFER=$(history -n -r 1 | fzf --no-sort +m --query "$LBUFFER" --prompt="History > ")
  CURSOR=$#BUFFER
}
zle -N select-history
bindkey '^r' select-history
```

## エラーの内容
macOSをMontereyにアップデート後,fzfを使用すると下記のようなエラーがでました。

```
fatal error: runtime: bsdthread_register error

runtime stack:
runtime.throw(0x1168a0f, 0x21)
	/usr/local/Cellar/go/1.9.2/libexec/src/runtime/panic.go:605 +0x95 fp=0x7ff7bfefea00 sp=0x7ff7bfefe9e0 pc=0x1028165
runtime.goenvs()
	/usr/local/Cellar/go/1.9.2/libexec/src/runtime/os_darwin.go:108 +0x83 fp=0x7ff7bfefea30 sp=0x7ff7bfefea00 pc=0x1025a03
runtime.schedinit()
	/usr/local/Cellar/go/1.9.2/libexec/src/runtime/proc.go:492 +0xa1 fp=0x7ff7bfefea70 sp=0x7ff7bfefea30 pc=0x102ab41
runtime.rt0_go(0x7ff7bfefeaa0, 0x1, 0x7ff7bfefeaa0, 0x1000000, 0x1, 0x7ff7bfefee10, 0x0, 0x7ff7bfefee14, 0x7ff7bfefee50, 0x7ff7bfefee92, ...)
	/usr/local/Cellar/go/1.9.2/libexec/src/runtime/asm_amd64.s:175 +0x1eb fp=0x7ff7bfefea78 sp=0x7ff7bfefea70 pc=0x105292b
```

## 解決策
[fzf-bin](https://github.com/junegunn/fzf-bin)がDeprecatedになっている点にあたりをつけ、下記のようにレポジトリを変更したところ、正しく動作しました。


```diff_shell
...
- zplug "junegunn/fzf-bin", \
+ zplug "junegunn/fzf", \
...
```
AtCoder-cli 環境をDocker化した話

# はじめに

表題の通りである
AtCoder参加回数数回のひよっこであるが、テスト環境をDockerの練習ついでに仮想化してみた.
Docker がまだしっかりわかっておらず、Node + Python の、2つの環境を交えたものの作り方がわからなかったので、下記の方のimageをベースとして作成した。

https://hub.docker.com/r/beevelop/nodejs-python/

# 手順

- git clone

```
git clone https://github.com/oura-hideyoshi/Atcoder-env
```

- Docker-compose

```
docker-compose up -d
```
もしくは、VSCodeで作業される方は、拡張機能のremote-containers の機能の 
**reopen-containers**
からcontainer作成

以上で環境が構築される。手軽すぎ

# atcoder-cliを使うまでの流れ
　
下記参照

https://github.com/oura-hideyoshi/Atcoder-env#readme

今回は全てpythonで行っている

# 参考

> atcoder初心者こそ環境構築しよう！(atcoder-cli,online-judge-toolsのインストール、使い方）
> https://qiita.com/Adaachill/items/3d4ddad56c5c2cc372cd

> atcoder-cli チュートリアル
> http://tatamo.81.la/blog/2018/12/07/atcoder-cli-tutorial/
[JS]配列の繰り返し処理

アウトプットとして

JavaScriptにおける繰り返し処理（for文）を先日記事にしたので、今回は配列の繰り返し処理について。
[JSの繰り返し処理](https://qiita.com/Shi-raCanth/items/d8a04310f99abc3a44df)

##for文を使う場合

```javascript
const fruits = ['apple', 'orange', 'banana']

for (let i = 0; i < fruits.length; i++) {
	console.log(`${i}:${fruits[i]}`)
}
//出力結果
//0:apple
​//1:orange
​//2:banana
```

条件式に「配列の要素数よりiが小さい場合に実行（上記は、３より小さい場合）」として処理すると、繰り返し処理が配列の要素分実行される。

##forEach文を使う場合
こちらの方がシンプルに書ける

forEach関数の引数に関数を指定することで、実行することができます。
指定した関数に引数を定義することで、その引数には配列の要素が入ります。
下記の例では、引数はvalueですが、自由に決めることができます。添字0から最後の要素まで繰り返すたびに、引数は各要素に置き換えられます。

```javascript
配列.forEach( function(value){
  // 処理の記述
})

//例
const fruits = ['apple', 'orange', 'banana']

fruits.forEach(function (fruit, i) {
	console.log(`${i}:${fruit}`) //配列の要素が置き換わるので添字が必要ない
})

//出力結果はfor文と同じ
```

　

色々書き方があってごちゃごちゃなるのでしっかり整理したい・・・！
※補足等ありましたらコメントいただけると幸いです。
Obniz縛りハッカソン備忘録

## 概要

制作したもの: https://protopedia.net/prototype/2646
上記製作中において Obniz の有用であったメソッドなどについてまとめます。

## 全体のアーキテクチャ

使い所は以下のとおりです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133081/bda136a6-40b8-ed83-007b-0da782a11b20.png)

## Obniz

### 概要

全てのものをインターネットに繋いで幸せになろう的な理念の会社及びプロダクト
(改めて確認してみたら `Make Everything Online` とのこと)
ESP32 が使われていてブラウザで JavaScript や Python、ブロックプログラミングでコーディングすることで制御でき、管理画面など即席で多機能です。
Animation 機能でオフラインの挙動もある程度制御可能です。
(オフラインといえば数年前にカジュアル面談へ行った際に Moddable や MicroPython もありますよね的な話をしたのをふと思い出しました。)

### 今後も使いそうなもの

- Obniz 公式ボードでない ESP32 ボードに Obniz を焼く
  - 今回は M5Stack を使いました。(確か Cookpad の社内ハッカソンでいただいたもの)
  - 既に esptool で MicroPython が入っていて何かが動く状態でした。
  - それ故 Obniz 公式ドキュメント及びツールでは上手く焼けませんでした。
    - 試すべき項目
      - エラー内容てきには esptool によるもので尚且 ESP32 の初期化に失敗してる模様でした。
      - 様々な種類の M5Stack のうちどれなのかしっかり確認します。
      - その上で、Obniz CLI 経由ではなく直接 esptool を扱い該当の型番にそったオプションで ESP32 のリセットを実施するべきです。
      - その後は公式ドキュメントに沿って焼くことが可能になると思われます。
  - 注: 1台目までは無料(ライセンス)
  - 公式ボードもいろいろ搭載されてますがボタンなどいろいろ搭載されてる M5Stack での実行の準備ができているとハッカソン的には心強いのでオススメです。
- QRコード関連
    - 該当:`obniz.display.qr`
    - 引数にURLなどの文字列を入れるだけで Obniz や M5Stack 上に QR コードを表示します。
    - 使用する際の注意事項
      - 長過ぎる文字列の QR コードを描画し画面に収まらない場合があります。(仕方ない)
- チーム機能 
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133081/5ab9c9c9-fb3a-b9de-f4c1-fd7c4281f3d6.png)
    - チームに招待した(された)人同士で複数台のデバイスで管理や開発を行うことができました。

## その他

ハッカソンなので本来慣れたものを使うと有利です。
しかしあえてあまり触れてなかったものを幾つか扱え、有意義でした。
(Prisma など)
(TypeORM のデコレータな感じの型定義でなく別途専用ファイルがあり
同ファイルに基づく型定義ファイルを作成してくれます。(補完も良く効いていい感じです。))
WAFで特定ドメインのIP制限をする（Terraform）

# ユースケース

- 1台のサーバーで管理画面アプリケーションと外部公開用APIサーバーの両機能が備わっている場合など（apiに制限はかけたくないが、管理画面にかけたいというシチュエーション）

# どーやるの

## ◾️ 流れ

1. ipのホワイトリストを作成（**aws_wafv2_ip_set**）
2. Web ACLを作成（**aws_wafv2_web_acl**）
3. **aws_wafv2_web_acl**のリソースの定義において、「特定のipは許可する」、「特定のドメインへのアクセスをブロックする」という定義をrulesブロックにて、 `priority`の重み順に実装する。これによりpriorityの若い数値で、「特定のipは許可する」という実装になっているため、この数値よりも高い数値のpriorityとして、特定ドメインのblockという定義を行なっているので、前述したruleの方が優先される。

[https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl#:~:text=WebACLで複数のルールを定義する場合、AWS WAFはrules、の値に基づいて順番に各リクエストを評価しますpriority。AWS WAFは、優先度の低いルールを最初に処理します。](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/wafv2_web_acl#:~:text=WebACL%E3%81%A7%E8%A4%87%E6%95%B0%E3%81%AE%E3%83%AB%E3%83%BC%E3%83%AB%E3%82%92%E5%AE%9A%E7%BE%A9%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%E3%80%81AWS%20WAF%E3%81%AFrules%E3%80%81%E3%81%AE%E5%80%A4%E3%81%AB%E5%9F%BA%E3%81%A5%E3%81%84%E3%81%A6%E9%A0%86%E7%95%AA%E3%81%AB%E5%90%84%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%82%92%E8%A9%95%E4%BE%A1%E3%81%97%E3%81%BE%E3%81%99priority%E3%80%82AWS%20WAF%E3%81%AF%E3%80%81%E5%84%AA%E5%85%88%E5%BA%A6%E3%81%AE%E4%BD%8E%E3%81%84%E3%83%AB%E3%83%BC%E3%83%AB%E3%82%92%E6%9C%80%E5%88%9D%E3%81%AB%E5%87%A6%E7%90%86%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)

>WebACLで複数のルールを定義する場合、AWS WAFは**`rules`**、の値に基づいて順番に各リクエストを評価します**`priority`**。AWS WAFは、優先度の低いルールを最初に処理します。

## ◾️ Terraformに書き起こすと

例）waf.tf

ipのホワイトリスト

```jsx
resource "aws_wafv2_ip_set" "example" {
  name               = "example"
  description        = "Example IP set"
  scope              = "REGIONAL"
  ip_address_version = "IPV4"
  addresses          = ["1.2.3.4/32", "5.6.7.8/32"]

  tags = {
    Tag1 = "Value1"
    Tag2 = "Value2"
  }
}
```

WebACLのterraform定義 & 実装

※細かいブロック定義は割愛してます

```jsx
resource "aws_wafv2_web_acl" "example" {
  ...

  // ip許可の定義
  rule {
    name     = "rule-1"
    priority = 1

		// statementの結果と一致した場合のアクション（この場合許可）
    action {
      allow {}
    }

		// 処理するステートメント （この場合ipとの一致を検証）
    statement {
      ip_set_reference_statement {
				aws_wafv2_ip_set.example
			}
    }
  ...

  // 特定ドメインblockの定義
  rule {
  ...

  // statementの結果と一致した場合のアクション（この場合拒否）
    action {
      block {}
    }

    // 処理するステートメント （この場合対象のドメインへのアクセスかどうかをチェック）
    statement {
      byte_match_statement {
        field_to_match {
          single_header {
            name = "host"
          }
        }
        positional_constraint = "EXACTLY"
        search_string         = "対象ドメイン名（admin.example等）"
        text_transformation {
          priority = 0
          type     = "LOWERCASE"
        }
      }
    }
    ...
  }
}

```

# 補足

- コンソールからであれば以下の記事で解説されてました。

[https://dev.classmethod.jp/articles/waf-virtualhost-iprestrict/](https://dev.classmethod.jp/articles/waf-virtualhost-iprestrict/)

## 本記事サンプルコードでは動作未確認のため自己責任でお願いします☆
webpackでdevtoolにsource-mapを指定したのにブラウザで確認できないとき

webpackでバンドルしたファイルのsource mapを生成したい時は`webpack.config.js`の`devtool`プロパティの値を変更します。

```javascript:webpack.config.js
  devtool: 'source-map'
```
値によってはプロダクションビルド時にも生成されてしまうので注意です。


ただしsource mapファイルを生成しただけではブラウザのdev toolで確認することができません。
ブラウザ側の設定も必要です。

例えばChromeだと
`Prefecences -> Sources -> Enable JavaScript source maps` 
にチェックを入れることでSourceタブ内のファイルツリー内（バンドルファイルの出力先ディレクトリの配下）にコンパイル前のファイルが表示されます。

---

参考
[StackOverFlow - Disable source maps in Chrome DevTools](https://stackoverflow.com/questions/35002087/disable-source-maps-in-chrome-devtools)
[webpack - devtool](https://webpack.js.org/configuration/devtool/#devtool)
PADを使って自動でメールの添付ファイルを保存してみた

#あいさつ
皆さま、こんにちは。
とある企業でデジタル化を推進する部署に所属しています。かきもとです。
さて、今回はPowerAutomateDesktopを使用して毎週している『メールの添付ファイルを保存』を自動化してみました。
この毎週送られてくる添付ファイルはExcelですが、画像データも入っており重たいため、いつも保存に時間がかかり面倒に感じていました。そこで、自動でできればストレスが減るかも！と思い自動化に挑戦しました😊

##使用したもの
・PowerAutomateDesktop
・Outlook

##PowerAutomateDesktopのフロー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2487483/64f4a212-d572-698d-238d-ff27f3c1fd3e.png)

##制作過程
###①PowerAutomateDesktopを開き、新しいフローを追加する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2487483/124a70ce-86a5-5693-278a-42e6f44d44c1.png)
フローの名前は『添付ファイル自動保存』としました。
###②使用するアクションを追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2487483/d6c1144e-9544-0601-3537-dab8fc2df228.png)

まず、アクションの一覧からOutlookを探し、クリック。Outlookを起動しますをドラッグします。
同じようにOutlookからメールメッセージを取得しますをドラッグ。

###③取得するメッセージの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2487483/59fd1e96-f7f8-08ce-2d41-a1335a24bc10.png)
今回は添付ファイルを保存したいため、添付ファイルを保存しますに設定します。

###④Outlookを閉じて完成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2487483/57e2ef86-aac6-3e3d-16c2-d583c1991b3e.png)


##工夫した点
毎週繰り返す作業の為、添付ファイルを保存する際にファイル名に日付を追加するアクションを付けてみました。添付ファイルは保存した後、加工し複数の店舗へ送信する為、日付を追加することでわかりやすくなりました。

##感想

他にも毎日、毎週と固定化している業務があるのでPowerAutomateDesktopを使用して効率化を図ることが出来ないか、自身の業務内容を見直したいと思いました。
これからも「仕事をもっと楽にする！」を合言葉に、日々模索していきたいです🙋‍♀️
Adobe XDで作成済みのコンポーネントに後からオブジェクトを追加する方法

## XDでコンポーネントを作成

コンポーネント化したいオブジェクトを全て選択し、右クリックから「コンポーネントにする」を選択します。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242071/d48fbc45-a80e-71c1-91b5-904a209894ff.png)


コンポーネント化したオブジェクトは以下の図のように配置されます。
![スクリーンショット 2022-01-23 23.51.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242071/f0e04e16-1939-828a-723e-29dbc8b0f4af.png)


## コンポーネントにあとからオブジェクトを追加

このようにコンポーネントを作成した後、「あっ、アイコンを追加したい！」と思うときありますよね？でも、ドラッグアンドドロップしてもコンポーネントの配下に上手く入ってくれない。
![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242071/9d513af8-84fb-2dd7-86c7-159cdcc5cbe6.png)


そんなときは、コンポーネントに入れたい素材をコピーorカットして、コンポーネント配下の素材を選択してペーストしましょう！
今回の場合はアイコンをコピーして、長方形42を選択してペーストですね。
そうすると
![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242071/9e60f598-fcdf-130a-3ddd-ecc8ebff1db8.png)


コンポーネント配下に素材を追加することができました！
もちろん、複数同時でも、コンポーネントの中にコンポーネントを入れることもできます。
XDでどんどんデザインを描いていきましょう！
Git開発初心者がハマりがちなGitアンチパターンと対策

#初めに

客先でGit番長みたいな扱いになりつつあるのですが、不慣れな方が結構やりがちなミスの傾向がつかめてきました。
社内外でgit運用を広める流れがあるのでたたき台としてまとめてみます。参考にして頂ければリベースする苦労が報われて幸いです。
前提としてgit自体の設定こそ済んでおり、`git clone`か`git init`でローカルリポジトリ作成を実施して作業し始めたあたりの初心作業者がやりがちなミスを想定してます。

#パターン1 Gitなのにコピーされたファイルが増える。
例えば`test.txt`というファイルがリポジトリに登録されてた場合に、`test_0118.txt`とか`test_old.txt`を追加したコミットをされる初心者の方って結構いる場合があったりします。
これに関してはgitの概念をなんかアクセスが若干不便なファイルサーバみたいな認識になっていると陥りがちです。
特に新しい改修の方として別名ファイルを参照するように修正が入っているとdiffが結構面倒なことになりますね。
(なりました。)
##パターン1の対策
まずテンポラリの改修を複数パターン試したい場合、

* それぞれを別ブランチで試す。
* 適宜stashを駆使する。

等の徹底を図ってもらいましょう。最悪テンポラリでファイルを追加するにしてもコミット時には動作として上手くいっているファイルを元のファイル名と同じに合わせてもらい、それ以外のファイルはコミットに含まない形でコミットを作成してもらいましょう。

Gitはファイルを差分で管理する(雑な表現)という前提を理解してもらうと不必要にファイルを増やすことを避けてもらえるように思われます。

#パターン2 .gitignoreに追加すべきファイルが残っている。
これも初心者のうちはあると思います。コミットに個人の開発環境で出たログ等を含める必要は大抵の場合ないのですが、初心者のうちはよくわからずコミットに含めがちです。
パターン1に関しても言えるのですがgit使い始めの人はステージングの概念をあまり分かっていない面もあるため、差分として見つかったものを全てステージングし、コミットしてしまう場合が多いようです。

##パターン2の対策

共通で作業を行う際は先に.gitignoreを慣れている人が編集しておくのが一つの手です。
またステージングの概念に関しても早いうちに理解してもらい、良いコミットを作成するのに慣れてもらうのが良いかもしれません。


#パターン3 コミットメッセージに書くべき情報がない/コミットメッセージに不要な情報がある。
これに関しては初心者関係あるか微妙ですが起きちゃったからにはもう…ね…！って感じで記載しておきます。
以前Git活用方法を伝えた初心者の方のpushされたコミットを確認してみた所、

```
タイトル行:(変更したファイル名.c)

メッセージ本文:(変更したファイル名.c)を改修
```

のようなメッセージが出てきたことがありました。これに関してはどのファイルを改修したか？という情報に関しては基本的にすぐ見れるのでコミットメッセージに書くことは正直意味がないです。
むしろコミットメッセージに関してはwhyの部分、何を目的に改修したのかをリポジトリ毎のルールで書いて欲しいと思います。
そのままだとこの辺の作業が全く意図を理解不能になるためコミット内容の方からコミットメッセージを類推・メッセージを修正し本人に確認を取りました……。

##パターン3の対策

コミットメッセージのルールを確認し、誰かが変なメッセージを即座に指摘できる体制づくりが大切かと思われます。
今回の場合は本人がローカルだけにコミットを保持しており、発見が遅れた面があります。
特にテンポラリのコミットでない場合かつブランチを切っている場合は他の作業者に状況を見せる意味でもローカルにコミットを保持し続けず、pushはマメに行うことを徹底してもらいましょう。


#さいごに
あまり凝った内容となっていない(ある程度フェイクを含みたいのもあってボカシた表現になっているのもあります)のでわかりにくい面も多いですが、あるあると一笑して頂いたりこういう点は気を付けようなどと思っていただければ幸いです。
あくまで決してこういったコミットをした人を非難したい訳ではなく、既にできる側から教えるときこういうことに注意してもらうよう教えていくとよりスタートや理解が早まるかな等の共有ですので、うっかりやってしまった人を責めずチーム一丸となってやっていきましょう。
またGit番長の皆様へ置かれましてはこういう事例があってもめげずに頑張っていきましょう。私もこんな事ありました等言っていただけると励みになります。
ここまでお読みいただきありがとうございました。
【初心者向け】 interfaceのシンプルな使用例

## 概要
「結局インターフェースって何なの？」
Javaを勉強し始めた人の大多数が抱く疑問かと思います。
そんな新規Javaユーザーを苦しめるinterfaceを簡単な文法のみでまとめてみました。

### 実際に書いてみましょう
経験談にはなりますが、記事だけ読んでいても身につくものでは無いと思います。
この記事は簡単なコードのみで解説しているので、読み終えた後などコードをコピペして遊んでみてください。
（実際にコピペする際はFormater、Printer、Mainをそれぞれ別のファイルに保存してください。）


## 使用例

```java:Formater
public interface Formater {

	public String format(String string);
}
```
さてさて、何やらフォーマットしてきそうなインターフェースが現れました。
そうです。このFormaterインターフェースは文字列を成形するメソッドを持ちます。
※interfaceを初めてみたよって人も臆さず読み進んでみてね。

```java:Printer
public class Printer {

	private Formater formater;
	
	public Printer(Formater formater) {
		this.formater = formater;
	}
	
	//format関数の結果を出力する
	public void println(String string) {
		String target = formater.format(string);
		System.out.println(target);
	}
}
```
今度はクラスのようです。
何やらプリントしてきそうなクラスです。

勘の良い方はお気付きになったかと思いますが、
このPrinterクラスでは**コンストラクタでFormter型**を受け取ります。

既にワケわからなくなっている方は是非Eclipseなどで実際に書きながら読み進めてみてください。

そして最後に上記二つを使用するMainクラスです。

```java:Main
public class Main {

	public static void main(String[] args) {
		
		/**
		 * Name:
		 * 		PaddingFormater
		 * Function:
		 * 		文字列をパディングする
		 * 
		 * @author Pricam
		 */
		class PaddingFormater implements Formater {
			@Override
			public String format(String string) {
				//引数の文字列をパディングする処理
				return "Complete Padding";
			}
		}
		
		/**
		 * Name:
		 * 		SplitFormater
		 * Function:
		 * 		文字列を分割する
		 * 
		 * @author Pricam
		 */
		class SplitFormater implements Formater {
			@Override
			public String format(String string) {
				//例えば文字列 "HelloWorld" を "Hello World"に成形する処理
				return "Complete Split";
			}
		}
		
		//文字列をパディングするインターフェース
		Formater paddingFormater = new PaddingFormater();
		//パディングインターフェースを使用
		Printer paddingPrinter = new Printer(paddingFormater);
		// "Complete Padding"が出力される。
		paddingPrinter.println("Argument"); 
		
		//文字列を分割するインターフェース
		Formater splitFormater = new SplitFormater();
		//スプリットインターフェースを使用
		Printer splitPrinter = new Printer(splitFormater);
		//"Complete Split"が出力される。
		splitPrinter.println("Argument");
	}

}
```
はい。コード長いですね。
関数内でクラス定義すんなとか言われそうですが、それはすまん。

なんて前置きはさておき上から順にコードを見ていきましょう。

*PaddingFormaterクラス* と *SplitFormaterクラス* は*implements Formater*によりformat関数を内包しています
この時点で小難しいので簡単にいうと**この二つのクラスは*Formater*で、format関数を持っています。**

その下の処理では各インスタンスを生成して*Printer*に代入しています。
何となく見えてきましたね。今度はクラス図で見てみましょう。

![JavaInterface.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2511626/21bcacfe-ad10-8710-b9cf-f6ca04ea2c44.png)

うーーんわかりやすい。
大体理解出来ましたでしょうか。

なーんでぇ〜と初めは思うかもしれませんが、普段皆さんが使用している標準APIでも同じ事をしております。
文面でinterfaceの必要性を説くには少し厳しいものがあるので、理解を進めたい方はGofのデザインパターンなどを勉強してみる事をオススメします。


#まとめ
今回はオブジェクト指向で頻出のinterfaceを勉強しました。
理解出来ましたでしょうか。理解出来ましたね。
三大要素である多様性、カプセル化、継承。これらは一朝一夕で身につくものではありません。
今はフレームワークなどによりオブジェクト指向に触れる機会が減ってきておりますが、是非ご自身でバッチ処理などを作成し理解を深めていきましょう！！

以上、
それではまた次回の記事でお会いしましょう😊
[PHP] XAMPPのPHPエラーログを出力する(時刻付き)

#１．ログフォルダを作成する
C:\xampp\php\logs\配下に"php_error.log"を作成します。

#２．php.iniファイルを開く
C:\xampp\php\ 配下にあるphp.iniファイルを開きます。

#３．以下の設定を変更する。
**・log_errors=On**
　→もしOffの設定がされている場合、Onにします。
**・error_log = php_errors.log**
　→php_error.logのコメントがされている場合コメントを外します。

**・タイムゾーンを東京にする**
;date.timezone=Europe/Berlin
date.timezone=Asia/Tokyo
　→ログに時刻を表示する場合、上記の設定にします。

#４．xamppを再起動する。
xamppよりapacheを再起動します。

---
#テストプログラムで確認する。

以下のtest.phpをC:\xampp\htdocs配下に作成します。
そしてhttp://localhost/test.php にアクセスします。

:::note info
「[時刻][ファイル名][行数]コメント」
のようにログに表示されます。
:::

~~~php
[test.php]
<?php
header( 'Content-type:text/html; charset=utf-8' );
echo '今日は' . date( 'Y年m月d日 H時i分s秒' ) . 'です';

$fruits = array(
        'orange' => 'みかん',
        'apple' => 'リンゴ',
        'greep' => 'ぶどう'
);
error_log(date("[Y/m/d H:i:s][").basename(__FILE__).']['.__LINE__.']'.print_r($fruits,true)."\n","3","C:\\xampp\\php\\logs\\php_error.log");
error_log(date("[Y/m/d H:i:s][").basename(__FILE__).']['.__LINE__.']'.'TEST'."\n","3","C:\\xampp\\php\\logs\\php_error.log");
error_log(date("[Y/m/d H:i:s][").basename(__FILE__).']['.__LINE__.']'.'TESTA'."\n","3","C:\\xampp\\php\\logs\\php_error.log");
error_log(date("[Y/m/d H:i:s][").basename(__FILE__).']['.__LINE__.']'.'TESTB'."\n","3","C:\\xampp\\php\\logs\\php_error.log");
error_log(date("[Y/m/d H:i:s][").basename(__FILE__).']['.__LINE__.']'.'TESTC'."\n","3","C:\\xampp\\php\\logs\\php_error.log");

?>~~~
データベースのバルクINSERTについて

# バルクINSERTとは
***SQLが高速化***することです。
つまり```複数のINSERTを１つ文にまとめる```ことです。

ex)
何万件ものデータをDBに入れる時にバルクINSERTを知っていると便利。

# INSERTが遅い理由は？
SQLのINSERTをたくさん行う場合をみていきます。

⚫︎```バッチ処理```
***バッチ処理はひとまとまりのデータを一括して処理***することです。
何千何万件ものINSERT処理をする時に使います。

⚫︎```データ移行```

これらの時にバルクINSERTが有効みたいです。

# 書き方
まず通常のINSERTの書き方です。
会社の社員データを想定します。

INSERT1文の場合です。

```sql
INSERT INTO staff(id1,id2) values('va1');
```
INSERT複数文の場合です。

```sql
INSERT INTO staff(id1,id2) values('va1','va2');
INSERT INTO staff(id1,id2) values('va1','va2');
INSERT INTO staff(id1,id2) values('va1','va2');
　　　　　　　　　　　　　　　　　　　　--・
　　　　　　　　　　　　　　　　　　　--　・
```
みたいな感じで永遠にINSERT文を書くことになります。

　バルクINSERTを使うと

```sql
INSERT INTO staff(id1,id2) values('va1','va2');
                           values('va1','va2'),
                           values('va1','va2');                           
```
上のSQL文と比べたらだいぶコードが簡単になったかと思います。


# どのくらい速いか
バルクINSERTを使うと20倍速くなるみたいです。

https://datumstudio.jp/blog/postgresql%E3%81%A7insert%E9%80%9F%E5%BA%A6%E6%AF%94%E8%BC%83/

参考動画も参照してください。

# なぜ速いのか
参考動画そのままになってしまうのですが、

ex)お店で水を5本買うとき、1本ずつ買うのと5本まとめたら5本まとめて買った方が
買い物は速いですよね？

こんなイメージです。

データベースでINSERTを実行するだけでもこんな手間があります。
1.DBとの接続をする
2.クエリを実行
3.レスポンスを受け取る

これらの作業があるのでデータが何千、何万あると時間がかかりますよね？
バルクINSERTを使う方が一括でまとめてできるので圧倒的に速いです。


# バルクINSERTに注意点
・クエリには文字数制限があるみたいです。
・1000行ごとに区切るのがいいみたいです。


# Load data infile
My SQLではCSVファイルをインポートできるみたいです。

```sql
Load data infile ファイル名
into table テーブル名;
```

https://qiita.com/tsukiwakka/items/3df3e14066a99e7323f9
この辺の記事を読んで参考にしてみてください。

# 参考資料

https://qiita.com/buntafujikawa/items/91283160b0a38956655e

# 参考動画

https://m.youtube.com/watch?v=Dclre2ns_3Q&list=PL-1KBX2gDRujQaRgEByueezHBiqHP8KDD&index=11
正規表現ってなんだっけ

# この記事を書くきっかけ
自分の場合，最初は00年代に当時抱えてた課題(立上げ中の新規カスタム設備が吐いてくるCSV形式のテキストログをVisualStudioもOfficeもないオフラインのWindows端末だけの現場でうまいこと解析したかった)を解決するために辿り着いた手法が正規表現を用いてのテキストファイル解析でそれから事あるごとに使ってきてるのですが，最近改めて正規表現って何？って聞かれることがあってそういや知らない人にうまく説明する言葉を持ってないなと気がついた次第。

# さて正規表現の実用的理解
Wikipedia記事の冒頭には

> 文字列の集合を一つの文字列で表現する方法の一つである。

とあります。

https://ja.wikipedia.org/wiki/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE

けどここだけ読んでも何が出来るのかよく分からないと思います。

ただ，普段何気なく読んでるログやドキュメントに何か繰り返しで出てくる言葉のパターンを感じることはありませんか。

ログであればIDのカラムには「アルファベット3文字+数字4桁」の組合せ，日付のカラムには「数字4桁-数字2桁-数字2桁」という並び，レポートであれば「部門名+課名」の組合せ等々無意識でもこういったパターンを見たことあるという記憶はあると思います。

正規表現とは，こういった「アルファベット3文字+数字4桁」というようなパターンを表現するためのルールを定めたモノ，と理解して実用的には問題無さそうに思っています。

# 簡単な正規表現の例

先の「アルファベット3文字+数字4桁」を正規表現で表すと

``` bash:RegularExpression
[A-Za-z]{3}[0-9]{4}
```
となります。この時点でピンと来る人がいるかもしれません。

同様に「数字4桁-数字2桁-数字2桁」は

``` bash:RegularExpression
[0-9]{4}-[0-9]{2}-[0-9]{2}
```
です。
記号が多くて最初は目がチカチカするかもしれませんが少し辛抱いただくとして，勘の良い方はお気づきの通り，

* ブラケット([])は文字列集合の中の任意の一文字
* ブラケット内のハイフン(-)は範囲
* ブレース({})は繰り返しの回数

というような意味があって，以下のように解釈されます。

``` bash:RegularExpression
[A-Za-z]
# これはA〜Z(*)までの集合の中からどれか一文字(=アルファベット)を意味します
# *大文字小文字があるのでA-Za-zと書く

[A-Za-z]{3}
# このように直前の文字の繰返し回数3をつなげるとアルファベット3文字と解釈されます
# IDX のような文字列がマッチします

[0-9]
# これはお分かりの通り0から9のどれかひとつ=数字を意味します

[A-Za-z]{3}[0-9]{4}
# これらより最初のこの例は IDX0022 のような文字列がマッチします

[AUOEI]
# ちなみにこれはA，U，O,E,Iの中のどれか一文字という意味の正規表現です。
```

また，日付の例のように正規表現には固定文字列を混ぜられます。

``` bash:RegularExpression
[0-9]{4}-[0-9]{2}
# これは数字4桁の後ろにハイフンがひとつ，その後ろに数字2桁という意味になります
# 2022-01 がマッチします
```

ね，簡単でしょ？

こんな感じで正規表現を使うとあらゆる文字列と数字の組合せはもちろん，記号を使って長大なHTMLファイルの中から特定のタグの行だけ抽出，のような使い方も出来るようになります。*要センス(笑)

# 実装するとどんな感じ

ここではみんな大好きpythonでの実装例で雰囲気をお伝えできたらなと思います。

早速ですが実装例がこちら。

```python:実装例
import re

# fileは文字列リストオブジェクトの想定
for row in file:
    if re.search(r'<[Hh][1-6]>.*</[Hh][1-6]>', row):
        # このブロックにやりたい処理を書く
        pass
```
pythonの構文について詳細は省きますが，reモジュールのsearchメソッドは第一引数に正規表現パターン，第二引数に対象文字列を渡すとパターンマッチ結果をbool値で返すので，結果をif文で直接判定しています。
この例では`<H1>...</H1>`のような見出しタグで，H1からH6すべてを対象としてマッチングします。
また，表記ゆれも考慮してH1でもh1でも検出できます。

:::note warn
実装例の正規表現に「.*」というのがありますが，これも正規表現の一種です。
「.」はいわゆるワイルドカードで任意の一文字を表します。
「*」は直前の文字の0回以上の繰り返し，という意味になります。
「.*」の組合せになると"長さ0以上の任意の文字列"ということになりそこに文字列があっても無くてもマッチングするので今回のようにタグ以外は何でも良いという場面で超使います
:::

HTMLに関しては各種言語にそれぞれ優秀なパーサーモジュールが標準で存在するのでこのコードがそのまま使われる場面はまず無いとは思いますが，このような時正規表現を使わずに実装するとどうなるか考えると使いどころのヒントになるのではないかと思います。

# 最後に
実は，正規表現を使った実装の面白さ，ありがたみは後方参照による強力な置換機能やグルーピングでのキーワード抽出にあると思っていますが，本稿の趣旨と大きく逸れそうだったので割愛しました。
また，本稿では基本正規表現に準じた内容に限定していますが，これを拡張した拡張正規表現というのもあってもっと便利な記法が用意されていたりします。
これらについては調べるととんでもない量のドキュメントが見つかると思いますので興味のある方は探してみるのも良いかもしれません。
認証ディレクティブ

###ログイン
@authを使用する事でユーザーがログイン済みの際にページ内で、表示させる項目やメニューを設定する事ができます。

＜実際の使用例＞


```php:home.blade.php
      @auth
      <li>{{ Auth::user()->name  }}</li>
      <li><a href="{{ route('profile.edit') }}">プロフィール編集</a></li>
      <li><a href="{{ route('photo.create') }}">画像登録</a></li>
      <li><a href="{{ route('follow.list') }}">フォローリスト</a></li>
      <li><button form="logout-button" type="submit">ログアウト</button></li>
      <form id="logout-button" action="{{ route('logout') }}" method="POST">
        @csrf
      </form>
      @endauth
```
このように@auth～@endauthで囲む事で使用する事ができます。


###非ログイン
@guestを使用する事で非ログイン時にページ内で、表示させる項目やメニューを設定する事ができます。

＜実際の使用例＞

```php:home.blade.php
      @guest
      <li><a href="{{ route('home') }}">ホーム</a></li>
      <li><a href="{{ route('timeline') }}">タイムライン</a></li>
      <li><a href="{{ route('trend') }}">トレンド</a></li>
      <li><a href="{{ route('login') }}">ログイン</a></li>
      @endguest
```
このように@guest～@endguestで囲む事で使用する事ができます。


認証ディレクティブ下記参照用

https://readouble.com/laravel/6.x/ja/blade.html#if-statements
Apple ホームAppで暖房の予約をする

#ｵﾌﾄｩﾝから出られない
執筆時現在の季節は真冬です。この寒い季節、私は朝布団からすぐに出ることができません。
そこで、起きる前にどうにかエアコンをつけて部屋を暖めておくことはできないかと考えました。

#自室の環境
エアコンの制御はhomebridgeを母艦とするAppleのホームAppを使用しています。
iPhoneのホームAppからエアコンの任意の設定を行うことが可能です。
わかりやすく言うと、iPhoneでエアコンのオンオフや温度設定を自由に行える状態にあるということです。

また、起床時のアラームはiPhoneの標準時計アプリを使っており、8時に予鈴が1回、20分後に1回鳴ります。

#環境の理想系
・就寝直前、翌朝の気温を確認して予約をする。
・予約がある場合、8時になったらエアコンをつける。
といったものを想定しました。

ここで必要になる事は、
__(A) 就寝から8時までの間、予約をすることを記録しておく事__
__(B) その記録を元にエアコンをつける事__
の両方を満たす事です。
この環境でのこれらを満たす最適解を見つけようとしました。

#解決策

###(i) ショートカットアプリ単体での使用
ショートカット起動後、○時間後にエアコンをつける、というもの。
しかし、この動作は○時間分ショートカットをつけっぱなしにする必要があります。
ショートカットアプリ自体長時間にわたる起動に対応していないので、これはうまく動きません。
つまり、先述の(A)を満たしていません。

###(ii) ショートカットのオートメーション
オートメーション機能を使って8時にエアコンを付けることができます。
しかし、翌朝はオンにする、オフにする、といった切り替えは時計アプリのアラームのようにボタン一つで簡単にできません。
そのため、これも(A)を満たしません。

###(iii) ホームオートメーション
これもショートカットのオートメーションと同じで、オンオフを簡単に切り替えられません。

###[現状での最適解] ホームアプリでのダミースイッチ作成
簡単に説明すると、
1. ホームAppにダミースイッチを設置
2. 毎朝8時のオートメーションのショートカットを作成
   ショートカットの内容:ダミースイッチがオンの場合、エアコンをつける

ホームAppはデバイスの状態を常に反映・記録させておくことができます。ここに目をつけました。
オンオフだけを記録するスイッチ（ダミースイッチ）を設置して、そのスイッチのオンオフを毎朝判定すれば良いのではと考えました。
つまり、これまでに解決できなかった(A)をダミースイッチによって克服することができます。

#方法

##1. ホームAppにダミースイッチを設置
これには__homebridge-dummy__を使用します。
任意の名前・スイッチの種類を作成することが可能です。

https://github.com/nfarina/homebridge-dummy


自分は`暖房予約`という名称で登録しました。
<img width="350" alt="Screenshot at Oct 27 18-00-47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330454/2806246b-7f15-edce-4595-5896f3544cd8.png">

##2. 毎朝8時のオートメーションのショートカットを作成
まず、ショートカットAppのオートメーションで以下の設定でオートメーションを組みます。
<img width="350" alt="Screenshot at Oct 27 18-00-47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330454/30c98b12-8f43-321e-87db-f49dfd8cc158.jpeg">

そして、以下のようなショートカットを作成します。
<img width="350" alt="Screenshot at Oct 27 18-00-47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330454/80647f3c-6146-deab-40c0-5282dd10bbfe.jpeg">
簡単に説明すると、if分岐でホームAppの暖房予約のオンオフを検出し、オンの場合暖房をオンにするというものです。

これで完成です。
あとは就寝前までに暖房予約のスイッチをオンにすれば、毎朝8時に暖房が入るようになります。


#あとがき
本当は"○時間後にオンにする"を実行したかったのですが、本文にあるようにショートカットアプリ自体が長時間の動作に対応していないため、実装することができませんでした。
これがいつしか使えるようになればいいのですが、、、
また、翌朝の予想気温を自動取得して完全に自動でエアコンのオンオフを制御するのも面白いと思います。
今回は行いませんでしたが、冷房のスイッチも作成しても便利になるかもしれません。
カード型の中身が増減してもボタンの位置を揃えたい

## やりたいこと
WordPressでよく出てくるカード型の一覧画面。
投稿する内容によって高さが変わったりしても、ボタンの位置や高さが揃うようにしたい

### 良くない例
![悪い例.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552308/d5a4434d-0a74-f101-cc9c-bbc46fd900bb.png)

```html
<!-- ulは端折る -->

<li class="bl_card">
<a href="">

<figure class="bl_card_imgWrapper"></figure>

<div class="bl_card_body">
<h2 class="bl_card_ttl">タイトルが入ります。</h2>
<p class="bl_card_txt">
本文が入ります。本文が入ります。<br>
本文が入ります。本文が入ります。<br>
本文が入ります。本文が入ります。
</p>
<p class="el_btn">詳細はこちら</p>
</div>
<!-- /.bl_card_body -->

</a>
</li>
```
```css
.bl_card {
  width: 320px;
  min-height: 420px;
}
.bl_card > a {
  display: block;
  height: 100%;
}
.bl_card_imgWrapper {
  width: 100%;
  height: 240px;
  background: #999;
}
.bl_card_body {
  padding: 20px;
  background: #fff;
}
.bl_card_ttl {
  margin-bottom: 16px;
}
.el_btn {
  width: 200px;
  height: 46px;
  background: #999;
  font-size: 20px;
  font-weight: bold;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 20px auto 0;
}
```
### 修正後
HTMLは同じなので、CSSだけ変更

```css
.bl_card {
  width: 320px;
  min-height: 420px;
}
.bl_card > a {
  display: block;
  height: 100%;
  
  /* ①ここから追加 */
  background: #fff;
  padding-bottom: 64px;
  position: relative;
}
.bl_card_imgWrapper {
  width: 100%;
  height: 240px;
  background: #999;
}
.bl_card_body {
  /* padding: 20px; */　
  padding: 20px 20px 8px;　 /*←padding-bottomを調整*/
  background: #fff;
}
.bl_card_ttl {
  margin-bottom: 16px;
}
.el_btn {
  width: 200px;
  height: 46px;
  background: #999;
  font-size: 20px;
  font-weight: bold;
  display: flex;
  align-items: center;
  justify-content: center;
  /* margin: 20px auto 0; 　←削除 */
  
  /* ②ここから追加 */
  position: absolute;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
}
```
●結果
![修正後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552308/8b71b6f0-0c3f-0a9b-6e66-efc6b000a2ae.png)
### 考え方
- 背景の色をカード全体につける
- ボタンを配置するための余白を取る
- その余白の部分にposition: absolute;でボタンを配置する
【Python】bit 単位 でencode するために

# はじめに

今日はpython でbit 演算子の使い方を調べたのでメモします。バイナリメッセージを生成するときなどに使えると思います。

- 12bit で値を書いて、続けてuint12 で別の値を書く
- さらに続けて2bit + int38 を書く
- それらをつなげる

ことができればミッション達成です。つなげるのは bytes 型を接続するだけなので問題ない。最初の２つ、できるかな。

# 調査内容

### 12 bits + 12 bits

bytes 型で8bit 単位で扱うのが基本作戦。なので、ここでは 24bit = 3bytes のbytes を作ることを目標にします。
最初に固定された ID (1005 = 0011 1110 1101)があり、続いて指定された数字を 12bit で続く、というものです。
作戦は、二つの整数値を作って、合体させるです。具体的には、それぞれの位置にシフトさせて、or(論理和)をとる、というものです。


２進数表記は下記で確認できます。

```Python
In [2]: bin(1005)
Out[2]: '0b1111101101'

In [3]: 0b1111101101
Out[3]: 1005

In [5]: hex(1005)
Out[5]: '0x3ed'

In [6]: (1005).to_bytes(2,'big')
Out[6]: b'\x03\xed'
```

このままだと、最初の6bit は0 で2bit + 8bit で1005 を実現しています。0b11 が0x3です。

```
In [10]: 0b11*256+0b11101101
Out[10]: 1005
```

なので4bit シフトさせると、8bit (上位は0)+ 4 bit にできます。今は3byteにしたいので 12bit シフトさせます。

```
In [13]: bin(1005 << 4)
Out[13]: '0b11111011010000'
In [14]: bin(1005 << 12)
Out[14]: '0b1111101101000000000000'

In [15]: (1005 << 4).to_bytes(2, 'big')
Out[15]: b'>\xd0'

In [16]: (1005 << 12).to_bytes(3, 'big')
Out[16]: b'>\xd0\x00'

In [63]: [ f'{x:02X}' for x in int(1005 << 12).to_bytes(3,'big')]
Out[63]: ['3E', 'D0', '00']
```

指定したい番号ｎが12だとします。このあと、論理和(or)をとればOKです。なお、bytes 型の文字列表示の読み方が最初分かりませんでしたが、アスキーコードと16進数表示が混じっています。最初の１ bytes はアスキーコードです。下記を試すと分かり易い。b'>'は0x3Eのことです。

```
In [80]: f'{b">"[0]:X}'
Out[80]: '3E'
```

```
In [18]: bin(12)
Out[18]: '0b1100'

In [19]: bin(1005 << (4+8+8) | 12)
Out[19]: '0b1111101101000000001100'

In [20]: int(1005 << 12 | 12).to_bytes(3,'big')
Out[20]: b'>\xd0\x0c'

In [57]: [ f'{x:02X}' for x in int(1005 << 12 | 12).to_bytes(3,'big')]
Out[57]: ['3E', 'D0', '0C']
```

後半の12bit が 12 (0x0c) になっています。良さそうだ。


### 2 bits + 38 bits

次のお題は、2bit の後に、指定した数字(int38)を書いた bytes 型を作成する、というものです。

作戦としては、40 / 8 = 5bytes の型を作ります。

最初の2bit を仮に0b01 として、38 bit シフトさせます。

```
In [84]: a = 1

In [85]: bin(a)
Out[85]: '0b1'

In [86]: bin(a << 38)
Out[86]: '0b100000000000000000000000000000000000000'
```

書きたい値Xは、38 bit の符号付整数値です。5 bytes で書くのですが、bytes にはunsigned int からしか変換できない。
ので、負の数は２進法38bit の補数であることを考えて

```
In [214]: bin((x0 + 2**38) % (2**38))
Out[214]: '0b11011011001001010110001110111101001001'
```

としてみました。38bit あるしあってそう。
'0b11 0110 1100 1001 0101 1000 1110 1111 0100 1001'

ということで、二つの論理和をとるには、これで良いのかな。

```
In [249]: y = (a << 38 | ((x0 + 2**38) % (2**38)))

In [250]: [ f'{x:08b}' for x in y.to_bytes(5, 'big')]
Out[250]: ['01110110', '11001001', '01011000', '11101111', '01001001']
```

これでとりあえず、やりたかったことはできたっぽい。

# まとめ

bit 演算子を使って、メッセージをencode するためのpython 実装方法を調査。int38 で負の数を扱うために２進数で補数を考えるところを復習してしまった。


明日から一週間、しんどいなー。とりあえず生き延びられるかな。
(2021/01/23)

### リンク

- 素晴らしすぎる bit 演算子の解説

https://qiita.com/7shi/items/41d262ca11ea16d85abc

- 昔書いた bytes 型のメモ

https://qiita.com/XPT60/items/887af044521bec3e3ca3
【Unity】「error CS0227: Unsafe code may only appear if compiling with /unsafe. Enable "Allow 'unsafe' code" in Player Settings to fix this error.」の解決方法

Unityであるアセットを利用しているときにでたエラーの解消法をメモしておきます。

# エラー内容

```
error CS0227: Unsafe code may only appear if compiling with /unsafe. Enable "Allow 'unsafe' code" in Player Settings to fix this error.
```

# 原因
ポインタをC#内で使っているとのこと。

# 解決方法

File > Build Settings > Player Settings > Player > Other Settings から

下の方に、「Allow 'unsafe' Code」という項目があるので、
チェックをつける。

これで解決します。

# 参考文献

https://www.hanachiru-blog.com/entry/2020/02/02/220110

以上となります。
C# で純正三和音を鳴らす

C#で純正三和音を鳴らしてみる

純正三和音とは周波数比が 4:5:6 であるような和音。純正律と呼ばれる音律(つまりドレミファソラシド)のもとになる周波数関係。

めちゃくちゃ美しい響きを持つけれどもピアノとかギターとかでは実現不可能。

ピタゴラスの時代には完全五度が存在していたけど純正律の三度が登場したのはルネサンス期(ダビンチとかそのへん？ガリレオガリレイの父ビンセントガリレイあたりかね？）

## プロジェクトタイプ

Consoleアプリケーションでは機能しない。
Windows Forms か WPFとする。

## 追加する nuget package

```xml
    <PackageReference Include="NAudio" Version="2.0.1" />
```

## 音を鳴らすコード

3つのSignalGeneratorにそれぞれ 1度、3度、5度を割り当ててWaveOutEventに投げる。 

```csharp
        private void Play()
        {
            var duration = 5F;

            var chord = new ISampleProvider[] {
                new SignalGenerator()
                {
                    Gain = 0.2,
                    Frequency = 442,
                    Type = SignalGeneratorType.Sin,

                }.Take(TimeSpan.FromSeconds(duration)),
                new SignalGenerator()
                {
                    Gain = 0.2,
                    Frequency = 442 * 5/4,
                    Type = SignalGeneratorType.Sin
                }.Take(TimeSpan.FromSeconds(duration)),
                new SignalGenerator()
                {
                    Gain = 0.2,
                    Frequency = 442 * 6 / 4,
                    Type = SignalGeneratorType.Sin
                }.Take(TimeSpan.FromSeconds(duration))
            };


            MixingSampleProvider provider = new MixingSampleProvider(chord);
            
            using (var wo = new WaveOutEvent())
            {
                wo.Init(provider);
                wo.Play();
                while (wo.PlaybackState == PlaybackState.Playing)
                {
                    Thread.Sleep(500);
                }
            }
        }
```

## その他

プログラムで音を鳴らすだけなら当然 NAudio 機能のファイル演奏機能とか MIDI演奏機能を使ったほうが圧倒的に早い。
【Ruby】偶数値の取得

※初心者向け
※アウトプット練習の為
※学習の復習

開発環境
rails 6.0.4.4
ruby 2.6.5

##問題内容
配列にある値の中から偶数の数をカウントして出力するメソッドを作りましょう。

**出力例：**
count_evens([2, 1, 2, 3, 4]) → 3
count_evens([1, 3, 5]) → 0

**ヒント**
even?というメソッドを使いましょう。

**even?メソッド**
Rubyが元々用意している、対象の数値が偶数かどうかを判断するメソッドです。
対象の要素の値が偶数であれば真を返し、そうでない場合は偽を返します。

```
10.even?
#=> true

5.even?
#=> false
```


##解答

```ruby
def count_evens(nums)
  count = 0
  nums.each do |num|
    if num.even?
      count += 1
    end     
  end
  puts count
end
```

##解説
配列の中の偶数の数を出力するためにカウントした数を保持するための変数が必要なので、変数**count**を用意しています。
変数**count**をeach文のループ処理内に記述すると、処理が繰り返されるたびに**count = 0**が実行され、countの数値が0に上書きされてしまいます。
そのため、countの定義はeach文のループ処理外で行いましょう。

配列に入っている数字を**each文**で取り出し、**even?メソッド**で一つずつ偶数かどうかを確認し、偶数だった場合は**count**に1を足していきます。

**count**に1を追加するための記述は**count = count + 1**でも可能ですが、自己代入演算子を使用するとシンプルに記述できるため積極的に使用していきましょう。

each文の処理が終了し、**count**に代入された最終的な数が偶数の数となります。
input type=fileのchangeイベントのメモ

![input-file.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587858/51980a95-a2c3-183b-180b-5187a01f7d8d.png)

```html
<!DOCTYPE HTML>
<html>
  <head>
    <meta charset=utf-8>
  </head>
<body>
  <input type="file" name="profile_icon">
</body>
<script>
  const profileIconSelector = document.querySelector('input[type="file"][name="profile_icon"]');
  profileIconSelector.addEventListener('change', (event) => {
    console.log(event);
  });
</script>
</html>
```
未経験エンジニアにとって必要なスキル

はじめまして！ホートンです！
こちらの記事は第一回目の記事ですので、前半は私の「自己紹介」を書かせていただきました。
後半はタイトル通り、「未経験エンジニアにとって必要なスキル」を書かせていただきました。
すべて私自身の考え方ですので、気軽に読んでください！

##自己紹介
　2021年3月　　　大学（外国語学部）卒業🏫
　2021年9月　　　DMMWEBCAMP受講開始💻
　2021年11月　　　同スクール卒業🌸
　2022年12月～ 　現在　就職活動💼

##エンジニアを目指したきっかけ
　プロフィールに記載した大学在学中の中国留学がきっかけです。留学先は浙江省杭州市にある浙江大学というところで、中国最大手のアリババグループの本社が位置するところです。現在の中国は若者からお年寄りまでが最新技術（決済、配送、配車）を使いこなしておりました。その街に1年間住み、日常と融合したIT技術を日本ではどのように活用できるのか？という疑問からITに関する知識を学習したのがきっかけです。

##未経験エンジニアにとって必要なスキル
未経験エンジニアにとって必要なスキルは以下3つあると考えております。

１、継続力　ex)毎日のGitHubコントリビューション・Qiita記事投稿
継続力はどの分野でも必ず必要な能力です。しかし、エンジニアは継続力があるどうかでその人の力量がある程度わかると思いました。毎日コードを見ている人とたまにコードを見ている人とでは、明らかに知識量に差があります。私はどんなに簡単なコードや知識でも毎日続けて学習していくことが大事だと思っています。

２、自走力　ex)エラー対処、学習方法（Udemy,Progate）
自走力はプログラミングスクール在学中にエンジニアにとってとても必要な力だと教わりました。プログラミングスクールを卒業した方や独学者の中で、一番多い悩みは「聞く人がいない」ことです。しかし、自走力が養われている人はそもそも人に聞くよりも自分自身で調べて解決できます。ではどうやったら、自走力が養われるのか？答えは次の「調査力」にあります。　

３、調査力　ex)公式ドキュメント、エンジニアブログ
調査力はその名の通り調べる力です。では調査力によってなぜ自走力が養われるかというと、自走力は調べることでしか力が養われないからです。ではなぜ自走力と調査力を分ける必要性があるのか？これはプログラミングスクール在学時に気づけたことですが、人に言われれば、皆大抵の調査力は身に付きます。「Railsのドキュメントを見ておくといいよ！」と言われて、見たはよいものの、その後はしばらく見ない...など。
なので、自走力と調査力というのは平行して身についていかなければならないと感じました・

##終わり
以上は自分の気づいたことをまとめたことなので、少しでも参考にしていただけたら幸いです。
これからは自分の新たな発見や共有したいことを記事にしていきたいと思っております。
読んでいただき、ありがとうございました！！！
【複数入力可能】タイピングゲームのシンプルなアルゴリズムとライブラリ

## 追記

ライブラリを作ったから使ってね。

https://www.npmjs.com/package/@mogamoga1024/typing-jp

# 語ること

```
やじゅう
```

というテキストに対して

```
yajuu
yajixyuu
yazyuu
```

とタイプしてもOKとするアルゴリズムを考えます。

# アルゴリズム

```
やじゅう
```

というテキストに対して

```
(や) -> (じゅ) -> (う)
```

とオブジェクトの単方向リストを作ります。

(A)は文字Aからなるオブジェクトであり、
(A)は文字Aがaかpqrsかxyzという入力で作られることを知っています。
よって文字に対する入力チェックのアルゴリズムはそれに一致しているかを判定すればよいです。

(や)の入力が完了したら、その次のオブジェクト(じゅ)が処理対象になります。
この時、jiと入力されたとします。
「じゅ」はjiでは作れないため入力結果はNGとなります。

しかし、(じゅ)は自分が(じ)と(ゅ)に分割可能であることを知っています。
そこでjiが(じ)で入力可能かどうかを判定します。
もちろん判定はOKのため、処理対象が(じゅ)から(じ)に移ります。
(じ)はすでに文字が入力で作られているため、処理対象が(ゅ)に移ります。

後はこれの繰り返しで最後の(う)で文字が入力完了となったら処理が終了します。

---

以上のフローを図で書いておきます。
[]は入力されたキーを表しており、
((A))は現在処理中であることを意味しています。

```
((や)) -> (じゅ) -> (う)
[]

((や)) -> (じゅ) -> (う)
[y]

(や) -> ((じゅ)) -> (う)
[ya]

(や) -> ((じゅ)) -> (う)
[yaj]

(や) -> ((じ)) -> (ゅ) -> (う)
[yaji]

(や) -> (じ) -> ((ゅ)) -> (う)
[yaji]

(や) -> (じ) -> ((ゅ)) -> (う)
[yajix]

(や) -> (じ) -> ((ゅ)) -> (う)
[yajixy]

(や) -> (じ) -> (ゅ) -> ((う))
[yajixyu]

(や) -> (じ) -> (ゅ) -> (う)
[yajixyuu]
```

# 最後に

このアルゴリズムで試しに実装したタイピングゲームを貼っておきます。
[タイピングゲーム](https://mogamoga1024.github.io/Typing/)
[ソースコード](https://github.com/mogamoga1024/Typing)