OmniAICreator/Qiita-1.07M huggingface dataset:
Tableauで動的なガントチャートを作成し、末尾に固定する方法

## 背景
Tableauのガントチャートの日数は固定した状態で、末尾の日付を動的にしたい。
末尾の日付を動的にすることにより、適切な開始日程を確認したい。
末尾を動かすことで納期を確認できる。

完成イメージは以下の画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/786947/654771f0-dfb1-f974-f8c7-adba2bcb33d2.png)

TableauPublicにも公開中
https://public.tableau.com/shared/9TRF2RJRG?:display_count=n&:origin=viz_share_link

## 方法
### ガントチャートを作成

サンプルスーパー・ストアのデータを使うので、まずはガントチャートを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/786947/3ff2e5c7-880d-913b-6c04-3eb720b5fce4.png)

日数差はDATEDIFF('day',[オーダー日],[出荷日])で算出
データが多すぎるので今回はフィルターで絞っている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/786947/d8b2546b-0a94-9be8-13ea-e6d252306c5f.png)

### パラメーター作成
日付を動的に動かすために、日付のパラメーターを作成する
最小値と最大値で便宜上2016年に絞っている
パラメーターは表示しておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/786947/0ce61704-0027-f896-1699-6c8833c8fb5a.png)

計算フィールドでパラメーター日付をピルとして使えるようにする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/786947/fd58ca90-e912-50f4-abce-0373a8df56fc.png)

### ガントチャート修正
ガントチャートの出荷日を終了日に変更する
縦一列に日付の線が入り、パラメーターをもとに動かせる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/786947/3196b25e-a2c2-cd1e-954b-97690eb64caf.png)

DATEDIFF('day', [出荷日],[終了日])
この計算式で下のガントチャートの出荷日とパラメーターで追加した終了日の日数差を算出
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/786947/77e519b0-fafa-6179-0604-3eace85edcf8.png)

DATE(DATEADD('day',[オーダー日と終了日の日数の差],[オーダー日]))
一つ前のステップで作成した[オーダー日と終了日の日数の差]を使用して、開始日を作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/786947/b5b31f4a-2aa1-5e9a-c54f-7fabb3e2b0f0.png)

開始日と終了日を行に入れて、二重軸の設定を行う
軸の動機を忘れずに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/786947/2258e165-fcd0-025a-4440-e8e6e1fb8da3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/786947/10f2ea06-9da0-945d-e2e6-ef0317de9b8a.png)

マークカードのサイズに日付差を入れる動的なガントチャートが完成
ただし、パラメーターより開始日があとの項目も表示されてしまう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/786947/650e1742-23ff-9950-7aae-27182652c397.png)

フィルターで[オーダー日と終了日の日数の差]がマイナスの項目は除外しておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/786947/75769ecc-ae3b-e799-062e-151d3c5ba3f3.png)
JavaScript周りの情報整理メモ

# JavaScript周りの情報整理メモ

## 最初に

### 用語メモ
- ライブラリは既存技術の機能を使って複数の処理にまとめたもの、フレームワークは利用することで新しい技術を使えるようになるイメージ
- APIとは、JavaScript関連で聞く場合は”仕様”を指します。他言語でAPIと表現する場合にはREST APIを指すことが多いと思うので混乱しないように注意です。


### フロントエンドの学習で便利なサイト
- [JavaScriptとTypeScriptのドキュメントとレポジトリ集](https://github.com/ochtum/js-documents)
　作成中、JS/TSのドキュメントや参考になるレポジトリをとりまとめたもの 

## ライブラリ & フレームワーク


### - JQuery
JavaScriptのライブラリ

### - Next.js
ReactベースのフルスタックWebアプリケーションフレームワーク。Reactはクライアントサイドのみをサポートするが、Next.jsはサーバーサイドもサポートする。

### - Nust.js
ナクスト・ジェイエスと読む。Vue.jsがベースになっているJavaScriptフレームワーク。Vue.jsをより使いやすくする機能を持っている。Vue.jsで記述して、サーバーサイドレンダリングができる。ルーティングもしてくれる。

### - Vue.js
MVCモデルのView層を扱うフレームワーク。コンポーネント構築のためのフレームワークで、Vueで出来ることはReactに似ています。

### - Vanilla JS
何のライブラリもフレームワークも使わないでJSを書くことをいう。語源はアイスクリームの標準的な風味であるバニラ味からきている。querySelectorの登場によってJQuery使わなくてもいいだろうという風潮が生まれて、最速最軽量なJavascript実装というVanillaJSという考え方が生まれた。

### - Node.js
サーバーサイドのjavascript実行環境。npmと呼ばれるパッケージ管理システムを同梱。http通信だけではなく、TCPやUDP通信も可能。

### - React

### - Angular


### - Express
Node.jsで動作するサーバーサイドアプリケーションを開発するためのフレームワーク。

### - Laravel
PHPで記述されたWebフレームワーク。Ruby on Rails、Python Djangoと並んで三大フレームワーク。

### - Vite
豊富な拡張機能を提供する開発サーバー

## パッケージ管理
### - npm
Node.jsに同梱されているパッケージ管理システム。

### - yarn
Node.jsで動作するパッケージ管理システム。npmで使用していたプロジェクト設定ファイル(package.json)がそのまま使える。npmよりインストールが早く、セキュリティが高い。バージョン管理も優れていて、yarn.lockというファイルが作成されて、インストールされたプログラム/パッケージだけではなく、依存しているプログラム/パッケージについてもバージョンが明確に書き込まれている。別環境で実行する場合であってもそれらのバージョンの整合性が保たれるため、バージョン不一致でプロジェクトが動かなくなるこをと防ぐ。

## レンダリングについて
### - SPA
シングルページアプリケーションの略。URLが変わらずにページ遷移が行われるようなアプリケーションをイメージすると良い。
### - SSR
サーバサイドレンダリングにより画面を作成する。要するに、要求されたURLからプログラムがHTMLコンテンツを作成してクライアントに返すよってことです。Node.jsによってJavaScriptでもそれが実現できるようになりました（従来はHTMLとセットでクライアントに渡す形で、クライアント側で動かすことしかできませんでした）、

サーバーサイドレンダリングは、サーバー側のリソース(CPUとかメモリとか)を使うので運用コストが増えます。しかし、クライアント側の動作が早くなるメリットがあります。

クライアントサイドレンダリングは、サーバー側のリソース使用を減らすことができるので運用コストを減らすことができます。しかし、クライアント側のリソースを多く使うことになるので、UXを落とす可能性があります。
エンジニアが知っておくべき請負契約と準委任契約の違い

こんにちは、Kaneyasuです。  
今回は、エンジニア、特にSIerのエンジニアがよく目にする「請負契約」と「準委任契約」の違いについて解説します。

# 業務委託契約とその種類

一般的に、顧客が自社の業務を外部の人に依頼する際には、業務委託契約を結びます。  
IT業界においても、業務委託契約はよく使われる契約形態です。  
業務委託契約には、以下の3つの代表的な種類があります。

| 種類        | 内容                                                                 |
|-------------|----------------------------------------------------------------------|
| 請負契約    | 業務を依頼し、その成果物に対して報酬を支払う契約。                      |
| 委任契約    | 業務の遂行を目的とした契約で、法律行為を伴う。                           |
| 準委任契約  | 委任契約に準じるが、法律行為を伴わない業務を遂行する契約。                |

参考

https://mynavi-agent.jp/knowledge/common/825.html

IT業界では、請負契約と準委任契約がよく使われます。  
委任契約はあまり使われることはなく、筆者も見たことがありません。
これは、エンジニアが法律行為を伴う業務を行うことが少ないためです。

# 請負契約と準委任契約の違い

請負契約と準委任契約は、どちらも業務委託契約の一種ですが、大きな違いがあります。  
一言でいうと、請負契約は「成果物を納品することが目的」であり、準委任契約は「業務の遂行自体が目的」です。  
請負契約では成果物を納品する責任が発生しますが、準委任契約ではその責任は発生しません。

ウォーターフォール開発で言うと、PoCや要件定義は準委任契約、設計や開発、テストは請負契約になることが多いです。  
また、SES（システムエンジニアリングサービス）も準委任契約で結ばれることが多いですね。

PoCや要件定義が準委任契約になることが多いのは、不確定要素が多いため、確実に成果物を納品することが難しいからです。  

システム開発の見積もりを行う際に不確定要素が多いと、リスクを見越して金額が高くなります。
これは、リスクマージンを積んで見積もりを行うためです。
筆者の経験では、まずリスクマージンを積んだ見積もりを作成した上で、PoCや要件定義を準委任契約で実施します。
要件定義終了後に再見積もりを行い、その後のフェーズを請負契約とすることが多いです。
このアプローチによって、見積もり金額が下がるケースがよくあります。

# 請負契約と準委任契約のメリット・デメリット

準委任契約は、成果物の納品義務がないため、一見「楽」と思われるかもしれませんが、それぞれの契約にはメリット・デメリットがあります。

| 契約形態   | 顧客側のメリット                             | 顧客側のデメリット                  | エンジニア側のメリット                     | エンジニア側のデメリット             |
|------------|----------------------------------------------|-------------------------------------|--------------------------------------------|-----------------------------------|
| 請負契約   | 納期と品質が保証される                        | 要件変更が発生すると追加料金が発生する | 納期と品質を守れば良いという明確なゴールがある | 納期と品質を守らなければならない     |
| 準委任契約 | 要件変更が発生しても追加料金が発生しない        | 納期と品質が保証されない               | 納期と品質に追われない                      | 検収や価格交渉が難しい              |

エンジニアにとって準委任契約のデメリットは、検収や価格交渉が難しい点です。
本来、業務を遂行すれば検収は通るはずですが、顧客に対して何らかの進捗や成果を示さないと信頼関係に影響を与える可能性があります。  
信頼関係が揺らぐと、目の前の検収はもらえたとしても次の案件に影を落とすことになります。  
成果が出せていれば何も問題はないのですが、何を持ってして成果かが定まってないのでアピールが困難です。    
そのため、準委任契約では常に顧客との信頼関係の維持に気を配る必要があります。

請負契約では、納期と品質が守られることが前提となりますが、エンジニアにとっては明確なゴールが設定されるため、それに向かって集中して業務を遂行できるというメリットがあります。
極端な話途中でグダグダになっても最後を締めれば問題はありません。  

# 契約形態を混同しない

請負契約と準委任契約は、業務委託契約の一種ですが、その内容は大きく異なります。  
エンジニアとして重要なのは、どちらの契約形態であるかを正確に理解し、その違いを意識して業務に取り組むことです。

たとえば、要件定義フェーズで準委任契約を結んでいるのに、ガチガチに成果物を定めてしまうと、エンジニアとして不利な立場に立たされることになります。
この状況は、曖昧な依頼に対して確定的な成果を求められる状況を生み、結果として社内や顧客からの信頼を損ねる可能性があります。  


請負契約の場合、要件の変更が発生すると追加料金が発生します。
軽微な要件変更は許容されることが多いですが、大幅な変更が発生した場合には適切に料金の交渉を行う必要があります。

この2つの契約形態を正しく理解して業務に取り組むことで、エンジニアとしての信頼性が高まり、顧客との良好な関係を築くことができます。

# まとめ

請負契約と準委任契約は、どちらも業務委託契約の一種ですが、その内容には大きな違いがあります。  
エンジニアとしては、契約形態を正しく理解し、適切に業務に取り組むことが信頼性の向上につながります。
契約形態を混同せずに進めることで、顧客との信頼関係を築き、プロジェクトの成功に貢献できるでしょう。

# 追記

契約の最後となる検収処理についても書いてみました。

https://qiita.com/satoshi256kbyte/items/f8b45563f3145cf6b78a
RAGBuilder覚書

## はじめに

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/6301a645-c9cb-73bd-b635-c5ca087056a3.png)

