OmniAICreator/Qiita-1.07M huggingface dataset:
User-Agent クライアント ヒントを使用した Windows 11の判別

2021年12月時点では、ユーザーエージェント（ＵＡ）から、Windows10とWindows11を判別することが出来ませんでしたが、javascriptによってUser-Agent クライアント ヒントを使用してWindows11を判別できる記事を見つけたので、メモ。


```script.js

navigator.userAgentData.getHighEntropyValues(["platformVersion"])
 .then(ua => {
   if (navigator.userAgentData.platform === "Windows") {
     const majorPlatformVersion = parseInt(ua.platformVersion.split('.')[0]);
     if (majorPlatformVersion >= 13) {
       console.log("Windows 11 or later");
      }
      else if (majorPlatformVersion > 0) {
        console.log("Windows 10");
      }
      else {
        console.log("Before Windows 10");
      }
   }
   else {
     console.log("Not running on Windows");
   }
 });

```

【参考サイト】
https://docs.microsoft.com/ja-jp/microsoft-edge/web-platform/how-to-detect-win11
@rollup/plugin-typescriptの8.2.5から8.3.0でincludeとexcludeのパス指定が変わった

## この記事の概要

タイトル通りですが、[@rollup/plugin-typescript](https://github.com/rollup/plugins/tree/master/packages/typescript)の8.2.5から8.3.0で`include`と`exclude`のパス指定が少し変わっていたので備忘録がてら記事にまとめました。

## 前提

React + TypeScriptでコンポーネントライブラリを作っている中で発見しました。

Storybookを導入しているのですが`*.stories.tsx`の型定義はビルド内容には含めたくありません。
そのため`rollup.config.js`内で`tsconfig`をオーバーライドしていました。

```jsonc:tsconfig.json（抜粋）
{
  "compilerOptions": {
    // オプション色々
    "rootDir": "src"
  },
  "include": ["src/**/*"]
}
```

```javascript:rollup.config.js（抜粋）
export default {
  input: "src/index.ts",
  output: {
    // オプション色々
  }
  plugins: [
    // プラグイン色々
    typescript({ exclude: ["src/**/*.stories.tsx"] })
  ]
}
```

### 8.2.5での挙動

元のコード | ビルドしたコード
--- | ---
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/5f868375-612e-8986-6081-45508e3ab90b.png) | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/bf2295bb-a93e-b2f7-cd33-5a8b62378475.png)

期待している通りになっています

### 8.3.0での挙動

コードは何も変えていないのに`stories.d.ts`が生成されてしまいました。

元のコード | ビルドしたコード
--- | ---
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/5f868375-612e-8986-6081-45508e3ab90b.png) | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/c6156576-2da2-09f9-dc38-15aad724fb63.png)

## 原因

8.3.0での変更内容は`filterRoot`というオプションの追加で、こちらのデフォルト設定によるものでした。

ざっくり説明すると、`include`と`exclude`のパターン指定において、ルートになるディレクトリを自分で指定できるようになる、というものです。
デフォルトでは`tsconfig.json`の`rootDir`を指定されていました。

つまり、もともと`rollup.config.js`に書いていた`exclude: ["src/**/*.stories.tsx"]`は、デフォルトの設定と相まって`src/src/**/*.stories.tsx`を指定しているのに等しくなっていたようです。

## 解決策

`exclude: ["**/*.stories.tsx"]`と指定したら無事期待通りの動きになりました。
子コンポーネントの再読み込みがかからない

# 目的
- 親コンポーネントと子コンポーネントがある。
- 親コンポーネントはデータアクセスがある
- 親コンポーネントのデータアクセス結果を子コンポーネントに伝え、それに合う表示をさせたい

# 環境
- react@17.0.2

## 問題と解決方法
### 実現したいこと
- 親コンポーネントで読み込んだデータを、子コンポーネントにpropで渡し（uid等）
- 子コンポーネント（ProfileComp） は、propの値を元にデータを検索し表示を行いたい

```
import React, {useState, useEffect} from "react";

// UIDを持たせるstate
const [illustUid, setIllustUid] = useState(0);

const Sample = (props) => {
  useEffect((props) => {
    loadData(params);
  },[]);

// 初期表示データの読み込み処理
  const loadData = (props) => {
    <<Firebaseからデータ取得>>.then((data) => { 
      // ここで
      console.log(item.id)
      setIllustUid(item.id);
    })
  }

  
  return (

    <Box>
      <ProfileComp uid={illustUid}/>  <= このコンポーネントが正しく表示されない
    </Box>
  );
}
  export default Sample;

```

### 問題
- しかし、子コンポーネント `<ProfileComp >` は、親コンポーネントのデータ読み込みが完了を待たずに描画がされる
- 親コンポーネントが `illustUid` を取得完了する前に、　`<ProfileComp>`の描画がされてしまうため、アイコンなど子コンポーネントの内容が正しく表示されなくなっている

![スクリーンショット 2022-01-08 15.09.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57455/cdc5153b-5f14-14a0-b54c-309ce5db79b1.png)
→アイコンのところに本当はpropで受け取ったuidを元に取得した画像を表示したいが、初期表示時はuidが得られるより先に描画されてしまい、 `<ProfileComp uid={null}>` の状態で表示されてしまっている。useEffectで実行される `loadData`　の読み込み処理完了後に、データが入ってから再描画したい


# 解決方法
- state `illustUid`　の内容に応じて子コンポーネントの描画を切り替える
- 親コンポーネントの読み込みが完了し、`illustUid` に値がセットされたら、子コンポーネントを表示する次のような式にする
- `{illustUid&& <ProfileComp uid={illustUid}/>}`
- `illustUid`にデータが入ると`<ProfileComp uid={illustUid}/>` の再描画が走り、子コンポーネントが正しいデータで表示される

```

import React, {useState, useEffect} from "react";

// UIDを持たせるstate
const [illustUid, setIllustUid] = useState(0);

const Sample = (props) => {
  useEffect((props) => {
    loadData(params);
  },[]);

// 初期表示データの読み込み処理
  const loadData = (props) => {
    <<Firebaseからデータ取得>>.then((data) => { 
      // ここで
      console.log(item.id)
      setIllustUid(item.id);
    })
  }

  
  return (

    <Box>
      {illustUid&& <ProfileComp uid={illustUid}/>}　＜＝　修正箇所
    </Box>
  );
}
  export default Sample;

```
アンドキュメントな事実をどこまで使っていいのか

# 結論
私は使ってしまっています。
きっとよくないことだとは思っています。
~~愚痴~~反省として書きます。

# 例１
https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shell_notifyiconw

こんなWindows APIがありました。
実行結果はBOOLの戻り値のみで、`GetLastError`関数が使えるとは書いていません。
たまに失敗することがあり、その際取得できるラストエラー値はそれっぽいもの。
中身を見てみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595099/3e318ef2-b93a-1c2d-594e-88a1a7bfbe5a.png)
"Shell_TrayWnd"を`FindWindow`してて、それのラストエラー値がちゃんと入る。
そのエラー値を見てエラー処理をしようと思いました。が、モヤっとしています。

# 例２
https://docs.microsoft.com/en-us/windows/win32/api/sspi/nf-sspi-deletesecuritypackagea

MSDN「成功すると**SEC_E_OK**が返り、失敗するとエラーコードが帰ります。」
私「ふむ。全然成功せんが...チラ」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595099/8966af45-a277-ae16-e132-90aac1935097.png)

``` C:Cで書くと
SECURITY_STATUS SEC_ENTRY DeleteSecurityPackageA( LPSTR pszPackageName )
{
  return 0x80090302;
}
```

この関数のエラー処理はそっ閉じしました。
何年か経ったら実装されるのかな。

### 注
一応2012 Server無印以上のOSでそれぞれ確認しました。
7以前は見てません。
React setState()　データ同期＆非同期の書き方

## データ非同期更新

setState()のデータ更新は非同期です。

同じスコープ内にsetState()を複数回呼び出されたも、render()は一回しか呼ばされないです。

```jsx
//非同期更新
handleClick = () => {
        this.setState({
            count: this.state.count + 1
        })

        console.log('first', this.state.count)  //1

        this.setState({
            count: this.state.count + 1
        })

        console.log('second', this.state.count)  //1
        
    }
```

