OmniAICreator/Qiita-1.07M huggingface dataset:
API31以上をターゲットにした時の変更点をざっくりと（UXについて）

# まもなくAndroid12！
最終beta版がリリースされて、いつリリースなのか推測が色々なされています。
QAエンジニアとのコミュニケーションで必要になってくる場合もあるのでチェックしておこうと思います。
今回はAPI31以上をターゲットにした時のUX変更点に関していくつかピックアップしたいと思います。

# UXの変更点
### ピクチャー イン ピクチャーの動作の改善
ピクチャーインピクチャーとは、Android8から導入された機能で、メイン画面でActivityを操作しながら別のActivityを画面の片隅に表示させられるというものです。

GoogleMapなどで体験したことある人多いと思います。

これに関して、いくつか動作変更が起きました。

例えば、PIPモードに入る時のジェスチャーナビゲーションは、ホームに戻るアクションを検知してからでしたが、新しくできたAPI `PictureInPictureParams` によりコールバックを待たずして `setPictureInPictureParams` を呼び出せるようになりました。

かなりスムーズな遷移が出来そうです。

### カスタム通知
基本的にバージョンごとのレイアウト互換性を保つためにテンプレートが用意されていますが、ユーザーの細かいニーズに応えるためにカスタム通知が許容されていました。

しかし、やはり互換性は保てなくなる状況が出てきてしまうので、それに対する改善が行われました。

そこで、中身のコンテンツ部分だけカスタムできるようにして、外観や動作をシステムが用意しているテンプレートで一貫させました。

<!--
 ### Android アプリリンクの検証に関する変更
これ何なのか全く分からなかったのですが、アプリリンクとはURLから（インストールされていれば）特定のアプリかもしくはWebページに直で誘導させるものみたいです。

似ているものとして、ディープリンク。
こちらは、特定のアプリのコンテンツに直で飛ばすリンクです。 
-->




# 終わりに
色々あるので、全部書くのはやめときました。

それとディープリンクとアプリリンクの違いとアプリリンクの検証が何をするのか良く分からなかったので飛ばしました。

他の変更点は、開発していて意図しない挙動が見られたらその都度確認するのが良さそうです。

# 参考

https://developer.android.com/about/versions/12/behavior-changes-12?hl=ja
【ちょっとした実験】ゲームのバトルマッチシステムの妥当性をシミュレーションする

# 概要
いわゆるソシャゲーというものの多くにはプレイヤー対戦やチームバトルというのがあります。
**とあるゲーム** のチームバトルは下記のように運営されます。

* 「ランク」の同じチームがマッチングされる（きっとランダム）
* ランクはS,A,B,C,Dとある
* 3回勝つとランクアップし、3回負けるとランクダウンする
    * ただしSランク以上にはならない。また、Cランク以下にもならない。（D→Cは上がるだけっぽい）

ここで個人的に謎だったのは、負けても勝利回数は減らないし、逆に勝っても敗北回数は減らないというところ。
これでランク間に変な偏りが発生したりしないんだろうかと検証したくなりました、という話。

単純なプログラムなので特に技術的に面白いことはないです。

# 検証
## シミュレーションのためのモデル化

バトルの勝ち負けは戦術や相性などにも影響されますが、そういうのは省いて下記のような単純なモデルを考えシミュレーションします。

* 5000のチームがある
* チームは順番に1,2,...5000の戦闘力を持ち、それは変動しない
* シミュレーション開始時点ではすべてのチームはDから始まる
* 各ターンごとに同じランク内でランダムにマッチングさせる
* 勝敗はチームの戦闘力の比較で決まる。乱数などは含めない。

## コード
https://gist.github.com/hakua-doublemoon/f0df1a081177342e4ddfc57f7beb7c8a

## シミュレーション結果
私の考えでは、ランク間の偏りが発生する、でしたがそういうことはなかったです。

とあるターンでのチーム数の分布:

| ランク | ランク内のチーム数 |
|---|----|
| D | 1  |
| C | 1075 |
| B | 1409 |
| A | 1413 |
| S | 1102 |

普通にSランクはやや少ないです。
Dランクは最弱のチームが１つ取り残されます。かわいそうですね。
少し意外なのはCランクで、これもSランクと同程度の少なさでした（むしろSランクより少なめ）。
Cランクに落ちてもすぐにランクアップするチームが多いようです。
Pipenvで普通にLockされない時の対処

最近Pytorch環境を作る際にいろいろ面倒なことがあったので作業メモ。

# 1. なぜpipenvを使っているのか
対応の開発環境(主にOS)の違いで、良い感じのDockerコンテナを作れていないので。  
特にcuda絡みがしょっちゅう環境で変わるので、cudaはcudaでしばらく単独で扱いたい。  

