OmniAICreator/Qiita-1.07M huggingface dataset:
docker(11)docker file作ってみた


```dockerfile:dockerfile
From ubunt
MAINTAINER @kaizen_nagoya
WORKDIR /root
ENV HOME /root
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    wget \
    git \
    libssl-dev \
    libbz2-dev \
    libsqlite3-dev \
    libreadline-dev \
    zlib1g-dev \
    libasound2-dev \
    libxss1 \
    libxtst6 \
    gdebi
RUN wget -O vscode-amd64.deb https://go.microsoft.com/fwlink/?LinkID=760868
RUN yes | gdebi vscode-amd64.deb
RUN rm vscode-amd64.deb
RUN alias python='python3'
```
### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
Windows10上のHomesteadで、Laravel dusk環境を作る方法（Failed to connect to localhost対策含む）

今回は、Windows10上のHomesteadで、Laravel dusk環境を作る方法をまとめました。

なお、Windows10でのHomestead環境の構築は、下記の記事にまとめています。
■Windows10でのLaravel Homestead構築方法 まとめ
https://qiita.com/dog-ears/items/316fa754f1acee2274df

前提として、homestead環境およびLaravelのインストールは完了しているものとします。

###（１）Laravel duskのインストールおよび初期化

**■Laravel 5.8 Laravel Dusk（公式）**
https://readouble.com/laravel/5.8/ja/dusk.html

```
composer require --dev laravel/dusk
php artisan dusk:install
```

上記２行のみで準備完了。

```
php artisan dusk
```

で、ブラウザテストをできるはずなのですが、実行すると下記のエラーが出ます。

```
Failed to connect to localhost port 9515: Connection refused
```

どうも、Windows10上で構築したHomestead環境では、Chromeドライバーがおかしいらしいです。

（参考）■Homestead上でlaravelのdusk使おうとしたらFailed to connect to localhost port 9515: Connection refusedって言われる
https://twinbird-htn.hatenablog.com/entry/2019/05/10/002248

上記サイトを参考にさせていただきました。

まず、vagrantを立ち上げて、仮想マシンに入る

```
vagrant up
vagrant ssh
```

次に、chrome-driverのインストール

```
sudo apt install libnss3

sudo wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
sudo sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
sudo apt-get update
sudo apt-get install google-chrome-stable
```

これで、duskが実行できるようになりました。

なお、この方法ですが、

```
vagrant destroy --force
```

で、仮想マシンを削除、その後vagrant upしたときに再度行う必要があるようです。
限定共有記事を全体公開するとURLはどう変わるか

* 投稿前
https\://qiita.com/drafts/b02d92ed0e490ddaba2c/edit

* 限定共有投稿後
https://qiita.com/kurapooh/private/b02d92ed0e490ddaba2c

* 全体公開後
https://qiita.com/kurapooh/items/b02d92ed0e490ddaba2c
<p></p>
(補足) 限定共有時点のURLにアクセスするとリダイレクトされる
https://qiita.com/kurapooh/private/b02d92ed0e490ddaba2c
↓
https://qiita.com/kurapooh/items/b02d92ed0e490ddaba2c
多機能アプリは有能か？

#はじめに

スマートフォンが世に出回ってから多くのアプリケーションが開発され，我々はその恩恵を日々受けてる。スマートフォンが開発される以前の携帯電話，いわゆるガラケーを思い出して見て欲しい。はじめは電話だけの機能だっかが，メール機能も搭載されより便利になった。しかし，それだけに留まらず，その後も多くの機能が追加された。おそらくそれらの全機能を使っているユーザーは少なかったと思える。それらの機能の多くはあってもいいが，無くても困らない機能ばかりだ。そういう現象がアプリケーションでも起きていると感じるのである。

#多機能性の問題

一つのアプリケーションで多くのことができれば便利ではあるけれど，機能が増えれば増えるほど見にくくもなるし，バグも増えやすくなる。特にスマートフォンはPCやタブレットと比べ画面が小さい。そのため上手くボタンなどを配置しないと見づらいし尚且つ使いづらい。

機能が増えると，それらを一箇所にまとめたものが登場しやすい。いわゆる「ハンバーガーメニュー」だ。ハンバーガーメニューは開けるまでどんな機能があるのかわからない。それではユーザーフレンドリーとは言わないだろう。それらの機能の多くはあってもいいが，無くても困らない機能ばかりだ。それが一番厄介だ。でもよく考えてみると，ユーザーがほとんど使うことのない機能を追加するのは開発コストの無駄ではないか？

#機能追加の制限

機能を追加する開発費用や人材があれば，それらをセキュリーティーやデザイン性の向上に繋げた方がユーザーにとっても良さそうに思える。もちろん便利な機能は追加しても構わないが，追加するならその機能が本当に必要かを考える必要がある。本当に必要な機能のみ追加させることだ。そうでなければ，機能の追加はやめ，保守・点検に徹した方がよい。

#多機能アプリは有能か

少なくても多機能性とユーザーフレンドリーは別であると思える。それよりもデザイン性や安全性に優れたアプリケーションの方がユーザーフレンドリーである。必要な機能は時代とともに変化していく。その変化を柔軟に取り込み機能を拡張させる。不要と思われる機能は削除し，常に必要最小限の機能に留めておく。そのためには常に時代を読み，ユーザーが真に求めている機能を模索するのが大切である。最小限の機能で長く使えるアプリケーションが一番有能ではないだろうか。