## データを同期更新させる方法

**`setState((state,props)⇒{})` を使用することです。**

　・state:　最新のstate

　・props:　最新のprops

```jsx
handleClick = () => {
        this.setState((state, props) => {
            return {
                count: state.count+1
            }
        })

        this.setState((state, props) => {
            console.log('second',this.state) //2  
            return {
                count: state.count+1
            }
        })

        console.log(this.state.count) //1 これを先にプリントする

    }
```

## setState()の第二引数

**`setState（updater[,callback]）`**

UIレンダリング後に、setStateの第二引数callbackを直ちに実行します。

```jsx
handleClick = () => {
        this.setState(
            //第一引数　updater
            (state, props) => {
            return {
                count: state.count+1
            }
            },
            
             //第二引数　callback
            () => {
            console.log(document.title)
        }
        )
    }
```

## コンポーネント更新の仕組み

setState() の役割は大きく二つに分けられます。

1.　stateの更新

2.　コンポーネントの更新

コンポーネントを更新する際に、子要素のコンポーネントしか更新しません。

兄弟や親のコンポーネントは更新しません。

![beforeUpdate.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/5a758773-bdfc-55ba-7409-60c5c989188f.jpeg)


![黄色部分は更新するところ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/323f125b-ce9a-f021-f49f-98d07f3682c6.jpeg)


黄色部分は更新するところ

## 注意すべきところ

レンダリング必要あるのデータだけ、stateに入れますが、

レンダリング必要ないデータはthisに入れます。

stateのデータが多ければ多いほど、renderの性能が低下してしまいます。
slackとgithubの連携を行った際に詰まったところ

## 背景
現在、個人アプリの改修を行っているのだが、slackとgithubの連携を行っていなかったので、CircleCIのテストが通ったかどうかがわかりづらかった。そこで、slackとgithubの連携を行ったのだが、途中詰まった箇所があったので、記録として残すことにした。

## 連携手順
以下記事を参考にした。
https://qiita.com/unsoluble_sugar/items/e42ac352400598a24915

下記のようにslack上で表示されたが、何故かissueを作っても、slackに通知が飛ばなかった。。

![slack_github_link.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702700/06ea90eb-d570-31fb-2801-65615f97d08e.png)

## 原因
下記画像の赤枠部分がunsuspendになっていると、slackに通知が飛ばない。
おそらく1年前のなにも分からない状態の時にいじってしまったため設定がおかしくなっていたと考えられる。。

![account_settings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702700/64260f68-46b8-ec92-b2c4-e4a2d80493f7.png)

## 最後に
基本的に「github slack 連携」で調べた記事通りにやればうまく行くと思いますが、自分のように設定を気づかないうちに変更してしまったことでうまくいかないこともあると思います。
もし手順通りにやってうまくいかない場合には、この記事を参考にしていただけますと幸いです。
Firestoreをmapフィールドに存在する値で検索する

こんにちわ、CROSSER開発者です:relaxed:
今回はFirestoreにあるmapフィールドにある値で検索する方法を共有したいと思います:fist:
どなたかの参考になれば嬉しいです:sparkles:


# Firestore Documentの例
例えばこんなドキュメントがあり、userAが2021/11/13よりも前のデータがあるmapのドキュメントのみを取得したい時にこの記事は参考になると思います。

user / user1 / like{'userA':2021/11/12, 'userB':2021/11/13,'userC':2022/1/1}
user / user2 / like{'userA':2022/1/2}


# やり方
```
admin.firestore().collection('user').where('like.userA', <=, 2021/11/12(Timestamp型)).get();
```
これでuser1のドキュメントが取得できます:grin:


# 補足
userAを可変にしたい時はこれでいけます:muscle:
```
admin.firestore().collection('user').where(`like.${userName}`, <=, 2021/11/12(Timestamp型)).get();
```
簡単に Visual Studio のコードスニペットを作れるWebサイトの紹介

# 概要
簡単に Visual Studio のコードスニペットを作れるWebサイトを作りました。

https://yamara-mh.github.io/CodeSnippetGenerator/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307985/d722d929-16ab-ffff-7bdb-852c0111328c.png)
[コードスニペットとは？という人はこちら](https://www.google.com/search?q=visual+studio+%E3%82%B3%E3%83%BC%E3%83%89%E3%82%B9%E3%83%8B%E3%83%9A%E3%83%83%E3%83%88)

# 使い方

\* が付く項目は必須です。
  
|項目|説明|
|-|-|
|Title*|コードスニペットの名前|
|Shortcut*|コードスニペットを呼び出す文字列|
|Author|作者の名前|
|Language*|言語|
|Imports|追加する名前空間。例「System」「UnityEngine」|
|Code|コード|
|Declarations|置換パラメータの詳細|

ダウンロードを押すと.snippet ファイルがダウンロードされます。
必須項目が未記入だったり、Declarationsの書き方が間違っていたりすると、正常に動かないスニペットファイルが作られるので注意してください。

## Declarations の書き方
Code に書いた置換パラメータ（例：\$value\$）の詳細情報を設定できます。

|項目|説明|
|-|-|
|Literal*|パラメータの名前|
|Default|パラメータの初期値|
|Tooltip|パラメータの説明|

次のパラメータを設定する時は2回改行してください。
MQTTの動作確認

# Pub/Subモデルのmqttプロトコルの動作確認

## イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296391/3a8e1bea-6c4a-5ca3-7411-636fb13ca83d.png)
※Publisherがbrokerにデータを登録し、接続されているSubscriberにデータを流す。

## ブローカのDockerfile
```Dockerfile:Dockerfile-broker
FROM ubuntu:20.04

RUN apt-get update
RUN apt-get install -y mosquitto

# ブローカの起動
CMD ["mosquitto", "-c", "/etc/mosquitto/mosquitto.conf"]
```

## 各クライアントのDockerfile
```Dockerfile:Dockerfile-client
FROM ubuntu:18.04

RUN apt-get update
RUN apt-get install -y mosquitto-clients
```

## docker-compose
```yml:docker-compose.yml
version: "3.7"

services:
  # ブローカ
  broker:
    build: 
      context: .
      dockerfile: Dockerfile-broker

  # publisher
  pub:
    build:
      context: .
      dockerfile: Dockerfile-client
    tty: true

  # subscriber1
  sub1:
    build:
      context: .
      dockerfile: Dockerfile-client
    tty: true

  # subscriber2
  sub2:
    build:
      context: .
      dockerfile: Dockerfile-client
    tty: true
```

## 起動
```shell:
docker-compose up
```

## 下記コマンドを実行してコンテナに入る
※上からpub、sub1、sub2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296391/eefafbc2-3d9b-d744-20fc-7a3f1d573baf.png)

## subscriber側で要求をする
```shell
mosquitto_sub -h broker -t sample-topics
```

## publisher側でデータ送信
```shell
mosquitto_pub -h broker -t sample-topics -m "send to subscriber"
```

## subscriber側でデータを受信できているのを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296391/15bff2d3-1d56-6dab-d663-64df4a65e704.png)

## github
https://github.com/kyosuke12345/mqtt-operation-check
UML2.0 ユースケース図

##初めに
ユースケース図のメモ

システム設計時にはよく利用します。
特に企画書や要件定義書で利用頻度が高い。

##内容
システムで何ができるかを「ユーザー目線で」表現する	
１．以下の４つで表現する
・アクター
　システムとやり取りする人やモノ、他のシステム
・ユースケース
　システムが提供する機能。
　1つの完結した機能を記述する。
　1つのユースケースで中断されないものを基準とする。	
・関連
　アクターとユースケースの関係を実線で表現する。
・システム境界
　対象システムの内部と外部の境界

・ユースケースの例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1308027/84075eda-9c30-88dc-603b-25fcded21f91.png)

２．汎化
あるユースケースの流れを別のユースケースが既定で利用している場合
ユースケース間に汎化の関係を引く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1308027/c1739c37-1181-5e9f-6b2b-22e47802e114.png)


３．包含
複数のユースケースに共通で利用している部分があるとき
該当箇所を新ユースケースで作成し包含の関係 <\<include>> で表現する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1308027/0c719bdb-1ccc-a0fd-cafb-bb9462dd85e7.png)