# 2. 発生した問題
[Pytorchのページ](https://pytorch.org/)で吐かれたインストールコマンドをそのままpipenvに渡すとPipfileのLockに失敗する。  
たとえば、

```bash
pipenv install torch==1.9.1+cu111 torchvision==0.10.1+cu111 torchaudio===0.9.1 -f https://download.pytorch.org/whl/torch_stable.html
```

これを解決するために```verbose```オプションを指定して直接wheelを指定することにした。  

# 3. wheelの探索
先のコマンド例の```-f```オプションの[引数のページ](https://download.pytorch.org/whl/torch_stable.html)に対象のwheelは存在する。  
しこたまあるので、先ほどのコマンドの引数を参考に対象のwheelを検索する。  
今回の環境ではPythonは3.9系を使っている。  
まず、```torch==1.9.1+cu111``に対応するtorchを探す。  
CUDAのバージョンが重要なのでここでは、11.1を示す```cu111```で絞り込む。  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154030/4919b39a-15a9-afa6-d153-f2d6240ebfca.png)

こんな感じ。ここで```cu111/```で始まるリンクのうち、1.9.1でcpが39(Python 3.9系)でwindows向けの物を今回は探した。  
リンク先のアドレスをコピーしたものが以下。

```
https://download.pytorch.org/whl/cu111/torch-1.9.1%2Bcu111-cp39-cp39-win_amd64.whl
```

これをpipenv install の--verboseオプションで与えてインストールする。  

```
pipenv install --verbose "https://download.pytorch.org/whl/cu111/torch-1.9.1%2Bcu111-cp39-cp39-win_amd64.whl"
```
これで、インストールが可能。  
同様に```torchvision```や```torchaudio```を入れれば完了。
ログアウトすると419セッションエラー画面が出る（Laravel）

プログラミング初心者です。

##問題
LaravelのAuthを使ってログイン、ログアウト機能を実装しました。
しかし、「ログアウト→戻る→ログアウト」をすると419画面が出てきてしまいます。

##解決方法

app/Exceptions/Handler.phpに追加実装します。


```Handler.php
<?php

namespace App\Exceptions;

//追加1
use Illuminate\Session\TokenMismatchException;

class Handler extends ExceptionHandler
{
    public function render($request, Exception $exception)
    {
        // 追加2
        //エラー画面をユーザーに見せる必要はないので、ログイン画面にリダイレクトさせる
        if ($exception instanceof TokenMismatchException) {
            return redirect('/login');
        }

        return parent::render($request, $exception);
    }

}
```
- namespaceの下に追加1を記載します。
- class Handlerの中に元から色々なメソッドがありますがその中のrenderメソッドの中に、追加2を記載します。

自分はこれで解決できました。
【PHP】【メモ】文字列連結の「.」「,」の違い

echoは「.」「,」両方使える
printは「.」のみ使える

「.」は連結した結果を出力する
「,」は連結せずに順次出力する

「.」は連結してから出力するため、「,」よりもやや遅い。
XSSF(xlsx)を扱う3種類の方法とメモリ消費量について

注意: 基本的にはこのあたりのドキュメントを読めばよい話ですが、自分用に簡単にまとめておきますね(´・ω・`)

- https://poi.apache.org/components/spreadsheet/
- http://poi.apache.org/components/spreadsheet/how-to.html#xssf_sax_api

JavaでExcelを操作するライブラリであるApache POIでは、HSSFとXSSFという2種類に対応しています。ざっくりいうとHSSFは拡張子がxlsのファイル、XSSFは拡張子がxlsxを扱います。Excel 2007以降はxlsxが標準となっているので、ここではXSSF/xlsxについて記述します (新規システム構築でHSSF/xls対応が必要なことはない…よね?)。

さて、XSSF/xlsxの読み書きに際して、Apache POIは大きく分けて3種類のAPIを用意しています。

① User API 

読み書き両方が可能。Google検索でよく引っかかるのは大体これ。いかにもJavaらしいオブジェクト指向的なAPIで、わかりやすく使いやすいのですが、読み書きするファイルの中身をすべてメモリ上に展開するため、メモリ消費がかなり激しいです。Out Of Memoryの原因になりがち。

② Streaming Usermodel API (SXSSF)

一応読み込みもできなくはないのですが、実質的には書き込み専用。User API互換で、特徴はメモリ消費量が少ないこと。これは一定量書き込むたびに一時ファイルへ書き出す作りになっているからで、書き込み時にOut Of Memoryなどを起こしている場合には、こちらに切り替えると、問題が解決する場合があります。ただし、一時ファイルに一度書きだした行は読み込みも書き込みもできないなど、若干使い方に癖があるため、ここは注意して使いましょう。

③ Event API

読み込み専用のAPIで、API体系や使い方は上記2つのAPIとは全く違います。名前の通り、イベントドリブン的に処理ができるAPIで、User APIに比べて、メモリ消費量が少なく、高速にxlsxファイルの読み込みが可能です。User APIを使ったExcelの読み込み処理で、Out Of Memoryを起こしている場合の代替案にすることが多いです。デメリットとしては、若干マイナーで、Google検索でもなかなかサンプルが見つからないことでしょうか。一応、[公式にサンプルコードは用意されています](https://svn.apache.org/repos/asf/poi/trunk/poi-examples/src/main/java/org/apache/poi/examples/xssf/eventusermodel/XLSX2CSV.java)が、複雑なことをやろうとすると、サンプルが転がっておらず、途端に難易度が上がります。

個人的な経験では、Apache POIを利用する場合、おうおうにしてメモリ消費が問題となります。Out Of Memoryとの戦いですね。上記3種類のAPIをうまく活用して、開発のしやすさとメモリ消費量の両天秤でうまく開発を進めていきたいものです。
【PHP】エルビス演算子

# エルビス演算子
**PHP5.3から導入**
**三項演算子の第二項が省略できるもの**

```
三項演算子
$a ? $a : $b;

エルビス演算子 // 第二項が省略されている
$a ?: $b;

上記の2つは同じ動きをする
```

[公式](https://www.php.net/manual/ja/language.operators.comparison.php#language.operators.comparison.ternary)から抜粋
> 式 expr1 ?: expr3 の結果は、expr1 が true と同等の場合はexpr1、 それ以外の場合は expr3 となります。

例えば

```
$a = 'Aです';
$b = 'Bです';

echo $a ?: $b;

//出力

Aです
```
```
$a = false;
$b = 'Bです';

echo $a ?: $b;

// 出力

Bです
```
という感じで、第一項がtrueなら第一項が評価され、第一項がfalseだったら第二項が評価される。

# 様々な値で試してみる

|      第一項の値      |   評価された項   |
|       :--:           |       :--:       |
|       'a'            |      第1項       |
|        1             |      第1項       |
|        -1            |      第1項       |
|       '1'            |      第1項       |
|       0.1            |      第1項       |
|      '0.1'           |      第1項       |
|       '0'            |      第2項       |
|        0             |      第2項       |
|       true           |      第1項       |
|       false          |      第2項       |
|       null           |      第2項       |
|     未定義の変数     |      第2項       |
|       空の配列       |      第2項       |

値がfalthyであれば第二項が評価されることがわかる。
iOSアプリでスクショをトリガーにする方法

# はじめに
AmazonPrimeやNetflixでスクリーンショットをとると、黒塗り画面が保存されますよね。
今回はその実行方法が気になり調べたので、記事にまとめました。

# 方法
`userDidTakeScreenshotNotification`っていう機能を使えば、
スクリーンショット後に処理を実行できるみたい。

# 実装
```ViewController.swift
import UIKit

class ViewController: UIViewController {

    // スクショ時、黒塗りするためのView
     @IBOutlet weak var filterView: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad();
        
        // 黒塗り画面を非表示
        filterView.isHidden = false;
        
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(processing(_:)),
            name: UIApplication.userDidTakeScreenshotNotification,
            object: nil)
    }
    
    @objc private func processing(_ notification: Notification) {
        
        // スクリーンショット時に黒塗り画面を表示
        filterView.isHidden = true;
    }
}
```

# 実行結果
実際に実行してみた。
スクリーンショット後に黒塗り画面が表示されることを確認！
ただ、保存される写真は黒塗りされていない...あれ、、、おかしい

# 原因
さらに調べてみたら、`userDidTakeScreenshotNotification`はスクショを取った後に実行されるらしい。
要するに以下の順で処理が実行されているみたい。

1. スクリーンショットボタンを押す
2. 写真が保存される
3. 画面が黒塗りになる

# 最後に
よくある動画配信アプリは他の方法で実装しているみたい。
（この方法はよく分からなかった、、、）
今回の機能は、保存する写真に対しては干渉できないが、スクショを検知することはできる。
IBM CloudのヘビーユーザーがMicrosoft Azure Fundamentals（AZ-900）を受けてみた

<img width="160" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/98edfa3c-f264-812a-b097-cd1743355ad0.png">

# スペック

* IT経験: >20年
* IBM Cloud経験: 7年
* Azure経験: $200のお試しクレジットで少し遊んだ程度

# 動機

* IBM Cloud以外も知っておきたかった
* 実は昔MSファンだった
* （オープンバッジが欲しかった）

# 試験対策

## Microsoft Azure Virtual Training Day: Fundamentals

無料のバーチャルトレーニング。試験の無料バウチャー目当てで受講しました。半日 * 二日間、ほとんど聞き流しで終了。

https://www.microsoft.com/ja-jp/events/top/training-days.aspx?activetab=a1%3aprimaryr3

## これだけで合格！AZ-900: Microsoft Azure Fundamentals模擬試験問題集（7回分430問）

AZ-900対策として有名なコースらしいです。有料（定価2400円）ですが、Udemyとビジネス契約を結んでいる会社の人なら無料で受けられます。

https://www.udemy.com/course/az-900-microsoft-azure-fundamentals4176/

試験の前日と当日に模擬試験1～5を解きました。ぶっつけで6～7割くらいの正答率。答えを見てからもう一周して98%～100%くらい。模擬試験6（130問）は時間がなくて出来ませんでした。学習時間は合計3時間ほどでした。

# 結果

850/1000点で合格しました。合格に必要な点数は700点でした。

# 感想

* 最初にUdemyで見覚えのない問題が続いて焦りました
* とはいえ、Udemyの模擬試験がなかったら危なかったと思います
* クラウドとは的な設問はIBM Cloudの経験でもある程度解けると思います

# IBM Cloudとの違い

次の用語の違いは理解しておくといいかもしれません。

用語|IBM Cloud|Azure
---|---|---
サブスクリプション|事前払い契約のこと|Azureの支払やリソースを分割する仕組み
リソースグループ|リソースグループ間でリソースの移動はできない|できる
オブジェクトストレージ|IBM Cloud Object Storage|Azure Blob Storage
ファイルストレージ|IBM Cloud File StorageはNFS|Azure FilesはNFSとSMB
NoSQL|IBM Cloud Databases for MongoDB, Cloudant|Azure Cosmos DB
セキュリティグループ|セキュリティグループ（SG）|ネットワークセキュリティグループ（NSG）
リージョン間通信|プライベート間なら無料|有料（AZ間は無料）
サーバレス|IBM Cloud Functions, Code Engine|Azure Functions
仮想プライベートクラウド|IBM Cloud VPC|Azure Virtual Network（仮想ネットワーク）
【Git】GitHubの新機能を初心者でも使えるか試してみた


#対象者

* Gitの新機能に関して知りたい方


#目的

* Gitの新機能を使ってみて自分の今後の開発に役立てること

#実際の手順と実例
###1.GitHubでリモートリポジトリを選択

自分はスクールで使用している本の投稿サイトを例に使ってみます。

自分のリモートリポジトリを開いて、、、
![スクリーンショット 2021-08-14 8.10.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681213/96f478c9-d1fa-ed62-8c31-a569c6d32eef.png)

ここでドットを押すと、、、、

![スクリーンショット 2021-08-14 8.12.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681213/2f22ea75-fad2-5761-8c76-b9aa4f5cceb6.png)


VSコードみたいなの出た！


###2.試しにREADMEファイルを編集してみる

![スクリーンショット 2021-10-03 18.40.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681213/89739355-2610-739d-7c70-d805097a8b04.png)

①をクリックして
②でコミットメッセージを入力
③の✅マークを押すと変更されました。

![スクリーンショット 2021-10-03 18.44.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681213/d8ddaa10-2083-06bd-2887-086089c6651e.png)

まだ全然使えていないですが、どんどん使って慣れていこうと思います。

色々調べてまた書きます！

今の所、調べてみると
・ターミナルが使えない
・使えない拡張機能がある

などデメリットもあるみたいですが、

OS問わず、動作も軽くて、コミットもプルリクもできるので便利です！
vscodeでdockerコンテナに入る(windows10)

vscodeでdockerコンテナに入る備忘録。

vscodeの拡張機能「Remote-Containers」をインストールする。

vscodeでリモートエクスプローラーを選択し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495919/9979234f-38f7-da5c-53dd-cc283cb3a35c.png)
dockerコンテナに入る項目を右クリックして、「Attach in New Window」を選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495919/91e05cd9-dc68-da92-1ae5-f45e7c436784.png)

コンテナに入れた!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495919/4c637e74-f567-0829-7f96-9cbde65c6197.png)
ポート疎通確認方法

# はじめに

疎通確認で`ping`を使用する機会が度々あるが、
通信先がICPMプロトコルを許可していない場合、
特定ポートに対しての疎通確認を実施したい場合がある。

本記事では、MACやwindowsで使用できるポートを指定した疎通確認方法について記載する。

# MAC編

## nc(netcat)コマンド

