OmniAICreator/Qiita-1.07M huggingface dataset:
iOS上で途切れた円(曲線)をアニメーション表示

## 概要
ある日、実装で途切れた円のを描く必要が出てきた。しかも場合によってはそれをアニメーション表示する必要があるとか…。

今まで線を描くアニメーションをやった経験が記憶上にはなかったので、調べるも大体正円や楕円、円グラフの描き方だったりで、途切れた円(曲線)の描き方とそれをアニメーションする方法を探し当てるのに苦労した。

色々検索してなんとか目星ついて最終的に出来たのがこれ↓
![output.gif](https://qiita-image-store.s3.amazonaws.com/0/154832/da88409f-d698-7aaf-d1e9-6066a69d8b4e.gif)

全体を100%とし、内部で入力した数値のパーセンテージをアニメーションで表示している

## 実装内容
* 独自classのみ記載したgist
https://gist.github.com/aryzae/6c09ba88fa9249a935ce6361e6587414

* 動作確認用repository(Xcode10.1)
https://github.com/aryzae/OddCircleAnimation

### 解説
#### 途切れた円(曲線)を描く
下記を使ってUIBezierPathを作る。

注意点として、

- 角度はradianで指定する必要があるので、`degree * CGFloat.pi / 180`で計算する必要がある
- `.close()`を呼んでUIBezierPathを閉じてはいけない

```swift
/// 円形の線を描く
///
/// - Parameters:
///   - arcCenter: 円の中心点
///   - radius: 半径
///   - startAngle: 開始角度(radianで指定)
///   - endAngle: 終了角度(radianで指定)
///   - clockwise: trueは時計周り、falseは反時計回り
UIBezierPath(arcCenter: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool)
```

#### UIBezierPathをlayerに渡してアニメションさせる

CAShapeLayerのプロパティ`.path`に先ほどのUIBezierPathの`.cgPath`を渡し、`"strokeEnd"`を指定してCABasicAnimationを作成する。
`"strokeEnd"`を指定することで線の描画をアニメーションとして表示できる。(自分はここでつまずいた)

あとは、アニメーションに設定をよしなに好みでつけ、`layer`に対して`animation`を追加してやると冒頭のようなアニメーションができる。

```swift
// アニメーションさせるlayer作成
let layer = CAShapeLayer()
layer.path = bezierPath.cgPath

// アニメーションの設定
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = 1.5
animation.fromValue = 0.0
animation.toValue = 1.0
animation.timingFunction = CAMediaTimingFunction(name: .easeOut)
animation.fillMode = .forwards
animation.isRemovedOnCompletion = false
layer.add(animation, forKey: animation.keyPath)
```
digdag の自前ビルド (macOS編)


EDIT: (2019.03.25) docker を使う方が紛れが少なくてオススメです => [digdag の自前ビルド (docker編)](https://qiita.com/sonots/items/626b5d08b5876a9c3e35)

# 事前準備

Java8 と node.js 8.x が必要

## macOS

```bash
brew tap caskroom/cask
brew tap caskroom/versions
brew cask install java8
brew install nodejs npm
```

トラブルシューティング: nodejs で digdag UI のビルドが走る時に

```
xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
```

というエラーが出たので command line tools を一度削除して、App Store から Xcode を入れ直した。サイズがでかい(> 5GB)しインストールに時間がかかるので辛い...

## Ubuntu

```bash
$ sudo apt install -y openjdk-8-jre-headless
$ sudo apt install -y nodejs npm
```

# ビルド

```
$ ./gradlew cli
```

pkg 下にできあがるのでそれを実行すれば起動する。実行ファイル形式になっているのでそのまま実行できる。

```
$ pkg/digdag-{VERSION}.jar
```

TODO: この jar は shadowJar なる全詰めのいわゆる fat jar。作るのに 10 sec ぐらいかかってつらいのでスキップして実行する手段があったら教えてほしい

# インストール

インストールはこの jar を digdag という名前で PATH が通っている場所におけば良い

```
sudo mv pkg/digdag-{VERSION}-SNAPSHOT.jar /usr/local/bin/digdag
```

# テスト


テスト対象を絞り込んで受け入れテストを流す

```
$ env CI_ACCEPTANCE_TEST=true ./gradlew digdag-tests:test --info --tests acceptance.RbIT
```

テスト対象を絞り込んで単体テストを流す

```
$ ./gradlew digdag-core:test --tests io.digdag.core.schedule.ScheduleExecutorTest
```
UniRX使ってUnityでずっと音を垂れ流す

```csharp

// Intervalで垂れ流す処理
IObservable<long> PlaySeObservable(double _time)
{
    return Observable.Interval(TimeSpan.FromSeconds(_time));
}
```
音の再生のくわしいやり方とかは、
他で調べてね

```csharp

[SerializeField]
private AudioClip audioClip;
[SerializeField]
private AudioSource audioSource;

void Start()
{
    float seTime = audioClip.length;
    PlaySeObservable(seTime).Subscribe(_ => {
        // 垂れ流せ！
        audioSource.PlayOneShot(audioClip);
    });
}
```

ずっと垂れ流しでうるせぇなぁと思うので、

```csharp

bool flag;
IObservable<long> PlaySeObservable(double _time)
{
    return Observable.Interval(TimeSpan.FromSeconds(_time)).TakeWhile(_ => !flag);
}
```

なんかのフラグをTrueにしたら、とめるようにする

```csharp

// onclickのEventとか
public void OnClick(){
    // 止まれ
    flag = true;
}
```

しかしながら、
ループ再生したいなら、
AudioSourceコンポーネントのloopオプションにチェックいれて、
ループ設定すればいいだけですね
与えられたビット列のビットの組み合わせをすべて列挙

# はじめに

あるビット列が与えられた時、その全てのビットについて「立っているか、立っていないか」の状態の組み合わせを列挙したい。

例えば`00100110`が入力された時、3ビット立っているので、それぞれが立っているか、立っていないかで2**3=8通りのビット列、つまり

```sh
00100110
00000110
00100010
00000010
00100100
00000100
00100000
00000000
```

が出力されて欲しい。ビット演算書いてて、同じようなコードを「あれ？これどうやって書くんだっけ？」と毎回考えてる気がしたので覚書として残しておく。

# 実装例

C++で書くならこんな感じになる。

```c++
template <class T> void search(T s1, T s2) {
  if (s2 == 0) {
    show(s1);//これが列挙したいビット列
    return;
  }
  T lsb = (s2 & -s2);
  s2 ^= lsb;
  search(s1, s2);
  T s3 = s1 ^ lsb;
  search(s3, s2);
}
```

これに、`s1`と`s2`に同じ初期値を与えて呼んでやればよい。ソースコード全体はこんな感じ。

```cpp:test.cpp
#include <cstdint>
#include <iostream>

template <class T> void show(T v) {
  size_t size = sizeof(T) * 8;
  for (size_t i = 0; i < size; i++) {
    std::cout << ((v & (1 << (size - i - 1))) ? 1 : 0);
  }
  std::cout << std::endl;
}

template <class T> void search(T s1, T s2) {
  if (s2 == 0) {
    show(s1);
    return;
  }
  T lsb = (s2 & -s2);
  s2 ^= lsb;
  search(s1, s2);
  T s3 = s1 ^ lsb;
  search(s3, s2);
}

int main() {
  uint8_t s = 38;
  search(s, s);
}
```

実行例。

```sh
$ g++ test.cpp
$ ./a.out
00100110
00000110
00100010
00000010
00100100
00000100
00100000
00000000
```

# 動作原理

`search`に渡される二つのビット列のうち、`s1`は出力したいビット列の途中経過、`s2`は「まだチェックしていないビットの集合」を表している。

`search`は、まず渡されたビット列のうち、今回消すか残すか検討するビット位置を

```c++
T lsb = (s2 & -s2);
```

で得る。`(s2 & -s2)`は、`s2`のLSBを得る有名なビット演算。`s2`からこのビットを消しておく。

```c++
s2 ^= lsb;
```

そして、このビットを「消す場合」と「消さない場合」の二通りで分岐する。


```c++
search(s1, s2); //このビットを消さない場合
T s3 = s1 ^ lsb;
search(s3, s2); //このビットを消す場合
```

こうして再帰していき、`s2`が0になったら、「すべての立っているビットについて検討を終えた」ということなので、その時の`s1`を出力すれば良い。

例えば`s=6`の場合はこんな感じになる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79744/abbc7af2-36ba-46db-8a81-2a16c65e4519.png)

要するに、検討するビットすべてをスキャンし、それぞれについて「消す」か「消さないか」の二通りで分岐していく形になっている。

# まとめ

任意のビット列について、それぞれのビットのすべての組み合わせを列挙するコードを紹介した[^1]。

[^1]: これ、だいぶ前に誰かに教わったのだが、それが誰だったか覚えていない。おそらくherumiさんだと思われるが確証がない。
NetlifyでGitHubに公開されているプロダクトをcloneしたい場合の覚書

ボイラープレートとか、SPAのモックとか、「自分のサーバーにクローンして使ってくださいね」となるやつあるじゃないですか。

ああいうのをNetlifyで配布する時、GitHubに公開されているものであれば、以下のようなURLで簡単にリンクが作れます。

```
https://app.netlify.com/start/deploy?repository=https://github.com/YOUR_NAME/REPO_NAME
```

Gatsbyのスターターテンプレートを見てる時に発見しました。
例：https://app.netlify.com/start/deploy?repository=https://github.com/LekoArts/gatsby-starter-portfolio-cara

今の所こういう使い方をしたいケースがないので、とりあえず覚書だけ。
ラズパイ: 緊急時用イメージ

buildrootで、緊急時用のイメージを作成

# 概要
こんなときに。

* ラズパイが起動しなくなってしまった。/ ログインできない。
    * `fstab`を間違って編集してしまって、起動しない
    * ユーザ(`pi`)のパスワード忘れた。

* 近くに、ext4(Linuxのファイルシステム)を読み出しできるPCがない。
    * ラズパイのSDカードのFAT領域を編集するPCはある。

---
- buildrootで作ったイメージです。
- 有線LANが接続してあれば、DHCPでIPを取りに行き、ssh(=dropbear)でログインできます


### 対象外
- 削除ファイル / まちがってフォーマットしてしまった など、そういう復旧のものは、できませんね


# 環境
- ラズパイ3B/3B+ のみ(2019-01-30現在)
- `rpi3-br-kernel-2019-0129-1.img` (23.5MB)
    - ユーザ名: `root`
    - パスワード: `raspberry`


# 手順
1. イメージファイルのダウンロード: [rpi3-br-kernel-2019-0129-1.img](https://github.com/mt08xx/files/raw/test/rpi3-br-kernel-2019-0129-1.img)
2. ファイル名を`rpi3-br-kernel.img`に変更
3. ラズパイのSDカードのFAT(`BOOT`)のところへ、コピーするのだが、そのままだとディスクフルで書き込めないので、(ラズパイ3Bで使用しない)`kernel.img`を消してから、コピーする。
4. `config.txt`の編集して、以下をファイルの最後に追記する

	```
	kernel=rpi3-br-kernel.img
	```

5. 電源ON

6. 起動したら、とりあえず、SDカードのマウント。

	```bash
	mkdir /mnt/1
	mkdir /mnt/2
	mount /dev/mmcblk0p1 /mnt/1
	mount /dev/mmcblk0p2 /mnt/2
	```
     `/mnt/1` に `/boot`、`/mnt/2`に `/` がマウントされます



あとは、 

- `vi /mnt/2/etc/fstab` で、`fstab`の編集のしたり、

- `chroot /mnt/2` とやって、`passwd pi` とかで、パスワードリセット

など、できると思います。


# その他
- buildroot 2018.11　ベースです
- [Buildrootでルートファイルシステムを構築するときに必ずすること](https://qiita.com/tetsu_koba/items/54d0573afe407592aed0) <br> こちらの記事にそって、dhcp, dropbear, avahiを追加してます。
 
- とりあえず、テストということで、なにかまずそうであれば、ファイルを消します。
- FAT(`BOOT`) 領域が壊れているときは、firmwareのファイルが必要になります。
OkHttpでAPIのスタブと通信してみた

## はじめに
Androidのアプリ開発でAPIとスタブを通信するのに、今まではリクエストURLなどを切り替えて対応しておりました。
今回、OkHttpのInterceptor機能を使うと簡単に向き先を切り替えることが出来る事を知ったので記事にまとめました。

Interceptorを使うと、アプリケーションとOkHttpの間に、任意の処理を割り込むことが出来る機能です。
https://github.com/square/okhttp/wiki/Interceptors

## スタブ仕様
今回はAssetsからレスポンスを取得したいので、
APIと同じレスポンスフォーマットのJSONファイルを用意する。

<img width="175" alt="stub.png" src="https://qiita-image-store.s3.amazonaws.com/0/112186/a677fee4-2476-1d46-fa36-23c202af9fb1.png">


## 実装
#### 1. スタブ用のInterceptorを実装する

```kotlin
class StubInterceptor(private val context: Context) : Interceptor {

    companion object {
        private val RESPONSE_TYPE = MediaType.parse("application/json; charset=utf-8")
    }

    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        val response = chain.proceed(request)
        var code = 200
        val body = try {
            loadFromAssets(request)
        } catch (e: FileNotFoundException) {
            // File not found
            code = 404
            e.toString()
        }
        val responseBody = ResponseBody.create(RESPONSE_TYPE, body)
        return response.newBuilder()
            .code(code)
            .body(responseBody)
            .build()
    }

    private fun loadFromAssets(request: Request): String {
        val url = request.url().url().path.substring(1)
        return context.assets.open("mock/$url.json").use {
            it.reader().readText()
        }
    }
}
```

#### 2.クライアントにStubInterceptorを追加する

```kotlin
val client = OkHttpClient().newBuilder().apply {
    addInterceptor(StubInterceptor(context))
}
```

#### 3.呼び出し元

```kotlin

val requestUrl = "https://xxxxxxxx/api/token"  // <- "token.json" をAssetsに配置する
val request = Request.Builder()
    .url(requestUrl)
    .get()
    .build()
val response = client.newCall(request).execute()
```

#### Retrofitと連携する場合

```kotlin
private val retrofit = Retrofit.Builder()
    .baseUrl("https://xxxxxxxx/")
    .client(client)  // OkHttpクライアントを設定する
    .addConverterFactory(GsonConverterFactory.create())
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    .build()
```

以上、意外と簡単に実装できる。
本番でマスタデータだけを更新したい。

## 困っていること
railsであるサービスを立ち上げたが既にDBに値が入ってる本番環境で
マスタデータのみを更新したいと思ったが
rails db:migrate:resetしてrails db:seedをしてしまうと
マスタデータ以外は全て消えてしまうのでどうしようと困っていた。

## gem
今回見つけたgemはseed_fuというもの。
これはseedデータを挿入してよしなにしてくれるもの？

## やったこと
まずgemファイルに以下を追加し、bundle install。

```Gemfile
gem 'seed-fu'
```

そのあとroot直下のdbの中にfixturesディレクトリを作成。
さらにfixturesディレクトリの中にdevelopmentとproductionディレクトリを作成。(ちなみに自分はこの二つは特に必要なかったので作成しなかった。)

fixturesディレクトリ配下に置いてあるseedを見てくれるらしい。
productionだったらproduction環境でのみ動くらしい。

自分は
fixturesディレクトリ直下にuser.rbというファイルを作成し、
以下のように配置した。

```rb
User.seed do |s|
  s.id = 1
  s.name = "山田太郎"
end
```

まあ、これだとちょっと多い時に長くなってしまうので

```rb
User.seed(
  { id: 1, name: '山田太郎' },
  { id: 2, name: '山田花子' }
)
```

こんな感じがいいよと教えてもらった。

あとはコマンドで以下を叩く。

```terminal
$rake db:seed_fu
```

そうすると本番環境でも、どの環境でも
fixtures配下に置いてあるものだけ更新された！
password_hash()ではパスワードが切り詰められる

## 元ネタ

[72文字を超えるパスワードを許容したい場合、password-hashを使うべきではない？ - stack overflow](https://ja.stackoverflow.com/questions/7133/72%E6%96%87%E5%AD%97%E3%82%92%E8%B6%85%E3%81%88%E3%82%8B%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E3%82%92%E8%A8%B1%E5%AE%B9%E3%81%97%E3%81%9F%E3%81%84%E5%A0%B4%E5%90%88-password-hash%E3%82%92%E4%BD%BF%E3%81%86%E3%81%B9%E3%81%8D%E3%81%A7%E3%81%AF%E3%81%AA%E3%81%84)
[password_hash()の重要な制限](https://blog.ohgaki.net/password_hash-important-limitation)
[PHPマニュアル](http://php.net/manual/ja/function.password-hash.php)
> PASSWORD_BCRYPT をアルゴリズムに指定すると、 password が最大 72 文字までに切り詰められます。

ほんとぉ？

## 試してみた

```
# php -v
PHP 7.2.7 (cli) (built: Jun 20 2018 08:21:26) ( NTS )
```

```php
<?php
$pass72 = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst";
//strlen($pass72) => 72
$pass73 = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu";
//strlen($pass73) => 73

$hash73 = password_hash($pass73,PASSWORD_DEFAULT);

password_verify($pass72,$hash73);
// bool(true) <- !!!
```
というように、**73** 文字のパスワードのハッシュと **72** 文字のパスワードが同じものとみなされてしまいました。
これは`PASSWORD_DEFAULT`の値が`PASSWORD_BCRYPT`、つまり`CRYPT_BLOWFISH `を使っているから(？)起こるらしいです。
少なくともPHP7.1以下では`BCRYPT`以外使えないので、必ず起こります。（PHP7.2からは標準で`Argon2i`が使える。）

## 実用上問題なさそう
ところで、上のコードは

```php
password_verify($pass73,$hash73);
// bool(true) <- !!!
```

でもあります。つまり`password_verify()`でも同様に切り詰められてから比較されるので、ユーザが72文字以上のパスワードを入力しても実用上問題はなさそうです。（ただし、90文字のパスワードを入力しても、72文字目までが同じ別のパスワードでクラックできる。）
下手にハッシュをはさんだりすると[脆弱性の原因にもなりかねない](https://blog.tokumaru.org/2019/02/caution-bcrypt-with-sha512.html)ので、とりあえずは72文字制限を受け入れておきましょう。どうしても気持ち悪いときはPHP7.2から`password_hash`の第二引数に`PASSWORD_ARGON2I`が[使えるようになっている](http://mikanmarusan.hatenablog.com/entry/2017/12/22/125252)ので、そっちを使いましょう。

### おわりに
今まで何も気にせず問題なく使ってきたのですが、知ってしまうと気持ち悪い挙動なので、今後は状況を見つつ`PASSWORD_ARGON2I`を使っていきたい感じ
slickカルーセルのcenterModeで中央以外を透過にした場合に2周目からがたつく

昨日Twitterのタイムラインで下記を見かけました
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">slickのがたつきの件、NxWorldさんのサイトのサンプルでもなってるからやっぱり自分だけじゃないな。／<a href="https://t.co/EJ5swAVGAu">https://t.co/EJ5swAVGAu</a></p>&mdash; ヤマシタレイコ｜OOOPEN (@OOOPEN_jp) <a href="https://twitter.com/OOOPEN_jp/status/1090502760288595968?ref_src=twsrc%5Etfw">January 30, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

以前このプラグインを使った時に同じような不具合に直面し、自力で何とかした経験があるので、同じように困っている方の参考になれば。。

#現象
[ここ](https://www.nxworld.net/example/slick-examples/current-class-examples.html)のスライドのNextとかPrevを押すと分かりますが、2周目の最初のスライドに来た時と、最初のスライドから最後のスライドに戻る時にがたつきます。
これは`.slick-current`というクラスが来た時に透過にしたり大きくしたりしているのですが、がたつくパターンの場合クラスが付与されるまでにDOMの操作が発生しその処理時間の差でがたつくのだと思います。

#対処方法

###HTML
HTMLは特に普通と一緒です。

```html:index.html
<div class="slider" id="js-slider">
    <div class="slider__item"><img src="http://lorempixel.com/output/business-q-c-800-480-4.jpg" width="800" height="480" alt=""></div>
    <div class="slider__item"><img src="http://lorempixel.com/output/business-q-c-800-480-6.jpg" width="800" height="480" alt=""></div>
    <div class="slider__item"><img src="http://lorempixel.com/output/business-q-c-800-480-7.jpg" width="800" height="480" alt=""></div>
</div>
```

###JavaScript
js側で小細工をします。
不具合があっても同じように透過させたりしたいのであれば、

- 最初のスライドから最後のスライドに移動する際に最後のスライドに対して`.slick-current`クラスが付与される時と同じ処理をするクラスを付与する
- 最後のスライドから最初のスライドに移動する際に最初のスライドに対して`.slick-current`クラスが付与される時と同じ処理をするクラスを付与する

という感じにすればいけそうな気がします。
移動する際の処理は、slickのイベントである`beforeChange`で出来ます。

```js:script.js
const $slider = $("#js-slider");

// 左右の透過の2周目ががたつく対応
$slider.on("beforeChange", (event, slick, currentSlide, nextSlide) => {
  $slider.find(".slick-slide").each((index, el) => {
    const $this = $(el),
      slickindex = $this.attr("data-slick-index");
    if (nextSlide == slick.slideCount - 1 && currentSlide == 0) {
      // 現在のスライドが最初のスライドでそこから最後のスライドに戻る場合
      if (slickindex == "-1") {
        // 最後のスライドに対してクラスを付与
        $this.addClass("is-active-next");
      } else {
        // それ以外は削除
        $this.removeClass("is-active-next");
      }
    } else if (nextSlide == 0) {
      // 次のスライドが最初のスライドの場合
      if (slickindex == slick.slideCount) {
        // 最初のスライドに対してクラスを付与
        $this.addClass("is-active-next");
      } else {
        // それ以外は削除
        $this.removeClass("is-active-next");
      }
    } else {
      // それ以外は削除
      $this.removeClass("is-active-next");
    }
  });
});

// スライダー
$slider.slick({
  centerMode: true,
  slidesToShow: 1,
  centerPadding: "20%",
  speed: 500,
  arrows: true,
  dots: true
});
```

###CSS
そして、`is-active-next`クラスに対してcss側で`slick-current`クラスと同じ処理をします。

```css:style.css

.slider__item {
  opacity: 0.34;
  transition: opacity 0.4s;
}
.slick-slide.slick-current .slider__item,
.slick-slide.is-active-next .slider__item {
  opacity: 1;
}
```

これで多分うまくいく(はず)....

###サンプル
CodePenにサンプルを置いておきましたので実際の動作は[こちら](https://codepen.io/daipdaip/full/mvRWwP)をご覧ください！
Wildfly+H2Databaseのアプリケーションサーバを冗長化

H2DatabaseをEmbedded型で利用しているアプリケーションをWildflyにシングルトンデプロイさせて冗長化する。
GlusterFSでミラーリング領域を作成し、その領域をデータベースの保存先として使用する。


######GlusterFSのインストールと領域の確保

想定するパラメータ
　Wildflyのベースディレクトリ(WILDFLY_HOME): /opt/wildfly
　H2Databaseの保存先: /opt/wildfly/h2database
　Wildflyの起動user/group: wildfly/wildfly
　GlusterFSに割り当てる領域: /var/glusterfs

```
[root@host1]# yum -y install centos-release-gluster
[root@host1]# yum -y install glusterfs-server
[root@host1]# systemctl stop firewalld
[root@host1]# systemctl disable firewalld
[root@host1]# systemctl start glusterd
[root@host1]# systemctl enable glusterd
[root@host1]# mkdir /var/glusterfs
[root@host1]# chown -R wildfly.wildfly /var/glusterfs
[root@host1]# mkdir /opt/wildfly/h2database
[root@host1]# chown -R wildfly.wildfly /opt/wildfly/h2database
```

```
[root@host2]# yum -y install centos-release-gluster
[root@host2]# yum -y install glusterfs-server
[root@host2]# systemctl stop firewalld
[root@host2]# systemctl disable firewalld
[root@host2]# systemctl start glusterd
[root@host2]# systemctl enable glusterd
[root@host2]# mkdir /var/glusterfs
[root@host2]# chown -R wildfly.wildfly /var/glusterfs
[root@host2]# mkdir /opt/wildfly/h2database
[root@host2]# chown -R wildfly.wildfly /opt/wildfly/h2database
```

######Gluster Volumeの作成
```
[root@host1]# gluster peer probe host2
[root@host1]# gluster volume create h2database replica 2 host1:/var/glusterfs host2:/var/glusterfs force
[root@host1]# gluster volume start h2database
```

######Gluster Volumeのマウント
```:/etc/fstab
localhost:/h2database /opt/wildfly/h2database glusterfs defaults,_netdev,nofail 0 0
```
ここでOSをリブートして、ミラーリング動作を確認してみる。
host1,host2それぞれの端末で

```
[root@host1]# touch /opt/wildfly/h2database/test.txt
```
```
[root@host2]# tail -f /opt/wildfly/h2database/test.txt
```
としておき

```
[root@host1]# echo "test" >> /opt/wildfly/h2database/test.txt
```
した時に、host2側に反映されればOK。
テストが完了したら、/opt/wildfly/h2database/test.txt は削除しておく。

######H2Databaseの接続URL

```
jdbc:h2:file:~/h2database/(Database Name)
```

######WebContent/META-INFにsingleton-deployment.xmlを配置

```:singleton-deployment.xml
<?xml version="1.0" encoding="UTF-8"?>
<singleton-deployment xmlns="urn:jboss:singleton-deployment:1.0"/>
```

######動作テスト
上記のように作成したアプリケーションをhost1,host2の順で、両方のサーバにデプロイする。
(Wildflyのconfigはstandalone(-full)-ha.xmlで立ち上げ)

host1のサーバでのみ動作していること(host2側にアクセスした場合には404 Not Found)を確認の上、host1を停止させた時にhost2側でアプリケーションが立ち上がってくることを確認する。

```
[root@host2]# tail -f /var/log/wildfly/server.log
```
```
[root@host1]# systemctl stop wildfly
```
host2側でシングルトンアプリが立ち上がるとともに、H2Databaseのjdbcドライバがデプロイされてhost2側で動作を継続する。

```:/var/log/wildfly/server.log
2019-01-31 17:39:41,143 INFO  [org.wildfly.clustering.server] (DistributedSingletonService - 1) WFLYCLSV0003: host2 elected as the singleton provider of the jboss.deployment.unit."XXXXX.war".installer service
....
2019-01-31 17:39:43,575 INFO  [org.jboss.as.connector.deployers.jdbc] (MSC service thread 1-2) WFLYJCA0004: Deploying JDBC-compliant driver class org.h2.Driver (version 1.4)
```
あとはkeepalivedでロードバランスするなり何なりしてやれば冗長化の完了♪
htmlのセレクトリストをfirefoxで選択したときに文字が見えない状態になる現象への対応

##現象
firefoxでhtmlのセレクトリストを選択したときに、文字が見えず真っ白な状態になりました（説明下手でごめんなさい）。
本来なら選択した後には自分が選択したテキストだけが見えるようになりますが、真っ白で自分が何を選択したのかわからないという状態です。
一度どこかをクリックすれば文字が見えるようになります。
ただ、値としてはそれが正しく選択されている状態になっているので問題はなかったのですが、できれば真っ白にならず選択したテキストがちゃんと表示されている状態にしたいと思い対応しました。

なぜこういうことになっているのかはわからないのですが、私が対応した方法を紹介します。

環境
firefox version 64.0.2
macOs Mojave version 10.14.2

##対応
```catsList.html
<select id="list">
  <option class="cats" value="blackcat">Black Cat</option>
  <option class="cats" value="whitecat">White Cat</option>
  <option class="cats" value="calicocat">Calico Cat</option>
  <option class="cats" value="americanshorthair">American Shorthair</option>
  <option class="cats" value="russianblue">Russian Blue</option>
  <option class="cats" value="abyssinian">Abyssinian</option>
  <option class="cats" value="siamese">Siamese</option>
</select>
```

```catsList.js
    $(document).on('change', "#list", function (e) {
    	$(this).css('color', '#000');
    });
```

ただ、セレクトリストが変更された時にテキストの色を黒くしているだけです。
私の環境ではこれでうまくいきました。

これにたどり着く前にいくつか試行錯誤して、全然わからない。。。:innocent:状態になってふと思いついてやってみたらできました。

ネットで検索しても方法が見当たらなかったので（探し方が悪いのかも。。。）備忘録の意味も込めての投稿です。
error:Type '' does not conform to protocol 'Decodable' & 'Encodable'

#はじめに
jsonをパースする際にとても便利なCodableプロトコルでの分かりづらいエラーをメモ。
#改善
こんな感じで起きる。
![fullsizeoutput_9b.jpeg](https://qiita-image-store.s3.amazonaws.com/0/292456/18aa58ab-c273-9f17-32d5-fff9a456abf3.jpeg)
明確な型定義がされていないと起こるらしいので、これをString型に定義する。

```swift:ViewController.swift
struct Item: Codable {
        let itemName: String
    }
```
これでエラーはなくなり無事成功。
[iOS] UIBarButtonItemの画像が青くなる件の対処方法

## 概要
<img width="374" alt="Screen Shot 2019-01-31 at 16.50.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/122091/c67bf708-6e73-0ada-82e4-4479643c8571.png">
上の図の星マークのように、UIBarButtonItem等で設置した画像が青で塗り潰されてしまう件の対処方法を書き留めておきます。

## コード経由
UIImageをセットするタイミングでRenderingModeも同時に指定しておくことでオリジナルの状態で描画させることができます。

```swift
    func setImageWithRenderingMode(image: UIImage) {
        starButton.image = image.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
    }
```

## Assets経由
Assets.xcassetsから該当の画像を選択し、右側のAttributes Inspectorを表示してRender Asの部分を"Original Image"に設定しておくことで、常にオリジナルの状態で表示させることも可能です。
ただし、この方法を適用した画像をタブのアイコン等に用いる場合、選択/非選択の状態で自動的に色を切り替えることができなくなるため注意が必要です。
<img width="253" alt="Screen Shot 2019-01-31 at 16.58.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/122091/f0496cd7-1909-098d-49cb-ed41ce5e0d18.png">
【SQL】基本のまとめ2

#内容
SQLを勉強し始めたので、これまでに学んだ知識をまとめます。
長くなったので[**【SQL】基本のまとめ1**](https://qiita.com/kikuri426/items/7f0ac73798f2ef8faf8f)とこの記事に分けました。

*この記事の内容*

 - 便利なコマンド
    - AND, GROUP BY, HAVING, DISTINCT
 - 結果を見やすくするコマンド
    - ORDER BY, LIKE, LIMIT, AS
 - より多くのデータを使うためのコマンド
    - サブクエリ, JOIN

*以下の内容を知りたい方は[【SQL】基本のまとめ1](https://qiita.com/kikuri426/items/7f0ac73798f2ef8faf8f)へ*

 - SQLとは
 - データベース内の名称
 - 基本のコマンド
    - SELECT, FROM, WHERE, NOT
 - 四則演算や集計のコマンド
    - AVG, SUM, COUNT, MIN, MAX

##下の例で用いるデータのテーブル
**cakes**

|       id      |type|      name     |     price    |cost |
|:-------------:|:----:|:-------------:|:-------------:|:---:|
|        1      |ケーキ|ショートケーキ    | 300         |  100|
|        2      |ケーキ|モンブラン        | 400         |200|
|        3      |ケーキ|チーズケーキ      |200           |50|
|        4      |タルト|フルーツタルト    | 400        |300|
|5|ゼリー| コーヒーゼリー| 200|50|
|6|タルト|チョコレートタルト|300|70|


**sales_january**

|cake_id      |total| 
|:-------------:|:----:|
|        1      |56|
|        2      |80|
|        3      |35|
|        4      |67|
|5|98
|6|23


##便利なコマンド
**条件を複数入れる** 
- かつ`AND` または`OR`
 : 300円以下のケーキを知りたい


```SQL
SELECT name
FROM cakes
WHERE type = "ケーキ"　AND price <= 300;
```

**グループ別にデータを見る** 
- `GROUP BY`
 : 商品の種類別の合計金額を知りたい

```SQL
SELECT type, SUM(price)
FROM cakes
GROUP BY type;
```

**グループ別に条件にあったデータを見る** 
- `HAVING`
 : 平均コストが150円以下の商品タイプを知りたい

```SQL
SELECT type, AVG(cost)
FROM cakes
GROUP BY type
HAVING AVG(cost) <= 150;
```

**重複なくデータを取り出す** 
- `DISTINCT(カラム名)`
 : どんな種類の商品があるか知りたい

```SQL
SELECT DISTINCT(type)
FROM cakes;
```

##結果を見やすくするコマンド

**データの並び順を決める** 
- 降順 `DESC` 昇順 `ASC`
 : 値段が高い商品から順に並べる


```SQL
SELECT name, price
FROM cakes
ORDER BY price DESC;
```

**一定のキーワードを含むデータを取り出す** 
- `LIKE` `%`（`%`はSQLにおけるワイルドカード。どの文字列にも一致することを指す）
 : 名前に「ケーキ」を含む商品を知りたい


```SQL
SELECT name
FROM cakes
WHERE name LIKE "%ケーキ%";
```

**取り出す件数を制限する** 
- `LIMIT`
 : 値段が安い上位5商品を知りたい

```SQL
SELECT name, price
FROM cakes
ORDER BY price ASC
LIMIT 5;
```

**カラムの名前を変更して出力する** 
- `AS`
 : price-costを利益という名前で出力する

```SQL
SELECT name, price - cost AS "利益"
FROM cakes
```

##より多くのデータを使うためのコマンド
**サブクエリを用いて条件を指定する** 
- `()`
 : チョコレートタルトよりも安い商品の名前と値段を知りたい

```SQL
SELECT name, price
FROM cakes
WHERE price < (
  SELECT price
  FROM cakes
  WHERE name = "チョコレートタルト"
)
;
```

**複数のテーブルを用いて分析を行う** 
- `JOIN テーブル名` `ON 結合の条件` `テーブル名.カラム名`
- 複数のテーブルに同じカラム名がある場合は、SELECTの後も`テーブル名.カラム名`で指定する
 : sales_januaryにある、商品が売れた個数を並べて出力したい


```SQL
SELECT name, total
FROM cakes
JOIN sales_january
ON cakes.id = sales_january.cake_id;
```
#まとめ
SQLの最初に学ぶ基本をまとめました。
コマンドを組み合わせることで、例に出したよりもさらに色々な分析ができます:thumbsup:
【SQL】基本のまとめ1

#内容
SQLを勉強し始めたので、これまでに学んだ知識をまとめます。
長くなったので[**【SQL】基本のまとめ2**](https://qiita.com/kikuri426/items/9fa8f1b458109ee1a4fa)とこの記事に分けました。

*この記事の内容*

 - SQLとは
 - データベース内の名称
 - 基本のコマンド
    - SELECT, FROM, WHERE, NOT
 - 四則演算や集計のコマンド
    - AVG, SUM, COUNT, MIN, MAX
   
*ここから先は[【SQL】基本のまとめ2](https://qiita.com/kikuri426/items/9fa8f1b458109ee1a4fa)へ*

 - 便利なコマンド
    - AND, GROUP BY, HAVING, DISTINCT
 - 結果を見やすくするコマンド
    - ORDER BY, LIKE, LIMIT, AS
 - より多くのデータを使うためのコマンド
    - サブクエリ, JOIN

##SQLとは
データベースの分析に使われるデータベース言語のこと。
データベースにはユーザーや商品など、様々なデータが入っています。
それらの情報を使って分析を行うためにデータベースに指令を送るのが**SQL**です。

##データベース内の名称
テーブル：データが入った表。
カラム：テーブルの縦の列。idカラム、nameカラムなど
レコード：テーブルの横の列。

**cakes**

|       id      |type|      name     |     price    |cost |
|:-------------:|:----:|:-------------:|:-------------:|:---:|
|        1      |ケーキ|ショートケーキ    | 300         |  100|
|        2      |ケーキ|モンブラン        | 400         |200|
|        3      |ケーキ|チーズケーキ      |200           |50|
|        4      |タルト|フルーツタルト    | 400        |300|
|5|ゼリー| コーヒーゼリー| 200|50|
|6|タルト|チョコレートタルト|300|70|


##基本のコマンド （ここからはひたすら例を上げていきます）

**必ずコマンドの最後に ; を入力する**

**テーブルからカラムを取り出す**
- `SELECT` `FROM`
 : ケーキの商品名を知りたい

```SQL
SELECT name
FROM cakes;  
```

**テーブルから複数のカラムを取り出す**
 : ケーキの商品名と値段を知りたい

```SQL
SELECT name, price
FROM cakes;  
```

**テーブルから全てのカラムを取り出す** 
- `*`
 : ケーキ屋の情報を全て知りたい

```SQL
SELECT *
FROM cakes;  
```

**テーブルから一定条件下のデータを取り出す** 
- `WHERE`
 : モンブランの値段を知りたい


```SQL
SELECT price
FROM cakes
WHERE name = "モンブラン";
```

**テーブルから条件とは異なるデータを取り出す** 
- `NOT`
 : タルトではない商品の値段を知りたい


```SQL
SELECT name, price
FROM cakes
WHERE NOT type = "タルト";
```

##四則演算や集計のコマンド
**四則演算をしたデータを取り出す**
- 合計 `+` 差 `-` 乗算 `*` 除算 `/`
 : それぞれの商品が売れた時の利益を知りたい


```SQL
SELECT name, price - cost
FROM cakes;
```

**集計関数を用いてデータを取り出す**
 - 合計`SUM(カラム名)` 平均`AVG(カラム名)` 個数 `COUNT(カラム名)` 最大`MAX(カラム名)` 最小`MIN(カラム名)` など
 : 商品の平均金額を知りたい


```SQL
SELECT AVG(price)
FROM cakes;
```

#まとめ
SQLで一番最初に学ぶ基本の部分をまとめました。
[【SQL】基本のまとめ2](https://qiita.com/kikuri426/items/9fa8f1b458109ee1a4fa)もどうぞ:blush:
[Azure] Azure アカウントとサブスクリプション [Learn]

この記事は2019年1月31日に書いています

Azureを本格的に学ぼうと思い、AzureLearnを始めた
基本的な部分からテクニカルな部分まで備忘として記述していきます

https://docs.microsoft.com/ja-jp/learn/modules/create-an-azure-account/2-azure-accounts-and-subscriptions

僕と同じようにAzureの初学者やなにかに利用したいと思う方の第1歩として
書いてまいります、表現の誤解 

- Azureアカウント
    - クレジットカード課金情報と紐付いてメアドなんかでアカウントを作成する
- Auzureサブスクリプション
    - Azureのクラウド上にいろんな機能やシステム、サービスを実装するためのリソースを利用する権利のようなもの（ここが初学者は理解が難しい、まず使ってみるとよい）
    - 種類
    - 無料（個人はここから利用）
    - Pay as you go （無料期間過ぎたらこちらへ無料サービスは多数）
    - EA→企業がよく利用する形態（お安くなったり）
    - 学生（よく知りません）
    
- 複数のAzureサブスクリプション
    - 1つのアカウントに対して複数のサブスクリプションを付与できる
        - 課金（ビリング）やユーザアクセス制御（セキュリティ）の観点で嬉しい
        - 開発環境、検証環境、本番環境などでサブスクリプションを分け運用
        - 商品開発部門に1アカウント作り開発と本番などにして管理が楽に

- アクセス管理と請求
    - サブスクリプションには、ハードウェアの制限があるため考慮する
    - サブスクリプションごとの Express Route 回線の最大数は10等
    - 課金はサブスクリプション別で支払いは_アカウント所有者_が行う
    - 筆者は過去に間違えてサブスクリプション(Visual Studio関連）を付与して2600JPY払っていました(Cost ManagementをAzure Portalからチェックすべき）

- AAD(Azure AD)を利用したアクセス認証
    - Azure AD テナントごとに_アカウント オーナー_がいる
    - 課金に対して責任を負う元の Azure アカウント
    - その他のユーザーをテナントに追加したり、サブスクリプション内のリソースにアクセスするために、他の Azure AD テナントからゲストを招待したりできる

- Azureのサポートオプション
    - 無料と有料があり、無料は基本的な使い方（製品やドキュメント、課金など）を教えてくれる
    - 有料は技術と運用面のアドバイザリを行う
        - Enterpriseな規模の会社はDeveloper サポートは使用できない
        - Standard、Professional Direct および Premier サポートから選ぶ
        - サポートはエンタープライズ契約 (EA) の一環として課金される
iOS 12におけるiPadのiPhone互換表示の調査結果

## 3.5inch対応はつらい
iPhone向けのiOS Appを作成している時、いまだに頭を悩まされるのが3.5inch対応です。

[以前にも記載した記事](https://qiita.com/aryzae/items/1d5cc833eb5b47e7dd6c)内で言及しているように、Universal Appでない時は、iPad上でiPhoneの互換表示が3.5inchで行われるため、対応していないと画面崩れ等を理由に最悪rejectになります。

## iPadのiPhone互換表示の調査結果
さて、iOS 12が出てから数ヶ月が経ちましたが、iOS 12からiPad上のiPhone互換表示が変わったことが知れ渡ってないように感じられたので、自分の記憶の裏付けを行いがてらSimulatorで確認してみました。
Xcode 10.1で確認

### iOS 11.4
iPad 種別 | version | 互換解像度 | 相当サイズ
:--|:-:|:-: | :-:
iPad (5th generation) | iOS 11.4 | 320 x 480 | 3.5inch
iPad Air | iOS 11.4 | 320 x 480 | 3.5inch
iPad Air 2 | iOS 11.4 | 320 x 480 | 3.5inch
iPad Pro (9.7-inch) | iOS 11.4 | 320 x 480 | 3.5inch
iPad Pro (10.5-inch) | iOS 11.4 | 320 x 480 | 3.5inch
iPad Pro (12.9-inch) (1st generation) | iOS 11.4 | 375 x 667 | 4.7inch
iPad Pro (12.9-inch) (2nd generation) | iOS 11.4 | 375 x 667 | 4.7inch

### iOS 12.0以降
iPad 種別 | version | 互換解像度 | 相当サイズ
:--|:-:|:-: | :-:
iPad (5th generation) | iOS 12.0 | 375 x 667 | 4.7inch
iPad (6th generation) | iOS 12.0 | 375 x 667 | 4.7inch
iPad Air | iOS 12.0 | 375 x 667 | 4.7inch
iPad Air 2 | iOS 12.0 | 375 x 667 | 4.7inch
iPad Pro (9.7-inch) | iOS 12.0 | 375 x 667 | 4.7inch
iPad Pro (10.5-inch) | iOS 12.0 | 375 x 667 | 4.7inch
iPad Pro (11-inch) | iOS 12.1 | 375 x 667 | 4.7inch
iPad Pro (12.9-inch) (1st generation) | iOS 12.0 | 375 x 667 | 4.7inch
iPad Pro (12.9-inch) (2nd generation) | iOS 12.0 | 375 x 667 | 4.7inch
iPad Pro (12.9-inch) (3rd generation) | iOS 12.1 | 375 x 667 | 4.7inch

## やっぱ…つれぇわ…
iOS 11では、12.9inchのiPadのみ4.7inch表示でしたが、iOS 12以降では全てのiPadで4.7inch表示になっています。

つまり、iOS 11を切れば3.5inch対応が不要になるんです！
実質あと1〜2年は頑張らないといけないですが、耐え忍ぶのです!
【Tips】一定データ数ごとに改行する定型パターン

>[プログラミング未経験者がPython覚えて子ども用計算ドリルを作る](https://qiita.com/sotogawa/items/14ecbf090ae05a8eddb7)

についてのリファクタリング(その２)


##改善内容

1. 改行処理をバッファを使った定型パターンに変更
1. データを一気に代入(append)　[参考](https://qiita.com/zaq9/items/6e08932edfa6d2c6db02)
1. 各計算式を一つのリストにまとめる


# 変更後のソースコード全体:


```py

"""計算練習ドリルを作成
	改行処理にバッファー活用＋appendで行ごと書き込むバージョン
"""

import random
import openpyxl

wb = openpyxl.Workbook()  #新規ワークブックを作成
sheet = wb.active

# 各計算式を一つのListとして取り扱うと理解しやすい
list_ = [[a, '+', b, '=', ''] for a in range(1, 10) for b in range(1, 10)]

random.shuffle(list_)

buf = []    #dataを一時ため込む変数
for v in list_:
	if len(buf) > 25: #一行に25列以上データがある場合は改行    
		sheet.append(buf)
		buf=[]
	buf.extend(v)     #buf内にデータを一時的に追加保存
sheet.append(buf)     #最終行書き込み

wb.save('output3.xlsx')

```

![drill_img.JPG](https://qiita-image-store.s3.amazonaws.com/0/351020/89dd4f95-15b9-609f-94a2-2d783d6aa60b.jpeg)
科学四分類　再考

科学を現象の確率に応じて論理科学、物理化学、生命科学、社会科学に分類する。

数学は論理科学。

経済学は電気回路のモデルを利用。

社会科学は物理量・生命量じゃない分、数学（論理科学）に依存する可能性あり。


 <この項は書きかけです。順次追記します。>

サルでも分かる人文科学／社会科学／自然科学の見分け方

https://readingmonkey.blog.fc2.com/blog-entry-199.html

科学三分類・四分類・五分類と算譜(program) 仮説(93) 統計と確率(7)

https://qiita.com/kaizen_nagoya/items/a2f2b9cc3a51b6af7603

無限次元空間を想定すること。仮説（120）

https://qiita.com/kaizen_nagoya/items/9f2c4d2e1ae4e1b4a7c6

連続と離散、時間と空間、物理量と生物量。統計と確率(2)

https://qiita.com/kaizen_nagoya/items/d0980c6bf9d3079aa98d

統計と確率(10) 科学哲学考

https://qiita.com/kaizen_nagoya/items/456273849f4b17bd9ab5

データサイエンティストへの５つの門。あなたはいくつの門をくぐりましたか？統計と確率(8)

https://qiita.com/kaizen_nagoya/items/ee5fa7b2a7f7c2b450d4

データサイエンティストの気づき!「勉強して仕事に役立てない人。大嫌い!!」『それ自分かも?』ってなった!!!

https://qiita.com/kaizen_nagoya/items/d85830d58d8dd7f71d07

プログラマにも読んでほしい「QC検定にも役立つ！QCべからず集」

https://qiita.com/kaizen_nagoya/items/d8ada7b7fceafe2e5f0e


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

# 文書履歴(document history)
ver. 0.01 初稿 20190131
ver. 0.02 URL追記　20221202
### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
EC2 apache2.4 にSSLの設定をするメモ（SSLはさくらで取得） 

# 証明書と中間証明書を取得（さくらの場合）
SSLサーバ証明書発行完了のメールがくるので、その中に取得先が載っています。
そこから取得してきてください。

# SSLの設定
[apache 2.4におけるSSL証明書の設定](https://qiita.com/bageljp@github/items/6b9876b7571852284ead)
[Amazon LinuxのApache 2.4にSSL証明書を設定してみた](https://dev.classmethod.jp/cloud/aws/amazonlinux-apache24-ssl/)
上記のサイトを見合わせながら設定しました！
最後にハマったのはec2のセキュリティーグループでHTTPSを解放していなかった事w

以上っす。
Railsのコンソールで、モデルのカラム名一覧をシンボル型の配列で取得する

カラムが大量にあるときに一括でストロングパラメーターを設定する場合などに、コピペすると便利。
(2/2 修正)scivola様より、改善いたしました。`.inspect`は、改行を防ぐためです。

```ruby:コンソール
[1] pry(main)> モデル名.column_names.map(&:to_sym).inspect

#=> "[:id, :user_id, :name, ...]"
```
QuantXでHLバンドを実装してみた

#今回やったこと
投資アルゴリズム開発プラットフォーム「QuantX」で、HLバンドを実装してみました。

#HLバンドとは
HLバンドは、直近の高値、安値のブレイクを捉えるテクニカル指標です。
Hバンド：前日から遡ってn日間の高値
Lバンド：前日から遡ってn日間の安値
中心線：HバンドとLバンドの平均
の3本線で構成されます。

今回はシンプルに、Hバンドを上向きにブレイクしたポイントを買い、Lバンドを下向きにブレイクしたポイントを売りとしてシグナルを生成してみます。

#アルゴリズム
今回作ったアルゴリズムは[こちら](https://factory.quantx.io/developer/63b82af9228c48aabb27737b8f8a32bc)

```python
import pandas as pd
import numpy as np 

def initialize(ctx):
    # 設定
    ctx.logger.debug("initialize() called")
    ctx.configure(
      channels={          # 利用チャンネル
        "jp.stock": {
          "symbols": [
            "jp.stock.1305",
            "jp.stock.9984",
            "jp.stock.9983",
            "jp.stock.7201",
            "jp.stock.9201",
            "jp.stock.9202",
            "jp.stock.7203"
          ],
          "columns": [
            "high_price_adj",    # 高値(株式分割調整後)
            "low_price_adj",     # 安値(株式分割調整後)
            "close_price_adj",    # 終値(株式分割調整後) 
          ]
        }
      }
    )

    def _my_signal(data):
      cp = data['close_price_adj'].fillna(method = 'ffill')
      hp = data['high_price_adj'].fillna(method = 'ffill')
      lp = data['low_price_adj'].fillna(method = 'ffill')
      hband = hp.rolling(20).max().shift(1)
      lband = lp.rolling(20).min().shift(1)
      hl_mean = (hband + lband)/2
      
      buy_sig = cp[(cp > hband) & (cp.shift(1) < hband.shift(1))]
      sell_sig = cp[(cp < lband) & (cp.shift(1) > lband.shift(1))]
      
      return {
        'buy:sig':buy_sig,
        'sell:sig':sell_sig,
        'hband':hband,
        'lband':lband,
      }

    # シグナル登録
    ctx.regist_signal("my_signal", _my_signal)

def handle_signals(ctx, date, current):
    '''
    current: pd.DataFrame
    '''

    done_syms = set([])
    for (sym,val) in ctx.portfolio.positions.items():
        returns = val["returns"]
        if returns < -0.03:
          sec = ctx.getSecurity(sym)
          sec.order(-val["amount"], comment="損切り(%f)" % returns)
          done_syms.add(sym)
        elif returns > 0.05:
          sec = ctx.getSecurity(sym)
          sec.order(-val["amount"], comment="利益確定売(%f)" % returns)
          done_syms.add(sym)


    buy = current["buy:sig"].dropna()
    for (sym,val) in buy.items():
        if sym in done_syms:
          continue
        
        sec = ctx.getSecurity(sym)
        sec.order(sec.unit() * 1, comment="SIGNAL BUY")
        ctx.logger.debug("BUY: %s,  %f" % (sec.code(), val))
        pass

    sell = current["sell:sig"].dropna()
    for (sym,val) in sell.items():
        if sym in done_syms:
          continue
    
        sec = ctx.getSecurity(sym)
        sec.order(sec.unit() * -1, comment="SIGNAL SELL")
        ctx.logger.debug("SELL: %s,  %f" % (sec.code(), val))
        pass

```

#結果
![スクリーンショット 2019-01-31 15.57.17.png](https://qiita-image-store.s3.amazonaws.com/0/325611/e745146c-8b93-22f9-5bb2-8697c441c3bd.png)


直近3年でこのくらいの数字。
HLバンドは上がり続ける大相場の時にこそ効果を発揮するもので、上昇局面にあった20年ほど前に人気があった手法であったそうですが、今日そこまでの大相場を形成することは珍しいので、シンプルな戦略は現在あまり効果がないようです。
【個人情報整理①】他人依存・面倒臭がりな私の、エンジニアポートフォリオ作成方法探求

・Netflixによって世界中から人気を博している「こんまり」さんに、多大な影響を受けて情報整理をしていく記事第一弾。
・この流れに紛れ込んで、几帳面の姿を炸裂して、野暮技術者ではないことを証明していこう。
・よし。八方美人技術者である私の、乱雑な技術情報の整理も兼ねたポートフォリオサイトを作成しよう。
・だが、他人依存・面倒くさがりの私は、この二大病魔に加えて、「良質かつ簡単」という末恐ろしい期待を持ってしまう。
・まずは、作成方法を探していくことにしよう。

## 希望
- シンプルかつ見やすいページが作れる。  
→デザイナー風の「色鮮やかさ」や「おしゃれ感」はなくてよいので、スキルや成果物がきちんと見やすく構成できるサイトが作成したい。
- すぐ公開できる。  
→サーバー構築なしで、素早く公開できる。
- 直感的に簡単に作成できる。  
→ある程度のフロント（HTMLやCSS）の知識、またはコード不要で、作成したい。そこに時間をかけたくない。

## 候補作成方法・サービス
### 1. HTMLテンプレートの使用
- ポートフォリオサイトのHTMLテンプレートをダウンロードして、自分用に少しコードを編集する方法。  
※その際は、HTMLやCSS、JavaScriptの知識が必要となってくる。
- 公開はGitHub PagesというGitHubの静的公開サービスで行う。  
※GithubアカウントやGitの知識が必要となってくる。

- 候補テンプレートは、下記。
    - [ポートフォリオHTMLテンプレート](https://webdesigner-go.com/template/portfolio/)  
    →[こちらの紹介記事](https://qiita.com/turmericN/items/76559f0b70983469e7c7)で、知りました。
    - [無料ホームページテンプレート.com](https://f-tpl.com/category/HTML%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88/)  
    →いろいろな種類があります。
    - [おすすめテンプレート紹介記事](https://homepagenopro.com/free/template.html)  
    →プロの方がおすすめの、10個のHTMLテンプレートが紹介されています。

### 2. ポートフォリオ作成サービスの使用
- 直感的にドラッグ&ドロップでのデザイン修正や項目入力のみ等、コード不要でサイトを作成する方法。
- 作成後のサイト公開も、そのサービスが自動的に行ってくれる。  
※ドメイン名は、そのサービス名がついたものになることが多い。
- 候補サービスは、下記。
    - [RESUME](https://www.resume.id/)  
    →ポートフォリオサイトに特化した作成サービス。項目入力やドラッグ&ドロップで、簡単に高品質なサイトが作成できる。
    - [HTML名刺](https://html.co.jp/)  
    →名刺風に、自分の紹介サイトが作成できる。シンプルで、載せられる情報量も多く、見やすい。
    - [Adobe Portfolio](https://portfolio.adobe.com/)  
    →Adobe社が提供しているポートフォリオ作成サービス。様々な高品質テンプレートデザインを選択できる。
    - [Portfoliobox](https://www.portfoliobox.net/jp)  
    →世界的人気のポートフォリオ作成サービス。高品質なテンプレートデザインが豊富。

## 結果
- 今回色々調査してみて、最終的に絞った候補サービスが下記。これらの中から選んで作っていくことにする。
    - [ポートフォリオHTMLテンプレート](https://webdesigner-go.com/template/portfolio/)  
    →少々のコード知識で作成可能であり、同時にGitHubの公開もできる。また、スキルや成果物の項目等、エンジニアポートフォリオとして最初から用意されている。
    - [RESUME](https://www.resume.id/)  
    →ポートフォリオに特化しているだけあって、スキルや経歴等の項目が非常に見やすい。
    - [HTML名刺](https://html.co.jp/)  
    →シンプルな名刺サイトということで、見やすいだけではくて、情報の整理やリンク紹介も簡単。これをポートフォリオにする選択肢もありだと思う。

## まとめ
- 今回は、ポートフォリオ作成方法探しということで、整理するほどでもない自分の希少情報に憂いながら、記事を書く。
- 整理整頓術が今後更に広がっていく中で私は、それと同時に増加するであろう説教干渉族からの抗戦の未来に恐れる。
- その対抗策としての作成方法も見つけたということで、平穏な技術者生活が送れることを切に願う。

## 参考
- https://qiita.com/turmericN/items/76559f0b70983469e7c7  
→エンジニアのポートフォリオ作成案として、参考にしました。大変お世話になりました。
- https://qiita.com/musou1500/items/24ed32d7f5b0a6377bc5  
→こちらの記事も作成案として参考にしました。大変お世話になりました。
PythonでExcel新規シート作成し、複数のデータを一気に代入（openpyxl、 append)

#概要:
PythonでExcel新規シート作成し、複数のデータを一気に代入する場合、
openpyxl　ライブラリでは append が利用可能

#使い方:
例：新規シートを作成し、リストや辞書のデータを代入

```py

import openpyxl

wb = openpyxl.Workbook()  #新規ワークブックを作成
sheet = wb.active
sheet.append(['hoge0', 'hoge1', 'hoge2'])
sheet.append([999,888,777] )
sheet.append({'A' : 'A列に書き込みたいこと', 'C' : 'C列に書き込みたいこと'})
wb.save('output_append.xlsx')

```

![append.JPG](https://qiita-image-store.s3.amazonaws.com/0/351020/dc0cc70f-1746-77ae-946d-942b432205a2.jpeg)



[公式ドキュメント(append):](https://openpyxl.readthedocs.io/en/latest/_modules/openpyxl/worksheet/worksheet.html#Worksheet.append)

```python

    def append(self, iterable):
        """Appends a group of values at the bottom of the current sheet.

        * If it's a list: all values are added in order, starting from the first column
        * If it's a dict: values are assigned to the columns indicated by the keys (numbers or letters)

        :param iterable: list, range or generator, or dict containing values to append
        :type iterable: list|tuple|range|generator or dict

        Usage:

        * append(['This is A1', 'This is B1', 'This is C1'])
        * **or** append({'A' : 'This is A1', 'C' : 'This is C1'})
        * **or** append({1 : 'This is A1', 3 : 'This is C1'})

        :raise: TypeError when iterable is neither a list/tuple nor a dict

        """
```

##参考情報：
「Write-only-mode」では、appendのみが利用可能で、cell()等は使えない。
[write-only-mode](https://openpyxl.readthedocs.io/en/stable/optimized.html#write-only-mode)
>> In a write-only workbook, rows can only be added with append(). It is not possible to write (or read) cells at arbitrary locations with cell() or iter_rows().

#感想：
ソースコードを見たところ、内部的にはfor文を回して、
逐一セルにアクセスしているだけ。ExcelのRangeに対応する機能は現状（2.5.15）弱そう。
TechBlog開設のお知らせ

こんにちは。株式会社クオリティアの@mihyonです。
この度、クラウドサービス企画部のTechBlogを始めることになりました。

現在、CloudNativeやDevOpsを目指して新しいクラウドサービスを開発しています。
このTechBlogでは、技術系カンファレンス情報、カンファレンスで発表した資料、
メールセキュリティ関連情報、Pythonなどプログラミング言語、
スクラム開発手法、等々情報を共有して行く予定です。

コメントやメンションなどでお気軽にフィードバックください。
皆様からのフィードバックを心よりお待ちしております。
Gitリポジトリ内にあるディレクトリを別リポジトリに移行する

# どういうことか

AAAAAの下にフォルダがあるが、それぞれのフォルダは別のプログラムを保持していて1つにまとめておく必要が一切ないので分割します。

これを

```
AAAAA
 BBBBB
 CCCCC
  aaa
  bbb
  ccc
 DDDDD
 EEEEE
```

こうなるようにします。
新しいリポジトリを作り、ログもそのまま持っていきます。

```
CCCCC
 aaa
 bbb
 ccc
```

# やったこと

- 作業ブランチを作る

```
 git checkout -b filter
```

- コマンドでCCCCC以外をフィルタ

```
 git filter-branch -f --subdirectory-filter CCCCC/ -- --all
```


```
コマンド結果
AAAAA
 CCCCC
  aaa
  bbb
  ccc
```

- CCCCC以下のファイルを移動

```
 git filter-branch -f --tree-filter "git mv -k CCCCC/* ."
```

```
コマンド結果
CCCCC
 aaa
 bbb
 ccc
```

- 移行対象のリモートに追加してプル

```
git remote add work file:///tmp/AAAAA
git pull work filter
```

- 移行対象のリモートにプッシュ

```
git push origin master
```

# 参考(そのまま)

- [gitレポジトリ内のディレクトリを別のgitレポジトリ以下に移動する](https://qiita.com/yasano/items/f9248eb99850a872b0a8)
vue-cli + axios でmock環境を雑に作ったのでメモ

vue-cliで開発するのにローカルのapiとmockを切り替えながら開発する環境を作ったが絶対忘れるので自分用にメモ
ローカルでの開発中に `yarn run serve` でapiにつないで `yarn run mock` でmockを見れるようにすることを目指します

## コマンド
まずコマンドの方から先に仕込んで行きます

```json:package.json
  "scripts": {
    "serve": "vue-cli-service serve",
    "mock": "vue-cli-service serve --mode mock",
    "build": "vue-cli-service build",
```
起動時に `--mode mock` をつけることで環境変数を読み込む元のファイルを `.env.development` から `.env.mock` に変えることが出来るのでこれを `package.json` に仕込んで `yarn run mock` で起動出来るようにします

今回は環境変数をそれぞれ以下の通りにします

```.env.development
VUE_APP_USE_MOCK=false
```

```.env.mock
VUE_APP_USE_MOCK=true
```
この環境変数を使ってmock環境かどうか判定します
mockを利用したい環境ではtrue、そうでないときはfalseにします

## axios
次にapiへのアクセス部分を書いていきます

```js:api.js
import axios from 'axios'
import mock from './mock/api';

export const client = axios.create({
  baseURL: <apiのurl>,
})

// モック起動
if (JSON.parse(process.env.VUE_APP_USE_MOCK)) {
  mock.run(client)
}

export default {
  getApi (params, cb, err_cb) {
    client.get('/', headers)
      .then(response => {
        cb(response.data)
      })
      .catch(error => {
        console.log(error)
        err_cb(error)
      })
  },
  postApi (params, cb, err_cb) {
    client.post('/', params, headers)
      .then(response => {
        cb(response.data)
      })
      .catch(error => {
        err_cb(error)
      })
  },
}
```

apiへのアクセスはaxiosを使っていて基本何か特別なことは無いです
ただ先程の環境変数がtrueな場合、mockを起動しています
(ここでは環境変数の判定をするのにJSON.parseを使っているのは値をbooleanに変換するためですが、正直あまりいい方法では無いと思う…）

## mock
最後にmockの振る舞いを定義します
今回はパスを `./mock/api` としています

```js:mock/api.js
import MockAdapter from 'axios-mock-adapter';

const initialData = () => ([
  { id: '1', name: '島村卯月', notes: '' },
  { id: '2', name: '渋谷凛', notes: '' },
  { id: '3', name: '本田未央', notes: '' },
])
let data = initialData()

export default {
  run : client => {
    const mock = new MockAdapter(client)

    mock.onGet('/').reply(200, data)
    mock.onPost('/').reply(
      config => {
        let res = JSON.parse(config.data)

        res.id = Number(data.length) + 1
        data.push(res)
        return [200, res]
      }
    )
  },
  getData: () => {
    return JSON.parse(JSON.stringify(data))
  },
  setData: input => {
    data = JSON.parse(JSON.stringify(input))
  },
  initialize: () => {
    data = initialData()
  },
}
```

作り込んではいないので雑ですが見ていきましょう
今回は `axios-mock-adapter` を利用します
`initialData` はmock用の初期データです
これを初期化時に実際のmockのデータを保存する変数である `data` に突っ込みます
`run` は起動する時に実行される関数で、ここにmockがどういった振る舞いをするかを定義しています
ここではgetでは現在のデータをそのまま、postでは追加してそのまま入ってきた物をそのまま返却しています
`getData` `setData` `initialize` ではテスト等でデータを見たりいじったりしています

あとはコマンドを最初に設定した通りに叩いてやればmock環境でvue-cliが起動します

```
$ yarn run mock
```
明日から使えるSwiftテクニック集


いろんなところでSwiftのサンプルコードを見ていて、
あんまり使われていないけれどこれって便利なのにな〜
と言うテクニックをまとめてみました。
そんなの知ってるるよ！と言う方も多いと思いますが、自分の中で知ったときに驚いたものということで、

# 連続 `guard let`
関数`hoge`の返り値が`Optional`でその返り値を使って関数`huga`を呼び出してと言うのを普通にやると以下のようになるかと思います。

```swift
guard let _hoge = hoge() else {return}
guard let _huga = fuga(_hoge) else {return}
```

ただこれだと`guard`×2回で冗長です。
そんな時Swiftでは、`guard`条件を連続で使用できます。

```swift
guard 
    let _hoge = hoge(),
    let _fuga = fuga(_hoge)
else {return}
```

(この例だとモナドを使えと言われそうですが、それは割愛。)

# `didSet` `willSetは`どこでも使える！

よくプロパティ監視に使われる`didSet` `willSet`ですが、実はどんな変数にでも使えます。

```swift
var value = 1{
	willSet{
		print(newValue)
	}

	didSet{
		print(oldValue)
	}
}

value = 6 // 6、1
```

このように変数宣言につけておけばどんな変数でも監視できるので変数の代入の流れを追うのに便利です。

# `do`でスコープを切る

Swiftの`do`は`do-catch`や`do-while`の組み合わせとして語れることが多いですが、実は単体でも結構使える子です。
`do`節はそのまま実行されますが、スコープ内から出ると名前空間が変わり、またガベージコレクタも動くので、同じ変数名が多く出てくる時やメモリを食う処理をするときに使えます。

```swift
do{
	let name = "Alice"
	...
}
do{
	let name = "Bob"
	...
}
```

私はUnitTestをしたり、`PlayGround`なんかでロジックの試しをするときなんかに使います。

# `optional`な`protocol`

Obj-C時代では`delegate`の任意に実装する関数なんかは
`@optional`属性にしていたと思います。
ただこれをSwiftで実装しようと思うと`@objc`を使う必要が出てきますし、その`protocol`のすべての引数、返り値などに`NSObject`を継承させる必要があります。

なのでPure Swiftでoptionalな`protocol`を実現する方法を探してみました。

```swift
protocol SomeProtocol{
    func hoge()
    func fuga()
}

extension SomeProtocol{
    func hoge() {}
}
```

Swift2.0から導入された`protocol extension`を用いることで、`hoge`は`@optional`に`huga`は`@required`にできます。

----

ミス、間違いなどありましたら。
よろしくお願いします。
HDPのzeppelinでphoenixを使うには

- zeppelin spark interpreterで

```
| spark.driver.extraClassPath  | /usr/hdp/current/phoenix-client/ |
|:--|:--|
| spark.executor.extraClassPath  | /usr/hdp/current/phoenix-client/  |
```

- artifactに

```
org.apache.phoenix:phoenix-spark:5.0.0-HBase-2.0 
```

を設定

```
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
import org.apache.phoenix.spark._
```

一旦確認
【SpringBoot】SpringBootを使うなら沢山入っているutilを使うと便利だった話

タイトルで結論書いてますが、SpringBootでやっているなら、`org.springframework.util`パッケージ内に設定されている色々なutil関数を使うことができて便利でした。

以下使ってみた関数と実装を2つ挙げます。

# リストのnull/空チェック
実装が色々槍玉に上がっている印象があるリストのnull/空チェックですが、`org.springframework.util.CollectionUtils.isEmpty`で定義されています。

```java
/**
 * Return {@code true} if the supplied Collection is {@code null} or empty.
 * Otherwise, return {@code false}.
 * @param collection the Collection to check
 * @return whether the given Collection is empty
 */
public static boolean isEmpty(@Nullable Collection<?> collection) {
	return (collection == null || collection.isEmpty());
}
```

# ファイルの拡張子取得
ググってもGuava入れるか自力実装しろという感じで出てきますが、実装されてました。

```java
/**
 * Extract the filename extension from the given Java resource path,
 * e.g. "mypath/myfile.txt" -> "txt".
 * @param path the file path (may be {@code null})
 * @return the extracted filename extension, or {@code null} if none
 */
@Nullable
public static String getFilenameExtension(@Nullable String path) {
	if (path == null) {
		return null;
	}

	int extIndex = path.lastIndexOf(EXTENSION_SEPARATOR);
	if (extIndex == -1) {
		return null;
	}

	int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR);
	if (folderIndex > extIndex) {
		return null;
	}

	return path.substring(extIndex + 1);
}
```

# 結論
Springに限った話ではありませんが、自力で実装したり新しいライブラリの導入を考える前に「既に導入したライブラリのutilに実装されていないか確認する」というのは重要だと思いました。
ググラビリティが低いのでどんな関数が実装されているかというのは把握しにくいですが、個々の関数は探せば意外と見つかります。
ライブラリの実装を持ってくるなら最低限一度コードを読んでおくべきだとは思いますが、自力実装してテストする手間と比べればマシですし、勉強にもなると思います。

後、その辺も簡単に探せるideaは偉大だと思いました。
Cognito IDトークンからユーザー情報を取得する方法

## はじめに
Cognitoを使用して認証基盤を作成しています。

IDトークンを用いて認証パスさせているのですが、エンドポイントでユーザー情報が欲しくなったので書いておきます。

###構成
Cognito、APIGateWayを使用。エンドポイントとしてVPC内のEC2を利用している。

###情報を渡す二つの方法
上記の構成だとCognitoの情報を渡すには
二つの方法があります。

1. APIGateWayのマッピング機能を使う
2. IDトークンをデコード

この二つになります。
今回は後者のIDトークンから複合する方法について書いていきます 

## 方法
IDトークンはデコードすることでユーザー情報に変換することができます。

IDトークンはJWT(JSON　WEB　TOKEN　)という方法でエンコードされています。
詳細については[こちらのQiita記事](https://qiita.com/t-toyota/items/8d0ffb265845ab8cc87c)を参照してください。

トークンはリクエストヘッダーに

```
"header": {
        "Connection": "Keep-Alive",
        "Host": "54.538.153.127",
        "Authorization": "fdasfdsafdsafdsafsdafdsafdsafdsadfasdTdjLTQ3NDYtOTg1My00ZTExYjI3OTlhNTYiLCJjb2duaX"
    }
```

といった形で格納されていることが多いはずです。
Authorizationに入っているIDトークンを変換していきます

PHPで実装したのでPHPのコードを載せます。

```php5

//composer require firebase/php-jwt でライブラリのインストールが必要
require __DIR__ . '/vendor/autoload.php';
use \Firebase\JWT\JWT;

function getUserInfo($header) {//トークンIDをデコードしてユーザー情報を取得
    $authorization = $header['Authorization'];
    $tks = explode('.', $authorization);
    $user_info = JWT::urlsafeB64Decode($tks[1]);//デコード
    return $user_info;
}

if (!function_exists('getallheaders')) {//リクエストのヘッダー情報を取得
    function getallheaders() {
    $header = [];
    foreach ($_SERVER as $name => $value) {
        if (substr($name, 0, 5) == 'HTTP_') {
            $header[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
        }
    }
    return $header;
    }
}

parse_str($_SERVER['QUERY_STRING'], $query_string);
$header = getallheaders();
$user_info = getUserInfo($header);
```

こちらを用いることで
```"{\"sub\":\"dddd\",\"cognito:groups\":[\"test-admin\"],\"email_verified\":true,\"iss\":\"https:\\/\\/cognito-idp.apm\\/ap-northeast-"}
```

のようにトークンからユーザー情報を取得することに成功しました。

## 注意
- アクセストークンでは情報を取得することができません。
コマンドGetUserで情報を取得できるのでそちらを試してください

- トークン全てをデコードするとデコードしきれない文字があります。explode等で区切ってから変換してください
SDLアプリコンテスト 応募してみた。その２

#概要

SDLアプリコンテスト、見つけたので挑戦してみる。
応募してみた。

#提出書類

提出資料は、pdf。
jsdoで、pdfを作ってみた。

http://jsdo.it/ohisama1/6TyC

#応募画像

![sdll.png](https://qiita-image-store.s3.amazonaws.com/0/18104/0f6be27b-f6e8-44d6-4eed-841af33132c4.png)


#応募動画

https://www.youtube.com/watch?v=Imb9XvckvFM

#リンク

SDLアプリコンテスト
http://sdl-contest.com/

以上。