OmniAICreator/Qiita-1.07M huggingface dataset:
GitHub Actions v2 で Windows Driver Kit を使ったビルドをする

# はじめに
[Windows Driver Kit (WDK)](https://docs.microsoft.com/ja-jp/windows-hardware/drivers/) を使ったビルドをしようとしたときにはまったのでその回避方法です。

# エラー内容
`MSBuild.exe` を使ってビルドしようとすると以下のエラーになります。

```shell
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppBuild.targets(379,5): 
error MSB8020: 
The build tools for WindowsUserModeDriver10.0 (Platform Toolset = 'WindowsUserModeDriver10.0') cannot be found. 
To build using the WindowsUserModeDriver10.0 build tools, please install WindowsUserModeDriver10.0 build tools.  
Alternatively, you may upgrade to the current Visual Studio tools by selecting the Project menu 
or right-click the solution, and then selecting "Retarget solution". [D:\a\user\user\repository\example.vcxproj]
```

# どうするか
[`runs-on:`](https://help.github.com/ja/articles/workflow-syntax-for-github-actions#jobsjob_idruns-on) で指定しているイメージに [`windows-latest`](https://help.github.com/ja/articles/software-in-virtual-environments-for-github-actions#windows-server-2019) や [`windows-2019`](https://help.github.com/ja/articles/software-in-virtual-environments-for-github-actions#windows-server-2019) を指定している場合は [`windows-2016`](https://help.github.com/ja/articles/software-in-virtual-environments-for-github-actions#windows-server-2016-r2) に変更します。

# なぜこれで回避できるのか
GitHub Actions は Azure Pipelines と同じイメージを使っているようで[^1] `microsoft/azure-pipelines-image-generation` リポジトリにヒントがあります。

https://github.com/microsoft/azure-pipelines-image-generation/blob/568bfe035a0583e89ac3f27e1fd2b3be93caa42f/images/win/scripts/Installers/Vs2019/Install-WDK.ps1#L33-L54
VS 2019 のインストールスクリプトで WDK.vsix のインストールがコメントアウトされており、当然使えるわけがありません。
これは [Update Windows Driver Kit to 1903](https://github.com/microsoft/azure-pipelines-image-generation/issues/1192) に起因する問題のようです。
なので VS 2017 を使っている `windows-2016` のイメージではこの問題は起こりません。

# windows-2019 でも動かしたい
`windows-2019` で解決するには WDK.vsix をインストールできれば良いと思うのですがうまくいきませんでした。
[Visual Studio 2019 - WDK for Windows 10, version 1903 · Issue #2994 · appveyor/ci](https://github.com/appveyor/ci/issues/2994#issuecomment-504776140) を参考に以下のコマンドを実行させてみましたが、エラーが発生します。

```shell
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\VSIXInstaller.exe" /a /f /sp /q /skuName:Enterprise /skuVersion:16.3.29318.209 "C:\Program Files (x86)\Windows Kits\10\Vsix\WDK.vsix"
Process completed with exit code 2003.
```

[vsix - VSIXInstaller.exe exit code documentation - Stack Overflow](https://stackoverflow.com/questions/21531596/vsixinstaller-exe-exit-code-documentation) によるとエラーコード `2003` は `NoApplicableSKUsException` とのことです。

# おわりに
問題は認識されているようなのでそのうち解決するとは思いますが、インストールの方法をご存知の方がいればここなり Microsoft のリポジトリなりにフィードバックお願いします。

[^1]: GitHub Actions は [Azure Pipelines のフォーク](https://www.kaizenprogrammer.com/entry/2019/08/18/205010#GitHub-Actions-%E3%81%A8-Azure-Pipelines)
JavaScript で new する関数を prototype ごと巻き上げする

### 注意

ここに書く内容は個人のノウハウのメモです。
使用する環境や職場によってはバッドノウハウになる可能性があります。

また、内容的には ES5 までを想定しています。

---

javascript では、`function xxx(){}` の形で書いた関数は、どこに書いてもいい。
コードの下に書いても、上でその関数を実行できる。

```js
hello("Takashi"); //<- Hello, Takashi!

function hello(name) {
  alert("Hello, " + name + "!");
}
```

いわゆる「関数の巻き上げ」の挙動で、 javascript の入門本などにはたいてい
「コードが理解しづらくなるので、関数はコードの先頭で宣言するように」と書かれている。

けれども自分の場合は、メイン処理だけをコードの先頭にまとめられるので、意図的によく使う。
（ExtendScript 使いなので、関数部分だけコピペで使用したくなる事が多いせいかも）

で、newしてオブジェクトのインスタンスを生成するタイプの関数を使いたいとする。

```js
var greeting = new Hello("Takashi");
greeting.func(); //<- Hello, Takashi!

function Hello(name) {
    this.name = name;
    this.func = function() {
        alert("Hello, " + this.name + "!");
    }
}
```

このように、 this を使って func 部分を書くならば、 function より上で実行できる。
ただしこの場合、 new するたびに func を生成するので
繰り返し利用するのならそのたび別関数を作っていて、処理負荷的に面白くない。

prototype を使って Hello の関数を宣言すれば、
何度 Hello インスタンスを生成しても、複数のインスタンスで func を共有することになる。
その方法で書いてみる。

```js
var greeting = new Hello("Takashi");
greeting.func(); //<- Uncaught TypeError: greeting.func is not a function

function Hello(name) {
    this.name = name;
}
Hello.prototype.func = function() {
    alert("Hello, " + this.name + "!");
}
```

下に書いた Hello.prototype.func は、functionより上では利用できない。
巻き上げられるのは `function Hello(name) {}` の部分だけで、
`Hello.prototype.func = function(){}` の部分は下で実行されることになるから
prototypeが追加されていないHelloをnewすることになってしまう。

下にコピペできるnew用関数を作りたい。
いろいろやっているうちに、こんな風に書くようになった。

```js
var greeting = new Hello("Takashi");
greeting.func(); //<- Hello, Takashi!

function Hello(name) {
    this.name = name;
    for (var _key in Hello.prototype) break;
    if (!_key) {
        Hello.prototype.func = function () {
            alert("Hello, " + this.name + "!");
        }
    }
}
```

Hello が new されたとき、 Hello が prototype を持っていなければ、 prototype を自己定義する。
2回目に new された時点では Hello はすでに prototype を持っているので、 prototype はインスタンスで共有になる。

function のブロック内に書いているので、 prototype 生成部分は一緒に巻き上げられるようになった。

#### 追記 2019/11/04

こういう風にオブジェクトで prototype を書くと失敗する。

```js
var greeting = new Hello("Takashi");
greeting.func(); //<- Uncaught TypeError: greeting.func is not a function

function Hello(name) {
    this.name = name;
    for (var _key in Hello.prototype) break;
    if (!_key) {
        Hello.prototype = {
            func: function () {
                alert("Hello, " + this.name + "!");
            },
            func2: function () {
                alert("Good morning, " + this.name + "!");
            }
        }
    }
}
```

Hello.prototype は空の状態で既に存在していて、
実行後はそれをオブジェクトごと置き換えはできないということみたい。
既にある Hello.prototype にひとつづつ設定する必要がある。

```js
var greeting = new Hello("Takashi");
greeting.func(); //<- //<- Hello, Takashi!

function Hello(name) {
    this.name = name;
    for (var _key in Hello.prototype) break;
    if (!_key) {
        var prototype = {
            func: function () {
                alert("Hello, " + this.name + "!");
            },
            func2: function () {
                alert("Good morning, " + this.name + "!");
            }
        }
        for(var k in prototype) {
            Hello.prototype[k] = prototype[k];
        }
    }
}
```
[JavaScript]HTMLタグは限定タグに変換、HTML特殊文字→文字実体参照 正規表現

#はじめに
タイトルが適当でごめんなさい:bow_tone1:
『この正規表現よりこっちの方がいいよ！』などあれば教えて頂けると嬉しいです。
『この正規表現どこで使うの?』ですが、どうしても可変の値をHTMLで表示したい場合のXSS対策に使うと思ってます。
どうやって書こうって悩んでしまったので今回qiitaに載せました。:bow_tone1:

#用語説明
自分のサイトなのに色々な用語をたくさん使ってしまったため、ここで用語の説明を簡単にさせて頂きたいと思います:shamrock:『用語全然理解できなくないよ！』と言う方はここは読み飛ばしてください！

**HTML特殊文字**
HTMLでは、特別な文字として取り扱われる文字。
`<strong>` をHTMLに記述するとHTMLタグと認識されるとかそういったもの。
参考:http://www.shurey.com/js/labo/character.html

**文字実体参照**
特殊文字を普通の文字として使いたいときがある。そう言う時はあらかじめHTMLでこのように書くとその文字を表示できるよなるものがあります。参考は上のサイトを。
`<`を書きたければ`&lt;`と書けみたいな

**可変の値**
固定の逆。その値が変わるだろう値。
例えば、
ユーザーの入力。
例えば、
API通信で取得する値

**XSS**
本来表示してあるHTMLの文章に意図したjsやHTMLなどを入れられそうだ！入れてしまえ！っといって入れられてしまうもの。

#正規表現(code全体)

```.js
var text = '<script>!!!</script>&<strong>aaa</strong>&<script>sssss</script>&&""""&&&&&&<b>aa</b><psss>dsds</p><script>!!!</script>';
var regex1 = /(&){1}/gi;
var chenge1 = text.replace(regex1, '&amp;')
var regex2 = /("){1}/gi;
var chenge2 = chenge1.replace(regex2, '&quot;')
var regex3 = /<[^\/]{1}.*?>/gi;
var chenge3 = chenge2.replace(regex3, '<strong>')
var regex4 = /<(\/){1}.*?>/gi;
var chenge4 = chenge3.replace(regex4, '</strong>')
console.log(chenge4);
```

出力↓

```
<strong>!!!</strong>&amp;<strong>aaa</strong>&amp;<strong>sssss</strong>&amp;&amp;&quot;&quot;&quot;&quot;&amp;&amp;&amp;&amp;&amp;&amp;<strong>aa</strong><strong>dsds</strong><strong>!!!</strong>
```

これをHTMLで表示↓
<img width="536" alt="スクリーンショット 2019-11-02 10.14.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133940/b24d1f17-01c1-6e23-6961-3701e99401a8.png">

※使用サイト:https://codepen.io/pen/

#正規表現の説明

```.js
var regex1 = /(&){1}/gi;　//『&』1文字を検索
var chenge1 = text.replace(regex1, '&amp;') //『&』1文字を『&amp;』に変換
```

```.js
var regex2 = /("){1}/gi;　//『"』1文字を検索
var chenge2 = chenge1.replace(regex2, '&quot;')//『"』1文字を『&quot;』に変換
```

```.js
var regex3 = /<[^\/]{1}.*?>/gi; //『/』で始めらない文字1文字から始めり、後はなんでも可能 <a>や<bb>など当てはまる
var chenge3 = chenge2.replace(regex3, '<strong>')//それらを<strong>に変換
```

```.js
var regex4 = /<(\/){1}.*?>/gi;　//『/』で始まる文字1文字から始めり、後はなんでも可能 </a>や</bb>など当てはまる
var chenge4 = chenge3.replace(regex4, '</strong>')//それらを</strong>に変換
```

ちなみに、

| 正規表現     | 意味  |   
|:-----------------|:------------------|
| .          |              改行文字以外ならなんでもマッチ！ | 
| 文字 + *          |           文字がが表示されないか文字が連続で表示されるか |
| 文字 + ?          |            文字が表示されないパターンか1回のみの表示となる | 

参考
[JavaScript 正規表現まとめ](https://qiita.com/iLLviA/items/b6bf680cd2408edd050f)
[正規表現パターンの記述](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Writing_a_Regular_Expression_Pattern)


#さいごに
以上！終わりです！(｡･ω･｡)
今お腹空いてます！:flushed:
tfenvを使ったterraformのバージョン管理が便利な件

とりあえず最新バージョンをインストールする派ですが、terraformの0.11と0.12にはかなり差分があるので簡単に切り替える方法を探していたところ、tfenvというterraformのバージョンを管理してくれるツールを発見したので、早速試してみました

## tfenvインストール
まずはインストール

```
brew install tfenv
```

エラーが発生

```
Please `brew unlink terraform` before continuing.
```

先にterraformがインストールされていると、tfenvはインストールできないようなのでアンインストール

```
brew uninstall terraform
```

## tfenvでインストールできるterraformのバージョン確認
インストール可能なterraformのバージョンを確認

```
tfenv list-remote
```
こんな感じでバージョン0.1までのリストが出てくる

```
$ tfenv list-remote
0.12.13
0.12.12
0.12.11
0.12.10
0.12.9
（省略）
```
## tfenvを使ってterraformをインストール
0.11と0.12の最新版をインストール（2019/11/2時点)
### 0.11系
```
tfenv install 0.11.14
```

### 0.12系
```
tfenv install 0.12.13
```

## tfenvでインストールされているterraformのバージョンを確認
ローカルにインストールされているterraformのバージョンを確認

```
tfenv list
```
先程インストールしたバージョンが表示される、今は `0.12.13` がデフォルトとして設定されている

```
$ tfenv list
* 0.12.13 (set by /usr/local/Cellar/tfenv/1.0.2/version)
  0.11.14
```

## tfenvを使ってterraformのバージョン切替

`0.11.14` に切り替えてみる

```
tfenv use 0.11.14
```

再度バージョンを確認

```
$ tfenv list
  0.12.13
* 0.11.14 (set by /usr/local/Cellar/tfenv/1.0.2/version)
```

## プロジェクトごとにterraformのバージョン管理
プロジェクトのルートにバージョンを記載した、 `.terraform-version` を配置する

```
echo 0.11.14 > .terraform-version
```

これでterraformのバージョンを0.11.14に戻してVPCPeeringの自動化を検証してみます

## 参考記事
- https://itnotebook.makaaso.work/entry/terraform/2019110202
PMなら速攻でマスターしたいGoogle Chromeのショートカット12選

# はじめに
 - 業務量は必然的に増えるので、作業効率改善のための工夫はいつだって必要です
 - 日常的に使うGoogle Chromeのショートカットをまとめました
 - macのみです

# ショートカット一覧
### タブとウィンドウ関連

| 内容 | ショートカット |
|:--|:--|
| 新しいタブを開く | Command＋T |
| タブを閉じる | Command＋W |
| 閉じたタブの復元| Command＋Shift+T |
| タブを右に移動 | Ctrl＋Tab |
| タブを左に移動 | Ctrl＋Shift＋Tab |
| 新しいウィンドウを開く | Command＋N |
| シークレットモードで新しいウィンドウを開く  | Command＋Shift＋N |
| 現在のウィンドウを閉じる | Command＋Shift＋W |


### その他

| 内容 | ショートカット |
|:--|:--|
| アドレスバーにカーソル移動 | Command＋L |
| デベロッパーツールを開く | Command＋Option＋I |
| リロード | Command＋R |
| スーパーリロード | Command＋Shift＋R |


# さいごに
 - 他にもあれば教えて下さい
ReactNativeでhooksを利用する最低限過ぎるメモ。


React 16.8から導入されたHook。
関数コンポートにおいて、state管理やcomponentDidMount等と同等の機能を利用するためのもの。
代表的なものはstate hooksとeffect hooks。

### ステートフック

ステートを管理するためのもので下記の構文で利用できる。


```
const [変数,関数] = useState(初期値);
```


### 副作用(effect)フック

componentDidMount()等と同等の機能を提供する。下記のような構文で利用する。
どういう動きをするかは引数で決まる（制御できる）。

#### componetDidMount風

下記のように書くと1回だけ実行。

```
useEffect(()=>{},[]);
```

#### 変化があるか

countが変化してるいるかどうか。

```
useEffect(()=>{},[count]);
```


### サンプル

とりあえず。


```js:App.js
import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';

export default function App() {

  //state hook
  const [count, setCount] = useState(0);

  //effect hook
  useEffect(() => {
    console.log('you clicked ' + count + 'times');
  });

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>You clicked {count} times.</Text>
      <Button
        title="click me"
        onPress={() => setCount(count + 1)}
      />
    </View>
  );
}
```
picoCTF 2019 Open-to-admins - Points: 200

#問題

https://2019game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/bf1772dc-632c-56e4-df3d-df89dffbb9af.png)

#解いてみた

アクセスすると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/b7bfce21-5d9d-1ddb-3fae-5ecb019f50fe.png)

Flagボタンがあるサイトが表示されました。

各ボタンの挙動を確認します。

Sign InとSign Outボタンはまだ実装されていません。というメッセージが出てくるだけでした。
URLは変わりません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/925bea51-600b-38ef-7518-fcebf44da2fe.png)

Flagボタンは時間が正しくないというメッセージが出てくるだけ。
URLは変わりません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/f8078a5d-e5b9-97a6-01af-5f3502b641d4.png)

ヒントを見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/9e9300c3-d0d3-df5c-2662-0d840d2944a5.png)

Cookieを使って答える問題のようです。
wiresharkでCookieを見てみます。

Flagボタンを押したとき

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/f76993a3-9806-dd9b-b626-1beb79c76948.png)

最初に/flagにアクセスしてCookieがセットされています。
その後トップページにリダイレクトされています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/d15825b2-2550-6ace-f1b1-bba815e33336.png)

