OmniAICreator/Qiita-1.07M huggingface dataset:
プログラミングを質問|学ぶ時、初心者に知ってほしいこと

##はじめに
まずこの記事は学ぶ際に
**「こうやって質問しろ！」**
**「こうやって学べば成功する！」**
って訳ではなく人にプログラミングを教える経験をした上で困ったこと~~やらないで欲しい事~~を軽くまとめるだけどの記事であることを注意してください。
ていうかこんな人の話を見ようとしている人はだいたいできているのでただの愚痴だと思っても平気です。

~~書いてる人も初心者であることは内緒でお願い~~

##プログラム学ぶ前に
人に教える時、1番驚いたことが有ってそれはパソコンの基本知識が足りていないことである。
**「タイピングが遅い！」**
**「ブラインドタッチをしろ！」**
とかではない。

例を出すなら
**電源をつける　ファイル、フォルダの作成や操作　ブラウザの検索方法 etc...**
といった質問が多い。

料理に例えるとするならば料理教室で作り方を学んでいる中、包丁の使い方がわからないと聞いているようなものだと思っている。
~~そこから教える教室もあるかもしれないのでそしたらごめんなさい~~
ただコンパイル方法を教える前にそこから手間取っていたら時間が足りないので流石にファイル操作やフォルダ操作などの基本的なやり方くらいや電源の付け方とかそういう部分は学んでおいてほしかったりする。

##質問の仕方について
まずみんなが質問する時Twitterとかでよく見かけるのは

**「質問です、なぜかわかりませんがこうなってしまいます…」**

**「何故か動かないのですが何故このコードだと動かないのですか？」**

といった質問をコードだけ乗せて投稿する人や聞いてくる人が多い。~~まれにエラーコード載せてくれる人も居るけど~~

ただここで思うのは、まずエラーコードを読んでほしいということ。
C#をよく書くので例として出すと

```Error.cs
using System;
using System.IO;

namespace Error{
    class Program{
        static void Main(string[] args){
            Console.WriteLine($"test:{test}");
            FileStream fs = new FileStream("null.jpg");
            //ここで参照しているのが存在していないファイルと仮定
            string a = fs.readToEnd();
            Console.WriteLine($"testA:{a}");
        }
    }
}
        
```
こんなコードが合ったとしてエラーを読むと大体内容がわかる。
今の時代Google翻訳やDeepLだって有るし検索かけてもエラーは出る。

**教えるのが仕事でも毎回こんな質問教えるほど介護してたら身につかん！！！**

職務怠慢みたいなことを言うが自分の技術をみにつける意味でもそれはして欲しい。
1対複数なら尚更他の人の真面目な質問に対応したりする方が有意義だしね。

ただこれで質問することに恐怖して質問しないよりは質問してくれる方がマシなので質問の前にワンテンポおいて調べてほしいというだけである。

##自分で自習しているときのやり方
**ここまで口をだすんか！**って思う方も多いかもしれないが僕も思う。
~~てかここまで口を出す必要もない~~

ただ自習しているときにわからない時飛ばしたりそこで止まってしまう人が居る。
でもちょっと待って欲しい。
流石にググったりしてそれでもわからないなら質問をしたりして欲しい。

**「上で言ってたことと違うやんけ！」**
って思うような質問だったとしてもエラーを読んで理解できないなら質問してもらっても構わないしして欲しい。
何故かというとわからないまま放置されていると教える時に

**「自習でここまで進みました！」**
と言われた際、僕は
**(ならここまでは事前知識と知っているからこう教えよう！)**
とか考えている。
でも一部でもわからない点があったら教えるときにそれ知っているんじゃないの？という知識の差異が合ってこれまた時間を非常に食う。

なので質問は残さずきちんと学んでおいてほしいというちょっとしたお願いでした。

##まとめ
質問は頼むからワンテンポおいて調べてそれでもわからないときだけ質問しよう！**脳死はNG**

質問はなるべく残さないでもらえると助かる。

基本的なパソコン操作くらいは学んでおいて欲しい。プログラミングを学んでいるのであってPC教室ではない。
Linuxコンソールでスクリーンセーバー

みなさま、お久しぶりの、技術の無駄遣いシリーズです。

## なぜスクリーンセーバー?!

うちの会社はセキュリティにも力を入れているのですが、社内のルールに、パスワードによって保護されたスクリーンセーバーを設定する、というのがあります。
ちょっと席を離れたときなどに、他の人に端末の画面を見られるリスクと、操作されるリスクを軽減することが目的だと思われます。

Windowsの場合、スクリーンセーバーの設定に「再開時にログオン画面に戻る」というのがあるので、これを設定しておけば実現できます。

しかし、うちのチームで管理しているパソコンの中にLinuxを入れたデスクトップマシンがあり、しかも、それはGUIを持っていないものでした。
なんとか、社内のセキュリティ要件を満たすべく、いろいろと調べてみました。

## やるべきことは?

まず、要件を整理しましょう。やりたいことは、

- 一定時間が経過したら、スクリーンセーバーを表示してほしい
- スクリーンセーバー表示後に端末を操作した場合、パスワード入力をさせてほしい

この2点です。

スクリーンセーバーの目的は、CRT画面の焼き付きを防止することではなく、画面を見られないようにすることですので、現在の画面が見えるようなタイプのスクリーンセーバーはNGです。

## スクリーンセーバーを探す

実は、探さなくてもLinuxのコンソールには既にスクリーンセーバーが用意されています。
単位は分です。

```sh
setterm -blank 10
```

で10分後に画面が真っ黒になるようなスクリーンセーバーが発動します。

しかし、これ、復帰したときに元の画面が丸見えなんですよね。
これでは、要件を満たしません。

ちょっとググってみると、なんかすごいのがありました。

https://github.com/pipeseroni/pipes.sh

ソースがいろいろありますが、pipes.shだけ持ってくれば動くようです。
適当に実行権限を付けて/usr/binあたりに置いておきます。

しかし、これは、スクリーンセーバーが動くだけのプログラムで、時間が経過したら起動するようなものではありません。
これについては、後で考えます。

## 一定時間経過後にログアウトさせる

bashにはTMOUTという環境変数があります。
単位は秒です。
ここで設定した時間が過ぎると、ログアウトされます。
/etc/profileあたりに書いておきましょう。
ついでに、readonlyで変更できないようにしておきます。

```sh:/etc/profile
TMOUT=600
readonly TMOUT
export TMOUT
```

## ログアウト時にスクリーンセーバーを動かす

さて、スクリーンセーバーの起動ですが、ログアウト時に実行させると、パスワード付きスクリーンセーバーになって都合がよさそうです。

ログアウト時にはEXITというシグナルが発呼されます。
これをトラップすることにしましょう。

```sh:/etc/profile
trap /usr/bin/pipes.sh EXIT
```

タイムアウトを5秒に設定したら、こんな感じになりました。

[![screensaver.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326401/b85bb0ba-cfe7-bf00-9fb3-1ebaa57f315a.gif)
](./screensaver.gif)

いい感じです。


## コンソール以外では動かないようにする

sshでつないだときとかターミナル側でもパイプが暴れまくってうざいので、コンソールでだけ動くようにしておきます。
最終形はこんな感じです。

```sh:etc/profile
if /usr/bin/tty | grep /dev/tty > /dev/null; then
    TMOUT=600
    readonly TMOUT
    export TMOUT
    trap /usr/bin/pipes.sh EXIT
fi
```

## さいごに

セキュリティを担保したいだけなら無理にスクリーンセーバーっぽいのを動かさなくても、ログアウト時に画面をクリアするだけでいいような気もしてきました。
なんか、無駄なことをしたような気がします。

それより、コマンド実行中はタイムアウトされないので、vi開きっぱなしとかはしないようにしないといけませんねぇ。

*本記事は @qualitia_cdevの中の一人、@hirachanさんに書いていただきました。
ガンマ関数・ディガンマ関数を理解したい

### 目標
- 論文でガンマ・ディガンマ関数に遭遇してもひるまない自分を手に入れる

###ガンマ関数のモチベーション
- 正の整数以外の数にも階乗を定義したい。（今回は正の実数への拡張のみを考える。）

### 定義


```math
\Gamma(s) = \int_0^{\infty} x^{s-1}\space e^{-x}\space dx, \space s \in R^{+}
```

### 性質1 

```math
\Gamma(s) = (s-1)!,\space  s\in N
```

### 証明１

```math
\Gamma(s) = (s-1)\Gamma(s-1)
= (s-1)(s-2)\Gamma(s-2)
=(s-1)(s-2)\cdots \Gamma(1)
= (s-1)(s-2)\cdots1
= (s-1)!
```
### 性質2

```math
\Gamma(s) = (s-1)\Gamma(s-1), s>1
```
### 証明２

```math
\Gamma(s) = \int_{0}^{\infty}x^{s-1} e^{-x}dx = [x^{s-1}-e^{-x}]_0^{\infty} - \int_0^{\infty}(s-1)x^{s-2}-e^{-x}dx= (s-1)\int_0^{\infty}x^{s-2}e^{-x}dx = (s-1)\Gamma(s-1)
```
### 性質3

```math
\Gamma(\frac{1}{2}) = \sqrt \pi
```

### 証明３


```math
\Gamma(\frac{1}{2}) = \int_0^{\infty} x^{-\frac{1}{2}}e^{-x} dx = \int_0^{\infty}t^{-1}e^{-t^2}2tdt = 2\int_0^{\infty} e^{-t^2}dt = \sqrt \pi
```
<br>

```math
(t^2 = x \rightarrow dx/dt = 2t \rightarrow dx = 2tdt
```
<br>

```math
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt \pi)
```

