OmniAICreator/Qiita-1.07M huggingface dataset:
WSL(Windows Service for Linux)上のdocker-composeで相対パスでvolumeをマウントする

# なぜこの記事を書いたか

いつもはmacOS上でdocker-composeを使って色々と開発環境を構築しているんですが、Windowsユーザーの方とdocker-compose.ymlを共有する必要があり、そこで「WSL上のdocker-composeではvolumeのマウントに相対パスが使えない」問題に引っかかりました。
良く見かける記事では「絶対パスにしましょう」とか「環境依存にならないように$ROOT_PATHなどを使って絶対パスを書きましょう」と書かれているのですが、絶対パスを使わなくても良い方法を検索で見つけたため、そちらを共有しようと考えました。

# TL;DR

WSL上の`/etc/wsl.conf`を新規で作成し、以下の状態にします。

```/etc/wsl.conf
[automount]
root = /
options = "metadata"
```

ファイルを保存したら、Windowsを再起動すると、WSL上のdocker-composeで相対パスが使えるようになります。

# 検索したページ

いくつかキーワードを設定し、たどり着いたのが以下のページ。

「WSLとDocker for WindowsでGROWIを動かすとvolumesでつまずく」
https://blog.mahoroi.com/posts/2019/04/growi-wsl-docker-for-windows/

こちらに上記の内容が書かれていて「おお〜っ！！」となりました。

# Windowsを再起動すると何が変わるか？

上記ページにも書かれていますが、簡単に言うと`/mnt/c/foobar/`といった形だったWSLのディレクトリ構造が、`/c/foobar/`に変わります。NTFSマウントのROOTが`/mnt/`から`/`に変わったわけですね。

# では何故これで相対パスが使えるようになるのか？

実は良く分かって無い状態で使ってます。何か副作用が無ければ良いのですが、、、（そんな無責任な）

# 最後に

ひとまずmacOSとWindowsで同じdocker-compose.ymlファイルが使えるようになりました。しばらく使って問題が出るようであれば、こちらに追記させて頂きます。
共有フォルダでScoop bucketを運用（超お手軽）

# プライベートなbucketが欲しい
Scoopをある程度使っていると、自作のツールや環境なんかをbucketに突っ込んで置いてコマンド打てば取ってこれたりすると便利だな、というような事を考え出す。

じゃあそうしよう、それもお手軽に、という記事である。
# まずgitリポジトリを作る
Scoopはインストール情報が入ったjsonをgitで管理してある。なので共有フォルダにgitリポジトリを作る。

便宜上共有フォルダのパスを ```\\sharedhost\myBucket\``` とする。
ここにbareリポジトリを作ろう。

実際のアーカイブの保管先も共有フォルダに作る。
ここでは```\\sharedhost\archive\```としておく。

# アーカイブを作る
要するにzipファイルである。
ここではお試しということで、hoge.batというバッチファイルをインストールすることにしよう。

```hoge.bat
echo 'hello hoge world.'
```
このhoge.batを圧縮し、hoge.zipにする。
hoge.zipを//sharedhost/archive/にコピーして置こう。

# jsonを作る

```hoge.json
{
    "version": "1.0",
    "url": "file:////sharedhost/archive/hoge.zip",
    "bin": "hoge.bat"
}
```

hoge.jsonの内容である。複雑なことをやろうと思えば複雑なことをやれる。今回はやんないけど。

jsonをgitリポジトリにaddしてcommitしてpushしよう。
これで準備は終わりである。
# ScoopにmyBucketを追加する
```
scoop bucket add myBucket \\sharedhost\myBucket
```

これでmyBucketが使える。追加したら```scoop update```をしておこう。

```
scoop install hoge
```

これで取れるはずだ。
インストールが終わったら早速hogeコマンドを叩いてみよう。**hello hoge world.**が表示されたらおめでとうなのである。

# 仕組みさえ分かれば
これをベースにリッチな運用方式を作っちゃうのも楽しい。
たったこれだけでも、チームでの業務アイテムの共有なんかが格段に便利になる。なんせコマンド渡すだけだ。

Scoopについては以下のような良記事があるので参考にされたし。

- [Scoopを使ったWindows環境構築のススメ - Super!!](https://qiita.com/rkbk60/items/12dc8fb14042888113d0)
- [Scoopを使ったWindows環境構築のススメ - Hyper!!!](https://qiita.com/rkbk60/items/c55223c26a42776f7101)
Googleカレンダーの招待通知をSlackに送信

Googleカレンダーの招待通知がわかりにくい。メールにしか届かない。Slackに通知したい。

##Zapier
フリープランだと回数制限。 トリガーが細かく指定出来て便利だがなるべく無料がいい。

##IFTTT
[Gmailトリガー、Googleに消されたらしい](https://japanese.engadget.com/2019/03/23/ifttt-3-31-gmail/)。復活してくれ(2019年3月)

#Gmail転送
こんな手があったとは。

###Slack環境設定
![Slack_IMG](https://cl.ly/43d47e5dfb87/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525202019-06-03%25252013.12.40.png)

![Slack_IMG_1](https://cl.ly/d23560589953/%255B39eb7a5c8a1e27b1d8341450fee129c8%255D_%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525202019-06-03%25252013.14.24.png)

###Gmail環境設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185109/fea5b3f6-3877-60d4-29c2-490184bf4c92.png)

![Gmail_IMG](https://cl.ly/e429f835ee26/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525202019-06-03%25252013.18.11.png)

![Gmail_IMG_1](https://cl.ly/b689ebcc5ecc/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525202019-06-03%25252013.20.36.png)

![Gmail_IMG_2](https://cl.ly/2032a84123ae/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525202019-06-03%25252013.25.33.png)

 添付ファイルにチェックを入れると確実（icsファイルくっついてる）

![Gmail_IMG_3](https://cl.ly/93d23f1d3e07/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525202019-06-03%25252013.30.35.png)

##完成

![Wei](https://cl.ly/cdb833b0b76f/%2525E3%252582%2525B9%2525E3%252582%2525AF%2525E3%252583%2525AA%2525E3%252583%2525BC%2525E3%252583%2525B3%2525E3%252582%2525B7%2525E3%252583%2525A7%2525E3%252583%252583%2525E3%252583%252588%2525202019-06-03%25252013.32.13.png)
vue.js css エラー

npm run watch したら

cssのセミコロン足りんよって。

CssSyntaxError:

```
 /css/app.css:287:19: Missed semicolon

```

見たけど、CSS異常無いやん。
ということで、以下を 個別vue に書いてたのがバグの原因でした。
app.js に書いたら治りました。


```

import { Radar, mixins } from 'vue-chartjs';

