OmniAICreator/Qiita-1.07M huggingface dataset:
Catalinaにアップデートしたらgitコマンドでエラー。xcrun: error: invalid active developer path…

#エラー内容と解決策　その１

MacをCatalinaにアップデート後、gitを使おうとしたら下記の様なエラーが出ました。

```terminal
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
````

Command Line Toolsというものがなく怒られているらしいです。
調べたところ以下でインストール出来るとのことなので実行。

```terminal
$ xcode-select --install
```

しかし……

#またエラー
多くは前記の工程で解決するようですが、私の場合はさらに以下の様なエラーが出ました。

`このソフトウェアは、現在ソフトウェア・アップデート・サーバから入手できないため、インストールできません。`

#解決策　その２
これに対する対策として、以下のページから手動でCommand Line Toolsをインストールすることで解決しました。

[More Downloads for Apple Developers](https://developer.apple.com/download/more/)

appleIDでログイン後、`Command Line Tools`で検索をかけ、自分のXcodeのバージョンとあったものをダウンロードして、解凍後にインストールすればOKです。

![スクリーンショット 2020-09-21 17.00.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546124/c5ce99a2-94bf-01e0-7608-feab5ed87269.png)

以上！！
デザインパターンをTypeScriptで学ぶ（Facade）

デザインパターンと言えば [TECHSCORE](https://www.techscore.com/tech/DesignPattern/index.html/) さんの記事が有名ですね。時々「このコード、何かのパターンで表現できそう...」と思うのですが、日常業務でデザインパターンをサッとかっこよく使う事ができていません。という訳で TECHSCORE さんの記事を読みつつ、自分の中で噛み砕いた知識を TypeScript のコードで書き起こしてみようと思います。

- 対象読者：Java のコードを読むのに苦戦する人（自分！！）
- 環境：typescript 4.0

23 パターン全部まとめたら記事同士のリンクを貼ろうと思います。

# Facadeパターン

ショッピングカートに入れた商品の購入を例としています。

```TypeScript
/*
Module
*/
interface Item {
  id: number;
  amount: number;
}

class ShoppingCart {
  items: Item[] = [];
}

class TaxService {
  calculate(items: Item[]): number { ... }
}

class PaymentService {
  isInValid(cardNo: string): boolean { ... }
  reserve(cardNo: string, amount: number): void { ... }
}

/*
Facade
*/
class OrderFacade {
  private payment = new PaymentService();
  private tax = new TaxService();
  
  purchase(cart: ShoppingCart, cardNo: string) {
    if (cart.items.length === 0) { ... }
  
    if (this.payment.isInValid(cardNo)) { ... }
    
    ...
  }
}
```

# 説明

## Module

サブシステム群を示しています。サンプルとして簡単なクラスを使っていますが、実際の運用ではサードパーティの決済サービスや、そのインターフェースが **Module** に該当します。

```TypeScript
/*
Module
*/
interface Item {
  id: number;
  amount: number;
}

class ShoppingCart {
  items: Item[] = [];
}

class TaxService {
  calculate(items: Item[]): number { ... }
}

class PaymentService {
  isInValid(cardNo: string): boolean { ... }
  reserve(cardNo: string, amount: number): void { ... }
}
```

## Facade

サブシステムに仕事を投げる役割を持ちます。インターフェースや継承などの決まりごとはありませんが **自分自身が実装を持たない** というルールがあります。

```TypeScript
/*
Facade
*/
class OrderFacade {
  private payment = new PaymentService();
  private tax = new TaxService();
  
  purchase(cart: ShoppingCart, cardNo: string) {
    if (cart.items.length === 0) {
      throw new Error("カートに商品がありません。");
    }
  
    if (this.payment.isInValid(cardNo)) {
      throw new Error("このカードは使用できません。");
    }
    
    const amount = this.tax.calculate(items);
    this.payment.reserve(cardNo, amount);
  }
  
  // 実装を持たない
  // purchase(cart: ShoppingCart, cardNo: string) {
  //   this.http.post("/payment/authencicate", cardNo).then((status) => {
  //     if (status === "expired") {
  //       this.cardService.markAsExpired(cardNo);
  //     }
  //   });
  // }
}
```

サンプルコードにはいくつかの仕様が含まれています。

- ショッピングカートが空っぽの時は、購入処理を中断する
- 有効なカード番号でない時は、購入処理を中断する
- カード番号の認証に時間がかかるため、ショッピングカートを先にチェックする

これらのドメイン知識をあちこちのページやユースケースで使い回す場合 **Facade** にその役割を集約する事ができます。

# このパターンが解決する問題

**Facade** はサブシステムの利用方法の知識を隠蔽し「窓口」として機能を束ねる事ができるパターンです。
AtCoderBeginnerContest179復習＆まとめ

# AtCoder ABC179
2020-09-19(土)に行われたAtCoderBeginnerContest179の問題をA問題から順に考察も踏まえてまとめたものとなります．（時間なかったので，考察は時間があるときに追加します汗）
問題は引用して記載していますが，詳しくはコンテストページの方で確認してください．
[コンテストページはこちら](https://atcoder.jp/contests/abc179)
[公式解説PDF](https://atcoder.jp/contests/abc179/editorial)

## A問題　Plural Form
> 問題文
> AtCoder 王国では、英小文字を用いる高橋語という言語が使われています。
> 高橋語では、名詞の複数形は次のルールで綴られます。
>　・単数形の末尾が"s"以外なら、単数形の末尾に"s"をつける
>　・単数形の末尾が"s"なら、単数形の末尾に"es"をつける
> 高橋語の名詞の単数形$S$が与えられるので、複数形を出力してください。

```python:abc179a.py
n = input()
if n[-1] == "s":
    print(n + "es")
else:
    print(n + "s")
```

## B問題　Go to Jail
> 問題文
> 高橋君は、「サイコロを$2$個振る」という行動を$N$回行いました。$i$回目の出目は$D_{i,1},D_{i,2}$です。
> ゾロ目が$3$回以上続けて出たことがあるかどうか判定してください。 より正確には、$D_{i,1}=D_{i,2}$かつ$D_{i+1,1}=D_{i+1,2}$かつ$D_{i+2,1}=D_{i+2,2}$を満たすような$i$が少なくとも一つ存在するかどうか判定してください。

```python:abc179b.py
n = int(input())
check_list = []
for i in range(n):
    d1, d2 = map(int, input().split())
    if d1 == d2:
        check_list.append(1)
    else:
        check_list.append(0)
flag = 0
for i in range(n - 2):
    if sum(check_list[i:(i+3)]) == 3:
        flag = 1
        break
if flag:
    print("Yes")
else:
    print("No")
```

## C問題　A x B + C
> 問題文
> 正整数$N$が与えられます。$A×B+C=N$を満たす正整数の組$(A,B,C)$はいくつありますか？

```python:abc179c.py
n = int(input())
count = 0
for a in range(1, n):
    count += (n - 0.5) // a
print(int(count))
print(count)
```

## D問題　Leaping Tak
> 問題文
> 一列に並んだ$N$マスから成るマス目があり、マスには左から順番に$1,2,…,N$の番号がついています。
> このマス目で暮らしている高橋君は、現在マス$1$にいて、後述の方法で移動を繰り返してマス$N$へ行こうとしています。
> $10$以下の整数$K$と、共通部分を持たない$K$個の区間$[L_1,R_1],[L_2,R_2],…,[L_K,R_K]$が与えられ、これらの区間の和集合を$S$とします。ただし、区間$[l,r]$は$l$以上$r$以下の整数の集合を表します。
>　・マス$i$にいるとき、$S$から整数を$1$つ選んで($d$とする)、マス$i+d$に移動する。ただし、マス目の外に出るような移動を行ってはならない。
> 高橋君のために、マス$N$に行く方法の個数を$998244353$で割った余りを求めてください。

```python:abc179d.py
n, k = map(int, input().split())
s_list = []
a_list = [0] * (n + 1)
b_list = [0] * (n + 1)
a_list[1] = 1
b_list[1] = 1
for i in range(k):
    l, r = map(int, input().split())
    s_list.append([l, r + 1])
for i in range(2, n + 1):
    for l, r in s_list:
        t2 = max(0, i - l)
        t1 = max(0, i - r)
        a_list[i] += b_list[t2] - b_list[t1]
    b_list[i] = (b_list[i - 1] + a_list[i]) % 998244353
print(a_list[n] % 998244353)
```

## E問題　Sequence Sum
> 問題文
> $x$を$m$で割った余りを$f(x,m)$と表します。
> 初期値$A_1=X$および漸化式$A_{n+1}=f(A_n^2,M)$で定まる数列を$A$とします。 
> $\sum_{i=1}^{N}A_i$を求めてください。

```python:abc179e.py
n, x, m = map(int, input().split())
x_set = set()
x_list = []
for i in range(n):
    if x not in x_set:
        x_set.add(x)
        x_list.append(x)
    else:
        break
    x = x**2 % m