４．拡張
あるユースケースの一部分が利用されたり、利用されなかったり
オプショナルな部分がある場合は、該当部分を切り出して新ユースケースとする。
拡張の関係 <\<extend>>で表現する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1308027/dc94eb30-f37e-9761-7297-0e11a89e0c7a.png)

###余談
ただ、包含や拡張は利用するケースは少なそうである。
※利用時は注釈入れないと読み手がUMLの知識無いので余計に混乱する。。


###履歴
2022/1/8 新規作成
rails new 時に "ActiveSupport::EncryptedFile::InvalidKeyLengthError" エラーが出た時の対応


タイミングは rails new に限りませんが、rails でコマンドを叩いた時に以下のように**ActiveSupport::EncryptedFile::InvalidKeyLengthError** が出ることがあったので対処方法を書きます。

```
$ rails new xxxxx
/Users/yyyyyy/.rbenv/versions/3.0.3/lib/ruby/gems/3.0.0/gems/activesupport-7.0.1/lib/active_support/encrypted_file.rb:114:in `check_key_length': Encryption key must be exactly 32 characters. (ActiveSupport::EncryptedFile::InvalidKeyLengthError)
```

```
# 環境情報
$ ruby -v
ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [arm64-darwin21]
$ rails -v
Rails 7.0.1
```

# 原因

環境変数に設定していた RAILS_MASTER_KEY が適切な文字数 (=32) ではなかったことが原因でした。

```
$ export -p | grep RAILS_MASTER_KEY
declare -x RAILS_MASTER_KEY="hogehoge" 👈 ここ
```

# 背景

検証中、ローカル端末の ~/.bash_profile 内で設定している環境変数のうち
RAILS_MASTER_KEY に一時的に適当な値を設定していました。
(Rails 5.2 以上で実装された credentials.yml と master.key の仕組みで使う環境変数）

しかし RAILS_MASTER_KEY は 32 文字であるという制限事項が設けられているため、適当な値をセットしていると弾かれる仕組みのようです。

# 対策

検証で一時的に適当な値をセットする際は、RAILS_MASTER_KEY には 32 文字の文字列をセットしましょう。
Game of Pods攻略(Redis Islands編)

# Game of Pods攻略~Redis Islands~
redisHAクラスターの構築です



Game of Pods関連のソースコードを挙げてます
https://github.com/hayama17/Game-of-Pods

## 作りたい環境
* Redisクラスター(StatefulSet)
    * NodePort
        * clinet
            * port: 6379
            * targetport: 6379
        * gossip
            * port: 16379
            * targetPort: 16379
    * PV6個
        * /dataをPVCにマウント
    * /confをconfigmapにマウント

## PVの作成
6個作る。
一気に作りたかったけどやり方が分らない...

```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: redis(01~06) #合わせて作る
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /redis(01~06)　#合わせて作る
    type: DirectoryOrCreate
```

## StatefulSetの作成
要件通りに作成

```yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-cluster
spec:
  serviceName: redis-cluster
  replicas: 6
  selector:
    matchLabels:
      app: redis
  template:
    metadata: 
      labels: 
        app: redis
    spec:
      containers:
        - image: redis:5.0.1-alpine
          name: redis
          command: ["/conf/update-node.sh", "redis-server", "/conf/redis.conf"]
          env:
            - name: POD_IP
              valueFrom: 
                fieldRef:
                  fieldPath: status.podIP
          ports:
            - name: client
              containerPort: 6379
            - name: gossip
              containerPort: 16379
          volumeMounts:
            - name: conf
              mountPath: /conf
              readOnly: false
            - name: data
              mountPath: /data
              readOnly: false
      volumes:
        - name: conf
          configMap:
            name: redis-cluster-configmap
            defaultMode: 0755
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        resources:
          requests:
            storage: 1Gi
        accessModes:
          - ReadWriteOnce
```

## NodePortの作成

```yaml
apiVersion: v1
kind: Service
metadata:
  name: redis-cluster-service
spec:
  ports:
    - name: client
      port: 6379
      targetPort: 6379
    - name: gossip
      port: 16379
      targetPort: 16379

  selector:
    app: redis
```

## 各コンテンナをクラスターとして登録

```shell
$ kubectl exec -it redis-cluster-0 -- redis-cli --cluster create --cluster-replicas 1 $(kubectl get pods -l app=redis-cluster -o jsonpath='{range.items[*]}{.status.podIP}:6379 ')

[ERR] Wrong number of arguments for specified --cluster sub command
command terminated with exit code 1
```
あれ？　動かない...


### 原因
ラベルが違っていた

yaml app: redis

command app:redis-cluster

### 解決策
ラベルを変えるだけ

```shell
$ kubectl exec -it redis-cluster-0 -- redis-cli --cluster create --cluster-replicas 1 $(kubectl get pods -l app=redis -o jsonpath='{range.items[*]}{.status.podIP}:6379 ')
>>> Performing hash slots allocation on 6 nodes...

