OmniAICreator/Qiita-1.07M huggingface dataset:
Rails7でのDockerfile

# 環境

- Rails 7.0.5
- Postgres
- Docker 20.10.23

# Dockerfile

開発環境、プロダクション環境共用。


```dockerfile
# Build stage
FROM ruby:3.2.2-alpine AS build

ARG UID=1000
ARG GID=1000
ARG RAILS_ENV=production

ENV APP_USER=app
ENV WORKDIR=/project

# yarn は rails assets:precompile のために必要。
RUN apk add --no-cache --update build-base \
  linux-headers \
  postgresql-dev \
  tzdata \
  busybox-suid \
  shared-mime-info \
  gcompat \
  yarn

RUN set -x && \
  addgroup -g ${GID} -S ${APP_USER} && \
  adduser -g '' -S -D -u ${UID} ${APP_USER} && \
  mkdir -p ${WORKDIR} && \
  chown -R ${APP_USER}:${APP_USER} ${WORKDIR}

WORKDIR ${WORKDIR}
USER ${APP_USER}

COPY --chown=${APP_USER}:${APP_USER} Gemfile Gemfile.lock ./

RUN if [ "$RAILS_ENV" = "production" ]; then \
      bundle config set --local without 'development test' \
    ; fi
RUN bundle install

COPY --chown=${APP_USER}:${APP_USER} . ./

RUN bundle exec rake assets:precompile

# Final stage
FROM ruby:3.2.2-alpine

ARG UID=1000
ARG GID=1000
ARG RAILS_ENV=production

ENV APP_USER=app
ENV WORKDIR=/project
ENV RAILS_LOG_TO_STDOUT=true

# gcompatが無いとrails起動時にnokogiriがエラーになる
# https://github.com/sparklemotion/nokogiri/issues/2416
# https://nokogiri.org/tutorials/installing_nokogiri.html#linux-musl-error-loading-shared-library
RUN apk add --no-cache --update \
  postgresql-dev \
  tzdata \
  busybox-suid \
  shared-mime-info \
  gcompat

RUN set -x && \
  addgroup -g ${GID} -S ${APP_USER} && \
  adduser -g '' -S -D -u ${UID} ${APP_USER} && \
  mkdir -p ${WORKDIR} && \
  chown -R ${APP_USER}:${APP_USER} ${WORKDIR}

WORKDIR ${WORKDIR}
USER ${APP_USER}

COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build --chown=${APP_USER}:${APP_USER} ${WORKDIR} ${WORKDIR}

CMD [ "rails", "s", "-b", "0.0.0.0" ]

EXPOSE 3000
```


# .dockerignore


```.dockerignore
*.md
*.log
*.pid
Dockerfile*
/.bundle
/.circleci
/.dockerignore
/.editorconfig
/.env*
!/.env.production
!/.env.staging
/.git
/.gitattributes
/.github
/.gitignore
/.overcommit.yml
/.rspec
/.rubocop.yml
/.ruby-lsp
/Procfile.dev
/app/assets/builds/*
/coverage
/docker
/docker-compose.yml
/docs
/log
/miniodata
/node_modules
/public/assets
/storage
!/storage/.keep
/out
/spec
/tmp
/vendor/bundle
```
「ふつうのエンジニア」になるための、ちょっとした発想の転換

エンジニアは、もしくはエンジニアを目指している人の中には、意識的かどうかはともかく、エンジニアとしてより活躍するために日々なにかを学んでいる方が多くいます。

学んでいる人の多くは、最新の技術や新しい設計のトレンドを追ったりしながら、いつかは「〜のスペシャリスト」もしくは「フルスタックエンジニア」と呼ばれるような人物像を目指すことが多いのではないでしょうか。

これは素晴らしいことです。目標を持たないよりは持っているほうが好ましいですし、そのモチベーションによって様々なスキルが向上することでしょう。

しかしこのエントリでは視点を変えてみて、上記のような目標に関心が薄かったり、周りの技術力の高さにくじけそうになってしまっていたりする人に焦点を当てて、**様々な種類のプロダクト開発・プロジェクトにおいて重宝される**ような「ふつうのエンジニア」になるための戦略を、個人の経験則から考えてみたいと思います。

## 「ふつうのエンジニア」とは

上記で書いた「ふつうのエンジニア」とは完全に造語です。

イメージとしては、IT業界において特殊なスキルや経験を持っている「替えの効かないエンジニア」ではなく、むしろ「替えの効くエンジニア」を指しています。

これは「価値を発揮しないエンジニアから替えが効く」ではなく「いろいろな種類のプロダクト開発・プロジェクトのどれに交わったとしても一定度の活躍ができるから替えが効く」ことが背景にあります。

言い換えれば「パッと見は気が付かれないけど、その人がいるといないとでは仕事のスムーズさがまったく違う」ようなエンジニアを表現しようとしています。結局「替えの効かないエンジニア」ではありますね。

それでは、あらためてその作戦を考えてみます。

## 「開発が上手い」より「仕事が上手い」を優先する

難しい設計手法や最新のテクノロジーを知らずともバリューを発揮するためには、**「開発」という言葉を一歩引いて「仕事」として捉えなおす**ことが重要です。

とくに経験の浅いエンジニアの場合、開発スキルよりも「仕事術」と呼ばれるような一般的な社会人のスキルが必要な場面も結構あるように思います。

もし「自分は〜して仕事を進めるのが得意・好きで、それを周りも評価してくれている」というような自己認識がまだなければ、先に「どう仕事をすると上手く進むか」を考え、日々試してみるとかなり効果があるはずです。

### 計画、計画、そして計画

仕事術には万能なものはなく、個人のキャラクタによって合うかどうかもありますが、ひとつ具体例を挙げてみます。

私が重要視するのは、**計画**です。

たとえば仕事を開始する前に10分、仕事を終わる前に10分でもよいので、1日を想像したりふりかえったりする時間を確保する。

始業前であれば、今日必ず終わらせたいこと、どんな進捗が出ていたら嬉しいかを確認しつつ、タイムスケジュールやTODOリストを整理する。

始業後であれば、今日の目標は達成できたかをふりかえりつつ、明日の自分へ引き継がないといけないことはないか整理する。

この少しの時間がさまざまな規模で効いてくることを、計画好きの人は知っています。好き嫌いはあると思いますが、ぜひ一度試してみてほしいです。

### 朝会前にひとりで計画する

ちなみに似たようなことをチーム単位で朝会やデイリーとして行っている組織やメンバーは多いでしょう。

しかしこれに加えて、朝会前にまず一人でデイリーのための準備をしてみることを強くオススメします。

その後にデイリーに参加すると、計画の解像度ははるかに上がりますし、チームの計画の「穴」を見つけたりすることもできます。

ここまで一切エンジニアリングスキルの話は出てきませんでした。しかしこのような形での貢献は、チームに対してもエンジニアとしての自身の業務にも、大きく意味があるはずです。

## 「開発が上手い」より「コミュニケーションが上手い」を優先する

エンジニアになった理由として「もくもくとパソコンでプログラミングしていればいいから」というのは私だけでしょうか。正直、必要な仕様だけもらってあとはひたすら集中してプロダクトを作るのはもっとも楽しい時間です。

しかし「コードを書く」以外でバリューを発揮しようと思うと、避けては通れないのがコミュニケーションです。

というか**コミュニケーションが面倒だからエンジニアになったのに、ややもすれば他の職種以上にコミュニケーションが重要かもしれない**のが、エンジニアのジレンマのひとつだとよく思っています。

「ふつうのエンジニア」を目指すのであれば、孤高の存在は諦めて、自身のできる範囲でコミュニケーションも頑張る必要はあるでしょう。

### とにかく発言を増やす

あなたが年がら年中まくしたてているエンジニアでなければ、シンプルに発言の量が倍になるよう意識してみるのは良い工夫のはずです。

とくに「発言するタイミングを見計らっている」ことが多いようであれば、そのフィルターをもうすこし緩くして気軽に話をしてみると、意外と効果があります。

フィルターを緩めようとする直前、「この話題には明るくないから」「無駄なことを言って恥を書きたくない」「みんなの時間を無駄にしたくない」など、色々な言い訳も出てくることでしょう。

しかしそのデメリットは、たいてい「自分が話をしてみたことがキッカケで話が円滑に進んだ」というメリットで上書きされるはずです。

### ミーティングの結論を想像しておく

もうひとつ、ちょっとの準備で大きく効果の出ることに「ミーティングの準備」があります。結局計画の話をしてますね。

準備といっても難しいことはなく、ミーティング前（もしくは最初の2,3分)で「**このミーティングはどのような結論に落ち着くだろうか**」ということを考えるだけです。

