OmniAICreator/Qiita-1.07M huggingface dataset:
'postmap /etc/postfix/sasl_passwd'したとき'postmap: fatal: parameter inet_interfaces: no local interface found for ::1'となったら

Dockerでpostfixいれて、mailtrapでメールを受けたいとき、
mailtrap曰く/etc/postfix/sasl_passwdを書かなきゃいけないんですが

そのとおりにやってると
```
postmap /etc/postfix/sasl_passwd                                                                                                                                  > [21/25] RUN postmap /etc/postfix/sasl_passwd:
#26 0.399 postmap: fatal: parameter inet_interfaces: no local interface found for ::1
```
とだめだよって・・

ぐぐるとipv6が使えないの/etc/hostsにあるから・・ということらしいので
じゃあその記述を抜いた/etc/hostsをDockerfileでCOPYしようとしたら
今度は
```
 => ERROR [20/25] RUN grep -v '::1' /etc/hosts > /etc/hosts                                                                                                                            0.3s
------
 > [20/25] RUN grep -v '::1' /etc/hosts > /etc/hosts:
#24 0.292 /bin/sh: /etc/hosts: Read-only file system
```
とhostsファイルをイジんじゃねぇとのこと・・

＼(^o^)／


ipv6使うつもりないからなぁ・・と見てたら


```/etc/postfix/main.cf
# Enable IPv4, and IPv6 if supported
inet_protocols = ALL
```

という記述を見つけたので
```/etc/postfix/main.cf
# Enable IPv4, and IPv6 if supported
inet_protocols = ipv4
```

としたらpostmap /etc/postfix/sasl_passwdは無事通りました！
AWS Single Sign On (SSO) メモ


## 概要

* AWS Organizationsと連携することで、複数のAWSアカウントへのシングルサインオンを実現するサービス
  * シングルサインオン
    * 1度のユーザー認証で複数システム（業務アプリやクラウドサービスなど）の利用が可能になる仕組み。
  * AWS Organizations
    * 複数のAWSアカウントを一元管理できるAWSサービス
    * 複数のAWSアカウントをグループ化し、グループごとに共通のポリシーを設定できる
    * 複数のAWSアカウントを「組織」として管理する
      * 組織内のAWSアカウントは「管理アカウント（マネジメント/マスターアカウント）」と「メンバーアカウント」に分けられる。

## 概念

* アクセス権限セット

  * AWS Organizationsのマネジメントアカウントから、ユーザごとのアクセス権限を一括管理する仕組み

    

## 機能

* **AWS Single Sign On ユーザーポータル**
  * AWS SSOでマネジメントコンソールにログインする為に開発者が参照する画面。
  * アカウント及び認可されたアクセス権限セットの一覧を参照できる。

* **AWS Organizations との統合**
  * 組織内全てのAWSアカウントにアクセスし、管理することが出来るようになる。
    * マスターアカウントでAWS SSO連携を有効にすることでAWSコンソールへのSSOアクセスが可能になる。
* **Active Directory との連携**
  * Active Directoryの認証情報を利用してAWSにログインすることが可能になる。

## メリット

* **ID の作成と接続を1 か所に集約できる**
  * SSO自体のユーザー・グループ管理オプションの利用
  * MS Active Directoryなどの外部サービスと連携
* **複数の AWS アカウントに対するアクセスを一元管理できる**
  * AWS Organizations との統合により、複数のアカウントへのアクセス管理が可能となる。
  * 個々のアカウントにおける追加の設定は不要。
  * 共通の職務をもとにユーザー権限を割り当て、個々のセキュリティ要件に合うようカスタマイズできる。
* **クラウドアプリケーションへのアクセスを管理できる**
  * ディレクトリの認証情報を使用し、AWS SSO ウェブユーザーポータルにサインインすることで、Amazon SageMaker Studio、AWS Systems Manager Change Manager、その他クラウドアプリ(Salesforce や Box、Microsoft 365 ほか) などにアクセスできる。

## 大まかな設定の流れ

1. AWS SSOの有効化

   * AWS OrganizationのメンバーアカウントとSSOを紐づける

2. IDソースの選択

   * SSOの独自IDストアを作成・使用
   * 既存のActive Directoryを使用
   * 既存の外部IDプロバイダーを使用

3. AWSアカウントへのSSO設定

   * アカウントにユーザー・グループ・アクセス権限セットを紐づける

   

## 参考情報