#参考文献
[君たちはそんなにハンバーガーメニューが好きなのかね？](https://qiita.com/usagimaru/items/930de80062bdae880630)
KaTeXの数式をLaTeXの\[...\]と$...$で記述し，それをHugoで生成するページで表示する

この記事では，KaTeXでLaTeXと同じ数式表記（ディスプレイ数式に`\[...\]`，インライン数式に`$..$`）を使い，それをHugoで生成するページで表示させます。KaTeXでLaTeX表記を使う方法を説明したサイトは多く見つかりますが，中には情報が古くて最新版では動かず，あるいはHugoと組み合わせると動作しないケースもあります。ここでは，2019年5月現在で入手できるKaTeXとHugoの組み合わせで動作が確認できた方法を記します。以下のバージョンを使いました。

- Hugo 0.55.6
- KaTeX 0.10.2

# KaTeXでLaTeXと同じ書式で数式を記述する

KaTeXは，MathJaxよりも軽量で，高速に数式をレンダリングします。KaTeXのデフォルトの記法では，ディスプレイ数式には`$$..$$`を，インライン数式には`\(...\)`を使うことになっています。HTML内にスクリプトを記述すれば，LaTeX同様にディスプレイ数式を`\[...\]`で，インライン数式を`$...$`で記述できます。この方法は，以下のサイトで説明されています。

- [軽量な数式組版ライブラリ KaTeX の導入メモ ::: metric](https://www.t3nro.net/2017/04/katex)
- [Auto-render Extension - KaTeX 0.10.2](https://katex.org/docs/autorender.html)

KaTeXは cdn.jsdelivr.net が提供するものを使います。以下の内容をHTMLの`<head></head>`内に書き込めば，KaTeXのデフォルト表記に加えて，LaTeX同様の記述が可能になります。

```html 
<!-- 標準的な設定 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.10.2/dist/katex.min.css" integrity="sha384-yFRtMMDnQtDRO8rLpMIKrtPCD5jdktao2TV19YiZYWMDkUR5GQZR/NOVTdquEx1j" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.10.2/dist/katex.min.js" integrity="sha384-9Nhn55MVVN0/4OFx7EE5kpFBPsEMZxKTCnA+4fqDmg12eCTqGi6+BB2LjY8brQxJ" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.10.2/dist/contrib/auto-render.min.js" integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI" crossorigin="anonymous"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
  renderMathInElement(
      document.body,
      {
          delimiters: [
              {left: "$$", right: "$$", display: true},
              {left: "\\[", right: "\\]", display: true},
              {left: "$", right: "$", display: false},
              {left: "\\(", right: "\\)", display: false}
          ]
      });
  });
</script>
```

# HugoでKaTeXを使い，LaTeX同様の表記を受け付ける

## 意図通りに認識されない可能性

ヘッダを記述する`layouts/partials/header.html`を開き，上に示した内容を追加します。ただし，`\`がエスケープする記号とマークダウン表記が対立することがあり，エスケープがうまく働かない可能性があります。

いくつか試した結果，エスケープの有無と変換結果は以下の通りになりました。なお，この結果はテンプレートによって異なるかもしれません。自分がよく使う表記が認識されるよう，設定を練る必要があります。

||テンプレート設定|本文の記述|表示|
|:-:|:----:|:-:|:----:|
|ディスプレイ数式|`\\[...\\]`|`\\[A+B\\]`|$A+B$|
|              |           |`\[A+B\]`|[A+B]|
|              |           |`[A+B]`|[A+B]|
|              |`\[...\]`|`\\[A+B\\]`|\\[ A+B \\]|
|              |         |`\[A+B\]`|$A+B$|
|              |         |`[A+B]`|$A+B$|
|インライン数式|`\\(...\\)`|`\\(A+B\\)`|$A+B$|
|              |          |`\(A+B\)`|(A+B)|
|              |          |`(A+B)`|(A+B)|
|              |`\(...\)`|`\\(A+B\\)`|\\( A+B \\)|
|              |         |`\(A+B\)`|$A+B$|
|              |         |`(A+B)`|$A+B$|

## 数式レンダリングのオン・オフをファイルごとに切り替える

さて，もし文書ごとに数式をレンダリングするか否かを切り替えたいなら，新たにページ変数を作って動作を切り替えるとよいでしょう。たとえば，以下の例では，マークダウンファイルの先頭で`katex`という変数を定義しています。

```md 
title: "Test Page"
date: 2019-05-18T13:55:59+09:00
draft: false
katex: true
```

この変数が`true`のときだけ数式をレンダリングできるようにします。さきほど紹介した`layouts/partials/header.html`の`<head></head>`内に書くべきタグ全体を，以下のようなHugo関数で囲みます。

```html 
{{ with .Params.katex }}
<!-- 上記のlinkとscriptタグをここに記述 -->
{{ end }}
```

あとは通常の手順で`hugo`を動かせば，KaTeXを利用するHTMLファイルができあがります。
【視聴メモ】Modern Web Testing and Automation with Puppeteer (Google I/O ’19)

この記事は Google I/O '19 のセッションの視聴メモです。
想定読者は自分なので正確性や網羅率には問題があるかもしれません。

---

## References

https://www.youtube.com/watch?v=MbnATLCuKI4

Speaker(s): Andrey Lushnikov, Joel Einbinder

## Abstract

PuppeteerはChrome DevToolsチームによって開発されたChromeをテストし自動化するためのNodeライブラリです。このセッションでは、Puppeteerの簡単なセットアップの方法とHeadless Chromeを用いた興味深いユースケースの紹介を行います。

## Contents

* PuppeteerをセットアップしてECサイト（発表者が発表者のグッズを売っている）の商品の値段を監視するスクリプトを書いている
    * 6行で書けてとても簡単
* **PuppeteerでFirefoxも制御できるようになった**
    * `npm i puppeteer-firefox`
    * Puppeteer APIの90%をカバーしている実験的プロジェクト
* クロスブラウザテストが簡単に書ける！
* テストが遅くなるのはなぜか
    * 各テストのたびに新しくブラウザを立ち上げているから
        * それぞれのテストが独立するのは良いことなんだけど…
        * PuppeteerはChromeのincognitoモードをベースに使っているのでブラウザを立ち上げ直さなくてもテストが独立になる
        * いちいち立ち上げ直すより100倍速い

```
const browser = await puppeteer.launch();
const context = await browser.createIncognitoBrowserContext();
// -> contextごとに操作する
```

* WebテストはFlaky（同じテストでもpass/fail両方起きてしまう）
    * テストをリトライするというのがよくある解決策だが、もっと良い方法もある
    * ボタンが非同期的にレンダリングされる場合など、表示されているときとされていないときで結果が変わる
        * レンダリングを1秒待ってみたりする解決策がある → それでもFlakyだし時間がかかる
        * `waitForX` API
        * `page.waitForSelector` でボタンが表示されるのを待てる
    * `page.waitForResponse`でネットワークリクエストのレスポンスも待てる
* Puppeteer is fast, reliabble, and simple
* `page.emulate(puppeteer.devices['iPhone 8'])` でモバイルのエミュレートもできる！
    * 画面サイズ、User Agent、DPI、タッチ、ランドスケープモードなどが制御できる
    * 100個以上のデバイスをサポートしている
* オフラインモードもテストできる
    * Service Worker もテストしていこう
    * SWオブジェクトを生成して処理をevalできる
        * デモではキャッシュがヒットするかどうかのテストをしていた
* Geolocation
    * devtoolでロケーションは設定できるけどめんどくさいよね
    * もちろんPuppeteerでも制御できます
* request interception
    * `page.setRequestInterception` でネットワークリクエストの監視と変更ができる
* マウスイベント
    * そもそも素のJSでマウスイベントを発行できるが本当にマウスを動かしているのとは挙動が違うことが多い
* Purformance testing
    * `page.metrics`で基本的な情報は取れる
        * JSのヒープサイズなどが取れる
    * `page.tracing`でChrome DevtoolのPerformanceと同じことができる
* Accessibility
    *  `page.accessibbility.snapshot`でDOM要素のアクセシビリティを確認したりできる
    *  Accessibility Visualizer
        *  https://github.com/GoogleChromeLabs/html-a11y-renderer
* Size Limit
    * https://github.com/ai/size-limit
        * Puppeteerを利用してコードサイズや実行時間を図るツール
            * Puppeteerを使っているので様々なネットワーク環境&デバイスを再現できる
    * https://github.com/pocketjoso/penthouse
        * 上記のCSSバージョン

* 詳しくは pptr.dev

## Memo

* 発表者もPuppeteerの発音が難しそうな感じだった
* 自分のグッズを売るためのECサイトを作りたくなった
* Firefoxサポートすごい
* Accessibilityの確認はすごく難しいのでPuppeteerがもっと便利になってAccessibilityに気を使うサービスが増えていけばいいと思った
generator/yeildとasync/awaitの共存の可否

# 目的
既存のコードで[co](https://github.com/tj/co)を用いたgenerator/yeildを使っていたが、
co自体がもう更新されなくなってきているためにasync/awaitに置き換えることになった。
作業中両者が混在することになるが、
その時どのような振る舞いをするかわからなかったので試した。

# 結論
asyncをyieldで待つことは**可能**
generatorをawaitで待つことは**不可能**

# 実行環境
* Windows 10
* Node.js 10.15.3
* TypeScript 3.4.1?
* co 4.6.0

# コード
5秒間待つ処理をするPromiseをgeneratorとasyncで覆って、
それぞれをyield、awaitで待つ4通りを試す。

<details><summary>長いので折り畳み</summary><div>

```javascript

const co = require('co');

const waitTime = 5000;
function execute() {
    generator_yield();
    async_await();
    async_yield();
    generator_await();
}

execute();


function generator_yield() {
    co(function* () {
        let result = yield generatorFunction('generator_yield');
        console.log(result);
    });
}

function async_await(){
    (async() => {
        let result = await asyncFunction('async_await');
        console.log(result);
    })();
}

function async_yield() {
    co(function* () {
        let result = yield asyncFunction('async_yield');
        console.log(result);
    });
}

function generator_await() {
    (async () => {
        let result = await generatorFunction('generator_await');
        console.log(result);
    })();
}

function* generatorFunction(callee: string){
    return timer(callee);
}

async function asyncFunction(callee: string) {
    return timer(callee);;
}

function timer(callee: string){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(callee);
        }, waitTime);
    });
}
```
</div></details>


# 結果
```
// generator/awaitの組み合わせだけ、5秒待たずに即座に表示される

{ next: [Function],
  throw: [Function],
  return: [Function],
  [Symbol(Symbol.iterator)]: [Function] }