.
.
.
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
.
.
.
[OK] All 16384 slots covered.
```
できた！

# GitHub
https://github.com/hayama17/Game-of-Pods/tree/main/Redis%20Islands
[golang error] go: gopkg.in/yaml.v2@v2.2.2: unknown revision v2.2.2を解決した話

### 状況
Dockerでgolangとmysqlの環境構築


### エラー内容
```
go: gopkg.in/yaml.v2@v2.2.2: unknown revision v2.2.2
go: error loading module requirements
```

### さきに結論  
- version (1.17)にupdateしましょう
- [上記をすでに試した場合](#自分の場合)


### より詳しく

結論の繰り返しになりますが
versionを更新することで解決できます
*参考にしたissueは[こちら](https://github.com/go-yaml/yaml/issues/791)*



解決できてない方は自分と同じ場合かもしれないので
先にお進みください

___


そもそも**versionが本当に更新されているか**
コンテナ内で確認してみてください


- **コンテナが動いてる場合**  
ログインしてgo versionで調べられます

- **コンテナがbuild時に失敗し強制終了している場合**  
Dockerflieまたはcomposeのcmd で go versionを調べてみてください

例: Dokcerfileの場合

```
CMD ["go","version"]
```

  


### 解決

自分の場合は**version:1.11.4**になってました
GitHub リポジトリを作成してファイルをコミットする(HTTP)

#とりあえず公式を見よう
https://docs.github.com/en/repositories/working-with-files/managing-files/adding-a-file-to-a-repository

git push origin mainのあとに、ユーザネームとパスワードが聞かれる。
パスワードはアカウントのパスワードを打つとエラーになる。もう対応してないらしい。
パスワードが聞かれたらアクセストークンを入力する。
アクセストークンの作成は以下。

https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token

でも自分は一度作ったので、アクセストークンはメモに残してる。（完全自分用・・・）
HTTPじゃなくてSSHで接続する方法のほうがいいらしいのでまた調べる。
Chrome拡張機能でTweet下書き機能を作ってみた

# はじめに
***皆さんは最近仕事以外で勉強していますか？***

以前の自分は休日は勉強するとしても数時間程度。平日はほとんど勉強していませんでした。
しかし職場の面談で以下のようなお言葉をいただきました。

***「今後どんな人生設計かにもよるが、結婚して子供ができたら今まで以上に学習時間を確保することは難しい。時間のあるうちに学習をしておくことが大切」***

ごもっともだなと思いました。また、自分の場合は、色々ありエンジニアになるのに遠回りをしているためなおさらです。

そこで、この面談の日から毎日少しでも学習をすることを決め今日まで続けています。

今回は、学習に取り組む中で自分用のChrome拡張機能を作ってみたのでここに記録します。

# 開発したもの
今回開発したものは、Tweetの下書きができる拡張機能です。

![スクリーンショット 2022-01-08 13.38.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/243f7482-a6eb-493a-ad6d-7040ec9652f2.png)

開発するにあたり、大事なことの1つとして作り切ることだと思っています。
途中で飽きてしまって完成できなかったものもいくつかあるので、今回は最低限の機能のみとしました。

実装した機能は以下の通りです。

- 文字数のカウント処理（全角、半角、URL形式）
- ツイートのテンプレート保存機能
- 記入内容の途中保存機能
- 記入内容の復元機能
- ストップウォッチ（拡張機能を閉じているときもカウント）


## 開発背景
毎日勉強をするにしても自分一人だと継続が難しいと感じたため、勉強熱心な友人を数人フォローしたツイッターのアカウントを作成し、そこで毎日の学習したことを呟くようにしました。

友人が勉強を頑張っているところをみると、自分も頑張ろうと思い今のところ毎日勉強は続いています。

そんな中、毎日勉強したことをTweetする際に、どのサイトを読んだか、参考にしたかなど忘れてしまうことが多々ありました。
また、特に勉強時間を計測したりもしていなかったのでどれくらい勉強したかも記録できていませんでした。

そこで、参考サイトなどをすぐに記録でき学習時間も計測できるような自分用のChrome拡張機能があったらいいなと思い開発しました。



## 仕様を決める
とりあえず、先ほど記述したように以下の機能を実装することを決めました。

- 文字数のカウント処理（全角、半角、URL形式）
- ツイートのテンプレート保存機能
- 記入内容の途中保存機能
- 記入内容の復元機能
- ストップウォッチ（拡張機能を閉じているときもカウント）

Twitterの現状の仕様としては、以下のような仕様らしいです

- 半角文字換算で280文字まで
- 全角文字は2文字換算
- URL形式は23文字の固定

そのため、上記ツイッターの仕様を考慮して実装しました。
テンプレート等の保存場所に関してはStorage APIでlocalに保存。
ストップウォッチに関しては、backgroundで処理を行うことで拡張機能を閉じてもカウントを継続するようにします。

### 参考
https://downtownreport.net/app/twitter-url-text-count/



# Chrome拡張機能について知る
とはいえ、Chrome拡張機能を作ったこともなく、どのようにやるのか全くわからないのでざっくりとした概念に関しては以下の記事を参考にしました。
今回は特定のWebページを対象としないため「Brower Action」でボタンを押したらツイートの下書き用ポップアップが表示されるようにします。

https://qiita.com/k7a/items/26d7a22233ecdf48fed8


# 機能紹介
![スクリーンショット 2022-01-08 13.49.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/a70d3610-9467-9d0b-50e9-e8e852fb6961.png)

### ストップウォッチ
上部にある数値がストップウォッチのカウント部分。学習時間を記録するために使用。
拡張機能を閉じてもカウントするようbackground側で動かしている（ただ止め忘れると、ずっと動いてしまうため現状は5時間で自動的に止まるようにしている）

### 文字数のカウント
文字数は、半角を1文字、全角を2文字としURL形式のものは一律で23文字とするようになっている。
また、規定の280文字を超えるとカウント部分が赤色になるようにしている。

### 各種ボタン
①ストップウォッチのスタートボタン
②ストップウォッチのストップボタン
③ストップウォッチのリセットボタン
④テンプレートの貼り付けボタン
⑤テンプレートの保存ボタン
⑥入力欄の復元ボタン


テンプレートに関しては1つのみ保存できるようにしている。
基本的に毎日ツイートする型が決まっているのでそれを保存している。

復元機能に関しては、テキストエリアを離れた際にテキストエリアの内容をlocalstorageに保存するようにしている。当初はこの復元ボタンで保存した内容を反映させていたが、最終的にはchrome拡張起動時に自動で復元するようにした。
※復元機能のボタン画像が機能とあっていない気もしますが直すのが面倒なのでこのままで

### デザイン
あまり力を入れていないので、かなりチープですがiPhoneをイメージして作ってみました。


# まとめ
今回は、勉強の一環でChrome拡張機能を作ってみました。
意外と楽しかったので、今度は他の人にも使ってもらえるような拡張機能を作ってみたいと思います。

また、学習は引き続き継続していきたいと思います。


# 参考

https://developer.chrome.com/docs/extensions/

https://developer.chrome.com/docs/apps/app_storage/

https://qiita.com/k7a/items/26d7a22233ecdf48fed8

https://future-architect.github.io/articles/20200625/

https://www.stay-home-build-app.com/entry/2021/02/07/085932
React lifecycle ライフサイクル

# React ライフサイクルとは

reactのライフサイクルはコンポーネントの誕生から消滅までに発生する一連のイベントとのことです。

reactのライフサイクルは三つの時期に分けられます。

　・Mounting—>コンポーネントの誕生

　・Update—>コンポーネントの更新

　・Unmount—>コンポーネントの停止

The diagram below is from the [official React documentation](http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/)

![reactLifeCycle1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/d7762996-0bf2-4f49-5987-dea8fcc087e1.png)

![reactLifeCycle2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/e36e07d7-52e2-2178-366d-d66d2ddf7de9.png)


## マウント時

マウント時の実行順番

| Hook  | トリガー | 役割 |
| --- | --- | --- |
| constructor | コンポーネント作成時 | 1. state初期化<br>2.イベントハンドラをインスタンスにバインドする |
| render | レンダー時 | UIレンダリング<br>(注1：setState()を使ってはいけない。<br>renderの用途はレンダリングだけのため。) |
| componentDidMount | コンポーネントがマウント後 | 1.ネットワークリクエストを送信<br>2.DOMに対する操作 |

※注1: render内に**`setState()`** を使用すると、無限ループになってしまう。

## 更新時

| Hook  | トリガー | 役割 |
| --- | --- | --- |
| render | レンダー時 | UIレンダリング<br>(マウント時のrender) |
| componentDidUpdate | 1.　setState()<br>2.   forceUpdate()<br>3.   New Props<br>(注2：上記のいずれもトリガーになる) | 1.ネットワークリクエストを送信<br>2.DOMに対する操作<br>(注3：setState()の設定はif文に入れる必要有) |

※注3:無限ループになるため。

```jsx
class App extends React.Component {
    constructor(props) {
        super(props)

        this.state {
            count: 0
        }
    }

    handleClick = () => {
        this.setState({
            count: this.state.count + 1
        })
    }
    render() {
        return (
            <div>
                <Counter count={this.state.count} />
                <button onClick={this.handleClick}> Click </button>
            </div>
        )
    }
}

class Counter extends React.Component {
    render() {
        return <h1 id="content"> Click count: {this.props.count}</h1>
    }

    //下記は悪い例：無限ループになる

    /*
    componentDidUpdate() {
        this.setState({})
    }
    */

    //正しい例：if文に入れる
    componentDidUpdate(prevProps) {

        if (prevProps.count !== this.props.count) {
            this.setState({})
        }
        
    }

}
```

## アンマウント時

| Hook  | トリガー | 役割 |
| --- | --- | --- |
| componentWillUnMount | コンポーネントがアンマウントされて破棄される直前 | コンポーネントのアンマウント |

componentDidMountで作成したコンポーネントを廃棄しようと思う時、componentWillUnmoutを呼び出す。

```jsx
class Counter extends React.Component {
    //set Timer
    componentDidMount() {
        this.timerId = setInterval(() => {
            console.log('timer')
        }, 500)
    }

    render() {
        return <h1 id="content"> Click count: {this.props.count}</h1>
    }