本記事は、RAGBuilderについての、導入としての紹介を意図しています。

https://docs.ragbuilder.io/

https://github.com/KruxAI/ragbuilder

## 背景

RAG Builderは、LinkedInのLangChainからの2024年10月5日のポストで紹介されていた。

https://www.linkedin.com/posts/langchain_ragbuilder-rag-optimization-ragbuilder-activity-7248361501164482560-F5vG?utm_source=share&utm_medium=member_desktop

Githubリポジトリを見ると、KRUX AIという組織が開発（リード）しているようだ。

https://www.krux.ai/


## RAGBuilder概要

RAGBuilder は、Retrieval-Augmented-Generation (RAG) アプリケーションを自動的に作成するのに役立つツールキットです。

RAGBuilderは、RAGアプリケーションの開発時に重要となるチャンクサイズの決定などの様々なパラメータに対して、ベイズ最適化を使用して、ハイパーパラメータ チューニングの実行を助けます。
RAGBuilder はこれらの構成をテストデータセットに対して評価することで、データに最適なセットアップを特定できるといいます。

さらに、RAGBuilder には、定義済み RAG テンプレートがいくつか含まれており、短期間でのRAGセットアップを実現します。
また、RAGBuilderは、WEBのインターフェースを提供し、RAG 構成のセットアップ、確認をガイドします。
【基本情報】独学マラソン プロジェクトマネジメント - EVM Day 6

集中すること　強みを基盤とすること　世の中を大きく変える物であること

:::note worn
この記事は自分用の備忘録です。
:::



# EVM (Earned Value Management) とは

納期だけじゃなく、💰もきちんと管理しようね

# シミュレーションしないと覚えられないので..

### シミュレーションするための仮定
- 受注額: 100万円
- エンジニア単価: 4000円/時間
- 目標粗利: 30%（コスト70万円　利益30万）
- 工数: 1人月（約160時間）
- 半月後に進捗確認をする

### 目標達成するための計算（BAC）
- 総コスト
    - 100万円 * 0.7 = 70万円
- 1人月の工数
    - 160時間 * 4000円 = 64万円
- 外部コスト
    - 70万円 - 64万円 = 6万円

総コスト内に1人月で十分おさまるので現実的である

### PV（計画予算）
- 予算計画通り進んでいるか
    - 開発開始から半月後に計測すると
        - 70万円 * 0.5 = 35万円

### EV（出来高）
- 実際にどれくらいの成果が得られているか
    - 半月経って実際には40%しか達成できていなかった場合
        - 70万円 * 0.4 = 28万円
            - 28万円の価値しか生み出せていないということ
                - 28万円使ったということではなく、あくまでアウトプット

### AC（実際に発生したコスト）
- 成果に対してどれくらいのコストを使ったか
    - 半月経っているので
        - 80時間 * 4000円 = 32万円
            - EV28万円に対してACが32万円

### BAC（完成時総予算）
- 最終的に全体でかかる予定のコスト
    - 前もって計算している70万円のやつ

<br>

# 分析するぞー！

### SV（スケジュール差異）
- SV = EV - PV
    - SV = 28万円 - 35万円 = -7万円
        - 計画より進捗が遅れている

### CV（コスト差異）
- CV = EV - AC
    - CV = 28万円 - 32万円 = -4万円
        - コストが計画より超過している

### SPI（スケジュール効率指数）
- SPI = EV / PV
    - SPI = 28万円 / 35万円 = 0.8
        - 計画より遅れている

### CPI（コスト効率指数）
- CPI = EV / AC
    - CPI = 28万円 / 32万円 = 0.875
        - コスト効率が低く、コストがかかりすぎている

### ETC（残作業コスト予測）
- ETC = (BAC - EV) / CPI
    - ETC = (70万円 - 28万円) / 0.875 = 48万円
        - 残りの作業に48万円必要
            - 粗利下がるのを許容する？
            - 業後キャッチアップでアウトプット効率を上げる？

### EAC（完了時コスト予測）
- EAC = AC + ETC
    - EAC = 32万円 + 48万円 = 80万円
        - 最終的に80万円かかる見込み

### VAC（完了時コスト差異）
- VAC = BAC - EAC
    - VAC = 70万円 - 80万円 = -10万円
        - 予算を10万円超過する見込み

<br>

### 分析完了🙌

# 感想
EACを定期的に算出すればなんかやる気出そう
従業員が売上ベースの視点を持ちながら仕事ができれば組織はぐんぐん成長する気がする
自分たちのスキルが💰で数値化されるからわかりやすい
まぁでも、売上命でギスギスした環境は嫌なのであくまでポジティブにEVMを使いたいな


# 参考

https://it-trend.jp/project_management/article/33-0019
Three-VRMで顔パーツの表情パラメータを直接指定する

# 概要

例えば口だけを笑顔にしたいとき、わざわざ表情登録をせずにパラメータ値を直接指定する方法です。VRoidStudioの顔パーツごとの表情パラメータの指定みたいな感じです。

