OmniAICreator/Qiita-1.07M huggingface dataset:
【husky v7対応】React×TypeScriptの開発環境をcreate-react-appで構築する

## この記事に書いてあること
create-react-appを使った、`React×Typescript`の開発環境構築

## create-react-appとは？
Reactの面倒な開発環境をコマンド一発で作成してくれる機能。
Reactを学習したり、新しいシングルページアプリケーションを作成するときに使います。

Node >= 14.0.0 及び npm >= 5.6 の環境が必要です

```
nodebrew list //nodeのバージョン確認
nodebrew use v16.14.0 //nodeのバージョン切り替え
```

## 各パッケージのバージョン
- React v17.0.2
- React-dom v17.0.2
- TypeScript v5.0.0
- husky v7.0.0
- lint-staged v12.3.7
- prettier v2.6.2

## create-react-appする
下記コマンドで開発環境を構築
```
npx create-react-app app --template typescript
```

バージョン変えたい場合は適当なものへ変更しても可
```
npm i react@17.0.2 react-dom@17.0.2
```

下記コマンドで環境が立ち上がるので確認
```
npm run start
```

## tsconfig.jsonを編集
TypeScriptによる型チェックの設定を編集します。

```json:tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "noImplicitReturns": true,//追記 関数戻り値の型注釈を必須にする
    "noUnusedLocals": true,//追記 使われていない変数を禁止する
    "noUnusedParameters": true,//追記 使われていない引数を禁止する
    "baseUrl": "src",//追記 モジュールのパスが絶対パス指定で場合、基準とするフォルダ
  },
  "include": [
    "src"
  ]
}
```

## コミット時のコード自動整形
下記を利用して、コミット時にコードの自動整形がかかるように設定する

- husky
- lint-staged
- prettier

まず必要なパッケージを以下のコマンドでインストール

```
npm i -D husky lint-staged prettier
```
.prettier.jsを作成する

```javascript:.prettier.js
module.exports = {
    printWidth: 120,
    singleQuote: true,
    semi: false,
}
```

下記コマンドを実行
※huskyの設定方法がv7から変更になったようです。

```
npx husky-init && npm install
```

処理が終わるとpackage.json に以下のような差分ができます。

```json:package.json
{
  "scripts": {
    // ...
    "prepare": "husky install" // 新しく追加
  },
}
```

また`.husky`というディレクトリが作成され、配下にpre-commitというファイルができているので、編集して、プレコミット時にlint-staged が実行されるように設定します。

```
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged //編集
```

次にpackage.jsonに新しくscriptを追記

```json:package.json
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "fix": "npm run format && npm run lint:fix",//追記
    "format": "prettier --write 'src/**/*.{js,jsx,ts,tsx}'",//追記
    "lint:fix": "eslint --fix 'src/**/*.{js,jsx,ts,tsx}'",//追記
    "prepare": "husky install"
  },
```

最後にlint-stagedの設定をして完了です。

```json:package.json
  "lint-staged": {
    "src/**/*.{js,jsx,ts,tsx}": [
      "npm run fix"
    ]
  }
```

## 参考記事
- https://qiita.com/sanogemaru/items/05c2e9381d6ba2d9fccf
- https://zenn.dev/luvmini511/articles/a47b1aa0310d1a
BigQuery Scripting と BigQuery ユーザー定義関数の使い分けメモ

# 結論
- Transaction処理が必要 -> BigQuery Scripting
- そうでないなら、BigQuery ユーザー定義関数を使っておけば間違いない

# BigQuery Scripting
https://cloud.google.com/bigquery/docs/reference/standard-sql/scripting

SQL上で変数定義、IF分岐、LOOP処理などができ、簡易なプログラミングのような処理が書ける。また、トランザクション処理の定義もできる。

BigQuery ユーザー定義関数と比べると

- Transaction処理が定義できる
- 処理が若干シンプルに書ける
- ただし、Scheduled Query や dbt では対応していないので注意

Transaction処理を行いたい場合は、BigQuery Scripting一択.
また、SQLで簡易に表現でき、かつ、Scheduled Queryなどで使う予定がない場合もこちらの方が若干シンプルで使いやすいかも.

# BigQuery ユーザー定義関数(以下UDF)

https://cloud.google.com/bigquery/docs/reference/standard-sql/user-defined-functions?hl=ja-JPFactory

SQLやJavascriptで表現された関数を一時的/永続的に定義できる。

BigQuery Scriptingと比べると

- JavaScriptなどで自由に定義できるためできることが多い
- 一時的な関数定義でもScheduled Queryで使える
- 永続化関数であれば、dbtでも使える
- 永続化関数は別のSQLから使いまわせるのも便利

基本、こちらを使っておけば間違いないと言う感じ。

# 例

SQL実行月の月初の文字列と、当月日数を取得する処理を、BigQuery ScriptingとBigQuery UDFで書いて見る

```sql
# BigQuery Scripting

CREATE TEMP FUNCTION get_begining_of_month_string()
RETURNS STRING
AS (
    FORMAT_DATE('%Y%m%d', DATE(EXTRACT(YEAR FROM CURRENT_DATE()), EXTRACT(MONTH FROM CURRENT_DATE()), 1))
);

CREATE TEMP FUNCTION get_month_dates()
RETURNS INT64
AS (
    DATE_DIFF(
        DATE_ADD(DATE(EXTRACT(YEAR FROM CURRENT_DATE()), EXTRACT(MONTH FROM CURRENT_DATE()), 1), INTERVAL 1 MONTH),
        DATE(EXTRACT(YEAR FROM CURRENT_DATE()), EXTRACT(MONTH FROM CURRENT_DATE()), 1),
        DAY
    )
);

-- SELECT get_begining_of_month_string()
-- SELECT get_month_dates()


# BigQuery UDF

DECLARE current_date DATE DEFAULT CURRENT_DATE();
DECLARE begining_date DATE DEFAULT DATE(EXTRACT(YEAR FROM current_date), EXTRACT(MONTH FROM current_date), 1);
DECLARE begining_date_str STRING DEFAULT FORMAT_DATE('%Y%m%d', begining_date);
DECLARE next_month_begining_date DATE DEFAULT DATE_ADD(begining_date, INTERVAL 1 MONTH);
DECLARE date_diff INT64 DEFAULT DATE_DIFF(next_month_begining_date, begining_date, DAY);

-- SELECT begining_date_str
-- SELECT date_diff

```

個人的にはUDFの方が若干可読性が高いと思っている
Pythonのf文字列（フォーマット済み文字列リテラル）の使い方