### コマンド
``` 
nc　-vz　{IPアドレスorドメイン}　{ポート}
```

### 成功時
```
$ nc -vz google.com 80
Connection to google.com port 80 [tcp/http] succeeded!
```

### 失敗時
```
$ nc -vz google.com 81
nc: connectx to google.com port 81 (tcp) failed: Operation timed out
```

## curlコマンド

### コマンド
```
curl -I {IPアドレスorドメイン}:{ポート}
```

### 成功時
```
$ curl -I www.google.com:80
HTTP/1.1 200 OK
Content-Type: text/html; charset=ISO-8859-1
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Date: Sun, 03 Oct 2021 09:24:04 GMT
Server: gws
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Transfer-Encoding: chunked
Expires: Sun, 03 Oct 2021 09:24:04 GMT
Cache-Control: private
Set-Cookie: 1P_JAR=2021-10-03-09; expires=Tue, 02-Nov-2021 09:24:04 GMT; path=/; domain=.google.com; Secure
Set-Cookie: NID=511=ktOtFTcRbid0LdiusrRdSYnOTa3W63s-fcwZxp8mbHZYISVe9vmsX6f1cPeJJ6hC_nm5XA3_fXpURlFEl-utQcAv4javRXiAssgGUUO1AiacMwgGT1pu8dihyrygUXRC4fBtV59tm-8NwkUabqd4rjF6ua7YXWSqDDETDrWo-fg; expires=Mon, 04-Apr-2022 09:24:04 GMT; path=/; domain=.google.com; HttpOnly
```

### 失敗時
```
$ curl -I www.google.com:81
curl: (7) Failed to connect to www.google.com port 81: Operation timed out
```

# Windows

## Test-NetConnection (PowerShell)

### コマンド
```
> Test-NetConnection {IPアドレスorドメイン} -Port {ポート}
```

### 成功時
```
> Test-NetConnection www.google.com -Port 80                                                                                                                                                                                                                                                                                                   ComputerName     : www.google.com
RemoteAddress    : 172.217.175.4
RemotePort       : 80
InterfaceAlias   : Wi-Fi
SourceAddress    : 10.229.71.193
TcpTestSucceeded : True
```

### 失敗時
```
> Test-NetConnection www.google.com -Port 81
警告: TCP connect to (172.217.175.4 : 81) failed

ComputerName           : www.google.com
RemoteAddress          : 172.217.175.4
RemotePort             : 81
InterfaceAlias         : Wi-Fi
SourceAddress          : 10.229.71.193
PingSucceeded          : True
PingReplyDetails (RTT) : 6 ms
TcpTestSucceeded       : False
```
chartckickで円グラフを実装（２つのモデルにまたがるデータ）


