OmniAICreator/Qiita-1.07M huggingface dataset:
TypeScriptでコマンドラインパラメーター解析

Node.jsのCLIなツールをいくつかTypeScriptで作っています。

毎回コマンドラインパラメーターの解析が似たような処理になるので、関数にして使い回していました。

せっかくなのでパッケージとして公開しています。

- [optionalist](https://www.npmjs.com/package/optionalist)

## 特徴

- コマンドラインパラメーターの解析として、当然指定されたパラメーターの情報に合わせて解析します。
  TypeScript用なので解析結果は指定した名前と型のプロパティを持つオブジェクトとして返します。
  このときのオブジェクトの型は可能な限り指定されたパラメーターの情報を反映したものにしてあります。
- 指定されたパラメーター情報からヘルプ用の文字列を生成します。
  CLIに指定されたパラメーターにエラーがあれば自動的にヘルプ用文字列を表示するようにもできます。
- プロパティの型情報にはパラメーターのヘルプ用の文字列や制約などの情報を載せています。`VS Code`などの型を表示してくれるエディターであれば、プロパティにマウスカーソルを合わせるだけで、そのパラメーターの情報を表示してくれます。
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122792/bb34ed6a-3c17-4800-67e7-8fed3f419ff7.png)

## 使い方

まずはパッケージをインストールします。

```cmd
npm install optionalist
```

ソースコードからインポートします。

```ts
import { parse, unnamed, helpString } from 'optionalist';
```

parseが解析用の関数、unnamed、helpStringは使用するシンボルです。

コマンドラインパラメータの解析にはparse関数にコマンドラインの詳細を指定します。

```ts
const options = parse({
  help: {
    type: 'boolean',
    alone: true,
    describe: 'このヘルプを表示します。',
  },
  timeout: {
    type: 'number',
    default: 5000,
    describe: 'タイムアウトまでの時間(単位ミリ秒)を指定します。',
    example: 'milliseconds',
  },
  list: {
    multiple: true,
    describe: '処理対象のファイルを記載したファイルを指定します。',
    example: 'filepath',
  },
  [unnamed]: {
    describe: '処理対象のファイルを指定します。',
    example: 'filepath',
  },
  [helpString]: {
    describe: 'サンプル用のプログラム',
    showUsageOnError: true,
  },
} as const);
```

解析結果の`options`は`alone: true`が指定されたパラメーター`help`があるのでUnion型になっています。

そのままでは扱いにくいので、まずは`help`から処理していきます。

```ts
if (options.help) {
  options;
  // const options: {
  //   readonly help: true & {
  //       [description]: ["--help: このヘルプを表示します。", "is specified alone."];
  //   };
  //   readonly timeout?: undefined;
  //   readonly list?: undefined;
  //   readonly [unnamed]?: undefined;
  //   readonly [helpString]: string;
  // }

  process.stdout.write(options[helpString]);
  process.exit(0);
}
```

`options.help`がtrueになっていると他のプロパティ(`[helpString]`を除く)は`undefined`になっていて`help`以外はアクセスできなくなっています。

`[helpString]`だけはアクセスできるようになっているので、表示して終了してしまいます。

早期`exit`で`options.help`が`true`である可能性を潰したら、`options`の型はこんな感じになっています。

```ts
options;
// const options: {
//   readonly [unnamed]: readonly string[];
//   readonly [helpString]: string;
//   readonly help?: undefined;
//   readonly timeout: number & {
//       [description]: ["--timeout milliseconds: タイムアウトまでの時間(単位ミリ秒)を指定します。", "as 5000 if omitted."];
//   };
//   readonly list: readonly string[] & {
//       ...;
//   };
// }
```

`timeout`はデフォルト値が指定されているので非オプショナルな`number`、`list`は複数指定可能なので`
string`の配列になっています。

正確にはそれぞれヘルプ用文字列やデフォルト値、複数指定可能などの情報が付加されています。

```ts
options.timeout;
// (property) timeout: number & {
//     [description]: ["--timeout milliseconds: タイムアウトまでの時間(単位ミリ秒)を指定します。", "as 5000 if omitted."];
// }
```

```ts
options.list;
// (property) list: readonly string[] & {
//     [description]: ["--list filepath: 処理対象のファイルを記載したファイルを指定します。", "can be specified multiple."];
// }
```

