OmniAICreator/Qiita-1.07M huggingface dataset:
Swagger UIから一覧データを取得する【備忘録】

# はじめに
こちらは備忘録になります。
Swagger UIから一覧を取得するための、簡単なスクリプトを作成しました。

<img width="1142" alt="スクリーンショット 2019-06-03 22.15.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226008/df31cd3d-c905-351d-56ea-b81c8b3396dd.png">

# スクリプト
```javascript
const section = document.querySelectorAll(".opblock-tag-section");
for(let i=0;i<section.length;i++){
  if(section[i].getElementsByTagName("h4")[0].textContent == "default"){
    continue;
  }
  const apiSummary = section[i].querySelectorAll(".opblock-summary");
  
  for(let j=0;j<apiSummary.length;j++){
    let text = "";
    text += section[i].getElementsByTagName("h4")[0].textContent;
    text += "," + apiSummary[j].querySelector(".opblock-summary-method").textContent;
    text += "," + apiSummary[j].querySelector(".opblock-summary-path").textContent;
    text += "," + apiSummary[j].querySelector(".opblock-summary-description").textContent;
    console.log(text);
  }
}
```
kintoneアプリから使えるカスタム帳票アプリを作ってみた

# はじめに

皆さん、Low-code platform (ロー・コード・プラットフォーム) って使ってますか？
海外勢では、[Salesforce](https://www.salesforce.com/jp/)、[Zoho](https://www.zoho.com/jp/creator/)、[Mendix](https://www.mendix.com/)等が有名ですが、日本発で奮闘しているのがサイボウズの[kintone](https://kintone.cybozu.co.jp/)です。

どのプラットフォームもコーディング無し、または、ほんの少しのコーディングで、つまりGUIからの設定のみで、非常に迅速に業務アプリの構築を可能としています。
多くのプラットフォームでは、これで承認ワークフローやレポート・ダッシュボードによる分析、メッセージングツールまで統合されているのですから、簡単に作れるからと言って侮れません。

もちろん、ノー・コードではなくロー・コードですので、必要に応じて（必要でなくても）ゴリゴリコードを書いて開発することもできます。
一般的にスクリプト実行の仕組みと外部からコール可能なWeb APIが用意されていますので、独自ロジック・画面の実現、機能拡張や外部連携が可能です。
大抵の場合、機能拡張やAppのマーケットプレイスも提供されています。

# モチベーション
今回、私はkintone用の帳票アプリを作成しました。
https://github.com/shellyln/menneu-reporting-app-for-kintone

海外事情は分かりませんが、本邦においては各Low-code platformに於いて（も）、帳票アプリ・帳票機能拡張が大人気となっております。
今どきのご時世、レポート・ダッシュボードとCSV出力があれば、余程の場合を除いて紙なんて必要無い筈なのですが、私のこれまで携わった仕事でもプラットフォームの種類に関わらず、漏れなく大人気でした。
Salesforceでもkintoneでも、標準の「印刷」機能はあるのですが、どうやらお気に召して頂けないようです。
各プラットフォーム定番の[これ](http://ncd-service.com/smarepo)とか[これ](https://cstap.com/product/print.html)等を使うことも多いのですが、デザインやセクションヘッダ・フッタの作成に制約があり、苦労することもあります。

Salesforceでは、最悪、Visualforceでhtml帳票という、よく舗装された逃げ道がありますが、kintoneで同様のことをするためには、各画面のクライアント側コードでhtmlを生成して別タブ等で開く必要があります。
これは、ReactやVueでSSRと同様にhtmlを作り、最終的にBlob URLを作れば実現できるのですが、毎度各画面で行うには負担が大きいです。

# ソリューション
https://github.com/shellyln/menneu-reporting-app-for-kintone
では、帳票定義を作成・編集・プレビューする[アプリ](https://github.com/shellyln/menneu-reporting-app-for-kintone#-reportingapp-%E5%B8%B3%E7%A5%A8%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88-app)(帳票テンプレート App)と、
各アプリの一覧または詳細画面に帳票ボタンを追加するための[スクリプトファイル](https://github.com/shellyln/menneu-reporting-app-for-kintone#-app-that-uses-the-reportingapp)を用意しました。

* 帳票アプリでの編集 - テキストエリアは[Ace editor](https://ace.c9.io/)になってます
<img alt="reportingapp-editview.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185253/2c28fecb-c116-7097-b73c-47089ea69925.png" width="50%">

* 各アプリでの帳票ボタン表示
<img alt="app-example-1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185253/d4bea78f-971e-561c-6aff-9b291471c8ee.png" width="50%">

帳票アプリでは、markdown、または、JSXの代替記法として作成した[LSX](https://github.com/shellyln/liyad#what-is-lsx)(lispだよ！)を使用して帳票を定義できます。プレビュー機能もあるので、編集しながらレイアウトを確認できます。
LSXでのデザインでは、[Paper CSS](https://github.com/cognitom/paper-css)がコンポーネントとして[使用できる](https://github.com/shellyln/menneu-reporting-app-for-kintone#report_template-lisp-lsx-scripting)ので、格好良いプレビュー付きhtml帳票が作成できます。

# 主な機能
* MarkdownまたはLSXによる帳票定義
* 帳票デザイン時のプレビュー
  * プレビューデータを対象アプリから取得することもできます
* QRコード、バーコード表示 (詳細は[こちら](https://shellyln.github.io/menneu/playground.html) → Demo (Markdown))
* UMLダイアグラム(Plant UML)表示 (詳細は[こちら](https://shellyln.github.io/menneu/playground.html) → Demo (Markdown))
* グラフ(Chart.js)表示 (詳細は[こちら](https://shellyln.github.io/menneu/playground.html) → Table and chart (Markdown))

# インストール・セットアップ
上記のアプリのGitHubリポジトリにある手順に従ってください。
アプリテンプレートのzipは用意しておりません。御免なさい。

# さいごに
書かなくてよいコードは書かずに、楽しいコーディング、したいですね
小説の単語をword cloudでみる

自然言語処理の学習途中でWordCloudで遊んでみた。
マスクを指定すればおしゃれなグラフィックが作れるし、形態素解析後の可視化ツールとしても便利
文章は羅生門。
羅生門のtxtファイル自体は青空文庫さんから


```
from janome.tokenizer import Tokenizer
import zipfile
import os.path, urllib.request as request
from wordcloud import WordCloud
import matplotlib.pyplot as plt
%matplotlib inline


file = withopen('rashomon.txt', 'r') as f:
    bindata = f.read()
textdata = bindata.decode('shift_jis')


t=Tokenizer()
tokens=t.tokenize(textdata)
```

word解析する。フォントを指定いないと文字化けするのでfpathとしてダウンロードしたNotoSanをpathとして指定。

```

words = ""
for token in tokens:
    if token.part_of_speech.split(',')[0] in ['名詞', '動詞', '副詞']:
        words = words + " " + token.base_form
        

fpath="NotoSansCJKjp-hinted/NotoSansCJKjp-Black.otf"
wordcloud = WordCloud(background_color="white",width=800,height=500,font_path=fpath).generate(words)


plt.figure(figsize=(30,24))
plt.imshow(wordcloud)
plt.axis("off")
plt.show()

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245823/ecb91b80-87fc-4b3d-3b41-be264f96ce04.png)


動詞のいる、するが大きく出てしまっているが登場人物の老婆と下人がやはり大きい。
内閣府のデータから国民の祝日を取得し、Listに格納する

#やりたいこと
何かと祝日のリストはあると便利（だと思います）。
Google APIを使用しようかと思いましたが、アカウントが必要なので内閣府の祝日リストを使うことにしました。

ここの祝日をListにする
https://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html

具体的にはこのcsvを読み取って必要なものだけListに入れる
https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv

鬼のような適当さを見せつけます。
これでとりあえず2020年の12月くらいまで取得できました

```c#:main.cs
using System;
using System.Collections.Generic;
using System.Web.Mvc;

namespace CleanDuty.Controllers
{
    public class DefaultController : Controller
    {
        // GET: Default
        public ActionResult Index()
        {
            List<DateTime> holiday = Utility.JapanHoliday.getHoliday();
            return View();
        }
    }

```

main.csはメソッドを呼び出しているだけ

```c#:getHoliday.cs
using System;
using System.IO;
using System.Net;
using System.Collections.Generic;

namespace Utility
{
    class JapanHoliday
    {
        public static List<DateTime> getHoliday()
        {

            string[] JapanHolidayfromCAO = new string[1] { "https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv" };

            try
            {
                WebClient wc = new WebClient();
                Stream st = wc.OpenRead(JapanHolidayfromCAO[0]);
                StreamReader sr = new StreamReader(st, System.Text.Encoding.GetEncoding("shift-jis"));
                List<DateTime> holiday = new List<DateTime>();
                int s = 0;
                DateTime today = DateTime.Today;
                while (!sr.EndOfStream)
                {
                    string line = sr.ReadLine();
                    if (s == 0) { s++; continue; }
                    string[] ch = new string[2];
                    ch = line.Split(',');

                    DateTime date = DateTime.Parse(ch[0]);

                    if (today.Year > date.Year)
                    {
                        s++; continue;
                    }
                    holiday.Add(date);
                    s++;
                }

                sr.Close();
                st.Close();

                return holiday;

            }
            catch (Exception e)
            {
                // URLのファイルが見つからない等のエラーが発生
                Console.WriteLine("エラーが発生しました\r\n\r\n" + e.ToString());
                List<DateTime> holiday = new List<DateTime>();
                return holiday;
            }

        }
    }
}

```

ヘッダーがあるので、ヘッダーはcontinueでスキップしています。
199○年とからあるので、今年の以前のものは排除します。

#参考文献
コンソールにいろいろ出すやつ
http://www.katch.ne.jp/~h-inoue/tips/cs/0001.html

streamreaderをListに入れる
http://koshinran.hateblo.jp/entry/2017/
05/31/210543

Webclientは古いらしいので、Httpclientを使うとのこと
https://qiita.com/volpe28v/items/b86e0bc9db8e42688cc3
pryをインストールしたらReadlineでうまく起動できなかった話


RubyのデバックようにPryをインストールして詰まったのでメモ

## tr；ld

pryをインストールするときに起動できなくて詰まったのだけど
原因としてはReadlineの問題だった。
brewで更新をかければ解消する。

## pryのインストール方法

pryはbrewではなくgemでインストールします。
ドキュメントの生成もしたかったのであわせてpry-docもインストール

```
$ gem install pry pry-doc
```

これでインストール自体はできたのだけど実行しようとしたら以下の問題が出てきた

```
$ pry
Sorry, you can't use Pry without Readline or a compatible library.
Possible solutions:
 * Rebuild Ruby with Readline support using `--with-readline`
 * Use the rb-readline gem, which is a pure-Ruby port of Readline
 * Use the pry-coolline gem, a pure-ruby alternative to Readline
 ＠中略＠
 /Users/pcuser/.rbenv/versions/2.6.0/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require': dlopen(/Users/pcuser/.rbenv/versions/2.6.0/lib/ruby/2.6.0/x86_64-darwin18/readline.bundle, 9): Library not loaded: /usr/local/opt/readline/lib/libreadline.7.dylib (LoadError)
  Referenced from: /Users/pcuser/.rbenv/versions/2.6.0/lib/ruby/2.6.0/x86_64-darwin18/readline.bundle
  Reason: image not found - /Users/pcuser/.rbenv/versions/2.6.0/lib/ruby/2.6.0/x86_64-darwin18/readline.bundle
```

最初はrbenvにコマンドのシンボリックリンクがないせいかなと思ってrehashをかけてみた。

参考リンク：[rbenv rehashは何をやっているのか？](http://dqn.sakusakutto.jp/2014/02/rbenv_rehash_what_it_does.html)

とりあえずrehash

```
$　rbenv rehash
```

ただ後でエラーコードを見たらここに気がついた

```

Possible solutions:
 * Rebuild Ruby with Readline support using `--with-readline`
 * Use the rb-readline gem, which is a pure-Ruby port of Readline
 * Use the pry-coolline gem, a pure-ruby alternative to Readline
```

怒られているのはReadlineの問題なのね

ということでReadlineの解消方法をググってみた。

結果これを試してみる

[Macでawkを実行するとエラー: "dyld: Library not loaded: /usr/local/opt/readline/lib/libreadline.7.dylib" となる問題の解決法](https://qiita.com/nwtgck/items/f5427c0d0f7827658bd5)

```‌
$ brew switch readline 7.0.5
Cleaning /usr/local/Cellar/readline/8.0.0_1
Cleaning /usr/local/Cellar/readline/6.3.8
Cleaning /usr/local/Cellar/readline/7.0.5
Cleaning /usr/local/Cellar/readline/7.0.3_1
Opt link created for /usr/local/Cellar/readline/7.0.5
$ pry
[1] pry(main)> 
```

うん、これで動いた。

今日はとりあえず問題を解決したことをメモしておくことで終了
CSS一日目

最近忙しさが増して、なかなか勉強できていなかった。。。
勉強を続けよう。

#CSSとは？
- CSS: Cascading style sheets
- 文字の色やサイズ、レイアウトを指定できる。
- HTMLで書かれた構造化された文章のスタイルを指定するための言語

##役割分担
- HTMLは文書構造。
- CSSは見た目。
- 普及前はHTMLのtableタグを駆使してレイアウトを整理していた。

##CSSのルール
セレクター(どこの){プロパティー(何を):値(どうする);
}

```
h1{
  color:#F0000;
}
```
h1要素の色を赤色にする


## CSS適用方法
##インラインで記述

```
  <body>
		<h1 style="color:#FF0000">はじめてのCSS</h1>
  </body>
```

##内部参照
これで`<p></p>`が青くなる。
headタグの中に入れるのがポイント

```
  <head>
		<!-- 内部参照 -->
		<style>
			p {
				color : #0000FF;
			}
		</style>
  </head>
  <body>
		<p>内部参照</p>
  </body>
</html>

```

##外部参照
このHTMLのスタイルシートはこれやで、って指定

```
<link rel=stylesheet"" href="stylesheets/first.css">

```

#CSSのメリット
複数のページでスタイルの使い回しができること。

##優先順位
インライン　＞　内部参照　＞　外部参照


#色の指定
三種類あるよ
##RGB
赤、緑、青の3つの色を混ぜて、色を表現

`#FF(red)00(green)00(blue)`

##色で直接
red, green, blueみたいな。

##ボーダー
これで、特定の要素に枠線をつけられる。その中の背景色も変えられる。

```
h2 {
	background-color : #2587BD;

	/* border-style: solid;
	border-color: #E2B483;
	border-width: 5px; */
  border: #E2B483 10px solid;

	color: #FFF;
}

```

#セレクター
##セレクターの種類
- エレメント(要素)セレクター
- IDセレクター
<p id="hello"></p>

`# hello{
}`

idはページ内でユニークである必要がる。
複数の要素に同じidはつけられない。

- クラスセレクター
<p class="hello">こんにちは</p>

`.hello{
}`
VGG16の結果をGrad-CAMで検証

# はじめに

この記事は「[Jetson NanoでVGG16を試す](https://qiita.com/yamamo-to/items/d66845a1cd561bebaf86)」でボトルが障子と判定された理由を探るものである。

# VGG16への入力画像の検証

最初の画像はJetson Nanoに接続されたカメラで撮像した640x360の画像である。
これに対してVGG16用の入力画像とするために`chainer.links.model.vision.vgg.prepare`を使って変換を行った。ソースコード[^1]を見ると次のような変換が行われている。

[^1]: https://github.com/chainer/chainer/blob/v6.0.0/chainer/links/model/vision/vgg.py#L440

1. 型チェック
2. (RGB型であっても)RGB型に変換
3. リサイズ(デフォルトでは224x224)
4. RGBをBGRの順序に変更
5. 各channelから次のオフセットを引く(103.939, 116.779, 123.68)[^2]
6. (height, width, channels)の順序を(channels, height, width)に変更

[^2]: imagenetの完全なデータセットの各channelの平均値

こうして変換されたものをmatplotlibを使ってグレースケールで表示すると次のようになる。

![boss_vgg16_input.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252224/2a1fc8be-41c4-1616-b0b4-52d08b50bfbc.png)

左からBlue, Green, Redのchannelになっている。
これを見る限り、少しほっそりとしたがまだ「ボトル」であることは分かる。

# Grad-CAMによる検証

https://github.com/tsurumeso/chainer-grad-cam

からChainer用のGrad-CAMをダウンロードして次のように実行。

```
pipenv run python3 run.py --input boss.jpg
```

何のトラブルもなくgcam.png, gbp.png, ggcam.png, が出来上がった。

# 結果

上から順にGrad-CAM, Guided Backpropagation, Guided Grad-CAM。

![gcam.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252224/a49b0019-695d-9a9c-87ee-dc9c05ac785e.png)
![gbp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252224/56f08c06-4426-f0e1-1a90-46d5c9037e91.png)
![ggcam.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252224/d82513f7-cf9e-df29-691b-1b20b1c76dc0.png)

おぉーい、ボトル消えてる・・・。

ヒートマップを見る限り、VGG16で「障子」と判定されたのは「ボトルを見てない結果」だと判明。
全画素数あたりの見たい対象物画素を増やさないとダメかな。
npm packageのバージョン一覧を確認したい

* npmのとあるpackageにどんなバージョンがあるのかを確認したかった際に調べたことの履歴として書き残しておきます
  * 誰かの何かのお役に立てれば。。。

### packageのバージョン一覧を確認する方法

```bash
$ npm info npm versions
```

* とりあえず、ググって出てきた方法を採用
* 確認したかったpackageだと`xxx more items`となってしまい全ての結果が見れない :sob:

### packageのバージョン一覧を全て表示する方法

* 以下のサイトを参考に`--json`オプションを付ければ良いことが分かった
  * [npm info foobar versions で表示される内容を全て表示する方法](https://obel.hatenablog.jp/entry/20180211/1518321838)

```bash
$ npm info npm versions --json
```

### ところで、公式ドキュメントに`info`が見つからない :sob: :sob:

* https://docs.npmjs.com/cli-documentation/cli

### 紆余曲折あって、ヘルプを見てみた

```bash
$ npm info --help
npm view [<@scope>/]<pkg>[@<version>] [<field>[.subfield]...]

aliases: v, info, show
```

#### なるほど :bulb: 

* 以下のドキュメントに`versions`や`--json`の記載を見つけることができました :v:
  * [npm-view  ~View registry info~](https://docs.npmjs.com/cli/view.html)


* ソースは以下の辺になるんですかね？
  * [./lib/config/cmd-list.js](https://github.com/npm/cli/blob/36682d4482cddee0acc55e8d75b3bee6e78fff37/lib/config/cmd-list.js)
C++で文字列から特定の文字を削除する方法

文字列strから文字cを削除する場合は、

```cpp
str.erase(remove(str.begin(),str.end(),c),str.end());
```

たとえば文字列strがXYZで削除する文字がXの場合、removeでYZZとなります。
削除された文字の部分に残された文字列が詰められ、空いた部分には以前の文字が残ります。
そしてremoveは以前の文字が残っている文字列の先頭要素を指すポインタを返すので
eraseを利用して詰めた後に残ってしまった文字列を削除します。
eraseとremoveを組合せないといけないのでちょいとめんどいです。。。
choreonoid v1.7.0のdockerイメージを作ってみた

Choreonid v1.7.0リリースされた。作者によるとこのリリースがこれまでの開発の区切りになるということで、いいタイミングではないかと思い、dockerイメージ作ってみた。

# dockerhubリポジトリ
https://hub.docker.com/r/hsnuhayato/choreonoid1.7

```bash

$ docker pull hsnuhayato/choreonoid1.7
```
でpullすれば良い。
Dockerfileもgithubに上げた。基本はchoreonoidリポジトリのchoreonoid/misc/docker/Dockerfile-ubuntu-xenial-gccと同じだが、

* ROSとの連携を想定して、ros:kineticをベースに作った。
* OpenRTMのversionを1.1.2にダウングレードした。OpenRTM1.2.0の一部APIが更新されたが、choreonoidはまだ追いついてないようで
https://discourse.choreonoid.org/t/openrtm-aist-1-2-0/273/3
そのため、

 + add-apt-repository http://openrtm.org/pub/Linux/ubuntu/
レポジトリではなく、 
 + add-apt-repository ppa:hrg/daily 
レポジトリに変更した。

前者でapt installすると1.2.0がインストールされるが、後者はまだ1.1.2のまま。

* hrpsysのrosパッケージも入れた。RTCを扱うときによくhrpsys_config.pyとrtm.pyの世話になるので。

# テスト
以下のスクリプトを実行し、dockerの環境を起動

```bash
#!/bin/bash

xhost +si:localuser:root
docker run  -it --name choreonoid_sandbox --rm   \
       -v $(pwd):/mnt --workdir=/mnt \
       --net host \
       --privileged     \
       --env="DISPLAY"  \
       --env="QT_X11_NO_MITSHM=1" \
       --env="LANG=ja_JP.UTF-8" \
       hsnuhayato/choreonoid1.7　/bin/bash
```
ホスト環境にomniNamesが起動していなければ、
docker環境に入って

```bash
# /opt/ros/kinetic/bin/rtm-naming
```
でネームサーバー起動する。ホスト環境にomniNamesすでに起動しているなら不要。

次にdocker環境で

```bash
# usr/local/bin/choreonoid
```
でchoreonoidを起動（表示がおかしい場合にchoreonoidウィンドウ画面の最大化ボタンを押すと大体治る）。
次にchoreonoidのUIから、File -> open object -> /usr/local/share/choreonoid-1.7/project/OpenRTM-SR1Walk.cnoidを選んでプロジェクト読み込む。
最後に緑色の"Start simulation from the beginning"ボタンを押してロボットが歩き出す。RTMでロボット動かすのを確認した。
![choroeidsample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159774/5b9c8207-eb53-444c-696a-95b1a96e0970.png)

これでchoreonoid上の開発環境の構築が完了！あとはdocker起動時にvolumeでホストのディスクマウントしてバリバリ開発すれば良い！

# おまけ
gtestをコンパイルする環境も入れた。

# TODO GUI日本語化
現状だと起動するとGUIが英語になってるね...
apt-get update && apt-get install -y locales && locale-gen ja_JP.UTF-8 && echo "export LANG=ja_JP.UTF-8"
にしても日本語にならない...どなた様うまく日本語化できたら教えてください。:confused:


次回を待て！！
Burp Suiteでのセキュリティテスト[導入編]

　昔々、新卒で入った会社の先輩がお薦めしてくれたWebアプリケーションのセキュリティ試験ツールであるBurp Suiteについての紹介です。
Webアプリケーションのセキュリティチェックの方法等を書いていきます。

このツールは、スマホ端末のアプリやWebブラウザなどのクライアントからローカルプロキシを通して、サーバー側のアプリケーションへどのような通信がされているのかを傍受し一目で通信内容を確認することができます。
通信内容を可視化するだけでなく、傍受した通信データを任意の値に変更し挙動を確認することもできます。
実際に完成したシステムに対し攻撃を行い脆弱性を確認するテスト、いわゆる"ペネトレーションテスト"を行う際にも有用なツールです。

＊外部サイトに、改変したデータを送ったり第三者の通信の盗聴は法に触れるので行っては行けません。

提供元のPortSWIGGER は３つのエディションを用意しています。
Enterprise　年間$3,999  脆弱性検査・定期スキャン・大規模スキャン・構成管理
Professional 年間$3,999 脆弱性検査・より強力な解析ツールもろもろ
Community タダ！　　　　　最低限の解析機能はもっています。

まずは、無料のものをダウンロードしていきます。
https://portswigger.net/burp

<img width="521" alt="burp1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426556/2ef1b098-6478-b95d-d4fc-2263bc347cbe.png">
ダウンロードしてきたBurpをクリックします。
<img width="234" alt="burp8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426556/7c317f33-e063-bb68-b9b0-49634eeb93a6.png">

ライセンス事項に同意
<img width="421" alt="burp5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426556/e6c46247-0812-7b65-9c99-37588589b5ae.png">

Community無料版は、一時プロジェクトしか作れないのでそのままNext
<img width="631" alt="burp6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426556/da76c150-8cd9-d0a0-94a2-2d94e2308a41.png">

インストールが完了しBurpが起動しました。
<img width="700" alt="burp7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426556/b6b3561f-a3d6-3641-cb80-99f00c7341d4.png">


今回書いていく記事で使いそうな項目タブの説明
[Target] = そのままターゲットです。検査対象をスコープ、範囲を指定したりもできます。
[Proxy]　＝プロキシの設定ができます。プロキシを追加したり、データの値の確認等ができます。
[Spider]　＝　検査したい内容をあらかじめ設定することにより、自動的に捜査対象を抽出してくれます。

*次の記事でリクエストのキャプチャと改ざんの方法について書いていこうと思います。
JP1を使うにあたっての基礎知識

## はじめに

「JP1 を使って夜間バッチを組んで。」と言われたときに、ざっと調べた内容です。
本家のドキュメントを読む前のとっかかりになれば嬉しいです。

## タスクスケジューラじゃなくて JP1 の方がよいかもしれない点

### ジョブの実行条件を細かく設定できる

* 先行ジョブが正常終了して初めて後続ジョブを実行する。
* 複数のジョブを並列実行して、全てのジョブが正常終了して初めて後続ジョブを実行する。
* 特定のフォルダにファイルが作成されたらジョブを実行する。　など。

### 複数のPCにまたがってジョブフローを組める

* ジョブ１（Win１号機）→ ジョブ２（UNIX機） → ジョブ３（Win２号機）

## JP1 の製品群

### JP1/AJS3-Manager

* JP1の実行管理プログラム。Agent 機能も有する。

### JP1/AJS3-Agent

* 実際にジョブを実行するプログラム。UNIX でも動作可能。
* Manager が 各PC にインストールされた Agent をリモート管理することで、複数PC内のジョブを一元管理できる。

### JP1/Base

* Manager、Agent を動かすためのコアプログラム。

### JP1/AJS3-View

* Manager の設定をする GUI ベースの管理ツール。


## JP1 のユニット（処理要素）

### ジョブ（管理ツールの「P」や「U」のようなアイコン）

* 1つずつの実行アクション。
* EXE や バッチをキックする起動単位で作成する。

### ジョブネット（管理ツールで「∴」のようなアイコン）

* ジョブの実行フローをひとまとめにしたもの。
* 階層構造（ジョブネットの中にジョブネット）を作れる。
* ジョブネットに対してスケジュール（実行する日時、繰り返しのサイクルなど）を指定する。
* １つのまとまった実行単位や実行のタイミング単位で作成する。

### ジョブグループ（管理ツールでフォルダのアイコン）

* ジョブネットをまとめたもの。
* 階層構造（ジョブグループの中にジョブグループ）を作れる。
* 環境単位に作成する。

## JP1 のジョブフロー（ユニット定義）

### JP1のユニット定義の例

[□]：ジョブグループ
[∴]：ジョブネット
[p]：ジョブ

```
[□]ROOT
 ├[□]本番環境
 │ ├[∴]日中バッチ
 │ │ ├ [p]日中ジョブ１
 │ │ ├ [p]日中ジョブ２
 │ │   ：
 │ └[∴]夜間バッチ
 │   ├ [∴]日次バッチ
 │ 　│ ├ [p]夜間日次ジョブ１
 │ 　│ ├ [p]夜間日次ジョブ２
 │ 　│   ：
 │   └ [∴]月次バッチ
 │ 　  ├ [p]夜間月次ジョブ１
 │ 　  ├ [p]夜間月次ジョブ２
 │ 　    ：
 ├[□]検証環境
 │ ├：
```


### JP1ユニット定義のポイント

#### ジョブグループ配下のジョブネットは、それぞれ独立した設定による実行になる。

上記の例だと、日中バッチと夜間バッチの間に関連性を持てません。
日中バッチは日中バッチの設定に基づき、夜間バッチは夜間バッチの設定に基づいて実行されます。

#### ジョブネット配下のジョブネットは、それぞれに関連性を持たせられる

上記の例だと、日次バッチの正常終了後に月次バッチを実行させることができます。
また、ジョブネットごとにスケジュールを設定できるので、

* 夜間バッチ：毎日00:00に実行。
* 日次バッチ：毎日実行。
* 月次バッチ：毎月1日のみ実行。

のように設定すると、毎日00:00から夜間バッチが実行し、最初に日次バッチ内のジョブを実行し、結果が正常終了で1日の場合のみ、更に月次バッチ内のジョブを実行するというような設定ができます。

## おわりに

JP1のもっとスマートな組み方があれば、コメント頂けるとありがたいです。
また、記事のレイアウトのセンスが壊滅的にないみたいです。誰が見やすくしていただけるとハッピーです。（前の記事を編集してもらったレイアウトを真似たつもりなんですけどね。。。）
「純粋関数型JavaScriptのつくりかた」に触発されて

「純粋関数型JavaScriptのつくりかた」の記事に
> あなたの好きな言語を浄化して
純粋関数型プログラミング言語にすることができます。

とありました。
やってみました。

```C#:C#
using System;
class Pure{

  public static
  Func<object,Func<object>>
  pure=a=>()=>a;

  public static
  Func<Func<object>,
  Func<Func<object,Func<object>>,
  Func<object>>>
  bind=m=>f=>()=>f(m())();

  public static
  Func<Func<object>,object>
  exec=m=>m();

  public static
  Func<Func<object,object>,
  Func<object,Func<object>>>
  wrap=f=>a=>()=>f(a);
}

class MainClass{
  static void Main(){

    Func<object,Func<object>>
    put=Pure.wrap(a=>
    {Console.WriteLine(
    ((string)a).ToUpper());
    return a;});

    Func<object,Func<object>>
    get=Pure.wrap(x=>
    Console.ReadLine());

    Func<object>
    main=Pure.bind(get(null))(put);
   
    Pure.exec(main);
  }
}
```

```Java:Java
import java.io.*;
import java.util.function.*;

class Pure{

  public static
  Function<Object,Supplier<Object>>
  pure=a->()->a;

  public static
  Function<Supplier<Object>,
  Function<Function<Object,
  Supplier<Object>>,
  Supplier<Object>>>
  bind=m->f->
  ()->f.apply(m.get()).get();

  public static
  Function<Supplier<Object>,Object>
  exec=m->m.get();

  public static
  Function<Function<Object,Object>,
  Function<Object,
  Supplier<Object>>>
  wrap=f->a->()->f.apply(a);
}

class Main{
  
  static BufferedReader in=new
  BufferedReader(new
  InputStreamReader(System.in));

  static Object _get(){
    Object s=null;
    try{
      s=in.readLine();
    }catch(Exception e){
      e.printStackTrace();
    }
    return s;
  }

  public static void 
  main(String[]args){
    
    Function<Object,
    Supplier<Object>>
    put=Pure.wrap.apply(a->
    {System.out.println(
    ((String)a).toUpperCase());
    return a;});

    Function<Object,
    Supplier<Object>>
    get=Pure.wrap.apply(x->_get());
     
    Supplier<Object>
    main=Pure.bind.apply(
    get.apply(null)).apply(put);
   
    Pure.exec.apply(main);
  }
}
```

```Python3:Python3
#pure=a=>()=>a;
pure=lambda a:lambda:a

#bind=m=>f=>()=>f(m())();
bind=lambda m:lambda f:lambda:f(m())()

#exec=m=>m();
exec=lambda m:m()

#wrap=f=>a=>()=>f(a);
wrap=lambda f:lambda a:lambda:f(a)

put=wrap(lambda a:print(a.upper()))

get=wrap(lambda x:input())

main=bind(get(""))(put)

exec(main)
```
GIMPでグラデーション付きの着色をする．

# 結果
左図にグラデーション付きの着色を行い，右図のようにする．

![242ldfsf2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422520/6c24c62f-3c5d-b5fb-2471-f9c9da2e4152.png)

# 方法
1. `Tools > Colorize` の `Saturation`を0にして脱色する．
2. `Layer > Duplicate Layer`[^1]でレイヤーを複製．複製されたレイヤーを選択する．
3. 着色したい部分を選択し，`Tools > Paint Tools > Gradient`[^2]で好みのグラデーションをかける．
4. レイヤーウィンドウの`Opacity`を調整し，不透明度を下げる．
5. レイヤーを統合するなり画像としてエクスポートしたりする．

[^1]: レイヤーウィンドウからレイヤーを複製．
[^2]: ツールボックスから選択する方が早い．
プログラミング学習記録91〜復活〜

##今日やったこと
- Progate Pythonリセット復習

Pythonはかなり久しぶりでしたが、ドットインストールでJavaScriptをゴリゴリやっていたおかげで、すんなり思い出せました。

変数や関数、ライブラリ、クラスなどいろいろ出てきますが、基本的にはJavaScriptと同じです。

Progateでは、そこまで複雑なものはないです。

最初はクラスやインスタンスがよくわかりませんでしたが、JavaScriptでの演習を繰り返すうちになんとなく理解できるようになりました。

この辺は使っていくうちに慣れていくと思うので、最初はコードをひとまとめにするためのものという認識でいいと思います。

３ヶ月以上プログラミングを勉強してきて、ようやくこの感覚に達しました。

アプリを作るのも楽しくなくはなかったのですが、次は機械学習を学んでいこうと思います。

Progateとドットインストールの有料会員は一旦解約します。

今後はPyQでマイペースにPythonを学び、いろいろ作っていきます。

おわり
CoreTweetを使ってTweetアプリを作ろうとしたときの備忘録

C#でTwitterアプリを作る場合、
CoreTweetというライブラリを利用するのが便利そうです。

ただ、このインストール方法がよくわからなかったのでメモとして残します。

githubのリポジトリからファイルをダウンロードします。
https://github.com/CoreTweet/CoreTweet
Gitがわからん、って人は、Clone or Downloadという緑のボタンから
DownloadZipでダウンロードできます

CoreTweet-All.slnってのがあるのでVisualStudioで開きます

そのままビルド…すると、「RestApis.cs が見つかりませんでした」というエラーが出ます
ソリューションの中にRestApisGenというものがあるので、
右クリック→「スタートアッププロジェクトに設定」をして実行します。
これで、RestApis.csのファイルが生成されます

あとはすべてをビルドすれば、CoreTweet.dllができるので、
これを自分のプロジェクトにコピーして、
右クリックメニューから「追加→参照」を選んで追加すればOKです
旧 MacBook Early 2008 (MB402*/A, MB403*/A, MB404*/A) に Ubuntu MATE 18.04 64 bit をインストールする

旧 MacBook の名機、MB403, MB404 に Ubuntu MATE 18.04 64 bit をインストールするというお話です。この機種をメモリ 1 GB で使ってるというのはかなり少ないと思われるので、64 bit でいっちゃいましょう。SSD に換装して使うと結構いい感じで動くかと思います。

### 0. 条件
0.1 セットアップ ディスクを DVD-R に焼いておく。
0.2 メモリは 2 GB 以上。
0.3 有線 LAN につないでおく。

### 1. セットアップ ディスクの起動
なんと、一番最初に苦難に陥ることになります。何もしないで起動すると、死んだかと思うくらいひたすら起動が遅くなります。これを回避しながら起動します。もちろん、何もしなくてもいつかは立ち上がりますが、回避策の実行時間よりもひたすら待つ時間のほうが長いでしょう。

1.1 電源を入れたら速攻で DVD を入れて、[option] を押し続けます。

1.2 ブート セレクタが表示されたら、3 つの光学ディスクのうち真ん中の "EFI Boot" を選んで起動します。
![IMG_0311.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371960/ee322296-82d9-95ad-e453-cbed366544ec.jpeg)

1.3 この機種が New world ROM の機種で EFI 機種ではないために起動に失敗することを利用して、GRUB メニューを表示させます。メニューが表示されたら Try Ubuntu MATE without installing を選んで [e] を押します。

1.4 linux の行の splash の後ろに video=SVIDEO-1:d を追加します。
![Untitled-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371960/4b05d4e8-8499-ec09-5f13-7eebe359efd8.png)

```
linux /casper/vmlinuz file=/cdrom/preseed/ubuntu-mate.seed boot=casper quiet splash video=SVIDEO-1:d ---
```

1.5 [F10] を押して起動を継続します。

### 2. セットアップ

2.1 セットアップは特に問題なく普通に実行できます。プロプライエタリな Wi-fi うんたらダウンロードしてインストールしても、結局は Wi-fi モジュールを後から入れ替えるはめになります。

2.2 ディスクはまっさらにして、Ubuntu だけで使うのがいいかと。OS X 10.7 Lion + Waterfox もいよいよ時代が終わりそうな感じです。Waterfox の次のバージョンは 10.9 以上が必要になるっぽいので、Lion でもいよいよ Web ブラウザがなくて使い物にならない時代に突入していくことでしょう。

2.3 セットアップ後の再起動時は要注意。再び起動が遅い問題がやってきます。

### 3. セットアップ後の初回再起動

3.1 再起動して白い画面が黒くなったら [ESC] を何回か押します。

3.2 起動が中断して GRUB コンソールになるので、GRUB メニューを表示させます。

```
grub> normal
```

3.3 メニューが表示されたら Ubuntu で [e] を押します。なぜか、メニューが表示されずに起動が走ってしまうことがあるようです。起動が走ってしまったら、あきらめて立ち上がるのを待ちましょう。インストール後の場合はおよそ 5 分ぐらいで表示が出ます。

3.4 linux の行で splash の後ろに video=SVIDEO-1:d を追加します。
![Untitled 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371960/f5378008-2b4f-4988-68cb-2a9c027c3009.png)

3.5 [F10] を押して起動を継続します。

3.6 無事に起動したら、ターミナルを立ち上げ、GRUB オプションをを変更します。

3.6.1 オプションを書き換えます。GRUB_CMDLINE_LINUX_DEFAULT に、video=SVIDEO-1:d を追加します。

```
sudo nano /etc/default/grub
```

3.6.2 書き換え内容を反映します。

```
sudo update-grub
```

3.7 再起動します。

### 4. Wi-fi モジュールの入れ替え

SSID とか表示されて、見た目 Wi-fi が使えるように見える場合に入れ替えを行います。Wi-fi が使えない場合はインストールします(4.2)。

4.1 bcmwl-kernel-source を削除して再起動します。

```
sudo apt remove --purge bcmwl-kernel-source
sudo reboot
```

4.2 firmware-b43-installer をインストールします。

```
sudo apt install firmware-b43-installer
sudo reboot
```

### 5. アップデートをやって仕上げます。

```
sudo apt update
sudo apt upgrade
sudo apt autoremove
sudo snap refresh
sudo reboot
```

### 6. 最後に
思ったよりも面倒でしたね。個人的にはメモリ 4 GB と SSD は必須だと感じますね。やはり Firefox の重さに影響しますね。メモリ 6 GB (2 + 4 GB) で動きましたが、DDR2 667 の 4 GB は値段が高くて、この機種のためには買う気にはならないでしょう。
Leetcode #198: House Robber

```swift
func rob(_ nums: [Int]) -> Int {
    if nums.isEmpty {
        return 0
    }
    var dp = Array(repeating: 0, count: nums.count+1)
    dp[1] = nums[0]
    for i in stride(from: 1, to: nums.count, by: 1) {
        dp[i+1] = max(dp[i-1] + nums[i], dp[i])
    }
    return dp[nums.count]
}
```
Leetcode #199: Binary Tree Right Side View

```swift
func rightSideView(_ root: TreeNode?) -> [Int] {
    if root == nil {
        return []
    }
    var stack = [root!]
    var answer = [Int]()
    while !stack.isEmpty {
        answer.append(stack.last!.val)
        var tmp = [TreeNode]()
        while !stack.isEmpty {
            let node = stack.removeFirst()
            if let leftNode = node.left {
                tmp.append(leftNode)
            }
            if let rightNode = node.right {
                tmp.append(rightNode)
            }
        }
        stack = tmp
    }
    return answer
}
```
Flutter で ListView

(2020/03/10) 追記: 再修正
(2020/02/10) 追記: ときどきみていただいているようなので修正

codelabs の [Write Your First Flutter App, part 2](https://codelabs.developers.google.com/codelabs/first-flutter-app-pt2/#4) での使われ方だと、自動で補充されるので挙動がちょっとわかりにくい。

いざ自分で書く際に、`ListView.builder` で作って入れるだけだと、サイズが計算できずにエラーになったりする。

[Flutter開発する前に知っておきたい35のWidget一覧](https://qiita.com/coka__01/items/dedb569f6357f1b503fd#listview--listtile)

個数が既知で固定の場合、`Column` のように `ListView(children: list)` で作っても良いですが、基本的には動的になると思うので、`ListView.builder` や `ListView.separated` で構築します。

## Expanded などでつつんであげる

レイアウト計算用に入れ物がいる場合、`Expanded` に入れたり、なんらかの形で高さを自動計算できるようにしておかないと駄目なことがある。

[Expanded class](https://api.flutter.dev/flutter/widgets/Expanded-class.html)

```dart
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('Hoge')),
        body: Column(children: [
          new Expanded(
            child: buildListView()
          ),
```

もちろん、明示的に高さを指定しても良いです。

```dart
Container(
  height: 200.0,
  child: ListView.separated(
    itemCount: list.length,
    itemBuilder: (BuildContext context, int index) { // 以下略
```

## アイテム数が既知なら ListView() / ListView.separated

一番シンプルなのは、Widget[] を並べるもの

```dart
ListView(children:list);
```

区切りを挟みたい場合は、ListView.separated を使います。
itemBuilder, separatorBuilder でアイテムと区切りを生成します。

https://api.flutter.dev/flutter/widgets/ListView/ListView.separated.html


```dart
ListView.separated(
  itemCount: list.length,
  itemBuilder: (BuildContext context, int index) {
    return ListTile(
      title: Text('${list[index]}'),
    );
  },
  separatorBuilder: (BuildContext context, int index) => const Divider(),
);
```

必要に応じて、`itemBuilder` の関数が呼ばれるので、`index` に対応した項目を作ってあげます。
ここでは、シンプルに `ListTile` を使っていますが、色々便利な `Widget` があります。

* [Card](https://api.flutter.dev/flutter/material/Card-class.html) や [SwitchListTile](https://api.flutter.dev/flutter/material/SwitchListTile-class.html)
* [Dismissible](https://api.flutter.dev/flutter/widgets/Dismissible-class.html) でフリック削除対応
* [flutter_slidable](https://pub.dev/packages/flutter_slidable) でフリックでアクションを出す

`separatorBuilder` は標準の `Divider` を使っていますが、独自の区切りにも出来るはず。

## 項目数が不明なら ListView.builder

`itemCount` を指定しないと、サイズが埋まるまで延々と `itemBuilder` を呼ぶような挙動をします。

[Flutter ListView Example | Displaying Dynamic Contents Tutorial ](https://appdividend.com/2019/01/01/flutter-listview-example-displaying-dynamic-contents-tutorial/)


範囲外は null を返します

```dart
  Widget buildListView() {
    return ListView.builder(
      padding: const EdgeInsets.all(16.0),
      itemBuilder: (context, i) {
        if (i.isOdd) return Divider();

        final index = i ~/ 2;
        if (list.length <= index) {
          return null;
        }
        return ListTile(
          title: Text(list[index].toString()),
        );
      });
  }
```
Leetcode 200: Number of Islands

```swift
func numIslands(_ grids: [[Character]]) -> Int {
    if grids.isEmpty || grids[0].isEmpty {
        return 0
    }
    var count = 0
    var grids = grids
    for i in 0..<grids.count {
        for j in 0..<grids[0].count {
            if grids[i][j] == "1" {
                count += 1
                helper(&grids, i, j)
            }
        }
    }
    return count
}

private func helper(_ grids: inout [[Character]], _ x: Int, _ y: Int) {
    guard x >= 0 && x < grids.count && y >= 0 && y < grids[0].count else {
        return
    }
    if grids[x][y] == "1" {
        grids[x][y] = "X"
        helper(&grids, x-1, y)
        helper(&grids, x+1, y)
        helper(&grids, x, y-1)
        helper(&grids, x, y+1)
    }
}
```
Flutter の DropdownButton の項目を、他の状態に応じて変更する

# setState で関連させたい状態の値を一緒に変更する
setState の中で変更したら良い。後は、build でその状態用のリストを動的に確保するだけ。
気付けば簡単。

ドロップダウンA に応じて、ドロップダウンB の項目を切り替える場合、以下のような感じ

```dart
  listForB() {
    return List.generate(stateB, (i) => i);  // stateB に応じてリストを作る
  }

  @override
  Widget build(BuildContext context) {
    var listA = listForA();
    var listB = listForB();
    // ... 中略 ...
      dropdownButton<_T>(
        value: stateA,
        onChanged: (newValue) {
          setState(() {
            stateA = newValue;
            // stateA で stateB を正規化などする
            // ここで選択肢に含まれるように修正する
            stateB = normalizedStateB(stateA);
          };
        },
        // ... 中略 ...
      ),
      dropdownButton<_T>(
        value: stateB,
        onChanged: (newValue) {
          setState(() {
            stateB = newValue;  // そもそも有効な値しか選択されないようになる
          };
        },
      // ... 以下略 ...
```

まだ、戯れているだけなので、効率がどうなのかはあまり気にしていない
（`listForA`, `listForB` をキャッシュする必要があるかなど）。

# onChanged を括り出したいのだけれど…
上記のように無名関数だと動くのに、`State` のメンバ関数にすると、下記のようなエラーが出ることが。

```
type 'int' is not a subtype of type 'String'
```

持ってるスコープの問題だったりするんだろうなぁ。この辺、`setState` の黒魔術がどうなっているのかほどかないと駄目そう。
ネット対戦できるテトリスを２週間で作った話

# はじめに

こんにちは。ユニバの MJ です。
会社が暇で暇でしょうがない(私だけ)ので、３０なる前に一つテトリスでも作るかと思い至った次第。
しかもテトリスエフェクト見たいなモテそうなやつ

# 開発メンバ

私を含めて 5~6人。
えいやえいやと有志が集まり複数人開発となりました。参加してくれた皆さんありがとう！

# 私の技術スタック

Unity歴ほぼなし!
普段はフロントエンド (iOS, Android アプリもやったりする) やってて、最近 Shader とか触ってた。
プログラムを書くこと自体は慣れているので `C#` 自体もそんなに苦にならない程度。
むしろ Unity 自体のツールに慣れるまで辛かった。

# 2週間の見通しとスケジュール

- 1週間目: テトリスの大枠を作る
- ２週間目: ネット対戦できるように転換

この目標を前提として、３日に一回ぐらい集まって、

- やったところ
- 次にやりたいこと
- 困っているところ

とかを共有して、常に目標とやる気ベースでサイクルを回していきました。
こういうお金関係ないプロジェクトは楽しくないと辛いですからね。

# 出来たもの

https://slack-files.com/T028UP1TV-FJVTVDD34-2a155a12e6

思った以上に雰囲気が出た。いやぁ〜弊社はすごい会社だなぁ(自惚れ)
ネット対戦は Score を共有して先に 10000点 とったほうが勝ちというクソザコルール。でもネット対戦だからガハハ。
(映像ではわかりにくいですが、対戦者が点数取るとそこが共有されます。)

# 個人的な開発プロセス

下に貼った、チュートリアルの内容を４回ぐらい写経して、作っては壊しを繰り返し Unity の開発になれる。
あとは wiki のロジックを実装していく。
という感じでした。特に何もないな。書いては捨てるの気持ちが大事。

# テトリスを作った上で得た技術

#### Unity の扱い

当初は、シーンをセーブせずに Mac がフリーズ、そして確認したら全てがパー。これだけは許すまじ。

#### 多人数開発

無駄なコンフリクトを避けるために、シーンをなるべく分けて、ギリギリまでリバートしてもコードは失われない状況を作った。
次は、シーンを分割する部分の落とし所をもっと探りたい。

#### UniRx

スクリプトが他のゲームオブジェクトに依存する形になると、すぐ転用が難しいコードが出来上がるので、こいつを使ってイベントを吐き出すだけにして実際のロジクは受け取り側で書くのが吉。まぁ普通によく出来たライブラリ。使っていきましょう。

#### ECS

とりあえず背景の頂点をうまく動かしたくて検索した結果
http://tips.hecomi.com/entry/2018/12/23/200817
に行き当たる。すごい(尊敬)。今回は拝借してパラメータを調整するだけに終わってしまったが、もっと有機的な動きをゲームのイベントと同期させたり、ロジック自体の理解を進めたい。
その中で ECS と出会う。この考え方は次世代の Unity の考え方のベースになると思うので今後も調べていきたいと思う。

#### Unity Package

ECS に関連して、まだ正式ではないライブラいを突っ込んだりした。
ここら辺の解決は Webpack の設定の困難さに似たものを感じた。世の中どこでもこういう苦労はあるものだ。

#### Photon - Bolt

ネットワーク対戦をお手軽にできんかと探したらあった。感謝しかない。
弊社で適当に作ってもよかったんだが、今回は敢えて他社サービスの利用をしました。P2P 通信とか簡単にできないからね。

理解すればすごい使いやすい。でもそこまでのチュートリアルが結構厳しいと思った。
あと転用したいときに API リファレンス読んでもうーんと唸る感じ。

#### テトリスの知識と実装。

テトリスのガイドラインってのが wiki に書いてあるのでそこから実装する機能を見繕う。
`next block` `hold` `super rotation` `hard drop` `ghost block` あたりを実装した。
テトリスは歴史があるので、調べるとそれぞれのロジックが書かれた参考が見つかるので、それを参考にしました。

https://www.youtube.com/watch?v=_G7jggODYy4&t=121s

あと基盤はこのシリーズ見たりすれば作れます。

# 作った感想

３０前にテトリス作れてよかった(本当に)。
あとゲーム作るのって本当に大変。UI/UX の塊だし、音とか適当に入れて変えて欲しいとか思って突っ込んでもそのまま放置されたり。
そういう意味で、一番最初にゲームのムードをきちんと設定できていると良かったんだなと思った。

途中で聞かれたのでサイバーリラクゼーションと伝えたらあれが出来た(たまげた)。

ちなみに当初はこちら(映像がないので gif だけ)
![May-19-2019 17-07-56.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68729/07b674b0-0af6-9e51-c0d6-1eb104cecba8.gif)

で少し経って (1週間時点)
https://slack-files.com/T028UP1TV-FJZSGUY6Q-7c69a49f01
ここでテトリスエフェクトの音とかフリー音源を当ててそれっぽくなった。

最終的には上のリンクのものになりました。
やる気ベースで開発するのって本当に大事だと思う。まじで。
案件ある中、やれる時間のなかで集中して作るのって結構しんどい。

次はレーシングゲーム作る妄想している。
野生動物のレースを参考にしようとしたけど、思った以上にしっかりと出来てた。。。。

テトリスは割と知見が溜まっているプロダクトなので、手始めに始めるにはすごい良い教材でした。
皆さんも作ったテトリス共有してドヤ顔しましょう。
【AWSの403エラー】本番環境だけimgタグが保存できないのはAWSのWAFのせいかもしれない話

# imgタグを入れた瞬間に保存できなくなった
フォームの入力欄に img　タグを含めた瞬間に保存できなくなってしまったのである。

本番Docker運用でテスト環境と全く同じ環境で作っているはずなのにエラー。
テスト環境では正常に保存できたのに。。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69647/4b64eb94-6c32-5268-404e-bf42896d3bdc.png)


なんのエラーも出ないし、サーバのログにも何も出力されていない。
CloudWatchのログにもなぜか200が返ったことになって表示されている。

## AWSのWAFがHTMLタグを含めたPOSTを弾いていた。
通常のH1タグやBタグは利用できて、imgタグのSRC属性を入れた瞬間に弾かれる

この挙動からセキュリティー的なものが悪さをしているのではと調査開始。

Laravel、マークダウンパーサーのライブラリをチェックしたが見つからず。

しかし

### WAFをみたら見事はじかれてました。。。。
さすが有料で買ったセキュリティー設定。
優秀。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69647/1491e602-f27a-de65-8770-2785d08d3857.png)

## こちらで例外を追加して対応
こちらの記事を参考に直しました

https://dev.classmethod.jp/cloud/aws/aws-waf-false-positive/


## 総括
よくわかってないセキュリティー設定をとりあえず安全そうだしこれでいいや！って入れると爆死することがある。

これ自体素晴らしい設定だとは思うのですが、よくわかってない素人が使うとダメですね←
Cyber Security Cloud Managed Rules for AWS WAF -HighSecurity OWASP Set-
GoPro HERO7 Black で撮影した GPS 情報付きのビデオファイルからメタデータを抜き出す最も簡単な方法。

以前は ffmpeg とかいろいろ使わなくちゃいけなかったんですが、

https://tailorandwayne.com/gopro-telemetry-extractor/

ここでファイルをあげるとさまざまなメタデータを抽出してくれるサービスが（今のところβみたいですが）始まっています。

裏側の部分は↓作者の方がオープンソースにしてくれてるみたいです。
https://github.com/JuanIrache

ありがたい限りです。
同じものを含む円順列（数学A)　その３

# 同じものを含む円順列　その３
今度は，三種類でやってみたいと思います。

### 問題
1. 白玉2個，黒玉3個，赤玉4個を円形に並べる方法は何通りか？
2. 白玉3個，黒玉3個，赤玉3個を円形に並べる方法は何通りか？

###解答
1. まず，白玉2個，黒玉3個，赤玉4個，合計9個を一列に並べます。並べる方法は，
$$\frac{9!}{2!3!4!} =1260\text{（通り）}$$
となります。

2，3，4の公約数は1のみです。

- 公約数1...$\frac{9}{1}=9個で1通り$

これしかないので，9で割ればいいことになります。
$$\frac{1260}{9}=140\text{（通り）}$$

2. まず，白玉3個，黒玉3個，赤玉3個，合計9個を一列に並べます。並べ方法は
$$\frac{9!}{3!3!3!} =1680\text{（通り）}$$
となります。


3，3，3の公約数は3，1です。

- 公約数1...$\frac{9}{1}=9個で1通り$
- 公約数2...$\frac{9}{3}=3個で1通り$


#### 3個をまとめて1通り

○⚫︎△を並べて，$3!=6\text{（通り）}$

円形に並べると，1，1，1の公約数は1なので，3で割ればよく，
$$\frac{6}3=2\text{（通り）}$$

#### 9個をまとめて1通り

全体から『3個をまとめて1通り』のケースを除いて，9で割ります。
$$\frac{1680-6}{9}=\frac{1674}{9}=186\text{（通り）}$$


以上より，
$$2+186=188\text{（通り）}$$
となります。
freemlの「メンバー掲示板」の投稿内容をテキストファイルに変換


#はじめに
メーリングリストサービスの「freeml」が、2019年12月2日で終了してしまうようです。
メーリングリスト自体は他にも様々あるので問題ない（LINE とか Slack とかもあるし）にしても、
サービスの一つであった「**メンバー掲示板**」が見れなくなるのが困る、という人は少なからずいるのではないでしょうか。
しかも「せめて、今までの掲示板の内容だけでも別途残しておきたい」と思っても、そのような機能はありません。

>https://help.freeml.com/hc/ja/articles/360000220481-掲示板のダウンロードはできますか-

>=================================
掲示板のダウンロードはできますか？

>MLホームページの掲示板に投稿された内容は、ダウンロードいただけません。
>恐れ入りますが、何とぞご了承ください。

>=================================

そのため、掲示板の内容をテキストファイルに変換するプログラムをPythonで作ってみました。

#コード

```python
########  編集が必要な箇所 ４つ  ###############################
##（１）ファイル出力先ディレクトリ（フォルダ）を指定
output_dir = "xxxxxxxxxxxxxxxxxx"
#  例：output_dir = "/Users/mac/Documents"

##（２）メールアドレスとパスワードを指定
user = "xxxx@xxxxxx"           #  ID
password = "xxxxxxx"           # password 

##（３）freemlページの「掲示板をもっと見る」をクリックした後のURLを指定
url = "https://www.freeml.com/ep.umzx/grid/MLC/node/MlcBbsDetailFront/local_part/xxxxxxxxxxxx"

##（４）掲示板の最終ページを指定
page = xxx
#　掲示板のURL末尾に数字を入れるとそのページに飛べるので、事前に確認
#　例：page = 821
###########################################################

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
import re
import os
import datetime

#  カレントディレクトリ指定
os.chdir(output_dir)    

# セッション開始
session = requests.session()

# ログイン
login_info = {
    "email":user,
    "password":password,
    "save_password":"save_password" }

url_login = "https://www.freeml.com/ep.umzx/grid/General/node/SpLoginProcess"
res = session.post(url_login, data=login_info)

if os.path.exists('keijiban_temp.txt'):     # 一時ファイルが既にあったら
    os.remove("keijiban_temp.txt")         # 削除する

name_list =[]    ## 空リスト

########  ここからloop　#########################
for i in range(1, page + 1):
    url_page = url + "/page/" + str(i)

    res = session.get(url_page)
    soup = BeautifulSoup(res.content, 'html.parser')

    li_elements = soup.select_one("div.bbs_list_bg > ul")

    #　抜粋した文書を一時ファイルに書き込む
    temp_file = open('keijiban_temp.txt', 'a')   #  a は追記モード
    temp_file.write(li_elements.text)
    temp_file.close()

   #　ユーザ名だけ抜粋
    li_elements_name = soup.find_all("strong")    ##  ユーザ名のみ
    name_list += [item.text for item in li_elements_name]
########  loopここまで　########################

####  テキストファイル整形　#########
#　一時ファイル読み込み
temp_file = open('keijiban_temp.txt', 'r')  # r は読み取り専用
areas = temp_file.readlines()
temp_file.close()

#　出力ファイル作成
url_end = url.split("/")[-1] 
now = datetime.datetime.now()

output_file_name = url_end +"_" + '{0:%Y%m%d}.txt'.format(now)   # 出力ファイル名にアドレス、日付含む
output_file = open(output_file_name, 'w') 

#　ファイル整形
name_unique = set(name_list)    # ユーザ名の重複除外

for area in areas:
    for i in  name_unique:
        name = "^" + i + "\n$"
        name2 = "-----------------------------------------\n" + i
        area = re.sub(name, name2, area)
    area = area.replace('[削除]','')
    area = area.lstrip()

    output_file.write(area) # 文字列を記載する

output_file.close()

#  一時ファイルは削除
os.remove("keijiban_temp.txt")
#############################################
```
Pythonが入っているPCなら動くと思われ…
（プログラミングに関してはど素人なので、コードが汚いのはご勘弁ください）
Aws＋SpringBoot構成でちょっとした日次処理を回したい

# Aws＋SpringBoot上での定期実行の実装方法検討
EC2⁺SpringBootで動いているWebアプリで定期実行機能を実装することになり、
何を使って実装するかについて検討を行ったのですが、
思ったより色々な方法があったので、備忘も兼ねてメモしておきます。

## やりたかったこと
トランザクションデータについて毎日深夜にチェックを行い
対応期日が近いにも関わらず未処理なデータを抽出して警告フラグを立てる。

## 前提
* データはRDS(Aurora)に格納されている。
* トランザクションデータ量は現状月間数百件と少ない。
* 小規模な社内用システムなので、EC2は冗長構成になっていない。
* 処理は対象レコードをSQLで抽出してUpdateするだけ。

ようするに、小さなシステムでのささやかな日次処理です。

## 候補として考えた/調べたもの
* AwsBatch
* AwsLambda
* Spring上で何とかする

## 検討結果

### AWSBatch
https://aws.amazon.com/jp/batch/
利用できなくはないものの、明らかにオーバースペックでした。
EC2インスタンスを大量に立て、その上で大規模データを分散処理するためのフレームワークなので、
ちょっとした処理を日次で回したいためだけに使うのは不適切です。

### AWS Lambda + CloudWatch
大した処理ではないのだからサーバーレスで行こうという発想です。

LambdaとAuroraは相性が悪いとよく言われます。
しかし、これはlambdaのトリガーとなるイベントの数が制御できない場合に
大量同時起動によってコネクションが枯渇する恐れがあるためです。
よって、今回のように一日深夜に一回だけというケースでは問題になりません。

実装方法としてはlambdaを適当な言語で書いて、
CloudWatchのスケジューリング型のルールにターゲットとして紐づけてやるだけなので大した手間はありません。
有力な候補です。

### Spring上で何とかする
この辺りまで考えて、そもそも現在の構成で定期実行機構を外に出す必要があるのかという疑問も出てきました。
現在のこの社内システムはユーザーがごく少数で、リソースには余裕があります。(深夜はなおさら)
何となく流行りのアーキテクチャということで外に出しそうとしていましたが、
モノリスティックな構成で制御可能な範囲ならそちらの方が楽なケースは多々ありますし、
分割する必然性はありません。
というわけで、すでに立っているEC2上で処理してしまう方法を考えます。

#### SpringBatchかSchedulingTaskか
cronで何かを叩かせてもいいですが、せっかく同じサーバー上で実行するからには
Spring上で行ったほうがロジックの再利用性や管理の面で便利です。

Springでバッチ系処理というとSpringBatchが有名ですが、
AwsBatchほどではないにしても、大規模で複雑なデータ処理用に高度に抽象化された基盤です。
今回の日次のちょっとした処理には依然としてハイスペックすぎます。

一方で、SchedulingTaskなら少し依存性を足してアノテーションを付けるだけで定期実行可能です。
https://spring.io/guides/gs/scheduling-tasks/
cron書式で指定できるので、当然日次実行も問題ありません。

というわけで、今回の目的のためには一番これが楽そうです。

##### スケールアウトが必要になったらどうするのか？
APサーバーとバッチ処理を密結合させてしまうことの最大の問題点は、
APサーバーを冗長構成にしたりスケールアウトさせた場合の実行制御が難しくなることです。
(普通にそのまま2台、3台と増やしてしまうと多重実行されてしまう)

今回検討しているシステムについてはそこまで拡大する予定がないので問題はないと思いますが、
万が一必要になった場合には、ロジックをWebAPIから呼び出す形に変えて、
AWSLambdaに叩かせるように変更しようと思います。

## まとめ
* ちょっとした定期実行処理ならSpring上でSchedulingTaskが楽。
* スケールアウトが必要にならばlambdaで。
* AWSBatchはビッグデータの分析等に
AmazonConnectのタイムアウトを防ぐため、別スレッドに処理を投げ、レスポンスを返す

下記のようにPOSTでやり取りしていた。
![flow.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384142/0d5b96ae-e6b0-bba7-d3b8-247f88e1f328.jpeg)

しかし、AmazonConnectのタイムアウトが最大8秒に制限されているため、タイムアウトしてしまう。
そこで、下記のように、8秒以上かかってしまう処理をスレッドに分けることにした。
スレッドの実行が開始できた時点で、呼び出し元にはOKを返却する。


```java:hoge.java

@Service
public class hogeService {
    @Autowired
    private ApplicationContext applicationContext;

    public hogeReturnDto hogeService(hogeRequestDto request){
        // 長い時間のかかる処理でスレッドを作成、実行する
        hogeThread thread = new hogeThread(request);
        applicationContext.getAutowireCapableBeanFactory().autowireBean(thread);
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.execute(thread);

        // 呼び出し元にはOKを返却
        ResponseDto responseDto = new ResponseDto();
        responseDto.setCode(200);
        responseDto.setMessage("OK");
        return responseDto;
        return;
    }
}
```
VirtualBoxを用いたローカル開発環境（備忘録）

**VirtualBox**とは、手元のPCの中にいくつもサーバを立ち上げることが出来るツール
**Vagrant**とは、VirtualBoxを簡単なコマンドで設定やインストール作業が出来るツール

<p>VirtualBoxのインストール</p>
[ここからダウンロードできます](https://www.virtualbox.org/wiki/Download_Old_Builds)

<p>Vagrantのインストール</p>
[ここからダウンロードできます](https://www.vagrantup.com/)

<p>※サーバは１つにつき、１つのフォルダが必要になります。<br>
  サーバを複数立ち上げても管理しやすいよう、それらをまとめるフォルダを作っておきましょう。</p>

<h2>仮想マシンの立ち上げ</h2>

```
# ホームディレクトリに移動
 => cd
# 複数のサーバをまとめるフォルダの作成(今回はMyVagrant)
 => mkdir MyVagrant
# MyVagrantに移動する
 => cd MyVagrant
# 仮想マシンを作るフォルダを作る（MyCentOS）
 => mkdir MyCentOS
# MyCentOSに移動する
 => cd MyCentOS
# 仮想マシン設定用のVagrantfileを作る
 => vagrant init bento/centos-6.8
# Vagrantfileを編集して仮想マシンのIPアドレスを決める（今回は192.168.33.10）
 => sed -i '' -e 's/# config.vm.network "private_network", ip: "192.168.33.10"/config.vm.network "private_network", ip: "192.168.33.10"/' Vagrantfile
# 仮想マシンを起動する
 => vagrant up
# 仮想マシンの状態を確認する(runnigと出れば仮想マシンは動いている)
 => vagrant status
```

<h2>仮想マシンの設定</h2>
```
#仮想マシンのサーバにログイン(ログインするとコマンドを打つ部分が変わる)
 => vagrant ssh
# OSを最新状態にアップデートする
 => sudo yum -y update
# スクリプトを入手するためのgitをインストール
 => sudo yum -y install git
# gitを使ってアプリケーション設定用のスクリプトをダウンロード
 => git clone https://github.com/dotinstallres/centos6.git
# centos6フォルダができるのでそちらに移動
 => cd centos6
# スクリプトを実行
 => ./run.sh
# 設定を反映
 => exec $SHELL -l
 ```

<h2>Cyberduckをインストール</h2>
<p>Cyberduckとは仮想マシン上のファイルを簡単に移動させるための転送ツール</p>
[ここからダウンロードできます](https://cyberduck.io/)

<h2>仮想マシンにアクセス</h2>
<p>Cyberduckを起動し、新規接続でプロトコルをSFTPを選択。サーバは仮想マシンで決めたIPアドレスを入力。<br>
  Vagrantで作られたサーバのユーザ名とパスワードは”vagrant"となる。</p>
<p>PHPやRubyを使う場合は、新規フォルダを作成する</p>
<p>例）PHPの場合（フォルダ名：php_lessons ファイル名：index.php）</p>

```
#PHPフォルダに移動
 => cd php_lessons
 #表示されたIPアドレス（192.168.33.10）をコピーし、ブラウザでアクセスする。

＃index.phpの内容が表示される。
```

<h2>終了の手順</h2>
<p>ブラウザ、ファイル転送ツール（Cyberduck）、エディタはそのまま終了させる。</p>
<p>ターミナ（PHPで作業していた場合）は、Ctrlキー + CでPHPを終了させる。</p>
<p>exutで仮想マシンからログアウトし、vagrant saspendで仮想マシンを停止できる。</p>
<p>その後、exitでターミナルを終了できる。</p>

引用資料
[ドットインストール ](https://dotinstall.com/lessons/basic_localdev_mac_v2)
Dark Mode 対応で抑えておくところ

Mojave で搭載された「Dark Mode」の対応について、抑えておくところのメモです。

# デザインで抑えておくところ

- Dark Mode と Light Mode それぞれの配色を考える必要がある
- 複雑な配色のアセットを避けるのも一つ
    - デザインアセットが増えると管理コストも増えるので、一つのアセットをプログラムでその配色に塗るようにするのもよいかも
- Human Interface Guideline で例に上がっている「アセットを別々のものにする必要がある」例
    - Light Mode 時インナーシャドウで表現しているところは、Dark Mode 時インナーグローで表現するようにする
        - Dark Mode でインナーシャドウが使われていると、そのアセットがダークな背景に溶けてしまう
    - HIG で解説されているので、詳しくは要チェック
- 消極的解決法：アプリに「Dark Mode をサポートしない」という設定ができるので一旦はこれでしのぐ

# 実装で抑えておくところ

## 画像を Dark Mode と Light Mode で切り替える

**Assets.xcassets** で管理する画像について、 「Appearance」 を `Any, Dark` に設定して、それぞれのスロットに画像をアサインする（Dark Appearance = Dark Mode 用、Any Appearance = いまのところ Light Mode 用）。

￼![スクリーンショット 2019-06-03 3.28.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5542/8cfd0960-338b-7ebf-39c0-95a1665122ff.png)

## 現在の外観モード（Dark Mode かどうか）を確認する

```swift
let appearanceName = NSApplication.shared.effectiveAppearance.name

switch appearanceName {
case .aqua:
    print("Light Mode")
    label.textColor = NSColor.red
case .darkAqua:
    print("Dark Mode")
    label.textColor = NSColor.blue
default:
    assertionFailure()
}
```

コードで切り替える場合は外観モードを確認した上で適用していきます。


##  外観モードが変更されたことを検知する

`NSView.viewDidChangeEffectiveAppearance()` を override します。

```swift
override func viewDidChangeEffectiveAppearance() {
    print(NSApplication.shared.effectiveAppearance.name)
}
```

macOS の設定画面で「外観モード」を変更すると、アプリでの表示も切り替わることを確認できます。

![スクリーンショット 2019-06-03 3.45.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5542/5955d3d0-9e41-d68f-d192-101544954249.png)


## 消極的解決法：外観モードをライトのみサポートする

```swift
NSApplication.shared.appearance = NSAppearance(named: .aqua)
```

OS で Dark Mode に設定していても、アプリは Light Mode な感じで表示されます。
OS が Dark Mode に設定してある場合、このコードが実行されてから画面に反映されるまで一瞬 Dark Mode で表示されてしまうので、バグっているように見せてしまうかも…。


## サンプル

こちらに上記を試せるサンプルコード載せておきましたー
https://github.com/feb19/DarkModeSampleApp-macOS



# 読んでおくと良さそうなリソース

- デザイン： [Human Interface Guideline - Dark Mode](https://developer.apple.com/design/human-interface-guidelines/macos/visual-design/dark-mode/)
- デザイン： [Dark Mode List](https://darkmodelist.com/ios/) (iOS でダークモードを独自で実装しているアプリの UI アーカイブカタログサイト)
- デザイン： [Material Design - Dark theme](https://material.io/design/color/dark-theme.html) (Material Design の配色を参考にするのもよさそう)
- 実装： [Apple Developer Documentation - Supporting Dark Mode in Your Interface](https://developer.apple.com/documentation/appkit/supporting_dark_mode_in_your_interface)