* [AWS Single Sign-On ユーザーガイド](https://docs.aws.amazon.com/ja_jp/singlesignon/latest/userguide/what-is.html)
Amazon ECS デプロイ中のイメージタグバージョン確認方法


* ECSにデプロイ中のコンテナイメージバージョンをわざわざAWSコンソールを開かずに確認したかったため、スクリプトを作成した。メモとして残しておく。

## スクリプト

* check_ecs_image_tag.sh

```shell
#!/bin/sh

# AWSリージョン
AWS_REGION="YOUR_AWS_REGION"
# AWsアカウント
AWS_ACCOUNT="YOUR_AWS_ACCOUNT"

# ECS タスクファミリー
TASK_FAMILY_PREFIX_ARRAY=(
    "dev-ecs-app"
    "stg-ecs-app"
)

#aws configure

for tfp in "${TASK_FAMILY_PREFIX_ARRAY[@]}"
do
    currnet_task_version=$(aws ecs list-task-definitions --family-prefix $tfp | jq '.taskDefinitionArns[-1]' | sed -e 's/arn:aws:ecs:`${AWS_REGION}`:`${AWS_ACCOUNT}`:task-definition\///g' | sed 's/''//g')
    echo $tfp`aws ecs describe-task-definition --task-definition $currnet_task_version | jq .taskDefinition.containerDefinitions[0].image`
done
```



## 実行結果

```shell
sh check_ecs_image_tag.sh
dev-ecs-app "YOUR_AWS_ACCOUNT.dkr.ecr.YOUR_AWS_REGION.amazonaws.com/YOUR_ECS_TASK:image_tag_version"
stg-ecs-app "YOUR_AWS_ACCOUNT.dkr.ecr.YOUR_AWS_REGION.amazonaws.com/YOUR_ECS_TASK:image_tag_version"
```



## 参考情報

* https://docs.aws.amazon.com/cli/latest/reference/ecs/
swaggerをvscodeで書いてみた

# swagger Viewer

RESTful APIの使用を記述するフォーマットにOpenAPIという規格があり、
OpenAPIを使用するツールにSwaggerがあります。

VSCodeでAPI仕様書を書きたい。
そんなときはSwagger Viewerを使いましょう。
拡張機能をインストールします。

https://marketplace.visualstudio.com/items?itemName=Arjun.swagger-viewer

# swaggerの書き方

```yaml
swagger: "2.0"

info:
  version: "1.0.0"
  title: users
paths:
  /users:
    get:
      description: ユーザー情報を取得する
      parameters:
        - name: name
          in: query
          description: user name
          type: string
      responses:
        200:
          description: Successful response
          schema:
            title: ArrayOfUsers
            type: array
            items:
              title: User
              type: object
              properties:
                name:
                  type: string

```

## info

ドキュメントのバージョン、タイトルを記述します。

## paths

`paths`にエンドポイントを記述します。
リソースIDを利用する場合は以下のように記述します。

``` yaml
paths:
  /user/{id}
```

HTTPメソッドを指定し、`description`に説明を記述します。
`parameters`にHTTPパラメータを記述し、`responses`にレスポンス情報を記述します。
```yaml
paths:
  /users:
    get:
      description:
      parameters:
      responses:
```

### parameters

| 名前 | 説明 |
|:-|:-|
| name  | パラメータ名  |
| in  | query: /users?id=1　<br> path: /users/{id}  |
| description  | パラメータの説明  |
| required  | 必須か否か  |
| type  | 型  |

### responses

| 名前 | 説明 |
|:-|:-|
| description  | レスポンスの説明  |
| schema  | レスポンスの値  |
| type  | 型  |
| items  | 中身  |
| properties  | プロパティ情報 |
Electron Build Tools でバイナリビルドしようとして goma_ctl.py で文字コードエラーが出る場合の解決法

Windows の日本語環境で Electron のバイナリ本体を [Electron Build Tools](https://github.com/electron/build-tools) でビルドしようとしたら、goma_ctl.py で以下のようなエラーが出た。

```
Traceback (most recent call last):
(省略)
  File "~\.electron_build_tools\third_party\goma\goma_ctl.py", line 133, in _DecodeBytesOnPython3
    return data.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8f in position 0: invalid start byte
```

# 解決法
エラーが出た goma_ctl.py の `_DecodeBytesOnPython3` 関数内にある行を以下のように書き換える。
```diff_python:goma_ctl.py
def _DecodeBytesOnPython3(data):
  """This function decodes bytes type on python3."""
  if isinstance(data, bytes) and sys.version_info.major == 3:
-   return data.decode('utf-8')
+   return data.decode('shift-jis')
  return data
```

今回のエラーの発端であるバイト `0x8f` は SJIS では有効なものなので、Windows のマルチバイト文字が SJIS 設定になっているのが今回の原因だと推測。Windows の設定で UTF-8 を使用するように変更しても解決しそう。
laravel バリデーション regex

## 概要

- POSTされた値の範囲をバリデートするバリデーションルール`rangx`についてまとめる。

## 記載方法

- バリデートしたい値の範囲は正規表現を用いて定義する。
- 「ハイフン無し郵便番号を文字列で受け取りたい。しかし数字だけに限定したい。。」場合などに使えそう。
- 下記のように記載する。
- 「文字列OK、ただし0~9までの数字のみ」のルールを記載する。（`stringバリデーションルールと組み合わせているがrangx`だけでも使える）

    ```formRequest.php
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'content' => ['string', 'regex:/^[0-9]+$/'],
        ];
    }
    ```

- 「文字列OK、ただし特殊文字はNG」

    ```formRequest.php
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'content' => ['string', 'regex:/^[0-9a-zA-Z]+$/'],
        ];
    }
    ```

## ご注意

- 当該バリデーションルールは内部でPHPのpreg_match関数を実行している。そのためpreg_match関数のフォーマットで値範囲を指定して上げる必要あり。
    - [https://www.php.net/manual/ja/function.preg-match.php](https://www.php.net/manual/ja/function.preg-match.php)
- バリデーションルールを複数記載する場合に区切りを`|`で区切る方法があるが`rengx`を使うときは使用できない。上記の例のように配列を用いてバリデーションルールを記載すること。


## 参考文献

- [https://readouble.com/laravel/8.x/ja/validation.html#rule-regex](https://readouble.com/laravel/8.x/ja/validation.html#rule-regex)
Djangoでデータベース構築時のエラー解消法（Python3.8)

# はじめに
Python3.8でDjangoのデータベースを構築した際にPython3.8の仕様変更でエラーになった箇所の
解消法をまとめた

# 環境
下記の各種バージョンで実施
```
$ python3 --version
Python 3.8.9

$ python3 -m django --version
4.0.5
```

# エラー1
ひとまず、マイグレーションを実行
```
python3 manage.py makemigrations

...(略)
'NAME': BASE_DIR / 'db.sqlite3',
TypeError: unsupported operand type(s) for /: 'str' and 'str'
```

'NAME'のvalue値の書き方でエラー発生
```setting.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
```
↓
下記へ変更
```setting.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR + 'db.sqlite3',
    }
}
```

もう一度実行します
```
python3 manage.py makemigrations

Migrations for 'sample':
...(略)
```

エラー解消し、正常終了しました

追加があれば都度更新していきます
【Power Shell】ネットワークドライブの割り当てをスクリプトで実行する。

共有フォルダにネットワークドライブの割り当てを行っておりましたが、度々ネットワークドライブの割り当てが解除されているような事象が発生致しました。
都度割り当てを行う・共有フォルダのパスを入力する等でアクセスは行えました。

しかし、上記の事を知らない場合は対応出来ない事もあります。
知らない方に都度説明を行う事が難しいので、ネットワークドライブの割り当てを行うスクリプトを作成する事としました。

ネットワークドライブの割り当てを行う際は、net useコマンドを使用します。下記はコマンド実行イメージとなります。

```:Sample
PS C:\> net use "ドライブレター" "フォルダパス"
コマンドは正常に終了しました。
```

まだ使用されていないドライブレターに割り当てを行えればよいと考え、For Each文で対応する事とします。

まず、変数・配列を定義します。
配列Arrayに割り当ててもよいドライブレターを設定します。x/y/zでいずれかで割り当てを行いたかったので、そのように設定しました。
New-Objectコマンドで、オブジェクトを作成します。(ポップアップでコマンドの結果をユーザーにお知らせしたい意図があります。)

```:変数・配列定義
#割り当て対象
$Array = @("x:","y:","z:")
#フォルダパス
$File_Path = "フォルダパス"
#オブジェクトのセット
$Ws_Obj = New-Object -ComObject wscript.shell
#カウンター
$Count_Array = 0
```

処理は下記となります。
配列Arrayで定義しているドライブレターをTest-Pathコマンドで既に割り振られていないかの確認を行っています。
存在しない場合は、net useコマンドの実行を行います。その後、breakで処理を終了します。
変数Count_Arrayはカウンターです。処理が3回行われて、配列Arrayに存在するドライブレターが全て割り振られていた場合はポップアップでその旨をユーザーにお知らせします。

```:メイン処理
#割り当てされていないファイルパスを検索
foreach($Network_Drive in $Array){
       
       $Count_Array += 1

       if (-not(test-path $Network_Drive)){
            
            net use $Network_Drive $File_Path
            $Msg_Box = $Ws_Obj.popup($Network_Drive + "に割り当てを行いました。")
            break
       
       }
       
       elseif($Count_Array -eq 3){
            
            $Msg_Box = $Ws_Obj.popup("配列Arrary内で定義しているドライブは既に割り振られています。")

       }

}

```

あまり使用する機会は思いつかないですが、何かの役に立てば幸いです。
laravel バリデーション in

## 概要

- POSTされた値が指定した値のいずれかであることをバリデートするバリデーションルール`in`をまとめる。

## 記載方法

- 下記のように記載することで`in`バリデーションルールを設定できる。
- 配列で指定する方法（POSTされた値が0 or 1であることをバリデートするルール）


    ```formRequest.php
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'content' => ['in:0,1'],
        ];
    }
    ```

- 配列で指定する方法（POSTされた値がint型の0 or int型の1であることをバリデートするルール）


    ```formRequest.php
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'content' => ['integer', 'in:0,1'],
        ];
    }
    ```

- Ruleバリデーションルールクラスを用いる方法　（POSTされた値が0 or 1であることをバリデートするルール）

    ```formRequest.php
    use Illuminate\Validation\Rule;

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'content' => Rule::in([0, 1]),
        ];
    }
    ```

- もちろん文字列も指定可能

    ```formRequest.php
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'content' => ['in:foo,var'],
        ];
    }
    ```

- 文字列でinバリデーションを用いるならstringバリデーションも併用したほうがよいかもしれない

    ```formRequest.php
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'content' => ['string', 'in:foo,var'],
        ];
    }
    ```

## 応用

- 本バリデーションルールを用いれば、受け取る値を限定する事ができる。「指定した単独の値しか通過させたくない」場合に使える。
- 例えばcontentの値を1のみ通したい場合、下記のようにinの引数で配列で1だけを指定すれば「1は通す、1以外は通さない」ことが可能

    ```formRequest.php
    use Illuminate\Validation\Rule;

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'content' => Rule::in([1]),
        ];
    }
    ```

- 配列で指定すると下記のようになる。多分こちらのほうが一般的

    ```formRequest.php
    use Illuminate\Validation\Rule;

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'content' => [in:1],
        ];
    }
    ```

## 参考文献

- [https://readouble.com/laravel/8.x/ja/validation.html#rule-in](https://readouble.com/laravel/8.x/ja/validation.html#rule-in)
FreeBSD SSH kex_exchange_identification 対策

# 0x1 現象
Freebsd 13.0から13.1へのアップグレードでは、次回の再起動時にこのエラーが表示される場合があります。

多分別のバージョンが発生する可能性があります。

# 0x2 原因
これは、システムに付属のsshdがアップグレードされていないためです。

しかし、エラーメッセージは同じではありません。

# 0x3 対策
sshの代わりにopensshを使用します。
```shell
pkg install openssh-portable
# portを使用することもできます
cd /usr/ports/security/openssh-portable/ && make install clean
```
opensshに変更
```shell
sysrc openssh_enable="YES"
sysrc sshd_enable="NO"
```
設定ファイルの変更を忘れないでください
```shell
nano /usr/local/etc/ssh/sshd_config
# viを使用することもできます
vi /usr/local/etc/ssh/sshd_config
```
openssh起動
```shell
service openssh start
```

# 0x4 
Freebsdは比較的安定したOSですが、いくつかの厄介な例外が発生することがあります。 

アップグレードして実行する前に、テスト環境でシステムを確認することをお勧めします。
awsで実現するsagaパターン(コレオグラフィ編)

# 概要

* マイクロサービスで複数のリソースの結果整合性を利用する方法として、**sagaパターン**というものがあります。

**sagaパターンについては過去記事をご参照ください。**

https://qiita.com/yoshii0110/items/4ae10eb071565cb90b37

* **今回は、sagaパターンにおけるコレオグラフィをAWSで実現するにはという内容で切り込んでいこうと思います。**

## Choreography(コレオグラフィ)とは

* Sagaパターンであるコレオグラフィは、中央集権的な調整(コントローラ)の必要性を避けて、**参加する要素がイベントを交換します。**
* コレオグラフィを使用すると、**他のサービスでローカルトランザクションをトリガーするイベントが各ローカルトランザクションによって発行されます。**
* もう少し簡単に説明すると必要なすべての情報を含んだ最初のイベントを1つのメッセージに保存しておき、最初のトランザクションを完了させます。
* その後、その他のサービスがそのメッセージを非同期的に取得し、それぞれのタスクを完了させるような動きとなります。
* イメージ的には、下記のようになります。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3536333633352f39393864633534392d646133632d376239382d393638392d6337303430613835316530302e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/062082dd-f273-b549-55a2-a40eb0054b1d.png)

## AWSで実現するChoreography(コレオグラフィ)

* このアーキテクチャの特徴は、サービスが疎結合になる為、直接互いがお互いに影響を与えません。
* さらにメッセージの保存と取得が非同期の関係になる為、**スケーラビリティという観点**と**信頼性の観点**でも利点があるといえます。

* **下記に示すのはあくまでawsで実現する時の一例となります。**
* あるサービスからのリクエストをSNSを使用し受けます。
* その後、そのリクエストをSQSを使用しキューに保存し、その後の処理にLambdaを使用します。
* このサービスのポイントとしてはキューにSQSを使用することでauto scalingの設定も簡単にできるためスケーラビリティという観点を満たすことができます。
* また、キューのアルゴリズムとしてFIFOを選択することで処理順の担保もできるのではないでしょうか。

![Untitled(2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/a83cfcce-c7de-7ea5-84ed-5b71d1029a9b.png)


# 参考

https://qiita.com/yoshii0110/items/4ae10eb071565cb90b37

https://d1.awsstatic.com/whitepapers/ja_JP/modern-application-development-on-aws.pdf?did=wp_card&trk=wp_card
バッチ実行でコマンドプロンプトを表示させない

# バッチ実行でコマンドプロンプトを表示させない設定方法
バッチを定期実行させる場合などに、PC画面に急にコマンドプロンプトが表示されるのを防止できます。
「コマンドプロンプトで確認する必要がない内容である」「実行履歴は別のファイルとして残す」場合にコマンドプロンプトは邪魔になるのでバッチ処理で表示させないようにしたいと思いました。

### この記事で出来ること
* コマンドプロンプトを表示させずにバッチ処理を実行可能
* タスクスケジューラでも上記仕様が可能


# 環境
windows 10
実行させるバッチファイル名：undisplay.bat

実行させるファイルは適宜自分のファイルに置き換えて、以下設定をしてください。


# vbsファイルを作成する
vbsファイルを作成します。
vbsファイル名は、わかりやすいようにバッチファイルと同じ(undisplay)にしました。
```:undisplay.vbs
Set ws = CreateObject("Wscript.Shell")
ws.run "cmd /c ファイル名.bat", vbhide
```

注意点として、上記設定内容はvbsファイルを、バッチファイルと同じディレクトリの階層に置いた場合の設定になります。

もし、他の場所にvbsファイルを配置する際は２行目の「ファイル名.bat」部分を、絶対パスに変更してください。
絶対パスの例：`C:\Users\test\desktop\undisplay.bat`

# タスクスケジューラの設定
タスクスケジューラの基本的な設定方法は説明しません。
既にundisplay.batのタスクスケジューラ設定済みを想定しています。

1. タスクの編集をする
1. 「操作」タブを選択する
1. 設定されている操作の編集をする
1. プログラム/スクリプト(P):の項目をバッチファイルから作成したvsbファイルに変更する（以下画像例）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/748917/bf33e4fd-b32f-538e-21f4-3b07975f5a52.png)

vsbファイルを設定することにより、コマンドプロンプトを表示させずにバッチ処理が可能になります。

# まとめ
バッチファイルをコマンドプロンプトを表示させずに実行させる方法
* vbsファイルを作成する
* vbsファイル →　バッチファイル　という流れで実行させる
* タスクスケジューラの実行ファイルをvbsファイルに変更する
【Rails】投稿記事の公開・非公開機能を実装する


投稿記事に公開・非公開機能をラジオボタンで実装したので記録を残します！
間違っている箇所があればご指摘頂けると大変助かります(_ _).｡o○


##### 前提
・Deviseログイン機能実装済
・Postテーブルにboolean型でカラム追加(今回のカラム名：is_published_flag）

#### Postモデルに条件式を定義

```ruby:/app/controllers/posts_controller.rb

class Post < ApplicationRecord
  belongs_to :user

  # 公開・非公開機能
  scope :published, -> {where(is_published_flag: true)}
  scope :unpublished, -> {where(is_published_flag: false)}
   ~省略~
end
```
scope :スコープの名前, -> { 条件式 }
公開・非公開を見分けられるように条件式を書きます。

#### Postsコントローラー

```ruby:/app/controllers/posts_controller.rb

class PostsController < ApplicationController
  before_action :authenticate_user!, only: [:create, :edit, :update, :destroy]

  def index
    @posts = Post.published
  end
~省略~
```

一覧ページのindexには、公開された記事のみ表示させたいので、```@post = Post.published```とします。


#### ラジオボタンの実装
true,falseで値を送信
true:publish
false：unpublished

```
~省略~
       <div>
         <%= f.label :is_published_flag, "公開", value: true %>
         <%= f.radio_button :is_published_flag, 'true' %>
       </div>
       <div>
         <%= f.label :is_published_flag, "非公開", value: false %>
         <%= f.radio_button :is_published_flag,'false' %>
       </div>
~省略~
```

以上のコードで無事に公開・非公開機能を実装しましたฅ( ˙꒳​˙ ฅ)



・参考記事：https://pikawaka.com/rails/scope
「Google Maps の検索結果から Yahoo! カーナビで経路案内できる iOS ショートカット」を再復活させた

# はじめに
@otchyさんと、@musubi05さんが作成していた「Google Mapsと Yahoo!カーナビのiOSショートカット連携」の再改修版です．

:::note warn
重要
この記事は明確な解決方法があるわけではありません．
デバッグ途中に動作したため、とりあえず残しておくというような結果となっています．
:::

# 共有URL（2022/06/12）

タップするとショートカットに追加できます

https://www.icloud.com/shortcuts/9280a473a4904845b74f982db7938cd7

# 改修

## 改修点

v4では、緯度・経度をショートカットで取得して、Y!カーナビで表示させるパラメータとして与えていました．ある日から、緯度・経度をショートカットで取得する部分で、緯度・経度が双方とも0になってしまっていました．その部分の修正です．

## やったこと

住所から緯度・経度を取得する前に、現在地を取得するコマンドを追加しました．
追加した理由ですが…、エンジニアあるあるとして有名なことですが、よくわかっていません．

よくわからんけど **なんか動いた** ってやつです．

これから調査していくために、現状報告も兼ねて、この結果に至るまでの思考と試行を書き連ねます．

# 思考と試行

1. 緯度・経度が0になってしまっていることを発見
2. 正しく住所が取れているか確認（皇居の住所）
![79E25CD2-8B17-464C-A1F2-7026C5D1DBBC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2256398/8558bb5f-6c9a-ec2d-7f65-eb1ea30314a6.png)

3. 緯度・経度取得に問題があると確定
下記の画像の、緯度（経度）を住所から取得のコマンド部分
![64F23FD1-6B62-423A-BB4B-FCDC1ECF13E4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2256398/06bd3de9-0955-4ffb-2c27-cec4d9a464b2.png)

4. 試しに現在地の緯度・経度取得が可能か確認 →　正常に動作
5. 現在地の緯度・経度であればカーナビが動くか確認　→　正常に動作
6. 一旦指定する緯度・経度を元の住所に戻す（Googleマップで指定した場所）
4と5で利用した現在地の取得コマンドを放置していたら、なぜか動作した．住所取得と緯度経度を取得の間に、現在地の取得コマンドがあれば動く...？

# おわりに

とりあえず使えるもの（今のところは）にしたという内容ではあります．引き続き調査はしていきますが、何かこういう理由ではないかという情報をお持ちの方は、ぜひコメントいただきたいです
Amazon Transcribeで音声の文字おこし

# はじめに

文字起こしのチュートリアルを実践しました。

https://aws.amazon.com/jp/getting-started/hands-on/create-audio-transcript-transcribe/

用意されたmp3ファイルをS3に置いて、文字起こしをするようです。

# S3にMP3を配置する

準備されたmp3ファイルをS3に配置してURLをコピーしておきます。

余談ですが、S3は配置したファイルをWeb上で開くことができるようになりました。mp3ファイルもS3上でダウンロードすることなく聞くことができます。

# 文字起こしジョブをCreateする

1. Amazon Transcribeのコンソールを開きます。こちらはまだ日本語化されていないようです。
1. Languageで英語(English, US (en-US)を選択し、input dataとして先ほどS3に置いたmp3ファイルを指定してそのまま次へ次へとクリックしていくとジョブが開始されます。
1. ```in progress```と表示されているステータスが```Complete```になったところで完了したジョブをクリックして開いてみると、文字起こしされたテキストを参照することができるようになります。サンプル用のファイルを使っただけあってうまく文字起こしされているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/5c6e98f8-56da-cb67-0be1-9dbaa91e0a72.png)

文字起こしの結果は単語ごとにその確度が記録されており、json形式でダウンロードすることもできるようになっています。

# 日本語の文字起こし
そうなると気になると、今度は日本語でも使えるのか、ということです。
1. Windowsのボイスレコーダーというアプリで、青空文庫から「[坊ちゃん](https://www.aozora.gr.jp/cards/000148/files/752_14964.html)」の1節を録音します。ファイル名を```bochan.m4a```とします。
1. 同じようにs3にアップロードしてtranscriptを行います。もちろんLanguageはJapanese, JP (ja-JP)を選択します。
1. 58秒あるファイルですが、45秒でジョブが完了しました。結果は下記の通り。普通の単語の音はだいたい聞き取ってくれましたが、いくつか日本語的な問題は見られました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/9e03724b-f4b9-092d-9298-7c297342cd76.png)
    1. 令和の現代ではあまり使われない「時分」や「小使い」はさすがに誤変換されている。
    1. 同級生のせりふ「弱虫やーい」は「弱虫焼いて」としているものの、確度55.21%と何かが違うような自覚あり。
    1. 句読点の位置が変。
1. 題材がよくなかったかもしれないので今度は[AWSのサイト](https://aws.amazon.com/jp/cloud/)から1節を録音して試してみました。やはり、句読点以外はほとんどOKのようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/41984625-52bd-e61a-d473-5356eeb7f454.png)

# おわりに
会議の議事録作り等で利用するのはまだ難しそうです。利用が増えればAIがどんどん学習して精度も上がるように思いますが、日本ではまだあまり使われていないのかもしれません。
AWS Fargateからherokuに移行した話

## はじめに
※ 自分用メモ
awsの無料期間がそろそろ切れそうなので、バックエンドをherokuに移行したお話


## 移行前
#### バックエンド
言語・フレームワーク: Ruby、 Ruby on Rails
インフラ： AWS ECS(Fargate)、ECR、Route53(ドメイン取得はお名前.com)、RDS(Mysql)無料枠があるから、Auroraではない、ALB、ACM、S3、EFS

#### フロントエンド
言語・フレームワーク: React、NextJs
インフラ：　バックエンドと同じ

#### ミドルウェア
webサーバー： Nginx
DB： mysql

## 移行後
#### バックエンド
言語・フレームワーク: Ruby、 Ruby on Rails
ミドルウェア： Nginx、mysql
インフラ： heroku、jawsdb、S3

#### フロントエンド
言語・フレームワーク: React、NextJs
インフラ：　vercel、Route53(ドメイン取得はお名前.com)、ACM


### バックエンド移行(aws ⇨ heroku)
#### アプリケーション
自分はm1 macなので↓以下の記事をそのまま実行でok
https://zenn.dev/daku10/articles/m1-heroku-container-trouble-exec-format-error

#### DB
dbはmysqlを使っていたので、移行後のdbもmysqlを使いたいということでjawsdbというのがherokuのアドオンで簡単に実装できる。
※ 他にもcleardbというのでもmysqlを使えるがmysql8.0が対応していない
jawsは↓この記事が参考になる
https://zenn.dev/junki555/articles/68d2186822d4cf

次にRDSにログインし、ダンプファイルを作成後herokuコマンドでインサート文を流していく


フロントエンド移行（aws ⇨ vercel）
vercelデプロイ
vercelのdomainのAレコードをRoute53のホストゾーンに追記する


### 所感
ずっと移行がめんどくさくてやっていなかったが、意外とスムーズ(丸1日もかからなかった)に移行ができた。もっと早く移行しとけばaws代が浮いた。herokuは30分リクエストがないとスリープしてしまうので、30分おきに自動アクセスするbotを作ろうと思ったが、スリープしても意外とすぐ起動するのでやらないことにした。
これにて移行完了！！🎉
Jetpack Compose 勉強記録その3 (Jetpack Compose チュートリアル レッスン:4)



Jetpack Compose 勉強記録その3です。

# 今回の内容

https://developer.android.com/jetpack/compose/tutorial?hl=ja


チュートリアルの続きをやっていきます。

今回はレッスン 4:リストとアニメーションをやっていきます。

リストは必ず使うと言っても過言では無いので、気になります。

# メッセージのリストを作成する

```MainActivity.kt
@Composable
fun MessageCard(messages: List<Message>) {
    LazyColumn {
        items(messages) { message ->
            CardItem(message)
        }
    }
}
```

``LazyColumn``　``LazyRow``
こちらを使用する事でリストを表示する事が出来るみたいです。
``LazyColumn``は縦のリストです。

``LazyRow``は横のリストです。

``items``に渡したデータを元にリストを作成していきます

``items``に渡したitemをラムダで受け取りレイアウトを作成するComposableの関数``CardItem``に渡して作成しています。


# メッセージに展開アニメーションを実装する

```MainActivity.kt
var isExpanded by remember { mutableStateOf(false) }

 Column(modifier = Modifier.clickable { isExpanded = !isExpanded })
```

``remember``を使用しローカルの UI 状態を保存します。
``mutableStateOf``に渡されているデータに変更があると自動的に再描画されるみたいです。


```MainActivity.kt
 Text(text = message.body,
    color = MaterialTheme.colors.secondaryVa
    modifier = Modifier.padding(all = 4.dp),
    maxLines = if (isExpanded) Int.MAX_VALUE
    style = MaterialTheme.typography.body2)
```

``maxLines = if (isExpanded) Int.MAX_VALUE``を設定しておくとタップされたセルは全文表示になります。


```MainActivity.kt
Surface(modifier = Modifier.animateContentSize().padding(1.dp))
```

先ほど設定した全文表示になる時にコンテナのサイズを滑らかにアニメーション化する事が出来るみたいです。


以上でチュートリアルは終わりになりました。

これだけでは作れるものが限られてしまう為、まだまだJetpack Composeについて調べて実装し、勉強記録を残していこうと思います。
【初心者】プログラムを作る材料5つ　その１「コンピュータ」

# はじめに
IT歴2ヶ月の初心者プログラマー鹿太郎です。
初心者なりに感じた疑問や分からないことを発信していきたいと思います！

まずはこちら！
「プログラムってどうやって作るの？」です！
今回はその材料の一つである、「コンピュータ」についてまとめました！
早速いきましょう！

# コンピュータ
コンピュータとは、電子回路を用いて計算を実行する機械のことです。
・・・
そんなことは分かってるよ！って感じですね。
詳しく見ていきましょう。

コンピュータは以下の５つの要素で構成されています。
## ①演算装置
データに対して、四則演算や論理演算などの演算を行う役割を担う装置のことです。
後述する制御装置とともに、CPU（中央処理装置）に実装されています。

## ②制御装置
言葉通り、他の装置の制御を行う装置のことです。
他の４つの装置を制御する親分的な役割ですね。
上記の演算装置とともに、CPU（中央処理装置）に実装されています。

## ③入力装置
コンピュータに命令やデータを与える役割を担う装置のことです。
これはイメージがつきやすいのではないでしょうか。
マウスやキーボードなどがこれに該当します。

## ④出力装置
入力装置の逆です。
命令やデータの結果を表示する装置です。
ディスプレイやプリンタがこれに該当します。

## ⑤記憶装置
こちらも言葉通り、データを記憶する装置です。
メモリやハードディスクなどがこれに該当します。




#  
以上、５つがコンピュータを構成している材料でした！
初歩的な内容ですが、用語の意味を正しく知っておかないと
のちのち分からないことが積み重なって
大変なことになりますので、ひとつずつ着実に
理解していきましょう！

次は、プログラムの材料その２！「OS」について、紹介したいと思います！
ではまた。
Nesterov加速勾配法

# Nesterovの加速勾配法とは

数値最適化における反復法はある関数$f:\mathbb{R}^m \rightarrow \mathbb{R}^n$に対して、適当な探索方向$d_k$を定義して

```math
x_k \rightarrow x_k + d_k
```

と更新する方法です。ただし、$d_k$は降下方向でなければならないので、

```math
\lim_{ c \rightarrow 0 } \frac{ f(x_k+cd_k) - f(x_k) }{c} = \nabla f^T(x_k) \cdot d_k < 0
```

を満たす必要があります。一番簡単なのは$d_k = -\nabla f(x_k)$とする最急降下法です。
しかし、このままでは収束性があまりよくありません。そこでこの収束性をよくする手法の１つがNesterovの加速勾配法です。更新の手順は次のようになります。

```math
x_0 = y_0 \\
x_{k+1} = y_k - \alpha_kf(y_k)\\
y_{k+1} = x_{k+1} + \beta_k (x_{k+1} x_k) \\
(k=0,1,2,\cdots)
```

パラメーター$\alpha_k$,$\beta_k$のとり方の１例として

```math
\alpha_k = const. = \frac{1}{L} \\
\beta = \frac{k}{k+3}
```
があります($L$はステップ数)。

# 実装

Nesterovの加速勾配法で最適化を行うクラスをつくりました。引数には目的関数とその微分を与えます。例として

```math
f(x) = |b - Ax|^2
```

を目的関数としました。

```math
b = A(1,1,\cdots,1)^T
```

としたので、$w = (1,1,\cdots,1)^T$で$f$が最小となります。


```nesterov.py
import numpy as np
from numpy import linalg as LA
from functools import partial

def f(w,A,b):
    v1 = b-A@w
    return v1.dot(v1)

def df(w,A,b):
    AA = (A.T).dot(A)
    return -2*A.T@b + 2*AA@w

class NesterovAccelaratedGradient:
   
    def __init__(self,df,threshold):
        self.df = df
        self.threshold = threshold

    def optim(self,w_ini,steps):
        #initial guess
        w = w_ini
        v= w.copy()
        err_list = []
        for i in range(steps):
            dv = self.df(v)
            err = LA.norm(dv)
            wn = v - 1/steps*dv
            err_list.append(err)
            if err<self.threshold:
                return wn,err_list
            v = wn + i/(i+3)*(wn-w)
            w=wn.copy()
        print("not converged")
        return wn,err_list

# m<n
m = 3
n = 5

A = np.array([[0.59, 0.99, 0.81, 0.56, 0.75],
       [0.62, 0.56, 0.96, 0.9 , 0.97],
       [0.91, 0.03, 0.46, 0.58, 0.21]])
b = A@np.ones(n)

steps=100000
threshold = 1e-3

w_ini = np.ones(n) + 0.01*np.random.random(n)

NAG = NesterovAccelaratedGradient(partial(df,A=A,b=b),threshold)
w_opt,err_list_NAG = NAG.optim(w_ini,steps)

from matplotlib import pyplot as plt
plt.plot(err_list0_NAG)
plt.yscale("log")
plt.legend()
plt.xlabel("iteration")
plt.ylabel("error")
plt.savefig("NAG.pdf")
```


実行結果を見てみます。誤差$|\nabla f|$の反復回数に対する変化をプロットすると、最適化の過程は次のようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2445529/5c7a18b2-786f-cf1b-723b-c311018118c2.png)

最急降下法(SD)とNesterovの加速勾配法(NAG)の収束性をを比べると次のようになり、確かに改善しています(両軸ともlogスケール)。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2445529/81536ab9-dde9-932d-c9e2-80fff8360d73.png)

また、最終的なoptimalなパラメーターは

```math
w_{opt} = (1.00133097, 0.99971504, 0.99921629, 0.99674919, 1.00312895)
```

となっていて、確かに$(1,1,\cdots,1)$に近い値になっています。停止条件が$|\nabla f | <10^{-3}$なので、誤差はこのくらいで妥当でしょう。
【typescript・eslint】awaitを忘れないようにしたい

初書：2022/06/18

# 前書き

Promiseを使う際に、順番通りに実行する必要があるコードだと、awaitを使って処理結果を待つことがある。
ただ、await自体は必須ワードではないので、つい書き忘れてしまい、その結果意図しないコードが出来ることがある。
と言うことで、エディター側で書き忘れていたらエラーが出るようにしたいと言うのが今回のお話。

# 前提

typescriptとeslintを使っていること。

# コード例

```ts
async function outputDataToConsole() {
  const data = getData(); // promise<object>
  console.log(data);
}
```

とても適当に用意したコード。
この中の`getData`がPromiseで例えばデータベースに接続して取得するようなコードだとしよう。
このコードを実行した場合、その下の`console.log`で出力されるのはpromise自体で、
データが出力されない。
これを防ぐために、`getData`のところでエラーが出るようにしたい。

# 対策

tslintに`no-floating-promises`と言うものがあり、
これを使うことでawaitのところでエラーが出るようになる。

```json:.eslintrc.json
  "overrides": [
    {
      "files": ["**/*.ts"],
      "rules": {
        "@typescript-eslint/no-floating-promises": "error"
      },
      "parserOptions": {
        "project": ["./tsconfig.json"]
      }
    }
  ]
```

typescriptのeslintのため、`overrides`のところに記述している。
これで、awaitを書き忘れるとエラーが出るようになった。

# 参考サイト

[「意図的なawait書き忘れ問題」との戦い方を考える ~JavaScriptと非同期処理の話~ - Qiita](https://qiita.com/KuwaK/items/f3ce503da410ac86325b)
Canvas Setting

メモです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374827/1d590e9f-9a7b-79a3-7eb9-3cbfc4e66644.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374827/3d739cc4-2530-01a2-4be4-9075d9859342.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374827/459d228f-38fd-6fb6-7a74-7594f223bef2.png)
Laravelでハッシュ化したいんですけどっ！！？

表題の通りです。

本ページではLaravelドキュメントの「[ハッシュ](https://readouble.com/laravel/8.x/ja/hashing.html)」についてのページを最低限理解できるようにかみ砕いたものです！

ハッシュについての簡単な解説はこちら↓

https://qiita.com/Sunasuna24/items/ebf97437271ab35b0ea4


# イントロダクション

Laravelが提供する`Hash`ファサードを使用することで、ユーザーのパスワードを安全に保存することができます。

# 基本的な使い方

`Hash`ファサードの`make`メソッドを使うことで、パスワードをハッシュすることができる。

```PHP
<?php
namespace App\Http\controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash; // こいつを読み込む

class RegisterController extends Controller
{
    // ユーザーを登録する
    public function register(Request $request)
    {
        $password = $request->input('password'); // 生のパスワード
        // ここでパスワードをハッシュする
        $hashed_password = Hash::make($password);
    }
}
```

# 生の文字列がハッシュされた文字列と一致するかの確認

`Hash`ファサードが提供する`check`メソッドを使用すると、生の文字列がハッシュ化された文字列と一致するかどうかを確認できる。

```PHP
<?php
/**
 * 'raw text'が$hashed_textと一致するかを検証
 */
$hashed_text = Hash::make('raw text');

// この場合の検証は成功する
if (Hash::check('raw text', $hashed_text)) {
    echo "一致しています！";
} else {
    echo "不一致です、、、。";
}
```

# 余談

ハッシュなんて概念、エンジニアしてないと知る機会ないよなぁ。

# 大参考文献

https://readouble.com/laravel/8.x/ja/hashing.html
コンテナイメージ使うならdistrolessもいいよねという話

# 概要

* distrolessは、Googleが提供している必要最小限の依存のみが含まれるDebian10(buster)を基に作成されたコンテナイメージです。
* imageのサイズが本当に小さく、aptやshellさえも含まれておりません。
* よくベースとして利用されるLinuxディストリビューションは、基本的な設定ファイルやパッケージが大体含まれます。(カーネルを除く)
* なので、実際使用しないような不要なファイルが多数含まれているのが現状です。

* distrolessは、このような不要なファイルを削除し、本当に必要な最小限のファイルのみを含んだimageとなっております。

https://github.com/GoogleContainerTools/distroless

# 何が嬉しいのか

上記にも挙げたのですが、嬉しさポイントは以下の２点です。

* **セキュア**
=> 本当に実行に必要なのファイルのみを含んだimageとなっているので、不要なバグや脆弱性を埋め込みにくいという点が、セキュアだといえます。

* **軽量**
=> 含まれるファイルを最小限にしているので、imageのサイズを小さくできます。

## distrolessのベースイメージ群

現在(2022/6/18時点)では、下記のベースイメージ群があります。

>gcr.io/distroless/static-debian11
gcr.io/distroless/base-debian11
gcr.io/distroless/java11-debian11
gcr.io/distroless/java17-debian11
gcr.io/distroless/cc-debian11
gcr.io/distroless/nodejs-debian11

一応下記のベースイメージもあるのですが、実験的なものと見なされており、本番環境での使用はお勧めしていないようです。

>gcr.io/distroless/python3-debian11

### staticとbaseの違い

* 詳しくは公式のREADMEに書いてあるんですが、違いとしては**Staticは**最軽量なコンテナイメージです。サイズも3.42MBほどで、イメージを起動しても6.6MB程度のようです。じゃあ**base**はというと、glibc,libssl, opensslなどを使いたい場合はbaseを選択するといった感じです。ただ、これらが入るとサイズが肥大化し、だいたい24MBぐらいになるようです。

https://github.com/GoogleContainerTools/distroless/blob/master/base/README.md



# 参考/引用

https://github.com/GoogleContainerTools/distroless

https://blog.inductor.me/entry/alpine-not-recommended

https://blog.unasuke.com/2021/practical-distroless/

https://ceblog.mediba.jp/post/662840014480326656/%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%81%A8%E3%81%97%E3%81%A6distroless%E3%82%92%E4%BD%BF%E3%81%86%E3%81%B9%E3%81%8D%E7%90%86%E7%94%B1%E3%81%A3%E3%81%A6
[Laravel]排他制御（悲観ロック・楽観ロック）の基礎を理解

# はじめに

業務でDB更新処理の際に悲観ロックをかけ忘れた実装をレビュー時に指摘され、この実装をした原因がロックに対しての理解度が足りていないからだなと思い、改めてしっかり理解しようとした。

特に実装忘れなので、その**重要性**（必ずないといけないこと）をちゃんと理解するのが最低限の目的。

また、悲観ロックと楽観ロックがあるのは知っているが、**使い分け方があいまい**なので、そこの理解も目的。

# 参考

https://qiita.com/NagaokaKenichi/items/73040df85b7bd4e9ecfc

https://masawan-guitar.hatenablog.com/entry/2016/08/14/163447

# 目的

排他制御の目的はトランザクション開始と終了時にデータの整合性が保つこと。

RDBMSで言えばACID特性の「一貫性（Consistency）」を担保することが目的。

※尚、筆者はRDBMS（MySQL）しか触ったことがないため、RDBMS前提で話が進みます。

# 方法

主にはよく聞く2つの方法がある

## 楽観ロック

基本「複数人によるデータの同時更新は起きないっしょ」という前提でのロックの方法。

実際にデータ自体にロックは行わない。

データの「更新開始時の状態」と「更新終了時の状態」が同じであるかを確認して疑似的にロックする。

具体的にはその「状態」を管理するカラムを用意して更新開始時と更新終了時にその状態が一致していれば更新してOK、一致していなければ楽観ロックエラー、てな感じ。

なので、万が一同時タイミングで複数人による更新処理が実行されたら、一番早く更新処理をした人の内容がDBに反映され、残りの方は楽観ロックエラーになり、更新処理ができないことになる。

## 悲観ロック

楽観ロックは「複数人によるデータの同時更新はめちゃくちゃ起こる！」という前提のロック方法。

更新対象のレコード取得時にロックすることで、他社からの更新処理を受け付けなくなる。そもそもレコードの読み取りが不可。

なので必然的にロックの対象はレコード単位となる。

ロックの解除はトランザクションのコミットかロールバックによって実行される。

ロックの解除の実装が漏れると常にロック状態になってしまうため、いつまでも他者がレコードを参照できない、という困りごとが起こる。

※但し、ロック処理中に「ブラウザを落とす」「強制シャットダウンする」などするとユーザー操作によるロックしたままの状態になってしまう。

これは「管理者権限でロック開放できるようにする」など別途対応が必要

# Laravelおける排他制御

## 楽観ロック

### 自作する

https://qiita.com/youstr/items/04018908522be2eda8ff

デフォルトでは楽観ロックの機能は備わっていないので、記事の様に自作して対応します。

記事内では`edited_at`というカラムを使ってレコードの状態を管理していますが、`version`みたいなintを持つカラムでもいいかもですね。

`edited_at`の代わりに`updated_at`でもいい気がするけど。

### ライブラリ導入

https://github.com/reshadman/laravel-optimistic-locking

ライブラリも1つの手かと。MITですし。

ただ、スター数が少ない、更新が2019/1に止まっているのが懸念ですね。

コチラはReadme見る限り、

> use OptimisticLocking;

というtraitをモデルに持たせることで、`lock_version`というプロパティをモデルに持たせてこれで楽観ロックを管理する形だと思います。

（使ったことはないので保証は出来ません。）

## 悲観ロック

## lockForUpdateを使う

https://readouble.com/laravel/8.x/ja/queries.html#pessimistic-locking

悲観ロックは非常にシンプルでLaravelが用意しています。

更新する対象モデル（レコード）取得に使う感じ。

```php
DB::table('users')
        ->where('votes', '>', 100)
        ->lockForUpdate()
        ->get();
```

```php
Use::lockForUpdate->findOrFail(1);
```

# おわりに

文字に起こして記事をしっかり読むと理解が深まりました。

（もうLaravelのlockForUpdateをトランザクション外で実装するような愚行はしないと思います。。。）

共有ロックをするsheredLockのメソッドがあることも今回知れました。

余談ですが、Laracastに「悲観ロック VS 楽観ロック」という記事もあったので共有します。

https://alirus.medium.com/pessimistic-vs-optimistic-locking-in-laravel-264ec0b1ba2

ざっくり結論としてはロック時間が長い高負荷な処理ついては楽観ロックだよね、って感じです。

最後までお読みいただきありがとうございました。
packageの複数のバージョンを管理する方法

負債解消の際、少しずつリファクタリングをするため、既に使用しているのバージョンのpackageを残しつつバージョンアップしたpackageを使いたい時があると思う。
そんな時に使える小技の紹介

まずnpmとyarnにはエイリアスを使用したinstallがある
ドキュメントはこちら
[npm](https://docs.npmjs.com/cli/v8/commands/npm-install)
[yarn](https://classic.yarnpkg.com/en/docs/cli/add/#toc-yarn-add-alias)

npm
```
npm install <alias>@npm:<name>
```

yarn
```
yarn add <alias>@npm:<name>
```

なので複数バージョンを管理するためにはこのようにエイリアスを指定し、パッケージ名の後に`@<version>` を追加してinstallすれば良い

npm
```
npm install package-V8@npm:package@8.0.8
npm install package-V10@npm:package@10.0.3
```

yarn
```
yarn add package-V8@npm:package@8.0.8
yarn add package-V10@npm:package@10.0.3
```

使う時は指定したaliasでimportできます
```
import Module from 'package-V8'
```


しかし全てのパッケージが複数のバージョンを並行して使用することをサポートしているわけではないので、そこは仕様を読み解きながらですね。

参考記事
[Use multiple versions of an npm package at the same time](https://www.nieknijland.nl/blog/use-multiple-versions-of-an-npm-package-at-the-same-time)
BCM系のGPIO

# WCA-G

|LED|COLOR|pin|ON|
|:--|:--|:--|:--|
|POWER|緑||
|SECURITY|橙|6|0|
|WIRELESS|緑|2|1|
|?|||
|DIAG|赤|7|0|
|INTERNET|緑|1|1|

|SW|pin|
|:--|:--|
|上 Push|0|
|RESET Push|4|
|未実装 Slide|3,5|

lan_ipaddr: 192.168.11.1

# WLI-TX4-G

|LED|COLOR|pin|ON|
|:--|:--|:--|:--|
|POWER|緑||
|SECURITY|橙|6|0|
|WIRELESS|緑|2|1|
|WIRELESS|赤|3|1|
|未実装|-|1|-|
|DIAG|赤|7|0|

lan_ipaddr: 192.168.11.1

箱はLCD無しSW有りのWCA-Gでアダプタは5Vです。

# WHR-G

|LED|COLOR|pin|ON|
|:--|:--|:--|:--|
|POWER|緑||
|SECURITY|橙|6|0|
|WIRELESS|緑|2|1|
|?|||
|ROUTER|緑|1|1|
|DIAG|赤|7|0|

lan_ipaddr: 192.168.11.1

# WHR-HP-G54

|LED|COLOR|pin|ON|
|:--|:--|:--|:--|
||橙|6|0|
|POWER|緑||
|WIRELESS|緑|2|0|
|?|||
|BRDGE|緑|1|0|
|DIAG|赤|7|0|

lan_ipaddr: 192.168.11.1

# WHR-AM54G54

|LED|COLOR|pin|ON|
|:--|:--|:--|:--|
||橙|6|0|
|POWER|緑||
|WIRELESS a|緑|2|0|
|WIRELESS g|緑|3|0|
|BRDGE|緑|1|0|
|DIAG|赤|7|0|

lan_ipaddr: 192.168.11.1

# WHR-G54S

|LED|COLOR|pin|ON|
|:--|:--|:--|:--|
||橙|6|0|
|POWER|緑||
|WIRELESS|緑|2|0|
||緑|3|0|
|BRDGE|緑|1|0|
|DIAG|赤|7|0|

|SW|pin|
|:--|:--|
|上 Push|0|
|下 Push|4|
|下 Slide|5|

lan_ipaddr: 192.168.11.1

# WLA2-G54C

|LED|COLOR|pin|ON|
|:--|:--|:--|:--|
|WIRELESS|緑|5|0|
|ETHERNET||||
|AOSS|緑|3|0|
|DIAG|赤|4|0|

lan_ipaddr: 192.168.30.1,192.168.11.100

# WLI3-TX1-G54

|LED|COLOR|pin|ON|
|:--|:--|:--|:--|
|WIRELESS|緑|5|0|
|ETHERNET||||
|AOSS|緑|3|0|
|DIAG|赤|4|0|

lan_ipaddr: 1.1.1.1

# PD-10

|LED|COLOR|pin|ON|
|:--|:--|:--|:--|
|LINK|緑|0|0|
|LINK|橙|1|0|
|BUSY|緑|2|0|
|BUSY|橙|3|0|

|SW|pin|
|:--|:--|
|START|5|
|RESET|7|

POWER OFF 4
エンジニア転職に成功した時に参考にしたYouTube動画厳選20本

![](https://storage.googleapis.com/zenn-user-upload/f648eec9fc20-20220616.jpg)

「エンジニア転職に興味あるんですが、これは見ておくと良いよっていうおすすめのYouTube動画ってありますか？」
「転職時に実際に特に役立ったYouTube動画があれば教えて下さい」

今回はそんなYouTube動画についてご紹介します。

【筆者について】
不動産会社で約3年間営業職を経験後、2020年4月に独学でプログラミングを学んで自社開発企業のWeb系エンジニアへ転職しました。
約2年間勤めた後、2022年5月に転職し、現在は渋谷の某メガベンチャー企業で働いています。

**【紹介する動画について】**
エンジニア・プログラミングに関する動画200本以上の中から、以下の観点で約2０本に厳選しました
- **エンジニア転職活動に実際に役立った動画**
- **転職活動を始める前に見ておきたかった動画**

# 転職時に参考になったYouTube動画
いま、YouTubeにはキャリア論やエンジニア転職についての動画が沢山あります。

私自身も、約３年前に**YouTubeの動画が最初のきっかけでWEB系エンジニアに転職しました**。
**転職して年収も100万以上上がり**、**ストレスも激減**したので、毎日最高にいいコンディションで働けています。

エンジニアに興味を持った日から転職するまで、そして転職してから今日までの約3年間、様々なYouTube動画を見てきました。
その中で、役に立った動画、他の人にもおすすめしたいと思った動画は再生リストにまとめ続け、
現在、**ストックした動画総本数は200本以上**です。

その200本以上の中から、
「**エンジニア転職活動に実際に役立った動画**」
「**転職活動を始める前に見ておきたかった動画**」
という観点で20本(+α)に厳選しました。

こちらです。

## 転職活動・キャリアについて

https://youtube.com/playlist?list=PLMD4tajVAx-MbLA4aa9Qa_pNAxfRDOexN

## 「プログラミング基礎学習編」もあります
プログラミング基礎学習用の動画リストも作りました。
よろしければご覧ください。

https://qiita.com/adwyaatd/items/e60ba093f2d723f66b08

# おまけ【元動画200本】
元にした200本以上の方の動画も見たいというアグレッシブなあなたはこちらをどうぞ！

https://youtube.com/playlist?list=PLMD4tajVAx-OYilF2T-5ha6rnYpPHERwg


これからもエンジニアを目指す人に役立つ情報を発信していきます!
よかったら、いいね、フォローお願いします!
【プログラミング学習編】おすすめYouTube動画厳選10本

![](https://storage.googleapis.com/zenn-user-upload/f4a57d0ae158-20220618.jpg)

「エンジニア転職に興味あるんですが、これは見ておくと良いよっていうおすすめのYouTube動画ってありますか？」
「プログラミング学習の参考になったYouTube動画があれば教えて下さい」

今回はそんなYouTube動画についてご紹介します。

【筆者について】
不動産会社で約3年間営業職を経験後、
2020年4月に独学でプログラミングを学んで、自社開発企業のWeb系エンジニアへ転職しました。
約2年間勤めた後、2022年5月に転職し、現在は渋谷の某メガベンチャー企業で働いています。

**【紹介する動画について】**
エンジニア・プログラミングに関する動画200本以上の中から、
以下の観点で約10本に厳選しました

- **エンジニア転職活動時のプログラミング学習に実際に役立った動画**
- **プログラミング学習の初期に見ておきたかった動画**
- **プログラミング初学者におすすめしたい動画**

# おすすめYouTube動画

いま、YouTubeにはキャリア論やエンジニア転職についての動画が沢山あります。

私自身も、約３年前に**YouTubeの動画が最初のきっかけ**でWEB系エンジニアに転職しました。
転職して年収も100万円以上上がり、ストレスも激減したので、転職してよかったと心から思います。

エンジニアに興味を持った日から転職するまで、そして転職してから今日までの約3年間、様々なYouTube動画を見てきました。

その中で、役に立った動画、他の人にもおすすめしたいと思った動画は再生リストにまとめ続け、現在、動画総本数は200本以上です。

その200本以上の中から、
「エンジニア転職活動時のプログラミング学習に実際に役立った動画」
「プログラミング学習の初期に見ておきたかった動画」
「プログラミング初学者におすすめしたい動画」
という観点で約10本に厳選しました。

こちらです。
参考になれば幸いです。

## プログラミング基礎学習

https://youtube.com/playlist?list=PLMD4tajVAx-NNY3cqBISFWIKOy93oPvPn

【動画リスト内容】

- プログラミングにはやってはいけない勉強法がある！？爆速で成長する王道のプログラミング学習法を紹介！（デイトラ）
- プログラミング初学者の「わかってから始めたい病」の危険性（KENTA/雑食系エンジニアTV）
- 成長の遅いプログラミング初学者の特徴（KENTA/雑食系エンジニアTV）
- 勉強する前に知るべき！プログラマーの種類を教えます（とだこうき）
- 【今さら聞けない】文系・知識ゼロでも分かる「プログラミング」っていったい何？（マコなり社長）
- IT用語66選！エンジニアリングの基本をこの動画1本で！【非エンジニア必見】（だれでもエンジニア / 山浦清透）
- 主要プログラミング言語16選！特徴と初心者向けおすすめ度まとめ（セイト先生のWeb・ITエンジニア転職ラボ）
- 非エンジニアでもわかる！Webサービス・アプリが動く仕組み（マコなり社長）
- Webとは何か？初心者エンジニア向けに解説します【HTTP / PHPによるWebアプリケーション開発講座・番外編】【Webの仕組み解説シリーズ#1】（プログラミングアカデミー）
- 「なにがわからないのかわからない」という状況への対処法（KENTA/雑食系エンジニアTV）
- プログラミングで「エラー」が起きたときの対処方法【３つあります】（マナブ）
- 知らないとヤバい！生産性の高いパソコンの使い方 13選（マコなり社長）

## 「転職活動編」もあります
転職活動・キャリアについての動画リストも作りました。
宜しければこちらもどうぞ。

https://qiita.com/adwyaatd/items/3a16f9acb04d22b89953

# おまけ【元動画200本】
元にした200本以上の方の動画も見たいというアグレッシブなあなたはぜひご覧ください。

https://youtube.com/playlist?list=PLMD4tajVAx-OYilF2T-5ha6rnYpPHERwg

これからもエンジニアを目指す人に役立つ情報を発信していきます！
よかったら、いいね、フォローお願いします！
ダブルクリックで Visual Studio Code で Remote SSH でリモートマシンを開く

## ダブルクリックで Remote-SSH でリモートマシンを開く

### 前提知識

以下の記事で Visual Studio Code で Remote SSH で開く方法を説明しています。


https://qiita.com/m-tmatma/items/f3cc666c2e667adab784



https://qiita.com/m-tmatma/items/6d04dc584b6d35ed5f75

### 具体的な方法


[Visual Studio Code の Remote SSH でリモートマシンをコマンドライン指定で開く](https://qiita.com/m-tmatma/items/6d04dc584b6d35ed5f75) の方法に基づいてコマンドライン引数を指定してショートカットを作る。これによってダブルクリックでリモートマシンを開くことができます。


#### ショートカット作成

エクスプローラでショートカットを作成したいフォルダで、`新規作成` から `ショートカット作成` を選びます。

#### Visaul Studio Code の実行パスを指定します。

通常以下のパス ( `"C:\Program Files\Microsoft VS Code\Code.exe"` ) を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500246/5409e38e-3ab9-adc8-232a-6fed298c2741.png)

`完了` を押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500246/68393059-a229-78e2-76cc-d89698aef307.png)

#### ショートカットのプロパティ

作成したショートカットでプロパティを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500246/83fcdc16-bb3a-fff4-9326-1b3d817c3068.png)

#### コマンドラインパラメータの追加

開きたいマシンのコマンドライン引数を追加します。(この例の場合、`hogehoge` という設定のマシンを開きます)
`"C:\Program Files\Microsoft VS Code\Code.exe" --remote ssh-remote+hogehoge`

(追記): 上記コマンドラインだと動作しない場合があるみたいなので以下のようにリモートマシンで開くパスも指定すると確実のようです。
`"C:\Program Files\Microsoft VS Code\Code.exe" --remote ssh-remote+hogehoge /home/user/`


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500246/be30f9ac-2c75-1b03-74c4-5a25fd17c573.png)


## ショートカット名の設定

全般タブに移動して、マシン名がわかるようなわかりやすい名前を付けます。ショートカット生成時に指定しておくことも可能です。

OK を押して確定します。
これでダブルクリックするとリモートマシンを開くことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500246/8887df84-a0b3-a54a-b9d0-0f718ea282f6.png)
プログラマのメンターとして生きられるの？ MENTA で初の単発案件を獲得した (1時間1000円)

# MENTAはプラットフォームとして

登録するだけでは何も応募がない。
たやすくはなさそうだ。

# 1000円の売上を獲得

メンタのプランの最低価格が1000円なのだ。初回は割引で最低価格のプランを作っていたので、この金額を売り上げた。
そして手数料を差し引きした分をゲットした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/78015da0-3bdc-8dfb-edd9-eaa95cdf0b96.png)

# 宣伝

自分が今まで書いた全てのQiita記事からMENTAのページにリンクを張って宣伝したが、はじめて応募があるまで1ヶ月かかった。ちなみにQiita経由かどうかは聞かなかったので、効果があったかどうかさえ不明。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/6156cf2c-c925-0dce-13e2-86829c1c4fb1.png)

# 自己紹介、スキルセット

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/09658387-7dbc-5592-715c-ce44dae9ead2.png)

# プラン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/d204e386-a82d-5c98-fe03-24790d8c8e69.png)


# 相談内容

Ruby on Rails での学習方針の相談に乗った。

アドバイスしたのは、

- 業務で難しさを感じている機能開発を主軸に勉強してみる。
- 業務コードで気になったところを調べたり、深堀りしてみる。
- Rails でてきとうなアプリケーションを作ってみる。Twitterみたいなものや、ブログみたいなものとか、それかまさにMENTAなど、慣れ親しんでいるサービスを模倣して作ってみても良いかも知れない。
- 今業務で利用しているアプリケーションを模倣して、自分で1から作ってみる。

業務のコードは、メンターが直接見られないところがネックになると思った。
メンティに自作アプリケーションを作ってもらった方が、コードも直接見られるし良いかも知れないという話をした。


# 誰が稼いでいるんだろう？

たった1案件をこなしただけだけど、メンタースコアが上がり、ランクが1000位ほどになった。
これはメンターの母数が少ないように思える。

あまりアクティブなメンターはそもそもいないのかもしれない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/f6abcb39-a587-519e-b8f6-4af3f766d1d1.png)

そもそもメンターというジャンル自体が成り立つのかどうか、MENTAというサービスが成り立っているのかを懸念に思い始めた。

プログラミングスクールは生徒から安くないお金を巻き上げているが、メンタはどうだろう、難しい仕事のような気もする。個人と企業の違いだろうか。

<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
第6週目 SPRING

第6週目

19講 EL(ExpressionLanguage)はJAVAのプロパティ、値をJSPの表現式<%=%>やアクションタグ<jsp:useBean>を使うよりも簡単かつ簡潔に取り出せるようにする技術
20講 @GetMapping GET要請をするAPIのアノテーションデータを 取得する際に使用@PostMapping POST要請をするAPIのアノテーションデータを 掲示する際に使用RequestMappingを簡単にする機能
21講 マッピング順序正確なマッピング>経路マッピング>拡張子マッピング>404エラー
URLインコーディングURLに含まれたノンアスキーコードを変える16進水文字列に転換全世界で通用するように
22講 redirect 要請も2回応答も2回目は自動的にGET方式で要請 forward 要請を1回他の方に伝達して応答も1回
23講 クッキーとは？ 名前と値で対に構成された情報サーバーで生成後、ブラウザに保存クライアント識別機能
24講 セッション？関連する要請を一つにまとめたもの訪問者がウェブサーバーに接続している状態を一つの単位で見て、それをセッション
クッキーはブラウザーに保存セッションはサーバーに保存するため、サーバーの負担が大きいためログイン、オンラインショッピングモールの買い物かごなどに使われる。
25講 index.jsp>BoardController.java>loginForm.jsp>loginController.javaセッション値をサーバに締め付けてページを移動
ログイン時にログインを維持させる接続性
26講 session=trueセッションがない場合は、生成session=false細線内づくり(セッションを開始しないという意味=セッションはサーバーに負担が多いため、ログインしない状態はセッションオブジェクトを外す必要がある)
行列のテンソル積表現

# これは何？

テンソルと行列の関係について，いくつかの線形代数の本を読んでいます．この短記事は，『線型代数学周遊』という良書の講義ノートです．なぜ「講義ノート」かというと，[著者の松谷先生](https://twitter.com/mono_dukuri_no)に twitter DM で質問と回答を繰り返しながら書いたからです！先生ありがとうございました．

https://www.amazon.co.jp/%E7%B7%9A%E5%9E%8B%E4%BB%A3%E6%95%B0%E5%AD%A6%E5%91%A8%E9%81%8A%E2%80%95%E5%BF%9C%E7%94%A8%E3%82%92%E3%82%81%E3%81%96%E3%81%97%E3%81%A6-%E6%9D%BE%E8%B0%B7-%E8%8C%82%E6%A8%B9/dp/4768704298/

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51055/e832390f-0203-47ae-45fb-db49bee7bd91.png)](https://www.amazon.co.jp/%E7%B7%9A%E5%9E%8B%E4%BB%A3%E6%95%B0%E5%AD%A6%E5%91%A8%E9%81%8A%E2%80%95%E5%BF%9C%E7%94%A8%E3%82%92%E3%82%81%E3%81%96%E3%81%97%E3%81%A6-%E6%9D%BE%E8%B0%B7-%E8%8C%82%E6%A8%B9/dp/4768704298/
)

