OmniAICreator/Qiita-1.07M huggingface dataset:
Ubuntuにvim9+python+rubyプラグイン環境を構築するぜ


**警告**
aptで入れられるvimに満足出来なくなった時用。
あくまで私個人の用途に最適化しているので、ご利用の際はコードをそのままコピペせずにご自身の環境に合わせて修正してください。
Ubuntuと明記していますが、当方ではDebianベースの**Raspberry pi OS**での動作を確認しています。

# 事前準備

## 必要なパッケージをインストールする

```bash
sudo apt install make cmake autogen automake libffi-dev libperl-dev libbz2-dev zlib1g-dev libreadline-dev libssl-dev libsqlite3-dev liblzma-dev
```

## pyenvを使ってpythonをインストール

[リンク](https://github.com/pyenv/pyenv)

```bash
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
echo 'export PATH="$HOME/.pyenv/bin:$HOME/.pyenv/shims:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.bashrc
pyenv -v
pyenv install --list | grep 3.10
pyenv install 3.10.8
pyenv global 3.10.8
python -V
# Python 3.10.8
```

## rbenvを使ってrubyをインストール

[リンク](https://github.com/rbenv/rbenv)

```bash
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc
rbenv -v
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
rbenv install -l | grep 3.1
rbenv install 3.1.2
rbenv global 3.1.2
source ~/.bashrc
ruby -v
# ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [aarch64-linux]
```

# vimのインストール

- `make install`する前に、 python3, rubyが'+'になっているかを確認すること!!
- python2とpython3の**動的(dyn)**なインストールは、windows以外では**不可能**です。あとで悩むことになるのでどちらか片方にしておきましょう。2020年にサポート終了する**2.x系**は今更なので、素直に**3.x系**で良いと思います。

```bash
cd /tmp
git clone https://github.com/vim/vim
cd vim
./configure \
  --enable-fail-if-missing \
  --with-features=huge \
  --disable-selinux \
  --enable-perlinterp \
  --enable-python3interp \
  --enable-rubyinterp \
  --with-ruby-command=$HOME/.rbenv/shims/ruby \
  --enable-cscope \
  --enable-fontset \
  --enable-multibyte \
  vi_cv_path_python3=$HOME/.pyenv/shims/python
make 

# ↓↓↓make installする前に、python, rubyが'+'になっているかを確認すること↓↓↓
./src/vim --version
# ↑↑↑make installする前に、python, rubyが'+'になっているかを確認すること↑↑↑

sudo make install
```

### 終わり～

# 失敗した場合

ビルドに失敗したり、良くわからない状況になったら以下のコマンドで全てを無かったことにしましょう。

```bash
cd /tmp
sudo make distclean
```

# 自動ビルド的なスクリプト(私家版)

私は`/usr/local/src/`に`git clone https://github.com/vim/vim`したので、以後の更新は`/usr/local/src/vim`に入って`git pull`すれば簡単に最新版を持ってこれます。なので`root`上で以下のスクリプトを実行すれば全自動で**最新激アツ**`vim`が勝手にビルドされます。`cron`で週に1回くらいビルドすると楽しいかも...。

```bash
sudo su -
```

```bash:update_vim81.sh
#! /bin/bash

cd /usr/local/src/vim && git pull \
./configure \
  --enable-fail-if-missing \
  --with-features=huge \
  --disable-selinux \
  --enable-perlinterp \
  --enable-python3interp \
  --enable-rubyinterp \
  --with-ruby-command=$HOME/.rbenv/shims/ruby \
  --enable-cscope \
  --enable-fontset \
  --enable-multibyte \
  vi_cv_path_python3=$HOME/.pyenv/shims/python
make && make install && make distclean
```
初心者のためのコンピュータの構造

情報系の授業を取ってる大学生やコンピュータの知識を深めたいと思っている方に役立ってもらえれば嬉しいです。

　コンピュータは以下の要素から構成される。それぞれの装置の間には、データ、アドレス、制御信号を送受信する伝送路（バス）がある。

　１：主記憶装置（メインメモリ）

　２：中央処理装置（CPU: Central Processing Unit, またはプロセッサ）
　　・制御装置
　　・演算装置（プログラムカウンタ、演算レジスタ、キャッシュメモリ等）

　３：周辺機器
　　　キーボード、マウス、マイク、プリンタ、etc...

１：主記憶装置

　主記憶装置は様々なデータやプログラムを記憶するための装置である。
　主記憶装置には、半導体で構成されたメモリチップが使われている。メインメモリとも呼ばれている。
　主記憶装置にはアドレスがあり、それに対して値が格納されている。値は、プログラムのコードであることもあれば、数値や文字列であることもある。主記憶装置の容量は性能を表し、それはアドレスの種類の多さを用いて表現される。例えばメインメモリが１Gバイトのコンピュータは、１バイトのコンピュータより多くのプログラムやデータを記憶することができる（バイトはデータの大きさを測る単位）

　一般に容量の大きい記憶装置は、データの読み書きの時間がかかる。例えばキャッシュメモリと呼ばれる記憶装置は、レジスタよりも低速であるが、主記憶装置よりも速くデータを読み書きすることができ、よく使用するプログラムのデータを一時的に保存しておくために使用されている。ただし、キャッシュメモリはメインメモリよりも容量が小さいため、メインメモリのすべてのプログラムやデータを格納しておくことはできない。高速の記憶装置を大量にコンピュータの中に入れておけばいいと考えるかもしれないが、一般に高速な記憶装置は高価である。

　コンピュータの電源を切ると、主記憶装置内のすべての内容は消去される。このように通電していなければ内部のデータが消えてしまう記憶装置を揮発性メモリという。主記憶装置に使われている半導体メモリは揮発性メモリである。それに対して、ハードディスクやUSBメモリは不揮発性メモリであるため、通電していなくても内容は消えない。

速い→遅い
レジスタ→キャッシュメモリ→メインメモリ→SSD→磁気ディスク、光ディスク→磁気テープ

２：中央処理装置（CPU）

　CPUはコンピュータの計算の役割を担っている。
　メインメモリ上に書かれたプログラミング言語はJavaやC言語ではなく機械語に翻訳されたプログラムであり、このようなプログラムは、複数の命令から構成されていて、通常は一つ一つ処理の順番に従って連続したアドレスに格納される。
プログラムは以下のように処理が進み、終了するまで繰り返される。

→プログラムカウンタを参照し、次の命令が格納されているメモリ上のアドレスを特定
→プログラムカウンタが指し示している主記憶装置のアドレスに格納されている命令を取り出す
→制御装置は取り出した命令を解釈して実行
　・指定されたメインメモリのアドレスからデータを取り出し、演算レジスタに格納
　・演算装置に処理の実行を依頼。これによって、プログラムカウンタの値が書き換えられる。通常は、プログラムカウンタの値が一つ増える。これは、次の命令を実行するための準備である。

　なぜ処理に必要なデータをメインメモリから演算レジスタに持っていくかというと、データの読み書きに要する時間が記憶装置によって異なるからである。演算レジスタは単一の値しか格納できないが、データを読み書きするのがもっとも早い。

３：周辺機器

　色々あるが主に補助記憶装置について説明したい。
　補助記憶装置には、ハードディスクドライブ（HDD：Hard Disk Drive)やSSD（Solid State Drive)などがある。外部記憶装置ともいう。
　外部記憶装置は不揮発性メモリである。例えば、ハードディスクには磁気ディスクが使われていて、磁気ディスクは、円盤に磁性体が塗布されており、それを磁化させることでデータを記録する。それゆえハードディスクに記録されたデータは、HDDの電源を切っても消えない。
　HDDは強い衝撃を与えると、回転軸が折れたり、ディスクが傷ついたりするといった物理的な弱点がある。
　今後はSSDがHDDに代わって使われる機会が増えると思われる。SSDは、HDDと違い機械的な動作を持たない。SSDの内部にはデータを記憶するためのメモリチップと。それを読み書きするための制御装置が入っている。機械的な動きがない分、静かで落下にも強いという利点がある。
USBメモリはSSDの一種である。
AVRマイコンでいろいろやる①-1　計画

AVRマイコンを使っていろいろやってみようという計画です。
今のところ大まかに作るものは2つ。
   ①測定用のオシロスコープ的なもの
   ②磁気浮上装置

①は②を作る際に使いそうなので作ります。
AVRマイコンのADCを使った簡易オシロスコープやデバッグ用のデジタル出力を測定するのが目的です。
②のコントローラもAVRマイコンで作ろうとしているので同型番のAVRマイコンをもう一つ用意して測定用に使えば②の測定装置としては十分ですね。
②に関してはデバッグ用に別途、PCへの出力機能も必要になってくると思います。