パラメーター情報にどういうものが指定できるかは[optionalist](https://www.npmjs.com/package/optionalist)の方で確認してください。
【テックジム無料講座】ゼロからはじめるPython入門講座の感想

テックジムが無料で開催している、ゼロからはじめるPython入門講座をオンラインで受講してみました。たった2時間ですが、Pythonを使い、関数を書いてみるところまで網羅していて、非常に勉強になりました。Python初心者で、ProgateやPaizaしかやったことがない、私のような人がいれば是非挑戦してみてください。気づきがあるはずです。

<a href ="https://youtu.be/YWENu3LcZYU">ゼロからはじめるPython入門講座 0：サンプルソースを動かしてみる（テックジム チュートリアル）</a>
<a href ="https://youtu.be/p9oY3LL4de4">ゼロからはじめるPython入門講座 1：インデントの説明（テックジム Py1-1））</a>
<a href ="https://youtu.be/cYIBNu_HBKs">ゼロからはじめるPython入門講座 2：条件分岐文を書いてみる（テックジム Py1-1解説、Py1-2）</a>
<a href ="https://youtu.be/FfLuCxM0QzA">ゼロからはじめるPython入門講座 3：関数の説明（テックジム Py1-2解説、Py1-3）</a>
<a href ="https://youtu.be/Dc1F1tLGlOc">ゼロからはじめるPython入門講座 4：関数を書いてみる（テックジム Py1-3解説）</a>
<a href ="https://youtu.be/kD7L4x9Ggw4">ゼロからはじめるPython入門講座 5：あなたの手と相手の手を表示する（テックジム Py1-4解説）</a>
<a href ="https://youtu.be/3D3NL0KooTs">ゼロからはじめるPython入門講座 6：inputメッセージにリストを使う（テックジム Py1-5解説）</a>
<a href ="https://youtu.be/N3VYrxxIQx8">ゼロからはじめるPython入門講座 7：辞書（ハッシュ）（テックジム Py1-6解説）</a>
<a href ="https://youtu.be/K4N8iUN9i7M">ゼロからはじめるPython入門講座 8：再帰的呼び出し（テックジム Py1-7解説）</a>
<a href ="https://youtu.be/DEFqwh9sZxw">ゼロからはじめるPython入門講座 9：while文、True/False（テックジム Py1-8解説）</a>
<a href ="https://youtu.be/Vz5h_5QL3Zk">ゼロからはじめるPython入門講座 10：バリデーション（入力チェック）（テックジム Py1-9解説）</a>

<a href ="https://colab.research.google.com/">プログラム実行環境</a>
<a href ="https://github.com/techgymjp/techgym_python">サンプルソースの公開場所</a>
NanoPi NEO Core-LTS(8GB eMMC) + Mini Shield をArmbian OSで起動する


[NanoPi Neo CoreのeMMCバージョン](https://www.friendlyelec.com/index.php?route=product/product&product_id=212)を購入しました。
Mini Shieldと合わせて起動してみたいと思います。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547685/d83fc459-e0b8-9726-66cb-4a88580c6a20.jpeg)



今回はArmbian OSを使用します。
[アーカイブ](https://mirror.yandex.ru/mirrors/armbian/archive/nanopineo/archive/)からArmbian_21.02.1_Nanopineo_bionic_current_5.10.12をダウンロード。

[Rasberry Pi Imager](https://www.raspberrypi.com/software/)や[Win32 Disk Imager](https://github.com/dnobori/DN-Win32DiskImagerRenewal/releases/)等でダウンロードしたArmbianOSのimageをmicroSDカードにimageを焼いてあげます。

microSDをNanoPi Neo Coreに差し込み、LANをつないで電源をON


SD差込口横のLEDが緑色に点滅したら準備はOKです。
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547685/b79a1dee-7d3b-0be5-343b-c20dd34d7d6f.jpeg)

LANをつないでSSH接続してみます。(ユーザー:root, パスワード:1234)
![スクリーンショット 2023-01-16 020557.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547685/ce58aeeb-b575-a89e-810b-dd2a1f448663.png)

無事、起動できた様です！
起動後はパスワードを設定したりユーザーを作るよう丁寧に案内してもらえるので迷いは無いかと思います。
([次回](https://qiita.com/ps0139hk/items/dbd4604c2635e42d5e2e)へ続く)
GitHubの2要素認証はWindowsのpin（4桁）でOKだった（スマホ不要）

GitHubの2要素認証にはスマホのGitHubアプリや、SMSメッセージを使用するのが一般的かと思います。
しかし、これらの方法だと毎回スマホを取りに行くのが面倒ですし、スマホを忘れたらログインできず一発アウトです。

調べたところ、Windowsのログインに使用している4桁の数字を2要素認証に使用できることが分かったので設定してみました。

## GitHubの2要素認証とWindowsのPin（4桁）を連携させる方法

まず、GitHubのアカウント設定から[Password and authentication](https://github.com/settings/security)を開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/a5fc1f4a-6c1b-ef66-a2ab-0d21de33bbaf.png)

次に、このページの「Two-factor authentication」内にある「Security keys」の「Edit」を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/f74da501-d568-57e5-ef28-f70010e1d4db.png)

すると2要素認証の設定ページに行くので、そこで「Register new security key」をクリックします。
（登録したいキーの名前を聞かれるので、適当なものを入力します。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/2bd6d12a-8fdb-b947-61a5-55d909489772.png)

すると、Windowsのログインに使用している4桁のPin番号を聞かれるので、入力すると設定完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/2d9b586d-7318-dafb-819c-8dbcc68e41c9.png)

私は普段Windowsのログインに4桁のPinを利用しているのでこのようなプロンプトが出ましたが、指紋認証など他のログイン方法を使用している方は、そのログイン方法が使用されるはずです。

## まとめ

- GitHubの2要素認証は、Windowsのログインに使用している4桁のPinでも可能
  - Windowsログインに他の方法（指紋認証など）を使用している場合は、それを用いた2要素認証も可能
- GitHubのモバイルアプリを使うよりも手軽でよかった

[公式ドキュメント](https://docs.github.com/ja/authentication/securing-your-account-with-two-factor-authentication-2fa/configuring-two-factor-authentication#configuring-two-factor-authentication-using-a-security-key)を一見するとYubiKeyとかNFCリーダとか要るのかな？と思っていましたが、そんなものは必要ありませんでした。
スマホを使わずパソコンだけでログイン作業が完結するので、おすすめです。
とにかくスマホ紛失対策のためにログインに使える端末を増やしておくと安心ですね。
Markdown 「Qiita」と「はてな」の違いを調べた。（途中）

# 公式

https://qiita.com/Qiita/items/c686397e4a0f4f11683d

https://staff.hatenablog.com/entry/2012/09/19/153219

# google検索

https://www.google.com/search?hl=ja&sxsrf=AJOqlzXIKeNOwHDniidzLFDDvzete1msHQ%3A1673777323381&q=markdown+qiita&oq=markdown+qiita&aqs=heirloom-srp..0l5

https://www.google.com/search?hl=ja&sxsrf=AJOqlzXxwzU1Gw4cpOHo8G7m8ftok0P7fA%3A1673776657929&q=markdown+%E3%81%AF%E3%81%A6%E3%81%AA&oq=markdown+%E3%81%AF%E3%81%A6%E3%81%AA&aqs=heirloom-srp.0.0l5

# 違い。Qiita固有

# 違い。はてな固有

[asin:4798110523:detail]

https://www.google.com/search?q=4798110523&source=hp&hl=ja&oq=4798110523&gs_l=mobile-heirloom-hp.12..0i546l3.4455.4455.0.7560.2.1.0.1.1.0.153.153.0j1.1.0....0...1c.2.34.mobile-heirloom-hp..0.2.234.U1x5iWMLpm8

「へんな会社」のつくり方 (NT2X) | 近藤 淳也 |本 | 通販 | Amazon
kube-apiserverが参照するetcdを変更する

kubeadmで構築したkubernetesの外部etcdサーバーを切り替える方法。
この環境では、kubernetesのマスターノードとetcdのクラスタが別のマシンで稼働している。
そのためマスターノードにあるkube-apiserverの設定を変更し、向いているetcdサーバーを変更する。

# 設定方法

マスターノードのkube-apiserverは下記のファイルで設定されている。

```
/etc/kubernetes/manifests/kube-apiserver.yaml
```

そのためこのファイルを下記のように編集する。

```diff:/etc/kubernetes/manifests/kube-apiserver.yaml
  apiVersion: v1
  kind: Pod
  metadata:
    annotations:
      kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 192.168.0.2:6443
    creationTimestamp: null
    labels:
      component: kube-apiserver
      tier: control-plane
    name: kube-apiserver
    namespace: kube-system
  spec:
    containers:
    - command:
      - kube-apiserver
      - --advertise-address=192.168.0.2
      - --allow-privileged=true
      - --authorization-mode=Node,RBAC
      - --client-ca-file=/etc/kubernetes/pki/ca.crt
      - --enable-admission-plugins=NodeRestriction
      - --enable-bootstrap-token-auth=true
-     - --etcd-servers=http://192.168.0.3:2379,http://192.168.0.4:2379,http://192.168.0.5:2379
+     - --etcd-servers=http://192.168.0.11:2379,http://192.168.0.12:2379,http://192.168.0.13:2379
      - --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
      - --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
      - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
      - --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
      - --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
      - --requestheader-allowed-names=front-proxy-client
      - --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
      - --requestheader-extra-headers-prefix=X-Remote-Extra-
      - --requestheader-group-headers=X-Remote-Group
      - --requestheader-username-headers=X-Remote-User
      - --secure-port=6443
      - --service-account-issuer=https://kubernetes.default.svc.cluster.local
      - --service-account-key-file=/etc/kubernetes/pki/sa.pub
      - --service-account-signing-key-file=/etc/kubernetes/pki/sa.key
      - --service-cluster-ip-range=10.96.0.0/12
      - --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
      - --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
      image: registry.k8s.io/kube-apiserver:v1.26.0
      ##### 後略 #####
```

その後 kubelet を再起動する

```
systemctl restart kubelet
```

これで設定完了。

ここでは結論だけ書いたが、詳細は下記を参照。

https://zenn.dev/tk_hamaguchi/articles/8af67acb61b7fc
SplashScreenについて(静止画編)

こんにちはandroidでアプリ開発を学習中のみのむしと申します。
今回は、SplashScreenを学びましたので、実装方法を忘備録として残したいと思います。

<h2>SplashScreenを表示させるActivityを作成する</h2>

今回は、新規作成したActivityにSplashScreenを表示させ、その後にMainActivityにIntentする流れで作成していきます。

<h2>drawableに新規xmlファイルを作成する</h2>

```xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/white"/>

<item>
    <bitmap android:src="@drawable/表示させたいファイル名" android:gravity="center"
        />
</item>

</layer-list>
```
<h2>themes.xmlファイルに以下内容に追記する</h2>

```xml
<!--SplashScreen-->
    
    <style name="SplashScreen" parent="Theme.MaterialComponents.DayNight.NoActionBar">
        <item name="android:windowBackground">@drawable/表示させたいファイル名</item>
        <item name="android:statusBarColor"  tools:targetApi="l" tools:ignore="ObsoleteSdkInt">?attr/colorPrimaryVariant</item>
    </style>
```
<h2>作成した新規Activity(SplashScreenMain)に以下内容を記述する</h2>

```java
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;

public class SplashScreenMain extends AppCompatActivity {

    private final long TIME = 3000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash_screen_main);

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {

            //splashscreenを起動してから3秒後にMainActivityへ遷移する
                Intent intent = new Intent(SplashScreenMain.this,MainActivity.class);
                startActivity(intent);

            }
        },TIME);
    }
}

```

<h2>AndroidManifest.xmlファイルを編集する</h2>

デフォルトではMainActivityが最初に実行されるように設定されているため、SplashScreenMain
クラスが最初に実行されるよう以下内容に変更する

```xml
<activity
            android:name=".MainActivity"
            android:exported="true"/>
        <activity
            android:name=".SplashScreenMain"
            android:exported="true"
            android:theme="@style/SplashScreen"
            >
```
OpenLDAPで使用する主なスキーマファイル

●OpenLDAPで使用する主なスキーマファイル。
・core.schema cnやouなどの基本的な属性を定義(必須)
・cosine.schema X.500で定義された属性などを定義
・inetorgperson.schema inetOrgPersonクラスなどを定義
・nis.schema NIS(Network Infomation Service)関連のオブジェクトクラスや属性などを定義

OpenLDAP2.2までは、使用するスキーマファイルは、OpenLDAPの設定ファイル「slapd.conf」で「include」ディレクティブを利用して読み込み。

include /etc/openldap/schema/core.schema

OpenLDAP2.3以降は、スキーマファイルは旧来同様に格納されているものの、slapd.confは廃止される方向となり、スキーマの読み込みもLDIFファイルで行われる。（主要なスキーマはスキーマファイルとLDIFファイルが用意）
OpenLDAPの構成や設定も、すべてLDAPのオブジェクトとして構成される。

※OpenLDAPサーバの設定は以前は設定ファイル「slapd.conf」で行ったが、現在は「slapd-config」で動的に設定。

例）「slapd-config」を使った動的な設定でのスキーマの読み込み
# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif

オブジェクトクラスや属性には、OID(Object Identifier)という一意の識別子がIANA(Internet Assigned Numbers Authority)という機関によって割り当てられ、新しいオブジェクトクラスや属性を作成するためにスキーマファイルを作成・拡張する場合は、IANAから一意のOIDを取得する必要がある。
【Linux】xargsで引数の位置を指定する方法

以下のように記述することで引数の位置を指定できます。

```zsh
find . -name "*.log" | xargs -i cp {} /exampledir/
```

以下のようなコマンドが実行されます。

```zsh
cp ./path/to/sample.log /exampledir/
```

また以下のように記述しても上記と同様のことが実現できます。

```zsh
find . -name "*.yml" | xargs -IXXX cp -f XXX ./exampledir/
```
Discordサーバー『elixirと見習い錬金術師』紹介

こんにちは、Elixir入門コミュニティpiyopiyo.exのオーガナイザー、nakoです！

2022年10月22日に、Elixir初心者〜中級者向けDiscordサーバー『elixirと見習い錬金術師』が公開されました！

https://discord.gg/k7PHppmy53

2023/1/15時点で76人にメンバーが増えています！

![スクリーンショット 2023-01-15 23.03.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109744/45d101a5-0c0d-ff99-aec3-63521d42c6af.png)

カテゴリーとチャンネルはこんな感じです。
入門者コミュニティpiyopiyo.exのほか、スマホアプリ開発入門、SPA開発入門、機械学習入門とElixirで実装できるジャンルの入門者向けでチャンネルが分かれています。
また、質問用チャンネルが揃っています。

![スクリーンショット 2023-01-15 23.05.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109744/51a1431e-aa72-373a-15fb-2b03fdedb0a9.png)

入門〜中級者向けのElixirオンライン勉強会は、piyopiyo.exのほか、LiveView JPも、テキストチャットのやり取りはDiscordに移行しています。

Elixirが最近気になっている方、入門したい方この機会にいかがでしょうか？

https://discord.gg/k7PHppmy53

また、Elixirオンラインコミュニティの紹介は、下記スライドをどうぞ。

https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian
Goで値渡しとポイント渡しのベンチマーク比較

# 条件
インライン化しないように指定(go:noinline)

下記の条件の組み合わせベンチマークテスト実行
+ ワード(1word=64bit)数 1~10
+ 関数 or 値レシーバ or ポインタレシーバ
+ 引数1~3、戻り値0~2


# 結果

https://github.com/shunsukuda/go-val_vs_ptr/blob/main/bench_result.txt

https://github.com/shunsukuda/go-val_vs_ptr/blob/main/bench_global_result.txt

+ ポインタのみの場合は常に一定
+ 引数と戻り値の数が少ない内は5~6ワード目まで差は小さい
+ 引数と戻り値の数が多くなると2ワード目からでも2倍程度の差になる
+ 2ワード以上の場合は素直にポインタを使用するほうが無難
+ ヒープ割り当て発生時は要計測
github actionsでmaster branchへpull requestした際の挙動とpush時の挙動を別々にしたい場合の備忘録

github actionsでmaster branchへpull requestした際の挙動とpush時の挙動を別々にしたい場合の備忘録

## やりたいこと
- pull requestした際はpull request対象ブランチをgit cloneしたい
- masterへpushした際はmasterブランチをgit cloneしたい
- ファイルは分けずに環境変数のみを分けたい

## 作成した`.github/workflow/ci.yaml`ファイル

```yaml:.github/workflow/ci.yaml
name: test-ubuntu
      
on: 
# push/pullrequest時にci実行
    push:
      branches: [master]
    pull_request:
        paths-ignore:
          - '.gitignore'
          - 'LICENSE'
          - '**.md'

# 環境変数
env:
  BRANCH_NAME : "master"

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.9', '3.10'] # [3.5, 3.6, 3.7, 3.8]

    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: update environment
        run: |
          echo "BRANCH_NAME=${{ github.head_ref }}" >> $GITHUB_ENV
        if: github.event_name == 'pull_request'
      - name: Install dependencies
        run: |
          echo $BRANCH_NAME
          git clone https://github.com/seigot/tetris -b ${BRANCH_NAME}
```

ポイントは以下の部分


```yaml
      - name: update environment
        run: |
          echo "BRANCH_NAME=${{ github.head_ref }}" >> $GITHUB_ENV
        if: github.event_name == 'pull_request'
```

`if: github.event_name == 'pull_request'`であれば環境変数を更新する。
この方法は環境変数に限らず、何か`pull request/push`時でそれぞれ挙動を変えたい場合に活用できそうに思えるのでどこかで活かしていきたい。

# 参考

https://qiita.com/Daara_y/items/b23bce4c0a2f763451b1

>```yaml
># Controls when the action will run. Triggers the workflow on push or pull request 
># events but only for the master branch
>on:
>  push:
>    branches: [ master ]
>  pull_request:
>    branches: [ master ]
>```

https://stackoverflow.com/questions/66205887/only-run-github-actions-step-if-not-a-pull-request

>```
> - name: Publish NuGet
>   uses: brandedoutcast/publish-nuget@v2.5.2
>   with:
>     PROJECT_FILE_PATH: "Orleans.Sagas/Orleans.Sagas.csproj"
>     NUGET_KEY: ${{secrets.NUGET_KEY}}
>   if: github.event_name != 'pull_request'
>```

https://docs.github.com/ja/actions/using-workflows/events-that-trigger-workflows

```
on: issue_comment

jobs:
  pr_commented:
    # This job only runs for pull request comments
    name: PR comment
    if: ${{ github.event.issue.pull_request }}
    runs-on: ubuntu-latest
    steps:
      - run: |
          echo A comment on PR $NUMBER
        env:
          NUMBER: ${{ github.event.issue.number }}
```

https://stackoverflow.com/questions/62331829/how-to-get-the-target-branch-of-the-github-pull-request-from-an-actions

https://docs.github.com/ja/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#pull_request

https://dev.classmethod.jp/articles/how-to-get-a-ref-branch-within-a-workflow-execution-in-github-actions/
エクスプローラで開いているフォルダをWindows Terminalで開く

## Windows Terminalを開きたい！

エクスプローラで現在開いているフォルダをカレントディレクトリにしてターミナルを開きたいときありますよね。

下図のように、Dドライブ直下を開いているときに、ここをカレントディレクトリとしてターミナルを開きたいとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255360/84339dbc-f216-154e-ee8c-bcdc5dc333a5.png)

そこで、アドレスバーに
```
wt -d .
```
と打ちます。すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255360/ee9f59cb-c0f9-5a10-1a11-04545f9783a6.png)

開きました🎊

## ちなみに...コマンドプロンプトの場合

アドレスバーに
```
cmd
```
と打つだけで開きます。
※下ではWindows11の設定でコマンドプロンプトもWindows Terminalで開くように設定しているためWindows Terminalが起動していますが、シェルはコマンドプロンプトとなっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255360/8f5c87a2-a6b9-df24-18e7-eeaad09c29e8.png)
【ネットワーク】パケットフィルタリングとは