total = 0
start = n
for i in range(n):
    if x_list[i] == x:
        start = i
        break
    else:
        total += x_list[i]
if start != n:
    m = len(x_list) - start
    k = (n - start) // m
    total += k * sum(x_list[start:])
    for i in range(0, n - k * m - start):
        total += x_list[start + i]
print(total)
```
herokuで.envの環境変数が反映されない！！！

Herokuで個人開発してる作品をDeployしようとしたら、なぜか
Server did not receive report: Origin Error message: API key not valid. Please pass a valid API key.
のエラーが出たので対処法を記しておきたいと思います。

結論から言いますと、どうやらHerokuの方でも.envの設定が必要なようです。
:fist_tone1:heroku plugins:install heroku-config
:fist_tone1:heroku config:push

で再びHerokuにgit push heroku masterしたら解決しました！！！！

で解決です！！！
Windowsファイアウォールをpowershellで無効にする

## はじめに
VMwareで構築したwindows Serverを別チームがOSをセットアップし、私のチームが引き継いでMWのインストールを行うという前提。
windowsファイアウォールの設定はデザインシートでは無効になっているはずが実際の設定は一部有効で払い出されていました。
もう一度OSチームに再設定してもらってもよかったんですが、調整も面倒くさいのでPowershellで一括で確認→設定をしました。
さらにリモートデスクトップで1台ずつ設定変更するのはめんどくさいので自席のPCから一括でできるようにしました。

## 1.環境
OS:Windows Server 2016
Domain:workgroup
powershellはSet-ExecutionPolicy RemoteSignedで実行可能な設定済み。

## 2.準備
まず、今回のpowershellの実行は管理者権限でpowershellを実行する必要があるため、以下のコマンドで起動しましょう。

```powershell:powershell
Start-Process powershell.exe -Verb runas
```

次に、workgroup環境なのでTrustedHostsの登録を行います。まず、Windows Remote Management (WS-Management)を起動する必要があるため、以下のコマンドを実行。

```powershell:powershell
PS C:\windows\system32> winrm quickconfig
WinRM はこのコンピューター上で要求を受信するように設定されていません。
次の変更を行う必要があります:

WinRM サービスを開始します。
WinRM サービスの種類を遅延自動開始に設定します。

変更しますか [y/n]? y

WinRM は要求を受信するように更新されました。

WinRM サービスの種類を正しく変更できました。
WinRM サービスが開始されました。
```

次に以下のコマンドを実行。
"value"でpowershellでリモート接続したいホスト名 or IPアドレスを登録。今回は検証環境なので"*"で登録しました。

```powershell:powershell
PS C:\windows\system32> Set-Item WSMan:\localhost\Client\TrustedHosts -value *

WinRM セキュリティの構成。
このコマンドは WinRM クライアントの TrustedHosts の一覧を変更します。TrustedHosts
の一覧内にあるコンピューターは認証されない可能性があります。クライアントはこれらのコンピューターに資格情報を送信する可
能性があります。この一覧を変更しますか?
[Y] はい(Y)  [N] いいえ(N)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): y
```

## 3.自分のPCからpowershellで設定変更
invokeを使って自席から実行。まず、credential(認証情報)を先に変数に入れておきます。

```powershell:powershell
PS C:\windows\system32>  $cre =Get-Credential localhost\administrator
```

プロンプトが表示されるのでPWを入力します。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693852/5c08d08f-a4d9-7d20-1c4c-0e65ef03bc54.png)

こうすると変数の中にID/PW情報が入るので、いちいち入力する手間が省ける。

invokeを使って、リモートでファイアウォールの設定を確認
↓

```powershell:powershell
Invoke-Command 192.168.1.1 -credential localhost\administrator -scriptBlock {Get-NetFirewallProfile |select-object name,enabled}

name           : Domain
Enabled        : False
PSComputerName : 192.168.1.1
RunspaceId     : 75f9bf5a-7ec7-4a68-a56d-ca5f7b7694b3

name           : Private
Enabled        : False
PSComputerName : 192.168.1.1
RunspaceId     : 75f9bf5a-7ec7-4a68-a56d-ca5f7b7694b3

name           : Public
Enabled        : True　　　←★Trueなので有効
PSComputerName : 192.168.1.1
RunspaceId     : 75f9bf5a-7ec7-4a68-a56d-ca5f7b7694b3

```

Publicがファイアウォール有効になってる(-_-メ)。じゃあ、有効にします。

```powershell:powershell
Invoke-Command 192.168.1.1 -credential localhost\administrator -scriptBlock {Set-NetFirewallProfile -Enabled false; Get-NetFirewallProfile |select-object name,enabled}

name           : Domain
Enabled        : False
PSComputerName : 192.168.1.1
RunspaceId     : 75f9bf5a-7ec7-4a68-a56d-ca5f7b7694b3

name           : Private
Enabled        : False
PSComputerName : 192.168.1.1
RunspaceId     : 75f9bf5a-7ec7-4a68-a56d-ca5f7b7694b3

name           : Public
Enabled        : False　　　←★Falseなので無効
PSComputerName : 192.168.1.1
RunspaceId     : 75f9bf5a-7ec7-4a68-a56d-ca5f7b7694b3

```
OK！

## 4.Credentailについて
検証環境はworkgroupで作ることが多く、Credentialをいちいちプロンプトで打つのがめんどい…。
なんとかファイルから読み取るようにしたい。ただセキュアにしたい…。
と思っていろいろ探してみたらよさげなサイトがありました。
↓
https://www.vwnet.jp/Windows/WS08R2/PSPassword/SecurePassword.htm

次回はセキュアなファイルからパスワード情報を読みとって実行してみます('ω')ノ
デザインパターンをTypeScriptで学ぶ（Bridge）

デザインパターンと言えば [TECHSCORE](https://www.techscore.com/tech/DesignPattern/index.html/) さんの記事が有名ですね。時々「このコード、何かのパターンで表現できそう...」と思うのですが、日常業務でデザインパターンをサッとかっこよく使う事ができていません。という訳で TECHSCORE さんの記事を読みつつ、自分の中で噛み砕いた知識を TypeScript のコードで書き起こしてみようと思います。

- 対象読者：Java のコードを読むのに苦戦する人（自分！！）
- 環境：typescript 4.0

23 パターン全部まとめたら記事同士のリンクを貼ろうと思います。

# Bridgeパターン

ユーザーのログイン処理と、ログイン時のログ書き込みを例としています。

```typescript
/*
Abstraction
*/
abstract class User {
  constructor(protected loggerImpl: Logger) {}
  abstract getLoginUrl(): string;

  login() {
    this.loggerImpl.log(`Logged in. ${this.getLoginUrl()}`);
  }
}

/*
RefinedAbstraction
*/
class Manager extends User { ... }
class Staff extends Manager { ... }


/*
Implementer
*/
interface Logger {
  log(message: string): void;
}

/*
ConcreteImplementor
*/
class ConsoleLogger implements Logger { ... }
class ApiLogger implements Logger { ... }
```

抽象クラス User は「ログインする」という振る舞いを持っています。そして、ユーザーロールによりログインの URL は異なるものとします。またログイン履歴をログとして書き込みます。

この時点で複数の分岐が発生しています。

1. ログイン先の URL
  - ユーザーロールによる
2. ログの書き込み先
  - 開発中のページではコンソール出力
  - リリース済みのページでは API を経由したロギングサービス、など

# 説明

## Abstraction と RefinedAbstraction

１つ目のログイン先の URL の分岐は、抽象クラス User を派生させる事で実装します。

```typescript
/*
Abstraction
*/
abstract class User {
  constructor(protected loggerImpl: Logger) {}
  abstract getLoginUrl(): string;

  login() {
    this.loggerImpl.log(`Logged in. ${this.getLoginUrl()}`);
  }
}
```

```typescript
/*
RefinedAbstraction
*/
class Manager extends User {
  constructor(protected loggerImpl: Logger) {
    super(loggerImpl);
  }
  getLoginUrl = () => "manager/login";
}

class Staff extends User {
  constructor(protected loggerImpl: Logger) {
    super(loggerImpl);
  }
  getLoginUrl = () => "staff/login";
}
```

## Implementor と ConcreteImplementor

２つ目のログの書き込み先の分岐は、コンストラクタインジェクションしたインターフェースを派生させる事で実装します。

```typescript
/*
Implementer
*/
interface Logger {
  log(message: string): void;
}
```

```typescript
/*
ConcreteImplementor
*/
class ConsoleLogger implements Logger {
  log(message: string) {
    console.log(message);
  }
}

class ApiLogger implements Logger {
  log(message: string) {
    import("http").then(http => http.request({ /* options */ }));
  }
}
```

## 利用例

```typescript
// Staff クラスを生成し、ロギングサービスを利用してログを残す
const staff = new Staff(new ApiLogger());
staff.login();