// 5秒待ってから表示される
generator_yield
async_yield
async_await
```

# 結論
asyncをyieldで待つことは**可能**
generatorをawaitで待つことは**不可能**

そのためgenerator/yeildからasync/awaitに置き換えるときは、
呼び出される関数から先にasync/awaitに置き換えていく必要がある。

# 感想
そもそもgeneratorとは何なのかふんわりとしか把握していないのが怖い。
【視聴メモ】Going Big: PWAs Come to Desktop and Chrome OS (Google I/O ’19)

この記事は Google I/O '19 のセッションの視聴メモです。
想定読者は自分なので正確性や網羅率には問題があるかもしれません。

---

## References

https://www.youtube.com/watch?v=2KhRmFHLuhE

Speaker(s): Paul Covell, Dominick Ng

## Abstract

PWAはもはやモバイルだけのものではありません。このセッションではどうやってDesktop PWAをビルドするのか、それらならではの機能、ベストプラクティスといったことを紹介します。

## Contents

* Webのユニバーサリティをもっと色んな所に持ち込もう
* PWAが始まったのは２０１５年のAndroidから
* SketchUp
    * Desktopで動くことを前提としたPWA
    * １つのコードベースで３プラットフォーム（Windows, Mac, ChromeOS)
* Write once, run anywhere
* しかも既存のサイトにいくつか追加の要素を追加するだけ
* Web App Manifest
    * PWA用の設定ファイル
    * `start_url`: デスクトップアプリとして開くときの起点のURL
    * `display`: `standalone`を指定するとデスクトップアプリとして追加できる
    * `theme_color`: デスクトップアプリとして起動するときのタイトルバーのカラー
* Service Worker
    * WorkBox使って簡単にSWを書ける
        * CSSは基本的にキャッシュしてバックグラウンドでアップデートしたり
* Desktop PWAはリンクで共有できるしSearchに出てくる
    * アプリのダウンロードリンクが「追加する」リンクに置き換わるとアプリを追加する心理的抵抗が非常に少なくなる
* インストールのアクションも開発者が制御できる
    * ページを初めて訪れたときがデフォルトだが、ユーザーのエンゲージメントが高い瞬間に出すように制御できる
    * Spotifyではページ上にインストールリンクがあって、それがクリックされたときに追加できる
* インストール後のイベントも取れる
* Chrome76からオムニボックス（Chromeの検索ボックス）にインストールボタンが追加される
* ビジネスインパクトの話
    * HuluがネイティブからPWAに舵を切った
    * Chromeブックで試してみたらなんの問題もなかった
    * 数ヶ月で96%のユーザーがネイティブからPWAに移行した
    * 再訪問率が27%増加し、エンゲージメントは5.5%増加した
* Native File System API
    * Not virtual but real!
* PWAアプリの起動時の動作制御
    * モバイルと違って複数ウィンドウが立ち上がることが期待されるときがある
    * ウィンドウを立ち上げたり立ち上がっているウィンドウにフォーカスしたりするAPIが開発中

デスクトップ開発状況

* ファイルシステムとウィンドウ制御のAPIは年末には入る予定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3387/1cc4673a-3acb-2a69-7e63-761b8e84cca5.png)

## Memo

* モバイルと共通している内容も多く聞きやすかった
* Chrome 76から追加されるオムニボックスのインストールボタンが激アツすぎる
    * インストールという行為の心理的抵抗がまったくなくて良い
* ウィンドウ制御APIがどんな形になるのか想像がつかないがとても楽しみ
Excelでお手製タブ作成メモ


# Excelでお手製タブ作成メモ
## 内容
Excelのタブを自作できることを知り[先人の記事](https://qiita.com/tomochan154/items/3614b6f3ebc9ef947719#%E3%83%AA%E3%83%9C%E3%83%B3-ui-%E3%81%AF-xml-%E3%81%A7%E5%AE%9A%E7%BE%A9%E3%81%97%E3%81%BE%E3%81%99)を参考に作成した際に躓いたポイントのメモ
「タブ名」タブがお手製のタブ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228134/e686c619-fde0-feab-29d3-2338c0738dfc.png)



## メモ
- Zip化するときはフォルダにまとめず対象を選択して圧縮する必要有り。フォルダにまとめると階層が深くなり構成が変わる
> XML ファイルを保存して ZIP ファイルにまとめてから拡張子を .xlsx に変更します。

- _rels/.relsファイルRelationship要素の属性名の表記について`id,type,targetの属性名をId,Type,Targetに変更`する
- customUI14.xmlファイルのxml宣言を明記して↓のようにする

```xml:customUI14.xml
<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" xmlns:mso="http://schemas.microsoft.com/office/2009/07/customui" onLoad="CustomUI.OnLoad">
  <ribbon>
    <tabs>
      <tab id="SampleTab" label="タブ名" getVisible="CustomUI.SampleTab_getVisible">
        <group id="SampleGroup" label="グループ名" centerVertically="true">
          <box id="SampleBox" boxStyle="horizontal">
            <editBox id="SampleText" label="サンプルテキスト" sizeString="wwwwwwwwwww" getText="SampleTab.SampleText_getText" onChange="SampleTab.SampleText_onChange"/>
            <button id="SampleButton" label="検索" imageMso="FindDialog" size="normal" onAction="SampleTab.SampleButton_onAction"/>
          </box>
        </group>
      </tab>
    </tabs>
  </ribbon>
</customUI>
```
※ファイルの文字コードをUTF-8で保存したのでUTF-8で宣言していますがSJIS等の場合はShift-JISで宣言が必要
※customUI.xmlを作成せず、customUI14.xmlのみで作成

## 環境
Windows10 Home
Excelのバージョン 1904

## 参考
[Excel のリボンUIを業務アプリとして使う](https://qiita.com/tomochan154/items/3614b6f3ebc9ef947719)
Seleniumでログインが必要なシステムから複数ページを跨いでデータを採取する

毎日特定の社内システムにログインしてデータを採取し、確認するのだが、
複数ページにまたいでのデータ採取であり面倒なため、スクレイピングで自動でデータ集めができないか実施した。
Seleniumでログインして、欲しいデータのタグからデータをリストにまとめる。


ライブラリをインポート

```
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
```

ウェブブラウザがIEであるため、IEDriverServer.exeを同じ階層にダウンロード
階層が違う場合はアドレスを指定する。
入力する場所のidタグをdriver.find_element_by_idで探索し、send_keysでIDとPASSを入力して、click()にてログインする。

```
URL="ログインページのアドレス"
driver = webdriver.Ie('IEDriverServer.exe')
driver.get(URL)

ID=""
PASS=""

driver.find_element_by_id('IDを入力するスペースのid').send_keys(ID)
driver.find_element_by_id('passwordを入力するスペースのid').send_keys(PASS)
driver.find_element_by_id('loginボタンのid').click()

matome=[]
blank=""
```



driver.find_element_by_idで欲しいidのデータをスクレイピングできる
ここではページの遷移も伴うので、driver.getでページを移動する。
ページの読み込みを待たないとErrorになるので、WebDriverWaitでidが読み込めるまで待つ

```
ページその１
driver.get("ページその１のアドレス")

WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'data_1_id')))

data_1=driver.find_element_by_id("data_1_id").text
data_2=driver.find_element_by_id("data_2_id").text
data_3=driver.find_element_by_id("data_3_id").text
data_4=driver.find_element_by_id("data_4_id").text

for i in (data_1,data_2,data_3,data_4):
    matome.append(i)

ページ2
driver.get("ページ２のアドレス")

WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'data_5_id')))

data_5=driver.find_element_by_id("data_5_id").text
data_6=driver.find_element_by_id("data_6_id").text
data_7=driver.find_element_by_id("data_7_id").text

for i in (data_5,data_6,data_7):
    matome.append(i)   

for n in matome:
    print(n)

```

実際はこれがページ５つ分あるが、これ以降は同じものの繰り返し。
これで自動で複数ページのデータをまとめてくれる
MacOS MojaveでVirtualBoxがインストールできないときの対策

![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403659/f8e5062d-98a0-5b63-3f4e-80a1092bc17c.png)

WEB系エンジニア転職にむけてMacBookProを購入しましたが、Rails学習前のローカル環境設定でいきなりハマりました。
いろいろ試して解決したのでシェアします。

## 環境
- MacBookPro corei7 16GB 512GB
- macOS 10.14.5 Mojave

## 症状
1. VirtualBoxがインストールできない。
2. インストールできてもvagrant up できない。

## エラー

```
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["hostonlyif", "create"]

Stderr: 0%...
Progress state: NS_ERROR_FAILURE
VBoxManage: error: Failed to create the host-only adapter
VBoxManage: error: VBoxNetAdpCtl: Error while adding new interface: failed to open /dev/vboxnetctl: No such file or directory
VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component HostNetworkInterfaceWrap, interface IHostNetworkInterface
VBoxManage: error: Context: "RTEXITCODE handleCreate(HandlerArg *)" at line 94 of file VBoxManageHostonly.cpp
```

```
mbp:MyCentOS kawahara$ vagrant ssh
VM must be running to open SSH connection. Run `vagrant up`
to start the virtual machine.
mbp:MyCentOS kawahara$ vagrant status
Current machine states:

default                   aborted (virtualbox)

The VM is in an aborted state. This means that it was abruptly
stopped without properly closing the session. Run `vagrant up`
to resume this virtual machine. If any problems persist, you may
have to destroy and restart the virtual machine.
```

```
Vagrant was unable to mount VirtualBox shared folders. This is usually
because the filesystem "vboxsf" is not available. This filesystem is
made available via the VirtualBox Guest Additions and kernel module.
Please verify that these guest additions are properly installed in the
guest. This is not a bug in Vagrant and is usually caused by a faulty
Vagrant box. For context, the command attempted was:

mount -t vboxsf -o uid=500,gid=500 vagrant /vagrant

The error output from the command was:

/sbin/mount.vboxsf: mounting failed with the error: No such device
```

## 対策

「VirtualBox製造元のOracleにkextを渡せばOK」

以下超訳です。

- Macのセキュリティが厳しくてVirtualBoxインスコできひんやん！
- なんやて！そんならセキュリティガバガバにして強制インスコや！
- さすがにそれはやりすぎやろ！
- せや！オラクルさんだけ特別に通行証渡したらええやん？

## 手順
1. Macをセーフモードで起動。（⌘+R押しっぱなし）
2. メニューバーからターミナルを起動。
3. ターミナルで下記のコードを入力しEnter。
4. Macを通常モードで再起動。

```
spctl kext-consent add VB5E2TV963
```

以上です。ありがとうございました。


## 参照

- [macOS 10.14.5 Mojaveアップデート後に仮想化ソフトウェア「VirtualBox」がインストール出来ない問題が発生しているとしてOracleが対応中。 \| AAPL Ch.](https://applech2.com/archives/20190517-virtualbox-kext-block-on-macos-10145-mojave.html)
- [macOS MojaveでVagrantが使えなくなった時の対処法 - Qiita](https://qiita.com/ShotaKameyama/items/35e9b860d26c28f306f4)
ResponderでCorsを有効にするメモ

# とりあえず動かす

```python
from responder import API


