OmniAICreator/Qiita-1.07M huggingface dataset:
ソースコードは設計である３つの理由。仮説(79) 

PCで開発し始めた４０年前くらいから「ソースコードは設計」ずっと言い続けています。

設計書は、紙テープ、紙カードで入力していた時代（約４０年以上前）の遺産。紙テープ、紙カードを見ても、理解できないから（デバッグを紙テープ、紙カードを眺めてされている方はいました）。計算機を独り占めできないからフローチャートを書いたり、机上でバッグしていた。今は、ソースコードと変換可能でない資料を作ることは、無駄なだけでなく、保守上の誤りを混入させるものとして忌遺すべきことです。

<この項は書きかけです。順次追記します。>
This article is not completed. I will add some words in order.
# ソースコードを設計と呼んでいる分野
HDLでは、ソースコードが設計で、回路図が実装です。

RTL Design Style Guide
は、日本が誇る名著です。

残念なことに、日本語よりも、英訳の方がわかりやすいです。

日本人にありがちな、日本語で書くと余分なこと、わかりにくく書くのに、英語で書くとわかりやすく書いてしまうという。

ちょうど、西暦2000年問題の時、日本の企業の日本語の情報はさっぱりわかりにくいのに、日本の企業の英語の情報やすごくわかりやすかったことを記憶しています。

#  ソースコードで仕様記述できる

仕様記述言語で記述し、機械語などに変換可能な言語に変換する方法では、仕様と動作が結びついていて、抜け漏れの可能性は低い。

仕様を記述することと、設計することは表裏一体。
設計不可能な仕様を記述しても仕方がないし、
設計によっては仕様が変わることがある。

追跡は自動的にできている。

整合性も、仕様記述言語、機械語等に変換可能な言語で確認が取れる。

# 設計を見直す
設計を見直す時、ソースコードまたは設計図で変更し、模擬試験(simulation)をして設計の良し悪しを判断する。ソースコードまたは設計図なら設計の良し悪しを判定できる。

設計書と称して、動かない文字をどれだけならべても、設計の良し悪しは反転できない。


＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.

# 文書履歴(document history)
ver. 0.01 初稿
ver. 0.02 標題追記 20190530
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
電力網制御

電力網の制御は、実際の現場での制御の経験がない。
模擬試験上での振る舞いについて検討し、どのような模擬試験を実施しているとよいかを検討する。

実際の電力線での電力変動の影響を最小にする制御のために、くまなく入力してあるとよい。

# 北海道電力の停電 2018.9.6

ほくでんからのお知らせ 2018年度
社長記者会見　発言要旨（9月6日12時15分）
https://www.hepco.co.jp/info/info2018/1229671_1762.html


ほくでんからのお知らせ 2018年度
森副社長記者会見　発言要旨（9月6日16時）
https://www.hepco.co.jp/info/info2018/1229721_1762.html

苫東厚真発電所の設備被害状況
https://wwwc.hepco.co.jp/hepcowwwsite/info/info2018/__icsFiles/afieldfile/2018/10/04/180908b.pdf

送電設備・配電設備の被害状況
https://wwwc.hepco.co.jp/hepcowwwsite/info/info2018/__icsFiles/afieldfile/2018/10/04/180908c.pdf

第1回　平成30年北海道胆振東部地震に伴う大規模停電に関する検証委員会　配布資料
https://www.occto.or.jp/iinkai/hokkaido_kensho/hokkaido_kensho_1_shiryo.html

# 送配電

瞬時電圧低下
高調波

平成29年度エネルギーに関する年次報告（エネルギー白書2018） HTML版
https://www.enecho.meti.go.jp/about/whitepaper/2018html/


## 送電線

日本の地域間連系送電網の経済的分析
https://www.rieti.go.jp/jp/publications/dp/05j033.pdf

送電線が記載されている地図
http://www.akoart.sakura.ne.jp/quest/maps.html


＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞

# 文書履歴(document history)
ver. 0.01 初稿 　20190518
ver. 0.02 ありがとう追記 20230504

## 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
javaScriptコンストラクタについて(お勉強用)

コンストラクタは、インスタンス生成のための関数のこと(コンストラクタ関数という)。
JavaScriptでは、関数もオブジェクトであり「関数オブジェクト」と呼ぶ、

JavaScriptには基本的にはクラスという概念はなく、オブジェクトの作成には以下の２通りがあります。

- 空のオブジェクトを作成する(new演算子なし)

```javascript

例)
var test = {};
```
- コンストラクタからインスタンスを作成する(new演算子あり)

```javascript

例)
function Test() {};
var test = new Test();
```

### new演算子によるインスタンス生成
「new」を付けることで、生成されるインスタンスが「this」にセットされる。

```javascript
//コンストラクタの定義 
function Cat(name, cry) {
  this.name = name;
  this.meow = function() {
    console.log(cry);
  };
}
//コンストラクタからインスタンスを生成する
var cat = new Cat('たま', 'にゃんにゃん');
console.log(cat.name); // たま
cat.meow(); // にゃんにゃん
```

生成したインスタンスのプロパティを利用するには、cat.nameのように「インスタンス名.プロパティ名」と書く。そしてcat.meow()のようにメソッドとして呼び出す。
Swiftで雑にSelenium! [Swift -> PythonKit -> Selenium]

## ハイライト