具体的には， p.55 「行列のテンソル積表現」の部分のメモです．行列を **「線型写像の表現」** とみたとき，それは **「テンソル積と同一視できるよ」** ということを言っています．


# 行列のテンソル積表現

$V$, $W$ を体$K$上の線形空間として， 

- $\mathrm{dim} V = n, \quad \mathrm{dim} W = m$
- $V$ の基底 $e_j$ ($j= 1,\ldots,n$)
- $W$ の基底 $b_i$ ($i=1,\ldots,m$)

$V$から$W$への線型写像全体を$\mathrm{Hom}_K(V,W)$とします．この時，$V$の双対空間を $V^*$として，

```math
\mathrm{Hom}_K(V,W) = W \otimes V^*
```

です(1)．これを絵でメモしました．これを行列と関連づけて理解したいのです！

![綿形代数-099.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51055/569f7d6d-7d31-d470-f767-61db67fd4947.jpeg)

ここで，行列を登場させます．線形変換 $\phi \in \mathrm{Hom}_K(V,W)$は，定義域$V$のそれぞれの基底ベクトル$e_j$が移る先$\phi(e_j)$が，値域$W$基底ベクトル$b_i$の線型結合の各係数としてどのように表現されるか，で表現されるのでした．

```math
[ \phi(e_1), \ldots, \phi(e_n)] = [b_1, \ldots, b_m] \begin{bmatrix}
a_{11} & \cdots  & a_{1n} \\
\vdots & \ddots & \vdots \\
a_{m1} & \cdots & a_{mn} \\
\end{bmatrix}
```
ここで， $A = [a_{ij}]$ が $\phi$の表現行列です．

