OmniAICreator/Qiita-1.07M huggingface dataset:
Lookup Data Tableアクティビティを使うときに気を付けたいこと

##はじめに

この記事はUiPath AdventCalender25日目の記事です。2021年もありがとうございました！！！
https://qiita.com/advent-calendar/2021/uipath

##注意事項
今回の解説で使用するのはCommunity Licence(コミュニティ版)です。
またUiPathのバージョンは2021.10.4で説明しています。

##Lookup Data Tableアクティビティとは
2018.2のバージョン以降に使用可能なアクティビティで、Datatable内の値を見つけたいときに使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/0c779514-4c90-ff0b-53c5-0f657d8b34e6.png)

使い方：プロパティの項目が多くてわかりにくいですが、ひとまず以下の項目を埋められれば使用できます。
<b>【Input】
Datatable：検索対象のDatatable
LookupValue：探したい値
【LookupColumn】
ColumnName：探したい値のある列名
【Output】
CellValue：TargetColumnの列から見つかった(取得した)値を格納する
見つからなかった場合はnullになります。
【TargetColumn】
ColumnName：取得したい値のある列名<b/>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/516b39f8-2895-cfdf-1523-0e49c8f08e3f.png)


##まずは慣れましょう

ここでは、「順位」列が"1"位のところにある「目標」列の値を取得してみようと思います。
★「MBA取得の第一歩」がログに出ればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/1c7f25b0-31c7-0524-f3aa-3a07632209fc.png)

こんな感じでフローを作っていきます(今回は一例なのでエラーハンドリングの対応はしていません)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/80d72bd4-bf00-6e75-2787-123ffc2b053a.png)

結果は...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/c7d71f81-9276-2a01-4755-d83619bf5ca6.png)

出ましたね！
では、次の問題に進みましょう。

##本題です
それでは、「目標」列に「UiPath」の値を含む項目を取得してみようと思います。
★「UiPathの資格取得？」がログに出ればOKです。
先ほどとの違いですが、LookupColumnのColumnNameとTargetColumnのColumnNameが同じ列になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/e926ed13-5b57-eac5-26a2-cbc7991bec4d.png)

結果は...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/b60299e4-6c77-3a87-4e83-af0e4401d86e.png)
あれれ、出ていませんね。。。
じゃあ、Input側のLookupValueの値を「UiPathの資格取得？」にしてみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/34aac0ea-2738-4b43-c727-fe1a8c0d8eab.png)
結果は...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/db124aac-4f0e-074d-3a8a-f48e21e57369.png)
出ましたね！
つまり、LookUpDatatbleアクティビティは
<b>探したい値と完全一致=取得できる
探したい値が含まれた値=取得できない(null)<b/>

ということになります。

##じゃ、対象の文字を含む値を探すには？
人によりやり方はあるのかもしれませんが、自分はこのやり方を採用することが多いです。
これはFor Each Rowアクティビティで変数dataaa(Datatable)をループして、列名「目標」のところに「"UiPath"の文字を含むものはあるか」という条件式を設定し、"UiPath"を含む値が見つかった場合は変数straaa(文字列)に値を格納してループを抜けるようにします。
(Elseは設定なし)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/d22cc456-c301-1392-860b-b72d23d05401.png)
結果は...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/81db44fb-4998-e04b-ecca-7835ffaed57e.png)
取得できましたね！

##まとめ
Lookup Data Tableアクティビティを使う際は検索したい文言が「単語でくるのか」「文章で来そうなのか」を推測しておくことが大事ですね。
また今回はデモの都合上プロパティに設定した値がハードコーディング(設定値を直接書いています)になっていますが、外部の設定ファイルで設定しておき、変数で対応ができるようにしておくとよいと思います。
最後までお読みいただきありがとうございました。
【Python】tqdmをインポートする際のエラー（警告）対処法

## 環境
+ Microsoft Windows 10.0.22000.318（21H2）
+ conda 4.11.0
+ Python 3.8.12.final.0

# 現象
このようにインポートすると、

```py
from tqdm import tqdm_notebook as tqdm
```
以下のように `TqdmDeprecationWarning` が出る。

```
TqdmDeprecationWarning: This function will be removed in tqdm==5.0.0
Please use `tqdm.notebook.tqdm` instead of `tqdm.tqdm_notebook`
```

## 対処法
このようにインポートすることで、警告が消える。

```py
from tqdm.notebook import tqdm
```

## 参考
https://blog.neko-ni-naritai.com/entry/modern-tqdm#Jupyter%E4%B8%8A%E3%81%A7%E3%81%AEtqdm%E3%81%AE%E3%83%A2%E3%83%80%E3%83%B3%E3%81%AA%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88%E6%96%B9%E6%B3%95
わーけーしょん環境をいずの山の中に作ったら・・・

