OmniAICreator/Qiita-1.07M huggingface dataset:
【Azure】Application Gateway WAFを本番環境と検証環境で使い分ける

### 概要
Application GatewayのWAFを運用する際、本番環境はポリシーA、検証環境はポリシーBにしたいという要望が多々あるかと思います。
最初からそのような設計になっていたら特に問題なさそうですが、導入時は本番・検証あわせてグローバルな1つのポリシーしかなかったのに途中から方針が変わってしまった際の対応方法メモです。

### 前提
Application GatewayのWAFはグローバルなポリシー設定の他に、Application GatewayのリスナーごとやルートパスごとにWAFポリシーを適用することが可能です。
今回使用するApplication GatewayのSKUはWaf_v2を想定しています。
Application Gatewayにて、本番環境用と検証環境用のリスナーが設定されていることを想定しています。

### シナリオ
株式会社Aでは、Application Gatewayをデプロイし、その際にApplication Gateway WAFポリシーとして「WAF-Policy-01」を作成して関連付けました。
ある日、本番環境と検証環境で別々のポリシーを設定したいという要望が社内であがりました。
リスナーごとにWAFポリシーを設定すれば実現可能であるということが判明したので、さっそく設定をしようとしたのだが・・・？

### 既存のWAFポリシー関連付け解除ができない
現在設定されているWAFポリシーの関連付けを解除しないと、いつまでもグローバルなポリシーがあたってしまいます。
しかし、WAFポリシーの設定画面からも、リソースグループ画面からも削除ができません。
一体なぜかと言うと、[Azureの仕様](https://learn.microsoft.com/en-us/answers/questions/841062/is-it-possible-to-disassociate-waf-policieswaf%20%20%20%20.html)として関連付け解除がサポートされていないためです。(2022年5月時点)

### ワークアラウンド
上記問題を回避するためには、以下いづれかの対応を実施する必要があります。
1. 既存のWAFポリシーを無効化して、リスナーごとに使用するWAFをデプロイ＆関連付け
1. Application Gatewayを再度作成

2の方はすでに運用されている環境だとなかなか難しい対応となるため、現実的には1を実施することになると思います。

仕様らしいので、ここはしょうがないですね。。。

### ざっくり手順
これまでの情報を踏まえて、本番環境・検証環境ごと（リスナーごと）にWAFポリシーを設定するための手順は以下になります。

1. 本番環境用のWAFポリシーA、検証環境用のWAFポリシーBをデプロイ
1. ポリシーAの「関連付けられたアプリケーションゲートウェイ」タブにて、「関連付けの追加」からHTTPリスナーを選択し、本番環境のリスナーを選択
1. ポリシーBでも上記と同様に検証環境用の設定を実施
1. 既存のWAFポリシーを無効化
1. 環境ごとにお好みのポリシー設定投入

以上です。

### 参考資料
- [Application Gateway 用の Web アプリケーション ファイアウォール ポリシーの作成](https://learn.microsoft.com/ja-jp/azure/web-application-firewall/ag/create-waf-policy-ag)
- [Is it possible to disassociate WAF policies?（WAFポリシーの関連付けの解除が可能か）](https://learn.microsoft.com/en-us/answers/questions/841062/is-it-possible-to-disassociate-waf-policieswaf%20%20%20%20.html)
default method of interface

default methodはextendsによりoverrideされる
```java
interface A {
    default void method() {
        System.out.println("aaaa");
    }
}
interface B extends A {
}

 public class Outer implements B {
    @Override
    public void method() {
        System.out.println("aaaa2");
        B.super.method();
    }
  public static void main(String[] args) {
      new Outer().method();
  }
}
```
```
aaaa2
aaaa
```
interfaceがextendsするときも利用可能
default methodは、extendsしたinterfaceのdefault methodをoverrideするときにだけ参照できる模様。
Outer extends Bのため、B.super.method()はokだが、A.super.method()はng
```java
interface A {
    default void method() {
        System.out.println("aaaaA");
    }
}
interface B extends A {
    @Override
    default void method() {
        System.out.println("aaaaB");
        A.super.method();
    }
}

 public class Outer implements B {
    @Override
    public void method() {
        System.out.println("aaaaOuter");
        B.super.method();
    }
  public static void main(String[] args) {
      new Outer().method();
  }
}
```
```
aaaaOuter
aaaaB
aaaaA
```
例外について要点まとめ

## 目次
　[1.例外の種類](#1-例外の種類)
　[2.例外の継承関係](#2-例外の継承関係)

## 1. 例外の種類
例外とは、Throwableクラスのサブクラスのオブジェクトのことを指す。
Throwableクラスのサブクラスとして、Errorクラス、Exceptionクラスが存在している。

###### ◆ Errorクラス
　プログラムが実行できないなどの重大な例外を扱うため、例外処理は通常おこなわない。
　例　IOError：重大な入出力エラー発生時にスロー

###### ◆ Exceptionクラス
　クラス名の末尾に必ずExceptionが付く。
　RuntimeExceptionクラスに属するクラスと、
　それ以外のExceptionクラスに属するクラスとに分類される。

　RuntimeExceptionクラスに属するクラスは「非チェック例外クラス」と呼ばれ、
　例外処理をおこなわなくてもコンパールエラーにならない。
　例　NullPointerException　　　　：null値の参照型変数を参照しようとした場合にスロー
　　　IndexOutOfBoundsException：配列やリストのサイズがが範囲外である場合にスロー
　　　NumberFormatException　　：数字でない文字列やnullなど、
　　　　　　　　　　　　　　　　　　　不適切な文字列を数値に変換した場合にスロー

　それ以外のExceptionクラスに属するクラスは「チェック例外クラス」と呼ばれ、
　例外処理をおこなわなければコンパイルエラーになるので、必ず例外処理をおこなう必要がある。
　例　IOException 　　　　　　 ：入力処理が何らかの原因で失敗した場合や、
　　　　　　　　　　　　　　　　　割り込みが発生した場合にスロー
　　　ClassNotFoundException：指定されたクラスが見つからない場合にスロー
　　　FileNotFoundException　：指定されたパス名のファイルが開けない場合、
　　　　　　　　　　　　　　　　　またはファイルが見つからない場合にスロー
###### ※ 参考用（図）

```
　　Throwableクラス
　　　　∟ Errorクラス
　　　　　　　　∟ IOErrorクラス

　　　　∟ Exceptionクラス
　　　　　　　　∟ RuntimeExceptionクラス（非チェック例外クラス）
　　　　　　　　　　　∟ NullPointerException
　　　　　　　　　　　∟ IndexOutOfBoundsException
　　　　　　　　　　　∟ NumberFormatException

　　　　　　　　∟ RuntimeException以外のExceptionクラス（チェック例外クラス）
　　　　　　　　　　　∟ IOException
　　　　　　　　　　　∟ ClassNotFoundException
　　　　　　　　　　　∟ FileNotFoundException
```
## 2. 例外の継承関係
たとえば何かしらの例外が発生したとき処理をおこないたい場合は、
catchブロックにExceptionクラスを記載するだけで、
下位クラスの例外をキャッチすることができる。

```java
package jp.co.study.sample;

public class Qiita {
	public static void main (String args[]) {
		
		String str1 = "おさかな";
		
		try {
		    Double.parseDouble(str1);
		    System.out.println(str1 + "：この文字列は数字です");
		    
		} catch (Exception e) {
		    System.out.println("何らかの例外が発生しました");
		}
	}
}
```
出力結果は「何らかの例外が発生しました」

例外の種類によって処理を分けたい場合は、
catchブロックに特定のExceptionクラスを記載する必要がある。

```java
package jp.co.study.sample;

public class Qiita {
	public static void main (String args[]) {
		
		String str1 = "おさかな";
		
		try {
		    Double.parseDouble(str1);
		    System.out.println(str1 + "：この文字列は数字です");
		    
		} catch (NumberFormatException e) {
		    System.out.println(str1 + "：この文字列は数字ではありません");
		}
	}
}
```
出力結果は「おさかな：この文字列は数字ではありません」

## 関連記事




https://qiita.com/osakanaaaa/items/860eb34aa0b19b5b62c3




https://qiita.com/osakanaaaa/items/551acec833af96e4bf4a
統計検定3級を受けてきた話

# はじめに

年末に統計検定3級を受けて合格してきましたので、受験までの過程をご紹介します。

# 勉強するまで

クリスマスはケーキやローストチキンを食べながらダラダラしていたのですが、

「あーこのままじゃ年末年始、何もせずにゴロゴロして終わりそうだな」

と思って、統計検定3級の勉強をする事にしました。

統計検定は会社の推奨資格になっておりまして、取得すると級に応じて奨励金が出ます。
統計や数学は苦手分野の私ですが、お金にもなるし、仕事にも役に立つと思って受けてみることにしました。

# 統計検定

統計検定は、その名の通り統計の知識を問う資格試験です。

3級の受験料は6000円と、資格試験の中ではまあまあ手頃です。（1万円超えの試験もたくさんあります…汗）

過去問もネット上に公開されていまして、どのような問題が出るのか、感覚を掴むことができます。

https://www.toukei-kentei.jp/prepare/kakomon/

また、統計検定は全国各地にあるテストセンターで、いつでも受験することができます。

試しに過去問をやってみたら、無勉強でも合格点の60点を超えていましたので、クリスマスから3日後の12月28日に受けに行くことにしました。

# 勉強方法

まず、本屋で公式問題集を購入しました。

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

公式問題集では5回分試験ができますので、試しに1回解いてみて、知らない単語、意味がわかっていない単語をメモします。

- 四分位数
- 箱ひげ図
- 変動係数
- 相関係数
- 共分散
- 標準偏差

などなど…

これらを、問題集の解説やGoogle検索、Youtube解説などを見て、解けるまで学習します。

その後、もう一度試験をやってみて、同様に知らない単語をメモするという作業を5回やりました。

あとは、電卓持ち込み可ですので、電卓を使った計算にも慣れるようにしました。

私が使っている電卓です（こちら会計の試験でも利用しています）

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

# 試験のポイント

試験は易しい問題が50%、難しい問題が20%ぐらいあります。

肝心なのは、易しい問題を取りこぼさないことです。

60%取れば合格なので、簡単な問題をとにかく絶対に間違えないことが合格の近道です。

# 簡単な分野

- 量的変数・質的変数
- グラフの種類
- 平均値・中央値・最頻値
- 最大値・最小値・四分位範囲
- 確率（サイコロ）
- 国勢調査の知識
  - 国勢調査は統計法に基づいて、1920年(大正9年)から5年ごと(年号の下一桁が5か0の年)に、日本に住む全ての人(外国人含む)を対象に行う調査です（これで1点）

あとは五択問題なので、適当に答えても20%の確率で当たります。

# 教科書

私は使いませんでしたが、教科書もあるようです。
Kindle版があれば買っていました…

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

# 私の結果

80点でした。
100点は取れそうになかったです。

100点は目指さないほうが良いかなと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1972052/a6444426-6d40-af84-95b3-1c2610a2b8b2.png)


# 次回の試験

次回は簿記2級かG検定を受けようと考えています。
static methodは継承されないし、overrideできない

```java
interface A {
    static void method() {
        System.out.println("aaaa");
    }
}

 public class Outer implements A {
    static void method() {
        System.out.println("aaaa2");
    }
  public static void main(String[] args) {
      A.method();
      Outer.method();
  }
}
```
```
aaaa
aaaa2
````
static method of interface

継承先でstatic method of interfaceは、利用できない
static method of interfaceは使用用途としてはfactory的なもの
自分をimplementsしてるクラスをnewする。
なのでstatic method of interfaceはこのインターフェース内で使用するもの
であり、継承されない
```java
interface A {
    static void method() {
        System.out.println("aaaa");
    }
}
interface B extends A{
}
class C implements A{
}

 public class Outer implements A {
  public static void main(String[] args) {
      A.method();
      B.method();
      C.method();
      method();
  }
}
```
```
com/mycompany/mavenproject1/Outer.java:[27,8] シンボルを見つけられません
  シンボル:   メソッド method()
  場所: インタフェース com.mycompany.mavenproject1.B
com/mycompany/mavenproject1/Outer.java:[28,8] シンボルを見つけられません
  シンボル:   メソッド method()
  場所: クラス com.mycompany.mavenproject1.C
com/mycompany/mavenproject1/Outer.java:[29,7] シンボルを見つけられません
  シンボル:   メソッド method()
  場所: クラス com.mycompany.mavenproject1.Outer
```
【SwiftUI】Listに検索機能を付ける

# はじめに
Listの検索機能作成します。

# サンプルアプリ
![Simulator Screen Recording - iPhone 14 Pro - 2023-01-10 at 19.50.34.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/3c780f3e-e53f-c2c9-809c-93d89c99a11d.gif)

# データ
Appleのサービスリストです。
同じような名前でわかりにくいです。
```swift
let appleServices = [
    "App Store",
    "Apple Account Card",
    "Apple Arcade",
    "Apple Books",
    "Apple Business Essentials",
    "Apple Business Manager",
    "Apple Card",
    "Apple Cash",
    "Apple Fitness+",
    "Apple ID",
    "Apple Messages for Business",
    "Apple Music",
    "Apple Music radio",
    "Apple Music Subscriptions",
    "Apple Online Store",
    "Apple Pay & Wallet",
    "Apple School Manager",
    "Apple TV Channels",
    "Apple TV+",
    "AppleCare on Device",
    "Device Enrollment Program",
    "Dictation",
    "FaceTime",
    "Find My",
    "Game Center",
    "Global Service Exchange",
    "Health sharing with provider",
    "HomeKit",
    "HomeKit Secure Video",
    "iCloud Account & Sign In",
    "iCloud Backup",
    "iCloud Bookmarks & Tabs",
    "iCloud Calendar",
    "iCloud Contacts",
    "iCloud Drive",
    "iCloud Keychain",
    "iCloud Mail",
    "iCloud Notes",
    "iCloud Private Relay",
    "iCloud Reminders",
    "iCloud Storage Upgrades",
    "iCloud Web Apps (iCloud.com)",
    "iMessage",
    "iOS Device Activation",
    "iTunes Match",
    "iTunes Store",
    "iWork Collaboration",
    "iWork for iCloud",
    "Mac App Store",
    "macOS Software Update",
    "Mail Drop",
    "Maps Display",
    "Maps Routing & Navigation",
    "Maps Search",
    "Maps Traffic",
    "News",
    "Photos",
    "Podcasts",
    "Radio",
    "Schooltime",
    "Schoolwork",
    "Screen Time",
    "Sign in with Apple",
    "Siri",
    "Spotlight suggestions",
    "Stocks",
    "Volume Purchase Program",
    "Walkie-Talkie",
    "Weather",
    "App Store",
    "Apple Account Card",
    "Apple Arcade",
    "Apple Books",
    "Apple Business Essentials",
    "Apple Business Manager",
    "Apple Card",
    "Apple Cash",
    "Apple Fitness+",
    "Apple ID",
    "Apple Messages for Business",
    "Apple Music",
    "Apple Music radio",
    "Apple Music Subscriptions",
    "Apple Online Store",
    "Apple Pay & Wallet",
    "Apple School Manager",
    "Apple TV Channels",
    "Apple TV+"
]
```

# 実装
```swift
import SwiftUI

struct ContentView: View {
    @State private var searchText: String = ""
    var body: some View {
        NavigationStack {
            List(appleServicesFiltered, id: \.self) { service in
                Text(service)
            }
            .navigationTitle("Apple Services")
            .searchable(text: $searchText)
        }
    }

    private var appleServicesFiltered: [String] {
        // MARK: 大文字小文字を区別しない
        let searchResult = appleServices.filter { $0.localizedStandardContains(searchText) }
        // MARK: 大文字小文字を区別する
        // let searchResult =  appleServices.filter { $0.contains(text) }

        return searchText.isEmpty ? appleServices : searchResult
    }
}
```

# おわり
この記事書いてて気づいたんですけど`searchable`バグありますね。
検索バーにフォーカスが当たった時にNavigationBarの所が一瞬白くなります笑
Workato：Workatoのデータセンターと接続元IPアドレス

# Workatoのデータセンター

Workatoは、2022/12時点においてUS（米国）, EU（ヨーロッパ）, JP（日本）, SG（シンガポール）のデータセンター上でサービスを提供しています。
Workatoは地域ごとにサービス基盤が独立しており、またどのデータセンターが提供されるかは、契約時に決まります。
2022/12時点においては、特段の理由がない限り、日本のユーザーに対してはUSのデータセンターが提供されます。
（Workatoの新規ユーザーと、既存ユーザーのうちJPデータセンターへの移行を希望するユーザーに対しては、今後JPデータセンターが提供される予定です）

https://docs.workato.com/datacenter/datacenter-overview.html

なお、後述の制限事項により、Workatoを契約の際はリージョンの選択を慎重に検討されることを推奨いたします。
（将来リージョン間の移行作業が生じることの無いように、ご利用になるリージョンを選択されることをお勧めします）

## 制限事項

先に記載した通り、Workatoは地域ごとにサービス基盤が独立しています。また、認証基盤も同様に独立しています。
リージョン間の連携・移行機能が現在のところ存在しないため、レシピやカスタムコネクタの移行（デプロイ）は次の方法で進めることになります。

- レシピ：Recipe lifecycle management を用いて、ZIPファイルによるレシピのインポート/エクスポートで対応
- カスタムコネクタ：ソースコードのコピー＆ペーストで対応

なお、現在利用中のデータセンター上の設定情報やログ等を、そのまま新しいデータセンターへ移行することはできません。
（新しいデータセンターへ切り替えて運用したい場合、新しいデータセンター上で真っ新な状態で１から再設定することになります）

また、以下についても対応しておりませんので、ご注意ください。
- リージョンをまたいだアカウントの連携
- Sharing privately using a link を用いた、共有トークンによるレシピおよびカスタムコネクタの共有

# Workatoの接続元IPアドレス

Workatoの接続元IPアドレス（WorkatoのレシピがWebAPI等へリクエストする際に使用される接続元IPアドレス）は、以下のページより確認することが出来ます。
先に書いた通り、Workatoは地域ごとにサービス基盤が独立しているため、現在利用中のデータセンターが分かれば、選択すべきIPアドレスは明確です。
（例えば、現在USデータセンターを利用中であるならば、SGやJPなどのデータセンターが接続元となることはありません）

https://docs.workato.com/security/ip-allowlists.html
JupyterNotebookで使えるマークダウン形式コード

Jupyterでのマークダウン形式についてPythonを復習していたら初めて使い方を知ったので、軽くメモっておきます。

## マークダウン方式を選択

セル上部のCodeをMarkDownに変更すると、コードの代わりにマークダウン形式のテキストを記載できるようになります。

![スクリーンショット 2023-01-10 193037.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337578/978baf72-f23c-e086-f126-83e4220a36d5.png)

## マークダウン方式テキストの種類

Qiita本文のマークダウン形式テキストと同様、以下の種別のテキストが扱えるようになります。

```python

# 見出し1
## 見出し2
### 見出し3
#### 見出し4
##### 見出し5
###### 見出し6

**強調** - アスタリスク2つではさむ
*Italic* - アスタリスク1つではさむ
`インラインコード` - バックダッシュではさむ
> 引用 - 大なり記号、半角スペースに続ける

- リスト1
- リスト2
    - リスト2-1
    - リスト2-2
- リスト3

1. 番号付きリスト1
2. 番号付きリスト2
    1. 番号付きリスト2-1
    2. 番号付きリスト2-2
3. 番号付きリスト3

|データ01|データ02|
|-|-|
|表1-1|表1-2|
|表2-1|表1-2|

```

![スクリーンショット 2023-01-10 193829.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337578/f80aadc0-a2eb-75a5-5ec5-f1cdd077761c.png)

## LaTex式の数式を記述

$$ - $$でくくることで、Latex形式の数式を記述することもできます。

```python
$$ \sum_{k=1}^{\infty} \frac{1}{k^2} $$
```

![スクリーンショット 2023-01-10 195955.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337578/3113aae6-a480-61a4-81f4-22294289a3d0.png)


こんな感じでPython・Jupyterの役立ち情報を発信していく予定です。よろしく！
anonymous classのclass name, methodsを確認

class name = Outer$1という名前のclass name
methods name = Object's methods + added method

```java
public class Outer {
  public static void main(String[] args) {
      var obj = new Object() {
          public void test() {
              System.out.println("i am test method");
          }
      };
      System.out.println(obj.getClass());
      Method m[] = obj.getClass().getMethods();
      for(Method mc:m) {
          System.out.println(mc);
      }
  }
}
```
```
class com.mycompany.mavenproject1.Outer$1
public void com.mycompany.mavenproject1.Outer$1.test()
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
```
Excel関数を使って楽をする話

プログラムを書く上で、よくぶち当たるのが
「全部大文字で書いてあるけど小文字に直したい」
「スネークケースだけどキャメルケースにしたい」
とかだと思います。

私がよく使うのは、Excelで適当なブックを作成し、
適当なセルに元の文字列を入力して隣のセル等に式を入力して変換する方法です。

大文字に直したい
⇒UPPER(A1)

小文字に直したい
⇒LOWER(A1)

スネークケースをキャメルケースに
⇒SUBSTITUTE(PROPER(A1),"_","")
※参考：[Excelでアンスコ区切りをキャメルケースに変換する](https://b.chiroito.dev/entry/Excel%E3%81%A7%E3%82%A2%E3%83%B3%E3%82%B9%E3%82%B3%E5%8C%BA%E5%88%87%E3%82%8A%E3%82%92%E3%82%AD%E3%83%A3%E3%83%A1%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B9%E3%81%AB%E5%A4%89%E6%8F%9B%E3%81%99%E3%82%8B)

のようにすると簡単に変換できます。
引用元にはローワーキャメルの例もありますが、式が長くなってしまうため、
ただ変換したいだけだったらアッパーキャメルケースで変換して先頭一文字だけ削るほうが楽です。
覚える関数も2つで済みます。

目視からの手打ちはtypoの温床なので極力なくしましょう。
競プロ用備忘録 g++を実行するエイリアスを作成する

# 何をするか？
競プロでC++を使うときの面倒な実行コマンドを、エイリアスを使って超簡単にする。
```zsh:before
$ g++ -std=c++11 a.cpp && ./a.out && rm -f a.out
```
```zsh:after
$ crun a.cpp
```



# ぼくが競プロでc++を使うときにテスト実行するコマンド
通常は コンパイル→実行 と2ステップを踏むが、かなり面倒。
おまけに実行ファイルがディレクトリに残ってしまうので邪魔。
Pythonとかの快適さに慣れてしまうとC++の実行コマンドはちょっとストレスに感じる。

そこで、 コンパイル(実行ファイル生成) → 実行 → 実行ファイル削除 の3ステップをまとめて実行するよう以下のようなコマンドを使用している。

```zsh:普段よく使う実行コマンド
$ g++ -std=c++11 a.cpp && ./a.out && rm -f a.out
```

ざっくり解説をすると
* `g++` コンパイルを行い、 `a.out` を生成。コンパイルエラー時は以降のコマンドはすべて無視される。
* `-std=c++11` なんか不要なWarningが出ることが多かったため追加。
* `./a.out` コンパイル後に出力されるファイルを実行する。
* `rm -f a.out` 実行後に `a.out` を削除する。

こんな感じ。

# エイリアスの設定
毎回このコマンドを打つのが非常に面倒だったため、 `.zshrc` にエイリアスを設定。

```zsh:~/.zshrc
function crun() {
    command g++ -std=c++11 $@ && ./a.out && rm -f a.out
}
```

を追記する。

# 結果
初回のみ忘れずに `$ source ~/.zshrc` を実行すると、 `crun` コマンドが使用できるようになる。

```zsh:エイリアス設定後
$ crun a.cpp
```
だけでコンパイル→実行→ファイル削除 までまとめて自動で実行してくれる。
コマンド名は適当なので、異論は認めます。
リアルタイムのマッチングアプリを Cloud Run にデプロイするときの注意点

こんにちは！今日は，リアルタイムのマッチングアプリを Cloud Run で動かすときの注意点についてお話しさせていただこうと思います．


# 前提条件
以下のような構成で，リアルタイムマッチングをしています．
![無題のプレゼンテーション (6).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1840262/a91eb122-2bd4-ee3f-f929-b4cac0ecab74.jpeg)


# この前提条件のままでCloud Runにデプロイすると何が起きるか
マッチングしているのに，その情報が API から伝わってこなかったりします．
下の図で説明してきます．

![無題のプレゼンテーション (8).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1840262/3851c4d0-b87c-c59a-3499-9e228461bff2.jpeg)



この図を見ると，API が二つに増えたことが確認できると思います．Cloud Run はインスタンス（APIサーバー的なやつ）数が自動スケーリングされます．そのため，API が複数で動いている場合があります．これが原因で，マッチングしているのに，その情報が API から伝わってこなかったりします．フローを追いながら説明してきます．

1. API1は，rdb をポーリングしてマッチングしてるか確認します．
1. マッチングしているので，rdbからデータを削除します．そして，API1とwebSocketコネクションで繋がっているuser1に伝えます．このとき，user2とは，webSocketコネクションで繋がっていないため伝えられません．
1. API2は，rdb をポーリングしてマッチングしてるか確認します．この時すでにマッチングした情報はAPI1により削除されているため，API2はマッチングしていないと認識します．
1. そのため，API2とwebSocketコネクションで繋がっているuser2には，マッチングしたという情報が伝わりません．

# 解決方法
これを解決する一つの方法が，__redis の pub/sub を使う__ やり方です．redis の pub/sub は，あるチャンネルにメッセージをpublishしたら，チャンネルを監視しているsubscriberに届くというものです．以下の図で説明します．
![無題のプレゼンテーション (9).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1840262/64befd90-7616-6022-4ddc-0a901029fefd.jpeg)


まず，API1，API2は redis のチャンネルを subscribe するようにしておきます．　

1. API1は，rdb をポーリングしてマッチングしてるか確認します．
1. API1は，マッチングを確認したので rdbからデータを削除します．そして，__redisのチャンネルにマッチングしたuserIDをpublish__ します．
1. API1は，webSocketコネクションで繋がっているuser1に伝えます．このとき，user2とは，webSocketコネクションで繋がっていないため伝えられません．
1. redis のチャンネルを subscribe している API2のもとに，マッチングしたuserIDの情報が届きます． 
1. API2は，webSocketコネクションで繋がっているuser2に マッチングしたという情報を伝えます．

このように行うことで，複数APIサーバーが動いている状態でも，マッチングを実現できます．

# まとめ
実はこの問題は以前AWS にデプロイするときに起きていた問題だったのですが，まさか Cloud Run でも同じ現象が起きているとは思わず原因を探るのに苦労しました..
複数リアルタイムのマッチングアプリを Cloud Run で動かすときに参考にしていただければ幸いです．
Nebo 4 – アイデアを形に

3ヶ月前、メモをパーソナライズする新たな仕様とともに、高性能なカラー機能を備えたダークモードを実装した際、ページの名称もそれぞれ変更されました。通常のページは ドキュメントページへ、フリーフォームページはメモへと変更されました。そしてこれが予期せぬことに、進行中だった新しい技術の開発における手がかりになりました。
## Nebo Noteの進化
![nebo4-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784576/46dea2b8-1c73-410d-3e62-efddf5b45973.jpeg)
最初に拡張可能で自由自在なキャンバスであるNebo Noteを公開したのは、どこまでも自由なメモ体験を提供し、ユーザーの創造性を妨げる全てのものを無くすことが目的でした。しかし、手書き認識機能がバックグラウンドで作動している間は、Nebo ドキュメントの多くのユーザーの方にご愛用いただいているインタラクティブなインク機能を使用することができないという難点がありました。当サービスの開発者がより大きな可能性を追求し新たな技術開発に取り組む一方で、UXの専門家が数多くのフィードバックをもとに、ユーザーが当サービスをどのように利用しているのかについて研究を重ねました。背景にあるのは、キャンバスがどんな時に便利でどんな時に不便なのかを知りたい、と言う私たちの思いです。

その結果、ユーザーのニーズはNeboの当初からのビジョンである「場所や書き方にとらわれず、書いたものを全て形にする魔法テク」と、100％一致しているという結論に至りました。

そして私たちはAI技術を活用し、テキストと図形、落書き、その他全てのあらゆるメモを区別することにこれまで以上に注力しました。非常に困難な道のりでしたが、時間と労力をかけ、最終的にはどのアプリよりも先を行く、満足のいく仕上がりになりました。

* そんな Nebo４を紹介します。
![nebo4-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784576/3caff93b-f028-d43d-3e0d-a266bd2e04a3.jpeg)
### 唯一無二の体験
Nebo 4は、図形や植字テキスト、背景パターンやアプリ外からテキストや画像を貼り付ける機能など、メモに欠かせない機能を搭載しています。それだけでなく、次のような機能も独自のインタラクティブ・インク技術によって補強されています。
### 手書き文字変換とキーボードの互換性
手書きされた文字を丸で囲って選択し、「変換」をタップするだけで瞬時にその場で植字テキストに変換できるようになりました。テキストのサイズや位置は変わらないため、コンテンツの構成やレイアウトを維持することができます。
また、ペンやキーボードを使ってメモのテキストを作成・編集できるようになりました。どちらもあらゆる場面で同じように便利に使うことができます。すべてのテキストをNeboに!
さらに、手書きから変換したもの、タイプしたもの、他のアプリケーションから貼り付けたものなどすべての入力テキストが編集可能で、サイズを変更しても対応することができます。
![nebo4-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784576/ac906a1d-ef72-5e20-220f-4b546dc5f010.jpeg)
### ペンジェスチャー
手書きや活字、絵、図形、矢印など、メモ内のあらゆるコンテンツを擦るだけで消せるようになりました。Neboは消す動作と色を塗る動作の区別もすることができます。シンプルながら魔法のような技術です。
取り消し線やアンダーラインの動作も認識されます。書式をそのまま適用するか、取り消し線の場合は文字を削除するか、下線の場合は文字を太くするか、といったカスタマイズをすることもできます。
### 図形の変換
ユーザーからの要望が最も多かった機能が、ついにNeboに搭載されました。図形を描いた後、ペンで画面を長押しすることで綺麗な形を作ることができるようになり、さらにNeboのAI技術は、複数の線が重なって描かれた図形までも認識するほどに高度になりました。
### 配置調整ガイド
何の制約もなくキャンバにスきれいなノートを作成できるよう、ブロック、図形、画像をページ内で移動する際にスマートアライメントガイドが表示されるようになりました。
### 大きな飛躍
Nebo 4は長年にわたる技術革新の集大成とも言えますが、私たちの挑戦はこれで終わりではありません。
私たちは、AIとユーザー体験を組み合わせて究極のメモ体験を実現する新たな方法を常に模索しており、すでに次の開発に向けて取り組みを始めています。
いつものように、皆さんが今回のアップデートを楽しんでくださることを願っています。
MyScript　Neboチーム

Nebo Noteについてはこちら
👉 [nebo.app](https://nebo.app/)
👉 [Support](https://app-support.myscript.com/)
不変マップを初期化する際はMap.ofEntriesを推奨

# 不変マップの初期化方法
不変マップの初期化方法は大きく下記2つの方法があります。
- Map.of()
- Map.ofEntries()

いずれもJavaSE9、JDK9以降に導入された機能になります。
https://docs.oracle.com/javase/jp/9/docs/api/java/util/Map.html

それではそれぞれの使い方を見ていきましょう。

## `Map.of()`
下記ドキュメントを参照しますと分かるとおり、of()の引数は、0〜10個の要素（キーとバリューのマッピング）を指定することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630308/325691c9-bd59-12eb-3c69-b97d716a01ab.png)

例えば、要素数が2つの不変マップを初期化する場合
```java
import java.util.Map;

Map<String, String> mapOf = Map.of(
    "key1", "value1",
    "key2", "value2"
);
```
Map.of()はキーとバリューを交互に指定していきます。

要素が1個とか2個のときはどれがキーでどれがバリューか分かりやすいですが、要素数が増えてくるとちょっと分かりにくくなりそうですね。

実際は、キーとバリューの名前がプログラム例のように『keyXX』とか『valueXX』とか分かりやすく命名されているはずもないので。



## `Map.ofEntries()`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630308/45ffa42f-3e28-4031-11c0-b3dd4de098e3.png)

`Map.ofEntries()`は指定したエントリから抽出されたキーと値を含む不変マップを作成します。

```java
import java.util.Map;
import static java.util.Map.entry;

Map<String, String> mapOfEntries = Map.ofEntries(
    entry("key1", "value1"),
    entry("key2", "value2")
);
```
要素ごとにentry("key", "value")を指定します。

`Map.ofEntries()`は指定できる要素数に制限はないため、要素数が増えても簡単に要素追加できますし、entry()で区切られているためキーとバリューのマッピングが一見して分かりやすいです。

# `Map.ofEntries()`を推奨する理由
ここまで`Map.of()`と`Map.ofEntries()`をそれぞれ見てきました。

最後に`Map.ofEntries()`を推奨する理由をまとめていきます！

## 可変性
`Map.of()`は最大10個の要素しか指定できず、11個以上の要素を指定できないという**可変性の低さ**があります。
そのため11個以上に要素が増える可能性がある場合は使用を避けるべきです。
その点、`Map.ofEntries()`は、**要素数の制限はないため、要素数が増えても簡単に追加することができます。**

## 可読性
先述したとおり、`Map.of()`はKeyとValueを交互に指定していきます。
要素が1個とか2個のときはどれがキーでどれがバリューか分かりやすいですが、要素数が増えていくと最大20個の要素が横並びすることになり、**可読性を著しく損ないます。**（IDEやエディタのコードフォーマットをしたら少しは見やすくなりますが）


一方で`Map.ofEntries()`は要素数の制限はなく、要素1つを指定する毎にentry(key, value)を指定するため、下記のように要素数が増えても簡単に要素追加できますし、キーとバリューの組み合わせが分かりやすいです。

```java
import java.util.Map;
import static java.util.Map.entry;

Map<String, String> mapOfEntries = Map.ofEntries(
    entry("1", "1"),
    entry("2", "2"),
    entry("3", "3"),
    entry("4", "4"),
    entry("5", "5"),
    entry("6", "6"),
    entry("7", "7"),
    entry("8", "8"),
    entry("9", "9"),
    entry("10", "10"),
    entry("11", "11")
);
```
CloudShellにLaravelをインストール

```bash
sudo apt update \
  && sudo apt install -y php8.2 php8.2-curl php8.2-xml php8.2-mbstring php8.2-sqlite3 \
  && composer create-project laravel/laravel example-app \
  && cd example-app \
  && php artisan about
```

<details><summary>Ubuntu 22.10</summary>

```bash
sudo apt update \
  && sudo apt install -y php php-curl php-xml php-mbstring php-mysql php-sqlite3 composer sqlitebrowser \
  && composer create-project laravel/laravel example-app \
  && cd example-app \
  && php artisan about \
  && git init \
  && git add . \
  && git config --global user.email "you@example.com" \
  && git config --global user.name "Your Name" \
  && git commit -m first
```
</details>
レキシカル・バインディングとダイナミック・バインディング

年末年始から、[An Introduction to Programming in Emacs Lisp](https://www.gnu.org/software/emacs/manual/eintr.html)を読んでいます。  
ちょっとつまずいた箇所があったので、まとめようと思います。

## 先にまとめ

Emacs 27.1でレキシカル・バインディングがデフォルトで有効になりました。  
GNUのドキュメントでは、その点カバーできていない部分があるようなので、気をつけよう。

## レキシカル・バインディングとダイナミック・バインディング

というか、レキシカルとかダイナミックとかって何？という話もあるので、簡単に。

```elisp
(setq value 255)

(defun inner ()
  (message "inner> value = %d" value))

(defun outer ()
  (let ((value 0))
    (message "outer> value = %d" value)
    (inner)))
```

上記は、ダイナミック・バインディングが有効か、レキシカル・バインディングが有効かで動作が変わります。

ここでは、`value`と名のついた変数が2つあります。  
1つは`setq`で設定した、グローバル変数に相当するもの。値は255に束縛しています。  
もう1つは`let`式内で定義された、`outer`関数のローカル変数に相当するもの。値は0に束縛しています。

### ダイナミックバインディングが有効な場合

上記のコードで、`(outer)`を評価すると、ミニバッファは以下のように出力します:

```
outer> value = 0
inner> value = 0
```

`inner> value = 0` とあるとおり、`inner`関数はローカル変数の`value`にアクセスしています。  
`outer`関数の中で呼び出された`inner`関数は、ダイナミック・バインディングにより、実行時に直近にある変数にアクセスしました。一番近くにあったのは、`outer` 内のローカル変数である `value`。そのため、ミニバッファの出力は `inner> value = 0` となりました。

### レキシカル・バインディングが有効な場合

同様にして、ミニバッファは以下のように出力します:

```
outer> value = 0
inner> value = 255
```

`inner> value = 0` ではなくなりました。レキシカル・バインディングにより、`inner`関数がアクセスするのは、実行時ではなく、コード記述時点で直近にある変数 `value`。つまり `setq` で設定したグローバル変数の `value` です。

- [Lexical Binding (GNU Emacs Lisp Reference Manual)](https://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html) ([日本語訳](https://ayatakesi.github.io/lispref/28.2/html/Lexical-Binding.html))

### Emacs 27.1からはレキシカル・バインディングがデフォルトで有効に

[Emacs 27.1からはレキシカル・バインディングがデフォルトで有効](https://github.com/emacs-mirror/emacs/blob/master/etc/NEWS.27#L365-L378)になっています。  
明示的にレキシカル・バインディングを有効にするには、`(setq lexical-binding t)` とします。

```elisp
lexical-binding  ; => t
```

- [Using Lexical Binding (GNU Emacs Lisp Reference Manual)](https://www.gnu.org/software/emacs/manual/html_node/elisp/Using-Lexical-Binding.html#index-lexical_002dbinding)

[An Introduction to Programming in Emacs Lisp](https://www.gnu.org/software/emacs/manual/eintr.html)では、2023年1月現在、この変更に追従できていないのか、ダイナミック・バインディングがデフォルトと記述がされています (そこで混乱して、この文章をまとめるに至りました)。気をつけんとなぁ、と思います。

> In computer science jargon, we would say the binding of a symbol is visible only in functions called in the let form; in Emacs Lisp, the default scoping is dynamic, not lexical. (The non-default lexical binding is not discussed in this manual.)
[Prevent confusion (Programming in Emacs Lisp)](https://www.gnu.org/software/emacs/manual/html_node/eintr/Prevent-confusion.html)
画像の不要物を削除　AOT-GAN-for-Inpainting

# Inpaintingやってみたいけど難しそう

![room1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/546e95e9-d9bc-d851-b93b-fabb439dbe51.png)![bafd8007-676f-488a-bf58-881faa645d0c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/663ecfef-5da9-d916-0edf-ad7dfc8c5643.png)



意外と簡単です。

# 使い方

InpaintingモデルAOT-GAN-for-Inpaintingの使い方です。

https://github.com/researchmm/AOT-GAN-for-Inpainting

リポジトリからトレーニング済みの重みをダウンロードしておきます。
リポジトリをクローンして、

・トレーニング済みの重みのパス
・画像ディレクトリ
・マスク画像ディレクトリ

を指定して実行します。
マスク画像は入力画像と同じ大きさの白黒（GrayScale）画像で、隠したいところを白く塗ります。

```shell
# clone
git clone https://github.com/researchmm/AOT-GAN-for-Inpainting.git
cd AOT-GAN-for-Inpainting/src

# run
python test.py --pre_train G0000000.pt --dir_image ../examples/object/image --dir_mask ../examples/object/mask
```

outputsディレクトリに出力が保存されます。

インプット画像
![room1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/546e95e9-d9bc-d851-b93b-fabb439dbe51.png)

マスク画像
![room.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/6f0159ed-20aa-1fc1-41f6-7dfd2ddf76c8.png)

出力
![bafd8007-676f-488a-bf58-881faa645d0c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/663ecfef-5da9-d916-0edf-ad7dfc8c5643.png)
Azure Synapse Analytics専用SQLプールで列名を変更する（sp_rename）

Azure Synapase Analytics 専用SQLプールを運用していると、ごくまれに「テーブルの列名を変更したい」という要望をいただく事があります。

2020年12月までは、`CTAS`を使って、列名を変更した新しいテーブルへ物理的にデータの移動などをやっていたのですが、2020年12月以降にプレビュー版ですが、sp_renameにて列名を変更することが可能になりました。
※ただし、sp_renameで変更できるのはユーザーオブジェクトの列名のみであり、また、Azure Synapase Analytics サーバーレスSQLプールではサポートされていません。

# 用途
Azure Synapase Analytics 専用SQLプールのユーザーオブジェクトのCOLUMNの名前を変更する。

# 使い方
***sp_rename '<スキーマ名>.<テーブル名>.<カラム名>','<新しいカラム名>','COLUMN'***

第一引数には、変更したいカラム名をスキーマ修飾、テーブル名修飾した状態で指定し、第二引数に新しいカラム名を指定します。第三引数は`COLUMN`固定です。

実際に、`sp_rename_test`と言うテーブルを作成し、列名を`col1`、`col2`、`col3`から`id`、`first_name`、`last_name`へ変更してみます。

```SQL
--テーブルの作成
create table sp_rename_test
(
	 col1 int
	,col2 nvarchar(100)
	,col3 nvarchar(100)
);
--カラム名の確認
select 
   t.name
  ,c.name column_name
from 
  sys.tables t inner join sys.columns c on 
    t.object_id = c.object_id 
where 
  t.name = 'sp_rename_test'
order by 
  c.column_id
;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/4035e817-29ef-ddd1-df54-a3b7704d2062.png)

上記の通り、作成できたので、カラム名を変更します。
```SQL
--カラム名の変更
sp_rename 'dbo.sp_rename_test.col1','id','COLUMN'
sp_rename 'dbo.sp_rename_test.col2','first_name','COLUMN'
sp_rename 'dbo.sp_rename_test.col3','last_name','COLUMN'
--カラム名の確認
select 
   t.name
  ,c.name column_name
from 
  sys.tables t inner join sys.columns c on 
    t.object_id = c.object_id 
where 
  t.name = 'sp_rename_test'
order by 
  c.column_id
;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/0851bce8-6931-aaeb-062d-8c6f0304f988.png)

# 備考
***ディストリビューション列はカラム名変更ができないので注意が必要です。***
```SQL
--テーブルの作成（COL1をハッシュキー（ディストリビューション列）に指定）
create table sp_rename_test2
(
	 col1 int
	,col2 nvarchar(100)
	,col3 nvarchar(100)
)
WITH
(   DISTRIBUTION = HASH(col1))
;
--カラム名の変更（col1→id）
sp_rename 'dbo.sp_rename_test2.col1','id','COLUMN'
```
エラー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/f09f6361-8049-0b48-7af1-889c95a45891.png)
React (Next.js) – radioボタン + onChange で送信ボタンを押さずにaxiosリクエストする

# コード例

```tsx
import axios from "axios";
import { useState } from 'react'

const RadioChangePost = () => {
  const [val, setVal] = useState('');
  const requestURL = "https://httpbin.org/post";
  const [gotResponse, setResponse] = useState({ "form": { item: "" }});

  const HeatHandleChange = (data: any) => {
    setVal(data.target.value);
    axios.post(requestURL, new URLSearchParams({ item: data.target.value })).then((response) => {
      setResponse(response.data);
    });
  }

  return (
    <>
      <div>
        <input
          type="radio"
          value="heat"
          onChange={HeatHandleChange}
          checked={val === 'heat'}
        />
        Heat
      </div>
      <div>
        <input
          type="radio"
          value="cool"
          onChange={HeatHandleChange}
          checked={val === 'cool'}
        />
        Cool
      </div>
      <div>{gotResponse['form']["item"]}</div>
    </>
  );
}
export default RadioChangePost;
```

# 動作例

![image](https://user-images.githubusercontent.com/13635059/211513395-599b1421-f006-4145-a4a0-d9dd0ee9a150.png)

# 環境


- react@18.2.0
- next@13.1.1


# チャットメンバー募集


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

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


# Twitter

https://twitter.com/YumaInaura
Power BIへのログイン時に何も表示されない場合の解消法

※ この現象は近々修正予定とのことで、直るまでの暫定措置。

## 現象

Power BIにログインしようと、https://app.powerbi.com/ にアクセスした際に、ライセンスが失効していると、`https://app.powerbi.com/SignupRedirect?pbi_source=websignup&responseError=UserNotLicensedru=https%3A...` のようなURLだけ表示され、何も画面に表示されないというトラブルが発生することがある。

## 回避策

URLの `https://app.powerbi.com/SignupRedirect?pbi_source=websignup&responseError=UserNotLicensedru=https%3A...` の、 `=UserNotLicensedru=` の箇所を `=UserNotLicensed&ru=` に置き換える。

すると次の画面に遷移できるようになり、新しくサインアップなどを行うことができるようになる[^1]。

[^1]: ライセンスが切れているのでエラーしても仕方ないかと思っていたが、ここで止まると新たなサインアップもできないため、Azureのサポートリクエストにより問い合わせたところ、この解決策を教えてもらえた。本当に感謝。
ABC284回答メモ

0.はじめに
　年明け早々に帯状疱疹になり、痛みに耐えて頑張りました。
　Cは今一攻め切れなさそうだったので、Dからやったら
　解けたので、年始一発目としては満足です。

1.A - Sequence of Strings
　あまりきれいに答えようとせず
　シンプルに考えて、回答しました。

　頭から保存していって、出力を後ろからにしました。
　
```
for i in range(N):
    print(list[N-i-1])
```
　https://atcoder.jp/contests/abc284/submissions/37797242


2.B - Multi Test Cases
　問題文通り、1つの入力で複数のテストケースを裁くだけの簡単なお仕事でした。

　https://atcoder.jp/contests/abc284/submissions/37802076

3.C - Count Connected Components
　ははーん。これは頓知的な問題で、辺数が頂点数以上なら
　全部つながっているし、それ以下なら、辺数-頂点数の固まりになるんだな！
　と、回答しましたがWA。

　ま、まぁ、3角形とかが出来てるケースを考えればダメなのは
　わかるんですが・・・。
　一筋縄ではいかないと思いスキップ（戻ってきませんでしたが）

　後日回答。
　普通に、辺を2次配列に格納し、再帰関数でつながっている固まりを
　カウントしてＡＣ。
　落ち着いてやれば時間内に行けたかもなと後悔。

　https://atcoder.jp/contests/abc284/submissions/37958467

4.D - Happy New Year 2023
　ぱっと見簡単に見えたので着手したもののTLEの解消にてこずりました。
　それでも時間内にACがもらえたので満足感のある問題でした。

　2個

　考え方１
　素因数分解で素数と個数を求める関数をググってもってくる。
　2個必要な素数pと1個の素数qが分かるので表示！
　→予想した通りTLEでした。

　考え方２
　素数表を作りその2乗で入力数を割っていき
　割り切れたら、その素数がp、商がq！

　→制限秒数で計算可能な素数の上限が7桁だったため、上記の方法では足りずWA。

　考え方３
　　1)7桁までの数字で素数表を作る
　　2)Nを素数表で割っていく
　　3)n%xが0の時n/xをさらにｘで割る
　　　3-1)割り切れた場合
　　　　・xがp、n/x/xがq
　　　3-2)割り切れない場合
　　　　・xがq、n/xよりsqrt関数で平方根を求めその数がp
　なんとかAC頂けました。
　
　https://atcoder.jp/contests/abc284/submissions/37835114
　
　後日解説を見たら、素数を求めずとも、pqどちらかがnの3平方内に収まることを
　利用すれば解けることを知りました・・・。まぁとけたからいいか・・・

