OmniAICreator/Qiita-1.07M huggingface dataset:
cheerioでのスクレイピングが気軽で良かった話

## 背景
ページをスクレイピングする際に、playwrightやpupptterしか知らなかったのですが、ChatGPTと相談しているときに勧められて、cheerioを使ってみると良かったのでメモしておきます。

https://pptr.dev/

https://playwright.dev/


## cheerio とは？

https://github.com/cheeriojs/cheerio

- jQueryライクなシンタックス
- 非常に高速
- ほぼすべてのHTML/XMLを解析できる

> Features
❤ Proven syntax: Cheerio implements a subset of core jQuery. Cheerio removes all the DOM inconsistencies and browser cruft from the jQuery library, revealing its truly gorgeous API.
ϟ Blazingly fast: Cheerio works with a very simple, consistent DOM model. As a result parsing, manipulating, and rendering are incredibly efficient.
❁ Incredibly flexible: Cheerio wraps around parse5 for parsing HTML and can optionally use the forgiving htmlparser2. Cheerio can parse nearly any HTML or XML document. Cheerio works in both browser and server environments.


## HTMLの読込みさせ方

使い方は簡単でした。
cheerioをimportし、cheerio.loadでHTMLを読み込みます。

```ts
// ES6 or TypeScript:
import * as cheerio from 'cheerio';

// In other environments:
const cheerio = require('cheerio');

const $ = cheerio.load('<ul id="fruits">...</ul>');

$.html();
//=> <html><head></head><body><ul id="fruits">...</ul></body></html>
```

特定のURLから取得する場合は、fetchを使います。
```js
const response = await fetch(url);
const body = await response.text();
const $ = cheerio.load(body);
```

## Selectorによる要素の取得

読み込み後、Selectorsを使って、各種要素が取得できます。

```js
$('.apple', '#fruits').text();
//=> Apple

$('ul .pear').attr('class');
//=> pear

$('li[class=orange]').html();
//=> Orange
```


## ChatGPTと一緒に使う

上記の使い方だけで、スクレイピングが簡単なことがわかると思います。
ただ、スクレイピングのクラス名や各種要素の取得をChatGPTと連携することで、更に楽することができます。

サンプルにQiitaをChatGPTと協力して、スクレイピングしてみます。

例なので簡単ですが、保存したい要素を、開発者コンソールから要素を選択して、Copy>Copy elementを実施します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3589058/dedd6afc-8b48-5663-ea09-5950aeea0b3f.png)


下記の文でChatGPTに質問します。

```Question
下記のHTMLからcheerioを使って要素と%を抽出する処理をJSで書いて。

~~CopyしたElement~~
```

HTMLの要素に合わせて、テキストを抽出する処理を書いてくれます。

サンプルの場合、量が少ないので、手でやるのとそんなに変わらないので、ありがたみが少ないです。
大量な要素をスクレピングしたい場合、一気に良い感じの変数名とスクレピングの処理を書いてくれるのでとても助かります。

```Answer
const cheerio = require('cheerio');

// ここにHTMLを入れます。
const html = `略`;

const $ = cheerio.load(html);

// 要素を選択し、それぞれのテキストとパーセンテージを抽出します。
$('.style-1yt4yhy').each(function() {
  const element = $(this).find('.style-8uhtka').text().trim();
  const percentage = $(this).find('.style-1wcgrdi').text().trim();
  console.log(`${element}: ${percentage}`);
});
```

最近ChatGPTと一緒にスクレピングしてデータを貯めるのにハマっていたので、まとめてみました。
個人開発では１人という限られたリソースで開発していく必要があるので、こういった気軽な工数削減がChatGPTによって行えて嬉しいですね。
New Relicで監視初心者が気をつけること

