OmniAICreator/Qiita-1.07M huggingface dataset:
『ダウンロードを保留しています』を解消する

タイトルの通りです。
androidユーザーが対象です。

Googleのplay storeでアプリをインストールしようとすると『ダウンロードを保留しています』とメッセージが表示され、そのままピクリともしなくなることがあります。

ググって色々な方法を試してみるも改善せず途方に暮れていましたが、1つピンと来るものがあったので確認してみたらビンゴでした！

play storeの設定でアプリの自動更新を『wifi接続時のみ』にしていたのが原因でした。

何日もwifi接続していないとアップデートが溜まってしまうわけです。
その状態で中途半端にwifi接続→接続断してしまうとアップデートが待機中のままになってしまうことがあるようです。
自動でキャンセルしてくれないんです。泣

もうお分かりですね？
手動でキャンセルして無事fixとなりました。

※スクショ撮り損ねたので画像がありません。すみません。
↓この画面で待機中のようなステータスのものがないか確認してみてください。

![Screenshot_20190806-232931~2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134325/9e365fa3-40b2-e658-d30f-7b065a582316.png)
疑似要素と疑似クラス

## 擬似要素
「:」は2つ付けます。
1つの要素に1つまでしか指定できません。

|疑似要素|意味|
|---|---|
|::after|要素の後に指定内容を追加|
|::before|要素の前に指定内容を追加|
|::cue|WebVTT(動画や音声の字幕やキャプションなど)にスタイルを適用| 	
|::first-letter|テキストの先頭1文字目にスタイルを適用|
|::first-line|テキストの先頭1行目にスタイルを適用|
|::selection|要素内の選択状態の部分にスタイルを適用|


## 疑似クラス
「:」は1つだけ付けます。
1つの要素に複数指定可能です。

### リンク系
:activeは他のリンク関連疑似クラスによって上書きされるので、「:link」→「:visited」→「:hover」→「:active」の順番で記述します。
「:link」と「:visited」は逆でも良いです。

|疑似クラス|意味|
|---|---|
|:hover|カーソルが乗った時|
|:link|閲覧したことがないリンク|
|:visited|閲覧済みのリンク|
|:active|要素がアクティブになったとき(ボタンを押してから離すまでなど)|

### 番目系
-child系　親要素から見た子要素を、指定の要素に関係なく数えます。(指定の要素が指定の順番にない場合は効かない)
-of-type系　親要素から見た子要素を、指定の要素だけを数えます。


|疑似クラス|意味|
|---|---|
|:first-child|兄弟関係の中で最初の子要素|
|:first-of-type|兄弟関係にある同じ種類の要素の中で、最初の要素|
|:last-child|兄弟関係の中で最後の要素|
|:last-of-type|兄弟関係にある同じ種類の要素の中で、最後の要素|
|:only-child|兄弟を持たない要素|
|:only-of-type|兄弟関係の中で同じ要素の兄弟が一つもない要素|
|:nth-child(n)|兄弟関係のn番目の要素|
|:nth-of-type(n)|兄弟関係にある同じ種類の要素の中の、n番目の要素|
|:nth-last-child(n)|兄弟関係の最後から数えてn番目の要素|
|:nth-last-of-type(n)|兄弟関係にある同じ種類の要素の中の、最後からn番目の要素|
|:empty|子要素を一つも持たない要素|


奇数番目　nに「odd」「2n+1」などを入れます。
偶数番目　nに「even」「2n」などを入れます。


### フォーム系

|疑似クラス|意味|
|---|---|
|:focus|フォームが入力状態|
|:focus-within|子や孫要素のフォームが入力状態|
|:disabled|入力が無効(disabled属性がある)|
|:enabled|入力が有効(disabled属性がない)|
|:checked|ラジオボタン、チェックボックスなどがチェックされてる時|
|:indeterminate|ラジオボタン、チェックボックスなどがチェックされてるかどうか不確定の状態の時|
|:default|ラジオボタン、チェックボックスなどが最初から選択されている状態|
|:required|入力必須項目(required属性がある)|
|:optional|任意の入力項目(required属性がない)|
|:read-only|入力できない項目(readonly属性がある)|
|:read-write|入力できる項目(readonly属性がない)|
|:in-range|値が制限範囲内の状態(最大値、最小値設定ありの時)|
|:out-of-range|値が制限範囲外の状態(最大値、最小値設定ありの時)|
|:valid|入力された値が形式的に正しい状態|
|:invalid|入力された値が形式的に正しくない状態|

### 印刷系

|疑似クラス|意味|
|---|---|
|:first|印刷文書の最初のページ|
|:left|印刷文書の左側のページ|
|:right|印刷文書の右側のページ|


### その他

|疑似クラス|意味|
|---|---|
|:defined|定義したCSSを他の要素に追加できる|
|:lang()|要素が指定された言語であるとき|
|:not()|()内に指定した以外の要素|
|:root|ドキュメントルートの要素|
|:target|アンカーリンク先の要素に対して、リンククリック後のCSSを指定|





## 疑似要素と疑似クラスを同時に指定する
疑似クラスが先で、疑似要素が後です。

```:css
:last-child::before
```
fileのinputタグの表示を隠す簡単なCSS

## fileのinputタグの表示を隠す簡単なCSS
ブラウザに依存したinputタグの表示を隠したい場合があるかと思います。そのような時には以下のスタイルが有効です。
`<input type="file" style="position: fixed; z-index: -1;"/>`
以下のスタイルが有効です。
この記事が参考になれば幸いです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
個人的なシリアライザの特徴表

個人的なシリアライザの特徴表（protobuf, msgpack, json, XDR）を書いておきました。
（補足や間違いがあれば指摘歓迎します。またお勧めのシリアライザがあればお知らせください）

https://shirouzu.jp/tech/serializer.md
ApexTriggerを作る際に気をつけること②

#複数レコードに対応したプログラミングをする

先輩に口すっぱく、トリガは単一のレコードが入ってくるような甘い設計はしてはいけないよと言われました。

salesforceでは、バッチ処理やdateloderなどで何千レコードが一回の処理で入ってくることは
珍しいことではありません。

その時に備えて複数レコードの処理が通るようにしておきましょう。

具体的にはまず下記の2点です。

1.SOQLをfor文の中で回さない。
2.DML処理をする際はリストなどでまとめて行う。

下記が具体的なソースになります。

1.SOQLをfor文の中で回さない。

```ruby:sampleTrigger
for ( Contact c : Trigger.new ){
       Account sample = [SELECT Name From Account Where Contact__c = :c.Id];
}
```

100以上のレコードが入ってきた場合確実に止まりますので注意です。
トリガに限らずですがSOQLはfor文内で回さないように癖づけておきましょう。

2.DML処理をする際はリストなどでまとめて行う。

```ruby:sampleTrigger
for ( Contact c : Trigger.new ){
       Account sample = new Account(Contact__c = c.Id);
       insert sample;
}
```

この場合もガバナ制限に引っかかる可能性が出てきますので、Listに一件づつ格納したあと、
まとめてインサートしてしまいましょう。
ESP32 Devkitc+IRremoteの注意点

# はじめに

bluetoothを使った赤外線リモコンを作ろうとしたときにハマったのでメモとして残しておきます。

## 環境