おなじみのadmin=trueを追加
時間はひとまずtime=1400を追加してみます。

Cookieの編集にはEditThisCookie使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/ed404b6d-b883-493f-00d3-0ac96529b6c3.png)

これでflagボタンを押す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/f3f12120-918a-cb24-92af-0355c1d364a9.png)

できた。。。
運が必要。。。
【SwiftUI】contentShapeでTap領域を広げる


SwiftUIで
あるViewに
`onTapGesture`を設定した際
中にある個々のViewをタップすることはできますが
その他の領域はタップしても反応しません。

例えば下記ような`VStack`に対して`onTapGesture`を設定します。

```swift

import SwiftUI

struct ContentView: View {

    @State private var checked = false

    var body: some View {

        VStack(spacing: 20) {
            Image(systemName: checked ? "checkmark.seal.fill" : "checkmark.seal")
                .foregroundColor(checked ? .green : .gray)
            Text("画像とテキストのみTapできる")
        }
        .frame(width: 300, height: 200)
        .padding()
        .background(RoundedRectangle(cornerRadius: 20).stroke(Color.green, lineWidth: 1))
        // 👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻
        .onTapGesture {
            self.checked.toggle()
        }
        .font(.title)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```

上記の場合ですと
VStackの中の画像とテキストにしかタップできません。