# はじめに
この記事はシスコの有志による Cisco Systems Japan Advent Calendar 2021 (2枚目）の 25日目の記事です。
　2021年版 1枚目: https://qiita.com/advent-calendar/2021/cisco
　2021年版 2枚目: https://qiita.com/advent-calendar/2021/cisco2 (これ)

今回はライフハッキングネタで、ほぼ在宅となった去年からいろいろと探してきた「自分に合ったワークスタイルとは？」という質問にたいする一つの答を得たのでは？と思える節があり、思い切って投稿することにしました。

題して「わーけーしょん環境をいずの山の中に作ったら・・・」

ぜんぜんテッキーなネタで無くてごめんなさい。でも左脳だけじゃ無くてしっかり右脳にも刺激を与えて心のバランスを保ちながら働く為には環境も大事じゃないでしょうか？ということで・・・

# これまでのあらすじ
今までの職場と家の往復する中で一つのリズムを得ていたワークスタイルがコロナ禍により崩れ、ほぼ家の中という環境なってしまい、気づいたことは「やはり働く環境は大事なのだ」ということ。会社と家だけでは無く、カフェやお店、駅、たまにグリーン車で帰りに飲むビール、などなどの様々な環境から受ける刺激はINPUTとして重要なのだと。
であれば、私の好みに沿う環境、移動経路と手段を、と紆余曲折探した結果が：
伊豆の山奥の中古別荘
程度良好の中古スポーツカー
というわけで最近は片道1．5時間の「通勤」を135号線の海岸線沿い行き来する日々過ごしております。
ちょっと脱線しますが、日本の不動産は首都圏をちょっと離れるとずいぶん安いですね。私が買ったの築50年の3LDK戸建てですが一応リノベされていて利息が1〜2％の今、本当に毎月のお小遣い感覚でワーケーション拠点を得られると言うのは良いご時世だと思います。キャンピングカーやトレーラーハウスなどがセカンドハウスとして話題になるのも、Creativityには環境が重要であり、日常と非日常などの切り替えでその渇望を満たすということが、昔の文豪や豪商でなくても気軽にトライできる時代になったということかなとも思いました。

# ちょっとITネタ
山小屋を買ったのはいいが、インターネットはどうなのよ？という点、気になりますよね？リモートワークのクオリティーはインターネットの質に依ると言っても過言ではございません。ファイバーがなかなか来てくれない中で4Gモバイルルーターを使っていましたが、普段は良くてもどうしても切れたり、会議中の音飛びとかが発生してヒヤヒヤなことがありました。ただ6ヶ月の待ちの末に11月、ついにFLETS光が来てからはとても安定した環境で、日本って凄いな、と思いました。
![スクリーンショット 2021-12-24 19.13.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92380/14aaf23a-9281-4050-3d3e-949c949640ee.png)
因みに静岡県はNTT西日本の管轄なのですね。遅延も西海岸まで140ｍｓフラット。
ちなみに私はSONETさんのFLETS光プラスというサービスを使わせて頂いていますが、IPoEというV6のサービスで、対応のルーターをネットでポチして接続すれば何の問題も無くつながりました。（PPPoEは過去のものになったのか！）FAST.COMで測定するとMERAKIのMR33の無線経由で200Mbpsくらいですが、そんなもんかなと。安定しているので使用感は横浜の自宅に引いたNuro光（2Gだっけ？）よりも良い気がしています。（プラシーボ効果かも）
ちなみに、別荘地なので済んでいる人もたまーにいますが、周りは家があってもほぼ空き家状態（GWなどに家族ずれでご利用というご家庭がほとんど）なので無線環境は抜群にいいです（笑）WIFI6はちょっと出番なさそうです。

# ライフハックねた
私がここに決めたいちばんの理由はこちらのVIEWです。林の中から見下ろす相模湾は明け方と夕暮れがとても美しく、四季折々、月の満ち欠けで違う面持ちを見せてくれます。
![IMG_4838 (1).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92380/954a526f-625b-5719-342d-f9f7227fec77.jpeg)
このビューと森のマイナスイオンに癒やされて、仕事に、創作活動にとインスピレーションを得ながら活動しているわけですが、いつもここに滞在するわけにはいきません。（家事や妻、子供達とのコミュニケーションも大事ですからね）

でも、家にいて仕事して、煮詰まっちゃうとき、ありますよね。そんなときは近所を散歩したり、買い物行ったり、テニスしたりとか、私にもルーティンがあるのですが、「今伊豆はどうなんだろー」と思う瞬間があるわけです。
そこで、「そうだ、余っていたRASPIにカメラを付けて定点観測すれば」

というわけで今回、使ったのはRasPi4
カメラはこちらをポチ
https://www.amazon.co.jp/gp/product/B086MK17K5/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1

![RasPi4.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92380/d8e735bb-2cc8-cc2e-dd95-f7028bf1e7a5.jpeg)
砲台の様に外をにらんでいるのがカメラ付きのRasPi4でその下にあるのがRasPi3（ThousandEyesのエージェントとして使ってます。）

後は、STILL画像を保存して、メールで送信するだけの簡単なスクリプトです。(いちばん短いコードかもｗ）

```
fn=/home/name/image/$(date +%Y-%m-%d-%H%M)
raspistill -t 1000 -o ${fn}S.jpg
echo "image from Ize" $(date) | mail -A ${fn}S.jpg -s "image" hogehoge@mail.com
```
あとはCronで10分間隔で回しただけです。（サイトにアップするとか動画にするとかいろいろアイディアはあったのですが、クリスマスに間に合わず・・・）
因みに映像としてつなげるとこんな感じです
https://youtu.be/UhwzSXZedUQ

# 所感
何となく今思っているのは、1と2の間には大きな隔たりがあると言うこと。自分の居場所も2つのバリエーションを持つことでいろいろ違いが見えてくるし、右脳と左脳もバックアップじゃ無く機能分化していて主従関係にあるとか、進化の過程で獲得したConcisousの由来にも関係しているとか。参考文献↓（まだ半分も読めていないですｗ）
https://www.amazon.co.jp/Master-His-Emissary-Divided-Western/dp/0300188374

メリークリスマス！
Bash for文を使った複数にサーバー対してのPING疎通確認

HPC用途のクラスタシステムなどで数多くのノードを一斉に構築することがある。
OSのインストール完了後にマスターノードとスレーブノードの間で簡易的にネットワーク疎通確認を行う際に下記シェルスクリプト使うことでことでログを残しながら疎通の確認を行うことができる。

###**■シェルスクリプト(for文)**

```
【例】pingtest.sh

#!/bin/bash
{
for ipaddr in 192.168.10.{1..10}  #IPアドレス範囲
do
  ping -c 1 "$ipaddr" > /dev/null 2>&1　#pingの回数は1回

  if [ $? -eq 0 ]; then
    echo "[OK] Ping -> $ipaddr"　#応答あればOK
  else
    echo "[NG] Ping -> $ipaddr"　#応答なければNG
  fi
done
} | tee pingtest.log  #ログファイルに保存
```


###**■実行**
```
$ bash pingtest.sh
```
###**■結果**

```
$ cat pingtest.log 
[NG] Ping -> 192.168.10.1
[OK] Ping -> 192.168.10.2
[OK] Ping -> 192.168.10.3
[NG] Ping -> 192.168.10.4
[OK] Ping -> 192.168.10.5
[NG] Ping -> 192.168.10.6
[OK] Ping -> 192.168.10.7
[OK] Ping -> 192.168.10.8
[NG] Ping -> 192.168.10.9
[OK] Ping -> 192.168.10.10
```
###**■補足**
この方法はCUIで死活チェックで行うことを想定している。
数多くのクラスター管理ツールではGUIのモニターを持っているが、
手っ取り早く死活チェックを行うならこの方法も検討してみていいと思う。
rails7からhelperを使って生成されるtypeがhiddenのinputタグでautocomplete属性にoffが指定される様になった

# 概要

* `hidden_field_tag`
* hidden_field_for_checkbox

などの`<input type="hidden">`を生成するヘルパーがあるのですが、これらを生成する時に強制的にautocomplete属性にoffが指定される様になりました。

```ruby
# Before
$ hidden_field_tag 'tags_list'
=> "<input type=\"hidden\" name=\"tags_list\" id=\"tags_list\" />"

# After
$ hidden_field_tag 'tags_list'
=> "<input type=\"hidden\" name=\"tags_list\" id=\"tags_list\" autocomplete=\"off\" />"
```

# 詳細
Firefoxのバグでhidden fieldのautocompleteに意図しないランダムな値が入力される可能性があるとのこと。
例えばCSRF保護などrailsはたくさんhidden fieldを使っているので意図しないエラーが発生するリスクがありました。
autocomplete="off"を指定することで回避する様にしたとのことです。

# 参考
https://github.com/rails/rails/issues/42610
https://github.com/rails/rails/pull/43280
上司が話を聞いてくれない！新米エンジニアの要点整理術

こんにちは。エンジニアリング マネジャーをしている今野です。
この記事は[リンクアンドモチベーション Advent Calendar 2021](https://qiita.com/advent-calendar/2021/mcs)の9日目の記事です。

## これはなにか

新しいフレームワークを導入したいとか、開発プロセスを変えたいとか...
学習していると、気になること、やってみたいことが出てくるもの。

ただ、**どうしたら決裁する人を動かす技術提案ができるのか**
挑戦したいエンジニアに向けて、僭越ながらヒントを書き記したものです。
個人的な経験に基づくものですが、少しでも参考になれば幸いです。

※ 私自身もエンジニアのマネジャーをやっておりますが
なんとなくOKを出しがちなので、自戒を込めてちゃんと言語化しようという記事です。


## 解決したいテーマ

開発のお仕事をしていると「効率上げたいからアーキを再構築したい！」とか
「開発プロセスをもっとTDDにやりたい！」といった相談を上げたりすると思います。
ところが、意気揚々とリーダーに相談するとなんとなく受けが悪い…。

そんな**「せっかく考えた技術提案に共感してもらえない！」**状態を今回の課題としています。
技術でチャレンジできる環境を、自分の提案で実現できたら最高じゃないですか！


## 原因らしいこと

技術的には面白い提案であるにも関わらずどうも共感が得られない場合
およそ次の3つの「_よくわからない_」が発生していることが多いように思います。

* **解きたい課題が何なのか** _よくわからない_
🤔ダメな例： 「効率悪くて、レガシーで、システムの見通しが悪くて...」


* **どんな選択肢があるのか** _よくわからない_
🤔ダメな例： 「絶対このライブラリ入れるのが良いですよ！」


* **やる気があるのか** _よくわからない_
🤔ダメな例： 「他社と同じプロセスを導入すべきだと思います。」

上記3点に気をつければ、だいたい共感が得られると言って良さそうです。

## 提案のコツ

なにもきれいなプレゼンを作って提案しましょう！という話ではなく
頭の中でちゃんと整理してから相談すれば、わかってくれるはずです。
たいていの場合、リーダーもそれなりに経験を積んだ手練なのですから。
3つのコツを紹介していきたいと思います。

* [【Point #1】 課題が何なのか特定する](#point-1-課題が何なのか特定する)
* [【Point #2】 解決の選択肢を考える](#point-2-解決の選択肢を考える)
* [【Point #3】 やり抜く意思を主張する](#point-3-やり抜く意思を主張する)


### 【Point #1】 課題が何なのか特定する

コードの見通しが悪いとか、バグが出やすいとか、やる気がでないとか
ソフトウェアには様々な問題があるわけですが、それらはまだ**課題**ではありません。
枝葉の問題から解決しようとすると、いくら時間があっても足りなくなってしまいます。
まずは、根本的な問題を特定して、**課題**を明らかにしましょう。

"根本"というと難しく聞こえますが、シンプルに2 Stepで見つけられます。

**Step 1：問題をディレクトリ構造で整理する**
抜けもれなく問題を見つけるために、ディレクトリで整理する。MECEですね。
> **Before:**
> コード調査が大変、開発が大変、テストできない、やる気が出ない
> インシデント多発、MTTR低い、スキルアップできない、負債が蓄積 etc...
>
> **After:**
> 低い生産性/
> ├プロダクト/
> │ ├コードの複雑性
> │ └テストコード不足
> ├プロセス/
> │ ├開発
> │ └運用/
> │ 　└通常運用
> │ 　└インシデント
> └エンジニア/
>　├スキル不足
>　└モチベーション低い

**Step 2：問題をリスト形式でなく、矢印形式に変える**
上記で出てきた課題たちの因果関係を明らかにするために、問題を矢印でつなげる
> **After：** 
> **コード複雑＋テストコード不足**
> → コード調査が大変
> → 日々の開発・運用で手一杯
> → 新たな挑戦ができない
> → スキルアップできない
> → 開発のモチベーションが低い

実際の現場では上記のサンプルほど単純ではないと思いますが
まずは矢印の出発点を根本の**課題**として認識できるはずです。


### 【Point #2】 解決の選択肢を考える

問題を解決するとき、複数の技術の選択肢を持っているのがエンジニアというもの。
1つしか選択肢がないと「ちゃんと検討できていないのでは？」と不安になってしまいます。
提案するときは、松竹梅で3つくらいプランを出すと良いでしょう。

> **Before:**
> 「Vue.jsでフロントを開発しましょう！」
> 
> **After:**
> ・| プラン① | 学習コスト:小 | 開発サイズ:小 | Vue
> ・| プラン② | 学習コスト:中 | 開発サイズ:中 | React
> ・| プラン③ | 学習コスト:高 | 開発サイズ:大 | Angular
> ⇒ 「プラン①にしましょう！」

さらに技術的な面白さも比較項目に入っているとモチベーション上がります。←私見


### 【Point #3】 やり抜く意思を主張する

合理的にロジックを説明するのも大事ですが、伝える側の心の声も欠かせません。
逆に合理性だけでは、遠巻きに評論家として言っているだけに映るリスクもあります。
最後までやり抜く意思表明として、欲求や感情を伝えることも大切にしましょう。

> **Before:**
> 「開発効率1.5倍が見込まれるのでTypescriptを導入したいです。」
> 
> **After:**
> 「もう変数が把握できない現在のコードベースでは正直つらいです！
> 　開発効率1.5倍にするのでTypescriptを導入しましょう！」

ポジティブに、エンジニアとして挑戦したい旨を伝えるのもオススメです。
挑戦したい気持ちを無下にするリーダーはそういないはずです。

## まとめ

エンジニアが、もっと技術の提案ができるようになると良いなぁ、という気持ちで
提案までの要点整理を3つのポイントで書き起こしてみました。

上司やリーダーがエンジニアの場合は、なんとなくで合意が取れるケースもありますが
周囲の仲間たちに納得してもらうためにも、上記の観点は意識してみると良いと思います。

提案が苦手だな、という方に少しでも伝わるものがあれば幸いです！
関数のまとめ

`puts`のように、関数のように見えるものもメソッドであるRubyに関数はないと思われると思いますが、Rubyには様々な関数があります。

## メソッド

### 定義

#### 定義

```rb
def method(argument, &block)
end
```

仮引数の直前に`&`があると、このメソッドに渡されているブロックがProcのオブジェクトとしてこの引数に格納されます。

```rb
def block_class(&block)
  block.class
end
```

```irb
irb> block_class {}
=> Proc
```

Ruby 3.1では、`&`を渡すことで、ブロックを他のメソッドに渡せます。

```rb
def method(&)
  def another(&)
  end
end
```

#### 一行メソッド定義

Ruby 3から使えます。

```rb
def square(x) = x * x
```

#### 動的な定義

以下をメソッドにします。

* Method
* UnboundMethod
* ブロック
* Proc

```rb
def foo
end
define_method(:bar, method(:foo))
```

### 呼び出し

Rubyは`()`を省略できます。

```rb
method() {}
method {}
```

#### オブジェクトをブロックの代わりに渡す

to_procメソッドが定義されたオブジェクトの前に`&`をつけてメソッドに渡すと、そのメソッドが呼び出されるときにto_procが呼び出されます。

```rb
class Foo
  def to_proc
    proc do |item|
      p item
    end
  end
end
```

```irb
irb> [1, 2, 3].each(&Foo.new)
=> [1, 2, 3]
```

## ブロック

ブロックはメソッドに渡す無名関数です。

### 定義

`do`と`end`または`{`と`}`に囲まれた式をメソッドに渡します。

### 呼び出し

仮引数を使って呼び出す場合はProcの呼び出しと同じです。

```rb
def foo
  yield(1, 2)
end
foo { |a, b| [a, b] }
```

## Proc

Procは二種類あります。

1. Proc
2. lambda

### Procとlambdaの違い

#### 引数の扱い

lambdaのほうがより厳密です。引数の数が違っているとエラーになります。

```irb
irb> proc { |a, b, c| p a, b, c }.call(2, 4)
=> [2, 4, nil]
```

### 定義

#### Proc

```rb
Proc.new {}
proc {}
```

#### lambda

```rb
lambda {}
->() {}
```

### 呼び出し

`.()`と`::()`はcallメソッドの糖衣構文です。

```rb
fibonacci = lambda do |number|
  case number
  in 0 then 0
  in 1 then 1
  else
    fibonacci.call(number - 2) + fibonacci.call(number - 1)
  end
end
fibonacci[10]
fibonacci.call(10)
fibonacci.(10)
fibonacci::(10)
fibonacci === 10
fibonacci.yield(10)
```

## Method

Methodはメソッドをオブジェクト化したものです。

### 生成

Object#methodによりオブジェクト化します。UnboundMethod#bindでUnboundMethodをレシーバにバインドします。

```rb
class Foo
  def foo
  end
end
Foo.new.method(:foo)
Foo.instance_method(:foo).bind(Foo.new)
```

### 呼び出し

呼び出しはProcの呼び出しと同じです。

## UnboundMethod

レシーバを持たないメソッドを表すクラスです。

### 生成

Module#instance_methodやMethod#unbindで生成します。

```rb
class Foo
  def foo
  end
end
Foo.instance_method(:foo)
Foo.new.method(:foo).unbind
```

### 呼び出し

呼び出す前にbindする必要があります。

## お詫び

投稿が遅くなりすみませんでした。
RubyとRuby on Railsの違い[3行で要約]

#結論

```
・Rubyはプログラム言語の一つ。（他にはJava,PHPなど）
・Ruby on Railsはフレームワークの一つであり、言語ではない
・プログラミング言語Rubyで作成されているので、Ruby on Railsという名前になっている。
```

#Ruby on Railsとは
Webアプリケーションフレームワークの１つです。Railsとも呼ばれています。

###Webアプリケーションとは
ブラウザを介してクライアントにサービスを提供する

###フレームワークとは
アプリケーションを開発するとき、その土台として機能させるソフトウェアのこと。

##Ruby on Rails 特徴

```
・MVCアーキテクチャ
・DRY(Don’t Repeat Yourself)
・CoC(Convention over Configuration)
```

###MVCアーキテクチャ
Model,View,Controller設計法に基づいて開発を行います。

###DRY(Don’t Repeat Yourself)
DRY原則とは、同じこと（ソースコード）を繰り返し記述するのは避けよ

###CoC(Convention over Configuration)
設定より規約
SwiftでTwitterでよくあるハートやコメントのボタンを作る方法

## Swiftでハートやダウンロードのiconの作り方がわからなかった
どうやってこの問題を解決したかというと、x-codeにButtonやimageViewを変更する機能が備わっていた!
しかし、誰もその方法を紹介していなかった😵‍💫
**どうやって気づいたのか?**
こちらの記事のサンプルを見ながら、「これボタンか?、どんな設定されているのか?」を調べたら理解できました。
https://qiita.com/onishi_820/items/658c626554e09e227fca

## 設定はユーティリティー・エリアの属性インスペクタで設定できた
スクリーンショット
![スクリーンショット 2021-12-25 9.16.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303722/0d57969b-bf49-a57e-7305-84828418b228.png)

ButtonやimageViewなど部品をクリックして選択された状態で右の画面のImageの中から、messageボタンを作りたかったら、Imageからセレクトボタン押してmessageを選択する。
messageと入力すると候補を表示してくれる。

完成したサンプル
![スクリーンショット 2021-12-25 9.32.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303722/2c4500ad-77fe-4a29-f4bb-e0a38652a029.png)

ButtonとLabelとimageViewだけで作られてます。

## 最後に
プログラミングスクールに通い始めて、自分で調べながらTwitterクローンを作るように課題を出され最初は、なぜチュートリアルがない🤯💢
と、高い金払ってるので機嫌悪くなりましたよ。
自分で調べて作っていくことで理解が深まるのですが、どうやって作ればいいのかネットの記事を参考にしますが、中々できない...
YouTubeで海外の動画を見たり、サンプルコードを入手してみて動かしてみるのが早く問題解決に繋がるが、いつもそう簡単は行かないので、相談できる人を作っておくのが良いと思います。

**悩んだときはどうするかというと**
- プログラミングスクールに通う
- メンターを雇う
- 独学しただけでは勉強にはならないので無理しない

お金と時間を確保する必要がありますが、最短で転職ができると思います。自社開発企業を最初から選ばなければ...
再帰関数とは何ぞや？

# はじめに 
Udemyで学習していると、再帰関数に遭遇し、まるで理解できなかったので軽く学習してみました。

# 再帰関数とは?
> 関数内で自分自身の関数を呼び出す関数
> https://www.wakuwakubank.com/posts/463-javascript-function-advanced/#%E9%AB%98%E9%9A%8E%E9%96%A2%E6%95%B0

はて？
関数の中で自分自身を呼び出す関数って何でしょうか？
具体例を見てみます。

# 具体例

```javascript:main.js 
const func = (num) => {
  if (num < 3) {
    return 1;
  }

  return num * func(num - 1);
}

console.log(func(5));
// 60 
```

仮引数に5を渡した簡単な階乗計算です。

この時のfunc(5)の戻り値は下記のようになります。

```javascript:main.js
return 5 * func(4)
```

今度は仮引数に4を渡しており、func(4)の戻り値は、

```javascript:main.js
return 4 * func(3)
```
となります。
これを繰り返していくと

func(2)の時にif文を通るのでfunc(2)の時の戻り値は1となります。

結果としてfunc(5)の戻り値は

```javascript:main.js
return 5 * 4 * 3 * 1
// 60
```

となります。

# さいごに
再帰関数の動きを少しだけ理解できたように感じます。
ついでにchromeのデバッガーで確認するとコールスタックにfunc関数が積み重なっていくのが確認でき、再帰終了文がないとスタックオーバーフローを引き起こす理由がわかりました。

# 参考
https://qiita.com/ryo2132/items/4bedeec846d0427f1ac7
https://qiita.com/jumpyoshim/items/20e6b5e70efa466699b4
https://developer.mozilla.org/ja/docs/Glossary/Call_stack
https://www.wakuwakubank.com/posts/463-javascript-function-advanced/
【作業メモ】ddタグの中にulを入れるか ddタグを複数使うか

# マークアップをしていて疑問に思ったことのメモ
本エントリーは個人的な作業メモです。


## ddタグの中にulを入れるか ddタグを複数使うか
`dd`タグに複数項目を定義したいときに、`ul`タグを入れるか`dd`タグを複数使うかどちらが適切なのかわからない。

### `ul`タグを入れる例

```html
<dl>
	<dt>フシギダネ</dt>
	<dd>
		<ul>
			<li>くさタイプ</li>
			<li>どくタイプ</li>
			<li>たねポケモン</li>
		</ul>
	</dd>
</dl>
```
引用元：[フシギダネ | ポケモンずかん](https://zukan.pokemon.co.jp/detail/001)

### `dd`タグを複数使う例

```html
<dl>
	<dt>ヒトカゲ</dt>
	<dd>ほのおタイプ</dd>
	<dd>とかげポケモン</dd>
</dl>
```
引用元：[ヒトカゲ | ポケモンずかん](https://zukan.pokemon.co.jp/detail/004)

### メモ

ぐぐると、入れ子の構造が正しいかどうかの記事ばかりヒットして、意味論的にどうなのかというものが見当たらない。そもそも例に挙げた2つがそれぞれどう違うのかを言語化できてないので、文書構造的にどうなのかを考えるところから始める。
UiPath 引数に関する考察


この記事は [RPAコミュニティアドベントカレンダー2021](https://adventar.org/calendars/6396 "RPACommunuty")の 25日目 の記事でもあります。

## 皆もすなるQiitaといふものを、儂もしてみむとてするなり。

と言う訳で、こん＊＊は！はなっち！です。

今回は、ちょっとしたやってみた！系の内容です。

UiPathで共通的な機能は、個別のXAMLファイルを作成し、それを「ワークフロー ファイルを呼び出し」アクティビティを使って、実現させます。その際に、入力属性の引数に、呼び出し側の値を設定し、出力属性の引数に呼び出し側で受け取る変数を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/d001990f-33de-baae-9b01-d63ee549d7f5.png)


この例では、Int型、String型、Object型、DataTable型、Dictionary型（辞書型）を引数に指定し、呼び出し先に渡しています。呼び出し先では、入力属性の引数で渡された変数に設定されている値を基に、処理をします。出力属性がないので、呼び出し側が受け取るものはないですね。

引数が「入力」属性であると言う事は、呼び出し側の変数の値は、「ワークフロー ファイルを呼び出し」アクティビティに指定されたxaml中で値を変更したとしても、**変わりません。**

と思っていたのですが、**実はそうでもない**んですね。

実験してみました。今回、Dictionary型（辞書型）を引数に加えてみたのは、他の人が作ったロボットを見たときに、よくある"CONFIG.xlsxから辞書型に変換しそれをロボで使う"変数以外に、String,ObjectのDictionary型を用意し、そこに引数を格納する、って方法に遭遇したからです。こうする事で陽に変数を指定しなくても、このDictionary型の変数にキーとその変数を格納してあげれば、仕様が変わって引数の変更があっても、引数タブでの改修は不要になるのですね。

では簡単なロジック紹介。
１）呼び出し元で、各属性の変数を用意、値を設定する。
２）呼び出し先で、入力属性として渡されてきた値を加工する。
３）呼び出し先で処理され、返ってきたら、入力属性である値がどうなっているか評価する。

※DataTableには、2列2行のデータ行を追加してあります。
※Dictionaryには、キーとして、"I","S","D"をキー挿入してあります。

| 変数 | 処理前の呼び出し元での値 | 呼び出し先での処理 | 処理後の呼び出し元の値 | 備考 |
|:--|:-:|:-:|:-:|:-:|
|Int型|10|2乗(=100)|10|CType(Int型 ^ 2, Int32)|
|String型|KOZAKI|左右入替え(=IKAZOK)|KOZAKI|String.join(String.Empty, String型.Reverse)|
|Object型|123|1加算|123|CInt(Object型) + 1|
|DataTable型|HAJIME|"FUJITSU"設定|FUJITSU|Dt.Rows(1).Item(1)に設定|
|Dictionary型(Int)| 10|1加算|11|CInt(Dictionary型("I").ToString) + 1|
|Dictionary型(String)|KOZAKI|"+ADD"連結|KOZAKI+ADD|Dictionary型("S").ToString & "+" & "ADD"|
|Dictionary型(DataTable)|HAJIME|"****"設定|"****"|左辺:CType(Dictionary型("D"), DataTable).rows(1).Item(1)|

このような結果になりました。すなわち、**DataTable型、Dictionary型は、**入力属性として指定されていても、、「ワークフロー ファイルを呼び出し」アクティビティに指定されたxaml中で値を変更してしまうと、**そのまま値が反映されてしまう**のですね。

一度、中の人に訊いた事があるのですが、例えば巨大なDataTableをxamlに渡した時、入力属性の変数情報を退避しなければならず、そうなると**メモリ圧迫につながるのを嫌ったため...**との事でした。

Dictionary型(String, Object)の中にInt型を格納して、そこに処理を加えた場合は、キーを指定して得た値は一旦仮の変数に格納され、それに対して処理し、その処理結果をキーに対応する領域に格納したためでしょうねぇ。

##おわりに
いかがでした？

▼呼び出し元からしてみれば、入力属性の引数の値が勝手に書き換わってしまうのだったらそんなxamlは使わないよ！ってな事になりかねません。
▼ですので、呼ばれる側は、入力属性の引数の値は保証してあげたいですね。
▼とは言え、中の人が言うように**メモリ圧迫につながる**のだったら、呼び出し側もこの事実を意識して、UiPathロボを作っていく他なさそうですね。利用者責任。なんだかつれない対応ですね(^^♪

今回も読んでいただきありがとうございました！
是非UiPathでのロボ開発の一助になればと思っています。

ありがとうございました！
djangoでmysqlを使うときに"Authentication plugin 'caching_sha2_password' cannot be loaded..."と出たとき

# 目的
djangoでsqliteの代わりにmysqlをデータベースとして利用すること。
# 結論
djangoでmysqlを使うときに"Authentication plugin 'caching_sha2_password' cannot be loaded..."とエラーが出た場合は、
**ユーザーの認証方法をmysqlclientが非対応だがデフォルトであるcaching_sha2_passwordからmysql_native_passwordに変更する必要がある。**
# 実施環境
### ハードウェア環境
| 項目 | 情報 |
|:-:|:-:|
| OS  |macOS Catalina(10.15.7)   |
|ハードウェア   |  MacBook Air (11-inch, Early 2015) |
|プロセッサ   | 1.6 GHz デュアルコアIntel Core i5|
|メモリ   |  4 GB 1600 MHz DDR3 |
|グラフィックス   |  intel HD Graphics 6000 1536 MB |
### ソフトウェア環境
| 項目 | 情報 |
|:-:|:-:|
| homebrew  | 3.3.8 |
| mysql | Ver 8.0.27 for macos10.15 on x86_64 |
| python  | 3.8.12 |
| django  | 3.1.2 |
| anaconda  | 4.10.1 |
| django  | 21.2.4 |
| pip  | 3.1.2 |


# 経緯
djangoでsqliteの代わりにmysqlをデータベースとして利用するために、mysqlclientをインストールした。
その後modelを反映させようとしている。

```
python manage.py makemigrations
python manage.py migrate
```
マイグレーション完了といきたいところだが、

```
django.db.utils.OperationalError: (2059, "Authentication plugin 'caching_sha2_password' cannot be loaded: dlopen(/opt/anaconda3/envs/djangoenv/lib/plugin/caching_sha2_password.so, 2): image not found")
```
このようなエラーが表示された。

# 原因究明
どうやら現在はdjangoの認証方式としてcaching_sha2_passwordがデフォルトとして利用されているが、ドライバであるmysqlclientが対応できていないため、上記のエラーが吐き出されたよう。

# 解決
[この記事](https://qiita.com/satoryosato@github/items/611809ebfb28c689ae8e)を参考に
利用するデータベースをmysqlに指定し、

```
mysql> use mysql
```
各ユーザーの認証方法を確認。

```
mysql> select user, plugin from user;
+------------------+-----------------------+
| user             | plugin                |
+------------------+-----------------------+
| mysql.infoschema | caching_sha2_password |
| mysql.session    | caching_sha2_password |
| mysql.sys        | caching_sha2_password |
| root             | caching_sha2_password |
+------------------+-----------------------+
```
必要最低限のユーザーだけ認証方法をcaching_sha2_passwordからmysql_native_passwordに変更していく。

```
mysql> alter user 'test'@'localhost' identified WITH mysql_native_password by 'パスワード';
```
もう一度確認し、pluginが変更されていることを確認

```
mysql> select user, plugin from user;
+------------------+-----------------------+
| user             | plugin                |
+------------------+-----------------------+
| mysql.infoschema | caching_sha2_password |
| mysql.session    | caching_sha2_password |
| mysql.sys        | caching_sha2_password |
| test             | mysql_native_password |
| root             | caching_sha2_password |
+------------------+-----------------------+
```

マイグレーションも無事成功。
Nuxt 2 with GithubAPI認証

# 概要

Nuxt2でGithubAPI認証からユーザー情報を取得する方法

# 前提条件

- GithubでClientIDとClientSecretが発行済であること

# 手順

１. 環境変数とCORS設定

```js:nuxt.config.js
publicRuntimeConfig: {
  // 事前に.envの作成が必要です。
  GITHUB_CLIENT_ID: process.env.GITHUB_CLIENT_ID,
  GITHUB_CLIENT_SECRET: process.env.GITHUB_CLIENT_SECRET
},

axios: {
  proxy: true
},

proxy: {
  '/github/': {
    target: 'https://github.com',
    pathRewrite: {'^/github/': '/'},
  },
  '/github-api/': {
    target: 'https://api.github.com',
    pathRewrite: {'^/github-api/': '/'},
  }
}
```

２. Githubのアクセストークンを保存するストアを作成

```js:store/index.js
export const state = () => ({
  accessToken: null
})

export const mutations = {
  setAccessToken(state, accessToken) {
    state.accessToken = accessToken
  }
}

export const actions = {
  setAccessToken({ commit }, accessToken) {
    commit('setAccessToken', accessToken)
  }
}
```

３. Githubの認証画面へ遷移する画面を作成

```vue:pages/index.vue
<template>
  <div>
    <!-- Vuetify.jsを使用しています -->
    <v-btn
      v-text="'Github'"
      @click="goTo"
    />
  </div>
</template>

<script>
export default {
  methods: {
    goTo() {
      window.location.href =`https://github.com/login/oauth/authorize?scope=user&client_id=${this.$config.GITHUB_CLIENT_ID}`
    }
  }
}
</script>
```

４. 認証画面からのリダイレクト先の画面を作成

```vue:pages/callback.vue
<template>
  <div>
    コールバック画面
  </div>
</template>

<script>
export default {
  asyncData({ query }) {
    return {
      code: query.code
    }
  },
  data: () => ({
    code: ''
  }),
  async mounted() {
    await this.github()
  },
  methods: {
    github() {
      const data = await this.$axios.$post('/github/login/oauth/access_token', {
        client_id: this.$config.GITHUB_CLIENT_ID,
        client_secret: this.$config.GITHUB_CLIENT_SECRET,
        code: this.code
      }, {
        headers: {
          'Accept': 'application/json'
        }
      }).catch((error) => { return error.response })
      
      this.$store.dispatch('setAccessToken', data.access_token)

      return this.$router.push('/home')
    }
  }
}
</script>
```

５. ホーム画面を作成

```vue:pages/home.vue
<template>
  <div>
    ホーム画面
  </div>
</template>

<script>
export default {
  async mounted() {
    await this.init()
  },
  methods: {
    async init() {
      const res = await this.$axios.$get('/github-api/user', {
        headers: {
          'Authorization': `token ${this.$store.state.accessToken}`,
          'Accept': 'application/vnd.github.v3+json'
        }
      }).catch((error) => { return error.response })

      // Githubのユーザー情報を出力
      console.log(res)
    }
  }
}
</script>
```

完了！！
docker-compose v2.2.2 のインストールメモ


## 概要

WSL2 上の Ubuntu 18.04 に対して、
従来(docker-compose v1.29.2)の手順で docker-compose の v2.2.2 をインストールしたところ、
docker-composeファイルの実体が「Not Found」と書かれたファイルになっていた.

　

どうやら、v2 では次のようにインストール手順が変化したようなので書き出しておく

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/d3e40f99-31ad-26a8-5f39-8548dfd07f04.png)

　

## 実行環境

### OS

```
  Operating System: Ubuntu 18.04.4 LTS
            Kernel: Linux 4.15.0-112-generic
      Architecture: x86-64
```

### docker version

```
Client: Docker Engine - Community
Version:           19.03.13
```
　

## 手順

基本的には「https://docs.docker.com/compose/cli-command/#installing-compose-v2」 に従うのみ.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/71910e1d-1671-a563-e5ec-2e3912756e2b.png)


### 1. docker-compose のバイナリ置き場

https://github.com/docker/compose/releases/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/189d7d13-9abf-3296-f762-aa04fc543994.png)




### 2. 上記 1 のバイナリから該当するものを選ぶために次を実行する

カーネルとハードウェア情報は次の通りなので、
上記 1 にある「docker-compose-linux-x86_64」を使用することになる

```bash
$ uname -s
Linux
$ uname -m
x86_64
```

　

### 3. インストール

[公式手順](https://docs.docker.com/compose/cli-command/#installing-compose-v2)通りに実行するだけ

```bash
$ mkdir -p ~/.docker/cli-plugins/
 
$ curl -SL \
   https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-linux-x86_64 \
   -o ~/.docker/cli-plugins/docker-compose

$ chmod +x ~/.docker/cli-plugins/docker-compose
```

　

### 4. 動作確認

「docker□compose」というように、□には半角スペースを空けて実行する

```bash
$ docker compose version
Docker Compose version v2.2.2
```

　

以上.


## 参考リンク

|項目|URL|
|:--|:--|
|公式サイト|https://docs.docker.com/compose/|
|公式GitHub|https://github.com/docker/compose|
|公式リリース置き場|https://github.com/docker/compose/releases/|
|docker-compose v2 系インストール手順|https://docs.docker.com/compose/cli-command/#installing-compose-v2|
|2021/12/24時点での最新版(v2.2.2)|https://github.com/docker/compose/releases/tag/v2.2.2|
Slack App（issue-alize for Redmine,Backlog）の開発して分かったこと


# はじめに
SlackメッセージからRedmineのissueを登録するアプリ（issue-alizeと言います）を開発しました。
[issue-alize for Redmine](https://tailshape.slack.com/apps/A01NTCE2G4A-issue-alize-for-redmine)
[issue-alize for Backlog](https://tailshape.slack.com/apps/A01F1AABZQW-issue-alize-for-backlog)
そのSlackAppの紹介と開発する上で少し困った点およびSlack App Directoryへ登録のメリットなどを記載します。

# 開発しようと思った経緯
- Slackの会話上でタスクを振られることが多く、それをRedmineに手動で登録していた
- その際、SlackのメッセージをコピペしてRedmineに登録するのが発狂しそうな作業だった
- SlackのメッセージをIssueとしてRedmineに登録するアプリがSlack App Directoryに見当たらなかった
    - 逆方向のRedmineの変更をSlackに通知するSlack　Appはありましたが。。。

# 実装した機能
- インストール時
    - SlackAppインストール後、issue-alizeの設定画面に遷移させてRedmineの情報と紐づける
- Slack利用時
    - Slackメッセージのショートカットメニューにアプリケーションのメニューを追加
    - メニュー実行後、ダイアログを表示
    - ダイアログでSubmitされたらRedmineのIssueを登録
    - SlackチャネルにRedmineのIssueのURLを投稿
    - AppHome画面からissue-alizeの設定画面に遷移


![Qiita記事issue-alize.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652145/45b50b20-50a1-fc9b-5090-62d2eaeeef46.png)




# システム構成
- 設定画面はWebアプリケーションで構成
- 設定画面以外は、AWSのAPIGateway＋Lambdaで構成
    - 起動・停止のメンテナンスが必要ない！
    - Lambda自体はユーザが少ないうちはお金がほとんどかからない！

# 開発上の少し困った点
以下が今回開発したメインの画面です。
![スクリーンショット 2021-12-25 3.14.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652145/8788df5a-4335-1ba6-a97d-76834906c6a6.png)
開発を振り返って困った点は以下の通り。

| 困った点 | 要因 | 対応方法 | 
|:-----------|:------------|:------------|
| 100以上Redmineのプロジェクトがある場合、選択できないプロジェクトが発生した|[Static Optionの上限が100であること](https://api.slack.com/reference/block-kit/block-elements#static_select) |フィルタ文字列でプロジェクトを絞り込めるようにした |
| 選択したプロジェクトに応じて、RedmineAPIでAssigneeの選択肢を生成しているが、それが間に合わないことがある  |プロジェクト選択後、Redmineからユーザリストを取得し、views.updateでUIを書き換える処理をしているが、それがそれなりに重い      |対応策なし|
| 時々SlackがResponseを受け取るに3秒以上かかりエラーとなることがある| Lambdaで実装しているので初期動作が遅い  |処理受付後はなるべく非同期処理で処理した。<br>Lambdaを使わず通常のウェブサービスにする（未対応） |
| Slackメッセージのメンションが<@XXXXXXXXXXX>のようにそのままRedmineのIssueに表示されている。| Slackのチャネルのメンバーの詳細情報を保持していないため| Backlogにデータを渡す際にメンションを削除するか、Redmineのユーザに変換する（未対応）|
| APIキーを預かる必要があること| RedmineはAPIキーによる認証しかない| 対応策なし。<br>ただしBacklogはAPIキーを使わずにOAuthによる認証で紐付けた|
| Slackの認証処理などでプログラムが複雑になってしまった| フレームワークを使わず、Slack Web APIだけを使って実装したから| Boltフレームワークを使う（未対応）|

# Slack App Directoryへ登録
##　申請から登録・審査について
- かかった期間は4ヶ月程度（だらだらとプログラム修正したのでちゃんとすればもっと早く対応できたかも）
- 本当にアプリをインストールおよび使用して審査される
- 審査してもらうのに必要な環境は用意する必要あり（今回の場合Redmineのテスト用の環境やアカウントなど）
- 応対は英語（Google翻訳でなんとかなる程度だと思います）
- 指摘は３点ほどあった
    - アプリの仕様上不要と思われるScopeを指摘された（実際不要であった）
    - SlackAppのダイアログ上で他アプリのAPIキーを入れていることを指摘された
    - その他、動作的な不具合を指摘された
- 指摘された点が再現しない場合などは丁寧にやり取りいただいた
- 申請、審査に関して費用は発生しなかった
- 利用規約やプライバシーポリシーの文書が必要
- アプリのUIは英語表記とし、サポート言語も日本語と英語にした

##　Slack App Directoryに申請してよかったと思ったこと
- Slack App Directoryに登録され、アプリケーションが全世界で検索対象になる。（すばらしい！）
- サポート言語を英語にしてUIを英語にすると実際、８割程度日本以外のユーザになった！（issue-alizeはヨーロッパが多い）
- Slack App Directoryに登録することで思ってたよりユーザが増えた。

# 課題
- Boltを使うようにする
    - BoltをLambdaで使える？か調査
- SlackユーザIDとRedmineユーザIDの紐付け機能（SlackのメンションをRedmineのユーザに変換する）
- APIキーでの認証以外でのRedmineの認証の実現
    - BacklogのようにOAuthでの認証が可能であれば、それがベター
- 広告などをいれて少しでも利益にできないかなぁ



# （おまけ）今後作ってみたいSlack App
- Slack向けの階層アドレス帳を作ってみたいと思っています
    - 組織単位宛にメッセージが送信できるもの
- SlackAppの開発をしていますのでご相談承ります：-）
インフラの基本単語を理解するために調べて書いてみる

## ipアドレス
192.168.1.1というのがあったとすると、ネットワーク部が192.168.1までで、そのあとの1はホスト部と言われる。同じネットワークに繋ぐときは、ネットワーク部を同じにしてホスト部を変える。

## サブネットマスク

IPアドレスのネットワーク部の長さを知るためのもの。
192.168.0.1/24という書き方をすることがあると思うが24はネットワーク部の長さを表してる。
この24をビット列で表すのがサブネットマスクである。

## ルーティング

ルーターを使って通信の宛先を決定すること。

## ポート代表的なやつ
80　http
443 https
22 ssh
20,21 ftp

## ファイヤーウォール（FW）
サーバを守る為のもの。通信を制御する仕組み。
インバウンドとアウトバウントの2種類がある。
サーバ自身にFWをもたせることができる。
JavaScript/TypeScriptでIoT開発したいときの最適なボード&SDK組み合わせフローチャート（2021年12月版）

IoT開発をしてみたいけどC/C++での実装はつらたん…な方は一定数いるのではないかと思います。
特に使い慣れたプログラミング言語で実装できたら最高ですよね。

私もまさにJavaScript/TypeScriptでIoTしたいユーザーなので、2021年12月現在時点で目的にあわせ最適なボードとSDKの組み合わせを導き出せるフローチャートを作ってみました。

![image](https://user-images.githubusercontent.com/22117028/147369783-65767d78-8851-479c-b1af-97cdd4a8266c.png)



# JSでIoTしたいわけじゃない → Arduino × M5Stackデバイス

ここがYesならArduino IDEなりでC/C++で実装しましょう。
Arduino IDEも[v2.0](https://github.com/arduino/arduino-ide)や[CLI](https://github.com/arduino/arduino-cli)がリリースされたりと段々と使い勝手が良くなってきていますし、[PlatformIO](https://platformio.org/)といった選択肢もあります。
（私はC++で実装するときはVS CodeとPlatformIOの組み合わせを使っています）

デバイスとしてはESP32をベースとしたM5Stackシリーズのデバイスがオススメです。
個人的にはM5Stackシリーズは目的に応じて以下の3モデルの中で選択するとよいと思います。

|機種|価格|特徴|
|---|:-:|---
|[M5Stack Basic V2.6](https://www.switch-science.com/catalog/7362/)|5,203 円|M5Stackと言ったらコレなモデルです。<br>2インチ液晶やバッテリーもあり単体でも十分ですが「Stack」という名のとおりさまざまなモジュールを積み重ねるだけで使えます。|
|[M5StickC Plus](https://www.switch-science.com/catalog/6470/)|3,058 円|M5Stackを全体的に小さくしたモデルです。<br>こちらも小さいながら液晶・バッテリーも搭載しており、小さくなった分リーズナブルです。|
|[M5ATOM Lite](https://www.switch-science.com/catalog/6262/)|1,287 円|ケース付きの状態では最小スペックモデルです。<br>液晶はなくLEDのみでバッテリーはありませんが、電子パーツを制御することが主目的なら十分な構成です。|

https://www.switch-science.com/catalog/7362/

https://www.switch-science.com/catalog/6470/

https://www.switch-science.com/catalog/6262/

ここで紹介しているもの以外にもさまざまなモデルが発売されています。

https://www.switch-science.com/catalog/list/?keyword=M5Stack



# ボードだけで動かしたい → Moddable SDK × M5Stackデバイス

JavaScriptで実装することを考えた場合、まず想像するのがJavaScriptで書いたソースをコンパイルして書き込むケースではないでしょうか。
それを実現したのが[Moddable SDK](https://github.com/Moddable-OpenSource/moddable)です。
ECMAScript2021を99%以上準拠しているとのことです。

https://github.com/Moddable-OpenSource/moddable



# 過電流検知やボードのみで1A出力したい → obniz × obniz Board

過電流検知や、モータドライバなしにボードのみでモータ制御したいという方にオススメなのが[obniz Board](https://obniz.com/ja/products/obnizboard)です。
そしてobniz Boardを使う場合プログラム実装はobniz SDKのみです。

obnizもJavaScriptで実装できるのですが先述のModdable SDKのようにJavaScriptのソースをコンパイルするわけではなく、ボードに書き込み済みのOS（obnizOS）に対しネットワーク（obniz Cloud）越しにプログラム（obniz SDK）で制御するしくみです。

基本的にはネットワーク接続できていることが前提の運用ですが、IoTであればネットワーク接続できることは前提ですし、実機への書き込み不要でプログラムを変更可能なことは大きなメリットだと思います。

https://obniz.com/ja/products/obnizboard



# 常時稼働は1台で十分 → obniz × M5Stackデバイス

obnizアカウントを作成すると1台まで無料でobnizOSをESP32デバイスへ書き込んで使用できます。
そのためobniz Boardを持っていなくとも手持ちのESP32デバイスからobnizを利用できます。

とりあえずobnizを試してみたいといった場合にもM5ATOM Liteといった安価なデバイスで気軽に試せます。

https://obniz.com/ja/doc/reference/obnizos-for-esp32/



# 複数のデバイスを運用したい → opniz × M5Stackデバイス

1台だけじゃなく複数デバイスを安価に運用したい、そんなケースではopnizがおすすめです。
opnizはobnizっぽいことができるオープンソースIoTフレームワークです。
私もopnizとM5ATOM Liteの組み合わせで自作おうちハックデバイスをいくつか常時稼働させています。

obnizほど機能は充実していませんがオープンソースのためライセンスは不要で、クラウドを経由せずとも直接デバイスとプログラムで通信を行えます。

他にも特徴としてはM5StackのArduinoライブラリをJavaScriptでラップしたような構成となっており、JavaScriptでArduinoライブラリと同じ書き味で実装できることを目指しています。

https://github.com/miso-develop/opniz
【Automation Anywhere】曜日の取得は１行でできる！（Automation360）

#はじめに

Automation Anywhere で日付を扱うためには、「日時」というアクションのパッケージを使います。

この日時アクション、一見すると、「曜日の取得」のアクションがないように見えますが、実はできるんです、１行で！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/8717a948-bfd2-2a12-a15a-aa6c5a81276d.png)

ということで、この記事ではそのやりかたを解説します。

#「日時」パッケージ　＞　「文字列に変換」で曜日を取得できる！

やりかたは簡単。

標準で入っている「日時」パッケージの「文字列に変換」で、「カスタムフォーマット」に「EEE」と指定するだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/d9dfe2fc-b5ba-13f6-59b1-3480b4a6afcb.png)


上記のBotでは取得結果を変数に代入し、メッセージボックスに表示しています。
メッセージボックスにはこんなかんじで表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/5e6fb367-e750-eeaf-f7e0-e3fc3ab1a726.png)


「カスタムフォーマット」を「EEEE」と指定すると、「土曜日」と長い曜日が取得できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/6a5a1c35-c03e-8d8b-ffa7-c35ad43ebb18.png)

# EEEやEEEEを入れればいいって、どこを調べればわかるの？

そんなこと言われても、EEEやEEEEで曜日が取得できるなんてわからなかったよー！　という人もいるかもしれませんね。

一応、Googleで「Automation Anywhere 曜日」と検索すると、公式ドキュメントが最初にヒットするはずです（2021年12月25日時点）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/15103af9-ed9f-5485-9fde-ec9742faea5d.png)

このリンク先を「曜日」でワード検索するか、下の方までスクロールしていくと、「カスタム日時形式」というコーナーがあります。

ここに曜日についての記載があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/449cd1e0-ffb1-2c40-11da-7ebc3b8cc434.png)

曜日の例が「Sun～Sat」となっているので、「日本語に対応していないのか？」などと思ってしまうかもしれませんね。
でも、一般的な日本企業の人が実行すれば、普通に日本語で値が取得できるはずです。（月も同様）

正確に言うと、この曜日や月の言語が何語になるかは、OSの言語に依存します。
Automation Anywhere の実行環境は Windows のみなので、実行機のWindowsが日本語なら日本語、英語なら英語の曜日や月が取得できます。

日本企業に勤めている人は日本語のOSを使っている可能性が高いので、「日本語で値が取得できるはず」というわけです。

もし、社員に個人によってOSの言語が違う可能性があり、それでも一貫して日本語の曜日を取得したい場合は、別の方法をとる必要がありますが、それも行数でいえば２行で処理できます（この方法については、別途記事を書きます）。

いずれにしても、この方法を知らなかったためにこんなすごいやりかたで曜日を求めている方がいたとは……ちょっと感動したとともに、申し訳ない気持ちになりました＞＜

https://qiita.com/auco67/items/7f508af083c7d2c39e42

https://qiita.com/auco67/items/b7bd6db6bf1da6974388

こんなにすごいことをしなくても、Automation Anywhereで曜日の取得はできます……！

# 曜日だけじゃない！　いろいろできる日付の編集

上記の「カスタムフォーマット」を使えば、曜日だけでなく、様々な形に日付を編集することができます。

## 例１：スラッシュ区切り（yyyy/MM/dd形式）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/45ef0603-618b-4fb7-4608-a96c45347372.png)

## 例２：年月日形式

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/426ed398-836d-8651-9bb4-20b23b1fcc42.png)

## 例３：時刻もとれる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/d23f3e60-2106-b104-7761-7f9f2c450b0b.png)

こんな形で、かなり自由に日付や時刻の編集ができますので、知らなかった方はぜひこれを機に活用してみてください！

#以上！

いかがでしたか？

今後もAutomation Anywhere について、初心者にもわかりやすく役に立つ記事を書いていきたいと思います。

わからない点や不明な点、「こんな記事を書いてほしい！」などのリクエストがありましたら、コメントやTwitterなどでお気軽にコメントいただければ幸いです。
バックトレースの読み方 備忘録

#目的
バックトレースの読み方 備忘録

#エラー内容

```terminal:ターミナル
NameError: undefined local variable or method 'distanse' for #<Gate: 0x007fa4ce148320 aname=: mikuni>
Did you mean? distance
/(ブログラムのパス)/lib/gate.rb:36:in `calc_fare'
/(プログラムのパス)/lib/gate.rb:26:in `exit'
test/gate_test.rb:33:in 'test_juso_to_mikuni
```
#NameError
NameError:は例外クラス名
未定義のローカル変数や定数を使用したときに発生する。

```terminal:ターミナル 
NameError: undefined local variable or method 'distanse' for #<Gate: 0x007fa4ce148320 aname=: mikuni>
```

Gateがクラス名
Ox007fa4ce148320がObjcctid、Oname=:mlkunlはこのオブジェクトが保持しているインスタンス変数の情報

```terminal:ターミナル 
#<Gate: 0x007fa4ce148320 aname=: mikuni>
```

distanceかい？って聞かれてる？

```terminal:ターミナル 
Did you mean? distance
```

次これ、正確にはプログラムが実行されてエラーが発生するまでのメソッド呼び出しの順番を示した情報らしい。
/(ブログラムのパス)/lib/gate.rbはファイルパス
36は行目を表示
 `calc_fare’はここでエラー起きてるよサイン

```terminal:ターミナル 
/(ブログラムのパス)/lib/gate.rb:36:in `calc_fare'
/(プログラムのパス)/lib/gate.rb:26:in `exit'
test/gate_test.rb:33:in 'test_juso_to_mikuni
```

#参考
おうちで学べるデータベースのきほん
データウェアハウスとデータレイクの違いについて

この記事は株式会社ナレッジコミュニケーションが運営する クラウドAI by ナレコム Advent Calendar 2021 の21日目にあたる記事になります。

#はじめに
データ分析に欠かせないものとしてデータの蓄積環境があります。データの蓄積環境は
様々な形態がありますが、最近良く耳にするのが「データウェアハウス」と「データレイク」があります。
どちらも大量のデータを収集する環境として利用されておりますが、この記事では、そんな「データウェアハウス」と「データレイク」との違いについてを簡単にご説明できればと思います。

#データウェアハウスについて
データウェアハウスは、直訳すると「データの倉庫」になります。
![751833376-logistics-748152_1920-mK3-1280x853-MM-100.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321357/44fd99bf-c4f6-cef6-ddbd-55520f69cf5c.jpeg)


倉庫には、様々な物品が、物品ごときれいに整理されていますよね。データウェアハウスは、まさにそのように用途別に整理されたデータが保存されている場所になります。
そのため、用途が明確な必要があります。

#データレイクについて
データレイクは、直訳すると「データの湖」になります。湖の中には、水はもちろんですが、その中には魚や微生物水面にも写真のような鳥などの生物がおり、湖には水の他に多種多様な生物がいます。
![2615331094-swan-752449-G67-1280x853-MM-100.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321357/bf338cc3-6277-c0d6-09eb-5028305f8afb.jpeg)

データレイクは、まさに湖のように様々なデータを蓄積されている場所になります。
データレイクの中には、整理されたテーブルデータだけでなく、画像やログファイルなどのデータも多く含まれております。そのため活用をする際には、活用をするためにデータ形式を変えていく必要があります。


#データウェアハウスとデータレイクの違いについて
データウェアハウスとデータレイクには、どのような違いがあるのでしょうか。
前段でデータウェアハウスは整理されたデータが保管されている倉庫。データレイクは、様々なデータが蓄積されている湖とお伝えしましたが、簡単に言うと、データウェアハウスには、刺し身を作るために加工された魚が保存されていて、データレイクには、生魚が保存されているような状態になります。
つまり、刺し身をベースにアレンジした料理を作りたいのであれば、データウェアハウスを利用するのが良いのですが、昨今は、生魚から煮魚や焼き魚など様々な形に活用をしていきたいというニーズが高まって来ております。そのため、データレイクを準備していく企業も増えてきております。

データレイクのデータを様々な形に加工していくことで、一つの生データから複数の利用が可能になっていきます。しかし、用途が決まっていないと魚をどう加工したらいいのかがわからず、生魚が次々に溜まってしまって、データスワンプ。直訳すると「データの沼」になってしまうということが起きてしまいます。

#データスワンプからの脱却
そんなデータレイクのデータスワンプ化から脱却する事ができる仕組みがあります。
それがDelta Lakeです。
Delta Lakeは、データ レイクに信頼性をもたらすオープンソースのストレージ レイヤーです。 Delta Lake は、ACID トランザクションとスケーラブルなメタデータ処理を提供し、ストリーミングとバッチ データ処理を統合します。 Delta Lake は既存のデータ レイク上で実行され、Apache Spark API と完全に互換性があります。詳しくは、[こちらの記事](https://azure-recipe.kc-cloud.jp/2020/08/spark-ai-summit-2020-%e3%83%80%e3%82%a4%e3%82%b8%e3%82%a7%e3%82%b9%e3%83%88%e3%81%ae%e5%86%85%e5%ae%b9%e3%81%94%e7%b4%b9%e4%bb%8b%e3%81%97%e3%81%be%e3%81%99-delta-lake/)を参考にしてみてください。


# 最後に
いかがだったでしょうか。データウェアハウスとデータレイクの違いについて、
ざっくりでも、違いを理解していただけたら幸いです。


# ◆参考記事及び書籍
Delta Engine および Delta Lake ガイド
https://docs.microsoft.com/ja-jp/azure/databricks/delta/
参考書籍
[AWSではじめるデータレイク: クラウドによる統合型データリポジトリ構築入門](https://www.amazon.co.jp/AWS%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%83%AC%E3%82%A4%E3%82%AF-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%81%AB%E3%82%88%E3%82%8B%E7%B5%B1%E5%90%88%E5%9E%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E6%A7%8B%E7%AF%89%E5%85%A5%E9%96%80-%E4%B8%8A%E5%8E%9F-%E8%AA%A0/dp/491031301X/ref=asc_df_491031301X/?tag=jpgo-22&linkCode=df0&hvadid=342518373760&hvpos=&hvnetw=g&hvrand=4144218916377909404&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009252&hvtargid=pla-923695857075&psc=1&th=1&psc=1)
SpresenseでSSD1351のOLEDを動かした話

Qiita Advent calendar2021の記事です。

:::note
Spresenseの関係会社に勤務していますが、業務外の個人活動の紹介です。
当記事は会社と関係ありません。
:::

:::note alert
誤った基板上のピン接続により故障する可能性があります。
自己責任でお願いします。
:::

SSD1351ドライバを使っているOLEDモニタをsoftwareSPIとHardwareSPIで比較してみました。

https://www.amazon.co.jp/gp/product/B01M19T96O/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1

####OLEDとSpresenseの接続
|OLED|Spresense
|---|---|
|GND|3.3v|
|SCL|D13 spi csk|
|SDA|D11 spi mosi|
|DC |D8|
|CS |D10 spi cs|
|RES|D9|

####スケッチ
SSD1351のサンプルスケッチtestSSD1351を用いました。
時間を比較するため、すべてのdelayをコメントアウトしました。

<details><summary> testSSD1351の選択場所 </summary><div>

``` 
// SoftwareSPIのときこっちを使う
// Option 1: use any pins but a little slower
//Adafruit_SSD1351 tft = Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, CS_PIN, DC_PIN, MOSI_PIN, SCLK_PIN, RST_PIN);  

// HardwareSPIのときこっちを使う
// Option 2: must use the hardware SPI pins 
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be 
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
Adafruit_SSD1351 tft = Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, CS_PIN, DC_PIN, RST_PIN);

```

</div></details>

####ライブラリ
そのままではHardwareSPIは動きませんでした。
試行錯誤した結果、ここを修正すると動きました。

<details><summary> SPI.hの修正場所 </summary><div>

``` 
class SPISettings {
public:
...
// clockを12000000に変更　14000000までは動くようだ
    SPISettings()
        : clock_(12000000), bit_order_(MSBFIRST), data_mode_(SPI_MODE0) { }

```

</div></details>

<details><summary> Adafruit_SSD1351.cppの修正場所 </summary><div>

``` 
// elseの周波数を12000000に変更　14000000までは動くようだ
// TODO: this will be moved to SPITFT, but for now:
#if defined(ARDUINO_ARCH_ARC32)
...
#else
#define SPI_DEFAULT_FREQ 12000000 // 24000000 ///< SPI default frequency
#endif

```

</div></details>

####実行の様子

https://www.youtube.com/watch?v=54eWri91DaE

HardwareSPIはSoftwareSPIより約8倍くらい早いようです。

####参考
https://www.youtube.com/watch?v=COPe5fKlkqA
Macへのnpm、npxのインストール

AWS　AmplifyでWebアプリケーションを構築するチュートリアルを進めようとしたところ、npxが必要になったのでインストール方法をメモしておきます。

https://aws.amazon.com/jp/getting-started/hands-on/build-react-app-amplify-graphql/?e=gs2020&p=frontend

#手順
##パッケージマネージャの更新
Macのパッケージマネージャを更新します。

```
$ brew update
```

##nodebrewをインストール
nodeのバージョンを管理するnodebrewをインストールします。
```
$ brew install nodebrew
```

##node.jsのインストール
node.jsインストール用のフォルダを用意した後、インストールを行ってから使用するバージョンを指定します。

```
$ mkdir -p ~/.nodebrew/src
$ nodebrew install-binary latest
$ nodebrew list
$ nodebrew use v[表示されたバージョン]
```

##パスを通す
.bash_profileに以下を追記します。
npmは~/.nodebrew/src/の下に存在します。

```:.bash_profile
export PATH=$PATH:[npmへのパス]
```

#まとめ
AWSのチュートリアルを実施したいだけだったのですが、node.js(npx)のインストールだけで1時間かかってしまいました。
この後、チュートリアルに取り組みたいと思います。

---
<<参考>>

https://www.suzu6.net/posts/45/

https://qiita.com/nbkn/items/01a11392921119fa0153
Amazon API GatewayでMockを作成する

# APIタイプを選択する
REST APIの「構築」をクリックします。
![スクリーンショット 2021-12-25 6.10.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/4a46ae8b-7468-f002-97ea-9a9465b5505f.png)

# プロトコルを選択する
「新しいAPI」を選択します。
API名に「hello-world」と入力します。
「APIの作成」をクリックします。
![スクリーンショット 2021-12-25 6.12.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/2e167de8-35b2-8224-ee90-90733ae97b2e.png)

# リソースを作成する
アクションから「リソースの作成」をクリックします。
![スクリーンショット 2021-12-25 6.12.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/eacecc22-f0eb-ac74-b720-dcea7b8b95a2.png)

リソース名に「message」と入力します。
「リソースの作成」をクリックします。
![スクリーンショット 2021-12-25 6.13.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/4d8f95bb-7266-6362-39b4-5924a87139c9.png)

# メソッドを作成する
アクションから「メソッドの作成」をクリックします。
![スクリーンショット 2021-12-25 6.14.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/36564b29-a45a-0fd2-f1b1-aba083441ffd.png)

「GET」を選択し、「チェック」をクリックします。
![スクリーンショット 2021-12-25 6.14.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/58afdcf9-88c5-a01f-013c-1a29ee52f5e7.png)

# メソッドの統合ポイントを選択する
統合タイプの「Mock」を選択し、「保存」をクリックします。
![スクリーンショット 2021-12-25 6.15.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/b2d8407d-907e-6224-587d-793c764a9e85.png)

# 応答データを作成する
統合レスポンスをクリックします。
![スクリーンショット 2021-12-25 6.19.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/ad8f8314-d926-a82e-83a7-e3a5d57c2582.png)

マッピングテンプレートの「application/json」をクリックします。
![スクリーンショット 2021-12-25 6.20.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/143274ed-5c84-fa4b-cbef-9596d68c42e7.png)

応答データをJSON形式で入力し、「保存」をクリックします。
![スクリーンショット 2021-12-25 6.21.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/d99ce36d-4d3e-f6d7-0c05-8b7049276917.png)

# APIをデプロイする
アクションから「APIのデプロイ」をクリックします。
![スクリーンショット 2021-12-25 6.23.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/09ab8b4f-2026-3989-d0c0-0889c05da283.png)

デプロイされるステージで「新しいステージ」を選択します。
ステージ名に「test」を入力します。
「デプロイ」をクリックします。
![スクリーンショット 2021-12-25 6.23.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/3623b72b-ea01-0911-90d4-90861b8bf834.png)

# APIをテストする
テストをクリックします。
![スクリーンショット 2021-12-25 6.47.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/84ea7193-0feb-1303-9388-911c80227ff7.png)

「テスト」をクリックします。
![スクリーンショット 2021-12-25 6.48.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/c378f722-6197-bf06-7245-44a3731e932c.png)

テストの結果が表示されます。
![スクリーンショット 2021-12-25 6.48.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/16c553f1-1dbe-e28e-0956-e71f54afddfc.png)
Linuxのsimplefbをクリスマスカラーにした（かった）

# LinuxのSimpleFBをクリスマスカラーにした（かった）

これはクリスマスワンナイトハッカソンの作品紹介記事です。

先に宣言しておきます。
# 間に合いませんでした！！！！！！！！

(というより、正常に動きませんでした）
やりたかったことを書いておきます。

## 概要
Linuxで（たぶん）もっとも単純な画面表示ドライバは、`simplefb`と呼ばれるものです。これはフレームバッファと呼ばれる、直接画面へ表示される画像データが格納されているメモリ領域に直接画像を書き込むことで画面を表示するものです。GPU専用のドライバがなくても動作するので何かと便利です。

改造も比較的簡単そうだったので、この`simplefb`で表示される黒以外のピクセルを赤と緑にして、コンソールをクリスマスカラーにしてやろうと考えたわけです。

結果これが

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177817/874d0edf-cf1d-78da-07bc-94cf849b9242.png)

こう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177817/a8d09f25-fbed-8e07-46ee-fe1b1fefaa82.png)



...どうしてこうなった? 寝ぼけてて単純なミスをしているのかもしれませんが、パッチはこんな感じです。

```diff_c
diff --git a/drivers/video/fbdev/core/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c
index a2bb276a8b24..7aa9c07b2a21 100644
--- a/drivers/video/fbdev/core/cfbimgblt.c
+++ b/drivers/video/fbdev/core/cfbimgblt.c
@@ -269,6 +269,7 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
 	u32 width = image->width;
 	u32 dx = image->dx, dy = image->dy;
 	u8 __iomem *dst1;
+    u64 x, y;
 
 	if (p->state != FBINFO_STATE_RUNNING)
 		return;
@@ -294,13 +295,21 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
 			bgcolor = image->bg_color;
 		}	
 		
-		if (32 % bpp == 0 && !start_index && !pitch_index && 
-		    ((width & (32/bpp-1)) == 0) &&
-		    bpp >= 8 && bpp <= 32) 			
-			fast_imageblit(image, p, dst1, fgcolor, bgcolor);
-		else 
-			slow_imageblit(image, p, dst1, fgcolor, bgcolor,
-					start_index, pitch_index);
+        for (y = 0; y < (u64)(image->height); y++) {
+            for (x = 0; x < (u64)(image->width); x++) {
+                u32 c_color = (((image->dx + x) / 40) % 2 == 0) ? 0x00ff0000 : 0x0000ff00;
+
+                u64 index = y * image->width + x;
+                u32 color = image->data[index] == 0 ? bgcolor : c_color;
+
+                u64 ptr = (u64)(p->screen_base);
+                ptr += (u64)(p->fix.line_length) * (u64)((u64)(image->dy) + y);
+                ptr += (bpp/8) * (u64)((u64)(image->dx) + x);
+
+                *((u32 *)(ptr)) = color;
+                FB_WRITEL(color, (u32 *)ptr);
+            }
+        }
 	} else
 		color_imageblit(image, p, dst1, start_index, pitch_index);
 }
```

しつこいぐらいキャストしてたり、タブ文字インデントをスペースインデントにしちゃってたり、コードがクッソ汚いのは許してください...。あとVirtualBox上で動作させることしか考えてなかったので、これは実は環境によって挙動が変わるコードです（）　どなたかバグの原因がわかる方がいたら教えてください。

気が向いたら再挑戦しようと思います。ハッカソンお疲れ様でした。
これをやるためにLinuxカーネルのフルビルドを2回、差分ビルドを30回はやったので、だいぶSSDの寿命が縮んだような気がします。
人を消し去りたかった

動く、動くはずなんですよ。
# まずはじめに
ハック(開発完了)できてません
# 内容
クリスマス、世の中がこんなに賑わって陰の私がこんな惨めな思いをするのも人間がいるからなんです。
つまり人間を消し去ればこの世界に平和が生まれるので人を消し去りたいと思います。

# 構成
![asdfgh.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604861/12243faa-e1d3-ddde-5895-4c724b312da5.png)

# 解説
Robust Video Mattingとは人物の透過切り抜きの研究です。
いわゆるZoomなどで使われている背景切り抜きがいい例です。
この研究により、高画質なままリアルタイム処理できるというのです。
この研究はCVPR2021に採択されています！
https://github.com/PeterL1n/RobustVideoMatting

これで透過切り抜きをしたあとはマスク画像をつくってinpaintingを行います、
inpaintingとは画像から特定の画素の情報を消し、消した場所を周囲の情報をつかって「いい感じに」してくれることです。
例を挙げるとGoogle Pixel 6で話題になった消しゴムマジックがまさにinpaintingです。


つまり人を認識して人の部分だけを消し去ることができるんです！

# 開発状況
22:00 開発開始　Dockerが急に言うことを聞かなくなる
23:10 Flaskを使おうと考える

https://twitter.com/_orikage/status/1474381507158765568?s=20

23:50  git管理を諦める
24:00　モチベが死亡
25:45  issueを覗いていたら書いていたコードの上位互換を発見する
26:30 Flaskのデバックをする　全く動かない
27:00 原因解明　開発停止

# なぜ開発停止したか
WindowsのWSL2上のDockerではusbカメラや仮想カメラを認識することが不可能でした！！！！！！！！！！
お疲れ様でした！！！！！！！！！！！！！！！
# 発見
WSL2でもimshowとかはできる
x11をごにょごにょするだけ

# 反省
環境由来の問題があることを認知すべきだった
ワンデイハッカソンとかいう速度が大切なときに知らない技術に手を出して手を焼くべきではなかった




でも楽しかったのでOKです
開催してくださった運営の方々、本当にありがとうございました！！！