以上
【SQL】指定した区切り文字で、文字列からテーブルを生成する

Azure Synapase Analytics 専用SQLプールはAzure上で提供されているDWH用途のRDBMSのPaaSサービスです。SQL Serverと高い互換性がありますが、一方で一部SQL構文が使えない場合があります。

今回は指定した区切り文字で、文字列からテーブルを生成する`STRING_SPLIT`関数を紹介します。当該関数はSQL Serverで「互換性レベル 130」以上で利用することが出来ますが、Azure Synapase Analytics 専用SQLプールでも利用可能です。

使ってみると大変便利でしたので、こちらで紹介します。

# 用途
***指定した特定の区切り文字で、文字列からテーブルを生成することが出来ます。***

例えばカラム区切りの文字列から、`value`と言うカラムを１つもつテーブル型を返してくれます。

こんなイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/917f0d94-1d26-9a96-2423-f98d1617bf4f.png)

# 使い方
**STRING_SPLIT ( [ 文字列 ]  , [ 区切り文字 ]  )**
STRING_SPLITは、第一引数の文字列を、第二引数で指定した区切り文字で分割して、結果をテーブルとして返してくれる関数です。
区切り文字は***１文字***で指定します。

文字列`AA,BBBB,CC,D`と言う文字列をカンマでスプリット
```SQL
SELECT * FROM STRING_SPLIT('AA,BBBB,CC,D', ',');
```
結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/c04d8159-f908-2950-ca49-ea40552a22c2.png)