私の別記事([Three-VRMで組み合わせて表情を登録する(Custom Expression)](https://qiita.com/nobrin/items/9085fed1ef5b8b508290))といった方法が一般的な方法だと思いますが、強制的に特定の顔パーツ(口だけ)の表情パラメータを指定する方法です。

# 動作確認環境

- VRoidStudio 1.29. 1 -- VRMファイルのエクスポート
- Three-VRM 3.1.2
- Firefox 131(Windows 10 22H2)

# 実装

最終的に、FaceグループにバインドされているSkinnedMeshオブジェクトの`morphTargetInfluences`の対応するインデックスの値にウェイトを格納し、`render()`されると反映されるようです。

これを実現するには、`requestAnimationFrame()`に渡されるコールバック中でそのように指定します。例えば最低限の実装は以下のようになります。

ここでは`scene`はルートの`Scene`オブジェクトです。

```javascript
// SkinnedMeshのmorphTargetInfluencesを直接指定することで表情を操作する
// FaceグループのSkinnedMesh#morphTagetDictionaryから、目的のmorphTargetIndexを得る
// FaceグループにはFace_(merged)などのSkinnedMeshが登録されている
const DIC = scene.getObjectByName("Face").children[0].morphTargetDictionary;

// 対象となるSkinnedMeshを得る
const meshes = [...scene.getObjectByName("Face").children];

function tick() {
    requestAnimationFrame(tick);
    // render()直前で値を決めることで他の影響を受けないようにする
    // DIC.Fcl_MTH_Funは32
    meshes.map(m => m.morphTargetInfluences[DIC.Fcl_MTH_Fun] = 0.8);
    renderer.render(scene, camera);
}

tick();
```

ここでは、`render()`の直前で値を直接上書きすることで、他のパラメータの影響を受けないようにしています。

VRoidStudioのように、顔パーツの表情パラメータをいじるのってどうするのかな？と思ったので、試してみましたが、それ以外ではあまり使わないかも。

# 参考

- Three-VRMの`VRMExpressionMorphTargetBind.ts:applyWeight()`あたり
    - https://github.com/pixiv/three-vrm/blob/dev/packages/three-vrm-core/src/expressions/VRMExpressionMorphTargetBind.ts#L48
IT現場を強くする 究極のチームビルディング

https://www.amazon.co.jp/IT%E7%8F%BE%E5%A0%B4%E3%82%92%E5%BC%B7%E3%81%8F%E3%81%99%E3%82%8B-%E7%A9%B6%E6%A5%B5%E3%81%AE%E3%83%81%E3%83%BC%E3%83%A0%E3%83%93%E3%83%AB%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0-%E6%96%89%E8%97%A4-%E7%A7%80%E6%A8%B9/dp/4822271862

# 本書を手に取った背景
仕事でチームビルディングについても考える必要があると感じ、読まずにおいてあった本書をてにとった。

# 結論
具体策よりも、体制やコミュニケーションに関する考え方が中心だったが、いろんな発見があり、読んでみてよかった。

# 本書のテーマ
組織の閉塞感に悩み、成果を出せないリーダーはたくさんいる。モチベーションがさがるメンバーもいるので、PMが躍起になって働きかけても改善されない。
そのような状況を打開するためのチーム作りをテーマにしている。

# 個人的なポイント
### ①大事なのはリーダーだけがリーダーシップを発揮することではない
チームメンバー全員がリーダーシップを発揮すること

### ②チームビルディングの8ステップ
チーム意識→安全な場→信頼関係→自信と本気→貢献意欲→当事者意識→リーダーシップ→ビジョン・ミッション
フォーミング→ストーミング→ノーミング→トランスフォーミング

### ③信頼関係がなければ気付けない
うつ病になったメンバーは信頼関係がなければ事前の相談はしない。
信頼関係があっても気づくのは難しい。
話しやすいだけでは足りない。信頼関係や、好かれている状態じゃないと無理。

### ④相手の宝物リストに入る
人間は基本的欲求を満たしてくれる人に好意を抱く。
その人に貢献したい、その人の役に立ちたいと感じる。
「大切なもの」「重要なもの」になれば宝物リストに入る。

### ⑤ 落伍者の上に立つのではなく、成功者を支えるリーダーに
落伍者の上に立ってるなら、一過性なもの

### ⑥過大な目標はメンバーをネガティブにする
目標やビジョンは本来、チームに一体感をもたらしメンバーを鼓舞するもの。
チームの状態とあっていなければネガティブに働く。おれにはできない、やめたいと思う。

### ⑦安全な場があるからこそ目標を目指せる
安全な場がなく、指示と感じているならやらされ感が生まれる。
「Look観察し、Think分析し、Glow改善し、Do実行する」を自らやる。

### ⑧信頼関係をより強くするために
悩みを共有する。
相手の悩みを受け入れる「他者受容」が大事。

# 今後やれること
まずは安全な場を作ること。
アドラー心理学と組み合わせてコミュニケーションをとっていく。

# まとめ
読みやすい内容で数日で読了したが、内容はライトで理解しやすかった。
納得できる部分については、実行していく。

考え方の分類としては、アドラー心理学とも近しいと感じるところがあり、個人的にアドラーの考え方は好きなので、この本の内容も活用したい。
投稿 96 Grafana 2024/10/05

本日の勉強時間　3H

Grafanaというのは、ざっくりと説明すると、色々なデータベースやデータソースから取得したデータをグラフにしたり、監視したりできる、モニタリングやデータ監視のためのOSS（無料で使えるソフトウェア）です。 特徴として、Grafanaはメトリクスがどこに保存されてるかに関わらず、データを可視化することができます。
Python3 基礎試験 スタックとキューとcollections.deque のメモ

Python3エンジニア認定基礎試験の勉強中です。
今日は問題を解いていて、あれ？となったスタックとキューについて、そこから派生して調べたcollections.dequeの処理が効率的な理由を簡単にメモを残します。

# スタック
**LIFO : 後入れ先だし = 最後に追加したものが最初に出てくる**
`push : スタックにデータを追加すること`
`pop : スタックからデータを取り出すこと`
```python
# 簡単な例
stack = []
stack.append(1) # pythonではpushをappend()を使用
stack.append(2)
stack.append(3)
print(stack) # [1, 2, 3]
print(stack.pop()) # pythonではpop()を使用 -> 最後に追加した 3 が取り出される
```
# キュー
**FIFO : 先入れ先出し = 先に追加したものが先に出てくる**
`enqueue : キューにデータを追加する`
`dequeue : キューからデータを取り出す`

```python
# 簡単な例
# 効率的にキューを使うために collections.dequeを使用する
from collections. import deque
queue = deque()
queue.append('a') # enqueueはappend()を使う
queue.append('b')
queue.append('c')
print(queue) # deque(['a', 'b', 'c'])
queue.popleft() # dequeueはpopleft()を使う: 'a' が取り出される
```

## 厳密にはcollections.dequeは両端キューというデータ構造
キューは先述の通り「先入れ先出し」だが、
collections.dequeでは実際は両端でデータの追加、削除ができる。(両端キュー)
- 末尾に要素を追加 : `append()`
- 先頭の要素を取り出す : `popleft()`
- 先頭に要素を追加 : `appendleft()`
- 末尾の要素を取り出す : `pop()`

## なぜcollections.dequeは効率的なのか？
リストは一列にデータが並んでいるのに対して、両端キューでは各要素が独立したノードとして存在していて、相互にリンクしあっているイメージ(ポインタ)。
n個の要素を持つリストに`pop(0)`を実行したときにかかる時間は`O(n)`なのに対し、
n個の要素を持つdequeに`popleft()`を実行したときにかかる時間は`0(1)`。
nの値が大きくなるほど、dequeの`popleft()`を使用した効率化のメリットは大きくなる。
### リストでの処理時間
`pop(0)`で先頭の要素を取り出すと、残った要素のインデックスを一つずつ前にシフトする操作も発生する。
**この時、リストの要素数を`n`個とすると処理にかかる時間は？**
(1) `pop(0)`で`O(1)`
(2)残りの`n-1`個の要素をインデックスを前方にシフトするため`O(n-1)`
**∴ `O(1) + O(n-1) = O(n)`**

### dequeでの処理時間
dequeでは`popleft()`を実行すると、先頭の要素Aのポインタが削除(Aの参照しているメモリが解放)され新たな先頭になる要素Bのポインタが更新される。これにかかる時間は定数時間で`O(1)`。



```
💡間違いがないように調べながら掲載するようにしていますが、
万が一間違いなどお気づきの点がありましたらコメントにてご指摘いただけますと幸いです🙇‍♂️
```
スクリプト ソースをフェッチできません。

# はじめに
たまに出ることがありますが、珍しいエラーメッセージです。
このエラーが出るのは、excuteScript()をbackground.jsで出力したときにconsole.js側のコンソールに表示されています。いざ、実行しようとしたが、その時にexcuteScript()が取得できないようです。background.js側では、excuteScript()を生成しているのですが。

原因はいまのところ、不明です。
特別なことは行っていません。この時のアクションは、サイトページで、ctrlKey+clickを行ったときです。
ctrlKey+clickを行ったときは、ポップアップ画面をページのbody要素にアペンドしています。ポップアップ画面には、各種ボタンを表示しています。この時、同時に、background.jsへ"clickSet"メッセージを送信しています。background.jsは、executeScript()で、ctrlKey+clickのイベントリスナーを登録しています。
# テストサイト
[https://tecoyan-net.jimdofree.com/2024/09/07/%E3%83%86%E3%82%B9%E3%83%88/](https://tecoyan-net.jimdofree.com/2024/09/07/%E3%83%86%E3%82%B9%E3%83%88/)

実行タイミングに問題があるのか?
すべて、リセットして、再度、タブをリブートして行うと、うまく行きます。
![スクリプトフェッチエラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198006/f8ba554d-9299-abd3-0c0b-8d6feef33287.png)

コンソールには、一見、VMxxxxxが表示されていて、うまくいっているように見えますが、クリックして見て見ると、次の画面が表示されます。

![スクリプトフェッチエラ-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198006/a4f1ee17-002a-6697-7e64-e57b82743c82.png)
ここに、executeScript()のスクリプトコードが表示されていないということは、この時点で、スクリプトコードをフェッチ(取得)できないということです。その原因を知りたいのですが。background.jsからcontent.js側へ渡すときに、何らかの理由で、渡すことができなかったということです。このexecuteScript()関数にはVMxxxxxというファイル名が自動で付けられています。このファイルを開くときに開けなかったということです。しかし、ある時には正常に開けているのです。その差は何なんでしょう。




# せめて、エラーの理由が書かれていれば
この時のエラーメッセージは、非常にそっけないものです。これだけでは、何をチェックしてエラーとしたかが知らされていません。もう少し、親切なエラーメッセージにしてもらいたいです。

# executeScript()を使用した背景
executeScript()は、プラグインのbackground.jsで使用しています。
このインジェクションスクリプトは、タブに含まれている動画のiframe要素のドキュメントオブジェクトへアクセスする必要がある時に使用できる大変便利なスクリプトです。

今回、タブには複数のyoutube動画がiframeを用いて埋め込まれています。
このiframeのドキュメントオブジェクトは、親フレームのタブのドキュメントオブジェクトとは別空間にあります。その空間の要素に、アクセスするためにexecuteSCript()を用いています。



# 成功した画面
![スクリプトフェッチ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198006/8e234dab-eff6-878e-5c0c-e4c8488d5533.png)
うまくいった場合は、この画面のようになります。background.jsで生成したexecuteScript()が表示されています。

# 中間報告
今のままでは、自力解決は難しい気がしていますが、試行錯誤を重ねながら、ネットでヒントを探すことも続けて行きたいと思います。
ヒントは、1,2回続けるとエラーは取れるというところにあるような気がしています。これは、初期化とか、一度実行すると何らかの設定が行われて、次回からはエラーが取れるようなことかとも思っています。
よくよく、テストをして見ると、VMxxxxxが生成されていないケースもありました。これも原因不明です。

再現性：あり
初回のctrlKey+clickではVMxxxxが正常にロードされず、2回目のctrlKey+clickでは正しく、VMxxxxがロードされています。



# あとがき
このように、システムから警告されるエラーメッセージには、何が悪くてエラーになったかの理由がついていません。ただ、「エラーです」だけでは、対策のしようがありません。ネットで検索しましたが、同じようなエラーメッセージは、ヒットしません。
どこかに、ヒントが出てくるのを待ちたいと思います。

# ご報告
ついに、原因が判明しました。おそらく、これが原因かと思われます。対処後、今のところ、順調に動作しています。
わかってみれば、なるほど、と思うことでした。このことは、これまでも何度も経験していたことですが、今回は、見落としていました。
原因は、ボタンにイベントリスナーを登録するときに、そのボタンの表示が間に合わなくて、一回目のctrl+click実行でリスナーが登録できていませんでした。
2回目のctrl+clickの時には、すでにpopup画面が表示され、ボタンも表示されています。そのため、ボタンにリスナーを登録できました。
そこで、簡単な方法ですが、1秒タイマーで、表示されるまでリスナー登録を遅らせました。これで、1回目のctrl+clickでも、ホバーイベント他のリスナーも登録され、タイトルにある、「スクリプト ソースをフェッチできません。」というエラーはなくなりました。お騒がせいたしました。
それにしても、このエラーメッセージでは、この原因にはたどりつけないです。

### 動的生成の要素にリスナーを登録するときは
忘れがちですが、あらためて気を付けたいと思います。
ボタンなどにリスナーを登録するときは、必ず、表示を確認してから実行する。

この「スクリプト ソースをフェッチできません。」というエラーの真の原因は、スクリプトコードを正常に出力できなかったという意味ではと。それは、先の理由で、イベントリスナーのスクリプトコードを対象とする要素がまだ、存在していなかった時点で、登録しようとしたためではないかと思います。
(SSD1306)M5NanoC6で温度を表示して遊ぶ。



x 過去ログを見よ!!
x Arudinoで「新規タブ」の操作ができる人


参考


https://qiita.com/caa45040/items/4842915974b371ad64dd


https://qiita.com/caa45040/items/507e196f7d94ebf6136e


https://qiita.com/caa45040/items/696505b5da5296bb5176



結果


![o_coq489.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a8d5916a-aaff-ba55-bc97-ccd5aa0418af.jpeg)


プログラム

SSD1306_ADC_TMP1o2_M5NanoC6_1.ino


```c++


//SSD1306_ADC_TMP1o2_M5NanoC6_1


//ヘッダーファイル
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "nana_Grvove_Temperature1o2.h"
#include "nana_Grvove_ADC.h"


//定義
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


//初期化
void setup() {

  // I2Cアドレスは使用するディスプレイに合わせて変更する
  display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);

}//setup


//メインループ
void loop() {

  // 画面表示をクリア
  display.clearDisplay();

  // テキストサイズを設定
  display.setTextSize(3);
  // テキスト色を設定
  display.setTextColor(WHITE);
  // テキストの開始位置を設定
  display.setCursor(0, 10);

  //電圧を求める
  float Voltage; //電圧
  Voltage = nana_Grvove_ADC();
  //Voltage = 2.5; //debug

  //温度を求める
  float Temperature; //温度
  Temperature = nana_Grvove_Temperature1o2(Voltage);
  //Temperature= 46.0;   //46を設定 debug

  // 温度を表示
  display.println((int)Temperature);

  // 描画バッファの内容を画面に表示
  display.display();

  delay(1000); //1秒待つ

}//loop



```

nana_Grvove_ADC.h


```c++


//インクルド
#include <Arduino.h>
#include <Wire.h>

//I2Cのアドレス
#define Addr 0x50

float nana_Grvove_ADC() {

  //内部アドレスの設定
  Wire.beginTransmission(Addr);
  Wire.write(0x00);
  Wire.endTransmission();
  delay(2);

  //データの読み込み
  Wire.requestFrom(Addr, 2);
  delay(1);
  int h, l;
  if (Wire.available() == 2) {
    h = Wire.read();
    l = Wire.read();
  }//endif
  delay(1);

  //値の変換
  int adc1 = ((h & 0x0F) << 8) + l;
  int vo = (adc1 * 6000) >> 12; // (adc1*(3/4096))*2

  return( ((float)vo) * 0.001 );
  
}



```

nana_Grvove_Temperature1o2.h


```c++


#include <math.h>

const int B = 4275;               // B value of the thermistor
const int R0 = 100000;            // R0 = 100k

float nana_Grvove_Temperature1o2(float Voltage){
    //入力は、電圧　出力は、温度
    //float R = 1023.0/a-1.0;
    //R = R0*R;
    float R,Current,Resistance; 
    Current = Voltage / 100000.0;   //電流を求める
    Resistance = 5.0 / Current;     //全体の抵抗を求める
    R = Resistance - 100000.0;      //全体の抵抗から検出抵抗を引く

    return( 1.0/(log(R/R0)/B+1/298.15)-273.15 ); // convert to temperature via datasheet

}



```
アトミックデザインを活用したフロントエンド開発：経験から得た教訓

# 概要
私は普段、Vue.js と Ruby on Rails を使用して開発しています
フロントエンドにはアトミックデザインを採用しています
ここでは、開発を進める中で「最初からこうしておけばよかった」と感じた点や「ここがよかった」という点をまとめています

# そもそもアトミックデザインって？
ざっくりといえば個々のUIコンポーネントのデザインと再利用に焦点を当て、効率的で一貫したデザインシステムを構築するためのアーキテクチャです
    
以下はディレクトリ構成の例です
- /components/: コンポーネントがアトミックデザインの階層に基づいて構造化されて配置される
    - atoms: 最小のUIコンポーネント（例：ボタン、入力フィールドなど）
    - molecules: 複数の原子を組み合わせたコンポーネント（例：フォームグループ、ナビゲーションバーなど）
    - organisms: より大きなUI構造（例：ヘッダー、フッター、製品リストなど）
    - templates: ページ全体のレイアウトテンプレート
- /pages/: 各ページコンポーネントが配置される
- /utils/: アプリケーション全体で使用されるユーティリティ関数


# 開発してきてわかったこと

## atomsやmoleculesコンポーネントでデータ取得処理は可能な限りさせないこと

これらのコンポーネントにデータ取得の処理を埋め込むと、コンポーネントが特定のAPIやビジネスロジックに依存してしまい、再利用性が損なわれる
このため、atoms や molecules は、できるだけ汎用的で再利用可能なものにしたい

これを避けるため、データ取得や状態管理などの処理は行わず、親コンポーネントから必要なデータやコールバックをプロパティ（props）として渡すようにする

## 再利用性を意識しすぎないこと

再利用可能なコンポーネントを作ろうとしても、細かいカスタマイズが必要になることがあります
結果として利用性の高いコンポーネントを作ることに集中しすぎて、かえって開発が遅くなったり
複雑なプロパティを追加したがためにコンポーネントが使いにくくなることも

これを避けるため、こうしたときは、別コンポーネントとして構築してしまうのがよいかと思う
ただし、あまり自由にしすぎるとアトミックデザインのよさが失われるのも事実のため、ほどほどに

## コンポーネントの共有をできていること

再利用可能なコンポーネントを作ったはいいものの、それが周知されず同様のコンポーネントを作ってしまうことがある
これを避けため、デザインガイドライン等でメンバーが迷わないようにしたい

## バグを生みにくい

一度作成したコンポーネントを再利用することで、同じロジックやUIを何度も実装する必要がなくなり、設計ミスや実装ミスが少ない
小さなコンポーネントはユニットテストがしやすく、テストカバレッジを高めやすい

# 最後に

どんなアーキテクチャもそうですが、使い方を誤ったまま続けると後から修正が大変になるかと思います
導入前に調査内容をまとめておくことももちろん大切ですが
今回のように教訓や反省を元にまとめることも大事かと思った次第です
FFmpegでトリミングした音声を映像と再結合する場合は再圧縮が必要

## 結論
ご唱和ください。
「FFmpegでトリミングした音声を映像と再結合する場合は再圧縮が必要」

## 経緯
動画編集アプリを作っています。

https://qiita.com/calcMCalcm/items/178901c752f6cef481f1

アプリはPythonで作成しており、動画の書き出しには、Moviepyを利用していましたが、最近FFmpeg+FFmpeg-pythonに変更しました。

https://qiita.com/calcMCalcm/items/1a2033cc874057c8dcb0

FFmpegに変更したので動画のトリミング機能を追加しました。
アプリでの大まかな処理の流れは次のようなものになっています。

```mermaid
graph 
  START([入力の元動画])-->B{トリミング
  があるか}
  B-->|トリミング無し| D
  B-->|トリミング有り| C[動画トリミング]--> D[Pythonでの動画処理]
  D-->E[動画から音声を分離]
  -->F{トリミング
  があるか}
　F-->|トリミング無し| Z
　F-->|トリミング有り| G[音声トリミング]-->Z[処理した動画に音声を結合]
  -->End([動画を出力])
```

FFmpeg動画と音声を結合する時、codecをcopy（入力と一緒）と指示することで、動画の再圧縮せずに結合することができます。（一瞬で処理が終わる）
例えばffmpeg-pythonでは次のような記述になります。

```python
stream=ffmpeg.output( input_audio, input_video.video,out_filename,movflags='faststart',acodec='copy', vcodec='copy',format='mp4').overwrite_output()
```

音声のトリミングは、ffmpeg-pythonでは次のように記述することで、トリミングができます。
```python
input_audio=(
    ffmpeg.input(audio_temp_filename)
    .filter('atrim', start=start_time, end=end_time,)
    .filter('asetpts', 'PTS-STARTPTS')
    )
```
この時、input_audioは **非圧縮の状態です。※ここが大事**
そのため、前述の結合のスクリプトに代入しても、音声のcodecがm4aなどMP4に合った形式となっていないため、音声の結合ができませんでした
（トリミングをした場合、無音の動画が出力されていた）

なので、トリミングが行われている場合には、codecを指定し、再圧縮することで、映像に音声を結合することができます。
全体の処理は下図のようになりました。


```mermaid
graph 
  START([入力の元動画])-->B{トリミング
  があるか}
  B-->|トリミング無し| D
  B-->|トリミング有り| C[動画トリミング]--> D[Pythonでの動画処理]
  D-->E[動画から音声を分離]
  -->F{トリミング
  があるか}
　F-->|トリミング無し| X[処理した動画に音声を結合
vcodec='copy' ,acodec='copy']-->End
　F-->|トリミング有り| G[音声トリミング]-->Y[処理した動画に音声を結合
vcodec='hevc_nvenc']-->End([動画を出力])
```

## 反省
手を抜かずにFFmpegのエラーを取得し見たらすぐにわかったのだろうと思います（近道しようとして、結局遠回りした）
TextMeshProでスクリプトを使用せずに縦書きにする

```
「医者さまを
   よばなくっちゃ。」
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/c56678f4-3dd3-f09f-3078-09cc472e7e33.png" width="68%">

これを縦書きにしてみます。
```
「<rotate=90>医者さまを
  よばなくっちゃ。</rotate>」
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/1a607226-a0c7-e206-69dc-70e03803d34e.png)
```<rotate>```タグで文字を回転させ、TextMeshProのオブジェクトを右に90°回転します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/b3560770-17b4-a0c7-b170-9302c70111a2.png)

「っ」や「。」が左にずれているので、位置を右に補正します。
```
「<rotate=90>医者さまを
  よばなく<voffset=0.2em>っ</voffset>ち<voffset=0.2em>ゃ</voffset><voffset=0.6em>。</voffset></rotate>」
```
<iframe width="560" height="315" src="https://www.youtube.com/embed/Fx-Nyfv8HoM?si=Kynsao5hkFd363aP" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
実際問題としては、こんな面倒なことを毎回やっていられないので結局スクリプトでタグを入れることになるかとは思いますが、 <a href="https://anogame.net/textmeshprougui-tate-vertical">メッシュを編集する方法</a> とはまた別のアプローチとして使えるのではないかと思います。

参考：[【Unity】TextMeshProのよく使うタグまとめ](https://kingmo.jp/kumonos/textmeshpro-frequently-used-tags/#index_id1)
keyball61組み立ての備忘録

## keyball61作る時に気をつけること
[白金ラボ](https://shirogane-lab.net/)さんが作ってくださっている自作キーボードキットシリーズのkeyball61を購入し自分で組み立てて運用中です。備忘録としてやってよかったことと次回作るときに気をつけることを備忘録として残していこうと思います。

初めてkeyballを組み立てようと思っている人が組み立てる前にさらっとみてくれたりしたら嬉しいです。

#### ✅ダイオードをあらかじめ並べておく

ダイオードには向きがありますので、向きを間違えると動きません。
毎回ピンセットで向きを確認するのもアリなんですが、組み立て方法が書いてあるgithubにも記載されている通り最初に全部向きを揃えてから半田付けに取り掛かった方が圧倒的に楽です。
![CB3785A0-A599-4274-B2C7-A38699A9517C_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940309/1ee4f89e-34d7-80b8-8cf9-e1f30ae97b98.jpeg)



#### ✅トラックボールセンサー基盤の取り付けの向きは気をつける

これネットで2人くらいみたのでもっと世の中やらかしてる人多いと思います。僕が3人目になりました。
githubには気をつけてと書いてあるのに後半なんで集中力切れてきて読まなかったのが大きな原因です。

:::note warn
※画像は逆につけてしまっていますので、皆さんは画像の通りにやらないようにしてください
:::


![B94E3879-0AD0-447A-9F0B-4A9D1B0E4589_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940309/e56e1efd-bb5f-9215-6b09-62a9812e3511.jpeg)


#### ✅キースイッチ用の半田付けが終わった段階で全部テストする

これは組み立てとか他の人のサイトに行っても見当たらなかったですが、絶対にやってよかったなと思います。
アクリルプレートをつけ終わった段階でキーを押して反応するか確かめた場合、反応しなかったら**アクリルプレート全部外し直し**です。

半田付けが終わった段階でキースイッチは差し込んでテストできます。

順番
- キースイッチ周りの半田付け終了
- テストファームウェアの書き込み
- キースイッチを全てにはめる
- キーを押して問題なく反応してればPCと繋がっている基盤のOLEDがどのキーを押したか表示してくれます

PCで文字が表示されるか確認してもいいですがshiftとかctrlキーとか文字が表示されないのもあるのでOLEDを確認するのが1番いいと思います。

![CleanShot 2024-10-06 at 04.42.53@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940309/7033ee2e-b368-7ad7-4116-22981b73b3c6.png)

↓OLED※組み立てサイトから拝借しました
![CleanShot 2024-10-06 at 04.55.03@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940309/8992137b-9722-59e4-fa04-48554dcc1ff0.png)


以上になります。

以下に僕の完成した後のkeyball61を載せさせていただきます。
テンティングやキーキャップの参考にしてください。
読んでいただきありがとうございました。
![1457F148-F738-4B25-B2C1-18441A881CCD_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940309/3a627015-98c8-e91f-d9bf-15f2893b96a5.jpeg)
人生初ハッカソンの振り返り

## はじめに
　エンジニアを目指す26卒大学院生です。Web系言語の学習開始して約10ヶ月が経ち、振り返ってみればいろいろな経験をしました。経験したはいいのですが、チャレンジした後の内省が足りないなと感じたため、ここに記そうと思います。今回は8月に参加したサポーターズさん主催の技育CAMPハッカソンの振り返りを行います。
 
 ## 技育CAMPハッカソンとは
 + 初心者大歓迎
 + 完全オンライン
 + メンターさんのサポート付き
 
　ハッカソンと聞くと初学者には少しハードルが高いですが、このハッカソンは7割がハッカソン初心者のため、参加のハードルはかなり低いと思います。自分の技術力と他の学生エンジニアの技術力を確かめるには絶好の場でした。Webの経験が浅い友人2人と参加しました。

## 制作物
### ハッカソンでのメンバーマッチング&制作物投稿サイト
　前章でも語ったのですが、初心者にとって、ハッカソン参加の障壁は非常に高いと思います。障壁が高い原因として次の2つがあると思います。

> ① チームメンバーを集めることができない。
② ハッカソンのレベル感がわからない、何を作ればよいかわからない。

この2つの問題を解決するために、**メンバーマッチング&制作物投稿サイト**を作成しました。

## 事前開発
　キックオフイベント後の事前開発期間では、何を作るか・どのような技術を使うかを決定し、ある程度のベースを作成しました。今回使用した技術と選定理由は以下になります。
- **Next.js(TypeScript)**
→ルーティングが容易、使用してみたかったため。
- **Firebase**
→バックエンドを担ってくれるため開発効率が上がる、リアルタイムでデータを同期できる、認証機能を提供しているため。
- **Tailwind CSS**
→UIの構築が高速に行える、ライブラリが充実しているため。
- **Slack API**
→Slackでの自動グループ作成を実装したかったため。
- **Vercel**
デプロイが容易であるため(GitHubと連携するだけで自動でデプロイされる)。

## 1日目
　事前開発で方針は定まっていたため、すぐにコーディングに取り掛かることができました。二人ともGitHubを使ったチーム開発はほぼ初めてでした。どうやって連携を取ればよいかわからず苦戦しましたが、なんとか認証周り・チーム募集・チャット機能の実装を終えることができました。

## 2日目
　最低限の機能は実装していため、発表準備に早く着手するべきだったのですが、欲が出てしまい、Slackの自動招待やいいね機能に手を広げてしまいました。Vercelでのデプロイはすぐにできると思っていため、開発終了間近まで追加機能の実装をしていました。しかし、まさかのVercelでのデプロイが失敗してしまい、結局中途半端なところで終わってしまいました...
　加えて、発表の準備時間を取っていなかったため、直前で急いでスライドを作成しました。そのため、下のようなスライドになってしまいました。発表練習もできず、ぶっつけ本番になってしまいました...
 
<iframe src="https://www.docswell.com/slide/54VVGW/embed?key=2024-09-22-004539" allowfullscreen="true" width="620" height="349" style="border: 1px solid #ccc; display: block; margin: 0px auto; padding: 0px; visibility: visible;"></iframe>

## 発表会
　発表時間が1グループ3分しかなかったため、なんとかなると思っていましたが、予想以上に3分が短く、魅力がうまく伝えきれなかったです。短時間で印象に残るプレゼンをすることの難しさを実感しました。

### 結果
　このアプリのアイデアや開発背景には自信がありました。また、最低限の機能は実装できていたので、心のどこかで良い結果を期待していましたが、残念ながらどの賞もいただくことができませんでした。

### 敗因
　このハッカソンは採点が参加者による投票であったため、3分のプレゼンでどれだけアピールできるかが重要でした。
 
- 作り込んだプレゼン資料
- 理解しやすいシンプルな機能(複雑なものを作っても伝える時間がない)
- あれこれ挑戦せず、完成させる
- 実装は思った以上に時間を要するため、企画段階では構想を大きくしない(期日までに絶対に実装できそうなものを企画し、時間が余ったらスケールしていく)
- UI/UXに時間をかけて見栄えを良くする

これが受賞のためには必要だと感じました。私のチームは、手抜きのプレゼン資料/様々な機能を盛り込みすぎて説明する時間がなかった/UIに時間を割かなかったためこの結果だったと考察します。

## おわりに
　評価が参加者による投票なのは少し疑問が残りますが、ハッカソンにはハッカソンなりの戦い方があるのだと思いました。また、ユーザに価値のあるものを届けたい私にとって、ハッカソンはマッチしていないような気もしました。とはいえ、短期間で膨大なアウトプットができましたし、エンジニアになるという同じ志を持った仲間とも交流ができたため、非常に有意義な2日間だったため、得たものの方がはるかに大きかったです。
【完全無料】Gemini APIチュートリアル（所要時間10分）

# はじめに
本記事ではGoogleの生成AI「Gemini API」の高速チュートリアルをします。10分あれば簡単なチャットBOTを作れるようになります。
### 想定読者
- とにかく無料で簡単に生成AIサービスの開発をしたい人
- Gemini APIの使い方を調べたがよく分からなかった人

### Why Gemini?
Gemini APIが他の生成AI APIより優れている点は2つあります。
1. 完全無料（制約はあるものの個人開発レベルであればほぼ無制限に使用できます）
2. 登録が簡単（Googleアカウントがあればすぐに使用可能です）

OpenAI APIが最も利用されている生成AIのAPIだと思いますが、上記2点より、個人開発やテスト段階においては、Geminiを使用することを強くお勧めします。


# 早速試してみる
### やりたいこと
ミニマムなQ＆Aシステムを構築します。
```
Q：GeminiとOpenAI、どっちが最強ですか？
A：ジェミニとOpenAIはどちらも強力な言語モデルですが、それぞれ異なる強みを持っています。・・・
```

 

実装にあたり、公式のチュートリアルはとても参考になるのですが、少し分かりにくく、コードの間違いも見られます。そこで、本記事では必要最低限のコードのみで説明します。

https://ai.google.dev/gemini-api/docs/get-started/tutorial?hl=ja&lang=python

### STEP1：APIキーの取得
まず始めにGeminiのAPIキーを入手しておきます。必要なのはgoogleアカウントのみです。
下記のリンクにアクセスして、Get API keyをクリックしましょう。

https://aistudio.google.com/

下図のように、APIキー作成をクリックするとプラン「無料」でAPIキーが発行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770170/da884617-2753-e94f-c71a-bbcf4b556d64.png)

### STEP2：Google ColaboratoryでAPIキーセット
続いてGoogle Colaboratory上で実装する準備をします。

https://colab.research.google.com/?hl=ja

下図のように鍵マークのシークレットを開き、名前に「GEMINI_API_KEY」と入力し、先ほどのAPIキーを値にセットすれば完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770170/910483dc-0dc6-842c-89c5-d3ed01e13aa4.png)

### STEP3：チャットbotを実装する
最後にチャットBOTを実装していきます。まず、geminiのライブラリをpipインストールします。
```
!pip install -q -U google-generativeai
```

続いてapiキーの読み込みを行います。
```python
# Used to securely store your API key
from google.colab import userdata
import google.generativeai as genai

# Or use `os.getenv('GEMINI_API_KEY')` to fetch an environment variable.
GEMINI_API_KEY = userdata.get("GEMINI_API_KEY")
genai.configure(api_key=GEMINI_API_KEY)
```

最後にQ&Aのbotを実装します。
```python
model = genai.GenerativeModel("gemini-1.5-flash")
question = "GeminiとOpenAI、どっちが最強ですか？"
response = model.generate_content(question)
print(response.text)
```
以下のような出力が得られます。
```
GeminiとOpenAIはどちらも強力な言語モデルですが、どちらが「最強」かは **明確な答えはありません**。なぜなら、両者の強みと弱みが異なり、どの側面を重要視するかによって評価が変わってくるからです。

**Geminiの強み:**

* **Googleの総合的なリソース:** Googleの膨大なデータと計算能力を活用
* **マルチモーダル:** 画像、音声、テキストなど、複数の形式の情報を理解し処理可能
* **実世界への統合:**  Googleの製品とサービスに統合され、より実践的な用途に役立つ
　　　・
　　　・
　　　・
```

### STEP4（任意）：出力を見やすくする
前述のように出力がアスタリスク（**）で囲われていたりするため、少し見づらいです。公式ドキュメントでは以下のようなto_markdown(text)関数を定義しています。
```python
import pathlib
import textwrap

from IPython.display import display
from IPython.display import Markdown

def to_markdown(text):
  text = text.replace('•', '  *')
  return Markdown(textwrap.indent(text, '> ', predicate=lambda _: True))

to_markdown(response.text)
```
上記コードを挟むことで、下記のように見やすい出力になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770170/542ac59e-006f-4545-739c-9b45fb5b900f.png)