[New Relic Advent Calendar 2023](https://qiita.com/advent-calendar/2023/newrelic) シリーズ3の25日目の記事です。メリークリスマス🎅

# 対象者
- **監視**や**オブザーバビリティ**のことはなんとなく知ってる
- 今まであまり監視に触れてこなかった
- なんとなく監視してる

# わかること
- 監視とオブザーバビリティの違い
- なんちゃって監視の危険性
- New Relicで監視する時のポイント

# 監視とオブザーバビリティ
#### 監視
システムにおいて特定または複数の視点であらかじめ想定された事象を検知し、通知すること。

#### オブザーバビリティ（可観測性）
システムの全容をどれくらい把握し、問題の予防や事象の根本原因を特定できるようにしているかを表す尺度。「O11y」と省略される。

:::note info
監視は<font size="1" color="red">**取り組み**</font>であり、オブザーバビリティを向上させるための１つの方法と言えるでしょう。
:::

# New Relic
New Relicはオブザーバビリティを向上させるための機能を揃えたプラットフォームサービスです。

:::note info
概要はウェビナーのアーカイブ動画をご覧ください。
[New Relic はじめの一歩](https://newrelic.com/jp/resources/presentations/nru-101)
:::

# 監視運用上の問題

監視の基本的な構築プロセスはざっくり以下のフローになるかと思います。

```mermaid
flowchart LR;
  P1(データ収集) --> P2(予兆や障害を検知) --> P3(担当者へ通知);
```
ここで以下の問題に直面することがあります。

:::note warn
#### ケース⑴ ほら吹きアラート
1. サーバーのCPUが８５％を超えたため監視ツールから担当者へアラートが自動通知される
1. 担当者は該当サーバーで稼働中のアプリに影響がないことを確認する
1. 1.と2.が何度か繰り返される
1. 当アラートが通知されても担当者は影響確認しなくなる
:::


:::note warn
#### ケース⑵ 属人化アラート
1. サーバーのCPUが８５％を超えたため監視ツールから担当者へアラートが自動通知される
1. 担当者は該当サーバーで稼働中のアプリに精通しており迅速にアラート対応ができる
1. 担当者が変わった後、当通知が来てもどうすれば良いかわからない
1. 対応が遅くなる
:::

上記は適当に作成したアラートをそのまま放置したり、対応ノウハウを蓄積・アウトプットしないことが原因で発生したと考えられます。

そのため
- **監視運用開始後、定期的にアラートの内容を見直すこと**
- **アラート内容に対応ノウハウを含めること**
 
により問題を回避することができます。

New Relicでは **Alert & AI** で通知する内容をカスタマイズすることで対応できます。
- まずはアラートを作成・運用して対応ノウハウを蓄積していきましょう
    - 最初から一般的な解決方法を通知内容に含めてもOK（ページリンク、生成AI）
- 次にアラートの対応方法を整理して通知内容に含めましょう
    - 対応方法を記載したドキュメントのページリンクもOK
- アラートの対応方法を通知内容に含められないようであれば、アラートの削除かデータや閾値の見直しを検討しましょう

:::note info
アラート通知内容のカスタマイズ及び任意の通知先に飛ばす方法
[カスタムインシデント](https://docs.newrelic.com/jp/docs/alerts-applied-intelligence/new-relic-alerts/advanced-alerts/advanced-techniques/alert-custom-incident-descriptions/)
[AWS EventBridgeとの連携によるインシデント対応の効率化（架電編）](https://newrelic.com/jp/blog/how-to-relic/notification-awseventbridge)
:::

# さいごに
今回はNew Relicを導入して実際に直面した問題を取り上げてみました。
すでに監視に携わっている、またはこれから監視を始める方のご参考になれば幸いです。
【レビュアー向け】コードレビューをするときに気を付けること


## 全体的に気を付けること

### 批判的な言葉遣いを避ける

レビューは協力的な雰囲気で進めるべきです。批判的な言葉遣いは極力避け、建設的なフィードバックを心がけましょう。
批判的な言葉は、度が過ぎると相手の人格をも否定することがあります。
またどうしても否定的な言葉を言う場合、まわりに聞こえない様に言いましょう。相手が萎縮し、パワハラになりかねません。

### 肯定的なコメントを挿入する

良い点や工夫された部分には積極的に伝えましょう。
メンバーのモチベーションを向上させ、最終的にシステムの品質向上に繋がります。

### 主観的な意見は避ける

あなた自身の好みや主観的な意見は控え、客観的な事実や規約に基づく評価を心がけましょう。
例えば、「このプロジェクトではこういう書き方を指定しているが、一般的にはこっちのが良いとされる」の様な言い方が良い例です。
そういうアドバイスをする為にも、レビューする側は日頃から知識のアップデートを怠らないようにしましょう。

## チャットやコメントでのコードレビューの場合

### 分かりやすいコメントを残す

コードへのコメントは分かりやすく、具体的な指摘を心がけましょう。その箇所だけを見ても理解しやすいコメントが効果的です。
また、全体的に○○という指摘や、特に理由も書かずつき返すのはやめましょう。
分かりずらいと、再再レビューや質問などで時間がかかり、結果的にあなたの時間が無くなってしまいます。

### 複数のコメントを一度にまとめない

行単位、ブロック単位、関数単位で指摘を行いましょう。
ファイル単位で指摘をしても、受け取った側はどこを修正していいのか分かりません。


## 対面でのコードレビューの場合

### 相手の反応を注意深く観察する

対面でのレビューでは相手の反応を注意深く観察し、適切なコミュニケーションを心がけましょう。
テキスト上とは違い、直に相手の感情や考えていることを読み取ることが出来ます。
それを利用して、相手が落ち込んでいたらポジティブな言葉をかけてあげたり、頭がいっぱいになってそうなら、時間を空けるか分割してレビューするなど臨機応変に対応できます。

### リアルタイムで修正を検討する

場合によってはリアルタイムで修正案を提案し、議論をすることも重要です。
具体的な実装例を提示することで、自分が考えていることが相手に伝わりやすくなります。
相手に考えさせることも大事ですが、場合に応じて使い分けましょう。


## 普段から意識すること

### コミュニケーションの重要性を理解する

コードレビューは技術的な面だけでなく、コミュニケーションの面もあります。
綺麗なコードや、効率の良い処理を意識するがあまり、相手もエンジニアである前に自分と同じ人間であると言うことを忘れないようにしましょう。

### フィードバックのバランスを取る

褒めるべき点と改善が必要な点のバランスを取り、メンバーの成長をサポートするフィードバックを心がけましょう。
どちらか一方に偏ってしまうのは、どちらにとっても良いことではありません。

### 相手の立場に立って考える

メンバーが直面している課題や制約を理解し、理解のもとでフィードバックを提供しましょう。
可能であれば相手が抱えている他の開発や、タスクの状況などをある程度把握し考慮した上でフィードバックを返して上げるのが良いかもしれません。
相手に余裕がないときにフィードバックをしても、あまり頭に入っていなかったりすることもあります。

### 柔軟性を持つ

時には自分の知識が古かったり、間違っていたりする場合もあるかもしれません。
もしレビュー依頼者から指摘をされたら、頭ごなしに否定したり、その場で考えて言うのではなく、相手の意見を尊重することも大切です。

### 定期的なフィードバックを提供する

定期的なフィードバックはメンバーの成長を促進し、信頼関係を築く上で大切です。
メンバーを育てるという観点からも、コードレビューの時以外にも、アドバイスをしたりする方が効果的です。

## さいごに

以上、レビューアーとしてレビューを行う際に気を付けること/意識することでした。
レビューをしてもらう側へ書いた記事もあるので、良かったら確認してみてください。

https://qiita.com/MURAMASA2470/items/35c99aa4db67ef9ffb4a


また、コードレビューそのものについてまとめた記事もあるので、合わせてお時間がある時にでもどうぞ。

https://qiita.com/MURAMASA2470/items/08813184350c620ec698
.NET MAUIを使用して「スマホ向けアプリでも作ってみない？」

# スマホ向けアプリのお時間です
今回は、.NET MAUIを使用してスマホ向けアプリを作ってみたいと思います。

スマホ向けアプリってなんか難しそうなイメージありますよね。
スマホ向けというよりマルチプラットフォーム向けアプリを作るのは難しそうです。
それでも簡単にマルチプラットフォーム向けアプリが作れるもののうち、今回は.NET MAUIを使用してみたいと思います。

# .NET MAUIとは
.NET MAUIは、.NET Multi-platform App UIの略で、.NETでマルチプラットフォーム向けアプリを作るためのフレームワークです。
まぁ簡単に言えば、HTMLみたいなXAMLでビューを書いて、C#で構造を書いてアプリを作れるよっていうやつです。

# というわけで、作ってみよう
まずは何も考えずにVS23を開いて、新しいプロジェクトの作成、`.NET MAUI アプリ`を選択します。
プロジェクト名やフォルダの場所をいい感じに決め、フレームワークもめんどくさいからデフォのままで作成します。

![スクリーンショット 2023-12-25 042401.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107984/02fa0ab5-832e-8ad5-8483-5987aa850cd9.png)

とりあえずこの画面まではもってこれましたかね？

# とりあえず動かしてみよう

とりあえず動かしてみましょう。

![スクリーンショット 2023-12-25 042741.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107984/be47188a-58bb-d2dd-551d-876f9d17b7eb.png)

こんな感じの画面が出てきたら成功です。

てかなんか前とデザイン違うなこれ...

# じゃ、編集してみよう

アプリケーション本体は`MainPage.xaml`と`MainPage.xaml.cs`に書かれています。
まずは`MainPage.xaml`を開いてみましょう。

なんか`Label`って書いてあるやつがあると思います。
これはラベルというもので、テキストを表示するためのものです。

```diff_xml:MainPage.xaml
  <Label
-     Text="Hello, World!"
+     Text="こんにちはあああああああああ"
      Style="{StaticResource Headline}"
      SemanticProperties.HeadingLevel="Level1" />
```

![スクリーンショット 2023-12-25 043318.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107984/6e31b5d3-f2ab-d8e3-2af8-dfb7ceffd22a.png)

と、編集するだけでホットリロード機能によって、勝手に変更が反映されます。
結構便利ですね～！

次に、`MainPage.xaml.cs`を開いてみましょう。

```diff_c_sharp:MainPage.xaml.cs
  private void OnCounterClicked(object sender, EventArgs e)
  {
      count++;
+     count++;

      if (count == 1)
          CounterBtn.Text = $"Clicked {count} time";
      else
          CounterBtn.Text = $"Clicked {count} times";

      SemanticScreenReader.Announce(CounterBtn.Text);
  }
```

`count++;`の下に`count++;`を追加します。
この`count`というのは、クリックした回数を記録するための変数です。
このインクリメントを2回にすることで、クリックした回数が2倍になります。クッキークリッカーみたい。

C#コードの編集には再コンパイルが必要なので、リビルドを行います。
リビルドしたら`Click me`のボタンを押してみましょう。
さっきまで1づつしか増えなかったのが、2づつ増えるようになっているはずです。

# スマホ向けに発行する方法
残念ながら私は実機のスマートフォンを持っていないので検証はできないのですが一応


まずはビルドターゲットを指定します。
ビルドターゲットは画面上部からから選択できます。
![スクリーンショット 2023-12-25 043821.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107984/1270ae23-2fdf-809f-e926-e205dd71a6ef.png)
android、ios、maccatalyst(macOS)、windowsですね。

次に発行をしていきます。
ソリューションエクスプローラーにあるプロジェクトを右クリックします。
「発行」を選択します。
発行のためのウィザードが出てくるので、適当に設定していくと発行できます。
（といっても、Windows環境で発行できるのはWindowsとAndroidのみですが...(さらに私はAndroidでの発行に苦戦した記憶があるから実質簡単に発行できるのはWindowsだけ)）

# まとめ
というわけで、今回は.NET MAUIを使用してスマホ向けアプリを作ってみました。
あんま作ってませんが。

導入のための一歩となれば幸いです。

というわけで、「スマホ向けアプリでも作ってみない？」
Wingetの初使用も兼ねてOpenSSLで「一般社団法人サイバー技術・インターネット自由研究会の電子公告」のTelnet over SSL版を表示してみた


前回の記事の続きになります。
https://qiita.com/NMRchan/items/40d82ecb37e80ef7731a

なんと、インターネット上の愚痴にこたえる形で「一般社団法人サイバー技術・インターネット自由研究会の電子公告」のTelnet over SSL版が公開されていたそうです。

前回の記事のついでに読んでおきたいと思い、環境を整え閲覧してみました。

### Wingetをインストールする

以下マイクロソフト社のリンクからアプリインストーラー（Wingetのこと）のインストールを完了します。

https://learn.microsoft.com/ja-jp/windows/package-manager/winget/

マイクロソフトストアへ誘導され、インストールが完了するだけですので、特に難しいことはないと思います。

コマンドプロンプトを開き動作確認をします。

```
winget -v
v1.6.3482
```

### OpenSSLをインストールする

窓の社の記事の方法

```
winget install openssl
```

ですが私の環境だとうまくインストールできなかったため、公式サイトからexeファイルを結局落としてインストールしました。

https://slproweb.com/products/Win32OpenSSL.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/acd738bd-657a-587c-934f-2ebfd34a1c7d.png)

タスクバーの検索からWin64 OpenSSL Command Promptを探して起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/fc7d52ba-9ada-b800-3891-788176a49266.png)

Win64 OpenSSL Command Promptが起動したら文字コードをUTF-8に変更します。
これはデフォルトがShift－JISであり、このままだと文字化けが発生するためです。

```
chcp 65001
```

そして接続を開始します。
```
openssl s_client -connect koukoku.shadan.open.ad.jp:992
```

相変わらず時間がかかりますが、表示されました。

https://slproweb.com/products/Win32OpenSSL.html

そして窓の社さんの記事によると、いろいろなツッコミに対する反論もこの場でされているとのことです。

現在アドカレを必死で書いており時間が取れない状況ですが、読んでみたい次第です。
2023/12/25主にITとかセキュリティの記事

Juniper製品に5つの脆弱性　パッチの適用は必要なのか(12/23)
https://kn.itmedia.co.jp/kn/articles/2312/23/news055.html

Cloudflare Pagesにおける権限昇格と任意ページの改竄(12/23)
https://buaq.net/go-209363.html

全社員・役員が受講！「生成AI徹底理解リスキリング」 – 6300名、99.6%完了の裏側(12/23)
https://developers.cyberagent.co.jp/blog/archives/45621/

EC2（Amazon Linux 2023）でファイルのハッシュ値に変更があった場合にCloudWatchから通知させてみた(12/23)
https://dev.classmethod.jp/articles/ec2-amazon-linux-2023-hash-check/

Web会議のセキュリティーリスクって？ 今すぐできる対策方法はある？ 【専門家が解説】(12/23)
https://news.allabout.co.jp/articles/o/73617/

サイボウズサマーインターン2023 プロダクトセキュリティコース 開催報告(12/25)
https://blog.cybozu.io/entry/2023/12/25/120000

ICO: 暗号通貨を使用して資金を調達する方法に関するガイド(12/22)
https://portalcripto.com.br/ja/ico-%E6%9A%97%E5%8F%B7%E9%80%9A%E8%B2%A8%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E8%B3%87%E9%87%91%E3%82%92%E8%AA%BF%E9%81%94%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%AB%E9%96%A2%E3%81%99%E3%82%8B%E3%82%AC%E3%82%A4%E3%83%89/

チェック・ポイント、年末に向け増えるフィッシングメールの最新事例を公開　国内企業において悪意あるファイルの99%はEメール経由(12/22)
https://japan.zdnet.com/release/30928950/

生成AIで業務効率化！活用のヒントと注意点(12/22)
https://www.intra-mart.jp/im-press/useful/AI_business_efficiency

ドージコイン (DOGE) をマイニングするにはどうすればよいですか?初心者向けガイド(12/22)
https://portalcripto.com.br/ja/dogecoin-%E3%82%92%E3%83%9E%E3%82%A4%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95-doge-%E5%88%9D%E5%BF%83%E8%80%85%E3%82%AC%E3%82%A4%E3%83%89/

「ビットコイン現物ETFは米企業年金から資金が流入する可能性がある」CNBCが専門家の見解を報道(12/23)
https://coinpost.jp/?p=500448

IT資格の受験、ERPリプレース問題、人事トレンドのホンネ記事が人気　～ERP／人事編～(12/22)
https://kn.itmedia.co.jp/kn/articles/2312/22/news053.html

NFTへの投資：メリットとリスク(12/22)
https://portalcripto.com.br/ja/NFT%E3%81%B8%E3%81%AE%E6%8A%95%E8%B3%87%E3%81%AE%E3%83%A1%E3%83%AA%E3%83%83%E3%83%88%E3%81%A8%E3%83%AA%E3%82%B9%E3%82%AF/

事業再構築補助金事務局の元職員、採択事業者情報11万人分を不正持ち出し営業利用か(12/23)
https://news.yahoo.co.jp/articles/aa7e9522b0ad04d2bc57182ab10b27969bdff903

「水道料金が未納」とウソをつくニセ水道局からのメールに注意(12/23)
https://ascii.jp/elem/000/004/177/4177232/?rss

国家サバイバル　テクノロジー持たざる国は滅びゆく テクノ新世　第3部まとめ読み(12/23)
https://www.nikkei.com/article/DGXZQOCB2017Z0Q3A221C2000000/

Webサービスの歩き方 - シン・境界値分析(12/23)
https://developers.freee.co.jp/entry/qa-adventcalendar-2023-12-23
PythonでTkinterじゃない「GUIアプリでも作ってみない？」2日目

# 2つの関数を同時実行する方法
非同期関数なら`asyncio.ensure_future`できるが、非同期関数ではないし...threadingでどうにかできないかな...などと思っていたのですが、どちらもメインスレッドでの実行を要求しており、なんか埒が明かない気がしてきたので別の方法を探してみました。

# multiprocessing
名前は似ていますが、threadingとは違い、プロセスを作成して並列処理を行うことができます。
これを使用することで、2つの関数を実行できる気がしてみました。

```py:main.py
import frontend
import backend

import multiprocessing

def main():
    backend_process = multiprocessing.Process(target=backend.main)
    frontend_process = multiprocessing.Process(target=frontend.main)

    backend_process.start()
    frontend_process.start()

    frontend_process.join()
    backend_process.kill()


if __name__ == "__main__":
    main()
```

今回、バックエンド部とフロントエンド部でまずファイルを分け、その中の`main`関数で、バックエンドなら`Sanic.run()`、フロントエンドなら`webview.start()`を実行するようにしています。
そして、`main.py`では、それぞれのプロセスを作成し、それぞれのプロセスを実行しています。
これを実行することで、いとも簡単に2つの関数を同時実行することができました。

やっぱり、プログラミングをするうえで、プロセスやスレッド、非同期処理などの知識は必要だなぁと思いました。

ちなみに今のコードだと、なんかよくわからないんですけどフロントエンドを終わらせてもバックエンドが終わらず生きたゾンビになるという問題があります。
よくわからないんですけどまぁ仕方ないなぁって思って割り切ってます。なんかいい方法見つけたら記事でも出してください。誰かが喜びます。

# まとめ
今回は、PythonでGUIアプリケーションを作る方法を紹介しました。
もっと短めの内容にする予定でしたがちょっと分野が分かれた説明ができてしまったので分けました。
こんな記事読んでるぐらいならRust勉強した方がいいと思いますﾀﾌﾞﾝ...

というわけで、「PythonでTkinterじゃないGUIアプリケーションを作ってみない？」
PythonでTkinterじゃない「GUIアプリでも作ってみない？」1日目


# Tkinterとは
みなさん、Pythonはめちゃくちゃ触ると思うんですよえぇまぁこんな記事を見てるぐらいだろうし。
で、PythonでGUIアプリを作るときにはTkinterを使うと思うんですよね。

TkinterはPythonの標準ライブラリで、Pythonをインストールしたらすぐに使えるGUIライブラリです。
しかし、TkinterはGUIアプリケーションとしてはやっぱり...なんか...うーんって感じです。いやまぁGUIアプリケーション！！って感じでいいんですけど。モダンじゃない気がする多分。

そこで今回はTkinterを使わないGUIアプリケーションの作り方を紹介します。

# 今回使うもの
皆さんElectronってご存じですか？
ElectronはJavaScriptでデスクトップアプリケーションを作るためのフレームワークです。

フロントエンドにはHTML、JS、CSSを使い、バックエンドにはnode.jsを使って、フロントエンドとバックエンドの間をIPCで通信することでデスクトップアプリケーションを作ることができます。
昔はこれを使ってGUIアプリケーションを作っていたのですが、いかんせんバックエンドのJavaScriptに慣れなくて断念しました。

じゃあ...それをPythonで再現してみればいいんじゃね...！？

というわけで開発したのが、勝手にPyctronと名付けて可愛がっているものです。
今回はそれの動作原理的なものから紹介していきます。

# 実際に作ってみよう

## Sanic
まずはバックエンドのサーバーを作ります。
今回はSanicを使います。
Sanicは、Pythonで簡単にWebサーバーを作ることができるものです。

```py
import sanic
from sanic import response, Request

app = sanic.Sanic(__name__)

@app.route("/")
async def index(request: Request):
    return await response.file("src/index.html")

@app.post("/greet")
async def greet(request: Request):
    return response.text(f"Hello {request.json['name']}!")

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)
```

こんな感じに書くだけで、2つのエンドポイントを持ったWebサーバーが作れてしまいました。
これを実行すると、`http://localhost:8000`にアクセスすると`src/index.html`の中身が表示され、`http://localhost:8000/greet`にPOSTリクエストを送ると`Hello {name}!`と表示されます。

## WebView
みなさん、WebViewってご存じですか？
WebViewは、ネイティブアプリケーションの中にWebページを表示するためのものです。
今回は、`pywebview`というものを使用してWebViewを起動していきたいと思います。

```py
import webview

window = webview.create_window("Google WebView", url="https://google.com")

if __name__ == "__main__":
    webview.start(http_server=True, debug=True)
```

これだけで、Googleのページを表示するGUIアプリケーションが出来上がってしまいます。

## 連携
これら2つのコードを合体させていきましょう。

さて、この2つを合体させる方法...あなたにはわかりますか？
私は（適切な方法は）わかりませんでした。

# まとめ
現状、それぞれの関数がメインスレッドでの実行を要求していながら、どちらもブロッキング関数なので、どちらかがメインスレッドを占有してしまい、もう片方が実行できないという状況になっています。
これを解決するための方法が...
今更話題になった「一般社団法人サイバー技術・インターネット自由研究会の電子公告」をTelnetで覗いてみた


2023年9月5日
「一般社団法人サイバー技術・インターネット自由研究会の電子公告」がTelnetで行われていることが話題を呼びました。

窓の社より当時の雰囲気がわかる記事
https://forest.watch.impress.co.jp/docs/serial/yajiuma/1528962.html

当時は仕事が忙しく、この話題に乗ることができなかったので、いまさらながらTelnetで表示してやりたいと思います。

### 環境

- Windows11 Telnet有効化済み


### Windows11でTelnetを有効化する

Windows11でTelnetを使うには、タスクバーにある検索で「Windowsの機能の有効化または無効化」を検索、選択し、OKボタンを押します。

OKボタンを押すことでTelnetクライアントのインストールが開始され、1分ほどで終了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/b0e6789d-504f-5193-5926-97863b2851fe.png)

### 「一般社団法人サイバー技術・インターネット自由研究会の電子公告」を閲覧してみる

コマンドプロンプトを起動し、以下を入力します。

```
telnet koukoku.shadan.open.ad.jp
```

![スクリーンショット 2023-12-25 034125.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/0a32f0a1-f0b0-b643-6a00-27e89e0fffac.png)

表示されましたが、いつまでたっても終わりが見えないほど読みこみが遅いです。

5分くらいたってもまだ次の行を1文字ずつ読み込んでいます。

しょうがないので強制的に閉じました。

### やってみた感想

- まだこの電子公告が存在していたことが分かった
- Telnetを人生で初めて使えた
ReactNative Expoでアプリ開発入門してみる Part2

Part1 の続きです。

https://qiita.com/RuruCun/items/4e7ffdfb071c8cee26eb


## 画像ピッカーを実装する

### 画像ピッカーをインストールします

`expo install`でインストールします。

```sh
$ npx expo install expo-image-picker
```

全デバイスに対応しています。強い。

https://docs.expo.dev/versions/latest/sdk/imagepicker/

### 画像選択を実装します。

App.jsへ、ImagePickerを起動する関数を追加します。

```App.js
//　略
import * as ImagePicker from 'expo-image-picker';

export default function App() {
  const pickImageAsync = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      allowsEditing: true,
      quality: 1,
    });

    if (!result.canceled) {
      console.log(result);
    } else {
      alert('You did not select any image.');
    }
  };
//　略
```

### ButtonComponentに押した時の処理を渡せるようにします。

onPress Propsを追加します。

```Button.js
export default function Button({ label,  theme, onPress}) {
// 略
        <Pressable
          onPress={onPress}
        >
```

App.jsでButtonにonPressPropsに先程追加したpickImageAsync関数を渡すようにします。

```jsx
      <Button theme="primary" label="Choose a photo" onPress={pickImageAsync} />
```


### 選択した画像を表示するようにします

追加した部分を抜粋しています。

```diff_jsx:App.js
import { useState } from 'react';


export default function App() {
  const [selectedImage, setSelectedImage] = useState(null);

  const pickImageAsync = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      allowsEditing: true,
      quality: 1,
    });

    if (!result.canceled) {
      setSelectedImage(result.assets[0].uri);
    } else {
      alert('You did not select any image.');
    }
  };
  return (
    <View style={styles.container}>
      <View style={styles.imageContainer}>
        <ImageViewer
          placeholderImageSource={PlaceholderImage}
          selectedImage={selectedImage}
        />
```

ImageViewerを、画像が選択されていた場合にその画像を表示するように修正します。

```jsx
export default function ImageViewer({ placeholderImageSource, selectedImage }) {
  const imageSource = selectedImage  ? { uri: selectedImage } : placeholderImageSource;

  return <Image source={imageSource} style={styles.image} />;
}
```

`Choose a　photo`ボタンを押すことで、画像選択できるようになりました。
画像を選択すると、自分の選択した画像が画面に表示されるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3589058/962b7ceb-85a5-481d-0c9f-511271ff34f6.png)
【ゼロから学ぶNuxt3×Typescript】⑥$route変数を使いidの中身を取得

Nuxt３×TypeScript 学習
下記の参考サイトを見ながら、Nuxt３とTypescriptを学ぶ第6回。

▼　神回|vue3.js nuxt3 typescriptどうやる？【ゼロから解説】

https://field.asia/%E7%A5%9E%E5%9B%9Evue3-js-nuxt3-typescript%E3%81%A9%E3%81%86%E3%82%84%E3%82%8B%EF%BC%9F%E3%80%90%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E8%A7%A3%E8%AA%AC%E3%80%91/


前回はこちら👇

https://qiita.com/sakuc47/items/c3f67a6c0873b4b32966

第1回はこちら👇

https://qiita.com/sakuc47/items/2770d40720070b682ee9

前回は
・[id].vueに求人情報を入れる`<ul>`を作り、`:class`属性（クラスバインディング）を使用して取得したidによって付与するclassを制御する
・リアクティブな`jobs`という変数を作成し、初期値の求人情報の配列を代入する（求人情報が変わるとUIも変わる）
というところまでやりました。

### 1.`[id].vue`の`id`を取得する
> nuxtが用意している$routeという変数を使いidの中身を取得していきます。
{{$route.params.id}}という形で取得することができます

#### $routeとは
現在のURLパス、クエリパラメータ、ハッシュフラグメント、およびその他のルートに関連する情報が含まれているオブジェクト
これにより、動的なルーティングやナビゲーションに関連する情報にアクセスできる。

たとえば、 http://localhost:3000/jobs/hoge?q=00 とした時
[id].vueに下記を書いてみる。

<ins>・[id].vue<ins>
```vue
<template>
  <h2>$route</h2>
  <p>{{ $route.fullPath }}</p><!-- クエリパラメータやハッシュを含む -->
  <p>{{ $route.name }}</p><!-- indexやaboutのようなルートの名前 -->
  <p>{{ $route.path }}</p> <!-- ルートのパス（クエリパラメータは含まれるがハッシュは含まない） -->
  <p>{{ $route.params }}</p> <!-- 動的なパスパラメータのオブジェクト -->
  <p>{{ $route.params.id }}</p><!-- 動的なパスパラメータから id という名前のパラメータの値を取得 -->

<!-- 以下略 -->
</template>
```

UIではこのように表示される。

![スクリーンショット 2023-12-25 2.47.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524465/9845ede4-0956-68c7-a941-17f8a22ee400.png)

今回は`[id].vue`の`id`を取得したいので、`{{ $route.params.id }}`で取得できるということ。

ここまで理解できた。
取得の前にJOB INDEXを作る。

### 2.`jobs/index.vue`を編集

お手本サイトでは`<h1>求人一覧</h1>`となっているが、ルートのindex.vueで`<h1>`を使っており重複するので`<h2>`にする。
（勉強には関係ない部分だが、自分は文書構造重視タイプなので。about.vueも直しておこうかな。）

・<ins>jobs/index.vue<ins>
```vue
<template>
  <h2>求人一覧</h2>
  <ul>
    <li v-for="job in jobs" :key="job.id">
      <p>求人ID: {{ job.id }}</p>
      <p>求人タイトル: {{ job.title }}</p> <!-- name? -->
      <p>求人内容: {{ job.description }}</p>
      <p>画像：<img :src="job.cover" alt=""></p>
    </li>
  </ul>
</template>

<script lang="ts">
import { ref,reactive} from 'vue'

export default {
  // awaitを使う時は関数の先頭にasyncをつける
  async setup() {
    // ref関数でjobs変数を作成
    const jobs = ref([])
    // await 非同期処理
    // fetch ブラウザのAPIで、HTTPリクエストを発行してデータを取得する
    // APIの中のdataというキーを変数に入れている
    const { data } = await useFetch(`https://62fe320941165d66bfbabe7e.mockapi.io/apt/v1/jobs`)
    jobs.value = data._rawValue
    console.log(data._rawValue);
    // const { data: jobs } = await useFetch(`https://62fe320941165d66bfbabe7e.mockapi.io/apt/v1/jobs`)
    return {
      jobs,
    }
  }
}
</script>

