OmniAICreator/Qiita-1.07M huggingface dataset:
【個人開発】Flutterでじぶんリリースノートを記録するアプリを2ヶ月でリリースしたかった


[株式会社 mofmof](https://www.mof-mof.co.jp/) では、毎週水曜日を個人開発の日に定めて、2 ヶ月に 1 つプロダクトを作ろう！というイベントを行なっています。

https://indie-dev.mof-mof.co.jp

今日が 3 月から始まった 2 ヶ月間の最後の水曜日になったので、~~未リリースですが~~どんなアプリを作っているか紹介したいと思います。

:::note info
2023.05.06 追記
iOS版をリリースしました！

2023.05.10 追記
Android版もリリースしました！
:::

### EvolVersion for iOS

https://apps.apple.com/jp/app/evolversion/id6448634763

### EvolVersion for Android

https://play.google.com/store/apps/details?id=jp.kmkkiii.EvolVersion

## どんなアプリ？

<div style="display:flex;">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317957/f3b8855a-a4f7-e5f0-c832-d92600746d9a.png" width="300px">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317957/5ea80ea7-a9b6-244a-a7e4-4288192a7ba5.png" width="300px">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317957/4cb22039-1f2a-f0b7-7d65-e6afc66ec009.png" width="300px">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317957/590e76e1-7d0d-f80e-f8ac-6b6a61a922a5.png" width="300px">
</div>

ブログや note で見かけた**じぶんリリースノート**という取り組みがいいなあと思ったので、このコンセプトでアプリを作ることにしました。

> https://blog.a-know.me/entry/2019/02/02/214612
> そもそも "じぶんリリースノート" とは？
> 特にこれといった定義があるわけではない（と思う）のだけど、「ある特定の期間、自分が何をし、どんなことがあったか」みたいなことを、「新しいバージョンのリリース」に見立ててリリースノート風にする、といった取り組み。

https://blog.a-know.me/entry/2019/02/02/214612

https://note.com/hashtag/%E3%81%98%E3%81%B6%E3%82%93%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%83%8E%E3%83%BC%E3%83%88

取り組まれている方々の記事を参考に以下のような仕様にしました。

- バージョン番号は `0.年齢.月齢`
- 誕生日の翌日の日付を毎月のリリース日とする

### 主な機能

- メール/パスワード認証
- メモ作成
  - 2 階層まで作成できる
- リリースノート作成
  - マークダウンで書ける
  - リリースすると紙吹雪が舞う
  - 🎉ボタンで紙吹雪を舞わせることができる

日々のイベントはメモとしてこまめに記録して、リリース日付近になったらメモを見て 1 ヶ月間をふりかえり、リリースノートを作成してリリースするという流れです。

### ネイティブアプリにした理由

- スマホで日々の記録を簡単に記録したい
- リリースノートを作成するタイミングをプッシュ通知でリマインドしてほしい
- 自分で作ったネイティブアプリをリリースしてみたい

## 何で作っているか

- Flutter
- Firestore Database
- Firebase Authentication

### パッケージ

- Cloud Firestore ODM
  アルファ版だけど使ってみたかったやつ。Firestore を使った開発が型安全に行える。
- markdown_widget
  リリースノートの Markdown テキストを表示するために導入
- timeline_tile
  リリースのタイムライン表示に使用
- confetti
  紙吹雪を舞わせるやつ
- flutter_speed_dial
  FloatingButton を押すと複数メニューのボタンを表示してくれるやつ

https://firebase.flutter.dev/docs/firestore-odm/overview/

https://pub.dev/packages/markdown_widget

https://pub.dev/packages/timeline_tile

https://pub.dev/packages/confetti

## あとがき

2 ヶ月でとりあえず主な機能は実装することができました。
最初の 2 週間くらいは作るかどうか悩んでしまって開発着手が遅くなってしまったので、来月から作るアプリはGW 中にアイデアを練って臨みたいと思います。

この記事で紹介したアプリも、アイコン・利用規約・ストア説明文の作成、アプリの審査などのリリース作業が残っていますが、GW 中にはリリースするぞ！という意気込みです。

---
このプロダクトは、株式会社 mofmof の「水曜日の個人開発」で~~作りました~~絶賛開発中です。

https://indie-dev.mof-mof.co.jp
Next.jsでuseRouterフックを使用して現在のページのパス情報にアクセスする方法。

# はじめに
Next.jsでは、`useRouter`フックを使用して現在のページのパス情報にアクセスすることができる。`window.location.pathname`の代わりに、`useRouter`フックを利用することで、サーバーサイドレンダリング環境での動作を問題なく保証することで、エラーにならない。

## `useRouter`を使った書き方の例は以下の通り。

### ①現在アクセスしているURLを取得する例
```typescript
import { useRouter } from 'next/router';

const Footer = () => {
  const router = useRouter();

  const GetHouseColor = () => {
    if (router.pathname === '/home') {
      return 'text-orange-400';
    } else {
      return 'text-black';
    }
  };
```
このコードでは、`useRouter`フックをインポートし、`router`オブジェクトを取得している。
その後、`router.pathname`を使って現在のページのパス情報にアクセスし、`/home`のページを表示している場合を指定しています。この方法で、サーバーサイドでの実行でも問題が発生せず、エラーにならない。

#### `pathname`とは
`pathname`は、URLの一部で、ドメイン名（またはIPアドレス）の後に続く、リソースへのパスを示す部分。
要するに、ウェブサイトの各ページを特定するために使用されるパスのこと。
例えば、以下のURLがある場合、
```
https://example.com/blog/post-1
```
このURLの`pathname`は `/blog/post-1` ということになる。
この`pathname`を使って、現在表示されているページがどのページであるかを判断することが可能。

#### ②現在アクセスしているURLの動的パラメータを取得する例
このコードは、Reactのフックを使用して、レシピの取得と状態管理を行うコンポーネント。
useRouterを使用して、URLからIDを取得し、axiosを使用してAPIからレシピの情報を取得する。
レシピ情報は、useStateを使用して、stateとして管理する。

## コード

```typescript
const router = useRouter()
const { id } = router.query
const [recipe, setRecipe] = useState<Recipe | undefined>(undefined)

// レシピの取得
const getRecipe = useCallback(() => {
  axios
    .get<Recipe>('http://localhost:8000/recipes' + id)
    .then((response) => {
      setRecipe(response.data)
      console.log('レシピの取得に成功しました', response.data)
    })
    .catch((error) => {
      console.log('レシピの取得に失敗しました', error)
    })
}, [id])
```
【レベルアップ正規表現】最長一致 vs. 最短一致

# 正規表現

ほぼあらゆるプログラミング言語では、正規表現を使って文字列のパターンをマッチングすることができますよね。今回正規表現のちょっとしたトラップにハマったのが悔しかったので調べて記事にしようと思います。結論から言えば、正規表現には、"lazy(怠惰)"と"greedy（貪欲）"の2つの種類があります。この記事では、これら2つの種類の違いについて見ていきます。

## Lazy(怠惰)な正規表現

Lazyな正規表現では、文字列の最短マッチングを行います。つまり、マッチする部分文字列が見つかった場合、即座にその部分文字列を結果として確定させ、それ以降の文字列に対してマッチングを続けます。

例えば、次のコードを見てみましょう。

```TypeScript
const lazyRegex = /a(.*?)b/g;

const input = "abaaxyzbadb";
const result = input.match(lazyRegex);
console.log(result); // ["ab","aaxyzb", "adb"]
```

このコードは、"aaxyzbadb"という文字列から"a"と"b"に挟まれたの最短（"ab"を含む）の文字列をマッチングしようとします。Lazyな正規表現では、".*?"を使って最短のマッチングを行い、["ab","aaxyzb", "adb"]という3つの文字列をマッチングします。

## Greedy(貪欲)な正規表現

Greedyな正規表現は、文字列の最長マッチングを行います。つまり、パターンにマッチする部分文字列の中で最も長いものを返してきます。

例えば、次のコードを考えてみましょう。 ***`lazyRegex`から`?`が消えているのがポイントです。***

```TypeScript
const lazyRegex = /a(.*)b/g;

const input = "abaaxyzbadb";
const result = input.match(lazyRegex);
console.log(result); // ["abaaxyzbadb"]

```

上記のコードは、"abaaxyzbadb"という文字列から"a"と"b"に挟まれた最長の文字列をマッチングしようとしています。Greedyな正規表現は、".*"を使って最長のマッチングを行い、"abaaxyzbadb"という文字列全体をマッチングします。

## まとめ

今回は正規表現における"lazy"と"greedy"の違いについて説明しました。Lazyな正規表現は、最短のマッチングを行い、Greedyな正規表現は最長のマッチングを行います。言語によって記法は多少違うと思いますが、私のように知らないと見落とすので普段使っている言語の正規表現を改めて調べてみても良いかもしれません。
B2C Commerce のその他 Salesforce 製品との接続 - Loyalty Management for commerce

※ これから記載する事項は、私が所属する会社とは切関係のない事柄です。


今回は[「B2C Commerce のその他 Salesforce 製品との接続」シリーズ](https://qiita.com/syunyama/items/366fcbc315be5e5c252f)として B2C Commerce と Loyalty Management の接続について紹介したいと思います。

![Cross Cloud (16) (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/89c0b338-d813-93b3-f01f-87557468345b.jpeg)



## 接続内容とポイント

* Loyalty Management と B2C Commerce を利用して下記の要件を実現できます
    * メンバー登録する
    * メンバーの解約
    * 購入に基づいてポイント付与される
    * 購入時にポイント利用する
    * 会員ランク付与される
    * クーポンの付与される
    * クーポンを利用する
    * メンバー情報、会員ランク、ポイント、取引記録、クーポン、特典の表示する
    * プロモーションが表示される
* 内部で共通の機能を利用しているので B2C-CRM-SYNC が入っている方が望ましいです
* Order オブジェクトを作成するので Order Management ライセンスが入っているのが望ましいです

:::note
現在では Order Management は必須ではありません。（[参考](https://help.salesforce.com/s/articleView?id=release-notes.rn_loyalty_for_commerce_oms_removal.htm&release=240&type=5)）
:::




### 画面例

#### アカウント作成時のロイヤリティメンバー加入
![スクリーンショット 2022-05-23 11.07.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/cf7fe0a3-ed49-5d90-ed6c-4b046d87af9c.png)



#### ダッシュボードでのロイヤリティ情報の確認
![スクリーンショット 2022-05-23 12.32.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/74a85bd8-8f6a-6d20-17df-59d09cecd05e.png)


#### カートでのポイントの利用
![スクリーンショット 2022-05-23 11.39.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/356fe588-c7b7-ee1d-1aea-9987c9ddbdad.png)


## 接続方法

　詳細は [PDF（要 Account Manager アカウント）](https://github.com/SalesforceCommerceCloud/loyalty-management-for-commerce/blob/main/Get%20Started%20with%20Loyalty%20Management%20for%20Commerce.pdf) を参考にしてください。



## 接続データとポイント

* B2C Commerce のジョブを利用した非同期で、カタログ・商品のデータを Platform に連携しています
* 利用している Platform のオブジェクトは [PDF（要 Account Manager アカウント）](https://github.com/SalesforceCommerceCloud/loyalty-management-for-commerce/blob/main/Get%20Started%20with%20Loyalty%20Management%20for%20Commerce.pdf) の 3 ページを参照してください
* ロイヤリティ情報の取得やクーポン・ポイントの利用は同期的に B2C Commerce から呼ばれます。その際 [REST からの Flow の起動](https://help.salesforce.com/s/articleView?id=sf.flow_distribute_system_rest.htm&type=5) や [Apex REST](https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_rest_code_sample_basic.htm) が利用されています



## リソース

* [loyalty-management-for-commerce の Github レポジトリ（要 Account Manager アカウント）](https://github.com/SalesforceCommerceCloud/loyalty-management-for-commerce)
* [Apex 内で利用されている LM の API](https://developer.salesforce.com/docs/atlas.en-us.loyalty.meta/loyalty/loyalty_apex_reference.htm)
GCPの各種DBのについて

# GCPの各種DBの操作について
##Cloud SQL

　①MySQLを接続するため、「gcloud sql connect innstanceName -user=root」</br>
　②MySQLを接続された後、普通のMySQLのコマンドでデータベース作成、DDL、DMLを実行する</br>

　③MySQLをバックアップするには、オンデマンドバックアップと自動バックアップある</br>
　　・gcloud sql backups create --async --instance [instance_name]</br>
　　・gcloud sql instance patch [instance_name] -backup-start-time [HH:MM]</br>

##DataStore

　①DataStoreにデータを追加するには、Entityを使用して、追加する。</br>
　②Entity作成した後、GQLを使って、ドキュメントデータベースを参照する</br>
　③Datastoreのデータベースをバックアップするには、バックアップファイルを格納するためのGCSバケットを作成して</br>
　　バックアップを実行するユーザに適切な権限を付与する </br>
　　・バックアップ用のバケットを作成するには、gsutil mb gs://[Bucket_name]</br>
　　・バックアップを作成するユーザに、datastore.database.exportアクセス権限が必要である</br>
　　　データをインポートするには、datastore.database.importアクセス権限が必要である</br>
　　　Cloud Datastore Import Export Adminロールには、上記両方のアクセス権が付与される。</br>
　　　　　　■バックアップ作成には、gcloud datastore export -namespaces='[NAME_SPACE]' gs://[Bucket_name]</br>
　　　　　　■バックアップファイルをインポート、gcloud datastore import gs://[Bucket_name]/[FILE].overall_export_metadata</br>

##BigQuery
　①BigQueryはフルマネージドデータベースサービスであるため、基本的な管理タスクは自動化される。</br>
　 エンジニアは一部管理タスクは実行できる、クエリのコスト試算とジョブのステータスの確認など</br>

##Clopud Spann
　①インスタンスを作成するには、以下の情報は必須</br>
　　・instance name</br>
　　・instance id</br>
　　・RegionかMulti Regionか</br>
　②インスタンスを作成したら、データベースを作成して、DDLを使って、テーブルの構造を定義する</br>

##Cloud　Pub／Sub
　①Pub／SubメッセージキューをDeployするには、トピックの作成とサブスクリプションの作成は必要である</br>
　②トピックはアプリがメッセージを送信できる構造である、Pub／Subはメッセージを受信して、アプリはそのメッセージ</br>
　　を読み取りまで保持する</br>
　③アプリはサブスクリプションを使って、メッセージを読み取る</br>
　④サブスクリプションを作成には、PullとPushとの２タイプは存在、Pushの場合、EndpointのULRは必要</br>
　⑤コマンドで作成する時、以下通りである</br>
　　・gcloud pubsub topics create [TPOIC-NAME]</br>
　　・gcloud pubsub subscriptions create [SUBSCRIPTION-NAME] --topic [TPOIC-NAME] </br>

##Cloud Bigtable
　①Bigtableを使うため、インスタンスを作成する必要あり、以下の情報は必須</br>
　　・instance name</br>
　　・instance id</br>
　　・instance type、Develpment向けか、本番モードか</br>
　　・Storage SSDか、HDDかを指定する</br>
　　・Cluster情報指定</br>
　②Bigtableの作業には、以下のcbtコマンドで実施できる</br>
　　・cbtをインストールする</br>
　　　　■gcloud components install cbt</br>
    ・BigTableの対象インスタンス名を.cbt構成ファイルに追加し、事前設定する必要がある</br>
　　・tableを作成する</br>
　　　　■cbt createtable [table-name]</br>
　　・tableのリストを出力するには</br>
　　　　■cbt ls</br>
　　・ファミリー列作成</br>
　　　　■cbt createfamily [table-name][FamilyNmae]</br>
    PS:もっと詳しいは以下の公式で</br>
    　[cbt リファレンス](https://cloud.google.com/bigtable/docs/cbt-reference?hl=ja"Refer")</br>

##Cloud Dataprocについて
　①DataprocはGCPマネージドApache Spark及びApache Hoopサービスで、ビッグデータアプリ向け設計された</br>
B2C Commerce のその他 Salesforce 製品との接続 - Marketing Cloud Connector

※ これから記載する事項は、私が所属する会社とは切関係のない事柄です。

今回は[「B2C Commerce のその他 Salesforce 製品との接続」シリーズ](https://qiita.com/syunyama/items/366fcbc315be5e5c252f)として B2C Commerce とMarketing Cloud の接続について紹介したいと思います。

![Cross Cloud (17) (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/7c0d4e18-f80f-ec15-d278-f9f4213bed99.jpeg)




## 接続内容とポイント

* `collect.js` という Javascript を利用してユーザのアクティビティをトラッキングします。このトラッキングデータを利用して[カート放棄時のメール](https://help.salesforce.com/s/articleView?id=sf.icx_b2c_abandonedcart_req_workflow.htm&type=5)のようなユーザーの行動に基づいた体験を提供できます
* MC のリストへのユーザの追加、削除を行うことでメルマガの実施ができます
* 下記のようなトランザクショナルメールを MC から送ることができます（Transactional Messaging API ではなく [Triggered Email](https://developer.salesforce.com/docs/marketing/marketing-cloud/guide/messageDefinitionSends.html) を利用）
    * アカウント - 登録、更新、パスワード変更、パスワードリセット、ロック通知
    * お問い合わせ、ギフトの送信、注文完了
* B2C Commerce のジョブを利用してデータを MC に同期できます



### 接続例 - カートの放棄時のメール

カート放棄時にメールを送信する大まかな流れを下記に記載します。
より詳細なフローは[ヘルプ](https://help.salesforce.com/s/articleView?id=sf.icx_b2c_abandonedcart_req_workflow.htm&type=5)を確認ください。またファイルの連携方法については [Github のマークダウン（要 Account Manager アカウント）](https://github.com/SalesforceCommerceCloud/marketing-cloud-connector/blob/master/docs/4_0_AdditionalFeatures.md#data-feeds)をご覧ください。

1. あらかじめジョブで商品情報を FTP で CSV（PSV）アップロードし、Catalog にインポートすることで連携しておく
2. あらかじめジョブで顧客情報を FTP で CSV（PSV）アップロードし、Data Extension にインポートすることで連携しておく
3. 顧客のアクティビティを MC へ送信する
4. [Cart Abandonment トリガー](https://help.salesforce.com/s/articleView?id=sf.mc_pers_triggered_campaign_trigger_cart_abandonment.htm&type=5)の資格当てはまるユーザが発生すると Data Extension にレコードが作成される
5. 作成された Data Extension レコードを Jorney Builder 利用してユーザにメールを送信します


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/04209438-7c75-28e3-bb19-5002f37630a1.png)



#### メールの例

![スクリーンショット 2022-01-26 14.36.33 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/34ca6d20-6ad8-5ad4-c261-ff275bfaeae0.png)


## 接続方法

接続方法については [marketing-cloud-connector の README](https://github.com/SalesforceCommerceCloud/marketing-cloud-connector) をご覧ください。



## 接続データとポイント

* B2C Commerce のジョブを使用して MC に同期される情報は下記の通りです
    * 商品、顧客、コンテンツ、注文、プロモーション、キャンペーン
* 連携されるアクティビティデータは下記の通りです
    * 全ページ、検索結果ページ、商品詳細ページ、カテゴリページの閲覧
    * カートの投入、変更、削除
    * 注文の完了



## リソース

* [MC の API リファレンス](https://developer.salesforce.com/docs/marketing/marketing-cloud/guide/apis-overview.html)
* [MC の Transactional Messaging API](https://developer.salesforce.com/docs/marketing/marketing-cloud/guide/transactional-messaging-get-started.html)
勉強会レポ：Cloudflare Meetup Tokyo Kick Off !!

昨日、こちらに参加してきましたので簡易レポです。

https://cfm-cts.connpass.com/event/275461/

事例を含めいくつかセッションがありましたが、抜粋して簡単にご紹介します。


# Cloudflareとは？

エバンジェリスト亀田さんからのセッションを超雑に紹介します。

- Cloudflareを一言でいうと：「インターネットの高速化とセキュリティ」を実現するサービス群
- 世界中のデータセンターに配置されたコンポーネントで分散処理をしている
- 「すべての通信をCloudflareに通す」のが基本的な使い方。これによってDDoS防御などセキュリティ担保もできる

また、Cloudflareの設備ではIP Anycastを活用しているということです。

例えばDNS名前解決のリゾルバーなどもそうですが、複数のエッジ機器が同じIPアドレスを持っており、一つのIPアドレスへのリクエストが1:多で同時に投げられることによって、その中で最適化された経路をたどるため応答性能が上がる、といったメリットがあるようです。

https://www.cloudflare.com/ja-jp/learning/dns/what-is-anycast-dns/


# ハンズオン

実際にCloudflareで「エッジに簡易アプリケーションをデプロイして利用する」体験を行いました。以下３パートに分かれており、1時間もかからず完了できるボリュームです。

① アカウント作成

https://zenn.dev/taketakekaho/articles/5f72f4c58ab0ba

② ローカル開発環境の準備

https://zenn.dev/kameoncloud/articles/1fac9762aab4ec

③ エッジアプリのデプロイ

https://zenn.dev/kameoncloud/articles/7236a2c6ad35c0


### お絵描きでハンズオンおさらい

私は普段ゴリゴリ開発をしていないこともあり、ハンズオンは時間内に完了したものの③の後半あたりから自分が何をやっているのかよく分からなくなってしまいました。

そのため帰宅後に復習がてら絵を描いてみると理解が追いつきました。
やっぱりビジュアルで右脳に染み込ませるの、大事ですね。

#### ③の前半でやったこと（To Doアプリのデプロイ via Webエディター）
![スクリーンショット 2023-04-25 22.32.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/caf0633a-73ef-21b4-c3ba-2426b6cb34e2.png)

#### ③の後半でやったこと（KVデータ取得アプリのデプロイ via ローカル開発環境）
![スクリーンショット 2023-04-25 23.02.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/e4fd3d0f-ca5f-df67-ae79-8d2b3408e752.png)


# おわりに

いつもコマンド操作やコピペの多いハンズオンをすると「あれ、結局自分は何をやったんだっけ…？」とすぐ迷子になるタイプなので、ハンズオンの際はなるべくコピペに頼らず自分の手でコードをトレースしたり、絵を描いて全体概要を咀嚼してこそ学習効果が定着するなぁと改めて実感しました。

素敵な勉強会の企画、ありがとうございました！
社内のオンライン技術情報交換会を36回やってやめた話

社内ではオンライン技術情報交換会を「雑談会」と呼んでいました。
以下、雑談会で統一します。

## 背景

弊社は受託開発の会社です。
社内では常時複数の開発案件が動いています。
各案件で働いて居る人は、それぞれ技術的な知見を貯めています。
しかし、別の案件で働いている人が、どのような知見を持っているか知るすべがありません。

特に、雑談会をはじめた当初はコロナ禍の最中でした。
オフラインで技術的な雑談や相談をする機会もありませんでした。

そこで雑談会をはじめることにしました。

## 雑談会の形態

毎週金曜日の15時から30分間、Slackのハドルで開催しました。
参加者のハードルを下げるために、Zoomのようなビデオ会議は使いませんでした。
発表者からは必要に応じて画面共有をしました。

特に継続性を重視し、運営や参加の負担を低くなるように雑談会を設計しました。
会の名称が雑談会なのも、この狙いのためです。

### 話題の例

弊社はRuby on Railsを得意としているのでRubyとRailsの話題が多いです。 

- Rails
    - Railsバージョンアップ
    - Railsアプリケーションでのサービスクラスについて     
    - ActiveRecordのdelegated_type
    - ActiveRecordのjoins, preload, eager_loadの使い分け
    - ActiveJobのバックエンド
    - Railsのソースコードリーディング
    - Railsタスク
- Ruby
    - Stackprof
    - ruby.wasm
    - Ruby Kaigi 2022のセッション紹介
- Web
    - SSL 
    - User-Agaent
    - Create.js
    - GraphQL
- 外部API連携
    - LINE API
    - ChatGPT API
    - Stripe API
- その他
    - デスクトップアプリケーションの作り方
    - slackでのtimesチャンネルの使い方
    - Googleサイトで社内ポータルを作る
    - Miro
    - 案件で開発に参加しているサービスの機能紹介
    - 書籍紹介
    - SQLのパフォーマンス改善
    - CFD法
    - スタンディングデスク
    - 会社説明会の様子を紹介
    - スクラム


## 開催情報

- 2022年4月28日～2023年4月7日
- 36回
- 参加者3～20名

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15964/c3b13571-d346-d781-d107-003443983e09.png)

参加人数は8月から取り始めました。25回分のデータです。
社員が30人程度です。最大で6割の出席率です。

雑談会をやめると公表したときには「寂しい」と感想をもらいました。


## 雑談会をやってみて

### よかったこと

- 雑談的なコミュニケーションが取れるのが楽しい
- 案件外の人とつながりが持てた
- 人前で説明する練習になった
- 常連になった参加者もいて、需要があった

約一年の開催期間中、コンスタントに参加者がいました。
常連になってくれた人も居て、やめると公表したときには「寂しい」言ってもらえました。
一定の需要があったと考えられます。

### よくなかったこと

- 発表者からの一方的な発表になる

雑談会の名称に反して、雑談への発展が少なく発表者からの一方的な発表になりがちでした。

## なぜやめるのか

一番の理由は運営者の負担です。
予想していたよりは運営者の負担が、大きく他の活動をする上での制約になっていました。
このまま雑談会を継続していくか、別の活動にチャレンジするか二択で考えて、別の活動を選びました。

雑談会は社内の有志による活動ではなく、業務の一部としてチームで行っていました。
チームのメンバーを増やして、運営者を増やしたり交代したりして継続する選択肢もあったと思います。
ですが、チームメンバーを変更すると、チームづくりからやり直しになります。
今回は運営者を交代する方法はとらず、すぱっとやめることにしました。

また、コミュニケーションチャンネルとしての役割は、1年前より低下しています。

- 社内で別のコミュニケーション系の活動が始まった
- コロナ禍が弱くなり、物理出社などのオフラインの交流機会がが増えた

### オンライン型の勉強会の課題

雑談会にかぎらず、オンライン型の勉強会では、次の課題があるように思います。

- 聞く立場としては、集中して聞きにくい点
- 発表する立場としては、反応が見えにくい点

自分もオンライン勉強会に参加する立場では、どうしても聞き流す感じになります。
特に自分が詳しくない分野ほど聞き流しがちです。
聞き流していると、自分の中で質問がうまれません。
リアクションが儀礼だけになりがちです。

これに対して運営の立場では次のようなファシリテーションを行います。

- 参加者に質問を求める
- 自分から質問を出す

質問を詳しそうな人に指名したり、自分で考えたりする必要があります。
このテクニックは司会者の個人技に依存しています。
司会者と話題と参加者の組み合わせ次第で、上手く行ったり行かなかったりします。
何かしらの仕組み化できなかったので、司会者役の負荷になりました。

運営の立場でも、反応が見えないと手応えのなさを感じます。
また、反応が少ないと、一つのネタから継続、発展していくことがありません。
このためネタ探しをする労力が掛かりました。
多様な話題を扱っているのは、一見良さそうに思えますが、運営の苦肉の策でもあります。
『Java SE11 Gold』 実務経験浅がこうやって取得した！

<h1>自己紹介</h1>

独学にてPythonを勉強し、2022年1月よりIT業界未経験にて会社に入社。入社後は研修にてJavaを学んだのち、Javaの開発に携わっています！
資格取得日は2022年10月で、取得時点では実務経験6カ月程度でした。現場経験が浅くても資格取得は十分可能なので、取得を検討されてる方はぜひ参考に！

<h1>勉強を始める前に</h1>

資格取得に向け、必要な情報収集と勉強スケジュールの組立を行いました。

勉強時間　→　150〜200時間程度
教材　→　<a href="https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5Java-SE-11-Gold%E5%95%8F%E9%A1%8C%E9%9B%86-1Z0-816/dp/4295012564">JavaSE11Goldの黒本</a>、<a href= "https://docs.oracle.com/javase/jp/13/docs/api/index.html">JavaAPIリファレンス</a>
スケジュール　→　Excelでスケジュール表作成

1day/3hの勉強時間を確保し、2カ月後に取得を目標としました。
勉強のスケジュールが確定した時点で試験予約！ <b>← ココ大事！</b>

<h1>勉強方法</h1>

黒本をやり込むのみ！合計３周しました。点数数位は下記の通り。

1~12章（カテゴリ別）　：0%　→　59%　→　90%
13章（総仕上げ問題）　：47％　→　73%　→　91%

黒本は第1章〜12章では出題範囲のカテゴリ別が約180問、13章で総仕上げ問題が80問の計260問になります。1周目は1問あたり20〜30分程度をかけて記述、理解、応用をしていました。おそらく1週目で100時間以上かけていたと思います。

まずは問題を解かず、全ての問題と解説のコードを書いて実際に動かし、自分なりに手を加えて再度動かしてみました。また<b>重要だと思ったところはコメントアウトで要点を記述したり、クラスの依存関係を図で書いたりしました。</b>

黒本2〜３周目は実際に問題を解いていき、間違った問題は1周目に自分で書いたコードのコメントアウトを確認しながら復習しました。

↓実際に書いたコード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2119179/a520ffd5-742e-ff8b-b0c5-b8bfdb744b62.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2119179/794a3ae2-686e-a891-f3fc-9b4d24f43bf8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2119179/7ad418ff-9a6e-64ac-e864-5d42cefdba22.png)

<h1>試験を終えて</h1>

正解率82%にて無事合格しました。
![スクリーンショット 2023-04-26 12.46.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2119179/e0ae7a6f-cc24-abb3-5531-9aed41b8f313.png)
ラムダ式、ストリームAPIの問題がかなり多かったイメージがあり、おそらく試験の半分はラムダ式、ストリームAPIに関しての問題でした。黒本全ての内容を理解することが必要ですが、特にこの２点は完璧になるまでやり込みましょう！
何も成果物を出したことがない学生が技育CAMPのハッカソンに初参加してみた！

先日、開催された技育CAMPのマンスリーハッカソンvol.2（4/15, 4/16）に即席チームで参加しました。そこで得られたことなどを書いていこうと思います。

## 簡単な自己紹介
いきなりで誰だ？と思っている人しかいないので簡単な自己紹介をしていこうと思います。
所属：情報系大学の３年生
趣味：音楽を聴く（YOASOBIや邦ロック系など）、AtCoder（灰色）、
　　　Kaggle（初心者向けで有名なTitanicをしただけ）、ドラマ鑑賞
プログラミング能力：成果物なし、授業程度のレベル感
## 今回作成した成果物の紹介
即席チームで話し合った結果、「LineBotで面接対策をするのとそれを促すInstagramツール」になりました。役割分担として、Instagramツール側になりました。

発表資料は下記の通りになります。（一部のみの掲載になっている）

https://twitter.com/geek_pjt/status/1647507936695160834?s=20

## ハッカソンを通して得られたこと
### １.技術・知識不足を痛感することができた
今までが授業程度のプログラミングしかしてこなかったので、今回の開発で任されたタスクを全然出来ずにチームの皆さんには非常に感謝しています。
また、全く出来なかったので技術・知識不足を痛感したと同時に自分の現状を把握することができたのでそこは参加して良かったと思っています。
### ２．参加している学生の開発姿勢を知ることができた
今回のハッカソンに私は即席チームで参加しましたが、参加している学生の中には個人で参加している人や事前にチームを組んで参加している人達がいました。
参加している多くの学生たちが今回初めて使う言語や開発手法などを積極的に取り入れていてレベルの高さに圧倒されるばっかりでした。
## 最後に
まず、ここまで読んでくれてありがとうございました。
こういうような記事を書いたのが初めてなので、拙い文章になっていると思いますが大目に見て頂けると助かります。
これから、個人開発を通して成果物を出していきたいと思っています。
また記事を書く機会があれば書いていくのでそのときは読んでコメントをしてくれると嬉しいです。
そして、最後になりますがチームの皆さんにはとても感謝しています。
本当にありがとうございました！
java初心者がいく～static～

# はじめに
java初心者が議事録的に書いています。
今回はstaticの代表的な使い方2パターンを描いていこうと思います。

# staticメソッド
java初心者の人はおまじないのようにstaticを使っていませんか？
特に以下のようなときに何となくかいていませんか？（私もそうでした）

```java
public class Driver {
    public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ
	}
}
```
ではこのstaticはどういう意味があるのでしょか。
結論から言うと、staticがついているメソッドは「インスタンス化しなくても呼び出せる」という特徴があります。
ふつうはメソッドを呼び出すときはnewを使ってインスタンス化した後に呼び出しています。しかしmainメソッドのように一番最初に呼び出すメソッドはインスタンス化できません。
そこでstaticをつけることでインスタンス化しなくても呼び出せるようにしているのです。

# static変数
staticはメソッドだけでなく変数にもつけることができます。
書き方としては以下の通り。

```java
class Sample{
    public static int num = 1;
}
```

ではインスタンス変数を用いることでなにがうれしいのでしょうか。
static変数を用いることでそのクラスから生成されたすべてのインスタンスで共有される値になります。

例えば以下のようなクラスがあるとします。
これを実行すると、、
```java
public class Store {
	public static int num = 1;
}
```

```java
public class Driver {

	public static void main(String[] args) {
		Store st = new Store();
		Store at = new Store();

		st.num = 2;

		System.out.println(at.num);
	}
}
```
```:実行結果
2
```
となります。
ここからわかる通り、直接的にat.numに触れていないにも関わらずat.numの値が変わっていることがわかります。（ちなみにstaticを外して実行すると実行結果は「1」になります）

以上がstaticの代表的な使い方です。
おまじないを少しでも減らしていきましょう！
【ServiceNow】Utahリリース　フローのアイテムをサブフローに変換する（Flow Designer）

Utahへのバージョンアップで新規追加された機能についてまとめます。

Flow Designerにてフローに配置した各種アイテムをフローの画面上からサブフロー化できる機能が追加されました。

今まではフローを作成したもののいくつかのアクションをサブフロー化したくなった場合は、
新たにサブフローを作成し直し、フローから１つずつアクションを削除していましたが、
今回の新機能によりアクションのサブフローへの移行がとても楽になりました。

https://docs.servicenow.com/ja-JP/bundle/utah-build-workflows/page/administer/flow-designer/task/convert-items-subflow.html

## 事前準備
プラグインのインストール等の事前準備は不要です。
 flow_designer または adminロールが付与されているユーザで利用可能です。

## 操作手順
1.フローにアクションを配置すると「複数選択」リンクが表示されるのでクリックします。
![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/96d3b8ae-4e88-38ec-6d58-96627377c404.png)


2.アクション番号横にチェックボックスが表示されるため
サブフロー化したいアクションのチェックをON、
画面右側の「サブフローに変換」をクリックします。
![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/0e38c419-7e4f-d74e-83da-7faaf2c29aa3.png)


3.「アクションをサブフローに変換」ダイアログボックスが表示されるため、
サブフロー名やinput/output項目名を必要があれば変更して「サブフローに変換」をクリックします。

※input/outputには各アクション実行に必要な項目が自動で設定されていました！
とても便利です。
![画像4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/c3d368e6-6998-d01b-4d9c-6d1761d2f329.png)


## 結果確認
### サブフロー
サブフローが作成されました。
![画像5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/1af7cf6d-6f4c-0122-b365-52c1de793b3c.png)

保存済、公開済の状態です。
![画像6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/bab6474e-6449-6e2f-385d-258ec80aa9f3.png)

### フロー
フローからはアクションが消え、生成されたサブフローがセットされた状態になっています。
![画像7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/a83515ff-31d6-74d1-f145-9783cfdaf06a.png)


## 終わりに
フローのアクション数が多くなると保存や公開に時間がかかるなど影響が出てしまいます。
その対策の１つとしてアクションのサブフロー化を行っていました。

冒頭にも記載したとおり今まではサブフローを手動で新規作成し、
サブフローに移したアクションをフローから削除をする必要がありましたが
今回のバージョンアップでそれが不要となりました。

またinputやoutputの定義も、サブフローの保存も自動化されています。
Flow Designerでの開発工数がかなり削減されるのではないでしょうか。
Utahバージョンへアップグレードした際は活用したい新機能の１つです。
EventBridgeによる重複起動を防ぐ(Spring Batch)

## 背景
JOBスケジューラー(オンプレ)から RESTAPI (SpringBoot) 経由でバッチを起動している。
オンプレからAWSへの移行に伴い、JOBスケジューラー(オンプレ)から Amazon EventBridge Scheduler へ移行したい。
負荷分散のため、バッチの起動は RESTAPI から ECS タスクによる起動（SpringBatch）に変更する。

## 課題
EventBridge には 以下の仕様が存在します。

https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-troubleshooting.html#eb-rule-triggered-more-than-once

>まれに、単一のイベントまたはスケジュールされた期間に対して同じルールが複数回実行されたり、トリガーされる特定のルールに対して同じターゲットを複数回呼び出されたりする場合があります。

つまり、EventBridge Rules/Scheduler は ECS タスクを稀に重複実行します。😨
Scheduler には重複実行の確率を下げる仕組み ( [フレックスタイムウィンドウ](https://speakerdeck.com/_kensh/the-art-of-eventbridge?slide=31) ) が存在しますが、0 % にはならないようなのでアプリケーション側で対処する必要があります。

## 対処内容
`eventbridge 重複起動` でググるといろいろな方法が出てきますが、SpringBatch の仕組みで対処しました。
SpringBatch の RunIdIncrementer は JOBを実行する度に run.id というJOBパラメータを +1 するので、何回も同じJOBを動かすことができます。
しかし、何回も同じJOBを動かせてしまうと EventBridge の重複実行は防げません。
そこで、以下のような MonthlyIncrementer を作りました。これを RunIdIncrementer の代わりに設定します。
```java
public class MonthlyIncrementer implements JobParametersIncrementer {
    @Override
    public JobParameters getNext(@Nullable JobParameters previousParameters) {
        JobParameters jobParameters = Optional.ofNullable(previousParameters).orElse(new JobParameters());
        YearMonth now = YearMonth.from(LocalDateTime.now());

        return new JobParametersBuilder(jobParameters)
                .addString("run.monthly.id", now.toString())
                .toJobParameters();
    }
}
```
これにより、月をまたがない限り JOB パラメータが変わらなくなり重複実行を防ぐことができます。
日次バッチの場合もほぼ同様です。
Miroの小技集

## ボードの移動

いずれかの動作でボード内を移動可能

- スペース押下しながら左クリック
- 右クリック
- トラックパッド

## 絵文字の利用

左にある「他のアプリ」から利用可能

![スクリーンショット 2023-04-26 12.45.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395131/a4e89812-4cad-01e1-6de0-f63c8f232b8f.png)

![スクリーンショット 2023-04-26 12.31.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395131/17cb63a5-0021-6a09-fbc5-9bf299f35658.png)


## コードブロック

左にある「他のアプリ」から利用可能

![スクリーンショット 2023-04-26 12.47.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395131/f140b722-cf08-ceae-341f-fa2a04d855d8.png)

![スクリーンショット 2023-04-26 12.48.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395131/e3f9c770-0416-d228-f211-531da0e2ead6.png)


## フレームの活用

複数人で操作する際に、領域を明示できる。
フレーム作成後に載せたオブジェクトはフレーム毎移動できる。

![スクリーンショット 2023-04-26 12.35.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395131/a7b52f81-4910-9a75-eba8-924fd6f9b9df.png)
![スクリーンショット 2023-04-26 12.37.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395131/c74c8c9a-f3b0-d15f-f3d5-b83c07dde07f.png)

## 選択

ドラッグで選択できる、選択中にCmd+クリックで部分的に選択を解除できる。

![スクリーンショット 2023-04-26 12.39.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395131/ee476987-836c-1cbc-be1b-3dff11d0548e.png)

## 複雑な選択

オブジェクトが幾つにも重なった状態で、最上部だけ選択したい場合の手順。

1. escで全てのフォーカスを外す
2. 左クリックを長押しする
3. 最上部にあるオブジェクトだけが選択できる

　![スクリーンショット 2023-04-26 12.43.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395131/bec99ab5-eaa0-2684-73db-66e0c3bd82d1.png)
![スクリーンショット 2023-04-26 12.42.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395131/e37e34b3-7f1c-c545-6f17-db2beb74a874.png)

## 他の人の視点を追従する

複数人以上が参加している場合、右上のユーザーアイコンをクリックすることでその人の視点に切り替えることができます。
研修などでMiroを利用する際は、講師の方が今どこをみているか把握しやすい機能です。
ホイール操作マウス操作などですぐに解除できて、相手に影響することはありません。

![スクリーンショット 2023-04-26 12.51.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395131/4764e70c-5c34-2e0e-c465-9bb361bcabe9.png)
Typedocを導入する

 # はじめに
[こちらの記事](https://zenn.dev/arsaga/articles/ba9ec8c004511c#typedoc%E3%81%AE%E6%B4%BB%E7%94%A8)に触発されて`Typedoc`を導入しようと思いました。
そちらの導入メモです。

# 導入
## インストール
[`typedoc-plugin-merge-modules`プラグイン](https://qiita.com/beijaflor/items/b47b8b88845569d66250)も一緒に導入します。
```
$ yarn add -D typedoc typedoc-plugin-merge-modules
```

## 設定
[設定ファイル名はいくつか選べます](https://typedoc.org/options/configuration/#options)が、今回はプロジェクト全体でESMを使う設定をされていることを前提に`typedoc.config.cjs`にします。

```ts: typedoc.config.cjs
const { sync } = require('glob');
const { resolve } = require('path');

module.exports = {
  entryPoints: sync(resolve('src/**/*{.js,.ts}')),
  out: 'typedocs/',
  categorizeByGroup: true
};
```
```json: package.json
{
  ...
  "type": "module"
}

```

ついでに細かいですが、tscのコンパイル対象から除いておきましょう。
```json: tsconfig.json
{
  ...
  "exclude": [
    ...
    "typedoc.config.cjs"
  ],
}
```

## 実行
ver 0.24以降はプラグインの実行のためにCLIのオプション指定が必要です。
```
$ npx typedoc --plugin typedoc-plugin-merge-modules
```

# 参照
https://typedoc.org/guides/installation/
chatGPTにより危機迫る職業ベスト5と今後の生存戦略

# chatGPTにより危機が迫っている職業ベスト5と今後の生存戦略

## はじめに
現在、AI技術が進化することで、多くの職業が危機的な状況に陥っています。特に、自然言語処理技術を応用したchatGPTは、さまざまな業界で利用されるようになり、これまで人間が行ってきた業務を自動化することが可能になっています。ここでは、chatGPTによって駆逐される職業ベスト5と、その対策について考えてみましょう。

## 置き換わるとされる職業ベスト5
1. データ入力作業
2. コールセンター・テレマーケティング業務
3. カスタマーサポート
4. コンテンツライター
5. 一般事務作業

以上の職種は、chatGPTによる自動化の対象となっています。特に、音声認識技術や自動手書き文字認識技術が進化することで、データ入力作業は不要になっていくと予想されます。また、FAQ回答や商品案内の自動応答ができるようになることで、カスタマーサポート業務も代替される可能性があります。

## 今後の生存戦略
chatGPTによる職業の危機から生き残るためには、以下の対策が考えられます。

1. AI・プログラミングスキルの習得
AI技術を扱えるエンジニアが増加することで、新しいサービスや製品を開発することができます。そのため、AI・プログラミングスキルの習得は必須です。

2. コミュニケーション能力の向上
AI技術を活用した顧客対応は24時間体制で行われるため、コミュニケーション能力が求められます。特に、英語力やマルチリンガルなどの語学力も重要視されるでしょう。

3. クリエイティブなアイデアの提供
chatGPTは、プログラムされた範囲内でしか動くことができません。そのため、クリエイティブなアイデアを持ち込み、人間的な価値を生かしたサービス開発を行うことが求められます。

4. 人間的な価値の提供
AIが担うことができない人間的な価値、たとえば感情や思考の面でのサービス提供などを行うことで、自分たちにしかできない付加価値を提供することが必要です。

## 最後に
AI技術の進化は、今後も止まることはありません。その中でもchatGPTの自然言語処理技術は、職業の自動化を促進することが予想されます。しかし、これによって一部の職種が消失すると同時に、エンジニアにとっては新しいチャレンジの機会でもあります。今後、AI技術を活用しつつ、人間の持つ付加価値やクリエイティブ性を生かしたサービス・製品の開発が求められるでしょう。
研究室の進捗報告に Notion を活用した話

# 当研究室、**進捗報告がない**研究室なんです。
　忙しそうな上司に声をかけずらい時ってありますよね。当研究室の教授（上司）は、統計や機械学習などの概念を数学的に且つ理論的に取り扱うお方です。そのため、数学科だけでなくデータサイエンス学科などの色々なところから引く手数多な状態です。そんな状態なので「教授忙しそうだな、後で聞こう」みたいに、**若干**コミュニケーションが取りずらい場面が多々ありました。

　コミュニケーションを楽に取るために何年か前からSlackが実装されました。チャンネルを立てて、業務連絡から雑談までチャンネルを分けて話すことができるのは便利ですよね。そんなこともあって、今では研究室の必需品となっています。

　しかし、今回 Notion で進捗管理を作ることになりました。というのも、Slackが進捗報告に**向かなすぎる**ことが発端です。Slackだと、週ごとに長文コメントを送信するとスレッドが鬼のように長くなって大変ですし、各メンバーごとにチャンネルを増やすとチャンネル管理が大変になります。**Slackでどうにかしたかったがやりづらい**ということで、Notionでの進捗管理に白羽の矢が立ったという訳です。

:::note info
ちなみに、GitHubでの進捗管理もあるようです。メンバーの中には、GitHubの名前すら知らない人もいたので活用しませんでした。
[研究進捗報告をGitHubでやってみた](https://note.com/akita11/n/n6d991c40d154)
:::

## こんな感じになりました。
　実際に作ってみたものが以下になります。（動かしてみたい方は「複製」すると動かせると思います）
https://www.notion.so/2bf1a9b8cab74a92a146c21c95ca71f7?pvs=4

### データベースAの動き
　データベースAの動きは、**報告書**と**週番号**管理です。報告書を作成する場合は、この表に追加します。追加した際には予め作成したテンプレートが出てくるので、メンバーごとの書式が変わることがないようにしています。また、報告日を登録すると**週番号**（2023年の4週目なら202304）が自動で算出されます。
　研究生は、ここに週次報告をしていくことになります。
![スクリーンショット 2023-04-26 12.17.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3341148/9173b52d-6855-7436-0953-dc52f49195be.png)

### データベースBの動き
　データベースBの動きは、**週番号の照合**と**メンバー管理**です。今週の週番号とメンバーの報告書に付与されている週番号が一致したときにチェックマークを付けるようにしています。また、メンバーごとにページを与えることで、週次報告以外でまとめておきたい情報があればメモできるようにしました。
　教授（上司）はこの表を確認して「誰が提出していないか」を判断できます。
![スクリーンショット 2023-04-26 12.22.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3341148/2b8abc4b-19ca-ab02-b1ff-da19bd1f447c.png)

### その他、まだ使いづらいところ
　1つはNotionとSlackの併用は大変じゃないか？という点です。Slackは使い慣れていますが、Notionは使い慣れていません。また、現在はSlackとNotionを連携させていないので、研究室全体が2つのアプリケーションを併用する努力が必要です。
　進捗報告以外にも気になったことを貼るページや全体に共有したいことな度をまとめるページなど、Notionを使いこなせるようになればいいなと思っています。
macのdocker desktopでVirtioFSを使おうとしたらローディング画面から進まなくなった件

macのdockerが遅いのは周知の事実ですがVirtioFSが速いよ！って話を聞いたので使ってみました。

設定画面から簡単に変えられるのですが、そんな気軽な設定変更がまさか半日docker使えなくなることになるとは・・・
今回は同じような方が居たときのために復旧手順の１例として残しておきます。

![SS 2023-04-26 10.17.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240634/e1f330a1-8dac-ed1a-625a-abab55f79b6e.png)

`gRPC FUSE`から`VirtioFS`に変更してApply&Restartするだけで使えるようになるのですが、ずーっとローディング画面が出続けるという問題に遭遇しました。（４時間ぐらい）

さすがに遅いし明日の仕事に差し障りある、ということで以下を実施してみました。

- 画面上からClean/Purge dataを実行
    - An unexpected error occurredで動かない
- 画面上からReset to factory defaultsを実行
    - やはりAn unexpected error occurredで動かない
- OS再起動
    - dockerを起動した際に、同じくローディング状態になって進まない
- アプリを削除して、再インストールする
    - dockerのデータが残っているのか、同じ状態になる

何やっても駄目で結構焦りました。

Resetしようとしたことから分かる通り、ImageやVolumesは諦めました。
とはいってもアプリ開発で使っているDBデータなどは永続化していることが多いので、自分の場合はそんなに被害は大きくないことに気づきましたので、手動での削除方法をしらべて実施することにしました。

その手順について記載します。
`念の為言っておきますが、自己責任でよろしくお願いいたします`

```
# 1. docker系のプロセスは全部落としておく

# 2. com.docker.xxxの２つを一旦バックアップ(消すの怖かったので。。。
mkdir ~/docker-backup
sudo mv ~/Library/Containers/com.docker.* ~/docker-backup

# 3. 以下を編集して、filesharingDirectoriesを空配列にする(記述をどこかにバックアップしておく
## "filesharingDirectories": [
##  ],
vi ~/Library/Group\ Containers/group.com.docker/settings.json
```

上記実施後、dockerを起動すると正常に起動するようになりました。

Imageなどは全部飛んでしまいましたが、上記で書いたとおりdocker上で使っていたデータは永続化していたりするのでそんなに被害はありませんでした。

再構築でnpm@latest的な記述が今実行するとバージョン不一致でエラーになるなど、最新状態での構築見直しになったので良かったかなとポジティブに考えるようにしています。

これで、ようやく念願のVirtioFSも使えるようになりました。

---

参考) https://stackoverflow.com/questions/69552636/cannot-launch-docker-desktop-for-mac
iOSシミュレーターで写真アプリのディレクトリを確認する

## 環境
macOS Ventuna バージョン13.3.1（22E261）
iPhone 14 iOS 16.2（Simulator）

# Finderで確認する
1. Finderで`~/Library/Developer/CoreSimulator/Devices`へ移動
2. Devicesのフォルダ内から、該当のシミュレーター（変更日などで確認）を選択する。
3. `data > Media > DCIM > 100APPLE`と潜っていくと、写真アプリに保存されているファイルが確認できる。

`~/Library/Developer/CoreSimulator/Devices`
(/Users/xxxx/Library/Developer/CoreSimulator/Devices)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/e255f46d-64a8-ad46-3c44-a6b93e30082e.png)

`data > Media > DCIM > 100APPLE`
(/Users/xxxx/Library/Developer/CoreSimulator/Devices/5DBBE119-D35A-4DFA-9F7B-5FFC8E8BFCB4/data/Media/DCIM/100APPLE)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/e8ff1c47-aa10-4376-052d-0d80b6ebff6a.png)


# メモ
- 写真ライブラリに保存されるファイル名はOS側の仕様で自動的に”IMG_xxxx.JPG”となる様子。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/c93df203-b55e-9763-2863-a385f99faf1d.png)
![Simulator Screen Shot - iPhone 14 - 2023-04-26 at 12.17.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245300/a34b65f3-6ff5-fd3a-5bf5-dd0d5617c0af.png)

- 写真アプリ（ライブラリ）に保存されているファイル名の変更については、ユーザーがiCloudなどにアップロードしてファイル名を変更する方法などがある。
- 今回は要件がアプリ内でダウンロードしたファイルは写真アプリに保存することなので、ファイル名の扱いについては特に考慮不要か。
- Androidの場合はOSや機種ごとに仕様が異なる気がするので、要調査。
Fixing docker 23 build failure due to ERROR: mkdir /root/.docker/buildx: read-only file system

In some cases such as passing .docker/config.json to a container, you would mount /root/.docker as read-only. But this makes buildx wrong due to `mkdir /root/.docker/buildx: read-only file system`. The thing is, buildx is the default of docker 23.

I found that specifying **BUILDX_CONFIG** (eg `BUILDX_CONFIG=/tmp/buildx`) can resolve this issue. /tmp/buildx will be gone after exiting the container, but saving persistent config of buildx inside container is not useful anyway.

----

For my reference later, this is how I found the solution:

1. ~/.docker/buildx/activity の存在を思い出す
1. https://docs.docker.com/build/release-notes/#0100 から https://github.com/docker/buildx/pull/1439 を発見する
1. https://github.com/docker/buildx/blob/v0.10.4/store/store.go のNewで失敗していることを把握する
1. https://github.com/docker/buildx/blob/v0.10.4/store/storeutil/storeutil.go
1. https://github.com/docker/buildx/blob/v0.10.4/util/confutil/config.go とたどり、当該Newの引数はBUILDX_CONFIGでオーバーライドできることを把握する

(我ながら目茶苦茶なたどり方だなぁ)
ESP32を使ったパルスハンドルのサンプル

# パルスハンドルとは
CNC工作機械で使うことの多い手動パルスハンドルです。AB位相信号を使っているエンコーダーやリニアスケールでも同じプログラムで処理できるはずです。差動出力の場合はAB位相信号のマイナスも同時に出力するタイプもあります。購入時には確認が必要です。


![IMG_0843.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683949/acc7ccf8-5247-8be2-858b-218e056e0d8f.jpeg)
![IMG_0844.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683949/ab688496-1680-392b-22d0-ebc2932b18d0.jpeg)

※ESP32は3.3V入力なので10kΩ程度の抵抗を入れてください。

5V系・3.3V系信号レベル変換
https://www.cepstrum.co.jp/hobby/5v33v/5v33v.html


# ESP32でのサンプルプログラム
割り込みによってAB位相信号の変化を検出しカウントします。

GPT3よりESP32のカウンターについて
"ESP32には、16チャンネルの8ビットカウンター/タイマーであるLED PWM、または2チャンネルの16ビットカウンター/タイマーであるRMT(Remote Control)があります。ただし、AB位相カウンターを実装するには、外部のカウンター回路を使用するか、GPIOピンを割り込みに割り当てて、割り込みハンドラでカウントする必要があります。"


```c

#include <esp32-hal.h>

#define ENC_A  18 // Encoder Phase A input pin
#define ENC_B  19 // Encoder Phase B input pin

int pulseCount = 0;

void IRAM_ATTR handleEncoderInterrupt() {
  static bool aLastState = false;
  static bool bLastState = false;
  
  bool aState = digitalRead(ENC_A);
  bool bState = digitalRead(ENC_B);
  
  if((aLastState == LOW) && (aState == HIGH)  && (bState == LOW)){pulseCount++;}
  if((bLastState == LOW) && (bState == HIGH)  && (aState == HIGH)){pulseCount++;}
  if((aLastState == HIGH) && (aState == LOW)  && (bState == HIGH)){pulseCount++;}
  if((bLastState == HIGH) && (bState == LOW)  && (aState == LOW)){pulseCount++;}

  if((bLastState == LOW) && (bState == HIGH)  && (aState == LOW)){pulseCount--;}
  if((aLastState == LOW) && (aState == HIGH)  && (bState == HIGH)){pulseCount--;}
  if((bLastState == HIGH) && (bState == LOW)  && (aState == HIGH)){pulseCount--;}
  if((aLastState == HIGH) && (aState == LOW)  && (bState == LOW)){pulseCount--;}


  
  aLastState = aState;
  bLastState = bState;
  
}

void setup() {
  Serial.begin(115200);
  pinMode(ENC_A, INPUT);
  pinMode(ENC_B, INPUT);
  attachInterrupt(digitalPinToInterrupt(ENC_A), handleEncoderInterrupt, CHANGE);
  attachInterrupt(digitalPinToInterrupt(ENC_B), handleEncoderInterrupt, CHANGE);

}

void loop() {
  Serial.printf("%d\n",pulseCount);
  delay(10);
}
```

# 動作確認
シリアルモニタにカウント数を表示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683949/58423207-07d8-186f-579a-a4cc0b21ef6d.png)
IBM Cloud: ID Federation方式の比較（IBMid Federation v.s. IBM Cloud App ID)

P.S. 
頑張って資料を読んだりまとめた後に、ほとんど[ここ](https://cloud.ibm.com/docs/account?topic=account-federation-option-for-you)とか[ここ](https://www.ibm.com/blogs/solutions/jp-ja/ibm-cloud-saml-federation-guide/)に載っていた・・・。削除するのが勿体無いので念の為残しておきます。





# IBMidとは

[このBlog](https://www.ibm.com/blogs/solutions/jp-ja/lets-create-ibmid/)より引用

> IBMid はIBMのアプリケーション、コミュニティー、サポートといった様々な分野のサービスを利用する際に使用する単一のユーザー ID です。例えばIBM ソフトウェア製品のダウンロード、サポート・コミュニティーから製品サポートへのご質問の際に必要となります。

IBMidとして特に理解しておく必要があるのは以下のポイントである。

- IBM Cloudのみならず、IBM全般のサービスを利用するために必要なID
- IBMidは、メールアドレス
- IBMidは、IBMが管理しているが、IBM Cloudで管理している訳ではない。IBMidのパスワードルールやIBMidのパスワードリセット方法などは[ここ](https://www.ibm.com/ibmid/myibm/help/us/helpdesk.html)を参照。
- IBM Cloudにログインする際にはIBMidを使うのがデフォルト

# IBMidを使わないIBM Cloudの利用方法

先述の通り、IBMidはIBM Cloudではなく、IBM全般で管理されているIDである。ID情報はIBMによって管理されており、パスワード変更もIBMのサイト経由で行う。
しかし、IBM Cloudでは、こうしたID管理やパスワード管理を自身が所有しているID管理システム、すなわちIdentity Provider(IdP)と連携して行いたいという要件にも対応しており、

- IBMid Federation 方式
- IBM Cloud App ID 方式

の2つが存在している。どちらを使うべきかは[IBM Cloud SAML Federation Guide](https://www.ibm.com/cloud/blog/ibm-cloud-saml-federation-guide)に記載されているが、以下で簡単にまとめてみた（認識の間違いがあるかもしれないので、記述内容は上記のガイドや、[IBM Cloud docsの記述](https://cloud.ibm.com/docs/account?topic=account-federation-option-for-you)を正としてください）。

||IBMid Federation方式|IBM Cloud App ID 方式|
|:--|:--|:--|
|Account Owner（IBM Cloudのアカウント管理者）|外部IdPで管理されたIBMidでも可能|対応していない|
|Email address|必要(IBMid=Email addressなので）|不要|
|コスト|不要|App IDの費用が必要|
|Federationのセットアップ|IBMid federation teamと手動での対応が必要。[こちら](https://ibm.box.com/v/IBMid-Federation-Guide)がガイド。|App IDを購入したあと、利用者が自身で構成可能|
|Federationのメンテナンス|IBMid federation teamと手動での対応が必要。|利用者が自身でApp IDを操作することで可能|
|Federationが有効となるスコープ|IBMidを利用するIBMのサービス全て(IBM Cloudに限定されない）|対象のIBM Cloud アカウントのみ|
|Accountメンバーの招待|IBMidは複数のIBMサービスにまたがって共通のため、IBM Cloud アカウントごとに招待が必要（そのあと、アカウントごとに権限を付与する必要がある）|どのIBM Cloud App IDと連携するかはIBM Cloud アカウントごとに構成するため、個別の招待は不要。**ユーザーは初回ログイン時に自動的に追加される**。|
|Account間の切り替え|IBMidは複数のIBMサービスにまたがって共通のため、一度そのIBMidでログインしたら、別の招待済みのIBM Cloudアカウントにも追加認証なしで切り替え可能|App IDはIBM Cloudのアカウントごとに構成するため、別IBM Cloud アカウントにログインする際には別途認証が必要|
|SAML assertions in Access Group Dynamic Rules|利用可能|利用可能|
|（外部IdP以外の）信頼性|IBMid自体はグローバルサービスであり、DC障害時にも別DCにスイッチして外部IdPと連携が可能。|App IDはリージョナルサービスであり、例えば東京リージョンのApp IDを利用中に、東京リージョン障害が発生すると、この方式ではログインできなくなる。その際には別リージョンのApp IDを利用するなどの運用上の考慮が必要。<br><br>一応App IDは東京リージョン・大阪リージョンの双方で提供可能であり、Identity providersとして最大5つまでApp IDを登録可能。|
|Customer Portalへのログイン方式|`https://cloud.ibm.com`|`https://cloud.ibm.com/authorize/xxxxxx`というアカウント固有のURLを利用|
|ibmcloud CLI|利用可能|利用可能|
【JavaScript】スコープについて

# はじめに
この記事はJS初級者が中級者を目指して学習した内容のメモであることをご承知おき下さい
## JSの主なスコープ
- グローバルスコープ
- 関数スコープ
- ブロックスコープ
- モジュールスコープ

※ここではモジュールスコープ以外のスコープについて記述します
## グローバルスコープ
グローバルスコープとはプログラム全体で利用可能な変数や関数が存在する領域のこと。
グローバルオブジェクトとほぼ同義でwebブラウザ環境だとwindowオブジェクトのこと指す。
```js
const hello = 'hello';
function a(){
  console.log('a is called');
}
```
上記の定数helloや関数aのようにJSファイルの直下で宣言した変数や関数はプログラムのどこからでもアクセスが可能になる。
ただし、グローバルスコープを過剰に利用するとコードの管理が難しくなり、バグの原因となることがある（グローバルスコープの汚染）ため、適切な管理が必要。
## 関数スコープ
関数内で宣言された変数や関数がアクセスできる範囲のこと。関数スコープ内で宣言された変数は、その関数内でのみアクセス可能。
```js
function a(){
  const hello = 'hello';
  console.log(hello);
}
a(); // => hello
console.log(hello); // Uncaught ReferenceError: hello is not defined ②
```
①関数スコープ内でならば定数helloへアクセスすることは可能だが、②関数スコープの外部からは定数helloにはアクセスできず'Uncaught ReferenceError'となる

※補足　関数宣言自体はグローバルスコープで扱われる
## ブロックスコープ
ES6から導入されたletとconstのみで生成されるスコープで、if文やfor文などの波括弧{}で囲まれた範囲のこと。
varではブロックスコープスコープは無視されるので現在はvarの仕様は推奨されない。
```js
{
  var a = 0;
  let b = 0;
  const c = 0;
}
console.log(a); // 0 ①
console.log(b); // Uncaught ReferenceError ②
console.log(c); // Uncaught ReferenceError ③
```
① varで宣言された変数aはブロックスコープの外からアクセス可能
②、③ letやconstで宣言されたbやcはブロックスコープの外からアクセス不可

:::note info 
## ブロックスコープ内の関数について補足
①ブロックスコープ内で関数宣言した関数aをブロックスコープ外から呼び出す
```js
{
  function a(){
    console.log('a is called');
  }
}
a(); // a is called
```
関数aは実行される
（関数宣言自体はグローバルスコープで扱われるため）

②ブロックスコープ内でconstを使用した関数式で定義した関数aをブロックスコープ外から呼び出す
```js
{
  const a = function(){ 
    console.log('a is called') ;
  } 
} 
a(); // Uncaught ReferenceError
```
関数aは実行できない
（関数aはconstを使用した関数式で定義されておりconstはブロックスコープを生成するため、ブロックスコープ外からは参照することができないため）
:::
【Obsidian】ノートにある画像をコピー

## はじめに

Qiitaの記事を書くときや業務のメモで
Obsidianというメモアプリを利用しているが、貼り付けた画像をそのままクリップボードにコピーできず困っていたが解決したので共有です。

## 結論

`Copy Image and URL in Preview`というコミュニティプラグインを導入することでクリップボードへのコピーが可能になる
https://obsidian.md/plugins?id=copy-url-in-preview


画像を右クリックを押し「Copy image to clip board」を選択することでクリップボードにコピーが可能

![スクリーンショット 2023-04-26 11.33.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/e6c129f5-81bc-98d0-b877-e9dab410e2e5.png)
jetpack composeでHorizontalPagerを使うときに気をつけること

# 初めに
今回は`jetpack compose`で`HorizontalPager`を使うときに自分が詰まったところをを書いていこうと思います
### 本文
`jetpack compose`で`HorizontalPager`を使う時に`accompanist`の記事が散見されるため、ページが切り替わったどうかを確認するのに`accompanist`の
```kotlin
derivedStateOf {
                val offset = calculateCurrentOffsetForPage(page)
                (-1.0f < offset) and (offset < 1.0f)
            }
```
を使ってる方や使おうとしてる方もいらっしゃると思いますが、実際には公式から既に`HorizontalPager`が出ているので下記のものを使うのが正しくなっています
```kotlin
LaunchedEffect(pagerState) {
                snapshotFlow { pagerState.currentPage }.collect { page ->
                   
                }
            }
```
下記の公式URLからもアナウンスはされてるのですが、`accompanist`時代の記事を参考に作ろうとすると挙動がおかしくなるので注意しましょう
https://google.github.io/accompanist/pager/#migration
### 最後に
今回は備忘録としてすぐに自分が確認できるように記事に残しました
どなたかのお役に立てれば幸いです
選択リスト


+ [RecordTypeのまとめ](https://qiita.com/Keiji_otsubo/items/0469aafa263da3b31f9f)

# 新しいレコードの作成中に、デフォルトの選択リスト値が選択されていません。

+ [Default picklist value is not selected while creating new Record. Why?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000PeRJl)

:::note
Does this object have a record type?

Each record type has its own Default. You have to set the default under each record type. 

Go to Setup -> Object Manager -> your object -> Record Types -> Open Record Type - Not Edit -> Picklist value to set default

https://developer.salesforce.com/forums/?id=9062I000000IO54QAG
:::


# レコードタイプ毎で表示されている選択リスト値の取得

+ [レコードタイプ毎のセールスプロセスや選択リストの表示一覧内容取得について](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007clLs9)

現在、システムの資料作りの業務がございまして、その中に各レコードタイプ毎で表示されているセールスプロセスや選択リストの内容をまとめるという作業があります。

直ぐにその内容を出力する処理の食い立て方が分からなかったので、愚直に選択肢の内容をctl+cでコピーして資料作りを進めようとしたのですが選択肢の内容はコピーが出来ませんでした

:::note
レコードタイプ と選択リストの値の関係はメタデータの[RecordType](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_recordtype.htm)のRecordTypePicklistValueの中にレコード タイプを定義する選択リストと有効な値の組み合わせとして格納されています。

パスは メタデータの [PathAssistant](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_pathassistant.htm)みたいです。
この中にレコードタイプの情報があります。


メタデータの取得ですが以下の方法があります

Salesforce CLIでメタデータ取得(retrieve)

メタデータ API を使用したワークベンチでの取得およびリリース
https://help.salesforce.com/s/articleView?id=000382512&type=1 
:::
【SSDモデル】Numpyイメージの色相を変える

ちんたらとディープラーニングの物体検出(SSD)のコードを読んでいます。コードを読んでいると、これをコーディングした人のプログラミング力を思い知らされると同時に、自分のPython力の足りなさに絶望的になります。しかし最近は強力な助っ人を得ることができたので、ちんたらとですが読み進めている状況です。助人は **ChatGPT(Bing)** さんです。


Python Numpy のイメージ処理で以下のコードがわかりづらかったので Bing さんに助けてもらいました。やってることはなんとなくわかるのですがね、コードが追いづらい。

```python:
image[:,:,0][image[:,:,0]>360.0] -= 360.0
```

以下のような回答を得ましたが、コードを正確に読みたかったので質問を続けました。

::: note warn
image[:,:,0]image[:,:,0]>360.0 -= 360.0とは、numpyの配列で画像を表したときに、色相の値が360度を超えた場合に360度引くという処理を意味します1。これは、画像の色空間をRGBからHSVに変換したときに、色相の値が0から360の範囲に収まるようにするために必要な処理です。
:::

3 回程度、Bingさんに質問をして、最後に以下の質問にたどり着きました。質問を繰り返すうちにimageという配列名はhsvという名前に変わっていますが、特に意味はありません。


::: note info
hsv[:,:,0][hsv[:,:,0]>360.0] -= 360.0の真偽配列の操作について
:::

以下のような完璧な回答を得ることができました。私にとっては**ブールインデックス参照**と**インプレース演算**を正確に読み取ることがポイントでした。回答の太字は私がつけました。

::: note warn
hsv[:,:,0][hsv[:,:,0]>360.0] -= 360.0の真偽配列の操作については、以下のように説明できます。

まず、hsv[:,:,0]はHSV配列の第一チャンネル（色相）を表す配列です。この配列の各要素は色相の値を持っています。次に、hsv[:,:,0]>360.0は、この配列の各要素が360よりも大きいかどうかを判定する真偽配列です。この真偽配列の要素はTrueかFalseの値を持っています。Trueは360よりも大きい色相の値を持つ要素に対応し、Falseはそれ以外の要素に対応します。

次に、hsv[:,:,0][hsv[:,:,0]>360.0]は、真偽配列を使って色相配列から特定の要素だけを選択する操作です。この操作は**ブールインデックス参照**と呼ばれます。**ブールインデックス参照では、真偽配列と同じ形状の配列から、真偽配列のTrueに対応する要素だけを抽出できます。** つまり、hsv[:,:,0][hsv[:,:,0]>360.0]は、色相配列から360よりも大きい色相の値を持つ要素だけを選択した配列です。

最後に、-= 360.0は、選択した配列から360を引くという演算です。この演算は**インプレース演算**と呼ばれます。**インプレース演算では、元の配列の値を直接書き換えます。** つまり、-= 360.0は、色相配列の360よりも大きい色相の値を持つ要素から360を引いて、その結果を元の色相配列に反映させるという操作です。

以上がhsv[:,:,0][hsv[:,:,0]>360.0] -= 360.0の真偽配列の操作についての説明です。詳しくは以下の参考サイトやドキュメントをご覧ください。
:::


つまり、hsv[:,:,0][hsv[:,:,0]>360.0]は360以上の要素を抽出し、続くインプレース演算でその要素から360を引いているのです。インプレース演算なので、オリジナル配列　hsv[:,:,0]　の要素が直接変更されているわけです。なかなかNumpyの多重配列操作に慣れていないと追いにくいコードでした。
in a frame because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self


+ [VisualforceページにBoxNotesを埋め込んだ際のERROR（埋め込みウィジェット使用）](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000PePv1)

英語の内容ですが似たようなエラーメッセージの回避策があります。

Whitelist Salesforce domain as below

1. Go to Setup > Session settings > "Whitelisted Domains for Visualforce Inline Frames"
2. Click Add Domain
3. Add: *.my.Salesforce and Save.


https://issues.salesforce.com/issue/a028c00000qPxIiAAK/apex-pages-are-served-from-separate-domain-causing-vf-pages-not-to-render-in-page-layout

リモート サイトを作成するようなことが提案されています。
https://salesforce.stackexchange.com/questions/262697/content-security-policy-error-while-loading-apex-iframe
【Mac】Logicool MX Ergoの設定 (VSCode編)



## はじめに

Logicool MX Ergoを利用して、VScodeの以下の操作をマウス上で行う方法を共有します。

- 関数ジャンプ：関数の定義にジャンプする
- 戻る：関数の定義元にジャンプした後、元の場所に戻る
- 進む：戻るボタンで元の場所に戻った後、再度関数の定義にジャンプする

### 設定環境

OS：Mac
キーボード設定：US配列

## 設定方法

### 関数ジャンプ

VSCode上のショートカット：`F12`

![Pasted image 20230426111105.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/230f3174-8f52-897f-86b4-6684cb92a3c8.png)


### 戻る

VSCode上のショートカット：`Ctrl`+ `-`

![スクリーンショット 2023-04-26 11.13.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/fb7241f5-f2a0-c9eb-ac97-46cf2403f5f9.png)


### 進む

VSCode上のショートカット：`Ctrl` + `Shift` + `-`

![スクリーンショット 2023-04-26 11.14.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/88206ba1-1aae-752f-33c2-f92561900596.png)
vbsの作法 その65

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

# 練習問題
Windows11でInternet Explorer11を起動して、スクレイピングせよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/87c84f9a-9fc1-60f8-60ca-92f7de4c8588.png)

# サンプルコード

```
Dim objIE
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True
objIE.Navigate "https://ev2-prod-node-red-09632ac9-94e.herokuapp.com/list/table"
Do While objIE.Busy = True Or objIE.readyState <> 4
	WScript.Sleep 1000
Loop
Dim tr
Dim t
For Each tr In objIE.document.getElementsByTagName("tr")
	For Each t In tr.Children
		msgbox t.innerText
	Next
Next
Set objIE = Nothing





```

以上。