OmniAICreator/Qiita-1.07M huggingface dataset:
【TypeScript】Opaque型を用いたより強力な型構成

# 概要

TypeScriptでは２つの型が構造的に同じであれば、互換性があると見なされます。
例えば下記の`name`と`password`は互換性があると言えます。

```ts
type name = string
type password = string
```

つまり、ユーザーから見た場合意味的には全く異なる上記の2つの型もTypeScriptは同じものとして扱います。
しかし、`password`は8文字以上で大文字や小文字を含んでいなければならない等の条件を持った型を定義した場合どうすれば良いでしょうか？

上記のような例ではTypeScriptは型的な安全性を保証してはくれますが、`name`と`password`のような意味的に異なる情報の分別が出来ていません。
このようなケースで`Opaque型`を用いる事で、より強力な型構成をもたらす事が可能です。

# Opaque型を使用しない例

まずは、Opaque型を用いない例を確認します。
下記の例では`name`と`password`もstring型として扱われています。

```ts
type User = {
  name: string
  password: string
}

const user: User = { name: "user1", password: "1234" }
console.log(user) // => { name: 'user1', password: '1234' }
```

# Opaque型を使用した例

`password`は8文字以上の文字列である事を保証する型`Password` を定義します。
TypeScriptはデフォルトでは`Opaque型`をサポートしていないので、`intersection型`を使用して、下記のように`Password型`は独自の型である事を明示的に定義していきます。

```ts
declare const validPassword: unique symbol;
type Password = string & { validPassword: never }
```

上記のコードに関しては下記の記事を読んで頂けると理解がより深まるかと思います。