// Manager クラスを生成し、コンソール出力にログを吐き出す
const manager = new Manager(new ConsoleLogger());
manager.login();
```

# このパターンが解決する問題

もしクラス継承を使って同じ例を実装した場合、分岐の数だけ掛け算式にクラスが増えてしまいます。

- User から派生した Manager（コンソール出力ログを持つ）
- User から派生した Manager（ロギングサービスを持つ）
- User から派生した Staff（コンソール出力ログを持つ）
- User から派生した Staff（ロギングサービスを持つ）

**Bridge** はこのような問題に対して「橋渡し」によって振る舞いと実装を分離し、拡張を自由にする事ができるパターンです。
ESLintとPrettierを同時に良い感じに動かす。今回はESLintからPrettierを呼び出す

プロジェクトにeslintを入れてルールを書いてるプロジェクト、

[VSCodeのPrettierの設定と、ESLintの衝突を回避したい。とりあえず文末のセミコロン - 青いやつの進捗日記。](https://tech.motoki-watanabe.net/entry/2020/09/20/160738)

このブログでも書いたが、VSCodeの拡張機能のPrettierが`.vscode/settings.json`に書いてある

```json
{
  "editor.formatOnSave": true,
}
```

でPrettierが起動することによりESLintと衝突し、ESLintの

```json
"semi": ["error", "never"],
```

で末尾のセミコロンはだめなのに、Prettierの拡張機能のデフォルトの

```
Prettier: Semi
Whether to add a semicolon at the end of every line
```

と衝突する、という。まあデフォルトの設定外せばいいし、もしくは`.prettierrc`で

```json
{
  "semi": false,
}
```

とすればプロジェクトの設定としてfalseになるので、おそらく衝突しない。けど、そもそもフォーマット系は保存時に動いてほしいし、あとそもそもプロジェクトとして設定は統一させて統一して良い感じに動いてくれるようになってほしい。

---

で、色々調べました。
方法はざっくりたぶん2つ。

① `eslint-config-prettier`（unnecessaryかmight conflict with PrettierなESLintのルールをオフにしてくれる）[https://github.com/prettier/eslint-config-prettier](https://github.com/prettier/eslint-config-prettier)
と
`eslint-plugin-prettier`（ESLintからPrettierを動かす）[https://github.com/prettier/eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier)

を入れて、

`.vscode/settings.json` で保存時にESLintを実行するように記述して、ESLintからPrettierを動かす

参考

[ESLint と Prettier の共存設定とその根拠について](https://blog.ojisan.io/eslint-prettier)

[ESLintとPrettierを併用するときの設定(eslint-plugin-prettier, eslint-config-prettier) - dackdive's blog](https://dackdive.hateblo.jp/entry/2019/03/15/100000)

②ESLintとPrettierをそれぞれ別に動かす

これは結局やってないからまだちゃんとはわかってないけど…ESLintはまあ通常通りで、Prettierは①で入れた2つのプラグイン両方を入れないで、`eslint-config-prettier`のみ入れてESLintとPrettierを別々に実行する方法。

参考記事にも書いてあるが、たしかにPrettierの公式ドキュメントとしては①の方法はgenerally not recommendedだと言っている。

Prettierはnpm scriptsから実行する、ということらしい。[Prettierを使って保存時にソースコードを自動で整形してもらう]([https://qiita.com/iewori/items/8a08678b86e69dba233b](https://qiita.com/iewori/items/8a08678b86e69dba233b))

たしかにwatchしてPrettier動かせば良い気はしている

参考

[TypeScript + Node.jsプロジェクトにESLint + Prettierを導入する手順2020 - Qiita](https://qiita.com/notakaos/items/85fd2f5c549f247585b1)

---

なんかいま書いてて②でも良い気がしてきたけれど、今回やってみたのは①なので①の方法について話す。

とりあえずインストール

```bash
$ yarn install --dev prettier eslint-plugin-prettier eslint-config-prettier
```

で、`.eslintrc.json`にextendsに`"plugin:prettier/recommended"`を追加

```json
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
```

（extendsとpluginとrulesにそれぞれ書く方法もあるが、これだけでも済む）

`.vscode/settings.json`に保存時ESLintを起動する設定を追加

```json
{
  "editor.formatOnPaste": true,
  "editor.codeActionsOnSave": {
    // For ESLint
    "source.fixAll.eslint": true,
    // For TSLint
    "source.fixAll.tslint": true,
    // For Stylelint
    "source.fixAll.stylelint": true
  }
}
```

で、これで保存時にESLint経由でPrettierも動きます。

しかし、Prettierの設定は前述の通りデフォルトがセミコロンが末尾についたり、ESLintの設定にもしセミコロン許さない設定をしていたら衝突してしまうものがあります。

なので、あとは`.prettierrc`にESLintに合わせて設定を追加します。私の場合、ESLintとPrettierで衝突していたものに

```json
"comma-dangle": ["error", "never"],
"quotes": ["error", "single"],
"semi": ["error", "never"]
```

があったので、これを回避するために`.prettierrc`に

```json
{
  "semi": false,
  "singleQuote": true,
  "trailingComma": "none"
}
```

と追加します。

これで、保存時にPrettierも動いて良い感じになってくれます。
Javascriptの基本の書き方③

#はじめに
前回,前々回は以下から

[Javascriptの基本の書き方①](https://qiita.com/itou-t/items/66b870ac75c3b1b5bbbd)

[Javascriptの基本の書き方②](https://qiita.com/itou-t/items/19dfe7bebaf4b7754aae)

##関数の定義と呼び出し

・定義方法

```Javascript
const 定数名 = function() {
  処理;
};
```

・呼び出し方法

```
定数名();
```


##アロー関数

ES6からは関数の定義方法を簡素化できるアロー関数が可能になった

・定義方法

```Javascript
const 定数名 = () => {
  処理;
};
```

##オブジェクト内で定義、実行する方法

・定義方法

```javascript
const 定数名={
  プロパティ値:() => {
    処理;
  }
}
```

・実行方法

```javascript
定数名.プロパティ値();
```

##クラスの作成方法

```javascript
class クラス名{
  
}
```

###クラスからオブジェクトを作成する方法
```javascript
class クラス名 {
}

const 定数名= new クラス名();
 ```

###コンストラクタ
コンストラクタとはインスタンスが生成されたときに実行する機能

```javascript
class クラス名 {
  constructor(){
    処理;
  }  
}
```

###クラス内でプロパティ値を使用する方法

・定義方法

```javascript
class クラス名 {
  constructor() {
    this.プロパティ値=値;
  }
}
```

・クラス外でプロパティ値を使用する方法

```javascript
クラス名.プロパティ値
```

##メソッド

インスタンスの動作を表す。

・定義方法

```javascript

class クラス名 {
  メソッド名(){
    処理;
  }
}
```

・クラス内のメソッドの呼び出し方法

```
クラス名.メソッド名();
```

###メソッド内でインスタンスの値を使用する方法

```javascript
this.プロパティ名
```

###メソッド内でメソッドを使用する方法
```javascript