# 終わりに
ここまで読んで頂きありがとうございました。
Geminiの情報は意外とQiita上にも転がっていないため、不明点等あればお気軽にご連絡ください。
なお、料金や無料プランの制約については、こちらに記載があります。不安な方はこちらをお読みください。

https://ai.google.dev/pricing?hl=ja
ドメイン駆動設計（DDD）を「文章」として捉える

## はじめに
プログラムを「文章」として考えてみます。文章を読みやすく理解しやすくするためには、主語と述語を明確にすることが重要です。プログラムもまた主語と述語を明確にすることで曖昧さを排除し、関係者が正しく内容を共有することが出来ます。この記事では、プログラムを「文章」として捉える視点から、ドメインモデルとトランザクションスクリプトの違いや、ドメイン駆動設計（DDD）の設計プロセスを考察します。

## プログラムを「文章」として考える

### トランザクションスクリプト: 動詞の羅列
トランザクションスクリプトはその名前の通り、トランザクションを手続き的（スクリプト的に）に表現したアプローチであり、**動詞の羅列**のようなものです。
- たとえば、在庫を確認して、注文を処理し、請求を行う一連の処理は、まるで動作の指示書のように並んでいます
- しかし、これでは第三者にとって、**何が主体で、何が目的なのか**が分かりにくくなり、システムの規模が大きくなるほど可読性や保守性が低下します

