OmniAICreator/Qiita-1.07M huggingface dataset:
Sass(SCSS)で使用出来る@mixinについて

#始めに
作成した個人アプリをリファクタリングする際Sassの機能の一つ@mixinを使用したのでその使用方法について説明します。

#`@mixin`(ミックスイン)とは？
定義したスタイルを別のスタイルに`@include`を使用して何度も呼び出す事が可能になるというものです。
よく使うスタイルを`@mixin`で定義しておけばどこからでも`@include`を使用すれば呼び出せるので、コードが見易くなり、メンテナンスもしやすくなります。

#記述方法
先ずは基本的な使用方法から`@mixin`の後にクラス名を定義して使用します。
その後使用したいファイルに`@include`を使用して定義します。

```ruby:mixin.scss
@mixin white {
  color: white;
  font-size: 2rem;
}
```

```ruby:test.scss
.test{
  @include white;
  float: left;
}


実際の中身
.test {
  color: white;
  font-size: 2rem;
  float: left;
}
```

後はパーシャルファイルを読み込むのを忘れないよう`@import`をファイル内に記述します。

```ruby:application.scss
  @import "modules/mixin";
  @import "test";
```
#引数を使用した方法
引数を使用した方法の場合は`$引数名`を()内に定義して使用します。

```ruby:mixin.scss
@mixin centerwhite($size) {
  color: white;
  text-align: center;
  font-size: $size;
}
```
この様に定義する事で今回の場合はサイズ指定をする事が出来るようになります。
使用方法はクラス名の後の()の中に指定します。

```ruby:test.scss
.test {
  @include centerwhite(2rem);
  float: left;
}

実際の中身
.test {
  color: white;
  text-align: center;
  font-size: 2rem;
  float: left;
}
```
#２つ以上の引数の場合
()内に複数`$引数名`を使用する事で複数指定する事も可能になります。

```ruby:mixin.scss
@mixin colorstyle($color,$size) {
  color: $color;
  font-size: $size;
}
```

```ruby:test.scss
.test {
  @include colorstyle(white,2rem);
  float: left;
}

実際の中身
.test {
  color: white;
  font-size: 2rem;
  float: left;
}
```

この様に複数指定すれば、色やサイズなどの指定が容易に出来、メンテナンスもしやすくなる為、便利だと思います。

#最後に
以上基本的な`@mixin`の使用方法でした。この他にも色々応用的な使用方法もありますので、今後使いこなせる様になれたらと思います。
以下、参考にさせて頂いた資料です。
https://www.webcreatorbox.com/tech/sass-mixin
Source Han Code JPをUbuntuにインストールしてデフォルトフォントに設定する