api = responder.API(cors=True, cors_params={
    'allow_origins': ['*'],
    'allow_methods': ['*'],
    'allow_headers': ['*'],
})
```

詳しいことは[このページ](https://qiita.com/y_k/items/6e4da3bef5c8d8bd2730#cors)を参照してください。
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException の回避策

毎回忘れる

正しい
====
`disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)`

```java
    public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
            .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
```

> Feature that determines whether encountering of unknown properties (ones that do not map to a property, and there is no "any setter" or handler that can handle it) should result in a failure (by throwing a JsonMappingException) or not. This setting only takes effect after all other handling methods for unknown properties have been tried, and property remains unhandled.
Feature is enabled by default (meaning that a JsonMappingException will be thrown if an unknown property is encountered).



間違い
====
`.enable(Feature.IGNORE_UNKNOWN)`


> Feature that determines what to do if the underlying data format requires knowledge of all properties to output, and if no definition is found for a property that caller tries to write. If enabled, such properties will be quietly ignored; if disabled, a JsonProcessingException will be thrown to indicate the problem. Typically most textual data formats do NOT require schema information (although some do, such as CSV), whereas many binary data formats do require definitions (such as Avro, protobuf), although not all (Smile, CBOR, BSON and MessagePack do not).
Note that support for this feature is implemented by individual data format module, if (and only if) it makes sense for the format in question. For JSON, for example, this feature has no effect as properties need not be pre-defined.
Feature is disabled by default, meaning that if the underlying data format requires knowledge of all properties to output, attempts to write an unknown property will result in a JsonProcessingException
Since:
2.5
Graph Theory

今日は、初投稿で緊張しています。頑張るのでご鞭撻のほどよろしくお願いいたします。私の一番の関心は量子アルゴリズムとそれに関わる分野です。したがって、そのような投稿が多いです。今日は私の勉強しているグラフ理論について軽い説明です。

今回は専門用語の説明。
vertex:頂点
edge:辺
parallel:２つの辺が同じ頂点を持つ
simple:ループとパラレルがない辺
empty:辺なし
null graph:頂点、辺ともになし
trivial:１つの頂点
adjacent:共通の頂点を共有している状態
end vertices:　最後の頂点
degree:　辺の数
pendant vertex:　degreeが１
pendant edge:辺がpendant vertexを持っている
isolated vertex:　辺の数がない頂点

これから勉強をすすめ説明できるようにします。
P.S.現在、qikit, bluqat、quantum annilingの勉強をしています。qiskitはラトビアの学習グループに所属しているので比較的得意な分野です。お互いの知識を共有、高めあえる仲間を募集中です。
Cloud Run を Firebase Hosting の rewrite で使うときの注意

CloudRun は単体でもカスタムドメインを使うことができますが、Firebase の Hosting rewrite 機能を使うこともできます。この場合は Firebase の CDN が利用できるので Cache-Control でキャッシュさせることができて便利です。使い方も Cloud Functions と同じで簡単です。

### firebase.json

```json
{
  "hosting": {
    "rewrites": [
      {
        "source": "/example/foo/**",
        "run": {
          "serviceId": "foo-run",
          "region": "us-central1"
        }
      }
    ]
  }
}
```

Cloud Run のコンテナ名が `foo-run` の場合は、それをそのまま serviceId に指定してあげるだけです。今は beta なので region は us-central1 だけです（ただ Cloud Functions の rewrite は us-central1 限定なので Cloud Run もそうなるかもしれません）。

これだけで CDN を有効にして rewrite できます。

### ここが注意

ただし、注意しなくてはならなのはデプロイする環境の `firebase-tools` は最新である必要があります。

```
$ npm install -g firebase-tools@latest
```

Cloud Run 自体は正常に動いているけれど、 Firebase Hosting 経由だと動かない場合はデプロイした環境の `firebase-tools` が最新かどうかを確認してください。
ガチャ試行回数・出現確率と当選確率の関係

#まえがき　　
ソーシャルゲームにおいてどれだけの確率で当たりを引くか(当選確率)は、課金や、高レアのキャラクターやアイテムが当たるまでリセットし続けるリセットマラソン(リセマラ)を行う基準となるので重要である。これまで、多くのインターネット上の記事では、試行回数・出現確率が決まっている時の当選確率が議論されてきた。しかし、試行回数や出現確率を変化させた時の当選確率は、ほとんど議論されていない。そこで本稿では、出現確率($P_s$)、試行回数(N[回])と当選確率の関係を明らかにする。
#当選確率の導出
出現確率$P_s$、試行回数N[回]までにおける当選確率は、確率の余事象を用いて以下のように求められる。

```math
\begin{split}
当選確率 &= 1-すべて外れる確率\\
&= 1-(出現しない確率)^N\\
&= 1-(1-P_s)^N
\end{split}
```
当然、以下のように二項分布を用いて直接求めることもできる。

```math
\begin{split}
当選確率 &= \sum_{k=0}^{N-1} {}_N \mathrm{C}_k (1-P_s)^k(P_s)^{N-k}
\end{split}
```
しかし、計算回数がより少ない方が計算時間が短く済むので、余事象を用いる方法を採用する。
#性能評価
縦軸：当選確率・横軸：試行回数(当選確率 vs 試行回数(N))のグラフ、縦軸：当選確率・横軸：出現確率(当選確率 vs 出現確率($P_s$))のグラフを描画することで性能評価を行う。本稿では、試行回数が増加しても$P_s$は変化しないものとする。
なお、グラフ描画と計算がまとめてできるためExcelを用いて計算を行った。
##性能評価諸元
ソーシャルゲームにおける最高ランクアイテムの$P_s$は、概ね0.005～0.03(=0.5%～3%)である。さらに、一般に$P_s$=0.01、N=100の時、当選確率は、約0.63(=63%)であることが知られている。
そこで今回、用いる性能評価諸元は以下のようにする。

ガチャ1回当たりの値段：300円

当選確率 vs 試行回数(N)のグラフ
$P_s$：0.005, 0.01, 0.03
$N$：0, 1, ..., 199, 200

当選確率 vs 出現確率($P_s$)のグラフ
$P_s$：0, 0.001, ..., 0.045
$N$：100, 200, ..., 600

##当選確率 vs 試行回数(N)のグラフ
当選確率 vs 試行回数(N)のグラフは以下のようになる。
![当選確率vs試行回数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370312/55546ae4-4b5d-d1ae-9fcb-5c4934fe5821.png)
##当選確率 vs 出現確率(Ps)のグラフ
当選確率 vs 出現確率(Ps)のグラフは以下のようになる。
![当選確率vs出現確率.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370312/acf65082-33ee-f2e2-f544-491721c90eb2.png)
#考察
　当選確率 vs 試行回数(N)のグラフからN>140の時、全ての$P_s$で当選確率>0.5を達成している。
　さらに、$P_s$=0.03の時、N=170で当選確率=1を達成できることが分かる。ここから、$P_s\geqq 0.005$の場合、42000円以上課金すれば50%以上の確率で最高ランクのアイテムが入手できることが分かる。
　また、当選確率 vs 出現確率(Ps)のグラフから$P_s$=0.005の時、N$\geqq$300の時、当選確率$\geqq$0.75を達成する。ここから、90000円課金することで75％以上の確率で最高ランクアイテムが入手できる。
　さらに、$P_s$を固定した時、Nの増加量に対する当選確率の増加量は、Nが大きくなるにしたがって小さくなる(ex. $P_S$=0.01の時、N=100からN=200に増加した時の当選確率は約23ポイント増大しているが、N=200からN=300に増加した時の当選確率は約10ポイントしか増加しない。)
　ここから、出現確率が常に一定のガチャの場合、課金すればするほど割に合わないといえる。
　さらに、$P_s\geqq$0.024の時、N$\geqq$100で当選確率=0.9を達成する。
　ここから、$P_s\geqq$0.024の時、30000円課金することで90%以上の確率で最高ランクのアイテムが入手できる。
#まとめ
本項では、出現確率($P_s$)、試行回数(N[回])と当選確率の関係を明らかにした。ここから
$P_s\geqq 0.005$の場合、42000円(300円/回)以上課金すれば50%以上の確率で最高ランクのアイテムが入手できることを明らかにした。さらに、出現確率が常に一定のガチャの場合、課金すればするほど当選確率の伸びが悪くなり、割に合わなくなることも明らかにした。
#最後に
本稿はソーシャルゲームで課金しているユーザを非難しているものではありません。あくまでも、計算したらこうなるということを示し、その結果を基に考察したものです。
ビットコインについて300時間で学んだ内容を3分に要約して説明します

１ヶ月間、毎日10時間程度ビットコインについて学習しました。
ビットコインって何？って疑問に対して、超重要な要点だけまとめて記述します。

<h2>ビットコインって？</h2>
ブロックチェーン技術を用いた電子通貨です。

<h2>普通の電子通貨とどう違うの？</h2>
中央となる単一のデータベースが存在せず、分散型ネットワークにデータがある電子通貨です。

<h2>分散してると何が嬉しいの？</h2>
中央管理をしていると、ハッキングや発行主体の不正といった通貨の信用リスクを生みます。

実際に過去に非分散型の電子通貨がハッキングされたり、政府の法律によって潰されたりといった事が原因で総額10億ドル規模の電子通貨が崩壊した事例がいくつかあります。

分散ネットワーク上で管理されていれば単一の攻撃点が存在しないため、信用リスクは極めて低いです。

<h2>ブロックチェーンって？</h2>
分散型のデータベースを成り立たせる仕組みです。

データベースが分散しているということは、複数の相互に矛盾したデータがネットワーク上に存在する可能性があります。

そのデータの矛盾を、プルーフオブワークと言うアルゴリズムを用いることによって、無矛盾の状態に収束させる仕組みがブロックチェーンです。

<h2>プルーフオブワークって？</h2>
計算コストの投資をデータの信用性の証明とする仕組みです。

簡単に言うと以下の2要素によって成り立っています。

1.正しいデータを生成すると報酬をもらえるインセンティヴ構造
2.データを生成するのに莫大な計算コスト（電気代）が必要となる

みんなは正しいデータを生成してインセンティヴを得ようとします。

不正なデータを作ろうと思うと、みんなの計算パワーを超えるコストを支払ってデータを生成する必要があります。
(莫大なコストを払って書き換えてしまうのが51%攻撃)

プルーフオブワークとは、こんなに計算コストをかけられたデータだから貴重なものだ、書き換えられるはずがないものだ、と言うようなニュアンスです。
JavaScript(制御構文)

#　制御構文とは？
普通プログラムは記述された順番で処理を実行するものですが、実際にはユーザーの入力や操作によって処理を分岐させる必要があります(例えば、1000円以上買うと10%オフ、それ未満は割引なし)。
JavaScriptでは、このように処理を分岐するための制御構文がいくつか用意されています。本日はそれらについて書こうと思います。

# if文
名前の通り「もし〜なら、〜する」という処理を行う構文です。
実際に書いてみます。

```js
if(条件式){
条件式がtrueの場合に実行する命令
}else{
条件式がfalseの場合に実行する命令
}
```
上記が基本的な書き方になります。ここではelseを書いていますが、trueの場合にしか処理を実行したくない場合はelseはなくても大丈夫です。
しかし条件式が一つしか書けないのなら、あまり汎用性がありません。でも大丈夫です。条件式は複数書くことができます。以下の書き方をみてみましょう。



```js
if(条件式1){
条件式1がtrueの場合に実行する命令
}else if(条件式2){
条件式2がtrueの場合に実行する命令
}
...
}else{
全ての条件式がfalseの場合に実行する命令
}
```
上記のようにif else(条件式n)を使えば必要となる分岐の数だけ列記できます。
では実際に条件式を書いて挙動を確認しましょう。

```js
var age = 10;  //変数を定義
if  (x >= 10) {
console.log("私の年齢は10歳以上です");
} else {
console.log("私の年齢は10歳未満です");
}                                        //result: 私の年齢は10歳以上です
```
もし変数ageが10未満の場合はelse以降の命令が実行されます。
次に複数の条件式を書いてみましょう。

```js
var x = 30;
if (x >= 20) {
console.log("xは20以上です");
}else if (x >= 10) {
console.log("xは10以上です");
} else {
console.log("xは10未満です");
}                           //result: xは20以上です
```
ちょっとこれはおかしいですね。x>=20 とx>=10はどちらとも条件に適合しています。しかしx>=20の時の処理しか実行されていません。しかししかしこれは正しい挙動です。説明するとif文は、複数の条件に合致する場合でも実行されるのは最初の1つだけなのです。なのでif文は条件に合致する条件を見つけると以下の条件に目を通すことなくif文を終了してしまうというわけです。

#for文
この構文は指定された回数だけ繰り返し処理を行う構文です。
実際に書いてみます。

```js
for (初期化式; ループ継続条件式; 増減式) {
ループ内で実行する命令
}
```
なんだかよくわかりませんね。まあ、実際に条件式に実際の値を入れて確認してみましょう。

```js
for (var x=8; x < 10; x++) {   
console.log("xの値は" + x);
}                         //result: xの値は8, xの値は９
```
説明していきます。まず初期化式でx=8と定義しています。最初のループだけこの初期化式が実行されます。よって最初のループではx=8なのでループの条件式にも適合し命令が実行されます。次に2回目のループです。2回目以降では初期化式は実行されません。よって現在のxの値に+1(x++)されx=9となります。9はループ継続条件に適合しているので命令が実行されます。続いて3回目のループですが現在のxの値(9)に+1するとx=10となります。ループ条件式をみてみるとx<10となっています。よってループ継続条件式の条件に外れてしまいます。ここでループが終了します。

#####for文を用いて配列を順番に取り出してみる
実際にコードを書きます。

```js
var data = ['apple','orange','banana']   //配列
for(var i=0; i < data.length; i++){
console.log(data[i]);
}
```
先ほど行ったfor文と違うところはループ条件式ですね。i<data.lengthはどういうことなのでしょうか？配列にはインデックス番号というものが割り振られています。上記の配列は0,1,2のインデックス番号が割り振られています。(0から始まるので注意。)上記コードのconsole.logをみてみるとiがインデックス番号を示していることがわかると思います。これを踏まえてもう一度ループ条件式をみてみるとなんとなくわかると思いますが、data.lengthは配列の長さ?を示しています。つまりi<3ということです。よってインデックス番号が0~2までループされるので配列の中身は順に出力されます。

# 最後に
HUNTERxHUNTERはよ連載してくれ:sob:
libsoundioを使ってみる。

# はじめに

最近、自作のシンセサイザーを作り始めているのですが、結構実装が楽だったので使ってるライブラリについて軽く情報を残しておきます。

## libsoundio

http://libsound.io/

オーディオのコールバック命令やイベント実行待ち等がすでに実装されているライブラリ。
（内部にスレッド使っててマルチスレッド的に処理可能みたい）

WindowsだとWASAPIとJACKが使える模様。
ただ自分はWASAPIだけ使う考え。デフォルト設定でつなぐ。
どうも列挙型SoundIoBackendの順番で取得しに行くっぽい。

## 実装例

公式ページの「Basic Sine Wave Example」を参照。
コールバック関数を用意すれば簡単にオーディオ再生の実装が出来上がる。

ちなみになんかアクションを行う場合、コールバック変数において書き込むバッファの数値を小さくするとレスポンスが早くなるけど、なんかシーケンス走らせてる場合それとは別に秒数を制御してデータを書き込む必要があるのに注意。

あと実装サンプルだとsample_rateが48000になってるけど、これを44100Hzにしたい場合、以下の手順で実装しておくこと。

- soundio_outstream_create()関数でSoundIoOutStreamのデータ取得
- SoundIoOutStream内のメンバであるsample_rateに44100をアサイン（他の数値も一緒に定義しとくと間違いがない）
- soundio_outstream_open()関数を実行
- soundio_outstream_start()関数を実行

ということはダウンサンプリングする場合は別途値を持っている必要がありそう。
（未確認だけど）

## 実装例

https://twitter.com/__machia__/status/1129654105327038466
https://twitter.com/__machia__/status/1125313931273052160

とりあえず位相を補正したサイン波とか波形メモリ音源を実装できてます。
IF周りも調整予定。（今の所dear imgui使ってサクッと実装しているのみ）

## 注意事項

あ、注意なのがDirectSound/XAudio2/ASIOについてはライブラリ側で対応してない部分ね。つまり上記API使う場合は別途定義したりオーディオレンダリングは別途スレッド立てる必要があるってことね。
だから実際のところ上記APIも組み込む場合はオーディオのクラス作ってそこにまとめてしまう実装になるかも。
（自分の場合XAudio2は不要としてlibsoundioだけで作ってる。今後必要なら上記方法でまとめる予定）

## おわりに

ライセンスはMITっぽいので、取扱もすごい楽。
現在、このライブラリ使ってシーケンサ＋シンセを実装中。
線形重回帰による決定係数の算出とモデルの選択 part_2

# はじめに
　線形回帰を実施するとき、どのモデルが最も効率が良いのか試行する。データはscikit-learnのbreast_cancerを用いて実装する。このデータはウィスコンシン乳癌データセットと呼ばれるもので、腫瘍が良性であるか悪性であるかを判定したものである。データは569あり、そのうち良性は212、悪性は357、特徴量は30種類ある。これらのデータを用いて腫瘍が良性か悪性かを判定するモデルを作成し、最も決定係数が高くなるものを選択する。

　前回、[線形重回帰による決定係数の算出とモデルの選択](https://qiita.com/FujiedaTaro/items/4ef757370ca19abe783c)にて線形回帰、Lasso回帰、Ridge回帰、ElasticNet回帰の決定係数を求めた。ElasticNet回帰のli_ratioは0.5のみ実施したため、決定係数が最大となるli_ratioと決定係数を求める。

#シリーズ
- [線形重回帰による決定係数の算出とモデルの選択](https://qiita.com/FujiedaTaro/items/4ef757370ca19abe783c)
- [線形重回帰による決定係数の算出とモデルの選択 part_2](https://qiita.com/FujiedaTaro/items/a7a23ce321f7733ae9cf)
- [単回帰分析による寄与率の算出](https://qiita.com/FujiedaTaro/items/090bad07672c322bceeb)
- [線形回帰と特徴量の絞り込み](https://qiita.com/FujiedaTaro/items/3fd874ae91b511eb1d1f)
- [ロジスティック回帰(分類)とハイパーパラメータのチューニング](https://qiita.com/FujiedaTaro/items/5784eda386146f1fd6e7)
- [線形SVC(分類)とハイパーパラメータのチューニング](https://qiita.com/FujiedaTaro/items/3e469688ad6f0dca62c0)
- [非線形SVC(分類)とハイパーパラメータのチューニング](https://qiita.com/FujiedaTaro/items/e5583f8767173e6a6f9a)
- [決定木とハイパーパラメータのチューニング](https://qiita.com/FujiedaTaro/items/47e06c758b451cbda412)
- [決定木とハイパーパラメータのチューニング２](https://qiita.com/drafts/0cc107bd69e9a0d2ce38/edit)

# 前回の結果
|線形回帰の手法|メソッド|汎化手法|決定係数|
|:---|:---|:---|:--:|
|線形回帰|LinearRegression()|-|0.73|
|Lasso回帰|Lasso()|L1正則化|0.61|
|Ridge回帰|Ridge()|L2正則化|0.72|
|ElasticNet回帰|ElasticNet()|L1 & L2正則化|0.66|
※ElasticNet回帰はL1：L2 = 50：50

# 今回の結果
L1：L2 = 19：81のとき決定係数は最大で0.68となる。（l1_ratio=0.19）
![ElasticNet_img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252172/f0dae6e2-a724-fe17-9e9a-f5c2ecfff648.png)


# 手順
- 乳癌のデータセットを読み込む
- 訓練データとテストデータを分離する
- 決定係数の最大値を初期化し、li_ratioと決定係数を入れるための空のリストを用意する
- li_ratioと決定係数をプロットする
- 決定係数最大となるときのli_ratioと決定係数を出力する

#pythonによる実装

```python
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import ElasticNet
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

