OmniAICreator/Qiita-1.07M huggingface dataset:
ネストのストロングパラメーターを扱う

## はじめに
Railsで「1つのフォームから複数のモデルに対して更新する処理」を作っていた時に結構苦戦したので、今回メモとして残していこうと思います。
もし誰かの参考になりましたら、幸いです。

### 使用する環境
- MacOS（M1）
- Rails 6.1.4
- Ruby 2.6.3
- yarn 1.22.17
- Homebrew 3.5.0


## コードの解説
今回の実装のポイントとしては2つあります。
1つ目は
「ネストされて送られてくるパラメーターを、ストロングパラメータで上手く受け取ってあげる」ということです。

下記のようにViewから送られてくる場合

```
#<ActionController::Parameters {"_method"=>"patch", "user"=>{"name"=>"hoge", "email"=>"", "profile_attributes"=>{"gender"=>"man", "weight"=>"60.0", "id"=>"12"}}, "commit"=>"更新", "controller"=>"users/registrations", "action"=>"update"} permitted: false>
```

```users_controller.rb
  # ネストされてるパラメーターを許可する
  def profile_params
    params.permit(user: {profile_attributes: [:gender, :weight]})
  end
```

2つ目は
「ネストされて送られてきたパラメーターを作成・更新時に上手く取り出してあげる」ということです。

下記のような形に取り出して更新しないとエラーが出ます。
```
#<ActionController::Parameters {"gender"=>"woman", "weight"=>"89.0"} permitted: true>
```
エラー内容
```
ActiveRecord::AssociationTypeMismatch: expected, got Fixnum
```

修正後
```users_controller.rb
def update
    @current_user_profile = current_user.profile
    @current_user_profile.update!(profile_params[:user][:profile_attributes])# 上手くネストされたパラメーターからprofileの内容だけ取得する
end
```

参考:https://kyohei8.hatenablog.com/entry/2013/04/25/115002

## 最後に
ちょっと自分用のメモのため少し雑になって、上手く説明できなかったところもあるかもしれませんが、少しでもお役になったら幸いです
AWS初心者がDVA-C02に合格した話


このたび、AWS Certified Developer - associate（DVA-C02）試験に無事合格したので、その経緯について書いていきます。

SAA試験に比べて圧倒的に情報が少なかったので、これから受験する方々に参考になるものがあれば幸いです。