これが想像できていれば、議論はスムーズに理解できるでしょう。あるいはそんなあなたが議事録を書いてあげれば、とても整理されたドキュメントが書けるはずです。さらには議論のファシリテーションだって行えるでしょう。

もし結論がまったく見えなくても、それもひとつの成果です。「なぜ想像できなかったか」がわかっていれば、そのミーティングで理解したり質問したりすべきことが明確になるはずですし、もしかするとミーティングを開催する意味が無いかもしれません。

ここでもコーディングは一切登場しません。しかしこのミーティングは、おそらく正しい設計やアジャイルな開発においてポジティブな影響を与えていることでしょう。

## まとめ

なるべく具体的なtipsとあわせて書いてみましたが、あらためて「エンジニアリングスキルよりも大切なものがあるかも」という観点を持ったときの考えを載せてみました。

エンジニアリングが楽しい人にとってこれらのスキルは、最新の技術を追うよりも地味でつまらないものかもしれません。

ただ「バリューを発揮する」という観点では、一度考えてみたり取り組んでみたりする価値はあるはずです。

ほか「ふつうのエンジニア」の人からのコメントもお待ちしています。

## こんな記事も書いています

### [ミーティングにはサプライズを持ち込まない](https://qiita.com/kobori_akira/items/8f721c17b9340d7f4219)

コミュニケーションに関して。「ミーティングの結論を想像しておく」というテーマをさらに書き直したものです。
Componet Error

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめA～M](https://qiita.com/Keiji_otsubo/items/f3ddedee6793bf1576f8)




+ [Componet Error](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007AhTeb)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/5001bfb0-1f72-1d91-ffa8-242e3fc256b3.png)

:::note
I just had to  "Enable Profile Access for Apex Class".  I went to Installed Packages, then into PopUps, then PopUpController and moved the other profiles over. 
:::
ディレクトリを扱う練習

|　コマンド　|　説明　|
| - | - |
| rmdir | 空のディレクトリを削除するとき　|
| umask | デフォルトのアクセス権,新規ファイルや新規ディレクトリの作成時のパーミッションを設定するコマンド,現在の設定値を表示する　|
|chmod | モードを変更するという意味合いで既存のディレクトリやファイルの許可モードの設定をする　|


例）
```sh
rm testfolder/ #削除できない
rmdir testfolder/
```
- ディレクトリにファイルやサブディレクトリが含まれている場合はrmdirコマンドでは削除できないので(rm -r)
```sh
例：rm -r testfolder
```
- ディレクトリの中にファイルやサブディレクトリを入れる時
```sh
例：mkdir -p
```
- umask (user maskの略)
ディレクトリやファイルを新規作成する際のデフォルト(既定)の許可モードの設定をする為のコマンド
パーミッションとはアクセス権のこと
<font color="Red">umaskの値を変更してしまうと、予期せずパーミッションがオープンになりすぎる危険性があるので注意</font>


- chmod (change modeの略)


## 参考
- https://e-words.jp/w/umask.html
- https://www.ibm.com/docs/ja/aix/7.2?topic=c-chmod-command
- https://wa3.i-3-i.info/index.html
- https://youtu.be/hH5Awy6QPNU
- ITエンジニア1年生のための まんがでわかるLinux コマンド＆シェルスクリプト基礎編
- https://qiita.com/kamorits/items/6f342da395ad57468ae3
生成ＡＩ時代の組織を考える：人間脳のために情報削減する作業から解放され、今まで切り捨てられていた冗長な説明や些細な情報も取扱い可能になり、結果として新しいチャレンジに取り組む決定ができるようになる。

https://note.com/z_wara/n/ndc762e90e224
2023/8/7主にITとかセキュリティの記事

NISCにサイバー攻撃、メールデータ5千人分流出か　気象庁も被害(8/5)
https://news.yahoo.co.jp/articles/e405a22aea924f9c45bb60217898aa2319ef1f31

内閣サイバーセキュリティセンターで情報漏えい　未知の脆弱性が原因(8/5)
https://news.yahoo.co.jp/articles/1a0baeb0365dca5528c86e5030f96cf8ab086f3f

内閣情報機関に不正侵入(8/5)
https://www.okinawatimes.co.jp/articles/-/1199619

気象庁に不正アクセス　メールの一部流出か(8/4)
https://www.sankei.com/article/20230804-7Q2OX64SCFNLJEFNBQIH4YBZLU/

不正アクセス受けたシステム 同種の攻撃受けた米企業のもの(8/5)
https://www3.nhk.or.jp/news/html/20230805/k10014153901000.html

病院ＰＣに「警告」、職員が「サポート窓口」へ電話すると…患者情報流出か(8/5)
https://www.yomiuri.co.jp/local/kyushu/news/20230804-OYTNT50146/

テスラ車をハッキングして有料機能をタダで使う方法が発見される(8/5)
https://www.gizmodo.jp/2023/08/tesla-self-driving-free-hack-jailbreak-research.html

正常なAndroidアプリがある日突然に不正なアプリに更新される危機、注意を(8/5)
https://news.mynavi.jp/techplus/article/20230805-2742566/

【墨汁速報】”カーブ”ハッカーETHを半分返金するも「攻撃から救済した」とし6.24億円の仮想通貨を請求(8/5)
https://coinchoice.net/curve-finance-alchemix-pool-hacker-persists-it-was-a-white-hat-operation_bnews/

レイヤーゼロ（LayerZero）とは？なぜイーサリアム上で今注目されているのか(8/4)
https://coinchoice.net/what-is-layerzero-and-zro-token/

｢攻撃を受けてからでは遅すぎる｣ロシアのハッカーから狙われる日本のサイバー防衛のお粗末さ(8/4)
https://news.goo.ne.jp/article/president/bizskills/president_72270.html

ChatGPT、Bard…学校で「生成AI」が活用されないワケ　“格差”生む可能性も　大学教員が解説(8/5)
https://news.yahoo.co.jp/articles/82d3d01bb5fa00a8391084a8d5b137efaa587623?source=rss

持ち帰り仕事は違法？ 働き方改革で顕著になる労働の「闇」とは(8/5)
https://news.yahoo.co.jp/articles/573d37745d5027dd1699362d190b780737b5de3f?source=rss

運転免許も母子手帳も…マイナカードと一体化、範囲は広がる？(8/4)
https://www.tokyo-np.co.jp/article/267939

政府が言う「マイナ保険証のメリット」検証　データはツッコミどころ満載　医師や患者よりビジネス優先か(8/5)
https://www.tokyo-np.co.jp/article/267976
テプラ情報まとめ

備品管理のお供、テプラを買う際にあると便利なPC接続機能の有無をメインに載せた表。追加情報大歓迎。

| 名称 | 価格 | PC接続 | 説明 | 発売年 | 製造 | 4mm<br>     テープ | 6mm<br>     テープ | 9mm<br>     テープ | 12mm<br>     テープ | 18mm<br>     テープ | 24mm<br>     テープ | 36mm<br>     テープ | URL |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 「テプラ」PRO   SR424 | 16,800円 | 不可 | 「テプラ」PROシリーズの家庭向けモデル。<br>     和文6書体（かな文字含）を内蔵するなど、家庭向けとしては従来機に比べて高い機能をほこっている。 | 1998年 | 中止 | △ | ○ | ○ | ○ | ○ | × | × | https://www.kingjim.co.jp/st/popup/products/tepra/gallery/sr424.html |
| 「テプラ」PRO SR606 | 26,800円 | 不可 | 「テプラ」PROシリーズ初めての機種。6mm幅から24mm幅まで5種類の幅のラベルが作成できる。<br>      ノンラミネートタイプのPROテープカートリッジを使用し、TRテープと比べてのランニングコストを約3割ダウンさせた。   <br>     さらにカートリッジのトップローディング化や、各種の自動化ソフトなど現在のラベルライター市場の標準となったモデル。 | 1992年 | 中止 | △ | ○ | ○ | ○ | ○ | ○ | × | https://www.kingjim.co.jp/st/popup/products/tepra/gallery/sr606.html |
| 「テプラ」PRO SR707 | 29,800円 | 不可 | 「テプラ」PROシリーズのビジネス向け上位機種として開発された。<br>     自動的にラベルのカドを丸くカットする「オートトリマー」や、<br>     複数のラベルを貼り合わせて大きなラベルを作る「でか２」（拡大印刷機能）を初めて搭載。 | 1995年 | 中止 | △ | ○ | ○ | ○ | ○ | ○ | × | https://www.kingjim.co.jp/st/popup/products/tepra/gallery/sr707.html |
| 「テプラ」PRO SR717 | 29,800円 | 不可 | SR707の後継機種。「テプラ」のオフィスユース向け最上位機種として開発された。   <br>     オートトリマーをさらにスピードアップさせた「スピードトリマー」を搭載している。 | 1995年 | 中止 | △ | ○ | ○ | ○ | ○ | ○ |  | https://www.kingjim.co.jp/st/popup/products/tepra/gallery/sr717.html |
| 「テプラ」PRO SR818 | 39,800円 | 不可 | 「テプラ」シリーズで初めて、36mm幅テープカートリッジが使用できるようになった、ビジネス向けの最上位機種。<br>     印字の美しい「ハイパーアウトラインフォント」や、ラベルの裏紙をはがしやすくする「ハイパーピーラー」などの機能を搭載している。 | 1997年 | 中止 | △ | ○ | ○ | ○ | ○ | ○ | ○ | https://www.kingjim.co.jp/st/popup/products/tepra/gallery/sr818.html |
| 「テプラ」PRO SR828 | 39,800円 | 不可 | SR818の後継モデル。基本性能を踏襲しつつ、内蔵書体を増やすことによって、表現力を強化した。 | 1997年 | 中止 | △ | ○ | ○ | ○ | ○ | ○ | ○ | https://www.kingjim.co.jp/st/popup/products/tepra/gallery/sr828.html |
| Anvie SEGA | - | 不可 | - | - | 中止 | ？ | ？ | ？ | ？ | ？ | ？ | ？ | - |
| SR520 | - | OK | - | - | - | ○ | ○ | ○ | ○ | ○ | ○ | × | - |
| SR520X | - | OK | - | - | - | ○ | ○ | ○ | ○ | ○ | ○ | × | - |
| SR720 | - | OK | - | - | - | ○ | ○ | ○ | ○ | ○ | ○ | × | - |
ChromeOSでできないことへの対応

