OmniAICreator/Qiita-1.07M huggingface dataset:
nginxのstatusを表示するモジュール /nginx_status


### 1. Add `http_stub_status_module` 
nginxをbuildするときにこれを入れる


```c

  && ./configure \
  ...
  --with-http_stub_status_module \         <--------------
  ...
```

Dockerfileの例
https://qiita.com/uturned0/items/3a0a7cb971edac40b11e


### 2. Enable conf

```nginx
server { 
   listen       80;

   location = /nginx_status {
       stub_status;       # <--------これだけ
   }

   location = / {
       # ...
   }

}
```

### 3. access

http://localhost/nginx_status 的な。

殺風景すぎる問題はあるが、まあ、動いてるのねくらいには使える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/7330f3d5-1f87-7845-bc9b-637486f5b69b.png)






#### nginx posts
nginxのstatusを表示するモジュール /nginx_status
https://qiita.com/uturned0/items/b4eb6839d75050933c7f

nginxにモジュールを追加できるDockerfile
https://qiita.com/uturned0/items/3a0a7cb971edac40b11e

nginxリバプロで header を cookieに書き込む方法
https://qiita.com/uturned0/items/112b8faba403bd534d5c

nginxリバプロで、requestに入っているheaderをlogに出す方法
https://qiita.com/uturned0/items/31162eeb03af05c7dc4b

nginxだけでコンテンツを返す方法 - Load balancerのhealth checkに
https://qiita.com/uturned0/items/a8bcca111b75c5055ed9
はてなブックマークのリンク生存確認スクリプト

# 目的

自分のはてなブックマークに貯めこんだリンクについて、デッドリンクがあれば知りたいなーと思い、Python で書いてみました。

特定のユーザー (想定は自分) のはてなブックマークを一個一個アクセスし、レスポンスコード `200` が得られない場合はタイトルを出力しています。

