OmniAICreator/Qiita-1.07M huggingface dataset:
Ubuntuの共有パーティション(fat32)にあるC, C++プログラムを実行できるようにしよう

# はじめに

僕のPCではデュアルブートしていて、両OSでデータが共有できるように共有パーティションを作ってあります。  

この共有パーティションはfat32というファイルシステムですが、このファイルシステム上では権限関連の概念がないらしいです。  

したがって、C/C++の環境構築をした際にエラーが起こりました。  
([この記事内](https://qiita.com/nsd24/items/805d0b53c67a1043e819)でも言及しました。)  

本記事では、このエラーの解決方法を説明していきます。  

# 前提環境

* Ubuntu 18.04.2 LTS
* コンパイルした後のファイルを実行できる環境([この記事内](https://qiita.com/nsd24/items/805d0b53c67a1043e819)参照)

# 具体的なエラー内容

[この記事内](https://qiita.com/nsd24/items/805d0b53c67a1043e819)で、コンパイルした後のファイルの実行ができませんでした。    

```
$ gcc -o hello hello.c && ./hello
bash: ./hello: 許可がありません
$ g++ -o hello hello.cpp && ./hello
bash: ./hello: 許可がありません
```

![1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289151/850b05f9-5455-1a4e-b064-608580244a86.png)

# エラー原因

そもそも、fat32では実行権限が付与できないらしいことがわかりました。([参考サイト](https://forums.ubuntulinux.jp/viewtopic.php?id=15515))

実際にファイルの実行権限をGUIで確認してみると、以下のように付与してもリセットされてしまいました。  

![1-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289151/a78c9fbb-13c6-16ec-f98e-73bc4300588a.gif)

# 解決方法

今回は、fat32じゃないシステム上に実行ファイルを作成し、それを実行するようにします。  

以下のコマンドで、ubuntuのシステムに実行ファイルだけ保存し、それを実行するようにしています。  

```
$ gcc -o /home/nsd/ドキュメント/hello hello.c && /home/nsd/ドキュメント/hello
$ g++ -o /home/nsd/ドキュメント/hello hello.cpp && /home/nsd/ドキュメント/hello
```

しかし、毎回これをやるのは非常にめんどくさいので、シェルスクリプトを書いて任意のコマンドを実行すると一気にコンパイルから実行までしてくれるようにやってみます。  

```C.sh
#!/bin/bash
gcc -o /home/nsd/ドキュメント/c-file $1 && /home/nsd/ドキュメント/c-file
```

```C++.sh
#!/bin/bash
g++ -o /home/nsd/ドキュメント/c++-file $1 && /home/nsd/ドキュメント/c++-file
```

パスは、fat32じゃないとこならどこでもいいです。  
そして、コマンドとして実行できるようにします。  

僕はC.shとC++.shを/home/nsd/ドキュメントの直下に置きました。  

そして、このファイルをおいた場所でターミナルを開き、以下のコマンドを実行します。  

```
$ sudo cp C.sh /bin/C-command
$ sudo cp C++.sh /bin/C++-command
```

このコマンドで、C-command ファイル名, C++-command ファイル名と打つことでどこからでもC/C++のファイルがコンパイルし実行できるようになりました！(コマンド名は何でもいいので好きにつけてもらってOKです。)

![1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289151/d2694fed-ef5b-c536-7099-ffd1f17be184.png)

実際に[以前書いた記事](https://qiita.com/nsd24/items/805d0b53c67a1043e819)でのHelloWorldのプログラムを実行してみます。  

```
$ C-command hello.c

$ C++-command hello.cpp
```

![1-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289151/c50af377-bdf7-3c7b-1997-1affe6924d72.png)

これで無事、fat32上にあるC/C++プログラムのコンパイル・実行が手軽にできるようになったと思います！

※もしこれで許可がないって出たら、/binに飛んで  

```
$ sudo chmod +x C-command
$ sudo chmod +x C++-command
```

で実行権限付与してからもっかいやってみてください。  

# まとめ

この記事では、fat32上にあるC/C++プログラムを、シェルスクリプトを使って簡単にコンパイル・実行できるようにしました。  
他のコンパイラ言語でも同様のことが起きると思うので、他の言語でもまた書いていこうと思います！  

環境構築の方法自体は[この記事](https://qiita.com/nsd24/items/805d0b53c67a1043e819)で書いたので、そちらの方をチェックお願いします！

# 参考文献

* [コンパイルして実行するシェルスクリプト C,C++](https://qiita.com/koshitake2m2/items/d188d70f549ae0138a75)
* [#!/bin/sh は ただのコメントじゃないよ！ Shebangだよ！](https://qiita.com/mohira/items/566ca75d704072bcb26f)
C#(.NET Framework) の GC 対象判定について

# 要約

* 参照を保持していても GC 対象になってしまうことがある
* マネージコード上で継続的に評価していないと Release ビルドの最適化により破棄される
* C++/CLI ラッパーフレームワークなどを運用していると起きがちなので気をつけよう

# こんなケース

何がしかのグラフィクスフレームワークで、こんなアプリを作ったとします。

```cs
var viewer = new Viewer();
var shape = new Shape();

viewer.Register(shape);

while (viewer.Draw())
{
}
```

描画ループの持ち方はさておき、一見動いてくれそうに見えますが、これが GC 発動のタイミングでクラッシュすることがあります。

# 何故起きるのか

**描画ループ内で shape が一度も評価されない**ことが原因です。Release ビルドにおいては、参照が保持されていても、長時間評価されないインスタンスが GC の対象になってしまうようです。
(追記)本来は Release ビルドの判断基準が正しく、Debug ビルドが~~気を利かせて?~~寿命を延長しているがために、挙動が異なっているようです。

viewer.Register() の際に参照を握っていれば良かったのですが、実はこのフレームワークは C++/CLI によるネイティブラッパーで、内部ではネイティブコード上での登録処理しか行っていませんでした。

# 延命実験

## 1. while ループ後に GC.KeepAlive() する

```cs
while (viewer.Draw())
{
}

GC.KeepAlive(shape);
```

アドホック感丸出しですが、その名の通り生存は担保されます。
(追記)描画ループ後に評価されることがマークされれば GC 対象から外れるので、ループ内で KeepAlive する必要はありませんでした。

## 2. 適当なラッパークラスを経由して適当に評価する

```cs
class ShapeWrapper
{
    private int count;
    public Shape Shape { get; set; }
    public void Update() { ++count; }
}
```

やろうとしていることは適当に評価してごまかすことでしかないんですが、被評価判定が伝播するかどうかを確認してみます。
ちなみにカウンタのインクリメントをしているのは、ただの空関数呼び出しだと最適化の際になかったことにされるためです。~~小賢しい~~賢い。

```cs
var wrapper = new ShapeWrapper { Shape = shape };
while (viewer.Draw())
{
}

wrapper.Update();
```

これでも生存が確認できました。参照を保持しているクラスインスタンスの何かしらのメンバーが評価されていれば、破棄されることはないようです。

## 3. スコープを広げる

上記の実験により、何かしらのメンバが評価されていれば OK ということがわかりました。ならば、クラスのフィールドにしておけば、わざわざ生存を保障する必要もないのではないでしょうか。

```cs
class App
{
    Viewer viewer = new Viewer();
    Shape shape = new Shape();
    void Run()
    {
        this.viewer.Register(this.shape);
        while (this.viewer.Draw())
        {
        }
    }
}

---

{
    var app = new App();
    app.Run();
}
```

コードにしてみれば一目瞭然ですが、フィールドを評価するには this を経由する必要がありますし、何よりメソッド呼び出し自体が this の評価の真っ最中ということになるので、各メンバーが勝手に破棄される恐れはなくなります。ローカル変数で長寿命のインスタンスを扱っていたこと自体が良くなかったのかもしれません。

# ベストプラクティスは

色々検証はしてみたものの、そもそも利用者側にこんな気遣いをさせるようではフレームワークとして良い状態ではありません。ネイティブコード上での参照保持関係は、マネージコード上でも同じように保持するべきでした。そのようにしましょう。
letter-spacingで文字間をつけたときに文字位置がずれるときの対処法


letter-spacingは文字間を調整するCSSプロパティで文字の後ろのスペースを調整します。
そのため、値分の文字の後ろにできたスペースのせいでずれてるように見えることがあります。
文字の折返しで揃えているとき、文字を中央寄せしたときなどに気になる部分で意外と困りますよね？

```HTML
<div>
  <p>あいうえお<strong>かきくけこ</strong>さしすせそ</p>  
</div>
```

```CSS
div {
    letter-spacing: 1em;
}
```

[デモはこちら](https://codepen.io/ShimokawaChan/pen/qGWYgq)

#テキストが右寄せ、左寄せ

子要素のインライン要素にネガティブマージンをかけます。

```CSS
div p {
  margin-right: -1em;
}
```

[デモはこちら](https://codepen.io/ShimokawaChan/pen/joNxdJ)

#テキストが中央寄せ(1行のみ)

letter-spacingと同じ値をtext-indentで指定します。

```CSS
 div {
  letter-spacing: 1em;
  text-indent: 1em;
 }
```

[デモはこちら](https://codepen.io/ShimokawaChan/pen/rgBvRa)

#テキストが中央寄せ(複数行)

右寄せ、左寄せと同様に子要素のインライン要素にネガティブマージンをかけます。

```CSS
div p {
  margin-right: -1em;
}
```

[デモはこちら](https://codepen.io/ShimokawaChan/pen/QRLrRo)
モデルに定義するメソッド、ヘルパーに定義するメソッドの違い

#はじめに
タイトル通り、モデルに定義するメソッド、ヘルパーに定義するメソッドの違いがいまいち分からなくなったのでまとめておきます。
##モデルに定義するメソッド
極力各モデルの責務部分は各モデルに任せ、コントローラーは指示を出すだけにする


```ruby:例
# モデル
class User < ApplicationRecord
  def admin?
    admin_status == true
  end
end

# コントローラー
class UsersController < ApplicationController
  def hoge
    @user = User.find_by(id: params[:id])
    @user.admin?
  end
end
```
関係のあるモデルにクラスメソッドやインスタンスメソッドを書くこと。
##ヘルパーに定義するメソッド
ヘルパーは全ビューで共通であるためメソッド名の衝突に注意する必要がある。
下の例はトピックの作成日の表示を簡易的なものにしている。
クラスメソッド`User.find_by`やインスタンスメソッド`user.admin?`のように前に何もつけなくてもそのまま使える。

```ruby:例
# application_helper
module ApplicationHelper
  def simple_time(time)
    time.strftime("%Y-%m-%d %H:%M ")
  end
end

# topics_controller
class TopicsController < ApplicationController
  def index
    @topics = Topic.all
  end
end
```

```erb
<!-- index.html -->
<div>
  <% @topics.each do |topic| %>
    トピック作成日<%= simple_time(topic.created_at) %>
  <% end %>
</div>
```
##参考文献

https://high-programmer.com/2018/11/23/ruby-on-rails-helper-usecase/

http://rails3try.blogspot.com/2011/12/blog-post_17.html
Linuxで複数のwavファイルをmp3へ一括変換する

# とりあえず結論

変換対象のwavファイルたちが存在するディレクトリで以下のコマンドを実行。

```shell

$ for targetfile in *.wav; do lame -b 320 "$targetfile"; done
```
※ @korogi3235 さんのコメントを受け一部修正(2020/1/18)

# 解説

見ての通り、for文でLAME(mp3エンコーダー)をぶん回しているだけです。
カレントディレクトリ内の全wavファイルに対して以下のコマンドを実行しているというわけです。

```shell
$ lame -b 320 hoge.wav
```

特に難しいこともないですが、2点だけ補足します。

###### 1. LAMEのインストール
当然ですが、LAMEがインストールされていないと実行できません。
インストール済か分からない場合は、以下のコマンドを実行して確認します。

```shell

$ lame --version
```

バージョンやらコピーライトが表示されたらインストール済、そうでない場合はインストールしましょう。
インストールは、各ディストリビューションの方法に則ってください。
Debian系ならば以下のコマンド。

```shell
$ sudo apt-get install lame
```

###### 2. オプションの指定

エンコード設定をオプションで指定できます。
冒頭のコマンドだと、`-b 320`がエンコード設定のオプションです。
これは固定ビットレート320kbpsでのエンコードを指定しています。いわゆる最高音質です。最強の設定。
変換後のファイルサイズの大きさが気にならない場合は、基本的にこのオプションで問題ないでしょう。

ファイルサイズを小さくしたい場合は可変ビットレートモードを使用しましょう。
大文字Vのあとに0~9の数字を指定します。数字が小さいほど高音質です。
高音質が良ければ`-V0`、音質をあまり重視しないのであれば携帯用の`-V4`や`-V6`を指定します。

# 参考にしたページ
[最新LAME コマンドライン指南 - 音風景ブログ](https://kamedo2.hatenablog.jp/entry/20111027/1319720601)
[エンコードオプション - Lame@wiki](https://www9.atwiki.jp/lameaintmp3encoder/pages/12.html)
Android の Camera2 API を使って カメラのプレビュー画面を表示する


### 概要

Android　5.0　Lollipop から カメラ制御のAPI が Camera2 API に変わり、
従来の「android.hardware.camera」は 廃止予定 (Deprecated) になった。

下記の公式サンプルが公開されているが。
コールバックが多用されており、読み解くのは大変です。

[How to use basic functionalities of Camera2 API](https://github.com/googlesamples/android-Camera2Basic/tree/master/Application/src/main/java/com/example/android/camera2basic)


下記のような解説記事も出てますが、すんなり理解できず。

[Android カメラアプリを作ろう　その３ プレビュー方法まとめ]
(https://qiita.com/Shiratori/items/8dfc0d9e996ee3844abe)

プレビュー画面を簡単に表示する方法はないかと、試行錯誤している人も多いのでは。
下記のように、Vision API を使う例もある。

[Mobile Vision API を使ってカメラ映像を表示する](https://qiita.com/niusounds/items/c20a0a90263df77a766e)

### Camera2Source

Vision API のソースから、必要なところを抜き出せば、汎用的なものが作れると思ったが。ソースが見つからず。
その代わりに、似たようなものを自作しているのを見つけた。

[Basic functionalities of both Camera1 API and Camera2 API with a Google Vision Face Detector added](https://github.com/EzequielAdrianM/Camera2Vision)

これを参考に、プレビュー画面を表示するクラス Camera2Base と、それを継承して写真を撮るクラスCamera2Source を作った。

サンプルコードをgithub に公開した。
https://github.com/ohwada/Android_Samples/tree/master/Camera27

![camera27_preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64075/ceba490f-80a6-d0f9-0bbd-b4788c26e10f.png)

### 関連記事

- [Camera2 API を使って カメラの機能一覧を取得する](
https://qiita.com/ohwada/items/63021abbccb7d71e0370)

- [Camera2 API を使って 写真を撮る](https://qiita.com/ohwada/items/9943deb61b8883b12aac)
- - [Camera2 API  を使って 動画を撮影する](https://qiita.com/ohwada/items/4ef112bf6758ceed46c3)
- [Camera2 API と SoundPool を使って シャッター音を鳴らす](https://qiita.com/ohwada/items/1b8ff549e31dc56e071a)
- [Camera2 API を使って オートフォーカスする](https://qiita.com/ohwada/items/d33cd9c90abf3ec01f9e)
- [Camera2 API を使って RAW モードで撮影する](https://qiita.com/ohwada/items/cd1e82f926ccd6bf9d5a)
- [Camera2 API を使って ズームする](https://qiita.com/ohwada/items/13c0d81b5b674474adbf)
- [Camera2 API と LocationManager を使って 位置情報付きの写真を撮る](https://qiita.com/ohwada/items/c7d824669372b9d1e212)
- [Camera2 API を使って マニュアルモードで撮影する](https://qiita.com/ohwada/items/10fa71120cf4b9e793c3)
- [Camera2 API を使って バーストモードで撮影する]
(https://qiita.com/ohwada/items/08c6022ddd276f59eeac)
- [Camera2 API を使って Webカメラにする](https://qiita.com/ohwada/items/fe78617c9c9b5650077b)
-[Camera2 API と MediaCodec を使って カメラの画像をH264形式で転送する](https://qiita.com/ohwada/items/dd69fdd5297e042d237d)
-  [Camera2 API と MediaCodec を使って カメラの画像を RTSP で配信する](https://qiita.com/ohwada/items/9698c3b7e426b3e66996)
- [Camera2 API を使って Color Effect する](https://qiita.com/ohwada/items/6b4bb3dbd2794b58f228)

- [Camera2 API を使って 顔検出する](https://qiita.com/ohwada/items/94105a7ea134ab4d2734)
- [Camera2 API と　Mobile Vision API を使って 顔検出する](https://qiita.com/ohwada/items/f66dcf14295d9e7c0bf5)
- [Camera2 API と　Mobile Vision API を使って バーコードを検出する]
(https://qiita.com/ohwada/items/7caf29e1acc28b96042b)
- [Camera2 API と　Mobile Vision API を使って 文字列を検出する]
(https://qiita.com/ohwada/items/7a09420b4838b4df7a12)
- [Camera2 API と　Mobile Vision API を使って 顔とバーコードを一緒に検出する](https://qiita.com/ohwada/items/4040095de92c399cf001)
Alibaba Cloud の仮想サーバECSをバックアップする

# Alibaba Cloud の仮想サーバECSをバックアップする

## ECSの隠れたメリット？
ECSの隠れた？メリットの1つは、ディスクのスナップショット作成機能が**『2019/04時点での日本リージョンでは』無料で提供されている**ことだと思います。

本来は有償のバックアップ機能（1ディスクにつき最大64個のスナップショット）が、**今は**タダで使えます。
検証時などは細かくスナップショットを取得したいですし、その費用が気にならないのはお得感があります。

## ECSをバックアップする手段
ECSのディスクをバックアップしておく方法はいくつかあります。
・スナップショットを作成
・バックアップツールで、別契約のクラウドディスクをバックアップ先に設定
・カスタムイメージを作成しておく

スナップショットはサーバ稼働中にも取得でき、自動取得の設定もできるため簡単ですから、お勧めです。

## スナップショットの仕組み
スナップショットはドキュメントでは「増分方式」と記載される、前のスナップショットからの増分（差分データ）のみが取得される方式が取られます。
一連のスナップショット（スナップショットチェーン）では、過去にコピー済みのデータはそれ以降のスナップショットでも参照されるため、単なる前回のスナップショットとの差分バックアップをする方法と比べ、効率が良いものとなっています。
詳細はドキュメントセンターの説明を参照してください。
[増分方式スナップショットのメカニズム](https://jp.alibabacloud.com/help/doc-detail/25392.htm)

## 良い点
・サーバなどが動作中でも取得が可能、私の環境では問題なく取れている
処理が遅延する等の注意事項はあります。
・各ディスクには最大 64 個のスナップショットを取得できる
スナップショットのクォータは、各ディスク毎に最大 64 個のスナップショットとなっています。
そこまで取得したことはありませんが、記載の通りですと、自動と手動を合わせて64回バックアップできます。

## スナップショットの取得方法（手動の場合）
1） プロダクト ＞ Elastic Compute Service を選択
![AF6E63DF-DA9A-4764-B6EC-1468A574CEA4.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/41ade65f-f207-d689-f26b-0030cdca7cbc.jpeg)
2） ブロックストレージ ＞ クラウドディスク を選択
![1C494C4F-2C18-456C-82FB-71D06616F8C9.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/d3e62afb-497b-14b3-2c8f-b1f98e77ff36.jpeg)
3） スナップショットを作成したいディスクの「スナップショットの作成」をクリック
![154E95A7-5DC6-4608-968E-709E5B45AF38.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/bc6e2b6a-e9a3-497f-1b0b-18050e1775ca.jpeg)
4） スナップショット名を記載し、OKボタンを押すと開始されます
![C08F1BDE-9BCE-4B5D-BAC8-38561AAC9FDB.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/0b1d8069-f190-53a2-f7b6-aa3e0976a7e9.jpeg)
5） スナップショットリストのステータスや進行度が更新されます
![3D6E88A3-687C-43B3-A170-3EFB8A3372EF.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/a41ce52a-b0c3-147c-4be5-34fdbc4a79e3.jpeg)

## スナップショットの取得方法（自動の場合）
画面の出し方と注意点だけ記載します。
1） プロダクト ＞ Elastic Compute Service を選択
![AF6E63DF-DA9A-4764-B6EC-1468A574CEA4.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/41ade65f-f207-d689-f26b-0030cdca7cbc.jpeg)
2） スナップショット＆イメージ ＞ 自動スナップショット を選択
![029FC13C-FCE1-40A1-82A3-FB580A609B83.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/3899656d-c32f-3734-dfb8-45fe5abe9dfb.jpeg)
3） ポリシーを作成 ボタンを押す
![FCA58569-8DD7-445B-B823-C7FF6F0E8F07.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/1c224b3e-269e-577e-4200-79fd27f42ead.jpeg)
4） 自動スナップショットのポリシーを設定する
![1C69D99E-0602-4749-B93C-A7A48A980CDC.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273559/d6f4abb4-78d5-49c7-3fbb-6d98d678472c.jpeg)

**注意**
作成時刻で設定する時刻は**UTC8（北京など、中国時間）**です。
日本（UTC9）の時刻で設定したい場合は、作成したい時刻＋1時間の設定にしておく必要があります。


## 参照元
[ドキュメントセンター > Elastic Compute Service > スナップショット](https://jp.alibabacloud.com/help/doc-detail/25391.htm)
macOSのVirtual BoxでWindows10を動かす時の備忘録

# はじめに（謝意）
いろいろなページを拝見しながら、バラバラに集めた情報を備忘録としてまとめました（自分用）
本来であれば出典を記載すべきだと思いますが、分からなくなってしまったところが殆どですので、ご容赦ください

# 前提（使用環境）
* **macOS** Mojave
* **VirtualBox** 5.2.26

# 確認事項いろいろ
## USBを使いたい
1. Extension Packをダウンロードする
　- 5.2系のダウンロードサイト：
　　[https://www.virtualbox.org/wiki/Download_Old_Builds_5_2](https://www.virtualbox.org/wiki/Download_Old_Builds_5_2)

1. Extension Packをインストールする
 - **VirtualBox**と**Extension Pack**のバージョン値が同じでないと機能しないです（ここでハマりました）
 - ダウンロードファイルのダブルクリックしてだとうまくいかなかったです<br>
   ダウンロードファイルは以下の手順でインストールしました<br>
　  設定　＞ 拡張機能　＞ 新しいパッケージを追加（＋アイコン）

1. USB機器を登録する
　- 対象とするUSB機器を接続します（物理的に接続）
　- 認識されたUSB機器をイジェクト等で（論理的に）取り外します（物理的には接続したまま）
　- USB機器の登録情報を編集します
icon moonで好きなアイコンをWEBフォント化する


WEBサイトを作成する際にオリジナルアイコンを使用したWEBデザインを見かけることがありますよね？

今までは画像で書き出していたのですが、BootstrapのようにWEBフォントでアイコン使えたら便利じゃね？ということに気づき、調べてみたところicon moonというサービスが便利なので備忘録として紹介していきます。

#必要な素材

icon moonでWEBフォントを作成するにはSVG素材が必要です。Freeのアイコンを使用するか、Illustratorを使ってSVG素材を書き出します。

アイコンのサイズは指定は特にないのですが、小さすぎるとアイコンが表示されないみたいでだめっぽいので128px×128pxくらいは必要だと思います。

アイコンの色は黒を選択してください。

##フリーのアイコンなら以下がおすすめ

フラットアイコンなら
[FLAT ICON DESIGN](http://flat-icon-design.com/)

シンプルモノトーンなら
[ICOOON MONO](http://icooon-mono.com/)

バリエーションなら
[iconmonstr](https://iconmonstr.com/)

##IllustratorからSVGを作成する方法

こちらに詳しく説明されてます。

[【決定版】イラストデータをIllustratorでSVGに(アートボード通りに)書き出す方法。
](https://www.linustock.com/article/voice/svg2018)

#icon moonにインポート

こちらにアクセスしてください。
https://icomoon.io/app/#/select

###1.Import Icons ボタンをクリックしてください。

###2.SVGファイルをアップロードしてください。(複数可)

###3.ウィンドウ下のGenerate Fontのボタンをクリックします。

###4.ダウンロードがはじまるのでそのファイルを解凍します。

###5.回答したフォントファイルとstyle.cssをHTMLで読み込みます。

###6.style.cssで指定しているclass名をHTML上に記述することでWEBフォントのようにアイコンを使用することができます。

#アイコンをWEBフォントにするメリット

・レスポンシブによる画像劣化等の問題が発生しづらい(SVG素材自体の解像度が低い場合はぼやけます、、、)

・画像変更や色などもしやすく管理しやすい

・サイズ調整もしやすく、アイコン付近のテキストとアイコンを合わせやすい

#参考

[icomoonで好きなアイコンを追加する手順
](https://qiita.com/masarufuruya/items/862a943b6de6ebf2ab4f)
node.jsでtypescriptを扱う

#概要
node.jsでtypescriptを扱うための手順をまとめました

#開発環境
- masOS Mojave 10.14.3
- Typescript
- node v10.14.2
- npm 6.9.0

#環境構築

まず作業ディレクトリを作って移動

```
mkdir typescript-node
cd typescript-node
```

次にpackage.jsonファイルの作成

```
npm init -y
```

続いてtypescriptをインストール

```
npm i --save-dev typescript
```


--save-devはモジュールのインストール場所を指定している(ここではdevDependencies)

次にNode.jsの型定義ファイルをインストール
これでNode.js標準のモジュールを扱えるようになる(fsなど)

```
npm i --save @types/node
```

次に```package.json```を次のように書き換える
npm scriptsにbuildとwatchを設定する

```:package.json
{
  "scripts": {
    "build": "tsc",
    "watch": "tsc --watch"
  },
  "devDependencies": {
    "typescript": "^3.4.5"
  },
  "dependencies": {
    "@types/node": "^12.0.0"
  }
}
```

次にプロジェクトディレクトリ直下に```tsconfig.json```ファイルを作成する
TypeScriptコンパイラの設定を行う

```:tsconfig.json
{
    "compilerOptions": {
      "module": "commonjs",
      "target": "es6",
      "sourceMap": true,
      "types" : ["node"]
    },
    "include": [
        "src/**/*"
    ],
    "exclude": [
      "node_modules"
    ]
}
```
includeでsrcディレクトリ以下をコンパイルするよう設定している
excludeでnode_modulesをコンパイル対象外に指定している

srcディレクトリの下に```app.ts```ファイルを作成

```
mkdir src
touch app.ts
```

app.tsファイルを書く

```
console.log('hogehoge');
```

package.jsonがあるディレクトリに移動して以下を実行

```
npm run build
```

すると```app.js```ファイルがコンパイル結果として出てくるので実行してみる

```
node src/app
```

hogehogeがコンソール上に無事表示される
完。
AWS Cloud9 × Wordpress

Cloud9 × S3 × Wordpress × StaticPressでできるだけ費用抑えたいと思い実施
サーバーをGCEの無料版にするとS3の数10円 ? くらいで済みそうだけど少し時間掛かりそうだったのでEC2の方

## Cloud9作成
- 東京リージョン
- Create a new instance for environment (EC2)
- t2.micro (1 GiB RAM + 1 vCPU)
- After 30 minutes (Default)

## awsコンソールからElastic IP紐付け
- EC2を選択
- Elastic IP > 新しいアドレスの割り当て
- 対象のIPチェック
- アクション > アドレスの関連付け

## セキュリティグループ設定
- セキュリティグループ
- 対象のグループチェック
- インバウンド > 編集
カスタムTCP 8080 0.0.0.0/0

## wordpressセットアップ
```
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
sudo service mysqld start

mysql -u root -e "CREATE DATABASE wordpress;"

awk '{ sub(/database_name_here/, "wordpress"); sub(/username_here/, "root"); sub(/password_here/, ""); print }' wordpress/wp-config-sample.php > wordpress/wp-config.php

sudo sed -ie '151d' /etc/httpd/conf/httpd.conf
sudo sed -ie '151i \    AllowOverride All' /etc/httpd/conf/httpd.conf

sudo sed -ie '131d' /etc/httpd/conf/httpd.conf
sudo sed -ie '131i <Directory "/home/ec2-user/environment">' /etc/httpd/conf/httpd.conf

sudo chown -R apache /var/www
sudo chgrp -R apache /var/www
sudo chmod 2775 /var/www
find /var/www -type d -exec sudo chmod 2775 {} \;
find /var/www -type f -exec sudo chmod 0664 {} \;
sudo service httpd restart
```

## サーバー起動
Run > Run With > PHP (built-in web server)
http://0.0.0.0:8080/wordpress
以降Runで起動

## 参考URL
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/security-group-rules-reference.html
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/hosting-wordpress.html
https://blog.simmon.design/aws-cloud9-tutorial-new-instance/

## 雑感
AWSのサービスになってから少し面倒になってた。
[Monaca] kintoneからFetch APIで取得した画像を、アプリ内に表示させる

# 方法

今回はkintoneに保存されている画像をMonacaアプリ内に表示してみます。

```main.js
fetch(`https://omj-f.cybozu.com/k/v1/file.json?fileKey=${fileKey}`, {
    headers: {
        'x-cybozu-api-token': token
    }
})
    .then(response => response.blob())
    .then(blob => {
        $scope.imgPath = (window.URL || window.webkitURL).createObjectURL(blob)
    })
    .catch(error => console.error(error.stack));
```

また、このままではCSPのエラーが出てしまいますので、`index.html`に以下の`meta`タグを追加する必要があります。

```index.html
<meta http-equiv="Content-Security-Policy"
          content="default-src * data: gap: https://ssl.gstatic.com; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'; img-src * blob:; media-src *">
```

追加したのは、`img-src * blob:; media-src *`の部分ですね。

あとは`img`タグのsrc属性にバインディングするようにすればOKです。

```html
<img ng-src="{{imgPath}}">
```

# 参考

- https://qiita.com/tronperidot/items/8adff1e953b4c251ac94
- https://www.yoheim.net/blog.php?q=20180901
Terraformでterraform_remote_stateが参照できない


## これは何？
Terraformでモジュール化する際に、terraform_remote_stateに書き込まれている変数を読めずにハマったので残しておきます。

## 環境
Terraform v0.11.10
provider.aws v2.7.0


## 何が問題だったのか

terraformはmain.tfのoutputをterraform_remote_stateに書き出します。
moduleの中でoutputしておけば勝手にmoduleに書き出してくれて、それを他のmoduleから参照できると思っていたことが間違いでした。
moduleを参照した先（ここで言うところのmain.tf)と同じ場所にoutput.tfを作りapplyすると、terraform_remote_stateに書き出してくれます。


こういうディレクトリ構成で、

```
.
├── main.tf
├── modules
│   └── vpc
│       ├── README.md
│       ├── output.tf
│       ├── variable.tf
│       └── vpc.tf
└── provider.tf
```

こういう実装をしているとします。

```
## main.tf
module "vpc" {
  source = "./modules/vpc"
}

output "sample" {
  value = "${data.terraform_remote_state.state.vpc_id}"
}
```

```
## modules/vpc/vpc.tf
resource "aws_vpc" "vpc" {
  cidr_block           = "10.0.0.0/16"

  tags {
    Environment = "${terraform.workspace}"
  }
}

output "vpc_id" {
  value       = "${aws_vpc.vpc.id}"
}
```

modules/vpc/vpc.tfでoutputに出力したvpc_idをterraform_remote_stateに書き込み、それを別の場所から参照したい。
これを実行すれば、terraform_remote_stateに書き込んでくれると思っていました。が、実際は書き込まれません。以下のようなエラーを受け取ります。

```
$ terraform apply
data.terraform_remote_state.state: Refreshing state...
data.terraform_remote_state.state: Refreshing state...

Error: Error running plan: 1 error(s) occurred:

* output.sample: Resource 'data.terraform_remote_state.state' does not have attribute 'vpc_id' for variable 'data.terraform_remote_state.state.vpc_id'
```


terraform_remote_stateに書き込むためには、moduleを参照した先（ここで言うところのmain.tf)と同じ場所にoutput.tfを作る必要があります。

```
.
├── main.tf
├── output.tf  ## このファイルを追加
├── modules
│   └── vpc
│       ├── README.md
│       ├── output.tf
│       ├── variable.tf
│       └── vpc.tf
└── provider.tf
```

```
## output.tf
output "vpc_cidr_block" {
  value       = "${module.vpc.vpc_cidr_block}"  ## ここではmoduleのoutputを指定する。
}
```

この状態でapplyするとterraform_remote_stateが書き込まれ、参照することが出来ます。

以上についてのドキュメントは以下に書かれています。
https://www.terraform.io/docs/providers/terraform/d/remote_state.html#root-outputs-only

```
Only the root-level outputs from the remote state are accessible. 
Outputs from modules within the state cannot be accessed. 
If you want a module output or a resource attribute to be accessible via a remote state, you must thread the output through to a root output.
```

結構長い時間ハマっていたので、同じような誰かの助けになれば幸いです。
Bteq概要

Teradataの日本語情報があんまりないので、
連休中にドキュメント読んだ内容をまとめようと思います

まずはBteq概要
ドキュメントは[こちら](https://docs.teradata.com/reader/jmAxXLdiDu6NiyjT6hhk7g/2a19OMPypUtVBfwXtnIEtA)

ところどころピックアップなのと、動作確認しているわけではないので解釈違いがあるかも…

> Each command must be preceded by a period '.' otherwise BTEQ will assume that it is an SQL request and submit it to the Teradata Database.
.始まりの場合はコマンドとして認識され、それ以外はSQLリクエストとしてTeradataデータベースに送信される

```
.HELP BTEQ
.LOGON mydbs/myid;
.SET SIDETITLES ON; .SET FOLDLINE ON ALL
SELECT DATE;
```
この場合最初3行はBteqコマンド。3行目については2つのコマンドを含んでいる状態になる。
4行目は.始まりじゃないので、SQLリクエストステップになる

> Constructing an instruction with a mix of commands and an SQL request is not supported. Furthermore, there are some commands which either must be the only step in an instruction or must be a last step. For example, the LOGON and OS commands can only be a last step within a multistep instruction.

コマンドとSQLを組み合わせるのは不可
※多分selectの結果を使ってコマンド実行とかはできないってことだと思う
さらに命令群中に1つだけしか実行できないものや、最終ステップでないといけないコマンドもある
例えばLOGONとOSコマンドは最終ステップでなければいけない
※最後の行がいまいちわからなかった…
logonは最初のステップでないといけない or logoutは最終ステップでなければいけない、ではなくだろうか…
英語力に自信なくてわからないけど、そういうのがあるっていうのはわかるのでいったん置いておく

> A trailing semicolon should be used on every step. Although it is optional for a last command step, it is generally required for an SQL request. The only exception is when a semicolon is omitted for an SQL request submitted in batch mode as the last instruction of a script.

どのステップでも文末のセミコロンは必要
最終コマンドステップは任意だが、一般的にSQLリクエストでは必要

```
* 通常、コマンドは基本的に最終になるのでいらないと思われる
.HELP BTEQ
.LOGON mydbs/myid
```

バッチモードで起動したときの最終命令部に限ってはセミコロンの省略が可能

```
* バッチモードの場合、コマンドのセミコロンは必要
.SET SIDETITLES ON;
.SET FOLDLINE ON ALL;

* クエリも最後じゃない場合は必要
SELECT DATE;

* 最後のクエリだけはセミコロンを省略できる 
SELECT DATE
```
文末のセミコロンは基本つける。最後のコマンドやバッチモードのクエリの場合は不要
(だけど場合に応じて外すとかはちょっと面倒なので、基本的に付けるようにしようと思う)

> Command input may also be provided to BTEQ by using the SQL ECHO statement either directly or as part of an executed SQL macro. For example:

```
ECHO '.HELP BTEQ';
```
ECHO コマンド で表示できるよってことらしいけど、使いどころはわからない…

複数のコマンドを1行で書く場合の利点については、一応以下のような記述があって
> Fewer trips are needed to accomplish ECHO-ing of BTEQ commands. Depending on use case, this could boost performance.
Fewer batch mode result blocks will be created making the resulting stdout/SYSPRINT file smaller. This may also make those results easier to read.

パフォーマンスの向上に寄与する可能性がある、ということらしい
[Python]dictのKeyErrorを排除する

dictのkeyを指定して値を読み出すとき、存在しないkey値を指定するとKeyErrorが発生するため、以下のようにエラー処理を入れていました。

```python:python
>>> num_dict = {1: "one", 2: "two", 3: "three"}

>>> def get_english_number(num):
...    try:
...        english_number = num_dict[num]
...    except KeyError:
...        english_number = "辞書にない数字です"
...    return english_number

>>> get_english_number(1)
'one'

>>> get_english_number(4)
'辞書にない数字です'
```

dictのget()関数を使うことでエラー処理を排除することができます。

```python:エラー処理を排除
>>> num_dict = {1: "one", 2: "two", 3: "three"}

>>> def get_english_number(num):
...    english_number = num_dict.get(num, "辞書にない数字です")
...    return english_number

>>> get_english_number(1)
'one'

>>> get_english_number(4)
'辞書にない数字です'
```

存在しないkeyを指定した場合get()関数の第二引数の値が返されます。

エラー処理を入れるよりコードが少しすっきりしたと思います。
Alexa Skill Kit for Pythonで、リクエストハンドラ共通の処理をさせる

# はじめに
AlexaのPythonのSDKででスキルを開発する際、以下のような状況に出くわすことがあります。

 - ワンショット対応のため、最初に呼ばれるリクエストハンドラを特定できない
 - 起動時に実行すべき処理がある。例えばDnyamoDBからの永続アトリビュートの取得とセッションアトリビュートへの格納など

最初に呼ばれるリクエストハンドラが決まっているのであれば、そのハンドラに起動時に必要な処理を記述すればよいです。
しかし決まっていない場合、最初に呼ばれる可能性のある全てのハンドラに、起動時必要な処理を記述すべきなのでしょうか。

---
# 解決策
AbstractRequestInterceptorを継承したクラスを用意し、そのprocess関数に処理を記述します。
すると、その処理はどのリクエストハンドラが呼び出されても、そのハンドラの最初に実行されます。
そのため、各リクエストハンドラに逐一処理を書かなくてよくなります。

---
# コード（関連部分のみ）

例えばこのように書くと、どのリクエストハンドラから呼び出された場合でも、セッションアトリビュートの有無を確認し、なければ設定します。

なお、SDKではハンドラやインターセプターの記述について、以下の二つがあります。ここでは前者を採っています。

 - クラスとして記述する方法
 - 関数として記述する方法

```python:anynameok.py
# AbstractRequestInterceptorをインポート
from ask_sdk_core.dispatch_components import AbstractRequestInterceptor

# AbstractRequestInterceptorを継承したクラス
class AnyNameInterceptor(AbstractRequestInterceptor):
    """リクエストインターセプター。各ハンドラの実行時に呼び出される"""

    def process(self, handler_input):
        """各ハンドラで共通して実行させたい処理を記述

        ここでは、セッションアトリビュートの有無を確認し、なければ関数get_s_attrで取得
        """
        if not handler_input.attributes_manager.session_attributes:
            handler_input.attributes_manager.session_attributes = get_s_attr(handler_input)

# StandardSkillBuilderへの登録
# ここではsbはStandardSkillBuilder
sb.add_global_request_interceptor(AnyNameInterceptor())
```
関数get_s_attrは自作です。コードは割愛しています。
最後の、StandardSkillBuilderへのインターセプターの追加は忘れがちです。

---
# 修正履歴
 - 19/05/04　15:45
  - この投稿のタイトルを「Alexa Skill開発用PythonのSDKの一機能であるリクエストインターセプターの使途」から変更。
  - 「コード」より前の記述の観点を、コードの使途からニーズとその解決策に変更。
  - コードの解説を追記

---
# 参考URL

**公式ドキュメント**
Alexa Skills Kit SDK for Python-JA / リクエスト処理 / リクエストと応答のインターセプター / リクエストインターセプター
https://alexa-skills-kit-python-sdk.readthedocs.io/ja/latest/REQUEST_PROCESSING.html?highlight=AbstractRequestInterceptor#id10
あたりまえですが、理解してから読むとなるほどと思います。
ー初心者でも分かるーJavascriptの正規表現とは

# **Javascriptの正規表現の概要と使い方** 

**1.そもそも正規表現とは何か**

　正規表現とは、文字列にある特定の文字を取り除く操作や、特定の文字が入力されていることを確認するための技術です。

 ex)あるHPでフォームに電話番号を入力する時
　課題：「000-1234-1234」「00012341234」と電話番号を入力する際にハイフンの要不要が分からなくなる
　問題：この違いによって、データベースでの管理などが煩雑になる
　対策：上記の場合に、「-(ハイフン)」を取り除いたりすることでフォーマットを統一する必要がある

　こういった場合に使うのが、正規表現です。

**2.正規表現を使うケース**

これは大きく分けると3種類あります。

 - 文字列の一部分を置き換えたい
　　電話番号の例のように、ハイフンを取り除きたい場合などです。

 - 文字列が規定を満たしているか確認する
　　例えばパスワードが8文字以上になっているかを調べる時などです。

 - 文字列の抽出をする
　　例えば、メールアドレスを入力した際に、ドメインを取り出したい場合などです。

**3.正規表現を実現するためのメソッド**

 - replaceメソッド

　「アリクイのいる動物園」を「シマウマのいる動物園」に変えたいとします。

   `var str = 'アリクイのいる動物園'
　  str.replace(/アリクイ/, 'シマウマ');
　  =>'シマウマのいる動物園'`

　第1引数に置換したい文字列を、第2引数に置換後の文字列を指定します。

 - matchメソッド

   「マッコウクジラのいる水族館」という文字列に「マッコウクジラ」という文字列が入っているか調べます。

 `var str = "マッコウクジラのいる水族館"
　str.match(/マッコウクジラ/)
　=>["マッコウクジラ"]`

　このように、文字列が含まれている場合は、文字列を返します。
　含まれていない場合の返り値はnullです。
Leetcode #67: Add Binary

```swift
func addBinary(_ a: String, _ b: String) -> String {
    var aArr = Array(a).map { Int(String($0))!}
    var bArr = Array(b).map { Int(String($0))!}
    if a.count < b.count {
        aArr = Array(repeating: 0, count: b.count - a.count) + aArr
    } else if b.count < a.count {
        bArr = Array(repeating: 0, count: a.count - b.count) + bArr
    }
    aArr = aArr.reversed()
    bArr = bArr.reversed()
    var answer = [Int]()
    var carry = 0
    for (index, num) in aArr.enumerated() {
        answer += [(num + bArr[index] + carry) % 2]
        carry = (num + bArr[index] + carry) / 2
    }
    if carry != 0 {
        answer += [carry]
    }
    return answer.reversed().map {String($0)}.joined(separator: "")
}
```
pryでRubyVM::AbstractSyntaxTree.ofを使って雑にASTを取る

TL;DR
-----

`~/.pryrc`に以下を足すだけでOK

```rb
unless defined?(SCRIPT_LINES__)
  SCRIPT_LINES__ = {}
end

Pry.config.hooks.add_hook(:before_eval, :"ast<3") do |code, _pry|
  SCRIPT_LINES__["(pry)"] = code.lines
  code
end
```

例
--

```
% pry
[1] pry(main)> RubyVM::AbstractSyntaxTree.of(-> { puts :hi })
=> (SCOPE@1:32-1:45
 tbl: []
 args:
   (ARGS@1:32-1:32
    pre_num: 0
    pre_init: nil
    opt: nil
    first_post: nil
    post_num: 0
    post_init: nil
    rest: nil
    kw: nil
    kwrest: nil
    block: nil)
 body: (FCALL@1:35-1:43 :puts (ARRAY@1:40-1:43 (LIT@1:40-1:43 :hi) nil)))
[2] pry(main)>
```

eval上書きではだめなのはなぜ
-------------------------

結論から言うとrubyには数々のeval属があってpryが使っているのはBinding#eval。
なのでKernel#evalを上書きしても動かない。

神速さんのエントリを読んだ。


> byebugやpryもevalを使っているだろうし、evalを上書きすれば他も簡単に対応できる....と思っていた。 世の中はそんなに甘くなかった。
https://sinsoku.hatenablog.com/entry/2019/05/04/032007

これはすごい! evalだけ書き換えればよいとかなりべんりじゃん、マーベラス!と思って一応eval上書きも試したがうまく動かなかった。

```rb
      def pry_eval(*eval_strs)
        b =
          if eval_strs.first.is_a?(String)
            Pry.toplevel_binding
          else
            Pry.binding_for(eval_strs.shift)
          end
        pry_tester(b).eval(*eval_strs)
      end
```
https://github.com/pry/pry/blob/69dd1a14bde6b02d24509c446e7b83b2807f8ef2/lib/pry/testable/evalable.rb#L11-L19

一応動かなかった実装例をあげておきます。
こうしてCで実装されているメソッドにパッチを当てておくとc_callじゃなくcallイベントで取れるようになる。
targetで指定できるようになるしbindingからローカル変数取れるようになってべんり。
戻り値を書き換えるときにも使えてべんりで詳しくは過去記事参照されたし。
https://qiita.com/hanachin_/items/d5e243048900344b2146

```rb
unless defined?(SCRIPT_LINES__)
  SCRIPT_LINES__ = {}
end

eval_patch = Module.new do
  def eval(string, binding = nil, filename = nil, lineno = nil)
    super
  end
end

Kernel.prepend(eval_patch)

ast_happier = TracePoint.new(:call) do |tp|
  filename = tp.binding.local_variable_get(:filename)

  next unless filename
  next if File.exist?(filename)

  SCRIPT_LINES__[filename] = tp.binding.local_variable_get(:string)
end
ast_happier.enable(target: eval_patch.instance_method(:eval))
```

ならば`Binding#eval`上書きだ!
---------------------------

byebugとかだと`byebug -r ast.rb foo.rb`みたいな感じで`-r`オプションで読み込ませておいてあげるとうまく動く

```ast.rb
unless defined?(SCRIPT_LINES__)
  SCRIPT_LINES__ = {}
end

eval_patch = Module.new do
  def eval(string, filename = nil, lineno = nil)
    SCRIPT_LINES__[filename] = string.lines
    super
  end
end

Binding.prepend(eval_patch)
```

pryの場合
--------

ところで`pry`にはモンキーパチらなくていいbefore_eval hookがあるのだった

https://github.com/pry/pry/wiki/Hooks#Hooks_before_eval_event

参考
----

- [RubyVM::AbstractSyntaxTree\.ofをevalやirbで動かすために調べたこと \- アジャイルSEの憂鬱](https://sinsoku.hatenablog.com/entry/2019/05/04/032007)
- [irbでRubyVM::AbstractSyntaxTree.ofを使って雑にASTを取る](https://qiita.com/hanachin_/items/bfd1dd0cf278e6f2d7b9)
S2Daoの埋め込み変数に気をつける

今更EOLしたS2Daoについてです。
業務で利用しているのですが、使い方を誤ると危険なのでメモしておきます。

## 埋め込み変数

S2Daoでは埋め込み変数というものが用意されています。
こちら使い方を誤ると大変危険な挙動になるのでメモとして残しておきます。

### 埋め込み変数の使い方

埋め込み変数は以下のように記述します。

>/\*$引数名*/リテラル


### 実際のコード

```java:BalanceDao
@S2Dao(bean = Balance.class)
public interface BalanceDao {
    @Sql("select id, name, amount, created_at, updated_at from balance where name = '/*$name*/'田中''")
    public List<Balance> findByName(String name);
}
```

### 動かしてみます

```shell:curl
$ curl -G "localhost:8080/sastruts/balance/findname" --data-urlencode "name=田中太郎"
id:1name:田中太郎created_ad:2019-05-03 19:25:33.0updated_ad:null
```

```shell:実行時ログ
DEBUG 2019-05-04 12:51:36,087 [http-nio-8080-exec-5] select id, name, amount, created_at, updated_at from balance where name = '田中太郎'
```

このように /*$name*/ で設定した部分（埋め込み変数）が置き換えられてSQLが実行されることがわかります。


## SQLインジェクション

では埋め込み変数の何が危険なのかというと、SQL部分が引数の内容でそのまま置き換えられてしまうため、SQLインジェクションの危険があるということです。

試してみます。

### SQLインジェクションしてみる

```shell:curl
$ curl -G "localhost:8080/sastruts/balance/findname" --data-urlencode "name=A'or'A'='A"
id:1name:田中太郎created_ad:2019-05-03 19:25:33.0updated_ad:null
id:2name:佐藤花子created_ad:2019-05-03 23:48:40.0updated_ad:null
```

```shell:実行時ログ
DEBUG 2019-05-04 12:54:57,636 [http-nio-8080-exec-6] select id, name, amount, created_at, updated_at from balance where name = 'A'or'A'='A'
```

このように全てのデータが取得できてしまいます。

## 対策

2つ対応方法があると思っています。

* バインド変数コメントを利用する
* Daoの呼び出し側でSQLインジェクション対策を行う


基本的にはバインド変数コメントを利用する方が良いと思います。

使い方は簡単です。
以下の指定をするだけです。
>/\*引数名*/リテラル

### バインド変数の使用例
```java:BalanceDao
@Sql("select id, name, amount, created_at, updated_at from balance where name = /*name*/'田中'")
public List<Balance> findByName(String name);
```

SQLインジェクションを試してみます。

```shell:何も返却されない
$ curl -G "localhost:8080/sastruts/balance/findname" --data-urlencode "name=A'or'A'='A"
$
```

```shell:実行時ログ
DEBUG 2019-05-04 13:01:31,270 [http-nio-8080-exec-3] select id, name, amount, created_at, updated_at from balance where name = 'A'or'A'='A'
```

実行ログ上ではSQLインジェクションに成功しているように見えますが、実際には何も返却されませんでした。

## 参考
[S2Daoリファレンス](http://s2dao.seasar.org/ja/s2dao.html)
PythonでCSVのIPアドレスリストを取り込み国名を付与する

# はじめに
アクセスログをみてアクセス元の国名を調べることがあります。
アクセスログはCSVで出力されているので、今まではそれを見てIPアドレスを [Cisco TALOS](https://www.talosintelligence.com/) や Linux の「geoiplookup」コマンドで手打ちして調べていました。流石にそれは効率が悪すぎるのでCSVファイルを取り込み自動で全部調べて国名を付与してまたCSVファイルをして出力する Python プログラムを作りました。

# 環境と準備作業
## 環境について
Winodws 10 Pro + Visual Studio Code で実施しました。
python のバージョンは Python 3.6.1 です。

## geoip2 モジュールのインストール
Python でIPアドレスから国名を調べようとすると geoip2 がインストールする必要があります。「pip install geoip2」コマンドを実行する必要がありますが Windows でも環境変数に python のパスが通っていればこのコマンドが動きます。PowerShell のコンソールを立ち上げてコマンドを打ったら無事 geoip2 のインストールができました。
![powershell2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160914/5d02f055-a4fe-6eb0-0f60-0ef14e50649f.png)

## GeoLite2 データベースのダウンロード
MAXMIND 社のサイトから IPアドレスのデータをダウンロードしてきます。
[GeoLite2 Free Downloadable Databases](https://dev.maxmind.com/geoip/geoip2/geolite2/)

「GeoLite2 Country」の「MaxMind DB binary, gzipped」をダウンロード、解凍して Python スクリプトがあるフォルダに置きます。tar.gz ファイルは Windows の標準の解凍ツールでは解凍できないので 7zip を使用しました。

# CSV ファイルについて
下記のようなタイトル行の無い「日時」「アクセス元IPアドレス」の2列のみで構成された CSV ファイルを想定しています。

```iplist.csv
2018/1/1 0:00,1.1.1.1
2018/2/1 0:00,2.1.1.1
2018/3/1 0:00,3.1.1.1
2018/4/1 0:00,4.1.1.1
2018/5/1 0:00,5.1.1.1
2018/6/1 0:00,6.1.1.1
2018/7/1 0:00,7.1.1.1
2018/8/1 0:00,8.1.1.1
2018/9/1 0:00,9.1.1.1
```

# IPアドレスの国名を求めるスクリプト
まず IPアドレスから国名を求める関数を作成します。ソースの CSV ファイルを取り込み1行ずつこの関数を実行して、結果を付加して CSV ファイルとして出力します。


```python:geoiplookup
## モジュールの読み込み
import geoip2.database
import csv


## GeoIPデータベースとCSVファイルのパス設定
geoip_db_path = "GeoLite2-Country_20190430/GeoLite2-Country.mmdb"
source_file_path = "iplist.csv" 
result_file_path = "result.csv"


## IPアドレスから国名を求める関数
def ipaddrlookup(ipaddress):
    reader = geoip2.database.Reader(geoip_db_path)
    response = reader.country(ipaddress)
    countoryname = response.country.names["en"]
    return countoryname


## IPアドレスリストの取り込み
source_file = open(source_file_path, encoding = "ansi") 
source_reader = csv.reader(source_file)
source_list = list(source_reader)


## 出力ファイルをオープン
result_file = open(result_file_path, "w", newline="")
result_writer = csv.writer(result_file)


## 取り込んだCSVファイルのIPアドレスから国名を求める
for row in source_list:
    outputdata = [row[0]]
    outputdata.append(row[1])
    outputdata.append(ipaddrlookup(row[1]))
    result_writer.writerow(outputdata)


## 出力ファイルをクローズ
result_file.close()
```


# 出力される CSV ファイル
下記のように「日時」「アクセス元IPアドレス」列の後に「アクセス元国名」の列が付加された CSV ファイルが出力されます。

```result.csv
2018/1/1 0:00,1.1.1.1,Australia
2018/2/1 0:00,2.1.1.1,France
2018/3/1 0:00,3.1.1.1,Singapore
2018/4/1 0:00,4.1.1.1,United States
2018/5/1 0:00,5.1.1.1,Ukraine
2018/6/1 0:00,6.1.1.1,United States
2018/7/1 0:00,7.1.1.1,United States
2018/8/1 0:00,8.1.1.1,United States
2018/9/1 0:00,9.1.1.1,United States
```

# 参考情報
## 参考サイト
[GeoLite2でサクッとできるIPアドレスの国判定](https://dev.classmethod.jp/cloud/aws/geolite2-python/)
[windows10でpipが使えるようになるまで(python3.6)](https://qiita.com/huushihi/items/c7f578bf51c0017c9076)

## 参考書籍
[退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング](https://amzn.to/2J0NCiq)
[実践力を身につける Pythonの教科書](https://amzn.to/2JmLFMD)
Homebrew 基本コマンドまとめ

Homebrew ユーザーなのでよく利用する基本的なものをまとめてみました。
Homebrew とは Mac(or Linux)向けのパッケージ管理ソフトのこと。
パスを通してるならすぐ使えます。


##基本的な利用方法
パッケージのインストール

```
$ brew install パッケージ名
```

アンインストール

```
$ brew uninstall パッケージ名
```

Homebrewを最新版にする

```
$ brew update
```

インストール済みのパッケージを更新

```
$ brew upgrade
```

パッケージの古いバージョンを削除

```
$ brew clearnup
```

インストールしたパッケージの確認

```
$ brew list
```

パッケージの探し方

```
$ brew search パッケージ名
```

## Homebrewユーザーの留意点
インストールしたパッケージをupgradeしても実は旧バージョンのパッケージは削除されないんです。
なのでHomebrewユーザーは定期的に旧パッケージの削除をしないとだんだん容量が圧迫されていきます。

1. Homebrewの更新
2. パッケージの更新
3. 旧版パッケージの削除をする (古いバージョン、新しいバージョンを使い分ける必要があるならやらない用が良さげ。)

を以下のように定期的に行うとよいでしょう。

```
$ brew update
$ brew upgrade
$ brew cleanup ## 古いバージョン、新しいバージョンを使い分ける必要があるならやらない用が良さげ。
```

## cacheやダウンロード時のzipフォルダを消したい。
> /Users/xxx/Library/Caches/Homebrew 以下にある。

cacheとダウンロードフォルダを削除

```
brew cleanup -s
```

formulae、casks関連のモノは残ったままなので、それごと消したい場合は以下のコマンドだけでOK

```
rm -rf "$(brew --cache)
```

##自動起動の設定
例えば、brew でインストールした PostgreSQL がOS起動時に立ち上がるように設定してみます。

```
$ brew services start postgresql
==> Successfully started 'postgresql' (label: homebrew.mxcl.postgresql)
```

以下のコマンドでstartedと表示されたアプリが自動で起動しています。

```
$ brew services list
Name       Status  User   Plist
mysql      stopped
postgresql started /Users/xxx/Library/LaunchAgents/homebrew.mxcl.mysql.plist

```

＊自動起動を停止、再起動する場合は以下のコマンド

```
$ brew services stop パッケージ名
$ brew services restart パッケージ名
```
Leetcode #96: Plus One

```swift
func plusOne(_ digits: [Int]) -> [Int] {
    var answer = [Int]()
    var carry = 0
    for num in digits.reversed() {
        answer += [(num + carry) % 10]
        carry = (num + carry) / 10
    }
    if carry != 0 {
        answer += [carry]
    }
    return answer.reversed()
}
```
Leetcode #97: Interleaving String

Use dynamic programming, otherwise get TLE

```swift
func isInterleave(_ s1: String, _ s2: String, _ s3: String) -> Bool {
    if s1.count + s2.count != s3.count {
        return false
    }
    if s1.isEmpty {
        return s2 == s3
    }
    if s2.isEmpty {
        return s1 == s3
    }
    let str1 = Array(s1)
    let str2 = Array(s2)
    let str3 = Array(s3)
    var dp = Array(repeating: Array(repeating: true, count: s1.count+1), count: s2.count+1)
    for i in 1...s1.count {
        dp[0][i] = dp[0][i-1] && (str1[i-1] == str3[i-1])
    }
    for i in 1...s2.count {
        dp[i][0] = dp[i-1][0] && (str2[i-1] == str3[i-1])
    }
    for i in 1...s1.count {
        for j in 1...s2.count {
            dp[j][i] = ((str3[i+j-1] == str1[i-1]) && dp[j][i-1]) ||
                ((str3[i+j-1] == str2[j-1]) && dp[j-1][i])
        }
    }
    return dp[s2.count][s1.count]
}
```
bike informatics

知人にバイク乗りが結構いる。

出身大学で、bike informatics研究をしている人がいる。
http://kitanilab.org

自動車の機能安全規格の国際会議に参加した時に、
「４輪以上の自動車と二輪とは一緒に議論できない」という意見と、
「バス、トラックも別に議論したい」という意見を、イタリアなどの自動車メーカの方から意見を伺った。

二輪の安全、四輪の安全、バス・トラックの安全は、分類して議論するとよいと思い、それぞれ分析中。

知人のバイク乗りに、bike informatics研究をゆっくり紹介するため、バイク関連のQiita記事を整理。

自分では２年ほど、外回りの仕事をしていた時に、共有の50ccバイクで街中を乗り回していたことがある。
普段は自転車、どちらも二輪(bike).

詳しいことはわかっていない。耳寄りな情報、記事の誤引用がありましたら、おしらせくださると幸いです。

移動通信が主研究であり、移動体としての二輪も貴重。大切にしたい。

#Qiita記事
ケチサイエンティストへの道〜Python3で自分のバイクの最適給油タイミングを求めよう〜 ①『自分の給油行動をモデリングしてみた』
https://qiita.com/YukihiroNISHIYAMA/items/2ed5154ee23260a603ee

ケチサイエンティストへの道〜Python3で自分のバイクの最適給油タイミングを求めよう〜 ②『シンプルな戦略でトータルコストの削減を狙おう』
https://qiita.com/YukihiroNISHIYAMA/items/1e209d6d6971ae6159f1

ケチサイエンティストへの道〜Python3で自分のバイクの最適給油タイミングを求めよう〜 ③『最適停止問題（結婚問題）を応用し，最適給油タイミングを求める』
https://qiita.com/YukihiroNISHIYAMA/items/a773cd0ca80b29ad16fe


バイク用ウインカーポジションを作ろう
https://qiita.com/KeKe115/items/1d371782fd0d3f9f412d

VFoundationやCoreLocationを利用したバイク用のスピードメーター兼簡易ドライブレコーダー
https://qiita.com/kazz12211/items/25e4e8efc6eba6ae7ea7


YOLOv3+pythonで車載動画中のバイクを認識し動画にする
https://qiita.com/zeze/items/18ae8e4ccb1eed9c979c


[画像認識]画像分類、画像検出、セマンティックセグメンテーション
https://qiita.com/YosukeHoshi/items/833c1f662a57e72d4d43

pythonで物体の自動検出→トリミング→リサイズまで
https://qiita.com/Yu-Nie/items/924cdadf9923d4af78a3


VRサイクリング「THE TRIP」＠渋谷 体験レポート
https://qiita.com/peroon/items/878f41f5f9e99a790db7

SpriteKitでiOS7/8で動作が異なっていたところ
https://qiita.com/HIkaruSato/items/4629d7f99ac3da238510

M5Stack+Nintendo Laboのバイクキット(ダンボールのみ)でWHILL Model CRを走らせてみた
https://qiita.com/s-katsu/items/3bd7e7a04bd96e23213f

stravaでロードバイクの偏差値を計算してみた
https://qiita.com/nati-ueno/items/a820339edb259f579ef6

# 文書履歴(document history)
ver. 0.01 初稿 20190504
ver. 0.02 URL追記　20230214

### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
curlの使い方色々

curlコマンドの使い方を色々とまとめていきます。

## 全角パラメータをGETメソッドで送る

GETメソッドでリクエストをする際に、URLの中のリクエストパラメータに全角文字を入れると怒られてしまって動かないことがあります。

```shell:
$ curl "localhost:8080/sastruts/balance/findname?name=田中太郎"

<!doctype html><html lang="ja"><head><title>HTTPステータス 400 – Bad Request</title><style type="text/css">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTPステータス 400 – Bad Request</h1><hr class="line" /><p><b>タイプ</b> 例外報告</p><p><b>メッセージ</b> リクエストの宛先に不正な文字が含まれています。利用可能な文字は RFC 7230 および RFC 3986 に定義されています。</p><p><b>説明</b> サーバは、クライアントエラー（例えば、不正なリクエスト構文、無効なリクエストメッセージフレーミング、または不正なリクエストルーティング）であると考えられるために、リクエストを処理できない、または処理しません。</p><p><b>例外</b></p><pre>java.lang.IllegalArgumentException: リクエストの宛先に不正な文字が含まれています。利用可能な文字は RFC 7230 および RFC 3986 に定義されています。
```

「--data-urlencode」を利用することでURLエンコードをしてくれます。

```shell
$ curl -G "localhost:8080/sastruts/balance/findname" --data-urlencode "name=田中太郎"

id:1name:田中太郎created_ad:2019-05-03 19:25:33.0updated_ad:null
```


## リクエストボディにjson入れる
```shell:
curl -v -X POST "localhost:8080/api/example" -d "{\"firstName\":\"太郎\",\"lastName\":\"田中\"}"
```

## リクエストボディにjsonファイルを入れる
```shell:
curl -v -X POST "localhost:8080/api/example" -d @test.json -H "Content-Type: application/json"
```

```shell:test.json
{
  "firstName": "太郎",
  "lastName": "田中"
}
```

## HTTPヘッダーを出力する
`-i`オプションを利用することでHTTPヘッダーが出力されます。

```console:
$ curl -i localhost:3000
HTTP/1.1 200 OK
Set-Cookie: last_access=1583929785944;
Content-Type: text/plain
Date: Wed, 11 Mar 2020 12:29:45 GMT
Connection: keep-alive
Transfer-Encoding: chunked

Hello World
```

## クッキーをセットしてリクエストする
クッキーをセットする場合は、`-H`でヘッダーに`Cookie`を指定するだけです。

```console:
$ curl -i -H 'Cookie: last_access=1583929785944' localhost:3000
```
Unity の uGUI のみで複数のタッチ入力を無視する方法

(検証環境: Unity 2019.1.0f2/Android 9)


## tl;dr

- https://gist.github.com/furukazu/163285d3181ebf3862d7800c15da09fa

## 概要

`Input.multiTouchEnabled` を `false` にすれば Unity 全体で無効にできるのですが uGUI でだけその機能を使いたくないときに非常に不便なので uGUI でのみ無効にする方法を考えてみました。

## やりかた

1. 複数のタッチ入力を無効にしたいコンポーネントを派生したクラスを作る。例えば `public class MyButton : UnitySystem.UI.Button` のようにする。
2. 1 で作ったクラスから `UnityEngine.EventSystems.PointerEventData` を受け取るメソッドを `override` して `eventData.pointerId` が 0 以外であればその場で return させる。 0 であれば親の処理を呼び出す。例えば `base.OnPointerDown(eventData);`　のように。
3. Button の代わりに 2 で作ったスクリプトを使う。すでに Button を貼り付けている場合は インスペクタを Normal から Debug に切り替えることにより Script を直接差し替えることができるので、それで変更すると、すでに設定してあるプロパティを消すことなく移行できる。


### 実装例

- https://gist.github.com/furukazu/163285d3181ebf3862d7800c15da09fa

## 他に考えたこと

おそらく EventSystem そのものに手を加えていけば uGUI のコンポーネントを改造することなくシングルタッチ環境を構成できると思うのですが、そこまで書き換えることが現実的でないと思ったので、コンポーネントに手を加える戦略を採用しました。
JavaScript 引数がnullなDateオブジェクト

jsのdateの引数にnullが来た時、うざいのでちょっとまとめてみました。 

## jsのDateの挙動
引数に何も渡さなければ現在のDateが返ってきます。

```js
new Date()
// Sat May 04 2019 11:28:52 GMT+0900 (日本標準時)
```
じゃあ、nullを引数に渡したら何もかえってこないな！！と思っていると...

```js
new Date(null)
// Thu Jan 01 1970 09:00:00 GMT+0900 (日本標準時)
```

ふざけんなよと数々の犠牲になった人々の声が聞こえます。

## nullの時、表示しないようにしたいなら
Dateの引数にnullがきた時は値を返さない解決策のひとつとしてNumber()にキャストしてやります。

```js
const nullDate = new Date(null)
Number(nullDate)
// 0
const currentDate = new Date()
Number(currentDate)
// 1556937299876
```

```js
const jsNullDate = new Date(null)
Number(jsNullDate)
// 0
```

条件文で０（falsyな値）となるのでこのときに値を返さないようにif文や三項演算子など利用すればいいでしょう。


解決策その２としてそもそもnullが返ってくるとわかった段階でnew Dateに値を渡す処理を止めるなどしたほうがシンプルで良いかと思います。
devise メール認証

#はじめに
deviseを使ったメール認証の設定について書いていきます。

#設定ファイルの編集

###送信者のメールアドレス指定

```config/initializers/devise.rb
Devise.setup do |config|
省略..

config.mailer_sender = "info~@~.com"
end
```

**config.mailer_sender**はdevise.rbにデフォルトで設定されているのでこちらを適宜変更。

変更なしの場合、

```
config.mailer_sender = 'from@example.com'
```

が設定されている。

###SMTP環境の設定

メールを送信するには追加でSMTPの設定が必要となる。

Gmailを使用する場合はメールアドレスとパスワードも必要。

以下のようにdevelopment.rbを編集する。

```config/environments/development.rb
Rails.application.configure do
  # default url
  config.action_mailer.default_url_options = {  host: 'localhost', port: 3000 }
  # mail setting
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    :address => "smtp.gmail.com",
    :port => 587,
    :user_name => "Gメールアドレス",
    :password => "Gメールパスワード",
    :authentication => :plain,
    :enable_starttls_auto => true
  }
end
```

2段階認証をかけている場合、以下参照
https://qiita.com/cigalecigales/items/f4274088f20832252374

##参考
https://qiita.com/cigalecigales/items/f4274088f20832252374
https://qiita.com/shizuma/items/c8c2e71af8c1dcf3d1c2
https://easyramble.com/devise-setup-config-mailer-sender.html
個々の文字ごとの文字詰めについて(プロポーショナルメトリクスの対策)


#きっかけ

こちらの記事に大変お世話になっているのですが、個々の文字ごとの文字詰め部分の対処法について自分なりに補足していきます。

[もし、HTMLのテキスト周りでデザイナーからこんなお願いをされたら...](https://qiita.com/ryosukemaehira/items/3af1196b9947dec79ed5)

↑めちゃめちゃ細かい部分まで書かれていて勉強になります。


##font-feature-settingsはブラウザやフォントによっては使えない。。。

記事内に紹介されている文字詰めの対応方法でfont-feature-settingsが書かれているのですが、とても便利なプロパティではあるのですがブラウザやフォントによっては使えないことがあります。

オープンタイプフォント(.otf)であれば、プロポーショナルメトリクスが搭載されているのでfont-feature-settingsを使用することができます。

とはいえ、案件ごとに毎回otfを用意できないときもありますし、大変ですよね？？

#「jQuery.Kerning.js」でクロスブラウザ対応する

そこで紹介したいのが「jQuery.Kerning.js」です。

プラグインはこちら
→http://karappo.github.io/jquery.kerning.js/

詳しい詳細はこちら
→[[JS]日本語のどんなWebフォントでも美しくカーニングできるスクリプト -jQuery.Kerning.js](https://coliss.com/articles/build-websites/operation/javascript/jquery-plugin-kerning-for-japanese.html)

##ざっくり

・指定した要素内の設定された特定のテキストごとにspanタグで囲い、いい感じに文字詰めしてくれます。

・使用する際は文字ごとのカーニングが設定されたjsonを読み込む必要があります。デフォルトのjsonだと全角約物のカーニングのみが適用されるようになっています。ぜんぜんこれでも問題なく使えます！！
(※現在さまざまなフォントで利用できるよう自動的にデータを生成するツールを開発中とのことです。)

##CSSでデフォルトでspan周りのスタイリングをしている際には注意！！

spanタグで文字が囲まれてしまうのでデフォルトで任意のスタイルをspanに当ててる場合は注意してくださいね！！
JupyterやColabのマジックコマンドに対してセル内で定義した変数を引数として与える

すごーーーーーーく下らないけど忘れそうだからQiitaにメモしておく


# どういうシチュエーションのことを言っているのか？

JupyterやColaboratoryをいじっているとたまに`%%`や`!`でマジックコマンドを実行したくなる時がある

しかもJupyter内で定義した変数を引数として渡したい時がある

今まではあまりなにも考えずに文字列をそのまま打ち込んでいたけど、shellのお作法にしたがって`$`をつければセルで定義した変数名の中に入っているオブジェクトをそのまま認識してくれることを今更知った

今更知って結構恥ずかしい

# アンチパターン

```python:チンパンジー的対処方法
# 無理やりファイル名を直で文字列として渡す！！
!python main.py --input_dir="/pathx/file.txt"
```

```python
# 別パターン
%%gcs list --objects "gs://mypath"
```
# 良さげパターン

```python:ホモ・サピエンス的対処方法
inputpath = "/pathx/file.txt"

!python main.py --input_dir=$inputpath
```

```python
# 別パターン
gs_path = "gs://mypath"
%%gcs list --objects $gs_path
```

画面イメージも一応記載

![スクリーンショット 2019-05-04 11.40.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55225/7d1a74f5-3370-2554-71af-b1e6582f6b2b.png)

やっぱり、しょうもないな。。。この記事

おしまい