OmniAICreator/Qiita-1.07M huggingface dataset:
Haskellでゴールドバッハの予想


[ゴールドバッハの予想
](https://ja.wikipedia.org/wiki/%E3%82%B4%E3%83%BC%E3%83%AB%E3%83%89%E3%83%90%E3%83%83%E3%83%8F%E3%81%AE%E4%BA%88%E6%83%B3)


``` Haskell
goldbach x = [(a, x-a )| a <- [1..(div x 2)], isPrime a, isPrime (x - a)]
isGoldbach x = [] /= goldbach x
filter (not. isGoldbach) [4,6..]
```
playwright-firefoxでggrksする

## まえおき

Firefoxでしか動かない社内システムに[puppeteer-firefox](https://www.npmjs.com/package/puppeteer-firefox)で対処していたのだけど、「Windowsでは動かない」って言われて、

<img width="1116" alt="貼り付けた画像_2020_02_06_15_51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74571/e98c4515-9a21-c0a8-8137-257d37c6a989.png">

うーん、じゃあしゃーない、[playwright](https://github.com/microsoft/playwright)使ってみるか。ってなった。

~~ちなみに私はMacユーザなので、これを書いている時点では本当にWindowsで動くかどうかは知らない。~~
(playwright-firefoxだと無事に動いたそうです）

## packages.json

```
  "dependencies": {
    "@types/node": "^13.7.0",
    "playwright-firefox": "^0.10.0",
    "typescript": "^3.7.5"
  }
```

こんなかんじかな。 バージョン違いはあるとおもうけど。

とりあえず `yarn add typescript @types/node playwright-firefox` すればよい。

## TypeScriptで書く

puppeteerはJavaScript実装だったのに対し、playwrightはTypeScriptだ。

ただ、GitHubのサンプルコードはなぜかJS。「PageとかBrowserとかどこから取ってこればええねん？」ってなる。

```typescript
import { Page, Browser, firefox } from "playwright-core";
```

playwrightのソースを読んだ感じだと、たぶんこうすればいい。

### tscが通らない...

```
$ /Users/yusuke-iwaki/src/hoge/node_modules/.bin/tsc index.ts
node_modules/playwright-core/lib/helper.d.ts:17:23 - error TS2688: Cannot find type definition file for 'debug'.

17 /// <reference types="debug" />
                         ~~~~~


Found 1 error.

error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

```

`@types/debug` を入れれば直る。

```
yarn add --dev @types/debug
```


## ブラウザを開くまでの定形コード

[puppeteer-coreとMacにインストール済みのChromeを使って自動操作](https://qiita.com/YusukeIwaki/items/e8e197ddcdf7f7f3013b#%E6%99%AE%E6%AE%B5%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%82%92%E4%BD%BF%E3%81%86%E3%82%88%E3%81%86%E3%81%AB%E3%82%A6%E3%82%A4%E3%83%B3%E3%83%89%E3%82%A6%E3%82%92%E9%96%8B%E3%81%8F%E3%81%AB%E3%81%AF)に書いてたコードをplaywrightで書き直すと


```ggrks.ts
import { Page, Browser, firefox } from "playwright-core";

const launchChrome = firefox.launch({
    // ブラウザ画面を表示しながら（ヘッドレスモードを無効にする）。
    headless: false,

    // 人間味のある速度で入力/操作する。
    slowMo: 50,
});

launchChrome.then(async (browser: Browser) => {
    // 大抵のサンプルコードはここで単純に browser.newBrowserContext(), browserContext.newPage() しているだけのものが多いが、
    // ブラウザを開いたときにすでに１つタブが開いている場合には、２つ目のタブが開いてしまう。
    // それを防ぐため、すでにタブが開いている場合にはそれを使うようにする。
    let browserContext = await browser.defaultContext();
    let browserPages = await browserContext.pages();
    let page: Page = browserPages.length > 0 ? browserPages[0] : (await browserContext.newPage());


    // 自動操作するコードをここに書く
});
```

## ggrksする

```ts
    // 自動操作するコードをここに書く
    await page.goto("https://google.com/");
    await page.type("input[name='q']", "puppeteer");
    await page.keyboard.press("Enter");
```

ここはpuppeteerのコードがそのまま使いわせる。すばらしや。

### ただ、完全に同一ってわけでもない

たとえばpuppeteerだと、waitForの `visible` っていう名前のオプションが、playwrightだと `visibility` になっている！など、微妙な変更は必要。

TypeScriptで書いていれば、ビルドエラーになってくれるから気付ける。（JSだと気づけないかも...？）


### おためしコード

https://github.com/YusukeIwaki/ggrks-playwright-ts

![ggrks.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74571/9359695e-9719-99bd-2ab8-1291766c382f.gif)
【メモ】jQueryでAjax処理終了時に実行する

①のajax後に
②のajax処理が走ってほしい

```js:app.js
// ajax実行後に処理するならこれでよい
$(document).ajaxStop(function(){
    // code
});
```

上記でajax実行後に何かするというのはいいのですが
ここにajaxを入れると無限ループするので一回に絞る

```js:app.js
$(document).one('ajaxStop',function(){
    // ajax処理
});
```

そもそも論、これを使う状態に陥るのが間違っている気がする
１日10時間株価予測AIを作り続ける　3か月目

[前前回の記事：1か月目](https://qiita.com/Lulu_die_Zweite/items/8e5cb713073982353ac3)
[前回の記事：2か月目](https://qiita.com/Lulu_die_Zweite/items/d607281c6fe78860010d)
##３か月目
２か月目まででかなり多くの問題に直面してきました。
一つのAIの予測精度を最大化するのは限界がありそうです。
そこで、そこからさらに予測精度を上げることができるかもしれない方法を思いついたのでここに書き記します。

##AI多数決理論
  その方法は簡単で、まずいくつかの良いAIを作ります、AIの数は奇数が望ましいです。その後集めたAIで多数決を取り最終決定を下します。そもそも一つのAIの中でも多くの場合多数決で予測を決めているという側面があり、実際に複数のAIを集めて判断させることで効果があるのかどうかは疑問ですがとにかくやってみましょう。
　問題点は、集められたAIがおそらく多様性に富んでいる必要があり、加えてある程度の数が必要だということです。
　今月の目標は色々なデータを使って高性能な予測AIをいくつか作ることでした。
##学習にあたっての問題点
　データを学習させるにあたって問題点が二つあります。
一つは過学習、もう一つの問題点は予測の偏りです。例えば0を上がる、1を下がると定義した場合、今までのモデルでは0を多く出力する(全ての予測の内0が70~100%を占める)問題が頻発しました。
これらの問題の難しいところは、過学習の問題を解決しようとすると予測の偏りが生じ、反対もまたしかりということです。
この問題には主に以下の３つの変数が関与していました、1. Normalization Layers(正規化層)の設定の強さや層の数。2. エポック数。3.選択するOptimizer
また、学習過程以外で結果に影響する要素は4.データの構造や質など。そして 5.モデルの構造が挙げられます。
##AI研究について　
稀に良い上記の変数の組み合わせを偶然に発見し、結果として悪くないまたはとても良いAIを手にすることができます。
　深層学習は、ただデータを学ばせればいいというだけではなくその過程で色々な調整や試行錯誤が必要で、ここに研究余地やAIを作るライブラリ側の向上余地があるのだろうとわかりました。
　今までに3種類のAIを作りましたが1番目のAIに比べて2番目3番目に作ったAIの性能がずば抜けて良く、1番目のAIを議会から追放することを検討中です。
#AI_No.2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558316/ef17edae-6475-75fd-997a-7e0eb6ed5319.png)

2つめに作ったAIの性能です。
アメリカの主要企業500企業の2000年からの全株価データ(43707個)に対して65.6%の予測精度を持ち、また0(株価が上がるとする予測)の出力比率は57%であり特に問題がありません。そして予測が完全にランダムだった場合に期待される精度が51.56%なことからもかなり強力に予測が可能である事が示唆されています。


##今後の方針
三つあれば多数決は成立するので現実の株式市場で検証をするためのコードを書こうと思います。
ImportError: cannot import name 'factorial'〜〜〜

`statsmodels` をimportしようとすると怒られてしまって困った。

多分scipyのssがimportできなくて、scipyのupgradeとかしてみたら、

```
ImportError: cannot import name 'factorial'〜〜〜
```

とかでてきてここに辿り着く人が多いんじゃないかしら。僕ですけど。


## 解決方法

```
pip install statsmodels==0.10.0rc2 --pre
```

めでたしめでたしです。

参考：
https://github.com/statsmodels/statsmodels/issues/5747
lightning web コンポーネントのnamespace

<h2>trailHead</h2>
"
....すべての Lightning Web コンポーネントには名前空間があり、フォルダ名とはハイフンで区切られます。たとえば、デフォルト名前空間 c 内にあるフォルダ名 app の Lightning Web コンポーネントのマークアップは <c-app> です。これは、Lightning Web Components Playground の main.js 内で確認できます。...."
これを読んだらピンっと来ないでしょうか。

では、分かりやすい説明、いたします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578884/2a1464df-16bf-2711-1dc3-7853b3e73609.png)

ソースと一緒に見たら分かりやすいかも。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578884/47801536-4e8c-ad91-ac11-5a2781744a88.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578884/1e130f0b-ea60-61d7-0971-6aefbd861ded.png)

参照元：

TrailHead
<a>https://trailhead.salesforce.com/ja/content/learn/modules/lightning-web-components-basics/create-lightning-web-components</a>
:point_up_tone5:
herokuにデプロイした際にCSSで指定した画像が表示されない

##backgroundで指定した画像が消えてる！？

Googleで検索しても・・・中々望んでる解答がない。

[**そこで検索してるうちにようやく見つけた解決策**]

http://kgmx.hatenablog.com/entry/2014/06/26/085304

```
CSS
.xxx {
background-image: url("heart.png");
}
```

これだと、デプロイしても画像は表示されません。
上手く画像を見つけ出してくれないらしいです。

```
.xxx {
background-image: image-url("heart.png");
}
```

image-urlとすることで、app/assets/images配下から画像を探してくれる。
との事で試した結果。すんなりと直りました。

という事で、今回のメモでした。
デイサービスで自社システムを作って楽をしています〜その２　FileMakerGoでipadからデータ入力

前回公開した自社システムの記事、多くの方に見ていただきありがとうございました！  
 [デイサービスで自社システムを作って楽をしています](https://qiita.com/gokkozemisei/items/79dd2e9a34fa06c67b32)

今回はサブ機能として活躍中の排泄管理システムをご紹介したいと思います。
デイサービスには排泄がうまくいかない方もいらっしゃるのですが、弊社ではなるべく自分でトイレにいけるようにと介護スタッフが排泄を記録してちょうど良い時間にスタッフがお連れしています。

##以前は紙で運用していた
![排泄エクセル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237172/2fd81de3-d92f-6da9-4f28-bccf544e09e8.png)

このようにエ〇セルでつくったシートを印刷して、これに手書きで記号を書き込んでいました。
排泄の管理をしないといけないご利用者さんは10名にも満たないので、紙での運用でも問題ないようにも思われましたが、離れたところから排泄状況を確認しないといけないときや、紙がご利用者さんのすぐそばにないときなど...スタッフがその情報のためにわざわざ移動したり、他の紙にメモしてそれを書き写したり、記録がとれない時間があったりしたそうです。

##ぱっとみて状況がわかるようにしてほしい
紙からipadへ移行することに関しては  [実績](https://qiita.com/gokkozemisei/items/79dd2e9a34fa06c67b32)があったため、あまり抵抗がありませんでした。UIにはかなり気を使っていますが、介護スタッフからの要求というのは「ぱっとみてわかるように！」というもので、それ以上は色々と質問してもはっきりとした要求はもらえませんでした。こういうときにFileMakerでの高速開発が真価を発揮します。笑
何度か実際に動かせるものを提案していくなかで、納得してもらったUIがこちらです。

▼排泄管理トップ画面
![排泄トップ画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237172/e081f85e-f9a7-45ee-10df-ef4eed194c74.png)

この黒いボタンはご利用者さんの氏名になっていて、これを押すとこの方の排泄状況をまとめた画面に遷移します。
このボタン、真っ黒の背景に白く大きい文字でご利用者さんの氏名を！というのは年配のスタッフからの強い要望を取り入れました。

▼ご利用者さんごとの排泄集計画面
![排泄集計.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237172/41a8a774-c429-441c-8705-814af1e7174b.png)


排泄の記録はこの画面やトップ画面から登録することができます。

尿、便、尿×、便×というボタンを押すと、詳細を登録するための画面に遷移します。
お連れしたが何も成果なしというときは尿×、便×ボタンです。

![排泄詳細.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237172/bb437da5-15b0-5ee5-d0da-4f3cbd7db00d.png)

自分からトイレに行かれたのか、誘導した結果なのか、排泄の量などを記録しています。
時間は尿、便、尿×、便×のボタンを押すタイミングでタイムスタンプを取得しています。

▼テーブルはこんな感じです
![排泄管理テーブル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237172/164a52a8-8850-e0df-c004-f21cf907b43b.png)

##分離モデルを採用
1日中記録しているしデータ量も多いので、データファイルとUIファイルは分けています。（弊社で運用しているシステムは全て分離モデルです）
分離モデルだと急にiphone用も作って！なんて言われても比較的すぐに対応できます。

##スタッフからの評判は◎
紙での運用では、排泄管理が必要なご利用者さんが増えたときににすぐに対応できなかったり、人によって記録の書き方が違っていたりといった問題があったため、それが解消され「楽～！」ということと、より詳細な情報を簡単に記録できるようになって、適切に誘導できるようになったとのことです。

##排泄データを使って集計しているが...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237172/12fa5c78-3e3b-7d93-8e34-922cdd0e2178.png)

こうした集計結果は今のところあまり見られていないようです。

以前は紙で運用しておりましたがログを残しておらず、次の月になると紙は役に立っていませんでした。（これをエ〇セルで打ち込む...ということはしていませんでした）
使える状態のログがどんどんたまってきているので、今後はこの排泄ログを利用して、排泄を予測したり身体の不調を早い段階で察知したり...と活用できれば良いな、と思っています。
正規表現でTwitterURLからユーザー名とstatusを取得する【Ruby】

#TwitterのURLについて

これがツイートのURLの例
`https://twitter.com/yurinolog/status/1209290280328814593?s=20`

httpsから始まり３つ目のyurinologが**ユーザー名**、５つ目の数字の羅列が**status**と呼ばれる各ツイートに割り振られる番号。(語尾のs=20の正体はいまだに分からない。知ってる方いらしたら教えて頂きたいです)

#書いたコードと結果

```ruby
url = "https://twitter.com/yurinolog/status/1209290280328814593?s=20"

/(https|http):\/\/(twitter.com)\/([A-Za-z0-9_]*)\/(status|statues)\/(\d+)/.match(url)

puts $1 #=> http or https
puts $2 #=> twitter.com
puts $3 #=> user
puts $4 #=> status or statuses
puts $5 #=> status

```

#使用した正規表現

正規表現は数度使ったことがあるが、抽象的というかコードから結果がイメージしにくく知識はほぼ皆無なので、一応復習しておくことにする。

##キャプチャ()と$について

キャプチャ（後方参照）と言うのは正規表現でマッチした部分の１部を取り出すときに使う。

取り出す予定の部分を`()`で囲うことで`$1`や`$2`といった風に取り出すことが出来る。

```ruby

/(https|http):\/\/(twitter.com)/.match(url)
puts $2 #=> twitter.com
```

##いくつかの候補から選択する
今回の場合はhttpsかhttpか、statusかstatusesとなる。

```ruby

/(https|http)/.match(url)
```
候補となる値を`|`で区切る。

##英数字とアンダーバーについて
今回は`[A-Za-z0-9_]`と書いた。
他にも
`[A-Z]`
`[a-z]`
`[0-9]`
と分けて表現できる。

あとstatusの数字の表現には`/d+`を使ってみた。

`*`と`+`は同じ文字や単語を繰り返しマッチさせたいと気に使う。
スクロールしても背景固定

[参考サイト](https://takafumimegumi.com/blog/background-attachment)
[参考デモ](https://takafumimegumi.com/demo/background-attachment/index.html)


```html:html
<div class="fixed-bg bg01">
	<h1>見出し</h1>
</div>
 
<div class="scroll-bg bg-color01">
	<p>コンテンツ</p>
</div>
 
<div class="fixed-bg bg02">
	<h1>見出し</h1>
</div>
 
<div class="scroll-bg bg-color02">
	<p>コンテンツ</p>
</div>
```

## 背景画像をつけるセクションに「background-attachment: fixed」を設定する

```css:css
.fixed-bg {
  min-height: 100vh;
  background-attachment: fixed;
  background-size: cover;
  background-position: center;
}
 
.bg01 {
  background-image: url(../images/bg01.jpg);
}
 
.bg02 {
  background-image: url(../images/bg02.jpg);
}
```
Nuxtのページ表示速度が遅かったので、色々改善方法のメモ

# はじめに
Nuxt, TypeScriptで速度とかを深く考えず実装を進めていったら、
ページ表示速度が著しく遅かったので色々と勉強したメモ。

# 前提
Nuxt 2.11.0
TypeScript導入済み
Nuxt generateして運用

# 速度改善
どこが遅いのか、とかを色々しらべると
- 画像が多い画面なので画像の読み込みに時間がかかる。
- node moduleが重い
- componentsのimportが無駄なものがあったり、importの仕方がまずい
とかが原因と思われました。
ちなみに改善する前のGoogle のpagespeed insights で測ったら真っ赤っかでした。

# 画像の読み込み改善
## 画像の遅延読み込みの実装
vue-lazyloadを使います。

```console
yarn add vue-lazyload
```
nuxtで使えるようにしていきます。

```javascript:~/plugins/vue-lazyload.ts
import Vue from 'vue'
import VueLazyload from 'vue-lazyload'

Vue.use(VueLazyload, {
  preLoad: 1.1,
  attempt: 1,
  observer: true,

  observerOptions: {
    rootMargin: '0px',
    threshold: 0.1
  }
})
```
オプションは、vue-lazyloadのドキュメントを読んでください。たぶん、このまま使って大丈夫です。
pluginをnuxt.config.tsで読み込みます。

```javascript:nuxt.config.ts
  plugins: [
    { src: '~plugins/vue-lazyload', ssr: false }
  ]
```
vue用に作られたmodulesをnuxtで使う場合pluginを書いて、configで読み込んだらだいたい使える気がします。
これでlazyloadの準備ができました。

実際componentsなどで使う場合

```javascript:hoge.vue
<template lang="pug">
div
  img(v-lazy='hoge.jpg', alt='')
</template>
```
とう感じに、`src` の代わりに `v-lazy`　を使ってください。
これでlazyloadが実装できました。
これだけで画像関連は十分ですが、せっかくなのでwebpも使える様にします。
## Webpと通常の画像の出し分け
lazyloadの実装に使ったvue-lazyloadを使ったらいい感じにwebpの出し分けも実装できました。
pluginを書き直しましょう。

```javascript:~/plugins/vue-lazyload.ts
import Vue from 'vue'
import VueLazyload from 'vue-lazyload'

Vue.use(VueLazyload, {
  preLoad: 1.1,
  attempt: 1,
  observer: true,

  observerOptions: {
    rootMargin: '0px',
    threshold: 0.1
  },
  filter: {
    webp(listener: any, options: any) {
      if (!options.supportWebp) return
      listener.src = 'hoge.webp'
    }
  }
})

```
`filter`を追加します。
ここで、ブラウザがwebpに対応していればwebpのパスを返す処理を追加しています。
もしくはパスの最後にパラメータを追加すると、変換して返してくれるような機能があればこんな感じで。
これはcontentfulです。

```javascript:~/plugins/vue-lazyload.ts

  filter: {
    webp(listener: any, options: any) {
      if (!options.supportWebp) return
      listener.src += '?fm=webp'
    }
  }

```

以上で、画像はlazyloadとwebpが実装できました。

ここまでやったら、多分だいたいOKなんじゃないかと思いますが、次へ。

# componentsのdynamic import
Nuxt,vueでcomponentをimportする場合

```typescript

import fuga from '~/components/fuga.vue'
```
だいたい、こうしますが。

```typescript
const fuga = () => import('~/components/fuga.vue')
```
こうすると、dynamic importになってbundleサイズが軽くなって速度が改善されます。
これをしてエラーが出ないcomponentならこうやったほうがいいですが、
たまにエラーが出るので、その場合は臨機応変に、従来通りのimportするかエラーを直すか。

# webpackのbundleの設定
nuxt でwebpackのbundleを分割するように設定します。

```typescript:nuxt.config.ts
const nuxtConfig = {
  splitChunks: {
    layouts: true,
    pages: true,
    commons: {
      test: /[\\/]node_modules[\\/]/,
      name: 'vendor',
      chunks: 'initial'
    }
  }
```
spliChunksの部分の設定をしてやると、よかったです。
おわり。

# おわり　
おわり

# 参考
https://webpack.js.org/guides/lazy-loading/
https://crieit.net/posts/Nuxt-Vue-dynamic-import-sed
json-server で使い捨てモックサーバを作る


フロントエンド開発に必要となったため json-server で
使い捨てモックサーバを構築する。

■json-server
https://github.com/typicode/json-server

インストール

```
mkdir /tmp/$(date +%Y%m%d)_moc && cd /tmp/$(date +%Y%m%d)_moc
yarn add json-server
```


初期設定

```
touch /tmp/$(date +%Y%m%d)_moc/db.json
touch /tmp/$(date +%Y%m%d)_moc/routes.json
touch /tmp/$(date +%Y%m%d)_moc/middlewares.js
```

データを用意する

```db.json
{
  "posts": [
    { "id": 1, "title": "json-server", "author": "typicode" }
  ],
  "comments": [
    { "id": 1, "body": "some comment", "postId": 1 }
  ],
  "profile": { "name": "typicode" }
}
```

パスを追加する

■参考
https://github.com/typicode/json-server#add-custom-routes

```routes.json
{
  "/api/v1/*": "/$1",
  "/api/v2/posts": "/posts",
  "/api/v3/comments": "/comments",
  "/api/v4/profile": "/profile"
}
```

GET以外のリクエストだとdb.jsonが書き換えられてしまうので、
全てのリクエストをGETにする


■参考
https://github.com/typicode/json-server#add-middlewares


```middlewares.js
module.exports = function (req, res, next) {
  req.method = 'GET'
  req.query = req.body
  next()
}
```


サーバ起動

```
/tmp/$(date +%Y%m%d)_moc/node_modules/.bin/json-server --routes routes.json --watch db.json --middlewares middlewares.js -p 3000
```

curlコマンドで試してみる

```
curl http://localhost:3000/posts
curl http://localhost:3000/api/v1/posts
```
>出力結果

>```
[
  {
    "id": 1,
    "title": "json-server",
    "author": "typicode"
  }
]
```
AWSルートアカウントのMFA(2段階認証)用の携帯が手元にない場合、着信1回で取らないと無限ループになる

# はまった問題

https://aws.amazon.com/jp/premiumsupport/knowledge-center/lost-broken-mfa/

- AWSルートアカウントの二段階認証番号が昔の電話番号に向けて送られているため、ログインできない状態。新しい電話番号に設定したい
- 上記URLの「unusable~」から専用フォームで問い合わせ、電話が来るのを待つが、いちど不在着信で取れずかけなおすことに
- かけなおすと、カスタマーサポートの自動音声が流れ、AWS関係を問い合わせる番号はなく、とりあえずその他を押す
- AWSがわからない人が出てきていろいろ言われるが何も意味はなくもう一度２に戻る


## なぜこうなったのか

おそらく、Amazonのユーザ側のカスタマーサポートが出てきちゃうので何もできなかったんだと思います。

さらに、どうやら日本のカスタマーサポートは中国人の方が非常に多くたまたまその人にあたってしまったのも大きそうです。

英語と日本語でサポート言語が選べますが、日本語の場合対応が遅いので英語のほうが絶対よかったと思いました。

## 教訓

着信がきたら必ず取れるようにしよう！(消音モードだった）
[js]配列の中身がObjectのとき、特定の要素があるかチェックするうまい方法

配列の中に特定の要素があるかチェックする方法はいくつかあります。
ここではpersonsというオブジェクト要素を複数もつ配列で考えてみます。

まずは、まあよくある書き方
##例１
```js:sample.js
const persons = [
    {name: 'takada'},
    {name: 'yamada'},
    {name: 'tanaka'},
    ]
const target = 'takada'

let hasTargetName = false
persons.map((person) => {
    if (person.name === target) {
        hasTargetName = true
    }
})

console.log(hasTargetName) //trueが表示される
```

for文でもいいですが、mapを使って配列の要素を見ていって、targetと一致するものがあるかを調べています。でもなんか、すごく原始的な感じがして嫌だ。。。
##例2
調べてみると**includes**というのがあった。使い方はどれどれ・・・

```js
const array = ['a' , 'b', 'c']
const target = 'a'
console.log(array.includes(target)) //trueが表示される
```

なるほど、簡単ですね。でも今回は配列の中身がオブジェクトだからこう書けばいいのか？

```js
const persons = [
    {name: 'takada'},
    {name: 'yamada'},
    {name: 'tanaka'},
    ]
const target = 'takada'
const hasTargetName = persons.includes({name: target})
console.log(hasTargetName) //falseが表示される
```
おいおいおい、falseになったぞ！！
どうやらincludesはオブジェクト比較のときは参照元が一致しているかを見てるようです。
試しにこう書いたらtrueになった。ふーん。

```js
const persons = [
    {name: 'takada'},
    {name: 'yamada'},
    {name: 'tanaka'},
    ]
const target = persons[0] //ここを変えてみた
const hasTargetName = persons.includes(target)
console.log(hasTargetName) //trueが表示される
```
とりあえず、includesはこの場合には使えないってのは分かりました。

##例3 じゃあどうするの！
どうやら、**some**というナイスガイがいるらしい。使い方は、ほぼincludesと同じだが比較する値を渡すのではなく、booleanを返す関数を渡してあげればいいようだ。

```js
const persons = [
    {name: 'takada'},
    {name: 'yamada'},
    {name: 'tanaka'},
    ]
const target = 'takada'
const hasTargetName = persons.some((person) => {return person.name === target})
console.log(hasTargetName) //trueが表示される
```
いいじゃないか！！！使いやすい！！！
ついでに、冗長な書き方を修正して・・・

```js
const persons = [
    {name: 'takada'},
    {name: 'yamada'},
    {name: 'tanaka'},
    ]
const target = 'takada'
const hasTargetName = persons.some(person => person.name === target)
console.log(hasTargetName) //trueが表示される
```

はい、スッキリです☆彡
今後使っていこう～！
Content-MD5の作成方法

RESTでContent-MD5の作成方法がなかなか探し出せなかったため、備忘録として残す

#Content-MD5
RESTのヘッダに使用する。MD5は暗号学的ハッシュ関数を用いた、不可逆な暗号化の手法の一つである。現在は、セキュリティの脆弱性が見つかっているため、あまり使用されない。
Content-MD5の作成方法は、コンテンツ(payload)に対して、128ビットのMD5ダイジェストをBASE64エンコードすることで、計算を行うことができる。
Anaconda cloudとcondaで新バージョンのTa-libを簡単インストール

私の動作環境
 `Windows8.1pro 64bit`
 `Anaconda3 2019.10`
 `(backtrader用の仮想環境をPython3.5で構築)`

#BacktraderからTa-libを動かす
BacktraderはTa-libに対応しています。すでに組み込まれているインジケーターと重複していますが、さらにいくつかのインジケーターを表示できるようになります。またロウソク足パターン識別、統計解析などを行うこともできます。

#Ta-libインストールは厄介
が、Ta-libのインストール失敗してしまいました。PIPを使ったのですがエラーが出てしまいました。どうやらTa-libはインストールが少々厄介なものみたいです。私のように躓いている人が結構いるようです。

そんな中、condaを使ってダウンロードするチャンネルを指定すれば簡単にインストールできるという解説記事を発見。さっそく記事を真似てインストールしてみました。サンプルスクリプトも一通りテストしてまったく問題ありませんでした。

*condaのチャンネルとは？*
https://qiita.com/yuj/items/8ce25959427ea97d373b

#QUANTPIANチャンネルからインストールできるTa-libは0.4.9
ところが当時の解説記事の中で使っていたチャンネルはQUANTOPIAN（トレーディングライブラリZiplineを提供している企業）だったのです。こちらからインストールされるTa-libは0.4.9です。すべてのOSに対応していてダウンロード・インストール数も多いのですがリリースが2015年と古い上に新しいバージョン0.4.15ではbacktrader向けの修正が追加されています。（2020年2月時点 最新0.4.19）

`0.4.15`
`[FIX]:` 
`Import TA_FUNC_FLAGS, TA_INPUT_FLAGS, TA_OUTPUT_FLAGS into talib.abstract to support backwards compatibility for backtrader`

#Acaconda cloudでTa-lib 0.4.15を探す
なのでQUANTPIAN以外のチャンネルから新しいバージョンのTa-libをダウンロードした方がいいです。その際にPrompt上でチャンネル及びTa-libパッケージを検索するよりもWeb上のAnaconda cloudで検索した方がわかりやすいです。

_*Anaconda cloudでta-libを検索*_
https://anaconda.org/search?q=ta-lib

このようにQUANTPIANからのインストールが圧倒的に多いのですが、他にも提供チャンネルがたくさんあることがわかります。
ありがたいことに0.4.17(condaだと0.4.16)を提供して下さっているユーザーがいるので、そちらからインストールすることにしました。チャンネルを選ぶとこのような画面になると思います。

![anaconda_cloud.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579602/e16466aa-c133-ca28-a4ba-4db3c000d629.jpeg)

こちらのページに書かれているコマンドをそのままコピーしてAnacondaprompt上に貼り付けて実行するとインストールできます。(仮想環境を使っている人はあらかじめ切り替えておきましょう)
すでに0.4.9をインストールしていてもアップデートしてくれます。いろいろと心配な人は新しく仮想環境を構築してもいいかもしれません。

確認のためbacktrader_documentのTa-libテストスクリプト(RSI)をAnacondapromptから実行してみます。
https://www.backtrader.com/docu/talib/talib/

```python:talib.py

(envbacktrader) C:\Users\xxxx>python talibtest.py --plot --ind rsi

```
※ドキュメントのスクリプトそのままではエラーがでます。こちらの記事を参考にしてCSVファイルを用意してスクリプトの一部を書き換えてください。
https://qiita.com/xxssxxx/items/e915b8afe51facc47a55
![Figure_0_416.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579602/220f4f3e-e174-1cae-2b4d-88f389f53fd9.png)

問題なく動作するようです。

![Figure_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579602/1301189a-0242-4fc7-d149-7dc81ee33906.png)

こちらはTa-lib_0.4.9で同じテストスクリプトを実行した結果です。RSIの表示はそのままですがチャートに表示されているDOJIマークが0.4.16と比較して明らかに少ないです。Ta-lib内部の判定式が変わったのでしょうか？？？やはり何らかの変更はあったみたいですね。

#MacOS対応のTa-lib 0.4.17
ということで、Anaconda cloudとcondaを使えば新しいバージョンのTa-libを簡単にインストールできます。しかし残念ながら現時点(2020年2月)でMacOS用のTa-lib 0.4.17を提供しているチャンネルはないみたいです。
CloudWatchのログをlocalにdownload

# CloudWatchのをlocalにdownloadしたい

get-log-eventsで落とせるとおもったけど、これloopさせないと全部取れないんですね。

```download.sh
#!/bin/bash
log_group_name=$1
log_stream_name=$2
response=`aws logs get-log-events --log-group-name ${log_group_name} --log-stream-name "${log_stream_name}" --start-from-head`
next_token=`echo $response | jq -r '.nextForwardToken'`
while [ -n "${next_token}" ]; do
    echo ${response} | jq -r .events[].message
    response=`aws logs get-log-events --log-group-name ${log_group_name} --log-stream-name "${log_stream_name}" --start-from-head --next-token ${next_token}`
    next_token=`echo $response | jq -r '.nextForwardToken'`
    if [[ $(echo ${response} | jq -e '.events == []') == "true" ]]; then
        break
fi
done
```



```
./download.sh /aws/lambda/hoge '2020/00/00/[$LATEST]xxxxxx'
```

注意　lambdaのlog streamは＄があるのでシングルクォートで囲む
golangでawsのs3のデータをダウンロードするコード


下記を参考にした
https://docs.aws.amazon.com/sdk-for-go/api/service/s3/
https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/go/example_code/s3

```go
package main

import (
	"fmt"
	"os"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/aws/aws-sdk-go/service/s3/s3manager"
)

func main() {
	creds := credentials.NewStaticCredentials("アクセスキー", "シークレットキー", "")

	sess := session.Must(session.NewSession(&aws.Config{
		Credentials: creds,
		Region:      aws.String("ap-northeast-1"),
	}))

	filename := "aaa.txt"

	// Create a downloader with the session and default options
	downloader := s3manager.NewDownloader(sess)

	// Create a file to write the S3 Object contents to.
	f, err := os.Create(filename)
	if err != nil {
		fmt.Println(fmt.Errorf("failed to create file %q, %v", filename, err))
		return
	}

	// Write the contents of S3 Object to the file
	n, err := downloader.Download(f, &s3.GetObjectInput{
		Bucket: aws.String("backet-name"),
		Key:    aws.String("/aaa.txt"),
	})
	if err != nil {
		fmt.Println(fmt.Errorf("failed to download file, %v", err))
		return
	}
	fmt.Printf("file downloaded, %d bytes\n", n)

}

// ついでにアップロードは下記
func upload() {

	accessKey := "your accessKey"
	privateKey := "your privateKey"
	region := "ap-northeast-1"
	fileName := "gazou.png"
	bucketName := "your bucketName"

	creds := credentials.NewStaticCredentials(accessKey, privateKey, "")
	sess := session.Must(session.NewSession(&aws.Config{
		Credentials: creds,
		Region:      aws.String(region),
	}))
	uploader := s3manager.NewUploader(sess)

	f, err := os.Open(fileName)
	if err != nil {
		log.Fatal(fmt.Errorf("failed to open file %q, %v", fileName, err))
	}
	res, err := uploader.Upload(&s3manager.UploadInput{
		Bucket: aws.String(bucketName),
		Key:    aws.String("/test/" + fileName),
		Body:   f,
	})
	if err != nil {
		fmt.Println(res)
		if err, ok := err.(awserr.Error); ok && err.Code() == request.CanceledErrorCode {
			fmt.Fprintf(os.Stderr, "upload canceled due to timeout, %v\n", err)
		} else {
			fmt.Fprintf(os.Stderr, "failed to upload object, %v\n", err)
		}
		os.Exit(1)
	}
	fmt.Println("successfully uploaded file!!")
}

```

exampleに、credentialsの部分の記述が見当たらなかったので、メモ的にアップしました。

それ以外はサンプル通りです。結構簡単ですね。
【Rails】フォームにフォーム外のファイルを追加しようとしたらJavaScriptをめっちゃ書くことになった

# 概要
Railsのフォーム送信は色々いい感じにやってくれるが、少し変えたい時もある。
僕はフォーム外からファイルを追加したかった。

そういう時は、rails-ujsのajaxイベントハンドラを使うとフォーム送信に要所で割り込める。
[Working with JavaScript in Rails#3.5 Rails-ujs event handlers](https://guides.rubyonrails.org/working_with_javascript_in_rails.html#rails-ujs-event-handlers) ※ Rails 5.1以降の機能

以下、これを使ってフォーム外のファイルをフォーム内容と同時送信する例を紹介する。

## やりたいことの例
本来フォーム内の`name`だけ送信されるところ、フォーム外からファイルを追加送信したい。
ここでは仮に、フォーム外の`newImageFiles`に画像ファイルを入れてあり、フォーム内容と一緒に送信したいという前提で話を進める。

```erb
<%= form_with model: [:user, @config] do |f| %>
  <div>
    <%= f.label :name, 'お名前' %>
    <div>
      <%= f.text_field :name %>
    </div>
  </div>
  <div>
    <%= f.submit '保存' %> <%#= 通常、フォームの内容(今回はname)のみ送信される %>
  </div>
<% end %>
<script>
  var newImageFiles = [] // ← フォーム外のファイルを送信に含めたい
</script>
```

※ `form_with`に`local`オプションを付けないでください。
参考：[【Rails】form_withのlocalオプション](https://qiita.com/pharma_tech3/items/6360a69641e18bfa5a96)
# 実装
```javascript
// ...前略
<script>
  var newImageFiles = [] // ← フォーム外のファイルを送信に含めたい
  document.body.addEventListener('ajax:beforeSend', function(event) { // [1]
    var detail = event.detail
    var xhr = detail[0], options = detail[1]
    // [2]コールバック
    options.success = function() {}
    options.error = function() {}
    options.complete = function() {}
    newImageFiles.forEach(image => {
      options.data.append('config[images][]', image, image.name) // [3]
    })
    xhr.onreadystatechange = function () { // [4]
      if (this.readyState === XMLHttpRequest.DONE) {
        if (this.status === 200) { // [4-1] 200の時、リロード
          window.location.href = location.href
        } else { // [4-1] 200以外の時、失敗表示
          alert(`フォーム送信に失敗しました`)
        }
      }
    }
    xhr.send(options.data) // [5]
    event.preventDefault() // [6] その後の通常処理を行わない
  })
```

[1] `ajax:beforeSend`イベントから、フォームから送信予定のxhrとoptionsがとれる。これをカスタマイズする

```javascript
  document.body.addEventListener('ajax:beforeSend', function(event) { // [1]
    var detail = event.detail
    var xhr = detail[0], options = detail[1]
```
[2] optionsにコールバック設定がある。そのまま利用してもよいが今回は雑に全部削除

```javascript
    // [2]コールバック
    options.success = function() {}
    options.error = function() {}
    options.complete = function() {}
```

[3] options.dataにフォーム外から含めたいデータをappend。

```javascript
    newImageFiles.forEach(image => {
      options.data.append('config[images][]', image, image.name) // [3]
    })
```

[4] onreadystatechangeを改めて書く。これも今回は最低限。

```javascript
    xhr.onreadystatechange = function () { // [4]
      if (this.readyState === XMLHttpRequest.DONE) {
        if (this.status === 200) { // [4-1] 200の時、リロード
          window.location.href = location.href
        } else { // [4-1] 200以外の時、失敗表示
          alert(`フォーム送信に失敗しました`)
        }
      }
    }
```

[5] xhrを送信。

```javascript
    xhr.send(options.data) // [5]
```

[6] その後の通常処理をキャンセル。Rails5以前のjquery-ujsではこういうところで`return false`と書くらしいので注意

```javascript
    event.preventDefault() // [6] その後の通常処理を行わない
```

# 感想
Railsの話だけどJavaScriptしか書いていない。
rails-ujsのこの機能は、ほかにも色々な用途で使えると思います。
文字列で記載している年月日を日付として取得し前日、翌日を表示させる方法

#環境
　node.js 8.11.4
　MariaDB　10.3.10.0

##やりたいこと
　MariaDBに登録しているYYYYMMDD(VARCHAR)をdate型に変換して前日および翌日を取得し、HTMLで表示させる。

###やったこと
　//date.parseで変換　NaN
  //var ddate = Date.parse(days);
  //console.log(ddate.toString());

  //newDateで変換　Invalid Date
  var ddate = new Date('YYYYMMDD');
  console.log(ddate.toString());

初歩的な質問でしたら大変申し訳ございませんが何卒よろしくお願い申し上げます。
【 Docker 】 あとから --restart always を適用する

# docker update
`--restart` をつけ忘れたりしても、いちいちコンテナを消して建て直す必要はありません。
`docker update` を使いましょう。

```sh
$ docker update --restart always <CONTAINER ID>
```

これでつけ忘れても簡単に適用できます。
個人的メモ





### ファイル名（拡張子あり）を取得
```sh
basename ./src_mov/upload_2018-11-23_18:00:00+0900.mp4
upload_2018-11-23_18:00:00+0900.mp4
```

### ファイル名（拡張子なし）を取得
```sh
basename ./src_mov/upload_2018-11-23_18:00:00+0900.mp4 .mp4
upload_2018-11-23_18:00:00+0900
```

### ディレクトリ名を取得
```sh
dirname ./src_mov/upload_2018-11-23_18:00:00+0900.mp4
./src_mov
```

### 動画を一括変換
```sh
for mov in $(ls -1d ./src_mov/*.mp4)
do
outfile=$(basename $mov)
ffmpeg -i $mov -vcodec h264_nvenc $outfile > /dev/null 2>&1 </dev/null &
done
```
python モジュールimport方法について

importとかfromとかよく使うけどなんとなくで使っていてよくわかっていないのでまとめる．

pythonだとpath周りとかかなりめんどくさい印象があるけどそれをなんとかできたらいいな

大部分を[入門python3](https://www.amazon.co.jp/%E5%85%A5%E9%96%80-Python-3-Bill-Lubanovic/dp/4873117380)から学んでいます．


## インポート方法まとめ

| Left align | Right align |
|:-----------:|:------------:|
| モジュールを読み込む | import module |
| モジュールからメソッド，クラスを読み込む | from module import method, class |
| パッケージからモジュールを読み込む | from package import module |
| パッケージの中のモジュールのメソッド，クラスを読み込む | from package.module import method, class |

基本的にこの四種類．
これを無意識に使えるようになれば良い．

## モジュールとは
pythonコードをまとめたファイルのこと．

モジュールを利用する際にはimportを使う．
main.pyからmodule.pyを利用したい場合は

```main.py
import module # ここは~~.pyの~~だけを書く 

module.hello_world()
```

```module.py
def hello_world():
    print('hello world!')
```

これだけ．main.pyを実行すると

```
hello world!
```
module.pyのhello_world関数が実行される．
これが基本形になる．

## 各種パターン
### メソッドだけインポートする場合
さきほどのパターンでhello_world関数だけインポートしたい場合，
from ~~.py import メソッド名
で関数をインポートできる．

```main.py
from module import hello_world

hello_world()
```
これで先ほどと同様に実行できる．

### ディレクトリ配下のモジュールをインポートしたい場合

```
.
|____main.py
|____child1
　 |____child.py

```

このようなディレクトリを設定する．

main.pyからchild.pyをインポートしたい場合，

```main.py
# ディレクトリ.モジュール　で指定
import child1.child

child1.child.child_hello()
```

このように読み込むことができる．基本的にどれくらいネストされていてもディレクトリ.~~.~~
のようにドットをつなげることで階層を潜っていくことができる．





## そもそもどうやってモジュールを探しているのか
結論：　sysモジュールのpathに指定されている`ディレクトリなどを順に参照していく`

```main.py
import sys

for path in sys.path:
    print(path)
```
こんな感じでsys.pathに登録されているpathを順に表示させる．
そうすると

```
/pythonTutorial3/study-module
/.pyenv/versions/3.6.0/lib/python36.zip
/.pyenv/versions/3.6.0/lib/python3.6
/versions/3.6.0/lib/python3.6/lib-dynload
/.pyenv/versions/3.6.0/lib/python3.6/site-packages
```
このように登録されているpathが返ってくる．
モジュールをインポートする際はこれらのパスを順にみていって一致するモジュールがあるかどうかを検索しているらしい．

注意点としてpath上に同名pyファイルが存在する場合は``最初にマッチしたファイルを読み込む``
.
なので同名ファイルを複数作成している場合は注意が必要．

### 一つ上の階層のモジュールを読み込む方法
よくあるパターンとして，一つ上の階層のファイル，ディレクトリにあるモジュールを読み込みたい時がある．

これも先ほどの学んだsys.pathを順に探す．というルールを理解していれば簡単になる．
要するにsys.pathに親階層を追加すればいい．

```child.py
import sys

# 一個上の階層をpathに追加
sys.path.append('../')

for p in sys.path:
    print(p)

# ../module.pyを読み込む
import module
module.hello_world()

```

## パッケージについて
パッケージとは\__init\__.pyを持っているディレクトリのこと．
モジュールとパッケージは名称は違うが，扱い方はほとんど同じ，ディレクトリかファイルかの違いだけと思ってもよい

## まとめ
- 処理上ではimport ~~ の~~の部分だけ使えると思っておけばいい
- moduleの読込先はsys.pathに登録されているpathを順に読み込む
- 上の階層などを読み込みたいときはsys.path.appendでpathを追加する
ssh 实现服务器端文件同步

#主题
- ubuntu服务器端添加其他成员的ssh访问
- 简单实现本地目录文件和服务器目录同步


##SSH用公开键和私密键生成

```
$ ssh-keygen -t rsa -b 4096 -C "your comments"
```

命令行执行后会提示，输入要保存的文件名
输入文件名回车后，会要求输入密码串，密码串可以为空（直接打回车）

密码串关联内容参照以下连接
https://qiita.com/shukan0728/items/e654953c89aab6f847a4


##服务器的publickeys登陆
本地的公开键上传到服务器（需要已存在的管理员用户来操作）

```
$ scp your-private-key.pub user@host:~/.ssh/
$ cat your-private-key.pub >> authorized_keys
$ chmod 600 authorized_keys
```

##本地ssh的config设定
默认路径一般在
/home/username/.ssh/config
config文件不存在的话可以新建一个
touch config

```config
#对外公开直连方式
Host aws_proxy_server
  HostName xx.xx.global.ip
  User ubuntu
  Port 22
  IdentityFile /home/username/your-private-key

#通过对外公开ip连接内部其他服务器
Host proxy_aa
  HostName xx.xx.global.innerip
  User ubuntu
  Port 22
  IdentityFile /home/username/your-private-key
  ProxyCommand ssh aws_proxy_server -W %h:%p

```
改变本地私密键的权限许可
```
$ chmod 600 your-private-key
```

测试一下可否能连接上

```
ssh aws_proxy_server
```

连接成功后直接会显示服务器控制台


##把本地文件同步更新到服务器

本地目录结构
>hello_world/
 -Makefile
 -src/
 -conf/
 -test/
 -tmp/
 -.gitignore
 -README.md
 -requirements.txt

```Makefile
all:
	@echo "deploy"

#ssh config中定以的服务器名
HOST := aws_proxy_server


deploy:
	@read -p "HOST: $(HOST)? [y,N]:" ans; \
	if [ "$$ans" = y ]; then  \
	rsync -C --filter=":- .gitignore" -av --exclude "tmp/*" --delete -e ssh ./ $(HOST):/home/username/dev/hello_world; \
	fi

```
Raspberry piに電源管理/死活監視モジュール「slee-Pi」をつけてMackerelをインストールしたら、色々と捗る仕組みができた件

[Mechatrax](https://www.mechatrax.com)の電源管理/死活監視モジュール[slee-Pi2](https://mechatrax.com/products/slee-pi/)を入手、これからの開発・調査をするために、先ずはMackerelをインストールしてみた。その後、ごちゃごちゃやっていたら、それなりに今後にも使えそうなものができたので、ここに記録しておく。

詳細な手順等は[GitHubで公開中](https://github.com/ackcell/mechatrax-slee-Pi2-Mackerel)なので、技術的にはもう何も言うことはないのだけど、ここではなぜこのような仕組みになったかを記す。

Raspberry piへの設定作業なので、[ansible](https://www.ansible.com/)のplaybookで実装するのは、この頃の私のデフォルト。一度コード化しておけば、何回も行う作業ならば、作業ミスも防げ、手順等をレビューなどで改善・改良できる。さらには資産にもなるので、もう私の中ではやらない手はないぐらい。

Mackerelを常用していると、その死活監視はその仕組み上リアルタイム性が劣るのを感じていた。特に電源管理・死活監視を司るslee-Piの開発・評価においては致命的になるかと考え、死活監視に関しては独自に実装する必要性を感じたので、boot・shutdown処理において直接slackに投稿する仕組みを実装することに

そのために、systemdのstartstop.serviceとして実装し、boot時に立ち上がったことを、shutdown時にはその旨のメッセージをslackにpostするようにした。当然、slackにはip reachableである前提。

そうこうするうちに、これを使えば、他の事にも使えると考え、実装したのがSTARTUP.shとSHUTDOWN.shをslackを叩くと同様なタイミングで実行する仕組み。

例えば、boot時に

```shell
sleep 300&&(sleepi2alarm --set "+5min" && shutdown -h now)
```

とやれば、５分後に

```shell
sleepi2alarm --set "+5min" && shutdown -h now
```

と投入されることになる。これによって、５分毎に起動・停止を延々と繰り返すRaspberry piができ上がり。

sleepi2alarmについては[sleepi2alarm](https://github.com/mechatrax/sleepi2-utils)を参照

さらには、

```shell
echo "(sleepi2alarm --set \"tomorrow 9:00:00\"&&shutdown -h)"|at 17:00
```

とやれば、9-5時にしか稼働しないRaspberry piができ上がります。
同様なシナリオとしては
boot時に

```shell
echo "shutdown -h now"|at 17:00
```
shutdown時に

```shell
sleepi2alarm --set "tomorrow 9:00:00"
```
と実行することでも可能です。
気を付けることとしては、boot時に時刻指定のshutdownコマンドを発行しないこと。例えば、

```shell
shutdown "17:00"
```
と投入すると、shutdownは17時に行われるが、Unprivileged usersがsshでログインできなくなり、色々と面倒なことになる。

これらのSTARTUP.sh/SHUTDOWN.shのコレクションは今後の評価・開発のシナリオに応じて充足していく予定。
JestでHTML5 FileAPI を使ったテストをする方法

# 概要

- HTML5 FileAPIのFileオブジェクトを使ったテストをJestで行う方法について書きます

# 前提

- Jestではフロントエンド アプリのテストもテスト時にNode.js用にコード変換して実行する
- この特性のため、Node.js用にブラウザ用のAPIをがんばって再現してる(JSDOM等つかって)
- なるべく~~Node.jsに媚びたコードを書かず~~フロントエンドのお作法だけでテストを書きたい

# FetchしたファイルをHTML5 Fileとして取り扱う方法

**やりたいこと**

Fetch APIを使って、あるURLからファイルをダウンロードしてきて HTML5 File APIのFileオブジェクトとして取り扱い、それをJestしたい。

## node-fetchをインストールする

フロントエンドでおなじみの<font color=red>Fetch API (window.fetch) はNode.jsには無い</font>ので、似た機能を提供する[**node-fetch**](https://www.npmjs.com/package/node-fetch)をインストールする

```
npm install --save-dev node-fetch
```

## fetchしたデータをHTML5 FileAPIのFileに変換して、それをJestする

コードは以下のとおり

```javascript
import fetch from 'node-fetch';

describe('Fetch on Node', () => {

    test('Get HTML5 "File" on Node ', (done) => {

        const path = 'https://riversun.github.io/img/riversun_256.png';

        fetch(path)
            .then(res => {

                return res.arrayBuffer().then(buffer => ({
                    contentType: res.headers.get('Content-Type'),
                    buffer: buffer
                }));

            })
            .then(data => {
                return new File([data.buffer], path, {type: data.contentType});
            })
            .then(file => {

                console.log(`fileName=${file.name} fileSize=${file.size} fileType=${file.type}`);

                //Write some tests
                expect(true).toBe(true);

                done();

            });
    });
});
```

ポイントは以下のあたり。

**node-fetch**で取得した`res.arrayBuffer()`をバッファとして`new File([バッファ])`で**File**を生成することができる。

（以前、[こちら](https://qiita.com/riversun/items/284f44b0a9950e9bdae2)の記事で、ブラウザ上でフェッチして**File**を紹介したが、この方法は**node-fetch**ではうまくいかなかった。**node-fetch**の**blob()**実装に何かありそう。）


```javascript

 .then(res => {

                return res.arrayBuffer().then(buffer => ({
                    contentType: res.headers.get('Content-Type'),
                    buffer: buffer
                }));

            })
            .then(data => {
                return new File([data.buffer], path, {type: data.contentType});
            })
```

# 参考情報

## ソースコード

紹介したコードを含む全ソースコードは https://github.com/riversun/jest_html5_file にあります

```shell:ソースコードの実行方法
npm clone https://github.com/riversun/jest_html5_file.git
npm instlal
npm test
```

## Jestの設定ファイルなど

Jestの設定ファイルなどは[こちらの記事](https://qiita.com/riversun/items/6c30a0d0897194677a37)と同様です
Links for AI


人工知能（AI)とは何か：ニューラルネットワーク入門
https://www.koi.mashykom.com/AI.html 

Jetson Nanoでリアルタイムに物体検出をする方法
https://qiita.com/karaage0703/items/67050f2418aa6bb3851a 


Jetson Nano 買ったので darknet で Nightmare と YOLO を動かすまで
https://toramamma.blogspot.com/2019/04/jetson-nano-darknet.html 


【物体検出】vol.2 ：YOLOv3をNVIDIA Jetson Nanoで動かす
https://www.nakasha.co.jp/future/ai/vol2_yolov3nvidia_jetson_nano.html 

Jetson Nanoにカメラを接続してリアルタイム画像類推を行う
https://denor.jp/jetson-nano%E3%81%AB%E3%82%AB%E3%83%A1%E3%83%A9%E3%82%92%E6%8E%A5%E7%B6%9A%E3%81%97%E3%81%A6%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%BF%E3%82%A4%E3%83%A0%E7%94%BB%E5%83%8F%E9%A1%9E%E6%8E%A8%E3%82%92%E8%A1%8C 
検索キーワード
https://www.google.com/search?q=jetson+%E7%94%BB%E5%83%8F%E8%AA%8D%E8%AD%98&rlz=1C1GCEU_jaJP868JP868&oq=jetson+%E3%81%8C&aqs=chrome.1.69i57j0l5j69i61.26278j0j4&sourceid=chrome&ie=UTF-8 


画像における物体検出用のアノテーションデータ作成に便利なツール
http://deep-architecture.hatenablog.com/entry/2017/09/26/003346 

Web Demos
http://www.robots.ox.ac.uk/~vgg/demo/ 
https://www.ipx.co.jp/tips 

機械学習 はじめよう
https://gihyo.jp/dev/serial/01/machine-learning/0021 


Python 機械学習入門
https://python.atelierkobato.com/kikai/ 

高校数学で理解・実装するニューラルネットワーク
https://qiita.com/perrying/items/6b782a21e0b105ea875c 

誤差逆伝播法をはじめからていねいに
https://qiita.com/43x2/items/50b55623c890564f1893 

NVIDIA Jetson TX2でTensorFlowによる人体姿勢推定プログラムを動かせるようになるまで
https://qiita.com/ababa831/items/57b43e788d684c380866 

NVIDIAが解説するディープラーニングの基礎
https://eetimes.jp/ee/articles/1804/26/news027.html 

画像認識で「綾鷹を選ばせる」AIを作る
https://qiita.com/tomo_20180402/items/e8c55bdca648f4877188 

KerasのCNNで、顔認識AIを作って見た〜スクレイピングからモデルまで〜
サンプル画像の集め方例。
https://qiita.com/yottyann1221/items/a08300b572206075ee9f 
PythonとKerasで画像認識CNN構築
https://qiita.com/mainvoidllll/items/db991dc30d3ddced6250
ゼロからのディープラーニング（コスト計算編）

[ゼロからのディープラーニング(フォワードプロパゲーション編)](https://qiita.com/sssssssiiiiinnn/items/3025c1e2460eeeeb5dba)の続きです。

前回はフォワードプロパゲーションを実装して入力値が$1$である確率$AL$を導くところまでを行いました。今回はモデルの精度向上のため、予測値と正解ラベルの誤差を導きだすところまでを実装します。


# コスト
本DNNは入力された画像が猫であるか否かを予測するものですので、コスト関数にはCross-entropy誤差を使います。

## Cross-entropy誤差
以下の式によって表されます。$AL$はYが1である確率を予測したもの、$Y$は正解ラベルです。
$$L(AL, Y) = \sum^m_{i=1}{(-Ylog(AL) - (1-Y)log(1-A))}$$

$Y=1$のとき$-log(AL)$を返し、$Y=0$のとき$log(1-AL)$を返します。以下のグラフから、予測値と正解が離れれば離れるほどコストが大きくなることがわかります。


![cross_entropy_cost_y_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315055/8b112c6d-d1cd-ba64-ee3b-b9deb415ec24.png)

![cross_entropy_cost_y_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315055/4f97c1c1-b8cd-41fd-3758-83cef125dffd.png)


関数にすると以下です。

```Python
def compute_cost(AL, Y):
    m = Y.shape[1]
    logprobs = np.multiply(Y, np.log(AL)) + np.multiply(1-Y, np.log(1-AL))
    cost = -1/m * np.sum(logprobs)
    return cost
```

ベクトル化された予測値$AL$と正解ラベル$Y$を渡すことでコストを返します。
ローカルでMysqlが急に動かなくなった

## 概要

いつも通りターミナルからmysqlコマンドでDBにログインしようとしたら以下のようなエラーがでた


```bash
$ mysql -u **** -D **** -h **.***.***.*** -p
dyld: Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
  Referenced from: /usr/local/bin/mysql
  Reason: image not found
Abort trap: 6
```

### やったこと

ん~なんか調べてもよくわからん
結果いろんな記事見てったらbrewでインストールしなおすのが一番簡単で早いっぽい


#### 1. アンインストール

```bash
$ brew uninstall mysql
Uninstalling /usr/local/Cellar/mysql/5.7.21... (323 files, 233.9MB)
```

#### 2. インストール

```bash
$ brew install mysql
Updating Homebrew...


(以下略)
```


#### 3. ログイン

```bash
$ mysql -u **** -D **** -h **.***.***.*** -p
Enter password:
```
動いた

### 事後に思ったこと

よくよく考えたらmysql起動しているかとか見るの忘れてた...
もしかしたらそれで解決したかも...


### おわり
[初心者向け]UserDefaultsを使って永続的に配列を保存する

## Userdefaultsの復習

### UserDefaultsのインスタンスの生成
まずはUserDefaulsのインスタンスをクラスの上部で作成します

```ViewController.swift
var userDefaults = UserDefaults.standard
```

### データを保存する
次にデータを保存します．
UserDefaultsは`Int`, `String型`, `配列`, `Date型`, `Float型`, `Double型`の保存に対応していて、保存の方法は全て同じです．

今回は`names`という配列を保存します．

```ViewController.swift
userDefaults.set(names, forKey: "キー")
```

### データを取り出す

次にデータを読み出してみます．
取り出す場合は取り出す変数の型により取り出し方が異なります．

#### Int型

```ViewController.swift
let number = userDefaults.integer(forKey: "キー")
```

#### String型

```ViewController.swift
let name = userDefaults.string(forKey: "キー")
```

#### 配列

```ViewController.swift
let names = userDefaults.array(forKey: "キー")
```

#### Date型

```ViewController.swift
let date = userDefaults.object(forKey: "キー") as? Date
```

## 配列を保存する場合の注意

配列をUserDefaultsを使って保存する場合を考えてみます．
このような場合、そのまま保存して良いのでしょうか？

**違いますね**

配列に保存する場合は、**事前に保存されているデータを読み込んでから**そこに追加をして、保存する必要があります．
そうしないと、毎回データを上書きしてしまい、一向に追加して保存されません．

### 保存する
`names`というString型の配列に変数`name`を保存する場合を考えてみます．

まず保存してあるかどうかを判別し、保存してあれば中身を取り出します．

```ViewController.swift
var names = userDefaults.array("キー") as? [String] ?? []
```
上で使用している`??`は、保存されたデータがない場合に`names`に空の配列を代入させるために使用しています．

次に実際に`names`に新たなデータを追加して保存していきます．

```ViewController.swift
names.append(name)
userDefaults.set(names, forKey: "キー")
```
配列に変数を新たに追加する場合は`append`というメソッドを使用します．

上記をまとめるとこんな感じです．

```ViewController.swift
var names = userDefaults.array("キー") as? [String] ?? []
names.append(name)
userDefaults.set(names, forKey: "キー")
```

### 取り出す場合
取り出す場合は特に留意する点はありませんが、`userDefaults`で取り出す値はどれもオプショナル型になっているため、同じように`??`演算子を使用します

```ViewController.swift
let names = userDefauls.array("キー") as [String] ?? []
```

## 最後に
初めてUserDefaultsで配列の保存や取り出しを行う際に、うまく保存できずにつまづいた経験があったので共有しました．
アークナイツマクロ

```python
import pyautogui
import cv2
import time

def ark(x):
    pyautogui.screenshot('filename.png')
    img = cv2.imread("filename.png", 0)
    temp = cv2.imread(x, 0)
    result = cv2.matchTemplate(img, temp, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    if max_val >= 0.90:
        pyautogui.click(max_loc)
    time.sleep(1)

pyautogui.PAUSE = 3

while 1:
    ark("ark2.png")
    ark("ark3.png")
    ark("ark5.png")
    ark("ark6.png")
```

![ark2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580670/019ee245-836b-ab2e-df9e-e36de39c82ef.png)
![ark3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580670/f8b85d20-f431-446d-1813-464c32ead25a.png)
![ark5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580670/e25454a8-ed9b-87a0-94d2-8d5f20be37b4.png)
![ark6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580670/4f20ac60-5476-0989-912b-15de2744e6fa.png)
【Flutter】画面の向きを縦や横に固定する

縦固定するなら `main.dart` にこのように書く。

```dart:main.dart
void main(){
  WidgetsFlutterBinding.ensureInitialized();
  //向き指定
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,//縦固定
  ]);
  //runApp
  runApp(MyApp());
}
```

`WidgetsFlutterBinding.ensureInitialized() ` を最初に書かないと起動時に以下のようなエラーメッセージが出てしまうので、書いておきましょう。

> FlutterError (ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized.
If you're running an application and need to access the binary messenger before `runApp()` has been called (for example, during plugin initialization), then you need to explicitly call the `WidgetsFlutterBinding.ensureInitialized()` first.
If you're running a test, you can call the `TestWidgetsFlutterBinding.ensureInitialized()` as the first line in your test's `main()` method to initialize the binding.)

参考: https://github.com/flutter/flutter/issues/40253

#### DeviceOrientation

以下の4パターンの指定ができます。

```dart
enum DeviceOrientation {
  portraitUp,
  landscapeLeft,
  portraitDown,
  landscapeRight,
}
```
ソフトウェア開発でのレジェンド評議会の有用性

#レジェンド評議会(LS)

総統　ソフトウェア開発のすべての責任者
書記長　**権力透過性**を利用し権力者の行動を可視化する。
評議員　ソフトウェアの関係者の収入の**遅延評価**を行う。不正が発覚した場合、書記長に連絡し適切な**社会的処分**を与える。
財経員　**財事**を行う。**公式SNSの運用**なども行う。
誘導員　ソフトウェア開発関係者の**幸福度を最大にする仕事**である。**GLの提供**、**自由の向上**、**他の構成員の仕事の作業を減らす**など重要な仕事である。
無名委員　評議員の不正を**監視**する。不正が発覚した場合、**権力透過性を利用しいじめがないと判断**した上で書記長により**社会的処分**を与える。
※再帰総統制　1か月ごとに役職を変更
再帰総統制を行うとチームの実力と団結力が向上し、**ソフトウェア品質が高水準で一定化**することができる。

#委員主義とは
構成員券を持つと他人にアドバイスを与えることができる。構成員券は財経員から買うことができる。その構成員がやめたり、社会的処分を受けた場合、無くなる場合もある。構成員全体に毎月仮想構成員券を配る。仮想構成員券は自分に対しては半分までしか投資できない。仮想構成員券で多いものが多く金が支払われる。仮想構成員券を保持していると構成員券と同じ効果が３倍受けられる(但し、1か月しかもたない)。
【rails】開発環境のデータをseed_dumpを使ってseedファイルとして書き出す

#はじめに
初学者がポートフォリオ作成でハマったことをメモします。

以前書いた記事でwebサイトからデータをスクレイピングして開発環境用のデータベースに保存した。
https://qiita.com/tsubasaweb1/items/5be78cefed67020ac483

今回は本番環境のデータベースへの保存を試みた。
しかし、herokuの「Cleardb」というアドオンを使ってMySQLを使用している為、時間当たりのクエリ数に制限があり、全てのデータを保存することができなかった。
そこで今回はseed_dumpというgemを使って開発環境のデータを分割して2つのseedファイルに書き出した。
その後2つのseedファイルを使って本番環境にデータを流し込んだ。




##環境
Ruby 2.6.3 ,Rails 5.2.4
インフラ：heroku

##手順
<b>・</b> gemをインストール

```ruby:Gemfile
gem 'seed_dump'
```
```ruby:ターミナル
$ bundle install
```
</br>
<b>・</b> db/seedsディレクトリを作成 (seed_dumpをデフォルトで使用するとdb/seeds.rbを上書きしてしまう)
</br>
<b>・</b>以下のコマンドを実行

```ruby:ターミナル
$ bundle exec rails db:seed:dump MODELS=Fish FILE=db/seeds/20200101_fish.rb
```
`MODELS=Fish`で書き出すテーブルを指定。`FILE=db/seeds/20200101_fish.rb`で作るファイル名を指定。今回はファイル名を変えて２回行い、お互いのデータを補完するように半分ずつデータ消した。

</br>
<b>・</b>db:seed用のrakeタスクを作成


```ruby:lib/tasks/seed.rake
Dir.glob(File.join(Rails.root, 'db', 'seeds', '*.rb')).each do |file|

  desc "Load the seed data from db/seeds/#{File.basename(file)}."

  task "db:seed:#{File.basename(file).gsub(/\..+$/, '')}" => :environment do

    load(file)

  end

end
```

</br>
<b>・</b>heroku にpushする

<b>・</b>データを追加したいテーブルに既にデータがある場合以下を実行してレコードを消去

```ruby:ターミナル
$ heroku run rails db:migrate:reset DISABLE_DATABASE_ENVIRONMENT_CHECK=1 #全てのテーブルのレコードを消去
$ heroku run rails db:seed #db:seeds.rbのデータを入れる
```



</br>
<b>・</b>dumpしたファイルを指定し、本番環境にデータを流す(今回は2つファイルを作ったのでファイル名を変えて2回行った。)

```ruby:ターミナル
$ heroku run rails db:seed:20200101_fish RAILS_ENV=production
```



##最後に
誰かのお役にたてれば幸いです。
間違えている部分があればコメントお願いいたします。

参考にした記事
https://gist.github.com/seak0503/5aa5db45abfac5c42a06
http://gre.hacca.jp/2018/09/12/rails-db%E3%83%80%E3%83%B3%E3%83%97%E3%81%A8%E3%83%AA%E3%82%B9%E3%83%88%E3%82%A2%EF%BC%88%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%81%A8heroku%EF%BC%89/
https://github.com/rroblak/seed_dump
【2020年2月】プロジェクトごとのnode.jsのバージョンを、direnv+nvmで【強制】【固定】

# プロジェクトごとにNode.jsのバージョンが異なって辛みマシマシ

そんな時は以下の処方箋がおススメ。
例えば node.js 10 を強制的に使用する場合は以下のようにプロジェクトのフォルダ直下に`.envrc`ファイルを作成し、nvm で `10` を指定しておきます。

```bash:.envrc
[[ -s ~/.nvm/nvm.sh ]] && . ~/.nvm/nvm.sh
nvm use 10
```

で、コマンドから direnv を有効にします。

```bash
$ direnv allow .
```

以上！

## direnv、nvm のリンク

- [nvm: Node Version Manager](https://github.com/nvm-sh/nvm)
- [direnv: unclutter your .profile](https://direnv.net/)
- [direnv | Github](https://github.com/direnv/direnv)
Puppeteer入門  Googleの検索結果を表示するサンプルアプリ

# はじめに
Puppeteerの使い方メモ。
アプリのセットアップから、Google検索できるまでの方法をメモ。

# 事前作業
Node.jsをインストールしておくこと。

# 手順
- 任意のフォルダを作成し、移動。
- 以下のコマンドを実行し、npmを初期化＆Puppeteerインストール

```
npm init

~その後、アプリ名等を記載（ここでは省略）~

npm install puppeteer
```

- test.jsをファイルを作成。

```test.js
const puppeteer = require('puppeteer');

(async () => {
const browser = await puppeteer.launch({
  headless: false,
  defaultViewport: { width: 2048, height: 1048 }
});
const page = await browser.newPage();

// Goolgeのページに移動
await page.goto("https://www.google.co.jp/");

// 検索ワードを入力　以下の例では"Puppeteer"
await page.type('input[title="検索"]', "Puppeteer", { delay: 50 });

//　検索ボタンをクリック
await page.evaluate(() => {
  document.querySelector('input[value^="Google"]').click();
});

// ページ遷移を待ちます。
await page.waitForNavigation({timeout: 600000, waitUntil: "domcontentloaded"});

  console.log('検索結果がブラウザに表示されました。');
})();
```
- 以下のコマンドで実行

```
$ node test.js
```