```

このままではもろもろエラーになっていて使えない＆ひとつひとつ調べないと理解できていないので次回じっくり学習します。

### 今回はここまで！
折を見てvueでコンタクトフォーム的な物を作成する。
メリークリスマスですね🎄寝ます。

### 参考サイト

https://qiita.com/TK-C/items/caab322156872d546331

不明点はGPTに聞いて単語の意味を知り、関連ワードをゲット→関連ワード含めて検索→ソースを探す、というふうにやっています。
間違えていたら教えてください。
Windows標準機能のみで正確な引用文を素早く作成する方法を布教します。


技術記事を作成する際、よくあるのが引用文を挿入することです。
しかし物理本を読みながらブラインドタッチをするのは非常に面倒くさいですね。

今回はWindows標準機能のみで正確な引用文を素早く作成する方法を紹介します。

### その1：引用したい文章を撮影する

例としてオライリー本の表紙を撮影してみました。

![unnamed.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/c9ee06c7-a1fc-d4a9-4e03-859a568ce0db.jpeg)

### その2：必要な文章のみを切り取る

スマホ向けGooglePhoto標準の切り取り機能で、必要な文章のみを切り取ります。

![unnamed (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/8c9ffa61-91b1-9008-fe10-48373f8229b7.jpeg)

### その3：PCに送信する

Gmailで送ったり、GoogleDriveで共有したりします。

### その4：Windows標準のスクリーンキャプチャを使う

Windows＋Shift＋Sで標準のスクリーンキャプチャを起動し、送信した画像をまるごとキャプチャします。

こんな状態になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/5c69de26-bd2f-fb6c-140a-ddf37f0f68ad.png)

### その5：テキストアクションボタンを押す

元に戻すボタンの左隣の「三」ににたアイコンを押します。

すると、文字列がすべてコピペできる状態になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/c1b500b3-19b1-a78a-5b2c-347d4cdf8952.png)

### その6：貼り付けたい場所にはりつける

```
プロダクト
マネージャーのしごと
1日目から使える実践ガイド
```

こんな感じに長い文章であればあるほど、ブラインドタッチするよりも素早く引用文を作成できます。

個人的にWindows標準機能を使うのが一番ストレスなくコピペできるのでお勧めです。

また、表もこの仕組みを利用して作ることができます。

ChatGPTに画像を添付し、コピーしたテキストも張り付けた状態で「画像を参考に、マークダウンで表を描いてください」などと指示すると、表も素早く作成することができます。
Python で自身の定義した関数の実行時間のみ簡単に知る方法

# はじめに
ある程度大きく複雑なプログラムを定義する際には、たびたび関数ごとの動作速度を分析し、実行速度の改善に臨む必要が出てきます。こんな時、Python でどうやって実行速度を調べると良いのか迷う人も多いかと思います。僕自身も time モジュールを使って知りたい部分の実行時間を合計して print していました。しかし、Python には標準で実行時間計測モジュールが入っているとのことで、少しだけカスタムして簡単に見る方法を作ってみました。

# 環境
MacOS
Python 3.12
Jupyter Notebook

# 実装例
```Python
import cProfile
import pstats
import time