    //Timer Unmount
    componentWillUnmount() {
        clearInterval(this.timerId)
    }

}
```
Stack Viewを使ってボタンを綺麗に配置したり追加するのを学んでみた

## StoryboardでStack Viewを使う
**参考にした動画**
https://www.youtube.com/watch?v=nfCNpL9hh3E

動画の半分の時間は、よくあるAutolayoutで制約をつける方法を紹介して、これだとボタンを追加したり、位置を変えたりするのが手間なのを紹介している。

ボタンを３つ新たに作り、全部選択した状態で、x-codeを開いているときに画面上のメニューから、Edigorを選び、Embed in -> Stack Viewを選択。
そうすると、ボタンが綺麗に配置される。
StackView自体にはAutolayoutの制約は必要!

## まずButtonを３つ配置する

![スクリーンショット 2022-01-08 13.25.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303722/c38ac333-f718-6fb5-64d8-70ee354a453d.png)

## 画面上のEdigorを選び、Embed in -> Stack Viewを選択。

**スクショとる前にStack View適用してましたすみません**

![スクリーンショット 2022-01-08 13.27.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303722/8b4f8255-8a66-f4ef-f24a-d6fcd584096a.png)

## ボタンが綺麗に配置される

![スクリーンショット 2022-01-08 13.25.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303722/f5f1dedb-f929-b235-7927-9b4e7fa8793c.png)

## Stack Viewを選択した状態で制約をつける(ここから学習が始まる)
**すみませんボタンの色変えてませんでした**

![スクリーンショット 2022-01-08 13.31.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303722/53ead3e7-5751-5105-4be5-9cc003d556b2.png)

## 画面右のユーティリティー・エリアから、インスペクターを選択し設定をする

DistributionからFill Equallyを選択するとボタンの幅を自動で設定してくれる。
Spacingを16にすると、自動でボタンの感覚を変更できる。

![スクリーンショット 2022-01-08 13.36.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303722/bc471bed-ed6f-222a-51b0-8c2de390e0ea.png)

## ボタンを追加する
エディターエリア左のView Controller Sceneの中にあるStack Viewの中にButtonをドラックアンド・ドロップする。
すると見た目が綺麗な状態で配置される。（ボタンの種類によってStackのSpacingの設定が必要です。messageボタンのような小さいボタンだと68位感覚が開きすぎる!）

![スクリーンショット 2022-01-08 13.47.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303722/a6fc885c-183f-7643-07d9-ad83a9bece06.png)
![スクリーンショット 2022-01-08 13.47.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303722/940c8ea1-7b97-46c7-2257-ea59e42c9a5a.png)
![スクリーンショット 2022-01-08 13.48.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303722/f2a66891-1d48-ecac-aaa8-55ec6ba9497a.png)

## 最後に
このLessonには続きがありご興味がある方は参考までにご覧ください。
YouTubeのチャンネルのURL

https://www.youtube.com/c/CODEJO/videos
MenubarXがとてもいい

## 概要

macのメニューバーにwebサイトを常駐させておけるアプリ

![スクリーンショット 2022-01-08 13.18.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189459/8793857d-f2f3-54ed-5e0f-00d2251a3a6b.png)


kibelaを日報代わりに使っているのですが、小さな画面でサクッと開いてサクッと書けるので便利。タブを開き過ぎてどこいったっけなーってことも無いし、よく使うサイトを登録しておけばそもそもタブを開きすぎることもなくなるかも…？
![スクリーンショット 2022-01-08 13.19.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189459/2f2485d1-278d-2cc0-a263-91f41a1a90f1.png)
VibratorManager を利用する

# Context.VIBRATOR が Deprecated に
API Level 31 (Android 12) より `getSystemService(Context.VIBRATOR)` が **Deprecated** になりました。
以降は同じく API Level 31 で追加された `getSystemService(Context.VIBRATOR_MANAGER_SERVICE)` の使用が推奨されます。

# Vibrator Manager の使い方

`AndroidManifest.xml` に次のパーミッションを追加します。

```xml:AndroidManifest.xml
<uses-permission android:name="android.permission.VIBRATE"/>
```

つづいて `MainActivity.kt` に処理を記述します。
サンプルではこまかな点まで考慮しておりませんのでご了承ください。

```kotlin:MainActivity.kt
class MainActivity : AppCompatActivity() {
    @RequiresApi(Build.VERSION_CODES.S)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val vibratorManager = getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
        val vibrationEffect = VibrationEffect.createWaveform(
            longArrayOf(500L, 500L),
            intArrayOf(VibrationEffect.DEFAULT_AMPLITUDE, 0),
            3
        )
        val combinedVibration = CombinedVibration.createParallel(vibrationEffect)

        findViewById<Button>(R.id.Button).setOnClickListener { vibratorManager.vibrate(combinedVibration) }
    }
}
```

従来の `Vibrator` を使用する方法との違いは、`CombinedVibration` が加えられる点です。
[公式リファレンス](https://developer.android.com/reference/kotlin/android/os/CombinedVibration) によると `CombinedVibration` は API Level 31 で追加された振動機能全般を管理するためのクラスとなっています。
従来の振動機能に加え、触覚フィードバックも一元化して扱いやすくするのが狙いなようです。
その点を除くと、 `VibrationEffect` オブジェクトを生成し `VibratorManager.vibrate()` に渡すという基本サイクルは変わりません。

実行中のvibratorをすべて停止するには、 `VibratorManager.cancel()` を使用します。
OSSのTypeScriptのソースでよくみかけるDictについて

# Dict型
```typescript
export type Dict<T = any> = Record<string, T>;
```
OSSのソースなどを読んでるとこんな感じでDict型を指定してる事があります

# Dict型の目的

```typescript
let obj={}
obj.name="Alex" //Property 'name' does not exist on type '{}'
```
これはjavascriptだとエラー起きないのですが、typescriptだとエラーが起きるので、



```typescript
let obj:{[key:string]:string}={}
obj.name="Alex"
```


にする必要があります。ここでRecordを使うとより簡潔に


```typescript
let obj:Record<string,string>={}
obj.name="Alex"
```
とする事ができます。それを更に簡潔にしたのがDict型という感じですね。

https://www.carlrippon.com/typescript-dictionary/
SharePointのリストのViewIDを取得する

「HTTP要求を送信する」アクションを利用して、
グループ化したビューの見出し部にあたるグループ名と件数のカウント結果を取得しようとしています。

参考にしたのはこのページです。

https://www.expiscornovus.com/2021/10/07/how-to-get-a-group-by-subtotal/


ビューIDが唐突に出てくるので、対象となるビューの編集ページを見ることにします。
ビューの名称（.aspx）指定やパブリックビューにするか
どの項目を表示対象にするか、といった設定は見受けられますがビューID自体の記載はありません。

どこにあるかというと、ビューの編集ページのURLの中に含まれています。リスト自体のID取得方法とほぼ同じでした。

https://tech.la-fra.com/2020/05/26/post-759/


?ViewID=%7B○○○%

の文字列がURLの途中に含まれているので、○○○にあたる部分が
ビューのIDとなります。
シェルスクリプトで対象の変数が数値かどうか判断する

シェルスクリプトで対象の変数が数値かどうか判断するための備忘メモです

シェルスクリプトでは型という概念は存在しなさそうなので、代わりに`expr`を使って判断する
（例によってもっといい方法があるような気がする、、良い案あればコメント下さい！）

```bash:test.sh
#!/usr/bin/bash                                                                                                                                                                                             

function check_if_int(){

    input=${1}

    # check if input is int                                                                                                                                                                                 
    # 0: 式が正しく評価され、評価値が0かnull以外の場合                                                                                                                                                      
    # 1: 式が正しく評価され、評価値が0かnullのとき                                                                                                                                                          
    # 2: 式が不当なとき                                                                                                                                                                                     
    # 3: (GNU版のみ)その他エラーが起こったとき                                                                                                                                                              

    expr "$input" + 0 >&/dev/null
    ret=$?
    if [ $ret -lt 2 ];then
        echo "$input is an int number: ${ret}"
    else
        echo "$input is not an int number: ${ret}"
        return 1
    fi
    return 0
}