# 備考
APPLYオペレーター（`CROSS APPLY`、`OUTER APPLY`）と併用するとさらに便利そうです。
```SQL
--テーブルの作成
create table split_test1(col1 nvarchar(100));
--データの挿入
insert into split_test1 values(1,'AA,BBBB,CC,D');
insert into split_test1 values(2,'11,222,3333,1234');

--id=1のcol1のデータをスプリット（エラーとなる）
SELECT value from STRING_SPLIT(split_test1.col1, ',') where id = 1;

--CROSS APPLYを使って、id=1のcol1のデータをスプリット（成功する）
SELECT value from split_test1 CROSS APPLY STRING_SPLIT(split_test1.col1, ',')
where id = 1;

--CROSS APPLYを使って、id=2のcol1のデータをスプリット（成功する）
SELECT value from split_test1 CROSS APPLY STRING_SPLIT(split_test1.col1, ',')
where id = 2;
```
id=1の結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/da38e428-81bd-2f93-9e87-c5c00bbc8779.png)

id=2の結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/d15ffb8a-f25f-b919-0a89-6ae9828410fd.png)
数学_61

## 考察
投資効率の良いものの選定
全体重量合計がある中で電源の最大を求める、最適化の話。

電源容量/重量をそれぞれ算出して
絶妙なバランスを人間が選択して・・・となるが
見逃す最適解があるかもしれない

