OmniAICreator/Qiita-1.07M huggingface dataset:
Tips: 過去のXcodeをダウンロードする方法


毎回迷っていたのと、以前からだいぶ見た目が変わっていたので記事化

# 過去のXcodeのダウンロードページ

## URL 直接

過去のものをダウンロードしたい場合は以下のリンクです。
サインインが必要です。
検索ボックスに「xcode」と入力することで過去のバージョンを探せます。

- https://developer.apple.com/download/all

![スクリーンショット 2021-10-18 16.30.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63607/7ee83593-1e7c-180f-d099-6404ac95618c.png)

## ページ遷移

以下のページから「その他のダウンロード」=>「コマンドラインツールと以前のバージョンのXcode（英語）」というリンクを探してクリックすれば上と同じXcodeのダウンロードページに飛べました。

https://developer.apple.com/jp/xcode/resources/

またリンクが変わったときに辿るための手順メモの意図です。

## 参考

https://softantenna.com/wp/tips/download-xcode/

## 更新

2025/2/25: この記事の方法で指定のバージョンで Xcode がダウンロードできたことを確認
Core DataのEntityが持つAttributesの初期値は基本GUIで設定して必要だったらawakeFromInsertで記載する

# はじめに

Core DataのEntityが持つAttributesは初期値をXcodeのGUI（.xcdatamodeld)で設定できます。`NSManagedObject`のメソッド`awakeFromInsert`ではInsert時の値を入れることもできるので同じ値を重複して入れることで紛らわしいと感じるかもしれません。

初期値をどうするかはあらかじめ整理しておくと良いのではないかと思ってこの記事を書いてみました。コメントなりでご意見を
ください。

# 最初に結論

基本はデフォルト値をGUIで設定し、どうしても必要だったら重複する値を`awakeFromInsert`で設定する。

- awakeFromInsertで設定する初期値
    - SHOULD
        - insert時に計算したい固定値でLight Weight Migrationで追加しない最初からあるAttributes
            - 例
                - UUID().uuidString
                - Date()


# 前提

- XcodeのGUIからはデフォルト値を決められる
    - DBマイグレーション時に新規にAttribute（カラム）が増やされたらこのデフォルト値が詰められる
- `awakeFromInsert`メソッドはデフォルト値ではなくinsert時の値をまとめられる
    - DBマイグレーション時に新規にAttribute（カラム）が増やされてもinsertではないためこの値は使われない


# 実例

```swift
class MemoEntity: NSManagedObject {    
    // 最初から存在した値達 ---
    @NSManaged var id: String
    @NSManaged var createdDate: Date
    
    // Light Weight Migrationで追加された値達 ---
    @NSManaged var isDeleted: Bool // どうしても必須なものを追加。これはGUIで設定。awakeFromInsertだけでは駄目
    @NSManaged var body: String? // 基本的には必須感でなくていいならOptionalでいい
}
```


```swift
    override public func awakeFromInsert() {
        super.awakeFromInsert()
        // 最初から存在し、計算した値を入れたい
        id = UUID().uuidString // GUIからはUUID生成なんてできない。GUI上には空文字列""を入れる
        createdDate = Date() // GUIから現在日付は入れられない。GUI上には適当な日付を入れる

        isDeleted = false // 書かないでほしい。GUI上で設定必須なのにさらにコードで書いてしまい双方の値が異なる場合はまぎらわしい 👎
        // body: Optionalなので必要がなければ何も設定しない 👍
    }
```

# その他

Appleのサンプルコードを見るとすべてOptionalになってて参考にならないですね。Optionalにしてもいいんだけど、利用側がそこで値がnilの場合にどんなハンドリングしたらよいかわからないので、型のレベルで表現してあげるほうがミスも迷いもなくシンプルだと思うんですが。

サンプルの"LoadingAndDisplayingALargeDataFeed"から引用

![スクリーンショット 2021-10-18 15.52.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16400/5acf5beb-b6b7-8699-25df-ae47485870ca.png)
【初心者向け】 企業で活躍できるエンジニアになるためのロードマップ②　デプロイ編

##目的

**未経験の人、プログラミング初心者　が
「企業で活躍できるエンジニア」 「どこでも成長できるエンジニア」**


↓に移動しました！

https://sg-report.com/loadmap2/
等価演算子と型変換

# 「等価演算子」と「厳密演算子」
JavaScriptでは、2つのオペランドが等しいか比較するための等価演算子が「**等価演算子(==)**」と「**厳密等価演算子(===)**」の2種類ある。
**等価演算子**：オペランド同士の値が同じの場合、true
**厳密等価演算子**：オペランド同士の同じ型、同じ値の場合、true
ここで、**等価演算子**はオペランド同士が異なる型の場合、比較する際に同じ型に<font color="Red">暗黙的な型変換</font>されてから比較される。

```javascript
// 同じ値だが型が異なる場合
console.log(1 == '1');      // true
console.log(1 === '1');     // false

// 真偽値の場合
console.log(0 == false);    // true
console.log(0 === false);   // false
```

#「暗黙的な型変換」と「明示的な型変換」
暗黙的な型変換とは、**ある処理において、その処理過程でオペランドの型によって、自動的に型変換されること。**

```javascript
// 暗黙的な型変換
console.log(1 + true);    // 2
```
上記のように、**ture**が**1**に暗黙的に型変換されて加算が行われる。


一方で、明示的な型変換を行う場合は、以下のようなコンストラクタ関数を使う。

```javascript
// 値から真偽値
Boolean(1);      // true
Boolean(null);   // false

// 数値から文字列
String(100);     // "100"
String(true);    // "true"

// 文字列から数字
Number("100");   // 100
```

#まとめ
等価演算子と型変換について調べてまとめてみた。
等価演算子の場合、暗黙的な型変換によって意図しない結果になってしまうことがある。
暗黙的な型変換が行われると、例外が発生しないため、バグの発見が難しくなる。そのため、暗黙的な型変換はできるだけ避けるべきであり、比較には厳密等価演算子を使うべきだと学んだ。

