OmniAICreator/Qiita-1.07M huggingface dataset:
SAML 認証による一時的な認証情報で boto3 を利用する

弊社では全社員が G Suite のアカウントを持っており、AWS マネジメントコンソールにアクセスする際は Google を Identity Provider として SAML 認証してシングルサインオン [^sso] をしている。この場合、STS の Assume Role という仕組み [^assume_role] を使って一時的な認証情報を入手し、フェデレーションユーザとしてマネジメントコンソールにアクセスすることになる。マネジメントコンソールにアクセスするために社員ごとに IAM ユーザを作成する必要がなくなるため、アカウント管理の手間が削減できる。

[^sso]: [G Suite アカウントを用いた AWS へのシングルサインオン | AWS Startup ブログ](https://aws.amazon.com/jp/blogs/startup/techblog-saml-gsuite/)
[^assume_role]: [IAMロール徹底理解 〜 AssumeRoleの正体 | Developers\.IO](https://dev.classmethod.jp/articles/iam-role-and-assumerole/)

ただ、シングルサインオンを導入した場合にひとつだけ困るのがアクセスキーである。そもそも IAM ユーザが存在しないため、(永続的な) アクセスキーを発行することができない。ローカル端末にあるファイルを AWS CLI を用いて S3 に転送したいときや、Jupyter Notebook から boto3 を用いて AWS リソースにアクセスしたいときなど、アクセスキーが必要になるケースは少なくない。[^access_key]

[^access_key]: そもそも強い権限を持った アクセスキーをローカル端末に保存するのはセキュリティリスクでしかないという話はある

そこで今回は、SAML 認証による一時的な認証情報で boto3 を利用する方法についてまとめる。

内容としては、SAML 認証で AWS CLI を使う方法が公式ドキュメントに書かれている [^awscli] ので、それを Python (boto3) に置き換えただけである。

[^awscli]: [AWS CLI を使用して SAML 認証情報の呼び出しおよび保存を行う](https://aws.amazon.com/jp/premiumsupport/knowledge-center/aws-cli-call-store-saml-credentials/)

## Role ARN と IdP ARN を用意する
Role ARN は Assume Role で利用している Role の ARN で、IdP ARN は SAML 認証の Identity Provider の ARN。

``` python
role_arn = 'arn:aws:iam::123456789012:role/GSuiteMember'
idp_arn = 'arn:aws:iam::123456789012:saml-provider/Google'
```

## SAML Response を取得する
[トラブルシューティングのためにブラウザで SAML レスポンスを表示する方法 \- AWS Identity and Access Management](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/troubleshoot_saml_view-saml-response.html)

これに従ってブラウザ上で SAML 認証を行うことで、SAML Resnponse という文字列を得ることができる。

``` python
saml_response = '...とても長い文字列...'
```

SAML Response は Base64 エンコードされており、とても長い文字列なのでコピペする際は注意が必要。

## アクセスキーを取得する
ここまでの情報があれば、AssumeRoleWithSAML という API [^assume_role_with_saml] を用いて一時的なアクセスキーを得ることができる。この操作は SAML 認証をしてから5分以内に行う必要がある。

[^assume_role_with_saml]: [AssumeRoleWithSAML \- AWS Security Token Service](https://docs.aws.amazon.com/ja_jp/STS/latest/APIReference/API_AssumeRoleWithSAML.html)

``` python
sts = boto3.client('sts')
response = sts.assume_role_with_saml(
    RoleArn=role_arn,
    PrincipalArn=idp_arn,
    SAMLAssertion=saml_response,
    DurationSeconds=43200,  # 12 hours
)
credentials = response['Credentials']
```

AssumeRoleWithSAML で取得したセッションはデフォルトでは1時間で失効するが、 `DurationSeconds` を指定することでこれを伸ばすことができる。(上限値は Role の Maximum session duration に設定されている時間まで)

## アクセスキーを利用する
あとは通常通りアクセスキーを用いて AWS リソースにアクセスすることができる。

``` python
session = boto3.session.Session(
    aws_access_key_id=credentials['AccessKeyId'],
    aws_secret_access_key=credentials['SecretAccessKey'],
    aws_session_token=credentials['SessionToken'],
    region_name='ap-northeast-1',
)

# EC2 インスタンスの一覧を取得する
ec2 = session.client('ec2')
ec2.describe_instances()
```

awscli を使う場合は以下の出力結果を `~/.aws/credentials` に書き込むと良い。

``` python
profile = "tmp"
print("\n".join([
    f"[{profile}]",
    f"aws_access_key_id = {credentials['AccessKeyId']}",
    f"aws_secret_access_key = {credentials['SecretAccessKey']}",
    f"aws_session_token = {credentials['SessionToken']}"
]))
```
AttributeError: 'Series' object has no attribute 'isna'　解決法

# Python pandas　を利用中・・・
Python 実践データ分析100本ノックという本を写経している時、こんなエラーができました!

![スクリーンショット 2020-04-09 0.45.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297375/a3ca9100-7cd9-2998-89a8-fd0cbf2c31e1.png)

*AttributeError: 'Series' object has no attribute 'isna'*

正しく写経しているはずなのに、エラー💦

#解決方法

原因は、バージョンの問題だった。
Python3.6を使っていましたが、
###3.7にアップデートしたら動きました。
pandasもアップデートしたけど、Pythonの問題だったらしい。

良かった！

Anacondaの人は以下のコマンドで一発

```
conda install python=3.7
```

###ちなみに・・・
Python3.8でも動きました。

解決はしたけど、なぜかはよくわかってないので、分かる人教えてくださいm(_ _)m
メモリダンプの出力設定＆動作確認

■メモリダンプの出力
「コントロールパネル」＞「システム」＞「システムの詳細設計」＞「詳細設計」タブの「起動と回復」エリアの「設定」ボタン＞「デバッグ情報の書き込み」プルダウンを「なし」に設定

<img width="300" alt="システムの詳細設計" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207111/a950cf74-c5ac-cab4-c40c-c33a66d45de5.png">　　<img width="300" alt="起動と回復" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207111/7b445818-2921-2c02-838f-ddf1fb9a8b32.png">


■ダンプファイル出力先
○メモリダンプ
C:\Windows\MEMORY.DMP
%SystemRoot%\MEMORY.DMP

○エラーレポート（Windows Error Reporting Service）
C:\ProgramData\Microsoft\Windows\WER\ReportQueue

■意図的にPCをクラッシュさせる
（１）レジストリエディタで下記パラメータを新規追加する
　　=========================================
　　場所：HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters
　　（※USB キーボードの場合は）
　　場所: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\kbdhid\Parameters

　　名前 ：CrashOnCtrlScroll
　　データ型：REG_DWORD
　　値：1
　　=========================================


（２）PCを再起動する
（３）`右側の「Ctrl」+「Scroll Lock」キーを2回押下する

<img width="600" alt="レジストリエディタ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207111/9fa67305-be78-0618-c7e9-a120aa4c6e15.png">
Laravel の Policy ってどんな場合に使うの？

`特定のリソースに対するユーザーアクションを認可`する仕組みだそうです。
例えば、ブログの記事削除は本人にしかできないようにすることが可能になる仕組みのことです。

Policyを使わないで書くと以下のようになり、

```php
public function delete(Article $article)
{
    if (request()->article()->isNot($article->user)) {
        return response([], 403);
    }

    $article->delete();
}
```

`ArticlePolicy`を作成すると、

```php:ArticlePlicy.php
public function delete(User $user, Article $article)
{
    return $user->id == $article->user_id;
}
```

以下のように書ける。

```php
public function delete(Article $article)
{
    $this->authorize('delete', $article);

    $article->delete();
}
```

また、ミドルウェアによる認可もできる。以下のように書ける。

```php:api.php
Route::delete('/articles/{article}', 'ArticlesController@destroy')->middleware('can:delete,article');
```

今の所、アカウントの種類によって認可するアクションを切り分けたいときに使う認識でいます。
VS Code で Jupyter を動かしてみる

VS Code でJupyter が使えるらしいのでやってみました。

###1. 環境
OS：Windows 10
VS Code：1.43.2
拡張機能：Anaconda Extension Pack 1.0.1
Pythonインタープリター：3.7.3 64-bit

###2. 拡張機能 Jupyterのインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/2743fef4-9691-a239-392d-7516dd894f84.png)

###3. コードを入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/6e2fcc31-0594-4488-1540-29b934f4c247.png)


```
# %%
from matplotlib import pyplot as plt
import numpy as np

# %%
x = np.linspace(-10, 10, 100)
# %%
y = (x**3) + (5*x**2) + (2*x)
# %%
print(x)
#%%
print(y)
#%%
plt.plot(x, y)
plt.show() 
# %%
z = np.sin(x)
# %%
print(z)
# %%
plt.plot(x, z)
plt.show() 
```

###4. コードを実行（Run Cell）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/b8538899-38b5-8c25-e821-79083d31c5a9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/acfd6a8e-f97c-6472-137a-d3c739440137.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/d96b0d7c-381e-0de6-9e2b-86af81f5b72f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/2be3993b-1071-ccbf-53f7-5bad0f0c139e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/f7138192-ae5d-f50e-a40f-b2a6b77fee2b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225878/de92d0d0-4779-c20e-49c3-994bf9a6867d.png)

###5. 参考サイト
https://qiita.com/surei/items/9f25d7efa7c67d55d98f
https://www.atmarkit.co.jp/ait/articles/1806/12/news041.html
TypeError: Cannot change data-type for object array.

ある日、matplotlibを使用した場合に、こんなエラーが出た。

  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/lib/stride_tricks.py", line 119, in broadcast_arrays
    zip(args, shapes, strides)]
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/lib/stride_tricks.py", line 32, in as_strided
    array.dtype = x.dtype
TypeError: Cannot change data-type for object array.


matplotlibを再インストールしたら解決した．
$ pip uninstall matplotlib
$ pip install matplotlib
ICMPヘッダのチェックサムを求めるメモ

# メモ

以下ハイライトしている部分がICMPヘッダの内容。
この中のチェックサムの値を求める手順をメモ。
ICMPはEcho Message。

![ScreenClip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50690/f765ed7f-883d-adac-4397-987fd211924f.png)

まず、ICMPのヘッダ構造は上から以下となっている。

- 8bit(タイプ)
    - Echo Message の場合は 8
- 8bit(コード)
    - Echo Message の場合は 0
- 16bit(チェックサム)
    - 0x665b
- 16bit(識別子)
    - 0x0001
- 16bit(シーケンス番号)
    - 0x000e
- 任意Byte(データ)

上記キャプチャの場合に置き換えると

タイプとコードは上記の通り8,0で、0x66 0x5b がチェックサム。残りがデータ部となる。

チェックサムの求め方は参考サイト(1)のものをそのまま利用させてもらうと、

> チェックサムフィールドはヘッダの全16ビットワード
　について１の補数を合計し、それをさらに16ビットの１の補数にする。
　チェックサムの計算ではチェックサムフィールドの値は０とする。

ちなみに1の補数というのはビット反転で、補数和というのは (4) 参照の通りで、補数を足し合わせて16bitからはみ出たものを最下位ビットにまわして足し合わせるもの。
なので、まずは16bit毎の1の補数の合計を求める。このときチェックサムの部分は0に置き換える。

```
0x0800 + 0x0001 + 0x000e + 0x6162 + 0x6364 + 0x6566 + 0x6768
= 0x199A3
```

そして `0x199A3` は2進数だと `11001100110100011` 
これは17bit。
1の補数和は桁上りを最下位ビットに加算するようなので、一番左の `1` を一番右に足して、  `1001100110100100`  となる。
これを反転すると `0110011001011011` で16進数に直すと `0x665b` で無事キャプチャのチェックサムを求められた。

ちなみにデータ部のバイト数が奇数の場合、例えば、1バイトの場合でデータが0x01の場合は、右側に0埋めして `0x0100` として計算する。

# 参考
(1)メモ帳　チェックサム
http://specialimpact.blog22.fc2.com/blog-entry-47.html

(2)Internet Control Message Protocol - Wikipedia
https://ja.wikipedia.org/wiki/Internet_Control_Message_Protocol

(3)ICMP
http://pentan.info/doc/rfc/j792.html

(4)
1の補数 ‐ 通信用語の基礎知識 https://www.wdic.org/w/SCI/1%E3%81%AE%E8%A3%9C%E6%95%B0
→ 1の補数和の計算が分かりやすい
WE ARE TEAM "LOT"

# このQiitaについて

## チーム結成
2020年、日本橋にて発足したクリエイティブ集団「LOT」、現在隊員4人。

## チーム体制
- プロデューサー 1名
- デザイナー 1名
- インフラ/サーバーサイドエンジニア 1名
- フロント、スマートフォンアプリエンジニア 1名

##目的
- とにかく4人で何か作る
- 情報を共有して高め合う
- 金が欲しい
- 飲む！  

以上
Office VBA 64/32Bit共用 Win32 API MsgWaitForMultipleObjects  待機関数

#VBAのフォーム間のやりとり
https://web.archive.org/web/20120522222109/http://homepage1.nifty.com/MADIA/vb/vb_bbs2/200706/200706_07060026.html
という記事を見つけました。

>Sleep している間は、ウィンドウメッセージを処理できなくなりますので、
ウィンドウを持つアプリは、そのメインスレッドから Sleep API を
呼ぶべきでは無いとされています。

>限定的にであれば、Sleep 呼び出しをごく短時間にして、DoEventsとあわせて
繰り返し呼び出すという対処方法もありますが、できれば、
http://msdn.microsoft.com/library/ja/jpdllpro/html/_win32_sleep.asp
にも書かれているように、MsgWaitForMultipleObjects API もしくは、
MsgWaitForMultipleObjectsEx を使った方が安全でしょう。

>そうすれば、待機中にもメッセージ(再描画要求、マウスやキー入力等)を
DoEvents等で処理できますので。

>```vb
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function MsgWaitForMultipleObjects Lib "user32" _
   (ByVal Count As Long, ByVal HandlesPointer As Long, _
    ByVal WaitAll As Long, ByVal MilliSeconds As Long, _
    ByVal WakeMask As Long) As Long
```


これをVBAで使えるのか、さらに64bit 32 bit共用で使えるのか。
結論から言うと簡単に使えます


```vb

#If VBA7 Then
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
Private Declare PtrSafe Function MsgWaitForMultipleObjects Lib "user32" _
   (ByVal Count As Long, ByVal HandlesPointer As Long, _
    ByVal WaitAll As Long, ByVal MilliSeconds As Long, _
    ByVal WakeMask As Long) As Long
#Else
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Function MsgWaitForMultipleObjects Lib "user32" _
   (ByVal Count As Long, ByVal HandlesPointer As Long, _
    ByVal WaitAll As Long, ByVal MilliSeconds As Long, _
    ByVal WakeMask As Long) As Long
#End If
Public Sub WaitAPI6432(ByVal msec As Long)
' msec ミリセカント(千分の一秒)単位
If msec <= 0 Then
msec = 1
End If
Dim Interval As Long
Dim tickBegin As Long
Interval = msec
tickBegin = GetTickCount()
Do
  If MsgWaitForMultipleObjects(0, 0, 0, Interval, &HFF&) = 0 Then
     DoEvents
  End If
  Interval = msec + tickBegin - GetTickCount()
Loop Until Interval < 0
End Sub
Sub test_WaitAPI6432()
' Test 用 Sub プロシージャ
Debug.Print Timer
Call WaitAPI6432(3000)
Debug.Print Timer
End Sub
```

このプロシージャの機能はSleepのように停止するのではなく、待機するという点が違うようです。
http://tokovalue.jp/function/MsgWaitForMultipleObjects.htm
>指定したオブジェクトのいずれか1つまたはすべてがシグナル状態になったとき、またはタイムアウト時間が経過したとき制御を戻す。

http://chokuto.ifdef.jp/urawaza/api/MsgWaitForMultipleObjects.html
Windows 95時代からある

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-msgwaitformultipleobjects
Leetcode 30 天挑戰, Week 2 Day 1, Middle of the Linked List, in Swift

資料結構或演算法： `Linked List` `Slow Fast Pointer`

因為想要紀錄自己思考解法的過程記錄下來，就寫了這篇。

## 相關連結

- 挑戰頁面： <https://leetcode.com/explore/challenge/card/30-day-leetcoding-challenge/529/week-2/3290/>
- 原題目 - [876. Middle of the Linked List](https://leetcode.com/problems/middle-of-the-linked-list/)

## 思考方式

因為 linked list 無法取得有幾個數，為了取得中間數，只能透過 slow fast pointer 來達成。這個方式也有人叫他「龜兔賽跑」。

而這題就是還滿典型和可以說是最簡化的 "slow fast pointer" 問題。
概要是 slow 一次移動一個位置（🐢），fast 一次移動兩個位置（🐰）。
當 fast 移動到尾端之後，slow pointer 停留的位置就自然就會是 linked list 中正中間的節點。

### 判斷尾端

判斷是否移動到尾端，用了 `fast != nil` 和 `fast?.next != nil` 的原因是，

- 有 **奇** 數個節點數的時候，需要用 `fast?.next != nil` 判斷
- 有 **偶** 數個節點數的時候，則需要用 `fast?.next != nil` 判斷

詳細說明和步驟附在最後面。

## Code

``` swift
class Solution {
    func middleNode(_ head: ListNode?) -> ListNode? {
        var slow: ListNode? = head
        var fast: ListNode? = head

        while fast != nil && fast?.next != nil {
            slow = slow?.next
            fast = fast?.next?.next
        }
        return slow
    }
}
```

### 複雜度分析

令 n 為 linked list 的長度

- 時間複雜度： O(n)
    - 即使最多是執行 n/2 次，但是還是會寫成 O(n)
- 空間複雜度： O(1)
    - 沒有用到和 list 長度有關個數的記憶體空間，所以這邊是常數

### 執行結果

- <https://leetcode.com/submissions/detail/321698369/>

## 尾端判斷說明

奇數個：

``` text
 1 -> 2 -> 3
--------------
 s
 f
-------------- s 移動 1 個, f 移動 2 個
      s
           f
--------------
// 這時候 fast 已經抵達尾端，同時也可以發現 fast 沒有下一個節點。
```

偶數個：

``` text
 1 -> 2 -> 3 -> 4
--------------
 s
 f
-------------- s 移動 1 個, f 移動 2 個
      s
           f
-------------- s 移動 1 個, f 移動 2 個
           s
                    f
--------------
// 這時候 fast 已經超過數列，可判定為到達尾端，同時也可以發現 fast 已經成為空值 (nil)
```

以上， happy leetcoding !!
"001 UILabelで文字を表示"  iOS app開発 習得日記 (5)

UIkitを覚えるために
こちらの写経がいいときいたので始めた
(http://docs.fabo.io/swift/uikit/001_uilabel.html)

001 UILabelで文字を表示

```
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        let bWidth: CGFloat = 200
        let bHeight: CGFloat = 50
        
        let posX: CGFloat = self.view.bounds.width/2 - bWidth/2
        let posY: CGFloat = self.view.bounds.height/2 - bHeight/2
        
        let label: UILabel = UILabel(frame: CGRect(x: posX, y: posY, width: bWidth, height: bHeight))
        
        label.backgroundColor = UIColor.orange
        
        label.layer.masksToBounds = true
        
        label.layer.cornerRadius = 20.0
        
        label.shadowColor = UIColor.gray
        
        label.textAlignment = NSTextAlignment.center
        
        self.view.backgroundColor = UIColor.cyan
        
        self.view.addSubview(label)
        
        
        
    }


}
```

selfは、ViewControllerのインスタンスを表しているのでよいのか？
また、

```
label.layer.masksToBounds
```
とドットを続けて書いているところがわからない。
labelインスタンスの　layerプロパティのmasksToboundsプロパティということ？
プロパティのプロパティ？
どういうこと？
SwiftとC#の書き方比較

## はじめに
C#を書くにあたり、「Swiftでいうと・・・これ？:expressionless:」「なんだ、これは？:innocent:」と
かなり困惑したので、比較表を作ろうと思いました。
私自身、初心者なので同じ初心者の方々のお役に立てれば嬉しいです:blush:
:triangular_flag_on_post:記事の内容に関して、勘違いもあると思いますし、これが全てではありません。
　 色々な記事を読んで、自らの手をどんどん動かしてみてください！

## 変数と定数
```Swift:Swift
//変数
var hoge: String = "Hello"
//定数
let fuga: Int = 810
```
```C#:C#
//変数
string hoge = "Hello";
//定数
const int fuga = 810;
```
- ポイント
    - Sfiftでは型名は後 / C#では型名は前
    - C#では文末にセミコロンが必要（初めは忘れがちです:angel_tone2:）
        - :point_up:右辺の型が自明である場合はわざわざ型を記載しなくても良いですが、本文では記載しておきます。

## 型変換(StringとIntで)
```Swift:Swift
//String → Int
var hoge: String = "114"
var fuga: Int = Int(hoge)!
//Int → String
var hoge: Int = 514
var fuga: String = String(hoge)
```
```C#:C#
//String → Int
string hoge = "114";
int? fuga = int.Parse(hoge);
//Int → String
int hoge = 514;
string fuga = hoge.ToString();
```
- ポイント
    - Swiftは 型(値)
    - C#はメソッドを使う（変換する型の組み合わせによっては他のやり方もある）

## 配列
```Swift:Swift
//配列の作成
var someInts: [Int] = []
//要素の追加
someInts.append(1)
someInts += [2,3,4,5]
print(someInts) //[1,2,3,4,5]
```
```C#:C#
//要素数が可変なリストの作成
List<int> someInts = new List<int>();
//要素の追加
someInts.add(1);
//これがC#の配列宣言
int[] addInts = new int[] {2,3,4,5};
someInts.AddRange(addInts);
Console.WriteLine(someInts); //[1,2,3,4,5]
```
- ポイント
    - Swiftの配列は要素数が可変
    - C#の配列は要素数が固定（Listは可変）

## for文
```Swift:Swift
//昇順処理なのでC#みたいに色々と書かなくてもよい
for i in 1...5 {
    print(i) //1,2,3,4,5
}
```
```C#:C#
//カッコ内で色々と書く
//iの開始値は1,iは5まで繰り返す,iはfor文の処理を終えるごとに+1する
for(int i = 1; i <= 5; i++)
{
    Console.WriteLine(i); //1,2,3,4,5
}

```
- ポイント
    - Swiftのfor-in文は昇順処理をしてくれるため、簡潔に記載できる（Swift3.x~）
    - C#はforのカッコ内で色々と書く必要がある
        - :point_up:map,foreachなど色々ありますが、今回は最も基本的なもので比較しています。

## if文
```Swift:Swift
var num: Int = 5
//カッコなしで書ける
if num == 5 {
    print("５だよ")
} else {
    print("５じゃないよ")
}
// 5だよ
```
```C#:C#
int num = 5;
//カッコがいる
if(num == 3)
{
    Console.WriteLine("3だよ");
}
else
{
    Console.WriteLine("3じゃないよ");
}
//3じゃないよ
```
- ポイント
    - 書き方はそんなに違いなし！？

## 関数
```Swift:Swift
//func 関数名(ラベル 引数名: 型) -> 戻り値の型
func plusWithNum(_ num1: Int, _ num2: Int) -> Int{
    return num1 + num2
}
//ラベルにアンスコを書くことでラベルなしで呼べる
plusWithNum(1,5)
//6

//ちょっと余談
//func 関数名(ラベル省略 引数名: 型) -> 戻り値の型
func plusWithNum(num1: Int, num2: Int) -> Int{
    return num1 + num2
}
//引数名がラベルになるが、呼び出すときに記述する必要あり
plusWithNum(num1: 1, num2: 5)
//6
```
```C#:C#
//戻り値の型 関数名(型 引数名)
int plusWithNum(int num1, int num2)
{
    return num1 + num2;
}
//普通に引数の型と同じものを入れたらよい
plusWithNum(1,5)
//6

//追記
// 名前付き引数での呼び出し
PlusWithNum(num1: 1, num2: 5);

// 名前付き引数の場合, 順番を前後させても問題ない
PlusWithNum(num2: 5, num1: 1);
```
- ポイント
    - Swiftは「->」の後が戻り値の型で関数を使用するときに引数にはラベルが必要
    - C#は関数名の前が戻り値の型で素直に引数を入れたらよい
        - :sunny:C#もSwiftのように引数名を書いて呼び出せるようです(@Midoliy さん、ありがとうございます！)

## さいごに
ざっくりと基本文法の比較を書いてみました。
これはほんの一部に過ぎません（氷山の一角ですらない:innocent:）
どんどん検索をして知識を深めていきましょう（私も頑張ります）
この記事が最初の１歩を踏み出す助けになれたら幸いです。
今後はSwiftのことを中心に記事を書いていこうと思うので、よろしくお願いします:v:
## 参考サイト
[Swift 言語ガイド](https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html)
[C# プログラミング ガイド](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/)
【Python】三井住友信託銀行プログラミングコンテスト2019C(DPの使いどころさん)【AtCoder】

>※この記事は、DP(動的計画法)の基本中の基本である
かえるくん問題2問がとけることを前提としています。

>- [Frog1](https://atcoder.jp/contests/dp/tasks/dp_a)
- [Frog2](https://atcoder.jp/contests/dp/tasks/dp_b)


DPでとけるんだ！！！
と感動した問題がありましたので記事にします。
DPの考え方は知っているけれども、実際の問題と結びつかない！
という人は参考になるかも(ならないかもw)

#[三井住友信託銀行プログラミングコンテスト2019C](https://atcoder.jp/contests/sumitrust2019/tasks/sumitb2019_c)
Difficulty:205
問題を読んで、bit全探索や6重for文が一瞬頭をよぎりましたがダメそう。

ちなみにDPが思いつかなくても解けます。(記事の最後に別解として載せておきます。)
しかしDPが思いつかなかった場合、
たぶん法則性をみつけるのに15分くらいかかる気がします。

**レートをあげるには早解きが必須！**

##DPのメリット
DPのいいところは、(DPに限らずの話ですが)
 「この問題、DPで解ける！」と気づいた瞬間、**ほぼ脳死でコーディングできる**
こと！ 
するとそこに**思考を挟まない**ので、
このレベルの問題は5分くらいでACを目指せるようになると思います！

**DPを使えることに気付けるかどうかがポイント！**

##具体例を考えよう
とにもかくにもノートとペンを用意して、
OKパターン・NGパターンを考えましょう。
>1~99：NG
100,101,102,103,104,105：OK
106~199：NG
200,201,202,203,204,205,206,207,208,209,210：OK
211~299：NG
300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315：OK
...

なぜ`200~205`がOKなのか？
それは、もともとOKの`100`に`100~105`を足しているから。
なぜ`201~206`がOKなのか？
それは、もともとOKの`101`に`100~105`を足しているから。
なるほど！
ではもともとOKの`200~210`それぞれに対して`100~105`を足せば、それもOKになりそう。

あ、DPでいけそう！
0円をOKとしてやれば、もともとOKの`0`に`100~105`を足してOKとなる！
うまくいきそう！
あとはコーディングするだけ！！！


##答え
DPMapのIndex番号だけちょっと考えれば、あとは脳死でいけるはず！
また、問題を読んだ瞬間にDPだとわかればノートとペンも必要なさそう！

```python:test.py
def I(): return int(input())
X = I()
dp = [0]*(X+1) #0_indexed
dp[0] = 1 #0円をOKとしてやる！
for i in range(X+1):
    if dp[i]:
        for j in range(100,106):
            if i+j<=X: #「out of lange」対策。
                dp[i+j] = 1
print(dp[-1])
```

##DPを使えるかどうかの目安
具体例を順番にあげていくときに、前の値から次の具体例を導き出せる場合
→DPが使えるかどうか考えてみる価値がありそう！！！

##別解
俺は初見でDPと気づかなかったのでこっちでやりました。
コード量は少ないけど、このコードを導くのに時間がかかると思います。
(こういう法則を見つけるのに慣れてる人はこっちの方が早いのかなぁ)

```python:test.py
def I(): return int(input())
X = I()
a,b = divmod(X,100)
print(1 if a*5>=b else 0)
```


おわり！
Capybaraのfill_inメソッドで、lavelがない時にfieldを特定する方法

#●はじめに
fill_inメソッドでlavelが無いfieldを指定する際に、どのように指定すれば良いか学習しました。

#●結論
text_fieldのvalue_nameで指定する。

#●方法
```erb

  <h2>ログイン</h2>

   <div class="field">
     <%= f.email_field :email, autofocus: true, autocomplete: "email",  placeholder: " Email" %>
   </div>
```
このようにtext.lavelが無く、コードからはどのように指定すれば良いかわからない。
そこで「検証」ツールを使用し、text_fieldのvalue_nameを確認する。

###1.右クリックを押し、検証を選択する。
![スクリーンショット 2020-04-08 23.37.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553621/64063866-ff89-4661-a3e7-660ed1c17c58.png)

###2.指定したいfieldを選択する。
![スクリーンショット 2020-04-08 23.40.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553621/40096ef0-5a5e-0994-3cda-f3d87c1a576a.png)

### 3.該当するコード部分をクリックし、value_nameを確認する。
![スクリーンショット 2020-04-08 23.42.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553621/b5ad0cde-6077-99ff-6f2b-9489ccc66ad4.png)

###4.value_nameを入力し、fieldを特定する。
```ruby

context "フォームの入力が正しい時" do
  it "ログインに成功し、フラッシュメッセージを表示する" do
    fill_in "user[email]", with: "#{user.email}"
    fill_in "user[password]", with: "password"
以下略
```

以上の方法で特定が可能です！　
ちなみにidを指定している場合はidでも特定が可能そうです。
Webサイトの読み込み順がよくわからないので少し調べた話

JSの勉強のため調べたのでメモメモ。
<h1>【読み込み順】</h1>
JSってとりあえずheadタグに書いておけばとりあえず動くって考えてました。

考えなきゃいけない発端が下記のコード。

(Vue.js の記事で書いたコードを少し変えて使用します。)

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>双方向データバインディング</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="js/main.js"></script>
    </head>
<body>
    <div id="app">
     	<p>{{ message }}</p>      

    <p><input type="text" v-model="message"></p>
    </div>
</body>
</html>
```

```js
(function() {
    'use strict';

    new Vue({
      
        el: '#app',

             data: {
            // name: 'taguchi'
            message: 'ばなな'
        }
    })


})();
```

headでJSを読み込んでいるのですが、こちら下記のエラーが出ます。

```
[Vue warn]: Cannot find element: #app
```

まだappを読み込んでないってことです。
それはこちらで解決できます。

```js
document.addEventListener('DOMContentLoaded', function() {
　　window.app = new Vue()
});
```

さて、自分が疑問に感じたところは
『Webページを読み込みはどの順番で実行されるの？』ということです。

基本的に、HTMLの一番上から順番に読んでいきます。
JSファイルを読み込んでいる間はHTMLの解析が止まります。
それにより、読み込み速度が遅くなります。

お客さんが見てることも考えるとSEO的にもよくありません。


CSSファイルの読み込みは、HTMLの読み込みと同時に行われます。
ページが表示されることを最優先に考えれば、
JSはbodyタグの一番下で読み込みのがいいとされます。
(Googleも推奨してるみたいですね)

一応、読み込みの順番を変えることもできます。

```html
<script src=“パス” defer></script>
<script src="パス" async></script>
```

deferは、HTML読み込み後に実行されます。

asyncは
1.HTMLの読み込み中にJSのダウンロードが行われる。
2.ダウンロード終了後、HTMLの読み込みがストップしJS実行。
という順序です。

他にもonloadなど、しっかり順序は把握しないといけないですね。
JQueryの$(function(){})に関しても、ページの読み込み完了後に実行されるみたいです。
(初めて知りました)

何だかごちゃごちゃしますね。
ライブラリもフレームワークも使う時は調べてから使った方が良さげな感じがします。

その内、調べてまとめていきたいです。


<h1>【おまけ:letとvarの違い】</h1>
変数を宣言する際、letが流行っているらしいので意味もなくletを使ってました。
違いってあったんですね・・・・・・・・
(とりあえず変数を宣言してることがわかるように書いてるんだと思ってた)

var：宣言後、再代入・再宣言が可能。

let：宣言後、再代入が可能。再宣言ができない。


おやすみなさい
Karabinerで日本語入力ができない

「commandキーで日本語に切り替え」をやりたかったが、なぜか出来ずにハマったので残しておく。

# 単刀直入に

MacでInput Sourcesのところに日本語を増やすのを忘れていませんか？

(画面は英語です)

<img width="669" alt="Screen Shot 2020-04-08 at 23.36.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386550/6788d7d4-6b92-444f-013d-6be8c59616a7.png">

USキーボードだと最初はここのJapaneseって書いてあるところ(多分日本語って表示されるはず)が存在してなくて、そもそも何に切り替えるねん、という感じになります。

もしこれでもダメだったら、karabinerのプロセスを一度全部殺してみてください。

```bash

pgrep karabiner | sudo xargs kill
```

で、karabinerは勝手にもう一度生えるので、それで出来るようになっていないかをみます。

それでもダメなら、ちゃんとmacの本体設定の方で Security & privacy のところでkarabinerを許可しているかどうかと、設定の中のinput monitorでkarabier observerとかにちゃんとチェックマークを付けているかどうかを確認しましょう。

# まとめ

これで2時間溶かすのは虚無すぎる...😇
rmコマンドに悩んだらmvコマンドで/tmpに移動させてもいいんだよ

rmについては話題性に富み、枯れた議論かと思いますが、エンジニア歴が長い方から教えていただき目から鱗であったTipsで、僕が適当かつバランス良くエンジニアとしてやっていく上でとても役に立っているTipsを一つ紹介させてください。

## 言いたいこと

`rm` コマンドで、ファイル削除に戸惑うなら `/tmp` ディレクトリに移動させておけばOK
（ただし、ファイルサイズには注意を）

### 方法

`rm foo.txt` であれば、 `mv foo.txt /tmp/` にするだけです。


## マサカリ回避用防護壁（=補足）

僕には、マサカリが鋭利すぎるので、補足します。

### そもそも rm は慎重に実行すべきでしょう

はい。
そもそも、消えたらまずいものがある環境に接続していること自体が慎重になるべきことで、それに輪を掛けてrmを実行するなど慎重に慎重を重ねて「慎重のミルフィーユ」と呼べるようなものを作れる程度に慎重になるべきだと慎重に考えて慎重にQiitaに書いた次第であるので、慎重にならないことなど想定するべきないと慎重に考えておりますが、そんな慎重なんて気分や体調次第や忙しさで忘れてしまうのが人であり組織だと思います。[^aa]
[^aa]: 仕組みが面倒だとズルをしたくなるじゃないですか、こんな感じにコレだけ慎重に慎重にって言ったら、面倒くさくなってしまいズルをして、ズルをした結果やらかすことが往々にしてあると思ってます。

### `/tmp` ディレクトリ配下は勝手に消えるのか？

はい。
ディストリビューションにもよりますが、だいたい消えるという理解で間違いないと思います。[^ディ]
[^ディ]: 3日後に消えているかもしれません。再起動したら消えているかも知れません。誰かが再起動したから直後に消えてるかもしれません。（消えない場合は意図的にそうしているか、そういうOSでないか等々の理由がありますが、長くなるので割愛します。他の記事を探してください。）

### `/tmp` が1分後に消えたり、再起動時に消えてたらrmでよくない？

はい。
たいして変わんないです。
ただ、今すぐ消えるか、1分後も残っているかでは、だいぶ気持ちの持ちようが変わってくると思います。[^かわんね]

[^かわんね]: そもそも論を言うならば、今すぐ削除する（読み込めなくする）必要があるファイルってあんまりないと思います。そのため、 mv で /tmpに移動しても良いと思ってます。

### `/tmp` の容量が足りなくなったりしない？

はい。
ありえると思います。ファイルサイズによってはとても良くないと思います。
rmコマンドで面倒な事になるか、容量不足で面倒なことになるかのどっちかだと思ってます。
ただ、一時的な用途に限るはずのディレクトリですから、中身を全部削除するとしても、心理的なハードルはすごく下がると思います。
参考になるとても良い記事: [/tmpと/var/tmpの仁義無き戦い](https://qiita.com/kuni-nakaji/items/f29be14be578b5a19d4b#fhsv23%E7%8F%BE%E8%A1%8C%E6%A8%99%E6%BA%96-2014329%E6%99%82%E7%82%B9)

### どんなときでも有効な話じゃないので参考にならなくない？

はい。
「この文章は日本語で書かれている」みたいに絶対的な話ではなく、環境依存する話なのに環境の話がないからそういうことを言うのかと思います。その通りだと思います。 [^補足2]

[^補足2]: だいたい `Linux` ってよばれてるOSについてはある程度つかえるTipsだと思いますが、RHELの〜とかUbuntuの〜とかそういう細かい話を調査してまとめるのが手間だったので省かせてもらいました。あと、少し前のmacOSとかでも[3日後に消える](https://www.d-wood.com/blog/2014/04/09_6008.html)らしいので、macでも使えると思いますが、macOS Mojaveで、なんか消えてない気がしますので、参考にしていただく際はご自身でご自分の環境について確認いただければとおもいます。

## 経緯

長い割に本題から外れ気味だったので注釈にしました。気になるようでしたら注釈を読んでください[^注釈]

[^注釈]: 仲良くさせていただいている方に、 `rm -rf ./大切なファイル（ディレクトリ）`を、とてもとても大切な環境で実行したことがある方がいます。これは、その方が涙目になりながら、教えてくださったTipsです。あの時、/tmpに移動していれば... と後悔されていました。（結局、なんとかなったと聞きましたが）不幸なことになるチームや人を減らすために書かせてもらいました。個人的な思い1としては、プログラマになり、自身のローカルのDockerやVagrant、もしくはリモートに存在する環境上で作業することが出てくると思います。その際に、ファイルを消したい... ということが往々にしてあると思います。ただ、そのファイルをあとで見たいと思うことないでしょうか。もしくは1時間後に見たいと思うことは無いでしょうか。たしかに、自身のターミナルのログを保存している（もしくは履歴が追える）のであれば、catしておくとかであとから見直すことも可能です。ただ、経験上、面倒くさいとおもってます。似たようなログがあったら「どれだ！?」ってなりました。そのため、取り敢えず削除したいなーって場合は `/tmp` に移動させています。個人的な思い2としては、本番環境でrmコマンドを使う場合もできる限りmvコマンドで代用してます。理由は、「取り返しの付かないファイル削除」もしくは「削除して慌てるようなファイルをやってしまう」ということを防げるためです。基本はmvでやって、どうしても削除しないと行けない場合のみ、慎重にrmコマンドを打つように心がけすることができます。個人的な思い3としては、shell スクリプトに入っていたrmコマンドで事故っているところをみたことがあります。被害は非常に軽微でしたが、見ていて変な汗が手からでてきました。その時も、/tmpに移動していれば、「/tmpから戻せばいいじゃろ」って冷静に対処できたと思います。当然、復旧させる方法もググれば一杯出てきますが、ググって探して方法を特定するまでドキドキしているところを見てるのがいやでした。あと結局復旧ではなく再度作り直すでなんとかしていたようです。
【swift 】Labelの表示関連いろいろ

SwiftのLabel表示関連を調べたので、自分用メモ。
今後またLabel関連で使いそうなものを見つけたら追記。

###### ・ラベルの最後尾に文字を追加して表示する
該当ラベル.text = 該当ラベル.text + 追加する文字
例:　resultLabel.text =  resultLabel.text! + String(sender.tag)

###### ・ラベルの文字サイズを表示範囲内に収まるようにリサイズする
該当ラベル.adjustsFontSizeToFitWidth = true
例:　resultLabel.adjustsFontSizeToFitWidth = true

###### ・文字の最小サイズを決める（リサイズとセットで使うと下限を設定出来る）

該当ラベル.minimumScaleFactor = 文字サイズ
例:　resultLabel.minimumScaleFactor = 0.1        

###### ・ラベル表示の行数を設定する
該当ラベル.numberOfLines = 行数（0にすると行数制限がなくなる）
例:　resultLabel.numberOfLines = 1

###### ・はみ出す文字は…を使用せずラベルに表示しない様に設定する
該当ラベル.lineBreakMode = .byWordWrapping
例:　resultLabel.lineBreakMode = .byWordWrapping

###### ・ラベルに表示されている文字数を取得する
該当ラベル.text.count
例:　resultLabel.text?.count
【SIRモデル解析】γ＊(R－１)の決定と感染数のピークアウト♬世界編

いよいよ日本も緊急事態宣言が発出された。
一方、最近、中国に引き続いて、韓国、そしてさらにイタリア、スペインなどが次々に感染数がピークアウトしつつあるというニュースが聞こえるようになってきた。
今回も以下のSIRモデルを基礎に世界の感染数、治癒数、死亡数を分析した。

```math
{\begin{align}
\frac{dS}{dt} &= -\gamma R I \\
\frac{dI}{dt} &=  \gamma (R - 1) I \\
\frac{dr}{dt} &=  \gamma I \\
\end{align} 
}
```

ということで、今日は[先日のモデル解析](https://qiita.com/MuAuan/items/6bf34a72b7cbe48434b3)を世界の合計値に応用してみることとした。
理論は、前回の記事を参照してほしい。
結果は、以下のとおりである。
まず、この図は、このまま伸びると1月程度で感染数が１０００万人になってしまいそうな図である。
![exterpolate_world_gamma_R_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/c0c966a2-33c5-a1ee-f610-8366fe2dba35.png)
しかし、よく見ると以下の特徴があることが分かる。
![removed_world_gamma_R_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/047390b7-f566-0f18-0a2c-cdb14404a760.png)
このグラフから分かること
①上図の赤い感染数のグラフを見ると、最初のピークは中国のピークで今回二度目の世界のピークになろうとしている。しかし、まだまだ増加している。
②治癒曲線を見ると、これも一度中国の終息と共に赤い線とクロスしたが、再び赤い線が急激に増加し、治癒はゆっくりとそのあとを追うように立ち上がり始めている
③I／(R+I)の曲線は、一度１を下回ったが、今は3あたりで水平となっていた。しかし、ここに来て少しマイナスの傾きを持ったようだ。すなわち、終息に向かい始めたことを示しているようだ。
④下のグラフは実効再生産数R＝1.5－10の間を緩やかに変化していることが分かる。しかし最近は８程度の大きな値であり、まだまだ強烈に感染していると言える
⑤γは最近二度目の0.015あたりまで減少してきており、これは中国のときの振る舞いと似ていて感染数ピークあたりの振る舞いに見える

最後にγ（R-1）の値は、対数スケールでもある程度分かるが、知りたいのはいつ０を通過するかということであるので、リニアスケールで描いてみた。
結果は以下のとおりとなった。
すなわち、直線的に減少しており、あと約10日で世界の感染数がピークアウトするという結果である。
![removed_world_gammaR_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233744/5fd016d1-9bfe-cbf0-5506-9778e8d9bbbe.png)
ピークアウトは終息ではない。

さらに今日の日本の新規患者は500人に達してしまった。
これからもさらに気を引き締めて
・出かけない
・集まらない
・マスク
・手洗い
を心がけて一日も早く世界がCOVID-19から解放されることを願う。
Node.jsのLambdaでPre-Signed URLを発行する

# Pre-Signed URL
S3はアクセス権を設定することで、誰でもファイルにアクセスできるようにしたり、できなくしたりが可能です。
Pre-Singed URLは誰でもファイルにアクセスできなくしているところに一時的にアクセスを許可することができます。
今回はこのPre-SingedをLamndaで発行してみたいと思います。

# S3
バケットを準備して非公開の設定にしておきます。
テスト用に1つ画像ファイルをアップロードしておきましょう。

# Lambda
今回はNode.jsでPre-Singed URLを発行します。
LambdaからS3にアクセスできるようにロールを設定しておきましょう。

## コード
バケット名、ファイルパスは適宜変更して下さい。

```js:Lambda
const AWS = require('aws-sdk');
const s3 = new AWS.S3()
const params = {
  Bucket: '<バケット名>',
  Key: '<ファイルパス>',
  Expires: 100 // 期限（秒）
}

async function getPresignedUrl(){
  return new Promise((resolve,reject)=>{
    s3.getSignedUrl('getObject', params, (err, url) => {
      if (err) {
        reject(err)
      } else {
        resolve(url)
      }
    })
  })
}

exports.handler = async (event) => {
  const url = await getPresignedUrl()
  return {
    url: url
  }
}
```

これで署名付きのURLが返ってくるのでアクセスするとアップロードした画像が見れるはずです。
markdown tips

- 1.見出し

# sample
- 2.コードの挿入

```python:test.py
print('Hello World')
```

- 3.リンク

[test](https://www.google "express")

- 4.引用

> quotation
>> dual quotation

- 5.文字の修飾

*itaric*
**bold**
***itaric&bold***

- 6.リスト

- list

1. list1
1. list2 

- 7.水平線

******

- 8.表

|左揃え|中央揃え|右揃え|
| :--- | :---: | ---: |
|1|2|3|
|right|center|left|

- 9.マークダウンのエスケープ

\#見出し
NavigationBarのtitle 文字色変更時のトラブル


## 症状
・NavigationBarのtitleの文字色をStoryBoardから変更
<img width="198" alt="スクリーンショット 2020-04-08 22.47.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613702/dbd8a20b-a52f-7e2f-0034-651447a5674a.png">

・NavigationBar全体の色をStoryBoardから変更
<img width="1353" alt="スクリーンショット 2020-04-08 22.56.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613702/e31734de-f89d-49a7-19e7-8aa8c9a99b1a.png">

そうするとこうなる・・・~_~;
変更したはずのNavigationBarのtitle文字色が黒色になってしまう
<img width="418" alt="スクリーンショット 2020-04-08 23.02.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613702/b3fc3fda-25ce-d9fb-bcb9-794ceecc0cd3.png">

## 色々試してみて他にわかった事
・シュミレータ上でも黒のまま
・navigationBarの背景色がデフォルトのときはtitleの文字色の変更は可能
・背景色をデフォルト以外の色にすると文字色が指定できず必ず黒になってしまう

## 解決方法 (原因はわからん)
原因はわからんがとりあえずこの方法でtitleに色を当てることはできた

・navigationControllerを一度削除する
・再度navigationControllerを設定
・storyBoardの設定で「Is Initial View Controller」を忘れずにチェック
・titleの文字＆title文字色をstoryBoardで設定
・AppDelegate.swiftのapplication()内で以下を記述

```rb
# NavigationBarの背景色設定
	UINavigationBar.appearance().barTintColor = UIColor.指定したい色
	
```

StoryBoard上
<img width="1353" alt="スクリーンショット 2020-04-08 23.13.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613702/18cde567-70c3-56b9-fa4f-3b4907276327.png">

シュミレータ起動時
<img width="469" alt="スクリーンショット 2020-04-08 23.14.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613702/89136f9a-d165-0a34-65e4-3e7d8c72a307.png">


不思議だ・・・

原因わかったらまた書こうと思います
Unityで画像処理をするためのライブラリを公開しました

#顛末
なんか画像処理の研究をすることになったけど，Unity+C#以外の環境でスクリプトが書ける気がしない...
↓
なんでUnity+C#で画像処理しちゃいかんの？ライブラリ書いたるわ！

#初めに
ということでUnityで画像処理ができるライブラリ，[ImageProcessingLibraryforUnity](https://github.com/Asalato/ImageProcessingLibraryforUnity)を作りました．
他のUnityで画像処理している記事は主に画面描画におけるポストプロセスの工程でのブラーの実装とかをしていますが，本ライブラリはTexture2DやTextureに対するものです．

ComputeShaderで書いているのでGPUがちゃんとしている環境ではまあまあ早いです．
画像処理ライブラリといったらOpenCVですが，Unityでこれが使えるAssetは[これ](https://assetstore.unity.com/packages/tools/integration/opencv-for-unity-21088)とか[これ](https://assetstore.unity.com/packages/tools/integration/opencv-plus-unity-85928)とかいくつかありますが，速度比較をしたところ自分のライブラリの方が早かったです．
<font color=gray>そのデータ紛失したので自信もって言えませんが...</font>

一番の特徴としては，LINQのようにメソッドチェーンの方式で書くことができます．
これによって直感的に記述することができ，雰囲気で画像処理ができます．うれしいですね．

#使い方
基本的にGitHubの[リポジトリページ](https://github.com/Asalato/ImageProcessingLibraryforUnity)にあるReadMeに書いてあります．

Unityのプロジェクトに本unitypackageを導入後，利用したいシーンにShaderSettingsのprefabを置いてください．これで準備完了です．

```cs
var renderTexture = texture.ToRenderTexture();
```

と書くことで，Texture2DやTexture型の画像をComputeShaderで扱える画像フォーマットであるRenderTextureに変換できます．

そのあとは，

```cs
renderTexture.GaussianFilter5X5().ExtractEdge().TransAlpha(true).MoveChannel(Color.white);
```

といった感じで行いたい処理のメソッドを後ろに追記していくだけで画像処理ができます．

#機能紹介
フィルタ関数

* [ガウスフィルタ](https://en.wikipedia.org/wiki/Gaussian_filter)
* [ラプラシアンフィルタ](https://en.wikipedia.org/wiki/Discrete_Laplace_operator#Image_Processing)
* [ソーベルフィルタ](https://en.wikipedia.org/wiki/Sobel_operator)
* [SMAフィルタ（単純移動平均フィルタ）](https://en.wikipedia.org/wiki/Moving_average#Simple_moving_average)
* [閾値フィルタ](https://en.wikipedia.org/wiki/Thresholding_(image_processing))
* [メディアンフィルタ](https://en.wikipedia.org/wiki/Median_filter)

便利機能

* 解像度変更
* マスク処理
* 色変換
* 透過度変換
* ２画像の足し合わせ

自分が画像処理の研究をするにあたり必要な機能を実装していっただけなので，現在ある機能は結構偏ったものとなっていますが，後々色々と追加していこうと思っています．

#動作例
![Lenna.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433211/9057ddfd-e657-a3a5-4175-3c2344d43dfc.png)
この画像に対し，この処理

```cs
// デノイズ処理を行い，その結果からエッジを抽出
texture.ToRenderTexture().GaussianFilter5X5().ExtractEdge();
```

を実行した結果がこちらになります．
![Destination.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433211/da9caf2b-733a-75a9-91bf-f501e5cb6c82.png)
ちゃんとエッジが抽出されているのが分かると思います．

`System.Diagnostics.Stopwatch` のストップウォッチを利用し時間計測をした結果13msとなりました．
この処理時間のほとんどはCPU-GPU間のデータ転送時間であり，もっと複雑な処理をしてもあまり増加しません．

#おわりに
今回色々なフィルタ関数を実装してみて，この程度の処理ならUnityでも十分な速度が出ることが分かりました．
今後も機能追加をしていこうと思っています．

##今後の課題
既知のバグとして，コードを書いていると時々アセンブリのコピーがうまくできないという現象があります．Unityを再起動することで修復されますが，すごくウザいので原因究明を行っています．

また，現在はRenderTextureを用いてGPUとのデータのやり取りを行っています．
そのため，画像表示を行うとUnity標準のガベージコレクションでは扱えないゴミが出るため，定期的にこちらからリソースの整理命令を出しています．
常にRenderTextureでやり取りをすると常に画像を可視化できデバッグなどとてもやりやすいのですが，ComputeBufferでGPUとのやり取りをして，必要に応じてRenderTextureに変換する，というやり方もあります．
どちらがよいのか検証しようと思っていますが，めんどくさいので現状このままになっています．知見のある方がおられましたらご指南をお願いします．

4/9編集：日本語が変だったので修正しました
Office 2019 VBA Web Browser Controlを使う

ドラッグ＆ドロップでファイル追加できるリストボックスの作成
https://reta-slot.com/access-drag-and-drop
公開日 : 2015年9月19日 / 更新日 : 2018年7月9日 

この記事の方法はつい先日まで不可能でした。なぜならVB6.0を使うものの、KillBitされており、参照できなかったからです。
しかし、先日ProgressBarがなぜか復活しているので、今はできます。最も、過去、32Bit系のコントロールはトラブルを起こしており、自然とすたれてきているため、これを積極的に使用することはためらわれます。

しかしながら、この方法は間違っています。
これはWeb BrowserControlを使うと、VB6.0系のコントロールを使う必要がないためです。
Windows7 に VB6.0 をインストールするとエラーが出る
#Web Browserの表示
アーリーバインディングでiFrame.exeを追加します。
こうしないと表示されません。
`.AddFromGUID "{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}", 1, 1'SHDocVw Microsoft Internet Controls C:\Windows\System32\ieframe.dll`
つまりこれです。
なお、Wordでこれをやろうとする人は
Accessにも参照設定してください。
`.AddFromGUID "{4AFFC9A0-5F99-101B-AF4E-00AA003F0F07}", 9, 0'Access  Microsoft Access 16.0 Object Library    C:\Program Files\Microsoft Office\root\Office16\MSACC.OLB`

これは先日のExcelのVBA開発用のプロシージャーテンプレートのAddreferenceで出てきます。
[ACCESSでファイルのドラッグアンドドロップ](http://blogwizhook.blog.fc2.com/blog-entry-250.html)
セオリーとコードはこちらです。
ここでは「ここではmscomctl.ocxがインストールされていない環境でも作動する方法を載せてみます。」と断っていますが、mscomctl.ocxの不安定さを考えるとWebBrowserの方がまだましかもしれません。
最もInternet Explorerの先行きを考えると不安はあります。
#Accessを参照設定していると、変数として宣言しなくてもAccess.NzでNz関数が使える。
これが今回のポイントです。
あと上記サイトのコード中、
`テキスト2 = URL '←併せてファイル名をテキストボックスに表示させ`
となっているところは、フォームにテキストボックスを配置したときのTextbox1の間違いか、テキストボックスに`テキスト2`という名前をつけているのかもしれません。
#なぜWordで検証しているのか
これは疑問に思われる方もいらっしゃると思います。これはWordで動くなら、ほかのすべてのOfficeアプリで使えることになるためです。
Pythonで再帰をやってみた②（フィボナッチ数列）

以前再帰を使った回文判定、Fractal図形の描画を行いましたが、今回は第2弾です。

#フィボナッチ数列

フィボナッチ数列とは、
1 1 2 3 5 8 13...
のように前２つの数字を足したものが次の項になるという数列です。
（例）第４項の3はその前２つの1と2の和
今回は再帰を使ってフィボナッチ数列の第n項を知るというプログラムを書きました。

```Python
def fibonacci(n):
    if n < 3:
        return 1
    else:
        return fibonacci(n-1) + fibonacci(n-2)
```

もし１項か２項なら１、それ以降は１つ前と２つ前の項に戻り、さらに１つ前、２つ前にもどるという形です。
少し分かりにくいですが、
n=5なら４項、３項の和が必要なので２，１項に戻って和を求めていきます。
これでn=10なら55、n=20なら6765となります（数が大きくなればなるほど時間がかかります）。
セッションハイジャック

##セッションハイジャック
セッションハイジャックとは名前の通り、なんらかの方法を用いて正規利用者ではないものが他人のセッションIDを乗っ取る攻撃手法です。
セッションハイジャックが行われた場合、アプリケーション内で正規の利用者ができることはほとんど実行が可能なので、正規利用者の個人情報閲覧、送金や物品購入、なりすましメールの送信やSNSへの犯罪予告など正規利用者への被害はとても大きくなります。
###セッションハイジャックの攻撃手法と対策
セッションハイジャックの具体的な攻撃手法
①セッションIDの推測
②セッションIDの盗み出し
③セッションIDの強制
###セッションIDの推測
Webアプリケーションに用いられるセッションIDの生成規則に問題があると、第三者にセッションIDが予測され、悪用されてしまう可能性があります。
生成規則に問題があるセッションIDは以下のようなものを元に生成されているものが多いです。
①ユーザIDやメールアドレス
②リモートIPアドレス
③日時
④乱数
上記のものをそのまま使う場合や、エンコードやハッシュ計算というものと合わせて利用される場合があります。
ユーザIDや日時は外部から参照可能なためセッションIDを推測することが可能になります。
推測可能なセッションIDの生成を回避するためには、Webアプリケーション開発ツールが持つセッション管理機構を利用します。
###エンコード
動画を視聴・編集したり、弊社で扱っているNVR(ネットワークビデオレコーダー)に保存されている動画データを取り扱うことです。
###ハッシュ計算
ハッシュアルゴリズムを使ってハッシュ値を計算します。
###セッションIDの盗み出し
セキュリティに不備のあるネットワークではセッションIDとして利用されるcookieを盗聴されてしまう可能性があります。暗号化されていない無線LANは、まさにそのようなネットワークの一例です。
SSLというネットワークを暗号化するプロトコルがあります。
###SSL
インターネット上の通信を暗号化してくれる技術です。これにより、第三者からの情報の盗聴や改ざんを防ぐことができます。
セッションIDのような重要な情報をやりとりする際はSSLを使うと機密性・完全性を保つことができます。
###セッションIDの強制
セッションIDを悪意のある第三者が外部から強制させる方法があり、これをセッションIDの固定化といいます。
セッションIDの固定化は以下の手順で行われます。
①悪意のある第三者は普通の利用者としてセッションID(abc123)を取得
②被害者に対して1.で取得したセッションIDを強制
③被害者は標的アプリケーションにログイン
④悪意のある第三者は、被害者に強制したセッションID(abc123)を使って標的アプリケーションにアクセスする
被害者は悪意のある第三者が強制したセッションIDで認証が完了しています。そのため、そのセッションIDを用いてアクセスした悪意のある第三者はすでに認証済みのページにアクセスすることができます。
セッションIDを固定する方法は多種多様です。Webアプリケーション側でセッションIDの固定化攻撃に対策する方法として、認証が完了した時点でセッションIDを変更するという方法があります。
そうすることにより、認証前にセッションIDが固定されたとしても、認証後にセッションIDが変わるため固定されたセッションIDでアクセスしようと試みる悪意のある第三者は認証されておらず攻撃は成功しません。
##Railsでのセッションハイジャック対策方法
【例】セッションの盗聴について

```/アプリ名/config/environments/production.rb
config.force_ssl = true   #コメントアウト
```
記述のコメントアウトを外します。これにより、本番環境で環境アプリケーションを公開する際に先ほど紹介したSSLを使い通信経路を暗号化してくれるため、セッションIDの盗聴を防ぐことが可能になります。
**※Rails側のHTTPSの設定は完了しますが、Nginx等の設定を、HTTPへのアクセスからHTTPSへリダイレクトする設定へ変更する必要があります。サービスをローンチする機会がある場合はNginx等の設定を変更し対策をします。**
###セッション固定化攻撃
対策として、ログイン成功後に古いセッションを無効にし新しいセッションIDを発行します。

```
reset_session
```
上記の1行をセッションを再発行したいアクション内に指定することにより、セッションは再発行されセッション固定化攻撃を防ぐことができるようになります。
【JavaScript】テンプレートリテラル

# テンプレートリテラル

**テンプレートリテラル**によって、複数行文字列や文字列補間は驚くほど簡単に実現できるようになりました。

例えば、従来のJavaScriptの構文でHTMLを組み立てようとした場合、おそらく次のようになるでしょう。

```js
var user = {
  name: '鈴木太郎',
  age: 25,
  image: 'exapmle.jpg'
}

var html = ''
html += '<div class="user">'
html += '<div class="name">名前：' + user.name + '</div>'
html += '<div class="age">年齢：' + user.age + '</div>'
html += '<div class="image">'
html += '<img src="' + user.image + '"alt="' + user.name + '" />'
html += '</div>'
html += '</div>'
```

いくつもの文字列の連結により、何がどのようになっているのか推測するには困難な状況です。しかし、この書き方よりほかに方法はありませんでした。
次に、テンプレートリテラルを用いた書き方を見てみましょう。テンプレートリテラルは、シングルクォートやダブルクォートの代わりに、**バッククォート**`を用います

```js
const user = {
  name: '鈴木太郎',
  age: 25,
  image: 'exapmle.jpg'
}

const html = `
<div class="user">
  <div class="name">名前：${user.name}</div>
  <div class="age">年齢：${user.age}</div>
  <div class="image">
    <img src="${user.image}" alt="${user.name}" />
  </div>
</div>`
```

以前の構文に比べて、かなり読みやすくなったのではないでしょうか。テンプレートリテラルでは、`\n`のような表現に頼らずに改行をすることができます。
また、文字列の補間として、ドル記号と波括弧で`${}`表すことができます。`${}`のなかで変数を展開したい計算をすることができます。

# テンプレートリテラルのタグ付け
ここまでの用法は、すでにご存知の方も多いかと思います。
テンプレートリテラルのさらに高度な使用法として、タグ付けされたテンプレートリテラルを使用することができます。

テンプレートリテラルにタグを付けるには、次のように使用します。

```js
greet`こんにちは、${user.name}さん。年齢は${user.age}歳です。`
```

ここでは、関数`greet`というタグを付けています。
`greet`関数の呼び出しでは、テンプレートが引数として渡されます。関数の本体では、テンプレートで何からの処理を実行して新しい値を返します。

greet関数を実装してみましょう。

```js
const user = {
  name: '鈴木太郎',
  age: 25,
  image: 'exapmle.jpg'
}

const language = 'en'

function greet(string, ...args) {
  string[0] // こんにちは、
  string[1] // さん。年齢は
  string[2] // 歳です。

  args[0] // 鈴木太郎
  args[1] // 25

  // 配列をコピー
  const copy = [...string]

  if (language === 'en') {
    const english = []
    copy[0] = 'Hello'
    copy[1] = 'age is'
    copy[2] = 'years old'
  } 
  // Hello Mr.鈴木太郎age is25years old
    return copy.reduce((previous, current) => {
      return `${previous}${String(args.shift())}${current}`
    })
}

console.log(greet`こんにちは、${user.name}さん。年齢は${user.age}歳です。`)
```

タグ付け関数の第一引数には、文字列部分が配列として入っています。
これは、リテラル中に`${}`が含まれている場合、`${}`によって分割されます。
この第一引数の配列には、**プロパティの変更・削除・追加が不可能** という特徴があるため、加工をするために配列をコピーしていることに注意してください。
2つ目以降のパラメータには、補間された値が入っているため、レストパラメータで配列として取得しています。
これらの文字列は、`reduce`関数でつなぎ合わせることができます。
このように。文字列を加工して返すことができます。
Docker-machine + Anaconda + Jupyter Notebook

# 目標

docker-composeで環境を作った後に、そのコンテナ内でAnacondaとJupyter Notebookを使う

## なぜdocker-compose?

たしかにコンテナを作って、そこに入れば解決するが、それだとファイルが手元に残らない。共有するように走らせるようなコマンドを叩くくらいなら、docker-composeでそれを済ませてしまおうという話。

# 必要なもの

まず、ファイル類の準備。

```
$ touch Dockerfile
$ touch docker-compose.yml
$ mkdir workspace
```

```:Dockerfile
FROM continuumio/anaconda3

ARG DOCKER_UID=1000
ARG DOCKER_USER=docker-user
RUN useradd -m --uid ${DOCKER_UID} --groups sudo ${DOCKER_USER}

WORKDIR /workspace

USER ${DOCKER_USER}

# 以下を付け足すと必ず起動してくれます。
CMD jupyter-lab --no-browser --port=8888 --ip=0.0.0.0 --allow-root
```

```docker-compose.yml
version: '3'
services:
  anaconda:
    build: .
    volumes:
      - ./workspace:/workspace
    ports:
      - "8888:8888"
    tty: true
```

ファイルの用意ができたら、コンテナをビルドしていく。

```
# 付け足した人の場合
$ docker-compose build
$ docker-compose up

# 付け足していないなら
$ docker-compose build
$ docker-compose up -d
```

使い方。
[図解！Jupyter Labを徹底解説！(インストール・使い方・拡張機能)](https://ai-inter1.com/jupyter-lab/)
[JupyterLabのすゝめ](https://qiita.com/kirikei/items/a1639954ce5ccaf7ac3c)

コンテナへの入り方。

```
# コンテナ名を確認
$ docker ps -a

$ docker-compose up -d
$ docker exec -it --user=docker-user コンテナ名 /bin/bash 

$ jupyter lab
```

複数コンテナで扱うことになった場合ポートが重複してしまうことがある、その時は以下のようにして対策。

```
# パスワードを設定したい場合は以下を実行してください
$ python
>>> from notebook.auth import passwd
>>> passwd()
Enter password: 【パスワード入力】
Verify password: 【パスワード確認で入力】
【ここの文字列(sha1: から始まるやつ)をコピーしておく】
>>> exit()

# この設定をする時は、rootでコンテナに入ることをお勧めします
$ docker exec -it --user=root コンテナ名 /bin/bash 
$ jupyter lab --generate-config
# ここでファイルが作られたパスが表示されるので
$ vim さっき表示されたフルパス
# vimがない場合
apt-get update
apt-get install vim
```
vimがひらけたら、以下のようにコメントを外して変更する。
(自分の時は、85,204,272,281,292行目にありました。)

```
## Whether to allow the user to run the notebook as root.
c.NotebookApp.allow_root =True

## The IP address the notebook server will listen on.
c.NotebookApp.ip = '0.0.0.0' 

...

## Whether to open in a browser after starting. The specific browser used is
#  platform dependent and determined by the python standard library `webbrowser`
#  module, unless it is overridden using the --browser (NotebookApp.browser)
#  configuration option.
c.NotebookApp.open_browser = False

## Hashed password to use for web authentication.
#  
#  To generate, type in a python/IPython shell:
#  
#    from notebook.auth import passwd; passwd()
#  
#  The string should be of the form type:salt:hashed-password.
c.NotebookApp.password = 'さっきのpasswd()でコピーしたもの'

...

## The port the notebook server will listen on.
c.NotebookApp.port = 「受信ポートの規則を追加する」で宛先ポート範囲に指定したやつ(デフォルトは8888)
```

## Anacondaコマンド集

注意点：環境毎にパッケージはインストールしてあげてください。そうしないと`ModuleNotFoundError`地獄にハマります。

```
# 現在の仮想環境情報
$ conda info

# 仮想環境の一覧表示
$ conda info -e

# 仮想環境の作成
$ conda create --name 環境名 python=3.6

# 仮想環境の切り替え
$ activate 環境名

# 仮想環境の終了
$ deactivate

# 切り替えがうまくいかなかったら
$ conda deactivate
$ conda activate 環境名

# インストールパッケージ一覧
$ conda list

# help
$ conda -h
```
Pinebook Pro のデフォルトOS（Manjaro KDE Edition）を eMMC にインストールする手順

# （事前準備）eMMCインストール用イメージのダウンロードと microSD への書き込み
20.04 以降は eMMC インストール用イメージが提供される。
これによって dd コマンドを使った eMMC への書き込み作業は不要になった。

## eMMC インストール用イメージのダウンロード
1. 次のサイトを開く：https://forum.manjaro.org/t/manjaro-arm-20-04-released/133374
2. Downloads: >> Pinebook Pro >> KDE Plasma 20.04 >> Manjaro-ARM-kde-plasma-pbpro-20.04-emmc-installer-20.04.img.xz 
3. .xz ファイルを展開して .img ファイルを得る

## eMMC インストール用イメージを microSD に書き込む
1. SDCardFormatter で microSD をフォーマットする
2. etcher で microSD に .img ファイルを焼きこむ

#  （Pinebook Pro 実機で作業）インストール手順
```shell
1. eMMC インストール用イメージを書き込んだ microSD を挿入して起動する >> LEDがオレンジ点灯 >> LEDがグリーン点灯 
2. manjaro のロゴが出てぐるぐる回る >> [ESC] を押すと先に進む（これは既知のバグ）

-------------------------------------------
Do you want to proceed >> [Yes]
Currently, the booted sdcard is at "mmcblk1" >> SDカードとは番号の違う "mmkclk2"（これがeMMC） を選んで[OK]

# イメージ展開フェーズ
# この extact の作業は1回目のみ発生する。2回目以降は展開イメージを使い回すので、省略される。
==> Extracting XZ Image. This will take some time (10-20 minutes)......（5分ほど待つ）
==> Extract finished >> Press any key to continue: >> [enter]

# eMMC への書き込みフェーズ
==> Flashing Image to eMMC. This will take some time (5-10 minutes)...... >> （90秒ほど待つ）
Flash Complete >> Press any key to continue >> [enter]
Flash is complete. The system will shut down so you can remove the SDCard >> [OK]
Power off in 5 seconds... >> 電源が落ちる
-------------------------------------------

3. microSD を抜いて起動する >> LEDがオレンジ点灯 >> LEDがグリーン点灯 >> manjaroのロゴぐるぐる

-------------------------------------------
キーボードレイアウトを選ぶ（us ANSI Layout）>> [OK]
Enter username: >> ユーザ名を入れて [OK]
Enter additional groups... >> 空欄で [OK]
Enter Full Name... >> フルネームを入れて [OK]
Enter Password... >> パスワードを入れて [OK]
Confirm Password... >> パスワードを入れて [OK]
Enter Root Pasword: >> root のパスワードを入れて [OK]
Confirm Root Password: >> root のパスワードを入れて [OK]
Choose your timezone! >> Asia/Tokyo >> [OK]
Choose your locale! >> en_US.UTF-8 >> [OK]
Enter desired hostname for this system: >> ホスト名を入れて [OK]
Is the below information correct: >> 内容を確認して [Yes]
-------------------------------------------

4. 再起動がかかる >> manjaroのロゴ >> LEDがオレンジ点灯 >> LEDがグリーン点灯 >> manjaroのロゴぐるぐる
5. ログイン画面が出る
```

# Pinebook Pro のデフォルト OS 変更について
2020年3月以降、デフォルトの OS が Manjaro KDE Edition になった。

従来のデフォルトOS（Debian Desktop Community）のインストールについてはこちらを参照：
https://qiita.com/cuminseed/items/de0a1721806c1e69759d

以上
Selenideのshould、shouldBe、shouldHaveの違い


[SelenideのQuick Start](https://selenide.org/quick-start.html)をやっていて、Assertionメソッドにshould、shouldBe、shouldHaveの3種類（と否定を表現するshouldNot、shouldNotBe、shouldNotHaveの3種類）があり、使い分けがよく分からなかったのでそれを整理したメモです。

## 違い
まず、自分の英語力が足りていませんでした。
以下のやりとりでもある通り、should、shouldBe、shouldHaveは同義語となるため違いはありません。

ただ、Selenideを使ってテストコードを書く場合、この3つの使い分けは「英語として自然でありより読みやすい形となるものを選択して使う」が使い分けるポイントとなるようです。ちなみに、[公式ドキュメント](https://selenide.org/documentation.html)にもその旨の記載があります。

>We recommend to choose the convenient alias so the line of code can be easily read like a common english phrase

ちなみに、「should be text」というのは英語の文法として正しくありませんが、以下のコードのようにshouldBe Textという使い方をしてもコンパイルエラーにはなりませんし、テストもパスします。

```
$(By.id("agree_and_goto_next")).shouldBe(text("NEXT"));
```

英語力が問われるところでもあるのかなと思いました。

## 参考
* https://selenide.org/documentation.html

以上です。
tmuxメモ

# tmuxの個人的メモ

tmuxのセッション開始

```
tmux
```

## 基本的にコマンドはctrl+b +何かしらのアルファベット

縦にペーン分割

```
ctrl+b  "
```

ペーン間移動

```
ctrl+b  矢印キー
```

viのようなコマンドモードに移行

```
ctrl+b :
```

この状態で、例えば下記のコマンドを実行する


![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/6f63d360-1bcc-449a-95e7-621a674ae864.png)


すると、複数のペーンで同じコマンドを同時に実行できる
複数VMにて同じコマンドを実行したい場合などに手軽に実行できるのが嬉しいみたい

![b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/09ad5423-06c0-7d1c-22bf-8d95732f5006.png)


tmuxセッションからのデタッチ

```
ctrl+b d
```

tmuxセッションのリスト

```
tmux ls
```

tmuxセッションへのアタッチ
session idはtmux lsで確認可能

```
tmux attach -t <session id>
```


tmuxのセッション終了

```
tmux kill-session 
```