def fastHelloWorld():
    time.sleep(0.1)
    print("Fast: Hello, World!")

def slowHelloWorld():
    time.sleep(1)
    print("Slow: Hello, World!")

if __name__ == "__main__":
    # 計測の実施
    with cProfile.Profile() as pr:

        # 関数の実行
        fastHelloWorld()
        slowHelloWorld()

        # プロファイルの分析と結果のソート
        stats = pstats.Stats(pr).sort_stats('cumtime')
        # ファイル内で定義した関数のみフィルターし出力
        stats.print_stats('/var/folders', 1.)

        # 参考：フィルターなしの出力はこちら
        # stats.print_stats()
```

# 結果
ファイル内で定義した関数のみの実行時間が簡単に出ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/511606/322bf77b-fac4-0481-90af-42cc9c70cb1c.png)
fastHelloWorld に関しては time.sleep で１秒間処理を止めているんですが、なぜ実行時間が0.8秒とかになっているんでしょう、ちょっとわかりませんでした……
また、Windows に関しては未検証のため、一旦フィルターなしで出力してみて、良い感じのフィルター方法を探してみてください。もしあればコメントいただけると助かります。（気が向いたら検証しておきます）

# 参考
https://docs.python.org/3/library/profile.html
QRコードをこき使ってアプリを楽に作りませう

## PowerApps、超便利
私の勤務先ではMicrosoft365が契約されており、OutlookやExcelはもちろんのこと、TeamsやPowerPlatformも便利に使わせていただいています。
私は開発はあまり得意ではない現場作業者ですが、現場作業者は日々大量のデータを扱います。
なのでデータ管理では過去に痛い目に何度もあっており、SharePointリストやDataverseに関心を寄せています。
## データを正しく入力しないと始まらない
私の仕事では大量の計測器を扱います。どの計測器にどんな設定をして計測するのか、間違えると間違えた結果がでます。過去の結果を参考にすることが多いのですが、検索に苦労します。
大文字小文字全角半角の違い、1と7とI、0とO、など、本人に悪気があっても違っていることがあったりします。
（最悪、担当者名で検索しますが、名前によってはやたら件数が出てきたり漢字変換ミスなどの影響を受けます）
## 入力を正しくするためにキーボードを使わない
PowerApps的には、マスタデータを引っ張ってきて、大分類→中分類→小分類と絞り込んだりドロップダウンから選ばせたりしますが、マスタのメンテナンスを怠ったり、借りて来た計測器がマスタに登録が無いなどの別の問題が発生します。
## 入力を正しくするために正しい情報しか入力できない仕組みを作る
ここで私がオススメするのがQRコードです。Appsにカメラコントロールを配置して、計測器に付いたQRを読み取らせます。誰が操作しても同じ結果が得られます。
### QRコードの作り方１：サイトを使う
私は　https://m.qrqrq.com/
を良く使います。URLではなくテキストで製作することが多いです。
作成したQRコードはPNGでダウンロートできます。
### QRコードの作り方２：テプラを使う
キングジムの「テプラ」はバーコードやQRコードが作成できます。黄色か白のテープを使うのがオススメです。
### 社員IDのQRコードを作って配布しておくのもオススメ
データベースに社員IDが保存されていれば、フルネームやメールアドレス、連絡先などを取り出しやすくなったりしますのでおすすめです。PowerApps的には、テナントのIDをQRコード化しておくのも良い方法でしょう。
## リンクを配る代わりにQRを配る
社内のポスターに「お問い合わせはこちらまで」とFormsのURLをQRコード化して貼って置くと、割とフィードバックが得られたり、アプリやwebサービスのリンクをQR化しておくと、日常の繰り返し業務やたまにしか実施しない作業の「あれ、どこだっけ」が減ります。
## URLパラメータが使えるならもっと便利
https://example.com/search?keyword=cat&page=2
みたいな形の？以降をURLパラメータと言うそうです。詳しくはQiitaなので別記事に譲ります。日時やページの設定を埋め込んで、作業者の手間を減らすことが出来ます。私が作った中で一番評判が良いのは、会議室予約で会議室の指定までパラメータに入れたものを、会議室の入り口に貼って置きました。予約状況が簡単に確認できます。
## まとめ
* アプリでは、QRを読ませることで入力の手間やミスを減らすことが出来る
* webでは、URLパラメータ付きのQRコードを作成することで比較的大量のテキストを簡単に渡すことができる

現場の作業者に、マスタデータのメンテナンスを依頼するのは割と大変だったりしますが、テプラでQRコードを貼る、そのQRはこうやって作る、と教えることで、現物とマスタデータを比較的平易に一致させることが出来ます。
大量のマスタデータに埋もれている方には、特にオススメです。

それでは皆様、愉快なPowerAppsライフをお過ごしください。

注１：「QRコード」は株式会社デンソーウェーブの登録商標です。
注２：「テプラ、TEPRA」は株式会社キングジムの商標または登録商標です。
普通に質問しただけで「怒られてる」と勘違いする人が少なからずいるの何故だろう？

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">普通に質問しただけで「怒られてる」と勘違いする人が少なからずいるの何故だろう？<br><br>幼いころから国語の読解問題で行間や言葉の裏を読むようなトレーニングをさせられたことの副作用だったりするのかな</p>&mdash; shelfall (@shelfall) <a href="https://twitter.com/shelfall/status/1738809353250152846?ref_src=twsrc%5Etfw">December 24, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Twitterでこちらのツイートを発見しました。

確かに、実際に私もそうですし、同じ思考回路を持っている人に遭遇したこともあります。

この件について幾つか参考になりそうな記載がある書籍を紹介し、どうしたらいいかを考えてみたいと思います。

### 心理を推測：世界一流エンジニアの思考法より

>日本では「決して失敗が許されないプロジェクト」が多々あった。（中略）
組織で失敗すると、左遷されたり詰め腹を切らされたりして悲惨な目に合うので、失敗を認めづらいのだ。

米MSで働く著者の日本企業への感想はココ以外でも暗い評価が多いです。

私の推測ですが、こういった空気が蔓延する日本企業と、空気を読むことに超特化した人が合わさったことにより、コミュニケーションの不和が起きている可能性があります。

例えば「なぜこうしたの？」と聞くと「（失敗したら終わりな空気で）なぜ？とわざわざ聞くくらいだから何かダメなんだろう」→怒られたと感じる。というように。

月並みですが、組織の雰囲気を変えていくことが重要でしょう。

### 言葉を変えてみる：プロダクトマネージャのしごと第2版より

>周囲の人たちと共に働きそこから学ぶ日々のなかで、気づけば自分が他の人の不安な気持ちや守りの姿勢を引き起こしてしまっている場面があるはずです。私の経験では、相手が答えを持っていないことを尋ねたときによく起こります。そのような防御反応が顕著に現れるきっかけになりがちな言葉があります。戦略的にいちばん重要な言葉である一方、同時に、脊髓反射的な反応を呼び起こしてしまう言葉でもあります。それが「なぜ?」です。

ここからは私の推測です。
「これを今やったのはなぜ？」など、「なぜ？」の譲歩は管理者としては知っておきたいものです。しかし質問された側には（答えを持っていないと、自分が無能だと思われるのではないか）という防御反応を引き起こす可能性があります。

本書では「なぜ？」の言い換えを提案しています。
>「やり方を見せてもらえますか？」

この言い換えは回答者に心の余裕を作ってもらったうえで真摯に回答をしてもらうためのテクニックだそうです。

心理を推測：世界一流エンジニアの思考法よりでも書いたように、空気読みに超特化した人が一部存在します。
私自身がそうなのですが、だとしても「ゆっくりと冗長に」なら「なぜ？」にもこたえられるのです。

そのため「なぜ？」という形式ではなく、ゆっくりと思考を話す中で整理する会話のスタイルの方が好きです。

プレゼンでもない場であれば、冗長なコミュニケーションをとっても良い場合があるのではないかと思います。
（ただ、プロとしてなるべく情報を短く正確に伝える努力はするべきです）

### まとめ

- 職場から懲罰的な雰囲気をなくすといいんじゃないか
- 「なぜ？」を言い換えてみる
【新人向け】コードレビューを依頼する時に気を付けること


## コードレビューをやる意味

コードレビューをやる意味には、以下のようなメリットがあります。

### 品質向上
- クラス設計などが適切か
- 可読性、保守性は担保されているか

### 属人化の防止
- 他の人が理解できるコードであるか
- ソースコードはドキュメントでもあるという考え方がある

### スキル向上
- 開発者の実装レベル向上させる
- 相互レビューなどをすることによりお互いの知らない知識を共有しあえる。また相乗効果なども期待できる

### バグの早期発見
- チーム全体でコードを検証することで、バグや潜在的な問題を早期に発見できる

## コードレビューの形式

### チャット または コメント形式

### メリット

チャットやコメント形式のコードレビューは、テキストチャットやGithubのレビュー機能などを使用し、レビュー実施者が自分のペースでコメントを残し、コードの品質向上を図ります。
レビュー内容がテキストで残るため、後で見返したり他の人の指摘などを確認出来たりとメリットがあります。

### デメリット

一方で、後で説明する対面形式と比べると、レビュー実施者の時間を使ってしまう事や、レビュー依頼者が分からないことが出てくると、対面と比べ質問しづらいというデメリットもあります。

### 対面形式

### メリット

対面形式のコードレビューは、メンバーが同じ場所に集まり、リアルタイムでコードを確認し合う形式です。
直接的なコミュニケーションや即時のフィードバックが出来るメリットがあります。

### デメリット

こちらも一方で、指摘内容を聞き逃してしまったり、レビュー実施者本人も何を指摘したか忘れてしまう というデメリットがあります。

## コードレビューを受ける前に確認すること

コードレビューを受ける前に、以下のポイントを確認しておくことが重要です。

### 聞かれた際に意図が答えられないコードは書かない

 自分で書いたコードには、責任を持つことが大切です。
 どういう意図で書いたか聞かれた際に、理由を明確に答えられるようにしておきましょう。
 「参考にした箇所がこうだったから」「検索したらこう書いてあった」などは理由になりません。

### 最低限、コーディング規約レベルの確認は済ましておく

 チームのコーディング規約やベストプラクティスに基づいているか確認します。
 初回なら仕方ないですが、2回目以降は一度指摘された内容は再度やらないように確認を徹底します。
 レビュー実施者も、コーディング規約レベルのミスを幾つも見つけると気持ちがげんなりしてしまいます。

### レビューは質問の場ではない

 レビューは分からないことを質問する場ではありません。
 実装方法や相談事項など、不完全な部分があるならば、先に別で確認しておきましょう。
 レビューする側は、大体忙しい事が多いです。相手の時間を使っているということを意識しましょう。

### レビューの意味/目的をきちんと理解した上でコーディングする

 レビューの目的や意図を理解し、それに合わせてコーディングしているか確認します。
 動けば良いという考えは、プロジェクトが本当に追いつめられている時以外はダメです。
 あなたが楽をした分、レビュー実施者の負担が増えてしまいます。

## コードレビューを受けている最中に意識すること

コードレビューを受ける際には、以下のポイントを意識しましょう。

### 謙虚な態度で挑む

 レビュー実施者の提案やコメントに対して、謙虚な態度で挑みましょう。
 相手も人間なので、同じミスが多かったりするとストレスが溜まります。
 あまりにも理不尽な場合は、大体パワハラなので、言い返すか他の人に相談しましょう。

### 正直に答える

 レビュー中に、どういう意図でそのコードを実装したか、忘れてしまうことがあると思います。
 思い出せずに、その場で新しい理由などを考えると、大抵支離滅裂な言葉になってしいまいます。
 忘れた時は、正直に忘れました と言った方がまだ良いです。

### 同じミスを繰り返さないようにする

 指摘に対して理解を深め、同じミスを繰り返さないことが大切です。
 修正する際も、なんとなく直すのではなく、自分の知識として吸収する様に心がけましょう。

### レビューは対話

 不明点や疑問点があれば、極力レビューの時間内に確認しましょう。
 それが指摘された時かレビューの最後の時間かは、レビュー実施者によります。
 私は指摘した時に確認すると、お互い内容がしっかり頭に残ってるので良いと思います。

## さいごに

コードレビューは、間違いなどを指摘することがある特性上、怒られていると感じてしまうこともあります。
ですが、多くの場合において、あなたを否定するために言っているのではないと思います。
レビューする側も、ちょっと言い過ぎたかな、、と思う時もあります。
もし傷ついたりムカついたりした際は、それを糧にして、相手にこういう書き方もあるんだ と教えてあげられるくらいになりましょう。

以上になります。


レビューする側に向けて書いた記事もあるので、良かったら確認してみてください。

https://qiita.com/MURAMASA2470/items/bf1729098e8fd1fd4fbb


また、コードレビューそのものについてまとめた記事もあるので、合わせてお時間がある時にでもどうぞ。

https://qiita.com/MURAMASA2470/items/08813184350c620ec698
AWS Skill Builderを使う

# AWS Skill Builderを使う
こちらは、AWS Advent Calendar 2023 22日目の記事として登録させて頂きました。

今回は、AWS Skill Builderを利用してみてのおすすめポイントを書いていこうと思います。

# AWS Skill Builderについて
AWS好きなユーザ様であれば、既にサブスクライブしている気もしますが、AWS 技術を学べるオンライン学習支援サービスとなり、以下のプランの通りで無料でもいくつかの学習コンテンツが受講でき、更に有料のサブスクリプションに登録すると、Skill Bulder LabsコンテンツやAWS Jamなどの実際に手を動かせるコンテンツや認定に向けてのコンテンツが受講できるようになります。

![aws1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90309/74d40da5-3fb3-b51c-54ba-a955649f7b95.png)

`おすすめ1`としては、基本的に新規コンテンツのリリース時の対象言語は英語版になっているとは思いますが、AWS Japanの方による日本語で収録し直したWebinarコンテンツも存在しているため、特にAWS認定の準備をされている方にも役に立つ方もいるのではないかと思います。(コンテンツがあるものに限りますが)
私もSpecialityの認定を受けた際に、Udemyなどの英語版の動画も見たりしていましたが、AWS Skill Builder上のAWS認定準備に向けた日本語版コンテンツも合わせて確認したりしていました。

なお、気になるお値段ですが、個人ですと`29 USD/月`から`299 USD/年`の契約が選択できます。

![aws2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90309/9033272f-d69a-b886-f903-aef2826c76ac.png)

支払いについては、既にサブスクライブしてしまっているので、細かい登録方法は忘れてしまいましたが、私の場合は個人AWS Organizationsで使ってる管理アカウント(ペイヤーアカウント)に紐づけて、AWSの利用料金と合わせて決済されています。
課金周り含めて、登録の進め方は以下に書かれていますので、参照してみてください。

https://aws.amazon.com/jp/builders-flash/202307/aws-skill-builder-subscription/?awsf.filter-name=*all


# AWS Skill BuilderのLabコンテンツの利用どころ
日本語のWebinarコンテンツもおすすめですが、もう一つ個人的に`おすすめ2`としては、個人規模ではリソース削除忘れたりするかもしれないし、料金が気になって触れなさそうなサービス等もSkill Builder Labsで触れる点もおすすめだと思います。
また、Skill Buuilder Labsにおいては基本的にシナリオに沿って触っていくことになりますが、お題と言いますか進められるようにはできているので、サクッと感触を試してみるのにも良いと思います。

直近で私が利用した例としては、以前から事前知識としてインプットしておきたかった、VPC Flog logs周りを触っておきたかったのでシナリオ上にVPC Flow logsの操作が出てくる`Controlling the Network (日本語版)`のコンテンツを試した事があります。

余談ですが、私は元々オンプレミスでのNetwork機器やサーバ等を触っていた事もあり、tcpdumpなどでのパケット解析な様な事はやっていた事があったのですが、それをAWS上で実際にやるとどこまでできるのか、できないのかの事前知識や操作感を知っておきたく、Skill Builder Labsを試しました。

### シナリオを見てみる
シナリオの概要など。アカウントを登録しなくてもシナリオを確認する事は可能なので、以下のように確認することができます。
今回の`Controlling the Network (日本語版)`は以下のリンク先の様な内容になっており、

https://explore.skillbuilder.aws/learn/course/external/view/elearning/13887/controlling-the-network-japanese

`その後、VPC フローログを使用して、各ゾーンのリソースに到達するトラフィックをモニタリングし、必要なトラフィックのみが許可されていることを確認します。`と記載があるので、VPC Flow logsを触れそうな内容。

実際の操作の流れは、操作手順が記載されているので、そのまま進めていけば実際の実際のAWSコンソール上と同等の画面で進めていくことになります。

# Skill Buulder Labsの自由度はどのくらいあるのか？
当然ながら全くシナリオに関係の無いサービスでの操作周りについては、ポリシーの制限がかかっておりリソースの作成等は難しいようです。

当然と言えば当然な気はしますが、今回はVPC Flow logsでの表示やフィルター具体を試したいなと感じていたのもあったのですが、実際触ってみるとログのフィルターについてはシナリオで用意されてるフィルター形式以外でも作成が可能でした。

最後の`おすすめ3`としては、Skill Builder Labsでの他のシナリオでどこまでシナリオ外での操作が許容されているかはわかりませんが、例えばこのようなフィルターを色々試して確認したりができるという事で、これもまたAWS Skill Builderを使ってみるメリットの部分なのではないかなと感じました。
Android の Gboard で全角チルダを入力する「さまぁ～ずハック」

# 波ダッシュと全角チルダ

全角の「から」としてよく用いられる記号には、「波ダッシュ」と「全角チルダ」の2種類が存在する。

[波ダッシュ・全角チルダ問題 - とほほのWWW入門](https://www.tohoho-web.com/ex/dash-tilde.html)

「波ダッシュ」は[MDNでは好まれる](https://github.com/mozilla-japan/translation/wiki/Editorial-Guideline)が、フォントとして「ＭＳ ゴシック」を設定した[サクラエディタ](https://sakura-editor.github.io/)では太い不自然な表示になり、SJIS では保存できないとみなされる**特殊な記号**である。

一方の「全角チルダ」は、フォントとして「ＭＳ ゴシック」を設定したサクラエディタで普通の表示になり、SJIS での保存も普通にできる**普通の記号**である。

![波ダッシュと全角チルダ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/03eefbe9-3e47-a5c5-6926-7d6283ca3416.png)

# Gboard で「ちるだ」と入力しても波ダッシュが入力される

自分は、特殊な記号である波ダッシュより普通の記号である全角チルダを優先して使いたい。
しかし、Gboardで「から」と入力して変換すると、波ダッシュが入力されてしまう。

[あの文字のバイト列は何になるんだっけ 各文字コードの16進数表記を求める(PHP/JavaScript/Perl/Ruby/Python) - INASOFT 管理人のふたこと](https://www.inasoft.org/talk/h201406a.html)
を用いて、何が入力されたかを確認する。

|「から」を入力|「波ダッシュ」を選択|これは波ダッシュ|
|:-:|:-:|:-:|
|![「から」を入力](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/7cbf1df8-2d42-4dbb-f254-3a2749b22ef9.png)|![「波ダッシュ」を選択](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/eb3b8a0b-5ed3-d363-aa2e-027832222968.png)|![これは波ダッシュ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/7a6d11b0-702e-c250-5599-df20c9e1009e.png)|

それだけでなく、「ちるだ」と入力し、明確に「チルダ」と表示されている記号を選択しても、**なぜか波ダッシュが入力されてしまう。**

|「ちるだ」と入力|「チルダ」を選択|これも波ダッシュ💢|
|:-:|:-:|:-:|
|![「ちるだ」と入力](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/24925b55-b0bc-9ffb-5f28-505a1520a042.png)|![「チルダ」を選択](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/72989e77-b55d-8caf-e6a4-71bc1d7982fd.png)|![これも波ダッシュ💢](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/654443d0-5fdf-336f-3cc0-2c69711b84f6.png)|

# さまぁ～ずハック

そんな中、辞書登録や既存のテキストからのコピペを用いずに、Gboard で全角チルダを入力できる方法を発見した。
それは、「さま」または「さまあ」と入力し、予測変換に出てくる「さまぁ～ず」を入力する方法である。

|「さま」を入力|「さまぁ～ず」を選択|全角チルダが含まれる👍|
|:-:|:-:|:-:|
|![「さま」を入力](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/9e612ffe-dec7-1eef-0cb5-09dddae27187.png)|![「さまぁ～ず」を選択](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/d26e4214-aa5f-2bc8-6d12-fdc528a5c2e9.png)|![全角チルダが含まれる👍](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/45d20332-333c-9ffd-7a76-38d7049245d9.png)|
  
入力される「さまぁ～ず」には全角チルダが含まれているので、「さまぁ～ず」を入力して余計な「さまぁ」「ず」を消すことで全角チルダを入力することができる。

# 結論

少なくとも執筆時点では、Android の Gboard において、「から」や「ちるだ」と入力しても波ダッシュが入力されてしまう。
しかし、「さま」または「さまあ」と入力し、予測変換に出てくる「さまぁ～ず」を入力して余計な部分を消すことで、全角チルダを入力することができる。

このハックは、今後のバージョンアップや予測の学習などにより潰されてしまう可能性が考えられる。
大事な場面においては、何が入力されたかを別途確認するか、そもそもAndroidを使わずにパソコンなどで入力を行なうとよいだろう。
基本情報技術者試験、受けてきました　〜記録と感想〜

# 前書き
新年明けましておめでとうございます。syamaです。
皆さん、クリスマスイヴの夜はいかが過ごされましたでしょうか？
大切なパートナーと？あるいは、家族でゆっくり？

私は、基本情報技術者試験を受けて参りました──。

本日はその結果の発表と、どれくらいの準備をしたのか、感想なども残すことでこれから受ける方の一つの基準になればと思います。

# 結果発表
早速ですが、結果の方からご報告させていただきます。
基本情報技術者試験にはITに関係する知識を問う問題が基本の __科目A試験__ (60問・90分)と、アルゴリズム・プログラミング系と情報セキュリティの __科目B試験__ (20問・100分)の2種類で構成されています。
私の今回の受験結果としましては、

**科目A**　**715点／1000点**
**科目B**　**855点／1000点**

という結果でした。~~受験者用のマイページではまだ結果としては未発表となっているのですが、合格点がそれぞれの科目で600点ずつということなので、 __合格__ ということで良いのだと思います（全体的にあっさりとした受験形式なので、実感がないです）。~~ （追記：1月中旬くらいに正式に合格発表が出てました。）やったー。

# どのように、どれくらい勉強したのか
今回受験した基本情報技術者試験について、受験者の規約として具体的な問題の内容などに言及することはできないのですが、何を使ってどのくらい勉強したのか、一例として私の場合を記させていただきます。

## スタート地点
前提として私が本腰を入れて勉強を始めたのは、__試験日の3週間前__ あたりでした。遅いですね。これには理由があり、私がものぐさでお尻を叩かれないと前に進めないタイプであるため、申し込める日に試験を申し込んでしまい、そこに間に合わせる形で勉強を進めようと考えたからです。その結果、クリスマスイヴを試験と過ごすことになったのですが（笑）

さて、私は試験対策のテキストに一通り目を通した後、知識確認として過去問を解いてみました。（問題は[基本情報技術者試験ドットコム](https://www.fe-siken.com/kakomon/sample/)の新制度サンプル問題を使用。）その際の点数が、__科目A 39問/60問__ 、__科目B 19問/20問__ でした。私は元来数学が好きで、この業界に入ってからも（今のところ）楽しくプログラミングができている人間でしたので、実際に解いてみた手応えとしてもこの時点で「科目Bはほどほどで大丈夫だな」という感覚を得られていたのはラッキーでした。
問題は科目Aで、一応合格ラインの6割に届いてはいるものの解いてみた上での手応えは全くなく、さらに言えば4択の問題ということで当てずっぽうで答えて当ててしまったものもあったと記憶しています。また、基本情報技術者試験では __IRT方式__ という、問題ごとの受験者全体の正答率によって配点が調整される方式がとられているため、正答率が6割ギリギリでは合格できない可能性があることも不安要素の一つでした。

ということで、受験まで時間があまり無いということもあり、早い段階で __科目Aに絞って対策を行う__ という方向性を取ることを決定しました。

## したこと
テキストも購入して一通り目を通しはしましたが、試験対策という面で見ればやはり過去問をひたすら解くというのが一番良いと考えています（しっかりと知識をつけることが目的なら、また別の方法があると思いますが……）。
新制度のサンプル問題は数がないので、基本的には旧制度の過去問を解いていました。時事問題系に対応できて一石二鳥ということで、最近の過去問から選択しています。
成績としては、
1回目：試験日2週間前　39/60
2回目：試験日1週間前 62/100
3回目：試験日4日前　71/100
4回目：試験日1日前　74/100
5回目：試験日当日（新方式の公開問題を使用）15/20
といった感じでした。結局当日まで絶対的な自信が付くことはありませんでしたので、これから受験されます皆様におかれましては、早めに取り掛かることを強くオススメします。

# 感想
今回実際に試験を受けて思ったのは、やはり試験に合格するという観点では過去問をとにかくたくさんこなすことが大正義であるということです。間違えた経験が知識に紐づきますし、なんなら似たような問題が出ることがあるかもしれません。
ここまで読んでくださった方には申し訳ありませんが、私のやり方はあまり参考にしない方がいいと私も思いますし、これから私が応用情報技術者試験を受ける、となればゆっくり時間をとって勉強すると思います。
科目Aは正直なところあまり自信がありませんでしたが、一方で実際に試験を受けた際には自信をもって答えられる問題も多くあり、これが過去問を解けば解くほど増えていくのだと身に染みました。
科目Bは点数からしておそらく20問中3問ほど落としていると思うのですが、こちらは自信があったので少し悔しいです。過去問を解いていると、意外と問題の読み間違えだとかそういった下らない原因で解ける問題を落としてしまうこともあったため、科目A,Bに関わらず時間に余裕を持って解いた上で確認の時間を設けることは本当に得点に影響を及ぼすと思います。

今回はこの辺で。読んでいただきありがとうございました。
Gmailが迷惑メール対策を強化するらしいので、TXTレコードを引いてSPF設定を確認したりしてみた


Googleは迷惑メール対策を強化するために、Gmailアカウントへ1日5,000件以上メールを送信する企業は、SPF/DKIM/DMARCの３つへ対応することを求めています。

2024年2月以降、適用されていくということです。
（詳細はNRIさんのブログでご確認願います。）
https://www.nri-secure.co.jp/blog/gmail-guideline-2023

そこで今回は自分が利用しているネットショップは既にこれらに対応しているのかを確認してみることにしました。

なお、途中で気づきますが、メールのソースを表示することで一瞬でわかります。

### 受信したサンリオのメールヘッダ

キキララ・・・誕生日おめでとうだよ！！

| 項目        | 内容                              |
|-----------|---------------------------------|
| From      | サンリオ <info@plus.sanrio.co.jp> |
| To        | user@example.com                |
| 日付       | 2023/12/24 10:11                |
| 件名       | Happy Birthday キキ＆ララ☆        |
| 送信元      | fc4053.cuenote.jp               |
| 署名元      | plus.sanrio.co.jp               |
| セキュリティ | 標準的な暗号化（TLS）             |

### SPF設定を調べてみる

Fromは差出人、送信元（Sender）が送信元ですので、今回の調査対象は「fc4053.cuenote.jp  」の方になります。

送信元からサンリオさんは「Cuenote」さんのメール配信サービスを利用しているようです。

digで「fc4053.cuenote.jp」のTXTレコードを引いてみました。

```
ANSWER SECTION:
fc4053.cuenote.jp.	600	IN	TXT	"v=spf1 ip4:210.152.237.130 ip4:210.152.237.131 ip4:210.152.237.132 ip4:210.152.237.133 ip4:210.152.237.134 ip4:210.152.237.135 ~all"
```

読みやすいようにIPアドレス指定の部分を改行しました。

```
ip4:210.152.237.130
ip4:210.152.237.131
ip4:210.152.237.132
ip4:210.152.237.133
ip4:210.152.237.134
ip4:210.152.237.135
```

上記IPアドレスを指定して、SPFレコード（TXTレコード）が設定されていることがわかりました。

これにより、fc4053.cuenote.jpからメールを受信したメールサーバが、DNSにSPFレコード（TXTレコード）を問い合わせ、末尾130~135以外のIPアドレスから送信された場合は不正とみなし、廃棄または隔離されます。今回の場合は「~all」が指定されているため、受信メールサーバによってスパムかどうか判断されます。これをソフトフェイルといいます。

### DKIMの有効性を確認する

DKIMの有効性を確認するには「ドメイン名」と「セレクタ」が必要になります。
「ドメイン名」はわかってますので「セレクタ」を調べます。

Gmailにはメールのソースを表示する機能がありますので、表示してみましょう。

あ・・・

![s-CB_0006.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2636207/76ab6510-da1d-aad8-d4b8-92e23733aa9a.jpeg)

何も見ていません。勉強のために続けましょう。

DKIM-Signature: という行のs=XXXXXの部分がセレクタです。

これで両方わかったので、以下のサイトでDKIMの有効性を確認し、検証完了とします。

https://dkimcore.org/tools/


### DMARCの有効性を確認する

NRIさんの参考情報より
https://www.nri-secure.co.jp/blog/gmail-guideline-2023

ダイレクトメールの場合、SPFまたはDKIMのAlignmentを一致させる：DMARCに準拠するための条件である

というものがあります。

DMARCに準拠しているかどうかの確認のため、以下のサイトを参考にしました。
https://baremail.jp/blog/2023/09/26/3474

>DMARC認証に合格するためには
メールがDMARC認証に合格するには、SPF認証とSPFアライメント、またはDKIM認証とDKIMアライメントのいずれかに合格する必要があります。
SPFとDKIMのどちらかが認証とアライメントをPass（合格）できていれば、もう一方は未導入あるいはFail（失敗）となっていてもDMARC認証にPassすることができます。ただし注意しなくてはならないのは、SPFとDKIMの認証がどちらも合格していたとしても、アライメントが両方とも合格できなかった場合DMARCの認証としてはFailとなってしまうということです。

DKIMアライメントでDMARCの有効性を確認する場合

>DKIMアライメントとは
ヘッダFromのアドレスが、DKM署名の「d=」で指定したドメインと一致するかチェックするのが「DKIMアライメント」です。

今回のサンリオさんからのメールの場合、

| 項目                        | 内容                  |
|---------------------------|---------------------|
| From                      | サンリオオンラインショップ本店 <info@ec.sanrio.co.jp> |
| DKIM Signing Domain (d)   | ec.sanrio.co.jp      |

でしたので一致が確認できました。

これによってSPFまたはDKIMのAlignmentを一致させていることが確認できましたので、DMARCも有効であるようです。

### まとめ

メールのソースを表示で一発ですが、詳細な確認方法を知っておくことはいつか役に立つ（と思います）。
Unityでゲームを作るその２　ナビゲーションを使う

この記事は、[【完走したい】楽しくいろいろやる Advent Calendar 2023](https://qiita.com/advent-calendar/2023/notbeginner)の23日目です。


# 経路探索
unityにはナビゲーションとかいう便利な機能があるようです。
これを使うと障害物を避けてオブジェクトが自動的に目的地まで到達できるようです。
せっかくなので、迷路を作ってどれだけ早くゴールできるか確認したいと思います。

# ナビゲーション
使おうとしたら、入ってませんでした。最近のunityはもとから入っていないようです。
package managerを使ってダウンロードします。
動かすオブジェクトにNav Mesh Agentを付け、通さないところにはNav Mesh Obstacleを付けます。
![スクリーンショット (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/8ba9ab43-0a7a-14e9-09ee-6c3326ce927c.png)

ちゃんとゴールまでたどり着けました
ちなみに、移動するオブジェクトは当たり判定を付けたオブジェクトをすり抜けて進むみたいです。
# ジャンプ
![スクリーンショット (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/0ab46cf4-bdbb-492b-7efc-7aaa424da603.png)
上の画像のように、飛び越えたいオブジェクトにNavMeshSurfaceをつけ、Defalt Areaをjumpに変更することで、ジャンプできます。
# 本題
前回PLATEAUを使ったので、その中でスタートからゴールまで行けるか試します。
PLATEAUは、インポートしたばかりの初期状態では地面と建造物が離れていることがあります。そういったところを直して、スタートとゴールを設定したら
<iframe width="560" height="315" src="https://www.youtube.com/embed/VTEFBqEDxL0?si=jZ2RMX4HMTelJDnw" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
こうなります。目的地まで、障害物を避けながら自動で動いていることがわかると思います
# まとめ
自動で障害物を避けながら、ゴールまで進んでくれるNavigationという機能があった。
ジャンプさせることもできて、便利。

参考

https://i-school.memo.wiki/d/AI%20Navigation%20%28Unity%202022.2%20%B0%CA%B9%DF%29

https://docs.unity3d.com/ja/560/Manual/nav-InnerWorkings.html

https://docs.unity3d.com/Packages/com.unity.ai.navigation@1.1/manual/NavigationWindow.html

https://vanikki.com/unity-navmesh/
optparseでコマンドラインのオプションを使えるようにする

## はじめに
コマンドラインから任意のオプションを設定するoptparseについて学習したので
その使い方についてまとめます。

## 使い方
optparseを使用する際は[公式リファレンス](https://docs.ruby-lang.org/ja/latest/library/optparse.html#argv)より以下の３つの工程が必要になります。
1. OptionParser オブジェクト opt を生成する。
2. オプションを取り扱うブロックを opt に登録する。
3. opt.parse(ARGV) でコマンドラインを実際に parse する。

 コードでは以下のようになります。
 ```ruby:code
 require 'optparse'