this.メソッド名();
```
Webex Teams から Microsoft Teams に Bot を移行した話


## はしがき

会社のチャットツールがWebex Teams(Webex)からMicrosoft Teams(MSTeams)に移行されました。
それに伴い、社内で利用していたBotも移行することになりました。
今回は、移行の際につまづいた点である、それぞれのBotの概念についてと、具体的なやり方について比較します。

## Botという概念の比較

### WebexにおけるBot

大まかにいうと、ユーザと扱いがほとんど変わりません。
スペースに対しての導入は、Bot作成時に登録するメールアドレス形式の識別子を使用してのインバイトですし、利用を止める時も、ユーザをremoveする時と同じ手順です。
これはAPI経由で同じ動作を行う際も同じで、ユーザと同じようにスペースへの追加・削除が行えます。

### MSTeamsにおけるBot
Webexに比べ、こちらはとても複雑です。
MSTeamsにおけるBotは、あるアプリケーションのBot機能、というイメージです。
アプリケーションの実体はAzure上にあり、Botの機能的な実体はBotFramework上に存在します。
BotFrameworkがAzure上のアプリの認証情報を使い、いろいろ動作する、というような挙動をします。
これはWebexのBotとは異なるもので、移行の際にイメージを掴むのがとても難しい部分でした。

## 具体的なやり方の比較

移行対象としたBot群には以下の機能がありましたので、それぞれのやり方について記載します。
- メッセージの受信（ユーザ → Botのメンションを受ける）
- メッセージの投稿（Botからの一方的なもの）
- メッセージの投稿（ユーザからのメンションを受けてから行う）
- メンションの投稿（Bot → ユーザへのメンション）

### メッセージの受信（ユーザ → Botのメンションを受ける）

#### Webex
メンションを受けた際のWebhook指定をすることで、メンションを受けて動作をするBotが作成可能です。

#### MSTeams
AppStudioなどで、BotFrameworkを利用したBot機能を持つアプリを作成することで、作成時にメンションを受けた際のWebhook指定ができます。

### メッセージの投稿（Botからの一方的なもの）

#### Webex
Bot作成時のトークンを利用し、メッセージ送信APIを打つことで投稿可能です。

#### MSTeams
BotFrameworkを利用したBotのみでは、一方的なメッセージ送信を行うことはできません。
そのBotに持たせる機能がメッセージ送信のみであれば、IncomingWebhookアプリを導入することで実現可能です。
他にも機能を持たせるのであれば、GraphAPIを利用するか、BotFrameworkを併用する必要があります。

### メッセージの投稿（ユーザからのメンションを受けてから行う）

#### Webex
メンションを受けた後、送信元のスペースIDに対してメッセージ送信APIを打つことで投稿可能です。

#### MSTeams
BotFrameworkを利用したBotでメンションを受け、送信元のテナント情報・会話オブジェクトを利用して送信 or 返信 APIを打つことで、投稿可能です。

### メンションの投稿（Bot → ユーザへのメンション）

#### Webex
対象ユーザの識別子（メールアドレス）を指定することでメンション可能です。

#### MSTeams
対象ユーザの識別子（ID）を指定することでメンション可能です。
このIDは、BotFrameworkでのみ（？）取得できるIDで、BotFramework以外を利用したメンションは基本的にできないものと思われます。
＊ユーザ識別子を静的に持っておく、などすれば可能です

## おわりに

以上です。
移行部分はある程度感覚でどうにかなるものの、概念部分は読み解くのに時間がかかりました。
（というか、MSのドキュメントわかりにくすぎる・・・）
いろいろな資料や、実際の動作ベースでなんとなく理解したものなので、実際の仕様とは異なる部分があるかもしれませんが、参考になれば幸いです。
Django-allauthでテンプレートを上書きするには、account配下にテンプレートを作成する


# 概要
- Django-allauthでテンプレートを上書きするには、`account/login.html`のように、`account`配下にテンプレートを作成します。
    - プロジェクトフォルダ内で管理できるので、`venv/lib/python3.6/site-packages/allauth/account/templates`にあるファイルを書き換えずにすみ、Gitなどでバージョン管理する際に楽です。
- 環境は、Python 3.6.9 + Django 3.1.1 + django-allauth 0.32.0 で確認しました。

# 内容
- 例えばログイン画面の`account_login`というURLは、`account/login.html`というテンプレートに対応しています。
- この名前でテンプレートを作成すれば、デフォルトのテンプレートを上書きすることができます。
    - 公式サイトの [Templates](https://django-allauth.readthedocs.io/en/latest/templates.html) にも記載があります。
    - URLとテンプレートファイルの対応は、公式サイトの [Views](https://django-allauth.readthedocs.io/en/latest/views.html#login-account-login) にあります。


# 具体例
- `settings.py`ファイルの`TEMPLATES`の`DIRS`で、テンプレートディレクトリを指定します
    - 例：manage.pyと同じ階層に`templates`というフォルダを作ってそこに入れる場合

```python

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'templates'),  # この行を追加
        ],
        (略)
    }
]
```

- 上記のtemplatesフォルダ内に、`account/login.html`を作成します

```sh

$ mkdir -p templates/account/
$ echo "<h1>this is login template...</h1>" > templates/account/login.html
```

- ブラウザで確認します
    - http://localhost:8000/account/login/

- 上記以外の画面では、デフォルトのテンプレートのままなことを確認します
    - http://localhost:8000/account/signup/


# 「account」という名前は固定

- 「account」という名前は固定です。
    - INSTALLED_APPS にも`'allauth.account',`を追加していますし、
    - `python3 manage.py showmigrations` すると、`account`というテーブルへのマイグレーションができているのがわかります。
        - 公式サイトの[Views](https://django-allauth.readthedocs.io/en/latest/views.html#login-account-login)では、`accounts`と`account`が混在しているのが気になります。。。(後でPR出しておきます)
iOS14でReact Nativeアプリで画像が表示されない

# パッチファイル作成

以下コマンドでルートディレクトリ配下に `patches/react-native+0.61.5.patch` を作成する。

```bash
$ npx patch-package react-native

npx: 150個のパッケージを3.464秒でインストールしました。
patch-package 6.2.2
patch-package: you have both yarn.lock and package-lock.json
Defaulting to using npm
You can override this setting by passing --use-yarn or deleting
package-lock.json if you don't need it

• Creating temporary folder
• Installing react-native@0.61.5 with npm
• Diffing your files with clean files
✔ Created file patches/react-native+0.61.5.patch
```

以下コードを追加する。

```patch
diff --git a/node_modules/react-native/Libraries/Image/RCTUIImageViewAnimated.m b/node_modules/react-native/Libraries/Image/RCTUIImageViewAnimated.m
index 01aa75f..4ef8307 100644
--- a/node_modules/react-native/Libraries/Image/RCTUIImageViewAnimated.m
+++ b/node_modules/react-native/Libraries/Image/RCTUIImageViewAnimated.m
@@ -269,6 +269,8 @@ - (void)displayLayer:(CALayer *)layer
   if (_currentFrame) {
     layer.contentsScale = self.animatedImageScale;
     layer.contents = (__bridge id)_currentFrame.CGImage;
+  } else {
+    [super displayLayer:layer];
   }
 }
```

以下のコマンドを叩き、 `node_modules/react-native/Libraries/Image/RCTUIImageViewAnimated.m` に反映させる。267行目付近。

```bash
$ patch -p1 -i patches/react-native+0.61.5.patch
```

```m
- (void)displayLayer:(CALayer *)layer
{
  if (_currentFrame) {
    layer.contentsScale = self.animatedImageScale;
    layer.contents = (__bridge id)_currentFrame.CGImage;
  } else {
    [super displayLayer:layer]; // 記載されていることを確認
  }
}
```


# 再ビルド

```bash
$ cd ios; pod install
$ react-native start --reset-cache
$ npx react-native run-ios
```

# 参考
- [iOS14でReact Nativeアプリをビルドすると、Imageが表示されない場合の対処](https://qiita.com/krile136/items/34b5d5a2a0209b281d0e)
Golandでdelve古くてデバッガ動かねえよって叱られた時の対処

うっすい内容ですがvscodeの情報は結構あったけどGolandのは発見出来なかったので一応

タイトル通り、GolandでDebug実行しようとすると

```
Version of Delve is too old for this version of Go ...
```
こんなんが出て叱られるときの対処です。
Golandはこの記事書いた時点で1番新しいです

単純に[go-delve](https://github.com/go-delve/delve)自前でビルドしてプラグイン差し替えれば良いです。
mainは`cmd/dlv/`配下にあるので、`git clone`かましたらディレクトリ移動して`go build`
念のためもともとあったdlvバイナリは`dlv.bk`とかにしておき、
できあがったバイナリを`[[your path]]/[[Goland本体ディレクトリ]]/plugins/go/lib/dlv/linux/`下に放り込めばok
ES6以降のJavaScript/TypeScriptで0...N-1の配列を作る

## 動機

JavaScript/TypeScriptで定数(N)で決められた数だけループしたい時、

```javascript
const N = 100;
for(let i = 0; i < N; i++){
   //...なんか処理
}
```

こんなダサいループは書きたく無い。。。

pythonの`range(N)`みたいなのがJavaScriptにもあったらなぁ。。。

## 解決策

英語でググってみたらStackOverflowに[良い解決策](https://stackoverflow.com/questions/3746725/how-to-create-an-array-containing-1-n)が載っていたのでご紹介。

世界には頭の良い人がいるものだなぁ。

```javascript
const N = 100;
[...Array(N).keys()].forEach(i => {
   //...なんか処理(iには0...N-1(=99)が格納される)
});
```

もし1...Nにしたければ、

```javascript
const N = 100;
[...Array(N).keys()].map(n => n + 1); // [1,2,3,...,100]
```

こんな具合にmapしてズラしてあげればOK。

## 応用

ということはもしかして、[FizzBuzz](https://ja.wikipedia.org/wiki/Fizz_Buzz)がワンライナーで書けるんじゃないか...?

```javascript
[...Array(100).keys()].map(n => n + 1).map(n => n % 15 === 0 ? 'FizzBuzz' : n % 3 === 0 ? 'Fizz' : n % 5 === 0 ? 'Buzz' : n.toString()).forEach(s => console.log(s));
```

出来た。

一応解説すると、

```javascript
[...Array(100).keys()] // [0,1,2, ... ,99]の配列を作る
   .map(n => n + 1)    // mapでズラして[1,2,3, ... , 100]にする
   .map(n => n % 15 === 0 ? 'FizzBuzz' : n % 3 === 0 ? 'Fizz' : n % 5 === 0 ? 'Buzz' : n.toString()) // FizzBuzzのルールを満たすように文字列に変換する
   .forEach(s => console.log(s)); //1行ずつ出力する
