OmniAICreator/Qiita-1.07M huggingface dataset:
Flask-RESTX (Flask-RESTPlus) で, サーバ起動せずに swagger.json を取得する

Flask-RESTX でサーバ起動せずにAPIドキュメントである swagger.json を取得したい場面がありました.

はじめに, Flaskアプリケーションのサンプルコードを示します.

```python
from flask import Flask
from flask_restx import Api, Resource, fields

def create_app():
    app = Flask(__name__)
    api = Api(app)

    @api.route("/sample")
    class SampleResource(Resource):

        @api.marshal_with(api.model("sample model", {
            "name": fields.String,
            "age": fields.Integer,
        }))
        def get(self):
            raise NotImplementedError()

    return app
```

`flask run` で起動すると, http://127.0.0.1:5000/swagger.json へのアクセスで, swagger.json を取得できます.

しかし, この方法では swagger.json を得るために, デバッグサーバを起動する手間がかかってしまいます. CIなどを使って, 自動で swagger.json を取得して共有するなどしたいケースでやや難があります.

そこで次のようなスクリプトを用意して実行すると, Flaskサーバを立ち上げることなく, swagger.json を取り出すことができます.

```python
import json
import sys
from app import create_app


app = create_app()
json.dump(
    app.test_client().get("/swagger.json").get_json(),
    sys.stdout,
)
```

Flaskに同梱されているテスト用クライアントを使っています.

このスクリプトでは標準出力にだしてますが, ファイルにリダイレクトするなりで, JSONファイルを取得できます.
ネットワーク構築（EtherChannel編）

##目的

最近机上の勉強ばかりで、手を動かせていないので
コマンドを忘れている恐れがあるためネットワーク構築してみます

##使用ツール
GNS3
IOS: c2600-adventerprisek9-mz.124-17
手元にあるCiscoルーターの2651から抜いたIOSのため古い・・・

##ネットワーク構成図
ちょうどCCNAの勉強をしていて、実際に手を動かしてみたくなったので
今日は、試験範囲でもある**EtherChannel**の検証をしてみようと思います。

そして作ってみた構成図は以下
![EtherChannel.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686507/1b7ce86d-8879-3223-9bcc-1aa98d603e3c.jpeg)



##構築してみる

**設定したい内容は下記**
１．特権モードから移行
２．複数設定するのは手間なのでレンジで一気に設定
３．トランクの設定
４．手動でEtherChannel設定

※まずはコマンド省略無しで**ESW1**の設定

```
ESW1#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
ESW1(config)#interface range fastEthernet 1/1 - 2
ESW1(config-if-range)#switchport mode trunk
ESW1(config-if-range)#channel-group 1 mode on
ESW1(config-if-range)#end
ESW1#
```

これで**ESW1**の設定投入が終わったので状態確認していきます。

```
ESW1#show etherchannel summary
Flags:  D - down        P - in port-channel
        I - stand-alone s - suspended
        R - Layer3      S - Layer2
        U - in use
Group Port-channel  Ports
-----+------------+-----------------------------------------------------------
1     Po1(SU)     Fa1/1(P)   Fa1/2(P)
```
ここで確認したいのはfa1/1と1/2がPortchannelに参加できているかどうかです。

見てみると　Fa1/1(P)   Fa1/2(P) となっていて(P)は参加できているステータスの表示なので
設定できている確認ができました。

次は**ESW2**の設定です。

```
ESW2#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
ESW2(config)#int ran f1/1 - 2
ESW2(config-if-range)#sw mo tr
ESW2(config-if-range)#
*Mar  1 00:45:55.613: %DTP-5-TRUNKPORTON: Port Fa1/1-2 has become dot1q trunk
ESW2(config-if-range)#cha 1 mo on
Creating a port-channel interface Port-channel1
ESW2(config-if-range)#
ESW2(config-if-range)#end
ESW2#
```

**ESW1**同様に状態を確認してみます。

```
ESW2#sho eth su
Flags:  D - down        P - in port-channel
        I - stand-alone s - suspended
        R - Layer3      S - Layer2
        U - in use
Group Port-channel  Ports
-----+------------+-----------------------------------------------------------
1     Po1(SU)     Fa1/1(P)   Fa1/2(P)
```

見るところは同じですね。
(P)であることを確認できたので設定完了となります。

##実験
検証環境ならではの実験をしたいと思います。

内容はというと、片っぽを**shutdown**しちゃいます。
（恐ろしすぎて現場では絶対できない・・・）

```
ESW1#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
ESW1(config)#int f1/1
ESW1(config-if)#shu
ESW1(config-if)#
```

この状態で状況確認してみます。

```
ESW1#sho eth su
Flags:  D - down        P - in port-channel
        I - stand-alone s - suspended
        R - Layer3      S - Layer2
        U - in use
Group Port-channel  Ports
-----+------------+-----------------------------------------------------------
1     Po1(SU)     Fa1/1(D)   Fa1/2(P)
```
f1/1をshutdownしたので(D)になりました。
Flags:　を見てわかる通りdownの意味ですね。

##まとめ
Qiita初投稿の内容はEtherChannelになりました。
久しぶりに構築してみると、やはり楽しいですね。
今回は小規模構築となりましたが、今後ルーティングだったりしていくと
規模を大きくできるのかな、と思います。
今はCCNAを取得するために学習中なので、基本的に範囲に被る技術で構築をしつつ
知識をつけていきたいと思います。
インプットしたものをアウトプットしていけたらと思います。


以上です。
Dart 2.9 で新しく追加された exhaustive_cases Lint が便利

Dart 2.9 で追加された、exhaustive_cases という Lint が便利でした。特別な制約を満たした Classを、 enum のように switch 文での網羅的な検査を可能にします。

https://dart-lang.github.io/linter/lints/exhaustive_cases.html

# Dart の enum

Dart の enum は特殊な Class です。

enum の特徴として、switch 文で使用すれば、すべての enum の値を列挙しないと警告されますので、列挙漏れの可能性を無くせます。

```dart
enum Color { red, green, blue }

var aColor = Color.blue;

switch (aColor) {
  case Color.red:
    print('Red as roses!');
    break;
  case Color.green:
    print('Green as grass!');
    break;
  default: // Without this, you see a WARNING.
    print(aColor); // 'Color.blue'
}
```

しかし、enum は（おそらくは Dart 1 時代の哲学としてベストな手法を決めるまでの対応として意図的に）表現力が低く、他言語で機能が豊富な enum を経験した開発者からの不満も多く聞こえてきます。

例えば toString()では、

```dart
print(Color.blue.toString()); // prints "Color.blue".
```

となりますので、value 部分の "blue" だけがほしいならば、

```dart
print(Color.blue.split('.').last); // prints "blue".
```

などとアドホックなコードを書くこともあります。

Flutter では、`describeEnum`という、上記の処理に相当する関数さえ用意されています。

https://api.flutter.dev/flutter/foundation/describeEnum.html

