OmniAICreator/Qiita-1.07M huggingface dataset:
Power Platform から Azure OpenAI Service 経由で ChatGPT を利用してみる


# はじめに

Power Platform から OpenAI API を利用する方法について、私の同僚が素晴らしい記事を書いてくれました。
API が提供されているため、Power Platform から、HTTP コネクタを介して利用したり、カスタムコネクタを作成して利用することが出来ます。

https://qiita.com/Satoshi_Yoshino/items/b4fc4a74265069fdf109

https://qiita.com/Satoshi_Yoshino/items/50a4918659bab73dd5ff

https://qiita.com/Satoshi_Yoshino/items/e2a47a3aaedef7ea5079

今回は、上記と同じような方法で (基本同じような感じですが)、Azure OpenAI Service 経由で ChatGPT を利用してみたので参考までに共有します。

# キーの取得

Azure OpenAI Service にサインアップしてリソースを作成すると以下のようにキーを取得できます。こちらで取得したキーを控えておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/082285b9-608a-c56b-ad46-2464789ca57d.png)

# API 情報の取得

モデルをデプロイすると、以下のようにチャットが可能になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/f19c9cc2-19e6-30ac-c599-c47de12f6eeb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/88b13cc1-88fe-2ffe-92f2-420b3fe1d2b2.png)

パラメーターやデプロイの方法などについてはこちらがとても参考になります。

https://qiita.com/AGV_morinaga/items/04c1b3f505efca8b1511#24%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AE%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4

こちらから、利用する URL や Json のコードをコピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/1d09fbea-7530-9ba9-c11c-54819074299d.png)

```
{
  "messages": [
    {
      "role": "system",
      "content": "You are an AI assistant that helps people find information."
    },
    {
      "role": "user",
      "content": "日本で一番高い山は？"
    },
    {
      "role": "assistant",
      "content": "日本で一番高い山は富士山です。"
    }
  ],
  "temperature": 0.7,
  "top_p": 0.95,
  "frequency_penalty": 0,
  "presence_penalty": 0,
  "max_tokens": 800,
  "stop": null
}
```


# HTTP コネクタからの利用

あとは、上記ブログと同じ要領で作成できます。全体像は以下のような感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/b21a09c0-f4d1-b472-8f3a-39ccc3751196.png)

以下のように、取得した情報をそれぞれ入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/e3a95907-bf2e-0fe3-4033-9b668f1b574f.png)

:::note warn
"role": "assistant" の部分の情報は削除します。
:::

実行結果は以下のような感じです。
(しんあのがわ。。。)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/4e8fa991-9e8e-76e3-b920-346051b2d8ed.png)


```
{
  "id": "chatcmpl-70zNRQLEX6tSsR9B2KuGSQLWyE9Lj",
  "object": "chat.completion",
  "created": 1680470289,
  "model": "gpt-35-turbo",
  "choices": [
    {
      "index": 0,
      "finish_reason": null,
      "message": {
        "role": "assistant",
        "content": "日本で一番長い川は信濃川（しんあのがわ）です。信濃川は長野県を源流とし、長野県、岐阜県、愛知県、三重県、滋賀県、京都府、大阪府、兵庫県を流れ、約367キロメートルの距離を持っています。"
      }
    }
  ],
  "usage": {
    "completion_tokens": 112,
    "prompt_tokens": 35,
    "total_tokens": 147
  }
}
```

とりあえず、Power Platform からも簡単に利用できました。
対話形式で利用する場合は、冒頭で紹介したブログが参考になると考えます。

# まとめ

Power Platform から Azure OpenAI Service 経由で ChatGPT を利用する方法を紹介しました。Open AI の API を直接利用する場合と大きな違いはなく利用することが出来ました (そちらを先に利用していたのであっという間に実装できました)。

今後、Power Platform を介してこれらのサービスを利用する新たなソリューションがどんどん生まれてくると思います。これだけ簡単に組み込めるわけですし、ここからは、アイディアの勝負かなと思っています。
Slackのchat.updateで小さく躓いたこと。

## はじめに
先日slackAPIを使ってslack連携機能を実装しました。
まず、chat.postMessageを使って、slackにメッセージを送信したりそのメッセージのスレッドに返信する機能を実装し、その後、chat.updateを使って、既存のメッセージの編集を実装しました。
chat.updateもchat.postMessageと使い方はそんな変わらないと思い、chat.postMessageのコードをコピペしてちょちょっと変えてササッと実装しようとしたのですが、数個の小さなトラップに引っかかったので、メモ程度に残しておきます。

### 1. 引数「channel」について
chat.postMessageでメッセージを送るときも、chat.updateでメッセージを編集するときも、channelという引数が必要です。しかし、2つのメソッドで引数の仕様が少し異なるのです。

まず、chat.postMessageではchannelという引数にチャンネルIDかチャンネル名を指定できます。ちなみに、slackでは、ワークスペース内でチャンネル名がユニークなのでチャンネル名でもチャンネルIDでも一意のチャンネルを特定できるし、どっちでもいいかという思いで、私はチャンネル名で実装していました。
それに対し、chat.updateでは引数channelに、チャンネル名を設定できず、チャンネルIDを設定しなければいけません。
chat.updateはchat.postMessageと同じ使い勝手でいけるんじゃない？と思って、chat.postMessageのコードをコピペしてちょちょっと変えただけの私はつまづきました。

### 2. 引数のslackのタイムスタンプはtsである。
次はタイムスタンプを渡す引数にトラップがありました。
chat.postMessageでは引数に、返信したいスレッドのタイムスタンプを設定する（キーワード引数で渡す）ことで、スレッドに返信することが出来ます。
そして、chat.updateでは引数に編集したいメッセージのタイムスタンプを設定する（キーワード引数で渡す）ことでメッセージを編集することが出来ます。
どちらもタイムスタンプを渡せばいいんだね！と思ったのですが、前者は「thread_ts」という名前の引数で、後者は「ts」という名前の引数でした。
言われてみれば、chat.postMessageの方は「ts」よりも「thread_ts」の方が正確な命名のように聞こえますが、「ts」でいいやんと思ってしまいました（小声）。
chat.updateメソッドの中身を読んで、ようやくtsやん...と気づきました。

### 3. ブロックの内容を上書くときは、ブロックで上書く
私がやろうとしていたことは、chat.postMessageでブロックを引数として投稿したメッセージの内容をchat.updateで上書くということです。更新後のメッセージは単なるテキストだったので、シンプルにchat.updateでtextを引数で渡していました。が、中身更新されない。
確かによく考えればそうかもしれないです。既存のを上書くには同じ構造で上書かないといけないです。

chat.postMessageを用いてブロックで組み立てた内容を送信したメッセージを、テキストで上書こうとした結果、chat.updateのリスポンスとして以下のようなものが返ってきました。これを見てみると、`response[:text]`には変更後のメッセージがちゃんと入っているのですが、`response[:message][:block]`には変更前の内容が残っているのが分かります。このように、ブロックで組み立てた内容をテキストで上書くとうまくいきません。ブロックはブロックで上書きましょう。

```ruby:ブロックをテキストで上書いた時
{"ok"=>true,
 "channel"=>"xxx",
 "ts"=>"xxx",
 "text"=>"変更後のメッセージ",
 "message"=>
   {"bot_id"=>"xxx",
    "type"=>"message",
    "text"=>"変更後のメッセージ",
    "user"=>"xxx",
    "app_id"=>"xxx",
    "blocks"=> [変更前のブロック内容],
    "team"=>"xxx",
    "bot_profile"=> {...},
    "edited"=>{"user"=>"xxx", "ts"=>"xxx"},
    "thread_ts"=>"xxx",
    "reply_count"=>1,
    "reply_users_count"=>1,
    "latest_reply"=>"xxx",
    "reply_users"=>["xxx"],
    "is_locked"=>false,
    "subscribed"=>false}}
```

```ruby:ブロックをブロックで上書いた時
{"ok"=>true,
 "channel"=>"xxx",
 "ts"=>"xxx",
 "text"=>"変更後のテキスト内容",
 "message"=>
   {"bot_id"=>"xxx",
    "type"=>"message",
    "text"=>"変更後のテキスト内容",
    "user"=>"xxx",
    "app_id"=>"xxx",
    "blocks"=>
      [{"type"=>"section",
        "block_id"=>"bst",
        "text"=>
          {"type"=>"mrkdwn",
           "text"=>"変更後のテキスト内容",
           "verbatim"=>false}}],
    "team"=>"xxx",
    "bot_profile"=> {...},
    "edited"=>{"user"=>"xxx", "ts"=>"xxx"},
    "thread_ts"=>"xxx",
    "reply_count"=>1,
    "reply_users_count"=>1,
    "latest_reply"=>"xxx",
    "reply_users"=>["xxx"],
    "is_locked"=>false,
    "subscribed"=>false}}
```