### ドメインモデル: 主語・述語の明確化
一方、**ドメインモデル**は、ビジネスを反映したエンティティを用いて、プログラム内の主語と述語を明確にするアプローチです。これにより、プログラム全体が「文章」としての構造を持ち、第三者にも正確に理解しやすくなります。

- **主語**: プログラムの中で何が主体で動作しているのか（例: 顧客、注文）
- **述語**: 主語がどのような行動をするのか（例: 注文を作成する、在庫を確認する）

ドメインモデルを使うことで、「主語」をエンティティ、「述語」をメソッドとして整理することができるので、理解しやすい文章のようなプログラムを作ることができます。

## ドメイン駆動設計の全体像

ドメインモデルを「文章」として捉える視点を持ちながら、ドメイン駆動設計の設計プロセスを3つの段階に分けて考えます。

### 1. 境界付けられたコンテキストへの分割
文章の曖昧さを作り出す原因に、単語に含まれる複数の意味があります。単語の意味を明確にするためには文脈を考えることが有効です。システムも同様に、文脈を固定できる領域（境界付けられたコンテキスト）に分割することで、領域内の単語の意味が曖昧になることを防ぐことができます。

- 例えば「注文」という単語は、販売コンテキストでが「顧客が商品を購入する行為」を指しますが、在庫コンテキストでは「在庫補充のリクエスト」を表します

