OmniAICreator/Qiita-1.07M huggingface dataset:
【PHP】プルダウンで設定した項目をselectedにするサンプル


##はじめに
[恐竜登録ツール2](https://qiita.com/knowledge87sun/items/36cb41d73e33e96bf256)
で、ハイブリッド恐竜を登録するときに、生成元恐竜タイプを別ページに送信した後、
前ページのタイプに該当恐竜名を選択する手法をとっていたけど、面倒くさい。

__タイプとそれに応じた恐竜名を一度に確定したいと考えていた。
そこで疑似的な連動プルダウンを考えてみたのだ__

1つ目の、2つ目のプルダウンともに、DBのSELECT結果を利用。
1つ目のプルダウンの選択項目(normal,rare,epic,legend)を決定(確定ボタン押下後)
後に、その項目にあった内容を2つ目のプルダウンの項目を出してみた。
下記のソースのポイントは、
__\$cate0と$select_data['type0']を比較している部分__
(※$cate0は1つ目のプルダウンで確定した項目)



##ソース
[恐竜登録ツール2](https://qiita.com/knowledge87sun/items/36cb41d73e33e96bf256)
で作成したテーブルや、ソースを一部流用。

```php:select_pulldown_dino.php
<!DOCTYPE html>
<html lang="ja">
<meta charset="utf-8">
<title>恐竜タイプ選択1</title>
<h1>恐竜タイプ選択</h1>

<body>

<?php 
    require "common_dino.php";
    $db_name='dino_collect.db';
    $db1 = new PDO('sqlite:'.$db_name);
    $query_type0 = "SELECT DISTINCT type0 from tbl_dino";
 ?>
    <form action="select_pulldown_dino.php" method="post">
カテゴリー:
    <?php $result_a=get_AllData($db1,$query_type0); 
    $cate0=isset($_POST['dtype0'])?htmlspecialchars($_POST['dtype0']):null;

     ?> 
    <select name="dtype0">
        <?php while($select_data=$result_a->fetch(PDO::FETCH_ASSOC)){
            //$cate0が$select_data['type0']と等しい場合
            if($cate0 == $select_data['type0']){ 
                echo "<option selected>".$select_data['type0']."</option>";
            //$cate0が$select_data['type0']と等しくない場合
            }else{
                echo "<option>".$select_data['type0']."</option>";
            }
        }   
        ?>
    </select><br>
    <input type="submit" name = "btn2" value="確定">
    </form>


<?php 
    $db_name='dino_collect.db';
    $db1 = new PDO('sqlite:'.$db_name);
    $query_select_type0 = "SELECT dname0 from tbl_dino where type0 = ?";
    $result3=$db1->prepare($query_select_type0);
    //パラメータをセット
    $result3->bindparam(1,$cate0);
    $result3->execute();

 ?>

    <form action="select_pulldown_dino.php" method="post">
対象生物：
    <select name="dname">
        <?php $dino0=isset($_POST['dname'])?htmlspecialchars($_POST['dname']):null; ?>
        <?php while($select_data=$result3->fetch(PDO::FETCH_ASSOC)){
            echo "<option>".$select_data['dname0']."</option>";
        }   
        ?>
    </select><br>
    <input type="hidden" name="btn3" value="<?=$cate0?>">
    <input type="submit" value="確定">
    </form>

<?php 
    $cate0=isset($_POST['btn3'])?htmlspecialchars($_POST['btn3']):null;
    if(empty($dino0) == false && empty($cate0)== false){
        print $dino0.",".$cate0;
    }

 ?>

```
##実行結果
カテゴリーを選択後、「確定」を押すと、選択したカテゴリーが表示され、
選択カテゴリーに含まれる恐竜がプルダウンに表示される。

![dino_2pulldown.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494408/5c9a0a2c-656b-015c-ab25-883841ae0839.jpeg)

###最後に

javascriptとかだと、複数プルダウンの連動とか簡単そうなんだけど、
phpのみで実装するのは面倒なのか、私の技術力不足なのか。
いい方法ないでしょうか。

全部取得できないことが判明したので修正
Q7.別のワークシートにセルの値をコピーするには？①

今回は別のワークシートに情報をコピーするテクニックを考えていきます。

以下のように、各個人のシートが作成されており、国語、数学、英語の点数が記載されています。
これを１つのシートに集約していくというマクロです。


![Q7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/f0060bd4-f8d8-3c17-5f90-751d12291638.png)



![7-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/558604dc-e63e-2092-608c-e5963320c847.png)


![7-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/d81e67d9-d81e-6847-3bce-62232bcd943f.png)






最終的に集約させるシートはこちらです。

![Q7-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/ba09ae1f-d196-3557-7465-15bd02b5b020.png)




###■ポイント
今回の作成のポイントは、他のシートの情報をどのように参照するかとなります。
例えば、Range("C3").valueという記述では、アクティブなワークシートの情報を取得することになります。

 Worksheets("田中").Range("C3").valueとすると、田中シートにあるC3セルの値を、
取得することができます。
ワークシートはこのまま直接名前を指定することもできますし、
Worksheets(1)といったインデックス番号で指定することもできます。
インデックスは左から1から順番に割り振られています。

田中シートは左から3番目にあるので、
Worksheets(3).Range("C3").valueと記述しても同じことになります。


ただし、インデックス番号で指定する場合は、シートの順番が変われば
番号も変わりますので、その点はご注意を。



###■回答
```VB
Sub Q7_Answer()
    Worksheets("全体").Range("B3").Value = Worksheets("田中").Range("B3").Value
    Worksheets("全体").Range("B4").Value = Worksheets("高橋").Range("B3").Value
    Worksheets("全体").Range("B5").Value = Worksheets("山田").Range("B3").Value
    Worksheets("全体").Range("C3").Value = Worksheets("田中").Range("C3").Value
    Worksheets("全体").Range("C4").Value = Worksheets("高橋").Range("C3").Value
    Worksheets("全体").Range("C5").Value = Worksheets("山田").Range("C3").Value
    Worksheets("全体").Range("D3").Value = Worksheets("田中").Range("D3").Value
    Worksheets("全体").Range("D4").Value = Worksheets("高橋").Range("D3").Value
    Worksheets("全体").Range("D5").Value = Worksheets("山田").Range("D3").Value
    Worksheets("全体").Range("E3").Value = Worksheets("田中").Range("E3").Value
    Worksheets("全体").Range("E4").Value = Worksheets("高橋").Range("E3").Value
    Worksheets("全体").Range("E5").Value = Worksheets("山田").Range("E3").Value
End Sub
```


###■解説
解説もクソもありません。たた、単純にコピーしただけのマクロです。

もちろん、これはいい例ではありません。
ただ、これでも今回の目的は達成されているわけなんですね。

そこで、次に考えるべきは、拡張性です。
同じように100人分のデータがあったとき、効率の違いが如実に現れます。
ただし、このように少ないデータの場合は、行数としてはそこまで変わらないんですね。

ループ処理を取り入れることによって、もっと効率的に記述することができるようになります。
効率的に記述できれば、3人だろうと、100人だろうと行数はそこまで変わりません。

次回それらへんを取り扱っていこうと思います。


それでは、最後の今回の結果を載せておきます。

![7-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560479/2b81c2d8-6ce3-28b0-e579-67617b0c1a93.png)
Confluent Kafkaのインストール方法（シングル構成：Local mode）


## 目的

シングル構成のConfluent-Kafkaのインストール方法について、本投稿で解説します。Confluent PlatformはConfluent社が提供するApache Kafkaを中心としたプラットフォームです。Apache Kafkaに加えて、運用ツール等が同梱されています。



## 手順

[Confluent社のHP](https://docs.confluent.io/5.3.1/installation/installing_cp/index.html#zip-and-tar-archives)を参照して、対象となるマシンにダウンロードを実施。この投稿では、AWS Linux 2を使用していたため、RHELのインストール手順を参照しました。
Confluentのパッケージでは、localモードと呼ばれる開発用のスタンドアローンで動作するモードが存在します。今回は機能検証を行うことを目的としてConfluent kafkaをインストールしたので、localモードで構築します。
localモードについての詳細は、[Confluent社のHP](https://docs.confluent.io/current/cli/command-reference/confluent-local/confluent_local_start.html)を参照してください。


Javaをインストールする。

```
yum install java-1.8.0-openjdk-devel
```

環境変数の設定を行う。

```
echo "export JAVA_HOME=$(readlink -e $(which java)|sed 's:/bin/java::')" > /etc/profile.d/java.sh
echo "PATH=\$PATH:\$JAVA_HOME/bin" >> /etc/profile.d/java.sh
source /etc/profile
```

Install the Confluent Platform public key. This key is used to sign packages in the YUM repository.

```
sudo rpm --import https://packages.confluent.io/rpm/5.3/archive.key
```
Navigate to /etc/yum.repos.d/ and create a file named confluent.repo with these contents. This adds the Confluent repository

```
[Confluent.dist]
name=Confluent repository (dist)
baseurl=https://packages.confluent.io/rpm/5.3/7
gpgcheck=1
gpgkey=https://packages.confluent.io/rpm/5.3/archive.key
enabled=1

[Confluent]
name=Confluent repository
baseurl=https://packages.confluent.io/rpm/5.3
gpgcheck=1
gpgkey=https://packages.confluent.io/rpm/5.3/archive.key
enabled=1
```

Clear the YUM caches and install Confluent Platform.

```
sudo yum clean all && sudo yum install confluent-platform-2.12
```

スタンドアローンで動作させる際に使用するconfluent localコマンドを利用するため、Confluent CLIをインストールします。

```
curl -L https://cnfl.io/cli | sh -s -- -b /opt/confluent-5.3.1/bin
```

Confluent binディレクトリのインストール場所をPATHに追加します。

```
echo "export PATH=/opt/confluent-5.3.1/bin:$PATH" >> /etc/profile.d/confluent.sh
source /etc/profile
```

confluent local startコマンドを使用してConfluent Platformを起動します。
このコマンドにより、Kafkaだけではなく、Kafka Connect、KSQLなどの全てのConfluent Platformのコンポーネントが起動します。

```
confluent local start
    The local commands are intended for a single-node development environment
    only, NOT for production usage. https://docs.confluent.io/current/cli/index.html

Using CONFLUENT_CURRENT: /tmp/confluent.rrEB8cE3
Starting zookeeper
zookeeper is [UP]
Starting kafka
kafka is [UP]
Starting schema-registry
schema-registry is [UP]
Starting kafka-rest
kafka-rest is [UP]
Starting connect
connect is [UP]
Starting ksql-server
ksql-server is [UP]
Starting control-center
control-center is [UP]
```
pythonのスクレイピング(requests)でエラーが出た時




#[Errno 11001]について
社内でpythonを使ってスクレイピングしようとしたとき、[Errno 11001]が出た。

プロキシ指定を行うと解決。



```py
import requests
from bs4 import BeautifulSoup

proxies = {
'http': 'http://123.45.678.000:0000',
'https': 'http://123.45.678.000:0000',
}

url = 'https://ja.wikipedia.org/wiki/Python'
res = requests.get(url, verify=False, proxies=proxies)
soup = BeautifulSoup(res.text)

soup
```


```
<!DOCTYPE html>
<html class="client-nojs" dir="ltr" lang="ja">
<head>
<meta charset="utf-8"/>
<title>Python - Wikipedia</title>
<script>document.documentElement.className="client-js";RLCONF={"wgBreakFrames":!1,"wgSeparatorTransformTable":["",""],"wgDigitTransformTable":["",""],"wgDefaultDateFormat":"ja","wgMonthNames":["","1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],"wgMonthNamesShort":["","1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],"wgRequestId":"XhwEyQpAICIAABeLnhMAAADL","wgCSPNonce":!1,"wgCanonicalNamespace":"","wgCanonicalSpecialPageName":!1,"wgNamespaceNumber":0,"wgPageName":"Python","wgTitle":"Python","wgCurRevisionId":75653560,"wgRevisionId":75653560,"wgArticleId":993,"wgIsArticle":!0,"wgIsRedirect":!1,"wgAction":"view","wgUserName":null,"wgUserGroups":["*"],"wgCategories":["無効な出典が含まれている記事/2018年","オブジェクト指向言語","スクリプト言語","オープンソースソフトウェア","Python","基本情報技術者試験"],"wgPageContentLanguage":"ja","wgPageContentModel":

・・・
```
初心者によるプログラミング学習ログ 210日目

#100日チャレンジの210日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

210日目は

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>210日目<br><br>udemyでRuby、javascript<br><br>前にRubyの環境構築やっておいたからよかった<a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a> <a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a> <a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1216814776640126978?ref_src=twsrc%5Etfw">January 13, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
【Ruby】Seleniumで露骨な人間アピール

# はじめに
seleniumを使用してサイト調査をしておりまして、
昨今のスクレイピング禁や[例の図書館事件](https://ja.wikipedia.org/wiki/%E5%B2%A1%E5%B4%8E%E5%B8%82%E7%AB%8B%E4%B8%AD%E5%A4%AE%E5%9B%B3%E6%9B%B8%E9%A4%A8%E4%BA%8B%E4%BB%B6)も含めビビり倒しながらの調査の私です。
問題が発生したわけではないのですが、
**露骨に人間アピール**をしようと思って下記のようなメソッドを作ってみました。
多分みんなやっていると思いますが。

# 該当ソースコード

```ruby
def rndSleep
rnd = rand(5) + 1
sleep rnd.to_i
end
```

```rand(5) + 1```で1～５のランダムな数字を**rud**に代入して、
動作を〇秒間停止するsleepメソッド、〇秒部分に当てています。

人間アピールしたい箇所に```rndSleep```を入れると1～5秒おいて実行してくれます。
私は繰り返し処理の、処理開始前に一息ついてもらう感じにしてます。

```ruby
while true do
    index = index + 1
    rndSleep # <= ここで一息
    begin
        news = driver.find_element(:xpath, "/html/body/div[3]/div[1]/div[2]/div[2]/div/table/tbody/tr[#{index}]/td[2]/a")
        href = news.attribute('href')
        newsUrl << href
    rescue Selenium::WebDriver::Error::NoSuchElementError
        break
    end
end
```

# おわりに
実際にBANされたりとか、ブロックされたりはないのですが、
されたら怖いのでちょっとでも抗いたい。
中身の調査をして抜け漏れ予防したいので、負荷かけたいわけではない。
つまり共存したいのです。
なので、プログラム実行側でうまいこと負荷を分散させて、
「人間ですよ～いいコンテンツですね～たくさん回遊しちゃうな～」
的なアピールをして乗り切る必要があるのではないかと感じました。

ちなみに、要素が表示されるまで待つことにsleepメソッドを使用するのは効率が悪いので、
下記の記事を参考にしていただいた方が良いかと思います。

## 参考記事
[seleniumで要素を待つ時にsleepを使うのはオススメしない](https://qiita.com/katsuya_ds/items/725840f11f5c7b314daa)
Flutterで前の画面に戻らせたくない時に使うwillPopScopeを紹介する

# 概要

Webで言うところのPOSTでアクセスするような、ユーザーが1つ前の画面に戻ってほしくないシチュエーションがあると思います。
willPopScopeを使え、で終わりなのですが日本語の記事がなかった上に筆者の英語力がヘボ過ぎて英語の記事も見つけられなかったのでメモとして残します。

雑にtwitterで呟いたら[へぶんさん](https://twitter.com/heavenOSK)が教えてくれました…圧倒的感謝…🙏

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">僕はよく戻らせたくない画面をWillPopScopeで囲んでる。<br>他にやり方があったら、教えてほしい。<a href="https://t.co/duWOwEoLpp">https://t.co/duWOwEoLpp</a> <a href="https://t.co/AaR4VXuF2b">https://t.co/AaR4VXuF2b</a></p>&mdash; へぶん🦌 (@heavenOSK) <a href="https://twitter.com/heavenOSK/status/1217020388552478723?ref_src=twsrc%5Etfw">January 14, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
https://twitter.com/heavenOSK/status/1217020388552478723?s=20


# 解説

APIドキュメントを読めば説明するまでもないと思いますが、一応やってみます。

## 前提

こんな感じの画面があると仮定してください。ルーティングやスタイルの部分は省略します。
![can-go-back.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201135/c2682d48-aaa6-9dcf-7aa8-119ae5e18c30.gif)

```dart

class Screen1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(child: Text('画面1')),
        bottomNavigationBar: BottomAppBar(
          FlatButton(
            onPressed: () => Navigator.of(context).pushNamed(Screen2.routeName),
            child: Text('次の画面に遷移する')
        ),
    );
  }
}


class Screen2 extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(child: Text('画面2'))
    )
  }
}

```

gifが分かりにくいかもしれませんが、画面2から画面１に戻れてしまっていますが、今回はこれを制限します。

## willPopScopeでラップする

やることは簡単で、遷移後のwidgetをwillPopScopeでラップしてください。
_willPopScope.onWillPopには`Future<bool>`を返す関数を登録しましょう。今回は戻ろうとした時に何もしないのでただ`true`を返す虚無関数です。(voidではない)

```dart

class Screen1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: _willPopCallback,
      child: Scaffold(
        body: Center(child: Text('画面1')),
        bottomNavigationBar: BottomAppBar(
          FlatButton(
            onPressed: () => Navigator.of(context).pushNamed(Screen2.routeName),
            child: Text('次の画面に遷移する')
        ),
      ),
    );
  }
  Future<bool> _willPopCallback() async {
    return true;
  }
}


class Screen2 extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(child: Text('画面2'))
    )
  }
}

```

## 結果

ツールの都合上マウスポインタが見えないですが、右にスワイプしても画面遷移しなくなりました。

![cannot-go-back.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201135/2cd28ddd-62d9-f873-bdfb-542aad887bc8.gif)

willPopScopeの説明にも**今開いているModalRouteを消す試みを拒否するコールバックを登録する**とあるので、責務がこれだけで実装も非常に簡単ですね。お疲れ様でした。

> Registers a callback to veto attempts by the user to dismiss the enclosing ModalRoute.

# 参考URL

- https://api.flutter.dev/flutter/widgets/WillPopScope-class.html
- https://stackoverflow.com/questions/49079580/how-to-access-flutter-back-button-functionality/49080132#49080132
クローラーを学ぶ前に知るべき基礎

SEOを担当されている方なら[クローラー](https://jp.scrapestorm.com/)、[クローリング](https://jp.scrapestorm.com/)や[スクレイピング](https://jp.scrapestorm.com/)といった言葉をよく耳にするのではないでしょう。今回は、クローラーを学ぶ前にクローラーの基礎を簡単に紹介します。
####1.クローラーとスクレイピングの区別
クローラ（Crawler）とは、ウェブ上の文書や画像などを周期的に取得し、自動的にデータベース化するプログラムです。「ボット（Bot）」、「スパイダー」、「ロボット」などとも呼ばれ、主に検索エンジンのデータベース、インデックス作成に用いられているほか、統計調査などの目的にも利用されます。
スクレイピングとは、「特定のニーズに合わせた」Webクローラーの一種です。検索エンジンクローラーとの違いは、スクレイピングがコンテンツを処理およびフィルターし、要件に関連するWebページ情報のみをクロールするようにすることです。
![1.ScrapeStorm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/c1d7d2cd-141c-459b-da98-ecf5ad4f42f3.png)
####2.HTTPステータスコード
**(1)ブラウザにhttpリクエストを送信する**
誰でも知っているように、クローラーの前提は、さまざまな「403禁止される」、「404Webページを見つけられない」のようなHTTPステータスコードを出現しない、Webサイトに正常にアクセスできることです。では、なぜHTTPステータスコードがよく見つけられますか？
ます、ブラウザにhttpリクエストを送信するプロセスを紹介します。
httpリクエストを送信するには二種類の方法があります。
**Get**
Getリクエストは主にWebページにデータを取得するために使われます。取得したデータはWebサイトが展示されるデータです。例えば、Yahoo！ショッピングに展示された商品情報はGetリクエストでアクセスしてくれます。
**Post**
Postリクエストは主にWebページにデータを送信するために使われます。例えば、Yahoo！ショッピングにアカウントとパスワードを入力、ログインをクリックして、Yahoo！ショッピングにPostリクエストを送信します。Webサイトはアカウントとパスワードに基づき、ログインを許可します。
![http-get-post.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/cfa2c334-83b9-cbc7-f38d-889455ff64c9.png)
**(2)ヘッダーデータ**
httpリクエストが分かりましたなら、リクエストのヘッダーデータを紹介します。まず、Webサイトを開きます。今回は、Googleを例として紹介します。キーボードのF12をクリックして、バックグラウンドを開き、ヘッダーデータが表示されます。
違うサイトのヘッダーデータが違います。偶にデータがクローラーできないの場合、その原因は、Webサイトは送信したリクエストのヘッダーデータを検証しました。もし、送信したヘッダーデータが足りないの場合、情報が取得できませんになりました。例えば、Webサイトがcookieを検証しましたが、ちょうとう送信したリクエストにcookieがないなら、Webサイトが「403」コードを報告して、データが取得できなくなります。
![headers.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/c7625b59-1b5e-6990-d0cd-b00f2cc6f0ca.png)
クローラーを学ぶ前に知るべき基礎は大体以上になります。データ分析がより大切になる今は、クローラー、スクレイピングなどの情報収集がどんどん重要になる一方だ。より良いWebスクレイピングツールがあれば、手数がかからずにデータを収集できます。[ScrapeStorm](https://jp.scrapestorm.com/)は、AIを使用した視覚的な[Webスクレイピングツール](https://jp.scrapestorm.com/)です。プログラミングが必要なく、ほぼすべてのWebサイトからデータを抽出できます。強い機能を持って、使いやすいです。 URLを入力だけで、自動的に抽出するデータと次のページボタンを識別できます。複雑なルール設定が必要ないし、1-clickだけで[スクレイピング](https://jp.scrapestorm.com/)をできます。
pt-query-digestの2020年問題にハマった話

# 背景
弊社ではDBのチューニング用に[prcona](https://www.percona.com/)のpt-query-digestを使っている
[※スローログの集計に便利な「pt-query-digest」を使ってみよう](https://thinkit.co.jp/article/9617)

# 突然動かなくなった
何もしてないのに壊れた

```
Pipeline process 4 (MySQLProtocolParser) caused an error: Argument "" isn't numeric in multiplication (*) at /usr/bin/pt-query-digest line 4525, <STDIN> line 293.
Will retry pipeline process 3 (MySQLProtocolParser) 1 more time.
The pipeline caused an error: Pipeline process 4 (MySQLProtocolParser) caused an error: Argument "" isn't numeric in multiplication (*) at /usr/bin/pt-query-digest line 4525, <STDIN> line 305.
Terminating pipeline because process 3 (MySQLProtocolParser) caused too many errors.
```

# 該当箇所を読んでみる
```perl
 4519 sub timestamp_diff {
 4520    my ( $start, $end ) = @_;
 4521    my $sd = substr($start, 0, 11, '');
 4522    my $ed = substr($end,   0, 11, '');
 4523    my ( $sh, $sm, $ss ) = split(/:/, $start);
 4524    my ( $eh, $em, $es ) = split(/:/, $end);
 4525    my $esecs = ($eh * 3600 + $em * 60 + $es);
 4526    my $ssecs = ($sh * 3600 + $sm * 60 + $ss);
 4527    if ( $sd eq $ed ) {
 4528       return sprintf '%.6f', $esecs - $ssecs;
 4529    }
 4530    else { # Assume only one day boundary has been crossed, no DST, etc
 4531       return sprintf '%.6f', ( 86_400 - $ssecs ) + $esecs;
 4532    }
 4533 }
```
何か時間関係でエラーになってるようだ・・・
2019年末には動いていたので、誰かがいじっていなければ2020年になった事が要因と考えられる

# フォーラムにあった
https://www.percona.com/forums/questions-discussions/percona-toolkit/55140-pt-query-digest-mysqlprotocolparser-caused-an-error

全く同じ。2019年のdumpなら動くが2020年になると日付計算でエラーになる模様

https://github.com/percona/percona-toolkit/pull/434

# 修正をアテる
## /usr/bin/pt-query.digest
```perl
 3627 sub parse_event {
 3628    my ( $self, %args ) = @_;
 3629    my @required_args = qw(next_event tell);
 3630    foreach my $arg ( @required_args ) {
 3631       die "I need a $arg argument" unless $args{$arg};
 3632    }
 3633    my ($next_event, $tell) = @args{@required_args};
 3634
 3635    local $INPUT_RECORD_SEPARATOR = "\n20";
 3636
 3637    my $pos_in_log = $tell->();
 3638    while ( defined(my $raw_packet = $next_event->()) ) {
 3639       next if $raw_packet =~ m/^$/;  # issue 564
 3640       $pos_in_log -= 1 if $pos_in_log;
 3641
 3642       $raw_packet =~ s/\n20\Z//;
 3643       $raw_packet = "20$raw_packet" if $raw_packet =~ /\A20-\d\d-\d\d/; # workaround for year 2020 problem
 3644       $raw_packet = "20$raw_packet" unless $raw_packet =~ m/\A20/;
 3645
 3646       $raw_packet =~ s/0x0000:.+?(450.) /0x0000:  $1 /;
 3647
 3648       my $packet = $self->_parse_packet($raw_packet);
 3649       $packet->{pos_in_log} = $pos_in_log;
 3650       $packet->{raw_packet} = $raw_packet;
 3651
 3652       $args{stats}->{events_read}++ if $args{stats};
 3653
 3654       return $packet;
 3655    }
 3656
 3657    $args{oktorun}->(0) if $args{oktorun};
 3658    return;
 3659 }
```

これで無事に動いた。
【C++】平面図形問題を解く。

# 【C++】平面図形問題を解く。
競技プログラミングにおいて平面問題を解く際のテンプレートを用意した。
需要があれば数学的な解説を図形付きで載せたい。
とりあえずは、自分用にまとめておく。

## 0.下準備
structを使ってpointを自分で定義する。
classを使ってもよい。その場合はメンバ変数をpublicにするとよい。

```cpp
#include <bits/stdc++.h>
#define FOR(i, m, n) for(int i = m;i < n;i++)

const double eps = 1e-9;
struct point { double x, y; };
point  operator+(point a,  point b) { return {a.x+b.x, a.y+b.y}; }
point  operator-(point a,  point b) { return {a.x-b.x, a.y-b.y}; }
point  operator*(double t, point b) { return {t*b.x, t*b.y}; }
point  operator/(point a, double t) { return {a.x/t, a.y/t}; }
double operator*(point a,  point b) { return a.x*b.x + a.y*b.y; } // dot product
double operator%(point a,  point b) { return a.x*b.y - a.y*b.x; } // cross product
bool operator<(point a, point b) { // lexicographical compare
	if (abs(a.x-b.x) > eps) return a.x < b.x;
	return a.y + eps < b.y;
}
ostream &operator<<(ostream &out, point a) { // for demplace_backugging
	return out << "(" << a.x << "," << a.y << ")";
}
```
ベクトルの和、差、内積、外積を、各演算子をオーバーロードすることにより定義する。
各点を`double`で表現しているので比較をするときには注意が必要。
`a.x != b.x`の気持ちで`abs(a.x-b.x) > eps`を使用している。
`0.1*100 != 10.0`が`true`になるのと同じ理由。詳しくは省略。
## 1.基本的な演算

```cpp
double abs(point a) { return hypot(a.x,a.y); }
point perp(point a) { return {-a.y,a.x}; } // rotate 90 degrees counterclockwise
point normalize(point a) { return a/abs(a); }
 
double angle(point a, point b) { // angle between two vectors (0 to pi)
	double d = normalize(a)*normalize(b);
	return acos(max(-1.0,min(1.0,d)));
}
 
ll ccw(point a, point b, point c) { // returns 1|0|-1 if ac is left|straight|right of ab
	double res = (b-a)%(c-a);
	return abs(res) > eps ? (res > 0 ? 1 : -1) : 0;
}

// 線分AB上に点ｐがあるか判定。
bool on_segment(point p, point a, point b) {
	return (a-p)*(b-p) < eps && ccw(a,b,p) == 0;
}
```

## 2.外心

```cpp
// point that has equal distance to a,b,c
point circumcenter(point a, point b, point c) {
	b = b-a, c = c-a;
	return a + perp(c*c*b - b*b*c)/(b%c)/2;
}
```
日本語で解説してる記事は見当たらなかった。3次元の場合はwikipedia(英語版)に解説あり。
https://en.wikipedia.org/wiki/Circumscribed_circle
需要があれば詳しく解説したい。

## 3.内心
```cpp
// center of incircle of triangle a,b,c
point incenter(point a, point b, point c) {
	double u = abs(b-c), v = abs(c-a), w = abs(a-b);
	return (u*a + v*b + w*c) / (u + v + w);
}
```
内心の公式でググれば、なぜこうなるかはわかる。

## 4.2円に接する直線と円との交点
```cpp
// finds all lines tangent to two circles (p,r) and (q,s)
// first outer, then inner tangents; be careful with touching/intersecting circles!
void find_tangents(point p, double r, point q, double s, vector<pair<point,point>> &res) {
	FOR(inner,0,2) {
		point v = q-p;
		double h = sqrt(v*v - (r-s)*(r-s));
		for (ll sign: {-1,1}) {
			point n = normalize((r-s)*v + sign*h*perp(v));
			res.emplace_back(p+r*n, q+s*n);
		}
		s = -s;
	}
}
```
円が2つ離れているとき、共通外接線2本と共通内接線2本が存在する。
それぞれの接線と円との交点を計算する。
図形付きで解説したいけど、図形書くのめんどくさい。
どこかにいい感じのソフトないかなぁ。

以上。
# 参考文献
[Circumscribed circle - wikipedia](https://en.wikipedia.org/wiki/Circumscribed_circle)
pandas.DataFrame内を変数で検索し、該当する行を取得する。

pandas.DataFrameから、該当する文字列がある行を取得する方法として、query()メソッドがある。

```python
df.query('name == "Suzuki"')
```

上記のnameに対象の列名、そして==の後に""で囲った検索する文字列を入れればOK。

ただ、for in で検索する文字列をループさせる、という処理をしたかったので、変数を入れる必要があった。

当然、

```python
search_name = 'Suzuki'
df.query('name == search_name')
```

をやったらエラーになる。

調べると、query()で変数を使うには、@をつければいいらしいので、

```python
search_name = 'Suzuki'
df.query('name == @search_name')
```

これでできました。
【2020年1月版】Docker ComposeでConcourse + Vault 連携。Traefik2.0 で Vault の HTTPS をスルー。

# お試しで立ててみた Vault の HTTPS を Traefik でスルーさせたい。

前回の記事([【2020年1月版】Traefik 2.0 で Docker-Compose の"80"ポートを交通整理](https://qiita.com/koinori/items/39ab0c3048fdcfaf3f65))で、Traefik 使っていろいろサービスを立てられるようになりましたので [Concourse CI](https://concourse-ci.org/) もローカルで試してみたのですが、git のキーをパイプラインに直書きするのは気に入らないので Vault との連携を試してみました。

- [1.11.2.1 The Vault credential manager](https://concourse-ci.org/vault-credential-manager.html)

Concourse と Vault の連携は Example の手順でおおよそ上手くできたのですが、一点だけ違うのが私の環境では Concourse と Vaultの間に **Traefikがいる**んですよね。

Vault は初モノなので、できるだけ Concourse の Exampleの手順通りにコトを済ませたいのですが…

## 状況の整理

Concourse CIのExampleの手順は認証に"クライアント証明書"を使うやり方式です。
SSL証明書の発行に [certstrap](https://github.com/square/certstrap) を使って、Vaultのコンテナ側にSSL証明書を入れております。
このSSL証明書からConcourse CI用の証明書を発行してもらって、Concourseの認証をする、というような連携となっております。

Treafik の一般的な使い方としては Traefik でTLSしてTraefikの内側はすっぴんのHTTP通信、となります。(この方式ではクライアント証明書での認証、使えないんじゃないかな…？)
これを調整しだすと結構かかりそうなので、"Concourseのパイプラインでキーを指定して git にアクセスする"、というのを先行して疎通確認するために、このままの設定で行ってみようかというのが今回のキモなわけです。

つまり、Traefikの内側ですでにTLS入っている状況で、これをスルーできるのか、という点ですね。

## いろいろやってみた結果。

以下の公式ガイドの箇所にちょっとあるのですが・・・

- [Configuring TCP Routers](https://docs.traefik.io/routing/routers/#general_2)

ここの "Configuring passthrough" という項目があるので開いてみると…

```
## Dynamic configuration
tcp:
  routers:
    Router-1:
      rule: "HostSNI(`foo-domain`)"
      service: service-id
      tls:
        passthrough: true
```
`tls.passthrough: true` ができるようです。

というわけで Vault の docker-compose.yml では以下のようなラベルを追加すればOKでした。

```yml:docker-compose.yml
  vault:
    image: vault
    cap_add:
      - IPC_LOCK
    command:
      - server
    expose:
      - 8200
    networks:
      - web
    volumes:
      - ./vault-certs:/vault/certs
      - ./vault-config/local.json:/vault/config/local.json
    labels:
      traefik.enable: true
      traefik.host: "vault"
      traefik.tcp.routers.vault.rule: HostSNI(`vault.192.168.1.50.nip.io`)
      traefik.tcp.routers.vault.service: vault
      traefik.tcp.routers.vault.entrypoints: https
      traefik.tcp.routers.vault.tls: ""
      traefik.tcp.routers.vault.tls.passthrough : true
      traefik.tcp.services.vault.loadbalancer.server.port: 8200
      traefik.docker.network: traefik_web
```
また、traefik 側で`https`のエントリーポイントも忘れずに追加をお願いします。

```yml:traefik.yml
...
entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"
...
```
以上でOKです！

しかし、**traefik のドキュメントは肝心なところが collapsedな場合が多くて要注意です**ね。。。
AWSでsshコマンドで接続できない場合2STEPで対処しよう！

以前AWSを使用していてsshで接続ができていたのに、寝て起きたら接続できなくなり焦ったのでまとめてみました。(； ･`д･´)

#手順

##1.
まずAWSでEC2インスタンスを作成した際にキーペアを作成してダウンロードしたかと思います。
※キーペアとは拡張子.pemのことです。

キーペアが存在しているディレクトリにまでcdコマンドを使い移動します。

$ cd downloads
rooter:downloads ユーザー名
$ pwd
User/ユーザ名/downloads
※私の場合downloadsディレクトリの中にキーペアが存在しています。

##2.
ディレクトリまで移動ができましたら下記sshコマンド実行！
$ ssh -i "book.pem" ec2-user@13.218.324.29
※book.pemとは私のキーペア名です。

![スクリーンショット 2020-01-14 19.24.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543413/857da483-d45c-f85e-a276-3fa47f15aed6.png)


接続できました！

@の後ろはパブリックアドレスが人により違います。
下記画像でいうところのIPv4パブリックIPと赤枠で囲っている部分です。

![スクリーンショット 2020-01-14 19.19.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543413/59310904-446e-b178-05bd-5d5729b3d4b4.png)
Azure SQL Server(Single DB or DW)内のADユーザ登録手順

#はじめに
Azure SQL Database(以下、DB)と Azure Synapse Analytics(以下、DW)にADユーザ or ADセキュリティグループ or Azure リソースを登録する方法についてメモ
※Azure リソースとはManaged IDを含むサービスプリンシパルを指します。本手順はData FactoryやMachine LearningなどのManaged IDに対する認可を確認済みです。Azure リソースに権限付与する場合はリソース名をSQL内に入れるようにしてください。

以下、参考リンク
MS Doc
[CREATE USER (Transact-SQL)](https://docs.microsoft.com/ja-jp/sql/t-sql/statements/create-user-transact-sql?view=sql-server-ver15)
[ALTER ROLE (Transact-SQL)](https://docs.microsoft.com/ja-jp/sql/t-sql/statements/alter-role-transact-sql?view=sql-server-ver15)
[sp_addrolemember (Transact-SQL)](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-stored-procedures/sp-addrolemember-transact-sql?view=sql-server-ver15)

#手順

 - SQL Server ユーザに追加
 - Database権限ロール付与にユーザ登録


##SQL Server ユーザに追加


```sql:sql
CREATE USER [ユーザID or リソース名] FROM EXTERNAL PROVIDER

```

ユーザIDはセキュリティグループ名を入れることも可能です。
通常はユーザID @xxx.onmicrosoft.comになりますが、もし外部ADからの招待ユーザなら下記のような指定となります。
ユーザID_外部ADドメイン#EXT#@xxx.onmicrosoft.com

##Database権限ロール付与にユーザ登録
上記だけだとSQLServerにはログインできますが、Databaseへアクセスできませんので、データへのアクセス権限を付与します。db_owner権限の場合の例です。
DBとDWで少し変わります。


###DB

```sql:sql
ALTER ROLE [db_owner] ADD MEMBER [ユーザID or リソース名]
```

###DW

```sql:sql
EXEC sp_addrolemember 'db_owner', 'ユーザID or リソース名'
```
Recursive Estimation and Time Series analysis

```{r}

#Recursive Estimation and Time Series analysis

#RLS(Recursive Linear Least Square) p.33

library(dplyr)

data=data.frame(anscombe)

char=c("x1","x2","x3","x4")

Y=data$y2

X=as.matrix(data[,colnames(data) %in% char])

#times=5

#for(j in 1:times){
  
#X=rbind(X,X)

#Y=c(Y,Y)
  
#}

a=as.matrix(rep(1,ncol(X)),dim=c(ncol(X),1))

P=diag(0,ncol(X))

for(k in 1:nrow(data)){
  
P=P+t(t(c(X[k,])))%*%t(c(X[k,])) 

P_mat=eigen(P)$vectors%*%diag(1/eigen(P)$values)%*%t(eigen(P)$vectors)

sig=sum((Y[1:k]-X[1:k,]%*%a)^2)/(nrow(data)-ncol(data)-1)

P_star=sig*P_mat
  
e=Y[k]-t(c(X[k,]))%*%a  

print(P_mat%*%t(t(c(X[k,]))))

a=a+P_mat%*%t(t(c(X[k,])))*as.numeric(e)

}

a_hat=eigen(t(X)%*%X)$vectors%*%diag(1/eigen(t(X)%*%X)$values)%*%t(eigen(t(X)%*%X)$vectors)%*%t(X)%*%Y

cbind(Y,X%*%a,X%*%a_hat)

cor(cbind(Y,X%*%a,X%*%a_hat))

```
[Oracle SQL] Unpivotする方法

# やりたいこと

### unpivot前

「昨日」「今日」「明日」のテストの点数が横持ちになっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532975/c13f75f9-ded9-fccd-fa80-2859e19e4c12.png)




```sql

select * from ora_test_score;
```


### unpivot後

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532975/b626469c-a356-b98b-56fb-3b06e8bea32e.png)



# unpivotのSQL

```sql

select * from ora_test_score
UnPivot(Score for いつ in(昨日, 今日, 明日));
```
Jenkinsでジョブ間のパラメータの引き渡しが全然上手くいかなかったのでメモ

#はじめに
初めてJenkinsでテスト用の簡単なjobを作成したが、なかなか上手くいかなかったので備忘録。

#やりたかったこと
表題の通り、Job1からJob2へのパラメータの引き渡しがしたかった。
&emsp;&emsp;&emsp;&emsp;<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521034/eb7bfcff-355a-41a5-da2a-b94ecb78ad10.png">

#成功手順
####①プラグインをインストール

-  [Jenkins Parameterized Trigger plugin](https://wiki.jenkins-ci.org/display/JENKINS/Parameterized+Trigger+Plugin)のプラグインを利用可能な状態にする

####②環境変数のインジェクトを設定

- Job1のシェルスクリプト内で、下記のようにプロパティファイルを作成し、渡したい変数`JOB_PARAM`をファイル内に書き込む

※ファイルが生成されない処理ルート（生成前にexit等）が存在すると、後続Jobでエラーが発生するため注意

```shell:Job1.sh
JOB_PARAM="aaa";

PROPERTY_FILE="example.properties";
echo "JOB_PARAM=${JOB_PARAM}" > ${PROPERTY_FILE};
```
- Job1のビルドタブにて [ビルド手順の追加] ⇒ [環境変数のインジェクト] を選択
- [プロパティファイルのパス] に`example.properties`と記入

####③ビルド後の処理を設定

- Job1のビルド後処理タブにて [ビルド後の処理を追加] ⇒ [Trigger parameterized build on other projects] を選択
<br>
- [Projects to build] に渡す先のジョブ名（ここでは「Job2」）を記入
- [Trigger when build is] で [Stable] を選択
- [Add Parameters] ⇒ [Predefined parameters] を選択し、渡したいパラメータを<br>`TARGET_PARAMETER=${JOB_PARAM}`のように設定

####④パラメータの受け取り

- Job2のGeneralタブにて [ビルドのパラメータ化] にチェックを入れ、[パラメータの追加] ⇒ [テキスト] を選択
- [名前] にJob1の [Predefined parameters] で指定した変数名（ここでは「TARGET_PARAMETER」）を記入
- Job2のシェルスクリプトでJob1で定義した`TARGET_PARAMETER`を下記のように利用可能

```shell:Job2.sh
echo "Job1で設定したAの値：${TARGET_PARAMETER}";
```
####⑤実行結果
~~~
Job1で設定したAの値：aaa
~~~

#はまった点
###環境変数のインジェクト
これに気づけませんでした。
単純にビルド後処理に [Predefined parameters] を追加してパラメータを渡すだけでは上手くいかず、
シェルスクリプト内で定義した変数がビルド後の処理に渡されませんでした。
つまり`TARGET_PARAMETER=${JOB_PARAM}`と [Predefined parameters] で設定するだけだと、
Job2には「${JOB_PARAM}」という文字列が渡されてしまいます。

ビルド処理の中でインジェクト用のファイルを作成し、渡したい変数の値をファイル内に
記述する作業が必要でした。
[環境変数のインジェクト] では上記のファイルを取り出すことができるようです。

実際、ビルド後の処理⇒ [Trigger parameterized build on other projects] ⇒ 
[Add Parameters] ⇒ [Parameters from properties file] でスクリプト内で書き込んだファイルを直接指定すれば
環境変数のインジェクトを設定しなくても出来ましたが、
個人的には見た目的な分かりやすさの違いなのかなと思っています。
（インジェクトしたいファイルを指定する方が、ビルド後の処理の記述で渡したい変数が明確でスマート）

#参考
- [Jenkinsであるジョブの完了後に他のジョブにパラメータを渡して実行する](http://yyhayashi303.hatenablog.com/entry/2013/11/03/004528)
- [jenkinsのスクリプト間で変数を共有したい](https://qiita.com/mkosuke/items/ef55ae48b2064873ba2b)
[Rust] 整数型のべき乗の引数はなぜ u32 なのか

Rust の整数型のべき乗の引数はすべて `u32` になっています (例えば `u64::pow` であってもべき指数は `u32` で指定する, ちなみに浮動小数点数の `powi` は `i32`). これはなぜか, という StackOverflow での [jdborg](https://stackoverflow.com/users/734463/jdborg) 氏の質問 [Why does Rust's u64.pow expect a u32?](https://stackoverflow.com/questions/57119562/why-does-rusts-u64-pow-expect-a-u32) に [trentcl](https://stackoverflow.com/users/3650362/trentcl) 氏が[丁寧な回答](https://stackoverflow.com/a/57120777)を寄せていたので全訳します. StackOverflow の投稿って CC BY-SA なんですね (そして Qiita に CC BY-SA を投稿できる).

要約すると, (1) べき乗はハードウェアサポートがないので引数を同じ型に揃えなければならないというハードウェア的要求がない, (2) 引数に 64 bit も取るのは無駄である (そんなに大きなべきを計算しても `u64` で表せる範囲に収まらない), (3) とはいえ 8 bit や 16 bit まで小さくしてもご利益がないので 32 bit がちょうど良かろう. という趣旨のことを述べています.

# trentcl 氏の回答の全訳

## なぜたいていの演算では引数は同じ型なのか?

人間にとっては `2i32 + 2i64` は `4i64` になるべきなのは明らかです. しかし, CPU にとっては `2i32` と `2i64` は完全に異質でまったく関係のないものに見えます. CPU の中では足し算はハードウェア的に実装されていて, たいてい「2 つの 32 bit 数の入力」または「2 つの 64 bit 数の入力」をサポートしています. ですから `i32` と `i64` を足すためには, その値を演算装置に入れる前に `i32` を 64 bit 数へと変換する必要があるのです.

一般に同じことがほとんどの整数および浮動小数点数の算術に当てはまります. 異なる型の間で演算を行うには型変換が必要なのです. C言語では通常コンパイラがすべてのオペランド (算術演算の引数) がともに同じ型を持つように bit 数を拡張します. この暗黙の型変換は文脈に応じて「汎整数拡張」 (integer promotion) あるいは「通常の算術変換」 (usual arithmetic conversion) と呼ばれます. ところが Rust ではコンパイラは同じ型の演算しか扱えないため, 人間がオペランドの変換方法を指定することでどのような演算をしてほしいのか選ぶ必要があります. Rust を好んでいる人はこのことを良いことだと考える傾向にあるようです (注1).

## なぜそれが `u64::pow` に当てはまらないのか?

ハードウェアで実装されているものも含め, すべての算術演算が同じ型の引数を受け付ける訳ではありません. シフト演算は引数のビット数を上回った部分はしばしばハードウェア的に無視されます (これはC言語で整数のサイズより大きなシフト操作が未定義動作を引き起こす理由です). LLVM が提供する powi 演算は浮動小数点数の整数べきを計算します.

これらの演算は入力が非対称という点で他の演算とは異なっていて, 設計者はこの非対称性を利用してハードウェアを速くかつ小さくします. `u64::pow` に関して言うと, これはハードウェア的に実装されていないのです. この関数は std 内で [Rust により実装](https://doc.rust-lang.org/src/core/num/mod.rs.html#3669-3689)されています. このことを考慮すれば, 指数部分に `u64` はまったく必要ないということは明らかでしょう. [Schwern の回答](https://stackoverflow.com/a/57120020)で指摘されているように, 正確な答えが期待される `u64` のべきは `u32` の範囲で十分なのであり, 余計な 32 bit は意味がないのです.

## それで, なぜ `u32` なのか?

この最後の主張は `u16` や `u8` であっても成立するでしょう. つまり, `u64` は 2 の 255 乗ですら表せないので, 指数部には `u8` で十分であり `u32` でさえ無駄に大きな bit を持っていることになります. ただ, 次のことを考慮する必要があります. 多くの呼び出し規約ではレジスタに関数の引数を渡すようにしていて, なので 32 bit (かより大きい) プラットフォームではそれより小さな bit を用いる利点は見当たらないでしょう. 多くの CPU は 8 bit や 16 bit の算術もネイティブサポートしていないため, exponentiation-by-squaring アルゴリズムを実装する際には, 引数に先に述べたような 32 bit への拡張を行う必要があります. 私は `u32` が選ばれた理由そのものを知っている訳ではないのですが, 標準ライブラリの設計時にこれらのことが考慮されたのだろうと思います.

注1: C言語の規則は過去の経緯, そして古いハードウェアを含む広い範囲の機器をサポートするということに制約されています. Rust は LLVM だけをターゲットとしているため, コンパイラは対象のハードウェアが 8 bit プリミティブの加算機構を持っているかどうかを考える必要がありません. Rust は単に 8 bit の足し算を呼ぶだけでよく, LLVM がプリミティブ演算にコンパイルすべきか 32 bit 演算で 8 bit 演算をエミュレートすべきかどうかを判断します. これが C 言語では `char + char` が `int` であるのに Rust では `i8 + i8` が `i8` である理由です.

# ライセンス表記
「trentcl 氏の回答の全訳」節の内容は [trentcl](https://stackoverflow.com/users/3650362/trentcl) 氏が [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/legalcode) ライセンスのもとで https://stackoverflow.com/a/57120777 にて 2019-07-20 に英語で公開したものを日本語訳したものです. ライセンスに従い, 本記事もまた [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/legalcode) ライセンスとします (©osanshouo 2020-01-14).
Pandasでcsvの複数カラムの変更方法（Unixtime -> Japan Time）

```python
import glob
import os
import pandas as pd
import pandas as pd
from datetime import datetime
from pytz import timezone


# CSVデータを変えるスクリプト (カラム 'starttime', 'endtime' をUnixtimeから日本時刻に変更）

# プログラム実行場所の直下に目的のcsvファイルがある
csv_list = os.listdir()

# !!適時 .remove()などでcsvじゃないファイルを抜いてあげてください。
# !!今時間がないのですが、修正してくれる人いたら大歓迎です！
# (↑csv以外をlistから削除 or listに入れない部分)



tz = timezone('Asia/Tokyo')


for csv_file in csv_list:
    
    
    
    japan_starttime_list = []
    japan_endtime_list = []
    
    
    print(csv_file, "を読み込む...")
    
    df = pd.read_csv(csv_file)
    
    starttime_series = df.starttime
    endtime_series = df.endtime
    
    
    for starttime in starttime_series:
        starttime_str = str(starttime)[:10]
        starttime_int = int(starttime_str)
        
        # Unixtime -> Japan time(str) -> listに格納
        utc_time = datetime.fromtimestamp(starttime_int)
        japan_time = utc_time.astimezone(tz)
        japan_time_str = japan_time.strftime('%H:%M:%S')
        japan_starttime_list.append(japan_time_str)
        
        
    # endtimeでも同じことを
    for endtime in endtime_series:
        endtime_str = str(endtime)[:10]
        endtime_int = int(endtime_str)
        
        # Unixtime -> Japan time(str) -> listに格納
        utc_time = datetime.fromtimestamp(endtime_int)
        japan_time = utc_time.astimezone(tz)
        japan_time_str = japan_time.strftime('%H:%M:%S')
        japan_endtime_list.append(japan_time_str)
        
    
    # dataframe の２つのカラムのデータ変更
    df.starttime = japan_starttime_list
    df.endtime = japan_endtime_list
    
    
    # 新たな csv を作成
    df.to_csv('rev_' + csv_file)
```
VuexってThe Elm Architectureみたいに状態を管理出来るの？


半年ぐらい前にElmを少し触って時の印象としては、
- アーキテクチャが決まってるので考えることがない。
- Haskellに似てるけど難しくない言語なので書くことが少ない。
- JavaScriptで書かれたライブラリを使うのが面倒い。
という印象でした。

Elmでthreejsを使うみたいなことは意外と面倒くさそうなんです。

もし、VuexがElmのようにアーキテクチャが決まってるとしたら、考えることがない上に、JavaScriptのライブラリも使えるので素晴らしいのでは？
あとはHaskellに似た文法だけど、TypeScriptで書けば型はあるしそこそこ楽できるのでは？

TypeScript + Vuex + threejsでなんかやりたいなぁ。
超初心者がwebpackerについて調べてみたぞ

Ruby on Rails を使って開発を始めた今日この頃。
サーバーサイドはそれとなく出来てきたからそろそろフロントも固めて行こうかしら。なんて思っていた僕はBootstrapをRailsで使おうと考えた。Bootstrapを使うのはいたって簡単。**htmlのhead内に以下のリンクをぶち込めばいいだけ**。

```application.html.erb
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
    integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
```
なんて便利だこと。
しかし、**Bootstrapを使うには他にも方法はある**。それは以下のリンクにある通りだ。
https://qiita.com/rhistoba/items/f724dae231d7e28bf477
つまり、**railsにBootstrapをインストールしてしまう方法**である。
基本的には、リンクの記事通りに手順を踏めばインストールできるのであるが、超初心者の僕はいくつかのワカラナイ点があったので自分用のメモとして残すことにした。

##前提
####僕のスペック
- プログラミング学習を始めて1ヶ月
- HTML/CSS/Javascript/Ruby/Railsをprogateで一応学習済
- Ruby on rails でポートフォリオを作成中

####開発環境
- 端末 : LENOVO ideapad 530S-14ARR
- OS : Windows 10 Home ver.1809
- シェル : PowerShell 5.1.17763.771
- Ruby : 2.6.4
- rails :  5.2.4.1

## そもそもwebpackerってなんだ？
**webpacker**とは**webpackをRubyで使えるようにしたもの**らしい。
僕「webpackかぁ～…聞いたことあるよ。…でもよく知らない。」

### webpackとは？
調べたところ、webpack というのは

>Webpackとは、CSS、JavaScript、画像などを１つのファイルとしてまとめるためのモジュールバンドラーで、node.jsのモジュールの1つです。

とのこと。（引用元：https://www.sejuku.net/blog/68146）
僕「**モジュールバンドラー**ってなんだよぉ(´;ω;｀)」
僕「**node.js**もよく分かんねーよぉ(´;ω;｀)」
調べても分からないが続く。まさに分からないリレー状態。

###モジュールバンドラーとは？
次にモジュールバンドラーについて知らべてみた。
モジュールバンドラーとはその名の通り、**モジュール（部品）をまとめたもの**をいうらしい。ここでモジュールとはあるプログラムと考えるのが良さげ。

例えば、現在時刻を表示するプログラムを作るとしよう。ここで、**現在時刻を取得するコードと、それを表示するコードと分けて作ったとする**。これらのコードを合体させたいのだが、その方法として、表示するためのコードに現在時刻を取得するコードをインポートすることにしよう。この時、**インポートされる側のコードをモジュールと呼ぶ**。

このような便利なコード集をモジュールバンドラーというみたい。
（参考：https://note.com/billion_dollars/n/n596fecfdeb2e）

###node.jsとは？
node.jsとは**サーバーサイドJavascript**である。
Javascriptは本来、ブラウザで動き見た目を作る（フロントで活躍する）言語なのだが、「**この言語でサーバーサイドも作れたら嬉しくね？**」という発想から作られたJavaScript 環境なんだとか。

僕「なるほどぉ。すごいじゃんnode.js」

（参考：https://eng-entrance.com/what-is-nodejs#Nodejs-2）
## 改めてwebpackって何ぞや？
ここまで調べたことをまとめて、もう一度考えるとwebpackとは、
>CSS、JavaScript、画像などの部品を上手にまとめて1つにするnode.js（Javascript環境の１つ）のモジュールだ！

ということですね。**要するにまとめ上手なお兄さんみたいな**（雑）

## とはいえ、なんでそんなにまとめたがるのか？
なんとなくwebpackについて分かったけど、**まとめることにどんなメリットがあるのかしら？**調べてみると通信との関係があるみたいだ。
僕たちがwebサイトを閲覧する時は、自分のPCからサーバーにリクエストを送り、そのレスポンスとしてあるwebページ（htmlファイルとか）を返してくれる。
しかし、そのhtmlが様々なコード（モジュール）や画像、css、javascriptなどを引用してきている時には、それらも同時に送ってやらないと不完全なwebページしか閲覧できない。だからそういう関係するファイルも一緒に送ってやるのだが、これらが**バラバラだとサーバーがPCに送るのに時間が掛かってしまう**みたい。
ここでそれらのファイルが1つに**まとまっていることで素早く通信できる**ようだ。

## まとめ
webpackerのことを調べて、本来の目的であるBootstrapのインストール忘れてた(/ω＼)
10分で説明するAtomic Design と、弊チームで扱うためのカスタマイズについて

## Atomic Design とは（解釈）
- 部品の組み合わせでUIを作れるようにするもの
- ５つのグループに分類し、それらの依存を一方向にして管理
- グループやその役割は自由にカスタマイズしていい

### ポイント
- 各グループの役割をしっかり決める、認識する
- グループの依存方向を守る

## ５つのグループの役割
|グループ名|組合せ可|関わる人|担保するもの|特徴|
|:-:|:-:|:-:|:--|:--|
| atoms     | x |dev| トンマナ、基本デザイン |・UIパーツの最小構成部品<br>・他のコンポーネントには依存しない<br>・配置パターンもatomsに含まれる|
| molecules | o |dev| 操作性 |・atomsを組み合わせて作る部品<br>・atomsの原始的行動に意味を付加する<br>　・eg.文字を入れる+クリックする=検索する|
| organisms | o |dev| 機能、価値、サービス |・atoms,molecules,organismsを組み合わせて作る部品<br>・独立して機能し、他のページでも同じ意図で使える|
| templates | o |dev+biz| レイアウト |・atoms,molecules,organismsを配置する<br>・プレイスホルダーだけのスケルトンの状態|
| pages     | o |dev+biz| 流し込むデータ |・templatesにデータを流し込みページを動かす|

### 境界
- atoms vs molecules
    - 単独コンポーネントか(atoms)複数組合せコンポーネントか(moelcules)
- molecules vs organisms
    - 組み合わせによって意味/意図が変わるか(molecules)否か(organisms）
- organisms vs templates
    - 配置を自由に変えられる（templates）か否か（organisms)
- templates vs pages
    - 実際のデータに依存するか（pages)否か(templates)

## 依存の方向について
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5514/4768d634-2cfa-cebd-0dbd-6b5972ab1a8e.png)
([本家ブログより](https://bradfrost.com/blog/post/atomic-web-design/))

- 自分自身から図中左側のレイヤーのみに依存する
- 修正したレイヤーより図中左側のレイヤーには影響が出ない状態

## グループのカスタマイズ
- スマホ用のコンシューマー向けサイトと、PC用の業務向けサイトで同じグルーピングが通用するか？
    -  -> **NO**

### うちのチームの場合
- 対象プロダクトの特徴
    - 多機能な巨大UI部品がある（一覧テーブル、オプション選択リストなど）
    - 1ページ内に複数の目的を持たせたダッシュボードの様なページはほぼない
- 上記とAtomicDesignの差
    - 複雑な部品が多く、ほとんどorganismsになりかねないので、moleculesを組み合わせたmoleculesを許容する
    - 本来global stateと繋ぐのはpagesだけだが、バケツリレーがひどくなるためorganismsでも許容する
        - ただし、そのorganisms固有とツール全体の汎用データのみ
    - 使いまわせるtemplatesが少なく、レイアウトを変える機会も少ないいため、templatesは必須としない
        - pagesである程度レイアウトしてしまう
    - 場合によってはmoleculesとorganismsの間にもう1階層追加する必要がでるかもしれない

## まとめ
- 本来はUI設計手法なのでもっといろんな要素があるが、まずは役割、分類、依存方向だけ意識してやっていき

## 参照
- [atomic design - brad frost](https://bradfrost.com/blog/post/atomic-web-design/)
- [Atomic Design 堅牢で使いやすいuiを効率良く設計する](https://www.amazon.co.jp/dp/B07CJ5TLK2)
Ergodox Ezを購入したお話

## 動機
大学生の頃に良いキーボードに目覚めました。
Real Force -> HHKBと経て、
新卒で働いていた現場で、現場の先輩からKinesis FreeStyle2のキーボードをいただいてから、
エルゴノミクスキーボードにも興味を持つようになりました。
理想は、HHKBみたいに手を極力動かさなくて済んで、左右分離型で、静電容量無接点方式であること。
ただ、そんなキーボードは今のところ存在しません。

そこで、HHKBみたいに手を極力動かさなくて済むようにカスタマイズ出来て、左右分離型で、軸を選ぶことができるErgodox Ezに白羽の矢が立ちました。

## 購入する場所
[Ergodoxの公式ページ](https://ergodox-ez.com/pages/customize)で購入しました。
メルカリとか見ると、結構売りに出されていて寂しい気持ちになる。

## 購入した構成
- 色：Black
    - キーボードの色
- 軸：Kailh Silver
    - 軸。お好きな押し心地のものを選ぶ
- 文字：印字無し
    - キーの印字いるかどうか。配置を自由に組み換えできることを考えるといらない
- Tilt Kit:あり
    - キーボードの角度を調節するキット。必須。
- Wing Rest:あり
    - 以外とキーボードの位置が高いので、無いと打ちづらい。必須。
- Shine:なし
    - 光る。いらない。
- Glow:なし
    - 光る。いらない。

金額：$325 -> 36,000円くらい

## 関税
1200円だった。

## 配達期間
都内で3日ほどでした。
UPSという配送会社から送られてきました。
地方の場合は、日本までUPSで送られてきて、ヤマト運輸などの会社の手に渡って配送されます。
都内だとUPSから送られてきます。
UPSは、平日にしか荷物を配送しないため、休日にしか受け取れない場合は、1度目の配送の後、ヤマトから配送するように再配達依頼をかけましょう。
そのままにしておくと、3度配送できなかった時点で5日間営業所に預けられ、配送元に返されます。

## 使い始め
超苦戦する。
デフォルトの配置は、かなり標準のキー配列に比べて異なっているので自分用にカスタマイズするのが吉。

## キー配列を変える
Webアプリから、配置を決めることができます。
ここである程度配置を決定したら、設定ファイルをダウンロードしてください。
https://configure.ergodox-ez.com/ergodox-ez/layouts/default/latest/0

したらば、下記の公式ツールをダウンロードします。
[Wally](https://ergodox-ez.com/pages/wally)

ツールの手順に沿って、ダウンロードした設定ファイルを指定し、キーボード右上の小さい穴のリセットボタンを、安全ピンかクリップで押したら設定完了。
一回目はどうやってもここを押すしかありませんが、このリセットをキーボードに登録することができるので、設定しておくことをおすすめします。

## ちょっと使ってみて
通常のキーボードと違って、キー配置が直列な感じで、ある程度デフォルトのキーボードの配置を再現しようとすると意外とうまくいかなくて苦戦します。
これは慣れかもしれませんが。
私の今の設定している配置はこんな感じ。
https://configure.ergodox-ez.com/ergodox-ez/layouts/aWW53/latest/0

標準のキーボードにある、Shift + 1 で ！ みたいなのは、OSの言語設定に依るみたいです。
最初、Shift押して挙動を変える方法がないかと暴れまわった結果出来ないっぽいとしって悲しかった。

慣れれば最強の相棒になる予感は非常にしているので、これからガンガン使っていきたいと思います。



Ergodoxはいいぞ！！！
【DS】エクセル行を追加するときのカウントについて

<img width="216" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/ad182e6c-3314-838d-6c61-bb2cf0bdc6fa.png">
こんな感じで　set content of row のときにファインダーに
カウント使って追加することも可能
FreeMarkerでSpring Security JSPタグを使う

# やりたいこと
FreeMarker上で、 `<security:authorize>` などのJSPタグを使いたい。https://vorba.ch/2018/spring-boot-freemarker-security-jsp-taglib.html で紹介されていたことを、自分でも確認したい。

FreeMarkerには元々、JSPタグを使う機能があるらしい。→ [参考URL](https://freemarker.apache.org/docs/pgui_misc_servlet.html#autoid_63)

# 環境
- AdoptOpenJDK 11.0.5
- Spring Boot 2.2.2.RELEASE
    - Spring Security 5.2.1.RELEASE
    - Embedded Tomcat 9.0.29
- FreeMarker 2.3.29

# 依存性

```xml:pom.xml
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jsp-api</artifactId>
        </dependency>
    </dependencies>
```

Spring SecurityのJSPタグ（ `spring-security-taglibs` ）およびJSP API（ `tomcat-jsp-api` ）が必要なのがポイント。

# Java Configクラス

```java:SecurityConfig.java
@Configuration
public class MyFreeMarkerConfig {

    private final FreeMarkerConfigurer freeMarkerConfigurer;

    public MyFreeMarkerConfig(FreeMarkerConfigurer freeMarkerConfigurer) {
        this.freeMarkerConfigurer = freeMarkerConfigurer;
    }

    @PostConstruct
    public void init() {
        freeMarkerConfigurer.getTaglibFactory().setClasspathTlds(
                Collections.singletonList("/META-INF/security.tld"));
    }
}
```

TLDファイルのパスを指定するのがポイント。

# 画面の書き方

```html:index.ftlh
<#assign security=JspTaglibs["http://www.springframework.org/security/tags"]/>
<html>
<head>
    <title>Index</title>
    <meta charset="UTF-8">
</head>
<body>
<h1>Index</h1>
<@security.authorize access="isAuthenticated()">
    <p>Hello, <@security.authentication property="principal.username"/>!</p>
</@security.authorize>
<p><a href="/secret">Go to secret page</a></p>
<form action="/logout" method="post">
    <input type="submit" value="Logout">
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
</body>
</html>
```

`<#assign security=JspTaglibs["http://www.springframework.org/security/tags"]/>` でJSPタグを指定する。

タグを使う時は `<@security.タグ名 プロパティ名="プロパティ値">` 。

# コードの全体像
https://github.com/MasatoshiTada/freemarker-spring-security-sample
Flutterでassets内の音声ファイルを再生する

## はじめに
Flutterでassets内の音声ファイルを再生するのに、少し手間取ったのでメモとして残しておきます。

## 前提
次のプラグインを使用
- audioplayers : 0.13.7

音声ファイルは`assets/sounds`に配置

## コード

`pubspec.yaml`に次を追記します。

```yaml:pubspec.yaml
dependencies:
  audioplayers: ^0.13.7

flutter:
  assets:
    - assets/sounds/
```

ローカルファイルのみ再生可能なため、アセットからローカルファイルを作成するSoundManagerクラスを作成します。

```dart
class SoundManager {
  AudioPlayer audioPlayer = AudioPlayer();
  Future playLocal(String localFileName) async {
    final dir = await getApplicationDocumentsDirectory();
    final file = File('${dir.path}/$localFileName');
    if (!file.existsSync()) {
      final soundData = await rootBundle.load('assets/sounds/$localFileName');
      final bytes = soundData.buffer.asUint8List();
      await file.writeAsBytes(bytes, flush: true);
    } 
    await audioPlayer.play(file.path, isLocal: true);
  }
}
```

あとは、次の方法で再生できます。

```dart
final SoundManager soundManager = SoundManager();
soundManager.playLocal('$fileName.wav');
```

## 参考
[Playing from assets · Issue #5 · rxlabz/audioplayer · GitHub](https://github.com/rxlabz/audioplayer/issues/5)
[avoid_slow_async_io](https://dart-lang.github.io/linter/lints/avoid_slow_async_io.html)
vue.jsの<a href="#" v-on:click="openWindow">で別ウィンドウリンク開こうとしたら親ウィンドウのURLからパスパラメータが消滅した

久しぶりの投稿です。開発した際に躓いたポイントの備忘のため

#やりたかったこと

vue.jsにて作成したアプリ内のリンクから、別ウィンドウにて別サイトのURLを開きたい
ここではリンクを設置したルーターパスを`/link`とします。
下記のようなリンクのイメージ
`https://vuejsproduction.jp/#/link`
aタグリンクをクリックしたら別サイトが別ドメインにて開かれるように設計

#サンプルソース
いろいろ省略してますが悪しからず

```test.vue
<template>
<div>
 <p>こんにちは。<a hlef="#" v-on:click="openWindow">こちら</a>を押したら別ページに飛びます
</div>
</template>

<script>
 methods: {
  openWindow: function() {
   const url = "https://google.com"
   window.open(url, '_blank', 'width=1024,height=768,scrollbars=yes,resizable=yes')
  }
 }
</script>
```

#何が起きたか

サブウィンドウは開かれました。が、
親ウィンドウのアドレスバーが何やら不穏な感じに
`https://vuejsproduction.jp/#/`
vue-routerで定義しているパスパラメータ部分がすっぽり抜け落ちてしまっていますね。
親ウィンドウ側のURLは変化してほしくなかったので下記のように修正

#修正後サンプルソース

```test.vue
<template>
<div>
 <p>こんにちは。<a hlef="#" v-on:click.stop.prevent="openWindow">こちら</a>を押したら別ページに飛びます
</div>
</template>

<script>
 methods: {
  openWindow: function() {
   const url = "https://google.com"
   window.open(url, '_blank', 'width=1024,height=768,scrollbars=yes,resizable=yes')
  }
 }
</script>
```

`v-on:click`に`.stop`と`.prevent`をつけてあげたら大丈夫でした。

`.stop`でaタグイベントハンドラ自体の親要素への伝搬を止め、
`.prevent`でaタグのイベントを通常通り処理すべきでないと指示している感じらしいです。

参考URL：https://techblog.roxx.co.jp/entry/2019/02/08/122914