```
CircleCIのみでbundle update〜プルリク作成までを自動化してみた

Github上でbundle update用のgemはいくつか見かけたが、個人用のリポジトリだったりしてメンテ頻度不明なため、CircleCIのみでbundle updateできないか模索した。

CircleCI2.0よりcron機能が利用できるようになってるので、それを利用すれば可能と判明。
以下、毎月1日に動作させるように設定した（以下、必要箇所抜粋）

~~~CircleCI:.circleci/config.yml

 bundle_update:
   docker:
     - image: 利用イメージ名記述
       environment:
         BUNDLE_JOBS: 3
         BUNDLE_RETRY: 3
         BUNDLE_PATH: vendor/bundle
   steps:
     - checkout
     - restore_cache:
         keys:
           - 接頭字-{{ .Environment.CACHE_VERSION }}-{{ checksum "Gemfile.lock" }}

     - run:
         name: Bundle Install
         command: bundle check || bundle install

     - run:
         name: Bundle Update
         command: bundle update

     # Create branch
     - run: git checkout -b bundle-update-$CIRCLE_BUILD_NUM
     - run: git config user.email "メールアドレス"
     - run: git config user.name "管理者名"
     - run: git add Gemfile Gemfile.lock
     - run: git commit -am '今月のGemfile更新用の自動作成プルリク'
     - run: git push origin bundle-update-$CIRCLE_BUILD_NUM
     - run:
         name: Create a pull request
         command: |
           curl \
             --header "Accept: application/vnd.github.v3+json" \
             --data "{\"title\": \"今月のbundle-update\", \"head\": \"ワークスペース名:bundle-update-$CIRCLE_BUILD_NUM\", \"base\":\"master\" }" \
             https://api.github.com/repos/githubアカウント/対象トリポジトリ名/pulls?access_token=${GITHUB_ACCESS_TOKEN}

workflows:
 version: 2
 monthly-bundle-update:
   triggers:
     - schedule:
         cron: "0 9 1 * *" ←UTC記述。毎月1日に動作させるよう記述
         filters:
           branches:
             only:
               - master
   jobs:
     - bundle_update
~~~

特徴としては、CircleCIの環境変数を利用してbranch名の重複を避けている点。
branch名の重複を避ける事でCircleCIをRerunしてもbranch名の重複でコケるのを避けられる。

`$CIRCLE_BUILD_NUM`： CircleCI側で準備されているビルド番号用の環境変数
`${GITHUB_ACCESS_TOKEN}`：　こちら側で独自に準備したGithub連携用のアクセスtoken

[※CircleCI側が提供している環境変数はこちら](https://circleci.com/docs/2.0/env-vars/)

注意点として、bundle updateする場合、Gemバージョンアップをどこまで許容するかが重要。

Gemfile内で、メジャーアップデートさせたいGem、マイナーバージョンのみアップデートさせたいGemなどを切り分ける必要がある。


`Gemのメジャーバージョンのアップデート(X.X.Xの2桁目をアップデート)を行う記述は以下の通り`

~~~Ruby:Gemfile
gem 'devise', '~> 4.6'
~~~

`Gemのマイナーバージョンのアップデート(X.X.Xの3桁目をアップデート)を行う記述は以下の通り`

~~~Ruby:Gemfile.lock
gem 'devise', '~> 4.6.0'
~~~

Railsであれば、Rspecなどのテストツールで書かれていない範囲にはサードパーティーのGem関連の機能が無いようにする事を忘れない事が重要。（Gemをバージョンアップした結果、動作しない事態を避けるため）
Expo SDK33のpreviewを試しに使う方法

## はじめに

ExpoはSDK31からbabel7になってtypescriptも使いやすくなるなど便利になって、使っています。SDK33ではwebサポートやパッケージの分離など様々な進歩がありそうです。

## preview版

5/31にブログ記事がアップされていました。

https://blog.expo.io/updated-expo-client-available-on-app-store-and-play-store-8747bd3a1364

> We haven’t yet released SDK 33, but it’s coming very shortly.

とのことです。

> expo init my-new-project --template blank@next

これで試せるようです。

## おわりに

自分でも試してみましたが、jestとtypescriptの型定義でうまくない部分があって、手を入れる必要がありました。まだ、移行手順がないので、何か勘違いしている部分があるかもしれません。興味ある方は、 [こちらのリポジトリ](https://github.com/dai-shi/typescript-expo-apollo-boilerplate/tree/6f16f45c11164430c5ae05ee7cbef602163a3db4) をご参照ください。
GoでHTTPリクエストのデバッグ

ヘッダに`Host: example.com`をつけているのに期待通りの動作にならなくて、少しハマったので、メモ。

まず実際に実行されたHTTPリクエストやサーバーからのレスポンスを確認するには、httputilの`DumpRequest`, `DumpResponse`が便利。

```go
	dump, _ := httputil.DumpRequest(req, true)
	fmt.Printf("%q", dump)

	res, err := client.Do(req)

	dump2, _ := httputil.DumpResponse(res, true)
	fmt.Printf("%q", dump2)
```

結果、

```go
req.Headers.Set("Host", "example.com")
```

では期待通りにヘッダがつけられていないことが判明。正解は、

```go
req.Host = "example.com"
```

と書くのだそうだ。

参考: https://qiita.com/hnakamur/items/8a8ad0813eb577fc9018
CSS2日目

今日はステップアップ編（らしい）

#フォント

```
セレクタ{
font-family: フォント名 or　フォントファミリー;
}
```

- 問題点
 - PCやスマホに入っているフォントはそれぞれ異なる。
 - デザイナーやエンジニアの意図しない表示がされる可能性がある。

##フォントファミリー
デザインを統一した、複数のフォントをまとめたもの。

.serif ⇒　明朝体
.sans-serif ⇒　ゴシック体

##### font-family: "Hiragino Kaku Gothic ProN", "メイリオ", "sans-serif"

- 普通、複数のフォントを指定する。
- 左から優先順位がが高い。
- sans-serifは「なんかしらの」ゴシック体を示す。

###フォントに関するプロパティ
- font-family: フォント名、フォントファミリーを指定
- font-size: フォントサイズを指定
- font-weight: 太さ(normal or bold)
- line-height: 行間(これちょっとわからん)
- text-align: 文字寄せ
- text-decoration: 装飾線(下線、取り消し線)

### WEBフォント
- WEBサーバー上に配置したフォントファイルをインターネットを経由して配信。
- WEBフォントを使うことで、どの環境でも同一のフォントが表示されるようになる。
- 製作者の意図した印象をユーザーに与えることができる。

-欧文フォント: Webフォントが普及している。
-和文フォント: 普及は十分とはいえない。
  - 文字数が多く、データ量が多い。

#### 代表的なWebフォント
- Google Web Fonts
- Google Web Fonts 日本語
- モリサワ　TypeSquare
- Font Awesome

##ボックスモデル
- CSSで自由にデザインを行う上で重要
- HTMLタグでマークアップされた要素はひとつの箱とみなされる。
- CSSではこのボックスの大きさや色、位置、大きさなどを指定して、デザイン・レイアウトを行う。

![あ](https://dekiru.net/contents/355/img/3554201.png)
[参照元はこれやで](https://dekiru.net/article/13077/)

##フロートレイアウト
Windowsでgithubを使う for Mac ユーザー

最近のWindowsにはデフォルトでPowerShellが付属している。
PowerShellはunixベースのコマンドが使えます。

PowerShell上でgithubの操作をしようとすれば、
下記ののようなログイン画面が出てくるので、
ログインしてください。

![GitHubLogin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27590/aa495350-ea9f-f961-d1c9-7451b43106a1.png)

あとはmacと同じにように操作できます。
EC2上のDjangoからAmazon RDSに接続する

## 環境
- AWS RDS
- Python: 3.6
- pipenv: 2018.7.1
- pip: 18.0.0
- Django: 1.11.18

## 執筆したきっかけ
- 研究で開発する実験用システムに必要！
- デプロイしたシステムとDBを接続したい
- 他の手段やどのDBがいいかはわからない．．
- あくまで備忘録程度です

## Amazon RDS側の設定
1. Amazon RDSのコンソールを起動する
2. 画面下にある`RDS無料枠の対象オプションのみ有効化`にチェックを入れる
3. データベースはMariaDBを選択する
4. インタンスの識別子，ユーザ名などを入力する
  - データベース名の入力を忘れない．あとで面倒なことになる
  - VPCセキュリティグループは，`EC2`と同一のグループにする
5. インスタンス生成後，セキュリティグループのリンク先を開く
6. インバウンドとアウトバウンドに，Mysql用のルールを追加する
  - ソースは`0.0.0.0`とする(本当は接続元IPを限定するべき)
  - このルールが上手く設定できないと，`ERROR 2003 (HY000): Can’t connect to MySQL server on...`のエラー発生原因になる

## Django側の設定
mysqlを使用するため，mysqlclientをインストールする

```
pipenv install mysqlclient
```

settings.pyを編集する

```Python:settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'DB名',
        'USER': 'マスターユーザー',
        'PASSWORD': 'マスターユーザーパスワード',
        'HOST': 'エンドポイント',
        'PORT': '3306',
    }
}
```

Djangoの管理コマンドを用いて，設定内容が有効かどうかを検証する

```
python manage.py dbshell
```
## 補足
タイムゾーンの設定ができておりません．また，DBを追加するときはSSHで入ってから，追加するのだろうか．．．

## 参考
- [Amazon RDS for MySQLインスタンス作成手順](https://qiita.com/na0AaooQ/items/7c69a88c80f1efb4cad3)
- [MariaDB データベースを作成して接続する](https://aws.amazon.com/jp/getting-started/tutorials/create-mariadb-db/)
- [EC2からRDS(MySQL)に接続できない。セキュリティグループの設定について・・・](https://qiita.com/nao-otsu/items/8cabd447d73b621cd07d)
- [Django、Amazon RDS(MariaDB)に接続する](https://narito.ninja/blog/detail/28/)
- [Python アプリケーション環境に Amazon RDS DB インスタンスを追加](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create-deploy-python-rds.html)
pip で「Consider using the `--user` option or check the permissions.」が出た

！！今回の記事は解決まで至ってませんが記録として残すものです。！！

```
PS D:\git\ramchan> pip list
Package    Version
---------- -------
pip        19.0.3
setuptools 40.8.0
You are using pip version 19.0.3, however version 19.1.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.
```
pip の最新がある模様ということでpipアップデート。

```
PS D:\git\myapp> pip install -U pip
Collecting pip
  Using cached https://files.pythonhosted.org/packages/5c/e0/be401c003291b56efc55aeba6a80ab790d3d4cece2778288d65323009420/pip-19.1.1-py2.py3-none-any.whl
Installing collected packages: pip
  Found existing installation: pip 19.0.3
    Uninstalling pip-19.0.3:
      Successfully uninstalled pip-19.0.3