### 視覚化

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2297919/685e0b1c-a348-af7e-d218-f78dc3829bd7.png)

### ディガンマ関数のモチベーション
Salesforceで商談完了時に商談完了日をカスタム項目に保存する方法

Salesforceで商談完了時に商談完了日をカスタム項目に保存する方法を紹介します
今回はカスタム項目「受注日」を作成し、
ワークフロールールを起動させてカスタム項目「受注日」の値を更新させます

１ワークフロールール作成その１

「新規ルール」ボタンをクリックします
![A1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/c73d7c10-d21c-69de-f895-bd680d3f539a.png)


２ワークフロールール作成その２
「商談」を選択し「次へ」をクリック
![A2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/7f986ad5-54b7-7ad7-b4d0-1cff5c45c6a3.png)

３ワークフロールール作成その３
レコードが次の場合にルールを評価:
を
作成されたとき、およびその後基準を満たすように編集されたとき
に設定。
「フェーズ」が「Closed　Won」（つまり受注）にして
「演算子」を「次の文字列と一致する」に選択し
「保存&次へ」をクリック
![A3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/84e3567d-8f97-4b05-7a81-bce9ea9e176a.png)


４ワークフロールール作成その４
「項目自動更新」を選択
![A4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/6ba50c50-79fe-b62c-15cc-14317eff2358.png)

５ワークフロールール作成その５
今回更新したい項目「受注日」を選択し数式を「TODAY()」に設定し「保存」をクリック
![a5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/9b2c6f4c-b90c-b3c7-0433-b11d084d5a0b.png)

６ワークフロールール作成その６
「完了」をクリック
![a6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/d4f2e465-de57-9a20-d87e-57d13973ddcd.png)


７ワークフロールール作成その７
「有効化」をクリック
![a7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/592fa9ce-6768-2b72-d92c-150bb7009bb0.png)
PRテンプレートを使ってチーム力アップ！