境界付けられたコンテキストはマイクロサービスの自然な単位として考えることができます。

### 2. 境界付けられたコンテキスト内部の設計
次に、各コンテキスト内の設計を行います。その際、**エンティティ**、**値オブジェクト**、**ファクトリー**、**リポジトリ**等の戦術的設計ツールを利用します。この記事では戦術的設計の詳細は扱いません。

### 3. 境界付けられたコンテキスト間の連携方法の設計
最後に、複数のコンテキスト間での連携方法を設計します。例えば、**腐敗防止層**を導入することで異なるコンテキスト同士が影響し合わず、それぞれの文脈を保ちながら連携を行うことができます。これにより、各コンテキストが独立した文章として完結しつつ、システム全体が統合されたまとまりを持つようになります。

## まとめ
ドメインモデルを「文章」として捉えることで、プログラムの構造がより明確になり、コードの可読性や保守性が高まります。ドメイン駆動設計では、システム全体を「境界付けられたコンテキスト」に分割し、それぞれが独立した明確な意味を持つ「文章」として設計されるため、複雑なシステムでも高い整合性と理解しやすさを保ちながら成長させることが可能です。
このアプローチを意識することで、開発者だけでなく、ビジネス側の関係者とも共有しやすいモデルを作ることができ、システム全体の成功に寄与します。
Error: The plugin "cloud_firestore" requires a higher minimum iOS deployment version than your application is targeting.解決法

# はじめに
Flutter × Firebaseの初期設定は頻繁にする作業じゃないので、何かとよく忘れがちです。。。

久々にfirebaseを導入する部分をやったら

```console
Error: The plugin "cloud_firestore" requires a higher minimum iOS deployment version than your application is targeting. To build, increase your application's deployment target to at least 13.0 as described at https://docs.flutter.dev/deployment/ios Error running pod install Error launching application on iPhone SE (3rd generation).
```

☝️のエラーでビルド失敗したので、、またやってしまったと思いながら記録します。

# Podfileを編集
デフォルトではコメントになってる部分をコメントじゃなくして、エラーのメッセージ通り13.0を指定します。

```ruby:ios/Podfile
# Uncomment this line to define a global platform for your project
platform :ios, '13.0'
```

# XcodeでMinimum deploymentsを編集

`ios/Runner.xcworkspace`からxcodeを開き、generalからMinimum deploymentsを編集します。

![Screenshot 2024-10-05 at 19.39.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/a57009fc-b3f0-688b-7e50-ca63b715cd51.png)



# 参考

https://stackoverflow.com/questions/78660250/flutter-firebase-core-error-searching-for-inspections-failed-undefined-meth
コミット履歴が別アカウントになった件について

いつも通りぽちぽち仕事をしていたら、「コミット履歴がプライベート用のgitアカウントになってる」という珍事件がおきました。
そもそもコミット履歴って何に紐づいているの？ってところから、実際の修正方法を記載していきます。