## コードで解決
pulpライブラリを使って数理最適化問題として対処する。

解決問題定義
```python
# 問題定義
prob = pulp.LpProblem('モバイルバッテリ選択最適化', sense=pulp.LpMaximize)

# モバイルバッテリ定義
## ラベル
goods = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
## 重さ
weight = [150, 170, 180, 200, 200, 240, 250]
## 出力
power = [3000, 4000, 5000, 7000, 8000, 8000, 9000]

# 変数定義
## 0 or 1の選択になるので変数カテゴリは Binary で定義する
## fstring使っています
xs = [pulp.LpVariable(f'{x}', cat='Binary') for x in goods]

# 目的関数定義 a*3000 + b*4000 + .... + g*9000：これを最大化する
prob.setObjective(pulp.lpDot(power, xs))

# 制約定義
## 合計 1kg以下(1000g)
prob += pulp.lpDot(weight, xs) <= 1000
print(prob)
```
![Screenshot from 2023-01-09 20-12-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/c69336c8-4425-60cc-e0c4-c5f783f1908d.png)



計算します。計算過程のログも出します（わからない・・けど、何かしら試行錯誤している様子あり）
選択するa〜gの組み合わせと
その結果が表示されます。

```python
# status = prob.solve(pulp.PULP_CBC_CMD(msg=0)) # ログなし
# ログ出力、4スレッドで実施
# status = prob.solve(pulp.PULP_CBC_CMD(msg=1)) # ログあり
# ログ出力、4スレッドで実施
status = prob.solve(pulp.PULP_CBC_CMD(msg=1, threads=4))
print("Status", pulp.LpStatus[status])
print(xs)
print([x.value() for x in xs])
print(prob.objective.value())
```
ログ：
![Screenshot from 2023-01-09 20-17-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/ee123af3-bb38-166e-9029-7d6256340de7.png)

