OmniAICreator/Qiita-1.07M huggingface dataset:
Teamsにﾈｺﾁｬﾝの画像を定期postする

[こちらの記事](https://qiita.com/e99h2121/items/6d5cc72679f43aa37be2)で紹介されている[TheCatApi](https://thecatapi.com/)というCaas(Cats as a Service)が大変アツかったので定期的に呼び出してチームに共有したいなと思いました。

# [TheCatApi](https://thecatapi.com/)とは？
ﾈｺﾁｬﾝの画像のURLをランダムに渡してくれるAPIです。[ドキュメント](https://docs.thecatapi.com/)のクイックスタートを読んでみましょう

>
好きな言語/フレームワークを選んで
1. https://api.thecatapi.com/v1/images/search にGET
2. 受け取ったJSONの最初の配列を取りだして
3. .urlのURLにアクセス
4. Enjoy the ﾈｺﾁｬﾝ 😺

サインアップしてAPIキーを取得すると画像が増えたりお気に入りを登録できたりフィルターで好きなﾈｺﾁｬﾝだけを取ってこれたりするみたいです。

# Power Automateでフローを登録する
Teamsへの定期postは[Power Automate](https://japan.flow.microsoft.com/ja-jp/)で行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245527/4c074cff-af25-73ec-77ab-1245ddaf02a6.png)

## Tips

- Recurrenceの*間隔*は詳細オプションの開始時刻からカウントが始まります。  
実行開始から数えてではないので時報を作るのにも安心。
- JSON解析のスキーマはサンプルから登録すると便利です。今回なら適当なレスポンスの  
`[{"breeds":[],"id":"9pn","url":"省略","width":500,"height":348}]`  
↑をコピペでOK
- アダプティブカードはどっかのネットで拾ったサンプルより[ここ](https://adaptivecards.io/designer/)から自分で作った方が確実です。ただしVersionが1.3だとTeams上で表示されない(2021/03/24現在)？ので1.2に書き換えています。

## テスト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245527/378f6743-bb09-28f2-857b-7dd13ea4924f.png)

このように投稿されれば成功です！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245527/76550551-2d02-5c75-6824-8483df31aace.png)

時々こうなってしまうのですがこれについてはまた後日。

# かくして…
弊部に毎時ﾈｺﾁｬﾝの画像が流れるだけのチャネルが誕生したのでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245527/b8473879-603e-07bb-3135-c8125937a014.png)

少しだけまじめな話をすると、社内コミュニケーションの主戦場であるチャットアプリとしてTeamsはいささか遊び心を加えられる余地が少ないと思うんですよね。標準機能だけを使っているとどうしても空気が堅苦しくなりがちなので、こういったおふざけチャネル(時報の意味も込めていますが)の存在って意外にも重要なんじゃないかという考えが今回の背景にありました。

Enjoy the ﾈｺﾁｬﾝ 😺
[Unity] 実行直後にAudio MixierのVolumeを変更しても変わらない件

#Audio Mixierの音量
ゲームを開始するたびに音量設定が元に戻っても困るので、
PlayerPrefsで保存した値をAudio Mixierに反映させたいと思ったら変更されなくてハマった


#事象

音量調整用スライダーの範囲を0~50にして、
mixierに-40db~10dbにするような最低限の記述がこんなだとして

```なんかAudioの.cs
public class AudioDirecter : MonoBehaviour
{
    [SerializeField] AudioMixer mixer;
    [SerializeField] Slider slider;
    [SerializeField] string mixerGroup = "audio";

    void Start()
    {
        float value = PlayerPrefs.GetFloat(mixerGroup, slider.value);
        slider.value = value;
        SetVolume(value);
    }

    void SetVolume(float value)
    {
        mixer.SetFloat(mixerGroup, -40 + value);
        PlayerPrefs.SetFloat(mixerGroup, value);
    }
}

```

これを実行しても保存した値がmixierに反映されなくて困った
（シーンの読み込み時は反映されるが、実行時には反映されない）
**※PlayerPrefs.Save()は別スクリプトにて実行している**

#解決案 1　コルーチンでワンテンポ遅らせる


```なんかAudioの.cs
public class AudioDirecter : MonoBehaviour
{
    [SerializeField] AudioMixer mixer;
    [SerializeField] Slider slider;
    [SerializeField] string mixerGroup = "audio";

    void Start()
    {
        StartCoroutine(Delay());
    }
    IEnumerator Delay()
    {
        yield return null;
        float value = PlayerPrefs.GetFloat(mixerGroup, slider.value);
        slider.value = value;
        SetVolume(value);

    }
    void SetVolume(float value)
    {
        mixer.SetFloat(mixerGroup, -40 + value);
        PlayerPrefs.SetFloat(mixerGroup, value);
    }
}
```

#解決案 2　実行順序を遅らせる
コルーチンでワンテンポ遅らせてできたのなら、そもそも実行されるタイミングが悪い説
なので
DefaultExecutionOrder(正の値)で実行されるのを遅らせる

参考[【Unity】コンポーネントのイベント実行順についてのTips - テラシュールブログ](http://tsubakit1.hateblo.jp/entry/2017/02/05/003714)

```なんかAudioの.cs
[DefaultExecutionOrder(10)]
public class AudioDirecter : MonoBehaviour
{
    [SerializeField] AudioMixer mixer;
    [SerializeField] Slider slider;
    [SerializeField] string mixerGroup = "audio";

    void Start()
    {
        float value = PlayerPrefs.GetFloat(mixerGroup, slider.value);
        slider.value = value;
        SetVolume(value);
    }

    void SetVolume(float value)
    {
        mixer.SetFloat(mixerGroup, -40 + value);
        PlayerPrefs.SetFloat(mixerGroup, value);
    }
}
```
線型代数について


線形空間には必ず0がありますが、他にも存在が保証される特別な組があり、それが基底です。

基底ベクトルとは、二次元、三次元それぞれの場合で空間上のあらゆるベクトルを v=xa+yb の形で表すことを可能にするベクトルの組み合わせ（一対）のことです。

ベクトルの線型独立（「一次独立」ともいう）とは、一言でいうと「空間における基底ベクトルがすべてゼロベクトルではなく、平行関係にない状態」のことです。
ベンダープレフィックス付けなくてもいいプロパティ

ベンダープレフィックスを付けなくてもいいプロパティ

animation
border-image
border-radius
box-shadow
box-sizing
text-shadow
transform
transition
@keyframes

参考サイト: 

https://qiita.com/amamamaou/items/42197e443134478befaf
輪読会をやってみて

弊社アクシス福岡支部では昼休みの時間を使って週二回輪読会なるものを行っています。
昼休みという貴重な時間を利用するので自由参加という形で運営しています。
輪読会について色々調べたのですが、「これだ！」というような輪読会の方法論はなさそうなので会を重ねて改善していければなと思っています。この辺りはアプリケーションを作る時と一緒ですね（輪読会に限らずですが）。

輪読会で学んだことについては、また別の機会に行うとして、輪読会について今回は書いてみようと思います。

## 「読む」よりも「理解」することを大事にしたい
「輪読会」という名前から読むことに重点が置かれやすいと思うのですが（実際に僕も読むだけの会だとイメージしてました）、せっかく複数人で同じ本を読む機会があるので、理解することに重きを置いてみようと思い、本を読む時間よりも読んだ内容について議論したり、抱いた疑問を解消することに多くの時間を割くようにしています。

なので、1日1時間の輪読会で読み進めることができたページ数は、**たったの1ページしかない**といったことが多くあります。遅々としてしか進まないですが、個人的にはそれで良いのかなと思っています。読んだテーマについて知っている人は教える側に周り「伝える」ということを学べますし、初めて学ぶテーマに関しては誰しもたくさんの疑問を抱くと思います。疑問を解消するためには抱いている疑問を相手に「伝え」、自分のイメージできる土壌に持っていくことが必要だと考えています。

個人的な「伝える」とは、「平易な言葉を使って相手のイメージを助ける」ことだと思っています。専門用語を使うにしても理解が難しくその時々の背景(コンテキスト)に応じて変わってしまうようなものではなく、できる限り言葉と意味が一対のものを選んで話すように心がけています。が、あまりうまくできた試しはないなといつも思います。難しいですね。

実際にアプリケーションを開発する現場でも、特定のテーマについて議論を行いより良いものを模索したり、ソースコードや、設計などに疑問を抱くことは多くあると思います。そういった機会で物怖じせずに疑問を呈することができる人材や特定のテーマについて議論を交わせるような人材が多くいるのとそうでないのとではできるものに大きな違いがあるのかなと個人的には思っています。そういった方を増やす意味でも良い試みなのかなと感じています。

## 勉強はしたいけど、読書は苦手の撲滅
「技術に関する勉強は積極的にしていきたいが、読書は苦手」という方は多くいらっしゃるのではないでしょうか？
ただ、成長していくためには本を読んだり、QiitaやZennなどのサイトに掲載されている技術文書を読んでいくことは常に行っていかないといけないので、活字からは逃げられないと私は思います。書く際も然りですね。

そういった「やる気はあるけど、読書はちょっと・・・」な方にも読むことを習慣化してもらいたいという気持ちが少なからずあったことも、輪読会を始めるきっかけだったと思います。正直、どれだけの効果があるのかは未知数ですし、個人差があると思っていますが、それでもこういった機会を経て読書を好きになる人がたくさんいれば良いなと思ったりします。

この点に関してはまだ成果を感じられる状態ではないため、回を重ねてまた報告したいなと思います。

## やってみて気づいたNGなところ
輪読会の際、音声を録音しています。録音をする主な理由は以下の二つです。
- 議事録などを作ってしまうと発言が偏ってしまう（可能な限り全員参加でやりたい）。
- 1週間に1回程度は輪読会の様子や学んだことを記事にしたい（今私が書いているように）。
 現在、4回程度しか行っていませんが、録音を聞き直して思うのは、説明を行う際に物によっては板書をする機会があるのですが、画像などを撮っとかないと後から聞き返しても状況を把握するのが大変であること。考えればすぐわかりそうなことですが、意外にやってみないとわからないものなのかもしれません。
また、板書での説明時に画像を撮影しても、指示語（「あれ」「それ」「これ」）での説明となると理解が難しくなるので、明快な言葉を使うように気をつける必要がありそうです。動画にすれば全て解決しそうですが、それもまた難しいですよね。

参加者の負担になるので賛否が分かれそうなところですが、個人的には次回実施までに読み進めてくるべきだと思っています。やはり、一回読むだけでは理解が難しい箇所がありますし、その場で質問を練るのは難しいとも思うので、より有意義な会にするのであれば、参加者全員が次回までに一度は読み「不明点」や「テーマ」を選定していくととても活発になりそうだな、と感じています。これは、NGではないですが、理想ですね。

## おわりに
まとめると以下のようにすすめてますね。

- 音読も大事だが、できる限り議論する場にしたい。
- 議論する場であることと同じぐらい質疑応答の場にしたい。
- 読書を好きなって欲しい。

今後もたくさんの課題が出てくると思いますが、全員で一つずつ考えて改善していければと思います。
【初心者でもわかる】プラグイン不使用！オリジナルのSNSシェアボタンの作り方

#どうも7noteです。サイトにSNSのシェアボタンを掲載したいけど、テンプレートやプラグインのものはダサいので使いたくない方向け

Wordpressのプラグインなどを使うことで、SNSのシェアボタンを設置することは簡単にできます。しかし、そのプラグインに用意されているボタンのため**サイトのデザインに合わないから変えたい**と思う方もいるかもしれません。

フリー画像としてSNSのアイコはたくさん公開されているので、その画像を使ってオリジナルのシェアボタンをサイトに設置する方法を解説していきたいと思います。

## 手順① 画像を用意

「SNS アイコン フリー」等で検索すれば、著作権フリーのシェアボタンがたくさん出てきます。
サイトに使いたい画像を探します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/4150ae15-b406-435e-2ccc-c5e4634498ff.png)

「オススメのSNSアイコンがあるサイト」
https://icon-rainbow.com/tag/sns/

※サービスによってはアイコンのガイドラインが決まっているものもありますので使用時には注意してください。（公式アイコンについてまとめているページ↓）
https://www.magical-remix.co.jp/magicalog/archives/3782

## 手順②URLを作成してimgタグとaタグを設置

### Facebook

```index.html
<a href="http://www.facebook.com/share.php?u={URL}" rel="nofollow" target="_blank"><img src="facebook.png" alt="facebookシェア" ></a>
```
`{URL}`の部分をシェアしてほしいURLに変更してください。

### twitter

```index.html
<a href="https://twitter.com/share?url={URL}" rel="nofollow" target="_blank"><img src="twitter.png" alt="twitterシェア" ></a>
```
`{URL}`の部分をシェアしてほしいURLに変更してください。
本文やタイトルも掲載する場合は以下のように設定が可能です。

```html
<a href="https://twitter.com/share?
  url={URL}&
  via={Twitter ID}&
  related={Twitter ID}&
  hashtags={ハッシュタグ（半角スペースつなぎ）}&
  text={テキスト}" 
  rel="nofollow" 
  target="_blank"><img src="twitter.png" alt="twitterシェア" ></a>
```



### LINE

```index.html
<a href="https://social-plugins.line.me/lineit/share?url={URL}" rel="nofollow" target="_blank"><img src="line.png" alt="LINEで送る" ></a>
```
`{URL}`の部分をシェアしてほしいURLに、`{URL}`の部分をタイトルに変更してください。


### はてなブックマーク

```index.html
<a href="http://b.hatena.ne.jp/add?mode=confirm&url={URL}&title={タイトル}" rel="nofollow" target="_blank"><img src="hatebu.png" alt="はてぶシェア" ></a>
```
`{URL}`の部分をシェアしてほしいURLに、`{URL}`の部分をタイトルに変更してください。

### 他

FeedlyやPocketは以下のサイトでご確認ください。
https://webdesign-trends.net/entry/3632

## まとめ

プラグインを使わなくてもコピペで簡単にシェアボタンを作成することができます。
ただシェア数を表示するなどはボタンの設置に比べると少し複雑になるのでphpなどのプログラミング言語を使う必要がでてきます。

ボタンだけならHTMLだけで簡単に作れるのでサイトやブログなどにオリジナルシェアボタンを設置してみてください。

アイコンは画像でなくても、アイコンフォントを使う方法もあります。
おすすめアイコンフォントはこちら↓

https://fontawesome.com/

Font Awesome以外のアイコンフォントもあります↓
https://webdesign-trends.net/entry/11656

参考：
https://webdesign-trends.net/entry/11656
https://webdesign-trends.net/entry/3632

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
herokuにデプロイできないのを解消した例【本番環境にデータベースが無い】

herokuにpipelineをつくり、STAGINGとPRODUCTIONを作ってデプロイしていました。
STAGINGには上手くデプロイできたのですが、そこから本番環境へのプロモートが上手くいきませんでした。

エラー内容は

```
bin/db:migrate
```

という風に出ていました。

どうやら、一度も本番環境にプッシュしていない状態でプロモートを行うと、PostgreSQLデータベースが存在しないというエラーが出るようです。

ですので、

```
heroku addons:create heroku-postgresql -a 本番環境のアプリ名
```
で本番環境に直接データベースを作成。

これで無事、本番環境にデプロイする事ができました。
nginx sub_filter による JSON レスポンスの置換メモ

# 問題

nginx で sub_filter を実施しているはずなのに Ajax で取得するレスポンス内のコンテンツが置換されないので迷った。
アプリケーションのバージョンアップか何かかが原因かと思って、１時間近く悩んでしまったのでメモ。


# 原因

sub_filter_types のデフォルトは `text/html` のみ。 `application/json` を置換するのであれば、sub_filter_types に明記して置換対象とみなしてやる必要がある。

http://nginx.org/en/docs/http/ngx_http_sub_module.html
高校生がwebアプリケーションを作ってみた!

#はじめに
記事を見ていただきありがとうございます。
恐縮ですが実務・業界共に未経験のため設計や図に間違いがある場合、***優しく***教えていただけると幸いです。
執筆時は高校を卒業していますが、ほぼ高校生ということでお願いします。
高校生なりに頑張って作ったので見ていってください。
コストの関係上、**2021/4/15**まで公開します。
記事中にも記載はありますが、各リポジトリのURLをまとめておきます。
・[アプリケーション repo](https://github.com/naruse666/portfolio_app)
・[docker repo](https://github.com/naruse666/laravel_docker)
・[k8s repo](https://github.com/naruse666/k8s_laravel)

#勉強期間・苦労したとこ
###期間
**合計すると約1年。**
内訳は、html,css,jsを遊びで半年。
php,laravelを3ヶ月,aws,dockerなどのインフラ系を3ヶ月。
ポートフォリオは2月上旬~3月中旬の約1ヶ月半です。
(制作中に引っ越しがあったので少々長くなりました)
###苦労した点
高校二年生で飲食店のアルバイトで稼いだお金でMacbookを買いましたが、高校の授業を受けながらなので***勉強時間の確保***に困りました。さらに、家が遠かったので尚更時間がなかったです。
また、周りにエンジニアがいないので情報収集に悩んだり。高校生なのでawsの課金額をいかに抑えるかで苦労しました。

#使用技術・機能
###使用技術
今回ポートフォリオに使用したものを書きますが、同じような類のものは1行にまとめます。
・PHP/Laravel
・MySQL
・html/css/bootstrap
・Node.js(npm)(未学習)
・AWS(EC2, VPC, IAM, EKS, ECR)
・k8s
・Helm(stable/nginx-ingress)
・Docker/docker-compose
・git/github
###機能
・ログイン
・簡単ログイン
・フォロー/相互フォローバッジ
・いいね機能
・検索機能
・つぶやき機能
・グループ

#サイトマップ・ER図
###サイトマップ
![Screen Shot 2021-03-23 at 21.44.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722539/a1cfaecf-97a7-063c-6907-ca094887899a.png)
###ER図
![Screen Shot 2021-03-23 at 22.25.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722539/3deb4d7b-9faf-30a1-2a2d-056af87d5f01.png)

#インフラ
###aws上での構成
![Screen Shot 2021-03-23 at 21.43.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722539/ff53663e-5419-20fd-8bf9-f202d66da847.png)
###k8sクラスタの構成
![Screen Shot 2021-03-24 at 15.58.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722539/13994359-bc5f-cfbf-fbb1-3f72ccb23829.png)

あらかじめ作成したdockerイメージ[docker repo 参照](https://github.com/naruse666/laravel_docker)をECRに登録し、k8sクラスタ上でawsを認証し、その他必要なvolumeを作成・マウントしています。

下の構成図は[k8s repo](https://github.com/naruse666/k8s_laravel)を表したもので、
Makefileにより簡単に構築・管理することができます。

#アプリケーション
アプリ名　　　：　Nanndemo
目的・企画理由：　デモのようなものをネット上でできないか、若年層に少しでも政治に
　　　　　　　　　興味を持ってもらいたい、コロナウイルスによる自粛が必要なため。
リポジトリ　　：　[アプリケーション repo](https://github.com/naruse666/portfolio_app)
URL　　　　　：　終了しました。
その他　　　　：　誹謗中傷などによる法的な問題への発展を考慮し利用規約の作成。
　　　　　　　　　コスト削減のため、***ドメイン名は取得しておりません***。
　　　　　　　　　ご理解お願いいたします。
　　　　　　　　　*スマホ・タブレットでは表示が崩れる可能性があります。

#最後に
実際にアプリケーションを見て頂けるとわかりますが、まだまだ能力不足です。
SSL化やCI/CD,利便性,新しい機能など追加事項があると思いますが、現時点での能力を鑑みた結果ここまでとさせて頂きます。
ですが、高校卒業ということでさらなる成長を求め精進して参ります。
ありがとうございました。
node備忘録

### 概要
nodeについて細かい備忘録をまとめました。

#### V8
Googleが提供しているオープンソースで、javascriptやwebアセンブリを実行するエンジン。

#### Node.js
Chromeのv8エンジンにて動作するjavascriptのフィールド（環境)。

- 特徴
イベント起因でコールバックを非同期的に発火することができる。
如何様にも状況が変化する（スケーラブルな)アプリケーションに対応する目的で設計されている。

#### CLI
コマンドラインインターフェース。
コマンドライン、ターミナルからソフトウェアやアプリケーションに対して情報を伝える環境。
Rustが安全で速い理由

# この記事について
個人的なメモです．
[The Rust Programming Language 日本語版](https://doc.rust-jp.rs/book-ja/)
を読んで学んだこと，気付いたことを追記していきます．

# 安全な理由
1. __所有権__のおかげで、メモリの複数回解放（memory corruption）が起こらない
2. __参照__のおかげで、データ競合が起こらない
  - 同一スコープで、ある変数の参照を複数生成する場合、全てが不変参照でなければならない?
3. __スライス__のおかげで、同期をとる変数を減らせる
  - e.g.) ある文字列の部分文字列を扱う場合に、配列のインデックスを変数に束縛するのではなく、スライスを束縛することでコンパイラが事前に危険なコードを検知してくれる?
4. ゼロコスト抽象化?
  - 静的ディスパッチ、人間による横展開と同じ?
  - [ゼロコスト抽象化とは何なのか？ - Qiita](https://qiita.com/kichion/items/d5d87b30176e1d2d5f54)
5. null機能がない
  > null値の問題は、nullの値をnullでない値のように使用しようとしたら、何らかの種類のエラーが出ることです。 このnullかそうでないかという特性は広く存在するので、この種の間違いを大変犯しやすいのです。
  >
  > しかしながら、nullが表現しようとしている概念は、それでも役に立つものです: nullは、 何らかの理由で現在無効、または存在しない値のことなのです。
  >
  > -- 引用「[Enumを定義する - The Rust Programming Language 日本語版](https://doc.rust-jp.rs/book-ja/ch06-01-defining-an-enum.html)」

6. orphan rule
  > トレイト実装で注意すべき制限の1つは、トレイトか対象の型が自分のクレートに固有(local)である時のみ、 型に対してトレイトを実装できるということです。例えば、Displayのような標準ライブラリのトレイトをaggregatorクレートの機能の一部として、 Tweetのような独自の型に実装できます。型Tweetがaggregatorクレートに固有だからです。 また、SummaryをaggregatorクレートでVec<T>に対して実装することもできます。 トレイトSummaryは、aggregatorクレートに固有だからです。
しかし、外部のトレイトを外部の型に対して実装することはできません。例として、 aggregatorクレート内でVec<T>に対してDisplayトレイトを実装することはできません。 DisplayとVec<T>は標準ライブラリで定義され、aggregatorクレートに固有ではないからです。 この制限は、コヒーレンス(coherence)、特に孤児のルール(orphan rule)と呼ばれるプログラムの特性の一部で、 親の型が存在しないためにそう命名されました。この規則により、他の人のコードが自分のコードを壊したり、 その逆が起きないことを保証してくれます。この規則がなければ、2つのクレートが同じ型に対して同じトレイトを実装できてしまい、 コンパイラはどちらの実装を使うべきかわからなくなってしまうでしょう。


# 速い理由
1. 明示しないかぎり deep copy が起こらず、 shallow copy のみが行われる
  - スタックに積まれるようなスカラー値では、 sahllow copy == deep copy
2. 単相化（monomorphization）
  > ジェネリックな型引数を使用すると、実行時にコストが発生するのかな、と思うかもしれません。 嬉しいことにRustでは、ジェネリクスを、具体的な型があるコードよりもジェネリックな型を使用したコードを実行するのが遅くならないように実装しています。
  > コンパイラはこれを、ジェネリクスを使用しているコードの単相化をコンパイル時に行うことで達成しています。 単相化(monomorphization)は、コンパイル時に使用されている具体的な型を入れることで、 ジェネリックなコードを特定のコードに変換する過程のことです。
  > この過程において、コンパイラは、リスト10-5でジェネリックな関数を生成するために使用した手順と真逆のことをしています: コンパイラは、ジェネリックなコードが呼び出されている箇所全部を見て、 ジェネリックなコードが呼び出されている具体的な型のコードを生成するのです。

3. 


# チュートリアルのメモ
## 8.3
練習問題をやる！！

## 9.2
if error.kind() == ErrorKind::Notfoundという条件式は、マッチガードと呼ばれます: アームのパターンをさらに洗練するmatchアーム上のおまけの条件式です。この条件式は、 そのアームのコードが実行されるには真でなければいけないのです; そうでなければ、 パターンマッチングは継続し、matchの次のアームを考慮します。パターンのrefは、 errorがガード条件式にムーブされないように必要ですが、ただ単にガード式に参照されます。 refを使用して&の代わりにパターン内で参照を作っている理由は、第18章で詳しく講義します。 手短に言えば、パターンの文脈において、&は参照にマッチし、その値を返しますが、 refは値にマッチし、それへの参照を返すということなのです。

## 9.3
関数にはしばしば契約が伴います: 入力が特定の条件を満たすときのみ、振る舞いが保証されるのです。 契約が侵されたときにパニックすることは、道理が通っています。なぜなら、契約侵害は常に呼び出し側のバグを示唆し、 呼び出し側に明示的に処理してもらう必要のある種類のエラーではないからです。実際に、 呼び出し側が回復する合理的な手段はありません; 呼び出し側のプログラマがコードを修正する必要があるのです。

## 10.2
```rust
pub fn notify(item1: &impl Summary, item2: &impl Summary) {
```
この関数が受け取るitem1とitem2の型が（どちらもSummaryを実装する限り）異なっても良いとするならば、impl Traitは適切でしょう。 両方の引数が同じ型であることを強制することは、以下のようにトレイト境界を使ってのみ表現可能です：

```rust
pub fn notify<T: Summary>(item1: &T, item2: &T) {
```

引数であるitem1とitem2の型としてジェネリックな型Tを指定しました。 これにより、item1とitem2として関数に渡される値の具体的な型が同一でなければならない、という制約を与えています。
AzureADのグループにAKSの読み取り権限をRBACを使って与える

AKSの読み取り権限を、AzureAD上にあるグループに与える必要があり調べてみました。AzureADとKubernetesのロールなどを使って行いましたので、そのあたりをまとめてみました。

#Azureの既存のロールをグループに割り当て
細かく権限を管理する場合は、カスタムロールを作って権限を精査する必要がありますが 、テスト環境などでそれほど気にしなくてよい場合は既存のロールで十分かと思います。
AzureADに存在する`MyReadOnlyGroup`に読み取り権限を与えます。

```bash
#権限をつけるグループとAKSのIDを取得
AksID=$(az aks show --resource-group my-resource \
      --name my-aks --query id -o tsv)
GroupID=$(az ad group show --group "MyReadOnlyGroup" \
        --query objectId -o tsv)

#ロールアサイメント
az role assignment create --assignee $GroupID \
   --role "Azure Kubernetes Service Cluster User Role" \
   --scope $AksID
```
Azure portalのAKSのアクセス制御（IAM）で`MyReadOnlyGroup`に`Azure Kubernetes Service Cluster User Role`が付いていることが確認できます。

#KubernetesのCluster Role/Viewをグループに割り当て
先ほどと同じグループに次はKubernetes内で`View`権限を割り当てます。`View`ロールだと大体のリソースを見ることはできますが、シークレットを見ることはできません。これもAzureADのロール同様、テスト環境なので既存のロールを使用しクラスター全体の読み取り権限を与えます。

```yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: aks-readonly
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: view
subjects:
- kind: Group
  name: groupObjectId
```
`groupObjectId`を先ほどの`$GroupID`で置き換えると、`MyReadOnlyGroup`にK8Sの読み取り権限を与えることができます。

`kubectl`で確認するとこのような感じです。

```bash
kubectl describe clusterrolebinding aks-readonly

Name:         aks-readonly
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  view
Subjects:
  Kind   Name                                  Namespace
  ----   ----                                  ---------
  Group  1111111-11111-1111-1111-111111111
```


#参考記事
https://docs.microsoft.com/en-us/azure/aks/azure-ad-rbac
Vue.js~ToDoリスト②~（関数と引数）

今回はToDoリストの追加ができるように実装していきたいと思います。
それではやってきましょう！！

```index.html
  <div id="app" class="container">
    <h1>ToDo-App</h1>
    <ul>
      <li v-for="todo in todo">{{ todo }}</li>
    </ul>
    <div class="inputs">
      <input type="text" v-model="newItem">
      <input type="button" value="UP" v-on:click="UPItem">
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
  <script src="script/script.js"></script>
```
今回HTMLでの大切な記述は以下2つになります！！
#①　v-model
これは、画面に入力された値がjs側に反映されます。とても大切なのでしっかり覚えておきましょう😊
前回の記事のときにformタグを使ってましたが、ここではinputに変えました🙌
#②　v-on:crick
これは、イベント実施時にjsの実行が行われます👍
それから、このアイテムを使うことでアイテムのリストを配列内のデータを使って表示することができインスタンスのメソッドを呼び出すことができます！

また、前回HTML側でformタグを使用していましたが、
formタグの場合は、画面変異されて、記入がめんどいので、今回はこちらの記述で行きます。
もし、フォームタグ使用する場合は、

```index.html
<div class="inputs" @submit.prevent="UPItem">
      <input type="text">
      <input type="submit" value="UP">
    </div>
```
とつけ加えます！！
preventの使い所については後ほど学習していきます😊

それではjs側の実装をみていきます。

```index.js
 methods: {
    UPItem: function(event) {
      this.todo.push(this.newItem)
    }
  }
```

前回オブジェクトについての学習でも登場したメソッドくんです👍
js側で実行してほしい内容を記述していきます。
今回初登場のfunctionです。これは、関数です。では、関数について学習していきましょう👍

#関数について
関数とはあるデータを受け取り、決められた処理を実行し、その結果を返す命令のことです。
今回の場合は、HTML側での入力内容をJs側でプッシュするんだよ。という感じです。
英語が並んでいますが、訳すとこんな感じです😊

#引数について
functionの隣にカッコがありますね。これは、引数と言います。
引数とは、関数に渡す値のことです。

関数と引数が難しいところですが、整理すると、function（機能）が自動車として引数がガソリンで、実行されるのが走り出す感じです。

それでは、続きからみていきましょう。
functionのデータ内には、thisでアクセスすることができます。
this.newItemとすることで、newItemに追加された内容がtodosに追加される感じになります。

ちょっとめんどくさいですがコンナ感じで、ToDoリストに追加できるようセットすることができました！！
R で数値を0を加えて文字列に変換

# はじめに
GFSのデータ([https://www.ncdc.noaa.gov/data-access/model-data/model-datasets/global-forcast-system-gfs](https://www.ncdc.noaa.gov/data-access/model-data/model-datasets/global-forcast-system-gfs))を扱うときにファイル名の扱いをちょっと調べたので、備忘録も兼ねて記事にしておく。数値的に連続したファイル名を扱いたい時に便利。

GFS は0から384時間後まで3時間区切りの予報データである。ファイルは、gfs_<mode>_<予報した日>_<予報した時刻>_<何時間後の予報か>.grib2 というフォーマットである（例：gfs_3_20210313_0600_003.grib2）。 ファイル名に"003"の様に0を文頭に含む数字で表現される。これを扱うときに数字でfor文を回しつつ文字列に変換して操作をしたかった。

# 0を文頭に数値を文字列に変換
数字を文字列に変換つつ0を加えるのには formatC 関数を使う。

```R:
> for (i in 1:10) {
+     num <- 3*i
+     num <- formatC(num, width = 3, flag = "0")
+     print(num)
+ }
[1] "003"
[1] "006"
[1] "009"
[1] "012"
[1] "015"
[1] "018"
[1] "021"
[1] "024"
[1] "027"
[1] "030"
```

width で文字列の桁数、flag で文頭に表示したい文字を指定する。flag で指定できるのは0+-#だけ。これを使って今日の0時に発表されたGFSのファイル名を作ると、

```R:コード
mode <- "3"
today <- Sys.Date()
date <- format(today, "%Y%m%d")
time <- "0000"

for (i in 0:128) {
  num <- 3*i
  num <- formatC(num, width = 3, flag = "0")
  filename <- paste("gfs_", mode, "_", date, "_", time, "_", num, ".grib2", sep = "")
  print(filename)
}
```

```:出力
[1] "gfs_3_20210324_0000_000.grib2"
[1] "gfs_3_20210324_0000_003.grib2"
[1] "gfs_3_20210324_0000_006.grib2"
-- 中略 --
[1] "gfs_3_20210324_0000_378.grib2"
[1] "gfs_3_20210324_0000_381.grib2"
[1] "gfs_3_20210324_0000_384.grib2"
```

となる。

# おわりに
RのTips も気が付いたものから記事にしていきたいと思う。
M1チップのMacでDockerが使えない。

ARMチップ搭載の最新のMacに変えたら、今までのDockerが使えなくなりました。
中でなにが起こっているか詳しくはわかりませんが、インテルチップ→ARMチップよって起こったエラーのようです。
以下からARMでも動くdockerがダウンロードできます。

https://docs.docker.com/docker-for-mac/apple-m1/
【kintone】Kintone Portal Designer と kintone UI Component v1でポータルにボタンを設置する

こんにちは！

今回は`Kintone Portal Designer` と `kintone UI Component v1` を使って、
kintoneのポータルにボタンを設置してみたいと思います！

# Kintone Portal Designer の準備

Kintone Portal Designer をChromeにインストールして、簡単なデザインを作ります。
↓詳しくは公式ページへ

https://developer.cybozu.io/hc/ja/articles/360030856652-Kintone-Portal-Designer%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%9D%E3%83%BC%E3%82%BF%E3%83%AB%E3%82%92%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%81%97%E3%82%88%E3%81%86

# kintone UI Component v1 の準備

kintoneシステム管理から、JavaScript / CSSでカスタマイズを選択し
kintone UI Component v1 のCDNを追加しておきます。

`https://unpkg.com/kintone-ui-component/umd/kuc.min.js`

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/b4bdc497-8f06-d3c9-7805-cd1156378976.png" width=300>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/b2e20890-cd9e-80f9-7641-193c0f45d833.png" width=400>


# デザインの作成
HTMLやCSSはこちらのサイトからお借りしてwidthやmarginの調整をしました。

https://saruwakakun.com/html-css/reference/box

## HTML
Kintone Portal Designer 上でHTML、CSS、JavaScriptを編集します。

ボタンを置く用に`id="button-test"`なdivタグを置いておきます。

```html
<div class="box30">
    <div class="box-title">ボタンを置くところ</div>
    <p>ボタンを置くところ</p>
    <div id="button-test"></div>
</div>
```

ブラウザ上ではこのような感じ。CSS、JavaScriptを書く時はタブを切り替えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/9259acb5-4598-a791-8bc1-ce1335d80826.png)

## CSS 
CSSタブに切り替えて書いていきます。

```css
.box30 {
    background: #f1f1f1;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.22);
    width:80%;
    margin: 30px auto;
}
.box30 .box-title {
    font-size: 1.2em;
    background: #5fc2f5;
    padding: 10px;
    text-align: center;
    color: #FFF;
    font-weight: bold;
    letter-spacing: 0.05em;
}
.box30 p {
    padding: 15px 20px;
    margin: 0 ;
}
```

## JavaScript
ボタンを設置＆ボタンクリックのコードを書きます。

```js
(() => {
  "use strict";
  kintone.events.on(["portal.show"], (event) => {
    //ボタン設置
    const divButton = document.getElementById("button-test");
    const sutekiButton = new Kuc.Button({
      text: "素敵なボタン",
      type: "submit",
    });
    divButton.appendChild(sutekiButton);
   
    //グラフ設定更新ボタンクリック
    sutekiButton.addEventListener("click", async () => {
      alert("ボタンをクリック！");
    });

    return event;
  });
})();
```

# 動作確認
ボタンが表示され、クリックでメッセージが表示されたでしょうか？

![portal2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/2cdd9e51-c934-adae-fbee-1a41976d5f33.gif)

# まとめ
 
Kintone Portal Designerを使うことにより、HTMLやCSSを自分で書いてデザインすることができます。自由度が高く、TwitterのTLを表示することもできます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/074ceb4a-953c-f464-7f22-53e1bf4dc8f8.png" width=500>


また、HTMLやCSSが苦手・・・という方でも、
**kintoneポータルデザインテンプレートギャラリー**から気に入ったものを選び、値や文字列を変更するだけで素敵なデザインのポータルにすることもできます。
次回は、Sample TemplateからデザインをImportしてポータルを作ってみたいと思います。

https://developer.cybozu.io/hc/ja/articles/360029783812
GNS3でネットワーク勉強するときの初期設定

GNS3を使って勉強するときの初期設定についてです。
いつも必要最低限の設定をしています。
※必要な設定や対象機器が増えたら随時更新します～

#Cisco機器
###ホスト名の設定

```
Router#configure terminal
Router(config)#hostname ホスト名
```

###パスワードの設定
**特権EXECモードに移行するとき**

```
Router(config)#enable secret パスワード
```

もしくは

```
Router(config)#enable password パスワード
```

一般的にはパスワードが暗号化されるenable secretコマンドを使用することが多いとのことなので、わたしはenable secretコマンドを使用しています。

**コンソール接続するとき**

```
Router(config)#line console 0
Router(config-line)#password パスワード
Router(config-line)#login
```
**telnet接続するとき**

```
Router(config)#line vty 0 4
Router(config-line)#password パスワード
Router(config-line)#login
```

**ssh接続するとき**

```
Router(config)#hostname ホスト名　（ここでは"R1"とする）
R1(config)#username ユーザ名 password パスワード
R1(config)#ip domain-name ドメイン名　（ここでは"abc.com"とする）
R1(config)#crypto key generate rsa
The name for the keys will be: R1.abc.com
Choose the size of the key modulus in the range of 360 to 2048 for your
  General Purpose Keys. Choosing a key modulus greater than 512 may take
  a few minutes.

How many bits in the modulus [512]: 1024
% Generating 1024 bit RSA keys ...[OK]

R1(config)#line vty 0 4
R1(config-line)#login local
```

sshの設定は少し手間がかかるので、コンソールとtelnetの設定をすることが多いです。
方法を覚えたいときに積極的に使います！
また、わたしが使っているC3745にはsshのバージョンを変更するコマンドがないので、バージョン1のままです。
Tera Termでssh接続するときは、SSH2ではなくSSH1に変える必要があるので注意です！

**コンソール/リモート接続のパスワードを暗号化**

```
Router(config)#service password-encryption
```
CCNAでも出てくるコマンドです。
勉強用ならわざわざ暗号化する必要もないですが、使っていくうちに自然と覚えるので使ったほうがいいです。

###インターフェース設定
**ルータの場合**

```
Router(config)#interface インターフェース
Router(config-if)#no shutdown
Router(config-if)#ip address IPアドレス サブネットマスク
```

**スイッチの場合**

```
Switch(config)#interface インターフェース
Switch(config-if)#no shutdown
Switch(config-if)#exit
Switch(config)#interface vlan VLAN番号
Switch(config-if)#no shutdown
Switch(config-if)#ip address IPアドレス サブネットマスク
```

リモート接続できるよう、必要なインターフェースを有効にしてIPアドレスを設定します。
スイッチは、インターフェースにIPアドレスを設定できないのでVLANに設定します。（no shutdownコマンドはVLAN 1のみで大丈夫です）
異なるセグメントからアクセスする場合は以下の設定も必要です。

**ルータの場合**

```
Router(config)#ip route ネットワークアドレス サブネットマスク ネクストホップ
```

**スイッチの場合**

```
Switch(config)#ip default-gateway IPアドレス
```

先輩から「最低限設定したら、コンソールではなく通信速度が速いリモートに切り替えるように！」と注意されてから、設定や確認時にコンソールをメインで使わないように気を付けています。。
なので、インターフェースもリモート接続用の分だけ設定すればOKです。

###設定したほうが作業が楽になるコマンド
**画面に表示される行数を指定**

```
Router#terminal length 0
```

確認やログ取るときに``--More--``と表示されるのをなくします。

**DNS機能の無効化**

```
Router(config)#no ip domain-lookup
```

デフォルトで有効になっているのですが、そのままにしておくとコマンドのタイプミスをした際に、ブロードキャストでありもしないDNSサーバに問い合わせるということが発生します。
いったん問い合わせるとコマンドの入力を受け付けなくなる（しかもその時間が長い）ので、使わない場合は無効にしたほうがいいです！

**コマンドを自動で再表示**

```
Router(config-line)#logging synchronous
```
コマンド入力最中にルータやスイッチからのメッセージが割り込んでも、自動で入力途中のコマンドを再表示してくれる設定です。
コンソールポート/VTYポートそれぞれに設定が必要です。

###設定を保存
```
Router#copy running-config startup-config
```
設定の保存が完了したら、リモート接続に切り替えて勉強を開始します。

#参考サイト

* [ネットワークエンジニアとして](https://www.infraexpert.com/)
* [ネットワーク入門サイト](https://beginners-network.com/)
PythonでTCPソケット通信サンプル

#サーバー側

```python:server.py
import socket
import numpy as np
import time

PORT = 12345

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    host = (socket.gethostbyname(socket.gethostname()))
    print(f"{host = }")
    s.bind((host, PORT))

    while True:
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.listen(1)
        print("listen")
        conn, addr = s.accept()
        print("accept")
        i = 0

        while True:
            try:
                print(f"{i*0.04:.03f}")
                i += 1
                data = np.zeros(3*64, dtype="int16")
                conn.sendall(data)
                time.sleep(0.04)

            except KeyboardInterrupt:
                print('Interrupted.')
                break

            except:
                break
```

#クライアント側

```python:client.py
import socket

HOST = '172.27.128.1'
PORT = 12345

recv_size = 0
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    print(s.connect((HOST, PORT)))

    while 1:
        data = s.recv(1024)
        recv_size += len(data)
        print(len(data), recv_size)

```
Notionで数式の行を揃える

### 解決

```latex
\begin{aligned}
E[Y] &= E[X+W] \\
     &= E[X] + E[W]
\end{aligned}
```

``` math
\begin{aligned}
E[Y] &= E[X+W] \\
     &= E[X] + E[W]
\end{aligned}
```

### 参考

- https://www.notion.so/Math-equations-b4e9e4e03677413481a4910e8bd328c
- https://katex.org/docs/issues.html
これからPycharmを使い始める人におすすめのプラグイン3選

Pythonのコードを書くにはIDE(統合開発環境)やテキストエディタが使えますが、選択肢の1つとしてJetBrainsの[Pycharm](https://www.jetbrains.com/ja-jp/pycharm/)というIDEがあります。

無料のCommunity版と有料のProfessional版がありますが、機能的には無料版でも十分です。ただしより快適に開発を進めるために使えるプラグイン3つを紹介したいと思います。

# おすすめプラグイン一覧
* Japanese language Pack / 日本語言語パック
* Database Navigator
* File watchers

## Japanese language Pack / 日本語言語パック
これは名前の通り、Pycharmの言語設定を日本語に変えるためのものです。
以前は[ここ](https://mergedoc.osdn.jp)からPleiadesプラグインをダウンロードしてインストールするのが主流だったようですが、現在はJetBrains公式より提供されているこちらのプラグインを使用するのが良いでしょう。

## Database Navigator
こちらも名前の通り、データベースの管理を簡単にするプラグインです。データベースを使用しないプラグラムであれば必要ないかもしれませんが、特定のGUIを持たないSQLiteなどを使用する場合、GUIベースで構造やデータを確認できるので重宝します。

使用できるデータベースは以下の通りです。

* Oracle
* MySQL
* SQLite
* PostgreSQL
* Any JDBC compliant database (EXPERIMENTAL)

## File watchers
こちらはファイルの変更をトリガにできるプラグインです。例えばPythonでは[Black](https://github.com/psf/black)という自動フォーマットツールがありますが、Blackに対しファイルの変更を通知して自動フォーマットを実行するというような使い方ができます。

# 最後に
Pycharmには豊富なプラグインが用意されており、検索も簡単に行うことができます。開発を快適に進めるために、自分にあったプラグインをぜひ探してみてください。
【Unity】UnityでGoogle Play Gamesにサインインできない問題の解決方法備忘録

# はじめに
Unityで製作しているAndroidアプリで長らくGoogle Play Gamesにサインインできない状態に陥っていました。
最終的に解決できたのですが、原因となる候補が色々あったので備忘録としてまとめておきます。

## 筆者の環境
- Unity：2023.1.10
- play-games-plugin-for-unity：0.11.01

# Google Play Gamesにログインできないエラーの原因かもしれないものとその解決方法一覧
## Unity Editor
### 上のツールバーで `Window/Google Play Games/Setup/Android setup...` してない
Google Play Consoleで対象のアプリを選択し、 `Playゲームサービス>設定と管理>クエスト` を開く。
次に右上の `リソースを取得` を押し、xmlをコピーしてAndroid setupに貼り付ける。

### `Assets/External Dependency Manager/Android Resolver/Resolve` 後に `Assets/Plugins/Android` に各種ライブラリファイルが生成されていない。
`Force Resolve` すれば直る。
失敗する場合はplay-games-plugin-for-unityを入れ直したりプロジェクトの `Library` ディレクトリを消せば成功するはず。

### Player SettingsのPublishing Settingsの `Custom Proguard File` にチェックを入れていない
チェックを入れる。
そうしたら `Assets\Plugins\Android\proguard-user.txt` というもの作られるので、このファイルに https://github.com/playgameservices/play-games-plugin-for-unity/blob/master/scripts/proguard.txt の内容を貼り付ける。

### Player SettingsのPublishing Settingsの `Minify` の `Release` にチェックを入れていない
チェックを入れる。
他の項目のチェックは外した方が良いかも。

## Google Play Console
### `Playゲームサービス>設定と管理>設定` で認証情報を設定していない
ちゃんと設定する。

## Google Cloud Platform
OAuth クライアントのSHA1フィンガープリントの値が正しいか確認する。
フィンガープリントの値の確認はkeytoolでも良いが、 `リリース>アプリの完全性` で確認するのが手っ取り早い。
アプリの完全性画面の `アプリ署名鍵の証明書` の方のSHA1フィンガープリントの値に設定する。

**備考**
うろ覚えだが、 `内部テスト版` では `アップロード鍵の証明書` の方のSHA1フィンガープリントの値でないとログインできなかった。
GitHub PagesでURLを発行するまで

##はじめに
git initからGitHub PagesでURLを発行するまでの過程を書きます。

大まかな流れ
git init→ユーザー名とメールアドレス登録→リモートリポジトリ登録→情報確認→add→commit→push→URL発行

##git init
git initはリポジトリを新規作成するコマンドで「.git」というディレクトリが作成される
（.gitは隠しファイルなので表示されないmacだと「comman+shift+.」で表示できる）

~~~
$ git init
~~~

##ユーザー名とメールアドレス登録
これをしないとaddするときにエラーが出る

~~~
$ git config --global user.name "ユーザー名"
$ git config --global user.email "メールアドレス"
~~~

##リモートリポジトリ登録
よく記事でみるのは以下の二つ

~~~
$ git remote add origin https://github.com/user/repo.git
or
$ git remote add origin git@github.com:username/repository.git
~~~
origin以下が違いますが、これはHTTPとSSHという通信プロトコルの違いがURLに現れています。
あまり気にしないで先に進みます。この「origin」がリモートリポジトリ名でURL部分がリモートリポジトリ名とのパスになります。
「origin」という名前がよく使われているので何も知らない人からすると「origin」がコマンドの一種に見えますが違います。結局以下のようになります。

~~~
$ git remote add リモート名 URL
~~~

##情報確認
リモートリポジトリの名前とアドレスと確認できる

~~~
$ git remote -v
origin    https://xxxxxx.xxx/xxxxx (fetch)
origin    https://xxxxxx.xxx/xxxxx (push)
~~~

##add→commit→push
これもよく見る流れ

~~~
$ git add ファイル名
$ git commit -m "add : inital commit"
$ git push origin master
~~~
ファイルをaddしてコミット、そしてリモートリポジトリにあるmasterにpushする。
ファイルはなんでも良くて「index.html」でも「style.css」とか上げたい物を書く。
commitの""の中はコミットメッセージと呼ばれ、commitにコメントをつける。今回は「add : inital commit」と書かれているがこれは、はじめてaddしましたよと言いたいからこうなっているが、形式は特にない。

##URL発行
GitHubの画面で、pushしたリポジトリのSettingのページに行きGitHub Pagesの項目で、公開したい内容が入っているブランチを選ぶとURLが発行される。

##参考
[リモートの URL の変更 - GitHub Docs](https://docs.github.com/ja/free-pro-team@latest/github/using-git/changing-a-remotes-url)
Nuxt.js 【Browserslist: caniuse-lite is outdated. ....... 】警告の対処法

Nuxt.jsにて、ビルド中に下記警告が出た時の対処法です。

```
Browserslist: caniuse-lite is outdated. 
Please run the following command: `npx browserslist --update-db`
```

## browserslistをアップデートする

警告にある通り、下記のコマンドでbrowserslistをアップデートします。

```
npx browserslist --update-db
```
`yarn.lock`などが更新され、警告も消えます。

https://www.npmjs.com/package/browserslist
Markdown 打ち消し線を使う

## 目的

- Markdownで打ち消し線の使い方をまとめる

## 方法

- 下記のように打ち消し線で打ち消したい内容を`~~`で囲む

    ```markdown
    ~~こんにちは~~
    ```

- 下記のようにプレビューされる。
    - ~~こんにちは~~
Dockerコンテナ内で面倒なgo buildを実行する

https://qiita.com/kishibashi3/items/2b1e342d1ce3957b3dc8

の続き。
# 概要

今回作成したサービスがopencvなどの環境を作成するのが面倒で、buildするのも一苦労するため、buildについてもdockerの中でやってしまおう、ということで試してみた。

### topic

* opencvやgstreamerなど多くのライブラリが必要
    * 開発環境用docker imageがそのまま使用できそう
* goライブラリの中に、privateなライブラリが含まれている
    * 上記にアクセスするために、SSH鍵が必要
* 前段のgo build処理 、通常のdocker buildのマルチステージビルド

# Dockerfile

今回作成したDockerfileは以下。

ベースイメージである`ghcr.io/my_organization/devcontainer-go1.15-opencv4.5:latest`については、

https://qiita.com/kishibashi3/items/e20aecef45ed8341e739

を参照。（上記からの連続記事です）


```docker
# syntax=docker/dockerfile:1.0.0-experimental
FROM ghcr.io/my_organization/devcontainer-go1.15-opencv4.5:latest as go-build

# set Hoge lib as private
ARG GOPRIVATE=github.com/Hoge

# for gocv
ARG LD_LIBRARY_PATH=/usr/local/lib:/app/lib
# for Hoge
ARG CGO_LDFLAGS="-L/app/lib -lHoge"
# for gocv
ARG PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/local/lib/pkgconfig

RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts

# ソースコードを/appにコピー
COPY . /app　
WORKDIR /app

RUN git config --global url."ssh://git@github".insteadOf https://github
RUN --mount=type=ssh go mod tidy
RUN go build -o main ./cmd

FROM ghcr.io/my_organization/devcontainer-go1.15-opencv4.5:latest

RUN mkdir /app
WORKDIR /app

# 1つ目のステージからバイナリだけコピー
COPY --from=go-build /app/main ./main

CMD ["./main"]
```

### `syntax=docker/dockerfile:1.0.0-experimental`
`go mod tidy`するためにホスト側のssh private keyをコンテナ内で使用する必要があった。DockerのBuildKitを使うとコンテナに含まれないようにsecret情報をbuild中にマウントできるという情報があり、使ってみた。
その機能を使うためにDockerfileの先頭にこの一行が必要。

参考

https://qiita.com/takasp/items/56e1399a484ed5bfaade

### `RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts`
known_hostsを作成するおまじない。goライブラリをダウンロードするときにgithub.comが追加されている必要があるため。


### `RUN git config --global url."ssh://git@github".insteadOf https://github`
golangのプライベートライブラリにsshでアクセスするためのおまじない。


### `RUN --mount=type=ssh go mod tidy`
今回の肝。これでローカルホスト側のssh鍵をマウントしている。実際にマウントされる鍵は、docker build実行時に指定する。

# Makefile

```makefile
IMAGE=ghcr.io/my_organization/my_application
TAG=latest

build:
	docker build --ssh default=${HOME}/.ssh/id_rsa -t $(IMAGE) .
	docker tag $(IMAGE) $(IMAGE):$(TAG)
	docker push $(IMAGE):$(TAG)
```

これで

```sh
$ make build
```
でgo build、docker buildが行われてrepositoryにpushされる。


# 評価
ssh鍵をdockerコンテナ内で使う方法で悩んだ。BuildKitを使う事で上記はクリアし、シンプルなDockerfile & Makefileになったように思う。

開発環境をそのままビルド環境に利用したことの是非は判断できていない。
開発環境イメージには不要なものもたくさん含まれているとは思うものの、開発環境なら確実にビルドできるだろう、という思いもある。

> ビルドに不要なものを.dockerignoreで外すのをお忘れなく！
How to run multiple Skype Accounts simultaneously

Skypeにいくつかの借金を同時に適用する1つの方法は、ラップトップでSkypeを既に実行している場合、web.skype.comでWebアプリを正直に開き、セカンダリアカウントでログインすることです。したがって、2つの特別債務を同時に使用することができます。
Sukaipu ni ikutsu ka no shakkin o dōjini tekiyō suru 1tsu no hōhō wa, rappu toppu de sukaipu o sudeni jikkō shite iru baai, web. Skype. Komu de u~ebu apuri o shōjiki ni hiraki, sekandariakaunto de roguin suru kotodesu. Shitagatte, 2tsu no tokubetsu saimu o dōjini shiyō suru koto ga dekimasu.



We use Skype each day to speak with our friends, family , withinside the paintings , for interviews. But    <b><a href=http://sites.google.com/view/skypelogins/home>skype login</a></b>    does not provide any apparent manner to apply a couple of debts simultaneously. Sometimes want to apply your non-public account and your paintings account on the equal time. As IT i had lot of requests in my paintings if can use Skype with a couple of debts on the equal time. I actually have observed this manner and i can percentage with you ways can do it. 

 

One manner to apply Skype a couple of debts simultaneously is when you have already running Skype  for your laptop you may honestly open the Web App at web.skype.com and login with secondary account. So you may use 2 special debts on the equal time.



 

To use greater than 2 Skype debts you may open the internet.skype.com from unique internet browser and login with unique debts. 

Very simple.

 

From Skype for Desktop in Windows
If you need to use Skype handiest from your Desktop or Laptop then you may register with a couple of debts with the subsequent steps.

Open your Skype and login with the primary account as usual
Go in Start - - >Run and sort the subsequent command when you have install Skype in default path.
For 64bit

"C:Program Files (x86)SkypePhoneSkype.exe" /secondary



For 32bit

"C:\Program Files\Skype\Phone\Skype.exe" /secondary



 

You can repeat this command for third,fourth and different extra copies of Skype.

Note: If you've got got set up in distinctive folder the Skype instedad of the default you ought to alternate the command with the course which you have set up Skype.

If you need to make it less complicated you could create shortcuts as an alternative to run each time the command.

Go to your desktop and Right click on in Shortcut of Skype.
Click Open File Location.


Right Click in Skype.exe and Select Send to - - >Desktop.


Go in Desktop and discover the brand new Shortcut of your Skype (typically the call is Skype - Shortcut)
Right click on and select Properties.
In the Target upload ultimately the word  /secondary.(After Skype.exe" go away area except you get an error)
Click OK.
 

Now login with the Skype which you have it.
Click in the Second Skype and you may see on the way to ask for credentias.
Login with your 2nd account.
You can repeat those steps for third,fourth and different extra copies of Skype.

I desire to discover intresting my article and already begin to use Skype a couple of accoutns.

Have a pleasant weekend !!!.
Rubyにおける繰り返し処理

## はじめに
この記事は、Rubyにおける繰り返し処理について調べたものの忘備録です。初心者の書いたものですのでミスがあるかもしれませんが、その場合指摘していただけると助かります。
## 結論
Rubyに用意されている繰り返しに使われる制御構造とメソッドについて代表的なものをまず紹介します。

#### 制御構造
* while
* until
* for

####メソッド

* each
* times
* upto
* downto
* loop

以下にその紹介と使い方を記します。

### while

```ruby
while "条件式" do #doは省略可能
  "処理"
end
```

と記述し、条件式が真の値を取り続ける限りにおいて、処理を実行し続けます。
例えば、

```ruby
num = 1
while num <= 3 do
  puts "Hello World!"
  num += 1
end
```

と記述すれば、numが3以下の間、Hello Worldと言う文字が表示されます。今回の処理には、numの値が1増えるよう記述しました。と言うことで、この処理は3回繰り返されます。

### until
```ruby
until "条件式" do #doは省略可能
  "処理"
end
```
と記述し、条件式が偽の値を取り続ける限りにおいて、処理を実行し続けます。
例えば、

```ruby
num = 1
while num > 3 do
  puts "Hello World!"
  num += 1
end
```
until文は条件式が偽の場合処理を実行する文なので、まずこの条件式について解説します。条件式は"num>3"。これはnumの値が3より大きいことを意味します。この条件が偽、つまり満たされない場合処理が実行されます。"3より大きい"が満たされない、すなわち、numが3以下の場合この処理は実行されます。
numが3以下の間、Hello Worldと言う文字が表示されます。while文の時と同様、処理が一度実行されるたびにnumの値が1増えるよう記述しましたので、今回の場合も処理は3回繰り返されます。


この例だとuntilのありがたみが薄いですが、whileで条件を表現するのが難しい時は、逆にuntilで条件を表示するのが容易である可能性があります。より分かりやすいコードになるようにwhileとuntilは使い分けるものだそうです。

### for

``` ruby
for "変数" in "オブジェクト" do #doは省略可能
  "処理"
end
```
と記述します。inの後ろには"範囲オブジェクト"が入ることがあります。これは値と値の間に".."または"..."と記されたもので、"先に書いた値から後に書いた値まで"を意味します。
例えば、

```ruby:for_example1
for i in 1..5 do
  puts i
end
```
と言う処理を実行すれば、for文の動きを理解しやすいかと思います。このプログラムを実行すると、
>\>ruby for_example1
1
2
3
4
5

と言う表示がされます。この結果から、for文で用意したiと言う変数に1~5がそれぞれ代入されていることがわかります。

また、オブジェクトが配列などの場合もfor文を使うことができます。

```ruby:for_example2
countries = ["Japan", "USA", "Korean"]
for country in countries do
  puts country
end
```
ここではfor文で配列をオブジェクトとして指定しました。以下に実行例を示します。

>\>ruby for_example2
Japan
USA
Koren

### each
eachメソッドはfor文とよく似ています。for文をeachメソッドを使ったプログラムに直すのは容易です。以下にeachメソッドの汎用例と、for文で紹介した二つの例の書き換えを記します

```ruby

"オブジェクト".each do |"変数"|
  "処理"
end

(1..5).each do |i|
  puts i
end

countries = ["Japan", "USA", "Korean"]
countries.each do |country|
  puts country
end

```

このように、書き換えは容易です。for文はeachメソッドを人に分かりやすい字面にするために追加された特殊な構文だそうです。

###times

```ruby
"繰り返したい回数".times do |"変数"|
  "処理"
end
```

と記述します。繰り返したい回数だけ、処理を繰り返すメソッドです。

```ruby

3.times do
  puts "Hello World!"
end
```
と記述すれば、3回ほどHello World!と表示されます。

### upto

```ruby
"オブジェクト".upto(max) do |"変数"|
  "処理"
end
```

オブジェクトを変数に代入し、処理を実行します。これを、値を1ずつ増加させながら繰り返し、オブジェクトの値がmaxになったら処理をやめます。繰り返しの例として、以下にuptoメソッドを使って"Hello World!"と3回表示させるようなプログラムを書きました。

```ruby

1.upto(3) do 
  puts "Hello World!"
end
```

### downto

```ruby
"オブジェクト".downto(min) do |"変数"|
  "処理"
end
```

オブジェクトのを変数に代入し、処理を実行します。これを、値を1ずつ減少させながら繰り返し、オブジェクトの値がminになったら処理をやめます。繰り返しの例として、以下にdowntoメソッドを使って"Hello World!"と3回表示させるようなプログラムを書きました。

```ruby

3.downto(1) do 
  puts "Hello World!"
end
```

### loop
終了条件がない繰り返しのメソッドです。

終了条件がないプログラムを実行してしまうのは問題があるので、繰り返しを制御する2つの命令を紹介します。

```ruby
break #繰り返しを中断し、繰り返しから抜ける 
next  #次の回の繰り返しに移動する   　　
```
この二つの命令をif文などと組み合わせて繰り返しを制御できます。
loopメソッドを使い、3回"Hello World!"と表示させる例を以下に示します。

```ruby

i = 0
loop do
  puts "Hello World!"
  i += 1
  if i == 3
    break
  end
end
```

## 感想、まとめ
メソッドの汎用例にある変数は使っても使わなくてもいいです。仮に使った場合、特に指定がなければ0から代入され、処理が繰り返すたびに値は1増加します。
無駄に長くなってしまった感があります。もっと端的に表現したい。
SQLの基礎 select,where,limit 

こちらの記事では、私が学んだSQLについて記載しております。
自身の忘れないためのメモとしております。
間違っている部分もあるかもしれませんので、ご了承ください。

#selectを使用して、テーブルのデータを取得する

```
・テーブルから一部のカラムを取る場合
select　列１（カラム）,列２（カラム名）・・・ from テーブル名；

・全ての列を取得したい場合
select * from テーブル名;
```

#テーブルのカラムを取得し、カラム名を変更する

```
・テーブルからnameというカラム名を取る場合
select name from テーブル名；

・取得したnameを、「名前」と日本語に変更する場合
select name as 名前 from テーブル名;
select name 名前 from テーブル名; ←asを省略してもOK
```

#取得したデータから計算をして取得することも可能
```
・価格のカラム(price)から、税込価格を入れて取得したい場合
select price * 1.1 税込価格 from テーブル名;
↑ 
追加でpriceを、税込価格と変更して取得しています。

・商品名も入れて行う場合
select name　名前, price * 1.1 税込価格 from テーブル名；
↑
商品名と税込価格の両方を取得できる！
```

#条件をつけたい時に、whereを使用する
```
・商品の金額が５０００円以上の商品のみを取得する場合　
select name, price from テーブル名 where price >= 5000;

・name(商品名)とprice（価格）５０００円以上の取得が可能になる！
```
#演算子の種類

| 記号       | 意味　　　　　 | 記号       | 意味　　　　　　　　　　　　　　　　　|
|:---------- |:-----------:|:-----------|:------------:|
| =          |        等しい |   in       |     ある値がセット内に含まれているかどうか |
| >          |      より大きい | not in     |     値がセット内に含まれていないかどうか |
| <          |      より小さい | is null    |     値がnull　　　|
| >=         |      以上　　 |  is not null    |    値がnullでない　　|
| <=         |       以下　　| like            |    あいまい検索 　　|
| <>, !=     |     等しくない | betwee..and..   |     値が値の範囲内に含まれているかどうか |

#演算子とwhereを使用した書き方
```
・テーブルのid 1を取得する場合
select * from テーブル名 where id = 1;

・田中さんのみを取得する場合
select * from テーブル名 where name = '田中';

・１０００以上を取得する場合
select * from テーブル名 where price > 1０００;

・１０００以下を取得する場合
select * from テーブル名 where price < 1０００;

・１０００以外を取得する場合
select * from テーブル名 where price <> 1０００;　＊！＝も同じ

・idの１、２、３のみを取得する場合
select * from テーブル名 where id in(1,2,3);

・idの１、２、３以外を取得する場合
select * from テーブル名 where id not in(1,2,3);

・null以外を取得する場合
select * from テーブル名 where price is not null;

・nullのみ取得する場合
select * from テーブル名 where price is null;

・１０００から２０００までの範囲を取得する場合　（書き方２種類）
select * from テーブル名 where price between 1000 and ２０００;
select * from テーブル名 where price >= 1000 and price <= ２０００;

・田中もしくは鈴木を取得する場合
select * from テーブル名 where name = '田中' or name = '鈴木';

・likeでの検索を行う場合　''中に、％もしくは_を使用する
select * from テーブル名 where name like '田%';　 '田'で始まる文字列を取得
select * from テーブル名 where name like '%田%';　'田'を含む文字列を取得
select * from テーブル名 where name like '%郎';　 '郎'で終わる文字列を取得
select * from テーブル名 where name like '_郎';　　何かしら2文字から始まり、'郎'で終わる文字列
```

#limitを使用して、取得の制限をかける
```
・limitの記述方法　オフセットはなくても良い！
select　カラム名 from テーブル名 limit [オフセット,] 最大取得数；

・１０件を取得する場合
select * from テーブル名 limit 10;  

・１から１０件を取得する場合　どこから取得したいかを制限する  
下記は１件目から１０件目を取得される
select * from テーブル名 limit 0, 10;　注意　１件目から取得する場合は、０から開始すること

・１０件目から１０件取得する場合　下記の場合だと１１件目から２０件目までを取得される。
select * from テーブル名 limit 10, 10;
```

#補足
####エラーが起こった場合は、下記三点を確認する！！
-DBの選択をしていない。
-スペルミスをしていないか。
-全角文字になっていないか。
上記３点で解決しなければ、エラーコードから検索して行うと早く発見できる可能性がある。

####過去に行ったSQLコードを再度読み込みたい場合
Action Outputから右クリックを押し、「Append Selected items to SQL script」をクリックすると過去のコードを読み起こすことが可能です。
[JS] アロー関数


無名関数
---

２つの出力結果は同じです

```
const hello = function(name = 'Shun') {
  console.log('hello' + name);
}

hello();
```

```
function hello(name = 'Shun') {
  console.log('hello' + name);
}

hello();
```

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

---
が、
１つ目の、実行後に変数の宣言があった場合にはエラーが発生します

```
hello();

const hello = function(name = 'Shun') {
  console.log('hello' + name);
}
```

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

JavaScriptの動きとしては、関数を一度ファイル全体で確認してから処理が行われるので、
２つ目の関数宣言はエラーが発生しません

```
hello();

function hello(name = 'Shun') {
  console.log('hello' + name);
}
```

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

この違いは認識しておきましょう

アロー関数
---
=>を用います
{　}内が一行の場合は{　}を省略できます
nameにデフォルト値がない場合、かつ関数の引数が１つの場合には(　)も省略できます

```
const hello = name => console.log('hello' + name);

hello('Shun');
```
[![Image from Gyazo](https://i.gyazo.com/ea73f9d290ef36ee551cdbf2436ae3ce.png)](https://gyazo.com/ea73f9d290ef36ee551cdbf2436ae3ce)

---
nameにデフォルト値がある場合

```
const hello = (name + 'Shun') => console.log('hello' + name);

hello();
```

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

---
かつ関数の引数が２つの場合

```
const hello = (name, age) => console.log('hello' + name + age);

hello('Shun', 20);
```

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

戻り値
---

```
const hello = (name, age) => 40;
console.log(hello());
```

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

これは

```
const hello = (name, age) => {
  return 40;
}

console.log(hello());
```

と同じ意味です

実用的な使い方
---
これを

```
const arry = [1,2,3,4,5,6];

arry.forEach(function(value) {
  console.log(value);
})
```

こうします

```
const arry = [1,2,3,4,5,6];
arry.forEach(value => console.log(value));
```

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

出力結果は同じですが、さっぱりしましたね
VSCode + PlatformIO で micro:bit + Zephyr RTOS 開発

# tl;dr

[VSCode](https://code.visualstudio.com/) + [PlatformIO](https://platformio.org/) というモダンな開発環境で [Zephyr RTOS](https://www.zephyrproject.org/)を使った [micro:bit](https://microbit.org/) の開発を試してみました。Linux 上での操作で説明します。
![mb_zephyr.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265397/638e4276-015e-9453-e696-b6eed2383f92.jpeg)

# いきさつ
VSCode + platformio が良いらしいということを聞いてひとつ試してみるかと思いました。手元にmicro:bitがあったのですが、framework が `Arduino`, `Mbed`, `Zephyr RTOS` の3択。Zephyr? なにそれ？ 聞いたことない、ということで、せっかくだから俺はこのZephyrを選ぶぜ、と思った次第です。

# VSCode
拡張機能にPlatformIOを追加すれば準備完了です。VSCodeじゃないところでPlatformIOを (aptやbrewなどで) 入れていると衝突するようなので注意しましょう。(ぼくは最初これでハマりました。)


# udev の設定 (Linux)

以下の2行を適当なファイル名で`/etc/udev/rules.d/`に入れておきます。

```text:/etc/udev/rules.d/50-myusb.rules
KERNEL=="ttyACM[0-9]*",MODE="0666"
ATTRS{product}=="*CMSIS-DAP*", MODE="660", GROUP="plugdev", TAG+="uaccess"
```

ファイルを作ったら`systemctl restart udev.service` あるいは再起動などして有効化してください。

# プロジェクトの作成

VSCodeの左に縦に並んでいるアイコンのPlatformIOを選択して、`QUICK ACCESS` > `PIO Home` > `Open` > `+ New Project` と進みます。
適当なプロジェクト名を入力し、Board を `BBC micro:bit`、Frameworkを`Zephyr RTOS` として Finish。これだけです。簡単！

# プロジェクトの設定

今回はデフォルトではビルドされない **Displayインタフェース** を使おうと思うので設定ファイルを一つ作ります。`PlatformIO` > `QUICK ACCESS` > `PIO Home` > `Open` > `Open Project` から今作ったプロジェクトを開きます。左にツリー表示が現れるので、`プロジェクト名` > `zephyr` を展開します。たぶん `CMakeLists.txt` だけがあると思いますが、それと同じ階層に `prj.conf` というファイルを新規作成します。内容は以下の通りです。

```text:prj.conf
CONFIG_DISPLAY=y
CONFIG_MICROBIT_DISPLAY=y
```

# main.c の編集

`src` に入っている `main.c` を開いて編集します。こんな感じでどうぞ。

```c:main.c
#include <zephyr.h>
#include <sys/printk.h>
#include <display/mb_display.h>

void main(void)
{
    struct mb_image patterns[] = {
        MB_IMAGE(
            {0, 0, 0, 0, 0},
            {1, 1, 0, 1, 1},
            {0, 0, 0, 0, 0},
            {1, 0, 0, 0, 1},
            {0, 1, 1, 1, 0},
        ),
    };
    struct mb_display *dpy = mb_display_get();
    mb_display_image(dpy, MB_DISPLAY_MODE_DEFAULT, SYS_FOREVER_MS, patterns, 1);
    while (1) {
        printk("hello, world %s\n", CONFIG_BOARD);
    }
}

```

# build & upload

VSCode 最下部にチェックマークがあると思います。これをクリックすればビルドできます。あるいは `PlatformIO` をクリックして現れる `PROJECT TASKS` の `Build` をクリックしても同じです。その際、最下部左側のアイコンの並びの最後の方にプロジェクト名が出ていますが、これが今作業したい対象のプロジェクトです。そうでない場合は、**ここをクリックすると選択できます**。
![vscodepiobottom.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265397/5a6934d0-ee0e-1930-0ec5-71e63f225bc4.png)この図だと右端の`Default (mbdemo)`の部分です。

なんかUIが非常に分かりづらいのですが、ぼくはVSCodeもpioもほぼ初めてなので何かもっと素直な方法があったら教えてください。

無事ビルドが終わったら micro:bit を差し込んでチェックマークの隣りの矢印（→）をクリックします。これで書き込み完了です！micro:bitに表示が現れます。(本記事の冒頭の写真)


# シリアル出力も確認
コードの最後の無限ループで`printk`しています。これはシリアルに吐いているはずなので確認してみましょう。Linux の場合はこんな感じです。上述の udev が効いていれば sudo 不要のはずです。

```shell-session:Linuxのシェル
$ stty -F /dev/ttyACM0 raw 115200
$ cat /dev/ttyACM0
```

# おわりに

これでいちおうPlatformIOの開発手順が把握できたし、Zephyr経験者になることもできました。RTOS要素ゼロですけど。
micro:bit はmbed OSのclassicな方しか対応していなかったと思うので、より本格的なRTOSが使いたい場合はZephyrが役に立つかも知れません。ぼくは…たぶんもう使うことはないだろうな。