## コミット履歴に紐づくGitアカウントについて
コミット履歴に紐づくGitアカウントはどのように決まるのかというと、ずばりコミットを行ったときの**user.name**と**user.email**に基づいて決まるようです。Git の各リポジトリやグローバルな設定には、user.name（コミット履歴に表示されるユーザー名） と user.email（コミット履歴に表示されるメールアドレス）の情報が記録されており、コミット時にその設定が使用されるとのこと。

## 実際にやったこと
### 1. 現状の設定を確認
まず、現在のリポジトリで使われているGitのユーザー名とメールアドレスを確認します。

```
git config --get user.name
git config --get user.email
```
これを実行すると、現在設定されている user.name と user.email が表示されます。実際に確認したところ、やはりプライベート用のアカウントが表示されていたので、これを修正していく必要があります。

### 2. ローカルリポジトリでのGit設定を修正
次に、現在のリポジトリ内で使うGitのユーザー情報を仕事用のアカウントに変更します。これにより、このリポジトリでのコミットが仕事用のアカウントに紐付けられるようになります。

```
git config user.name "仕事用のユーザー名"
git config user.email "仕事用のメールアドレス"
```

この設定は、現在のリポジトリに対してのみ適用されるので他のプロジェクトには影響しません。
ちなみに、グローバル設定を変更することで全てのリポジトリに対して変更をかけることもできますが、私はリポジトリによって使い分けたいので、ローカルリポジトリ内での変更に留めました。

グローバル設定を変更したいときは、以下のコードで変更できるみたいです。

```
git config --global user.name "仕事用のユーザー名"
git config --global user.email "仕事用のメールアドレス"
```
これで今後のコミットについては、仕事用のアカウントに紐付けることができました。次の章からは過去のコミット履歴のアカウントを修正する方法について見ていきます。

### 3. 過去のコミット履歴を修正する方法
過去のコミット履歴を遡って修正していきます。git rebase や git filter-branch を使用する方法などありますが、私はgit rebaseで修正していきました。

#### 1. インタラクティブリベースを開始する

変更したいコミットよりも古いコミットを指定して、インタラクティブリベースを開始します。私は、直近 5 件のコミットの中に修正したいコミットがあったので、以下のように実行しました。

```
git rebase -i HEAD~5
```

コマンドを実行すると、過去 5 回分のコミットがリストされたテキストエディタが開きます。この画面で各コミットの操作を指定できます。

#### 2. エディタの操作
エディタが開いたら、insertモードにして修正したいコミットの前に editと書きます。
edit を指定することで、そのコミットに対して変更を加えられるようになります。
指定が終わったら、escを押して、:wqでエディタを閉じましょう。

#### 3. コミットのユーザー情報を変更する
コミットを edit で選択すると、リベースが一時停止してそのコミットの状態になります。この状態で以下のコマンドを実行すると、ユーザー名やメールアドレスを変更できます。

```
git commit --amend --author="新しいユーザー名 <新しいメールアドレス>"
```

修正が完了したら、リベースを続行します。

```
git rebase --continue
```
これで、指定したコミットのユーザー名とメールアドレスが変更されます。
アプリのプロモーション用の動画をGoogle広告でお手軽に無料で生成する

動画を作成したことのないモバイルアプリ開発者を想定して記事を書いています。
Google広告の動画生成はモバイルアプリに限らず幅広い用途でお使いいただけます。

# プロモーションで動画を用意することを考え始める
「動画を用意するのはなんだか面倒そうだなあ。」
「予算のある組織ならまだしも個人開発だし、本格的なのを用意するのもなあ。」
そんなあなたに、Google広告の無料機能で楽に生成できますよ、というお話です。
テンプレートを選んでいい感じに仕上げてもらえます。

# こちらで用意するもの
1. アプリアイコン
1. アプリの画像
1. キャッチコピー

これだけ！
1.はアプリで使用のモノだし、
2.はアプリ実行中の画面のスクショならお手軽に用意できるし、
3.は実際にツール上で組み立てながら考えてもいい

# 手順
### Google広告にログインして左上の「作成」を押す
![作成ボタン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3902045/b2c93f73-b990-b748-8f2a-e15c27fe7b36.png)

### ポップアップメニューの「アセット」を選択
![メニュー：アセット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3902045/c463cc6a-5814-2ada-13fb-a9e2abf48cf9.png)

### 「動画を作成する」を選択
![動画を作成する.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3902045/97630e84-9db7-71d3-1cdb-b1cbe2c2e59b.png)

### テンプレートを選ぶ
スマホアプリならそれに向いているものを選びましょう
![テンプレート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3902045/8238718e-f100-dfa1-2ffe-235d4d12ee51.png)

### あとは案内に従っていく
想像していたよりも楽に出来るのではないでしょうか。

### [参考]実際に作成した動画
このような感じに仕上げられます。

縦画面

https://www.youtube.com/shorts/qNOFDUu_fKo

横画面

https://www.youtube.com/watch?v=QW9LLFK7yGw
[DBMS] データ復旧の要件

# 一覧
|要件||
|:--|:--|
|RPO<br>目標復旧時点|Recovery Point Objective<br>データ損失の最大許容範囲|
|RTO<br>目標復旧時間|Recovery Time Objctive<br>障害停止の最大許容時間|