opt = OptionParser.new

opt.on('-a') {|v| p v }
opt.on('-b') {|v| p v }

opt.parse!(ARGV)
p ARGV
 ```

↑のコードを記載したrubyファイルを起動する際にオプションとして```-a```と```-b```が
使用できるようになりそのオプションの処理が行われます。

### 1.OptionParser オブジェクト opt を生成する。
まずruby標準搭載のライブラリであるoptparseをrequireします。
その後にOptionParserクラスのインスタンスを生成します。
以後このインスタンスでオプションの設定を行います。
 ```ruby:code
 require 'optparse'
opt = OptionParser.new
 ```

 ### 2.オプションを取り扱うブロックを opt に登録する。
 インスタンスメソッドのonで入力可能にするオプションと
 そのオプションの処理を設定します。
 処理内容はブロック内に記載しブロック変数にはオプションの引数つまり
 コマンドラインでオプションの次に入力した値が入ります。
 ここで注意しなければならないのがonメソッドがよばれた時点では
 ブロック内の処理が行われていないことです。
 ブロック内で引数を別の変数に入れて利用するケースで思わぬ不具合が出る
 ということがあるので気をつけて下さい。
 処理が行われるタイミングは後述のparseメソッドに付随して説明します。
```ruby:code
opt.on('-a') {|v| p v }
opt.on('-b') {|v| p v }
 ```

 ### 3.opt.parse(ARGV) でコマンドラインを実際に parse する。
 perseメソッドでオプションの引数を解析しARGVにその値が入ります。
 また、先ほど説明したonメソッド内の処理はperseメソッドがよばれたタイミングで
 行われます。
 ```ruby:code