# パケットフィルタリングとは


パケットフィルタリングとは、パケットの内容を見て通過を可否を振り分ける機能のことです。


ネットワークのセキュリティを高めるためにファイアウォールを設けます。ファイアウォールは通して良いデータだけを通してそれ以外を遮断するもののことです。
その中の一つの手法としてパケットフィルタリングがあります。

パケット内のIPアドレスやポート番号などの情報を見て通過の可否を判断します。



# まとめ


パケットフィルタリングとは、パケットの内容を見て通過の可否を振り分ける機能です。

ちなみにAWSだと「セキュリティグループ」として設定するものに当たります。
Vueのライフサイクルフックを3分間でおさらい

Vue.jsを開発で使い始めた人が最初の方で詰まるのが`ライフサイクルフック`だと思います。
どのタイミングで取得したデータを表示するかといったことはライフサイクルメソッドを理解していないと上手く実装できません。
フロントエンドのライフサイクルフックは`４つのタイミング`を押さえておくことで使いこなせるようになります。
ここでは、ライフサイクルメソッドに登場する４つのタイミングを紹介します。
この４つのタイミングを覚えておくことでVueのインスタンスとデータの扱いがより柔軟になります。

## ライフサイクルフックとは？
Vueインスタンスが作られてから消えるまでの一連のサイクルにある節目のタイミングで呼ばれる処理を事前に登録して、そのタイムングで自動に呼ばれることです。
生き物の一生と同じです。
例えばカエルが`産まれる`・`あるタイミングになったら脱皮をする`・`死ぬ`というように生き物にはあるタイミングがあります。