今までメインに利用していたWindows11ではできて、ChromeOSではできないことについては以下の対応を行いました。

## ネイティブアプリが提供されていないもの

- OneNote -> Web版の利用
- VTune Profiler -> 別のLinuxマシンに[GUI版をインストール](https://www.intel.com/content/www/us/en/docs/vtune-profiler/installation-guide/2023-0/package-managers.html#APT)し、利用は[ThinLinc](https://averagelinuxuser.com/thinlinc/)によるリモートアクセスとする

## ハードウェアが対応していないもの

- 音楽CDのリッピング -> 別のLinuxマシンに[環境を用意](https://github.com/zyake/cd_ripping)して対応(OneDriveへのアップロードも自動化する予定)
    - [CDの仕様](https://theproaudiofiles.com/cd-text-metadata-artwork/)を理解しておらず、エンコード方式の選定やスクリプトの作成も含めてこれが一番時間がかかりました...
【Unity】アイリスイン/アイリスアウトShader

## 概要
よく見かけるワイプ演出のやつです。
ポケモンスリープで見かけたので作ってみました。
![wipe.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3112894/d153007a-fb30-a9da-26b2-70ac35841671.gif)

## 実装
```
Shader "Custom/FadeRadial"
{
    Properties
    {
        [NoScaleOffset]
        _MainTex ("Texture", 2D) = "white" {}
        _Threthold ("Threthold", Range(0, 1)) = 0
        _CircleCenterX ("Circle Center X", Range(0, 1)) = 0.5
        _CircleCenterY ("Circle Center Y", Range(0, 1)) = 0.5
    }
    SubShader
    {
        Tags {
            "RenderType"="Transparent"
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderPipeline"="UniversalPipeline"
        }
        LOD 100

        Pass
        {
            Name "ForwardLit"
            Tags { "LightMode"="UniversalForward" }

            Cull Off
            Lighting Off
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes
            {
                float4 positionOS : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct Varyings
            {
                float2 uv : TEXCOORD0;
                float4 positionHCS : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_TexelSize;
            half _Threthold;
            half _CircleCenterX;
            half _CircleCenterY;

            CBUFFER_START(UnityPerMaterial)
            float4 _MainTex_ST;
            CBUFFER_END

            Varyings vert (Attributes v)
            {
                Varyings o;
                o.positionHCS = TransformObjectToHClip(v.positionOS.xyz);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            half4 frag (Varyings i) : SV_Target
            {
                // Textureサイズによって円の比率が歪むので正円になるようにする
                half resolution = _MainTex_TexelSize.z / _MainTex_TexelSize.w;
                half2 center = half2(_CircleCenterX, _CircleCenterY);
                half2 targetUV = i.uv;
                targetUV -= center;
                targetUV.x *= resolution;
                targetUV += center;
                half d = distance(center, targetUV);
                // stepの引数の順番を変えると印象が変わる
                half isMasked = step(_Threthold, d);
                half4 col = tex2D(_MainTex, i.uv);
                return isMasked ? half4(0, 0, 0, 1) : col;
            }
            ENDHLSL
        }
    }
}
```

## あとがき
Textureの解像度によって円部分が楕円になってしまう現象に躓きました。。
Textureのサイズを参照して解消していますが、Image.Width/HeightがTextureの縦横比と一致してないと多分おかしくなります。
システム環境変数が変更できない...

PCを新しくしたタイミングで、システム環境変数を編集しようとた時に起きた出来事の備忘録です。

OS：Windows10 Pro

以下の手順で環境変数の編集を試みたが、なぜか編集ボタンが非活性になっていて編集できない...
「設定」→「システム」→「バージョン設定」→「システムの詳細設定」→「環境変数」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520337/c2739696-c778-54a0-8b0a-99ca39d5be13.png)

管理者権限があるユーザーなのに、なぜか非活性...


解決方法
①タスクバーの検索ボックスにコマンドプロンプトと入力。
②検索結果のコマンドプロンプトを右クリックし、管理者として実行を選択。
③コマンドプロンプトに以下のコマンドを入力。

```
rundll32.exe sysdm.cpl,EditEnvironmentVariables
```

こちらで編集することができました。
なぜ普通に編集できなかったんだろうか...
市民開発者によるPowerPlatform（PowerApps）開発録①

# はじめに
開発者は非IT職従事の市民開発者:beginner:。
業務外でコツコツ学習と開発
アウトプットが大事とのことなので初投稿

# 開発経緯
AzureのCognitiveServeceにあるAIOCR‐FormRecognizerを連携させたシステムをつくりたいなー。
Progateで言語学習するもAPIまで考えるとIT初学者にはハードルが高く右往左往:sweat_drops:

そういえば、PowerAppsというアプリ開発ツールがあるな・・・コネクタがAPIの代わりになりそう！MSツールで統一すれば色々都合がよさそうでRPA（PAD）まで連携できそう。

##### Microsoftの統合されたローコードツールPowerPlatformを駆使して開発だ！&#x1F4A1;
市民開発者的には下記概念で置き換える。
- フロント-PowerApps
- バックエンド-PowerAutomate
- DB-SharePointList
- API-コネクタ連携
- RPA-PowerAutomateDesktop

# 開発したPowerAppsの構成図
![構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3086885/30540d28-9c10-ce2f-0b43-96ccd898d888.png)

# PowerAutomate
![スクリーンショット 2023-08-07 002339.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3086885/2d3141ef-2028-6859-1db5-6ef6a65d90a6.png)
![スクリーンショット 2023-08-07 002354.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3086885/1fd7d3db-155b-24ff-88b1-6e1eac4609e9.png)


# PowerApps画面
初期画面では任意のPDFを選択しOCR実行ボタンでPowerAutomateを起動させます。
FormRecognizerのOCR分析は時間がかかるので10秒程度Waitさせてから画面遷移。
![スクリーンショット 2023-08-07 000021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3086885/2c4903fb-48a3-1219-015e-d94831b872a2.png)
![スクリーンショット 2023-08-07 000128.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3086885/dc705ad4-e5c8-c8a8-1b07-578177f28a2d.png)
分析結果の突合もできた方が良いので左上の＜アイコンでPDFを展開
左下Excel出力ボタンをクリックしフォーム値をローカルのOneDriveエクセルに出力。
ドロップダウンにPADのフローURLを埋め込んで任意のPADフローを起動。
![スクリーンショット 2023-08-07 000152.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3086885/94bce645-41e0-bcf2-8623-46ef15c65ca0.png)

# まとめ
AiBuilderを使った方が開発は圧倒的楽ですが、分析性能に差異が見受けられたためFormRecognizerを使った統合的機能を持ったPowerAppsを開発しました。
次回の２はFormRecognizerスタジオのモデル設計から再度確認していこうと思います。
![スクリーンショット 2023-08-07 005946.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3086885/3d942d5a-b4d6-0e47-848e-25173dbfe93d.png)
VSCode + PlatformIO で ATtiny406の開発環境を準備

# VSCode + PlatformIO の用意
ATtinyはAtmelが開発したAVRと呼ばれる8bit RISCのマイコンです。
AVRの一種であることからメジャーなATtiny(ATtiny85やATtiny402など）はArduinoIDEに対応しています。
しかし本稿のターゲットとしているATtiny406はArduinoに対応していないようで利用できませんでした。
（対応していたらすみません。コメントで教えていただけると嬉しいです）
そこでVSCode + PlatformIOで開発環境を作りました。
ちなみにATtiny406をターゲットとした理由として、パッケージはFQN20のためGPIOが18本あります。
価格も100円を以下(2023/8/1時点)と安く、はんだ付けは大変ですがサイズも3mm×3mmと小さくメリットが多いです。
# インストール
インストール自体はVSCodeとPlatformIOをインストールだけなので簡単です。
1. VSCode のインストール
下記からインストーラをダウンロードし、VSCodeをインストールします。
https://azure.microsoft.com/ja-jp/products/visual-studio-code
2. 拡張機能から「PlatformIO IDE」をインストールします。
こんな感じのアイコンの機能拡張です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181997/aefd7c04-ca09-25ef-afdc-b0548284f5f1.png)
# ATtiny406 でLチカをやってみる
## 新規プロジェクト
1. 画像のアイコン →「Open」をクリックして、PlatformIO のポータル画面を立ち上げます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181997/785d105f-f55c-525e-0c42-cf20571c8340.png)
2. 「New Project」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181997/2fb97fff-03a8-6bd6-f9c8-ac7d5afa0ca1.png)
3. Wizardが表示されるので、「Board」に「ATtiny406(Microchip)」を選択して「Finish」をクリックします。
「Name」は適当に、「Framword」は「Arduino」が自動選択されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181997/aa748aca-0b30-a3bc-d3ac-bdcb4470c825.png)
4. こんな感じでファイルが自動生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181997/310dc5ce-e5d0-f2d9-e2dc-8d3de902a62c.png)
## main.cpp
1秒ごとに点滅を繰り返すLチカを実装します。
出力ポートはPA1を想定しています。
```cpp:main.cpp
#include <Arduino.h>

void setup() {
  // put your setup code here, to run once:
  pinMode(PIN_PA1, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  static uint8_t val = HIGH;
  digitalWrite(PIN_PA1, val);
  val = !val;
  delay(1000);
}
```
## platformio.ini
platformio.iniでは、書き込みルールや動作周波数について記載します。
私はSerial UPDIでしか書き込んだことがないので、他はわかりません。
そこで本稿でもSerial UPDIで書き込みます。
また書き込み速度について遅めに設定しています。（速いと失敗しました）
CPUの周波数はboard_build.f_cpuで設定しています。（今回は1MHz）
```ini:platformio.ini
[env:ATtiny406]
platform = atmelmegaavr
board = ATtiny406
framework = arduino

board_build.f_cpu = 1000000L
board_hardware.oscillator = internal
upload_protocol = serialupdi
upload_speed = 57600

board_hardware.bod = 1.8v
board_hardware.eesave = yes
board_hardware.uart = no_bootloader
board_hardware.rstpin = reset
```
## 配線
書き込みについてはUSB-Serialアダプタを使いますが、Serial UPDIは基本的に一本のPINへ書き込むだけでOKです。
下記はスイッチサイエンスのATtiny402のボードの配線ですが、ATtiny406も一緒です。
シリアルポートのRXとTXを、マイコンのUPDIに対して下記の通り接続すればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181997/af3b1a69-e684-5a7e-dc09-b3989d51ad4d.png)
# 最後に
GPIOからの読み込みや書き込みを、digitalReadやdigitalWriteを使わずに行う方法について書く予定です。
またCCLについても書いていこうと思います。
気が向いたらElecrowを使った基板発注の方法も書いていきたいです。
Ubuntu で Docker のインストール