結果：
![Screenshot from 2023-01-09 20-17-32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/8e13b2a0-2f84-4eff-0c41-1a999122c2bb.png)

## これだけだとわかりにくいので
条件、結果、効率をまとめます。

```python
df = pd.DataFrame({
  '製品': xs,
  '選択': [int(_.value()) for _ in xs],
  '電源容量': power,
  '重量': weight,
  '効率': [np.round(p/w, decimals=2) for p, w in zip(power, weight)],
  }).T
df
```
いろいろ納得
![Screenshot from 2023-01-10 20-11-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/61dab21c-26c8-6867-3a63-a4c5f300acb3.png)

なんとなくですが
- 効率の良いものから、半分よりちょっと少ない分を採択
- 一旦固定
- ここから調整
がいい感じの試行錯誤ステップになっているような、そうでないような。

今回：７つ　→ 7/2を切り捨てて３
効率の良い順から３つを採択、あとは試行錯誤。
数学_56

## 考察
相関係数の算出
定義どおり計算すれば良いけど、実にめんどい

## コードで解決
0.7735

```python
x = np.array([2, 3, 5, 4, 5])
y = np.array([3, 2, 4, 4, 5])
df = pd.DataFrame([x, y]).T

# Pandasの場合
print(df.corr())

# numpyの場合
print(np.corrcoef(x, y))
```
![Screenshot from 2023-01-09 19-57-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/aa01a351-9f69-1c91-c661-28e21e1cdd31.png)
数学_45