ちなみにchatGPTの回答↓
’’’
Vue.jsはJavaScriptのフレームワークで、コンポーネントベースのアプリケーションを構築するために使用されます。Vueのコンポーネントには、ライフサイクルフックと呼ばれる特別なメソッドがあります。これらのメソッドは、コンポーネントのライフサイクルの中で特定のイベントが発生したときに呼び出されます。
例えば、コンポーネントが作成されるときに、beforeCreateやcreatedといったメソッドが呼び出されます。また、コンポーネントが更新されるときに、beforeUpdateやupdatedといったメソッドが呼び出されます。これらのメソッドを使用することで、コンポーネントのライフサイクルに応じて、適切なタイミングで処理を実行することができます。
’’’
###  ライフサイクルフックを理解するうえで知っておくべき知識
- Vue.jsのdata
- Vueインスタンス
- DOM
- DOMにマウント
(Googleにコピペして調べてみてください！)

## 4つのタイミング
ライフサイクルフックは流れやタイミングは暗記する必要は特になく、大まかな流れを把握して必要なときに図を参照して実装すれば十分です。
Vue.jsのライフサイクルを調べるときに"４つのタイミング"というキーワードを知っておけば早く把握できると思います。

> [Lifecycle Hooks](https://vuejs.org/guide/essentials/lifecycle.html)

| フックの種類 | タイミング |
| --- | ---|
| create | vueインスタンスが生成されて、データが初期化される前後 |
| mount | vueインスタンスがDOM要素にマウントされる前後 |
| update | データが変更されて、DOMに適用される前後 |
| destroy | vueインスタンスが破棄される前後 |

## おわりに
一見難しそうなライフサイクルフックですが特定のタイミングで何か処理をしたいときに使うものだと理解したら意外と簡単な概念です！
少しでも役に立てば幸いです！！
[Python]ABC285 レポ

# 要約
2完（A, C）
PyPyはいいぞ

# 個人的解説
## A - Edge Checker 2
`b`に対して`a * 2 or a* 2 + 1`と合致するか調べた
よく考えれば`a // 2`でよかった🥲

```py
a, b = list(map(int, input().split()))
if a*2 == b or a*2+1 == b:
    print("Yes")
else:
    print("No")
```

## B - Longest Uncommon Prefix
問題文が読めない！むずい！けど実装してみたら案外簡単だったやつ。

```py
n = int(input())
s = list(input()[:])

for i in range(1, n):
    l = 0
    for k in range(n-i):
        if s[k] == s[k+i]:
            break
        l += 1
        
    print(l)
```

...が、これで**TLE**。
いろいろ試したが、結局コンテスト中には間に合わず、Twitterで調べた「PyPyで実行したらいけたわ笑」を信じて実行したら通った。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/84fddcb3-b84b-c3d0-21bd-725be884a573.png)

今まで「名前が卑猥なライブラリ」という印象しか持っていませんでした。ごめんなさい。

## C - abc285_brutmhyhiizp
`A-Z`を一桁とした**26進数**として処理するのがミソ。

```py
s = str(input())[::-1]
total = 0


def c_to_base(c):
    return ord(c) - ord('A') + 1


for i in range(len(s)):
    c = s[i]
    weight = 26 ** i
    
    total += c_to_base(c) * weight
    
print(total)
```
# おわりに
久しぶりにやってみたら結構さっくりと解ける問題が多めで楽しかった。

普段はpaizaラーニングみたいな「ロジック組めればOK!」といった感じのところの問題しか解かないので、制限時間にはしばらく苦しめられそう。
IAMロールについて

## IAMロールとは

AWSリソースへのアクセス権限を付与するための仕組み。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733779/1e98c7e6-a9cf-aa38-ed2d-3fd7c74e0dd5.png)

## リソースベースポリシーとアイデンティティベースポリシーとは
- リソースベースポリシー
IAMロールの信頼ポリシー/s３バケットポリシー/kmsポリシーなど、
リソースそのものに付属しているポリシー
- アイデンティティベースポリシー
IAM アイデンティティ( IAMユーザー、IAMグループ、IAMロール)にアタッチできるポリシーで、いわゆる IAM ポリシー・Permissions policy がこれに該当します。

## クロスアカウントについて
クロスアカウントでのアシュームロールは双方向で許可が必要。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733779/ffbe9919-651a-18ee-0765-825b256abbf5.png)
【react navigation】react-navigation/bottom-tabsが動かない（自分メモ）

