OmniAICreator/Qiita-1.07M huggingface dataset:
ゆるふわ Ruby エンジニアが矢を受けた小ネタ集

**Ruby よくわかんなくなっちゃった**

Ruby の小ネタ集です。
ぜんぜんわからない。私は雰囲気で Ruby を書いている。

## `'ゆるゆり♪♪'.next`
```ruby
'♪'.next
# => "♫"

'ゆるゆり♪♪'.next
# => "ゆるゆる♪♪"
```

( ´Ꙩωꙩ` )

*Ruby リファレンスマニュアル: [instance method String#next](https://docs.ruby-lang.org/ja/latest/method/String/i/next.html)*
> self にアルファベットや数字とそれ以外の文字が混在している場合、 アルファベットと数字だけが「次の」文字になり、残りは保存されます。

## `042`
```ruby
042
# => 34
```

`0` から始まる整数は `0o` と同じく、8進数の扱いになるみたいです。
これって Ruby に限らないことなのかな

```ruby
0_42
# => 34

0o_42
# SyntaxError (numeric literal without digits)
# 0o_42
# ^~~
```

:clap::cry:

## `?🍣`
```ruby
?🍣
# => "🍣"
```
完全に私が無知だっただけなのですが、`?` は文字リテラルです。
`'🍣'` と書くよりも `?🍣` のほうが 1 文字少ないので、コードゴルフに使えますね :golf::basketball_player:

## `[true, false, nil].one?`
```ruby
[true, false, nil].one?
# => true
```
完全に私が無知だっただけなのですが、
`Array#one?` は真（`nil`, `false` 以外）となる要素の数が `1` のときに `true` を返します。
ブロックを与えると、真偽をブロックの評価で行ってくれます。

## `'abc'[1.4142]`
```ruby
'abc'[1.4142]
# => "b"
```
`String#[]` や `Array#[]` の引数は `to_int` されるため、

```ruby
1.4142.to_int
# => 1
'abc'[1]
# => "b"
```
となるみたいです。

## `'abc'[3..3]`
```ruby
'abc'[4..4]
# => nil
'abc'[3..3]
# => ""
'abc'[3..2]
# => ""
'abc'[3..4]
# => ""
```
:sleeping:
*Ruby リファレンスマニュアル: [instance method String#[]](https://docs.ruby-lang.org/ja/latest/method/String/i/=5b=5d.html)*

## `cat = 'nya' if false`
```ruby
cat.nil?
# => NameError (undefined local variable or method `cat' for ...)

cat = 'nya' if false
cat.nil?
# => true
```
*Ruby リファレンスマニュアル: [ローカル変数](https://docs.ruby-lang.org/ja/latest/doc/spec=2fvariables.html#local)*
> 宣言は、例え実行されなくても宣言とみなされます。

ははぁん。

## `+str << 'piyo'`
```ruby
str = 'hoge'.freeze # または -'hoge'
+str << 'piyo'
str
# => "hoge"
```

?? :eye:ω :eye:

Frozen なオブジェクトへの変更、
たとえば以下のように `<<` を使ってオブジェクトに文字列を追記すると `FrozenError` が発生します。
（`+=` は新規オブジェクトを作って再代入するのでエラー出ないです）

```ruby
str = 'hoge'.freeze
str << 'piyo'
# => FrozenError (can't modify frozen String)
```

なので、`String#+@` したりするのですが、
これはレシーバが Frozen な場合に同じ文字列から成る、Frozen でない新規オブジェクトを生成するので、
その新規オブジェクトに `<<` で追記しても `str` に代入されず、どこかへ飛んでいってしまいます。じゃあの。

```ruby
str = 'hoge'.freeze
str.object_id
# => 47425922840860
+str.object_id
# => 47425922840860 （同じオブジェクト。呼び出し優先度が +@ よりも object_id のほうが高いため）
(+str).object_id
# => 47426029865800 （別のオブジェクト！）
```

*Ruby リファレンスマニュアル: [instance method String#+@](https://docs.ruby-lang.org/ja/latest/method/String/i/=2b=40.html)*

凍ったオブジェクトが代入されてる変数に追記して再代入して...とするなら、素直に `+=` つかったほうが良さそう。

```ruby
str = 'hoge'.freeze
str += 'piyo'
str
# => 'hogepiyo'
str.frozen?
# => false
```

もう一度冷凍するなら `(str += 'piyo').freeze` ってかんじで！ :snowflake:

Ruby 3 から文字列リテラルがデフォルトで Frozen になるっぽいので（そうなの？）、
`# frozen_string_literal: true`
を書いて準備されている方も多いと思います。事故にお気をつけを :helmet_with_cross:

この記事よかったです。楽しい
[Perfect Frozen String Literal](https://qiita.com/k0kubun/items/1c3e605645ba5ff683a1) by @k0kubun

## おわりの言葉
```ruby
def １＋１は？
  'みそスープ'
end

１＋１は？
# => "みそスープ"
```

**[雑感]**
秋になるとチェーン店がイモまみれになって、特にイモが好きでもない私は「またかー」ってなる
次はカボチャまみれ
Laravel5.6から5.7へのアップグレード

Laravel5.6(5.6.33)から5.7(5.7.9)にアップグレードしました。

手順は本家を参考
https://laravel.com/docs/5.7/upgrade

まずはcomposer.json内の`laravel/framework`を`5.7.*`に書き換えてアップデート

## laravel-query-detector

N+1検知用のライブラリがなんかひっかかった

[Error when upgrading when Laravel 5.6 to Laravel 5.7 · Issue #39 · beyondcode/laravel-query-detector · GitHub](https://github.com/beyondcode/laravel-query-detector/issues/39)

全く同じで0.4.1だったので、composer.jsonのバージョンを`0.6`に書き換えて

laravel-query-detectorだけを先にアップデート。

## hamburgscleanest/laravel-guzzle-throttle

今度はhttpクライアントライブラリがひっかかった。

issue見てみたがそれらしいのが見当たらずreleases見たら**Laravel 5.7 Compatibility**の文字が。

https://github.com/hamburgscleanest/laravel-guzzle-throttle/releases/tag/v3.0.0

composer.jsonのバージョンを`2.0`から`3.0`に書き換え。

こちらは`illuminate/support 5.7`が必須になっているのでLaravelと同時にアップデート

## Likelihood Of Impact: Very High

とりあえず[Very High](https://laravel.com/docs/5.7/upgrade)だけ対応

## 無事終了

少ないけどテストもok

```sh
$ composer test
> phpunit
PHPUnit 6.5.13 by Sebastian Bergmann and contributors.

....................................                              36 / 36 (100%)

Time: 8.78 seconds, Memory: 32.00MB

OK (36 tests, 131 assertions)
```
firebase deploy時に起きたエラー

# Request had invalid authentication credentials.　Expected OAuth 2 access token, login cookie or other valid authentication credential.

訳：リクエストに無効な認証資格があります。 OAuth 2アクセストークン、ログインCookie、またはその他の有効な認証資格が必要です。

## 解決（その場しのぎ）
まだ根本的な解決策が見つからなかったため、その場しのぎの方法

```zsh:再度認証
firebase login --reauth
```

```zsh:再度認証(localhostでやっている場合)
firebase login --reauth --no-localhost
```

## 参考サイト
[I Can't Deploy Using firebase deploy](https://github.com/firebase/firebase-tools/issues/689)

# Error: Authentication Error: Your credentials are no longer valid. Please run firebase login --reauth

訳:認証エラー：資格情報はもはや有効ではありません。 firebase login --reauthを実行してください

やはり、reauthするしかないかもしれない

※原因が分かり次第追記する

## For CI servers and headless environments, generate a new token with firebase login:ci

訳：CIサーバーとヘッドレス環境では、firebase login：ciを使用して新しいトークンを生成します

- どうやらCI用のトークンを発行して利用するとうまくいくようだ

[CI用に認証トークンを用意する](https://qiita.com/yamacraft/items/d8b623cceb5c91692b65#ci%E7%94%A8%E3%81%AB%E8%AA%8D%E8%A8%BC%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%82%92%E7%94%A8%E6%84%8F%E3%81%99%E3%82%8B)

```zsh:CIのトークン発行
firebase login:ci
```

```zsh:CIのトークン発行(localhostでやっている場合)
firebase login:ci --no-localhost
```
すると、表示されるURLでCLIを使用する確認を求められるので、それに従うと以下のような表示がされる

```zsh:トークン発行時の表示
✔  Success! Use this token to login on a CI server:

1/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Example: firebase deploy --token "$FIREBASE_TOKEN"
```
xの羅列は任意の文字列になっており、プロジェクトごとに異なるようだ

<font color="red">こちらのトークンはどこかに記録しておこう</font>
~~deployの度に使うことになる~~
→一回トークンを合わせて使うと次からは`firebase deploy`だけでいけるみたい

deploy時は以下のように叩く

```zsh:deployとトークンをあわせて使う
firebase deploy --token 1/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```
MFCプログラマーの「MFC」ってなんですか？

Visual C++ によって実装された Microsoft のクラスライブラリ **Microsoft Foundation Class** です。

- [Microsoft Foundation Class - Wikipedia](https://ja.wikipedia.org/wiki/Microsoft_Foundation_Class)
- [Visual Studio 2017 Visual C++ による MFC デスクトップアプリ開発 (Dialog Base) - Qiita](https://qiita.com/tadnakam/items/13738da833801f297d9b)


要点をまとめてみると、

1. （過去）.NET Framework 登場前は Windows アプリ開発の主役
2. （現在） MFC の新規開発はもうないでしょう
3. （未来）古いアプリを流用したり、保守したりということはときどきある
4. .NET での開発が主流となって、 MFC を扱える人もどんどん減っている

MFC に長く触れていると、「C++ 開発者です！」と言い切れない歯がゆさがあったりします。（ラッパークラスばかり使うことになるので、標準C++へのキャッチアップが疎くなるような気がするからです）

```cpp:ダイアログベースアプリのイニシャライズの例
BOOL CMFCApplicationDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        BOOL bNameValid;
        CString strAboutMenu;
        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
        ASSERT(bNameValid);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    SetIcon(m_hIcon, TRUE);
    SetIcon(m_hIcon, FALSE);
    return TRUE;
}
```

`CDialog`、`CMenu`、`CString` など、`Cxxxx` クラスの prefix をもったものを扱いながら開発をすすめていきます。

## MFC の良き

Document View アーキテクチャーを採用していて、メッセージパッシングでビューとドキュメントがやり取りするようになっています。
MFCの作法にしたがうかぎり、ビューとドキュメントが疎結合で見通しのよいコードベースになります。



## MFC のツラみ

CObject から派生したクラスの学習サンクコストの高さ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/2883/ef4d8356-91b8-3be2-eb41-492ea6a376c7.png)
babel-loader8で最新のreactの環境を構築する

# babel-loader 8
なんか知らぬまにupdateされていたようで、久々にreactの環境構築をしよとしたらめちゃくちゃエラー出て焦ったのでそれのメモ。
要はwebpackでreactとかをjsにトランスパイルするときによしなにやってくれるやつ。
babel coreとかと一緒にwebpackにぶち込む。

# 何が変わったのか
babel-loaderを使うときに今まではbabel-coreとかbabel-preset-〇〇とかを使ってたのが、8系から@babel/〇〇ってライブラリを使うようになった。
なんだそれだけかって感じかもしれないが、呼び出しのときも変わったりして意外と面倒。

なので、変えないといけないところを変えたそのまま構築できるやつを載せときます。

# 環境構築

```shell
npm init
npm install --save react react-dom
npm install --save-dev webpack webpack-cli babel-loader @babel/core @babel/preset-env @babel/preset-react
```

で、必要なライブラリのインストールはおしまい。

次に、configを書いていきます。
`package.json`と同じディレクトリに

```js:webpack.config.js
const path = require("path");

module.exports = {
  entry: "./app.js",
  output: {
    path: path.join(__dirname, "static/js"),
    filename: "bundle.js"
  },
  resolve: {
    modules: ["node_modules"],
    extensions: [".js", ".jsx"]
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env", "@babel/preset-react"]
          }
        }
      }
    ]
  }
};
```

これで動くはず。
変わったポイントとしては、

```js
options: {
  presets: ["@babel/preset-env", "@babel/preset-react"]
}
```
ここが以前との違いです。これに気づかないと無駄に時間が溶けちゃいます。

あとはトランスパイルするだけ。

僕は普段、

```js:package.json
"scripts": {
  "watch": "npx webpack --mode development --watch",
  "build": "npx webpack --mode production"
},
```
を書いて、

```shell 
npm run watch
```
で実行しています。

これをすると保存のたびに差分でトランスパイルしてくれるので便利です。

# 動作確認

```js:app.js
import React from "react";
import ReactDOM from "react-dom";

class App extends React.Component {
  render() {
    return <div>hello react!</div>;
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
```

```html:index.html
<html>
    <head></head>
    <body>
        <div id="root"></div>
        <script src="./static/js/bundle.js"></script>
    </body>
</html>
```

`npm run watch`してから`127.0.0.1`をブラウザで開くと、hello react!と表示されるはずです。

[github](https://github.com/Dragon-taro/saga-sample/tree/template)にあげてあります。

僕のブログでReactの勉強法をまとめているのでこちらもよかったら！
[【progateの次はこれ！】reactの勉強手順まとめ](https://dragon-taro.com/technology/post-298/)

では、みなさんよいreactライフを〜！
ローカルにService DiscoveryできるConsulを入れた

```
version: '3'

services:

  consul:
    image: consul:latest
    ports:
      - "8400:8400"
      - "8500:8500"
      - "8600:8600"
      - "8600:8600/udp"
    command: "agent -server -bootstrap-expect 1 -ui -client 0.0.0.0"

  registrator:
    image: gliderlabs/registrator:latest
    network_mode: "host"
    depends_on:
      - consul
    volumes:
        - "/var/run/docker.sock:/tmp/docker.sock"
    command: consul://localhost:8500

networks: 
  default:
    ipam:
      config:
        - subnet: "172.30.0.0/16"
  
```
Excelのグラフのもとデータ範囲の選び方

Excelでグラフを描くのは簡単です。
でも、変更やデータ追加、削除はとても面倒で最初から作った方がいいんじゃないかと思うこともしばしば。
そこで、グラフの範囲指定の変更の方法についていろいろな方法をものすごくシンプルに紹介します。
# データ範囲の変更
データ範囲の変更方法は、本来であればグラフをクリックした後、グラフツールタブのデザインのデータ範囲で設定し直すというのが一般的ですが、ものすごく高速に行う方法２つを紹介します。
## マウスドラッグで変更
実は、データ範囲は、グラフを選択したときに現れる元データのシート上のフィルハンドルをドラッグして変更できます。
![bas30952.gif](https://qiita-image-store.s3.amazonaws.com/0/247287/f0b017cf-4797-e138-34cf-561fcc36747a.gif)
## 数式バーで変更
1つのデータ系列は、クリックし、もう一回クリックすると選べるので、この状態で数式バー上で範囲が見えますが、ここを書き換えます。
![bas30953.gif](https://qiita-image-store.s3.amazonaws.com/0/247287/523157ce-cbf2-1c43-73b6-b4aa23858e64.gif)
# データ範囲の追加
ワークシート上のデータはグラフにコピーできます。
ちょっと何言ってるかわかんないかもしれないので、実際の操作方法をご覧ください。
![bas30954.gif](https://qiita-image-store.s3.amazonaws.com/0/247287/db65c598-c7ab-9635-b687-8fd34c5533ec.gif)
# データ系列の削除
グラフ上のデータ系列を選んだ状態でDeleteキーです。
![bas30955.gif](https://qiita-image-store.s3.amazonaws.com/0/247287/de740369-ffd3-df14-50dc-441afa3d0f1e.gif)
# データの順番の変更
データの並び順は、その系列を選んだ時に数式バーに表示される関数のようなものの、一番後ろの引数を書き換えれば変わります。
![bas30956.gif](https://qiita-image-store.s3.amazonaws.com/0/247287/0e816a5e-198a-8046-aafe-43bc855db5fc.gif)
この数字、順番を表しているもののようなのですが、ほかに順番が1のものがあっても1と設定することもでき、その場合、従来の1は2に自動で変わります。
# まとめ
なかなか難しいExcelのグラフの変更ですが、この技を使うととても楽になります。
元データの複雑な場合はこの方法は使えませんが、一般的なグラフであれば覚えておくと効率化できますので、ぜひ、進捗報告、バグ報告にご活用ください。
Monacaカスタムデバッガ、デバッグビルドでiPhoneXに対応させる方法

# メモ
記事執筆時点では、monacaでビルドしたアプリはiPhoneXに対応してくれなかったので、なんとかしてみた。
忘れそうだったので、メモしておく。

## 原因と方法
iPhoneXが出た当初はmonacaアプリをiPhoneXに対応させるにはデフォルトではないSplashScreenの画像が必要だった。
多分今回もこれが原因だろうと思って調べてみた。

#### 基本的な対処法
① 解像度 2732 * 2732の「Default@2x~universal~anyany.png」を作成。
これをres/ios/screen/の中に入れる。

② config.xmlにこんな感じで追記する


```
<platform name="ios">
<!-- すでに入っているものは消さない -->
<!-- 追加で必要なのはこの1行↓ -->
<splash src="/res/ios/screen/Default@2x~universal~anyany.png" width="2732" height="2732"/>
</platform>
```

これでなんとかなる、はず。

## と思ったら。
①のDefault@2x~universal~anyany.pngはres/ios/screen/の中に既に入っていた。
②のconfig.xmlの記述がなかったからiPhoneXに対応していなかったみたい。

ファイルがあるのにxmlに記述していないのは謎だけれど、とりあえずこれで解決した。
.NET Standardってなに？

そういえば.NET Standardって何なのか知らなかったので、少し調べてみたこと。

# .NET Standardって何なのよ？
.NET Frameworkとか.NET Coreとかあるけれど、.NET Standardも同じようなフレームワークなの？→違います。仕様です。

# .NET Standardは仕様
[公式の説明](https://docs.microsoft.com/ja-jp/dotnet/standard/net-standard)によると、`.NET Standard`というのは`仕様`であって、実体のないAPIの目録みたいなもの。

で、この仕様に従って`.NET Framework`や`.NET Core`、`Xamarin.iOS/Mac/Android`、`UWP`といった様々な`.NET実装`においてAPIが実装されている。
それぞれの.NET実装は「固有部分のAPI」+「.NET Standard実装部分のAPI」からなる。

この.NET Standardに従って実装されたAPIというのは、どの.NET実装でも使えるAPIなので、このAPIだけを使ってライブラリを作成すれば、そのライブラリをすべての種類のアプリケーションの作成において使うことができる。

# .NET Standardのバージョンと各.NET実装の関係

ただし、.NET Standardにはもちろんバージョンがあり、各.NET実装のそれぞれのバージョンにおいて、どのバージョンの.NET Standardを実装しているかが異なる。
例えば、.NET Framework4.6が実装している.NET Standardのバージョンは1.3。
（[公式の説明](https://docs.microsoft.com/ja-jp/dotnet/standard/net-standard)を参照。）

複数の.NET実装の間で共通のライブラリを作成する場合は、それぞれのバージョンに気を付ける必要がある。

## .NET Standard準拠のライブラリありきで考えるとき
.NET Standard2.0に準拠したライブラリを作成し、それを.NET FrameworkとXamarin.Androidで使いたい場合、.NET Frameworkのバージョンは4.6.1以上、Xamarin.Androidのバージョンは8.0以上でなければならない。

## 既存のアプリケーションにあわせるとき
逆に、.NET Framework4.6のアプリケーションと、Xamarin.Android7.0のアプリケーションの間で一部処理をライブラリで共有化したい場合、ライブラリ作成時に選択する.NET Standardのバージョンは低いほうの「1.3」でなければならない。


# .NET Standardの下位互換性
.NET Standardは下位バージョンのAPIを完全に含むので、下位互換性100%。
例えば、.NET Standard2.0に準拠しているということは、それ以前のバージョンである1.6や1.0のAPIも含んでいるということ。

# おわりに

* .NET Standardはただの仕様。
* 各.NET実装において.NET Standardが実装されている。
* .NET Standardは下位互換性100%。
CoreOSで初期設定を変更して反映させる

CoreOSでインストールスクリプトでミスした場合に修正する方法です。

# パスワードhashを間違えてログインできない（シングルユーザーログイン）

パスワードを設定しないとログインできなくなります。

boot画面で`e`を押し、GRUB編集画面に入ります。

linux$...の行の最後に coreos.autologin=tty1を付け加え、`Ctrl+x`を押します。

<img width="572" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/14768/0ba3d5ac-0432-6ae5-e918-e5d156cb44a6.png">

コンソールログインができたらpasswdコマンドでパスワードを設定します。

```
passwd core
```

# 設定を書き換えたい

普通に設定を書き換えても最初にスクリプトで設定したものは、再起動すると初期値に戻ってしまうようです。なんでやー。

最初に設定した`cloud-config.yaml`は`/var/lib/coreos-install/user_data`として保存されているようです。

```
sudo vi /var/lib/coreos-install/user_data
```

その後、上記の自動ログインの方法を適用すると設定が反映されます。

# cloud-config.yamlの確認

書式だけは下記で確認できるようです。

https://coreos.com/validate/
配列の要素２つごとに線を引いて表示させる方法

この記事では、初心者向けに配列の要素を下記のように表示させるロジックを紹介したいと思います。
実行環境は、Ruby2.3.1  Rails5.2.1 です。

![96839ab1756c575a1204ae3b80818a25.png](https://qiita-image-store.s3.amazonaws.com/0/300592/85f246fd-f745-0b10-f207-ba179e8a93cf.png)



重複なくデータを表示させるためのRubyの便利なeach_with_indexメソッドを紹介させていただきます。


each_with_indexメソッドの書き方

```

配列.each_with_index do |item, i|
```

具体的なソースコード

```erb

games=[“将棋”, “囲碁”, “オセロ”]

#配列gamesを用意

games.each_with_index do |item, i|

puts “#{i+1}番目の要素は#{item}です。”

end


結果

1番目の要素は将棋です。

2番目の要素は囲碁です。

3番目の要素はオセロです。
```


次にループの処理が２回行われるごとに線を引きます。



```erb

<% @post.each_with_index do |post, i| %>

  <% if i%2==0 %>
    <hr>

    <%= post.id %>
  
  <% else %>
    <div clasa = "content2">
    <%= post.id %>
    </div>
  <% end %>

<% end %>

```

これで下記のとおり、データ２つごとに線を引く動作が出来ます。


![a6e6402637c740f6e9a663db66532f06.png](https://qiita-image-store.s3.amazonaws.com/0/300592/b5568098-71ed-c7b1-a629-34801de6cdd3.png)

あとは、データベースから画像を受け取ったり、レイアウトを調整すれば、下記のようなものが創れます。
![8d27b2d1faef85495ae44be47df8c320.png](https://qiita-image-store.s3.amazonaws.com/0/300592/612755c9-82f5-ace8-3c56-d0720bae75e4.png)

以上です。
Docker for DesktopのKubernetesでローカルdockerで作ったイメージを使う

https://stackoverflow.com/questions/51826603/kubectl-run-from-local-docker-image

`imagePullPolicy: Never`を設定する。
初期値IfNotPresentだと駄目らしい。`image-name:1.0`でも駄目だった。

```
piVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
    - name: my-app
      image: image-name:1.0
      imagePullPolicy: Never
```

サーバで`imagePullPolicy: Never`を設定することはあまりないと思うので、ローカル開発用と本番用で設定が違うのちょっと微妙。
S3にファイルをアップロードしたときに自動的にCache-Controlを設定する

はじめに
---
ふとPage Speed Insightを眺めていたら、ブラウザキャッシュが効いてないファイルが・・・ :thinking: 
そういえば、S3に置いてるファイルって`Cache-Control`設定されてないやん！:open_mouth:
ということで、AWS Lambdaを使って、S3にアップロードされたときに自動的に`Cache-Control`を設定する仕組みを作っていきます :muscle: 


Lambdaを作成する
---
まずは要のLambda functionを作っていきます。

一から作るよりもテンプレートを使ったほうが手っ取り早いので、

関数の作成 > 設計図 > `s3-get-object` を選択して「設定」をポチります。

適当な関数名をつけて、ロールもテンプレートから新しく作成しちゃいましょう。
（このロールのままだと権限が不足してるのであとで編集していきます :point_up: ）

![スクリーンショット 2018-10-11 15.54.32.png](https://qiita-image-store.s3.amazonaws.com/0/611/62e8e032-7adb-b457-9fb5-0cc2b4a715e8.png)

S3のイベントタイプは「PUT」を選択し、「関数の作成」をポチります。

![スクリーンショット_2018-10-11_15_47_19.png](https://qiita-image-store.s3.amazonaws.com/0/611/8deb8cf4-b530-8863-6ccf-54ca5d54f1ed.png)

するとこんな感じで関数ができあがります。
![スクリーンショット 2018-10-11 16.35.42.png](https://qiita-image-store.s3.amazonaws.com/0/611/ea3595e8-2607-0e93-722b-942116a66ee6.png)



テンプレートの関数を編集して、`Cache-Control`を付与するように書き換えます。
（今回は`max-age=86400`にしました）

```js
console.log('Loading function');

const aws = require('aws-sdk');

const s3 = new aws.S3({ apiVersion: '2006-03-01' });


exports.handler = async (event, context) => {

    const bucket = event.Records[0].s3.bucket.name;
    const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    console.log('Bucket: ', bucket);
    console.log('Key: ', key);

    try {
        const data = await s3.getObject({Bucket: bucket, Key: key}).promise();

        const contentType = data.ContentType ? data.ContentType : 'application/octet-stream';
        const params = {
            Bucket: bucket,
            CopySource: `${bucket}/${key}`,
            Key: key,
            ContentType: contentType,
            CacheControl: "max-age=86400",
            MetadataDirective: "REPLACE"
        };

        const newData = await s3.copyObject(params).promise();        

        console.log('success!');
    } catch (err) {
        console.log(err);
        throw new Error(err.message);
    }
};
```

いったんここで「保存」をポチっておきます。 :sleeping: 


ロールを編集する
---
テンプレートから作成したロールのままだとS3の読み込み権限しかないので、書き込み権限を追加します。

IAM > ロール に移動し、作成したロール（今回だと`lambdaS3Role`）のS3ポリシーに書き込み権限を追加します。

VisualEditorでポチポチ設定できます。お手軽〜 :smile: 
![スクリーンショット 2018-10-11 16.09.08.png](https://qiita-image-store.s3.amazonaws.com/0/611/6e815164-0504-4117-6b5d-4b60c62f5a1a.png)

結果、S3に関するポリシーに`s3:PutObject`が追加されました :point_down: 

![スクリーンショット_2018-10-11_16_10_16.png](https://qiita-image-store.s3.amazonaws.com/0/611/8d00a87e-75bc-f2b6-d3a9-bd905c82121c.png)


動作確認する
---
では、Lambdaもロールも完成したので、動作確認しましょう。

実際に画像をUPLOADしてみると、`Cache-Control`が設定されました :tada: 
![スクリーンショット_2018-10-11_16_12_17.png](https://qiita-image-store.s3.amazonaws.com/0/611/3817d485-834b-ca5a-82ff-0a98cc991064.png)


めでたしめでたし :hugging: 



参考
---
- [Amazon S3の画像をAWS Cloudfrontで配信するキャッシュコントロールをAWS Lambdaで自動化する ｜ DevelopersIO](https://dev.classmethod.jp/cloud/aws/s3-cache-control-by-using-lambda/)
- [[AWS][Lambda] S3に put object されたら自動的に Lambda で Expires ヘッダを追加する - Qiita](https://qiita.com/wokamoto/items/85506f44b16cd0dfea32)
- [Class: AWS.S3 — AWS SDK for JavaScript](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html)
PythonでElasticsearchのSearch APIを使って検索するときのめも

ElasticsearchのAPIで10000件以上のデータを検索するとなると　一回じゃデータを取れないから[分割して検索](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html)するのか〜面倒だなということでpythonで書きました。

これですねー

```python
#!/usr/bin/env python3

import urllib.request
import json
import sys
from optparse import OptionParser

def print_message(msg):
    print(msg, file=sys.stderr)

def do_request(url, query):

    json_data = json.dumps(query).encode('utf-8')

    req = urllib.request.Request(url, data=json_data, method='GET')
    with urllib.request.urlopen(req) as res:
        body = res.read()
        return json.loads(body)

def dump_to_file(data, prefix, index):
    name = "%s_%02d.json" % (prefix, index)

    with open(name, mode="w") as f:
        json.dump(data, f, indent=2)

def build_query(options, scroll_id):
    if scroll_id is not None:
        return {
            "scroll_id": scroll_id,
            "scroll": "10m",
        }

    with open(options.jsonfile, "r") as f:
        return json.load(f)

def build_url(options, scroll_id):
    if scroll_id is not None:
        return "{}/_search/scroll".format(options.url)

    params = {
        "size": 10000,
        "scroll": "10m",
    }
    return "{}/{}/_search?{}".format(options.url, options.index, urllib.parse.urlencode(params))

def parse_arguments(args):
    parser = OptionParser()
    parser.add_option("-j", "--json", dest="jsonfile",
                      help="query file", metavar="JSON")
    parser.add_option("-u", "--url", dest="url",
                      help="e.g. https://es.example.com", metavar="URL")
    parser.add_option("-i", "--index", dest="index",
                      help="index name", metavar="INDEX")
    parser.add_option("-p", "--prefix", dest="prefix",
                      help="output file name prefix", metavar="PREFIX",
                      default="log")
    parser.add_option("-m", "--maxpages", dest="maxpages",
                      help="max pages", metavar="MAXPAGES",
                      default=20)

    (options, args) = parser.parse_args()

    if options.jsonfile is None or options.url is None or options.index is None:
        print("invalid options: run %s -h to see more information" % sys.argv[0])
        sys.exit(0)

    return options

if __name__ == "__main__":
    scroll_id = None

    options = parse_arguments(sys.argv)

    for i in range(1, options.maxpages):
        print_message("[*]fetch log:%d" % i)
        url = build_url(options, scroll_id)
        query = build_query(options, scroll_id)

        result = do_request(url, query)
        if len(result["hits"]["hits"]) == 0:
            print_message("[*]no more data")
            break

        dump_to_file(result, options.prefix, i)

        scroll_id = result["_scroll_id"]
        result = None

    print_message("[*]Done")
```

1回目のURLは __/index名/_search/__ なんだけど2回目からは __/_search/scroll__ にしないといけないんですね。あと、bodyで渡すデータも1回目は通常のjson形式の検索条件だけど2回目からはscroll_idとscrollを渡すだけになる。

scroll_idは1回目の検索結果に_scroll_idというキーにデータがあるのでこれを使う。
上記のスクリプトで試した感じ値はforループが何回か回っても変化なかったのでscrollで指定した期間内は同じ値なんでしょうね（未確認）。
react-native-navigationでモーダル遷移時に画面がチラつく

react-native-navigationを使ってモーダル遷移時をするとNavigationBarがチラついてしまいました。
AppDelegateのdidFinishLaunchingWithOptionsメソッド内で、NavigationBarの背景画像に空画像を設定してあげることで解決しました。

```objective_c
[[UINavigationBar appearance] setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setShadowImage:[UIImage new]];
```
ActiveRecord で "最新の子" を has_one で表現する

たとえば、複数のバージョンを持つブログの記事を下記のようなモデルで表現しているとする。

```ruby
class Entry < ApplicationRecord
  has_many :versions

  def latest_version
    versions.order(number: :desc).first
  end
end

class Version < ApplicationRecord
  belongs_to :entry
  # 新しいバージョンほど number の値が大きいものとする
  validates :number, uniqueness: true, numericality: {greater_than: 0, only_integer: true}
end
```

このとき最新のバージョンは `Entry.find(1).latest_version` で得られるが、単なるメソッドなので `includes` などを使うことができない。

`has_one` では絞り込みの条件を lambda で渡す事ができるので下記のように書けばよい。

```ruby
class Entry < ApplicationRecord
  has_many :versions
  has_one :latest_version, -> {
    # 同じ entry_id で number がこれより大きいレコードが存在しない、という条件
    where(
      <<~SQL
        NOT EXISTS (
          SELECT 1 FROM versions AS v
            WHERE
              versions.number < v.number AND
              versions.entry_id = v.entry_id
        )
      SQL
    )
  }, class_name: "Version"
end
```

これで `Entry.includes(:latest_version).find(1).latest_version` のように書ける。
実は奥が深いpythonのprint関数の使い方

# 　はじめに
pythonの基礎として、print関数の扱いについて記載します。

#　環境
python3.6
anaconda1.8.7
macOS

# 　print関数
文字列、変数、計算などの結果を出力する関数。
もともとは、print文という存在でしたが、python3で関数になっています。

# 　やってみる


```python
>>>print("Hello world!")
Hello world!
```

print関数では、変数を出力することもできます。


```python
>>> word1 = "hello"
>>> word2 = "world"
>>> print(word1,word2)
hello world
```
違う型でもOK。

```python
>>> word1 = "hello"
>>> number1 = 4649
>>> print(word1,number1)
hello 4649
```

コンマで区切ればいくつでも出力可能です。
また通常はスペースで区切られますが、任意のセパレタを指定可能です。

```python
>>> word1 = "hello"
>>> number1 = 4649
>>> print(word1,number1,sep=",")
hello,4649
>>> print(word1,number1,sep=":")
hello:4649
```



## 　リストや辞書の出力

リストや辞書型オブジェクトなどの中身も出力できます。

リスト型

```python
>>> ittosanken_list = ["tokyo","kanagawa","saitama","chiba"]
>>> print(ittosanken_list)
['tokyo', 'kanagawa', 'saitama', 'chiba']
```
セパレタを指定すればアンパックすることもできる

```python
>>> print(*ittosanken_list)
tokyo kanagawa saitama chiba
>>> print(*ittosanken_list,sep='')
tokyokanagawasaitamachiba
```

リストの中身が全て表示されます。


続いて辞書型オブジェクト。
辞書のkeyとvalueの両方が出力されます。

```python
>>> shopping_dict = {"milk":200, "natto":150, "tofu":100}
>>> print(shopping_dict)
{'milk': 200, 'natto': 150, 'tofu': 100}
```

##　print関数のその他

お気づきのように、明示されていないものの、末尾には改行が入っているので
プライマリプロンプトは出力の次の行に移動しています。

```python
>>> print("hello world!")
hello world!
>>> 
```

以下のようにendオプションで空指定することで、末尾の改行を削除することができます

```python
>>> print("Hello world!",end="")
Hello world!>>>
```



##　formatメソッド

formatを使うと、文字列の中に変数を埋め込むことが出来ます。

formatを使用すればprint関数で変数の値を出力することができます。

```python
>>> print("I eat {}.".format("eggs"))
I eat eggs.
```

引数を複数指定し対応する {} を記述すると複数の要素を埋め込める。
引数の数と {} の数は同一であることに注意が必要

```python
>>> print("area: {}, age {}.".format("chiba", 33))
area: chiba, age 33.
```

 {} の中に引数に対応する数を指定すると、指定した値を埋め込める。

```python
>>> print("{0}, {1}, {0}".format("chiba", "saitama"))
chiba, saitama, chiba
```

formatの引数に辞書を指定。 
 {} の中には指定する引数の数と辞書の角括弧 [] の中にキー値を指定することで呼び出しができる。

```python
>>> dict = { "area": "chiba", "age": 33 }
>>> print("area: {0[area]}, Age: {0[age]}".format(dict))
area: chiba, Age: 33
```

※.format()とfstringは数値列であっても埋め込むことができる。

#　おわり
まだまだやれることはありますが、また別途記載します。
or列挙、リスト、タプル、集合でのif文の速度評価

# まえがき
[Pythonにおけるif文の長いor列挙の回避方法](https://qiita.com/takey/items/8d0a2497f78ab575d378)

上記の記事で、if文においてorを列挙するよりリストのin演算子を使用したほうが少しスマートと書いた。
はたして速度面ではどうか。

# 計測
とても長いプログラムをベタ書きしたら記事にアクセスできなくなったので、プログラムは以下を参照してください。

https://gist.github.com/taketakeyyy/33c460066ec9a1a75f5cf55cfbb043a9

# 結論
- リストとタプルを使ったin演算子によるifの比較が最も速い（両方とも同程度の速さ）
- orの列挙もリストと比べて遅すぎるというわけではない
- 集合（set）は遅すぎる

メモリ使用量は考慮していない。
上記結果をふまえて、個人的にはやはりin演算子を使ったほうが少しスマートだと思う。
Support Libraryを28.0.2に上げたらFABの中のアイコンがずれちゃった


Support Libraryのバージョンを27.1.1から28.0.2にしたらFABのアイコンがこんなふうにずれてしました。

![Kobito.F7eVem.png](https://qiita-image-store.s3.amazonaws.com/0/18273/fb436ca9-3e95-40f9-188a-539782023657.png "Kobito.F7eVem.png")

FABのサイズを`layout_height`と`layout_width`でカスタム値を指定しており、中のアイコンも24dpとは異なるサイズだったせいかもしれません。

もとのコードはこんな感じでした。

```xml
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/hoge"
        android:layout_width="66dp"
        android:layout_height="66dp"
        android:scaleType="center"
        android:src="@drawable/icon"
        />
```

それを以下のように`fabCustomSize`でサイズを指定することで修正すると正常になりました。

```xml
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/hoge"
        app:fabCustomSize="66dp"
        android:layout_width="66dp"
        android:layout_height="66dp"
        android:scaleType="center"
        android:src="@drawable/icon" />
```

![Kobito.qYOvej.png](https://qiita-image-store.s3.amazonaws.com/0/18273/211d27b2-dea2-383b-787c-5f2d0bd68c26.png "Kobito.qYOvej.png")
CoreOSでdocker0のIPアドレスを変更する

過去に[docker0のIPアドレス帯を変更する方法](https://qiita.com/bellx2/items/21fdc3bdc6958f749f3e)をポストしたが、CoreOSを使ったらもう一度同じところでハマったので、再調査。

#環境

CoreOS 1855.4.0

#変更方法

1.ファイルを作成

`sudo vi /etc/systemd/system/docker.service.d/docker.conf`

```:/etc/systemd/system/docker.service.d/docker.conf
[Service]
Environment="DOCKER_OPTS=--bip=192.168.200.1/24"
```

2.サービス再起動

`sudo systemctl daemon-reload`
`sudo systemctl restart docker.service`

#参考

docker0のIPアドレス帯の変更
https://qiita.com/bellx2/items/21fdc3bdc6958f749f3e

Customizing docker
https://coreos.com/os/docs/latest/customizing-docker.html
iPhone Xs Max の判定


# iPhone Xs Max 辛い

最近出たiPhoneXsMaxがreactnativeで対応されていないところが多くて、
iPhoneXsMax用の判定できるようにした。
これを判定させたいところでimportするだけで大丈夫!(booleanで返ってくるから便利だと思う)

```
import { Platform, Dimensions } from 'react-native';

const XSMAX_WIDTH = 414;
const XSMAX_HEIGHT = 896;

// iPhone XS Max対応
export const _IPhoneXsMax = () => {
  const { width, height } = Dimensions.get('window');
  return (
    Platform.OS === 'ios' &&
    (width === XSMAX_WIDTH && height === XSMAX_HEIGHT)
  );
}
```
使用例

```
import {_IPhoneXsMax } from "path"

height: _IPhoneXsMax()
        ? 110
        : 92
```
判定ロジックを見やすくするための工夫


# データが存在するかの判定をするとき
指定したキーがオブジェクト内に存在するかの判定を行うケースで見てみましょう。

## ベタ書きした場合

```javascript
  function filtering(data) {
    if (data.name) {
      // 名前データが存在するときの処理
      console.log("exist");
      
    } else {
      // 名前データが存在しない時の処理
      console.log("not exist");
    }
  }
  
  
  var data = {
    id:1
  };
  
  filtering(data);

  // not exist

```

これでもわからなくはないですが条件が増えてくると見づらくなりますし、何より判定ロジックの使い回しができません。
コードが短くなるという利点はありますが1度変数に入れて意味を持たせた名前に格納する方が可読性が上がります。


## 三項演算子で簡単な存在判定してみる

判定ロジックを1度変数に格納してみましょう。
今回の場合は存在するかが条件なので `isNameExist` と命名してみます。
データが存在する場合は `true` 、存在しない場合は `false` が入ります。

```javascript
  function filtering(data) {
    const isNameExist = data.name ? true : false;

    if (isNameExist) {
      // 名前データが存在するときの処理
      console.log("exist");
      
    } else {
      // 名前データが存在しない時の処理
      console.log("not exist");
    }
  }
  
  
  var data = {
    id:1
  };
  
  filtering(data);

  // not exist
```

このままでも問題はないですが判定ロジックに不安があります。

たとえば、

```javascript
  var data = {
    name:" "
  };
```
こういうデータが来た時存在する扱いになってしまいます。
なので判定ロジック部分だけ別関数に分けるようにしましょう。
他の処理で同じ判定をしなければならないときも使い回せて便利です。


## 別関数に分けた判定関数を使って1度変数に格納し判定する
`isKeyExist`という関数を作ってみました。(文字列系キーの存在判定をする際に使い回せる命名。もちろんNameの存在判定をする時に独自の判定をする場合は`isNameExist`が適切かと思われる)
とりあえず空白のみだと空と判定してほしいので`trim().length`を使用して複数条件にしてみます。
ちなみにconstでオブジェクトを作ってそれぞれの判定結果を持たせておくと後から拡張するとき簡単に済むのでかなり楽でおすすめです。

```javascript
  function isKeyExist(key) {
    var isExist = false;
    var valueLength = key.trim().length;

    // keyが存在し、格納されている文字列が空白など以外で1文字以上
    if(key && valueLength > 0) {
      isExist = true;
    }
    
    return isExist;
  }
  
  function filtering(data) {
    // 2回以上判定結果を使いたい場合1度変数に格納する
    const isExist = {
      name: isKeyExist(data.name)
    };

    if (isExist.name) {
      // 名前データが存在するときの処理
      console.log("exist");
      
    } else {
      // 名前データが存在しない時の処理
      console.log("not exist");
    }
  }
  
  
  var data = {
    id:1,
    name:" "
  };
  

  filtering(data);

  // not exist
```

ちなみに1回しか判定しない場合こんな書き方でも大丈夫です。関数名の命名がイケてるとこれでもまあまあ読みやすくはなります。

```javascript
  function filtering(data) {
    if (isKeyExist(data.name)) {
      // 名前データが存在するときの処理
      console.log("exist");
      
    } else {
      // 名前データが存在しない時の処理
      console.log("not exist");
    }
  }
```

### 三項演算子パターン
これは短くはなりますが正直可読性めっちゃ落ちると思います。


```javascript
  function filtering(data) {
    isKeyExist(data.name) ? console.log("exist") : console.log("not exist");
  }
```

まあでも存在してる時の処理と存在しない処理を関数に分けたらスリムにはなりそうですね。

```javascript
  function filtering(data) {
    isKeyExist(data.name) ? keyExistProcess(data.name) : keyNotExistProcess();
  }

  function keyExistProcess(name) {
    console.log("exist");
    console.log(name);
  }

  function keyNotExistProcess() {
    console.log("not exist");
  }
```

これでも正直横に長過ぎてわかりにくい気がするなあ

## まとめ

ifに複数条件をめっちゃくっつけるときは読みやすくする工夫をするために、関数に判定ロジックを分けたり変数に1回入れたりしましょう。読みやすくなると思います。
windows10にPython3.6とtensorflowをインストールする方法

#Python3.6のインストール
*※ 2018/10現在、tensorflowを動かすにはPython3.7ではダメらしい。*

下記URLよりPython本体をダウンロードする。
https://www.python.org/downloads/windows/

・ Python 3.6.7rc1 - 2018-09-26 
　 「Windows x86-64 executable installer」あたりが妥当。

ダウンロードしたインストーラに従い、Pythonをインストールする。


#### Pythonのインストール確認
`$> C:\WINDOWS\system32>python --version`
`$> Python 3.6.7rc1`

※ うまくいかない場合、環境変数のパスが通っていないと考えられるため
システム環境変数のPathにインストールしたPyrthonフォルダ
例：[「C:\~~\Python36」、「C:\~~\Python36\Scripts」]、へのパスが通っているか確認する。


#### pipのUpgrade
*※pipとはpython用のパッケージ管理システムのこと。*
場合によってはpipが古く、tensorflowのインストールに失敗するため、アップグレードしておく。
`$> python -m pip install --upgrade pip`

# tensorflowのインストール
下記コマンドにてtensorflowをインストールする。
`$> pip install tensorflow`

#### tensorflowのインストール確認
`$> python -c "import tensorflow as tf; print(tf.__version__)"`
`$> 1.11.0`


とりあえずここまで。
昔受けたスクラム研修のメモ

# Sprint Planning(スプリント計画)
目的：短期間で、**何を**、**どのように**実現するか
時間：だいたい２〜４時間/Week

Input:プロダクトバックログ
Output:選択されたプロダクトバックログ＆スプリントバックログ

プロダクトバックログ(PBL)→目的の資料、相対見積もり
スプリントバックログ(SBL)→PBLを実現するための具体的なタスク一覧。絶対見積もり(時間)

やること
次のスプリントで何をするかを計画する

メモ：
- チームが働ける時間≠勤怠時間（本当にチームがプロダクトに費やせる時間がチームが働ける時間.
だいたい１日５時間くらい)

Howto相対見積もり
- 一番単純なモノを２とする
- その後相対的に８となるものを決める
- その２つの作業をベースに大きいか、小さいかで見積もって行く


# Daily Scrum(デイリースクラム)
目的：チームが**学習したことを共有すること**
時間：15分/日。終わりの時間厳守

Input:SBL、チームの学習
Output:最新のSBL

やること
今日、何をやるか、昨日学んだことを共有する

DailyScrumで３つの聞くべきこと
- (前日のDailyScrumから)何をしたか
- (次のDailyScrumまでに)何をするか
- 気にしていること、懸念事項

メモ：
- **問題解決の議論の場ではない**

# Product Backlog Refinement(プロダクト計画)
目的：中・長期的な計画
時間：2~5時間/2Weeks(まとめてやる必要はない)。時間厳守(時間かけても終わらないものだから)

やること
次回以降のスプリントでやること・優先度を決める

Input:PBL、マーケットの動き、顧客の情報、チームからの情報
Output:最新のPBL

プロダクトバックログの要素は**INVEST**の原則を満たすようにする
I - Independent(独立していて、他の作業に依存していないこと)
N - Negotiable(交渉可能であること)
V - Valuable(顧客にとって価値のあるものであること)
E - Estimable(見積もり可能な単位であること)
S - Sized Right(小さい手頃なサイズであること。大きすぎないこと)
T - Testable(テスト可能であること。その作業が完了したかどうかが明確に分かること)

# Sprint Review(スプリントレビュー)
目的：Productの現状を確認する、Productをよりよくするための議論をする
時間：1~2時間/sprint。各スプリントの最後らへんでやる

Input:製品、選択されたプロダクトバックログ（つまり、SBL)、みんなからのコメント
Output:ステータス(Accept/Deny)の更新されたプロダクトバックログ

# レトロスペクティブ(振り返り)
目的：チームの働き方を改善する
時間：1~2時間/sprint

メモ：プロダクトの話はNG

Intput:SBL、チームの学び
Output:次のスプリントでTryしてみること

# Define of Done(完了の定義)
What is ：全てのプロダクト、リリース共通でやることの定義一覧

Done:スプリント中に実現可能かどうかの判断で、可能なもの
UnDone:スプリント中に実現可能かどうかの判断で、できないもの

Undoneに割り振られたものはPBLに追加し、作業として扱う

メモ：
- Undoneを減らせばリスクが減って行く
- Undoneの作業をするスプリントをリリーススプリント、あるいはバーンスプリントと呼ぶ
- Sprint単位のアウトプット(ベロシティ)を安定させる。Undoneを減らすことが重要
GCPストレージの概要説明


# データを格納する場合はどのサービスを使えばいいの？
- [Google Cloud Storage](#google-cloud-storage)
- [Google Cloud Datastore](#google-cloud-datastore)
- [Google Cloud SQL](#google-cloud-sql)
- [Google Cloud Spanner](#google-cloud-spanner)
- [Google Cloud Bigtable](#google-cloud-bigtable)
- [Google BigQuery](#google-bigquery)


## Google Cloud Storage
構造化データではない場合、 `Cloud Storage`を使います。

## Google Cloud Datastore
リレーショナルデータベースでは無い場合は、`Cloud Datastore`を使います。

## Google Cloud Spanner
リレーショナルデータベースが必要な場合は `Cloud SQL` or `Cloud Spanner`、
高拡張性が必要な場合は、 `Cloud Spanner`を使います。

## Google Cloud SQL
リレーショナルデータベースが必要な場合は `Cloud SQL` or `Cloud Spanner`、
拡張性が気にならない、元々MySQLなどで十分だった場合は、 `Cloud SQL`を使います。

## Google Cloud Bigtable
データ解析をする場合は、 `Cloud Bigtable` or `BigQuery`、
低レイテンシーが必要の場合は `Cloud Bigtable`を使います。

## Google BigQuery
データ解析をする場合は、 `Cloud Bigtable` or `BigQuery`、
レイテンシーを気にしない場合は `BigQuery`を使います。

## 選択に迷ったらこれ！
![flowchart](https://cloud.google.com/images/storage-options/flowchart.svg)

**参考 :**
[Google Storage Options](https://cloud.google.com/storage-options/)
Java AppletをIDEを使わずにコマンドラインで簡単に使いたい

ke9000氏が書いた「 [Java AppletをIDE使わずにビルドしたい](https://qiita.com/ke9000/items/3fa9b3645ceeff5ec223) 」を試していたところ、一つのプロジェクトならいいが、学校の授業のように頻繁にソースコードを切り替えるときには、毎回HTMLファイルを書き換え、Classesフォルダを作り・・・っとやるのは大変なことに気づいた。
そこで、LinuxやMac等のOSに限るが、簡単に操作ができるようにしてみる。
もちろんやってることは当たり前すぎて、参考になるほどでもないが、備忘録として書いておく。
基本的に先述の記事を読んだことを前提に進めるが、一応適宜コードは書いていく。
(**注:　Classesフォルダに毎回コピーをしているのは、授業ではNetBeansを使用しているため、srcフォルダから元ソースファイルを動かせないためである**)

## 1. フォルダ構成について
今回は、~/Javaというフォルダ内で作業する。
Java/の中にプロジェクトフォルダがあり、その中にソースコードがあるという前提で話をすすめる。

## 2. HTMLファイルを用意する
```html:applet.html
<html>
<head><title>Applet Test</title></head>
<body>

<applet code="CLASS_NAME.class" width="150" height="150">
</applet>

</body>
</html>
```

これを**~/Java/applet.html**として保存する

## 3. シェルスクリプトを書く
```shell:applet.sh
#!/bin/sh

javac $1.java
# 引数として渡された名前の.javaファイルをコンパイル
 
if [ -e $1.html ]; then
    :
else
    cat <Javaフォルダのパス>/applet.html |  sed "s/CLASS_NAME/$1/" > $1.html
fi
# 先程作ったhtmlファイルをベースに、「CLASS_NAME」をそのときに使うファイルに変更したものを作る。あったら作らない。

mkdir Classes 2>/dev/null
# Classesフォルダがなかったら作る

cp *.class Classes
# コンパイルでできた.classファイルをClassesにコピー/上書きコピー

appletviewer $1.html
# Appletを起動
```

mkdirのところはifで分岐させても良かったが、エラーは単純に「すでにあるから作れないよ！」なので、表示させなければそれでいいということでこうした。
ちなみにapplet.htmlとapplet.shは同じディレクトリにいることを前提としている

## 4. エイリアスに登録する
今作ったシェルスクリプトを、.javaフォルダのあるところで簡単に実行できるようにbashrcに書く

```shell:.bashrc
alias applet='<applet.shのパス>/applet.sh'
```

## 5. 使ってみる

アプレットを使用したプログラムのソースコード(hoge.java)の位置まで移動して、
```applet hoge```(.javaはいらない)
で、コンパイルから指定フォルダまでの移動、起動までやってくれる)

以上。

~~元記事でも言ってるけど、JavaAppletって非推奨なんじゃないの？~~
CSSで複数の列にまたがる文章をレイアウトする

初記事なので、簡単なものを。。
以前社内でちらっと言ってみたら誰も知らなかったという事があったので、もしかしたら知らない方もいるかも・・・いないかも・・・

# TL;DR:
[columsプロパティ](https://developer.mozilla.org/en-US/docs/Web/CSS/columns)を使います。

# CSS columns プロパティ

![columns-sample.png](https://qiita-image-store.s3.amazonaws.com/0/300822/c9cc17db-05af-48e4-4809-9b4192c811cc.png)

こういうレイアウトを実装するとします。
最初はdisplay: flexを使ってあーだこーだやってたのですが、
よく考えたら英語ベースなのにこのレイアウトが再現できない*1なんてことは無いよなと気付き調べたらありました。

*1 マルチカラムレイアウトは英字新聞等紙媒体で一般的に見られます。

## 詳細

これだけだとなんともあれなので・・・

指定の仕方としては、「列数指定」か「幅（サイズ）指定」の２パターンがあります（併用可）。

具体的に言うと、

```css
/* .article-box */
.article-box {
  columns: 3 150px;
}
```

これだけです。
なお、幅サイズ指定だけにしておくと、ブラウザ幅に収まりきらない場合勝手にカラム数が減ります。

誰かの役に立てれば嬉しいです。
でもよく考えたらQiitaなので（？）次からはJSの話書くようにします。
faviconとホーム画面アイコンを作る

1.180x180のpng画像作成
2.下記サイトを使用してマルチicoを作成
https://ao-system.net/favicongenerator/
3.metaに記入

```
<link rel="shortcut icon" href="https://XXXX.com/favicon.ico" type="image/vnd.microsoft.icon">
<link rel="icon" href="https://XXXX.com/favicon.ico" type="image/vnd.microsoft.icon">
<link rel="apple-touch-icon" href="https://XXXX.com/webclipicon.png">
```
Vueの疑問(随時更新)

# Vueインスタンスの`el`と`.$mount()`の違い
- ほぼ一緒だけど、`.$mount()`は「**特定の要素がある**」もしくは「**非同期プロセスが完了させる**」という理由でマウントを遅らせたいときに使える。

[Difference between .$mount() and el [Vue JS]](https://stackoverflow.com/questions/46831452/difference-between-mount-and-el-vue-js)
***

# ライフサイクルフックで何が起きているのか
[インスタンスライフサイクルフック](https://jp.vuejs.org/v2/guide/instance.html#%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B5%E3%82%A4%E3%82%AF%E3%83%AB%E3%83%95%E3%83%83%E3%82%AF)
下の絵の**<font color="Crimson">赤い外線</font>**で囲まれたところ
![vue lifecyle](https://jp.vuejs.org/images/lifecycle.png)

| イベントフック名    | 説明                                                      |
|:--------------:|:--------------------------------------------------------:|
| beforeCreate   | すべてのフックの中で一番最初に実行されるフック<br>data,eventがまだセットされていないのでアクセスできない|
| created        | data,eventにアクセスできる<br>まだテンプレート、DOMはレンダリングされていない<br>コンポーネントの最初にセットされないといけないdataをここでセット|
| beforeMount    | テンプレートがコンパイルされ、初めてレンダリングが起きる|
| mounted        | コンポーネント、テンプレート、DOMにアクセスできる<br>ただし、[子コンポーネントが先にマウントされる](https://cdn-images-1.medium.com/max/2000/1*RX2SmRXgdIsUOApbUq9HIQ.png)のですべての子コンポーネントに対してアクセスできる保証はない<br>[.$nextTick](https://jp.vuejs.org/v2/api/index.html#mounted)を使うとDOMの更新を待ち受けた直後にアクセスできる|
| beforeUpdate   | コンポーネントのデータが変わって、DOMが再レンダリングされる前に実行する<br>再レンダリングされる前の新しい状態のデータが取得できる|
| updated        | コンポーネントのデータが変わり、再レンダリングされた直後に起きる<br>ここでの処理によっては無限ループに陥ることもある<br>mountedと同様、[.$nextTick](https://jp.vuejs.org/v2/api/index.html#mounted)を使うことでDOMの更新を待ち受けた直後にアクセスできる|
| beforeDestroy  | destoryされる直前に呼ばれる<br>まだコンポーネントの機能とデータを持っている<br>イベントリスナーを削除するときに使う|
| destroyed      | destroyされた後に呼ばれる<br>該当Vueインスタンスの全てのディレクティブのバインドが解除され、全ての下位Vueインスタンスも削除される|
[Vue.js 2.0 라이프사이클 이해하기
](https://medium.com/witinweb/vue-js-%EB%9D%BC%EC%9D%B4%ED%94%84%EC%82%AC%EC%9D%B4%ED%81%B4-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-7780cdd97dd4)
[Vue Parent and Child lifecycle hooks
](https://medium.com/@brockreece/vue-parent-and-child-lifecycle-hooks-5d6236bd561f)

***

# These relative modules were not foundのエラーが出たときに見直してみること
1. 原因としてファイル内のパスが間違っていることで起きるエラー
2. 相対パスで指定しておいたけど、途中でディレクトリ構成が変わってしまい、ファイルの依存関係がおかしくなった可能性がある

- 安全策として、絶対パスを使いましょう。

```zsh:絶対パスの例
import Home from '@/components/Home.vue'
@import "~less/variables";
```

[webpack モジュールのパスを絶対パスで指定する方法
](https://zukucode.com/2017/04/webpack-absolute-path.html)

[フロントエンジニアが3年間チャットワークにメモしてたことを振り返る](https://v-meta.com/blog/history.html#%E7%B5%8C%E6%AD%B4)
vimの諸設定

##１．設定場所
HOMEディレクトリに移動
探し方：
```$　echo $HOME```　

##２．設定ファイル
vimrc
```$ vim ~/.vimrc```

##３．いろんな設定
```
set number //行番号
set title　//編集中のファイル名を表示
set smartindent  //組み込みのC言語風のインデントを行う
syntax on  //コード色分け
colorscheme kalisi　//kalisiは色の一種
```

####　色設定
```
$ mkdir ~/.vim
$ cd ~/.vim
$ mkdir colors

$ git clone https://github.com/freeo/vim-kalisi //kalisiをgitからダウンロードする
$ mv vim-kalisi/colors/kalisi.vim ~/.vim/colors/
```
設定ファイルに移動する
```$ vim ~/.vimrc```
```colorscheme kalisi　```
を入力
Swift4.2 を AWS の Ubuntu18.04  AMI のインスタンスにインストールしたときのログ

# 概要

AWS で Ubuntu18.04 の AMI 
`Ubuntu Server 18.04 LTS (HVM), SSD Volume Type - ami-07ad4b1c3af1ea214`

からインスタンスを生成した後
https://swift.org/download/#releases
ここの内容をやればだいたいOK!

# 手順

### １　パッケージマネージャをアップデート

```
$ sudo apt-get update
```

### ２　Swift 本体をダウンロード

```
$ wget https://swift.org/builds/swift-4.2-release/ubuntu1804/swift-4.2-RELEASE/swift-4.2-RELEASE-ubuntu18.04.tar.gz
```

### ３　Signature をダウンロード

```
$ wget https://swift.org/builds/swift-4.2-release/ubuntu1804/swift-4.2-RELEASE/swift-4.2-RELEASE-ubuntu18.04.tar.gz.sig
```

### ４　必要なパッケージをインストール

```
$ sudo apt-get install clang libicu-dev
```

### ５　PGPキーをインポートしてベリファイ

```
$ wget -q -O - https://swift.org/keys/all-keys.asc |gpg --import -
$ gpg --keyserver hkp://pool.sks-keyservers.net --refresh-keys Swift
$ gpg --verify *.sig
```

### ６　Swift の tar をバラす

```
$ tar xf *.gz
```

### ７　Swift のパスを追加

```
$ vi .profile
PATH="$HOME/swift-4.2-RELEASE-ubuntu18.04/usr/bin:$PATH"
```

### ８　起動してみると怒られる^^;

```
$ swift
/home/ubuntu/swift-4.2-RELEASE-ubuntu18.04/usr/bin/lldb: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory

```

### ９　libpython2.7 をインストール

```
$ sudo apt-get install libpython2.7
```

### 10 起動できました！
```
$ swift
  1>
```

# 感想

手順４で

```
sudo apt-get install clang libicu-dev libpython2.7
```

とやっておけば、手順８、９はいらなそう。
rails5.2でvalidates_acceptance_ofが効かない

`allow_nil`オプションがデフォルトで`true`となっていたので`false`に指定する必要がありました。

```ruby
validates_acceptance_of :confirming, allow_nil: false, on: [:create]
```

rails5.1くらいから変わった？
[検証\(validation\) \- \- Railsドキュメント](http://railsdoc.com/validation#%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E3%81%AE%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%81%8C%E5%85%A5%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E3%81%8B(acceptance))

参考
[Railsで入力の確認画面を出すときの定石 \- Qiita](https://qiita.com/mm36/items/3753cb2fa65feedb145b)
自分用のコマンドメモ

# 自分用のコマンドメモ（設定確認篇）

###１．Ubuntu バージョン確認
$ cat /etc/issue
補足：ほかにもlsb-releaseコマンドで確認可、ただしlsb-releaseパッケージが必要

###２．python バージョン確認
$ python --version 
$ python -V
(python3の場合:python3--version)

###３．Pythonのパッケージ（ライブラリ）のバージョンを確認
$ pip list  （こっちの方が見た目分かりやすい）
$ pip freeze　（上記とほぼ同じ）
$ pip show XX  （XXの詳細を確認）
（ほかにcondaコマンドも確認できる）
TypescriptでObject.assignでobjectのcopyを作ってるなら今すぐ変えたほうが良い

## はじめに
自分用です

## 型
Objectのassignの型

```typescript

     /**
     * Copy the values of all of the enumerable own properties from one or more source objects to a
     * target object. Returns the target object.
     * @param target The target object to copy to.
     * @param sources One or more source objects from which to copy properties
     */
    assign(target: object, ...sources: any[]): any;
```
戻り値がanyだ。。。と。。。！？

つまり、以下のコードがコンパイルで通ってしまう。

```typescript

type A = { id: 'hello', name: 'abc' };
type B = { id: 'world', age: string };
let hoge: A = { id: 'hello', name: 'abc' };
let fuga: B = { id: 'world', age: 'abc' };

let piyo: A = Object.assign({}, fuga); // 通る
```

## 改善
スプレッド演算子ならちゃんと型安全にイケるみたい

```typescript
type A = { id: 'hello', name: 'abc' };
type B = { id: 'world', age: string };
let hoge: A = { id: 'hello', name: 'abc' };
let fuga: B = { id: 'world', age: 'abc' };

// let piyo: A = Object.assign(fuga);
let piyo: A = {...fuga}; // エラー出る
```

## 最後に
やったね！
Android Studio ショートカット(Visual Studioとの比較あり）

この記事では、Android Studio3.2で筆者が使用したショートカットをまとめていきます。
業務でAndroid開発要因に加わりそうなため、現在Android開発周りを勉強中です。
今まではVisual StdudioでWebアプリケーションの開発に携わっていたので、
VSのショートカット合わせて紹介していきたいと思っています。

最初に表示するのがAndroid Studioのショートカットで、
後ろに紹介しているのはVisual Studioでのショートカットです。

>Android Studioの操作

projectウィンドウの表示切り替え
`Alt+1`　　`Ctrl+Alt+L(表示）Esc(非表示)`

赤枠の部分ですね。
![android_projecttab.PNG](https://qiita-image-store.s3.amazonaws.com/0/77473/24a26463-829e-2d32-05e0-a758437f874d.png)
このprojectウィンドウは、VSだと「ソリューションエクスプローラー」に
該当すると思ってます（あってますかね・・・）。
※VSの場合、表示を固定にしているとショートカットが聞きません

>ビルド・デバック

ビルドして実行
`Shift+F10`　`F5`

ブレークポイント貼り付け/解除
`Ctrl+F8`　`F9`

>ソース操作

行コメント（//)
`Ctrl+/` `Ctrl+K,Ctrl+C(コメントアウト)、Ctrl+K,Ctrl+U(解除)`

ブロック化コメント（/**/)
`Ctrl+Shift+/`

大文字↔小文字の変換
`Command+Shift+U`　`Ctrl+Shift+U(大文字)Ctrl+U(小文字)`
Android Studioの方が同じコマンドで置換できるので便利ですね。

1行削除
`Ctrl+Y`　`Ctrl+L`

1行行複製
`Ctrl+D`　`Ctrl+C,Ctrl+V`
WordpressとBootstrapでNavigationBarを実装する。

Webはチョットしか触ったこと無いけど、HP制作の際に勉強がてら調べてみました。

時間のあるときに説明分等を書き足せればと思います。



```php:function.php
//======================================
//メニューの<li>からID除去
function removeMenuId( $id ){
    return $id = array();
}
add_filter('nav_menu_item_id', 'removeMenuId', 10);


//======================================
//メニューの<li>からクラス除去
function removeMenuClass( $classes ) {
    return $classes = array();
}
add_filter( 'nav_menu_css_class', 'removeMenuClass', 10, 2 );


//======================================
//メニューの<li>にクラスを付与する
function addMenuClass( $classes ) {

    $classes = array(
        'nav-item',
    );
    return $classes;
}
add_filter( 'nav_menu_css_class', 'addMenuClass', 10, 2 );


//======================================
//メニューの<a>にクラスを付与する
function my_nav_menu_attr_add( $atts, $item, $args ) {

    // aタグに付与したいクラスを入れる。
    $atts['class'] = 'nav-link';

    return $atts;
}
add_filter( 'nav_menu_link_attributes', 'my_nav_menu_attr_add', 10, 3 );
```


```php:header.php

<div class="headerNavigation">
      <nav class="navbar fixed-top navbar-expand-lg navbar-light">
        <a href="#" class="navbar-brand">
          <img src="イメージファイルのパス" alt="navigation_logo">
          tornado
        </a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse right-content" id="navbarSupportedContent">
          <?php
            wp_nav_menu(array('theme_location'=>'headerNavigation',
                              'container'     => 'div',
          		              'depth'         => 0,
                              'items_wrap'    =>'<ul class="navbar-nav mr-auto">%3$s</ul>'
                            ));
          ?>
        </div>
      </nav>
    </div>
```

これで管理画面からHeaderメニューの編集が簡単にできるかな？と思っています。



>参考サイト
HACK NOTE様 ：[WordPress : カスタムメニューの<li>タグのムダなid/classを除去する](https://hacknote.jp/archives/36137/)
WordPress Snippet様 ：[wp_nav_menu()のリンクに属性を追加する](https://tenman.info/labo/snip/archives/5307)


（この様に参考にしたサイトは記載したほうがいいんですよね？許可などはもらってないけどマズイんでしょうか。。。？）