## 考察
分布グラフを書いて推察する。
手作業・・

## グラフで解決
```python
# グラフを描いて判断する（snsのsncatter Plot）
od = OrderedDict()
od['A'] = [10, 8]
od['B'] = [7, 6]
od['C'] = [8, 9]
od['D'] = [8, 6]
od['E'] = [4, 7]

df = pd.DataFrame.from_dict(od, orient='index',columns=['デザイン性','機能性'])
print(df.T)

sns.scatterplot(y='デザイン性',x='機能性',data=df,hue=df.index)
```

![Screenshot from 2023-01-09 19-29-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/81609b49-211a-3192-be71-60b3802f67c7.png)
数学_44

## 考察
TP,TN,FP,FNの話
正解率、再現率、適合率、F値

問題文中に定義は書いてあるが
理解しておくべきテーマ

## コードで解決
```python
# 変数定義
TP,TN,FP,FN, A = symbols('TP TN FP FN A', real=True, positive=True)

# -------------
#  TP   | FN
# -------------
#  FP   | TN
# -------------

# 課題から以下定義
TP = 1236 # 正しく検出
FN = 148  # 誤って検出せず「本当は問題あるのに）
FP = A    # 誤って検出「本当は問題ないのに）
TN = 946  # 正しく検出せず

# 正解率
f0 = Fraction(TP + TN)/(TP+TN+FP+FN)

# 再現率：疾患者を正しく陽性と判定した割合
f1 = Fraction(TP)/(TP+FN)

# 適合率：陽性者のうち実際に疾患している割合
f2 = Fraction(TP)/(TP+FP)

# F値 再現率と適合率の調和平均
## 調和平均：逆数の平均の逆数
f3 = 1/((1/f1+1/f2)/2)

print(f'正解率: {f0}')
print(f'再現率: {f1}')
print(f'適合率: {f2}')
print(f'F値: {f3}')

# 不等式で解く
reduce_rational_inequalities([[f3>=0.8]], A)
```

