OmniAICreator/Qiita-1.07M huggingface dataset:
Webとは何か



ここではwebとは何かについて書いていきます。

webアプリを作成した経験がある人でも、「webとは何か？」と聞かれると答えに詰まる人もいるのではないでしょうか。


# webとは

webとは、ブラウザを通して文書などを閲覧するシステムのことです。

Chromeなどのウェブブラウザ（クライアント）からウェブサーバへ要求を投げ、受け取った情報をブラウザが表示して閲覧します。


webの仕組みの根幹は、URI、HTTP、HTMLです。

つまり、webでやることは「**URIにHTTPでリクエストし、HTMLなどを受け取ること**です。」
やりとりするのはブラウザとウェブサーバです。

自作したブラウザからでもHTTPでリクエストをすれば世界中のサーバとやりとりができるということですね。


# webの２つの側面


情報システムとして見ると、webはハイパーメディアシステムと分散システムという２つの側面をもってます。

## ハイパーメディアシステム

URIを指定することによって、自由にページ（テキストや画像や動画や音声などを含んだ情報）を行ったり来たりすることができます。

Web上に存在する各リソースはその他のリソースへのURIをもっています。
（リソースというのは、URIを指定すると返されるHTMLなどのことです。URIはリソースの名前ということになります。）

このことから見ると、Webは「それぞれのリソースに他のリソースへのリンクが埋め込まれたハイパーメディアシステム」であるといえます。


## 分散システム

複数のコンピュータを組み合わせて処理を分散させるしくみを分散システムといいます。

webは、世界中のサーバに世界中のブラウザがアクセスする分散システムです。



# まとめ


webは、ブラウザを通して文書などを閲覧するシステムで、ブラウザがURIにHTTPでリクエストし、サーバから返されたHTMLを表示することで成り立っています。
応用情報技術者試験合格体験記(開発者向け勉強法)

# はじめに
この記事では、しっかり受かるための応用情報技術者試験合格方法をお伝えします。
新米PM、アーキテクトなどサービスやシステム全体に対して、業務している方にはおすすめの資格です。
<img width="50%"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286023/573ddf65-0a8c-c288-7832-c757a82d65f3.png">

## 応用情報技術者試験とは
### 概要
https://www.jitec.ipa.go.jp/1_11seido/ap.html
> 高度IT人材となるために必要な応用的知識・技能をもち、高度IT人材としての方向性を確立した者

まさに、PM・アーキテクトにオススメです。
試験価格も**7,500円**と安いのが特徴です。

### 試験時間・形式
||午前|午後|
|-|-|-|
|試験時間|9:30～12:00(150分)|13:00～15:30(150分)|
|出題形式|多肢選択式（四肢択一）|記述式|
|出題数|80|11|
|解答数|80|5 ※情報セキュリティは必答、他４問選択|

午前午後どちらも60点以上で合格です。
※午前が60点未満の場合、午後試験は採点されません。

### 合格率
|開催期|応募者数|受験者数|受験率|合格者数|合格率|
|-|-|-|-|-|-|
|R4秋期|54,673人|36,329人|66.4%|9,516人|26.2%|

毎年20パーセントほどを推移しています。
(応募しても、受けない人が18,000人もいるのは驚きです。)