Docker のインストール方法は [色々](https://kinsta.com/jp/blog/install-docker-ubuntu/) あるみたいですが，

-   **パターン 1: Docker Engine のインストール**
-   パターン 2: Docker Desktop のインストール

の 2 つについて紹介します

Docker Desktop が Ubuntu をサポートしたのは最近なので，まだ Docker Desktop に対応していないツールがあります

そのため，私は **パターン 1: Docker Engine のインストール** を推奨します

**動作環境**

Ubuntu 22.04

## 前準備 ([参考](https://docs.docker.com/engine/install/ubuntu/#set-up-the-repository))

必要なパッケージをインストールします

```shell
    sudo apt update
    sudo apt install ca-certificates curl gnupg
```

aptリポジトリを追加します

```shell
    sudo install -m 0755 -d /etc/apt/keyrings
    sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
    sudo chmod a+r /etc/apt/keyrings/docker.asc

    # Add the repository to Apt sources:
    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
      $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
      sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    sudo apt update
```

docker グループを作成し，ユーザーを所属させます

```shell
    sudo groupadd docker
    sudo usermod -aG docker <ユーザー名>
```

これで前準備は完了です

## パターン 1: Docker Engine のインストール

Docker Engine のインストール

```shell
    sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```

インストール確認

```bash
    docker --version
```

最新バージョンの Docker には `docker-compose` もデフォルトで付属しています

```bash
    # ハイフンは不要です
    docker compose version
```

これで完了です

## パターン 2: Docker Desktop のインストール ([参考](https://docs.docker.com/desktop/install/ubuntu/))

deb パッケージを[公式リンク](https://docs.docker.com/desktop/install/ubuntu/)からダウンロードし，インストールします

```bash
    sudo apt-get update
    sudo apt-get install path/to/docker-desktop-<version>-<arch>.deb
```

Docker Desktop のアプリケーションがインストールされているはずです

![docker_install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291419/df5c1efe-44b6-ef30-418c-17f65129f291.png)

---

以上です
GitHub Actionsのストレージ容量オーバーの対処

```
Create Artifact Container failed: Artifact storage quota has been hit. Unable to upload any new artifacts
```

レポートを出力するものを使うとすぐ容量オーバーする。ちな自分はPlaywrightのGithub Actionsのテンプレ使ってたらいつの間にか容量オーバーした

## 全消し

個人的にコレが使いやすい↓

https://github.com/kolpav/purge-artifacts-action

```yml
name: 'artifacts cleanup'
on:
  workflow_dispatch:

jobs:
  delete-artifacts:
    runs-on: ubuntu-latest
    steps:
      - uses: kolpav/purge-artifacts-action@v1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          expire-in: 0
```

`expire-in`を`0`にすると全消し。`workflow_dispatch`は手動実行出来て便利なのでおまじないのようにとりあえずつけてる

で実行すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496802/5a3048c8-54a3-46ae-4280-3d711c799e4e.png)

削除権限がないので```Settings > Actions > General > Workflow permissions```で ```Read and write permissions```に変更

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496802/fe414d15-3b13-e0d9-8e83-56c6bc665a69.png)

こういうのはエラーになって初めて知るから嫌になっちゃう
【Android】WebViewを使ってみた①

## はじめに
WebViewの技術を使って、AndroidのアプリでWebページを表示してみようと思います。
また、webページからAndroidのプログラムのメソッドを呼び出してみたり、Android側のページに戻ったりもしてみようと思います。
プログラムソースがちょっと多めなので、複数回に分けて投稿しようと思います。

第一回目は作成するアプリの紹介をします。
※デザインはこだわっていません。。


#### トップ画面（Android）
webページに遷移するためのボタンを配置しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/61fa020b-b910-2c76-70cd-f219de1744bd.png)
#### 計算画面（webページ）
こちらの画面はwebページです。
URLをたたいて、webページにアクセスしています。
計算ボタンを押すことで足し算の結果を求めることができます。
メイン画面に戻るボタンを押すとトップ画面に戻ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/de214956-c349-307f-951e-a8ac0058358d.png)

## 関連リンク

https://qiita.com/mojapico/items/a6ef2e741b80c88787c0

https://qiita.com/mojapico/items/ed8ca624de85fe47cffa

https://qiita.com/mojapico/items/09cd43293e503e3b49d2
ICカードの種類を識別してみる。

# はじめに
カードの種類を識別できたら、なんか良いような気がしたので識別してみることにする。

リポジトリはこちら
PaSoRiに対応してます

https://github.com/segfo/smartcard

# 動機
ICカードのタイプ識別をしたい。
細かい仕様は券面に書いてないので、そういうのを知るために。
脆弱なICカード（Mifare Classic 1K/4K）とかを簡単に識別したかった。

# PC/SC
PC/SC仕様に則ってるカードのみが対象になる。
あと、原則として非接触ICカード（Contact Less=CL）を対象とする。
銀行のカードはCLじゃないけどなんか読めた。

