OmniAICreator/Qiita-1.07M huggingface dataset:
Bitbucketで特定プロジェクトのリポジトリ一覧を取得する

# 概要

[Bitbucket API](https://developer.atlassian.com/bitbucket/api/2/reference/)で特定プロジェクトのrepository名リストを取得します。



## Requirement

APIレスポンスの加工に[jq](https://stedolan.github.io/jq/)コマンドを使用するので適宜インストールしてください。

```shell
# macの場合 以下でOK
brew install jq
```

# 手順

以下のスクリプトを作成。

```list_bitbucket_repositories.sh
#!/bin/bash

bitbucket_username=$1
bitbucket_password=$2
workspace_id=$3
project_name=$4

PAGE_LEN=100

repo_size=`curl -s -u ${bitbucket_username}:${bitbucket_password} https://api.bitbucket.org/2.0/repositories/${workspace_id} | jq '.size'`
page_count=$((repo_size / PAGE_LEN + 1))

for page in `seq ${page_count}`
do
  repos=`curl -s -u ${bitbucket_username}:${bitbucket_password} "https://api.bitbucket.org/2.0/repositories/${workspace_id}?pagelen=${PAGE_LEN}&page=${page}&sort=name" | jq ".values | map(select(.project.name == \"${project_name}\"))" | jq '.[]' | jq -r '.name'`
  echo "${repos}"
done
```

実行します。

例として、WorkSpaceID=`testworkspace` のワークスペース配下にプロジェクトが複数あり、その中の`TestProject`というプロジェクトに紐づくリポジトリ名のリストを取得したい場合を考えます。

```bash

$ sh list_bitbucket_repositories.sh {bitbucketログインアカウント} {bitbucketログインパスワード} {ワークスペースID} {プロジェクト名}

# 例
$ sh list_bitbucket_repositories.sh testuser testpass testworkspace TestProject
test-android-repo
test-ios-repo
test-server-repo
...
```

## 内容

### 1. ワークスペース内の全リポジトリ数を取得

```bash
$ curl -s -u {bitbucket_username}:{bitbucket_password} 'https://api.bitbucket.org/2.0/repositories/{workspace_id}' | jq '.size'

# 例
$ curl -s -u testuser:testpass 'https://api.bitbucket.org/2.0/repositories/testworkspace' | jq '.size'
388
```

ワークスペース内にリポジトリが388件あることが分かります。

### 2. リポジトリ名を取得

```bash
$ curl -s -u {bitbucket_username}:{bitbucket_password} 'https://api.bitbucket.org/2.0/repositories/{workspace_id}?pagelen=100&page=1&sort=name' | jq '.values | map(select(.project.name == "{project_name}"))' | jq '.[]' | jq -r '.name'

# 例
$ curl -s -u testuser:testpass 'https://api.bitbucket.org/2.0/repositories/testworkspace?pagelen=100&page=1&sort=name' | jq '.values | map(select(.project.name == "TestProject"))' | jq '.[]' | jq -r '.name'
test-android-repo
test-ios-repo
test-server-repo
...
```

ワークスペース内の全リポジトリ一覧から`TestProject`プロジェクトに紐づくリポジトリのみフィルタし`name`フィールドを出力します。
APIのレスポンス数(`pagelen`)は100が最大なので、必要に応じて`page`パラメータをincrementします。

詳細は[API document](https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Bworkspace%7D)を参考にしてください
kindle検索のchrome拡張作ってみた

#Chrome拡張はショートカット作るのと同じ感覚
##Twitterみてたら本がオススメされてた
Twitterみてたら好きな絵師さんが「この漫画面白すぎい！」ってツイートしてた
気になってkindleで検索してsample読んだらマジで面白かったからポチってしまった
でも検索が結構めんどかったんよなあ
だって
本の題名コピー
↓
amazon開く
↓
amazonの検索条件をkindleにして題名を検索バーにペースト
↓
検索結果
ってやるの結構手間じゃん
ブクマしていてもめんどいし一発でやりたいなーって思った
##Chrome拡張でつくってみた
題名を選択して右クリック、そこからkindleで検索ってやると検索できる拡張を作ってみた
https://twitter.com/nya3_neko2/status/1211293878457782274?s=20
だが作ったのはいいんだが「kndle検索のショートカットのchrome拡張を作ったはいいが脳死でポチる可能性が高くなるのでオススメできない」
##chrome拡張の中身
.
├── background.js
├── icon.png
└── manifest.json
まあこのchrome拡張はクソ簡単
基本的にchromeのバックグラウンドで動き続けているタイプ
書くのはchrome拡張について記述するjsonとプログラムのJSだけ
あとはアイコン画像
##ソースコード
```JS
chrome.contextMenus.create({
    "title": "kindleで「%s」を検索",
    "type": "normal",
    "contexts": ["selection"],
    "onclick": function(info) {
        chrome.tabs.create({
            url: 'https://www.amazon.co.jp/s?i=digital-text&k='+encodeURIComponent(info.selectionText)
        });
    }
});
```
内容は右クリックでメニュー開いた時にやる内容はこれ〜って言うのを書いてある
titleは右クリックの時に出てくる言葉
onclickがそれをクリックした時にする動作
これは新しいタブを生成してこのURLにいくよってやつ

```JSON
{
    "name": "kindle search shortcut",
    "version": "0.0.1",
    "manifest_version": 2,
    "description": "選択したテキストをkindleで検索",
    "icons": {
        "16": "icon.png",
        "48": "icon.png",
        "128": "icon.png"
    },
    "permissions": [
       "contextMenus"
    ],
    "background": {
       "scripts": ["background.js"]
    }
}
```

JSONの方はあんまり考えなくていいよ
manifest.jsonでぐぐれば出てくるから
おれもよくわかってない

##う〜ん
つぎはポップアップでなんかしてみたいな〜って思う
フラクタル図形を描く(Koch曲線)

# Koch(コッホ)曲線

何はともあれ、Koch曲線はこのような「自己相似性」をもった図形です。
![koch_head.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101445/7891bbe1-9582-f31e-a83a-21c96e2993a5.png)


描き方の手順は以下です：

- 横(X軸方向)に長さLの直線を引く
- この線を３等分し、真ん中の直線の端を２頂点とする正三角形を描く
- 真ん中の直線（正三角形の底辺）を消す
- それぞれの辺に対して上記３ステップを適用、というのを無限に繰り返す

手作業はもちろんの事、プログラムでも、無限に繰り返す事はできないので、上記ステップを８まで繰り返した結果です。

![koch_8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101445/95513345-4be7-99e7-0b2d-01a59e2598c2.gif)

# タートルグラフィクスを使った描画コード

前に描いた記事「[フラクタル図形を描く(道具編)](https://qiita.com/fujim2/items/a4a3e3b8c1824c09fd02)」で紹介した簡易タートルグラフィクスライブラリのコードturtle.cxxを利用して、koch曲線を描画するコードを以下に紹介します。

```c++
// kochmain.cxx
#include <stdio.h>
#include <math.h>
void pd();
void pu();
void rt(float th);
void lt(float th);
void fd(float len);
void bk(float len);

void koch(float len, int n) {
  if(n > 0) {
    koch(len/3.0, n-1);
    lt(60.0);
    koch(len/3.0, n-1);
    rt(120.0);
    koch(len/3.0, n-1);
    lt(60.0);
    koch(len/3.0, n-1);
  } else {
    fd(len);
  }
}

int main(int argc, char **argv)
{
   pd();
   rt(90.0);
   koch(10.0, 6);
}
```

ビルド、実行は以下で。

```sh
$ g++ kochmain.cxx turtle.cxx -o kochmain
$ ./kochmain > tt.dat
```

描画も「[フラクタル図形を描く(道具編)/描画](https://qiita.com/fujim2/items/a4a3e3b8c1824c09fd02#%E6%8F%8F%E7%94%BB)」と同様に、gnuplotを利用します。

# Koch Snow-flake

koch曲線を３つ組み合わせて、以下のような絵が描けます。

![koch_snowflake.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101445/e70fad2e-eafe-d505-7c41-bcb353f87408.png)

Snow-flake（雪片）や、Island(島）と呼ばれているようです。


コードはmainを以下のように書き換える事で簡単に実装できます。

```c++
int main(int argc, char **argv)
{
   pd();
   rt(90.0);
   for(int i = 0; i < 3; i++) {
     koch(10.0, 6);
     rt(120.0);
   }
}
```

# koch「曲線]?

Koch曲線は、「曲線」という名前がついています。しかし、手順的にも、プログラム的にも、描いているのは「直線」だからか、何か腑に落ちないところがあります。

```
「無限にやったからといって曲線といって良い代物だろうか」
```
と。。

## 微分不可能

おそらく、通常我々が知っている（想定している）曲線のほとんどは、

「なめらかな」

曲線だからかもしれません。

この言葉は、数学の言葉に置き換えると、この曲線上のいたるところが「微分可能」という事になります。
あまり厳密な話に突入するつもりはありませんが、このことは、Koch曲線がどういう図形なのか、なんとなくでも想像できる鍵になると思います。

高校生くらいまでに習う、二次曲線やsin(x), cos(x)のような関数で描画する曲線は、定義域の範囲でどんな値を持ってきても、その点でその関数の「傾き」が決まります。しかし、koch曲線はそうではありません。
このような性質はフラクタルな性質を持つ図形がは往々にして持つもののようです。

# フラクタル次元
そして、数学的な概念「フラクタル次元」の観点からkoch曲線を眺めるのも面白いと思います。フラクタル次元という次元は、通常我々が使う0(点),1(線),2(面),3(立体)といった「整数次元」だけでなく、その中間の「非整数次元」を取り扱います。例えば、koch曲線のフラクタル次元は、、

```
1.2618595
```
という事です([Wikipeida](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%83%E3%83%9B%E6%9B%B2%E7%B7%9A)より）。



今回は以上です。
Helm 3.0でkubernetesに簡単導入

Kubernetesにアプリを簡単に入れられるHelmがv3へメジャーアップデートされ、Tillerがなくなることで操作性が変化したので試す。

今回はElasticsearchとKibanaを入れる。環境はWindowsのDocker desktop付属のkubernetesを使用。

#1. Helmのインストール
###1.1 Helmのインストール
Windowsの場合はChocolateyを使用する。Chocolateyのインストール方法は下記参照。  
https://chocolatey.org/install


Chocolateyのインストール後はコマンドプロンプトやPowerShell等のコンソールからHelmをインストール。

```
> choco install -y kubernetes-helm
```
###1.2 Chart（必要なアプリケーションの集合）を検索
Helmでは必要なアプリケーション（コンテナ）の集まりをChartと呼ぶ。
search repo コマンドで目的のChartに関して検索可能。

```
> helm search repo Chart名
```

#2. HelmでElasticsearchをインストール
###2.1 ElasticsearchのChartを検索
今回のターゲットとなるElasticsearchをhelmにて検索。

```
# ElasticsearchのChart検索
> helm search repo Elasticsearch
```

![2019-12-29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377965/6762a50c-7bbc-ba63-372f-887954ddd543.png)

一番上のbitnami/elasticsearchを今回はインストールする。
表示されたURLをブラウザに入力する。

![2019-12-29 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377965/3a8aa5fc-a425-921f-31e9-00e77670864b.png)

###2.2 レポジトリの登録とChartのインストール
表示された下記コマンドを入力。

```
# レポジトリの登録（Chartのインストールに必要）
> helm repo add bitnami https://charts.bitnami.com
> helm repo add stable https://kubernetes-charts.storage.googleapis.com
# Elasticsearch Chartのインストール（設定なし)
> helm install elasticsearch bitnami/elasticsearch
```
elasticsearchという名前でbitnami/elasticsearchがインストールされる。
設定を変えるため、一旦アンインストール。

```
helm delete elasticsearch
```

#3. Chartの設定変更（Kibanaのインストール）

Chart（アプリケーションの集合）の設定をファイルに出力する。

```
helm inspect values bitnami/elasticsearch > config.yml
```
config.yml中の14行目、global中kibanaEnabledのfalseをtrueに変更
これでElasticsearchと同時にKibanaがインストールされる。

```
  kibanaEnabled: true
```

変更した設定を反映しつつElasticsearch Chartのインストールを実施。この変更によりKibanaも同時にインストールされる。

```
> helm install elasticsearch bitnami/elasticsearch -f config.yml
```

コマンドプロンプトやPowerShell等のコンソールから、下記を入力して
Kibanaのサービスをローカルにポートフォワードする。

```
> kubectl port-forward svc/elasticsearch-kibana 80:80
```
ブラウザでlocalhost:80と入力してKibanaを開く。
デモデータを入れると下記のダッシュボードが閲覧可能。
![2019-12-29 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377965/eab9bbae-0c2d-62d5-e798-afa18090107a.png)

KibanaとElasticsearchを個別にコンテナとしてインストールすると、コンテナ上のKibanaからElasticsearchを認識させるのがDNSの関係でしんどい。Helmを使えば、各種コンテナがパッケージ化されているため楽に処理できる。

Ingressを使って、Elasticsearchをlocalhostで公開し、Kibanaは80以外のポートを使ってポートフォワードで使用するのが最適解だろうか。
Elasticsearchは階層で認識する方式なので、ingressと相性が悪い。Ingressで80以外のポートを指定できれば便利なのだが……。

ElasticsearchとKibanaのOSS版だけでは外部データの取り込みが難しいので、EmbulkかFluentdの追加に関して追記するかも。
（一般的なCSV取り込みは有償版Kibanaの機能）

以上
v-modelのcomputedを動的に定義する方法

オブジェクトをコンポーネントにバインドする時に困ったことがありました。
例えば以下の様な例で考えてみます。

この例ではコンテナ層とプレゼンテーション層でフォームデータをバインドしています。
今回はdataとしてpostFormオブジェクトを定義しており、項目数は２つです。

```PostConatainer.vue
<script>

import Post from '../../components/Post/Post.vue'

export default {
  components:{
    Post,
  },
  data(){
    return {
      postForm:{
        name: null,
        photo: null
      }
    }
  },
  render: function(createElement){
    return createElement(Post,{
      props:{
        value: this.postForm
      },
      on: {
        "input" : ($event) => { this.postForm = $event },
      },
    })
  }

}

</script>

```

propsとして受け取ったPost.vueではフォーム項目をcomputedのプロパティとして定義しています。
でもこれ仮に項目数が100個に増えると、computedの定義も100個にしなければいけないと思いませんか？

````Post.vue
<template>
  <div class="form">
    <el-form ref="form" label-width="120px">
      <el-form-item label="名前">
        <el-input v-model="name"></el-input>
      </el-form-item>
      <el-form-item label="写真">
        <el-input v-model="photo"></el-input>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>

export default {
  props:['value'],
  computed:{
    name:{
      get(){
        return this.value.name
      },
      set(val){
        this.$emit('input',{ ...this.value, name: val})
      }
    },
    photo:{
      get(){
        return this.value.photo
      },
      set(val){
        this.$emit('input',{ ...this.value, photo: val})
      }
    }
  }
}

</script>

```

#解決策

vueのライフサイクルフックであるbeforeCreateでは算出プロパティを定義することができます。
今回$optionsを使用してカスタムプロパティを定義します。


```Post.vue
<template>
  <div class="form">
    <el-form ref="form" label-width="120px">
      <el-form-item label="名前">
        <el-input v-model="name"></el-input>
      </el-form-item>
      <el-form-item label="写真">
        <el-input v-model="photo"></el-input>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>

export default {
  props:['value'],
  methods: {
    emitData(val) {
      this.$emit('input',{...this.value, ...val});
    },
  }, 
  beforeCreate() {
    [
      'name',
      'photo'
    ].forEach((key) => {
      this.$options.computed = 
        {...this.$options.computed,
          [key] : {
            get() {return this.value[key];},
            set(val) {this.emitData({ [key]: val });},
          }
        }
    });
  },
}
</style>

```

これで項目数が増えても、キーを足していくだけで追加することができます！。
本当はObject.keysでforEachしたかったですが、beforeCreateの段階ではthis.valueがundefinedとなりました。
これは改善したいので、方法があれば教えて頂きたいです。
Python初心者が「Python文法詳解」を読んだメモ #7

# バックナンバー
- [Python初心者が「Python文法詳解」を読んだメモ #1](https://qiita.com/usayomo/items/7024c619c5f72462cb10) 
- [Python初心者が「Python文法詳解」を読んだメモ #2](https://qiita.com/usayomo/items/9c1537678bdde813a273)
- [Python初心者が「Python文法詳解」を読んだメモ #3](https://qiita.com/usayomo/items/57e6156c95e60b3223ca)
- [Python初心者が「Python文法詳解」を読んだメモ #4](https://qiita.com/usayomo/items/01fdb8bbe7704da236bb)
- [Python初心者が「Python文法詳解」を読んだメモ #5](https://qiita.com/usayomo/items/eb2c59b538f5c349bc52)
- [Python初心者が「Python文法詳解」を読んだメモ #6](https://qiita.com/usayomo/items/db5a79ca379480cc349e)

## タプル
- どんなオブジェクトでも自由に登録可能
- リストと似ているが、更新不能（作成後の要素追加・削除などはできない）
- 要素は他のオブジェクトへの参照
- 当然シーケンスオブジェクトなので、添字やスライスでの要素取り出しが可能。

```py:タプル
# 基本の書き方はリストと同じ。
t = (1, 2, 3)
t = ()
t = (1, 'Two', [3, 4])

# タプルリテラルの()は省略可能（ただし空タプルの場合は必須）
>>> t = (1, 2, 3)  # これは
>>> t
(1, 2, 3)
>>> t = None
>>> t
>>> t = 1, 2, 3  # こう書ける
>>> t
(1, 2, 3)

>>> t = 1,  # 一つの整数値からなるタプル
>>> t
(1,)
```

```py:タプルを利用した2変数値の入れ替え
# CやJavaだと一時保存の変数が必要になるが、Pythonだとこんな感じでできる
>>> a = 1
>>> b = 2
>>> b, a = a, b   # b, a = (a, b)
>>> a
2
>>> b
1
```

```py:タプルのメソッド
# 引数と等しい値の要素数を取得
>>> t = (1, 2, 1)
>>> t.count(1)
2

# 引数と等しい値の要素を検索して最初に一致した要素のインデックスを返す
>>> A = (3, 4, 5, 3, 4, 5)
>>> A.index(4)
1
```

### リストとタプルの位置付け・使い分け
- 更新不能シーケンス（つまりタプル）は、辞書のキーや集合の要素として使用できるというメリットがある。
- リストの要素はそれぞれが独立したデータ（例えば、「ユーザ名のリスト」「売上金額のリスト」など）で、
決まったデータのリストとして作成するのが一般的。  （RDBだったら列を入れるイメージ？）
- タプルは、タプル全体でデータとして意味を持つ（要素単独では意味をなさない）ような場合に使われる。（RDBだったら行を入れるイメージ？）
- なので、タプルは配列というよりは構造体に近い使い方になる。
- タプルは固定長シーケンスであるためリストよりもメモリ利用効率が良い。上記方針を踏まえると、タプルで保持したいようなデータは性質上大量になるケースも珍しくないため、リストではなくタプルを適切に利用することで効率的なリソース利用やガベージコレクションの負荷軽減が期待できる。
Gitについてのメモ２

[サルでもわかるGit入門](https://backlog.com/ja/git-tutorial/)を読んで僕のようなサルでも理解ができたが、忘れないようにここにメモしておきます。

## ブランチとは/使いどき
ソフトウェア開発をチームで行っている場合、一つのソフトウェアに対して複数人が同時に新機能の追加やバ グ修正を行うことがある。
この時に並行して行われる機能追加やバージョン管理のために<strong>ブランチ</strong>という機能 がある。
 
<strong>ブランチ</strong>とは、履歴の流れを分岐して記録していくもの。
メリットは、ブランチを分岐させると、他のブランチの影響を受けない。つまり、他の人が加えたり変更したことの影響を 受けずに開発ができる。 （自分が頑張って追加したCSSが他の人に全部消されちゃった！とかが起こりにくくなる。）

## ブランチの種類　統合ブランチとトピックブランチ 

トピックブランチとは ある課題（例：機能追加・バグ修正など）に関する作業を行うために作成するブランチ。 複数の課題に関する作業を同時に行う場合はその数だけトピックブランチが作成される。 トピックブランチでの作業が完了したら統合ブランチに取り込む。 

統合ブランチとは リリース版がいつでも作成可能にしておくためのブランチ。通常はMaster Branchがこれにあたる。 何か変更をする場合は、トピックブランチを作成し作業をする。 

## チェックアウトでブランチを切り替える
 チェックアウトを行うと、移動先の最後のコミットの内容がワークツリーに展開される。 最後にやったコミット（最新のコミット）がHEADとなる。 最後のコミットってなんだったっけ？って時にgit show HEADで行われた最新のコミット情報が見れる。 HEADがなければ長いコミットのハッシュ値を打たなければならない。  

## 消したファイルもコミットする必要性
 Git管理下のファイルは、「消した」こともちゃんと明示しなければならないのです。
Gitは、Git管理下に置かれたファイルを常にくまなく監視していますが、 ファイルを消したからといってそれを自動的に消す処理をしてくれるわけではない。

今回は、本当に自分が忘れたくないことをメモしただけなので、もし詳しくGitのことが知りたい方はこちらのサイトをみるとわかりやすいかと思います。
[サルでもわかるGit入門](https://backlog.com/ja/git-tutorial/)。ちなみに、ブランチに関しては発展偏に詳しく書かれています。

お読みいただきありがとうございました。
Azure PipelineでAzure Web AppsのCI/CDをやってみる

#0. はじめに
Azure Pipelineを使ってどういうことができるのか知りたいので、とにかく使ってみようと思った。
まずは、Azure Web Appsへのデプロイを構築してみようということで、やったことをメモ。
（MSDNのチュートリアルとそんなに変わらなさそうだけど･･･）

###0.1 開発環境
- Windows 10 1809 x64 Home
- Visual Studio Community 2019(以降、VS2019)

###0.2 すでにやってあること
- VS2019で、.NET Coreのソリューションを作成済み(デプロイはしてない)
- GitHubに、.NET Coreのソリューションをプッシュ済み
- Azure Web AppsをFree枠で作成済み
- Azure DevOpsで、GitHubを登録済み
- Azure DevOpsで、WebAppsのためのプロジェクトを作成済み
- Azure Pipelinesで、GitHubのソースをビルドするPipelineを作成済み

#1. Azure Web Appsのデプロイ
以下の手順でやってみた。（スクショ載せようかと思ったけど、Azureってコロコロ画面変わるから載せてもしょうがないかなぁと思って、さぼった）
(1) Azure portalにサインイン
(2) Web Appsを選択
(3) デプロイメントの「デプロイセンター」を選択
(4) ソース管理で「Azure DevOps」を選択
(5) ビルドプロバイダーで「Azure Pipelines」を選択
(6) 構成で、以下の通りに選択
#####コード
- Azure DevOps組織：Azure DevOps作った時に自分でつけた名前
- プロジェクト：Azure DevOpsで作成したプロジェクト
- リポジトリ：GitHubで作成したリポジトリ
- ブランチ：master

#####ビルド
- Webアプリケーションフレームワーク：ASP.NET Core

(7) 完了を選択

しばらくしたら、画面に「継続的デリバリーが正常にセットアップされ、ビルドがトリガーされました」と表示された。

#3. デプロイの確認
Web AppsのURLにアクセスしたら、VS2019で作ってあったASP.NET CoreのWebページが表示された。 
また、Azure DevOpsのAzure Pipelineをのぞいてみたら、新しいパイプラインができていた。

すごーい。(小並感)
実は、もともとは先にPipelineを作っておいて、既存のWebAppsにデプロイしようとしてたんですよね。
でも、なんか失敗したからAzure WebAppsのほうでやってみた、って感じ。

こっちのがいいな。まあ、すぐできたからそう感じるってだけなんだけど･･･
今度は、実際にソースに修正をコミットしてみよう。
きょうはここまで。
年末まで毎日webサイトを作り続ける大学生 〜72日目 Mouse Overと画像~

##はじめに
こんにちは！@70days_jsです。
mouseoverで画像が少しずつ現れるサイトを作りました。(gif)↓

![test3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516248/933232ef-549d-d3b2-d8fa-35faebc9be5d.gif)

今日は72日目。(2019/12/29)
よろしくお願いします。

##サイトURL
https://sin2cos21.github.io/day72.html

##やったこと
mouseoverで画像が少しずつ現れるものを作りました。

今回JavaScriptとcssで作ったので、htmlは何も書いていません。

html↓

```html
  <body></body>
```

cssではあらかじめ画像を表示したり、スタイルを用意しています。

css↓

```css
body {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  margin: 0;
  background-image: url("day31_image/4.jpg");
  background-size: cover;
}

.oneBlock {
  background-color: white;
  position: absolute;
  border-right: solid 2px black;
  border-bottom: solid 2px black;
  display: flex;
  justify-content: center;
  align-items: center;
}
```

JavaScript↓

```javascript
let bodyWidth = window.innerWidth,
  bodyHeight = window.innerHeight,
  oneBlockWidth = bodyWidth / 10,
  oneBlockHeight = bodyHeight / 10,
  oneBlockList = [];

for (var i = 0; i < 10; i++) {
  for (var j = 0; j < 10; j++) {
    let div = document.createElement("div");
    div.classList.add("oneBlock");
    div.style.width = oneBlockWidth - 1 + "px";
    div.style.height = oneBlockHeight - 1 + "px";
    div.style.top = oneBlockHeight * i + "px";
    div.style.left = oneBlockWidth * j + "px";
    let number = i * 10 + (j + 1);
    div.setAttribute("id", number);
    div.innerHTML = number;
    oneBlockList.push(div);
    document.body.appendChild(div);
  }
}

for (var i = 0; i < oneBlockList.length; i++) {
  let oneBlock = oneBlockList[i];
  oneBlock.addEventListener("mouseover", function() {
    oneBlock.style.backgroundColor = "rgba(0,0,0,0)";
    oneBlock.innerHTML = "";
  });
}
```

まず1~100のblockはdivで出来ていますが、これはfor文のネストで作っています。↓

> for (var i = 0; i < 10; i++) {
 for (var j = 0; j < 10; j++) {
...
  }
}

この段階で全てのdivのスタイル・idを設定し、全てのdivを1つの配列に格納しています。

>    oneBlockList.push(div);

その後、配列をfor文で回してイベントリスナーをつけています。↓

>for (var i = 0; i < oneBlockList.length; i++) {
...
  oneBlock.addEventListener("mouseover", function() {
...
}
}

わざわざ配列に入れずに初めのfor文に書いてもいいのですが、長くなりすぎるのを懸念して分けて書きました。
そう考えると、スタイルの付与等も役割別で分けてもよかったかもしれません。

##感想
残りあと2日。頑張ろう

最後まで読んでいただきありがとうございます。明日も投稿しますのでよろしくお願いします。
シェルスクリプト 標準出力と標準エラー出力のリダイレクト

#### 標準出力
もしリダイレクト先のファイルが存在していなければ、新しいファイルが作成されます。

```bash:standard1
# 上書きモード
$ date > file
# 追記モード
$ date >> file
```

また、”> ファイル名” は ”1> ファイル名” の省略形であるため、上記の例は以下のようにも書ける。
このように書かれていると、”標準出力の分がリダイレクトされている” ということがより分かりやすい（一般的には省略されている）。

```bash:standard2
# 上書きモード
$ date 1> file
# 追記モード
$ date 1>> file
```

#### 標準エラー出力
標準出力"1" に対して、標準エラー出力"2" となっており、使い方は標準出力と同じである。

```bash:standard-error1
# 上書きモード
$ rm text 2> file
# 追記モード
$ rm text 2>> file
$ cat file 
rm: cannot remove 'text': No such file or directory
rm: cannot remove 'text': No such file or directory
```

上記の例ではエラー出力を file に書き込みをしたが、不要なエラー出力を無視したい場合もある。
シェルスクリプトにおいて、エラーを非表示にするオプションがあるコマンドの方が少ない。
そのような場合、リダイレクト先にファイルではなく、/dev/null を指定するのが一般的。
追記モードで rm test 2>> /dev/null とも書けるが意味はない。

```bash:standard-error2
# エラー出力を捨てる
$ rm test 2> /dev/null
```

#### 標準出力と標準エラー出力
標準出力と標準エラー出力を同時にファイルにリダイレクトする場合は、両方を同時に指定することが出来ないため、標準エラー出力"2"を標準出力"1"に入れて、全て標準出力としてリダイレクトするような書き方になる。

```bash:standard3
$ rm test > file 2>&1
# 省略しなければ、以下のようにも書ける
$ rm test 1> file 2>&1
```

#### set -C がセットされている場合
以下の記述のように、ファイルの上書きが禁止されるため、リダイレクトするとエラーになる。

```bash
$ help set
(中略)
-C  If set, disallow existing regular files to be overwritten
    by redirection of output.
```

ただし、”>| ファイル名” と書くことで、強制的に上書きすることが可能となる。

```bash:standard4
$ set -C
$ rm test > file 
bash: file: cannot overwrite existing file
$ rm test >| file 
```

ちなみに、set -C を解除したいときは、set +C と実行する。
【REACT】Propsをもっと理解しましょう。

# 概要

以前、投稿したPropsとStateの説明の追記です。
まず、part.1のコードを説明しようかと思いましたが、
コード簡単すぎで省略します。
代わりに、part.1で説明しなかったPropsを説明します。

## Props

### defaultProps


```react
class Main extends Component {
  render() {
    return (
      <div>
        hello! I'am <b>{this.props.name}</b> .
      </div>
    );
  }
}

export default Main;
```

```react
import Main from './Main';

class Sub extends Component {
  render() {
    return (
      <Main name="Tanaka" />
    );
  }
}

export default Sub;
```

以前、使ったコードですが、
実は、このコード問題があります。
今は、nameに【Tanaka】で代入していますが、
Propsにvalueを入れるのを忘れたり、
何らかの理由で、Propsを空にする場合があります。

defaultPropsは、Propsのプロパティにデフォルト値を指定することです。
defaultPropsを使って、名前のデフォルト値を'Tom'にします。

```react
class Main extends Component {
  render() {
    return (
      <div>
        hello! I'am <b>{this.props.name}</b> .
      </div>
    );
  }
}

Main.defaultProps = {
  name: 'Tom'
};

export default Main;
```

他には、

```react
class Main extends Component {
  static defaultProps = {
    name: 'Tom'
  }
  render() {
    return (
      <div>
        hello! I'am <b>{this.props.name}</b> .
      </div>
    );
  }
}

export default Main;
```

こんな風に使うのができます。

### Functional Component

もし、Propsだけ貰って、見せるだけの機能だったら、
componentを使うより、Functional Componentをもっと使います。
上にあるMain Classを修正してみます。

```react
import React from 'react';

const Main = ({ name }) => {
  return (
    <div>
      hello! I'am <b>{name}</b> .
    </div>
  );
};

export default Main;
```
毎日のごはんを楽に記録する Part2

#はじめに
前回投稿した[毎日のごはんを楽に記録する Part1](https://qiita.com/kaji-tan/items/ee9ffd4e177663190452)の続きです。
今日何を食べたのかを、毎日忘れずに かつ 楽に 記録したい　というのが目的です。

#Part1のバグ
昨日からこのシステムを運用していたのだが、晩御飯を記録していないはずなのに、記入を促すSlack通知が来ないことに気づいた。
この課題を解決する。

#原因
スプレッドシートの最終行の記入日付が今日の日付かを判定し、今日の日付が存在しない場合、通知を送るような実装になっていた。

そのため、今日の朝ご飯 or 昼ご飯を記入していると、記入済と認識されてしまい、通知が来なかった。

#対策
今日晩御飯が記入されているかどうかの判定基準に、日付だけでなく、ご飯の種別も判断するように以下のようにコードを改修した。

```Java:dailycheck.gs
  //日付を比較して不一致なら書き込みフォロー処理関数呼び出し
  if(lastdate2 != currentdate){
    postSlack("今日の晩御飯は何を食べましたか？");
  }else if(lastdate2 == currentdate){
    //記入されているのが晩ごはんかを判定する
    if(mealtype.match(/晩/) || mealtype.match(/夜/) || mealtype.match(/夕/)){
      //今日の分は記入済みなのでなにもしない
    }else if(mealtype.match(/朝/) || mealtype.match(/昼/)){
      //朝または昼が記入されているので、書き込みフォロー関数呼び出し
      postSlack("今日の晩御飯は何を食べましたか？");
    }else{
      postSlack("dailyCheck error1!\n" + lastdate2 + "\n" + currentdate + "\n" + mealtype);
    }
        
  }else{
    postSlack("dailyCheck error2!\n" + lastdate2 + "\n" + currentdate + "\n" + mealtype);
  }
```

#得た知識
変数内の文字列の検索には、matchが使える。
mealtype.match(/晩/) とすると、mealtypeの文字列内に"晩"という文字列が含まれているかをチェックできる。

#追記
[Part3](https://qiita.com/kaji-tan/items/b1e5545ead076cc6beca)を書きました。
HTML の href 属性の値一覧を表示するブックマークレット

ブックマークレットを実行すると、ブラウザーのコンソール画面に`href`属性の値の一覧が表示される。

## ブックマークレット用のコード

- `Array.prototype.reduce()` を使ったコード

```js
javascript:console.log([].reduce.call(document.querySelectorAll('[href]'), (pre, cur) => pre + cur.getAttribute('href') + '\n', '\n'));
```

- `Array.prototype.forEach()` を使ったコード

```js
javascript:[].forEach.call(document.querySelectorAll('[href]'), el => console.log(el.getAttribute('href')));
```
Mac: yarn install

## memo
windowsの開発では`yarn`を使っていましたが、Macに移行した際`yarn`のインストールができなくて一時的に`npm`を使用していました。
しばらくそのまま使っていたのですが、`npm`でのインストールが遅すぎたため`yarn`を入れることを決意。
ここでは手順のみ記載しているため、各コマンド等の詳細な説明は省きます。

## 環境
- macOS: 10.15.2
- node.js: 10.16.0
- terminal: iTerm

## about yarn
[公式サイト: Yarn](https://yarnpkg.com/lang/en/)

## yarn install for Mac
基本は公式の[ドキュメント](https://yarnpkg.com/en/docs/install#mac-stable)通り。

### homebrewのインストール
[Homebrew](https://brew.sh/index_ja)

- 記載通りにscriptをコピー＆ペースト

例:  

```
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

1. scriptは変わる可能性があるため、上記codeはそのまま使用せず、必ず[公式](https://brew.sh/index_ja)を確認すること。
2. 実行中 Enter, password 等確認を求められます。
::

### yarn install

```
brew install yarn
```

- インストールが終わったらコマンドが使えるか確認

versionを確認: 

```
yarn --version
```

終了。

***

## memo
2019/12/25: Macでの開発が初めてのため、インストーラーをダウンロードできなくて戸惑った。原因がOS依存のものとわかればあとは公式に書いてある通りに対応すれば問題ないと思います。
12時間タイマー

最近、働き方改革とやらで、12時間以上会社にいてはいけないというルールが流行っているらしい。

出社時間が日によってまちまちな自分は、本日の12時間期限が何時なのか、よくわからなくなる。なので、わかりやすい12時間タイマーが欲しいと思った。こういう感じのもの。
https://www.amazon.co.jp/dp/B07MTL166J/ref=cm_sw_r_tw_dp_U_x_xnkcEbPN0H31F
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82958/3b5a90fa-ea1a-5707-bd17-36e3fa959f53.png" width=50%>
しかし、いざ探してみると1時間はあっても12時間ものはない。
ということで、1時間ものタイマーを12時間にしてみた。

当初、クォーツ式のムーブメントへの入力クロックを12分周させようかなと思っていた。しかし、便利ワンチップが見つからず、FlipFlop組み合わせて12分周させるのが案外面倒そうだったので、転がっていたArduino UNOに逃げた。

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82958/f1167951-5d5a-68a1-8050-87c8816d5498.png" width=50%>

下に名刺ケースを両面テープで貼り付けてUNOを収納。やっつけ感たっぷり。

<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82958/e9680355-2ba2-58b5-21e9-f62f47ceaf15.png" width=50%>

PIN2と4でムーブメントを動かす。元の基板は無視。タイマー終了接点から200ΩでPIN5に入力し、ムーブメント動作を停止させる。表の顔も0〜60のままでは混乱しそうなので、0〜12版をそれっぽく作り変更。動いてるかどうか不安になるので、UNOのビルトインLEDを秒で点滅するようにした。

完成。電源はUSBになり電池も不要になった。
来年から使おう。
実は、結構需要あったりしないかしら？これ。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82958/3f601ded-e8f9-be8e-074d-3cced86fe4f8.png" width=50%>


スケッチはこちら。久々にArduino触ったけど、お手軽でいいね。
元基板の動作を観測してみるとムーブメントへは30msec幅でクロックが入っていたので、それに習う。

```C++
const int clk_pin1 = 2; // for movement
const int clk_pin2 = 4; // for movement
const int stp_pin  = 5; // for timer end
const int pulse_time = 30;
const int delay_time = 1000 - pulse_time;
const int clk_counter_default = 12;  // 12 minutes
int clk_counter = clk_counter_default;
bool isLed = false;
bool isPin1 = false;

void pulse() {
  if (digitalRead(stp_pin)) {
    digitalWrite(LED_BUILTIN, LOW);  // 停止
    clk_counter = clk_counter_default;
    return;
  }
  digitalWrite(LED_BUILTIN, isLed);
  isLed = !isLed;
  if (--clk_counter > 0) {
    return;
  }
  clk_counter = clk_counter_default;
  
  if (isPin1) {
    digitalWrite(clk_pin1, HIGH);
    delay(pulse_time);
    digitalWrite(clk_pin1, LOW);
  } 
  else {
    digitalWrite(clk_pin2, HIGH);
    delay(pulse_time);
    digitalWrite(clk_pin2, LOW);
  }
  isPin1 = !isPin1;
}

void setup() {
  // put your setup code here, to run once:
  digitalWrite(clk_pin1, LOW);
  digitalWrite(clk_pin2, LOW);
  pinMode(clk_pin1, OUTPUT);
  pinMode(clk_pin2, OUTPUT);
  pinMode(stp_pin, INPUT); // 停止確認用
  pinMode(LED_BUILTIN, OUTPUT); // 動作確認用
}

void loop() {
  // put your main code here, to run repeatedly:
  pulse();
  delay(delay_time);
}
```


#参考
- [クオーツ時計を100倍速&リバースモード付きに改造してみた。](http://curious4dev.mydns.jp/post-601/)
- [Arduinoで時計にいたずら](https://n.mtng.org/ele/arduino/clock.html)
WSL2(ubuntu18.04)にrbenvでRuby2.3.3を入れようとしたら「The Ruby openssl extension was not compiled.」と言われた

# 起こったこと
AtCoderで原因不明のランタイムエラーが起きたので、調査のために手元のUbuntu on WSL2にrbenvでRuby2.3.3をインストールしようとしたら以下のエラーメッセージが出て、インストールが中断されてしまいました。

```
$ rbenv install 2.3.3
Downloading ruby-2.3.3.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.3.tar.bz2
Installing ruby-2.3.3...

BUILD FAILED (Ubuntu 18.04 using ruby-build 20191205-4-gf04eb99)

Inspect or clean up the working tree at /tmp/ruby-build.20191229214156.195.oPHCjW
Results logged to /tmp/ruby-build.20191229214156.195.log

Last 10 log lines:
installing rdoc:              /home/yagao/.rbenv/versions/2.3.3/share/ri/2.3.0/system
installing capi-docs:         /home/yagao/.rbenv/versions/2.3.3/share/doc/ruby
The Ruby openssl extension was not compiled.
ERROR: Ruby install aborted due to missing extensions
Try running `apt-get install -y libssl-dev` to fetch missing dependencies.
```
言われるがままに`apt-get install -y libssl-dev`したんですが、インストール済みと言われてしまいました。

```
$ sudo apt-get install -y libssl-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
libssl-dev is already the newest version (1.1.1-1ubuntu2.1~18.04.5).
0 upgraded, 0 newly installed, 0 to remove and 127 not upgraded.
```
# 解決策
困り果ててGoogle先生に聞きに行ったら、以下の大変ありがたい記事を見つけることができました。

[Ubuntu 18.04上においてruby-buildでruby 2.3.*をインストールする - 有馬総一郎のブログ](https://arimasou16.com/blog/2018/04/30/00255/)

>答えはここにあった[Can’t build on Ubuntu 18.04 (bionic64) · Issue #1199 · rbenv/ruby-build · GitHub](https://github.com/rbenv/ruby-build/issues/1199)

>>Ruby < 2.4 is not compatible with openssl 1.1.
You need to install libssl1.0-dev.

確認してみると、確かに手元のopensslのバージョンは1.1でした。

```
$ openssl version
OpenSSL 1.1.0g  2 Nov 2017 (Library: OpenSSL 1.1.1  11 Sep 2018)
```
あとはサイトにある通りopenssl 1.0をインストールしてうまく行けばいいのですが。。。

```
$ sudo apt install libssl1.0-dev
$ rbenv install 2.3.3
Downloading ruby-2.3.3.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.3.tar.bz2
Installing ruby-2.3.3...
Installed ruby-2.3.3 to /home/yagao/.rbenv/versions/2.3.3
$ rbenv versions
  2.3.3
* 2.6.5 (set by /home/yagao/.rbenv/version)
```
成功！！（`apt`だったり`apt-get`だったりしてすみません汗）

# おわりに
ほぼほぼ既存の記事の焼き直しなんですが、WSL2上のUbuntuでも同じ対処法が有効だという検証の意味も込めて作成させていただきました。素晴らしい記事を書いてくださった有馬総一郎さん、ありがとうございました。
MacでPythonの環境構築，Jupyter labを使うところまで

MacでPythonの環境を構築した時につまづいたので，メモ．

先に結論から書くと，うまくいかなかった原因はMacOSがCatalinaになって，デフォルトシェルが `bash `から `zsh` になったのを知らずに，bashを編集していたため．

今までは，pyenvの環境変数は，`.bash_profile`や.`bashrc`に書き込んでsourceすれば良かったので油断していました．

技術は常にアップデートされているのに，知識をアップデートしないでいると，失敗することもあるという話でした．

では，以下に実際に行ったことを記述します．



### 1. Anaconda をインストール
   https://www.anaconda.com/distribution/
   ここから，python3.7をダウンロードして，パッケージを展開

   Applyはいつになったらデフォルトのpythonを3系にしてくれるんですかね？
### 2. pythonインストールの準備
`$ python --version` でpythonのパージョンを確認．
   macだとおそらく，標準で2.7が入っているので，切り替える．

   そのために，pyenvを入れます．
   で，pyenbを入れるために，Homebrewを入れます．

   1. brewをインストール
      https://brew.sh/index_ja

   2. brewでpyenvをインストール 

      ```
      $ brew install pyenv
      ```

   3. で，ここが，問題のつまづいたところ．

      ```
      $ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
      $ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
      $ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
      ```

      上記を `~/.zshrc` に書き込む．←（Mac OSがCatalina以上の場合）
      デフォルトのシェルがbashのままである，Catalina以前のOSの場合は`~/.bash_profile` に書き込む．

   4. `$ source ~/.zshrc `  or `$ source ~/.bash_profile ` を実行

   5. `$ echo $PATH` で環境変数のPATHを確認

      ![echo_path.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147064/df406d1c-a3c4-9ee1-6ff8-d7d80d8b4f6e.png)


### 3. pythonのインストール
   今回は，3.7.0をインストールします．バージョンは必要に応じて，3.7.4などと変更してください．

   ```
   $ pyenv install 3.7.0
   ```

    
でOKです．

### 4. pythonの切り替え

   ```
   $ python --version
   Python 2.7.16
   ```

   のように，python2のままなので，python3へ切り替えます．

   ```
   $ pyenv gloval 3.7.0
   $ python --version
   Python 3.7.0
   ```

   でOKです！
   これで切り替わって無い場合は，一度ターミナルを再起動して見てください．

### 5. anacondaのインストール

   ```
   $ pyenv install anaconda3-5.3.1
   ```

   このときの最新をいれました．
   `$ pyenv install list` でバージョンを確認してください．

### 6. anacondaへの切り替え
   このままでは，condaコマンドが使えないので，anacondaに切り替えます．

   ```
   $ pyenv global anaconda3-5.3.1
   $ pyenv versions              
     system
   * 3.7.0 (set by /Users/ユーザ名/.python-version)
     anaconda3-5.3.1
   ```

   あれ，切り替わってません．
   また，ここでつまづいてしまいました．
   原因は，.python-versionというファイルがここに存在するのがまずいみたいです．なので，

   ```
   $ rm ~/.python-version
   $ pyenv versions
     system
     3.7.0
   * anaconda3-5.3.1 (set by /Users/ユーザ名/.pyenv/version)
   ```

   これで，切り替えが完了しました．

### 7. Jupyterlabの起動
   最近はanacondaに既にJupyterlabが入っているみたいなので，わざわざインストールしなくても，

   ```
   $ jupyter lab
   ```

   とすると起動します．
熱で自家発電するモジュールの電圧を計測した結果

#熱で自家発電するモジュールの電圧を計測する

##きっかけ
「熱で発電してファンを回す」というキャンプギアが売ってたので勢いで購入しました。
発電量が書いてないですが、ファンを回せるなら 応用すればモバイルバッテリーの充電もできるのでは？と思いどのくらい発電できているのかobnizを使って計測をしてみます。

キャンプでは日常生活と違い電気が貴重になってきます。（特に冬）
寒いとスマートフォンの充電も減りが速いし、モバイルバッテリーも一日持たせるのもなかなか辛い…
焚火やコンロの熱で発電できれば、世の中的にも色々が捗ると思います。


##発電量の測定の動画
撮影が下手すぎてめちゃくちゃ分かりにくいですが、
テント内の石油コンロ（タクード）の上にECOFANを設置して、obnizと結線します。
ゆるキャン△のテーマとともに発電量が上がっていくことが分かります。
だいたい3.6Vぐらいまで徐々に上昇します。

[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/SArBCD_IlRw/0.jpg)](http://www.youtube.com/watch?v=SArBCD_IlRw)


##obniz board 1Y(わんわい)の起動実験
3.6Vの電圧なら obniz board 1Y(わんわい)動くんじゃね？と思い、
±のポートに結線してみたところの動画です。
結果からするとLEDだけ点灯しますが、電圧不足でダメっぽいです。（おしい？4.5Vぐらい必要？）
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/4O_GWJ1OZv0/0.jpg)](http://www.youtube.com/watch?v=4O_GWJ1OZv0)

##必要な機材
・エコファン ウルトラエアー Ecofan UltraAir 16,000円 (ファイヤーサイド)
https://www.firesidestove.com/products/accessories/ecofan.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399986/9138099d-dfbe-3640-5c55-bc26f80ebbd8.png)


・obniz Board
・ジャンパワイヤ（オス-オス）×2本
　※長めの方が、ストーブと接触しにくいので良い

・暖炉など

##配線図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399986/fdfd6ed5-1d18-b089-5954-d8214b724c53.png)

##発電量計測のソース
※obnizの外部回路の電圧を読み取るサンプルとほぼ同様です

```index.html
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
  <link rel="stylesheet" href="/css/starter-sample.css">
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@3.1.0/obniz.js" crossorigin="anonymous"></script>
</head>
<body>

<div id="obniz-debug"></div>
<script>
  var obniz = new Obniz("obnizID");
  
  obniz.onconnect = async function () {
    obniz.io11.output(false);
    while(true){
      obniz.io11.output(false);
      var voltage = await obniz.ad0.getWait();
      console.log(voltage);
      obniz.display.clear();
      obniz.display.print("voltage: " + voltage);
    }
  };
</script>
</body>
</html>
```

##熱発電の仕組み
モノの温度差を電圧に変換し、それを利用して発電を行う仕組みです。
っといってもわかりにくいので、
下側を暖炉やコンロの熱で暖めると上側の温度との差で発電する仕組みらしいです。

ベーゼック効果という原理を使って発電しています。
※下記の絵はファイヤーサイドのページより参照
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399986/51d00e2c-dbf2-821c-3bfb-b7a9db60fe3b.png)

##撮影場所
長野県 蓼科のとあるキャンプ場のテントの中

##最後に
冬キャンは虫もいないし、空が澄んでいて良いですが、装備には十分気を付けてください。
PHP 変数に格納された値の足し算あれこれ

# 目的

- PHPの変数に格納された値の足し算で省略方法をまとめる。

# 変数Aに格納された数値に任意の値を足し、再度変数Aに格納する。

- 通常通り記載すると下記のようになる。

```php
$変数A = $変数A + 任意の値;
```

- 省略形を記載する。

```php
$変数A += 任意の値;
```

# 変数Aに1を足し、再度変数Aに格納する。

- 通常通り記載すると下記のようになる。

```php
$変数A = $変数A + 1;
//前述の省略を行った時
$変数A += 1;
```

- 省略形を記載する。

```php
$変数A++;
```

- 前述の省略形の実行と同時に`echo`を実施する際の差異

```php
//echoした後に+1する
echo $変数A++;

//echoする前に+1する
echo ++$変数A;
```
【Django2.2】リレーション先の値をソートして取得

# リレーション先の値をsortする方法

`Country -> Team -> Player`
というリレーションがある場合、Team一覧を取得し、かつPlayerの並びを変更したいときがある。

そんな場合、Prefetchオブジェクトを利用すれば良い。

```python:views.py
from django.db.models import Prefetch

    def get_queryset(self):
        queryset = Team.objects.filter(country="japan").prefetch_related(
            Prefetch(Player, queryset=Player.objects.order_by('name')))
        return queryset
```

`prefetch_related`の中身にPrefetchオブジェクトをセットする。

### 公式Doc
QuerySet API reference | Django ドキュメント | Django
https://docs.djangoproject.com/ja/2.2/ref/models/querysets/#prefetch-objects
firewalldでSSHポートを変更

## はじめに
Firewalldのサービスファイルは以下の2つに配置される。

1. /usr/lib/firewalld/services/
1. /etc/firewalld/services/

1は事前に定義されたサービスファイルが配置されている。2はユーザーが新たに定義したサービスファイルを配置する。

## SSHポートの変更

1のディレクトリ内に `ssh.xml` がある。これを直接編集するのも問題ないが、今回は2のディレクトリに新たにファイルを作成する。この方法だと既存の設定を上書きする形で設定をすることができる。

今回はSSHポートを `TCP/20022` へポートを変更してみる。

```
$ sudo vi /etc/firewalld/services/ssh.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>SSH</short>
  <description>Secure Shell (SSH) is a protocol for logging into and executing ccommands on remote machines.</description>
  <port protocol="tcp" port="20022"/>
</service>
```

firewalldに読み込ませる。

```
$ sudo firewall-cmd --reload
```

sshd自体のlistenするポートの変更も忘れずに。 `/etc/ssh/sshd_config` を編集してsshdのrestartで適用させる。

## 補足:独自で作成したサービスを新たに登録する場合

[firewalldで独自サービスを追加する方法](https://qiita.com/tomoyk/items/74d21b0887f98290dc1f)

## 参考

- [Documentation - HowTo - Add a Service | firewalld](https://firewalld.org/documentation/howto/add-a-service.html)
- [firewalld: if I change the ssh service port, is it enough to allow the new port number, or should I add a new service? - Server Fault](https://serverfault.com/questions/746548/firewalld-if-i-change-the-ssh-service-port-is-it-enough-to-allow-the-new-port)
firewalldで独自サービスを追加する方法

softether vpnでポート443/TCPと5555/TCPと992/TCPを開ける必要があるのでfiwalldの設定ファイルを書いてみる。

ファイル名を `softether.xml` で作成して編集する。

```
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>SoftEther VPN</short>
  <description>SoftEther VPN Server</description>
  <port protocol="tcp" port="443"/>
  <port protocol="tcp" port="992"/>
  <port protocol="tcp" port="5555"/>
</service>
```

このファイルを特定のパスへコピーする。

```
cp softether.xml /etc/firewalld/services/
```

systemdへサービスを追加する。 `--permanent` をつけ忘れると永続化されない。

```
firewall-cmd --add-service=softether --permanent
```

ファイルを配置したらfirewalldを再読み込みさせる。

```
firewall-cmd --reload
```

## 補足:既存のサービスのポートを変更

[FirewalldでSSHポートを変更](https://qiita.com/tomoyk/items/7b475dea50c2da0949f5)
MuninサーバをDocker(Ubuntu 16.04)で構築

Ubuntu 16.04のDockerイメージを使ってMuninをインストールした。

今回はDockerfileをもとに手元でビルドする。

リポジトリ[jekil/docker-munin-server: A docker Munin server, with cgi support and configurable via docker args](https://github.com/jekil/docker-munin-server)

```shell
$ sudo mkdir /opt/munin
$ cd /opt/munin
$ git clone https://github.com/jekil/docker-munin-server
$ cd docker-munin-server
$ sudo docker build . -t munin-server
Sending build context to Docker daemon 160.3 kB
Step 1/19 : FROM ubuntu:16.04
…
```

ビルドに少し時間がかかる。ビルド終了後に確認する。

```
$ sudo docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
munin-server         latest              a3b39615948b        2 minutes ago       286 MB
```

サーバー起動用のスクリプト `start-munin.sh` を作成する。

```bash
#!/bin/bash -xe

docker run -d -p 127.0.0.1:8800:80 \
           -e NODES="foo.server.local:192.168.1.1 bar.server.local:192.168.1.2" \
           -v $PWD/data/lib:/var/lib/munin \
           -v $PWD/data/log:/var/log/munin \
           -v $PWD/data/conf:/etc/munin \
           -v /etc/localtime:/etc/localtime:ro \
           --restart=always \
           munin-server
```

**追記:** 改良版の `munin-service.sh` (以下)は再起動や停止もできるのでこっちがおすすめ

```bash
#!/bin/bash

case $1 in

  "start"  )  docker run -d -p 127.0.0.1:8800:80 \
                -v $PWD/data/lib:/var/lib/munin \
                -v $PWD/data/log:/var/log/munin \
                -v $PWD/data/conf:/etc/munin \
                -v /etc/localtime:/etc/localtime:ro \
                --restart=always \
                munin-server ;;
  "stop"   )  docker ps | grep munin-server | awk '{print $1}' | xargs docker stop | xargs docker rm ;;
  *        )  echo "[usage] munin-service.sh [start|stop]" ;;

esac
```


ディレクトリをあらかじめ作成

```
mkdir -p data/lib data/log data/conf
```

`data/conf`へ`munin.conf`を以下の内容で配置する。　`graph_strategy cgi`がなくてグラフが表示されずトラブルシュートした。

参考: [nginx configuration — Munin 2.0.43-detached-2018-12-11-c16-g4537119 documentation](http://guide.munin-monitoring.org/en/stable-2.0/example/webserver/nginx.html)

```
dbdir	/var/lib/munin
htmldir /var/cache/munin/www
logdir /var/log/munin
rundir  /var/run/munin
staticdir /etc/munin/static
graph_strategy cgi
cgiurl_graph /munin-cgi/munin-cgi-graph
```

起動すると `template` や `static` のディレクトリがないと怒られた。そのため、別コンテナでUbuntuからmuninをインストールしたファイルたちをコピーして `data/conf` の下に配置した。transfer.shにあげたので、落として展開してうまく使うと楽にできる。

```shell
wget https://transfer.sh/wE0hQ/a.tgz
```

**補足:** muninにはtemplateがあり、任意のテンプレートを挿入することでUIを変えられる。Twitter BootstrapベースのUIにしたければ[ここ](https://github.com/jonnymccullagh/munstrap)から落として展開して `data/conf` へ配置する。

```shell
git clone https://github.com/jonnymccullagh/munstrap
cd munstrap
cp -r template/ ../data/conf/
cp -r static/ ../data/conf/
```

実行権限をつけてRoot権限で実行する。

```shell
sudo chmod +x start-munin.sh
sudo ./start-munin.sh
```

疎通確認のためにtelnetを入れておく。

```shell
sudo docker ps
(コンテナidを控える)
sudo docker exec -it (コンテナid) /bin/bash
apt update
apt install telnet
```

ServerからNodeへの疎通を確認する。

```shell
telnet 192.168.1.2 4949
```

`list` などを入力して帰ってくるか試してみる。

続編: [Nodeのインストール](https://gist.github.com/tomoyk/99ee9289ebfab20c066b97173ad9c4f8)
WindowsでDjangoのstartprojectができないときの解決策


#エラー

Windowsです。ちょっと公式ドキュメントをみてもよくわからなかったのでQiitaに記録しておきます。プロジェクトを作成しようと思ってもエラーになってしまった。`django-admin startproject mysite`をコマンドラインにぶち込めばいいはずなのですが…

```
C:_________>django-admin startproject mysite
'django-admin' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
```
なぜ！？インストールは…

```
C:_________>py -m django --version
3.0.1
```
ちゃんとしてあるよ。パスが違うのか…うーん

#解決策
まぁよくわからないけれど、このコマンドでプロジェクトを作成することができました。

```
py -m django startproject mysite
```




#参考文献
- はじめての Django アプリ作成、その 1
https://docs.djangoproject.com/ja/3.0/intro/tutorial01/
Vuejsで非親子関係のコンポーネントを同期する

# Vuejsでコンポーネントを同期する

### やったこと
非親子関係のコンポーネントを同期させる。

### 実際にできたもの
ボタンを押した数だけどちらのコンポーネントも加算される

![285kb-0cb47.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236151/869cff56-0f10-0ebb-bacd-2255143ca522.gif)


### 構成
```
commponents
 ┣ Button.vue 
 ┣ Component1
 ┣ Component2
 ┗ HelloWorld.vue

```
Component1とComponent2のコンポーネントを同期させる

#### Button.vue
``` vue
<template>
  <div>
    <v-btn color="primary" @click="click()">ボタン</v-btn>
    {{dataset.count}}{{message}}
  </div>
</template>
<script>
export default {
  props: { dataset: { type: Object, default: null } },
  data() {
    return {
      message: ""
    };
  },
  methods: {
    click() {
      this.message = "押されたよ";
      this.dataset.count += 1;
    }
  }
};
</script>>
```
dataset.countにボタンを押された回数が入っている。
propsで同じ変数を見るようにする。
#### Component1.vue,Component2.vue
Component1.vueとComponent2.vueは中身は同じ。
バインディングするプロパティ(:dataset="datasetHoge")をComponent1.vue/Component2.vueで同じにする。
同じプロパティをバインドすることで、非親子間での動機が可能になる

``` vue
<template>
  <div>
    <Button :dataset="datasetHoge" />
  </div>
</template>
<script>
import Button from "./Button";
export default {
  props: {
    dataset: {
      type: Object,
      default: null
    }
  },
  components: {
    Button
  },
  data() {
    return { datasetHoge: this.dataset };
  }
};
</script>>
```

#### HelloWorld.vue
``` vue
<template>
  <div>
    <v-col cols="3">
      <Component1 :dataset="dataset" />
    </v-col>
    <v-col cols="3">
      <Component2 :dataset="dataset" />
    </v-col>
  </div>
</template>

<script>
import Component1 from "./Component1";
import Component2 from "./Component2";

export default {
  components: {
    Component1,
    Component2    
  },
  data() {
    return { dataset: { count: 0 } };
  }
};
</script>
```
Component1とComponent2をImportする
AtCoder Beginner Contest 149 参戦記

# AtCoder Beginner Contest 149 参戦記

## [ABC149A - Strings](https://atcoder.jp/contests/abc149/tasks/abc149_a)

1分で突破. 書くだけ

```python
S, T = input().split()

print(T + S)
```

## [ABC149B - Greedy Takahashi](https://atcoder.jp/contests/abc149/tasks/abc149_b)

6分で突破. 書くだけ. 最初文章の意味がわかってなくて、どっちもK枚減らすのかと思ったけど、入出力例を試して正しい意味に気づいた.

```python
A, B, K = map(int, input().split())

a = max(A - K, 0)
K -= A - a
b = max(B - K, 0)
print(*[a, b])
```

## [ABC149C - Next Prime](https://atcoder.jp/contests/abc149/tasks/abc149_c)

7分で突破. ABC084D - 2017-like Number で書いたエラトステネスの篩を持ってきて書くだけ.

```python
from math import sqrt

N = 10 ** 6

p = [True] * (N + 1)
p[0] = False
p[1] = False
n = int(sqrt(N) + 1)
for j in range(4, N + 1, 2):
  p[j] = False
for i in range(3, n + 1, 2):
  if p[i]:
    for j in range(i + i, N + 1, i):
      p[j] = False


X = int(input())
for i in range(X, N + 1):
    if p[i]:
        print(i)
        break
```

## [ABC149D - Prediction and Restriction](https://atcoder.jp/contests/abc149/tasks/abc149_d)

44分で突破. WA1. 取り敢えず勝つ手を出す前提で話を進め、K個前の手と同じ手になってしまった場合はあいこにするという実装にしたら WA が出て、「DP しないといけないのかあ!? でも突破人数的にそれはないか(腐った推論)」とだいぶ長時間悩んで、負けの手のほうがいい可能性があることに気づいて AC. そのせいで順位が1400番台になってしまったので、unrated になって助かった感.

```python
N, K = map(int, input().split())
R, S, P = map(int, input().split())
T = input()

d = {'r': P, 's': R, 'p': S}
result = 0
wins = [False] * K
for i in range(len(T)):
    if not wins[i % K] or T[i] != T[i - K]:
        result += d[T[i]]
        wins[i % K] = True
    else:
        wins[i % K] = False
print(result)
```

## [ABC149E - Handshake](https://atcoder.jp/contests/abc149/tasks/abc149_e)

突破できず. オーダーを切り下げる方法が思いつかず TLE いっぱいのまま終了.

追記: すべての組み合わせを生成するのは計算量が *O*(10<sup>10</sup>) になってしまうから無理なので、生成する組み合わせをなんとか M までに抑えようと思っても、M も 10<sup>10</sup> で変わらなく詰み. なので発想を逆転して、組み合わせの数が M を超える一回で発生する幸福度の閾値を二分探索で調べる. これは累積和を使うと *O*(<i>N</i>log<i>N</i>) で計算できる.

これが求まってしまえば、左手をベースにループを回し、右手はどこまで下げれるかはさっき作った累積和で分かり、もう一個右手のパワーの累積和を作っておけば *O*(*N*) で最終的な幸福度の合計値が求まる. ただし、組み合わせの数がちょうど M とは限らないので、M を超えている分だけさっき求めた一回で発生する幸福度の閾値を差し引く必要がある.

```python
N, M = map(int, input().split())
A = list(map(int, input().split()))

A.sort(reverse=True)
LB = A[-1] * 2  # 一回の握手で上がる幸福度の下限は、左手も右手もパワーが一番低い人を握った場合
UB = A[0] * 2   # 一回の握手で上がる幸福度の上限は、左手も右手もパワーが一番高い人を握った場合

# cgs[i] は パワーがi以上のゲストの数
cgs = [0] * (UB + 1)
for a in A:
    cgs[a] += 1
for i in range(UB, 0, -1):
    cgs[i - 1] += cgs[i]


# 組み合わせの数がM以上になる一回で発生する幸福度の閾値を二分探索する
def is_ok(n):
    m = 0
    for a in A:
        m += cgs[max(n - a, 0)]
    return m >= M


ok = LB
ng = UB + 1
while ng - ok > 1:
    m = (ok + ng) // 2
    if is_ok(m):
        ok = m
    else:
        ng = m

# cps[i] は A[0]～A[i] の累積和
cps = A[:]
for i in range(1, N):
    cps[i] += cps[i - 1]

result = 0
for a in A:
    t = cgs[max(ok - a, 0)]
    if t != 0:
        result += a * t + cps[t - 1]
        M -= t
result += ok * M
print(result)
```
メモ : Jetson NanoでOpenCVを使えるようにする

#OpenCVがインポートできない・・・
最新のJetPack4.3には既にOpenCVがインストールされているみたいですが、Pythonでインポートするとnumpyがないと怒られました(-_-;)

ということでnumpyをインストールします。

```
$ sudo pip3 install numpy
```

あれpipがないと怒られました。ということでpipをインストールします。

```
$ sudo apt install python3-pip
```

pipはインストールできましたが、まだインストールに失敗します。

なのでpipを使ったインストールはあきらめて、aptでインストールします。

```
$ sudo apt install python3-numpy
```

今度は無事インストールできたようです。

Pythonでインポートしてみます。

```
$ python3

>>> import cv2
>>> cv2.__version__
'4.1.1'
>>>
```
無事インポートできたようです。
alfyを試す


久しぶりにダラダラとスクリプティングした


成果物
https://github.com/bonk/alfred-bonk-textlint

巨人の肩の上にのって、fixするようにしました



Alfred上で自分のはてなブックマークを検索できるWorkflow | Web Scratch
https://efcl.info/2017/10/20/alfred-hatenabookmark/

alfy便利そう



ルールプリセットを使ってお手軽にtextlint入門 | Web Scratch
https://efcl.info/2015/12/30/textlint-preset/

日本語対応についてどうするかに言及


Collection of textlint rule · textlint/textlint Wiki
https://github.com/textlint/textlint/wiki/Collection-of-textlint-rule#rules-japanese

ルールセット


JTF日本語標準スタイルガイドのルールセットで文章をチェックできるtextlintプリセット | Web Scratch
https://efcl.info/2015/10/19/textlint-plugin-jtf-style/

プリセット

textlintをてんこ盛りカスタマイズした | Trial and Spiral
https://blog.solunita.net/fully-customized-textlint/

表記ゆれとホワイトリスト

textlint校正ツールで表記ゆれをチェックする方法 | ある計算機屋さんの手帳
http://my-web-site.iobb.net/~yuki/2018-05/e-book/review-textlint-ja-prh/

表記ゆれの辞書の具体例

ブログの文章をチェックするためtextlintを入れてみた - A1 Blog
https://blog.a-1.dev/post/2019-03-09-textlint/

プラグイン実績例
Svelteで双方向のデータバインディングをしようとしてハマって解決するまで

この記事は個人ブログの記事の転載です。
http://skawashima.com/blog/2019/12/svelte-two-way-data-binding

Svelteで双方向のデータバインディングをしようとして若干ハマりました。
つまり、親←→子で常に同じデータを持っておこうとしてうまく行かなかったわけです。
解決したので、そのあたりをさらっと紹介します。
Svelteとは？みたいなところには触れません。

## 何をしようとしたのか

`input` フォームのコンポーネントからそれを呼び出す親のコンポーネントで入力されたデータを扱おうとしました。

```html:Input.svelte
<script>
  export let value = 'value'
</script>

<input bind:value={value} />
```

```html:Form.svelte
<script>
  import Input from '../atoms/Input.svelte'
  let data = 'test'
</script>

<Input value={data} />
```

こんな感じのファイル更生で、Form.svelteを描写した際に表示する瞬間はinputタグにdataの内容である `test` と表示されますが、inputタグの中身を編集してから再度dataの内容を参照して見ると `test` から変わっていない！

つまり、親（Form.svelte）→子（Input.svelte）のデータバインディングは出来ているが、子→親方向にデータがバインディングされていない！という状態です。

## 解決方法

変数に対してデータの更新を受け付けるようにするには、子であるInput.svelteでもやってるのと同様に `bind:` を加えます。
これを親であるForm.svelteでやるだけです。

具体例です。
解決済みのForm.svelteはこんな感じ。

```html:Form.svelte
<script>
  import Input from '../atoms/Input.svelte'
  let data = 'test'
</script>

<Input bind:value={data} />
```

引数（今回は `value` ）を送るときに `bind:` をつけると、変更を受け付けて適宜更新してくれるようになります。
なるほど、理解してしまえばわかりやすくて良いですね！

## 今回の学び

### 双方向データバインディングは英語で「Two way data binding」

今回のでハマったときに `svelte data binding` みたいな調べ方をしてたら一番上に「 **Two way data binding** 」がでてきて「あっこれかぁ」となったりしました。
が、それが双方向のデータバインディングを指していると気づかずに若干右往左往したので、同じような人に向けて記事を書いています。

### Svelte、コードの記述料が少なく済んでいいカンジ

Svelte、動作速度から記述方法まで僕の「好み」だったので、ひたすら孤独に推しています。
Svelteの良さを紹介している記事を貼っておくので、興味のある方は是非！

https://qiita.com/so99ynoodles/items/a8144ced1a21467c6300
[Vue.js] v-forで指定できるinとofの違いについて

ある日、Vueの勉強をしていたら、こんな文章がありました。
> また、区切り文字として in の代わりに of を使用することができます。これは JavaScript のイテレータ構文に近いものです[^1]

そして、こう疑問に思いました。
「なるほど。v-forはinとofが指定できるのね。で、違いは？」
しかし、公式のどこを探しても機能の違いについては書かれていません。

[^1]: https://jp.vuejs.org/v2/guide/list.html#v-for-%E3%81%A7%E9%85%8D%E5%88%97%E3%81%AB%E8%A6%81%E7%B4%A0%E3%82%92%E3%83%9E%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B

## 僕はこう思った
「わざわざ二つ用意しているんだから、絶対に違いあるでしょ！」
「JavaScriptだって違いがあるんだし！」

## 調べてみた
[公式のGitHub](https://github.com/vuejs/vue/blob/dev/src/compiler/parser/index.js#L28)を覗くと。。。

```js
export const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/
```

違いないやんけ！！！（って皆んなでなった。）