```math
[ \phi(e_1), \ldots, \phi(e_n)] = [b_1, \ldots, b_m] A
```

すなわち， $\mathrm{Hom}_K(V,W)$ は，$\mathrm{Mat}_k(m,n)$ と同型です．これら2つのことから， $m \times n$ 行列は，テンソル積を使って表現されるのです．このことを例で書き下します．具体例として，$2 \times 3$ 行列 $A$ を扱っています．

![綿形代数-100.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51055/7de32dec-f824-593d-3957-675151b41777.jpeg)

$A$の行はそれぞれが，双対空間の元（一次形式）で， 元の$V$の元を一次元の体$K$に移します．この具体例でさらに計算を入れて，具体化してみます．

![綿形代数-101.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51055/da3ce6bf-1522-609e-633b-11858dca80be.jpeg)

これで，理解したかった，

```math
\mathrm{Hom}_K(V,W) = W \otimes_k V^* \cong　\mathrm{Mat}_k(m,n)

```
にたどり着きました．ここまで，著者の松谷先生に，twitter DM でご指導いただきました！ありがとうございました．この本を再掲しておきます．

https://www.amazon.co.jp/%E7%B7%9A%E5%9E%8B%E4%BB%A3%E6%95%B0%E5%AD%A6%E5%91%A8%E9%81%8A%E2%80%95%E5%BF%9C%E7%94%A8%E3%82%92%E3%82%81%E3%81%96%E3%81%97%E3%81%A6-%E6%9D%BE%E8%B0%B7-%E8%8C%82%E6%A8%B9/dp/4768704298/

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51055/e832390f-0203-47ae-45fb-db49bee7bd91.png)](https://www.amazon.co.jp/%E7%B7%9A%E5%9E%8B%E4%BB%A3%E6%95%B0%E5%AD%A6%E5%91%A8%E9%81%8A%E2%80%95%E5%BF%9C%E7%94%A8%E3%82%92%E3%82%81%E3%81%96%E3%81%97%E3%81%A6-%E6%9D%BE%E8%B0%B7-%E8%8C%82%E6%A8%B9/dp/4768704298/
)