# ATR(Answer To Reset)
カードを置くと、カードリーダーに対してICカードがATRペイロードを送る。
ATRには、どのようなカードなのか、みたいな簡易的な識別情報が書いてある。
そいつをパースしていい感じに表示する。

## パースの補助情報
ここに識別情報がリストされてるので、これを使ってみる。
数が膨大なので7割から8割程度対応できればいい。

https://pcsc-tools.apdu.fr/smartcard_list.txt

## パースの方針
原則としてATRを真面目にパースする。
例外として、txtには .. みたいなやつとか [7,8]　のような正規表現っぽいものが書かれてるのでそういうのは弾く。

## ATRのヘッダ
1バイト目からヘッダ情報に成っていて、ここらへんには興味はない。
必要なのはカードのヒストリカルバイト（履歴バイト・JISX6320-3:2009では管理情報バイト）で識別することにする。

### ヒストリカルバイトとカード名だけ抽出したJSON

https://github.com/segfo/smartcard/blob/master/smartcard_list.json

### 識別している部分

https://github.com/segfo/smartcard/blob/master/src/pc_sc_standard.rs#L191

# 実行結果
いろんなカードを置いてみる/刺してみる

## 銀行のICカード
MUFGではないがMUFGと識別された。おそらく共通のものを使っているっぽい。

```
[Answer to reset(ATR)]
    カード名: MUFG (.jp) (Bank)
    管理情報バイト: 80-73-c6-01-08
確立したプロトコル: T1(ブロック転送モード)
ATS: 読み出し非対応
カード種別: 不明なカード
種別名: 不明
カードID: 不明
```

## 免許証

```
[Answer to reset(ATR)]
    カード名: Driving License card of Japan (NFC type-B) (eID)
    管理情報バイト: 00-00-00-00-91-81-c1-00
確立したプロトコル: T1(ブロック転送モード)
PUPI: 95-bb-b9-c7
ATS: 情報無し(コマンドは成功しました)
カード種別: ISO14443-4B (Infineon / Atmel /ST microelectronics)
カード名: Type B(T=CL)
種別名: Type B(T=CL)
カードID: b4
```

## マイナンバーカード
```
[Answer to reset(ATR)]
    カード名: ID card issued by Japan government (eID)
https://www.kojinbango-card.go.jp/mynumber/index.html
    管理情報バイト: 00-00-41-e0-b3-81-a1-00
確立したプロトコル: T1(ブロック転送モード)
PUPI: 5b-f7-f3-8b
ATS: 情報無し(コマンドは成功しました)
カード種別: ISO14443-4B (Infineon / Atmel /ST microelectronics)
カード名: Type B(T=CL)
種別名: Type B(T=CL)
カードID: b4
```
## SUICA
```
[Answer to reset(ATR)]
    カード名: RFID - FeliCa (generic) (as per PCSC std part3)
Suica public transit card (Japan IC system)
(also: Hayakaken, ICOCA, Kitaca, manaca, nimoca, PASMO, PiTaPa, SUGOCA, TOICA)      
https://en.wikipedia.org/wiki/Suica
Octopus, MTR network from Hong Kong, 2014
    管理情報バイト: 80-4f-0c-a0-00-00-03-06-11-00-3b-00-00-00-00
確立したプロトコル: T1(ブロック転送モード)
IDm: **-**-**-**-**-**-**-**
PMm: 10-0b-4b-42-84-85-d0-ff
ROM種別: 10
IC種別: 0b
カード種別: FeliCa
カード名: FeliCa
種別名: FeliCa
カードID: f0

```
## Qurio Lockの施錠・解錠用カード
```
[Answer to reset(ATR)]
    カード名: RFID - FeliCa (generic) (as per PCSC std part3)
Suica public transit card (Japan IC system)
(also: Hayakaken, ICOCA, Kitaca, manaca, nimoca, PASMO, PiTaPa, SUGOCA, TOICA)      
https://en.wikipedia.org/wiki/Suica
Octopus, MTR network from Hong Kong, 2014
    管理情報バイト: 80-4f-0c-a0-00-00-03-06-11-00-3b-00-00-00-00
確立したプロトコル: T1(ブロック転送モード)
IDm: **-**-**-**-**-**-**-**
PMm: 00-f1-00-00-00-01-43-00
ROM種別: 00
IC種別: f1
カード種別: FeliCa
カード名: FeliCa Lite
種別名: FeliCa
カードID: f2
```

# 感想
やったぜ
金がねえor金を払いたくねえ人向けの無料Copilot検討

# Github Copilotすごいよね
Github Copilotの長所
* 生産性が上がる!

**Github Copilotの欠点**
* **`10$/month(or 100$/year)かかる`**

僕如きの生産性をいくら向上させても10$/monthの元を取れる気がしないよー😢
ということで、無料で使えるやつがないか調査して、実際に試せるものは試して定量的に評価して表にしました。
評価基準はすごく適当なので正確なものではないですが、参考になればと思います。

extension一覧、それぞれの簡単な解説、評価結果の順に記載します。

# 2023/08/06時点でのCopilot系Extension一覧
網羅的ではありません。
vscodeのextensionの検索画面で"copilot"とか"AI"とかを入力して、出てきたものを上から見ていって探しました。

* Github  Copilot
* Fauxpilot
* Tabby
* AWS Toolkit(のCodeWhisperer)
* Tabnine
* Blackbox
* Codeium
* CodeGeeX
* EasyCode Copilot Chat

# 各Extension簡単解説
## Github Copilot
一番有名なやつですね、githubが持ってるサーバー上でモデルが動くのでよわよわPCでも大丈夫です。
現時点では、登録して30日間は無料なので、無料期間中に調査しました。
ちなみに学生は無料らしいです。
## Fauxpilot
localのPCのGPUでモデルを動かすので、NVIDIA GPUの入っていないPCだとそもそも動かないと思います。
GPUの最低要件は以下のようです。
* 2GB VRAM
* Compute Capability 6以上

選択できるモデルはいろいろあるのですが、今回の調査では私の持っているGPUの都合上、最低要件で動くSelesForce CodeGenモデルを選択しました。

## Tabby
こちらもlocalで動かす系のものです。cpuでも動かせるとのことだったのですが、私のPCではうまく動かなかったので調査を断念しました。

## AWS ToolkitのCodeWhisperer
AWS Toolkitという拡張機能に入っている機能です。
AWSのサーバー上でモデルを動かしてくれているっぽいので、よわよわPCでも使えます。
個人なら無料で使えます。

## Tabnine
無料版と有料版があり、無料版では単語ごとの補完機能しかないようです。有料版については、公式のPricingのページになぜか飛ぶことができなかったのでよくわかりません。
無料版はしょぼすぎるため今回は調査を割愛しました。

## Blackbox
chat機能もついてます。
chat機能は無料なんですが、コード補完機能は有料で`1$/month`かかります。しかも回数制限があって、無制限でコード補完したい場合、`2$/month`のPlanに加入しないといけないようです。
お金がかかるので割愛します。

## Codeium
アカウント登録が必要ですが、無料でコード補完機能が使えます。
chat機能もついていてお得感はあります。
どっかのサーバー上でモデルを動かしてくれるタイプです。

## CodeGeeX
Codeiumとだいたい同じです。

## EasyCode Copilot Chat
chat機能がメインそう。コード補完機能も実験的に公開しているようですが、登録しても動きませんでした。私が何か間違っている可能性もありますが、今回は調査を断念しました。

# 評価結果
## 結果
先に載せておきます。
| name| 複数候補表示| 補完切替| はやさ| 賢さ|挿入ミスなし|
|-|-|-|-|-|-|
| Github Copilot| T| T|5| 5|T
|Fauxpilot| F| F|5|2|F|
| AWS Codewhisperer| F| T|0|4|F
| Codeium|F| T|3|4|T
| CodeGeeX|T| F|1|0|T

## テスト方法
atcoderの適当な問題の回答コードをPythonで用意し、これを写経しながら各extensionを使用しました。
評価基準は以下5つです。
* 複数候補表示機能があるか
* 補完切替機能があるか
* 補完のはやさ
* 補完の賢さ
* 挿入ミス(バグ?)がないか
### 複数候補表示機能
Github CopilotのCtrl+Enter機能です。
複数の補完候補を同時に確認して選択することができる機能です。