# 概要
[家計簿WEBアプリ](https://www.kyodokoza.com/)で、月毎やカテゴリ毎に支出を可視化したい！
→グラフを簡単に導入したい！
→chart.jsってのがあるらしい！
→でも、基本的な使い方以外の記事が少ないな…。

ということで、自分なりに試行錯誤した内容を記事にしてみました。

なお、導入や基本機能については以下記事を参照してください。
[公式のgithub](https://github.com/ankane/chartkick)
[導入方法と基本機能](https://qiita.com/Y_uuu/items/0d57748954c7cdb9bbcb)

# 開発環境
Ruby 2.7.4 / Ruby on Rails 6.1.4 / RSpec<br>
Docker / Docker-compode / CircleCI(CI/CD) / Heroku / SendGrid(mailer)

# 完成のイメージ
以下のモデルのアソシエーションから、
![ER2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1766860/4c2a033a-6e54-55e5-5a4a-f456a1d7e90e.png)

以下のようなグラフを作りたい。
Post（支出）モデル元にカテゴリと月毎にまとめたデータを可視化する。
グラフをタップすると、カテゴリ名と支出の小計が表示される

![スクリーンショット (55).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1766860/94b1a667-13ee-2bc6-fdb8-2c98c338debe.png)

つまり必要なのは、 **Category.name, Post.priceの合計, Category.color** あたり。
CategoryとPostの２モデルにまたがっているので、面倒そう…。

#### 作りたいデータの形
いくつかの記事を見ていると、
以下のような１つのモデル内で２カラムを取り出すような形の取り扱いが多い。

```
<%= pie_chart RugbyWorldCupHostCountry.pluck(:held_at, :total_attendance) %>
```
２モデルにまたがっているの場合はどうすれば…？
…[調べてみると](https://chartkick.com/)、でーたの形式は以下のように
index(今回で言う"category.name")とvalue(今回で言うところの"post.price")配列になっているのだそう。

```
[[data1_index, data1_value], [data2_index, data2_value], … ]
```
ここまでわかれば後は簡単なはず！


# 実装

こうすれば、適宜@monthの値を変えて、前月のグラフなども出せます。

```controller/hoge.rb  
  def month
    family_category_ids = @relationship.category_ids
    # 今月の１日を取得
    @month = Time.zone.now.beginning_of_month

    # 空の配列を用意
    @pie_chart = []

    # カテゴリ毎にループを回す
    family_category_ids.each do |c_id|
      @pie_chart.push(
        [Category.find_by(id: c_id).name, 
          Post.where(category_id: c_id, payment_at: @month.all_month).sum(:price)]
      )
    end

    # @pie_chartとは別にcolorsの配列も用意
    @pie_chart_colors = Category.where(id: family_category_ids).map(&:color)
  end

```
<br>
以下では少しスタイルをいじっています。

- legend: {display: false}で、凡例を消す
- donut: trueで真ん中に穴


```views/hoge.html.erb
  <%= pie_chart @pie_chart,legend: {display: false}, donut: true, width: "200px", height: "200px", colors: @pie_chart_colors %>
```

# さいごに
以上です。
質問や、「ほかにもこんな実装方法があるよ！」などコメントいただけると幸いです。
どなたかのためになればうれしいです。
世にも奇妙なデフォルト引数の話

# この記事は？
pythonの本を読んでいたらデフォルト引数に関して気になる記載を見つけたので実際に自分でも調べてみました。
要は**デフォルト引数に動的に変化するものは使うな！**ってことと**デフォルト引数に更新可能なものを使うな！**ってことが分かります。

# デフォルト引数に動的に変化するものは使うな！
デフォルト引数に動的なものを使用するとモジュールが読み込まれたタイミングでしか読まれないため都度変化させたいケースでは想定通りの動きとなりません。
実際に下記のようにコードを書き確認してみると分かります。
## 検証コード
``` python:time_test.py
from datetime import datetime
from time import sleep

def time_test(time_test=datetime.now()):
  print(f"time_test: {time_test}")

time_test()
sleep(1)
time_test()

time_test(datetime.now())
sleep(1)
time_test()
```
## 出力結果
```
time_test: 2021-10-03 17:54:41.832564
time_test: 2021-10-03 17:54:41.832564
time_test: 2021-10-03 17:54:42.845571
time_test: 2021-10-03 17:54:41.832564
```

## 分かること
モジュール読み込み時の時間がデフォルト値に設定されたら今後その設定値が変わることなく
仮に引数に値が指定された場合でも最初に設定されたデフォルト値が維持されます。

# デフォルト引数に更新可能なものを使うな！
デフォルト引数に更新可能なものを使用した場合、その引数をそのまま使いまわしてしまいます。
実戦で今回検証するようなコードを書くケースは少ないかもしれませんが、安全を考えれば使用しないほうが良いかなと思いました。

## 検証コード
```python:test.py
def dict_test(dict_test={'default': 1}, add_value='test'):
  print(f"dict_test: {dict_test}")
  print(f"add_value: {add_value}")
  dict_test[add_value] = add_value
  add_value = '更新したよ'

dict_test()
dict_test()
dict_test({'test3': 'test3'})
dict_test()
dict_test({'test2': 'test2'}, 'test4')
dict_test()

```

## 出力結果
```
dict_test: {'default': 1}
add_value: test
dict_test: {'default': 1, 'test': 'test'}
add_value: test
dict_test: {'test3': 'test3'}
add_value: test
dict_test: {'default': 1, 'test': 'test'}
add_value: test
dict_test: {'test2': 'test2'}
add_value: test4
dict_test: {'default': 1, 'test': 'test'}
add_value: test
```

## 検証から分かること
デフォルトで使った引数がそのまま使用されるので2回目の呼び出しの時は1回目の呼び出し時の'test'がキーに追加されて表示されています。
3回目の呼び出しのタイミングではデフォルト値は使用されないので引数で与えられた値が使用されてしまいます。
4回目の呼び出しではデフォルト値は2回目の呼び出しで更新されてから変わってない(1回目と同じ値なので実質1回目から変わっていない)のでそのままです。
5回目の呼び出しでデフォルト値ではない同名の辞書を更新しましたが、6回目の呼び出しでデフォルト値は2回目の呼び出しと同じでした。
また、add_valueのように更新不可能な値であれば仮に関数内で変更を加えても変わることはありませんでした。

# 解決策
共にデフォルト引数にはNoneを指定して関数内でNoneの場合にデフォルト値を設定するように書けば解決できます。

## 記載例
```python:test.py
def time_test(time_test=None):
  if time_test is None:
    time_test = datetime.now()
  print(f"time_test: {time_test}")

def dict_test(dict_test=None, add_value='test'):
  if dict_test is None:
    dict_test = {'default': 1}
  print(f"dict_test: {dict_test}")
  print(f"add_value: {add_value}")
  dict_test[add_value] = add_value
  add_value = '更新したよ'
```

# 終わりに
今回はコメントを省略しているのですが、実際にコーディングするときはデフォルト値が何になるか？ということも補った方がよさそうですね。(読んだ本にも書いてありました…)
知っている人からしてみればそんなの当たり前だろうという内容なのかもしれないのですが、私の直感とは反するので知らないとはまってしまいそうだなと思って具体的な動きを確認して記事にしてみました。
デフォルト引数を書くときは思い出していただければと思います。
【Laravel】モデルの作成（初心者向け）

#はじめに
今回は、Laravelでのモデル作成方法について見ていきます。

#モデルとは
MVCモデルのMの部分で、データベースとのやりとりを行い、必要なデータをコントローラーに渡します。

#モデルの作成方法

```php:ターミナル
php artisan make:model Models/モデル名
```

モデルが増えてきたときのために、Modelディレクトリを作ってその中にモデルを作成しています。
実際には、`Menu.php`のように`モデル名.php`というファイルが作成されます。

#オプション
オプションを付けることで、モデルの作成と同時にマイグレーションやファクトリなども生成することができます。

```php:ターミナル
php artisan make:model Models/モデル名 -f //ファクトリを同時に生成
php artisan make:model Models/モデル名 -m //マイグレーションを同時に生成
php artisan make:model Models/モデル名 -c //コントローラを同時に生成
php artisan make:model Models/モデル名 -s //シーダーを同時に生成
```
ほかにもオプションはあるので、気になる人は確認してみてください。

#モデルの中身
作成したモデルを開いてみると、以下のような記述がなされています。

```php:モデル
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class モデル名 extends Model
{
    //
}

```

#モデルの命名規則
モデル名には、テーブル名の単数バージョン、かつ、アッパーキャメル記法を使います。
具体的には、`menus`というテーブルを作成したのであれば、モデルは`Menu`になります。

#おわりに
以上で、モデルの作成は完了です。
中身の記述等についてはまた別の機会で書いていきたいと思います。
[Ruby] AtCoder過去問 C - Tax Increase

##はじめに
AtCoder過去問C問題をRubyで解いてみました。
よろしくお願いします。

問題はこちらから確認してください↓

https://atcoder.jp/contests/abc158/tasks/abc158_c

##C - Tax Increase
まずは入力を受け取ります。
最終的に答えとなる変数ansを用意して、条件を満たす税抜き価格が存在しなかったときに出力する-1を代入しておきます。


```ruby
a, b = gets.split.map(&:to_i)

ans = -1
```

続いて消費税は制約からmax100とわかります。つまりmaxの税抜き価格は1000だということです。
1000程度であったらeach文で回せるので1~1000をeachで回してそれぞれの消費税を求めてその答えがaとbと等しいかif文で分岐させます。

ほとんどがfalseを返しますが、trueになったときにansを書き換えてbreakで処理を抜け出します。

最後にansを出力すれば完成です。

```ruby
a, b = gets.split.map(&:to_i)

ans = -1

(1..1000).each do |i|
  if (i*0.08).floor == a && (i*0.1).floor == b
    ans = i
    break
  end
end

puts ans
```
フロントエンド開発の色々

フロントエンド開発について興味があるので，どういったやり方があるのか勉強がてらまとめてみました．

## Traditional Way (伝統的によくあるやり方)
ブラウザからのリクエストに対して、サーバはバックエンドのAPIを実行し、必要な情報をあつめて、都度HTMLを生成して応答します。

![traditionalWay.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580420/a64a5b2c-0c2e-6ef1-79ec-af390dc0fbb8.png)

## Single Page Application (SPA)
SinglePageApplicationとは，単一のページで構成されるアプリケーションです．
初回のみHTML/CSS/JSのセットをホスティングサーバから取得したら，あとはブラウザでHTMLをレンダリングします．
ブラウザが直接バックエンドとやりとりして動的にページを更新します．
ReactやVueはSPAのフレームワークです．

![spa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580420/a8689fa5-eac1-8254-56b4-7df31418ef64.png)


### SPAの問題点
- SEO対策

Web検索エンジンのクローラからみて，SPAのページは，javascriptが解釈される前は真っ白のページになっています．これでは，クローラに見つけてもらうことができません．ただし，最近のGoogleのクローラは，javascriptを解釈してくれるので，この問題の影響は少し小さくなりました．

- 初回の読み込みに時間がかかる

最初に全てのコンテンツを読み込むことになるので，初回の読み込みには時間がかかります．そのかわり，以降の更新は部分的になるため高速になります（図の④と⑤）．

## Sever Side Rendering (SSR)
SSRは，SPAの問題であるSEOが解決されています．
SSRでは，初回のHTMLをサーバサイドでレンダリングします．これにより，レンダリング済みのコンテンツを配信することになるので，クローラに見つけてもらえない問題が回避できます．
Next.jsやNuxt.jsが有名なフレームワークです．

![ssr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580420/cdd144d6-ae83-029d-6a42-12de395688d8.png)

### SSRの問題点
- 初回のHTMLをレンダリングを行うサーバが必要となること

SPAのときにはシンプルなWebホスティングを利用すればよかった（Amazon S3など）のですが，サーバ側でレンダリングをするとなったもんだから，めんどうなことになってしまいました．レンダリングサーバへのアクセス集中への対策やインフラの管理，運用が必要です．

## Static Site Generation (SSG)
SSGでは，SSRのようなレンダリングサーバが必要ありません．
すべてを事前に静的なページとしてレンダリングします．
したがって，レンダリングサーバのアクセス負荷を考慮する必要はなく，単純なホスティングサービスを利用すればよいです．すべてのページが事前にビルドされているため，アクセスに対して高速に応答することができます．
Next.jsやNuxt.jsでは，SSGにも対応しているようです．このほか，GatsbyやHugoなども有名なようです．

### SSGの問題点
- ビルドプロセスの管理

全てのページを事前にビルドするという特性上，少しでもWebページの内容が変わったら，すべてビルドをし直す必要があります．これは結構やっかいな問題です．

- 動的なコンテンツに対応できない

全てのページは事前にビルドされており，ブラウザからバックエンドに通信することはないので，動的な情報を表現することはできません．したがって，そういったことが必要な場合には，これまでに述べてきたSPAやSSRを利用する必要がでてきます．しかしながら，動的に変わる情報を表現しなくても良いのであれば，バックエンドとの通信が発生しないぶん，セキュアであると言えそうです．それぞれ良し悪しがあるといったところでしょうか．

## Incremental Static Regeneration (ISR)
ISRは，SSGと同じく，リクエストに対して静的にビルドされたページを返します．ただし，有効期限を定めており，有効期限がきれたページは非同期的にレンダリングし直されます．
また，ISRでは，一旦アクセスされたら，アクセスされたページのみビルドします．このため，すべてを一度にビルドするSSGと比べるとビルドが短時間で済みます．さらには，ビルド済みのページに再度アクセスがあった場合には，一旦ビルド済みのページを返しつつ，裏で再ビルドを走らせます．こうすることで非同期的にページを更新していくことができ，SSGのようにすべてをビルドし直すことにはなりません．
Next.jsでISRを使えるようです．

## まとめ
作ろうとしているWebアプリが，どういった性質のものなのかによって最適な方法が変わってくると思います．
たとえば，

- SEO対策には力をかけなくてよい，シンプルなホスティングサービスでWebアプリをデプロイしたい

ー＞　SPA

- 頻繁にはコンテンツが変わらないサイトで，シンプルなホスティングサービスでWebアプリをデプロイしたい

ー＞　SSG

といった具合かと思います．

## どうやってデプロイするの？？　AWSでは
じゃあ，それぞれどうやってAWS上にデプロイすればよいのでしょうか．

- SPA, SSG

Simple Storage Service(S3)にコンテンツをホストすることで実現できます．
サーバが不要なため，インフラが非常に簡単です．

- SSR, ISR

これらの方式ではアクセスに応じてレンダリングするサーバが必要です．
サーバといっても運用負荷と自由度とのトレードオフで色々な方法がありますが，最も簡単な方法は，AWS Amplifyを利用することです．
Vue.js、index.html以外にもページを作ってくれ頼む。

速攻でSPAから離れた話題。

使用したもの

* Vue.js
* vue-cli
* Vuetify
* Veevalidation
* Netlify

## おさらい
なんでこんな話をしているかっていうと[前回の記事](https://qiita.com/AS-box/items/dcc105e2aaaaef3c42c1)にて、Netlify formを使った際、フォーム内容をsubmitした後に遷移する画面が静的HTMLでないと飛ばなかったという話から。

じゃあその静的HTMLを作ってしまえと作った訳だが、vue.jsからFontAwesomeまで全部CDNで読み込んで無理やりファイルを作った。
Vueプロジェクトの中に独立したVueファイルがある状態は非常に気持ち悪い。

## 本題：index.html以外のhtmlをpublicに書き出したい。

SPAというのはちょっと置いておいて。。。

当初の構成はこんな状態。
静的thanksページにはCDNで色々読み込んでありhtmlという拡張子がついたVueファイル。（？）

```
src
  |
 public
  |--index.html
　　　　|--thanks.html//←静的thanksページを手動で追加した。
 component
  |-Form.vue
 views
  |--contact
      |--index.vue
      |--thanks.vue

```

そんな状態より、せっかく作ってあった`/src/views/contact/thanks.vue`を使ってthanksページを書き出してあげたい。絶対寂しい思いしてる。

**そもそも`public/index.html`ってどうやって生成されるんだ**

`vue-cli`をインストールしたらもうプロジェクトの雛形ができてるからあまり意識してなかった。
どうして・・・どこかに`app.vue`を/public/index.htmlに書き出せとか・・・
ないんですか？？あるなら出てきてくれ〜〜〜！！！

出てこなかったのですが、解決策は出てきました。
[Vue CLI 3でSPAではなくMPA(複数エントリーポイント)のプロジェクトを作成する](https://qiita.com/kamicop/items/c5c0917ed226234ee288)

か、神〜〜〜〜〜〜！！！！

私は`Vuetify`を使うときに勝手に（？）`vue.config.js`が作られていたみたいだけど、ない時は自分で作ればいいんだろう。
そこに、ハァ〜〜〜エントリーポイントね！！`webpack`でやったやつだ！

上記のありがたい記事を読みながら今回私は`vue.config.js`を次のようにしました。

```
module.exports = {
  transpileDependencies: [
    'vuetify'//このへんは`Vuetify`を使うときに勝手に記述された。ありがとう。
  ],
  pages: {
    index: {
      entry: 'src/pages/main.js', 
      template: 'public/index.html', 
      filename: 'index.html', 
    },
    thanks: {
      entry: 'src/pages/thanks/main.js',
      template: 'public/thanks.html',
      filename: 'thanks.html',
      title: 'お問い合わせありがとうございました。',
      },
  }
}
```
エントリーポイントのファイル名は`main.js`でしかダメなの？
`src/main.js`と`src/thanks.js`にしたかったけどうまく動いてくれなかったのでコードのようにディレクトリを分けてみました。

`src/pages/main.js`が`App.vue`を`public/index.html`を書き出すように、`src/pages/thanks/main.js`が`public/thanks.html`に書き出せるようにvueファイルをつくってあげればいい。

そこで私は`App.vue`と同じ階層に中身はほぼ同じ`ThanksPage.vue`を作ってあげて、`/src/views/contact/thanks.vue`をインポートしてみました。

で！！！！できない・・・？

どうやら、自動で`public/thanks.html`を作ってはくれないみたいなので最初に適当に作っておかないといけないみたい。

最後、危なかったでしたが無事、コンポーネントを使った`public/thanks.html`ができた。
めでたしめでたし。
データベーススペシャリスト午後2問2メモ

データベーススペシャリスト午後2問2解く上でメモ

スーパタイプ・サブタイプが複数に分割する際の見分け方
　スーパタイプに区分が設定されている場合。
　（例）データベーススペシャリスト 平成31年春期試験問題 午後2問2
　　　品目（品目コード、品目名、品目分類コード、計量単位、調達内製区分、貯蔵区分）
　　　　　調達品目（省略）
　　　　　内製品目（省略）
　　　　　貯蔵品目（省略）

　問題文より「調達または内製のいずれかを表す調達内製区分」
　　　　　　「貯蔵対象かどうかを表す貯蔵区分」

　スーパタイプに区分が設定されている場合サブタイプが複数に分割される。
プラス１勝！店舗メタを可視化するアプリを作ってみた

# アプリ
https://metagamevis.herokuapp.com/

![スクリーンショット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188786/c2d1f08c-3ce5-2d1c-d49e-cca7c9644fc9.png)




店舗とアーキタイプと出現回数でフィルタできます。

# 店舗メタとは
カードゲームのイベントに参加するとき、多かれ少なかれ
「他の参加者はどのデッキを使うのか」
ということが気になります。

近所のよく行くお店であれば、「この前〇〇さんが△△デッキを使っていたな、対策カードを入れていこう」といった具合のことをしたりしなかったり。

端的にセコいといってしまうこともできますが、
その日の終わりにうまい飯を食べるためにも最善を尽くしてイベントに臨みたいものです。
とはいえ店舗メタなんていう付け焼き刃のために時間と労力を使うのは本質的な努力とはいえないのも事実です。
「イベントに行く前日に、楽に明日の相手のことを知りたいな」
というのが今回の開発のモチベーションです。


# データ
デッキの情報は晴れる屋のデッキ検索の結果を元に作成しています。
https://www.hareruyamtg.com/ja/deck/

上述の店舗というのは晴れる屋のそれぞれの店舗に対応しています。
集計期間は特に決めておらず、１店舗ごとに２０個ずつデッキの情報を集めています。

恣意的に店舗を選んでますので、日本の縮図、とは言えませんが、
なんとなくの全体像を把握した上で、自分が知りたい店舗のアーキタイプの構成比を確認します。
多重請負じゃない多重地獄を観測した件ので共有したい

# とある日のこと
天使「(……きこえますか…こぴぺたんよ…天使です……今… あなたの…DMに…直接… 投げています… 多重請負です…多重請負について調べなさい…)」

一二三🔗多重請負は悪の記事リンク

僕「( ﾟ∀ﾟ)･∵. ｸﾞﾊｯ!!」

僕「これは酷い…酷い…酷すぎるよ…なんてものを天使は僕に見せるんだ…」

僕「やってやるのだ！(๑╹ω╹๑ )」

天使「やれ（ﾆﾁｬｱ」

# 自称 不健全な業界と健全な業界
※元記事の表現がSIerでしたがここでは元請け企業と解釈してください。

## 不健全な業界
僕「こりゃ、酷いSES企業同士で仕事回しているよ…」

天使「これだと個人単体を会社間で行き来させたりしてチーム戦出来んぉ」

僕「まぁ、単価は低くなるけど待機リスクは低くなるけど…エンジニアとしてはずっと下層だぉ…」

![不健全な業界図.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363845/fa920921-187e-2515-c7d5-b3988a74e24d.png)

## 健全な業界

僕「これだと一見確かに健全な業界に見えるね！」

天使「そうだね！一見ね！」

![健全な業界図.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363845/47964d48-1fa4-c996-f828-8a355bb45c8b.png)

## 一見すると
僕「SIerや発注者がよくわからんSES企業に依頼したりするかな？」

天使「普通に弾かれる！」

僕「発注者もSESなんて使わずにコンサルに依頼するよねー？」

天使「だよー。SIerと直取引するってならそれなりの規模の会社じゃないと無理だし、多分窓口が開かれない企業は別会社経由で入ってこようとするよー。そして『アレ』を使うんだよー。」

![健全化しよう.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363845/10f881ba-89eb-b2b9-c5fa-5fbe4c4a4c40.png)

# 不健全なSES企業の登場
僕「『アレ』って…営業会社だね！」

天使「Exactly」

僕「営業会社を利用するとチームや商流を考えないでいい案件がいっぱいなイメージがあるぉー」

天使「自社の方針で営業出来ないから商流が悪くなるし、実際1つ挟んでるから更に下層に落ちてるんだよ！」

![不健全なSESが広まる.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363845/d41107ad-e446-9cce-0042-3c5efca1eecc.png)

# 商流を上げる努力
僕「イメージ的にこんな感じ？」

天使「んだんだ」

僕「これ4次請けのの下に営業会社って営業会社が5次請けになって実質6次請けになりますやん…」

天使「だよー。だから会社は社員、チームを育成して力を付けてこの中間を排除出来るようにするんだ。そうすると会社としては儲けが出てくるのよ」

※発注額は雑にしています。
![商流を上げると単価が上がる.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363845/36f0ab55-55e7-a2b0-486c-38b5e7991e0f.png)

# 多重は辞めようとって話

僕「多重を辞めようって話になるとまず元請けだけで片付けるのが正解じゃね？」

天使「だよー。そうすると下請けやSES企業は基本的に成り立たないよ。フリーランスエンジニアなんてこの世から消えるんじゃね？」

僕「問題なのは業界構造を複雑化してスラム街みたいな形成しているのと一見きれいに見えるけどやっぱスラムを作ってるやつらじゃね？」

天使「🤫スラム街を形成してこっちに来ないならええから黙っていてね」

僕「(´・ω・｀)」
【Windows10】Python MATLAB engine APIのインストールでハマったところ（管理者権限でも所有者変更でも直らなかった場合）

## 背景
https://jp.mathworks.com/help/matlab/matlab_external/install-the-matlab-engine-for-python.html

matlabのコードをpythonから呼び出せるなんて便利な機能があります。早速使おうと、windows10 PCにインストールしようとしました。

## 環境
PC OS: windows10
Python: 3.9.7
Matlab: R2021B

## エラー
まず、公式ドキュメントにしたがって、

`cd "matlabroot/extern/engines/python"`
`python setup.py install　`

を実行したところ、

`error: could not create 'build': Access is denied`

アクセスができないとのエラーに遭遇。管理者権限でプロンプトを立ち上げても状況は変わらず。↓

https://www.javadrive.jp/command/ini/index12.html

また、プロパティからフォルダ所有者を変更する方法でもうまくいかず。↓
https://www.billionwallet.com/goods/windows10/win10_access_admin.html


## うまくいった方法

Windows Powershellを管理者権限で開き、下記のコードを実行する。

`python setup.py build --build-base=$env:temp install --user`

これで無事インストールできました。管理者権限がなくてもうまくいくはずですが、自分はなぜか管理者権限でPowershellを開かないとできません。

## その他、参考文献

https://www.scivision.dev/matlab-engine-callable-from-python-how-to-install-and-setup/
TypeScript - 変数

[TypeScript - Hello World](https://qiita.com/fumi-410/items/d948dd1a7638dba43173) ができたので、次に変数を使ってみます。

# Hello worldの振り返り

前回のHello Worldは次のようなコードでした。

```hello.ts
console.log("Hello, world!");
```

# 変数

今回は文字列部分をいったん変数で保持し、それを表示することにします。
変数宣言は次のように行います。

```
let 変数名: 型;
```

文字列を格納するためにstring型を格納できる変数を宣言し、そこに値を代入します。

```ts:hello.ts
let greeting: string;
greeting = "Hello, world!"
```

同時に初期化を行うこともできます。

```ts:hello.ts
let greeting: string = "Hello, world!";
```

代入する値から暗黙に決めてよいときは省略できます。

```ts:hello.ts
let greeting = "Hello, world!";
```

無理やり別の型の値を代入しようとすると、（JavaScriptと違い）コンパイル時にエラーになります。安心ですね。

```ts:hello.ts
let greeting: string;
greeting = 10; // error TS2322: Type 'number' is not assignable to type 'string'.
```

あとは、変数の内容を出力するだけです。

```ts:hello.ts
console.log(greeting);
```

まとめます。

```ts:hello.ts
let greeting = "Hello, world!";
console.log(greeting);
```

# 定数

なお今回のように値が決まっていて変更（再代入）がない場合は`let`ではなく`const`で定数とすることができます。
`const`は`let`と違い、一度初期化した値を変更できないので想定外の変更を避けることができます。

```ts:hello.ts
const greeting = "Hello, world!";
```

宣言と値のセットを別に行うことはできません。

```ts:hello.ts
const greeting: string;
greeting = "Hello, world!" // error TS2588: Cannot assign to 'greeting' because it is a constant.
```
別ブック(複数)から指定列の値をコピーペーストする方法


[キーワード検索で指定フォルダ内のファイル名一覧を取得する方法 ExcelVBA](https://qiita.com/akari_n/items/2dc98a8c3705b5f114f7)
の続きになります。

#ユーザーから見た画面の流れ

①データを取得・貼付ボタンを押下
②検索結果 ファイル名を元にデータの取得・貼付開始
![１１１.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433296/6b222914-cf6f-ae29-a6cc-47ddf9ce8456.jpeg)
###結果
各ファイル名とデータが貼付けられます。
B列とD列のデータがある行までをコピーしてくるように指示しています。
![２２２.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433296/6bfc5388-587e-7a99-5001-a7102571a74b.jpeg)
コピー先のテストデータは以下の通りです。
各シート名はすべて、"取り込むシート"として、
C:\test\ディレクトリの下に置いてあります。

![３３３.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433296/dd6f0b53-d522-d79d-cc63-fc60e2b042b5.jpeg)


```vb
Sub データ取込貼付()

    Const Path As String = "C:\test\" '固定ディレクトリパス'
    
    Dim SetFile As String
    Dim wbCopy, wbPaste As Workbook
    Dim row As Integer
    Dim cnt As Long 'カウント'
    Dim FileName As String
    Dim NextRow As Long
    
    row = 7
    cnt = 6
    
    Do Until ThisWorkbook.Worksheets("マクロ定義シート").Cells(row, 2).Value = ""
    
        cnt = cnt + 1
        FileName = ThisWorkbook.Worksheets("マクロ定義シート").Cells(cnt, 2)
        SetFile = Path + FileName
    
        Set wbPaste = ThisWorkbook
        Set wbPaste = ActiveWorkbook
        
         Application.DisplayAlerts = False

        Workbooks.Open FileName:=SetFile, ReadOnly:=True, UpdateLinks:=0 '読み取り専用で開く
        Set wbCopy = Workbooks.Open(SetFile)
        
            wbCopy.Worksheets("取り込むシート").Range("B2", Range("B1").End(xlDown)).Copy '★選択1列目コピー
            
            NextRow = ThisWorkbook.Worksheets("貼付先シート").UsedRange.SpecialCells(xlCellTypeLastCell).row + 1 '☆最終行から追加する
            
            wbPaste.Worksheets("貼付先シート").Range("A" & NextRow + 1) = FileName    'ファイル名記入
            wbPaste.Worksheets("貼付先シート").Range("B" & NextRow + 1).PasteSpecial xlPasteFormulasAndNumberFormats '★選択1列目貼付
    
            wbCopy.Worksheets("取り込むシート").Range("D2", Range("D1").End(xlDown)).Copy '★選択2列目コピー
            wbPaste.Worksheets("貼付先シート").Range("D" & NextRow + 1).PasteSpecial xlPasteFormulasAndNumberFormats '★選択2列目貼付
            
            Application.CutCopyMode = False  'コピー切り取りを解除
            wbCopy.Close False  'マスターデータ取り込み先のファイルを閉じる
    
        Application.DisplayAlerts = True
        
        row = row + 1
        
    Loop
    
End Sub
```
Firebase Cloud Messaging証明書更新

しばらく忙しくて自作アプリを放置していたらAPSの有効期限が残り３日を切っていましたｗ
APS証明書の更新がてら更新手順とFirebaseの証明書更新について備忘録を残そうと思います。

# 1. CSR作成
証明書といえばCSRの作成から始まりますね。

1. キーチェーンアクセス起動
1. 証明書アシスタント
1. 認証局に証明書を要求
1. 以下情報登録
    * ユーザのメールアドレス
    * 通称
    * ディスクに保存
    * 鍵ペア情報を保存
1. 続ける
1. 保存場所を決めて保存
1. 鍵ペア情報はそのまま
1. 続ける 

# 2. ADPで証明書を作成
1. identifiersから対象のアプリのものを選択
1. Push Notifications -> Edit![スクリーンショット 2021-10-03 16.50.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457333/82599f6f-01f7-808d-c32e-d4693c8aacd4.png)
1. Production SSL Certificate -> Create Certificate
    1. 開発環境も用意している場合は同様にdevelopmentも設定
1. 先程作ったCSRを指定しContinue
1. Download
1. Downloadした証明書をダブルクリックしキーチェーンに登録
1. 登録したキーチェーンの秘密鍵を右クリックで書き出す

# 3. FirebaseのCloud Messagingの更新
Firebaseの歯車アイコン -> プロジェクトの設定 -> Cloud Messagingタブを開く
![スクリーンショット 2021-10-03 16.33.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457333/dc01b6b2-9d35-985c-dcbf-abcf9b8b36f4.png)
見事に真っ赤...
更新 -> 先程作ったp12ファイルを登録＆書き出すときのパスワード入力
すると
![スクリーンショット 2021-10-03 17.21.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457333/079fb182-0395-db53-9fe3-b2fca7104576.png)

無事更新されました
【React】縦スクロールをすると横にスライドするページを実装する

<!-- =========================================================== -->
# 概要
<!-- =========================================================== -->
**縦スクロールする（マウスホイールする）と、ページが横に切り替わるコンポーネント**を実装します。

![output(video-cutter-js.com) (6).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/617dc325-426a-2a8e-9873-04dcf4409688.gif)

:::note info
スタイリングには、<strong>emotion/css</strong>（CSS in JS）を使用しています。
:::

https://emotion.sh/docs/@emotion/css

https://qiita.com/nemutas/items/dac73aa645f27cde92cd

<!-- =========================================================== -->
# 実装
<!-- =========================================================== -->
実装のイメージ図です。主要なCSSプロパティを記述しています。

![スクリーンショット 2021-10-03 163643.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/381e321d-2324-6c8c-bfd2-88b5039d46c4.png)

```.tsx
import React, { useEffect, useRef, VFC } from 'react';
import { css } from '@emotion/css';

export const ParallaxHorizontalScrollPage: VFC = () => {
	const screenRef = useRef<HTMLDivElement>(null)

	useEffect(() => {
		screenRef.current!.onwheel = ev => {
			ev.preventDefault()

			let delta = (ev.deltaY / Math.abs(ev.deltaY)) * window.innerWidth
			if (delta > 0) {
				delta += screenRef.current!.scrollLeft
				delta = Math.floor(delta / window.innerWidth) * window.innerWidth
			} else {
				delta += screenRef.current!.scrollLeft
				delta = Math.ceil(delta / window.innerWidth) * window.innerWidth
			}
			screenRef.current!.scrollLeft = delta
		}
	}, [])

	return (
		<div ref={screenRef} className={styles.screen}>
			<div className={styles.container}>
				<div className={styles.page('#0085d1')}>
					<div className={styles.text}>Page 1</div>
				</div>
				<div className={styles.page('#db0063')}>
					<div className={styles.text}>Page 2</div>
				</div>
				<div className={styles.page('#ffcd43')}>
					<div className={styles.text}>Page 3</div>
				</div>
			</div>
		</div>
	)
}

const styles = {
	screen: css`
		position: relative;
		width: 100vw;
		height: 100vh;
		overflow: auto;
		scroll-behavior: smooth;
	`,
	container: css`
		width: 300vw;
		height: 100%;
		display: flex;
	`,
	page: (bgColor: string) => css`
		position: relative;
		width: 100vw;
		height: 100%;
		display: flex;
		justify-content: center;
		align-items: center;
		background-color: ${bgColor};
	`,
	text: css`
		font-size: 3rem;
		color: white;
	`
}
```
useEffectの中で、screen（CSS名のdiv要素）に対してスクロール量を調整しています。

deltaは横のスクロール量で、1回の縦スクロールで画面幅（innerWidth）だけ横スクロールします。
縦のスクロール量を絶対値で割ることで、+/-を取得しています。

```.tsx
let delta = (ev.deltaY / Math.abs(ev.deltaY)) * window.innerWidth
```

以下のコードでは、ページを途中まで手動で横スクロールしているときに、縦スクロールをしたときの横のスクロール量を決めています。
これによって、デモ（記事上部のGIF）のような動作になります。

```.tsx
if (delta > 0) {
	delta += screenRef.current!.scrollLeft
	delta = Math.floor(delta / window.innerWidth) * window.innerWidth
} else {
	delta += screenRef.current!.scrollLeft
	delta = Math.ceil(delta / window.innerWidth) * window.innerWidth
}
```
AtCoderログ：0132 - ABC 221 に参加しました

この記事は 2021年10月02日(土)21:00-22:40 に開催された [AtCoder Beginner Contest 221 (ABC 221)](https://atcoder.jp/contests/abc221) に参加した記録です。

https://atcoder.jp/contests/abc221

# 結果
- 得点：600 (=100+200+300)
- 時間：74:10 (= 69:10 + 05:00 × 1)
- 順位：4041 / 8297
- パフォーマンス：617
- レーティング：323 → 355 (+32)
- 段級位：9級

![2021-10-02_abc221.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1589302/f435e75e-f938-0a2a-22a4-9f983cf3286a.png)

# 詳細
|問題|得点|時間|提出コード|復習|
|:--:|:--:|:--:|:--:|:--:|
|[ABC 221 A](https://atcoder.jp/contests/abc221/tasks/abc221_a)|100|05:38(1)|[○](https://atcoder.jp/contests/abc221/submissions/26280005)|[AtCoderログ：013*]()|
|[ABC 221 B](https://atcoder.jp/contests/abc221/tasks/abc221_b)|200|12:45|[○](https://atcoder.jp/contests/abc221/submissions/26287243)|[AtCoderログ：012*]()|
|[ABC 221 C](https://atcoder.jp/contests/abc221/tasks/abc221_c)|300|69:10|[○](https://atcoder.jp/contests/abc221/submissions/26309174)|[AtCoderログ：012*]()|
|[ABC 221 D](https://atcoder.jp/contests/abc221/tasks/abc221_d)|400|---|---|---|
|[ABC 221 E](https://atcoder.jp/contests/abc221/tasks/abc221_e)|500|---|---|---|
|[ABC 221 F](https://atcoder.jp/contests/abc221/tasks/abc221_f)|600|---|---|---|
|[ABC 221 G](https://atcoder.jp/contests/abc221/tasks/abc221_g)|600|---|---|---|
|[ABC 221 H](https://atcoder.jp/contests/abc221/tasks/abc221_h)|600|---|---|---|

# 感想
- C まで完答しました。
- A は回答を急ぎすぎて WA になってしまいました。
- C の処理内容はすぐにイメージできたのですが、なかなかコーディングできず、1時間近くを使ってしまいました。今思うと、何であんなにはまっていたんだろう。
- レーティングは微増だったので、よしとしましょう。
 
# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0131 - ABC 108 B](https://qiita.com/RoadLynton/items/d87f781ac8ed49d6712b)
GitHubActionで簡単CI

<h1>CIをRspecで自動で行いたい</h1>
everyday-railsを軽く流し読みしまして、実際に自分のアプリでテストを書いてみようと思いました。

今回行うテストはモデルだけなので、コントローラーやフィーチャースペック等の複雑なテストもおいおい実装していきたいと思います。

__rspecに関しては今回は触れません__
everyday-railsを読んでください、笑

<h1>実装</h1>
一応モデルのスペックも載せておきます。
本当に簡単なテストしか書いていませんが、気にしないでください！

（includeの引数が日本語なのはエラー文を日本語で出力するようにしているため、includeが日本語じゃないとエラーになるからです。）

```&:user_spec.rb
require 'rails_helper'

#bin/rspec spec/models/user_spec.rb
RSpec.describe User, type: :model do
  #ニックネーム,メールアドレス,パスワードがあれば有効
  it "is valid with a nickname, email, and password" do
    user = FactoryBot.build(:user)
    expect(user).to be_valid
  end

  #ニックネームがないと無効
  it "is invalid without user nickname" do
    user = FactoryBot.build(:user, nickname: nil)
    user.valid?
    expect(user.errors[:nickname]).to include("を入力してください")
  end

  #メールアドレスがないと無効
  it "is invalid without user email" do
    user = FactoryBot.build(:user, email: nil)
    user.valid?
    expect(user.errors[:email]).to include("を入力してください")
  end

  #重複したメールアドレスだと無効
  it "is invalid with a duplicate email address" do
    FactoryBot.create(:user, email: "new@example.com")
    user = FactoryBot.build(:user, email: "new@example.com")
    user.valid?
    expect(user.errors[:email]).to include("はすでに存在します")
  end

  #パスワードがないと無効
  it "is invalid without user password" do
    user = FactoryBot.build(:user, password: nil)
    user.valid?
    expect(user.errors[:password]).to include("を入力してください")
  end

  #プロフィールが300文字以上だと無効
  it "is invalid within 300 characters" do
    user = FactoryBot.build(:user, profile: "a" * 301)
    expect(user.valid?).to eq false
  end

  #300文字以内であれば有効
  it "is valid within 300 characters" do
    user = FactoryBot.build(:user, profile: "a" * 299)
    expect(user.valid?).to eq true
  end
end
```

__テストがパスするかの確認を忘れずに！__


<h1>Workflowの設定</h1>

次はgithub actionを使うためのファイルを作成します。

githubディレクトリの下にworkflowsを作ります。

```
mkdir github/workflows
```

workflowsの下に今回使うファイルをyml形式で作ります。(ファイル名は任意です)

```
touch github/workflows/test.yml
```

ここに記述します。

```&:test.yml
name: Test

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  run_spec:
    name: Run Test
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Set up Ruby 2.6.5
      uses: ruby/setup-ruby@v1
      with:
        ruby-version: 2.6.5
    - name: Test with Rspec
      run: |
        gem install bundler
        bundle config set --local path vendor/bundle  --jobs 4 --retry 3
        bundle install --jobs 4 --retry 3
        bundle exec rake

```

ymlファイルはインデントで判断するみたいなので気をつけてください。

__on: push またはpull_request__みたいに書くことで
今回だと、
masterブランチにpush , pul__requestされた場合に動くようになります
githubのActionから結果を見ることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1541345/42b45e42-a01d-2cd9-597a-d39fb4fc2a44.png)


無事テストがパスししてくれました！
何か問題があった場合は、問題のstepのところで✖︎マークが出ているのでわかりやすいです

githubaciton　以外にもjenkinsやcirfleciなどなど、、
ci/cdツールは山ほどあるので実際に使ってみてください！
AtCoderログ：0131 - ABC 108 B

# 問題

https://atcoder.jp/contests/abc108/tasks/abc108_b

## 収録されている問題セット
- [[BfB-E](https://kenkoooo.com/atcoder/#/training/Boot%20camp%20for%20Beginners/1)] AtCoder Problems - Boot camp for Beginners (Easy 100) #030

# 回答
## 回答1 (AC)
点 $(x_1,y_1)$ から点 $(x_2,y_2)$ に移動する際の増分を $D_X=x_2-x_1$, $D_y=y_2-y_1$ とおくと、点 $(x_3,y_3)$, 点 $(x_4,y_4)$ の位置関係は下図のようになるので、$x_3=x_2-D_y$, $y_3=y_2+D_x$, $x_4=x_3-D_x$, $y_4=y_3-D_y$ となります。コードは以下のようになりました。

![abc108b.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1589302/7648d6af-acd0-4354-e6a3-04501ce62623.jpeg)

```C++:abc108b-1.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int x1, y1, x2, y2;
  cin >> x1 >> y1 >> x2 >> y2;

  int dx = x2-x1, dy = y2-y1;
  int x3 = x2-dy, y3 = y2+dx;
  int x4 = x3-dx, y4 = y3-dy;

  cout << x3 << " " << y3 << " " << x4 << " " << y4 << endl;
} 
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc108/tasks/abc108_b/editorial) → [ユーザ解説](https://blog.hamayanhamayan.com/entry/2018/09/02/223200)
回答1と同じ方針でした。回転行列という表現を使っていますが、要は上図のような関係のことです。

## [AtCoder の解説](https://atcoder.jp/contests/abc108/tasks/abc108_b/editorial) → [ユーザ解説](https://img.atcoder.jp/arc102/editorial.pdf)
回答1と同じ方針でした。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0130 - ABC 114 B](https://qiita.com/RoadLynton/items/61bbebd04a89ce258a83)
【Python】List append()とextend()の違い

# append()とextend()の違いをちょっと比較します。
## append()
```python
student_id = [1, 2, 3]
student_id.append([4, 5])
print(student_id) #[1, 2, 3, [4, 5]]
```
listをappend()と実行したら、listのまま格納されます。

## extend()
```python
student_id = [1, 2, 3]
student_id.extend([4, 5])
print(student_id) #[1, 2, 3, 4, 5]
```
listをextend()と実行したら、listのelementを取り出し、格納されます。

以上、簡単なメモでした！
HTMLとJavaScriptで表を作る

最初にスタイルを整えていきます

```
body {
  font-size: 22px;
  background: #808080;
}

table {
  border-collapse: collapse;
  border-collapse: separate;
  border-spacing: 2px 2px;
}

th {
  background: #FFA500;
  padding: 3px 12px;
}

td {
  text-align: right;
  background: white;
}
```


次にjavascriptの部分

まず一番上の列を作る

```
document.write('<tr>');

document.write('<th></th>');
for(var i=1; i <= 9; i++) {
  document.write('<th>', i ,'</th>');
}

document.write('</tr>');
```

次に二列目以降を作る。

```
for(var y=1; y <= 9; y++) {
  document.write('<tr>');

  document.write('<th>' + y + '</th>');
  //ここが縦の列になる
  for(var x =1; x <= 9; x++) {
    // データの出力
    document.write('<td>'+ x * y +'</td>');
　　//ここが横の列になる
  }

  document.write('</tr>');
}
```
縦の1列に対して横の列を9まで作るのでこのような形になる。

それを9まで繰り返す。

縦の1を作ったら横を9まで作る

縦の2を作ったら横を9まで作る

縦の3を作ったら横を9まで作る

これを縦の9まで繰り返す。

という形になる。


![スクリーンショット 2021-10-03 162742.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1612146/cd060553-3b71-9233-7d1e-c594d25a0cd7.png)
完成したもの
Twitterデベロッパーサイトの登録方法（2021年10月）

## 概要

Twitterデベロッパーサイトの登録方法が昔とかなり変わっていたので、登録方法をメモしておきます  
ざっくり概要を知りたい方や、登録が面倒かなと思っている方が、意外と簡単だと思っていただけたら嬉しいです

[TwitterデベロッパーサイトのURL](https://developer.twitter.com/en/apps/)

## 手順

1. ユースケースの選択
  ![スクリーンショット 2021-10-03 15.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126290/ba8fc2e3-fcf4-e3ab-1134-bf6cd4763846.png)

2. 基本情報を記載
  ![スクリーンショット 2021-10-03 15.57.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126290/610fbc8a-186e-7600-f2ed-58e997b78209.png)

3. 重要項目の記載
  ![スクリーンショット 2021-10-03 16.07.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126290/aef16fa3-5253-273a-efaf-54940d729f36.png)

4. 記載内容の確認
  ![スクリーンショット 2021-10-03 16.07.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126290/4b0ba47c-b967-3c3c-37f2-144af380a7fb.png)

5. 利用規約の確認
  ![スクリーンショット 2021-10-03 16.08.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126290/a3050649-51dd-a336-59a9-085d31f5ea02.png)

6. メールの確認
フィッシャー線形判別について

#はじめに
統計の資格試験のために判別分析について勉強したので忘れないように自分メモがてら残しておきます.

#線形判別とは
**線形判別**(Discriminant analysis)は入力された特徴量に基づいて対応するクラスラベルを出力するための方法である．代表的なものとしてフィッシャー線形判別分析や正準相関分析(CCA)　やサポートベクターマシン(SVM)等が挙げられる.

#フィッシャー線形判別
フィッシャー線形判別は主成分分析と同様に、入力された特徴量を低次元空間に射影するための手法である.
つまり**与えられた特徴量を最もよく判別するために1次元に射影して判別しよう**という雰囲気である．
ここまで聞くと主成分分析と同じように聞こえるが主成分分析はサンプルが属する群の情報を使用しないのに対して判別分析はサンプルが所属する群の情報を使用する点で異なる.

####問題設定
最も基本的な場面として２値のラベル判別問題を考える.
観測するデータは群$G_{j},j=1,2，i=1,..,n$に属する
n個のp次元サンプル　

```math
\mathbf{x}_{i}^{(j)}=
\begin{pmatrix}
x_{1}^{(j)}  \\
\vdots \\
x_{p}^{(j)}
\end{pmatrix}
```
を1次元空間に射影する.

####次元縮約の方法
ベクトル$\mathbf{w}\in\mathbb{R}^p$による射影を考える.
最終的には**群$G_{1}$と$G_{2}$が最もよく分離されるような射影ベクトル$\mathbf{w}$を求めること**が目標である.
射影後のサンプルを

```math
y_{i}^{(j)}=\mathbf{w}^T\mathbf{x}_i^{(j)}    \qquad  j=1,2, i=1,..,n_{j}

```
とする．
射影後のサンプル$y_{i}^{(j)}$は1次元であり，この射影後のサンプルから群$G_{1}$と$G_{2}$の標本平均を求める．
群$G_{1}$と$G_{2}$の標本平均は群1,2に属するサンプルの平均ベクトルを$\bar{\mathbf{x}}^{(j)}=\frac{1}{n_{j}}\sum_{i=1}^{n_j}\mathbf{x}_{i}^{(j)}$として

```math
\bar{y}^{(j)}=\frac{1}{n_{j}}\sum_{i=1}^{n_j}=\mathbf{w}^T\bar{\mathbf x}^{(j)}, \qquad, j=1,2
```
2つの群の平均はなるべく離れているように$\mathbf{w}$を定める.しかし**平均が離れているだけではうまく2郡に分割できない**
例えば$G_{1}$の点が$G_{2}$の点が密集している位置に混ざっていても，平均的には2つのクラスは離れているとみなされてしまう．
つまり2群の分散はなるべく小さい方が適切な境界線を引くには適切である.つまり以下の基準を最大化する$\mathbf{w}$を求める．

```math
    \lambda(\mathbf{w})=\frac{クラス間の平均の最大化}{クラス間分散の最小化}
```
ここで分子は

```math
    (\bar{y}^{(1)}-\bar{y}^{(2)})=\mathbf{w}^T(\mathbf{x}^{(1)}-\mathbf{x}^{(2)})
```
で表される.分子も分母と同様分散の形で　表現するために以下のように変形する.

```math
\mathbf{w}^T(\mathbf{x}^{(1)}-\mathbf{x}^{(2)})(\mathbf{x}^{(1)}-\mathbf{x}^{(2)})^{T}\mathbf{w}
```

上記が$\lambda(\mathbf{w})$の分子となる．
また，群$G_{j}$($j=1,2$)内の分散は

```math
\frac{1}{n_{j}}\sum_{i=1}^{n_{j}}(y_{i}^{(j)}-\bar{y}_{i}^{(j)})=\mathbf{w}^{T}S_{j}\mathbf{w}
```
で定義される.
ただし$S_{j}$は群$G_{ｊ}$に含まれるサンプルの標本共分散行列である．$\lambda(\mathbf{w})$の分母はプールした分散

```math
S=\frac{1}{n_{1}-n_{2}-2}((n_{1}-1)S_{1}-(n_{2}-1)S_{2})
```
を用いて$\mathbf{w}^{t}S\mathbf{w}$と定義される　．
つまり

```math
\lambda(\mathbf{w})＝\frac{\mathbf{w}^T(\mathbf{x}^{(1)}-\mathbf{x}^{(2)})(\mathbf{x}^{(1)}-\mathbf{x}^{(2)})^{T}\mathbf{w}}{\mathbf{w}^{t}S\mathbf{w}}
```
を最大にする$\mathbf{w}$を求めれば良い.($\mathbf{w}^T-\mathbf{w}=\mathbf{1}$の制約のもとで)
ラグランジュの未定乗数法を用いて最適な$\mathbf{w}$を求めると$\hat{\mathbf{w}}=S^{-1}(\bar{\mathbf{x}}^{(1)}-\bar{\mathbf{x}}^{(2)})$となる．


ここで新しいサンプル$\mathbf{x}$は$y=\hat{\mathbf{w}}\mathbf{x}$のように射影される．
このサンプルがどちらの群に属するかを判別するには以下の関数の符号によって判別する.

```math
f(\mathbf{x})=\hat{\mathbf{w}}\mathbf{x}-\frac{1}{2}(\bar{\mathbf{x}}^{(1)}-\bar{\mathbf{x}}^{(2)})^{T}S^{-1}(\bar{\mathbf{x}}^{(1)}+\bar{\mathbf{x}}^{(2)})
```

この関数の符号が正ならば新しいサンプルは群１，負ならば群2に分類すれば良い.
関数$f(\mathbf{x})$を**フィッシャー線形判別関数**という.