## 最後に
今回はslackのchat.updateを使ってスッと行かなかったところをメモしました。結局公式を読むのが正義ですね。

## 参考

・[chat.updateメソッドについて](https://api.slack.com/methods/chat.update)
・[chat.postMessageメソッドについて](https://api.slack.com/methods/chat.postMessage)
エンジニアとしてGPTによってなくなる仕事、生まれる仕事

以下はChatGPTに対してブラッシュアップしながら自動作成した内容です。


## GPTによってなくなる仕事
### 1. ルーチンワーク

GPTは自然言語処理によって文章の自動生成や分類を可能にするため、エンジニアが行っていたルーチンワークの一部を自動化することができるようになります。例えば、ドキュメント作成やコードのコメント追加などの作業は、GPTが行うことができます。このため、これらの作業に関するエンジニアの仕事がなくなる可能性があります。

### 2. 設計

GPTは自然言語処理によって文章の生成を行うことができるため、コードの設計や要件定義の作業を自動化することも可能です。これにより、エンジニアが行っていた設計の一部をGPTに任せることができます。しかし、これらの作業にはエンジニアの経験や知識が必要であり、完全に自動化することはできないため、エンジニアの設計に関する仕事は減る可能性があるものの、完全になくなるわけではありません。

### 3. シンプルなテスト

GPTは自然言語処理によって文章の自動生成を行うことができます。これにより、エンジニアが行っていたテストの一部を自動化することができる可能性があります。例えば、テストケースの生成や自動テストの実行などをGPTに任せることができます。しかし、テストに関しては、自動化することが難しいとされており、完全に自動化することはできないため、エンジニアのテストに関する仕事は減る可能性があるものの、完全になくなるわけではありません。

## GPTによって生まれる仕事

### 1. GPTの開発や設計

GPTを活用するためには、GPT自体の開発や設計が必要です。これにより、GPTの導入や運用に関する仕事が生まれる可能性があります。また、GPTをより効率的に活用するために、GPT自体を改良する研究開発が必要となるため、GPTの開発や設計に関する仕事が生まれます。

### 2. GPTを活用した業務の設計・改善

GPTを活用した業務の設計・改善に関する仕事が生まれる可能性があります。GPTは文章の自動生成や分類を行うことができますが、その活用方法は多岐に渡ります。例えば、カスタマーサポートやFAQ、マーケティングなど、業務の多くでGPTを活用することができます。そのため、エンジニアがGPTを活用した業務の設計・改善を行う仕事が増える可能性があります。

### 3. GPTの保守・運用

GPTを導入することで、自動生成された文章や分類結果の品質を維持するためには、GPT自体の保守・運用が必要です。GPTは大量のデータを学習するため、運用中にエラーやトラブルが発生する可能性があります。そのため、GPTの保守・運用に関する仕事が生まれる可能性があります。

### 4. AIによる業務自動化の設計・改善

GPTを活用した業務自動化は、AIによる業務自動化の一例です。GPT以外のAI技術を活用した業務自動化も増加しており、そのための設計や改善に関する仕事が増える可能性があります。

## まとめ

GPTはエンジニアの仕事にも影響を及ぼす技術です。ルーチンワークやテストに関する仕事は自動化される可能性がありますが、設計に関する仕事は完全には自動化されず、設計の一部をGPTに任せることができるようになると予想されます。一方で、GPT自体の開発や設計、GPTを活用した業務の設計・改善、GPTの保守・運用など、新たな仕事も生まれることが予想されます。GPTの活用によって、エンジニアの仕事は変化していくことになるでしょう。
特許分類を日本語に置き換えてみる（その２）

# はじめに

下記の記事では、Fタームを使用してバブルチャートを作成してみました。

https://qiita.com/ip_design/items/33ac06773ce9e92d9750

このバブルチャートは、いわゆるマトリクスの形式なのですが、縦軸、横軸の軸項目が20個くらいあるので、一目で理解しにくい図となっております。今回は、この軸項目を減らす作業をしたいと思います。

# やりたいこと
軸項目を減らす方法としては、単純に軸項目を削ることが考えられますが、今回は、軸項目のグループをつくり、そのグループ名で軸項目を置き換えることにより、軸項目を減らしたいと思います。

# 軸項目のグループの作成法
グループの作成法はいろいろあると思いますが、今回はGPT-4へ丸投げすることにより、課題軸、解決手段軸についてそれぞれ５つのグループにまとめたいと思います。GPT-4は分類するだけでなく、グループの名称も考えてくれるので、とても楽です。

以下が、GPT-4が分類した課題と解決手段のグループとなります。
```
課題のグループ

1.水との関係性
'吸水性','親水性','透水性','撥水性','逆流防止','水分解性'
2.物質の拡散・通過性
'通気性','拡散性','光透過性'
3.形状と構造の変化性
'嵩高','膨張性','伸張性','伸縮性' 
4.物質の強度・安定性
'剛性','密度','接着性','分解性'  
5.感触と保護性能
'風合','保温性' 

解決手段のグループ

1.素材のタイプ 
'繊維材料','紙','不織布','合成繊維','パルプ','織編物','合成樹脂','ポリマー' 
2.形状・構造' 
'シート状','スポンジ状','弾性材料','高吸収性材料'
3.処理・改質
'表面処理','化学的処理','処理変性'
4.接着・固定化
'接着剤','薬剤','凝血剤'
5.機能性添加物 
'脱臭剤','活性炭','抗菌剤','香料','潤滑剤'
```
# プログラム
上記グループに置き換えるプログラムを追加します。具体的にはグループ化の辞書を新たに作成し、Fタームを日本語化した辞書をupdateしてゆきます。コードは以下の通りです。
```python
# 課題グループ化の辞書
input_dict1 = {item: '水との関係性' for item in ['吸水性','親水性','透水性','撥水性','逆流防止','水分解性']} 
input_dict1.update({item: '物質の拡散・通過性' for item in ['通気性','拡散性','光透過性']})
input_dict1.update({item: '形状と構造の変化性' for item in ['嵩高','膨張性','伸張性','伸縮性']}) 
input_dict1.update({item: '物質の強度・安定性' for item in ['剛性','密度','接着性','分解性']})  
input_dict1.update({item: '感触と保護性能' for item in ['風合','保温性']})  

# 解決手段グループ化の辞書
input_dict2 = {item: '素材のタイプ' for item in ['繊維材料','紙','不織布','合成繊維','パルプ','織編物','合成樹脂','ポリマー']} 
input_dict2.update({item: '形状・構造' for item in ['シート状','スポンジ状','弾性材料','高吸収性材料']})
input_dict2.update({item: '処理・改質' for item in ['表面処理','化学的処理','処理変性']}) 
input_dict2.update({item: '接着・固定化' for item in ['接着剤','薬剤','凝血剤']})  
input_dict2.update({item: '機能性添加物' for item in ['脱臭剤','活性炭','抗菌剤','香料','潤滑剤']})  

# mapメソッドを使用して分類をグループに置き換える
df_fterm.loc[:, '課題'] = df_fterm['課題'].map(input_dict1)
df_fterm.loc[:, '解決手段'] = df_fterm['解決手段'].map(input_dict2)
# データフレーム確認
print(df_fterm)
```
下が生成されたデータフレームです。うまく5×5のマップになるような気がします。
```
           課題    解決手段  Counts
0   形状と構造の変化性   処理・改質       1
1   形状と構造の変化性   形状・構造     439
2   形状と構造の変化性  接着・固定化     108
3   形状と構造の変化性  機能性添加物       9
4   形状と構造の変化性  素材のタイプ     345
5     感触と保護性能   処理・改質       6
6     感触と保護性能   形状・構造      82
7     感触と保護性能  接着・固定化      51
8     感触と保護性能  機能性添加物      14
9     感触と保護性能  素材のタイプ     279
10     水との関係性   処理・改質      56
11     水との関係性   形状・構造     176
12     水との関係性  接着・固定化      95
13     水との関係性  機能性添加物      86
14     水との関係性  素材のタイプ     947
15  物質の強度・安定性   処理・改質       8
16  物質の強度・安定性   形状・構造     283
17  物質の強度・安定性  接着・固定化     217
18  物質の強度・安定性  機能性添加物      62
19  物質の強度・安定性  素材のタイプ     569
20  物質の拡散・通過性   処理・改質       5
21  物質の拡散・通過性   形状・構造     128
22  物質の拡散・通過性  接着・固定化      54
23  物質の拡散・通過性  機能性添加物      32
24  物質の拡散・通過性  素材のタイプ     393
```
下が生成された特許マップです。5×5のマップになりましたので、軸項目を減らすことができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3110569/67a68268-e01d-b7ce-4882-dc3b31a51c90.png)
# 感想
このグループ作りについては、GPT-3.5ではあまりうまくゆかなかったのですが、GPT-4ではうまくゆくようになりました。もう少しGPT-4を使っていろいろ試したいと思います。

また、グループ化やグループの名称を考えることは、面倒な作業でしたが、これからはGPT-4にたたき台を作ってもらえるようになりましたので、格段に作業が楽になりました。今後も活用したいと思います。
【Rust】unwrapと?の違い

## 概要
`unwrap`と`?`は、Rustにおいてエラーハンドリングに使用される2つの異なる方法です。

## unwrap
`unwrap`は、`Option`型や`Result`型の値が`Some`や`Ok`であることを前提として、値を取り出します。

もし`None`や`Err`だった場合は、`panic!`マクロが呼ばれてプログラムがクラッシュします。

つまり、`unwrap`はエラーハンドリングではなく、プログラムの実行中に予期しないエラーが発生した場合にのみ使用するべきです。

## ?
一方、`?`は、`Result`型の値を扱う際に使用される演算子で、エラーハンドリングに使用されます。

`?`演算子は、左側の式が`Ok`の場合は値を返し、`Err`の場合はその`Err`を呼び出し元に返します。

つまり、`?`演算子は、エラーが発生した場合にそのエラーを呼び出し元に伝えることができます。

`?`演算子は、`Result`型の値を安全に取り出すための方法であり、`unwrap`よりも安全で、より堅牢なコードを書くことができる認識です。
Lightning でのナレッジ記事の印刷


+ [Printing a Knowledge Article in Lightning](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000OsAfG)

色々な方法が提案されています。

+ css

また、印刷メディアを対象とする CSS を実装し、ユーザーがブラウザーで印刷をクリックしたときに特定のスタイルを適用することもできます。

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Bswi5SAB

[ナレッジ記事のコミュニティに印刷ボタンを追加](https://ideas.salesforce.com/s/idea/a0B8W00000GdituUAB/add-print-button-to-community-for-knowledge-articles)

+ アプリ

https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3u00000MSqd​​FEAT

+ 設定がある？

顧客に PDF を送信するために印刷しようとしていますか? 実装ガイドの 31 ページの「記事をメールに挿入」を使用できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/509d1e2a-d63a-aeec-0373-f97634631ff7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/221fe4e9-015e-ab67-322e-101a4ea87959.png)

+ ロードマップにはある？

今後更新される ナレッジ用のLightning Article Editor には、 記事を PDF としてエクスポートする機能が搭載される予定です。次のリリースでベータ版として登場するはずです

+ [Lightning Article Editor Beta Experience Spring'24 記事全体の印刷可能なビュー、完全なビューと PDF への印刷オプションの必要性について、このアイデアに賛成票を投じてください:](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007OYLjw)
【Rust】unwrap, unwrap_or, unwrap_or_elseの違い

## 概要
Rustには、Option型やResult型のようなエラーを表現する型があります。
これらの型は、値が存在しない（None）場合やエラーが発生した場合に、それを処理するためのメソッドを提供しています。
その中でも、unwrap、unwrap_or、unwrap_or_elseはよく使われます。

## unwrap
Option型やResult型の値がSomeやOkであることを前提として、値を取り出します。
もしNoneやErrだった場合は、panic!マクロが呼ばれてプログラムがクラッシュします。
つまり、使用に際してはその型が必ず値を持っていることが保証されている場合に使用するべきです。

## unwrap_or(default: T)
Option型やResult型の値がSomeやOkであれば、その値を取り出します。
もしNoneやErrだった場合は、指定されたデフォルト値を返します。
引数には、デフォルト値として使用する値を指定します。

## unwrap_or_else(f: FnOnce() -> T)
Option型やResult型の値がSomeやOkであれば、その値を取り出します。
もしNoneやErrだった場合は、指定されたクロージャーを実行し、その結果を返します。
引数には、デフォルト値を生成するためのクロージャーを指定します。
このクロージャーは、値が必要になった場合にのみ呼び出されます。

## まとめ
これらのメソッドは、Option型やResult型の値を安全に取り出すための方法を提供します。
unwrapは、値が必ず存在することが保証されている場合に使用するべきです。
unwrap_orは、デフォルト値を指定することで、値が存在しない場合の処理を安全に行うことができます。
unwrap_or_elseは、デフォルト値を生成するためのクロージャーを指定することで、値が必要になった場合にのみデフォルト値を生成することができます。
2023年04月何故かベストアンサーをつけてくれない質問

[2023年4月の質問の中から整理します](https://qiita.com/Keiji_otsubo/items/ff507f99e677abe9768f)

# トレイルヘッド

+ [Not seeing the New option in the Add an Upcoming Reservation to Your Prediction section of the Einstein Preiction Builder course](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Jgxjt)

:::note
Check if the New button is hidden

https://automationchampion.com/2022/02/27/how-to-hide-the-standard-new-button-from-list-view/
:::

:::note
The answer did not really help me. I solved the issue by going out of the lightning GUI and using the old one. Then, I could see the Reservation object.
:::

+ [Can't find a new Product Support case for Pyramid Construction](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000JgyLH)

:::note
Go to Object Manager-->Cases-->Record Type-->Product Support--> Under Picklists Available for Editing Click edit next to Type-->Add Problem to Selected Values--> Create a new case with Type Problem.

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000BuSCk
:::

+ [Toda vez que crio um playground novo tenho que instalar todos os pacotes que me interessam, mesmo os já instalados em outros playgrounds?](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000JgzsT)

:::note
I don't think it's necessary unless there's a challenge or module advocating for installing a package.
:::

+ [Not Getting Recruiting on app launcher](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000PePup)


# レポート

+ [Display of a text picklist value as a numeric value in a report](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Osrpa)
cscの作法 その300

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
ラズベリーパイpico用のプログラムランチャーを実装せよ。

# 方針
- ctrl+eを使う。
- ctrl+dを使う。
- ボーレイトは、115200
- シリアルポートは、COM3
- delegate使う。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/6358d566-ab1c-6580-c081-b1ad50c09ca7.png)


# サンプルコード

```





using System;
using System.Windows.Forms;
using System.Drawing;
using System.IO.Ports;
using System.Text;
using System.Threading;

class form1: Form {
	private Button button1;
	private TextBox textBox0;
	private TextBox textBox1;
	private static TextBox textBox2;
	private SerialPort port1;
	form1() {
		Text = "program launcher";
		ClientSize = new Size(800, 400);

		button1 = new Button();
		button1.Location = new Point(700, 20);
		button1.TabIndex = 0;
		button1.Text = "send";
		button1.Click += new EventHandler(button1_Click);

		textBox0 = new TextBox();
		textBox0.Location = new Point(30, 20);
		textBox0.Multiline = true;
		textBox0.Size = new Size(300, 300);
		textBox0.TabIndex = 2;
		textBox0.Text = @"led = machine.Pin(25, machine.Pin.OUT)";

		textBox1 = new TextBox();
		textBox1.Location = new Point(30, 340);
		textBox1.Multiline = false;
		textBox1.Size = new Size(300, 20);
		textBox1.TabIndex = 2;
		textBox1.Text = @"led.toggle()";

		textBox2 = new TextBox();
		textBox2.Location = new Point(400, 80);
		textBox2.Multiline = true;
		textBox2.Size = new Size(300, 300);
		textBox2.TabIndex = 2;
		textBox2.Text = @"";

		port1 = new SerialPort("COM3", 115200, Parity.None, 8, StopBits.One);
		port1.BaudRate = 115200;
		port1.Parity = Parity.None;
		port1.DataBits = 8;
		port1.StopBits = StopBits.One;
		port1.Handshake = Handshake.None;
		port1.PortName = "COM3";
		port1.Encoding = System.Text.Encoding.ASCII;
		port1.NewLine = "\r\n";
		port1.DtrEnable = true;
		port1.RtsEnable = true;
		port1.DataReceived += new SerialDataReceivedEventHandler(DataReceived_Handler);
		port1.Open();
		Controls.AddRange(new Control[] {
			button1,
			textBox0,
			textBox1,
			textBox2
		});
	}
	private void button1_Click(object sender, EventArgs e) {
		string s = "e";
		byte[] array = Encoding.UTF8.GetBytes(s);
		array[0] = 5;
		string ctrl_e = Encoding.UTF8.GetString(array);
		array[0] = 4;
		string ctrl_d = Encoding.UTF8.GetString(array);
		string msg;
		msg = ctrl_e + textBox0.Text + "\r\n\r\n" + ctrl_d + textBox1.Text;
		port1.WriteLine(msg);
		//textBox1.Text = "";
		Console.WriteLine(msg);
	}
	private delegate void SetTextDelegate(string msg);
	private static void SetText(string msg) {
		textBox2.Text = msg;
	}
	private void DataReceived_Handler(object sender, SerialDataReceivedEventArgs e) {
		SerialPort sp = (SerialPort) sender;
		string msg = sp.ReadExisting();
		Console.Write(msg);
		this.Invoke(new SetTextDelegate(SetText), new object[] { msg });
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}





```

# 実行結果

```
>pico5
led = machine.Pin(25, machine.Pin.OUT)

led.toggle()

```

以上。
【解決】配布ポイントを利用したOffice LTSC 2021のアップデートで「今すぐ更新」ができない

配布ポイントを利用したOffice LTSC 2021のアップデートで「今すぐ更新」ができない。

家でテストすると問題ないのに、職場でテストするとエラーが出るのはなんなのか…。OSのライセンス関連かな。

・下記は配布ポイントに配置したファイルをダウンロードする際に利用したconfiguration.xml
```configuration.xml
<Configuration ID="c3436ece-ea4e-431c-bcd6-0c7d221a3284">
　<Add OfficeClientEdition="64" Channel="PerpetualVL2021" Version="16.0.14332.20481" SourcePath="C:\officeUpdate" AllowCdnFallback="FALSE">
　　<Product ID="ProPlus2021Volume" PIDKEY="FXYTK-NJJ8C-GB6DW-3DYQT-6F7TH">
　　　<Language ID="ja-jp" />
　　　<ExcludeApp ID="OneDrive" />
　　　<ExcludeApp ID="Teams" />
　　　<ExcludeApp ID="Lync" />
　　　<ExcludeApp ID="OneNote" />
　　　<ExcludeApp ID="Publisher" />
　　　<ExcludeApp ID="Access" />
　　</Product>
　　<Product ID="LanguagePack">
　　　<Language ID="ja-jp" />
　　</Product>
　</Add>
　<Property Name="SharedComputerLicensing" Value="0" />
　<Property Name="FORCEAPPSHUTDOWN" Value="FALSE" />
　<Property Name="DeviceBasedLicensing" Value="0" />
　<Property Name="SCLCacheOverride" Value="0" />
　<Property Name="AUTOACTIVATE" Value="1" />
　<Updates Enabled="TRUE" UpdatePath="C:\officeUpdate" />
　<Display Level="Full" AcceptEULA="TRUE" />
</Configuration>
```

【追記】
原因がわかった。
「setup /download configuration.xml」する際に、configuration.xml の中でダウンロードするOfficeのバージョンを **指定してはいけなかった。**

バージョンを指定してダウンロードしたファイルを配布ポイントに配置した場合、Officeの更新で「今すぐ更新」が使えなくなる。
バージョンを指定した場合と、指定しない場合の差はダウンロードしたファイルに「v64.cab」が含まれるか含まれないか。

いやー、罠だったわ～。最新のファイルをダウンロードしたい場合はバージョンを指定しなくて良し！

参考
https://kojikoji75.hatenablog.com/entry/2019/09/07/225036
エンジニアとして知っておこう・情報セキュリティとは

未経験からエンジニアになりたい人は、プログラミングから始める人が多いと思いますが、
エンジニアの仕事は、プログラミングだけではありません。そして、プログラミングだけでは、エンジニアになれません。同時にプログラミングが苦手でも、システム構成や開発の流れを理解するとエンジニアに近づきます！
![インスタスライド_2023031704.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/6cd4e176-590f-4300-0460-1bf39ff34930.gif)


今回は具体的な情報セキュリティについて更に詳しく調べてみましょう！
# 情報セキュリティとは
情報セキュリティとは、
機密性（Confidentiality)
一貫性（Integrity)
可用性(Availability)

を維持すること

｢情報のCIA｣と呼ばれる
# 機密性とは
許可されたものが許可された時間のみ、許可された権限に従ってアクセスできる事
# 一貫性とは
情報が正確で、改ざんや破壊される事なく完全に維持される事
情報自体が誰にいつ、送信・受信されたかの確認が可能な事
# 可用性とは
コンピュータシステムが効率よく安定稼働し、障害が発生しても中断する事なく、利用し続ける事ができる事。
# まとめ
情報セキュリティとは、

- 機密性（Confidentiality)
- 一貫性（Integrity)
- 可用性(Availability)