check_if_int 1
check_if_int 0
check_if_int 1000000000000000
check_if_int -1
check_if_int 1.1
check_if_int hoge
```

実行

```bash
$ bash test.sh
1 is an int number: 0
0 is an int number: 1
1000000000000000 is an int number: 0
-1 is an int number: 0
1.1 is not an int number: 2
hoge is not an int number: 2
```

# 参考
[シェルスクリプトで数字かどうか判断する方法(exprだけじゃない)](https://rcmdnk.com/blog/2018/09/05/computer-bash-zsh)
micro:bit用GROVEシールドで 3つのモジュールをいっぺんに使う

この記事では、以下のツイートの動画で動かしているものに関して、構成やプログラムの内容を紹介しています。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">micro:bit と Groveモジュール 3つの組み合わせ。<br><br> <a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://t.co/YGEsVF4YbU">pic.twitter.com/YGEsVF4YbU</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1479652662958522370?ref_src=twsrc%5Etfw">January 8, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 構成
デバイスの構成的には、以下のものを使っています。
リンクは、LEDテープ以外は、全てスイッチサイエンスさんのオンラインサイトを掲載しています。

- [micro:bit（マイクロビット） - スイッチサイエンス](https://www.switch-science.com/catalog/6600/)
- [micro:bit用GROVEシールド v2.0 - スイッチサイエンス](https://www.switch-science.com/catalog/5434/)
- [GROVE - 7セグメント4桁ディスプレイ - スイッチサイエンス](https://www.switch-science.com/catalog/1175/)
- [Grove RGB LED テープ 防水 (WS2813 - 30 LED/m - 1m) - Seeed Studio](https://jp.seeedstudio.com/Grove-WS2813-RGB-LED-Strip-Waterproof-30-LED-m-1m-p-85.html)
- [GROVE - 超音波距離センサモジュール - スイッチサイエンス](https://www.switch-science.com/catalog/1383/)

micro:bit用GROVEシールドと各モジュールとの接続については、以下の対応関係になっています。

- P0/P14 ⇒ 7セグメント4桁ディスプレイ
- P1/P15 ⇒ RGB LED テープ
- P2/P16 ⇒ 超音波距離センサ

![Groveモジュールを接続する部分](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/3775f843-45ec-9fc1-533a-3827017ee112.jpeg)

## 動作・プログラム
### 動作概要
シールドを介して、micro:bit に 3つのモジュールがつながっています。

そして 3つあるモジュールのうち、「超音波距離センサ」が入力になり、「7セグメント4桁ディスプレイ」と「RGB LED テープ」が出力となる構成です。
もう少し補足すると、超音波距離センサで距離の値を取得し、距離の値をディスプレイにそのまま表示させています。また、距離の値が特定の決まった範囲に入っている場合、それに応じて特定の個数の LEDが光る（※個数のパターンは3種類）という動きをさせています。

### プログラム
プログラムは、MakeCode for micro:bit を使って作った、以下のブロックベースのものです。

![Notification_Center.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/d95ed86f-2a20-fa41-679d-b735331c9594.jpeg)

「最初だけ」の中は、初期化・セットアップの処理になっています。
2つのモジュールのセットアップ用の処理では、接続している端子や光らせる LED の個数を指定しています。

「ずっと」の中は、超音波距離センサによる距離の取得（単位はセンチメートル）と、それに応じた出力のための処理です。
なお、シリアル通信はデバッグ用に使っていて、冒頭のツイートの動画の見た目上には表れていません。

全体のブロックがあまり多くならないように作っています。
心霊写真もインスタ映え🧁　暗い画像を明るくする機械学習がすごい

#明度の低い画像を明るくしてくれる機械学習モデルを使う方法です
GLADNetというモデルを使って、暗い画像を明るくします。
Pythonでかんたんに実行できます。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/dacac71d-8d85-e994-ab41-4e53715830d4.jpeg width=500>
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/99f91c8c-462d-51ae-34c6-574b2400a738.jpeg width=500>
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/435b701e-4623-5024-c4a0-ed99f892762d.jpeg width=500>
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/712eedea-e091-8fcd-0b4d-ae160dcf61b7.jpeg width=500>




#暗い画像から情報を取り出したい

暗くて上手く取れなかった画像や、夜の監視カメラや車載カメラの画像を明るくできれば、
役に立つ情報が取り出せる場合があります。

しかし、単にフィルターで明度を調整しても、情報は増えません。

#GLADNetで綺麗に明るくなる
GLADNetに画像を入れるだけで、明るい画像が返ってきます。
これが、本当に明るくしたみたいに見えます。

#使用方法

GLADNetのリポジトリをクローンし、以下のコマンドで実行できます。

```python
python main.py --use_gpu=1 --gpu_idx=0 --gpu_mem=0.5 --phase=test --test_dir=path/to/input_images --save_dir=path/to/output
```

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/66126f06-3b23-02cd-58da-1f42157b23db.jpeg width=500>
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/4bea54b4-72d0-f6e7-d3ce-7bb8d3728f42.jpeg width=500>




#さまざまな用途に

こういった手法を使うことで、必要な情報が取り逃がしなく取得でき、
心霊写真も怖くなくなりま

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/5ce4ac17-1c56-d077-a4ee-b528d5b13c1e.jpeg width=500>
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/ba1b8a54-4ce8-f13d-8a2b-9fd1104094a8.jpeg width=500>
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/d902b2c4-e58b-943b-6fa5-316b95658aba.jpeg width=500>
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/f0c395e7-8996-f91f-c831-dba2a438dead.jpeg width=500>

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
macOS Monterey (バージョン12.1) Python3.8.0がinstallできなかったときの対処法

macOS バージョン12にて、下記記事を参考にPython3.8.0をinstallしようとした際にエラーが発生

https://www.comp.tmu.ac.jp/s-yokoyama/misc/pythonmac.html

エラー内容


```ターミナル：ターミナル
% pyenv install 3.8.0

//省略
 error: implicit declaration of function 'sendfile' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
        ret = sendfile(in, out, offset, &sbytes, &sf, flags);