opt.parse!(ARGV)
p ARGV
 ```

 ## 最後に
 以上optparseの解説になりました。
 使い方はさまざまあると思いますので気になる方はぜひ[公式リファレンス](https://docs.ruby-lang.org/ja/latest/library/optparse.html#argv)も活用して
 学習してみて下さい。
WindowsでAirflowのCustom XCom Backendを試した


WindowsでAirflowのCustom XCom Backendを試してみました。
- https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/xcoms.html#custom-xcom-backends

環境構築で参考にした記事はこちら
- https://blog.devgenius.io/installing-airflow-on-windows-without-docker-in-5-mins-21d16091ebc5

では本題。流れは以下です。
1.Custom XCom Backendの定義したPythonファイルを作成
2.cfgファイルにてCustom XCom Backendファイルを設定
3.DAGファイルを作成
4.実行

## Custom XCom Backendの定義したPythonファイルを作成
以下使用するCustom XCom Backendの定義したPythonファイル
```
from airflow.models.xcom import BaseXCom
class XmasBuckend(BaseXCom):

    @staticmethod
    def serialize_value(value):
        return BaseXCom.serialize_value(value)

    @staticmethod
    def deserialize_value(result):
        result = BaseXCom.deserialize_value(result)
        return f"Received value from Santa Claus: {result}" 