Dart 2.9 で追加された lint である、[exhaustive_cases](https://dart-lang.github.io/linter/lints/exhaustive_cases.html) を有効にすれば、記載の通りの制約付き class を用いて、switch 文で enum と同じように網羅的な検査がされ、かつ class の表現力を得られます。

# Enum のように使える Class

この lint を適用すると、enum のように switch 文で網羅的な検査がされます。網羅的な検査に引っかかると、静的解析器が警告します。

ただし、そのように使える Class にするには、以下の制約を満たす必要があります。

- only private non-factory constructors
- two or more static const fields whose type is the enclosing class and
- no subclasses of the class in the defining library

制約を満たせば、Class の表現力を使えますので、たとえば、実行時に`describeEnum`で文字列処理をして enum value を取り出さなくとも、単に instance 変数に String 表現を保存しておけます。

```dart
class EnumLike {
  final String name;
  const EnumLike._(this.name);

  static const red = EnumLike._('red');
  static const green = EnumLike._('green');
  static const blue = EnumLike._('blue');
}

void bad(EnumLike e) {
  switch (e) {
    // LINT
    case EnumLike.red:
      // red case
      print(e.name); // red;
      break;
    case EnumLike.green:
      // green case
      print(e.name); // green;
      break;
  }
}
```

Instance変数をそのまま文字列化したい場合には、enum を採用して `describeEnum` するのが素直です。上記の方法でも、static 変数とコンストラクターパラメーターで記述が重複しているのが少し気になりますが、2 つの距離が近いので許容範囲内の冗長さでしょう。

(ちなみに、exhaustive_cases lint のページに に記載されているサンプルコードはコンストラクターの文法違反でコンパイルエラーです)

Class ですので、もちろん final instance 変数や method を追加していくことができます。enum に extension をつける手法よりもイディオマティックになり、class の表現力を得られます。

また、`describeEnum`と比較して、処理負荷が下がります。気にする必要もない水準ですが。

# まとめ

導入しても不都合なことはないので、無条件に導入しておきたい Lint です。

Dart 言語にパターンマッチングの仕様策定が進行中ですし、現状でも現行の仕様のもとenumのインターフェース実装で疑似 Union Type を作ってswitch文で使えば、やや冗長ながらもさらに表現力が増します。実装が単純で明白なので、私はその手法を好みます。[Dart の基本的な言語機能のみを使用してパターンマッチングもどきを実装し、静的に網羅的な検査をする手法 - Qiita](https://qiita.com/ntaoo/items/541bcd33e4c4e36eede4)

それも不満ならば、package:freezed などのパッケージの採用を検討すればよいのではないでしょうか。
Could not find a declaration file for module 'vee-validate/dist/locale/ja.json'. で怒られる。

## 結論

```ts:types/vee-validate.d.ts
declare module "vee-validate/dist/locale/*";

```

## 問題提起

VeeValidateの日本語設定を行っているファイルでこんなエラーが出ました。

```:English
Could not find a declaration file for module 'vee-validate/dist/locale/ja.json'. 
```


```:Japanese
モジュール 'vee-validate/dist/locale/ja.json' が見つかりません。
```

### VeeValidateはTypeScriptで書かれているハズ…

最初はTS非対応のプラグインでよくある`@types/{pluginName}`を探しました。
しかし、有りません。

それもそのハズ、Veevalidateは既にTypeScriptで書かれています。
https://github.com/logaretm/vee-validate

また、エラーが表示されるのはlocal言語指定しているjsonファイルの呼び出し部分のみです。


### nodo_modules以下を見てみる

```
$ cat node_modules/vee-validate/dist/locale/ja.json
```

結果はGitHubのこのページと同様のコードが表示されました。
https://github.com/logaretm/vee-validate/blob/master/locale/ja.json

## 解決

`"vee-validate/dist/locale/*"`のパスの型をグローバルに宣言してあげます。

```ts:types/vee-validate.d.ts
declare module "vee-validate/dist/locale/*";

```

### おわりに
正直なぜ宣言ファイルを見つけられなかったのかも、
Pathに対するグルーバルな型指定でエラー消えるのかも理解できていません。

もし理解された方や他のもっといい方法があるという方がいらっしゃいましたら
コメントにてご指摘頂けると幸いです。

## 参考
GitHubの問題解決issue
https://github.com/logaretm/vee-validate/issues/1477

Veevalidateの型宣言ファイル
https://github.com/logaretm/vee-validate/blob/master/src/types.ts
Address already in useのエラーを解決する

#事象
rails sでサーバを起動しようとすると、エラーが発生して、サーバーが起動できない。
エラー： 「port3000は既に使用されている」

```
`initialize': Address already in use - bind(2) for "127.0.0.1" port 3000 (Errno::EADDRINUSE)
```

#原因
使用したいport3000が過去の古いプロセスにより使用されており、新たなプロセスによるサーバー起動を邪魔している

#対処法 ： 利用ポートのバッティングを解消する

1. エラーが発生しているポート番号が使用されているプロセス(PID)を確認

```
mao-no-MacBook-Air:hello_world_sample mao$ lsof -i:3000
COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ruby    30406  mao   12u  IPv4 0x982d8086b787a0bb      0t0  TCP localhost:hbci (LISTEN)
ruby    30406  mao   13u  IPv6 0x982d8086b93685bb      0t0  TCP localhost:hbci (LISTEN)
```
※ 「lsof」でオープンしているファイルを一覧表示　オプション「-i:ポート番号」を指定

2.起動済みプロセスを削除

```
mao-no-MacBook-Air:hello_world_sample mao$ kill 30406
```

3.サーバを再起動してエラーが出ないことを確認

```
mao-no-MacBook-Air:hello_world_sample mao$ rails s
/Users/mao/.rbenv/versions/2.7.1/lib/ruby/2.7.0/x86_64-darwin17/stringio.bundle: warning: already initialized constant StringIO::VERSION
=> Booting Puma
=> Rails 6.0.3.2 application starting in development 
=> Run `rails server --help` for more startup options
Puma starting in single mode...
* Version 4.3.5 (ruby 2.7.1-p83), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:3000
* Listening on tcp://[::1]:3000
Use Ctrl-C to stop
```
.zsh_history を fish_history に簡単に移行するツール作った

# 使い方

このコマンドを実行するだけ

```
curl -L https://git.io/zshhist2fishhist | ruby
```

もし .zsh_history が見つからない場合は指定してください

```
curl -L https://git.io/zshhist2fishhist | ruby - <your .zsh_history>
```

念の為 fish_history をバックアップしておくことをおすすめします

# 概要

そろそろ fish shell でも使ってみようかなと思ったんですが、宝の山であるコマンドラインヒストリを引き継ぎたい。いろいろググってみるとサンプルコードはいろいろ出てくるが、非ASCII文字に対応してなかったり、気軽に実行できない。

どうせヒストリファイルの移行なんて最初の一回しかやらないから、そのために何かインストールしたり、手作業でゴニョゴニョやるのも面倒なので、コマンドライン一発で移行できるやつを作ってみた

# やってくれること

.zsh_history を読み込んで、.local/share/fish/fish_history に追加してくれます。

.zsh_history は非ASCII文字を変な形にエンコードするので、それを元に戻します。
参考:
http://kawabata.github.io/blog/2013-03-17-zsh-history.html

`&&` を `; and ` に `||` を `; or ` に変換してくれます

# 他に

何かあれば教えてクレメンス
【Power BI】同じ折れ線グラフ上で前年度比較をする

# 集計じゃなく、前年度比較・前月比較を出したいんだ
折れ線グラフで前年比較したいときってありますよね。
去年の傾向とどう違うのかしら？ていうのを、重ねて表示したい。
だってせっかくPowerBI使っているんだもの。
グラフを二つ別々に出すなんてスマートじゃないですわ。

でも、調べてみても、なかなか出てこない。
メジャーを使って集計するやり方はわかったよ。
PreviousYearとか、DateADDとか、
僕がやりたいのは集計しないやり方なんだ。
10分おきの細かいデータを、カテゴリとか、センターとか、いろんなフィルタ使える状態で見たいんだ。

![viewrating.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678689/8b3c7155-3fe2-9fe8-cffc-e9b09d2a5ccb.png)
▲弊社で独自分析しているコミュニティチャンネルの視聴率データ。今年度と前年度を重ねて出したい。何ならヒント機能で今年・去年でそれぞれ何の番組やっていたかマウスオーバーするだけでわかるようにしたい。

# そうだ、列をつくろう
はい、スマートじゃないですね。
だってそれしか思いつかないんですもの。
例えば2020年8月7日23:50の視聴率データがあったら、2019年8月7日の視聴率もデータで持ってしまおうというもの。
![名称未設定-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678689/4dbcd739-dcd8-50e8-87a6-94d3969dd2bb.png)

でも、こうしておけば、重ねて表示することもできます。
今回つかうDAX関数はこちら

``` 前年度時刻列の追加
前年度時刻 = CONVERT(EDATE('テーブル名'[時間],-12)&" "&TIMEVALUE('テーブル名'[時間]),DATETIME)
```

``` 前年度データ列の追加
前年度データ = LOOKUPVALUE('テーブル名'[対象データのカラム名],
                'テーブル名'[条件列のカラム名],'テーブル名'[条件列のカラム名],
                'テーブル名'[時間],'テーブル名'[前年度時刻],
              0)
```

あとは、グラフの「値」「第2の値」に今年度データと前年度データを読み込ませればOKです。

# 解説
## 前年度時刻の追加
``` 前年度時刻列の追加
前年度時刻 = CONVERT(EDATE('テーブル名'[時間],-12)&" "&TIMEVALUE('テーブル名'[時間]),DATETIME)
```
列を追加して強引にデータを持ってしまおうというのは先に述べた通り。
前年度時刻を算出するために、EDATE関数を使って時間を12か月分さかのぼります。
ただし、EDATE関数はDATE型を返すので、TIME部分が抜け落ちてしまいます。
そのため、TIMEVALUEで時間部分を抜き出して、＆でつないでやっています。
このままだと文字列型になっているので、最後にCONVERTでDATETIME型に変換しています。
（じぶんは日時に重複あるデータを使ったので怒られましたが、日時がユニークな方はもしかしたらDATEADD関数とかでいけるかも？）
ちなみに、前月比較したいときは、EDATEの二つ目の引数の-12ってなっているところが月なので、-1に変えてやればいけます。

## 前年度データ列の追加
``` 前年度データ列の追加
前年度データ = LOOKUPVALUE('テーブル名'[対象データのカラム名],
                'テーブル名'[条件列のカラム名],検索条件,
                'テーブル名'[時間],'テーブル名'[前年度時刻],
              0)
```
LOOKUPVALUE関数は、検索条件に一致するデータを探してきてくれます。
最初に対象データを指定、カンマで区切って、次に条件列のカラム名、検索条件を書きます（検索条件は複数OK）。
今回じぶんは時刻だけじゃなく、ほかのデータでも条件つけたのでこう書きましたけど、条件が時刻だけという方は2行目は不要です。
なお、時刻以外条件を変化させないときは（その行と同じ条件で時刻だけ前年度にしたデータを持ってきたい場合）、二行目を

```
'テーブル名'[条件列のカラム名],'テーブル名'[条件列のカラム名],
```
と変えてやればうまくいきます。

毎回言っていますが、ヒント機能は楽しいですね。
とりあえずマウスオーバーしたときに前年度と今年度のデータを出せるようにしてみましたが、本当はもう少し凝りたいところです。
それでは素敵なPowerBIライフを！
LAMP環境にてBasic認証のウィンドウが出ない。

# 概要

「インフラとか設定まわりいじってみるか。」と思い立ち、練習がてらBasic認証の設置に挑戦。
手順通り進めたものの、想定したウィンドウが出ない。以下、試したことと解決策を列挙。
環境は以下の通り。

・CentOS 7
・PHP 7.2
・Apache 2.3

# 準備・試したこと
## ファイル
・file.php : 認証をかけたいファイル
・.htaccess : 認証の設定ファイル
・.htpasswd : IDとパスワードの設置場所

## 中身
```file.php
<?php
//パスワードを記録したファイルの場所
echo __FILE__;
// /~/file.php

echo '<br>';
//パスワード(暗号化)
echo(password_hash('パスワード', PASSWORD_BCRYPT));

?>
```

**↓.htaccess**

```
AuthType Basic
AuthName "IDとパスワードを入力してください。"
AuthUserFile /~/.htpasswd
require valid-user

(※ファイル末尾は改行入れておく)
```

**↓.htpasswd**

```

admin:(暗号化されたパスワード)

(※ファイル末尾は改行入れておく)
```

## 試したこと
・ファイルの記述漏れ、ファイル名の間違い確認
・キャッシュのクリア
・.htaccessの操作権限確認（通常ファイルと同様644等であればよいとのこと）

上記はいずれも問題なしとのこと。しばし調査を続けていたところ、解決策を発見。

# 解決策
httpd.confから「.htaccess」を使用する許可をすること。

```
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be “All”, “None”, or any combination of the keywords:
# Options FileInfo AuthConfig Limit
#
# AllowOverride None
AllowOverride All
```
AllowOvewrrideを「None」から「All」に変更してあげたところうまく動いてくれた模様。

# 今回お世話になった先人の知恵
・ApacheでBasic認証設定
https://qiita.com/syama1127/items/d72aa5d8786fe19f26ff

・ApacheのBasic認証が効かない場合に確認すべきことはコレ
https://www.yajiuma-soul.com/entry/20160617-1466110800
サブディレクトリ内を含むすべてのファイル名を取得する方法

①dirコマンド
dir /b /s /a-d | clip

②Excel関数
=MID(SUBSTITUTE(A1,LEFT(A1,FIND(">",SUBSTITUTE(A1,"\",">",LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))),1)-1),""),2,LEN(A1))
あなたのファイル、ソーシャルディスタンス保てていますか？

## 注意
__この記事は今の御時世に関係ありますが、まじめな記事ではございません。__

# はじめに
最近コロナのせいで、いつも以上に電車やバスなどで他の乗客との距離感が気になったり、
ドラマや映画で密になっていたりすると「これめっちゃ密やん」って思ったりしますよね。

__それと同じで、ファイルの中身を見ているとなにかムズムズしませんか？__

しますよね？

__それって行間のソーシャルディスタンスが保てていないからじゃないですか？__

__そんなムズムズを解消してくれるプログラムを GO で作ってみました！__

# ファイルがソーシャルディスタンスを保つ方法
ウェブサイトで推奨されているフォントサイズが__約 3 ～ 4 mm__ 、
日本の社会的距離の推奨距離である __2.0 m__ から、
__571 行__の行間を開けることで、ファイルに社会的距離を保たせることにしました。

# 環境
* OS : Windows10
* Go : 1.14.6
* エディタ : Visual Studio Code

# プログラム
プログラムのソースコードはこんな感じ。
Goは触って1ヶ月もたってないので、多分ひどいコードだと思います（笑）。

```Go
package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"path"
)

func main() {

	flag.Parse()

	if flag.NArg() != 1 {
		fmt.Println("ファイルを１つだけ指定してください(Please specify only one file)")
		return
	}

	filepath := flag.Arg(0)

	_, fname := path.Split(filepath)

	rfp, err := os.Open(fname)
	defer rfp.Close()
	if os.IsNotExist(err) {
		fmt.Println("ファイルが存在しません。(file does not exist.)")
		return
	}

	wfp, err := os.Create("sdt-" + fname)
	defer wfp.Close()
	if os.IsNotExist(err) {
		log.Fatal(err)
	}

	lines := bufio.NewScanner(rfp)

	for lines.Scan() {
		line := lines.Text()

		io.WriteString(wfp, (line + "\n"))

		for j := 0; j < 571; j++ {
			io.WriteString(wfp, ("\n"))
		}
	}

	if err != nil {
		log.Fatal(err)
		return
	}

}
```

__1.__ ソーシャルディスタンスを保ちたいファイルを読み込む。
__2.__ 書き込み用のファイルをファイル名「sdf-{読み込んだファイル名}」で用意する。
__3.__ 1 行書き込んでは、571 行改行するを繰り返す。

という感じの流れで実装しました。

# 実行方法
Go を実行できるターミナルなら動く__はず__。

```terminal
$ go run main.go ファイル名

もしくは

$ go build main.go
$ ./main.exe ファイル名
```

# 実際どうなる？
今回は例として「じゅげむ」を用意してみました。
見ているだけで密になっていて__ムズムズ__しますね。

```txt
じゅげむ　じゅげむ　ごこうのすりきれ
かいじゃりすいぎょの　すいぎょうまつ
うんらいまつ　ふうらいまつ
くうねるところに　すむところ
やぶらこうじの　ぶらこうじ
パイポパイポ　パイポのシューリンガン
シューリンガンのグーリンダイ
グーリンダイのポンポコピーのポンポコナーの
ちょうきゅうめいのちょうすけ
```

__変換前のファイルは、9 行でサイズが 445 バイトでしたが、__

ソーシャルディスタンスを保たせると、、、

__変換後のファイルは、5149 行でサイズが 5577 バイトになりました！__
(ファイルの行数が多すぎてここに掲載できません。)

__ファイルサイズは大きくなりましたが、ソーシャルディスタンスを保てていない方が問題ですよね？__

# まとめ
社会的距離や密を避けるために多大なコストが必要というのは、
__リアルの世界もデータの世界も変わらない__ということがわかりました。

__しかしこれで、ファイルのソーシャルディスタンスを保つことができたので快適な生活を送れますね！__

GitHubにソースコード上げているので、ここが気に入らないなどがあればプルリク等くださいね！
[GitHub:SocialDistanceFile](https://github.com/hajikuma11/SocialDistanceFile)

>あれ、今度は１文字１文字の間隔がムズムズしてきたな。
ターミナルでは実行できるsendmailがcronで動作しなかった話

Linuxでsendmailを含んだシェルスクリプトがターミナルのコマンドでは動作するのにcronで動作しなかった時の対処法の備忘録です。

次のような書式でシェルを書いた後、cronに定時実行するように書き込みました。すると、コマンド上では正常動作しメールが送信されましたが、cronに書き込んだ定時になってもメールが送信されませんでした。

```mail.sh
#!/bin/sh
{
echo "From: <****@gmail.com> "
echo "To: <****@gmail.com> "
echo "Subject: タイトル"
echo "Content-Type: text/plain;charset='UTF-8'"
echo "Content-Transfer-Encoding: base64"
}| sendmail -i -t
```

そこで、まずcronに問題があるのかと疑い、ファイル権限をchmod 777にした後、ログを確認してみましたがcronは問題なく動作しているようでした。

```
$ tail /var/log/cron
Aug  7 14:20:01 ip-***-**-*-** CROND[17995]: (root) CMD (/home/***/mail.sh)
```

問題はsendmailにあるらしいことが断定できたので調べ回ったところ、/usr/sbin/をつけたら問題なく動作しメールが送信され、gmail上では迷惑メールフォルダに受信できていました。

```mail.sh
#!/bin/sh
{
echo "From: <****@gmail.com> "
echo "To: <****@gmail.com> "
echo "Subject: タイトル"
echo "Content-Type: text/plain;charset='UTF-8'"
echo "Content-Transfer-Encoding: base64"
}| /usr/sbin/sendmail -i -t
```
UWAのLua CPUコスト分析サポート

現在、開発者にソースコードのHotFix機能を提供する最も標準的なソリューションがLuaではないでしょうか。Luaの性能改善は、開発者にとってますます重要になってきています。すでにUWA GOT OnlineでLuaメモリ診断の機能をできるようになっていますが、これに加えてLuaのCPUコストの分析機能を追加しました。 [UWAホームページ](https://jp.uwa4d.com/)に登録すれば、すぐ 「Lua性能診断」を確認できます。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/f508232a-839d-c334-0c66-4eb9040ae307.png)
下図はUWAウェブサイトにあるデモデータ，すでに[UWA GOT Onlineサービス](https://jp.uwa4d.com/price)で見たことあるかもしれないですが、最新のLua性能分析画面で、分析項目としての「コードの実行効率」の「CPU使用時間」で、一番処理時間かかっているTop10の関数がリストアップされています。
<img width="687" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/3fe7dcee-81aa-b142-87eb-5c3e364c8513.png">
これらの関数をクリックすると、関数の全体のCPU時間、指定シーンの処理時間及び任意のフレームでの処理時間などの情報を確認できるようになり、開発者が速くボトルネックのポジショニングできるようになります。

UWA GOT OnlineはこれでLuaコードの全面的なCPU処理時間分析、メモリ分析ができるようになります。また、診断の深さや全面的なメモリ割当情報に基づいて、開発者が直接ボトルネック問題を特定し、速く性能改善やゲームの実行効率向上に役に立ちます。
<img width="629" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/1709ca45-2928-522b-291f-d6cdc46ed82e.png">
ご注意頂きたいのは，Luaモードでの診断対象はLua関数のみですが、Luaに割り当てられたC#関数も含まれています。

---
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、**パフォーマンス分析**と**最適化ソリューション**及び**コンサルティングサービス**を提供している会社でございます。

UWA公式サイト：https://jp.uwa4d.com
UWA公式ブログ：https://blog.jp.uwa4d.com
Nextcloud を使ってみる - 基本情報とインストールについて

既に個人的に Google Drive や Dropbox を使用しているのですが、個人的なプロジェクトで複数人と動画、画像、音声ファイルなど様々なデータを共有して共同作業することになり、Google Drive、Dropbox は既に有料版を別のプロジェクトで使用していてデータ共有に関して共同作業においては使い勝手がさほど良くなかったので、Gandi.netのサーバーインスタンス上で Nextcloud を試してみました。

結果、Nextcloud の使い勝手が良かったのでここで共有します。

#Nextcloud とは

![スクリーンショット 2020-08-07 15.49.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242535/d3fd667a-5ecd-cfd2-5df2-b3d6c0df18e9.png)


まず、Nextcloudとはオープンソースのファイル共有ソフトウェアで、ownCloudという別のオープンソースファイル共有ソフトウェアのフォークとして始まったプロジェクト。
簡単に言うと、一般的に皆が使用している Google Drive や Dropbox などオンラインストレージサービスのオープンソース版です。

公式サイト
https://nextcloud.com/

インストール
https://nextcloud.com/install/ 

ちなみに、Nextcloud の英語ブログがあるのですがプロダクトやそれを取り巻く技術や環境、機能について詳しく書かれている投稿が多く勉強になります。

Nextcloud ブログ
https://nextcloud.com/blog/ 

###基本情報

- 他オンラインストレージサービスと同様、いつでもどこもアクセス可能
- Nextcloudをサーバーにセットアップ後、アカウントを発行して他人に同じストレージへのアクセス権を付与可能
- チャット、ビデオチャット、その他ミニアプリ機能が多数
- ブラウザ上だけではなく、iPhone、Androidアプリ、デスクトップ版は Windows、Mac、Linuxで使用可能。
- 活発な開発コミュニティ
- コントリビューターが多くいるためメンテナンスや機能追加が頻繁に行われている
- 何より、自分のサーバーに立てられるのでファイルの所有権は100%自分自身

###セキュリティ機能

その他のサービスと比べてNextcloudではセキュリティ関連の機能が充実。

- ブルートフォース攻撃対策
- 同じストレージにアクセスする人のアクセス権の詳細設定
- クライアントサイド、サーバーサイドでのファイルの暗号化
- LDAPや端末、IPアドレスでのアクセス制限、管理
- etc....


Nextcloud と他オンラインストレージサービスの比較
https://nextcloud.com/compare/


で、自分が契約しているサーバーに直接インストールするのも良いのですが、Gandi.net で Nextcloud のワンクリックインストールができるようになったので試してみました。

もちろん、AWS、オンプレ、その他諸々自由にインストールして使用できます。

##Gandi.netでワンクリックインストール

![スクリーンショット 2020-08-07 13.56.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242535/385b09a7-cca1-0dcb-0d0f-c8beaa54b6fc.png)

該当リンクはこちら

https://www.gandi.net/ja/simple-hosting/nextcloud

Nextcloud 使用開始までの手順はこのような流れです。

1. Gandi.net でドメイン名を取得
2. Nextcloud用のサーバープランを選択
3. Nextcloudに使用するドメイン名を選択して、使用したいサブドメインを入力
4. 支払い
5. セットアップ完了まで2-3分待つ
6. Gandiのサーバーインスタンス管理ページでHTTPSアクセスに変更 (この操作はなくてもok)
7. 自分が選んだドメイン名をブラウザのアドレスバーで入力するとNextcloudのアカウント作成ページが表示されるので、アカウント作成
8. 使用開始

セットアップから使い始めまでスムーズに行えます。自分は、こうやって設定した後にWindowsデスクトップアプリをインストールして、ディスクスペースにパーティションを作成してNextcloudで共有ファイルの管理をしています。

自分のサーバー上でオンラインストレージを使いたい人にはNextcloudおすすめです。
Power BIにPowerPointを埋め込もう

# はじめに
　Power PIをPower Pointにエクスポートするのは、こちら（ [レポート全体を PowerPoint にエクスポートする - Power BI | Microsoft Docs](https://docs.microsoft.com/ja-jp/power-bi/consumer/end-user-powerpoint)）にあるようにできるのですが、各ビジュアルが静止画になってしまいます。
　私がやりたいことは、プレゼンをしながら、途中でPower BIで中身を動かしたりしながら紹介することでした。探していると、**Power BI ServiceにPowerPointスライドを埋め込む** というやり方がありましたので紹介します。

## 前提等
 - Power BI Desktopではなく、Webに発行された後のPower BI Serviceを使います。
 - PowerPointはOneDriveに保管されているものとします。
 - 完成したPower BI SerivceのアプリをAnonymousアクセス許すWEBの一般公開はできません。Power BI Serivceを利用する組織内でWEBブラウザ等で共有できます。

## 埋め込むPowerPointスライドのアドレスの取得

　Web上のOneDrive等からPowerPointをWebブラウザで開きます。[ファイル]-[共有]から[埋め込み]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/37ce2c77-acc9-1994-c26e-b3c7b811d014.png)

埋め込みコードをコピーします。

```ruby:埋め込みコード
<iframe 
　src="https://ishia〇〇〇-my.sharepoint.com/personal/ishiayaya_〇〇〇_info/_layouts/15/Doc.aspx?sourcedoc={23991384-fcf6-4b63-a73c-〇〇〇〇〇〇〇〇〇〇〇〇}&amp;action=embedview&amp;wdAr=1.7777777777777777"

 width="350px" height="221px" frameborder="0">これは、<a target="_blank" href="https://office.com/webapps">Office</a> の機能を利用した、<a target="_blank" href="https://office.com">Microsoft Office</a> の埋め込み型のプレゼンテーションです。</iframe>
```

こちらのsrcの中にあるURLの部分をコピーします。実際の中身は以下です。

```ruby:コピーする部分のみ
https://ishia〇〇〇-my.sharepoint.com/personal/ishiayaya_〇〇〇_info/_layouts/15/Doc.aspx?sourcedoc={23991384-fcf6-4b63-a73c-〇〇〇〇〇〇〇〇〇〇〇〇}&amp;action=embedview&amp;wdAr=1.7777777777777777
```


## Power BI Serviceのアプリ作成
 Power BIを埋め込みたいレポート等を含むワークスペースを準備します。そこから右上の「アプリを...」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/63c79572-f54b-fb17-6552-badfe5acf8a2.png)

上部の「ナビゲーション」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/8a5d40d4-5b60-93ea-33d9-2d2822a2afaa.png)

名前を適当につけて、リンクに、PowerPointで取得コピーしたリンクを張ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/211f613d-97e1-72a6-4c26-eafa1493cea8.png)

次の方法で開くは「コンテンツ領域」を指定します。

下の[アプリの更新]を押し、進めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/73664488-0365-30cf-44b4-87c4feb20719.png)

ここで[アプリの移動]へ進むと埋め込んだPowerPointが見られます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/0fea8632-642a-b32d-1074-cc3b618ef279.png)

起動時はこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/fb1f3742-a6d8-9656-a87b-651d64fd36f3.png)

スライドの移動は下部や、矢印キーです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/bafc719c-ce9b-508f-15ab-4abdfee58329.png)

PowerPointのアニメーションも表示されます。

Power BI レポートのセクションにいくと、Power BIが表示され、通常どおり動かせます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419691/42c33ccd-adc8-638d-7944-4fefb4672803.png)

プレゼンの際は、絞り込んだ結果のブックマークをしておくなどの準備をするとよいですね。

## 参考にした動画サイト

[Guy in a Cube](https://www.youtube.com/channel/UCFp1vaKzpfvoGai0vE5VJ0w)

- [Can you embed PowerPoint into a Power BI App? Let's try! - YouTube](https://www.youtube.com/watch?v=fr1yjm-uFRE)

で紹介されていた内容です

# おわりに
　とても便利で、早速勉強会のプレゼン等で利用開始しています～
本題ではないですがマイクロソフトさん「Power」のネーミングほんと好きそうですねw
ボタン連打防止用コード

自分用メモ
・ボタン連打防止用コード
※参考にする場合は、ご自身で検証してください。（検証不十分なため）

```java:qiita.java

public class TestActivity {

  // ！！！自分用メモでテスト不十分なことをご承知ください！！！

  // バックキー連打防止用フラグ
  private boolean backKeyEnabled = true;

  @Override
  public boolean dispatchKeyEvent(KeyEvent event) {
    // 連打しようとしたらボタン無効
    if(!backKeyEnabled) {
      return false;
    }
    // ボタンを押したら
    backKeyEnabled = false;
    // ボタンをしばらく押せないようにする
    new Handler().postDelayed(new Runnable() {
      @Override
      public void run() {
        backKeyEnabled = true; // 1sec後に押せるようにする
      }
    }, 1000);

    // 以後処理 
  }
}
```
WSL2でvenvにパッケージがインストールされない。

初歩的なミスだけどめちゃくちゃハマったので自分用にまとめる。
## 環境
- WSL2
- Ubuntu18.04
- Python3.8


# 起きた問題
[wslでpythonのvenv環境が作れない](https://qiita.com/tatamyiwathy/items/c673c19202eea260f37e)でvenv環境作成後、
インストールしたパッケージが、venvではなくグローバルにインストールされてしまう。

```bash
(venv) $ pip install janome
Successfully installed janome-0.3.10

(venv) $ pip show janome
WARNING: pip is being invoked by 
Name: Janome
Version: 0.3.10
Summary: Japanese morphological analysis engine.
Home-page: https://mocobeta.github.io/janome/en/
Author: Tomoko Uchida
Author-email: tomoko.uchida.1111@gmail.com
License: AL2
Location: /home/USERNAME/.local/lib/python3.8/site-packages
Requires:
Required-by:
```

`<カレントディレクトリ>/venv/lib/python3.8/site-packages`にインストールしてほしいのに`/home/USERNAME/.local/lib/python3.8/site-packages`にインストールされてしまう。

```
(venv) $ pip show pip
Location: /home/USERNAME/.local/lib/python3.8/site-packages
```
そもそもvenv内のpipを使ってないことに気づく。

# 解決策
[wslでpythonのvenv環境が作れない](https://qiita.com/tatamyiwathy/items/c673c19202eea260f37e)でvenv環境に新たにpipをインストールしているので、
一旦deactivateし再度activateしないとvenv内のpipを使えない。
BigQueryってなんだっけ? そんな君たちに教えたい本見つけたのでまとめてみる。

# 対象読者
- データ分析基盤を作ってみたいけど、分析基盤の作り方がわからない
- BigQueryって聞いたことあるけど、実際に使ったことがない。興味ある。
- BigQueryって使おうと思ってググってみたけどあんまりまとまった情報がない

そのような気持ちを持つ方が読者想定です。
自身もこの本に出会う前には、同じような**BigQuery童貞**でした。


# (結論)イイタイコト

BigQuery初心者や、これから導入考えてる人が、読むべき本を見つけました！！

<a href="https://amzn.to/3koixnU" target="_blank"><img border="0" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/a444ff95-d07f-38e2-349f-755df98daed3.jpeg" width="200"></a>
<a href="https://amzn.to/3koixnU">Google Cloud Platform実践ビッグデータ分析基盤開発 ストーリーで学ぶGoogle BigQuery</a>
です。
あまりBigQueryの本がなく、半信半疑で読みましたがBigQueryの全体像が捉えられる良書でした。


# この本のイイところ
この本のイイところは3つあります。

1. BigQueryの概要が難しすぎず、ちょうど**かゆいところに手が届く**適度な難度
2. 実際にデータ基盤を入れるストーリーになっているので、**具体的な導入イメージ**が湧く
3. ストーリー仕立てて、**サクッと読める**(数時間で読めます)

# ポイント独自まとめ
自分が読んでみてポイントに感じたところ。面白かったところかいつまんでまとめます。

- 最初は同期するデータ絞って、分析基盤回す
- 上限(Quota)を割り当てておく(1TB/日だと$5程度なので安心)
- 文字コードはUTF-8
- 読み込み形式は多数(json, avro, parquet, ORC, csv) => メジャーはcsv, パファーマンス改善が必要ならavro等検討
- データ加工: create table as selectクエリで、データ加工したものを別のテーブルとして保存する (実験のときはviewがオススメ)
- レガシーSQLと標準SQL => 標準SQL使おう
- google data studio (google データポータル)は素晴らしい可視化

## Bigqueryのアーキテクチャ
- Dremelクエリエンジン: 1TBのテーブルスキャンを1秒以内にすることを目標として進められたエンジン(大規模分散処理)
- カラム指向ストレージ:selectする列数は絞ったほうがパフォーマンスが出やすい

## 特殊なテーブル指定
- パーティション分割テーブル: 日付or整数でテーブル内のパーティションを区切ることができる
- クラスター化テーブル: 指定したクラスタリングを行うことで、特定のクエリでスキャン幅を縮められる RDSのインデックスに近いイメージ、最大4つまで

## DataWarehouseアーキテクチャは、ETLでなくELTにするのがポイント
E: Extract 抽出
L: Load データ取り込み
T: Transform データ加工
後ろに加工を持ってくることで、bigquery内で自由に扱える。(利便性やコスト面でgood！)

## 実運用方法
1. まずは、既存テーブルを一括で持ってくる
2. トランザクション系テーブルは、日時の分割テーブルとする
3. マスター系は大きくないので、単に連携データを追加していく

# まとめ・感想
BigQueryなんか使えそう、程度の軽い気持ちでしたが読んでみていい本でした。
1TBのテーブルスキャンを1秒以内にすることを目標とか、Googleさん流石化け物です。w
Emblukでもマスター系データは毎回全消しして入れ直す想定みたいで、、、それもまた大味だなと感動しました。
是非気になった方は本も手にとってみて下さい！

<a href="https://amzn.to/3koixnU" target="_blank"><img border="0" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/a444ff95-d07f-38e2-349f-755df98daed3.jpeg" width="200"></a>
<a href="https://amzn.to/3koixnU">Google Cloud Platform実践ビッグデータ分析基盤開発 ストーリーで学ぶGoogle BigQuery</a>

# おまけ
開発データDBをEmbulkでBigQueryに入れて、Google Data Studioで可視化してみました！！
こんな感じで、データが常に可視化でき好きにカスタマイズできれば、ここから戦略に繋がりそうでいい感じです。
![Screen Shot 2020-08-07 at 15.46.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/e4148f5c-cd46-94e2-f230-b2719029489f.png)
Fixed Joint2Dの解説

今回はFixed Joint2Dについて解説していきます。

#Fixed Joint2Dとは
Fixed Joint2Dとは、`２つのオブジェクトの相対位置を固定する`機能です。
Fixedの意味は「修繕」や「所定」など、
Fixed Jointになると「固定関節」になるそうです。

#Fixed Joint2Dの各パラメータ
![FixedJoint2D_param.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685029/c165a410-f9ba-229d-3767-93ec1d2f96db.png)
やっぱりパラメータが多いですね。
どうやらJoint2Dと名の付くものは「Joint2D」や「AnchoredJoint2D」といったクラスを継承しており、似通ったパラメータになっているそうです。
なので、今回は少し解説を省こうと思います。

###・Auto Configure Connected Anchor
ここのチェックボックスにチェックを入れると、下の`Connected Anchorが自動的に決定されます。`
Distance Joint2Dではこれを使うのはオススメしませんでしたが、Fixed Joint2Dではこれを使うことを**オススメします**。Fixed Joint2DのConnected Anchorはプロジェクトを実行するとAnchorと同じ場所に移動し、アタッチしたオブジェクトもそれにつられて移動してしまうからです。ちょっと言葉では理解しにくいと思いますが、実際にやってみたら分かると思います。

###・Frequency
Damping Ratioの前にFrequencyの解説をします。
簡単に言うと関節の硬さです。実際には、力を加えたときに１秒間に何回振動するか、つまり周波数のパラメータです。
数字が小さいほど柔らかくなりますが、`０になると完全に固まってしまいます`。

###・Damping Ratio
振動の幅がどのくらいの割合で減っていくかを決める場所です。
０～１までの値をとり、１に近づくほど振動幅が減りやすくなります。
注意してほしい点は、０でもある程度は振動幅が減っていくということです。

###・Break Torque
Fixed Joint2Dを破壊するのに必要な回転力を決めるところです。
infinityと入れると絶対に破壊されません。
また、infinityに戻したいときはinfと入力してください。

#使い道
私が思いついたのは、チューチュー（２つに折って食べるアイス）を折るゲームです。
あとはプールの飛び込み台など、けっこう色んなところに使えるかと思います。

#おわりに
UnityマニュアルのFixed Joint2Dを見てみたら、何かRelative Joint2Dと比較されていたので次回はRelative Joint2Dの解説をしたいと思います。
もしかしたらFixed Joint2DとRelative Joint2Dの比較記事になってしまうかもしれませんが、それもいいかもしれませんね。
Linuxにリンクローカルアドレスをアサインして DNS-SD/SSDPを使ってガサる

DHCPが無い環境で リンクローカルアドレス(IPv4)で自動的に上がってくるようなデバイスの
自動構成をしたくて Ubuntu/Debianで APIPAをふる方法と discoverのやりかた

## 準備

必要なパッケージのインストール

APIPAをふるだけなら avahi-autoipdがあれば目的としては達成できます

```bash
sudo apt-get install -y avahi-autoipd
```

名前やサービスの解決させたりもあるので 関連ツールとして avahi-daemon と avahi-utils、
さらに SSDPで検出したい場合なんかに gupnp-toolsも入れておく。

```bash
sudo apt-get install -y avahi-utils gupnp-tools
```

## 設定

eth2で使いたい場合、/etc/network/interfaces に以下を追加する。
この設定で eth2:avahi インターフェースに APIPAがふられる

```interfaces:/etc/network/interfaces
auto eth2
iface eth2 inet manual
  up /usr/sbin/avahi-autoipd -D --force-bind eth2
  down /usr/sbin/avahi-autoipd -k eth2
```

## 利用

interface を upするだけ

```bash
sudo ifup eth2
```

## 確認

```console
root@buster:~# ip -4 a
...
4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 169.254.5.253/16 brd 169.254.255.255 scope link eth2:avahi
       valid_lft forever preferred_lft forever
```

## 名前がわかっている物のIPを解決する

名前がわかっていれば mDNSで .local ドメインで名前解決する。
例えば fsというマシンを解決したければ `ping fs.local`

## DNS-SDで サービス一覧を表示してみる

`avahi-browse -al`

実行するとこんな感じ

```console
root@buster:~# avahi-browse -al
+   eth1 IPv4 amzn.dmgr:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:xxxxxxxxxx:##### _amzn-wplay._tcp     local
+   eth1 IPv4 fs - SSH                                      SSH Remote Terminal  local
+   eth1 IPv4 fs - SMB/CIFS                                 Microsoft Windows Network local
+   eth1 IPv4 fs - NFS - home                               Network File System  local
+   eth1 IPv4 Google-Home-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  _googlecast._tcp     local
+   eth1 IPv4 Chromecast-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx   _googlecast._tcp     local
```

オプションにrをつけるとさらにIPやポートまで解決して表示してくれる

## SSDPでデバイス一覧を表示してみる

インターフェースを指定して gssdp-discoverで行う

`gssdp-discover -i eth2:avahi`

```console
root@buster:~# gssdp-discover -i eth2:avahi --timeout=3
Using network interface eth2:avahi
Scanning for all resources
Showing "available" messages
resource available
  USN:      uuid:1a78e91b-d86d-11ea-8157-080027e8f737::upnp:rootdevice
  Location: http://169.254.86.237:1900/ddd.xml
```
使用してきた関数（メソッド）を忘れないように記載していくよ（PHP版 随時更新）

#はじめに
今まで使用してきたメソッド
これから使用してみるメソッド
忘れないように、随時更新していきます。

時間の都合上、
コードは載せる場合と、
載せない場合があります。

例）
■ メソッド名

意味：

参考コード

```php

雛形
```

一つ一つ書くのが手間なので、
雛形を書かせていただきました！


#書いていきます٩( ᐛ )و
■ is_null

意味：nullであればtrue,それ以外であればfalseを返す

参考コード

```php

<?php
 
$value = NULL;
 
if (is_null($value)){
  echo 'NULLです。';
}else{
  echo 'NULLではありません。';
}

実行結果
//NULLです。
?>
```

■ asset

意味：「public(公開)ディレクトリ」のパスを返すヘルパ関数
　　　 ヘルパとはviewファイルで使えるメソッドのことです。
　　　 現在のURLのスキーマ（httpかhttps）を使い、
　　　 アセットへのURLを生成するメソッド

参考コード

```php

<img src="{{ asset('storage/image/' . $headline->image_path) }}">
//保存した画像のファイル名が $head->image_pathに入っていることを想定
//このことで「.」を使用して、画像のパスを返していることになります。
```

■ str_split

意味：文字列を配列に変換する

参考コード

```php

array str_split ( string $string [, int $split_length = 1 ] )
//文字列を配列に変換します。
```


■ asset

意味：

参考コード

```php

雛形
```
インライン要素をCSSだけで区切って表示する方法

##例えば次のようなHTML要素があったとします。
```html
<div class="contents">
  <span>テキスト1</span>
  <span>テキスト2</span>
  <span>テキスト3</span>
  <span>テキスト4</span>
</div>
```
##必ずテキストが存在する要素のみで構成されたHTMLであれば次のCSSで問題ありません。
```css
.contents > span:not(:nth-child(1))::before {
  content: "、"
}
```
結果
テキスト1、テキスト2、テキスト3、テキスト4

class="contents"の配下のspanタグの先頭要素を除く、全ての要素の直前に読点を表示させるというCSSになります。

##しかし、次のように要素数は決まっているが、値が入っているかどうかはランダムである場合はどうでしょう？
パターン①

```html
<div class="contents">
  <span>テキスト1</span>
  <span></span>
  <span>テキスト3</span>
  <span></span>
</div>
```
結果
テキスト1、、テキスト3、

本当はこうなってほしい
テキスト1、テキスト3

パターン②

```html
<div class="contents">
  <span></span>
  <span>テキスト2</span>
  <span></span>
  <span>テキスト4</span>
</div>
```
結果
テキスト2、、テキスト4 

本当はこうなってほしい
テキスト2、テキスト4

##そのような場合はこのCSSを試してください
```css
.contents > span:not(:empty) ~ span:not(:empty)::before {
  content: "、"
}
```

E ~ Fは、E要素の後ろにある同じ階層のF要素にスタイルを適用する際に使用します。
http://www.htmq.com/selector/precede.shtml
テキストが存在するspanタグの後ろにある同じ階層の全てのspanタグでテキストが存在ものに対して、
その要素の直前（疑似要素：before）に読点を表示するというのがこのCSSの内容になります。
【Git】誤って違うブランチに複数Pushしたコミットを正しいブランチ先に移動する。【cherry-pick】

自分用のメモとして残します。


# ■やり方
前提として、cherry-pickを用いて連続したコミットをFromTo形式で移動させるのため、途中移動させたくないコミットがある場合は、この方法はできません。
また、移動先ファイルでも同じような修正が場合はコンフリクトがあるため、基本できません。
## コミットの移動（コピー）
### 1.移動したいコミットRevを確認する。
移動したいコミットがあるブランチ（＝誤ってコミット＆プッシュしたブランチ）をチェックアウトする。
続いて、` git fetch ` でリモートのコミット情報を取得してから
 ` git log --oneline ` コマンドで コミットRevを確認してFrom~Toの2件分控える。

```shell
git checkout 移動したいコミットRev群があるブランチ名
git fetch
git log --oneline
```


### 2.コミットの移動先ブランチをチェックアウト
```shell
git checkout 移動先ブランチ名
```

### 3.コミットをコピー
1で確認したFromToのコミットRevを指定

```shell
git cherry-pick FromRev^..ToRev
```

FromRev^の `^` は**FromRevを含む**という意味です。

### 4.コミットのコピーまでの情報をリモートに反映する。
```shell
git push
```

## 移動して不要になったコピー元コミットを削除する
### 5.コピー元コミットがあるブランチをチェックアウト

```shell
git checkout コピー元コミットがあるブランチ名
```

### 6.コミット削除
**注意）下記の例はブランチのHeadから3つ前まで履歴を削除するという例です。**

```shell
git reset --hard HEAD~3
```

例えばHEADを含む2つのコミットをコピーした場合は
上記のようにHEADから数えて3つ前のコミットがHEADになるようにHEAD,HEADの直前コミットの2件をリセットするという意味なる。

### 7.コミット削除をリモートに反映する。
```shell
 git push -f origin ブランチ名
```

以上。
djangoアプリでフロント作るときにmixinの読み込み方がわからなかった話【初学者が参考書片手にpython学習】

## はじめに
[大高隆・著「動かして学ぶ！Python Django開発入門」](https://www.amazon.co.jp/dp/B07YY5RDPC/ref=cm_sw_r_tw_dp_U_x_TCsYEbRH6SF0V)を使用して
python・Djangoの学習を始めた初学者です。

ruby・railsを使用して4ヶ月ほどプログラミングの勉強をしていましたが、
エンジニア転職にあたり、pythonを使用することになったのでこの本を片手に勉強を始めました。

ド級の素人なので、補足・ご指摘等コメントいただけると大変助かります。

## 概要

一旦バックエンドが落ち着いたので、試しにフロントエンド工作。
そういえば、'rails'だと'application.scss'に記入しておけば
勝手にmixinとか全部読みこんでくれるけど、djangoはどうすれば良いのだろうか？？

## 結果

mixinを利用したい.SCSSファイルの最初に

```
@import "mixin.scss";
```

と、書いておいてあげればいいのでした。そのまんまですね。

## 参考文献
[大高隆・著「動かして学ぶ！Python Django開発入門」](https://www.amazon.co.jp/dp/B07YY5RDPC/ref=cm_sw_r_tw_dp_U_x_TCsYEbRH6SF0V)
計算量の多い教師なしレコメンドデータセットを作成する際の工夫

# 想定される状況

- 自然言語をBERTなど単語分散表現を用いてベクトル化
- cos 類似度を計算し、文章同士の類似度を数値化
- 類似度の高いコンテンツ同士を似ているコンテンツとみなし、レコメンドするためのデータセットを作成する

以上の状況において、 O(N^2) のデータ量となるが、 「コンテンツデータが100万件あります！」みたいな、 O(N) = 10^6 規模のデータセットとなると、計算コストなどが大きくなり計算が容易ではないという問題が発生します。（実体験）
その解決策をまとめておきます。

# 計算コストの削減

1. ベクトルの L2 正規化
1. 行列の内積を演算
1. 正規化済みのベクトルなのでこの演算結果で得られるベクトルが類似度ベクトルとなる

## 計算アルゴリズム
正規化したN個の文章ベクトルをそれぞれ 

```math
V_i (i = 1 ... N)
```

とするとき、文章ベクトルを縦方向に結合し、まとめた行列を

```math
A = \left( \begin{array}{c} V_1 \\ V_2 \\ \vdots \\ V_N \end{array} \right)
```

と定義し、類似度行列 W を以下のように得る。

```math
W = A \cdot A^{\mathrm{T}}
```

このとき W は N × N 行列となる。
それぞれの要素は各アイテム間の類似度をそのまま示す。例えば、  

```math 
W_{12}
```

は、1個目のアイテムと2個目のアイテムの類似度を示す。

# データ量の削減

上記の計算コストの削減では計算量は減らせるものの、データ量は変わらず O(N^2) のままである。
そこで、N の数を減らす工夫が必要となる。

- クラスタリングによるデータセットの分割
    - 混交ガウスモデルなど教師なしクラスタリングを使い、データをK個のデータに分割する
- 類似度は Top M 個のみを採用する
    - 例えば、類似度の高い順に並べ替え、上位30個のみ保持することにすれば、類似度行列のデータ量は N × 30 となる
- 特徴量ベクトルの集合行列 A の分割
    - 詳細は後述する

## ベクトルの集合行列の分割方式

特徴量ベクトルの集合行列 A 

```math
A = \left( \begin{array}{c} V_1 \\ V_2 \\ \vdots \\ V_N \end{array} \right)
```
を、縦方向にM個に分割する。例えば、1個の行列に100個ずつのベクトルを含むとすると、

```math
A_1 = \left( \begin{array}{c} V_1 \\ \vdots \\ V_{100} \end{array} \right) \\ 
A_2 = \left( \begin{array}{c} V_{101} \\ \vdots \\ V_{200} \end{array} \right) \\ 
A_3 = \left( \begin{array}{c} V_{201} \\ \vdots \\ V_{300} \end{array} \right) \\ 
\vdots \\
A_M = \left( \begin{array}{c} V_{N-99} \\ \vdots \\ V_{N} \end{array} \right)  
```

このとき、A_1 に対する類似度行列は、

```math
W_1 = A_1 \cdot A^{\mathrm{T}}
```

であり、W_1 の大きさは 100 × N 行列となる。この方法では計算コストも同様に減らせる。

最終的に、W_1 ... W_M を縦方向に結合したものは W に一致するので計算上の差異はない。

```math
\left( \begin{array}{c} W_1 \\ \vdots \\ W_M \end{array} \right) = W
```
import requests できない

# 起きた問題
```bash

(venv)$  python main.py
```
```bash

Traceback (most recent call last):
  File "main.py", line 3, in <module>
    import requests
ModuleNotFoundError: No module named 'requests'
```

## 環境
- WSL2
- Ubuntu18.04
- Python3.8

# パスの確認
[Pythonモジュールのimportができなくなったときの対処記録](https://qiita.com/Kent_recuca/items/349586e9c034535f2991)に従ってPathの追加までやってみる。

### pythonが探索するパス
```python

>>> import sys
>>> sys.path
['', '/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload', '/home/USERNAME/documents/manzai/venv/lib/python3.8/site-packages']
```
### requests 

```
(venv)$ pip show requests
```
```bash

WARNING: pip is being invoked by an old script wrapper. This will fail in a future version of pip.
Please see https://github.com/pypa/pip/issues/5599 for advice on fixing the underlying issue.
To avoid this problem you can invoke Python with '-m pip' instead of running pip directly.
Name: requests
Version: 2.24.0
Summary: Python HTTP for Humans.
Home-page: https://requests.readthedocs.io
Author: Kenneth Reitz
Author-email: me@kennethreitz.org
License: Apache 2.0
Location: /usr/local/lib/python3.8/dist-packages
Requires: chardet, idna, urllib3, certifi
Required-by: httpie
```
`/usr/local/lib/python3.8/dist-packages`にインストールされている。
このディレクトリはPythonの探索範囲に入っていないのでPathを追加。

```python

>>> sys.path.append('/usr/local/lib/python3.8/dist-packages')
```
```python

>>> import requests
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.8/dist-packages/requests/__init__.py", line 43, in <module>
    import urllib3
ModuleNotFoundError: No module named 'urllib3'
```

今度は`urllib3`がないと言われた。

# 解決
```bash

$ sudo pip install requests -t /usr/lib/python3.8
```
`/usr/lib/python3.8` にrequestsをインストールで行けた!!
Texのコンパイルが遅い

#Texのコンパイルが遅いのをどうにかしたい



texのコンパイルが遅くなる原因は画像データの描画であるらしい。


####結論から言うと、draftオプションをつかえ

````
\documentclass[a4paper,twocolumn,10pt,draft]{jsarticle}
```

画像の部分が枠と、画像のパスに置き換わり、レイアウトを組みつつ、高速なコンパイルが可能になる。

ある文書で測定してみたら、画像ありだと約1分かかるが、draftオプションを使用すると約20秒でpdfが生成された。
Laravelの学習備忘録　その3

プログラマー初心者です。
Laravelを触って頑張っています。
Laravelでアプリを作りながら学んだことを雑多に記していきます。
記事の正確性は低めです。なので、各項目ごとの参考を参照したほうが良いと思います。
それでは！

### .envのAPP_URLの設定
ローカルで複数のプロジェクトを作る際にAPP_URLの設定をしておく。
`php artisan serve`で立ち上がる、簡易サーバでアクセスされるのが、このURLを設定しておくとよさそう。

```php:.env
APP_URL=http://localhost/{プロジェクト名（任意）}
```
にしておくとよさそう。

### バリデーション
参考：[ドキュメント「バリデーション」](https://readouble.com/laravel/7.x/ja/validation)
Laravelではバリデーションの方法がいくつかあるようだ。
- validate()メソッドを使う
- FormRequestを使う←おすすめとのこと。

FormRequestを使う方法は、学習済み。
- `$ php artisan make:request DiaryRequest`でフォームリクエスト作成
- ↑で作ったファイルを編集。
    - authorizeメソッド内をtrueに
    - rulesメソッド内にバリデーション定義を記していく。
    - attributesメソッドを作って、バリデーションエラーのときに表示する名称を個別に設定する。
    - messagesメソッドにして、そのままエラーメッセージを表示することもできる。
    - 

validateメソッドの方法でも試してみよう。
やりかたは、コントローラの中で、$requestを受けるときに、
`$validated_date = $request->validate([バリデーションルールを記述]);`
でオッケー。簡単。

でも、FormRequestを使おう。なぜなら、コントローラーをすっきりさせて、見通しを良くしたいから。
また、より複雑なロジックを組める。

### $fillableか$guardedか
参考：[Qiita「僕がLaravelのEloquentに$fillableでなく$guardedを指定する理由」](https://qiita.com/toro_ponz/items/b33c757cb7ba5bb48ed4)
\$fillableで指定したもののみ代入可能（ホワイトリスト化）。
\$guardedは指定したものが代入不可能（ブラックリスト化）。
記事の内容が僕にはまだ理解しづらかったので、とりあえず今はfillableをつかう。

### 中間テーブル
参考：[Qiita「中間テーブルとは」](https://qiita.com/morikuma709/items/9fde633db9171b36a068)
- 多対多のテーブル同士のリレーションだと、お互い関係させようとすると、カラムが無駄に多くなったり、空白になってしまう。
- 例：articlesテーブルとtagsテーブルがあるときに、例えば、articlesタグにtagカラムをつけようとすると、1つの記事にタグをつけたいけど、いくつつくかわからないし、tagカラムがいっぱい作っておかないといけないし、空白フィールドもできて管理しづらくなる。
そこで間に１つテーブル入れることで、空白のカラムをつくることなく、管理しやすくなる。詳しくは上の参考を見るのが一番いい。
- なお、laravelで中間テーブルのマイグレーションを作るときは、単数形で！

### マイグレーションでのつまづき

#### 複数形
テーブル、マイグレーション作成時に複数形にするとLaravelではきちんと関係性を読み込んでくれるのだが、複数形にするときに困ったのが、'diary'の複数形。
'diarys' or 'diaries'　どっちだ。

答えは**diaries**

'diarys'で最初作ったら、マイグレートのときにエラーが出て先に進めなかった。やり直して、diariesでいったら、通った。単数形にsをつけるだけじゃないんだね。英語の初歩って感じだけど、複数形の法則ってちゃんとデータベースに仕組みが入っているのね。

#### マイグレーションファイルの作成順番
外部キー制約させたい元のテーブルのマイグレーションファイルは先に作っておかないと、エラーがでるので、マイグレーションの順番にもちょっと注意が必要。
よく考えてみれば、日付が新しい順から実行してマイグレーションupするんだから、「外部キーがないよ」ってなるのは当たり前か。
一気にマイグレーションファイルを作ってからマイグレートでいいけど、ファイルの作成順番が大事ということで。
【Laravel】生のSQLの書く方法

# はじめに

Laravelで複雑な生SQLを書きたい時ってありますよね。

生のSQLの書き方が中々見つからなかったり、別の書き方では動かなかったりしたので、残しておきます。

# 前提条件
・PHP7.3
・Laravel5.8
・MySQL8.0


# 書き方

これだけです。

```sql.php

DB::select(

 // 生のSQL文

);

```

パラメータや変数の値をSQL分に含めたい時は、以下の通り。

```sql.php

$user_id = $request['user_id'];

DB::select(

 // 生のSQL文

 :user_id

 // 生のSQL文

, ['user_id' => $user_id]);

```
SQL文中に変数を代入する部分は、「:変数名」としてあげて、連想配列の形で定義済み変数を渡して上げましょう。
単純な共通鍵をC言語で書いた

<h1>単純な共通鍵をC言語で書いた</h1>

クソしょうもないですが、共通鍵の説明を概念図を使って説明するよりはマシかなと思いました。

^演算子は、排他的論理和です。
多分どの環境でも動くはずです。

```
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void DecodeWithCommonKey(char *data, char key){
    int i;
    int len;
    len = strlen(data);
    for(i=0; i<len; i++){
        *(data+i) = *(data+i)^key;
    }
}
void EncodeWithCommonKey(char *data, char key){
    int i;    
    int len;
    len = strlen(data);
    for(i=0; i<len; i++){
        *(data+i) = *(data+i)^key;
    }
}
int main(){
    char key = 0x10;
    char data[]="Niwaka";

    //暗号化
    DecodeWithCommonKey(data, key);
    printf("暗号文：%s\n", data);

    //復号化
    EncodeWithCommonKey(data, key);
    printf("平文：%s\n", data);
    
    return 0;
}
```

keyでNiwakaを暗号化し、また復号化するという単純なプログラムです。
Niwaka文字列の１つ１つの文字に対して、keyとの排他的論理和を実行しています。
(文字コードはasciiコードのはずです。)

受信者と送信者で同じkeyを持っておかないといけないので、共通鍵を使用する場合は鍵配送問題が生じます。
受信者と送信者で共通鍵を共有しておかないといけないので、安全な方法で共通鍵を送信しなければいけません。共通鍵を安全に送信できる方法があるのでしたら、その方法でデータを送信したらいいだけですよね。(共通鍵はここが問題点)
【Android】WorkManager+MVVM+Hilt

# WorkManagerとは？
Android Jetpackのライブラリの一つ。
ForegroundServiceやJobSchedulerの代わりになる。
https://developer.android.com/topic/libraries/architecture/workmanager?hl=ja

# やりたいこと
1. アプリから切り離して長時間の処理を行わせたい
2. ロジック部分はWorkManager外に定義したい
3. ついでに通知に結果を流し込みたい

# 1. アプリから切り離して長時間の処理を行わせたい
#### WorkManager基礎部分
```MyWorker.kt
class MyWorker constructor(
    private val context: Context,
    private val params: WorkerParameters
) : CoroutineWorker(context, params) {
  override suspend fun doWork(): Result {
    // 処理
    return Result.success()
  }
}
```
```MyViewModel.kt
class MyViewModel : ViewModel() {
  fun run(){
    WorkManager.getInstance(context)
            .enqueue(OneTimeWorkRequest.from(MyWorker::class.java))
  }
}
```
WorkerManagerをViewModel等から呼び出し、一度きり指定でMyWorkerを実行させます。
doWorkの中の処理がバックグラウンドで実行され、終わるとResult.success()が返却されます。

#### ForeGroundService化
```MyWorker.kt
  override suspend fun doWork(): Result {
    setForeground(ForegroundInfo(notificationId, notificationBuilder.build()))
    // 処理
  }
}
```
普通にNotificationBuilderを生成したら（割愛）、ForegroundInfo()に突っ込んでsetForegroundを呼び出します。
ForegroundServiceと違ってWorkManager側が実行をForeground化するかどうか決定出来るので、見る場所がスマートになっていい感じ。

#2. ロジック部分はWorkManager外に定義したい
MVVMパターンとHiltによるDIと組み合わせて、Repositoryに書いた処理をworkManagerから実行させたい。

```だめなパターン.kt
@AndroidEntryPoint// つけられない
class MyWorker constructor(
  private val context: Context,
  private val params: WorkerParameters
) : CoroutineWorker(context, params) {
  @Inject
  lateinit var myRepository: MyRepository
  override suspend fun doWork(): Result {
    myRepository.doSomething()// not initialized
    return Result.success()
  }
}
```
WorkManagerはServiceではないので@AndroidEntryPointが設定出来ません。
そのため、Injectが作用せずnot initializedと怒られてしまいます。
ではどうするか。

```MyApplication.kt
@HiltAndroidApp
class MyApplication @Inject constructor() : Application() {
  lateinit var myRepository: MyRepository
  override fun create(){
    WorkManager.initialize(
      this,
      Configuration.Builder()
        .setWorkerFactory(MyWorkerFactory(myRepository)).build()
    )
  }
}
```
```MyWorkerFactory.kt
class ThetaWorkerFactory @Inject constructor(
  private val myRepository: MyRepository
) : WorkerFactory() {
  override fun createWorker(
      appContext: Context,
      workerClassName: String,
      workerParameters: WorkerParameters
  ): ListenableWorker? {
      return MyWorker(myRepository, appContext, workerParameters)
  }
}
```
```MyWorker.kt
class MyWorker constructor(
  private val myRepository: MyRepository,
  private val context: Context,
  private val params: WorkerParameters
) : CoroutineWorker(context, params) {
  override suspend fun doWork(): Result {
    myRepository.doSomething()
    return Result.success()
  }
}
```
```AndroidManifest.xml
<application>
  <provider
    android:name="androidx.work.impl.WorkManagerInitializer"
    android:authorities="${applicationId}.workmanager-init"
    android:exported="false"
    tools:node="remove" />
```
ApplicationクラスでWorkerFactoryを上書きし、Workerに引数でrepositoryを渡すことで達成出来ました。
Workerは初期化が一度しか出来ないので、Manifestに初期化するなよとおまじないしなきゃいけないっていうやつは使うたび忘れそう~~気が利かない。~~

# 3. ついでに通知に結果を流し込みたい
長くなったので別記事に分けようと思います。
ロジスティック関数を描いてみる

# Overview

けっこう前に sympy でテイラー展開を描いてみたんですけど、
https://qiita.com/arc279/items/dda101b39b96c4aa94d0

視覚化するとイメージがわきやすいので、
今回はロジスティック回帰に出てくるロジスティック関数を描いてみます。

ロジスティック回帰の詳しい説明はこの辺が詳しいので、以下のサイトの解説と合わせてグラフを眺めてみてください。
http://darden.hatenablog.com/entry/2016/08/22/212522

ここでは数式のちゃんとした説明はしません、というかできないｗ

# 前準備

```bash
$ pip install matplotlib sympy     
```

```python:以下、jupyterのセルだと思ってください
from sympy import Symbol
from sympy.plotting import plot

p = Symbol('p')
x = Symbol('x')
```

# 登場する計算式

```math
\begin{align*}
& {\rm オッズ比 }: \frac{p}{1-p} \\
& {\rm ロジット関数 }: f(p) = \log \frac{p}{1-p} \\
& {\rm ロジスティック関数 }: g(x) = \frac{1}{1+e^{-x}}
\end{align*}
```

## `オッズ比(p) = p/(1-p)`

```python:jupyter
plot(p/(1-p), (p, -2, 2), ylim=(-100, 100), legend=True)
```

![fig1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41925/21077f31-44f7-fe74-3465-7c08ed151e5e.png)


*p = 1* で *-inf* と *+inf* が繋がっちゃてるのはご愛嬌なんですが、
これの *0 <= p <= 1* を切り取ると、

```python:jupyter
plot(p/(1-p), (p, 0, 1), ylim=(-100, 100), legend=True)
```

![fig2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41925/94d513a3-0560-5d0d-cbfb-10751c79cf8e.png)

定義域 *0 <= p <= 1* に対して 値域が *0 <= オッズ比(p) < +inf* まで拡張されます。

## ロジット関数 `f(p) = log(p/(1-p))`

オッズ比の対数を取ることで、

```python:jupyter
from sympy import log

plot(log(p/(1-p)), legend=True)
```

![fig3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41925/3cb1c733-b886-72b5-c85e-7032ef303846.png)

オッズ比と同じ定義域に対して、値域が *-inf < f(p) < +inf* まで拡張されてますね。

## ロジスティック関数 `g(x) = 1/(1+exp(-x))`

ロジット関数の逆関数なので、

```python:jupyter
from sympy import exp

plot(1/(1+exp(-x)), legend=True)
```

![fig4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41925/33f4bb70-1ed0-b1dd-512e-6f4f8c8baf70.png)

ロジット関数の値域と定義域が入れ替わって、

* 定義域： *-inf < z < +inf*
* 値域　： *0 <= g(z) <= 1*

つまり、確率 *0 <= g(z) <= 1* とみなせる値を出力する関数、と見なせるってことですね。


みたいな解釈で合ってる？