はてなブックマークで公開されている [REST API 系](http://developer.hatena.ne.jp/ja/documents/bookmark/)ではユーザーのブックマーク一覧を取得できないようでしたので、[RSS](http://developer.hatena.ne.jp/ja/documents/bookmark/misc/favorite_feed) から取得しています。

# コード

```Python
import feedparser
import requests

currentPage = 1
USERNAME = "<はてなブックマークのユーザー名>"

URL = "https://b.hatena.ne.jp/{user}/bookmark.rss?page={page}"
geturl = URL.format(user=USERNAME,page=currentPage)

rssResponse = feedparser.parse(geturl)

# とりあえず中身があるかどうか確認
if len(rssResponse.entries) == 0:
    exit("何かが間違っていると思います")

# メインのループ処理
while True:
    for entry in rssResponse.entries:
        try:
            currentUrlStatusCode = requests.get(entry.link).status_code
        except requests.exceptions.RequestException as e:
            currentUrlStatusCode = e

        if str(currentUrlStatusCode) != "200":
            print(entry.title, ": NG (", currentUrlStatusCode, ")")
    
    currentPage = currentPage + 1
    geturl = URL.format(user=USERNAME,page=currentPage)
    rssResponse = feedparser.parse(geturl)

    # 簡易的な進捗表示。不要な場合はコメントアウト
    print(currentPage)

    # 要素数が 0 なら終わり
    if len(rssResponse.entries) == 0:
        break

print("終わり。最後のページは ", currentPage, " です。")
exit(0)
```

## 出力イメージ

```
...
<中略>
IBM Redbooks | Linux : NG ( 404 )
Exchange 2013 の CPU 使用率の上昇のトラブルシューティング | Microsoft Docs : NG ( 404 )
Not found | Nomura Research Institute (NRI) : NG ( 404 )
33
OSS iPedia 記事 : NG ( HTTPConnectionPool(host='ossipedia.ipa.go.jp', port=80): Max retries exceeded with url: /doc/201/ (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x000001EBC957F460>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed')) )
OSS iPedia 記事 : NG ( HTTPConnectionPool(host='ossipedia.ipa.go.jp', port=80): Max retries exceeded with url: /doc/457/ (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x000001EBC9537100>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed')) )
PowerShell DSC for Linux is now available! - Windows PowerShell Blog - Site Home - MSDN Blogs : NG ( 403 )
34
終わり。最後のページは  34  です。
```

## 動作確認環境

* Windows 10
* Python 3.8.3 64-bit

## 備考

* リンクによっては「ドメインがもう無い」など様々な理由でコネクションエラーになったりするので、エラー処理をかませています。
* RSSフィードを操作する際は、[feedparser](https://pythonhosted.org/feedparser/) を利用しています。XML を操作しなくて良いので、すごく楽でした。
* はてなブックマークの RSS の仕様やサンプルページは[こちら](http://developer.hatena.ne.jp/ja/documents/bookmark/misc/favorite_feed)にあります。
React初心者覚書07 - フォーム ー

[Reactの記事](https://ja.reactjs.org/docs/forms.html)を参考に初心者がわからないけど覚書を書いています。

### FORM

- Formは内部になんらかの状態をもっているので、他のDOM要素とは少し異なる

```html_form.html
<form>
  <label>
    Name:
    <input type="text" name="name" />
  </label>
  <input type="submit" value="Submit" />
</form>

```

- フォームの送信に応答してユーザがフォームに入力したデータにアクセスするような JavaScript 関数があった方が便利
- "制御された (controlled) コンポーネント” と呼ばれるテクニックを使う

#### 制御されたコンポーネント= React で値を制御している入力フォーム要素のこと


- HTML では <input>、<textarea>、そして <select> のようなフォーム要素は通常、自身で状態を保持しているが、
Reactでは、変更されうる状態は通常はstateプロパティに保持され、setState()関数でのみ更新される。

#### this.handleChange = this.handleChange.bind(this);がわからない
NameForm.handleChange = NameForm.handleChange.bind(NameForm);ってこと？

でも見てたら何をしているかはなんとなく理解。
フォームイベントが起こると、 NameFormクラス自身の中で、イベントの内容に合わせて変更されるってこと？

```nameform.js

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

ReactDOM.render(
  <NameForm />,
  document.getElementById('root')
);

```
VSCodeで「プロキシ認証が必要」ダイアログを２回表示させないで起動する方法

# VSCodeで「プロキシ認証が必要」ダイアログを2回出さない方法

　Microsoft Visual Studio Code（以下`VSCode`）を起動するたびに２回も表示される「`プロキシ認証が必要`」ダイアログを出さずに起動する方法を書き殴ります。この悪魔のダイアログに2回も同じプロキシサーバのユーザIDとパスワードを入力するのが超面倒くさいのでこの記事を書きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124810/30c0bb42-8282-d028-6a96-652e96de2cf8.png)

* 前提条件
    * Windows10 Pro

とします。

　システムインテグレータでご勤務されている方には、開発環境がWindows10 Proでプロキシサーバが外部のインターネットとの間に立ちはだかって関所になっているところは多いと思います。

　フリーランスで自宅でMacBook Proな人や、多くのWeb系自社開発・受託開発企業で、Mac Book Proで、かつプロキシサーバなんて設置していない会社な人は、関係ない世界だと思います。（かく言うこの私も自宅でプロキシサーバーの無い平和な環境でMacBook ProにBENQの31.5インチ４Kディスプレイを繋いでこの記事を書いているので、実は関係ない人です。）

　でも、システムインテグレータ会社に勤務するシステムエンジニアや、そこにシステムエンジニアリングサービス（SES）で常駐しているエンジニアな人はそうではないと思います。皆さんどうしているんでしょうねぇ〜？「そんなしょうもない事記事にせんでもええわあー。ちゃんとやっとるわい」てな感じでしょか？

## 以下のショートカットを「VSCode-Proxy」という名前で作成します。

```terminal
code --proxy-server="http=http://ProxyユーザID:Proxyパスワード@proxyサーバ名:8080"
```

## ショートカットのプロパティを設定します

* ショートカットアイコン　:arrow_right:　コンテクストメニュー　:arrow_right:　プロパティ

* プロパティダイアログ :arrow_right: アイコンの変更　ボタンを押します

* このファイル内のアイコンを検索
    * :arrow_right:　`%USERPROFILE%\AppData\Local\Programs\Microsoft VS Code\Code.exe`

* 下の一覧から（と言ってもアイコンは見慣れた`VSCode`アイコン しか表示されないはずですが・・）　:arrow_right:　`VSCode`アイコンを選択します

* :arrow_right:　[OK]ボタン押します

## 以下のパスに上記のショートカットを置きます

* VSCodceをユーザーインストールした場合は以下の場所になります

```terminal
C:\Users\Windowsアカウント\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Visual Studio Code
```

* 左下Windowsスタートアイコン　:arrow_right:　Visual Studio Code 　:arrow_right:　「VSCode-Proxy」 :arrow_right:　右ボタンクリック　:arrow_right:　コンテキストメニュー　:arrow_right:　スタートにピン留めする

* 左下Windowsスタートアイコン  :arrow_right:　スタートメニュー　:arrow_right:　`VSCode`　:arrow_right:　VSCodeが起動

　以上を行って、　左下Windowsスタートアイコンを押して出てくる「VSCode-Proxy」アイコンをクリックして起動する`VSCode`には二度と再びあの忌まわしい「プロキシ認証が必要」ダイアログは出ませんよ。　:arrow_right:　ばんざ〜い🤗　ばんざ〜い🤗　ばんざ〜い🤗　

　しかもプロキシサーバ認証は行ってくれるというね。なかなか便利です。こんな簡単な事も知らずに`VSCode`起動時に無駄な時間を消費していた私はなんとおバカさんだったのでしょう・・・。

## Windows10スタートメニューに配置した例
　私の場合`VSCode-proxy`という名前を付けて区別しています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124810/be790828-9d8c-31d9-ac3b-50285c6d0d64.png)
GoogleAppsScript　スプレッドシートの名前付き範囲から値を取得する

#スプレッドシートの名前付き範囲から値を取得する
スプレッドシートに設定を記述し、何らかの処理をする場合、名前付き範囲が便利です。

スプレッドシートの名前付き範囲から値を取得する方法を書きます。

例えば↓のようなスプレッドシート
A1～B6に　料理の味　と名前付き範囲を設定したと仮定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369082/410f1878-a87d-5807-b559-a4a47916692f.png)

ポイント
1 まずスプレッドシートを取得→名前付き範囲の取得と進みます。エクセルのようにシート名の指定はいりません。
2　戻り値は二次元配列です。2次元配列とわかれば取り出し方は簡単!!indexOfで検索したりもできます。

```GAS:スプレッドシートの名前付き範囲の値取得

  var sheet = SpreadsheetApp.openById('シートのID');
  var cook = sheet.getRangeByName('料理の味').getValues();
  Logger.log(cook[0][0]);　//料理の味
  Logger.log(cook[0][1]);  //
  Logger.log(cook[1][0]);  //とてもおいしい
  Logger.log(cook[1][1]);  //5.0
```

設定の記述に名前付き範囲は便利ですよね。
nginxリバプロで header を cookieに書き込む方法

login基盤から送られてくる認証情報がheaderでくる。それを処理するにはサーバサイドで拾う必要があるけど、先にvueが拾っちゃうとめんどくさくって。vueに行く前にリバプロ側でcookieに入れたかった。これやったらいろいろ楽になった！

## example.com.conf

`location /login` のところだけで、 `my_header_name` というheaderが来たら cookie `MY_COOKIE_NAME` にセットするようにしてます。

```nginx

upstream lapi {
     server my-server-side.local:5000;
}

server {
    listen       80;
    server_name example.com;

     # required when LB offloads SSL
     proxy_set_header         X-Forwarded-HTTPS     on;

     # reverse proxy parameters
     proxy_buffering          off;
     proxy_set_header         Host                  $http_host;
     proxy_set_header         X-Real-IP             $remote_addr;
     proxy_set_header         X-Forwarded-Host      $host;
     proxy_set_header         X-Forwarded-Server    $host;
     proxy_set_header         X-Forwarded-For       $proxy_add_x_forwarded_for;
     proxy_redirect           off;
     proxy_read_timeout       60000;
     proxy_max_temp_file_size 0;

     location /login {

        # insert cookie when a header comes
        if ($http_my_header_name != "") {
           add_header Set-Cookie MY_COOKIE_NAME=$http_my_header_name;
        }

        proxy_pass http://lapi;  
     }

     location / {
        proxy_pass http://lapi;  
     }

```



nginx 便利！！




#### nginx posts
nginxのstatusを表示するモジュール /nginx_status
https://qiita.com/uturned0/items/b4eb6839d75050933c7f

nginxにモジュールを追加できるDockerfile
https://qiita.com/uturned0/items/3a0a7cb971edac40b11e

nginxリバプロで header を cookieに書き込む方法
https://qiita.com/uturned0/items/112b8faba403bd534d5c

nginxリバプロで、requestに入っているheaderをlogに出す方法
https://qiita.com/uturned0/items/31162eeb03af05c7dc4b

nginxだけでコンテンツを返す方法 - Load balancerのhealth checkに
https://qiita.com/uturned0/items/a8bcca111b75c5055ed9
npm と node.js のインストールから Hello World まで。

Linux もしくは Windows Subsystem for Linux  のターミナルから以下のコマンドを実行し、npm と node.js をインストールする。


```bash
   sudo sed -i -e 's%http://.*.ubuntu.com%http://ftp.jaist.ac.jp/pub/Linux%g' /etc/apt/sources.list
   sudo apt update
   sudo apt upgrade
   sudo apt-get install -y nodejs
   sudo apt install npm

```

任意のフォルダを作成し、その中で npm init コマンドを実行し package.json を作成する。
expressのパッケージをインストールし、アプリケーションのエントリーポイントとして app.js を作成する。

```bash
   mkdir hoge
   cd hoge
   npm init
   npm i express --save

   touch app.js
```

package.json の中身は次の通り。npm init の実行時になされる質問で main で指定するエントリーポイントをデフォルトから app.js に変更している。

```json
{
  "name": "hoge",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Matsuoka",
  "license": "MIT",
  "dependencies": {
    "express": "^4.17.1"
  }
}
```


app.js の中身は次の通り。

```js
const http = require('http');
const express = require('express');

const app = express();

app.use( function (req, res, next) {

    return res.send('こんにちは世界！');

});

let server = http.createServer(app);

server.listen('3000');

```

以下のコマンドで、node から app.js を実行する。

```bash
node app.js 
```

http://localhost:3000/ をブラウザで開く。

![コメント 2020-07-24 003701.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19862/4bebf63b-c246-9ffb-952c-4a6ab9cc6f79.png)
Flutter for Webをintellijで始めたときのメモ

intellijのHPからダウンロード
参考HP
https://sukkiri.jp/technologies/ides/intellij-idea/intellij-idea-mac.html

参考HP
【初心者向け】すぐできるIntelliJ IDEAの最初の使い方
https://qiita.com/syu_chan_1005/items/46f94412f7493d6e60eb

FlutterとDartの二つのPluginをインストール
参考HP
http://gdgkyoto.blogspot.com/2017/10/intellij-flutter.html

参考HP
IntelliJでFlutter Webに入門してHello World
https://qiita.com/ikemura23/items/afe67cc6164a955b6da0
nginxリバプロで、requestに入っているheaderをlogに出す方法

# <1> header まるごと出す方法
ぱっと調べた感じverboseすぎるけどdebug modeが一番よかった。こういうことをしたいときは全体的な動きを作ってるとき、debug中が多いと思うので、debugにするのはいいと思う。

## step 1. debug moduleをいれてbuildする

yumやaptで入れたnginxは、最初から入ってるのでこの手順は不要。**docker hub の nginx official image (`nginx:latest`など）は入っていないので注意**。

```nginx
  && ./configure \
   ...
  --with-debug \
   ...
```
参考
> nginxにモジュールを追加できるDockerfile
> https://qiita.com/uturned0/items/3a0a7cb971edac40b11e


## step 2. 

error logのlevel をdebugにする。これは `nginx.conf` でやってもいいし `server.conf` でやってもいい

```nginx
http {
    error_log /var/log/nginx/error_log debug;
}
```

もしくは

```nginx
server {
    error_log /var/log/nginx/error_log debug;
}
```

## step 3.
リバプロでやってる場合、logを見るとこんな感じで `http proxy header` という行がわかりやすく値を出してくれます。

```js
...
2020/07/23 17:06:42 [debug] 8#0: *1 http proxy header: "X-Forwarded-Port: 443"
2020/07/23 17:06:42 [debug] 8#0: *1 http proxy header: "X-Forwarded-Proto: https"
2020/07/23 17:06:42 [debug] 8#0: *1 http proxy header: "MY_CUSTOM_HEADER1: foovar1"
2020/07/23 17:06:42 [debug] 8#0: *1 http proxy header: "MY_CUSTOM_HEADER2: foovar2"
...
```

# <2> 特定のheaderだけ毎回loggingする方法


nginx 1.19.1 を使用

# nginx.conf

```nginx

http {

    log_format addHeaderlog '$remote_addr - $remote_user [$time_local] ' 
                        '"$request" $status $body_bytes_sent ' 
                        '"$http_referer" "$http_user_agent" "$http_x_forwarded_for" "$request_body" "$http_Authorization" "$http_x_my_header1" "$http_x_my_header2"'
                        '"$http_my_header1" "$http_my_header2" ';

    access_log  /var/log/nginx/access.log  addHeaderlog;


    error_log  /var/log/nginx/error.log debug; |

}
```

`log_format` ディレクティブは http{} の中にしか書けないぽいので `nginx.conf` に書く。

nginx の log_format て不思議ね。single quoteで囲むと改行できるのかな？

`access_log` は各 `server{}` にも書ける。


`$http_x_my_header1` と `$http_my_header1` の２つが `_x_` あるなしであるのは、どっちで取れるのかわからなかったから。今回は `xなし` で取れました。








#### nginx posts
nginxのstatusを表示するモジュール /nginx_status
https://qiita.com/uturned0/items/b4eb6839d75050933c7f

nginxにモジュールを追加できるDockerfile
https://qiita.com/uturned0/items/3a0a7cb971edac40b11e

nginxリバプロで header を cookieに書き込む方法
https://qiita.com/uturned0/items/112b8faba403bd534d5c

nginxリバプロで、requestに入っているheaderをlogに出す方法
https://qiita.com/uturned0/items/31162eeb03af05c7dc4b

nginxだけでコンテンツを返す方法 - Load balancerのhealth checkに
https://qiita.com/uturned0/items/a8bcca111b75c5055ed9
CentOS7系にChromeをインストールする

# 目的

- CentOS初体験でChromeのインストールすら詰まったので方法をまとめる

# 実施環境

- CentOSバージョン 7.8.2003

# 概要

1. rpmファイルのダウンロード
1. yumを利用したインストール

# 詳細

1. rpmファイルのダウンロード
    1. 下記ページにアクセスする。
        - [https://www.google.co.jp/chrome/thank-you.html?brand=CHBD&statcb=0&installdataindex=empty&defaultbrowser=0](https://www.google.co.jp/chrome/thank-you.html?brand=CHBD&statcb=0&installdataindex=empty&defaultbrowser=0)
    1. 64ビット.rpm(Fedora/openSUSE用)を選択して「同意してインストール」をクリックする。 
    1. 「プログラファイルとして保存する」をクリックする。
1. yumを利用したインストール
    1. Downloadディレクトリに移動する。
    1. 下記コマンドを実行してインストールを行う。

        ```terminal
        $ sudo yum -y install google-chrome-stable_current_x86_64.rpm
        ```
    1. ディスクトップ左下の「Kickoff アプリケーションランチャー」をクリックして「アプリケーション」→「インターネット」の中にChromeのアイコンが存在する。
Twitterでコード共有する時に便利かも「Polacode」

## はじめに

[Polacode](https://github.com/octref/polacode)っていうvscodeの拡張が便利です。

外国人の人がナイスな感じにコードを貼り付けているのをよく目にして気になっていたんですよね。

こんな感じのやつ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113181/f357169a-3c26-b733-cf71-348e4d74c66b.png)

ちょっと雰囲気違うけど^^;

他にもツールがあるんでしょうね。

## 使い方

「Polacode」というvscodeの拡張入れて

<kbd>command+shift+p</kdb> 

を押して「Polacode」と入力して、Enterを押せばこんな感じにプレビューが出るから

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113181/db6a411f-c32f-2eb7-7a7c-d6e0da489cfc.png)

写真にしたいところを選択してキャプチャーボタンを押せば終わり

[![Image from Gyazo](https://i.gyazo.com/89c486dfb1895ea919eb8b1e35c8da4e.gif)](https://gyazo.com/89c486dfb1895ea919eb8b1e35c8da4e)


実際キャプチャーを取った画像がこれ

![code.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113181/a41e5b79-c58e-ef93-6df5-d2a06a849d85.png)

これはいいぞ！！！
JS初心者がKintoneカスタマイズ行うために

###どーも「りょうちんです」今回からシリーズものとして、JS初心者がKintoneカスタマイズを行っていく上で感じたことを書いていきますー
業務でKintoneを使用するのですが、カスタマイズはJavaScriptで行います。ただ僕はずっとRubyの学習してたので、JavaScriptはProgateで触ったことと、RailsでjQueryとかをペタペタしてたくらいです。苦笑

[「cybozu developer network」](https://developer.cybozu.io/hc/ja) ← こちらからKintoneカスタマイズのチュートリアルを開始できます。

ProgateのJavaScript(ES6)コースを受講した程度の知識レベルでもとりあえず始めることができると思います。

チュートリアルタグをクリックすると下記のような感じの画面が表示されます。
<img width="400" alt="スクリーンショット 2020-07-23 23.42.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580882/38a877d0-8121-9983-f2e2-03994be6b9c5.png">

まずはざっと「Kintoneカスタマイズをはじめる前に」を読んで... 次に「はじめようJavaScript」を開始します。
#####ProgateとかでJavaScriptを触ったことがある人は、第10回まではおさらい程度に流し読みでいいかと思います。
第11回から実際にKintoneカスタマイズを行っていくのですが、ここから第16回まで、回が上がるごとにどんどん複雑な内容になります。Kintoneに用意されている便利な関数（Kintone JavaScript API）を多用していくので、初めはクラっとくるかも知れません。笑
なので、プログラミング初学者の方は全部把握しようとせずに、「大体のイメージを掴む」程度でいいと思います。

#####次に、「はじめようKintoneAPI」を行います。
本日は第６回まで進めましたが、上記の「はじめようJavaScript」と異なり、Kintoneで簡単なアプリを作ってからカスタマイズを行うため内容が頭に入りやすいです。その上内容も重複している箇所があり、復習を兼ねてどんどん進めます。
#####なので、「はじめようJavaScript」で時間をかけ過ぎずに、ある程度理解したら「はじめようKintoneAPI」に移ってもいいと思います。

明日はチュートリアルを終えた所感を掲載しようと思います。
画像ポップアップ

#画像ポップアップ実装

####[参考記事](https://allabout.co.jp/gm/gc/470618/)




```index.html
<body>
   <link href="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.7.1/css/light      box.css" rel="stylesheet">
   <script src="https://code.jquery.com/jquery-1.12.4.min.js" type="text/javascr     ipt"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.7.1/js/light.     box.min.js" type="text/javascript"></script>
</body>
```

body内に記述



```index.html
<a href="sakura.jpg" data-lightbox="abc" data-title="桜写真拡大">
   <img src="sakura-thumbnail.jpg" alt="桜写真">
</a>
```


data-title="○○○"　は省略可能。拡大時に表示されるタイトル。
サムネイル画像　src="sakura-thumbnail.jpg"(img要素)
拡大時の画像　　href="sakura.jpg"(a要素)


data-lightbox="abc"　は属性。abc(グループ名)は必須！！ないとうまく表示しなかった。
複数画像がある場合、全て同じ属性名にしておけば、**グルーピング**できる


[![Image from Gyazo](https://i.gyazo.com/c6424405615e1339ff16411c266359f1.gif)](https://gyazo.com/c6424405615e1339ff16411c266359f1)
rails s -d時のサーバー終了方法

新しいGemでslimを導入した際、railsサーバーを立て直したかったが、デタッチモードで起動していたため、サーバー終了方法がわからなかった。

[この記事](bit.ly/3fTxps5)を参考に、

`$ kill -9 $(lsof -i tcp:3000 -t)`
を実行したところ、サーバーを終了することができた。
RubyからCocoaを使ってみる

RubyからCocoa（macOSのAPI）を使ってみる。
以前、RubyCocoaというものがあった。今は動かなくなっているようだ。
近いものとして、cocoaというgem packageがある。
https://github.com/patrickhno/cocoa/

インストールする。
> % gem install cocoa
> Successfully installed cocoa-0.1.6
> Parsing documentation for cocoa-0.1.6
> Done installing documentation for cocoa after 3 seconds
> 1 gem installed

サンプルプログラムを実行してみる。

```test1.rb
require 'cocoa'
Cocoa::NSAutoreleasePool.new
app = Cocoa::NSApplication.sharedApplication
app.setActivationPolicy Cocoa::NSApplicationActivationPolicyRegular
app.activateIgnoringOtherApps true
alert = Cocoa::NSAlert.alloc.init.autorelease
alert.setMessageText "Hello world!"
alert.runModal
```

> % ruby test1.rb
> /usr/local/lib/ruby/gems/2.7.0/gems/cocoa-0.1.6/lib/cocoa/objc/method_def.rb:154: warning: constant ::Fixnum is deprecated
> /usr/local/lib/ruby/gems/2.7.0/gems/cocoa-0.1.6/lib/cocoa/objc/method_def.rb:154: warning: constant ::Fixnum is deprecated
> /usr/local/lib/ruby/gems/2.7.0/gems/cocoa-0.1.6/lib/cocoa/objc/method_def.rb:154: warning: constant ::Bignum is deprecated

無事実行されるのだが、warningが気になるな。今度、修正してみよう。
【⭐️オススメ便利機能⭐️】~インデントを色で識別！？~

【概要】
----------------------------------------



<b>1.オススメ便利機能とは</b>

<b>2.なぜ入れた方がいいの?</b>

<b>3.どのように使うのか⁉︎</b>

<b>4.導入してわかったこと</b>



1.オススメ便利機能とは
----------------------------------------
その名も”<b>indent-rainbow</b>”

今すぐ、入れるべき‼︎




2.なぜ入れた方がいいの？
----------------------------------------
下記の画像を見てください！
インデントが列によって、
レインボーに色別されています！

<img width="90" alt="スクリーンショット 2020-08-12 22.45.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686400/3132e48d-811b-027e-00a6-b0f6f169e765.png">

これにより、どの開閉タグ(ex:divでの表示ミス）
がどこに対応しているのか一発でわかります！

またタブではなくスペースキーで１文字開けた時は、
赤くなり教えてくるのも大変便利です！



3.どのように入れて、使うの⁉︎
----------------------------------------
Vscodeの<img width="44" alt="スクリーンショット 2020-08-12 23.12.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686400/c5197027-f9b9-0ac8-dc5d-5a4f678dae4c.png">
から”indent-rainbow”と検索するだけ！
あとはインストールを押すだけ！

そして緑のインストールボタン押して
視覚化されるので簡単です！



4.導入してわかったこと
----------------------------------------
I)実は列がレインボーになるだけと思っていました笑
　たまたまスペースを押したら赤くなったのでさらに
　便利だなと感じました！

II)divで表示ミスをすることが頻繁にあったので
　列を見易くすることでミスに気付けました！
TCPとUDPについて

プロトコルにはそれぞれにポート番号が割り振られている。

サービスプログラムへ各プロトコルを振り分ける「通信規約」が存在する。
それがTCPとUDPである。

#TCPとは？

- **T**ransmission **C**ontrol **P**rotocolの略で、通信の挙動を指定する。

- **コネクション型**(相手が通信できるかどうかを確認し、相手のOKの返事を受け取ってからデータを送信する)で通信する。

- プロトコルによってはTCPしかないものもある。

- TCPは`「信頼性」`を重視したプロトコルであり、送信するデータを確実に相手に届けたいときに使う。

- TCPを利用したサービス：WWW、電子メールなど

#UDPとは?

- **U**ser **D**atagram **P**rotocolの略で、通信の挙動を指定する。

- **コネクションレス型**(相手が通信できる前提で自分が通信したいタイミングで通信を開始する)で通信する。

- UDPは`「速度」`を重視したプロトコルであり、送信するパケットが小さいときや、データを再送する必要のないときに使う。

- UDPを利用したサービス：IP電話、ストリーミングなど
PHPで動的変数(可変変数)を扱う

#変数を動的に作成する(可変変数)
変数を動的に作成したら楽なのにな…と思うけど案外使っている方が少なかった？ので記録として。
例えばPHPの場合、変数の初期化宣言をしなくても代入を書いてしまえば使えてしまうわけですが、以下のように初期化宣言している場合です。

```test.php
$apple = "";
$peach = "";
$grape = "";
```
上記のような例はよく見られると思います。
場合によってはもっと多くの変数を宣言しないといけない…なんて事もあるかもしれません。
これを動的に作成する方法は以下のようになります。

```test_arr.php
$arr = array(
  "apple",
  "peach",
  "grape"
);

foreach ($arr as $value) {
  ${$value} = "";
}
```

`${}`の中にforeachでloopしたvalueを入れてあげることでtest.phpとやっていることは同じになります。
コード量増えたじゃん！って思うかもですが、稀にtest.phpのように初期化処理を行っているプログラムで10個も20個も初期化処理を頑張って書いているのを見たことがあります。
そんな時にこれを使えば4行くらいで書けてしまいます。
`//各変数の初期化処理`
などとコメントを入れておくと「ここで変数の初期化やってるんだな」くらいに見て貰えると思います。

##### ちょっと追記
後輩にこれだけ見せても理解できません！って言われたのでもう少し詳しく解説。
`$arr`の中には`apple`、`peach`、`grape`。この値が入っていることは見ての通りと思います。
例えばこれを普通に`foreach`でloopしてvalueを`print`で表示すると`apple`、`peach`、`grape`…の順番に表示されますよね？
処理の最初`apple`をデバッグ風に表現するとしたら以下のようになると思います。

```
foreach ($arr as $value) {
  ${apple} = "";
}
```

`$value`の部分に`apple`が入りましたね。
これは普通の`foreach`の動きと一緒になります。
問題は`${apple}`の部分だと思います。
PHPで変数の宣言等は`$`をつけて行います。
では上記の`${apple}`はというと…？

実は`$apple`と同じ意味となります。

では先ほど挙げた構文を今の例を踏まえてさらに砕いていくと

```
foreach ($arr as $value) {
  $apple = "";
}
```

こうなるわけです。
これが、続いて`peach`、`grape`と配列の最後まで続く為、冒頭で挙げた`test.php`と同じ意味となる。と言うわけです。


##動的変数(可変変数)応用編
先ほどまでは$arr配列の中身の変数をそのまま作っていました。
この変数を元に、更に別の変数を作ってみましょう。

```test_arr2.php
$arr = array(
  "apple",
  "peach",
  "grape"
);

foreach ($arr as $value) {
  ${$value} = "";
  ${$value . "_flg"} = true;
}
```

ここでは`.`と`""`でくくった文字列を連結することで配列の中身を元に

```
$apple = "";
$apple_flg = true;
$peach = "";
$peach_flg = true;
$grape = "";
$grape_flg = true;
```

このような変数宣言と同様の事が出来ます。
上記のような例では変数宣言を単純にしているだけですが、配列で使用することで世界が広がるかと思います。

上記は単純に変数を作っているだけですが、実はClassも同様に生成できたり実行できたりします。
ぜひ試してみてください。
IBM Cloudでのユーザ招待、他ユーザへの多要素認証の要求設定

# はじめに

IBM Cloudを用いてチームで開発する際、アカウントを作成したアカウント所有者以外は、アカウント所有者から対象のアカウントに招待してもらうかたちで参加することになります。

アカウントに招待してもらうことで、各ユーザ（またはアクセスグループ）に割り当てられた権限で、アカウント内でサービスを作成したり、利用したりすることができます。

当記事では、自身がアカウント所有者の場合に、他のユーザを自分のアカウントに招待する方法を紹介します。

また、[別記事](https://qiita.com/hisato_imanishi/items/d14f229cc07cf9a26b6d)で、自身のユーザ認証をワンタイムパスワードを使用した多要素認証に変更する手順を紹介しましたが、加えて、アカウントに招待したユーザに多要素認証を要求する設定についても紹介します。

# 自分のアカウントに他のユーザを招待する

IBM Cloudにログイン後、アクセス（IAM）の[ユーザ管理のページ](https://cloud.ibm.com/iam/users)にアクセスします。

「ユーザーの招待」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/ce147a41-f330-83ae-80b9-2755acf6bf37.png)

ユーザーの招待画面で、招待する人のメールアドレスを入力します。対象者はこのメールアドレスでIBMidを作成する必要があります。
また、「ユーザーへの追加のアクセス権限の割り当て」を展開し、招待する人に対して権限を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/edafceae-4afb-1a82-b387-c207c245b868.png)


例えば、IAM対応サービスに対しての権限を設定する場合、「IAMサービス」を選択し、設定対象（サービスの種類、アカウントまたはリソース・グループ、リージョン）を選択し、付与する権限（管理者、エディターなど）を指定し、「追加」ボタンをクリックします。

以下の例では、このアカウントにおいて、全てのサービスに対して、全てのリージョンで、管理用の権限として「エディター」を、サービスアクセス用の権限として「ライター」「リーダー」を付与しています。（「ライター」は「リーダー」の上位の権限なので、何故複数選択できる仕様になっているのかはよく分からないですが）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/e8b3fb31-965b-75b0-02fb-910f37fa645a.png)


このような手順で、「クラシック・インフラストラクチャー」や「アカウント管理」のパネルでも権限を追加していきます。

必要な権限の追加が終わった後、画面右側のアクセス・サマリーで内容を確認し、「招待」ボタンをクリックします。
<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/c9d3b490-3098-87cc-7ec4-638fec6d950a.png">

これで他ユーザの招待が完了です。


# アカウントに招待したユーザに多要素認証を要求する設定

それでは次に、招待したユーザに多要素認証を要求するようにしましょう。

アクセス（IAM）の[設定ページ](https://cloud.ibm.com/iam/settings)にアクセスします。

アカウント・ログインの「編集」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/4cf1088e-a57f-dee8-0211-259679e46155.png)

表示されたダイアログで多要素認証を設定します。「全てのユーザー」、または、「非フェデレーテッド・ユーザーのみ」に設定することが可能です。
<img width="600" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/2b42e933-0b95-c799-5a6f-2647e7722369.png">

フェデレーテッド・ユーザーとは、企業などでIBM Cloudを使用しており、その組織のID認証の仕組みとIBM Cloudでフェデレーションしている場合に、その組織に属するユーザ（対象のドメインのメールアドレスをIBMidとしているユーザ）のことです。フェデレーテッド・ユーザーについては、その組織固有の認証の仕組みを持っているため、そちらを優先したい場合は「非フェデレーテッド・ユーザーのみ」を選択します。

選択後、「更新」ボタンをクリックすることで設定が完了します。

これで、招待したユーザがIBM Cloudにログインする際、多要素認証が求められるようになります。


---
なお、この設定を実施した後、ログアウトし、再度IBM Cloudにログインしようとしたところ、ワンタイムパスワードの入力画面でGoogle Authenticatorで表示されたコードを入力しても認証エラーとなりました。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/3ef78e1f-c143-b240-2336-23fadaf2ba2a.png">


再度オーセンティケーターの設定が必要なのかと思い、上記画面の「オーセンティケーター・アプリケーションをセットアップします」リンクをクリックし、送付されたメールに沿って処理を進めましたが、今度は以下のようなエラーとなりました。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386149/792097f6-b5ff-2c04-832f-664bfda9d76b.png">

既にセットアップ済みのデバイスでワンタイムパスワードを生成しているのですが...。
（このときは、「非フェデレーテッド・ユーザーのみ」にしていたので、招待済みであったフェデレーテッド・ユーザーでログインし、多要素認証の設定を解除して事象を解消できました。）
Debian apt update  GPG error

## 経緯
私はDockerをよく使っていて、公式imageを用いるが、大体はdebianが親になっていることが多い。
そして、メンテナンスされていないimageも多々有り、祖先のdebianイメージのバージョンがどんどん古くなってしまっている。危ない。

そんな古い公式imageを利用することになった。

## 問題
古いdebianイメージ(私の場合はjessie)で`apt update`をするといかのようなエラーが出た

```console
$ apt update
...
W: GPG error: http://security.debian.org jessie/updates InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY XXXXXXXXXX
```

- debian(なのかaptなのか)は、セキュリティのためパッケージが本物であることを検証するためにGPGという仕組みを利用しているらしい。
- 古いdebianのaptは、その鍵の有効期限が切れていることがあるらしく、今回のようなエラーが出るらしい。
- GPGというのは公開鍵暗号方式を用いた署名の仕組みらしい。
- SSLなどと違い第三者機関としての認証局は無く、俺自身が認証局となることだ…という感じらしい。
- 自分が認証するので、自分の鍵で他人の鍵に署名したりしてもらったりするらしい。
- 署名していいケースというのは、物理的に対象の人物と出会い、十分に身分を証明してもらったときのみらしい。
- 対処法をググると腐るほど出てくるが、エラーの鍵をinstallしてしまえばいいという手順がかいてある。しかし私にはそんなことをして良いか(安全か)全然わからん。

~~だいたい私は今何度「らしい」といったのか。私はただ単にaptでパッケージをインストールしたいだけだというのに。何なんじゃもう。ブラックボックスで使わせてくれよもう~~

理解度が足りて無く、それをやっていいという納得が得られないので、GPGについて深く理解するしかなさそうだ。

・・・と思っていたところ

```
$ apt-get update 
$ apt-get install debian-keyring debian-archive-keyring 
$ apt-get update
```

で治ったではないか。
これが何なのか。正直わからん。

https://packages.debian.org/ja/jessie/debian-keyring

> Debian プロジェクトは、偽造を防ぐために開発者が自分のパッケージであることの 表明に GnuPG による電子署名を行うことを要求しています。 本パッケージには、GnuPG のキーリングと Debian 開発者 (アップロード権を持つ者と持たない者) や Debian メンテナの GnuPG 鍵が含まれています。

らしい。

~~だが、これがセキュリティ的にだめじゃないことだけはわかる。
よくわかっていない私は特に何も認証操作をしていないからだ。~~

```console
WARNING: The following packages cannot be authenticated!
  debian-archive-keyring debian-keyring
```

って出てたのでもうダメだ。
もうだめなのだが、もうこれでいいと思うことにした。(後述)


---

Dockerでの話

```Dockerfile:Dockerfile
FROM xxxx # メンテナンスを放棄された、祖先に鍵の有効期限が切れた可愛そうなdebianを持つimage

RUN apt-get update \
&& apt-get install -y --force-yes debian-keyring debian-archive-keyring \
&& apt-get update \
&& apt-get install -y \
* \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
```

という感じになる。
`--force-yes`で`WARNING: The following packages cannot be authenticated!`を無視する。

なんだか自己改造しているロボットみたいだ。

今回私は仕方なくメンテナンスを放棄されたimageを使ったが、普通は潔く最新のimage使ったいい。公式imageに無いなら自分で作ったほうがいい。

こういうことがないようにDockerhubにimageを公開する開発者の方々に置かれましては、Dockerhubのbuild settingsで「祖先のimageが更新されたら自動で更新する」ようにしておいてほしい。

---

追記

https://wiki.debian.org/SecureApt#Other_problems

に公式マニュアルっぽいものを発見した。
ここに書いてある対処法はdebian-archive-keyringパッケージの更新だ。

しかし、```apt-get install debian-archive-keyring```を実行すると```The following packages cannot be authenticated!```と出る。

そもそもdebian-archive-keyringパッケージというのはaptの署名鍵を管理するプログラムだ。
とはいえ、こいつもaptパッケージだ。つまりこいつ自身の署名鍵が期限切れしてたらどうしようもないのだ。

普通に使うときは、期限切れの前に余裕を持って更新された鍵が配布されるなり、こいつだけ時期をずらして更新されたりするのだろう。（と推測する)

本末転倒だ。ブートストラップ問題というやつだ。もうダメだ。


このことについてのQ&Aが見つけられて

https://serverfault.com/a/337283

言ってることは、やっぱりこれはブートストラップ問題なので、

- ちゃんとしたいなら頑張って鍵信用できる方法でinstallしなさい
- ちゃんとしなくていいなら```apt-get install debian-archive-keyring```を行って警告は無視しなさい

ということだ。
そろそろ私も疲れてきたのでもうちゃんとしたくはない。
このへんで記事は締めくくろうと思う。

ただ、Docker使っているのだから最新のイメージの中の秘密鍵をexportしてくれば、ちゃんとできる気がしますな。
FacesMessageを設定したのに表示されないときの対応方法

# 事象 : FacesMessageをコンテンツに設定したのにメッセージが表示されない
- 環境
    - CentOS Linux release 7.8.2003 (Core)
    - Eclipse IDE for Enterprise Java Developers.Version: 2020-03 (4.15.0)
    - openjdk version "11.0.7" 2020-04-14 LTS
    - JSF 2.3.9


```xml:ajaxでメソッドを実行して
  <h:form id="formId">
    <div id="uploadArea">
<!--...省略...-->
          <f:ajax event="change" execute="uploadArea" render="uploadArea" listener="#{uploadBean.uploadFile}" />
<!--...省略...-->
      <div>
        <h:message for="uploadArea" errorClass="error" warnClass="warn" infoClass="info" />
      </div>
    </div>
  </h:form>
```

```java:メソッドでメッセージをコンテンツに設定したのに表示されない
    public void uploadFile(AjaxBehaviorEvent event) throws IOException {
        if (!isUpload()) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "", "ファイルが選択されなかったよ。");
            event.getFacesContext().addMessage("uploadArea", message);
//...省略...
```

```html:出力されたHTML
<form id="formId" name="formId" method="post" action="/tryJsf/base.jsf" enctype="application/x-www-form-urlencoded">
  <input type="hidden" name="formId" value="formId">
  <div id="uploadArea">
<!--...省略...-->
    <input id="formId:file" type="text" name="formId:file" style="display:none;" onchange="mojarra.ab(this,event,'change','uploadArea','uploadArea')">
    <div>
    </div>
  </div>
  <input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="-7689768516583343150:2206148480801750608" autocomplete="off">
</form>
```

## 原因 : 不明(誰か教えてください。)
どうも`f:ajax`のメソッドが実行された後に再表示されていないもよう。
`render="uploadArea"`が・・・無視られた？HTMLのタグはダメ？JSFのタグじゃなきゃダメ？
JSFのタグで書かないものはコンポーネントではない？

>  The clientIds of components that will participate in the "render" portion of the Request Processing Lifecycle.
> [ajax(JSF 2.2 View Declaration Language: Facelets Variant)](https://docs.oracle.com/javaee/7/javaserver-faces-2-2/vdldocs-facelets/f/ajax.html)

### 対応方法 : divタグをh:panelGroupに変える

```xml:ajaxでメソッドを実行して
  <h:form id="formId">
    <h:panelGroup id="uploadArea">
<!--...省略...JSFのタグにしたので指定するid属性にする..-->
          <f:ajax event="change" execute="formId:uploadArea" render="formId:uploadArea" listener="#{uploadBean.uploadFile}" />
<!--...省略...-->
      <div>
        <h:message for="formId:uploadArea" errorClass="error" warnClass="warn" infoClass="info" />
      </div>
    </div>
  </h:form>
```

```java:メソッドでメッセージをコンテンツに設定したら表示された
    public void uploadFile(AjaxBehaviorEvent event) throws IOException {
//...省略...対応前と同じ...指定するid属性だけ変える...
            event.getFacesContext().addMessage("formId:uploadArea", message);
//...省略...対応前と同じ...
```
VS CodeのスニペットでReactのコンポーネント雛形を作る

コンポーネントの雛形をVS Codeのスニペットに登録しておくと捗ります♪

# スニペットの設定手順

1. VS Codeの `Code > Preferences > User Snippets`
2. tsxファイルのスニペットを作る場合`typescriptreact`と入力
VS Codeではスニペットをファイル種別ごとにjsonファイルで管理します。
![スクリーンショット 2020-08-12 23.14.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29775/dd2003b8-44fb-bcde-c2fc-847ea67f01bb.png)


3. 以下をコピペ
以下はReact Nativeのコンポーネントの一例です。お好みで変更して下さい。  

```json
{
	"React Native Component": {
		"prefix": "react-native-component",
		"body": [
			"import React from \"react\";",
			"import { View, StyleSheet } from \"react-native\";",
			"",
			"type Props = {};",
			"",
			"export const ${TM_FILENAME_BASE}: React.FC<Props> = ({}) => {",
			"\treturn (",
			"\t\t<View style={styles.container}>",
			"\t\t\t<View />",
			"\t\t</View>",
			"\t)",
			"};",
			"",
			"const styles = StyleSheet.create({",
			"\tcontainer: {}",
			"});"
		],
		"description": "React Native component"
	}
}
```

# スニペットの利用
エディタで`react-native-component`と打ち込んでTabキー。

スニペットが挿入されます！
コンポーネント名はファイル名が自動的に反映されます。

![9ab7fc4ed4df7c0297cd34d53750df23.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29775/3ee31b58-4100-6b45-8b31-795b5e3ee51a.gif)
google search console の sitemap の api client は searchconsole ではなく webmasters にある

# 概要
google search console のサイトマップに対する API のクライアントを探していたときに sdk の searchconsole ディレクトリを見て、サイトマップの操作に対するメソッドがないなあと少しはまったので共有です。

# 結論
ruby sdk の例ですが、
`searchconsole_v1` ではなく、
https://github.com/googleapis/google-api-ruby-client/blob/master/generated/google/apis/searchconsole_v1/service.rb

`webmasters` にサイトマップの API はあります。
https://github.com/googleapis/google-api-ruby-client/blob/master/generated/google/apis/webmasters_v3/service.rb
機械学習の可視化ツールTensorboardを使ってみた

# はじめに
Tensorboardを初めて使いグラフを書きその便利さに感動したので、共有します。
Deep LearningのフレームワークはPyTorchを使用しました。

# インストール
Anacondaを使っているので以下のコマンドでTensorboardをインストールします。

```
conda install tensorboard
```

# コーディング

```Python:tb.py
import numpy as np
from torch.utils.tensorboard import SummaryWriter#グラフを書くSummaryWriterをimport

np.random.seed(1000)

x = np.random.randn(1000)

writer = SummaryWriter(log_dir="./logs")#インスタンス生成　保存するディレクトリも指定

for i in range(1000):
    writer.add_scalar("x", x[i], i)#値を書き込む
    writer.add_scalar("sin", np.sin(i), i)

writer.close()#閉じる
```

ファイル名を***tensorboard.py***にするとmoduleと被りImportErrorになるので注意しましょう。

# 解説
簡単にいうと、上のコードでは、ランダムな値を持つ配列とsin関数をプロットしています。

## SummaryWriterをimport
`from torch.utils.tensorboard import SummaryWriter` 
Tensorboardでグラフの描画に必要なmoduleであるSummaryWriterをimportします。

## インスタンス生成
`writer = SummaryWriter(log_dir="./logs")` 
これはカレントディレクトリにlogsディレクトリを作成し、そのlogsの中にTensorboard用のファイルが保存されます。

## 値を代入
`writer.add_scalar("x", x[i], i)`で配列の値を入れます。
`writer.add_scalar(tags, scalar_value, global_step)`となっており、tagsでグラフの名前を指定して、scalar_valueで保存する値を代入、global_stepでグラフの横軸の間隔を指定します。

## 閉じる
`writer.close()`で最後に閉じましょう。

# グラフをみる
## tb.pyの実行
上記のコードを実行しましょう。グラフが描画されます。

```
python tb.py
```

## グラフをみる
以下のコマンドを実行しましょう。`--logdir=""`で保存したディレクトリを指定しましょう。
今回は`./logs`です。

```
tensorboard --logdir="./logs"
```
そうすると、以下の文がターミナルに出力されます。

```
TensorBoard 2.2.1 at http://localhost:8000/ (Press CTRL+C to quit)
```

ローカルサーバーが立ち上がるので、ブラウザに`http://localhost:8000/`と打ちましょう。

<img width="1438" alt="スクリーンショット 2020-08-12 22.48.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590810/955326a0-54a4-b2d1-8857-2493958b0359.png">

chromeでみると、グラフが綺麗にプロットしていることがわかります。

# ssh先のグラフをみる
Deep Learningのコードは計算量が多くローカルPC(手元のPC)では莫大な時間がかかるので、
研究室にあるサーバーのGPUにsshしてサーバー上でコードを回すことがデフォルトです。
では、そういう場合はリモートサーバーで描画したグラフをローカルPCでどうやってみるのでしょうか?

## リモートサーバーにsshする
sshをする時に、-Lオプションを用いてクライアント(ローカルPC)のlocalhost:9000をリモートサーバーのユーザ名@サーバーのIPアドレス:8000に繋げます。

```shell:@ローカルPC
ssh ユーザ名@サーバーのIPアドレス -L 9000:localhost:8000
```

## リモートサーバーでtb.pyの実行
sshしたリモートサーバーでグラフを描画するコードを実行しましょう。

```shell:@リモートサーバー
python tb.py
```

## Tensorboardの実行
sshしたリモートサーバーでグラフをみるためのコマンドを実行しましょう。
sshした際にローカルPCに繋いだポートは8000なので、--portオプションで8000を指定して実行しましょう。

```shell:@リモートサーバー
tensorboard --logdir="./logs" --port 8000
```

以下のような文が出力されます。

```shell:@リモートサーバー
TensorBoard 2.2.1 at http://localhost:8000/ (Press CTRL+C to quit)
```

## グラフをみる

さっきは`http://localhost:8000/`をブラウザに入力したら、グラフがみれましたが今回は見れません。

今回はリモートサーバーのポート8000とローカルPCのポート9000を繋げたので、
ローカルPCのブラウザで`http://localhost:9000/`と入力すれば、さっきと同じグラフが見れます。

<img width="1438" alt="スクリーンショット 2020-08-12 22.48.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590810/955326a0-54a4-b2d1-8857-2493958b0359.png">

# まとめ
PyTorchでTensorboardを用いてグラフを描画しました。
また、ssh先のリモートサーバーでまわしたコードのグラフをローカルPCでみる方法を紹介しました。
私もこのTensorboardとssh -Lを利用してDeep Learningに活用していきたいと思います。
ionicを初めて使う時の環境構築

##想定環境

* npmがインストールされていること

```
$npm --version
6.14.7
```

* nodeがインストールされていること

```
$node --version 
v14.8.0               
```
##環境構築

1.Ionic CLIをインストール

```
$npm install -g @ionic/cli
```
*以前にインストールしたことがあり、エラーになってしまう場合は下記コマンド

```
$npm uninstall -g ionic
$npm install -g @ionic/cli
```
2.プロジェクトを作成したいディレクトリに移動してサンプルプロジェクト作成
("myApp"という名前でサンプルプロジェクトが作成されます)

```
$ionic start myApp
```
3.プロジェクト作成にあたりいくつかの質問があるので答える

* Angulerで作成するのか、Reactで作成するのかはここで選択します

```
Framework?
>Angular
>React
```

* どのようなテンプレートにするのかはここで選択します

```
? Starter template
>blank
>tabs
>sidemenu
```
*テンプレートイメージは下記です([ionic公式](https://ionicframework.com/jp/docs/intro/cli))
<img width="639" alt="スクリーンショット 2020-08-12 23.12.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594379/14198603-b669-dec5-aee1-0bc4db50b79f.png">

4.サンプルプロジェクトに移動

```
$cd myApp
```
5.サンプルプロジェクトを立ち上げる

```
$ionic serve
```
このような画面が立ち上がると成功です(tabsを選択したので下にtabsがあります)
<img width="1432" alt="スクリーンショット 2020-08-12 23.15.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594379/b827608b-8484-9115-080d-15242b15faff.png">
ExcelVBAユーザーフォームに標準モジュールから値を渡し、結果を受け取る(グローバル変数なし)

#概要
　「ブックのオープンイベントやボタンのクリックイベントでユーザーフォームを開いて処理を開始して，標準モジュールを呼ぶ」
　それが基本的な処理であることは間違いありません。しかし，どうしても処理の途中でユーザーに選択してもらわないと後処理の都合上うまくいかないときがあります。
　標準モジュールからユーザーフォームの部品の値の設定をするのは簡単ですが，ユーザーの選択結果を標準モジュールで受け取るところでつまづいたのでまとめます。
#ユーザーフォームの値を設定する
　これは簡単で，標準モジュール内で
・ユーザーフォーム名.コントロール名.プロパティ
・ユーザーフォーム名.コントロール名.メソッド
とすれば，普通にユーザーフォームの各部品にアクセスできます。

```vb:ユーザーフォームに値を設定
Sub input_userform1()
    UserForm1.Label1.Caption = "標準モジュールから値を設定しました"
    UserForm1.ComboBox1.Text = "任意の作家名"
        Dim i As Integer
        i = 1
        Do While Cells(i, 1) <> ""
            UserForm1.ComboBox1.AddItem Cells(i, 1)
            i = i + 1
        Loop
    UserForm1.Show
    Unload UserForm1
End Sub
```
<img width="900" alt="2020-08-12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/36fbd868-391b-a76c-9d2e-26794f3b0706.png">
値が設定されています。

#ユーザーフォームの結果を受け取る
　まず，ユーザーフォームをどうやって閉じるか，という問題があります。
　今回の場合，「OK」ボタンで閉じることとします。
　まずはやりがちなうまくいかない例から。


```vb:うまくいかない例：ユーザーフォーム
Private Sub CommandButton1_Click()
    Unload UserForm1
End Sub
```
```vb:うまくいかない例：標準モジュール
    UserForm1.Show
    Dim result As String
    result = UserForm1.ComboBox1.Text
    MsgBox result
```

<img width="900" alt="2020-08-12 (1).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/2886ee8c-a026-4718-f587-d3901396bec8.png">
ユーザーフォームで選択しても，結果が取得できません。

　うまく動きません。それもそのはず，値を取得する前，ユーザーフォームを閉じた段階でUnloadしているのですから，部品の値も取得できなくなってしまうのです。
　かといって，ユーザーフォームが開かれている間は次の処理にいかないので，ユーザーフォームを開いている間に値を変数に入れたりはできません。

　ではどうするかというと，ユーザーフォームをいったん隠してしまえばよいのです。

```vb:ユーザーフォーム
Private Sub CommandButton1_Click()
    UserForm1.Hide
End Sub
```
　ユーザーフォーム側では，Unloadではなくhideを使ってユーザーフォームを隠し，次の処理に進みます。

```vb:標準モジュール
    UserForm1.Show
    Dim result As String
    result = UserForm1.ComboBox1.Text
    Unload UserForm1
    MsgBox result
```
　標準モジュール側で必要な値を変数に入れるなどしてから，ユーザーフォームをUnloadします。
<img width="900" alt="2020-08-12 (2).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622636/8b4f0cce-ced9-6f55-f4b2-884277763603.png">
　結果を標準モジュールのメッセージボックスで受け取ることができました。

　標準モジュールの処理の最中にユーザーフォームを呼べるようになると，ユーザーフォームの活用の幅が更に広がりますよね。
roslaunch時にエラー（Could not load controller 'joint1_velocity_controller' because controller type 'velocity_controllers/JointVelocityController' does not exist.）


roslaunch jetbot_gazebo main.launch時にエラー

```
$ roslaunch jetbot_gazebo main.launch
...
[ERROR] [1597240741.631704313, 0.290000000]: Could not load controller 'joint1_velocity_controller' because controller type 'velocity_controllers/JointVelocityController' does not exist.
[ERROR] [1597240741.631739984, 0.290000000]: Use 'rosservice call controller_manager/list_controller_types' to get the available types
[ERROR] [1597240741.786883, 0.311000]: Failed to load joint1_velocity_controller
[ERROR] [1597240741.790108038, 0.311000000]: Could not load controller 'joint2_velocity_controller' because controller type 'velocity_controllers/JointVelocityController' does not exist.
[ERROR] [1597240741.790142061, 0.311000000]: Use 'rosservice call controller_manager/list_controller_types' to get the available types
[ERROR] [1597240742.632978, 0.425000]: Failed to load joint1_velocity_controller
[ERROR] [1597240742.636252224, 0.426000000]: Could not load controller 'joint2_velocity_controller' because controller type 'velocity_controllers/JointVelocityController' does not exist.
[ERROR] [1597240742.636293428, 0.426000000]: Use 'rosservice call controller_manager/list_controller_types' to get the available types
[ERROR] [1597240742.791305, 0.446000]: Failed to load joint2_velocity_controller
[ERROR] [1597240743.637433, 0.557000]: Failed to load joint2_velocity_controller
```

以下で解決

```
sudo apt-get install ros-melodic-ros-control ros-melodic-ros-controllers ros-melodic-joint-state-controller ros-melodic-effort-controllers ros-melodic-position-controllers
```

# 参考
[https://github.com/kimbring2/DeepSoccer](https://github.com/kimbring2/DeepSoccer)
DockerでImageMagickを使える環境を整備する

#DockerでImageMagickを使える環境を整備する
## DockerでUbuntuの環境整備
### imageのpull
```bash

$ sudo docker pull ubuntu
```
```bash

Using default tag: latest
latest: Pulling from library/ubuntu
Digest: sha256:5d1d5407f353843ecf8b16524bc5565aa332e9e6a1297c73a92d3e754b8a636d
Status: Image is up to date for ubuntu:latest
docker.io/library/ubuntu:latest
```
### imageの確認
```bash
$ sudo docker images
```
```bash
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
ubuntu                            latest              1e4467b07108        2 weeks ago         73.9MB
```
### コンテナの起動
```
sudo docker run -it ubuntu
```
オプションの-itについてはこの方の記事が参考になりました。
[docker run -it の「-it」とはなにか](https://qiita.com/k_uchida_____/items/8ca31226bd6d10850791)
とりあえず-itをつけておけばbashのような端末が使えます。
## ubuntuの仮想環境内でImageMagickのインストール

```shell

# apt update
```
とりあえずupdateしないとインストールできないので。終わったら

```bash
# apt-get -y install imagemagick
```
結構時間がかかりますが気長に待ちましょう。途中住んでる地域を聞かれるので適当に答えましょう。

終わったら

```bash

# which convert
/usr/bin/convert
```
Imagemagickがインストールできていることが確認できました。

## イメージの保存
`ctrl p ctrl q` でコンテナを起動したままコンテナから一旦抜ける。
起動中のコンテナを確認

```bash

$ sudo docker ps -n=-1
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS              PORTS                    NAMES
0ab73f0f184a        ubuntu               "/bin/bash"         20 minutes ago      Up 20 minutes                                hungry_joliot
```
`0ab73f0f184a`というIDのコンテナから新しいimageを`ubuntu/imagemagick`という名前で作って保存する

```bash
$ sudo docker commit 0ab73f0f184a ubuntu/imagemagick
```
imageができたか確認

```bash
$ sudo docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
ubuntu/imagemagick                latest              fdc18d136f6f        8 seconds ago       247MB
```
できていることが確認できた。
imageのcommitについては以下の記事を参考にさせていただきました。
[Dockerでcommitしてみる](https://qiita.com/mats16/items/712575dc50513dfdf0a2)

### 再度起動中のコンテナに入ってコンテナを終了する

起動中のコンテナの確認

```bash

$ sudo docker ps -n=-1
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS              PORTS                    NAMES
0ab73f0f184a        ubuntu               "/bin/bash"         27 minutes ago      Up 27 minutes                                hungry_joliot
```
起動中のコンテナを停止する。psコマンドで出てきたcontainerIDの最初5文字くらいをstopの後に入れる。

```bash

$ sudo docker stop 0ab73f
```

停止しているか確認

```bash
$ sudo docker ps -n=-1
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS              PORTS                    NAMES
```
ちゃんと停止していることが確認できた。
LaravelでMockeryを使う際の注意点

めちゃくちゃ便利な`Mockery`。テストを書く方なら多分結構使ったことがあるかなと思います。
今回はMockeryを使う際の注意点を紹介します。

# Mockeryはprotectedなメソッドには使えない
意外な落とし穴としてはこれが上げられるかなと思います。

`Mockery`は`protected`なメソッドには使えないのです。
ただ、どうしても`protected`でメソッド宣言したい、でもテストするときに必要だしな ~ みたいなパターンあると思います。

めちゃくちゃ親切なことにそれ専用のメソッドが用意されています。

# shouldAllowMockingProtectedMethodsを使おう
`protected`専用のメソッドです。
こいつを使ってあげれば一発で解消します。[(公式)](https://readouble.com/mockery/1.0/ja/protected_methods.html)

```PHP
$service = \Mockery::mock('Class')->shouldAllowMockingProtectedMethods();
```

上記の様に呼び出してあげればokです :v_tone1:
【Angular】プロジェクトへBootstrapの適用方法【忘備録】

### Angular プロジェクト作成
```
> ng new angular-bootstrap
```

### Angular プロジェクトへ移動
```
> cd angular-bootstrap
```

### Angular プロジェクトへBootstrapのインストール
```
> npm install --save bootstrap
> npm install --save @ng-bootstrap/ng-bootstrap
> ng add @angular/localize
```

### 設定ファイルの書き換え
```angular.json
"styles": [
  "src/styles.css",
  "./node_modules/bootstrap/dist/css/bootstrap.min.css"
],
```
### app.module.tsへの追記
```app.module.ts
...
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
@NgModule({
  ...
  imports: [
    BrowserModule,
    AppRoutingModule,
    NgbModule,
  ],
  ...
})
export class AppModule { }
```
### app.component.htmlの書き換え
```app.component.html
<div class="form1">
  <div class="form-group">
    <input 
      type="text" 
      class="form-control"/>
  </div>
  <button 
    class="btn btn-primary">OK</button>
</div>
```

おしまい！
アジャイルスクラム開発を行う前に知っておくべき事②

# はじめに
本記事は「アジャイルスクラム開発を行う前に知っておくべき事①」の続きです。
前はアジャイル開発の内容中心に記載しましたので、ここからは**スクラム開発**を中心にお話しをしたいと思います。

# スクラム開発とは？
スクラム開発とは、簡単に言えば**チーム一丸となってプロジェクトを進めていく**開発手法です。
ラグビーでスクラムを組んで相手にぶつかっていくのと同じようなイメージです。

スクラム開発では、役割別に以下のように呼びます。

* プロダクトオーナー(PO)  
→開発プロダクトのオーナー。顧客。
* スクラムマスター(SM)  
→スクラムチーム全体のコーチ
* 開発メンバー  
→プロダクトオーナーとスクラムマスターを除いた、チームメンバー全員

スクラム開発で重要なのは、**POもチームの一員である**という事と、**全員がフラットな関係性である**という所です。
なのでスクラム開発以外でよくある、顧客→PM→PL→開発メンバーみたいな上下関係はありません。
(実際はアリアリの場合が多いですが。。。)

# スクラム開発でのタスクの作り方
スクラム開発では、ユーザーストーリー単位でタスクを作成するのは前項でお話ししましたが、
もう少し具体的にお話ししようと思います。

スクラム開発では、タスクを以下のように分割します。

* Epic  
→一番大きな括り。大きな目標をEpicとして定義する。
* Future  
→Epicをもう少し分割した単位。正直ここらへんの分け方はプロジェクトによると思われる。
* Product Backlog Item  
→実際の作業単位。もう少し細かく言うと、POが確認を行えるタスク単位。(画面の機能等)
* Sprint Backlog Item  
→開発者が作業を行う単位。開発、設計、テスト等もこの部分で分割される。

# プロダクトオーナー(PO)の役割
POの役割は、プロダクトの機能や要件などを纏めて**プロダクトバックログ**を作成し、
何を優先して進めていくのか等の全体的な調整を行う事です。

POがエンドユーザでない場合は、エンドユーザとの要件調整なども役割の一部となってきます。

# スクラムマスター(SM)の役割
一言で言うと、**プロダクトを進めていく上でチームの障害を取り除く事**が役割となります。
基本的には開発等には参加せず、スクラムについてのコーチングや、雑用までなんでもやります。

私が参加しているチームの実例では、

* HDMIケーブルが欲しいんだけど。
* 〇〇さんとの打ち合わせ調整お願い。
* こういう場合に、スクラム的にはどういう考え方をすべきなのか

等々、**チームに起こるプロダクトを遂行するにあたって障害となりえる問題**を解決するのも仕事の一部となっています。

上記の事から、スクラムマスターはチーム内で誰よりもスクラムを熟知している必要があると言われています。
(プロダクトオーナーよりも熟知している必要がある)

# 終わりに
いかがでしたでしょうか。

今回の記事は、特にアジャイルスクラム開発をやったことがなく、イメージが湧きにくい方向けの説明でした。
正直まだまだ書くべき事はたくさんあるのですが、全てを説明していると恐らく１０ページ以上になってしまうので。。。

私が今回のスクラムアジャイル開発で感じたのは、やはりどちらの開発も一長一短があり、
「どっちの開発手法が優れている！」ではなく、プロジェクトの状況に応じて「今回はこの開発手法で行こう！」「基本はウォーターフォールだが、アジャイルスクラムのここは良いので取り入れよう」といった臨機応変に対応することが大切だと思いました。

最初は新しい事で抵抗があるかもしれませんが、
より良い開発ライフを楽しむためにも、一度は経験してみると良いと思います。
UFTをダークテーマにする方法

# はじめに
UFTの標準設定では明るい白いテーマが適用されています。

エンジニアの方は目を労わるために様々なツールをダークテーマにしているかと思います。
Visual Studio Codeは初期からダークテーマで提供されているらしいですね。

今回は、UFTでのダークテーマの設定方法について解説します。

# 対応バージョン
 
|前提条件|
|---|
|UFT One(15.01)|
ダークテーマは<font color="RED">UFT One(15.01)</font color>から対応しています。
それ以前のVer.では対応していないので、ご注意ください

# 設定方法
1.UFTを起動する
2.メニューバーにある[ツール] > [オプション]を押下
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288745/5d8a6a16-bd3a-2c4e-abe2-b60e52eb4278.png" width=50%>
3.[一般]タブを選択し、起動オプションを押下
4.[外観]からダークテーマを選択する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288745/9a1bdf12-79d0-255a-0057-77ef300317ea.png" width=50%>
5.再起動を促すダイアログが表示するので、[今すぐ再起動]を押下する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288745/a05ba8c4-1dff-ccbe-c051-babd4ae29d34.png" width=50%>
6.これで通常テーマからダークテーマに変更できました。
**[上：ダークテーマ・下：通常]**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288745/7f994fcd-f539-68dc-d88b-02d48d0ec94d.png" width=50%>



# おわりに
私はQTPからこの自動化ツールを使っていて、このダークテーマの登場は悲願でした。
このダークテーマが追加されたというお知らせを見たときはニヤニヤしたものです。

この感動を皆様にも共有したく記事にした面もあります。

今後もUFTとは長い付き合いにはなると思うので、これからの進化も楽しみです
Convert.FromBase64Stringがエラーになる

# 状況
サーバ側で作成したJWTをGETパラメータとしてくっつけたURLをメール送信。
そのメールのURL叩いて取得したGETパラメータのJWTから[.]で分割した真ん中(Claims)の文字列をBase64デコードするとエラー。

```C#
string jwt = "jwt文字列"
Encoding enc = Encoding.GetEncoding("UTF-8");
var splits = jwt.Split('.');
return enc.GetString(Convert.FromBase64String(splits[1]));　// FromBase64Stringでエラー
```

# エラー内容
どうやら指定されている文字列が不正だと言われている。

    Error in base64DecodeThe input is not a valid Base-64 string as it contains a non-base 64 character, 
    more than two padding characters, or an illegal character among the padding characters.


ただ、生成されたJWTを見ても禁止文字は入っていないし、
そのまま文字列コピーでいろんなサイトでBase64デコードしてみたけどエラーでない。。。

#原因
FromBase64Stringでは、4の倍数の文字数しか受け付けないらしい。。。(内部でやってくれよ。。。)
なので、文字数が4の倍数になるようにPaddingしてやったら上手くいきました。

```C#
string jwt = "jwt文字列"

Encoding enc = Encoding.GetEncoding("UTF-8");

var splits = jwt.Split('.');
for(int i = 0;i < (splits[1].Length % 4);i++) splits[1] += "=";

return enc.GetString(Convert.FromBase64String(splits[1]));
```