```

この`.map()`や`.forEach()`を繋げて書く表記に慣れていない方は、手前味噌で恐縮ですが私の[過去記事](https://qiita.com/tetsuya-zama/items/6c88f26302a3fe9b28f3)をご覧ください。

## (ちなみに)indexを使用しない場合

生成した配列の中身の数値を使わず、単にN回ループしたい場合は`[...Array(N)]`で良いらしい。

```javascript
// 長さが100の0から99までのランダムな整数の配列を作成
const randomInt = [...Array(100)].map(() => Math.floor(Math.random() * 100));
```

## 追記(2020/09/22)

この記事に対して別途SNSで頂いたコメントを元に続きを書きました。
ぜひ合わせてご一読ください。

[なぜ我々は頑なにforを避けるのか](https://qiita.com/tetsuya-zama/items/11e19b9da4892eb365c4)
OpenLDAPよりFreeIPAのほうが良い

# directory seviceとは？
マシーンが複数台あるとき、いちいちそれぞれのマシンに対してユーザを管理していくのは非効率です。
そんな時はユーザ情報をLDAPで管理すると楽になります。
LDAPも設定がいろいろ大変です。

## なんでFreeIPA？　OpenLDAPは？
CentOS8からOpenLDAPがサポートされなくなりました。
あれって思ってみたら、389 Directoryが代わりにあるようです。
ただ、そのまま使うと学習コストが高く、いろいろと一つのパッケージになっているもの、FreeIPAを使うことにしました。
バックエンドで389を使っています。

## 環境
- CentOS8 x1台（FreeIPAのサーバ、以下はすべてクライアント）
- CentOS7 x1台
- Ubuntu 20.04 x2台

環境の違いも関係なく、FreeIPAではそのまま設定すれば使えるようになります。

## FreeIPA
FreeIPAは、いくつかのソフトウェアスタックが一括になっていて、簡単にインストールすることができます。
ディレクトリサービスやDNS、ケルベロス認証、ウェブインタフェースが統合されていてシームレスに動作します。

## システム要件
基本的に、DNSで逆引きも可能であることが条件になります。
そのため、普通に/etc/hostsに記述するだけではだめで、DNSサーバをきちんと立てる必要があります。
ドメインはすでに取得したドメインがあるので、そのサブドメイン `int.xxx.com`のように設定しました。

## FreeIPAのインストール
### hostnameの設定
hostnameは、FQDNでないとインストールに失敗します。host名の設定はちゃんとやっておきましょう。

```:/etc/hostname
nozomi.int.kotsuki-lab.com
```

hostname コマンドで一時的にセットすることもできます。

### /etc/hostsへの追記
```:/etc/hosts
$ cat /etc/hosts
10.4.200.96 nozomi.int.kotsuki-lab.com
...
```
先頭に書く必要があるそうです。インストーラで最初に参照するところなのかな？

### freeipa(サーバ)のインストール
```
$ sudo dnf module -y install idm:DL1/dns 
$ sudo ipa-server-install --setup-dns 
```

対話式でインストールを進めます。

## クライアントのインストール概要
DNSサーバを登録して、hostnameを設定して、そのあとにインストールをすると、自動的にホストサーバを検出して自動的に設定してくれます。
特に何も設定はいらないはずです。

## webインターフェースによる設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533324/dac3b1cb-ce27-8ce1-ab82-b89504177ecd.png)
Userや、Host、sudoの設定などがwebからできます。コンソールが嫌いな人はここからやってもいいと思います。学習コストが低いです。（効率は、悪いかも）

## 参考
https://qiita.com/MahoTakara/items/3114e88e7b38469eeed6
https://www.server-world.info/query?os=CentOS_8&p=freeipa&f=1
UnrealC++でGameViewかを取得する

#はじめに
突然ですが、UE4の機能である「Game View」をご存知でしょうか？
そう、レベルエディタでGキーを押すことでボリュームのフレームとかが消えるあれです。
私は「ue4 level editor g key」とかで調べて初めてこれが「Game View」ということを知りました(１年半くらいUE4を触っているのに知らなかった...)。
そんな「Game View」の状態かを取得する方法をご紹介しようと思います。

[ビューポートの基本 | Unreal Engine ドキュメント](https://docs.unrealengine.com/ja/Engine/UI/LevelEditor/Viewports/Basics/index.html)

#取得方法
タイトルでお気づきの方も多いと思いますが、BPからは取れません。そのため、UnrealC++でBPに公開してあげる必要があります。

```TestFunctionLibrary.cpp
#include "Editor.h"
#include "EditorViewportClient.h"

bool UTestFunctionLibrary::IsInGameView()
{
	if (GEditor)
	{
		if (FViewport* ActiveViewport = GEditor->GetActiveViewport())
		{
			if (FEditorViewportClient* ViewportClient = StaticCast<FEditorViewportClient*>(ActiveViewport->GetClient()))
			{
				return ViewportClient->IsInGameView();
			}
		}
	}

	return false;
}
```

こちらの関数を作るには「UnrealEd」モジュールが必要ですので忘れずに追加してください。

#おわりに
プラグインなどでDrawDebug～系で実装したデバッグ表示などは「Game View」の状態でも表示されてしまうので、こちらの方法で状態を取得してちゃんと消えるようにすると気の利いたプログラマーになれるのではないでしょうか。
そもそも「Game View」と言うのを知らないとエディタ上で入力を取ろう！とかそういった方向に向かってしまう~~（経験者は語る...）~~可能性がありますので、こちらの記事が同じ問題に出くわした方のお役に立てば幸いです。
AtCoder Beginner Contest 179

##[A - Plural Form](https://atcoder.jp/contests/abc179/tasks/abc179_a)

```Python:Python
S = str(input())
 
if S[len(S)-1] == 's':
    print(S + 'es')
else:
    print(S + 's')
```

##[B - Go to Jail](https://atcoder.jp/contests/abc179/tasks/abc179_b)

```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define pai 3.1415926535897932384
 
using namespace std;
using ll =long long;
using P = pair<int,int>;
 
int main(int argc, const char * argv[]) {
    
    int N;
    cin >> N;
    
    vector<int> d1(N);
    vector<int> d2(N);
    
    int Ans = 0;
    int sum = 0;
    for(int i=0; i<N; i++){
        cin >> d1[i] >> d2[i];
        
        if(d1[i] == d2[i]){
            sum++;
            Ans = max(Ans, sum);
        }else{
            sum=0;
        }
    }
    
    if(Ans>=3) cout << "Yes" << endl;
    else cout << "No" << endl;
    
    return 0;
}
```

##[C - A x B + C](https://atcoder.jp/contests/abc179/tasks/abc179_c)

```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define pai 3.1415926535897932384
 
using namespace std;
using ll =long long;
using P = pair<int,int>;
 
int main(int argc, const char * argv[]) {
    
    ll N;
    cin >> N;
    
    ll Ans = 0;
    for(ll A=1; A<N; A++){
        for(ll B=1; A*B<N; B++){
            ll C = N - (A * B);
            if(C > 0) Ans++;
        }
    }
    
    cout << Ans << endl;
    
    return 0;
}
```
WSLでsshpassを使ってscpファイル送信①

# 初めに
WSL(Ubuntu)で、シェルを実行したら、パスに記載しているファイルを指定サーバー上の指定フォルダに転送する。
どこまでファイルにして、どこまで実行ファイルに書くかはお好みで

# 実行(確認)環境
WSL2 
Ubuntu 18.04
CentOS7（格納先）


## フォルダ構成

```
# 実行フォルダ（どこでも大丈夫なハズ）
c:\test\
 ├ transport.sh
 ├ filepath(パスを記載)
 └ passfile(パスワードを記載)

# 転送ファイル群
c:\temp\
 ├ test1.txt
 ├ test2.txt
 └ test3.txt
```

## ソース
### 設定ファイル系 
``` text:filepath
C:/temp/test1.txt
C:/temp/test2.txt
C:/temp/test3.txt
```
※改行はLFで

``` text:passfile
hogehoge
```
※１行で記載する必要あり

### シェルスクリプト
``` Shell:transport.sh
#!/bin/sh

# サーバーの転送先
SERVERPATH="/root/"
# sshのユーザー名
USERNAME="root"
# サーバーのホスト
SERVERHOST="XXX.XXX.XXX.XXX"

# ファイルパスをループ
for line in `cat filepath`
do
    # ローカルファイルパス変換
    upfiles=${upfiles}$(wslpath -u $line)" "
done