## 勉強方法
### 使用教材(7000円ほど)
1. [キタミ式イラストIT塾 応用情報技術者 令和04年(3600円)](https://www.amazon.co.jp/dp/429712453X)<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286023/9b8437d7-0a6a-0c15-260d-e030e0a5727c.png">

2. [2022 応用情報技術者 午後問題の重点対策 (重点対策シリーズ)(3700円)](https://www.amazon.co.jp/dp/486575251X)<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286023/d8e6aca9-276f-b4c6-8c43-b717d957d14d.png">

3.
https://www.ap-siken.com/apkakomon.php

無料です。
### 期間・時間
- 期間
    - 1カ月半ほどです。
    - 9月頭から勉強を始めて、10月9日の試験で合格しました。
- 時間
    - 100時間ほどです。
        - 午前：50時間
        - 午後：45時間 


### 具体的な勉強方法
午前も午後も60%取れれば合格なので、難解な問題に足を止めすぎないで勉強しましょう。
#### 勉強方法概要
- 午前試験
    - キタミ式(30時間)→応用情報技術者試験過去問道場(午前)(20時間)
- 午後試験
    - 午後問題の重点対策(25時間)→応用情報技術者試験過去問道場(午後)(20時間)
#### 午前試験
##### キタミ式
- 目的
    - 応用情報試験で問われる知識のインデックスを貼ること。
- 方針
    - とにかくページ数が多い(900ページ)ので、暗記などはせず、できるだけ早く読み切る。
- やり方
    - 1周目
        - 1日3章をノルマとして、7日で1周目を読み切る。
    - 2周目
        - 章末の過去問を解く→該当の説明を読む
    - 3周目
        - 2周目で解けなかった解説を読む
##### 過去問道場
- 目的
    - 本番の感覚を掴み、苦手分野を潰すこと
- 方針
    - やれるだけやる。午後問題のリフレッシュにやる。
- 方法
    - 過去問道場にアカウントを作成し、記録をつけながら、空き時間に勉強
        - 私は8回分を90%以上解ける状態まで仕上げてました。
        <img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2286023/d0aa8e62-3a08-c61b-ba81-a29a9bab2900.png">
#### 午後試験
##### 問題選定
1. 情報セキュリティ(必答)
1. 経営戦略
1. プログラミング
1. システムアーキテクチャ
1. ネットワーク
1. データベース
1. 組込みシステム開発
1. 情報システム開発
1. プロジェクトマネジメント
1. サービスマネジメント
1. システム監査

上記から5問を選ぶ必要があります。
開発者・アーキテクトの方は、3, 4, 5, 6, 8から4問を勉強しておいて、
難問だった場合に7を解くという方法をおすすめします。
組み込みシステム開発は、一問解いてみるとわかりますが、
特に技術的な知識を必要としないため、保険の問題としてとっておくのがおすすめです！

##### 午後問題の重点対策
- 目的
    - 午後問題に慣れ、自分なりの回答方針を立てる
- 方法
    - 大問ごとに5,6問過去問が載っているので、解き切る
##### 応用情報技術者試験過去問道場(午後)
- 目的
    - 重点対策で自信がない分野を補填する
- 方法
    - 苦手分野の最新問題から順に納得するまで解く
        - 私はデータベースとネットワークを重点対策に加えて3年分解きました。

## 最後に
記述試験のため、結果までの2カ月半の間とても不安でした。
(選択問題のマークできていたかな？など)
余談ですが、私の自己採点の感覚ですが、記述問題に関しては、部分点がありそうです。
皆様が、無事受かるように応援しております。
Lambdaから直接Parameter Storeの値を取得する

今まではboto3を使ってParameter Storeから値を取得していました。
```python
import boto3

ssm = boto3.client('ssm')
response = ssm.get_parameters(
    Names=[Parameter Store Key],
    WithDecryption=True
)
```
が、以下のアップデートにより、直接Parameter Storeなどから値を取得できるようになったので、実際に試してみた際のメモです。

https://aws.amazon.com/jp/about-aws/whats-new/2022/10/aws-parameters-secrets-lambda-extension/

# 必要な権限
SDKを使って実装していたときと同様に、Lambdaの実行ロールに以下の権限を渡す必要がある。
* `ssm:GetParameter`
* `kms:DecryptSecureString` (SecureStringを取得する場合に必要)

# 必要なレイヤーの追加
## AWSレイヤー
Paramter StoreやSecrets Managerから値を取得するためのレイヤーがAWSから提供されているので追加する。

`レイヤーの追加` → `AWS レイヤー` → `AWS-Parameters-and-Secrets-Lambda-Extension`　の順に操作し、レイヤーを選択・追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157652/ab94bad2-c069-1342-59d8-c4bd7e122df7.png)

## カスタムレイヤー
後述するが、今回の手法でParameter Storeから値を取得する場合、ローカルホストに対して以下のようなHTTPリクエストを投げる。
```python
parameter_url = ('http://localhost:' + port + '/systemsmanager/parameters/get/?name=' + ssm_parameter_path)
```
本記事では`Requests`モジュールを利用するため、必要であれば以下のように事前に`Requests`モジュールをレイヤー化して登録しておく。
```shell
$ mkdir python/ 
$ cd python
$ pip install -t ./ requests
$ cd ..
$ zip -r Layer.zip python/
```

### 補足: 標準ライブラリのrequestの利用
LambdaでHTTPリクエストを行う場合 `urllib.request` であれば標準で用意されているので、多少コードが長くなっても問題ない場合はレイヤーを作成しなくても良いかも。
```python
import urllib.request
```

# Lambdaから値を取得するサンプルコード
必要な権限・レイヤーを追加したあとは、Lambda関数内で特定のエンドポイントへHTTPリクエストを行うような処理を実装すれば良い。
```python
import os
import requests

# デフォルトのポートは2773 (変更可能)
endpoint = 'http://localhost:2773/systemsmanager/parameters/get/?name={}'.format('Parameter Storeに登録してあるKey名')
# GETリクエストを行うために必要なトークンの情報
headers = {
    'X-Aws-Parameters-Secrets-Token': os.environ['AWS_SESSION_TOKEN']
}
res = requests.get(endpoint, headers=headers)
```
上記を実行することでParameter Storeに対するリクエストが可能。
ちなみにレスポンスの中から値のみを取得したい場合は以下のようにすればOK。
```python
value = res.json()['Parameter']['Value']
```

# 利用できる環境変数
環境変数を設定することでポートやTTLの変更などの細かい設定を行うことができる。

https://docs.aws.amazon.com/systems-manager/latest/userguide/ps-integration-lambda-extensions.html

# まとめ
本機能を使うことで、Lambdaで直接値を取得できるだけでなく、AWS側でキャッシュしてくれます。自前でのキャッシュ実装が不要になるだけでなく、レイテンシー改善およびコスト削減を行うこともできるため、積極的に利用してくと良いかもしれないです。
コピペで使えるVueの検索フォームコンポーネント

# こういうの
![](https://storage.googleapis.com/zenn-user-upload/fed0f67f2d3a-20220919.png)

## 前提
- Vue3
- Bootstrap5

# コード

```vue
<template>
  <div class="form">
    <i class="fa fa-search"></i>
    <input type="text" class="form-control form-input" placeholder="キーワードを入力...">
  </div>
</template>

<style scoped>
.form {
  position: relative;
}

.form .fa-search {
  position: absolute;
  top: 20px;
  left: 20px;
  color: #9ca3af;

}

.left-pan {
  padding-left: 7px;
}

.left-pan i {
  padding-left: 10px;
}

.form-input {
  height: 55px;
  text-indent: 33px;
  border-radius: 10px;
}

.form-input:focus {
  box-shadow: none;
  border: none;
}
</style>
```
新しい年は、OKR(Objectives Key Results)でチャレンジ

OKRとは？ 【Googleが使う目標管理ツール】
---

__O：Objectives__
チームのモチベーションを高めるような挑戦しがいのある目標

__KR：Key Results__
進捗を図るための具体的指標

__OKR導入の効果:エンゲージメント向上、迅速な展開__
毎週それぞれどんなことを達成したのか、OKRの進捗状況を可視化し、情報を共有する

__OKRとは？__
以前、元Googleの人事担当とお話した際に、
学んだ内容の主なものをピックアップしました。

・部下や上司が成功(失敗)すれば、自分も成功(失敗)するという視点を持つ

・自分のためにも、上司や、部下が成功できるようにマネジメントする

・OKRを実現するためにはどうすればいいのか、一人で考えない

・OKRを相互に共有する
__「コラボレーター（協力者）」や「コントリビューター（貢献者）」を設定し、OKRを少しづつ変える__

・チームメンバーとCompassion（思いやり）を持って対話する
__「何か困っていることがあれば、手伝ってあげたい」と働きかける姿勢で、業務に取り組む__

例：Googleの厳しさを表現している言葉
「よく、部下に対して「あいつは仕事ができないから」と嘆く上司もいますが、Googleではそれはつまり「自分は仕事ができない」と表明しているようなもの」

・OKRは、継続して更新する〔毎週〕

・チームメンバーと課題を共有する
__「信頼と尊重の関係性」、「心理的安全性」を構築し、OKRを達成し続ける__
FlutterでFirebaseのTwitterログインを使う方法

# twitter_loginパッケージの使用
twitter_loginパッケージを使うことで簡単にTwitterログイン機能を実装できます。
https://pub.dev/packages/twitter_login

## APIKeyの外だし
APIKeyなどは間違ってリモートリポジトリへPushしないよう外部定義しておきましょう。
```dart:config.dart
class Config {
  static final apikey_twitter = 'fugagagagagaga';
  static final secretkey_twitter =　'hogegegegegege';
}
```

```dart:twitter_auth.dart
  Future _signInWithTwitter() async {
    final twitterLogin = TwitterLogin(
      apiKey: Config.apikey_twitter,
      apiSecretKey: Config.secretkey_twitter,
      redirectURI: 'socialauth://',
    );
    ・
    ・
    ・
```

## Twitter developerの設定
Twitter developerに登録しているアプリのApp InfoにリダイレクトURLとして[socialauth://]を設定します
![](https://storage.googleapis.com/zenn-user-upload/6f84d1d9cceb-20221224.png)

## iOS AppでTwitterログインを使えるようにする設定
以下にあるファイルに
/AppName/ios/Runner/Info.plist

次のコードを追記
```:Info.plist
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleTypeRole</key>
    <string>Editor</string>
    <key>CFBundleURLName</key>
    <string></string>
    <key>CFBundleURLSchemes</key>
    <array>
      <!-- Registered Callback URLs in TwitterApp -->
      <string>socialauth</string>
    </array>
  </dict>
</array>
```

# TiwtterAPIのバージョン差異による落とし穴
FlutterでFirebaseのTwitterログインを実装するには、いくつかポイントを抑えておく必要があります。
具体的には、twitter_loginというパッケージはTwitterAPI V2で実装されているのにFirebaseのTwitterAuthProviderはV1にしか対応していないため、Twitter DeveloperアカウントをElevatedに変更する必要があります。


# ソースコード
**機能**
```dart:twitter_auth.dart
// Twitterログイン
  Future _signInWithTwitter() async {
    final twitterLogin = TwitterLogin(
      apiKey: Config.apikey_twitter,
      apiSecretKey: Config.secretkey_twitter,
      redirectURI: 'socialauth://',
    );

    final authResult = await twitterLogin.loginV2(); //login()ではなくloginV2()
    switch (authResult.status) {
      case TwitterLoginStatus.loggedIn:
        // success
        print('====== Login success ======');
        final credential = TwitterAuthProvider.credential(
          accessToken: authResult.authToken!,
          secret: authResult.authTokenSecret!,
        );
        await FirebaseAuth.instance.signInWithCredential(credential);
        break;
      case TwitterLoginStatus.cancelledByUser:
        // cancel
        print('====== Login cancel ======');
        break;
      case TwitterLoginStatus.error:
      case null:
        // error
        print('====== Login error ======');
        break;
    }
  }
```

**ボタンウィジェット**
```dart:twitter_auth.dart
ElevatedButton(
                child: const Text('Twitter'),
                style: ElevatedButton.styleFrom(
                  primary: Colors.blue,
                  onPrimary: Colors.white,
                  shape: const StadiumBorder(),
                ),
                onPressed: () async {
                  await _signInWithTwitter();
                },
              ),
```
[Laravel]Object of type App\UseCases\Admin\Authority\MakeAuthorityGroupsUseCase is not callable の解決例

## 何をしたらでた？
app/Console/Commands/MakeAuthority.php(batchファイル)でapp/UseCase/Admin/Authority/MakeAuthorityGroupsUseCase.phpのファイルを呼び出そうとしたらエラーが出ました。

## 原因
batchファイルのhandle関数の引数でMakeAuthorityGroupsUseCaseクラスの型指定をした変数を持たせたことで、invoke関数を呼び出さずそのままinvoke関数を使えると勘違いしてしまいました。

## 解決方法
MakeAuthorityGroupsUseCaseクラスの型指定をした変数→invoke();の形にして明示的に呼び出すようにすることで解決できました。

## 間違ってしまっていたソースコード

```:app/Console/Commands/MakeAuthority.php
＝＝＝＝＝==前略＝＝＝＝＝==
use app/UseCase/Admin/Authority/MakeAuthorityGroupsUseCase
＝＝＝＝＝==中略＝＝＝＝＝==
    public function handle(MakeAuthorityGroupsUseCase $makeAuthorityGroupsUseCase)
　　　　　 {
        $makeAuthorityGroupsUseCase(); // ← $makeAuthorityGroupsUseCase->invoke();にしなければいけなかった。
        return 0;
    }
＝＝＝＝＝==後略＝＝＝＝＝==
```
kotlinx.serializationをKMMで使うと「kotlinx.serialization compiler plugin is not applied to the module, so this annotation would not be processed.」とエラーになる（解決）

# この記事は？

本年もあと少し。今年もQiitaには大変お世話になりました。
ところで最近KMMを勉強し始めました。結構ど頭でつまづいたのですが情報がほとんどなかったので、簡単にまとめたいと思います。

# KMMとは？

この記事を読んでいるってことはKMMについてはご存知だと思うので省略。

https://kotlinlang.org/lp/mobile/

# 発生した症状

kotlinx.serializationをサイトの記述に沿ってプロジェクトに追加したのに、アノテーションなどが有効にならない。

例） `@Serializable`を付与すると、強調表示になって以下のメッセージが表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65508/2f66a9fc-bff9-49d1-e802-a980912e14fb.png)

```text
kotlinx.serialization compiler plugin is not applied to the module, so this annotation would not be processed. Make sure that you've setup your buildscript correctly and re-import project.
```

# 解決方法

Google先生に聞いて色々なサイトを当たりましたが、自分の環境で思い当たる節はなく、、、
結局、原因は`shared`配下の`build.gradle.kts`の`plugins`にも`kotlin("plugin.serialization")`を追加しないとダメだったということ。

修正前（抜粋）：

```kotlin:/shared/build.gradle.kts
plugins {
    kotlin("multiplatform")
    id("com.android.library")
}
```

修正後（抜粋）：

```kotlin:/shared/build.gradle.kts
plugins {
    kotlin("multiplatform")
    kotlin("plugin.serialization")
    id("com.android.library")
}
```

# まとめ

自分、まだGradle歴が浅いため「トップディレクトリのbuild.gradle.ktsに書いたら、配下に伝播する」と勝手に思い込んでいました（各種公式サイトには確かにそうは書いていない、けど`/shared/build.gradle.kts`にも書けとも書いてない）。Gradle周り、ご存知の方ならなんの問題ないことなのかもしれませんが、初学者には厳しいハードルとなっています。もう少しスマートにならないものでしょうか、、、
[Biopython]環状ゲノムを描画する

:::note info
2025-05-23 追記:
[gbdraw](https://github.com/satoshikawato/gbdraw)をリリースしました！
![gbdraw.png](https://raw.githubusercontent.com/satoshikawato/gbdraw/refs/heads/main/examples/gbdraw_social_preview.png)
:::

2024-02-06追記: 直鎖状・環状ゲノムを可視化するスクリプトを[パッケージ化](https://github.com/satoshikawato/gbdraw)しています。お楽しみに

# 動機
細菌やウイルスのゲノムダイアグラムを描くには[CGview](https://cgview.ca/)や[Artemis](https://www.sanger.ac.uk/tool/artemis/)といったソフトがポピュラーだが、自分の好みに合った絵柄でSVG出力したかった。
SVG出力することで、[Inkscape](https://inkscape.org/ja/)等を用いて編集可能となる。
Matplotlibでは環状ゲノムの描画が難しかったため、SVGを描画するライブラリ ([SVGwrite](https://svgwrite.readthedocs.io/en/latest/)) を用いて一から実装した。
イントロンにも対応している。

# plot_circular_genome.py
Generate genome diagram in SVG
https://github.com/satoshikawato/bio_small_scripts/blob/main/plot_circular_genome.py
## Requirements
- [Biopython](https://biopython.org/)
- [pandas](https://pandas.pydata.org/)
- [SVGwrite](https://svgwrite.readthedocs.io/en/latest/)
## Usage
```
$ ./plot_circular_genome.py -h
usage: plot_circular_genome.py [-h] -i INPUT [-t TABLE] [-n NT] [-w WINDOW] [-s STEP]

Generate genome diagram in SVG.

optional arguments:
  -h, --help            show this help message and exit
  -i INPUT, --input INPUT
                        Genbank/DDBJ flatfile (required)
  -t TABLE, --table TABLE
                        color table (optional)
  -n NT, --nt NT        dinucleotide (default: GC).
  -w WINDOW, --window WINDOW
                        window size (default: 1000)
  -s STEP, --step STEP  step size (default: 100)
```
![NC_003225](https://user-images.githubusercontent.com/58936715/192824730-4fddc66c-8853-4ee7-83e6-58f945916411.svg)
![NZ_LR214945](https://user-images.githubusercontent.com/58936715/192824717-099c20e0-f976-431e-9881-f333ee10e597.svg)
各レーンは外側から
- +方向 feature (タンパク質:青色、ribosomal RNA: 緑色、transfer RNA: 黄色、misc_feature: 灰色）
- -方向feature
- GC skew(エメラルド色:+/紫色:-)
- GC含量 (灰色）
を示す。
ソースコードを編集するか、カラーテーブルを別途指定することで色は変更可能である。
入力genbankファイルがエントリを複数含む場合 (Vibrioゲノム等)、各エントリのダイアグラムはLOCUS IDをファイル名とした個別のファイルに保存される。この理由から出力ファイル名のオプションは実装していない。
せっかくだし我が家の名前解決事情を晒し上げ祀って2022年を締めくくる話

# これはなんなのですか?
> (^_^；)｢そういえば今年全然 Qiita さんにネタ出してねぇし2022年最後だしなんか出さないとなー｣

と思って書き出した~~ただのクソ~~記事です｡
~~書き始めたのが2022-12-31 20:44からとか締めの記事にもってこいでs(ry~~

# 構成
![dns.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19210/cc0341d2-c9cc-5578-8aba-e592d1167104.png)
よくわかりそうでわからない図を載せて(いると自画自賛して)ますw

家の中から問い合わされた DNS のリクエストは一旦軽めのリゾルバを front Resolver にして､特定のホスト(CDN や属性型の JP､ arpa ドメインなど)の場合は Resolver 2 を介して ISP のリゾルバに､それ以外はフルリゾルバの Resolver 1 に問い合わせるように振り分けています｡
一応振り分けリストを作っておいて設定ファイルに吐き出すようにしてます｡

# この構成にしたきっかけ
数年前に DNS 周りでいろいろあった xxx とか xxxxx とかの話で自分はふと｢あんまり安全じゃない戦場みたいなインターネットのほうがおもしろいじゃん?｣と思っている側の一人なので
図のような構成にしてみました｡
~~｢なにやってんだこいつ…?｣って思いましたよね｡ 自分もそう思っています｡でも面白いと思ってやってるんですwwww~~

## adblock の説明は…
またいつかの記事でってことで…(逃
BLOCS で エディタ / IDE のサポートを有効にする

最近のエディタや各種 IDE においては大体入力をサポートしてくれる機能があり、少ないタイプ数で、あるいは少々うろ覚えでも書き進めることができます。

ところで BLOCS という新しいテンプレートエンジンをリリースしました。こういう時に困るのが入力のサポートを受けられないことです。そこでいくつかのエディタ / IDE で BLOCS のデータ属性を入力する際にサポートを受けれるようにスニペットやライブテンプレートを用意しました。

ちなみに BLOCS はこちらになります

https://github.com/blocs/blocs

# Sublime Text で Snippets を使う

上記リポジトリの `snippets/SublimeText/*.sublime-snippet` を以下のディレクトリに置く

[Windows]
`~\AppData\Sublime Text\Packages\User\`

[Mac]
`~/Library/Application Support/Sublime Text/Packages/User/`

![sublimetext.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975625/0e1deae4-26a2-2ea8-d584-69b30f69edf0.png)

# Visual Studio Code で Snippets を使う

上記リポジトリの `snippets/vscode.code-snippets` を以下のディレクトリに置く

[Windows]
`~\AppData\Roaming\Code\User\snippets`

[Mac]
`~/Library/Application Support/Code/User/snippets`

![vscode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975625/d1a05865-bcc2-c594-f37f-1552755632e4.png)

# PhpStorm で Live template を使う

上記リポジトリの `snippets/PhpStorm/BLOCS.xml` を以下のディレクトリに置く

[Windows]
`~\AppData\Roaming\JetBrains\PhpStorm<version>\templates`

[Mac]
`~/Library/Application Support/JetBrains/PhpStorm<version>/templates`

PhpStorm が起動中の場合は再起動後に使えるようになります。

![phpstorm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975625/d597d43c-8fb5-35bb-a497-03f6c00e52be.png)
[Biopython] ORF予測プログラムを作る

# 動機

原核生物ゲノムの遺伝子予測（注）ソフトといえば[Prodigal](https://github.com/hyattpd/Prodigal)や[MetaGeneAnnotator](http://metagene.nig.ac.jp/)がある。
ただこれらはORF間のオーバーラップに対応していなかったり（ウイルス等で困る）、GFF3形式でのアウトプットに対応していなかったりする。
そこで、遺伝子間の重複を許しつつGFF3ほかの形式で結果を出力するORF予測プログラムを書いた。

幸いBiopython Tutorial and Cookbookにズバリ[Identifying open reading frames](http://biopython.org/DIST/docs/tutorial/Tutorial.html#sec384)
というセクションがあった。
これを骨格に、
- 開始コドンから翻訳開始すること
- 遺伝暗号表を変更可能なこと
- 入力出力ファイルを指定可能なこと

等の改変を加えた。

（注）ここでは遺伝子予測＝[Open reading frame (ORF)](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3%E3%83%AA%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0)の予測ということにする。機能アノテーションは本稿では扱わない

## orfind.py
ORF prediction allowing CDS overlaps and GFF3 output

https://github.com/satoshikawato/bio_small_scripts/blob/main/orfind.py

### Requirements
- [Biopython](https://biopython.org/)
### Usage
```
$ ./orfind.py -h
usage: orfind.py [-h] -i INPUT [-o OUT_GFF] [-a OUT_FAA] [-f OUT_FNA] [-g TRANS_TABLE] [-m MIN_AA_LEN]

Predict ORFs

optional arguments:
  -h, --help            show this help message and exit
  -i INPUT, --input INPUT
                        sequence file in FASTA format (required)
  -o OUT_GFF, --out_gff OUT_GFF
                        output annotation in gff3 format (default: stdout)
  -a OUT_FAA, --out_faa OUT_FAA
                        output protein sequences in FASTA format (optional)
  -f OUT_FNA, --out_fna OUT_FNA
                        output CDS sequences in FASTA format (optional)
  -g TRANS_TABLE, --trans_table TRANS_TABLE
                        translation table (default: 1)
  -m MIN_AA_LEN, --min_aa_len MIN_AA_LEN
                        minimum protein length (default: 50)
```
## 参考
http://biopython.org/DIST/docs/tutorial/Tutorial.html#sec384
Elixir初学者が悩む、「括弧の省略」「無名関数」「キャプチャ演算子」の組み合わせ

# 初めに（ポエム）
Elixir は関数を呼び出す際の括弧を省略できます。
無名関数はキャプチャ演算子で略記ができます。
これら複合技により、スマートに早くコーディングできるのですが、初学者にはとても分かりにくい・・・。

初学者、初見殺しです。

諦めないためにも、ここで色んなパターンを見て、理解を深めて貰えたらと思います。


# 「括弧の省略」「無名関数」「キャプチャ演算子」の組み合わせを理解する
まずは、基本的な部分についておさらいします。

## 無名関数
無名関数の作成はfnで始まりendで終わります。  

例：`fn (x, y) -> x + y end`

->の左側には仮引数（parameters）の組`(x, y)`がカンマで区切られています。
仮引数は、呼び出された関数などが値を受け取るために宣言された変数のことです。
関数作る時に、最初に関数名と受け取る引数を書きますね。その引数を仮引数と言います。

->の右側に書かれた式`x + y`が無名関数の本体です。

無名関数を`add_fn`に束縛した場合、`add_fn.(引数1,引数2)`で引数を与えて呼び出せます。無名関数の時はドットが必要なので忘れないように注意ください。
（逆に名前付き関数では、ドットが不要です。）

```Elixir
iex> add_fn = fn (x, y) -> x + y end
#Function<41.3316493/2 in :erl_eval.expr/6>
iex> add_fn.(1,5)
6
```

`fn (x, y)`の括弧は省略することができます。

```
iex> add_fn = fn x, y -> x + y end
#Function<41.3316493/2 in :erl_eval.expr/6>
iex> add_fn.(1,5)
6
```

## キャプチャ演算子
キャプチャ演算子を使って、`fn -> end`までのくくりを`&()`、
`x, y -> x + y`の第一引数`x`を`&1`として、第二引数`y`を`&2`として簡略化することができます。

先ほどの関数をキャプチャ演算子で置き換えてみましょう。
```
iex> add_fn = &(&1 + &2)
&:erlang.+/2
iex> add_fn.(1,5)
6
```
とてもシンプルです。分かりにくいと思うかもしれませんが慣れです。
基本、`fn x, y -> x + y end`の書き方の方が煩わしいので使わないです。

ここからが分かりにくなるので、自分でプログラム打ちながら確認してください。

括弧は省略できます。ただし、最初の`&`の後に空白を入れないとコンパイルエラーになります。
```Elixir
iex> add_fn = & &1 + &2
&:erlang.+/2
iex> add_fn.(1,5)
6
```

しかし、`&`の後に関数が続く場合、空白は不要です。
以下の例では、出力結果をIntegerからStringに変換しています。

```Elixir
iex> add_fn = &to_string(&1 + &2)
#Function<41.3316493/2 in :erl_eval.expr/6>
iex> add_fn.(1,5)
"6"
```

後ろの括弧も省略できます。
```
iex(14)> add_fn = &to_string &1 + &2
#Function<41.3316493/2 in :erl_eval.expr/6>
iex(15)> add_fn.(1,5)
"6"
```
正直、初学者からすると`&to_string`で一つの関数に見えるし、
後の処理でも`&1 + &2`が付いているので、`&`いっぱい付いててなんだろこれ？になります。

もっと省くこともできて、空白も省けます。

```Elixir 
iex(18)> add_fn = &to_string&1+&2
#Function<41.3316493/2 in :erl_eval.expr/6>
iex(19)> add_fn.(1,5)
"6"
```

初学者の初見殺しです。
コンパイルエラーにはなりませんが、可読性が悪いので、普通はここまでしないと思います。

実際には、以下のようなパターンで表記される事が多いと思います。
```Elixir
iex(22)> add_fn = &(to_string &1 + &2)
#Function<41.3316493/2 in :erl_eval.expr/6>
iex(23)> add_fn.(1,5)
"6"
```

また、キャプチャ演算子を用いることで関数を無名関数と同じように呼び出せるので、
以下のようにも書けます。

そろそろパターン多くて飽きてきますが、たくさん見慣れておいてください。

`to_string/1`の`/1`は、アリティ（引数）が1個という事です。
こちらは、割り算の演算子`/`と同じなので、一瞬割り算かと思いますが、関数の後に付いているのでアリティだと読み解いてください。

```
iex> add_fn = &to_string/1
#Function<42.3316493/1 in :erl_eval.expr/6>
iex> add_fn.(1 + 5)
"6"
```

## どうやって見分けるのか？
`&`が一つだけ出てきたら、無名関数だと認識しましょう。
`&&`で論理積の演算子になりますが、あまり出てこないと思います。


# さいごに
Elixirのソース見て、`&`たくさん付いてて意味不明と、嘆いている初学者の方の一助になればと思います。
誤りなどありましたらご指摘お願いいたします。
GraphQL サーバー構築(その5. GraphQL Code Generator)

id: 4f38f3f8
## 前回
https://qiita.com/ponchuchu/items/1527044fe9d87b2aaf21

## 今回やること
- [x] GraphQL Code Generatorによる型定義ファイルの生成
- [ ] 生成した型定義ファイルをresolverへ適用

### GraphQL Code Generatorによる型定義ファイルの生成
```sh:bash
--save-dev @graphql-codegen/cli @graphql-codegen/introspection @graphql-codegen/typescript @graphql-codegen/typescript-operations @graphql-codegen/typescript-resolvers
```

* 下記を追加
```json: package.json
"scripts": {
    "codegen": "gql-gen --watch",
```

* codegen.yml を作成
```yaml: codegen.yml
overwrite: true
# スキーマファイルのパス
schema: src/typedefs/*graphql 
generates:
  # 生成する型定義ファイルのパス
  src/generated/graphql.ts:
    plugins:
      - "typescript"
      - "typescript-resolvers"
  ./graphql.schema.json:
    plugins:
      - "introspection"
```

```sh: bash
$ npm run codegen
```

* src/generated/graphql.tsが生成される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193053/d05cdd90-5a47-9e88-8e1f-fbdae0efdedb.png)

### 生成した型定義ファイルをresolverへ適用
```ts: index.ts
import type { Resolvers } from "./generated/graphql"
const resolvers: Resolvers = {
  Query: {
    books: () => books,
  },
  Mutation: {
    addBook(parent, args) {
      const book = {
        author: args.author,
        title: args.title,
      };
      books.push(book)
      return book;
    }
  }
};
```
[Biopython] 細菌ゲノムのGC skewを描画する


## GC skewとは
   [GC skew](https://en.wikipedia.org/wiki/GC_skew)とは、ゲノムDNA上のグアニン(G)とシトシン(C)含量の偏りのこと。
```GC skew = (G - C)/(G + C)```
GC skew (下図青線)の累積 (cumulative GC skew; 下図橙線) は、複製開始点から終結点にかけてだんだん上がっていく/下がっていく(計算する鎖がリーデイング鎖かラギング鎖かによる)。Cumulative GC skewの変曲点 (下図赤線) が複製起点または終点に対応することが多い。
![GC_skew.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689564/29209195-c1a7-869d-ce98-c91df29c0253.png)

## plot_skew.py
Generate dinucleotide skew plot(s) of FASTA format DNA sequences in SVG format. Plots are saved separately for each entry in a multifasta file

https://github.com/satoshikawato/bio_small_scripts/blob/main/plot_skew.py

### Requirements
- [Biopython](https://biopython.org/)
- [pandas](https://pandas.pydata.org/)
- [Matplotlib](https://matplotlib.org/)
### Usage
```
$ ./plot_skew.py
usage: plot_skew.py [-h] -i INPUT [-n NT] [-w WINDOW] [-s STEP]

Generate dinucleotide skew plot(s) of FASTA format DNA sequences in SVG format. Plots are saved separately for each entry in a multifasta file

optional arguments:
  -h, --help            show this help message and exit
  -i INPUT, --input INPUT
                        Fasta (required)
  -n NT, --nt NT        dinucleotide (default: GC).
  -w WINDOW, --window WINDOW
                        window size (default: 1000)
  -s STEP, --step STEP  step size (default: 100)
```
Example: [Escherichia coli str. K-12 substr. MG1655, complete genome NC_000913.3](https://www.ncbi.nlm.nih.gov/nuccore/NC_000913.3?report=fasta)
```
$ ./plot_skew.py NC_000913.3.fasta # (output: NC_000913.3.svg)
```
![NC_000913 3](https://user-images.githubusercontent.com/58936715/192764584-f21297c2-8595-40c4-baae-20d6aab5575e.svg)
[Biopython]BLAST結果をドットプロットとして描画する

# 動機
[ドットプロット (ハープロット)](https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%83%E3%83%88%E3%83%97%E3%83%AD%E3%83%83%E3%83%88_(%E3%83%90%E3%82%A4%E3%82%AA%E3%82%A4%E3%83%B3%E3%83%95%E3%82%A9%E3%83%9E%E3%83%86%E3%82%A3%E3%82%AF%E3%82%B9))をもっと気軽に描きたい。
[BLAST](https://blast.ncbi.nlm.nih.gov/Blast.cgi)や[YASS](https://bioinfo.lifl.fr/yass/yass.php)も便利だが、SVG形式のファイルでアウトプットしたい。


# blast2dotplot.py
https://github.com/satoshikawato/bio_small_scripts/blob/main/blast2dotplot.py
## Requirements
pandas
[svgwrite](https://svgwrite.readthedocs.io/en/latest/) (verified with v. 1.4.3)
[Biopython](https://biopython.org/) (verified with v. 1.79)
## Usage
```sh
$ ./blast2dotplot.py
usage: blast2dotplot.py [-h] --input FILE

Draw a dot plot based on a pairwise BLASTN/TBLASTX result

optional arguments:
  -h, --help            show this help message and exit
  --input FILE, --in FILE, -i FILE
                        input BLASTN/TBLASTX result file in XML format (-outfmt 5)
```

## Output example
![200174764-310d8112-2e50-42b6-9e31-b030a48648c2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689564/a10bf270-1fe3-0c50-7b2a-febc099cb7b1.png)
- 順鎖のヒットを青、逆鎖のヒットをオレンジで表現する
- 今後　output file名を指定可能にする
今日のdocker error:process caused "exec: \"-it\": executable file not found in $PATH": unknown.

師走に追われて、初めての誤り。

```macOS:bash
$ docker run -it kaizenjapan/gcc -it
process caused "exec: \"-it\": executable file not found in $PATH": unknown.
$ docker run -it kaizenjapan/gcc /bin/bash
```
[Biopython] NCBI RefSeqの真核生物ゲノムから各遺伝子１本ずつタンパク質を取り出す

米国[NCBI](https://www.ncbi.nlm.nih.gov/) が公開する[RefSeq](https://www.ncbi.nlm.nih.gov/refseq/)は、DDBJ/ENA/GenBankといった公共配列データベースに登録された配列の中でも重要・高品質な参照配列 (<b>Ref</b>erence <b>Seq</b>uences) を集めたもの。

ゲノム配列を収録したRefSeq genomesは、NCBIが独自にアノテーションを加え、遺伝子やその転写産物とタンパク質の情報を追加している。
[NCBI RefSeqが収録する真核生物ゲノム](https://www.ncbi.nlm.nih.gov/genome/annotation_euk/all/)は、[NCBI Eukaryotic Genome Annotation Pipeline](https://www.ncbi.nlm.nih.gov/genome/annotation_euk/process/)というパイプラインでアノテーションされている。

例：クルマエビ <i>Penaeus japonicus</i>
[NCBI Penaeus japonicus Annotation Release 100](https://www.ncbi.nlm.nih.gov/genome/annotation_euk/Penaeus_japonicus/100/)

RefSeqのアノテーションに付属するタンパク質配列は、ゲノムアセンブリから欠落した配列がトランスクリプトーム等のデータで補われており、より信頼性が高い（と思われる）。

NCBI RefSeqの真核生物ゲノムアノテーション(GenBank形式ファイル*)から各遺伝子１本ずつ最長アイソフォームのタンパク質を抽出するスクリプトを書いた。
# gb2nrfaa.py
https://github.com/satoshikawato/bio_small_scripts/blob/main/gb2nrfaa.py
## Requirements
- [Biopython](https://biopython.org/)
## Usage
```sh
$ ./gb2nrfaa.py -h
usage: gb2nrfaa.py [-h] -i INPUT [-o OUTPUT] [-t TABLE]

Extract the longest isoforms of protein-coding genes from a NCBI RefSeq euaryotic genome assembly

optional arguments:
  -h, --help            show this help message and exit
  -i INPUT, --input INPUT
                        GenBank flat file format of the genomic sequence(s) (required)
  -o OUTPUT, --output OUTPUT
                        output fasta-formatted file (optional)
  -t TABLE, --table TABLE
                        output tab-separated table (optional)
```
Example: 
```sh
$ wget https://ftp.ncbi.nlm.nih.gov/genomes/all/annotation_releases/27405/100/GCF_017312705.1_Mj_TUMSAT_v1.0/GCF_017312705.1_Mj_TUMSAT_v1.0_genomic.gbff.gz
$ gunzip GCF_017312705.1_Mj_TUMSAT_v1.0_genomic.gbff.gz
$ mv GCF_017312705.1_Mj_TUMSAT_v1.0_genomic.gbff Penaeus_japonicus.gb # optional
$ ./gb2nrfaa.py  -i Penaeus_japonicus.gb -o Penaeus_japonicus.faa # can take a few minutes
$ seqkit stats Penaeus_japonicus.faa
file                   format  type     num_seqs     sum_len  min_len  avg_len  max_len
Penaeus_japonicus.faa  FASTA   Protein    22,301  11,476,300       31    514.6   21,694
```

*FASTA+GFF形式ファイルだとpatchされた配列を反映できない。.faaファイルはLOCUS IDをヘッダに含んでおらず遺伝子情報が失われている。

2023-03-29追記: 各遺伝子とタンパク質配列の対応表をtab-seaprated fileとして出力できるようにした (default: ```out.tbl```)。オプションは```-t```または```--out-table```。
M5 ATOMS3を触ってみる

M5 ATOMS3を買ったのと、[大みそかハッカソン](https://omisoka-hackathon.connpass.com/event/269353/)にエントリーしたので触ってみる。

# 準備
UIFlowでいじれるのかな？と思ってたんですが、どうやらまだUIFlowではいじれないらしい。
なので、Arduino IDEを使う必要があるらしい。
使ったことないんだが・・・ｗ
こちらのサイトを参考にしつつ進めていく。

https://lang-ship.com/blog/work/m5stack-atoms3/


まずは[Arduino IDEの公式](https://www.arduino.cc/en/software)からArduino IDEをダウンロード。
そしてインストール。
デフォルトが英語なので、必要に応じて日本語なりに変えるとよさそう。

メニューのツールからライブラリの管理を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/b0fc1ad1-a422-4c4a-f27e-698023c55a9f.png)

M5Unifiedを検索してインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/0236d10f-8a4f-3f92-3026-7e426ca5b6f6.png)

ファイルの基本設定を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/436aed03-d8e5-fe6a-1831-25f0a762c6b9.png)

設定タブの下部にある、追加のボードマネージャのURLに[こちら](https://github.com/arduino/Arduino/wiki/Unofficial-list-of-3rd-party-boards-support-urls)で公開されている、以下のURLを追加する。
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
その後、ボードマネージャで、ESP32 Dev Boardをインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/506e0928-23db-b5c0-db11-c090aa6354d8.png)

インストールが完了すると、ESP32S3 Dev Moduleが選択できるようになります。
ESP32S3 Dev Moduleの設定は以下の参考サイトを確認して設定します。

https://lang-ship.com/blog/work/m5stack-atoms3/


# 動かす

参考にしたサイトに掲載されている、M5Unifiedの「HowToUse」を動かしてみる。

https://lang-ship.com/blog/work/m5stack-atoms3/


・・・動いた！
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">助言もあり、参考にしたサイトに載ってたソースが動いた！<br>ここからだな・・・本当の戦いは！<br>とりあえず、だるま落としに使えるようにしたい。<br>(あと、借りてるセンサーでもだるま落としはやりたい)<a href="https://twitter.com/hashtag/%E5%A4%A7%E6%99%A6%E6%97%A5%E3%83%8F%E3%83%83%E3%82%AB%E3%82%BD%E3%83%B3?src=hash&amp;ref_src=twsrc%5Etfw">#大晦日ハッカソン</a> <a href="https://t.co/uZV2GmMT5F">pic.twitter.com/uZV2GmMT5F</a></p>&mdash; ᴛᴀᴋᴀ@浜松/ᴋʀᴏʜɪɢᴇᴡᴀɢᴍᴀ (@project_dev_tk) <a href="https://twitter.com/project_dev_tk/status/1609159883219415040?ref_src=twsrc%5Etfw">December 31, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


UIFlowを待つか、このまま進めるか・・・悩ましい。
【Swift】WebKitでbackspaceを押すと前のページに戻る仕様の対処法

# はじめに
タイトルの通りです。
MacApp開発時に見つけた問題ですがiPadでキーボード接続時にも起きると思います。(未検証)

タグに`JavaScript`とあるようにjsを使って解決します。
swift側で解決する方法があれば教えてください。

# 実行環境
- `MacOS 13.1`
- `Xcode 14.2`
- `swift 5.7.2`

# ソースコード
```Swift:NavigationDelegate.swift
// "WebViewController"は各自命名したclassに合わせて変更してください
extension WebViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
        webView.evaluateJavaScript("document.addEventListener('keydown',function(a){var b=a.target.nodeName.toLowerCase();'Backspace'!==a.key||'input'===b&&!'range checkbox radio color submit reset button image file hidden'.split(' ').includes(a.target.type.toLowerCase())||'textarea'===b||a.preventDefault()},!1);")
    }
}
```

# 解説
`func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!)`
を使い遷移開始時にjsを実行します。

jsのコードは圧縮しています、圧縮前のコードはこちらです。
```js
document.addEventListener("keydown", function (e) {
    var nodeName = e.target.nodeName.toLowerCase();
    var type = e.target.type.toLowerCase();
    var typeList = ["range", "checkbox", "radio", "color", "submit", "reset", "button", "image", "file", "hidden"];
    if (e.key === "Backspace") {
      if (!(nodeName === "input" && !typeList.includes(type) || nodeName === "textarea")) {
        e.preventDefault();
      }
    }
  },
  false
);
```

`textarea`と一部の`input`ではバックスペースが入力できないと困るのでそれ以外の時に無効化する処理を入れています。

これでテキスト入力時以外はバックスペースを無効化します。
GASでGoogle Mapの一部を画像で切り抜いてみた

## はじめに
GASでは、Google　MapをWebサイト等に埋め込むことなどができるようになる、Maps Static APIを簡単に使うことができます。僕自身、Maps Static APIをあまり知らなかったので、今回はそれを含めて何ができるか簡単に紹介したいと思います。

## GASでGoogle Mapの一部を画像で切り抜いてみた
まずは、Maps Static APIで何ができるか簡単に紹介したいと思います。簡単にではありますが、以下のことができたりします。

- 場所を指定して地図を表示する
    - 地図を独自のスタイルに変更可能
- 地図にマーカーを追加する
    - マーカーのスタイルは変更可能
- 地図にパスを追加する
    - スタイルは変更可能
- 地図にポリゴンを追加する
    - スタイルは変更可能
- 地図をWebサイト等に埋め込む
- 地図を画像として保存する
- など...

今回は、これらのできることの一部を実際にやってみたので、紹介したいと思います。

### 場所を指定して地図を表示してみる
まずは簡単に場所を指定して、地図を表示してみたいと思います。今回は、名古屋城を表示するようにしてみたいと思います。わかりやすいようにマーカーも追加してみました。場所の指定の仕方は、地名や緯度経度で指定することができます。

```js
const testMap = () => {
    const map = Maps.newStaticMap()
                    .setLanguage('ja')
                    .addVisible('名古屋城') // 表示するものを指定
                    .addMarker('名古屋城'); // マーカーを立てるところを指定

    // 地図を画像として、Google Driveに保存する
    DriveApp.createFile(Utilities.newBlob(map.getMapImage(), 'image/png', 'map_test.png'));
}
```

保存された画像は以下です。
![IMG_0828.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/2178b67f-ef0c-2b8d-d8f9-c73408e549bc.jpeg)

### 地図にパスを追加する
Maps Static APIでは、地図に線（パス）を引くことが可能です。道のりを示すときにできるかなあと思い、今回はとある駅から名古屋城の入り口までの道のりで線を引いてみました。今回引いた線ですが、2点をしていて線分を作り、それらを組み合わせて引いています。

```js
const testMapRoute = () => {
    const map = Maps.newStaticMap()
                    .beginPath() // パスの始点
                    .addPoint(35.182464, 136.904922)
                    .addPoint(35.182558, 136.904691)
                    .addPoint(35.183797, 136.904441)
                    .addPoint(35.183785, 136.903968)
                    .addPoint(35.183936, 136.903727)
                    .addPoint(35.183927, 136.903429)
                    .addPoint(35.184049, 136.903106)
                    .endPath() // パスの終点
                    .addMarker(35.182464, 136.904922)
                    .addMarker(35.184049, 136.903106)
                    .setLanguage('ja');

    // 地図を画像として、Google Driveに保存する
    DriveApp.createFile(Utilities.newBlob(map.getMapImage(), 'image/png', 'map_route.png'));
}
```

![IMG_0827.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/aac82f33-8e82-648d-a73a-e7d4efa188eb.jpeg)

こちらが保存された画像です。思いのほか道を示せるようになっているなと思いました。画像ではなく、実際のインタラクティブな地図だとより上手く使えるかなと思いました。

## さいごに
今回は、GASでMaps Static APIを使う方法を紹介しました。地図に埋め込むなど割と使える場面は多いかなと思うので、興味がある方はぜひ使ってみてください。
今年中に書く予定だったプログラム


AUTOSAR 

http://www.autosar.org

2022年12月にWebの更新があった。　

文書URLが一部変更になった。 

https://www.autosar.org/fileadmin/user_downloads/standards/foundation/21-11/AUTOSAR_TPS_AbstractPlatformSpecification.pdf

から

https://www.autosar.org/fileadmin/standards/foundation/21-11/AUTOSAR_TPS_AbstractPlatformSpecification.pdf

に変更。　/user_downloads が減るだけ。
 
Qiita の記事で、1000箇所くらいに記載がある。　

編集していると10個くらい編集したところで、新しい記事が投稿できなくなる。　

編集の回数が多いとのこと。　

スマフォでは必ず表示する。　

PCでは、表示しないことがある。　

なにしてくれちゃうの Qiita.

SNS系では、自動プログラムによるさまざまな現象に対して、


Qiitaに登録して、確認済みの認証を受けたら、プログラム動かしても、編集の回数が多いと新規投稿を拒否するのやめてもらえると嬉しいかも。　

あ、これ、単にプログラムうまく作れない愚痴です。


### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
【LOG】Next.js に Tailwind CSS を導入してみる

# 前置き
勉強がてら Web サイトを 1 から作ってみようと考えた。
Next.js を触ったことがあったので、それを使うことを決定。
いざ、作り始めよう！（⇦ イマココ）

## CSS どうしよう
とりあえずやったことないことをしたいので、仕事中に小耳に挟んだ TailWind CSS 触ってみることを決意。

# 本題
公式ページを参考にして Next.js に Tailwind CSS を入れてみる。
[Tailwind CSS 公式ページ](https://tailwindcss.com/docs/guides/nextjs)

**1. プロジェクトを作る**
```
npx create-next-app@latest my-project --typescript --eslint
cd my-project
```
今回はすでにプロジェクト作成済みなので skip

**2. Tailwind CSS をインストールする**
```
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```

**3. tailwind.config.js を書き換える**
```
module.exports = {
  // この中身は適切に書き換える
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

**4. style 用のファイルを作成してディレクティブをファイルに追加する**
`./styles/globals.css` に下記を追加
```
@tailwind base;
@tailwind components;
@tailwind utilities;
```

**5. 開発環境を立ち上げる**
```
npm run dev
```

**6. Tailwind CSS を実際にコード内に埋め込む**
【Sample】
```
export default function Home() {
  return (
    <h1 className="text-3xl font-bold underline">
      Hello world!
    </h1>
  )
}
```

**これで動くはず！！！**

だったけど css が当たらずにスタイルが変わらなかった...

## 原因調査log
**1. globals.css どこからも import してなかった...**
_app.tsx で globals.css を import するように変更

**→ できた！**
凡ミスすぎて辛かった...

# まとめ
ひとまず Tailwind CSS を導入することはできたから、実際に使ってみる！
レビューの指摘点を分析してみた

# はじめに
 最近全員レビューをチームに導入しました。全員レビューを開始して1ヶ月くらい経ったので、今後のコードの品質向上に役立てる目的で、直近のレビューの指摘点を大雑把にカテゴライズしてみました。チームの構成としては、超ベテラン1名、ノーマル1名、ルーキー2名、ひよこ1名のメンバー構成となっています。チーム発足以来、ずっとペアモブでのプログラミングを進めてきたので、レビューに関しては、ほぼほぼ初心者の集まりです。

# 環境
- GitHubのプルリク
- Googleスプレッドシート
- 手作業で頑張る

# 結果
今回の指摘点を大雑把にカテゴリ分けしてみたところ、次の4つのカテゴリに分けられました
- コードの可読性に関すること（コメント、変数の命名などについて）
- コードの保守性に関すること（クラス設計やDRYなコードなどについて）
- 無駄コード（デバッグログの残り、コードの消し忘れなど）
- 機能実装漏れの指摘

割合はこんな感じです。
|カテゴリ|可読性　|保守性　|　無駄　| 実装漏れ |　バグ　|
| --- | --- | --- | --- | --- | --- |
|　％| 　46.8 |　32.3|　12.9 |　6.5　|　1.6　|

![カテゴリグラフ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815054/c6f886d0-0856-d317-f8b2-3a008cfc694d.png)

圧倒的に可読性に関することが多いですね。

# 各カテゴリについて
### コードの可読性に関すること
主にコメントについての指摘が一番多かったです。
#### コメントについて
1. 3行コメントを付け忘れている
私のチームでは、メソッドの頭に3行コメントをいれるように決めているのでそのつけ忘れが多い
2. HowではなくWhy
コメントを書く際に、コードに書いていることをそのまま日本語に翻訳しただけコメント多い、「なんのための処理」なのか「意図はなんなのか」などをコメントに書いてほしいと指摘している
3. 書いている本人はわかっているが、レビューする人には伝わってない
コードを書いている際は、当然何をしているコードなのか理解できているので、特にコメントを必要に感じないが、レビューを通してコードを書いてない人が見ると、理解するのに時間がかかるので読みやすいようにコメントをつけてほしいと指摘している。
4. 消し忘れ、不適切、修正漏れ
メソッドの名称と内容を変えたのに、コメントは変更し忘れていることの指摘
#### 命名
1. メソッドは動詞
メソッドの始まりは動詞になるように決めています
2. 真偽値を持つ変数はis~
真偽値（True/False）は「is〜」のように真か偽で答えられる形式にして読みやすくしています。
3. (余談)codic
同じ動作を表す単語が複数あり、チーム内で意見が割れる際には[codic](https://codic.jp/engine)というサービスを使用しています
### コードの保守性に関すること
1. クラス設計に関すること
処理が一箇所にまとまりすぎているので、新しくクラスに切り分けたい
他のクラスに置くべきではないかという責任範囲の話
2. DRY
既存の処理をコピペして目的の動作を実現した後、共通化することなくそのままにしていることに対する指摘
既存の定数やメソッドに気づいてなくて使用していないことの指摘
独自の書き方ではなくすでに他の処理で実装されている書き方に統一すべきという指摘
### 無駄コード＆機能実装漏れの指摘
特に記載することはないです。

# やってみて
レビューを本格的に始めてみて、1レビューに対する指摘コメントが多いことが問題にあがり、指摘点を減らす目的のために、この取り組みをやってみました。この取り組みの中で、どんな指摘点があるのかチーム内で共有、再認識できることができました。認識することで、レビューに慣れてきたこともありますが、この取り組みの翌週からケアレスミス的な指摘の数はどんどん減っていきました。やらないよりは、チームのコードに対する意識の成長につながったのではと思っています。
Scratch のクローン時のスプライト変数の動きに関して

# はじめに

Scratch の変数に関してクローン時の変数スコープを解説している記事で自分にとってわかりやすい記事がなかったので備忘録として記載する


## 変数スコープとは?

簡単に一言で変数がアクセスできる範囲のことです
アクセスすることができる範囲を絞ることでより変数を管理しやすくなります


# Scratch の変数スコープ
Scratch には 「グローバル変数」と　スプライトごとに範囲を絞った変数の「スプライト変数」があります

## 変数のスコープの設定方法

変数のスコープは変数作成時に設定することができます
すべてのスプライト用が「グローバル変数」です
このスプライトのみが「スプライト変数」となります

![スクリーンショット 2022-12-31 15.22.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316631/880c4b27-4130-bfa3-820f-6a47408efe05.png)

### グローバル変数

グローバル変数は全てのスプライトからアクセスすることができます
これは変更と呼び出しをすることができます


### スプライト変数

スプライト変数は変数作成時にスプライトのみでアクセスすることができる

## クローン時のスプライト変数について

スプライト変数を設定された変数のスコープについて解説していく

### スプライト変数の値はクローンされた時点の値を使う

下記のような動きを検証するため、スプライト変数のHPを10に設定しクローンを作成後スプライト変数のHPを0にするコードを作成する

![スクリーンショット 2022-12-31 20.18.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316631/1d7f8861-d896-f84f-a045-97be2e2b29b7.png)

実行結果としてはクローン実行時の値が参照されるようになる

![スクリーンショット 2022-12-31 20.20.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316631/974a1324-f523-4281-5c45-a07d61af89ee.png)

### 変更はローカルなスコープで行われる

検証のためにコウモリと触れた際にはHPを減らすし0になったら「倒された」と表示するコードを作成する

![スクリーンショット 2022-12-31 20.26.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316631/64968d98-58a8-d692-1e6b-dae36f9fab51.png)


スプライト1をコウモリに触れさせると触れたスプライトだけHPが減っていることがわかる

![スクリーンショット 2022-12-31 20.27.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316631/1512d7ab-ad60-1f43-7c85-9c59d05e6e9d.png)
Node.jsでExcelファイルのデータを取得する


触る機会がありましたので、忘れないようにまとめておきます。

## ファイル構成
```
└── test
    ├── Book1.xlsx
    ├── package.json
    └── excel.js
```

## 作成したファイル

### Book1.xlsx
| 日付 | 名前 |
|:-:|:-:|
|  2022/4/11 |  河森 |
| 2022/4/17  |  田中 |
| 2022/4/29  | 山田  |
| 2022/5/6  |  新岡 |
| 2022/5/19  |  満島 |
| 2022/6/5  |  阿島 |

### excel.js

```js:excel.js
const xlsx = require('xlsx');

// エクセルファイル
const excelFile = xlsx.readFile('./Book1.xlsx');
const shName = 'Sheet1';
let sh = excelFile.Sheets[shName];

// A1の記述を取得する
const a1 = sh['A1'].w.replace(/(\t|\n)/g, '');
console.log(a1);
/* 出力結果
  日付
 */

// シートをまるごと取得し、json化する
const sheet1 = xlsx.utils.sheet_to_json(sh);
console.log(sheet1);
/* 出力結果
  [
    { '日付': 44662, '名前': '河森' },
    { '日付': 44668, '名前': '田中' },
    { '日付': 44680, '名前': '山田' },
    { '日付': 44687, '名前': '新岡' },
    { '日付': 44700, '名前': '満島' },
    { '日付': 44717, '名前': '阿島' }
  ]
 */
```

## 困ったこと

### xlsx導入時にエラーが出た
`npm install xlsx`実行時に以下のエラーが出た
```
npm ERR! code UNABLE_TO_GET_ISSUER_CERT_LOCALLY
npm ERR! errno UNABLE_TO_GET_ISSUER_CERT_LOCALLY
npm ERR! request to https://registry.npmjs.org/xlsx failed, reason: unable to get local issuer certificate

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/xxx/.npm/_logs/2022-12-20T16_09_00_486Z-debug.log
```
以下のコマンドで解決しました
```
npm config set registry http://registry.npmjs.org/ 
```
【初心者向け】Zabbixサーバ構築してみた

# はじめに
ZabbixでDockerコンテナの監視をしたいと要望が出たので、検証のためにZabbixサーバを構築してみました。
その構築過程を残しておこうと思います。

# サーバ構成
- AWS(EC2)
- CentOS7.9
- Zabbix5.0

# 前提条件
- ネットワーク環境(VPC,サブネット,ルートテーブル,セキュリティグループ)が既に構築済みであること

# 構築してみる

### Zabbixパッケージダウンロード
```
rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm
```

### Yumの掃除
```
yum clean all
```

### インストール
```
yum -y install zabbix-server-mysql zabbix-agent
yum -y install centos-release-scl
```

### Yumリポジトリ編集
```
sed -i '11s/enabled=0/enabled=1/g' /etc/yum.repos.d/zabbix.repo
```

### Zabbix-sclのインストール
```
yum -y install zabbix-web-mysql-scl zabbix-apache-conf-scl
```

### MariaDBのインストール
```
yum -y install mariadb mariadb-server
```

### DB起動
```
systemctl start mariadb && systemctl enable mariadb
```

### DBのセキュリティ設定
```
mysql_secure_installation
```

### DB設定
```
mysql -u root -p

create database zabbix character set utf8 collate utf8_bin;
create user zabbix@localhost identified by 'password';
grant all privileges on zabbix.* to zabbix@localhost;
set global log_bin_trust_function_creators = 1;
quit;
```

### Zabbix初期データ投入
```
zcat /usr/share/doc/zabbix-server-mysql*/create.sql.gz | mysql -u zabbix -p zabbix
```
DB設定で登録したパスワードを入力する

### DB設定戻し
```
mysql -u root -p

set global log_bin_trust_function_creators = 0;
quit;
```

### Zabbixパスワード設定
```
vi /etc/zabbix/zabbix_server.conf
```

以下を設定
```
DBPassword=password
```

### PHP設定
```
vi /etc/opt/rh/rh-php72/php-fpm.d/zabbix.conf 
```

以下をコメントアウト、Asia/Tokyoに変更
```
php_value[date.timezone] = Asia/Tokyo
```

### Zabbix再起動
```
systemctl start zabbix-server zabbix-agent httpd rh-php72-php-fpm
systemctl enable zabbix-server zabbix-agent httpd rh-php72-php-fpm
```

### SELinux無効
CentOS7.9の場合、デフォルトでSELinuxがEnforcingになっているので、無効にする必要がある。

```
sed -i 's/SELINUX=Enforcing/SELINUX=Disabled/g' /etc/selinux/config
```

### 再起動
```
shutdown -r now
```

### ブラウザ確認
以下のURLでアクセスする。
```
http://${グローバルIPアドレス}/zabbix
```

ログインするときは以下の情報を入力する。
```
ID:Admin
PASS:zabbix
```

以上
oneapiを用いたlammpsインストール


## 注意点

oneapiとHPCをインストールする。
eclipseとの統合は無視でok
.bashrcに以下を追記する
```
source /opt/intel/oneapi/setvars.sh
````
起動時にoneapiのパスが通る

```
wget https://download.lammps.org/tars/lammps-stable.tar.gz
tar xvzf lammps-stable.tar.gz
```
```
mkdir ~/lammps/build
cd  ~/lammps/build
```

cmakeは以下のコマンドにする
```
cmake ../cmake/presets/basic.cmake -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DCMAKE_Fortran_COMPILER=ifx -D BUILD_MPI=yes -D BUILD_OMP=yes -D PKG_OPENMP=yes -D PKG_MANYBODY=yes -D BUILD_SHARED_LIBS=yes -D PKG_PYTHON=yes -D PKG_MEAM=yes ../cmake
```
```
make -j 4
```
SOを指定しての実行
```
make install
```

pythonでの実行
```
make install-python
```

ちなみにicxコンパイラーを用いるとsrc/fmt/format.hおよび/src/fmtlib_format.cppにて警告がでることがある。

警告が出るが一応普通に使える。
icpxの方が計算が少し速いかも?

srcディレクトリでmake mpiコマンドでシリアルオプションでmakeしたときのlammpsが残っていると怒られる。（丁寧にどのコマンドを叩けば消せるか教えてくれる）

manybodyとかで他のペアのソースファイルを足したい場合なんかはsrc/MANYBODYにそのソースファイルをコピペしてcmakeすればok

## 実行sh
```
mpirun -np 4 lmp -sf omp -in in.CVD >> CVD.out
```
【29歳/未経験/独学】Web系エンジニアに転職して1か月経過したので感想を共有します！

# はじめに

こんにちは！

先日、以下の記事を投稿しました。

[【29歳/未経験/独学】転職活動用SPAポートフォリオをご紹介します！【Nuxt\.js, Rails, Docker, CircleCI, AWS ECS\(Fargate\), Terraform】 \- Qiita](https://qiita.com/takepro14/items/29c94ca31bd9e4a975d3)

ありがたいことに多くの方に記事をお読みいただき、個別にフィードバックをいただくこともありました。

さらに、本当に運が良いという言葉に尽きるのですが、11月に都内の自社開発企業様よりご縁をいただくことができ、12月よりWeb系エンジニアとして勤務しておりました。

今回は転職から1か月が経過したということで、転職活動の振り返りやWeb系エンジニアとして働いた感想など、簡単に共有していきたいと思います！

現在、同様に転職を考えている方のモチベーションや参考になれば幸いです！

# 転職活動を終えて

## 結果サマリ

転職活動期間は丸1か月程度、最終的な結果は以下の通りです。

- 応募：16社
- スカウト：36社
- 選考：10社
- 内定：1社

スタートアップ系企業様を中心に見ていたため、転職活動はwantedlyを使用しておりました。
ただ最終的には、Twitter経由でお声掛けいただいた都内にあるスタートアップ系の自社開発企業様に内定をいただき、入社いたしました。

## 評価いただいた点

選考の中で「企業様から評価いただいた」と特に感じた点は以下の通りです。

- ポートフォリオでフロントエンド・バックエンド・インフラまでカバーしている点
- ポートフォリオでやや難しめの技術(SPA、ECS、Terraformなど)にチャレンジしている点
- Qiitaにアウトプットしている点

これらの要素は言ってみれば、**しっかり動くものを作る、技術チャレンジをする、要約して人に伝える**というエンジニアに必要なスキルやマインドをアピールするために未経験者ができること、ということになるのではないかと考えています。

採用担当者の方にそれらのレベルが及第点だと感じていただければ、未経験でも選考ステップに何とか駒を進められる可能性はある、というのが今の所感です！

# エンジニアとして働いてみて

この1か月で感じたことや学びを共有します。

※ 記載してあることは個人の一意見に過ぎず、会社によって差はあると思います。あくまで参考程度に留めていただければ幸いです。

## 先輩エンジニアがとにかく優しい

これは一番最初に感じたことであり、私が入社を決断した大きな判断材料にもなったことですが、エンジニアの先輩方がとてつもなく優しく、人格的に優れた方ばかりです。

私は運良く入社前に未経験から入った先輩エンジニアと交流することができたのですが、このような機会は会社の雰囲気を掴むのにとても有益でした。

結果、入社した後も特にギャップを感じることなく働けているので、やはり**中の人と交流する**というのは企業研究の一環として間違いない手段だと感じました。

## ハイレベルなコード

入社前から想像はしていましたが、やはり実際のサービスで使われているソースコードはかなり膨大なものでした。(多くの人は一度は面食らうのではないでしょうか・・)

ただ、膨大でかつコメントもほとんど無いのに、読み易い、デベロッパーフレンドリーなコードでもあるとも感じました。

普段の業務でも変数名やメソッド名やクラスの責務など議論が飛び交っていますが、つまり妥協がないコードを積み上げ、高品質なコードを書いているためだと感じます。

このような環境であるゆえ、自分自身も**高品質なコーディング技術や設計技術**を身に付けて成長していけそうな期待感を持っています。

## 仕事のおもしろさ

現在はコードを読む、ということが頻繁にあるのでその点で挙げると、たくさんのユーザーに利用されているサービスが裏でどのように動いているかを知っていくプロセスはとても爽快です。
現在は昨日知らなかったことが今日わかるようになるという体験を毎日のようにしています。

たくさんのコードを読んで、仮説を立てて、デバッグしながら検証していく。
このようなサイクルを繰り返すことでシステム全体への理解が徐々に進んでいき、新たな事実が判明していきます。**パズルのピースがはまっていくような感覚**があり、とても楽しいプロセスと感じます。

# さいごに

簡単ですが以上となります！

2022年、エンジニア転職した自分にとって大きな変化のある1年でした。

ご縁あって素晴らしい環境に参画できたことに感謝すると共に、サービスへの貢献で還元できるよう、来月以降も引き続き頑張っていこうと思います。

最後までお読みいただきありがとうございました！！
webdataset のための tar のメモ

## 背景

昨今機械学習データ(主に画像)は tar で固めてメタデータは parquet/json で webdataset 形式が増えてきた気がします.

tar は `tar.bz2` とかで使っているがそもそも tar とはなんぞや?

## 情報

https://ja.wikipedia.org/wiki/Tar

http://52.198.195.249/2010/06/14/%E8%89%B2%E3%80%85%E3%81%AAtar%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88%E3%81%AE%E7%A2%BA%E8%AA%8D%E6%96%B9%E6%B3%95/

## webdataset の tar

webdataset の tar を dump すると @PaxHeader と出るので, Pax 形式ですかね.

```
00000000  2e 2f 2e 2f 40 50 61 78  48 65 61 64 65 72 00 00  |././@PaxHeader...
```

webdataset の tar ファイルはそんなに大きくないですが(分割の仕方にもよるが 100 ~ 200 MB くらい?), 毎回ファイル展開するのはめんどいですよね.
非圧縮なので mmap あたりで抽出できるはずです!

Python tarfile なら直読み出しできるっぽ?

https://docs.python.org/ja/3/library/tarfile.html

画像の場合これを使ってサムネイル生成とかで使えそうです!
Azure Container Instances 起動時に「Inaccessible Image...」エラーが出たとき確認すべきこと

## はじめに
Azure CLIやPythonを使ってでAzure Container Registry (以下ACR) からプルしたイメージでACIのコンテナーグループ作成する際に以下のようなエラーが出ることがありました。
```
Got exception in creating container group: 400 
.
.
.
azure.core.exceptions.HttpResponseError: (InaccessibleImage) The image '<レジストリサーバ名>/<イメージ名>:<バージョン>' in container group '<コンテナーグループ名>' is not accessible. Please check the image and registry credential. 
Code: InaccessibleImage Message: The image '<レジストリサーバ名>/<イメージ名>:<バージョン>' in container group '<コンテナーグループ名>' is not accessible. Please check the image and registry credential.
.
.
.
```
けっこう困ったので、当時の私が欲しかった情報をまとめてみました。本記事が少しでも誰かの役に立てると嬉しいです。

## 実行環境
- Windows 10 Pro
- Git Bash
    * git version 2.36.1.windows.1
- Azure CLI 2.42.0
- Python 3.10
## やった (やろうとした) こと
* [MS公式ACIチュートリアル](https://learn.microsoft.com/ja-jp/azure/container-instances/container-instances-tutorial-deploy-app)
* [Azure Container Instancesの定期実行をAzure Functionsのタイマートリガーで行う](https://torumakabe.github.io/post/aci-runner-on-functions/)

## 確認項目
- イメージ名とバージョンが正しいか
- サービスプリンシパルを使った認証の場合、ACRリポジトリのアクセス情報、AcrPull権限があるサービスプリンシパルIDとパスワードが正しいか
    * `registry-username`に指定するのは`principalName`、IDぽいのが複数あるので注意
    * パスワードを忘れた場合は再取得できないので新しくサービスプリンシパル作成した方が早い
    * サービスプリンシパルの代わりにマネージドID使った方が良さそう、パスワードが平文でコードに含まれちゃうので。。
- ACRレジストリがPrivateかつAzure SDK for Pythonを使っている場合
    * [これ](https://torumakabe.github.io/post/aci-runner-on-functions/)やろうとして、上記情報が正しいはずなのに本エラー
    * [Azure側のバグかも](https://github.com/Azure/azure-sdk-for-python/issues/16731
)、他の言語を使うのが無難
##  参考資料
- https://learn.microsoft.com/ja-jp/azure/container-registry/container-registry-auth-aci
- https://learn.microsoft.com/ja-jp/azure/container-instances/using-azure-container-registry-mi