[KINTO Technologies Advent Calendar 2021 - Qiita](https://qiita.com/advent-calendar/2021/kinto-technologies) の16日目の記事です。
## TL;DR

- レビューを出す時はレビュアーが見やすいフォーマットにして提出しよう。
- レビューをお願いする前に必ず変更点をGithub上で再確認しよう。

上記の点を意識すればレビュアーは短時間で的確なフィードバックを返しやすくなり、
チーム全体の作業時間が増えるし、自分のスキルアップにも繋がるよねってお話です。

## レビューが大変💦

レビューが溜まってなかなかちゃんとした指摘ができない。（そもそも溜めるなという話もありますが...😅）
レビューで何度も同じ様な指摘をしている。

そういった事はチーム開発を行なっているとよく遭遇します。
解消する方法は色々ありますが、今回はプルリクエストのテンプレートを使った方法を発表します。
また、以後プルリクエストは **PR** と表記していきます。

レビューがなぜ大変なのか色々と原因はありますが、
一つに *何がしたいのか分からず、追うのが大変* という事があるかと思います。
そういった問題を解消するのに役に立つのがPRテンプレートです。

## PRテンプレートは何が良いのか？

PRテンプレート自体はご存知の方も多いと思いますが、PRテンプレートを設定しておく事で、PR作成時に入力しないといけない事柄をチームで共有できるので、フォーマットをチームで決めてしまえばレビュアーはPRの内容を素早くキャッチアップできる様になり、**PRレビューのコストを下げる**事ができます。

## 弊チームのPRテンプレート

早速ですが、弊チームが現在使っているPRテンプレートがこちらになります。

``` markdown
## WHY
> この PR で実現したいことを記載してください

## WHAT
> この PR でやったことを記載してください

-
-
-

## SCREEN SHOTS
> UIを変更した場合、変更前後のスクリーンショットを貼って下さい

| BEFORE | AFTER |
| --- | --- |
|  |  |

## MEMO
> レビューをする際に見てほしい点、ローカル環境で試す際の注意点、など

## CHECKs
> レビュー前の最終チェック項目です。落ち着いて確認しましょう☕️

- [ ] Push内容を再確認したか？
- [ ] DangerのLGTMはもらえたか？
- [ ] 着目点、注意点がちゃんと伝えられているか？
- [ ] PRで対応すべき範囲以上の変更が入っていないか？ ([YAGNI原則](https://e-words.jp/w/YAGNI%E5%8E%9F%E5%89%87.html))

> ロジックの追加・変更があった場合はこちらも確認しましょう。

- [ ] テストは足りているか？
- [ ] [SOLID原則](https://qiita.com/baby-degu/items/d058a62f145235a0f007)を満たせているか？
```

このテンプレートは大きく二つの構成になっていて、

1. PRの定義の明確化（レビュアー向け）
1. 自分のコードの再確認（レビュイー向け）

という構成になっています

### PRの定義の明確化

主にレビュアーのために用意する項目になります。
レビューをする上で何をどこまでレビューするのかを明確にするための項目で、
レビュアーはここを見ればPRの内容をおおよそ理解する事ができます。

#### WHY

PRで実現したい内容を書きます。

この欄に書いた内容以外の要素はこのPRに入れてはいけません。

#### WHAT

PRで対応した内容を書きます。

やった作業の明文化をする事で自身の作業を頭の中で整理すると同時に、
レビュアーの人にPRの内容の大まかな概要を理解してもらうための要素。

#### SCREEN SHOTS

画面に変更がある修正・機能追加を行なった場合にスクリーンショットを添付します。

画面構築をするクライアントサイドならではの項目で、
ローカルでビルドする前にレビュアーがPRの内容を理解しやすくするための要素

#### MEMO

このPRでの注意事項や着目してほしい事柄、ビルド時の注意点を書きます。

WHYでもWHATでもない事柄をここに書きます。

### 自分のコードの再確認

自分の確認用の項目になります。
基本的にはチェックボックスを埋めてからレビューをお願いするフローです。

#### CHECKs

``` markdown
## CHECKs
> レビュー前の最終チェック項目です。落ち着いて確認しましょう☕️

- [ ] Push内容を再確認したか？
- [ ] DangerのLGTMはもらえたか？
- [ ] 着目点、注意点がちゃんと伝えられているか？
- [ ] PRで対応すべき範囲以上の変更が入っていないか？ ([YAGNI原則](https://e-words.jp/w/YAGNI%E5%8E%9F%E5%89%87.html))

> ロジックの追加・変更があった場合はこちらも確認しましょう。

- [ ] テストは足りているか？
- [ ] [SOLID原則](https://qiita.com/baby-degu/items/d058a62f145235a0f007)を満たせているか？
```

CHECKsの項目はチェックボックス化してレビュイーが自分でチェックを入れる様にしています。
これはCI中やレビューをお願いする前に再度自分の上げた内容を見直してもらいたい。
自分自身で最終確認をしてもらいたいという狙いです。
また、YAGNI原則やSOLID原則を知らないエンジニアにもチェック要素に入れる事で、各原則に沿っているかを確認してもらい、それらの原則への理解を深める目的もあります。
※もちろん、自分のチェック用なので、チェックを入れたからといってレビュアーからその件に対して指摘が入る事はあります。

## さいごに

弊チームではこの発表内容以外にも開発に集中できる様な環境づくりに力を入れています。
今後もチームの状態に合わせてどんどんアップデートしていきます。

当社では、トヨタ車のサブスク「KINTO」等の企画/開発を行っており、エンジニアを募集中です。
[KINTO Technologies コーポレートサイト](https://www.kinto-technologies.com/)
Delta Live TablesのFAQ

[Delta Live Tables frequently asked questions \| Databricks on AWS](https://docs.databricks.com/data-engineering/delta-live-tables/delta-live-tables-faqs-issues.html) [2022/12/1時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

# 別のクラスター、SQLエンドポイントからパイプラインのビューにクエリーを実行することはできますか？

いいえ、現在はビューは同じパイプラインの他のテーブルからしかアクセスできません。

# Delta Live TablesはDeltaテーブルのアップデートのみをサポートしていますか？

はい、Delta Live TablesはDeltaテーブルの更新のみに使用できます。

# Delta Live Tablesは私のテーブルに対するメンテナンスタスクを実行していますか？

はい、Delta Live Tablesは24時間周期でテーブルに対するメンテナンスタスクを実行します。メテナンスによって、クエリーの性能を改善し、テーブルの古いバージョンを削除することでコストを削減します。デフォルトでは、システムは[VACUUM](https://docs.databricks.com/spark/latest/spark-sql/language-manual/delta-vacuum.html)に続いて、完全な[OPTIMIZE](https://qiita.com/taka_yayoi/items/e8797891fbc305328d49)オペレーションを実行します。テーブルの[テーブルプロパティ](https://docs.databricks.com/data-engineering/delta-live-tables/delta-live-tables-language-ref.html#tbl-properties)である`pipelines.autoOptimize.managed = false`を設定することでOPTIMIZEを無効化することができます。メンテナンスタスクがスケジュールされる24時間前にパイプラインのアップデートが実行された場合にのみ、メンテナンスタスクが実行されます。

メンテナンス用クラスターが必要なストレージロケーションへのアクセス権を有していること確実にするために、デフォルトクラスターとメンテナンス用クラスターの両方に対して、ストレージロケーションへのアクセスに必要なセキュリティ設定を行う必要があります。[Cluster configuration](https://docs.databricks.com/workflows/delta-live-tables/delta-live-tables-configuration.html#cluster-config)をご覧ください。

# テーブルの過去のスナップショットに対してクエリーを実行することができますか？

デフォルトでは、Delta Live Tablesパイプラインによって作成されたDeltaテーブルは、7日間履歴を保持しますので、テーブルの[スナップショット](https://docs.databricks.com/delta/history.html)に対してクエリーを実行することができます。7日以上の履歴が必要であれば、[テーブルプロパティ](https://docs.databricks.com/data-engineering/delta-live-tables/delta-live-tables-language-ref.html#tbl-properties)を変更することで、保持期間を変更することができます。

# 同じターゲットテーブルに対して書き込みを行う複数のクエリーを一つのパイプラインに含めることはできますか？

いいえ、それぞれのテーブルは一度で定義される必要があります。テーブルを作成するのに複数の入力を組み合わせる必要がある場合には、[UNION](https://docs.databricks.com/spark/latest/spark-sql/language-manual/sql-ref-syntax-qry-select-setops.html#union)を使うことができます。インクリメンタルテーブルに対するUNIONの追加、削除は、フルリフレッシュを必要とする破壊的オペレーションとなります。

# Delta Live TablesのパイプラインでScalaやJavaのライブラリを使うことができますか？

いいえ、Delta Live TablesではSQLとPythonのみをサポートしています。パイプラインでJVMライブラリを使うことはできません。JVMライブラリのインストールによって、予期しない挙動を引き起こし、将来的なDelta Live Tablesリリースを損なう場合があります。

# SQLでライブテーブルを作成する際にどのようにアイデンティティ列を使用しますか？

標準的な[CREATE TABLE構文](https://docs.databricks.com/sql/language-manual/sql-ref-syntax-ddl-create-table-using.html)と同じ様に`CREATE LIVE TABLE`文のスキーマ定義でアイデンティティ列を指定することができます。しかし、`STREAMING`として定義されていないライブテーブルにおいては、それぞれのリフレッシュでテーブルが完全に再生成され、それぞれの行に対して新たなID値の割り当てを行うことになります。

アイデンティティ列は[APPLY CHANGES](https://docs.databricks.com/workflows/delta-live-tables/delta-live-tables-cdc.html)テーブルではサポートされていません。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
2つのiframeを同期スクロールさせる


```
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
	</head>
	<body>
		<iframe id="iframeTxt1" src="longlong.txt"></iframe>
		<iframe id="iframeTxt2" src="longlong.txt"></iframe>
	<script>
		var iframe1 = document.getElementById("iframeTxt1");
		var iframe2 = document.getElementById("iframeTxt2");

		function scroll1() {
			iframe2.contentWindow.scrollTo(0,iframe1.contentWindow.pageYOffset);
		}
		function scroll2() {
			iframe1.contentWindow.scrollTo(0,iframe2.contentWindow.pageYOffset);
		}
		
		document.addEventListener('DOMContentLoaded', function() {
				iframe1.addEventListener('load', (function(element) {
						return function() {
								element.contentWindow.addEventListener('scroll', scroll1);
						};
				})(iframe1, false));
				iframe2.addEventListener('load', (function(element) {
						return function() {
								element.contentWindow.addEventListener('scroll', scroll2);
						};
				})(iframe2, false));
		}, false);
	</script>
	</body>
</html>
```


参考
https://qiita.com/sinsia/items/54865025821cb9203cfc
アドベントカレンダーに参加しようかまだ迷っている人に

そろそろ本当に12月なので自分なりの動機を書いてみます。

## 書く理由

**自分が得をするから書いています。**
言われたから書かなきゃとか、面白そうだからとかキッカケはあると思いますが、書ききると何が良いかと言うと自分の経験値が増えます。増える順を可視化すると

1. 自分の頭の中で理解する。
1. チームの人に伝えられるくらい理解する。
1. 全社の人に伝えられるくらい理解する。
1. 全世界の人に伝えられるくらい理解する。

飛躍していますがしかしそれが「貢献（Contribution）」というものなので、どうせ同じことを伝えるなら経験値高めていくほうがお得だなと思って書いています。


## 時間がかかる？

**時間をかける価値のあることだから、躊躇わず時間をかけたら良いとおもいます。**
人に伝えられるくらいに理解できていないと、技術も知識も不安です。
「自分の考えと経験と知識を人に伝える」、伝えられるってプログラムをリリースできるのと同じだと思います。


## 自分の場合

### 記事を書き始めようと思った理由

2010年くらいの時代、もともと社内Wikiも私が作った！というと言い過ぎなのだが、社内Wikiの黎明期の管理メンバーの一人でもありました。その頃から「情報共有」や記録、発信していくことは単純に好きだったんですが、テックブログの一番のメリットって「書いたものがまるごと自分自身の経験値になる」ですね。

社内だけじゃなく、社外の人に対しても、技術や開発をキーワードに（全世界に）発信できるってすごいです。それを合法的に業務として会社が推奨してくれているなら、やらない手はない、という感じです。書くのが苦じゃない、むしろ好きっていうのも大きいかもしれないですが。あとは別にQiitaに書くに限らずとも自分で動画にして人に伝えるでもよいのではと、エクストリームに思ったりもします。

### 記事を書くときに意識していること

全部が全部できているわけではないですが、こういう人に読んでもらいたい、を想像して、その人に、自分だったらこう話す、みたいなことを考えながら書くとわかりやすい記事になる気がします。自分が等身大で考えたことそのままポエムにしてチームメンバーに語ろうと考えたら大体これ、

https://qiita.com/e99h2121/items/50d51b05f110425115a5

ですし、[開発者としてアイディアを整理したり問題を解決したいときの「6色ハット」](https://qiita.com/e99h2121/items/abe7b5241d0fe1136b5d)なんていうのも「これ、重要な考え方なんだよ～」というのを引継ぎたくて書きました。あとは自分が面白がることを第一に。

## まとめ

[Write Code Every Day. Have Fun Every Day. - Qiita](https://qiita.com/e99h2121/items/be3a2399a4655baba40f)
[記事やソースコードを公開するときに気をつけていること - Qiita](https://qiita.com/e99h2121/items/f580aa695bdd58dd80bc)

ということで、明日から12月だなというポエムでした。
参考になればさいわいです。
ImportError: cannot import name 'texttospeech_v1' from 'google.cloud' (unknown location)

おはようございます。朝からAnacondaを再インストールしていると、Google Text-To-Speechのコードが動かなくなり、困りました。

Windows11 > Anaconda > Jupyter Notebook/Lab で下のエラーメッセージ出たときのお直し忘備録を記載しておきます。

:::note alert
ImportError: cannot import name 'texttospeech_v1' from 'google.cloud' (unknown location)
:::

```python:Python
pip install google-cloud-texttospeech
```

```python:Python
def explicit():
    from google.cloud import storage

    # Explicitly use service account credentials by specifying the private key
    # file.
    storage_client = storage.Client.from_service_account_json(
        'service_account.json')

    # Make an authenticated API request
    buckets = list(storage_client.list_buckets())
    print(buckets)
```
https://cloud.google.com/docs/authentication/production?hl=ja

以上です。。
AtCode ARC113 -B A^B^C 解

##問題概要
正整数A,B,Cに対して$A^{B^C}$の1の位を求めよ。

* 制約
    * $1 \le A,B,C \le 10^9$

https://atcoder.jp/contests/arc113/tasks/arc113_b
##考察
愚直解では間に合わないので計算量を落とす。

$A^{B^C}$ の1の位とは$A^{B^C}$ のmod10での値のこと。
Aは1桁目しか興味がないので初めから`A %= 10`としてよい。これでもまだ間に合わないので$B^C$の桁も落としたい。

10は素数ではないので、フェルマーの小定理によってnestされた累乗を計算することはできない。そこで、Aのmod10での周期p(必ず10以下になる)を使って、$B^C$の桁を落とすことを考える。

$B^C$のA(mod10)-周期成分は除いてよいので、$B^C$を`power = pow_mod(b,c,p)`に代えてよい。この`power`は周期p以下になるので、以降の計算量は極小で済む。

周期pはループを回して強引に求めてしまえばよい。今回のケースでは、どうせ10回(=modの値)もかからないので。

##実装
```cpp
int main() {
    const int mod = 10;
    // read input
    auto a = in<ull>() % mod;
    auto b = in<ull>();
    auto c = in<ull>();

    // trivial case: mod period = 1
    // e.g., 5*5 = 5 mod10
    if (a <= 1 || a == 5 || a == 6) {
        print(a);
        return 0;
    }

    // calc non-trivial mod period of a.
	// d is a temporary variable
    ll d      = (a * a) % mod;
    ll period = 1;
    while (d != a) {
        d *= a;
        d %= mod;
        ++period;
    }
    ull power = pow_mod(b, c, period);
    // power must be positive
    if (power == 0) power = period;

    // show
    print(pow_mod(a, power, mod));
}
```
ウィトゲンシュタインとボブおじさんのおかげで私は2つの誤解が解けた結果、仕事における胆力と責任感が増した気がするゴリゴリの主観ポエム

この記事は [Ateam Lifestyle Inc. Advent Calendar 2021](https://qiita.com/advent-calendar/2021/ateam-lifestyle) 11日目の記事です。

この記事では、ある２人のおかげで私は2つの誤解が解け、それによって仕事に生かせそうな感じがしてるのでエピソードと合わせて紹介しています。

ゴリゴリの主観ポエムです。

## 丁寧に、論理的に説明すれば分かってくれるという誤解

自分では丁寧に説明したと思っていても、大事なところが伝わっていなかったという経験はありませんか？もしくは、「こんなに丁寧に説明したのに、なんで伝わらないんだ」なんて経験はないでしょうか。

私は何度か経験していて、自分の伝え方に問題があると思っていました。

20世紀を代表する哲学者ウィトゲンシュタインの著書「哲学探究」では**私たちは、理解し合うために言語を使うが、だからと言って私たちの頭の中にある物事の理解や定義・思考などが、言語を通じて相手にそのまま送られるわけではない。**って感じのことを言ってます。

https://www.iwanami.co.jp/book/b261168.html

「言語によって人と人がわかり合うことはありえない」的なことも、ウィトゲンシュタインは言っています。

たしかに

- 自分が苦労して覚えた
    - フレームワーク
    - 新しいツールの使い方
    - プログラミング言語
- 長年運用して得た現状のシステムの仕様や課題感
- いろいろ検証してやっと見つけた不具合の原因

それらを、チャットや口頭で聞いただけで相手が分かる（自分と同程度理解できる）なら苦労しませんよね。

また、ウィトゲンシュタインは、こんなことも言っています。

> 私たちが理解し合うためには「定義の共有」ではなくて「経験の共有」が必要

これは私の解釈ですが、**理解してもらうためには、相手にも同じような苦労（経験）が必要**だと思っています。

もちろん、いちいち相手に同じような経験をしてもらうのは不効率です。しかし、上記の内容をあたまに入れておくだけで、「なんで分からないんだ。。」というフラストレーションは貯まりにくくなるのではないでしょうか。

また、もっと丁寧に説明しようという気持ちも湧いてきます。聞き手に回る時も、理解したフリをせず、理解に徹する努力をしていこうと思えました。

ありがとう、ウィトゲンシュタイン。

## スーパーエンジニアが全てを解決してくれるという誤解

スーパーエンジニアの存在を認めてしまったが最後、「自分がこのシステムを守るんだ」という最後の砦の意識はなくなりますよね？どうしても。

ですが、スーパーエンジニアだってただの人です。例えば、本番環境で不具合が起こった時、どれほどスーパー優れたエンジニアであっても、我々と同じように体系的に、論理的に問題を解決していくはずです。多少勘が働いて解決が早いだけです（それがすごいってのもありますが）。

むちゃくちゃ先を行ってるように見えて、実は昨日仕入れた知識かもしれません。スーパーエンジニアだってかつては全くコードが書けなかったはずです。そこから長い時間をかけて自分を磨き、好奇心を持ち続けた結果スーパーエンジニアになれたのだと思います。

であれば、誰だって再現可能です。

なので、自分と比べて悲観せず、粛々とやるべきことをやっていきましょう。そして、不具合の鎮火をいつまでもスーパーエンジニアに頼っていては一生成長できません。

ボブおじさんだって**「プロのエンジニアとは自分の製品に責任が取れる人でそんな奴が成長するよ」**とか言ってました。

https://books.google.co.jp/books?id=nAmODwAAQBAJ&pg=PA134&lpg=PA134&dq=robert+c+martin+Take+responsibility&source=bl&ots=eqrEKMG4iA&sig=ACfU3U2CXOF6FZSjAz4B6lTgB1kKr-JH2A&hl=ja&sa=X&ved=2ahUKEwjvodG6sbv0AhXrsVYBHeA4DZ8Q6AF6BAgTEAM#v=onepage&q=robert%20c%20martin%20Take%20responsibility&f=false

不具合が起こったら、最初のうちはトンチンカンなことをやってしまうかもしれません、そして怒られるかもしれません。ですが、態度だけはボブおじさんの言う通り、**自分が責任を取るんだ**という態度や覚悟が成長を促すのかもしれません、

なので、スーパーエンジニアを英雄崇拝せず、自分が責任を持ってトンチンカンかもしれなくても恥かいてもTRYしていこう鎮火していこう！と思えました。

ありがとう、ボブおじさん。

## アウトプット100本ノック実施中

こんなゴリゴリの主観ポエムを最後まで読んでくれてありがとうございました！

https://qiita.com/ryosuketter/items/713474dbd009870e4103

お時間がある時にでもどうぞ :tea:
AWS Certified SysOps Administrator - Associate に合格しました

2021/11/29に SOA に合格しました。新試験になりラボが追加されたので、どうなるのか不安でしたが、ぎりぎりですが無事に合格できました。
![AWS-Certified-SysOps-Administrator-Associate-pdf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/780549/403179dc-fd2d-8485-45b5-1bc9950040a8.png)

## ラボ対策

新試験となって日が浅いので、まだまだラボ試験対策の情報が少ないですが、可能な限り情報を集めました。その上で、下記のような対策・ヤマをはりました。

- SQS, SNS, Lambda, S3, RDS は、サービスを新規作成できるようにする。プラスアルファで、下記のような問題を想定しました。
    - SQS は、メッセージの送信とポーリングを開始してメッセージを受信する
    - Lambda は、バージョン管理、メモリの調整、IAMロールを作成して CloudWatch Logs への書き込み権限
    - RDS は、KMS を使用した暗号化、スナップショットの作成、スナップショットからの復号方法
    - S3 は、オブジェクトのライフサイクル
- CloudFormation はリソースの変更ができるようする。
- ネットワーク周りだと、VPC を作成して Public サブネットと Private サブネットを作成できるようにする。

2021/12/31 までに試験の登録をするとラボ試験のサンプルが利用できるので、SOA を受験する予定がある人は、期限が迫っているのでお早めに登録した方がいいです。そして、ラボ試験のサンプルを受験してどんな感じの問題がでるのかを確認すると、さらに対策を立てやすくなります。

## 感想

ラボ問題は、問題文中に誘導（センター試験での数学みたいなやつ）があればそこまで難しくない、あるいは、そこまで点数を落とすことはないと思いますが、誘導がなくてかつ一度も作成したことがないサービスの場合は、キビシイと思います。
Alexaとラズパイを連携して音声でスクリプトを実行する

# 概要

Alexaとラズパイを連携してラズパイ内のスクリプトを実行する方法を紹介します。
これを活用することで、Alexaに呼びかけて、ラズパイに接続した赤外線LEDを動作させて照明のON/OFFをしたり、PCをWOL(Wake ON Lan)で起動させたりすることができます。
(他にも色々スクリプトで実行できることならアイデア次第で色々できると思います)

# 仕組み

[Node-RED Alexa Home Skill Bridge](https://alexa-node-red.bm.hardill.me.uk/) でデバイスの登録を行い、
RaspberryPi上にインストールした [Node-RED](https://nodered.jp/) に紐付けし、コマンドを実行させる

# 導入

## ラズパイにNode-REDをインストール

```shell
## Node-REDのインストール
$ bash <(curl -sL https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/update-nodejs-and-nodered)
## サービスの自動起動設定
$ sudo systemctl enable nodered.service
```

## Node-RED Alexa Home Skill Bridgeの設定

### アカウントの作成

https://alexa-node-red.bm.hardill.me.uk/

からアカウントを作成を行う。

### デバイスの登録

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/77c14a1e-5e0c-c310-4abe-4e280358b158.png)

`Add Device`からName、Description、スイッチの種別を選択する。


## Node-REDの設定

### node-redの起動

ラズパイでnode-redを起動しておく

```shell
$ node-red-start
```

起動後、ブラウザで [http://xxx.xxx.xxx.xxx:1880/](http://xxx.xxx.xxx.xxx:1880/) へアクセス(xxx.xxx.xxx.xxxはラズパイのIPアドレス)

### 各動作ノードの追加

画面が開けたら右上ハンバーガーメニューからパレットの管理を選択

![Untitled (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/c23bdbc4-f2f5-d68e-eb83-e469630a2536.png)

`ノードを追加`タブで`node-red-contrib-alexa-home-skill`を検索し、ノードを追加ボタンをクリック

![Untitled (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/775433f6-2e01-24b0-a6be-c56a5823013d.png)


起点として `alexa-home`
それを受けて `Switch`
分岐先に `exec`
終点に `debug`
のノードを配置する(下図は完成形の図)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/75e33986-2510-e399-c558-f90b3928bf69.png)

### akexa-homeノードの設定

`alexa-home`のノードをクリックすると設定画面が開くので、Account：`新規にalexa-home-conf`を追加を選択し、鉛筆アイコンをクリック→Node-RED Alexa Home Bridge で登録したアカウント情報を入力すると、Deviceの欄に登録したデバイスが表示されるので選択する

![Untitled (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/dab2abd1-f06a-f1e6-fd66-0470ee2ceb43.png)

### switchノードの設定

`switch`のノードをクリックすると分岐条件を追加できるので追加する（スイッチ系の場合は「つけて！オン！」の場合 `is true`、「消して！オフ！」の場合`is false`となる）

![Untitled (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/73deaf19-c436-3ed1-aa09-10f9a937a44d.png)

`is true`や`is false`の先にexecのノードを配置する

![Untitled (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/04805ce1-3aeb-b53f-5e97-d0b87e9d2391.png)

### execノードの設定

`exec`コマンドをクリックすると実行コマンドを割り当てられるので、ラズパイ上でshellを記述して、パスを指定する

![Untitled (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/d0fbe4cd-af26-fce6-4b0d-570c628ace0b.png)

## Alexaに Node-RED のスキルインストール

AmazonAlexaアプリもしくは[https://alexa.amazon.co.jp](https://alexa.amazon.co.jp/) からNode-REDのスキルを検索し、インストールする
![Untitled (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127686/34e03d4e-b97d-c4d9-8f3d-11cc039548eb.png)
有効にしたときにログイン情報が聞かれるので、Node-RED Alexa Home Skill Bridgeで登録したユーザ情報を入力する

## 動作確認

ここまでの設定でNode-RED Alexa Home Skill Bridgeで登録したデバイス名 + 「つけて！オン！」のようにAlexaに呼びかければラズパイでコマンドが実行されるようになります。
Python初心者がノンプロ研でPython学んでみた vol.3

# はじめに
こんにちは、な～です。ノンプロ研でPythonを学び始めました。その学びについての第3段です。

# 今回学ぶこと
- リスト
- タプル
- 辞書

# リスト
リストはインデックスで管理するデータの集合です。
リストは角括弧[]内に、リストの要素をカンマで区切って並べます。
また、要素を呼び出すときは、リスト名[インデックス]で呼び出すことができます。
![20211124初心者講座Pythonコース-03 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1208544/4533ca63-1b21-d34e-7ac4-79906e303865.png)
また、リストの部分選択をスライスといいます。
リスト名[開始位置,終了位置、増分]でリストの部分選択ができます。

![20211124初心者講座Pythonコース-03 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1208544/b7d9350e-8ce3-6302-7286-614296197319.png)
リスト要素の存在チェックは、値 in リストで確認できます。

![20211124初心者講座Pythonコース-03 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1208544/bf3547de-6d47-ca8a-b3cb-b9f464e4f7d4.png)
for inを使って、リスト内の要素１つ１つについて繰り返し処理ができます。

![20211124初心者講座Pythonコース-03 (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1208544/feb144d4-76fa-ef6b-4cbc-a184b4c160b4.png)

2次元リストは、[]の中に[]を入れることによって表現できます。
number = [[10, 30, 20, 40],[11,31,21],[12]]
number[0]では、外側の配列の1つ目の要素（[10, 30, 20, 40]）が取得できます。
number[1][2]は、外側の配列の2つ目の要素の中の3つ目の要素（[21]）が取得できます。

# タプル
タプルは、インデックスで管理するデータの集合ですが、リストとは違いタプルの要素は上書きが禁止されています。
![20211124初心者講座Pythonコース-03 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1208544/cd30fe4a-ee19-72cc-1140-8d7a05e94edb.png)
タプルは、括弧()内に、タプルの要素をカンマで区切って並べます。また、要素を呼び出すときは、タプル名[インデックス]で呼び出すことができます。
タプルは、リストと同じように「値 in タプル」で存在確認をしたり、「for 変数 in タプル」で繰り返し処理ができます。

# 辞書
辞書とは、キーで管理するデータの集合です。
辞書は、{}の間にキー:バリューをセットにしてカンマで区切って定義します。
{キー1: バリュー1, キー2: バリュー2, …}
要素の参照は、辞書[キー]です。
また、存在しないキーを使って代入すると辞書に要素を追加できます。
![20211124初心者講座Pythonコース-03 (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1208544/d0bb872d-720a-7458-6e71-f1c745ff13c9.png)
リストやタプルと同じように「値 in 辞書」で存在確認をしたり、「for 変数 in 辞書」で繰り返し処理ができます。ただし、「for 変数 in 辞書」の変数はキーになるので注意が必要そうです。

# まとめ
今回は、リスト・タプル・辞書について学びました。
まだまだ、しっかりイメージできている自信はありませんが、GASの配列やオブジェクトと比べたり、使っていくことでしっかりと身に付けたいです。

いつものように、ツイートもまとめました。
[ノンプロ研 Python初心者講座第3回目 byな～](https://togetter.com/li/1807528)
AtCoder ARC112 B - -- - B 解

##問題概要
整数Bと正整数Cが与えられる。以下の操作を総コストがCを上回らない範囲で任意回数行うとき、作ることができる整数は合計でいくつあるか。
1. Bに-1をかける。コストを1だけ支払う。
2. Bから1を引く。コストを2だけ支払う。

* 制約
    * $-10^{18} \le B \le 10^{18}$
    * $1 \le C \le 10^{18}$

https://atcoder.jp/contests/arc112/tasks/arc112_b

##考察
整数を作る過程は以下4種類に分類できる
(a) $\|B\|$から操作2で原点まで下る
(b) (a)の途中または終わりに操作1によって負領域に折り返す
(c) $-\|B\|$から操作2によって-∞方向に下る
(d) (c)の途中または終わりに操作1によって正領域に折り返す

(a)(b) では絶対値が $\|B\|$ 以下の整数の部分集合を作ることができ、(c)(d) は絶対値が $\|B\|$ より大きい整数の部分集合を作ることができる。

### (c)(d)ケース
(c)にコストを全振りして$-|B|-N$まで負数を作ったとする。$-|B|-1,...-|B|-N$を正領域に折り返す際、払えるコストが1余っていれば、これら$N$個の負数を全て正領域に折り返すことができる。余っていなければ折り返せるのは$-|B|-1,...-|B|-(N-1)$だけになる（$-|B|-N$を作るコストを$-|B|-(N-1)$の折り返しに当てる）。つまり、予算が奇数あれば作った負数を全て折り返せるが、偶数だと奇数ケースより1減る。

### (a)(b)ケース
ほぼ同様の議論ができる。(a)によって0に到達し得るか否かで場合分けが発生することに注意。到達し得るなら作れる数は$\|B\|+1$個。$+1$は0の分。到達し得ないなら(c)(d)のように予算の奇偶で生成個数が分かれる。

##実装
絶対値が $\|B\|$ 以下の整数の数を数える関数`count_in`と、絶対値が $\|B\|$ より大きい整数の数を数える関数`count_out`を作ればよい。

以下の実装では、Bの正負によって各count関数の数え始めの位置をどこにセットするかが変わるため引数が多少動いている。

たとえば、`count_in`はB>0に対して定義したが、`count_out`は B<0 に対して定義したため、B>0 ケースではBの値を負数側に折り返した後の予算`c-1`を`count_out`に渡している。

```cpp
int main() {
    // read input
    auto b = in<ll>();
    auto c = in<ull>();
    // assume b > 0. count intergers |x| <= |b|
    auto count_in = [](const ull &b, const ull &c) -> ull {
        if (b > c / 2) { // touch 0 ? -> NO
            // #{x: 0 <= x <= b}
            ull pos = c / 2 + 1;
            return (c % 2 != 0) ? 2 * pos : 2 * pos - 1;
        } else {
            // b,-b,(b-1),-(b-1),..., 1,-1,0
            return b * 2 + 1;
        }
    };

    // assume b < 0. count intergers |x| > |b|
    auto count_out = [](const ull &c) -> ull {
        if (c <= 1) return 0;
        // #{x: x < b}
        ull neg = c / 2;
        return (c % 2 != 0) ? neg * 2 : neg * 2 - 1;
    };

    // show
    if (b > 0) {
        print(count_in(b, c) + count_out(c - 1));
    } else if (b < 0) {
        print(count_in(-b, c - 1) + count_out(c));
    } else {
        print(1 + count_out(c));
    }
}
```
SchemaSpyでER図を自動生成

この記事は　[ZOZO #3 Advent Calendar 2021](https://qiita.com/advent-calendar/2021/zozo) ３日目の記事になります。

DBのテーブル設計ってみなさんどうしていますか？
最初に図に書いて、あとは実テーブルみれば、、、というのが多いかと思います。

[SchemaSpy](https://schemaspy.org/)というツールを使うと、実テーブルからER図をHTMLで自動作成してくれます。

俯瞰的にテーブル設計を見直したい場合などに使うとよいでしょう。

使い方は簡単で、
[github](https://github.com/schemaspy/schemaspy)からjarファイルをダウンロードできますので、これを実行するだけです。

```bash
java -jar $PWD/lib/schemaspy-6.1.0.jar -t h2 -db ./testdb.db -u sa -o ./build/schemaspy -dp ./lib/h2-1.4.200.jar
```
引数は以下の通り
-t: データベースのタイプ
-db: 接続するデータベースの名前
-u: データベースユーザーID
-o: 出力ディレクトリ
-dp: JDBCドライバ
詳細は[ドキュメント](https://schemaspy.readthedocs.io/en/latest/index.html)を参照してください。

私達のチームとしての使い方は、gradleにタスクを仕込んで、CIで自動生成したり、h2で[Flyway](https://flywaydb.org/)を毎度migrateして、Flywayのテストを兼ねて実行したりと言った使い方をしています。

また、テーブルに設定したコメントも表示してくれますので、CREATE TABLEではコメントを積極的に入れるといいと思います。ファイルのコメントは読み取ってくれないので、DDL内にコメントを仕込む必要があります。

```sql
CREATE TABLE stores
(
    store_id INT NOT NULL comment 'ストアID',
    store_name VARCHAR(100) NOT NULL comment 'ストア名',
    pref_id INT  NOT NULL comment '都道府県ID'
    PRIMARY KEY (store_id)
    FOREIGN KEY (pref_id) REFERENCES prefs(pref_id)
) comment ='　ストア';
```

こんな感じで出力されます。

![スクリーンショット 2021-11-30 1.16.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150455/a93571b4-f1ee-d417-338a-aaffd5f3bf62.png)

![スクリーンショット 2021-11-30 1.16.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150455/1b0b2300-3398-ca30-63e7-05098456e1d5.png)

![スクリーンショット 2021-11-30 1.18.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150455/6ac0aef9-adb8-f9ee-3be2-272a0f773600.png)


明日は、@naoya_s　による「Code With Meについて書く」です。同じ開発チームのメンバーによる記事になります。モブプロでCodeWithMe使えるのかどうなのか？お楽しみに！
M5StickC / M5StickC PLUSの省電力についてもう少し調べてみた

以前、[M5StickCのDCDCをオフにしたら稼働時間が倍に延びた話](https://qiita.com/sullblue/items/d1bcd7c099fbcd26bb26)という記事を投稿しました。
その時 M5.Axp.beginでなにやらできることは分かっていたのですが、「目的は達成したしまあいいか」と思って深くは調べてませんでした。
今回ちゃんと調べてみました。

#M5.Axp.beginで一体何をしているのか
GitHubで見てみると、Axp.beginには引数が6つあります。

```
void AXP192::begin(bool disableLDO2, bool disableLDO3, bool disableRTC, bool disableDCDC1, bool disableDCDC3, bool disableLDO0)
```

DCDC3というので5V出力をオンオフできることは前回調べました。
ついでに**DCDC1をいじるとM5StickCが操作できなくなる**というのも経験しました。
じゃあその他は一体何なのか。

###公式ドキュメントにあたってみる
[公式ドキュメントm5-docs](https://docs.m5stack.com/en/products)
ここのM5StickCのページをみると、PINMAPのところに_Power structure block diagram_という図があります。AXP192のどのピンからどこに供給しているかという図の様です。
こうなっていたんですか、なるほど……

M5StickC PLUSのページも確認しましたが図は共通でした。

内容をまとめてみます。
それぞれ、次の機能をオンオフできることがわかりました。

| LDO2 | LDO3 | RTC | DCDC1 | DCDC3 | LDO0 |
|------|------|------|------|------|------|
|TFT|TFTバックライト|リアルタイムクロック|ESP32、MPU、3V3|5V|MIC|

###まとめ

DCDC1はESP32本体に電力を供給していたんですね。**それをオフにしたら操作できなくなくなるわ。**
あと、MPUあんまり使ってないんでオフにしたかったんですが、そうはいかないみたいですね……
そして最近追加されたLDO0はマイクに繋がっていました。こっちはオフにする意味あるんかな……？

今回しらべてみていろいろ分かりました。
とりあえず**公式ドキュメントに勝るものはない**という事ですね。
つい日本語の記事を探しがちなんですが、いざとなったら公式ドキュメント。肝に銘じておこうと思います。
【AWS】AWS Amplify基礎と学習の道標

## 概要
AWS Amplifyは、Webおよびモバイルアプリ開発のためのプラットフォームです。
サーバレスなバックエンドの構築からWebサイトのホスティングすることができます。


### サービス・ツール群
Amplifyでは下記のサービス・ツールを利用してアプリケーションを構築、デプロイすることができます。

* Amplify CLI  
コマンドでAWSのサービスを利用したバックエンドを構築、管理することができるインターフェースです。
* Amplify Libraries  
ユースケースに合わせた様々なリソースを利用することができます。(認証、データストア、API等)  
iOS、Android、Web(React,Vue)といった複数のクライアントに対応しています。
* Amplify Console
静的なWebサイトのホスティング、Gitとの連携、CI/CDを提供するサービス。
* Amplify Admin UI
コンテンツ管理ができるサービス。

### 参考
基本的には、下記のサイトから学習を進めることを推奨します。
BlackBeltセミナーからワークショップ、事例やチュートリアルまで幅広いコンテンツが提供されています。
公式ドキュメントは英語のみですが、チュートリアルやAPIリファレンスが充実しています。

[Amplify学習リソース集](https://github.com/aws-amplify-jp/awesome-aws-amplify-ja)


[Amplify 公式ドキュメント](https://docs.amplify.aws/)
Mi 9T pro(グローバル版)でAmazon Primeを高画質で見たい！

## 初めに
`Mi 9T Pro`は**HDR10+**や**Widevine L1**をサポートしている！！
…にもかかわらず`Amazon Prime Video`で映画を見るとSD画質並みの粗さでしか見られない…

### そんなの勿体ないよ！！！！！！！！！！

ということで見られるようにしてみる。

## 本題
`google playストア`で`Prime Video`のアプリ詳細からベータテストに参加するだけ！
参加後、数分後にアップデートが可能になる(来ない場合は、アップデート管理画面に行くとアップデート待ちとなっているかも)

すると、`Prime Video`の設定で`パフォーマンス改善モード`が選択できます！！！
Rでのファイル操作/文字化けの対策をしたい/CSVファイル

# ファイルの読み書きをする

## CSVファイルの読み書き
# 読む
```r
read_csv("ファイル.csv")
```
# 書く
ここでは使用中のディレクトリが自動で保存先となる。
_row.names = FALSE_を書くと、一番左の列に数字が入ることを防ぐことが出来る。

```r
write.csv(df,"df.csv",row.names = FALSE)
```

# 文字化け対策
しかしファイルには文字コードというものがあり、それが違うファイルを開くと文字化けしてしまう。
Windowsz→Shift-jis
mac→UTF-8
が使われていることが多い。

**読みでは元の文字コード、書きでは書きたい文字コードを指定することで文字化けを防ぐことが出来る。**

# 読む
```r
read_csv("data/data_utf8.csv", locale = locale(encoding = "utf8"))
```

# 書く
```r
write.csv(df,"df.csv",fileEncoding="CP932",row.names = FALSE)
# CP932はShift-Jisのことを指している。
```
WEBアプリでSmartHome 家電編 Node-RED+RaspberryPi+IRkit

前回
----------------------------------
Node-RED＋RaspberryPiで照明をコントロールするアプリを作成しました。
下記参照。今回は、照明だけでなく、赤外線で操作可能な家電を追加しました。

https://qiita.com/taisuke0430/items/58a401d55b64335a51f7

構成
----------------------------------
RaspberryPiに加えて、IRkitを用いて操作する構成にしています。

IRkit（生産終了）

https://getirkit.com/

全体システム構成
![スクリーンショット 2021-11-30 0.32.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204852/e05c85f0-170f-da89-6bf9-7b2ed3ec1d12.png)

Flow
![スクリーンショット 2021-11-25 22.48.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204852/958b4152-c19b-5174-26e8-0fd9debb6028.png)

<img width="400" alt="スクリーンショット 2021-11-23 0.56.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204852/dcd0c17e-a617-d70a-815d-3ec0c48ef17f.png">

IRkitに記憶したい赤外線リモコンを送信し、下記をコマンドラインに打ち込んで赤外線信号を取得する。
curl -i "http://IRkitIPアドレス/messages" -H "X-Requested-With: curl"

<img width="400" alt="スクリーンショット 2021-11-23 0.57.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204852/e70a6913-83b8-41ee-1442-30ec27aa8609.png">


IRkitのIPアドレスを指定。
<img width="400" alt="スクリーンショット 2021-11-23 0.57.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204852/be47d4f7-6855-c212-b3f5-c8d6432eb0b8.png">


デフォルトのNode-RED　Dashboardを使って、下記のようにまとめています。
TVは単純ですが、エアコンだけは温度毎のデータを取得しないといけないので、かなり手間なのと合っているか確認する術がないので、よく使う温度帯とOFFボタンを設けるようにしています。
<img width="400" alt="IMG_3011.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204852/fb475521-f46c-99ea-7a5f-2212e208f8aa.jpeg">


参考
---------------------------
https://getirkit.com/

https://helloworld.sakura.ne.jp/db/?p=1424
女子美術大学にロボットアームを使ってもらった結果（概要、1班まで）

# 恒例の女子美
がじぇるねGRは2017年から女子美術大学 プロダクトデザイン課の授業を支援して参りました。

今年はその5年目。今回のテーマは、
「ロボットアームを使って人の心を豊かにするプロダクトを提案」

気づきからリサーチ、アイディア展開・プロトタイプモデル・提案までの一連のデザインプロセスを実践！20名の学生が集ってくれました。がじぇるねGRからはGR-ROSE、3軸ロボットアームをご提供します！
![joshibi1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161718/ab4a7416-7c0c-a388-f729-1e327e2791c1.png)
#スケジュール
期間は約2か月です。製作(モデル作成)は約1か月ですので、普段の授業やアルバイト(?)とかも兼ねて学生の皆さんは激務の期間を過ごすことになるのです。
(でもいつもはきはきと元気で、礼儀が正しい印象の美大生です)。
- 9/13  &nbsp;&nbsp;課題説明・講義＆ワークショップ
- 9/17  &nbsp;&nbsp;アイディアチェック
- 9/24  &nbsp;&nbsp;ペルソナ＆カスタマージャーニーマップ発表
- 10/1  &nbsp;&nbsp;ストーリーチェック
- 10/8  &nbsp;&nbsp;中間報告会 (モデル作成開始)
- 10/15 &nbsp;企画案・プロトタイプモデル中間チェック
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(モデル作成＆プレゼン作成)
- 11/5  &nbsp;&nbsp;講評会

#1班「えびだっぴ」
![joshibi2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161718/91dc14cb-ff5e-4443-d10a-52523529b1a6.png)
ペルソナは大学生まほちゃん20歳。コロナで友達にも会えず、小さなストレスが蓄積。誰かに打ち明けずらいこのストレスを発散させるプロダクト。どちらかといえば内向的なまほちゃんだが、内向的な人でも外向的な要素も持ち合わせるもの。ストレスの発散方法は発散系・浄化系、動的・静的の2軸で4つに分類される。今回はえびだっぴを用いて発散系の動的アプローチでストレスを発散するプロダクトを考えた。
えびだっぴは元々はむきえび。自慢のシックスパックをもっている。いつの日かスーパーでエビフライデビュー・・。といったストーリーからこのシュールなプロダクトは生まれた。

https://youtu.be/DsfzWnZrmyc

##プロトタイピング
ロボットアームをRandomに動かすだけですが、電源ON/OFFのたびに動きのパワーが激しくなったり、緩やかになるようにしています。
基本は即興のコードですので、スパゲティなのはご理解ください。

```
#include <EEPROM.h>
// pin 10: Pressure sensor, GND 330 ohm
#include <ICS.h>

#define KRS_MIN 3500
#define KRS_MAX 11500
#define KRS_ORG 7500
#define KRS_FREE 0
#define SERVO_MIN -135
#define SERVO_MAX 135

IcsController ICS(Serial1);
IcsServo servo[3];

void krs_setfree(IcsServo* servo){
  servo->setPosition(KRS_FREE);
}

int krs_getposition(IcsServo* servo){
  return map(servo->getPosition(), KRS_MIN, KRS_MAX, SERVO_MIN, SERVO_MAX);
}

void krs_setposition(IcsServo* servo, float radian){
  int angle = radian * 180 / PI;
  int pos = map(angle, SERVO_MIN, SERVO_MAX, KRS_MIN, KRS_MAX);
  if(pos > KRS_MIN && pos < KRS_MAX){
    servo->setPosition(pos);
    delay(1);
  }
}

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (float)(x - in_min) * (out_max - out_min) / (float)(in_max - in_min) + out_min;
}

void setup() {
  Serial.begin(9600);
  ICS.begin();
  int setting;
  if(EEPROM.read(0) == 0){
    setting = 30;
    EEPROM.write(0, 255);
  } else {
    setting = 120;
    EEPROM.write(0, 0);
  }
  for(int i = 0; i < 3; i++){
    servo[i].attach(ICS, i+1); // id1 to id3
    servo[i].setStretch(setting);
    delay(1);
    servo[i].setSpeed(setting);
    delay(1);
    krs_setposition(&servo[i], 0);
    delay(1);
  }
}

void loop() {
  for(int i = 0; i < 3; i++){
    int angle = random(-45, 45);
    float radian = angle * PI / 180;
    krs_setposition(&servo[i], radian);
    delay(100);
  }
}
```
今回はここまでです。次回2班、3班をお楽しみに！
2021年 GOJAS活動報告

GOJAS のOrganizerをしています[山田](https://www.facebook.com/yamadanoel/)です。

あまり明るい報告はできないのですが、2021年のGOJASの活動実績は、、、なんと２回!!たったの2回....
振り返ってみると、あのときもう少し工夫すれば違う結果になっていたかなー、、と反省しかありません。スミマセン....
私事ではありますが、4月に長男が誕生しまして、初めての子供ということもあり、すったもんだしていました。

2021年初頭の目標では、最低３ヶ月に１回はMeetupを開催したいなと考えていたのですが、実現できず。
実は5月にMeetupを計画していたのですが、流会となりました。無念。
だがしかし。2021年も残り１ヶ月ですが、12月中にMeetupの開催を目指しています!!

さて、2021年のGOJASへの新規登録者数と累計参加者数を可視化してみました。

**新規参加者数**
![GOJAS新規登録数2021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528751/09851daf-4567-7dfc-56c6-c9f2665d0ed6.png)

**累計参加者数**
![GOJAS累計参加者数2021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528751/3fd985eb-3ef1-4684-0bb9-9d34e77ccd77.png)

2021年の新規登録者数は83名、累計参加者数1,226名です。
1年前のちょうど今ごろ、1,000名超えたヒャッホーイ!!と浮かれていましたが、熱量が下がってしまいました。
コロナが落ち着くまではVirtual Meetupでの開催となり、多くの制約の中、どうすれば満足度向上につながるか、どうすれば盛り上がるかを、引き続き検討・検証を続けていこうかと思います。
2022年にはオフラインで賑やかなMeetupができることを祈っております!!

GOJASでは、運用スタッフや講演いただけるかたを大募集しております。
ご興味があるかた、まずはお気軽に相談からしましょう!!
ご連絡お待ちしております。
Next2D入門

# Next2Dプロジェクトとは
JavaScript製FlashPlayer「swf2js」から派生したプロジェクトです。
swf2jsはエミュレーターとして完成し、そこで得た技術を次代に活用するべく、Next2Dプロジェクトを開始しました。

Next2Dには、大きく3つの機能があります。

## Next2D Player
WebGL対応の2D描画ライブラリで、ブラウザやデバイスの互換性を気にすることなく、リッチでインタラクティブなグラフィックス、クロスプラットフォームなアプリケーションやゲームを作成することができるライブラリ
[Next2D Playerの特徴](https://next2d.app/#player)

## Next2D NoCode Tool
NoCode開発を主体としたWebブラウザ上で動作するオーサリングツールです。
イメージしたアニメーションを直感的に作成することができ、書き出したデータはWebにアップロードすることで簡単に公開することができます。
出力したJSONは、Next2D Playerで読み込むことが可能です。
[NoCode Toolの特徴](https://next2d.app/#tool)

## Next2D Framework
MVVMアーキテクチャを採用。個人でもチームでも、規模を問わず、最新の開発手法で効率的な開発をサポートします。
[Next2D Frameworkの特徴](https://next2d.app/#framework)

主にこの3つの機能を有しています。
GitHubのリポジトリは以下となります。
- [Player](https://github.com/Next2D/Player)
- [NoCode Tool](https://github.com/Next2D/tool.next2d.app)
- [Framework](https://github.com/Next2D/Framework)
 
昨年のアドベントカレンダーで、少しだけ「Next2D」の紹介をさせていただきました。
[Flash Advent Calendar 25日目 - ありがとうFlashPlayer -](https://qiita.com/ienaga/items/02ef47b2843faa8eb986#%E6%AC%A1%E3%81%AE%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88)
今日の記事は上記の記事の続きとなります。

# FlashPlayerのサポート終了
昨年、FlashPlayerのサポートが終了しました。
その結果、世の中には沢山のSWF資産が冬眠することになったかと思います。
そんな資産を再利用できる(?)`NoCode Tool`の紹介を今日は行いたいと思います。

# Next2D NoCode Toolとは
一言で紹介すると、Webブラウザ上で動作するオーサリングツールです。
インストール不要、会員登録も不要、アクセスすれば誰でも利用できるサービスです。
サイトはこちら：[NoCode Tool](https://tool.next2d.app)


基本のワークスペースはこのような名称になっています。
![workspace.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80502/b85f4e14-9a51-ccde-529a-054a665a22fa.png)

## Tool Area
描画ツール、テキストツール、プロジェクトの読込・保存、書き出し設定や言語設定など各種ツールと設定項目が設置されているエリアになります。

## Screen Area
現在のフレームでStage上に表示されるDisplayObjectの閲覧・配置・重ね順など、描画情報を確認できるエリアになります。Command+EnterまたはCtrl+Enterで、Playerのプレビュー再生が行えます。

## Timeline Area
レイヤーやアニメーションのキーフレームなどを操作するエリアになります。Label名の設定や、フレームに任意のJavaScriptを埋め込む事ができ、レイヤー毎のTweenの追加・削除のコントロールも可能です。

## Controller Area
拡大縮小/回転/カラー操作/BlendMode/Filterなど、Screen AreaのDisplayObjectの操作を行えるエリアになります。テキストデータはサイズ、スタイル、行揃えなどの設定ができ、ビデオ・音声データはループ設定や音量の設定が可能です。Libraryタブから外部データ(画像、MP4、MP3、SWF)を読み込む事ができ、JavaScriptタグではプロジェクト全体に埋め込まれたJavaScriptの一覧を確認・編集ができます。

# SWFを読み込む
本日は、昨年の続きという事でSWFファイルをどのように読み込むかを動画で紹介できればと思います。
 
## 動作動画
<iframe width="560" height="315" src="https://www.youtube.com/embed/qTUcGV5EV_8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

### SWF読み込み手順
- Controller AreaのLibraryを右クリックしてSWFを読み込む(直接ドロップも可能です)
- MovieClipをScreen Areaにドロップ
- Controller Areaで好きなサイズに変更
- Screen Areaで右クリックして動作プレビュー
 
SWFファイルはどのバージョンでも読み込み可能で、これまでの資産を再利用できます。
また、これまで通りAnimateCC(Flash)、Illustrator、AfterEffectsなどAdobe製品からSWFを書き出し、`NoCode Tool`で読み込む事でNext2D Playerで再生が可能です。
つまり、過去の資産の再利用もこれまで通りの運用スタイルも可能にすることができます。

## SWFファイルの対応範囲 
- Shape
- Bitmap
- MovieClip
- Matrix
- ColorTransform
- Blend Mode
- Filter

## 非対応機能
- ActionScript
- Text

# なぜ非対応機能があるのか
`swf2js`でエミュレートできている機能をなぜ`NoCode Tool`で対応しないのか
それは、このカレンダーを通して説明させて頂ければと思います。

本日は最後まで記事をご覧いただきありがとうございました。
`NoCode Tool`にはSWFを読み込む以外にも色々な機能があります。
そちらは明日以降でご紹介させて頂ければと思います。
Gradle project sync failed. Basic functionality will not work properly. エラーの対処法

### エラーについて

GitからCloneしたAndroidStudioプロジェクトを開いた際に`Gradle project sync failed. Basic functionality will not work properly` というエラーが発生したため、これらのエラーの対処法をまとめました。

## Android SDK Build-Toolsをインストールする

Android SDK BuildToolsをインストールしていない状態だとこのエラーが表示されるようです。

```AndroidStudio → Tools → SDK Manager``` でSDK Managerを開きます。

SDK Managerが開きますので、SDK Toolsタブを選択して、Android SDk Build-Toolsにチェックを入れてインストールしてください。

![qiita-asgps1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145857/9bc2b898-e594-6f68-20a0-11a8a3819aa6.png)

## インストールが終わったらTry Againする

エラー表示ダイアログにTry Againという項目がありますので、クリックしてください。

Android SDK Build-Toolsがインストールされていれば、エラーが解消されて無事にビルドができると思います。
バリデーションだけじゃ足りない時がある。契約について考察する。

この記事は　[ZOZO #3 Advent Calendar 2021](https://qiita.com/advent-calendar/2021/zozo) 2日目の記事になります。


バリデーションについて。普段使っているSpringFrameworkを例にとりますが、SpringFrameworkではBeanValidationの機能があり、フィールドにアノテーションを付与するだけでバリデーションが実現するというものです。

たとえばこんな感じ。

```java
public class CustomerName {
  @NotEmpty
  final String firstName;

  @NotEmpty
  final String lastName;
}
```

SpringMVCであれば、リクエストで＠Valueをつけることで自動でバリデーションを行ってくれます。

```java
@PostMapping(
        value = "/customers/cancel",
        produces = { "application/json; charset=utf-8" },
        consumes = { "application/json" }
    )
public ResponseEntity<Response> cancel(@Valid CustomerName customerName) {
    ・・・
  }
```

アノテーションを付与するだけでバリデーションしてくれるこの機能はすごい便利です。
ただ、このケースですとモデルをControllerから使う前提になり、Viewとモデルが密となる状態はいかがなものかというのもあります。

その場合、Viewのリクエストをモデルに変換し、Application層から明示的にバリデーションを呼び出す必要があります。

そのような使われ方だけならまだこれでいいのですが、このモデルが他にバッチとか、gRPCのサービスからとかからも使われるということになると、バリデーションの呼び忘れなんてこともあるかもしれません。

もっと強力に強制力をもって制御したいとなれば、BeanValidationだけだと心もとない。ということで、「契約による設計」を参考に事前条件を設定するという考えに至りました。

たとえばこんな感じです。

```java
public class CustomerName {
  final String firstName;
  final String lastName;

  public CustomerName(String firstName, String lastName){
    this.setFirstName(firstName);
    this.setLastName(lastName);
  }

  private void setFirstName(String firstName){
    if(firstName.isEmpty()){
      throw new IllegalArgumentException("firstName is required!");
    }
    this.firstName = firstName
  }

  private void setLastName(String lastName){
    if(lastName.isEmpty()){
      throw new IllegalArgumentException("lastName is required!");
    }
    this.lastName = lastName
  }
}
```

コンストラクタから呼び忘れてれば同じじゃないかというのはありますが、このクラスに閉じているので最初に作ってしまえば、あとはどこから呼ばれても強制的にこの制約が働くことになります。APIのリクエストからも、DBからの復元も、Factory使うときでも必ず呼ばれます。

もちろんsetXXXはprivateなので他から呼ばれることはありません。
テストもしやすそうですね。

契約による設計については色々なところで述べられています。
DDDに絡めてであれば、[実践ドメイン駆動設計](https://www.amazon.co.jp/dp/B00UX9VJGW/)の第5章エンティティの箇所を読むといいと思います。

もっと鈍器でよければ[オブジェクト指向入門](https://www.amazon.co.jp/dp/4798111112)の第11章が詳しいです。

アドベントカレンダー２日目は契約による設計お話でした。次の日も自分ですね。「schema_spyでER図を自動生成」というタイトルでお届けいたします。
VS CodeのTeminal標準ShellをBashからZshに移行したので覚え書

## やったこと
* mac terminal shellをbashからzshに移行
* vs codeのterminal shellの標準をbashからzshに移行
* vs codeのterminalを開くたびに更新されていくセッションコンテンツが邪魔なので表示させなくする

### 1. mac terminalのshellをbashからzshに移行

現場から支給されたmacのOSを更新(mojaveからmonterey)したら標準ShellがBashからZshに変更になっていたため、ターミナルの指示通り、下記コマンドを走らせて移行を実行

```　
$ chsh -s /bin/zsh
```

bash_profileの中身をzprofileに移動させるのも忘れずにやる

```
cat ~/.bash_profile >> ~/.zprofile
```

### 2. vs codeのterminal shellの標準をbashからzshに移行

VS CodeのTerminal標準Shellは変更されていないようだったので、指示通り同じコマンドを走らせてみる

```　
$ chsh -s /bin/zsh
```  

結果

 ```　
The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
```  

なんで・・・？
VS Codeを終了して再起動しても、Macを再起動しても上記のメッセージが出続けて消えない。
メッセージを元に検索をかけて調べてみたところ、以下のユーザ設定をsetting.jsonに追記することで解決

```terminal:setting.json
  "terminal.integrated.defaultProfile.osx": "zsh",
```

### 3. vs codeのterminalを開くたびに更新されていくセッションコンテンツが邪魔なので表示させなくする

```
session contents restored from {{current date}}
```

前回までならまだ良かったが、どこまで遡るのか増え続ける履歴の表示にうんざりして、どうにか消せないか調べたところここに辿り着いた。読んでみるとちょっと面白い。
https://github.com/microsoft/vscode/issues/136566

中身を見てみると、スレ主は相当この追加機能にまいっている様子。わかる。
結果、zshをデフォルトにするために編集したsetting.jsonに下記の記述を行うことで解決することがわかった

```terminal:setting.json
"terminal.integrated.persistentSessionReviveProcess": "never"
```

おわり！
思ってたほどトラブルはなかった。
PCのubuntu18.04LTS+ROS melodic環境をubuntu20.04LTS+ROS noetic環境にアップグレードする

# 概要
PCのROS開発環境をROS以外のアプリや設定などを変えずにubuntu18.04LTS+ROS melodicからubuntu20.04LTS+ROS noetic環境にアップグレードする


# ROS melodicのアンインストール

ROS関係のパッケージをアンインストール

```bash
sudo apt --purge remove ros-*
```


.bashrcのROS関係の記述を削除する

# ubuntu18.04LTSをubuntu20.04LTSにアップグレードする

アップグレード手順は以下記事の通り

https://qiita.com/hitobb/items/2ee9b1c2c49760976e0f






アップグレード前に以下を実行して各パッケージを最適化して
再起動

```bash
$ sudo apt update
$ sudo apt list --upgradable
$ sudo apt upgrade
$ sudo reboot
$ sudo apt --purge autoremove
```

アップグレード

```bash
$ sudo apt update
$ sudo apt install update-manager
$ sudo apt dist-upgrade
$ sudo do-release-upgrade -d
```




# ROS noeticのインストール

公式wikiの通りにインストール

http://wiki.ros.org/noetic/Installation/Ubuntu


# 参考


https://blog.adachin.me/archives/11494


https://qiita.com/porizou1/items/7c2c4b33126cfad05944
バイナリーサーチを利用して要素を検索する

調べたことを整理して落とし込めるためにまとめます。
Rubyを使用しています。


## バイナリーサーチとは
データの検索をする際に用いられる手法のことを言います。

* ソート済みのデータ
* 同一の値が存在しない配列に入ったデータ

などが対象です。

検索したい値 = A
リストの中央に位置する値 = B　
を用意し、AがBより大きければリストの左側にある値を検索対象から除外します。
これを繰り返すことで検索にかかるコストを減らすことができます。


## 実際に書いたコード
```ruby
def binary_search(array, num)
  first = 0
  last = array.length - 1

  while first <= last
    center = (first + last) / 2

    if num == array[center]
      return puts "#{num}は配列の#{center}番目に存在します"
    elsif num > array[center]
      first = center + 1
    else
      last = center - 1
    end
  end

  puts "#{num}は配列内に存在しません"
end


array=[1,3,5,6,9,10,13,20,26,31]
puts "検索したい数字を入力してください"
num = gets.to_i
binary_search(array, num)
```

検索したい値を入力すると、
「○は配列の△番目に存在します」
存在しない値なら
「○は配列内に存在しません」
という結果が返ってきます。


```ruby
array=[1,3,5,6,9,10,13,20,26,31]
puts "検索したい数字を入力してください"
num = gets.to_i
binary_search(array, num)
```
この部分で検索したい数字を入力して変数numに代入したのち、変数numと配列arrayをbinary_searchへと渡しています。


```ruby
def binary_search(array, num)
  first = 0
  last = array.length - 1
  ~省略
end
```
firstに0を、lastに配列arrayの最後に位置する値の添字を代入しています。
このfirstとlastが検索対象になります。

```ruby
  while first <= last
    center = (first + last) / 2
```
while文を使用し、firstはlastよりも小さいという条件式がfalseとなるまで処理を繰り返します。
firstとlastを足して2で割った数を変数centerに代入しています。
これは、配列arrayの中央に位置する値の添字となります。

```ruby
if num == array[center]
  return puts "#{num}は配列の#{center}番目に存在します"
elsif num > array[center]
  first = center + 1
else
  last = center - 1
end
```
if文を使用し、検索対象が配列の中央に位置する値を同じであるか、そうでないか、
また、それよりも大きい値であるかを比較しています。
同じ値であったなら配列の何番目に存在するかを表示します。
違う値であったなら、検索対象を限定して再度検索をかけるように処理を記述します。

検索対象が配列の中央に位置する値より大きい値であったなら、firstにcenterに1足した数字を
小さい値であったなら、lastにcenterから1引いた数字を再代入しています。

```ruby
def binary_search(array, num)
  while first <= last
  ~省略
  end
  puts "#{num}は配列内に存在しません"
end
```

そうして値が見つかることなくfirstとlastの値が同じになる（配列arrayの最後の値まで検証し終わる）と、while文に指定した条件式の結果がfalseとなり処理が終了します。
そして、○は配列内に存在しませんと表示されます。


## コードを書いていて感じたこと
バイナリーサーチを使用して検索をするだけなら、配列arrayの値を再代入しながら限定していくこともできます。
最初はこの方法でコードを書いていました。
ただ、結果として配列の何番目に存在するのかを表示する必要があるため、この方法ではダメだとわかりコードを書き直しました。
色々試行錯誤しましたがなかなか思いつかず、検索をすることにして見つけたのがこの方法です。
コードを読んで理解したことを思い出しながら書きました。
決して丸々コピーなんてしてません。:neutral_face:

まとめている中で検索をする処理と、結果を表示する処理は分けたほうが良かったのかな？とも思いました。

コードに関して指摘していただけると勉強の励みになります。