を維持すること

# 最後に
未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
Python3 getch()関数


pythonによるgetch()関数。
一文字キー入力待ちの関数です。

```getch.py
#!/usr/bin/python3
import sys,tty
import termios

def getch():
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    tty.setraw(sys.stdin.fileno())
    ch = sys.stdin.read(1)
    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    return ch

# ここからテスト

while True:
    key=getch()
    if key==chr(3):
        break
    print(key,end='',flush=True)
exit(0)
```

これが元の関数
```getch.c
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <getch.h>

int getch(){
      struct termios oldt, newt;
      int c;
      tcgetattr( STDIN_FILENO, &oldt );
      newt = oldt;
      newt.c_lflag &= ~ICANON;
      newt.c_lflag &= ~ECHO;
      tcsetattr( STDIN_FILENO, TCSANOW, &newt );
      c = getchar();
      tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
      return c;
}
```
2023/4/4主にITとかセキュリティの記事

【特別企画】経営者と現場で認識にギャップも、見逃される「API」のリスクとどう向き合うか
https://www.security-next.com/144053

マイナポイント事務局を偽るフィッシング確認、注意を(4/2)
https://news.mynavi.jp/techplus/article/20230402-2641622/

情報通信政策に関する記事のまとめ(2023.3.27～2023.4.2）
https://blogs.itmedia.co.jp/business20/2023/04/2023327202342.html?ref=rss

GPD WINシリーズの新モデルはクラムシェル型に？／Windows標準のスクショ撮影機能の脆弱性を修正(4/2)
https://news.yahoo.co.jp/articles/67013b7bd15ea3f86005476561a9d9c6bccd40ea?source=rss

米国議会はTikTokの何を問題視したのか。(4/1)
https://tamakino.hatenablog.com/entry/2023/04/02/080000

オープンイノベーションを阻害する技術情報流出をセルフチェック！情報セキュリティ対策に関する国の認証の取得に役立ちます(4/2)
https://www.jiji.com/jc/article?k=000000061.000082634&g=prt

自動運転「レベル４」解禁＝自家用車は対象外―改正道交法施行(4/1)
https://www.risktaisaku.com/articles/-/78092

中途採用の強化でデジタル人材を4倍超に、パーソルは事業創出の担い手求む
柘植 悠太 氏　パーソルホールディングス 執行役員CIO/CDO(4/3)
https://xtech.nikkei.com/atcl/nxt/column/18/01159/030700042/

検索サイトの広告に潜む脅威(4/3)
https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/111900071/031600042/
【激ムズ！】pikalangでHello World!出力してみた

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2586059/59e250a7-bebb-22e3-e51a-f10e49a80643.png" width="70%">

# PikaLangとは？
https://github.com/groteworld/pikalang

Pokémonのピカチュウの語彙に基づくEsoteric programming languageです！

# 書き方
次のコードを上から順番に実行する
```terminal:terminal
pip install pikalang
git clone https://github.com/grotewold/pikalang.git
cd pikalang
python setup.py install
```
`run.pokeball`というファイルを作成する
```run.pokeball
pi pi pi pi pi pi pi pi pi pi pika pipi pi pi pi pi pi pi pi pipi pi pi
pi pi pi pi pi pi pi pi pipi pi pi pi pipi pi pichu pichu pichu pichu ka
chu pipi pi pi pikachu pipi pi pikachu pi pi pi pi pi pi pi pikachu
pikachu pi pi pi pikachu pipi pi pi pikachu pichu pichu pi pi pi pi pi
pi pi pi pi pi pi pi pi pi pi pikachu pipi pikachu pi pi pi pikachu ka
ka ka ka ka ka pikachu ka ka ka ka ka ka ka ka pikachu pipi pi pikachu
pipi pikachu
```
実行
```terminal:terminal
pikalang run.pokeball
```
```terminal:結果
>> Hello World!
```
# 最後に
具体的な中身は解読不能でした:information_desk_person_tone1:
わかる方いれば教えて欲しいです！！
zsh compinit: insecure directories and filesをファイルの権限を変えずに黙らせる

Mac OS Ventura 13.1でアカウントが2つある状況で、1つ目のアカウントでhomebrewを使ってインストールしたzshを2つ目のアカウントで使うとワーニングが出た。

```
zsh compinit: insecure directories and files, run compaudit for list.
Ignore insecure directories and files and continue [y] or abort compinit [n]?
```

ググると `compaudit` を行い、これらのディレクトリの権限がよくないので適切な権限に変えればよいらしい。
`chmod` や `chown` を使って権限を変更したら確かにエラーは出なくなったのだが、1つ目のアカウントでbrewでzshをアップデートできなくなってしまったので、仕方なく元に戻した。

そもそもなんで怒られるのだろう？

> For security reasons compinit also checks if the completion system would use files not owned by root or by the current user, or files in directories that are world- or group-writable or that are not owned by root or by the current user.

https://github.com/zsh-users/zsh-completions/issues/680#issuecomment-588003627

なるほど。書き込み権限を適切にしても変わらずワーニングが出るので、ワーニングが出るディレクトリの所有者がrootでも今のユーザーでもないのがいけないっぽい。

> To avoid these tests and make all files found be used without asking, use the option -u, and to make compinit silently ignore all insecure files and directories use the option -i. This security check is skipped entirely when the -C option is given.

どうも `compinit` にはいくつかオプションがあり、このワーニングを無視できるそう。自分のzshrcを見ると `-u` でcompinitを呼んであった。

```
autoload -Uz compinit && compinit -u
```

上記のドキュメント読んだ感じでは、 `-u` でも `-i` でも `-C` でもワーニング無視してくれそうに見えるが、全部試したところ、 `-i` のみワーニングを抑制してくれた。

```diff
-autoload -Uz compinit && compinit -u
+autoload -Uz compinit && compinit -i
```

なぜうまくいったのかはよくわからないけれど、ディレクトリの所有者が2つ目のアカウントのユーザーでないので怒られるのは問題ないと思うので、しばらくワーニングを無視で使ってみる。

参考
* [The Z Shell Manual - 20 Completion System](https://zsh.sourceforge.io/Doc/Release/Completion-System.html)

https://github.com/zsh-users/zsh-completions/issues/433

https://github.com/zsh-users/zsh-completions/issues/680
【TypeScript】インデックスシグネチャのキーに変数を設定したい

## 概要
インデックスシグネチャは[インデックスシグネチャ](https://zenn.dev/tsuboi/articles/ee43ddc5a2cd941de138)の記事にある通り、連想配列のような用途などでobject型を用いるものになります。
今回はこのインデックスシグネチャで、キーに変数を設定する場合に、どのように書けばよいかをメモ書きします。

## 実装例
以下のように、キー設定する変数を`[]`で囲みます。

```ts
const indexSignatureKeyType = () => {
  const key = { key1: "key1", key2: "key2", key3: "key3" };
  const sampleObj = {
    [key.key1]: 1,
    [key.key2]: 2,
    [key.key3]: 3,
  };
  // 1が取得できる
  const sample1 = sampleObj[key.key1];
  console.log(sample1);
}
```

## その他参考
[【TypeScript】インデックスシグネチャのオブジェクトで存在しないキーを指定した時の動作](https://qiita.com/someone7140/items/1ea1c312166efc003971)
C#でiText7を使ってPDFファイルのページ分割・結合をする

C#でiText7を使う
---
C#でiText7を使ってPDFファイルのページ分割と結合をやってみました。
巷ではiTextSharpの情報は見かけるのですが、JavaではなくC#のiText7の記事が少ないと思い書いてみました。

iText7はiTextSharpの後継版で、.NET6と組み合わせればMacでも使えます。
嬉しいなあ、クロスプラットフォーム:bangbang:


動作確認は、
* macOS Ventura 13.2
* .NET6
* Visual Studio for Mac 17.5 Preview
* iText7 7.2.5
![スクリーンショット 2023-04-03 22.52.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294209/36e78d95-feb3-befa-eb7d-bdc6b2bae40d.png)

で行いました。

ページの分割
---
以下、ちょっと難のあるサンプルですが、使い方の理解を目的に書いてみました。
まず、**9ページのパスワード無しのPDFファイル**を用意します。それを適当なディレクトリに置いてください。ここではホームーディレクトリに置くことにしました。

Macで試したのでファイルパスはMac用です。Windowsでもファイルパスを適切に書き換えれば問題なく動作します。
1〜3ページ、4〜7ページ、8〜9ページ、と3つのPDFファイルに分割を行います。
元ファイルの`hoge.pdf`は、`hoge1.pdf`、`hoge2.pdf`、`hoge3.pdf`に分割されます。



```C#
using iText.Kernel.Pdf;

public void SplitPdfPages() // ページ分割
{
    string sourcePdfPath = "/Users/mackohei/hoge.pdf";
    using PdfReader pdfReader = new(sourcePdfPath);
    using PdfDocument srcPdfDoc = new(pdfReader);
    int i = 1;
    int firstPage = 1;
    int[] lastPages = { 3, 7, 9 };
    foreach (int lastPage in lastPages)
    {
        string destPdfPath = "/Users/mackohei/hoge" + i.ToString() + ".pdf";
        using PdfWriter pdfWriter = new(destPdfPath);
        using PdfDocument destPdfDoc = new(pdfWriter);
        srcPdfDoc.CopyPagesTo(firstPage, lastPage, destPdfDoc);
        firstPage = lastPage + 1;
        i++;
    }
    File.Delete(sourcePdfPath);
}
```

読み込み用`PdfDocument`の`CopyPagesTo`メソッドで、書き込み用`PdfDocument`にコピーを行います。
### CopyPagesTo メソッド
PDFファイルのコピーを作ります。

* **第一引数**　コピーしたい最初のページ番号
* **第二引数**　コピーしたい最後のページ番号
* **第三引数**　書き込み用`PdfDocument`クラス（コピー先のPDFファイル）
<br />


最後に、読み込み用としていたコピー元ファイルを削除します。


ページの結合
---
結合も基本的に分割と同様です。読み込み用`PdfDocument`の全てのページを書き込み用`PdfDocument`にコピーするだけです。書き込みの際、書き込み用`PdfDocument`に既にページがあれば、後ろに追加されます。
先ほどの分割メソッドで作られた3つのファイル、`hoge1.pdf`、`hoge2.pdf`、`hoge3.pdf`は、この結合メソッドを実行することで`hoge.pdf`に結合されます。


```C#
public void MergePdfPages() // ページ結合
{
    string destPdfPath = "/Users/mackohei/hoge.pdf";
    using PdfWriter pdfWriter = new(destPdfPath);
    using PdfDocument destPdfDoc = new(pdfWriter);
    for(int i = 1; i <= 3; i++)
    {
        string sourcePdfPath = "/Users/mackohei/hoge" + i.ToString() + ".pdf";
        using (PdfReader pdfReader = new(sourcePdfPath))
        using (PdfDocument srcPdfDoc = new(pdfReader))
        {
            srcPdfDoc.CopyPagesTo(1, srcPdfDoc.GetNumberOfPages(), destPdfDoc);
        }
        File.Delete(sourcePdfPath);
    }
}
```

二つのメソッドを交互に繰り返し実行すると、ファイルが3つに分かれたり1つに戻ったりします。
（しょーもな:sweat_smile:）

本当に限定的な状況下でのサンプルコードですが、目的に合わせて書き換えれば、色々と活用できると思います:rocket:

https://kb.itextpdf.com/home/it7kb/ebooks/itext-7-jump-start-tutorial-for-net
【Dockerの知識を整理】DockerとDocker Composeを使ったWebアプリの開発環境構築について

# はじめに
### 本記事を読んでほしい方
- Docker, Docker Composeを学んだが知識があまり整理されていない初学者

本記事ではDockerとDocker Composeを使ったWebアプリの開発環境構築について、知識を整理するため簡単に説明していきます。Dockerfileやdocker-compose.ymlの詳細な記述の仕方については[他記事](https://docs.docker.jp/compose/rails.html)を参考にしてください。


### Dockerとは？
Webアプリケーションを開発する際の開発環境、本番環境、テスト環境を構築できる仕組みのことです。プロジェクト単位で環境構築を行うため、ある人の開発マシンではプログラムが動くけど、ある人は動かないという問題が発生しないという利点があります。Linuxの仮想コンテナを立ち上げ、その中で開発を行います。


# Docker, Docker Composeを使った Webアプリの開発環境構築
１つのコンテナには1つのアプリケーションのみ配置できるという原則があります。しかし、通常Webアプリケーションの開発環境を作るには、アプリケーションのフレームワーク+データベース等、複数のコンテナを用意しなければなりません。(例:Ruby on Rails + PostgreSQL)
そこで、Docker Composeを活用するのです。Docker Composeは、Yamlファイルの内容に沿って、複数のコンテナを立ち上げることができます。

Dockerでの開発環境の構築の際に必要なファイルは以下の通りです。
- Dockerfile (Docker imageを作成し、コンテナを起動するためのファイル)
- docker-compose.yml (コンテナの立ち上げ方について記述するためのファイル)
- database.yml (データベースを別で使用する場合、編集するファイル)

実際にDocker + Docker Composeを使った環境構築の方法を説明していきます。まず、Dockerを使って開発環境を構築するにはコンテナを立ち上げる必要があります。このコンテナというものは、Docker imageから作られます。そしてこのDocker imageを作るものがDockerfileです。



わかりにくいと思うので、下に図示します。(DockerfileからDocker imageを作り、Docker imageからコンテナを作ります)
また、DockerfileからDocker imageを作る際は、`docker-compose build`コマンド、Docker imageからコンテナを立ち上げるのが`docker-compose up`コマンドを使います。
![コンテナ作成イメージ図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782490/f072d6fb-904b-fe98-2001-7ec29dd71227.png)


こちらの一連の流れを行うために、上記のDockerfile, docker-compose.ymlを作成し、編集を行っていくのです。

Dockerfile, Docker-compose.ymlの編集の仕方については下記記事をご参照下さい。(Ruby on Railsの場合)
- [Rails/PostgreSQL アプリを設定し実行する手順](https://docs.docker.jp/compose/rails.html)

# まとめ
Dockerを使うことで複数人で開発するプロジェクトの開発環境を一人ひとり揃えることができ、Docker Composeを使うことでWebアプリケーションフレームワーク+データベースのような複数コンテナを起動する場合にも対応することができます。非常に強力なツールですね。

以上で説明を終了します。最後まで読んでいただきありがとうございました！
再開＆今年度の目標

# 1. はじめに
2021年にE資格を取得するために始めたQiitaですが、E資格を途中で挫折し2021年の12月以来全く触ってなかったんだけど、なんやかんやあって今データサイエンティストからデータエンジニアになった。
最近はGoogleCloudとか色々触るようになったんで、それの勉強とか資格取得をしていくための勉強をしているところ。
目標をこういったところで発信したり、あと自分用に色んなことまとめておきたいなと思いQiitaの再開をしようかなとおもってこの記事をかいている

# 2. 今年度の目標
E資格は挫折したけど、これからの目標は下記！！
とりあえずはこの4つが目標だけど、勉強したり業務しながら興味出たりこれ必要だなと思ったら都度追加予定

| #   | Center align |
|:----|:------------:|
| 1   | Associate Cloud Engineer(GoogleCloud)|
| 2   | Professional Cloud Architect(GoogleCloud)| 
| 3   | Professional Data Engineer(GoogleCloud)|
| 4   | AtCoder 水色|

# 3. 今のレベル
- Google Cloud
    - 1か月前から勉強してるレベル
    - 動画で研修見たり実際に少し触った程度
    - すでにACEの勉強開始してるから、ACE程度のレベル

- AtCoder
    - 使用言語はPython
    - 茶色なったばっかり

# 4. 最後に
とりあえずは自己満記事を週1程度は投稿していきたいとおもってる（がんばろ・・）
ACEに関しては今月取得目指してそのあとすぐにPCAとりたい
AtCoderはできるだけ、毎週参加して回答した問題については自分なりの考え方を記載して
コメントとかで他のやり方とか考え方を聞けたら嬉しい(^^)

すべては知識をふやすため
知識を増やすのは仕事をもっといい感じにしていくため
仕事をもっといい感じにしていくのは年収増やすため
1年間で年収100万あげてぇ
資格とりまくれば資格手当で年収50万は増やせる・・・
POP3とIMAPの違い

●POP3とIMAPの違い
POP3もIMAPもリモートサーバ上のメールボックスにアクセスするプロトコルですが、以下の点が大きく異なる。

■POP3（Post Office Protocol - Version3）/POP3S（POP3 over SSL/TLS）
・リモート（サーバ）のメールボックスからローカルにメールをコピーしてくる。基本的にはコピー時に削除を行うため、リモートにメールは残らず、メールをコピーしたローカルのMUAはリモートと切断したオフライン状態でも、ローカルに取得済みのメールにアクセスできる。
・POP3は110/tcpのウェルノウンポートを使用。
・SSL/TLSに対応したPOP3Sは995/tcpを使用。

■IMAP（Internet Message Access Protocol）/IMAPS（IMAP over SSL/TLS）
・メールは基本的にリモート（サーバ）上に保存される。そのためメールボックス内の検索処理もサーバ上で動作することになる。メールをローカルに保存せずに済むので、複数の端末からメールボックスにアクセスしてもメールの処理状況（未読管理など）が変わらない。
・IMAPは143/tcpのウェルノウンポートを使用。
・SSL/TLSに対応したIMAPSは993/tcpを使用。
【Shell】コマンドの実行結果を画面に出力した上でパイプに渡す方法


## はじめに
コマンドの結果をパイプで渡すと以下のようになります。

```zsh
$ ls -a | grep .env
.env
```

上記の`ls -a`の実行結果も画面に表示させる方法について記載します。

## 画面にも表示させる方法
 
コマンドの実行結果を画面とパイプの両方に渡すには以下のように実行します。

```zsh:zsh
$ ls -a >&2 | grep .env
.
..
.DS_Store
.env
.git
.env
```

上記の実行結果の内上から`.git`までが`ls -a`の実行結果です。
最後に再度`.env`と表示されているのが`grep .env`の実行結果になります。

上記の方法はshやbashでは使用できません。

```bash:bash
$ ls -a >&2 | grep .env
.           
..
.DS_Store
.env
.git

$ echo $?
1
```

以下の方法はzshとbashで使用することができます。

```zsh:zshまたはbash
$ ls -a | tee >(grep .env)
.
..
.DS_Store
.env
.git
.env
```
shで実行すると以下のようにエラーとなります。

```sh :sh
$ ls -a | tee >(grep .env)
sh: 1: Syntax error: "(" unexpected
```

以下の方法であればshでも使用可能です。

```
$ ls -a | tee -a /dev/stderr | grep .env
.
..
.DS_Store
.env
.git
.env
```
Partial Custom Tabsを使って、ボトムシートのようにChromeを呼び出す

`androidx.browser:browser:1.5.0`以降、Custom Tabsの機能としてPartial Custom Tabsというものが使えるようになっています。
これを使うと、ボトムシートのようにChrome（ブラウザ）を呼び出すことができるようになります。

https://android-developers.googleblog.com/2023/02/bringing-best-of-chrome-to-android-developers-and-users.html

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/6c7481ee-109a-a43a-f72e-d41cf0bd9ef4.png" width="400" />

使い方は、単にCustomTabsIntent.Builderの[`setInitialActivityHeightPx()`](https://developer.android.com/reference/androidx/browser/customtabs/CustomTabsIntent.Builder#setInitialActivityHeightPx(int))メソッドを使って、ボトムシートの高さ（px単位）を指定するだけです。

```kotlin
val customTabsIntent = CustomTabsIntent.Builder(CustomTabsHelper.session).also {
    builder.setInitialActivityHeightPx(
        resources.getDimensionPixelSize(R.dimen.initial_activity_height),
    )
}.build()
customTabsIntent.launchUrl(this, uri)
```

`setInitialActivityHeightPx()`メソッドは第二引数でボトムシートの挙動を指定することもできます。
ACTIVITY_HEIGHT_DEFAULT / ACTIVITY_HEIGHT_ADJUSTABLE / ACTIVITY_HEIGHT_FIXED
の3種類の値が指定できます。
引数を省略すると、ACTIVITY_HEIGHT_DEFAULTが指定され、この挙動はACTIVITY_HEIGHT_ADJUSTABLEと同一になるようです。

ACTIVITY_HEIGHT_ADJUSTABLEを指定すると、表示された状態からシートを引き上げることができます。ACTIVITY_HEIGHT_FIXEDを指定すると引き上げることはできず、閉じることしかできません。

---

当然ブラウザ側の対応も必要であるため、ブラウザ側が対応していなければ全画面で起動してしまいます。
とはいえ、完全にブラウザに切り替わるのではなく、ボトムシートとしてチラ見せして、ユーザーにブラウザ側に遷移するか、アプリにとどまるかを選択してもらうような使い方ができますね。
現状では確実にこの見せ方ができるという訳ではありませんが、今まで同様のことをやろうと思うと、WebViewを使って独自実装しなければならず、実装コストやメンテナンスコストの高い部分でした、これを外部のブラウザアプリに任せられるようになるのは便利かもしれません。
C++による格子ボルツマン法を用いた二次元キャビティ流れのシミュレーション

# はじめに

前回の記事の続きで、格子ボルツマン法を用いて二次元キャビティ流れをシミュレーションするプログラムをC++で作成してみました。

https://qiita.com/shohirose/items/edd4676b924aa77cff73

https://github.com/shohirose/lbm-simulator/tree/master

使用しているライブラリは前回同様以下の通りです。

- 行列計算：[Eigen](http://eigen.tuxfamily.org/index.php?title=Main_Page)
- JSONファイルの読み込み：[JSON for Modern C++](https://github.com/nlohmann/json)
- コマンドライン解析：[CLI11](https://github.com/CLIUtils/CLI11)
- フォーマット：[{fmt}](https://github.com/fmtlib/fmt)
- 結果の可視化：Jupyter Notebook + matplotlib.pyplot

# 参考文献

https://www.maruzen-publishing.co.jp/item/?book_no=303613

https://www.morikita.co.jp/books/mid/067661

# C++での実装

境界条件以外の部分は、外力項がなくなっただけで、前回とほとんど変わりません。詳細は[cavity_flow_simulator.cpp](https://github.com/shohirose/lbm-simulator/blob/master/src/cavity_flow_simulator.cpp)の`lbm::CavityFlowSimulator::run`関数を参照してください。

境界条件については、瀬田の「格子ボルツマン法」の2.7節と同様にハーフウェイバウンスバックスキームを用いています。実際にプログラムを書いていて、異なる境界条件の影響を受ける角のセルの処理方法について本の中で解説されていなかったことが気になりました。色々試したところあまり影響がなかったので、最終的に特別な処理は行わないこととしました。

衝突則については、Single Relaxation Time (SRT) modelとMultiple Relaxation Time (MRT) modelを実装しました。

# 結果

セル数$n _ x = n _ y = 52$、上面の壁の速度を$u_x=0.1$、レイノルズ数を$\mathit{R\kern-.04em e}=400$として、MRT衝突則を用いて計算したときの速度分布が下図となります。

![cavity_mrt_velocity_cmap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130485/a9de28d2-1413-25a2-12d9-a6c7d55e9352.png)

$x=0.5$および$y=0.5$における$x$・$y$方向速度をプロットしたものが下図となります。

![cavity_mrt_ux_uy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130485/ec928683-ed4b-8a97-124a-76bb0cbc943b.png)

Ghia et al. (1982)[^1]とほぼ同じ結果が得られていることがわかります。

SRT衝突則を用いたときにVisual Studio 2022のパフォーマンスプロファイラーを使って分析した結果は下図です。SIMDやOpenMPは有効にしていない状態での測定結果です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130485/9b571c3b-5120-5050-22c5-3bd0d0fee0a5.png)

平衡分布関数(`calc_equilibrium_distribution_function`)および並進過程(`run_propagation_process`)の計算が全体の58%を占めており、格子ボルツマン法ではこれらの2つの部分の最適化がパフォーマンスの観点で重要であることがわかります。


[^1]: V.Ghia, K.N.Ghia and C.T.Shin. 1982. "High-Re solutions for incompressible flow using the Navier-Stokes equations and a multi-grid method", J. Comp. Phys., vol. 48, pp. 387-411
クラウドサービスのメリットとデメリットについて

## クラウドサービスのメリットとデメリットについて
``クラウドサービスは、インターネット上で提供されるさまざまなサービスのことを指します。``
クラウドサービスのメリットとデメリットについて解説していきます！
自身の備忘録も兼ねていますm(__)m


## メリット
1. **コスト削減**
クラウドサービスを利用することで、自社でサーバーやストレージなどの機器を購入する必要がなくなります。また、運用やメンテナンスなどの人件費も削減できます。これにより、大幅なコスト削減が可能となります。

2. **柔軟なスケーリング**
クラウドサービスでは、必要なリソースをいつでも増減できます。これにより、急激なトラフィックの増加にも柔軟に対応することができます。また、リソースを無駄なく使用できるため、コスト面でも優れています。

3. **高い可用性と信頼性**
クラウドサービスは、複数のデータセンターにデータを分散させることができるため、システムの可用性が高くなります。また、バックアップやセキュリティ対策も、プロバイダーが行うため、高い信頼性が期待できます。

4. **最新技術の利用が可能**
クラウドサービスを利用することで、常に最新の技術を利用することができます。これにより、自社で新しい技術を導入するコストや手間を削減できます。

## デメリット
1. **セキュリティ上の問題**
クラウドサービスを利用する場合、データの管理権限が外部に委ねられるため、セキュリティ上のリスクがあります。また、データがインターネット上でやり取りされるため、ハッキングやデータ漏洩のリスクもあるため、適切な対策が必要となります。

2. **通信速度や帯域幅の問題**
クラウドサービスを利用する場合、インターネット回線の速度や帯域幅に依存するため、通信速度が低下する可能性があります。また、一時的な通信障害などにより、サービスが利用できなくなることもあります。そのため、インターネット接続環境によっては、クラウドサービスの利用に制限が生じる場合があります。

3. **制限されたカスタマイズ**
クラウドサービスを利用する場合、ユーザーはプロバイダーが提供するサービスや機能に制限されることがあります。そのため、カスタマイズや拡張ができない場合があります。また、プロバイダーがサービスの提供を中止した場合、利用者は突然サービスを利用できなくなるリスクがあります。

4. **データの制御が困難**
クラウドサービスでは、データが複数のサービスや場所に分散するため、データの統合や管理が困難になることがあります。また、データの移行や削除なども難しい場合があります。

## まとめ
クラウドサービスのメリットとデメリットについて解説しました。クラウドサービスを利用することで、コスト削減や柔軟なスケーリング、高い可用性や信頼性、最新技術の利用が可能になります。一方で、セキュリティ上の問題や通信速度や帯域幅の問題、制限されたカスタマイズ、データの制御が困難といったデメリットもあります。利用する際には、これらのメリットとデメリットを比較し、十分に検討したうえで適切な選択をすることが重要という事でした！
閲覧いただき、ありがとうございました！
業務フローは難しくないか？

いろいろな案件を見ていると、「この案件、業務フローが難しくないか？」と気づく時があります。
逆に仕事がしやすい職場もありますね。

作業の流れは、良くも悪くも職場独自のものが多いです。
「昔からそうしてたから」で、ずっと変えていないところもよく見かけます。

慣れてくると業務の流れを理解できて、スムーズにできるようにもなります。
がしかし、現代の人材が流動する社会では、誰でもすぐに仕事に参加できる業務フローに改善していったほうがいいでしょう。

## 業務を改善するために見るべきポイント

### 作業の見直し
前までは必要だったが、今では必要ない作業。
そういう作業はなくして、どんどん作業をシンプル化します。
何度もやっていると、実は無駄だった作業が見えてきます。

### コミュニケーションを増やす
タスクが属人化しているケースがあります。
実は他の人と作業が重複していたり、やり方を共有していればワンステップ無駄な作業を減らせる場合も。

### ツールの導入
実はツールでやったら一発。
そういう作業は結構あります。

しかし、「知らなかった」「導入がめんどうくさい」「そもそも調べてない」などで先延ばしにされていることも。
こういう問題を解消するためにも、コミュニケーションが大事です。
ちょっとしたキッカケから改善の糸口が見える時もあります。

https://amzn.asia/d/iXJUQgY
Jestなるものを使ってみる。

Jest。
4月からVuejsをやることになりそうなのだが、
新しいことたくさん聞きました。

# Jest
Vue.jsのテストコードを実行してくれるやつ。
テストコードにはどのメソッドを実行して、
その時にどの値を渡して、どう返ってくるか、というのを指定できる。

現状処理(コンポーネント？)単位でのテストしかよく分かっていないが、
E2Eテスト(シナリオを制定して実施するテスト)もできるらしい。

# チュートリアル
https://jestjs.io/ja/docs/getting-started

```
npm install --save-dev jest
```

まず、sum.jsを作る。ここには簡単な処理が書かれている。
```javascript sum.js
function sum(a, b) {
  return a + b;
}
module.exports = sum;
```

その後、sum.test.js というファイルを作成します。 このファイルに実際のテストが含まれます。
```javascript sum.test.js
const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});
```

package.jsonファイルをこのように
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/2bc6da9b-f0bf-2a24-ba2a-09552f0cf0b1.png)

コマンドライン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/1d46cb98-5818-b175-f6df-212e56a6dab7.png)

自動実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/691e714d-3c03-b925-3f61-56ed8787de8f.png)
StackViewに入れたButtonの幅を調整する方法

# 始めに
オートレイアウトそのまま使えば簡単にできますが、あとでレイアウト変更が楽なStackViewを使ってやってみたのでメモです。
他にも色々方法はあると思います。
# やりかた
こんな感じのレイアウトでボタンの横幅を変えたい
![スクリーンショット 2023-04-03 18.55.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883687/920f1db5-fa9b-9ad5-7943-f2f9f1102e68.png)

## StackViewを追加
親のStackViewの中に子StackViewを追加してButtonを入れ子にします
![スクリーンショット 2023-04-03 22.00.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883687/c1b3fa81-f190-9df2-c7af-a1776bdd5463.png)


## Buttonのwidthを設定
ボタンの横幅を固定します
![スクリーンショット 2023-04-03 22.00.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883687/8c4a7dfd-6e68-7d92-d3a7-d5cd3914bf64.png)



### 警告が出る
「固定幅の制約でクリッピングが発生する場合があります」と警告がでます
この警告はこちらの記事が詳しく解説していて参考になります。
https://qiita.com/onishi_820/items/b8fe02a07581f85d208d
![スクリーンショット 2023-04-03 20.54.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883687/c7309a61-98a6-5613-8f32-1c7003085dd0.png)


### ここをEqualからGreater Than or Equalに変える
これで警告は消えます！
![スクリーンショット 2023-04-03 21.04.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883687/bf74a916-ce80-b84e-5a1d-d2df35eb32ff.png)

# 完成
![スクリーンショット 2023-04-03 21.04.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883687/82f87de5-f858-bef2-5953-470a5d69436c.png)

# 最後に
最初はボタンの両端にViewを入れ込んで実装していました。
![スクリーンショット 2023-04-03 22.02.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883687/ea270c55-3465-c773-3a44-ef9c97ff6693.png)
Viewを固定横幅にして挟むと画面サイズが広い時にボタンが横に伸びてしまうとアドバイスをいただき今回の方法で行いました。
![スクリーンショット 2023-04-03 22.25.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883687/ff170455-7558-f63c-fa61-0c465f757d4d.png)
npmコマンドよく使う集

## はじめに
npmツールでパッケージを管理していく。

モジュールが沢山集まったものがパッケージのイメージ。

package.jsonファイルはパッケージ管理ファイル。

パッケージのバージョンや開発環境(devDependencies)で使用するパッケージなのか、とかnpmのスクリプトを書くことができる。

## npmコマンド

package.jsonを生成。-yを付けることで対話形式を蹴って原型を自動で作成してくれる。

```bash
npm init -y
```

パッケージを検索。githubとかに公開されているパッケージまで飛んでくれる。

```bash
npm docs <パッケージ名>
```

パッケージインストール、アンインストール。dependenciesに追加、削除。

```bash
npm i <パッケージ名>
npm rm <パッケージ名>
```

パッケージインストール、アンインストール。Devdependenciesに追加、削除。

```bash
npm i -D <パッケージ名>
npm rm -D <パッケージ名>
```

パッケージインストール、アンインストール。グローバルに追加、削除。

```bash
npm i -g <パッケージ名>
npm rm -g <パッケージ名>
```

グローバルパッケージの保存先。

```bash
npm root -g
```

パッケージインストールリスト。

```bash
npm ls
```

パッケージ毎の歴代バージョンの確認。
```
npm view versions <パッケージ名>
```
モジュール管理システム

## モジュール管理システムの違い

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2082391/8ac66a8b-e2e1-979c-4d5f-0b7422be20f2.png)


CommonJS（モジュール管理システム①）→主にnodejs上で動く。

ESmodule（モジュール管理システム②）→ブラウザでもnodejsでも動く。基本こっちで書く。

モジュールのインポートエクスポートの記法が異なる。

Node.js v18.15.0

CJS

```sub.js
//CommonJS(モジュール管理システム)のエクスポート書き方
exports.hello = () => {
    console.log("hello,japan")
}

// const hello = () => {
//     console.log("hello,japan")
// }
// module.exports = {
//     hello
// }
```

```main.js
//CommonJS(モジュール管理システム)のインポート書き方
const myModule = require("./sub")
myModule.hello()
```

EJS
```sub.js
//EJS(モジュール管理システム)のエクスポート書き方
const hello = () => {
    console.log("hello,japan")
}

export {
    hello
}
```
```main.js
//CommonJS(モジュール管理システム)のインポート書き方
import { hello } from "./sub.js"
hello()
```
```package.json
{
    "type": "module"
}
```
環境構築の参考サイト備忘録

https://qiita.com/ohtsuka1317/items/617a865b8a9d4fb67989

https://qiita.com/kooohei/items/0e788a2ce8c30f9dba53

https://qiita.com/tatsuya_1995/items/7aa899483bcf90df8531

https://ari23.hatenablog.com/entry/wsl2-uninstall

https://www.techgaku.com/fix-ubuntu-boot-error-on-wsl-after-reinstall/

https://bitto.jp/can-not-exec-docker-command/

https://qiita.com/sosomuse/items/86609dc46e7e8835f7de

https://eng-entrance.com/java-servlet-tomcat-install

https://ja.stackoverflow.com/questions/85622/pom-xml%E3%81%AE1%E8%A1%8C%E7%9B%AE%E3%81%A7%E3%82%A8%E3%83%A9%E3%83%BC-cvc-elt-1-a-cannot-find-the-declaration-of-element-project

https://qiita.com/quzq/items/1096c638c0d86795be13

https://www.javadrive.jp/start/install/index4.html#section2
身も蓋も無えprint(end="Hello, world")

# こんにちは
Pythonを使っていて、`print`関数で改行させたくない場合、
```python
print("Hello, world", end="")
```
こうすることで目的を達成できます。これは、文字列の末尾につける`end`引数のデフォルト値が改行であり、それを空文字列で置き換えることによって改行を防げるという仕組みです。

## ちょっと待ってください
ところで、文末の`end`は1文字である必要はなく、文字列を受け取ります。つまり
```python
print(end="Hello, world")
```
でいいんですね。

## 終わりに
print(end="身も蓋も無え！\n")
[AWS Q&A 365][API Gateway]AWSのよくある問題の毎日5選 #22

# 1. REST APIとは何ですか？
答え：REST APIとは、HTTPリクエストを使用してデータにアクセスし、操作するためのWebサービスの一種です。Webサービスを構築するためのアーキテクチャスタイルであり、拡張性、柔軟性、保守性に優れています。

# 2. REST APIを使用することの利点は何ですか？
答え：REST APIは使いやすく、柔軟で、拡張性があります。開発者は複数のソースからデータにアクセスし、操作することができ、広範囲のプログラミング言語やプラットフォームと統合することができます。

# 3. Amazon API Gatewayを使用してREST APIを作成するにはどうすればよいですか？
答え：Amazon API Gatewayは、REST APIを作成するためのシンプルで柔軟かつ拡張性のある方法を提供します。API Gatewayコンソール、AWS CLI、またはAWS SDKを使用してAPIを作成できます。

# 4. REST APIを保護するにはどうすればよいですか？
答え：Amazon API Gatewayには、認証および承認、APIキー、OAuth 2.0など、REST APIを保護するためのいくつかのオプションがあります。

# 5. REST APIを監視およびトラブルシューティングするにはどうすればよいですか？
答え：Amazon API Gatewayには、CloudWatchメトリクスやログ、X-Rayトレース、API Gatewayキャッシュなど、REST APIを監視およびトラブルシューティングするためのいくつかのツールが用意されています。第三者のツールやサービスを使用して、APIを監視およびトラブルシューティングすることもできます。
[AWS Q&A 365][API Gateway]Daily Five Common Questions #22

# 1. What is a REST API? 
Answer: A REST API is a type of web service that uses HTTP requests to access and manipulate data. It is an architectural style for building web services that are scalable, flexible, and maintainable. 

# 2. What are the benefits of using a REST API? 
Answer: REST APIs are easy to use, flexible, and scalable. They allow developers to access and manipulate data from multiple sources, and can be integrated with a wide range of programming languages and platforms. 

# 3. How do I create a REST API using Amazon API Gateway? 
Answer: Amazon API Gateway provides a simple, flexible, and scalable way to create REST APIs. You can create APIs using the API Gateway console, the AWS CLI, or the AWS SDKs. 

# 4. How do I secure my REST API? 
Answer: Amazon API Gateway provides several options for securing your REST API, including authentication and authorization, API keys, and OAuth 2.0. 

# 5. How do I monitor and troubleshoot my REST API? 
Answer: Amazon API Gateway provides several tools for monitoring and troubleshooting your REST API, including CloudWatch metrics and logs, X-Ray tracing, and API Gateway caching. You can also use third-party tools and services to monitor and troubleshoot your API.
gitlab project user整理

# gitlab project user権限管理表を作る
# 希望：gitlab project user権限管理表
目の前のプロジェクトがユーザー管理表が作る，自分が統計で時間がかかります、ちょっとpythonを利用して



```python
import json
import requests
import csv

#gitlab person access token
TOKEN = ""
GITLABURL = "https://gitlab.com"
##gitlab project ID
PROJECTID = ""
getallmemberApi = "api/v4/projects/{}/members/all".format(PROJECTID)

def GiveRequestInfo():
    headers = {"PRIVATE-TOKEN":TOKEN}
    url = "{}/{}".format(GITLABURL,getallmemberApi)
    content = requests.get(url,headers=headers)
    return content 

def handdate(data):
    for line in data.json():
        createName = line.get("created_by", line["username"])
        if not isinstance(createName, str):
            createName = createName.get("created_by")
        
        yield {
            "username": line["username"],
            "name": line["name"],
            "access_level": line["access_level"],
            "created_at": line["created_at"],
            "createdby": createName
        }

def writecsv():
    filename = "{}.csv".format(PROJECTID)
    with open(filename, "w") as f:
        fieldnames = ["username", "name", "access_level", "created_at", "createdby"]
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()
        while True:
            content = yield
            
            writer.writerow(content)

if __name__ == "__main__":
    a = GiveRequestInfo()
    contest = handdate(a)
    writer = writecsv()
    next(writer)
    for line in contest:
        writer.send(line)
    writer.close()
```
# 結果は以下になります

![gitlabupdate.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231872/7d11c92b-6ee6-dd53-da87-d3bdc49d2c5f.jpeg)