![Screenshot from 2023-01-09 19-25-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/6ceb2bb0-852d-306f-2b2c-6cbeb3ca80bd.png)
数学_40

## 考察
$ \displaystyle detA=0$
であれば変数と式の次元が異なる。
得られた結果から考察する。

## コードで解決
```python
# 変数定義
a = symbols('a', real=True)

# 行列定義
M = Matrix([
    [1, a, a**2],
    [a, 1, a],
    [a**2, a, 1]
])
display(M)

# 条件設定と解
eq1 = Eq(M.det(), 0)
display(solveset(eq1, a))
```

![Screenshot from 2023-01-09 18-52-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/31e77a6f-8188-be8d-b7a9-24a216a0b198.png)

結果から a = 1 or a = -1が得られる。
行列を見てa = 1のときは全て要素が１になり解不定。

a = -1として計算する。

```python
# 比例級数の和
a = -1
print(f'解答')

# factor（使わなくても一緒だった）とsummationを使って等比級数算出を行う
i = symbols('i', integer=True)
factor(summation((-1)**i,(i,0,10)))
```
数学_39

## 考察
吐き出し法だと思うが計算だるい
３分は無理だと思う。

## コードで解消
sympyの行列演算で即解。ステキ。
```python
# 行列定義
M = Matrix([
    [1, 0, -2],
    [2, 3, 1],
    [2, 1, -2]
])

# 逆行列
M.inv()
```
![Screenshot from 2023-01-09 18-41-52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/65faee22-4add-bb48-8fb9-003a79e3cc22.png)
数学_38

## 考察
２☓２の行列の扱い
逆行列
計算するだけ、だけどちょっとめんどい。

## コードで解決
sympyの行列処理で簡単解決
行列の関係（右、左）を間違えぬように。

```python
# 行列定義
A = Matrix([
    [2, -1],
    [5, -3]
])
BA = Matrix([
    [18, -10],
    [-1, 0]
])
display(A, BA)

# Bを算出
print(f'解答')
display(BA*A.inv())
```
![Screenshot from 2023-01-09 18-36-56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/5d5f90df-d300-3ffd-068c-57412e2590aa.png)
数学_37

## 考察
計算問題のラスボス登場
手作業だと１階微分→２階微分→３階微分→４階微分
途中の計算過程が地獄。

ただうまいところ
$ \displaystyle (1-x+2^x)^{-3/2} $
で囲ってあげると計算がちょっと楽になる、僅かですが。
$ \displaystyle (1-x+2^x)^{-1/2} $
で囲うと計算は楽にはならず。

