OmniAICreator/Qiita-1.07M huggingface dataset:
WindowsにBlenderとBlender GISをインストールする

# WindowsにBlenderとBlender GISをインストールする

**※現在最新のSTABLEであるBlender 2.79b とBlender GISをWindows版にインストールする場合についての記事です。**

Blender GISの以下の手順がベースとなっています。

[How to install GDAL](https://github.com/domlysz/BlenderGIS/wiki/How-to-install-GDAL)


## パッケージのダウンロード

- [Bledner 2.79b](https://www.blender.org/download/)
- [Blender GIS/Branch:Blender279](https://github.com/domlysz/BlenderGIS/tree/Blender279)
- [GDAL‑2.4.1‑cp35‑cp35m‑win_amd64.whl](https://www.lfd.uci.edu/~gohlke/pythonlibs/#gdal)
    - 該当バージョンがない場合は新しいものでも（たぶん）大丈夫。
- [numpy-1.16.4+mkl-cp35-cp35m-win_amd64.whl](https://files.pythonhosted.org/packages/b4/1b/36bd20a4a1f41729c406014974925598edaeca1ca2510a2843892329b2f1/numpy-1.16.4-cp35-cp35m-win_amd64.whl)

## インストール手順

### Blenderインストール

**blender-2.79b-windows64.msi** を実行し、普通にBlenderをインストールします。
Blenderのインストールパスは**%BLENDER_DIR%**とします。

### 既存のnumpyを削除
**%BLENDER_DIR%\2.79\python\lib\site-packages\numpy** フォルダを削除します。
Blender GIS公式には言及がありませんが、この手順を行わないと正常に動作しません。

### pythonのセットアップ
python環境のセットアップを行います。必ずBlednerバンドル版のpythonを実行してください。
また、実行時は管理者モードで実行してください。

```BAT
REM pipセットアップ
"%BLENDER_DIR%\2.79\python\bin\python.exe" -m ensurepip
REM numpyアンインストール(失敗しても気にしない）
"%BLENDER_DIR%\2.79\python\bin\python.exe" -m pip uninstall -y numpy
REM numpyセットアップ
"%BLENDER_DIR%\2.79\python\bin\python.exe" -m pip install .\numpy-1.16.4+mkl-cp35-cp35m-win_amd64.whl
REM gdalセットアップ
"%BLENDER_DIR%\2.79\python\bin\python.exe" -m pip install .\GDAL-2.4.1-cp35-cp35m-win_amd64.whl
```

### GDAL_DATAの設定
GDAL用の環境変数 *GDAL_DATA* を以下のパスに設定します。
**%BLENDER_DIR%\2.79\python\lib\site-packages\osgeo\data\gdal**
![2019-06-28_18h07_40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22962/417743e4-7385-3fe2-1584-e39c059c48f7.png)

### GDALテスト
インストールしたGDALパッケージが正常に動作するかチェックします。
Blenderを起動してpythonコンソールから以下のスクリプトを実行します。エラーが表示されなければOKです。

```python
from osgeo import gdal
from osgeo import gdalnumeric
```
さらに次のスクリプトを実行して戻り値が0ならば正常です。

```python
from osgeo import osr
osr.SpatialReference().ImportFromProj4('+init=epsg:3857')
```

### Blender GISアドオンの設定
あとはBlender GISアドオンを通常の手順で追加してください。

[[Blender] アドオンのインストール・アップデート・アンインストール方法のまとめ](https://qiita.com/nutti/items/5e9ebe9c28751066b688#%E6%96%B9%E6%B3%952%E3%82%A2%E3%83%89%E3%82%AA%E3%83%B3%E7%94%A8%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AB%E3%82%A2%E3%83%89%E3%82%AA%E3%83%B3%E3%81%AE%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E7%9B%B4%E6%8E%A5%E9%85%8D%E7%BD%AE%E3%81%99%E3%82%8B)

他の記事でアドオンをpythonスクリプトで有効化する方法について書いたので参考にしてください。
[pythonスクリプトでBlenderのaddonを有効にする](https://qiita.com/warenashi/items/b8fd9953ffd6f50f4387)
kotlinのコメントをドキュメントコメントに変換する正規表現

# やりたいこと

```
// コメント
```

↓

```
/** コメント */
```

# やり方

1. VSCodeで置換のショートカットを押す(Macの場合は`⌥⌘F`)
2. 以下を入力して置換する
 - フィールド1: `//(.*)`
 - フィールド2: `/**$1 */`
Railsと併用中のReact.jsを15系から16系にバージョンアップした際に詰まった事をまとめてみた

Railsのjavascriptの既存資産を流用するため `react-rails` を活用していた環境で併用しているReact.js(15系を利用中)に関して、17系がそろそろリリースされるため16系の最新バージョンに上げる事になった。

それに伴い、react-railsを Asset Pipeline方式からWebpack方式に変更した。
→ 理由： 従来から言われているように、Asset Pipeline方式だと、コードをapp/assetsやlib/assetsなどに置くか、誰かがgem化してくれるまで待つ事になる。javascriptでは同じことを、npm installコマンドやarn addコマンド一発で取り込めるよう対応している。また、Asset Pipelineを支えるビルドツールのSprocketsメンテ状況が良くない。

■バージョンアップ前の環境
・React.js： v15.6.2
・Ruby： 2.6.3
・react-rails： 2.4.7（Asset Pipeline方式）
・webpacker： 3.5.5

■バージョンアップ後の環境
・React.js： v16.8.6
・Ruby： '2.6.3'
・react-rails： 2.5.0（Webpack方式）
・webpacker： 4.0.7

# ■1. react-railsとwebpackerのバージョンアップ
### ▽詰まったところ
バージョンアップ対応当初は気づかなかったのだが、react-rails： 2.4.7を利用していると、React.jsのバージョンが15系に固定されるようだった（隣に座っている神エンジニアが発見してくださった）。元々、Asset Pipelineに15系のReact.jsとReactDOMのコードファイルを読み込ませていたのだが、これによって、React.jsが15系になっていたのではなかったのだと後から知った。。。

### ▽対応方法
react-railsとwebpacker gemのバージョンアップ

# ■2. babel-polyfillの置き換え
### ▽詰まったところ
厳密には詰まっていないが、各ブラウザに対応するため、元々、`babel-polyfill`というライブラリーをimportしていた箇所があった。Babelも最新の7系にしようと色々な情報を探したところ、大半は、`@babel/polyfill`を利用するようにとあったが、この方法の採用は実は非推奨になっていた。

### ▽対応方法
`@babel/polyfill`ではなく、`core-js/stable`と`regenerator-runtime/runtime`をimportする。
→背景としては、直近のBabelのバージョンアップで、Babel7.4.0から`@babel/polyfill` の利用は避ける方向になっていた。。。
参考： https://aloerina01.github.io/blog/2018-11-29-1

# ■3. PropTypesやライフサイクルメソッドの修正
### ▽詰まったところ
React.jsの16系から、`prop-types`がReact.jsの本体から切り離された事を最初知らず、props関連のエラーが大量発生してしまった。

### ▽対応方法
`import PropTypes from 'prop-types';`する。
また、PropTypesの定義をオブジェクト形式での指定から以下のように変更した。

~~~React.js:PropTypesの定義（他の書き方もあるが１例）
static get propTypes() {
  return {
    onSelect: PropTypes.func.isRequired
  }
}
~~~

# ■4. React.js17系で廃止予定のライフサイクルメソッド対応
※こちらは特に詰まっていない。以下を参考に対応した。
https://qiita.com/mori-dev@github/items/c0a458384b5390494784

### ▽対応方法
React.js17系で廃止予定のライフサイクルメソッドを洗い出し、先頭に`UNSAFE_` を付与する対応を一括変換にて実行した（根本対応は時間がある際に対応する事にした）。

＜廃止予定のライフサイクルメソッド＞
・ componentWillMount
・ componentWillReceiveProps
・ componentWillUpdate

# ■5. .babelrcからbabel.config.jsへの変更
### ▽詰まったところ
途中、`.babelrc`か`webpack.config.js`に記載するものなのか、個人的に混乱してしまった。Compileが成功したりしなかったりしてエラーが分かりにくかったため、修正に修正を重ねて途中で動作しなくなり困ってしまった。。

### ▽対応方法
こちらは、隣に座ってる神エンジニアに相談したところ、あっさり解決された。。。
対応された内容は、`react-rails` のWebpack利用方式の初期コマンドを実行し、生成された`babel.config.js`に必要な記述を加えただけとの事だった。

個人的に、`.babelrc`と`babel.config.js` で何が異なるのか疑問だったため公式ページを参照した。
公式ページ： https://babeljs.io/docs/en/config-files#root-babelconfigjs-files

調べた結果としては、結論、どちらを利用して良いように思う。今回は、`react-rails` のWebpack利用方式の初期コマンドにてデフォルトで生成された方が安心という事で、`babel.config.js` を採用する事になった。

# ■最後に
バージョンアップ対応前は自分自身で何とか対応できるつもりだったが、実際対応してみると、利用しているライブラリの公式ページの読み込みが浅かったり、原点に立ち返って検証をやり直して解決のアタリを付けていなかったり等、やるべき事が全くできていなかったという反省しかない。。。

次に同じようなバージョンアップ対応があった時は、今回の反省を踏まえてリベンジしたい。
日々の進捗ノート_言語処理100本ノック09

# 09. Typoglycemia
>スペースで区切られた単語列に対して，各単語の先頭と末尾の文字は残し，それ以外の文字の順序をランダムに並び替えるプログラムを作成せよ．ただし，長さが４以下の単語は並び替えないこととする．適当な英語の文（例えば"I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind ."）を与え，その実行結果を確認せよ．


```gen09.py
import random
def shuffle_doumei_ken(sentence):
    word_list = sentence.split(" ")
    result = ""
    for i in word_list:
        if len(i) > 4:
            firstchr = i[0]
            centerchr = "".join(random.sample(i[1:-1],len(i)-2))
            lastchr = i[-1]
            result = result + " " + firstchr + centerchr + lastchr
        else:
            result = result + " " + i
    result = result[1:]
    return result

sentence = input("文章を入力してください") 
print (shuffle_doumei_ken(sentence))
```
####結果
`文章を入力してくださいI couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind .
I cul'odnt bilevee that I cluod alltacuy uredtnsnad what I was rndaeig : the penoehnmal power of the haumn mind .`

####備忘録
・random.shuffle()は入れたオブジェクトそのものに対する操作なので，変更不可である文字列には使えない．
深層学習（前編 1）：「Section3：出力層」

出力層では、最終的な総入力u = Wx + bを活性化関数に代入して、正解値との誤差関数を求める。活性化関数と誤差関数の組み合わせは以下の通り。
回帰問題
活性化関数：恒等写像、誤差関数：二乗誤差
二値分類
活性化関数：シグモイド関数、誤差関数：交差エントロピー
多クラス分類：
活性化関数：ソフトマックス関数、誤差関数：交差エントロピー
※yを出力層のアウトプット、dを正解値として、二乗誤差：1/2Σ(yn-dn)2、交差エントロピー：-Σdilogyi
Cookieの情報を【取得/保存/削除】する

## Cookieとは
Cookie（クッキー）とは、ホームページを訪問した ユーザーの情報を一時的の保存する仕組みです。
サイトを訪れた日時、訪問回数など、様々な内容が ユーザー情報として保存されることによって、サイトを再訪問したときにユーザーを特定し、情報を入力する手間が省けます。

①IDとパスワードを入力して一度ログインしたサイトに、しばらくしてから再度アクセスするとIDとパスワードを入力せずに入ることができる。
②ショッピングサイトに訪問したとき、すでにログイン状態になっていたり、カートに入れた商品がそのまま残っている。

どちらも、ログイン/カート情報がCookieに保存されているおかげ！！
このように、CookieはWebサイトのアクセスを便利にしたり、様々なサービス提供を可能にすることに一役買っています。（インターネットバンキングの多くもCookieが有効になっていないと使用できない）

##Cookieから値を取得する
Cookie取得の基本であり、シンプルな方法です。
ただ、Cookieに複数の値が書き込まれている場合";"で区切られた文字列として取得するので、すご～くわかりにくい…

```javascript
var str = document.cookie;
// 「 key1=val1; key2=val2; key3=val3; ・・・ 」
```
##Cookieをkeyで取得する
Cookieから値を取得して連想配列にセットします。
これでCookieがすご～く扱いやすくなります。

```javascript
// 連想配列に格納
function getCookieArray(){
    var arr = new Array();
    if(document.cookie != ''){
        var tmp = document.cookie.split('; ');
        for(var i=0;i<tmp.length;i++){
            var data = tmp[i].split('=');
            arr[data[0]] = decodeURIComponent(data[1]);
        }
    }
    return arr;
}

// keyを指定して取得
// 「 key1=val1; key2=val2; key3=val3; ・・・ 」というCookie情報が保存されているとする
var arr = getCookieArray();
var value = 'key1の値：' + arr['key1'];
// key1の値：val1
```
##Cookieの保存と削除
###Cookieの下準備
```javascript
var kigen = 30; //Cookieの期限（1ヶ月とする）←適宜、適切な期限を設定
var nowdate = new Date(); //現在の日付データを取得
nowdate.setTime(nowdate.getTime() + kigen*24*60*60*1000); //1ヶ月後の日付データを作成
var kigendate = nowdate.toGMTString(); //GMT形式に変換して変数kigendateに格納
var cookievalue = "session_id=user_0001; ";
var expires = "expires=" + kigendate + "; ";
var path = "path=/";
var dt = new Date('1999-12-31T23:59:59Z'); // 過去の日付をGMT形式に変換
```
クッキーの値（上記ソース内cookievalueに値する）にはセミコロン ( ; )、カンマ ( , ) や空白を含めてはならないので、書き込む値はencodeURIComponent()でエンコードしましょう。

※セキュリティの観点から考慮して、半永久的にユーザー情報を保持しているのは良くないため、期限を設定するのが慣例となっています。

###Cookieにデータを書き込む（保存）
```javascript
document.cookie = cookievalue + expires + path;
```
###Cookieのデータを削除する
「Cookie」には有効期限を設定することができ、期限が過ぎると「cookie」のデータが自動的に削除されるので、意図的に削除することが可能となります。

```javascript
document.cookie = "session_id=; expires=" + dt.toUTCString() + "; "+ path
// 「expires=dt.toUTCString();」の部分は「max-age=0;」でもOK
```
「expires=dt.toUTCString()」というのは有効期限が「過去の日付」を表していて
「max-age=0」というのは有効期限が「0秒」という意味なので
どちらを使用しても、即座にCookieを削除ができるというわけです。

###Cookieのオプション属性
|  属性  |  内容  |
| ---- | ---- |
|  path  |  指定したパスがcookieの有効範囲  |
|  expires  |  指定した日付までが有効期限  |
|  max-age  |  指定した秒数だけ有効期限  |
|  domain  |  指定したドメインがcookieの有効範囲  |
|  secure  |  https通信の時だけcookieが有効  |
domainとsecureは個人的には使ったことないな…

##Cookieの危険性【セッションハイジャック】
Cookieの識別子が漏えいすることによるセッションハイジャック。

CookieにはサイトのセッションIDとともに、ログイン情報が含まれていることがあり、この情報自体がSSLなどで暗号化されていても、セッションIDさえわかってしまえばサーバーに送ることでログイン状態が再現されてしまいます。

Cookieは便利な反面、セキュリティに関するリスクがあることも認識して、セキュリティを高めてプライバシーを守りたい場合は、Cookieを削除するように設定を変更するなどの対応をしましょう。
[C#]クラス自体がinternalなときのUnitTest

# UnitTest関連記事
https://tera1707.com/entry/2022/02/06/144447#UnitTest


# やりたいこと
[以前](https://qiita.com/tera1707/items/c1d4dee3611bb693dd10)、private、internalなメソッドをUnitTestしたいときのやり方を調べたが、クラス自体がinternalだったときに、そもそもUnitTest側コードからそのクラスが見えないため、テストできなかった。何とかUnitテストしたい。

# やり方
InternalsVisibleTo属性を使う。

まず、dll側のAssenblyInfo.csを開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/8771ec1f-4a39-803a-3fa3-3f51d097d78d.png)

そこに、下記の一文を追加する。
「UnitTestProject1」の部分は、internalクラスを公開する公開先のアセンブリ名を書く。

```cs
[assembly: InternalsVisibleTo("UnitTestProject1")]
```

これで、公開先のアセンブリ(ここでいうところの「UnitTestProject1.dll」)からは、Class1に含まれるinternalなクラスが見えるようになる。

# コード
https://github.com/tera1707/WPF-/tree/master/028_PrivateClassUnitTest
※[以前](https://qiita.com/tera1707/items/c1d4dee3611bb693dd10)のコードと同じ。Class1とClass1Subがinternalにしただけ。

# 参考

Visual Studio の単体テストで利用するInternalsVisibleTo属性について
http://moriblog.kit-eng.com/?p=867
【Linux】サーバ上に調査結果を保存して、ローカルにコピーする

システムの不具合調査などでサーバに入ってlogを調査する際、そのlogを保存したり、ローカルにコピーしたりしたいことってよくありますよね。

でも、そういう時に限ってコマンドや書き方を忘れてしまい、急いでググることもまたよくありますよね。

調査時に使いそうなコマンドを自分のメモとして書き起こします。


## シーン1：hogehoge.logファイルを開き、fugafugaが含まれる行を抽出し、結果をtmpディレクトリ直下に 'piyopiyo.txt'という名前で保存する

`cat hogehoge.log | grep 'fugafuga' > /tmp/piyopiyo.txt`

使うのは'cat'と'grep'と'>（リダイレクション）'と'|（パイプ）'

ちなみに、リダイレクションは'>'で上書き、'>>'で追記になり、ファイルが存在しない場合はどちらも新規作成されます。
参考：https://shellscript.sunone.me/input_output.html


## シーン２：ssh鍵を指定してリモートサーバーからローカルのDesctopにpiyopiyo.logを保存する

`scp -i 秘密鍵ファイル user@IP:/tmp/piyopiyo.txt ~/Desktop/`

使うのは'scp'

秘密鍵を用いて接続する場合はiオプションを指定してあげます。
[AWS] Kinesis Firehoseの自分まとめ

# [[AWS] Kinesis Firehose](https://docs.aws.amazon.com/ja_jp/firehose/latest/dev/what-is-this-service.html)

- リアルタイムデータを指定先へ配信するための完全マネージド型サービス
- Kinesisストリーミングデータプラットフォームの一部
- アプリケーションの記述、リソース管理の必要なし
- データ送信先のプロデューサーを設定すると指定した送信先にデータが自動的に配信される
- データの配信前に変換するように設定も可能

## 主な配信先

- S3
- Redshift
- Elasticsearch Service
- Splunk

## 主要コンセプト

### 配信ストリーム  
- 基盤となるエンティティ
- Firehoseの使用には配信ストリームを作成しそれに対してデータを送信する

### record
- データプロデューサーがFirehose配信ストリームに送信する目的のデータ
- レコードの最大サイズは `1,000KB (1MB)`

###  データプロデューサー
 -  プロデューサーはFirehose配信ストリームにレコードを送信します
 -  例えば配信ストリームにログデータを送信するWEBサーバーはデータプロデューサー
 -  Firehose配信ストリームが自動的に既存のKinesisからデータを読み取り配信先にロードするよう設定することもできる

###  バッファサイズおよびバッファ間隔
-  Firehoseは特定の期間、受信するストリーミングデータを特定のサイズにバッファして送信先に配信する
-  バッファサイズは `MB単位` でバッファの間隔は `秒単位`

## データフロー

- いくつかの配信先のデータフロー
  - https://docs.aws.amazon.com/ja_jp/firehose/latest/dev/what-is-this-service.html#data-flow-diagrams

### S3

1. Firehoseにデータレコードが送信される
2. バッファ設定に応じてバッファする
3. バッファが設定値を超えたらS3へデータを配信する
4. データ変換が有効の場合は元データを別バケットへバックアップ取得も可能　

## [データ配信](https://docs.aws.amazon.com/ja_jp/firehose/latest/dev/basic-deliver.html)

### S3へのデータ配信頻度

- バッファサイズとバッファ間隔によって決まる
- 上記どちからを満たした場合データ配信がトリガーされる
- 送信先へのデータ配信が配信ストリームへのデータ取り込みより遅くなった場合自動的に遅れを取り戻す

#### バッファサイズ

- 1MB ~ 128MB
  - 圧縮前のサイズ
  - 通常はGZIPでの圧縮

#### バッファ間隔

- 60秒 ~ 900秒

### データ配信の失敗

- Firehoseは配信が成功するまで最大24時間にわたり再試行する
- Firehoseのデータ最大保持期間は24時間
- 24時間を超えて失敗した場合はデータ消失する

### S3のデータ整理

- 配信されたデータはUTC時間のプレフィックスを `YYYY/MM/DD/HH` 形式で追加してS3に配信される
- 任意の最上位フォルダとフォワードスラッシュを追加できる（myApp/YYYY/MM/DD/HH）
- `YYYY`　の前に任意のテキストを追加できる（myAppYYY/MM/DD/HH）
- 配信ストリーム作成時に上記設定が可能

### カスタムプレフィックス

- Hive形式などのプレフィッスを指定可能
  - [参考](https://docs.aws.amazon.com/ja_jp/firehose/latest/dev/s3-prefixes.html)
- `year=yyyy/month=mm/day=dd` とか
- 時間形式は `UTC となっている
  - `JST` と合わせる場合は `-9h` する必要がある

### オブジェクトの命名規則

- `DeliveryStreamName-DeliveryStreamVersion-YYYY-MM-DD-HH-MM-SS-RandomString`
- `DeliveryStreamVersion` は1からはじまる
  - 配信ストリームの設定が変更されるたびに1ずつ増加する

## [入力レコード形式の変換](https://docs.aws.amazon.com/ja_jp/firehose/latest/dev/record-format-conversion.html)

- データをS3へ保存する前に入力データ形式をJSONから変換できる
- `Apache Parquet` または `Apache ORC` に変換可能
- ParquetとORCは容量を説やしJSONの行指向の形式に比べてより高速なクエリを可能にするカラム
- JSON以外の場合（CSVとか）はまずはLambdaでJSONに変換することも可能
  - [参照](https://docs.aws.amazon.com/ja_jp/firehose/latest/dev/data-transformation.html)

### 配信先（重要）

- レコード形式の変換を行うと以下サービスに配信できなくなる
  - Elasticsearch Service
  - Redshift
  - Splunk

- S3のみ有効

### 変換の要件

#### JSONを読み取るでシリアライザー
- JSONに含まれるタイムスタンプの形式に応じてシリアライザーを選択する
  - [詳細](https://docs.aws.amazon.com/ja_jp/firehose/latest/dev/record-format-conversion.html#record-format-conversion-deserializers)
- 位置情報であれば `OpenX JSON SerDe`　を使用する
  - `yyyy-MM-dd'T'HH:mm:ss[.S]'Z'` に対応している為

#### データの解釈方法を決定するスキーマ
- AWS Glue を使用してデータカタログにスキーマを作成する
- Firehoseはスキーマを参照し使用して入力データを解釈する
- [参照](https://docs.aws.amazon.com/glue/latest/dg/populate-data-catalog.html)

#### データをターゲットのカラム型ストレージ形式に変換するシリアライザー

- `Parquet` か `ORC` から選択

## SLA

- `99.9%` の月間稼働率を保証
客先常駐の仕事で99%出てくる頻出ソフトウェア・ツール三種の神器

# はじめに
[@neet_se](https://twitter.com/neet_se)といいます。
普段はフリーランスエンジニアとして客先常駐の仕事をしています。
エンジニアとして働き始めて、現在5,6の客先を経験しました。

今回はその中でよく出てくるソフトウェアやツール類を紹介していきたいと思います。

# 1.Windows 10
説明不要、Windowsです。

Webの仕事ですとMacの比率が上がると思いますが、業務用システムの開発では殆どWindowsです。
Windowsのよく使うショートカットキーや機能は覚えておくのはマストでしょう。

ファンクションキーまで使いこなすと定型作業が楽になります。

## 1-1.ショートカットキー
### 1-1-1.必修
Ctrl+C:コピー

Ctrl+V:ペースト

Ctrl+X:切り取り

Ctrl+Z:元に戻す

Ctrl+Y:操作を戻す

Ctrl+S:上書き保存

F5:ページの再度読み込み

### 1-1-2.最初から覚えてると一目置かれる
F2:ファイルを選択した状態だとファイル名の変更

Alt+F4:ウィンドウを閉じる

Windowsキー+↑:ウィンドウを最大化（全画面）

参考：https://linq.career-tasu.jp/magazine/knowhow-windows-short-cut-key40/

# 2.Excel
はい、Excel職人で悪名高いExcelです。笑
Office製品は色々ありますが、その中でもExcelの使用頻度が高いと思います。

Windowsや他のOffice製品のショートカットキーと被る部分はありますが、Excelでよく使うショートカットキーも存在します。
ショートカットキーを覚えること、Excelの数式を覚えること、できれば簡単なマクロを最初から組めれば一目置かれる存在になれるでしょう。

## 2-1.ショートカットキー
Ctrl+S:作業中のファイルを上書き保存

F12:［名前を付けて保存］ダイアログの表示

Ctrl+PageUp:前のワークシートを表示

Ctrl+PageDown:次のワークシートを表示

Ctrl+F:「検索」ダイアログの表示

Ctrl+H:「置換」ダイアログの表示

Ctrl+N:新しいブックを作成

Ctrl+F4/Ctrl+W:選択されたブック閉じる

Alt+F4:Excelを終了

参考：https://www.relief.jp/docs/000099.html

## 2-2.数式
特によく見るのはIF、SUM、COUNTIF、VLOOKUPあたりでしょうか。
細かい書式はExcel先生が親切にサジェストしてくれます。

参考：http://officetanaka.net/excel/function/

## 2-3.マクロ
Excelのマクロは操作を記録して保存し、再生する方法がありますが内部的にはExcel VBAというプログラミング言語を使用しています。
記録よりプログラミングして作ることが多いので、覚えて損はありません。

Excelがあれば動くのでプログラミングに慣れるのにかなりハードルが低かったりします。
また、Excel VBAを用いて独自の数式を定義することも可能です。

参考：http://officetanaka.net/excel/vba/

# 3.サクラエディタ
有名なテキストエディタです。
最近だとVisual Studio Codeが隆盛していますし、IDE代わりに開発に使うには不向きなエディタです。

しかしながら、ショートカットキー、テキスト編集、Excelとの合わせ技は非常に強力です。
多くのプロジェクトでデフォルトでインストールされていたり、使用を許可されています。

## 3-1.ショートカットキー
Ctrl＋F:検索

Ctrl＋G:Grep検索

Ctrl＋R:「置換」ダイアログの表示(実はこれが一番使う)

Ctrl＋N:新規ウインドウ/新規タブ表示

Ctrl＋Tab:ウインドウ/タブ切り替え

参考：https://itlogs.net/sakura-editor-shortcut/

## 3-2.テキスト編集
サクラエディタはテキストを編集するのに長けているエディタです。
他にも色々とお便利な機能がありますが、特に使うのは置換ダイアログだったりします。
サクラエディタの置換ダイアログでは正規表現が使えます。
正規表現はプログラミングでも使うので、正規表現を覚えるのにもサクラエディタは有用だったりします。

参考：https://proengineer.internous.co.jp/content/columnfeature/5432

## 3-3.Excelとの合わせ技
サクラエディタで編集したものをExcelにペタっと貼り付ける。
もしくはExcelのデータをコピーしてきて、サクラで編集する。
作業していると、サクラエディタ、Excelだけではいまいちはかどらないシチュエーションはよく出てきます。

参考：http://blog.livedoor.jp/it_tutorial/archives/1015607043.html

# おわりに
いかがでしたでしょうか？
特に、これからSIerやSESで働きだす人はご参考になったのではないでしょうか？

色々と悩みや課題はあると思います。
私の運営しているコミュニティTECH::Survivorでは無料で相談を行っています。
月１程度で会合も行っていますので、もしご興味がありましたら参加してみてください。

http://techsurvivor.top
Visual Studio CodeのRemote ContainersでRuby on Railsをリモートデバッグ

Visual Studio CodeのRemote Containersはとても簡潔に開発環境の構築が出来ます。
DockerとVSCode(拡張機能含む)さえ入っていれば難しいインストール作業は不要で開発環境の構築が行えます。

公式サンプルにRubyは存在しますが、Ruby on Railsは存在しないので、作成してみました！！！

リポジトリ：
https://github.com/MasanoriIwakura/vscode-rails-remote

# ●目的

開発に必要なツールのインストールや設定を自動化し、開発環境依存を無くす。

# ●使用ツール

|ツール名|バージョン|備考|
|:--|:--|:--|
|Visual Studio Code|1.35.1||
|Remote Development|プレビュー|VSCode拡張機能|
|Docker for Mac|2.0.0.3|UbuntuのDockerでも動作確認済み|

# ●使用方法

- Visual Studio Codeをインストール　※自分のOSに合わせてインストールしてください
- Remote Development拡張機能をインストール(VSCode拡張機能)
<img width="762" alt="Remote.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199056/b06a53dd-fb95-cf49-a991-5052b0cdcce0.png">

- Dockerをインストール　※Macの場合はDocker for Mac

※Linuxの場合は`sudo`しなくても使用できるように設定を行ってください。

- 本リポジトリをクローン

```bash
git clone https://github.com/MasanoriIwakura/vscode-rails-remote.git
```

- VSCode起動

```bash
code vscode-rails-remote
```

- VSCode右下のダイアログから[Reopen in Container]を選択

![Reopen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199056/8cc7f58a-6e8f-bee8-7d62-d8c59f562982.png)

コンテナイメージのインストールが実行される

- ブレイクポイントの設定

下記イメージのようにブレイクポイントを設定する

<img width="479" alt="break-point.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199056/891472ed-ab40-74b7-fa38-e1cdc97f92ee.png">

- [F5]キーを押下し、実行

- ブラウザやcurlを使用して`http://localhost:3000`にアクセス

<img width="1011" alt="debug.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199056/4b141acb-071c-afa4-4793-617501c593a9.png">

ブレイクポイントで止まります。

# ●ポイント

## [Dockerfile]

Ruby on Railsのビルドや開発に必要なツールをインストールしておく

- build-essential　※ビルド用(これがないとbundle installでコケる)
- libsqlite3-dev
- nodejs
- git
- sqlite3　※今回はSQLiteを使用

## [devcontainer.json]

リモートデバッグに必要な設定を記載

- 使用するDockerfile
- バインディングするポート番号
- 使用する拡張機能
- 起動時に実行するコマンド

## [launch.json]

デバッグ用のコマンドを設定
リモートデバッグの場合、`0.0.0.0`を指定しないとアクセス出来ない

今回は以上です。
気が向いたらMySQL込みの開発環境も作成してみます。
知識ゼロから学ぶ ソフトウェアテスト(3章 ブラックボックステスト④ 状態遷移テスト)

知識整理のために投稿しています。
本は `知識ゼロから学ぶ ソフトウェアテスト[改訂版]`です。
テストってなかなか書けない。

## 状態遷移テスト

- 「状態」をモデル化して行うテスト

(例) 
メモ帳ソフトウェアを考える

|イベント/状態 |システム|入力待ち|ダイアログオープン|
|:--:|:--:|:--:|:--:|:--:|
|立ち上げ | 入力待ち | NA | NA |
|メニューコマンド| NA | ファイルダイアログオープン | NA |
|入力| NA | 入力待ち | NA |
|ダイアログ閉じる️ | NA | NA | 入力待ち |
|アプリケーション終了 | NA | システム | NA |

**見つかるバグ**

- 期待していない状態に遷移するバグ
- 繊維自体がない場合

**役立つとき**

- GUI(Graphical User Interface)ソフトウェア
- オブジェクト指向ソフトウェア
- **通信プロトコルテスト**(絶対やるべき)

**向かないとき**

- 状態の数が多くなるとモデルが複雑化する
- モデリングに時間がかかりすぎるとテストする時間がなくなる
SORACOM LTE-M Button for Enterprise (白ボタン) と SORACOM Beam の組み合わせがうまくいかないときのトラブルシューティング

# はじめに
白ボタンでは UDP でSORACOM へ投げるしコンソール接続などができないため、SORACOM Beam での転送がうまくいかなかったときにどこで問題が起こっているのかを切り分けるのが難しいです。今回は、SORACOM Harvest を使ってトラブルシューティングしてみました。
なお、設定が間違っているときとかは、[エラーログ機能](https://blog.soracom.jp/blog/2016/09/30/log-feature/)で確認ができます。

白ボタン？な方はこちら
https://soracom.jp/products/gadgets/
https://dev.soracom.io/jp/enterprise_button/

# トラブルのシナリオ
白ボタンと SORACOM Beam を連携してみたが、ボタンをクリックしてもLED が赤くなる。しかしどこに原因があるのかがわからない。

(失敗例) [SORACOM の公式チュートリアル](https://dev.soracom.io/jp/start/enterprise_button_beam/) に従って [PostBin](https://postb.in/) にPOST しようとしたが、うっかり URL を 1 文字漏らしてコピペしてしまった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125247/7fcc43f6-4c2f-8136-d79c-cad4c22d8c3a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125247/4b2ddba5-0777-3064-c18d-228b3edacaee.png)

# トラブルシューティング手順
1. SORACOM Harvest を有効にしてボタンをクリックし、SORACOM Harvest にデータが格納できているかを確認する
2. SORACOM Harvest に格納されたデータを curl などで SORACOM Beam の転送先に送り、エラーなどが返らないかを確認する

# トラブルシューティングのフローチャート
![flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125247/8e9594c0-6a8f-194b-c0b3-44baae5c659b.png)

# 1. SORACOM Harvest を有効にしてボタンをクリックし、SORACOM Harvest にデータが格納できているかを確認する
白ボタンが所属しているグループで Harvest を有効にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125247/02cac358-c78b-c50a-4fa1-bd6fc596ad65.png)

この後、ボタンをクリックします。ここで LED に緑色になるのは Unified Endpoint 経由で Harvest への送信には成功しているからです。Harvest を無効にすると Beam だけに送られるためまた赤色になります。

次に、Harvest にデータが格納されているかを確認します。下のように表示されていれば、少なくとも Harvest にはデータが送られているのでネットワークなどは問題ないといえます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125247/56f17488-4de2-6e7f-4952-507a619fe123.png)

なお、もし下のようになっていたら、バイナリパーサーが有効になっていないので[有効](https://dev.soracom.io/jp/start/enterprise_button_harvest/#create_group)にしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125247/d6804a89-2e70-ee88-b6e8-c21717bfc502.png)


# 2. SORACOM Harvest に格納されたデータを curl などで SORACOM Beam の転送先に送る
先ほど Harvest で格納を確認した json 形式のデータをそのまま手元の PC から curl で送ってみます。もしポート番号やヘッダを別途設定している場合はよしなにつけてください。

```bash
$ curl -XPOST -H 'Content-Type:application/json' -d '{"clickType":1,"clickTypeName":"SINGLE","batteryLevel":1,"binaryParserEnabled":true}' https://postb.in/1561708098714-987965611973
404 - Not Found
```

今回の場合、PostBin の URL をコピペミスしていたのでここで 404 が返り、そもそもの URL が怪しいのかも、という切り分けができます。以下のように、URL を直せば正常なレスポンスが返ってきます。もし詳細なログを見たければ `curl -v` オプションをつけるのも良いです。

```bash
curl -XPOST -H 'Content-Type:application/json' -d '{"clickType":1,"clickTypeName":"SINGLE","batteryLevel":1,"binaryParserEnabled":true}' https://postb.in/1561708098714-9879656119737
1561709365768-3901113041210
```

もし curl でうまくいくが引き続き Beam では失敗するようなことがあれば、たとえばアクセス認証などを疑うことが考えられます。少なくとも URL が正しく対向のサーバには到達しているので、対向のサーバ側のエラーログを見るというトラブルシューティングが考えられる。
Laravelメモ

# はじめに
へーって思ったこと書く。
だいたいLaravel。




# ルーティング

```php:web.php
Route::get('/test', 'TestController@index')->name('test.testIndex');
```

->nameで名前をつけられる。

```php:test.blade.php
<a href="{{ route('test.testIndex') }}">戻る</a>
```
名前で呼べる。
formタグからsubmitの遷移方法しか知らなかったから
**「名前つけたらaタグから呼べるんだー」**
って思ってた。

**別に名前つけなくても呼べる。**

```php:test.blade.php
<a href="/test">戻る</a>
```

#モデル作成
artisanコマンドでモデルを作る時、オプションでコントローラーとマイグレーションファイルも作れる。

```:ターミナル
php artisan make:model -m -c クラス名
```

-fでファクトリーも作れるぽいけど**知らない**。
実際作った時は-vも付いてたけど**知らない**。




# @
`@extends()`して`@section()`と`@endsection`で囲むと`@yield()`に挿入される。

```html:layout.blade.php
<!DOCTYPE html>
<html>
<head>
    <title>@yield('title')</title>
</head>
<body>
    @yield('content')
<!-- フッター的な部分 -->
    <p>
        <a href="{{ route('game.init') }}">
            リセット
        </a>
        <a href="{{ route('game.title') }}">
            タイトルへ
        </a>
    </p>
<!-- /フッター的な部分 -->
</body>
</html>
```

これの`@yield()`に

```html:play.blade.php
@extends('layout')

@section('title')
    タイトル
@endsection


@section('content')
    <p>本文</p>
@endsection
```

`@section()`と`@endsection`で囲まれた箇所が挿入される。
play.blade.phpを表示した時フッター的な部分が本文の下にあるように表示される。




# セッション
Requestを使う。使ったやつだけ書く。

```php:コントローラー
// セッションに保存
$request->session()->put('名前', 値);
// セッションから取得
$request->session()->get('名前');
// セッションから消す
$request->session()->forget('名前');
```

Sessionファサードを使うのもあるけど書かない。




# リダイレクト
フォームで入力した値を保持したままリダイレクトして欲しかった。

```php:コントローラー
return redirect('/game/play')->withInput();
```

withInput()をつけて…

```php:リダイレクト先コントローラー
$value = $request->old('フォームのinputタグの名前');
```

受け取る。

```php:リダイレクト先コントローラー
$value = Session::get('_old_input')['フォームのinputタグの名前'];
```

これでも受け取れる。`use Session`を書いておく。


# ルーティング2

Laracastsを見て。
[Browse>Laravel>Laravel 6 From Scratch>Episode 23 - Form Handling](https://laracasts.com/series/laravel-6-from-scratch/episodes/23)


```php:web.php
Route::get('/articles/{article}', 'ArticlesController@show');
Route::get('/articles/create', 'ArticlesController@create');
```

この状態で`/articles/create`にアクセスしようとするとcreateが{articles}に吸われて上の方のルートになる。

```php:web.php
Route::get('/articles/create', 'ArticlesController@create');
Route::get('/articles/{article}', 'ArticlesController@show');
```

アクセスして欲しい方を上に持っていけばいい。

# おわり
pythonでのデータの書き込みをまとめました

#はじめに

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているにのみやです。

Pythonでのファイルの書き込み方を調べたのでまとめます。
プログラミング初心者なので、間違いも多いと思います。
間違いがあれば、ぜひ教えてください。

# write() – 文字列を引数に取って、ファイルに書き込む

### サンプル1
```Python:sample1.py
text = 'サンプル1が作成されたよ'
file = open('test1.txt', 'w')
file.write(text)
file.close()
```
|コード|やっていること|
|:-----------:|:------------:|
|  text = 'サンプル1が作成されたよ' |ファイルに保存するテキストの内容を変数 text に代入   |
|  file = open('test1.txt', 'w') |  open()関数で 新規 test1.txt ファイルの作成、そしてそれをコード file として管理 |
| file.write(text)  |  先ほど作成した test1.txt に 変数text を書き込み、保存 |
| file.close()  | 書き込み作業の終了宣言  |


###サンプル2
```Python:sample2.py
text = 'サンプル2が作成されました'
with open('test2.txt', 'w') as f:
    f.write(text)
```
|コード|やっていること|
|:-----------:|:------------:|
| text = 'サンプル2が作成されました'  | ファイルに保存するテキストを変数 text に代入  |
|  with open('test2.txt', 'w') as f: |  open()関数で 新規 test2.txt ファイルの作成、そしてそれを変数 f として管理。with文の為、 close() 不要に。 |
|  f.write(text)  | 変数 f  に 変数 text を書き込み、保存  |

### サンプル3
```Python:sample3.py
f = open('test3.txt','w')
f.write('サンプル3を作ったよ')
f.close()
```
|コード|やっていること|
|:-----------:|:------------:|
|  f = open('test3.txt','w' |  open()関数で 新規 test3.txt ファイルの作成、そしてそれを変数 f として管理 |
|f.write('サンプル3を作ったよ')   | ｈ変数 f に write() 関数内の文字を書き込み。  |
|   f.close() |  書き込み作業終了 |

##実行すると
実行前
<img width="514" alt="2019-06-28 (4).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423451/2b5d5fb0-475f-bfb7-1091-1d8c3b98e31d.png">

実行後
<img width="537" alt="2019-06-28 (5).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423451/5bf7ee7e-a170-ea96-ea5f-c9ff76220794.png">

テキストを開くと
<img width="512" alt="2019-06-28 (6).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423451/6ab23c9b-9862-fb10-da7c-4ea355fd4441.png">


##open('','w')のｗについて

### open(..., "w") にした場合: ファイルへの書き込み  
同じファイル名のファイルがあった場合は、新規作成したファイルで上書きされる  

###open(..., "a") にした場合:ファイルへの追記
同じファイル名のファイルがあった場合は、既存のファイルに追記していく  
という違いがあります。

どちらも基本は同じ「ファイル作成」ですが、すでに同じ名前のファイルがある場合の動きが違います。  
  
#おわりに
今回はwrite()についてまとめました。
何か間違いがあれば、コメントお願いします。
【Ruby】eachメソッドで複数の配列を同時にループさせる方法

#はじめに
最近、勉強している際に配列の中の要素を取り出すことがとても多い。そこでいつも`each`メソッドを使って取り出すのですが、今回2つの配列から同時にループさして取り出したいと思ったので、その方法についてまとめておきます。
##zipメソッドを使う
使い方は

`1つ目の配列.zip(2つ目の配列) do |変数１,変数２|
　処理
end`
##例）
```ruby
odd = [1,3,5]
even = [2,4,6]

odd.zip(even) do |x, y|
  puts x
  puts y
end
```
##実行結果
```ruby
#実行結果
irb(main):001:0> odd = [1,3,5]
=> [1, 3, 5]
irb(main):002:0> even = [2,4,6]
=> [2, 4, 6]
irb(main):003:0> 
irb(main):004:0> odd.zip(even) do |x, y|
irb(main):005:1*  puts x
irb(main):006:1>  puts y
irb(main):007:1> end
1
2
3
4
5
6
=> nil
```
##参考
https://freesworder.net/ruby-each-multiple/
Private, Protected, Readonlyなどの目的

##Private
Privateの挙動は、class内からしかそのプロパティーやメソッドが呼び出されない。
その目的は、APIの公開範囲を限定することにより、影響の範囲を限定することにある。
Privateメソッドを削除したり変更したりした時、クラスの内部だけに影響範囲が限定されていることを保証する
##Protected
classの内部と、継承先にAPIの公開範囲が限定される。
これも同じく、影響範囲がそのクラスと継承先のクラスのみに限定される。

##ReadOnly
値が変更されないことを保証する。
pythonで入力した文字列をLINE BOT でLINEに送信する


## 実現したいこと

- pythonでLINE BOTを作る
- Pythonのinput()で入力した文字列をLINEで送りたい

## 環境

- Mac
- Python3

## 参考

- [FlaskでLINE botを実装し，herokuにdeployするまで](https://qiita.com/suigin/items/0deb9451f45e351acf92)

  この記事の通りに進めて、まずFlaskでLINE BOTを作ってみました。

- [PythonでLINE Bot APIを使ってプッシュ通知を実装する](https://qiita.com/kotamatsuoka/items/6f56d0d0a3225160b4d0)

  メッセージの送信はこの記事にならいました。

- [【GitHub】に載せたくない環境変数の書き方 Python](https://qiita.com/hedgehoCrow/items/2fd56ebea463e7fc0f5b)

  .envファイルからTOKENを取り出すのがうまく出来ずハマったときに助けて頂きました。

## 実装

今回は自分のuser_idに送るようにしました。同じディレクトリに.envファイルを置いています。

```python:message_sender.py
import os
from os.path import join, dirname
from dotenv import load_dotenv

from linebot import LineBotApi
from linebot.models import TextSendMessage

dotenv_path = join(dirname(__file__), '.env')
load_dotenv(dotenv_path)

channel_access_token = os.environ.get('LINE_CHANNEL_ACCESS_TOKEN')
user_id = os.environ.get('USER_ID')

line_bot_api = LineBotApi(channel_access_token)




def sendMessage(message):

    messages = TextSendMessage(text=message)
    line_bot_api.push_message(user_id, messages=messages)


if __name__ == "__main__":
    print("メッセージを入力してください")
    message = input()
    sendMessage(message)
    print("メッセージを送信しました")
```

.envにUSER_IDも記述しています。

```:.env
LINE_CHANNEL_ACCESS_TOKEN=
USER_ID=
```

## 実行例

とてもシンプルです。

```
メッセージを入力してください
こんにちは
メッセージを送信しました
```

これで「こんにちは」と自分のラインにメッセージが届きます。
pythonスクリプトでBlenderのaddonを有効にする

#pythonスクリプトでBlenderのアドオンを有効にする

**※本記事はWindows版のBlenderが前提**

アドオンを含めてBlednerを配布する必要にせまられた。
Bledner自体はmsiファイルなのでBATファイルでインストールすることができ、アドオンもaddonsフォルダへのコピーで配置できる。

アドオンの有効化処理をpythonスクリプトで行う方法を見つけたのでまとめる。

## GUIからBlednerのアドオンを有効にする

以下の記事の通りにやればできる。
[[Blender] アドオンのインストール・アップデート・アンインストール方法のまとめ](https://qiita.com/nutti/items/5e9ebe9c28751066b688)

## PythonスクリプトでBlenderアドオンを有効にする
アドオンをaddonsフォルダへコピーする。
[方法2：アドオン用ディレクトリにアドオンのソースコード直接配置する](https://qiita.com/nutti/items/5e9ebe9c28751066b688#%E6%96%B9%E6%B3%952%E3%82%A2%E3%83%89%E3%82%AA%E3%83%B3%E7%94%A8%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AB%E3%82%A2%E3%83%89%E3%82%AA%E3%83%B3%E3%81%AE%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E7%9B%B4%E6%8E%A5%E9%85%8D%E7%BD%AE%E3%81%99%E3%82%8B)

以下のファイルを用意する。

```python:addon_enable.py
import bpy
# アドオンフォルダ名 はaddonsへコピーしたフォルダ名を設定
bpy.ops.wm.addon_enable(module = "アドオンフォルダ名")
bpy.ops.wm.save_userpref()
```
Blednerバンドルのpythonを利用して上記のスクリプトを実行する。

```bat
REM Blenderはデフォルトのインストール先へインストールした前提
"%PROGRAMFILES%\Blender Foundation\Blender\blender.exe" -b -P addon_enable.py
```

配布時にBATファイルで実行し、Blenderアドオンを自動的に有効化するようにした。
インターネットから切り離された Raspberry Pi アクセスポイントに Android スマホからつながらない話

# 概要
Raspberry Piをアクセスポイント化して、Androidスマホから操作したい。

具体的にはAndroidスマホからRaspberry Pi側に用意したWebページ開いて、MP3の一覧を表示。その中から再生用のボタンを押すとRaspberry PiにつながっているBluetoothスピーカーから音楽が再生されるみたいなシステム作ってます。

で、Raspberry Piが家のLAN上にいて、インターネットにつながっている間は期待通りに動くんですけど、Raspberry Piをアクセスポイント化してインターネットから切り離した途端にアンドロイドスマホからRaspberry PiのWebページが開けなくなったという話です。

# 結論
この状態で、AndroidスマホからRaspberry Piのプライベートネットワークに接続するためには、Androidスマホ側で「モバイルデータ通信」をOFFにする必要があるらしい。
（Raspberry Pi全然関係なかった）

OFFにするための具体的な方法はこの辺
[スマホのモバイルデータ通信・Wifiの違いとは何？オフにした時は？](https://itojisan.xyz/%E3%82%B9%E3%83%9E%E3%83%9B%E3%81%AE%E7%9F%A5%E8%AD%98/%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB%E3%83%87%E3%83%BC%E3%82%BF%E9%80%9A%E4%BF%A1%E3%83%BBWifi%E3%81%A8%E3%81%AF/)

# もうちょっと詳しく
## こんなシステム
```
Bluetoothスピーカー
  ↑ Bluetooth
Raspberry Pi
（アクセスポイント化／WebIOPi）
  ↑ 無線LAN、HTTP
Androidスマホ
```
Bluetoothスピーカーもスマホ（ここに移ってるのはスマホじゃないな）もバッテリーで動くし、Raspberry Pi (Zero) もモバイルバッテリーで動かすと、電源無しでどこでも音楽をならせるのです（楽器の伴奏用システムです）。
![D7dnqm5UcAAJ53_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449620/2d0605b9-ca53-dbc4-cf77-481d6b38faac.jpeg)

## 何が起きた？
システム作ってる間は家のLANにRaspberry Piつなげてまして、多少の問題（WebIOPiの使い方が分からないとか）があったもののけっこう思い通りに動いてたんですよ。

で、これ、家じゃないところで楽器演奏するときでもスピーカーから伴奏流すために作ってたので（家でならこんな面倒なことしないでPCから流すでもいいしね）、Raspberry PiをLANから切り離してアクセスポイント化した途端に、スマホからつながらない問題発生。

上の画像に写ってる Amazon Fire からはつながるものの、スマホからつなげようとしたらスマホのブラウザが `ERR_ADDRESS_UNREACHABLE` ってエラーを吐いて全くつながる気配なし。

何が悪いのか全く分からずの私です。

## スマホとRaspberry Piの動きを確認してみる
- スマホ「IPアドレスが割り当てられてない」
- Raspi「DHCPでIPアドレス割り当て成功してる」

ふたりの言い分が真っ向から食い違ってます。
「PCからもFireタブレットからも接続できてるし、Raspberry Pi側のhostapdとかdhcpdとかの設定は間違ってないだろう」と思いつつ、何度も何度も同じ設定を確認したり、ちょこちょこと設定を変更したりしても全く症状は改善せず。

スマホが「IPアドレスなし」というだけあって、ブラウザからページを開きに行ってもRaspberry Pi側にはHTTPのリクエストすら来ていません。`ERR_ADDRESS_UNREACHABLE` のエラーは伊達じゃない。

なかなか解決に至らなかったのはRaspberry Piの設定ばかり確認していて、Android側の設定をあまりいじってなかったからなんですが、この件に関係しそうなAndroidの設定って見つからなかったんですよ。

## 同じようなことになっている人がいないか？
これが見つからないんですよね。

「Raspberry Piをアクセスポイント化してスマホから操作する」みたいなサイトはたくさん見つかるんですけど、誰も「スマホからつながらない！」って状態におちいっていない。LANから切り離して操作してみてる人って意外と少ないのでしょうか？

## 家じゅうのAndroid端末で試してみる
（iPhone等で確認していないのは家に1台もないからです）
Android端末、、、奥さんのスマホ、昔使ってたタブレット、子供にあげた私のお古のスマホ（SIMなし）と色々な端末から接続を確認してみると、どうやらSIMが入ってないやつからならつながるらしいという傾向が見つかりました。

このシステム使うたびにSIMカードを抜いていられないので、「要するに携帯会社のネットワークにつながってなきゃいいんじゃね？」ということで「モバイルネットワーク」をOFFにしたら、これがビンゴ。Raspberry Piにつながるようになりました。

## ところで
なんで「モバイルネットワーク」がONのままだとつながらないのでしょう？
どなたか詳しい方教えていただけませんか？
Leet 文字列を力技で作った後 str_replace に気づいた話

[フリー百科事典『ウィキペディア（Wikipedia）』 > Leet](https://ja.wikipedia.org/wiki/Leet)
>leet（リート、1337、l33t）は、主に英語圏においてインターネット上で使われるアルファベットの表記法である。leetspeak（リートスピーク）とも呼ばれる。
leet は、英語の elite（エリート）が eleet に変化し、さらに語頭の e がとれてできた俗語である。日本ではハッカー語と呼ばれることもある。
たとえば、「Warez」という語を leet で表記すると、「W@rez」や「W4r3z」などとなるように、一部のアルファベットを形の似た数字や記号などに変化させる。

知らなかったので検索しましたが、こういう文字列のことは Leet と呼ぶそうで。
今回、入力文字列を Leet 変換したいシーンがあり、それを若干の力技で解決した後、もっと楽な方法に気づいた脱力感を記事にします。
(PHP 便利な関数多すぎて、存在を認識しないまま作っちゃうことがよくある反省)

# お題

入力文字列のアルファベットを以下のルールで変換して標準出力。
入力値の読み込みは [標準入力から読み込むコード](https://qiita.com/terra_yucco/items/fa26df1c8debfcf8ddf60) を使います。

入力文字|変換後文字
:--|:--
O|0
I|1
Z|2
E|3
A|4
S|5
G|6
T|7
B|8
P|9

## 力技で解いた

```php:leet1.php
<?php
$leets = [
    'O' => '0',
    'I' => '1',
    'Z' => '2',
    'E' => '3',
    'A' => '4',
    'S' => '5',
    'G' => '6',
    'T' => '7',
    'B' => '8',
    'P' => '9',
];
$s = trim(fgets(STDIN));
foreach ($leets as $src => $dest) {
   $s = str_replace($src, $dest, $s);
}
echo $s . PHP_EOL;
```

## str_replace には配列を渡せた

```php:leet2.php
<?php
$src = ['O', 'I', 'Z', 'E', 'A', 'S', 'G', 'T', 'B', 'P'];
$dest = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
$s = trim(fgets(STDIN));
echo str_replace($src, $dest, $s) . PHP_EOL;
```

AtCoder のカスタムテストで計測した範囲では、メモリや実行時間には大きな差がなかったため、内部的な実装はあまり変わらないのかもしれません。
Angular Databinding #memo

#はじめに
AngularはMVCモデルを使って、viewはDOM、controllerはJavascript、Modelはjsにobjectのプロパティが保持されたデータ。

#Data Binding
Angularは{{data}}構文でDOMにデータを表示する。

#Model定義
先ずはModelの生成。```$ ng generate('g') <schematic>```
schematicに応じたファイルを生成する

```
$ ng g class('cl') models/article
```

###Articleモデル
anyにより動的に型を与えることができる。
今回はjsonで扱うので

```typescript:article.ts

export class Article {

    articleId: number;
    articleTitle: string;
    articleContent: string;
    niceCount: number;
    pictureUrl: string;
    createdBy: string;
    createdAt: Date;
    updatedAt: Date;

//    constructor(article: any = {}) {
//        this.articleId = article.articleId || 0;
//        this.articleTitle = article.articleTitle || '';
//        this.articleContent = article.articleContent || '';
//        this.niceCount = article.niceCount || 0;
//        this.pictureUrl = article.pictureUrl || '';
//        this.createdBy = article.createdBy || '';
//        this.createdAt = article.createdAt || new Date(2000, 1, 1);
//        this.updatedAt = article.updatedAt || new Date(2000, 1, 1);
//    }
    constructor() {
        this.articleId = 0;
        this.articleTitle = '';
        this.articleContent = '';
        this.niceCount = 0;
        this.pictureUrl = '';
        this.createdBy = '';
        this.createdAt = new Date(2000, 1, 1);
        this.updatedAt = new Date(2000, 1, 1);
    }
}
```
###Mock Object
mockとはテストに必要な部品の値を擬似的に設定するもの。

```typescript:mock-article.ts
import { Article } from './article';

export const ARTICLES: Article = {
    articleId: 1,
    articleTitle: '記事タイトル',
    articleContent: '記事文章内容',
    niceCount: 2,
    pictureUrl: '',
    createdBy: 'spa.training',
    createdAt: new Date(2019, 1, 1),
    updatedAt: new Date(2019, 1, 1)
};
```
#ModelからViewへ
###Component
```typescript:article-list.component.ts
import { Component, OnInit } from '@angular/core';
import { ARTICLES } from '../../models/mock-articles'; 

@Component({
  selector: 'app-article-list',
  templateUrl: './article-list.component.html',
  styleUrls: ['./article-list.component.scss']
})
export class ArticleListComponent implements OnInit {

  article = ARTICLES; 
  constructor() { }
  ngOnInit() {
  }
}
```

Safe Navigation Operator(?.)によりobjectがnull(or undefined)の場合続くプロパティへアクセスしない

```html:article-list.component.html
<br>
<!-- Article Card List -->
<div class="card">
  <div class="card-body">
    <h5 class="card-title">{{article?.articleTitle}}</h5>
    <p class="card-text">{{article?.articleContent}}</p>
    <div class="card-footer">
      <div class="item">
        <i class="fas fa-heart"></i> {{article?.niceCount}}
      </div>
      <div class="item">
        <img src="{{article?.pictureUrl}}" class="rounded-circle" ngbTooltip="{{article?.createdBy}}" placement="bottom"/>
        {{article?.createdAt}}
      </div>
    </div>
  </div>
</div>
```
日々の進捗ノート_言語処理100本ノック08

# 08.暗号文
>与えられた文字列の各文字を，以下の仕様で変換する関数cipherを実装せよ．
・英小文字ならば(219 - 文字コード)の文字に置換
・その他の文字はそのまま出力
この関数を用い，英語のメッセージを暗号化・復号化せよ．

```gen08.py
def cipher(word):
    result = list(word)
    for x, i in enumerate(word):
        if i.islower():
            result[x] = chr(219 - ord(i))
            
    return "".join(result)

getword = input("文字列を入力")
encoded = cipher(getword)
print(encoded)
decoded = cipher(encoded)
print(decoded)
```
####結果
`文字列を入力Do you hear the people's sing?
Dl blf svzi gsv kvlkov'h hrmt?
Do you hear the people's sing?`

####備忘録
・絶対もっと簡単にかけると思う
・islowerは()でちゃんと実行しないとダメ
・関数名は省略しないほうがいい，と言われたのでそうしてみることにする
・こっちのほうがいいかも

```gen08re.py
def cipher(word):
    for i in word:
        if i.islower():
            word = word.replace(i , chr(219 - ord(i)))
    return word

getword = input("文字列を入力")
encoded = cipher(getword)
print(encoded)
decoded = cipher(encoded)
print(decoded)
```
Arduino IDE(C++) で LILO (queue)・LIFO (stack) を使ってみる

# この記事について
Arduino IDE の開発 で FIFO / FILO の処理をしてみます。

# キューとスタック
一時的にデータを溜め込んでおいて、あとで１個づつ処理したいこと、よくありますよね？
C++ の標準的な手法で解決してみます。
今回は Arduino IDE での開発を想定してみます。

なお、いわゆる普通の Arduino (Unoやそのクローンなど）ではコンパイルが通らないようです。
ESP-WROOM-02 / 32 であれば問題なく動作するようなので、そちらで動かしてみます。

## FIFO処理 (queue:キュー)
FIFO とは First In, First Out の略、つまり 先入れ先出し です。
データを入れ物に溜め込んでおいて、先に入れたものから順に取り出していくようなイメージです。

### 使い方
説明は省略。ソースを見れば誰でも分かると思う。
詳細は [このへん](https://ja.cppreference.com/w/cpp/container/queue) を確認しましょう。

```cpp:queue.ino
#include <queue>

std::queue<int> q;

void setup() {
  Serial.begin(115200);
  Serial.println("");

  // キューに値を貯め込む
  q.push(1);
  q.push(2);
  q.push(3);

  // キューのサイズを確認
  int size = q.size();
  // 3 が表示される
  Serial.printf("size=%d\n", size);

  // キューから値を取得する
  int value = q.front();  
  // 1 が表示される
  Serial.printf("value=%d\n", value);

  // キューの値を捨てる（FIFOなので先頭の値が捨てられる）
  q.pop();

  // キューから値を取得する
  value = q.front();  
  // 2 が表示される
  Serial.printf("value=%d\n", value);
}

void loop() {
}
```

## FILO処理 (stack:スタック)
FILO とは First In, Last Out の略、つまり 先入れ後出し です。
データを入れ物に溜め込んでおいて、後に入れたものから順に取り出していくようなイメージです。

### 使い方
上記と同様に説明は省略。
詳細は [このへん](https://ja.cppreference.com/w/cpp/container/stack) を確認しましょう。

```cpp:stack.ino
#include <stack>

std::stack<int> s;

void setup() {
  Serial.begin(115200);
  Serial.println("");

  // スタックに値を貯め込む
  s.push(1);
  s.push(2);
  s.push(3);

  // スタックのサイズを確認
  int size = s.size();
  // 3 が表示される
  Serial.printf("size=%d\n", size);

  // スタックから値を取得する（FILOなので最後の値が取得される）
  int value = s.top();  
  // 3 が表示される
  Serial.printf("value=%d\n", value);

  // スタックの値を捨てる（FILOなので最後の値が捨てられる）
  s.pop();

  // スタックから値を取得する
  value = s.top();  
  // 2 が表示される
  Serial.printf("value=%d\n", value);
}

void loop() {
}
```

# まとめ
C++って便利ですねｗ
Arduino IDEで開発をしていると、Cでの開発に頭が行ってしまい、C++の標準的な仕組みを忘れがちなので、面倒な処理をやる必要が出てきたらC++を少し調べてみましょう。
さくらのVPSでredmine

突然以下のメッセージが表示されredmineが起動しなくなった。
We're sorry, but something went wrong.

詳しく調べる
[!] There was an error parsing `Gemfile`: You cannot specify the same gem twice with different version requirements.
You specified: test-unit (~> 3.0) and test-unit (>= 0). Bundler cannot continue.

 #  from /var/lib/redmine/Gemfile:111
 #  -------------------------------------------
 #    #TODO: switch to "eval_gemfile file" when bundler >= 1.2.0 will be required (rails 4)
 >    instance_eval File.read(file), file
 #  end
 #  -------------------------------------------

どうやらgemを複数回、異なるバージョンで指定しているらしい。

redmineのプラグインを確認する。
redmine_time_trackerこのプラグインが悪さしていた。
11月18日にプラグインフォルダにを展開しっぱなしだったredmine_time_trackerが
apacheが何らかの原因で再起動した際に読み込まれてしまったのが原因だった。
macでopenposeを使い始めるまで

# openposeをcloneする
https://github.com/CMU-Perceptual-Computing-Lab/openpose

`git clone https://github.com/CMU-Perceptual-Computing-Lab/openpose `

## openposeのディレクトリに移動する
`cd openpose`
## brewがなければbrewをインストールする
`bash scripts/osx/install_brew.sh` 
## CMakeGUIをインストールする
`brew cask install cmake`
## openposeが依存しているパッケージを一括でインストールする
`bash scripts/osx/install_deps.sh`.

## Cmakeでbuildを作成する
configureでunix makefileが選択されていることを確認してDone

<img width="636" alt="Screen Shot 2019-06-28 at 14.40.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171398/53cfe2bb-6220-71a2-99cf-fd3f6fe2302b.png">

<img width="272" alt="Screen Shot 2019-06-28 at 14.42.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171398/f2d795ad-ca54-f7e0-54ec-5f995031814e.png">

しばらく待ちます
confingが終わったらgenerateをクリックして終了です。

もしdoxygenがないとエラーになったら
`brew  install doxygen` でdoxygenをインストールして上げればOKです
## makeする
makeするのですが

### (macOS 10.14以降)vecLibが見つからなくてエラーになる
```shell:output
CMake Error at /Applications/CMake.app/Contents/share/cmake-3.14/Modules/FindPackageHandleStandardArgs.cmake:137 (message):
  Could NOT find vecLib (missing: vecLib_INCLUDE_DIR)
Call Stack (most recent call first):
  /Applications/CMake.app/Contents/share/cmake-3.14/Modules/FindPackageHandleStandardArgs.cmake:378 (_FPHSA_FAILURE_MESSAGE)
  cmake/Modules/FindvecLib.cmake:24 (find_package_handle_standard_args)
  cmake/Dependencies.cmake:135 (find_package)
  CMakeLists.txt:49 (include)


-- Configuring incomplete, errors occurred!
See also "/Users/taka/deeplearning-X/openpose/build/caffe/src/openpose_lib-build/CMakeFiles/CMakeOutput.log".
make[2]: *** [caffe/src/openpose_lib-stamp/openpose_lib-configure] Error 1
make[1]: *** [CMakeFiles/openpose_lib.dir/all] Error 2
make: *** [all] Error 2
```
は
/Users/taka/deeplearning-X/openpose/build/caffe/src/openpose_lib-build/CMakeCache.txtの483行目を

```
vecLib_INCLUDE_DIR:PATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Accelerate.framework/Versions/Current/Frameworks/vecLib.framework/Headers/
```

に変更してあげるとmakeが通るようになります。

```shell:CMakeCache.txt(line->483)
//vecLib include directory
vecLib_INCLUDE_DIR:PATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Accelerate.framework/Versions/Current/Frameworks/vecLib.framework/Headers/
```

#### makeが通った!!!
<img width="766" alt="Screen Shot 2019-06-28 at 16.06.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171398/d72cec87-a98b-f355-ec2e-c37938a0b868.png">

```
[100%] Built target openpose_wrapper
```
今回はbody_25を使います。

###  OpenPose trained modelsをダウンロード

openpose上で

```shell:モデルをダウンロード
./models/getModels.sh 
```

## 実行!

```
./build/examples/openpose/openpose.bin
```
【keras】重たいモデルのload/save

kerasでモデルを学習して保存しておく際、通常であれば

``` python
model.save('test_model.h5')
```

などで保存するのが一般的であるが、これをそのままload_modelすると以下のようなエラーが出ることがある。100M以上とかの大きいファイルを読み込む時に良く出て来る。

```
OSError: Unable to open file (file signature not found)
```


保存したモデルを推論に使うのみであれば、以下のように学習に必要な情報を省略して保存することで、ファイルの大きさが半分程度になる。大体の場合はこれでエラーが出なくなる。

``` python
model.save('test_model.h5',  include_optimizer=False)
```
Vue.jsによるタブ切り替えのサンプル (スタンダードなUIからVueに慣れる)

#Vue.jsでタブの切り替えを実装してみた。

社内でVue.jsに移行する場合、今までjQueryで実装できてたものが作れなくなるのは困る。
よく使うUIの一つにタブの切り替えがあるので、今回はVue.jsでタブの切り替えを実装してみた。
まずはスタンダードなUIがVue.jsでも実装できる事を体感してメリットを感じれば、Vueへの移行に対して心理的ハードルが下がると思う。

##CSS

CSSについては説明割愛

```css

.tab-list {
  overflow: hidden;
}
.tab-list > .tab-list-item {
  display: inline-block;
  line-height: 40px;
  width: 120px;
  text-align: center;
  cursor: pointer;
  background: #eee;
  transition: 0.3s;
  border-radius: 10px 10px 0 0;
}
.tab-list > input {
  display: none;
}
.tab-list > input:checked + label,
.tab-list > label:hover {
  background: #56B4BE;
  color: #fff;
}
.tab-target-contents {
  width: 500px;
  height: 100px;
  margin: 0;
  padding: 10px;
  border: 1px solid #eee;
  border-top: 2px solid #56B4BE;
  list-style: none;
}
.text {
  font-size: 14px;
  margin: 0;
}

```

##HTML
v-ifディレクティブで条件分岐分岐をしてタブを切り替えている。
v-ifディレクティブについては、[公式サイト](https://jp.vuejs.org/)の[条件付きレンダリング](https://jp.vuejs.org/v2/guide/conditional.html)を参照。

ラジオボタンのv-model="isActive"とvalueの値でどのタブを表示させるか判定させている。
v-modelを使用したデータバインディングについては[フォーム入力バインディング](https://jp.vuejs.org/v2/guide/forms.html)を参照。

```html
<div id="tabApp">
    <div class="tab-list">
        <input type="radio" value="1" id="tab1" v-model="isActive">
        <label for="tab1" class="tab-list-item">タブ1</label>
        <input type="radio" value="2" id="tab2" v-model="isActive">
        <label for="tab2" class="tab-list-item">タブ2</label>
        <input type="radio" value="3" id="tab3" v-model="isActive">
        <label for="tab3" class="tab-list-item">タブ3</label>
    </div>
    <ul class="tab-target-contents">
        <li v-if="isActive === '1'">
            <p class="text">
            テスト本文1テスト本文1テスト本文1テスト本文1テスト本文1テスト本文1<br>
            テスト本文1テスト本文1テスト本文1テスト本文1テスト本文1テスト本文1</p>
        </li>
        <li v-else-if="isActive === '2'">
            <p class="text">
            テスト本文2テスト本文2テスト本文2テスト本文2テスト本文2テスト本文2<br>
            テスト本文2テスト本文2テスト本文2テスト本文2テスト本文2テスト本文2</p>
        </li>
        <li v-else-if="isActive === '3'">
            <p class="text">
            テスト本文3テスト本文3テスト本文3テスト本文3テスト本文3テスト本文3<br>
            テスト本文3テスト本文3テスト本文3テスト本文3テスト本文3テスト本文3</p>
        </li>
    </ul>
</div>
```

##JavaScript

大規模な開発では**$npm install vue**でvueをインストールするといいみたいだけど、
今回はCDNで簡易的に実装した。

```html
<script src="//cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue ({
    el: '#tabApp',
    data: {
        isActive: '1',
    }
});
</script>
```

##まとめ
Vueを使ってタブの切り替えを実装すると改行入れても6行で実装が完了する。
HTML側にisActiveで条件分岐を入れるのがはじめは気持ち悪いかもしれないけど、すぐに慣れるんじゃないかなと思う。
プログラミングを初めて2週間の学び

京都大学2回生の中田祐輔です。
プログラミングを初めて2週間が経ったくらいです。
まだ、プログラミングのコーディングをするので戸惑っているという状況です。
今回は、プログラミングのコーディングをする際に忘れやすいことを記事にしていきたいと思います。
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。
ぜひ一緒に高め合っていければと思います。

■consoleのコーディングは最後まで気を抜かない
JavaScript ではconsoleで出力する場面が頻繁にあると思います。
その際には、consoleの最後に；が必要になることを頻繁に忘れます。
consoleのコーディングをする際に毎回確認することは難しいです。
自分なりに考えた対処法は、ある程度キリが良くなったときにそれまでコーディングしたconsoleに；を付け忘れていないかを一気に確認することです。
上記のようにすることでconsoleのコーディングの際に、余計なことに頭を使わなくて済みます。
consoleで困っている人はぜひ一度やってみてください。
生産性がかなり上がってくると思います。

これからもプログラミングを続けて、実力を高めてきたいです。
一緒に実力を高めていきましょう。
【PowerBI】リレーションでトランザクションデータがないマスタデータも表示させる

##Accessの場合。
こんなデータがあるとします。
①マスタ（メンバー名）
![Qiita1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221359/d21725ae-bcaf-eb80-19e3-40d7f10250f0.png)

②トランザクションデータ（日ごとの指名履歴）
![Qiita2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221359/20573f40-6aea-b35c-9764-932f1f4061f9.png)


Access慣れしていると、マスタデータとトランザクションデータをつなぐ時はこんな感じで、
![Qiita3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221359/a793bc0d-1889-f4c4-402b-1ead59247872.png)

集計する場合、もちろんトランザクションデータにないマスタデータ（今回の場合は全く指名のないメンバー）も表示されます。
![Qiita4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221359/0b13c016-fcaa-7a51-8a2c-3e6a8f867001.png)

##Power BIの場合。

Access癖がついてるとこれが当然と思うので、Power BIで同じようにリレーションして、
![Qiita5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221359/4ae0f7e6-f3bd-794d-118b-5d04124ec44b.png)

集計すると、全く指名のないフーディーは表示されないので困ってしまいます。
![Qiita6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221359/32b4248c-ce82-c6d6-653e-a2fc484ce3f9.png)

##IFを使ってトランザクションデータがないマスタデータも表示させる
全く指名のないメンバーも表示がないと、指名がなかったことが明示されません。

そこで、

```
指名数 = IF(ISBLANK(COUNT('指名履歴'[指名])),0,COUNT('指名履歴'[指名])) 
```

というメジャーを使用すると、
![Qiita7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221359/5b3bf634-57f3-16b0-6b40-3865b9d1491b.png)

全く指名のなかったフーディーも0件であることが明示されます。

（ちょっとした落とし穴かなぁと思い、備忘録的に記事にしてみました。）

##2019/07/03　神からのFBを受け追記
なんと！ひっそりと投稿したこんなちっぽけな記事にPoewrBI神がコメント欄でFBを下さいました。ありがたや・・・

コメント欄の通りなのですが、記事に追記させて頂きます。

ビジュアルをマトリクスじゃなくてテーブルを使用して、名前と日付のカウントを出します。
![Qiita1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221359/9a3a853a-39b4-006a-e2e2-7e2a02b75d93.png)

で、名前の設定を「データのない項目を表示する」にします。
![Qiita2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221359/6ac98367-7b8c-ca27-0f36-99cb4ca439af.png)

すると！！
![Qiita3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221359/f92ab39f-8066-f91b-62a9-648cc720cfd8.png)

指名のないフーディーも表示されました！

神のコメントにある通り、ブランクでいいのか、0を表示させる必要があるのかは考える必要がありますが、ブランクで問題ないのなら、わざわざメジャーを書く必要がないということが分かりました。勉強になりました！ありがとうございます！！