OmniAICreator/Qiita-1.07M huggingface dataset:
iOS13のDark Modeにつまずいた

# はじめに
iOSアプリ作成初学者の方が下記のようにHello worldをやったとします。

1. Xcodeでプロジェクトを作成
2. StoryboardのViewControllerにUILabelを設置
3. シミュレーターで起動

やった表示できた！！よし実機でも見てみよう！！

あれっ！？UILabelが・・・消えた・・・!

それ、Dark Modeのせいかもしれもません。

# Dark Modeの対応
私が担当していたアプリは今回予算や時間の問題でDark Modeの対応はなくなりましたが何も対応しなくていいわけではありません。何もしないと冒頭のようなことが起こりえます。

これはUIViewの背景色がwhite、UILabelの文字色がdefaultの時に起こります。

ダークモードにするとUIViewの背景色はそのままwhiteで表示され、UILabelの文字色は白っぽくなり見事に背景と同化してUILabelが見えなくなります。

## Light Mode専用にする
Info.plistに下記を追記してDark Mode非対応にしました。

```
<key>UIUserInterfaceStyle</key>
<string>Light</string>
```

これで完了と思いきや思わぬ不具合が！？

## Status Barを設定する
上記の対応で全画面対応できたと思ったのですが、ダークモードの時にステータスバーが白っぽくなって見えにくくなるという現象に遭遇しました。

今手元では再現しないのですが、とりあえずInfo.plistに下記を追記して対応しました。

```
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
```

（たしかXcode11.1だったような気がするんですが...）

Flutterで同じ現象に遭遇している方がいらっしゃいました。

