OmniAICreator/Qiita-1.07M huggingface dataset:
【環境構築】macOS Big Sur 11.6.1 + Dockerのpython containerにpandasをinstall

会社貸与のMacBook Proに飲み物をこぼしてしまい動かなくなったので交換してもらった。:bow_tone1:
前のマシンにはPythonやらPandasやら使いたいライブラリーを直接インストールしていたので、環境のトラブルがあった場合に色々と面倒だった。今回は素直にDockerで環境構築して、いざとなればimage捨てて作り直せばいいやと思い、環境構築の手順をロギング。

pyhtonのcontainer実行できるようになったので、自分の仕事の効率化のために書いたpythonコード実行する環境を再構築する。
ということで、今回はpandsをinstall

前回までの記事
【環境構築】macOS Big Sur 11.6.1 にDockerをInstall
https://qiita.com/cocoapuff/items/e3eee747b1aeafa32037
【環境構築】macOS Big Sur 11.6.1 + Dockerでpython
https://qiita.com/cocoapuff/items/1daaf9e91b24bc3818ad

# pandsをインストール

pythonのcontainerは動いている前提
自分macにはpipをinstallしていないので、間違ってMacのterminalで実行しても問題ないけど、cpntainer側のCLIで実行するよう気をつける

```
# pip3 install pandas
```

これだけです。

# pandasを使ったpythonコードを実行してみる

pandasをimportして使えていることを確かめる簡単なコードを書いて実行してみる

```python:pandas_test.py
import pandas as pd

df = pd.DataFrame(
        {
            'name':['itoh', 'saitoh'],
            'age':['20', '30']
        })

print(df)
```

```
# python ./pandas_test.py
     name age
0    itoh  20
1  saitoh  30
````

問題なく動いたので、pandasは使える

今日はここまで。
container内でコード書くの大変なのでVScodeで書けるようにしたい。
"データ"を扱う職種に転職してみて

2021年は目標としていた「データを扱う職種」へ転職することができました。
[昨年](https://qiita.com/Ippei_3535/items/20d5cd3125143731ca61)に引き続いての"定点観測"として、転職活動の振り返りや、これまでの経験の中で転職後に活かせたと感じる点を箇条書きベースでまとめたいと思います。

#自己紹介・経歴

理系の大学院（非情報系）を修了後、事業企画を3年、エンジニアを1年半ほど経験し、21年春からデータ分析・活用の支援を行なっています。

####自動車部品メーカーにて新規事業企画・マーケティング（3年）
主に事業計画の作成、M&A、投資先の管理等の業務に従事
社内、社外調整に奔走・・・
事業企画をする中で、表面的な提案しかできないことに課題を感じ、「技術的知見を持って事業企画をしたい」と考え、エンジニアへの転職を決意
####SIerでの開発業務（1年半）
主にCIツールを用いた自動評価環境構築業務に従事
チームマネジメント、顧客折衝の割合が多め

####データ分析・活用に関するコンサル・自社サービスのCS（現職）　←NEW!!
自社サービスを用いたデータ活用、出力されたデータの可視化などの業務を行なっています。

#転職活動の振り返り
####転職活動で重視した点
* データ分析や利活用の検討をする職種であること
* 顧客とのやり取りを行えること
* 在住する地方都市でそのまま働けること


####使用したサービス
* Green, Wantedlyなどのサービス ←結果的にこちらを経由して転職
* 転職エージェント

リモート面接のおかげで自身での日程調整など問題なくスムーズに行えました。

####転職活動でアピールした点
* 1職目、2職目の顧客折衝経験
* データサイエンスの基礎を学んでいる点（[データラーニングスクール](https://school.data-learning.com/)での学習）

#転職後に活かせた経験
####エンジニア経験
現職ではコードを書くことはないものの、以下の際に役に立っています。

* 顧客の要望を抽出する
* 社内のエンジニアと要件について議論する

深い知識はあまり必要とせず、基本情報技術者試験の内容が概ね理解できていることが重要と感じています。

####顧客折衝経験
顧客と直接やり取りする職種なので、この経験が一番役に立っています。
顧客と同じゴールを見て"伴走"することを意識しています。

#今後に向けて学習していること
今は、在庫管理や需要予測など、「顧客の業務や改善したいこと」についての知識をつけるべく書籍、記事での学習をする毎日です。
そのほかに、Tableauでのダッシュボード作成方法を模索しています。

#おわりに

今年は、目標通りデータを扱う職種への転職をすることができました。
業務を行う中で徐々に、「データ×〇〇」の〇〇部分を具体化していきたいです。

ご覧いただきありがとうございました。
Windows デスクトップのAcrobat ReaderDCの閲覧スピードを劇的に改善する6つのキーボードショートカット

#対象としている機種
Windows デスクトップマシン
マッキントッシュ、スマホはできません
しかもReaderでの閲覧に集中しています。
ほかは知らない。

# ありそうでない・・・
[Adobe Readerの操作をスピーディに――覚えておきたいショートカット5選 2015/03/18](https://www.itmedia.co.jp/bizid/articles/1503/18/news011.html)
えええそうなの！？思っていたのと違った。。。

## 劇的に改善するショートカット
最近の研究で、大半の人がマウスをカチカチやってホイールをギャーギャー回していることがわかりました。つまりマウスをカチカチやって、ホイールをギャーギャー回す分が必要なんです。それを6つだけ覚えましょう。

### Ctrlキーに注目
今回はCTRLキーを中心にしている。覚える数が少ないほどすぐ覚えられるから。

 1. 小さくスクロール <Font color = "blue">上下矢印</font>
 2. ページ単位 <Font color = "Red">Ctrl</Font> + <Font color = "blue">上下矢印</font>
 3. ページの最初 最後 <Font color = "Red">Ctrl</Font> + <Font color = "DarkGreen">Shift</Font> + <Font color = "blue">上下矢印</font>
 4. 拡大縮小 <Font color = "Red">Ctrl</Font> + +/-
 5. ページの回転 <Font color = "Red">Ctrl</Font>+<Font color = "DarkGreen">Shift</Font>+セミコロン　「れ」って書いてあるキー
 6. 大きく(画面単位) スクロール PageUp PageDown（ノートPCの場合、FN+<Font color = "blue">上下矢印</font>など）

色々他の方法があるときもありますが、<Font color = "Red">Ctrlキー</Font>を押すことでできます。
大きく(画面単位) スクロール PgUp PgDownというのもありますが、今のノートはFNキーで矢印がPageUp PageDownになる場合もあります。ついでに覚えてください。回転は右左ありますが、一個覚えていたらそれで回せるので忘れましょう。
やっぱりPDFファイルはどうしてもページが回転していることがあります。これが閲覧効率を下げるわけですが、5を覚えると、結構改善します。

## ノートPCで劇的に改善する方法
まずノートPCの場合、***FNキー付き***キーボードを買ってつなぎましょう。***FNキー付き***だと音声くらいはコントロールできます。
するとHOME ENDで最初と最後にあっさり飛べます。今はケチっているので、EndキーとかないしPageUP PageDownがないこともあります。
Endキーがないとかなりのダメージです。
しかし、PCを持ち運ぶとキーボードがないときがあります。上記の方法はなくても使えます。

## 慌ててパニクったときのために必要なショートカットキー

### メニューバー F9

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/c36a5a87-6023-2cb6-4222-01eb735ccf39.png)

大変だ、ファイルが開けない。というのはありがち。気がつくと消えている。

### 黒くてじゃまなやつ　F8
これがツールバーらしい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/4bf363fd-8831-78f7-b653-97e53b1a9ff5.png)

###<Font color = "Red">Ctrl</Font> 0123
気持ちのいい大きさに切り替える。
どういう設定かは気にしない。
1が実際の大きさって言うけど、Readerで読むにはたいして意味がない。


### 検索は <Font color = "Red">Ctrl</Font> + F
これはどれもそうですね。

### 文書の概要とか <Font color = "Red">Ctrl</Font> + DK
***D*** 文書のプロパティ 表題とか
***K*** 環境設定
ファイルのできDKを操作(CTRL)で覚えられる

### ページの指定とか <Font color = "Red">Ctrl</Font> + <Font color = "DarkGreen">Shift</Font> + N
でもダイアログが開くのが遅い。
<Font color = "DarkGreen">Shift</Font>を忘れると、ファイルを開こうとする。

ほかは自分が何度もマウスでポチポチやるなー、って思ったときに覚える。
Readerの閲覧はキーボードショートカットなんて覚えている暇がないので、最低6つだけ覚えると十分でしょう。
上記の通り、Ctrlキーと矢印と+-でやれます。
しかし、どういうわけか、そういうのはなかったので、書き留めました。
【Python】ネストされた辞書型配列の要素を再帰的に取得する方法

###はじめに
pythonでは、JSON形式のデータをdict型（辞書型配列）に変換して扱うケースは多いと思います。その際、JSONの階層が可変であったり、list型を含んでいたりするなどの複雑な構造を持つデータに対して、特定のKeyを指定して値を検索・取得できる関数があると便利だなと考え、勉強の一環で作ってみました。

※既にあるのかも知れませんが、ググっても出てこなかったのであくまで教材・課題のつもりで...
※ご指摘、ご指南いただけるとありがたいです

###環境
macOS Monterey 12.0.1
Python 3.9.2
Visual Studio Code

###コード
関数内部で関数自身を呼び（再帰関数）、ネストが可変でも対応できるように実装。list型が含まれる場合にも対応しています。
   
```py:util.py
def dict_search(d,key):
    
    if not d or not key:
        return None
    elif isinstance(d, dict):
        if key in d:
            return d.get(key)
        else:
            l = [dict_search(d.get(dkey),key) for dkey in d if isinstance(d.get(dkey),dict) or isinstance(d.get(dkey),list)]
            return [lv for lv in l if not lv is None].pop(0) if any(l) else None
    elif isinstance(d,list):
        li = [dict_search(e,key) for e in d if isinstance(e,dict) or isinstance(e,list)]
        return [liv for liv in li if not liv is None].pop(0) if any(li) else None
    else:
        return None