前回[Pythonでドラクエ風対戦ゲームを作ってみた](https://qiita.com/TP-faure/items/4c48fa919522aec0ae6d)という記事を書いたところ、早速アドバイスを頂き、分からないことだらけだったので皆様と共有したいと思います。まずはf文字列から！

# f文字列とは

Python3.6から追加された、文字列の中に書式を指定して数値などの値を埋め込めるようにしたもの。f'{値:書式}'という具合に、文頭に「f」をつけてクウォートで文字列を囲み、その文字列の中に波括弧で変数名や式を入れられるようになった。

以前は
```python
name = '太郎'
print('私の名前は' + name + 'です')
```

あるいはformat()メソッドを使って
```python
name = '太郎'
print('私の名前は{}です'.format(name))
```

としていたところをf文字列を使うと
```python
name = '太郎'
print(f'私の名前は{name}です')
```
こんな感じ！スマートに書けますね！


f文字列はデフォルトで文字列を返すので変数に数字をいれてもOK！
```python
age = 20
print(f'私の年齢は{age}歳です')
#出力
私の年齢は20歳です
```

# 式やメソッドも使える
波括弧の中に式を入れると、その結果を出力してくれます。
```python
f'1 + 1 + 2 + 3 + 5 + 8 = {1 + 1 + 2 + 3 + 5 + 8}'
#出力
'1 + 1 + 2 + 3 + 5 + 8 = 20'
```

また、メソッドも使うことができます。
```python
name = 'taro'
print(f'{name}を大文字にすると{name.upper()}です')
#出力
taroを大文字にするとTAROです
```


# 書式を指定する
f文字列はf'{値:書式}で書式を指定することができます。

- 数字にカンマを入れる　f'{値:,}'
```python
number = 3628800
f'{number:,}'
#出力
'3,628,800'
```

- 数字に＋符号をつける f'{値:+}'
```python
x = 300 
f'{x:+}'
#出力
'+300'
```

- 小数点の桁数を指定する f'{値:.(桁数)f}'
桁数の前のドットを忘れずに。
```python
pi = 3.141592653589793238462643383279502884197169399375
print(f'{pi:.2f}')
print(f'{pi:.10f}')
#出力
3.14
3.1415926536
```

- 日付の表示　f'{値:%Y%m%d}'
```python
import datetime
birthday = datetime.date(2020, 1, 3)
print(f'{birthday:%Y%m%d}')
print(f'{birthday:%Y年%m月%d日}')
print(f'{birthday:%Y/%m/%d}')
print(f'{birthday:%Y.%m.%d.}')
#出力
20200103
2020年01月03日
2020/01/03
2020.01.03.
```

- 空白を作る　f'{値:< or > or ^ (数字）}'
右に空白
```python
word = 'pyton'
print(f'[{word:<10}]')
print(f'[{word:<30}]')
＃出力
[pyton     ]
[pyton                         ]
```
左に空白
```python
print(f'[{word:>15}]')
print(f'[{word:>20}]')
#出力
[          pyton]
[               pyton]
```
両端に空白
```python
print(f'[{word:>20}]')
print(f'[{word:^25}]')
#出力
[  pyton  ]
[          pyton          ]
```

---
この他にもf文字列の書式には色々あるようです。表示したいものがあったら調べてみるといいですね。
以上、f文字列についてでした！
TypeScriptとTerraform、CDK、CDK for Terraformの関係性についての整理

Terraform、CDK、CDK for Terraformの3つの特徴を整理するためのメモです。間違っていたら教えて下さい。

## IaCとは

- IaC(Infrastructure as Code)は、インフラをコードで定義するアプローチ全般を指す言葉
- 従来:
    - 構成や手順は文書で定義
    - 文書を参照し、手動で構築
- IaC:
    - プログラミング言語やドメイン特化言語(DSL)で構成や手順を定義
    - 自動で構築

## Terraformとは

- IaCを実現するインフラ構成ツール
- HCLという宣言型のドメイン特化言語でインフラを定義できる
- AWS、Azure、GCPをはじめ様々な1,000を超えるプラットフォームに対応している
- 競合: Pulumi

```hcl:Terraformのサンプルコード
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }

  required_version = ">= 0.14.9"
}

provider "aws" {
  profile = "default"
  region  = "us-west-2"
}

resource "aws_instance" "app_server" {
  ami           = "ami-830c94e3"
  instance_type = "t2.micro"

  tags = {
    Name = "ExampleAppServerInstance"
  }
}
```

## CDKとは

- CDK(Cloud Development Kit)は、IaCを実現するインフラ構成ツール
- TypeScript、Python、Javaなどのプログラミング言語で、インフラを定義できる
- AWSにのみ対応している
- 競合: CloudFormation

```ts:CDKのサンプルコード
import * as cdk from 'aws-cdk-lib';
import { aws_s3 as s3 } from 'aws-cdk-lib';

export class HelloCdkStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    new s3.Bucket(this, 'MyFirstBucket', {
      versioned: true
    });
  }
}
```

## CDK for Terraform

- CDK for Terraform(CDKTF)は、IaCを実現するインフラ構成ツール
- TypeScript、Python、Javaなどのプログラミング言語で、インフラを定義できる
- HCLを書かずにTerraformを使えるようにするもの
    - CDKの書き味の良さと、Terraformのマルチプラットフォーム対応のいいとこどりができる
- 競合: Pulumi

```ts:CDKTFのサンプルコード
import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";
import {
  GoogleProvider,
  ComputeNetwork,
  ComputeInstance,
} from "./.gen/providers/google";
import * as path from "path";
import * as fs from "fs";

class MyStack extends TerraformStack {
  constructor(scope: Construct, name: string) {
    super(scope, name);

    const credentialsPath = path.join(process.cwd(), "google.json");
    const credentials = fs.existsSync(credentialsPath)
      ? fs.readFileSync(credentialsPath).toString()
      : "{}";

    new GoogleProvider(this, "Google", {
      region: "us-central1",
      zone: "us-central1-c",
      project: "terraform-cdk",
      credentials,
    });

    const network = new ComputeNetwork(this, "Network", {
      name: "cdktf-network",
    });

    new ComputeInstance(this, "ComputeInstance", {
      name: "cdktf-instance",
      machineType: "f1-micro",
      bootDisk: {
        initializeParams: {
          image: "debian-cloud/debian-9",
        },
      },

      networkInterface: [
        {
          network: network.name,
        },
      ],
      tags: ["web", "dev"],
      dependsOn: [network],
    });
  }
}

const app = new App();
new MyStack(app, "typescript-gcp");
app.synth();
```

## 所感

- TypeScriptでIaCするなら、次のいずれかになる
    - CDK
    - Pulumi
    - CDK for Terraform
- CDKはAWS専用なので、マルチプラットフォームを扱うなら選択肢から除外される
- PulumiとCDK for Terraformだと、どっちでも良さそうだが、PulumiよりTerraformのほうがエコシステムが大きそうなので、CDKTFが魅力的
Linuxコマンド

# 誰でも使えるLinuxコマンド集
* Linuxコマンドは勉強が必要ですが、誰でも使えるコマンドを紹介したいと思います。

## 基礎編

#### 過去入力されたコマンド履歴を見る

`一番おすすめコマンドです。このコマンドがおすすめ度1位です。他のメンバーがどんなコマンドを使うのかの勉強にもなります。`

```bash
$ history
```

#### redhatバージョン確認

```bash
cat /etc/redhat-release
```

#### 容量確認（/配下の全ディレクトリ）

```bash
$ du --max-depth=1 -h /

★容量順で並び替えたい時：
$ du --max-depth=1 -h / | sort -h
```


```bash
$ df -f

$ du -sh /*
$ du -sm /*


[root@ebidserver001 ~]# df -h
Filesystem            Size  Used Avail Use% マウント位置
/dev/sda2              40G   32G  6.2G  84% /
tmpfs                 7.3G     0  7.3G   0% /dev/shm
/dev/sda1             248M   37M  199M  16% /boot
```

#### ファイルの一覧を出力する

```bash
$ find /var/opt/FJSVj2ee/deployment/ijserver/WUxxxxxx/apps/sample.war -type f > fileListLnx.txt
```

#### フォルダーのみ一覧を出力する＋3階層まで表示

```bash
 find -maxdepth 3 -type d
　　　　　👆3階層　 👆フォルダーのみ
```

#### プロセス起動確認

```bash
$ ps aux | grep Daemon　　　　　　　　　　　　　　Daemonプロセス起動確認
$ ps aux | grep Daemon --color=auto　　　　　　　　　　👆プラス赤文字表示オプション
```

#### メモリ確認（利用率、残）

```bash
$ free -m　　　　　　　　メガ単位で

             total       used       free     shared    buffers     cached
Mem:         14942      11488       3453          0        204        721
-/+ buffers/cache:      10562       4379
Swap:         1999        268       1731
```

#### CPU確認（利用率、残）

```bash
$ top

Tasks: 257 total,   1 running, 256 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.7%us,  0.6%sy,  0.0%ni, 97.8%id,  1.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  15301204k total, 11766628k used,  3534576k free,   209784k buffers
Swap:  2047992k total,   274432k used,  1773560k free,   740632k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                    
 4477 root      20   0 15168 1376  956 R  0.7  0.0   0:00.05 top                                                                                                                         
24204 root      20   0 3086m 280m  10m S  0.7  1.9  19:11.13 java                                                                                                                        
 2642 root      20   0  122m 3516 3380 S  0.3  0.0  26:09.69 extp_momo                                                                                                                   
 2775 root      20   0 2480m  65m 5712 S  0.3  0.4  19:07.24 java                                                                                                                        
 6363 root      20   0 2661m  37m 8592 S  0.3  0.2  16:40.98 java                                                                                                                        
 7981 root      20   0 3522m 580m  11m S  0.3  3.9  15:29.05 java                                                                                                                        
 8289 root      20   0 2870m 387m  10m S  0.3  2.6  12:47.52 java       
```

#### fileの検索

```
find . -name "*.gif"
```

#### fileの検索結果に追加のコマンドの実行

```
find . -name "*.gif" -exec file {} \;

※git,GIFの大文字小文字両方検索は
find . -iname "*.gif" -exec file {} \;
```
Azure Key Vaultのアクセスポリシー "Azure Databricks"は何を指すか

## はじめに

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1022607/7aafd1a4-d363-d393-3b94-20357b52da01.png)