[【Flutter編】ダークモードをONにすると status barが白くなる件 について](https://toconakis.tech/darkmode-avoidance-flutter/)

# その他の現象
その他Dark Modeの影響で起こる現象についてもメモしておきます。

* UISegmentedControlのTintColor設定でバグる！？  
[20190920 iOS 13 対応ではまった話](https://speakerdeck.com/itok/20190920-ios-13-dui-ying-dehamatutahua?slide=13)これの12枚目くらい
* MacのダークモードでAssetがバグる！？  
[ダークモード対応で今注意すべきこと](https://qiita.com/tattn/items/c56b15ed8d1cea26a955)

私は今回Dark Mode対応しなかったので遭遇しませんでしたが、上記のような現象もあるようです。

# Dark Modeの確認
シミュレータで確認する場合はEnvironment Overridesが便利。

<img width="300" alt="Environment_Overrides" src="https://user-images.githubusercontent.com/34936885/69808745-9e7b5d00-122b-11ea-87c3-2260ee0cce67.png">

わざわざ設定アプリで変更しなくても上記のようにLightとDarkを切り替えることができます。（他にもアクセシビリティ関連のものが切り替えれるようです。）

# さいごに
ついに登場したDark Mode！！嬉しいことですが、ちゃんと対応しようと思うとなかなかしんどそうです...

現在は対応必須ではないですが、後々必須になるかもとの噂もあるそうです。
[公式のドキュメント](https://developer.apple.com/documentation/appkit/supporting_dark_mode_in_your_interface/choosing_a_specific_interface_style_for_your_ios_app)にも下記のような記載があります。

>Important
>
>Supporting Dark Mode is strongly encouraged. Use the UIUserInterfaceStyle key to opt 
>out only temporarily while you work on improvements to your app's Dark Mode support.


余裕があるうちにちょこちょこ対応していった方が良さそうです:sunglasses::sunglasses::sunglasses:
JavaScriptの基本　1

#はじめに

この記事は、2019/11/1からプログラミング学習を始めた学生がプロのプログラマーになるまでのアウトプットする為の書き込みの場である。

#JavaScript
DOMとはDocument Object Model(ドキュメントオブジェクトモデル)

1. DOMツリーからノードを取得する
2. JavaScriptでやりたい処理を書く
3. イベント発火でHTML側で動かす

##JavaScript書き方
- document.getElementById("id名");
 - マッチするidを持つノードを取得することができます。
-  document.getElementsByClassName("class名");
 - クラス名とマッチするデータを取得することができます。
- document.querySelector("セレクタ名");
 - HTML上から、引数で指定したセレクタに合致するもののうち一番最初に見つかった要素1つを取得します。
 - DOMの取得とは、querySelectorメソッドなどを使用して、HTML要素をノードとして取得することです。
-  addEventListener
 - あるノードオブジェクトに対して、イベントリスナを追加するメソッドです。
- innerHTML
 - HTML要素の中身を書き換えることができます。
- classList.add 
 - クラスが追加されるようにclassList.addを利用します。
- classList.remove
 -  クラスを削除するclassList.removeを利用します。
- Array.prototype.slice.call()
 - 引数にとったオブジェクトを配列に変換してくれます。
- forEach()
 - 配列に対してよく使われる繰り返し処理です。
- indexOf()
 - 配列に対してだけ使い、DOMを引数にとって一致した要素番号を戻します。

##今日の感想　明日から
今日は、インプットに集中した結果、JavaScriptの基礎、jQueryの基礎を学んだ。
アウトプットについては、基礎的な事ができるまでこのまま毎日投稿するが、簡単で端的にアウトプットしていこうと思います。

##終わりに

もっとこうした方が良いよなどご指摘頂けると幸いです
Android Navigation Componentによる画面遷移時のToolbar

# はじめに
この記事ではNavigation Componentの基本的な使い方は記載していません。
Navigation Componentを使った画面遷移時のToolbarの処理に着目しています。

## Activityが持つViewの処理をActivityに書く
Toolbarを表示する際、ほとんどの場合ホストとなるActivityがToolbarを持ちます。
その際、ゲストのFragmentでToolbarに関する処理を書くと

```Kotlin
val toolbar = view.findViewById<Toolbar>(R.id.toolbar)
requireActivity().setSupportActionBar(toolbar)
```
となりますが、あまり書きたくないです。
Toolbarに限らずFloatingActionButtonなど、Activityが持つViewに関する処理の変更はFragmentに書かずに極力Activityに書き、正しく役割分担することにより保守性を高めたいです。

## Navigation Componentによる画面遷移時も同様
Navigation Componentを使う場合に作成するActivityとFragmentも同様に正しく役割分担させたいです。
この記事ではNavigation Componentによる画面遷移時の、Activityが持つToolbarの処理に着目し、Activityに処理を書いています。
以下の項目について記載しています。

- FragmentによってToolbarの処理を分岐
- Fragment間の画面遷移時にToolbarに関するViewを変更

## 各種バージョン
コードを読みやすくするために[RxBinding](https://github.com/JakeWharton/RxBinding)を使っています。

- Kotlin 1.3.60
- Navigation Component 2.2.0-rc02
- RxBinding 3.1.0

# FragmentによってToolbarの処理を分岐
Navigation Componentを使っているActivityに、表示しているFragmentによってToolbarの戻るボタン押下時の処理を分岐させた例です。
現在のDestinationのID(navigationレイアウトのfragmentのID)に応じて処理を分岐させています。

```Kotlin:MainActivity.kt
binding.toolbar
    .navigationClicks()
    .filter { navController.currentDestination != null }
    .subscribe {
        when (navController.currentDestination!!.id) {
            R.id.firstFragment -> finish()
            R.id.secondFragment -> navController.navigate(
                SecondFragmentDirections.secondToFirst()
            )
        }
    }
```
現在のDestinationがFirstFragmentの場合、Activityを終了(finish())します。
現在のDestinationがSecondFragmentの場合、FirstFragmentに遷移します。

# Fragment間の画面遷移時にToolbarに関するViewを変更
NavControllerにはaddOnDestinationChangedListenerというDestinationの変更に関するListenerがあります。
これを利用し画面遷移時にToolbarにあるButtonのvisibilityを変更しています。

```Kotlin:MainActivity.kt
navController.addOnDestinationChangedListener { _, destination, _ ->
    when (destination.id) {
        R.id.firstFragment -> binding.toolbarButton.visibility = View.GONE
        R.id.secondFragment -> binding.toolbarButton.visibility = View.VISIBLE
    }
}
```
scss import使い方

##importの使い方について

importとは作業ファイルから別のファイルを読み込む際に使用する

変数back-colorを定義しているファイルを呼び出したい時

```scss
//ファイル名　_variable.scss
$back-color: #ffffff;
```

変数$back-colorを呼び出す

```scss
//ファイル名　stylesheet.scss
@import 'variable'; //_（アンダーバー）と拡張子は省略可能

.top-page{
  background-color:$back-color;
}
```
これで使えるようになる
importファイルは名前のファイル名の先頭には**「_（アンダーバー）」**をつける必要がある
NoSQLについて調べたこと

#NoSQLとは
- PostgreSQLやMySQLなどの[RDB](https://qiita.com/selftalk______/items/1a1449789f54830ffbc0)では対処しづらいようなビッグデータにも対応すべく生み出された技術
- SQLを使用しない
- 代表例はGoogleのBigTable,アマゾンのAmazon DynamoDBなどがある

## RDBとNoSQLの違い
### RDBは
- 機能が少ない
- データの整合性がゆるい
- 結果整合性で良いと言う考え
- JOIN(結合）が通jぷではサポートされていない
- 大量のデータを素早く処理することを優先している

### CAP定理
- 分散型データベースシステムに置ける三大要件として以下３点が存在する
- この３つの売り、最大2つしか満たすことができないというのがCAP定理

1. Consistency(整合性)・・・常に同一のデータを参照する
2. Availability(可用性)・・・常に読み出しと書き込みができる
3. Partition Tolerance(分断耐性)・・・ネットワークが分断されても間違った結果を引き起こさない

## NoSQLに期待すること
- 一台のサーバーには収容できないほどの膨大なデータを扱う
- データを複数のサーバに分割して割り当てる
- 高価なハードウェアがなく安価な汎用ハードウェアの上で稼働する
- データに紛失がなく、データは安全な状態に格納されている
- システム全体としては、いつでも使える状況にある
- 障害が発生しても短時間で復旧できる
- リアルタイムに近い応答性能を備えている
- 高速なデータベースチューニングの技術を必要としない


## NoSQLのデータモデル
- キーバリュー型
 - テーブルや関係性を定義せず、キーとバリューという組み合わせからなるシンプルなデータモデル
 - スケールアウトに最適
- カラム指向型
    - 上記のキーバリュー型に絡むの概念を持たせたデータモデル
    - 行に付与されたキーが複数のカラムを持つことができる
    - カラム数はRDBのように固定ではなく、動的に追加していくことができる
    - 他の行には存在しない絡むを持つ行を作ることができる
- ドキュメント指向型
    - [JSON](https://qiita.com/selftalk______/items/0ef7eb744d1a6952e8ae)やXML形式で記述されたドキュメントの形でデータを管理することができる 


[【超入門】RDBとNoSQLの違いに着目！NoSQLに求めるものとは？](http://tech-blog.rakus.co.jp/entry/20180919/nosql/bigdata#NoSQL%E3%81%A8%E3%81%AF)
JSONについて調べたこと

## JSON
- JavaScript Object Notation
- 軽量のデータ交換フォーマット
- 誰が書いてもわかるようにするため
- 機会が判別できるようにするため
- XMLなどと同様のテキストベースNOデータフォーマット
- XMLTO比べて完結に構造化されたデータを記述できる
- JavaScriptだけではなく、Java,PHP,Ruby,Pythonなど、様々は言語感のデータ交換、特にAjaxやREST APIなどで使用される

### XMLとJSONを私がみた印象
- XML・・・書き方がHTMLっぽい
- JSON・・・書き方がcssっぽい

~~（この記事を何年後かに見たらアホ丸出しで死にたくなるだろうなぁ）~~

####JSON

```JSON
{
    "user": "太郎",
    "age": 23,
    "gender": "男"
}
```

こんな感じでJSONはかくらしい

- 一つのデータには左に名前をつけて、右にデータをかく
- "user"(左)・・・key
- "太郎"(右)・・・value
- keyとvalueが一つのセットとなって扱われる概念を***KVS(Key Value Store)***という




追加で調べたことあればまた書きます！

[JSONの形式を完全理解して読み書きできるようになるための記事](https://www.sejuku.net/blog/80617)

[JSON入門](http://www.tohoho-web.com/ex/json.html)
portmapのツールでポート開放ができなかった話

#ポート開放って？
　まず、ポート開放ってなんだろうというお話ですがぐぐったらめちゃんこヒットするので完結に説明すると<b>ルーターとサーバー(自分のPC)を繋ぐトンネルを作る</b>ことです。
トンネルができてしまえば、トンネルの名前(ポート番号)を指定すればその出口(自分のPC)にいけちゃうんです。
今回は、そのポート開放を行うときにハマった話です。

#マイクラでサーバーを立てたい！
　ふと、そんなことを思うときありますよね。
いまどきYoutubeやブログなどで紹介されているので誰でも簡単にマルチプレイは可能ですよね？
ただそのとき必ず必要となるのが、portmapというツールを使ったポート開放です。
さきほども書きましたが、マイクラで自分のワールドに友達を呼ぶということは自分のPCに友達が入ってこれるようなトンネルを用意するということになります。

つまり、portmapを使ったポート開放ができればよいのですが....
私はできませんでした！！泣

"ルータとの互換性がない"とでてしまったのでルーター側の問題かなと疑いルーターの設定画面開きながらぐぐっていると、なんとIPv6だとポート開放ができないそうで....

さらに、デフォルトポート(webページだと80番、sshは22番、マイクラだと25565番、etc...)だと開放できないみたいです。セキュリティの問題かな？なので可能なポートを指定しましょう。

なので`192.168.1.1`ではなく、`192.168.1.1:8888/t`でIPv4設定に入り、ポートを開放しましょう。
<img width="791" alt="スクリーンショット 2019-11-28 21.50.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191249/114af0e2-5a00-342c-ad45-647e41dea112.png">
<img width="1260" alt="スクリーンショット 2019-11-28 21.50.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191249/77db68ca-7655-d4c5-2cf2-a8e2cd4cd1fc.png">

そのあとは、一般的なやり方通りを行いますがポートが25565(デフォルト)ではないので、
`server.properties`ファイルの1行を書き換えましょう。xxxxは開放したポート番号です。

```
server-port=xxxx
```


そのあとは、ワールド作成時と友達がワールドアドレスを指定する際に末尾に
`:xxxx`をつけるだけで完了です！

#まとめ
今回は、IPv6プラスの場合のポート開放のやり方をマイクラサーバーを例にまとめました。
Ubuntu の Desktop 環境を Docker で

# 本日は


- [Dockerを導入してGUI操作可能なLinux(Ubuntu)コンテナを作成する](https://qiita.com/ryoya-s/items/ee1daf9cab18c100c990)

を参考に自分の環境でも再現したよ〜報告を書きます．Ubuntuさん基本的にターミナルベースでしか使わないので応用はとくに考えてないのですが・・・



# 環境

ホスト：macOS Catalina 
Docker: Docker version 19.03.5, build 633a0ea

# Dockerfile

```Dockerfile
FROM ubuntu:16.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
    ubuntu-desktop \
    samba-common-bin \
    x11-apps \
    sudo

ARG uid=1000
ARG gid=1000
RUN groupadd -g ${uid} developer && \
    useradd -u ${gid} -g developer -G sudo -r developer && \
    mkdir -p /home/developer/.config/nautilus &&\
    chown ${uid}:${gid} -R /home/developer && \
    mkdir -p /var/lib/samba/usershares

RUN echo 'Defaults visiblepw'             >> /etc/sudoers
RUN echo 'developer ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

# set locale to initialize terminal property
RUN locale-gen en_US.UTF-8  
ENV LANG en_US.UTF-8  
ENV LANGUAGE en_US:en  
ENV LC_ALL en_US.UTF-8

USER developer
WORKDIR /home/developer
```

# 使い方

下記のようなシェルスクリプトを作っておきます．

```init.sh
docker build -t udesk .
xhost + 127.0.0.1
HOSTDISPLAY=host.docker.internal:0
docker run --rm -it\
       -e DISPLAY=$HOSTDISPLAY \
       -v /tmp/.X11-unix/:/tmp/.X11-unix \
       --name udesk \
       udesk /bin/bash -c "nautilus"
xhost - 127.0.0.1
```

あとは `bash init.sh` でイメージのビルドから起動までできます．他のターミナルを開いておいて `docker stop udesk` で止めることができます．`--rm` オプションをつけてるので終わるとコンテナが消えてしまいます．ですので引き続き使いたい人は `--rm` を取り除いてコンテナを再起動する感じでお願いします．


- 上の `init.sh` で書いている `xhost +`/ `xhost -` のテクニックはDocker のコンテナで matplotlib の描画結果を表示させたいな場合にも応用が効きますね．
- Linux がホストの場合は `xhost + local:docker`/ `xhost - local:docker` とか `HOSTDISPLAY=$DISPLAY` としておくとうまくいくはずです．

# References

- [Dockerを導入してGUI操作可能なLinux(Ubuntu)コンテナを作成する](https://qiita.com/ryoya-s/items/ee1daf9cab18c100c990)
- https://marsee101.blog.fc2.com/blog-entry-4438.html
- https://askubuntu.com/questions/798928/nautilus-share-message-called-net-usershare-info-but-it-failed
- [Docker: コンテナのlocaleを設定したい](https://qiita.com/suin/items/856bf782d0d295352e51)
- https://medium.com/@mreichelt/how-to-show-x11-windows-within-docker-on-mac-50759f4b6

# References for those who would like to try with XForwarding
- https://unix.stackexchange.com/questions/12755/how-to-forward-x-over-ssh-to-run-graphics-applications-remotely
- https://blog.amedama.jp/entry/docker-container-x11-forwarding
- http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/
- https://unix.stackexchange.com/questions/108679/x-client-forwarded-over-ssh-cannot-open-display-localhost11-0
- [sshのX11Forwadingがうまく動作しない](https://rougeref.hatenablog.com/entry/20170419/1492562281)
CentOSのVimにMolokaiを導入する


# 要旨

VimのカラースキームにMolokaiを入れると、見た目が綺麗になり、作業が楽しくなります。

↓未導入 [^1]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532054/95ce6852-6e2b-eaeb-9bee-ba40745c9256.png)

↓導入後 [^1]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532054/dc6e125c-ba6e-c8b4-49c9-1889c0ae3476.png)

どうですか。この見た目。

Vimを起動するたびに恍惚とした表情で作業できそうです。

ぜひ導入しましょう。

# 導入

## git clone

```
cd /tmp
git clone https://github.com/tomasr/molokai
mkdir -p ~/.vim/colors/
mv molokai/colors/molokai.vim ~/.vim/colors/
```

## 設定ファイル

```:~/.vimrc
" 下記のように変更、または追記
colorscheme molokai
```

# 個人的な好みで設定変更

## コメント文字色の変更

Molokaiをそのまま使うと、コメントが黒背景に紛れてやや読み辛いので、変更しておきます。

```:~/.vim/colors/molokai.vim
" (略)
   "コメント色の変更
   "hi Comment         ctermfg=59
   hi Comment         ctermfg=241
" (略)
```

## tmux設定ファイルの変更

tmuxで256色表示にしておきます。

こうしないと、せっかくMolokaiを導入しても、tmuxのペインの中で色が変わってくれません。

```:~/.tmux.conf
set-option -g default-terminal screen-256color
set -g terminal-overrides 'xterm:colors=256'   
```

それではごきげんよう。


[^1]: ソースコードはこちらのサンプルを使いました。 → https://www.php.net/manual/ja/language.oop5.basic.php#example-186
Centos8にPostfixをインストールした

#◆環境
　　　CentOS Linux release 8.0.1905 (Core)
　　　サーバ（GUI）だけでインストールを実施
　　　ネットワーク設定は済ませた
　　　MySQL8.0はインストールした
　　　Zabbixはインストールした
　　　　・・・やっぱりメール送信したくなりますよね

#◆やったこと
1.Postfixのインストール

```diff:
　# dnf install postfix
メタデータの期限切れの最終確認: 1 day, 21:33:26 時間前の 2019年11月26日 00時43分36秒 に実施しました。
依存関係が解決しました。
==============================================================================================================================
 パッケージ                  アーキテクチャー           バージョン                           リポジトリ                 サイズ
==============================================================================================================================
Installing:
 postfix                     x86_64                     2:3.3.1-8.el8                        BaseOS                     1.5 M

トランザクションの概要
==============================================================================================================================
インストール  1 パッケージ

ダウンロードサイズの合計: 1.5 M
インストール済みのサイズ: 4.4 M
これでよろしいですか? [y/N]: y
パッケージのダウンロード中です:
postfix-3.3.1-8.el8.x86_64.rpm                                                                195 kB/s | 1.5 MB     00:07    
------------------------------------------------------------------------------------------------------------------------------
合計                                                                                          161 kB/s | 1.5 MB     00:09     
トランザクションの確認を実行中
トランザクションの確認に成功しました。
トランザクションのテストを実行中
トランザクションのテストに成功しました。
トランザクションを実行中
  準備             :                                                                                                      1/1 
  scriptletの実行中: postfix-2:3.3.1-8.el8.x86_64                                                                         1/1 
  Installing       : postfix-2:3.3.1-8.el8.x86_64                                                                         1/1 
  scriptletの実行中: postfix-2:3.3.1-8.el8.x86_64                                                                         1/1 
  検証             : postfix-2:3.3.1-8.el8.x86_64                                                                         1/1 

インストール済み:
  postfix-2:3.3.1-8.el8.x86_64   
```

2.サービス起動設定を行う

```diff:
　# systemctl start postfix
　# systemctl enable postfix
Created symlink /etc/systemd/system/multi-user.target.wants/postfix.service → /usr/lib/systemd/system/postfix.service.
```
3.メールサーバの設定変更

```diff:
 # vi /etc/postfix/main.cf
```
4.設定ファイルを修正する
変更したのは以下の点。送信専用ならこれだけでもいい気がします・・・

```diff:
・myhostname：送信に使うメールアドレス
・mydomail：送信に使うドメイン名
```

5.telnetが無かったのでインストールする
テストメールはtelnetを使って送ろうと思います

```diff:
　# dnf -y install telnet
```
https://www.rem-system.com/mail-postfix01/
・・・の通りメールをGmailに送ってみたけどダメっぽい。

https://qiita.com/Esfahan/items/6fa613069b13eb7daa17
このあたりの対策が必要だそうです。

6.Gmailに送れるように対策を実施する

```diff:
　# dnf install cyrus-sasl-plain cyrus-sasl-md5

　# vi /etc/postfix/sasl_password

　# postmap hash:/etc/postfix/sasl_password
```
もう一回送ったらいけました。


参考サイト
https://mizuti69.github.io/book_configure_centos8/8.smtp/1.smtp_config.html
http://park1.wakwak.com/~ima/centos4_switchmta2.html
https://www.rem-system.com/mail-postfix01/
https://qiita.com/Esfahan/items/6fa613069b13eb7daa17
pythonのmodels.pyで設定するテーブルを関連付ける

#やりたい事
pythonでdjangoを使ってブログを作っている。
models.pyにテーブルの設定を行う際に、
カテゴリー>記事のような親と子の関係にあるテーブルを作りたい。

#やり方
各テーブルを紐づけるには、
各テーブルに存在する変数を用いる。
その際指定される変数をforeign_keyとして設定する。

#実際にやってみた
ブログに投稿する記事には以下のclassとデータが入っている。
postクラスには
id,title,cantent,created_at,category
その際categoryクラスは別で作り、
id,name,created_at
で構成されている。

これらをデータ型も決めてコードに落とすと、

```
class Category(models.Model):
    name = models.CharField('カテゴリ名',max_length=255)
    created_at = models.DateTimeField('日付',default=timezone.now)

class Day(models.Model):
    title = models.CharField('タイトル',max_length=200)
    text = models.TextField('本文')
    date = models.DateTimeField('日付',default=timezone.now)
    category = models.ForeignKey(Category,verbose_name='カテゴリ',on_delete=models.PROTECT)
```

Dayクラスのcategoryインスタンスに代入しているのはmodelsにForeignKey関数を掛け合わせたものである。
その際に第一引数にcategoryを取り、verbose_nameでモデルの名前を任意のものに変えられます。
そしてon_deleteにPROTECT関数を代入する事でcategoryクラスで消去の処理を行った際でもpostクラスが存在する限り消去が行われなくなる（カテゴリを消しても投稿した記事は消えない）。

#まとめ
ForeignKey関数を使う事で、
設定元が親テーブル、参照される側は小テーブルとなり関連づけられる。

参考記事
ForeignKey：https://www.sejuku.net/blog/54072
verbose_name:https://codor.co.jp/django/how-to-use-verbose-name
僕が開発しやすいReact環境を構築する。

# 環境
* React
* ESlint
* prettier
* TypeScript
* styled-components

# 手順
## TypeScript用のReactプロジェクトを作成する
```
yarn create react-app my-app --typescript
```

## src内にあるファイルをすべて削除する。
```
cd my-app
cd src

# If you're using a Mac or Linux:
rm -f *

# Or, if you're on Windows:
del *

# Then, switch back to the project folder
cd ..
```
## ESlintをインストールする
```
yarn add -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
```

## prettierをインストールする

```
yarn add -D prettier eslint-config-prettier eslint-plugin-prettier

```
### 基本設定
```json:.eslintrc.json
{
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/eslint-recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:@typescript-eslint/recommended-requiring-type-checking",

    "plugin:prettier/recommended",
    "prettier/@typescript-eslint"
  ],
  "plugins": [
    "@typescript-eslint"
  ],
  "parser": "@typescript-eslint/parser",
  "env": { "browser": true, "node": true, "es6": true },
  "parserOptions": {
    "sourceType": "module",
    "project": "./tsconfig.json"
  },
  "rules": {
    // 適当なルール
  }
}
```

### VS CODE
```json:setting.js
{
  // "editor.formatOnSave": false,
  "eslint.autoFixOnSave": true,
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    {"language": "typescript", "autoFix": true },
    {"language": "typescriptreact", "autoFix": true }
  ]
}
```
* editor.formatOnSave: trueは自動整形が衝突するので指定しないでください。
* eslint.validateでtypescriptを指定してください。
* reactを使用するのでtypescriptreactも指定します。

## styled-componentsをインストールする
[公式](https://www.styled-components.com)

```
yarn add styled-components
yarn add @types/styled-components
```

## Material-UIをインストールする
[公式](https://material-ui.com/getting-started/installation/)

```
yarn add @material-ui/core
```

## フォルダを構成する
Styled-componentsの作者の提案する構成にする。
この構成はページやコンポーネント固有のものと複数のコンポーネントから使用される共通コンポーネントに大きくディレクトリを分けるアプローチです。

```
src
├── App
│   ├── Header
│   │   ├── Logo.js    
│   │   ├── Title.js   
│   │   ├── Subtitle.js
│   │   └── index.js
│   └── Footer
│       ├── List.js
│       ├── ListItem.js
│       ├── Wrapper.js
│       └── index.js
├── shared
│   ├── Button.js
│   ├── Card.js
│   ├── InfiniteList.js
│   ├── EmojiPicker
│   └── Icons
└── index.js
```




# 参考
* [VSCodeでESLint+@typescript-eslint+Prettierを導入する（v2.0.0）](https://qiita.com/madono/items/a134e904e891c5cb1d20)
* [styled-componentsを使ったCSS設計](https://qiita.com/taneba/items/4547830b461d11a69a20)
IBM Cloud functions(python)からDB2 on Cloudへ接続する方法

[IBM Cloud functions(node.js)からDB2 on Cloudへ接続する方法](https://qiita.com/testnin2/items/fa0c11f49f709f94b12e) のpython版です。この記事ではpython3.7でDb2 on Cloudへの接続を試してみたいと思います。
といっても、Create Action時にnode.jsではなくpythonを選ぶだけですが・・・
pythonを使ったDb2への接続方法の資料としては、以下が参考になります。
https://github.com/ibmdb/python-ibmdb/wiki/APIs#ibm_dbcallproc


```python:Db2OnCloudへの接続サンプルコード
import sys
import ibm_db

def main(dict):
    ssldsn = "DATABASE=xxxx;HOSTNAME=xxxxxx;PORT=xxxxx;PROTOCOL=TCPIP;UID=xxxxx;PWD=xxxxxx;Security=SSL;"
    conn=ibm_db.connect(ssldsn,'','')
    
    #Client Information
    client = ibm_db.client_info(conn)
    if client:
        print("DRIVER_NAME: %s" % client.DRIVER_NAME)
        print("DRIVER_VER:  %s" % client.DRIVER_VER)
        print("DATA_SOURCE_NAME: %s" % client.DATA_SOURCE_NAME)
        print("DRIVER_ODBC_VER: %s" % client.DRIVER_ODBC_VER)
        print("ODBC_VER: %s" % client.ODBC_VER)
        print("ODBC_SQL_CONFORMANCE:  %s" % client.ODBC_SQL_CONFORMANCE)
        print("APPL_CODEPAGE: %s)" % client.APPL_CODEPAGE)
        print("CONN_CODEPAGE: %s)" % client.CONN_CODEPAGE)
    else:
        print("client information cannot be retrieved.")

    
    #Server Information
    server = ibm_db.server_info(conn)
    if server:
        print("DBMS_NAME: %s"  % server.DBMS_NAME)
        print("DBMS_VER: %s" % server.DBMS_VER)
        print("DB_NAME: %s" % server.DB_NAME)
        print("DB_CODEPAGE: %s"  % server.DB_CODEPAGE)
        print("DFT_ISOLATION: %s" % server.DFT_ISOLATION)
        print("IDENTIFIER_QUOTE_CHAR: %s" % server.IDENTIFIER_QUOTE_CHAR)
        print("INST_NAME: %s" % server.INST_NAME)
    else:
        print("server information cannot be retrieved.")
    
    #SQL statements
    sql = "SELECT DBPARTITIONNUM, REG_VAR_NAME, REG_VAR_VALUE from SYSIBMADM.REG_VARIABLES"
    stmt = ibm_db.prepare(conn, sql,)
    result = ibm_db.execute(stmt)
    row = ibm_db.fetch_both(stmt)
    while ( row ):
        print("%-5d"  % row['DBPARTITIONNUM'])
        print("%-30s" % row['REG_VAR_NAME'])
        print("%-30s" % row['REG_VAR_VALUE'])
        row = ibm_db.fetch_both(stmt)
    
    
    ibm_db.close(conn)
    return { 'result': 'finished!' }
```
Node.jsでMySQLに接続するのをDockerでやってみた

この記事は[富士通クラウドテクノロジーズ Advent Calendar 2019](https://qiita.com/advent-calendar/2019/fjct) 5日目の記事です。
4日目は @tmtms さんの [MySQL Parameters を拡張した](https://tmtms.hatenablog.com/entry/201912/mysql-params) でした。


# はじめに
- ※本記事は、 [Node.js超入門[第2版]](https://www.amazon.co.jp/dp/4798055220/ref=cm_sw_r_tw_dp_U_x_By-TDb0E9TCZY) のサンプルコードをDocker上で動かす趣旨のものです。
よって、書籍で言及されている階層は触れません。

はじめまして。Node.jsを勉強中の新卒エンジニアです。
配属したてホヤホヤです。
今回は [Node.js超入門[第2版]](https://www.amazon.co.jp/dp/4798055220/ref=cm_sw_r_tw_dp_U_x_By-TDb0E9TCZY) を使って勉強したときの話をします。

この書籍の内容をDockerで実現しようとした経緯ですが、そのまま「Dockerを理解したかったから」です。
弊社の研修でもDockerについて触れていただいたのですが、一度教わっただけでは理解が難しいものでした。
というわけで、サンプルコードを写経するだけになりがちだった（主観です）プログラミングの本で、ついでに理解を深めようという魂胆です。

今回は、書籍の Chapter5「値とデータをマスターしよう！」の、Section5-3～5-4 で書かれている、Node.jsでDBにアクセスして情報を取得し、ブラウザに表示するプログラムを紹介します。書籍が手元にある方はぜひ確認してみてください。

# 環境構築

必要な環境

- Linux
- Docker https://docs.docker.com/install/
- docker-compose https://docs.docker.com/compose/install/
- 今回のコードは [GitHub](https://github.com/pinkeysheep/NodejsMySQLDocker) にpushしました。以降、これを読んでいるものとして話を進めます。


参考記事： 

- [docker-compose でMySQL環境簡単構築](https://qiita.com/A-Kira/items/f401aea261693c395966) 
- [Docker MySQLコンテナ起動時に初期データを投入する](https://qiita.com/NagaokaKenichi/items/ae037963b33a85df33f5)
- [Node.js Web アプリケーションを Docker 化する](https://nodejs.org/ja/docs/guides/nodejs-docker-webapp/)

# 解説

- 今回は、Node.jsもMySQLも、Dockerコンテナとして生成しています。
- Node.jsサーバーは、 `docker-compose.yml` から `Dockerfile` を呼び出す形で書き、MySQLサーバーは `docker-compose.yml` 内で定義しています。
- `docker-compose.yml` で指定するMySQLのDockerイメージは、MySQLのバージョンが8よりも前になるように古いものを使っています。
8以降はそのままだとNode.jsとの連携ができないようです。
  - [Node.jsでMySQL 8.0へ接続しようとする時に発生するエラー](https://qiita.com/monga3/items/6583c07a9b275b469608)
- `init-mysql.sh` は、ローカル環境から、データベース用のコンテナにアクセスし、テーブル作成->データ挿入までを行っています。
- 実は、`docker/db/my.cnf` と `docker-compose.yml` の2か所で `mysqld` を設定しているのですが、どちらかを消すとなぜかエラーになってしまうため（！）そのままにしてあります。いい方法ががありましたら教えていただけると幸いです・・・。
- 余談ですが、今回のコードは、いままで述べてきたものとは別のDockerfileでExpress-generatorを実行し、
`docker cp` でローカルにファイルをコピーしてから作成していきました。
めんどうくさいことをしたなと自分で思います。


# 動作確認

- 上記のリポジトリをcloneします。
- リポジトリに移動
- `docker-compose up -d` でコンテナを立ち上げます。
- すこし(10秒ほど)時間をおきます。（コンテナが出来上がるまで待つ）
- ローカルで `./init-mysql.sh` を実行します。
- `localhost/hello` にアクセスし、 `docker/db/sql/002-insert-records.sql` で入れたデータが表示されていることを確認してください。
- ↓ こんなふうに表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321497/f5ebea69-1f7d-5f9f-0a1a-877d6ff00b14.png)

# おわりに

まず、Node.jsについての書籍を読み、サンプルを実行してみることで、Node.jsの挙動についてざっくりと理解できるようになりました。
加えて、それらをDocker上の環境で行うことで、
いままで「VirtualBoxより軽い仮想化するアプリケーション？」という認識だったDockerについての理解も深まりました。
Linuxのコンソールの扱いも以前よりわかるようになってきました。
やっと `.profile` や `.vimrc` をカスタマイズできるようになり、快適なUbuntu生活をしております。

また、試行錯誤して、調べたり人に聞いたりしていくことが学びへの近道だと実感しました。
例えば、MySQLのバージョンに関しては自分では調べきれず、先輩方の知恵をお借りしました。
ありがとうございました。


まだまだエンジニアとしては若輩者ですが、これからもっと勉強してスキルをつけ、開発をたくさんしていけたらと思います。
RDBについての備忘録

#RDBとは
- リレーショナルデータベース
- OracleやMySQL、PostgreSQLなど
- データを表形式で扱う
- 普段使ってるデータベースのこと
- 行と列によって構成された表形式のテーブル
- 行（横）をレコード、列（縦）をフィールド、表をテーブルと呼ぶ
- データベースの種類
- 関連があるデータ項目の集合体

### DB,RDB,DBMS,RSBMSの違い

- DB（データベース）・・・データを入れる箱
- RDB・・・(リレーショナルデータベース)データベースの種類
- DBMS(データベースマネジメントシステム)・・・データベースを扱うための道具
- RDBMS(リレーショナルデータベースマネジメントシステム)・・・リレーショナルデータベースを扱うための道具

＊[わかりそうでわからない](https://wa3.i-3-i.info/word11770.html)サイトを参考にしました
*[大塚商会](https://wa3.i-3-i.info/word11770.html)
Automation Anywhere A360 ショートカットキー まとめ


まだ公式ドキュメンテーションでは見つけられていないのですが、いじっていて発見したショートカットキーをまとめておきます。

#Task Botの編集画面でのショートカットキー

|ショートカットキー|ショートカットキー （Mac）   |機能、解説|
|:-----------------:|:------------------:|:------------------:|
|Ctrl+A|⌘+A|全選択|
|Ctrl+C|⌘+C|コピー|
|Ctrl+V|⌘+V|貼り付け|
|Ctrl+S|⌘+S|保存|
|Ctrl+X|⌘+X|切り取り|
|Ctrl+Z|⌘+Z|元に戻す|
|Del|Fn+Del|削除|
|Ctrl+Enter|⌘+Enter|アクションの詳細設定を保存して閉じる|
|Ctrl+/|⌘+/|選択したアクションを無効にする（コメントアウト）|
|F2|fn+F2|変数が使用可能なフィールドで変数挿入用のウィンドウを開く。※|
|F5|fn+F5|Botの実行|
|F9|fn+F5|ブレークポイントの設定/解除|
|Shift+F9|Shift+fn+F9|全てのアクションにブレークポイントの設定/解除|
|F10|fn+F10|デバッグモードのOn/Off|コピー|
|Space|Space|アクションの詳細設定画面の表示/非表示|
|Enter|Enter|アクションの詳細設定画面を表示して編集|

※変数が使用可能なフィールドで、$を入力することでも同じ画面が開きます。
URIスキーマを活用しチャット相手を指定してTeamsを開く

# URIスキーマを活用しチャット相手を指定してTeamsを開く

　ショートカットをクリックすると、チャット相手を指定してTeamsを開いたり、既に開いているTeamsのチャット画面出せないかなと色々と試した結果。

## 結論

 URIスキーマが使えないシーンが増えており、その場合は、以下のようなURLでチャット相手を指定してTeamsを開くことができます。

```
https://teams.microsoft.com/l/chat/0/0?users=<相手のメールアドレス等>
例：
https://teams.microsoft.com/l/chat/0/0?users=im:hogehoge@qmail.com
```

以下リンクを生成し、クリックすることでチャット相手を指定してTeamsを開く事ができます

```
im:<相手のメールアドレス等>
例：
im:hogehoge@qmail.com
```

## URIとは

　URI (Uniform Resource Identifier) とは、簡単に言ってしまうと「名前や場所の書き方を示したルールの総称」です。WindowsにはこのURIスキーマを用いて特定の動作をするアプリを呼び出す書式を定義されており、それを活用することでアプリの呼び出しを便利に行なえます。

　これらの定義の中には"im:"という定義があり、この定義はインスタントメッセージアプリを起動するものになります。上記はこれを活用して、Teamsのチャット画面を開く仕組みになります。


## 関連付けられているアプリの確認方法

　Windowsの設定で「プロトコルごとに既定のアプリを選ぶ」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151198/46117a7b-9c48-d6b3-0709-f344645e08b6.png)

　"URL:IM"の欄を確認します。ここで指定されているアプリケーションでチャットツールが開きます。何も設定されていなかったり、既に何か違うアプリが指定されている場合は、Microsoft Teamsを指定することで、"im:～"というリンクがMicrosoft Teamsで開くようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151198/ca58bbe6-f2e2-00be-6878-5cf6130d8c28.png)


　URIは色々と活用できそうなので引き続きいじってみようと思います。


## 注意点

　残念ながら、このURIはMicrosoft Teamsの会話では有効にならないので注意してください。
（メールやOfficeファイルからTeamsに誘導するのに使うといいと思います）

　imにMicrosoft Teamsが関連付けられておらず、他のチャットツールが関連付けられている場合は、そちらが起動します。

　また、imにどのアプリも関連付けられていない場合は、以下のように既に入っているアプリケーションの中から開くアプリ、既定のアプリを選ぶ画面が表示されるので、ここからMicrosoft Teamsを選択します。
（これを利用してあえてimにアプリを設定せず、毎回開くチャットツールを選ぶことも可能です）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151198/29412c10-315c-222b-4f49-d1d5ca8fc8f9.png)


## 補足
Teams上のファイルもURIを使ってデスクトップアプリで開くことが可能。以下が詳しいです：

https://qiita.com/Rambosan/items/34fd50aea330355b94c2


## 参考文献

- [URI に応じた既定のアプリの起動 \- UWP apps \| Microsoft Docs](https://docs.microsoft.com/ja-jp/windows/uwp/launch-resume/launch-default-app)
- [Office URI スキーマ \| Microsoft Docs](https://docs.microsoft.com/ja-jp/office/client-developer/office-uri-schemes)
- [URLとURIの違いとは？ パーツの構造・名称・意味も大解説！ \| 初代編集長ブログ―安田英久 \| Web担当者Forum](https://webtan.impress.co.jp/e/2010/03/09/7539)
- [URL と URI の違い \- Qiita](https://qiita.com/Zuishin/items/3bd56117ab08ec2ec818)
- [作りこむよりシンプルに: リンクを開くと「Teamsで指定した宛先へのチャットメッセージを作成する」、というリンクを作成する。](https://www.peridot-green.com/2020/12/teams.html)
【ど忘れシリーズ】llコマンドがcommand not foundになったときの対処法


# はじめに
``` shell
[hoge@hoge ~/Documents/hogehoge]$ ll
bash: ll: command not found
```

**新米エンジニア「ファッ！？先輩！！llコマンドが使えません！」**
**先輩エンジニア「フォッフォッフォ！落ち着くがよい。」**

とても便利なllコマンド。
しかし、稀にコマンドを入力しても「そんなコマンドねーよ」と怒られる場合があります。
（私も初めてのころはすごく焦っていました笑）

# llコマンドって？
「ls -l」コマンドのショートカット（エイリアス）です。
なので実際にllコマンドは**「ls -l」コマンドと同等のもの**が実行されています。

## llコマンド
``` shell
[hoge@hoge ~/Documents/hogehoge] $ ll
total 0
-rw-r--r-- 1 hoge 197608 0 11月 28 17:31 hoge_file_1.txt
-rw-r--r-- 1 hoge 197608 0 11月 28 17:31 hoge_file_2.txt
-rw-r--r-- 1 hoge 197608 0 11月 28 17:31 hoge_file_3.txt
```

## 「ls -l」コマンド
``` shell
[hoge@hoge ~/Documents/hogehoge] $ ls -l
total 0
-rw-r--r-- 1 hoge 197608 0 11月 28 17:31 hoge_file_1.txt
-rw-r--r-- 1 hoge 197608 0 11月 28 17:31 hoge_file_2.txt
-rw-r--r-- 1 hoge 197608 0 11月 28 17:31 hoge_file_3.txt
```
# どうしたらいいの？
llコマンドが「ls -l」と認識できるようにすればよいので、
```.bashrc```というファイルに登録すればOKです。手順は次に進んでみてね。

## １．.bashrcファイルを開きます
``` shell
[hoge@hoge ~]
$ vi ~/.bashrc
```

↓
## ２．下記を追記します
``` shell
alias ll="ls -l"
```

# これで？
``` shell
[hoge@hoge ~/Documents/hogehoge]$ ll
total 0
-rw-r--r-- 1 hoge 197608 0 11月 28 17:31 hoge_file_1.txt
-rw-r--r-- 1 hoge 197608 0 11月 28 17:31 hoge_file_2.txt
-rw-r--r-- 1 hoge 197608 0 11月 28 17:31 hoge_file_3.txt
```

これでllコマンドで実行できるようになりましたね。

**新米エンジニア「先輩！！これで今夜はぐっすり眠れそうです！」**
**先輩エンジニア「よかったね！おやすみ！」**
ESP32でタッチセンサ

3ボタンのタッチセンサをさくっと作ってみます。

ESP32のタッチセンサ機能は以下のように割り当てられているみたいです。

- T0 GPIO4
- T1 GPIO0 
- T2 GPIO2 
- T3 GPIO15
- T4 GPIO13
- T5 GPIO12
- T6 GPIO14
- T7 GPIO27
- T8 GPIO33
- T9 GPIO32

このうちの、GPIO12,13,14ピンに接続したパッドをタッチセンサにします。

絶対値は使用環境によってゆらぎが入るので、3ボタンの平均値を求め、その平均値に係数をかけたものをしきい値としてボタンにタッチしたかどうかを判定するようにしました。


```
void setup()
{
  Serial.begin(115200);
  delay(1000);
  Serial.println("Touch Sensor Test");
}

void loop()
{
  int v0,v1,v2,vborder;
  v0 = touchRead(T4);
  v1 = touchRead(T5);
  v2 = touchRead(T6);
  float coefficient=0.3;
  vborder=(v0+v1+v2)/3*coefficient;
  if (v0 < vborder ) {
    Serial.print(" ON  ");
  } else {
    Serial.print(" OFF ");
  }
  if (v1 < vborder ) {
    Serial.print(" ON  ");
  } else {
    Serial.print(" OFF ");
  }
  if (v2 < vborder ) {
    Serial.print(" ON  ");
  } else {
    Serial.print(" OFF ");
  }
  Serial.println();
  delay(100);
}

```
初心者によるプログラミング学習ログ 171日目

# 100日チャレンジの171日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

171日目は

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>webサイトコーディング課題<br><br>オブジェクトの位置とか修正<a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a> <a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1199780716260708352?ref_src=twsrc%5Etfw">November 27, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
シェルスクリプト グループコマンド

{} で囲んだリストはグループコマンドとなり、複合コマンドとなる。

##### グループコマンドを使わない場合
それぞれのコマンドでリダイレクトしなければならない。

```bash:group-example1.sh
echo "group" > example1.log
pwd >> example1.log
date >> example1.log
```

##### グループコマンドを使う場合
最後のリダイレクトですべての標準出力がリダイレクトされる。

```bash:group-example2.sh
{
  echo "group"
  pwd 
  date
} > example2.log
```

```bash:group-result2.sh
group
/home/blueskyarea/work2
Thu Oct 10 11:01:34 JST 2019
```

[サブシェル](https://qiita.com/blueskyarea/items/02ba29a04b9f0d56f4ac)と違って、同一プロセス上で動作する。
リダイレクトは必要なくても、なんらかのまとまったコマンドの塊であることを明示するのに便利。
CentOS 7にPHP 7.4をインストール（Remi's RPM repository）

# はじめに

Remi's RPM repositoryを利用してCentOS7にPHP7.4をインストール
親記事：[PHP, PHP-FPMの各種インストール方法とEOLまとめ](https://qiita.com/witchcraze/items/dfe3823554b7caba6f6a)
参考：[Remi's RPM repository](https://rpms.remirepo.net/wizard/)

## サポート

本手法で導入した場合、[PHP: Supported Versions] (https://www.php.net/supported-versions.php)/[PHP: Unsupported Branches](https://www.php.net/eol.php)より、2022-11-28がEOLになると思われる。
それ以降に報告された脆弱性や不具合への対応は実施されない可能性がある。

## note

- インストール後の更新は `yum --enablerepo=remi-php74 update`

## LOG

### インストール

```shell-session
# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)

# yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm
... 略

# yum install -y --enablerepo=remi-php74 php which
... 略
```

### 各種確認

```shell-session
# which php
/usr/bin/php

# php -v
PHP 7.4.0 (cli) (built: Nov 26 2019 20:13:36) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies

# php -i | grep php.ini
Configuration File (php.ini) Path => /etc
Loaded Configuration File => /etc/php.ini

# yum info php
Loaded plugins: fastestmirror, ovl
Loading mirror speeds from cached hostfile
 * base: ftp.riken.jp
 * epel: ftp.riken.jp
 * extras: ftp.riken.jp
 * remi-safe: ftp.riken.jp
 * updates: ftp.riken.jp
Installed Packages
Name        : php
Arch        : x86_64
Version     : 7.4.0
Release     : 1.el7.remi
Size        : 10 M
Repo        : installed
From repo   : remi-php74
Summary     : PHP scripting language for creating dynamic web sites
URL         : http://www.php.net/
License     : PHP and Zend and BSD and MIT and ASL 1.0 and NCSA
Description : PHP is an HTML-embedded scripting language. PHP attempts to make it
            : easy for developers to write dynamically generated web pages. PHP also
            : offers built-in database integration for several commercial and
            : non-commercial database management systems, so writing a
            : database-enabled webpage with PHP is fairly simple. The most common
            : use of PHP coding is probably as a replacement for CGI scripts.
            :
            : The php package contains the module (often referred to as mod_php)
            : which adds support for the PHP language to Apache HTTP Server.
```
ロータリーエンコーダーをESP32で使う

ロータリーエンコーダー使おうとしたらライブラリがいくつかありました。

今回は最近更新された「RotaryEncoder」ライブラリを使ってみました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/de153fc3-7e27-1229-08a8-53c7eeb23924.png)


# 環境
Ubuntu18.04
Arduino 1.8.10
ESP32
GxEPD2

# ライブラリインストール
「ツール」-「ライブラリを管理...」でライブラリマネージャを呼び出し、「Rotaryencoder」と入力しインストール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/18265941-8622-26c9-2948-1c97ec2c420f.png)

「RotaryEncoder by Matthias Hartel」を選びます。

# サンプルプログラム

「ファイル」-「スケッチ例」-「カスタムライブラリのスケッチ例」-「RotaryEncoder」-「SimplePallRotater」
を呼び出す

以下の箇所を探して

```

// Setup a RoraryEncoder for pins A2 and A3:
RotaryEncoder encoder(A2, A3);

void setup()
{
  Serial.begin(57600);
  Serial.println("SimplePollRotator example for the RotaryEncoder library.");
} // setup()
```

以下のように変更

```

// Setup a RoraryEncoder for pins A2 and A3:
RotaryEncoder encoder(12, 13);

void setup()
{
  Serial.begin(115200);
  Serial.println("SimplePollRotator example for the RotaryEncoder library.");
} // setup()
```


これで動いた。

# 動作解説

```

void loop()
{
  static int pos = 0;
  encoder.tick();
```

ということで、tick() をループ中で呼び出している。次の割り込み駆動のプログラムでは、ピン状態変更割り込みでtick()を呼び出している。


# 割り込みで動かす


「ファイル」-「スケッチ例」-「カスタムライブラリのスケッチ例」-「RotaryEncoder」-「InterruptRotater」
を呼び出す

```

#include <RotaryEncoder.h>

// Setup a RoraryEncoder for pins A2 and A3:
RotaryEncoder encoder(A2, A3);

void setup()
{
  Serial.begin(57600);
  Serial.println("SimplePollRotator example for the RotaryEncoder library.");

  // You may have to modify the next 2 lines if using other pins than A2 and A3
  PCICR |= (1 << PCIE1);    // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
  PCMSK1 |= (1 << PCINT10) | (1 << PCINT11);  // This enables the interrupt for pin 2 and 3 of Port C.
} // setup()



// The Interrupt Service Routine for Pin Change Interrupt 1
// This routine will only be called on any signal change on A2 and A3: exactly where we need to check.
ISR(PCINT1_vect) {
  encoder.tick(); // just call tick() to check the state.
}

```


となっているのを

```
#include <RotaryEncoder.h>

// Setup a RoraryEncoder for pins A2 and A3:
RotaryEncoder encoder(12, 13);
// The Interrupt Service Routine for Pin Change Interrupt 1
// This routine will only be called on any signal change on A2 and A3: exactly where we need to check.
void IRAM_ATTR ISR() {
  encoder.tick(); // just call tick() to check the state.
}

void setup()
{
  Serial.begin(115200);
  Serial.println("SimplePollRotator example for the RotaryEncoder library.");
  attachInterrupt(12, ISR, CHANGE);
  attachInterrupt(13, ISR, CHANGE);

} // setup()
```

とすると動いた


# チャタリング防止

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/168de6f0-8143-b2fa-b2c6-f76534acb872.png)

0.1uFのコンデンサを入れるのが効果的
githubのプルリクエストのマージ後にブランチを自動で削除できるようになった

githubのプルリクを使う方は多いと思いますが、
forkなどを使わずにoriginでブランチを切っていると大量にブランチが残ってきますよね。
個々で消すことも全然できますが、マージ後のヘッドブランチの自動削除が設定でできるようになりました。
地味に便利ですね！

やってみようとしたら、

あ、

管理者権限なかったわ。

詳細の設定方法はこちらに。
https://help.github.com/en/github/administering-a-repository/managing-the-automatic-deletion-of-branches
LaravelのHerokuへのデプロイ、DBはMySQL。

##データベースにMYSQLを使う
HerokuではデータベースとしてPostgreSQLになっているため、アプリごとにClearDBを入れなければならない。利用にはクレジットカードが必要。（ClearDBの利用自体は無料）


```
$ heroku addons:add cleardb
```
上記にコマンドの入力またはHerokuのサイトのsettingタブから導入できる。

##Procfile を作成する
ProcfileというHerokuの設定ファイルを作成。サーバーにApacheを使うこと、public/をドキュメントルートとすることを宣言するために使います。アプリフォルダの直下に作成する。

```:Procfile
web: vendor/bin/heroku-php-apache2 public/
```
中身は上記のように。

##環境変数の設定
どの項目を登録すべきかよくわからなかったためいろいろやってみたが注意すべきはDBに関する項目。

DB_DATABASE=[データベース名]
DB_HOST=[ホスト名]
DB_USERNAME=[ユーザー名]
DB_PASSWORD=[パスワード]

これらはenvファイルの設定ではなくclearDBの設定で、そのURL内にある。下記コマンドで表示。

```
heroku config:get CLEARDB_DATABASE_URL

＃URLが表示される
mysql://[ユーザー名]：[パスワード]@[ホスト名]/[データベース名]?reconnect=true
```

またセキュリティ関連のAPP_KEYの設定も必須。

```
heroku config:set APP_KEY=$(php artisan --no-ansi key:generate --show)
```

envファイルのAPP_KEYの項目をartisanコマンドで取得

##HerokuのMYSQLにmigrateする
自分はここに一番時間を取られた。マイグレーションがうまくいかない。


```
Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
```
何度やってもこのエラーメッセージが出てくる。訳すと「指定されたキーは長すぎます。キーの長さは最大767バイトです。」

調べていくとvarchar型の文字数を191に制限しなければこのエラーが出るらしい。

app\Providers\AppServiceProvider.phpに以下を追加。

```php:AppServieProvider.php
use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}
```
自分はSchemaクラスをuseするのを忘れていたため時間がとられてしまった。
use Illuminate\Support\Facades\Schema;を忘れないように。

##デプロイする
HerokuではアプリをGitを利用してデプロイする。自分はGitも初心者だったためここでもかなり時間を要した。

まずはHerokuのアプリをリモートとして登録

```
git init
heroku git:remote -a <herokuのアプリ名>
```

ローカルリポジトリにコミットし

```
git add .
git commit -m "コミットメッセージ"
```

プッシュすることによりデプロイする

```
git push heroku master
```
問題がなければheroku openでサイトを開くことができる

```
heroku open
```




思った以上に時間がかかってしまった。自分が犯していた間違いはdevelopブランチにProcfileファイルを作成し、マージしないままmasterをプッシュをしていたこと。そのほかにもGitの基本的な操作ができていなかった。HerokuよりもGitに慣れていないことを痛感させられた。

こちらの記事に全体的な流れをまとめましたのでよかったらどうぞ
[【Laravel】Herokuでのデプロイ](https://qiita.com/rope19181/items/07d556715a3a4f6191bd)
ブラウザ動作ゲーム開発で良さそうライブラリ

ちょっと触ってみて、良さそうなものをメモ

| 名称 | サイトURL | メモ |
|---|---|---|
| PixiJS | https://www.pixijs.com/ | アニメーションや変形・色変が強そう |
| CREATE JS | https://www.createjs.com/ | 音系があるので音の場合良さそう |
| Matter.js | https://brm.io/matter-js/ | 物理演算系いい感じ |

ゲーム系ライブラリは　PixiJS　や　CREATE JS　が強そうですが　
物理演算系は　matter-js　良さそうかも

##PixiJS 

![NoName_2019-11-28_20-19-11_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/bf78bffd-c5eb-1c9e-e45a-d9a4f73d52ad.png)

スクラッチで除去(pixijs)
https://pixijs.io/examples/#/demos-advanced/scratchcard.js


##CREATE JS
![NoName_2019-11-28_20-19-28_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/9140339f-b9ba-206e-502c-80fdf69bf5cb.png)

ヨコ走り系(createjs)
https://www.createjs.com/demos/easeljs/spritesheet

シューティング系(createjs)
https://www.createjs.com/demos/easeljs/game

雲り除去(createjs)
https://www.createjs.com/demos/easeljs/alphamaskreveal

##Matter.js
![NoName_2019-11-28_20-18-58_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/963cc9f5-52b0-5eb0-61f6-eed18fedfaad.png)

スリングショット系(matter-js)
https://brm.io/matter-js/demo/#slingshot

##人気のゲームエンジンらしい（ほんまもの向け）
　https://www.egret.com/en/case
　https://cocos2d-x.org/filecenter/jsbuilder/
[ruby2.5~] 文字列中の先頭, 末尾から特定文字を一つだけ消す

特定の文字を先頭から見つかった最初だけ、末尾から見つかった一つだけ消したいニーズがあった
gsubやdeleteだと下記の様に見つかった全部の文字を消してしまうので使えない

```ruby
'中野区東中野'.gsub('中野', '')
=> "区東"
'中野区東中野'.delete('中野')
=> "区東"
```

地味に面倒な記憶があったけれど、ruby2.5から`delete_suffix`, `delete_prefix`というメソッドが追加されていた

```ruby
'中野区東中野'.delete_prefix('中野')
=> "区東中野"
'中野区東中野'.delete_suffix('中野')
=> "中野区東"
```

破壊的メソッドも用意されているらしい。便利！

参考
https://docs.ruby-lang.org/ja/latest/method/String/i/delete_suffix.html
https://docs.ruby-lang.org/ja/latest/method/String/i/delete_prefix.html
【1分解説】ファイルの中身を出力したい時に使うコマンド【catコマンド】

##はじめに
ファイルの中身がみたい！と思った時はcatコマンドでファイルの中身を出力してみましょう。

##発行コマンド
test1の中身を出力する場合、
以下のコマンドを発行します。

```
$ cat test1
```

##実際に発行してみた
発行するとファイルの中身が出力されます。

```
$ cat test1
aaaa
bbbb
cccc
```
![9EDB6D0A-7B73-4700-ADDC-04719A43B945.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536706/77e0d6ac-9fc6-d7ac-ab1b-703f6389e769.png)
【1分解説】Apacheのアクセスログ解析（アクセス元IPアドレスをTOP10で抽出）

<h2>はじめに</h2>
アクセス元IPアドレスをTOP10で抽出したい！という時に使うコマンド。

##発行コマンド
```
$ cat access_log |cut -f 1 -d ' ' | sort |uniq -c|sort -nr|head -10
```

<h2>中身</h2>
◆cut -f 1 -d ' ' 
access_logの中身を「 」（スペース）で区切り、１項目を表示する

◆sort | uniq -c
で重複行をカウント

◆sort -nr	
数字が大きい順に並べかえる

◆head -10
TOP10のみ出力

<h2>実際に発行してみた</h2>
実際に発行してみると、

```
$ cat access_log |cut -f 1 -d ' ' | sort |uniq -c|sort -nr|head -10
103 X.X.X.X
99 X.X.X.X
93 X.X.X.X
91 X.X.X.X
88 X.X.X.X
50 X.X.X.X
33 X.X.X.X
29 X.X.X.X
18 X.X.X.X
6 X.X.X.X
```

左からアクセス数、つぎに接続元IPアドレスが出力されます。

例えば、接続数が多いIPアドレスが海外のブラックリストに登録されているIPアドレスだった場合は、拒否したりすることもできます。
pythonで背景が透明な文字や画像をウィンドウ枠なしで表示させる

## やりたいこと
・ソフトウェアを起動させるときに画像を表示させたい。
・画像を表示させるときは、ウィンドウの枠を表示させたくない。
・画像を表示させるときは、画像の背景は透明にしたい。
・起動時に画像を表示させ、裏でアプリ本体をロードさせ、その後に起動時の画像を消したい。

## 動作環境
Windows10
PyCharm
python3

## それをスプラッシュスクリーンといいます
[スプラッシュスクリーン](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%97%E3%83%A9%E3%83%83%E3%82%B7%E3%83%A5%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3)とは、ソフトウェアを起動させるときに表示される画像のことを言います。

## 困ったところ
・tkinterで作ったウィジェットのmainloopが抜けられなくて困りました。結局、destroy()ではなくて quit()を使えば上手く行きました。

## コード
スプラッシュスクリーンで文字を表示させる場合の例です。

``` python3
import tkinter
import win32api
import win32con
import pywintypes


label = tkinter.Label(text='Powered by \nHogeHoge株式会社', font=('メイリオ','40'), fg='snow', bg='white')
label.master.overrideredirect(True)
window_width = 700
window_height = 500
label.master.geometry(str(window_width) + "x" + str(window_height) + "+400+300")
label.master.lift()
label.master.wm_attributes("-topmost", True)
label.master.wm_attributes("-disabled", True)
label.master.wm_attributes("-transparentcolor", "white")

hWindow = pywintypes.HANDLE(int(label.master.frame(), 16))
exStyle = win32con.WS_EX_COMPOSITED | win32con.WS_EX_LAYERED | win32con.WS_EX_NOACTIVATE | win32con.WS_EX_TOPMOST | win32con.WS_EX_TRANSPARENT
win32api.SetWindowLong(hWindow, win32con.GWL_EXSTYLE, exStyle)


def call_back_func():
    print("call_back_funcの実行")
    label.quit()
    # label.destroy()
    # =============================
    # 色々と実験しましたが、結局 quit() すれば、mainloopを抜けることができることを発見しました。
    # destroyではmainloopを抜けられないので、注意されたし。
    # ==============================


label.pack()
# label.after(3000, call_back_func)
# label.after(3000, lambda: label.quit())
label.after(3000, lambda: [print("call_back_funcの実行"), label.quit()])
label.mainloop()

print("quitを実行すれば、mainloopを抜けることができた。\nめでたし、めでたし。")
print("mainloopを抜けた後に、目的のアプリを表示させれば、自分の考えた通りの動作になります。")
```
## 実行結果
<img width="932" alt="splash_screen.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262477/b7843156-7da9-14e4-f4cb-023f90776cea.png">
よっしゃ！
３秒後にmainloopを抜けることも成功！

## コード内の説明
Widgetのafter関数
after関数はコールバック関数です。
http://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.after-method
コールバックということはlambda関数を使うチャンスです。

## 課題
・画面の真ん中に表示出来るようにするのを忘れてました。
・クラス化。

## 新たな問題発生
・spash screenは表示させて消すことは出来るのですが、その後に立ち上がる本体アプリが一部黒く表示されるというバグを確認しました。解決でき次第、修正コードを追加します。SetWindowPosで再度表示すれば解決する気がしますが、なんかうまくいきませんねぇ・・・。

## 画像を表示させる場合のコード
後日追加します。
ログイン時などに開かれる Safari をフルスクリーンにする。例：Googleログイン

# はじめに
iOSエンジニアの[やまたつ](https://twitter.com/yamatatsu109_ja)です！
iOS13で modalPresentationStyle のデフォルトが変更されたため、 `modalPresentationStyle = .fullScreen` を付加していく作業を行っています。（画面数多いとつらい）

ログインに GIDSignIn を使用していたときに、「どこに .fullScreen 書くんだろう？」となったので解決策のシェアです。

# 解決策
SFSafariViewController でログイン画面を表示させるもの限定になりますが、
SFSarafiViewController を拡張するとOKです。


```swift:SFSafariViewController+.swift

extension  SFSafariViewController {
    override open var modalPresentationStyle: UIModalPresentationStyle {
        get { return .fullScreen}
        set { super.modalPresentationStyle = newValue }
    }
}

```



# さいごに
SFSafariViewController は .fullScreen にせずにハーフモーダルで良いと思ってます。笑
CDP Install Error: Solr 権限エラー

## Error:

```
Thu Nov 28 05:40:08 EST 2019
JAVA_HOME=/usr/java/jdk1.8.0_232-cloudera
using 7 as CDH_VERSION
CONF_DIR=/var/run/cloudera-scm-agent/process/105-solr-SOLR_SERVER
CMF_CONF_DIR=
Unable to set the cluster property due to following error : Error setting cluster property
Error: Unable to set the cluster property in ZK
ERROR: Failed to configure urlScheme property for Solr cluster in Zookeeper
Thu Nov 28 05:40:12 EST 2019
JAVA_HOME=/usr/java/jdk1.8.0_232-cloudera
using 7 as CDH_VERSION
CONF_DIR=/var/run/cloudera-scm-agent/process/105-solr-SOLR_SERVER
CMF_CONF_DIR=
Unable to set the cluster property due to following error : Error setting cluster property
Error: Unable to set the cluster property in ZK
ERROR: Failed to configure urlScheme property for Solr cluster in Zookeeper
Thu Nov 28 05:40:17 EST 2019
JAVA_HOME=/usr/java/jdk1.8.0_232-cloudera
using 7 as CDH_VERSION
CONF_DIR=/var/run/cloudera-scm-agent/process/105-solr-SOLR_SERVER
CMF_CONF_DIR=
Unable to set the cluster property due to following error : Error setting cluster property
Error: Unable to set the cluster property in ZK
ERROR: Failed to configure urlScheme property for Solr cluster in Zookeeper
Thu Nov 28 05:40:23 EST 2019
JAVA_HOME=/usr/java/jdk1.8.0_232-cloudera
using 7 as CDH_VERSION
CONF_DIR=/var/run/cloudera-scm-agent/process/105-solr-SOLR_SERVER
CMF_CONF_DIR=
Unable to set the cluster property due to following error : Error setting cluster property
Error: Unable to set the cluster property in ZK
ERROR: Failed to configure urlScheme property for Solr cluster in Zookeeper
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/9ccd22c8-0207-3bf1-c6aa-4247fd2d70a7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/f55f6e92-3238-9f4c-877a-f63fe86db40a.png)