# sshpass でファイルを転送
sshpass -f passfile scp -o StrictHostKeyChecking=no ${upfiles} ${USERNAME}@${SERVERHOST}:${SERVERPATH}
```

# 実行(一応)
``` Shell:
cd /mnt/c/test/
./transport.sh
``` 

次はファイル別にサーバーのフォルダ指定するやつを作りたい
【java】【javaSliver】インタフェースと抽象クラスがややこしいのでまとめ

# この記事の目的
来週javaシルバーを受験するので、曖昧な部分を潰していくことに。
ちょっと混乱していた`インタフェース`と`抽象クラス`について整理しておこうかな。というのがこの記事の目的です。

## 混乱していた理由
「抽象メソッドはabstractをつけて宣言する。つけないとコンパイルエラー」と書かれていたり、
「省略した場合、暗黙的にpublic abstractが付与される」と書かれていたり・・・

「あれ？勘違い？」と混乱していました。
ので、一旦しっかり整理して混乱から脱出したかったんです。
今思えば、抽象メソッドと抽象クラス、インタフェースがごっちゃになっていたんだろうな。って思ってます。

## ルール比較

インタフェースと抽象クラスで定義できるものを一覧でまとめました。整理整理。
メソッドとフィールド変数に分けて整理しました。

### メソッドについて

まずはメソッドから。
`インタフェース`と `抽象クラス`それぞれでテーブルにまとめました。

#### **インタフェースのメソッド達**

| 定義できるもの | アクセス修飾子 | 省略できる？|その他|
|:-:|:-:|:-:|:--|
| 抽象メソッド | public | 省略してもpublic |インタフェースだとabstractも省略できるよ。|
| defaultメソッド | public | 省略できちゃう| ※SE8以降定義できるようになりました。|
| staticメソッド  | public or private  | 省略するとpublic | ※SE8以降定義できるようになりました。|

#### **ポイント**
- インタフェースの場合で宣言する抽象メソッドは`abstract修飾子`も省略できるみたいです。
- アクセス修飾子を記述しないとpublicになるってのが共通ルールですかね？
- staticメソッドについては、アクセス修飾子がpublicに限らずprivateの指定もできちゃうのがちょっと厄介ですね。

##### なんで、インタフェースだとabstract修飾子を省略できるんだろ？
これは個人的にたどり着いた推測ですが・・・。
インタフェースでは基本的に抽象メソッドしか定義できない（SE8までは）ので、abstractを明示的に宣言しなくても、コンパイラが空気読んでabstractつけてくれるんだな。と考えることにしました。

#### **抽象クラスのメソッド達**

| 定義できるもの | アクセス修飾子 | 省略できる？|その他|
|:-:|:-:|:-:|:--|
| 抽象メソッド | なんでもあれ | abstractは必須。|アクセス修飾子は省略可。省略してもpublicとかにはならないよ|
|具象メソッド| なんでもあれ | 省略できちゃう | アクセス修飾子は省略可。省略してもpublicとかにはならないよ|

#### **ポイント**
- インタフェースと違って、アクセス修飾子は自由に定義できちゃう。
- アクセス修飾子を省略すると、具象クラスと一緒で、修飾子なしのメソッドとして扱っちゃう。
- 抽象メソッドの`abstract修飾子`は**必須!!!**

##### なんで、抽象クラスだとabstract修飾子を省略できないんだろう？
抽象クラスの中には、具象メソッドと抽象メソッドが混在するから、混乱しないように明示的にabstractをつけないといけないって考えることにしました。
(これも個人的にたどり着いた推測です。)

### 続いて、変数

#### **インタフェース**

| フィールドの種類 | 定義できる？できない？ | staticを省略できる？|その他|
|:-:|:-:|:-:|:--|
| 非static変数（インスタンス変数) | 定義できない | - | インタフェースはインスタンス化できないからね。|
| static変数| 定義できるけど、定数になるよ| 省略できる | 省略しても`public static final`になっちゃう。| 

#### **ポイント**
- インスタンス変数は定義できない
- static変数は何がなんでも`public stati final`になる

インタフェースはインスタンス化できないから、インスタンスした時の変数のことなんて考える必要ないですね。
だから定義できないってことですね。うん。納得。
インスタンス化はできないけど、型としては扱えちゃうからこれまたややこしポイントですね。

#### **抽象クラス**

| フィールドの種類 | 定義できる？できない？ | staticを省略できる？|その他|
|:-:|:-:|:-:|:--|
| 非static変数（インスタンス変数) | 定義できる | そもそもいらない | アクセス修飾子はなんでも定義できちゃう。 |
| static変数| 定義できる| 省略できない | staticを省略したらインスタンス変数になってしまうよ。アクセス修飾子はなんでも定義できちゃう。 | 

#### **ポイント**
- 具象メソッドとなんら変わらない！

##まとめ

- インタフェース
 - 抽象メソッド
   → abstractは**省略可能**
 - defaultメソッド
 - staticメソッド
   → **staticメソッドだけは privateでも扱える**
 - static変数
   → static **変数は定数としてしか使えない**

- 抽象クラス
 - 抽象クラス
   → **abstractは絶対書く**
 - 具象メソッド
 - static変数
 - 非static変数
 
## さいごに
結構自分ようのメモになっちゃいましたが、やっぱりこうやって整理する時間は必要ですね。
もし、解釈が違う、間違っているなあればお手数をおかけしますが、ご指摘いただけますと幸いですm(_ _)m
【Nodeが壊れた】internal/modules/cjs/loader.js:582 throw err;

Reactで作られたサービスをクローンして勉強していたら、Nodeが壊れた（のかもしれない）

```
internal/modules/cjs/loader.js:582
    throw err;
    ^

Error: Cannot find module 'C:\Users\User\Desktop\NodeJsProject\app.js'
```

## 解決策

理由はわからんが、以下のコマンドを打ったらうまくいった

```
$ npm uninstall --save-dev request
$ npm install --save request
$ npm start
```

![スクリーンショット 2020-09-21 15.44.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319526/3f6fa7a9-96fc-375f-be91-faff55aef772.png)

参考
https://stackoverflow.com/questions/53545800/internal-modules-cjs-loader-js582-throw-err
https://qiita.com/TakuTaku04/items/02ff2f4555f705e8c055
AtCoder Beginner Contest 178

過去最低パフォーマンスを計測したコンテストです。
戒めとして記憶に残したいと思います。

##[A - Not ](https://atcoder.jp/contests/abc178/tasks/abc178_a)

```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define pai 3.1415926535897932384
 
using namespace std;
using ll =long long;
using P = pair<int,int>;
 
int main(int argc, const char * argv[]) {
    
    int a;
    cin >> a;
    
    if(a==0) cout << 1 << endl;
    else cout << 0 << endl;
    
    return 0;
}
```

##[B - Product Max](https://atcoder.jp/contests/abc178/tasks/abc178_b)

```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define pai 3.1415926535897932384
 
using namespace std;
using ll =long long;
using P = pair<int,int>;
 
int main(int argc, const char * argv[]) {
    
    ll a, b, c, d;
    cin >> a >> b >> c >> d;
    
    ll Ans = -9223372036854775808;
    
    Ans = max(a*c, Ans);
    Ans = max(a*d, Ans);
    Ans = max(b*c, Ans);
    Ans = max(b*d, Ans);
    
    cout << Ans << endl;
    
    return 0;
}
```
【Angular】VS Codeでデバック 再度書き直し

#【Angular】VS Codeでデバック設定

#前提条件
nodeが動く状態を確認（入ってなければ導入）
npmで拡張できる状態
npmでTypeScriptを入れる
angular-cliを使用していること


##VSコードの権限変更
PowerShell Get-ExecutionPolicy　ポリシーの確認
Set-ExecutionPolicy Bypass -Scope CurrentUser　ポリシーの変更
https://www.gesource.jp/weblog/?p=8203


##launch.jsonの作成

```
{
  "version": "0.2.0",
  "configurations": [
      {
          "type": "chrome",
          "request": "launch",
          "name": "angDebug",
          "url": "http://localhost:4200",
          "webRoot": "${workspaceFolder}"
      }
  ]
}
```

#動かし方
ng serveをコマンドプロンプトかVSで起動する。
VSデバックで先ほど動かしたデバックを実行する。
WEBページが立ち上がるのでブレークポイントが出来てるか確認する

#deployの方法

Apacheのhtdocにdビルドしたデータを入れた
index.htmlのパスを変更した（rootでは無いので）
変更したくないならC:\xampp\htdocsの直下におくと
index.htmlが反応してくれる。

参考資料
https://mosapride.com/index.php/2018/04/12/post-774/
https://qiita.com/jlkiri/items/0e76f31a8af5c12019be
[Rails]flashメッセージの使い方

#はじめに
flashとは、ページ遷移した時に簡単なメッセージを一時的に表示させる機能です。
例えば、ユーザーがログインに成功した時に『ログインできました。』と表示させることで、ユーザーが進行具合を確認できるというものです。

#目次
1 基本的な書き方
2 flashとflash.nowの違い
#1. 基本的な書き方
###コントローラーの編集
flashはハッシュのような形で扱います。

```
flash[:キー名] = “表示さたいメッセージ”
```

キー名はあらかじめ用意せれているnoticeかalertオプションを用います（自分で好きな名前をつけることも可能です）。

例

```controlle.rb
if @outgo.update(outgo_params)
   flash[:alert] = ‘メッセージが’登録されました。’
   redirect_to root_path