今まで取得したAWS資格はこちらです。
- [AWS実務未経験者が18日でSAA-C03に合格した話](https://qiita.com/ryuken/items/aafe762bb6e3e7d78088)

## AWS DVA-C02とは
AWS資格のうち、開発者向けアソシエイト資格の一つです。
![aws-certified.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272102/ae450733-66d7-d0b6-941a-5e94815362e8.png)
出典元：[AWS 認定](https://aws.amazon.com/jp/certification/)

## 受験を決めた経緯
一ヶ月前に合格したSAA-C03勉強で主にお世話になったのが[TechStock](https://techstock.jp/)、AWSおよびGCPの問題集サイトです。

TechStockは一度課金すると９０日間有効になります。１つ目の資格SAA-C03を3週間弱で取得できたので、購読期間がだいぶ余った状況になってしまいました。それで90日もあれば他の資格も取得しようと思い、デベロッパー資格のDVA-C02勉強を始めました。

## 勉強方法
SAA-C03の受験経験から、TechStockのみ解くことにしました。問題セットは#1~#58までありました。一度回答し次回からは間違った問題のみ復習するスタイルです。一見するとSAA-C03と同じですが、実は今回勉強スタイルを少し工夫することにしました。

参考にしたサイト
- [AWS認定デベロッパーアソシエイト（DVA）合格までにしたこと](https://qiita.com/tukky/items/23333573b2e55dc748fa)

上記サイトで取り上げられたこちらの動画が参考になりました。動画で紹介しているのは別の資格ですが、この動画で見てほしいのは勉強方法です。何の勉強でも共通して使える方法です。
- [AWS認定資格 SAA試験に落ちたくない人は必見！試験テクニックを無料で伝授します！【ソリューションアーキテクトアソシエイト試験】](https://www.youtube.com/watch?v=lJTh8n_q3Zw)(YouTube)

このYouTube動画を見て、「そういえば、こんな本あったなー」と思い、即Amazonでポチったのがこちらの本です。
- [大量に覚えて絶対忘れない「紙１枚」勉強法](https://www.amazon.co.jp/dp/4478114110)（Amazon）

結局本は頭を少し読んだだけなので、買わなくても良かったかもです・・・

## 勉強時間
毎朝のもくもく会がメインでした。この期間はプライベートで用事が多く、ほぼ朝の勉強だけでした。記録を振り返ったらなんだかんだ33時間勉強していました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272102/e5c3e8cc-cab2-df2a-a838-ff4cadfcaf72.png)

## 受験
地方在住であまり出かけないので、今回も旅行がてら会場で受けたかったです。しかし、希望の日に受験できる会場がなかなか近くで見つからなく、一番近い会場でも移動に数時間かかってしまうので、諦めて自宅でオンライン受験することにしました。

時間になって受験リンクにアクセスすると、まず環境テストが始まります。その後、自身の顔写真・身分証の写真・デスク周りの写真をスマホで撮影し送信します。するとチャットで試験監督から連絡が来て、その指示に従ってデスク周りをもう一度お見せしたら準備完了です。試験がロードされた後は、試験会場の試験と同じ試験が自身のPCで受けられます。

終わってみれば自宅受験は簡単ですが、デスク周りの写真撮影でかなり苦戦しました。AWS指定リンクでカメラが起動し、そのカメラで撮影することになりますが、画角が異常に狭く（望遠設定のまま変更できない不具合？？）デスク全体を撮影することができませんでした。最後は仕方なく諦めて適当に撮影してアップしたら、試験監督からデスク周りを見せることを求められたので、PCのWebカメラで見せてパスしました。

試験問題はSAA-C03同様、TechStockで解いたことのある問題が多かったです。またまた個人的な所感ですが、
- ほぼ同じ問題：6割
- 二択まで絞れて悩む問題：3割
- 初見の問題：1割
です。

時間がかかりそうな問題3問をスキップし、とりあえず62/65回答完了。その後じっくり時間をかけて残りの３問を解いて受験完了。それでも130分の受験時間のうち、40分ほど余ってしまいました。SAA-C03試験よりはだいぶ余裕でした。

受験完了後6時間ほど経過し、AWS認定サイトにアクセスしてみたら、合格していました。
![スクリーンショット 2023-05-13 21.27.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272102/4342fcea-1bd1-e5cd-846f-4917a4ad15c4.png)

「1000点満点中、720点以上で合格」のところ、789点で合格でした。

## 感想
受験後の感想は、SAA-C03試験より解きやすい感じがしました。時間もだいぶ余っていましたし。DVA-C02試験は、Associate試験の中で難易度が一番低いと言われていますし、僕自身普段開発をしているので、なんとなく雰囲気でも当てやすかったかもしれません。

実務経験も大事ですが、なぜか資格勉強を優先している自分がいました。参考にした動画でも話していましたが、実践力と資格は全く別物ですので、これからも資格勉強をちょこちょこと続けていきます。資格取得は一見無駄なように見えますが、少なからずAWSに関する基礎を覚えられるので、やはり勉強して損はないと思います。

## 勉強になった内容
やたらと登場頻度が高く、調べてみて良かった内容
- [アプリにユーザー認証機能を簡単に追加 !「Amazon Cognito」をグラレコで解説](https://aws.amazon.com/jp/builders-flash/202103/awsgeek-cognito/?awsf.filter-name=*all)
- [AWS Elastic Beanstalkで使えるデプロイポリシーを理解する](https://dev.classmethod.jp/articles/elastic-beanstalk-deploy-policy/)
ファシリテーションの大切さ

# 概要
DX案件など含めたあらゆる案件や
様々なイベントのファシリテーションをやってきた中で気付いた重要ポイントについて記述します。
要約すると【ファシリテーション】がプロジェクトの成否を決めるということ。

# 対象読者
・いつも会議が無駄な集会に終わって困っている人
・あちこち議論が飛び交っていて良いアイデアが出なくて困ってる人

# こんな経験ないでしょうか？
複数のステークホルダーが集まる貴重な場での収集つかない議論。
認識が合わない・何言ってんのかわからない。
抽象度が違う話でモヤモヤ。時には口論みたいにもなり、
そしてただただ時間だけが過ぎ去ってゆく、、、専門家とかが集まってもなりやすい現象。

ずっとそこに疑問を抱いており、先日その根源と解決法の糸口をつかんだのでここに記載します。

# ファシリテーションに問題あり
DXが進まないPJでの会議には以下の特徴を感じました。
・そのシステム化対象の背景などといった前提条件の確認の甘さ
・そもそものWF、スパイラル、アジャイルでの前提条件の取り扱いの認知の薄さ
・アイデア出しと収束の取り扱いミスによる空気の不穏さ
・なんとなく全員集まった会議
・ファシリテーションができる人材がいない


そこで以下の５つのアンチパターンにわけて解決法を記載していきます。

# アンチパターン①　とりあえず会議だよ、全員集合！
・0→1が得意だけど収束が苦手な、アイデア出しが得意な人
・実現可能性とか考えつつ収束が得意だけど0→1のアイデア出しが苦手な人
・そのPJの意義を分かってる人・分かってない人
・抽象な視点の話が苦手・または得意な人
こんな感じで様々な特性の人々を意味もなく集めても、
お互いの価値観の衝突を生み、モチベーションの低下につながります。
良く見かけませんか？なんかよくわからないけど、とりあえず定期集会みたいなの開いて進捗報告とか。
それでは【みんなで仲良く】会議を開くのが目的になってしまっています。
こんなんはハッキリ言って時間の無駄です。

## ①の解決法　必要な時に必要な人を集める
会議の目的や目標から逆算して、必要と思われるステークホルダーを呼ぶようにすることで、
その人たちの長所を発揮しやすくし、自信を取り戻すきっかけなどをつくりやすくすることで
モチベーションUPにつなげるわけです。

参加者の性格やこだわりなどから、その人材がこれからやろうとしてる議論の目的に沿った発言を得意とするのか？
それとも苦手とするのか？を見極めておく必要がある。
でないと以下のようなことになりやすいです。
・0→1のアイデア出しが苦手な人が大量に集まって、
アイデア出しのフェーズにおいて、従来の考え方や事例・成功パターンに縛られたものしか出てこない。
・拡散したアイデアを収束させるとこで0→1の人間が「そもそも～～？」と話を振り出しに戻して議論が進まない。
(これ昔よくやってた自覚あり)


# アンチパターン②　暗黙的前提条件
これ、意外と色んなとこでよく見かけるPJ最初の時点でのプロダクトオーナーからの
対象のビジネスやシステムに関する説明議会で見受けられる現象です。
なんかやたら長い説明で対象のシステムの詳細な機能の説明とかが始まるわけです。
「これにはこんな機能があって、これはこんなプロセスで～～～云々」
こういう時わたしは常に「？？？ポカーン」ってなってます。

本当に話すべき内容はそのシステムを通してどんな目的を達成したいのか？ということ。
誰に向けての価値を届けたくて考えるものなのか？ということ。

でもこれ本当にPJメンバーで足並みそろってないこと多く見かける気がします。
意外と皆さんよくやりがちな暗黙的な前提条件の確認不足。
今から話そうとしてる対象のスコープや6W2Hについての確認共有不足。

もちろん仮説検証を通して、スコープを変えたりすることはあれども考えるべき対象の背景や
そのシステムを通してどのようなステークホルダーに価値を届けたいのかもわからないことには、
仮置きのスコープすら決められない。
　→スコープが定義できないとこれから議論することの手段の妥当性も主観になってしまう。
　→「いや、それ違いますよね？」みたいに誰かに言われて
「いや、それあなたの感想ですよね？」と思ってしまい心理的安全性も下がってしまう。
## 解決法　前提条件を定義が明確になるまで具体化し共有
これについてはもうめんどくさがらずに必ず細かいスパンで足並みを揃えること。
必ず仮置きの前提条件でもいいから議論開始前に設定して、そのうえで会議終了時の目標まで込みで
参加者全員に共有して足並みをそろえておくこと。
でないと現在の位置もあやふや、ゴール地点もあやふやだから皆が共通認識を持てていないことになります。
議論開始時点で足並みがそろってないことは大問題以外の何物でもありません。

この状態で「君の言ってる手段は妥当じゃないよ」みたいなこと言われても、
「は？それの根拠は？」って感じてしまうので空気感も悪くなるっていうメカニズムです。

# この時点でのまとめ
さて以上の2つで主に会議が始まる前段階でやっておかないといけない事項をアンチパターンを通して解説しました。
サクッとまとめると、

①必要なステークホルダーを必要なタイミングに集まってもらうことでその人たちの長所を生かしやすくする。
②前提条件、いまの現在地・会議後の目標地点をあらかじめ認識がずれないくらいまで具体化し共有する。

この２つは以降の３つにも繋がっていく大事なものなので、しっかりとモノにしてみてください。
次回は、会議中の発散フェーズにおいて＆収束してまとめるフェーズにおいての事項を解説します。
ChatGPT Plusのブラウジング（Browsing）モードを有効にする方法

一部のユーザーのみに開放されていたブラウジングモードが多くのユーザー向けに開放されたそうです。


ブラウジングモードを利用することで、以下の2つのことが可能となります。
1. 最新情報を取得してくれる
1. Web上の事実ベースに結果を出してくれる

開放されている人は以下の方法で設定できます。なお、現時点では有料のChatGPT Plusユーザーのみ利用な機能となっております。

## ベータ機能の設定方法

1. 左下のユーザー名をクリックして「Settings」を選択
![browsing.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61189/45d608d0-d00c-6eb4-ba19-adf5010905a5.png)

2. ポップアップの「Beta features」の **Web browsing** をチェック
![browsing02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61189/9c9e5a6b-46e9-20bc-e21e-477b5b6b1a22.png)

3. モデル選択時に **Browsing** を選択
![browsing03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61189/6c4911ef-e939-3a9a-d016-763bed0ac1b7.png)


## Browsingモードでできること

「Browsing」モードでは、インターネットの検索やウェブサイトの閲覧を行うことができます。具体的な機能としては次のようなものがあります：

- **search(query: str, recency_days: int)**：
指定したクエリで検索エンジンを使用して検索します。recency_daysパラメータを指定することで、特定の期間内の情報に限定した検索を行うことも可能です。
- **click(id: str)**：
表示された検索結果の中から特定のIDを選択し、そのウェブページを開きます。IDはウェブページのURLに対応しています。
- **quote(start: str, end: str)**：
開いているウェブページから特定のテキスト範囲を選択し、それを記録します。テキスト範囲は、開始する部分の文字列（start）と終了する部分の文字列（end）で指定します。
- **back()**：
前のページに戻り、それを表示します。
- **scroll(amt: int)**：
開いているウェブページを指定した量だけ上下にスクロールします。
- **open_url(url: str)**：
指定したURLを開きます。

これらの機能を使うことで、最新の情報を取得したり、特定の情報を詳しく調べたりすることが可能になります。そして、その情報を参照して回答を提供します。

## 使ってみた

実行するとChatGPTが情報を検索して、その結果から必要な情報を取り出してくれました。**quote** の部分を見ていただくとわかりますが、参考として各記事のURLへのリンクが表示されています。

![browsing04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61189/40a47e6b-dd93-b867-c5d0-5e5b91faac0d.png)

さらにこの結果に対して質問をすることも出来ます。今回は **AI advancements** について調べてもらったので、更に質問してみました。

<blockquote>AI advancementsについての引用してくれた記事の内容でビジネスマンとして抑えるべきポイントを3つ教えて。</blockquote>

長いので抜粋しますが以下のような事を教えてくれました。

1. **AIの能力と限界の理解**：
AIは多くの分野で人間を超える能力を持つ一方で、まだ限定的なタスクに特化しています。 
1. **AIの倫理的な問題と規制**：
AIの進化は驚異的なスピードで進んでおり、その結果、倫理的な問題や規制のニーズが高まっています。
1. **AIの革新的な応用例の理解**：
AIは様々な分野で新たな可能性を開いています。


この機能の素晴らしい点は、最新情報を取得し、Web上のデータから生成されるため信頼性が高いことが挙げられます。また、ITに関連するものとして、わずかな時間で20近くの英語記事をまとめてくれ、それに対して質問したりできることに感じました。

## 今後の展開

公式Twitterから以下のようにアナウンスがありました。近日中に他のプラグインも使えるとのことで楽しみです！

<blockquote>
来週中に、すべての ChatGPT Plus ユーザーに Web ブラウジングとプラグインを展開します。アルファからベータに移行すると、ChatGPT がインターネットにアクセスし、70 以上のサードパーティ プラグインを使用できるようになります。</blockquote>

https://twitter.com/openai/status/1657128759659745280
【AndroidStudio】AndroidStudioをXcodeに近い見た目にする

# はじめに
最近、Flutterを勉強し始めました。
AndroidStudioを使っているのですが、
iOS開発者としては慣れているXcodeのようなテーマカラーにしたいです。

やりかたを記録しておきます。

# テーマのダウンロード
https://github.com/johncodeos-blog/XcodeKotlinColorScheme

![スクリーンショット 2023-05-13 21.13.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/32e8f65b-eb5f-7ed4-5adb-d5bcaa7f2fe3.png)

# テーマの設定
① 「AndroidStudio」を選択します
② 「Settings...」を選択します
![スクリーンショット 2023-05-13 21.14.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/9664cab5-5de2-6ae6-9cf1-59ae5b78d5f7.png)

③ 「Color Scheme」を選択します
④ 歯車マークを選択します
⑤ 「Import Scheme」を選択します
![スクリーンショット 2023-05-13 21.18.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/27ad9fee-15f8-6aef-99fb-a650899ddfdf.png)

⑦ ダウンロードしたテーマを選択します
⑧ 「Open」を選択します
![スクリーンショット 2023-05-13 21.20.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/ca19fc26-bcb6-de76-9d9c-78a9c2c635ec.png)

⑨ 「Apply」を選択します
![スクリーンショット 2023-05-13 21.22.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/e771dacf-2124-bb02-8dd0-02fe38130c47.png)

完成！！

# おわり
いい感じになりました

# 参考記事
https://johncodeos.com/how-to-make-android-studios-editor-looks-like-xcode/
コンピュータの5大装置について

## コンピュータの5大装置
コンピュータのハードウェアを構成する主要な装置を5つに分類したもののこと。
制御装置、演算装置、記憶装置、入力装置、出力装置の5つに分類される。
>「コンピュータっていうのはね。この5つの装置が組み合わさって、できているんだよ」な「入力装置」「出力装置」「記憶装置」「演算装置」「制御装置」のこと
https://wa3.i-3-i.info/word19239.html

## CPU（中央演算処理装置）
パソコンの脳みそにあたる部品。
CPUは、コンピューターの5大装置の制御装置と演算装置にあたる。

## GPU
3Dグラフィックスなどの画像処理のための行列演算を行うプロセッサ。
AIのディープラーニングの演算にも使われたりもしている。

### CPUとGPUの違い
>CPUの目的は汎用的な処理を行うこと、GPUの目的は高速な画像処理を行うことです
https://www.ntt.com/business/sdpf/knowledge/archive_05.html#anc02


### 行列
>行列：
数を長方形や正方形の形になるように並べたもの。
表の数部分だけを抜き出して縦横に並べ、括弧でくくったものが行列です。
https://lab-brains.as-1.co.jp/enjoy-learn/2022/11/37648/
https://oguemon.com/study/linear-algebra/matrix-op/

### プロセッサ
>プロセッサは、処理装置の総称であり、コンピュータの中で機械語の命令語を実行しているハードウェアです。パソコンの中のプロセッサとしては、CPUがプロセッサにあたる部品です。そのため、一般的にはプロセッサという言葉はCPUをさす言葉です。
https://gimo.jp/glossary/details/processor.html


## MIPS
コンピュータに対して1秒間に処理できる命令の数を表す。
>MIPSとは、コンピュータの処理速度をあらわす単位の一つで、毎秒何百万回の命令を実行できるかを表す値。1MIPSのコンピュータは、1秒間に100万回の命令を処理できる。主にマイクロプロセッサの性能を反映するため、プロセッサの性能指標として扱われることもある。
https://e-words.jp/w/MIPS.html

### MIPSの求め方
>MIPSの公式
>1 ÷ 平均命令実行時間（秒） × CPUの使用率
>https://medium-company.com/mips/#MIPS

例：
平均命令実行時間が20ナノ秒のコンピュータがある。このコンピュータの性能は何MIPSか。

1 ÷ (20^-9) × 1 = 50,000,000[回]
　→問題文にCPU使用率の記載がない場合は、100%として計算するとのこと。

MIPSは百万単位の命令回数なので、上記回数を百万で割る。
50,000,000 ÷ 1,000,000 = 50
答えは50MIPSとなる。

　→20ナノ秒 = 20 ÷ 1,000,000,000秒 (1秒あたりのナノ秒の数)
　　→ 0.00000002秒
cartographerの3d backpack demoをROS 2で実行する

# 動作確認環境

OS : ubuntu22.04LTS
ROS : ROS2 Humble


# cartographerのインストール

```bash
sudo apt install ros-humble-cartographer 
```


# rosbagファイルのダウンロード

 適当な場所に　3D backpack demo　をダウンロード

```bash
wget -P ~/Downloads https://storage.googleapis.com/cartographer-public-data/bags/backpack_3d/with_intensities/b3-2016-04-05-14-14-00.bag
```


# ROSのrosbagデータをROS2 のrosbagに変換

https://qiita.com/porizou1/items/a8004ed1f238ea0242d9

こちらを参照してROS2で使えるrosbagに変換

```bash
rosbags-convert b3-2016-04-05-14-14-00.bag 
```



rosbagと同じ名前のディレクトリができる

```bash
.
├── b3-2016-04-05-14-14-00
│   ├── b3-2016-04-05-14-14-00.db3
│   └── metadata.yaml
├── b3-2016-04-05-14-14-00.bag
```


# 実行

bag_filenameにrosbagがあるディレクトリを指定

```bash
 ros2 launch  cartographer_ros demo_backpack_3d.launch.py  bag_filename:=${HOME}/Downloads/b3-2016-04-05-14-14-00
```







https://twitter.com/porizou1/status/1655074651389964289?s=20







# 参考


https://google-cartographer-ros.readthedocs.io/en/latest/demos.html
初めてのhtml　勉強まとめ　

## そもそもHTMLとは
Hyper Text Markup Languageの略で人間が見てわかるように表示しつつ、コンピューターに指示することができる言語。ちなみにHTMLは物理学者のティムバーナーズリーさんが物理学の研究成果などを共有する際に毎回ドキュメントをコピーしたりするのが面倒で、何か便利なものができないかということで開発したそうです。
ちなみにHTMLのなにが画期的かというと文書間の参照を行えることです。
Ａ文書はＢという文書を参照しているということをコンピューターに理解させることができる、これをハイパーリンクと呼んでいます。

## HTMLファイルの骨組み

```<!doctype html>```
ページがどのバージョンのHTMLで、どの仕様に合わせて作られているかを書いている。
HTMLのバージョンにはHTML4.0やXHTML 1.1などがありますが、2023年時点で主流なのはHTML5というバージョンになります。
とくにバージョンの指定がない場合は、HTML5を指します。


```<html lang="ja">```
このファイルがhtmlの文書だということを明示しています。lang=""で言語指定ができ、jaは日本語の文書ということを明示しています。

```<head></head>```
ページのタイトルや説明文、使用する外部ファイルのリンクなど、ページ情報を記述しています。
ブラウザには表示されません。

```<meta charset="UTF-8">```
文字コードをUTF-8にするという指定です。この指定がないと文字化けする可能性があります。
必ず記述する必要があります。

```<title></title>```
ページのタイトルを記述します。この名前がブラウザのタブやユーザーがＷＥＢサイトをブクマしたり、検索したときのページタイトルとし表示されます。

```<meta name="description" content="~">```
ページの説明文を記載します。検索エンジンでページタイトルとともに表示される部分です。
ユーザーが検索したときにどんなサイトなのかを瞬時に判断できるよう、必要なキーワードを含めて記述するとページを開いてもらいやすくなる

```<body></body>```
HTML文書の本体。ここにコンテンツを入力することで、実際にブラウザ上で表示することができる。


## まとめ
1.HTMLはハイパーリンク機能が画期的だった
2.htmlにはいくつか最初に記載しないと文字化けしたり、思いもよらないエラーが出る。
3.headはページには表示されず、bodyに記載しているものがページに表示される。

:::note 
次回はhtmlの簡単な実例をもとに基本の書き方を身に着ける
:::


※参考文献
・プロになるためのWeb技術入門
・1冊ですべて身につくHTML＆CSSとWEBデザイン　入門講座
Laravel 8系 barryvdh/laravel-debugbar のインストールエラー 解決

# 環境
PHP: 8.0.28
Laravel: 8.83.27
PC: M1 mac

# 起こったこと
Laravelのプロジェクトにデバックバーのライブラリをrequireを使って導入しようと、下記のコマンドを実行した。

```
composer require barryvdh/laravel-debugbar                                                                                                                        
```
しかし、下記のエラーが吐かれた。

```
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - barryvdh/laravel-debugbar[dev-master, v3.8.0, ..., v3.8.1] require illuminate/routing ^9|^10 -> found illuminate/routing[v9.0.0-beta.1, ..., 9.x-dev, v10.0.0, ..., 10.x-dev] but these were not loaded, likely because it conflicts with another require.
    - barryvdh/laravel-debugbar 3.8.x-dev is an alias of barryvdh/laravel-debugbar dev-master and thus requires it to be installed too.
    - Root composer.json requires barryvdh/laravel-debugbar ^3.8 -> satisfiable by barryvdh/laravel-debugbar[v3.8.0, v3.8.1, 3.8.x-dev (alias of dev-master)].


Installation failed, reverting ./composer.json and ./composer.lock to their original content.
```

# 解決策
私の環境では、composer.jsonのrequire-devに下記を加え、composer updateをすることで解決ができた。

```
"barryvdh/laravel-debugbar": "^3.6"
```
様々な記事を見たが、明確な原因はわからなかった。
ただ、おそらくLaravelのv8系とbarryvdh/laravel-debugbarのv3.8系があまり相性が良くないのではないかと思う。
私の環境では、v3.7.0でbarryvdh/laravel-debugbarがインストールがされた。

# 参考記事
下記のスレッドの内容を参考にしました。
もし私の方法で解決できない方がいらっしゃいましたら、他にも下記のスレッドで解決策を紹介しているみたいなので、ぜひ見てみてください。

https://github.com/barryvdh/laravel-debugbar/issues/1236
【学習】Ruby on Rails チュートリアル 第7版 - 第4章Rails風味のRuby

5/13 19:45 開始

・カスタムヘルパー：新しく作ったメソッド
↓で定義する
app/helpers/application_helper.rb

・rubyの文法

4.2.1 まで終了

5/13 20:20 終了

5/14 10:00 開始

・rubyの文法

4.3.2まで終了

5.14 11:00 終了


5/14 13:30 開始

・rubyの文法
*inspectメソッド
オブジェクトを表現する文字列を返す。
(例)
>> puts (1..5).to_a.inspect
[1, 2, 3, 4, 5]
>> puts :name.inspect
:name
>> puts "It worked!".inspect
"It worked!"

上記のショートカット「p」が用意されている
>> puts :name.inspect
>> p :name
:name

*メソッドの呼び出し
Rubyではメソッド呼び出しの丸カッコは省略してもok

stylesheet_link_tag("application", "data-turbo-track": "reload")
⇅同じ
stylesheet_link_tag "application", "data-turbo-track": "reload"

4章 終了!

5/14 15:00 終了
AIで作成した文章

　今流行りのGPT-3を使って、wikipediaの文章を学習させて文章生成してみた文章が史実を捏造しまくりで面白かったので、掲載します。モーツァルトについての文章です。
　https://axross-recipe.com/recipes/135
　こちらの記事を参考に、wikipediaのモーツァルトの記事の冒頭を抽出して入力しました。
　以下生成された文章です。

```
モーツァルトは、家族の影響を受けなかったが、自身の名声を高めるために多くのコンサートで演奏した。

父親は楽器製作人であり、母親は才媛であった。

モーツァルトの作品は、楽器によって様々な演奏ができるように書かれている。

オペラは音楽劇であるが、モーツァルトはオペラ・ハウスで演奏することを嫌ったため、最初に書かれたオペラは、楽器による演奏ができるように書かれていた。

モーツァルトは、1782年に最初の妻として古典派の女流作曲家、カンツォーナ・アマデウス・パーラ（音楽家）を結婚させた。

彼女は、その後、夫のモーツァルトは2人目の妻として、ボルガ・フィルハーモニーのコンサートマスターとして働くようになったため、結婚できなかった。

モーツァルトとパーラはコンサートや演奏会を行うためにブダペストからウィーンに移り住んだ。

モーツァルトは、彼の父親と共に、1780年にウィーンに赴任している間に妻を失った。

彼は、次の結婚して、二人目の妻として、ボルガ・フィルハーモニーのコンサートマスターをしていたロシア人女性、ロザリーナ・ボロディノワ（音楽家）を結婚させた。

この妻との婚姻生活は、3人の子どもをもうけたが、長期間にわたる苦しい時期となった。

1787年に、モーツァルトは、家族を探してウィーンへ帰った。

そこで、3年間暮らしたが、そのうち最初の1年間で、彼は、「オペラ・ファウスト」を完成させた。

モーツァルトとロザリーナの仲は、数年間、崩壊したが、彼は、1791年にロザリーナを見つけ、彼女と再婚した。

モーツァルトが、ウィーンの医師のとの再会の場にいた時に、彼は、悪性の腫瘍を持っていたことに気づいた。

この日から、彼は、その腫瘍に対抗していた。

モーツァルトは、1791年12月5日に、享年35歳で死んだ。

彼は、ウィーン藩王であったブルーノ・ハインツ・アンドレーエフに殺害された。

モーツァルトは、英語のスラングで、「Original Genius」と呼ばれる。

兵士たちが、戦争中、彼のオペラを演奏することにより平和を促進したことで知られている。

モーツァルトは、ドイツ語の通例のないエピソードを多数持っている。

モーツァルトは、彼のシューベルトに対する好き嫌いについて、シューベルトを「バカヤロウ」「臆病者」「じじい」などと罵倒している。

「Cosi fan tutte」は、その当時の人々には、バカヤロウを意味する「Così fanno tutte」と書かれていたという。

「Così fan tutte」という誤訳のために、この作品は「恋する戯れ」として知られている。

「Così fan tutte」は、実際のことを書いた曲ではない。

この曲は、モーツァルトが、いわゆる「モーツアルト職人論」で、ヴィヴァルディとハイドンを取り上げている。

この曲は、「ドン・ジョヴァンニ」と同

```

　モーツァルトが何回結婚したかよく分かりませんね(笑)
　殺害されたというのも、映画アマデウスの影響でしょうか。
　シューベルトとモーツァルトは面識ないはずなんだけどな～。
　モーツァルトとベートーヴェン、ベートーヴェンとシューベルトは会った事あるので、惜しいですね。

　という感じの今回はネタ記事でした。
MySQLのトランザクション制御

[MySQL徹底入門](https://amzn.asia/d/9y73cW2 "MySQL徹底入門")で紹介されているトランザクション制御についてメモ。

START TRANSACTION 〜 COMMIT or ROLLBACKは基本的なので割愛し、その他の内容について紹介。

## 暗黙のトランザクション制御
トランザクションの実行中に電源が落ちるなどでサーバーが停止してしまった場合、**次回起動時に自動的にROLLBACLされる**。

```sql
START TRANSACTION;
-- いくつか実行して途中で落ちた。
-- 次回起動時に自動で↓
ROLLBACK; 
```

## SAVEPOINT
文字通りだが、ゲームのようにSAVEPOINTを置くことが可能で、ROLLBACK時にどこまで戻すかを指定可能。
```sql
START TRANSACTION;

SAVEPOINT save1;
-- 処理
SAVEPOINT save2;
-- 処理
-- ここで失敗
ROLLBACK TO save2;
-- 処理
COMMIT;
```

## オートコミットモード
MySQLのデフォルトの動作として、クエリ実行すると即コミットされる（オートコミットモード）が、それを解除することも可能
```sql
SET AUTOCOMMIT=0; -- 0でオートコミット解除
SET AUTOCOMMIT=1;　　-- １で戻せる
```
【DisplayLink・複数ディスプレイ】Macbook Pro（2022 M2）でトリプルディスプレイを（LG32型）

こんにちは。ネットワークエンジニアの「だいまる」です。
今回は、デュアルまでしか使えないMacbookpro m2（2022）でトリプルディスプレイ環境を構築してみたので、その紹介をさせていただきます。

・https://daimaru-tech-blog.com/?p=768
【学習】Ruby on Rails チュートリアル 第7版 - 第3章ほぼ静的なページの作成

5/13 16:00 開始

・RenderでPostgreSQLを作成する

・railsコマンドで誤りがあり、戻りたい時・・・
 →rails destroyというコマンドを実行することで元に戻せる!
  ※generate ↔︎ destroy

 *コントローラの自動生成を元に戻す
  rails destroy controller StaticPages home help
 
 *モデルの自動生成を元に戻す
 rails destroy model User

 *マイグレーションの変更を元に戻す
 ※元に戻したいときは、db:rollbackで1つ前の状態に戻す。
　　rails db:rollback
　　※最初の状態に戻したいときは、VERSION=0オプションを使う
  rails db:migrate VERSION=0

・routeファイルの役割
 get "static_pages/home"の場合・・・
 get：GETリクエストを受け取ったときに対応するアクションを結びつけており、Web上のデータを読み取る（get）ときに使われる。

・テスト
テスト駆動開発（TDD:①「正しいコードがないと失敗するテスト」を書く = RED②本編のコードを書いてそのテストがパスするようにする = GREEN）

*テストファイル
 コントローラ作成(rails generate controller実行)時に
 test/controllers/[コントローラ名]test.rbにテストファイルが生成される。
 ↑にテスト内容を記述し、↓でテストを実行する。
 rails test


3.3まで終了

5/13 17:30 終了

5/13 18:10 開始

・テストファイル
　assert_selectメソッド※「セレクタ」と呼ばれることもある
　→特定のHTMLタグが存在するかどうかをテスト

・「DRY」（Don’t Repeat Yourself: 繰り返すべからず）という原則
 コードの繰り返し（重複）を追放しようという思想がある。
　　→コードをDRYにする為に、以下を実行する。
  ・HTMLビューのファイルの拡張子であるERB(Rubyの埋め込みコード)を用いる。
  ・アプリケーションのページの共通部分をテンプレートに置く。

第3章まで終了

5/13 19:30
Laravel , PHP コードレビューガイドラインの作成

# コードレビュー

Laravel / PHP での開発を想定しています。


## コードレビュー前の心構え

### 1. 開放性と受け入れの意識

- レビューは改善と学習の機会であり、批判ではないという意識を持つ。

### 2. 尊重とプロフェッショナリズム

- レビューは尊重の精神で行う。批判はコードに対するもので、人間や能力に対するものではない。

### 3. 明確なコミュニケーション

- レビューのフィードバックは明確で具体的であるべき。好意的なトーンと言葉を用いる。

### 4. タイムマネジメント

- レビューに適切な時間を割く。長時間連続してレビューを行うと、集中力が低下する可能性があるので、適度な休憩を取る。

## コードレビュー時のガイドライン

### 1. コーディング規約

- Laravel の公式コーディング規約を遵守します。
- 命名規則、インデント、スペース、改行、コメントのスタイルなどを統一します。

### 2. コードの品質

- コードは簡潔で、明確で、再利用可能でなければなりません。
- 不必要なコードや重複コードは避けます。

### 3. テスト

- すべての新規コードには適切な単体テストが伴います。

### 4. ドキュメンテーション

- コードには適切なコメントが含まれているべきです。

### 5. パフォーマンス

- コードは効率的に動作するようにします。

### 6. セキュリティ

- Laravel のセキュリティベストプラクティスを遵守します。

### 7. プルリクエスト(PR)の作成

- PR は一つのタスクやバグ修正に対応するようにします。
- PR の説明には変更の目的と詳細を記述します。

### 8. 静的コード解析ツールの利用

- PHPStan や Psalm などの静的コード解析ツールを利用します。

### 9. フィードバックの提供

- レビュワーはコードの問題点を明確に指摘し、可能であれば改善策を提案します。

### 10. 継続的な学習

- チーム全員が最新の PHP と Laravel の機能、ベストプラクティス、セキュリティ更新について継続的に学習します。

## コードレビューの手順
### 1. 準備
- レビューが必要なプルリクエスト(PR)の目的と内容を理解するため、PRの説明を読む。
- 関連するタスクやバグ報告を確認する。

### 2. 全体の理解
- PR全体を一通り読み、大枠の理解をする。

### 3. 詳細なレビュー
- コーディング規約、コードの品質、テスト、ドキュメンテーション、パフォーマンス、セキュリティに注意を払う。
- PRの変更が要件を満たしているか確認する。

### 4. フィードバックの提供
- 問題点を見つけたら、具体的で明確なフィードバックを提供する。
- 可能であれば、改善のための提案も行う。

### 5. 再レビュー
- フィードバックに対する修正が完了したら、再度レビューを行う。
- 修正が適切に行われ、問題が解決されていることを確認する。

### 6. 承認
- 全ての問題が解決されたら、PRを承認する。
- 必要であれば、最終的なコメントやフィードバックを提供する。
lazeの作法

# 概要
lazeを見つけたので、やってみた。

# 参考にしたページ。

https://qiita.com/coder6583/items/9adc2a7d5b55207c4b74

# hello world

```
print("hello world!");

```

# fizzbuzz

```
function: main() => () {
	int: i = 0;
	repeat (100)
	{
		i++;
		if (i % 15 == 0)
		{
			print("FizzBuzz");
		}
		else if (i % 5 == 0)
		{
			print("Buzz");
		}
		else if (i % 3 == 0)
		{
			print("Fizz");
		}
		else
			print(i);
	}
}
```

# zundoko

```
function: main() => () {
	int: i = 0;
	repeat(100)
	{
		if (rand() < 0.5)
		{
			i++;
			print("zun");
		}
		else
		{
			i = 0;
			print("doko");
		}
		if (i > 3)
		{
			print("doko");
			print("kiyosi!");
			break;
		}
	}
}
```

# 九九

```
function: main() => () {
	(int: i = 1;) from (i == 10) to (i++;)
	{
		string: str = "";
		(int: j = 1;) from (j == 10) to (j++;)
		{
			str += i * j;
			str += " ";
		}
		print(str);
	}
}
```


以上。
【RubyKaigi2023】 初耳だったruby.wasmを簡単に触ってみる

# はじめに
RubyKaigi2023が2023年5月11日から13日の3日間で開催されていることを最終日に知ったため、午後以降のセッションにオンラインで参加しました。
参加した「Load gem from browser」というセッションでruby.wasmという言葉が初耳で気になったので、少し調べてみました！

# ruby.wasmって何？
セッション中では、「ruby.wasmはrubyスクリプトをブラウザ上で動かすことができる技術」とお話しされていました。
ruby.wasmについては、[ruby.wasmについて](https://qiita.com/getty104/items/67245fb24ad101a6ec97)　でも説明されています。

# ruby.wasmを触ってみる

[https://github.com/ruby/ruby.wasm](https://github.com/ruby/ruby.wasm)を参考に↓のRubyコードが記載されたHTMLコードを作成し、ブラウザ上（chrome）で実行

```html:index.html
<html>
  <script src="https://cdn.jsdelivr.net/npm/ruby-3_2-wasm-wasi@1.0.1/dist/browser.script.iife.js"></script>
  <script type="text/ruby">
    puts "Hello, world!"
    a = [1,2,3]
    b = [4,5,6]
    a.concat(b)
    puts a[0..1]
  </script>
</html>
```

ブラウザ画面上には表示されていませんが、ブラウザの開発者ツールで確認するとコンソールにHello, world!と配列の値が表示されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3382528/f79fad60-be82-7fd6-1cf8-cc06ed0d3f26.png)

# おわりに
これまでブラウザ上ではjavasciptが実行されることは頭の中にありましたが、実際にruby.wasmを触ってみてRubyコードが実行されていたので非常に新しい発見でした。
また、[Rubyの資格](https://www.ruby.or.jp/ja/certification/examination/version3.html)の勉強において、ruby.wasmを使用することにより開発環境を準備することなく気になったコードを叩いてメソッドの動きや実行結果を確認することができるようになっていいなと個人的に感じました。
今後、ruby.wasmを駆使してできることが増えいくと思いますので、自分も少しずつ触っていければと思います。

# おまけ
今回参加したセッションは英語と日本語が使用されていて、英語に慣れるとさらにキャッチできる情報が増えるなと思い、英語ドキュメントもしっかり読んで力をつけていきたいと思いました。（そもそも日本語だったとしても自分のスキル不足で理解できない部分も多々ありましたが泣）
また、今回RubyKaigiに初めて参加して、Rubyに関する様々な情報をキャッチできる非常に有意義な場だと感じました！今回は最終日の午後のみの参加でしたが、次回開催される際は可能であれば初日から参加したいと思いました！

# 参考文献

https://qiita.com/getty104/items/67245fb24ad101a6ec97

https://github.com/ruby/ruby.wasm

https://www.ruby.or.jp/ja/certification/examination/version3.html
Event Busを作ってみよう version#1

# 見た目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3125845/b2c7d0b8-ef3f-1b41-c3f4-ff8e85da77ad.png)

# URL
GitHub: branch at "release/23-05-13"

https://github.com/shiganai/event_bus/tree/release/23-05-13

# 元々の構想

https://qiita.com/shiganai/items/76996ffdc4439103d6a4

# やっていること

```call_apps.py dummpy_trigger```
1. new_event_dirにイベント情報を個別のファイルとして追加

```event_loop.py```
1. 初期化として、apps/内にある各アプリのトリガー情報を"registered_event/"内に1つのテキストファイルとして書き出し
1. ループスタート
    1. "registerd_event/"内の最も新しいファイルを読み込んで、アプリを起動するキーワードを取得。
ここで取得することで、外部からトリガー情報を更新できる-->event_loopを止めなくても新しいアプリを追加できる。
    1. "new_event_dir"内にあるイベント情報を順番にロード。
        1. イベント情報に含まれているキーワードを読み込む。
        1. キーワードに一致するアプリにイベント情報を丸投げ。処理方法は各アプリに任せる。
        1. ここまでで処理し終わったので、このイベント情報が入ったログファイルを"old_event_dir/"に移動。これで次の時には読み込まれない。
    1. 2.1.に戻る

# この時点での構想

## アルゴリズムイメージ
event_loop.pyのイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3125845/305df116-ecdc-a345-741f-0eb8a3fc108e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3125845/99828d09-3e7c-1510-0808-26a69309f0c0.png)


## ディレクトリ構造

```
event_bus/
|
|- event_loop.py
|- call_apps.py
|- <some other config>
|
|- apps/
    |- dummy_trigger.py
    |- print_event.py
    |- <other apps coming soon>
|
|- new_event_dir/
    |- 2023_05_14_10_21_19_704567_526212028_dummy_trigger.txt (サンプル)
    |- <other apps event coming soon>
|
|- old_event_dir/
    |- 2023_05_13_17_46_05_903853_210209713_dummy_trigger.txt (サンプル)
    |- 2023_05_13_17_46_06_616911_073043986_dummy_trigger.txt (サンプル)
    |- <other apps event coming soon>
|
|- registered_event/
    |- 2023_05_13_18_19_37_203768_158712787.csv (サンプル)
    |- 2023_05_13_18_22_37_302726_415965892.csv (サンプル)
    |- ...
|
|- src/
    |- get_random_int.py
    |- get_absolute_path.py
    |- <other common modules>
|
```

## イベントファイルやトリガー情報ファイルの中身
イベントファイルの例: 2023_05_14_10_21_19_704567_526212028_dummy_trigger.txt
```
1684027279.704568
59944308
dummy
None
```
つまり、
* timestamp: 1684027279.704568
* random int: 59944308
* category: dummy
* path_to_data: None


トリガー情報ファイルの例: 2023_05_13_18_22_37_302726_415965892.csv
```
dummy_trigger,None
print_event,dummy
```
つまり、
* dummy_trigger.pyは"None"というcategoryを持ったイベントが発生したときに呼び出す(Noneというcategoryは禁止ワードにするつもり)
* print_eventは"dummy"というcategoryを持ったイベント(dummy_triggerがそのようなイベントを発生させる)が発生したときに呼び出される


# TODO
* event_loop内のメイン処理の、どのタイミングでイベントが追加される/トリガー情報ファイルが更新されるが起きると不具合が起きそうか整理
    * トリガー情報ファイルを読み込んだ後に、トリガー情報ファイルの更新とそれを前提にしたイベントが追加されると、そのイベントに対する処理は以前のトリガー情報ファイルに従うから、新しく作ったトリガー情報ファイルは適用されなくて、意図しない動作になる可能性がある
* 複数のcategoryの登録を可能に
    * イベントファイルもトリガー情報ファイル(csvファイル)も
    * もっと発展すれば、categoryの組み合わせによる条件付けもしたい
        * この2つのcategoryを同時に持たないと起動しない
        * あるcategoryがあっても、他に抑制するcategoryがあったら起動しない
        * etc.
* 各appを非同期処理に
    * イベント情報を引数にして渡して、app側でpath_to_dataをどう処理するかとか決めて、勝手にバックグラウンド処理するイメージ
    * 終了イベントを投げるかとかはapp次第
* subscribe/unsubsribeの実装
    * トリガー情報ファイルの更新をapp側などから呼び出せるようにする
ssh/configの書き方

ssh/config の書き方メモ。
```bat
C:\Users\user\.ssh\config

Host [SVName] # ここは自分の覚えやすい様に設定する
    HostName        [踏み台サーバーアドレス]
    port            [踏み台サーバーのsshdポート番号(任意)]
    IdentityFile    "[踏み台サーバーの秘密鍵パス]"
    User            [踏み台ユーザー名]

Host server.host # ここも自分の覚えやすい様に設定する
    HostName        [最終目的サーバーのアドレス]
    port            [最終目的サーバーのsshdポート番号(任意)]
    IdentityFile    "[最終目的サーバーの秘密鍵パス]"
    User            [最終目的サーバーのユーザー名]
    ProxyJump       [SVName]  #自分で設定した踏み台サーバーのHost名
```

example.
```bat
C:\Users\user\.ssh\config

Host proxysv
    HostName        192.168.0.1
    port            22
    IdentityFile    "C:\Users\user\.ssh\id_ed25519"
    User            root

Host server.host # ここも自分の覚えやすい様に設定する
    HostName        192.168.0.2
    port            22
    IdentityFile    "C:\Users\user\.ssh\id_ed25519"
    User            root
    ProxyJump       proxysv
```
入力された月の数、本日から遡り、さらにその月の初日から本日までの日数を出力するメソッド

```swift
///入力された月の数、本日から遡り、さらにその月の初日から本日までの日数を出力する。
func calculateDaysInPreviousMonths(months: Int) {
    let calendar = Calendar.current
    let today = Date()
    
    // 去年の今日の日付を取得
    let todayInLastYear = calendar.date(byAdding: .year, value: -1, to: today)!
    
    //去年の今日がある月の初日を取得
    let firstDayOfThisMonthLastYear:Date = calendar.startOfMonth(for: todayInLastYear)
    
    let numberOfDays:Int? = calendar.dateComponents([.day], from: firstDayOfThisMonthLastYear,to:today).day
 
    if let dayCounts = numberOfDays{

        print("Total days in the last \(months) months: \(dayCounts)")
}

    }

///https://qiita.com/tamadeveloper/items/8e4f68d586cc5b0f9a5a
extension Calendar {
    func startOfMonth(for date:Date) -> Date {
        let comps = dateComponents([.month, .year], from: date)
        return self.date(from: comps)!
        
    }
}
// 12ヶ月分の日数を計算
calculateDaysInPreviousMonths(months: 12)
```


参考：https://qiita.com/tamadeveloper/items/8e4f68d586cc5b0f9a5a


Date()、Calendar()あたりって奥が深いよね。この仕様を作成したハッカーたちはウキウキで考えてたんだろうな。
sshで公開鍵認証

https://blog.htkyama.org/ssh_ed25519

## ed25519の公開鍵と秘密鍵の生成
ssh-keygenコマンドで公開鍵と秘密鍵のペアを生成。
-tオプションにed25519を入れると、ed25519の鍵が出来上がる。
```shell:
$ ssh-keygen -t ed25519
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/user/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```
パスフレーズを設定してもいいが、設定するとsshの接続の度にパスフレーズを求められてしまう。

## 公開鍵/秘密鍵が生成されていることを確認
```shell
$ ls .ssh/id_ed25519*
.ssh/id_ed25519      .ssh/id_ed25519.pub
```
pubのついたid_ed25519.pubが公開鍵。


## 公開鍵を接続先に登録
生成された公開鍵id_ed25519.pubを接続先のホストに登録する。
接続先のユーザ名がuser、ホスト名がhostの場合
```shell
$ ssh-copy-id user@host
```
または、
```shell
# cat ~/.ssh/id_ed25519.pub | ssh user@host 'cat >> .ssh/authorized_keys'
# ssh user@host
# chmod 700 .ssh
# chmod 600 .ssh/authorized_keys
```
```
> type %USERPROFILE%\.ssh\id_ed25519.pub | ssh user@host "cat >> .ssh/authorized_keys"
> ssh user@host
# chmod 700 .ssh
# chmod 600 .ssh/authorized_keys
```
で、リモートホスト側のauthorized_keysに公開鍵の情報が登録される。
再度sshでログインしてみて、パスワードを求められなければ成功。
```
> ssh user@host -i %USERPROFILE%\.ssh\id_ed25519
```

---
引用元サイト様、パクりました。
C++で文字列クラスStringでイコールオペレータを実装してみた

# 概要
C++で文字列クラスを実装してみました。イコールオペレータを実装してみました。以下のページを参考にしました。
http://wisdom.sakura.ne.jp/programming/cpp/cpp27.html

# ソースコード
```string3.cpp
#include<iostream>

class String {
private:
  char* m_data;
  int m_size;
public:
  String(){
    m_data = new char[1];
    m_data[0] = '\0';
    m_size = 1;
  }
  void ShowData(){
    std::cout << "==>> ShowData" << std::endl;
    std::cout << m_data << std::endl;
  }
  void SetData(char *data){
    m_data = data;
    int i = 0;
    while( m_data[i] != '\0' ) i++;
    m_size = i+1;
  }
  char *GetData(){
    return m_data;
  }
  int GetSize(){
    return m_size;
  }
  void SetData(const char *data){
    m_data = (char *)data;
  }
  char GetData(int index){
    return m_data[index];
  }
  String operator = (char *str){
    this->m_data = str;
    return *this;
  }
  String operator = (const char *str){
    this->m_data = (char *)str;
    return *this;
  }
};

int main(){
  String str;
  str.ShowData();
  char data1[10] = "abcd";
  str.SetData(data1);
  str.ShowData();
  str.SetData("1234");
  str.ShowData();
  String str1, str2;
  str1 = str2 = "abcdefg";
  str1.ShowData();
  str2.ShowData();
  return 0;
}
```

# コンパイル
以下のコマンドを実行しました。
```
$ g++ string3.cpp
```

# 実行結果
以下のコマンドを実行しました。
```
$ ./a.out 
==>> ShowData

==>> ShowData
abcd
==>> ShowData
1234
==>> ShowData
abcdefg
==>> ShowData
abcdefg
```

# まとめ
次はプラスオペレータを実装してみようと思っています。
何かの役に立てばと。
macのVSCodeでpythonのDb2ライブラリ ibm_db.connectを実行するとmallocエラー発生への対応策

なんだか似たような話ばかり書いてますが、、、、。
[macでpythonのDb2ライブラリ ibm_dbをimportすると発生するエラーへの対応策(Symbol not found: ___cxa_throw_bad_array_new_length )](https://qiita.com/nishikyon/items/47be9d5682374979f547)
の対応をした後、VScodeのJupyter notebookではなく、そのまま以下の ibm_db.connectを呼び出すtest.pyをVSCodeから実行したところ、
```py
import ibm_db

DBNAME='xxxx'
USERID='xxxxxxx'
PASSWD='xxxxxxxxxxxxxxxx'
HOSTNAME='xxxxx.xxxxx.xxxxx.xxxx.xxxxx.com'
PORT=50001

conn= ibm_db.connect(f"DATABASE={DBNAME};HOSTNAME={HOSTNAME};PORT={PORT};PROTOCOL=TCPIP;\
                      UID={USERID};PWD={PASSWD};SECURITY=SSL;", "", "")
ibm_db.close(conn)
```


`conn= ibm_db.connect`の部分で以下のようなmallocエラーが発生しました。
```
python(32720,0x700007616000) malloc: *** error for object 0x7ff94901c790: pointer being freed was not allocated
python(32720,0x700007616000) malloc: *** set a breakpoint in malloc_error_break to debug
```
このエラーへの対応策を説明します。

参考:
Qiitaの記事[macOSでGUIアプリの環境変数を設定する方法探求](https://qiita.com/homu-konamilk/items/5886f3e48ffa658f4f78)を参考にさせていただきました。

# 対応策
これは
[macでpythonのDb2ライブラリ ibm_dbをimportすると発生するエラーへの対応策(Symbol not found: ___cxa_throw_bad_array_new_length )](https://qiita.com/nishikyon/items/47be9d5682374979f547)
で設定した`DYLD_LIBRARY_PATH`が設定されないために発生するエラーでした。

フォルダーを開く場合はそのフォルダーに`.env`を置いてその中に`DYLD_LIBRARY_PATH`が設定してあればこのエラーはでません。
例:
```
DYLD_LIBRARY_PATH=/usr/local/lib/gcc/8:$DYLD_LIBRARY_PATH
```

Dockから開いたVSCodeでファイル単品xxxx.pyを開いてしまうと、`.env`が読み込まれず、このエラーが出るようです。

VSCodeをDockから開いた時にも`DYLD_LIBRARY_PATH`を設定しておく必要があります。
その設定をするには以下のようにします。

以下のファイルを`setenv_DYLD_LIBRARY_PATH.plist`というファイル名で`~/Library/LaunchAgents/`に置きます。
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key> 
    <string>setenv_DYLD_LIBRARY_PATH</string>
    <key>ProgramArguments</key>
    <array>
      <string>/bin/launchctl</string>
      <string>setenv</string>
      <string>DYLD_LIBRARY_PATH</string>
      <!-- 以下は必要応じて自分のPATHに変更 -->
      <string>/usr/local/lib/gcc/8:$DYLD_LIBRARY_PATH</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
  </dict>
</plist>
```
この後システムをリブートするかログインし直せば、設定が有効になります。
今すぐ適用する場合は以下を実行します。
```
launchctl load ~/Library/LaunchAgents/setenv_DYLD_LIBRARY_PATH.plist
```

以上です。
めも１

![スクリーンショット 2023-05-13 18.04.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630834/53a11b3a-1078-e33e-c051-de8374543cc8.png)
![スクリーンショット 2023-05-13 18.03.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630834/64abd20f-914e-1c90-2145-380d66842fdf.png)
![スクリーンショット 2023-05-13 18.01.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630834/872b7de7-192b-22eb-c16f-2be8a1a68c17.png)
![スクリーンショット 2023-05-13 17.58.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630834/4326db46-1e6a-52cc-8da7-4469e25d2c18.png)


![スクリーンショット 2023-05-13 18.07.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630834/755d0762-e4f0-1b22-a35c-b3ec275e2486.png)

![スクリーンショット 2023-05-13 18.07.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630834/a112b7b9-da25-8840-d60d-819a6e5d1d7f.png)


![スクリーンショット 2023-05-13 18.07.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630834/5db78594-64ff-dfa7-9f86-059abd357992.png)
UnityプロジェクトをGitHubにあげる際のエラー（fatal: the remote end hung up unexpectedly）

# はじめに
Unityで作成したプロジェクトをGitHubにあげようとしたら、「git add .」のコマンドでエラーが発生したので、解決策を共有します。Macを使用している方向けの内容です。

# エラー内容
```terminal:terminal
warning: in the working copy of 'RPG_dev/Library/PackageCache/com.unity.collab-proxy@1.15.7/.signature', CRLF will be replaced by LF the next time Git touches it
git-lfs filter-process: git-lfs: command not found
fatal: the remote end hung up unexpectedly
```

# 解決策
こちらの記事を参考にしました。

https://stackoverflow.com/questions/67395259/git-clone-git-lfs-filter-process-git-lfs-command-not-found

```terminal:terminal
brew install git-lfs
git lfs install
git lfs install --system
```

上記のコマンドを打った後に、「git add .」でいけるはず。
VSCodeのEmmetでHTMLタグを楽に後から囲むやり方メモ

## 1行1単語のとき

```html
<p>今日もらったベルギーワッフルが美味しかった</p>
```

ベルギーワッフルを`<b>`タグで囲みたいとき。

`囲みたいタグ名{囲みたい単語}`
下記例なら`b{ベルギーワッフル}`とすると

```html
<p>今日もらったb{ベルギーワッフル}が美味しかった</p>
```

Emmetのウィンドウでプレビューされる。

![VSCode Emmet 省略記法](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/3bd104c2-743b-6b42-e6ab-675cf42f20e6.png)

そのままEnterキー押せば、完成！

```html
<p>今日もらった<b>ベルギーワッフル</b>が美味しかった</p>
```

## 複数行にまたぐとき

2つ目の`<p>`タグを`<div>`タグで囲みたいとき

```html
<p>今日もらった<b>ベルギーワッフル</b>が美味しかった</p>
<p>
  どこに売ってるのかな？<br>
  明日会ったら聞いてみよう！<br>
  妹にも食べさせたい
</p>
```

### 1.囲みたいところを複数選択

![VSCodeで複数選択しているところ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/5c6a5766-2ee0-422f-df10-bce7e2ffbbdd.png)

### 2.コマンドパレットを開く

`Command + shift + P`または`Ctrl + Shift + P` 

### 3.コマンドパレットの検索窓に`ew`と入力
「Emmet: ラップ交換」と出てくるので、それをクリック。

![VSCodeのコマンドパレットで「Emmet: ラップ交換」と表示されているところ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/a20fe7bb-f653-a9c4-ad0c-4e7b8162322d.png)

### 4.新たに入力枠が出てくる

![VSCodeのEmmetラップ交換で入力枠が出てきたところ!](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/fc20599a-456e-0875-9b25-3036fbdaf5a0.png)

囲みたいタグの名前`div`を入力する。
下にプレビューが出るので、Enterキーを押す。

![VSCodeのEmmetラップ交換でdivを入力しているところ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40940/e75f78ee-04c8-6b2e-6c0f-d33be7485efc.png)

完成！

```html
<p>今日もらった<b>ベルギーワッフル</b>が美味しかった</p>
<div>
  <p>
    どこに売ってるのかな？<br>
    明日会ったら聞いてみよう！<br>
    妹にも食べさせたい
  </p>
</div>
```
相加・相乗平均の関係の応用「2023岩手大学前期【1】(1)」をWolframAlphaとsympyでやってみた。


WolframAlphaとsympyのグラフがでます。

オリジナル

http://kamelink.com/blog/2023/05/11/1-4-23iwatedai-kyouiku-rikou-nou-1-1/

上と同じです。大学入試数学問題集成＞【1】テキスト 

https://mathexamtest.web.fc2.com/2023/202310061/2023100610100mj.html

# WolframAlphaで
グラフがでます。
???3点プロットされました。???

https://www.wolframalpha.com/input?i=0%3Cx%2C+0%3Cy%2C2x%2By%3D1%2Cxy%E3%81%AE%E6%A5%B5%E5%80%A4+&lang=ja

???曲面表示???

https://www.wolframalpha.com/input?i=0%3Cx%2C+0%3Cy%2C2x%2By%3D1%2Cmax%28xy%29&lang=ja

# sympyで(オリジナル様の方法を参考に)
勉強中。「相加平均≧相乗平均」参考あり。

# sympyで(sympy的?安易なやり方で)
・Plots a 3D parametric line plot　にしました。参考あり。
・maximumでわからなかったので、1変数関数にしました。
・「(未)2変数関数の極大・極小・鞍点をsympyを利用して求める」いつかやってみたい。
https://gist.github.com/Yunaka12/f5ea9a04119b5c77d24bbd9bc1614e95

```python
from sympy import *
from sympy.plotting import plot3d_parametric_line
f  =Function('f'  )
x,y=symbols ('x y')
myEq=Eq(2*x+y,1)
y=solve(myEq,y)[0]
xmax=solve(y,x)[0]
plot(y,(x,0,xmax))
f=x*y
myx=solve(diff(f,x),x)[0]
print("#",myx,y.subs({x:myx}),f.subs({x:myx}))
# #xxxx print(maximum( x*y, (x, 0, 0.5) ))
plot3d_parametric_line(x,y,f,(x, 0, xmax))
# 1/4 1/2 1/8
```
①私の環境は,pycharmです。
②よく聞くのは、Jupyterです。
③web上で、上記のソースを「SymPy Live shell」に、コピー貼り付けでもできました。
黒背景の右上に、マウスを移動すると、コピーマークが発生します。
???　タブレット環境で、コピー貼り付けが実行できませんでした。???

次図の範囲のためのつもり？

![0png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/74bcbac9-81f2-aeb1-0f98-239b5d972b80.png)


![1png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/a084bdd9-13e3-f7a2-5ff5-55a82e754b2b.png)

# 参考
過去問

https://qiita.com/mrrclb48z/items/d413ff75fb2efe332aab

sympy.plotting.plot.plot3d_parametric_line(*args, show=True, **kwargs)
Plots a 3D parametric line plot.

https://docs.sympy.org/latest/modules/plotting.html#sympy.plotting.plot.plot3d_parametric_line
【Bash】コマンドをクリップボードにコピー


# Introduction

記事を投稿する際に、コードの中身をコピペするのが地味に面倒......
出力結果をコマンドでクリップボードにコピーするコマンドを紹介します。

エラーログや出力結果など、チームで共有する際に重宝します。

**本記事が少しでも読者様の学びに繋がれば幸いです！**
**「いいね」をしていただけると今後の励みになるので、是非お願いします！**

## 環境

Windows10
Mac
Ubuntu22.04

## Windows

`Windows`には`clip.exe`コマンドが標準機能として提供されています。
コマンドの後ろに`| clip`でコピー可能です。

```powershell:
cat .\test.txt | clip
```

## Mac

`Mac`には`pbcopy`コマンドが標準機能として提供されています。
コマンドの後ろに`| pbcopy`でコピー可能です。

```bash:
cat test.txt | pbcopy
```

## Ubuntu

`Ubuntu`には標準機能としての提供がないため、クリップボードへのコピーを提供する`xsel`コマンドをインストールします。

```bash:
sudo apt install xsel
```

コマンドの後ろに`| xsel --clipboard --input`でコピー可能です。

```bash:
cat test.txt | xsel --clipboard --input
```

`Ubuntu`だけ覚えるのが面倒なので`.bashrc`にエイリアス登録します。

```bash:
sudo vim ~/.bashrc
```

`clip`で`xsel`を呼び出せるようにします。

```vim: ~/.bashrc
alias clip='xsel --clipboard --input'
```

エイリアス登録することで、`Windows`同様に`| clip`でコピー可能になります。

```bash:
cat test.txt | clip
```

## 最後に

ターミナル上でのコピペが少しストレスだったので、もっと早く導入するべきでした......

最後まで閲覧頂きありがとうございました。
備忘録の側面もありますが、本記事がお役に立てば幸いです！

### 参考 URL

https://noauto-nolife.com/post/linux-commandline-clipboard/
【Django】一度`migration`ファイルを削除すると...再作成してもマイグレートで`no migrations to apply`となる

# 概要
* Djangoで`migration`ファイルを削除すると、うまくマイグレートすることができなくなりました。`migration`ファイル削除による影響を記載します。

## マイグレーションファイルの詳細：
* Djangoがデータベーススキーマの変更を記録するためのファイル。
    * 変更=フィールドの追加やモデルの削除など
* ファイルは、「アプリ名/migrations/」以下に保存されます。
* ファイル名は、「マイグレーション番号_マイグレーション名.py」という形式（番号が実行順序）になります。

## `migration`ファイルを削除すると...
* ネットの記事で「マイグレーションファイルを削除して再度マイグレーションすることができる」みたいな文章を見かけるのですが、自分のdocker環境では一度消して再度実行すると、マイグレーションファイルは作成されマイグレーション履歴まで表示されているのに、実行結果は`no migrations to apply`と返ってきてしまいました。

## 原因は？
* おそらく、マイグレーション履歴テーブルに既にそのマイグレーションが適用されたことが記録されているため、再度マイグレーションを実行する必要がないと判断された？のだと思います。
* DB削除してコンテナ起動し直すと、無事に実行できましたが、マイグレーションファイルはdjangoとDBの不仲を生み出す可能性がある存在なので、迂闊にいじらない方がいいなと思います。ローカル環境なので好きに触っていますが、本番ではバックアップ取らずにいじると大変なことになるでしょう...。マイグレーションファイルの削除は最後の手段ですね。
compose.ymlからコンテナに環境変数を渡す(Node.js側からの参照まで)

## 実装に至る経緯
E2Eのplaywrightでテストを実装している際に、ログイン処理を書く必要がありました。ただログイン情報(メールアドレス・パスワード)をそのままテストファイルに書くのもセキュリティ的に良くなかったので、ログイン情報を非公開ファイル扱いとしてそこに定義した環境変数をコンテナに渡してアプリケーション側(Node.js)から参照する方法を取りました。以下にその手順を記載していきます。

### .envファイルを用意
まず.envファイルを用意します。これは環境変数を定義しておく為のファイルで、ここにログインに必要な情報を記載していきます。

```.env
MAIL_ADDRESS=xxxxx.jp
LOGIN_PASSWORD=xxxxx
```
.envファイルはdocker-compose.ymlと同階層にあれば、勝手に参照されるので必ず同階層に置くようにしてください。

### docker-compose.ymlにコンテナ側から参照できる環境変数を定義する
```docker-compose.yml
environment:
  MAIL_ADDRESS: $MAIL_ADDRESS
  LOGIN_PASSWORD: $LOGIN_PASSWORD
```
.envファイルに定義した環境変数がコンテナ内部からも参照できるように、compose.ymlに上記の定義を加えました。こうすることでアプリケーション側(Node.js)からも参照することができるようになります。

### 後はコンテナに渡された環境変数を参照するだけ
playwrightのテストはNode.jsのスクリプトとして実行されますが、Node.jsで環境変数を参照する為には'process.env'を使用します。
```spec.js
await page.getByRole('textbox', {name: 'email'}).fill(process.env.MAIL_ADDRESS);
await page.getByPlaceholder('password').fill(process.env.LOGIN_PASSWORD);
```
上記ではメールアドレス・パスワードをそれぞれformに入力するスクリプトを書いているのですが、それぞれのfillコマンドで環境変数に定義された値を詰めています。これでログイン情報を直接テストファイルに書くことなく、テストを実行できるようになりました。


## 終わりに
以上が(.envファイル => docker-compose.yml => コンテナ)と環境変数を渡して、Node.js側から参照するまでの流れでした。処理の流れとしては非常に簡単なので、手順さえ覚えてしまえばどなたでも使えるはずです。参考になれば幸いです。
JavaScriptで標準入力から数値や文字列を一発で受け取る

# はじめに
オンラインのコーディング問題を解く際に標準入力からカンマ区切りや改行区切りなどでパラメーターが与えられるケースがありますが、問題によって数値、文字列、配列など様々な受け取り方が必要となり、試行錯誤してしまうときがあります。
本質的でないところで手間取るのは思考も途切れてもったいないため、できるだけ簡潔に一発で所望の変数に格納できる方法を考えました。

# コード全体
```JavaScript:stdin.js
process.stdin.resume();
process.stdin.setEncoding("utf8");

const lines = [];
const reader = require("readline").createInterface({
    input: process.stdin,
    output: process.stdout
});
reader.on("line", (line) => {
    lines.push(line);
});
reader.on("close", () => {
    // Change left-hand side dependent on input
    const [x, y] = lines.map(e => e.split(/[,\s]/).filter(e => e != "")).flat().map(e => isFinite(e) ? +e : e);   
    console.log(x, y);
});
```

# ケース1: 文字列が改行区切りで与えられる
```JavaScript
const [s, t] = lines.map(e => e.split(/[,\s]/).filter(e => e != "")).flat().map(e => isFinite(e) ? +e : e);
console.log(s, t);
```
実行例
```
$ node stdin.js
ABCDEF
GHIJKL
(press Ctrl+d)
ABCDEF GHIJKL
```

# ケース2: 文字列がカンマ区切りや改行区切りで与えられる
```JavaScript
const [x, y, z] = lines.map(e => e.split(/[,\s]/).filter(e => e != "")).flat().map(e => isFinite(e) ? +e : e);   
console.log(x, y, z);
```
実行例
```
$ node stdin.js
ABC, DEF
GHI
(press Ctrl+d)
ABC DEF GHI
```

# ケース3: 数値と複数の文字列が改行区切りで与えられる
```JavaScript
const [n, ...pets] = lines.map(e => e.split(/[,\s]/).filter(e => e != "")).flat().map(e => isFinite(e) ? +e : e);
console.log(n, pets);
```
実行例
```
$ node stdin.js
3
dog
cat
hamster
(press Ctrl+d)
3 [ 'dog', 'cat', 'hamster' ]
```

# ケース4: 小数や負の数が与えられる
```JavaScript
const [...nums] = lines.map(e => e.split(/[,\s]/).filter(e => e != "")).flat().map(e => isFinite(e) ? +e : e);
```
実行例
```
$ node stdin.js
0.2
-9
-4.5
(press Ctrl+d)
[ 0.2, -9, -1.2 ]
```

# ケース5: 解説用
```JavaScript
console.log(lines.map(e => e.split(/[,\s]/).filter(e => e != "")));
console.log(lines.map(e => e.split(/[,\s]/).filter(e => e != "")).flat());
console.log(lines.map(e => e.split(/[,\s]/).filter(e => e != "")).flat().map(e => isFinite(e) ? +e : e));
```
実行例
```
$ node stdin.js
3.5
flower, -9, coffee
book, 2.5
(press Ctrl+d)
[ [ '3.5' ], [ 'flower', ' -9', 'coffee' ], [ 'book', ' 2.5' ] ]
[ '3.5', 'flower', ' -9', 'coffee', 'book', '2.5' ]
[ 3.5, 'flower', -9, 'coffee', 'book', 2.5 ]
```

# 解説
- オンラインの問題では入出力がインタラクティブに行われるようなケースはあまりないので、入力終了となるまで一発で受け取り、後続で処理するための変数や配列に一発で格納することを目的としています。
- `lines.map()`で各要素に対しカンマ＆空白文字区切りでさらに要素を展開したのち、空白文字区切りにより展開されてしまう空文字要素を`filter()`で削除します。
- 次に、`flat()`で2次元配列を1次元配列に変換します。
- 最後に、`isFinite()`で有限数かどうか判断して真なら単項演算子`+`をつけることで数値に変換します。`isFinite()`による判定を挟まないと数値でない場合に"NaN"に変換されてしまうので注意が必要です。
- よくある「Nという数値が入力されたのち、続けてN個の文字列が入力されます」というパターンでは`[n, ...params]`のように残りの文字列を残余引数を使用して配列で受けてください。

# 参考にした記事
https://qiita.com/Molly95554907/items/fddb0a426f9e01d50663
【Vue JS】４７都道府県人口密度ゲーム

友人と志摩スペイン村に向かっていたとき、長すぎる志摩までの道中でやることのなくなった我々は暇潰しに日本の都道府県の人口密度を調べていました

![](https://4.bp.blogspot.com/-ORpuq79ARTI/Vf-emw0l5jI/AAAAAAAAyRI/gjzMflOfM6I/s800/train_densya_smartphone.png)

（※画像は3人ですが実際は男2人です）

これが意外に楽しくて、単に都道府県の人口を知っているだけではだめで、その県の面積も考慮しなければいけません

例えば**佐賀県の人口密度は広島県の人口密度よりも高い**というのは直感に反しているかもしれませんが、広島県の広さと佐賀県の狭さを考えると納得いくと思います

「これをゲーム化したら面白いんじゃないか？」と考えて実現したのが以下のアプリ（ゲーム）です

https://population-density-game.netlify.app/

上のリンクからとんでもらえればブラウザからすぐに遊べます

使っている技術は Vue JS のみです

と言ってもあらかじめ用意した４７都道府県の名前と人口密度のセットからランダムに2つ選んで10問出題するだけの簡単な仕掛けです

![](https://storage.googleapis.com/zenn-user-upload/b188b7f00d3a-20221121.png)


![](https://storage.googleapis.com/zenn-user-upload/023c0e686510-20221121.png)

10問解き終わると結果の集計とツイッターへの投稿ボタンを表示します

イラストは「[ちょうどいいイラスト](https://tyoudoii-illust.com/)」から三点お借りしています

画面の遷移は `gameStatus` という変数を作ってそれを `v-if` で判定することによってコンポーネントを切り替えて実現しています

ソースコードの全体はこちら

https://github.com/kromiii/population-density-quiz

JSONファイルの読み込みは過去に Qiita で書いた記事

https://qiita.com/kromiii/items/56e4b0c15786bf8d787b

を参考にしました

JSONファイルの中身を入れ替えれば全く別のゲームになるので、これを拡張して例えば **「東京２３区人口密度ゲーム」** とか **「世界１９６カ国人口密度ゲーム」** など作っても面白いかもしれません

よかったら遊んでみてください

P.S. 
志摩スペイン村は想像していたよりもしっかりとした遊園地でした
私が行った時はアトラクションの待ち時間はゼロでしたが、最近は大手のVTuberとコラボして盛り上がっているみたいなのでまた行ってみたいと思います
個人的にはピレネーがめちゃめちゃ楽しかったです
SwitchBot API v1.1をRubyから呼び出す

# はじめに
[SwitchBot API v1.1をPostmanから呼び出す](https://qiita.com/nakatahr/items/e72662da466c55481273) に引き続き、RubyでSwitchBot APIを呼び出すテストを行いました。公式の [SwitchBot Open API Documents](https://github.com/OpenWonderLabs/SwitchBotAPI) にはPython, JavaScript, C#など代表的な言語のサンプルコードは用意されていますがなぜかRubyはなかったので参考になれば幸いです。

# コード
```ruby:SwitchBotAPIv11.rb
require 'openssl'
require 'securerandom'
require 'base64'
require 'httpclient'

def getDevices
    token = "92708d6a34f4ea9f4a79f..."
    secret = "00f394fc46f732b6..."
    t = (Time.now.to_f * 1000).to_i
    nonce = SecureRandom.uuid
    payload = "#{token}#{t}#{nonce}"
    signature = Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', secret, payload))

    client = HTTPClient.new
    url = "https://api.switch-bot.com/v1.1/devices"
    header = { "Authorization" => token, "sign" => signature, "nonce" => nonce, "t" => t }
    response = client.get(url, header: header)
    puts (response.body)
end

getDevices
```

# 実行結果
```shell
$ ruby SwitchBotAPIv11.rb 
{"statusCode":100,"body":{"deviceList":[{"deviceId":"44179310230F","deviceName":"デバイス名"...
```

# ハマったポイント
- 唯一ハマったのが`t`(UnixTime)です。Rubyの`Time.now.to_i`は秒単位までのUnixTimeしか返してくれず、`Time.now.to_i`で送っても応答はUnauthorizedになってしまいます。必要なのはミリ秒単位のUnixTimeなのですが、それを送るには`Time.now.to_f * 1000`と小数のUnixTimeを1000倍してから整数に直すという力技が必要になります。