Swift で [PythonKit](https://github.com/pvieito/PythonKit) を利用して [Selenium](https://www.seleniumhq.org) を動かします。

## 対象の読者
- Swift Package Manager の利用経験がある方
- Selenium がなんとなく分かる方
- Python を雰囲気で書ける方

向けに雑にご紹介致します。

## PythonKit の導入

[PythonKitのREADME](https://github.com/pvieito/PythonKit#swift-package-manager) に従い，[Swift Package Manager](https://github.com/apple/swift-package-manager) を用いて導入します。

```Package.swift
.package(url: "https://github.com/pvieito/PythonKit.git", .branch("master")),
```

[Usage](https://github.com/pvieito/PythonKit#usage) の通り，runした際にバージョンが出力されれば導入完了です。

```main.swift
import PythonKit

let sys = try Python.import("sys")

print("Python \(sys.version_info.major).\(sys.version_info.minor)")
print("Python Version: \(sys.version)")
print("Python Encoding: \(sys.getdefaultencoding().upper())")
```

## Selenium の導入

`pip` と `brew` を用いてインストールします。WebDriver は ChromeDriverにしました。何でも良いです。

```
$ pip install selenium
$ brew cask install chromedriver
```

## Selenium チュートリアルを Swift から書く

[ChromeDriver](http://chromedriver.chromium.org/getting-started) の Python チュートリアルを Swift で書き直してみましょう。こんな感じになります。

```main.swift
import PythonKit

let time = Python.import("time")
let webdriver = Python.import("selenium.webdriver")

let driver = webdriver.Chrome("/usr/local/bin/chromedriver")
driver.get("https://www.google.com/")
time.sleep(5)
let searchBox = driver.find_element_by_name("q")
searchBox.send_keys("ChromeDriver")
searchBox.submit()
time.sleep(5)
driver.quit()
```

## まとめ

Swift で雑に Selenium してみました。**いかがでしたか?**

[PythonKit](https://github.com/pvieito/PythonKit) のチュートリアルにはなったかもしれません。

一方で，[PythonKit](https://github.com/pvieito/PythonKit) 経由での import のため，Xcode で書いても残念ながら補完は効きません。エラーは出力されるので雑に雰囲気で書きましょう。それが本記事のオチです。

## References
- [Selenium - Web Browser Automation](https://www.seleniumhq.org)
- [GitHub - pvieito/PythonKit: Swift framework to interact with Python.](https://github.com/pvieito/PythonKit)
- [GitHub - apple/swift-package-manager: The Package Manager for the Swift Programming Language](https://github.com/apple/swift-package-manager)
- [Getting started - ChromeDriver - WebDriver for Chrome](http://chromedriver.chromium.org/getting-started)
Sublime Text でマッチした部分だけ抜き出す

# やりたいこと

↓のようなログファイルから「===…」で囲まれた部分を抜き出したい

```
==========
Start something at 2019-05-28 12:00
==========
出力1
出力2
:
==========
Start another at 2019-05-28 12:45
==========
出力a
出力b
:
```
↓

```
==========
Start something at 2019-05-28 12:00
==========
==========
Start another at 2019-05-28 12:45
==========
```

# 課題

マッチさせる正規表現は下記の通りです。

```
(=+\n.*?\n=+)
```

ただ、ここからどうやって抜き出すのかがわかっていませんでした。

# 解決

`Find All` で該当箇所をすべて選択した状態になるので、これを新しいタブにコピペすると、抜き出した状態になります。具体的な手順は以下の通りです。

1. `Ctrl+F` で正規表現を有効にして（`.*`アイコンをONにして）、`(=+\n.*?\n=+)` で検索
2. 検索ボックス横の `Find All` をクリック → マッチした部分がすべて選択状態になる
3. 選択状態のまま `Ctrl+C` でコピー
4. 新しいタブを開き（`Ctrl+N`）、ペースト（`Ctrl+V`）

# 感想

なんのことはない手順ですが、正規表現の否定先読みなんかを駆使しようとしていたので、それよりもずっと素直で簡単に実現できたので、やはり好きなエディタだなぁと思いました。
CentOS6とCentOS7を比較してみた

#OSインストール部分

###CentOS 7
①anacondaの画面フロー変更がされている
②GUIでのパッケージ選択を廃止した
③6.5➡7へのupgradeをサポート

#デフォルトファイルシステム

###CentOS 6
ext4
###CentOS 7
xfs

※詳しくは以下の記事
[Linuxファイルシステムをまとめてみました](https://qiita.com/sion_cojp/items/c8e015db39ddbf43012e)

#ブートローダー
###CentOS 6
GRUB Legacy (+efibootmgr)
設定ファイル: /boot/grub/menu.lst
###CentOS 7
GRUB2
設定ファイル: /etc/default/grub
/boot/grub.d/配下
/boot/grub/grub.cfg

①BIOS, UEFIの両方へ対応
②RAID, LVMのLinuxでのサポート（パーティションの中に少なくとも１つのファイルシステムが必要だった。）
③パーティションテーブル：GPTの正式サポート
MBRを2TiB➡8ZiBまで管理出来るようになった
CentOS 7におけるCUIからのWi-Fi設定の仕方

# 概略
ウェブサーバーにしようと、CentOS7.6を余っていたデスクトップマシンにクリーンインストールしたので、それの色々な設定について備忘録を記す。今回は、CentOS7.6をminimalインストールした直後に、まずWi-Fiでネットに接続するためにアレコレした奮闘の記録である。

# マシン概要
CPU：AMD A8-7600
RAM: Corsair DIMM DDR3 1333 MHz 4GiB (２枚)
SSD: TS64GSSD340 64GB
HDD: Toshiba THNSNJ12 128GB
Wireless interface: Intel wireless 7260

# Wi-Fi設定手順
まずは、ネットワークを起動。
<pre>service network start</pre>

ネットワークデバイスの状態を表示。
<pre>nmcli d</pre>

結果は以下の通り。
<pre>DEVICE  TYPE     STATE       CONNECTION
lo      loopback unmanaged   --
enp1s0  ethernet unavailable --
wlp3s0  wifi     unmanaged   --</pre>

無線LANデバイスは動いているので、利用できるアクセスポイントを表示。
<pre>
$ nmcli dev wifi list
IN-USE SSID MODE CHAN RATE SIGNAL BARS SECUIRY</pre>

何も表示されない。
NetworkManager-wifiが、インストールされていないことが原因だと考えられたため、USB経由でインストールすることにした。

別のマシンで、ネットからNetworkManager-wifiのrpmファイルをダウンロードして、USBメモリ経由でインストール。
<pre>sudo fdisk -l</pre>
で、USBデバイスを確認。

<pre>sudo mount /dev/sdc /mnt</pre>
でデバイスをマウント。

<pre>sudo rpm -i /mnt/*.rpm</pre>
でインストール。

ネットワークマネージャを再起動。
<pre>systemctl restart NetworkManager</pre>

すると、
<pre>nmcli dev wifi list
IN-USE  SSID  MODE   CHAN  RATE        SIGNAL  BARS  SECUIRY
        SSID  Infra  124   405 Mbit/s  44      **    WPA2</pre>

目的のアクセスポイントが検出された！

さっそく接続。
<pre>nmcli --ask dev wifi connect SSID</pre>
* SSIDの部分は、接続したいネットワークのSSIDを入力。
* パスワードを聞かれるので、入力。

接続されていることを確認。
<pre>nmcli d
DEVICE  TYPE     STATE       CONNECTION
wlp3s0  wifi     connected   SSID
lo      loopback unmanaged   --
enp1s0  ethernet unavailable --
</pre>

これでWi-Fi経由で色々インストールして、サーバーのセットアップができる！
URLに付与するパラメーターが特殊文字として表示されてしまう

## 事象
`http://localhost?a=1&regist_media`

のようにHTMLメールでも表示したいが、実際は以下になる。

`http://localhost?a=1[商標マーク]ist_media`

これは[商標マーク] = &reg と表されているため。

## 対策
以下のようにかく（PHP）

`"http://localhost?a=1".htmlspecialcharactors(&regist_media=)."12345"`

Gmailは`http://localhost?a=1&regist_media`でも正常に表示されるのですが、
Yahooで受信するとダメみたいです。
今時の Linux resolve 解決編

# さくっと名前解決してほしい

## nameserver 127.0.0.53

- グローバルとプライベートの名前解決が別れているとどっちかしか解決できない件
- GlobalDNS=8.8.8.8 (安定感ある)
- GlobalDNS=1.1.1.1 (使ってみよう)
- GlobalDNS=4.4.4.4 (ns1-value-domain.com からの更新がめちゃ遅くて使えない)

### DNS 確認

```bash
systemd-resolve --status
```

### ちゃんと設定

- プライベートなDNSがグローバルの名前解決をしてくれないとき

```conf:/etc/systemd/resolved.conf
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See resolved.conf(5) for details

[Resolve]
DNS=1.1.1.1 8.8.8.8
FallbackDNS=1.1.1.1 8.8.8.8
#Domains=
#LLMNR=no
MulticastDNS=yes
#DNSSEC=no
#Cache=yes
#DNSStubListener=yes
```

### リンク作って再起動

```bash
sudo ln -sfn /var/run/systemd/resolve/resolv.conf /etc/resolv.conf
sudo systemctl restart systemd-resolved
```

### DNS 確認

```bash
systemd-resolve --status
```
Windows10にてNode環境構築によくあるエラー

Node.jsの環境構築はLinuxでは問題なく一発で完了できるのはほとんどですが、
Windows10のOSだと、よくエラーが発生し、回避しないと先に進まないケースもあります。
・node-gypにてコンパイルエラー
・Nodeのバージョンが高すぎる問題
・npm ERR! git xxx

#node-gypにてコンパイルエラー
Node.jsではすべてJavaScriptで実現したのではなく、C++を利用している部分がありました。
C++を利用すると、C++コンパイルツールが必要です。

https://github.com/nodejs/node-gyp
にて２つのやり方は紹介されました。
##案１：windows-build-tools
PowerShellを管理者権限で起動し、下記のコマンドを発行する
```npm install --global --production windows-build-tools```

ネットの記事を探してもこの案で回避できたという記載が多いです。
残念ながら、私の環境では何度も試してもエラーが解消しませんでした。

##案２：Visual Studio Build Tools 
①、Visual C++ ビルド環境のインストール　
　インストール方法は２つあります。
　方法１：BuildToolsをダウンロードしてインストール　※こちらのほうが楽です。
　　　https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools
 
　　　※2015バージョンが欲しい場合はMSBuild2015をダウンロードしてインストール
　　　https://go.microsoft.com/fwlink/?LinkId=691126 


　方法２：Visual Studio 2017 Community　をインストール

②、Python 2.7をインストール
　下記のURLのからダウンロードしてインストール。※Python 3.x.xはサポートされません。
　https://www.python.org/downloads/release/python-2715/
　

③、npm設定を行う。2017はインストールしたバージョンです。BuildTools2015の場合は「2015」でセット
　```npm config set python python2.7```
　```npm config set msvs_version 2017```

これでコンパイルエラーがは解消できました。

#Nodeのバージョンが高すぎる問題
たまにNodeのバージョンが高すぎる問題がありました。
その際にはDowngradeする対応は多いでしょう
nodistツールでバージョン管理でも楽です。
https://github.com/marcelklehr/nodist/releases

インストール後、Pathに追加し、PowerShellから実行できるように。
必要なバージョンを指定すると簡単に切り替えできます。
・```nodist -v ```コマンドでNodistのバージョン確認できます。
・```node -v ```コマンドでNodeのバージョン確認できます。
・```nodist dist ```コマンドでインストール可能なNodeバージョンリスト確認できます。
・```nodist 8.16.0 ```のようにバージョンを指定してNodeを切り替えできます。

#npm ERR! git xxx
初回目のnpm install にて問題なかったですが、２回目以降は、下記のようなエラーが発生する場合もあります。
>npm ERR! path xxxxxx\node_modules\web3-providers-ws\node_modules\websocket
npm ERR! code EISGIT
npm ERR! git xxxxxx\node_modules\web3-providers-ws\node_modules\websocket: Appears to be a git repo or submodule.npm ERR! git    xxxxxx\node_modules\web3-providers-ws\node_modules\websocketnpm ERR! git Refusing to remove it. Update manually,npm ERR! git or move it out of the way first.


このエラーの場合は乱暴的な解決方法として、node_modulesフォルダーをまるごと削除し、npm install で再インストールします。

以上
AWSで操作可能なリージョンを縛るためのIAM Policy

AWSのIAM Userが操作できるリージョンを縛るためのPolicyです。
以下は例となります。

```json:policy.json(例)
{
       "Version": "2012-10-17",
       "Statement": [
              {
                     "Sid": "DenySpecificRegionsAccess",
                     "Effect": "Deny",
                     "Action": [
                            "ec2:*",
                            "rds:*",
                            "redshift:*",
                            "ecs:*",
                            "lambda:*",
                            "dynamodb:*",
                            "apigateway:*",
                            "batch:*",
                            "workspaces:*",
                            "glue:*"
                     ],
                     "Resource": [
                            "*"
                     ],
                     "Condition": {
                            "StringNotEquals": {
                                   "aws:RequestedRegion": [
                                          "ap-northeast-1",
                                          "us-east-1",
                                          "ap-northeast-3"
                                   ]
                            }
                     }
              }
       ]
}
```

#ポイント
上記ポリシーを翻訳すると、
**「リージョンがap-northeast-1/us-east-1/ap-northeast-3ではない場合、指定されたActionをDenyする」**
となります。
別途、フルアクセスを当てておきつつ、追加でこのように書くと、リージョンがap-northeast-1/us-east-1/ap-northeast-3ならば全部利用できるがその他では操作できない、といったことを実現できます。(AllowよりもDenyが優先です)
これにより、無秩序にリソースが乱立することを防ぎ、ガバナンスが効いた使い方ができるようになります。

#注意点
ならばActionに\*って書けばいいんじゃないの？と考えるところですが、AWSにはリージョンの範囲がない「グローバル」のサービス(例:IAM など)があり、\*と書くとこれらのサービスが使えなくなるという欠点があります。リージョンを縛るConditionは、最終的に操作するIAM Policyで指定されていなければならず、スイッチロールでは回避できないようです。上記のPolicy例では、全サービスを縛るために、Actionにサービス名をひたすら書き続ける必要があります。
現実解は、上記のポリシーのように書きつつ、Actionで乱用されるとまずいものだけを縛り、課金状況やCloudTrailで監視しながら、Actionに追加していくといった流れになるかと思います。
(誠に恐縮ですが、より良いやり方がありましたら、ご教示いただけると幸いです)
dein.tomlでプラグインに別名を与えたい

# 状況
dein.vimでvimのカラースキームを管理しようとしたら、vimというプラグインが出てきた。
よく見ると、draculaのリポジトリ名がvimになっている。
https://github.com/dracula/vim

パッケージを入れる際、deinはそのまま**リポジトリ名を使用**するようなので、実害はなかったが、 `vim` という名前でインストールされているのがちょっと気になった。

# 解決
なんのことはない、nameをつければいいだけだった。

```toml
[[plugins]]
repo = 'dracula/vim'
name = 'dracula'
```

これで `dracula` としてプラグインがdeinに認知された。
wtforms で 自作 Validator を field に追加時、重複して表示される

# 追記
Formクラスはシングルトンのため。
最後に書いたようにクラスを分ける方が正しい。
以下の本文はなんの参考にもならない

# 環境

* flask-wtfでログインページを作成

# 事象

以下のチェックを行いたく、viewにてformのfieldにバリデーションを追加した。

* ログインでは存在チェック
* 登録ではユニークチェック

が、存在チェックエラーが連続で発生した場合、バリデーションが複数登録され、回数分のエラーメッセージが表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321322/f5431ae4-12b8-0e8a-6f3c-2722bc658d6b.png)

# ソース
重要部のみ抜粋

```python:view.py
from flask import Flask
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, Length, ValidationError

app = Flask(__name__)

# form
class LoginForm(FlaskForm):
    name = StringField('name(必須)', validators=[DataRequired(), Length(1, 15, "15文字以下で入力してください")])
    password = PasswordField('password')

# 自作Validator
class Validators:
    class Unique:
        def __init__(self, message='すでに存在するユーザーです'):
            self.message = message

        def __call__(self, form, field):
            if User.is_exists(field.data):
                print('raise')
                raise ValidationError(self.message)

@app.route('/login/sign_up', methods=['post'])
    form =  LoginForm()
    # 自作Validatorを追加
    form.name.validators.append(Validators.Unique())
    if form.validate_on_submit():
        # 登録処理 ...
    else:
        # バリデーションエラー
        return render_template('login.html', title='login', form=login_form)

    
```

# 確認
`print`を入れて確認

```python
# 自作Validatorを追加
print(login.name.validators) #追加
form.name.validators.append(Validators.Unique())
```

2回目のエラー時のprint内容（1回目に`append`した自作バリデーションが残っている）
`[<wtforms.validators.DataRequired object at 0x000002AC0F9807F0>, <wtforms.validators.Length object at 0x000002AC0F980898>, <server.routes.login.Validators.Exists object at 0x000002AC0FA00AC8>]`

# 対処
`type`で確認する。（もっといい方法ないのか…）

```python
# 自作Validatorを追加
validator_unique = Validators.Unique()
if type(validator_unique) not in [type(v) for v in form.name.validators]:
    # 存在しない場合のみ追加
    form.name.validators.append(validator_unique)
```

# 最後に
そもそもページの作りが悪かったり、Formクラスを分けるべき なんだろうなー
Desktop : OpenCV Find Transform ECC

<h5>Goal</h5>
Test OpenCV find transform ECC.

```OpenCV_FindTransformECC.java
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.TermCriteria;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.video.Video;


public class OpenCV_FindTransformECC {
    static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }

    public static void main(String[] args) {

        Mat templste = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0675.jpg",Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
        Mat needToBeAdjusted = Imgcodecs.imread("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\DSC_0663.jpg",Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);


        //定義運動模型的warp matrix
        Mat warp_matrix2=Mat.eye(2, 3, CvType.CV_32F);

        int maxIterations=5000;
        Mat mask=new Mat();

        //執行ECC算法。結果被存儲在warp matrix
        Video.findTransformECC(templste, needToBeAdjusted, warp_matrix2,Video.MOTION_EUCLIDEAN,new TermCriteria(TermCriteria.COUNT | TermCriteria.EPS, maxIterations, 1E-10),mask);
        Mat aligned=new Mat();

        //for  Euclidean and Affine
        Imgproc.warpAffine(needToBeAdjusted, aligned, warp_matrix2, templste.size(),Imgproc.INTER_LINEAR+Imgproc.WARP_INVERSE_MAP);
        Imgcodecs.imwrite("D:\\projects\\Java\\OpenCV_Samples\\resource\\imgs\\findTransformECC2.jpg",aligned);
    }
}
```
<h5>Result</h5>
![DSC_0675.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276243/4d17afd5-c2a7-83ae-ba5b-fe7da3baa318.jpeg)
![DSC_0663.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276243/8c5f1b76-ff50-f954-ac6f-6909ed66e512.jpeg)
![findTransformECC2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276243/3b0222ad-0d19-3105-e5f0-617ee33f808e.jpeg)
未読メッセージ数　バッジ表示

### 実装内容
下記のように未読メッセージがあった場合にバッジを表示させる

---

【完成画像参考】
![スクリーンショット 2019-05-27 17.11.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383660/689bc839-164c-fa5f-3d3c-8ce1c3e8fa29.png)


---

### 実装の目的

新規でメッセージを受信した際にアテンションがなく、未読メッセージの存在が見える化できていなかった
そのため、ハンバーガーメニューの送受信メッセージ一覧に未読メッセージ数のバッジを表示できるように実装をおこなった。

## 手順
#### 1. chat_rooms_controllerのshowアクションでページが開いた際に下記のコード相手のidをview側に渡す。

```user_chat_rooms_controller.rb
# メッセージの受信者のidをUserChatRoomから自分以外で検索し代入。未読アテンション表示のための準備として
@receive_user = UserChatRoom.where(chat_room_id: params[:id]).where('user_id != ?', current_user.id).first
```

この手順は次の説明するshowページ内でメッセージを相手に送信する際に必要となるため。


####  2. chat_rooms_controllerのshowページでメッセージを送信する際に上記１で渡した@receive_user.user_idをhidden_fieldでuser_messages_pathに一緒に送る。


```views/chat_rooms/show.haml
.message-container__input
  .message-container__input__message
    = form_with model: @message, url: user_messages_path(user_id: current_user.id), local: true do |f|
      = f.text_area :content, placeholder: "メッセージを入力して下さい" , class: "message-container__input__message__area", autocomplete: "off"
      = f.hidden_field :chat_room_id, value: @chat_room.id
      -# メッセージの受信者のidをUserChatRoomから自分以外で検索し代入。未読アテンション表示のための準備として
      = f.hidden_field :receive_user_id, value: @receive_user.user_id
      = f.submit "送信",class:"post-btn"
```

#### 3. ストロングパラメーターに :receive_user_idを追加

```controllers/messages_controller.rb
  def create
    @message = Message.new(message_params)

~中略~

  def message_params
    params.require(:message).permit(:content, :chat_room_id, :receive_user_id).merge(user_id: current_user.id)
  end

```

#### 4.　既読処理メソッド
- 該当のチャットルーム内で自分宛てのメッセージがあるかチェック
- 自分宛てのメッセージがあれば、そのレコードを取得する
- 既読の情報となるカラム（カラム名: receive_user_id_checked_message）も持たせてupdateで更新する。

```controllers/chat_rooms_controller.rb
  def show
    if Message.where(chat_room_id: params[:id]).where(receive_user_id: current_user.id).present?
      @room_message = Message.where(chat_room_id: params[:id]).where(receive_user_id: current_user.id)
      @room_message.update(receive_user_id_checked_message: current_user.id)
    end
```

#### 5. 自分宛のメッセージがあり、未読の物をカウントして表示させるためのヘルパーメソッド
- 自分宛のメッセージ件数を取得
- 自分宛のメッセージで既に既読となった件数を取得
- その２つの差分が未読メッセージ数となる
- 未読メッセージがあった際にビューページに表示させたいHTML要素を持たせてビューに飛ばすことができるようにcontent_tagを使用した。（未読メッセージなければHTML空）


```app/helpers/application_helper.rb
# 　未読メッセージ表示のメソッド
  def new_message_badge
    receive_user = Message.where(receive_user_id: current_user.id).count
    receive_user_checked_message = Message.where(receive_user_id_checked_message: current_user.id).count
    message_count = receive_user - receive_user_checked_message
    if 0 == message_count
    else
      # 未読メッセージがある際にdiv要素を吐き出させてハンバーガーメニュー内に配置する。
      # 未読メッセージが無い際に未読バッジを表示させないため
      content_tag(:div, message_count, class: 'new-message-badge')
    end
  end
```

#### 6.ビュー側の処理
下記の記述で上項で作成した未読バッジ表示のためのメソッドを呼び出す。
(表示させたい任意の位置に置く）

```views/hoge.html.haml
%p= new_message_badge
```

以上
プロトコルを定義する

# この投稿は何？
過去の投稿で、Swift標準ライブラリにある基本的なプロトコルをいくつか扱いました。
今回は、独自のプロトコルを定義して、準拠するまでを実践したいと思います。

## 実行環境
Xcode10.2.1
Swift5.x

# ハンズオン
「フルーツを商品として扱う」みたいなケースを想定しています。

## こんな型があったとして...

 `Fruit` 型は果物を表現しています。
リンゴとオレンジをインスタンス生成しました。

````Swift:フルーツ型
struct Fruit {
    var name:  String
    var emoji: String
    var sugarContent: Int
}

// インスタンスを生成
let apple  = Fruit(name: "Apple",  emoji: "🍎", sugarContent: 8)
let orange = Fruit(name: "Orange", emoji: "🍊", sugarContent: 11)
````

## 商品として販売するには
この `Fruit` 型を商品として扱うには欠けている情報があります。
例えば、価格とかですね。
単純にメンバープロパティとして、`price` を定義しても良さそうです。
ただ、商品として扱うのは `Fruit` 型オブジェクトだけとは限りません。
もしかしたら、ジュースとして `Drink` 型みたいなオブジェクトがあるかもしれません。
商品プロトコルを定義することにします。
そうすれば、商品として扱うなら価格が決まっていることが保証されますし、 `price` プロパティの実装を忘れることはありません。
ついでに、宣伝メッセージを出力してくれるメソッドもあるといいですね。

````Swift:商品プロトコル
protocol Salable {
    var  price: Int { get set }
    func advertise()
}
````

プロトコルの定義では、具体的な値や実装はありません。
この時点で、金額が決まっていたり、宣伝文句を固定するのはおかしなハナシです。
また、プロパティは読み取り専用・読み書き可を明示する必要があります。

### プロトコルに準拠する
`Salable` プロトコルを採用すると、エラーメッセージが表示されます。
_Type 'Fruit' does not conform to protocol 'Salable'_
Fixボタンを押すと、準拠に必要なプロパティおよびメソッドが自動的に記述されます。

````Swift:販売可能なフルーツ
struct Fruit: Salable {
    var name:  String
    var emoji: String
    var sugarContent: Int
    var price: Int
    
    func advertise() {
        print("This \(name) is ¥\(price)")
    }
}
````

`advertise` メソッドは、この時点で具体的な実装を記述します。
プロトコルを採用した型次第で、実装をアレンジできます。

## インスタンスを生成する
すでに生成したインスタンスはプロパティに初期値がないから、エラーになります。
初期化コードを修正します。

````Swift:初期化コードを修正
let apple  = Fruit(name: "Apple",  emoji: "🍎", sugarContent: 8, price: 100)
let orange = Fruit(name: "Orange", emoji: "🍊", sugarContent: 11, price: 120)
````

プロトコルに準拠して、販売可能になったことを確認しましょう。

````Swift:
apple.advertise()    // This Apple is ¥100
orange.advertise()   // This Orange is ¥120
````

メッセージが出力されました。

# Protocol-Oriented Programming
クラスには継承という概念がありますが、構造体に継承はありません。
一方で、Swiftプログラミングではクラスより構造体を使うことが推奨されているようです。
プロパティやメソッドの共用をプロトコルで設計することが __POP__ の基本と感じました。
GNSSモジュールを使って、地図上トラッキングに挑戦！・GUI編 （設定変更 1）

STM32 Nucleoボードを使ったGNSS（Global Navigation Satellite System、全地球航法衛星システム）評価環境の使い方のつづきです。
[（最初の記事はこちら）](https://qiita.com/Yuji_Kawano/private/9b193c9f6ce1c4ae61e9)
GUIツール（TESEO-SUITE）を使って、[Teseo-LIV3F](https://www.st.com/content/st_com/en/products/positioning/gnss-modules/teseo-liv3f.html#overview)（GNSSモジュール）の設定変更方法について解説します。変更方法はウィザードを使う方法と、マニュアルで直接該当ビットを操作する方法の２つがありますが、今回はウィザードを使う方法を紹介します。
[（マニュアル操作方法はこちら）](https://qiita.com/Yuji_Kawano/private/24f2c92f254fd42f4b46)
#TESEO-LIV3Fモジュールの設定を変更してみる・ウィザード編
##ウィザードをオープン
ウィザード形式なので、希望する変更を各ステップで選択して進めていくことで完了します。最終的にデバイスへそのまま書き込むこともできますし、設定ファイルとしてPC内に保存することも可能です。最初に、Configuration wizardsアイコンをクリックします。
![toolbar_wizard_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/0667dad3-6738-6dfc-c8dc-e28824504a71.png)



Wizard Selectionウインドウが開きますが、ここでデバイスが接続されていれば”COM x Device X”に自動選択されますので確認します。ここでは例として使用するコンステレーション（衛星システム）を変更してみます。Constellationsを選択した状態でPlay Wizardをクリックします。
![wizard_select_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/cee1d797-0599-58b7-d646-f96e27ee6e5d.png)


デフォルトではGPS（アメリカ）、GLONASS（ロシア）の２つのコンステレーションがオンになっていますので、追加として**QZSS（日本）**をオンにしてみます。


####１．アクティブにするコンステレーションを選択
**"QZSS"**にチェックしてNextをクリックします。
![wizard_select_qzss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/3719bacc-5d30-95b4-7622-042f7832bd5f.png)





####２．位置取得用として使用
続けて**"QZSS constellation used for fix"**にチェックしてNextをクリックします。
![wizard_select_qzss_fix.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/99ca6e10-a449-94a1-7605-a51355e62c56.png)


####３．確認画面
そのままNextをクリックして次に進みます。
![wizard_select_qzss_fix_verify.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/d6cf41e1-7b73-9eb1-0726-f9dc40a57639.png)



####４．最終レビュー
最終設定内容のレビュー。今回QZSSをオンにしましたので該当項目ビットが１（=ON）になっています。問題なければOKをクリックします。
![wizard_select_qzss_fix_verify_review.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/aaf28b81-a396-506a-c9a4-716f98e16392.png)


####５．デバイスへ設定送信
変更内容をデバイスへ反映させる場合、**Send my configuration to the device**をクリックしてモジュール内のFlashメモリにセーブします。また、Export my configuration into a patch fileをクリックすると以上の設定内容をPC内にxmlファイルとして保存できます。読み出しは最初の「Wizard Selection」→「My configuration」タブから行えます。
![wizard_select_qzss_fix_verify_review_send.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/cc9fd47e-eeab-a3d2-ba37-ef5fa9b08169.png)


ウィザードでの設定は以上で完了です。次に確認してみます。

##確認
設定変更前の衛星シグナル受信例の様子です。デフォルト設定ではGPSと、GLONASSの信号が観察できます。
![signal_default_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/915d495e-34bc-3cbf-8d18-e504c88526d5.png)


上記ウィザードによる変更後、QZSS信号が追加されました。
![signal_addQzss_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360475/ea784059-b7ad-431f-3360-77c437443f86.png)



いかがでしたが？合わせてマニュアル設定方法もご参照ください。
商品CSV登録時に画像も一括登録する方法

EC-CUBEで商品を一括登録する際、画像も一括で登録したいということがあると思います。

今回は、画像と商品データともに一括で登録する手順を説明します。

# 手順
## 画像を一括登録
- 全商品に使用する画像を準備
- 画像に対して名前を付与する  
今回は各商品に画像を3つずつ用意するとして以下形式で、画像に名前をつけておきます。

```
例）
商品A（商品コード1）にセットする画像：1-1.jpg / 1-2.jpg / 1-3.jpg
商品B（商品コード2）にセットする画像：2-1.jpg / 2-2.jpg / 2-3.jpg
商品C（商品コード3）にセットする画像：3-1.jpg / 3-2.jpg / 3-3.jpg
```

- サーバにログインし、`/html/upload/save_image/` に全画像ファイルをアップロードする


## 商品CSVをアップロード
- 商品CSVを作成します

```
例）
"商品名","検索ワード","商品コード","在庫数","商品画像"
"商品A","A","1","100","1-1.jpg,1-2.jpg,1-3.jpg"
"商品B","B","2","200","2-1.jpg,2-2.jpg,2-3.jpg"
"商品C","C","3","300","3-1.jpg,3-2.jpg,3-3.jpg"

```


-
【MovableType】カテゴリにスペースが入っていた場合のカテゴリ指定方法

MovableTypeで日本語サイト構築後に英語サイトを構築していた際に詰まったのでメモ。

##やりたいこと
記事一覧を出力する際、スペースが入った複数のカテゴリ名を除外したい


##解決方法

例：
カテゴリ名
日本語→「ニュース」「その他のニュース」
英語→「news」「Other News」

```MT:日本語サイト
<mt:Entries category="NOT ニュース AND NOT その他のニュース">
```
```MT:英語サイト
<mt:Entries category="NOT news AND NOT (Other News)">
```

##まとめ
蓋を開ければシンプルで、リファレンスの「category= ～」に書いてあった方法を試してみたら実現できました。
[]が有力かと思いきや()でよかったんですね。
リファレンスはやはり大切ですね。

##参考

[MTEntries - テンプレートタグリファレンス | CMSプラットフォーム Movable Type ドキュメントサイト](http://www.movabletype.jp.s3-website-ap-northeast-1.amazonaws.com/documentation/appendices/tags/entries.html)
EC-CUBE4で管理画面から背景色を変更する

今回は管理画面から**コンテンツ管理＞CSS管理**を使って背景色を変更する方法です。
CSSの変更にあたって参考にするのは下記です。

*EC-CUBE 4 Style Guide*
http://eccube4-styleguide.herokuapp.com/#/
編集したい部分を選択/検索して、【Show CSS】を押すと現在使用されているCSSが表示されます。

# 変更点を確認しよう
今回は背景色の変更になるのでヘッダー部分のCSSを変更します。
対象はec-layoutRoleのbackgroundです。
デフォルトでは【#fff】が設定されています。

```css
.ec-layoutRole {
  width: 100%;
  transition: transform 0.3s;
  background: #fff;
  & &__contentTop {
    padding: 0;
  }
```

参照先はこちら。
http://eccube4-styleguide.herokuapp.com/#/section/11.2

背景色のみ変更したいので、背景色を設定しているCSSだけ管理画面に記述します。

# CSS管理から背景色を変更しよう
**コンテンツ管理＞CSS管理**にてCSSを設定します。
背景色のみの変更となりますので、CSSとしては下記です。
※背景色は新たに【#ffa07a】を設定します。

```css
/* サイト全体の背景色変更 */
.ec-layoutRole {
  background: #ffa07a;
}
```

今後も更に色々と記述を追加することも考えて、この変更がどういった変更なのかコメントも合わせて設定しておきます。
![CSS管理1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422413/d72df86f-fef1-bee0-4a1d-2ce3c0211977.png)

ではサイトを見てみます。

![TOP1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422413/93ef44f0-97a4-b1db-59b9-229468095f70.png)
背景色が変更されています。
※もし反映されていない場合はキャッシュなどの影響が考えられるため削除してください。

ただヘッダーのカテゴリナビの部分が白いのが気になりますね。
こちらも変更しましょう。

# カテゴリナビの背景色を変更しよう
合わせて追加するのは下記の記述です。

```css
/* ヘッダーカテゴリナビの背景色変更 */
.ec-itemNav__nav li a {
  background: #ffa07a;
}
```
先ほどと同じように管理画面に設定します。
![TOP2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422413/f683c6ec-b227-0197-c98b-8de6708ed607.png)

さあ、もう一度サイトを見てみます。
![TOP2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422413/1886ba49-a70a-bbbd-4c98-f5bc4a58b8d6.png)
無事に反映されていますね。

以上で背景色の変更は完了です。

EC-CUBE4は元々のデザインのベースがシンプルなので、メインビジュアルや背景色/レイアウトの変更などによって大きくサイトの印象を変えることが出来ます。

是非こういった機能も活用してオリジナルなサイトづくりに役立ててください。
NuxtにGTMを入れて、ページタイトルをGAに送る

Nuxtに@nuxtjs/google-tag-managerをインストールしても、GA上でページタイトルが取得するために少し工夫がいるため、@nuxtjs/google-tag-managerを使用しないでGTMからGAに送るようにしました。
(GTMの設定は割愛します)

```gtm.js
class GTM {
  constructor(ctx, id) {
    this.ctx = ctx
    this.id = id
    this.loadScript(id)
  }

  loadScript(id) {
    const win = window, doc = document, script = doc.createElement('script'), dl = 'dataLayer'
    win[dl] = win[dl] || []
    win[dl].push({
      event: 'gtm.js',
      'gtm.start': new Date().getTime(),
    })
  
    if (!id) {
      return
    }
    script.async = true
    script.src = `https://www.googletagmanager.com/gtm.js?id=${id}`
    doc.body.appendChild(script)
  }

  pageTracking() {
    this.ctx.app.router.afterEach(function(to) {
      setTimeout(() => {
        window['dataLayer'].push({
          event: 'NuxtRoute',
          pageType: 'PageView',
          pageUrl: to.fullPath,
          routeName: document.title
        })
      }, 500)
      // ページ遷移時に、遷移前のタイトルを送ることがあるのでsetTimeoutで少し遅らせる
    })
  }
}

export default (ctx, inject) => {
  // 本番環境以外は動かさない
  if(process.env.NODE_ENV != 'production') return
  const $gtm = new GTM(ctx, 'GTM-XXXXXXX')
  // 今後の拡張のためinjectして、すべてのコンポーネントで使えるようにする
  inject('gtm', $gtm)
  $gtm.pageTracking()
}
```

```nuxt.config.js
  plugins:[
    { src: '@/plugins/gtm.js', ssr: false }
  ]
```

結構無理やりな実装になってしまいました。。。。
SQL Serverのクエリの書き方で学んだこと

#はじめに
SQL Serverに流すクエリの書き方で学んだことをまとめます。

#可読性を高める書き方
・命令語（SELECT等）は小文字でもエラーにならないが、全て大文字で統一するべき

#SELECT文
```sql:SELECT文の構文
SELECT 列,.. FROM テーブル WHERE 条件式 ORDER BY 並び替え基準列
```

-列：抽出対象の列。
-テーブル：抽出対象のテーブル
-条件式：出力データの絞り込み条件
-並び替え基準列：この列の値を基準に並び替える。通常は昇順。オプションでDESCを指定すると降順。

○列にアスタリスクを指定すると全列指定になる
○条件式で使える比較演算子

|比較演算子|意味|    
|:-:|:-:|
|A = B|A = Bか|
|A <> B|A != Bか|
|A > B|A > Bか|
|A < B|A < Bか|
|A >= B|A >= Bか|
|A <= B|A <= Bか|
|A BETWEEN B AND C|B <= A <= Cか|
|A LIKE '%B%'|AにBの文字列が含まれるか|
|A IN (B,C,...)|Aが括弧内の要素のどれかに一致するか|

#スカラ変数宣言から代入まで
```sql:宣言文の構文：
DECLARE @変数名 型名 = 代入値（代入部は省略可）
```
```sql:代入文の構文：
SET @変数名 = 代入値
```
-<font color="Blue">変数名</font>：任意の変数名
-<font color="Green">型名</font>：INTやVARCHARなどの型を指定
-<font color="Red">代入値</font>：代入する値。ここにSELECT文を書く場合は括弧で囲む必要がある

○宣言文、代入文をSELECT文内に書くことはできない

#CASE文の使い方
```sql:CASE文の構文(単純CASE式)：
CASE 変数名 WHEN 比較値 THEN 出力値 ELSE 規定値 END
````

```sql:CASE文の構文(検索CASE式)：
CASE WHEN 条件式 THEN 出力値 ELSE 規定値 END
```
-変数名：任意の変数名
-比較値：この値と変数名が一致すると条件成立
-出力値：条件に一致した時に出力する値
-規定値：どの条件にも当てはまらない時に出力する値
-条件式：条件式

○単純式は見やすく書きやすい。検索式は汎用性が高い

#バインド変数
- コロン(:)から始まる項目(Oracle等)やクエスチョンマーク(?)(他の言語)をプレースホルダと呼び、プレースホルダーを割り当てることを<font color="Red">バインド</font>と呼ぶ
- データベース管理システムへSQL文を発行する際、一部を動的に変更できる変数にする機能のこと。その部分に後から代入や変更を行ってもSQL文の再生成や解釈をし直す必要がなく、高速に実行することができる

#INSERT文
```sql:INSERT文の構文
INSERT INTO テーブル(列,...) VALUES(値,...)
```

-テーブル：値を挿入するテーブル
-列：挿入先の列
-値：挿入する値

○(列,...)部を省略するとテーブル内の全列を指定したことになる
○VALUES(値,...)部にSELECT文を書くと、他のテーブルから取ってきた値を入れたりできる


#サブクエリ
SELECT文を括弧でくくって色々な部分に組み込める。

```sql:例1
SELECT * FROM テーブル名1 WHERE 列名1 = (SELECT 列名2 FROM テーブル名2) 
```
```sql:例2
SELECT * FROM テーブル名1 WHERE 列名1 IN (SELECT 列名2 FROM テーブル名2) 
```

○乱用すると可読性が低下する

#リンクサーバー
リンクサーバーのテーブルを参照する為には以下のように記述する

```sql:リンクサーバーへのアクセス
[リンクサーバー名].[DB名].[テーブル名]
```

#UPDATE文
```sql:UPDATE文の構文
UPDATE テーブル名 SET 列名1 = データ1,... WHERE 更新条件
```
-テーブル名：更新対象のテーブル名
-列名：更新対象の列名
-データ：更新データ
-更新条件：更新する列を絞り込む条件
【急募】java.util.dateからjava.sql.dateへの変換ができません・・・・・。

こんにちは。
java.util.dateからjava.sql.dateへの変換ができません・・・・・。

現状としては、

①JSPにて、DATE型で日付をinputし、サーブレットへ送信
②サーブレットからDAOへ送信
③DAOのメソッド内で、受け取ったjava.util.date型の変数を、SQL文に格納する際にjava.sql.date型へ変換する必要があるとのエラーが表示されます。

どんな方法を試してもうまくいかないため、どなたか知識を共有していただければと思います。
よろしくお願いいたします。
NuGetパッケージの共有方法

社内用に作成したUiPathのライブラリを共有する方法を調査したメモ。

# 共有フォルダ
ローカルフォルダをソースに指定することができるので、共有フォルダも指定可能。
一番シンプルな方法。社内ネットワークの中だけで共有するなら、これで良さそう。

# Azure Artifacts
Azure DevOpsにパッケージ管理機能がある。

[Azure Artifacts を使って自前 NuGet サーバー運用を捨てる](https://blog.shibayan.jp/entry/20181126/1543219664)

DevOpsを利用できるならこれで良さそう。
ただし、パッケージ管理のためだけに使うのではお値段が高い。

# NuGet.Server
ASP.NETのWebサイトを自分で作って、それをNuGet.Serverにできるライブラリ。
それをAzureやIISにデプロイして使用できる。

[NuGet.Server を使用して NuGet フィードをホストする | Microsoft Docs](https://docs.microsoft.com/ja-jp/nuget/hosting-packages/nuget-server)

# NuGet Gallery
公式NuGet Galleryが作れる。
https://github.com/NuGet/NuGetGallery

# 参考サイト
[How to build and deploy a private NuGet server on IIS or Azure · Nicola Iarocci](https://nicolaiarocci.com/how-to-build-and-deploy-a-private-nuget-server-on-iis-or-azure/)
Rails Tutorial（2週目）-8-

#session
##HTTPはステートレスなプロトコル
>HTTPのリクエスト１つ１つは、それより前のリクエストの情報をまったく利用できない、独立したトランザクションとして扱われます。HTTPは言ってみれば、リクエストが終わると何もかも忘れて次回最初からやり直す健忘症的なプロトコルであり、過去を捨てた旅から旅の流れ者的なプロトコルです

そのため、HTTPにはユーザーIDを保存しておく手段がない
→sessionと呼ばれる半永続的な接続は、HTTPとは階層が異なるために、独立して扱うことができる。
→Railsではcookiesと言われるユーザーのブラウザに保存される小さなテキストデータを利用する

###ルーティングの確認
`$ rails routes`で現在のルーティングを確認

##sessonではエラーメッセージは手動
sessionはactiverocordオブジェクトを扱っていないので、自分でエラーメッセージを設定する必要がある
→フラッシュメッセージでエラーメッセージを表示

##sessionでのform_forの使い方
`form_for(@user)`のようなコードはuserモデルが存在するために、railsが自動で「フォームのactionは/usersというURLへのPOSTである」と解釈してくれるが、sessionの場合はsessionモデルが存在しないから、この方法は使えない

→セッションの場合はリソースの名前とそれに対応するURLを{ session: { password: "foobar", email: "user@example.com" } }的に指定する必要がある
`form_for(:session, url: login_path)`

ユーザーから送られたログイン情報は
params = { session: { password: "foobar", email: "user@example.com" } }
というハッシュに保存されている。

#フラッシュによるエラーメッセージの表示
```
 def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      # ユーザーログイン後にユーザー情報のページにリダイレクトする
    else
      flash[:danger] = 'Invalid email/password combination' # 本当は正しくない
      render 'new'
    end
  end
```

redirect_toではなくrenderを使ってレンダリングしても、フラッシュメッセージは残り続けてしまう
→`flash.now[:danger]`とすることで、メッセージはその後リクエストが発生したときに消滅する

##log_inメソッド
###sessionメソッド
Railsに事前定義済みのメソッド
`session[:キー] = 値`でセッションに情報を保存できる。キーを使って値を取りだせる

`session[:user_id] = user.id`
>上のコードを実行すると、ユーザーのブラウザ内の一時cookiesに暗号化済みのユーザーIDが自動で作成されます。この後のページで、session[:user_id]を使ってユーザーIDを元通りに取り出すことができます。一方、cookiesメソッド (9.1) とは対照的に、sessionメソッドで作成された一時cookiesは、ブラウザを閉じた瞬間に有効期限が終了します。

```実際のコード
def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      redirect_to user
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end
```

ログイン成功時の一連の流れ
①find_byメソッドを使って、ログインフォームに入力された情報をparamsハッシュから取り出して検索し、user変数に格納する
②ログインフォームに入力されたユーザーの存在性とauthenticateメソッドでパスワードをハッシュ化して、事前にハッシュ化して保存されていたパスワードと認証する。
③log_in ヘルパーを用いて、ユーザーのidをsession[:user_id]に保存する。

##現在のユーザー
current_userメソッドを定義することで、ログイン中のユーザーの情報を取り出しやすくする

```
def current_user
  if session[:user_id]
    User.find_by(id: session[:user_id])
  end
end
```
##テストユーザーの作成
テストユーザーのpassword_digest属性を設定するために、暗号化のメソッドをクラスメソッドとして、ユーザーモデルに定義する。

`BCrypt::Password.create(string, cost: cost)`
でパスワードが生成されている

>上のstringはハッシュ化する文字列、costはコストパラメータと呼ばれる値です。コストパラメータでは、ハッシュを算出するための計算コストを指定します。コストパラメータの値を高くすれば、ハッシュからオリジナルのパスワードを計算で推測することが困難になりますので、本番環境ではセキュリティ上重要です。しかしテスト中はコストを高くする意味はないので、digestメソッドの計算はなるべく軽くしておきたいです。

`cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                              BCrypt::Engine.cost`
>コストパラメータをテスト中は最小にし、本番環境ではしっかりと計算する方法

##ログアウト
>ログアウトの処理では、リスト 8.14のlog_inメソッドの実行結果を取り消します。つまり、セッションからユーザーIDを削除します15。そのためには、次のようにdeleteメソッドを実行します。
`session.delete(:user_id)`
【GNU Parallel】複数サーバーでコマンドを実行


#複数台のサーバーを管理されている方へ

インフラ屋のみなさん、今日も可愛いサーバーたちの子守をしてますでしょうか。
大規模 or 複数のプロジェクトのサーバー管理となると大変ですよね(小並)。
特に複数サーバーのログを収集する時やソースの反映時など。

今回はそんな悩みを解決するツールを紹介します。

# 目次

- [GNU Parallel](#gnu-parallel)
  - [導入方法](#導入方法)
     - [Mac(Homebrew)](#machomebrew)
     - [yum使える環境](#yum使える環境)
     - [それ以外の環境](#それ以外の環境)
  - [使い方](#使い方)
     - [複数のサーバーからSCP経由でファイル取得(転送も可)](#複数のサーバーからscp経由でファイル取得転送も可)
     - [複数のサーバーでgit clone](#複数のサーバーでgit-clone)
  - [所感・まとめ](#所感まとめ)


# GNU Parallel

- [GNU Parallel](http://www.gnu.org/software/parallel/)

並列でコマンドを実行できるらしい。

## 導入方法

※筆者はMac版しか試してません。。。。

### Mac(Homebrew)

```bash
$ brew install parallel
```

### yum使える環境

```
$ yum install -y parallel
## 実行時は「--gnu」オプションをつける
$ parallel --gnu echo ::: hoge
```

### それ以外の環境

```
## 執筆時点の最新版をここから(ftp://ftp.gnu.org/gnu/parallel/)ダウンロード
$ wget ftp://ftp.gnu.org/gnu/parallel/parallel-最新版.tar.bz2
$ tar xvjf parallel-最新版.tar.bz2
$ cd parallel-最新版
$ ./configure
$ make
$ sudo make install
```

## 使い方

### 複数のサーバーからSCP経由でファイル取得(転送も可)

```bash:scp_webserver.sh
#!/bin/bash
## リモートのログファイルをローカルへ(scp)
parallel -j+0 scp -i ~/.ssh/hogehoge.pem {}:~/ログファイルのパス ./logs/ :::: hostlist
```

上記の「hostlist」には、対象ホストの`ユーザー名@IPアドレス`が記載されてます。

```bash:hostlist
hoge@xx.xx.xx.xx
piyo@yy.yy.yy.yy
```

### 複数のサーバーでgit clone

```bash:gitclone.sh 
#!/bin/bash
## 対象ホストにSSHログインして複数のコマンドを実行できる
parallel -j+0 ssh -i ~/.ssh/hogehoge.pem {} '"
mkdir -p ~/contents/;
cd ~/contents/;
git clone git@github.com:fugahogepiyo/hoge.git;
"' :::: hostlist
```

## 所感・まとめ

実は僕自身、今現在はこのツールを利用してません。
過去には複数のサーバへのデプロイ作業や、アプリケーションログの収集などに利用していた時期もありました。
しかし現在では、デプロイツールが優秀であったり、そもそもログはfluentdで収集していたりなどで並列化する必要性が薄くなってしまいました。

「こういう技術があって、こういう使い方ができる」と考えていただければ幸いです。

## 参考リンク

http://gitpub.hatenablog.com/entry/2015/03/25/211652
http://bicycle1885.hatenablog.com/entry/2014/08/10/143612
(備忘録) Virtualbox等の仮想マシーンから抜ける方法

実オンプレミス環境に近づけた検証環境が必要になったので、仮想化技術をおさらいしています。

仮想マシーンから抜ける方法が分からなくなったのでここに記載しておきます。

###仮想マシーンから抜けるキー


|仮想マシーン        |キー組合わせ        　|
-------------------|----------------
|Virtualbox        |右側のControl  　　　 |
|Hyper-V           |Ctrl+Alt+Right-Arrow|
|VMWare            |Ctrl+Alt      　　　 |


###終わりに
happy hacking
チームで開発するためのBacklog運用ルール 

Backlogでプロジェクトの課題管理をする場合、何をするべきかまとめました。
大事なのは、「ルールを決めて、ルールを守る」ことです。
Backlogってなに？という人は[コチラ](https://backlog.com/ja/features/)を。

#1. ルールを決める


## 課題の書き方を決めよう
課題を書く人それぞれで書き方が異なると、読む人にとって負担です。課題の質を担保するためにも、書き方を決めましょう。テンプレートを作成して運用するのも効果的です。
具体的な例として、以下のようなルールがあります。

- ひとつの課題に複数の内容を含めない
- 課題詳細に共通の小見出しを使う（概要、完了条件、注意事項など）
- 課題詳細には「事実」を書き、意見や感想を含めない
- 課題詳細はメールのような文体にしない（○○さん、お疲れ様です〜のような）



## 課題の完了条件を明確にしよう
課題で大事なのは、「どうすれば完了なのか」が分かりやすいことです。
ざっくりとした作業の内容ではなく、できるだけ具体的に書きましょう。

**BAD...** 

- タイトルを変更する。

**GOOD!**

- テスト環境で、ディレクターが、タイトルの変更を確認したら完了。



## 課題の期限を決めよう
期限は作業の順番に影響します。仮でも良いので、課題製作時に設定しましょう。
期限の未設定は放置の元になります。



## 課題タイトルの書き方を決めよう
タイトルは単純かつ明快につけましょう。ルールが乱れやすい場所なので、注意が必要です。
大切なのは、１つの課題としての分かりやすさだけではなく、課題一覧として分かりやすいことです。

**GOOD**

- トップ画面のタイトルにアニメーションを追加

**BAD...**

- トップ画面にアニメーションを追加　→ 何にアニメーションをつけるの？
- 【トップ画面】タイトルにアニメーションを追加　→ 勝手な装飾ルールをつくらない
- トップ画面のタイトルにアニメーションを追加してください　→ 話し言葉にしない


## フローを決めよう
課題の登録や完了のフローを決めましょう。
課題を完了するのはプロダクトマネジャーに限定したり、親課題の完了は各職能のリーダーにするなどの方法があります。
重要な課題は責任者を含めた複数人が関わる方が良いですが、重要な範囲を広げすぎないことも大事です。例えば、バグ報告は課題登録者が確認して完了とするといったルールが良いと思います。


## 担当者を切り替えよう
ひとつの課題を複数の作業者が担当することはよくあることです。自分の作業が終わったら、次の人に担当を変更しましょう。作業が終わった課題を貯めていたら、プロジェクトは進みません。


## ファイルの管理方法を決めよう
Backlogには課題とは別に色々なファイルをアップロードする場所があります。こちらもルール化しないとゴチャゴチャになります。特によく更新されるデータは、最新のデータの場所を明確にしましょう。フォルダを整理した上で、Wikiにデータの場所について説明を書いておくと良いと思います。
ファイル更新時の連絡ルールとして、必ず課題を通すのは良い方法です。直接URLをSlackなどで送ると、後から文脈を追いにくくなるためです。



## 連絡方法を決めよう
仕事の連絡方法は色々なチャンネルがあります。（メール、Slack、電話…）
Backlogに登録した内容をSlackで連絡し、問題ないか電話で確認していては効率が悪いです。連絡のコミュニケーション・コストを最適化するために、「Backlogを中心に課題を管理する」といったやり方をチームで徹底するのも方法のひとつです。
もちろん、緊急時はコスト云々言ってられませんが。



## ルールを更新しよう
一度決めたルールは変えられないわけではありません。
使い勝手が良いよう、プロジェクトの状態に合わせて更新しましょう。更新のための確認フローを決めておくと良いかもしれません。更新を提案できる場と、相談できる相手がいれば、もやもやは減ります。
人や状況によって選ぶべきルールは変化します。その時々の最適解を探りましょう。



#2. ルールを守る

## Wikiを活用する
BacklogにはWiki機能があります。制作についての情報をまとめるだけでなく、Backlogの運用ルールを書いておきましょう。困った時の相談窓口も書いておくと良いです。


## チーム内に共有する
みんながルールがあることを意識している状態をつくらなくては、ルールは機能しません。
プロジェクトのはじめにしっかり話し合うことが肝心です。Backlog課題の書き方について話すことは、どうしても優先度が低く設定されがちです。期間の長いプロジェクトほど、はじめにしっかり共有することで、後から困らないでしょう。


## みんなで守る
プロジェクトが進むと、どうしてもルールがゆるくなることがあります。次の工程を担当する人のためにも、みんなでルールを守りましょう。
忙しい時、「とにかく課題を立てよう。内容の整理は後回しで」といった事が起こりがちです。ただ、その課題を受け取る人も忙しいことは容易に想像できます。忙しい時ほど丁寧に課題をつくりましょう。
どうしてもルールが乱れてしまった時は最終手段です。「みんなでBacklogルールを読み合わせる」という課題を立てましょう。


## 状況を確認する
ルールを守るためにも、まずは「自分の状況を知ること」が大事です。
Backlogを使い始めた人には、まず以下の３つを覚えましょう。

- 課題の検索をする（基本は、`完了以外` ＋ `自分が担当`の確認。）
- ガントチャートを見る（「いつまでに、何をするか」を意識する。）
- メール通知を設定する（必要な情報だけ届くように。もしくは分類する。）

マネージャーやリーダーは、複数人分の課題を見ることになると思います。１日の終わりや決めた曜日に必ず確認するといった習慣をつくると良いでしょう。Backlogで一番怖いのは、「放置」です。



#3. まとめ
今回、チームで開発する上でBacklogについて考えるべき項目をまとめました。
具体的にどういった内容のルールを選択するべきかは、プロジェクトの性質（規模、期間、スピード感、フェーズ）により多種多様です。規模が大きく、期間が長いほどルール化は重要になってきますが、小さいプロジェクトでも身軽なルールがあると良いでしょう。
大事なのは、ルールをつくるだけではなく、チーム内で共有し協力して運用することです。
上手に使って、効率的に開発しましょう。
#Slack のプロフィール設定の Full Name / Display Name の違いと、メッセージ入力中のアカウント名補完の甘い関係について。 ( 日本語の名前でも英語入力で検索したいですし )

# まとめ

- Full Name が アカウントの表示名になる
- Display Name (オプション) を設定すると、そちらがアカウントの表示名になる
- Full Name と Display Name の両方が、メッセージ入力中のアカウント検索の対象になる ( @ の後に出てくる補完 ) ( スペース / ハイフン / アンダースコアなどの単語区切りごとに前方一致 )

# 備考

- ワークスペースのデフォルト設定や個人設定にもよる
- Full Name / Display Name の扱いを入れ替えることもできるが、デフォルト設定だと上記の通りっぽい


# 用法用例

- Full Name 稲浦 悠馬 yuma inaura / Display Name いなうらゆうま とかいう設定にしておくと、表示名はシンプルに、補完は柔軟にできる


# 参考

[名前の表示方法を変更する – Slack](https://get.slack.help/hc/ja/articles/115004692303-%E5%90%8D%E5%89%8D%E3%81%AE%E8%A1%A8%E7%A4%BA%E6%96%B9%E6%B3%95%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B)

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2045








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
GitLabのアカウント情報（パスワード）を変更したらSourceTreeからPush,Pull,Fetchができなくなった場合の対処法


# TL;DR

SourceTreeが保存していたアカウント情報のファイルを消して再サインインしたら直った。
（環境は**Windows10**の**SourceTree**）

# GitLabのパスワードを変更したらSourceTreeからPush,Pull,Fetchができなくなった

まあ普通に当たり前なんですが、**GitLab上でパスワードを変更したらSourceTreeからPush,Pull,Fetchができなくなった**
しかしとくに再認識のためのアカウント入力ウィンドウも出てこない。

ちなみにエラーとしては

```
remote: HTTP Basic: Access denied
```

とでてました。

# 解決方法

**`C:\Users\USERNAME\AppData\Local\Atlassian\SourceTree`**以下にある**`passwd`というファイルを削除する**か、
このファイルの中の**Gitホスティングサービスごとに書かれているアカウント情報（2行分）を消して保存**してやると、
**SourceTreeからPush,Pull,Fetchする際に再認証のためのウィンドウが出てくる**ので、そこに**現在のアカウント情報を入力してやる**といいみたいです。

![WS000015.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85815/7609584b-897f-7c8f-fc16-574727eded9f.jpeg)

Macはちょっとわからないです。

# なおらんが？

Windowsの場合、**コントロールパネル**から「**資格情報マネージャー**」を開いて、そこの「**Windows資格情報**」から、
Windowsに記録されている**Gitホスティングサービス（ここではGitLab）の資格情報を削除**してみてください。
調べてみると、このエラーの多くの場合は**アカウント情報変更後も変更前の情報（資格情報）を使ってアクセスしようとするのでエラーがでる**みたいです。

↓以下の画面から該当する資格情報を削除
![WS000016.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85815/d8e30a5d-69d0-2ff5-40dd-ed8e6a946390.jpeg)

# ちがうみたいだが？？

ごめんなさい、これ以上はちょっとわかんないです。。

# 参考URL
- [Solved: How to update HTTP(S) credentials in sourcetree](https://community.atlassian.com/t5/Sourcetree-questions/How-to-update-HTTP-S-credentials-in-sourcetree/qaq-p/297564)
- [git - GitLab remote: HTTP Basic: Access denied and fatal Authentication - Stack Overflow](https://stackoverflow.com/questions/47860772/gitlab-remote-http-basic-access-denied-and-fatal-authentication)
webpackに引数を渡す

bundleをいくつか作らないといけない時に、毎回 webpack.config.js を書いてると大変なので…（今回１００くらい書かなくちゃいけなさそうになりました）webpackに引数を渡して、それによって分岐できるようにしました。

## 公式
[webpack：Environment Variables](https://webpack.js.org/guides/environment-variables/)
正直、`env.`の後ろが決まった名前なのかどうなのかよくわからなかった。
やってみたらなんでもできた。

## webpackに引数を渡す
```コマンドライン
webpack --env.hoge=ほげ
```
複数ある場合も半角スペース区切りでできる
```
webpack --env.hoge=ほげ --env.fuga=ふが
```


```webpack.config.js
module.exports = env => {
  console.log('hoge: ', env.hoge);  // 出力：ほげ

  return {
    // ...いつものentryとかoutputとか
  };
};
```
`module.exports` の後ろに `env` があるのがポイント。


## npm runに引数を渡す
```コマンドライン
npm run build -- --env.fuga=ふが
```
`--`が`--env.xxx=zzz`の前にあるのがポイント

```package.json
  //略
  "scripts": {
    "build": "webpack",
  },
  //略
```

```webpack.config.js
module.exports = env => {
  console.log('hoge: ', env.fuga);  // 出力：ふが

  return {
    // ...いつものentryとかoutputとか
  };
};
```

## 引数による分岐
```webpack.config.js
module.exports = env => {
  console.log('design: ', env.design);

  const entries = ['main.js'];
  if (env.design == 'a') {
    entries.push('design_a.js');
  }

  return {
    entry: entries,
    // ...略
  };
};
```
mery 風 head css

僕はメリーのデザインが好き。
ということで、ヘッダを再現してみました。

```style.css


    .cover {
        position: relative;
        overflow: hidden;
        max-height: 300px;
        height: 211px;
    }

    .cover span.crop_image {
        height: 100%;
        display: block;
        background-color: rgb(245, 245, 245);
        background-position: center center;
        background-repeat: no-repeat;
        background-size: cover;
        background-image: url('/img/hoge.jpg');
        vertical-align: middle;
    }


    .cover .filter {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-image: -webkit-gradient(linear,left top,left bottom,color-stop(65%,rgba(0,0,0,.06)),color-stop(80%,rgba(0,0,0,.15)),to(rgba(0,0,0,.18)));
        background-image: -webkit-linear-gradient(rgba(0,0,0,.06)65%,rgba(0,0,0,.15)80%,rgba(0,0,0,.18));
        background-image: linear-gradient(rgba(0,0,0,.06)65%,rgba(0,0,0,.15)80%,rgba(0,0,0,.18));
    }

    .cover .curator {
        position: absolute;
        bottom: 15px;
        left: 15px;
        color: #fff !important;
    }


    .icon.icon-button-float-love {
        background-image: url(https://a.mery.jp/8a2ceea/images/sprites/sprite.@2x.icon.8419ab5c.png);
        background-position: -149px -161px;
        background-size: 448px 437px;
        width: 64px;
        height: 64px;
    }


    #btn-waku {
        position: relative;
        padding: 0 15px;
    }


    .like-button {
        position: absolute;
        top: -30px;
        right: 15px;
    }

    .icon.icon-button-float-love {
        background-image: url(https://a.mery.jp/8a2ceea/images/sprites/sprite.@2x.icon.8419ab5c.png);
        background-position: -149px -161px;
        background-size: 448px 437px;
        width: 64px;
        height: 64px;
    }

    .icon {
        display: inline-block;
        margin: -1px auto 1px;
        vertical-align: middle;
    }




```


そして

```hoge.html


<div class="cover">
                <span class="crop_image"></span>
                <div class="filter"></div>

                <a href="#" class="curator">
                    <img src="https://pbs.twimg.com/profile_images/945436187056947200/ROg1tP94_normal.png"><span>hideki</span>
                </a>
            </div>


            <div id="btn-waku">
                <div id="fav_area1" class="like-button">
                    <div id="like_bt" class="js-nonUserLove">
                        <span class="icon icon-button-float-love"></span>
                    </div>
                </div>
            </div>

```

とりあえずコピペで動きます。
識別関数と事後確率

決定問題を解く3つのアプローチ
⑴ 生成モデル
⑵ 識別モデル
⑶ 識別関数を求めるモデル(確率は計算しない)

上記の3つのアプローチの使い分けに関して
⑶は具体的に入力xを引数にとり、分類問題では直接入力の分類先を出力する識別関数f(x)を求める。つまり、推論段階と決定段階がすべて識別関数である分類器の生成問題にまとめられている。

⑶のアプローチでは事後確率$p(C_k|x)$を求める必要がないように思える
しかし、以下で事後確率を計算する必要性を示す

リスク最小化：損失行列の要素が時間とともに変化する場合
識別関数のみを使って意思決定を行う場合、損失行列を修正したとき訓練データに戻ってクラス分類問題を一から解き直すことになる
→ 計算資源の非効率的な無駄を省く(リスク最小化)ために、事後確率を計算しておく必要がある