## 参考
[https://jsprimer.net/basic/implicit-coercion/](https://jsprimer.net/basic/implicit-coercion/)
marp-cliをWindowsに導入してPDF出力させる

Windows 10 + vscodeにmarpを導入するときの自分用メモ．

Marp for VS Codeを導入

https://github.com/marp-team/marp-vscode

このままでは，PDF出力の際にローカルのファイルを取り込まないので，marp-cliを導入してこちらでコンパイルさせる．

https://github.com/marp-team/marp-cli

scoopを導入して，そこからインストール．

```
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
scoop install marp
```

ターミナルで以下を打ち込む．

```
marp --pdf --allow-local-files hogehoge.md
```

参考
- https://qiita.com/takeshisakuma/items/5a61e6eac123d28602fb
サーバーって...？

# 記事を書くきっかけ
　最近サーバー寄りの勉強を始めたはいいものの、そもそもサーバって何？という前提知識があやふやだったのでまとめてみました。

# 目次
- サーバーとは
- サーバーの種類
  - コンピューターサーバー
     - 物理サーバー
         - 共用サーバー
         - 専用サーバー
     - 仮想サーバー
         - VPS
         - クラウドサーバー
  - ソフトウェアサーバー
     - Webサーバー
     - メールサーバー
     - ファイルサーバー
     - データベースサーバー
     - DNSサーバー
     - アプリケーションサーバー
     - FTPサーバー
- まとめ
- 参考

## サーバー (server) とは
　利用者(クライアント)の要求(リクエスト)に対して、それに応じたデータを提供するコンピューターやプログラムのこと。
　簡単に言えば、「インターネットを通じてパソコン等にサービスを提供する専用のコンピューター」のことを指します。
　私たちが使っているPCと同様に、サーバー用のコンピューターにソフトウェアサーバーを入れることで機能を果たします。

## サーバーの種類
　一概にサーバーと言っても、大きく分けてコンピューターサーバーとソフトウェアサーバーがあり、さらにコンピューターサーバーには物理サーバーと仮想サーバーがあり、ソフトウェアサーバーにも...

　という具合に色々と種類があるようなので1つ1つ簡単に紹介します。笑

## コンピューターサーバー
### 物理サーバー
　物理サーバーは物理的に存在するサーバーのこと。
#### 共用サーバー
　共用、つまりレンタルサーバーのこと。1台の物理サーバーを、複数の利用者でシェアして利用する。
**メリット**
　・専門知識不要
　・コストを抑えられる

**デメリット**
　・設定などカスタマイズできない
　・他の利用者の使用状況によって処理に影響が出る可能性がある

#### 専用サーバー
　物理サーバーを1台レンタルするため、企業や個人で自由に使うことができる。
**メリット**
　・様々なOSやアプリケーションをインストールしてカスタマイズできる
　・他の利用者の影響を受けない

**デメリット**
　・サーバーの運用や構築も自分でしなければいけない
　・コストがかかる

### 仮想サーバー
　1台の物理サーバーで複数のOSを動かすことで、複数のサーバーと見なして稼働させる仕組みのこと。

#### VPS
　VPS(Virtual Private Server)：仮想の専用サーバー
**メリット**
　利用者1人1人に対して環境が仮想上に構築されるため
　・様々なOSやアプリケーションをインストールしてカスタマイズできる
　・他の利用者の影響を受けない

**デメリット**
　・仮想サーバーの運用やセキュリティ対策を自分でしなければいけない

#### クラウドサーバー
　クラウド環境に作られたサーバーのこと。
**メリット**
　・サーバーの機能を自由に拡張することができるため、機能の自由度が高い
　・従量課金制なので導入費が発生せず、導入のハードルが低い

**デメリット**
　・専門的な知識・スキルが必要
　・従量課金制のため、VPSや専用サーバーより利用料金が高くなる場合が多い

## ソフトウェアサーバー
　ここからはソフトウェアサーバーについて紹介します。
### Webサーバー
　Webサイト運営に必須のサーバー。
　WebサーバーにはWebページをクライアントに表示する上で必要であるHTMLファイルやCSSファイル、画像ファイルなどが納められている。
　Webサーバーは、格納されたWebページの情報をクライアントに要求された時に取り出して送る。

### メールサーバー
　メールの送受信サービスを提供するサーバー。
　送受信で別々のサーバーになっており、
　　送信側：SMTPサーバー
　　受信側：IMAP,POP3サーバー
　という。
　メールを送信するときには、SMTPサーバーがDNSサーバーと協力して宛先を割り出し、送信される。IMAPやPOP3サーバーには利用者ごとに割り当てられたメールボックスがあり、送信されたメールはこのメールボックスに入る。

### ファイルサーバー
　ネットワーク上でデータを共有・使用するためのサーバー。
　複数のサーバーおよび様々なOSのクライアントPC間でのデータ共有をスムーズに行うことができる。

### データベースサーバー
　クライアントからのリクエストに応じて、データベース上にあるデータを送り返すためのサーバー。
　データベース管理システムを使って、データの整理している。

### DNSサーバー
　DNS（Domain Name System）
　IPアドレスとドメインを結びつけるためのサーバー。
　　IPアドレス：Web上の住所
　　ドメイン：独自のWebサイト名
　IPアドレスをドメイン名に変換することで、表示させたいWebサイトにアクセスできるようになっている。

### FTPサーバー
　FTP（File Transfer Protocol）
　Webサーバーとのファイルの送受信を行なうサーバー。FTPはファイル転送プロトコルとも呼ばれる。
　リクエストがある場合のみにファイルを送信するWebサーバーと異なり、FTPサーバーはクライアントがコンピュータからサーバーにデータをアップロードしたり、サーバーからデータをダウンロードしたりすることができる。

# まとめ
　あまり理解できていなかったサーバーについて、私たちが扱っているPCと本質は似ていることや、様々な種類があることを知ることができた。サーバーについての概要は理解できたので、実際に操作できるよう今後勉強していこうと思う。

# 参考
https://www.rworks.jp/system/system-column/sys-entry/16259/

https://www.internetacademy.co.jp/trends/it-strategy/what-is-server-introductory.html
メモ: UnityEditor内のAndroid NDK を利用する

公式ドキュメント

https://docs.unity3d.com/ja/2020.3/Manual/android-sdksetup.html

UnityEditorの主に2020以降 [^1] ではUnityインストール時にモジュールで「Android Build Support（Android SDK & NDK Tools、OpenJDK）」を指定できる。
Android SDK, Android NDK, Gradle, OpenJDK がインストールされる。

[^1]: 2019.4のときにも含まれていた。詳しいバージョンはリリースノートにて

それぞれUnityに限定せず利用できる。

ネイティブライブラリビルドの時に利用している。

```bash
export ANDROID_NDK_ROOT=${UnityEditorインストールパス}/PlaybackEngines/AndroidPlayer/NDK

# ex: Unity Hub でインストールした Unity 2020.3.4f1 の場合
export ANDROID_NDK_ROOT=/Applications/Unity/Hub/Editor/2020.3.4f1/PlaybackEngines/AndroidPlayer/NDK
```

SDK もある。

```bash
${UnityEditorインストールパス}/PlaybackEngines/AndroidPlayer/SDK

# ex: adb を利用
/Applications/Unity/Hub/Editor/2020.3.4f1/PlaybackEngines/AndroidPlayer/SDK/platform-tools/adb
```

Gradle、バージョン確認で見ていた。

```
/Applications/Unity/Hub/Editor/2020.3.4f1/PlaybackEngines/AndroidPlayer/Tools/gradle/lib/gradle-launcher-5.6.4.jar
```


Unity の環境設定 => 外部ツールでパスを確認できる。

![image_2022_2_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63607/e1e49087-aa06-d7dd-ab44-041e778ae48c.png)

ローカルでもCIでもインストールがかんたんになってうれしい。
GitHubのソースコードから自動学習して提案してくれるAIプログラミング機能「GitHub Copilot」について

**■GitHub Copilotとは**

・Open AIのcodexで開発

・GitHubにあるcodeのデータ学習させ　コメント、関数名でコードを提示してくれる

・コーディングの自動補完機能と似ている

・AIっていうけど、新しく作成っていうより、既存の似たようなコード探してくれるイメージが強い

・今後有料になる予定

※著作権の問題があるコードも出る可能性があるみたい


<br>
**■使用申請**

・現在テストで使うためには事前申請が必要

・２週前に申請したんだけどまだ。。（人が多くなかなか時間かかるみたい）



申請後VScodeで利用できる（承認前は使えない）
![image2021-10-18_11-32-0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2123165/523e2600-911e-8252-c95b-68495b6ecea4.png)



**■公式サイト**

https://copilot.github.com/


<br>
**■ひとこと**

単純なコーディングには結構使えて作業のスピードアップにつながるかと。
M1 MacでiOSアプリをXcodeから走らせる

## M1 MacでiOSアプリをXcodeから走らせる

M1 MacでiPadアプリが動かせるようになって、iOSアプリの新たなプラットフォームとなりました。
基本的にはほとんどiPadと同様の動きのようですが、一部そうではないようです。

#### iPadで問題なく動作するのにM1 Macでは死ぬ

iPadで問題なく動作するのにM1 Macでアプリがクラッシュする事象が発生しました。
私がクラッシュに直面したのは以下のコードです。

```swift
let appearance = UIToolbarAppearance()
if #available(iOS 15.0, *) {
	self.toolbar.scrollEdgeAppearance = appearance // ここで死ぬ
}
```
どうやらUINavigationControllerのツールバーにsetScrollEdgeAppearance:というセレクタが無いことが原因のようです。
このコードの解決策は

```swift
let appearance = UIToolbarAppearance()
if #available(iOS 15.0, *) {
	if (!ProcessInfo.processInfo.isiOSAppOnMac) { // macOSじゃないよ
		self.toolbar.scrollEdgeAppearance = appearance
	}
}
```
でした。

#### ProvisioningにM1 MacのiPad環境をどう含める？

XcodeからM1マックでdebugする際に少し手間取りました。
Apple DeveloperサイトにM1 MacのハードウェアUUIDを登録していたので、iOSアプリのDevelopment Provisioningにデバイスを追加しようとしたのにDevicesの欄にM1 Macの名前が現れません。
実はMacのシステムレポートのハードウェアUUIDの下にプロビジョニングUUIDというものがあって、これをApple Developerサイトにデバイスとして登録しないとならないようです。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f33313639362f31333062323462612d613565302d363933382d353061302d6431666633633536643138612e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31696/a75d3977-70f6-acc7-06a8-c7d9bdf46d73.png)



以下の画面で
Platform は iOS, tvOS, watchOS、
Device Name は適当な名前、
Device ID(UDID) は先程のプロビジョニングUUID
をそれぞれ入力します。
![register_device.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31696/28a617fa-03ac-628b-e0a4-fdbcbce73286.png)

iPodとして登録されるんですね。

これで目的のiOSアプリのプロビジョニングの編集画面のDevices一覧に出現しますので修正登録して、ダウンロードしてXcodeのプロジェクトに登録してやると、XcodeからM1 Macを実行対象デバイスとしてビルド・デバッグが可能となります。
WordPressのNinja Formsのメール文の入力欄を縦長にする

入力フォームを簡単に設置するWordPressプラグイン「Ninja Forms」のメール文の入力欄が狭いので、縦長に調整したい。

https://ninjaforms.com/

実際の画面
![スクリーンショット 2021-10-18 15.30.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522445/548a65f8-3827-bd9f-24ae-216790dc2ce0.png)
これだと5行くらいしか表示されずに見づらいし、拡大しても画面を切り替えるたびに狭い範囲に戻る。

毎回下のバーを伸ばせば拡大できるが、それすらも手間がかかってしまうのが課題。

## プラグインを編集して解決

プラグインのCSSファイルを編集すれば解決。

WordPress管理画面から
→プラグイン
→プラグインエディター
→「編集するプラグインを選択」から「Ninja Forms」を選択
→assets
→css
→summernote.cssを開く

`ninja-forms/assets/css/summernote.css`を開いたら一番下に以下のコードを書いて保存すれば完了。

```css
.note-editing-area .note-editable{
    height:800px!important;
}
```
＊例として800pxにしましたが、実装する際はメール文の長さに応じて自由にカスタマイズしてください。

## WordPressのお役立ち情報

https://wagtechblog.com/programing/wordpress-school

https://wagtechblog.com/programing/php-school
【Draft.js】Entity