else
        ~ 略 ~  
```

###ビューの編集
フラッシュメッセージを表示させたい箇所に下記を記述します。

```
<%= flash[:キー名] %>
```

例

```html.erb
<%= flash[:alert] %>
```

#2. flashとflash.nowの違い
###両者の使い分け
- flashは次のアクションが動いた後のビューファイルにflashメッセージを表示する時（redirect_toを用いた時）
- flash.nowは現在のアクションで表示するビューファイルのみ有効なflashメッセージを表示させたい時（renderを用いた時）

###renderとredirect_toの挙動
- render ：　controller　→　view <br>
コントローラーの直後にビューを表示しています。
-  redirect_to ：　controller　→　URL　→　route　→　controller　→　view <br>
コントローラーの直後に一度ルーティングを経由してビューを表示しています。<br>
なので<br>
flashは最初のアクションが実行された後の1回のみflashメッセージが表示されるのでredirect_toメソッドと一緒に用います。<br>
flash.nowは次のアクションが動く間表示されるのでrenderメソッドと一緒に用います。

#参考リンク
https://pikawaka.com/rails/flash
https://qiita.com/dice9494/items/2a0e92aba58a516e42e9
swingにおける日本語入力時にUIが崩れる不具合と解決方法

# はじめに

ここ最近、swing関連のバグ？に悩まされていました。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/726479/718e9d1f-239f-c8a3-1369-7da707d1a3d0.png)

例えば、このようにJTextFieldやJTextAreaなどのJTextComponent系コンポーネントを用意したとします。
半角英数字を入力する分には特に変わりはないのですが、日本語入力をした途端に、

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/726479/5e6dd881-3c86-b5a0-a4dc-71c4aadef996.png)
<font color="red">$\Huge{な~ん~な~ん~す~か~こ~れ}$</font>

バグにも程があります。

ググってみると`InputMethodListener`を用いてウィンドウの`repaint()`を叩き続ければ良いという解決法を見つけたので、フレームを最小化していない間はコンポーネントへの全角文字入力以降に`while`でフレームの`repaint()`を叩き続けるためのバグ修正用クラスを用意。

<details><summary>バグ修正用クラス</summary><div>

```Java:
final class SwingPaintBugFix extends Thread {
    private Window w;
    private boolean running = true;

    private static SwingPaintBugFix bugfix = new SwingPaintBugFix();

    private SwingPaintBugFix() {}

    private SwingPaintBugFix(Window w) {
        this.w = w;
    }

    public static void of(JTextComponent txtComp, Window w) {
        w.addWindowListener(new WindowAdapter() {
            @Override public void windowIconified(WindowEvent e) {
                bugfix.stopRunning();
            }
            @Override public void windowDeiconified(WindowEvent e) {
                bugfix = new SwingPaintBugFix(w);
                bugfix.start();
            }
        });
        txtComp.addInputMethodListener(new InputMethodListener() {
            @Override public void inputMethodTextChanged(InputMethodEvent e) {
                // 全角文字を受け取る
                bugfix.stopRunning();
                bugfix = new SwingPaintBugFix(w);
                bugfix.start();
            }
            @Override public void caretPositionChanged(InputMethodEvent e) {}
        });
        txtComp.addKeyListener(new KeyAdapter() {
            // 半角文字を受け取る
            @Override public void keyTyped(KeyEvent e) {}
        });
    }

    @Override public void start() {
        new Thread(this).start();
    }

    @Override public void run() {
        while (running) {
            ((Component) w).repaint();
        }
    }

    private void stopRunning() {
        running = false;
    }
}
```
</div></details>

しかしながら、常にwhileで処理を実行し続けるという行為に抵抗感が否めず、すべてのJTextComponent系コンポーネントにバグ修正用クラスを適用するのも手間がかかるため、抜本的な解決策を探ることとしました。

# 原因究明

とりあえず数回再起動しても治らず。

Windows Updateで不具合がでないかどうか確認しながら最新版に更新しても駄目。

「あーめんど」と思いながらも、仕方がないのでセーフモードに。セーフモードでは先程のバグが発生しないことを確認したので、「バッググラウンドプロセス」と「サービス」を控えて通常起動に戻す。

「これでもない、これでもない・・・」と、タスクマネージャーからセーフモード以外のタスクを一つづつ終了させ、ついに原因を特定！

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/726479/6226a5ae-e6c4-162e-17eb-abf535a32efb.png)

「Nahimic Service」というサウンドユーティリティが犯人だったようです。こいつを試しに停止させてみたら見事にバグが直りました。ググってみると、こいつはUI関連以外にもいろいろと競合を起こしているようです。

・・・これならバグ修正クラスなんて作る意味なかったじゃんか。
Petit4SendをLinuxで動かしてみる

## はじめに
QiitaもLinuxも超初心者です。
変なところがありましたら、コメント等で指摘していただけると幸いです。

## 目次
- 環境とか
- 準備
- 手順
- やってみた
- 参考
- 宣伝

## 環境とか
- Manjaro GNOME 20.1
- Wine 5.16
- Petit4Send ver.1.2.2

## 準備
Wineをインストールして、[れいさんのサイト](http://rei.to/petit4send.html)からPetit4Sendをダウンロードします。

Petit4Sendのハードウェア（以降ProMicroと呼びます）とSwitchも手元に用意しておいて下さい。

## 手順
1. ProMicro（PC側）とPCを接続します。
1. ProMicro（Switch側）とSwitchを接続します。
1. 端末に`$ls -l /dev/serial/by-id/`と打ち込みます。
![Screenshot from 2020-09-21 12-56-38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286055/672ae0f2-f675-dd43-e2b0-aee2ababa6a7.png)<br>
LinuxではCOMポートが無い代わりに、**「/dev/tty\*\*\*0」**のような形で識別されるようです。<br>
今回はポートに**「ttyACM0」**が割り振られました。
1. 次に、`$ls ~/.wine/dosdevices -l`と打ち込みます。
![Screenshot from 2020-09-21 13-05-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286055/cea13be4-a668-d980-00ca-41adda779faa.png)<br>
Wine上で、何にどれが割り振られているのかが表示されます。<br>
COM5に先程の**「ttyACM0」**が割り振られていますね。<br>
~~COM6にも同じのが割り振られてるのはよくわかんないです~~
1. 最後に`$sudo chmod 666 /dev/ttyACM0`で**「ttyACM0」**の権限をrwに変更します。<br>
<font color="Red">※再起動すると初期化されてしまうので、接続する度に行う必要があります</font>

## やってみた
![Screenshot from 2020-09-21 13-25-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286055/205a667e-e52f-9f55-5a8e-c81fd5d55175.png)
**動きました！！**
これで毎回WindowsのPCを立ち上げなくて済みます…。有り難や。。

## 宣伝
[SmileBasic4のVSCode拡張](https://marketplace.visualstudio.com/items?itemName=arrow2nd.sb4-extension)を作りました。
![sb4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286055/8e456209-1c93-38f5-9da0-a02e0b6a8fcf.png)
Petit4Sendと組み合わせるといい感じに捗るかもしれません。。。

## 参考
[LinuxPCでserial通信をしようとした話](https://qiita.com/sttn/items/567c9f49b88ff275b51a)
[Linuxで複数のシリアルポートやデバイスを見分ける](http://tclip.blog.fc2.com/blog-entry-86.html)
[Linux MintのWineでCOM1（シリアルポート：RS-232C：/dev/ttyUSB0）を使うには。ーLinuxでIC-PCR1000を使いたい。ー](https://bigmoro.cocolog-nifty.com/blog/2020/01/post-eb2d02.html)
flutterメモ

メモ of メモ。

# 便利補完

```
// stfulと打つと、IDEが下記を生成
class Hoge extends StatefulWidget {
  @override
  _HogeState createState() => _HogeState();
}

class _HogeState extends State<Hoge> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

// stlessと打つと、IDEが下記を生成
class Hoge extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