[公称型をTypeScriptで実現するための基礎](https://qiita.com/suin/items/ae9ed911ebab48c98835)

上記で定義した`Password型`は通常の型と同様の使い方が可能です。

```tsx
type User = {
  name: string
  password: Password
}
```

こうしてあげる事で、TypeScriptは`password`に`string型`の値が渡されると、エラーを出すようになります。

```tsx
const user1: User = { name: "test", password: "1234" }  // Error: Type 'string' is not assignable to type 'Password'.
```

次に、`password`が8文字以上である事を保証したいので、与えられた文字列が8文字以上であった場合、値を`Password型`として返す`validatePassword`を定義します。

```tsx
const validatePassword = (input: string) => {
  if (input.length < 8) {
    throw new Error("パスワードは8文字以上で入力してください。")
  }
  return input as Password
}
```

`User型`のオブジェクトの`password`には`Password型`の値を与えたいので、`validatePassword`を使用して、下記のようにオブジェクトを定義する事が可能です。

パスワードが8文字以下の場合はしっかりとエラーを発生させてくれるようにもなりました。

```tsx
const user1: User = { name: "user1", password: validatePassword("1234") }
// => Error: パスワードは8文字以上で入力してください。
const user2: User = { name: "user1", password: validatePassword("12345678") }
// => { name: "user1", password: "12345678" }
```

ここまでのコードをまとめると下記のようになります。

```tsx
declare const validPassword: unique symbol;

type Password = string & { validPassword: never }

type User = {
  name: string
  password: Password
}

const validatePassword = (input: string) => {
  if (input.length < 8) {
    throw new Error("パスワードは8文字以上で入力してください。")
  }

  return input as Password
}

const user1: User = { name: "user1", password: validatePassword("12345678") }
const user2: User = { name: "user1", password: validatePassword("1234") }
```

# 参照

- [Stronger JavaScript with Opaque Types](https://codemix.com/opaque-types-in-javascript#:~:text=TypeScript%20does%20not%20have%20built,number)
- [Implementing an opaque type in typescript](https://evertpot.com/opaque-ts-types/)
- [TypeScript: 「電話番号型」という意味を持たせた特殊なstring型の作り方 - Qiita](https://qiita.com/suin/items/421ae4bf99d333ccfe0d)
googleスプレッドシートのデータをjsonで吐き出して、NUXTでセクションごとにリスト表示する

スプレッドシートのデータを取得して、データをセクションごとにリスト表示させたのを忘れないようメモ。
axiosでGETしてくるとこが遅いので改善したい。



#スプレッドシートに表を用意
<img width="1437" alt="スクリーンショット 2020-07-30 9.23.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306936/1a30aacf-3cff-1d07-1398-558e18060b31.png">


#データをjson形式で出力。
方法はここを参考。
https://qiita.com/YukiIchika/items/778856a7ea92e5a2383c

#NUXT側でデータを取得する。
ここを参考。
https://ma-vericks.com/nuxt-axios/

vueファイル内で

```
export default {
  async asyncData({ $axios }) {
    const url = 'https://script.google.com/macros/s/ID/exec';
    // リクエスト（Get）
    const response = await $axios.$get(url);
    // 配列で返ってくるのでJSONにして返却
    return { result: response }
  }
};
</script>
```

#セクションごとにリスト表示させる
これのためにsectionsKeyを設定しておく。

```
<ul>
  <template v-for="item in result">
    <template v-if="item.sectionsKey === 1">
      <li>
        <nuxt-link :to="item.url">{{ item.pages }}</nuxt-link>
      </li>
    </template>
  </template>
</ul>
```
自炊で作成したjpgを1つのPDFファイルにする

#Acrobatを利用する方法
- Acrobat Pro DCでツール->ファイルを結合

#コマンドだけで行う方法
- カレントフォルダに以下のように連番のjpgファイルのみあると仮定する。

```
00001.jpg 00002.jpg 00003.jpg 00004.jpg 00005.jpg 00006.jpg
```

- 以下のコマンドを実行してmyoutput.pdfというファイルを作成する。
 - [mogrify](https://imagemagick.org/script/mogrify.php), [pdftk](https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/)

```
mogrify -format pdf $(ls -1 *.jpg)
pdftk $(ls -1 *.pdf) cat output myoutput.pdf
rm -f *.pdf
```

# 参考にしたページ
- [画像をPDFファイルへ変換する@Linux Mintのメモ](https://sites.google.com/site/linuxnomemo/command-shell/image-to-pdf)
【PHP】Excelで文字化けしないCSVファイル作成

# はじめに
色々なところで紹介されているものだと思いますが、
私の環境ではどうしても上手くいかなかった。。。
こんなところで詰まっている場合ではないのに。。。

コピペに頼っているから悪い。一から自分で作るしかない！
作ったらうまくいった～しかも簡単すぎ！！

なんだかんだできたので記事にしてみたいと思います！
※初投稿&PHP歴半年なのでお手柔らかに。

#コード
「ファイル名」「データカラム」「データ本体」を渡すと決められたパス先にCSVを作成し、作成したCSVファイルのフルパスを返す関数。

```php

/**
 * CSVファイルの作成
 */
public function createCSV($fileName, $csvColumn, $csvBodyData){
        
    //ファイルフルパス作成
    $filePath = 'ファイルパス'.$fileName;
        
    //CSVファイル作成
    $csvFile = fopen($filePath, 'w');

    //CSVを開いても文字化けしないように
    stream_filter_prepend($csvFile,'convert.iconv.utf-8/cp932');

    //カラムを書き込む
    fputcsv($csvFile, $csvColumn);

    //データを書き込む
    foreach($csvBodyData as $csvBody){
        fputcsv($csvFile, (array)$csvBody);
    }

    //ファイルフルパスを返却
    return $filePath;
}
```

なんでこんな簡単だったのに悩んだのか。。。

参考
[fputcsv関数を覚える！PHPでCSVファイルを出力する方法【初心者向け】](https://techacademy.jp/magazine/12330)
#最後に
やはりコードのコピペはダメですね～
理解が大事でそれが一番の近道だと思い知りました。

もっと勉強せねば！！！

もっと良い方法あれば教えてください。
あと間違っていたらお願いします。
NUXTでgenerateするとluminous-lightboxが動かない

NUXTでLuminousGalleryを使おうとすると動かなかったのでメモ。


[公式通り](https://github.com/imgix/luminous)プラグイン内で

```
var galleryOpts = {
  // Whether pressing the arrow keys should move to the next/previous slide.
  arrowNavigation: true
};

var luminousOpts = {
  // These options have the same defaults and potential values as the Luminous class.
};

new LuminousGallery(document.querySelectorAll("a"), galleryOpts, luminousOpts);
```

とやるとgenerateすると動かないので、

`new LuminousGallery(document.querySelectorAll("a"), galleryOpts, luminousOpts);`

この部分だけluminousを動かすvueファイル内で

```
  mounted(){
    new LuminousGallery(document.querySelectorAll(".luminous"));
  }
```

としてあげると解決した。
【備忘】Amazon DynamoDBへのアクセスプログラム

Amazon DynamoDBにアクセスするための基本的なプログラムを記載

1.Entityの用意

```
@DynamoDBTable(tableName = "テーブル名")
public class SampleTableEntity {
    // HashKey
    @DynamoDBHashKey
    private String hashKey;

    // RangeKey
    @DynamoDBRangeKey
    private String rangeKey;

    // 項目
    @DynamoDBAttribute
    private String item;
}
```


2.接続

```
// 指定リージョンのDynamoDBにアクセスするためのClient生成
AmazonDynamoDB amazonDynamoDB = AmazonDynamoDBClientBuilder.standard()
				.withRegion(リージョン名)
				.build();

// テーブルへのMapperを生成
DynamoDBMapper mapper = new DynamoDBMapper(amazonDynamoDB);

```

3.データの取り出し(load)

```
String hashKey="000001";
String rangeKey="000002";
SampleTableEntity entity = mapper.load(SampleTableEntity.class, hashKey, rangekey);
```

4.データの検索(query)

```
String hashKey="000001";
String rangeKey="000003";

Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":v1", new AttributeValue().withS(hashKey));
eav.put(":v2",new AttributeValue().withS(rangeKey));

DynamoDBQueryExpression<SampleTableEntity> queryExpression = new DynamoDBQueryExpression<SampleTableEntity>() 
    .withKeyConditionExpression("hashKey = :v1 and rangeKey <> :v2")
    .withExpressionAttributeValues(eav);

List<SampleTableEntity > entityList = mapper.query(SampleTableEntity.class, queryExpression);
```

5.データの検索(scan)

```
String item = "Item";

Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":v1", new AttributeValue().withS(item));

DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
    .withFilterExpression("item = :v1")
    .withExpressionAttributeValues(eav);

List<SampleTableEntity > entityList = mapper.scan(SampleTableEntity.class, scanExpression);
```

6.データの登録・更新(save)

```
SampleTableEntity entity = new SampleTableEntity();
entity.setHashKey="0000001";
entity.setRangeKey="0000002";
entity.setItem="Item";

mapper.save(entity);
```
ECS上のFargateタスクを夜間は自動的に落とすようにして節約してみた

# 概要

ECS上のfargateタスクをスケジュールで起動したり落としたりしたい。
例えば開発環境のfargateタスクは夜間落としておいて、朝起動しておくと
タスクの実行時間が減るので料金を節約することができる。

# 大まかな流れ

- Lambdaを作り、ECS Serviceを更新し、必要なタスク量を増減させる
- Cloud Watch Eventにて、cronの時間になったらLambdaを発火する


# 実装

## Lambda

### ソースコード

今回はpythonで実装。

- eventで受けとったデータの中から、操作する対象のECSのクラスタ名、サービス名、更新するタスク数を取得
- ECSに対して更新操作を発行

サンプルソース

```python
import json
import boto3
import logging
from botocore.exceptions import ClientError

logger = logging.getLogger()
logger.setLevel(logging.INFO)


def lambda_handler(event, context):

    logger.info("Event: " + str(event))

    targets = event["targets"]
    desiredCount = event["desiredCount"]

    for target in targets:
        edit_ecs(target, desiredCount)


def edit_ecs(target, desiredCount):
    try:
        client = boto3.client('ecs')

        # update ecs cluster
        service_update_result = client.update_service(
            **target,
            desiredCount = desiredCount
        )

        print(service_update_result)
    except ClientError as e:
        print("exceptin: %s" % e)
```


### IAMロールの加工

Lambda実行時のIAMロールに、ECSへの更新操作権を付与する

Lambdaに付与したIAMロールを開き、以下のようにポリシーを編集

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecs:DescribeServices",
                "ecs:UpdateService"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        }
    ]
}

```

### テスト実行

Lambdaでテストイベントを作成。
ECSのクラスター名が `dev-ecs-cluster` で
タスクの増減をしたいサービスが `dev-service1` `dev-service2` の２種類があると仮定すると以下のようなJSONになる

```json
{
  "targets": [
    {
      "cluster": "dev-ecs-cluster",
      "service": "dev-service1"
    },
    {
      "cluster": "dev-ecs-cluster",
      "service": "dev-service2"
    }
  ],
  "desiredCount": 1
}
```

上記でLambdaをテスト実行すると ECSの必要タスク数が1に更新され、
タスクが２つ以上上がっていた場合、自動的に１つに変更されるはず。


## Lambdaを指定時間で発火させる

指定時間でLambdaを起動させたいので、 `Cloud Watch` でルール設定をする。

Cloud Watch -> イベント -> ルールの作成

イベントソースをスケジュールに設定し、cron式を入力する。
たとえば毎日AM08:00に実行するなら `0 23 * * ? *` となる(時間はGMTなので注意)

イベントターゲットに上記で作成したLambdaを指定し
入力の設定で「定数(JSONテキスト)」を選択し、そこにLambdaのテストで利用したようなJSONを記載する
（入力フィールドがテキストエリアでないのが辛い・・・）
こうするとLambda実行時のeventとして指定したJSONがLambdaに渡る。

desiredCountを `0` にすると該当サービスのタスクをゼロにできる。
なので同様のルールを２つ作り、08:00にはdesiredCountを `1` に。20:00にはdesiredCountを `0` のように設定しておけば夜間にタスクを落としておくことができる

![](https://i.imgur.com/8LtEZkB.png)
グローバルシャッターとローリングシャッターどれだけ違うのか検証してみた

「ローリングシャッター」「グローバルシャッター」といったシャッター方式は、イメージセンサーがどのようにして画像を露光し読み出すかの違いで

ローリングシャッターのカメラ（Webカメラなど）の場合、イメージセンサーのピクセルの上から順々に露光を行い、電荷に変換された電子を一斉に読み出さずに1行1行順々に読み出す。

グローバルシャッターのカメラ（産業用カメラなど）の場合、イメージセンサーの露光と読み出しはすべてのピクセルが同じタイミングで行っている。

ローリングシャッターは1枚の画像の上部と下部では撮影タイミングが異なっており、1枚の画像の上部と下部で撮影タイミングが異なると、動いている撮影対象物は像が歪んでしまう。

実際に動画の場合どの程度歪みが出てしまうのか確認するために検証してみた。

参考：https://www.argocorp.com/UVC_camera/UVC_shutter.html

##実際に試してみた
グローバルシャッターのセンサーを使用した産業用カメラとローリングシャッターのセンサーを使用したWebカメラでどのくらい違いがあるのか外の風景をカメラを激しく動かして撮影してみた。

###ローリングシャッターの実行結果（Webカメラで撮影）
![SO2LcbkN4v.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136687/c6ce8132-7713-7292-0a46-8a4336d34301.gif)
豆腐のようにビルが揺れ被写体ぶれが起きている。これはモーションブラー (motion blur) という現象。

###グローバルシャッターの実行結果（産業用カメラで撮影）
![3v7LmM2Svi2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136687/c729b14d-04ce-e645-272c-85090da4fc21.gif)
像の歪みは確認できない。

###検証結果
ローリングシャッターのカメラを使うと移動体のスピードが速すぎるとブラーという現象が起きてしまう。車載用のカメラ、ベルトコンベヤーで高速に流れる商品を撮影して画像処理する用途には不向き。
シンボルを見つけられません。import android.support.v4.app.ActivityCompatの読み込みエラー

ReactNativeでAndroidのネイティブモジュールを実装しようとしたところ、前使っていたコードが動かないことがわかりました。

```bash
/path/project/android/app/src/main/java/com/project/TestModule.java:28: エラー: シンボルを見つけられません
import android.support.v4.app.ActivityCompat;
                             ^
  シンボル:   クラス ActivityCompat
  場所: パッケージ android.support.v4.app
```

というエラーがでました。

どうやら、**android.v4**はサポートが切れ、
代替えとして、**androidx.**に移行する必要があるようです。

調べたところ、やることは2つで、

① dependencyの追加

build.gradleのdependenciesに

```gradle
implementation "androidx.core:core-ktx:+"
```

を追加

② importするパッケージの変更

```java
import android.support.v4.app.ActivityCompat -> import androidx.core.app.ActivityCompat
import android.support.v4.content.ContextCompat -> import androidx.core.content.ContextCompa
```

に変更することで動くようになります。
PHPの概要


###<概要>
PHP（Hypertext Preprocessor）は
Webサイトの作成を目的としたオープンソースのプログラミング言語

###＜特徴＞
・HTMLに埋め込むことができる
（Javascriptは主にブラウザで動作するが
PHPはサーバーで動作する）
・初心者がとっつきやすい
・プロのエンジニアに対しても多くの機能を提供
・手っ取り早く開発
・広く使われていて、採用数も多い

###＜歴史＞
１９９５年にRasmusLerdorfがPHP1.0を公開
最初はプログラム言語として作ったのではなく、
オンラインに公開されたRasmusの履歴書の訪問者数を追跡するためのツールとして開発した。
[Memo][terminal] xfce-terminal 

# 外観

- フォントスタイル: Migu 1M Regular
- フォントサイズ: 14

# 配色

プリセット: Xterm

![スクリーンショット_2020-07-30_08-29-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282788/5dbffc73-ee8e-5221-ddbf-dc597694090a.png)
中古のMacbookProを起動させるのに苦労した話

タイトルの通りMacbookProを中古で購入した時を振り返ってみようと思います。


#起動したら画面が真っ白でした

Macを使うことは初めてなのでワクワクしながら右上の電源ボタンを押しました。



その後真っ白な画面が表示され鍵マークが出てきます。



なんだこれは？起動できない、、、

#OSのインストールが必要ある

ネットで調べているうちにわかったことは中古のMacは最初にOSのインストールが必要とのことです。
（当たり前のことですが当時の無知すぎる自分は全く知りませんでした、、、）


OSのインストールってどうやるんだよ、、、知らねーよ、、、



どうやら電源を入れた直後に「command」＋「option」＋「R」を押して互換性のある最新バージョンのOS
をインストールする必要があるようです。



「command」＋「R」だと中古MacにインストールされていたバージョンのOSをインストールすることになる
ようなので当時インストールしたApple ID の入力の必要があります。（当然知るわけがない、、）

#試したこと


「command」＋「option」＋「R」を押して互換性のある最新バージョンのOS
をインストールを行いました。



設定を行い、ようやく起動できました！



わからないことだらけで大変だったです。。
[GAS] 決められた曜日にだけ実行するScript

## やりたいこと
特定の曜日にだけ動くScriptを書きたい。

## 準備
Momentを使うために、

- リソース > ライブラリから
- `MHMchiX6c1bwSqGM1PZiW_PxhMjh3Sh48`

を追加してください。
詳細は、[Moment](https://momentjs.com/)をご覧ください。

## これで解決
例) 月曜にだけ動かしたい

トリガーで日次実行にしていただいて、以下を設定すればOKです。

```js
// Momentを使うために
// リソース > ライブラリから
// MHMchiX6c1bwSqGM1PZiW_PxhMjh3Sh48
// を追加しておく

// Momentを日本語設定に
Moment.moment.lang(
    'ja',
    { weekdays: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],
      weekdaysShort: ["日","月","火","水","木","金","土"]})


function main() {
  // momentを取得
  m = Moment.moment()
  // 省略形の曜日に書式を変更
  day_of_the_week = m.format('ddd')
  Logger.log(day_of_the_week)
  
  // 月曜以外であれば、強制終了
  if ( day_of_the_week !== '月' ) {
    Logger.log('強制終了')
    return
  }
  
  // 月曜であれば、以下を実行
  Logger.log('実行')
}
```
(普段は、console.info使うのですが、ちょっと事情があってLogger.logです。適当に変更してください。)

## 補足
```js
// Momentを日本語設定に
Moment.moment.lang(
    'ja',
    { weekdays: ["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],
      weekdaysShort: ["日","月","火","水","木","金","土"]})
```

特に不要ではありますが、日本語の曜日にならない!! っておっしゃる方用に作成してます。
データベースに保存　session75

入力して配列に一時保存している会員情報をデータベースに保存するプログラムを作成する。

まずはデータベースにアクセスするプログラムを作成していく。

データベースにアクセスするプログラムは何度も使用するので別ファイルに書いてインクルード（呼び出す）する形を取る。

同じフォルダ内にファイルを作成していく。
dbconnect.phpを作成する。

```
try{
try{
    $db = new PDO('mysql:dbname=mini_bbs；host=127.0.0.1;charset=stf8','root','root')
}
```
まずは例外処理というものをやっていく

mini_bbsの部分は phpMyAdminで作った今回使用するDBの名称になる
host後のIPアドレスはローカルアドレスを指定
文字はutf8を指定
ユーザー名とパスワードはMAMPの場合、それぞれ root になる（XAMPPの場合、パスワードは’’　←なし）

これでDBに接続できるようになる。

今回作成した　dbconnect.php　をcheck.php の会員登録のデータベースに登録していく

-----------------------------------------------------------------------------
```
<?php
session_start();
require('../dbconnect.php');

if(!isset($_SESSION['join'])){
	header('Location: index.php');
	exit();
}

//登録ボタンが押されたら、データベースに情報を保存する
if(!empty($_POST)){
	$statement = $db->prepare('INSERT INTO members SET name=?, email=?, password=?, picture=?, created=NOW()');
	echo $statement -> execute(array(
		$_SESSION['join']['name'],
		$_SESSION['join']['email'],
		sha1($_SESSION['join']['password']),
	));
	unset($_SESSION['join']);

	header('Location: thanks.php');
	exit();
}

?>
```
check.phpの先頭部分に`require('../dbconnect.php');`を追加する。

prepareで準備した ? に値を入れていく。
echo 以降の記述で値を入れていく。

unsetは SESSION変数を空にする命令になる。
→上記の記述でデータベースに値を保存したのでSESSION変数に値を保存しておく
意味がなくなったので初期化しておく。
保存し終わったSESSION変数に値が残っているとデータベースのデータと重複してしまう
可能性があるのでそれを防いでおく。

データベースに保存し、SESSION変数の値を空にしたら、
`header('Location: thanks.php');
exit();`でthanks.phpに移動して処理を終了させる。
ncc で ビルドしてみた[Typescript]

# やること

`tsc` で **lib/** にビルドした後に `ncc` で再びビルドし、 **dist/index.js** の 1ファイルにまとめる

## メリット

- 軽い
- minify がお手軽に行える(`-m` オプションをつけるだけ)
- 圧縮率が良い感じ(?)(未検証)
- webpack 等の複雑な設定ファイルを書かなくて良い

こんなところに感じた

## package.json

主なオプション

- main: lib/main.js
- scripts
  - build: "tsc"
  - pack: "ncc build -m"

`build` の後 `pack` を実行する

```ts
{
  "name": "add-issue-links",
  "version": "1.0.3",
  "description": "A GitHub Action for adding an issue reference to a pull request.",
  "main": "lib/main.js",
  "scripts": {
    "build": "tsc",
    "format": "prettier --write \"{src,test}/**/{*.ts,*.tsx,*.js,*.jsx}\"",
    "format:check": "prettier --check \"{src,test}/**/{*.ts,*.tsx,*.js,*.jsx}\"",
    "lint": "eslint \"{src,apps,libs,test}/**/{*.spec.ts,*.ts,*.tsx,*.js,*.jsx}\"",
    "lint:fix": "eslint \"{src,apps,libs,test}/**/{*.ts,*.tsx,*.js,*.jsx}\" --fix",
    "test": "jest --passWithNoTests",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "pack": "ncc build -m",
    "all": "npm run format && npm run lint && npm test && npm run build && npm run pack"
  },
  "author": "tktcorporation",
  "license": "MIT",
  "dependencies": {
    "@actions/core": "^1.2.3",
    "@actions/github": "^2.1.1"
  },
  "devDependencies": {
    "@types/jest": "^25.1.4",
    "@types/node": "^13.9.2",
    "@typescript-eslint/parser": "^2.24.0",
    "@zeit/ncc": "^0.22.3",
    "eslint": "^6.8.0",
    "eslint-plugin-github": "^3.4.1",
    "eslint-plugin-jest": "^23.8.2",
    "jest": "^25.1.0",
    "prettier": "^1.19.1",
    "ts-jest": "^25.2.1",
    "typescript": "^3.9.7"
  }
}
```

# tsconfig.js

tsc の 実行用

- module: "commonjs"
- outDir: "./lib"

```ts
{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "strictPropertyInitialization": true,
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "target": "es2019",
    "sourceMap": true,
    "outDir": "./lib",
    "baseUrl": "./",
    "incremental": true
  },
  "include": [
    "**/src/**/*"
  ],
  "exclude": [
    "node_modules",
    "test",
    "__test__",
    "dist",
    "lib",
    "**/*spec.ts",
  ]
}

```

# 参考

- https://future-architect.github.io/articles/20200319/
- https://qiita.com/kyusyukeigo/items/d913d35e455aba782c55
新卒プログラマの学習ログ　〜　其の二　〜

#App Architecture
Codelabsをとりあえず一周、手を動かしながら進めてみました。

その中で、書かれているコードのパターンが、MVVM（Model-View-ViewModel）と呼ばれるアーキテクチャです。
Googleより推奨されているライブラリを用いた実装パターンで、これに従うことでメンテナンス性、可読性に優れたプログラムとして開発を行うことができるとされています。
しかし、普及としては割と最近のようで、Androidアプリ開発者用の参考書ではまだまだ異なるパターンの記述が多い印象です。

##MVVMとは？
先述の通りModel-View-ViewModelを表しています。

###Model
データを管理する役割を担います。
APIやデータベースを扱う際のDaoやdataクラスに当たります。

###View
UIコントローラーの役割を担います。
画面表示や遷移、Fragmentの切り替えやユーザーのアクションを検知するリスナーをここで設定します。
Viewの管理はDataBindingのライブラリによって行っています。
下記のコードではフラグメントでの実装です。

```MainFragment.kt
class MainFragment : Fragment() {

    // OnCreateView以外でも参照するため、lateinitで定義しておきます
    private lateinit var binding: MainFragmentBinding

    private lateinit var viewModel: ViewModel

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {

        binding = DataBindingUtil.inflate(
                inflater,
                R.layout.game_fragment,
                container,
                false
        )
        Log.i("MainFragment", "Called ViewModelProviders.of")

        // viewModelの取得
        viewModel = ViewModelProviders.of(this).get(GameViewModel::class.java)

        binding.sampleButton.setOnClickListener { onClick() }
        
       
        return binding.root
    }

    /** ボタンクリック時に実行するメソッド **/
```

###ViewModel
Modelからデータを取得するViewとModel間の仲介的役割を担います。


#とりあえず。。
メモ代わりに書いていますが、これから理解が深まれば書き足していきます。

# 初学者から一人前まで、、
ここでは一人前のプログラマの定義を
「おおよそ自力で様々なツールを活用しながら、ある程度思い通りの実装ができること」
とします。

また、人生においてプログラミングに向き合う時間として、現時点で2000時間取り組めればある程度の基盤が備わると仮定しています。
（言語やツールに依存しない思考法や情報収集能力）

プログラミングは大学で学んで来ましたが、特に根詰めてやってきていないので、ノーカウントとして取り組みます。

現在までの学習時間
**およそ340時間**
どんどん更新していきます。
JavaScriptのfetch()にcgiで返すときは改行コードを取ろう

# 概要
- Javascriptでfetch()からサーバに問い合わせした時に、文字列を返すとします。その文字列を読み込んだのに条件判定に失敗しました。
- わかってしまえば簡単なこと。文字列に改行コードが入っていたのでした。

## コード
cgiで何かの処理とか条件判定した時に文字列をJavaScript/fetch()に返すとき、JavaScriptでは例えばこんな問い合わせをサーバにするとします。

```{JavaScript}
...
fetch('/cgi/hoge.cgi', {
  headers : {"Content-Type": "text/html"},
  body    : hoge
}).then(response => {
  sonsole.log(response.text);
  if (response.text === "FILE_EXIST" ){
    ...
    //ファイルがあった場合の処理
    ...
  }
}).catch(error => {...})

```

サーバ側のhoge.cgiでは問い合わせに結果を返す時に、例えばファイルが存在するのかを文字列で返したとします。その例です。

```{bash}
$ cat hoge.cgi
# なんかの条件判定を設定。
...
# 例えばファイルが存在するか？
[ -f $hoge ] && result="FILE_EXIST" || result="NONE"
#結果を返す
echo "Content-type: text/html"
echo ""
echo -n $result
exit 0
```
ポイントは`echo -n`と改行コードをつけないようにすることです。最初`echo $hoge`で返してうまく行かなたったので一晩悩みました。`console.log(response.text)`ではリターンが表示されないので気が付きませんでした。XRLのレスポンス（応答ペイロード）を見て気が付きました。

どなたかのお役に立てれば嬉しいです。
BIG-IPのAuto Last Hop機能には気をつけろ！！

# はじめに
ふと以前仕事でハマったことを思い出したので、どこかの誰かが同じことでハマらないよう書き残しておきます。

別ベンダが担当していたF5社製負荷分散装置の`BIG-IP LTM`を他社製品に入れ替える際、`Auto Last Hop`機能で苦労させられたという話です。

# BIG-IPのAuto Last Hop機能とは
応答パケットを送信元に返送する際、送信パケットを受け取った時にあらかじめ覚えておいたMACアドレスに返送する機能。

つまり複数ゲートウェイが存在するような場合、**いちいちルーティングを設定しなくても送信元のゲートウェイに対してパケットを返送する機能**になります。

【参考】[トラフィックの戻り先決定方法について](http://www.f5networks.co.jp/shared/pdf/BIG-IP_TB_Last_Hop.pdf)

## Auto Last Hopの厄介な点
1. `Auto Last Hop`が有効の場合、対象となるパケットはルーティングテーブルに**従わない**。
2. BIG-IPではデフォルトで`Auto Last Hop`が有効になっている。

デフォルトで有効となっているため、そもそも担当者も分かっていない場合もあるというのが一番厄介。

理解して使用する分には非常に便利な機能なんですけどね。

# 何があったか
あるクライアントから通信する際、通常ネットワークA経由で`BIG-IP LTM`にアクセスしますが、設計書にも載っていなかった要件で、**リダイレクトされた通信の場合のみネットワークB経由でアクセスしていた**ことが発覚しました。

![AutoLastHop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/9db7fc6a-9713-da01-8f41-b79547b613bf.png)

そもそもルーティング等から追えなかったのは前述の通り、`BIG-IP LTM`では`Auto Last Hop`がデフォルトで有効となっているため、**ルーティングテーブルに書かれていなくても**ネットワークA経由で通信が来た場合はネットワークA経由で応答パケットを返送し、ネットワークB経由で通信が来た場合はネットワークB経由で応答パケットを返送していたため、気付けなかったということですね。

`BIG-IP LTM`は私もよく使っていた機器だったので`Auto Last Hop`自体の動きも知ってましたが、さすがに設計書にも書かれていない要件までは気づけなかった・・・

# どう対応したか
他社製品には`Auto Last Hop`に相当する機能が無かったため、前段のルータでポリシールーティングをゴリゴリ書いて何とか対処しました。

# 最後に
`BIG-IP LTM`を別の担当者から引き継ぐとか、入れ替えるという場合は、ルーティングだけではなく、`Auto Last Hop`の動きにも注意しましょう。
OAuth認証プロセスについてのメモ

OAuth1.0a を使ったプログラムを書いていて、OAuth について整理したくなったのでメモ。
Webシステムを想定。

OAuth の文脈で言うと、ユーザー、サービスプロバイダー、コンシューマーの3者を想定する。

ユーザーはとにかくサービスプロバイダーのサービスを受けたい。
ここではサービスプロバイダーをZaimとしましょう。
Zaimのサービスを利用するにはユーザーはZaimにアカウントを作ります。
ユーザーに紐付いた情報をサービスするのですから当然ですね。
Zaimは個々のユーザーのデリケートな情報を扱わなければならないので、あるユーザーを他のユーザーと区別しなければなりません。このプロセスを認証(Authentication)といいます。多分。
Authentication の意味を Google 先生に確認してみましょう。

the process or action of proving or showing something to be true, genuine, or valid.

何かが正式なものであることを証明するためのプロセスのことらしいです。コンピューティングにおいては、

the process or action of verifying the identity of a user or process.

とのことで、この場合、サービスプロバイダー(Zaim)が、ユーザーが本当にサービスにアカウントを持っているか、また、ユーザーが誰であるかユーザー自身に証明してもらうプロセスになりますかね。

やさしい世界においては、名前があれば十分かもしれませんし、そのような認証はあちこちに存在しますが、名前は運用上もセキュリティ上も不備が多いです。

Webサービスにおいては、セキュリティの度合いに応じて様々な認証方法が存在するかと思いますが、サービス上でユニークな、ユーザーが任意に決めたユーザー名（もしくはE-mailアドレス）＋パスワードという形式がポピュラーなのではないでしょうか。私の認識ではZaimもこの方式です。

サービスプロバイダーはこの2つで1セットの情報をもとに、ユーザーを認証します。いつも思うのですが、なぜ本質的には1つの情報を2つに分けるのでしょうか？パスワードだけでよくない？この疑問は根が深そうですが、少なくともシステムでユニークなIDと任意のパスワードに分けることで、前者が絶対にかぶらないことを保証でき、後者がかぶることを許容でき、全体としては絶対にかぶらないという性質を担保できそうです。

ユーザーがIDとパスワードをサービスプロバイダーに提示して晴れてサービスプロバイダーに認証されると、ユーザーはサービスプロバイダー(Zaim)のサービスを受けることができます。具体的には収支を入力したり統計を閲覧したりとかですね。いわばZaim公式のサービスです。

しかしユーザーの中には、公式のサービスは使いづらいと感じる人がいるかもしれません。Webサービスはだいたい機能とUIがセットなので、機能は欲しいがUIが気に入らないというユーザーにはちょっともったいないですよね。そこで、機能だけを開発者に開放して、UI開発の余地を与えるシステムがOAuthです！(あってる？)

ここでいう開発者が、OAuthでいうコンシューマーですね。サービスプロバイダーの提供する機能を消費(利用)して、独自のUIを設計し、アプリとしてユーザーに提供できるのです。なんて素晴らしい！

ここからが本題なのですが、OAuth1.0aではどうやってこれを実現しているのでしょうか。

私調べでは、まずコンシューマーはあらかじめサービスプロバイダーに開発者としてアカウントを作ります。サービスプロバイダーは、開発者を認証するための「コンシューマーID」と「コンシューマーシークレット」を発行します。ユーザーの例で出てきたIDとパスワードみたいなものですね…ん？

ここで早くも間違いに気づきました。そもそも開発者は、サービスプロバイダーの提供する機能を使って、「アプリ」を作ることが前提となっています。「コンシューマーID」と「コンシューマーシークレット」は「アプリ」に紐付けられます(どうやら)。アプリは複数登録でき、アプリごとに権限範囲など、設定が可能です。このへんの話はZaimの場合の話かもしれませんが、先に進みます。

開発者はアプリの実装上、ユーザーに機能を提供するために、最終的には「シークレットトークン」なる、一定期間だけ有効な鍵のようなものをサービスプロバイダーからゲットする必要があります。この魔法の鍵により、コンシューマーであるアプリがZaimの機能にアクセスして調理し、ユーザーに提供することができるのです。

このシークレットトークンを得るためには、どうしてもユーザーにサービスプロバイダーへの認証をお願いしなければなりません。この認証のための画面だけは、サービスプロバイダーが提供することになります。そうしなければ、コンシューマーが間に入ってユーザーの認証情報を知ってしまうことになるからです。コンシューマーができるのは、サービスプロバイダーの窓口(後述)をユーザーに知らせることだけです。

ユーザーは、コンシューマーにもらった伝票にかいてあるサービスプロバイダーの窓口へ行き、認証してもらい、伝票にハンコを押してもらい、その伝票をコンシューマーの窓口に戻します。この辺の作業はブラウザが手伝ってくれるので、ユーザーはそれほど大変ではありません。伝票とかハンコはあくまでイメージです。

コンシューマーは受け取った伝票をサービスプロバイダーに提出し、間違いなくサービスプロバイダーの認証したユーザーがコンシューマーを通じてサービスプロバイダーの機能を利用することを承諾した旨を確認し、コンシューマーは晴れてシークレットトークンをサービスプロバイダーからゲットすることができます。

ここで一つ説明をおろそかにした部分があるのですが、ユーザーを認証するためのサービスプロバイダーの窓口は、コンシューマーごとに専用の窓口があります。こうすることで、サービスプロバイダーとコンシューマーが連携していることをユーザーに示すことができ、ユーザーは安心して認証プロセスを完了させられるのです(この辺の理解はまだあやふや)。

このユーザー認証窓口を設置するために、コンシューマーはまず最初に自身をコンシューマーIDとコンシューマーシークレットを使ってサービスプロバイダーに認証してもらい、まずリクエストトークンとリクエストシークレットというものをもらい、その2つを使って窓口(認証用URL)を用意してもらうという手順を踏みます。このリクエストトークン＆シークレットは、シークレットトークンを得るときにも必要になるので、一旦ブラウザセッションの切れるコンシューマーアプリは、セッションなどに保存しておく必要があります。

以上、先人が何度書いたかわからない、アウトプットのためのOAuthに関するメモでした。
Kinx アルゴリズム - ハノイの塔

# Kinx アルゴリズム - ハノイの塔

## はじめに

**「見た目は JavaScript、頭脳(中身)は Ruby、（安定感は AC/DC）」** でお届けしているスクリプト言語 [Kinx](https://github.com/Kray-G/kinx)。「プログラム＝アルゴリズム＋データ構造」。アルゴリズムの実装例をご紹介。

元ネタは「C言語による（30年経っても）最新アルゴリズム事典」。今回はライフゲームです。

* 参考
    * 最初の動機 ... [スクリプト言語 KINX（ご紹介）](https://qiita.com/Kray-G/items/ca08b6fb40d15dd0ec76)
        * 個別記事へのリンクは全てここに集約してあります。
    * リポジトリ ... [https://github.com/Kray-G/kinx](https://github.com/Kray-G/kinx)
        * Pull Request 等お待ちしております。  

最新アルゴリズム事典にはこういうのも結構載ってる。パズル的な。

Kinx では最初のころにこのサンプルコードを書いて、再帰関数の確認に使った。良いテストになった。

## ハノイの塔

* https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%8E%E3%82%A4%E3%81%AE%E5%A1%94

Wikipedia より
> 以下のルールに従ってすべての円盤を右端の杭に移動させられれば完成。
>
> * 3本の杭と、中央に穴の開いた大きさの異なる複数の円盤から構成される。
> * 最初はすべての円盤が左端の杭に小さいものが上になるように順に積み重ねられている。
> * 円盤を一回に一枚ずつどれかの杭に移動させることができるが、小さな円盤の上に大きな円盤を乗せることはできない。

## ソースコード

```javascript
function movedisk(n, a, b) {
    if (n > 1) movedisk(n - 1, a, 6 - a - b);
    System.println("円盤 %d を %d から %d に移す" % n % a % b);
    if (n > 1) movedisk(n - 1, 6 - a - b, b);
}

const N = 4;
System.println("円盤 %d 枚を柱 1 から柱 2 に移す方法は"
        "次の %u 手です." % N % ((1 << N) - 1));
movedisk(N, 1, 2);
```

## 結果

```
円盤 4 枚を柱 1 から柱 2 に移す方法は次の 15 手です.
円盤 1 を 1 から 3 に移す
円盤 2 を 1 から 2 に移す
円盤 1 を 3 から 2 に移す
円盤 3 を 1 から 3 に移す
円盤 1 を 2 から 1 に移す
円盤 2 を 2 から 3 に移す
円盤 1 を 1 から 3 に移す
円盤 4 を 1 から 2 に移す
円盤 1 を 3 から 2 に移す
円盤 2 を 3 から 1 に移す
円盤 1 を 2 から 1 に移す
円盤 3 を 3 から 2 に移す
円盤 1 を 1 から 3 に移す
円盤 2 を 1 から 2 に移す
円盤 1 を 3 から 2 に移す
```

## おわりに

こちらも C 言語版ほぼそのままです。GitHub は英語基準なのでこれまで文言を英語に直していましたが、一応日本語でも動くので、今回の上記のソースコードは日本語のままにしました。ただし GitHub に例としてコミットしているものは英語にしてあります。

ではまた、次回。
NaturalLanguageフレームワークを使用して日本語のための自然言語処理

Appleには、テキストの分析を支援する `NaturalLanguage` というフレームワークがあります。この記事は、日本語テキスト分析のための自然言語フレームワークがサポートする、いくつかの機能について取り上げます。

```swift
import NaturalLanguage
```

- テキストの言語を検知
- 文を単語区分に分割

この例では、入力テキストは以下のとおりです。

```
データの保存はiOSアプリの持つ主要な機能です。たとえば、ユーザーが指定した色などの環境設定を保存したり、ウェブサイトのトークンをアプリに保存したり、ToDoリストのアプリを作ってタスクを保存したりすることができます。データをシステムに保存する方法はいくつもあります。
```

## 言語検知

このコマンドを実行して、文の言語を検知できます。

```swift
func detectLanguage(text: String) {
    let recognizer = NLLanguageRecognizer()
    recognizer.processString(text)
    print("Language: \(recognizer.dominantLanguage?.rawValue ?? "unknown")")
}
```

結果はこのとおりです。

```
Language: ja
```

## トークンへの分解

このコマンドで文を単語に分解します。

```swift
func tokenize(text: String) {
    let tokenizer = NLTokenizer(unit: .word)
    tokenizer.string = text
    let tokens = tokenizer.tokens(for: text.startIndex ..< text.endIndex)
    var textTokens: [String] = []
    for token in tokens {
        let tokenStartI = token.lowerBound
        let tokenEndI = token.upperBound
        let text = text[tokenStartI ..< tokenEndI]
        textTokens.append(String(text))
    }
    print(textTokens)
}
```

結果はこのとおりです。

```
["データ", "の", "保存", "は", "iOS", "アプリ", "の", "持つ", "主要", "な", "機能", "です", "たとえば", "ユーザー", "が", "指定", "し", "た", "色", "など", "の", "環境", "設定", "を", "保存", "し", "たり", "ウェブサイト", "の", "トークン", "を", "アプリ", "に", "保存", "し", "たり", "ToDo", "リスト", "の", "アプリ", "を", "作っ", "て", "タスク", "を", "保存", "し", "たり", "する", "こと", "が", "でき", "ます", "データ", "を", "システム", "に", "保存", "する", "方法", "は", "い", "くつ", "も", "あり", "ます"]
```

`NaturalLanguage` フレームワーク内には他の機能もあります。試してみましたが、英語でのみ利用可能なものもありました。より多くの機能が利用可能になりましたら、この記事を更新します。

---

:relaxed: [Twitter @MszPro](https://twitter.com/MszPro)

:sunny: [私の公開されているQiita記事のリストをカテゴリー別にご覧いただけます。](http://mszpro.com/ioskiji/)
<img width="150" src="https://cdn.mszmagic.com/static-web-content/AppClipImage_small.png">
【React Hooks】useState()でcannot assign to read only propertyが出た時の対処法

# はじめに
useState()でオブジェクトを管理していましたが、タイトルのようなエラーが発生したので、その解決法を記してあります。

# エラー時のコード
```react:test.js
import React, { useState, useEffect } from "react";
import { db } from "../firebase.js";

const Test = () => {
  const [imgStyle, setImgStyle] = useState({backgroundImage: ""});

  useEffect(() => {

   db.collection("test").get().then((querySnapshot) => {
      querySnapshot.forEach((doc) => {
        const docVal = doc.data();
        imgStyle["backgroundImage"] = `url(${docVal.imgUrl})`;
        setImgStyle(Object.assign({}, imgStyle));
      });
    }).catch(function(error) {
      console.log("Error getting document:", error);
    });

  }, []);

  return (
    <div>
      <div className="reportBefore" style={imgStyle}></div>
    </div>
  );
}

export default Test;

```

# 解決後のコード
```react:test.js
import React, { useState, useEffect } from "react";
import { db } from "../firebase.js";

const Test = () => {
  const [imgStyle, setImgStyle] = useState([]);

  useEffect(() => {

   db.collection("test").get().then((querySnapshot) => {
      querySnapshot.forEach((doc) => {
        const docVal = doc.data();
        setImgStyle(oldForm => [...oldForm,
          {backgroundImage: `url(${docVal.imgUrl})`}
        ]);
      });
    }).catch(function(error) {
      console.log("Error getting document:", error);
    });

  }, []);

  return (
    <div>
      <div className="reportBefore" style={imgStyle[0]}></div>
    </div>
  );
}

export default Test;

```

# まとめ
読みのみで変更はできないので、useStateでオブジェクトを扱う際は追加のイメージを忘れずに持っておくことが必要です。
AWS IAM メモ

### IAM
AWS全体の認証認可基盤

### IAM user
アカウント作成時のルートユーザーとは異なる作成されたユーザー
権限を制限したIAM userを付与するのが基本
policyやroleをアタッチできる
しかしIAM groupへpolicyやroleをアタッチして使うのがベストプラクティス

### IAM group
roleやpolicyをアタッチ可能な集合
ここにユーザーを所属させるのがベストプラクティス

### IAM policy
AWSへのアクセス権限
管理ポリシーとインラインポリシーがある

### IAM role
EC2やlamdaにアタッチして権限付与ができる
内部的には使い捨てのキーとパスを発行しているらしい
【macOS】Pythonのversionを切り替える方法【pyenv】

# はじめに
※本記事はPython初心者向けに記載した記事です。
　分かりにくい箇所や誤りはご指摘いただければ幸いですm(__)m

pythonのversionを2系から3系に切り替えるために以下の記事を参考にしたのですが、
つまずいてしまったので同じような事象が発生している方向けに参考になればと思い、記載します。
#### 参考サイト 
[それでもPythonのversionを切り替えたい](https://qiita.com/bootsnin/items/5735f667a83beaca078b)


# .bash_profile を編集しても python の version が2系のまま。。
上記参考サイトの通り、.bash_profile を編集し、いざターミナルで以下のコマンドを実行しても version は2系のままでした。

```ruby:qiita.rb
python --version
```

# python のパスを確認
そこで次のコマンドを実行すると

```ruby:qiita.rb
which python
```

[/usr/local/bin/python]と返ってきました。
pyenv でインストールした python の version を見にいっていないようです。

[~/.pyenv]と返ってきた場合は以下のサイトを参考にしてください。

#### 参考サイト 
[pyenv globalで切り替わらない！](https://qiita.com/1234224576/items/11ad3509fe4b0a9a33ed)

# pyenv のversionを確認
以下のコマンドで pyenv の version を確認します。

```ruby:qiita.rb
pyenv versions
```
次のように pyenv でインストールした python の version 表示されます。

```ruby:qiita.rb
  system
* 3.8.1 (set by /Users/[username]/.pyenv/shims/python3)
```

### pyenv ってなんぞや!?って方向けに
簡単にpythonの複数versionを管理することができるソフトウェアです。
利用する前にHomebrewをインストールする必要があります。
詳しくはGitHubを参照して下さい。
#### Github
[simple Python Version Management: pyenv]
(https://github.com/pyenv/pyenv#installation)

以下のサイトが使い方など分かりやすく記載されていましたのでご参考までに。
#### 参考サイト 
[Managing Multiple Python Versions With pyenv](https://realpython.com/intro-to-pyenv/#using-pyenv-to-install-python)

# pyenv の version を default に設定
ここまでで、pythonのパスが[/usr/local/bin/python]を見にいっていること、
pyenv の version が3系であることが確認できました。

次に、 pyenv の version を見にいくよう、　.bash_profile　を編集します。
以下のコマンドをターミナルで実行して下さい。

```ruby:qiita.rb
vi ~/.bash_profile  
```

編集モードで以下を追記して下さい。

```ruby:qiita.rb
alias python='/Users/[username]/.pyenv/shims/python3'
```
[esc]キーを押して以下を入力して下さい。

```ruby:qiita.rb
:wq
```
bash_profileを更新します。

```ruby:qiita.rb
source ~/.bash_profile
```
再度、以下のコマンドを実行するとpyenvで設定したpythonのversionが表示されます。

```ruby:qiita.rb
python --version
```
#### 参考サイト 
[stackoverflow:how to change default python version?]
(https://stackoverflow.com/questions/5846167/how-to-change-default-python-version)
Rust, Ubuntu で Windows 向けに SDL2 アプリをビルドする

# 概要
Ubuntu (WSL) で Windows 用の GUI アプリを Rust で作りたかったので、 SDL2 を動かすまでのメモです。

## コンパイルターゲットを追加
rustup で windows 用のツールチェインを追加。

``` sh
$ rustup target add x86_64-pc-windows-gnu
```

windows 用のリンカをインストール

``` sh
$ sudo apt install mingw-w64
```

## SDL の準備
SDL のサイト https://www.libsdl.org/download-2.0.php から `SDL2-devel-2.0.12-mingw.tar.gz` をダウンロード

``` sh
$ tar xf SDL2-devel-2.0.12-mingw.tar.gz
$ cp -r SDL2-2.0.12/x86_64-w64-mingw32/lib/* ~/.rustup/toolchains/stable-x86_64-unknown-linux-
gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/
```

## プロジェクトを作る
``` sh
$ cargo new mysdl
$ cd mysdl
```

Cargo.toml はこちら。

``` toml:Cargo.toml
...
[dependencies]
sdl2 = "0.32"
```

使用するリンカを指定するために、`mysdl/.cargo/config` ファイルを作る。中身は以下。

``` toml:mysdl/.cargo/config
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
```

`main.rs` は適当にこんな感じ。

``` rust:mysdl/src/main.rs
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::Color;
use std::time::Duration;
use std::thread;

fn main() {
    let sdl_ctx = sdl2::init().unwrap();
    let video_subsys = sdl_ctx.video().unwrap();
    let window = video_subsys.window("SDL2", 640, 480)
        .position_centered()
        .build()
        .unwrap();
    let mut canvas = window.into_canvas()
        .build()
        .unwrap();
    let mut event_pump = sdl_ctx.event_pump().unwrap();

    'running: loop {
        canvas.set_draw_color(Color::RGB(0, 255, 0));
        canvas.clear();
        canvas.present();

        for ev in event_pump.poll_iter() {
            match ev {
                Event::Quit {..} |
                Event::KeyDown {keycode: Some(Keycode::Escape), ..} =>
                    break 'running,
                _ => {}
            }
        }
        thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
    }
}
```

## ビルド
``` sh
cargo build --target x86_64-pc-windows-gnu --release
```

ビルドに成功すれば、`mysdl/target/x86_64-pc-windows-gnu/release/mysdl.exe` に実行ファイルが生成されます。

## SDL2.dll を入手
SDL のサイト https://www.libsdl.org/download-2.0.php から `SDL2-2.0.12-win32-x64.zip` をダウンロードします。
解凍すると `SDL2.dll` があります。

## 実行
ビルドした `mysdl.exe` と `SDL2.dll` を同じディレクトに置いて `mysdl.exe` を実行すると動きます。
黄緑色のウィンドウが出ます。閉じるボタンか Esc キーで閉じることができれば成功です。

お疲れさまでした。:coffee:
HTMLへの動画の埋め込み方

## なぜ記事を書いたのか
ポートフォリオ サイトに、動画を埋め込もうとした際に備忘録として残しておきたかったからです。

##　方法
```OOO.html
<video src="video.mov" controls></video>
```
といった形の記述をして動画ファイルをvscode内に取り込めば
<img width="644" alt="スクリーンショット 2020-07-30 2.50.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636995/6948113e-bb33-1c98-8644-fd444b02463c.png">
このような形でコントロールパネル付きで動画が表示されるようになります。
以上です。
AWSの監視入門したのでCloudWatchについてざっくりまとめ

ブログからの転載です
https://wally-ngm.hatenablog.com/entry/2020/07/28/180048

----

最近こちらのハンズオンをちらほら進めております.
https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-hands-on/:embed:cite


今日は監視編をやってみましたが, CloudWatchって色々機能あって驚いたのでメモしておきます.
全て網羅しているわけではないです.

# まとめ

|  サービス  |  用途  | 備考 |
| ---- | ---- | ---- |
|  メトリクス  |  ちょい調べたい ときに使える  | |
|  ロググループ  |  インサイトでクエリの対象になる. mysqlでいうテーブル的な.  | ロググループへログを集める設定が別途必要 |
| インサイト | クエリ書いてログをより好きなように見れる.(4xx系のエラーだけにフィルタしたり)||
| アラーム | 何か異常起きたら知らせれる. | SNS使って知らせると楽ちん|
| ダッシュボード | ダッシュボード| |


## メトリクス

リソースのメトリクスをぽちぽち選んで見れる.
Redash的なダッシュボードではなく, そのときに見たいものを見るような用途で使いそう.

Redashみたいなダッシュボードが欲しい場合は, `ダッシュボード` という別の機能を使える.

## ロググループとインサイト

`ロググループ` に対して各アプリケーションはログを吐き出す.
EC2とかが吐き出したログは勝手にCloudWatchで見れるようになるが, ロググループを指定するのはルールとか, cloudwatch agentが関係してきそうだけどそのへんはまだ分からない.

`インサイト` ではクエリを書いてそのログを好きなように加工して見れる.

## アラーム

EC2が死んだときとか, CPUの使用量が増えたときなどにアラームを出せる.
アラームの出す先はSNSっていうサービスを使ったり, Lambda使ったりできる.


## ダッシュボード

今まで見てきたようなメトリクス, インサイトを常にまとめて見たいときに使える.Redash的なやつ.



次はちゃんと稼働してるサービスの監視設定したい.
あともうちょっと何にお金がかかって何にお金がかからないのかを調べて追記したい.
micro:bitとProcessingでSerial通信して可視化する2

以前書いた[記事](https://qiita.com/kikpond15/items/e9256ead4779f365a1a3)より簡単にまとめました．
micro:bitの加速度をProcessingへ送り，画面サイズにmapしellipseで描画します．


## 1つの値を送る
### micro:bitコード
![スクリーンショット 2021-08-26 153153.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/c8099b9d-127f-d0ec-6524-80f05ad0862b.png)


### Processingコード
```java
import processing.serial.*;
Serial microbit;
float x = 0;

void setup() {
  size(640, 480);
  String []portName = Serial.list();
  println(portName);
  microbit = new Serial(this, portName[0], 115200);
}

void draw() {
  background(0);
  if (microbit.available() > 0) {
      int val = int(microbit.readString());
      x = map(val, -1023, 1023, 0, 640);
  }
  ellipse(x, height/2, 30,30);
}

```

## 複数の値を送る

### micri:bitコード
![スクリーンショット 2021-08-26 153021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/ae0fba7a-d281-2330-3696-1bb1d254bdb1.png)


### Processingコード
```java
import processing.serial.*;
Serial microbit;
float x = 0;
float y = 0;

void setup() {
  size(640, 480);
  String []portName = Serial.list();
  println(portName);
  microbit = new Serial(this, portName[0], 115200);
  microbit.bufferUntil(10);
}

void draw() {
  background(0);
  ellipse(x, y, 30, 30);
}

void serialEvent(Serial microbit) {
  String str = microbit.readStringUntil('\n');
  if (str != null) {
    str = trim(str);
    float[] sensors = float(split(str, ','));
    if(sensors.length > 1){
    x = map(sensors[0], -1023, 1023, 0,width);
    y = map(sensors[1], -1023, 1023, 0, height);
    }
  }
}

```
【ネタ】FORTRANでGoToキャンペーン

# これは何？

GoToキャンペーンに乗っかって（激遅）FORTRANでGoTo文を書くついでに忌まわしき要素をいくつか詰め込んでみたやつです。

**誤解の無いように言っておくと、現代におけるfortranでは改善されている(はずの)内容です。**

# お題

[AtCoderの問題](https://atcoder.jp/contests/abc170/tasks/abc170_b)から適当な奴を拝借しました。
都合上、ファイルIOなどを入れてみたりしているので少し変わっています。

要約すると、鶴亀算の問題。
鶴と亀が合わせてX匹(1≤X≤100),足の数Y本(1≤Y≤100)で、与えられたX,Yの妥当性を判断し"yes","no"を出力する。

**AtCoderでは入力は標準入力で与えられますが、今回はより実際に作られたプログラムっぽくファイル引き渡しにしています。**

## ソースコード

何はともあれソースコードを見ていただこう。

```fortran:MAIN.F
      PROGRAM MAIN
      COMMON /MYDATA/ NX,NY
      CALL READ
      NKAME = NX
      IFLAG = 1
C      WRITE(6,*) NX,NY
  10  NASHI = 2*NKAME + 4*(NX-NKAME)
      IF (NASHI.EQ.NY) IFLAG = 0    
      IF (NKAME.GT.0) THEN
      NKAME = NKAME -1
      GO TO 10
      END IF
CCCCCCC 結果出力
      IF (IFLAG.EQ.0) THEN
      WRITE(6,*) "YES"
      ELSE
      WRITE(6,*) "NO"
      END IF
      STOP
      END
```
```fortran:READ.F
      SUBROUTINE READ
      COMMON /MYDATA/ NX,NY
      OPEN(99,FILE="INPUT.DAT",STATUS="OLD")
      READ(99,*) NX,NY
      END SUBROUTINE READ
```
入力ファイルはこんな感じで、適当にいじれます。

```text:INPUT.DAT
3 8
```

## 解説

### GO TO文

本題です。
FORTRANでのGoTo文はなぜか、DOループで書けるところをわざわざGoTo文+文番号でやっていることがあります。
いきなり文番号だけ出てきて後から、「あの文番号にもどれ」とか言われると認知負荷がやばいですね。(慣れると読めますが。。。）


```fortran:MAIN.F
      PROGRAM MAIN
  　　!(略)
  10  NASHI = 2*NKAME + 4*(NX-NKAME) !ここに戻る
      !(略）
      GO TO 10　!ここから↑
      !(略）
      END
```

時々ループの外からGoTo文と文番号使って、ループ途中に飛び込んでくる場合があってさらに頭が混乱したりしなかったり

### 暗黙の型宣言

fortranは静的型付け言語ですが、暗黙の型宣言というものが存在します。
特に指定しない限り、a~h,o~z始まりの変数は実数、それ以外は整数になります。
これを利用してハンガリアン記法やオレオレルールにのっとったコードが量産されます。
（今回は本数や個数はN始まりの変数としています）

### COMMON文

このCOMMON文は``COMMON /ブロック名/　変数``という形で使用します。
着目すべきはブロック名が同じであれば、同じデータ領域を指します。
COMMONを乱用すると、あらゆる変数がグローバルという素晴らしい()プログラムが完成してしまいます。

### 固定形式

見にくいと感じるのは私だけでしょうか。すべて大文字で書かれていると更に見にくく感じます。

パンチカードを使っていた時の名残です。以下の制限事項があります。
- 1行当たり72カラムまで
- 1~5カラムには文番号、1カラム目に`C`or`*`があればコメント行
- 6カラム目は通常は空白、文字があれば継続行として認識

## 簡単に改善方法

### GoTo文
それぞれに合った書き方をしましょう。どうしても使うなら、エラー処理のような、ソースの上から下へ行く方向にしましょう。

### 暗黙の型宣言

`implicit none`をつけましょう。コンパイラに怒ってもらいましょう。

### COMMON文
変数のスコープに気を付けながらmoduleで置き換えましょう。グローバルである必要がないなら、なるべくスコープは小さくしましょう。

### 固定形式

今は自由形式を使う方がいいんじゃないかな...（古いコードのメンテナンス等は除く)

# 最後に

GoToキャンペーンはやめといた方がいいんじゃないかなー:thinking:

~~一番やばいのは、これがコンパイルできてしまうコンパイラがやばい~~

# 参考
[NAG Fortran入門](https://www.nag-j.co.jp/fortran/index.html)
Java8以降のNullPointerException 対策例(Optional)


## 本稿について
Java8でNullPointerException の対策で新しいやり方が見つかっていますので自身の備忘的に書いておきます。


## 事象
早速ぬるぽ出してみます。

```java:java

public class Test {
	public static void main(String[] args) {
		String str = null;
		System.out.print(str.length());
	}
}
```

```java:処理結果
Exception in thread "main" java.lang.NullPointerException
	at Test.main(Test.java:6)
```
NullPointerExceptionが出てしまいました。
java8より実装された対処法として、Optional をつけてあげることで
NullPointer対処することができます。
下記のイメージで変更します。

```java:対処例
import java.util.Optional;

public class Test {

	public static void main(String[] args) {
		// nullを代入
		String str = null;
		
		Optional<String> strOpt = Optional.ofNullable(str);
		strOpt.ifPresent(v -> System.out.println(v.length()));
	}
}
```

NullPointerException は出ずに無事処理終了しましたー

## 簡単な解説
java8以降で`Optional`が実装されています
https://docs.oracle.com/javase/jp/8/docs/api/java/util/Optional.html

```java
Optional<String> strOpt = Optional.ofNullable(str);
strOpt.ifPresent(v -> System.out.println(v.length()));
```

上記のようにして、strを`Optional`でラップしてあげることで`ofNullable()`関数を使うことができます。
`ifPresent`関数の引数として、
いったん、変数`v`に`str`の中身を退避させて、System.out.pintline内で使う
このようなやり方をラムダ式(lambda expression)といい、Optionalと合わせてjava8より実装された新機能となります。

※ラムダ式についてまとめてある記事
https://engineer-club.jp/java-lambda-expression


## ちなみに`isPresent` と`get()`を使っているだめな例・・・（2020/07/31追記）
最初に下記の例を別パターンとして書いていましたが、下記のやり方は ***万死に値する対処法*** なようで、
自身への戒めを込めて悪い例として載せておきます。
こちらの記事をご覧頂くとお分かりいただけます
https://qiita.com/BlueRayi/items/ef46496ef2ef36b9cbb7
（※この記事を読むとそもそもOptional使ってのNullチェック自体ナンセンスなようですが。。）


```java:悪い例
import java.util.Optional;

public class Test {
	public static void main(String[] args) {
		String str = null;
		
		Optional<String> strOpt = Optional.ofNullable(str);
		if(strOpt.isPresent()) {
			String message = strOpt.get();
			System.out.println(message.length());
		}
	}
}
```

具体的には、if文内でisPresent()を使ってその値をget()というやり方は安易に実装できるが
Optionalを使うメリットを活かせておらず、isPresent()関数はやむを得ない場合の使い方、という捉え方をするのがよく、ニュアンス的に下記の記事がわかりやすそうです。

>getを使用する機会は少ないはずです。
>Optionalをわざわざ使用すると言うことは「値が入っていない場合はよしなにしてくれ」というメッセージです。
>getを使用していきなり例外になるのなら、NullPointerExceptionが発生するのと同じです。

https://irof.hateblo.jp/entry/2015/05/05/071450
int定数の代わりにenumを使用する

###int enumパターン
表現力が乏しい。
オレンジを期待しているメソッドにアップルを渡したり
アップルとオレンジを==演算子で比較してもコンパイラに怒られない。

````java
public static final int APPLE_FUJI = 0;
public static final int APPLE_PIPIN = 1;
public static final int APPLE_GRANNY_SMITH = 2;

public static final int ORANGE_NAVEL = 0;
public static final int ORANGE_TEMPLE = 1;
public static final int ORANGE_BLOOD = 2;

````

###enumを使用した場合

````java
public enum Apple {FUJI, PIPIN, GRANNY_SMITH}
public enum Orange {NAVEL, TEMPLE, BLOOD}
````

###値によって切り替えるenum型
以下のコードでは、技術的にはメソッドの終わりに到達可能であることや、
switchへ対応するcaseの追加を忘れるなどの問題点がある

````java
public enum Operation {
		PLUS, MINUS, TIMES, DIVID;

		// 定数で表される算術操作を行う
		public double apply(double x, double y) {
			switch(this) {
			case PLUS:
				return x + y;
			case MINUS :
				return x - y;
			case TIMES:
				return x * y;
			case DIVID:
				return x / y;
			}
			throw new AssertionError("Unknown op" + this);
		}
	}
````

抽象メソッドを定義し、定数ごとに抽象メソッドをオーバーライドすることで問題点を改善することができる。

````java
public enum Operation {
		PLUS {
			public double apply(double x, double y) {
				return x + y;
			}
		},
		MINUS {
			public double apply(double x, double y) {
				return x - y;
			}
		},
		TIMES {
			public double apply(double x, double y) {
				return x * y;
			}
		},
		DIVIDE {
			public double apply(double x, double y) {
				return x + y;
			}
		};
		public abstract double apply(double x, double y);
	}

````

ラムダを使用することでより簡潔にかける


````java

public enum Operation {
    PLUS((x, y) -> x + y),
    MINNUS((x, y) -> x - y),
    TIMES ((x, y) -> x * y),
    DIVIDE ((x, y) -> x / y);

    private final DoubleBinaryOperator op;

    Operation (DoubleBinaryOperator op) {
        this.op = op;
    }

    public double apply(double x, double y) {
        return op.applyAsDouble(x, y);
    }
}
````

こちらを参考にさせていただきました。
<a href="https://www.amazon.co.jp/dp/B07RHX1K53/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1">Effective Java</a>
RealityKitで動画テクスチャを設定する

WWDC2020で [Video materials](https://developer.apple.com/documentation/realitykit/videomaterial) が発表されました。こちらの動画 "[What's new in RealityKit](https://developer.apple.com/videos/play/wwdc2020/10612/)" で映像付きで解説されています。RealityKitでオブジェクトに動画を設定し再生できる新機能です。

この機能だけ試したくなりましたが、RealityKitで新規プロジェクト作成すると `Experience.rcproject` を読み込んで別シーンを表示する構成で簡単には試せません。そこでシンプルに平面を配置し動画を流すまでの部分を作成してみました。

![output2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63205/66633efc-28a9-a743-71f7-3a48e9d06df9.gif)

AR空間に配置されたPlaneで自動的に動画を再生します。
ソースコードは [こちら](https://github.com/satoshi0212/RealityKitVideoMaterialsExamples001) に置いています。

## 環境

- Xcode 12.0 beta 2
- iPadOS 14 beta
- iPad Pro 11 inch (第2世代)

## プロジェクト作成

今回は `Content Technology` を `RealityKit` で、`Interface`を`Storyboard`で作成しました。

<img width="480" alt="スクリーンショット 2020-07-29 3.22.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63205/72a06198-c459-f5a7-7475-b70e1ebe4da3.png">

`video001.mp4` をプロジェクトに追加しておきます。

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63205/b6493cfc-bcdf-4a4b-2b2b-bb71ab8791fc.gif)

## 実装

### ソース全体

```swift:ViewController.swift

import UIKit
import RealityKit
import AVFoundation

class ViewController: UIViewController {
    
    @IBOutlet private var arView: ARView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // ① Anchorの追加
        let anchor = AnchorEntity()
        arView.scene.anchors.append(anchor)

        // ② Playerの生成と動画再生
        let asset = AVURLAsset(url: Bundle.main.url(forResource: "video001", withExtension: "mp4")!)
        let playerItem = AVPlayerItem(asset: asset)
        let player = AVPlayer()
        player.replaceCurrentItem(with: playerItem)
        player.play()

        // ③ Plane生成とVideoMaterial設定
        let planeMesh = MeshResource.generatePlane(width: 0.8, height: 0.45)
        let material = VideoMaterial(avPlayer: player)
        let planeModel = ModelEntity(mesh: planeMesh, materials: [material])
        planeModel.position = SIMD3<Float>(0.0, 0.0, -1.0)
        anchor.addChild(planeModel)
    }
}
```

#### ① Anchorの追加
ARViewに対してAnchorを追加。

#### ② Playerの生成と動画再生
再生対象の動画から`AVPlayerItem`を生成。`AVPlayer`に設定し`play()`で再生開始。

#### ③ Plane生成とVideoMaterial設定
`MeshResource.generatePlane`でPlaneを生成。数値は現実世界でメートルです。これにより「0.8m x 0.45m の横長の板」が生成されます。`VideoMaterial`を生成後、`ModelEntity`で`Entity`生成。positionはzに-1.0を設定し「1メートル手前」を設定。anchorに`addChild`で追加。

この状態で起動すると

![output2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63205/66633efc-28a9-a743-71f7-3a48e9d06df9.gif)

無事再生されました！
【Flutter】ことはじめ

#まえがき
本記事はFlutterのセットアップが完了した後の動作確認用です。
インストールとflutter doctorによる初回セットアップを完了してから実行してください。

flutter doctorで詰まっていた場合、手前味噌で恐縮なのですがこちらに簡単な解決コードを載せているので確認してみてください。mm
https://qiita.com/kaitoland/items/6fe41fdcfeb3bbdb4001


#プロジェクトの作成

```
flutter create app_name
```

#起動
```
flutter run
```
このままだと、No supported devices connected.と出てくるので
以下のようにiOS androidをセットアップする

#iOS

```
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -runFirstLaunch

//起動
open -a Simulator
```

#Android
AndroidStudioからアプリを検索結果AVDを起動します

#起動 その2
シミュレータが起動した状態で、flutter runを実行するとアプリが起動します。
Railsのcredentials.yml.encとmaster.keyについて

Railsの秘匿情報管理用のファイルについて

## credentials.yml.enc

・アプリケーション内で使うキー情報を書いておく
・内容は暗号化されている状態

中身を見る/編集するにはターミナルでエディタを指定して開く必要がある。
`EDITOR=“vi” bin/rails credentials:edit`



## master.key
・credentials.yml.encの暗号化復号化に使う鍵(文字列)。
・バージョン管理に含まれていない(デフォルトで.gitignoreに指定されている)