# Entityとは
- [ContentBlock](https://qiita.com/y-hira18/items/d0449b6370abc617e8a6) の `text` のメタデータを表す要素
- [ContentState](https://qiita.com/y-hira18/items/1acf13d44a71c5d8fd36) の `entityMap` にエンティティの数分格納されている

## Entityに格納される情報
### type
- どのような種類のエンティティであるか
  - デフォルトで用意されている `type` は下記の通り
      - LINK
      - TOKEN
      - PHOTO
      - IMAGE
  - 上記以外に自作の `type` も定義可能
- `type` に対してレンダリングするReactコンポーネントを指定可能

### mutability
- エンティティオブジェクトでアノテーションされたテキストの範囲をエディタ内で編集する際の動作を示す
  - 下記の3つを指定可能
      - MUTABLE  
      `text` からエンティティアノテーションを削除しなければ編集不可  
      **（例）** 画像、メンション
      - IMMUTABLE  
      `text` を自由に編集可能  
      **（例）** テキストリンク
      - SEGMENTED  
      基本的には `IMMUTABLE` と同じだが、削除時の挙動をカスタマイズ可能

### data
- エンティティのメタデータ  
  **（例）** `LINK` エンティティの場合、`a` タグの `href` に渡すurlを持つ  
  `{ url: "https://example.com" }`
stripe+connectのクーポン機能の仕様確認メモ

# このドキュメントの目的

stripe+connectでクーポン機能を実装するにあたってクーポンの挙動をメモ。connectが絡むとプラットフォーム手数料の扱いがどうなるかなど気になったのでそこを重点的に

# 検証の条件

- connect
- stripe elements
- ディスティネーション支払いでプラットフォーム手数料をユーザーからとっている形
- subscription

# プラットフォーム手数料について

クーポンで割引した際のプラットフォーム手数料の計算は下記記事の通り。


>application_fee_percent の計算方法については、このシナリオを検討してください。

>請求サイクルのサブスクリプションコストが 30 USD。
次のインボイスに 10 USD のインボイスアイテムがある。
50% のクーポンが適用される。
application_fee_percent は 10。
このケースでは、プラットフォーム手数料の合計は 2 USD: (30 USD + 10 USD) x 50% x 10% です。

https://stripe.com/docs/connect/subscriptions#calculating-application-fee-percent

全体からまずクーポンで割引されてそこからプラットフォーム手数料の計算が入る。

# クーポンの挙動

下記条件で挙動を検証

- ユーザーに対して下記のクーポンを適用
- subscription
- 無期限に割引

## 適用範囲

>後から追加するサブスクリプションを含む、顧客のすべての継続支払いを常に割引したい場合を除いて、顧客ではなくサブスクリプションにクーポンを追加することをお勧めします。

https://stripe.com/docs/billing/subscriptions/coupons

以前契約したsubscriptionも含めこれからの決済全てが割引される。

## 優先度

>サブスクリプションに適用されるクーポンは、顧客に適用されるクーポンよりも優先されます。

https://stripe.com/docs/billing/subscriptions/coupons

## 途中でクーポンを削除した場合

>クーポンを削除しても、適用される割引がサブスクリプションまたは顧客から削除されるわけではありませんが、そのクーポンは今後のサブスクリプションまたは顧客に適用されなくなります。

https://stripe.com/docs/billing/subscriptions/coupons

ちょっとわかりにくいが「適用される割引」というのは適用された割引で支払いが完了しているものはもちろん変更されない。ただsubscriptionの次の決済は割引なしになる。

## 複数のクーポンは適用できるか

複数はできない

## 途中でクーポンの割引率など条件を変更できるか？

- クーポンの条件は変えられず、名前しか変更できない
- 新しいクーポンを作成し、違うクーポンに変更するのは可能

# 参考資料

stripeクーポンドキュメント

https://stripe.com/docs/billing/subscriptions/coupons
npm経由でfirebase cliをM1Macにインストールしてもエラーになる

# はじめに
なんかエラーになるんだけど、日本語で直接言及しているのが見当たらなかったのでメモ

# 解決方法
Node16にあげてからインストールしてください。
14系は駄目でした。

以上！
GitHub featureブランチを作成し、Pull Request

#【GitHub featureブランチを作成し、Pull Request】

基本は[GitHub Flow](https://qiita.com/haruki_uejima/items/5d8e1bf2a80c4720d85c)。（自分の過去記事です。）

##featureブランチ作成と作成後の流れ
※ 何か作業をする時は、予めfeatureブランチを作っておく。
　→　最初からファイルをgit管理化に置くことでPush時のミスや手間を減らす。

```
# 現在のブランチを確認
git branch

# mainブランチの最新を取得する。
git checkout main 
git pull

# featureブランチを新規に作成し、切り替える。（一度に実行する場合）
git checkout -b feature/（任意ブランチ名）

# サブディレクトリも含めて、ファイルをアップ
git add .

# ローカルリポジトリへコミット
git commit -m "コミットメッセージ"

# featureブランチをoriginへ反映
git push origin feature/（任意ブランチ名）

# GitHubのmainリポジトリに向けて、Pull Requestを出す。
# ここで修正箇所を指摘された場合、修正して、再度feature/（任意ブランチ名）にpush
# （Pull Requestの内容も自動的に更新される。）
```

### git status

```
# 「git status」 で表示される内容を、-sオプションを付けて短く表示する。
git status -s
# -bオプションも付けると現在のブランチが表示される。
git status -sb

# 実行例
# 「git add」 されているが、「git commit」 されていないファイル
M  aaa.txt
# 「編集、変更、削除」されているが、「git add」 されていないファイル
 M bbb.txt
# 「Gitによって追跡」、「.gitignoreによって無視」されていないファイル
?? ccc.txt
```

##自分の過去記事、備忘録

- ブランチ、マージ、コンフリクト
    - [GitHub ブランチとマージについて](https://qiita.com/haruki_uejima/items/a0de7da67de2c1ca473f)
- GitHub Pull Request
    - [GitHub プルリクエスト](https://qiita.com/haruki_uejima/items/a862c4093126f509a086)
Swiftの@unknown defaultを理解する

Swift 5で追加されたswitch文で使える`@unknown default`の旨味が最初、全然分からなかったが、実例を通じて使い方と意図を掴んだ気がするので知見として広めたい。

### swiftのswitch文の良さは網羅性を言語レベルで担保できる
swiftのswitch文は全てのcaseを満たすようなコードを書かないとコンパイラーエラーになり、実装漏れを気づかせてくれる優秀な言語機能だと思っています。
なのでなるべくdefault文は使わずに全てのcaseを書いておくようにしていました。

### `@unknown default`の良さがいまいち分からなかった
- ウィジェットのサイズパターン分けで`@unknown default`を使った方が良いとの警告が出てたが、「網羅性担保できなくなるだろうがぁ:triumph:」と思って全部case書いていた
![スクリーンショット 2021-09-28 17.39.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147358/81ac63ea-3eda-d85d-228f-227e61b09c99.png)


- 将来のバージョンで追加されるって警告は出てるけれど、それはその時対応するよって思ってた

### iOS15で早速追加された
- `.systemExtraLarget`(iPad専用)のケースが追加された。

- 軽率にcase追加だぁとやったが、そうすると古いXcodeでコンパイル出来なくなってしまう。
特にXcodeのメジャーバージョンリリース直接などの過渡期は困る。

- そこで`@unkonwn default`の出番
![スクリーンショット 2021-09-28 17.40.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147358/ec019913-1a74-1b32-b63c-d459814e07de.png)

- 下位互換を保ったまま対応できます。ただ、完全なる網羅性を保っているわけではないので`Switch must be exhaustive`の警告が残り続けてくれる。
これは人やプロジェクトによって好みが分かれるかもしれません。警告が把握しきれていないほど出ている場合は見落としてしまう気がしますので、プロジェクト内で決まりごとを決めておいた方が良さそうです。


## `@unknown default`を使うか否かの線引
主にenumの管理者によって変わると思っています。
#### 自分たちで管理しているenumのswitch文
- 全てcase文を書いて実装漏れを防ぐのが基本
- caseを追加しているという事は意図が明確でまさにunknownなcaseではないはずだから

#### 自分たちの管理外のenum(3rd Party製ライブラリやApple公式ライブラリ etc...) 
- swiftのアトリビュートに`@frozen`が付いていないもの(つまり将来case追加予定があるenum)
- 未知の値にどういった処置をとるか明確は場合に`@unknown default`を使用
- ホントの意味のデフォルトの挙動ならdefaultでもいい
Vue.js を 1 年半くらいやった男が最近 React を始めたので Vue.js の印象を振り返る

# はじめに

はじめまして。
Vue.js を ( いわゆる ) Options API が半年、Composition API ( v2 系 ) が 1 年くらいやってきました。期間はだいたいです。
そんな私ですが、直近のチームの既存資産が React だったこともあり、( 以前、少し触ったことはあるものの ) ついに React に足を踏み入れました。
ちなみに、Angular は AngularJS 時代に結構書いてましたが、遠い過去の話なので忘れた & 世代間で全く別物らしい　ので、今はあまり興味がありません。

Vue 書きの視点から書き連ねていきます。

# Vue.js の良いところ

SFC (Single-File Component) によって、プレゼンテーションとロジックが同一ファイル内で別々に記載できるのはめちゃくちゃ良いところだと思います。
ロジックだけでなく、HTML/CSS を書くのが好きなエンジニアにとって、とても嬉しい部分。
これは Options API だろうが Composition API だろうが関係なく使える、Vue.js の好きなところです。

## Options API

Options API は非常にとっつきやすいです。
悪い言い方をすると、あまり "プログラミングができなくても" 書くことができます。
ですが、これは逆に言えば、アプリケーションを作成したい多くの人に対しての障壁が低いことを意味します。

コンポーネントのあらゆるデータが、大いなる一つのコンテキストに直接ぶら下がるので、データや処理の流れを強く意識しなくて済みます。
SFC としてのイメージがつきやすく、コンポーネントに必要なデータは "ぶら下げていく" ような感覚で書けるので、「このファイルはこういうコンポーネントを実装してるものだ」というのが、あまりプログラミングに慣れていない人でも脳味噌大爆発せずにコーディングできるような気がします。

簡単でシンプルであるというのは、技術を選ぶ上で重要なことです。

## Composition API

[以前書いた記事](https://qiita.com/les-r-pan/items/65c680417dfaf22f1eef)にも挙げましたが、

1. template で利用している変数が追いやすくなる
1. 処理の分割・カプセル化・共通化・外部化がしやすくなる
1. TypeScript のパワーが発揮される

かな、と思います。

コンポーネント自体のコンテキストと切り離された機能を書くことができるため、独立した何者か (オブジェクト) の状態とそれにまつわる処理を閉じ込めることができます。
これにより、再利用性が高まり、コードにも流れや文脈を表現できるようになるので意図が伝わりやすくなります。

また、純粋関数を切り分けるモチベーションも保てます。
「純粋関数でできることは純粋関数に任せる」というコードは、シンプルな機能が増えるため、読みやすく、テストも容易にします。
そして、そういった "テスト" に相当する部分の多くが、「TypeScript で書いていれば勝手に TypeScript が担ってくれる」状態になります。
Options API でもできますが、「大いなるコンテキストに紐づいた沢山のデータ」を実装していると、切り分けるのが面倒くさくなるシチュエーションが多々発生します。体感的な問題ですが。

# Vue.js の悪いところ

## Options API

一つは、TypeScript の恩恵が受けにくい。
そして、もう一つは大きく複雑化したコンポーネントの改修・分割・リファクタを困難にする、という点だと思います。
「この computed って、いじったらこっちに影響しないかな・・・」とビクビクしながらコードを触ることになります。

## Composition API

まず、一番は、"良いところ" で挙げた内容に「？」となってしまう人にとっては初学のハードルが非常に高いという点があります。
「簡単でシンプルであるというのは重要なこと」ですが、そのトレードオフとなります。
ただ、私はもう「Options API で書く」という選択肢は取れないと思います。
それほどまでに vs Opstion API では優位な点が多いです。

次に、Composition API は Reactivity オブジェクトの取り扱いが面倒くさい。
こちらも[以前書いた記事](https://qiita.com/les-r-pan/items/65c680417dfaf22f1eef)でも触れましたが、Reactivity が意図せずに途切れたり、UnwrapRef に泣かされたり、( Ref は ) `.value` を意識しないといけません。めっちゃ面倒です。

また、無理やり Compositon API のコーディングに対応したためか、Vue が提供しているコアな機能であっても `setup()` のコールスタック外の定義で使えない ( コンテキストエラーかなんかになる ) ものがあったりします。

そして、最後の悪いところは、これらの良いところ・悪いところの多くが「React Hooks 使えばよくね？」で済みそうな点です。


# おわりに

Composition API をやっていたという下地があるというのは大きいですが、今のところ React ( Hooks ) やってて Vue ほど「なんでやねん」になることが多くない印象です。まだ歴は浅アサですが。
`useState` が代入による状態の変更を許さないというのも良い部分だと思います。

もうちょっと React 詳しくなったら印象も変わるかもしれません。
認識等に誤りがあれば、優しくご指摘いただければ幸いでございます 🥺

そんな感じです。
ポエムをご覧いただきありがとうございます。

おしまい。
4.6 (標準) 二変数確率変数の変数変換2 一様分布に従う確率変数の和，積 (畳み込み)

## 方針

```math
\begin{align}
\begin{cases}
Z=X+Y\\
W=XY
\end{cases}
\end{align}
```

という変換では一対一にならない (X=,Y=,と一意に書けない) ため，Z,Wそれぞれを畳み込みで求める．それぞれの定義域に注意．

## 答案

```math
\begin{align}
\begin{cases}
Z=X+Y\\
V=Y
\end{cases}\Leftrightarrow
\begin{cases}
X=Z-V\\
Y=V
\end{cases}
\end{align}
```

なる一対一変換を考える．

```math
\begin{align}
f_{Z,V}(z,v)&= f_X(z-v)f_Y(v)\\
\therefore f_Z(z)&= \int f_X(z-v)f_Y(v)dv,\ \ \ (0<v<1,0<z-v<1)
\end{align}
```

zの値によって積分範囲が変わるため，場合分けして求める．0<z<1の時，0<v<zより

```math
f_Z(z)=\int_0^zdv＝z
```

1<z<2の時，z-1<v<1より，

```math
f_Z(z)=\int_{z-1}^1dv=2-z
```

次に，

```math
\begin{align}
\begin{cases}
W=XY\\
U=Y
\end{cases}\Leftrightarrow
\begin{cases}
X=W/U\\
Y=U
\end{cases}
\end{align}
```

なる一対一変換を考える．

```math
\left|\frac{\partial (X,Y)}{\partial(W,U)}\right|=\left|\begin{pmatrix}
1/u & -w/u^2\\
0 & 1
\end{pmatrix}\right|=\frac{1}{u}
```

なので，

```math
\begin{align}
f_{W,U}(w,u)&= f_X(\frac{w}{u})f_Y(u)\frac{1}{u}\\
\therefore f_W(w)&= \int f_X(\frac{w}{u})f_Y(u)\frac{1}{u}du,\ \ (0<\frac{w}{u}<1,0<u<1)
\end{align}
```

ゆえ，w<u<1であるから，

```math
f_W(w)=\int_w^1\frac{1}{u}du=-\log w
```

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
Google SheetsでGoogle Formsの回答を別のシートから参照する方法

## Sheetsの参照がずれてしまう

Google Formsの回答を集計したり校正したりするとき、回答が蓄積されていくGoogle Sheetsの「**フォームの回答1**」シートを直接編集するのではなく、別のシートから解答を参照して複製したシートを作り、その上で作業することが多いと思われます。
その際に、単純な参照ではずれてしまうことがあります。

||A|B|C|
|-|:-|:-|:-|
|**1**|タイムスタンプ|メールアドレス|好きな果物|
|**2**|2021/10/01 01:00:23|taiyo@taiyo-hoge.com|メロン|

上のようなシートを複製する際に、以下のように参照してしまうと、回答が増える時に参照範囲がずれてしまいます。

||A|B|C|
|:-|:-|:-|:-|
|**1**| =‘回答シート!A1‘ | =‘回答シート!B1‘ | =‘回答シート!C1‘|
|**2**|=‘回答シート!A2‘| =‘回答シート!B2‘| =‘回答シート!C2‘|
|**3**|=‘回答シート!A3‘| =‘回答シート!B3‘| =‘回答シート!C3‘|
|**4**|=‘回答シート…| …|…|

## ソリューション
まずソリューションを書きます。
Formsの回答を参照するシートには```=‘フォームの回答1’!A1```や```= ‘フォームの回答1’! $A$1```のように参照するのではなく、[INDIRECT関数](https://support.google.com/docs/answer/3093377?hl=en)を用いて```=INDIRECT('フォームの回答1'!A1)```と書きましょう。

## なぜINDIRECT関数を使うのか

Google Formsから書き込まれる回答は行を置き換えるのではなく、新たな行を作って挿入されているため、「$」による絶対参照を使っても、関数から参照する行はずれてしまいます（実際には行がずれているのではなく、参照範囲の上に回答が挿入されています）。

例えば冒頭の例で3行目に2件目の回答が追加されると、参照している関数は以下のようにずれてしまいます。

|**3**|2021/10/01 01:00:24|taiyo@taiyo-hoge.com|マロン|
|-|:-|:-|:-|

||A|B|C|
|:-|:-|:-|:-|
|**1**| =‘回答シート!A1‘ | =‘回答シート!B1‘ | =‘回答シート!C1‘|
|**2**|=‘回答シート!A2‘| =‘回答シート!B2‘| =‘回答シート!C2‘|
|**3**|=‘回答シート!**A4**‘| =‘回答シート!**B4**‘| =‘回答シート!**C4**‘|
|**4**|=‘回答シート…| …|…|

これを回避するためにINDIRECT関数を用いてみました。参照すべきセルが文字列になるので、Google Sheetsが参照先を追跡することもありません。

||A|B|C|
|:-|:-|:-|:-|
|**1**|=INDIRECT('フォームの回答1'!A1)|=INDIRECT('フォームの回答1'!B1)|=INDIRECT('フォームの回答1'!C1)|
|**2**|=INDIRECT('フォームの回答1'!A2)|=INDIRECT('フォームの回答1'!B2)|=INDIRECT('フォームの回答1'!C2)|
|**3**|=INDIRECT('フォームの回答1'!A3)|=INDIRECT('フォームの回答1'!B3)|=INDIRECT('フォームの回答1'!C3)|
|**4**|=INDIRECT('フォームの回答...|...|...|

CSVで大量に作っておけば安心して作業を行うことができるでしょう。Google SheetsのImportは部分置き換えにも対応していますしね。
Unityでシーン遷移する

#はじめに
この記事は、Unityで複数のsceneを切り替える手順を説明したものです。

#環境
Unity 2019.4.17f1

#ポイント
sceneを追加するには、Hierarchyじゃなくて、ProjectタブのAssetsの中に追加する。それだけでは足りなくて、Build SettingのScene In Buildingに作ったSceneをD&Dで追加する必要がある。編集対象を切り替えるには、Assetsの各sceneをダブルクリックで、選択すればよい。

シーン変更コマンドは、
SceneManager.LoadScene("xxxxx");

ただし、冒頭にこれを書く必要がある。
using UnityEngine.SceneManagement;


#手順
１、Assetsにあるデフォルトのシーンファイルをscene1に名前変更する。
２、新規にscene2を作成する
３、スクリプトtoScene2と、toScene1を作成し、内容を下記に変更。
４、scene1に適当なボックスを作成し、toScene2.csをアタッチ。
５、scene2に適当な球を作成し、toScene1.scをアタッチ。
６、Build SettingのScene In Buildingにscene2も放り込み、２つのシーンがある状態にする。
７、実行して、スペースキーで、切り替わりを確認する。

```cs:toScene2.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;//追加

public class toScene2 : MonoBehaviour{
    void Start(){
    }

    void Update(){
        if (Input.GetKey(KeyCode.Space)) {
            SceneManager.LoadScene("scene2");
        }
    }
}
```

```cs:toScene1.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;//追加

public class toScene1 : MonoBehaviour{
    void Start(){        
    }

    void Update(){
        if (Input.GetKey(KeyCode.Space)) {
            SceneManager.LoadScene("scene1");
        }
    }
}
```
numpy.randomでの乱数生成が変わった（っぽい）

kaggleをしていると見慣れない関数のpartyが夜通し開催されています。
その中で、numpy.randomでの乱数生成の方法が少し変わったぽいので忘れないうちに書いておきます。

# 従来
例えば、整数をランダムに呼び出したいなら```np.random.randint(n, m)```みたいな感じでした
正規表現なら```np.random.normal（loc=u, scale=s）```みたいな感じでした（loc: 平均, scale:標準偏差）

# 現在
[https://numpy.org/doc/stable/reference/random/generator.html](https://numpy.org/doc/stable/reference/random/generator.html)

一応従来の方法も使えるんで、早急な対応が必要というわけでもなさそうですが、現在のnumpy側の推奨は

- np.random.default_rng()でインスタンス化
- このインスタンスから欲しい乱数を定義

という流れになったそうです。

## 簡単なコード例
```
print(np.random.normal(loc=10, scale=0.5))

rng = np.random.default_rng(seed=123)
print(rng.normal(loc=10, scale=0.5))

rng = np.random.default_rng()
print(rng.normal(loc=10, scale=0.5))

>>>10.498672723291794
>>>9.505439324826074
>>>9.296869256963326
```

ってな感じ。

個人的にはどっちが良いって言うのはないですが、インスタンス化の方が少しコードがスッキリしそうな気もします
ebitenで走査線シェーダーを作ってみた

　ebitenのシェーダーで「走査線シェーダー（昔のブラウン管テレビの走査線を模倣する）」を作ったので、メモ代わりで公開します

　走査線処理的には、Windows版餓狼伝説MOWのドットの境界線を走査線で強調するパターンです

```golang
package main

func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
	if int(position.y) % 3 != 0 {
		return imageSrc0At(texCoord)
	}
	
	var clr vec3
	clr.r = imageSrc0At(texCoord).r * 0.5
	clr.g = imageSrc0At(texCoord).g * 0.5
	clr.b = imageSrc0At(texCoord).b * 0.5
	
	return vec4(clr, 1.0)
}
```

　ファミコンの頃の像解度をNintendo Switchで表示すると３×３倍になるので、「% 3」のmod処理で余りを調べて、Y軸で３ドットずつ走査線処理を行ってます

###### おまけ：進化版シェーダー

　ブラウン管はレーザー光線で表示していたため、画面が明るく、ぼやけてます。それを追加した現在のシェーダーは

```golang
package main

func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
	col := imageSrc0At(texCoord)
	
	// ボカシ
	var x,y float
	
	x = texCoord.x / position.x	// 1dot当たりのテクセル数
	y = texCoord.y / position.y
	
	colA := imageSrc0At(vec2(x * 0.5 + texCoord.x - x, y * 0.5 + texCoord.y))
	colB := imageSrc0At(vec2(x * 0.5 + texCoord.x    , y * 0.5 + texCoord.y - y))
	colC := imageSrc0At(vec2(x * 0.5 + texCoord.x + x, y * 0.5 + texCoord.y))
	colD := imageSrc0At(vec2(x * 0.5 + texCoord.x    , y * 0.5 + texCoord.y + y))
	// x * 0.5、y * 0.5はドットの中心へずらしている
		
	col.r = (((colA.r + colB.r + colC.r + colD.r) * 0.25 * 0.25) + col.r * 0.75)
	col.g = (((colA.g + colB.g + colC.g + colD.g) * 0.25 * 0.25) + col.g * 0.75)
	col.b = (((colA.b + colB.b + colC.b + colD.b) * 0.25 * 0.25) + col.r * 0.75)
	
	// 走査線とブラウン管
	var clr vec3
	if int(position.y) % 3 != 0 {
		// ブラウン管なので明るい
		clr.r = col.r * 1.5
		if clr.r > 1.0 {	// 数値は1.0まで
			clr.r = 1.0
		}
		clr.g = col.g * 1.5
		if clr.g > 1.0 {
			clr.g = 1.0
		}
		clr.b = col.b * 1.5
		if clr.b > 1.0 {
			clr.b = 1.0
		}
		
		return vec4(clr, 1.0)
	} else {
		// 走査線
		clr.r = col.r * 0.5
		clr.g = col.g * 0.5
		clr.b = col.b * 0.5
		
		return vec4(clr, 1.0)
	}
}
```
となります。1dot当たりのテクセル数の求め方は、とりあえずの物で今後、変更するかも知れません

　物理学的には光線の波長のエネルギーは単純な四則演算で足す事や引く事が出来るので、掛け算で光線を強めるアンプの処理が可能になります
move_baseを停止させる

# はじめに

ROS Navigationのmove_baseにrvizからゴールを送った後に、動作中に停止したいことがあります。その時に停止する方法をいくつかまとめました。

# 環境
Jetson XavierNX
Ubuntu 18.04

# 方法

## 1. cmd lineから

```
rostopic pub /move_base/cancel actionlib_msgs/GoalID -- {}
```

(参考)https://answers.ros.org/question/57772/how-can-i-cancel-a-navigation-command/

## 2. pythonから (その1)

### 動作確認環境

- python 2.7.17

### ソースコード

```python:stop.py
#!/usr/bin/python

import rospy

import actionlib
from move_base_msgs.msg import MoveBaseAction

rospy.init_node("stop_move_base")

client = actionlib.SimpleActionClient('move_base', MoveBaseAction)
client.wait_for_server()
client.cancel_all_goals()
```

## 3. pythonから (その2)

### 動作確認環境
- python 2.7.17
- python 3.6.9

### ソースコード

```python:stop.py
import os
os.system("rostopic pub /move_base/cancel actionlib_msgs/GoalID -- {}")
```
【レアケース】Let's Encryptのルート証明書の切り替えができていなかった場合の対処法

9月末でLet's Encryptのルート証明書が切り替わり、ISRG Root X1というものに変わりました。
それに伴ってサーバーの方も確認しなければならなかったのですが、直前にca-certificatesのアップデートが来てたのでてっきり新しいルート証明書に対応していると思ってました。

いざLet's Encryptを使ったサイトにwgetでアクセスしたらエラーが。

ということでいくつか試して解決するかやってみました。

# 旧ルート証明書を無効化する
一番ベターな方法です。普通は、これがca-certificatesのアップデート時に行われているはずです。
ブラックリストに入ってるはずなので `/etc/ca-certificates.conf`を見てみます。

```conf:ca-certificates.conf
!mozilla/DST_Root_CA_X3.crt
```

ちゃんと「！」が付いているので無効化されていました。
それにISRG Root X1も追加されてました。
それなのにおかしい。

# 証明書ファイルを消してみる
解決できなかったので、straceコマンドでwgetがどんな挙動をしているか見てみました。
すると、

```
stat("/usr/local/ssl/certs/8d33f237.0", 0x7ffecc263f40) = 0
```

というログがあって、なにかのルート証明書を読み込んでいることが分かりました。
これが何なのか調べます。opensslコマンドで確認します。

```shell
$ openssl x509 -text -noout -in /usr/local/ssl/certs/8d33f237.0
```

なんとDST Root CA X1でした。なぜか読み込まれています。
このようなケースは稀と見られます。

ということで古いルート証明書を削除して、証明書ストアを更新します。

```shell
$ sudo rm /usr/local/ssl/certs/8d33f237.0
$ sudo update-ca-certificates
```

# 解決

再びwgetでletsencrypt.orgにアクセスできるか試したところ、うまく行きました。
今回は極めてレアケースであったため記事にしましたので、参考になればと思います。
Windowsのコンソールのバッファリング解除

---
### 結論

Console.ReadKey()メソッドか使える。

---
### Windowsのコンソールのバッファリングについて

netcatとかUNIX/Linuxのコマンド履歴が記録できるscriptコマンドのようなシェルのラッパーなどのコンソールプログラムを開発するうえで、時折問題になるのが、Windowsのコンソールでは、**キー入力を「リターン」キー入力まで**バッファリングしてしまいプログラムにまで落ちてこないこと。
(まぁ、これはこれで使い勝手が有効な場面もあるのだけど・・・)

.NET FrameWorkでは、Console.ReadKey()メソッドがあるので、バッファリングなしでキー入力を取得したい場合に使えますよ。...ということ。

```c#
while (true) {
 ConsoleKeyInfo info = Console.ReadKey();
 Console.Write(info.KeyChar);
}
```

結果は、こんな感じで**「Hello」**と入力したのだが、キー入力と同時に出力されていることからバッファリングされていないことが分かる

```
C:\>ConsoleApp1.exe
HHeelllloo
```

---
### その他

多分、他の方法もあるとは思う。

---
### 以上
おまけ: LiveViewでエラー通知編【Sentryを使ったElixir/Phoenixアプリのエラー監視】

[fukuoka.ex](https://fukuokaex.connpass.com/) の koyo です！
前回Sentryを使ったElixir/Phoenixアプリのエラー監視を紹介しましたが、今回はおまけとして、LiveViewで実装したSPA経由でエラー通知し、さらにGmail通知されるという仕組みを作ってみます！

https://qiita.com/koyo-miyamura/items/52cd7732e745281b30f7

# エラー通知ボタンを作る
前回まで Gmail 通知できるようになりました。
せっかく Phoenix + LiveView を使っているので、 `Web画面上のButtonクリック -> Sentry -> Gmail` をSPAで行う仕組みを作ってみましょう！ 

Buttonを押したらLiveViewでハンドリングしてSentryに通知するコードを書いてみます！
差分は以下です↓

https://github.com/koyo-miyamura/sentry_sample/commit/8d5ca6e7bf5156e62f90db083ef7f9da80044baf

## 動作確認
ここにボタンがあるじゃろ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201242/471552e9-109c-ccec-3241-f9ef57aed27b.png)

ぽちっとな！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201242/b9a489af-8457-3602-966e-506c1d62dd22.png)

SentryやGmailに通知が来てますねb
やったね！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201242/18f81d5a-11c3-1f86-00b3-e0bd39b2db4c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201242/8ceb71bd-cf7a-626f-d0c2-c30f0d5a87cb.png)
PuttyにてAWSへの接続メモ

以前PuttyにてAWSでEC2を接続して動作させていて
サービス終了後にDNSは動作していた気がする……
と思ってもう一度動作させるメモ表記失礼いたします。


なんかコンソールにログインして
インスタンス見てみると”実行中”ってあるから
Puttyで接続したいんだよな……

C:\Users\hoge\Desktop\memo\ssh鍵
にソレっぽいのがあるけどコレが秘密鍵かな？？？
clasp login時エラー

clasp login時以下のエラー表示。

```shell
node[3450]: ../src/api/callback.cc:125:void node::InternalCallbackScope::Close(): Assertion `(env_->execution_async_id()) == (0)' failed.
```

nodeのバージョンが
v.16.2.0だったのを
現在の安定版
v.14.18.1
にしたら解決。
https://nodejs.org/en/download/

### 参照

https://qiita.com/Hide-Zaemon/items/cbb4497237843a729994
[正規表現]関数の引数を正規表現で置換する

#複数ある関数の引数を置換したい。

何千もある関数の引数を置換したい時に便利な正規表現のgrep置換、こちらを記述します。

```

kansuの第二引数がhogeだったらキャスト追加
(kansu\s*?\(\s*?.*?\s*?,\s*?)hoge
↓
$1(int)hoge

kansuの第三引数が"hoga"だったらキャスト追加
(kansu\s*?\(\s*?.*?\s*?,\s*?.*?\s*?,\s*?)hoga
↓
$1(int)hoga

kansuの第一引数が"homa"だったらキャスト追加
(kansu\s*?\(\s*?)homa
↓
$1(int)homa
```

1つずつ精査していくと
(kansu\s*?)
↑kansuの後にくる文字列が空白を含んでいる場合でもって感じの意味合いです。
\(\s*?)
↑最初の\は(を文字列としてみます。(エスケープ)
 \s*?は(の後にくる文字列が空白を含んでいる場合でもって感じの意味合いです。
.*?
↑ 左端から始めて、最初にマッチするものの表現です。
,
↑一つの引数の場合は必要ないですが、第二引数以上の置換をしたい場合は記述します。
あとは括弧をとじて置換したい文字列を記述すれば、置換前の文字列の完成です。

置換後を精査します。
$1
↑(kansu~~~)の括弧をそのまま保持しますよって意味合いです。置換後の文字列は(int)hogeです。
Mac上のRubyコードからクリップボードを操作する

Macで動くRubyスクリプトを書いていて、処理結果を直接クリップボードに格納したいケースがあった。（Rubyの処理結果をコピペしたかった）

macOSでは、`pbcopy`と呼ばれるクリップボード保存用システムコマンドが用意されていて、

```shell-session
$ echo 'piyo' | pbcopy
```

のように文字列をパイプでpbcopyに渡すことで、クリップボードに文字列を格納することができる。

一方Rubyスクリプトでは、バックスラッシュで囲まれたコードをシステムコマンドとして実行できる：

```ruby
str = 'piyopiyo'
`echo #{p str}`

=> "piyopiyo\n"
``` 

これらをまとめると、Mac上のRubyコードからクリップボードを使うことができる：

```ruby
str = 'piyopiyo'
`echo #{p str} | pbcopy` # クリップボードにstrが入る
```
[AtCoder][ABC130D] しゃくとり法の解説


競プロでよく使われるテクニックの１つである「しゃくとり法」について解説する
[ABC130 D - Enough Array] (https://atcoder.jp/contests/abc130/tasks/abc130_d)

## 問題

配列における連続する部分列の和がK以上になるような組み合わせの数を求めよ

例えば下記の配列AとKを考える。
A = [6 1 2 7], K = 10

単純に考えると２つのポインタ(left, right)を用意してポインタ間の部分列がK以上になるかどうか確認するとO(n^2)の計算量で計算できる。

1. (left=0, right=0) sum = 6
2. (left=0, right=1) sum = 6 + 1 = 7
3. (left=0, right=2) sum = 6 + 1 + 2 = 9
4. (left=0, right=3) sum = 6 + 1 + 2 + 7 = 16 ★ここで初めてKを超えるのでans+1
5. (left=1, right=1) sum = 1
6. (left=1, right=2) sum = 1 + 2 = 3

（省略）

コードで書くと下記のようになる。

```cpp
int ans = 0;
for (int left=0; left<n; ++left) {
    int sum = 0;
    for (int right=left; right<n; ++right) {
        sum += A[right];
        if (sum >= K) ans++;
    }
}
```

## しゃくとり法

上記問題をよく考えると無駄な部分がある。
部分列の和は単調増加なので、sum(left, right)がK以下であればsum(left+1, right)もK以下となる。上記で5と6の部分はあきらかにK以下となるので省略可能。

よってleftを更新するたびにrightをleftの位置まで戻す必要がなく、rightは前回の位置からの再開で問題ない。

1. (left=0, right=0) sum = 6
2. (left=0, right=1) sum = 6 + 1 = 7
3. (left=0, right=2) sum = 6 + 1 + 2 = 9
4. (left=0, right=3) sum = 6 + 1 + 2 + 7 = 16 ★ここで初めてKを超えるのでans+1
6. (left=1, right=3) sum = 1 + 2 + 7 = 10 ★ans+1
7. (left=2, right=3) sum = 2 + 7 = 9
7. (left=3, right=3) sum = 7

コードで書き直すと下記のようになる。
rightポインタとsumの関係がややこしくなるが、半開区間をイメージすると整理できる。sumを計算した後は必ずrightポインタを進める。

```
sum = [left, right) = leftからright-1までの合計
```

```cpp
int sum = 0;
for (int left=0; left<N; ++left) {
    while (right < N && sum+A[right] < K) {
        sum += A[right];
        right++;
    }
    ans += N - right;
    sum -= A[left];
}
```

## 関連問題

[典型90 034 - There are few types of elements] (https://atcoder.jp/contests/typical90/tasks/typical90_ah)
Git管理下のファイルをtag指定して取得しアーカイブ

Git管理下のファイルを、git管理用のファイルを除いて取得しアーカイブ(zip等)で入手するには「git archive」が便利

```
[prompt] # git archive --format=tar --prefix=一時格納するディレクトリ名/ 入手対象(タグ|コミットID|ブランチ名) リポジトリ名 | gzip > アーカイブファイル名.tar.gz;
```
【Dockerエラー】An HTTP request took too long to complete.

##環境
Docker version 20.10.7
docker-compose version 1.29.2

##状況

```docker-compose　up -d```や```docker-compose　down```を実行すると下記のエラーが出る

```
ERROR: for XXX  UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)
ERROR: An HTTP request took too long to complete. Retry with --verbose to obtain debug information.
If you encounter this issue regularly because of slow network conditions, consider setting COMPOSE_HTTP_TIMEOUT to a higher value (current value: 60).
```

##解決法
Docker Desktopを再起動するだけ！
月間売上100万、ユーザー数が600人を超えたサービスがStripe connectを導入して感じたこと

## ISSUEに単価表の記事を追加しました
https://i-ssue.com/topics/de478ab0-b0d1-4449-a8ff-0d4c8f403896

## はじめに

サービス立ち上げから、徐々にトラフィックが増えてきました。
そこで少しでも運用の知見をアウトプットしたく、今回はStripeを実装した決済代行について書き連ねて見ようと思います。

決済システムのようなsensitiveな部分は運用してはじめてわかる部分が多いと思うので、これから決済代行システムの比較検討をしている方々のお役に立てればいいなと思います。

## 今回利用したStripe製品

[Stripe connect](https://stripe.com/jp/connect)です。
マーケットプレイスに適した決済サービスになります。APIを使えば即時決済やグローバル決済など幅広い決済に対応することもできます。
私が運営しているサービスもエンジニアと企業をマッチングさせるプラットフォーム型になるので、今回はStripe connectを利用しました。

![名称未設定.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658704/fec5d795-49db-71e9-4d4d-7680e2f85b31.jpeg)


## Stripeの利用メリット

### 導入前

#### 導入コスト、審査期間がないので導入しやすい
他決済代行サービスと違い、導入に当たっての初期費用やプラットフォーム利用の審査期間がありません。
サービスの構想ができてすぐに開発したいとなったら、すぐに実装できてしまいます。

#### 公式ドキュメントが公開されていているので、他サービスと比較検討がしやすい

Stripeの公式ドキュメントは公開されています。

[**公式ドキュメント**](https://stripe.com/docs)
[**APIドキュメント**](https://stripe.com/docs/api)

公式ドキュメントを導入前に確認できるのは実装イメージが湧くので大きいです。
他決済代行サービスでは審査などを通過後に確認できることが多いです。
「スピード」に焦点を当てたときに差が出てきますね！


### 導入後

#### あらゆる操作を自動化できる

私は今回決済処理以外にも下記内容を自動化しました。

- **送金**(エンジニアへの売上の送金)
  - 最初は手動入金をしていましたが、トラフィック数が増えるにつれて人的ミスを防ぐために自動化しました。
- **手数料**(プラットフォーム手数料)
  - プラットフォーム手数料を毎回計算して送金処理をするのはかなり大変です。
- **本人確認**
  - Stripe connect(custom)を利用する場合に必要になります。([参考](https://stripe.com/docs/connect/identity-verification))


### 運用してみてつまずいたところ

#### 本人確認が必要になった
サービス開始当初は問題なかったのですが、customアカウントの取引額もしくはアカウントが作成されてから一定時間経った後にcustomアカウントが制限されて売上の入金処理ができなくなりました。([参考](https://stripe.com/docs/connect/testing-verification#testing-thresholds))

本人確認APIを利用して、stripe側に本人確認画像データをアップロードして対応しました。
![スクリーンショット 2021-10-16 21.49.20（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658704/2a902bfc-8f89-ef30-c59f-0134db9cb905.png)


#### 振り込み名義が変更できない

振り込み名義が「ストライプジャパン」になってしまいました。これはまだ解決できていません。。
変える方法知っている方がいれば教えてください。

![iOS の画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658704/9aa5b720-66af-1a7e-7997-770d951c0f32.png)

### 運営がするオペレーション

現状ありません！
あなたの貴重な時間を他の作業に当てられるように自動化しておきましょう。


### 実装工数

**2週間**ほどです。(8時間/日)
最初は手動送金、その後自動化などの実装手順だったのでおおよその足掛け工数になります。

### 所感

#### あらゆる決済操作を自動化できる

やはりここが大きいです。特にCtoCなど、トラフィックが大量に見込まれる場合は手数料や送金などの自動化は必須になってくるでしょう。

#### マネタイズがしっかり固まってない場合はStripeのダッシュボードから手動決済でもいい

散々自動化と言ってきましたが、マネタイズがしっかり固まっていない場合はいきなりStripeを実装せず
Stripe管理画面からの手動決済でもいいと思います。

検証段階を終えて、マネタイズが固まってから自動化の方が余計な実装をしなくて済みます。

#### ドキュメントだけ見て全て理解するのは結構難しい(特に送金や入金周り) 

公式ドキュメントはとても充実しているStripeですが、全てをそれだけで把握するのは難しいと思いました。
特に原文が英語のものを日本語に直してるので読みにくい箇所がある。。

まずはサンドボックスなどでも触ってみて、運用してみるのがいいと思います！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658704/99588134-fda6-8a69-b5d8-849af2958710.png)
https://i-ssue.com/

エンジニアの副業やフリーランス、スキルアップについての情報発信してるのでフォローしていただけると励みになります！
[@twinsdevelopper](https://twitter.com/twinsdevelopper)
eclipseでgitにタグ付け

eclipseでGitのタグ付けするには「Gitリポジトリパースペクティブ」を使用する
![Gitリポジトリの操作.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77448/7d992edb-3b8b-7d6c-f2af-cfd0adcd6697.jpeg)
右クリックでペインを開けばタグ作成が可能
![タグの作成.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77448/bb64f065-3b69-3f39-bfb4-1bcc1bcae6c9.jpeg)
タグ名、説明を入力して作成・プッシュすればOK
![タグを作成してプッシュすればタグ付けOK.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77448/786bd0d9-5f59-0866-f900-edd2ba5ee464.jpeg)
【Github】 Pullリクエストがgithubで表示されない

<h1>まずはじめに</h1>

Cloud9からgithubにpushをしたのに、
なぜかpull requestが表示されない...?!

なぜ？といった状況になってしまった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1810522/a16df3a3-a491-d3a8-1290-4bd52aa67693.png)

この状況をどうやって解決するか簡単に解説していきます！

<h2>解決方法</h2>

解決方法はいたって簡単です。

まず、Pull requestタブを押した後に、右上に緑の New pull requestがあるので
そこをぽちっとクリックしましょう。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1810522/cd684c3a-94bd-c18c-5572-17324e37226f.png)

するとどういうわけか、
過去にpull requestの通知が来なかった git pushの一覧が表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1810522/eb6fc957-2a0e-8f8b-ed5c-c6227ae736eb.png)


該当のpullリクを選択しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1810522/c735a01c-58dd-e7f1-8f6c-6331722da7ac.png)

するとこんな感じでいつもの画面がでてきます。

あとはいつも通りプルリクを進めればOKです。

<h2>まとめ</h2>

・githubにpushしてもpull requestが出ない場合がある
・pull requestが出ない場合はNew pull requestを押す
・通常のプルリク画面になるのであとはマージ等を行う

いかがでしたでしょうか。
分りづらい等ありましたらコメントくださいね。

それでは！
【Swift】入力フォームで入力金額から手数料を引いた額を自動算出して表示

Swiftを使って、入力フォームで入力金額から手数料を引いた額を自動算出して表示させる機能を実装。

イメージとしてはメルカリの出品画面のように、売値を入力すると、手数料を引いた売上額が自動で算出＆表示される機能。

今回は入力フォームライブラリ「Eureka」を使用。

https://github.com/xmartlabs/Eureka

## Eurekaを導入

Eurekaの導入は以下の記事を参照してください。

https://qiita.com/ShinokiRyosei/items/3090290cb72434852460

https://wagtechblog.com/programing/swift-eureka.html

http://swift.hiros-dot.net/?p=448

導入が終わったらswiftファイルでimportします。

```swift
import Eureka
```

## 入力フォームで入力金額から手数料を引いた額を自動算出して表示


次にフォームのコードをviewDidLoad内に入力します。

```swift

class ViewController : FormViewController{

    var profit : Int?

    override func viewDidLoad() {
        super.viewDidLoad()
        form
        +++ Section("金額")
            
        <<< IntRow(){ row in
            row.title = "金額"
            row.value = 0
            self.profit = row.value ?? 0
        }.onChange({ [unowned self] row in
            self.profit = row.value ?? 0  
            let real = Int(round(Double(self.profit ?? 0) * 0.9) - 300)
            let PrefRow = form.rowBy(tag: "real_profit") as! LabelRow
            PrefRow.value = String(real)
            PrefRow.reload()
        })
        <<< LabelRow(){ row in
            row.tag = "real_profit"
            row.title = "手数料を引いた金額"
            let real = Int(round(Double(self.profit ?? 0) * 0.9) - 300)
            row.value = String(real)
        }
    }
}

```

IntRowとLabelRowを用意し、IntRowが変更されるごとにonChangeが呼び出され、LabelRowの表示内容に反映させる仕組み。

onChange内でLabelRowのtagを呼び出し、valueを変更し、reloadしている。

また今回計算している手数料は入力金額の1割から300円引いた額。

round関数を用いて少数第1位を四捨五入し、整数になるように表示しています。


## Swiftのお役立ち情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html
FullCalendar.jsを使ってカレンダーFlaskアプリを作る


FullCalendar.jsを使って簡単にカレンダーFlaskアプリを作る方法をまとめました。


#### 最終形態
![2021101802.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192434/a3b1d27b-9155-b555-4792-f42fcd9f41f7.png)



### Flaskのセットアップ
##### 1. **app.py**を作成
```python/app.py
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def home():
    return render_template('index.html')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)
```

##### 2. **templates**フォルダーを作成し、フォルダー内に**index.html**を作成
```html/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>Flask Calendar App</h1>
    <a href="/calendar">Calendar</a>
</body>
</html>
```

##### 3. **app.py**にカレンダーページを表示させるRouteを追加
```python/app.py
@app.route('/calendar')
def calendar():
    return render_template('calendar.html')
```

##### 4. **templates**フォルダー内に**calendar.html**を作成
```html/calendar.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    
</body>
</html>
```

### FullCalendar.jsの導入
##### 5. **calendar.html**にfullcalendarを追加 
```html/calendar.html
<head>
    (snip)
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fullcalendar@5.5.0/main.min.css">
    <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.5.0/main.min.js"></script>
</head>
<body>
    <div id="calendar"></div>
    <script>
        let calendarEl = document.getElementById('calendar');

        let calendar = new FullCalendar.Calendar(calendarEl, {});

        calendar.render();
    </script>
</body>
```

##### 6. `flask run`を走らせ、ローカルリンクにアクセス
以下のように表示されれば:thumbsup:
![2021101801.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192434/356d2156-07da-3c62-d5c7-4c690186ffc6.png)


### イベントの追加
##### 7. **app.py**内にeventsのvariableを作り、calendar routeに渡す
```python/app.py
events = [
    {
        'title': 'event1',
        'date': '2021-10-15'
    },
    {
        'title': 'event2',
        'date': '2021-10-20'
    }
]

(snip)
@app.route('/calendar')
def calendar():
    return render_template('calendar.html', events=events)
```

##### 8. 以下のコードを**calendar.html**に追加し、イベントを追加
```html/calendar.html
let calendar = new FullCalendar.Calendar(calendarEl, {
    events: [
    {% for event in events %}
    {
        title: '{{ event.title }}',
        start: '{{ event.date }}',
    },
    {% endfor %}
    ]
});
```

##### 9. `flask run` を走らせ、確認
以下のように表示されれば成功！
![2021101802.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192434/212fa1e7-5631-ea14-4ad0-f476049ee995.png)


##### プロジェクトコード
[https://github.com/risatoy/demo-flask-calendar](https://github.com/risatoy/demo-flask-calendar)
条件分岐で学んだこと10/18


```js
public class Main { 
  public static void main(String[] args) {
    int isHungry = 1;
    String food = "魚";
    System.out.println("こんにちは");
      if (isHungry== 0) {
        System.out.println("お腹がいっぱいです");
      } else {
        System.out.println("はらぺこです");
      }
      if (isHungry == 1) {
        System.out.println(food + "をいただきます");
      }
      System.out.println("ごちそうさまでした");
    }
}
```
<h2>三項演算子でシンプルに描く</h2>
```js
int isHungry = 1;
String food = "魚";
System.out.println("こんにちは");

System.out.println(isHungry == 0 ? "お腹いっぱい" : "はらぺこです");
System.out.println(isHungry == 1 ? (food + "をいただきます") : "ご馳走さま");
```


```ruby:結果
こんにちは
はらぺこです
魚をいただきます
```
<h3>キーボードから整数を受け取る</h3>
```js
int input = new java.util.Scanner(System.in).nextInt();
```
<h3>文字列受け取る</h3>
```js
String s  = new java.util.Scanner(System.in).nextLine();
```
<h3>ランダムで数字入れる</h3>
```js
int r = new java.util.Random().nextInt(10);
```

```js
System.out.print("【数あてあそび】");
		int ans = new java.util.Random().nextInt(10);
		for (int i = 0; i < 9; i++) {
			System.out.print("数字をいれてください");
			int num = new java.util.Scanner(System.in).nextInt();
			if(ans==num) {
				System.out.print("あたり");
				break; //数一致で終了する動き
			}else {
				System.out.print("ハズレ");
			}
		}
}
		System.out.print("終わり");　//for文繰り返しブロックの外で表示させる
```
<h2>拡張for文で書く</h2>
```js
int[] moneyList= {1111,2222,4444};
		for(int i =0;i<moneyList.length;i++) {
			System.out.println(moneyList[i]);
		}
		for(int m: moneyList) {
			System.out.println(m);
		}
```

```ruby:それぞれ結果
1111
2222
4444

```
交差するはしご問題（Crossed Ladders Problem）の整数解

### 交差するはしご問題 (Crossed ladders problem)
Wikipediaの英語版にある[Crossed ladders problem](https://en.wikipedia.org/wiki/Crossed_ladders_problem)ですが日本語訳がないので日本ではあまり馴染みのないかもしれません。幅がwで壁で挟まれた道路に長さがaとbのはしごをかけたときhを求めよという問題です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1922159/1f966882-1893-3706-e275-1da2aaf1c501.png" width=50%>

### この問題の整数解

[Wolfram MathWorldにも同様の記事](https://mathworld.wolfram.com/CrossedLaddersProblem.html)がありますがここにとても**興味深い記述**があります。変数の書き方が違いますが、要はすべての辺が整数になっているということです。今回はそれは他の例を探したいと思います。

> これらの解の中に l_1, l_2, h_1, h_2, h だけでなく、d_1やd_2も整数となるものがあります。一つの例は(l_1,l_2,h_1,h_2,h,d_1,d_2)=(119,70,105,42,30,40,16)です。

### 【問題】 0<a<b<300 の時a, b, A, B, w, h, wa, wb (wをhの垂線で分割したもの)　がすべて整数のものを、列挙せよ。
#### ステップ.1 ピタゴラス数 

直角三角形で辺が整数ということで、
1. 基本ピタゴラス数を発生させていきます。これについては参考コードがたくさんあると思いますので説明省略します。
2. 基本ピタゴラス数を整数倍して三角形の長辺がN未満のものをすべて作ります。
3. 直角を挟む２辺を片方をKeyにしてDICTに加えてリストにします。これによってwをしていしたとき、AとBの候補が分かります。例えばw=16の時は[12,30,63] が候補なのでここから２つ選ぶ組合せは[12,30], [30,63],[63,12]となるので、これをA,Bとして整数判定を行います。
コードは以下のようになります。

```python
from collections import defaultdict
import itertools, math
## Generate Pythagorean triple
def pyth():  
  for m in itertools.count(2):
    for n in range(1,m):
      if (m%2)==(n%2): continue
      if math.gcd(m,n) != 1: continue
      yield m*m - n*n, 2*m*n, m*m + n*n

N = 300
ptall = defaultdict(list)
g = pyth()
for _ in range(N):
  t = next(g)
  for i in range(1,(N-1)//t[2]+1): # Multiples up to N
    t1 = (t[0]*i,t[1]*i,t[2]*i)
    for j in range(2):             # Add to dict (both small edges)
      ptall[t1[j]].append(t1[1-j])
print(len(ptall), ptall[16])
# 159 [12, 30, 63]
```
#### ステップ 2. hを求めて整数判定を行う

前出のWikiからhを求めるのは以下の式があります。hの整数判定を行った後、wa, wbを求めて整数判定を行えば完了です。

> $\Large\frac{1}{A}+\frac{1}{B}=\frac{1}{h}$
> $\Large h =\frac{A*B}{A+B} $

```python
count = 0
for w in ptall.keys():
  if len(ptall[w]) < 2: continue
  for A, B in itertools.combinations(ptall[w],2): 
    if (A*B) % (A+B) == 0:     # check h is integer
      h =  (A*B) // (A+B) 
      if w*h % A == 0 and w*h % B ==0: #check wa, wb are integers
        wa, wb = w*h//A, w*h//B
        a = int(math.sqrt(w**2+A**2))
        b = int(math.sqrt(w**2+B**2))
        count += 1
        print(count, ":", a, b, A, B, h, w, wa, wb)
#1 : 70 119 42 105 30 56 40 16
#2 : 104 296 40 280 35 96 84 12
#3 : 140 238 84 210 60 112 80 32
#4 : 175 119 140 56 40 105 30 75
#5 : 210 182 126 70 45 168 60 108
```
このコードを走らせると答のすべて整数となる組み合わせは5個あることが分かります。（1と3のように相似形のものを含んでいます）

ちなみにProject EulerのProblem 309: Integer Laddersはwa, wbが整数はもとめてないのでその判定を除いたものになります。
GETメソッドとPOSTメソッドの違い

<dl>
<dt>初めに</dt>
<dd>初学者として勉強を進めていく上で違いをはっきりと理解することが難しかったため、自分の理解を深める為にも記事にしたいと思います。
私と同じ初学者の方でGETとPOSTの違いがよくわからないという方の助けになれば嬉しいです。</dd>
</dl>

<dl>
<dt>GETとPOSTの使い道</dt>
</dl>
<dl>
<dt>GET</dt>
<dd>指定されたリソースを取り出す際に使う。</dd>
<dｔ>具体例</dｔ>
<dd>・見たい商品の詳細</dd>
<dd>・同様のページが何ページにも渡る場合の特定のページ番号</dd>
<dd>→見たい商品や動画などのWebページのURLを指定することで、HTMLファイルがWebサーバーからブラウザに返されて表示ができる</dd>
</dl>
<dl>
<dt>POST</dt>
<dd>Webページで入力されたリソースをWebサーバーに送り特有の処理をさせたい際に使う。</dd>
<dｔ>具体例</dｔ>
<dd>・ログイン画面に入力するメールアドレスやパスワード</dd>
<dd>・画像ファイル、音声ファイル、その他のファイルなど</dd>
<dd>→フォームに入力された内容がWebサーバーに送られ、データベースに登録される</dd>
</dl>

<dl>
<dt>GETの特徴</dt>
<dd>・リクエストとして送信されるデータはURLに含まれる </dd>
<dd>　⚪︎「URL?パラメータ名=値」という形式 </dd>
<dd>　⚪︎「?」パラメータのはじまり</dd>
<dd>　⚪︎「&」パラメータの切れ目 </dd>
<dd>　⚪︎「=」挟んだ左側がGETの変数名、右側が渡される</dd>
<dl>
<dd>（例）</dd>
<dd>https://example.com?param1=value1&param2=value2</dd>
</dl>
<dl>
<dd>・データベースの値を変更せずにデータを取得する場合</dd>
<dd>・送信できるデータ量は、ブラウザやサーバーといった環境に依存する</dd>
<dd>・第三者に見られてしまう可能性がある（送信するデータがアドレスバーに表示されるため）</dd>
<dd>・ブックマークに保存することで再度同じページが参照できる</dd>
<dd>・テキストデータのみ送信できる </dd>
</dl>
<dl>
<dt>POSTの特徴</dt>
<dd>・リクエストとして送信されるデータはメッセージボディ部に含まれる。</dd>
<dd>メッセージボディはHTTPリクエストのパラメータ内容を渡す場所。</dd>
<dd>・データベース内のデータを画面上の値（FORMタグ内の値）で変更したい時に使用</dd>
<dd>・データの更新、削除、新規登録などで使用する</dd>
<dd>・パスワードのような秘匿情報をがURLに表示されない</dd>
<dd>・データ量が多くても送信できる</dd>
<dd>・バイナリデータを送信できる </dd>
<dd>・FORMタグでMETHOD=POSTを指定すると使用できる</dd>
</dl>

<dt>参考</dt>
https://qiita.com/Sekky0905/items/dff3d0da059d6f5bfabf