```

試したこと
https://github.com/pyenv/pyenv/issues/1643

上記のgithub issuesを読むと、homebrewからこのエラーのパッチが出てるとのことなので、参考にターミナルで以下のコマンドを入力

pyenv 3.8.0のインストール

```ターミナル：ターミナル
% CFLAGS="-I$(brew --prefix openssl)/include -I$(brew --prefix bzip2)/include -I$(brew --prefix readline)/include -I$(xcrun --show-sdk-path)/usr/include" LDFLAGS="-L$(brew --prefix openssl)/lib -L$(brew --prefix readline)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib" \
pyenv install --patch 3.8.0 < <(curl -sSL https://github.com/python/cpython/commit/8ea6353.patch\?full_index\=1)

```

pyenv 3.8.3のインストール

```ターミナル：ターミナル
% CFLAGS="-I$(brew --prefix openssl)/include -I$(brew --prefix bzip2)/include -I$(brew --prefix readline)/include -I$(xcrun --show-sdk-path)/usr/include" LDFLAGS="-L$(brew --prefix openssl)/lib -L$(brew --prefix readline)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib" \
pyenv install --patch 3.8.3 < <(curl -sSL https://github.com/python/cpython/commit/8ea6353.patch\?full_index\=1)

```

pyenv version コマンドでpyenvの3.8.0と3.8.3がインストールできているのを確認

pyenv global 3.8.0でバージョン切り替えを行い、ターミナルを再起動

python -Vでバージョン確認

```ターミナル：ターミナル
% python -V
Python 3.8.0
```

無事Python3.8.0のinstall成功
[ExcelVBA]64ビット版AcrobatReaderでの印刷処理

# はじめに
先日、AcrobatReaderの64ビット版へのアップデートがありましたが、これによって、印刷処理を行うエクセルマクロが動作しなくなってしまいました。

# 32ビット版AcrobatReaderでの印刷処理
`参照設定`に`Windows Script Host Object Model`を追加して、以下のコマンドで印刷することができました。

```
Dim wshShellObj As IWshRuntimeLibrary.WshShell
strShellCommand = "AcroRd32.exe /t " & 印刷ファイルのパス & " " & プリンタの名前
wshShellObj.Run (strShellCommand)
```

# 64ビット版AcrobatReaderでの印刷処理
実行ファイル名前が変わってしまっているので、`AcroRd32.exe`を`Acrobat.exe`に変更する必要があります。

```
Dim wshShellObj As IWshRuntimeLibrary.WshShell
strShellCommand = "Acrobat.exe /t " & 印刷ファイルのパス & " " & プリンタの名前
wshShellObj.Run (strShellCommand)
```

# 参照
- [VBAでPDFを印刷する方法・管理しやすいツールにする方法を解説！](https://www.sejuku.net/blog/99169)
AWSのクラウドコンピューティングについて

<h2>最初に</h2>
<p>
この記事はAWS認定試験を目指す学生のノートの１ページです。
間違いや言葉の言い回しが多少異なることがあります。ご了承ください
</p>
<h2>AWSとは</h2>
<p>
AWS(Amazon Web Services)とはAmazon社が提供している<br>
従量課金制（使用した分しか取らない）Webサービスです。<br>
またAWSでは様々なビジネスの場面で使えるようにたくさんの製品が用意されているのも一つの特徴です。
</p>
<h2>クラウドコンピューティングの利点</h2>
<p>
クラウドコンピューティングの利点は大きく分けて６つあります<br>
<h3>・先行支出を変動支出に切り替えれる</h3>
使用するかどうかわからない膨大な量ではなく使用した分だけ料金を払うので結果的に費用が安くなる<br>
<h3>・データセンターの維持管理費用が不要</h3>
データセンターのコンピューティングで必要なインフラストラクチャとサーバー管理に割く多くの時間と費用をカットできる<br>
<h3>・キャパの予測がいらない</h3>
クラウドコンピューティングではアプリケーションのデプロイ前に、インフラストラクチャに必要なキャパを予測する必要がなく、必要になった時だけ足せばいい<br>
<h3>・圧倒的なスケールメリット</h3>
クラウドコンピューティングを使用すると自社で環境構築するよりもコストを低く抑えることができる<br>
<h3>・スピードと俊敏性の向上</h3>
クラウドコンピューティングの柔軟性で、アプリケーション開発とデプロイが簡単になります<br>
<h3>・数分でグローバルに展開</h3>
AWSクラウドのグローバルなサービス規模により、世界中のお客様にアプリケーションを低レイテンシー（遅延時間）で提供します<br>
</p>
<h2>AWSのクラウドコンピューティング</h2>
<h3>クラウドコンピューティングとは</h3>
<p>
ITリソースをインターネット経由でオンデマンド配信（必要な時に必要な分だけ渡す）
ことです。<br>
AWSでは使用した分だけ料金を支払うので通常時は必要最低限、必要になったらメモリを増やして使わなくなったらまたもとにすぐに戻せます
</p>
<h2>クラウドコンピューティングのデプロイモデル</h2>
<h3>デプロイモデルとは何か？</h3>
<p>
簡潔に書くとクラウドサービスの基盤のことです。基本的にはシステムごとに統一されます
</p>
<h2>クラウドベースデプロイ</h2>
<p>
＜特徴＞<br>
・アプリケーションのすべてをクラウド上で実行する<br>
・既存のアプリケーションをクラウドに移行する<br>
・新しいアプリケーションをクラウド上で計画及び構築する<br>

クラウドベースデプロイは上記に記した通り既存のアプリケーションを<br>
クラウドに移行することや、新しいアプリケーションをクラウド上で計画、構築することができます。
</p>
<h2>オンプレミスデプロイ</h2>
<p>
＜特徴＞<br>
・仮想化ツールとリソース管理ツールを使用して、リソースをデプロイする<br>
・アプリケーション管理と仮想化技術を使用して、リソースの使用率を向上させる<br>

オンプレミスデプロイは、プライベートクラウドとも呼ばれ、このモデルでは仮想化ツールとリソース管理ツールを使用して、リソースをオンプレミスにデプロイします。<br>
※オンプレミスとはサーバーやソフトウェアなどの情報システムを、使用者が管理している施設の機内や機器に設置して運用していくことです
</p>
<h2>クラウドベースデプロイ</h2>
<p>
＜特徴＞<br>
・クラウドベースのリソースをオンプレミスのインフラストラクチャに接続する<br>
・クラウドベースのリソースを従来のITアプリケーションと統合する<br>

ハイブリッドデプロイでは、クラウドベースのリソースをオンプレミスのインフラストラクチャに接続します。ハイブリッドデプロイは様々な状況で使用されます。<br>
例えば、オンプレミスで最適化して管理しているレガシーアプリケーションを規定などでオンプレミスで保持を求められたときなどに使用します。
※レガシーアプリケーションとは現在のOSではサポートされないアプリケーションを指します。
</p>
<h2>まとめ</h2>
<p>
初投稿で書き方や口調がぐちゃぐちゃになってしまいました。
AWS認定試験に向けた最初のページなのにとても長々と書いてしまいました。
何か間違いや不明瞭な点を発見しましたらコメントにて指摘していただけるとありがたいです。
</p>
時間出力コマンド


#使い方

コマンドプロンプトで時刻を表示させるコマンドになります。
スクリーンショットなどの時刻を記録するためにに便利なコマンドです。

```
echo %date% %time%
```

yyyymmddの形式で出力されます。


随時追記していく予定です。
Next.jsで画像を配置する方法

#Next.jsで画像を配置する方法
最近学んだことをoutputするために書きました。
##やり方
①まずpublicフォルダにstatic fileを作り、その中に画像をぶち込みます。
②その次に画像を配置したいフォルダー内に行き、Imageタグで画像を表示していきます。この時、publicは"/"で表示できるので気をつけましょう。

```html
<Image 
src="/static/logo.png"
alt="logo"
width="150px"
height="50px"
/>
```

以上で表示できます！以上グッピーでした！

##参考にした記事
https://qiita.com/KMD/items/f201b846b2485841c0ff
Eclipse上でGithubに新規リポジトリをpushする

###はじめに
Eclipseでローカルリポジトリの作成からリモートへのpushまでの説明。
ここではGitについての説明はしません。
Gitってなんぞや？という方は[こちら](https://qiita.com/nnahito/items/565f8755e70c51532459#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB)を参照してください。
### 環境
```
Ecllipse 2021-12 (4.22.0)
Windows 11
Github 2022/1時点
```
### 前提条件
- Githubのログイン
- 新規リポジトリの作成
- Eclipseでプロジェクトを作成（プロジェクト名は任意）

### ローカル環境にリポジトリ（ローカルリポジトリ）を作る
Eclipsを開き、pushしたいプロジェクト名を右クリック。チーム＞プロジェクトの共有＞Gitを選択し次へをクリック。
![スクリーンショット (46).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169545/6bc8bb80-52c3-f0a0-5228-60b4f48b5d0e.png)
プロジェクトの親フォルダー内のリポジトリを使用または作成とのチャックボックスがあると思うのでチェックを入れる。すると以下のような画面に変わるはず。
![スクリーンショット (47).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169545/672d11fc-1654-ab02-93c1-dd67aa38b3fb.png)
リポジトリを作成をクリック。この時にチェックボックスにチェックは不要。
![スクリーンショット (48).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169545/37672827-8042-a43e-f8e6-089864a04097.png)
チェックを入れて、完了をクリック。
![スクリーンショット (49).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169545/17e9d35c-3837-1fdd-93a4-18225bf8b231.png)

### git addからcommitまで
プロジェクト名を右クリックし、チーム＞コミットを選択。
コミットメッセージを入力し、ステージされていない変更のファイルをステージされた変更に追加する。
コミットをクリック。これでコミット完了。
![スクリーンショット (51).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169545/f7060a7e-6207-3fe3-065b-8799dfaec0a1.png)
### リモートリポジトリにpush
プロジェクト名を右クリック。チーム＞リモート＞プッシュをクリック。
作成したリポジトリのURLをコピーし（画像１を参照）、画像２のURIに貼り付ける。
プロトコルをhttps（任意）を選択。ユーザー名、パスワードはGitHubで登録したものを入力。セキュア・ストアに保管をチェック。
プッシュをして未認証とのエラーが出てきた場合は[こちら](https://qiita.com/Dexctersu/items/f0dadd3024910dad0085)を参照

![スクリーンショット (36).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169545/612f98fb-ae5e-dea8-ef2f-112511d7c75c.png)
＊画像１
![スクリーンショット (55).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169545/6c6fd26d-b3e7-558a-ac20-57342518eb92.png)
＊画像２


### ブランチの選択
ソースの参照でブランチを選択。
仕様の追加をクリックし、完了！
![スクリーンショット (53).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169545/74a3648f-e0b7-a600-62cc-72ef125581dd.png)
以下のようなプッシュ結果が出てくるはず。これでpush成功すると思うので、GitHubを確認してみて下さい。
![スクリーンショット (54).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169545/1a5432fd-afeb-8c1f-65eb-454e7758ca5f.png)




### 参考文献
- [Eclipse 上から新規プロジェクトを Github に Push する方法](https://qiita.com/cotrpepe/items/7cafaacb538425a78f1f)
ドローン飛行計画時に道路使用許可を警察署で取得しなければならなない条件とは

人口密集地区におけるドローンの飛行にあたり、道路の上空を横断することは極力さけて計画を行うとされていることは理解できよう。
しかしながら道路を横断するということは、どうしても避けられないということは想定される。
実際、道路の警備を行う警察署がどのような考えをしているのかまとめておきたい。

#道路交通法
道路交通法は、車両や人が通行する道路において、安心・安全を保つことつまり、「道路における危険を防止し、その他交通の安全と円滑を図り、及び道路の交通に起因する障害の防止に資すること」が目的としている。道路上において危険になる行為は制限または、改修工事などのように一定条件・目的により使用や規制を行うことになる。

#ドローン印象と警察
　過去にドローンが一般化する前に祭りなどでドローンが一般人の上空を飛行したり、重要施設などに接近したりと、割とお騒がせな印象をもっている方も多いと思われますが、警察に関してもその印象は同様です。ただ、昨今の利活用していく流れを受けて、偵察用のドローンを導入する警察も増えてきていることから、多様化していくものだという認識は持たれているのが現状としてあります。
　中国製のドローンが国内の公共事業でも推奨されない傾向にある中で、普及やコスト面において広がりが若干鈍くなっている２０２２年ですが、新聞メディアなどでも記事が増えていることからも、我々の生活の身近な存在及びこうした街中の飛行が珍しくない時代に向かっていることからも、これからと言ったところでしょうか。

#道路使用許可
　道路使用許可とは、道路交通法により交通の妨げになる行為を禁止している中で、一般の通行の安全を確保しながらであれば、期間を設けて許可するものです。ドローンの飛行は上空であることで一般の通行を妨げる行為であるか否かということは、一般的な見解といいつつその指針事態はしっかりと決められたものではなく、関係各位と協議の上、理解の得られる状況下で実施することになります。

#許可が必要か否かの判断
　ドローンの飛行に関して管轄する部署は各署の警備課になります。
　道路使用許可が必要とされる行為として、
「ドローンが飛行中に、道路上に一定の人数が集団で留まるような行為があるか否か。」
ということだそうです。
つまり、ドローンの飛行に関しては航空法上での人家への接近が３０ｍ確保できるのか否かということが法律での禁じられていることに対して飛行承認が得られていることに関与するものではなく、警察が管轄している部分に影響があるか否かということになります。
　判断については、ドローンの飛行＝使用許可が必要ということではなく、どのような飛行をするかによって、警察が警備していることに抵触しているかどうかという行為があるかないかという考えになります。

　尚、この記事に関しては、警察と打ち合わせを行う上で協議した内容により、考え方をまとめたものであり、警視庁及び都道府県警・警察署が公式に発表されたものではありません。
laravel 例外発生時の処理が記載されているところ

# 概要

- laravel8において例外発生時の処理が記載されているところ（httpレスポンスの処理とか）をメモ的に記載する。

# 記載されているところ

- `laravelアプリ名ディレクトリ/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php`
- `laravelアプリ名ディレクトリ/app`直下に当該のクラスを継承したクラスがあるので戻り値をカスタムする場合は下記をいじる。
    - `laravelアプリ名ディレクトリ/app/Exceptions/Handler.php`
【Project Euler】Problem 12: 約数の多い三角数

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 12. 約数の多い三角数

原文 [Problem 12: Highly divisible triangular number](https://projecteuler.net/problem=12)

**問題の要約：約数の数が初めて500を超える三角数を求めよ**

まず[三角数(Wikipedia)](https://ja.wikipedia.org/wiki/%E4%B8%89%E8%A7%92%E6%95%B0)にあるように$n$番目の三角数$T_n$は$1$から$n$までの和なので、

```math 
T_n = n(n+1)/2
```
まずsympyのdivisorsを使うと、とても簡単プログラムになります。

```Python
import sympy
import itertools

for n in itertools.count(1):
  dn = len(sympy.divisors(n*(n+1)//2))
  if dn>500:
    break
print(f" n={n}, Tn= {n*(n+1)//2}, divisors={dn}")
```

ただし、これだとすべての三角数の約数を求めるので速いとは言えません。

ここで[約数の個数(Wikipedia)](https://ja.wikipedia.org/wiki/%E7%B4%84%E6%95%B0#%E7%B4%84%E6%95%B0%E3%81%AE%E5%80%8B%E6%95%B0)を求める公式を使います

```math 
Nの素因数分解を \\
\large N = p_1^{a_1} p_2^{a_2} \dots p_k^{a_k} \\
とし、約数の個数を d(N)とすると\\
d(N)=(a_1+1)(a_2+1) \dots (a_k+1)
```
要は素因数分解さえできれば約数を全部列挙しなくても数だけを求めることができるということです。素因数分解はsympyのfactorintでDICT形式で求めることが出来ます。

```python
from sympy import factorint
for i in [4,5,6]:
  print(sympy.factorint(i))
#{2: 2}
#{5: 1}
#{2: 1, 3: 1}
```

約数の個数の公式を元にfactorintで素因数分解されたDICT形式から約数の個数を求める関数**fct2divn**は以下のようになります。

```python
import numpy as np
# Factors to number of disivors
def fct2divn(fct):
  return np.prod(np.array(list(map(lambda x: x+1,list(fct.values())))))

print(fct2divn({2: 1, 3: 1}))
# 4
```
そこで問題の三角数$T_n$の約数の数ですがポイントは以下になります。

* $n$と$n+1$は共通の素因数がない（互いに素）
* 従って$d(n \times (n+1)) = d(n) \times d(n+1)$
* $n$と$n+1$はどちらかが偶数なのであらかじめ２で割っておける
* 例えば$n$が偶数の時$d(Tn) = d(n/2) \times d(n+1)$となる

これをプログラムに実装すると以下のようになります。**divisors**と**factorint**のプログラムの実行時間の比較表を見るとかなり速くなっているのが分かります。

```python
dn = 1
for n in itertools.count(1):
  n1 = (n+1)//2 if (n+1)%2 == 0 else n+1 
  dn1 = fct2divn(factorint(n1))
  dnt = dn * dn1
  if dnt>500: 
    break
  dn = dn1
print(f" n={n}, Tn= {n*(n+1)//2}, divisors={dnt}")
```

| N| 500|1000|2000|3000|5000|
|:--:|:---:|:---:|:--:|:--:|:--:|
|divisors |0s|5s|133s| x| x|
|factorint|0s|0s|8s|13s|90s|
【Project Euler】Problem 11: マトリクスの中の最大積

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 11．マトリクスの中の最大積

問題の原文 [Problem 11: Largest product in a grid](https://projecteuler.net/problem=11)

**問題の要約：マトリクスの中の隣り合う（縦・横・斜め）4つの数の積の最大値を求めよ**

Pythonのnumpyマトリクスはちょっと癖があるので慣れが必要ですね。マトリクスの定義は長いので下に書きました。4x4のマトリクスを切り出して上辺、左辺、2つの斜めの積を計算して最大値を求める関数が**maxProdArr**です。

```Python
import itertools
import numpy as np

# return max product of left-vertical, top-horizontal, diagonal lines
def maxProdArr(mtx):     
  return max(np.prod(mtx[0,:]), 
             np.prod(mtx[:,0]), 
             np.prod(np.diag(mtx)),
             np.prod(np.diag(np.fliplr(mtx))))

sizeMtx, sizeWin = 20, 4
maxprod = 0
for y, x in itertools.product(range(sizeMtx-sizeWin), repeat=2):
  m  = Mtx[y:y+sizeWin,x:x+sizeWin]   # extract small matrix
  maxp = maxProdArr(m)
  if maxp > maxprod:
    maxprod, pos, maxarr = maxp, (y,x), m
      
print(f"Answer : {maxprod} at {pos}  \n{maxarr}")
```

```Python
import numpy as np
s = '08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 '\
'49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 '\
'81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 '\
'52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 '\
'22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 '\
'24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 '\
'32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 '\
'67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 '\
'24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 '\
'21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 '\
'78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 '\
'16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 '\
'86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 '\
'19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 '\
'04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 '\
'88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 '\
'04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 '\
'20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 '\
'20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 '\
'01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48'
Mtx = np.array(list(map(int,s.split()))).reshape(20,20)
print(Mtx, Mtx.shape, Mtx[2][4])
```