OmniAICreator/Qiita-1.07M huggingface dataset:
React の ErrorBoundary で非同期のエラーをキャッチする

React の ErrorBoundary は、ドキュメントにあるように非同期のエラーをキャッチできない。

```js
async function getUser() {
  /* ... */
}
function Profile() {
  const [user, setUser] = useState(null);
  useEffect(() => {
    (async () => {
      try {
        const user = await getUser();
      } catch (error) {
        // このエラーは ErrorBoundary でキャッチできない
        throw error;
      }
      setUser();
    })();
  }, []);

  if (!user) return null;
  return <div>{user.name}</div>;
}
function App() {
  return (
    <ErrorBoundary>
      <Profile />
    </ErrorBoundary>
  );
}
```

[Dan Abramov 曰く](https://github.com/facebook/react/issues/14981#issuecomment-468460187)、こういうテクニックで想定どおりのキャッチができる。

```js
const [, setState] = useState();
```
```js
setState(() => { new Error("Hi") });
```

なので、さっきのコードでいうと

```js
async function getUser() {
  /* ... */
}
function Profile() {
  const [user, setUser] = useState(null);
  const [, setState] = useState();
  useEffect(() => {
    (async () => {
      try {
        const user = await getUser();
      } catch (error) {
        // これは ErrorBoundary でキャッチできる
        setState(() => {
          throw error;
        });
      }
      setUser();
    })();
  }, []);

  if (!user) return null;
  return <div>{user.name}</div>;
}
function App() {
  return (
    <ErrorBoundary>
      <Profile />
    </ErrorBoundary>
  );
}
```

こうすれば ErrorBoundary でキャッチできる
MacのMAMPでバーチャルホストをカスタマイズ

MAMPでバーチャルホストをカスタマイズする方法について書きます。

# 前提条件
- MacにMAMPがインストールされていること

# 設定
`httpd.conf`ファイルで以下の箇所の`#`コメントアウトを外します。

```conf:/Applications/MAMP/conf/apache/httpd.conf
#Include /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf
↓
Include /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf
```

`httpd-vhosts.conf`ファイルの末尾に以下のような記述を追記します。
`Listen`と`VirtualHost`に使われていない適当なポート番号を、
`DocumentRoot`と`Directory`には使いたいディレクトリパスを入れます。

```conf:/Applications/MAMP/conf/apache/extra/httpd-vhosts.conf
Listen 8001
<VirtualHost *:8001>
    DocumentRoot "/Users/userId/test"
    <Directory "/Users/userId/test">
        AllowOverride All
    </Directory>
</VirtualHost>
```

同じようにポート番号を8002、8003と使われていない番号で追記していくと、
複数のバーチャルホストを設定することが出来ます。

# アクセス
safariで設定したポート番号のページを開く

```shell
open -a '/Applications/safari.app' http://localhost:8001
```

# 参考文献
この記事は以下の情報を参考にして執筆しました。

- [MAMPでの複数のローカルホストのたてかた！](https://qiita.com/tsukishimaao/items/cab4caa065d901608856)
社会人1年目できをつけること


# 社会人1年目できをつけること 
IT業界に入って、私もはれて社会人二年目になります。
そこで、はじめから気を付けていればと思うことをまとめます。

正直、頭の回転がよろしくない私からすると、
IT業界は覚えることが多忙で辛くなって休む日もありました。

大変だったけど、憧れた業界だったので毎日全力を尽くしました。

でも社会人って結果がすべてで、
どこまで頑張ったか？
ではなく、
どこまでできたか？
でしか評価を得ることはできません。

悲しいけどこれが現実.....

でも、はじめからこれができれば...
てことが

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

私が１番に思うことは「質問の仕方」なのです。

# 以前の質問...
これを言っては「あれ」ですが、
はじめてする仕事はわからないことばかりです。

なので、とりあえず「全部教えて！」みたいな投げやりな質問を繰り返してました。

考えて質問してないので、
もちろん上司からの評価は最悪です......。

上司「え？　どこどこ？（調べたらわかるやろが（怒））」

でも、ほんとの初期はそれでいいと思います。

だってほんとに何もわからないんだから仕方ないじゃん。

#現在の質問...
でも、ある程度時間が経つと質問しなくてもいいことが出るてくると思います。

例えば質問の切り分けをしてみるとか。

聞かないとわからないこと
・仕様的な問題でググってもわからないこと。
・未確定の問題で自分では決めれないこと。

調べたらわかりそうなこと
・プログラムなど

切り分けると簡単です。
聞かないとわからないことすなわち、

自分で解決できない問題は考えるだけ無駄！無駄！無駄！

いち早く聞くことをおすすめします。

その問題はググっても出ないし、時間は解決してくれません。

でもいるんですよね。

「自分で考えて(笑)」

みたいな人。

そんなやつはクソ！！！

でも、粘着して質問するしか解決方法はありません。



じゃあ問題は「調べたらわかりそうなこと」

これが一番大変。

でも、調べたらわかるなら質問しなくてよくない？

とはじめは思います。

でも、実際は違いますよね。

時間は有限です。

上司は賢く活用すべきだと思います。

例えば、調べたらわかりそうだけど時間がかかる問題。

5分調べてわからなかったら質問するなどルールを決めます。

だったら今までの質問では、
「全部教えて！」
から
「ここまで調べたけど、ここからはわからん　or　ここからは教えて！」

後者のような質問になりますよね。

上司からしても「一応調べてから質問してるのかな」って悪い印象は回避できます。

しかも、自分でわかる部分は調べてるので

時間のかかる部分だけ説明してもらえるので「時間短縮」になります。

#質問の形式...

次は、質問の形式を考えます。

まず私の質問ルール。
・不要なことは省く。
・問題点　→　試したこと　→　質問　の順番
・質問をまとめる

・不要なことは省く。
　不要なことは省くについては、
　上司の時間は貴重だと意識する。
　ああ、上司様は私のために時間を使ってくれている。
　そうです、上司はとは自分より多忙で責任も大きい方です。
　簡単な問題は暇そうなネットサーフィンしている人に聞きましょう。
　適当な質問を続けると「またお前か・・・・」と負の存在と認識されます。

・問題点　→　試したこと　→　質問　の順番
　問題点　→　試したこと　→　質問　の順番については、（割と重要）
　この形式、この順番が鉄則。
　例えば、
　いま何行目でエラーが出ていて、
　ログを調べると、
　これが原因だとわかりました。
　修正方法はこれで合ってますか？
　といった無駄のない質問内容になります。
　
　この質問方法は上司の時間を極限に減らせます。
　必ずこの質問にできるわけではないですが、
　はい　or いいえ　で答れる質問に必然的になるので、
　上司は二択から選ぶだけ。
　もし質問内容が間違っていた場合も、
　どの部分が間違っているのか指摘してもらえます。
　なので、現時点で最強の質問方法だと私は思います。
　
・質問をまとめる
　質問をまとめるについて、
　あなたは普段問題が起きた都度質問してませんか？
　もちろん悪いことではないです。
　でも、あなたは終わりの見えない距離をマラソンできますか？
　そうです。人はゴールが決まっていることでそこまで頑張ろうと思います。
　なので、本日の質問は３点あります！
　と、終わりが見えると心の準備ができます。
　何本か説明する、しない、では大きな違いがあります。

　
# まとめ
　ほんとに困ったら聞くべき！
　悩む時間は無駄！
　調べてわかるなら調べよう。
　でも、時間かかるなら説明してもらおう。
　無駄を減らそう。
　質問の形式を整えよう。
　質問はまとめよう。

　所感
　　悩んでいる時間はほんとに無駄です。
　　でも、なかなか質問できない気持ちはわかります。（コミュ障）
　　ですが、私は社会人....
　　嫌われてもいいから勇気をもって自分の現状を伝えるべき。
　　申し訳ない気持ちは余計。
　　後輩ができたら、いやな顔をせずに、
　　教えることが恩返しになるのです。
　　できる上司ならそう思うはず。
　　そう願いたいです。　　

　　以上、1年目を振りかえって感じたことでした。
よく使うVSCodeのプラグイン

# 共通
## [Japanese Language Pack](https://marketplace.visualstudio.com/items?itemName=MS-CEINTL.vscode-language-pack-ja)
インターフェースを日本語で表示する

## [Material Icon Theme](https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme)
ファイルにアイコンをつけて分かりやすくする

## [Bracket Pair Colorizer](https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer)
階層構造の括弧に色をつけて見やすくする

## [indent-rainbow](https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow)
インデントに色をつけて見やすい状態にする

## [Indenticator](https://marketplace.visualstudio.com/items?itemName=SirTori.indenticator)
現在のインデントをハイライトして見やすい状態にする

## [Trailing Spaces](https://marketplace.visualstudio.com/items?itemName=shardulm94.trailing-spaces)
末尾の不要な空白をハイライトする

## [Path Intellisense](https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense)
パスの入力で候補を出してくれる

## [Duplicate action](https://marketplace.visualstudio.com/items?itemName=mrmlnc.vscode-duplicate)
簡単にファイルを複製出来る

## [GitLens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens)
行単位でコミットの歴史を見ることが出来る

## [Git Graph](https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph)
SourceTreeみたいにgitを見ることが出来る

## [Output Colorizer](https://marketplace.visualstudio.com/items?itemName=IBM.output-colorizer)
consoleで色つける

## [Partial Diff](https://marketplace.visualstudio.com/items?itemName=ryu1kn.partial-diff)
diff取れる

# 言語
## [Beautify](https://marketplace.visualstudio.com/items?itemName=HookyQR.beautify)
HTML、CSS、JSのフォーマッター

## [HTML Snippets](https://marketplace.visualstudio.com/items?itemName=abusaidm.html-snippets)
HTMLを使いやすくする

## [Highlight Matching Tag](https://marketplace.visualstudio.com/items?itemName=vincaslt.highlight-matching-tag)
HTMLタグの始まりタグと閉じタグをハイライトする

## [language-stylus](https://marketplace.visualstudio.com/items?itemName=sysoev.language-stylus)
Stylusを使いやすくする

## [pug](https://marketplace.visualstudio.com/items?itemName=amandeepmittal.pug)
Pugを使いやすくする

## [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur)
Vueを使いやすくする

## [PHP Intelephense](https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client)
PHPを使いやすくする

## [Laravel 5 Snippets](https://marketplace.visualstudio.com/items?itemName=onecentlin.laravel5-snippets)
Laravelを使いやすくする
単一画像から, 3D 顔形状 + expression を復元する RingNet のメモ

https://github.com/soubhiksanyal/RingNet

単一画像から, 3D 顔形状復元 + expression parameter 推定します. FLAME を使っています.

term of use などライセンス, 利用許諾を確認してから, 同意できる場合のみ, コードと pretrained model ダウンロードしましょう.

以下は同意できて, コードと pretrained model をダウンロードできた人向けです.

## 環境

* miniconda python3.6
* CUDA 9.0(!)
* Ubuntu 16.04
* Tensorflow 1.12.0

CUDA 9.0 で tensorflow-gpu をセットアップするのがめんどいです.
もしかしたら CUDA 10 + Ubuntu 18.04 + tf 1.15 あたりで動くかもしれません.

## python3 でビルドする.

python2.7 はいろいろ依存ライブラリのビルドがうまくいかないので, python3 でやります.

ちなみに neural net での推論(tensorflow)は, 画像を入力して結果がでるというオーソドックスなものなので, 残りの部分(3D 形状復元)などは自前でやってしまうのも手です.

`pip` は, conda のものが使われているか, `which pip` で確認しておきましょう.

システムなどにインストールされている pip のパスが出る場合は, `python -m pip ...` で pip 関連を処理するのも手です.

pyrender だけ最新をインストールします.

opendr は OSMesa がいるので, ubuntu でしたら

```
$ sudo apt install libosmesa6-dev
```

でインストールしておいてから,

```
$ pip install opendr
```

します(2020/03/13 時では opendr-0.78 がインストールされました)

### psbody-mesh

https://github.com/MPI-IS/mesh

をビルドしてインストールしておきます.

Makefile を使うと変な処理が走るので,
apt で libboost-dev など入れておき,

```
$ python setup.py build
$ python setuo.py bdist_wheeel
$ pip install dist/psbody-****.whl
```

とするのがよいです. 



### ソースコード書き換え

cPickle を使っているところがあるので,


Python3でcPickleのエラーを回避する
http://testpy.hatenablog.com/entry/2017/03/17/000626

などを参考にして書き換えます.

posemapper の import に失敗したりするので,

py2在py3上运行遇到的问题
https://blog.csdn.net/qq_43593646/article/details/86670084

を参考に書き換えます.

他にも python2 的なコードを py3 に書き換えます.

## 推論を実行する.

あとは demo.py を実行するだけです.

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ありがとう RingNet 🎉🎉🎉🎉🎉🎉🥰🥰🥰🥰😊😊😊😊🥳🥳🥳 &gt; <a href="https://t.co/qGnOMCc8jj">https://t.co/qGnOMCc8jj</a> <a href="https://t.co/ftH3jnC2OU">pic.twitter.com/ftH3jnC2OU</a></p>&mdash; Syoyo Fujita 🌸 RayWa(Ray and Peace) (@syoyo) <a href="https://twitter.com/syoyo/status/1238519934361059329?ref_src=twsrc%5Etfw">March 13, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

ただ, 3d mesh overlay あたりはうまくいきませんでした(結果は真っ黒). サーバーで実行したから OpenGL が使えないとかでしょうか.


とりあえず .obj mesh は出ますので, あとは自前でメッシュオーバーレイ可視化など書いて対応が楽でしょうか.


## TODO

* [ ] RingNet を fork して, Python3 対応版を github に上げる(現状いろいろ書き換えて無理やり動かしたので整理が必要)
* [ ] FLAME モデルのパラメータを理解して, expression 情報を出す
MacのDocker Desktopを使ってみる

# MacのDocker Desktopを使ってみる。

 - インストールしたときの記事はこちら。
    - https://qiita.com/pupupupupu/items/23dc0c4465a9402ad9bf
- MacのDocker Desktopを触ってみたら、いろいろできそうなので、まとめてみる。


# ログ (Logs項目)
 - docker logsのコマンドを叩いたときなどにでてくるログが出てきている。
 - Logsの項目にはいると、コンソールを起動したり、コンテナの停止、再起動、処分などがGUI操作で実施することができる。結構便利そうと思った。


# 起動時のパラメタ(Inspect)
 - docker inspect コマンドを叩いたときの設定項目が出てくる。
    - docker inspectよりもみやすい。項目などがきちんと整理されている。
        - Environment
            - 起動したときの、情報。
            - Jenkinsを参考にする
                - Javaのバージョン
                - JavahoeのPATH
                - ログの場所

        - Mount
            - ホストとコンテナのそれぞれのバインドされているファイルパスが明記されている。
        - Ports
            - ホストとコンテナのそれぞれどこのポートがつながっているか。
    
# ステータス監視 (Status項目)
- いま、コンテナがどのような状態なのかをみることができる。下記の項目が見えた。
    - CPU USAGE
    - MEMORY USAGE
    - DISK READ/WRITE
    - NETWORK I/O
   
<img width="1332" alt="docker.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412423/3f7013bf-dabf-0658-e169-2116f30090c5.png">
phpで簡易電卓を作る②

## phpで簡易電卓を作る
前回記事はこちら→https://qiita.com/pezio/items/ba31b0cba33b54c25a82

### 課題
・数値入力欄に数値以外を入力されたらどうする？
・続けて計算ができない

### エラーハンドリング
```caluculate.php
<?php
$number1 = $_POST['number1'];
$symbol = $_POST['symbol'];
$number2 = $_POST['number2'];
$answer ='';
if (isset($number1) && isset($number2) && is_numeric($number1) && is_numeric($number2)) {
    switch ($symbol) {
         case '+':
             $answer = $number1 + $number2;
             break;
         case '-':
             $answer = $number1 - $number2;
             break;
         case '*':
             $answer = $number1 * $number2;
             break;
         case '/':
             $answer = $number1 / $number2;
             break;
    };
    header('Location: index.php/?answer='.$answer);
} else {
    $message = '無効な値です';
    header('Location: index.php/?message='.$message);
};
```

ifの中で、（①要素が空白じゃない②数字である）場合のみswitch文への処理を行う。

`is_numeric — 変数が数字または数値形式の文字列であるかを調べる`
`isset — 変数が宣言されていること、そして NULL とは異なることを検査する`

条件が満たされない場合は変数`$message`にメッセージをつめて、パラメーターを送る。
それ以外の場合は計算結果を`$answer`につめて送る。

###　index.php
```index.php
<!DOCTYPE html>
<html lang='ja'>
  <head>
    <meta charset="utf-8">
    <title>Caluculator</title>
  </head>
  <body>
    <h1>電卓(簡易版)</h1>
    <form class="formula" action="calculate.php" method="post">
      数字1:<input type="string" name="number1"><br>
      記号:<select name="symbol">
        <option value="+">+</option>
        <option value="-">-</option>
        <option value="*">×</option>
        <option value="/">÷</option>
      </select><br>
      数字2:<input type="string" name="number2" value=""><br>
      <input type="submit">
    </form>
    <h2>答え:<?php echo $_GET['answer']?></h2>
    <h2><?php echo $_GET['message']?></h2>
    <a href="/"><input type="submit" value="リセット" ></a>
  </body>
</html>
```
`$message`を表示するために`<h2><?php echo $_GET['message']?></h2>`で表示。
`<a href="/"><input type="submit" value="リセット" ></a>`でトップへのリンクを作ることで、計算結果のリセットが可能に。

## 次回
機能追加
　・数字入力欄を新たに追加できるようにする
【EC2】本番環境で反映されない！？本番環境エラー時log確認系コマンド【リリース前】

こんばんみ

おささです

さ、前置きはダラダラ書かず

log確認行きまっしょい！

##EC2関係のエラーで役立つlog確認コマンド

まずはEC2サーバーにログインしてね！

その後

[ec2-user@ip-アドレス〜]$ **cd /var/www/確認したいリポジトリ名/current/log**
↓
[ec2-user@ip-アドレス log]$ **ls**
↓
[ec2-user@ip-アドレス log]$ ls
**production.log　unicorn.stderr.log　unicorn.stdout.log**
　　　↑　　　　　　　　↑　　　　　　　　　↑

上記、３つのlogが出てきたら準備OK！
（これらがなければ、本番環境構築時のミスがあるかも？）

あとは、確認したいlogの前に　**less**　をつけて、これらを確認！

【例】→　[ec2-user@ip-アドレス log]$ **less production.log**

ちなみに***production.log***を見れば、
　・syntax errorなのか
　・method errorなのか
　・unknown errorなのか　等

ざーっくりとしたerror箇所は確認できます。

##もっと詳しくエラー内容を知りたい！

[ec2-user@ip-アドレス log]$ **tailf production.log**

これで、もっと詳しいエラー内容を見ることができます😃
※「この引数がおかしいよ！」みたいに。

##その他
***nginxの再読込＆再起動***
　[ec2-user@ip-アドレス リポジトリ名]$ **sudo service nginx reload**
　[ec2-user@ip-アドレス リポジトリ名]$ **sudo service nginx restart**

***MySQL（お使いの方は）の再起動***
　[ec2-user@ip-アドレス リポジトリ名]$ **sudo service mysqld restart**

***unicornのmasterをkill***
　[ec2-user@ip-アドレス リポジトリ名]$ **ps aux | grep unicorn**
　[ec2-user@ip-アドレス リポジトリ名]$ **kill マスターの番号**

***gitを最新にpull***
　[ec2-user@ip-アドレス リポジトリ名]$ **git pull**
　[ec2-user@ip-アドレス リポジトリ名]$ **git log**　←一番上のlogが最新になっているか確認をしてね！

なども有効ですので、参考までに♪
jQuery+Colorboxでaタグ無しで画像のモーダル表示を実現する簡単な方法

画像のモーダル表示のためにLightbox系のライブラリの使い方を検索してみると、モーダル表示したい画像のimgタグをaタグで囲むようなものばかりが検索結果として出てきます。
しかし、CMS等の環境の制約によりaタグでimgタグを囲めない場合や、メンテナンス効率の低下を避けるためにaタグでimgタグを囲みたくない（aタグとimgタグの両方をメンテナンスしたくないし、それ以前に入力が面倒なのでやりたくない）場合があると思います。
そのような場合は、JavaScriptで画像(img)のクリックイベントを取得し、クリックされた画像のsrcを取得し、その値をColorboxのようなモーダル表示時に表示させる画像のリンク先（パス、URL）を指定可能なライブラリへ受け渡すことで、imgタグをaタグで囲むことなく、画像のモーダル表示を行うことができます。
※事前にjQueryとColorboxのファイル一式を用意（アップロード）しておきます。
```html
<script src="/lib/jquery/jquery.min.js"></script>
<script src="/lib/jquery/jquery-migrate.min.js"></script>
<script src="/lib/colorbox/jquery.colorbox-min.js"></script>
<link rel="stylesheet" href="/lib/colorbox/example4/colorbox.css" media="all">
<script type="text/javascript">
$(document).ready(function() {
    $("#content img").css("cursor","pointer");
    $("#content img").click(function() {
        $.colorbox({href:this.src});
        return false;
    });
});
</script>
```
## 関連URL
- [Colorbox](http://www.jacklmoore.com/colorbox/)
- [Is there any lightbox-script which doesn't need a html-anchor(Stack Overflow)](https://stackoverflow.com/questions/13068570/is-there-any-lightbox-script-which-doesnt-need-a-html-anchor)
フロントエンドエンジニアに必要なchromeのプラグイン4つ


# [The QR Code Extension](https://chrome.google.com/webstore/detail/the-qr-code-extension/oijdcdmnjjgnnhgljmhkjlablaejfeeb)
QRコードを使って現在開いているページを、読み込むことが出来る

# [PerfectPixel](https://chrome.google.com/webstore/detail/perfectpixel-by-welldonec/dkaagdgjmgdmbnecmcefdhjekcoceebi)
画像を透かして重ねてデザインとの差異を確認、微調整出来る

# [Page Ruler Redux](https://chrome.google.com/webstore/detail/page-ruler-redux/giejhjebcalaheckengmchjekofhhmal)
サイトの要素サイズや間隔を、仮想定規を引いて測ることが出来る

# [Alt & Meta viewer](https://chrome.google.com/webstore/detail/alt-meta-viewer/jjcjblcbnjhgjlnclhficglfjedhpjhl)
imgタグのalt属性や、ページのmeta情報を確認出来る
ブックマークレットで13日の金曜日を数える

#この記事は
2020年3月13日が13日の金曜日だったので、javascriptで13日の金曜日を数えてみました。
自分の誕生日から今日までに何度13日の金曜日を過ごしたか確認できます。

#コード

```javascript:friday_13th.js
javascript:(function(){

  let inputDate=prompt('誕生日は？', '2012/12/12'); //yyyy/m/d
  let birthday = new Date(inputDate);
  let today = new Date();
  let jasonDate = [];

  const listOf13th = (year)=>{
    return Array(12).fill().map((_, i) => new Date(`${year}/${i+1}/13`));
  }

  for(let y=birthday.getFullYear(); y<=today.getFullYear(); y++){
    let fridays = listOf13th(y).filter( 
      (d)=> (birthday < d && d < today && d.getDay() == 5)
    );
    jasonDate.push(...fridays);
  }

  alert('あなたは' + jasonDate.length + '回、13日の金曜日を生き抜きました。');

  console.table(jasonDate.map( (v,i)=>{
    return {date:v.toLocaleDateString()};
  }));
})
()
```

#まとめ
何事もなく過ごせました。よく頑張った。
【styled-components】styled(Component)でクラス名が付与されない

あまりにも何回もやってしまうのでメモ。

`styled-components`では`styled.div`とする以外に、既存のコンポーネントに`styled(Component)`とする方法がある。

```tsx:styled.div
import styled from "styled-components"

export const Component = styled.div`
  display: flex
  align-items: center
  justify-content: center
`
```

```tsx:styled()
import styled from "styled-components"
import { BaseComponent } from "../components"

export const Component = styled(BaseComponent)`
  display: flex
  align-items: center
  justify-content: center
`
```

## classNameを記述

React.FCコンポーネントを`styled(Component)`でスタイリングする場合、classNameを受け取れるようにしておく必要がある。

```tsx:OK
import React from 'react';

type Props = {
  className?: string;
};

const BaseComponent: React.FC<Props> = props => {
  return (
    <div className={props.className}>
      <div className="flex-center">{props.children}</div>
    </div>
  );
};

export const Component = styled(BaseComponent)`
  .flex-center {
    display: flex
    align-items: center
    justify-content: center
  }
`;
```

- next.jsでの例。  
 クラス名が注入されていることがわかる。  
![スクリーンショット 2020-03-14 1.35.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508043/fe869873-b559-ac58-a6fb-33c28d7cb0b7.png)


```tsx:NG
import React from 'react';

const BaseComponent: React.FC= props => {
  return (
    <div>
      <div className="flex-center">{props.children}</div>
    </div>
  );
};

export const Component = styled(BaseComponent)`
  .flex-center {
    display: flex
    align-items: center
    justify-content: center
  }
`;
```

当たり前だが、コンポーネントがクラス名を受け取れないためクラス名が付与されない。
![スクリーンショット 2020-03-14 1.36.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508043/927a154b-622e-5ed1-d245-51f916029781.png)
if式とif文

# Rustのif
 * プログラミング言語にはif文とif式があり、Rustはif式 
    * 計算式に答えがあるように式には戻り値がある。
    * 命令文は式ではないので、戻り値がない。
 * if式だけを書いても、戻り値があるため、結果を関数に渡せる。



```rust

 // 階乗を計算する。
fn factorial(n: usize) -> usize{
    // ifは式なので関数の最後に置くと値を返せる。
    if n == 0 {
        println!("1");
        1
    } else {
        println!("{}", n);
        n * factorial(n - 1)    
    }
}

fn main(){
    // `;`をつけると文になり、コンパイルが通る。
    // factorial(10);
    println!("10の階乗は {}", factorial(10));

}
```

```
10
9
8
7
6
5
4
3
2
1
1
10の階乗は 3628800
```

# 参考文献
https://employment.en-japan.com/engineerhub/entry/2017/07/10/110000
Dart(Flutter)における非同期処理入門(Firestoreのデータ取得サンプルつき）

こんにちは最近趣味でFlutterを書いている@glassmonkeyです。
今回は自分の勉強メモを兼ねて、Dartにおける非同期処理の書き方に関してまとめます。
おまけ程度ですが、それらを活用したFirestoreのデータの取得のサンプルも載せています。

間違ってたり、表現不足な内容などがありましたらぜひご指摘ください。

# Dartにおける非同期処理
パッケージ `dart:async`で定義されており、1.9から使える機能。
下記の２種類が存在します。
非同期で扱うデータが単数か、複数かで使い分けする形です。

* Future<T> (単体）
* Stream<T> (複数）

それぞれの使い方に関して説明します。

# Futureについて
いわゆる async/await。
FutureそのものはJSでいうところのPromiseなものだと私は認識している。（間違ってたらすみません）
メソッドにasyncキーワードを付与すれば、そのメソッドはFutureを意識せずに書けるのでとても見やすいです。
 個人的には値のマークアップは`型`より`Future<型>`としてたほうが非同期感がわかりやすくていいかなとは思います。(`void main()` は対比のためFutureをつけていません）

## 例

```dart

import 'dart:async';
Future<int> zero() async {
  return 0;
}

void main() async {
  print(zero()); // Instance of 'Future<int>'
  print(await zero()); // 0
}

```


awaitする場合はFuture処理系でないとだめなので注意。

```dart

import 'dart:async';
Future<int> zero() async {
  return 0;
}

//asyncを外してFuture処理系ではなくす。
void main() {
  print(await zero()); // Future処理系ではないのでawaitできない。
}

```

# Streamについて
Futureが単発の非同期データを扱うのならStreamは複数の非同期データを扱う方法です。例を先に見てもらったほうがわかりやすいです。


## 例

```dart

import 'dart:async';
Stream<int> countStream(int to) async* {
  for (int i = 1; i <= to; i++) {
    yield i;
  }
}

void main() {
  countStream(3).listen((value) => print(value)); 
} 

// 出力
// 1
// 2
// 3
```
`Future` が`async`キーワードを使ったものに対して `Stream` は`async *`を使います。
`yield 値`で値をストリームに流します。（*がついてて配列感あるのはポインタっぽい）

この例では引数で加えた値3をfor分で回して、3回ストリームに加えています。

```dart
for (int i = 1; i <= to; i++) {
    yield i;
  }
```

値の取り出しは

```dart

ストリーム.listen((値) => 処理);
```
で行っています。ジェネレータで与えられた値が都度流れてくるため、イベント駆動的な挙動が言語的にも組みやすくなっています。

返り値を同期的に扱いたいケースもあると思われます。その場合は`async`キーワードと組み合わせて`await for`を使うと良いです。

```dart

import 'dart:async';
Stream<int> countStream(int to) async* {
  for (int i = 1; i <= to; i++) {
    yield i;
  }
}

void main() async {
  await for (var value in countStream(3)) {
    print(value);
  }
}
// 出力
// 1
// 2
// 3
```
これらの内容はStreamの使い方の一端なので、詳細は[公式](https://dart.dev/tutorials/language/streams)をご確認ください。

# 応用(Firestoreからリストデータを取得)
上記の内容を使うとFirestoreのデータ取得処理を同期的扱うこともできます。

* Firestoreからデータを取得するをawait
(データ型Hogeは適当に読み替えてください）


``` dart
Future<List<Map<String, Dynamic>>> fetch () async {
  final Stream<List<Hoge>> stream = Firestore.instance
      .collection('コレクション名')
      .snapshots()
      .map((QuerySnapshot snapshot) {
    return snapshot.documents.map((DocumentSnapshot document) {
      return document.data; //Documentの実態。型はMap<String, Dynamic>なのでオブジェクトに変換したい場合はここで行うと良い。
    }).toList();
  });
  await for (var data in stream) {
    return data;
  }
}
```

このようにしておくと、awaitでデータを受け取れるようになります。
データを取得する箇所はstreamのままで扱うよりは、個人的にはこのほうが直感的で好みです。
テスト用のダミーも作りやすいですし。

```dart

final items = await fetch()

```


また、非同期処理用のビルダーの[StreamBuilder](https://api.flutter.dev/flutter/widgets/StreamBuilder-class.html), [FutureBuilder](https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html)と組み合わせると描画コストを抑えつつ非同期にウィジェットを扱うこともできます。（今回はFlutterを主題としてないので割愛します。）


# おわりに
実際はRxDartとか使うのと思うのでStreamを生で触る機会はあまりないのかもしれませんが、これらを知っておくとちょっとした非同期処理を書くときに便利かなと思います。

たまにFlutter（Dart）関係のことつぶやいていたりするので、[@glassmonekey](https://twitter.com/glassmonekey)をフォローしてくれると嬉しいです。
DVWA（weak-session-id）全レベルの脆弱性について

## 前提
- kali linux環境がある
- [DVWAのセットアップ済み](https://qiita.com/KPenguin/items/7e4f1c428c3dadf8591c)
- [初級レベル理解済み](https://qiita.com/KPenguin/items/d76fc4627fceb536724a)

## 目標
- 脆弱性の理解を深める。

## 手順概要
- 挙動を把握する
- コードを見て脆弱性を理解する

## 内容
###挙動の把握
### low
- generateした結果を以下に示す。
- 容易に推測できる。。。

```
session:1
session:2
session:3
etc...
```

### medium
- generateした結果を以下に示す。
- 取り合えず増えていることは分かる。
- [なんか見覚えある数字感だったのでjsでDate.now()してみた](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date/now)
- 1584113931674。。。オワタ

```
session:1584112966
session:1584112969
session:1584112974
etc...
```

### high
- generateした結果を以下に示す。
- やっと暗号化された。
- [暗号と言えばMD5なので逆変換してみる](https://hashtoolkit.com/decrypt-md5-hash/)
- 1,2,3...
- 一般人が変換できるMD5はもはや暗号ではない。。

```
session:c4ca4238a0b923820dcc509a6f75849b
session:c81e728d9d4c2f636f067f89cc14862c
session:eccbc87e4b5ce2fe28308fd9f2a7baf3

etc...
```

### コードを確認

#### low
```php:
<?php
    if (!isset ($_SESSION['last_session_id'])) {
        $_SESSION['last_session_id'] = 0;
    }
    $_SESSION['last_session_id']++;
    $cookie_value = $_SESSION['last_session_id']; 
?> 
```

#### medium

```php:
<?php
    $cookie_value = time();
    setcookie("dvwaSession", $cookie_value); 
?> 
```

#### high

```php:
<?php
    if (!isset ($_SESSION['last_session_id_high'])) {
        $_SESSION['last_session_id_high'] = 0;
    }
    $_SESSION['last_session_id_high']++;
    $cookie_value = md5($_SESSION['last_session_id_high']); 
?>
```

#### impossible
- sha1はMd5の4倍の長さがある暗号キー。とはいえ逆変換ツールはあるので完全ではない
- この場合、mt_rand()の全パターンを1秒間隔で送り込めば解読も不可能ではないが、一般人の悪ガキは諦めてくれるセキュリティはある
- 後、setcookieのsecureを有効にしている

```php:
<?php
$cookie_value = sha1(mt_rand() . time() . "Impossible"); 
setcookie("dvwaSession", $cookie_value, time()+3600, "/vulnerabilities/weak_id/", $_SERVER['HTTP_HOST'], true, true); 
?>
```
個人的に気に入ったXPの考え方・プラクティス

# エクストリームプログラミング 第二版を読んで
最近、原因は掴めないけどSprintが上手くいかないなぁと体感。
そこでプラクティスをいくつか知っているだけで、ちゃんと読んだことのなかった[エクストリームプログラミング](https://www.amazon.co.jp/%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%A0%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E3%82%B1%E3%83%B3%E3%83%88-%E3%83%99%E3%83%83%E3%82%AF/dp/4274217620/ref=asc_df_4274217620/?tag=jpgo-22&linkCode=df0&hvadid=295719984664&hvpos=&hvnetw=g&hvrand=15640897662947466806&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009308&hvtargid=pla-527007822636&psc=1&th=1&psc=1)を読んでみた。
結果としてSprintが上手くいく実感を掴めるようになったか、と言われるとよく分からない。が、チームで取り組んでみたいプラクティスや個人的に新しい発見があったので、備忘録として記録しておく。

### XPの価値
XPとは何か？という問いへの答えの中で最もアツい答えは
「XPとはソフトウェア開発で人間としての欲求を満たすことである」
という答え。
創造的で達成感のあるSprintを続けていけるようになるのが幸せだと非常に共感。
よく分からないゴールを立てて、どうすれば終わるのかも分からない作業をひたすら続けるSprintは本当に苦痛。

で、苦痛を避けるため、チームの目標を達成するためにXPが重要視している価値は
・ コミュニケーション
・ シンプリシティ
・ フィードバック
・ 勇気
・ リスペクト
と記載されている。

この中で個人的に意識していきたい価値は**シンプリシティ**、**フィードバック**。

・**シンプリシティ**: 書籍の後半にもシンプリシティに言及しているが、XPチームは問題に対して、できるだけシンプルな解決策を提案する。
コードを書かなくて良い解決策があるなら、それが最もシンプルな解決策かもしれない。
複雑な解決策はさらに別の問題を生み出す可能性すらある。
「シンプル」の定義が難しいな、と思ったが基準もしっかり記載されていた。

・設計を理解できるかどうか
・システムの要素が情報を正確に表現できているかどうか
・ロジックや構造に重複がないかどうか
・システムの要素が最小限かどうか

問題に対して、複雑なロジックを実装した経験は山ほどある。元来コードを書くのが好きなものだから、複雑な問題を複雑に解決することに尽力しがちな自分は心に刻んでおきたい価値と基準だと思った。

・**フィードバック**: フィードバックを早く多く得ることで、変化し続ける環境に適応していくことができる。
個人的にこの価値について重要視できていなかったな、と感じるのはフィードバックを得た後に舵を切り直すこと、環境の変化に目を向けること。
SprintPlannningで決めた方針はSprint2日目には最適な方針ではなくなっているかもしれない、ということに気付けなかったり、実際に仕事をすると当初見積もったコストを大幅に超える可能性があることをフィードバックとして得ているにも関わらず、リプランを行おうとしなかったり。


### 試してみたいプラクティス
・**ゆとり**: 開発チームはSprint中にゆとりを自発的に持つべきだと言っている。
そうすることでオーバーコミットはなくなる。
オーバーコミットがなくなれば、約束した価値を、約束した期限に顧客に届けられるようになる。
開発チームは顧客から信頼されるようになり、チームの士気は維持され、顧客との信頼関係は良好になる。

・**インクリメンタルな設計**: 毎日設計に手を入れること。
できるだけ早期に詰め込めるだけの柔軟で多様な設計を作り込むのとは真逆である。
日々のフィーチャーを追加する前に、設計を見直せばフィーチャーの実装は楽になる。
とにかく機能を追加することを急いで、設計の見直しを行わなければ1年後にはフィーチャーを追加することは今の何倍も難しくなっているはず。
ただ過剰に設計を毎日作りこめ、って話ではなく、あくまでフィーチャーを追加する直前にフィーチャーを追加するために必要な設計の見直しを行おうって話だと思う。

### 個人的に学びのあった考え方
・**制約理論**: 開発プロセスの改善箇所の発見の考え方。
システム開発プロセスにはどこかに制約があると考える。制約とは作業が山積みになっているところ。
その制約の負荷を下げたり、制約となっている作業の仕事量を増加させてあげるなりして、制約となっているところに仕事が山積みにならないようにする。
そうして制約が解消したら、次に最も仕事が山積みになっているところを解消しにいく。

・**設計(時間の重要性)**: 「インクリメンタルな設計」を日常化するための考え方。
経験を踏まえた時点が最も設計の品質が高い。何もわかっていない初期段階で設計書を想像で書いても、何一つ的中せず、不具合や無駄な複雑さを埋め込むだけ。
必要最小限の設計を繰り返すことにより、コストを抑えられる。
そして最も改善すべき設計は「重複」である。フィーチャー追加するたびに複数の同じロジックを修正することになれば、不具合は容易に発生する。


### 感想
プラクティスはなぜそれがプラクティス足り得るのかを理解することができる。
今後も価値、原則の章は忘れずにいたい。
価値、原則を常に念頭に、プラクティスを実践していくのみだなあと、認識した。
[原创漏洞通告]jackson-2653/jackson-databind JNDI注入导致远程代码执行

### 漏洞描述
近日,亚信安全网络攻防实验室跟踪到jackson-databind更新了jndi注入的黑名单类.如果在项目包中存在该类的jar包且JDK版本满足注入版本,则可以使用JNDI注入的方式导致远程代码执行.该类为`org.apache.shiro.jndi.JndiObjectFactory`.该漏洞为亚信安全安全研究员——`清水川崎`提交给fastxml官方.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/a037d26c-269e-ec80-99f9-6d6636552a44.png)

### 漏洞编号
Jackson内部编号2653

### 漏洞威胁等级
中危

### 不受影响范围
2.9.10.4

### 漏洞验证
这里选用2.10.3这个较新的版本
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/1e34bc22-73d7-a206-86c3-4fcdef9c6023.png)
fastjson同样受影响
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/10113a36-64e3-aadb-770e-ca5ec931635c.png)

### 修复建议
1.更新到最新版本
2.使用高版本JDK

### 时间轴
[0] 2020/03/09 亚信安全安全研究员——清水川崎提交该漏洞给fastxml官方
[1] 2020/03/11 fastxml官方关闭该漏洞
[1] 2020/03/13 亚信安全网络攻防实验室分析&复现该漏洞并发布漏洞通告

### Reference
https://github.com/FasterXML/jackson-databind/issues/2653
Google Cloud PlatformのCentOSでApacheを立ち上げるまで。

# 概要（TL;DR）

GCP(Google Cloud Platform)の無料リソースでWebページを表示するのに、ハマったので共有します。

# 前提条件

OSはCentOS7とします。


# httpdのインストール

どのページを見ても、下記のコマンドを実行すればTesting 123...が表示されると書いてある。

```
$ sudo yum install httpd
$ sudo systemctl httpd start
$ 
```

しかし、VMインスタンスの外部IPの横のリンク（下図）を押しても表示されない。ERR_CONNECTION_REFUSED。

<img width="759" alt="スクリーンショット 2020-03-14 0.06.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44112/c2a06933-0c9f-523b-0de7-fcb677c422a4.png">

# あっけない結論
上記のリンクから接続した場合は、**https**になっているのでアクセスできない。ブラウザのプロトコルを**http**に変更すれば表示される。ほんとにつまらない事で時間を使った。（CentOSなのでSELinux側の設定がいるのか？とか的外れな詮索をしてしまった。）
【今日のアブストラクト】 Dropout as a Bayesian Approximation: Representing Model Uncertainty in Deep Learning【論文 ほぼ Google 翻訳 自分用】

1 日 1 回 (努力目標) 論文の Abstract を Google 翻訳の力を借りて読んでいきます.

この記事は自分用のメモみたいなものです.
ほぼ Google 翻訳でお送りします.
間違いがあれば指摘していだだけると嬉しいです.

翻訳元
[Dropout as a Bayesian Approximation: Representing Model Uncertainty in Deep Learning](https://arxiv.org/abs/1506.02142)


# Abstract

### 訳文

ディープラーニングのツールは, 機械学習の応用において多大な注目を集めています. ただし, 回帰および分類のためのこのようなツールは, モデルの不確実性を捉えられていません. これに対して, ベイジアンモデルはモデルの不確実性を推論するための数学的に根拠のあるフレームワークを提供しますが, 通常, 計算コストが非常に高くなります. この論文では, ディープガウス過程における近似ベイズ推定として, ディープニューラルネットワーク (NNs) でドロップアウトトレーニングをキャスト (鋳造) する新しい理論的フレームワークを開発します. この理論の直接の結果は, ドロップアウト NNs – これまでに捨てられた既存のモデルから情報を抽出する, で不確実性をモデル化するツールの提供です. これにより, 計算の複雑さやテストの精度を犠牲にすることなく, ディープラーニングの不確実性を表す問題が緩和されます. ドロップアウトの不確実性の特性に関する広範な研究を実施しています. さまざまなネットワークアーキテクチャと非線形性が, MNIST を例として使用して, 回帰と分類のタスクで評価されます. 既存の最先端の方法と比較して, 予測対数尤度と RMSE の大幅な改善を示し, 深層強化学習におけるドロップアウトの不確実性を使用して終了します.


### 原文

Deep learning tools have gained tremendous attention in applied machine learning. However such tools for regression and classification do not capture model uncertainty. In comparison, Bayesian models offer a mathematically grounded framework to reason about model uncertainty, but usually come with a prohibitive computational cost. In this paper we develop a new theoretical framework casting dropout training in deep neural networks (NNs) as approximate Bayesian inference in deep Gaussian processes. A direct result of this theory gives us tools to model uncertainty with dropout NNs – extracting information from existing models that has been thrown away so far. This mitigates the problem of representing uncertainty in deep learning without sacrificing either computational complexity or test accuracy. We perform an extensive study of the properties of dropout's uncertainty. Various network architectures and non-linearities are assessed on tasks of regression and classification, using MNIST as an example. We show a considerable improvement in predictive log-likelihood and RMSE compared to existing state-of-the-art methods, and finish by using dropout's uncertainty in deep reinforcement learning.
がっつり開発するほどじゃないけどちょっとLaravelいじりたい時の環境構築

Laravel使ってるところに放り込まれたので軽く予習するために環境を作ったメモ。


```
macOS Catalina v10.15.3
Homebrew v2.2.9
```

## Composerインストール
```terminal
▶︎ brew install composer
▶︎ composer -V
Composer version 1.9.3
```

## PHPインストール
MacにプリインストールされているPHPを使ってると、このあとうまくいかなかったのでついでにPHPも入れる。
どのみち、[公式](https://laravel.com/docs/7.x)で**Homestead**を使わないなら`PHP >= 7.2.5`じゃないとだめって書いてあるのでアップデートの必要はあったっぽいが詳しくはわからない。

```terminal
▶︎ brew search php
==> Formulae
brew-php-switcher      php-cs-fixer           phplint                phpstan
php                    php@7.2                phpmd                  phpunit
php-code-sniffer       php@7.3                phpmyadmin
```

`brew install php`したら`v7.4.3`が入った。

## Laravelインストール
```terminal
▶︎ composer require "laravel/installer"
▶︎ laravel new ディレクトリ名
```

もしくは

```terminal
▶︎ composer create-project laravel/laravel ディレクトリ名
```

（どっちの方がいいとかあるのだろうか？）
#### バージョン確認

```terminal
▶︎ php artisan -V
Laravel Framework 7.0.8
```

## Hello World

#### コントローラー
```terminal
▶︎ php artisan make:controller SampleController
Controller created successfully.
```

```php:app/Http/Controllers/SampleController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class SampleController extends Controller
{
    public function sampleFunction()
    {
        $hello = 'Hello';
        return view('sample', ['h' => $hello, 'w' => 'World']);
    }
}
```

#### ビュー

```html:resources/views/sample.blade.php
<h1>{{ $h }} {{ $w }}</h1>
```

#### ルーティング

```php:routes/web.php
<?php

use Illuminate\Support\Facades\Route;

Route::get('/','SampleController@sampleFunction');
```

#### ローカルサーバー起動

```
▶︎ php artisan serve
Laravel development server started: http://127.0.0.1:8000
```

![HelloWorld](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125175/94b9c332-4a95-cedf-f58c-928967a71402.png)

`http://127.0.0.1:8000`にアクセスするとこんな感じ。

## TODO
* Bladeテンプレート
* artisanコマンド
* データベース関連
Qiitaの言語別記事数･フォロワー数ランキングをシェル芸で作る

今回はGithubの**シンタックスハイライト対応言語一覧**[^1]を使って,

- Qiitaでの**言語別記事数**と**タグフォロワー数**CSVを作成(2020年03月14日時点)
- ソートしランキングにする

ことを考える.

[^1]: https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml

# 結果

- 列名: `ランク,言語,記事数,フォロワー数`
- 全体の結果は[ここ]
  - 以下に示すのは結果を`head`したもの
[ここ]: https://gist.github.com/eggplants/8b78a265e71337df58a8461a16e9a3f5

## 記事数Top10[^2]

```csv:articleRank10.csv
ランク,言語,記事数,フォロワー数
001,Python,38538,71962
002,JavaScript,32653,72158
003,Ruby,26104,40486
004,PHP,19102,44786
005,Java,14326,47284
006,CSS,7329,46345
007,Cpp,7123,30398
008,HTML,6518,55321
009,Objective-C,4030,19990
010,Scala,3094,12501
```

## 読者数Top10[^3]

```csv:followRank10.csv
ランク,言語,記事数,フォロワー数
001,JavaScript,32653,72158
002,Python,38538,71962
003,HTML,6518,55321
004,Java,14326,47284
005,CSS,7329,46345
006,PHP,19102,44786
007,Ruby,26104,40486
008,Cpp,7123,30398
009,C#,3042,26228
010,Objective-C,4030,19990
```

[^2]: https://gist.github.com/eggplants/8b78a265e71337df58a8461a16e9a3f5#file-articlerank-csv
[^3]: https://gist.github.com/eggplants/8b78a265e71337df58a8461a16e9a3f5#file-followrank-csv

# 手段
2パートです.

## CSV作成パート

```bash:qiitaLangCSV
$ curl -s "https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml" |
egrep -o '^[^\ \#][^:]+' | sed '1d;y/+/p/'| while read i
    do echo "$i,$(
        curl -s "https://qiita.com/tags/${i,,}" |
        tr -d \\n | grep -oPm1 '(?<=<span class="tsi-Stats_count">)\d+'
    )" | tr \\n ,;echo
done | sed 's/\([0-9]\),$/\1/g' > result
```
## ランキング作成パート

- もし数値が同じであればもうひとつの数値で比較する
 
```bash:makeRank
$ head=ランク,言語,記事数,フォロワー数
$ (echo $head;sort -t, -rnk2 -rnk3 result | nl -nrz -s, -w3 | head) > articleRank10.csv
$ (echo $head;sort -t, -rnk3 -rnk2 result | nl -nrz -s, -w3 | head) > followRank10.csv
```

# ちなみに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278919/cce24c96-ceb3-483e-444e-8f474be68c3d.png)



- タグがない言語は**全545言語中40%**の**218言語**

```bash:Terminal
$ cat result | tee >(wc -l) >(grep -c ",,") 1>/dev/null | nl -nln
1       218
2       545
$ cat result | tee >(wc -l) >(grep -c ",,") 1>/dev/null |
  tr \\n / | sed 's/^/scale=1;/;s/.$/*100\n/' | bc
40.0
```

- タグはあるが記事もフォロワーもいない言語は**15言語**

```bash:Terminal
$ grep ",0,0" result
CSON,0,0
CWeb,0,0
Cool,0,0
Eiffel,0,0
Fancy,0,0
Harbour,0,0
Jison,0,0
Jolie,0,0
Nit,0,0
Nu,0,0
Raku,0,0
STON,0,0
Tea,0,0
UrWeb,0,0
XC,0,0
$ grep -c ",0,0" result
15
```

- タグはあり記事もあるがフォロワーがいない言語は**64言語**

```bash:Terminal
$ grep -P '(?<!,0),0$' result | head
ABNF,1,0
APL,27,0
ASN.1,5,0
ApacheConf,1,0
Batchfile,2,0
Befunge,1,0
CLIPS,2,0
COLLADA,5,0
Chapel,2,0
Cycript,2,0
$ grep -cP '(?<!,0),0$' result
64
```

- タグはあり記事はないがフォロワーがいる言語は**0言語**

```bash:Terminal
$ grep -P ',0,[^0]+$' result
$ grep -cP ',0,[^0]+$' result
0
```

- タグがあり記事もフォロワーもいる言語は**248言語**

```bash:Terminal
$ grep -vP ',0?(,|$)' result | head
4D,5,3
ABAP,46,34
ANTLR,12,7
ASP,43,14
ATS,35,2
ActionScript,249,247
Ada,27,10
Agda,29,18
Alloy,59,26
AngelScript,5,1
$ grep -vPc ',0?(,|$)' result
248
```
インフラエンジニアとは

一通り基本情報の投稿もし終わって
少し今までのことを振り返ろうと思い
色々投稿していきます。

# インフラとは
「インフラ」とは、インフラストラクチャー（Infrastructure）の略語で
「基盤」、「下部構造」などの意味があります。

例えば生活インフラ(基盤)に当たるのが
電気、ガス、水道といえばわかりやすいです。


# インフラエンジニアとは
アプリやwebページなどフロントエンドなどの前面を担当するとは逆に
バックエンド側、サーバやOS裏方の業務を扱うことになります。

インフラ基盤に従事する人がインフラエンジニアと呼ばれます
インフラエンジニアの種類をあげると

* ネットワークエンジニア
* セキュリティエンジニア
* サーバーエンジニア
* データベースエンジニア

となり、他にもクラウドやカスタマーなど多岐に渡ります。

## ネットワークエンジニア
仕事は、ネットワークの設計から要件定義、構築、保守・監視、運用など多岐にわたりますが、大きく次の4つに分類することができます。

1.ネットワーク設計

クライアントからヒアリングし、要件をまとめて設計します。
ネットワークの構成や使用するネットワーク機器（ルーターなど）の種類・数
使用回線などを決め。維持コストや構築までのスケジュールもここで検討します。

2.ネットワーク構築

スケジュールに基づき、実際にネットワーク機器を設置し設定していきます。
数ヵ月かかる場合もあり、構築後はテストを行った後、運用開始となります。

3.ネットワーク運用

随時機器の設定変更や構成変更などを行う必要があります。
立ち上げたネットワークに手を加えて運用を助けるのも、ネットワークエンジニアの仕事のひとつです。

4.ネットワーク保守

円滑なネットワークを維持するのも、ネットワークエンジニアの重要な仕事です。


## セキュリティエンジニア

サーバーに関連する業務や情報セキュリティを専門に担当するエンジニアのことです。

サーバーの構築や運用・保守を専門とし
セキュリティに配慮したシステム設計・運用
サイバー攻撃を防ぐための調査や対策などを行います。

## サーバーエンジニア

サーバーを、ゼロから構築・設計し、管理保守をするのが「サーバーエンジニア」の仕事です。
仕事は、構築業務と保守業務に分かれます。

サーバーエンジニアの仕事で必要になるのは、「OS」に関する知識です。
「Windows Server」「Mac OS」「Linux」「UNIX」といったOSについて知識が必要で
どれかひとつだけではなく、どのOSに対しても広く知識を習得していることが望まれます。

## データベースエンジニア

データベースの開発・設計、もしくは運用・管理を行うエンジニアの総称です。
使用される技術としては
Oracleや Microsoft SQL Serverなど、データベース製品が知られています。

# インフラエンジニアの業務

インフラエンジニアは、ITインフラを設計・構築し、それらが問題なく動くための運用・保守を行います。

快適なIT環境を提供するための業務ですが、詳しく分類すると以下の通りとなります。

## 要件定義
　お客様の希望をヒアリングして、どのようなITインフラを作成するかを決定する。

## 設計
　どの機器を用いて、どのような構成および設定値にするかなどを決定する。
　稼働した後にどのような取り決めで運用していくかも合わせて検討する。

## 構築
　機器を調達して実際に接続などの構築を行う。

## テスト
　設計書通りに問題なく動作するかのチェックを行う。

## 運用保守
　正常に動作しているかを監視し、障害が発生した場合にはトラブルシューティングを行う。

# インフラエンジニアの資格
内容にしても営業にしても注目を浴びる資格を上げます。
基本的な資格やかなり注目される資格を先んじて上げます。
派生する資格も多くあるので、参考程度に見てください。

## 基本情報処理技術者
基礎的なITスキルからプログラミング、ネットワーク、データベース、セキュリティや経営戦略など
ITエンジニアとして身に着けておきたい幅広い分野を万遍なく学ぶことができます。

## Linux技術者認定 LinuC
LinuC（リナック）は、特定非営利活動法人LPI-Japanが開発管理するLinux技術者試験です。
レベル１は最もエントリーレベルとなっており、インフラエンジニアの中でも、サーバー系の資格です。

## シスコ技術者認定 CCNA
スコシステムズ社が実施するCisco技術者認定試験の一つです。
ネットワークに関する基礎知識も合わせて学べることから、ネットワークエンジニアの登竜門とも言われています。

## 応用情報処理技術者
基本情報処理技術者試験の上位資格に位置づけられ、問われる内容もより高度なものとなっています。

## ネットワークスペシャリスト
基本情報処理技術者や応用情報技術者の試験範囲が非常に広範囲であるのに対し
ネットワークスペシャリストは文字通り、ネットワーク技術に特化した内容となっています。

## データベーススペシャリスト
応用情報技術者の上位に位置づけられ、データベースに関する専門知識が必要となります。
[漏洞通告]CVE-2020-0796/微软SMBv3协议远程代码执行漏洞

### 漏洞描述
2020年3月12日,微软更新安全通告针对Windows SMBv3客户端/服务器远程代码执行漏洞紧急发布了安全补丁.`Microsoft Server Message Block 3.1.1(SMBv3)`协议在处理某些请求的方式中存在代码执行漏洞.攻击者可以以未授权的方式精心构造数据包发送到SMB服务器,即可在目标服务器上执行任意代码,严重威胁服务器安全.该漏洞与`MS17-010「永恒之蓝」`漏洞较为相似.目前该漏洞相关细节已公开,请广大客户及时安装系统补丁.


### 漏洞编号
CVE-2020-0796

### 漏洞威胁等级
高危

### 影响范围
Windows 10 Version 1903 for 32-bit Systems
Windows 10 Version 1903 for ARM64-based Systems
Windows 10 Version 1903 for x64-based Systems
Windows 10 Version 1909 for 32-bit Systems
Windows 10 Version 1909 for ARM64-based Systems
Windows 10 Version 1909 for x64-based Systems
Windows Server, version 1903 (Server Core installation)
Windows Server, version 1909 (Server Core installation)

### 漏洞验证
可以根据网上公开的脚本进行自查
Python版
https://github.com/ollypwn/SMBGhost/blob/master/scanner.py
Nmap检测脚本(nse脚本)
https://github.com/cyberstruggle/DeltaGroup/blob/master/CVE-2020-0796/CVE-2020-0796.nse
Powershell检测脚本
https://github.com/T13nn3s/CVE-2020-0976/blob/master/CVE-2020-0796-Smbv3-checker.ps1

### 修复建议
1.安装相应补丁
2.禁用SMBv3压缩
2.1 使用以下PowerShell命令禁用压缩功能，以阻止未经身份验证的攻击者利用SMBv3 服务器的漏洞.
`Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" DisableCompression -Type DWORD -Value 1 -Force`
2.2 用户可通过以下PowerShell命令撤销禁用压缩功能
`Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" DisableCompression -Type DWORD -Value 0 -Force`

### 时间轴
[0] 2020/03/12 微软更新安全通告
[1] 2020/03/13 亚信安全网络攻防实验室发布漏洞通告

### Reference
https://catalog.update.microsoft.com/v7/site/Search.aspx?q=KB4551762
GitHubで特定のコミットまで遡って、それ以降のCommitを取り消す

#始めに
僕は普段からローカルの環境でAtCoderの問題を解いていて、定期的にGitHubに上げるようにしています。ただ、リポジトリ名が"AtCoder"と、AtCoder専用みたいになっちゃってたので、ローカルのAtCoderリポジトリの上に新しく"CompatitionProgramming"という親リポジトリを作って、それをGutHubにpushしました。が、その際に今まで解いてきた問題の**全ての**コミットメッセージが同じコミットメッセージになってしまい、「これは嫌だ…」になってしまいました。`git reset`などのコマンドでローカルのコミットは元に戻せましたが、GitHub上のCommitは以下のようにして修正しました。

#GitHubブラウザ上のCommitを消す
至って簡単でした。まずGitHub上のCommit一覧を見て、そこまで遡りたいCommitをクリックします。

550521b0a6540b87b5edf6be2edad2ab15a2afac

そして右側にあるこんな⇑感じの文字列をコピーした後、こいつを以下のコマンドと共にぶっ叩きます。

```
git push -f origin 550521b0a6540b87b5edf6be2edad2ab15a2afac:master
```

右側の`:master`を忘れないで下さい。これを叩くと、GitHubの対象リポジトリまでのCommitが全て消えると思います。そこからローカルにCommitして誤ミットは万事解決です！~~コミット、ヨシ！~~

#参考
Gitで誤ってpushしてしまったときのpushの取り消し方法
https://awesome-linus.com/2019/03/09/git-push-by-mistake/
Wordpressでプラグインを使わずカスタムタクソノミーを追加する方法

## カテゴリーのような階層のあるタクソノミーを作る
- functions.phpに以下の関数を追記
- カテゴリーのような階層化されたタクソノミーを作るには`hierarchical`をtrueにする
- 保存してブラウザ再読み込みすると、指定した投稿タイプにタクソノミーが追加されてる
- 各オプションについてはcodex参照
[register_taxonomy()](https://developer.wordpress.org/reference/functions/register_taxonomy/)

```php
function create_topics_taxonomy() {
  $args = array(
    'hierarchical' => true, // ここをtrueにすることでカテゴリーっぽいタクソノミーを作れる
    'labels' => array(
      'name' => __( 'トピックス' ),
      'singular_name' => __( 'トピックス' ),
    ),
    'show_ui' => true,
    'show_admin_column' => true,
    'query_var' => true,
    'rewrite' => array( 'slug' => 'topic' ),
  );
  // タクソノミー名、投稿タイプ（複数可）、オプション
  register_taxonomy('topics',array('post'), $args);
  // 投稿タイプをproductsにする場合
  // register_taxonomy('keywords','products', $args);
}
add_action( 'init', 'create_topics_taxonomy', 0 );
```

## タグのようなタクソノミーを作る
- タグのようなタクソノミーを追加するには`hierarchical`をfalseにするだけでOK
- カスタム投稿タイプに対してタクソノミーを作成するには`register_taxonomy()`のパラメータの２つ目に指定するだけ

```php
function create_keyword_taxonomy() {
  $args =　array(
    'hierarchical' => false,
    'labels' => array(
      'name' => __( 'キーワード' ),
      'singular_name' => __( 'キーワード' ),
    ),
    'show_ui' => true,
    'show_admin_column' => true,
    'query_var' => true,
    'rewrite' => array( 'slug' => 'keyword' ),
  );
  // タクソノミー名、投稿タイプ（複数可）、オプション
  register_taxonomy('keywords',array('post'), $args);
  // 投稿タイプをproductsにする場合
  // register_taxonomy('keywords','products', $args);
}
add_action( 'init', 'create_keyword_taxonomy', 0 );
```

## カスタムタクソノミーの記事一覧を表示する方法
- カスタムタクソノミー用のテンプレートはこちら
- とくに分ける必要がなければ`archive.php`のみでOK

```php
// タクソノミーの特定の要素
taxonomy-{taxonomy}-{term}.php
taxonomy-topics-event.php

// タクソノミー全体
taxonomy-{taxonomy}.php
taxonomy-topics.php
```
Go言語初心者が「Go言語によるWebアプリケーション開発」を読みながら開発してみた

# はじめに
**「Go言語によるWebアプリケーション開発」**という本はオライリー社から出版されている技術書です。

Webアプリケーション開発をする機会があったので、

<font color=red> **「せっかくならGo言語使ってやってみっか！」**</font>
ということで「Go言語によるWebアプリケーション開発」を読みながら開発しました ~~（現在進行中）~~

今回はその**感想**だったりつまづいたところ等を紹介できればなと思います。

## 2020/04/10第二章更新
---

購入ページ ：[amazon](https://www.amazon.co.jp/Go%E8%A8%80%E8%AA%9E%E3%81%AB%E3%82%88%E3%82%8BWeb%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA-Mat-Ryer/dp/4873117526/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=%E3%80%8CGo%E8%A8%80%E8%AA%9E%E3%81%AB%E3%82%88%E3%82%8BWeb%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA%E3%80%8D&qid=1583089451&sr=8-1)

作成したコードをちょくちょくGithubにもあげているので参考にどうぞ
[Github](https://github.com/marnysan111/Golang_web)

---

## 1章 WebScketを使ったチャットアプリケーション
- つまづいた点  
① **1.3でのチャットアプリケーションとして動作させる際、チャットを送信してもなにも反映されない**<br>
②**1.4.1.4にて、go test -coverの結果が本と異なる**
- 解決法<br>
①単に誤字でした。場所はchat.htmlのJavaScriptの部分です。コンパイルできた時点でGoのほうに問題がない（確実ではないが）と考えられるので、Webがみえない→Goのせい、チャットができない→htmlのせい、っていう考えでいいかなと<br>
②こちらも誤字。HandlerなのかHeadなのか、その辺がごっちゃになるので注意。<br>
あと、GOPATHの設定で理解できてないと結構きついかなと思いました
- 感想<br>
    - この本で開発をする前、予習の意味を込めて[A Tour of Go](https://go-tour-jp.appspot.com/welcome/1)や[Go Webプログラミング](https://astaxie.gitbooks.io/build-web-application-with-golang/ja/)にて勉強しましたが、個人的には結構難しい内容だったかなと思います。プログラミングが得意ではないというのもありますが、一章を終えるのにも結構な時間を消費してしまいました。でも、チャットができて、そのログがターミナルにて表示されるのをみると結構感動できましたw


## 2章 認証機能の追加
- つまづいた点  
①Gomniauthの実装(そもそもインストールができなかった)
- 解決法  
①本にあったように「Bazaar」のインストールが必要なのか、本に載っているコマンドがちがうのか…  
実際わからないが、僕は、Bazzarインストールし、Gomniauthのgithubにあったコマンドを実行しました
- 感想  
①OAuth2を用いて、google,github,facebookのアカウントでログインできるようになり、感動した

## まとめ
- とりあえず、第二章まで演習をしてある程度のGoの書き方を学んでみました。のちにGoを使った開発をしましたが、本書以外にネットで調べていくと、ソースコードの構成が全く違ったりするんで、なんともって感じですね。まぁやった分成長できたのは事実ですが。

では、
【rails】複数チェックボックス選択によるAND条件検索を実装してみた（サーバサイド）

# what
メモアプリで、メモに紐づくタグを複数選択することにより、AND条件で検索できるようにした。
# why
メモの数が膨大になっても探せないメモはない説浮上のため。

--------------------------------------------------------------
#### 前提条件

・rails 5.2.4.1
・メモアプリで、メモに紐づくタグをチェックボックスで選択し、絞り込み検索を実装する。
・メモとタグのモデルは多対多。
・メモモデルとタグモデルの中間テーブルは、tag_memo

--------------------------------------------------------------

### ビュー（チェックボックス）

次の通り実装

  【rails】チェックボックスを使ったAND条件による検索
  　https://qiita.com/igat/items/dc35d42889580026bb4d

### サーバサイド

##### コントローラ

```app/controllers/tags_controller.rb
           ...
  def search
    begin
      selected_tag_ids = selected_tags_params # Tag id array checked with form.
      filtered_memo_ids = Memo.filter(selected_tag_ids) # Memo id array filtered with checked tag by And condition.
      @memos = Memo.where(id: filtered_memo_ids) # Memos instance selected with filtered memo ids.
    rescue
      redirect_to root_path
    end
  end
           ...
  private
  def selected_tags_params
    params.require(:tag_ids)
  end

```

1. tagsコントローラのsearchアクションは、選択されたチェックボックスの値（タグid）を、ストロングパラメータから配列で受け取る。

2. tagsコントローラのsearchアクションは、配列で渡されたタグIDをタグメモモデル（中間テーブル）のメソッド「filter」に渡す。

3. メソッド「filter」は選択された複数のチェックボックスに紐づくメモIDをAND条件で返す。


#####メソッド「filter」

```app/models/tag_memo.rb
  def self.filter(selected_tag_ids) # Tag id array checked with form.
    selected_memo_ids = TagMemo.where(tag_id: selected_tag_ids).pluck(:memo_id).uniq.sort # Memo id array associated to checked tag.
    return Memo.all unless selected_tag_ids 
    memo_filtered = [] # Memo id array associated to all tags checked with form.
    selected_memo_ids.each do |id|
      loop_count = 0
      while selected_tag_ids.length > loop_count do
        break unless Memo.includes(:tags).find(id).tags.pluck(:id).include?(selected_tag_ids[loop_count].to_i)
        loop_count += 1; # Get memo id that associated tag id is equall to all tag id selected.
      end
      memo_filtered << id if loop_count == selected_tag_ids.length
    end
    return memo_filtered
  end
```

1. タグメモモデルに定義したメソッド「filter」は、引数のタグIDに紐づくメモIDを配列で取得する。
 (selected_memo_ids = ...)
2. 取得したメモIDの配列に格納された各メモIDについて、選択されたタグIDが紐づくかチェックする。
 (break unless Memo.includes(:tags).find(id)...)
3. チェックを通過したメモIDのみ配列で取得する。
 (memo_filtered << id if ...)


もっとスマートな方法があるかな。。。
Kernel#forkのサンプルメモ

# メモ

> fork(2) システムコールを使ってプロセスの複製を作ります
> ブロックを指定して呼び出した場合には、生成した子プロセスでブロックを評価します。
https://docs.ruby-lang.org/ja/latest/method/Kernel/m/fork.html


```ruby:fork.rb
i = 10
puts "object_id: #{i.object_id}" #=> 21

3.times do
  fork do
    puts "object_id: #{i.object_id}" #=> 21 (ObjectIDは親プロセスの時の値と変わらない)
    i += 1
    puts i # => 常に11(元々の親プロセスの10が引き継がれる)
  end
end

Process.waitall # すべての子プロセス終了まで待つ
puts "end: #{i}" # => end: 10 (子プロセスのインクリメントは影響されない)
```

```ruby:実行結果
 % ruby fork.rb     
object_id: 21
object_id: 21
11
object_id: 21
11
object_id: 21
11
end: 10
```

## Thread オブジェクトの場合

Threadオブジェクトも複製されて `Thread.current` や object_id は親プロセスと子プロセスとで同じものが参照されるが、OSレベルでスレッドIDを確認するとちゃんと別々のが確認できる。
参考: [【Ruby】スレッドID(tid)を表示する](https://qiita.com/kure/items/c8ef555ab9152905edfa)

```ruby
puts Thread.current # => #<Thread:0x0000565035403310 run>
puts syscall(186) #=> 24837

fork do
  puts Thread.current # => #<Thread:0x0000565035403310 run>
  puts syscall(186) # => 24891
end
```

ちなみにThread.currentで子プロセスで値を代入しても、もちろん親では参照できない。

```ruby
Thread.current[:hoge] = "hoge"

fork do
  puts Thread.current[:hoge] # => hoge (親のが複製)
  Thread.current[:hoge] = "hoge2"
end

Process.waitall
puts Thread.current[:hoge] # => hoge (子の影響は受けない)
```

# 参考
なるほどUnixプロセス ― Rubyで学ぶUnixの基礎 - 達人出版会 
https://tatsu-zine.com/books/naruhounix
Hexo × GitHub Pagesでカスタムドメインをつける

Hexoでは、ビルドの際に`sources`内の`.md`以外のファイルはそのまま`public`ディレクトリにコピーされます。

これを利用して、GitHub Pagesでカスタムドメインを設定するときに必要な`CNAME`ファイルを`sources`直下に追加します。

```text:sources/CNAME
custom.domain.com
```

あとは、普通にデプロイすれば、`public`直下に`CNAME`ファイルがコピーされます。

これで、GitHub Pagesのカスタムドメインの設定を維持することができます。