#データの読み込み
cancer_data = load_breast_cancer()

#データポイントと特徴量(569,30)
print("データポイントと特徴量\n{}".format(cancer_data.data.shape))
print("")

#訓練データとテストデータを分離
train_X, test_X, train_y, test_y = train_test_split(cancer_data.data, cancer_data.target, random_state=0)

#モデルを学習し、最も高いl1の値と決定係数を出力する
maxvalue = 0
x = []
y = []

for i in range(1, 101):
    j = i / 100
    model = ElasticNet(l1_ratio=j)
    model.fit(train_X, train_y)
    score = model.score(test_X, test_y)

    x.append(j)
    y.append(score)

    if score >= maxvalue:
        maxvalue = score
        k = j

plt.xlabel("l1_ratio")
plt.ylabel("Coeficient of Determination")
plt.plot(x, y)
plt.show()

print("最も決定係数が高くなるli_ratioは：{}".format(k))
print("最も高い決定係数は：{:.2f}".format(maxvalue))
```
出力

```
データポイントと特徴量
(569, 30)

最も決定係数が高くなるli_ratio：0.19
最も高い決定係数は：0.68
```

# おわりに
　ElasticNet回帰で決定係数が最大となるli_ratioを求めることができた。しかし、線形回帰には及ばなかったためモデルは線形回帰を選定する。
matplotlibで時系列データをプロットする際の軸の設定＋おまけ

# 前略
時系列データをmatplotlibでプロットするとき、軸のフォーマット調整で結構苦労します。サンプルを残しておきます。

# 手順
## 時刻の列を折れ線グラフのx軸に使用する
折れ線グラフの場合、時系列の列をそのままx軸に使用できます。ただしフォーマットがmatplotlibが自動で調節して、意図しない表示になることがあります。LocatorとFormatterで軸の表示を設定します。

```python
import matplotlib.pyplot as plt
import matplotlib as mpl
import pandas as pd
import io