![cannottap720.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219965/97b25255-96a5-f4c2-c5fb-9405afb52a0a.gif)


そんな時に活用できるのが`contentShape`です。
https://developer.apple.com/documentation/swiftui/vstack/3278318-contentshape

これを実行すると自身のhitテストを実行してくれるViewを返します。

今回は枠内をタップできるように設定します。

```swift


struct ContentView: View {

    @State private var checked = false

    var body: some View {

        VStack(spacing: 20) {
            Image(systemName: checked ? "checkmark.seal.fill" : "checkmark.seal")
                .foregroundColor(checked ? .green : .gray)
            Text("枠の中は全部Tapできる")
        }
        .frame(width: 300, height: 200)
        .padding()
        .background(RoundedRectangle(cornerRadius: 20).stroke(Color.green, lineWidth: 1))
        // 👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻👇🏻
        .contentShape(RoundedRectangle(cornerRadius: 20)) 
        .onTapGesture {
            self.checked.toggle()
        }
        .font(.title)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```

すると下記のようにタップエリアを拡大することができます。
![cantap720.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219965/c945cb17-88c1-1ce1-700e-b4abf251de3a.gif)



画像をタップできるようにしたいけれど
画像だけだとタップできる領域が狭い場合などに
コードを１行加えて領域を広げることができるのは
大変便利ですね😄
o365 既定のフォントを変更する（MacOS編）

# PowerPoint
1. （2019年11月時点の調べでは）規定のものから選ぶしかなさそうです。
2. 「デザイン」タブから、フォントテーマを選択。
![Kobito.0W46Zf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43829/b7057430-ea9b-8003-d427-17bc06cfa27c.png "Kobito.0W46Zf.png")

# Excel
「環境設定」から「規定のフォント」を変更することでも対応可能。
ただ、「規定のフォント」が「本文のフォント」となっていることからは、テーマを作る、あるいはテーマを選ぶのExcelが作者の期待かな？
テーマ選択の手順は以下。
1. 「ページレイアウト」タブから「フォント」メニューを選択。
![Kobito.SLQupJ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43829/f20d4041-e737-8d08-dcd8-c72d3497d46a.png "Kobito.SLQupJ.png")
2. その後、これをテンプレート保存するらしいのだが、いくら保存してもテンプレートを選ばないと指定フォントが使用されないのは無念。

# Word
1. 新規文書作成。
2. 「フォーマット | フォント...」メニューを選択。
![Kobito.RX9jfX.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43829/b7b843f5-4a76-3fe6-a4c4-11ca46c72c71.png "Kobito.RX9jfX.png")

3. 好みのフォントに変更する。
![Kobito.Jeo1fV.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43829/81eb6267-a261-5998-ce74-c1dec743a5ff.png "Kobito.Jeo1fV.png")

4. 左下の「規定値...」ボタンを選択する。
![Kobito.QTDXk4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43829/b295119b-c523-6a58-9896-73bbc755ec6e.png "Kobito.QTDXk4.png")


5.「すべてのドキュメントは標準テンプレートを基にしていますか？」にチェックをつけて、「OK」ボタン。
うーん、日本語微妙w
エディタの使用に関する小ネタ

今回は、テキストエディタ(Windows 標準の notepad は除く)や Visual Studio Code 等、エディタの使用に関する小ネタです。

2 つご紹介します。
マウスを使うのが何となく面倒な時に便利です。

# カーソルを動かさずにページを上下させる

Ctrl + ↑、Ctrl + ↓ で、カーソルの位置はそのままに、ページを上下させることができます。

# 行中で単語単位でカーソルを移動させる

Ctrl + →、Ctrl + ← で、行中で単語単位でカーソルを移動させることができます。


マウスを使えば不要な知識ですが、有用な時があるかもしれないと思い、投稿した次第です。

短いですが、以上です！
picoCTF 2019 Mr-Worldwide - Points: 200

#問題

https://2019game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/4a6edb4e-4664-7955-e973-d7cafff48d12.png)

#解いてみた

メッセージを見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/856ea619-4a9f-8c4b-e235-9ddaffeb290f.png)

ぱっと見、座標みたいなのでgoogleで検索してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/5672d090-145c-3b0a-cf14-fb02ae31bdc3.png)

京都ですか。
次。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/caff649b-22f1-8aaa-833f-dce9ebe591b9.png)

ロシアですか。
と思ったらウクライナでした。

国名の頭文字とかを拾っていけばいいんですかね？
全部を検索すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/5f77c89f-3fc5-a380-3e71-c5d5e3a4029a.png)

こんな感じでした。
国名の頭文字を取って回答してみましたが、違ってました。
都市名の頭文字を入力してみても違ってましたが、大文字にするとあってました。
expoでtest(jest)するときのセットアップメモ（2019年11月版）