参考サイトのやつを一通りやってみたが，エラーで止まったので，
otf作るまでの最速の方法を調べた．
addSVGtable.py'が削除されていたので，使用しない方向で．
必要な場合は、[source-han-code-jpのgithub](https://github.com/adobe-fonts/source-han-code-jp)に記載されているリンクから入手できる．
シェル環境はbashだが，zshでもかまわない．

また，gnome-terminalのPreferencesのカスタムフォント一覧にインストールしたフォントが表示されない事件も発生したので，対処法を載せる．

# バージョン
- Ubuntu 18.04.3 LTS (Bionic Beaver)
- Python 3.6.8
- GNU bash 4.4.20

# 実行手順

```bash:afdkoをpipにインストール
$ sudo apt-get install git
$ git clone https://github.com/adobe-type-tools/afdko/
$ git clone https://github.com/adobe-fonts/source-han-code-jp

$ cd afdko

# パッケージなどのインストール
$ sudo apt-get install gcc-multilib g++-multilib
$ sudo aptitude install python-pip
$ sudo pip install fonttools
$ sudo apt-get install python3-venv

# python3.6でafdkoするための環境を作成
$ python3 -m venv afdko_env
$ source afdko_env/bin/activate
$ pip install wheel
$ pip install afdko

# パス
$ echo "export PATH=xxx/afdko/afdko_env/bin:$PATH"　>> ~/.bashrc
# ライブラリのパスは不要かも．．．
$ echo "export $ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxx/afdko/afdko_env/lib" >> ~/.bashrc
```

# addSVGtable.pyに関する項目のコメントアウト

```bash:source-han-code-jp/commands.sh
#!/bin/sh
(略)

    #if addSVGtable.py -s $svg ${nf} ; then :
    #else
    #    echo #rror
    #    exit
    #fi
    #if addSVGtable.py -s $svg ${inf} ; then :
    #else
    #    echo #rror
    #    exit
    #fi

(略)
done
```

```bash:source-han-code-jpのotf作成
ターミナルを開き直す
$ cd source-han-code-jp
$ ./commands.sh
$ mkdir ~/.fonts
$ ls ./*/*.otf　# 作成されたかチェック
$ cp ./*/*.otf ~/.fonts/
$ sudo fc-cache -fv
```

```bash:確認
$ fc-list | grep Han

Bold,   ExtraLight,   Heavy,
Medium,   Normal,   ExtraLight,
BoldIt, ExtraLightIt, HeavyIt, 
MediumIt, NormalIt, ExtraLightIt,
のotfが登録されているはず
```
# フォントの設定

[Ubuntu 18.04 LTSをインストールした直後に行う設定 & インストールするソフト](https://sicklylife.jp/ubuntu/1804/settings.html#font_change)の「フォントを変更(追加)する」より，以下3つを実行．

- otfファイルを~/.fontsにコピー
- naiutilsで.fonts/SourceHanCodeJPをクリックしてインストール
- tweakのインストール
    - フォントの種類は「源ノ角 code jp ... 」

# 参考

- [Source Han Code JP(源ノ角ゴシック)をEmacs on Ubuntuに導入する](http://msyksphinz.hatenablog.com/entry/2017/03/04/020000)
- [Source Han Sans / 源ノ角ゴシック をビルドする]
(http://sadah.hatenablog.com/entry/2014/07/24/221254)
- [フォントをインストールするには - Ubuntu Japanese Wiki](https://wiki.ubuntulinux.jp/UbuntuTips/Desktop/InstallFont)
マウスストーカーをPure JavaScriptで実装する

## 結果
<p class="codepen" data-height="601" data-theme-id="0" data-default-tab="css,result" data-user="loki__codepen" data-slug-hash="OJLwMJV" style="height: 601px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Cool UI - Mouse Chaser 01">
  <span>See the Pen <a href="https://codepen.io/loki__codepen/pen/OJLwMJV/">
  Cool UI - Mouse Chaser 01</a> by Loki (<a href="https://codepen.io/loki__codepen">@loki__codepen</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 追従するマウスカーソルについて
ここ最近、マウスカーソルに装飾をするサイトが増えてきている気がします。
自作するのは面倒なので、多くの制作者は以下のサイトのコードをコピーすることも多いでしょう。

> イケてるマウスカーソルを簡単に実装する | 株式会社 エヴォワークス -EVOWORX-
> https://www.evoworx.co.jp/blog/mouse-stoker-gsap/

jQueryを利用して書かれています。
Webサイトの制作であればjQueryを利用しない機会はあまりないと思いますが、記述をPure JavaScriptに調整したものを作成しましたので、共有いたします。

## ソースコード
```javascript

const 
  cursor = document.getElementById('js-cursor'),
  chaser = document.getElementById('js-chaser'),
  target = document.querySelector('a');
let
    delay = 10,
    cursorPosX = 0,
    cursorPosY = 0,
    chaserPosX = 0,
    chaserPosY = 0;

// カーソルの遅延アニメーション
TweenMax.to({}, .001, {
    repeat: -1,
    onRepeat: function() {
        chaserPosX += (cursorPosX - chaserPosX) / delay;
        chaserPosY += (cursorPosY - chaserPosY) / delay;
        
        TweenMax.set(cursor, {
            css: {
                left: cursorPosX - (cursor.clientWidth / 2),
                top: cursorPosY - (cursor.clientWidth / 2)
            }
        });

        TweenMax.set(chaser, {
            css: {
                left: chaserPosX - (chaser.clientWidth / 2),
                top: chaserPosY - (chaser.clientWidth / 2)
            }
        });
    }
});

// マウス座標を取得
document.onmousemove = function(event) {
    cursorPosX = event.pageX;
    cursorPosY = event.pageY;
};

// マウスオーバー時の処理
target.onmouseover = function() {
    cursor.classList.add('is-active');
    chaser.classList.add('is-active');
};

// マウスアウト時の処理
target.onmouseout = function() {
    cursor.classList.remove('is-active');
    chaser.classList.remove('is-active');
};
```

## その他に調整した点
以下の点を修正しております。
- セレクタ名を`.cursor`から`#js-cursor`に変更
- セレクタ名を`.follower`から`#js-chaser`に変更
- `cWidth `や`fWidth`など、JavaScript側でもサイズを入力する必要があった値を、CSSのみで認識するように変更

## さいごに
マウスカーソルの視認性が良くなるので、個人的には好きな実装です！
十数年前の流行りが回帰していますが、アニメーション系のライブラリと合わさって現代バージョンとして流行っていることがなんだか面白いですね。
やりすぎには注意（笑）

---
Twitterのフォロワーを募集しております！
すでにWeb業界にいらっしゃる方や、業界未経験の方、どんな方でも募集しておりますので、どうぞよろしくお願いいたします(\*^^\*)

Twitter - https://twitter.com/hiroki_web
Amazon SageMaker ノートブックインスタンスで最新版の SageMaker Python SDK を使用する

2019 年 8 月より [Amazon SageMaker](https://aws.amazon.com/sagemaker/) のトレーニングジョブでスポットインスタンスが使用できるようになったため、早速試してみようとしたところ、SageMaker ノートブックインスタンスにプリインストールされる SageMaker Python SDK のバージョンが古く使用できなかった。そこで、本稿ではこの SageMaker Python SDK のアップデート方法について記述する。

#### 関連記事
- [管理型スポットトレーニング: Amazon SageMaker トレーニングジョブで最大 90% を節約 | Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/managed-spot-training-save-up-to-90-on-your-amazon-sagemaker-training-jobs/)
- [SageMakerのトレーニングジョブでマネージドスポットトレーニング機能がリリースされました！ | DevelopersIO](https://dev.classmethod.jp/machine-learning/sagemaker-spot-training/)

## 解決方法

[ライフサイクル設定](https://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/notebook-lifecycle-config.html) を作成し、以下のスクリプトをノートブックインスタンスの開始時 (Start notebook) に実行するよう設定する。

```bash
#!/bin/bash
set -e

sudo -u ec2-user -i <<'EOF'
source /home/ec2-user/anaconda3/bin/activate mxnet_p36
pip install --upgrade sagemaker
source /home/ec2-user/anaconda3/bin/deactivate
EOF

initctl restart jupyter-server --no-wait
```

`mxnet_p36` の部分はノートブックインスタンスで使用するカーネルに合わせて適宜書き換える。`mxnet_p36` と記述した場合は、`conda_mxnet_p36` カーネルでのみ最新版の SageMaker Python SDK が使用できるようになる。

なお、以下のように記述すればすべてのカーネルで最新版の SageMaker Python SDK が使用できるようになるが、スクリプトの実行に 5 分以上かかるとノートブックインスタンスの起動に失敗することに注意が必要だ。

```bash
#!/bin/bash
set -e

sudo -u ec2-user -i <<'EOF'
for env in base /home/ec2-user/anaconda3/envs/*; do
  source /home/ec2-user/anaconda3/bin/activate $(basename "$env")
  if [ $env = 'JupyterSystemEnv' ]; then continue; fi
  pip install --upgrade sagemaker
  source /home/ec2-user/anaconda3/bin/deactivate
done
EOF

initctl restart jupyter-server --no-wait
```

#### 実際にスポットトレーニングを実行してみる

Estimator のパラメータに `train_use_spot_instances` , `train_max_wait` , `checkpoint_s3_uri` , `checkpoint_local_path` を追加する。最新版の SageMaker Python SDK がインストールされていれば正常に動作する。

```python
od_model = sagemaker.estimator.Estimator(
    image_name,
    role,
    train_instance_count=1,
    train_instance_type='ml.p3.2xlarge',
    train_volume_size=8,
    train_max_run=3600,
    input_mode='File',
    output_path='s3://example-bucket/2019-09-15/output',
    sagemaker_session=session,
    train_use_spot_instances=True,
    train_max_wait=3600,
    checkpoint_s3_uri='s3://example-bucket/2019-09-15/checkpoints',
    checkpoint_local_path='/opt/ml/checkpoints')
```

参照： [Estimators &mdash; sagemaker 1.39.2 documentation] (https://sagemaker.readthedocs.io/en/stable/estimators.html)

## 知見など

- ノートブックインスタンスのターミナルから `pip install --upgrade sagemaker` を実行しても効果がなかった。
- 上記を実行後ノートブックインスタンスを再起動すると SageMaker Python SDK のバージョンが元に戻っていた。

## 参考

GitHub の以下のリポジトリに AWS 公式のライフサイクル設定例がいくつか紹介されている。
https://github.com/aws-samples/amazon-sagemaker-notebook-instance-lifecycle-config-samples
windows store appsに対するプロキシの有効化

コマンドプロンプトで
"CheckNetIsolation loopbackExempt -a -p=app_SID"を
実行すればそのアプリはプロキシ経由でインターネットに接続できるようになる。
ちなみに、オプション"-a"の意味は"add"である。
app_SIDはアプリのSIDストリングを指す。
app_SIDはレジストリの"HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppContainer\Mappings"のディレクターの中にあるフォルダ名を指す。左の方のフォルダをクリックすれば右の方の情報を見てどのアプリに当たるのかを判断できる。
レジストリエディタ：regedit // reg editの意味

CheckNetIsolation loopbackExemptのマニュアルは"CheckNetIsolation loopbackExempt -?"を使って確認できる。
返るマニュアルを読むことでこのコマンドを使いこなせるようになる。

元文章（中国語）：
https://www.jianshu.com/p/7b8c8571cb28
PathMatcher::matchesでIllegalArgumentExceptionが発生する

# 事象

いきなり個人的な事情で申し訳ないのですが、一連のファイルやディレクトリに対して、globを使ってフィルタリングしたいという場合、`Files::newDirectoryStream(Path, String)`を利用してきました。というより、その方法しか知りませんでした。

このAPIでは第2引数にglobを指定します。以下がその例になります。

```java
var dir = Paths.get(".");
try (var paths = Files.newDirectoryStream(dir, "**.py")) {
    for (var path : paths) {
        doSomething(path);
    }
} catch (IOException e) {
    e.printStackTrace();
}
```

正直なところ`DirectoryStream`は使いにくいAPIで、とくに「`java.util.Stream`につなげづらい」というのが、個人的にはもっともつらい。__要するに「globによるフィルタリングをStream処理に組み込みたい」わけです。__そこで、いろいろと調べてまわったところ、`java.nio.file.PathMatcher`を利用すればよいということが判明。

```java
var dir = Paths.get(".");
var matcher = FileSystems.getDefault().getPathMatcher("**.py");
Files.walk(dir).filter(matcher::matches).forEach(path -> doSomething(path));
```

さっそくこれを実行したところ、以下のように`IllegalArgumentException`が発生し、想定通りに動作しませんでした。

```text

Exception in thread "main" java.lang.IllegalArgumentException
    at java.base/sun.nio.fs.WindowsFileSystem.getPathMatcher(WindowsFileSystem.java:262)
    at Main.main(Main.java:19)
```

# 原因と対処

今回は「JavaDocをちゃんと読みましょう」案件でした…。[`FileSystem::getPathMatcher(String)`のJavaDoc](https://docs.oracle.com/javase/jp/7/api/java/nio/file/FileSystem.html)には次の通り記述されています。

> syntaxAndPattern パラメータは、構文とパターンを識別し、次の形式をとります。
>> *syntax:pattern*

> ここでの ':' はそれ自体を表します。
> FileSystem 実装では、「glob」および「regex」構文をサポートしますが、その他をサポートすることもできます。構文コンポーネントの値は大文字小文字に関係なく比較されます。

今回のようにglobパターンを利用したい場合は`glob:**.py`というような書き方をする必要があるということです。それを使って上記の例を書き換えたものが以下になり、これを実行すると`IllegalArgumentException`が発生しなくなりました。

```java
var dir = Paths.get(".");
var matcher = FileSystems.getDefault().getPathMatcher("glob:**.py");
Files.walk(dir).filter(matcher::matches).forEach(path -> doSomething(path));
```
便利ページ：Javascriptでカラーピッカー

[便利ページ：Javascriptでちょっとした便利な機能を作ってみた](https://qiita.com/poruruba/items/6c67c7eef34ed302feb3) のシリーズものです。

今回は、色の選択とRGB値の表示です。
HTMLにカラーピッカーがあるので、それを使います。また、プリセットカラーで選択できるようにします。

こんな感じのページです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/b851826e-126c-95d2-171d-4b45f9d9598b.png)

毎度の通り、デモページとGitHubです。

GitHub
　https://github.com/poruruba/utilities

デモページ
　https://poruruba.github.io/utilities/

(2019/9/15 追記)
一番近い色の名前を検索できるようにしました。色差を計算するのに以下を使わせていただきました。
　https://gka.github.io/chroma.js/
一口に色と言っても奥が深いですね。


# カラーピッカーを表示する

HTMLは以下の通りです。

```html:index.html
<div class="form-inline">
    <input type="color" v-on:change="color_change" v-model="color_value">&nbsp;&nbsp;
    <label>RGB:</label> <input type="text" size="7" class="form-control" v-model="color_value">
</div>
<br>
<table class="table table-borderless">
    <td v-bind:bgcolor="color_value">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
    <td><label>R:</label><input type="range" min="0" max="255" v-model.number="color_r" v-on:input="color_range"><input type="number" class="form-control" v-model.number="color_r" v-on:change="color_range"></td>
    <td><label>G:</label><input type="range" min="0" max="255" v-model.number="color_g" v-on:input="color_range"><input type="number" class="form-control" v-model.number="color_g" v-on:change="color_range"></td>
    <td><label>B:</label><input type="range" min="0" max="255" v-model.number="color_b" v-on:input="color_range"><input type="number" class="form-control" v-model.number="color_b" v-on:change="color_range"></td>
</table>
```
カラーピッカーは、type="color"のinputです。
あとは、color_valueに格納されたRGB値をテーブルのセルの背景色として表示しています。
type="range"のinputのゲージでもRGBの各値を変更できるようにしました。
ここらへんは、Vueのデータバインディング機能が大活躍です。

基本16色などのテーブルがありますが、プリセットとしてcolor.jsに配列として格納しておいたものを、テーブル表示しているだけです。

単純ですね。。。

以上
日本語を含む PowerShell スクリプトの文字コード

（この記事では、Windows PowerShell（5.1 以前: powershell.exe）を PowerShell と書きます。PowerShell Core（6.0 以降: pwsh.exe）とは異なるので注意。）

PowerShell スクリプトを UTF-8 で書いて PowerShell で動かそうと思ったら動かなかった。調べてみたら、[VSCode と PowerShell でのファイルのエンコードの概要](https://docs.microsoft.com/ja-jp/powershell/scripting/components/vscode/understanding-file-encoding?view=powershell-6)というページが参考になった。

PowerShell には文字コードの自動判別機能がない。また、実行時に文字コードを指定することもできない。ファイルに BOM（byte order mark: バイト順記号）があれば文字コードがわかるけれど、BOM がなければデフォルトの文字コードで読もうとする。デフォルトの文字コードは、日本語ロケールでは Shift-JIS。なので、BOM なし UTF-8 で書かれたファイルは読めない。

したがって、PowerShell が読める日本語のファイルは Shift-JIS か BOM 付きユニコードということになる。

ということは、メモ帳で書き出せる文字コードなら PowerShell が読める。メモ帳での表記は「ANSI」「Unicode」「Unicode big endian」「UTF-8」となっているけれど、実際にはそれぞれ Shift-JIS、UTF-16（リトルエンディアン）、UTF-16（ビッグエンディアン）、BOM 付き UTF-8。そのいずれかでスクリプトを書けば、PowerShell で実行できる。
[Rails]ajaxでpostアクションを叩いたらsessionが拾えなかった。

どうもこんばんは、Rails学習2〜3ヶ月くらいのChihaです。
タイトル通り、jQueryからajaxでアクションを叩いて動かすと、それまで定義してきたsessionの値が拾えなくなる現象に遭遇&解決したので、ざっくりと書きます。

## 開発環境

- Ruby on Rails 5.2.2
- Ruby 2.5.1
- jQuery

## 概要
ajaxからのpostリクエストを叩くと、アプリ側に持たせていたsessionの値が取得できなくなった。

```javascript:signup.js
//何かしらの処理後
$.ajax({ 
          url: "/signup",
          type: "POST",//コントローラのアクションをpostで叩く
          data: {
            //送るデータとか
          },
          async: false //今回は同期通信でした
        })
```

```ruby:signup_controller.rb(例)
#前のページでの入力項目をsession保存
def before_page_content
  session[:birthyear] = profile_params[:birthyear]
  session[:birthmonth] = profile_params[:birthmonth]
  session[:birthday] = profile_params[:birthday]
end

#ajaxで叩くcreateアクション
#/signup（method: :post）
def create
  ※下のcreateが失敗する
  @profile = Profile.create(
  birthyear: session[:birthyear],
  birthmonth: session[:birthmonth],
  birthday: session[:birthday]
  )
end

```
こんな感じのコードでjsから直接postメソッドのアクションを叩くと、それまでに取得して来ることができたはずのsessionの値が全部nilになっていた。そりゃ当然失敗する。

```:ターミナル
ActionController::InvalidAuthenticityToken
```
エラーはこういうのが出ました。

## 解決策

```javascript:signup.js
//何かしらの処理後
$.ajax({ 
          url: "/signup",
          type: "POST",
          data: {
            //送るデータとか
          },
          //下の記述を追記
          beforeSend: function(xhr) {
            xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
          },//ここまで
          async: false
        })
```
これで無事にcreateアクションでsessionの値を拾って処理ができるようになりました。

[Rails not reloading session on ajax post](https://stackoverflow.com/questions/5126721/rails-not-reloading-session-on-ajax-post/5127927#5127927)
[【Rails API】ActionController::InvalidAuthenticityTokenの解決方法](https://qiita.com/_ayk_study/items/88269643c675fd4ca975)
[外部からPOSTできない？RailsのCSRF対策をまとめてみた](https://qiita.com/KumatoraTiger/items/cc6a1107374cce500e6d)

解決はこの辺りを参考にしました。
どうやら、RailsでのCSRF対策にjsからget以外のメソッドを叩いたのが悪かったようです。
[【Rails API】ActionController::InvalidAuthenticityTokenの解決方法](https://qiita.com/_ayk_study/items/88269643c675fd4ca975)
詳しい理由とCSRFについてはこの記事に書かれてます。

## トラブルの経緯

スクールでの開発にて、wizard形式（複数ページに渡りユーザー情報を入力させ、最後のページで一括createする形式）でのユーザー登録機能を実装していた時の話。
各ページで入力された値は、sessionとしてアプリ側に預ける形に（詳しくはそのうち）。
最終ページでクレジットの情報を登録する必要があったため、[payjp](https://pay.jp/)を利用することに。

payjpでは、ユーザーが入力したクレジット情報をjavascript経由でpayjpに送り、トークンの情報を返す処理を行うことで、クレジット情報をRails側で使用せず、トークンを用いたユーザーのクレジットカード登録機能の実装、使用が可能となります。
こちらについては詳しくはpayjp.jsのリファレンス（[カード情報のトークン化](https://pay.jp/docs/cardtoken)）で。

というわけで、最終ページでcreateではなく、payjp.jsでのトークン取得を経てcreateする形で実装することに。

つまり、jsでの処理を経由してpayjpからのトークンを取得したのち、トークンをjsから投げつつ、postメソッドのcreateアクションを叩く、という感じでの実装を考えた。

ここでjsからcreateアクションを叩くとsessionが一つも取得できなくなっていた。
要するに上記の症状が発生していた。
↓
js側に記述を書き足すと解決した。

という流れになります。

かなりアバウトな感じになりましたが、詳しくは上記の参考記事にて。
クレジットカード登録を含めたwizard形式でのユーザー登録フォームの実装については、長くなりそうなので後日ということで。。。

## 最後に
引き続き気まぐれにトラブルや知った技術などを忘備録として書いていこうと思います。
まだまだ右も左もあやふやなド初心者ですので、より良いコード、間違った点などがあればご教授頂けると幸いです。
Ubuntuインストール後の初期設定

# 概要
他の記事にも書いていますが、備忘録もかねて、独立させます。

# UBUNTUの初期設定
```
# hostname の設定
$ sudo hostnamectl set-hostname <任意のホスト名>

# パッケージリストの更新
$ sudo apt-get update

# インストールされてるパッケージの更新
$ sudo apt-get upgrade

# binutilsをインストール
$ sudo apt install binutils

# 日本ロケール設定# 
# language-pack-ja のインストール
$ sudo apt-get install language-pack-ja
# locale に ja_JP.UTF-8 を設定
$ sudo update-locale LANG=ja_JP.UTF-8
$ strings /etc/default/locale

# /usr/share/zoneinfo/Asia/Tokyo から /etc/localtime にリンクを張る
$ sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

# timezone に Asia/Tokyo を設定
$ sudo dpkg-reconfigure --frontend noninteractive tzdata
$ strings /etc/localtime

```

以上です。
GitHub Markdown APIの使い方

## リクエストURL

```bash
https://api.github.com/markdown/raw
```

## ヘッダ

|ヘッダ|値|
|---|---|
|Content-Type|text/plain|

あとはデータにマークダウンを渡してPOSTするだけ。

## curlを使った例

```bash
curl -X POST https://api.github.com/markdown/raw -H 'Content-Type: text/plain' -d '# Hello World'
# => <h1>
#    <a id="user-content-hello-world" class="anchor" href="#hello-world" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Hello World</h1>
```

## Golangを使った例

[【Go】GitHub Markdown APIを叩いてみる - Qiita](https://qiita.com/kou_pg_0131/items/800a920a3e5287012314)

## おわりに
データをJSON形式で渡してオプションを指定する方法もあるけど、正直上記のもので十分なので今回は割愛。
知りたい方は下記参考リンクを参照。

## 参考

- [Markdown | GitHub Developer Guide](https://developer.github.com/v3/markdown/)
Mac 入門

# Mac 入門

## Windows から Mac に乗り換えた場合（Macに慣れていればスキップ）

- **右クリック**
    - トラックパッドを２本指でクリックする
- **スクロール**
    - トラックパッドを２本指でスライドする
- **ブラウザで進む・戻る**
    - トラックパッドを２本指で左右にスワイプする
- **アプリを開く**
    - 画面下に表示されているアプリアイコン表示 (**Dock**) を使用する
    - **Launchpad** を使用してアプリを開く（ https://support.apple.com/ja-jp/HT202635 ）
       ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44953/f0fca125-1db1-7218-0947-84614a3d5243.png)


- **ファイルエクスプローラー**
    - **Finder** を使う（ https://support.apple.com/ja-jp/HT201732 )
        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44953/60afdf1b-737b-131e-b35a-68d9893a0696.png)


- **ファイルを削除する**
    - **Dock** 右下の**ゴミ箱** を使用する

- **ファイル名を変更する**
    - ファイルを選択して Enter を押す


## 初期設定

### システム環境設定
- **キーボード** ->
    - **キーボード** ->
        - **キーのリピート**のスライダーを速い（最大値）にする
        - **リピート入力認識までの時間**のスライダーを短い（最大値）にする
        - **[修飾キー]** -> **Caps Lock** を **Control** に変更する
    - **ショートカット** ->
        - **キーボード** の **次のウインドウを操作対象にする** で 右側のコマンド欄をダブルクリックして 好みのショートカットへ変更する（ **option + tab** を推奨）
- **Dock** ->
    - **Dockを自動的に表示/非表示** にチェックを入れる
- **日付と時刻** ->
    - **メニューバーに日付と時刻を表示** にチェックし、**24時間表示にする**・**曜日を表示**・**日付を表示** にチェックを入れる
- **セキュリティとプライバシー** ->
    - **スリープとスクリーンセーバの解除にパスワードを要求** を **すぐに** に変更する
    - **ファイアウォール** を **オン** にする
- **省エネルギー** ->
    - **電源アダプタ** の **コンピュータのスリープ** を **しない** に変更する
- **ディスプレイ** ->
    - **光度を自動調整**　のチェックをはずす
    - **True Tone** のチェックをはずす
- **トラックパッド** （必須ではなく推奨） ->
    - **ポイントとクリック** の **タップでクリック** にチェックを入れる
    - **軌跡の速さ** を速いに変更


### ステータスバー

- バッテリーの割合を表示する

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44953/0fc56a98-5b01-d035-9c7a-42c6beb374ae.png)
![](images/0_mac/3.jpg)

### Finder 設定

**Finder**　の **環境設定** を開く

- **一般** ->
    - **フォルダを新規ウインドウではなくタブで開く** にチェックを入れる
- **詳細** ->
    - **すべてのファイル名拡張子を表示** にチェックを入れる



## Google日本語入力インストール

ほぼ必須

https://www.google.co.jp/ime/


## ショートカット

Mac のキーボードショートカット

https://support.apple.com/ja-jp/HT201236

### よく使うショートカット

#### 基本
- **カット** : command + X
- **コピー** : command + C
- **ペースト** : command + V
- **すべて選択** : command + A
- **検索** : commnad + F
- **保存** : command + S
- **新しいタブを開く** : command + T
- **ウィンドウを閉じる** : command + W
- **アプリを切り替える** : command + tab
- **同じアプリで複数のウィンドウを切り替える** : 自分が設定したショートカット（推奨設定をしていれば **option + tab** になる）
- **取り消し** : command + Z
- **アプリを終了する** : command + Q
- **アプリを強制終了する** : option + command + esc


#### 文字列編集
プログラマーにとっては必須操作

- **１文字進む** : ctrl + F
- **１文字戻る** : ctrl + B
- **１行上へ移動** : ctrl + P
- **１行下へ移動** : ctrl + N
- **末尾へ移動** : ctrl + E
- **先頭へ移動** : ctrl + A
- **１文字削除** : ctrl + H
- **現在位置から最後尾まで削除** : ctrl + K

#### Finderのショートカット

- **ホームフォルダを開く** comannd + shift + H
- **アプリケーションフォルダを開く** command + shift + A
- **ダウンロードフォルダを開く** option + command + L
- **ファイルをゴミ箱に入れる** command + delete
- **上階層のフォルダへ移動する** command + 上矢印キー
- **下階層のフォルダへ移動する** command + 下矢印キー

#### Google日本語入力(ことえり)のショートカット

全角文字変換中に

- **ひらがなに変換** : ctrl + J
- **カタカナに変換** : ctrl + K
- **全角英字数に変換** : ctrl + L
- **半角に変換** : ctrl + ;
Project Euler 016, 020を解いてみる。「各位の数字の和」

# Project Euler 016, 020
[016](http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2016)
>215 = 32768 であり, 各位の数字の和は 3 + 2 + 7 + 6 + 8 = 26 となる.
同様にして, 2<sup>1000</sup>  の各位の数字の和を求めよ.

[020](http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2020)
>n × (n - 1) × ... × 3 × 2 × 1 を n! と表す.
例えば, 10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800 となる.
この数の各桁の合計は 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27 である.
では, 100! の各位の数字の和を求めよ.

->[次の問題](https://qiita.com/radiol/items/fad37d1775134cb0db81)

## 考え方
016と020は類似の問題なので合わせて解きます。
桁数や第1桁、最高位の数字を出す方法はありますが、各位の数字は実際に計算する以外の方法が思いつかなかったので、単純に計算しています。
pythonはstrにすることで各桁の数字を文字列で取り出せるので便利ですね。

## コード

```Python:euler016.py
def main016():
    number = 2 ** 1000
    num_list = [int(i) for i in str(number)]
    print(sum(num_list))


def main020():
    number = 1
    for i in range(2, 101):
        number *= i
    num_list = [int(i) for i in str(number)]
    print(sum(num_list))


if __name__ == '__main__':
    from time import time as t
    start = t()
    main016()
    print(t() - start)
    start = t()
    main020()
    print(t() - start)
```

[paiza](https://paiza.io/projects/new)にて実行
`結果
1366
6.604194641113281e-05
648
3.266334533691406e-05
`
シンプルな問題が続きますね
Windows WSL2に移行後 bundle exec rails xxx が激遅だったが解決

解決した方法を先に書くと
**WindowsのCドライブなどに置いていたrailsプロジェクトをWSLのUbuntu配下に移動する**

Mac使っていないマンとしてはWSL2を試してみたくなってWindows Insider Programに参加しました。
Windows Insider ProgramとWSLについては簡単にこちらのブログに書きました。
https://blog.higekick.net/wls2/

Rails Tutorialをやっているのですが、WSL2に移行後、`bundle exec rails s`とかが遅いことに気づきました。
確かに各種`git`コマンドは速くなっている気がします。
なんでかなと思って予想したのがrailsのプロジェクトを置いているディレクトリの位置でした。
wsl2は仮想マシン上で動いているとかなんとか聞いたのですがWindows側から見た時の位置が以下のようになっていました。

![wsl-directory-path.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152641/e84094e7-cd3c-5739-9c50-b215ac3851f5.png)

パスとしてはこんな感じになっていました。

```
\\wsl$\Ubuntu
```

wsl1の時の位置はちょっと把握していないのですが、Networkの下とかじゃなかったですよね。
本題のrailsプロジェクトですが、WindowsのDドライブに置いてUbuntuのホームディレクトリからシンボリックリンクで参照できるようにしていました。
wsl2に移行後もちゃんとそれは維持されていて、wsl1と同じようにrailsプロジェクトのディレクトリを参照できて、`$ code rails-tutorial-sampleapp/` とかでVS CODEで開いてRails Tutorialを楽しむことができました。

```
hige@thkpdE480:~$ pwd
/home/hige
hige@thkpdE480:~$ ls -la src
lrwxrwxrwx 1 hige hige 10 Sep  5  2018 src -> /mnt/d/src
```

しかしrailsの各種コマンドが遅いのですね。5分くらいでやっとrails serverが立ち上がる感じです。
そこまで待ってみた私もすごいのですが、なんでこんな遅いのか解決したかったです。

で、やっぱりこのネットワーク下になってしまった `\\wsl$\Ubuntu` のディレクトリからDドライブのプロジェクトを参照してしまっているからでは？と思ったのですよね。
そこで以下のようにホームディレクトリに配置したら速くなりました。

```
\\wsl$\Ubuntu\home\hige\src2\rails-tutorial-sampleapp
```

実際にはgitでcloneしなおしたのですが、railsプロジェクトなので移動後、railsが起動できるようになるまでどうやったのかメモしておきます。railsプロジェクトをcloneして自分の端末で開発できるようにするときはだいたいこうやるのかなと思っております。

- Ubuntu下のディレクトリでcloneしなおす

```
$ git clone [リポジトリURL]
```

- rubyをセットする

```
$ rbenv local 2.6.1
```

- gemsをインストールする

```
$ bundle install --path vendor/bundle
```

- DBをテスト環境(開発環境？)用にマイグレートする, テストデータを入れる

```
$ bundle exec rails db:migrate RAILS_ENV=test
$ bundle exec rails db:seed
```

- テストして通ればOK

```
$ bundle exec rails test
```

- サーバーが立ち上がってログインし、テストデータが見えればOKとする

```
$ bundle exec rails server
```

これらの`bundle exec rails xxx`コマンドが前みたいに普通の速さで実行できるようになりました。
wsl1の頃よりたぶん速くなっているんですよね！？確かに速くなっている気がします。
Macだとこんな苦労しなくても良さそうだけど、いろいろな制約でWindows使うしかない方とかたくさんいらっしゃると思います。共にがんばりましょう！

増税前にMac買ったほうがいいですかね... 2019/09/15
【Go】GitHub Markdown APIを叩いてみる

## はじめに

GitHub Markdown APIの使い方に関しては、以下の記事を参照。

- [GitHub Markdown APIの使い方 - Qiita](https://qiita.com/kou_pg_0131/items/83265f40da75cb1cdccc)

## サンプルコード

```go
package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

func main() {
	apiURL := "https://api.github.com/markdown/raw"
	markdown := "# Hello World"

	// リクエストを生成
	req, err := http.NewRequest("POST", apiURL, strings.NewReader(markdown))
	if err != nil {
		panic(err)
	}
	req.Header.Add("Content-Type", "text/plain")

	// POSTリクエストを送信
	client := &http.Client{}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	// レスポンスを読み取り
	bytes, err := ioutil.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(bytes))
	// => <h1>
	//    <a id="user-content-hello-world" class="anchor" href="#hello-world" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Hello World</h1>
}
```

## 参考

- [Markdown | GitHub Developer Guide](https://developer.github.com/v3/markdown/)
- [Go net/httpパッケージの概要とHTTPクライアント実装例 - Qiita](https://qiita.com/jpshadowapps/items/463b2623209479adcd88#post)
怖くないよね？マルチステージビルド

会社の本番環境をAWSのEKSに移行することになりその際にgolangのアプリを配布する際に使用したマルチステージビルドについて備忘録を交えながら記事を書いていきます。

先に言うんですけど

## すみません僕Docker自体初めてです

今まで特に自分でDockerなどで環境構築をしたことがなかったのでこれが初めてのDocker作成です。
ほとんど分かっていないのでこいつダメやなって思いながら見てください

マルチステージビルドについて
https://github.com/moby/moby/pull/31257

簡単に言うと、fromでから作られた2つの複数のFROMイメージ間のファイルを COPY --from で直接を参照できるようになったのと AS で中間イメージに名前が付けられるようになったと言うものです。

golangってクロスコンパイルなどでシングルバイナリさえあればgolangの実行環境不要ですもんね
(golangにいては割愛します。)

## 早速やりましょうか

基本的なファイル構成はこちら

```
├build(ここにbuildの成果物が格納される)
│　└ appname(実行バイナリ)
├cmd(実行ディレクトリ)
│ └ main.go
├configs(設定ファイル関連)
├bitbucket-pipelines.yml
├.env(環境変数設定ファイル)
├docker-compose.yml
├Dockerfile
├go.mod
├go.sum
├Makefile(タスクランナー実行ファイル)

```

### Makefile

基本的には今回は `go build` なども含めて全てMakefile側に任せています。

makefileに関しての設定はここで書きませんがちゃんとbuild配下にバイナリが入るように以下のように設定しました

```
build: 

@go build -ldflags="-w -s" -o build/appname ./cmd/main.go
```

これで`make build`のコマンドをターミナルで実行するとbuild配下にappnameと言うシングルバイナリが作成されます

### Dockerfile

```Dockerfile:Dockerfile
FROM golang:1.12.9 as builder

WORKDIR /appname/

ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64

COPY go.mod .
COPY go.sum .

RUN GO111MODULE=on go mod download
COPY . .

RUN make build 

FROM alpine

RUN apk update \
  && apk add --no-cache

COPY --from=builder /appname/build /app/build

ENTRYPOINT [ "/app/build/appname" ]
```

まずポイントを解説すると

```
FROM golang:1.12.9 as builder
```

これでgolangのbaseimageを作成しますこの `as builder`と言うのがこの後にこのimageを渡すためのエイリアスになります

```
ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64

COPY go.mod .
COPY go.sum .

RUN GO111MODULE=on go mod download
COPY . .
```

go.modはgolangのモジュール関連の設定ファイルです(jsのpackage.jsonみたいなもの)
https://qiita.com/propella/items/e49bccc88f3cc2407745

`ENV GO111MODULE=on`はおまじないみたいなもので現行のgo1.13の環境では必要ないと思う（動かなかったらいれてください）

```
RUN make build 
```

ここでgoのbuildを行います `make build`コマンドは先ほど作成した `Makefile`のトリガーとして `build`を設定していたのでこのようなコマンドでタスクの実行が可能です

クロスコンパイルについてはこちらを参照してください
https://qiita.com/xshirade/items/abeb0d595be27cb6326e

```
FROM alpine
```

こちらはDockerの公式が提供している軽量なLinuxのイメージです。
https://alpinelinux.org/

```
COPY --from=builder /appname/build /app/build
```

ここで先ほどbuildした実行バイナリの格納ファイル等をこちらにCOPYしています
これでマルチステージビルドの完成です


## 補足

これで`ducker build` などでもいいのですが開発環境等でmysqlに接続できる等などの確認が必要だと思うのでdokcer-compose.ymlで環境の構築を行います

```docker-compose.yml
version: "3"

services:
  mysql:
    image: mysql:5.7.26
    container_name: db
    env_file:
      - .env
    ports:
      - "3306:3306"
    volumes:
      - db_data:/var/lib/mysql
      - ./mysql/scripts/init:/docker-entrypoint-initdb.d
      - ./mysql/config:/etc/mysql/conf.d
  api:
    build: .
    depends_on:
      - mysql
    env_file:
      - .env
    ports:
      - "8080:8080"

volumes:
  db_data:

```

これで

```
$ docker-compose up --build -d
```

こちらで接続ができているかなどの確認（go側にmysqlに接続などのプログラムは書いてくださいね）


## 最後に

僕自身初めてのDockerだったので探り探りでの実装だったのですがもし他にこれの方がいいよってものがありましたら是非教えて頂けますと幸いです。
最後まで読んで頂いてありがとうございました。

次にbitbucket-pipelines.ymlを使用したECRへのPUSHをしたいと思います。
JavaScriptで綺麗にリンク一覧を取得する

スクレイピングするまでもないけど、サイトのリンク一覧をさっと取得したいシーンがあったのでスクリプトを書きました。
実用的なスクレイピングやもっと高度なことを求めている方はChrome拡張の[Scraper](https://chrome.google.com/webstore/detail/scraper/mbigbapnjcgaffohmbkdlecaccepngjd)等の利用を検討して、どうぞ。
#仕様
「綺麗に」の内訳。

- リンクのテキストとURLを並べて表示、クリップボードにコピー
- URLの重複は除去する
- テキストの無駄な改行は除去する
- 特定のドメインに絞れるようにする
- For文は使わない

#コード
copy()コマンドを利用しているので、Chrome前提です。
ブラウザのConsoleに貼って実行してください。

```javascript

// 検索ワードは適宜変更してください。
const targetLinkWords = ['www.bbc.com'];

const createLinkList = (el) => {
  let existsList = [];
  let res = '';
  Array.prototype.filter.call(el, (node) => {
    // hrefの値重複とtargetLinkWordsに登録されたワードを含まない場合、除外
    if (existsList.indexOf(node.href) === -1 && 
      targetLinkWords.find((val) => {return node.href.indexOf(val) !== -1;})) {
      existsList.push(node.href);
      res = `${res}\r\n` + (node.text.trim() === '' ? 
        'テキストなし':node.text.replace(/\r?\n/g, '')) + `||${node.href}`;
    }
  });
  return res;
};

const result = createLinkList(document.querySelectorAll('a'));
console.log(result);
copy(result);

```
#結果
試しに[BBC NEWS Tech](https://www.bbc.com/news/technology)のページで実行してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274701/969c30e3-eb6d-7054-766d-a3ddb880f0cd.png)


```
Homepage||https://www.bbc.com/
Skip to content||https://www.bbc.com/news/technology#skip-to-content
Accessibility Help||https://www.bbc.com/accessibility/
Sign in||https://session.bbc.com/session?ptrt=https%3A%2F%2Fwww.bbc.com%2Fnews%2Ftechnology&context=news_gnl&userOrigin=news_gnl
Notifications||https://www.bbc.com/news/technology#
News||https://www.bbc.com/news
Sport||https://www.bbc.com/sport
Reel||https://www.bbc.com/reel
Worklife||https://www.bbc.com/worklife
Travel||https://www.bbc.com/travel
Future||https://www.bbc.com/future
Culture||https://www.bbc.com/culture
Music||https://www.bbc.com/culture/music
Weather||https://www.bbc.com/weather
More||https://www.bbc.com/news/technology#orb-footer
Video||https://www.bbc.com/news/video_and_audio/headlines
World||https://www.bbc.com/news/world
Asia||https://www.bbc.com/news/world/asia
UK||https://www.bbc.com/news/uk
Business||https://www.bbc.com/news/business
TechTech selected||https://www.bbc.com/news/technology
Science||https://www.bbc.com/news/science_and_environment
Stories||https://www.bbc.com/news/stories
Entertainment & Arts||https://www.bbc.com/news/entertainment_and_arts
Health||https://www.bbc.com/news/health
World News TV||https://www.bbc.com/news/world_radio_and_tv
In Pictures||https://www.bbc.com/news/in_pictures
Reality Check||https://www.bbc.com/news/reality_check
Newsbeat||https://www.bbc.com/news/newsbeat
Special Reports||https://www.bbc.com/news/special_reports
Explainers||https://www.bbc.com/news/explainers
Long Reads||https://www.bbc.com/news/the_reporters
Have Your Say||https://www.bbc.com/news/have_your_say
Africa||https://www.bbc.com/news/world/africa
Australia||https://www.bbc.com/news/world/australia
Europe||https://www.bbc.com/news/world/europe
Latin America||https://www.bbc.com/news/world/latin_america
・・・
```
ちゃんとコピーされました。
JavaScript の Array で undefined などの値を除外する方法

## TL;DR
```javascript
const array = [0, 1, 2, "", undefined, null, NaN, "hoge"]
array.filter(Boolean) // => [1, 2, "hoge"]
```

## 詳細
`Array.prototype.filter` を使用しています。引数に入るコールバックの処理に対して true を返す値のみに絞る関数です。

例えば、以下のように偶数である値のみを抽出したいときなんかにも使えます。

```javascript
[...Array(10).keys()].filter(n => n % 2 == 0) // => [0, 2, 4, 6, 8]
```

上記の例の場合は偶数かどうかの処理をはさみましたが、ここに `Boolean` を入れると `Boolean()` を実行してくれます。関数呼び出しですね。`Boolean()` を実行すると値の真偽を判定してくれます。Boolean の仕様によると、以下の値はすべて `false` と判定されるようです。

### false と判定される値
```javascript
[0, -0, null, false, NaN, undefined, ""]
```

> If the value is omitted or is 0, -0, null, false, NaN, undefined, or the empty string (""), the object has an initial value of false.

## 備考
蛇足ですが、`new Boolean()` でオブジェクトを作るときは `false` と判定された値を持つ Boolean オブジェクトも生成されるようです。しかも if 文とかで判定するときも常に true が返ってきます。不思議。

```javascript
const bool = new Boolean(false)
if(bool) console.log("false is true!") // => "false is true!"
```

## 参考文献
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
Python経由のDarknetでdetectした画像をpng形式で保存する話

# はじめに
Darknet(yolo)をpythonから使いたいなと思い、
デフォルトで入っているdakrnet.pyを参考に作ろうと思ったのですが、
そのコードには画像を保存する方法が書かれていませんでした。

とりあえず調べてみるかと、[こちらの記事](https://qiita.com/massie_g/items/a2bcfac4fed66b1b0717)を参考に画像を保存するコードを実装したのですが、
jpg形式以外で保存することができませんでした。

どうしてもpngで保存したかった私は、
~~しぶしぶ、忌まわしき~~C言語で書かれたソースを読むことにしました。

# 結論
以下のようにすれば、png形式等で保存可能です。

```darknet.py
class CtypesEnum(IntEnum):
    """A ctypes-compatible IntEnum superclass."""
    @classmethod
    def from_param(cls, obj):
        return int(obj)
        
class IMTYPE(CtypesEnum):
    PNG = 0
    BMP = 1
    TGA = 2
    JPG = 3

lib = CDLL("libdarknet.so", RTLD_GLOBAL)
save_image_options = lib.save_image_options
save_image_options.argtypes = [IMAGE, c_char_p, IMTYPE, c_int]

# -------------------中略-----------------------

save_image_options(image, "predictions".encode('utf-8'), 0, 80)
```


# 1.コードの確認

参考にさせていただいた記事で呼ばれている関数 *save_image*は、保存用の関数 *save_image_options*の導入に使用されている関数で、
指定imageをJPG形式で保存するというものでした。

```c:image.c
void save_image(image im, const char *name)
{
    save_image_options(im, name, JPG, 80);
}

```

この *save_image_options*の第三引数は、**darknet.h**で定義されているenum型の変数でした。

```c:darknet.h
typedef enum{
    PNG, BMP, TGA, JPG
} IMTYPE;
```

あれ、ctypesでenumってどう表現すればいいんだ？？？

# 2.ctypesでenumを表現する。
[こちらの記事](https://v4.chriskrycho.com/2015/ctypes-structures-and-dll-exports.html)にありました。

```python
from enum import IntEnum
class CtypesEnum(IntEnum):
    """A ctypes-compatible IntEnum superclass."""
    @classmethod
    def from_param(cls, obj):
        return int(obj)
        
class IMTYPE(CtypesEnum):
    PNG = 0
    BMP = 1
    TGA = 2
    JPG = 3

lib = CDLL("libdarknet.so", RTLD_GLOBAL)
save_image_options = lib.save_image_options
save_image_options.argtypes = [IMAGE, c_char_p, IMTYPE, c_int]
```
これでいけます。
Enum型は自作データ型に当たるようで、from_param() クラスメソッドを実装しなければならないようです。
[ドキュメント](https://docs.python.org/ja/3.7/library/ctypes.html#specifying-the-required-argument-types-function-prototypes)

# オチ
これを書いているときに気づきました。
よく考えると、enum型ってint型で代用できるので
わざわざclassで定義するまでもなく、c_intと定義してしまえば十分じゃね？と

```python
lib = CDLL("libdarknet.so", RTLD_GLOBAL)
save_image_options = lib.save_image_options
save_image_options.argtypes = [IMAGE, c_char_p, c_int, c_int]

save_image_options(image, "predictions".encode('utf-8'), 0, 80)
```

~~学生時代から忌まわしきとかいって避けてたツケが回ってきてる。。。~~
ctypesの勉強にはなったからよかったと思いたい。
【Ruby】変数の定義方法、配列の定義方法

# この記事の概要
・Rubyについて、Progateで学んだことを書き記す
・ガチ初心者によるもの
・主に備忘録として、随時書き足していく

# 項目
## 変数の定義の方法
変数の宣言
`name = "tanaka"`

変数の出力

```
name = "tanaka"
puts name

実行結果）tanaka
```

ちなみに、PHPの場合

```
$name = "tanaka";
echo $name;

実行結果）tanaka
```

## 配列の定義の方法
まずはシンプルな配列から

`name = ["tanaka","suzuki","sato"]`

```
name = ["tanaka","suzuki","sato"]
puts name

実行結果）
tanaka
suzuki
sato
```

配列の要素を、インデックス番号を指定して出力

```
name = ["tanaka","suzuki","sato"]
puts name[1]

実行結果）
suzuki
```

配列の要素を、eachを使用して全部出力

```
names = ["tanaka","suzuki","sato"]
names.each do |name| //namesの要素全てを、nameという変数に代入
  puts name
end

実行結果）
tanaka
suzuki
sato
```

ちなみにPHPだと、

```
$names = array("tanaka","suzuki","sato"];
foreach($names as $name){
    echo $name;
}
実行結果）
tanaka
suzuki
sato
```

## 変数を、文字列と結合して出力

```
name = "tanaka"
puts "My name is #{name}"

実行結果）My name is tanaka
```

```
names = ["tanaka","suzuki","sato"]
  puts "My name is #{name[2]}
end

実行結果）My name is sato
```

## クラスの使用

```
Class Menu
    attr_accessor:name  //Menuクラスが持つインスタンス
    attr_accessor:price  //Menuクラスが持つインスタンス
end

menu1 = Menu new //Menuクラスからインスタンスを生成し、変数Menu1に代入
menu1.name = "pizza" //Menuクラスのインスタンス変数であるnameに値を代入
puts menu1.name

実行結果）pizza
 ```

##　インスタンスメソッドの利用

```
Class Menu
    attr_accessor:name
    attr_accessor:price

  def show  //Menuクラス内でメソッドを定義（＝インスタンスメソッド）
    puts "today's menu"
  end
end

menu1 = Menu.new
menu1.show  //インスタンスメソッド呼び出し

実行結果）today's menu
```

## インスタンス変数の利用

```
class Menu
  def show_name
    puts "My name is #{self.name}"
  end
end

menu1 = Menu.new
menu1.name = "tanaka" //インスタンス変数に値を代入
menu1.show_name  //インスタンスメソッドの呼び出し
```

## IF文を含んだインスタンスメソッド呼び出し例

```
class Menu
  attr_accessor :name
  attr_accessor :price
  
  def info
    return "#{self.name} #{self.price}円"
  end
  
  # get_total_priceメソッドを定義
  def get_total_price(count)
    total_price = self.price * count
      if count >= 3
        total_price = total_price - 100
      end
    return total_price
  end
end

menu1 = Menu.new
menu1.name = "ピザ"
menu1.price = 800

# menu1に対してget_total_priceメソッドを呼び出し、その戻り値を出力
puts menu1.get_total_price(3)

```
T-SQL  ユーザー定義関数、エラー処理　他

#T-SQL

#変数
DECLARE　＠変数名　型名
SET　＠変数名　＝　代入値

または

SELECT　＠変数名　＝　代入値

 
```sql
DECLARE　
　　　＠変数名１　型名
　　　＠変数名２　型名
SELECT
　　　＠変数名１　＝　代入値
,          ＠変数名２　＝　代入値
```
 

#テーブル変数
・実行時のみメモリ上に存在する仮想テーブル
・通常の変数同様に処理完了時に自動的に廃棄されるため、データの削除処理やテーブル自体の削除処理は不要
・大量のデータを挿入するとその分メモリを消費するが、高速に処理できる

 

DECLARE　＠変数名  table {
　　列名１　型名　オプション
,  列名２　型名　オプション
}

 

主キーの設定

DECLARE　＠変数名  table 
　　列名１　型名　オプション
,   列名２　型名　オプション
,      PRIMARY  KEY 
,      主キー
　　）
）

 

INSERT  INTO  ＠変数名  VALUES ( 値１,  値２,  値３)
INSERT  INTO  ＠変数名  VALUES ( 値１,  値２,  値３)

 

UPDATE　＠変数名
SET　カラム名　＝　代入値
FROM　＠変数名
WHERE（条件）

 

#一時テーブル
・変数ではなく本物のテーブルが一時的に作られる
・セッションが有効な間は削除されない（エディタを閉じるまで有効）
・処理は低速だが大量のデータを一時的に扱う場合は効果的

 

CREATE　TABLE　＃テーブル名 {
    列名１　型名　オプショ
,   列名２　型名　オプション
}

 

エラー処理
・TRYの部分に実行したい処理を書く
→　もしその中でエラーがあったらCATCHに移動
CATCHにはエラーが起きた場合の処理を書く

 

BEGIN　TRY
　　処理
END　TRY
BEGIN　CATCH
　エラー処理
END　CATCH

 

###TRANSACTION　✖️　TRY CATCH　の組み合わせ

```sql
BEGIN  TRY
    BEGIN TRANSACTION
　　-- 処理
    COMMIT TRANSACTION
END TRY
BEGIN  CATCH
  ROLLBACK TRANSACTION
　-- エラー処理
END  CATCH
```

 
```sql
#ユーザー定義関数 
CREATE  FUNCTION  関数名
　　@引数１　データ型
,   @引数２　データ型
）
RETURNS　戻り値　データ型
AS
BEGIN
　　処理
　　RETURN　戻り値
END
GO
```
 

以下、お店の商品ごとに割引するという処理
idと金額を入れたら割引後の値段を出してくれるfnc_calc_discountという関数を作ります。
例：id１番は10%引きです。



 

テーブル作成などの処理は省略します。

```sql
CREATE FUNCTION [dbo].[fnc_calc_discount](
  @p_id int
, @p_price money
)
RETURNS money
AS
BEGIN
DECLARE
   @w_money money
 , @w_discount_rate money

SELECT
 @w_discount_rate = campaign_discount.discount
FROM campaign_discount
WHERE(campaign_discount = ISNULL(@p_id, ''))

SELECT @w_money = ISNULL(@p_price, 0) * (1 - ISNULL(@w_discount_rate, 0))

RETURN @money

--実行

SELECT dbo.fnc_discount_rate(1, 500) → 450
SELECT dbo.fnc_discount_rate(2, 500) → 400
SELECT dbo.fnc_discount_rate(3, 500) → 350
```
Firebase Cloud FirestoreをNode.jsから利用するスニペット


毎回忘れるのでメモです。

テストモード利用でチェック。

```bash
$ npm i firebase
```

```app.js
'use strict';

const firebase = require("firebase/app");
require("firebase/firestore");

//この辺をFirebaseの管理画面からコピペ
const firebaseConfig = {
  apiKey: "",
  authDomain: "",
  databaseURL: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: ""
};

const firebaseApp = firebase.initializeApp(firebaseConfig);

const db = firebaseApp.firestore();
db.collection('collectionName').get() //コレクション名を各々のモノに
 .then((snapshot) => {
  snapshot.forEach((doc) => console.log(doc.data()));
 })
 .catch((err) => console.log('Error getting documents', err));
```

```bash
$ node app.js
```
T-SQL  ストアドプロシージャ編

#ストアドプロシージャー

###ストアドプロシージャーとは
データベースに対する連続した複数の処理を１つのプログラムにまとめ、データとともに保存できるようにしたもの。

 
例えば、毎回SELECT文を書くのは手間なので、「こういう処理をしたい時のプログラム」としてあらかじめ作っておくことができる。

 

例：

「金額に現行の消費税を掛けて・・・」というクエリを毎回書くのは手間
   →「消費税を計算する処理」を作っておき保存。

 

イメージで言えば、様々な処理手順を有した箱がある
   →キーワードを入れればそれを加工して完成させてくれる。
   
 

消費税計算の例では、「日付」「金額」を入れれば税込金額が帰ってきます。

'2019/09/01',  1000  →　1080

'2019/10/01,   1000  →    1100

そうした「税率計算してくれる箱」「学生の情報を登録してくれる箱」「店舗の新情報を追加してくれる箱」とかをあらかじめ作っておけば、

金額いくら！　日付いつ！、　名前は〜　番号は〜、　商品名は〜　単価は〜

と引数だけ箱に入れてやればあとは自動（あらかじめ設定した処理）で加工して完成してくれます。

 

雛形：

IF  EXISTS ( SELECT ＊ FROM sys.objects  WHERE  object_id  =  OBJECT_ID
(N'[dbo].[ストアド名] )  AND  TYPE  in  (タイプ名)

 

BEGIN
    DROP   PROCEDURE  [dbo].[ストアド名]
END
GO

 

CREATE PROCEDURE   [dbo].[ストアド名]
    @引数　データ型　＝　初期値
AS
BEGIN
　処理
END
GO



TRANSACTIONやエラー処理はSELECTでは使わなくても大丈夫そうです。

UPDATEやDELETEなど途中で問題が起きたら困る処理には必要です。


```sql
IF EXISTS(SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[student_registration]') AND type in N'TF')

BEGIN
    DROP PROCEDURE [dbo].[student_registration]
END
GO

CREATE PROCEDURE [dbo].[student_registration](
  @p_id int = NULL
, @p_name varchar(50) = ''
)

AS
BEGIN
BEGIN TRY
    BEGIN TRANSACTION
    DECLARE @error_set table (
       id int NULL
     , message varchar(50) NULL
    )

    IF ISNULL(p@_id, 0) < 1
    BEGIN
    INSERT INTO @error_set(
     id
     , message
     )
    SELECT
      1
    , '学生番号が不正です'
    END
    ELSE
    BEGIN
    IF EXISTS(
       SELECT students.country_id
       FROM students
       WHERE (country_id = @p_id)
    )
    BEGIN
    INSERT INTO @error_set(
      id
    , message
    )
    SELECT
      2
    , '学生番号(' + CAST(@p_id AS varchar(8)) + ')は登録済みです'
    END
  END



IF ISNULL(@p_name, '') = ''
BEGIN
INSERT INTO error_set(
 id
 , message
 )
SELECT
3
 , '生徒名は必須入力です'
END

 
    IF EXISTS(
    SELECT error_set.id
    FROM @error_set AS error_set
     )
    BEGIN
    GOTO EXIT_SPC
    END

--更新

INSERT INTO students(
 id
 , name
 )
SELECT
   @p_id AS id
 , @ISNULL(@p_name, '') AS name

 EXIT_SPC: 
 IF NOT EXISTS(
 SELECT error_set.id
 FROM @error_set AS error_set
   )
BEGIN
COMMIT TRANSACTION
END
ELSE
BEGIN
ROLLBACK TRANSACTION
END
END TRY



BEGIN CATCH
INSERT INTO @error_set(
 id
 , message
 )
SELECT
ERROR_NUMBER()
 , '[Error] :' + CHAR(13) + CHAR(10) +
'Procedure: ' + ISNULL(ERROR_PROCEDURE(), '???') + CHAR(13) + CHAR(10) +
'Line: ' + ISNULL(CAST(ERROR_MESSAGE()), 'An unexpected error occured')
ROLLBACK TRANSACTION
END CATCH



--エラー内容返却

SELECT
 error_set.id AS id
 , error_set AS error_set
FROM @eeror_set AS error.SET
ORDER BY error_set.id ASC
END
GO
Safariでsvgへのrotateやtranslate表示が崩れる

[g4](https://www.g-g-g-g.games) のポモドーロタイマーのSafariでの表示がおかしかったのだが、どうやら、svg配下のtext要素にtransformが効かないみたいだった。

`<g>`タグで囲んでそれにtransformしたら解決した

https://stackoverflow.com/questions/48248512/svg-transform-rotate180-does-not-work-in-safari-11
SQL  トランザクション編

トランザクションは

「データベースに対する１つ以上の更新をまとめて呼ぶ時の名称」です。

 

トランザクションを使う目的は、処理の途中で予期せぬトラブルでコンピューターの処理が中断してしまった時に整合性を保たせるためです。

 

例えば、銀行の処理

Aさんの口座からBさんの口座に1万円を移す処理。

①Aさんの口座から１万円引く

↓

②Bさんの口座に１万円増やす

もし①が終わった段階で処理が滞ってしまったら、Aさんの口座は１万円減っているのにBさんの口座には１万円入っていないという不整合が起きてしまいます。

 

なので上記のような処理を「１セット」とし、途中で終わったらその処理が「なかったこと」にすればいいですね。そして、最後まで処理が終わって初めて「完了」になれば整合性は保たれます。

 

###・ACID

・Atomicity（原子性）

処理を一つの塊とし、「処理が全く行われない」OR「処理が完全に終わる」のいずれか。途中まではありえません。

###・Consistency（一貫性）

データベースにあらかじめ設定された制約は最後まで守られる。

###・Isolation（独立性）

割り込み禁止。トランザクション同士が互いに干渉を受けないことを保証。

###・Durability

永続性。トランザクションが終了したら、その時点でのデータの状態が保存されることを保証する。

 

BEGIN TRANSACTION;
処理１
処理２
COMMIT;
(処理がなかったことにするには、ROLLBACK）


--トランザクション

```sql
BEGIN TRANSACTION;

--処理１

UPDATE Shohin
SET hanbai_tanka = hanbai_tanka - 1000
WHERE shohin_mei = 'カッターシャツ';

--処理２

UPDATE Shohin
SET hanbai_tanka + 1000
WHERE shohin_mei = 'Tシャツ';

COMMIT;
```
 

トランザクションの処理に慣れる

 

自分の練習方法：

AをBに変更する場合、トランザクションを使わない場合、やっぱり戻したいと思ったら反対にBをAに変更する処理が必要になります。

トランザクションを使えば、BEGIN　TRANSACTIONを先に書き、

処理を書いていきます。あとはCOMMITさえしなければ、処理する前の状態に戻したい場合は、最後にROLLBACKを書けばOKです。

 

本番で失敗したくないので、練習用のデータベースで色々試してみるのはオススメです。
SQL  WHERE句に書けるもの、書けないもの

WHERE句はテーブルから情報を取得する際に、条件をつけることができます。

販売単価を取得したい、条件として価格が100円以上のものとしたい場合、

```sql
SELECT hanbai_tanka
FROM Shohin
WHERE hanbai_tanka > 100
```
 

いろんな条件で取得したい時、ついついWHERE句に全て詰め込みたいところですが、

WHERE句になんでも書くことができる訳ではありません。

 

WHERE句に書けるのは「条件式のみ」です。

真・偽の条件式で、もともとテーブルにある行のみです。

例えば、SUMは行の数字を足し合わせる、COUNTは行数を数えるなどテーブルに何か加工して別の数字として引数が帰ってきますので使えません。単価が３００円と５００円の２行のテーブルがあったとして、合計の８００円を取得したいということはできません。取得できるのは８００円と３００円のみです。

 

下記、WHERE句に書けるもの、書けないものをまとめます。

 

#書けるもの

 

###比較演算子

・IS NULL

・IS NOT NULL

・LIKE

・BETWEEM

・IN

・ANY

・ALL

・＝,  <,  >,  <=,  >=,  <>

###論理演算子

・AND

・OR

・NOT

 

#書けないもの

###四則演算

・＋,  ー,  ＊,  /

###下記の関数など

・SUM

・COUNT

・AVG

   etc...

 

関数でも、例えば下記のLENとかは使えます

```sql
SELECT shohin_mei
FROM Shohin
WHERE LEN(shohin_mei) > 3
```

上でも書きましたが、要は条件式になるかどうかです。
mysqlエラー備忘録


macのmysqlをmysql5.5から8へバージョンアップする際に下記のエラーがでた。
```
Mysql2::Error (Authentication plugin 'caching_sha2_password' cannot be loaded: dlopen(/usr/local/Cellar/mysql@5.5/5.5.60/lib/plugin/caching_sha2_password.so, 2): image not found):
```
下記のリンクを参考にエラー解消

```
update mysql.user set plugin = "mysql_native_password";
FLUSH PRIVILEGES;
```

https://qiita.com/yusuke_dev/items/7f0ca12ced72363f9448


webpackとforemanを使っているとエラーは解消されない。
下記のエラー。
```
Mysql2::Error::ConnectionError: Access denied for user 'root'@'localhost' (using password: YES)
```
再度、元に戻す。


```
update mysql.user set plugin = "caching_sha2_password";
FLUSH PRIVILEGES;
```
もう一度、起動させてら何故かmysqlのエラーは解消された。
SQL  関数まとめ編（SQL server向け）

SQLを勉強し始めて、よく目にする関数をまとめていきます。

RDBMSによって使える関数が異なりますが、SQL Server向けの関数をまとめます。

 

#集計関数

 

###AVG　平均を計算

```sql
SELECT AVG(販売単価) AS 平均単価
FROM Shohin
```
 

###COUNT　行数をカウント

```sql
SELECT COUNT(販売単価) AS 単価の行数
FROM Shohin
```
 

###MAX　最大値を得る

```sql
SELECT MAX(販売単価) AS 最も高い単価商品
FROM Shohin
```
 

###MIN　最小値を得る

```sql
SELECT MIN(販売単価) AS 最も低い単価商品
FROM Shohin
```
 

###SUM　合計値

```sql
SELECT MIN(売上) AS 売上合計
FROM Shohin
```
 

 

#文字列関数

 

###CONCAT　文字列結合

```sql
SELECT CONCAT(last_name, '', full_name)
FROM Staff
```
 

###LEN　文字列長を得る

```sql
SELECT LEN(商品名） AS 商品名文字数
FROM Shohin
```
 
```sql
SUBSTRING　文字列の部分抽出
SUBSTRING（切り取り文字列,  切り取り開始位置,  切り取り文字数）
```
```sql
SELECT SUBSTRING('あいうえお’, 2, ３)
-- いうえ

--'あいうえお'の２文字目から３文字切り取る
```
 

 

#日付関数

 

###CURRENT_TIMESTAMP　現在日時を得る

```sql
SELECT CURRENT_TIMESTAMP
```
 

###FORMAT　日付時刻の整形

```sql
SELECT FORMAT(GETDATE(), 'yyyyMMdd')
```
 

 

#変換関数

 

###CAST　型変換を行う

CAST(値  AS  変換後のデータ)

数値型　→　文字列型

```sql
SELECT CAST(100 AS VARCHAR(10))
```

文字列型　→　日付型

```sql
SELECT CAST('2018-01-01' AS DATE)
```
 

###CONVERT　型変換を行う

CONVERT（変換後のデータ, 変換したい値）

```sql
SELECT CONVERT(decimal, '10.1')
```
 

###COALESCE　NULLでない最初の値を返す

COALESCE（列や式１, 列や式２・・・）

```sql
SELECT COALESCE('A', 'B', 'C')
--A
```
```sql
SELECT COALESCE(NULL, 'B', 'C')
--B
```

###COALESCE（列や式,  NULLの代替値）

```sql
SELECT COALESCE(hanbai_tanka, 0) AS 販売単価
```

ISNULLもNULL値の変換ができます

流れはCOALESCEと同じです。

 

###REPLACE　文字列を置換

REPLACE（対象文字列,  この文字を,  これに置き換える）

```sql
SELECT REPLACE('YAMADA', 'DA', 'ZAKI')
--YAMAZAKI
```
 

 
#算術関数

 

ABS　絶対値を取得

ABS(数値）

```sql
SELECT ABS(-50)
--50
```
 

###ROUND　丸め処理

・ROUND(四捨五入したい数字）

・ROUND（四捨五入したい数字,  小数点第何位まで）

```sql
SELECT ROUND(10.234, 2)
--10.230
```

POWER　べき乗

POWER（数値,  〜乗）

```sql
SELECT POWER(3, 4)
--81
```
 

 

#分析関数

 

###RANK　順位を決める

対象列,  RANK（） OVER（ORDER  BY  対象列  DESC）

```sql
SELECT tanka RANK OVER (ORDER BY tanka DESC)
FROM Shohin
```
EC-CUBE4 Twigで現在設定されている税率を出す方法

```php
{% set taxRule = repository('\\Eccube\\Entity\\TaxRule') %}
{% set nowTax = taxRule.getByRule().tax_rate / 100 %}
{{ dump(nowTax) }} // 0.08 （9/14 現在）
```

何かに使えるかもしれないので置いておきますね。