Could not install packages due to an EnvironmentError: [WinError 5] アクセスが拒否されました。: 'C:\\Users\\username\\AppData\\Local\\Temp\\pip-uninstall-sbi5uw51\\pip.exe'
Consider using the `--user` option or check the permissions.
```

pipをアップデートするだけでアクセス拒否が出た。
--userオプションの利用を検討してみよとのメッセージが出てるのでオプションつけてみた。

```
PS D:\git\myapp> pip install -U pip --user
Requirement already up-to-date: pip in c:\users\username\appdata\local\programs\python\python37-32\lib\site-packages (19.1.1)
PS D:\git\myapp> pip list
Package    Version
---------- -------
pip        19.1.1
setuptools 40.8.0
```
すでに最新になっているとのこと。
ちょっと謎だが次回また発生したら試してみよう。
UNIX版MicroPython

#免責
この記事に従って発生した如何なる損害も筆者は負うことができません。ご免なさい。

#はじめに
使い勝手が良いのでMicroPythonがお気に入りです。

#目的
Ubuntuで使いたいのでUNIX版をインストールしてみます。
README.mdをそのまま素直に実行します。

#Ubuntu前準備
ビルドで使うパッケージをインストールします。足りなかったら、ごめんなさい。

```shell-session:ビルドで使うパッケージ
$ sudo apt install libffi-dev pkg-config build-essential git
```

#ダウンロード
githubからソースコードを拾います。
--recursiveをつけないとエラーが出ました。

* 「make: *** 'build/genhdr/qstr.i.last' に必要なターゲット 'lib/axtls/ssl/asn1.c' を make するルールがありません.  中止.」
* "No rule to make target 'lib/berkeley-db-1.xx/btree/bt_close.c', needed by 'build/genhdr/qstr.i.last'. Stop."

```shell-session:MicroPythonのソースコード
$ #--recursiveをつけないとエラーが出ました。
$ git clone --recursive https://github.com/micropython/micropython.git
```

#インストール
コンパイルしてインストールします。
まずコンパイルします。

```shell-session:MicroPythonをコンパイル
$ make -C micropython/mpy-cross # 必要みたいです
$ make -C micropython/ports/unix
```

次にインストールします。

```shell-session:MicroPythonをインストール
$ sudo make -C micropython/ports/unix install
```

#MicroPythonを動かす

```shell-session:MicroPythonを実行
$ micropython
MicroPython v1.16-171-gf834fef6b on 2021-08-08; linux version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>>
```

#MicroPythonスクリプトで使うパッケージを追加
追加パッケージはupipを使ってインストールします。
使うときはimportします。

```shell-session:パッケージ追加
$ micropython
MicroPython v1.16-171-gf834fef6b on 2021-08-08; linux version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>>
>>> import upip
>>> upip.install("urequests")
Installing to: /home/pi/.micropython/lib/
Warning: micropython.org SSL certificate is not validated
Installing urequests 0.6 from https://micropython.org/pi/urequests/urequests-0.6.tar.gz
>>> 
>>> 
>>> data = urequests.get("https://micropython.org/help/")
>>> data.status_code
200
```

#アンインストール
MicroPythonをアンインストールするには次のようにします。

```shell-session:MicroPythonをアンインストール
$ sudo make -C micropython/ports/unix uninstall
```

パッケージや操作の履歴も全て消したいのなら次のように実行します。
削除操作は危険なのでご注意を。

```shell-session:パッケージと操作の履歴も消す
$ rm -fr ~/.micropython
$ rm ~/.micropython.history
```

#まとめ
これでMicroPythonをUbuntuで使うことができます。
php-pdftoppm実行時のエラー「PdfToPpm was unable to convert pdf to images」の対処


https://github.com/waarneembemiddeling/php-pdftoppm
でPDFから画像ファイルへの変換の実行時間が60秒を超えると
エラー「PdfToPpm was unable to convert pdf to images」が出力されていた。

vendor/symfony/process/ProcessBuilder.php
の
private $timeout = 60;
を変更したところエラーは出なくなった。
render メソッドの高速繰り返し処理について

#renderメソッドを使って、高速繰り返し処理をする。

#1. 具体例の提示
以下において、二つの例を挙げて、両者を処理速度を比較しつつ説明する。
**例１**

```haml
@users = User.all
@users.each do |user|
  = render 'user',  user: user
```

**例2**

```haml
@users = User.all
  = render 'user', users: @users