```

###動作検証
実際にネスト深めのJSONファイル(sumple.json)を用意して検証してみます。同じ階層のディレクトリに以下のファイルがある環境とします。
・sumple.json
・util.py
・test.py

```json:sumple.json
{
    "data": {
        "orders": {
            "edges": [
                {
                    "node": {
                        "id": "4595490455781",
                        "nodeName": "#123456",
                        "customer": {
                            "id": "abcdefg@hijklmn.com",
                            "name": "kajuta"
                        }
                    }
                }
            ]
        }
    }
}
```
#####：使用例：
別ファイル(util.py)に関数を定義したので、from ~ importを使って関数をインポートして使用してみます。jsonファイルの読み込みについての説明は割愛します。

```py:test.py
from util import dict_search
import json

# jsonを読み込んでdictに変換
with open('sumple.json','r') as f:
    j_dict = json.load(f)

# keyを指定してdict内の要素を取得（この例では'name'の値を取得）
result = dict_search(j_dict,'name')

# 出力
print(result)
```


実行結果は以下のとおり。途中でlistを含む階層の奥にある"name"の値を取得できているのがわかります。

```console:console
kajuta
```
#####：検証：
「name」というkeyが別階層に重複して存在するサンプルで検証

```json:sumple2.json
{
    "node": {
        "id": "4595490455781",
        "name": "#123456",
        "customer": {
            "id": "abcdefg@hijklmn.com",
            "name": "kajuta"
        }
    }
}
```
実行結果は予想通り、浅い階層から先にヒットしました。



```console:console
#123456
```
このようにkeyが重複して存在する場合に、何番目の要素にヒットさせるかを、引数で指定できるようにしても面白いかもしれません。

###おわりに
最近、API連携などの開発を行なっていて、その際に得られたJSON形式のデータから特定の値を取得する方法をいろいろ模索していました。大抵は与えられるJSONの階層やKeyが事前にわかっている場合が多いとは思いますが、階層が複雑な場合や可変の場合のベストな方法はないかと思い、勉強のつもりで自分なりに考えてみたので投稿しました。

ご指摘・ご指南等あれば、是非ともよろしくお願いします。

###参考
・[Pythonで再帰関数を作る方法【初心者向け】](https://techacademy.jp/magazine/19308)
・[Pythonで理解する再帰関数](https://qiita.com/dhirabayashi/items/2f079e62fa2e286f1766)
・[Pythonのリストの深さを再帰的に計算する：空のリストの扱いに注意しよう](https://www.mathpython.com/ja/python-list-depth/)
Google Cloud Certified Professional Machine Learning Engineer 合格体験記

# はじめに
Qiita Advent Calendar 2021の記事として、執筆しました。
皆様の参考にしていただけると幸いです。
なお、この記事は2021年12月時点の情報をもとに執筆されています。もし、皆様が受験する場合は必ず公式のホームページ等で最新の情報を確認しするようにしてください。

# 受験した資格

* [Google Cloud Certified Professional Machine Learning Engineer](https://cloud.google.com/certification/machine-learning-engineer)
* 主催: [Google Cloud](https://cloud.google.com/)
* 費用: 200ドル（USD）

# 内容

[試験ガイド](https://cloud.google.com/certification/guides/machine-learning-engineer/)から、抜粋するとだいたい以下のような内容になっています。

> セクション 1: ML 問題の枠組みの構築 
> セクション 2: ML ソリューションの設計
> セクション 3: データ準備 / 処理システムの設計
> セクション 4: ML モデルの開発
> セクション 5: ML パイプラインの自動化とオーケストレーション
> セクション 6: ML ソリューションのモニタリング、最適化、メンテナンス

私が受験した体験から言うとGoogle CloudにおけるML（Machine Learning）関連サービスだけではなく、一般的なMachine Learningの知識やTensorFlowについて問われる試験となっています。詳細は[試験ガイド](https://cloud.google.com/certification/guides/machine-learning-engineer/)を参照してください。

# 受験方法

* 試験時間: 2時間
* オンライン監視によるリモート受験、またはテストセンターでの受験（私はテストセンターで受験しました。）
* 言語：英語（今のところ日本語には対応していないようです）

CBTで多肢選択式の問題を解いていくのですが、1問あたり約2分程度になります。また、現在のところ英語のみしか対応していないので、その点は注意する必要があります。

# 受験のきっかけ・目的

[Google Cloud Certified Professional Cloud Architect](https://cloud.google.com/certification/cloud-architect)や[Google Cloud Certified Professional Data Engineer](https://cloud.google.com/certification/data-engineer)には既に合格しており、Google CloudにおいてMachine Learning関連の業務を行なっているため、Professional Machine Learning Engineerを受験しようと考えました。

# 学習方法

まず、試験範囲を学習するため、以下のコースのVideo Courseを購入して受講しました。またPractice Testsも購入しました。（合計で約50USD。ディスカウントがありました。）

* [Google Cloud Certified Professional Machine Learning Engineer (Whizlabs)](https://www.whizlabs.com/professional-machine-learning-engineer/)

このWhizlabs教材は英語の教材です。他にもCourseraで以下のコースがあるのですが、9つのコースがあり、全てを完了するのに長い時間がかかると思いましたので、Whizlabsのコースを利用することとしました。

* [Preparing for Google Cloud Certification: Machine Learning Engineer (Coursera)](https://www.coursera.org/professional-certificates/preparing-for-google-cloud-machine-learning-engineer-professional-certificate)

私はJDLA（日本ディープラーニング協会）の[E資格](https://www.jdla.org/certificate/engineer/)や[TensorFlowデベロッパー認定資格](https://www.tensorflow.org/certificate)、[Google Cloud Certified Professional Data Engineer](https://cloud.google.com/certification/data-engineer)に合格しているのと、機械学習の知識を持っており、また業務でもGoogle Cloudを利用していたため、時間数の少ないコンパクトにまとまったWhizlabsのVideo Courseでも問題ありませんでした。
模擬試験問題（Practice Tests）については上述したWhizlabsのPractice Testsと以下の<font color="Blue">**Udemyの問題集**</font>を購入して解きました。

* [Google Professional Machine Learning Engineer Certification (Udemy)](https://www.udemy.com/course/google-professional-machine-learning-engineer-certification-t/)

この問題集も英語です。定価は6,600円でしたが、私はセールの時に1,500円で購入しました。ブラックフライデーのセールのときは、1,200円でしたのでセールのタイミングを狙えば安く購入できると思います。
WhizlabsとUdemyの問題集をそれぞれ2回解いたら準備は充分だと思います。

# 結果

**合格**

# 所感
試験時間は2時間ですが、1時間15分程度経過したところで全ての問題を一通り解き終えました。試験問題と選択肢は全て英語ですが難しい文章はなく、機械学習（Machine Learning）における専門用語を覚えておけば特に問題ないと思います。あと、公式の試験ガイドにも記載されているとおり、TensorFlowの知識も要求されますので、TensorFlowについても対策をしておけば万全だと思います。
個人的には、英語が特に苦手でなく、Google CloudでMachine Learning関連のサービスを業務で利用している人にはお勧めできる資格だと思います。
JavaScriptで簡易な定数のグルーピング（ちょっとしたリファクタリングの話）

## はじめに

こんにちは、運動通信社でバックエンドメインに携わっている Takeya です。
フロントエンドもちょくちょく実装してます。
今回はES6の書式でよく忘れるのでメモしておきたいと思います。

## 背景

当時の実装方針や歴史的な経緯もあって、ライブ配信ページの定数宣言クラスがこんな感じになってました。

```js
class Config {
  static get BEFORE() {
    return 0;
  }

  static get PLAYING() {
    return 1;
  }

  static get END() {
    return 2;
  }