```

`Auto Format	自動フォーマット	command+option+L`

`同一ワード選択同時編集（sublimeのcmd+D）： ctr+G`

`定義にジャンプする：	⌘B`

# バージョン指定

[Dart - Caret Syntax](https://dart.dev/tools/pub/dependencies#caret-syntax)
> For example, ^1.2.3 is equivalent to ‘>=1.2.3 <2.0.0', and ^0.1.2 is equivalent to '>=0.1.2 <0.2.0’.  

  
つまり

```
firebase_auth: ^0.5.10
```
の場合は、'>=0.5.10'で。'<0.6.0'ということ。


# No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp() in Flutter and Firebase

Firebase.initializeApp()が必要になった。
このstackoverflow見るべし。
https://stackoverflow.com/questions/63492211/no-firebase-app-default-has-been-created-call-firebase-initializeapp-in

#  The method 'findAncestorStateOfType' was called on null
この辺りが参考になった。
- [The method 'findAncestorStateOfType' was called on null in flutter dart](https://stackoverflow.com/questions/60711890/the-method-findancestorstateoftype-was-called-on-null-in-flutter-dart)
- [Why do we need the context to Navigate?](https://medium.com/@rodrigobastosv/why-do-we-need-the-context-to-navigate-68379fc4d1bc)

# [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzao@fe1e944
androidの方で、minsdkversionを21にすると発生。
Firebaseのauthが突然動かなくなって結構ハマった。
この辺かなと思ってみてたが違う模様で、
- [FIREBASE LOGIN NOT WORKING IN FLUTTER ANDROID APP](https://dikaseba.blogspot.com/2020/10/firebase-login-not-working-in-flutter.html)
ここをよくよく見てみると↓
- [W/BiChannelGoogleApi(27734): [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzaq@832113d](https://github.com/FirebaseExtended/flutterfire/issues/352)
- [W/BiChannelGoogleApi(27734): [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzaq@832113d](https://github.com/flutter/flutter/issues/37015)
もしやエミュレータがネット接続できてないのでは、と調べるとビンゴ（前つながってた気がするがどこかできれたのか。）
下記のようにDNS設定すると解決。ふぅ
- [Androidエミュレータがネットワークに繋がらないときの対処](https://kgarage.hatenablog.com/entry/2019/11/11/091205)

# iphone実機にて「“iproxy”は、開発元を検証できないため開けません。」
この辺で対応。
- ["idevicesyslog", "iproxy" や "idevice_id" 等のセキュリティの警告が表示される場合の対処方法](https://flutter.keicode.com/devenv/flutter-on-mac-catalina.php)

# iOS14以上での実機にて。How to change debug mode in Flutter app on iOS 14+ to launch it multiple times
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20014/9471e684-6b76-f1db-3cdc-9a623bece89b.png)
これ見るとOK
https://www.youtube.com/watch?v=3I8yrpXoPok
addEventListenerにより重複している処理を防ぐ方法

動作環境
Ruby 2.6.5
Rails 6.0.3.2

以前、addEventListenerによって同じ処理が何度も発生していたことにより、エラーが起きてしまい、思うような処理ができないことがあったので、投稿してみました。

##addEventListenerにより重複している処理が発生してしまう例

```Ruby:index.html.erb
<% @hugas.each do |huga| %>
  <div class="huga" >    
    <%= huga.content %>
  </div>
<% end %>
```
上記のコードは、hugaのcontentカラムを繰り返し表示させており、その表示されたcontentのclassはhugaであるということを表しています。

```JavaScript:huga.js
function hoge() {
  const hugas = document.querySelectorAll(".huga");
  hugas.forEach(function (huga) {
    huga.addEventListener("click", () => {
    //クリックすることで発生する処理
    });
  });
};
setInterval(hoge, 1000);
```
function hoge()を１行目として、２行目からこのコードの解説をしていきます。
２行目でclassがhugaである要素をすべてhugasに代入しています。
３行目でhugasを１つずつに分けて、それらの名前をhugaとしています。
４行目でhugaをクリックすると５行目の処理を発生するようにしています。
最終行により、以上の動作を毎秒発生させています。

つまり、上記の２つのコードはcontentをクリックすると、huga.jsの５行目に書かれた処理が発生するということを表しています。

しかし、このままではエラーが起きてしまいます。なぜなら、huga.jsの最終行により毎秒２行目と３行目の動作が発生しているからです。それによって何が起こるのかというと、例えばそのページに遷移してから１０秒後にcontentをクリックした場合、５行目の処理が１０回同時に発生してしまうというようなことが起きてしまいます。

この問題を解決するために、この記事のタイトルである「addEventListenerにより重複している処理を防ぐ方法」が必要となります。

※そもそもsetIntervalではなく、window.addEventListener('load',hoge);にすれば良いのではという意見が出ると思いますが、その通りです。しかし、index.html.erbのhuga.contentにおいて非同期通信が使われている場合はsetIntervalを使う必要があります。非同期通信だとページのロードが行われないからです。

##addEventListenerにより重複している処理を防ぐ方法
```javascript:huga.js
function hoge() {
  const hugas = document.querySelectorAll(".huga");
  hugas.forEach(function (huga) {
    if (huga.getAttribute("baz") != null) {
      return null;
    }
    huga.setAttribute("baz", "true");
    huga.addEventListener("click", () => {
    //クリックすることで発生する処理
    });
  });
};
setInterval(hoge, 1000);
```
重複している処理は、上記のコードの４行目から７行目を追記することで防ぐことができる。なぜなら、この追記によって何秒経過してからcontentをクリックしても、１つのhugaには１回の処理しか行わないという意味になるからです。

追記した部分を詳しく解説していきます。
まず、１秒経過すると１回目の処理が行われ、if文によって条件分岐が起きます。hugaはbazという属性(Attribute)は持っていないのでnullとなり、条件式はfalseとなりますが、falseの場合の処理は記載されていないため、そのまま次の処理に移ります。７行目によって、hugaにbazという属性が与えられ、それはtrueとなります。つまり、**１回目の処理は記載する前と変わっていません。**

２秒経過した場合を見ていきます。２秒経過すると２回目の処理が行われ、再度if文によって条件分岐が起きます。１回目と違い、hugaにはbazという属性を持っているため、nullではありません。そのため、条件式はtrueとなり、trueの場合の処理が行われ、return nullが実行されます。return nullとは、処理を抜け出すという意味なので、この記載以降の処理は行われなくなります。つまり、２秒経過してから、contentをクリックしても、**処理が１回しか行われないようになります。**
当然ですが３秒後以降も同じであるため、重複している処理を防ぐことができます。
巨大な桁の足し算

### 1.問題
2つの巨大な桁数(ただし2つの数字の桁数は同じ)の足し算を実行する処理を考える。


### 2.４桁同士の足し算例

巨大な桁数というテーマだったため、下記のように各桁構成が
わかるように図示していく。
PCの性能の許す限り、桁数の制限なく整数として加算できる言語もある(python)が,
そうでない言語の場合は下記のように考えていく必要がある。

&nbsp; 9999
+9998
————-
19997

3桁目までの文字列は前の桁の繰り上がり数と、各桁の足し算の１桁目で構成される事がわかる。
4桁目の足し算では、3桁目の繰り上がり＋4桁同士の足し算の結果を3桁目までの文字列と連結すれば
いい事がわかる。

### 3.コード例(Python:文字列処理をしたもの)

```python

#2つの数字の入力
in1=input()
in2=input()
#入力文字列の長さ
len1=len(in1)
#出力結果文字列
str1=''
#前の桁の繰り上がり状態0:繰り上がりなし 1:繰り上がりあり
p_fugo=0

for i in range(len1):
    c1=in1[len1-i-1:len1-i]
    c2=in2[len1-i-1:len1-i]
    ret=int(c1)+int(c2)+p_fugo
    
    if ret >= 10 and i<len1-1:
        ret=ret-10
        fugo=1
    else:
        if ret<10 and i<len1-1:
            fugo=0
            
    str1=str(ret)+str1
    p_fugo=fugo

print(str1)
```
### ４.コード例(Python:整数として演算)

```python
in1=input()
in2=input()

in3=int(in1)+int(in2)
print(in3)

```

###５．コード例(PHP)

```php
<?php
    // 自分の得意な言語で
    // Let's チャレンジ！！
    //2つの数字の入力
    $in1 = fgets(STDIN);
    $in1 = trim($in1);
    $in2 = fgets(STDIN);
    $in2 = trim($in2); 


    //入力文字列の長さ
    $len1=strlen($in1);
    //#出力結果文字列
    $str1="";
    //前の桁の繰り上がり状態0:繰り上がりなし 1:繰り上がりあり
    $p_fugo=0;

    for($i=0;$i<$len1;$i++){
        if($i>0){
            $c1=substr($in1,$len1-1-$i,1);
            $c2=substr($in2,$len1-1-$i,1);        
        }else{
            $c1=substr($in1,$len1-1-$i);
            $c2=substr($in2,$len1-1-$i);
        }
        $ret=(int)($c1)+(int)($c2)+$p_fugo;

        if($ret>=10 && $i<$len1-1){
            $ret=$ret-10;
            $fugo=1;
        }else{
            if($ret<10 && $i<$len1-1){
                $fugo=0;
            }
        }

        $str1=strval($ret).$str1;
        $p_fugo=$fugo;
    }

    echo $str1;
?>

```

###入力

```
19477493103053478137749318918913894542872478759819
19384757571019848171788474166467574776163353517133
```

###出力結果

```
38862250674073326309537793085381469319035832276952
```