```
上記のうち例2のコードが、renderメソッドを使った、高速繰り返し処理を可能にしたコードである。

#2. 両者における処理速度の違いについて
##例１における処理速度
例１では、@ usersにeachを使用して、user一人一人に対してrenderを実行している。そのため、userの数が多ければ多いほど、処理の実行が大きなり、かつ、処理速度が遅くなりやすい。

##例2における処理速度
他方で、例2では、renderする際の変数に@ usersを渡している。そのため、renderは、@ usersという一つの変数を実行すればよいことになる。また、userの数が多くなったとしても、変数自体の数は増えないので、処理の速度はそのまま維持される。よって、例１のコードよりも処理速度が早くなるのである。

なお、render @ users と省略して記述することも可能である。

　　　　　　　　　　　　　　　　　　　　　　　　　　　以上
VirtualBoxにUbuntu18.04LTS入れてcloud9に接続しようとしたら接続できない話

この記事の原因と同じ
https://qiita.com/v97ug/items/eca44cf160b65570e423

Ubuntu18.04LTSではデフォルトですべてのポートが閉じられてるようです。
SSH接続は問題なかったのでファイアウォールが原因だとは思わなかった。

VirtualBoxでホストオンリーアダプタ設定して接続してたのでそこらへんが原因じゃないかと2日調べまくってた。
react + pdfmakeでかんたん日本語PDF出力

#はじめに
reactでpdfを出力したいので、[pdfmake](http://pdfmake.org/)の利用を考えたんだけど、参考ＵＲＬを見ると日本語出力が面倒そう…。

と、思ったら意外と簡単にできたのでメモ。ttfファイルさえあればいくらでもフォントが追加出来ます。

#参考
[クライアントサイドでpdfを生成できるpdfmake.jsをreactで使ってみた](https://qiita.com/rio1228/items/dbab910036d54487f6b9)
[クライアントサイド(React)で日本語PDFを出力する。](https://qiita.com/maecho/items/071abbb60dcbeabef7a6)

#準備
[create-react-app](https://github.com/facebook/create-react-app)　でプロジェクトを作り、`pdfmake`パッケージを追加します

```
create-react-app testApp
cd testApp
yarn add pdfmake
```
`pdｆmake`のモジュールディレクトリに移動して、作業ディレクトリ `exsamples/fonts` に日本語フォントを設置します。今回は[源様明朝](https://github.com/ButTaiwan/genyo-font)を使わせて頂きました。

```
cd node_modules/pdfmake
mkdir -p examples/fonts
cp /path/to/fonts/*.ttf examples/fonts/
```

フォントをコンパイルするのに`gulp`を使います。．事前に `yarn global add gulp`等でインストールしておいてください。そのまま`pdfmake`のディレクトリ内で

```
yarn install
gulp buildFonts
```
これで日本語フォントのインストールが終わりました。`buildFontｓ`はもともとインストールされていたフォントを消してしまうので注意して下さい。

#実装
```index.js
import React, { Component } from 'react';
import pdfMake from 'pdfmake';
import pdfFonts from 'pdfmake/build/vfs_fonts';

pdfMake.vfs = pdfFonts.pdfMake.vfs;
class App extends Component {
  download = () => {
    pdfMake.fonts = {
      GenYoMin: {
        normal: 'GenYoMinJP-Regular.ttf',
        bold: 'GenYoMinJP-Bold.ttf',
      },
    };
    const docDefinition = {
      content: [`テスト出力`],
      defaultStyle: {
        font: 'GenYoMin',
      },
    };

    pdfMake.createPdf(docDefinition).download();
  };
  render() {
    return (
      <button onclick={()=>this.download}>ダウンロード</button>
    }
  }
}
```

#結局
`pdfmake`では既存のＰＤＦファイルの編集が出来ないので、お蔵入り。
GHDLでベンダのVHDLライブラリをコンパイルする

# はじめに
GHDLでシミュレーションを行うためにXilinx ISEのライブラリをコンパイルしたときの記録です。
他にも以下のベンダライブラリ等がコンパイルできるようです。

* Supported Vendors Libraries
  * Altera Quartus (≥13.0)
  * Lattice (≥3.6)
  * Xilinx ISE (≥14.0)
  * Xilinx Vivado (≥2014.1)
* Supported Simulation and Verification Libraries
  * OSVVM (for VHDL-2008)
  * UVVM (for VHDL-2008)

詳しくは[Compile Scripts for Vendor VHDL Libraries](https://github.com/ghdl/ghdl/tree/master/libraries/vendors "Compile Scripts for Vendor VHDL Libraries")を参照してください。

# 開発環境
* Windows10 Pro 64bit
* GHDL 0.35

# Xilinx ISE ライブラリのコンパイル

Pathは適宜読みかえてください

## コンパイル設定

`<GHDL>\lib\vendors/config.psm1`にあるInstallationDirectoryを設定します

```powershell:config.psm1
"XilinxISE" = @{
    "InstallationDirectory" = "C:\Xilinx\14.7\ISE_DS"; # "C:\Xilinx\14.7\ISE_DS";
    "SourceDirectory" = "ISE\vhdl\src";
    "DestinationDirectory" = "xilinx-ise"
};
```

`<GHDL>\lib\vendors/compile-xilinx-ise.ps1`にパラメータを設定します

```powershell:compile-xilinx-ise.ps1
# Compile all libraries and packages.
[switch]$All = $true,
# Set VHDL Standard to '08
[switch]$VHDL2008 =	$true, # ここではVunitで使用するためにtrueにした、ただし一部コンパイルエラーになる
# Set GHDL binary directory.
[string]$GHDL = "<GHDL>\bin"
```

## コンパイル実行
シミュレーション用フォルダに移動し、powershellでコンパイルを実行します。

```:powershell
cd <MySimulationFolder>
<GHDL>\libraries\vendors\compile-xilinx-ise.ps1 -All
```

`<MySimulationFolder>\xilinx-ise`内にcfファイルが生成されます。


# 問題点
* VHDL-2008でコンパイルするとstd_logic_misc等が使えないためなのかコンパイルエラーになるものがいくつかあります

# 参考
* [Compile Scripts for Vendor VHDL Libraries](https://github.com/ghdl/ghdl/tree/master/libraries/vendors "Compile Scripts for Vendor VHDL Libraries")
振り返りフレームワーク "サソリ" のご紹介

# はじめに

Twitter上でKPTとか振り返りフレームワークの話題が出てたのでオレオレフレームワークをシェアしてみる

## 話題になってた内容

http://tbpgr.hatenablog.com/entry/2017/12/19/122601
https://twitter.com/matsutakegohan1/status/1135221811019362304

# サソリとは？

Thanks（サンクス）、Sorry （ソーリー）、Request （リクエスト）

の頭文字をとりました
チームとしてのプロジェクト振り返りに関するフレームワークになります

感謝の場と自分が出来なかった事を発表する場です
**愛** にあふれた振り返り手法だと信じています

# Thanks（サンクス）

ナニカに感謝の気持ちを伝えよう

**〜してくれてありがとう**

Thanksには「愛」があるので、自分も相手もほんわかあったかい気持ちに

# Sorry （ソーリー）

自分自身でもっとこのようにすればよかったという反省点を書き出そう

**〜でごめんなさい**

Sorryは課題であり、解決の余地がある。同じこと繰り返さないようにちゃんという。結果としてお互いHappyになるはず。

# Request （リクエスト）

次にナニカにして欲しいことを伝えよう
自分自身のSorry が改善できるように書こう！

**◯◯にXXを次はして欲しいと思います**

# ルール

1. 誰かを責めることはしない
    + 感謝の場と自分が出来なかった事を発表する場です
    + 以下のような発言はしないように
    + **◯◯さんが◯◯な事してごめんなさい**

2. 発言はシンプル、ショート、ストレート　枕詞は添えない
    + 言いにくいことがあったら「妖精さんが言うには〜」って言う
    + 良くしていく活動であることを前提に。
【初心者】CSSだけで画像を丸く表示する

##はじめに
入社してから早3か月が経ちました。自分で書いたHTMLとCSSは、まだまだ初回レビューではチェック項目を全部クリア出来ないのですが(汗)、1つの見せ方でもいろいろな方法があるのだな～と勉強の日々です。今回はその中でも、研修課題の1つにあった「画像を丸く表示する方法」をまとめたいと思います。

##①border-radiusだけでもいいけど、今回は不正解！？
「画像を丸くして赤線で囲み表示する」という課題の原画が正方形に近い四角形で提供されていたので、最初は「borderの角を丸く（border-radius: 50%;）してしまえばそれっぽくなるのでは・・？」と思ったのです。確かにこの方法でも画像は丸くなっているのですが、なぜか見本とちょっと違う。隙間があるというか、borderで設定した赤線の丸の中に画像が入っているだけというか・・・。残念ながら、今回はこれだけではやりたいことが実現出来ていない！ということで、安定のやり直しになりました。

####＜HTML＞
~~~HTML
<!DOCTYPE html>
<html lang="ja">
　<head>
　　<title>Sample</title>
　　<link rel="stylesheet" href="css/index.css">
　</head>
　<body>
　　<img src="photo.png" alt="写真">
　</body>
</html>
~~~
####＜CSS＞
~~~css
img {
    border: 3px solid #ff0000;
    border-radius: 50%;
    width:  180px;
    height: 180px;
}
~~~

##②画像を丸く表示する＝丸く切り取る！
いろいろ調べた結果、どうやら画像を丸く表示したい場合は、画像の一部を丸く切り取っているということが分かりました。しかも、その場合はHTMLのimgタグで画像を指定せず、CSSのbackground-imageを使う必要がありました。

####＜HTML＞
~~~HTML
<!DOCTYPE html>
<html lang="ja">
　<head>
　　<title>Sample</title>
　　<link rel="stylesheet" href="css/index.css">
　</head>
　<body>
　　<p class="circle">表示領域</p>
　</body>
</html>
~~~
####＜CSS＞
~~~css
circle{
    background-image: url(../img/photo_1.png);
    width:  180px;
    height: 180px;
    border: 3px solid #ff0000;
    border-radius: 50%;
    background-size: 200px 200px;
}
~~~

##③丸く切り取る位置も指定
background-imageを使って画像を丸く出来たのですが、見本と比べてみると何かがずれていました。よくよく見てみると赤線の丸の中に納まっている画像がちょっと斜め左上にずれて表示されている・・？今回はちょっと右下にずらしたかったので、CSSにbackground-positionを追加して調整しました。

####＜CSS＞
~~~css
circle{
    background-image: url(../img/photo_1.png);
    width:  180px;
    height: 180px;
    border: 3px solid #ff0000;
    border-radius: 50%;
    background-size: 200px 200px;
    background-position: right bottom;
}
~~~

これで、課題通りの画像を表示することが出来ましたっ！

##反省と補足
「①border-radiusだけでもいいけど、今回は不正解！？」で書いたCSSでも、画像は丸くなって表示されています。今回は原画が正方形に近かったので実装中は気が付かなかったのですが、横長の画像を同じ設定で表示した場合、画像は指定したサイズにギュっと縮んでしまうため、不正解という言葉を使いました。原画が正方形の場合は、この設定だけでも十分かもしれません。

「②画像を丸く表示する＝丸く切り取る！」では、初めてbackground-imageを使用しました。最初は”画像を表示する領域を確保する”ということを理解できておらず、赤丸も画像も表示されないな～と思っていました(汗) 画像を丸くすることとは関係ないですが、background-imageを使用するときは表示領域を確保することを忘れないようにしないといけないですね。

「③丸く切り取る位置も指定」の時は何も表示が変わらないな～と思っていたのですが、表示領域より小さいサイズで表示している画像の場合は、当たり前ながらbackground-positionを設定しても意味がありません。表示する画像のサイズを大きく調整してから、右下部分を切り取ることで今回の研修課題通りの表示にすることが出来ました。

##まとめ
HTMLとCSSの研修だったため、画像そのものを丸く加工すること以外で考える必要がありました。表示領域を確保したうえで丸く見せる。なるほどな！と思った使い方でした。
Ubuntu18.04LTS の Trac にて、ShiftJISエンコードファイルの文字化け表示を直す

# Trac のファイル文字化け修正の記録

## はじめに
Trac のレポジトリブラウザは、１つのプロジェクトにエンコーディングが混在(コミットメッセージが utf-8 で、登録ファイルがShiftJISなど)しているとファイル内容の表示が文字化けすることがあります。これを修正します。
下記参考資料のパッチをそのまま適用しました。

### 参考資料
 * [2007年02月20日20:31 Tracでファイルの文字コードを自動判定](http://blog.livedoor.jp/yamamb/archives/50613027.html)

> Tracはリポジトリブラウザによるファイル表示や添付ファイルの表示の際、
MIMEタイプの"charset="属性による判定
BOMコードによるUnicode判定
の順に判定を行い、 判定不能の場合は設定ファイルの[trac]default_charsetを使用します。
プロジェクト内で文字コードが統一されていれば [trac]default_charsetを適切に設定することで問題無いのですが、 Windows向けとLinux向けのソースが混在するプロジェクトを管理する必要が生じたため、以下のパッチを作成しました。
既存の判定処理で判定不能な場合に追加で以下の判定処理を行います。

> EmacsやVIMのエンコード指定が存在すれば使用する。
(例: "# -*- coding: ENCODING_NAME -*-"あるいは"# vim:fileencoding=ENCODIG_NAME")
chardetモジュール(Universal Encoding Detector)が利用可能であれば、これを用いて判定する。
これでも判定できない場合、[trac]default_charset設定を使用します。

  
## 環境
 - Ubuntu 18.04LTS
 - Trac 1.2

昔はTracのインストールは大変でしたが、今は apt install 一発で済むので楽です.

```shell-session
sudo apt install subversion subversion-tools libapache2-mod-svn
sudo apt install trac libapache2-mod-wsgi
```

## 修正手順
```shell-session
# Tracのパッチ対象を探して、そこへ移動する.
locate trac/mimeview/api.py
cd /usr/lib/python2.7/dist-packages/trac/mimeview/

# バックアップを作成する.
sudo cp -p api.py api.py.orig
sudo cp -p api.pyc api.pyc.orig

# エディタにて手動でパッチ修正する.
#  参考資料のdiffは差分元の内容が古くて前後のコンテキストが一致せず、patch や git apply で扱えなかった. 
sudo vim api.py

# 文字エンコーディング判定ライブラリを入れる(Ubuntu18.04LTSでは最初から入っている)
sudo apt install python-chardet

# 修正結果をコンパイルして、アパッチを再起動する.
sudo python -m py_compile api.py
sudo systemctl restart apache2
```

### 今回の修正差分
次回は、これを ```patch``` に与えて自動でパッチ修正できるはず.

```patch:api.py.patch
diff --git a/api.py b/api.py
index 856ba26..6c1a248 100644
--- a/api.py
+++ b/api.py
@@ -76,6 +76,19 @@ from trac.util import Ranges, content_disposition
 from trac.util.text import exception_to_unicode, to_unicode
 from trac.util.translation import _, tag_

+# --- PATCH START hkuno from http://blog.livedoor.jp/yamamb/archives/50613027.html
+# For charset detection.
+CHARSET_RE = re.compile(r'coding[=:]\s*(\S+)')
+
+try:
+    # Universal Encoding Detector
+    # http://chardet.feedparser.org/
+    import chardet
+    CHARDET_CONFIDENCE_LIMIT = 0.8
+    CHARDET_MAX_SAMPLE = 1000
+except ImportError:
+    pass
+# --- PATCH END

 __all__ = ['Context', 'Mimeview', 'RenderingContext', 'get_mimetype',
            'is_binary', 'detect_unicode', 'content_to_unicode', 'ct_mimetype']
@@ -920,6 +933,16 @@ class Mimeview(Component):
             utf = detect_unicode(content)
             if utf is not None:
                 return utf
+            # --- PATCH START hkuno from http://blog.livedoor.jp/yamamb/archives/50613027.html
+            m = CHARSET_RE.search(content, 0, 200)
+            if m:
+                return m.group(1)
+
+            if 'chardet' in globals():
+                result = chardet.detect(content[:CHARDET_MAX_SAMPLE])
+                if CHARDET_CONFIDENCE_LIMIT < result['confidence']:
+                    return result['encoding']
+            # --- PATCH END
         return self.default_charset

     @property
```
### 終わり
phpinfoの内容をコマンドラインで確認する

phpの設定内容を確認するときに、ドキュメントルートに`phpinfo.php`などのようにファイルを作成してphpinfo()と記述するのは面倒ですし、確認対象が本番環境の時にそのようなファイルを置くことはできません。

コマンドライン上で確認出来、且つファイルに出力して後で確認しやすいようにする方法です。

以下のコマンドで、phpinfo()関数の結果がphpinfo.txtに出力されます。

```
$ php -r 'phpinfo();' > phpinfo.txt
```
BottomSheetDialogFragmentでonBackPressed時の挙動を制御

BottomSheetDialogを継承するのがポイント。

```kotlin
class BottomSheet : BottomSheetDialogFragment() {

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return object: BottomSheetDialog(requireContext(), theme) {
            override fun onBackPressed() {
                // 任意の処理
            }
        }
    }
}
```
【Rails】個人開発のPWAをGoogle Playストアに掲載するときハマったこと

個人開発のWebアプリ**「[まちかどルート](https://machiroute.herokuapp.com/)」**v6.0rc6を**[Google Playストアに掲載した](https://play.google.com/store/apps/details?id=xyz.appmaker.tzozva)**ときのメモです。

# TWA + PWA

[こちらの記事](https://qiita.com/zprodev/items/181c1c8f19bc0beb1183)にもありますが、**PWA(Progressive Web Apps)**として構築したWebアプリならば、**TWA (Trusted Web Activity)**なるものを使用することでGoogle PlayストアにAndroidアプリとして登録できる、というので試してみました。

# PWA2APKを使いました

[こちらの記事](https://webty.jp/staffblog/production/post-1213/)を参考にしました。

# ハマったこと

PWA2APKで作成したAPKファイルをGoogle Play Consoleを通じて登録しましたが、下記2点でハマりました。

## 1. SHA 256のコードを追記

PWA2APKによって作成された`assetlinks.json`というファイルを`https://<domain>/.well-known/assetlinks.json`となるようにアップロードするのですが、そのJSONファイルにGoogle Play Consoleの「アプリの署名」で得られるSHA 256のコードも追記しなければいけないそうです。

[PWA2APK – Publishing PWA Android App on Playstore](https://appmaker.xyz/docs/pwa2apk-publishing-pwa-android-app-on-playstore/)

## 2. ルーティングを設定

`assetlinks.json`というファイルを`https://<domain>/.well-known/assetlinks.json`で外部からアクセスできるよう、Railsの`routes.rb`に追記しなければいけませんでした。言われてみれば当然ですね...。

```ruby:config\routes.rb
  get '.well-known/assetlinks' => "wellknown#assetlinks"
```

それに伴い、controllerのファイルも新規作成します。

```ruby:wellknown_controller.rb
class WellknownController < ApplicationController

    def assetlinks
        render file: '.well-known/assetlinks.json', layout: false, content_type: 'text/json'        
    end

end
```

# あとがき

上記2点をクリアしなくても掲載およびインストールが可能です。ただし、URLバーというかアドレスバーが表示されてしまい、せっかくネイティブアプリのようにフルスクリーン表示するPWAが台無しになってしまいます。

おかげでスッキリ。
いろいろ試行錯誤しましたが、個人開発のWebアプリ(PWA)が無事にGoogle Playストアに掲載されました。
Postgresで実行中のSQLをSTOPする

## postgresユーザーで操作する
``` sql
su - postgres
```

※実行権限によってsu - が使えない場合

## 実行するデータベースを設定する
``` sql
psql [databaseName]
[例]
psql sample_database
```

##SQL実行ログを確認する
``` sql
 SELECT * FROM pg_stat_activity;
```

##実行中のSQLを確認する
``` sql
SELECT pid, query_start, substr(query, 0, 50) FROM pg_stat_activity WHERE state='active' ORDER BY query_start;
```
```result
# SELECT pid, query_start, substr(query, 0, 50) FROM pg_stat_activity WHERE state='active' ORDER BY query_start;
  pid  |         query_start          |                      substr
-------+------------------------------+---------------------------------------------------
 12773 | 2019-06-03 11:36:47.05513+09 | SELECT pid, query_start, substr(query, 0, 50) FRO
(1 行)
```

※pidを確認する

##SQLを止める
``` sql
SELECT pg_cancel_backend([pid]);
[例]
SELECT pg_cancel_backend(12773);

```

※再度実行中SQLを確認する。数秒かかる場合もある
Vue CLI3でBuefyを使う方法

プラグインがあるようなので、記述。

参照先
[vue-cli-plugin-buefy](https://www.npmjs.com/package/vue-cli-plugin-buefy)

1 プロジェクトがない場合（ある場合は２に）

```
$ vue create プロジェクト名
```

2 プラグインのインストール

```
$ cd プロジェクト名
$ vue add buefy
```

3 Sassを使いたい場合

```vue.config.js
// vue.config.js
const fs = require('fs')
 
module.exports = {
  css: {
    loaderOptions: {
      sass: {
        data: fs.readFileSync('src/variables.scss', 'utf-8')
      }
    }
  }
}
```

nuxt.jsで動かしてもよいのですが、SSRが必要じゃないサービスなので、CLI3で十分かなと思っていますので、書いてみました。
Laravelを使おうと思っているので、Vue+Vuex+axios+Larabelとしたいので、これにnuxt.jsまで含めるとちょっとなぁと思ったので、こちらで考えてみました。
「render」についておさらいしよう！

#「render」についておさらいしよう！
Railsでよく出てくるrender。
なんだかよく分からないので、復習してみます。
##1. ビュー内のrenderメソッド
ビュー内でのrenderは、部分テンプレート（partial）を表示するために使用する。
部分テンプレートとは、共通のビューの表示を別ファイルに切り出すことができ、様々なビューから呼び出すことが可能。
GASでGoogleDrive内のファイル・フォルダを一括で共有設定する

#■はじめに
ビジネスシーンにおいて、社内でファイルを共有したいときにファイル・フォルダの共有設定は大変重要になってきます。
案件関連、顧客情報、人事関連などなど…
しかし、大量のファイル・フォルダに対して手作業でそれらの共有設定を行うのは正直なかなかに骨が折れる作業です。

今回はGoogleDriveでファイルの作成と共有設定をするGASを開発する機会があったので、GoogleDriveにおいて大量のファイル・フォルダを一括で細かな共有設定ができるGASについて紹介します。

#■今回紹介するツールイメージ
1. ファイル名、アクセス権限者を1つのスプレッドシート(マスタ)に記載する
2. GASで記載のスプレッドシートを元にテンプレファイルからファイル作成&権限付与をする

今回はマスタとなるシートから読み込んだユーザーのみに共有設定を行う例です。

#■マスタとなるスプレッドシート(ファイル共有設定)

極めて単純なシートですが、
下のようなスプレッドシートを用意して、マスタとしてファイル名と編集権限者を設定したいように記載します。
下記スクリプトでは編集権限者を横に連続して書かなくても読み込むように作っています。

また、Gsuiteでグループを設定していればそのグループで記載してもまとめて共有設定が可能です。

※今回はGsuiteのアカウントでいうメールアドレスの頭(○○@××××××.×××でいうと○○)を編集権限者として記載

![master.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322392/2e53dfab-ac64-c67f-e2fc-10a0e05c03d2.png)


#■スクリプト


```javascript
function makeFilesSetShare() {
  var template = DriveApp.getFileById('<テンプレファイルのID>')
  var fileShareRange = SpreadsheetApp.openById('<ファイル共有設定のID>').getActiveSheet().getDataRange();
  
  //ファイル設定のデータを配列で取得
  var arr = fileShareRange.getValues();
  
  //配列の行数・列数を取得
  var row = fileShareRange.getLastRow();
  var column = fileShareRange.getLastColumn();
  
  var parentFolder = DriveApp.getFolderById('<親フォルダのID>'); //親フォルダ
  
  
  for (var i = 1; i < row; i++){
    var fileName = arr[i][0];
    var removeEditors = parentFolder.getEditors();
    
    var file = parentFolder.getFilesByName(fileName).next();
    
    //ファイル作成
    template.makeCopy(fileName, parentFolder);
    
    
    //権限設定
    //親フォルダの共有者の権限を外す
    for (var j=0; j < removeEditors .length ;j++) {
      file.removeEditor(removeEditors[j]);
    }
    
    //マスタのスプレッドシートで指定したメンバー・グループに権限付与
    var k = 1;
    while (k < column) {
      //空白のセルをスルーしないとエラーになるため
      if (arr[i][k] != '') {
        file.addEditor(arr[i][k]+'@××××××.×××');
      }
      k++;
    }
  }
}
```
#■他にできることなど
##通知をしないで共有設定
上記のスクリプトを動かして、共有設定するとすべてのファイルにおける権限付与者に通知がいきます。
大量のファイルに対して共有設定をする場合、スクリプトを実行した際に一斉に大量の通知がいく可能性があります。


通知がいく理由は、DriveAppクラスで`addEditor`で権限付与しているためです。
通知がいかないようにするには、その他のクラス(SpreadsheetApp、DocumentAppなど)で`addEditor`で権限付与します。

上で記述したスクリプトを以下のように書き換えます。(作成ファイルがスプレッドシートの場合)

```javascript
/**
var file = parentFolder.getFilesByName(fileName).next();
上記の変数定義を下記に変更
*/
var id = parentFolder.getFilesByName(fileName).next().getId();  //DriveAppでIDを取得
var file = SpreadsheetApp.openById(id);                         //SpreadsheetAppに変換
```


##フォルダに共有設定
基本的にはファイルの場合と変わりません。
上で記載したスクリプトで、共有設定するファイル`var file = parentFolder.getFilesByName(fileName).next();`の定義をフォルダの定義に変えるだけになります。
例:`var folder = DriveApp.getFolderById(<対象フォルダのID>);`

ただし、
フォルダはDriveAppクラスでの共有設定になるため、どうしても通知がいくようになってしまいます。

通知なしで権限設定する場合は、Google Apps Scriptとは別のGoogle DriveのAPIで実現可能です。
こちらの記事を参考にしてください。
[Google Apps - 通知メールを飛ばさずにGoogle Driveフォルダに権限追加する方法](https://qiita.com/nurburg/items/7720d031a3adac5a3c34)

#おわりに
GASでここまで細かい権限設定までできるとは思ってませんでした。
社内の様々な業務の工数削減でGASは活躍する気がするので、もっと活用していきたいです。
mongoDBにてデータベースをリネームする

mongoDBのissueサイトにて、データベースのリネーム機能が欲しいというユーザーに対して、MongoDB Product TeamのAsya Kamskyが答えています。
データベースのリネーム機能の実装はmongoDBの仕様上難しいということです。
https://jira.mongodb.org/browse/SERVER-701

そのため、copyDatabaseコマンドで代替します。

mongoDBコンソールに入り、以下のコマンドを実行します。

```
db.copyDatabase('old_name', 'new_name');
use old_name
db.dropDatabase();
```

例えば、fooデータベースを、new_fooにリネームする場合は以下のようにします。

```
db.copyDatabase('foo', 'new_foo');
use foo
db.dropDatabase();
```
copyDatabaseのあと、`show dbs`コマンド（DB一覧表示）でコピー成功を確認すると、より確実です。
CentOS7サーバを構築するためのメモ。

# 概要

CentOSサーバを構築する際の備忘録。必要とあらば随時更新。

# sudo権限を付与する

## rootになる

```
$ su
```

でrootになる。

## visudo


```
# visudo
```

とタイプすると`/etc/sudoers`を編集できる。デフォルトだと


```
## Allow root to run any commands anywhere
root    ALL=(ALL)    ALL
```

と記述されているが、ここに

```
ユーザ名    ALL=(ALL)    ALL
```

と記載することで、そのユーザ名の人にもsudo権限を与えることができる。

# インターネット接続

## ifcfg-eno1の編集

root権限で`/etc/sysconfig/network-scripts/ifcfg-eno1`を編集。`ONBOOT=no`を`ONBOOT=yes`に変更して保存。

## ネットワークデーモンの再起動

```
# service network restart
```

とタイプしてネットワークデーモンを再起動後、適当なインターネットブラウザを開いてググれることを確認。

参考記事: [CentOSを入れたらネットにつながらなかった話](https://qiita.com/burokko/items/bca3790557ea07a0e014)
砂時計形星タワーを印字 Print Stars Tower In Hourglass

# Question
- 下記の砂時計形★タワーを印字する(△はスペース)
    
- Example:

```text:input_5   
        ★★★★★
        △★★★△     
        △△★△△
        △★★★△
        ★★★★★