  // ... 略 (ライブ配信状態と関係ない各種定数が並列に書かれてる)
}
```

この3つはライブ配信状態を表している定数なので、グルーピングして `LIVE_STATUS.BEFORE` って参照したいですね。

## 結論

今回に関しては、なんのことはなく、定数っぽいキー名にしたオブジェクトを返せばいいかなと。

```js
  static get LIVE_STATUS() {
    return {
      BEFORE: 0,
      PLAYING: 1,
      END: 2,
    };
  }
```

これで `Config.LIVE_STATUS.BEFORE` で参照できます。

(※Javaとかなら enum で解決な気がしますが、JavaScriptには enum がないです。
`Symbol` を使えば enum っぽくできるみたいですが、今回はそこまで考えが至らず:sob:)

https://qiita.com/naruto/items/312adeb6145eb6221be7#%E5%88%97%E6%8C%99%E5%AE%9A%E6%95%B0

### 理想はどうすべきなのか?

おそらく理想は、クラス設計を見直して、あるべきクラスに定数を移管する、のがいいのかなと思います。(Javaっぽく考えると `LIVE_STATUS` 自体を ValueObject としてクラス化すべきな気がします)

しかしながら、

- 結構規模があるので設計見直しは工数的に現実的でない。
- 一部のライブ配信ページは Vue.js に移行し始めているので、Vueとの相性を考えた設計を検討した方が良さそう。
- ちょっと可読性が気になったという話なので、手軽な修正で可読性が上がればOK。

と思って今回の実装を落とし所にしました。

今回の落とし所だと、 jsdoc でObject型の中身の型を表現できないみたいで、Lint系ツールなど型チェックには弊害があるかもしれません。
リファクタリングは工数(納期)とできることのバランスをとっていくのが難しいところです。

今回は非常にちょっとした話でしたが、少しずつリファクタリングを進めています、っていう一例でした。

## おまけ

enum に関して、
TypeScriptなら enum をサポートしてたので軽く調べると、 enum じゃなくて union 型を使おう、ってなってるようです。
色々クセがありますね。。。

https://weseek.co.jp/tech/1609/
[研究：その1]mediapipeを使用したジェスチャー認識で色々遠隔操作してみる

現在、私は大学で骨格認識技術を使用してIOTデバイスだったりアプリケーションをジェスチャーで遠隔操作すると言った研究をしています。この記事は、進捗報告件、やってみた記事として上げていきたいと思います。

これまでは、OpenPoseを使用して、色々試してきましたがOpenposeの環境構築がとても大変で今回は、簡単に実装ができるMediapipeを使用しました。

https://mediapipe.dev

## 今回作る全体構成図
ハンドジェスチャーのみで様々なデバイスを遠隔操作できるようにする
![arch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/631744d7-8c06-b2aa-5b6a-838272ff75c7.png)

## 利用技術とシステムの全体図
![スクリーンショット 2021-12-04 23.35.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/063958c0-5781-b98b-7039-68c56ad128cc.png)

### 実装する機能
|  モード  |  機能  |
| ---- | ---- |
|  メインモード  |  音楽モードかライトモードに移れる  |
|音楽モード|音楽を再生、停止、ボリューム調整ができる|
|ライトモード|ライトを点灯、消灯、光量調整、色調整ができる|

音声はPygameを使用する

https://www.pygame.org/news

ライトはyeelightを使用する。

https://yeelight.readthedocs.io/en/latest/

##### 注)メインモード以外は機能提供中にモードを移ることができない。
※音楽モードからライトモードに移動したい時は、必ず、メインモードに戻る必要がある。
![memo_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/71d2daf3-9425-b2ac-4a52-5fd587471255.png)

## 実装したもの
2021年11月29日〜2021年12月05日で実装した内容。
### 判定できるようにしたジェスチャー

![gesture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/23ed17d4-357b-6a13-295c-7d24763c5a78.png)

### モード切り替えの実装

![modeList.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/1a1e2c99-940c-2217-342a-5721df350b2b.png)

#### 色んな所で呼ばれているので、リファクタリング
雑に書かれていたのでclassで書き直した。
![refactering.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/388a9af6-5d6a-73b8-ca4b-91d56e4cb78a.png)

#### スレッドを作成してその中でサービスを制御する
##### [問題点]whileの中で認識した後、機能を提供すると、何回も呼び出されてしまう。
![スクリーンショット 2021-12-05 14.05.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/b5777443-b1b5-b0db-5153-319362e55aca.png)

![threadproblem.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/3620d208-018e-cc03-b18a-f9db8a36832b.png)




## 浮上した問題点と出来なかったところ。
- ハンドジェスチャーは人によって認識しなくなる時がある。
- 次の音楽へ行く


## 今後の進めていくもの
1. Lightモードを進める
    1. [yeelight](https://jp.yeelight.com/#/index)の実装
  
      > 仕様　https://yeelight.readthedocs.io/en/latest/

2. ハンドジェスチャー認識の閾値の調査
    1. 調査用UI構築?(時間がなかったらデータ集めだけ)

![Web 1366 – 83.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/e17c89bb-cefc-baa0-261d-9d61f8b2fb44.png)

https://streamlit.io



## 今後のスケジュール
yeelightの繋ぎこみ中心に作業を行う
![スクリーンショット 2021-12-04 23.17.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/d17cbec6-22dd-d479-36a3-a04e1749ffb1.png)

---
### [参考]これまで作ってきたもの

###### ジェスチャー認識技術と簡易ドローンを利用した審判補助用システムとその検証用シミュレータの試作

https://www.ieice.org/~iss/jpn/Publications/issposter_2021/data/pdf/ISS-A-044.pdf

https://www.youtube.com/watch?v=lU0TZhb3IEM

https://www.youtube.com/watch?v=z29qPcBg7uI

https://github.com/CMU-Perceptual-Computing-Lab/openpose
(EC2) pullしてもlocalのcredencials.yml.encが反映されない

##問題
AWSにデプロイする中でEC2のcredentialsにlocalのDB内容を反映させようとしたが、pullしても反映されない
##原因
ローカルでcredentialsを編集してpushした後に、EC2内で

```
git pull origin main
```

を実行するとconflictが起きていたので、解決するためにEC2からgithubにpushしてpullしたのがよくなかった。(EC2からpushせずにcommitは削除するべきだった)

##解決方法
githubですでにpushしてしまったEC2からのcommitを

```
git reset --hard HEAD^
```
で遡り、

```
git push origin +main
```

でEC2のcommitを消して、消したcommit上にあったlocalからのcommitを復活させるためにlocalのアプリケーションディレクトリで再度push。そして

```
git pull origin main
```

を実行するとcredentialsにはローカルと同じ内容が反映されている。
Markdown記法ってなんやねんって話

# Markdown記法とは…
* Markdownという、**記号などでシンプルに文書構造を明示でき、装飾されたHTML文書に変換できる軽量マークアップ言語**を使う上での書き方のルールのこと。
* 記号は半角で書く。
* 使うのに特別なアプリやソフトが必要ない。
* HTMLなどのマークアップ言語を簡単に使えるようにしたもの。
* 「マークダウンテキストエディタ」なるものを使えば、リアルタイムでプレビューを見れるため、作業効率が上がるらしい。

# これだけは覚えておけば使える
##「＃」ハッシュ記号　（シャープは縦棒が左に傾いてるらしい）
 * これをつけると**見出し**を書くことができる。
 * 記号の数で字の大きさを変えることができる。
 * 前の行から一行開けなければいけない。  

##「*」アスタリスク
* これをつけると**箇条書き**をすることができる。
* 記号の後に**半角スペース**が必要。
* 二つ目の点からは改行で書くことができる。
* 二回改行しないと、他の表示がうまく動かないのかもしれない。

##「１．」数字+ピリオド
* これをつけると**番号付けリスト**にすることができる
* 箇条書きの下には、かけなそう？。
* 開業すると、数字は一緒だけどプレビューは数字変わってる。
* ていうか数字は関係なく１から始まる。

##「***」アスタリスク三つ以上
* **水平線（区切り）**を書くことができる
* **ハイフン**や**アンダーバー**でも同じことができる。

##「**で囲む」　アスタリスク二つで文字を囲む
* **文字を太字で強調表示**できる。

## 「[文字]（URL）」[]で文字を囲み、（）にURLを記入する
* **文字を押すとURLに飛ぶ**ことができる。
* 表示例　[Qiita](https://qiita.com/)

##「＞」大なり記号
* これを使うと**引用表示**することができる。


>これが表示例。横になんか出てるね。　　

#「```」バッククォート三つで囲む
* **コードブロックをpre表示できる**（よくみる背景が黒い奴）
* 半角スペース四つとかでもできるらしいけど、うまくいかんかった。

```
Console.Writeline("こんな感じ")
```

##「`」バッククォートで文字列を囲む
* **コードの一部を表示することができる**
* 例`Console.Writeline("こんな感じ")`
ゆめみさんの模試問題をTDD+DDDで解いてみた