## はじめに
2022年5月にreact-navigation/bottom-tabsが動かなくなった時の対処法をメモ_φ(･_･

バージョン管理は大事。

## 原因
react-navigation/nativeとreact-navigation/bottom-tabsのバージョンが違ったため

## 解決策
react-navigation/bottom-tabsのバージョンが6であったため、既存のreact-navigation/nativeも5→6にバージョンアップした

## 参考記事
https://stackoverflow.com/questions/60248336/check-the-render-method-of-bottomnavigation-react-native　https://reactnavigation.org/docs/upgrading-from-5.x/
【react navigation】react navigationで遷移先に値を送る（自分メモ）

## はじめに
react navigationで遷移先に値を送る時、いつもググって、できなくて、大変なので、メモ_φ(･_･

## react navigationで遷移先に値を送る方法

■遷移元

```
const navigation = useNavigation();
```

```
navigation.navigate("ページ名", { hoge: 4 })
```

■遷移先

```
const { hoge } = props.route.params
```
AtCoder Beginner Contest 285 A〜C問題をPythonで解いてみました

AtCoder Beginner Contest 285 A〜C問題をPythonで解いてみました

[ABC285(AtCoder Beginners Contest 285)](https://atcoder.jp/contests/abc285)
A〜C問題をPythonで解いてみました。

- コードは雑めです。ゆるしてー
- 競技プログラミングの勉強一切したこと無いので、テクニックは知らないよ。ごめんねー

## [A問題](https://atcoder.jp/contests/abc285/tasks/abc285_a)(diff=11)
[提出コード](https://atcoder.jp/contests/abc285/submissions/38051466)
```python
a, b = map(int,input().split())
 
if b == a*2 or b == a*2+1:
  print('Yes')
else:
  print('No')
```

- パッと見ちょっと難しいんでは？って思うかもしれませんが、「これがA問題ということは発想の転換をするだけで解ける問題かなぁ〜」と当たりをつけてよくよく木を見ました。
- よく見ると分岐先は **分岐元＊２** と **分岐元＊２＋１** になっていることがわかりますね
- 2分木だから当たり前かー、と思いながらその順序でif文を書いてやればOKでした。
- $ 1 \leqq a < b \leqq 15$ となっており、$ a<b $ なところも確認してsubmitって感じですね。

## [B問題](https://atcoder.jp/contests/abc285/tasks/abc285_b)(diff=108)
[提出コード](https://atcoder.jp/contests/abc285/submissions/38056777)
```python
N=int(input())
S=input()
for x in range(1,N):
    for l in range(N):
        if l+x >= N or S[l+x] == S[l]:
            break
    print(l)
```
- Longest Uncommon Prefix というタイトルがまずヒントでしたね。解きたい問題がイメージしやすかったです。
- xを1から、lを0から初めて、同じ文字が出てくるまで検索するプログラムを書いていけばOKですね。
- l+x >= Nとなるケースについては問題文の最後にあるようにNを超えた時点のlを出力すればOKということで、こんなプログラムになりました。

## [C問題](https://atcoder.jp/contests/abc285/tasks/abc285_c)(diff=157)
[提出コード](https://atcoder.jp/contests/abc285/submissions/38058625)
```python
S=input()
n=0
for i in range(len(S)):
    n*=26
    n+=ord(S[i])-ord('A')+1
print(n)

```
- まず１文字ずつの数値化について考えますと、抽出した文字のASCIIコードから`A`のASCIIコードを引いて+1すればいいと求まります
- あとは桁が進むごとに進数分掛けてやればいいので、２６進数ということで26倍してやればいいだけです。

## 感想
- 今回の問題も易しめでしたね。最近は簡単めな問題が多いAtCoderですね
    - 学生エンジニアとしてアルバイトしたい方など、プログラム練習中の方にはわりと丁度いい問題かと
    - 冷静に問題を読んで、アルゴリズムを書けば解ける問題かと思います
- 10分ぐらい遅れてUnratedで参加したのですが、20分ぐらいで解けましたね。
dxlib-for-linux 2022年の進捗

# （旧暦になってしまいましたが）今年の進捗
[前回のAdC](https://qiita.com/dragoon2014/items/04f809868fc77f57742a) 以降ですこし追加実装しました

## sample09_window
ウィンドウサイズが変更できるようになりました
そもそもオリジナルの実装と違いウィンドウサイズに合わせた
メモリの確保といった操作はしていないので
サイズ変更を許容するように実装を切り替えただけです
（逆に言うとメモリは浪費してるのかも）

![sample09.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51482/3d081fb2-921c-9ab4-ddd2-4d65a5203584.gif)

## sample10_dnd
ドラッグアンドドロップができるようになりました
ファイルをつかめる別のGUIアプリケーション（Thunarとか）から
ファイルをひっつかんで落とすとパスを取得できます
オリジナルと違い、text/uri-list形式なのでご注意ください
この形式はブラウザでDnDを扱っている方は馴染みがあるとおもいますが
fileスキームにパーセントエンコーディングされたパスの形となります
例：/path/to/ほげ.txt→file:///path/to/%E3%81%BB%E3%81%92.txt

![sample10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51482/fd613188-d4a1-0bd2-69eb-a51f476b2950.png)

## sample11_change_font
フォントの変更ができるようになりました
予めDxLibに同梱されているCreateDXFontDataでdftフォントを作成することで
日本語含む任意のフォントを使用することができます（要フォントのライセンス確認）
欠点としては一度Windowsにフォントをインストールし、dftファイルを生成する手間がかかります
Wineでも変換できるかもしれませんが未確認です

![sample11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51482/cc8d18d6-e6e8-d1b3-16af-a2b2a912ad2c.png)

## //sample12_clipboard
//クリップボードへ読み書きができるようになる予定でした
今年はクリップボード周りを実装したいです

# おまけ、ビルドに必要なパッケージ一覧

Ubuntu(Xubuntu Live 20.04.5 / 22.04.1で確認、多分各フレーバーのインストール直後と同じ)で
素の状態からインストールが必要なパッケージ一覧を貼っておきます
とりあえず動かしたい場合は以下を端末に貼れば動くと思います

```
sudo apt update
sudo apt install make g++ \
  libegl-dev libgles-dev \
  libtiff-dev libpng-dev \
  libopenal-dev libvorbis-dev libtheora-dev libopusfile-dev
```

# おまけ2、dxlib-for-linux on Windows Subsystem for Linux

だいぶ物好きな方向けですが、Windows上でもdxlib-for-linuxが動作しました
デフォルトでUbuntu 20.04(22.04はまだないっぽい)がインストールされるようです
挙動の差を見やすいので便利ですね

![wsl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51482/6e91ec33-094d-8748-55c5-3d615820c8e3.png)

## おまけ2のおまけ
おま環かもしれませんが、WSL上で右シフトキーが使えず不便だったので右シフトを左シフト扱いするレジストリ貼っておきます

```
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,02,00,00,00,2a,00,36,00,00,00,00,00
```
参考
https://so-zou.jp/pc/keyboard/scancode-map.htm
pecoを使ってgitのローカルブランチを複数削除する

# gitブランチの削除コマンド
最初にコマンドを記載します。
末尾は`-D`としていますが、削除したい方法に合わせて`-d`に変更してください。
※この記事でいうブランチは「ローカルブランチ」を指します。
```
$ git branch | peco | cut -b 3- | xargs git branch -D
```
こちらのコマンドを使用することで git のブランチ名を都度入力やコピペすることなく、
複数選択して削除することができます。
（pecoをインストールしていることが前提です）

pecoについての参考記事
https://qiita.com/tmsanrinsha/items/72cebab6cd448704e366

上記コマンドを実行すると存在するブランチ一覧が表示され、
選択→削除できる状態になります。

複数の行選択は
```
Ctrl + Space
```
でできます。
以下はブランチ削除するブランチを選択した状態です。
（色は環境によると思いますが私の環境では水色になっています）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360742/943a0151-907b-ec2d-6a74-1bb1869c6a69.png)


# pecoを使わない場合
ちなみにpecoを使わずgitのローカルブランチを削除する基本コマンドは以下です。
```
マージ済みブランチの削除
$ git branch -d [ブランチ名]

強制削除
$ git branch -D [ブランチ名]
```
[ブランチ名]をコピペするのが意外と手間です。

# コマンドについて簡単に説明
```
$ git branch | peco | cut -b 3- | xargs git branch -D
```
では「`｜`（パイプ）」で区切っているコマンドごとに見てきます。
- `git branch`
    - ブランチの一覧を表示
- `peco`
    - pecoを実行
- `cut　-b 3-`
    - cut：必要な項目を表示
    - -b：必要な項目をバイト数で指定するオプション
    - 3-：3バイト目以降を表示
    ※`git branch`コマンドを実行してブランチ一覧を表示するとわかりますが、
各ブランチ名の先頭に2バイト分の空白があるためそれを取り除き3バイト目以降を全表示します
- `xargs git branch -D`
    - xargs：標準出力やファイルからリストを読み込み、任意のコマンドに引数として渡します。
あるコマンドの実行結果や出力内容をパイプ (|) で xargs コマンドに渡し、
別のコマンドの引数として使用することができます
    - git branch -D：ブランチを削除

これらのコマンドを「`｜`（パイプ）」で繋ぐことで、
1. gitのブランチ一覧を表示
2. 削除対象ブランチを1〜複数選択
3. 選択したブランチを一括削除
することができます。 

便利ですね。


# メモ
`｜（パイプ）`の意味をなんとなくでしか理解していなかったので記載しておきます。
Linuxコマンドを使って標準出力された内容を次のコマンドへ橋渡しするために使われるコマンド
こちらが参考になります。
https://academy.gmocloud.com/know/20210630/12090#:~:text=%E3%83%91%E3%82%A4%E3%83%97%E3%81%A8%E3%81%AF%E3%80%81Linux%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89,%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%BE%E3%81%97%E3%82%87%E3%81%86%EF%BC%81
ファイルシステムとデータベースシステムの違い

# 特徴の違い
### 【ファイルシステム】

- 一人が管理する
- 複数人で編集することを前提としていないため、同時編集不可
- 暗号化機能がある
- 圧縮機能がある
- データはOSが管理（OSに依存するため、OSによる差分大きい）

### 【データベースシステム】

- 複数人で管理可能
- 同時にシステムにログインすることが可能
- [CRUD操作](https://ssaits.jp/promapedia/glossary/post-6593.html#)権限をユーザーごとに設定可能→Aさんは読み取りのみ、Bさんは書き込みのみ等設定可能（システムごとに権限分けるのも可能）
- SQLを使って同一の書き方で検索・挿入が可能（システムによるプログラミング言語の違いを無視できる）（再利用性◎）
- バックアップ機能が充実
- 大量のデータを保存したとしてもある程度軽量
- データはDBMSが管理

# まとめ

- それぞれ特徴が存在するため、**どちらか一方のみを使用する**のではなく両方の特徴を理解したうえで使い分けるのが重要

# 参考サイト

- [https://emeao.jp/guide/system/system-knowlege/post-28848/](https://emeao.jp/guide/system/system-knowlege/post-28848/)
- [ファイルシステムとデータベースの違いを現役エンジニアが解説 | システム開発会社を探すなら「比較ビズ」 (biz.ne.jp)](https://www.biz.ne.jp/matome/2005444/)
【Docker】docker-composeで起動したnginxコンテナがExit1となった時の解決法

## はじめに
インターン先でDockerを使うので、Dockerへの理解を深めようと、自作で開発していたLaravelアプリをDockerで環境構築してみました〜😸

## 経緯
1. コンテナを立ち上げる
```
docker-compose up -d
```
▼ 結果
![スクリーンショット 2023-01-15 21.45.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2412660/19f472fe-d913-9eec-4331-677bfbdf8c08.png)
2\. コンテナを起動を確認する
```
docker-compose ps
```
▼ 結果
![スクリーンショット 2023-01-15 21.23.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2412660/e53f3477-fe02-dc55-79dd-7e89e2a60093.png)
nginxコンテナだけが、StateがExit1になってる...😿

## エラー内容

```
Name               Command               State                Ports                       
--------------------------------------------------------------------------
（中略）
nginx   /docker-entrypoint.sh ngin ...   Exit 1     
```

▼ `docker-compose logs`でログを見ると、`Operation not permitted`となっている。
```
nginx    | nginx: [emerg] open() "/etc/nginx/conf.d/default.conf" failed (1: Operation not permitted) in /etc/nginx/nginx.conf:31
```
## 試してみたこと
- `docker-compose kill`コマンドを実施
- Dockerイメージ、コンテナの削除
- `docker-compose.yml`ファイルの`nginx`イメージを、`nginx:stable-alpine`→`nginx:latest`に変更

## 解決方法
Docker for Macでアクセスの許可がされていないため、nginxコンテナがExit1となってしまったよう。

今回の場合、私はプロジェクトフォルダを「書類」フォルダに配置していたので、「書類」フォルダからのアクセスを許可する必要があったっぽい🙀

1. Macの左上のりんごマーク → システム環境設定
1. セキュリティとプライバシー
1. 「プライバシー」タブ
1. 赤枠の箇所に✅を入れる
![スクリーンショット 2023-01-15 21.55.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2412660/6561bc3f-598e-c527-d3b8-6b61489caab8.png)

## 参考記事
https://osusublog.net/?p=411

https://github.com/aschmelyun/docker-compose-laravel/issues/51

https://qiita.com/miyamasaru/items/7db072628e03b8dbb08a
データ構造と計算量について

# データ構造とはなにか

> [コンピュータプログラミング](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)での、[データ](https://ja.wikipedia.org/wiki/%E3%83%87%E3%83%BC%E3%82%BF)の集まりの形式化された構成([Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0))

とあるが、本記事ではこのうち「データの集まりの形式化された構成」について深堀をしていく。
データの集まりといえば、データベースが初めに思い浮かぶと思うが、実は「データベース≠データ構造」である。
実は、以下のものもデータ構造である。
- プログラミングにおけるすべての変数
- List,Map,Set等のコレクション
- ファイル
- データベース etc…

このことから、言い換えるとデータ構造とは**プログラミングにおけるアルゴリズム以外のすべて** といっても過言ではない（と思う）。

# 実は普段からデータ構造を意識している

データ構造は実はプログラミング以外にも活かすことができる。
例えば、あなたは本を保管するときにどのようにして保管しているだろうか。
私は本棚に本を巻数順に並べて保存しているが、本の保管方法はほかにもたくさんある。
例えば「本棚に入れずに無秩序に本を保管する」というのも一つの保管方法である。
しかし、大半の人は本棚に入れて本を保管していると思う。ではなぜ私を含め、多くの人は本棚に本をいれて保管するのだろうか？

それは私たちは無意識に**データ構造のトレードオフの関係** を意識しているからだと思う。ここでは、本棚に入れる方法と無秩序に保管する方法のそれぞれのメリット・デメリットについて考えてみよう。

|                              | メリット                                                     | デメリット                                         | 
| ---------------------------- | ------------------------------------------------------------ | -------------------------------------------------- | 
| 本棚に入れて本を保管する方法 | 整列されていて、本を探すのが楽                               | 本を新しく買ったときに整列しなおさなければならない | 
| 無秩序に本を保管する方法     | 買った後、何の操作もせずに保管ができる（整列する必要がない） | 本を探すときに大変                                 | 

以上に示したように、普段から私たちはデータ構造について無意識的に考えているのである。
プログラミングにおいては、これらを意識的に考えなければならない機会が数多く存在する。なぜなら、コンピュータには次に示すある特性があるからだ。

# コンピュータの特性

コンピュータには以下の特性がある

- 有限な記憶領域
    - コンピュータが一度に記憶できる情報の量は有限である
- 記憶領域へのアクセスの正確性
    - コンピュータは指定した記憶領域へのアクセスを間違うことなく、正確に行うことができる（これをランダムアクセスという）
- 高速性
    - コンピュータはCPUによって、高速に記憶領域へのアクセスを行うことができる

したがって、一見なんでもできるように見えるコンピュータだが、実は記憶領域は有限であるため一度に複数の情報を保存できるわけではないし、高速に処理できるといっても限界はある。
この「どのくらい記憶領域を使うか」を定量的に表したものを**空間計算量**といい、「どのくらい計算に時間がかかるか」を定量的に表したものを**時間計算量**という。

# 計算量

計算量には空間計算量と時間計算量があるが、この２つのうちどちらが重要だろうか？

どちらも重要であることには変わりないのだが、近年のコンピュータの進化により記憶領域はかなり大きな領域確保できるようになった。しかし、CPUに関しては発熱の観点もあり、進化はほぼ頭打ち状態であり、今後も集積回路を用いたCPUは大きく進化しないだろう。

したがって、この２つの計算量のうち**プログラマーが意識すべきは主に時間計算量**だと思う。

そのため、多くの場合単に「計算量」というと時間計算量のことを指す。

計算量の具体的な算出方法は以下を参考にしてほしい。

[計算量とは？プログラムの性能を計ってみよう | Shino's Mind Archive (shinoarchive.com)](https://shinoarchive.com/contents/746/#toc2)

# まとめ

- データ構造は**プログラミングにおけるアルゴリズム以外のすべて**
- データ構造は**トレードオフの関係**
- トレードオフを考えるときの定量的な基準が**計算量**
- 特に重要なのは時間計算量

# 参考サイト

- [計算量とは？プログラムの性能を計ってみよう | Shino's Mind Archive (shinoarchive.com)](https://shinoarchive.com/contents/746/#toc2)
- [データ構造 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0)
- [基本的なデータ構造まとめ - Qiita](https://qiita.com/keitean/items/de4846d5d0ecdd4e8e63)
- [構造化データと非構造化データとは？活用の難しさと解決手法｜CONTENTS｜TOPPAN DIGITAL](https://solution.toppan.co.jp/digital/contents/cdp_contents07_0831.html)
- [【アルゴリズム】2文探索木の探索及び計算量についてのあれこれ | 明日以降本気出します (ikumi-1.com)](https://ikumi-1.com/2019/03/31/post-606/)
【Android】Guidelineとは【Kotlin】

# はじめに
今回はたまたまコードを眺めているうちに見つけたXML上のLayoutについて気になったので
記事にしようと思いました
発見した要因は、「～～Layout」や「～～View」といったものはよく目にしますが、全く違うものがあったので目に留まったといった感じでしたｗ

# Guideline
直訳すると　そのまま「ガイドライン」ですね
いわゆる　補助線を追加できるといったものになります
このGuidelineは垂直または、水平のいずれかに設定できます

配置方法は3種類で
|説明|実際のコード|
|:---|:---|
|レイアウトの左辺or上辺からの固定距離の指定|layout_constraintGuide_begin|
|レイアウトの右辺or下辺からの固定距離の指定|layout_constraintGuide_end|
|レイアウトの幅または高さのパーセンテージを指定|layout_constraintGuide_percent|


    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/vertical_guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_end="250dp" />

![スクリーンショット 2023-01-15 21.40.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2394054/009e97e8-b723-8bde-a1ee-638547fde1a8.png)


android:layout_widthとandroid:layout_heightは　線なのであたいに意味がないそうです
ですが、設定していないとエラーが発生するため"０"又はwrap_contentを設定しておくことを推奨します

# 参考
https://qiita.com/yamadacsa/items/3434c277d23e04ee50cb

https://developer.android.com/reference/androidx/constraintlayout/widget/Guideline

# おわりに
今回普段は目にしないLayout関連のものを記事にしてみましたが、こういったものも使った経験をして自分の身につけていかないとどんどん忘れてしまいそうなのでチャンスを見つけて使ってみたいですね
これからはComposeを使う機会が増えると思いますが、まだまだXMLも勉強が必要かもしれませんw
Azure ADライセンスと課金体系についてまとめ


Azure ADライセンスの課金がどのように発生するかまとめました。

資料はMicrosoft公式の以下のページで、ここから抜粋しています。
https://jpazureid.github.io/blog/azure-active-directory/azure-ad-purchase/

1.Azure AD有償ライセンス割り当て方法
>1. Azure ポータル にアクセスします。
>2. [Azure Active Directory] にアクセスします。
>3. [ライセンス] を選択します。
>4. [すべての製品] を選択します。
>5. 購入した ライセンスを選択します。
>6. [ライセンスされているユーザー] に [割り当て] を選択して割り当てます (※ 事前にユーザー プロファイルより、「利用場所」を設定する必要があります。設定していない場合はライセンスの割り当てに失敗します。)

2.支払いは年支払いor月々の支払で行われる
>オンラインからの購入であれば、1 個単位で購入が可能です。期間は年間契約 (年支払い or 月々の支払) になりますので、月単位での購入はできません。試用版も用意していますので、短期間の場合は、まず試用版をお試しください。

3.有料プランに切り替わるタイミングはユーザーが決められる
>こちらで、30 日間無料で、Azure AD Premium P2 ライセンスの機能を試すことができます。なお、30 日間経過後に自動で有償ライセンスに移行するといった動作はありませんのでその点ご安心ください。一度試用版の有効期限が経過すると、再度試用を有効にすることはできません。
UIFlow2.0 で ATOMS3 を扱ってみた時のメモ（ファームウェア「Alpha-1」を利用）

この記事は、以下のツイートに出てきている「UIFlow2.0用のファームウェア（Alpha-1 という名前のアルファ版第2弾のもの）を使って、ATOMS3 のプログラムを作って動かす」ということをやった流れのメモです。

https://twitter.com/youtoy/status/1614066789448822784

開発には、以下のツイートで紹介されており、現在アルファ版の「[UIFlow2.0](https://uiflow2.m5stack.com/)」を使います。それと、現時点で UIFlow2.0 を使った開発が行えるデバイスは ATOMS3 のみのようです。

https://twitter.com/M5Stack/status/1611730509784305665

## 大まかな手順
今回の大まかな手順は以下の通りです。

1. M5Stack Community などで使うアカウントを作成
1. M5Burner を使い、ATOMS3 に UIFlow2.0用のファームウェアを書きこむ ← この時、上記のアカウントでのログインが必要（※ アカウントを経由して、デバイスと UIFlow2.0を紐付けるようです）
1. UIFlow2.0のサイトを開き、上記アカウントでログイン
1. 上記のファームウェアを書きこんだデバイスを指定する
1. プログラムを作成して実行する

## 手順の補足
上で書いていた手順について、画像・説明などを掲載します。

### ファームウェア書き込み時のログイン
上記手順で、M5Burner を使う際にログインが必要と書きました。これは、UIFlow2.0 とデバイスの紐づけを、アカウント経由で行うためのようです。

ログインをせずに書き込みを行おうとすると、書き込みボタンを押したタイミングで以下のエラーメッセージが表示されます。

https://twitter.com/youtoy/status/1611926307075690496

### M5Burner上でファームウェアを選ぶ方法
今回扱う UIFlow2.0用のファームウェアを選ぶには、M5Burner の左にあるメニューで「ATOMS3」を選択してください。
![M5Burner上で選ぶメニュー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/1db675c2-196d-8d15-ee0e-c3cadea15939.png)

### 書き込み時の流れ・操作
ログインした状態で、M5Burner を使った書き込みを行おうとすると、ポートなどを選ぶ画面へ進むことができます。
![ポートなどを選ぶ画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/5c292d23-21d3-26f9-4d81-58c3fd9a8fec.png)

そして、書き込みを行おうとした際、デバイスをアカウントに紐付けることについて、注意書きが出てきます。
![デバイスの紐づけに関する注意メッセージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/584c79dc-c0d0-8e30-677e-37a2882031e3.png)

その後で、デバイスの MACアドレスなどが表示されました。ここでは、自分はデフォルト設定のままで次に進みました。
![デバイスの情報など](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/24c36c55-0c64-bef6-0add-46bf1dc03108.png)

次の画面では、自分が利用する Wi-Fi の設定を行いました。他は、デフォルト設定のままです。
![Wi-Fi設定など](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/bafd7c4a-4b72-5497-2919-eea7a0986838.png)

その後、書き込みが始まり、完了の画面まで進められました。
![書き込み完了画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/4fef578e-aa52-b24d-d9d6-dbc615888aff.png)

ファームウェア書き込み完了後に、ATOMS3 が再度立ち上がると、以下のような画面表示になりました。
![ファームウェア書き込み完了後に再起動した後](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/272f443d-890c-d79e-6d7e-8d2fa294d688.png)

### UIFlow2.0側での操作
上記のファームウェア書き込みが完了したら、次は UIFlow2.0側での操作です。

[UIFlow2.0 のサイト](https://uiflow2.m5stack.com/)を開きます。
![UIFlow2.0](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/c501b44e-0823-e553-a092-686c2540157d.png)
この画面で、画面右下にある「Select a device」と書かれたボタンを押します。

もし、ログインをしていない場合、ここでログインを求められます。そして、ログイン後だと以下の画面が表示されます。ここで、ファームウェアを書きこんだ ATOMS3 を選択できます。
![デバイスの選択画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/1b112a7b-d695-8648-c8e9-bb2b26d2e80a.png)

また、この画面で以下のように、MACアドレスやトークンを確認することもできるようです。
![MACアドレス・トークンの表示](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/a4139402-9ac2-8a78-16df-1dbab44a0e93.png)

あとは、プログラムを作ってから、UIFlow2.0 の画面右下にある「Run」ボタンで実行をすると、冒頭に掲載した以下のツイートのように、プログラムをデバイスで実行することができます。

https://twitter.com/youtoy/status/1614066789448822784
さくらVPSでSinatra(＋mysql)を使って簡単なWEBアプリを作る



## ■環境

- さくらVPS（Cent OS７）
- Nginx
- MySQL (5.7)
- Sinatra (2.2.0)

## ■ゴール

Rubyで書いた簡単なTodoアプリを Nginxで動かしてみたいと思います。

## ■サーバの準備と Nginxのインストール

- サーバのプログラムをアップデートし、 Nginx等をインストールする準備をする。

```jsx
  sudo yum update
```

- Nginxをインストールする。

```jsx
  sudo yum install nginx
```

- ブラウザからログインし、Cent OSトップページが表示されることを確認する。

　　※ さくらVPSのコンパネにログインすればIPアドレスを確認できます。
![スクリーンショット 2023-01-15 21.34.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092884/12d463c0-4208-abdc-702a-327ce5e40ffa.png)


- トップページのHTMLは /usr/share/nginx/html/index.html に記載されており、このディレクトリ以下のHTMLを Nginxがブラウザに返してくれます。

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>タスク管理アプリケーション</title>
  </head>
  <body>
    <h1>タスク管理アプリケーション</h1>
    <input id="task-title-input" type="text" />
    <button id="task-add-button">追加</button>
    <h2>タスク一覧</h2>
    <table>
      <thead>
	<tr>
	  <th>タイトル</th>
	  <th>作成日時</th>
	</tr>
      </thead>
      <tbody id="tasks-table-body"></tbody>
    </table>
    <script src="main.js"></script>
    <p id="message"></p>
  </body>
</html>
```

ここまでで静的なHTMLは完成しています。

## ■動的なJavaScriptファイル作成

- 動的コンテンツ作成のため、以下のJavaScriptファイルを作成します。

/usr/share/nginx/html/main.js

```jsx
const tasksTableBodyElement = document.getElementById('tasks-table-body')
const taskTitleInputElement = document.getElementById('task-title-input')
const taskAddButtonElement = document.getElementById('task-add-button')

async function loadTasks() {
	const response = await fetch('/api/tasks')
	const responseBody = await response.json()
	console.log(responseBody)

	const tasks =responseBody.tasks

	while(tasksTableBodyElement.firstChild) {
		tasksTableBodyElement.removeChild(tasksTableBodyElement.firstChild)
	}

	tasks.forEach((task) => {
		const titleTdElement = document.createElement('td')
		titleTdElement.innerText = task.title

		const createdAtTdElement = document.createElement('td')
		createdAtTdElement.innerText = task.createdAt

		const trElement = document.createElement('tr')
		trElement.appendChild(titleTdElement)
		trElement.appendChild(createdAtTdElement)

		tasksTableBodyElement.appendChild(trElement)
	})
}

async function registerTask() {
	const title = taskTitleInputElement.value
	console.log(title)
	const requestBody = {
		title: title
	}

	await fetch('/api/tasks', {
		method: 'POST',
		body: JSON.stringify(requestBody)
	})

	await loadTasks()
}

async function main() {
	taskAddButtonElement.addEventListener('click', registerTask)
	await loadTasks()
}
```

![スクリーンショット 2023-01-15 21.29.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092884/085cc1c9-a40d-1e46-e952-001ce4f92f6e.png)


- 以上で簡単なTodoアプリ作成完了です。トップページの入力欄にタスクを追加することで画面にタスク名・登録時間を表示できます。現状ではDBMSを導入していないことから、ブラウザのリロードのたびにタスクが初期化されてしまうので、次回MySQLの導入から記載していきます。

## ■引用

[MySQLの設定（CentOS 7）](https://www.sakura-vps.net/centos7-setting-list/mysql-settings-for-sakura-vps-centos7/)

[さくらのVPSにRubyをインストール - Qiita](https://qiita.com/d0ne1s/items/fd1c19154a48edef9af2)
loss, val-loss が nan になり、交差エントロピー関数の log の引数に 1e-7 を足しても nan が直らなかった問題。

　私は、hugging face の Whisper の fine tuning を使ってみている傍ら、

https://tensorflow.classcat.com/2022/06/27/keras-2-examples-audio-transformer-asr/

のページのプログラムを日本語の単語を予測するように改修して精度を上げられないか試しています。そんな中で、学習させると、loss と val-loss が nan になってしまいました。

　交差エントロピーとは、

```python
def cross_entropy_error(y, t):
    delta = 1e-7
    return -np.sum(t * np.log(y + delta))
```

です。y = 0 だと交差エントロピーが nan になるので、delta = 1e-7 を足してやれば nan はでなくなると、ネットには書いてあり、最初、それに従って対応しました。しかし、nan が直らない。

　結局、原因は、y 自体が nan になっていることでした。上記ペーでは、

```python
y = model.predict( x )
```

で y を予測していたのですが、x を作るのに

```python
audio = tf.io.read_file(path)
audio, _ = tf.audio.decode_wav(audio, 1)
audio = tf.squeeze(audio, axis=-1)
stfts = tf.signal.stft(audio, frame_length=200, frame_step=80, fft_length=256)
x = tf.math.pow(tf.abs(stfts), 0.5)
# normalisation
means = tf.math.reduce_mean(x, 1, keepdims=True)
stddevs = tf.math.reduce_std(x, 1, keepdims=True)
x = (x - means) / stddevs                
```

としていて、stddevs が 0 になり、0割を起こして、x が nan になり、y が nan になっていたようです。上記部分を

```python
audio = tf.io.read_file(path)
audio, _ = tf.audio.decode_wav(audio, 1)
audio = tf.squeeze(audio, axis=-1)
stfts = tf.signal.stft(audio, frame_length=400, frame_step=160, fft_length=512)
x = tf.math.pow(tf.abs(stfts), 0.5)
# normalisation
means = tf.math.reduce_mean(x, 1, keepdims=True)
stddevs = tf.math.reduce_std(x, 1, keepdims=True)
tmp = tf.math.equal( stddevs,  0 )                                #修正部分
stddevs += tf.cast( tmp, dtype=tf.float32)  * 1e-12               #修正部分
x = (x - means) / stddevs
```

のように直したら、loss も val-loss も正常値が表示されました。
Laravel FortifyのレスポンスをJSONで返す方法

## 背景
通常、Laravel Fortifyを使用してログインに成功すると、Fortifyはアプリケーションの`fortify.php`内の `home`設定オプションで設定した URI にリダイレクトします。ログイン要求がXHR要求であった場合、200HTTPレスポンスを返します。

ただし**SPAの構成などをとっている場合は、レスポンスをJSON形式で返したい**こともあリます。そんな時に行う設定を備忘録がてら記載していきます。

## FortifyのレスポンスをJSONで返す方法
早速結論ですが、`App\Providers\FortifyServiceProvider.php`内の`register`メソッドに下記コードのように実装します。返すJSONの構造は適宜変更してください。
```php:App\Providers\FortifyServiceProvider.php
use Laravel\Fortify\Contracts\LogoutResponse;

public function register()
{
    $this->app->instance(LogoutResponse::class, new class implements LogoutResponse {
        public function toResponse($request)
        {
            // JSONの構造は適宜変更してください。
            return response()->json([
              'code' => 200,
              'user' => $request->user()
            ]);
        }
    });
}

```
これでログイン成功時にはJSONが返却されるようになりましたが、ログイン済みの状態でAPIを叩いた場合はHOME画面にリダイレクトされてしまうので、以下のように`App/Http/Middleware/RedirectIfAuthenticated.php`のコードを修正します。
```diff_php:App/Http/Middleware/RedirectIfAuthenticated.php
+ use Illuminate\Http\JsonResponse;

class RedirectIfAuthenticated
{
    public function handle(Request $request, Closure $next, ...$guards): JsonResponse
    {
        $guards = empty($guards) ? [null] : $guards;

        foreach ($guards as $guard) {
            if (Auth::guard($guard)->check()) {
-               return redirect(RouteServiceProvider::HOME);
+               return response()->json([
+                   'message' => '既に認証済みです。'
+               ], 200);
            }
        }

        return $next($request);
    }
}

```
これでログイン成功時、ログイン済みの状態でAPIを叩いた場合どちらでもレスポンスにJSONが返却されるようになります。

## 終わりに
簡単ですが、以上になります。
他の詳しい内容は下記Documentにも記載されているので、よければご覧ください。
https://laravel.com/docs/9.x/fortify
Googleプロジェクト管理：プロジェクト計画の価値と構成要素

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/7c79c997-e4e4-7d71-3686-e01b7badaa3c.png" width="800">

# 計画フェーズを開始する

計画フェーズは、プロジェクトのライフサイクルの第二段階です。

計画を立てることは、プロジェクトを成功させるために重要なことです。プロジェクトの大小に関わらず、プランニングは重要です。

プロジェクトを計画する間...

- あなたとチームの他のメンバーは、目標を達成するために必要なプロセスとワークフローを決定し、プロジェクトを成功させる方法について考えをまとめます。
- これまでのプロジェクトの経験を生かすこともあるでしょうが、結果を出すための新しい方法を考えることも臆することはありません。すべてのプロジェクトは異なるので、新しい、異なるアプローチが必要かもしれません。

:::note info
この時期は、検討すべきことが多く、プロジェクトマネージャーにとって難しい時期かもしれません。しかし、重要なことは、プロジェクト計画は最初から完璧である必要はないということです。また、最初に素晴らしい計画を立てたとしても、プロジェクトが進展するにつれて、計画が変更される可能性があります。
:::

# 計画フェーズのメリット

- プロジェクトの全体像を把握するのに役立ちます。
- 目標を達成するために必要な作業を把握することができます。
- 他チーム、請負業者、ベンダーとの努力やタイムラインの調整に役立ちます。
- プロジェクトに影響を与える可能性のあるリスクを特定し、それに備える時間を確保できることです。
    - 例）タイムラインの遅延、重要なチームメンバーの離脱、主要なステークホルダーによるプロジェクトの方向性の変更
- これらのリスクを軽減したり、対処したりするための方法をブレインストーミングする機会も得られます。
- プロジェクトチームの主要メンバーから「賛同」を得ることができます。賛同を得るということは、あなたの計画に対する彼らの支持を得るということです。
- ステークホルダーに対して、チームが詳細な計画を立ててプロジェクトを開始するように配慮していることを示すことができます。
- プロジェクトをゴールまで押し進めるためのチームワークを築きます。計画段階で協力し合うことで、プロジェクトにアサインされたメンバーとは、計画が終わって作業を開始しようとする頃には、強力なチームになっていることでしょう。一緒に計画を立てることで、プロジェクトに関わるすべての関係者の間に共通の理解が生まれます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/e660bd2d-321c-584d-8ec9-ad633a847013.png" width="600">

# 計画フェーズの構成要素

### <font color="MediumVioletRed">スケジュール

基本的にプロジェクトのタイムラインです。開始日、終了日、そしてその間に起こることの日付が含まれます。

### <font color="MediumVioletRed">予算
プロジェクトを完了するために必要な総費用を計上することになります。この総費用は、プロジェクトの各要素にどれだけの費用が必要かを決定するために、内訳を明らかにする必要があります。

### <font color="MediumVioletRed">リスク管理

これは、起こりうる問題を探し出し、そのリスクを軽減するために前もって計画を立てることです。どのようなプロジェクトにもリスクはつきものです。良いプロジェクト計画とは、問題が発生しそうな場所を探すことです。

- スケジュールが狂う可能性があるのはどこか？
- 予算が見積もりを超える可能性があるのはどこか？

これらの質問に対する答えをチームと一緒に考え、発見したことに基づいてリスク管理計画を作成するのです。