```
 
```text:input_3 
        ★★★     
        △★△
        ★★★
```

```text:input_9
        ★★★★★★★★★    
        △★★★★★★★△
        △△★★★★★△△
        △△△★★★△△△    
        △△△△★△△△△
        △△△★★★△△△
        △△★★★★★△△
        △★★★★★★★△
        ★★★★★★★★★
```

# Solution

```cpp:solution.cpp
#include <iostream>
#define SKIP 2
using namespace std;

void printStar( int stars ){
    
    for( int i = 0; i < stars; i++ )
        cout << "*";
}

void printSpace( int spaces ){
    
    for( int i = 0; i < spaces; i++ )
        cout << " ";
}

int main(void){

    int times;
    cout << "Input an ODD number to print star hourglass:\n";
    cin >> times;

    if( 0 == times % 2 ){
        cout << "Please input an ODD number!" << endl;
        return 0;
    }

    int stars, spaces, revPos;
    
    // reverse point is the most stars of lines
    revPos = times / 2;
    
    for( int i = 0; i < times; i++ ){

        // count stars and spaces in this line
        if( i <= revPos ){
            stars = times - i * SKIP;
            spaces = times - stars;
        }else{
            stars = times - ( ( times - ( i + 1 ) ) * SKIP );
            spaces = times - stars;
        }
        
        // stars always start from the center, insert spaces in the front and tail of stars
        printSpace(spaces/2);
        printStar(stars);
        printSpace(spaces/2); //this line can be commented out
        
        // change line
        cout << endl;
    }
}