# データ読み込み
data = """date,val_1,val_2
2018-11-01 09:00:00,65,d g
2018-11-01 09:01:00,26,e h
2018-11-01 09:02:00,47,h w
2018-11-01 09:03:00,20,k d
2018-11-01 09:04:00,65,8 d
2018-11-01 09:05:00,4,l d
2018-11-01 09:06:00,31,w d
2018-11-01 09:07:00,21,s s
2018-11-01 09:08:00,98,a b
2018-11-01 09:09:00,48,f f
2018-11-01 09:10:00,18,g 4
2018-11-01 09:11:00,86,s f"""
df = pd.read_csv(io.StringIO(data), parse_dates=[0])

# グラフ作成
plt.figure(figsize=(8,4))
plt.plot(df['date'], df['val_1'])

# ロケータで刻み幅を設定
xloc = mpl.dates.MinuteLocator(byminute=range(0,60,1))
plt.gca().xaxis.set_major_locator(xloc)

# 時刻のフォーマットを設定
xfmt = mpl.dates.DateFormatter("%H:%M")
plt.gca().xaxis.set_major_formatter(xfmt)

plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/c1e2ea91-498a-2b79-439e-d041a72931d5.png)


## 時刻の列を棒グラフのx軸に使用する
`plt.bar`の第一引数は棒グラフの棒の左端座標を表します。時系列データを直接使用すると座標がおかしくなってしまいます。

```python
import matplotlib.pyplot as plt
import matplotlib as mpl
import pandas as pd
import io

%matplotlib inline


data = """date,val_1,val_2
2018-11-01 09:00:00,65,d g
2018-11-01 09:01:00,26,e h
2018-11-01 09:02:00,47,h w
2018-11-01 09:03:00,20,k d
2018-11-01 09:04:00,65,8 d
2018-11-01 09:05:00,4,l d
2018-11-01 09:06:00,31,w d
2018-11-01 09:07:00,21,s s
2018-11-01 09:08:00,98,a b
2018-11-01 09:09:00,48,f f
2018-11-01 09:10:00,18,g 4
2018-11-01 09:11:00,86,s f"""


df = pd.read_csv(io.StringIO(data), parse_dates=[0])
x = range(len(df['date']))

plt.figure(figsize=(8,4))
plt.bar(df['date'], df['val_1'])
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/020103ae-dd24-6cbc-472c-6ddc86710215.png)

そこでx軸を整数値にとって、あとから時刻目盛りを時刻文字列で置き換えます。

```python
import matplotlib.pyplot as plt
import matplotlib as mpl
import pandas as pd
import io

%matplotlib inline


data = """date,val_1,val_2
2018-11-01 09:00:00,65,d g
2018-11-01 09:01:00,26,e h
2018-11-01 09:02:00,47,h w
2018-11-01 09:03:00,20,k d
2018-11-01 09:04:00,65,8 d
2018-11-01 09:05:00,4,l d
2018-11-01 09:06:00,31,w d
2018-11-01 09:07:00,21,s s
2018-11-01 09:08:00,98,a b
2018-11-01 09:09:00,48,f f
2018-11-01 09:10:00,18,g 4
2018-11-01 09:11:00,86,s f"""


df = pd.read_csv(io.StringIO(data), parse_dates=[0])
x = range(len(df['date']))

plt.figure(figsize=(8,4))
plt.bar(x, df['val_1'])

xloc = mpl.dates.MinuteLocator(byminute=range(0,60,1))
xfmt = mpl.dates.DateFormatter("%H:%M")
plt.gca().xaxis.set_major_locator(xloc)
plt.gca().xaxis.set_major_formatter(xfmt)

plt.xticks(x, [pd.to_datetime(str(date)).strftime("%H:%M") for date in df['date']], rotation=45)
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/8b01a67e-a7ca-aa17-c128-0eba2012b0b5.png)

# 草々
matplotlibの棒グラフは使いにくいですねえ。
画像認識で動く六軸ロボットアームを作って苦労した話

#画像認識で動く六軸ロボットアームを作って苦労した話
##仕様
- Arduino Mega(ロボットアームの制御)
   - ステッピングモータ×3
   - シリアルサーボ×4 
   - ステッピングモータドライバ×3
- Raspberry Pi 3B+(画像認識と逆運動学の計算処理)
 - USBカメラ

