OmniAICreator/Qiita-1.07M huggingface dataset:
PHPでlz4を使う

# はじめに

PHPでlz4を使いって解凍したいという要望が社内で出た。
ただ、日本語の資料があまりにもないので個人的に備忘録としてまとめる。

## 書くこと

- PHPが動いてるサーバにlz4を入れて動かす方法

## 書かないこと

- PHP環境のサーバの構築


# lz4とは？

- [リンク](http://lz4.github.io/lz4/)
- [2016年のOSS圧縮ツール選択カタログ](https://qiita.com/nishemon/items/818cc64dc2f8577edd87)（ちょっと古いですが）

簡単に言えば優秀な圧縮ツール。

# 手順

```bash
$ yum install lz4
$ yum install lz4-devel

$ yum installed list | grep lz4

# lz4.x86_64                            1.7.5-3.el7                    @base
# lz4-devel.x86_64                      1.7.5-3.el7                    @base

$ yum --enablerepo=remi install php-lz4
```

これで基本的に必要なものは入る。

```bash
$ sudo systemctl restart php-fpm
```

これでプログラム内から`lz4_compress()`等の関数が呼び出せるようになる。
Intellij/WebStormでts-nodeデバッグ設定

デバッグ環境がわからなくなったのでメモ

Webアプリの起動ファイルはsrc/main.tsにしています。
`node --inspect --require ts-node/register src/main.ts`
nodemonを入れているなら

`nodemon --inspect --require ts-node/register src/main.ts`

これで


```
$ node --inspect --require ts-node/register src/main.ts
Debugger listening on ws://127.0.0.1:9229/977cea48-33da-4f31-86ad-9f7a465a4429
 
Server listening at port 3000
```

などと表示され、9229ポートでデバッガーが動くようです。

このあと、爆速で設定

Intellij/WebStormで

1. 上部のパネルから'Edit Configuration'を選ぶ。

![191024-0002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80546/008ca813-c358-b195-ff2d-7e68d15d2e0d.png)

2.左にTemplatesの選択があるので、そこで"Attach to Node.js/Chrome"を選択

 ![191024-0003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80546/04ae1f1a-bdfc-d918-ac87-d558fd3770c7.png)

3. このままの設定でOKなのでデバッグ設定に追加.

![191024-0004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80546/6f0c3a39-4b27-b1b2-bb11-4bf17b0eb238.png)


- アプリを起動した状態でデバッガーボタン（虫の形ボタン）を押すと、Intellij上でブレークポイントが設定できデバッグできます。
AWS CLIを使ってAmazon SNSからPushKitのVoIPプッシュ通知を送る

# これはなに

AWS CLIを使ってAmazonSNSからiOSのVoIPプッシュ通知（PushKit通知）を送る手順について、主にデバッグ用途です。
当方、AWSに詳しくないので内容に誤りがある場合はご指摘ください。

# 準備

+ AWS CLIをインストールする
+ AmazonSNS full access権限のあるIAMを払い出す（もしくは最小限のアクセス権限）
+ 環境変数にIAMの情報をセットする
 
```
# env | grep AWS
AWS_SECRET_ACCESS_KEY=XXXXX....
AWS_DEFAULT_REGION=ap-northeast-1
AWS_DEFAULT_OUTPUT=json
AWS_ACCESS_KEY_ID=YYYYY...
```

# エンドポイントの登録

試験用であればAmazonSNSのGUIから登録すればよい、手順は省略。

注意点とし、手元の環境では東京リージョンに登録したエンドポイントへはcliから送信できなかった。米国東部 (バージニア北部)にアプリケーションを作成して登録したら送信できた（要調査）。

# aws cli からVoIPプッシュ通知を送る

## 開発環境（sandbox）の例

endpointのarnが `arn:aws:sns:us-east-1:xxxxxxxxx:endpoint/APNS_VOIP_SANDBOX/your_app_name/yyyy....` の場合のコマンド

```
aws sns publish \
--target-arn arn:aws:sns:us-east-1:xxxxxxxxx:endpoint/APNS_VOIP_SANDBOX/your_app_name/yyyy.... \
--message-attributes \
'{ "AWS.SNS.MOBILE.APNS.PUSH_TYPE":{"DataType":"String","StringValue":"voip"}}' \
--message '{"APNS_VOIP_SANDBOX":"{\"aps\":{\"foo\":\"bar\"}}"}' \
--message-structure json
```

ポイントは

- `--message-attributes` で `"AWS.SNS.MOBILE.APNS.PUSH_TYPE":{"DataType":"String","StringValue":"voip"}` を指定すること
- `--message` で `APNS_VOIP_SANDBOX` キーに `aps` を含むデータを入れること

## 本番環境の例

基本的に開発用の場合と同じ、ただし `APNS_VOIP_SANDBOX` を `APNS_VOIP` に変更すること。

# 要調査

- 東京リージョンに登録した場合にcliで送信できない件、仕様なのか手順ミスなのか

# 参考情報

https://docs.aws.amazon.com/sns/latest/dg/sns-send-custom-platform-specific-payloads-mobile-devices.html#mobile-push-send-message-apns-background-notification

https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns
データウェアハウス(DWH) / データレイク / データマート の違いって・・・

聞かれて説明が上手くできなかったので整理しておく備忘録。
S3, Redshiftの住み分けの考え方の整理にもできる。

#データレイク
　・元データ、ローデータそのまま
　・共有フォルダやS3, 場合によってはそのまま取り込む形でRDBMS(SQL Server, Oracle Database, ...) などに保管

#データウェアハウス(DWH) 
　・複数のデータを蓄積
　・意味のある形で保管(参照・結合、加工、・・・)
　・Redshift, RDBMS(SQL Server, Oracle Database, ...)などに保管

#データマート
　・特定の利用者、用途向けにデータを加工・蓄積
　・ExcelやBIツールを指すことが多くPower BI, Tableau, Qlikview, Qlik Sense などが代表例

定義上、最終的に利用者が見るものはデータマートとなる。
データマートに至るまでの途中過程は環境によってバラバラだと思う。
大規模日本語ビジネスニュースコーパスを学習したXLNet（MeCab+Sentencepiece利用）モデルの紹介 

#はじめに
以前、日本語の[BERT事前学習済モデル](https://qiita.com/mkt3/items/3c1278339ff1bcc0187f)と[ELMo学習モデル](https://qiita.com/mkt3/items/9577b63900109ff91665)の紹介記事を投稿しましたストックマークの森長です。
モデル公開の記事を多くの皆様に読んでいただき、ありがとうございます。

昨今の自然言語処理界？では、事前学習モデルであるBERTの登場を皮切りに、XLNet、RoBERTa、ALBERTと多数のモデルが提案され、SOTAを競いあい、大いに盛り上がっています！
ですが、最先端のモデルは英語や中国語で事前学習されたモデルが多く、日本語で試すにはハードルがかなり高いと感じています。
そこで、今回はBERT、ELMoに続いて、XLNetの日本語事前学習済モデルを公開いたします。

#XLNetとは
XLNetとは、自己符号化ベースであるBERTの以下懸念点を解消するために作られた、自己回帰ベースのモデルです。

- BERTの[MASK]トークンは、fine-tuningの時に使用しないためpre-trainingとfine-tuningの学習に差異が生じる
- 予測対象の単語が複数あった場合、BERTは、自己回帰モデルのように予測対象の単語間の依存関係を考慮できない。
    - 【原文】： New York is A city.
    - 【BERTのMLM】：[MASK] [MASK] is A city. (NewとYorkの依存関係を学習できない)

XLNetの論文やアルゴリズム等の紹介はとても丁寧に解説していただいている記事が多数ありますので、それらの記事を読んでいたただけると良いと思います。私も大変お世話になっています。

XLNetは、通常の自己回帰モデルとは異なり、単語の予測順序の入れ替えを行い、順方向・逆方向両方の依存関係を学習できるようにしたことがとても注目すべき点だと思います。

# 弊社のXLNet事前学習済モデルの特徴
## 学習元データ
以前公開しましたBERTの事前学習済モデルと同様に学習用データを日本語ビジネスニュース記事としています。そのため、本モデルは、主にビジネスに関するドメインで効果を発揮します。

## tokenizer
弊社では、tokenizerにMeCab + NEologd及びSentencepieceを利用して、文章をトークン化しています。
まずMeCabを利用することで形態素として正しく分割し、その上でSentencepieceを行うことで、語彙のカバー範囲を広げています。

## 文字コード
XLNetの[公式github](https://github.com/zihangdai/xlnet)では、正規化手法としてNFKDを採用しています。そのため、公式githubのライブラリをそのまま使用すると、日本語の濁点・半濁点がロストしてしまいます。
日本語では、濁点・半濁点の有無で意味が変わる可能性もありますので、弊社ではNFKD及びNFKCで正規化した2つのモデルを作成しています。

例)
[原文]ストックマーク社が新サービスを発表した
   →[NFKDで正規化すると]ストックマーク社か新サーヒスを発表した (公式ライブラリを利用)
   →[NFKCで正規化すると]ストックマーク社が新サービスを発表した (公式ライブラリの正規化をNFKCに変更)

## 事前学習済モデルの詳細
| 事前学習用データ | トークナイザー | 語彙数 | 正規化| シーケンス長|
|:--|:--|:--|:--|:--|
|日本語ビジネスニュース記事(300万記事)| MeCab +  NEologd 及び Sentencepiece | 32,000語 | NFKD(公式の正規化)| 128 |
|日本語ビジネスニュース記事(300万記事)| MeCab +  NEologd 及び Sentencepiece | 32,000語 | NFKC| 128|

#ダウンロード
[公式(TensorFlow)](https://github.com/zihangdai/xlnet)と[PyTorch版](https://github.com/huggingface/transformers)で利用可能なモデルを公開します。

[ダウンロードリンク](https://drive.google.com/drive/folders/1ot_a417j6QQxUa8Et4WVVfNtkE-xI1Fp?usp=sharing)
モデルの内訳は以下の通りです。(NFKD及びNFKCのディレクトリ構成は同様です)

- TensorFLow版
 - model.ckpt.meta、 model.ckpt.index、 model.ckpt.data-00000-of-00001
 - config.json
 - spiece.model (Sentencepieceのモデル)
- PyTorch版
 - pytorch_model.bin
 - config.json
 - spiece.model (Sentencepieceのモデル)

#利用方法
事前学習済モデルの使用にあたっては、TensorFlow版及びPyTorch版で公開されているサンプルスクリプトで動作しますが、以下のようにスクリプト及びライブラリを修正してください。

- 入力データ(入力文章)をMeCab+NEologdでわかち書きしてください。
- NFKC版を利用する場合は、各ライブラリ(TensorFlow版及びPyTorch版)のnomalizeをNFKDからNFKCに変更してください。(ライブラリのコードの位置はバージョンによって変わってしまうので、grepでNFKDを検索して場所を特定したほうが良いかもです)

# XLNetの日本語事前学習済モデルを利用した所感
## BERTとの比較
弊社の検証用タスク（記事の分類）においてはBERTを1%程度下回る性能となっていました。
また、自己回帰モデルの特性上、BERTと比較して計算時間も増加しており、利便性も低下しています。
とはいえ、単語間の関係性が重要になるタスク（固有表現抽出等）に対して適応した場合は違った結果が期待できるため、今後はそれらのタスクで検証を行っていきます。

## NFKDとNFKCの比較
NFKD版とNFKC版の精度を比較しましたが、精度に大きな差はありませんでした。
濁点・半濁点がロストしても以下の理由で精度が変わらないのでは無いかと考えていますので、今後検証していきます。

### が→か 、で→て 等の助詞でのロスト

  助詞のため、タスクの精度向上に大きく寄与しない可能性がある。

### サービス→サーヒス 等の一般名詞や固有名詞でのロスト
  濁点・半濁点がロストしても、ほとんどの単語で、単語としては一意のままなので影響がない。濁点・半濁点がロストして違う意味になる単語ならば影響があると考えられる。

#まとめ
検証中の内容が多い中、最後までお読みいただき、ありがとうございました。
BERT、ELMoと同様に公開したXLNet事前学習済モデルが、自然言語処理の盛り上がりに少しでも貢献ができると大変嬉しいです。
セマンティックとは

# 序文
SQLを「エス・キュー・エル」って発音で会話しております。
新人の頃「シークェル」って発音が正しいと教わりましたが、
その方はすぐに居なくなり結局「エス・キュー・エル」って発音で会話しております。
最近になって「シークェル」って発音を周りで聞くようになり、変えようかと検討してます。

NoSQLの製品やらサービスやらを扱う様になって
「ノットシークェル」って流暢な発音されたときには本気で発声の変更を考えました。

# 用語
## NoSQL
Not only SQLの略
「Key Value Store」が出来るデータストアだと思ってたのですが、
RDBMSに対して他にも色々な利便性が有ることを知りました。

RDBMS以外のDBをNoSQLとカテゴライズされているんですね。
業務で「セマンティック」って概念を取り扱うことになったので、何者なのかを探ってみました。

## RDFトリプル
RDFは資源を説明するフレームワーク
コンピュータ上で扱う情報に意味情報を持たせて表現する為の概念。 
主語、述語、目的語で構成されているためトリプルと呼ぶ。

## セマンティック
トリプルの集合体 
トリプルを関係付けてさらに意味を詳細化する概念。 

# 人に説明する場合
私がDBといえば「RDBMS」「ER図が必要」って観点で長年生活していたので、
NoSQL的なデータストアについてはちんぷんかんぷんでした。

## RDBMSとの比較
「カラムベースではない」「レコードセットを持たない」って説明されると大混乱。
「正規化しないでデータを格納してます」って事で「レコードセット」については何となく理解できた。
比較的オブジェクト指向に近いデータストアと言われると解りやすかった。

## 開発者的な視点
オブジェクト指向開発でRDBMSを使ってる人から見ると設計手法がかなり変わる
 * O/Rマッピング不要
 * 精緻なER図の定義不要
 * SQL的なデータ取得も可能

## エンドユーザへの説明
「コンピュータ上では文字列は文字列としてしか認識してなく、 
その文字列に意味を持たせたのがセマンティックって概念」
相手の頭上に「？？？」が確かに見えました。

言葉で説明することは今の私には出来ませんでした。
トリプルの具体例を幾つか挙げてセマンティックグラフを見せて説明することで理解してもらえた。
多分。。。

# あとがき
セマンティックについて今の理解を吐きだしてみました。
最後になりますが、このページ見るぐらいならWikipedia見たほうが遥かに良いです。
[SQL]色々、SQLクエリの小技集

#####1.DATETIME(created_at, "Asia/Tokyo)で、UTCをJSTに変換できる。




#####2.例えばTable名が
`xxx.xx_xx.20190001`
`xxx.xx_xx.20190002`
の様に連番になっていて、その複数を指定したい時。

FROM `xxx.xx_xx.2019*`の様にして
WHERE _TABLE_SUFFIX = "0001"
の様に指定できる。

WHERE _TABLE_SUFFIX = BETWEEN "0001" and "0004"の様にもできる。



#####3.WHERE カラム名 IN (xxx, yyy, ...)で、そのカラムのある値だけを抽出出来る。

#####4.SUM(CASE WHEN xxx = "aaa" THEN 1 ELSE 0 END)
意味xxxの列がaaaであれば、1。それ以外であれば0と変換する。そしてその変換されたものの合計を出す。
→ある列の中の特定の要素だけカウントしたいときに便利

#####5.WINDOW関数の注意点
LAST_VALUEを使うときにはROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWINGを最後につけなければならない。
どうしてかというと、`over`内のクエリのデフォルトは、一つ目から自分までしか調べないことになっているから。LAST_VALUEは、自分より比べたいものが後ろにありますよね（並び方にもやりますが）だから、先程の一文を入れないといけないのです。
例文
`LAST_VALUE(status)OVER(PARTITION BY id ORDER BY created_at ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOING)`

→これがめちゃ詳しい
https://qiita.com/namachapanda20/items/1b3ee91759f040738ac1


https://prestodb.github.io/docs/current/functions/window.html
https://support.treasuredata.com/hc/ja/articles/216392117-Window-関数を使いこなす-集約関数系-


#####6.UTCとJST
https://qiita.com/ool/items/6be9cc290c8ad9e0f5bc
UTC 協定世界時　　UTC + 00:00

JST 日本標準時 UTC + 09:00
例えば
https://www.jisakeisan.com/?t1=utc&t2=jst!

[スクリーンショット 2019-10-24 15.08.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278640/1864f1e7-bcb6-b863-7dcf-d68215f2265b.png)


#####7.BIGQUERYショートカット
https://qiita.com/ool/items/9ec04c413622b0c2bfbf
command e で、選択部分の部分実行が可能。中間テーブルの中身を調べる時とかに便利。
command return で全体の実行が可能


#####8.NULLと０
特にCASE WHEN xxx THEN xxx ELSE NULL or 0 END
のところとか、間違えない様に。





-----------------------------------------------------------

UTCとJST
https://qiita.com/ool/items/6be9cc290c8ad9e0f5bc
今流行りの量子コンピューター
[量子コンピューター]Qisikitでアダマールゲートを実装する
https://qiita.com/ool/items/1a5041edddc11b14efc0
[Qiskitのアカウント認証の仕方]Qiskit IBMQ プロバイダー
https://qiita.com/ool/items/e80c1266cda68984a103
Qiskitの使い方
https://qiita.com/ool/items/2227d2d515caa5087752
[量子コンピューター]Qiskit Tutorials
https://qiita.com/ool/items/2a5038df1471635d442c
ArduinoProIDEがデタヨ！(α版)

# 0.あいさつ
こんにちは
RHEMS技術研究室荒木です

つい先日ArduinoProIDE(α版)が発表されました
ですが重たいしArduinoは認識されないわでわやだったので書こうか迷っていたのですが、若干安定してきたのでまとめます

#目次
1.どこでダウンロードするの？
2.なにが変わるの？
3.で、使いやすいの？
4.もしかしてこれってVSC...?


#1.どこでダウンロードするの？
現在2019/10/24の段階では0.0.1α版までがリリースされています
https://github.com/arduino/arduino-pro-ide/releases
ここから最新版をダウンロードできます
お使いの環境にあったものをダウンロードしてください
自分はMacを使っていますが、ダウンロードが驚くほど重たいので気持ちと時間に余裕があるときにダウンロードすることをおすすめします
Win版Linux版はわからないですが多分Mac版同様重たいと思います・・・


#2.なにが変わるの？
現状のバージョンとα版を並べて見てみましょう
<img width="1920" alt="スクリーンショット 2019-10-24 16.57.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269207/b8c733a6-ccce-4eab-6782-f15f93803b35.png">

左が現行バージョン、右がα版です
まず注目すべきなのがα版にミニマップが標準搭載されていることですね
まあただビジュアルでの変更ってこのぐらいなんですけどね。

あと地味なところなのですが個人的に嬉しいのが、全画面表示になることですね
現行バージョンだと全画面表示にならなくてただ大きくなってしまうだけなのでウィンドウを移動したいときに背面にデスクトップが隠れてしまうのがとてもストレスだったのですが、α版ではしっかりと全画面になるのでウィンドウ遷移が楽チンになりました(伝われこの気持ち)

ビジュアル以外にももちろん変更はあります
現行バージョンの設定よりも詳細にエディタをカスタマイズできるようになりました
preferenceの場所が現行バージョンと変更になり見つけにくいですがきちんとあります
上タブのメニューより、**File→Settings→Open Settings**で設定のタブがひらきます
<img width="412" alt="スクリーンショット 2019-10-24 17.33.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269207/47f520a4-4573-5c1f-245f-faa783b6e3d5.png">
こんな感じ
で、開くと設定項目がずらっと並びます
<img width="1919" alt="スクリーンショット 2019-10-24 18.12.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269207/0688060c-07b2-c5d2-2b5d-4e42f398fb1a.png">

右の**User**では変更した項目が追加されていきます
ちなみに、初期設定のままでも一回でも変更したら追加されてしまうのでよくわかんない項目は触らないほうがいいかも。(変更した項目がわかりにくくなるからね)
さらっと見た感じフォントやフォントサイズ、Tabの広さといった基本的な設定項目もありました
ミニマップの非表示もここから設定できますし、表示される場所や大きさも変更出来ました
なにげに嬉しいのは**wordWrap**です
wordWrapは１行に収まりきらないときに自動でいい感じに改行してくれる機能です

オートセーブも追加されたので不慮の事故でPCが落ちてしまった場合も安心です

あとの設定項目はご自身でご確認ください！


#3.で、使いやすいの？

現状のバージョンと比べると**とても**使いやすいです
標準で複数のてテーマが内蔵されているので気分を変えたいときに変更できるのも嬉しい
<img width="1920" alt="スクリーンショット 2019-10-24 19.30.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269207/881f6c7a-b9c6-e385-b679-d02f216bb685.png">



#4.もしかしてこれってVSC...?
ProIDEがElectronを元にしているということもあり、VisualStudioCodeのArduino拡張をいいとこ取りしてまとめたものな気がします
なのでVSCをお使いの皆さんはわざわざProIDEに移行する必要はないかな
現状のバージョンをお使いで"なんか使いにくいなぁ"って思っている方にはとてもおすすめできます


#5.さいごに
ProIDEはまだα版なので現行バージョンと競合して環境が壊れたら嫌だな、と思う方はまだおすすめしません
ですが、GA版が出たときには一度触ってみることをおすすめします

触り始めてまだ日が浅いので間違いや指摘等あればお願いします。
Node.jsでWebSocketサーバをUnixドメインソケットで立てる

Node.jsで[ws]パッケージのWebSocketサーバをUnixドメインソケットでlistenする方法です。サンプルコードはTypeScriptです。

[ws]: https://www.npmjs.com/package/ws

## Unixドメインソケットを使ったWebSocketサーバを立てるコード

Serverクラスのコンストラクタの`server`オプションに`http.Server`のインスタンスを渡すのがミソです。

```typescript:server.ts
import websocket from 'ws'
import http from 'http'
import fs from 'fs'

// UnixドメインソケットでWebSocketを待ち受けるHTTPサーバー
const hs: http.Server = http.createServer()

// WebSocketサーバー (いわゆるechoサーバーです)
const wss = new websocket.Server({server: hs}) // 最重要
wss.on('connection', ws => {
  ws.send('hello, this is websocket echo server.')
  ws.on('message', message => {
    ws.send(message) // オウム返し
  })
})

// Unixドメインソケットのファイル名
const socketPath = '/tmp/server.sock'

// UnixドメインソケットのファイルがあるとHTTPサーバが起動しないので必ず削除する
fs.existsSync(socketPath) && fs.unlinkSync(socketPath)

// HTTPサーバのlistenを開始する
hs.listen(socketPath, () => {
  console.log(`websocket server listening on ${socketPath}`)
})
```

## WebSocketサーバーと話してみる

WebSocketサーバと話すには、[wscat](https://www.npmjs.com/package/wscat)というWebSocket CLIクライアントが便利です。

Unixドメインソケットではない、普通のTCPのWebSocketと疎通するには、`npx wscat -c ws://echo.websocket.org`のように、URLを`ws://`で始めますが、Unixドメインソケットでは、URLスキーマの部分が`ws+unix://`になります:

```bash
$ npx wscat -c ws+unix:///tmp/server.sock
Connected (press CTRL+C to quit)
< hello, this is websocket echo server.
> てすと
< てすと
>
```

## 参考文献

* [ws.ServerのAPIドキュメント](https://github.com/websockets/ws/blob/HEAD/doc/ws.md#new-websocketserveroptions-callback)
* [node.js - WebSockets listening on UNIX domain socket? - Stack Overflow](https://stackoverflow.com/questions/23930293/websockets-listening-on-unix-domain-socket)
[Rails] NameError in MessagesController#index  uninitialized constant Message::ImageUploader エラー


目的：
CarrierWave・Imagemagickというgemを使い、画像送信できる機能をつけたい！
しかし標題エラーが出たので解決したい。

結論：rails sでサーバー再立ち上げしたところ解決。
他解決案：
・ターミナル：brew install imagemagickでimagemagickを再インストール→bundle update
・ターミナル：spring stop、　spring startでspring再起動
参考URL: https://qiita.com/yokoyan/items/0f82fc3eede75cd6db55

★下記コード入力後、

```
class Message < ApplicationRecord
  belongs_to :group
  belongs_to :user
  validates :content, presence: true, unless: :image?

  mount_uploader :image, ImageUploader
end
```


localhost立ち上げたら、こちらのエラーが出ました。

```
NameError in MessagesController#index  
uninitialized constant Message::ImageUploader 
```

エラー要因：
コードの記述自体はあっていたが、imagemagickがうまくインストールされてなかった。
そこで、再度　brew install imagemagickでインストールし直したが、serverを再度立ち上げてなかったのでその内容が読み込まれてなかった。

学んだこと：
configやgemなどはインストールし直したりすると、その変更内容がサーバー上に反映されてなかったりするので、rails sでサーバー再度立ち上げるのが大事。
MacとPythonとRealSenseとOpenCVでリアルタイム顔検知

#RealSenseD435iを触ってみたのでMacでPythonからRealSenseSDKを扱う方法について書く
ひとまず動いたので記念に。
例のごとく記憶を頼りに書くので、漏れてる点などあるかも。

## 前提
* macOS Mojave
* Python 3.7.4
* OpenCV 4.1.1
* pyrealsense2

## 準備
1. Python3のインストール
2. JupyterLabのインストール(https://jupyterlab.readthedocs.io/en/stable/#)
3. OpenCVのインストール
`pip3 install opencv-python`
4. pyrealsense2のビルド、インストール

ここが一番大変。
https://github.com/IntelRealSense/librealsense/tree/master/wrappers/python
からソースコードをCloneして、cmakeします。
上記URL中にpipのインストールコマンドが提供されているような記載がありますが、**MacOSは現時点対応されていません。**自力でビルドあるのみです。

ビルドしたら、PATHの設定などを実施。自分はzshなので、`vi ~/.zshenv`で。
また、`librealsense/build/tools/realsense-viewer`に`realsense-viewer`があるのでこれを実行できればビルドが成功していることを確認できます。

インストールしたら`librealsense/wrappers/python/examples`にサンプルコードがありますので、その中から、`opencv_viewer_example.py`を実行してください。
実行できれば、Python3環境にPyrealsense2がimportできることを確認できます。

場合によっては、Python環境へ`.so`ファイルのシンボリックリンクを手動で配置する必要があるかもしれません。

## OpenCVとの連携
まず、JupyterNotebook上からもimportができるか確認しておきます。

```python:importtest.py
import cv2
import pyrealsense2 as rs

print(cv2)
print(rs)
```
早速、Pyrealsense2のサンプルコードと、OpenCVのサンプルコードを組み合わせて、コードを書きます。

```python:importtest.py
import numpy as np
import cv2
import pyrealsense2 as rs

face_cascade = cv2.CascadeClassifier('/usr/local/lib/python3.7/site-packages/cv2/data/haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('/usr/local/lib/python3.7/site-packages/cv2/data/haarcascade_eye.xml')
 
# Configure depth and color streams
pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)

# Start streaming
pipeline.start(config)

try:
    while True:

        # Wait for a coherent pair of frames: depth and color
        frames = pipeline.wait_for_frames()
        color_frame = frames.get_color_frame()
        depth_frame = frames.get_depth_frame()
        
        if not depth_frame or not color_frame:
            continue

        img = np.asanyarray(color_frame.get_data())
        depth_img = np.asanyarray(depth_frame.get_data())
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        
        depth_colormap = cv2.applyColorMap(cv2.convertScaleAbs(depth_img, alpha=0.03), cv2.COLORMAP_JET)
        
        faces = face_cascade.detectMultiScale(gray, 1.3, 5)
        for (x,y,w,h) in faces:
            img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
            roi_gray = gray[y:y+h, x:x+w]
            roi_color = img[y:y+h, x:x+w]
            eyes = eye_cascade.detectMultiScale(roi_gray)
            for (ex,ey,ew,eh) in eyes:
                cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)

        images = np.hstack((img, depth_colormap))

        cv2.imshow('img',images)
        cv2.waitKey(30)
        cv2.destroyAllWindows()
    
finally:

    # Stop streaming
    pipeline.stop()
```

理由はわかりませんが、`cv2.waitKey(30)`の数値の部分を小さくすると、異常終了しやすくなります。（気のせいかも）

## 終わりに
これだけで、RGB画像と、深度画像を同時表示させつつ顔認識を実施するアプリを実装できました。
OpenCVとPyrealsense2を勉強すれば、Open3Dなどと組み合わせてPointCloudを表示したりすることができるはずです。
今後挑戦していきます。
コンテナ基礎 Dockerとkubernetes

#####はじめに
コンテナの基礎勉強会の内容メモです。

## コンテナ
OSSの仮想化技術。

##docker
アプリケーションの動作環境をコンテナにデプロイするための単位。
VMと比べて軽量で高速。

##コンテナへデプロイの流れ
１．コンテナを定義（DockerFile)

２．コンテナをDockerFile通りに作成、保管。

３．Dockerのimageから起動

##VMとの違い
OSの上にHypervisorが存在せずカーネルが存在する。コンテナにはOS自体はなく一つのサーバの上でライブラリのようにLinuxやWindowsが動く。

##メリット
・アプリケーションの環境差異を減らせる。
・テスト環境では動くが本番環境で動かないという事態を防げる。
・環境構築やセットアップの手間を減らせる。

##kubernetes
1つのホストではなく複数のホストで動かしたい場合

・docker-composeを使う方法
単一のホストで複数のコンテナを組み合わせて実行する仕組み
のdocker-composeだと自動復旧やアップデートができない。

・kubernetesを使う方法
kubernetesは複数のホスト上でコンテナを適切に動かし自動復旧できる。

##開発側のメリット
OS以下の層に過度な注意を向けることなく開発に専念できる。
ただしコンテナの中のソースコードやミドルウェアは意識しなくてはならない。

##コンテナを用いた設計
・ステートレス
コンテナが停止した場合も想定してにコンテナの外にセッションやファイルを管理する。
・1つのコンテナに1つの役割
tomcat,apache,mysqlなどそれぞれを別のコンテナに管理しなくてはならない。

##例え
コンテナはレトルトや冷凍食品のようにいつでもどこでも同じ味で簡単に作れる。
自分で環境構築する場合は１からチャーハンを作るようなもの。
Salesforce で Excel出力

Salesforce でExcel帳票出力するにあったって。

あまり調べても出てこなかったこと。

そもそも。

結局のところHTMLをExcelに張り付けている。なので。

・　HTMLに、数式を書けば、一度保存は必要だけど、数式は有効になる。

・　数値フォーマットは、Apexにお任せするよりは、View側のExcelで操作したほうが、
　　結局面倒がないので、以下を利用

mso-number-format:\0022￥\0022\#\,\#\#0;

・　結合セルに表示する文字列を縮小して全体を表示

white-space:nowrap;mso-text-control:shrinktofit;
Azureリソースの最適化をお助け　Azure Advisorの強化

# はじめに
この記事はこの記事はマイクロソフトが2019/10/16に発表した["Azure Advisor cost recommendation enhancements"](https://azure.microsoft.com/en-us/updates/azure-advisor-cost-recommendation-enhancements/)の要約記事です。

この記事では、始めに今回の発表のハイライトを紹介し、Azure Advisorの基礎的な内容について述べていきます。

# 今回の発表のハイライト
今回強化されたのは使用率の低い仮想マシンの推奨が強化されました。
これにより、コストを効率的に最適化することができます。
- Advisorは、7日間の仮想マシンの使用状況を監視し、使用率の低い仮想マシンを特定します
    - Advisorが使用率が低いと判断する基準は以下
        - CPU使用率が5％以下で、ネットワーク使用率が2％未満であり、メモリ負荷が閾値である場合
        - 現在のワークロードをより小さな仮想マシンサイズで収容できる場合
    - 推奨されるアクション（例えば仮想マシンのサイズ変更やシャットダウン）を実行した時の推定コスト削減量を表示
    - 仮想マシンのサイズ変更の際に推奨SKUを提供

# Azure Advisorとは
Azure Advisorとは利用者の使用状況などに基づいてAzureデプロイメントを最適化するクラウドコンサルタントです。
Azureのリソース構成と利用統計情報を解析し、Azureリソースの費用対効果・パフォーマンス・高可用性・セキュリティの向上に役立つ情報をダッシュボード上に表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174954/847523cb-4612-2e78-a777-188c52c7fdec.png)
(この画像は[こちら](https://docs.microsoft.com/ja-jp/azure/advisor/advisor-overview)から引用させていただきました）

# おわりに
この記事はこの記事はマイクロソフトが2019/10/16に発表した["Azure Advisor cost recommendation enhancements"](https://azure.microsoft.com/en-us/updates/azure-advisor-cost-recommendation-enhancements/)を要約しました。
Azure Advisorを活用して、よりAzureデプロイメントを最適化していきたいですね。
Rubyの基本箇所についての復習③(gets.chomp)

#はじめに
[前回](https://qiita.com/Moon1126Snow/items/d2c0896ea076587eccc0)に引き続き、Rubyの基礎について書いていきます。
#内容
変数をいちいちコードに書かなくて済むようにします。
#実行
前回は変数を使った、文章の出力について書かせていただきました。
もし'私の趣味は読書です'という文章を出力したい場合は、

```ruby
hoby = "読書"
puts "私の趣味は#{hoby}です"
```
とすれば良いのでした。

しかし、これでは違う文章を出力する場合は、その度にコードを書き換えなくてはいけません。
そこで、今回は```hoby```の中身をコードに書くのではなく、ターミナルから直接入力するようにします。

直接入力するには、```gets.chomp```というメソッドを使えばいいです。
これを使ってコードを書き換えると、

```ruby
hoby = gets.chomp.to_s
puts "私の趣味は#{hoby}です"
```


`gets.chomp`の後に`.to_s`が追加されていますが、これは「文字のみを入力する」という事になります。
仮に数字を入力しても、文字として扱われます。
ちなみに、数字のみを入力したい場合は`.to_i`を追加します。

このコードを書いてプログラムを実行すると、ターミナル上で文字を入力できるようになります。
ここで例えば'旅行'と入力してみると、'私の趣味は旅行です'と出力されます。

この状態だと、入力する際に何も表示されず、入力していいのかどうかわかりにくいので、コードを以下の様に書き換えます。

```ruby
puts "あなたの趣味はなんですか？"
hoby = gets.chomp.to_s
puts "私の趣味は#{hoby}です"
```

このプログラムを実行すると、'あなたの趣味はなんですか？'と出力され、先ほどと同じように文字を入力できるようになります。
このように、良いプログラムを書くためには、使い手の使いやすさを考える必要も出てきます。

#終わりに
ここまで変数の使い方を見てきましたが、現状では一つの変数に一つの値しか代入できていません。
しかし、変数には一つだけでなく、もっと多くの値を代入することができます。
次回はその方法について書いていきたいと思います。
R8C/M120ANを用いたLEDの点灯プログラム

R8C/M120ANを用いたLEDの点灯プログラムです。

スイッチを2個用意し、
・SW1を押したら右シフト
・SW2を押したら左シフト
上記動作を実現します。


▼詳細設定▼
・8個のLEDを使う
・初期状態は、一番右から4番目のLED4のみ点灯
・並びはこれ↓
LED8 ← LED7 ← LED6 ← LED5 ← LED4（初期点灯） ← LED3 ← LED2 ← LED1


▼注意事項▼
・右端（LED1）点灯時にSW1を押下しても無効。LED1点灯状態が維持される。
・左端（LED8）点灯時にSW2を押下しても無効。LED8点灯状態が維持される。


```
    .INCLUDE   sfr_r8m12a.inc
    .INCLUDE   initial.inc
    .SECTION   PROGRAM,  CODE
    .ORG       0F800h

MAIN:
    BSET      prc0
    BSET      ckpt0
    BSET      ckpt1
    NOP
    NOP
    NOP
    NOP
    BSET     scksel
    BCLR     prc0

;I/O初期設定

    MOV.B    #0FFh, pd1
    MOV.B    #00h,  pd3
    MOV.B    #08h,  p1

MAIN_LOOP:
    BTST     p3_3
    JNZ      SW1_ON
    SHL.B    #-1, p1

    JMP      LOOP_END

SW1_ON:
    CMP.B    #01h, p1
    JZ       LOOP_END
    SHL.B    #-1, p1

    JMP      LOOP_END

SW2_ON:
    CMP.B    #80h, p1
    JZ       LOOP_END
    SHL.B    #1, p1

    JMP      LOOP_END

LOOP_END:
    JMP     MAIN_LOOP

   
```
【Ruby】配列に入れるハッシュを使いまわしてみた

#この記事でしていること
配列の中にハッシュを入れる際、奇妙な挙動をしたのでそれについて検証しました。
具体的には配列に対してハッシュを追加した後、ハッシュの中身を変更して再度配列に追加しました。

中身を変更する前に空のハッシュを再宣言しなかったらどうなるか？が今回の記事になります。

#経緯
Rubyの簡単な記述を練習していた時に

1. 配列を宣言
2. ハッシュを宣言
3. ハッシュに中身を追加
4. ハッシュを配列に入れる
5. 空のハッシュを再度宣言
6. ハッシュに中身を追加
7. ハッシュを配列に入れる

という一連の流れの中で「5.は削れるのでは？」と思い実際に削ってみました。
すると期待している動きと違っていた・・・どころか謎の挙動をしていたので、検証してみました。

#再現
###Before
配列の中にハッシュを入れる際は下記のような手順を踏んでいくことが一般的かと思います。

```ruby:test.rb
# 空の配列とハッシュを宣言する
array = []
hash = {}

# ハッシュに【キー:num 値:1】を入れ、ハッシュを配列に入れる
hash[:num] = 1
array << hash

# 再度空のハッシュを宣言し、同じキーに別の値「2」を入れる
hash = {}
hash[:num] = 2
array << hash

# 配列の中身を出力
puts array
```
```irb:ターミナル
$ ruby test.rb
{:num=>1}
{:num=>2}
```

これが通常の結果です。
配列の中に一個目と二個目のハッシュが入っていることがわかります。

###After
続いて空のハッシュの宣言を抜いてみます。

```ruby:test.rb
array = []
hash = {}

hash[:num] = 1
array << hash

# ここでハッシュを宣言しない

hash[:num] = 2
array << hash

puts array
```

#####期待していた結果

```irb:ターミナル
$ ruby test.rb
{:num=>1}
{:num=>2}
```

#####実際の結果

```irb:ターミナル
$ ruby test.rb
{:num=>2}
{:num=>2}
```

**<font color="purple">前に入れた「1」はどこいった。
そしてなんで「２」は２つも入っとるんや・・・</font>**

#検証

###確認
まずは下記の時にどのような値が入っているのか確認します。

[1.] １つ目のハッシュを配列に入れた時
[2.] ハッシュの中身を入れ替えた時
[3.] 中身を入れ替えたハッシュを再び配列に入れた時

```ruby:test.rb
array = []
hash = {}

hash[:num] = 1
array << hash
puts array # [1.]
puts "---------------"

hash[:num] = 2
puts array # [2.]
puts "---------------"

array << hash
puts array # [3.]
puts "---------------"
```
```irb:ターミナル
$ ruby test.rb
{:num=>1} 
---------------
{:num=>2}
---------------
{:num=>2}
{:num=>2}
---------------
```
[2.]の結果を見てびっくりしました。
えっ・・・一度配列に入れたのにハッシュの中身を入れ替えたら配列の中の方も変わってしまうの・・・？
そして[3.]の結果を見ていただくとわかる通り、配列の追加をすると同じ中身でも配列内に積載されるため、結果として「{:num=>2}」が２つも入ってしまっていたようです。

###検証

結果は理解したけどまだちょっと納得いかない！
ということで検証してみました。

####検証1：空のハッシュを使わない

```ruby:test.rb
array = []

hash = {:num => 1}
array << hash
puts array
puts "---------------"

hash = {:num => 2}
puts array
puts "---------------"

array << hash
puts array
puts "---------------"
```

```irb:ターミナル
$ ruby test.rb
{:num=>1}
---------------
{:num=>1}
---------------
{:num=>1}
{:num=>2}
---------------
```
・・・あれ？うまくいったぞ

####検証2：変数


```ruby:test.rb
array = []

num = 1
array << num
puts array
puts "---------------"

num = 2
puts array
puts "---------------"

array << num
puts array
puts "---------------"
```
```irb:ターミナル
$ ruby test.rb
1
---------------
1
---------------
1
2
---------------
```

変数も期待通りの動きだ・・・

#考察
今回は配列の中身をハッシュと変数で試しましたが、検証の結果を踏まえた仮説は以下になります。

```ruby:
hash[:すでに配列に入っているハッシュのキー] = 値
```
<font color="red">→すでに宣言されているハッシュのキーの値の『変更』という扱いになってしまう</font>

```ruby:
hash = {:すでに配列に入っているハッシュのキーと同名のキー => 値}
```

```ruby:
変数 = 値
```
<font color="red">→上記はどちらもその都度ハッシュまたは変数を『新しく宣言』している扱いになるため、すでに宣言されたハッシュまたは変数の値には影響しない</font>

上記の違いがあったために期待した結果にならなかったのだと思いました。

#最後に
今回の内容はあえて通常しない記述をしているため、実務においてはあまり問題になることはないと思われますがQiitaの投稿練習も兼ねてまとめてみました。
内容に誤りがある場合やさらに詳しい情報をお持ちの方がいらっしゃいましたら教えていただけると嬉しいです。
今更聞けないAR/VR,分散処理,AI/機械学習/ディープラーニング,データサイエンス,IoTにお役所、総務省の資料が使えた件

#ありがとう総務省！
http://www.soumu.go.jp/ict_skill/
http://www.soumu.go.jp/ict_skill/pdf/ict_skill_c1_set.pdf
で一括PDFダウンロード（463ページ）するのも手。
今日まで知らなかったが日本のお役所のIT事業で民間がまともに使えるシステム、資料を初めて見た気がする。
今更恥ずかしくて聞けないNoSQL、分散処理（hadoop, spark, ...）、マシンラーニングやディープラーニングの手法の根幹、 Rのお話まで登場。これは使える！
最近時のテクノロジーの基本的事項の網羅性が高い！
Laravel のルーティングのまとめ方


Laravel5.8ですが、ほかのバージョンでも問題ないと思います。

#viewフォルダ

![SC000004.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/d008cb91-b2d1-51f6-0136-294e01ac67a4.jpeg)

#ルーティング
これをまずまとめずにルーティングすると、一般的にこのようになるではないでしょうか。
なお、私はルート名`(->nameの部分)`については、viewと合わせているので今回もそのように記述しています。

```php:web.php
Route::get('/main/list','MainController@list')->name('main.list');
Route::get('/main/edit','MainController@edit')->name('main.edit');
Route::get('/main/search','MainController@search')->name('main.search');
```

これを、`/main`部分が共通なので,`Route::prefix`を使いまとめることができます。

>prefixメソッドはグループ内の各ルートに対して、指定されたURIのプレフィックスを指定するために使用します。

```php:web.php
Route::prefix('main')->group(function () {
    Route::get('list','MainController@list')->name('main.list');
    Route::get('edit','MainController@edit')->name('main.edit');
    Route::get('search','MainController@search')->name('main.search');
});

```

これとは別にルート名でまとめると下記のようになります

```php:web.php
Route::name('main.')->group(function () {
    Route::get('/main/list','MainController@list')->name('list');
    Route::get('/main/edit','MainController@edit')->name('edit');
    Route::get('/main/search','MainController@search')->name('search');
});

```


ただ、URIでもまとめたくて、ルート名についてもまとめたい時や、ここに`middleware`が加わってそれでもまとめたい時があります。

その場合 `Route::group`が使えます。
>ルートグループは多くのルートで共通なミドルウェアや名前空間のようなルート属性をルートごとに定義するのではなく、一括して適用するための手法です。Route::groupメソッドの最初の引数には、共通の属性を配列で指定します。

下記のように、一つずつでも、複数でも使えるので、共通でまとめられる様なら積極的に使いたいところです。

```php:web.php
//複数(URI、ルート名)でのグループ化
Route::group(['prefix' => 'main', 'as' => 'main.'], function () {
    Route::get('list','MainController@list')->name('list');
    Route::get('edit','MainController@edit')->name('edit');
    Route::get('search','MainController@search')->name('search');
});

//URIでのグループ化
Route::group(['prefix' => 'main'], function () {
    Route::get('list','MainController@list')->name('main.list');
    Route::get('edit','MainController@edit')->name('main.edit');
    Route::get('search','MainController@search')->name('main.search');
});

//ルート名でのグループ化
Route::group(['as' => 'main.'], function () {
    Route::get('/main/list','MainController@list')->name('list');
    Route::get('/main/edit','MainController@edit')->name('edit');
    Route::get('/main/search','MainController@search')->name('search');
});

//ミドルウェアでのグループ化
Route::group(['middleware' => ['auth']], function () {
    Route::get('/main/list','MainController@list')->name('main.list');
    Route::get('/main/edit','MainController@edit')->name('main.edit');
    Route::get('/main/search','MainController@main')->name('main.search');
});

// whereもつかえる
Route::group(['prefix' => '{user_id}', 'where' => ['user_id' => '[0-9]+']], function () {
    Route::get('/edit','UserController@edit')->name('users.edit');
});

```

間違いや、より良い方法がありましたらご指摘宜しくお願いします。
cssでdiv要素を重ねることなく背景画像を透過する方法

こんにちは！さくです！

<br>
web制作をしていると

「背景画像を透過したいなぁ」とか「背景を薄くしたい！」

というシチュエーションに多く遭遇すると思いますが、google先生に方法を尋ねると【div要素を重ねて上から透過レイヤーを掛ける】という冗長な方法が散見されます。

background-imageは要素ではないのでopacityは適用されません。よって、ここでは**blend-mode**を活用します。

## サンプル

```:css-lighten-sample
background-image: url("room_syosai.png");
background-color: rgba(255, 255, 255, 0.8);
background-blend-mode: lighten;
```
>結果
![スクリーンショット 2019-10-24 15.37.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519143/67aa1466-bea6-76f0-16ef-cfc79d9a120b.png)

```:css-darken-sample
background-image: url("room_syosai.png");
background-color: rgba(0, 0, 0, 0.6);
background-blend-mode: darken;
```
>結果
![スクリーンショット 2019-10-24 15.38.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519143/41f5b840-4e80-6d96-64ea-52323450b2a2.png)

**blend-mode**とは事前に用意された背景色あるいは背景画像を効果を与えて合成する機能です。
たったの三行で背景透過が実現できました。div要素を使って〜よりかは遥かに少ない行数で望んだ結果が得られたかと思います。

<br>
またblend-modeには他にも十数種類のブレンド方式が存在します
blend-modeについて、詳しくはこちら

>HTMLクイックリファレンス様
http://www.htmq.com/css/background-blend-mode.shtml

## グラデーション

blend-modeとは違いますがグラデーションを重ねる方法も紹介したいと思います。

```:css-gradation-sample
background: linear-gradient(315deg, rgba(250, 68, 101, 0.6), rgba(105, 188, 200, 0.6)) ,url(room_syosai.png);
```
![スクリーンショット 2019-10-24 15.38.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519143/540b338b-7f7a-7c8f-7ca3-5c58dbecb41c.png)

**linear-gradient**を使ってたったの一行で画像にグラデーションを掛けることができました。


<br>
linear-gradientについて、詳しくはこちら

>MDN web docs様
https://developer.mozilla.org/ja/docs/Web/CSS/linear-gradient

##最後に

簡単に背景画像を透過する方法を紹介しました。どちらの機能もデザイン面の検証を行う際捗る機能です。
皆さんのweb開発の一助となれれば幸いです！

twitter→([@saku_nectaris](https://twitter.com/saku_nectaris))
フォローよろしくな！
Proxy環境下でWinSCPを使う

# Proxy環境下でWinSCPを使う

接続の設定で「編集」をクリックしたら「設定」を開く

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323052/0cec7203-f72b-9c4e-80e8-475c4a07e478.png)

「接続」の項目配下にある「プロキシ」を選択する
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323052/c069d6ec-f9e2-f9c4-d615-2ba12b3271c3.png)

各項目を入力し「OK」をクリック
コメントアウト

対象の箇所をドラッグして、command / で、一気にコメントアウトできる


----------------------------------------------------------
SQL小技集
https://qiita.com/ool/items/75da830e7373138c8125
UTCとJST
https://qiita.com/ool/items/6be9cc290c8ad9e0f5bc
今流行りの量子コンピューター
[量子コンピューター]Qisikitでアダマールゲートを実装する
https://qiita.com/ool/items/1a5041edddc11b14efc0
[Qiskitのアカウント認証の仕方]Qiskit IBMQ プロバイダー
https://qiita.com/ool/items/e80c1266cda68984a103
Qiskitの使い方
https://qiita.com/ool/items/2227d2d515caa5087752
[量子コンピューター]Qiskit Tutorials
https://qiita.com/ool/items/2a5038df1471635d442c
Nuxt.js(SPA) で Auth Module を使う際にページのルーティングでトークンの期限をチェックする

# 概要
Nuxt.js で SPA を作っていて、Auth Module を使って Azure AD のアプリケーションを OAuth 2.0 で認証しています。
ログイン時にアクセストークンを取得しますが有効期限が設定されているので一定時間経過後トークンが無効になります。
トークンを使った API 実行時にエラーとなってしまうので事前に検知したい。

# 対象環境
- Nuxt.js
  - 2.10.1
  - mode: 'spa'
- Auth Module
  - @nuxtjs/auth
  - 4.8.4
  - https://auth.nuxtjs.org/
  - 認証方法: OAuth2.0
  - 暗黙的なフローによるアクセストークン

# ミドルウェアの作成
アプリケーション内でルーティングされる場合(アプリ内でのページ遷移)にチェックしたいのでミドルウェアを作成していきます。
middleware ディレクトリに tokenCheck.ts という名前で作成しました。
認証チェックが必要な場合、保存されている JWT をデコードして `exp` の有効期限を取得します。
それを現在日時と比較して無効ならログイン画面にリダイレクトさせます。
リダイレクト先でログインすると本来表示したかったページが表示されます。

```typescript:middleware/tokenCheck.ts
import { routeOption } from '@nuxtjs/auth/lib/core/utilities';
// JWT のデコードに使用。jwt-decode, @types/jwt-decode のパッケージをインストールした。
import JWT from 'jwt-decode';

export default function(ctx) {
  // Auth Module が提供する middleware の設定を同じように参照する
  // https://auth.nuxtjs.org/guide/middleware.html
  // 各ページで auth:false の場合は処理しない
  if (routeOption(ctx.route, 'auth', false)) {
    return;
  }

  const $auth = ctx.$auth;
  if (!$auth.loggedIn) {
    ctx.$auth.redirect('login');
    return;
  }

  // キー名は strategies の設定によります
  const key = '_token.AzureAD';
  const token = ctx.$auth.$storage.getUniversal(key);
  if (JWT<any>(token).exp < new Date().getTime() / 1000) {
    ctx.$auth.redirect('login');
  }
}
```

# ミドルウェアの設定
作成したミドルウェアを設定に追加します。

```typescript:nuxt.config.ts
  router: {
    middleware: ['auth', 'tokenCheck']
  },
```

# 各ページの対応
認証が必要ないページやログインページなどは Auth Module の設定と同様に `auth:false` を指定します。

```vue
export default Vue.extend({
  auth: false,
  // ...
}
```

# まとめ
- ミドルウェアを使うことで各ページ表示前に処理を記述することができます。
- 今回の対応だと、フォームなどのページを開いて入力した後の POST。などは対応できていません。
  - 良いやり方があれば情報いただきたいです
- なんでもフィードバックお待ちしています!
[メモ]SHOW SLAVE STATUSで確認出来る項目(一部)

```
Master_Host ： マスタのホスト名
Master_User ： マスタへの接続に使用するユーザー名
Master_Port ： マスタのポート番号
Connect_Retry ： マスタと接続出来なかった場合にスレーブが再接続を試みるまでの待機秒数

Master_Log_File ： スレーブのI/Oスレッドが現在処理中のマスタのバイナリログ・ファイル名
Read_Master_Log_Pos ： I/Oスレッドが読み込んだマスタのバイナリログの位置

Relay_Log_File ： スレーブのSQLスレッドが現在処理中のスレーブのリレーログファイル名
Relay_Log_Pos ： SQLスレッドが実行完了したスレーブのリレーログの位置

Relay_Master_Log_File ： SQLスレッドが最後に実行したクエリが記録されていたマスタのバイナリログファイル名
Exec_Master_Log_Pos ： SQLスレッドが最後に実行したクエリのマスタのバイナリログでの位置

Slave_IO_Running ： スレーブのI/Oスレッドが稼働中か
Slave_SQL_Running ： スレーブのSQLスレッドが稼働中か

Replicate_Do_DB ： レプリケートするように指定されているDB名
Replicate_Ignore_DB ： レプリケートしないように指定されているDB名

Last_Errno ： 最後に実行したクエリのエラー番号。「0」なら成功
Last_Error ： 最後に実行したクエリのエラーメッセージなど。空文字はエラー無し

Skip_Counter ： 最後にSQL_SLAVE_SKIP_COUNTERを使用した時の値。使用がなければ「0」
Relay_Log_Space ： 存在するリレーログファイルのサイズ。単位はバイト
Seconds_Behind_Master ： I/Oスレッドに対してSQLスレッドの処理がどのくらい遅れているかを示す。単位は秒。マスタとスレーブとの間のネットワークが十分に早い状況下ならば、マスタに対してスレーブがどのくらい遅延しているかの指標になる。
```
flask_sqlalchemyで複数のデータベースに接続したい

flask_sqlalchemyを使って複数のデータベースに接続する場合の書き方です。
参考：Youtube動画 [How to Use Multiple Databases With Flask-SQLAlchemy](https://www.youtube.com/watch?v=SB5BfYYpXjE)

以下はmysqlを３つ接続する場合です。

#ディレクトリ構成

```
├── startup.py  #起動ファイル
├── application
│   ├── __init__.py  #アプリケーション本体ファイル
│   ├── models.py
│   └── views.py
├── instance
│   └── config.py

```

#コンフィグの書き方
１つ目のデータベースをSQLALCHEMY_DATABASE_URIへ記載しています。
残りの２つのデータベースをSQLALCHEMY_BINDSに辞書型で指定しています。

```config.py
DB_USER = 'test_user0'
DB_PASS = 'password0'
DB_HOST = 'xxx.xxx.xxx.101'
DB_NAME = 'db1'
db_uri = "mysql+pymysql://{0}:{1}@{2}/{3}?charset=utf8".format(DB_USER, DB_PASS, DB_HOST, DB_NAME)

DB_USER1 = 'test_user1'
DB_PASS1 = 'password1'
DB_HOST1 = 'xxx.xxx.xxx.201'
DB_NAME1 = 'db234'
db_uri_another1 = "mysql+pymysql://{0}:{1}@{2}/{3}?charset=utf8".format(DB_USER1, DB_PASS1, DB_HOST1, DB_NAME1)

DB_USER2 = 'test_user2'
DB_PASS2 = 'password2'
DB_HOST2 = 'xxx.xxx.abb.202'
DB_NAME2 = 'db456'
db_uri_another2 = "mysql+pymysql://{0}:{1}@{2}/{3}?charset=utf8".format(DB_USER2, DB_PASS2, DB_HOST2, DB_NAME2)

SQLALCHEMY_DATABASE_URI = db_uri
SQLALCHEMY_BINDS = {"adding_db1": db_uri_another1, "adding_db2":db_uri_another2}
```

#モデルの書き方
adding_db1のテーブル(table1)を利用したい場合は
SQLALCHEMY_BINDSで指定したbind_keyをtablenameの前に書きます。

```models.py
from application import db

class sample01(db.Model):
   __bind_key__ = 'adding_db1'
   __tablename__ = 'table1'
   id = db.Column(db.Integer, primary_key=True, autoincrement=True)
   name = db.Column(db.String(30))
   memo = db.Column(db.String(150))
```
※bind_keyを書かなかった場合はSQLALCHEMY_DATABASE_URIに接続するようです。

（参考）

```startup.py
from application import app


if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000)
```

```___init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__, instance_relative_config=True) #コンフィグはinstanceフォルダを見るように指定
app.config.from_pyfile('config.py', silent=False) #config.pyが見つからない場合はエラー
db = SQLAlchemy(app)

import application.views
import application.models
```
【Mac】Finderの隠しファイル表示方法

ターミナルで操作を行う

隠しファイル表示方法
`defaults write com.apple.finder AppleShowAllFiles TRUE`
隠しファイル非表示方法
`defaults write com.apple.finder AppleShowAllFiles FALSE`

上記実行後、最後に以下を実行する
`killall Finder`
iOSDC 2019 軽くまとめ

投稿するの忘れてた ('・ω・')

# ランチセッション

# 施策・気づき

## 座談会を実施している
- 開発する機能に関してユーザーから直接ヒアリングする
- ユーザーからの評価が高いユーザーなどに直接ヒヤリングなどして、意見を拾っていく
- 密に連絡をとっているユーザーがいる

## 評価は１日が終わったあとに、まとめて評価している
- 思い出さなければならない
    - ワンショット評価
    - カードをスワイプで評価している
    - ドライバーからヒヤリングした結果を表示している

## 評価フロー
- 評価の基準がわからない
- 基準が人によってぶれている
- 星３の参考値などを出すようにしている
- 5か1によるので、２択にした

## 体制
iOS 2
Android 2
server 1
SRE 1
PO/PM 3
Design 2

- 一週間のサイクルでスクラム
- 意味を輪読会
- 正しいものを正しく作る
- アーキテクチャはviper
- 交流イベントもあり 恵比寿 9/13(Fri) 20:00 ~
- スクラムマスターが存在したことで、スクラム化が進んでいった
- 物理カンバンを使っている

## ユーザーヒヤリングについて
- 考えていることを口に出して言ってください
- 心理的安全を作る
- 一部のユーザーには先にβとして使ってもらったりもする

## 開発でドライバーとライダー、どっちを優先するのか
- KPIを追っていない、直接聞いて対応している
- プロダクトチームはUXに軸を置く

# クリーンコード

- 提唱 -> Uncle bob

##  読みやすいコードとは
- わかりやすい
- 安全である
    - バグに強い
- 変更に強い

### KickStarterを参考にできる

## クリーンコードを書くには
### ジェネリック
- 具体的なデータ型に依存しない
- 汎用的に利用できる
### プロトコル
- static ジェネリティクスの型安全
- dynamic 直接方として
な面がある
よりジェネリックにするために、protocolを使う
#### ここの問題を解決し、ジェネリックな解決策を抽出する

APIで通信する場合に、ジェネリックを利用して、共通した処理を書く
プロトコルを利用してきれいに書く
ジェネリクスの型制約
PATにぶつかったときは、protocolを配列として使うかどうかを考える
重複削除や、再利用という点で、ジェネリックにする
プロトコルにこだわるのではなく、選択する
まずは具体的な問題を具体的に解決する
パターンを考えるのではなく、具体的に考える

## クリーンに書き続けるには

コードをチェックアウトしたときよりも、コードをキレイにしていく

# Bluetooth

BLE

## 仕組み
Central -> 電波探す
Periphreral -> 電波を発信

ペリフェラルになれない端末が存在する
最適なデータ交換について説明する

## L2CAP
端末同士を接続して、双方向でデータ送受信を行う方法
iOS 11 以上
ANdroid 10
でないと使えない

メリット
BLEの仕様を知らなくても使える
接続し終わったらあとはただのストリームのプログラミング

チャンネルを開くとPSM（UInt）がとれる
もう片方の端末で、チャンネルのオープンを試みる
(コルーチン？)

## 双方向通信
inputStream, outputStream

どのくらい送れるのか
普通のBLE: 20バイト
L2CAP: 2048バイト

シーケンスをまとめる

最適なバイト数がわからない場合、送信されたデータをペリフェラルから返す

ペリフェラルは複数の端末から接続される場合がある

iOS のプロパティにBLEを必ず保持しておく
バイトオーダーの問題がある

# AppStoreReview
- fastlaneのプラグインに、ipaのリジェクトチェックができる
- PrivateFrameworkを使っていないか
- frameworkをインストールすると、iPhoneの中に入る、アプリはそのヘッダーを利用している
iOKitというのは、使っているとリジェクトされる
- warningが出ていれば、リジェクトされる可能性があり
- AppCheckerを使って、CIツールでビルド後にチェックする
- ガイドラインはdiffをとることで、わかりやすい
- IDFAを使っているかどうかチェックできるのか？ -> 不明

# EAR（輸出規制）
- iOSはappleが配信しているため、輸出になる
- httpsは暗号化技術
- 判定チャートがある
- 一般に入手可能化？一般なものはマスマーケット品目となる
- EARで規制されない
- 自己番号分類報告を提出しないといけない
- 報告は、２箇所のメールアドレスに送る
- 暗号化 -> 「はい」 満たしているか -> 「はい」となる

# XCFrameworks
- xcode11から、フレームワークをバイナリ配布するようになった
- Swift 5.1 module stability -> バージョンの違いがなくなる

# 設定プロファイルはplist
[iOS13]UITextViewDelegateがTouchDownで反応してしまう

## 何が問題か
iOS13からテキストのリンクなどに用いられる[UITextViewDelegate](https://developer.apple.com/documentation/uikit/uitextviewdelegate)の[textViewメソッド](https://developer.apple.com/documentation/uikit/uitextviewdelegate/1649337-textview)が
iOS12までは`TouchUp`で反応していたもののiOS13からなぜか`TouchDown`で反応してしまうという問題がありました．
[参考記事](https://stackoverflow.com/questions/58189447/ios-13-1-uitextview-delegate-method-shouldinteract-called-when-scrolling-on-atta)

## どう解決するか
* iOS13の不具合(?)の修正を待つ
* textViewメソッドのtextViewインスタンスからタッチイベントを取得する
* そもそもtextViewDelegateメソッドを使用しない

以上の３つがあると思います．

### iOS13の不具合修正を待つ
いつAppleが修正を行うのかは不明瞭で今の所この修正はベータ版にも含まれていないようなので，これは懸命な解決法ではなさそうです．

### textViewメソッドの`textView`インスタンスからタッチイベントを取得する

以下のtextViewメソッドから受け取れるtextViewのタッチイベントを取得する方法です．

```.swift
func textView(_ textView: UITextView,
                  shouldInteractWith URL: URL,
                  in characterRange: NSRange,
                  interaction: UITextItemInteraction) -> Bool
```

以下のようにまず`interaction`で処理をわけ，`textView`のタップイベント処理が終わった時に何かの処理をさせることで擬似的に`TouchUp`の挙動と同じになるようにしています．出典は[stackOverflow](https://stackoverflow.com/questions/58189447/ios-13-1-uitextview-delegate-method-shouldinteract-called-when-scrolling-on-atta)です．

```.swift
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {

    switch interaction {
    case .invokeDefaultAction:
        if textView.gestureRecognizers?.contains(where: {$0.isKind(of: UITapGestureRecognizer.self) && $0.state == .ended}) == true {

            // Handle your custom logic here.

            return false
        }
        return true
    case .presentActions:

        // Default action.

        return true
    case .preview:

        // Default action.

        return true
    @unknown default:
        fatalError()
    }
}
```

### そもそもUITextViewDelegateを使用しない
そもそもiOS13側の不具合である可能性が高く，いつ対応がされるのかがわからないため上記の`textView`のタッチイベントを拾って`touchUp`のように振る舞わさせるのは少し冗長な気もします．
iOS13からURLなどを長押しした際のOS側の挙動が変わっている(以前までのアクションシートが起動するだけのものから変更されてプレビューが表示されるなどOS準拠の挙動がリッチになってきている)こともあり，あえて自分でそのさきを処理せず，OS準拠の挙動に合わせるということもありなのではないかなと思います．


## 参考資料
https://stackoverflow.com/questions/58189447/ios-13-1-uitextview-delegate-method-shouldinteract-called-when-scrolling-on-atta
業務内容に準ずる人材採用と投資の重点、人材育成のフレームワーク（業務の現状にマッチしていますか？）

今から13年前に見た記事だが、人材育成関係の資料は過去の文献が参考になることが多い。ITも例外ではなくプログラマーもいればヘルプデスクもあればコンサルもいる。多種多様な人のニーズがあるが、業務のプロセスのあり方、投資の重点、採用基準、評価・処遇基準が的を得ていないことが多く最近は人事評価を辞めたという話も聞くが果たして本当にそれで良いのかも疑問。きれいにまとまっていた資料の備忘録。参考：

![採用システムと人材育成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/832608d8-901b-889e-36c2-e51da944b5f5.png)
【Java】Dateの時刻を00:00:00にする方法

# 概要
- チェックする対象の日付が今日より前か後か当日かを調べたい
- ただしチェックする対象の日付は時刻が00:00:00なので日付だけ比較したい
- `new Date()`で生成した今日の日付は時刻まで入っている
  - 比較すると日付が一緒でも時刻が違うと当日判定にならない

# 実現方法
## 使うメソッド
- `java.util.Date`のメソッドを使って前後比較をします
- 言わずと知れた`org.apache.commons.lang3`の`DateUtils`を使います

```java:UseMethod
java.util.Date.equals(Object obj)
java.util.Date.before(Date when)
java.util.Date.after(Date when)

org.apache.commons.lang3.time.DateUtils.truncate(Date date, int field)
```

## サンプル
```java:DateUtilService.java
public void printDate(Date targetDate) {

    // 今日の00:00:00を取得
    Date today = DateUtils.truncate(new Date(), Calendar.DAY_OF_MONTH);

    if (targetDate.equals(today)) {
        System.out.println("今日です。");
    } else if (targetDate.after(today)) {
        System.out.println("今日より後の日付です。");
    } else if (targetDate.before(today)) {
        System.out.println("今日より前の日付です。");
    }
}
```

### 解説
1. `DateUtils.truncate`の第1引数にはゼロ埋めしたい日付を入れる
2. 第2引数に`Calendar.DAY_OF_MONTH`を渡す
3. todayの時刻が00:00:00になるから、targetDateとフォーマットが揃う
4. あとはequals、after、beforeで前後関係を調べる

## ちなみに
### `DateUtils.isSameDay`を使う方法
当日かどうかだけなら`DateUtils.isSameDay`を使えば、truncateで00:00:00にしなくても日付だけ比較してbooleanを返してくれます。
※今回はbeforeとafterを使いたかったのでゼロ埋めしました

### ゼロにする位置を変える場合
`DateUtils.truncate`の第2引数に渡す変数次第でゼロにする位置を変えられます。

| int field           | ゼロになる位置 |
|:--------------------|:-------------|
|Calendar.DAY_OF_MONTH|00:00:00      |
|Calendar.HOUR_OF_DAY |XX:00:00      |
|Calendar.MONTH       |1日の00:00:00 |
|Calendar.YEAR        |1/1の00:00:00 |


# 参考
[【Java】Dateの時分秒を切り捨てる方法](http://javatechnology.net/java/dateutils-truncate/)
[Class DateUtils｜org.apache.commons.lang3.time](https://commons.apache.org/proper/commons-lang/javadocs/api-3.8/org/apache/commons/lang3/time/DateUtils.html)
【Angular】TSLintで特定の拡張子(.jsonなど)のファイルを検査対象外にする

# 概要

TSLintで特定の拡張子(.jsonなど)のファイルを検査対象外にする。

# 方法

ネットでよく出てくるのは以下の方法であるが、こちらを試行したところ、検査対象外にすることはできなかった。
※.jsonファイルを検査対象外にする例

```json:tslint.json

{
  "linterOptions": {
    "exclude": [
      "*.json",
      "**/*.json"
    ]
  }
}
```

以下の方法だと、検査対象外にすることができた。

```bash
# ng lint project_name --exclude src/**/*.json
```

`ng lint` コマンド実行の際にオプションで除外ファイルを指定した。
こちらの例では、Angular環境なので、 `ng lint` で実行しているが、
`tslint` コマンドでも同様かと思われる。こちらは未確認。

`npm scripts` で実行するのなら、以下のように定義する。

```json:package.json
{
  "scripts": {
    "lint": "ng lint project_name --exclude src/**/*.json"
  }
}
```
iOSの有名リポジトリのコードの小技

うまい人の研究してわかったこと

- アクセス修飾子をちゃんと書く
- アクセス修飾子ごとにextentionを切る
- `internal var heroIDToSourceView = [String: UIView]()` というふうに、propertyをoptionalにするようなことはしない
 - optinalはoptinalにする必要にするときだけ
- delegateはweakにする
- `UIView(frame: transitionContainer?.bounds ?? .zero)` nullのcheckに演算子を使う
- `for v in animatingToViews { _ = context.snapshotView(for: v) }` 
- 1行for文もあり
- deferの使い方が上手い（loadingを消したり、初期化処理をしたりする）
 - deferとは、途中でreturnしても実行される文

- funcに対するコメントを書く

```
  /**
   Update the progress for the interactive transition.
   - Parameters:
   - progress: the current progress, must be between 0...1
   */
```

- propertyのViewControllerの宣言が、くっそうまい（関数的で、他に影響がないように書いている)

```
lazy var mmPlayerLayer: MMPlayerLayer = {
        let l = MMPlayerLayer()
        l.cacheType = .memory(count: 5)
        l.coverFitType = .fitToPlayerView
        l.videoGravity = AVLayerVideoGravity.resizeAspectFill
        l.replace(cover: CoverA.instantiateFromNib())
        return l
    }()
```

Layerのアニメーションに関して

```
fileprivate func setFrameWith(quadrant: VideoPositionType, dismissVideo: Bool) {
        let margin = self.config.margin
        var rect = self.config.playLayer?.playView?.frame ?? .zero
        let size = UIScreen.main.bounds
        switch quadrant {
        case .leftTop:
            rect.origin.x = dismissVideo ? -rect.size.width : margin
            rect.origin.y = margin
        case .rightTop:
            rect.origin.x = dismissVideo ? size.width : size.width-rect.size.width-margin
            rect.origin.y = margin
        case .leftBottom:
            rect.origin.x = dismissVideo ? -rect.size.width : margin
            rect.origin.y = size.height-rect.size.height-margin
        case .rightBottom:
            rect.origin.x = dismissVideo ? size.width : size.width-rect.size.width-margin
            rect.origin.y = size.height-rect.size.height-margin
        }
        
        to?.view.alpha = 0.0
        UIView.animate(withDuration: self.config.duration, animations: {
            if dismissVideo {
                self.config.playLayer?.playView?.alpha = 0.0
            }
            self.config.playLayer?.playView?.frame = rect
        }) { [unowned self] (_) in
            if dismissVideo {
                
                (self.config as? MMPlayerPassViewPresentConfig)?._dismissGesture = true
                self.config.playLayer?.setCoverView(enable: true)
                self.to?.dismiss(animated: true, completion: nil)
            }
        }
    }
```

willSet + newValueを使う

```
    @IBOutlet weak var okButton: UIButton! {
        willSet {
            // OKボタンの修飾
            newValue.layer.borderColor = UIColor.white.cgColor
            newValue.layer.borderWidth = 1.0
            newValue.layer.cornerRadius = 5.0
        }
    }
```
LCD-A173Vの修理 

実家にあったIO DATAのLCDディスプレイのLCD-A173Vが壊れたのでいじってみました。

チップのマーキングから2004年くらいの製品のようです。

このディスプレイは以前にもコンデンサーが膨らんでいて取り替えて修理して使えていたのですが、その後また壊れてしまいました。

電源が入った時や信号が出た瞬間は表示されるのですが1秒もせずにブラックアウトします。

ブラックアウトしても信号は認識していて、入力がある時はLEDが緑に点灯しています。信号がなくなるとオレンジです。

この機種の故障はネットで調べると沢山ページがあります。おおよそ以下のようなパターンのようです。

* 電解コンデンサーの劣化
* 半田のクラック
* 2SC5706の故障
* レギューレータのONOFF回路のスイッチのTRの故障

手元の基板は表面実装部品がちょっと斜めになっていたり、結構作りは荒いです。

コンデンサーは怪しいのは取り替えて、半田も一通りリワークしてみたのですが、直りません。

2SC5706が壊れて短絡するケースもあるようなので、外して抵抗値を確認してみましたが全て問題なかったで、元に戻しました。

![写真（2019-10-23 19.39）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/cecf12ad-c7a3-8fe3-073c-9d86b77f7d1f.jpeg)

ネットで検索して見ていると2SC5706が一つ壊れて、同じような症状のページがありました。

この機種はバックライト用のインバーターが2系統あり、1系統に2つ2SC5706が使われています。

2SC5706や代替えになる2SC5707は入手が困難なようですが、マルツの提携先在庫にはあるようです。

いろいろ調べていたら同じ製品のサービスマニュアルが出てきました。

![スクリーンショット（2019-10-24 15.47.53）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/c5d26910-8122-b40a-daa9-3965fab4dab4.png)

Q203,Q204(8ピンSOP FET)の左側がレギュレーター部分で、右側がインバーター部分のようです。インバーターはDCから高電圧のACを作っているようです。

一つ壊れたのであれば、半分暗いとかで表示しそうなものと思ってました。

一通りサービスマニュアルの確認手順を見てみましたが、問題が見つかりません。

レギュレータ回路はROHMのBA9741F(上の回路図では同等品のTL1451)を使っています。このチップは2系統あるので、それぞれにまったく同じ回路がぶら下がっています。

BA9741Fのデーターシートを眺めていると、保護回路(SCP)があり、どちらかで異常がある場合には両方とも出力を停止するようです。保護回路の時定数は15番ピンのコンデンサー(C207)で設定されます。これが一瞬だけ表示される理由です。

![スクリーンショット 2019-10-25 7.31.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/9924df17-318a-0f54-8545-1e8bf2401557.png)

私のところの故障は2SC5706ではなく片方のバックライト自体が壊れて、通電しなくなったために異常検知されていたようです。

いろいろ調べましたが、バックライトのケーブルを一つ外して交互に確認すると、片方がつかないのが確認できました。また完全にバラしてつかない方のソケットにつく方のコネクタを接続すればインバーターかバックライトの切り分けができます。

古い製品なので、レギュレータ部分で少し発振が聞こえ、当初レギュレータを疑ったので、ちょっと手こずりました。

とりあえずバックライト一つでも気になるほど暗くはなくムラもないので、一つだけで使うことにしました。

お勧めできないので、細かいことは省きます。

こちらの方はバックライトを交換されてようです。

http://www5a.biglobe.ne.jp/jh2clv/lcd72repair.htm

ヤフオクで中古動作品が2000-3000円くらいなので、壊れたものを危険をおかして修理してまで使う必要があるかは、かなり微妙です。ただ製造後10年以上経ち故障例も多いので動作品でもすぐに壊れてしまうかもしれないので、どちらにしてもお勧めしません。
上司部下タイプ別適合度マトリクス

以前どこかで見つけた記事だが、上司と部下の関係で参考になりそうな資料。チームワークで同僚にも使えそうだ。最近、主体性とか協調性とかいろいろな言葉があるが、結局上司部下の人間関係の良し悪しは上司の行動タイプ、部下の行動タイプに依存するところが大きい。**部下に主体性を求めておきながら、上司が指示指導型、交渉取引型では困る。同じように権限移譲をする上司がいるのに部下の協調性が人一倍強く素直従順では上手くいかない。**　参考：

![上司部下マトリクス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518389/7b9a7e55-bd91-209d-df9a-6f096f916f0f.png)