```
Firestoreのドキュメントのフィールドに画像をBLOBで保存

最近、FirebaseのCloudFirestoreを勉強中のエンジニアです。
Firestoreの保存形式にバイナリーBLOBが合ったので気になって試してみました。
CloudStorageを使うまでもない小さなサムネイルを保存するときに使うのかなと。


```js
const fs = require("fs");
const firebase = require("firebase");

// 保存先のドキュメントの取得
const userRef = await db.doc('/users/' + UID);

// 保存する画像の読み込み
const icon = fs.readFileSync("icon.png");

// blobに変換
const blob = firebase.firestore.Blob.fromUint8Array(icon);
const img = {img : blob};
// firestoreに保存
await userRef.set(img, { merge: true }).catch(error => console.log(error));

// 下記は保存したデータの取得
const userSnapshot = await userRef.get();
const userImg = userSnapshot.data()['img'];
console.log(userImg.toBase64());
```

## 注意するべき点
Firestoreには1ドキュメント 1MiBの制限があるので、保存する画像のサイズは注意が必要です。
Splunkのstreamstatsを使って移動平均線(trendline)を描画

移動平均線をグラフにマップしたい
--
- streamstatsについては、前回eventstatsとの比較を元に[紹介](https://qiita.com/odorusatoshi/items/790a519f6e017b6ae2a1)しました。
- 今回は、[tutorialdata](https://docs.splunk.com/Documentation/Splunk/7.2.6/SearchTutorial/Systemrequirements#Download_the_tutorial_data_files)のWebアクセスログを対象にしてStatusCodeの件数集計とWebアクセス全体件数の移動平均線（trednline）を描画したいと思います
- あわせてstreamstatsと似ていることができるtrendlineコマンドについても触れます


streamstatsを使って7時間毎の移動平均線を描画
---
- 使用するSPL
    - timechart
    - addtotals (←ポイント)
    - streamstats
    - fields

```
index="tutorial" sourcetype=access_combined_wcookie
|timechart span=1h count by status
|addtotals fieldname=sum
|streamstats window=7 avg(sum) as Trend
|fields - sum
```
- 検索結果イメージ
![スクリーンショット 2019-06-03 10.07.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185759/d533790a-d342-5508-1b59-fd5732b8fa55.png)

- ポイント
    - timechartを使って1時間間隔でstatusコードを集計
    - **addtotalsを使ってsumフィールドを作成し、時間毎のstatus合計値を算出**
    - streamstatsを使って、過去7イベント分のsum値を対象に移動平均を計算しTrendフィールドを作成
    - グラフ化に不要なフィールド(sum)を除外


trendlineを使って7時間毎の移動平均線を描画
---
- 使用するSPL
    - timechart
    - addtotals
    - **trendline** ~~streamstats~~  (←ポイント)
    - fields
   
```
index="tutorial" sourcetype=access_combined_wcookie
|timechart span=1h count by status
|addtotals fieldname=sum
|trendline sma7(sum) as Trend
|fields - sum
```

- 検索結果イメージ
![スクリーンショット 2019-06-03 10.20.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185759/7858d09a-c30d-e2bc-d955-9598087ee5c0.png)


- ポイント
    - timechartを使って1時間間隔でstatusコードを集計
    - addtotalsを使ってsumフィールドを作成し、時間毎のstatus合計値を算出
    - **trendlineを使って、過去7イベント分のsum値を対象に移動平均を計算しTrendフィールドを作成**
    - グラフ化に不要なフィールド(sum)を除外


それぞれの違いを確認
---
- streamstatsとtrendlineどちらでも移動平均線は導き出せる
- 違いは？
    - 下記スクリーンショット２つを見比べてみます。上がstreamstats、下がtrendlineの結果
     <img width="1264" alt="スクリーンショット 2019-06-03 10.26.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185759/1f9e13a9-a24f-6388-48eb-59d21894b4cd.png">
    - streamstatsは7件分のデータがなくても、過去2件、過去3件・・と存在するデータ分を元に移動平均を自動的に計算して値を生成していることがわかります。
    - trendlineはデータ対象が7件揃っている場合にのみ、移動平均を計算しています
    - もしかすると、それぞれのSPLのオプションでいろいろとチューニングができるかもしれませんが、シンプルに使うとこのような差がでます。

####実はtrendlineコマンドには、複数のtrendlineを一度に計算し描画する事ができる

```
index="tutorial" sourcetype=access_combined_wcookie
|timechart span=1h count as sum
|trendline sma7(sum) as 7h_Trend sma24(sum) as 24h_Trend sma72(sum) as 3d_Trend
```

- 検索結果イメージ
![スクリーンショット 2019-06-03 10.41.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185759/c362c4c3-0cbc-0211-e366-2fea3370e941.png)

- ポイント
    - 下記trendlineコマンド1行の中で、7時間、24時間、3日間の移動平均を計算
    - timechartではこれができない。一つのwindow幅しか指定できない。

>|trendline sma7(sum) as 7h_Trend sma24(sum) as 24h_Trend sma72(sum) as 3d_Trend

まとめ
---
- シンプルに過去7時間の移動平均を求めるならstreamstatsコマンド
- 複数の移動平均を描画したいならtrendlineコマンド （FX、株トレーダー向け？）
Linux screenコマンド 簡単メモ

minecraftのサーバをscreenでバッググラウンド起動しているがちょくちょく停止するので、
物覚えが悪く再度起動するたびにscreenのコマンドをググっているのでメモ代わりに手順を残す。

# screen 基礎

|用語|概要|
|:--|:--|
|セッション|screenで作るバッググラウンドプロセスの単位|
|アタッチ|screenで作ったバッググラウンドプロセスに入ること|
|デタッチ|screenで作ったバッググラウンドプロセスから出ること|

# まずはscreenの既存のセッションがあるか確認

存在する場合はセッションの情報が出力される。
※'.pts'の前の数字がセッションID

```
# screen -ls
There are screens on:
        18.pts-1.871083537b16   (03/21/2019 09:12:31)   (Attached)
        259.pts-1.871083537b16  (05/21/2018 05:56:33)   (Dead ???)