こんにちは、HCB Advent Calendar 2021の5日目を担当する、take-2405です。
[HCB Advent Calendar 2021](https://qiita.com/advent-calendar/2021/hcb-2021)

ハッカソンの記事を書く予定でしたが、急遽変更してしまいました。ごめんなさい🥺

今回は、TDD、DDDを書籍で学んだのちに、実際にコードを書きながら理解を深めた過程を書きたいと思います。

# この記事について  
この記事は、「TDDとDDDについて学んだから実践してみたい」ということでゆめみさんが公開している模試問題に取り組んでいます。
TDDの開発サイクルとオニオンアーキテクチャを意識して問題に解答しました。


# 取り組んだ問題
今回取り組んだ問題は、ゆめみさんが公開している模試問題です。
内容は、とあるゲームのスコアログをソートし、上位10位のスコアに概要するプレイヤー一覧を表示するという問題です。

詳細は下記ページをご確認ください。
https://www.yumemi.co.jp/serverside_recruit

# 本題

TDDのマントラに従うならば、最初にすべきことは必要なテストを洗い出し、失敗する自動テストを用意することです。一方で、DDDはドメインへの理解を深めモデルを作成する(改善し続ける)ことが最初に必要です。

**TDDのマントラ**
1. レッド
2. グリーン 
3. リファクタリング

これら(テストの用意、モデル作成)の優先順位はケースバイケースだと思いますが、今回はテスト項目を洗い出し、失敗する自動テストを用意することで必要なモデルへの理解を深め、モデル作成しました。


**問題を呼んで洗い出したテスト項目**

```
- 引数をきちんと受け取れている
- ログファイル(csv)をきちんと開けている
- ログファイル(csv)のヘッダー、列数を確認する(対象のログかどうか)
- ログファイル(csv)の中身をパースする
- ログファイル(csv)のスコアなどの型を適したものにする
- プレイヤーごとの合計得点、プレイ回数を計算する
- プレイヤーごとの平均得点を計算する
- 平均点ごとにプレイヤーをソートする
- 平均点を高い順に1-10位まで出力する(同じ得点の場合は同じ順位として出力し、10位まで出す)
```

**最初に作成したモデル**

```golang
type playData struct{
	Count int `csv:"player_id"`
	Score int `csv:"score"`
}

type PlayDatas struct{
	Datas map[string] playData
}

type RankingDatas struct{
	Datas map[int] string
}
```

もちろん上記のテスト項目から増えたもの、減ったものがありました。(初めてということもあり、項目の洗い出しは悩みました。)
最初に作成したモデルも、後々無駄な処理が必要になると感じる部分が度々あり、変更しました。

テスト項目を洗い出し、モデルを作成した後はのサイクルは至ってシンプルでした。

```
    1. TDDのマントラに従い、テスト項目の中から1つを選択し、テストを作成、機能を実装、テストを通す。
    2. 必要があればモデルを修正する。
```
の繰り返しです。

以下が最終的なアウトプットになります。
この記事ではアーキテクチャに関してほとんど触れられていないので、リポジトリを見ていただけると幸いです。

https://github.com/take-2405/yumemi_test_adapt_ddd_tdd


# 感想
TDD、DDDともに学ぶ前の敷居は高く感じられましたが、実践するうちにそれぞれのメリットが感じられました。
テストの粒度などを意識しすると、メソッドの分け方が洗練られた気がします。また、オニオンアーキテクチャを採用したことで普段よりも依存性に意識してコードを書くことができたと思います。

# 参考記事
- https://zenn.dev/foxtail88/articles/a9243dd25acd98
- https://zenn.dev/foolishell/articles/589536ec741ddd

# おわりに
明日のAddvent calenderは @QT21-004-6_HCB が記事を書くので、是非そちらも見てください。
【Nuxt.js】ボタンを押したらデータ値をとる＆色が変わる方法

#はじめに
こんにちは！
今回は【Nuxt.js】ボタンを押したら値をとる＆色が変わる方法についてアウトプットしていきます！

#前提
・Nuxtの新規プロジェクト作成が既に済んでいる
・vue.jsの基礎学習が済んでいる
・tailwindcssが扱える

#対象
・真偽値を使用しての開発を学びたい方
・診断アプリケーションを作りたい方


#実装

```vuejs:template
<button class="text-2xl my-6 mx-10 py-6 px-6 border-2 border-red-600 rounded-full h-28 w-28 flex items-center justify-center"
   :class="answers.q1 ? 'bg-red-200' : ''"
   @click="answer('q1',true)">
   YES
  </button>
<button class="text-2xl my-6 mx-10 py-6 px-6 border-2 border-blue-600 rounded-full h-28 w-28 flex items-center justify-center"
   :class="answers.q1 === false ? 'bg-blue-200' : ''"
   @click="answer('q1',false)">
   NO
</button>

```
```javascript:script
  data() {
    return {
      answers: {
        q1: null
      },
    };
  },

  methods: {
    answer(questionNumber, bool) {
      this.answers[questionNumber] = bool;
    },
  }

```


#解説
上記のコード、下記の写真のようにYESとNOのボタンがあります。

![スクリーンショット 2021-12-05 16.25.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114750/e8d8265c-793a-d60d-d453-c0fed171b30d.png)

・YESを押したら`true`をデータ値としてとる。背景を赤色にする。
・NOを押したら`false`をデータ値としてとる。背景を青色にする。

ということがしたいです。

初期値は`null`。からの状態。

##【YESのボタン】
`@click="answer('q1',true)"`
YESボタンをクリックしたとき、script部分`answer`に**q1はture**というデータ値が入ります。
それを`this.answers[questionNumber] = bool;`と記述し、**q1＝true**と処理が働き、決定付けられます。

`:class="answers.q1 ? 'bg-red-200' : ''"`
この記述の`'bg-red-200' : ''`この部分は`'左辺（tureの時）' : 右辺（falseの時）`という意味になります。よって全体を訳すと**YESボタンを押すとデータ値にtrueが入る。answers.q1のデータ値がtrueの時YESボタンの背景カラーは赤色に変わる**という意味になり、処理が実行されている。

##【NOのボタン】

まず最初に、初期値は`null`とお話ししました。`bool`に`null`と定義してしまうと、性質的な問題で**「nullはfalsyな値なので、if文の条件式ではfalseとなる」**と処理してしまう働きがあります。

なので上記同様に`'': 'bg-red-200'`と記述してしまうと、

![スクリーンショット 2021-12-05 17.14.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114750/ad8e95ff-7ca4-3854-32a7-deb32a8e5dd0.png)

初期状態から色が入ってしまうことになります。（nullだが、falseの影響が出てしまう）
なので`'bg-blue-200' : ''`というように記述しなければなりません。


NOボタンの場合は`:class="answers.q1 === false`（answer.q1はfalseと定義）と記述してしまいます。
これで初期値は`null`ではなく`false`なので、NOボタンをクリックしたら反対の`true`になることになります。
背景色も`'bg-blue-200' : ''`と記述しているので、初めから青く染まっているのではなく、しっかりクリックしてから青く染まるようになりました。

しかしこのままではYESもtrue、NOもtrueとデータをとってしまうので、`@click="answer('q1',false)"`と書き加えることで、**NOボタンを押したら、answer.q1のデータにfalseが入る**という処理法に塗り替えました！

NOボタンの処理をまとめると**ボタンを押したらtrueになるのだが、データとして入るのはfalseである**ということになります！


#最後に
今回はボタンを押したらデータ値をとる＆色が変わる方法についてアウトプットしました。
今回の記事を読んで質問、間違い等あればコメント等頂けると幸いです。

今後ともQiitaにてアウトプットしていきます！

最後までご愛読ありがとうございました！
Raspberry PiでXMRigを利用してマイニング

# 環境
- 製品 : `Raspberry Pi 3 Model B+`
 - OS : `2021-10-30-raspios-bullseye-arm64-lite.zip`を利用してセットアップ済み
  - 32bit版ではうまくいかないため、64bit版の`Raspberry Pi OS`を導入する必要があることに注意。

# XMRigをビルド
[参考](https://xmrig.com/docs/miner/build/ubuntu)

## 必要なパッケージをインストール
```sh
sudo apt-get update
sudo apt-get install git build-essential cmake libuv1-dev libssl-dev libhwloc-dev -y
```

## ソースコードを取得
```sh
cd ~
git clone https://github.com/xmrig/xmrig.git
```

## ソースコードを編集
デフォルトでは寄付の割合が1%と設定されているため、0%に変更する。

```sh
sed -i -e "s/DonateLevel = 1;/DonateLevel = 0;/g" ~/xmrig/src/donate.h
```

## ビルド
```sh
mkdir xmrig/build && cd xmrig/build
cmake ..
make -j$(nproc)
```

# configurationsファイルを用意する
[こちら](https://xmrig.com/docs/miner/config)のドキュメントや[デフォルト設定ファイル](https://github.com/xmrig/xmrig/blob/master/src/config.json)、[ウィザード](https://xmrig.com/wizard)を参考に`config.json`ファイルを用意し、任意のフォルダに配置する。
(今回は`~/config.json`に配置する。)

```conf
{
    "autosave": true,
    "cpu": true,
    "opencl": false,
    "cuda": false,
    "pools": [
        {
            "coin": null,
            "algo": "rx/0",
            "url": "randomxmonero.usa-west.nicehash.com:3380",
            "user": "<マイニングウォレットアドレス>.raspberrypi",
            "pass": "x",
            "tls": false,
            "keepalive": true,
            "nicehash": true
        }
    ]
}
```

# XMRigを実行
```sh
~/xmrig/build/xmrig -c ~/config.json
```

以下のような初期表示が出力された後にマイニングが開始される。

```
 * ABOUT        XMRig/6.16.2 gcc/10.2.1
 * LIBS         libuv/1.40.0 OpenSSL/1.1.1k hwloc/2.4.1
 * HUGE PAGES   supported
 * 1GB PAGES    unavailable
 * CPU          ARM Cortex-A53 (1) 64-bit -AES
                L2:0.0 MB L3:0.0 MB 4C/4T NUMA:1
 * MEMORY       0.3/0.9 GB (29%)
 * DONATE       0%
 * POOL #1      randomxmonero.usa-west.nicehash.com:3380 algo rx/0
 * COMMANDS     hashrate, pause, resume, results, connection
 * OPENCL       disabled
 * CUDA         disabled
```

`randomxmonero`を`rx/0`アルゴリズムでマイニングした際に`12 H/s`ほど出る模様。

## バックグラウンドで実行
バックグラウンドで実行すれば、実行後にsshクライアントから切断しても処理が継続される。

```sh
sudo apt-get install screen
screen -d -m ~/xmrig/build/xmrig -c ~/config.json
```
BitVisor論文の被参照数

この記事は[BitVisor Advent Calendar 2021](https://qiita.com/advent-calendar/2021/bitvisor)の5日目の記事です．

BitVisorに関しては多数の論文が出版されています．最も有名な論文は，あの論文ですよね，そうです．あれです．

> Shinagawa et al., 
> "BitVisor: A Thin Hypervisor for Enforcing I/O Device Security"
> In Proceedings of VEE '09, 2009.
> https://doi.org/10.1145/1508293.1508311

著者がすさまじく多くて，参照が面倒＆紙面取るやつ（個人の感想です）．

でもBitVisor関連論文の中ではこの論文がずばぬけて被参照数も多いです．
被参照数はGoogle Scholarですぐ見られます．今日現在では287です．

<img width=1080 border=3 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105071/79da4ffa-e7a1-3a08-dace-8e6a410b8fe5.jpeg">

<img width=1080 border=3 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105071/117b7a19-dbc6-da80-9574-2fc99fd9661b.jpeg">

ふと思い立って，最近のこの論文の被参照数の時系列的な変化を調べてみました．過去のGoogle Scholarのデータを全部ファイルとして保存してあったので．

結果はこんな感じ．

<img width=1080 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105071/5c19b795-0443-3f9f-4f25-913dc48de7a2.jpeg">

年間30くらいずつ増えていきます．2022年のうちに被参照数300を超えるかもしれません．
出版から10年以上経った現在でも多くの人に読まれていて，参照が着実に増えていくのは，正直，うれしいですね．
【Tableau】VIZの垢抜けスキル④〜散布図のマークを変えてみる〜

この記事は[Advent Calendar 2021 Tableau](https://qiita.com/advent-calendar/2021/tableau2021)の4日目の記事となります。
※私の解説＆キャプチャはTableauDesktopのバージョン2020.4、PCはMacを使ってます。
バージョンが異なったりPCがWindowsの場合、操作が一部異なる場合もあるかもしれません。

本日は散布図の形状を変える方法をご紹介します。
私は散布図は今まで丸を利用していたのですが、以下のキャプチャのように形状を変えて活用したところViewerから好評でした。
![スクリーンショット 2021-12-05 16.29.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1537142/c6f12a3a-19bf-dc2a-4d97-a56de40489b8.png)

↓普段はこのように丸で済ませる事が多いです。
![スクリーンショット 2021-12-05 16.24.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1537142/29fb58b7-b0ca-4751-ae64-6c5182895eb8.png)

尚、本日キャプチャに使っているデータはTableau に付属している「サンプルスーパーストア」ですが、無理くりディメンション名等いじって再現してます。。。その点ご了承ください。

##STEP①
マークのプルダウンで「形状」を選択。
そして形状で分類したいディメンションをドラック＆ドロップします。（ここでは天気の種類ごとにマークを設定したいので、天気を持って来てます）
![スクリーンショット 2021-12-05 16.45.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1537142/098b36e3-cfea-7103-22e3-1db77f6e9331.png)

デフォルトだとこのようになります。（○・□・＋などなど）

##STEP②
次に形状を変えていきます。
マークの形状をクリックし、詳細を設定することができます。
![スクリーンショット 2021-12-05 16.56.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1537142/7871a6c4-a0ee-231b-7b0d-4215c2808eb4.png)

![スクリーンショット 2021-12-05 16.57.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1537142/86f3a510-94d4-e436-8c8e-02dd55bd661b.png)

![スクリーンショット 2021-12-05 16.58.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1537142/11c41278-a80f-e75f-4288-48ea021b8aec.png)

これで形状を変える作業は終わりです。
![スクリーンショット 2021-12-05 16.58.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1537142/f7c8adb4-b44c-8506-bd61-9894b954294d.png)

##STEP③
更に見やすくするために色を変えていきます。
![スクリーンショット 2021-12-05 17.00.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1537142/1b4013cb-2563-a6e6-1788-7d3714ec0a6a.png)

これで完成です！

今回は参考に、男女のキャプチャも載せます。
![スクリーンショット 2021-12-05 17.03.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1537142/2294106a-c1f0-6bc2-603a-f4a4ae9b0f31.png)

分類数が少ないもの向きなので、
今回の天気（晴れ・曇り・雨）や性別（男性・女性）などのディメンションには活用しやすいなと感じました。
形状パレットの種類を見ても、パターンはそんなに多くはないですね。

今回ご紹介した散布図以外のチャートでも、勿論使えます。
【Heroku】 ActionView::Template::Error (Webpacker can't find application.js in /ideaFrameworks/public/packs/manifest.json. Possible causes:

 Rendered layout layouts/application.html.erb (Duration: 1.8ms | Allocations: 983)
2021-12-05T07:57:51.553760+00:00 app[web.1]: I, [2021-12-05T07:57:51.553723 #5]  INFO -- : [7101643d-e3f6-44fc-8f81-5b4e42542e97] Completed 500 Internal Server Error in 45ms (ActiveRecord: 5.6ms | Allocations: 2446)
2021-12-05T07:57:51.554362+00:00 app[web.1]: F, [2021-12-05T07:57:51.554328 #5] FATAL -- : [7101643d-e3f6-44fc-8f81-5b4e42542e97]
2021-12-05T07:57:51.554363+00:00 app[web.1]: [7101643d-e3f6-44fc-8f81-5b4e42542e97] ActionView::Template::Error (Webpacker can't find application.js in /ideaFrameworks/public/packs/manifest.json. Possible causes:
2021-12-05T07:57:51.554364+00:00 app[web.1]: 1. You want to set webpacker.yml value of compile to true for your environment
2021-12-05T07:57:51.554364+00:00 app[web.1]: unless you are using the `webpack -w` or the webpack-dev-server.
2021-12-05T07:57:51.554365+00:00 app[web.1]: 2. webpack has not yet re-run to reflect updates.
2021-12-05T07:57:51.554366+00:00 app[web.1]: 3. You have misconfigured Webpacker's config/webpacker.yml file.
2021-12-05T07:57:51.554366+00:00 app[web.1]: 4. Your webpack configuration is not creating a manifest.
2021-12-05T07:57:51.554367+00:00 app[web.1]: Your manifest contains:
2021-12-05T07:57:51.554368+00:00 app[web.1]: {
2021-12-05T07:57:51.554368+00:00 app[web.1]: }
2021-12-05T07:57:51.554368+00:00 app[web.1]: ):
2021-12-05T07:57:51.554369+00:00 app[web.1]: [7101643d-e3f6-44fc-8f81-5b4e42542e97]      7:     <%= csp_meta_tag %>
2021-12-05T07:57:51.554370+00:00 app[web.1]: [7101643d-e3f6-44fc-8f81-5b4e42542e97]      8:
2021-12-05T07:57:51.554370+00:00 app[web.1]: [7101643d-e3f6-44fc-8f81-5b4e42542e97]      9:     <%= stylesheet_link_tag 'application', media: 'all' %>
2021-12-05T07:57:51.554371+00:00 app[web.1]: [7101643d-e3f6-44fc-8f81-5b4e42542e97]     10:     <%= javascript_pack_tag 'application' %>
2021-12-05T07:57:51.554371+00:00 app[web.1]: [7101643d-e3f6-44fc-8f81-5b4e42542e97]     11:   </head>
2021-12-05T07:57:51.554371+00:00 app[web.1]: [7101643d-e3f6-44fc-8f81-5b4e42542e97]     12:
2021-12-05T07:57:51.554372+00:00 app[web.1]: [7101643d-e3f6-44fc-8f81-5b4e42542e97]     13:   <body>
2021-12-05T07:57:51.554372+00:00 app[web.1]: [7101643d-e3f6-44fc-8f81-5b4e42542e97]
2021-12-05T07:57:51.554373+00:00 app[web.1]: [7101643d-e3f6-44fc-8f81-5b4e42542e97] app/views/layouts/application.html.erb:10


といったエラーがおきた

ActionView::Template::Error (Webpacker can't find application.js in /ideaFrameworks/public/packs/manifest.json. Possible causes:

とあったので、

```
rails webpack:install
```



```
heroku run bundle exec rails webpacker:compile

```

```
git push heroku master
```


をして、エラーが解決できた。
Waveshare 4.3inch DSI LCDのセットアップ

## 対象製品 ##
この製品。

https://www.waveshare.com/wiki/4.3inch_DSI_LCD

AliExpressで5,000円くらい。他のメーカーからも出ていて5inch、7inchなどもある様子。IPSじゃないのもあるので製品選びは慎重に。大抵、LCDの裏側にRaspberry Piを裏返しにセットするようになってるぽく、SDカードの抜き差しは致命的にやりづらいが、GPIOやUSB接続を一切使うことなく表示とタッチが有効になるのが利点。

## セットアップ ##
### SDカード焼き ###
Raspberry Pi公式ツールで最新の32bit OSを焼く。現時点ではBullseye。

### タッチを有効化 ###

```/boot/config.txt
dtoverlay=rpi-ft5406
```

### アップデート ###
何故か最近のイメージはupgradeは失敗するのでdist-upgradeを行う。

```
$ sudo apt-get update
$ sudo apt-get dist-upgrade
```

以上。
STM32G031で「HELLO」と液晶表示 (VSCのCubeIDE)(AQM0802A) HAL



x 過去ログを見よ->


1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり

x PlatformIOと言うらしいが超ムズ(以下省略)(誰かに手伝ってもらいましょう?)

目的
I2Cのテスト

stm32g031_i2c_1内をいろいろ適当にコピー


https://os.mbed.com/users/caa45040/code/f303_h_p1/



![5C119F72-ED7F-4850-90E8-D5D9A20FE0AD.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/3a144955-2c73-4800-6953-00dc2e1bb38e.jpeg)



![o_con133.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/582aef90-d517-5ee8-6e37-8e42c32d2b74.jpeg)




![o_con131.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/87588311-ce22-5dad-b788-71223f81022b.jpeg)




![o_con132.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/e08265a8-a300-761e-b6aa-3e9e1741df2d.jpeg)





main内



```c++




    //I2Cアドレス
    const int ADDR_LCD   = 0x7C; //  address

    //液晶の初期化の文字列
    uint8_t INIT_com[]= {
        0x0,0x38,
        0x0,0x39,
        0x0,0x4,
        0x0,0x14,
        0x0,0x70,
        0x0,0x56,
        0x0,0x6C,
        0x0,0x38,
        0x0,0xC,
        0x0,0x1,
        0x40,0x41
    };//INIT_com

    //画面のクリア
    uint8_t INIT_cls[]= {0x0,0x1};

    //液晶の初期化
    HAL_Delay(200); //液晶の安定待ち
    for(int ii=0; ii<11; ii++) {
        HAL_I2C_Master_Transmit(&hi2c2, ADDR_LCD, &INIT_com[ii*2], 2, 3000);
        HAL_Delay(3);
    } //for

    //液晶のクリア
    HAL_I2C_Master_Transmit(&hi2c2, ADDR_LCD, INIT_cls, 2, 3000);
    HAL_Delay(3);

    //HELLOを表示
    uint8_t dat[]="@H@E@L@L@O";
    for(int ii=0; ii < 5 ; ii++) {
        HAL_I2C_Master_Transmit(&hi2c2, ADDR_LCD, &dat[ii*2],  2, 3000);
        HAL_Delay(1);
     }//for






```
【図解解説】JOI2021-2022 一次予選 第2回 問題4 希少な数

## 図解解説シリーズ
競技プログラミングを始めたばかりでAtCoderの解説やJOIの解説ではいまいちピンと来ない…という人向けに、図解を用いて解説を行います。

## 問題文
### 情報オリンピック日本委員会に掲載されている問題

https://www.ioi-jp.org/joi/2021/2022-yo1/2022-yo1b-t4.html

### AtCoderに掲載されている問題
入出力など実際に確認して自分の作成したプログラムを採点することができます。

https://atcoder.jp/contests/joi2022yo1b/tasks/joi2022_yo1b_d

## 図解解説
今年度の一次予選のD問題は、以下の５つのスキルを確認する問題になっています。
１．入力・出力を正しく利用できる
２．算術演算子を正しく利用できる
３．条件分岐（if）を正しく利用できる
４．繰り返し処理を正しく利用できる
５．配列（リスト）を正しく利用できる

問題文を整理するために、具体的な数字を用いて、図示して考えてみます。
![スライド1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2211017/35041081-65ef-8f6d-fb5f-0ea05840b134.png)
出現回数が入っているリストAを先頭から一つずつ確認し、数え上げていきます。出現回数をまとめると、2,5,8が1回、4が2回出現します。出現回数が最小の数字の中で最小の整数が答えとなるので、入力例２では2が正解となります。

ここで、どのように数え上げていけばいいか考えます。問題文から、1<=Ai<=2000となっているため、最大2000種類の整数が出現します。また、リストAの要素数は1<=N<=100となっていることから、出現回数は最大100回となります。

![スライド2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2211017/94e5ac3d-308e-b0ec-88f9-859f9482459e.png)
そこで、2通りの方法を考えてみます。リストAの先頭から確認していく作業はどちらも同じです。

1つ目の方法は、出現回数を保存するリストBを作成します。1～2000までの整数を数え上げることができればよいので、要素数を2001にしたリストを用意します（0は使用しませんが、そのほうが操作が楽になります）。リストAの先頭から1つずつ数字を確認し、該当する数字の要素番号の値を1増やします。そうすることで、リストBにそれぞれの数字の出現回数を保存することができます。最後に、リストBの先頭から出現回数が1以上の値を確認し、最小の出現回数が出てきたらその値を変数に保存します。以上で最小の整数を求めることができます。

2つ目の方法は、Python固有のcountメソッドを使用して数字が何個あるか確認を行います。同じ数字を何度も調べてしまい効率が悪いと感じるかもしれませんが、この方法で考えてみます。現在の出現回数の最小値と数字を保存する変数が必要になりますが、解答例のように丁寧に整理してプログラムを記述してください。リストAの数字は小さい順に並んでいませんので、出現回数が同じ場合は必ず数字の大小関係を比較するように注意してください。

## 解答例

```d1.py
N = int(input())
A = list(map(int,input().split()))
#出現回数を保存するリストを作成し、初期値をすべて0にする
B = []
for i in range(2001):
  B.append(0)
#要素番号=数値として、先頭からリストAをチェックし出現したら+1する
for i in range(N):
  B[A[i]] = B[A[i]] + 1
#答えを探すために数字と出現回数を記録するための変数を用意
#最初に大きな値を設定しておいて、これよりも小さい値が出てきたら書き換える
suji = 3000
kaisu = 1000
#先頭から順番に確認を行い出現回数が1以上のものが見つかったら、
#保存している出現回数と大小関係を比較する
#もし、保存している値よりも出現回数が小さかったら数字と出現回数を書き換える
for i in range(2001):
  if B[i]>=1:
    if kaisu>B[i]:
      kaisu=B[i]
      suji=i
#最後に数字を表示
print(suji)
```
[採点サイトに提出したプログラム](https://atcoder.jp/contests/joi2022yo1b/submissions/27682049)


```d2.py
N = int(input())
A = list(map(int,input().split()))
#答えを探すために数字と出現回数を記録するための変数を用意
#最初に大きな値を設定しておいて、これよりも小さい値が出てきたら書き換える
suji = 3000
kaisu = 1000
#先頭から順番に確認を行いcountメソッドを使って出現回数を数え保存している出現回数と大小関係を比較する
#もし、保存している値よりも出現回数が小さかったら数字と出現回数を書き換える
#保存している値と出現回数が同じだったら、保存している数字と大小関係を比較し、数字が小さかったら数字を書き換える
for i in range(N):
  if A.count(A[i])<kaisu:
    kaisu = A.count(A[i])
    suji = A[i]
  elif A.count(A[i])==kaisu:
    if A[i]<suji:
      suji = A[i]
#最後に数字を表示
print(suji)
```
[採点サイトに提出したプログラム](https://atcoder.jp/contests/joi2022yo1b/submissions/27682117)

## イラスト
スライド内で使用しているイラストはすべて「[いらすとや](https://www.irasutoya.com/)」の素材を利用しています。
DFplayer miniの 起動時のブチっとするノイズ対策について

# dfplayer mini + esp32

dfplayer mini を ESP32で使用したいと思っていたところ、
起動時のブチっていう音が気になったので調べた。

###  問題
dfplayer miniにスピーカー(適当にあ利ものを使用3W4Ω）をつけて使用。

esp32のuart（hardware serial)につなげたところ(3.3vのため、信号線に抵抗は入れてない）、再生時には問題ないが、起動時にブチっというノイズが発生。

### 対策1 - スピーカとSPK1の間に抵抗を入れる

4Ω
10Ω
47Ω
75Ω
100Ω
120Ω　→　音鳴らない

をテスト、徐々にブチっとする音は小さくなるものの、全体のボリュームも下がる。
120Ωは音が鳴らなかった。

### 対策2 - 内部抵抗を取って、8002のpin1とbusyショート

http://work-now-dammit.blogspot.com/2016/08/dfplayer-mp3-module-power-onoff-clicks.html?m=1

ここが検索で見つかった。詳しい内容は理解できないものの、とりあえず0Ωの抵抗を取り、ショートさせた。

下の000って書いてある0Ω抵抗をとる。（自分はハンダごてを当てて無理に取った）
無理にとってしまったので、パターンもぶっ飛んだ。
ほんとはここをショートさせるっぽいが、
上の繋がってないハンダのところをつなげてもよいと書いてあった。


![IMG_5610.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580563/eb507105-fdf1-f11c-711d-a818a9f2eba4.jpeg)

![IMG_5611.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580563/fd56afff-2ef7-51e4-c489-5422cfffd6fe.jpeg)


### 結果

これで起動時のブチ音がなくなった。
リンクの記事によると待機電力面でも良い的なこと書いてあるが、検証はしていない。


### 追記

最近amazonで買ったものはすでにこの対策がされていました。
豆腐のような形のキューブ型のなにかのSTLデータ


　湯豆腐の美味しい季節となりました。豆腐は木綿が好きです。

　toio™友の会(非公式)のもくもく会で、キューブの3Dデータがないですかねぇというお話が出たのでFusion360で描いてみました。

<img alt="tofu1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431649/e10dbb56-88ce-95ff-f5ae-ec4f270b7eea.png" width=40%/><img alt="tofu2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431649/84a66b20-e126-7d35-fe44-e6de7c5bbc9e.png" width=40%/>

　寸法とか位置は https://toio.github.io/toio-spec/docs/hardware_shape/ に出ている情報と、実物をノギスと定規で測りながらテキトーに決めています。「ここが本物と違う！」ということもあるかとおもいますが、どうにもなりませんので悪しからず。

Thingiverseの置き場所
https://www.thingiverse.com/thing:5155569
tofuロゴ入り、ロゴなしの２つのSTLファイルを置いてあります。
Gatsby + graphql でクエリのnullを許容する

# 概要

Gatsby + graphql はデータが空の状態だと、default では error を吐いてしまうのでその対応

## 解決できること

`gatsby dummy content`

```
There was an error in your GraphQL query:
Cannot query field "hoge" on type "fuga".
```

このあたりが関連してくるerrorは解決できます。

## version

`"gatsby": "^2.24.0"`

## 原因

default では型推論が働き、null を許容しないため error を吐きます。

error全文(hoge, fuga はご自身のものに置き換えて下さい)

```
There was an error in your GraphQL query:

Cannot query field "hoge" on type "fuga".

If you don't expect "hoge" to exist on the type "fuga" it is most likely a typo.
However, if you expect "hoge" to exist there are a couple of solutions to common problems:

- If you added a new data source and/or changed something inside gatsby-node.js/gatsby-config.js, please try a restart of your development server
- The field might be accessible in another subfield, please try your query in GraphiQL and use the GraphiQL explorer to see which fields you can query
and what shape they have
- You want to optionally use your field "hoge" and right now it is not used anywhere. Therefore Gatsby can't infer the type and add it to the
GraphQL schema. A quick fix is to add at least one entry with that field ("dummy content")

It is recommended to explicitly type your GraphQL schema if you want to use optional fields. This way you don't have to add the mentioned "dummy
content". Visit our docs to learn how you can define the schema for "fuga":
https://www.gatsbyjs.org/docs/schema-customization/#creating-type-definitions
```

## 対応方法

上記errorが見やす過ぎて感謝…(ありがとうGatsbyの中の人)

1. typoしてない?
2. ほんとにそんなクエリ存在してる?
3. データがないのであればdummy data作ればいいよ
4. スキーマ定義したらdummy dataも要らないよ

と書かれてます。

[公式](https://www.gatsbyjs.org/docs/schema-customization/#creating-type-definitions)

公式がわかりにくい人は [コチラ](https://stackoverflow.com/questions/60289062/allow-optional-graphql-data-in-gatsby)

### 詳細の対応方法

①②に関しては再度ご自身でご確認ください。

③はdummy作ってフロントで参照しないkeyを作っておいて、 filterかけてdummy dataは表示しない。
みたいな処理書けそうと思いましたがイケてない(内容次第ではこれでも良さそうだけどなんか嫌)

ということで④が無難すね。

### スキーマの定義の方法

`gatsby-node.js`に下記内容を追加して下さい。
(なければrootに作成して下さい)

```js:gatsby-node.js 
exports.createSchemaCustomization = ({ actions }) => {
  const { createTypes } = actions
  const typeDefs = `
    type Users implements Node {
      name: String
      id: Number
      image: URL
    }
    type URL {
      url: String
    }
  `
  createTypes(typeDefs)
}
```

実際にクエリを発行してるコード(抜粋)↓

```js:User.js
export const query = graphql`
  {
    allUser {
      nodes {
        id,
        name,
        image {
          url
        }
      }
    }
  }
`
```

#### 補足

ネストしてる部分の記述で少し詰まりましたが、

`Cannot query field "name" on type "Users".`

と書かれているのであれば、素直にerrorに従って

```js:gatsby-node.js
    type Users implements Node {
      name: String
    }
```

と書けば問題ないです。

あとは

`name: String!`
これで必須 parm (nullを許容しない)

`name: [String]`
これで string が入った配列

`type Users implements Node`
を
`type Users implements Node @dontInfer`
こうすることで、未記載のものは型推論が働くという実装に変わります。

type の書き方は ts と違うので直感と反している部分もありますが、これは慣れるしかないすね〜

## お気持ち

https://zenn.dev/take77/articles/a266a75bf12c23

→Gatsbyの記事が少ないはわかりみが深いw

あとはそろそろGatsby3も触っていきたいな…(と思ったら4の話がそこまで来てたので見ないふりをした)
Rubyプログラミング問題にチャレンジ！ －改訂版・チェリー本発売記念－ に挑戦しました

この記事は[Rubyプログラミング問題にチャレンジ！ －改訂版・チェリー本発売記念－ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/ruby-challenge) 14日目の記事です。

バックエンドエンジニアをしておりますyukoonoと申します。
書いたコードを外部に公開したことがないので、力試しをしてみたいという動機で参加させていただきました。
よろしくお願いします。

## プルリクエストのリンク、または自分が書いたコード
[Github: 点字メーカーチャレンジ 12/14 #20 JunichiIto/tenji-maker-challenge ](https://github.com/JunichiIto/tenji-maker-challenge/pull/20)

## ロジックの解説

1. 入力をひらがな一文字分ずつ分割する

    例：`"KI RI N"` -> `"KI", "RI", "N"`
    このとき、`"N"` または `"NN"` が入力されていた場合は、「ん」を点字にした
    `"--\n-o\noo"` に直接変換し、次のひらがな一文字分の処理に移る。

    1. ひらがな一文字分のローマ字をさらに英字一文字に分割する

        例：`"KI"` -> `"K", "I"`

    1. 英字に `"Y"`, `"W"` が含まれている場合、母音の位置を下に下げるフラグ (`vowel_tenji_needs_shift_downward_flag`) を立てる
    1. 英字を、母音・子音ごとにクラスで定義した点字対応表を用いて、それぞれ相当する点字に置き換える

        例： `"K", "I"` -> `"--\n--\n-o", "o-\no-\n--"`

    1. 母音の位置を下に下げるフラグがfalseであれば、5 に進む
        1. フラグがtrueである場合、母音の o の位置を一段下げ、上に`"--"`を挿入する操作を行う

             例： `"A"` -> `"o-\n--\n--"` -> `"--\no-\n--"`

        1. 一番下の段に o が移動するまで 4.1 の操作を繰り返す
    1. 母音と子音を組み合わせて一文字の点字にする

        例： `"--\n--\n-o", "o-\no-\n--"` -> `"o-\no-\n-o"`

1. 得られた点字を横並びで表示できるよう、ひと続きの文字列に置き換える

    例： `"o-\no-\n-o"`, `"--\n-o\n--"`, `"--\n-o\noo"\`
-> `"o- -- --\no- -o --\n-- -o oo"`

結果を出力すると、以下のように表示されます。

```
  tenji = @tenji_maker.to_tenji('KI RI N')
    assert_equal <<~TENJI.chomp, tenji
      o- o- --
      o- oo -o
      -o -- oo
    TENJI
```

## コードのアピールポイント
一番のポイントは、音と点字の対応表を作成し、それを利用してテキストの変換を行なったことです。例えば、母音では以下です。

```
VOWELS = {
  A: <<~A.chomp,
    o-
    --
    --
  A

  I: <<~I.chomp,
    o-
    o-
    --
  I

  U: <<~U.chomp,
    oo
    --
    --
  U

  E: <<~E.chomp,
    oo
    o-
    --
  E

  O: <<~O.chomp,
    -o
    o-
    --
  O
}
```

点字にしたときに、どの音がどのような形に対応するのかを視覚的に示したかったため、対応表を文字列で用意し、それを組み合わせたり、順番を入れ替えることでテキストの変換を進めました。コードを見る人に、処理するための材料を示すことが狙いです。

### 工夫したところ
* 母音を移動させる行について、母音を o が下の行に入るまでシフトさせる仕様にしたこと

1.4.1, 1.4.2の手順です。
この方法で、元々の変換対象ではなかった「を」について、変換できるようになりました。

実は、最初は「や・ゆ・わ」の変換はできていたのですが、母音由来の o が二段目にもある違いから「よ」の変換がうまくできず、試行していたら思いがけず「を」が変換できてしまった、という感じです。
自分で工夫した点なのか、と聞かれると微妙ですが、お題の範囲外の変換ができたので記しました。

* 「ん」について、`"N"` と `"NN"` からの点字の変換ができるようにした

手順1に記述していますが、「ん」についてだけは、他の文字の変換処理と切り離して、`"N"` または `"NN"` の入力があれば変換する形式にしました。test.rb には `"N"` から変換するケースのみが書かれていましたが、個人的によく `"NN"` で入力することから、これも「ん」に変換したいというこだわりがありました。他の変換方法として、`/N+ $/`が入力されていたら「ん」に変換したらどうか、とも考えましたが、`"NNN"` も「ん」に変換されそうだったのでやめました。

### 苦労したところ
とにかく大変だったところは、変数の名付けです。

- 一文字分の点字
    - ( ex: `"o-\n--\n--"` )
- 点字が配列に複数入っている状態
    - ( ex: `["o-\n--\n--", "o-\no-\noo"]` )
- 点字の点と線を1文字ずつに分解したものが配列に入っている状態
    - ( ex: `["o", "-", "\n", "-", "-", "\n", "-", "-"]` )
- 点字の点と線を1文字ずつ取り出した状態
    - ( ex: `"o"`, `"-"` )

などが処理の中で登場しました。
コードを書き始めた当初は、「これどうやって名付ければ状態伝わるの？」と、かなり困ることになりました。数日後に見返して理解できそうな表現か確かめる、図を描いて自分で状態遷移を整理するなどして、ようやくこれだ、と思う名付けができた、さあ Qiita に書こう！と書き始めたあとで、また違和感を覚えて書き直しました。ようやく自分の中では整理されて、わかりやすい表現になってきたのではないかと思っています。

おかげで、変数名を変えただけのコミットが積み上がってしまいましたが。苦笑

## 伊藤さんにメッセージ（もしあればw）
面白い企画を立ち上げて頂きありがとうございます。会社の方以外に自分のコードを見ていただく機会などなかなか無いので、怖くもありますが、わくわくもしています。

また、他の参加者の方のコードなどは見ていませんが、Qiitaのカレンダーからタイトルだけは見ています。読むのをとても楽しみにしています。
postgreSQLで1000万件データをいれてみる

# きっかけ

大量のデータを投入してテストをしてみたいと思い、まずは大量のデータを投入してみることにしました。

# 結論からいうと、こんな感じに
select count(*)して1000万件を確認
700MBのcsvファイルを投入して30秒ほどでinsert完了しました。
もっと時間かかるかと思いましたが、早い！
![スクリーンショット 2021-12-05 16.25.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681795/1988781b-7cee-0cc2-b3a7-2581f6a20327.png)

# テストのテーブルを作成する
適当にテーブルを作成
インデックスはまだ作りません。

```sql:SQL
CREATE TABLE public.test (
    id character varying(256) NOT NULL,
    num integer,
    created_at timestamp with time zone
);
```

# CSVは以下のようなものを作ります

↓sql_many.csvの中身

id,num,created_at
c6afae11-6be6-4f5b-b9c6-6e626b299301,9149,2019-06-02 10:34:59+00
...省略

# pythonでcsv作成プログラムを作ってみる
ランダムなデータを入れ込んでいます。
日付はちょっと適当かも。
最初、大量のinsert into命令を作成するプログラムを作っていたのですが、CSVファイルimportしたほうがinsert処理時間が早いためcsv作成プログラムに変更しました
(途中で変更したのでpythonのcsvライブラリを使っていない・・)

↓sql.pyを作成

```python:python
import string
import uuid
import datetime
import random

#開始関数
def main():
    fileName = 'sql.csv'
    maxRowNum = 1000 * 10000
    createCsvFile(fileName, maxRowNum)

#追記モードでファイルに書く
def createCsvFile(fileName: string, maxRowNum: int):
    with open(fileName, 'at') as fb:
        header = createHeader()
        fb.write(header)
        for rowNum in range(maxRowNum):
            sql = getOneSql(rowNum)
            fb.write(sql)
            print(str(rowNum) + ' - ' + sql)
        fb.close()

#ヘッダーを作成
def createHeader():
    return "id,num,created_at\n"

#1件分のCSV作成
def getOneSql(num: int) -> string:

    #GUID作成
    csv = ''
    csv += str(uuid.uuid4())
    csv += ','

    #ランダムな数字
    csv += str(random.randrange(0, 10000 +1, 1))
    csv += ','

    #ランダムな日付を作成
    csv += random_date(datetime.datetime(2018, 1, 1), datetime.datetime(2021, 2, 1)).replace(tzinfo=datetime.timezone.utc).isoformat()

    csv += '\n'

    return csv

#ランダムな日付を作成する関数  他サイトから拝借
def random_date(start, end):
    """Generate a random datetime between `start` and `end`"""
    return start + datetime.timedelta(
        # Get a random amount of seconds between `start` and `end`
        seconds=random.randint(0, int((end - start).total_seconds())),
    )

#開始する
main()
```

#実行
python 3.10.0で実行しました
2-3分かかります。
csvは700MB近くになります。
```python sql.py```

#pgAdmin 4でimport
1.対象のテーブルで右クリック
2.Import/Exportを選択
3.以下の画面が開くので、設定して終わり
![スクリーンショット 2021-12-05 16.29.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681795/e23eeb4b-6868-9543-146f-331742932bc0.png)

#これから
SQLを実行して、どのぐらい時間がかかるか、実行計画などを見ていこうと思います

#参考
Generate a random date between two other dates
https://stackoverflow.com/questions/553303/generate-a-random-date-between-two-other-dates/26883710#26883710
Google ID と Apple ID のアカウント連携

会社のApple製品をMDM管理にしたいなと思って色々調べていたら、Google ID (Google Workspace) と Apple ID を連携させてGoogleをIdPにできそうなことに気がついたので実験してみました。

基本的な考え方は、AzureADを中継させるということです。

Apple Business Manager に Microsoft Azure Active Directory と連携させる機能があるので、あとは Microsoft Azure Active Directory と Google Workspace を連携させれば良いです。

もともとシンプルウェイはGoogle WorkspaceとAzureADはSAML連携していたので、あとはAzureADとABMで連携するだけです。

これからGoogle WorkspaceとAzureADのSAML連携を設定したい場合は[このあたりの記事](https://www.misuzilla.org/Blog/2019/07/26/FederatingGSuiteWithAzureActiveDirectory)が参考になりそうです。

AzureADとABMの連携は[Microsoftに丁寧な記事](https://docs.microsoft.com/ja-jp/azure/active-directory/saas-apps/apple-business-manager-provision-tutorial)がありますので、これに従って設定します。

1点注意としては、設定がすべて完了したら、ドメインの連携を有効化しなければならないということです。AzureADのログではプロビジョニング完了になっているのに、ABMではなかなか取り込まれないなと思ったら、ドメイン連携が有効化されているか確認しましょう。

![abm.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219010/0886b45e-63a3-9d4e-ab84-a913174d9644.jpeg)

ABMでもアカウントが取り込まれたことを確認したら早速Apple製品でログインしてみます。

![appleid.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219010/ac8dcc6a-77ad-b06d-9eb9-caec3174055c.gif)



まだMDMの導入まで完了していないので、すべてがまるっと上手くいくとは限らないのですが、ひとまずAppleIDとGoogleIDを統合するところまでは動作しているようです。
とにかくすぐにApacheが欲しいときのdockerコマンド


```bash
# docker run --rm -p 80:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4
```

```bash
$ curl localhost
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
 <head>
  <title>Index of /</title>
 </head>
 <body>
<h1>Index of /</h1>
<ul></ul>
</body></html>
```

[Httpd \- Official Image \| Docker Hub](https://hub.docker.com/_/httpd)