OmniAICreator/Qiita-1.07M huggingface dataset:
処理中にNavigationBarのボタン操作を無効にする。

# まくら
`Navigation Controller` を使ったアプリを作っている時に、稀によくある問題に対するアプローチです。

例えばこんな場合

* とある画面で時間のかかる処理中に読み込み中のインジケータを出したい
* インジケータが出ている間はナビゲーションバーの操作（戻るボタンとか）を無効にしたい

インジケータを出すのはいいとして、操作を無効にする方法はいくつか思いつきますが、今回は前面に目隠しを出して操作できないようにしてみましょう。

# ほんだい

まずはソースをどうぞ。
インジケータを表示する部分です。

``` swift

    // インジケータを表示する
    private func showIndicator() {
        
        // 背景になるView
        let backView = UIView()
        backView.backgroundColor = UIColor.init(white: 0.0, alpha: 0.5)
        backView.tag = 12345 // 消す時用にタグを付けておく
        
        // インジケータ
        let indicator = UIActivityIndicatorView()
        indicator.activityIndicatorViewStyle = .whiteLarge
        indicator.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        
        // NavigationControllerのViewを使う
        guard let naviView = self.navigationController?.view else {
            return
        }
        
        // 背景にインジケータを貼り付け
        backView.addSubview(indicator)
        
        // 背景をNavigationControllerのViewに貼り付け
        naviView.addSubview(backView)
        
        // サイズ合わせはAutoLayoutで
        backView.translatesAutoresizingMaskIntoConstraints = false
        backView.topAnchor.constraint(equalTo: naviView.topAnchor).isActive = true
        backView.bottomAnchor.constraint(equalTo: naviView.bottomAnchor).isActive = true
        backView.leftAnchor.constraint(equalTo: naviView.leftAnchor).isActive = true
        backView.rightAnchor.constraint(equalTo: naviView.rightAnchor).isActive = true
        
        // インジケータもAutoLayout
        indicator.translatesAutoresizingMaskIntoConstraints = false
        indicator.centerXAnchor.constraint(equalTo: backView.centerXAnchor).isActive = true
        indicator.centerYAnchor.constraint(equalTo: backView.centerYAnchor).isActive = true
        indicator.widthAnchor.constraint(equalToConstant: 100).isActive = true
        indicator.heightAnchor.constraint(equalToConstant: 100).isActive = true
        
        // インジケータ起動
        indicator.startAnimating()
    }
```

これを適当に実装するとこんな感じになります。

<img width="303" alt="SS 2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106197/e7b4934a-85f2-65e1-ea3a-e7509db6a576.png">

ポイントは`NavigationBar`がグレーの`View`に覆われていて`BarButtonItem`が押せない状態になっているところです。

ここですね。

``` swift 
    // NavigationControllerのViewを使う
    guard let naviView = self.navigationController?.view else {
        return
    }
```

``` swift
    // 背景をNavigationControllerのViewに貼り付け
    naviView.addSubview(backView)
```

要は、**`NavigationController.View`にも`addSubView`できますよ**って事ですね。

`NavigationController`の上に`View`を貼り付けるので、当然その下のボタン等は押せなくなるわけです。

<br>

ちなみに注意点としては、当然ですが、`NavigationController.View`が存在しないと使えません。

`prepare for segue`の遷移時など`NavigationController`が追いづらい時には正直使いづらいです。

<br>
現場からは以上です。
NVL2で違うデータ型の評価をされてしまう件について

```
NVL2の構文
NVL2(expr1, expr2, expr3)
expr1
NULLかどうかを調べる値を指定する。

expr2
expr1がNULL以外の場合に返す値を指定する。expr1と同じデータ型を指定する。expr1と異なるデータ型を指定した場合はエラーになる。

expr3
expr1がNULLの場合に返す値を指定する。expr1と同じデータ型を指定する。expr1と異なるデータ型を指定した場合はエラーになる。
```

expr2とexpr3が異なるデータ型の場合、expr2のデータ型につられて、expr3での型の評価が変わってしまう場合がある。
expr3のデータ型を変換されたくない場合は、expr2を型変換してあげることで、解決できる。
例)
expr2・・・ NUMBER型
expr3・・・ CHAR型
修正前：NVL2(expr1, expr2, expr3)
修正後：NVL2(expr1, T0_CHAR(expr2), expr3)
AnyとAnyObject

### Any
どんな型とも相当する。
関数型でもいい。

````swift:一貫性がない型のコレクション
let items: [Any] = [123, "ACB", 4.5, true]
````

### AnyObject
クラスなら、どんな型にでも相当する。構造体とかはダメ。

## キャストする

````swift:Any型はキャストして使う
if let firstItem = items.first as? Int {
    print(firstItem + 77)    // 200
}
````
Nightwatch.js検証

Nightwatch.jsを試す機会があったため、ドキュメントではわからない、実際に使ってみて気づいた点をまとめている。

#### 開発環境構築