##内容
定点カメラから撮った画像からぬいぐるみの識別を行い、ぬいぐるみをロボットアームを使って仕分けた。
proxyquire で 間接的に require するオブジェクトは @global で差し替える

## やりたいこと

`let app = proxyquire('../app.js', stubs);` でスタブにしたいオブジェクトが `app.js` に定義されている例はよく見るけど、 「app.js」 -> 「module_a.js」 -> 「module_b.js」  の様に `app.js` を `require` した先で `require`　しているオブジェクトを スタブにしたい。

今回は Slackのボットを 「npmモジュールのslack」 を利用して実装している。Slackのチャンネルの一覧を取得するために API `slack.channels.list({token})` を使用している。テストコードで本物のAPIを呼び出すわけにはいかないのでスタブに差し替えたい。

## tl;dr 

* proxyquireの[Globally override require](https://github.com/thlorenz/proxyquire#globally-override-require)を使った。

## 環境

* node.js: v8.10.0
* [npmのslack](https://www.npmjs.com/package/slack): 11.0.2
* proxyquire: 2.1.0
* mocha: 6.1.4

## ソースコード

### 実装

```javascript:app.js
var express = require('express');
var commandRouter = require('./routes/slack/command');

var app = express();
```

```javascript:./routes/slack/command.js
const Slack = require('slack');
const slack = new Slack();

slack.channels.list({"token":BOT_TOKEN}).then(function(res){
  // 受け取ったレスポンスを利用する処理
});
```


### テストコード

```javascript:/test/command.test.js

const request = require('supertest');
const expect = require('expect');
const proxyquire = require('proxyquire');

// スタブに定義する slack.channels.list の実装
let channelsListSub = function (token) {
    return new Promise(function (resolve, reject) {
        resolve({
            ok: true,
            channels: [
                {id: "C59K2FFTL", name: "general", members: ["USER1"]}
                , {id: "C59MVDJUD", name: "random", members: ["USER2"]}
                , {id: "CJCP9UW9H", name: "test1_channel", members: ["USER2"]}
                , {id: "CJD0VJUE6", name: "test2_channel", members: ["USER2"]}
            ]
        })
    })
}

// require('slack') で読み込まれるスタブを定義
let stubs = {
    'slack': function () {
        this.channels = {
            list: channelsListSub
        }
    }
};
stubs.slack['@global'] = true;
let app = proxyquire('../app.js', stubs);


it('スラッシュコマンド mycommand', (done) => {

    const qs = {
        command: '/mycommand',
        text: '',
        // スラッシュコマンで渡られる他のパラメータが続く
    };

    request(app)
        .post('/command')
        .type('form')
        .send(qs)
        .expect(200, {
            text: "期待するメッセージ"
        })
        //非同期処理のテストの際にdoneでキチンと終了を知らせる
        .end(done);
})

```

## 説明

テストコード `test/command.test.js` の `let app = proxyquire('../app.js', stubs);` で読み込みを行うと、連鎖的に `app.js` -> `routes/slack/command.js` -> `node_moduels の slack` が読み込まれる。

先に

```javascript
let stubs = {
    'slack': function () {
        this.channels = {
            list: channelsListSub
        }
    }
};
```
でスタブを定義して

```javascript
stubs.slack['@global'] = true;
```
で *Globally override require* の指定を行う
Railsのform_forとRouting Error

#Railsのform_forとRouting Error
###今回の記事の目的###
Railsで`form_for`で編集などの`view`を書いている時によく`Routing Error`が起きていたことについて今回やっと解決したのと色々調べているうちに得られた知見をまとめてみました。

ちなみにteratailに初投稿して解答を頂き解決しました。
[こちら](https://teratail.com/questions/189669)です。

---
`https://ruby-rails.hatenadiary.com/entry/20140813/1407915718`
今回エラーが起きたのはこちらのサイトのミニBlog作成、
4.2. 最初のフォームのところです。
#問題点
editからupdateに送信時にrouting errorが起こりました。

#エラーメッセージ
```
Routing Error
No route matches [PATCH] "/posts.1"
Rails.root: /Users/xxxxx/workz/blog

Application Trace | Framework Trace | Full Trace
Routes
Routes match in priority from top to bottom
```

#ソースコード
###routes.rb
```
Rails.application.routes.draw do

  resources :posts

end
```

###post.controller.rb
```
def edit
  @post = Post.find(params[:id])
end

def update
  @post = Post.find(params[:id])
  if @post.update(post_params)
      redirect_to @post
    else
      render :edit, status: :unprocessable_entity
    end
end

private
def post_params
  params.require(:post).permit(:title, :text)
end

```

###edit.html.erb
```
<h1>投稿を更新</h1>
<%= form_for :post, url: posts_path, method: :patch do |f| %>
  <% if @post.errors.any? %>
    <div id="error_explanation">
      <h2><%= @post.errors.count %>件のエラーが発生したため保存ができませんでした。</h2>
      <ul>
      <% @post.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>
```
##試したこと
`rake routes`でURL一覧を出した時にupgradeのURLが

```
post PATCH  /posts/:id(.:format)     posts#update
```
だったので何となく`posts_path`だと思ったのですが、
`resources`の対応pathが
| action | path | url |
| index | posts_path | /posts |
| show | post_path(@post) | /posts/1 |
| new | new_post_path | /posts/new |
| edit | edit_post_path(@post) | /posts/1/edit |
| create | posts_path | /posts |
| update | post_path(@post) | /posts/1 |
| destroy | post_path(@post) | /posts/1 |
で`post_path(@post)`を指定する必要がありました。

##今回学んだこと
-form_forの役割-
１．`form_for`は自動で`post`に合ったpathを自動で探すので例えばeditからupdateに送る時はmethodにpatchを指定しないといけない。

２．`form_for`で指定するURLのところはresourcesのところで確認してupdateなど個別のidを持つものは単数形で指定する`post_path(@post)`
REST

# 参照
- [REST入門 基礎知識](https://qiita.com/TakahiRoyte/items/949f4e88caecb02119aa)
    - REST(REpresentational State Transfer)はWebサービスの設計モデルです。RESTなWebサービスは、そのサービスのURIにHTTPメソッドでアクセスすることでデータの送受信を行います。
- [0からREST APIについて調べてみた](https://qiita.com/masato44gm/items/dffb8281536ad321fb08)
- [RESTとは何か](https://qiita.com/aosho235/items/125af74e2eab66c7a816)
良く使うUNIXコマンド: 初級編

# はじめに
簡単なUNIXコマンドについてまとめました
これだけできれば「簡単なCUI操作ができる!」言うことができると思います

[良く使うUNIXコマンド: 初級編 now](https://qiita.com/NaokiOsako/items/18228ebc4f8ce764087f)
[良く使うUNIXコマンド: 中級編](https://qiita.com/NaokiOsako/items/8fd62231e7175bc3528b)
##目次
1. [ls (list segments)](https://qiita.com/NaokiOsako/items/18228ebc4f8ce764087f#ls-list-segments)
2. [cd (change directory)](https://qiita.com/NaokiOsako/items/18228ebc4f8ce764087f#cd-change-directory)
3. [mkdir (make directory)](https://qiita.com/NaokiOsako/items/18228ebc4f8ce764087f#mkdir-make-directory)
4. [touch](https://qiita.com/NaokiOsako/items/18228ebc4f8ce764087f#touch)
5. [rm (remove)](https://qiita.com/NaokiOsako/items/18228ebc4f8ce764087f#rm-remove)
6. [cat (concatnate), head, tail](https://qiita.com/NaokiOsako/items/18228ebc4f8ce764087f#cat-concatnate-head-tail)
7. [cp (copy)](https://qiita.com/NaokiOsako/items/18228ebc4f8ce764087f#cp-copy)
8. [mv (move)](https://qiita.com/NaokiOsako/items/18228ebc4f8ce764087f#mv-move)
9. [sudo (substitute user do)](https://qiita.com/NaokiOsako/items/18228ebc4f8ce764087f#sudo-substitute-user-do)
10. [open](https://qiita.com/NaokiOsako/items/18228ebc4f8ce764087f#open)
11. [pwd (print working directory)](https://qiita.com/NaokiOsako/items/18228ebc4f8ce764087f#pwd-print-working-directory)

###ls (list segments)
カレントディレクトリにあるファイル, ディレクトリを表示

```bash

$ ls #ファイル, ディレクトリを表示
$ ls -l #権限, 所有者, 作成時刻などの表示
$ ls -a #隠しファイルの表示
$ ls hoge* #hogeから始まるファイル, ディレクトリを表示
```


###cd (change directory)
ディレクトリ移動

```
$ cd tmp #tmpディレクトリに移動
$ cd #homeディレクトリに移動
```
### mkdir (make directory)
ディレクトリ作成

```bash
$ mkdir tmp #tmpディレクトリ作成
$ mkdir -p tmp #tmpディレクトリが存在した場合作成せずエラーを表示しない
```
### touch
ファイルの作成

```bash
$ touch tmp #tmpファイルを作成
```
### rm (remove)
ファイル, ディレクトリの削除
ディレクトリを削除は rmdir コマンドでもできる

```bash
$ rm tmp #tmpファイルの削除
$ rm -r tmp #tmpがディレクトリの場合でも削除
```
### cat (concatnate), head, tail
ファイルを表示
エディタで開区必要なくファイルの中身が見れるので便利

```bash
$ cat tmp #tmpファイルを表示
$ head tmp #tmpファイルの先頭10行を表示
$ tail tmp #tmpファイルの末尾10行を表示
```

### cp (copy)
ファイル及びディレクトリのコピー

```bash
$ mv tmp tmp2 #tmpの内容をtmp2にコピー
```
### mv (move)
ファイル及びディレクトリの移動
ファイル及びディレクトリの名前変更
コピー後, ファイルの削除をおこなうため名前の変更もできる

```bash
$ mv tmp ./tmp2/ #tmpをtmp2ディレクトリの中に移動
$ mv tmp tmp2 #tmpをtmp2に名前変更
```
### sudo (substitute user do)
root 権限でコマンドを実行

```bash

$ sudo (コマンド) #root権限て(コマンドを実行)
```
### open
ほとんどのファイルを開くことができる
エクセル, パワーポイントが入っていればエクセルファイル, パワーポイントファイルですら
開くことができる

```bash
$ open tmp.xlsx
$ open tmp.pptx
```
### pwd (print working directory)
カレントディレクトリまでのパスを表示
(bashスクリプトとか書く時に便利)

```bash
$ pwd #カレントディレクトリまでもパスを表示
```
## 参考文献
[【Linux】コマンドまとめ 〜コマンド名の由来を添えて〜](https://qiita.com/taji-taji/items/0b4bcccf097371bc143c)
PowerEdge R730xd にはUbuntu1804がインストールできなかった話。

つぶやきみたいなの。
仕事でDell PowerEdge R730xd　を使ったサーバ構築をしました。

自分はubuntuを主軸に勉強しているので今回もUbuntu18.04を入れようと思ったんですね。
インストールのタイミングでDmesgみたいなところでなんかのエラーが出ました。
（/dev/sdcが見つからないみたいなやつ。）
しかし進むので、
言語設定、キーボードレイアウトと設定を進める。

NICの設定でエラーが出る。

https://certification.ubuntu.com/hardware/201409-15508/

サポートされてないんですかね。
18.04LTSになってカーネルやらネットワークのデーモン（networkdとかNetoworkManager）とか
だいぶ変わったみたいなのでそれがR730xdに合わないんでしょうかね…。


CentOS7（18.04）をインストールしたらサクッと完了しました。

そこそこ古いサーバだと新しいOS入れられなかったり、だめなんですかね。
Rails5でView、API共用時のCSRF対策

#### 環境
- Rails 5.2.3
- devise 4.6.2
- devise_token_auth 1.1.0

ViewとAPIを共用しようとした場合、API利用想定のものもCSRF保護でエラーとなってしまう。
Rails5非APIモードでdevise token authを使用したところ以下のようなエラーが発生する。

```
Started POST "/api/v1/auth/sign_in" for 172.17.0.1 at 2019-05-18 08:44:58 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by DeviseTokenAuth::SessionsController#create as */*
  Parameters: {"email"=>"one@example.com", "password"=>"[FILTERED]", "session"=>{"email"=>"one@example.com", "password"=>"[FILTERED]"}}
HTTP Origin header (chrome-extension://aejoelaoggembcahagimdiliamlcdmfm) didn't match request.base_url (http://192.168.11.176:3000)
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)


  
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
  
vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_controller/metal/request_forgery_protection.rb:211:in `handle_unverified_request'
vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_controller/metal/request_forgery_protection.rb:243:in `handle_unverified_request'
vendor/bundle/ruby/2.6.0/gems/devise-4.6.2/lib/devise/controllers/helpers.rb:255:in `handle_unverified_request'
vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_controller/metal/request_forgery_protection.rb:238:in `verify_authenticity_token'
```

以下のドキュメントの記載のように修正するとJSON形式で送られてくるリクエストについてはCSRF保護を回避して処理することができる。
https://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html


```
class ApplicationController < ActionController::Base
  include DeviseTokenAuth::Concerns::SetUserByToken

  protect_from_forgery unless: -> { request.format.json? } # 追記部分
end
```

#### 修正後

```
$ curl -X POST -H 'Content-Type:application/json' -d '{"email":"one@example.com","password":"MyString"}' http://192.168.11.176:3000/api/v1/auth/sign_in
{"data":{"id":980190962,"email":"one@example.com","provider":"email","uid":"one@example.com"}}
```
git commit名間違えた時に修正する方法

###git commit --amend

`git commit --amend` は、間違って出してしまった「直前の」コミットを修正する コマンド

→vim操作で以下の部分の間違いなどを編集できるようになる
　・間違ったコミット名
　・間違ったソースコード
など



###直前ではなく、前のコミット名を変えたい場合 git rebase -i
以下のURLの通りに実行
http://www-creators.com/archives/5238

しかし修正したコミットがHEADになってしまっていた。
aliasの登録方法（mac）

`bash` の場合は、 `~/.bash_profile` に記述。
`zsh` の場合は、 `~/.zshrc` に記述。


`$ vim ~/.zshrc`の場合
以下のような感じで記述を追記。

```
alias gs="git status”
alias gd="git diff”
alias gc="git checkout”
alias gb="git branch”
alias gl="git log”
alias rs=“rails s”
alias rc=“rails c”
```

で、記述したら
`$ source ~/.bash_profile`
または
`$ source ~/.zshrc`
で使えるようになる。
イベント招待メール送信の半自動化ばなし【vol.1】

株式会社オズビジョンのユッコ (@terra_yucco) です。
日々細かい記事を上げていますが、その中でもそれなりに登場する Google Apps Script。
これは業務だけではなく、プライベートのサークル活動での事務活動を効率化するのにも使えています。今日はその中から、イベントご招待メールの送信を半自動化しているコードを共有します。

# イベントご招待メール送信を半自動化したい
## 前提

- 大体、半年に 1 回イベントご招待があり、そのご案内をメールで送付している
- メールをプリントアウトして持参いただければ入場できる仕組み
- 次以降のご招待のため、来てくださった方の情報が必要
    - 要するに何らかの差し込みが必要

Outlook とかの差し込み機能でもうまくいくのかもしれませんが、普段使っていないので使い方がわかりません。
顧客リストはパスワードをかけたローカル Excel で管理しているので、コピペしたら普通に扱える Spreadsheet がいいのではないかと思い GAS にしました。

## シート

- イベント自体はどんどん回数表記が増えるタイプ
- 送付先ごとに ID を振っている
- 複数回ツールが動いても重複送信はできるだけしないように

ということで以下のような項目分けになっています。
チープ感満載ですが「メール送信」オブジェクトに次に記載するスクリプトが割り当ててあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95030/723bebd7-a278-bf4f-40ea-7283f5d75882.png)

## コード

工夫してある点としては、上にも書きましたが、メール送信が終わったらフラグを立て、同じシートで複数回送信することが無いようにしてある点となります。
※実際この記事を書いているときも誤爆しそうになりました。

```js
function sendInvitationMail() {
 
  var mySheet = SpreadsheetApp.getActiveSheet();
  var rowSheet = mySheet.getDataRange().getLastRow();
  var docMail = DocumentApp.openById("【ドキュメントID】"); //ドキュメントをIDで取得
  var strDoc = docMail.getBody().getText(); //ドキュメントの内容を取得

  /**
   * 1行目はヘッダ
   * 2行目以降データがなくなるまで差し込む
   */
  for (var i = 2; i <= rowSheet; i++) {
    var strNumber = mySheet.getRange(i, 1).getValue(); // 回次
    var strID = mySheet.getRange(i, 2).getValue(); // ID
    var strEmail = mySheet.getRange(i, 3).getValue(); // メールアドレス
    var isSent = mySheet.getRange(i, 4).getValue(); // 送信済みか
    var strBody=strDoc.replace(/{ID}/g, strID);
    if (isSent != "") {
      Logger.log(strID + ": skipped");
      continue;
    }

    // メール件名
    var strSubject = "第{Number}回【イベント名】へのご招待".replace(/{Number}/g, strNumber) + " (" + strID + ")";
    var strFrom = "【From メールアドレス】"; //From
    var strSender = "【From 表示名】"; //差出人

    /* メールを送信 */
    GmailApp.sendEmail(
      strEmail, //toアドレス
      strSubject, //メールタイトル
      strBody, //本文
      {
        from: strFrom, //fromアドレス
        name: strSender //差出人
      }
    );
    mySheet.getRange(i, 4).setValue(1);
    Logger.log(strID + ": sent");
  }
}
```

このあたりもいつかもう少しブラッシュアップしたいのですが、ちょっとスクリプトが書けるだけで、プライベート活動も効率化することができるよ、という話でした。