`Azure Databricks` で **[Azure Key Vault Backed Scope](https://docs.microsoft.com/ja-jp/azure/databricks/security/secrets/secret-scopes)** を使うときに `Key Vault` のアクセスポリシーをみると `Azure Databricks` となっていました。
これを見る限り、 `Azure Databricks` はすべて許可しているように見えます。

実際、個別の `Azure Databricks` ワークスペースを指定することはできないようで、
例えば `dbw-abc` みたいな名前の `Azure Databricks` ワークスペースのみにアクセスポリシーを付与することはできません。

だとすると、 アクセスポリシーに `Azure Databricks` があれば、誰でも `Azure Key Vault Backed Scope` を設定できてしまうのか気になりました。

## 結論：`Key Vault` の権限があれば、誰でも `Azure Key Vault Backed Scope` を設定できる

`Azure Key Vault` と `Azure Databricks` の両方にアクセスできる人に限って `Azure Key Vault Backed Scope` の設定ができるようです。
`Azure Key Vault` にアクセスできない人は `Azure Databricks` からスコープ設定しようとしても、エラーになります。

ちなみに、 `Azure Key Vault Backed Scope` をすでに設定済みの場合は、
`Azure Key Vault` にアクセスできない人でも `dbutils.secrets.get()` コマンドでシークレットを利用できるようになります

| `Azure Key Vault` の権限を持っている | `Azure Databricks` にログインできる | `Azure Key Vault Backed Scope` を設定できるか |
|:-----------:|:------------:|:------------:|
| YES       | YES       | **YES**         |
| NO     | YES      | **NO**       |
Apache SparkとHadoop：力を合わせて

[Apache Spark and Hadoop HDFS: Working Together](https://databricks.com/blog/2014/01/21/spark-and-hadoop.html)の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

:::note
2014年の記事です。
:::

我々はよく、[Apache Spark](https://spark.incubator.apache.org/)がどのように[Hadoopのエコシステム](https://databricks.com/jp/glossary/hadoop-ecosystem)に収まるのか、既存のHadoopクラスターでどのようにSparkを実行できるのかという質問をいただきます。この記事では、これらの質問に回答します。

最初に、SparkはHadoopスタックの置き換えでなく、*エンハンス*することを目的としています。当初から、Sparkは[HDFS](https://databricks.com/jp/glossary/hadoop-distributed-file-system-hdfs)や、HBaseやAmazonのS3など他のストレージシステムとデータを読み書きできるように設計されていました。Hadoopのユーザーは、SparkとHadoopの[MapReduce](https://databricks.com/jp/glossary/mapreduce)、HBaseや他のビッグデータプラットフォームを組み合わせることで、自身の処理能力を向上させることができます。

次に、我々は*全てのHadoopユーザー*が、Sparkの能力を可能な限り簡単に活用できるようにすることにフォーカスし続けています。Hadoop 1.xあるいはHadoop 2.0 (YARN)を実行していようが、[Hadoopクラスター](https://databricks.com/jp/glossary/hadoop-cluster)を設定できる管理権限を持っていようが持っていまいが、Sparkを実行する方法が存在します！特に、HadoopクラスターにSparkをデプロイする方法は3つ存在します。スタンドアローン、YARN、そしてSIMRです。
![](https://databricks.com/wp-content/uploads/2014/01/SparkHadoop.png)

**スタンドアローンデプロイメント**: スタンドアローンデプロイメントでは、Hadoopクラスターのマシンの一部あるいは全部のリソースを静的に割り当てることができ、SparkとHadoop MRを同居させて実行することができます。ユーザーはHDFSデータに対して任意のSparkジョブを実行することができます。このシンプルさは、多くのHadoop 1.xユーザーに対するデプロイメントの選択肢となります。

**[Hadoop Yarn](https://hadoop.apache.org/docs/current2/hadoop-yarn/hadoop-yarn-site/YARN.html)デプロイメント**: [Hadoop Yarn](https://hadoop.apache.org/docs/current2/hadoop-yarn/hadoop-yarn-site/YARN.html)をデプロイしている、あるいはこれからデプロイしようとしているHadoopユーザーは、事前インストールや管理者アクセスなしにシンプルにYARN上でSparkを実行することができます。これによって、ユーザーは容易にSparkを自身のHadoopスタックにインテグレーションし、Sparkのフルパワー、その他のSparkで動作するコンポーネントを活用することができます。

**Spark In MapReduce([SIMR](https://databricks.com/blog/2014/01/01/simr.html))**: まだYARNを実行していないHadoopユーザーに対して、スタンドアローンのデプロイメントに加えて、MapReduce内でSparkジョブを起動するSIMRを使うという別のオプションを提供します。SIMRを用いることで、ユーザーはSparkを用いた実験を開始することができ、ダウンロードした後の数分でシェルを使用することができます！これは、デプロイメントの障壁を劇的に引き下げ、誰でもSparkで遊ぶことができるようになります。

# 他のシステムとの相互運用性

SparkはHadoopとだけではなく、他の人気のあるビッグデータテクノロジーと相互運用することができます。

- [**Apache Hive**](https://hive.apache.org/): [Shark](https://github.com/amplab/shark/wiki)を通じて、Sparkは[Apache Hive](https://databricks.com/glossary/apache-hive)のユーザーがクエリーを変更することなしに、より高速にクエリーを実行することが可能となります。HiveはHadoop上で動作する人気のある[データウェアハウス](https://databricks.com/jp/glossary/data-warehouse)ソリューションですが、SharkはHadoopではなくSpark上でHiveフレームワークをどうさせるためのシステムです。結果として、Sharkは入力データがメモリーに収まる際はHiveのクエリーを100倍高速にし、入力データがディスクに格納されている場合も10倍高速にします。
- [**AWS EC2**](https://aws.amazon.com/): ユーザーは、Sparkに同梱されているスクリプトあるいはAmazonのElastic MapReduce上に[ホストされているSpark、Shark](https://aws.amazon.com/articles/run-spark-and-spark-sql-on-amazon-elastic-mapreduce/)を用いて、容易にAmazon EC2の上でSpark(とShark)を実行することができます。
- [**Apache Mesos**](https://mesos.apache.org/): Sparkは、[MPI](https://www.mcs.anl.gov/research/projects/mpi/)とHadoopを含む分散アプリケーション間での効率的なリソース分類を提供するクラスターマネージャシステムであるMesos上で動作します。Mesosは、Sparkジョブの実行時におけるクラスターのアイドルリソースを同的に活用するために、*きめ細かい*共有を実現します。これによって、特に長時間実行するSparkジョブにおいては劇的な性能改善につながります。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
HerokuでMattermostを使う方法

# Mattermost導入方法

1. herokuアカウントを作成
    - [Heroku](https://signup.heroku.com/login?redirect-url=https%3A%2F%2Fid.heroku.com%2Foauth%2Fauthorize%3Fclient_id%3Dd2ef2b24-e72c-4adf-8506-28db2218547d%26response_type%3Dcode%26scope%3Dglobal%252Cplatform%26state%3DSFMyNTY.g2gDbQAAAHhodHRwczovL2Rhc2hib2FyZC5oZXJva3UuY29tL2F1dGgvaGVyb2t1L2NhbGxiYWNrP3N0YXRlPTU0YWQyNDMwOTkxYzM0ZGNjOTI4NTY1OWU0NmRmMmUxNjZkNzIwNzc5ZDdhOWJhYmQ1MWIyNTMyNTdmYjJhNzZuBgAYFVO-fgFiAAFRgA.120W6AasxtnBONrJEyVG64zrQf3gtXWKmG5TEnWAEt8)
2. 以下URLにアクセス
    - URL：https://heroku.com/deploy?template=https://github.com/mattermost/mattermost-heroku
3. 「App name」に任意の名前を入力し、「Deploy app」ボタンを押下する。
![matter01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/ad9dc321-d943-8668-124f-1c7d37aa023c.png)
![matter02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/a194f837-827c-3100-714f-def2a73ccc7a.png)
4. 「Deploy to Heroku」と表示されれば成功。
![matter03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/995b0931-055d-f5b7-b31c-f219757ad6dd.png)
5. 「View」ボタンからサイトに遷移し、設定を行う。
![matter04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/368216f9-613e-1bb7-4300-06a8dba252b4.png)
6. 「Create a team」を押下する。
![matter05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/9014dd09-1728-212d-51f1-9166adcc68db.png)
7. 「Team Name」を入力し、「Next」ボタンを押下する。
![matter06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/3d109ff4-c78b-8a95-5ed2-2c603bc29906.png)
8. 「Team URL」を入力し、「Finish」ボタンを押下する。
![matter07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/9f490cf8-3523-11a9-43c4-6dd760c0c53b.png)
9. 以下の画像のページが表示されれば成功。
![matter08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/b44a4c56-b12b-c7ec-7720-e45828e5b941.png)

# Mattermost日本語化
1. `Account Settings` を開く。
![matter09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/6db6f651-65c5-d82b-1e6b-4942fe83b7b8.png)
2. `Display > Language` から　`日本語` を選択し、 `Save` を押下する。
![matter10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/bf6dc772-7a6d-5cbf-bf54-ad1dd0b30099.png)
Zoomで待機室をずっと無効化して、ホストの許可なしで入室できるようにする

ホストがブラウザ版の設定で待機室をオフにすればOK。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/6d7e8542-7021-0f5d-8f4b-80d1372361ae.png)


https://us02web.zoom.us/profile/setting











<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
E: Unable to locate packageの解決方法 on Linux


# はじめに
先日、Windows11にてLinuxを使おうと思い、WSL（Windows Subsystem for Linux）をインストールした。WSLとは、Windows上でもLinuxを使えるようにする代物だ。
無事インストールが完了し、oktetaをインストールしようとした。しかし、「E: Unable to locate package」というエラーメッセージが出た。
今回は、その解決方法を書きたいと思う。

## 開発環境
+ Ubuntu 20.04
+ WSL2
# 解決方法
1. aptコマンドをアップデートする
1. aptで再度、インストールする
```
sudo apt update
sudo apt okteta
```
*もしaptのアップデートが反映されない場合は、PCの再起動を行ってほしい
*`sudo`はroot(管理者)ならいらないです。
# 追記
初めてQiitaで記事を書きました。とってもいい経験になったと思います。至らないところも多かったと思います。もし、不備等があればお知らせください m(_ _)m
# 参考文献
[WSLのインストール方法(windows10以上がおすすめ)](https://docs.microsoft.com/en-us/windows/wsl/install)
PlayCanvasでカーブを作る

### new pc.Curveを利用する
https://developer.playcanvas.com/en/api/pc.Curve.html

### 使用例
##### 1. new pc.Curve([time, value....])としてカーブを定義

```javascript
this.curve =  new pc.Curve([
  0, 0,        // At 0 time, value of 0
  0.33, 2,     // At 0.33 time, value of 2
  0.66, 2.6,   // At 0.66 time, value of 2.6
  1, 3         // At 1 time, value of 3
]);
```

### 使用例（ライトの強さを変更する）

##### curve.value(time)にて値を取得します。

```javascript
const AnimationLight= pc.createScript('animation-light');

AnimationLight.prototype.initialize = function () {
    this.time = 0;
    this.curve = new pc.Curve([
        0, 1,
        0.5, 2,
        1, 1
    ]);
};

AnimationLight.prototype.update = function (dt) {
    if (this.time < 1) {
        this.entity.light.intensity = this.curve.value(this.time);
        this.time += dt;
    } else {
        this.time = 0;
    }
};

```
iOS開発者に教えたいAndroidの複数バージョンサポート開発手法

# iOS側の問題

複数バージョンをサポートしているアプリにおいて、
最新機能を実装する場合、以下の問題が常々発生します。

* APIの仕様が新バージョンでは異なる
* 旧バージョンのデバイスでは、最新バージョンの機能を呼び出せない

従ってiOS開発では、バージョン毎にコード分けをする必要が度々発生します。

```swift
if #available(iOS 15, *) {
    print("このコードはiOSバージョンが15以降のデバイスのみ動作する")
} 
```

## Androidにおける複数バージョン対応方法

Androidでは、大きく2つのライブラリーに別れます。

* 標準SDK - Android OSにアクセスするためのライブラリー
* Jetpack - 外部ライブラリーとして用意

実は現在主要な機能は、Android OS側ではなく、**Jetpack(外部ライブラリー)** として配布されています。

つまり最新機能は、**アプリ側に組み込んで開発する** といったことが可能になります。

この主要な機能には、Androidの根幹を成す `Activity` や `Fragment` だけでなく、以下のような最新のUIコンポーネントが用意されています。

* Navigation - UINavigationControllerに相当
* Toolbar - マテリアル対応されたツールバー
* RecyclerView - UICollectionViewに相当
* ViewPager2 - UIPageViewController

さらに、iOSのCoreDataに相当するライブラリーも外部ライブラリー(room)として用意されています。

そしてこの **Jetpack** の大きな特徴の一つとして、低いバージョンでも動作するといった **下位互換性** があります。
(これは前身のSupportライブラリーがその役割であったため)

従ってAndroidでは、アプリが対応する全てのバージョンにおいて、最新機能を提供できるということが可能になっています。

外部ライブラリーは、開発中にも常に更新されるため、不具合などは、OSのアップデートを待たなくても良いというメリットもあります。

# まとめ

Androidにおける複数バージョン対応方法

* 最新機能は外部ライブラリーとして用意
* 下位互換性を持っている
* 不具合はOSのアップデートを待つ必要なく、外部ライブラリーのバージョンを上げることで可能
* アプリの容量が大きくなる
オブザーバーパターンとは

## オブザーバーとは
OOPの代表的なデザインパターンの一つで、
- 一つの観測対象者オブジェクトと一つもしくは複数の観測者オブジェクトがある
- 観測対象者が観測者全員に通知を送ることができる
- 観測者が増えても既存のコード（観測対象者+観測者）を修正しなくてもいい
というもの。

よくある「イベント」もこのパターンで実装されているらしい。

## 埋め込み方法

### 観測者の登録
まず、観測対象者が観測者を把握していないといけないので、以下の`addSubscriber`メソッドのようなパブリックメソッドを用意しておく。観測者はそれを利用して観測対象者に自分を登録してもらう。（観測者のリストは設定ファイル等に保存しておく。）

![スクリーンショット 2022-04-05 7.37.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253501/9df535f3-194a-c2c6-05cb-c25b46614d6d.png)

### 通知

観測者に以下の`update`メソッドのようなパブリックメソッドを用意しておく。通知するタイミングで観測対象者がループ処理などを使い全ての観測者の`update`を呼び出す。観測者は渡された観測対象者のインスタンスから必要な情報を取って各々必要な処理を行う。
![スクリーンショット 2022-04-05 7.40.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253501/67e7d116-8565-9d76-9ae4-99a64e4c2dde.png)

重要なのは観測者が増えても`notifySubscribers`に変更が無いように実装すること（設定ファイルからサブスクライバーのIDを読み込む→ループ処理 等）。もちろん`update`は無くてはならないのでインターフェースに書いておく

## 参考
めちゃめちゃわかりやすかった
https://refactoring.guru/design-patterns/observer
PowerShellによるGraph APIからのデータ取得

# 0.Intro
さくっとGraph APIからデータを抜きたい場面はしばしばあります。ただ認証の部分であったりとか、ページングがあったりとか手間も多かったりします。
ですのでテンプレとして使えるコードを作成してみました。以下はTeamsのあるチームのメンバー一覧を取得するものです。
前提としてAzureADにアプリ登録があること、且つアプリには適切な権限が付与されていることが必要です。

ポイントはページングの処理です。次ページが存在する場合は **@odata.nextLink** に次ページへのリンクが入っています。更に次のページには…と続くので無くなるまでリンクを辿り、それぞれを配列に入れていきます。
最後まで取得しリンクが全て揃ったら順にGraph APIを叩いていき結果を抽出します。

# 1.実装
```
Import-Module adal.ps

#Parameters
$clientId = <クライアントID>
$redirectUri = "myapp://XXXXX" #登録しているアプリのリダイレクト URI
$resourceUrl = "https://graph.microsoft.com"
$authority = "https://login.microsoftonline.com/common"

$response = Get-ADALToken -Resource $resourceUrl -ClientId $clientId -RedirectUri $redirectUri -Authority $authority -PromptBehavior:Always
$accessToken = $response.AccessToken

$links = @()
$apiUrl = "https://graph.microsoft.com/v1.0/teams/XXXXXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/members"
$links += $apiUrl #最初のエンドポイントのURLも忘れずに格納
#全ページのリンクを取得
while($true)
{
	$recdetail = Invoke-RestMethod -Headers @{Authorization = "Bearer $accessToken"} -Uri $apiUrl -ContentType 'application/json' -Method Get
	if($recdetail.'@odata.nextLink'.Length -ne 0)
	{
		$apiUrl = $recdetail.'@odata.nextLink'
		$links += $recdetail.'@odata.nextLink'
	}else{
		break;
	}
}

#実データ取得開始
foreach($l in $links){
	$recdetail = Invoke-RestMethod -Headers @{Authorization = "Bearer $accessToken"} -Uri $l -ContentType 'application/json' -Method Get
	foreach($m in $recdetail.value){
	Write-Output ("Name:" + $m.displayName)
	Write-Output ("Email:" + $m.email)
	}
}
```
tkinter.filedialogで取得したパスのセパレータを信用してはいけない

Windowsでのお話です。
tkinter.filedialog.asksaveasfilename()で指定したファイルがあるフォルダを開きたいとします。
直感的に以下のコードを書きます。

```py
from subprocess import Popen
from tkinter.filedialog import asksaveasfilename

file_path = asksaveasfilename()    # D:\github\sample.json を選択する
if file_path:
    Popen(['explorer', '/select,'+file_path])
```
```
#=> PCが開く
```
なんで？？？

```py
print(file_path)
```
```
D:/github/sample.json
```
セパレータがバックスラッシュではなくスラッシュになっている。
```py
from os.path import sep
from subprocess import Popen
from tkinter.filedialog import asksaveasfilename

file_path = asksaveasfilename()    # D:\github\sample.json を選択する
if file_path:
    file_path = file_path.replace('/', sep)    # '/'をプラットフォームのセパレータに置換
    Popen(['explorer', '/select,'+file_path])
```
```
#=> D:\githubが開く
```
ヨシ！
3000人以上のE-commerceユーザーが参加したShoptalkカンファレンスに参加してみた＆これからのブログに関して

どうもimgixのtkanemotoです。
米ラスベガスにて3月27日-30日まで開催されたEcommerceユーザーが集まるShoptalkというカンファレンスに企業スポンサーとして参加してきました。世界各国から総勢3000人を超える参加者がいたとても大きなカンファレンスです。私が初めて企業スポンサーとしてアメリカのカンファレンスに参加した感想を書いていきたいと思います。毎年行われており是非2023年のカンファレンスではみなさまとお会いできることを祈っています。

Shoptalkカンファレンスとは世界中の小売業界の企業が自社にとって有効なテクノロジーとの出会いを求める場で、1on1で気になる企業からお話を聞けるマッチング形式があるのもShoptalkの醍醐味。私が所属するimgixは10社との1on1商談を実施し全てのお客様よりポジティブなコメントを頂きました。商談以外の時間はブースで話かけて頂いた方にimgixの画像、動画ソリューションを紹介しざっくばらんにE-commerceプラットフォーム(salesforce commerce cloud,Magento,shopify,Contentful等）の使用方法、改善方法などに関して会話しました。
![51B61CF1-8CFE-4A0D-9029-27C899C43844_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2592456/ca6b18b2-b4bc-29fe-0c46-36a1ec0374d7.jpeg)
![935C3934-5224-42E3-BC0D-3F13F7251966_1_201_a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2592456/36f57000-df39-0030-8b14-f9988c281d23.jpeg)
![5027749A-9B78-48BE-84B9-574ED57C9276_1_201_a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2592456/8d68e740-a63b-d779-1696-a10596782d46.jpeg)

ShoptalkではGAFAをはじめ、最前線で活躍する多くの企業が参加されテクノロジーだけではなく様々なswagが振る舞われていて、イベント後のパーティーには有名な歌手がステージで歌を歌ったり、お酒や豪華な料理も振る舞われていました。カンファレンスでは日本からきた方々とも複数人会話させて頂き世界各国の方とお話しできる大変貴重で今後に繋がるイベントでした。2023年もスポンサーとして参加する予定なので是非今から繋がりませんか。


今後の私のブログではウェブサイトの効率化、ユーザーの獲得方法など多くの情報をアウトプットしていく予定です。前の記事ではnext-generationと呼ばれるAvifフォーマットについて書かせて頂きました。今後はShoptalkに参加したのでE-commerceユーザー向けに様々なプラットフォームの最大効率使用方法に関して投稿していく予定です。今後ともご閲覧宜しくお願いします：）

それではhave a great day!
LaravelでRoute::resourceでバインディングするモデルのキーを変更する

# 前提とRoute model Bindingとは

ルーティングで`id`などを指定して受け取るのを、Controllerに来た時点でモデルインスタンスを受け取れる

```php
Route::get('{id}', function($id) {
    Post::find($id);
});

// ↓↓↓↓↓↓

Route::get('{photo}', function(Photo $photo) {

});
```

`Route::resource`や`Route::apiResource`というのがあり、これはCRUD系のルートを一括定義してくれる。


|動詞|URI|アクション|ルート名|
|:----|:----|:----|:----|
|GET|	/photos|	index|	photos.index|
|GET|	/photos/create|	create|	photos.create|
|POST|	/photos|	store|	photos.store|
|GET|	/photos/{photo}|	show|	photos.show|
|GET|	/photos/{photo}/edit|	edit|	photos.edit|
|PUT/PATCH|	/photos/{photo}|	update|	photos.update|
|DELETE|	/photos/{photo}|	destroy|	photos.destroy|

※上記はRoute::resourceの定義されるもの

これらは定義されたルートを見るとわかるように、コントローラー側で下記のように記述することで対象のモデルを受け取れる
ルートモデルバインディングは基本的にプライマリーキーで処理される

```php
// PhotoのPKがidなのでidで検索され取得されたモデルが渡ってくる
public function show(Photo $photo)
{

}
```

idで検索されるがカスタマイズもできる

1
```php:web.php
Route::get('/photos/{photo:slug}', function(Photo $photo) {

});
```

2
```php:Photo.php
/**
 * モデルのルートキーの取得
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'slug';
}
```

3
```php:AppServiceProvider.php
public function boot()
{
    Route::bind('photo', function ($value) {
        return Photo::where('slug', $value)->firstOrFail();
    });
}
```

しかし1番目は`Route::resource`、`Route::apiResource`では使えない

２、3番目は`Route::resource`、`Route::apiResource`でも基本的に問題ないが、全体が変更される。
常に指定したバインドされる際にキーが使われる。
例えば、ユーザー側と管理側と分ける場合、どちらも指定したキーでバインドすることを意識する必要がある。


# やりたいこと

1番目のように、ルートごとに明示したキーを使用したい。

# やりかた

scopedを使う。

本来下記のように、ネストしたリソースを定義し子リソースを取得するフィールド指定するときにscopedメソッドを使用します。
そもそもドキュメントにもそのような用途での記述でした
https://laravel.com/docs/9.x/controllers#restful-scoping-resource-routes


```php:web.php
use App\Http\Controllers\PhotoCommentController;

Route::resource('photos.comments', PhotoCommentController::class)->scoped([
    'comment' => 'slug',
]);
```

しかしこれはネストしていなくても使用できます

```php:web.php
use App\Http\Controllers\PhotoCommentController;

Route::resource('photos', PhotoCommentController::class)->scoped([
    'photo' => 'slug',
]);
```

これでこのルートだけは、指定したキーを使用してモデルを取得できるようになりました。
2022/4/5主にITとかセキュリティの記事

「Apache Tomcat」のアップデートが公開 - 「Spring4Shell」対策も
https://www.security-next.com/135438

中小企業の3分の1、直近3年間のセキュ投資ゼロ - 「必要性を感じない」
https://www.security-next.com/135364

WindowsやDell、Trend Micro製品のサイバー攻撃での活発な悪用を確認、更新を(4/1)
https://news.mynavi.jp/techplus/article/20220401-2309288/

Google、3月後半に東欧で行われたサイバー攻撃報告、中国やロシアの攻撃者が暗躍(4/3)
https://news.mynavi.jp/techplus/article/20220403-2309856/

サイバー警察局発足　「深刻化するサイバー犯罪」に重点、対処業務を追加(4/1)
https://www.itmedia.co.jp/news/spv/2204/01/news093.html

備忘録､､､File1　エクセルが開かなくなった(4/3)
https://note.com/comet007/n/n2d00466a0916

東証の売買システム更新、富士通に委託　障害対策仕上げ(4/3)
https://www.nikkei.com/article/DGXZQOUB231910T20C22A3000000/

西暦1996年のインターネット(4/3)
https://www.orangeitems.com/entry/2022/04/03/001148

AxieInfinity、ハッキング後にアップグレードを1週間延期(4/1)
https://nextmoney.jp/?p=49337

QNAP NASに無限ループの脆弱性、アップデート待ち(4/2)
https://gunosy.com/articles/eHryv

Windowsのレジストリなどに見られるGUIDとは？(4/3)
https://ascii.jp/elem/000/004/088/4088189/?rss

JCBA、NFTビジネスのガイドライン改訂──“所有”の説明責任と賭博罪を追記(4/1)
https://www.coindeskjapan.com/145242/

iExecは新しいインターフェース「iExec Portal」を発表(3/31)
https://www.value-press.com/pressrelease/293461

メンバーに10代も、MicrosoftやNVIDIAに侵入した「Lapsus$」が裏をかく手口とは(4/4)
https://xtech.nikkei.com/atcl/nxt/column/18/00001/06701/

IPAがDXの手引書を改訂、変革規模や組織成熟度を高める策を盛り込む(4/4)
https://xtech.nikkei.com/atcl/nxt/news/18/12567/

「時代は変わった」、ITや先端技術と切り離せない経済安保推進法案の中身とは(4/4)
https://xtech.nikkei.com/atcl/nxt/column/18/02014/040100001/

会社支給PCのプライベート利用はNG、「ちょっとだけ」が思わぬトラブルに(4/4)
https://xtech.nikkei.com/atcl/nxt/column/18/02004/040100002/

己を知る「脅威インテリジェンス」でランサムウエア攻撃を防ぐ、竹中工務店の活用法(4/4)
https://xtech.nikkei.com/atcl/nxt/column/18/02007/033100002/

スマホが情報戦争の“武器”、ITリテラシーが戦況を左右する時代に(4/4)
https://xtech.nikkei.com/atcl/nxt/column/18/00065/00559/
【Kotlin】端末UUIDを任意で生成してPreferenceに保存する

# 概要

端末UUIDを端末から取得するのが厳しそうだったのでUUIDを自動生成して`Preference`に保存していくことにしました。
実装時の備忘録になりますが、ベストプラクティスが他にあればコメントいただけますと嬉しいです

https://developer.android.com/guide/topics/ui/settings/use-saved-values?hl=ja

# やり方

```kotlin
import android.os.Bundle
import android.preference.PreferenceManager
import android.webkit.WebView
import androidx.appcompat.app.AppCompatActivity
import java.util.*


class MainActivity : AppCompatActivity() {
    val UUID_KEY_NAME: String = "uuid";
    var uuid: String = "";
    var url: String = "";

    /**
     * preferencesから直近のUUIDを取得する
     */
    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        // 保存した値を取得する
        val preferences = PreferenceManager.getDefaultSharedPreferences(this);

        // Preference 値の読み取り
        var preferencesUuid: String? =
            preferences.getString(UUID_KEY_NAME, UUID.randomUUID().toString());

        // Preferenceになければ自動生成
        uuid = if (preferencesUuid.toString() == "") {
            UUID.randomUUID().toString();
        } else {
            preferencesUuid.toString();
        }

        // 共有環境設定に書き込む
        val editor = preferences.edit();

        // 書き込み後保存する
        editor.putString(UUID_KEY_NAME, uuid.toString()).apply();

        // アクティビティにテキストやボタンといった部品を配置
        setContentView(R.layout.activity_main)
    }

    /**
     * スタッフ一覧画面を表示する
     * 
     */
    override fun onStart() {
        super.onStart()

        // アクティビティのレイアウト XML ファイルに追加
        val webView: WebView = findViewById(R.id.webView)

        // JavaScript を有効にする
        webView.settings.javaScriptEnabled = true

        // URLを読み込む
        webView.loadUrl("http://www.google.co.jp/");
    }
}
```
Unity備忘録 Macのカメラで写した映像を表示する方法

Macのカメラで写した映像をUnity内でリアルタイム表示する方法ですが、
非常に簡単にできたので共有いたします。

適当にクラスを作成し、下記のコードをコピペして下さい。
ここではWebCam.csとしました。
```
using UnityEngine;
using UnityEngine.UI;

public class WebCam : MonoBehaviour {

    [SerializeField] RawImage rawImage;
    WebCamTexture webCamTexture;

    void Start ()  {
        webCamTexture = new WebCamTexture(512, 512, 60);
        rawImage.texture = this.webCamTexture;
        webCamTexture.Play();
    }
}
```

次に、Unityのヒエラルキー上で右クリックメニューから、UI > Raw Imageを選択。
作成されたRawImageにWebCam.csを付けて、
SelializeFieldの空欄にRawImageをクリックアンドドラッグでセットしてください。
![スクリーンショット 2022-04-05 1.42.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604215/68fca9bd-0eb4-6145-8ee6-3b848f9c3219.png)

Unityを実行すると、下記のように映す事ができます。
![スクリーンショット 2022-04-05 1.46.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2604215/59e28cce-df1e-7a70-c8bb-330e06f0f626.png)

WebCam.csでは60fpsで滑らかに撮影するようにしていますが、60→30に変更すると30fpsに設定できます。
Binary Indexed Tree

BITはセグメント木の機能を限定したものであり、実装が簡単でメモリを節約できる
```C++
//数列a(a[0],a[1],…,a[n-1])についての区間和と点更新を扱う
//区間和,点更新,二分探索はO(log{n})で動作する
class BIT {
public:
    //データの長さ
    ll n;

    //データの格納先
    vector<ll> a;//(1の最小bitの桁)個数分の範囲和を持つ

    //コンストラクタ
    BIT(ll n) :n(n), a(n + 1, 0) {}

    //a[i]にxを加算する
    void add(ll i, ll x) {
        i++;
        if (i == 0) return;
        for (ll k = i;k <= n;k += (k & -k)) {//下から上
            a[k] += x;
        }
    }

    //a[i]+a[i+1]+…+a[j]を求める
    ll sum(ll i, ll j) {
        return sum_sub(j) - sum_sub(i - 1);
    }

    //a[0]+a[1]+…+a[i]を求める
    ll sum_sub(ll i) {
        i++;
        ll s = 0;
        if (i == 0) return s;

        for (ll k = i;k > 0;k -= (k & -k)) {//上から下
            s += a[k];
        }
        return s;
    }

    //a[0]+a[1]+…+a[i]>=xとなる最小のiを求める(任意のkでa[k]>=0が必要)
    ll lower_bound(ll x) {
        if (x <= 0) {
            //xが0以下の場合は該当するものなし→0を返す
            return 0;
        }
        else {
            ll i = 0;ll r = 1;
            //最大としてありうる区間の長さを取得する
            //n以下の最小の二乗のべき(BITで管理する数列の区間で最大のもの)を求める
            while (r < n) r = r << 1;
            //区間の長さは調べるごとに半分になる
            for (int len = r;len > 0;len = len >> 1) {
                //その区間を採用する場合
                if (i + len < n && a[i + len] < x) {
                    x -= a[i + len];
                    i += len;
                }
            }
            return i;
        }
    }
};
```
【Android Studio】アプリケーションのタイトルバーを削除・横画面固定する方法

# 概要

Webviewを導入することになったので詰まった箇所を残していきます

今回はAndroidStudioで起動したアプリケーションのタイトルバーの非表示方法と横画面を固定化する方法をまとめます


# アプリケーションのタイトルバーの非表示

https://stackoverflow.com/questions/23708951/android-styles-xml-windownotitle-actionbaractivity

```xml:src/main/res/values/themes.xml
<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style>
        <!--   タイトルバーの退避    -->
        <item name="windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowContentOverlay">@null</item>
    </style>
</resources>
```


# 横画面を固定化する

https://ao-system.net/note/145

以下を追加する

```xml
android:name=".MainActivity"
android:screenOrientation="landscape"
```


```xml:src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:name="android.permission.INTERNET" />
    <application>
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:screenOrientation="landscape"
            >
        </activity>
    </application>
</manifest>
```
基本情報技術者試験対策　23日目

基本情報技術者試験勉強 23日目
-
この記事の目的
-
今年の5月に基本情報技術者試験を合格するために、過去問で間違えた箇所をただまとめる自分のための記事

プロフィール
-
・文系大学の３年生
・ITパスポートは保有
・ウェブアプリやサイト作成を個人で行ったことがある程度
・猫好き

今日の目標
-
午前問題を最低でも30問解く。午後問題を最低でも5問解く。

間違った箇所
-
1、コンパクション
手記屋上の断片化した空き領域をまとめることで、連続した空き領域を作り出すフラグメンテーションを歌唱する

2、マルチプロセッサシステム
多数の演算ユニットの接続形態を動的に切り替える

3、グリッドコンピューティング
多数のPCをネットワークで接続し強調動作させる

4、TDMA(Time Division Multiple Access，時分割多元接続)方式
端末ごとにタイムスロットを決める

5、概念スキーマ
データベースか対象の業務とデータの内容を論理的な構造として記述したもの

6、外部スキーマ
データの利用者からの見方を記述したもの

7、内部スキーマ
データを記憶装置上にどのような形式で格納するかを記述したもの

8、偽装請負
契約上では業務委託の形式をとっているのに、実態は労働者派遣のようになっている状態

9、ECC(Error Check and Correct)
誤り訂正符号としてハミング符号や垂直水平パリティを用いることで、記録内容に発生した誤りを検知・自動訂正できる誤り制御方式

次回
-
次回も引き続き、午前問題を最低30問は解く、その上で、午後問題を10問程度取り組む。


>引用
基本情報技術者試験ドットコム
https://www.fe-siken.com
SAPS/4HANA用語メモ

# SAP、S/4HANA とは
- SAPとは、ドイツに本社を置くソフトウェア会社のSAP社が提供しているERP製品の一つです。
（会計、ロジスティック、人事、生産/プラント/プロジェクト）
- S/4HANA とは、SAP社のインメモリーデータベース「SAP HANA」を標準プラットフォームとするERP製品であり同社においては、「SAP R/3」および「SAP ERP」の後継であり第４世代のERPとして位置付けられています。

# SAP S/4HANAバージョン
(マネージドサービス昇順)
- SAP S/4HANA Any Premise (On premise)
  ①ユーザが自社データセンターにて環境管理
- SAP S/4HANA Any Premise on AWS/GCP/Azure
　①ユーザがパブリッククラウドにて環境管理
- SAP S/4HANA Any Premise on HEC
　①SAPが環境管理
- SAP S/4HANA Cloud Private Edition
　①allows the use of partner templates
　②permits additional customization, including modifications　that alter SAP's core functionality.
- SAP S/4HANA Cloud EX(STE:single tenant version)
　①SaaSモデル：一定程度の最低ユーザー数分の料金を支払う必要があります
　②Can be hosted on HEC or Public Cloud such as aws,azure,gcp
　③ABAP Extension allowed,modifications that alter SAP's existing functionality are not permitted
　④FullERP,SAPの標準プロセスやベストプラクティスを受けながら、少し柔軟性や機能性が必要とするユーザ向け
　⑤including third-party integrations

- SAP S/4HANA Cloud (multi-tenant version or Essentials Edition)
　①Limited ERP
　②SaaSモデル


# そのた
- HEC とは
「HANA Enterprise Cloud」の略。
SAPのデータセンターではなく、AWS/GCPなどクラウドを利用するマネージドクラウドサービスです。

- RISE WITH SAP
RISE with SAP is a comprehensive offering<単一契約> with:
  Cloud ERP for every business need
  Industry next practices and extensibility
  Analytics and business process intelligence
  Outcome-driven services from SAP and our partners

参考リンク：
①https://blogs.sap.com/2020/07/09/difference-between-sap-s-4hana-any-premise-sap-s-4hana-cloud-essentials-and-sap-s-4hana-cloud-extended/
②https://www.techtarget.com/searchsap/tip/Understand-your-S-4HANA-deployment-options
③https://blogs.sap.com/2020/07/09/deciphering-the-world-of-sap-s-4hana/
文系出身ネットワークエンジニアが半年間プログラミングを学んだ結果

## 概要
文系出身のネットワークエンジニアが約半年間プログラミングを学んでみて思ったこと、出来るようになったことを書き連ねた記事です。

### 筆者について
- 文系大学を卒業後、新卒入社した会社で、NW商材(ルータ・スイッチなど)のセールスエンジニア業務を担当していました。（情報系の知識は皆無なので、サーバって何ですか？デスクトップPCのことですよね？というところから始まりました。）
- その後海外で働こうと思い退職したが、コロナ禍で渡航できず、日本でアルバイターをしていました。
- IT業界や技術を習得することが好きなことから、もう一度ネットワークエンジニアへ転職し、現在に至ります。
- 普段はオンプレのサーバ・ネットワーク機器の構築・運用業務などを担当しています。
- 将来は場所・時間・お金の自由度が高いエンジニアとしてご飯を食べていきたいため、約半年前からソフトウェア開発を勉強中です。

### これまで勉強したこと
- Progate/ドットインストール
    - HTML
    - CSS
    - JavaScript
    - Ruby
    - Ruby on Rails
    - SQL
- Railsチュートリアル1周（重めで全然終わらない＆難しいので、やった内容はぼんやりとしか覚えていない。。。）
- Vim/Viエディタ操作
- Git/Github基本知識
- Linux基本コマンド（Linuxコマンドは実務で使用しながら習得しました。1年かかりました汗）
- Markdown記法（下記のサイトがとても参考になりました。）
    - [Markdown記法 チートシート \- Qiita](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
- Web技術基本知識の学習（学習内容は下記記事にまとめています。）
    - [Web技術の基本について \- Qiita](https://qiita.com/yyy_muu/items/0fa5293e099a0fe625ce)
- Web開発の基本の流れ
- Docker基本知識

### 出来るようになったこと
- Vim操作
現職でLinuxサーバを操作するので、dでの行削除や:wq、/で検索などの操作をしたことはありました。
（恥ずかしながら、覚えるのが面倒臭くて矢印キーでカーソル移動していました。）
しかし、Vim操作でソースコードを書ける状態になりたいので、新たにコマンドを調べ、都度使いながら段々活用できるようになってきました。
最初は、この操作するにはどのコマンドだっけ・・・（あ〜矢印キー、マウス使いたい）という状態でしたが、最近はそらで使えるようになってきて嬉しいです。
ex. hjkl移動、^で行頭移動、$で行末移動、ctrl+[でエスケープ、xで1文字削除、uで操作取り消し...

- Git/Github基本操作
pull, clone, 作業ブランチ作成, push, mergeなどの基本コマンド操作を使えるようになりました。
また、これらのコマンドを使って、add->コミット->push->Pull Request->mainブランチにマージといった流れを理解・実行できるようになってきました。

- Web技術の基本理解
Web技術の基本知識の中でも、特にCookieやセッションの役割や概要を理解し、説明できるようになったことが大きな変化だと思います。
これまでは、ブラウザでURLを入力した後に、パケットがどのようにして宛先にたどり着くか？という、ネットワークの部分の知識しかなく、アプリケーションの仕組みはほとんど理解できていませんでした。
学んでみて改めて、サーバ・クライアントがそれぞれ何を行なっているのか？HTTPプロトコルのリクエスト・レスポンスについて理解できるようになったなあ〜と実感します。

- Docker環境構築（簡単な環境ではあるが）
ドキュメントや各種教材を見たり、ぐぐったりしながらではありますが、なんとか一人でDockerfileを書いて簡単な環境構築ができるようになりました。
Docker環境構築をしてみて、一つ一つコマンドを打ってインストールして、間違えてはアンインストールして、ちゃんと消せない・・・というストレスがなくて最高！という感想に尽きます。
現職で使う検証環境は、物理サーバの上にハイパーバイザを載せた仮想マシンのため、そもそもコンテナという概念を理解するのが難しかったです。
しかし、Docker学習を通じてLinux知識の重要性を実感することができ、以前よりLinuxに対する苦手意識が減りました。

### 最後に
2021年10月にプログラミングの学習を始めて、Progateやドットインストール、Railsチュートリアルでの学習までは、これまでの経験や独学でなんとかなりました。

ですが、ポートフォリオを作成して転職活動をすることを考えた時に、ソフトウェア開発のプロでない自分が、今後独学で勉強し続けるのは厳しいと思っていました。そんな時に、たまたまTwitterで[@yudai_on_rails](https://twitter.com/yudai_on_rails)さんをお見かけし、現在は[Happiness Chain](https://qiita.com/organizations/happiness-chain)の生徒としてご指導いただいております。（Twitterのアルゴリズムで本当に偶然tweetをお見かけして、私が将来なりたい姿を実現されていたのでびっくりしたことを覚えています。笑）

本格的なポートフォリオ作成に着手するまでには、まだ時間がかかりそうですが、これからも毎日コツコツ勉強して理想像に着実に近づいて参ります！
他の人が見ても分かるIssueを書くために意識していること

開発の中でバグ報告や機能改善でIssueを書くことはよくあることですが、エンジニアになり始めの頃はどのようにタイトルを決めるのが良いのか、概要はどのように書くと相手に伝わりやすいのか悩みながら書いていました。

試行錯誤していく中で身につけていったこと、普段意識していること、やっていることをまとめてみようと思います。

※前提
・自分が所属、担当している環境ででIssueを書く場合を想定しています
・OSS等でIssueを書く際はテンプレートが指定されている場合もあるためこの限りではありません

## Title
まずはTitleを決める際に意識していることについてです。最初に目に入るものであり、一覧に一番大きく表示されるものなのでTitleを決めることが一番大切だと思っています。

### おすすめしない書き方

#### エラー内容を記載
- 「No method Errorを直す」
- 「〇〇ページのバグを直す」

エンジニアがバグ報告で一番手っ取り早くIssueを作成するには、Titleにエラータイトル、Descriptionにエラー詳細をペーストすることです。しかしこれだけでどんな対応が必要なのか瞬時に判断するのは難しく、読み手に必要以上の手間を与えてしまいます。

#### 内容が抽象的
- 「〇〇ページの改善」
- 「〇〇の追加対応」

Titleが抽象的だと実際にどんなことを行ったのか想像ができず、リンクを押してDescriptionを見てみたら探していたIssueとは全く異なるものだった、ということになってしまいます。

#### 長い
- 「〇〇〇〇に遷移後、×××××になってしまうことが稀にあるため△△△△△△△のロジックを□□□□□に変更したい」

Issue一覧でこのようなTitleがあってもTitleを読むだけで疲れてしまいます。情報をできるだけ書くことは大切ですが、同じ内容であれば一文字でも少ない方が読み手にとって親切です。


### Titleを決める際に意識すること

#### 1. 状態を意識する

そもそもIssueとは「問題、論点」という意味であり、問題や課題を解決させるための機能として命名されています。

私はTitleを下の式が成り立つような命名にするのが良いと考えています。
`このIssueが終わる = Titleの状態になる（またはTitleが解決する）`

機能改善の場合は「〜になる」、バグ報告は「〜ができない」という書き方をまず意識するだけでもこのIssueがどんな対応をしていたのか分かるようになると思います。

#### 2. 一文字でも短く簡潔に
上にも書きましたが同じ情報量であれば一文字でも短い方が読み手は楽になります。タイトルを決める際は一度Titleを決めた後に「もっと短くかけないか？」、「他の言い回しで短く言い換えることはできないか？」を考えるようにしています。

初めは思いつかないこともあるかもしれないですが、文章表現系の本をいくつか読むと言い換え表現が浮かびやすくなります。

言葉ダイエットという本がおすすめです。

https://www.amazon.co.jp/dp/B0836G8ZT1


## Description
次にDescriptionを書く際に意識していることについてです。DescriptionはTitleと比べて文章量が多く、自由度が広いことが書き方に困る原因になります。対処法として、自分なりの型を作ってしまうのがおすすめです。

### おすすめしない書き方

#### URLのみ
Slack等のチャットツールで話した内容がそのまま機能改善のIssueになった場合、Descriptionに会話のURLを貼っておけば情報量としては十分ですが、何度も遷移する手間を取らせてしまいます。
それだけではなく、会話形式の場合情報がまとまっていないことも多く、内容の把握に時間がかかってしまうため会話の内容をDescriptionにまとめ直す方が読み手にとって親切です。

#### タスク完了の定義が曖昧
- 「登録に時間がかかっているので速くする」

このような機能改善の依頼があっても担当者はどのくらい速くなれば改善されたことになるのか分からず、Issue作成者と担当者の間で認識のズレが生じてしまうリスクがあります。
開発を終えて速度が半分になったとしてもIssue作成者は三分の一の速度を求めていた、となると開発工数が余計に増える原因となってしまいます。

#### とにかく書く
要望があった場合に考えていることをとにかく書いてみると、状況を把握している自分自身は文章を読んで理解することができますが、前情報の無い他の人は理解に時間がかかる、または理解できないことがあります。


### Descriptionを決める際に意識すること

#### 1. タスク完了の条件を具体的に書く
- 「現状の半分の速度で更新できるようになる」
- 「複数アカウント作成できるようになる」

タスク完了の条件を書き、またその条件も具体的に書くと認識のズレがなくなります。どちらの例も「〜になる」という文章になってるように、タスク完了の条件とTitleは近いものになることが多いです。

#### 


#### 2. テンプレートを用意する
読みやすいDescriptionを書く一番のコツはテンプレートを用意することです。項目を埋めていくだけで情報が整理されるので長い文章を書くのが苦手でもDescriptionを書きやすくなります。

私は「As-Is/To-Be」分析を参考にしてテンプレートを作成しています。

https://kaizen-penguin.com/asis-tobe-meaning-how-to-use-4303/

テンプレート例
```
### As Is
（今の状態を記載）

### To Be 
（理想の状態を記載。タスク完了の条件にもなる。）

### アクション
（改善のための具体的なアクションを記載）

### 課題
（現状分かっている課題を記載）
```

#### テンプレートは保存しておくと便利

GitHubにはIssueテンプレートを設定する機能があります。

https://docs.github.com/ja/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository

設定しておくとIssue作成時にテンプレートを指定できるのでおすすめです。

私はテンプレートをツールに依存せずに使いたいのでClipyというスニペットアプリにテンプレートを保存していつでもペーストできるようにしています。

https://clipy-app.com

登録、更新も簡単でショートカットですぐに呼び出せるので気に入っています。

## まとめ
私がIssueを作成する際に意識していることをまとめてみました。リモートワークが主流になった今、文章で伝えるスキルがより一層大切になっていると感じています。これからも伝えるためのより良い方法を模索していきたいと思います。
プロセスが完了しました。zshが動かない

## 環境
zsh
zsh以外でも同じだと思います

## 何が起きた？
zsh関係の設定をしていると突如terminalを開いてもコマンドを受け付けなくなった。
どこかの記事で再起動したらなおるみたいなことが書いてあったが全く直らなかった。

## なぜ起きたのか？
私の場合デフォルトで使っていた`terminal`をカスタマイズしようとしいたところ、参考記事にてmac標準搭載のzshではなく`brew`管理のzshを使った方が良いという情報を目にしたので、その設定をしていました。
`brew`経由でinstallしたところまでは良かったのですが、サイトの掲載者と私とではbrewのinstall先が違いました。
サイト掲載者は`usr/local....`
私は`opt/homebrew....`
これに気づかず、使用する`ログインshell`を`usr/local...`に変更してしまったためエラーが起きました。
そんなところに`zsh`はないですよ？ってことですね。

## どうやって解決したか？
`terminal`が動かないとなると、`ログインSHELL`を再度変更することもできなそうですが、Macに搭載されている`SHELL`は一種類ではありません。
完全に無反応になってしまったterminalを開いて上のMac上部のメニュー欄から シェル > 新規コマンドを開きます
`/bin/sh`を入力して `sh`でターミナルを新規で立ち上げます。
立ち上げたターミナルで`ログインSHELL`を正しいPATHに変更することで解決しました。

ちなみに使えるSHELLは`/etc/shells`に記載されているものです。そこから好きなものを選んでください。新しくSHELLを追加した際もこちらにpathを記述します。

## 他にどんなケースが考えられるか？
今回私のケースはログインSHELLのpathをまちがえていることで発生しました。
他の理由で発生することもあると思います。
例えば`~/.zshrc`の記述にタイポ(打ち間違い)がある等
その場合は怪しそうなファイルを一度Desktopに移してから再度terminalを立ち上げてみてください。

## おまけ
なぜだかわかりませんが、terminalとiterm2ではログインSHELLが変更されていたのに、vscodeのターミナルには変更が反映されずずっとエラーが出ていました。
Mac自体を再起動することで解決しました.

エラーと戦ったわけですが、なんか途中で楽しくなってきた自分がいました笑

## 参考

https://qiita.com/kohemon/items/7128cac7e5717181abc7
IT初心者が競馬AIを作成するまで①～環境構築１～

初めてQiitaに投稿、というか趣味で何か開発するのは初めてです。
備忘録として記載しています。

今回のゴールは競馬AIを作成するまで。
その過程をちまちま更新していこうと思います。

今回は環境構築の回。
スクレイピングができるまでを目的にしています。

【前提条件】
Windows10PRO
Chrome

主に以下のツールを設定しました。
・Anaconda
・Jupyter
・Github
・TortoiseGit
・ChromeDriver
・Selenium
・Beautiful Soup4
・lxml

～～～～～～～～～～～～～～～～～～～～～～～～～～～～～～～～～～～
Anaconda、Jupyter、Github、TortoiseGitの導入については割愛します。
TortoiseGitは日本語化しておくとよいです。

さて、細かな設定を記載します。
といっても以下の記事を参考にしているので、ほとんど同じことです。
https://self-development.info/netkeiba%E3%82%92%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%82%92%E8%A7%A3%E8%AA%AC%E3%80%90%E6%BA%96%E5%82%99%E7%B7%A8%E3%80%91/

その中で躓いた点を。
①Seleniumのインストール
先ず、Anaconda以外にPythonをインストールしているとうまくいきませんでした。
参照先を変更すればよいのかもですが、使用しないのであればアンインストールを推奨します。

また、コマンドをうつプロンプトですが、OSのプロンプトではなくアナコンダのプロンプトを使用してください。
pipをアップグレードし、seleniumを無事インストールできたら成功です。

②Beautifulsoup、lxml
インストールコマンドをうってもエラーが出てきてしまいます。
pip listで見ると既にインストールされていました。
存在すれば問題ないですね。

～～～～～～～～～～～～～～～～～～～～～～～～～～～～～～～～～～～

今回はこれで終わります。
共同開発のためGitを使用していますが、個人の場合は自由です。
次回はネット競馬をスクレイピングします！
Ktor2.0.0でWebsocketのテスト

# KtorでWebsocketのテスト

Ktorで作成したwebsocketの機能をどのようにテストするのか最初わからなかったので、メモ。

## バージョン
Ktor : 2.0.0
kotlin : 1.6.10
org.jetbrains.kotlin:kotlin-test-junit : 1.6.10

## 実装
websocketを以下のように実装した

```
fun Application.configureSockets() {
    install(WebSockets) {
        pingPeriod = Duration.ofSeconds(15)
        timeout = Duration.ofSeconds(15)
        maxFrameSize = Long.MAX_VALUE
        masking = false
    }

    routing {
        webSocket("/") { // websocketSession
            for (frame in incoming) {
                when (frame) {
                    is Frame.Text -> {
                        val text = frame.readText()
                        outgoing.send(Frame.Text("YOU SAID: $text"))
                        if (text.equals("bye", ignoreCase = true)) {
                            close(CloseReason(CloseReason.Codes.NORMAL, "Client said BYE"))
                        }
                    }
                }
            }
        }
    }
}
```

## テストコード
テストコードを以下のように書いた。
```
@Test
fun testWebsocket() = testApplication {
    // クライアントのwebsocketを設定
    val client = client.config {
        install(WebSockets)
    }

    // テストコードやwebsocketの通信など実行
    client.ws("/") {
        val sendMessage = "connected"
        outgoing.send(Frame.Text(sendMessage))
        val receivedMessage = incoming.receive() as? Frame.Text ?: return@ws
        assertEquals("YOU SAID: $sendMessage", receivedMessage.readText())
    }
}
```