expoでjestを使ってテストをする際は原則[ここ](https://docs.expo.io/versions/latest/guides/testing-with-jest/#structure-your-tests)に書いてある通りにすればよい。

しかし、2019年11月2日現在、

```bash
npm test
```

を実行すると、

```bash
 Cannot read property 'current' of undefined
```

というエラーに遭遇。[ここ](https://github.com/expo/expo/issues/5268)の情報によるとreact-test-rendererのバージョンミスマッチのよう。

react-test-rendererのバージョンをreactとかのバージョンと合わせばよいらしい。
最近expoでもライブラリのバージョンミスマッチが多い。。。

package.jsonを変更する。

以下、抜粋。


```diff:package.json
  "dependencies": {
    "expo": "^35.0.0",
+    "react": "16.8.3",
+    "react-dom": "16.8.3",
    "react-native": "https://github.com/expo/react-native/archive/sdk-35.0.0.tar.gz",
    "react-native-web": "^0.11.7"
  },
  "devDependencies": {
    "babel-preset-expo": "^7.1.0",
    "firebase-mock": "^2.2.10",
    "jest": "^24.9.0",
    "jest-expo": "^35.0.0",
+    "react-test-renderer": "16.8.3"
  },
```

> わかりやすいように+でハイライトしているが、追加というわけではない。

変更したら再度npm install。再度、npm testで、無事動いた。

## メモ

エラーとは関係ないが、下記にfirebase-mockを利用したテスト方法がある。

* https://techunderthesun.in/setting-up-tests-in-expo-app-using-jest/
【python3】変数名をキーとして文字列のformatを行う

# 実装した関数

```py
from inspect import currentframe,getargvalues

def varfmt(target,*argv):  
    return target.format(**getargvalues(currentframe().f_back).locals)  
```

【※追記※】@shiracamus さんより、python3.6以降なら以下の書き方でOKとのコメントを頂きました。
ありがとうございます！

```py
def hoge_aa_print(hoge, aaa):
    print(f"{hoge} {aaa}")

hoge_aa_print(10, 20)
```

[参考]
https://qiita.com/AnchorBlues/items/f7725ba87ce349cb0382
https://docs.python.org/ja/3/library/inspect.html

# example
```py
from inspect import currentframe,getargvalues

def varfmt(target,*argv):  
    return target.format(**getargvalues(currentframe().f_back).locals)  


def hoge_aa_print(hoge,aaa):
    print(varfmt("{hoge} {aaa}",hoge,aaa))

hoge_aa_print(10,20)
```
このように、変数名をキーとして文字列のformatを行うことが出来ます。

# 補足
誤り、マサカリ、苦情、鬱憤晴らし等有りましたらコメントお願いします。
Git って何？

Gitについて人に説明する必要があった時にまとめたメモ。
不正確な部分があるが、わかりやすくを心がけてまとめたもの。
（技術的な仕組み・操作・用語などの説明は無し。）

# 参考サイト

わかりやすそうなサイト。
[【絶対理解できる】Gitとは？特徴やできることまとめ！](https://www.sejuku.net/blog/5756)
[【初心者向け】Gitってなに？①まず流れを理解する（コードなし）](https://qiita.com/nutsinshell/items/96cb83aecf9d09a7a8bc)

#何をするもの？

- プログラム等のファイル一式を置いておく場所（サーバー上のシステム）。ファイルを修正したらどんどん最新のものに上書きしていく。
- 複数人のチームで何か（プログラムでもそれ以外でも）を制作する場合や、他の人にファイルを渡したい時に、ファイルを共有できる場所。
- クラウド（インターネット上）のGitにファイルを置いておけば、複数の場所を移動して開発する人にとっては、どこからでも自分のファイルにアクセスできる。

#共有フォルダーやGoogleドライブ等でファイルを共有するのと、何が違う？

###1. いつ、誰が、どのファイルに、どんな変更をしたかの変更履歴が、全て自動で記録される。<br>
「いつ」「誰が」「どのファイルに」「どんな変更を」「どんな目的で」したかという、変更の 5W1H（？） は、自分の変更を細かくメモしているようなマメな人でない限り、どんどん忘れ去られていく。
Gitにファイルを置くと、「いつ」「誰が」「どのファイルに」「どんな変更を」の部分は、自動で、正確に記録される。<br>ファイルの数、ファイルの更新回数、更新に関わる人数がどんなに多くても、正確に記録してくれる。
「どんな目的で」の部分は、ファイルの変更をGitに反映（COMMIT）する時に出てくる画面で、それをコメントで書いておける。

| ～テキストデータの場合だけ、「どんな変更を」の自動記録ができる ～ |
|:----------------------------------------------------|
|「どんな変更を」の自動記録は、テキストデータ（Windowsの「メモ帳」で見れる文字のデータ）限定。<br>Officeファイルや画像ファイルなどは、「いつ」「誰が」「どのファイルに」の記録のみで、具体的な変更内容は記録されない。<br><br>Gitは、自動で、全てのファイルの中身を解析し、前回との変更内容を自動で見つけ出して記録してくれるのだが、Officeファイルや画像の中身は解析できないため。<br><br>それらのファイルの場合、変更者が自分で、Gitに反映（COMMIT）するときのコメントで書いておく。|


###2. 過去の特定の時点のファイルの状態を戻すことが、簡単にできる。

どんなささいな変更をしても、そのたびに裏で自動でバックアップが作られる。そのため、プログラムにエラーが発生した時、エラー発生前に戻したい時がよくあると思うが、それが簡単にできる。
（これは、テキストデータ限定でなく、どんなファイルでもバックアップが作られる）<br>

`ファイルの変更履歴が必要ないデータや、ファイル数が少なくて、自分で何を変更したか全部覚えておけるような場合は、Gitを使わなければならない必然性は無い。
ツールの環境構築や、使い方を覚えるのに、それなりの時間的コストはかかるため。`

# 誰が使う？

たぶん、こんな人達が、Gitにプログラムを置いているのだろう･･･。

- **複数人で、ある程度の規模のプログラムを開発するチーム**
    - チーム開発の手間を減らすためや、トラブル回避のために使う。

- **IT業界に就職しようとしている人**
    - 就職先で使う可能性が高いので、学習しておくために使う。
    - 自分が作成したプログラムのソースコードを、採用担当者にすぐ渡せるよう、クラウドのGitに置いておく。Gitが使える証明にもなる。

- **プログラム技術者の情報共有**
    - プログラムに関する知識を、誰かと共有・情報交換するために使う。

上のリンクをはっているサイトによると、最近では、記事のライターさんなどにも使われているとの事。

#もしGitが無かったら？

Git（バージョン管理システム）が無かったら、開発者の人数が多いプログラム開発は、たぶんこうなってる･･･。

- エラーが起きたらすぐ戻せるように、ファイルを修正する前には必ずコピーして、ファイル名に日時をつけて（「sample_20191101100331.java」みたいな）バックアップしておくことが推奨される。
そのうちに、日時のついたコピーデータだらけになる。コピーデータをいちいち作ったり管理するのも大変。

- 情報共有のため、「いつ」「誰が」「どんな変更を」「どんな目的で」修正したかのコメントを、どこか（ファイルの先頭部分や、変更箇所の近辺など）に書くのが必須ルールになる。そのうちにプログラムがコメントだらけになる。
それでも、誰かの変更を、他の人が消したり安易に変更してしまうことが頻発する。

- 上書きのトラブル
  AさんとBさんが同じファイルの別の箇所を修正した場合、Aさんが先に共有フォルダーに自分の修正ファイルを置いた後、Bさんが誤って上書きすると、Aさんの修正が消えてしまい、戻せなくなったり。


#Gitの種類
###(1) クラウド（インターネット上）のGit
有名どころとしては以下の２つ。
**GitHub**
世界中の人々が自分の作品(プログラムコードやデザインデータなど)を保存、公開することができるようにしたウェブサービス。情報共有のためによく使われる。<br>無料コースだと、全てのデータが世界中に公開される。有料コースにすれば、自分だけの非公開にすることもできる。
**GitLab**
GitHubの類似サービスだが、無料で、非公開リポジトリを作成できるのが特徴。（リポジトリ：ファイルの置き場所）


・・・と思ったら、GitHubでも、非公開リポジトリを使えるようになったみたい。ただし機能制限はあるみたい。
参考サイト:[GitHubが無料でプライベートリポジトリを無制限に作れるようになったぞ☆](https://qiita.com/wagase/items/4ed3e9998848cfa733be)

###(2) 社内や個人PCに構築したGit
社外に公開できないプログラムなどを置く。
クラウド上だと、ネットワーク障害やGitのサービス側の障害で、使えなくなる事があり得るので、その対策にもなる。
また、自分のスキルアップのために、Gitサーバーを構築してみる人もいる。

# その他参考に見たサイト
https://blog.sixapart.jp/2014-03/mttips-02-what-is-git.html
http://www.startup-git.com/beginners/git-merit/
[メモ] Kubernetesで private registry のイメージをPull する場合には ImagePullSecretsを使う


## なにに困って、どのように解決したか

CI/CD のパイプラインを作成時に、イメージ置き場をプライベートレジストリに変えたあとにログインが必要になり、イメージPullが失敗しビルドが通らなくなりました。

プライベートレジストリからイメージをPullするためにはログインが必要になります。

複数のログイン方法がありますが（詳細は「[Pull an Image from a Private Registry](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/)」を参考）ここではCI/CDパイプラインでイメージをビルドするときや、コンテナをデプロイするときにプライベートレジストリからイメージをダウンロードする際にログインしておらず、エラーで停止してしまうことを防ぐための方法を記載します。

## やるべきこと

プライベートレジストリから Pull するときにはコンテナレジストリの認証のためのSecretを作って、ServiceAccount に `IamgepullSecrets` を追加します。
こうすることでServiceAccount に追加されたImagepullSecretsがPod作成時に自動で付与されるようになります。

各マニフェストに`imagePullSecrets`に記載する方法もあります。

## imagePullSecrets

`spec.Pod.imagePullSecrets` が準備されており、こちらにpull時に使用するSecretを設定するとクレデンシャルとして使用するようになります。

imagePullSecretsの設定方法としては２つあります。

* マニフェスト作成者が`imagePullSecrets`を記述
* namespace の default service account を作成したSecretをimagePullSecretとして使うよう変更

## 手順

1. Secretを作成する
2. default service account の ImagePullSecrets を変更する。　（マニフェストに直接書く場合は不要）

## コマンド

Secretの作成を実施します。
ここではGCRからコンテナイメージを取得することを想定しています。
そのため`--docker-server` に指定しているレジストリはGCRのアドレスとなっています。

プライベートレジストリなら方法は同じです。--docker-server を適宜変更してください

コマンドラインからSecret作成時にユーザ名、パスワードを設定します。

```bash
$ kubectl creates secret docker-registry regcred --docker-server=asia.gcr.io --docker-username=_json_key --docker-password="$(cat key.json)" --docker-email=email-address@address -n namespace
```

default service account に `imagePullSecrets` を追加します。上記で作成したSecret名をnameに設定します。

```bash
kubectl patch serviceaccount default -p '{\"imagePullSecrets\": [{\"name\": \"regcred\"}]}' -n namespace
```

以下のURLで公開されているマニフェストを例に説明します。

- https://k8s.io/examples/pods/private-reg-pod.yaml

サンプルでは `imagePullSecrets`が記載されており、`name: regcred`  が指定されています。
この場合、Secretオブジェクトの regcred をイメージPull時に使用します。

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: private-reg
spec:
  containers:
  - name: private-reg-container
    image: <your-private-image>
  imagePullSecrets:
  - name: regcred
```

default service account の imagePullSecretを変更した場合は次のようにマニフェストを定義しても（imagePullSecrets がない）、実際は上記のマニフェストと同じようになります。

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: private-reg
spec:
  containers:
  - name: private-reg-container
    image: <your-private-image>
```

## 所感

個人的には今回の用途としては、ImagePullSecretをサービスアカウントに設定し問題を解決しました。

運用時にはどちらがいいかと言われると、ケースバイケースという回答になりそうです。
いくつか方法があるということと、デプロイ時に追加できるということを覚えておくことで類似の問題は解決できるのではと考えます。

他にもトークンを設定してログインする方法もあります。
セキュリティ上、本来はトークンを都度生成したほうがいいのかなとも今回考えました。
最適な姿についてはもう少し検討したいと思います。

## 参考

- [Pull an Image from a Private Registry](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/)

- [Add ImagePullSecrets to a service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account)
ArrayList配列でwhileによる繰り返し処理でIteratorで全部表示する

#ArraylistをIteratorで全件表示する方法


```:java

        //Listの宣言
        List<String> fruits =new ArrayList<>();

        fruits.add("リンゴ");
        fruits.add("スイカ");
        fruits.add("ナシ");
        fruits.add("バナナ");

       //Iterator<Stromg>の宣言 
　　　　Iterator<String> it2= fruits.iterator();
        
        //hasNextを使用して値がある場合はループを継続する
        while(it2.hasNext()){
            //nextを使用して値を取得する
            String nation = it2.next();
            System.out.println(nation);
        }
```
毎日ブログ五日目

ただ今の時刻2:02

早めに書き上げます。

今日したことは

東フリさんが取り上げていた、海外の人がコーディングしているのを写経しました。
https://www.youtube.com/watch?v=V_lAhqLXT9A&feature=youtu.be

途中までしか、終わりませんした。

mlのlはleftである。

text-transform:uppercase; は、
テキストの大文字表示・小文字表示を指定するものである。

あんまりインプットできませんでした。

明日終わらして、復習します。

今日はその他にhttps://magazine.krowl.jp/4026/このサイトを写経しました。
このサイトはすごい参考になり、構造の分解の仕方がよくわかりました。

transform:translate(-50%,-50%);
positionとtop,leftで50%ずつ移動させ、要素の表示位置をtransformプロパティで調整するやり方です。これはパターンみたいなもので覚えよう。
要するに中央にするやり方。

background-image:url("../img/picture_pc_2.jpg"); ..が必要であった。

Bootstrapではいらなかったような。

after 要素の直後に内容を追加するやり方。これは入れたいものを挟み込む感じ。

今日はあまり、インプットできませんでした。明日もう一度復習したいと思います。

明日も頑張りましょう！！！！

2:16
Vimでカーソルが常に画面中央行になる設定

# はじめに

```
コメントで指摘頂いた内容です。
記事の内容は、ファイル末尾の挙動を除いて、

:set scrolloff=999

というコマンド一つで満たされるので、こちらをお使いください。
また、省略形で

:set so=999

というものもあるので、編集中に設定する場合はこちらがおすすめですよ！

記事の設定を用いるとVimを開いたまま元に戻すことができないのに対し、
:set so=0
とすると何もしない状態に戻すことができます。
また、
:set so=5
とすると、上下少なくとも5行を表示してくれるので、前後関係の把握に便利です。
```



こんなのがあれば便利なのではないかと考えて設定しましたが、やっぱり不便だったのでボツにしました。
しかし、必要な人もいるのではと思ったので、設定を晒します。

# 設定方法
`~/.vimrc`に以下を追記するとよい。

```config:.vimrc(一部抜粋)
noremap h hzz
noremap j jzz
noremap k kzz
noremap l lzz
noremap gj gjzz
noremap gk gkzz
noremap + +zz
noremap - -zz
noremap e ezz
noremap b bzz
noremap w wzz
noremap ge gezz
noremap E Ezz
noremap B Bzz
noremap W Wzz
noremap gE gEzz
noremap n nzz
noremap N Nzz
noremap G Gzz
noremap g; g;zz
noremap g, g,zz
noremap <C-u> <C-u>zz
noremap <C-d> <C-d>zz
noremap u uzz
noremap <C-r> <C-r>zz
noremap % %zz
noremap d dzz
noremap o ozz
noremap O Ozz
```

# 解説
Vimでは、`zz`コマンドによってカーソル行が中央になるように画面を移動してくれる。
そこで、Vimで移動するコマンドを`*zz`とマッピングする。（今回は思いついたものだけ抜粋したため、適宜必要なコマンドをマッピングしてもらうと良い）
画面上部ではカーソル行を中央にすることはできない。
【72日目】オブジェクト指向を「日本語で」理解するための記事　ー継承編ー

[前回記事](https://qiita.com/untrustworth/items/336c0888b608ba947351)の続きになります。
今回は「継承」について見ていきます。

# 2 継承
継承は、いわゆる三大柱の中では一見すると一番わかりやすいと感じると思います。
なぜかというと、継承すると起きることが目に見える上わかりやすいからです。
**親クラスの変数やメソッドを子クラスでも使用できる**ようになるということです。
これによって、複数のクラス全部に書いていた変数やメソッドを、親クラスに1回書けばいいのでとても楽です。

しかし、だからこそ**安易に使用しまくって**、めちゃくちゃなクラスが出来上がりがちなようです。
それでは継承の目的やメリット、どういう時に使えばいいのかを見ていきましょう。

### 2.1 継承の利点
基本的に、あちこちのコードに同じことが書いてあると文字数が増えてわかりにくいですよね。
このわかりやすさを追求すると、便利に使えて、かつ変更に強くなるのです。

#### 2.1.1 変更に対応しやすくなる
複数のクラスに全部書いてるようなメソッドを直さないといけない！　となった時、親クラスにまとめていないと、まずはどのクラスにそのメソッドを書いていたかを全部探し尽くして、１つ残さず直さないとなりません。
1つでも漏らしたらバグが生じます。
しかし、親クラスにまとめていれば、１箇所直したらそれでオッケーです。

例えば「自動車」というクラスがあったとして、自動車にも技術革新はつきものですから新しいパーツを導入していく必要があるわけです。
もし１０種類の自動車クラスを製造していたとして、エンジンというパーツを各クラスで定義していた場合、新型エンジンに交換しようとすると全クラス書き換えが必要です。
こういう頻繁に取り替えたい部品を親クラスにまとめてしまうことで、簡単に取り替えが可能になるのです。

#### 2.1.2 機能拡張しやすくなる
これは次回説明するポリモーフィズムにも通ずる考え方になります。
例えば子クラスの部品を取り替えるだけではなく、親クラスにぶら下がっている子クラスを簡単に増やしたり減らしたりできるようになります。

また、プログラムを作成している時に、最初から全貌が確定しているわけではないと思います。
そうなると「こういう種類のもの」を作るだろうなという「抽象的」なことはわかっていて作業をするわけですが、より詳細な内容はあとあと変更があるかもしれません。

例えば「自動車」を作ることは決まっていて、とりあえずセダンと軽トラは作ろう。ミニバンもやるかもしれないし、ジープも作りたいけど、その詳細までは決まっていないような感じです。
そんな時に、自動車に共通する規格ーー例えば、タイヤ、ハンドル、シート、エンジンなどを部品として先に作ってまとめておけば、あとで車種を増やした時にも基本パーツはある程度揃った状態で増やせるわけです。
いざミニバンも作ろう！　と思ったら、規格品であるハンドルやエンジンは親クラスから継承して、ミニバン用のシャーシとか、ボディとかだけを作ればよくなります。



###2.2 継承 ＝ 共通部品を取り出して「規格」を作る
継承には親クラスと子クラスを**「共通部分（規格）」**で繫ぎとめるような**「結節点」**を作る役割があると言えます。
子クラスから見れば、他の子クラスとの「共通部品」を束ねて繋ぎ止めてくれる存在が親クラスです。
親クラスにお願いすれば、みんなの共通部品を一気に書き換えできます。
親クラスから見ると、親クラスに記載されている定義を共有している、脱着可能な構造をいくつもぶら下げているような感じです。
「まだ思いついてないけど共通の部品」を持つものにも対応できてしまう柔軟性があります。

このような便利な継承ですが、やってはいけない継承とはどのような場合でしょうか？
それは、継承を「親の機能を流用できる」機能と勘違いしてされる継承です。

## 2.3 破ってはいけない「AはBであるの原則」
破ってはいけない原則として**「子クラスは親クラスである」**というものがあります。

例えば「自動車」という親クラスがあって、その中に「走る」というメソッドがあったとします。
でもその機能の一部を使い回したい目的で「犬」というクラスに「自動車」クラスを継承したらどうでしょうか。
最初はいいかもしれませんが、「走る」メソッドは自動車用に作られていくため、犬には適合しないはずです。
犬用に修正すると自動車に合わない、自動車用に修正すると犬に合わなくなり破綻します。

あくまで継承の目的は「頻繁に変更する共通部品の抽象化」 であって「抽象化」できないものは継承できません。
なので、種類の異なる親クラスの一部機能を他クラスでもちょっと使いたいから継承、というのは良くないのです。

## 2.4 まとめ

- 継承すると子クラスで親クラスの変数やメソッドを使うことができる
- 継承の大前提は「子クラスは親クラスである」と言えること
- 継承とは「共通部品」を束ねて規格化することであって、親クラスの機能を流用する目的ではない。
- 継承することによって、共通部品の修正交換が簡単になるなど、「変更」に強くわかりやすいプログラムになる。
pyenvのpythonでtkinterを使用する方法

## Issue

pyenvでinstallしたpythonで`python -m tkinter`や`import tkinter`をしたときに以下のエラーが発生。
ネット上の記事を見ると、`brew install tcl-tk`で治るなど書いてあったが、上手くいかなかった。
しかし、どうやら最近リリースされたpyenvの`v1.2.14`でtcl-tkとの互換性が修正されたらしく、[GitHubのissue](https://github.com/pyenv/pyenv/issues/1375)で解決策も書いてあったのでシェアします。

```python
Traceback (most recent call last):
  File "/Users/ken/.pyenv/versions/3.7.4/lib/python3.7/runpy.py", line 183, in _run_module_as_ma
in
    mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
  File "/Users/ken/.pyenv/versions/3.7.4/lib/python3.7/runpy.py", line 142, in _get_module_detai
ls
    return _get_module_details(pkg_main_name, error)
  File "/Users/ken/.pyenv/versions/3.7.4/lib/python3.7/runpy.py", line 109, in _get_module_detai
ls
    __import__(pkg_name)
  File "/Users/ken/.pyenv/versions/3.7.4/lib/python3.7/tkinter/__init__.py", line 36, in <module
>
    import _tkinter # If this fails your Python may not be configured for Tk
ModuleNotFoundError: No module named '_tkinter'
```

## Solution

- Upgrade pyenv (>=1.2.14)

```shell
brew upgrade pyenv
```

- Install tcl-tk

```shell
brew install tcl-tk
```

- Set environment variables

  - If you use bash

      ```shell:bash_profile
  export PATH="/usr/local/opt/tcl-tk/bin:$PATH"
  export LDFLAGS="-L/usr/local/opt/tcl-tk/lib"
  export CPPFLAGS="-I/usr/local/opt/tcl-tk/include"
  export PKG_CONFIG_PATH="/usr/local/opt/tcl-tk/lib/pkgconfig"
  export PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I/usr/local/opt/tcl-tk/include' --with-tcltk-libs='-L/usr/local/opt/tcl-tk/lib -ltcl8.6 -ltk8.6'"
  ```

  - If you use fish

      ```shell:config.fish
  set -x PATH "/usr/local/opt/tcl-tk/bin" $PATH
  set -x LDFLAGS "-L/usr/local/opt/tcl-tk/lib"
  set -x CPPFLAGS "-I/usr/local/opt/tcl-tk/include"
  set -x PKG_CONFIG_PATH "/usr/local/opt/tcl-tk/lib/pkgconfig"
  set -x PYTHON_CONFIGURE_OPTS "--with-tcltk-includes='-I/usr/local/opt/tcl-tk/include' --with-tcltk-libs='-L/usr/local/opt/tcl-tk/lib -ltcl8.6 -ltk8.6'"
  ```

- Reinstall python via pyenv

```shell
pyenv install 3.7.4
```

- Run tkinter

```shell
python -m tkinter
```

- Solved :beer:

## Reference

- [pyenv install doesn't work with homebrew installed tcl-tk · Issue #1375 · pyenv/pyenv · GitHub](https://github.com/pyenv/pyenv/issues/1375)
jQueryでパスワードを見えるようにする

Railsでパスワードの入力フォームを使っているときに、パスワードが可視化できないと不便だと思って調べました。

## 環境
Rails 5.2.3
jQuery

## 留意点
htmlはhamlで記述。

## コード
```new.html.haml
%input#passcheck{:type => "checkbox"}
```

```sign_up.js
$(document).on('turbolinks:load', function() {
  $(function() {
    $('#passcheck').change(function(){ // passwordの切り替え
      if ( $(this).prop('checked') ) {
          $('.password').attr('type','text');
      } else {
          $('.password').attr('type','password');
      }
    });
  });
});
```
htmlに表示切り替え用のチェックボックスを作り、イベント発火用にidを付与します。
Javascriptのchangeイベントで表示の切り替えをしますが、この時、propメソッドでチェックボックスの状態を判別します。
最後にattrメソッドでtypeをtextかpasswordに変更します。
typeが変わっても中身のテキストは消されないのが便利でした。

**propメソッド**
[prop(attr)の使い方](https://www.sejuku.net/blog/36294)にも書かれているように、propメソッドは「checked」や「disabled」などのプロパティを使って条件分岐するようなケースで使い、結果として、trueかfalseを返してくれます。

## 実行結果
![demo](https://gyazo.com/4ecd1b0e6c1e0b82a7fce25d535b786b/raw)

自分のアプリケーションではチェックボックスにbootstrapのtoggleを適用させているのでこのような見た目になっています。

## 参考サイト
[jQueryやJavaScriptでパスワードフィールドの文字を表示する方法](http://www.koikikukan.com/archives/2014/05/12-015555.php)
学習記録＃3

#今日やったこと

- progate：RubyⅠ復習
- progate：RubyⅡ-1-2 まで

#####課題点
- スケジューリング：大学の課題との兼ね合い→もう少し調整用の遊びを持たせる
- 時間割つくってみる？

##progate：RubyⅠ復習
スライド流して復習した上で最終課題をした。
UnityでやるC#と気をつけないと混ざる。並行してやってる悪い点。比較して共通点見つけたりできるのは楽しいけど。

##progate：RubyⅡ-1-2 まで
できればⅡを終わらせるまでいきたかったけど〆切近い課題を優先。週末で調整したい。
【ELB(AWS)】Railsアプリを常時SSL化したらアプリにアクセスできなくなった

一度デプロイに成功したアプリケーションが常時SSL化をしたところ、pcからならアクセスできるけどスマホからだとアクセスできない、なんてことになりました。

ものすっごい初歩的なところで１日かけてしまったので、自分への戒めも含めて投稿しようかと思います。


## 前提

・EC2インスタンスランニング状態(ポート：HTTP 80を開き、ソースはロードバランサのセキュリティグループを指定)
・ロードバランサのターゲットグループのステータスはHealty(ポート：HTTP 80を設定)
・ロードバランサのDNS名にはAレコードが設定されている
・ロードバランサのリスナー：HTTPS 443 (SSL認証書も紐づいている)
・コンソールからec2-userにログイン可能
・本番環境内のproduction.logにはFatalやErrorの記述なし
・Capistranoの自動デプロイにエラーなし

##### しかしアプリにアクセスできたりできなかったりする！！

## 結論

##### ELBのセキュリティグループインバウンドでソースにマイIPを指定していた

つまり、自宅のWifiなら接続できるけど、スマホの通信やカフェのWifiじゃ条件が違うからアクセスできなかっただけのこと！

時間経過でだめになってるのかと思っていました…
なんて愚かなんでしょう…

## 概念図(これが超重要！)

一番の敗因は概念図を理解していなかったことだと思います。
自分の構築した設定が、どんな構造をしているのかわかっていなかった。

ちなみに今回の場合の概念図は下図です。

![01-01-パターン1：ELB証明書→EC2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434850/c2d8856f-5e98-bf5c-78fd-14a2eae30c75.png)

## 最終的にはこんな設定になりました

### ①ロードバランサーのリスナー設定
<img width="1205" alt="ロードバランサ リスナー.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434850/530785b8-85b7-3cdc-723d-3ec4287e097c.png">

### ②ロードバランサーのインバウンド設定
<img width="1212" alt="ロードバランサーのインバウンド.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434850/3c8c4b91-a294-9a19-d25b-131f88646b10.png">

### ③ターゲットグループの基本設定
<img width="1211" alt="ターゲットグループ基本設定.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434850/e3ea61e5-c585-c99c-bef3-8eb606251535.png">

###  ④ターゲットグループのEC2インスタンス設定
<img width="1204" alt="ターゲットグループ インスタンス設定.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434850/9c35b598-2447-3161-e01d-6d3644d8465c.png">


### ⑤EC2インスタンスのインバウンド設定
<img width="1128" alt="EC2インスタンス.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434850/555fb390-eb89-13e8-95ac-a662e7fd59c0.png">


### ⑥Route53のロードバランサー設定
<img width="1225" alt="Route53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434850/512f5227-9e06-3bfc-0b73-77aa83dda065.png">



## 成功パターン
上記の設定をしたものを概念図に書き起こすと、こうなります。
クライアントからEC2まで適切なポートと信号を設定してあげて通信をする、というイメージでしょうか。

![成功.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434850/e5e376f6-0dc5-ffad-2e16-f1bab8ad050b.png)


## 失敗パターン
今回の場合僕は、②の時にロードバランサーのインバウンド設定の時にソースとして自宅のIPアドレスを指定していたということです。
つまり概念図に書き起こすとこんな感じです。ちょっと見にくいですね、編集能力なくてごめんなさい・・・。

![成功.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434850/66c091d6-52be-574a-23ac-31dd3cfa6820.png)

なんと頑固なロードバランサーであろうか・・・。

この設定をしてしまっていたので、自宅Wifiを使った環境のものならばアプリケーションにアクセスできるけど、場所を移動してカフェから繋いだり、スマホからアクセスしようとすると繋がらなかった、ということみたいです。

## まとめ
とにかく一度手を動かしてみるという信条で勉強していて、その方針は間違っていないんじゃないかなと思います。
ただ本を読んだだけで理解できるほど頭も良くないので・・・。

しかしこうして詰まった時に一度俯瞰してみたりとか、実装段階でちょっとずつでも概念を噛み砕いていく癖をつけないとなと思いました。

Qiitaに書いてあったから、ブログに書いてあったから、その結果動いたからこれでOK！というのは危険だなと感じました。
反省です・・

## 補足
ちなみにデプロイの際にはNginxを使っているのですが、Nginxのconfファイルの設定で、listen 80;にしています。

ここが違っているのであれば、概念図とそのポート番号とかはまた変わってくるかと思います。
RobolectricでBackボタンのテスト

Androidのローカルテストで、フレームワーク依存のコードのテストを書く際にはみなさん、Robolectricを使っているかと思います。
今回はActivityやViewに対するBackボタン＝戻るボタン処理の挙動をテストする方法をメモります。

大した内容じゃないですが、再度調べなくて良いように。

## なぜ戻るボタンのテストをしたいか？

普通にライフサイクルのテストとかするなら、activity.pause()やactivity.finish()などを呼ぶのがいいと思います。
今回テストしたかったのは、以下の動作確認がしたかったからです。

- Activity内のViewが特定条件で戻るボタンをconsumeするので、条件を変えた際の戻るボタンのイベント伝播を確認したい。
- Activityが戻るボタンを受けとった際の処理をテストしたい。
   - onBackPressedがコールされること。 
- 特定viewに対するkeyEventを送信することでテストを記述したい。
    - 手動で呼べば再現できるけど、なるべくフレームワークの実装通りに伝播させたい。

## 戻るボタンイベントの渡し方

結論ですが、以下のようにKeyEventをdispatchすることで、Viewを通してActivityにイベントを伝播させることができました。

```kotlin
@Test
fun バックボタンを押すとActivityが閉じる() {
    // onBackPressedは戻るボタンのUp時に発火される。
    val keyEvent = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK)

    // ただし、KeyEvent自体が該当Viewに対してDownされてTracking状態になっていないと発火しない。
    // そのため、trackingを監視するクラスにDownイベントを渡して開始させて、Upイベントにフラグを立たせる。
    val state = KeyEvent.DispatcherState()
    state.startTracking(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK), null)
    state.handleUpEvent(keyEvent)

    // KeyEventがisTrackingかつisCanceledじゃない時、onBackPressedが呼ばれる。
    println("event: ${keyEvent} ${keyEvent.isTracking()}, ${keyEvent.isCanceled()}")

    // イベントは伝播して誰かにconsumeされる
    val consumed = view?.dispatchKeyEvent(keyEvent)
    assertThat(consumed).isTrue()

    // onBackPressedが呼ばれてActivityがfinishしている。
    assertThat(activity.get().isFinishing).isTrue()

}
```

KeyEventの伝播の仕方は次のような順番でした

1. Focusの当たったView
2. Parent ViewGroupをたどる（行き着くまで）
3. DecorView
4. PhoneWindow
5. Window.Callback(Activityが継承してWindowに登録している)

ActivityとWindowクラスの関係がイマイチ理解できていないですが、Activityで受け取るタイミングは後ろの方でした。

## 参考

AOSPのActivityやKeyEventのコードを見ればわかることでした。

https://github.com/aosp-mirror/platform_frameworks_base/blob/android10-release/core/java/android/app/Activity.java#L3636-L3646

```java:Activity.java
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (getApplicationInfo().targetSdkVersion
                >= Build.VERSION_CODES.ECLAIR) {
            if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking()
                    && !event.isCanceled()) {
                onBackPressed();
                return true;
            }
        }
        return false;
    }
```

https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/view/KeyEvent.java#L2890-L2898

```java:KeyEvent.java
        public void startTracking(KeyEvent event, Object target) {
            if (event.getAction() != ACTION_DOWN) {
                throw new IllegalArgumentException(
                        "Can only start tracking on a down event");
            }
            if (DEBUG) Log.v(TAG, "Start trackingt in " + target + ": " + this);
            mDownKeyCode = event.getKeyCode();
            mDownTarget = target;
        }
```

ちょっと行き着くのに時間かかってしまったのでメモしておきます。
Neural Architecture Search研究のベストプラクティス

# はじめに
- 自己紹介：UbuntuでPythonを書いてデータ分析とか異常検知してます。
- AutoMLの一つであるNAS(Neural Architecture Search)に興味があります。
- 「Neural Architecture Search研究のベストプラクティス」というpaperを翻訳しました。
- https://arxiv.org/abs/1909.02453
- イイネと思ったらぜひフォロー, thumbs-up&拡散をお願いします！


# 目次
- イントロ
- コードをリリースする時の3項目
- NAS手法を比較する時の8項目
- 詳細をレポートする時の3項目
- まとめ

# イントロ
!["NAS論文数の推移"](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331449/341c2cab-35c9-6de0-a8fc-549c46affd2e.png)
図:NAS論文数の推移

NASはホットトピックですが、AIの他の分野と比べて、実証評価の質は負けています。
再現性を高める為のチェックリストを作りました。
再現性は、分野の持続的な進歩に繋がります！

# コードをリリースする時の3項目
**①学習パイプラインを公開する**
学習パイプラインはNNの構造より精度に寄与する事もある。
・最適化手法
・正則化手法
・学習エポック数
・活性化関数
・学習率調整手法
・Data augmentation手法
なども公開しよう。

**②NASのコア部分のコードを公開する**
自明。これがないと追試は不可能。

**③コードが十分にきれいになるのを待たず、すぐ公開する**
「コードが十分にきれいになる」時なんて、永遠に来ない。

# NAS手法を比較する時の8項目
**①同じデータセット+同じベンチマークを使おう**
同じデータセットを使ったとしても、
・探索空間が違う
・最適化手法が違う
・正則化手法が違う
・ハイパラが違う
などの理由で正しく比較できない事がある。

以下のような、一貫したNASベンチマークを使おう!
例1：DARTS (Liu et al., 2019b)と同条件でやる
例2：NAS-Bench-101 (Ying et al., 2019)というベンチマークを使う

**②Ablation Studiesをしよう**
複数の工夫を適用するなら、一つ抜きで実施してみること。
そうしないと、どれが効いているかわからない。

**③同じ評価手法を使おう**
自明。

**④処理時間-パフォーマンスの関数を作ろう**
特定の処理時間におけるパフォーマンスを比較・評価することは非常に大切。

**⑤ランダムサーチと比較しよう**
baselineと比較することも大事。
探索空間を適切に設計すれば、実はランダムサーチはかなり有効な手法。

**⑥結果の評価は何回かやってみよう**
確率的手法なので同じ手法&データでやっても同じ結果が返るとは限らない。
NASの実験はお金がかかるけど、最近の手法はそこまででもないから安心。

訳注：CIFAR-10の探索コスト, テストエラー
NAS(Zoph&Le,2016)：GPU800台で28日, 2.65%
ENAS(Pham et al., 2019)：0.45[GPU台x日], 2.89%
ASNG-NAS(Akimoto et al., 2019)：0.11[GPU台x日], 2.83%

**⑦tabular benchmarksを使おう**
・NAS-Bench-101
・NAS-HPO benchmarks
などのtabular benchmarksは、GPUを使わずにNASの評価ができる！

**⑧交絡因子をコントロールしよう**
上記の項目以外にも、
・ハードウェア
・ライブラリのバージョン
などで結果に違いが出るので注意しよう。
apples-to-applesで評価すること！
訳注：同じ条件で適切に比較することをapples-to-applesという。


# 詳細をレポートする時の3項目
**①ハイパラ最適化手法をちゃんと書く**
「ハイパラ調整まで自動化してこそのNAS」みたいな風潮のせいで、
あいまいにしか書かない人がいるけどNG。

**②時間計測はエンドトゥエンドで計測しよう**
NASをスタートしてから最終的なNNを返すまでの時間を記録しよう。
例えば、train時に潜在的に学習していたNNをvalidation時に呼び出すモデルで、
validationの時間しか報告しないのはNG。

**③実験のセットアップの全てを明示しよう**
自明。

# まとめ
**「再現性は脚光に勝る(Reproducibility is ever more in the limelight)」**
サーバのクラスタリングについて

#クラスタリングをする意味
あくまで自分用メモです。

クラスタリングとは複数のサーバをネットワークで接続し、一つに見せる技術の事でいつどこで障害が起こるか分からないサーバのデータを複数台で共有し、いずれかのサーバが壊れてもその一台だけをネットワークから切り離し、
残りのサーバで処理を続け、信頼性を上げるためにこういった構成にする。

#クラスタを組むためにはクラスタソフトウェアが必要。

Windowsserverでは
・マイクロソフト製　microsoftclusterservice
・NEC製　CLUSTERPRO

linuxでは

・オープンソース　heartbeat
・サイオステクノロジー　lifekeeper

等が存在する。

#ストレージ構成
クラスター構成はストレージの持ち方によって
「共有ストレージ構成」
複数のサーバで共有するストレージを用意することによって
障害時にデータの整合性を確保する方式
拡張性が高いので、大規模なシステムで採用されている。
「データミラー構成」
ローカルディスク上のボリュームのコピーをネットワークで送るによって
障害時におけるデータの整合性を確保する方式

の2つに分かれる。

#どうやって冗長性を確保している？
クラスター構成では、クライアントからのトラフィックを「仮想IPアドレス」
というIPで受け付ける。

クラスターはこの仮想IPアドレスをアクティブサーバに付け替えることで、冗長性を確保している。

#RADEとはなんなのか

ITパスポートの取得をする際に勉強範囲として学んだが、
簡単に表すと「障害が起きた時にいかにデータを守るか」というシステム。

企業用のサーバ内データはサービスの損失だけでなく金銭や信用問題にも
関わってくるものなので、どうやってもデータを守る、被害を最小限に食い止めなければならない。

データを冗長化する方法として一般的には
「RADE1」
ミラーリング（複数のドライブに同じデータを保存、同じデータを複数のドライブで持つのでディスク容量の面では非効率）

「RADE5」
分離パリティ（データを修復する為のデータを複数のドライブに分散、信頼性とディスク容量の効率性を両立）

「RADE1+0」
（ミラーリングとストライピングのハイブリッド、複数のドライブにデータを書き込むことで読み込みと書き込みが高速に行える）

RADEを組むときは複数のハードディスクを用意し、「RADEコントローラカード」という専用カードを使用して複数ドライブをつなぐ。
[JavaScript]サブドメイン許可 url 正規表現 チェック

#はじめに
@htsignさんにご指摘頂いたので記事訂正してます！
@htsignさん本当にありがとうございます！:bow_tone1:

タイトルが適当でごめんなさい:bow_tone1:
『この正規表現ではこれが通っちゃうよ！』などあれば教えて頂けると嬉しいです。
『この正規表現どこで使うの?』ですが、主にフィッシング詐欺対策かな？と思っています。
どう書こうか悩んでしまったためqiitaに載せました。:bow_tone1:

#想定URL
今回の『モデル』はqiitaにさせて頂きます:bow_tone1:

○合格のurl例
`http://qiita.com`
`https://qiita.com`
`https://sample.qiita.com`
`https://qiita.com/sample`
`https://qiita.com/sample/aaaa?a=aa`
`https://qiita.com/sample/aaaa?a=aa&b=bb`
`https://b.qiita.com/sample/aaaa?a=aa&b=bb`

×不合格のurl例
`http://qiitaacom`
`http://a.com/qiita.com`
`https://a.com/qiita.com`
`javascript:alert( 'test' )`
`https://aqiita.com`
`https://a.com?qiita.com=a`
`https://aaa.com/qiita.com?a=aa`

#正規表現

```.js
/^(https|http):\/\/([a-z]{1,}\.|)(qiita\.com)(\/(.*)|\?(.*)|$)$/g;
```
<font color="red">『キャプチャ』なしにしたい場合の記述は以下です！</font>

```.js
/^(?:https|http):\/\/(?:[a-z]{1,}\.|)(?:qiita\.com)(?:\/(?:.*)|\?(?:.*)|$)$/g;
```
一応キャプチャありなしの画像です！
<img width="836" alt="スクリーンショット 2019-11-02 15.40.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133940/7d8ceb48-90e7-7ef9-9be8-82e5db0259dc.png">
※https://rubular.com/
$\tiny{Ruby用の正規表現のツールなのですが、正規表現はほとんど変わらないので、よく使わさせて頂いているツールです！}$

キャプチャとは、後で『()』に入ったものを取り出せるためのもの。
キャプチャにしておくことで配列にして取って置いてくれるので、
後で一致した値が何かを知りたいときなど非常に便利！
しかし、
そうでない場合以下のようなことがあるのでしないほうがいいです。

>数百万回くらい実行すると性能に差が出ると思われます

ちなみにキャプチャなしにしたい場合は『(sample)』と言う記述を『(?:sample)』といった感じにします。

#具体的な判断チェックcode

```.js
const newValue = 'https://sample.qiita.com';
const pattern1 = /^(https|http):\/\/([a-z]{1,}\.|)(qiita\.com)(\/(.*)|\?(.*)|$)$/g;
const result1 = pattern1.test(newValue);
if (result1) {
    console.log('合格', result1)
}else{
    console.log('不合格', result1)
}
```

#正規表現メソッドについて
色々なメソッドがあるので全てみたいと言う方は以下のMDNのサイトをご覧ください！
参考:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp
今回は『exec』と『test』の違いについて説明します。

ちなみにこれらの場所は上のcodeで言うと以下の部分です！

```.js
const result1 = pattern1.test(newValue);
```

違いですが、『exec』は検索で、『test』はテストです。

なので、対象とするものが『あっている』『あっていない』のみ知りたい場合は『test』を使うといった感じにとらえるのが良さそうです！

ちなみに値がない時の出力は、
検索の場合が『null』、
テストの場合が『false』
です。

```.js
RegExp.prototype.exec() //検索
```

```.js
RegExp.prototype.test() //テスト
```



#正規表現の説明
:blush:

```
^(https|http):\/\/
```

始まりから[https://]または[http://]かのチェック

:information_desk_person_tone1:他の書き方では`^https?:\/\/`ができます！教えて頂きました！
好きな方を使って下さい！

:blush:

```
([a-z]{1,}\.|)(qiita\.com)
```

`([a-z]{1,}\.|)`は『a~z』のアルファベット1文字以上+『.』または何もなし。

:information_desk_person_tone1:他の書き方では`([a-z]{1,}\.)?`ができます！教えて頂きました！
好きな方を使って下さい！

`(qiita\.com)`の中の『\.』は『.』が特殊な文字なので『\』によってエスケープしていると言う感じです。

他にも許可したい場合`(qiita\.com|aaa\.com)`のように書けば大丈夫です。
※エスケープ…特殊な文字をただの文字列として認識するためのもの

:blush:

```
(\/(.*)|\?(.*)|$)
````

『/』+なんの文字が来てもいい
※ドメインの後にパスが続く想定

『?』+なんの文字が来てもいいい
※ドメインの後にパラメーターが続く想定

何もなし
※ドメインの後に何も来ない想定

#最後に
以上！終わりです！(｡･ω･｡)
今眠いです！:sleeping:
Spring Boot でテーブルのデータをビューに出力するまでの流れ

## 事前に必要なこと
・DBへの接続設定を行う

## 大まかな流れ
Usersテーブルからデータを取得し、表示するという設定です。

1. エンティティを作成する
2. リポジトリを作成する
3. コントローラを作成する
4. ビューを作成する

## エンティティを作成する
Usersテーブルのデータを取得した値を保存するのに利用する。

```com.example.entities.UsersEntity.java

@Entity
@Table(name="Users")
public class UsersEntity{
  @Id
  private Integer id;
  private String name;

  public Integer getId(){
    return id;
  }

  public String getName(){
    return name;
  }
}
```

## リポジトリを作成する
リポジトリはDBとデータのやり取りを行う。

```com.example.repositories.UsersRepository.java
import com.example.entities.UsersEntity;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UsersRepository extends JpaRepository<UsersEntity, Integer>{
}
```

## コントローラを作成する

```com.example.controller.UserController.java
@Controller
public class UserController{
  @Autowired
  // 変数に代入
  private UsersRepository usersRepository;

  // このURLにアクセスした際の動作
  @RequestMapping("/index") 
  public String index(Model model){
    List<UsersEntity> users = usersRepository.findAll();
    model.addAttribute("userlist", users);
    return "view/user/index";
  }
}
```

## ビューを作成する

```/view/user/index.html
  <table>
    <tr th:each="users : ${userlist}">
      <td th:text="${users.id}"></td>
      <td th:text="${users.name}"></td>
    </tr>
  </table>
```