OmniAICreator/Qiita-1.07M huggingface dataset:
Python Paiza-スキルチェックと 標準入力(input)のいろいろ

#はじめに
Paizaのスキルチェックをやっていると必ず使用する、「input関数」についてまとめてみました。
いろいろな使い方があるので、どのように使い分けるか確認したいときに見てください。

#Paizaのスキルチェックの使い方
本文に入る前に、スキルチェックの問題を解く前にすることを書いておきます。
僕は最初問題を解く前にする作業を知らず、３０分くらいコードが打ち込めないことで格闘していました。
初めてスキルチェックを解く方の助けになれば幸いです。

①まず[Paiza_スキルチェック](https://paiza.jp/challenges)をクリックして、Paizaのスキルチェックまで飛びましょう。
②左の各ランクの問題一覧から好きなものを選んでクリックしてください。（Dが一番優しく、Sがおに難かしくなってます）
③その後一覧から好きな問題を選び、「チャレンジする」を押します。
④そうすると確認画面が出るので、「問題にチャレンジする」を押します。
⑤そうする上から順に
-「問題文」
-「評価ポイント」 : 点数について
-「入力される値」　：　inputで持ってこれる値の説明
-「期待する出力」　：　出力して欲しいものの説明
-「条件」　：　数値の下限、上限
-「入力される値」で説明されている具体的な入力例と「期待 する出力」で説明されている具体的な出力例
-「解答欄」　：　実際のコードを書く場所
となってい流ので全てに目を通して理解しておきます。
⑥解答欄の右上の「使用する言語」から自分が使用する言語を選んでください。そうするとコードが書けるようになります。ここまでが下準備なので、ここからは各自問題を解いていってください。

#「input」とは
そもそも「input」って何と思う方もいらっしゃると思います。

「input」とは、キーボードに入力したデータを受け取るものです。Paizaのスキルチェックで入力例と書かれている部分にあるものを「input」を使うことで受け取ることができます。「print」が出力なので、その逆と考えてもらうとわかりやすいかもしれないです。

#「input」の基本的な使い方
「input」の基本的な使い方を紹介します。

```
>>>変数名 = input()
#入力を求められる
>>>print(変数名)
#入力したものが出力される
```
このように入力されたものを受け取ることができます。
最初どこに入力して良いのかわかりづらいですが、大体は次の行に入力すれば受け取ってくれます。
下記のように「input」の中に入力して欲しいものを指示する文章を書くことができます。

```
>>>変数名 = input('入力して欲しいものの指示:')
```
paizaでは上記のように入力することで、入力例に書かれているものを引っ張ってこれます。
また、入力したものは文字列として受け取ります。
つまり、「１」と入力しても「'1'」となるということです。

```
>>>number = input()
1
>>>number
'1'
>>>int(number)
1
```
このようにすることで、文字列型から数字に変換することができます。

#複数の値を受け取る
基本的な使い方では１つの値しか受け取れません。
では複数の値を受け取るにはどうしたら良いのでしょうか？

```
>>>a,b=input().split()
one two
>>>a
one
>>>b
two
```
このようにすると、「a」には「one」、「b」には「two」が入るようになります。
もちろん「a,b,c,d...」と受け取れる数を増やすことはできますが、あまり長くなりすぎると見にくくなるので気をつけてください。

###数字として受け取る

そして今回も受け取った時は文字列ですので、数字として受け取りたい場合は「int」を使うと良いです。

```
>>>a,b=input().split()
1 2
>>>a
'1'
>>>b
'2'
>>>int(a)
1
>>>int(b)
2
```
でも数字にするのに３行必要だと少しめんどくさいですよね。
そんな時は「リスト内包表記」を使いましょう。

#リスト内包表記で複数の値を受け取る
言葉だけ聞くと難しいかもしれないですが、順番に説明していきます。

```
>>>a,b=[int(x) for x in input().split()]
1 2
>>>a
1
>>>b
2
```
①まずfor文で「input().split()]」にリストとして入っている要素を一つずつ取り出します。
②その取り出した要素は「x」に入り、その「x」に対して「int」で数字に直す処理をします。（後ろから見て良いくと理解しやすいです）
③最後に数字に直したものを「a」や「b」に入れていきます。
さっきまで３行で書いていたものがたったの１行で書けるのは魅力的ですよね。

別のやり方もあるので紹介しておきます。
###ちょっと違うバージョン

```
>>>N = int(input())
#入力回数を指定
>>>a,b = [int(input()) for i in range(N)]
1
2
>>>a
1
>>>b
2
```
まず入力回数を指定してもらい、その回数分for文を回します。その後「int(input())」で１行ずつ要素を受け取り、１つずつ数字にして「a」や「b」に入れていきます。
１つ前の物との違いは横に「１行に複数の値があるのか」、「複数行に１つずつ値があるのか」です。

###map関数を使う

```
>>>a,b=map(int,input().split())
1 2
>>>a
1
>>>b
2
```
「map関数」とは、第２引数（input().split()）に変更対象をかき、それを第１引数(int)によって加工します。
こっちの方がより短いので使いやすいかもしれません。

#最後に
今回は「input」についてまとめました。
Paizaのスキルチェックでは必須の知識になるので、覚えておいて損はないです。
どんどん活用していきましょう。
Windows10上の仮想マシンが起動しないときの対処方法

# はじめに
去年Windows上で、仮想マシンを起動しようとした時のこと、あるエラーが発生した.
それについての記事を上げるも、詳しい情報を返すことなく放置すること１年以上.
Dockerの勉強をしようとしたら、当然のようにまた同じエラーにぶつかった.


 **今年は魔法のような修正方法が出てるのでそれを紹介します！！**