* [Getting Started - Installation](https://nightwatchjs.org/gettingstarted/#installation)に従えば、インストールは問題なくできる。
* Windows環境ではChrome Driverを使ってテスト実行すると以下のエラーが出力された。

  ```
  An error occurred while trying to start ChromeDriver: cannot resolve path: "node_modules/.bin/chromedriver".
  ```

* これはChrome Driverのパス設定の問題なのでnightwatch.jsonを変更すればよい。（[参考](https://github.com/nightwatchjs/nightwatch/issues/1992)）

  ```
  "server_path": "node_modules/chromedriver/lib/chromedriver/chromedriver.exe"
  ```

#### テスト実装

* テストランナーにはMocha、アサーションにはchaiが使えるため、取っつきやすい。
* テストコードの構造化には、[Page Objects](http://nightwatchjs.org/guide/#working-with-page-objects)パターンや、事前・事後処理を定義する[Global Hooks](http://nightwatchjs.org/guide#using-before-each-and-after-each-hooks)が使える。また、テストファイルのグループ化（[Test Groups](http://nightwatchjs.org/guide/#test-groups)）もできる。
* TypeScriptを使うこともできるが、公式にサポートされてはいないので使いにくいところがある。
  * Nightwatch.jsはテストファイルの拡張子がjs前提になっているため、ts-nodeでは実行できず、tscでトランスパイルしたものを読み込む形にする必要がある。
  * 型定義（[@types/nightwatch](https://www.npmjs.com/package/@types/nightwatch)）の最新版は0.9.12と少し古い。（Nightwatch.jsの最新安定版は1.0.19）
  * Page Objectはオブジェクトとして定義するため、型（`EnhancedPageObject`）に合わせられない。
  * NightwatchBrowserオブジェクトから参照できるPage Objectの型も`EnhancedPageObject`型になるため自分で定義したメソッドを使うためには、キャストが必要になる。
* async/awaitは[v1.1（beta）以降で使える](http://nightwatchjs.org/guide#using-nightwatch)とのことだが、v1.1.8時点ではPromiseを返すメソッドと返さないメソッドが混じっている。また、Page Objectはasync/await未対応。

  ```typescript
  browser.url('http://www.google.com')) // Promise
  browser.click('input[name=btnK]') // 同期的
  browser.pause(500) // Promise
  browser.waitForElementVisible('input[name=btnK]') // 同期的
  ```

* Visual Studio Codeでのデバッグ実行はnodeコマンドにinspectオプションを指定すれば簡単にできる。
Markdown 書き方


[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている松井です。
＊プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

## はじめに
Markdownの書き方を練習の意味も込めてまとめます。
自分がよく使いそうだと思ったものだけを取り上げています。
もっといろいろな使い方を知りたい方は他を当たってください。

## 目次
1. 見出し
2. リンクの挿入
3. コードの挿入
4. 引用
5. エスケープ

## 1.見出し
文のはじめに「#」をつけることで見出しになります。
また、「#」の数で見出しの大きさが変わります。
HTMLで言うと``<h1>``や ``<h2>``などをhの後ろの数字が「#」の数と同じ意味です。
>#見出し
\#見出し（h1）

>##見出し
\##見出し

のように書きます。

## 2.リンクの挿入
>\[未来電子](https://www.miraidenshi-tech.jp/intern-content/program/)
のように書くと
[未来電子](https://www.miraidenshi-tech.jp/intern-content/program/)

\[リンクテキスト](URL)と書きます。

## 3.コードの挿入

> \```
def double(a):
    return a * 2

> \```

のように書くと

 ```
def double(a):
    return a * 2
```

のように表示されます。
さらに、コードの上にファイル名を入れることができます。

> \```python:double.py
def double(a):
    return a * 2

> \```

のように書くと

 ```python:double.py
def double(a):
    return a * 2
```
のように表示されます。
最初の「\```」の後に「言語:ファイル名」と書きます。

## 4.引用
「\>」を書きます。
「\>」によってネストできます。
> \>引用文を書く
>> 引用文を書く
>> ネスト
>>>ネスト

と言うように階段状に表示できます。

## 5.エスケープ
Markdownの前に「\」をつけるとMarkdownを無効化できます。
この記事ではかなり使われています。

## まとめ
本当はもっといろいろありますが、これだけでも十分です。
自分の1記事目もこれだけで書きました。
基本情報技術者試験を受ける上での"準備"の話

# はじめに
はじめまして、K4to_0です。Qiita初投稿です。
今回、基本情報技術者試験を受け、無事合格しました。
初めてのQiita体験も兼ねて、記事を書いてみます。

さて、IPAが載せている統計情報によると、平成31年度春期では、応募者**77,470人**に対し、受験者は**54,686人**となっています。[^1]
ここで既に**約30%の人が脱落している**わけです。
仮に何事もなく受験できたなら、既にあなたは上位70％です。おめでとうございます。
[^1]: https://www.jitec.ipa.go.jp/1_07toukei/toukei_h31h_sg_fe.pdf

# なぜなのか
まず、受験資格を失う原因として、主に次のようなものが挙げられます。

- 試験会場を間違える
- 持ち物(特に受験票)を忘れる
- 二度寝、そもそも起きない
- 試験会場に遅刻する
- マークミス(特に受験番号)

1つずつ見ていきましょう。

# 基本会場確認者試験

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ごめん、基本情報技術者試験(姫路)にはいけません。今神戸の会場にいます。この兵庫を東西に縦断する地下鉄に乗ってます。本当は恋しいけど、私の落とす試験もきっといつか誰かの資格を乗せるから。 <a href="https://t.co/vkfJ1BdJBQ">pic.twitter.com/vkfJ1BdJBQ</a></p>&mdash; Tako! (@TLE_maker) <a href="https://twitter.com/TLE_maker/status/1119755660667678720?ref_src=twsrc%5Etfw">2019年4月21日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

これは、今回**実際に起きた事例**の１つです。
実際、このようなケースは珍しいと思いますが、**近くの別の施設と間違えてしまう**等のミスは起こりうるので、
**受験票に書いてある地図も参考に**しながら、受験日前に確認しておくことを推奨します。

# 基本持ち物点検者試験
「基本情報　持ち物」でgoogle検索してみると、以下のようなサイトが見つかりました。[^2]
[^2]: https://studying.jp/kihonjoho/about-more/bring.html

> 基本情報技術者試験当日は、次のものを携行してください。

>持ち物
・受験票※（万が一忘れても、試験開始より30分以内に用意できれば、受験は可能です。）
・黒鉛筆及びシャープペンシル（B又はHB）
・鉛筆削り
・消しゴム
・定規
・時計（時計型ウェアラブル端末は除く。アラームなど時計以外の機能は使用不可）
・ハンカチ
・ポケットティッシュ
・目薬

原則、この通りに持っていけばOKです。(定規は使用しませんでしたが…)
ただし、いくつか説明が不足しているので、補足します。

### 昼食について
基本情報は、午前が9:30~12:00、午後が13:00~15:30で、間に１時間の休憩があります。
その時間で昼食をとるわけですが、試験会場は大抵の場合、初めて行く場所となります。
仮に店などの下調べをしていたとしても、会場には多くの人が集まるため、**店が混む可能性は十分に考えられます**。
よって、**昼食は弁当等を持参する**ことを強く推奨します。

### 時計について
引用にも書いてありますが、基本情報には腕時計を持参することができます。
持参しなくても受験は可能ですが、**午後問題を解く上で、時間配分がかなり重要**になってきます。
受験会場が大学等だった場合、室内はかなり広いので、**室内の壁掛け時計が見えない**可能性も十分あり得ます。
なので、1000円しない安い時計[^3](余計な機能がない分、そちらの方がむしろ安全かも)でもいいので、
**腕時計を用意する**ことを強く推奨します。
[^3]: 僕は[この腕時計](http://www.amazon.co.jp/gp/product/B00FLMCJMY/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1)を買いました
#
あと、**受験票には証明写真を忘れない**ようにしましょう！

# 基本起床技術者試験

人によっては**最も過酷な準備**がやってきました。
先程も書いたとおり、午前の開始時間は9:30です。なお、試験前に説明時間が取られているので、
**9:00には会場に着いている**ことが望ましいです。
遠方から参加する場合、**起床時刻が6:00より早くなる**というケースは珍しくないでしょう。
僕は朝に弱いタイプではないので特別なアドバイスはできませんが、しいて言えば、
**前日の勉強が控えめで済むよう、予め勉強しておきましょう！**

# 基本会場到着者試験

基本情報では、**午前の試験開始から30分経過まで(つまり10:00まで)は、遅刻しても試験を受けることができます。**
予め経路を確認しておいた場合、多少遅れたとしてもおそらくその時刻までには到着するでしょう。
試験会場によっては、**駅から試験会場までの臨時バスが出ている可能性もある**ので、有効活用しましょう！

# 基本マーク記入者試験

平成31年春期試験の時点では、**解答用紙の裏面にマークミスへの注意事項**が書いてありました。
特に**受験番号は、間違えると最悪採点されない**ことがあります。
午前のみでなく**午後も、問題を解き終わった後にもう一度チェックをしましょう！**

# おわりに
基本情報技術者試験は、取っておくと役に立つ資格の一つです。
年二回の試験なので、そういった**ミスで受験できないと、次の試験は半年後**となってしまいます。
せっかくの機会を失わないためにも、試験前に一度確認してみてはいかがでしょうか！

# おまけ(基本申込技術者試験)
基本情報技術者試験は、**毎年4月と10月**に開催されます！[^4]
[^4]: https://jitec.ipa.go.jp/
公式サイトで日程を確認し、申し込んでおきましょう！

2019/11/10 - 10月の試験を過ぎていたので修正
rails6.0でWARNING"DEPRECATION WARNING: Uniqueness validator will no longer enforce case sensitive comparison in Rails 6.1"が発生する理由

# 出力するケース

railsのバリデーション`uniqueness`の"大文字小文字の区別"と、対するDBのユニーク制約の"大文字小文字の区別"に不整合があるときに発生します。

## 具体例
たとえば、railsで以下の様にmodelを定義していたとします。

```
class Account < ApplicationRecord
  validates :email, uniqueness: true
end
```

そして、DBにMysqlを使用していて`accounts.email`に`utf8mb4_unicode_ci`などのcase insensitiveな`collation`を指定していたとします。
この時にも同様のWARNIGが出力されます。

# 出力する理由

`Account`モデルのバリデーション`uniqueness`の`case_sensitive`オプションが未指定なのでデフォルトの挙動`case_sensitive = true`になります。

その為、railsでのユニークバリデーションは
「大文字小文字の区別を**する**ユニーク制約」を行います。

一方、DBのcollationは`utf8mb4_unicode_ci`なので、
「大文字小文字の区別を**しない**ユニーク制約」を行います。

この不整合がMysqlでは様々な問題を起こしていたそうで、
rails6.1では仕様変更を行い、デフォルトの挙動を"DBのcollationに合わせる"にする様です。

なのでこのケースだとrails6.1以降は`Account`のユニークバリデーションもDBにあわせて
「大文字小文字の区別を**しない**ユニーク制約」に**変更**されます。

# WARNIGの意味

"このケースだとrails6.1以降は挙動が変わるから、rails6.0以前(現在)の挙動を維持したい場合は
明示的に`case_sensitive: true`を指定してね"って事っぽいです。

> railsでのユニークバリデーションは
「大文字小文字の区別を**する**ユニーク制約」を行います。

> 一方、DBのcollationは`utf8mb4_unicode_ci`なので、
「大文字小文字の区別を**しない**ユニーク制約」を行います。

# 参考
https://blog.kamipo.net/entry/2019/05/15/152652
https://railsguides.jp/active_record_validations.html#uniqueness
Google Colabで書いたipynbファイルをpyに変換してそのまま実行する

##はじめに
プログラミングは本業ではないですが、最近機械学習を学ぶ機会があり、
これを機会にPythonやらRやらを勉強中。G検定もクリアし、次はE資格かなと思うこの頃。

Pythonで機械学習のモデルを学習をさせる際、GPUが非力でも
GoogleColaboratoryを使えば、どんなPC環境でも快適に走らせられるので
最近気に入って使っています。
本気スペックPC+Anacondaよりこっちで十分足りる。というか速い。。。

##本題
教本を見ながら完成したスクリプトを引数指定して、実行しようと思ったときに
通常ならコマンドプロンプトからpyファイルを実行すれば良いと思うのですが、
これをGoogleCoab上で完結させようと思ったらどうすれば・・・？
と行き詰ったので、調べた結果を備忘録として以下に記載します。

自分はGoogleドライブをマウントしてお勉強するので、一連の動きを記載します。
前提として、コードは書き終えていて、Googleドライブ内にipynb形式で保存しているとします。

```python:Googleドライブをマウントする
from google.colab import drive
drive.mount('/content/drive')
```
これで認証画面のリンクが表示されるので、認証を済ませてマウントさせる。


```python:カレントディレクトリをGoogleドライブ上の目的フォルダへ移動
cd /content/drive/My Drive/Colab Notebooks/'目的フォルダ'
```

```python:実行するipynbファイルを確認
!ls
```

```python:プロンプト上ではipynb形式は走らせられないので、pyファイルに変換する
!jupyter nbconvert --to python '目的ファイル名'.ipynb
```
これでGoogleDrive上にpyファイルが作成される。
最後に、pyファイルを実行する。

```python:GoogleColab上（セル上）でpyファイル実行
!python "目的ファイル名".py
```

ちなみに、numpyのバグなのか走らないことがあるので以下の通りに
numpyをバージョン指定してインストールするのが吉。

```python:numpyのバグでコードが走らないことがあるので、バージョン指定してnumpyを入れ直す
!pip install numpy==1.16.1
```

##あとがき
初Qiita投稿です。今後も調べものの備忘録を記載していく予定です。
Macで画面収録した動画をGIFに変換する

# 変換ソフトのインストール
```shell-session
$brew install ffmpeg
```

# 稼動確認
```shell-session
$ffmpeg -version
```

# 使う
```shell-session
$ffmpeg -i input.mov -r 10 output.gif
```

# 圧縮する

アップロード画像の上限は10MBです。
[画像のアップロード方法 - Qiita:Support](https://help.qiita.com/ja/articles/qiita-image-upload)

まずはffmpegで圧縮

```shell-session
$ffmpeg -i input.mov -crf 30 output.gif
```

25MBから13MBになった。

```shell-session
$ffmpeg -i input.mov -crf 10 -t 05 -ss 0 output.gif
```

-t 切り出したい秒数
-ss 切り出しを開始する頭の秒数

13MBから9MBになった！

![theflyingpig1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268023/43d02d43-267d-d557-3806-0675ad86260d.gif)

[動画圧縮する時ってみなさんどうしてます？ | NIJIBOX BLOG](https://creatorsblog.nijibox.jp/mov-optimize/)

# 参考
[Macで画面を録画してGIFに変換する方法 - タダケンのEnjoy Tech](https://tadaken3.hatenablog.jp/entry/mov-to-gif)
[Qiitaにgifアニメを投稿する僕が考える一番簡単な方法【GIPHY CAPTURE】 - Qiita]( https://qiita.com/hirothings/items/7ed040d017bda13e261a)
[FFmpegの動画圧縮・変換コマンドの使い方 – Mankind Inc.](http://mankindinc.jp/wp01/2018/03/14/ffmpeg%E3%81%AE%E5%8B%95%E7%94%BB%E5%9C%A7%E7%B8%AE%E3%83%BB%E5%A4%89%E6%8F%9B%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/)
ElixirにおけるUUIDの生成（初投稿）

UUIDは他のIDと衝突しないIDを生成するために用いられるID生成アルゴリズムだそうです．本日は最近触ったばっかのElixirをつかってUUIDを生成する方法をまとめたいと思います．
#UUIDとは
16進数表記で「XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX」の32桁で表されるIDだそうです．UUIDにはいくつかバージョンが有るそうです．

|Version  |生成方法  |
|---|---|
|1  |時刻とMACアドレスを元にするもの  |
|2  |DCEセキュリティバージョン  |
|3  |バイト列を元にするバージョン．MD5ハッシュを使用|
|4  |ランダム生成するバージョン|
|5  |バイト列を元にするバージョン．SHA1ハッシュを使用|

基本的に用いられるのはバージョン1かバージョン4が用いられるそうです．バージョン1は時刻とMACアドレスを元に生成するためにユニークなIDを生成することができますが短時間に端末でアクセスして生成すればそのIDからMACアドレスを解析できてしまうため匿名性を犠牲にしています．逆にバージョン4はランダムに生成するために衝突する可能性がありますが，匿名性は担保されます．基本的にはバージョン4を使ってもほとんど衝突しないので問題ないとのことです．

#ElixirでUUIDを使う
まずはmixの準備

```sh
mix new example
cd example
mix test
```

./deps.getのExample.MixProject内のdepsを編集し，[UUID](https://hexdocs.pm/uuid/readme.html)ライブラリを追加

```elixir
  defp deps do
    [
      { :uuid, "~> 1.1" }  # UUIDを使うためのライブラリ
    ]
  end
```

そのあとmixで変更内容を読み取る

```sh
mix deps.get
```

32文字のUUIDを生成

```elixir
#UUIDをハイフンなしの大文字で生成
iex(1)> uuid_up = UUID.uuid4(:hex) |> String.upcase() 
"A0554870EC964556837BDAD67A6D8662"
```
32文字は長いので26文字の小文字の英数字のIDに圧縮

```elixir
#UUIDを16進数からBase32へ変更
iex(2)> uuid_base32 = uuid_up |> Base.decode16()|> elem(1) |> Base.encode32() 
"UBKUQ4HMSZCVNA333LLHU3MGMI======"
# UUIDのパディング（"="）を削除し，小文字に変換
iex(3)> String.replace(uuid_base32, "=", "") |> String.downcase() 
"ubkuq4hmszcvna333llhu3mgmi
```

これより短くするにはBase64を使えば22文字にまで減らせるが大文字と小文字の区別が必要になります．

#参考
UUIDの基礎
https://ja.wikipedia.org/wiki/UUID
http://blog.katty.in/5124
https://www.sohamkamani.com/blog/2016/10/05/uuid1-vs-uuid4/
ID生成アルゴリズムまとめ
https://qiita.com/j5ik2o/items/1799887fec241c10af39
mixの基礎
https://elixirschool.com/ja/lessons/basics/mix/
UUIDのAPIドキュメント
https://hexdocs.pm/uuid/readme.html
Baseのドキュメント
https://hexdocs.pm/elixir/Base.html
UUIDの圧縮
https://blog.kishikawakatsumi.com/entry/20131031/1383235295
http://www.hoshilabo.net/2018/02/22/uuid（128bit）を可逆短縮する手法/
Elixirの他のUUIDドキュメント
https://hexdocs.pm/ecto/Ecto.UUID.html
https://hexdocs.pm/shortuuid/ShortUUID.html
UnityでUIをレスポンシブに対応する方針について

## UnityでUIをレスポンシブに対応する方針について
UnityのCanvasにはVertical LayoutやHorizontal LayoutといったLayout Groupの機能があります。

Webフロントを経験していた自分はこれをたくさん使ってレスポンシブ対応をするのかと思いましたが、勉強していくと違うことに気がつきました。

Vertical LayoutやHorizontal Layoutは分かりにくいですし、細かい調整が面倒です。
また、デザイナーの方に調整してもらうことも難しくなります。

そこで、**アンカーやピボットを正しく設定する方針**が良いことに気がつきました。
例えば公式にもこのようなドキュメントがあります。
https://docs.unity3d.com/Manual/HOWTO-UIMultiResolution.html

Vertical LayoutやHorizontal Layoutは必要な箇所だけに限るようにした方が良さそうです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
新社会人エンジニアとして1か月半研修を受けた感想


## はじめに
私は4月から、19卒エンジニアとして名古屋のITベンチャーで働いています
そこで私自身の感じたことや成長を綴っていきます
よければ見てください

---

## 今までの自分がどれほど怠けていたのか

お恥ずかしながら、今まで「私って結構できる人間なのでは？」と慢心していました
それも、3年半続けていたドラックストアでのアルバイトで
社員さんにも指示をしたり、店舗の改善を行うことが多かったからです
今考えると、
**私に対し良いところ悪いところを真剣に考えてくれる人が居なかった、
言ってくれる人を作ろうとしていなかった**のだなと反省しています

---

### 社会人としての働きかた
4月から5月までの1か月間、私は**社会人になること**を目標にしてきました
その上で講義型の研修を通して学んだ社会人とは何かを自己理解したことを共有していきます

- 待つな、挑め
    - チャンスはどこにでも転がっている
    - 常にアンテナを張って誰かの独り言でも飛び込めばチャンスになる

---

### エンジニアとしての働き方
GW明けから今日までの2週間、**所属する会社のエンジニアになる**ことを目標に研修を行っていました
研修を行う上で何を意識たことで変わったこと、これからの課題は何なのかの2つを共有していきます

---

#### 1.意識したことで変わったこと
##### スタンス面
- 悪い所は良い所
    - 自分のダメなところを見つめ直して＋aすれば良い所に変わる
- 結論ファーストで伝える
    - 最初に結論を共有することで後の説明の理解が深まる
- わからないことは聞く
    - わからないことは悪ではない。
    - わかろうとしないことが悪。
- 誰からのフィードバックでも素直に受け止めて改善する
    - 自分自身が感じていなくても指摘を受けたということは出来ていないことである
    - 人生素直に生きよう
- 気づいた、感じた（自分の感情）ことは素直に伝える
    - 伝えたことで新たな発見があったことが沢山あった
- チームメンバーのGOOD BADを言い合える関係を意識して築く
    - 個人、メンターでは気づけないことがチームメンバーなら気づける
    - お互いの相互理解にも繋がる
- 自己開示を行う
    - 上記の関係を築く点においてとても重要
    - まずは自分を理解して貰うところから始めよう
- 幸せの共有を行う
    - 深堀することでその人が何を感じているのかを理解できる

---

##### 行動面
- PDCAサイクルは最短で回そう
    - 不可能はない
    - 早ければ早いほど早く成長できる
    - 仕事ができる人はみんなしている
- 報連相は相手が嫌になるくらいしても良い（しないよりかは）
    - 報連相されないと相手は不安である
    - 誰も不安にさせたくない
- 気づいた、感じた（自分の感情）ことは素直に伝える
    - 伝えたことで新たな発見ができる
- ダブりより漏れのリスクを重要視する
    - (例)1.会社の未来に関わる作業を同時に行い工数が増える 2.会社の未来に関わる作業があるのに忘れている　
    では圧倒的後者のほうがリスクがある
- 1つの議題に対して共通の議論時間を決める
    - 白熱し、議論がまとまらなくなる時の原因の1つにチーム内全員時間の意識が少ないことがある
- 議題を見える形にしておく
    - まとまらなくなる原因の1つに話が逸れ、各個人毎に今何を話しているのかの相違が生まれてく
- 共有をしっかりと行う
    - 今、誰が、何をしているのか
    - これからするべきことは何なのか
    - 根本的に今の作業は必要なのか
    - チーム間でダブり、漏れがないか
- ヒアリングはしっかり準備をしよう
    - 貴重な時間を頂いている認識を持つ
        - 伝えたいこと、教えてほしいことを先に知らせておく
        - 1回の返答には必ずなぜそう思ったのかを深堀りする

---

#### 2. これからの課題

- 結論ファーストで話すことに少し慣れたことで 
    - 結論の理由付けが弱い
    - 聞いてもらう相手を聞く体制にできていない
- 主張が弱い
    - もっとやりたいことをやりたいと発信する

---

#### みんながみんなを幸せにできる世界を作りたい
[C++/C#]C#をC++/CLIでラップしてC+＋アプリから呼ぶ

# やりたいこと
すでにC#で作ってあるライブラリ(dll)を、C++のアプリから呼びたい。
方法として、C#のdllをC++/CLIでラップして、C++から呼ぶということを試してみる。

## C#dllを作る

クラスライブラリ(.NET Framework)のプロジェクトを新規追加し、下記のコードを追加する。

```DllCs.cs
namespace DllCs
{
    public class DllCsClass
    {
        public static int Add(int a, int b) => a + b;
    }
}

```

## C++/CLIのラッパーを作る
VisualC++ > CLR > CLRクラスライブラリ を選択し、プロジェクトを作成し、下記のコードを追加する。

```CsWrapperCppCLI.cpp
// C#をC++/CLIでラップするラッパー関数群
#include "stdafx.h"
#include "CsWrapperCppCLI.h"

// C#(.net)のクラスのnamespace
using namespace DllCs;

// C++/CLIラッパー関数
double __cdecl Add(int a, int b)
{
	// ここで、C#(.net)のメソッドを呼ぶ
	int ret = DllCsClass::Add(a, b);

	return ret;
}

```

```CsWrapperCppCLI.h
#pragma once

// エクスポートとインポートの切り替え
#ifdef VC_DLL_EXPORTS
#undef VC_DLL_EXPORTS
#define VC_DLL_EXPORTS extern "C" __declspec(dllexport)
#else
#define VC_DLL_EXPORTS extern "C" __declspec(dllimport)
#endif

VC_DLL_EXPORTS double __cdecl Add(int a, int b);

```

※参照に、DllCsのプロジェクトを追加。
※このあたりの書き方は、通常のC++からC++のDLLを呼ぶ方法と同じ。
　→[こちら参照](https://qiita.com/tera1707/items/727e7ad4dc9f3205c137)

## ラッパーを呼ぶC++アプリを作る
C++のコンソールアプリのプロジェクトを作成し、下記コードを追加する。

```ConsoleApplication1.cpp
#include "pch.h"
#include <iostream>
#include <Windows.h>

using namespace std; 

typedef int(*Add)(int p1, int p2);

int main()
{
	auto dll = ::LoadLibrary(L"CsWrapperCppCLI.dll");
	auto add = reinterpret_cast<Add>(::GetProcAddress(dll, "Add"));
	wcout << add(10, 20) << endl;

	system("pause");
}
```

※ここも、通常のC++からC++のDLLを呼ぶ方法(動的)と同じ。
　→[こちら参照](https://qiita.com/tera1707/items/727e7ad4dc9f3205c137)

# 参考
C#のメソッドをC++から呼ぶ方法
https://qiita.com/tetsurom/items/a0ad9bd24dbe513afdc4

# コード
https://github.com/tera1707/WPF-/tree/master/026_CallCsDllViaCppCLI
Readabilityで本文っぽい文章を抽出

# Readabilityのインストール

まずはReadabilityとhtml2textをインストール。

```
pip install readability-lxml
pip install html2text
```
1. Readabilityで本文抽出
1. html2textでmarkdown形式に変換し読みやすくする

# Readabilityを使う

```python.py
# ライブラリをimport
from readability.readability import Document
import urllib.request
import html2text

# 実行
url = "https://flatclub.jp/shinobiwriting/"
html = urllib.request.urlopen(url).read()
# 本文っぽい部分を抽出
article = Document(html).summary()
# htmlからmarkdown形式に変換
text = html2text.html2text(article)
# とりあえずコマンドラインに出力
print(text)
```
抽出完了。

# 参考
[<Python, readability, html2text, urllib> HTMLから本文抽出。 - ねこゆきのメモ](http://nekoyukimmm.hatenablog.com/entry/2015/12/24/113719)
[Python – readability-lxmlを利用して本文抽出｜Miningoo](https://miningoo.com/1003/)
[Python]リスト内法表記で複数の返り値を返す方法

# リストなどでまとめて返してあげましょう。

```Python:OK
[[i,i] for i in range(0,10,1)]
```
「リスト内法表記 複数 返り値」で検索しても一瞬で出てこなかったので、検索用として記しておきます。

---
リストに入れないとエラーが出ます。

```Python:NG
[i,i for i in range(0,10,1)]
```

---
これで大丈夫だったので感覚的に大丈夫かなと思ったらいけませんでした。
関数の返り値が複数の場合はタプルで帰ってくるので当たり前でしたね。

```Python:OK
def double(x):
    return x,x
[double(i) for i in range(0,10,1)]
```
これと同じですね。

```Python:OK
[(i,i) for i in range(0,10,1)]
```

---
条件式と内法表記でもちゃんと使えます。

```Python
[[i,"even"] if i%2 else [i,"odd"]  for i in range(0,10,1)]
```

返り値の個数を可変にもできますが、処理がめんどくさくなるので、避けたほうがいいと思います。

```Python
[[i,"even"] if i%2 else ["odd"]  for i in range(0,10,1)]
```

---
リスト内法表記は以下の記事が非常に参考になります。
上記の内容も「二次元リストを作る」に書いてありましたが、実装したい動作イメージと検索ワードが異なっており、見逃しておりました。
[リスト内包表記の活用と悪用 - Qiita](https://qiita.com/KTakahiro1729/items/c9cb757473de50652374)
【Java】Progateで取り上げられていないJavaの基本まとめ~その2・List編~

# リスト
Progateでは配列については取り上げられているが、リストについては触れられていない。
配列とリストは似ているが何が違うのか？


## 配列
```java:
int result[] = new int[5];

result[0] = 85;
result[1] = 78;
result[2] = 92;
result[3] = 62;
result[4] = 69;
```

入れ物に例えるなら、配列result[]は先に入れ物の大きさを決めなければならず、
さらに一度その大きさを決めるとそれ以降は変更できないという特性をもつ。

## リスト
```java:
List<String> list = new ArrayList<String>();
```

これに対しリストの大きさは可変であり、要素の追加・削除が可能。

### インターフェイス

javaではリストを扱うためのインターフェイス(仕様書のようなもの)が定義されている。
このListインターフェイスはCollection（コレクション）をルーツとしたインターフェースである。

### packageのimportが必要

Listを使用するためには`java.util.List`を`imrport`する必要がある。

```java:
import java.util.List;
```
また、Listはインターフェイス(仕様書)なのでそれ自体は実装を持たないため、
別途Listインターフェイスを実装した`class`も`import`する必要がある


### ArrayListとLinkedList

Listインターフェイスを実装した`class`に、`ArrayList`と`LinkedList`がある。

#### ArrayListクラスのインスタンスを作成してみる

```java:
import java.util.list;
import java.util.ArrayList;

public class Main {
  public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    System.out.println(list);
  }
}


/// 実行結果
/// >[]
``` 

`List<String> list = new ArrayList<>();`
変数がList型であること、このListが扱うデータがString型であることを宣言している。


#### LinkedListクラスのインスタンス作成

```java:
import java.util.list;
import java.util.LinkedList;

public class Main {
  public static void main(String[] args) {
    List<String> list = new LinkedList<>();
    System.out.println(list);
  }
}


/// 実行結果
/// >[]
``` 

LinkedListにはListにない固有メソッドがいくつか定義されているがここでは省略。
(ArrayListにはほとんどない)

#### プリミティブ型を扱うリストの場合

Listは`int`, `long`などのプリミティブ型を直接扱うことができない。
`String`は参照型。
プリミティブ型と参照型について詳しくは以前の記事の表を参考までに。
https://qiita.com/hiroshimahiroshi/items/01de02cfe1caacd07540#3-%E5%9F%BA%E6%9C%AC%E3%83%87%E3%83%BC%E3%82%BF%E5%9E%8B%E3%81%A8%E5%8F%82%E7%85%A7%E5%9E%8B

ということで`int`や`long`などのプリミティブ型を扱う場合には`int`のラッパークラス`Integer`、
`long`のラッパークラス`Long`を使用する。

```java:
    List<Integer> list = new LinkedList<>();
```

プリミティブ型？ラッパークラス？がよくわからないけどとりあえずリストだけ先にわかりたい！
という場合は、とりあえず`List<型>`の型が小文字で始まっていたら何か変だと思っておいて、
プリミティブ型と参照型、ラッパークラスについては別途学びましょう。


# 終わりに

記事を大幅に編集しました。
Progateを終えてJavaを何でもわかった気になってしまった自分みたいな人の為の記事ですので、
さわりしか触れていませんが重要基礎知識だと思いますので、この先は[CODEPREP](https://codeprep.jp/)で理解を深めましょう。
Lambda関数のローカル作成方法(chalice)

[lambda-uploaderの記事](https://qiita.com/makishy/items/ca830cf7c4caae8724c1)を書きましたが続いてchaliceのご紹介を。

# chalice
chaliceはAWS謹製のツールで、非常に簡単にLambda + API Gatewayをデプロイできるすぐれものです。
https://chalice.readthedocs.io/en/latest/


## インストール〜デプロイ
公式サイトにも記述がありますが、

```
$ pip install chalice
$ chalice new-project helloworld && cd helloworld
$ chalice deploy
```
たったこれだけでLambda + API Gatewayのデプロイをしてくれます。
デプロイが完了すると以下のように生成されたエンドポイントをガイドしてくれます。

```
Creating deployment package.
Creating IAM role: helloworld-dev
Creating lambda function: helloworld-dev
Creating Rest API
Resources deployed:
  - Lambda ARN: arn:aws:lambda:ap-northeast-1:000000000:function:helloworld-dev
  - Rest API URL: https://000000.execute-api.ap-northeast-1.amazonaws.com/api/
```

Flaskをベースに作られているので、Flaskに馴染みのある方であればすぐにご利用いただけるかと。また、以下のコマンドを実行するとローカルでサービス起動できるので、デプロイ前のローカルテストもできます。

```
chalice local
```

## Lambdaの設定カスタマイズ
chaliceを使ってデプロイするとIAMロール作成など必要な設定を自動で実行してくれます。ただ、運用によっては困るケースもありますよね。以下の設定ファイル（config.json）をカスタマイズすることで手動で指定することもできます。

```
$ tree -a
.
├── .chalice
│   └── config.json
├── app.py
└── requirements.txt
```
例えば、既存のIAMロールを指定したい場合などは以下のように設定します。

```
{
  "version": "2.0",
  "app_name": "app",
  "stages": {
    "dev": {
      "autogen_policy": true,
      "api_gateway_stage": "dev"
    },
    "beta": {
      "autogen_policy": false,
      "iam_policy_file": "beta-app-policy.json"
    },
    "prod": {
      "manage_iam_role": false,
      "iam_role_arn": "arn:aws:iam::...:role/prod-role"
    }
  }
}
```
上の例では、３つのステージ（dev, beta, prod）を指定しています。devステージはポリシーを自動生成します。betaステージは設定ファイル（.chalice/beta-app-policy.json）をロードし、IAMロールとの関連付けを行います。prodステージは、IAMロールの変更はされません。Lambda関数に指定されたロール（arn:aws:iam::...:role/prod-role）の設定のみを行います。

詳細は[公式](https://chalice.readthedocs.io/en/latest/topics/configfile.html)を参照してくださいませ。

## スケジュール、SNS、SQS、S3イベント
chaliceは、API Gateway以外にもスケジュール、SNS、SQS、S3イベントの設定もサポートしています。サーバーレス構成のバリエーションが広がりますね。
https://chalice.readthedocs.io/en/latest/topics/events.html#

## まとめ
最高ですね。
ただ、このツールがサポートしているのはpythonのみです。サーバーレス環境のバックエンドをpythonで手軽に書きたい方にはオススメです。お試しいかがでしょうか？
SELinuxやFirewallは正義か？

# はじめに
今どきのLinuxは、SELinuxやFirewall（ここではfirewalldやiptablesなどのソフトウェア実装を指す）がデフォルトで有効になっていることが多い。これらはインフラ屋にとって難しい存在で、セキュリティ強化をアシストしてくれる一方、これらの機能によって思い通りに操作できないことがある。

そのため

**とりあえずSELinuxとFirewallは全部OFF**

という人もいれば、

**すぐにSELinuxとFirewallを無効にするのはエンジニアとして思考停止。お金をもらうプロフェッショナルならばセキュリティの重要度を考えるべし**

という人もいる。楽観主義者と原理主義者が混在している状況だ。

独断と偏見で言わせてもらえば

**「状況に応じて判断するべきもので、絶対的にどちらが優れている、という性質のものではない」**

本番環境であれば、十分な対策を施したうえでのことではあるが。

# 他の代替策も考える

たとえばオンプレミスの場合、ルータでACLをがっちり固めていれば、OSのソフトウェアFWは正直なところ必要ないだろう。またクラウドではOS上のソフトウェアFWはトラブルにつながるので、そもそも無効化されていることがある（誤ったFW設定でssh接続できなくなる危険性など）。AWSでは当然それに変わる機能をクラウド側で備えている。

またSELinuxは、万が一潜入されても被害を最小限にできる機能だ。だからWAFを入れるなど、そもそも潜入させない仕組みも重要だろう。さらにその前に「クラウド上にログイン用のssh秘密鍵を置く」といったリテラシーの低い行為を徹底的に禁止すべきだ。

# 全体のメンバースキルも考える

とても困るのは、全体の状況やメンバーのスキルを考えない開発者で、自分のスキルに自信を持っているが故に、ガチガチに固めたうえ、ろくなドキュメントも無く、それを他人にも押しつけるケースだ。

これらを押しつけた結果、SELinuxやfirewalld/iptablesの操作が難しく開発・構築フェーズの生産性が上がらない。また運用フェーズで間違ったオペレーションをしてしまいトラブルが発生する。

さらに最悪なのは運用フェーズで何かトラブルがあっても、SELinuxやfirewalld/iptablesに精通しているメンバーが不在で、設定した本人以外はどうにもできないという状況だ。

**セキュリティも重要だが、身の丈を超えたものは、他のトラブルを招く。**

# 運用トラブルいろいろ

**なんだか本題のSELinuxとFirewallから本題がそれてきた気がするが、このまま突っ走ることにする（笑）。**

この手のトラブルはセキュリティ以外にもある。筆者は直接の当事者では無かったが、以下のような経験をしたことがある。

1. 突如Webサーバが停止。Webにページアクセスできず
2. 運用担当者が```service httpd status```で確認したところ停止していた
3. 急いで```service httpd start```でWebサーバ起動。しかし解決せず
4. 運用手順書を見ると、独自の起動用スクリプトがあることを発見。それを使っても起動できず
5. 最終的な原因はrpmでインストールする標準のhttpd以外に、別ディレクトリにソースコードからインストールしたWebサーバがあったこと。起動／停止には独自スクリプトを使う必要があったが、```service httpd start```でWebサーバを起動してしまったためにポートを確保。そのため独自の起動用スクリプトを使っても起動できなかった

ここから得られる反省点は、標準および標準化に対する認識が不足していたこと。標準のhttpd以外にhttpdがあるならば、標準のhttpdは削除しておくべきだし、依存性で削除できないならば、起動スクリプトを差し替えてワーニングのメッセージを出すのも一つだろう。

**間違う可能性があるならば、それを徹底的に排除する対策をとることも重要だ。**

# 利用者／運用者の目線を持つこと

一般的なエンタープライズシステムは、開発期間と比べて運用期間ははるかに長い。はるかに長いゆえ、開発時のことをよく知っていた運用担当者がいなくなり、保持しているノウハウも低下する。たとえ、いたとしても記憶は薄まる。

また開発者はそのとき注力しているため十分な知識があるが、利用者／運用者はそれほどの知識を持たない。

このことを十分に理解せず

**「エンジニアならば、この程度のことはできるだろう」**

という高い目線で設計やドキュメントすると、利用者／運用者が使いこなせず、トラブルや問い合わせ頻発というのも、ありがちな話だ。

# まとめ
全然まとまっていないが、全体を俯瞰できる高い視点に立ち、ナルシストに陥らず、運用までを考慮することが重要だろう。なんだか、タイトルと全然違う内容になっている気がするけれど、ごめんなさい。

* **全体を考えたバランス感**
* **自分だけで無く、運用担当者を含めた企業全体のリテラシーを考えた設計**
* **標準への順守。間違いづらい設計**
text as bitmap And New Line

テキストをBitmapにするやつがあるけど、改行とかどうするの？って時に。
あとはfeelingでなんとかして！

```java:TextToBitmap.java

    public static Bitmap textAsBitmap(String text , float textSize , int textColor){
        Typeface font = getTypeface(); // Get Your Typeface
        Paint paint = new Paint();
        paint.setTextSize(textSize);
        paint.setTypeface(font);
        paint.setColor(textColor);
        paint.setTextAlign(Paint.Align.LEFT);
        float baseline = -paint.ascent();
        int width,height;
        String message = "";
        String[] splitList = text.split("\n"); // new Line!!
        if(splitList.length != 0){
            for (String s : splitList) {
                if (message.length() < s.length()) {
                    message = s;
                }
            }
            width = (int)(paint.measureText(message)+0.5f); // round
            height = (int)((baseline * splitList.length)+paint.descent()+0.5f);
        } else {
            width = (int)(paint.measureText(text)+0.5f); // round
            height = (int)(baseline+paint.descent()+0.5f);
        }
        Bitmap image = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(image);
        if(splitList.length != 0){
            for(int i = 0 ; i < splitList.length ; i++ ){
                canvas.drawText(splitList[i], 0, baseline * (i+1), paint);
            }
        } else {
            canvas.drawText(text, 0, baseline, paint);
        }
        return image;
    }

```

元ネタ
https://stackoverflow.com/questions/8799290/convert-string-text-to-bitmap
hivexregeditを使うとバックスラッシュが消えてしまう問題

# BCDファイルからバックスラッシュが消える
　先日Windows10が壊れまして。どうもブートローダがおかしくなったっぽいので色々いじってたら回復環境すら起動しなくなり、 http://d.sunnyone.org/2015/11/uefi-windows-safe-mode-with-linux.html < こちらの記事を頼りにUSBブートしたlinuxからBCDを直接書き換えようとしたわけです。ところが、イマイチ上手くいかない。
　気づけば、この方法で編集したregファイルをmergeするとダブルクオートで囲まれているパスの文字列からバックスラッシュが消えていたのです。

# 解決方法
　どうしたらいいのこれ？と言うことで検索したところ、 http://libguestfs.org/hivexregedit.1.html のSHELL QUOTINGという項目が引っかかりました。
　なので、まずはダブルクオートになっているところをシングルクオートに直してmergeしましたが、これはダメ。シングルクオートはダブルクオートに直され、そしてその中のバックスラッシュはやはり消えています。
　結局ダブルクオートの中のバックスラッシュをダブルにしたところ、merge後もバックスラッシュが維持されました。

# 余談
　ちなみに壊れたWindows10なのですが、上記の方法でもセーフブートすらしない状況だったのが、最近はMacでもLinuxでもWindows10のブータブルUSBを作れるみたいで、そちらから無事再インストールして回復しました。
　こんなことができるのも、Microsoftが直々にWindows10のディスクを配布しているからなんですね。 > https://www.microsoft.com/ja-jp/software-download/windows10ISO
　こんな豪奢な配布があるとはつゆ知らず、ずいぶんな遠回りをしてしまいました。
[C++/C#]C#をCOM参照可能にしてC+＋アプリから呼ぶ2

# やりたいこと
[前回](https://qiita.com/tera1707/items/7e22812f27884d0e3c49)の続きで、`C#のdllを、COM参照可能にしたC#dllでラップして、C++アプリから呼ぶ`ことができるのは分かったが、その`C#のdll`と`COM参照可能にしたC#dll`と`C++アプリ`のそれぞれのプラットフォーム(x64/x86/ANYCPU)の組み合わせで、動く動かないをはっきりさせたい。

# 関連項目目次

- [[C++/C#]C#をCOM参照可能にしてC+＋アプリから呼ぶ1](https://qiita.com/tera1707/items/7e22812f27884d0e3c49)
- [[C++/C#]C#をCOM参照可能にしてC+＋アプリから呼ぶ2](https://qiita.com/tera1707/items/a12341d87ce0b47eba55)

# 実験内容
[前回](https://qiita.com/tera1707/items/7e22812f27884d0e3c49)のプロジェクト一式を使用して、`C#のdll`と`COM参照可能にしたC#dll`と`C++アプリ`について、それぞれ`x64``x86``ANYCPU`のdllを作成する。(C++アプリについてはANYCPUはなし)

それを組み合わせて実行し、うまく動作するかどうかを確認する。

動かすときは、下のような`exerun_64.bat``exerun_86.bat`を作成し、`COM参照可能にしたC#dll`を登録してから`C++アプリ`を実行する。

```exerun_64.bat
@echo off
cd %~dp0
regasm_64 /u DllCsComWrapper.dll
regasm_86 /u DllCsComWrapper.dll

regasm_64 /codebase DllCsComWrapper.dll
pause
start /wait ConsoleApplication1.exe
echo exeからの戻り値は %ERRORLEVEL% です

regasm_64 /u DllCsComWrapper.dll
regasm_86 /u DllCsComWrapper.dll
pause
```

```exerun_86.bat
@echo off
cd %~dp0
regasm_64 /u DllCsComWrapper.dll
regasm_86 /u DllCsComWrapper.dll

regasm_86 /codebase DllCsComWrapper.dll
pause
start /wait ConsoleApplication1.exe
echo exeからの戻り値は %ERRORLEVEL% です

regasm_64 /u DllCsComWrapper.dll
regasm_86 /u DllCsComWrapper.dll
pause
```

### 前提
ｘ64,86それぞれのregasm.exeをとってきてそれぞれregasm_64.exe、regasm_86.exeに改名し、同じ階層に置いている。

### ポイント
ｘ64、ｘ86のラッパーdllは、ｘ64.ｘ86それぞれのregasmでしか登録できない。
anycpuのラッパーdllは、ｘ64.ｘ86どちらのregasmでも登録できる。
その際、x64のregasmで登録すればx64向けのdll、ｘ86のregasmで登録すればx86向けのdllとなる。

### 便利bat
各dll、exeのターゲットが何か(x86/x64)を出力する。
※AnyCPUはｘ86と出る様子。

```CheckBinaryTarget.bat
@echo off
echo process start...

rem 開発用コマンドプロンプト(環境によってはパス違うかも)
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\Tools\VsDevCmd.bat"

cd %~dp0

SET TARGET1="ConsoleApplication1.exe"
SET TARGET2="DllCsComWrapper.dll"
SET TARGET3="DllTestCs.dll"

echo %TARGET1%
dumpbin /headers %TARGET1% | findstr machine

echo %TARGET2%
dumpbin /headers %TARGET2% | findstr machine

echo %TARGET3%
dumpbin /headers %TARGET3% | findstr machine

pause
```

# 結果
下記のようになった。※C#dllのAnyCPUは試してない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/ace63f29-99d1-1ea3-6b3f-3729bd5a81a9.png)

結果としては、

- C#dllがx64であれば、ラッパーもC++アプリもx64でないといけない
- C#dllがx86であれば、ラッパーもC++アプリもx86でないといけない

という普通な結果となった。

# しかし
COMは、もうちょっと便利な、x64ともx86とも連携できる便利な奴、ではなかった？
イメージが間違えていた？？

このHPにあるように、なにかやり方があるのかも。(未検証)
ここにあるのは(32bitDLLを64bitプロセスから呼ぶ方法だが...)
https://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-code/

# 参考
64bitアプリと32bit DLLの混在
https://www.backyrd.net/entry/20130704/1372920343

# コード
https://github.com/tera1707/WPF-/tree/master/025_CallCsDllFromCpp
WP-CLI + sed でインストール済みプラグインのスラッグだけを1行にまとめて出力する

開発環境の WordPress にインストールされているプラグインのみリモート環境に再現したかったので。

``wp plugin list --field=name | sed -e ':loop;N;$!b loop;s/\n/ /g'``

出力された文字列をコピーして、リモート環境で

``wp plugin install ``に続けてペースト。
scalaで実装！Affine層を実装してみた！

#Affine層をscalaで実装！
###復習
Affine層での処理は以下図の通りでしたね（詳細：[図で理解！”学習”の基盤：ニューラルネットワークの”逆伝搬”と”更新”](https://qiita.com/NagisaOniki/items/324b26065e1917469907)）

![Affine計算グラフ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334811/922a769b-2118-2d64-cf89-10fe174cfdda.png)
![Affine計算グラフ逆伝搬.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334811/c4917bd1-899f-c004-7f4e-7cfbd4b75677.png)

ではこの処理を実際に、コードに落とし込んでいきましょう。

作成したいAffine層のクラスの大枠は以下のようになります。
＊バッチ数（ここではデータ数と捉えてもらえれば）が１の場合

```scala:Affine.scala

class Affine(val xn:Int, val yn:Int) extends Layer {
  override type T = Float
  //必要な変数宣言
  val rand = new util.Random(0)
  var W = DenseMatrix.zeros[T](yn,xn).map(_=>rand.nextGaussian.toFloat *0.01f) //重み
  var b = DenseVector.zeros[T](yn) //バイアス
  var dW = DenseMatrix.zeros[T](yn,xn) //Wの誤差
  var db = DenseVector.zeros[T](yn) //bの誤差
  var xList = List[Array[T]]() //入力を格納
  var sW = DenseMatrix.zeros[T](yn,xn) //update(Adam)で使用 
  var sb = DenseVector.zeros[T](yn) //update(Adam)で使用
  var rW = DenseMatrix.zeros[T](yn,xn) //update(Adam)で使用
  var rb = DenseVector.zeros[T](yn) //update(Adam)で使用
  var p1t = 1f //update(Adam)で使用
  var p2t = 1f //update(Adam)で使用

 def push(x:Array[T]) = { xList ::= x; x }
 def pop() = { val x = xList.head; xList = xList.tail; x }

 def forward()={
   //WX+bの処理
 }

 def backward()={
   //WX+bの逆伝搬の処理
 }

 def update(){
   //パラメーター更新
 }

 def reset(){
   //パラメーターの初期化
 }



}
```


##forward実装
```scala
  def forward(x:Array[T]) = {
    push(x) 
    val xv = DenseVector(x) //xをベクトル化
    val y = W * xv + b //WX+bの処理
    y.toArray //出力を返す
  }
```

##backward実装

```scala
def backward(d:Array[T]) = {
    val x = pop() 
    val dv = DenseVector(d)
    // dW,dbを計算
    dW += dv * DenseVector(x).t
    db += dv
    // dxを計算
    var dx = DenseVector.zeros[T](xn)
    dx = W.t * dv
    dx.toArray //dxを返す
  }
```

##update実装(Adam)
```scala
def update() {
   val ep = 0.01f //学習率
   val p1 = 0.9f //モーメントの推定に対する指数減衰率
   val p2 = 0.999f //モーメントの推定に対する指数減衰率
   val delta = 0.00000001f //数値安定のための小さな定数デルタ
   p1t = p1t * p1 
   p2t = p2t * p2
   sW = p1 * sW + (1f-p1) * dW
   sb = p1 * sb + (1f-p1) * db
   rW = p2 * rW + (1f-p2) * ( dW *:* dW )
   rb = p2 * rb + (1f-p2) * ( db *:* db )
   val s_W = sW /:/ (1f-p1t)
   val s_b = sb /:/ (1f-p1t)
   val r_W = rW /:/ (1f-p2t)
   val r_b = rb /:/ (1f-p2t)
   W += -ep * s_W / (r_W.map(a=>math.sqrt(a).toFloat) + delta ) //パラメーターWの更新
   b += -ep * s_b / (r_b.map(a=>math.sqrt(a).toFloat) + delta ) //パラメーターbの更新
  }

```

Adamの更新方法については、別記事で解説予定なので、ここでは
”とりあえずパラメーターを更新している”
と考えてください。
##reset実装
```scala
def reset() {
    dW = DenseMatrix.zeros[T](yn,xn)
    db = DenseVector.zeros[T](yn)
    xList = List[Array[T]]()
  }
```


##まとめ:scalaで実装！Affine層を実装！
実際1つのネットワーク層を実装するとforward,backward,update,resetに大きく分かれ、
それぞれで処理を行います。

次回実装編はConvolution層を実装してみようと思います。
MAMPでMediaWikiを構築する

MacにMediaWikiを使用してローカルのprivate wikiを構築しました。
初心者ゆえSQLの設定にまんまとハマったので備忘録です。
MAMPでmysqlを導入した際に、MySQLWorkbenchの設定も行ったので最後に簡単に併記します。

##環境
MacOSX Mojave version 10.14.5
5.7.25 MySQL Community Server (GPL)
MAMP version 5.3
MediaWiki version 1.31.1
MySQLWorkbench version 8.0.16


##SQL編

###MAMPをダウンロード
https://www.mamp.info/en/downloads/

MAMPを起動し、Start Serversを押す。


### mysqlを実行する
参考：[MAMP ver 5.2環境下で、ターミナルからMySQLにログインする](https://qiita.com/hoshi_shiitake/items/69a5a0a3ba0c4fb7a488)

ターミナルでbinに移動し、mysqlを起動してパスワード（defalt：root）を打ち込む。

```shell
cd /Applications/MAMP/Library/bin
$　./mysql -u root -p
Enter password: root

# 成功時は以下
mysql>
```

### MySQLでユーザーの作成やパスワードの変更
以下を参考にしながら、ユーザーの作成などを行う。

参考：[MySQLインストール時にやること（DBとユーザーの作成等）](https://qiita.com/daichi87gi/items/f9dac6cd8acc3ad4330d)
参考：[【MySQL】ユーザーを作成と権限の追加](http://www.sky-limit-future.com/entry/mysql_create_user)

```sql:mysql
mysql> CREATE USER 'ユーザー名'@localhost IDENTIFIED BY 'パスワード';
mysql> USE mysql;
mysql> select user, host from user;

/*結果はこれ*/
+---------------+-----------+
| user          | host      |
+---------------+-----------+
(略)
| ユーザー名     | localhost |
(略)
+---------------+-----------+
7 rows in set (0.00 sec)

```


### トラブルシューティング
rootのパスワードを変更したつもりでもう一度ログインしようとしたところめっちゃエラーが出た。
参考：[MySQL の root パスワード忘れた時](https://qiita.com/y1row/items/994ecf8b478b7aac4c7d)
参考：[MySQLのrootパスワード忘れ時のリセット対応方法](https://qiita.com/mou34/items/d9540399cdfc6e5d8140)


```bash
# MySQL を停止
sudo /etc/init.d/mysqld stop
# セーフモードで起動
./mysqld_safe --skip-grant-tables &
# rootでログイン
./mysql -uroot
```

```sql:mysql
use mysql;
/*任意のパスワードを設定*/
update user set authentication_string=PASSWORD('パスワード') where user='root';

flush privileges;
quit
```

```bash

#起動
./mysqld
```

```sql:mysql
/*起動後にステータスの確認*/
/*Current userが目的のものになっているか確認*/

mysql> status
```

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

上記がうまくいかなかった場合もあったが、こちらの方法で変更したパスワードでrootにログインできるようになった。
参考：[MySQLのrootパスワード忘れ時のリセット対応方法](https://qiita.com/mou34/items/d9540399cdfc6e5d8140)

```bash
# init-fileオプションでmysqlを起動
./mysqld --init-file=/path/to/init --user=mysql &

mysql> mySET PASSWORD FOR 'root'@'localhost' = PASSWORD('パスワード');

# ログイン
./mysql -u root -p　でパスワードを入れてログイン
```

--------------
MAMPからSQLサーバーが立ち上がらなくなることもあったがこちらで解決。

参考：[【MAMP】MySQLが起動しない場合の対処方法２つ](https://manablog.org/mamp-mysql-error/)

------



##Mediawiki編

Mediawikiを公式からダウンロード
https://www.mediawiki.org/wiki/Download

MAMPのサーバーを起動して、ダウンロードしたフォルダをhtdocsに放り込む。

アプリケーション > MAMP > htdocs > bluespice

http://localhost:8888/bluespice/ にアクセスで簡単につながる。

最初ログインできなかったので以下を参考にした。
参考：[Mediawikiを構築したのにセッションのエラーで自分でログインできないとき](https://qiita.com/onokatio/items/9e9c09b02624074f9077)

LocalSettings.phpをSublime Textなどのコードエディターで開いて、
```$wgMainCacheType = CACHE_ANYTHING;```に書き換え。

細かい設定などは手順通りに行う。



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

## おまけ：MySQLworkbenchから'ユーザー名'のユーザーにアクセスする。

MySQLworkbenchからwikiのデータベースを覗き見ることができる。
最初は繋がらなかったが、設定のポートの番号を変えたら接続できた。
mysqlにログインしてから、

```sql:mysql
mysql> show variables like 'port';
```
でポート番号を確認してから、MySQLworkbenchの設定のportに反映させた。
そういえばしれっと匿名クラス登場してたじゃんか

応プロでそういや登場してましたね。

```java
button.addActionListener(
  new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent event){
      /* ここにボタンが押されたときの処理を記述 */
    }
  }
);
```

これについて。

# 匿名クラス

**匿名クラス**って言って、その場でさっくりクラスを作成できる書き方がある。

例えば、こんなインタフェースを設計してみる。

```java:SampleInterface.java
interface SampleInterface{
    public void sampleMethod();
}
```

じゃ、コレの**匿名クラス**を生成してみる。

```java
SampleInterface sample = new SampleInterface(){
    @Override
    public void sampleMethod(){
        System.out.println("Hello :-) ");
    }
}

sample.sampleMethod();
// >>> Hello :-) 
```

こんなして使える。

やってることとしては

```java:ExampleClass.java
class ExampleClass implements SampleInterface{
    @Override
    public void sampleMethod(){
        System.out.println("Hello :-) ");
    }
}
```

```java
SampleInterface sample = new ExampleClass();
sample.sampleMethod();
// >>> Hello :-) 
```

これと同じ。
わざわざ別ファイルでインターフェースを実装したクラスを作る手間が省ける。

# 何に使う？
これを使うと、他のクラスに処理そのものをブチ込める。

```java:SampleClass.java
class SampleClass{
    private SampleInterface sampleInterface;

    public SampleClass(SampleInterface sampleInterface){
        this.sampleInterface = sampleInterface;
    }

    public void callInterfaceMethod(){
        sampleInterface.sampleMethod();
    }
}
```

```java
SampleClass sample = new SampleClass(
    new SampleInterface(){
        @Override
        public void sampleMethod(){
            System.out.println("Hellooooooo!!!! :-) ");
        }
    }
);

sample.callInterfaceMethod()
// >>> Hellooooooo!!!! :-)
```

こんな感じ。

Javaを使ったフレームワークなんかだとしょっちゅう見かける。
ボタンの処理をしているクラスを変更することなく自分のしたい処理を差し込めるから、フレームワークの便利な処理をそのままにできるってこと。
Androidでもボタン押したときにやる処理なんかはこのパターンだし。

----
以上、**リスナーパターン**ってやつのお話でした。
西暦と月を指定すると給料日が返ってくるメソッド

#用途
給料日を知りたい・給料日を元にシステムの切り替えを行うような仕組みで使いたい等

#仕様
・給料日は通常25日とする
・その日付が土曜日、日曜日、祝日であれば、該当しない日付になるよう早める
例
2018年11月25日　：　日曜日
2018年11月24日　：　土曜日
2018年11月23日　：　祝日
2018年11月22日　：　金曜日　←この日付が返ってくる

・祝日かどうかの判定は外部より参照する
https://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html

セクション『平成３１年（２０１９年）及び平成３２年（２０２０年）の「国民の祝日」』の最下部にて、実データの参照が可能。
今回はダウンロードして使うのではなく、GASが持つhttp通信（UrlFetchApp.fetch）を使って取得する。
なお、祝日の「名称」はここでは使わない。

#コーディング

```給料日.gs
function returnPayDay(seireki, month){
  var templateDate = seireki + "/" + month;
  //給料日が25日じゃないなら下記行の右端を他の値に変えてね。でも数値型にすること！
  var paymentDay = 25;
  var inputDate = templateDate + "/" + paymentDay;
  var tmpDate = new Date(inputDate);
  var holidayList = getHolidayList();
  while(tmpDate.getDay() == 0 || tmpDate.getDay() == 6 || holidayList.indexOf(inputDate) != -1){
    //逆に給料日を遅らせる場合は、下記行の「-」を「+」に変えたらできるよ
    tmpDate.setDate(tmpDate.getDate() - 1);
    inputDate = parseInt(tmpDate.getYear()) +  "/" + (parseInt(tmpDate.getMonth()) + 1) + "/" + parseInt(tmpDate.getDate());
  }
  return inputDate;
}

//祝日のデータ一式を取得するよ
//返り値の型はString配列["2018/11/23","2018/12/23","2018/12/24",・・・]
function getHolidayList(){
  var opt = {
    "method" : "GET",
    "contentType" : "plain/text;charset=shift_jis"
  };
  var holidayList = UrlFetchApp.fetch("https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv",opt);
  var text = holidayList.getContentText().split("\n");
  for(var i = 0; i < text.length; i++){
    text[i] = text[i].split(",")[0];//祝日の名称はいらん
  }
  
  return text;
}
```

#テスト結果
```test.gs
function test(){
  var salaryDay1 = returnPayDay("2019","5");
  Logger.log(salaryDay1);
  
  var salaryDay2 = returnPayDay("2018","11");
  Logger.log(salaryDay2);
}
```

↓

![qiita6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420117/dc2a9da6-5513-26c8-0c06-17548246db10.jpeg)


#終わりに
スプレッドシートで家計簿をつけている。その中で「今日の日付が給料日なら、入力データの登録先も自動で切り替わらないかな」と思ったのが始まり。
コーディングにおいては、他の言語でも（特殊な独自仕様が無ければ）汎用的に使えるはず。

#2019/10/13更新
作成当日は問題なかったけど、今は「給料日が祝日である」かつ「土曜日の前に祝日がある」ケースで誤って祝日が給料日になってしまうことが分かったよ。
【ExcelVBA】画像の挿入

# はじめに

Excel上で使われる図は、Excel上で作図されるグラフが大半だと思いますが、以下のようなケースではExcelファイル（ワークブック）から見て外部ファイルを画像として貼り付ける必要があります。

* ワークシート上の表とセットで、別のアプリで作図した図をワークシートに載せたい時。
* Excelで帳票を作成する際に、会社のロゴや社印を付けたい時。

もちろん手作業で画像を貼り付けることも可能ですが、ここではプログラムを使って画像を挿入する方法を紹介します。

# 利用する関数

> Addpicture(FileName、 linktofile、 savewithdocument、 Left、 Top、 Width、 Height)

* 上記の[AddPicture](https://docs.microsoft.com/ja-jp/office/vba/api/excel.shapes.addpicture)という関数を使うと、ワークシート上に簡単に画像を貼り付けられます。
* この関数のポイントは、**「第6/第7引数のWidthとHeightに-1を渡すと、元の画像の幅や高さが保持される」**という仕組みになっています。
 * APIを見るまでは、[こんな方法](http://officetanaka.net/excel/vba/tips/tips87.htm)で画像ファイルのサイズを事前に取得しておいて、得られた画像の幅と高さを指定しなければいけないのではと思っていました...



# サンプルコード

```vb:Module1
Option Explicit

' ワークシートに画像を挿入する。
Sub InsertImage()
    With ThisWorkbook.Worksheets("Sheet1")
        .Shapes.AddPicture "C:\Users\NKOJIMA\Desktop\cat2.png", msoFalse, msoTrue, 100, 30, -1, -1
    End With
End Sub
```

* サンプルコードを実行すると、このようにワークシート上に画像が挿入されます。

![add_picture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/039172fc-9d68-dbce-b49c-ac1debb0ae17.png)
UiPath Tips集

#個人的に使えるTips
###ショートカット
- [Ctrl] + [Alt] + F　アクティビティの検索ボックスにフォーカス

###文字コード
- 改行コード　vbCrlF、Environment.NewLine

###UiPathとは別だけど使えるTips
- バックスラッシュ含むパスでもcdできるように　→　シングルクォーテーション(')で囲む

###デスクトップのパスを関数で取得したい
- System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
Lambda関数のローカル作成方法(lambda-uploader)


サーバーレスでアプリを作っていて、日々Lambda関数を生産しています。
コンソールから作成することもできますが、コード管理が煩雑になるのと、IDEの補完機能を使いたいのとで、私はできるだけローカルで作成してからデプロイするようにしています。ただ、ローカルで作成したLambdaをデプロイするには、コードのZip化とファイルのアップロードが必要で地味に面倒です。
そういった作業をサポートしてくれるツールがあるので紹介したいと思います。
まずは手軽なやつから

# lambda-uploader
いくつか使っている中で一番手軽なツール（だとおもう）
https://github.com/rackerlabs/lambda-uploader

## インストール
```
pip install lambda-uploader
```

## プロジェクト作成

```
mkdir myFunction
```

```
cd myFunction
touch my_function.py
```

my_function.pyに所望の実装を施します。

```例：my_function.py
def lambda_handler(event, context):
    return {'hello': 'world'}

```

lambda.jsonを作成します。

```例；lambda.json
{
  "name": "myFunction",
  "description": "hello world",
  "region": "ap-northeast-1",
  "runtime": "python3.7",
  "handler": "my_function.lambda_handler",
  "role": "arn:aws:iam::00000000000:role/lambda_basic_execution",
  "requirements": ["pygithub"],
  "timeout": 30,
  "memory": 128,
}
```

外部ライブラリを利用したい場合は、lambda.jsonにrequirementsを追加します。

```
{
...snip...
  "role": "arn:aws:iam::00000000000:role/lambda_basic_execution",
  "requirements": ["requests"],
  "timeout": 30,
...snip...
}
```

（requirements.txtで指定することもできます。）



## デプロイ
lambda.jsonを作成したディレクトリで以下のコマンドを実行します。

```
lambda-uploader
```

ターミナルに次のようなメッセージが出れば無事成功。

```
Î» Building Package
Î» Uploading Package
Î» Fin
```

## その他
lambda.jsonにはアカウントに依存した情報（role）が入っています。CI/CDにlambda-uploaderを利用する場合には、lambda.jsonをDevとPrdに分けて、--configオプションで切り替えるようにすると良さそう。
ABC - 007 - A&B&C

#AtCoder ABC 007 A&B&C
[AtCoder - 007](https://atcoder.jp/contests/abc007)

過去の問題ってとっても教育的なものがあって好きかも。
C問題とか。

#A - 植木算

```java
	private void solveA() {
		int n = nextInt();

		out.println(n - 1);
	}
```

#B - 辞書式順序

 - 辞書順だけ考慮すればいいのなら、常に"a"いれればいいよね
    - 入力が"a"の場合、辞書順で"a"より小さいものはないので-1を出力

```java
	private void solveB() {
		String wk = next();

		if (wk.equals("a")) {
			out.println(-1);
		} else {
			out.println("a");
		}
	}
```

#C - 幅優先探索
 - 幅優先探索（BFS）の教育的な問題

####参考サイト

 - [01-BFSのちょっと丁寧な解説](https://betrue12.hateblo.jp/entry/2018/12/08/000020)
 - [全探索アルゴリズム入門](https://qiita.com/MasayaMizuhara/items/86099ad721a329e1d6cd)
 - [競プロ覚書：深さ優先探索，幅優先探索 まとめ](https://pyteyon.hatenablog.com/entry/2019/03/01/211133)
 - [貰う DP と配る DP、メモ化再帰、個数制限なしナップサック問題](https://qiita.com/drken/items/ace3142967c4f01d42e9#%E8%A7%A3%E6%B3%95-2-bfs)
 - [深さ優先探索と幅優先探索](https://mathtrain.jp/dfsbfs)

 参考サイトを一通り読むのが一番


```java
	private void solveC2() {
		int r = nextInt();
		int c = nextInt();
		int sX = nextInt() - 1;
		int sY = nextInt() - 1;
		int gX = nextInt() - 1;
		int gY = nextInt() - 1;

		char[][] map = new char[r][c];
		for (int i = 0; i < r; i++) {
			map[i] = next().toCharArray();
		}
		Deque<Cordinate> que = new ArrayDeque<Cordinate>();
		Cordinate start = new Cordinate();
		start.x = sX;
		start.y = sY;
		start.step = 0;
		/*
		 * Queu（LIFO）として使うのでaddLast()
		 */
		que.addLast(start);
		boolean[][] memo = new boolean[r][c];
		memo[sX][sY] = true;
		int res = bfs(map, que, r, c, gX, gY, memo);

		out.println(res);
	}

	private static class Cordinate {
		private int x;
		private int y;
		private int step;
	}

	private static final int[] vX = { 1, 0, 0, -1 };
	private static final int[] vY = { 0, 1, -1, 0 };

	private int bfs(char[][] map, Deque<Cordinate> que, int r, int c, int gX, int gY, boolean[][] memo) {

		while (!que.isEmpty()) {
			/*
			 * Queu（LIFO）として使うのでremoveFirst()
			 */
			Cordinate curr = que.removeFirst();
			if (curr != null) {
				if (curr.x == gX && curr.y == gY) {
					return curr.step;
				}
				for (int i = 0; i < 4; i++) {
					int wkX = curr.x + vX[i];
					int wkY = curr.y + vY[i];
					int step = curr.step + 1;
					if (wkX >= 0 && wkX < r && wkY >= 0 && wkY < c && map[wkX][wkY] != '#' && !memo[wkX][wkY]) {
						Cordinate newC = new Cordinate();
						newC.x = wkX;
						newC.y = wkY;
						newC.step = step;
						/*
						 * Queu（LIFO）として使うのでaddLast()
						 */
						que.addLast(newC);
						memo[wkX][wkY] = true;
					}
				}
			}
		}
		return -1;
	}
```
さくらサーバー 500 エラー

さくらサーバーで一部のCGIにエラーコード500が出る。

```error.log
AH01215: suexec policy violation: see suexec log for more details: https://~
```

これだけの情報しか吐かない上、suEXECのログも見れず、どうすりゃいいのよ。
ググっても「パーミッション755」にしろとしか書いておらず、完全にお手上げ状態。

二時間悩んだ末、CGIファイルのエンコードが**UTF-8 with BOM**だったことが判明。
BOMなしのUTF-8にしたらすんなり実行。

にゃー。（もおおおおおお貴重な時間を返してほしい！）