```

# セッションにアタッチする(バッググラウンドプロセスに入る)

> screen -r [ID]

例)

```
screen -r 18
```

※セッションが1つなら以下でもOK

```
screen -r
```

# セッションからデタッチする(バッググラウンドプロセスから抜ける)

> Ctrl + a してから d

# 死んだセッションを掃除する

```
screen -wipe
```
.

#職業訓練校とは

職業訓練校とは、ハローワークからの紹介で通える、就職に必要な技術を学べる学校のような施設です。
立ち位置的には専門学校のような場所ですが、基本的には無料、有っても月１万円程度と格安の料金で通えることが最大の違いであり、訓練校を選ぶインセンティブになります。
私が通っているのは、月1万円でIT系エンジニアに必要な知識を身につけようという（特定を避けるため限りなくフワっとした表現をお許しください）コースです。
なお、立地はやや東京に近い郊外になります。

##入校に至るまで

文系大学を留年して卒業→就活失敗→無職→面接で喋ることが無さ過ぎて気まずいのでいよいよ目に見えるスキルを付けなければという思いに駆られる→入校
といったルートで入る運びになりました。
一般的には、専門学校の代わりに来る新高卒や、失業保険を受けながら転職準備のために来る元社会人の方が多いようです。
また、訓練校ってお値段が安いぶん正直ピンキリでアカンとこは本当アカンという話も聞いていたのですが、かなり大規模で近所でも有名な、また家族が卒業して建築士として就職していることもありここなら大丈夫かな、と思った所もあります。

##授業がヤバい

結論から言うとタイトルの通り、かなり後悔しています..................................................
まず入校して最初に行うのが「情報基礎」のような授業なのですが、これは何と本職員さんたちは事務作業で忙しいということでパートタイムの講師さんが行うことになり、1日90分×4コマ、ひたすら購入させられたテキストを各自開いたうえ中央のモニターにも同じものを映し、延々音読するだけ。
「プロトコル」「ビット演算」といった初めて聞く単語の応酬が何の説明も無いまま頭の中をツルーっと通過していくなか、気の遠くなるような思いをしました。この時点で授業中に寝る生徒が多数（私は授業中寝れないたちなので助かり？ました）
それが一通り終わると次はプログラミング言語ということでJavaの授業に入ったんですが、週五日・一か月ほどかけてif・while・forなど初歩的なものをなぞったあと、「メソッドを作ってみよう」というところで一旦終わってしまいました。
自分は今のところ他のプログラミング講座なども体験していませんし比較ではできませんがおそらく猛ッッ烈に進みが遅いことはなんとなく分かります。なんとなくですが

##周囲の意識がヤバい

基本的に高校を卒業してそのまま来たり、またなんとなく失業保険や給付金を貰うために来ているために、基本的に物凄く意識が低いです（これは各所によってもちろん差はある事と思います）。
自分はもともと「意識高い系」を割とヘラヘラして見てきた側で今でもそのマインドは十分根付いているのですが、そんな自分でもかなりの危機感・違和感を感じます。
こんな授業内容なのでyoutubeを見たりゲームをする生徒もいますがそれでも講師も別に注意しないし、座っていてくれればいい、座って適当にさせてくれればいい、という宜しくない意味で利害が一致してしまっています。
まあこれはここ個別の問題である可能性もあり、愚痴っぽくなってしまうのでここまでにしておきます（大変失礼しました）

##就職先がヤバい

そして、ハローワーク直系の施設なので頻繁に就職指導が入るのですが、これもかなりヤバいと感じています。
8～9割が派遣業務である上、基本給が11～13万のものがザラです（！ここは都心に近い郊外です）。
入校パンフレットには「就職率98％！」等と謳われていましたが、おそらく技術も要らず誰でもいいような人材を求めている企業に無理やり押し込んでいるのだな、という印象を受けてしまいました。


#危機感

どうやら、このままここでダラダラしていたらヤバそう、と身をもって日々感じています。
ということで、訓練校での学習内容とは別に、独学でJavascript、HTML/CSSの勉強を始めました（主に授業中に励んでいます）。
プログラミング自体に興味は持てたので、本当は今すぐ辞めてTechcamp等に通いたいという気持ちも強いのですが、迷惑をかけた家族に対するメンツ等もあり今のところ通うという選択をとっています。
単なる愚痴のような内容で失礼しました。これから通われるという方にとって助けになればと思います（ポジティブなことも書きたいと思いましたが現状あまり思いつきませんでした）。
もし読んでくださってる方がいらっしゃいましたら、アドバイス等も頂けたら幸甚に存じます。
御清読ありがとうございました。
【Mac】エイリアス（ターミナルコマンドのショートカット）の設定

* ホームに移動

```
➜  ~ cd $HOME
```

* .bashrcファイルをvimで編集（ファイルが存在しなければ新規作成）

```
➜  ~ vim .bashrc
```

* エイリアスコマンドを追記し、保存して終了  
ailias エイリアス名='設定したい内容'
例）

```
alias cdlswb='cd ~/work/xxxx/ls/web'
alias vimalas='vim ~/.bashrc'
```

* .bash_profileファイルをvim編集

```
➜  ~ vim .bash_profile
```

* 下記を追記し、保存して終了

```
source .bashrc
```

* （再ログインでも反映されるが）追加したエイリアスを即時に反映する

```
➜  ~ source .bashrc
```
Db2のインデックス情報

#Db2のインデックス情報


###データベース内全てのテーブルのインデックス情報
```
SELECT TABNAME,INDNAME,COLNAMES FROM SYSCAT.INDEXES 
```

これでデータベース内の全てのインデックスの状況がみれる。

###テーブル指定でのインデックス情報
```
SELECT TABNAME,INDNAME,COLNAMES FROM SYSCAT.INDEXES WHERE TABNAME = 'TABLE_NAME'
```

テーブル名は大文字で格納されているので大文字で指定する。
「PythonとKerasによるディープラーニング」のリスト7-1

これは間違いではないのか！？という部分があったので載せておきます。
僕が間違っている場合は教えていただきたいです。

「PythonとKerasによるディープラーニング」のリスト7-1(P.251)

修正前

```python:qiita.py
text_input = Input(shape=(None, ), dtype="int32", name="text")
embedded_text = layers.Embedding(text_vocabulary_size)(text_input, 64)
encode_text = layers.LSTM(32)(embedded_text)
```

修正後

```python:qiita.py
text_input = Input(shape=(None, ), dtype="int32", name="text")
embedded_text = layers.Embedding(text_vocabulary_size, 64)(text_input)
encode_text = layers.LSTM(32)(embedded_text)
```
plunkerでsimcirjs その9

#概要

plunkerでsimcirjsやってみた。
式からjson作ってみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/671745ae-5932-25ad-d81c-6d7866f9dd76.png)

#サンプルコード

```
var c0 = new J(8);
c0.in(0, 2);
c0.wire(3, 5);
c0.xor(1, 2, 3);
c0.and(1, 2, 4);
c0.xor(0, 3, 7);
c0.and(0, 3, 5);
c0.or(4, 5, 6);
c0.out(6, 7);
c0.disp('koko');
```

#結果

```
{"width":600,"height":600,"showToolbox":false,"toolbox":[],"devices":[{"type":"In","id":"dev0","x":40,"y":40,"label":"In"},{"type":"In","id":"dev1","x":40,"y":90,"label":"In"},{"type":"In","id":"dev2","x":40,"y":140,"label":"In"},{"type":"XOR","id":"dev3","x":200,"y":40,"label":"XOR"},{"type":"AND","id":"dev4","x":200,"y":90,"label":"AND"},{"type":"XOR","id":"dev5","x":200,"y":140,"label":"XOR"},{"type":"AND","id":"dev6","x":200,"y":190,"label":"AND"},{"type":"OR","id":"dev7","x":200,"y":240,"label":"OR"},{"type":"Out","id":"dev8","x":400,"y":40,"label":"Out"},{"type":"Out","id":"dev9","x":400,"y":90,"label":"Out"}],"connectors":[{"from":"dev3.in0","to":"dev1.out0"},{"from":"dev3.in1","to":"dev2.out0"},{"from":"dev4.in0","to":"dev1.out0"},{"from":"dev4.in1","to":"dev2.out0"},{"from":"dev5.in0","to":"dev0.out0"},{"from":"dev5.in1","to":"dev3.out0"},{"from":"dev6.in0","to":"dev0.out0"},{"from":"dev6.in1","to":"dev3.out0"},{"from":"dev7.in0","to":"dev4.out0"},{"from":"dev7.in1","to":"dev6.out0"},{"from":"dev8.in0","to":"dev7.out0"},{"from":"dev9.in0","to":"dev5.out0"}]}
```
#成果物

https://embed.plnkr.co/JLB0ZwQ73TRHbL6Iw9VI/

以上。
文字列型

##NO PAIN NO GAINの出力
```go
func main() {
	fmt.Println("NO PAIN NO GAIN")
	fmt.Println("NO PAIN " + "NO GAIN")
}
```
##0番目の文字列を取得するには
```go
func main() {
	fmt.Println("NO PAIN NO GAIN"[0])
	//アスキーコードが出て0番目の文字は取得できないので、stringでキャストしてやる
	fmt.Println(string("NO PAIN NO GAIN"[15]))
	//ちなみに[2]だと空文字が出力される。[15]だとエラー:invalid string index 15 (out of bounds for 15-byte string)
}
```
##文字の置き換え(NOをNOPEにする)
```go
func main() {
	var s string = "NO PAIN NO GAIN"
	//s[1] = "OPE" とやるとエラー
	fmt.Println(strings.Replace(s, "O", "OPE", 1))
	fmt.Println(s)
	//strings.Replaceではvar sをコピーしてそれを置き換えて出力してるだけなので、Println(s)すると何もかわってない。
	//(パッケージ名がstringsなのでstringと間違わないように)
	//元のvar sを書き換えるには下記のように

	s = strings.Replace(s, "O", "OPE", 2)
	fmt.Println(s)
}
```
##該当する文字列があるか調べる
```go
var s string = "NO PAIN NO GAIN"
func main(){
	fmt.Println(strings.Contains(s, "NO"))
	//Containsは該当の文字列が含まれてるか調べてtrueかfalseを返す
}
```
##リテラル
```go
func main(){
	//実際に記述したように文字列を表示させたいときの書き方。バッククオートで囲う。
	fmt.Println(`hoge
	hoge
	hoge

	hoge`)

	//特殊文字を文字列として表示させたいとき。直前にバックスラッシュ置くか、バッククオートで囲う。
	fmt.Println("\"")
	fmt.Println(`"`)
}