②は実際に動くものです。
センサにホール素子なり距測センサなりを使って支えのない永久磁石の位置を測定し、
電磁石で磁界を発生させ、永久磁石を浮かせようというものです。
Arduinoを使ったものはすでに例があるのでATMEGA328Pでも必ず実現可能です。
大学の授業ではArduinoとSimulinkを使って実現しようとしていました。
今回はソフトはすべて自分で作ります。
それと②に関してはオフライン制御を目指しています。
つまり制御にPCを介しません。
なので計算リソースがかなり制限されます。
浮動小数点計算は望めないです。
これでどの程度正確に制御できるかは腕の見せ所ですね。


開発環境は今のところ以下の通りです。
PC S/W：Visual Studio 2017 C#
AVRマイコンS/W：Atmel Studio C
マイコンプログラムライタ：自作ArduinoにArduinoISPスケッチを書き込み、avrdudeでターゲットマイコンへプログラムを書き込み

自作ライタはAtmel Studio上でデバッグできないのもあり少々不便かと思われます。
私は大学時代にライタを買うのをけちっていて自作ライタでなんとかやっていました。
DCモータ制御系は自作できたので磁気浮上程度なら自作ライタでも行けるでしょう。

以上です。
次回はマイコン-PC間通信手法を確立させます。
【令和元年版】BitBucket PipelinesでHerokuに自動デプロイ試してみた！

# 概要
**BitBucket**
https://bitbucket.org/

> 無料かつ無制限のプライベートリポジトリ

**Heroku**
https://jp.heroku.com/

> Heroku はアプリの構築、提供、監視、スケールに役立つクラウドプラットフォーム


どちらも便利でよく使います！

そして僕はこう考えるわけです。

「BitBucketにPushしたらそのままHerokuに反映されないかなぁ･･･」

いちいちHerokuにデプロイしてー、BitBucketにPushしてー、だと二重管理にもなりますし
なによりも**めんどくさい！**

↓こんな感じにしたい
![summary.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147118/a31ba95a-4564-eb73-bf7c-7a8461ae2b93.png)

# こんな方に読んでほしい
* WebアプリやWebサイトの開発をしている方
* BitBucketのリポジトリを持っている方
* Herokuのアカウントを持っている方
* デプロイ時にめんどくさいのをどうにかしたい方

# 参考

下記の記事を参考にさせて頂きました！
BitBucketのPipelineの設定方法が若干変わっているようなので、補足になればと思います！
https://qiita.com/ucc_black/items/01a36ad015be4dc7a864

# 手順

## HerokuのAPI KEYを作成

Heroku CLIでAPI KEYつくってね～と書いてあります。
https://devcenter.heroku.com/articles/authentication
https://help.heroku.com/PBGP6IDE/how-should-i-generate-an-api-key-that-allows-me-to-use-the-heroku-platform-api

## BitBucketでのPipeline設定
### Pipelineを有効化
Pipelineを作成したいリポジトリに入って、設定 > PIPELINE > Settings > 「Enable Pipelines」にチェック

![2019-05-14_22h07_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147118/90c5626a-c5a8-63ce-6a1d-1211ea19783d.png)

という流れですが、ぼくは最初、 設定 > PIPELINE　が表示されなくて困りました。

下図のようにサイドメニューの「PIPELINE」を一度押して中に入ったら　設定 > PIPELINE > Settings > 「Enable Pipelines」
が現れたような気がします。
![2019-05-14_22h09_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147118/16fe0ef1-351f-32e4-fc74-121324b7ba83.png)


もし同様の状況になった場合はお試しあれ！

### リポジトリ変数の設定

設定 > Pipelines > Repository variables に `HEROKU_API_KEY`と、`HEROKU_APP_NAME`をリポジトリ変数として
登録します。