# 後少し，もやもやしていること

ゴールは，行列を **「線型写像の表現」** とみたとき，それは **「テンソル積と同一視できるよ」** なんですが，

- では， **$\phi$ の表現行列の式を直接計算してみて，書き下したい**
- $W \otimes_k V^*$ は，  **次元が $mn$ であることが分かった段階で(線形空間なのだから)$m \times n$行列と同型ですよね**．という議論は成り立つ？


と思っています．どうなるんですかね？ どなたかコメントください．
cscの作法 その198

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

# 練習問題

qiitaapi、叩いて、datagridviewで表示せよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/cab44e72-1085-59d8-53c9-6cc25d6867dd.png)

# サンプルコード

```
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using System.Text;
using LitJson;
using System.Net;

namespace app
{
	public class Form1 : Form {
		DataGridView dgv;
		public Form1() {
			this.Text = "qiita";
			this.Size = new Size(780, 280);
			dgv = new DataGridView();
			dgv.Dock = DockStyle.Fill;
			this.Controls.Add(dgv);
			this.Load += new EventHandler(Form1_Load);
		}
		void Form1_Load(object sender, EventArgs e) {
			dgv.RowCount = 5;
			dgv.ColumnCount = 5;
			dgv.TopLeftHeaderCell.Value = "qiita";
			dgv.Columns[0].HeaderCell.Value = "title";
			dgv.Columns[1].HeaderCell.Value = "created_at";
			dgv.Columns[2].HeaderCell.Value = "url";
			for (int i = 0; i < 5; i++)
			{
				dgv.Rows[i].HeaderCell.Value = i.ToString();
			}
			ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
			WebClient wc = new WebClient();
			string jsonText = "";
			using (Stream st = wc.OpenRead("https://qiita.com/api/v2/users/ohisama@github/items?page=1&per_page=5"))
			{
				using (StreamReader sr = new StreamReader(st))
				{
					jsonText = sr.ReadToEnd();
					LitJson.JsonData json = LitJson.JsonMapper.ToObject(jsonText);
					for (int i = 0; i < 5; i++) 
					{
						dgv[0, i].Value = json[i]["title"];
						dgv[1, i].Value = json[i]["created_at"];
						dgv[2, i].Value = json[i]["url"];
					}
				}
			}
			dgv.RowHeadersWidth = 40;
			dgv.AutoResizeColumns();
		}
		[STAThread]
		static void Main() {
			Application.Run(new Form1());
		}
	}
}





```


以上。