### 補完切替機能
Github CopilotのAlt+],Alt+[機能です。
現在表示されている補完を別のものにできます。

### はやさの定義
特定のタイミングを5つ指定して、そのタイミングで補完がすぐに表示されるかどうかを見ました。
そのタイミングですぐ表示されたら、1点加点として、5点満点で評価しました。

### 賢さの定義
これもはやさ同様、特定の補完が正しく提示できるかを確認しました。5点満点です。

### 挿入ミス
一部のextensionでは、補完を行うと閉じ括弧が余ってしまう現象が発生しました。補完を確定して文章に挿入する処理がうまくいってないのだと思います。私の環境がおかしいだけかも...?

# まとめ
表を再掲
| name| 複数候補表示| 補完切替| はやさ| 賢さ|挿入ミスなし|
|-|-|-|-|-|-|
| Github Copilot| T| T|5| 5|T
|Fauxpilot| F| F|5|2|F|
| AWS Codewhisperer| F| T|0|4|F
| Codeium|F| T|3|4|T
| CodeGeeX|T| F|1|0|T

Github Copilotが強いことを改めて確認させられました。補完が優秀すぎて、ここは補完が出ないだろうと思っている箇所でも自分が書こうとしていた通りの補完が出てびびります。

Fauxpilotは私のGPU的に一番軽量なモデルしか使えなかったので、あまり賢くなかったです。賢くなくても、補完はかなりはやかったので是非使いたいんですが、挿入ミスが発生して閉じ括弧が無駄に生成されてしまうのが致命的です😢

AWSのは頭でっかちで遅すぎるので使えないです。挿入ミスも発生しました。

Codeiumは微妙に遅いんですが、他はまあまあいいので、Github Copilotの無料枠が切れたらこれを使おうかなと思います。

CodeGeeXは、遅すぎるし補完も的外れだったので残念です。

# 結論
**お金があるならGithub Copilot一択!**
**お金がないけど強いGPUを持っているならFauxpilotを試そう!**
**何にも持ってない人はCodeiumがおすすめ!**
【分かったつもりになるAWS】Kinesis 編


<font color="darkorange"> **各種ログ等のストリーミングデータ** </font>を処理するために設計されていて、データの収集・処理・分析を行うことができる。

AWSセミナー資料
https://www.slideshare.net/slideshow/embed_code/key/1FOYKqQGXtjjIh?startSlide=8



## Data Pipelineとの違い
Pipeline　は保存場所にあるデータに定期的にアクセスし、データの変換と処理を行い、その結果を Amazon S3、Amazon RDS、Amazon DynamoDB、Amazon EMRなどに転送する。そのため、リアルタイムで処理が求められるような要件には不向き



## Kinesis Stream / Kinesis Firehose の違い

Kinesis Streamsは次々と送られる大量のデータをリアルタイムに収集、次のサービスに配送するためのサービスです。一方Kinesis Firehoseは同じく次々と送られる大量のデータをRedShiftやS3に流し込むサービスです。 
ではこの2つのサービスは、どのような違いがあって、どう使い分けるべきなのか？


## Kinesis Streamsは「リアルタイム」「カスタム」

<img width="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3412108/360fd5a8-a69e-5e5e-9262-fc79b21d2110.png">




データを受け取ったあと、 <font color="darkorange">**何らかの処理**</font> をしてから保存するためのサービス。
Kinesis Streamsの最大の特徴は <font color="darkorange">**低レイテンシー**</font> であること。
Kinesis Firehose がデータロードまで60秒かかるのに対し Kinesis Streams は1秒以下でのデータロードで設計されている。 Kinesis Streams の主なユースケースとしては「次々に生成されるデータの内容をリアルタイムに加工、表示させたい」というニーズへの対応になる。
Lambda / EC2 等でStreamsレコードを取得してすぐに加工・表示できる


## Kinesis Firehoseは「Zero Administration」「ダイレクト」
<img width="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3412108/05ef38f0-9359-06d7-0736-434a35309493.png">

Kinesis Firehoseの特徴は `Zero Administration` =  <font color="darkorange">**管理不要**</font> という点。
Kinesis Streamsと違って、EC2からポーリングしたりLambdaのコードを書く必要がない。設定を行うだけでS3やRedshiftにデータをそのまま流すことが可能。 

Amazon Kinesis Data Firehose は、ストリーミングデータをデータレイクやデータストア、分析ツールへ簡単に送信する方法です。
ストリーミングデータをキャプチャして変換し、「Amazon S3」、「Amazon Redshift」、「Amazon Elasticsearch Service」、「Splunk」などへ送信し、お使いのビジネスインテリジェンスツールやダッシュボードでほぼリアルタイムに分析できます。
完全マネージド型サービスのため、データスループットに応じて自動的にスケールされますので、継続的な管理は不要です。
送信前にデータのバッチ処理、圧縮、変換、暗号化が行われるため、送信先でのストレージ量を最小化し、セキュリティを強化できます。Kinesis Data Firehose を使用すると、アプリケーションを記述したり、リソースを管理したりする必要はありません。
Kinesis Data Firehose にデータを送信するようデータプロデューサーを設定すると、指定した送信先にデータが自動的に配信されます。
AWS マネジメントコンソールから Firehose デリバリーストリームを簡単に作成して、設定すればわずか数分で大量のデータソースからストリームにデータ送信を開始して、AWS に継続的に送信できます。
Kinesis Data Firehose を利用した場合、使用した分のみの料金が発生いたします。最低料金や初期費用は必要ありません。


## ユースケース
WEBサーバーのアクセスログやアプリケーションログをリアルタイムで収集し解析(監視)する。

- Kinesis Data Firehoseストリームを作成して、データストリームを取得
- Kinesis Data Firehose でデータストリームをS3バケットに保存
- 必要に応じて利用頻度の低いデータを Glacier に移動するライフタイムサイクルを設定


Kinesis でログデータを監視、特定条件を満たした場合 `CloudWatch Events` をトリガーとして Lambda 実行・SESメール通知など
【分かったつもりになるAWS】CloudWatch Events編


<font color="darkorange">**AWSのリソースやサービスで発生するイベント** </font>をリアルタイム で監視し、それらのイベントに対してアクションを実行するためのサービス。アクションには、AWS Lambdaを含むさまざまなAWSサービスが利用できる。

とくに CloudWatch + Lambda の組み合わせは利便性が高い。
AWSサービスのほとんどがCloudWatch Eventsをサポートしており、Lambda関数で独自の処理を組み込めるため様々な用途に利用できる。
「AppSyncってなんだ？」を解消しよう

# はじめに
開発で既に AppSync が使用されており、「AppSyncってなんだ？」となったので、そもそものリソース自体を調べたのを以下にまとめました。

## 本記事の対象者
:::note info
- AppSync を初めて知る方
- 実装ではなく、リソース自体を知りたい方
:::

# Appsync とは
AWS AppSyncは、AWS によって開発された**フルマネージドサーバーレスの GraphQL サービス**です。サーバーレスの GraphQL API を作成し、単一のエンドポイントを通じて安全にデータの照会、更新、公開を行うことができます。

クライアント側は単一の GraphQL エンドポイントから複数のデータベース、マイクロサービス、およびAPIにクエリを実行できます。

![スクリーンショット 2023-08-06 20.45.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2849898/7a1f3dd1-84e7-b586-d64e-8e26a8a0ccdb.png)

https://aws.amazon.com/jp/appsync/

ここで、GraphQL が出てきて、GraphQL もわからないので、調べました。

## GraphQL とは
GraphQLは、**APIクエリ言語とサーバーサイドのランタイム**の両方を指します。単一のエンドポイントを用意して、そこにクエリを投げ込むことで操作を行います。

https://graphql.org/

クライアント側でクエリを単一のエンドポイントに投げて、AppSync側でスキーマを定義して、定義された各リクエストタイプにリゾルバー（リクエスト先の情報）をアタッチすることができます。

以下は、簡単なクエリ（リクエスト）になります。

```graphql
query {
   users {
     name
   }
 }
```

個人的には、以下のメリットがあると思いました。

:::note info
- 単一のエンドポイントのため、複数のAPI呼び出しをまとめられる
- スキーマで型定義できているため、クライアントとサーバー間の食い違いが発生するリスクが少なくなる
:::

## Amazon Aurora Serverless と DynamoDB との接続
Appsync は、`Amazon Aurora Serverless` と `DynamoDB` なら、直接連携することができます。ここでいう直接連携とは、中間サービス（Lambdaなど）を使用せず、連携できるという意味になります。リゾルバの設定は必要になります。

もしRDSと連携したいのならば、`Lambda` をリゾルバとして使用し、連携する必要があります。

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Introduction.html

### DynamoDBを使用している場合
> フルマネージド NoSQL データベースサービスであり、シームレスなスケーラビリティを備えた高速で予測可能なパフォーマンスを提供します。

AWS公式には、上記にように記載がありました。
そのため、パフォーマンス観点でいうと、DynamoDBを使用する方がよさそうです。

普段RDSを使用している構築の場合は、Lambda等を利用して、DynamoDBにコピーするなどすれば良いかと思います。

## 料金体系（2023/08時点）
AppSync では**使用した分に対してのみ支払いが発生**します。主に以下3つに料金が発生します。

- クエリとデータ変更操作
- リアルタイム更新
- キャッシュ

具体的な料金は公式サイトをご確認ください。

https://aws.amazon.com/jp/appsync/pricing/

# 最後に
AppSyncを知るために、GraphQLやDynamoDBも知る必要があり、幅広くいろんな知識を入れることができてよかったです。次は実装をメインに調査をしてみようと思います。

最後までご覧いただき、ありがとうございました。

# 参考文献
- https://www.ragate.co.jp/blog/articles/12064
- https://kinsta.com/jp/blog/graphql-vs-rest/
- https://www.redhat.com/ja/topics/api/what-is-graphql
- https://blog.serverworks.co.jp/appsync-direct-lambda-resolvers
【YAML】複数行で記述する方法


## 空白で連結
```sample.yml
test: >
  aaa
  bbb
  ccc

# "aaa bbb ccc\n"
```

最後の改行を削除

```sample.yml
test: >-
  aaa
  bbb
  ccc

# "aaa bbb ccc"
```

## 改行で連結
```sample.yml
test: |-
  aaa
  bbb
  ccc

# "aaa\nbbb\nccc"
```
[Python / ReID] pytorch_Realtime_Multi-Person_Pose_Estimation を docker-compose でサクッと動かせるようにした

以下の GitHub Repository の `Demo > Easy demo` の通り。

https://github.com/siruku6/pytorch_Realtime_Multi-Person_Pose_Estimation/tree/trial#easy-demo


# 手順

より細かい手順を記載しておきます。

## 1. modelファイルのダウンロード

以下のdropboxのURLから、modelファイルを保持しておきます

https://www.dropbox.com/s/ae071mfm2qoyc8v/pose_model.pth?dl=0


## 2. コマンド実行

```bash
# repository の準備
$ git clone https://github.com/siruku6/pytorch_Realtime_Multi-Person_Pose_Estimation.git
$ cd pytorch_Realtime_Multi-Person_Pose_Estimation
$ git checkout -b trial
$ git pull origin trial
```

[1.]でダウンロードした model ファイルは、`models`ディレクトリの中に格納する必要があります。
ここまでできたら、ソースコードを実行するのみです！

```bash
# docker を利用したデモの実行
$ cd docker/demo
$ docker compose build
$ docker compose up
```

これを実行することで、CPU上であっても `demo` が実行でき、 `result.png` が生成される。

# 注意点

マシン性能やネットワークの通信速度によっては、 Dockerfile 内の requirements.txt に対する pip インストールの際にタイムアウトする。（私はした）₍₍ (ง ˘ω˘ )ว ⁾⁾ｽﾔｯｽﾔｯ
AWS Certified Solutions Architect Associateの認定を取ることができました！

AWS SAAを受験するにあたり、どのくらいの期間、どのように勉強していたか、受験当日についてのことをここに記したいと思います。

・学習期間
勉強には2週間かけました。
前提として、IT未経験、SAAを受ける前にAWS CLF(クラウドプラクティショナー）を約1ヶ月かけて勉強し、受かりました。
受かった次の日にSAAの試験を予約してそこからSAAに向けての勉強をスタートしたという感じです。
バイトがある日は1日1時間、休日は3、4時間程度勉強する時間を確保していました。

・学習方法
Webにあった無料の問題集、Udemyの問題集、AWS公式サイトのホワイトペーパー、AWS Skill Builderなどを活用して勉強していました。
問題集は一旦、CLFの知識で解きましたが3、4割ぐらいしか取れなかったです。
そこから逆算して自分には何が足りていないのかを明確にして知識を入れましたね。
また、IT用語など、あまり馴染みのない言葉が多かったので適宜ググって意味などを調べるようにしていました。
正直、CLFと比べると1問あたりの文章量が問題文と選択肢ともに多い上、単にサービスの名前を答えるのではなく、問題に対して最もベストプラクティスな回答を選ぶというのがSAAの特徴だったので、どのサービスとどのサービスで構成したら一番コスパ良いか、みたいな問題が多かったような気がします。

・受験当日
CLFを受験した時と同じ会場だったので特段変わったことはなかったかなという感じです。
試験自体、自分にとって結構難しかったです。
確かに、問題集と似たようなものもありましたが半数以上は解いたことがないものばかりでした。
また、問題文と選択肢は日本語と英語で切り替えることができるので日本語でわかりにくい文章だったら英語にすることで明確になる場合もありました。

・結果
![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513801/1ab753fe-b14e-5727-4a6b-d2804670e414.png)
無事合格することができました。

しかし、スコアレポートを見てみると…
![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513801/5d5029ff-c887-887f-3709-71a512e5fd08.png)

完全に合格とは言えないレベルですね。スコアもSAAの合格点が720点なのですが、実際の自分の得点は724点というスレスレで受かったので、まだまだです。
2週間では少し厳しかったのかなという印象だったので、今後また別の認定を受けるときは少なくとも3週間は学習期間を確保すべきだと思いました。

もしこの記事を見てくださっている方は参考程度にしていただければ幸いです。

以上、AWS SAA受験の事後報告でした。
[SwiftUI] デフォルトでfocusが当てられたTextFieldにするために頑張った

# はじめに
SwiftUIにはTextFieldというテキストを入力するためのViewがデフォルトで準備されているのですが、viewをロードした段階ですでにTextFieldにフォーカスが当てられているような方法が見つからなかったので、今回はその実装をしてみました。

# したいこと
下の画像のように、viewが読み込まれた時にデフォルトでTextFieldにフォーカスが当てられているようにしました。

また、本記事では説明しませんが、今回はクロスワードアプリを作っていたので、文字入力がされると、次のブロックへ移動して新たなTextFieldにフォーカスが当たるようにしました。

![スクリーンショット 2023-08-06 23.20.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1193085/ab9cd562-3442-8f55-a999-46752e6b3d54.png)

![スクリーンショット 2023-08-06 23.20.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1193085/063e53e5-1197-56c7-aff2-ced79abd8b8d.png)


# 実装

``` swift
import SwiftUI

struct FocusableTextField: UIViewRepresentable {
    
    class Corrdinator: NSObject, UITextFieldDelegate {
        
        @Binding var text: String
        var didBecomeFirstResponder = false
        
        init(text: Binding<String>) {
            _text = text
        }
        
        func textFieldDidChangeSelection(_ textField: UITextField) {
            text = textField.text ?? ""
        }
    }
    
    @Binding var text: String
    var isFirstResponder: Bool = false
    
    func makeUIView(context: UIViewRepresentableContext<FocusableTextField>) -> UITextField {
        let textField = UITextField(frame: .zero)
        textField.delegate = context.coordinator
        return textField
    }
    
    func makeCoordinator() -> FocusableTextField.Corrdinator {
        return Coordinator(text: $text)
    }
    
    func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<FocusableTextField>) {
        uiView.text = text
        if isFirstResponder && !context.coordinator.didBecomeFirstResponder {
            uiView.becomeFirstResponder()
            context.coordinator.didBecomeFirstResponder = true
        }
    }
}
```

上の処理の流れとしては以下の感じです。
- FocusableTextFieldというUIViewRepresentableプロトコルを継承したstructを作成します。このUIViewRepresentableというのはSwift UIとUIKitの橋渡しを行なってくれます。
- makeUIViewというメソッドで新しいUITextFieldを生成し。UITextFieldDelegateをCoordinatorに割り当てることでテキストフィールドの状態を監視しています。
- updateUIViewでフォーカスの処理を行っています。ここではisFirstResponderやdidBecomeFirstResponderの状態を監視して、必要に応じてuiView.becomeFirstResponder()を呼び出します。ここで使用しているbecomeFirstResponder()はUILitのメソッドで、呼び出されるとそのviewが一番はじめに入力操作を受け付けるようになるため、今回したかったことが実現されます。

# 最後に

色々調べてみても、フォーカスの検知などの記事しか見つからなかったため、今回は自作でデフォルトでフォーカスが当てられるTextFieldの実装を行なってみました。もしSwift UIでそのようなViewがデフォルトで用意されていたり、良い方法をご存知の方いれば教えていただけると幸いです。
ではここまで読んでくれてありがとうございました^^

# 参考文献
https://developer.apple.com/documentation/swiftui/uiviewrepresentable/
【Vue.js】「6万5千円」「6.5万円」の通貨形式をhelper.tsでフォーマットする方法

# 概要
Vue.jsのヘルパー関数（`helpers.ts`）で「●●万▲▲千円」という表示方法と「●.▲万円」という表示方法を実装しました。
例：6万5千円 → 6.5万円　

# サンプルコード

`helper.ts`とは、Vue.js アプリケーション内で共通のユーティリティ関数やヘルパーメソッドを定義するための TypeScript ファイル。以下のように定義しておくことで、Vue コンポーネント内で効率的に使用できます。

## 「●●万▲▲千円」の表示方法

```ts
export function formatMoney(value: number): string {
    const man = Math.floor(value / 10000);
    const sen = Math.floor((value % 10000) / 1000);
    return `${man}<span class="text-money">万</span>${sen ? sen + '<span class="text-money">千</span>' : ''}<span class="text-money">円</span>`;
```

- `Math`：数学的な演算や関数を提供するJavaScriptの組み込みオブジェクト。
    - `Math.floor()`メソッドは、小数点以下を切り捨てて整数に変換するために使用
- `man`：`value`を`10000`で割った商（万単位の部分）を計算
- `sen`：`value`を`10000`で割った余りを`1000`で割った商（千単位の部分）を計算
- テンプレート文字列：バッククォートで囲まれており、変数や式を埋め込むことができる

## 「●.▲万円」の表示方法

```ts
export function formatMoney(value: number): string {
    const money = value / 10000;
    const man = Number(money.toFixed(2));
    return `${man}<span class="text-money">万円</span>`;
```

- `money`変数：与えられた`value`を`10000`で割った結果を代入
- `Number(money.toFixed(2));`：小数点以下2桁まで丸めて、数値に変換

## 以下で実行してみると...

上記JavaScriptのコードをコマンドライン上で直接実行すると以下のようになります。

```js
function formatMoney1(value) {
    const man = Math.floor(value / 10000);
    const sen = Math.floor((value % 10000) / 1000);
    return `${man}万${sen ? sen + '千' : ''}円`;
}

function formatMoney2(value) {
    const money = value / 10000;
    const man = Number(money.toFixed(2));
    return `${man}万円`;
}

const value = 65000;
const result1 = formatMoney1(value);
const result2 = formatMoney2(value);

console.log(result1);
console.log(result2);

// 6万5千円
// 6.5万円 
```

二つの異なる表示方法が出力されたことが確認できました。
【UE5】自作のCharacterとPlayerControllerを連結する

今回は時間が無いため画像はあとで貼ります

◯テーマ
この２つを連結させたい
自作の「Characterを継承したBP」
自作の「PlayerControllerを継承したBP」

◯前提条件
・WorldSettingsでのDefaultPawnClassをNoneにしたい
　→「自作のGameModeにて二人分の自作Character」を管理したいから
・自作したPlayerControllerはWorldSettingsでセット
![スクリーンショット 2023-08-06 231652.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/b8577abe-cfcb-0c90-4aa7-c312f0a23262.png)


◯問題点
・自作のCharacterは「AddInputMovement」では動かない
・GetControllerでもNullが返却される

![スクリーンショット 2023-08-06 234336.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/2f93010f-0b52-e2eb-93b4-aa1dc40fe7a2.png)




◯解決策
自作のCharacter　→　Pawn　→　Auto　Possess　Player　→　Player０に変更すること

![スクリーンショット 2023-08-06 231652.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/a6f9dbff-5634-5b67-33fd-d5b72f437d7d.png)

おそらく、WorldSettingsで設定されている自作のPlayerControllerを自動的に結びつけてくれるみたい
Player1では反応はなし
fiber.Ctxで返される値が変化してしまう問題を試す

まずは、公式ドキュメントの[Zero Allocation](https://docs.gofiber.io/#zero-allocation)の項目を読む。

ここに記載されている内容(発生原因と解決策)は、公式ドキュメントで書いてある内容を、再度書いているようなもの。公式ドキュメントを読んだのであれば、実際に値が変わる様子を見たい人のみ、以下を読む。

## fiber.Ctxで返される値が変化してしまう問題とは
`fiber.Ctx`は、デフォルトでは、not immutableな値を返す。それをハンドラ外で保持するしており、複数のリクエストを受けた場合、値が書き変わってしまう可能性がある。
そのため、`fiber.Ctx`から得られる、params(`ctx.Params(key)`)などは、ハンドラ外で使用する場合、注意して使用する必要がある。

## 問題の挙動を見てみる
```golang
func main() {
	addr := "localhost:3000"
	go server(addr)
	time.Sleep(3 * time.Second) // サーバ起動の待ち
	client(addr)
	time.Sleep(5 * time.Second) // wait関数の待ち
}

func client(addr string) {
	eg := errgroup.Group{}
	for i := 0; i < 10; i++ {
		i := i
		eg.Go(func() error {
			u := fmt.Sprintf("http://%s/users/%d", addr, i)
			_, err := http.Get(u)
			return err
		})
	}
	_ = eg.Wait()
}

func server(addr string) {
	app := fiber.New()
	app.Get("/users/:id", func(c *fiber.Ctx) error {
		go wait(c.Params("id"))
		return c.SendString("OK")
	})
	app.Listen(addr)
}

func wait(text string) {
	time.Sleep(2 * time.Second)
	fmt.Println(text)
}
```
#### 結果

```text
3
5
6
9
7
0
4
1
1
0
```

**0が2つ、1が2つ出力されてしまっている**

#### 原因
公式ドキュメントで説明されている通り、fiberのCtxから返される値は、[not immutable](https://docs.gofiber.io/#zero-allocation)である。

そのため、ハンドラ外で値を使用していると、途中で変化してしまう可能性がある。
今回だと、`go wait(c.Params("id"))`。

#### もう少し調べる
`CopyString()`を利用して調べる。

`CopyString()`を初めて見ると言う人は、この記事の冒頭で言っているのにも関わらず、[公式ドキュメント](https://docs.gofiber.io/#zero-allocation)を読んでいない人だと思うので、公式ドキュメントを読むことを勧めます。

```golang
// ハンドラ内のwait関数実行を以下に書き換える
go wait(utils.CopyString(c.Params("id")), c.Params("id"))

// wait関数を書き換える
func wait(a, text string) {
	b := utils.CopyString(a)
	time.Sleep(2 * time.Second)
	fmt.Printf("%s, %s -> %s\n", a, b, text)
}
```
出力結果
```text
// ハンドラ内でCopy、wait関数内でCopy -> wait関数の引数
2, 2 -> 2
5, 5 -> 5
8, 8 -> 5
4, 4 -> 5
3, 3 -> 3
9, 9 -> 9
7, 7 -> 7
1, 1 -> 1
0, 0 -> 1
6, 6 -> 6
```

これからわかるように、`utils.CopyString()`でコピーした値は、1度しか出力されていないが、`c.Params()`で得られた値は、重複している。また、wait関数内でも途中で変更されている。例えば、`8, 8 -> 5`

## 最後に
公式ドキュメントをよく読むこと。そして遊ぶこと。

もちろん、ハンドラ内で値が閉じている場合は、Ctxから得られて値を使用すればいい。今回だと、`go wait(c.Params("id"))`となっているが、`wait(c.Params("id"))`と、なっていれば、ハンドラ内で実行されているので、問題はない。
Spring SecurityとopenLDAPの連携方法（Spring Boot）

## バージョン
Spring Boot:3.1.1

ネットの記事通りにソースコードをコピーしても



spring boot でアプリを作り
spring securityでログイン認証
ユーザ格納をopenLDAP

## openLDAPは以下のサイトを参考に構築

https://www.server-world.info/query?os=CentOS_7&p=openldap&f=1

demoプロジェクト
src/main/java
com.example.demo


## spring bootのコード

AuthenticatingLdapApplication.java
```
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class AuthenticatingLdapApplication {
	
	 public static void main(String[] args) {
		    SpringApplication.run(AuthenticatingLdapApplication.class, args);
		  }

}
```

HomeController.java

```
package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HomeController {
	
	@GetMapping("/")
	  public String index() {
	    return "Welcome to the home page!";
	  }

}

```


```
package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.password.LdapShaPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;



@Configuration
public class WebSecurityConfig {

  @Bean
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
      http
      .authorizeRequests()
      .requestMatchers("/**").authenticated() // 全てのパスに対して「認証済み」を要求するアクセスポリシーを設定する
      .and()
      .logout().permitAll() // ログアウト機能を有効化
      .and()
      .formLogin().permitAll(); // フォームログイン機能を有効化
      
      return http.build();  
}

  @Autowired
  public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
      .ldapAuthentication()
        .userDnPatterns("uid={0},ou=people")
        .groupSearchBase("ou=group")
        .contextSource()
          .url("ldap://192.168.2.220:389/dc=srv,dc=world")
          .managerDn("cn=manager,dc=srv,dc=world") 
          .managerPassword("Zaq12wsx@1")
          .and()
        .passwordCompare()
          .passwordEncoder(new LdapShaPasswordEncoder())
          .passwordAttribute("userPassword");
  }

}

```