```
## cfgファイルにてCustom XCom Backendファイルを設定
上記ファイルを使用できるようにcfgファイルの設定を変更します。
xcom_backend = ファイル名.クラス名を設定すればOKです。
```
xcom_backend = Custom_XCom_Backned.XmasBuckend
```

## DAGファイルを作成
```
from airflow import DAG
from airflow.operators.python import PythonOperator
from airflow.operators.bash import BashOperator
from datetime import datetime


with DAG(
    'Santa_Claus',
    schedule=None,
    ) as Santa_Claus:

    push_task = BashOperator(
        task_id='push_task',
        bash_command='echo presents',
        do_xcom_push=True
    )

    pull_task = BashOperator(
        task_id='pull_task',
        bash_command='echo {{ ti.xcom_pull(task_ids="push_task") }}',
    )

push_task >> pull_task

```
## 実行
以下で確認しました。
- http://localhost:8080

結果ログ(該当部分抜粋)
```
[2023-12-24, 15:53:16 UTC] {subprocess.py:93} INFO - Received value from Santa Claus: presents
```

想定通りの結果になりました、よかった！
メリークリスマス🎄
画面全体を拡大表示（Mac, iPad, iPhone, Windows）

こんにちは。
画面全体を拡大表示する方法を調べました。
* ズーム領域：フルスクリーンズーム

各OSの機能設定方法と、利用時のGUIは、
* Mac：システム設定＞アクセシビリティ＞ズーム機能（ジェスチャを使うなど）
* iPad, iPhone：設定＞アクセシビリティ＞ズーム機能 （3本指で画面をダブル・トリプルタップなど）
* WindowsOS：「拡大鏡」を用いる
* Linux：未調査

#### マウスカーソル位置の強調表示
および、マウスカーソル位置を強調表示するツールを調べました。

* Mac：
  * Simple Mouse Locator
  *  ScreenPointer
* Windows: 未調査
* Linux: 未調査
Docker環境の Laravel10 で "laravel allowed memory size of *** bytes exhausted (tried to allocate *** bytes)" とエラーが出た時の対処法

# 結論

php artisan を実行するディレクトリで、`chmod 707 -R storage`を実行すれば解決した（私の場合では）。

# 何があったか

## 未知(エラー)との遭遇
ローカル開発環境をDockerで新規構築して、Xdebug入れたりログの出力先などのphpの調整をしていた。

バニラPHPでは正しく動作することを確認したのち、Laravel10をインストール。

すると、Laravelのエラー画面で以下のテキストが表示された。

> Allowed memory size of 268435456 bytes exhausted (tried to allocate 29364224 bytes) 

「あんたのPHPは268MBしか使えんようになっとるで！せやのに、293MBを使おうとしたから終了したで！（関西翻訳）」といわれているようだ。

## え、どうして...?

今までLaravel9で開発をしていたが、こんなエラーが出たことなど一度もなかった。Laravel10はメモリをいっぱい使うのかな～とか思いながら、php.iniを`memory_limit=1024M`というように変更した。

すると今度は、

> laravel Allowed memory size of 1073741824 bytes exhausted (tried to allocate 165959713 bytes)

一気に1.6GBを要求するエラーに変わっていた。ただウェルカムページを表示しようとしているだけなのに。

もうこの時点で、メモリ不足の問題が原因ではないだろうなと感じた。

とりあえずlaravel.logの出力でも見るか・・・。



・・・。



## あれ！？laravel.logが作られてない！！

そもそもの、laravel.logが存在していなかった。

ここでピンときた。これまで何度も、DockerのLaravel環境で「**storageフォルダへのその他ユーザのアクセス権がないためログファイルが出力できない**」というエラーが起きることがあった。

.envに`APP_DEBUG=true`と設定していると、全てのリクエストの処理のコールスタックごとのログをlaravel.logに書き込むようになっていて、storageフォルダへのアクセス権がないと異常終了してしまうのだ。
今までだったら、`Cannot access to laravel.log`的なエラーが出ていたのだが、laravel.logが作られていないということは、それにかかわるエラーかもしれない。

## 一件落着。2時間溶けた。

その時の解決法である、`chmod 707 -R storage`を試してみると、無事解決。

環境によっては、アクセス権エラーと表示されず、メモリ不足といったエラーが出ることもあるようだ。

この記事が、どなたかのエラー解決の助けになれば幸いです。

# 余談

ウェルカムページが表示された後、あらためてlaravel.logを確認しようとしたところ、なんと存在しなかった（！）。

たまたま今回はうまくいったが、どうも自分の勘違いだったらしい。

・・・え？マジで、どこに消えたんだ？Laravel10から廃止になったのか？
Nuxt で Server Component やってみた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509303/0571512e-c331-c8a4-c49e-636aa3bc8cd8.png)

これの、my component 以下の部分が Server Component になっていて、テキスト入力をするたびにリクエストが飛んでいきます。

# セットアップ
```nuxt.config.ts
export default defineNuxtConfig({
  devtools: { enabled: true },
+   experimental: {
+     componentIslands: true,
+   },
})
```
たったこれだけ！
実験的機能なので今のところ遊びでしか使えそうにないですね。

# コード
```pages/index.vue
<template>
  <input type="text" v-model="text" />
  <Test :text="text" />
</template>

<script setup lang="ts">
const text = ref('');
</script>
```

このページの、`<Test />` が Server Component です。

```components/test.server.vue
<template>
  <div>{{ text }}</div>
  <div v-html="html" />
</template>

<script setup lang="ts">
import MarkdownIt from 'markdown-it';
import { ref } from 'vue';

const props = defineProps<{
  text: string;
}>();

const md = new MarkdownIt();
const string = `# my component
- markdown list
- rendered as html
- cool
- ` + props.text;
const html = md.render(string);
</script>
```

Server Component は `.server.vue` のようなファイル名にしてあげると勝手にサーバでレンダリングされるようになります。

# おわり
```components/test.server.vue
<template>
  <div>{{ text }}</div>
  <div v-html="html" />
</template>
```
👆 の、`{{ text }}` を外してみるとまともに動かなくなった。そういうもの？
難しかった。
【C#】HelloWorldを表示させる方法

# はじめに
今回は`C#`で`HelloWorld`を表示させていこうと思う
```c#
using System;
class Main
{
    public static void Main()
    {
        Console.WriteLine("Hello World");
    }
}
```
実行する
# さいごに
今回は`C#`で`HelloWorld`を表示させた