級数展開しての $\displaystyle x^4 $ の係数なので求めるものは
$\displaystyle \frac{f''''(0)}{4!} $
になります。留意。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/9c3cd593-df1b-9b29-2fed-3a5a8b3b4dbb.png)

## コードで解決
f''''を直接求められるので
コードでは極めて簡単に。。。`sympy`ステキ

手計算では15分かかったのに。。。


```python
# 変数定義
x = symbols('x', real=True)

# 関数定義
f = sqrt(2*x**2 -x + 1)
display(f)

# ４階微分
f.diff(x, 4).subs(x, 0)/factorial(4)
```
![Screenshot from 2023-01-09 18-29-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/79041ab7-cc43-0c73-098a-de6446ed9242.png)
数学_36

## 考察
極限値を持つ
級数展開を行うと何かしら条件が見えてくる（はず）。

級数展開して $\displaystyle x $ の次元から判断。
a=1の縛りが見えてくる。

あとはその前提で級数展開結果から極限値を計算して左辺と一致。
ｂが見えてくるはず。

## コードで解決
```python
# 変数定義
a, b, x = symbols('a b x', real=True)

# 関数定義
f = (x**2 * sin(b*x))/(a*x - sin(x))
display(f)

# 級数展開
series(f, x, n=3)

# 級数展開結果が値を持つこと、分子→０のため分母→０でなければならない
# 故に a=1と確定する
_a = 1
display("a = 1")
```
![Screenshot from 2023-01-09 18-16-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/4d4d7919-2ced-b8a6-9ac3-69991c60bd45.png)

aが確定したので
左辺の極限値を算出して右辺と比較、bの値を求める。

```python
_f = (x**2 * sin(b*x))/(_a*x - sin(x))
display(_f)

eq1 = Eq(limit(_f, x, 0), 3)
display(eq1)
_b = solve(eq1, b)[0]

print(f'解答')
display(6*_a * _b)
```
![Screenshot from 2023-01-09 18-17-40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/1c328ec0-71e6-3cf9-1c06-abbaac6e1711.png)
数学_35

## 考察
２階微分。
手計算だと１階微分を経由してなのでほしいものを直接取得していない。
sympyだと２階微分を直接取得できるので便利。
微分計算をやるだけ

## コードで解決
```python
# 変数定義
x, y = symbols('x, y', real=True)

# 関数定義
f = exp(-(x**2 + y**2))
display(f)

# ２階微分を直接実行
display(f.diff(x, 2) + f.diff(y, 2))

# 微分、共通因子でまとめる
separatevars(f.diff(x, 2) + f.diff(y, 2))
```
![Screenshot from 2023-01-09 17-55-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/2a3abb4f-0d4a-cdc8-b60a-755db32785c3.png)
数学_34

## 考察
問題分の誘導（？）に従って微分すると
どうやら微分方程式になる。

$\displaystyle f(x)cosx = f'(x)-cosx $
から
$\displaystyle (f(x)+1)cosx = f'(x) $
故に
$\displaystyle (f(x)+1)cosx = (f(x)+1 )' $
が導かれて積分につながる流れ。

$\displaystyle \log|(f(x)+1)|  = sinx + C1 $

## コードで解決
```python
# 変数定義
x, t = symbols('x t', real=True)

# 関数定義
f = Function('f')
g = integrate(f(t)*cos(t), (t, 0, x))
h = f(x) - sin(x)
display(g,h)
display(g.diff())
display(h.diff())

eq = Eq(g.diff(), h.diff())
display(eq)
solve(eq, f(x))
```
![Screenshot from 2023-01-09 17-25-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/f5e3c2d7-b677-133f-8b24-c1de3344a336.png)


なんかうまく解けてない
sympyには微分方程式に対応するライブラリがある。

```python
# 微分方程式を分類
print(f'アルゴリズム提案')
display(ode.classify_ode(eq))

# 常微分方程式を解く
print(f'解く')
display(ode.dsolve(eq, hint = "factorable"))

# 初期値を与える
print(f'初期値を与えて解く')
display(ode.dsolve(eq, hint = "factorable", ics = {f(0):0}))
```
なんと、、そのままの式から`sympy`が解いてしまう

![Screenshot from 2023-01-09 17-18-45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/9600fcf5-7975-d734-3c11-dfa9a81ce8aa.png)
数学_32

## 考察
logの積分、いろいろ定番はある。
$ \displaystyle \int_2^3 log({x-1}) dx →  \int_2^3 (x-1)'log({x-1}) dx $
この状態にして部分積分

## コードで解決
式変形なく一発演算
```python
# 変数定義
x = symbols('x' , real=True)

# 関数定義
f = log(x-1, E)
display(f)

# 積分計算
integrate(f, (x, 2, 3))
```

![Screenshot from 2023-01-09 16-24-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/d1bc6bfa-f0c3-2fac-faff-281162100fc5.png)
数学_31

## 考察
行列で考える。
次元が潰れるからDet=0
ここから解く

## コードで解決
```python
# 変数定義
k = symbols('k', real=True)

# 行列定義
A = Matrix([
    [-2, 2, 2],
    [1, -3, 4],
    [-3, 5, k],
])
display(A)

# 潰れることからDet＝０
print(f'解答')
solve(A.det(), k)[0]
```
![Screenshot from 2023-01-09 16-17-56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/cf3e25ab-8f6e-f320-24dc-aade14407b71.png)
数学_30

## 考察
ベクトルの大きさ、ノルムですね。懐かし。
単純計算。

## コードで解決
```python
# 変数定義
k = symbols('k', real=True)

# ベクトル定義
a = Matrix([
    [2, -1]
])
b = Matrix([
    [-1, 3]
])

# ベクトル生成
p = k*a + b
display(a, b, p)

# ノルム生成
p_norm = p.norm(ord=2)
display(expand(p_norm**2))

# 範囲での最小値を求める
## sympy.minimam(関数,x ,sympy.Interval(範囲))
print(f'normの最小値')
minimum(expand(p_norm**2), k, Interval(-1, 3/2))
```
![Screenshot from 2023-01-09 16-07-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/8226a522-47ae-9530-88a2-f8fd25102d10.png)
数学_29

## 考察
確率密度関数の特性と平均、分散計算定義
計算自体は容易だけど計算そのものはめんどい。
３分ぎりぎりくらい

## コードで解決
```python
# 変数定義
x, a = symbols('x a', real=True)

# 関数定義
f = a*(x-x**2)
display(f)

# 条件からaを確定させる
eq1 = Eq(integrate(f, (x, 0 ,1)), 1)
display(eq1)
print(f'aの値を確率定義から確定')
display(solve(eq1, a)[0])
a_ = solve(eq1, a)[0]

# 改めて関数定義
g = a_*(x-x**2)
display(g)


# 分散を求める
## まず平均
mu = integrate(x*g, (x, 0, 1))
print(f'mu:= {mu}')

# 分散
var = integrate(x**2*g, (x, 0, 1)) - mu**2
print(f'var:= {var}')

# 解答
print(f'解答')
print(f'a = {a_} , var = {var}')
```
![Screenshot from 2023-01-09 15-53-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/e2608bb1-4340-fafc-139e-c5a9958c02c0.png)
数学_27

## 考察
この手の問題は`sympy`が得意と思う。
３分。。。無理。

## コードで解決
期待通りめんどい計算を一発解答。

```python
# 変数定義
x, a, b, c, d = symbols('x, a, b, c, d', real=True)

# 関数定義
f = a*x**3 + b*x**2 + c*x + d
display(f)

# 条件定義
eq1 = Eq(f.diff(x).subs(x, -2), 0)
eq2 = Eq(f.diff(x).subs(x, 4), 0)
eq3 = Eq(f.subs(x, -2), 15)
eq4 = Eq(f.subs(x, 4), -12)
display(eq1, eq2, eq3, eq4)

# 解決
## 解答
print(f'解答')
display(solve([eq1, eq2, eq3, eq4], [a, b, c, d]))
```
![Screenshot from 2023-01-09 15-31-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/6ee9e841-3964-7053-6d7c-057599b77eec.png)
数学_26

## 放物線と積分
この手の話はsympyが得意そう

## コードで解決
正・負の部分含めて`sympy`がいい具合に計算してくれるかと思ったけど
そうじゃないみたい。境界で分けて演算。

```python
# 変数定義
x = symbols('x', real=True)

# 関数定義
f = x**2 - 5*x
display(f)

# 面積計算
display(integrate(f, (x, 0, 5)))
display(integrate(f, (x, 5, 6)))

# 面積計算リトライ
print(f'解答')
display(-integrate(f, (x, 0, 5))+ integrate(f, (x, 5, 6)))

# 面積計算リトライ（積分範囲をまとめて？）
## NG、正負部分を見極め必要
display(integrate(f, (x, 0, 6)))
```
![Screenshot from 2023-01-09 15-23-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/71b49b07-5801-eb4b-d0b2-31b0deae574e.png)
数学_Q24

## 考察
$ \displaystyle x^{log_{ 10 }x} = 1000\sqrt{x} $

対数をとって計算

## コードで解決
一発解決
```python
# 変数定義
x = symbols('x', real=True)

eq = Eq(x**log(x, 10), 1000*sqrt(x))
print(f'解答')
display(solve(eq, x))
```
![Screenshot from 2023-01-09 15-02-29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/7791effb-68d1-2fd5-3b07-585ee51363c6.png)
数学_22

## 考察
袋から異なる色の球を取り出す組み合わせ・確率
値ではなく確率の順番、分母はみんな一緒になるので
分子の計算で判断。
シンプルに組み合わせ計算の課題。

## コードで解決
```python
# 変数定義
P_0, P_1, P_2, P_3 = symbols('x_{0:4}', real=True)

# 分母は皆同じ、大小比較なので分子だけ計算
P_0 = nC(5, 0) * nC(10, 3)
P_1 = nC(5, 1) * nC(10, 2)
P_2 = nC(5, 2) * nC(10, 1)
P_3 = nC(5, 3) * nC(10, 0)

# 結果格納
result = {'P0': P_0, 'P1': P_1, 'P2': P_2, 'P3': P_3}
print(result)

# 解答
print(f'解答')
sorted(result.items(), key=lambda x:x[1])
```

よさげ
![Screenshot from 2023-01-09 13-24-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/d0be1d40-0b2c-4039-6c28-b47e51f1557c.png)
数学_Q20

## 考察

$ \displaystyle 2000\frac{\int_0^1 (1-x^{20})^{100} dx}{\int_0^1 (1-x^{20})^{101} dx} $

$ \displaystyle  I_n = \int_0^1 (1-x^{20})^{n} dx $
とおいて
$ \displaystyle  I_{101} = \int_0^1 (1-x^{20})^{101} dx $
から
$ \displaystyle  I_{100} = \int_0^1 (1-x^{20})^{100} dx $
部分を抽出して漸化式の方針。
$ \displaystyle  (1-x^{20})^{101} = (1-x^{20})(1-x^{20})^{100} $
から計算。
$ \displaystyle  I_{101}とI_{100}$ の関係を漸化式でつくる

しかし、、、これ３分で計算し切る？

## コードで解決
返ってこない・・・
そりゃそうだろうなあ。３分経過でギブアップ。

この手のものは単純に演算コードだけでとはいかない模様。

![Screenshot from 2023-01-09 12-14-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/182c00e4-cc7f-e482-ba9b-d41baebeb568.png)
数学_Q19

## 考察
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/dcb22320-e3ec-af7c-c516-40f1ffdd0461.png)

$ \displaystyle xy の係数なので \frac{1}{2!}と 2xy $ の関係に注意して計算。
偏微分。分数と２変数の偏微分がからんで計算量多め。３分でいけるか？
atanの微分と分数の微分。

## コードで解決
sympyではどうやら２変数の偏微分をサポートしていない。
なので`series（マクローリン展開）`はこのケースでは使用できない。
計算の過程をトレースする。

```python
# 変数定義
x, y = symbols('x y', real=True)
a, b = symbols('a b', nonzero=True)

# 関数定義
f = atan(a*x + b*y + 1)
display(f)

# 偏微分
display(f.diff(x))
display(f.diff(x).diff(y))

# 偏微分演算
## x,yの値渡しかた：留意
print(f'解答：xyの係数')
display(f.diff(x).diff(y).subs([(x, 0),(y, 0)]))
```
![Screenshot from 2023-01-09 12-05-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/bee978c2-e24c-8bf2-44da-a91f4117696f.png)
数学_Q18

## 考察
三角関数の極限値、公式を適用できるようひと工夫。
$ \displaystyle \lim_{ x \to +0 } \frac{sinx}{x} = 1 $

$ \displaystyle \lim_{ x \to +0 } \frac{sinbx}{sinax} = \lim_{ x \to +0 } \frac{sinbx}{bx}b\frac{ax}{sinax}\frac{1}{a} $ とすれば見えてくる。

## コードで解決
式変形考慮なく演算可能。

```python
# 変数定義
x = symbols('x', real=True)
a, b = symbols('a b', nonzero=True)

# 関数定義
f = sin(b*x)/sin(a*x)
display(f)

# 極限値
print(f'極限値 x->0')
limit(f, x, 0)
```
![Screenshot from 2023-01-09 11-32-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213343/8462a9ab-5407-c767-7ae9-be13d12d42b3.png)