ちなみにこれが、[前回の記事](https://qiita.com/reef1217/items/e760b6e4078dedc0b434)

# 環境
- Windows10 Pro 1909 buid 1863...
    - 後に、Windows10 Pro 2004 buid 1904...
- VMware Player 14
    - 後に、VMware Player 15.5.5へ
- 仮想マシン(CentOS 6)

# エラーの内容
``` 
VMware Player と Device/Credential Guard には互換性がありません。
VMware Player は Device/Credential Guard を無効にした後で実行することができます。
詳細については、http://www.vmware.com/go/turnoff_CG_DG を参照してください。
```
![error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316424/0622ad52-a5d5-28f6-59c1-95e75cc9219a.png)

- VMwareで仮想マシンを起動するには Dvice/Credential Guard を無効にしなきゃいけないらしい

 詳細についてのリンク先には英語でめっちゃかいてある.
 日本語訳で対処されてる方々もいるけど、総じて新しいドライブか新規パーティションを作成しなきゃいけないらしい.
 え、そんなんめっちゃやなんだけど.

# 解決手段
[VMware Player 15.5.5](https://www.vmware.com/jp/products/workstation-player/workstation-player-evaluation.html)

> 米VMwareは5月28日（現地時間）、パーソナルデスクトップ向けの仮想化ソリューション「VMware Workstation 15.5.5」「VMware Workstation Player 15.5.5」をリリースした。本バージョンの目玉は、「Hyper-V」との共存が可能になったこと。

**まじ！？**

すぐに鵜呑みにするタイプなので、すぐに上記ソフトをインストールした

![error2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316424/29f30aca-196f-7b7f-23a6-939da676d9cb.png)

また、すぐには治らないやつ.
かとおもったら、

> なお、VBSが有効化されたホストで「VMware Workstation」「VMware Workstation Player」を利用するには、OSを「Windows 10 May 2020 Update（バージョン 2004）」へアップグレードする必要がある。また、CPU要件としてIntel製の場合“Sandy Bridge”もしくはそれ以降、AMD製の場合“Bulldozer”もしくはそれ以降のアーキテクチャーが指定されているので注意

そうなのね！
ということで、こちらもすぐにダウンロードしてこよう！！

前回のアプデ同様に、順次インストールされるらしいけど、手動でやりたい！
[Windows 10 May 2020 Update](https://www.microsoft.com/ja-jp/software-download/windows10)

結構時間かかったけど、無事インストールが終わって再起動した！

Windowsの機能から、WSLやHyper-Vなどいままで使えなかった機能を全部チェック！！

再起動！！

VMware Player 15.5.5を起動して仮想マシンを起動してみたら、、

![centos6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316424/71fede98-7581-8da4-a260-cc6bf107af6c.png)

起動した！！
完了！！！

# あとがき？

VMware15.5.5は、microsoft社とvmwareが協力して作ったAPIを活用してるらしい.

DockerからUbuntsuも起動できたし、今のところ問題はなさそう.

VirtualBoxは試してないけど、記事曰く、今後もこのAPIへの準拠を促していくので、対応してないソフトも順次対応しだすのかなぁと.

にしても、使える環境を整えるだけでこんなめんどくさいのか…さすが開発最難関、環境整備だわ
【Laravelで個人開発】ユーザー認証系の機能を導入する

# はじめに
このドキュメントは、Laravel初心者の方が、ユーザー登録、ログインを必要とするサービスを作るために、Laravelから標準的に提供されているパッケージを用いてサクッと実装することをゴールに定め書いています。

# ゴールの具体的な状態
- 以下の機能を提供できる
    - 会員登録
    - ログイン/ログアウト
    - パスワードリマインダー
- 上記機能における各種メッセージが日本語で提供される

# インストールするソフトウェア・パッケージ
今回は、`laravel/ui`を導入するのみです。最新のバージョンは2.xですが、今回インストールしたLaravelのバージョンは6.xなので、1.xを指定してインストールします。

# 導入手順
vesselを用いた環境で作業を進めます。

## 1. `laravel/ui`のインストール

```bash
./vessel comp require laravel/ui "^1.0" --dev
composer require laravel/ui "^1.0" --dev
```

## 2. 認証機能のセットアップ
```bash
# 認証用のスキャフォールド生成
./vessel art ui vue --auth
php artisan ui vue --auth

# マイグレーション
./vessel art migrate
php artisan migrate
```

## 3. ローカライズ設定
```config/app.php
# タイムゾーンを以下の値に変更
'timezone' => 'Asia/Tokyo',

# ロケールを以下の値に変更
'locale' => 'ja',

# fakerロケールを以下の値に変更(テストデータを作るときに必須の設定)
'faker_locale' => 'ja_JP',
```

## 4. 言語ファイルの追加
プロジェクトのルートディレクトリに移動して以下を実行します。成功すれば、 `resources/lang/ja` というディレクトリが新たに作成されています。

```bash
php -r "copy('https://readouble.com/laravel/6.x/ja/install-ja-lang-files.php', 'install-ja-lang.php');"
php -f install-ja-lang.php
php -r "unlink('install-ja-lang.php');"
```
## 7. テストデータのセットアップ
下記のファイルのコメントアウトを解除し、UserTableSeederを作リます。これにより、認証用のユーザーテーブルに、テストデータを作成することができるようになります。

```databese/seeds/DatabaseSeeder.php
    public function run()
    {
        // $this->call(UsersTableSeeder::class);
        $this->call(UsersTableSeeder::class);
    }
```

以下は内容をそのままコピペします。

```databese/seeds/UsersTableSeeder.php
<?php

use Illuminate\Database\Seeder;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(App\User::class, 30)->create();
    }
}
```
新しいクラスを追加したのでdump-autoloadを実行する

```bash
./vessel comp dump-autoload
```

## 7. テストデータを作成する
seedコマンドで、usersテーブルにテストデータを作成します。

```bash
./vessel art db:seed

# mysqlコンテナにアクセスする
./vessel mysql

# usersテーブルをカウントする(30件入っているはず)
select count(*) from users;
```

## 8. 画面を確認する
localhostにアクセスするとトップページに認証用のメニューが追加されています。
![Laravel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111432/b9e2953b-1044-4b3b-344d-ff92709b5507.png)

また、そのメニューからログイン画面に遷移し、適当な文字列を入力してログインを試みると、日本語でエラーメッセージが出力されます。
![validate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111432/8096a110-d81e-baf6-1f1a-f0df651a31c4.png)
【Swift】 基本構文

## 変数の宣言

```swift:Variable.swift
 // 型も宣言する場合
 var 変数名:型 = 値
 var age: Int = 20
 
 // 型推論が行われる場合
 var 変数名 = 値
 var age = 20
 
 // 値を入れない（初期値nil）場合(オプショナル型）
 var 変数名: 型!
 var age: Int!
```


## 定数の宣言

```swift:Constant.swift
 // 型も宣言する場合
 let 変数名:型 = 値
 let age: Int = 20
 
 // 型推論が行われる場合
 let 変数名 = 値
 let age = 20
 
 // 値を入れない（初期値nil）場合(オプショナル型）
 let 変数名: 型!
 let age: Int!
```

## メソッドの定義

```swift:Method.swift
 func メソッド名(第一引数名: 型, 第2引数名: 型) -> 戻り値の型{
     return num1 + num2
 }
 
 func plus(num1: Int, num2: Int) -> Int {
 	return num1 + num2
 }
```
PropsとStateの違い

Reactを学習していて、PropsとStateの違いってなんやろ
とふとした時に思い調べました。

学習メモなのでふわっとしていますが、どうぞよしなに。

*間違いがあれば教えていただけると、ありがたいです。

【Propsとは】
・オブジェクト
・親コンポーネントからもらう値
・Propsを受け取る側の子コンポーネントではPropsを変化させれない
・親コンポーネントから変化させられる

【Stateとは】
・オブジェクト
・コンポーネント自身で定義する
・初期値を設定したらsetStateでStateの値を変更する

<まとめ>

Props→上から下に流れるデータ
State→コンポーネント自身が持つデータ
Linux育ちの人間がWindowsでターミナルを使う道

# これはなに
Unixコマンドじゃないとやだと駄々をこねる人間がWindowsで生きるために試行錯誤してWSLとかWindowsTerminalとかchocoとかに救命してもらうお話
内容はないよ
## 今までのWindowsのターミナル事情をおさらいしよう
### CMD.exe
- 見た目のカスタマイズに弱いイメージ
- 公式的には手放したいのにできなくて放置だったはず(Win7くらいの時)なのに最近いろいろ改善された
- これ自体に罪はない（はず）

### powershell.exe
- 諸悪の根源（？）
- スクリプトなのはすごくいいし.Netのオブジェクトとかも叩きやすい
- コマンドレット長すぎ問題にぶちあたる
- 方式が違いすぎてこれでCMD置き換えるのは無理だと思う
- これ自体はいいツールで罪はない(ISEとか付属するし)

### Cygwin
- Unixライクなコマンド使おうとすると一度は通るやつ
- 全部がCygwinのdllにつながってるのがちょっと...
-  POSIX完全再現を目指しすぎてて重い
-  最近は嫌がられるイメージ

### MSYS2
- もとはCygwin
- だけど最近はこっちがおおいイメージ
- 多分MinGWと一緒に使われるからだと思う（確証なし）
- もとはCygwinなのでこれでビルドしたのはMSYSでしか動かない

### MinGW
- UnixツールをWindowsネイティブにしましょうプロジェクト(あまり正確ではない)
- クロスコンパイル環境にはほぼ必須
- Terminalかって言われるとそうでもない

## 今のターミナル事情はすごい！
久しぶりに戻ったWindowsのターミナル事情が変わりすぎてまじでびっくりした
### Windows Subsystem for Linux (WSL)
<b>こいつやばい</b>
昔あった（今もあるかも）coLinuxみたいな感覚で起動できて(仕組みは全然違うけど)、公式のサポートがついて、多くの人が使ってる（<b><font color="red">最重要</font></b>）
X11もいれるとWindowsにGNOME Terminalを起動することができる
セットアップはそこらへんに転がってるので検索してLGTMに入れましょう
### Git Bash
MinGW+MSYS2だけどGitにくっついてくるのでなんだかんだ使いやすい
ほぼBashのためだけにいれた
chocoで入れるときはオプション打たないとコマンドラインツールはいらないので気を付けよう

### Windows Terminal
<b>なにこれ</b>
複数Shell同時に動かせるし、タブもあるし分割もできるし、カスタムがJSONだし、Macのデフォターミナルの5000倍くらいいいと思う（個人的感想）
MSStoreからいれよう
### Chocolatey
MacでいうHomeBrew、Debianでいうapt、Fedoraでいうyum
パッケージ管理ツールが成熟して私はうれしいですわよ
いろいろ突っ込みすぎてなにいれたか忘れた
インストール方法:

 ```
 Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
 ```
### これらを混ぜ合わせると
![wsl.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572200/ed854fb2-1a78-fb87-18c9-c9d2807515f7.png)
![wsl2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572200/2d086da0-ca92-25b5-ec12-4f1a402d3e2d.png) 
これがWindowsですか...
【Swift】UIButtonを画像付きのテキストにする

テキストの横に画像のあるボタンを作成したい場面に出会ったことのある人は結構いると思います。
そんな時`UIImage`と`UILabel`を組み合わせなくても`UIButton`のみで作ることができます。

- R.swiftを使っています
- 表示する画像はこちらのイカちゃん

![iks.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305854/daa11581-349f-529f-ac25-fedf21649e4f.png)

完成はこんな感じです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305854/a6094d51-888d-530b-d313-35199ebe8ef0.png" width=50%>


#### UIButtonに画像とテキストを設定する
```swift
leftImageButton.setTitle("左側アイコン", for: .normal)
leftImageButton.setImage(R.image.ika(), for: .normal)
```

#### titleEdgeInsets・imageEdgeInsetsを使います
`EdgeInsets`は余白の設定ができます。
それぞれ最適に余白の設定をすることで、ボタンとテキストをいい感じに表示させることができます。
初期値は`titleEdgeInsets`も`imageEdgeInsets`も`(top: 0, left: 0, bottom: 0, right: 0)`なので、画像とテキストを同時に設定すると被って表示されます。

#### テキストの左に画像を付ける
テキストの左側に余白を設定します。画像の`width`を元に設定するのが良いと思います。


```swift
leftImageButton.titleEdgeInsets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 0)
```

#### テキストの右に画像を付ける
画像を右側に持っていく為に左側にテキストの長さ分の余白を設定します。こちらも固定値を設定していますが、テキストの長さから設定した方が良いと思います。
またテキストの位置も調整したいので、テキストの余白も設定します。

```swift
rightImageButton.imageEdgeInsets = UIEdgeInsets(top: 0, left: 200, bottom: 0, right: 0)
rightImageButton.titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 20)
```

仕組みがわかれば同じ要領でテキストの上側に画像を設定したり、下に画像を設定したりできます。
#### テキストの上に画像を付ける

```swift
topImageButton.imageEdgeInsets = UIEdgeInsets(top: 0, left: 100, bottom: 20, right: 0)
topImageButton.titleEdgeInsets = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)
```

#### テキストの下に画像を付ける

```swift
bottomImageButton.imageEdgeInsets = UIEdgeInsets(top: 25, left: 100, bottom: 0, right: 0)
bottomImageButton.titleEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 20, right: 0)
```

以上です。
仕組みを理解すれば簡単にちょっと凝ったボタンを作成することができてとても便利です。

###### 関連
[【Swift】UIButtonにimageをセットしたが表示されない件](https://qiita.com/_asa08_/items/c94bb1a8746f07e8933a)
【yarn】エラー　「/bin/sh: webpack-dev-server: command not found error Command failed with exit code 127.」


#はじめに
急に`yarn run dev`が通らなくなり、

```shell
yarn run v1.21.1
$ webpack-dev-server
/bin/sh: webpack-dev-server: command not found
error Command failed with exit code 127.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
```
というエラーが出るようになった。


#対処

```shell
 $ yarn add yarn
```
これで問題なく通るようになりました！


`yarn install`は試したが駄目でした。


###終わりに。
最後まで読んで頂きありがとうございます:bow_tone1:
転職の為、未経験の状態からReact,Railsを学習しております。正しい知識を着実に身に着け、実力のあるエンジニアになりたいと考えています。継続して投稿していく中で、その為のインプットも必然的に増え、成長に繋がるかと考えています。
今現在、初心者だからといって言い訳はできないですが、投稿の内容に間違っているところや、付け加えるべきところが多々あるかと思いますので、ご指摘頂けると幸いです。この記事を読んで下さりありがとうございました。
SwiftUIでナビゲーションバーの中央にロゴ画像を配置する方法

最近SwiftUIを触り始めて、巷でよく見るNavigationBarの中央にロゴ画像を配置する実装をしようとしたところ、少しつまづいたので、備忘録がわりに書きます。

最終的にSwiftUIで以下の画像の様な状態を目指します。
<img width="327" alt="スクリーンショット 2020-06-24 20.40.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152335/b8b5515c-7935-a5cf-875d-cafecaa776c8.png">

#UIKit
まずは、UIKitでナビゲーションバーで中央に画像を配置する場合はUIViewControllerのnavigationItemが持つ`titleView`というプロパティにUIImageViewを設定することで、表示することができます。

```swift
import UIKit

class ViewController: UIViewController {

    func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.titleView = UIImageView(image: UIImage(named: "logo"))
    }
}
```

#SwiftUI
SwiftUIで同じことをやろうとした場合、NavigationViewのタイトルの文字列を設定する関数は存在するのですが、どうやらUIKitでのtitleViewにあたる、ナビゲーションバーの中央にViewを配置する関数というのは存在しない様です。

```swift
import SwiftUI 

struct SwiftUIView: View {

    var body: some View {
        NavigationView {
            Text("Hello World")
                .navigationBarTitle("App Name", displayMode: .inline) 
                // 文字列は設定できるが、Imageは設定できない😱
        }
    }
}
```

<img width="380" alt="スクリーンショット 2020-06-24 21.02.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152335/7e69e2c6-bdf1-501f-3f57-cb798c59045c.png">

調べてみるとナビゲーションバー左右にViewを配置する関数を利用して、画像を配置してから、画面のサイズを元に中央に寄せる方法などもあったのですが、元来想定されていなさそうな使い方の様に感じたので、別の方法で試してみました。

それが以下の方法です。

```swift
import SwiftUI

struct SwiftUIView: View {

    var body: some View {
        ZStack(alignment: .top) {
            NavigationView {
                Text("Hello, World!")
                    .navigationBarTitle("", displayMode: .inline)
            }
            Image(uiImage: UIImage(named: "logo"))
                .resizable()
                .scaledToFit()
                .frame(width: nil, height: 44, alignment: .center)
        }
    }
}
```

alignmentを.topに設定した`ZStack`(Viewの重なりを設定するStack)に、NavigationViewとImageを配置することで、最前面の上部であるナビゲーションバーの中央にImageを表示する仕組みです。

この様にすると無事、UIKitと同様にNavigationBarの上部にロゴが表示されました
<img width="305" alt="スクリーンショット 2020-06-24 21.12.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152335/531b2823-29bb-30c0-4048-58d13fa59b5f.png">
EmbeddedFrameworkでCarthageを使用した際にPreviewがPotentialCrashError: Update failedになる場合の対処法

Xcode11から使用できる様になったPreview機能はSwiftUIでの開発をサポートしてくれる強力な味方ではあるのですが、特定の状況で読み込めなくなってしまうこともあり、そうなった場合は開発が滞ったりしてしまいます。

今回、EmbeddedFrameworkとCarthageを利用してSwiftUI開発している際に、Previewが読み込めなくなってハマった際の対処法を紹介します。

#環境
- Swift5.2
- Xcode11.5
- Carthage
    - Nuke(画像キャッシュ)
    - Alamofire(API通信)

プロジェクトの構成はアプリのターゲットに、`Domain`、`DataStore`、`Presentation`の三つのEmbeddedFrameworkを追加しています。
<img width="166" alt="スクリーンショット 2020-06-25 0.21.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152335/70eb540c-ad42-6cd0-3ba9-f910a1c406f9.png">

UI周りのコードは`Presentation`に全て書いているので、そのFramework内でPreviewを確認します。

#PotentialCrashError: Update failed
では、早速PresentationのFramework内に試しに書いたPreviewを見てみましょう。

```swift
struct SwiftUIView_Previews: PreviewProvider {

    static var previews: some View {
        Text("Hello, World!")
    }
}
```

![スクリーンショット 2020-06-25 0.28.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152335/8d5e1e4c-c7ce-db4b-ff46-8f0461f9fce7.png)

読み込めない😭

エラーの詳細を見てみると・・・

![スクリーンショット 2020-06-25 0.29.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152335/b9486496-47fb-c162-b78b-7b68bc634da1.png)

どうやらCarthageで導入しているNukeが読み込めないがためにPreviewが表示されないようです。

![スクリーンショット 2020-06-25 0.37.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152335/b8e7a7bf-fad6-0e6f-c391-21f21c8222ef.png)

しかしシミュレーターのビルドは通っているので、ちゃんとCarthageで導入したFrameworkの参照はうまくいってるはず🤔

#解決法

色々と調べていると、PreviewからFrameworkの参照するためのパスの設定はBuild Settingの`Framework Search Paths`ではなく`Runpath Search Paths`から行われているようです。

![スクリーンショット 2020-06-25 0.48.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152335/698093e2-bbc6-0f75-0e69-9be3dd6050bc.png)

そうと分かれば、以下の画像のように`Runpath Search Path`に、新たに`Framework Search Paths`に入力されている`$(PROJECT_DIR)/Carthage/Build/iOS`を追加してあげれば、Preview時にCarthageで導入したFrameworkも参照できるようになりそうです。

<img width="759" alt="スクリーンショット 2020-06-25 0.51.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152335/29048819-953c-540d-7418-b9cb6c4c2eb3.png">


この状態でPreviewを確認すると・・・

![スクリーンショット 2020-06-25 0.56.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152335/f46fd2f6-b28d-fbbd-6616-d9785a0d1d48.png)

ちゃんと表示された！😂

#最後に
以上がEmbeddedFrameworkにCarthageで導入したFramework際にPreviewが表示されない場合の対処法でした。

この記事によって、誰かが私のようにこの問題を修正するために、EmbeddedFramework化を諦めそうになったり、休日の大事な時間を無駄にしたりしないことを祈ります🙏
ストレステスト用のstress-ngコマンドにREST風I/Fつけてコンテナにしてサクッと呼べるようにしてみた

# 概要

このエントリでは、OSでストレステストを実施するためのコマンド[stress-ng](https://wiki.ubuntu.com/Kernel/Reference/stress-ng)をREST風I/Fから呼べるようにしてみたことを紹介します。

ちょっとしたストレステストを掛けたいときに、ターミナルからstressやstress-ngをコマンドとして使っていたのですが、REST風に叩けるようにすると、kubernetesクラスタなどでちょっとした負荷をかけるときにも便利なのでは、と思い作ってみたものです。

## 想定読者

- stress, stress-ngといった、ストレスツールをWEBのインターフェースから呼び出したい方
- ネタが好きな方

# TL;DR; 動かし方

手元でコンテナを動かすとき、例えば以下のようにします。
ローカルマシンで、8080ポートにREST風インターフェースができます。

```console
sudo docker run --rm -p 8080:8080 hrkt/stresst:0.1.0
```

叩いてみます。ブラウザからでもcurl等のコマンドからでもよいです。
(REST風インターフェースには、別エントリで紹介した[REST風にコマンドを呼び出せる(例えばhttp://localhost/bin/date　な)command-as-a-serviceのコンテナを作ってみた](https://qiita.com/hrkt/items/faaddc27c02dbea828c8)をそのまま使っています。)

```console
curl "http://localhost:8080/usr/bin/stress-ng?--cpu&1&-l&50&-t&15s"
```

OSでtopコマンド等で状況を確認すると、下記のように負荷がかかっています。

```
top - 07:09:32 up 59 min,  2 users,  load average: 1.08, 0.43, 0.59
Tasks: 228 total,   1 running, 227 sleeping,   0 stopped,   0 zombie
%Cpu(s): 41.3 us,  8.8 sy,  0.0 ni, 49.7 id,  0.0 wa,  0.0 hi,  0.2 si,  0.0 st
MiB Mem :   5958.4 total,    205.0 free,   2241.6 used,   3511.8 buff/cache
MiB Swap:   2048.0 total,   2046.7 free,      1.3 used.   3247.4 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 8758 root      20   0   18316   4676   1756 S  43.9   0.1   0:02.03 stress-ng-cpu
 4795 hiroki    20   0 3717964 465576 212860 S  20.9   7.6   4:54.82 firefox
```



# おわりに

このエントリでは、ストレステスト用のコマンドstress-ngに、WEBのインターフェースをつけて呼べるようにしてみました。
例に挙げた以外にも、stress-ngは、メモリ、ディスクへの負荷など、多彩な設定が可能です。


## 関連リポジトリ

- DockerHub: [https://hub.docker.com/repository/docker/hrkt/stresst](https://hub.docker.com/repository/docker/hrkt/stresst)
- GitHub: [https://github.com/hrkt/stresst](https://github.com/hrkt/stresst)
Fetch APIでPHPにデータを送信する方法

画面遷移をせず、ajaxでデータをPHPに渡す方法です。

下記は「ボタンをクリックした時にPHPにデータを渡す」処理についてのサンプルです。

## Javascript

`id="start"`のボタンがあるとします。

```HTML:index.html
<div class="Container">
   <button class="btn" id="start">start</button>
</div>
```
vanilla Javascriptでは、下記のように記述します。

```javascript:main.js
start.addEventListener('click', () => {
        const postData = new FormData; // フォーム方式で送る場合
        postData.set('firstName', 'hoge'); // set()で格納する
        postData.set('lastName', 'fuga');
      
        const data = {
          method: 'POST',
          body: postData
        };
      
        fetch('test.php', data)
          .then((res) => res.text())
          .then(console.log);
    });
```
## PHP

PHP側で、$_POST連想配列に値が保存されます。

```php:test.php
<?php
echo $_POST['firstName']; // hoge
```

未対応の古いブラウザでも`Polyfill`を使用することで、従来の`XMLHttpRequest`を使った処理を`fetch`に置き換えることができます。

## jQuery

ちなみに`jQUery`にも`ajax`で`POST`できる構文があります。

```javascript:test.js
 $.post( "ajax/test.html", function( data ) {
  $( ".result" ).html( data );
 });
```
プロジェクトによってはこちらを使用する事もあるかもしれません。

## 参考
[github/fetch](https://github.com/github/fetch)
[MDN/Fetch API](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API)
[MDN/Promise](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)
[jQuery.post()](https://api.jquery.com/jQuery.post/#jQuery-post-url-data-success-dataType)
matlabでBLEを使う③

　toioにはモータ（車輪）が二つ付いています。[資料から](https://toio.github.io/toio-spec/docs/ble_motor)、基本的な動きを確認します。
# モータの仕様
　モータにはIDが振られています。それぞれのIDに対して、回転方向と速度を指示します。

|データ位置	|タイプ	|内容	|例|
|:------|-------------|------------------:|:------------------:|
|0	|UInt8	|制御の種類	|0x01（モータ制御）|
|1	|UInt8	|制御するモータの ID	|0x01（左）|
|2	|UInt8	|モータの回転方向	|0x01（前）|
|3	|UInt8	|モータの速度指示値	|0x64（100）|
|4	|UInt8	|制御するモータの ID	|0x02（右）|
|5	|UInt8	|モータの回転方向	|0x02（後ろ）|
|6	|UInt8	|モータの速度指示値	|0x14（20）|

# 回転テスト
　上記の制御をmessage_move、速度を0としたmessage_stop、逆方向への移動をmessage_moveRとし、3回連続で実行します。message_move自体は、その場で片方の車輪を軸としてぐるぐる回る動作です。

```matlab
clear
list = blelist("Timeout", 10);
toio_address = "C3F086EFC762"
b = ble(toio_address);
% bb = b.Characteristics;

Cube_ServiceUUID = "10B20100-5B3B-4571-9508-CF3EFCD7BBAE"
Motor_CharacteristicUUID = "10B20102-5B3B-4571-9508-CF3EFCD7BBAE"
message_move  = [0x01,0x01,0x01,0x64,0x02,0x02,0x14]
message_stop  = [0x01,0x01,0x01,0x0,0x02,0x02,0x0]
message_moveR = [0x01,0x01,0x02,0x14,0x02,0x01,0x64]

for i = 1:3
    c = characteristic(b, Cube_ServiceUUID, Motor_CharacteristicUUID);
    write(c, message_move) 
    pause(1)
    write(c, message_stop) 
    pause(0.5)
    write(c, message_moveR) 
    pause(1)
end

clear b  % disconnect
```

　実行した様子です。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"> <a href="https://t.co/mppaJHSk98">pic.twitter.com/mppaJHSk98</a></p>&mdash; <a href="https://twitter.com/DenshiClub/status/1275597151184187392?ref_src=twsrc%5Etfw">June 24, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
(自分用)Flask_8(pythonでデータベース内の追記/編集/削除)

# 項目
1. データベースの簡単なおさらい
2. データベース内に追記
3. データベース内の編集
4. データベース内の削除

# 1.簡単なおさらい
```python:python
from flask import Flask, render_template
import pymysql
app = Flask(__name__)

def getConnection():
    return pymysql.connect(
        host='localhost',
        db='mydb',
        user='root',
        password='',
        charset='utf8',
        cursorclass=pymysql.cursors.DictCursor
    )

@app.route('/')
def select_sql():
  
    connection = getConnection()
    message = "Hello world"

    sql = "SELECT * FROM players"
    cursor = connection.cursor()
    cursor.execute(sql)
    players = cursor.fetchall()

    cursor.close()
    connection.close()

    return render_template('view.html', message = message, players = players)
```
- `pymysql`で編集するよと宣言し
- `.connect()`で編集するデータベース情報を選択
- `def select_sql`で選択したデータベースにSQLコマンドを入力

# 2.データベース内の追記
```python:python
@app.route('/')
def select_sql():
  
    connection = getConnection()
    message = "Hello world"

    cursor = connection.cursor()

    sql = "INSERT INTO players (name, level, job_id) VALUES ('霧島1号', 1, 1)"
    cursor.execute(sql)
    connection.commit()

    sql = "SELECT * FROM players"
    cursor.execute(sql)
    players = cursor.fetchall()

    cursor.close()
    connection.close()

    return render_template('view.html', message = message, players = players)
```
- 基本は同じ
- `cursor`を参照できる様に、先に`cursor = connection.cursor()`しといた方がいい
- `sql = "INSERT INTO players (name, level, job_id) VALUES ('霧島1号', 1, 1)"`で、`INSERT INTO <table名>`でtableを選択し、編集したいカラムを選択後、`VALUES ('霧島1号', 1, 1)`で選択したカラムにデータを追加する。<br>カラムと順番と追記データの順番は要連動
- `connection.commit()`でデータベースにSQLコマンドを実行?している

# 3.データベース内の編集
```python:python
    sql = "UPDATE players SET level = 10 WHERE id = 12"
    cursor.execute(sql)
    connection.commit()
```
- さっきの`INSERT`の所をこれで置き換える
- `UPDATE <table名>`で編集したいtableを選択`SET level=10`で選択したlevelカラムの値を10に変更すると選択し指示し、`WHERE id = 12`でlevelカラムの中のどのデータが編集されるかを選択する

# 4.データベース内の削除
```python:python
    sql = "DELETE FROM players WHERE id = 12"
    cursor.execute(sql)
    connection.commit()
```
- 基本同じ
- `DELETE FROM players`でplayersテーブルから消しますよと宣言し
- `WHERE id = 12`「何を?」「idが12の奴を」とやっている

# 5.終わりに
- 今日もあんまり出来んかった
- 一回1日ぐらい休んだ方がいいかもしれない
マカフィーのフルスキャンが20時間近く経っても終わらなかった話

McAfee VirusScan Enterpriseの話です。

ゴールはこの画面が表示されることです。
![McAfeeVirusScan Enterprise.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223785/b3b67b3c-8a80-d580-62e6-6a51bbe12878.png)
<h3>```【事象】20時間近く経ってもフルスキャンが終わらない```:scream:</h3>

```前提条件.
 1.とある23日の18時、ウイルススキャンを起動。開始、約30分は画面を開いたまま動作確認。
　 その後、ノートPCの画面を閉じた。
　 →フルスキャンの実行漏れではない。

 2.Cドライブ直下（C:\Program Files\）は最低限のデータ量にしてからフルスキャンを実行。
　　→データ量の過多が原因ではない。
　　例）1ファイル１５GBのデータ等がない事、確認済み。
```

```仮説.
   そもそも20時間近く、ぶっ通しでノートPCは動いていたか（イベントログの）確認をする必要がある。
```
<blockquote>
<p>イベントログとは<br>
［目的］Windowsシステム内やアプリケーションなど、発生したイベントを記録、<br>
　　　　 後のメンテナンスなどに利用するもの。</p>
</blockquote>

**イベント ビューアーの出し方**
Windowsキーを押下後、「イベント」で検索すると「イベント ビューアー」が現れます。
![イベントビューア.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223785/c88cc106-fec9-fc3c-f191-3da21f2c1075.png)

```結果.
   「システムがスリープ状態になります」と断言し、私より早くノートPCは就寝していました(苦笑)

   ［補足］24日7時12分は私がノートPCに電源を入れた時間です（苦笑） 
```

納品先から借りている端末のため、設定を変更することもできず…

```対応策.
   「手動で22時に電源を入れること」です。
```

どなたかの参考になれば幸いです。
functools.partial

#クロージャーと同じようなことができます

```py
import functools


def f(x, y):
    return x + y


def task(f):
    print('start')
    print(f())


# def outer(x, y):
#     def inner():
#         return x + y
#     return inner


# f = outer(10,20)
p = functools.partial(f, 10, 20)
# task(f)
task(p)  
```
実行結果：

```txt
start
30
```
GitHub CLIでプルリクレビューを少し楽にする

[GitHub CLI](https://cli.github.com/) ご存知ですか？

私はこの前存在を知りました。
まだ現時点でベータ版ですが、なかなかに便利なので、ほぼ毎日利用しています。

プルリクエスト上で、レビューを行うチームであれば、一度使ってみてもいいと思います。

今回は、

- 人のプルリクをレビューする場合
- 自分がプルリクを出す場合

にわけて、実際にやるであろう流れで書いていこうと思います。


# まずインストール

macの場合は、brewでインストールするだけです。

```
$ brew install github/gh/gh
```

他OSは、[環境別のインストール手順](https://github.com/cli/cli#installation)を参考にしてください。


# 人のプルリクをレビューする場合

だれかから、何かしらの手段で、プルリクのレビュー依頼が飛んでくるかと思います。(slack通知や、声かけられたなど)
まず今出ているプルリクの一覧を確認してみます。
以下のコマンドで、ステータスが `open` なプルリクが確認できます。

```
$ gh pr list

Showing 1 of 1 pull request in TARO-YAMADA/gitcli-sample

#2  Add Fuga module  feature/add_fuga_module
#1  Add Hoge         feature/add_hoge
```

プルリクの内容を知りたいので、確認してみます。webに飛んじゃいましょう。 [^1]
以下のコマンドで該当のプルリクページがブラウザで開きます。

```
$ gh pr view 2 --web
Opening https://github.com/... in your browser.
```

プルリクの内容を確認したところで、実際に手元でビルドして動かしてみたいので、該当のブランチを落としましょう。
以下のコマンドのようにプルリク番号で指定すれば、勝手にfetchしてくれて、ブランチを切り替えてくれます。
わざわざブラウザからプルリクのブランチ名を確認、コピペして。。。などは必要ありません。

```
$ gh pr checkout 2
Switched to a new branch 'feature/add_fuga_module'
```

# 自分がプルリクを出す場合

ブランチを切って開発し、コミットまで済んだとしましょう。
以下のコマンドで、現在のブランチのプルリク作成画面をwebで開くことができます。 [^2]

```
$ gh pr create --web
```

# まとめ

いつもやってる作業が少し楽になった気がします。
スクリプトやaliasなどで、ある程度楽にしている人もいるかもしれませんが、公式の機能として提供されているので、私には安心感があります。

# おまけ(複数アカウントは無理)

```
$ gh pr list
not found
```

ん？？？
何がnot foundやねん、githubのweb上にはあるのに。
と思ってあれこれしてたら、どうやら最初にコマンドを打ったときに認証するんですが、
別のアカウントのリポジトリのプルリクを確認しようとしていたので、not foundが出ていたようです。

現状はアカウントを切り替えたり、再認証する機能がないようで、設定ファイルを消すぐらいしかなさそうです。 [^3]
リリース版で対応されることを祈りましょう。。

[^1]: ターミナル上で内容の出力もできますが、流石に描画はwebに勝てないのと、長いと全て出力されないので、あくまで概要をみるぐらいかな。
[^2]: これもオプションでtitile, bodyなどを指定してcliでプルリクを作成できるけど、自動化などの用途以外ではあまり使わなそう。
[^3]: このような[issue](https://github.com/cli/cli/issues/887)がいくつかでてる。
Swift：あるNSWindowより下層領域のスクリーンショットを取得

retina画質に対応したものが取得できる。
NSImageの幅高さとCGImageの幅高さは異なることがあるので注意。

# 下準備

```swift:NSScreenとCGImageのExtensionを用意
import AppKit
import CoreGraphics

extension NSScreen {
    var displayID: CGDirectDisplayID {
        let key = NSDeviceDescriptionKey(rawValue: "NSScreenNumber")
        return deviceDescription[key] as! CGDirectDisplayID
    }
}

extension CGImage {
    static func background(_ displayID: CGDirectDisplayID,
                           _ windowID: CGWindowID,
                           _ frame: CGRect) -> CGImage? {
        let bounds = CGDisplayBounds(displayID)
        let windowOptions: CGWindowListOption = [
            .optionOnScreenOnly,
            .optionOnScreenBelowWindow
        ]
        let imageOptions: CGWindowImageOption = [
            .bestResolution,
            .boundsIgnoreFraming
        ]
        return CGWindowListCreateImage(bounds, windowOptions, windowID, imageOptions)
    }
}
```

# 画像を取得

```swift
class CustomWindow: NSWindow {

    func getScreenShotUnderThisWindow() -> NSImage? {
        let windowID = CGWindowID(windowNumber)
        guard let screen = self.screen,
            let cgImage = CGImage.background(screen.displayID, windowID, frame)
            else { return nil }
        return NSImage(cgImage: cgImage, size: frame.size)
    }

}
```
ディープラーニングを加速！Colabで最高性能のGPUを使用する。

Google Colaboratoryで使用できるGPUにはさまざまなタイプがあります。最高性能のGPUは「Tesla P100-PCIE」です。場合によっては、このモデルは他のモデルの2倍の速度です。

1、Colabノートブックで使用されているGPUを確認します。

```shell:
！nvidia-smi
```
<img width="873" alt="スクリーンショット 2020-06-25 2.33.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/363eab65-438d-82f5-1718-c4f132727664.png">

2、GPUの名前が「Tesla P100-PCIE」でない場合は、セッションを終了し、新しいセッションに再接続します。そして、新しいGPU名を確認します。「Tesla P100-PCIE」が表示されるまでこれを繰り返します。


機械学習関連の情報を発信しています。
https://twitter.com/JackdeS11
bottleのHTTPサーバーを3分でSSL化する

# 元のコード
例えば、以下のようなソースコードがあったとして、

```python:http_server.py
from bottle import route, run

@route("/")
def root():
    return "Server running"

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

# 必要なモジュールをインストール

```bash
pip install gevent
```

# 鍵を準備
Let's Encryptでやるときはここを見ると良さそう
https://certbot.eff.org/lets-encrypt/ubuntufocal-nginx
オレオレ証明書を使うときはここ
https://qiita.com/ll_kuma_ll/items/13c962a6a74874af39c6
localhostで作りたいときはここ
https://qiita.com/rkunihiro/items/530b5dc685bd3bff2082

# コードをちょっと変える

こうする

```python:https_server.py
from bottle import route, run, ServerAdapter
from gevent.pywsgi import WSGIServer

CERT = "<公開鍵>"
KEY = "<秘密鍵>"

class SSLWebServer(ServerAdapter):
    def run(self, handler):
        srv = WSGIServer((self.host, self.port), handler,
                         certfile=CERT,
                         keyfile=KEY)
        srv.serve_forever()

@route("/")
def root():
    return "Server running"

if __name__ == '__main__':
    run(host="0.0.0.0", port=443, server=SSLWebServer)
```

Let's Encryptで鍵を用意した場合、
公開鍵は`/etc/letsencrypt/live/<ドメイン>/cert.pem`
秘密鍵は`/etc/letsencrypt/live/<ドメイン>/privkey.pem`
にある

# 注意点
UNIX系OSで1024未満のポートをバインドできるのはrootユーザーのみなので、実行するときは

```bash
sudo python3 https_server.py
```
とする必要がある
しかし、一般ユーザー権限で`pip install`した場合、モジュールは`$HOME/.local/lib/python3.8/site-packages`に格納される。そして、root権限でPythonを実行した場合、上記のパスをモジュールパスに含めないため、`ModuleNotFoundError`を起こしてしまう。
対策として、

- root権限で`pip install`し直す必要がある
- 以下のようにモジュールパスに上記パスを追加する

```python
from sys import path, version
path.append("/home/ubuntu/.local/lib/python{ver}/site-packages".format(ver=".".join(version.split(".")[:2])))
```
ReactでSemantic Uiを 使ってみる

■semantic ui react

```
yarn add semantic-ui-react
```

※フォントを変えたいのでsemantic-cssは読み込まない

LESSを読むためにcracoをインストール

```
yarn add @craco/craco @semantic-ui-react/craco-less semantic-ui-less --dev
```

Package JSONを書き換え

```
{
  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "craco eject"
  }
}
```

craco.config.jsを作成

```
module.exports = {
  plugins: [{ plugin: require('@semantic-ui-react/craco-less') }],
}
```

必要なbuildツールをインストール

```
npx @semantic-ui-react/bootstrap
```

インストールされた新しいフォルダ内にあるtheme.configの設定を変更
`src/semantic-ui/theme.config`

```

/*******************************
            Folders
*******************************/

@themesFolder : 'themes';
@siteFolder  : '../../src/semantic-ui/site';


/*******************************
         Import Theme
*******************************/

@import (multiple) "~semantic-ui-less/theme.less";
@fontPath : '../../../themes/@{theme}/assets/fonts';
```

Index.jsでimport

```
import 'semantic-ui-less/semantic.less'
```

font の変更

```
src/semantic-ui/site/globals/site.variables
@headerFont        : 'Muli', 'Noto Sans JP', sans-serif;
@pageFont          : 'Muli', 'Noto Sans JP', sans-serif;
@googleFontFamily  : 'Noto+Sans+JP:wght@300;400;700|Muli:wght@300;400;700';
```
iOSで100vhが効かない問題で、楽な方法をNuxt.jsでやってみる

iOS safariで100vhがうまくいかない時に、
`window.innerHeight`を取って各要素のstyle属性に一個一個付ける、
というのをやりがちでしたが、楽な方法が無いかと探すとカスタムプロパティが使えるそうなので、
その手順をNuxt.js版で書きます。

# mixinを作る
`--wh`という名前でカスタムプロパティを定義する。
ロード時と、リサイズ時に`window.innerHeight`を取って`--wh`に入れる。

```javascript:mixins/device.js
export default {
  data: () => ({
    style: {
      '--wh': '100vh'
    }
  }),
  mounted() {
    this.$nextTick(() => {
      this.getWindowSize()
      window.addEventListener('resize', this.getWindowSize)
    })
  },
  methods: {
    getWindowSize() {
      this.style['--wh'] = `${window.innerHeight}px`
    }
  }
}
```

# mixinを読み込む
mixinを読み込んで、styleオブジェクトをwrapper要素のstyle属性に入れる。

```html:layouts/default.vue
<template lang="pug">
.l-wrap(:style="style")
  nuxt
</template>

<script>
import deviceMixin from '~/mixins/device'

export default {
  mixins: [deviceMixin]
}
</script>
```
# カスタムプロパティを使う
heightに`var(--wh, 100vh)`と書いて、使用する。
書き方: var(設定したカスタムプロパティ名, プロパティが無い時用の初期値)

```html:pages/index.vue
<template lang="pug">
.p-top
</template>

<script>
export default {}
</script>

<style lang="stylus" scoped>
.p-top
  height var(--wh, 100vh)
</style>
```

# まとめ
これで、iOSのツールバーを考慮した実装が

1. wrapperで`window.innerHeight`取って、変数に格納する
2. wrapperかそれ以下の小要素で`height var(--wh, 100vh)`する

という形でほぼCSSで指定出来るようになりました。

IEはまだ未検証ですが、Nuxt.jsの場合は`height var(--wh, 100vh)`とすると、
`height 100vh`を自動的に手前に追加してくれるようなので、
varが認識されなくても問題なくvhできるかと思います。

```html
<style lang="stylus" scoped>
.p-top
  height 100vh
  height var(--wh, 100vh)
</style>
```

※mixinを使ったのはlayoutsが複数あるときに、各所に同じ処理を入れることになりそうで面倒だと思ったからなので、default.vueでmixinでやってる処理をそのまま書いても問題ないです。

※実際に使うときはモーダルとかのfixed系要素じゃ無い要素に使うと、iPhoneのスクロール時にがくがく高さ変わるので、リサイズが横幅のリサイズであることを判定することを検討してください。
3回まわってワン!

例えば以下のようなスクリプトを作ります。

```tcl:hello.tcl
#!/bin/sh
#-*-mode:tcl:coding:cp932;tab-width:8-*-\
	exec wish "$0" ${1+"$@"}
grid columnconfigure . 0 -weight 1
grid [label .w1 -text "Hello, world!"] -sticky we -padx 10 -pady 5
grid [button .w2 -text "Quit" -command exit] -sticky we -padx 10 -pady 5
bind .w1 <Triple-Button-1> [list console show]
```

実行すると↓こんな感じ。
![hello.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165786/5f38525b-153f-35fa-5867-904b647e0be5.png)

おもむろに「Hello, world!」を3回クリックします。すると↓こんなウィンドウ(Console)が開きます。
![console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165786/95a50fdd-d136-ce15-5767-9a0a18537feb.png)

そしてConsoleで

```tcl
.w2 configure -relief groove
```

と入力してEnterキーを叩くと、↓こんな感じにボタンの縁が変わります。
![groove.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165786/3a1d2c94-a195-b365-a275-ad6d16afdd27.png)

Consoleの右上の☓をクリックしてConsoleを閉じても、もちろんhelloウィンドウはそのままです。

こんな感じで隠しモードとしてConsoleを出せるようにしておくと、デバッグやGUIの調整のみならず、関数を直接呼び出して隠しコマンド的に使うなど、地味に便利です。

デバッグ用の使い方としては、スクリプトに

```tcl
puts "DEBUG: a=$a"
```

と書いておけば、Consoleにputsによる出力が表示されます。

まぁ別に~~3回まわって~~トリプルクリックじゃなくてもいいんですが、簡単に実装できて、それでいて誤操作でトリプルクリックになっちゃうことがほぼ無い、というのは一石二鳥です。

ちなみに標準のコンソールの代わりにTkConを使った方が便利なんですが、それはまた機会があれば紹介したいとおもいます。
Ubuntu on WSL2でVPNに接続する

# はじめに
企業や団体などで使われることの多いCisco AnyConnectですが，すべての通信をVPN側に送ってしまいます
（もしかしたら設定で変更できるかもしれませんが）
なので．VPN先のファイアウォール設定によっては必要な通信ができなくなることがあります
そこで，WSL2にAnyConnectと互換性のあるOpenconnectを入れることでVPNと通常のネットワークを共存させます

## Step by step

### Windowsのバージョンを確認する

WSL2を使うので，Windows 10 May 2020 Updateが必要です
バージョンが`2004`以降であることを確認してください
設定 -> システム -> バージョン情報 で見れます

### WSL2を有効にする
Microsoftが[インストールガイド](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)を公開しているので、従って下さい

### Ubuntuを入れる
Microsoft StoreでUbuntuと検索すれば出てくるのでインストールしてください

### Openconnectを入れる
UbuntuにOpenconnectを導入する方法は[ここ](https://websiteforstudents.com/install-openconnect-ssl-vpn-client-on-ubuntu-18-04-18-04/)にあります
要するに`$ sudo apt-get install openconnect`です

### VPNにつなぐ
`$ sudo openconnect -u ユーザ名 --passwd-on-stdin ホスト名 &`
でつながります

### スクリプトで楽をする

毎回コマンドを打つのは面倒なので，スクリプトを書きます

```bash
VPNHOST=ホスト名
VPNUSER=メールアドレス
sudo openconnect -u $VPNUSER --passwd-on-stdin $VPNHOST &
```

### もっと楽をする

パスワードを打つのも面倒です
自動化しましょう

まずは，sudoのためのパスワードをいらなくします
`$ sudo visudo`します

インストール直後ならこうなっているはずなので，

```bash
# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d
```

こうします

```bash
# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# Allow members to execute sudo command without password 書き足しています！
ユーザ名 ALL=NOPASSWD: /usr/sbin/openconnect             書き足しています！

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d
```

あとは，スクリプトをこうすれば完了です

```bash
VPNHOST=ホスト名
VPNUSER=メールアドレス
VPNPASS=パスワード
echo $VPNPASS |  sudo openconnect -u $VPNUSER --passwd-on-stdin $VPNHOST &
```
【Laravel】日本語で指定されたFakerから英語のFakerを使う

#はじめに
モデルファクトリをつかってテスト用のデータを生成する際、氏名は日本語でFakerを使いたい、でもIDとかは英語で使いたい・・・ってなった時に、コンフィグで日本語設定をしつつ、使いたいときだけ英語のFakerを使う方法です。


###標準言語設定
```php:app.php
    /*
    |--------------------------------------------------------------------------
    | Faker Locale
    |--------------------------------------------------------------------------
    |
    | This locale will be used by the Faker PHP library when generating fake
    | data for your database seeds. For example, this will be used to get
    | localized telephone numbers, street address information and more.
    |
    */
    'faker_locale' => 'ja_JP',
```


この状態でFakerを使うとこんな感じなる。

```php:Factory.php
$factory->defineAs(User::class, 'user', function (Faker $faker) {
    return [
        'login_id'     => $faker->unique()->firstName . '_' . $faker->unique()->lastName,
         //例)山口_真綾
        'firstname'    => $faker->firstName, 
         // 例)津田
        'lastname'     => $faker->lastName, 
          //例)裕樹
    ];
});


```
氏名はいいけどlogin_idは英語にしたい時

```php:Factory.php
$factory->defineAs(User::class, 'user', function (Faker $faker) {
    $faker_en = \Faker\Factory::create('en_US');
    return [
        'login_id'     => $faker_en->unique()->firstName . '_' . $faker_en->unique()->lastName,
　　　　　//例)Brannon_Donnelly
        'firstname'    => $faker->firstName,
         // 例)津田
        'lastname'     => $faker->lastName,
          //例)裕樹
    ];
});

```
configはデフォルトの言語を設定してくれるだけなので、他言語を使うときはfaker オブジェクトをインスタンス化する際に引数に指定するだけでよかった。

##調べてみて
Laravelにデフォルトでついている機能なだけあって、他にも簡単に設定ができて柔軟に対応できる機能が沢山あった。
ただLogin_idの値とfirstname,lastnameでの値が変わってくるのはどうしようもないのか・・・。
テストでのみ使うと割り切ればいいのかな。
gitコマンドでワーキングツリーがクリーンかどうか判定する

# 用語について

- **ワーキングツリー** …… リポジトリからチェックアウトされたファイルのツリー
- **クリーン** …… ワーキングツリーの内容がHEADが指すリビジョンと一致していることを表す
- **ダーティー** …… ワーキングツリー内に、コミットされていない変更が含まれていることを表す

# やり方
おそらく、可能なやり方はたくさん考えられると思いますが、ふつうはこれを使えばよさそうというやり方を紹介します。
また、シェルスクリプトなどで機械的に判定を行う上で便利なやり方を紹介します。

なお、動作確認時のgitのバージョンはv2.17.1です。

## gitで追跡されていないファイルを含めて判定する

当然 `git status` でわかるわけですが、そのままでは機械的に扱うには少々不便です。
`--short|-s` オプションを使うと出力がよりシンプルな扱いやすい形になります。

```sh:例
$ git status -s
 D bar.txt
D  baz.txt
 M foo.txt
?? new.txt
```

上の出力結果で、 `D` は削除されたものを、 `M` は差分のあるファイルを、 `??` はuntrackedな（git管理外の）ファイルを表しています。
ワーキングツリーがクリーンなときには何も表示されないところが、コマンドで判定する上で嬉しいポイントです。

従って、シェルスクリプト上では例えば次のように判定できます:

```sh:判定例
if [ $(git status --short | wc -l) -ne 0 ]; then
  # dirty!
fi
```

他のやり方としては、 `git add` コマンドを `-N|--intent-to-add` オプションを付けて実行した上で、 `git diff` コマンドを使う、といったやり方もあるようです。
こちらについては、後掲のreboooot․netさんの記事をご覧ください。

## gitで追跡されているファイルのみを対象とする

この場合、 `git status` だけでなく、 `git diff` コマンドでも判別できます。
機械的な正否判定には `git diff --quiet` が便利です。

```sh:判定例
if ! git diff --quiet; then
  # dirty!
fi
```

`--quiet` オプションを付けると一切の出力をせず、 `--exit-code` オプション同様に差分のあるときに `exit 1` してくれるので、検出が可能です。

# 参考記事

- [Chapter 11. GIT 用語集](http://img.atwikiimg.com/www8.atwiki.jp/git_jp/pub/git-manual-jp/Documentation/chunked/ch11.html)
- https://git-scm.com/docs/git-status
- https://git-scm.com/docs/git-diff
- https://git-scm.com/docs/git-describe
- [git status -s でちょっと幸せになれる - Qiita](https://qiita.com/tommy_aka_jps/items/af536a7c20747f99aa42)
- [Git での新規ファイル作成を含んだファイル変更有無の判定方法 - reboooot․net](https://reboooot.net/post/how-to-check-changes-with-git/)
- [Git その445 - ワーキングツリーがダーティーな時に出力結果にサフックスを追加して、コミットオブジェクトから到達できる最初の注釈付きのタグを表示する（git describe） - kledgeb](https://kledgeb.blogspot.com/2015/11/git-445-git-describe.html) ... こちらが使えるケースもありそうだと思いましたが、リポジトリに注釈付きタグがないと使えないという制限があるので、本文中では割愛しました。また、機械的に扱いたいときには `git diff --exit-code|--quiet` の方が便利でしょう。
PowerBI リレーションシップを作成したい列が複数ある場合の対応

覚え書きです。

#結論
- 日付の列が複数あるテーブルで、ビジュアルによって結合する列を切り替えたい場合、USERELATIONSHIPを使用する。
- まずは非アクティブなリレーションシップを作成しておく。
- 次にCALCULATE関数とUSERELATIONSHIP関数を使用してメジャーを作成する。
    - メジャー = CALCULATE(SUM([売上]),USERELATIONSHIP('t_出荷予定'[検品日],'カレンダー'[Date]))
- そのメジャーを使用したビジュアルでは、USERELATIONSHIPで設定したリレーションシップが適用され計算される。
- 最後にこの方法のデメリットと公式で推奨される対応を追記しました。


#解説
日付を扱うレポートでは、通常カレンダーテーブルを作成し[Date]列とデータテーブルの日付情報列の間でリレーションシップを作成します。
すると、カレンダーテーブルのデータを軸にして、年月ごと、曜日ごと、週ごとなど様々な軸でグラフ(ビジュアル)を作成したり、スライシングすることができます。

ただし、データテーブル内に日付情報の列が複数ある場合は、どちらか一つの列でしかレーションシップを作成できません。
複数作成しようとしても、非アクティブなリレーションシップとして点線で表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/3b738b40-da41-f1df-7777-61ff0e67a647.png)
[図1]

上記の写真では「出荷予定日」と関連付けていますが、「検品日ベースの売上」といったビジュアルを作成したい場合はどうすればいいのか。

| 出荷予定日 | 検品日    | 数量 | 単価   | 売上    |
|------------|-----------|------|--------|---------|
| 2020/6/24  | 2020/6/22 | 4    | ¥395   | ¥1,580  |
| 2020/6/24  | 2020/6/22 | 17   | ¥468   | ¥7,956  |
| 2020/6/24  | 2020/6/22 | 12   | ¥2,577 | ¥30,924 |
| 2020/6/24  | 2020/6/22 | 18   | ¥2,426 | ¥43,668 |




USERELATIONSHIP関数を使用すると解決することができるようです。
### 非アクティブなリレーションシップの作成
予め、[Date]と[検品日]でもリレーションシップを作成します。
[図1]のように非アクティブなリレーションシップになりますが問題ありません。

### メジャーの作成
以下のようにCALCULATE関数とUSERELATIONSHIP関数を使用してメジャーを作成します。
※USERELATIONSHIP関数はCALCULATE関数内でしか使用できません。

```
売上_検品日 = CALCULATE(SUM([売上]),USERELATIONSHIP('t_出荷予定'[検品日],'カレンダー'[Date]))
```

### 結果
左：[Date]と[出荷日]で結合した結果(アクティブなリレーションシップ)
右：[Date]と[検品日]で結合した結果(USERELATIONSHIPによる結合)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/d7a4e1ab-8bb5-d72c-e797-f3f49a98b26e.png)

#'21/2追記
いつの間にか公式マニュアルが充実していました。
メジャーの数が多くなる場合は、日付列ごとにカレンダーテーブルを作成するのが良さそうです。
https://docs.microsoft.com/ja-jp/power-bi/guidance/star-schema#role-playing-dimensions

###USERELATIONSHIPによる方法は以下のようなデメリットがあります
- 合計や平均といった自動メジャーが使用できない。
- 特にドリルスルー画面で勘違いしやすいです。
- ドリルスルー画面で作成した自動メジャーを使用した日付ごとの合計、カウントといったグラフは全てアクティブなリレーションシップが適用されています。
- よって、ドリルスルー画面では全てUSERELATIONSHIPでメジャーを作成する必要があります。
- 使用するメジャー2～3個程度ならUSERELATIONSHIPで問題ないと思います。
書くときにも発生する MalformedInputException


自分が書いた Java プログラムが以下のエラーを出力した。

```java
Caused by: java.nio.charset.MalformedInputException: Input length = 1
	at java.base/java.nio.charset.CoderResult.throwException(CoderResult.java:274)
	at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:306)
	at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:281)
	at java.base/sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
	at java.base/java.io.OutputStreamWriter.write(OutputStreamWriter.java:211)
	at java.base/java.io.BufferedWriter.flushBuffer(BufferedWriter.java:120)
	at java.base/java.io.BufferedWriter.flush(BufferedWriter.java:256)
（以下、アプリケーションコードのスタックトレース部分を省略）
```

文字エンコーディングに関する問題であることはすぐわかるが、次のアプリケーションコードの該当箇所を見ても理由が思い当たらない。

```java
File file = ...;
try (BufferedWriter writer = java.nio.file.Files.newBufferedWriter(file, StandardCharsets.UTF_8)) {
    String s = ...;
    writer.write(s);
    writer.flush(); // ここでエラーが出るので直前の write の引数が怪しいが...
}
```
こういうときは文字列の s をダンプして s の中身を調べるのが常套手段。

```java
System.err.println("[" + s + "]");
```
とすると、以下のように表示された。? は何だろう、文字化けか？
そもそも、`System.err#println` だとエラーが出ないのか...

```console
[?]
```
ここで [サロゲートペア](https://qiita.com/wingsys/items/81d46451d8b93ab065de) にすぐ気づかなかったのは迂闊であった。
以下のコードで s の各文字を調べると、 `High.` が表示された。最初のエラーの原因はこれだ。

```java
for (char c : s.toCharArray()) {
    if (Character.isHighSurrogate(c)) {
        System.err.println("High.");
    }
    if (Character.isLowSurrogate(c)) {
        System.err.println("Low.");
    }
}
```
2020年現在、サロゲートペアをきちんと考慮した Java プログラミングは、常識のお作法であろうか。
C#でコンソール画面で文字列出力をする際のConsole.WriteLine以外の箇所について解説します

どうも、**[臨床工学プログラマken](https://twitter.com/home?lang=ja)**です。
初投稿です。

エンジニアに転職して一年弱、身に付けた基礎知識を人に説明してより理解を深め、誰かの役に立ってくれたら幸いですし、凄腕エンジニアの方からご意見も得られたらいいなと思い、Qiitaの投稿を始めることにしました。


早速いきます。
C#で初めてコンソールアプリを動かす時、おそらく多くの人がコンソール画面に
「Hallo World！」
と出力するかと思いますが、

ただHallo World！と出力するだけなのになんかコード長くない？

と思ったことないですか？
PHPやRubyを学習したことあるなら尚更そう感じるかと思います。

今回は基礎の文字列出力するコードの細かい箇所を解説していきます。

## C#で「Hallo World！」を出力するときの細かいところを解説
以下のコードを実行することでコンソール画面に「Hallo World！」と出力する事ができます。

```C#:test_1.cs
using System;

namespace test_1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            Console.ReadKey();
        }
    }
}
```

一行目から解説していきます。

###usingについて###

```C#:test_1.cs
using System; // 名前空間の指定
```
**using**は指定した名前空間に属するクラスをクラス名だけで呼び出すことを可能にするキーワードです。
ここでは指定した名前空間である**System名前空間**に含まれるクラスを呼び出せるようにしています。

usingを使わなくても呼び出すことは可能ですが、その場合は
System.Console.WriteLine
のようにクラスを呼び出すたびに名前空間名からの記述が必要になるので、複数回呼び出すクラスがあるときは基本的にはプログラムの最初にusingで記述して、以降はクラス名だけで呼び出せるようにしてます。


###namespaceについて###
```C#:test_1.cs
namespace test_1 // 新規の名前空間の宣言
{

}
```
**namespace**は名前空間を宣言するキーワードです。
今回の例で言うと、{}で囲まれた箇所がtest_1という名前空間に属することになります。


###classについて###
```C#:test_1.cs
    class Program // クラスの宣言
    {

    }
```


**class**はクラスを宣言するキーワードです。
[]で囲まれた箇所がProgramクラスに含まれます。



###static void Main(string[] args)について###
```C#:test_1.cs
        static void Main(string[] args) // メソッドの宣言
        {
            Console.WriteLine("Hello World!");

            Console.ReadKey();
        }
```
メソッドの宣言部です。
**メソッド**は簡単に言うと、プログラムを実行するための処理をひとまとめにしたコードのブロックのことです。
{}で囲まれた中がメソッド内の処理です。

メソッドですが、プログラムの中に単独で記述して使うことはできず、**必ずクラスの中に含める必要があります。**

また、**C＃ではMain（）という名前がついたメソッドが最初に実行される決まりになっています。**


メソッドの基本的な書き方としては
アクセス修飾子 戻り値のデータ型 メソッド名（パラメーター）
のような書式で記述します。

今回のコードに当てはめると
・アクセス修飾子→なし（アクセス修飾子は省略可能、メソッドの場合アクセス修飾子を省略した時はデフォルトでprivateとなります。）

アクセス修飾子の後にstaticキーワードをつけると、静的メンバーとして扱うことになります。
staticな変数やメソッドは、インスタンスを作成してから呼び出す必要はなく、クラス名.メンバー名で呼び出すことが可能です。


・戻り値のデータ型→なし(戻り値がないメソッドの時にはvoidと記述します)


・パラメーター→string[] args

ちなみにこのstring[] argsは**コマンドライン引数**と呼ばれています。
アプリケーションを起動する際に渡されるオプションの値となります。

そしてこのMainメソッド内でConsole.WirteLineを呼び出して文字列を出力しています。
（System名前空間のConsoleという静的クラスのWirteLineメソッドを呼び出しています）

###まとめ###
以上がC#のプログラムを実行する際の基本的な構成となります。
学習を始めた最初のうちはこの辺りは気にしなくても、特に支障はありませんが、開発などをする際にはこれらの細かい要素を理解している必要があります。

今回はそれぞれ本当に簡単に解説しました。
最後まで読んでいただきありがとうございました。

ちなみに僕は趣味で個人ブログを運営しております。
前職の臨床工学技士のことや、筋トレ初心者がベンチプレス100kg上げる方法、医療職からエンジニアに転職した方法などについて、個人ブログで発信していますのでご興味ある方は覗きに来てください。
[臨床工学プログラマブログ](https://ce-fitness-note.com)



今後もC＃関連の基礎的な内容で記事作成していきたいと思います。
どうぞよろしくお願いします。

**参考文献リンク**
[C#を攻略しよう アクセス修飾子](https://www.kisoplus.com/kihon/acc.html)
[ピーコックアンダーソン](https://anderson02.com/cs/cskiso/cskisoniwari-25/#:~:text=static%E3%82%AD%E3%83%BC%E3%83%AF%E3%83%BC%E3%83%89%E3%81%AF%E9%9D%99%E7%9A%84,%E3%81%A8%E3%81%8D%E3%81%AB%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)
2つのPDFファイルを1ページ毎相互にマージする

#2つのPDFファイルを1ページ毎相互に挟み込みつつ1つのPDFにする
職場でリクエストがあったので作ってみた。

**【準備したファイル】**
　・pdfA.pdf
　・pdfB.pdf
　・pdf.py

**【イメージ】**
pdfA.pdf --> pageA-1, pageA-2, pageA-3, ...
pdfB.pdf --> pageB-1, PageB-2, pageB-3, ...
pdfC.pdf --> pageA-1, pageB-1, pageA-2, pageB-2, pageA-3, pageB-3, ...

###【手順】
####PyPDF2ライブラリのインストール

```zsh
conda install -c conda-forge pypdf2
```

####スクリプト作成

```pdf.py
#! ~/usr/bin/python
# *-# -*- coding: utf-8

import PyPDF2

#ファイルのパス
pdfA = "pdfA.pdf"
pdfB = "pdfB.pdf"

#出力pdfオブジェクト
pdf_writer = PyPDF2.PdfFileWriter()

#ｐｄｆAオープン
f_A = open(pdfA, "rb")
pdfA_obj = PyPDF2.PdfFileReader(f_A)

#ｐｄｆBオープン
f_B = open(pdfB, "rb")
pdfB_obj = PyPDF2.PdfFileReader(f_B)

#pdfAファイルのページ数を取得
pdfA_obj.numPages

#各PDFを1ページ毎に挟み込む。繰り返しの回数はpdfA_obj.numPagesで取得したものを設定する
for page_num in range(pdfA_obj.numPages):
	page_obj = pdfA_obj.getPage(page_num)
	pdf_writer.addPage(page_obj)
	page_obj = pdfB_obj.getPage(page_num)
	pdf_writer.addPage(page_obj)

#ｐｄｆC.pdfとして出力
pdf_output = open('pdfC.pdf', 'wb')
pdf_writer.write(pdf_output)
pdf_output.close()
```

###実行

```zsh
% python pdf.py
```

**今後**
ページ数を自動で取得して、スクリプトの編集なしで目的の動作をさせる。
DiskStationを使用したVPN Serverの構築

#参考サイト
設定方法
https://wwq.mydns.jp/1606/
VPNプロトコルについて
https://it-trend.jp/vpn/article/48-0067#chapter-3
ポート開放
https://www.akakagemaru.info/port/wnax2033gr2-portfw.html