`HEROKU_API_KEY`には[上で](https://qiita.com/drafts/30f61b9bf1e3f969c680/edit#heroku%E3%81%AEapi-key%E3%82%92%E4%BD%9C%E6%88%90)取ってきたAPI KEYを入力します。
![2019-05-14_22h16_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147118/0f5226f9-a55c-00ca-d759-c5e3cba8069f.png)


### bitbucket-pipelines.ymlの作成

```yml:bitbucket-pipelines.yml
# This is a sample build configuration for JavaScript.
# Check our guides at https://confluence.atlassian.com/x/14UWN for more examples.
# Only use spaces to indent your .yml configuration.
# -----
# You can specify a custom docker image from Docker Hub as your build environment.
image: node:latest

pipelines:
  default:
    - step:
        # set HEROKU_API_KEY and HEROKU_APP_NAME environment variables
        # set clone `depth: full' as described here: https://confluence.atlassian.com/x/Y9-5Mw
        name: Deploy to Heroku
        deployment: test   # set to test, staging or production
        # trigger: manual  # uncomment to have a manual step
        script:
          - git push https://heroku:$HEROKU_API_KEY@git.heroku.com/$HEROKU_APP_NAME.git HEAD
```

### bitbucket-pipelines.ymlをBitBucketのリポジトリにPush

![2019-05-14_23h02_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147118/ee5403c7-d5ad-a519-8c82-50b2ec9d4dd5.png)

# 最後に

意外と簡単な手順ですが、大きく手間を減らせました！！！
firebaseでbasic認証サイトを公開する

ポートフォリオを作成するにあたり、
なるべく安く（出来れば無料で）サイトを公開したかったので手順を自分用にメモ。

Github pageはbasic認証がかけられなそうだったので今回は見送り（出来たらすみません）

環境
windows 10
Git Bash

# firebaseにアカウントを登録

https://console.firebase.google.com/

# node.js & NPM をインストール

インストール済み想定なので割愛

# firebase-tools

globalにfirebase-toolsをインストール

```
npm install -g firebase-tools
```

# firebaseへログイン

```
firebase login
```

# firebase初期化

```
firebase init
```

・Functions
・Hosting

にチェックを入れる（spaceキー)
※basic認証不要ならfunctionsのチェックは不要。ディレクトリの移動やファイルの書き換えも不要

他基本的にデフォルトのまま設定をしていけばok

public以下のファイルはすべて削除

functions/index.js を以下の通り書き換える

``` functions/index.js
const functions = require('firebase-functions')
const express = require('express')
const basicAuth = require('basic-auth-connect')
const app = express()

app.all('/*', basicAuth(function(user, password) {
  return user === 'username' && password === 'password';
}));

app.use(express.static(__dirname + '/static/'))

exports.app = functions.https.onRequest(app)
```

``` firebase.json
{
  "hosting": {
    "public": "public",
    "rewrites": [
      {
        "source": "**",
        "function": "app"
      }
    ],
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  }
}
```

```
> cd functions
> npm install --save express
> npm install --save basic-auth-connect
```

以下もnpm installしないとエラーを吐いたのでインストール

```
> npm install firebase-functions
> npm install firebase-admin
```

/functions/static/ 配下に作業ファイルを追加

デプロイしたい時は

`firebase deploy`

何事もなければ

Deploy complete!

でデプロイ完了

※以下を参考にさせて頂きました。

・FirebaseでBasic認証をかけてサイトを作る(Hostingする)
https://qiita.com/567000/items/65f55eda8d7c6df09138
Excel VBA AcitiveCellに令和を条件付き書式で表示させるマクロ

#ところで条件付き書式
条件付き書式で変換するというのを検討したのですが、令和元年が本当にガンですね。
これがあるがゆえに条件付き書式は令和元年、令和２年、令和３年と用意しなければなりません。
確かにこれだと日付形式を保持します。しかし現在の使用では令和５年、２０２３年までは対応できますが、2024年も令和５年になります。
変わっているのは日付、Date関数で設定しても、マクロになるとシリアル値になるところです。（なぜか開始日だけ）
これを手書きでDate関数にしても問題がありません。

##時間への対応を忘れない
2021/4/5という値は2021年4月5日5時1分より小さい値です。つまり時間の分だけ足す必要があります。
このため時間まで考えるとシリアル値に+0.999999加算する必要があります。9が7つくらいですね。
ここでexcelの演算誤差、15桁の限界が顔をのぞかせます。シリアル値が5桁なので、7桁程度が安全でしょう。
自動で記録すると、なぜかExcel4Macroが出現します。


```vb
Sub SetReiwaFmtConditonActiveCell()
'ActiveCellに日付が入っている場合、令和に変換する条件付き書式を設定します。
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = ActiveSheet
Dim r As Range: Set r = Range(ActiveCell.Address)
Dim xlFormatCondition As FormatCondition, xlFormatConditions As FormatConditions
r.Select
'現在のセルに入っている条件付き書式を削除する Delete Activecell FormatConditions
If r.FormatConditions.Count > 0 Then
For Each xlFormatCondition In r.FormatConditions
xlFormatCondition.Delete
Next
End If
Set xlFormatConditions = r.FormatConditions
r.Select
Set xlFormatCondition = xlFormatConditions.Add(Type:=xlCellValue, Operator:=xlLess, Formula1:="=Date(2019,5,1)")
xlFormatCondition.NumberFormat = "gggee""年""m""月""d""日""(aaa)"
' Selection.FormatConditions(Selection.FormatConditions.Count).SetFirstPriority
' ExecuteExcel4Macro "(2,1,""gggee""年""m""月""d""日""(aaa)"")"
' Selection.FormatConditions(1).StopIfTrue = False
xlFormatCondition.SetFirstPriority
xlFormatCondition.StopIfTrue = True
Set xlFormatCondition = xlFormatConditions.Add(Type:=xlCellValue, Operator:=xlBetween, _
Formula1:="=43586", Formula2:="=""date(2019,12,31)+0.99999""")
xlFormatCondition.NumberFormat = """令和元年""m""月""d""日(""aaa"")"""
xlFormatCondition.SetFirstPriority
xlFormatCondition.StopIfTrue = True
Set xlFormatCondition = xlFormatConditions.Add(Type:=xlCellValue, Operator:=xlBetween, _
Formula1:="=Date(2020,1,1)", Formula2:="=""date(2020,12,31)+0.99999""")
xlFormatCondition.NumberFormat = """令和2年""m""月""d""日(""aaa"")"""
xlFormatCondition.SetFirstPriority
xlFormatCondition.StopIfTrue = True
Set xlFormatCondition = xlFormatConditions.Add(Type:=xlCellValue, Operator:=xlBetween, _
Formula1:="=Date(2021,1,1)", Formula2:="=""date(2021,12,31)+0.99999""")
xlFormatCondition.NumberFormat = """令和3年""m""月""d""日(""aaa"")"""
xlFormatCondition.SetFirstPriority
xlFormatCondition.StopIfTrue = True

Set xlFormatCondition = xlFormatConditions.Add(Type:=xlCellValue, Operator:=xlBetween, _
Formula1:="=Date(2022,1,1)", Formula2:="=""date(2022,12,31)+0.99999""")
xlFormatCondition.NumberFormat = """令和4年""m""月""d""日(""aaa"")"""
xlFormatCondition.SetFirstPriority
xlFormatCondition.StopIfTrue = True

Set xlFormatCondition = xlFormatConditions.Add(Type:=xlCellValue, Operator:=xlBetween, _
Formula1:="=Date(2023,1,1)", Formula2:="=""date(2023,12,31)+0.99999""")
xlFormatCondition.NumberFormat = """令和5年""m""月""d""日(""aaa"")"""
xlFormatCondition.SetFirstPriority
xlFormatCondition.StopIfTrue = True
End Sub
```
納得できるかな？Pythonのタプル

先日開催されたPyCon mini SapporoのLT「[PHPerが聞きたいPythonのいくつかのこと](https://speakerdeck.com/tacck/phpergawen-kitaipythonfalseikutukafalsekoto-pycon-mini-sapporo-2019-number-pyconsap)」で出たこのネタにマジレス。

![screenshot.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285004/b4145ceb-384d-1424-5abd-66bd03048708.jpeg)

えーっと、これは「要素がひとつだけのタプルを定義するとき、なんでカンマが必要なのか納得いかない😑」って顔してますね。なんとか納得してもらえるよう説明してみます。

## タプルの記法

要素が2つ以上のとき、リストとタプルの記述上の違いはカッコの種類だけです。

```shell
>>> lst = ['spam', 'ham', 'egg'] # リスト
>>> tpl = ('spam', 'ham', 'egg') # タプル
```

しかし要素がひとつだけの場合リストは普通に要素を記述するだけでいいのに、タプルだと要素の後ろにカンマを入れる必要があります。

```shell
>>> lst = ['spam'] # カンマは必要ない
>>> type(lst)
<class 'list'>
>>> lst
['spam']
>>> tpl = ('spam',) # カンマが必要
>>> type(tpl)
<class 'tuple'>
>>> tpl
('spam',)
```

「ホントはカンマいらないんじゃないの？」って思ったら、試しにカンマを省略してみましょう。

```shell
>>> tpl = ('spam')
>>> type(tpl)
<class 'str'> # ？？？タプルじゃない！
>>> tpl
'spam'
```

タプルじゃなく文字列になってしまいました。なぜでしょう？`('spam')`の部分をよく見てください。何か気づきませんか？`('spam')`の部分です。よーく見てください。

そうです。`('spam')`のカッコは式の評価順を指定するためのカッコなんです。この場合カッコの前後には何もないので、カッコ無しで`'spam'`と書いたのと同じ結果になります。

Pythonのタプルの記法がちょっと分かりにくくなってるのは、タプルを表すカッコと式の評価順を表すカッコが混在しているためです。同じ記号なのに文脈によって意味が違ってくるんです。

最初に書いたタプルの例、実は次のようにカッコを省略して記述できます。

```shell
>>> tpl = 'spam', 'ham', 'egg' # カッコを省略
>>> type(tpl)
<class 'tuple'>
>>> tpl
('spam', 'ham', 'egg')
```

ここで重要なのは'spam'と'ham'と'egg'がカンマで区切られているってことです。タプルかどうかを示しているのは実はカッコではなくてカンマの方です。

なお最後の要素の後にカンマを付けても構いません。付けても付けなくても結果は同じです。

```shell
>>> tpl = 'spam', 'ham', 'egg', # 最後の要素の後にカンマを付けてみる
>>> tpl
('spam', 'ham', 'egg')

```

要素がひとつだけの場合は必ず要素の後にカンマを付けなければなりません。理由はわかりますよね。これを省略したらタプルであることを示すものが何も無くなってしまうためです。

```shell
>>> tpl = 'spam', # 最後のカンマがタプルであることを示す
>>> type(tpl)
<class 'tuple'>
>>> tpl
('spam',)
```
タプルを記述するときはカンマが必要、その理由がお分かりいただけたでしょうか。

ただし例外があります。空のタプルはカンマを使わず、カッコだけを記述しなければなりません。

```shell
>>> tpl = ()
>>> type(tpl)
<class 'tuple'>
>>> tpl
()
```

こうゆう分かりにくさが生まれた原因はキーボードから直接入力できるカッコが()、[]、{}しかないこと。タプル用にもう一種類別のカッコが欲しかったんだけど、無いので()を使いまわすしかなかったってことなんだと思います。

## タプルの使いどころ

リストとタプルは似ていますが、リストがミュータブル(更新可能)なのに対し、タプルはイミュータブル(更新不能)です。「いやいや、それは分かるけど、リストさえあればタプル無くてもいいんじゃない？更新しなければリストはタプルと同じように使えるんでしょ。リストがあればいいじゃん」って思いました？

でもタプルにはそれなりの存在理由があるんです。ひとつはメモリ消費量です。リストに比べタプルの方がシンプルな実装となっているため、プログラム内で大量のデータを保持する必要がある場合、タプルを使った方が少ないメモリで高速に動作します。

また辞書のキーや集合の要素にリストを使うことはできませんが、タプルはどちらにも使用可能です。

```shell
>>> d = {}
>>> d[1, 2] = True # 辞書のキーにタプルを使用
>>> d[1, 3] = False
>>> d
{(1, 2): True, (1, 3): False}
>>> s = {(1, 2), (3, 4), (5, 6)} # 集合の要素にタプルを使用
>>> s
{(1, 2), (3, 4), (5, 6)}
```

## これも実はタプル

複数の変数の値を一度にセットする次のような書き方、Pythonではよく見かけるものです。これも実はタプルです。

```shell
>>> x, y, z = 5, 10, 20
```

右辺は(5, 10, 20)というタプルですね。このタプルから値を取り出し(アンパック)、その値を用いて左辺のタプルを生成(パック)、結果的にx, y, zそれぞれに値がセットされるという仕組みです。
Leetcode #41: First Missing Positive

```swift
func firstMissingPositive(_ nums: [Int]) -> Int {
    var index = 0
    var nums = nums
    while index < nums.count {
        if nums[index] >= 1 && nums[index] <= nums.count && nums[index] != index + 1 && nums[nums[index]-1] != nums[index] {
            nums.swapAt(index, nums[index]-1)
        } else {
            index+=1
        }
    }
    for i in 0..<nums.count {
        if nums[i] != i+1 {
            return i+1
        }
    }
    return nums.count+1
}
```
RegExp#exec() が返す配列にはundefinedが含まれているかもしれない

いきなり言われてもピンとこないとおもうので、画像を用意しました。

```js
const result = /a(b)?/.exec('a');
const { length } = result; // 2
const [matched, capture1] = result; // "a", undefined
```

![testRegex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96935/36ff0360-498b-4f34-b5fa-84cd23950237.png)
`groups`は名前付きキャプチャを使わなければ`undefined`なのでいいとして、`result[1]`が`undefined`ですね。
ただ、このぐらい単純な場合、書き方を変えればそれを回避できます。

```js
const result = /a(b?)/.exec('a');
const { length } = result; // 2
const [matched, capture1] = result; // "a", ""
```

![testRegex2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96935/d81d7549-9222-1766-5c19-d3efd37d7d2c.png)
この挙動の違いは**0文字をキャプチャしたグループ**と**そもそも適用されなかったグループ**の違いです。
`?`や`*`、`|`によってスキップされてしまったグループをキャプチャすることは当然できません。
その場合、`RegExp#exec()`の配列の要素数は変わらず、`undefined`が代入されます[^1]。

この挙動は[ES5時点から変わらず仕様として定められています](https://www.ecma-international.org/ecma-262/5.1/#sec-15.10.2.1)。

MDN(英語版)にも書いてない挙動[^2]なので、`RegExp#exec()`や`String#replace(regex, replaceFunction)`でスキップするようなキャプチャグループは記述しないほうが混乱が減るでしょう。

[^1]: ただし[非常に古い一部のブラウザ(IE含)は`undefined`ではなく`""`になってしまっています](http://blog.stevenlevithan.com/archives/npcg-javascript)。
[^2]: 英語圏だとブログとかではちらほら記述されているけど、日本語圏では皆無。というか陥りやすい罠なのにMDNに書かれてないのはどうなのか
Magic Leap MagicScript Landscape Application. Notification

**Prepare**
Magic Leap One
https://www.magicleap.com/magic-leap-one

mlsdk v.0.20.0
https://creator.magicleap.com/downloads/lumin-sdk/overview

magic-script-cli v2.0.1
https://www.npmjs.com/package/magic-script-cli

magic-script-polyfills v2.1.1
https://www.npmjs.com/package/magic-script-polyfills

**Create Project**

```
magic-script init my-nf org.magicscript.nf "Notification"
cd my-nf
```

**Code**
Change app.js

```javascript
import { LandscapeApp, Notification, ui } from 'lumin';
const { 
    UiLinearLayout
  , UiText
  , UiButton
  , EclipseLabelType
  , Alignment
  , HorizontalTextAlignment } = ui;
const { 
    NotificationSound, 
    NotificationActivateGlyph, 
    NotificationDismissGlyph } = Notification;

export class App extends LandscapeApp {
  onAppStart () {
    const prism = this.requestNewPrism([0.5, 0.5, 0.5]);
    const app = this;
    const layout = UiLinearLayout.Create(prism);
    layout.setAlignment(Alignment.CENTER_CENTER);
    
    const text = UiText.CreateEclipseLabel(
      prism,
      '',
      EclipseLabelType.kT7
    );
    text.setAlignment(Alignment.CENTER_CENTER);
    text.setTextAlignment(HorizontalTextAlignment.kCenter);
    layout.addItem(text, [0.01, 0.01, 0.01, 0.01]);
    
    const button = UiButton.Create(prism, 'Notification', 0, 0.1);
    button.onActivateSub(function (uiEventData) {
      const n = new Notification();
      n.setIsExclusiveNotification(true);
      
      n.setTitle("Notification Title");
      n.setDetailedMessage("Notification Detailed Message");
      
      n.setActivateButtonText("PERSON");
      n.setActivateButtonGlyph(NotificationActivateGlyph.kPerson);
      n.setActivateAction(function()
      {
        text.setText("Person");
      });
      
      n.setDismissButtonText("CLOSE");
      n.setDismissButtonGlyph(NotificationDismissGlyph.kClose);
      n.setDismissAction(function()
      {
        text.setText("Close");
      });
      app.postNotification(n);
    });
    layout.addItem(button, [0.01, 0.01, 0.01, 0.01]);
    prism.getRootNode().addChild(layout);
  }
}
```

Change manifest.xml

```xml
<manifest xmlns:ml="magicleap"
          ml:package="org.magicscript.nf"
          ml:version_name="0.0.1"
          ml:version_code="1">
  <application ml:visible_name="Notification"
               ml:application_type="untrusted"
               ml:sdk_version="1.0">
    <component ml:name=".universe"
               ml:visible_name="Notification"
               ml:binary_name="bin/index.js"
               ml:type="Universe">
      <mode ml:shareable="true"/>
      <icon ml:model_folder=""
            ml:portal_folder=""/>
    </component>
    <uses-privilege ml:name="MagicScript"/>
    <uses-privilege ml:name="NormalNotificationsUsage"/>
  </application>
</manifest>
```

**Build**

```
magic-script build -i
```

**Run**

```
magic-script run --port=10000
```

**Reference**
Notification (MagicScript API)
https://docs.magicscript.org/lumin.Notification.html

magicscript
https://www.magicscript.org/

Thanks!
HTML初心者による備忘録~主にタグ~

#はじめに　
HTMLにご無沙汰した時に、さっぱり忘れていたのでアウトプットの重要性に気付きました。
個人的なメモであり、先駆者様からに指摘いただきたくもあるので、どうぞよろしくお願いします。

#HTML文の先頭に


`<!DOCTYPE html>　
<html lang="ja">`

を書く。

1行目のはHTMLを書き始めるための宣言みたいなもの。あんまり深くは突っ込まない。

2行目は何の言語を用いるかを宣言している。ただし、最近ではlang=jaと定義する必要は無いっぽい。

#headタグの中身
さて、ユーザが任意に書ける本文部分に入っていく。

まずは、headタグ。
このタグの中でどういうサイトなのかを大まかに説明する。

`<meta charset="utf-8">`

これで、どの文字コードを用いるかを決める。上の分ではUTF-8を使っている。

`<title>美味しいトマトの育て方</title>`

titleタグで、ブラウザのタブの部分に出てくる文字を決めることが出来る。

`<meta name="description:" content="トマトの栽培方法についてのページです。">`

サイトの説明をするところ。検索エンジンが参照するところらしい。


`<link rel="stylesheet" href="/css/master.css">`

当HTMLファイル以外にサイトのリソースを用いた場合には、ここで書いておくとそれが反映される。
relで何を変更するのかを書いて、その変更内容を記したものがどこにあるのかをhrefに書く。
上の文ではCSSのstyleseetを書いたので、relにstyleseet、hrefにそのCSSファイルの所在を示してある。


以上が今作っているサイトのHTML文でのメタタグです。

#bodyタグの中
いよいよbodyタグ、すなわちページの中身に入っていきたいと思う。

##header
はい。ヘッダータグです。ページの目次とかタイトルをこの中に（任意のタグを用いて）記述します。最初に来るから書いたけどいらないみたい。

##hタグ
見出しを書くときに使います。文字が大きめです。hにつく数字が大きくなればなるほど小さくなっていきます。

```html
<h1>h1タグです。</h1>
<h2>h1タグです。</h2>
<h3>h3タグです。</h3>
<h4>h4タグです。</h4>
<h5>h5タグです。</h5>
```
↓

![hタグ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416736/f94d8747-f113-8be8-3e14-a29dfce5c30f.png)

##pタグ
見出しにぶら下がる本文をこれで囲う。

```html
<p>p1タグです。</p>
```

↓
![pタグ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416736/7a0bcc30-723e-05d9-9fb3-e6ca02f4f935.png)

ここまで分かればサイトはできる。（暴論）
Docker for Mac で X11 アプリケーションを動かす

Docker for Mac で X11 アプリケーションを動かそうとしたら少しハマったのでメモ。

## 環境
- macOS Mojave (10.14)
- XQuartz 2.7.11 (xorg-server 1.18.4)

## 手順
### 0. 動かしたい X11 アプリの Docker イメージを用意する
今回は例として、xeyes が動くイメージを作って `xeyes` という名前をつけておく。

``` Dockerfile:Dockerfile
FROM alpine

RUN apk --no-cache add xeyes

CMD ["/usr/bin/xeyes"]
```

``` console
$ docker build -t xeyes .
```

### 1. ホスト側 (macOS) で X11 サーバ (XQuartz) を起動させておく
環境設定で `ネットワーク・クライアントからの接続を許可` にチェックを入れておく必要がある。 `接続を認証` はデフォルトでチェックが入っていると思うが、こちらはチェックが入ったままでよい (外すのはセキュアではない)。

また、環境設定の変更は XQuartz を再起動しないと反映されないので注意。

![XQuartz Settings](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/a926aacf-2e79-33a5-feca-d36e8055d0df.png)

### 2. 環境変数 `DISPLAY` と認証情報を共有しつつ、コンテナを起動する
コンテナ起動時にやるべきことは２点。

- コンテナ側の環境変数 `DISPLAY` に `<ホスト名>:0` を指定する
- ホスト側の `~/.Xauthority` をコンテナ側のホームディレクトリにマウントする

``` console
$ docker run --rm \
    -e DISPLAY=$(hostname):0 \
    -v ~/.Xauthority:/root/.Xauthority \
    xeyes
```

![xeyes](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/cf3c46ce-3603-a90a-45c5-b6a869ac381c.png)

動いた。

## [おまけ] OpenGL アプリを動かす
X11 サーバ側で Indirect GLX を有効にすれば OpenGL アプリも動かせる。

参考： [X Window Systemを使ってリモートサーバでOpenGLなプログラムを走らせる方法 \- ぼくたち宇宙人](https://itakeshi.hatenablog.com/entry/2018/02/03/134644)

XQuartz で Indirect GLX を有効にするには以下のコマンドを実行する。

``` console
$ defaults write org.macosforge.xquartz.X11 enable_iglx -bool true
```

試しに glxgears を動かしてみる。

``` Dockerfile:Dockerfile
FROM alpine

RUN apk --no-cache add mesa-demos

CMD ["glxgears"]
```

``` console
$ docker build -t glxgears .
```

``` console
$ docker run --rm \
  -e DISPLAY=$(hostname):0 \
  -v ~/.Xauthority:/root/.Xauthority \
  glxgears
```

![glxgears](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/2c2a40bd-5743-b401-d71d-8231979d972c.png)

動いたっちゃ動いたのだけど、めちゃくちゃ遅い。

MacBook には GPU が積まれていないので Intel HD Graphics を利用しているはず？だが、とはいえこんなに遅くなるものなんだろうか。

## 関連
- [Docker コンテナ上で動く X11 アプリケーションのウィンドウをディスプレイに表示させる \- Qiita](https://qiita.com/hoto17296/items/7c1ba10c1575c6c38105)
Slack超初心者向け指南書

# お品書き
1. はじめに
1. 用法集
1. むすび

# はじめに
Webで超初心者記事を探したものの、内容が少し多かったり少なかったりがあってもやもやしたので自分で記事を作ることにしました。
なので、この記事はSlack登録したはいいものの**本当に**「全くわからん」という人向けです。


# 用法集
## リアクション  
Slackの絵文字リアクション(リアクション)は自分の文章だけでなく他人の文章につけることがきます。
何か人が言ってたら(業務連絡など)👍~~(や🍤)~~などのリアクションなんかを積極的につけてあげましょう。発言者はとても安心します。  
ググればチーム独自のリアクションの作り方もすぐ出てくるのでどんどん作ると良いと思います。

## メンション  
SlackのChannelでは**`@ebiten`**のように**@その人のスラック表示名**でその人に通知を飛ばすことができます。  
また、**`@Channel`**でそのChannelに入ってる人全員、**`@here`**でChannel内でオンラインの人全員に通知を飛ばせます。  


## 基本的なMarkdown  

### Code記法  
バッククオートで囲う  
プログラムのコードを共有するときに使う  
文字の大きさが小さくなるので長文を送るときにも便利  
記入例  
`` `Code記法` ``  
表示例  
`Code記法`  
### 強調表記(イタリック)  
アンダーバーで囲う  
(Qiita上では日本語だとイタリックに見えないのでアルファベットを示す)  
記入例  
`_Woow!_`  
表示例  
_Woow!_  
### 強調表記(太字)
アスタリスクで囲う  
記入例  
`*強調記法*`  
表示例  
**強調記法**

## その他  
### データの共有  
Slack無料版ではワークスペースのコメント・データ保存容量が限られています。  
なので、画像や動画などを共有する場合はGooglePhotoを使うと容量をセーブできるので幸せです。  
### 電話番号の非表示  
無意識にプロフィール画面で自分の電話番号が表示されてしまっていることがあります。  
個人的には非表示にしておくとよいと思うので方法を示します。  
ワークスペースごとにルールがある場合があるのでルールがあればそれに従ってください。  
左上のWorkspace名⇒プロフィール & アカウント⇒プロフィールを編集する  
⇒電話番号の部分を削除する  
### Markdownの重ね掛け
先述したMarkdown、じつは重ね掛けができます。
たとえばイタリックの太字、とかです。
記入例  
`_*Wooow!*_`  
表示例  
_**Wooow!**_  

# むすび
徐々に書き足していこうと思います。
誤り等あれば連絡いただけると幸いです。  

TwitterID：[@ideshi00](https://twitter.com/ideshi00)
OSXにredmine 3.4を入れるメモ 補足1



## 問題

ブラウザ上でEasy Ganttをひらくと

```
Internal error
An error occurred on the page you were trying to access.
If you continue to experience problems please contact your Redmine administrator for assistance.

If you are the Redmine administrator, check your log files for details about the error.

Back
```
と、見覚えのあるエラーが。

production.logには

```
ActionView::Template::Error (Mysql2::Error: Table 'redmine.easy_settings' doesn't exist: SHOW FULL FIELDS FROM `easy_settings`):
```

こんな記載がありました。

## 解決

```
$ bundle exec rake db:migrate RAILS_ENV=production 
$ sudo apachectl restart
```

参考: https://trialanderror.jp/easygantt-install/
JavaScriptで数字の桁数を0で揃える方法

## JavaScriptで数字の桁数を0で揃える方法
英語でいう"zero padding"です。(英語でなんて言うかを知っておくのは大事なのでぜひ覚えてみて下さい。)

さて、JavaScriptのzero paddingには
`String​.prototype​.pad​Start()`
が使えます。zero paddingに関わらず、任意の文字で先頭を埋めることが出来ます。

以下、公式のコードです。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart

```javascript
const str1 = '5';

console.log(str1.padStart(2, '0'));
// expected output: "05"

const fullNumber = '2034399002125581';
const last4Digits = fullNumber.slice(-4);
const maskedNumber = last4Digits.padStart(fullNumber.length, '*');

console.log(maskedNumber);
// expected output: "************5581"

```
ぜひ使ってみてください。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
OSXにredmine 3.4を入れるメモ③

## 目標
テーマの追加

## 参考

http://redmine.jp/glossary/t/theme/change-themes/

## 方法

/public/themes/にダウンロードしたテーマをごっそり設置。

redmineから管理→設定→表示から任意のテーマを指定。

『保存』する。

表示が崩れる場合は、そのテーマのディレクトリのパーミッションを確認。

必要に応じて

```
$ cd chmod -R 755 {テーマのディレクトリ名}
```

で権限を変更する。
【初心者】Docker/Prometheus　：参考記事一覧

## 目的
- 自己学習のため
- 備忘のため
- 構築準備（★から参照予定）
- マークアップ技法の練習＾＾

## Docer環境構築
★windows 10 home で docker を導入するメモ
　https://qiita.com/idani/items/fb7681d79eeb48c05144
　→　Windows10 Home 64bit
　　　VirtualBox～Docker起動停止まで
　　　※手順わかりやすそう

Windows10+VirtualBox+VagrantでDockerはじめました
　http://www.nct-inc.jp/engineer_blog/2807/
　→　VirtualBox/Vagrant/Docker概要
　　　　～Docker Container動く（Ubuntu）


## Prometheus連携
PrometheusをDockerを使って触ってみる
　https://qiita.com/ryuichi1208/items/caf2d32b7a49ce5a39b1
　→　概要～アーキテクチャ～grafana連携まで

Prometheusを触ってみる。のをDockerでやってみる。のとgrafana。
　https://bufferings.hatenablog.com/entry/2016/12/11/130254
　→　自身の監視～grafana表示まで

★Prometheusでお手軽サーバ監視 (Docker編)
　https://www.indetail.co.jp/blog/5819/
　→　VirtualBox～Docker自身の監視
　　　※コードあり

## おまけ
マークアップ技法
　https://qiita.com/tbpgr/items/989c6badefff69377da7




------
Thank U Next!
☺yucco
shのパラメタ展開で遊ぶ

##パターン置換相当を作る
dashとかだと前方一致部分の削除と後方一致部分の削除しかないので、

- 先頭から置換したいパターンまでを削除した文字列
- 置換したいパターンから末尾を削除した文字列

を用意してつなぎ合わせる。
bashとは異なり最短一致で置換する。

```
$ sub hogehoge hoge fuga
fugahoge
$ sub hogehoge 'o*e' age
hagehoge
$ sub hogehoge '*' h
hogehoge
```

```
$ gsub hogehoge hoge fuga
fugafuga
$ gsub hogehoge 'o*e' age
hagehage
$ gsub hogehoge '?' A
AAAAAAAA
```

### コード

```bash:dashsub
if ! type return_val >/dev/null 2>&1; then
  alias return_val='echo'
fi

gsub() {
  case "$2"
  in *[!*]*) :
  ;; *)
    return_val "$1"
    return
  esac

  local h= v=$1
  while :; do
    case "$v"
    in *$2*)
      eval "h=\"$h\${v%%$2*}$3\""
      eval "v=\"\${v#*$2}\""
    ;; *)
      return_val "$h$v"
      break
    esac
  done
}

sub() {
  case "$2"
  in *[!*]*) :
  ;; *)
    return_val "$1"
    return
  esac

  case "$1"
  in *$2*) eval "echo \"\${1%%$2*}$3\${1#*$2}\""
  ;; *)    return_val "$1"
  esac
}
```

##部分文字列展開相当を作る

```
$ substr hogehoge 2 4
geho
$ substr hogehoge 4
hoge
```

### コード
```bash:dashsub
if ! type return_val >/dev/null 2>&1; then
  alias return_val='echo'
fi

substr() {
  local t= str n=$2 m=${#1} l=$3
  if [ "$2" -ge "$m" ]; then
    return_val ""
    return
  fi
  if [ -z "$3" ]
    then l=0
    else l=$((m-n-l))
  fi
  while [ $n -gt 0 ]; do
    t=${t}?
    n=$((n-1))
  done
  eval "str=\"\${1#$t}\""
  t=
  while [ $l -gt 0 ]; do
    t=${t}?
    l=$((l-1))
  done
  eval "return_val \"\${str%$t}\""
}
```
Rails Ruby 検索の仕方

<h1>Rails Ruby 検索の仕方</h1>
<h2>基本的なところで理解しきれてなかったので、まとめておく。Userモデルデータは次の通り</h2>
id:8
name：山田太郎
department：開発部
email: yamada@gmail.com 
まずはターミナルから該当のフォルダに入り

```ターミナル
>#rails c
```
id（インデックスで検索する）

```ターミナル
>User.find(8)
>SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 8], ["LIMIT", 1]]
> => #<User id: 8, name: "山田太郎", email: "yamada@gmail.com", created_at: "2019-05-13 21:29:13", updated_at: "2019-05-13 21:29:13,department: "開発部
````
以下検索結果は同じで省略
名前で検索

```ターミナル
>User.find_by(name:"山田太郎")
```

whereで名前検索

```ターミナル
>User.where(name:"山田太郎")
```
複数検索

```ターミナル
>User.where(name: '山田太郎', department:"開発部")
```

曖昧検索
where("カラム名 like '%検索テキスト%'")

```ターミナル
>User.where("name like '%山田%'")
```
orあるいは
 データ
id:4
 name：伊藤五郎
department：業務部
email: itogoro@gmail.com 

```ターミナル
>User.where(name: '山田太郎').or(User.where(department:"業務部"))
結果
User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE ("users"."name" = ? OR "users"."department" = ?) LIMIT ?  [["name", "山田太郎"], ["department", "業務部"], ["LIMIT", 11]]
 =># #<ActiveRecord::Relation [#<User id: 4, name: "伊藤五郎", email: "itogoro@gmail.com", created_at: "2019-05-12 04:36:29", updated_at: "2019-05-13 21:56:54",  department: "業務部">, #<User id: 8, name: "山田太郎", email: "yamada@gmail.com", created_at: "2019-05-13 21:29:13", updated_at: "2019-05-13 21:29:13,department: "開発部"
```
参考にしたサイト
https://qiita.com/QUANON/items/0033a5adb76d0cb963cd
以上間違ってたらご指摘下さい
vue.jsで Date Time Picker なら「VueCtkDateTimePicker」

# VueCtkDateTimePicker
[Github](https://github.com/chronotruck/vue-ctk-date-time-picker)
[Demo & Samples](https://chronotruck.github.io/vue-ctk-date-time-picker/)

# ここがすごい
- カスタマイズの自由度が高い
- デフォルトデザインのままでも結構使える
- レスポンシブ対応＆スマホでの操作性も良さそう（実機未確認）

# ここがいまいち
- マウスホバーの動きがちょっとうざい
- ~~SP版のデザインがちょっと惜しい（カレンダーの右側に謎の隙間）~~
→久しぶりに見たらSP版が洗練されてました。 マウスホバーは相変わらずややうざい。

とはいえ両方CSSでなんとかなるので問題なしです。

# 使い方
導入方法やカスタマイズは公式ドキュメントに丁寧に記載されていますので、制作中のnuxt.jsアプリで使っているコードを（ほぼ）そのまま一例として掲載します。

```vuejs
<template>
    <dl>
      <dt>希望日時</dt>
      <dd>
        <Datetime
          v-model="requestDate"
          :minute-interval="30"
          :format="'YYYY-MM-DD HH:mm'"
          :disabled-hours="['00', '01', '02', '03', '04', '05', '06', '07', '08', '17', '18', '19', '20', '21', '22', '23']"
          :overlay="true"
          :min-date="start"
          :max-date="end"
        ></Datetime>
      </dd>
    </dl>
</template>

<script>
import moment from 'moment'
import Datetime from 'vue-ctk-date-time-picker';
import '@/node_modules/vue-ctk-date-time-picker/dist/vue-ctk-date-time-picker.css';

export default {
  components: {
    Datetime
  },
  data() {
    return {
      requestDate: ''
    }
  },
  computed: {
    start() {
      // min-date に明日の9時を指定
      const start = moment().add(1, 'days').hour(8)
      return start.format('YYYY-MM-DDTHH:mm:ss')
    },
    end() {
      // max-date に min-date から3ヶ月後を指定
      const start = moment(this.start)
      const end = start.add(3, 'months').endOf('day')
      return end.format('YYYY-MM-DDTHH:mm:ss')
    }
  }
}
</script>

```
## 詳細
```vuejs

<Datetime
:format="'YYYY-MM-DD HH:mm'"
:minute-interval="30"
:disabled-hours="['00', '01', '02', '03', '04', '05', '06', '07', '08', '17', '18', '19', '20', '21', '22', '23']"
:overlay="true"
:min-date="start"
:max-date="end"
>
```

- `format=""` : 表示フォーマット
- `minute-interval="30"` : 選択可能な「分」の間隔を指定。この場合30分間隔
- `disabled-hours="[...]"` : 選択**不可能**な「時」を配列形式で記載
- `overlay="true"` : trueにするとDateTimePicker表示時に背景が暗くなる
- `min-date`, `max-date` : 「日」を選択可能な期間を指定


# 補足
公式ドキュメントでわかりづらかったところ

### `position`
`position="'top' or 'bottom'"`

DateTimePickerは、入力欄の表示位置がウィンドウの上に近ければ入力欄の下側、ウィンドウの下に近ければ入力欄の上側に表示されます。（日本語がわかりづらい…）

![datetimePCtop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185122/8b8f8087-f18a-9b26-9d26-35a0c7f14da0.png)
▲ 入力欄（赤枠部分）が上の方にあればDateTimePickerはその下側に

![datetimePCbottom.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185122/02f15212-d427-3542-9d70-2ae4bd9795e1.png)
▲ 入力欄（赤枠部分）が下の方にあればDateTimePickerはその上側に

`position="top"`で上側固定、`position="bottom"`で下側固定になります。

### `format`
default: `format="'YYYY-MM-DD hh:mm a'"`

時刻のフォーマットを`HH:mm`にすると「時」の選択が24時間形式になります。

## おしまい
vuejsで使えるDatetimePickerは数あれど、自分の用途に合い、かつ使いやすいものにはなかなか出会えずにいました。
ずいぶん探し回りましたがようやく出会えました。
[VueCtkDateTimePicker](https://github.com/chronotruck/vue-ctk-date-time-picker)、大好き！（あのCM風に）
Gitの簡単なコンフリクトを解消する　　～わかばちゃんと学ぶGit使い方入門SECTION13～

#コンフリクトとは？
Gitにおけるコンフリクトとは、ソースコードの同じ行に別々の修正がされた際、Gitは内容の優先順位を決定できないためにマージができない状態のことを指す。今回はGit初心者の筆者が[わかばちゃんと学ぶGit使い方入門](https://www.amazon.co.jp/gp/product/4863542178/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1)を参考に、意図的に簡単なコンフリクトを起こしてそれを解消することでコンフリクトの解決方法を学ぶ。

#コンフリクトさせる前のソースコード
コンフリクトさせるソースコードの例としてごく単純な例を示す。

```c:src
#include <stdio.h>
int main(){
    printf("Hello World!\n");
    return 0;
}
```

Gitを使う際は書籍に倣い、GUIがとても親切な[SourceTree](https://ja.atlassian.com/software/sourcetree)を用いた。

まず、上記のコードをmasterとし、new_branchという名前のブランチを切る。
そしてソースコードのprintf()の文言を下記のように変更する。

```c:src
#include <stdio.h>
int main(){
    printf("Hello Branch World!\n");
    return 0;
}
```

次に、masterにチェックアウトし、masterの方でもprintf()の文言を変更する。

```c:src
#include <stdio.h>
int main(){
    printf("Hello Master World!\n");
    return 0;
}
```

それぞれをコミット＆プッシュしたときのSourceTreeは下記のようになる。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321441/e73cb275-c0aa-7d51-3047-e96d0ccceb8d.png)


これらは同一の行にあるprintf()のコードを変更しているのでコンフリクトが発生する。masterにチェックアウトしていることを確認し、作ったブランチnew_branchをmasterにマージする。そうすると下記の警告が出てコンフリクトが発生したことを教えてくれる。
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321441/681e3a2f-6349-cd99-c721-7c2e942431c6.png)

![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321441/d3a2fc0b-4fec-1777-a18d-59e5f516fd1d.png)

ここでソースコードを確認する。エディタはVScodeを使っている。

![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321441/86d53d1d-66bb-8331-5c22-178eab5422ff.png)

なんとまあご丁寧にコンフリクトの場所を教えてくれるだけでなく、変更の取り込み方も提案してくれている。しゅごい。

とりあえず今回は自分の手でコンフリクトを解消するということなのでコンフリクトしているprintf()について下記のように変更を行った。

```c:src
#include <stdio.h>
int main(){
    printf("Hello Master Branch World!\n");
    return 0;
}
```

文言としては支離滅裂だがとりあえずこのままで再度コミットをする。コミットの際は自動的に下記のコメントがつく。

```
Merge branch 'new_branch'

# Conflicts:
#	src.c
```

これにより、無事にコンフリクトを解消し、無事にマージすることができた。

![キャプチャ5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321441/28ffafdf-9c13-f6a2-35db-57aae6dcea5a.png)


#まとめ
Git初心者の筆者が[わかばちゃんと学ぶGit使い方入門](https://www.amazon.co.jp/gp/product/4863542178/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1)を参考に、意図的に簡単なコンフリクトを起こしてそれを解消することでコンフリクトの解決方法を改めて学んだ。この本はコミットやブランチなど、基本的なコマンドについて概念から説明している本であり、絵や行間も多く用語も丁寧に説明しているため、Gitをほとんど使ったことのない本当の初心者が知らない単語を連発されて学習意欲をなくすことがほとんどないと思われる。
玄人にはおすすめできないが、趣味で小規模な開発するGit初心者にオススメできると考えられる。

#リポジトリ
https://github.com/fumikiri/WakabaChanGitSec13

#参考文献
[湊川あい著　DQNEO監修 (2017) 『わかばちゃんと学ぶGit使い方入門』 C&R研究所](https://www.amazon.co.jp/gp/product/4863542178/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1)
Leetcode #8: String to Integer(atoi)

```swift
func myAtoi(_ str: String) -> Int {
    let str = str.trimmingCharacters(in: .whitespaces)
    var isMinus = false
    var num = 0
    for (index, char) in str.enumerated() {
        if index == 0 {
            if char == "+" {
                isMinus = false
            } else if char == "-" {
                isMinus = true
            } else if char >= "0" && char <= "9" {
                isMinus = false
                num = Int(String(char))!
            } else {
                return 0
            }
        } else {
            if char >= "0" && char <= "9" {
                num = num * 10 + Int(String(char))!
            } else {
                break
            }
        }
        if isMinus && -num < Int(Int32.min) {
            return Int(Int32.min)
        } else if !isMinus && num > Int(Int32.max) {
            return Int(Int32.max)
        }
    }
    return isMinus ? -num : num
}
```
Leetcode #6: Zigzag Conversion

```swift
func convert(_ s: String, _ numRows: Int) -> String {
    var s = Array(s)
    var strs = Array(repeating: String(), count: numRows)
    var currentIndex = 0
    while currentIndex < s.count {
        for i in 0..<numRows {
            guard currentIndex < s.count else {
                break
            }
            strs[i] += String(s[currentIndex])
            currentIndex+=1
        }
        guard currentIndex < s.count else {
            break
        }
        for i in stride(from: numRows-2, to: 0, by: -1) {
            guard currentIndex < s.count else {
                break
            }
            strs[i] += String(s[currentIndex])
            currentIndex+=1
        }
    }
    return strs.joined(separator: "")
}
```
OSXにredmine 3.4を入れるメモ②

## 今回の目標
- Apacheと連携して、作ったredmineに社内からアクセスできるようにする
- プラグインを入れる

## 参考
http://redmine.jp/tech_note/apache-passenger/ こちらに沿って作業します。

プラグインは
https://qiita.com/kooohei/items/3c86554af93d12ad9322 の入れ方を参考に
https://qiita.com/will_meaning/items/97f5ff6b1a3a66fcf975 のおすすめプラグインからチョイスして導入させていただきました。

## エラーと解決
### その1

```
$ bundle exec rake redmine:plugins:migrate RAILS_ENV=production
rake aborted!
Redmine::PluginRequirementError: redmine_lightbox2 plugin requires Redmine 4.0 or higher but current is 3.4.10.stable
```
Redmine 4.0かそれ以上といわれたので、おそらくredmine_lightbox2のバージョン違いだろうと予測し

https://github.com/paginagmbh/redmine_lightbox2/tree/redmine-3.4 からredmineの古いバージョン用プラグインをインストール。

再度`$ bundle exec rake redmine:plugins:migrate RAILS_ENV=production`すると成功。

### その2
ブラウザ上で下記エラーが発生

```
Internal error
An error occurred on the page you were trying to access.
If you continue to experience problems please contact your Redmine administrator for assistance.

If you are the Redmine administrator, check your log files for details about the error.

Back
```

error.logを確認すると

```
ActionView::Template::Error (uninitialized constant ViewCustomize::INSERTION_POSITION_HTML_HEAD):
```
とのこと。

プラグインの該当フォルダ`redmine-view-customize`を`view_customize`へ変更。(https://github.com/onozaty/redmine-view-customize/issues/28)

```
$ bundle exec rake redmine:plugins:migrate RAILS_ENV=production
$ sudo apachectl restart
```

こちらも忘れず実行。ブラウザをリロードすると解決。
aria-live属性を使ってフォームのエラーメッセージ

##エラーメッセージは動的に生成する場合

- アクセシブルじゃない

```html:form.html
<form name="signup" id="signup" method="post" action="">
  <label>お名前 (必須)</label> <!-- for属性がinputと結びついていない -->
  <input type="text" name="name"> <!-- idが無くlabelと結びついていない,本当に必須かわからない -->
  <p class="errors"></p>
  <button type="submit" name="button" id="button">送信</button>
</form>
```

- アクセシブル

```html:form.html
<form name="signup" id="signup" method="post" action="">
  <label for="name">お名前 (必須)</label>
  <input type="text" name="name" id="name" required aria-required="true">
  <p class="errors" aria-live="polite"><span>お名前は必須項目です。</span></p> 
  <button type="submit" name="button" id="button">送信</button>
</form>
```

要素の変更があった時に即座に変更が通知されます。
初期読み込み時にDOMに読み込んでおかなければなりません。
`aria-live`のプロパティには以下があります。

> off: 内容が更新されてもユーザーに伝達しない(デフォルト)
> polite: 現在の読み上げの終了やユーザー入力時など適切なタイミングで、内容が更新されたさいにユーザーに伝達する
> assertive: 即座に伝達を行う

`role="alert"`なども通知を行う用途としてあります。
`role="alert"`や`aria-live="assertive"`はこのフォームでのエラーメッセージの読み上げというよりかは、例えば読み込みが完了しましたという通知やアップロードが完了しましたといった通知系での用途が適切です。

フォームだけのものではなく、色々と使い所があるので実装して実際に音声読み上げで聞いてみて、コンテンツのコンテキストが正しく伝えられているかを考えて使いましょう。

### 参考
	
- https://developers.google.com/web/fundamentals/accessibility/semantics-aria/hiding-and-updating-content?hl=ja
- https://waic.jp/docs/WCAG-TECHS/ARIA19.html
one-hotvector化とbin(Discretize)化ライブラリ比較

前処理で必ず発生するonehotvector化とdiscretizeのライブラリ比較。
何か発見したら追加するかも。
pandasを使いまくってる身としてはpandasで処理してしまいたくなります。



|ライブラリ　　　　　　　|discretize|onehot|
|---|---|---|---|
|tensorflow|[tf.feature_column.bucketized_column](https://www.tensorflow.org/api_docs/python/tf/feature_column/bucketized_column)|[tf.feature_column.categorical_column_with_vocabulary_list](https://www.tensorflow.org/api_docs/python/tf/feature_column/categorical_column_with_vocabulary_list)|
|scikitlearn|[KBinsDiscretizer](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.KBinsDiscretizer.html#sklearn.preprocessing.KBinsDiscretizer)|[OneHotEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html)|
|gensim|-|-|
|keras|-|[keras.utils.to_categorical](https://keras.io/utils/#to_categorical)<br>[keras.preprocessing.text.one_hot](https://keras.io/preprocessing/text/#one_hot)|
|pandas|[pandas.cut](https://pandas.pydata.org/pandas-docs/version/0.23.4/generated/pandas.cut.html)|[pandas.get_dummies()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.get_dummies.html)|

<br>
<br>

[numpy.eye](https://docs.scipy.org/doc/numpy/reference/generated/numpy.eye.html)、[numpy.digitize()](https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html)も組み合わせれは同じことができるそうで。
ORCA レセ電ビューワ（レセ電ビューア）をUbuntu 18.04にインストールする

# 概要
レセ電ビューワ（レセ電ビューア）のLinux版のインストール方法です。
https://www.orca.med.or.jp/receipt/use/jma-receview.html

# やり方
## apt-lineに追加
- `sudo nano /etc/apt/sources.list`でパッケージリストを開く
- 最後の行に`deb [trusted=yes] http://ftp.orca.med.or.jp/pub/ubuntu bionic5.1 jma`を追加して保存。[trusted=yes]無しだと、セキュリティが低いため更新されません、というようなメッセージが出て`sudo apt update`ができない。
- `sudo apt update`を実行

## apt install する
- `sudo apt install jma-receview`を実行
- `sudo apt install libcanberra-gtk-module`自分の環境ではなぜかこれだけ自動でインストールされなかったので後から追加した

# 起動
- `jma-receview`
- `jma-receview -v`バージョン確認
- `jma-receview -h`ヘルプ

# 参考
[トップ > 日医標準レセプトソフト > 運用のための各種設定 > レセ電ビューワ](https://www.orca.med.or.jp/receipt/use/jma-receview.html)
[APT／apt-lineについて](http://morimoru.blogspot.com/2009/02/apt.html)
[Bypass GPG signature checks only for a single repository](https://unix.stackexchange.com/questions/198000/bypass-gpg-signature-checks-only-for-a-single-repository)
[電子レセプトについて調べた話](https://developer.medley.jp/entry/2018/07/06/114000)
物体・条件を考慮した物体検出

# はじめに

物体の検出方法でよく使われるのは、差分をとってRGBの差分を取ることですが、
検出したい物体の性質を考えることにより、もっと適した検出方法があります。

# 対象

私は今、最終的にダイスの出目を判別できるようなシステムを作ろうとしています。
ダイスの性質としては次のようなものが考えられます。

- 室内で使用する
- 小さい
- 様々な色がある

背景からダイスだけ切り出そうとした場合、
ダイスの影が物体検出の邪魔になることがあります。

今回はRGBではなく、HSVで物体検出することによって影の影響を抑えてみます。
影となる場所は彩度・輝度の変動は小さく、色相の変化はないはずですので、それを踏まえたしきい値の選択をしています。
なお、HSVへの変換方法は[OpenCVとVisual C++による画像処理と認識（４）](http://ishidate.my.coocan.jp/opencv_4/opencv_4.htm)を、
HSVの各チャンネルごとの変換には[NumPy配列ndarrayを分割](https://note.nkmk.me/python-numpy-split/)を参考にしました。
最後のマスク処理は[Python + OpenCVによるマスク画像適用方法](https://qiita.com/Zumwalt/items/fb2e7c20d935803126c7)を参考にしています。

```python
import cv2
import numpy as np

GAUSSIAN_SIZE = (7,7)

camera = cv2.VideoCapture(0)

# 背景画像とダイスの画像を取得

result, image_base = camera.read()
if not result:
    exit()
image_base_blured = cv2.GaussianBlur(image_base, GAUSSIAN_SIZE, 0)

cv2.imshow("baseImage",image_base)
cv2.waitKey(0)

# カメラの画像を読み取るとき、前回のカメラのバッファを読んでる？
result, image_dice = camera.read()
result, image_dice = camera.read()
if not result:
    exit()
image_dice_blured = cv2.GaussianBlur(image_dice, GAUSSIAN_SIZE, 0)

# HSVに変換した上で差分をとる

base_hsv = cv2.cvtColor(image_base_blured, cv2.COLOR_RGB2HSV)
dice_hsv = cv2.cvtColor(image_dice_blured, cv2.COLOR_RGB2HSV)

diff_hsv = cv2.absdiff(base_hsv, dice_hsv)

# 2次元目を3つに分割→HSVの差分のチャンネルを分離
diff_imagelist = np.split(diff_hsv,3,2)

width = diff_hsv.shape[0]
height = diff_hsv.shape[1]

hdiff = diff_imagelist[0].reshape(width,height)
sdiff = diff_imagelist[1].reshape(width,height)
vdiff = diff_imagelist[2].reshape(width,height)

image_dice[hdiff>15] = [255,0,0]
image_dice[sdiff>50] = [0,255,0]
image_dice[vdiff>65] = [0,0,255]

cv2.imshow("diceImage",image_dice)
cv2.waitKey(0)

cv2.destroyAllWindows()
```

##結果

![dice.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395414/29fb3e5e-38b3-3891-5746-956467e1ed0c.png)
ダイスの例

![dice_hsv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395414/d834a9ba-6abd-170b-4b33-81ba25b26f8f.png)
上記コードで分割した例

![dice_rgb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395414/434b971e-55dd-16b1-6c8d-5abd4bfada34.png)
RGBでしきい値をとった場合

#結論

画像処理を行いたい対象がいる場合、対象物に適した処理方法がないか考えると、処理が楽になることがあります。
今回はダイスに適した処理を行うことができました。
プログラミング学習記録87〜priventdefault()を使わなくてもなぜかエラーにならなかった〜

##今日やったこと
- ドットインストール「スライドショー」を作り、動画に投稿
- ドットインストール「モーダルウィンドウ」を作り、動画に投稿
- ドットインストール「タブメニュー」を作り、動画に投稿

###「スライドショー」
スライドショーではCSSとJavaScriptを存分に活用しました。

特にplayボタンにhiddenクラスをつけて、pauseボタンからhiddenクラスをとることで、 再生と停止を同じ箇所に表示させるのはなるほどな〜と感心しました。

ハンバーガーメニューなどでもおなじみのJavaScriptの活用法ですね。

これにより、クリックするとボタンと画面が切り替わって、もう一回クリックすると元に戻るボタンを作ることができるようになります。


###「JavaScriptでモーダルウィンドウを作ろう」
ソースコードはこちらです。
https://github.com/yuta-kinu/MyModalWindow
これはめちゃくちゃ簡単でした。

JavaScriptのミニアプリを作ろうの6番目の講座なのですが、１番簡単かもしれません。

記述量も少ないです。

作ってみて流石に物足りなさを感じたので、maskの背景を薄ピンクにして、modalのアニメーションをいじりました。

見本ではmodalを左から４回転して出てくるようにしました。


###「JavaScriptでタブメニューを作ろう」

見本ではpriventdefault()を使ってみるが、使わなくても特にエラーは起きませんでした。
<br>
という感じで、今日はそこそこしっかり進めてよかったです。

おわり
Pythonで標準入力 ~入力行数が指定されていないとき~

標準入力を受けるとき、AtCoderなどでは入力行数が常に指定されているため、 for ループを用いて入力を受けることができる。しかし、今回、入力行数が不明のまま標準入出力を受ける必要がある場面に出会し、非常に苦労したのでメモ。

```py
Input = []
while True:
    try:
        i = list(map(int, input().split()))
        Input += i
    except EOFError:
        break
```

上のように、while 節を用いて入力を受ける必要がありそう。ただし、これはPycharm上では動作しなかったので、その点は注意。
> 2019/5/15 追記
> Shellを起動してCtrl+Dを入力することで、EOFErrorを発生させて入力を終了することができる。