# 参考リンク
- [令和4春55](https://www.ap-siken.com/kakomon/04_haru/q55.html)
[SQL] [DML] SELECT

# 一覧表
|SQL文|詳細|
|:--|:--|
|SELECT DISTINCT|重複行を除いて出力する|
||`SELECT DISTINCT * FROM A`|
|SELECT<br> SELECT ALL|重複行も含んで出力する|
||`SELECT * FROM A`|

# 参考リンク
- [令和4秋28_DISTINCT](https://www.ap-siken.com/kakomon/04_aki/q28.html)
画像から琵琶湖の面積をシンプルに求める


## きっかけ

https://qiita.com/shinichi1729/items/bb4ced8625ca8b6defb4

## 方法

画像のピクセル数を数えるだけの簡単なお仕事です。
1辺の長さは滋賀県の南北長（101.4km）から導きます。
（滋賀県の面積から比を使って求めるのは個人的になんか違うなと思った。その滋賀県の面積はどうやって求めたんだ？と思うから。）

ちなみに期待する琵琶湖の面積は670.4km²です。

また画像はこれを利用します。

https://www.ac-illust.com/main/detail.php?id=1190333

## コード

```js
import { createCanvas, loadImage } from "canvas";

loadImage("./sigaken.png").then(image => {
    const canvas = createCanvas(image.width, image.height);
    const context = canvas.getContext("2d");
    context.drawImage(image, 0, 0);
    const imageData = context.getImageData(0, 0, image.width, image.height);
    const data = imageData.data;

    let canCount = true;
    let prefHeightPixelCount = 0;
    let biwakoPixcelCount = 0;
    
    for (let y = 0; y < image.height; y++) {
        canCount = true;
        for (let x = 0; x < image.width; x++) {
            const i = x * 4 + (image.width * 4) * y;
            // 透明なら県外
            if (data[i + 3] === 0) {
                continue;
            }
            // 青っぽいところは琵琶湖
            else if (data[i + 2] > data[i + 1]) {
                biwakoPixcelCount++;
            }
            // 県の縦のピクセルの数
            if (canCount) {
                canCount = false;
                prefHeightPixelCount++;
            }
        }
    }

    // 滋賀県の南北長（101.4km）から滋賀県の面積を求める
    console.log(((101.4 / prefHeightPixelCount) ** 2) * biwakoPixcelCount);
});
```

## 結果

```
664.6264770862265
```

実際は670.4km²なので5.8km²ほど誤差が出ました。
1%未満の誤差なんでいいでしょう。
ちょっと使うかもしれないpythonをChatGPTに聞いて( ..)φメモメモ


ちょっと使う予定ができたpythonスクリプトのひな形をChathGPTに聞いてみてメモ
ChatGPTが便利すぎる(ノД`)・゜・。
普通に調べて同じもの作ろうとしたら5倍の時間はかかかると思います。

パワポの作成編集
pip install python-pptx
```ptest.py
from pptx import Presentation
from pptx.util import Inches

# 新しいプレゼンテーションを作成
prs = Presentation()

# スライドを追加
slide_layout = prs.slide_layouts[0]  # タイトルスライド
slide = prs.slides.add_slide(slide_layout)

# タイトルとサブタイトルを設定
title = slide.shapes.title
subtitle = slide.placeholders[1]

title.text = "Hello, PowerPoint!"
subtitle.text = "Created with python-pptx"

# 画像を追加
slide = prs.slides.add_slide(prs.slide_layouts[1])  # コンテンツスライド
img_path = 'path_to_image.png'  # 画像ファイルのパス
slide.shapes.add_picture(img_path, Inches(1), Inches(1), width=Inches(5))

# プレゼンテーションを保存
prs.save('presentation.pptx')
```

グラフのプロット、画像保存
```gtest.py
import matplotlib.pyplot as plt
import numpy as np

# データの生成
x = np.linspace(0, 10, 100)
y = np.sin(x)
z = np.cos(x)

# グラフの作成
plt.figure(figsize=(12, 6))

# 散布図を作成
scatter = plt.scatter(x, y, c=z, cmap='viridis')
plt.title('Sine and Cosine with Colorbar')
plt.xlabel('x')
plt.ylabel('sin(x)')

# カラーバーの追加
cbar = plt.colorbar(scatter)
cbar.set_label('cos(x)')

# 描画領域の調整
plt.subplots_adjust(right=0.85)  # 右側のスペースを増やす

# 画像の保存
plt.savefig('sine_cosine_with_colorbar.png', dpi=300, bbox_inches='tight')

# グラフを表示する場合（必要に応じて）
# plt.show()
```

エクセルの作成編集１
```etest.py
# python 
from openpyxl import Workbook, load_workbook

# 新しいワークブックの作成
wb = Workbook()
ws = wb.active
ws['A1'] = 'Hello, Excel!'
wb.save('sample.xlsx')

# 既存のワークブックを読み込む
wb = load_workbook('sample.xlsx')
ws = wb.active
print(ws['A1'].value)  # 出力: Hello, Excel!
```

エクセルの作成編集2
```etest2.py
# python 
from openpyxl import Workbook, load_workbook

# 新しいワークブックの作成
import pandas as pd

# Excelファイルを読み込む
df = pd.read_excel('sample.xlsx')
print(df)

# データを操作して新しいExcelファイルを保存
df['New Column'] = df['Existing Column'] * 2
df.to_excel('modified_sample.xlsx', index=False)
```

エクセルの作成編集3
```etest3.py
import xlsxwriter

# 新しいExcelファイルを作成
workbook = xlsxwriter.Workbook('example.xlsx')
worksheet = workbook.add_worksheet()

# データを書き込む
worksheet.write('A1', 'Hello')
worksheet.write('A2', 'World')

workbook.close()
```
これまでに勉強したWeb系技術。（ポエム）

## これまでに勉強したWeb技術

## はじめに
Web開発超初心者が、ちょっとだけわかってきたので、
どんなふうに、勉強したかを紹介するポエム。

ほとんどの方には、メリット0の記事となると思います。

## HTML・CSS・JS

htmlだけのシンプルなサイトをいくつか作ってきたので、
「調べたらどんなこともできる状態」
になってきた。

CSSのプロパティとかJSのAPIやらは無限にあるので、覚えなくていいと思う。

アニメーションを作るのが楽しい。

## GAS（Google Apps Script）
バックエンドの処理を書きたいなーと思ってたら、
GASで簡単にAPIを作る。

クロスドメイン制約がめんどくさかったけど、
簡単に、バックエンドの導入だ。

ついでに、HTTPについてもお勉強。JSON便利やなー

でもなんでサーバーでJSが動くんだ？


## Node.jsの発見

Node.js。
これまで、ブラウザでしか動かないはずのJavaScriptがサーバー側で動く。

普通にすごい！

でも何がしたかった？

## TypeScript

先延ばしにしたくないこと第一位。
型定義のできるJS。その名もTypeScript。

これまで、デバッグにかなり時間をかけていたが、
これで、デバッグとはおさらば。

「エラーがない」＝「ちゃんと動く」

というのは、意外と強い。
開発速度がとても速くなる。

## Reactの発見
なぜ、わざわざサーバーでJSを動かすのか、
それの理由の一つがこれだと思った。
ReactというhtmlライクなJSの書き方。「JSX」

htmlを書いていた頃の悩みを全て解決してくれる。

最初は、VuteとReactの組み合わせがいい。

この組み合わせだと、静的ホスティングだけで公開できるので、
これまで作ったサイト同じ容量で公開できる。

もう離れられない。

## Next.js
Reactだと、SEOできないじゃん
→Next.jsを使おう。

SSRとSSGに対応しているフレームワーク。
便利だし、これまでGASで作ってきたAPIも同じプロジェクト内で簡単に作れる。

APIを作るためだけに、使うのもアリだろという便利さ。

Vercelを使って無料でWebアプリを公開する。

## いろんなAPIを触ったりWebスクレイピング

* X API
* LINE messaging API
* Slack API
* 各種ネタ系API

できることが爆発的に増える。

## 飽きた。

ローカルのファイル操作とかできないの悔しいし、JS飽きた。
他の言語、特に完全オブジェクト指向な言語書きたい！

## 現在

* C C++ C# がブラウザで動いてしまうWeb Assembly
* Play Canvas・UnityのHTML5出力・React Three Fiberなど、3Dをブラウザで描画する
* PWA・React Native・Electronなど、Webの技術をネイティブアプリでも使うんだという叫び
* バックエンドをJava・Pythonとかでかきたいな
* 通信関係の技術（特に、SSH・Web Socketなど）
* サーバーを自分で立てて、Ngrokで公開する

## 終わり
Webって深い。そして変革が速い。

そういえば、全ての根源のHTMLってただのマークアップ言語だね。
フォームを使わずに PowerAppsからSharePointリストの画像列に画像を保存する 最も簡単な方法

PowerAppsからSharePointに画像を保存する方法としては、フォームを使うか、JSON関数を活用して複数列テキストの列に保存する方法、PowerAutomateを使用する方法と様々ありますが、今回ご紹介するのが一番簡単な方法ではないでしょうか。

<iframe width="560" height="400" src="https://www.youtube.com/embed/IBTXk9U8fmM?si=HhRi5lndVZCwkvTv" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
↑動画でも解説しています。

## SharePointリストの準備

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/08b85607-222d-d297-8e9e-a151dfbdc7fc.png)

まずSharePointリストに画像列を追加します。
リスト名は「image_list」画像列の名前は「image_gazou」にしました。

## PowerAppsの準備
＋アイコン➤メディア➤画像の追加を配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/5a88b9a5-c752-c97e-7b08-5cfe5a32344e.png)

画像の追加は、ローカルから画像を追加したり、スマホならカメラで撮影した写真を表示することができるコントロールです。

次に＋アイコン➤入力➤ボタンを配置して、
OnSelectプロパティに以下の数式を設定します。
```
Collect(image_list,{image_gazou:{Value:UploadedImage1.Image}})
```
これだけです。

「image_list」リスト名
「image_gazou」画像列の列名
「UploadedImage1.image」保存する画像
ですので、ご自分の環境に合わせて変更してください。

## 画像を追加してみる

実際にボタンを押してみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/2e878805-fd31-9ad5-2896-25723968feee.png)
きちんと画像列に画像が保存されています。

ちなみに、画像の追加コントロール内の
AddMediaButton1のOnChangedプロパティに先ほどの数式を設定すると
画像を追加・変更する毎にSharePointリストの画像列に保存されるため、
連続して撮影し、保存する場合には便利です。

## ギャラリーで表示
PowerAppsにギャラリーを追加して、データソースを「image_list」にしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/76d14cbf-c902-90e6-3f82-f0d170d62187.png)
特に設定も必要なく画像が表示されました。

ただ、そのままだと画像が荒いので、
表示している画像コントロールのimageプロパティで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/12d640ca-1478-0e22-c3aa-4b135f2584e5.png)
「.Large」や「.Full」を付けると、綺麗に表示するようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/5f362d06-8fd2-c403-0654-7b254355a884.png)

## 画像の更新も可能
ちなみにPatch関数で以下のように数式を設定すると
```
Patch(image_list,{ID:Gallery1.Selected.ID,image_gazou:{Value:UploadedImage1.Image}})
```
ギャラリーで選択した画像を、画像の追加コントロールで表示している画像に更新することができます。
【正規表現】最短一致と最長一致

## 一覧

| 最長一致 | 最短一致 | 意味                          |
|---------------------|----------|-------------------------------|
| *                   | *?       | 直前のパターンの0回以上連続  |
| +                   | +?       | 直前のパターンの1回以上連続  |
| ?                   | ??       | 直前のパターンの0回か1回の出現 |

### 最長一致

デフォルトでは、`*` や `+` は最長一致です。

```text
あいうえお かきくけこ さしすせそ
```

上記の文字列に対して

```
^.*\s
```

は

```
あいうえお かきくけこ 
```

にマッチします。

## 最短一致

最短一致を行うには、`?` を使用します。

```regex
^.*?\s
```

は

```
あいうえお
```

にマッチします。
powershellからタスクスケジューラのタスクを実行するコマンド

~~あんまり使用する場面なさそうだけど~~powershellからタスクスケジューラのタスクを実行するコマンドについて。
タスクスケジューラからpowershellの実行はいくらでもヒットしますが、逆は意外と見つからなかったのでメモも兼ねて記載。


```
Start-ScheduledTask -TaskName "実行するタスク名"
```


ちなみに複数タスクをシリアル実行する場合はforeachを使用して
```
$taskNames = @("実行するタスク名1", "実行するタスク名2", "実行するタスク名3")

foreach ($taskName in $taskNames) {
    Start-ScheduledTask -TaskName $taskName
}
```
でできる。
[Cost Management] EVM(Earned Value Management)

# 一覧
|EVM指標||
|:--|:--|
|`PV`<br>Planned Value|計画時の出来高|
|`EV`<br>Earned Value|完了した作業の出来高|
|`AC`<br>Actual COat|実際に費やしたコスト|
|`BAC`<br>Budget At Completion|完成時総予算|



|現時点での状況評価||
|:--|:--|
|`CV`<br>Coat Variane|負ならコスト超過|
||`EV`-`AC`|
|`SV`<br>Schedule Variance|負なら計画遅れ|
||`EV`-`PV`|
|`CPI`<br>Cost Performance Index|CPI<1ならコスト超過|
||`EV`/`AC`|
|`SPI`<br>Schedule Performance Index|SPI<1なら計画遅れ|
||`EV`/`PV`|


|将来の予測||
|:--|:--|
|`ETC`<br>|残作業コスト予測|
||(`BAC`-`EV`)/`CPI`|
|`EAC`<br>|完成時総コスト予測|
||`AC`+`ETC`|
|`VAC`<br>|完成時コスト差異|
||`BAC`-`EAC`|





# 参考リンク
- [H24A53](https://www.ap-siken.com/kakomon/24_aki/q53.html)
- [R6S51](https://www.ap-siken.com/kakomon/06_haru/q51.html)
- [R5A52](https://www.ap-siken.com/kakomon/26_haru/q52.html)
- [R1A9_PM](https://www.ap-siken.com/kakomon/01_aki/pm09.html)