使用ソフト：Arduino
使用マイコン：esp32-devkitc
使用ライブラリ：[IRremote(GitHub)](https://github.com/z3t0/Arduino-IRremote)

## 行おうとしたこと

IRRemoteをArduino IDEにインストールし、サンプルスケッチのIRremote>IRrecvDumpV2をESP32に書き込もうとした。

## 発生したトラブル

esp32に11番ピンがなかったのでIrecvDumpV2のrecvPinを15に書き換えて実行したところ下記のコンパイルエラー。


```

Arduino：1.8.9 (Windows 7), ボード："ESP32 Dev Module, Disabled, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), 80MHz (WiFi/BT), QIO, 80MHz, 4MB (32Mb), 115200, None"

In file included from C:\Users\ユーザー名\AppData\Local\Temp\arduino_modified_sketch_934277\IRrecvDumpV2.ino:4:0:

C:\Users\ユーザー名\Documents\Arduino\libraries\IRremote/IRremote.h:365:23: error: 'SEND_PIN' was not declared in this scope

   const int sendPin = SEND_PIN;

                       ^

exit status 1
ボードESP32 Dev Moduleに対するコンパイル時にエラーが発生しました。

「ファイル」メニューの「環境設定」から
「より詳細な情報を表示する：コンパイル」を有効にすると
より詳しい情報が表示されます。

```

IRremote.hは赤外線の送受信用のライブラリなのだが、ESP32では赤外線送信がサポートされていないからESO32用のSEND_PINが定義されていないようだ。~~(Wifiの送信周りと干渉するらしい？)~~

8/29追記：多分割り込みやPWM信号がArduinoと互換性が無いからだろう。[別記事](https://qiita.com/mickie895/items/efcfe32b7c410adf577a)にて自作してみたので作ってみたい人は確認してみてください。

なのでライブラリ(C:\Users\ユーザー名\Documents\Arduino\libraries\IRremote\IRremote.h)の365行目付近を下記のように書き換えた

書き換え前

```IRremote.h

#ifdef USE_SOFT_CARRIER
	private:
		int sendPin;

		unsigned int periodTime;
		unsigned int periodOnTime;
		
		void sleepMicros(unsigned long us);
		void sleepUntilMicros(unsigned long targetTime);
#else
		const int sendPin = SEND_PIN;
#endif
```

書き換え後

```IRremote.h

#ifdef USE_SOFT_CARRIER
	private:
		int sendPin;

		unsigned int periodTime;
		unsigned int periodOnTime;
		
		void sleepMicros(unsigned long us);
		void sleepUntilMicros(unsigned long targetTime);
#elif defined(ESP32)
// No system LED on ESP32, disable blinking by NOT defining BLINKLED

// avr/interrupt.h is not present
#else
		const int sendPin = SEND_PIN;
#endif
```

これでコンパイルが通り、動かしてみたら問題なく動いたので良しとする。


## 余談

赤外線送受信用のセンサーやLEDは[Seeed](http://wiki.seeedstudio.com/)のデバイスを利用した。FETや抵抗などがまとめてセットになっているので楽。
LeetCode / Path Sum

（[ブログ記事](https://mhiro216.hatenablog.com/entry/2019/08/06/231212)からの転載）

[https://leetcode.com/problems/path-sum/]

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.

Note: A leaf is a node with no children.

Example:

Given the below binary tree and sum = 22,
<img width="124" alt="スクリーンショット 2019-08-05 9.43.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122973/f398ff71-29ec-9bab-0556-da08a8307466.png">
return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.

binary treeの先端から末端までのroot-to-leafの合計値が、変数sumの値と合致する箇所があるかどうかを判定する問題です。

#### 解答・解説

##### 解法1
recursiveを使った解法。
recursiveにrootの値を辿っていくときに、sum -= root.valとしてsumを減じていき、sum == root.valとなればTrueを返す、それがないまま末端のrootまで到達してしまったらFalseを返す、という処理。

```python
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def hasPathSum(self, root: TreeNode, sum: int) -> bool:
        if not root:
            return False
        if not root.left and not root.right and root.val == sum:
            return True
        sum -= root.val
        return self.hasPathSum(root.left, sum) or self.hasPathSum(root.right, sum)
```

##### 解法2
Iterativeな解法。
Iterationを回す過程で、(root, root.val)のタプルの形式で変数stackに格納しつつ、curr, val = stack.pop()で先にstackに格納されたタプルを取り出し、valがsumと同値かどうか判定します。

```python
class Solution:
    def hasPathSum(self, root: TreeNode, sum: int) -> bool:
        if not root:
            return False
        stack = [(root, root.val)]
        while stack:
            curr, val = stack.pop()
            if not curr.left and not curr.right:
                if val == sum:
                    return True
            if curr.right:
                stack.append((curr.right, val+curr.right.val))
            if curr.left:
                stack.append((curr.left, val+curr.left.val))
        return False
```
【Cisco】IPSec設定時のshowコマンド

#はじめに
CiscoルータでIPSecの設定を行う際には多くの設定が必要となり、
要件にあわせて適切に設定する必要がある。
本記事ではIPSec設定時に不可欠となる確認コマンドを掲載する。

#コマンド
・ISAKMP SAの確立を確認をしたい
show crypto isakmp sa

・ISAKMPポリシーの確認をしたい
(algorithm/hash/group…など)
show crypto isakmp policy

・IPSecトランスフォームセットの確認がしたい
show crypto transform-set

・暗号化マップの確認がしたい
show crypto map

・IPSec SAの確立を確認したい
show crypto session

一通りの設定確認が終わったらpingにて疎通が確認できるとなおよい。
(途中経路でpingがFWポリシーなどで遮断されている場合、pingによる疎通確認はできないが…。)

#おわりに
show crypto ?連打で乗り切ってきた自分に対する自戒もこめて本記事を掲載した。
適切に設定値を確認しながら動作状況を把握することで、疎通不良の予防に繋がるため必要に応じてコマンドによる確認を行っていきたい。
【Linux】awkでログに含まれる数値を集計及び平均する方法

###ログから数値を抽出し、集計します。
以下のログファイルのspendtimeを集計します。

```test.log
2019/08/06 22:31:00.300 KEY0 spendtime:5ms
2019/08/06 22:31:01.300 KEY1 spendtime:6ms
2019/08/06 22:31:02.300 KEY2 spendtime:7ms
2019/08/06 22:31:03.300 KEY0 spendtime:1ms
2019/08/06 22:31:04.300 KEY1 spendtime:2ms
2019/08/06 22:31:05.300 KEY2 spendtime:3ms
2019/08/06 22:31:06.300 KEY0 spendtime:100ms
2019/08/06 22:31:07.300 KEY1 spendtime:23ms
2019/08/06 22:31:07.300 KEY2 spendtime:12ms
```

まずは、数値を抽出する必要があります。
awk -f '[ :]でセパレータを指定しています。

```test.log
[test@localhost ~]$ cat test.log | awk -F'[ :]' '{print $7}'
5ms
6ms
7ms
1ms
2ms
3ms
100ms
23ms
12ms
```

msをカットします。

```test.log
[test@localhost ~]$ cat test.log | awk -F'[ :]' '{print substr($7,1,length($7)-2)}'
5
6
7
1
2
3
100
23
12
```

変数sumで集計し、最後にsumをプリントします。

```test.log
[test@localhost ~]$ cat test.log | awk -F'[ :]' '{sum+=substr($7,1,length($7)-2)} END {print sum}'
159
```

平均はNRでsumを割ります。

```test.log
[test@localhost ~]$ cat test.log | awk -F'[ :]' '{sum+=substr($7,1,length($7)-2)} END {print sum/NR}'
17.6667
```
ComposerでPlease provide a valid cache pathとなったときの対応方法

- 環境
    - Windows10 bit64
    - Laravel Framework 5.5.40
    - PHP 7.3.7 (cli)


# 事象 : composerでインストールしたら何かお願いされた

```bash
$ composer install
#... 省略 ...
In Compiler.php line 36:

  Please provide a valid cache path.


Script @php artisan package:discover handling the post-autoload-dump event returned with error code 1
```

## 原因 : `strage/framework`ディレクトリ配下にstorage_pathで設定されているディレクトリがないから
- 参考
    - [Please provide a valid cache path. - Laravel5開発](https://umebius.com/laravel/please-provide-valid-cache-path/)
    - [laravel - Please provide a valid cache path - Stack Overflow](https://stackoverflow.com/questions/38483837/please-provide-a-valid-cache-path)

```bash
$ find storage/framework/ -type d
storage/framework/
storage/framework/aop
storage/framework/aop/compile
```

### 対応 : 設定されているディレクトリを作成する
```bash
# configディレクトリからstorage_pathで設定している値を確認して
$ find config/ -type f | xargs grep storage_path | grep framework
config/cache.php:            'path' => storage_path('framework/cache/data'),
config/iwrsAspect.php:                'compile_dir' => storage_path('framework/aop/compile'),
config/iwrsAspect.php:                'cache_dir' => storage_path('framework/aop/cache'),
config/session.php:    'files' => storage_path('framework/sessions'),
config/view.php:    'compiled' => realpath(storage_path('framework/views')),

# ないディレクトリを作成する
$ mkdir -p storage/framework/cache/data/
$ mkdir -p storage/framework/aop/cache
$ mkdir -p storage/framework/sessions
$ mkdir -p storage/framework/views
```
File exists, 今日のshell error(42)

計算物理学
https://qiita.com/kaizen_nagoya/items/af924f5ac71ff5cc8c89

のdocker内で実行するshell scriptを作成中。

今日のshell error

```shell-session:docker/ubuntu
# ./mkall.sh
mkdir: cannot create directory ‘cp’: File exists
./mkall.sh: line 11: syntax error near unexpected token `('
./mkall.sh: line 11: `mkdir VisualCodes(old)'
# ./mkall.sh
mkdir: cannot create directory ‘cp’: File exists
cp: cannot stat 'urltext0.txt': No such file or directory
../../wgeturl.sh: line 5: ./urllist.txt: No such file or directory
./mkall.sh: line 29: cd: cp/HPCodes: No such file or directory
```

最初のはフォルダ名で(を使うにはescape sequenceを使わないといかなかったからかも。

ややこしいフォルダ名はやめることにした。URLと全く一緒にする必要はなさそうだから。

次のFile existsは、さっきmkdir 実行してすでにあるから。

次のNo such file or directoryは名前を間違えてた。

その次のNo such file or directoryは、一つ前で名前を間違えていたのでcpできてないため。
# Reference
Error一覧 error(0)
https://qiita.com/kaizen_nagoya/items/48b6cbc8d68eae2c42b8

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.
### 文書履歴(document history)
ver. 0.01 初稿 　20240504
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
ShellScript基礎

#これはなに
ShellScriptの基礎的な部分のメモを残す。

##特殊変数
```sh
#./test a aa aaa
#実行ファイル名
echo $0 
#引数の数
echo $# #3
#引数全て
echo $@ # a aa aaa
#引数全て
echo $* # a aa aaa 
```

##ユーザー入力

```sh
#read という命令を使い、ユーザーから1行の入力を受け取ってnameに格納
read name
echo "hello $name"
read -p "Name: " name
echo "hello $name"

#複数の値を一気に複数の変数に割り当てる
read -p "Pick 3 colors: " c1 c2 c3
echo $c1
echo $c2
echo $c3

```

##配列

```sh
#配列変数定義
colors=(red blue pink)
echo ${colors[0]} #red
echo ${colors[1]} #blue
echo ${colors[2]} #pink

#配列要素全ての出力
echo ${colors[@]} #red blue pink
echo ${#colors[@]}

#配列の要素編集
colors[1]=silver

#配列の要素追加
colors+=(green orange)
echo ${colors[@]}
```
Vue.jsとAPIサーバとのaxiosでCORSに引っかかった時のProxyを使った回避方法 

## 最初に
開発環境にて
Vue.jsでバックエンドのAPIをaxiosで叩こうとした時、
Policyで引っかかってしまうことがあります。

```
Access to XMLHttpRequest at 'http://localhost:3000/api/test' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource
```

## 問題点

Originが違うため、ブラウザでアクセスが拒否されます。

```
(example)Originが違う
Vue.js:http://localhost:8080
Golang:http://localhost:3000
```

## 解決方法
1. CORSを設定する
[CORSについて](https://qiita.com/tomoyukilabs/items/81698edd5812ff6acb34)
サーバ側で、Originを許可する必要があります。

2. **proxy**を使って、回避します。



今回は2.のPROXYを使った解決方法をご紹介します。
2.のメリット
- ドメインをよしなに設定できるため、向き先を自由に変更できます
- ``` axios.get('/api').then() ``` のように、ドメインを指定する必要がないので、開発環境でも本番環境でもコード修正の必要がありません。
- 本番環境(Build)には影響しません

## Proxyを使う

```
(example)Originが違う
Vue.js:http://localhost:8080
Golang:http://localhost:3000
```
の場合、

Vue.js側のroot階層で
***vue.config.js***を作成します

```js:vue.config.js
module.exports = {
  devServer: {
    proxy: {
      "/api/": {
        target: "http://localhost:3000",
      }
    }
  }
};
```

このように書いておくと、

```js
axios.get("/api/test").then(res=>{
    console.log(res.data)
})
```

Golang側の``` /api/** ```にアクセスする時、向き先を**http://localhost:3000**に変更します。

これで、policyを回避できます。

## おまけ
こんな感じで書いておくと、env設定で向き先を自由に変更ことができます！

``` js
module.exports = {
  devServer: {
    proxy: {
      "/api/": {
        target:  process.env.USE_LOCAL_SERVER ? 'http://localhost:3000' : 'http://aaa.com',
      }
    }
  }
};
```
artisanコマンドでXdebug could not open the remote debug file '\tmp\xdebug.txt'となったときの対応方法

- 環境
    - Windows10 bit64
    - Laravel Framework 5.5.40
    - PHP 7.3.7 (cli)

# 事象 : artisanコマンドを打ったら怒られた
```bash
$ php artisan --version
Xdebug could not open the remote debug file 'C:\path\to\php-7.3.7-Win32-VC15-x86\tmp\xdebug.txt'.
```
## 原因 : リモートログ用に指定したディレクトリがないから
php.iniで[xdebug.remote_log](https://xdebug.org/docs/all_settings)に指定したディレクトリがないから。

```bash
$ grep xdebug.remote_log php.ini
xdebug.remote_log="C:\path\to\php-7.3.7-Win32-VC15-x86\tmp\xdebug.txt"
```

### 対応 : tmpディレクトリを作る
```bash
$ cd /c/path/to/php-7.3.7-Win32-VC15-x86
$ mkdir tmp
```
Windows10+Neovim+vim-plug環境構築

# Windows10 + Neovim + vim-plug環境構築

## 概要

Windows10でNeovim+vim-plugの環境構築をするための手順のまとめです。

## Neovimインストール

Windows版のNeovimはpre-builtなバイナリを使います。
[公式のインストールガイド](https://github.com/neovim/neovim/wiki/Installing-Neovim#pre-built-archives)に従い、[このあたり](https://github.com/neovim/neovim/releases)からダウンロードしましょう。
※Chocolateyでインストールもできるようです。

## vim-plugをインストール

[インストール手順](https://github.com/junegunn/vim-plug#windows-powershell-1)に従い、PowerShellで以下を実行。

```powershell
md ~\AppData\Local\nvim\autoload
$uri = 'https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
(New-Object Net.WebClient).DownloadFile(
  $uri,
  $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(
    "~\AppData\Local\nvim\autoload\plug.vim"
  )
)
```

## 設定ファイルを作成

NeovimのWindows版では設定ファイルは`%USERPROFILE%\AppData\Local\nvim\`に置きます。
先にディレクトリを作っておきます。

```
mkdir %USERPROFILE%\AppData\Local\nvim
```

Neovimで

```
:e ~/AppData/Local/nvim/init.vim
```

設定ファイルを作成して、以下のように設定。

```vimscript
call plug#begin('~/.vim/plugged')

" 入れたいプラグインを書いていく
Plug 'iamcco/markdown-preview.nvim', { 'do': { -> mkdp#util#install() } }

call plug#end()
```

保存してNeovimを再起動、以下のコマンドを実行してプラグインをインストールする。

```
:PlugInstall
```

## その他の設定など

その他の設定方法などは[こちらの記事](https://qiita.com/akiya64/items/169d202700a4ffefe407)がわかりやすいです。
firebase functionsの諸々の設定方法

備忘録

## リージョンの設定方法

functionsのregionを使用する

```ts
functions.region('asia-northeast1')
```

## スペックの指定方法

functionsのrunWithでmemoryを設定する
[Cloud Functions の料金](https://cloud.google.com/functions/pricing?hl=ja)にメモリ、CPU、料金の対応表がある

```ts
functions.runWith({ memory: '2GB' })
```

## クライアントSDKから直接Cloud Functions for Firebaseを呼び出す場合の指定方法

cloud functions側ではonCallを使う

```ts
export const func = functions.https.onCall((data, context) => {
  console.log(data.hoge) // クライアント側が下記の記述の場合にはhoge
})
```

クライアント側はhttpsCallableを使う

```ts
const func = firebase
    .app()
    .functions('asia-northeast1')
    .httpsCallable('func')

await func({ hoge: 'hoge' })
```
【EC-CUBE4】⑦EC-CUBE本体の開発環境を整える（PHPUnit編）

EC-CUBE4の環境構築続きです。
[【EC-CUBE4】①EC-CUBE本体の開発環境を整える（インストール編）](https://qiita.com/junpeko5/items/199af36a31a335a73d38)
[【EC-CUBE4】②EC-CUBE本体の開発環境を整える（GitHub Flow編）](https://qiita.com/junpeko5/items/8706a91452e85eef5109)
[【EC-CUBE4】③EC-CUBE本体の開発環境を整える（MYSQL,MailCatcher編）]
(https://qiita.com/junpeko5/items/3316b654b4b80ee59376)
[【EC-CUBE4】④EC-CUBE本体の開発環境を整える（Postgres,MailCatcher編）]
(https://qiita.com/junpeko5/items/ef572490c44da90eac59)
[【EC-CUBE4】⑤EC-CUBE本体の開発環境を整える（Xdebug、PhpStorm編）](https://qiita.com/drafts/890e6b73b0e1f9930093)
[【EC-CUBE4】⑥EC-CUBE本体の開発環境を整える（Codeception編）](https://qiita.com/junpeko5/items/f593f20adc19c4208f71)

## 前提条件

- Mac
- .phpenvでphp7.2.8がインストール済み
- EC-CUBE4がローカル環境にインストール済み（<a href="https://qiita.com/junpeko5/items/199af36a31a335a73d38">【EC-CUBE4】①EC-CUBE本体の開発環境を整える（インストール編）</a>が終わっていること）
- Postgres、Mailcatcherがローカル環境で利用できること（<a href="https://qiita.com/junpeko5/items/ef572490c44da90eac59">【EC-CUBE4】④EC-CUBE本体の開発環境を整える（Postgres,MailCatcher編）</a>が終わっていること）
- [【EC-CUBE4】⑤EC-CUBE本体の開発環境を整える（Xdebug、PhpStorm編）](https://qiita.com/drafts/890e6b73b0e1f9930093)が終わっていること。

今回、DBはPostgresがローカル環境で動作している状態でテストを行います。

```
$ docker ps
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                                            NAMES
59ca43ad1f56        schickling/mailcatcher   "mailcatcher --no-qu…"   13 hours ago        Up 13 hours         0.0.0.0:1025->1025/tcp, 0.0.0.0:1080->1080/tcp   docker-postgres_mailcatcher_1
92fdda3109f5        postgres:10.9            "docker-entrypoint.s…"   13 hours ago        Up 13 hours         0.0.0.0:5432->5432/tcp                           postgres_container
```


## PHPUnitの実行

テストの実行は以下のコマンドです。

```
$ cd <EC-CUBEがインストールされているディレクトリ>
$ vendor/bin/phpunit 
```
tests以下の全てのテストを実行します。

## ファイルを指定して実行する

特定のファイルを実行したい場合は、ファイルのパスを指定します。

```
$ vendor/bin/phpunit tests/Eccube/Tests/Service/PurchaseFlow/Processor/StockReduceProcessorTest.php
```

## メソッドを指定して実行する

特定のメソッドを実行したい場合は`--filter`オプションを利用し、正規表現で表します。

```
$ vendor/bin/phpunit --filter "/(::testRollback)( .*)?$/" tests/Eccube/Tests/Service/PurchaseFlow/Processor/StockReduceProcessorTest.php
```

## PhpStormで実行する

PhpStormで実行すると、かなり快適にテストが実行できるようになります。
<img width="1140" alt="スクリーンショット 2019-08-06 22.43.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166768/bfd0189f-aa7b-1fa1-f6a9-adc29c94fecc.png">

メソッドの左側にある実行マークを押すと下図のようになり、テストの実行をかんたんに行うことができます。

<img width="1618" alt="スクリーンショット 2019-08-06 22.46.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166768/b0db16da-bc78-efb5-e3a5-d6718ade1984.png">

Xdebugでテストコードを追うことも可能です。

<img width="1313" alt="スクリーンショット 2019-08-06 22.47.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166768/f76f4b0f-3a29-442a-3d16-f3d771afbf9d.png">



## 参考

http://doc4.ec-cube.net/plugin_test
https://phpunit.readthedocs.io/ja/latest/
Leetcode #840: Magic Squares in Grid

```swift
func numMagicSquaresInside(_ grid: [[Int]]) -> Int {
    var count = 0
    for i in stride(from: 0, through: grid.count-3, by: 1) {
        for j in stride(from: 0, through: grid[0].count-3, by: 1) {
            if grid[i+1][j+1] != 5 {
                continue
            }
            let set = Set([grid[i][j], grid[i][j+1],grid[i][j+2],grid[i+1][j],grid[i+1][j+1],grid[i+1][j+2],grid[i+2][j],grid[i+2][j+1],grid[i+2][j+2]])
            if set != Set(1...9) {
                continue
            }
            let subgrid = [[grid[i][j], grid[i][j+1],grid[i][j+2]],
                           [grid[i+1][j],grid[i+1][j+1],grid[i+1][j+2]],
                           [grid[i+2][j],grid[i+2][j+1],grid[i+2][j+2]]]
            if isMagic(subgrid) {
                count += 1
            }
        }
    }
    return count
}

private func isMagic(_ grid: [[Int]]) -> Bool {
    return grid[0][0] + grid[0][1] + grid[0][2] == 15 &&
        grid[1][0] + grid[1][1] + grid[1][2] == 15 &&
        grid[2][0] + grid[2][1] + grid[2][2] == 15 &&
        grid[0][0] + grid[1][0] + grid[2][0] == 15 &&
        grid[0][1] + grid[1][1] + grid[2][1] == 15 &&
        grid[0][2] + grid[1][2] + grid[2][2] == 15 &&
        grid[0][0] + grid[1][1] + grid[2][2] == 15 &&
        grid[0][2] + grid[1][1] + grid[2][0] == 15
}
```
Atcoder のA問題をn=20問といてみた[#2]

# 内容
_#1の続き。abc_a問題を解いてない100問ぐらいを対象に順番に解いていく。

実験の待ち時間にちょこちょこやっていたのだが、案外時間がないことを意識して余計なことを考えずにやると意外に進んだ。（前回は記事書きながらやったから時間がかかった面は否定できないが）

同じような問題が続き、流石に飽きてきたので、shortest codeを意識して（結局１つも取れなかったけど）遊びながら書いていた。

[AtCoderProblem](https://beta.kenkoooo.com/atcoder/?user=&kind=user#/user/knk_kei)のスクショを載せておきます。

これをみると登録から全然精進してないのがわかりますね。。
<img width="1330" alt="スクリーンショット 2019-08-06 22.20.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253261/bfd64e70-daa8-d734-c288-c06a8e1f28d6.png">

簡単に各問題の感想を（少し抜けてますが）書いていきます。
##abc022_a.py

##abc025_a.py
文字列順に出力する。
5で割ったあまりと5で割った商を出力する

n-1で割った時の値にしないとダメね。

##abc026_a.py
x+y=Aとなるx、yのうち、x*yが最大となるもののxyを求める。
x(a-x)を微分すると、a/2で極大値をとる。
aは偶数という制約があるのでa/2**2を出力すれば良い。

##abc029_a.py
末尾に"s"をつける。input()+"s"でいい。
##abc030_a.py
２つの割り算の大きさの比較

```a.py
a,b,c,d = map(int,input().split())
if b/a > d/c :
  print('TAKAHASHI')
elif b/a == d/c:
  print('DRAW')
else:
  print('AOKI')
```

##abc031_a.py
２つの積の大きさ比較

```a.py
a,d= map(int,input().split())
if a <= d:
  print((a+1)*d)
else:
  print(a*(d+1))
```

##abc032_a.py
n 以上で最小のa,bの公倍数
再起を使う問題は出ないだろうと思ったので、ループを回しました。

```a.py
a = int(input())
b = int(input())
n = int(input())
for i in range(n,n+a*b):
  if i %a == 0 and i%b == 0:
    print(i)
    break
```

`a,b,n=[int(input())for _ in'___']`
で複数行の入力を受け取れるんですね。
答えを変数に保管しておく方が綺麗なコードっぽいですね。

##abc034_a.py
比較してifぶん
##abc035_a.py
同じ。比較してif文
同じような問題が続くのは時ごとにテーマがあるのかな？

##abc036_a.py
末尾が”T"かどうかを判定する。
##abc043_a.py
1+2+..+nを出力する。階差数列懐かしい。
`n = int(input());print((n+1)*n//2)`

#感想
なかなか、時間を置いてから解説を書こうと思うと難しい。
短いコードを書くには、eval や"YNEOS"を使うなどの凝った工夫をしないと難しい。
ただ、色々発見があって楽しいので、shortest codeを取れないにしても、飽きがきている人にはいいかも。
【Python】リストで利用できるメソッド

# はじめに
Pythonのリストで利用できるメソッドをまとめる。
新しく学んだら随時更新する。

# 並び替えメソッド
## sort()メソッド
リストの並び替えを行うメソッド。
昇順・降順に並び替えられ、ソート順をカスタマイズすることもできる。
以前、こちらにまとめたので今回は省略。こちらを参照。
[Pythonのsort()メソッド](https://qiita.com/chii-08/items/e0dd17e8f83fcf1b72d8)

## reverse()メソッド
リストを逆順にソートする。

```Python:例
#リストheightを逆順にソートする
hight = [48, 65, 53, 90, 60]
hight.reverse()
print(hight) # => [60, 90, 53, 65, 48]
```

# 削除メソッド
##remove()メソッド
指定した値と同じ要素を検索し、**最初の要素を削除**する。

```Python:例
#リストfruitsから要素"peach"を削除する。
fruits = ['apple', 'peach', 'banana', 'orange']
fruits.remove("peach")
print(fruits) # => ['apple', 'banana', 'orange']

#指定した値が２つ以上ある場合も最初の要素のみ削除される。
fruits = ['apple', 'peach', 'banana', 'orange', 'peach']
fruits.remove("peach")
print(fruits) # => ['apple', 'banana', 'orange', 'peach']
```

##pop()メソッド
指定したインデックスの要素を削除する。

```Python:例
#fruits[1]を削除する。
fruits = ['apple', 'peach', 'banana', 'orange']
fruits.pop(1)
print(fruits) # => ['apple', 'banana', 'orange']
```

##clear()メソッド
リストの全ての要素が削除される。

```Python:例
#リストfruitsの要素を全てを削除する。
fruits = ['apple', 'peach', 'banana', 'orange']
fruits.clear()
print(fruits) # => []
```

#追加メソッド
##append()メソッド
リストの**最後に**指定した値を追加する。

```Python:例
#リストfruitsの最後に"lemon"を追加する。
fruits = ['apple', 'peach', 'banana', 'orange']
fruits.append("lemon")
print(fruits) # => ['apple', 'peach', 'banana', 'orange', 'remon']
```

##extend()メソッド
リストの最後に、リストやタプルを追加する。

```Python:例
#リストを追加する。
fruits = ['apple', 'peach', 'banana']
fruits.extend(['lemon', 'strawberry'])
print(fruits) # => ['apple', 'peach', 'banana', 'lemon', 'strawberry']

#タプルを追加する。
fruits = ['apple', 'peach', 'banana']
fruits.extend(('lemon', 'strawberry'))
print(fruits) # => ['apple', 'peach', 'banana', 'lemon', 'strawberry']

```
#検索メソッド
##index()
リストから指定した値を検索し、最初に見つかった要素のインデックスを返す。

```Python:例
#リストfruitsから'banana'を検索し、そのインデックスを返す。
fruits = ['apple', 'peach', 'banana', 'orange']
print(fruits.index('banana')) # => 2
```

#参考サイト
[Python3.7.4](https://docs.python.org/ja/3/tutorial/datastructures.html)
Python入門 変数、数値、文字列、型変換

# 変数
変数とは何らかのオブジェクトをある文字列にいれることをさします。なぜ変数が必要なのか説明していきます。例をあげると選挙のアプリを作るとします。ずいぶん前ですが選挙に行ける年齢が２０歳から１８歳になりましたね？こういう時に使われるのです。２０際から参加できるようなプログラムを作ったとします。１８才に変更した時にいちいち全てのプログラムを２０から１８に変更するのはめんどくさいですよね？そういう時にa=２０として変更したい時にa=18に変更したらこれだけの変更でプログラム全てに変更ができます。
変数の定義の仕方は

```py
a = 18
```
これを出力したいのならprintメソッドを使います。

```py
print(a)
#実行結果
18
```

#数値
数値には主に整数、浮動小数点数の二つがあります。これらを演算子（足し算とか引き算諸々）を使っていろんなことをしていきます。

|意味|演算子|　例　|結果|
|:----|----:|------:|----:|
|足し算|+|8+5|13|
|引き算|-|8-5|3|
|掛け算|*|8*5|40|
|割り算（浮動小数点数）|/| 8/5|1.8|
|割り算（切り捨て）|// |8//5|1|
|指数|　** |8**5|32768|
実行してみると
<img width="770" alt="スクリーンショット 2019-08-06 11.29.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477641/88295903-8fdc-5613-f18d-5403b6f0227a.png">
このような結果になります。注意点として数字の前には０を入れてはいけない。

```py
print(05)
# 実行結果
    print(05)
           ^
    SyntaxError: invalid token
```

#文字列
python３はUnicodeを標準サポートとしていますので、世界中の色々な言語を使うことができる。Pythonの文字列はイミュータブルである。イミュータブルというのは置き換えられないオブジェクトのことを言います。だがコピーすることによって文字列の変更は可能になる。
##クオートを使った文字列の作成
Pythonにはシングルクオートとダブルクオートの二つがある。なぜこの二つがあるかというと、例えば　We're living in Japanという文字列を打つとしよう。これをシングルクオートで囲むとどうなるか。

```py
print('We're living in Japan')
# 実行結果
File "<stdin>", line 1
    print('We're living in Japan')
               ^
SyntaxError: invalid syntax
```
このようにエラーが出ます。その原因がシングルクオートで囲んだためWe'の時点で繋いでしまっていたのです。そうなると残りのre living in Japanは何も繋いでいないことになる。これwp防ぐためにダブルクオートというものが存在する。

```py
print("We're living in Japan")
# 実行結果
We're living in Japan
```

とエラーなく文字列を打つことが可能になる。

# 型変換
## データ型を文字列に変更
str()を使用します。

```py
print(str(10))
# 実行結果
'10'
```
stringは文字列という意味だ。
## データ型を数値に変更

```py
print(int(True))
# 実行結果
1
```
Integerは数値という意味だ。
となる。ちなみに`True`を数字化すると`1`になり`False`を数値化すると`0`になる。ここで注意してほしいことがある。それは小数点を含む数字は型変換ができないということだ。そのことを注意してやってみましょう。
WordPress 一覧／記事ページで前次ページへのリンクがない場合、非表示にする方法

WordPressのカスタマイズでタグをググりまして、
情報が全然出てこなくて苦労した解決方法をメモしておきます 🙂

投稿一覧ページで前ページ／次のページへリンクするカスタマイズです。

# 記事ページで前次ページがない場合リンクを非表示

「previous_post_link／next_post_link」を使います。

```php:php

<?php if (get_previous_post()):?>
<div class="p-pagenavi -prev">
<?php previous_post_link('前へ'); ?>
</div>
<?php endif; ?>

<?php if (get_next_post()):?>
<div class="p-pagenavi -next">
<?php next_post_link('次へ') ?>
</div>
<?php endif; ?>
```

# 一覧ページで前次ページがない場合リンクを非表示

「previous_posts_link／next_posts_link」を使います。
記事ページ記事ページとの違いは…よーく見ると「post」と「posts」の違い。

条件分岐はsをつけるだけじゃなく、
get_previous_post→get_previous_posts_linkです。

「post」と「posts」の違い
末尾に「_link」追加の違いがあります。

```php:php

<?php if( get_previous_posts_link() ) :?>
<div class="p-pagenavi -prev">
<?php previous_posts_link('前へ'); ?>
</div>
<?php endif; ?>

<?php if( get_next_posts_link() ) :?>
<div class="p-pagenavi -next">
<?php next_posts_link('次へ'); ?>
</div>
<?php endif; ?>
```

メモっておけば簡単。
こちらでカスタマイズ自由度がかなり上がります💪


#参考URL
https://codex.wordpress.org/Function_Reference/previous_posts_link
irisを樹状図で見る【R, rpart】

極めて短く備忘録的なものを。
データが複雑に入り組んでいるとき、どのデータが多いのか、
値が何以上のものが何個くらいありそうなのか調べたかったけど
なかなかrpartが検索しても出てこなかったので自分用に残す。

```R
library(rpart)
library(rpart.plot)

model=rpart(Species~.,data=iris)

rpart.plot(model)

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/5bc89f70-dfa7-4f7a-90ca-544975dad657.png)


#以上
たまにはこういうメモも書こうかと。
Leetcode #155: Min Stack

```swift
class MinStack {
    private var numStack = [Int]()
    private var minimumStack = [Int]()
    
    func push(_ x: Int) {
        numStack.append(x)
        if minimumStack.isEmpty {
            minimumStack.append(x)
        } else {
            minimumStack.append(min(x,minimumStack.last!))
        }
    }
    
    func pop() {
        guard !numStack.isEmpty && !minimumStack.isEmpty else {
            return
        }
        numStack.popLast()
        minimumStack.popLast()
    }
    
    func top() -> Int {
        guard !numStack.isEmpty else {
            return -1
        }
        return numStack.last!
    }
    
    func getMin() -> Int {
        guard !minimumStack.isEmpty else {
            return -1
        }
        return minimumStack.last!
    }
}
```
JavaScript コンソール に 文字 を 出力する 〜console.log("Hello World");〜

# 目的
- JavaScriptの基礎であるコンソールに文字を出力する方法をまとめる。

# 押さえるポイント
- コンソールに文字列を出力するときは`console.log("表示したい文字列");`とする。
- 表示したい文字列をカッコ内にシングルクオートかダブルクオートで囲んで書く。
- 最後にセミコロンを忘れずに。
- コメントアウトはスラッシュを二つ

# 書き方の例
- 「○○○」は表示したい文字列が入る
- 下記にJavaScriptファイルの内容を記載する。

``` javascript
//これはコメントです。処理には関係ありません。
console.log("○○○");
```

# より具体的な例
- コンソールに「こんにちは」と表示するコードを書く。
- コードの説明をコメントで記載する
- 下記にJavaScriptファイルの内容を記載する。

``` javascript
//これはコンソールに「こんにちは」と出力するコードです。
console.log("こんにちは");
```
AWS CloudHSMのオンラインセミナー受けてみた

「[AWS Black Belt Online Seminar AWS CloudHSM](https://www.slideshare.net/AmazonWebServicesJapan/20190723-aws-black-belt-online-seminar-aws-cloudhsm)」の自分向けメモ
暗号化技術は分かるけど、AWS CloudHSMって何？......レベルの人向け


## 暗号化技術概要
### 共通鍵暗号
 - 高速に暗号化、復号化可能
 - AESが代表的な暗号方式
 - S3、EBSで利用されている

### 公開鍵、秘密鍵暗号
 - 共通鍵より処理が重い
 - RSA方式が代表的なアルゴリズム

### SSL/TLS
 - 上記2つの併用
 - クライアント⇒サーバーにサーバー証明書で暗号化したクライアントの共通鍵を送る
 - その後の通信は共通鍵で双方暗号化して行う

### 管理の重要性
 - 暗号鍵の安全な保管とアクセス管理が重要な課題
 - 暗号鍵管理のインフラストラクチャーを利用するのが一般的

## AWSにおける暗号鍵管理
### KMSとHSM
 - KMS（暗号鍵へのアクセス、アクセス制御）
    - マルチテナント
    - 共通鍵のみ
 - HSM（暗号鍵の保管庫）
    - シングルテナント：ハードウェア占有型暗号鍵管理サービス
    - 共通鍵と公開鍵


## 機能とユースケース
### HSMとは
 - 鍵の不正利用を防ぎ、外部から鍵がアクセスできないようにする
 - PVC内サービス、VPC外からの場合はルーティングが必要
 - 異なるリージョンからアクセス不可
 - 異なるAZにクラスター構成され、バックアップイメージをS3に保管
 - FIPS140-2のレベル3認証
    - 物理的な改ざんへの耐性をもつ
    - 筐体を無理やり開けようとするとデータがゼロリセットされる
    - 外からの電磁波、中からの電磁波の漏れにも対応
 - Non-Exportableの設定が可能

### ユースケース
 - KMSのカスタムキーストアとして利用
 - SSL/TLS暗号化
 - CA局の秘密鍵管理
 - ファイル等のデジタル署名 

### KMSとの連携
- レベル3でKMSのカスタマーマスターキーを保管でき、KMSの機能はそのまま使える
- KMSではマルチテナントでハードウェアを使っている


## 管理と運用
 - AWSコンソールから操作可能
 - HSMに対する操作権限はIAMとは別
    - ハードウェアの中のユーザーに権限が振られる
 - イニシャライズはCLIから

### クォーラム認証
 - 複数の認証されたユーザーが承認しないと操作ができないモード

### クラスター管理
 - メトリクスで稼働を確認可能
 - オートスケールではないので、手動で追加すること
 - 最低限24時間に1回のバックアップ取得
 - リストアはバックアップを取得したクラスターにしかリストアできない
 - 災害対策のために、別リージョンへのコピーが可能

### ログと監査
 - CludTrail
 - メトリクス
 - クライアントログ
 - CloudWatch Logs

## まとめ
 - 手間のかかるHSMの準備と提供をオンデマンドかつ従量課金で提供
 - KMSとの使い分け
    - FIPS140-2 Level3対応のHSMが必要な場合
    - CA局として大量の暗号化復号化処理が必要な場合
 - KMSのキーストアの強靭化を図れる
 - AWSマネジメントコンソールとCLIの併用が必要
 - リージョンをまたいだバックアップは不可
 - 手動操作によるバックアップとリストアが必要
Leetcode #299: Bulls and Cows

```swift
func getHint(_ secret: String, _ guess: String) -> String {
    var secret = Array(secret)
    var guess = Array(guess)
    var secretDict = [Character: Int]()
    var guessDict = [Character: Int]()
    var bulls = 0
    var cows = 0
    for i in stride(from: 0, to: secret.count, by: 1) {
        if secret[i] == guess[i] {
            bulls += 1
        } else {
            if let value = secretDict[secret[i]] {
                secretDict[secret[i]] = value + 1
            } else {
                secretDict[secret[i]] = 1
            }
            if let value = guessDict[guess[i]] {
                guessDict[guess[i]] = value + 1
            } else {
                guessDict[guess[i]] = 1
            }
        }
    }
    for key in secretDict.keys {
        if let value = guessDict[key] {
            cows += min(secretDict[key]!, value)
        }
    }
    return "\(bulls)A\(cows)B"
}
```
Leetcode #367: Valid Perfect Square

```swift
func isPerfectSquare(_ num: Int) -> Bool {
    var root = 1
    while true {
        let square = root * root
        if square == num {
            return true
        } else if square > num {
            break
        }
        root *= 2
    }
    for i in stride(from: root / 2 - 1, to: root, by: 1) {
        if i * i == num {
            return true
        }
    }
    return false
}
```
ASP.NET MVCとは

## Web Formの問題点

### 単体テストを自動化しづらい
Webフォームは基本的にPagesクラス
を中心にしたFWであるためPagesクラスを直接インスタンス化できないのでテストにあたりサーバ環境の準備が必要になる。
また、イベントハンドラが原則としてUIから呼び出されてしか動かないこともテストの自動化を妨げる要因

### Web Form 固有の概念が多い
サーバコントロール、イベントどぶリン、ポストハック、ビューステートなどの固有の概念が慣れてないとハードルになる

### 出力の制御が難しい
サーバーコントロールの目的は、出力をブラックボックス化することだが、細かな出力の制御が難しい

## ASP.NET MVCの特徴

### MVCを採用

|要素 |概要
|---|---|
|Model|データベースのアクセス、データ処理、ビジネスロジック。UI変更の影響を受けずらい
|View|UI.データの入出力フォームや処理結果の表示などフロントエンド|
|Controller|ModelとViewの仲介。ViewからのデータをModelに渡し、Modelでの処理結果をViewに渡す|

### フロントコントローラーを採用

個々のページでリクエストを受け、処理結果もページからクライアントに返す方式をページコントローラーとよぶ。
対してAPS.NET MVCではフロントコントローラー方式を採用する。
フロントコントローラーとはクライアントからのリクエストをまずフロントコントローラーで受けて、それから各クラスへ振り分ける方法のこと。
また、リクエストURLに応じた処理の受け渡し先を決定することを*ルーティング*とよぶ。

### 単体テストを自動化しやすい
各クラスがインスタンス化できるので単体テストが容易

### サーバーコントロールを利用しない
イベントドブリンやポストバック、ビューステートという概念がなく、コード埋め込みのアノテーションを利用してHTMLを出力する。

### Webフォームの知識を生かせる
セクションやクッキー、キャッシュといった基本的な機能の大部分ではASP.NETの知識を流用できる。

## APS.NET MVCの主な機能

- ルーティング
- 認証やキャッシュ、例外処理などのフィルター
- 入力データを処理するモデルバインド
- コントローラーの処理結果を管理するActionResultオブジェクト
- ビュー開発を効率化する種種のヘルパーメソッド
- アプリケーションの骨格を自動生成するScaffolfing機能
Leetcode #459: Repeated Substring Pattern

```swift
func repeatedSubstringPattern(_ s: String) -> Bool {
    let str = Array(s)
    for i in stride(from: 1, through: s.count / 2, by: 1) {
        if str.count % i != 0 {
            continue
        }
        if isRepeated(i, str.count / i, str) {
            return true
        }
    }
    return false
}

func isRepeated(_ length: Int, _ count: Int, _ s: [Character]) -> Bool {
    for i in stride(from: 0, to: length, by: 1) {
        for j in stride(from: 1, to: count, by: 1) {
            if s[i] != s[i+length*j] {
                return false
            }
        }
    }
    return true
}
```
VBAでセルの先頭に文字列挿入

#はじめに
初めまして。駆け出しエンジニアです。
備忘録も兼ねて投稿していきます。
今回はVBAの簡単なコードを書いたので載せていきます。

#コードの内容
Excelのシート内のデータで日付、数値になっているセルの先頭にクォーテーション(')を入れるVBAです。
セルのデータを文字列として認識させたいときに便利です。


#ソースコード
    
    '変数宣言
    Dim head As String
    Dim target As Range
 

    'エスケープを入れるレンジの指定
    Selection.SpecialCells(xlCellTypeConstants, 1).Select
    head = "'"

    '数値もしくは日付の場合エスケープする
    For Each target In Selection
        If IsDate(target) Or IsNumeric(target) Then
            target.Value = head & target.Value
        End If
    Next
Leetcode #747: Largest Number At Least Twice of Others

```swift
func dominantIndex(_ nums: [Int]) -> Int {
    var largest = nums[0]
    var second = 0
    var index = 0
    for i in stride(from: 1, to: nums.count, by: 1) {
        if nums[i] > largest {
            second = largest
            largest = nums[i]
            index = i
        } else if nums[i] > second {
            second = nums[i]
        }
    }
    return largest >= second * 2 ? index : -1
}
```
Leetcode #734: Sentence Similarity

```swift
func areSentencesSimilar(_ words1: [String], _ words2: [String], _ pairs: [[String]]) -> Bool {
    if words1.count != words2.count {
        return false
    }
    
    var dict = Set<[String]>()
    for pair in pairs {
        dict.insert([pair[0],pair[1]])
        dict.insert([pair[1],pair[0]])
    }
    for i in stride(from: 0, to: words1.count, by: 1) {
        if words1[i] == words2[i] || dict.contains([words1[i],words2[i]]){
            continue
        } else {
            return false
        }
    }
    return true
}
```
GoogleColabratoryのメモリ上限を無理やり解除できるらしいので検証してみた


今回の記事の趣旨ですがメモリ上限の解除ができるかどうかの検証であって、**メモリ上限の解除を推奨するものではないこと**をご承知おきください。

推奨しない理由としてはこの後説明しますが、デフォルトのメモリサイズは13GBを使い切る処理を行うとセッションがクラッシュします。その後メモリ上限が解除されたランタイムに切り替えるかどうかのダイアログが表示されるのですがこれを見る限り、**メモリ不足のための救済措置**のようであるためです。それでもやってみたいという方は自己責任でよろしくお願い致します。

元ネタはこちらのツイートです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">GoogleColabratoryのメモリ使用量を上限を超えてクラッシュさせると25GB上限のインスタンスに切り替えられるハックを見つけた<a href="https://t.co/sstIkVfOcV">https://t.co/sstIkVfOcV</a></p>&mdash; wakame@kaggleサボりマン (@wakame1367) <a href="https://twitter.com/wakame1367/status/1158653393960763392?ref_src=twsrc%5Etfw">August 6, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

上記件について検証に使ったGoogleColabratoryはこちらになります。

[GoogleColabratory - RAM_Increase_runtime_test.ipynb](https://colab.research.google.com/drive/17M4Jrhup8IiJwAI9yvCSrP8wlv1vYV2i)

以降は上記GoogleColabratoryで行いました、メモリ上限の解除の確認のための各手順を説明したものになります。

## メモリ上限が解除されていないことを確認する
メモリ上限が解除されていないことを確認するため下記コマンドを実行します。
解除されていないことが確認できました。

```
# before RAM increase
!free -h 
# output
              total        used        free      shared  buff/cache   available
Mem:            12G        381M         11G        872K        718M         12G
Swap:            0B          0B          0B
```

## セッションを強制的にクラッシュさせる

以下コードをGoogleColabratoryノートブックにて実行する。デフォルトのメモリサイズは13GBを使い切る処理のためセッションがクラッシュします。

```python 
[_ for _ in range(10000000000)]
```

その後ノートブック右下に下記メッセージが表示されます。
![ram_increase_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40310/969d3e58-6d6b-7c56-9526-3ed315b26a73.png)

RAMを増やすをクリックすると下記ダイアログが表示されます。メモリ上限を解除するためはいを押します。
![ram_increase_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40310/0446a186-ea69-ff4a-fb8e-8ea4fd1374e5.png)

## メモリ上限が解除されていることを確認する

メモリ上限が解除されていることを確認するため下記コマンドを実行します。
解除されていることが確認できました。

```
# after RAM increase
!free -h
# output
              total        used        free      shared  buff/cache   available
Mem:            25G        421M         23G        872K        1.6G         24G
Swap:            0B          0B          0B
```

# 参考
- [Qiita - 【秒速で無料GPUを使う】深層学習実践Tips on Colaboratory](https://qiita.com/tomo_makes/items/b3c60b10f7b25a0a5935)
- [Github - Just crash your session by using the whole of the 12.5 Gigs of RAM then the door opens where you can directly double your RAM to 25 Gigs in Colab.](https://github.com/googlecolab/colabtools/issues/253#issuecomment-518029492)
buttonタグ内でaタグを使用すると、エラーが出るそうです。

僕も今日初めて知りました。
今まで普通に使っても問題なく表示されましたが、現在通っているスクールの先生から指摘を受け初めて知りました。

実際にコードのvalidateを行うと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465903/822abf01-2e8b-3d1f-c302-b18c487ec01e.png)

というエラーがが出てきました。今後、皆さんも参考にしてみてください。
最小の手間でgremlin-consoleを使ってNeptuneに接続する

1. Neptuneと同じvpc内にec2を立ち上げdockerをinstallする
2. 以下のコマンドを打つ
3. 終わり

```
docker run -it -e NEPTUNE_ENDPOINT=[YOUR ENDPOINT HERE] --rm amothic/gremlin-neptune
```

https://github.com/amothic/docker-gremlin-neptune
Leetcode #849: Maximize Distance to Closest Person

```swift
func maxDistToClosest(_ seats: [Int]) -> Int {
    var index = -1
    var distance = Int.min
    for i in stride(from: 0, to: seats.count, by: 1) {
        if seats[i] == 1 {
            if index == -1 {
                distance = i
                index = i
            } else {
                distance = max(distance, (i - index)/2)
                index = i
            }
        }
    }
    distance = max(distance, seats.count - index - 1)
    return distance
}
```
JavaでCookieにSameSite属性をつける

（20/01/08 19:45追記）

## 概要
javax.servlet.http.CookieにはSameSite属性を付与するAPIがありません。
そんな時の対応です。
ちなみにSameSite属性はほぼ全てのブラウザが対応しています。
[参考](https://caniuse.com/#search=samesite)

## Cookieクラスを使用せず、Set-Cookieヘッダーを使用する

Spring bootでやってみます。

```java
@RestController
public class DemoController {

    @GetMapping(value = "/")
    public String index(HttpServletResponse response) {

	    String name = "name";
	    String value = "takeshi";

	    String cookie = String.format("%s=%s; max-age=3600; Path=/; HttpOnly; Secure; SameSite=Lax;", name, value);

	    response.addHeader("Set-Cookie", cookie);

	    return "hello, world!";
    }

```

<img width="878" alt="Screen Shot 2019-08-06 at 17.11.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469184/a4ba2d13-33d6-b76a-d999-830147cb6aa3.png">

無事takeshiが入りました。

## Spring Boot編
Spring BootにはResponseCookieというヘッダー用のCookie文字列を作ってくれるクラスがあります。
このクラスを使用して、Set-Cookieでセットしたレスポンスを返却すると、Cookieをセットしてくれます。

```java
@RestController
public class DemoController {
    @GetMapping(value = "/")
    public String index(HttpServletRequest request, HttpServletResponse response) {

        String name = "name";
        String value = "takeshi";

        ResponseCookie cookie = ResponseCookie.from(name, value).domain("localhost").maxAge(Duration.ofDays((long) 1))
            .httpOnly(true).secure(true).sameSite("Strict").build();
        response.addHeader("Set-Cookie", cookie.toString());

        return "Hello, World";
    }
}

```

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469184/fd174bf6-128c-d0cd-3946-e0bd2edde728.png)



頻繁にCookie書き込みを行う場合は、パラメータで受け取ってセットするカスタムクラスを作った方が良さそうですね。
もしくはApacheやnginxなどのWebサーバ側で一括設定もできます。
[参考](https://dev.to/shosta/security-headers-to-use-on-your-webserver-3id5)



### 参考
[Class Cookie](https://docs.oracle.com/javaee/6/api/javax/servlet/http/Cookie.html)
https://stackoverflow.com/questions/42717210/samesite-cookie-in-java-application
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie

[Class ResponseCookie](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/ResponseCookie.html)
gremlinを利用したグラフDB開発環境構築

gremlinを利用してグラフDBの開発環境を構築します。
構築のポイントなど書いていきます。

### 結論
```
git clone https://github.com/amothic/gremlin-dev
cd gremlin-dev

docker-compose up -d
docker-compose run --rm console
```
gremlin-serverに接続されたconsoleが立ち上がります。

### 構成
公式のdockerイメージとdocker-composeを活用して開発環境を構築します。
公式のdockerイメージは使いにくいですが、confをマウントすることで使っていきます

```docker-compose.yml
version: '3'

services:
  graph:
    image: tinkerpop/gremlin-server:3.4.2
    ports:
      - 8182:8182
    volumes:
      - ./gremlin-server:/opt/gremlin-server/conf
      - graph-data:/opt/gremlin-server/data
  console:
    image: tinkerpop/gremlin-console:3.4.2
    command: "-i conf/remote.groovy"
    volumes:
      - ./gremlin-console:/opt/gremlin-console/conf

volumes:
  graph-data:
```

### gremlin-server
オンメモリの簡易グラフDBとしても使うことができます。
貧弱ですが、ファイルに書き出して永続化することもできます。
（ファイルに書き出すには、gremlin-consoleで`graph.close()`コマンドを入力する必要があります）

永続化するための設定をvolumeとしてマウントします。
graph.propertiesを変更した以外は公式の設定を引っ張ってきているだけです。
log4jの設定は無いとwarningで怒られます。

```
gremlin.tinkergraph.graphLocation=/opt/gremlin-server/data/graph.json
gremlin.tinkergraph.graphFormat=graphson
```

### gremlin-console
https://github.com/amothic/gremlin-dev/tree/master/gremlin-console

接続先の指定を行っています。
また、`remote.groovy`に起動時のコマンドを記載し、立ち上げた時にgremlinのコマンドが打てる状態にしています。

### gremlinを利用してみる
```
docker-compose up -d

## gremlin-consoleを立ち上げる
docker-compose run --rm console
```

```
gremlin> g.V()
gremlin> g.addV('person').property('name', 'toma')
==>v[0]
gremlin> g.addV('person').property('name', 'daichi')
==>v[2]
gremlin> g.V().valueMap()
==>[name:[toma]]
==>[name:[daichi]]
gremlin> graph.close()
==>null
```

`graph.close()`を入力しないと、`docker-compose down`するとデータが消えてしまいます。
わりと面倒なのでバックエンドに`neo4j`など使っていくほうが懸命な気がします。
C#のDataContractJsonSerializerでインデントをして出力する(minifyしない方法)

C#でJsonをシリアライズする一つの方法に DataContractJsonSerializerがある。
これを使ってファイルに書き込むためには以下のように記述する。

```csharp
        public void Save(T data)
        {
            using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
            {
                var serializer = new DataContractJsonSerializer(typeof(T));
                serializer.WriteObject(fs,data);
            }
        }
```

インデントされずに1行で出力されてしまうのだが設定ファイルだとかに使いたい場合は不便。
何とかできないものかと逆コンパイルして追ってみるとWriteObjectは
[JsonReaderWriterFactory.CreateJsonWriter](https://docs.microsoft.com/ja-jp/dotnet/api/system.runtime.serialization.json.jsonreaderwriterfactory.createjsonwriter?view=netframework-4.8#System_Runtime_Serialization_Json_JsonReaderWriterFactory_CreateJsonWriter_System_IO_Stream_System_Text_Encoding_System_Boolean_System_Boolean_)なるものを使っているそう。
WriteObjectはXmlWriterでもオーバーロードされているので、このCreateJsonWriterで作ったWriterを以下のように渡せば、インデントが可能となる。

```csharp
        public void Save(T data)
        {
            using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
            using (var writer = JsonReaderWriterFactory.CreateJsonWriter(fs, Encoding.UTF8, true, true))
            {
                var serializer = new DataContractJsonSerializer(typeof(T));
                serializer.WriteObject(writer, data);
            }
        }
```
Kali Linuxを使いMACアドレス偽装を体験

　Kali LinuxではMACアドレスを簡単に偽装することができてしまいます。
一時的にMACアドレスを変えることにより、MACアドレスフィルタリングをかわす方法となりえます。

## 前提
Kali Linux実行環境があること。
⇒ [Virtual BoxにKali Linuxインストール](https://qiita.com/y-araki-qiita/items/4621a21e9f0d2e38c331)

## macchangerコマンド
macchangerというコマンドでMACアドレスの変更が可能です。

・MacChangerで現状のMACアドレスを確認する

```
macchanger -s eth0
```

・ベンダーIDを変化させずにMACアドレスを変化させる

```
macchanger -s eth0
```

・MACアドレス全体を変化させる

```
macchanger -r eth0
```

・指定したMACアドレスに変化させる

```
macchanger --mac=XX:XX:XX:XX:XX eth0
```

本来のMACアドレスに戻す

```
macchanger -p eth0
```

## 実際の例
では実際にMACアドレスを変えててみます。
無線LANアダプターももちろん可能ですが、今回は有線LANアダプターでやります。

```
root@kali:~# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.20.10.13  netmask 255.255.255.240  broadcast 172.20.10.15
        inet6 fe80::a00:27ff:feae:1ba0  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:ae:1b:a0  txqueuelen 1000  (イーサネット)
        RX packets 1519852  bytes 2155526240 (2.0 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 274906  bytes 19514595 (18.6 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```

この中の 08:00:27:ae:1b:a0 の部分がMACアドレスです。
同じネットワーク内のWindows端末からarp -aで確認しても同じでした。

一旦インターフェースを無効にします。

```
ifconfig eth0 down
```
今回MACアドレスを12:34:56:78:90:12に変更してみます。

```
root@kali:~# macchanger --mac=12:34:56:78:90:12 eth0
Current MAC:    08:00:27:ae:1b:a0
Permanent MAC:  08:00:27:ae:1b:a0
New MAC:        12:34:56:78:90:12
```

その後有効化するにはインターフェースをアップさせます。

```
ifconfig eth0 up
```

確認してみます。

```
root@kali:~# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.20.10.6  netmask 255.255.255.240  broadcast 172.20.10.15
        inet6 fe80::a00:27ff:feae:1ba0  prefixlen 64  scopeid 0x20<link>
        ether 12:34:56:78:90:23  txqueuelen 1000  (イーサネット)
        RX packets 1519852  bytes 2155526240 (2.0 GiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 274906  bytes 19514595 (18.6 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```
　IPまで変わってしまいましたが、MACアドレスが意図した通りに変更されていることがわかります。同じネットワーク内のWindows端末で見ても変更されていました。

## 対策
　macでもspoofなどMACアドレスを簡単に偽装することができるのですが、無線LAN配下のアクセス制限がMACアドレスフィルタリングだけでは重度の高いセキュリティとは言えないです。それはネットワークの方もわかるところだと思います。推測されにくい暗号化キーや、より強度の高い暗号方式を利用する等、他にもセキュリティを高める方法はあると思います。
　なのでこういうこともできてしまうんだ、くらいに見て頂けると。

## 関連記事
[・Kali LinuxでJohn The Ripper,hydraによるパスワード解析](https://qiita.com/y-araki-qiita/items/cda417e49108eee1fb7b)
[・Kali LinuxのMetasploitで脆弱性を突きサーバを遠隔操作](https://qiita.com/y-araki-qiita/items/b5e345984d8a076145c8)
[・Kali LinuxでDVWAを使いSQLインジェクション体験](https://qiita.com/y-araki-qiita/items/131efa82c4205e83fef8)
[・Kali LinuxでWebクローニングを使いログイン情報取得](https://qiita.com/y-araki-qiita/items/2870354cc97842db0ea3)