```
>【参考】
現役シリコンバレーエンジニアが教えるGo入門(https://www.udemy.com/share/100BhMB0obeFpbTX4=/)
analytics.js から gtag.js に移行

#analytics.js から gtag.js に移行

analytics.js から gtag.js へ移行することで google optimize の導入を簡単に済ませたい

今まで使用していた analytics.js

```analytics.js
<script>
function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
  ga('create', 'TRACKING_ID', 'auto', {'useAmpClientId': true});
  ga('set', 'dimension1', 'DIMENSION1');
  ga('set', 'userId', 'USERID');
  ga('set', 'dimension2', 'DIMENSION2');
</script>
```
カスタムディメンションを２つ, また userid を導入している。

新しく導入した gtag.js

```gtag.js
<script async src="https://www.googletagmanager.com/gtag/js?id=TRACKING_ID"></script>
<script async src="https://www.googletagmanager.com/gtag/js?id=TRACKING_ID"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('set', 'dimension1', 'DIMENSION1');
  gtag('set', 'user_id', 'USERID');
  gtag('set', 'dimension2', 'DIMENSION2');
  gtag('config', 'TRACKING_ID', {
       'optimize_id': 'OPTIMIZE_TRACKING_ID>'
      });
</script>
```

`ga()` で渡していたそれぞれの値は gtag で渡すように修正
`gtag('config')` で optimize_id として tracking_id を入れることで簡単に google optimize を導入することができた。


#参考資料

新しいGA「gtag.js」を使うとGoogle Optimize実践まで超簡単だった
https://qiita.com/kent_ear/items/04304753eb1f8c972b54
pandasでcsvを読み込む時に「OSError: Initializing from file failed」が出る

# はじめに
pythonのpandasでダウンロードしてきたcsvファイルを読み込むことって結構あると思うのですが、
そんな時に表題のエラーが発生する時があります。
何故か毎回忘れてしまうので、戒めとして書きます。

ちなみに、pandasのバージョンが古い場合、日本語がファイルパスに含まれていると同様のエラーが発生するようです。
自分のパスには日本語が含まれていませんでした。

※pandasのバージョンが古く、ファイル名に日本語が含まれている場合は、以下の記事が大変わかりやすく書かれております。 
 https://qiita.com/aira002/items/ffeb750569b6bc42d799

# 環境

### pandas: 
0.24.2

### python:
3.6.8 |Anaconda, Inc.| (default, Dec 29 2018, 19:04:46) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]

# 結論
パーミッションが不適切であるかと思います。
必要な権限を与えてください。

```bash
$ ls -l | grep df
----------  1 user  user    4849711  5 10 18:00 df.csv

$ chmod 600 df.csv
$ ls -l | grep df
-rw-------@ 1 user  user    4849711  5 10 18:00 df.csv
```

何故か毎回このエラーを出してしまう。。。