OmniAICreator/Qiita-1.07M huggingface dataset:
【随時更新】RefineryCMSを利用したサイト作成で行ったこと

# config/initializers/refinery/pages.rb への修正
## Page Parts追加・削除を許可する
```
  config.new_page_parts = true
```
* ページ編集画面の右上にボタンが表示され、ページパーツのタブの追加・削除ができるようになる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281492/82f9ef32-0b77-2ad2-e91c-6f0adcbded81.png)

## URLをカスタマイズしたい
* デフォルトだとTitleがURLになってしまう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281492/cfa65c1d-1393-063a-3936-f03859182ef0.png)
* 下記設定にすることにより、URLをカスタマイズできる

```
config.use_custom_slugs = true
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281492/f4986e2d-43f3-9e36-201d-9a37b51165c1.png)


# デザインテンプレートの設定
## 下記赤枠のHomeページ部分を編集したい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281492/e6a2d5e0-496c-b5e1-2e13-f447d0ece4df.png)

* 下記コマンド実行すると、home.html.erbが生成されるので、  
生成されたファイルを編集する

```
$ rake refinery:override view=pages/home 
      create  app/views/refinery/pages/home.html.erb
```

## ヘッダ、フッタを編集したい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281492/45fc1223-9d94-81cb-38a5-e23f5b25c3cf.png)

* Homeページと同様

```
$ rake refinery:override view=refinery/_header.html
      create  app/views/refinery/_header.html.erb
$ rake refinery:override view=refinery/_footer.html
      create  app/views/refinery/_footer.html.erb
```

## その他 Homeページと同様に。。。
* レイアウト

```
$ rake refinery:override view=layouts/application.html
      create  app/views/layouts/application.html.erb
```
* 

``` ページレイアウト
$ rake refinery:override view=refinery/pages/show
      create  app/views/refinery/pages/show.html.erb
```

# サイト名を変更する
``` :/config/initializers/refinery/core.rb
  config.site_name = "Company Name"
```

# テンプレートを自前のhtml（haml）にしたい
* app/views/refinery/pages 以下に任意のhtmlファイルを配置する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281492/3303cc73-48b9-f0d4-a98b-df5884033860.png)
* refinery管理画面のPagesから任意のページを新規作成または編集状態にする
* Toggle advanced optionsメニューを開き、View templateドロップダウンリストを開くと、先に配置したhtmlファイルがリストされているので、  
任意のtemplateを選択して保存する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281492/10046957-18c7-2095-bb26-7721e2561dfa.png)
* Aboutを選択した場合、http://localhost:3000/home/about にアクセスすると、  
app/views/refinery/pages 以下に配置したabout.html.hamlの内容が表示される

# 既存Railsプロジェクトに拡張機能としてRefineryCMSのengineの追加（generate）・削除（destroy）

## 追加（generate）
* [公式サイト-Generate an Extension to Use Your MVCs](https://www.refinerycms.com/guides/generate-an-extension-to-use-your-mvcs)の通り、  
下記コマンドの実行でOK  
（blog機能を追加 項目はtitle、date、text）

```
rails generate refinery:engine blog title:string date:datetime text:text
```
上記コマンド実行後、下記を実行(ログに実行するように表示される)

```
bundle install
rails generate refinery:blogs
rake db:migrate
rake db:seed
```


## 削除(destroy)
* generate ・・・でRfineryCMS enginを生成するので、  
destroy ・・・で削除できる

```
# engin削除コマンド　→ blog engineが削除される
rails destroy refinery:engine blog
```

* seeds.rbに削除したengineのシードが残っていたので、  
手で削除した

``` :db/seeds.rb
　：
Refinery::Blogs::Engine.load_seed　→　この行を削除した
　：
```
きれいなコーディングってどんな書き方だろう

自身の備忘を兼ねて記載を行っています。
「とりあえず動いた」程度のソースなどもございますので参考程度にブラシアップ頂けると幸いです。
また、誤りやもっとよいコーディングやきれいな書き方があるなどご指摘頂けるととてもうれしいです。

## 今回のお題
キレイで、見やすいプログラムコードってどんな書き方だろうと日々悩んで右往左往する

## まず初めに
今回は、「**こうである**」というような結論は出ません。
私の、現状のベストを紹介してコメントを頂ければより良いものに進んでいける。
そんな記事になっています。

## では考察
今回、シンプルかつ複雑でながーくなったりもするＳＱＬを題材として考察を進めたいと思います。

### 改行のポイント
改行ってどこでするのが一番良いのでしょうか・・・
例えば、

```SQL
SELECT name, age, address, tel, job, luck FROM users WHERE age >= 30 AND luck > 100;
```

というSQLがあった場合、どのような改行をしますか？
これぐらいのSQLならシンプルなので改行しなくてもいい気がしますが、

私は、

```SQL
SELECT 
   name
  ,age
  ,address
  ,tel
  ,job
  ,luck 
FROM 
  users 
WHERE 
  age >= 30
AND 
  luck > 100
;
```

こんなSQLを書きます。
こだわりを説明すると、

* カラム/テーブルの開始位置を合わせて縦に見やすく
* カラムの区切りを先頭に持ってくることによって入れ替えやカラムの追加時にカンマの不足や過剰を起こしにくい
* 条件もWHERE句やAND/OR句と分離することによって入れ替えをしやすく

そんなつもりです。

### インデントのポイント
インデントはどうしたらいいでしょうか・・・

私は、上記のように基本的に半角スペース２個分を下げ、カンマが改行で並ぶ場合は先頭のみ半角スペース＋一つ分下げてます。
また、条件句が複雑となる場合はパッとみてグループであることがわかりやすいと思い下記のように記載しています。

```SQL
SELECT 
   name
  ,age
  ,address
  ,tel
  ,job
  ,luck 
FROM 
  users 
WHERE 
  age >= 30
OR (
      luck > 100
  AND job = '魔法使い'
)
;
```

### 別名のポイント
カラムやテーブルにつけることが出来る別名ですが、どのようにすると見やすいでしょうか・・・

またもや私の例ですが、

```SQL
SELECT 
   u.name    AS 名前
  ,u.age     AS 年齢
  ,u.address AS 住所
  ,u.tel     AS 電話番号
  ,u.job     AS 職業
  ,u.luck    AS 運
FROM 
  users    u
WHERE 
  u.age >= 30
AND 
  u.luck > 100
;
```

こちらも開始位置を合わせて縦に見やすくしているつもりです。
また、この書き方のメリットとしては、テキストエディタなどで矩形選択(ブロック選択)が使える場合は開始位置や次の句が始まる位置が揃っているほうが選択しやすいというのもあります。

### 複雑な場合のポイント
SQL的に合っているかは置いといて、このようなケースとなるとより良い書き方を求めたくなるのがわかるかと思う。
JOIN句や条件句の優先順位などシステム開発で書くSQLはもっと複雑で長く、個数も多い。
その中で、醜いコードを書き続けることがどれだけ不具合に繋がるかを考えるとプログラマについて回る恒常的課題なのではないだろうか。

```SQL
SELECT 
   u.name    AS 名前
  ,u.age     AS 年齢
  ,u.address AS 住所
  ,u.tel     AS 電話番号
  ,j.job     AS 職業
  ,s.power   AS 攻撃力
  ,s.defense AS 防御力
  ,s.speed   AS 俊敏
  ,s.luck    AS 運
FROM 
   users     u
  ,jobs      j
LEFT JOIN 
   status    s
     ON u.id = s.user_id
WHERE 
  u.job_id = j.id
AND
  u.age >= 30
AND (
  (
        s.luck > 100
    AND j.job = '魔法使い'
  ) OR (
        s.speed > 200
    AND j.job = '戦士'
  ) OR (
        s.power > 250
    AND j.job = '踊り子'
  )
)
```

下記は、以前見たことがあるSQLの再現なのだが、どうだろうか？
一見見やすいような気がするのだが、検索対象のカラムが増えた場合どうだろうか・・・

実際30近いカラムが列挙されているSQLの4カラム目にカラムの追加が必要となり、そんなSQLが何本もあったときは・・・
呪言を吐きながら修正を行ったのを未だに忘れない。

ただ条件句の優先順位箇所に関しては見やすいような気がする。私は比較的好きだ。

```SQL
SELECT 
   u.name AS 名前,u.age   AS 年齢  ,u.address AS 住所  ,u.tel   AS 電話番号
  ,j.job  AS 職業,s.power AS 攻撃力,s.defense AS 防御力,s.speed AS 俊敏
  ,s.luck AS 運
FROM 
   users u
  ,jobs j
LEFT JOIN status s 
  ON u.id = s.user_id
WHERE 
  u.job_id = j.id
AND 
  u.age >= 30
AND (
     (s.luck  > 100 AND j.job = '魔法使い')
  OR (s.speed > 200 AND j.job = '戦士')
  OR (s.power > 250 AND j.job = '踊り子')
)
```

## まとめ
SQLに限らず、プログラムをコーディングする際気を付けなければならないのは、コーディングミスだけではない。
見やすさを意識し改修時に他のエンジニアがみてもわかりやすく、修正しやすいものを作り上げる意識を持つ必要がある。

その際に改行をいれる場所、スペース/タブの数など動作には影響しない部分にまで少しづつでも意識を向けると、きっと不具合を生みにくいプログラムとなるのではないかと思います。

## お願い
みなさんはどんなコーディングをしているだろうか？
是非とも自分のこだわりや目からうろこ的なコーディング例があればコメントで教えて頂きたい。
今回はSQLを題材にしたがもちろん、別の言語でも大歓迎です。
yarn run serveが失敗した

[こちら](https://github.com/ClaytonMatulich/vue-tv)を試していたのですが、
いくらかいじった上で

```
$yarn run serve
```

としたら、

```
yarn run v1.17.3
$ vue-cli-service serve
 INFO  Starting development server...
 10% building 2/2 modules 0 activeevents.js:180                              
      throw er; // Unhandled 'error' event
      ^

Error: ENOSPC: System limit for number of file watchers reached, watch...
（略）
```

みたいな感じなエラーが出まして、
色々と調べた結果、

http://www.jitaku-svr.info/index.php?lsync_%E6%A7%8B%E7%AF%89

こちらが参考に。以下は、上記リンク先にあった記述です。

```
$cat /proc/sys/fs/inotify/max_user_watches
8192
```
この値が大きいのか小さいのか、正直そこまで把握していませんが、
とりあえず増やしとけということで、

```
$sudo vi /etc/sysctl.conf
最終行に以下を追加
fs.inotify.max_user_watches = 819200
```

kernelを再読み込み

```
$sudo /sbin/sysctl -p
$ cat /proc/sys/fs/inotify/max_user_watches
819200
```

再度

```
$yarn run serve
```

とすると、

```
You may use special comments to disable some warnings.
Use // eslint-disable-next-line to ignore the next line.
Use /* eslint-disable */ to ignore all warnings in a file.
 
  App running at:
  - Local:   http://localhost:8080/ 
  - Network: http://xxx.xxx.xxx.xxx:8080/
```
という感じで、無事立ち上がりました。
AndroidのDagger2で多階層のComponent構造を作った話

# はじめに
事の起こりはFragmentでViewPagerを使っていた時。

![Untitled Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76726/c8118e11-e910-5666-4e07-a0c4ec91eb2b.png)

上記のような、

 * 親Fragment(ViewPagerFragment)がViewPagerをレイアウトとして持ってて、
 * 親Fragmentが登録したい子Fragment（ChildFragment)のインスタンスを生成して登録する

ような構成は（多分）よくあると思う。

で、今回の要求は親Fragmentの生存期間と同等のインスタンスを子からも使いたい、というものだった。
具体的には以下の要素を満たすようにDIマップを作りたかった

- 親Fragmentが生成されたときにインスタンスも生成される
- 親Fragmentが破棄されたときにインスタンスも破棄される
- **子Fragmentが切り替わっても同一のインスタンスを見る**
- 子Fragmentのライフサイクルに等しいインスタンスもある(これは子Fragment毎に生成)

こんな構成にしたかった理由は下記のようにSharedPresenterをParentFragmentやChildFragmentから呼び出したい、というニーズがあったから。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76726/551a3f84-db92-029f-6064-ef9659cc96ee.png)

# 実装

こんな感じに実装したらいい感じになった

```kotlin

@AppScope
@Component(modules = [
   BindingModule::class:) 
interface AppComponent {
/*省略*/
}

@Module
abstract class BindingModule {
  @ActivityScope
  @ContributesAndroidInjector(modules = [ParentModule::class, SharedModule::class, ChildBindingModule::class])
    abstract fun bindingViewPagerFragment(): ViewPagerFragment
}

@Module
class ParentModule {
  @ParentScope
  @Provides
  internal fun provideParentPresenter(..): ParentPresenter =
            ParentPresenterImpl(..)
}

@Module
class ParentModule {
  @ParentScope
  @Provides
  internal fun provideSharedPresenter(..): SharedPresenter =
            SharedPresenterImpl(..)
}

@Module
abstract class ChildBindingModule {
    @ChildScope
    @ContributesAndroidInjector(modules = [(Child1Module::class)])
    abstract fun bindingChild1Fragment(): Child1Fragment

    @ChildScope
    @ContributesAndroidInjector(modules = [(Child2Module::class)])
    abstract fun bindingChild2Fragment(): Child2Fragment

    /*以下省略*/
}

@Module
class Child1Module {
  @ChildScope
  @Provides
  internal fun provideChild1Presenter(..): Child1Presenter =
            Child1PresenterImpl(..)
}
```

**実装ポイント**

ミソは以下の`ChildBindingModule`。

```kotlin
@Module
abstract class BindingModule {
  @ActivityScope
  @ContributesAndroidInjector(modules = [ParentModule::class, SharedModule::class, ChildBindingModule::class])
    abstract fun bindingParentFragment(): ParentFragment
}
```

親のFragmentとライフサイクルを同じにしたいものは親の`ContributesAndroidInjector`に追加する（`ParentModule`と`SharedModule`)。子のライフサイクルに登録したいものは、`ChildBindingModule`の中に登録する。そして`ChildBindingModule`の中のスコープを`ChildScope`にすることで実現できる。

こうすると以下のようなライフサイクルになる。子のライフサイクルは親のライフサイクルの配下にいる感じになるので、子からSharedModuleの要素にアクセスする場合は同じインスタンスを見るようになる。そして親が破棄されると子も一緒に破棄されるようになる。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76726/5cf50ad1-140b-3c7a-739c-47bf162217fc.png)
Ubuntu 19.03 に Pyenv で Python3をビルドするのに必要なパッケージ


どのネット上の記事でも、微妙にパッケージが足りないので、自分用にメモ

# Install dependencies

```
$ sudo apt install git gcc make openssl libssl-dev libbz2-dev libreadline-dev libsqlite3-dev zlib1g-dev libffi-dev
``` 

# Install pyenv
https://github.com/pyenv/pyenv#basic-github-checkout

# Install Python 3.7
```
$ pyenv install 3.7.4
```
CSS margin auto についての備忘録

#ボックスモデル#
要素の中身があり、
その周りの余白がpaddingで、
その周りの線がborder(図のオレンジの線)で、
その外側の余白がmarginですね。

![boxmodel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/2e072a20-0495-db31-2073-a82037ec093a.png)

#marginをまとめて指定する#
・【上下】と【左右】をまとめて指定する場合

```css
marign: 0 auto;
```

この場合、上下の余白が0px、左右が余白を均等に分けるのでセンター揃えになります。

・【上】【右】【下】【左】をまとめて指定する場合

```css
margin: 0 0 0 auto;
```

この場合上、右、下に余白がなく左のみに余白があるので、右揃えになります。

#参考#
・[Taneppa!](https://taneppa.net/margin_auto/)
[サルワカ](https://saruwakakun.com/html-css/basic/margin-padding)
S3の複数ファイルをbashでテキスト処理する

# 概要

S3のファイルを一括処理したい場合[S3バッチオペレーション](https://aws.amazon.com/jp/blogs/news/new-amazon-s3-batch-operations/)のlambdaを利用するのがクラウド的だと思うのですが、~~調べるのが面倒だったので~~ シェルでやります。

# 環境

awscliをpythonのvenvにinstallしています。
credentialの設定も完了しているものとします。

```console
$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.14.5
BuildVersion:   18F132
$ python --version
Python 3.7.3
$ aws --version
aws-cli/1.16.245 Python/3.7.3 Darwin/18.6.0 botocore/1.12.235
```

# やること

json形式のログを集めてS3に保存しているのですが、エントリーとエントリーの間に改行を入れておらず、扱いにくい状態でした。

```json:before
{"hoge": "fuga"}{"hoge": "piyo"}
```

やりたいのは次のようにエントリーの間に改行を入れる簡単なテキスト処理です。

```json:after
{"hoge": "fuga"}
{"hoge": "piyo"}
```

これがS3に`s3://bucket-name/2019/01/01/00/filename` のような形式で集積されています。

# 内容

簡単なテキスト処理なのでシェルでやってしまいたいです。

## ローカルファイル

ファイルがローカルだと次のようにすると思います。

```bash
FILE='./file-name'
cat ${FILE} | sed 's/}{/}\'$'\n{/g' > ${FILE}_out
```

## S3の単一ファイル

AWSCLIではS3のファイルを標準出力にコピーできる & 標準入力をS3のファイルに保存できるので、同じように処理できます。

```bash
FILE='s3://bucket-name/2019/01/01/00/file-name'
aws s3 cp ${FILE} - | sed 's/}{/}\'$'\n{/g' | aws s3 cp - ${FILE}
```

## S3の複数ファイル

指定のフォルダ以下を再帰で探索して先述の処理を実施します。
`&`と`wait`で並列実行しても良いかもしれません。

```bash
#!/bin/bash

function dfs () {
    echo ${1}
    if [ $(echo ${1} | rev | cut -c1) != '/' ]; then
        aws s3 cp ${1} - | sed 's/}{/}\'$'\n{/g' | aws s3 cp - ${1}
        return
    fi
    
    for deeper in $(aws s3 ls ${1} | rev | cut -f1 -d' ' | rev);
    do
        dfs ${1}$deeper
    done
}

dfs 's3://bucket-name/'
```

# まとめ

やっぱり非効率的なので[S3バッチオペレーション](https://aws.amazon.com/jp/blogs/news/new-amazon-s3-batch-operations/)をつかいましょう。
vue.js 日時差分

day.js を使って
日時の差分を取りたい。

timeago.js もあるんだけど、いまいち使いづらい。
ということで、day.jsを使う。

本来は10年3ヶ月前とかやりたいんだけど、
まぁ、 10年前 って感じでいいや。

しかも、10年「前」ってのはいらんから
10年 って表示させる。

参考

https://www.webopixel.net/javascript/1460.html


# プラグイン追加

```app.js

import 'dayjs/locale/ja';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';


dayjs.locale('ja');
Vue.prototype.$dayjs = dayjs;
Vue.prototype.$dayjs.extend(relativeTime);


//フィルターに追加

Vue.filter('dateSabun', function (value) {

    var res = '-';
    if(value != "0000-00-00 00:00:00"){
        res = dayjs().to(dayjs(value)).replace('前','');
    }

    return res;
});

```


```hoge.vue

{{teller.teller.uranairekiday | dateSabun}}

```


出力 -> 10年 

って感じぃ♪
FirebaseのFirestoreに都道府県の固定データをインサート

#FirebaseのFirestoreに都道府県の固定データをインサート

都道府県の固定データをインサートメモ

firebaseDBへの接続が完了している前提のコードです。。

```
var query = firebaseDB.collection('address');
query.add({ ,value: 0, ,label: '北海道', });
query.add({ ,value: 1, ,label: '青森県', });
query.add({ ,value: 2, ,label: '岩手県', });
query.add({ ,value: 3, ,label: '宮城県', });
query.add({ ,value: 4, ,label: '秋田県', });
query.add({ ,value: 5, ,label: '山形県', });
query.add({ ,value: 6, ,label: '福島県', });
query.add({ ,value: 7, ,label: '茨城県', });
query.add({ ,value: 8, ,label: '栃木県', });
query.add({ ,value: 9, ,label: '群馬県', });
query.add({ ,value: 10, ,label: '埼玉県', });
query.add({ ,value: 11, ,label: '千葉県', });
query.add({ ,value: 12, ,label: '東京都', });
query.add({ ,value: 13, ,label: '神奈川県', });
query.add({ ,value: 14, ,label: '新潟県', });
query.add({ ,value: 15, ,label: '富山県', });
query.add({ ,value: 16, ,label: '石川県', });
query.add({ ,value: 17, ,label: '福井県', });
query.add({ ,value: 18, ,label: '山梨県', });
query.add({ ,value: 19, ,label: '長野県', });
query.add({ ,value: 20, ,label: '岐阜県', });
query.add({ ,value: 21, ,label: '静岡県', });
query.add({ ,value: 22, ,label: '愛知県', });
query.add({ ,value: 23, ,label: '三重県', });
query.add({ ,value: 24, ,label: '滋賀県', });
query.add({ ,value: 25, ,label: '京都府', });
query.add({ ,value: 26, ,label: '大阪府', });
query.add({ ,value: 27, ,label: '兵庫県', });
query.add({ ,value: 28, ,label: '奈良県', });
query.add({ ,value: 29, ,label: '和歌山県', });
query.add({ ,value: 30, ,label: '鳥取県', });
query.add({ ,value: 31, ,label: '島根県', });
query.add({ ,value: 32, ,label: '岡山県', });
query.add({ ,value: 33, ,label: '広島県', });
query.add({ ,value: 34, ,label: '山口県', });
query.add({ ,value: 35, ,label: '徳島県', });
query.add({ ,value: 36, ,label: '香川県', });
query.add({ ,value: 37, ,label: '愛媛県', });
query.add({ ,value: 38, ,label: '高知県', });
query.add({ ,value: 39, ,label: '福岡県', });
query.add({ ,value: 40, ,label: '佐賀県', });
query.add({ ,value: 41, ,label: '長崎県', });
query.add({ ,value: 42, ,label: '熊本県', });
query.add({ ,value: 43, ,label: '大分県', });
query.add({ ,value: 44, ,label: '宮崎県', });
query.add({ ,value: 45, ,label: '鹿児島県', });
query.add({ ,value: 46, ,label: '沖縄県', });
```
Java設定wordページの背景色

Java設定wordページの背景色
Wordでは、異なるドキュメントレイアウトの設計要求に対して背景設定色を設定することができます。一般的には、単一の色、グラデーション、または指定された画像を読み込み、背景に設定できます。下の方の3種類のWordページの背景色をJavaで設定します。

<b>単一色の背景色を追加します</b>

```java

import com.spire.doc.*;
import com.spire.doc.documents.BackgroundType;
import java.awt.*;
import java.io.IOException;

public class BackgroundColor_Doc {
    public static void main (String[] args) throws IOException{
        //テストドキュメントの読み込み
        String input="test.docx";
        String output="backgroundcolor.docx";
        Document doc = new Document(input);

        //モノクロの背景を設定
        doc.getBackground().setType(BackgroundType.Color);
        doc.getBackground().setColor(Color.PINK);

        //文書を保存
        doc.saveToFile(output,FileFormat.Docx_2013);
    }
}
```

<b>グラデーションの背景色を追加</b>

```java

import com.spire.doc.*;
import com.spire.doc.documents.BackgroundType;
import com.spire.doc.documents.GradientShadingStyle;
import com.spire.doc.documents.GradientShadingVariant;
import java.awt.*;
import java.io.IOException;

public class GradientBackground_Doc {
    public static void main(String[] arg) throws IOException{
        //テストドキュメントの読み込み
        String input= "test.docx";
        String output="GradientBackgound.docx";
        Document doc = new Document(input);

        //グラデーションの設定
        doc.getBackground().setType(BackgroundType.Gradient);
        doc.getBackground().getGradient().setColor1(Color.white);
        doc.getBackground().getGradient().setColor2(Color.green);
        doc.getBackground().getGradient().setShadingVariant(GradientShadingVariant.Shading_Middle);
        doc.getBackground().getGradient().setShadingStyle(GradientShadingStyle.Horizontal);

        //文書を保存
        doc.saveToFile(output, FileFormat.Docx_2010);
    }
}
```

<b>画像を背景に読み込む</b>

```java

import com.spire.doc.*;
import com.spire.doc.documents.BackgroundType;
import java.io.IOException;

public class ImgBackground_Doc {
    public static void main(String[] arg) throws IOException {
        //テストドキュメントの読み込み
        String input= "test.docx";
        String output="ImgBackgound.docx";
        String img= "lye.png";
        Document doc = new Document(input);

        //画像の背景を設定
        doc.getBackground().setType(BackgroundType.Picture);
        doc.getBackground().setPicture(img);

        //文書を保存
        doc.saveToFile(output, FileFormat.Docx);
    }
}
```
CSSのobject-fitをIEでも使えるようにする

##Javascriptファイルの読み込み＆実行

```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/object-fit-images/3.2.3/ofi.js"></script>
<script>objectFitImages();</script>

```

##CSSの書き方

```css
img{
    object-fit: cover; /* 通常 */
    font-family: 'object-fit:cover'; /* IE */
    width: 100%;
    height: 100%;
}

```
grepの結果がウザい

※ オレオレgrepコマンドを作り直しました。 https://qiita.com/digitarhythm/items/20472caee63344ba4e44

# grepの結果がウザい
例えば、grepで、

```bash
$ grep localhost /etc/*
```
とやると、

```bash
grep: /etc/python2.7: ディレクトリです
grep: /etc/python3: ディレクトリです
grep: /etc/python3.5: ディレクトリです
grep: /etc/rc0.d: ディレクトリです
grep: /etc/rc1.d: ディレクトリです
grep: /etc/rc2.d: ディレクトリです
grep: /etc/rc3.d: ディレクトリです
grep: /etc/rc4.d: ディレクトリです
grep: /etc/rc5.d: ディレクトリです
grep: /etc/rc6.d: ディレクトリです
grep: /etc/rcS.d: ディレクトリです
grep: /etc/resolvconf: ディレクトリです
grep: /etc/rsyslog.d: ディレクトリです
grep: /etc/samba: ディレクトリです
grep: /etc/sane.d: ディレクトリです
grep: /etc/security: ディレクトリです
grep: /etc/selinux: ディレクトリです
grep: /etc/sensors.d: ディレクトリです
grep: /etc/sgml: ディレクトリです
grep: /etc/shadow: 許可がありません
grep: /etc/shadow-: 許可がありません
grep: /etc/skel: ディレクトリです
・
・
・
```
みたいに出てウザい。
なので、grepの「-s」オプションを使うとエラー表示が抑制される。

```
$ grep -s localhost /etc/*
/etc/hosts:127.0.0.1    localhost
/etc/hosts:::1          localhost ip6-localhost ip6-loopback
```
しかし、カレントディレクトリの全ファイルを対象とする場合とかだと、最後のパラメータを指定するのが面倒くさい。
なので「grp」という名前で、

```bash
#!/usr/bin/env bash
if [ -z "${1}" ]; then
  echo "parameter required."
  echo "usage:"
  echo "grp [-r] search_string [search_direcotry]"
  exit
fi

if [ ${1} = "-r" ]; then
  if [ -z ${3} ]; then
    eval '/usr/bin/env grep -sr ${2} *'
  else
    eval '/usr/bin/env grep -sr ${2} ${3}'
  fi
else
  if [ -z ${2} ]; then
    eval '/usr/bin/env grep -s ${1} *'
  else
    eval '/usr/bin/env grep -s ${1} ${2}/*'
  fi
fi
```
というスクリプトを書いた。

```bash
$ grp hoge
```
とやると、カレントディレクトリ内の全ファイルを対象に「hoge」を検索する。
ヒットした行だけ表示される。

```bash
$ grp -r hoge
```
とやるとディレクトリ階層を掘り下げてgrepする（rgrepと同じ動作）。

最後の引数としてディレクトリを指定すると、そのディレクトリ内の全ファイルを対象に実行される。
ファイルを指定すると実行されないので注意。
【Android】文字列をresourceIdに変換する方法

## 注意点
 - fragmentはgetActivity().getPackageName()を使わないとエラーになる。
 - Integer.parseInt()を使うと、 java.lang.NumberFormatExceptionエラーになる。
 
```MainActivity.java
//java.lang.NumberFormatExceptionエラーになります
String bookImage = "book_image";
int imageId = Integer.parseInt(bookImage);
```

## Activityで、文字列をresourceIdに変換する方法

```MainActivity.java
String bookImage = "book_image";
int imageId = getResources().getIdentifier(
                    bookImage, "drawable", getPackageName());

-----------------------------
//出力結果 
bookImage : book_image
imageId   : 2131099756 (なんらかの数値)
```


## Fragmentで、文字列をresourceIdに変換する方法
```MainFragment.java
String bookImage = "book_image";
int imageId = getResources().getIdentifier(
                    bookImage, "drawable", getActivity().getPackageName());

-----------------------------
//出力結果 
bookImage : book_image
imageId   : 2131099756(なんらかの数値)
```
【Rails】自作クラスを読み込む際、開発中はrequireではなくloadを使うと捗る

## 起こったこと
1. Railsで開発中、model単位ではなく機能単位で処理をまとめたいことがあったのでlib直下に自作クラスを作成
2. 処理を使いたいところで `require` して動作確認
3. 1回目は動作したが、修正して2回目は期待通りの動作をしなかった(変更が反映されていなかった)
4. サーバー再起動で読み込まれるが、**めんどくさい**　のでどうにかしたい

## 原因
`require`が一度しか読み込まないという仕様だった

## 対処法
開発中は`require`ではなく`load`を使う
pythonでコマンドライン引数を受け取る (sys.argv, argparse)

pythonコードでコマンドライン引数 (terminalで実行する際につけられる引数) を受け取る操作をまとめます。

argparse公式ドキュメント
https://docs.python.org/ja/3/library/argparse.html#

# 試行環境
Windows10
python3.6

# sys.argvを使うやり方

こっちは簡単です。sys.argvがファイル名と引数を文字列で格納したlistになっているのでこれを使うだけです。

```python:test.py
import sys

if __name__ == "__main__":
    print(sys.argv)
    print(len(sys.argv))
    print(type(sys.argv))
```

```terminal:コマンドプロンプト
(base) > python test.py a b 10 3.14
['test_receive_value1.py', 'a', 'b', '10', '3.14']
5
<class 'list'>
```
でもparseは自分でやらないといけませんのでちょっと面倒です。

# argparseを使うやり方

argparse.ArgumentParser()を定義しておくと自動でparseしてくれます。

```python:test2.py
import argparse

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='プログラムの説明')  # parserを定義

    # 受け取る引数を追加する
    parser.add_argument('arg1', help='引数arg1の説明')  # 必須の引数を追加
    parser.add_argument('arg2', help='引数arg2の説明')
    parser.add_argument('--arg3')  # オプション引数（指定しなくても良い引数）を追加
    parser.add_argument('-a', '--arg4')  # '-a'が省略形、'--arg4'が正式名のオプション引数

    args = parser.parse_args()  # 引数を解析

    print('arg1=', args.arg1)
    print('arg2=', args.arg2)
    print('arg3=', args.arg3)
    print('arg4=', args.arg4)
```
省略したものはNoneが入ります。

```terminal:コマンドプロンプト
> python test_receive_value2.py hoge fuga --arg3 uga
arg1= hoge
arg2= fuga
arg3= uga
arg4= None
```
-hオプションで使い方を確認することも出来ます。

```terminal:コマンドプロンプト
> python test2.py -h
usage: test_receive_value2.py [-h] [--arg3 ARG3] [-a ARG4] arg1 arg2

プログラムの説明

positional arguments:
  arg1                  引数arg1の説明
  arg2                  引数arg2の説明

optional arguments:
  -h, --help            show this help message and exit
  --arg3 ARG3
  -a ARG4, --arg4 ARG4
```
現代的な引数処理をやろうと思ったらargparse.ArgmentParser()を使うやり方が良さそうです。

# argparse応用編

以下はこちらの内容そのままです
https://qiita.com/kzkadc/items/e4fc7bc9c003de1eb6d0

### 省略した場合のdefault値を指定する

```python:python
parser.add_argument('--message', default='hello!')
```

### data型を指定する

```python:python
parser.add_argument('--number', type=int)    # 整数値(int)
parser.add_argument('--alpha', type=float, default=0.01)    # 実数値(float)
```

### 呼ばれただけでTrueや定数を格納する
引数を与えなくても--hogeが呼ばれるだけで何かするようにできます。以下だとTrueが入ります。

```python:python
parser.add_argument('--flag', action='store_true')
```
定数を入れたい場合は以下のようになります。

```python:python
parser.add_argument('--flag', action='store_const', const=3.14)
```

### 選択肢にある引数しか受け取らない

```python:python
parser.add_argument('--fruit', choices=['apple', 'banana', 'orange'])
```

### 複数個まとめて受け取る
nargs='*' で任意の数の引数を受け取るように出来ます。

```python:python
parser.add_argument('--colors', nargs='*')
```

```terminal:コマンドプロンプト
(base) > python test.py --colors red green blue
['red', 'green', 'blue']
```
nargs=3 などのように数を指定することもできます。

### 順不同で良いけど必須の引数を作る

```python:python
parser.add_agument("-a", required=True)
```
かなり色々できて面白いです。レッツトライ！

# 参考にしたページ
https://qiita.com/taashi/items/07bf75201a074e208ae5
https://qiita.com/kzkadc/items/e4fc7bc9c003de1eb6d0
【macOS】プロンプトにgitのブランチ名を出す方法

# 概要
- `git-prompt.sh`でターミナル上でgitのブランチ名がわかるようにする
- 環境変数PS1をカスタマイズしてプロンプトに時刻を出す
- `git-completion.bash`でgitコマンドがtab補完されるようにする

# 実現方法
## 1. Homebrewでgitをインストール
```
$ brew install git
$ git --version
git version 2.18.0
```
Homebrewでgitをインストールすると`git-prompt.sh`と`git-completion.bash`もインストールされる。

## 2. 実行権限を与える
```
$ chmod a+x /usr/local/etc/bash_completion.d/git-prompt.sh
$ chmod a+x /usr/local/etc/bash_completion.d/git-completion.bash
```

## 3. `.bashrc`にPS1の設定を追記する
```sh:.bashrc
# read script
source /usr/local/etc/bash_completion.d/git-prompt.sh
source /usr/local/etc/bash_completion.d/git-completion.bash
# option
GIT_PS1_SHOWDIRTYSTATE=true
# git ps1
export PS1='\[\033[37m\][\t \[\033[36m\]\u\[\033[37m\]@\h \[\033[32m\]\W\[\033[37m\]]\[\033[31m\]$(__git_ps1)\[\033[00m\]\$ '
```
### 設定可能なオプション
設定したいオプションをtrueにする

- `GIT_PS1_SHOWDIRTYSTATE`
  - addしてない変更がある(unstaged)ときに`*`を表示
  - add済みでcommitしてない変更がある(staged)ときに`+`を表示
- `GIT_PS1_SHOWUNTRACKEDFILES`
  - addしてない新規ファイルがある(untracked)ときに`%`を表示
- `GIT_PS1_SHOWSTASHSTATE`
  - stashがある(stashed)ときに`$`を表示
- `GIT_PS1_SHOWUPSTREAM`
  - 現在のブランチがupstreamより進んでいるときは`>`を表示
  - 現在のブランチがupstreamより遅れているときは`<`を表示
  - 現在のブランチがupstreamより遅れてるけど自分の変更もあるときは`<>`を表示

### PS1に使える設定
私が使ってる設定について紹介。
他にも色々と使えるのでこちらを参考にどうぞ：[Bashのプロンプト変更](https://qiita.com/amidaku/items/841d62335a03792424d5)

#### エスケープ文字
- `\h`：ホスト名
- `\t`：時刻(HH:MM:SS、24時間表記)
- `\u`：ユーザー名
- `\W`：現在のディレクトリ名

#### 文字の色
- `\[\033[37m\]`：White
- `\[\033[36m\]`：Light Cyan
- `\[\033[32m\]`：Light Green
- `\[\033[31m\]`：Light Red

## 4. 変更を反映する
もし`.bashrc`を読み込んでない場合は`.bash_profile`に下記を追記する。

```sh:.bash_profile
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi
```
設定を反映する。

```sh
$ source .bashrc
$ source .bash_profile
```


# はい完成
こんな感じで出力されるようになります。
>[14:50:54 <font color="DeepSkyBlue">user</font>@host <font color="LimeGreen">current_dir</font>] <font color="Red">(branch)</font>$

参考：[「Git補完をしらない」「git statusを1日100回は使う」そんなあなたに朗報【git-completionとgit-prompt】](https://qiita.com/varmil/items/9b0aeafa85975474e9b6)
AWSサービス、モバイル

# モバイル

モバイルについての備忘録
サービスの概要・特徴・料金などを簡潔（できれば）に記載します。

## AWS Amplify

## Amazon API Gateway

### 概要
API の公開、保守、モニタリング、セキュリティ保護、運用を簡単に行えるフルマネージドサービス

### 特徴

* リージョンサービス
* フルマネージド型のサービス
* 呼び出し回数の使用量に応じた課金
* クライアントからのアクセスを集中的に受けるポイント
* CloudFrontの連携が可能
* REST または WebSocket の2種類のAPIを扱うことが可能
* REST APIのエンドポイント
  * エッジ最適化、一旦エッジロケーションにルーティング
  * リージョン、リージョンに特設ルーティング
  * プライベート、VPC内から AWS PrivateLink(VPCエンドポイント）経由でのみアクセス可能
  * APIキャッシュ機能が利用できる
* カナリアリリースができる
* AWS WAF と連携ができる
* AWS X-Ray連携ができる
* クライアントSDK

### ユースケース

* インターネットからアクセス可能なパブリックなWeb APIの基盤
* イントラネットからアクセス可能なプライベートなWeb APIの基盤
* AWSサービスを独自のWeb API化する手段
* マネージドサービスの特性を活かしサーバレスアーキテクチャを実現する手段

## Amazon Pinpoint
## AWS AppSync
## AWS Device Farm
i3 Window Managerでzoomの画面共有がうまくいかない問題の解決

# i3 Window Managerとは？
> i3 (i3 Window Manager; i3と呼ばれる他の語と区別する為に“i3-wm”と表記されることもある) はX上で動作する動的タイル型ウィンドウマネージャの一つ。 wmiiの修正かつ後継を念頭に置き、“Do What I Mean. Good Docs. Clean Code. Sounds good?（直感的な操作。優良な手引き。簡潔な算譜。魅力的だろ？）”という理念を掲げている。 GNU/Linux及び*BSDに向けて無料・無償で配布されている。 

wikipediaより引用
https://ja.wikipedia.org/wiki/I3_(ウィンドウマネージャ)

先輩から
「使いやすいから試してみて！」
と言われて使い始めてから約半年が経ちました。

ショートカットキーちゃんと設定して覚えれば
たしかにすごく使いやすいです。

でも、おかげでWindowsを使いにくく感じるようになってしまいました (^ ^;)

# zoomの画面共有がうまくいかない
さて、本題に移ります。

今の時代、テレカンとか普通にやると思います。
そのとき、開発中の画面を見てもらって意見もらいたいとかあると思います。

しかし、13でzoomの画面共有をしようとすると
画面が真っ暗になって強制シャットダウンを余儀なくされます（2019/09/25 現在）。
強制シャットダウンはマストか分かりませんが
僕はそれ以外に回復する方法が見つかりませんでした。

これはいかん！
ということで、それを解決しましょうという話です。

とっても簡単です。
xcompmgrをインストールして、バックグランド起動させるとうまくいきます！

```code:bash
sudo apt install xcompmgr
xcompmgr &
```
いちいち起動するのは面倒なので
ログインしたら自動で起動するようにしましょう。
~/.config/i3/configに以下の内容を追記しておきましょう。

```code:~/.config/i3/config
exec xcompmgr
```

これで次回ログイン時からxcompmgrが自動的に起動してくれるので
ストレスなくzoomの画面共有ができることでしょう。

# 背景色がライトグレーになる問題
xcompmgrが自動的に起動してくれるのは良いのですが
なぜか背景色がライトグレーになる問題が発生しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207140/92374fe6-471b-1bd3-f0ec-65a35d9e76c9.png)

こちらも解決しましょう。

これもとっても簡単です。
hsetrootをインストールして背景色を設定するコマンドを実行するだけです。

```code:bash
sudo apt install hsetroot
hsetroot -solid "#2C001E"
```

今回はUbuntuのDark aubergineという色にしました
cf. https://design.ubuntu.com/brand/colour-palette/ 
こんな感じです↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207140/a92b76c3-0fff-90cc-8ce4-a4c0adcea3ba.png)

これもいちいち実行したくないので
先ほどと同様に~/.config/i3/configに追記しておきましょう。

```code:~/.config/i3/config
exec hsetroot -solid "#2C001E"
```

# まとめ
つまり、xcompmgrとhsetrootをインストールして

```code:bash
sudo apt install xcompmgr
sudo apt install hsetroot
```

~/.config/i3/configに以下を追加しとけば良いということですね。

```code:~/.config/i3/config
exec xcompmgr
exec hsetroot -solid "#2C001E"
```

どなたかのお役に立てれば幸いです。
WorkMailで快適メール生活

# WorkMail

みなさんWorkMail使っていますか。
ドメインに設定すると、お気軽にメールが使用できます。
1ユーザ$4/月です。
小規模な会社のメールの移行で使用しましたので、ご紹介します。


## 設定

### 組織の設定

AWSコンソールから、WorkMailを選択します。
こちらから、組織を追加します。
数分かかります。
組織というとわかりづらいかと思いますが、ドメインやユーザを管理する単位です。
こちらは会社名を英語で入れました。
会社が増えたら、こちらが増える感じですね。

![organization.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52386/45f41d22-c77f-cc12-51b8-21a128d28f8f.png)

### ドメインの設定

組織が出来たら、ドメインを追加します。
複数管理できます。
こちらでドメインに追加するレコードなどが表示されますので、DNSに設定すると認証されます。
TTLとかによって反映時間が変わってくると思います。

![domain.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52386/beb75a87-b3c7-e9e7-ebef-37d52708d938.png)

### ユーザの作成

Create userでユーザを追加します。
複数ドメインがある場合は間違わないようにしてください。
なぜなら、ユーザの削除は画面から行えません。
awsコマンドで行うことになります。
パスワードのリセットと、ユーザの有効と無効は行なえます。

![user.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52386/a8f97773-b966-0bb9-afba-cebf15878867.png)

## WEBメーラーで確認

WEBメールに以下のURLから、入れます。
作成したユーザとパスワードで入って下さい。

![login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52386/f8e25b00-0b88-a745-48a9-58b79da08e1c.png)

WEBメールはこんな感じです。
gmailみたいで使いやすいですね。

![スクリーンショット 2019-09-25 15.14.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52386/116f88e1-4064-89ce-d754-561c34a06f74.png)



## PCのメーラーで確認

基本的に以下のような感じです。
バージニアで立ち上げたのでSMTPとIMAPは以下のようになっています。
これを入れればスマホでも受信できます。

```
ユーザ名にメールアドレスを入れてください。（アカウント名ではなくメールアドレスです）
パスワードには、パスワードを入れてください。

受信サーバ
ポート番号993
imap.mail.us-east-1.awsapps.com
指定のポートを使用するのチェックをはずしてください
SSLを使用して接続するにチェック

送信サーバ
ポート番号587
smtp.mail.us-east-1.awsapps.com
指定のポートを使用するのチェックをはずしてください
SSLを使用して接続するにチェック
```
react-native-renameであとからアプリ名変更（フォルダ等も）

React Nativeはすぐにアプリが作りはじめられる代わりに、適当にinitしすぎて、あとから名前変えたい！みたいなことも多いです（僕だけ？
そこで超絶便利だったのがreact-native-rename。ios/androidのプロジェクト名や定義されているメタデータなども修正してくれます。

# インストール
react-native-renameをグローバルにインストールします。

```bash
yarn global add react-native-rename
# or
npm install react-native-rename -g
```

フォルダ名変更などで致命的なことが起きるかもしれないので、まずはブランチを変更

```bash
git checkout -b rename-app
```

あとは`react-native-rename 新しいアプリ名` で変更するだけ。

```bash
react-native-rename newAppName 
```

APP SUCCESSFULLY RENAMED TO "newAppName"! 🎉 🎉 🎉
みたいなメッセージが出たら完了。

元のコードによってはこれで完全に変更されるとは限らないので、念の為確認しましよう。

# どこを書き換えているのか
以下のようにリネーム・ファイル修正をしてくれます。

```scala

/ios/newAppName RENAMED
/ios/newAppName-tvOS RENAMED
/ios/newAppName-tvOSTests RENAMED
/ios/newAppName.xcodeproj RENAMED
/ios/newAppName.xcodeproj/xcshareddata/xcschemes/newAppName-tvOS.xcscheme RENAMED
/ios/newAppName.xcodeproj/xcshareddata/xcschemes/newAppName.xcscheme RENAMED
/ios/newAppNameTests RENAMED
/ios/newAppNameTests/newAppNameTests.m RENAMED
/ios/newAppName.xcworkspace RENAMED
/android/app/src/main/res/values/strings.xml MODIFIED
/index.js MODIFIED
/ios/newAppName/Base.lproj/LaunchScreen.xib MODIFIED
/ios/newAppName/Info.plist MODIFIED
/package.json MODIFIED
/app.json MODIFIED
/ios/newAppName.xcodeproj/project.pbxproj MODIFIED
/ios/newAppName.xcworkspace/contents.xcworkspacedata MODIFIED
/ios/newAppName.xcodeproj/xcshareddata/xcschemes/newAppName-tvOS.xcscheme MODIFIED
/ios/newAppName.xcodeproj/xcshareddata/xcschemes/newAppName.xcscheme MODIFIED
/ios/newAppName/AppDelegate.m MODIFIED
/android/settings.gradle MODIFIED
/ios/newAppNameTests/newAppNameTests.m MODIFIED
/ios/Podfile MODIFIED
/app.json MODIFIED
/android/app/src/main/java/com/newAppName BUNDLE INDENTIFIER CHANGED
/android/app/BUCK MODIFIED
/android/app/src/main/java/com/newAppName/MainActivity.java MODIFIED
/android/app/src/main/java/com/newAppName/MainApplication.java MODIFIED
/android/app/src/main/java/com/newAppName/MainActivity.java MODIFIED
/android/app/build.gradle MODIFIED
/android/app/src/main/java/com/newAppName/MainApplication.java MODIFIED
/android/app/src/main/AndroidManifest.xml MODIFIED
```

# まとめ
とても便利。
RSpec導入/テスト実施

## はじめに
未経験者の方や一人で勉強していたり、プログラミングスクールに通っていた人は
あまりテストコードを書く習慣がないと思いますが
現場では、テストコードを書く作業はとても大事です
今回はruby、RSpecで導入し、簡単なテストコードを書いてみます

## RSpecをインストール
### 1.Gemfileに追加

```ruby:Gemfile
group :development, :test do
  # 〜 省略 〜
  gem 'rspec-rails'
end
```
インストールします

```
$ bundle install
```

### 2.RSpecの初期設定

次のコマンドを実行し初期設定をします

```
$ bin/rails generate rspec:install
```
RSpecを使うための準備ができました。

## テスト実施
### テスト対象とするサンプルのモデルを作成

姓(last_name)と名(first_name)を属性に持つUserクラスを作成し、姓名を返却する「full_nameメソッド」を持つ仕様

次のgenareteコマンドを実行

```
$ rails g model user first_name:string last_name:string
```

DBのマイグレーションを実行

```
$ rails db:create
$ rails db:migrate
```

user.rbにfull_nameメソッドを作成

```ruby:/models/user.rb
 def full_name
     last_name + " " + first_name
 end
```


### テストコードを書く

```
expect(実行結果).to eq 期待する結果
```

文章にすると「実行結果は期待結果と等しいこと」となります

ここでは
full_nameメソッドが姓名を返すことを検証するテストコードを書きます

```ruby:spec/models/user_spec.rb
RSpec.describe User, type: :model do
  it "姓、名を登録すると、姓名が取得できること" do
    user = User.new(
            last_name:  "侍",
            first_name: "太郎"
    )
    expect(user.full_name).to eq "侍 太郎"
  end
end
```
### テストの実行

RSpecを実行する

```
bundle exec rspec
```

実行結果：
#### テストが成功した場合は,下記のようになります

```
Finished in 0.08988 seconds (files took 11.41 seconds to load)
1 example, 0 failures
```



※失敗した場合は、下記のようになります
 
```
Failures:

# 〜 省略 〜(エラーの内容が表示される)


Finished in 0.15678 seconds (files took 11.69 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/models/user_spec.rb:4 # User 姓、名を登録すると、姓名が取得できること
```

ここまでRSpec導入からテスト実施の流れを書いてみました
ありがとうございました


参考：https://www.sejuku.net/blog/47847
【HTML】ブロックレベル要素 インライン要素 インラインブロック要素 の違いは？

## ブロックレベル要素
単にブロック要素とも。
ブロック = 塊 として扱われる。 

### 特徴
* 改行を伴う
    * 縦に要素が並ぶ
* width , heigth でサイズが指定できる
* margin , padding で余白が指定できる

|代表的なタグ|
| :------------------ |
|`<p>`|
|`<h1>-<h6>`|
|`<div>`|

## インライン要素
ブロックレベル要素の内容として用いられる。

### 特徴
* 改行を伴わない
    * 横に要素が並ぶ
* width , heigth でサイズが指定できない
* margin , padding で**左右に対してのみ**余白が指定できる

|代表的なタグ|
| :------------------ |
|`<a>`|
|`<input>`|
|`<span>`|

## インラインブロック要素
2つの特性を併せ持つインラインブロック要素。
ブロック = 塊 として扱われるが、改行を伴わない。
主にブロック要素を横並びにしたいときに用いられる。

### 特徴
* 改行を伴わない
    * 横に要素が並ぶ
* width , heigth でサイズが指定できる
* margin , padding で余白が指定できる

### 使用方法

CSS の display プロパティで inline-block を指定することでインラインブロック要素になる。


```css
div {
  display: inline-block;
}
```
この場合、div タグがすべて横並びに表示されるようになる。


## まとめ

|要素|改行|サイズ指定|余白指定|
| :-- | :-- | :-- | :-- | :-- |
|ブロック|する|できる|できる|
|インライン|しない|できない|左右のみできる|
|インラインブロック|しない|できる|できる|
【RubyOnRails】テーブル操作(insert,select)

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

# 項目
## 環境情報
・Introduceモデルがある。中身は、

```
class Introduce < ApplicationRecord //saveメソッドが使えるクラスを継承している

end
```

・introducesテーブルがある。カラムは、
　- id
　- content
　- created_at
　- updated_at

## データベースへのinsert
※rails consoleという、Railsが使えるディレクトリにおいて起動することで、Rubyを実行できるツールを用いている
　実際の開発では別途、Controller内でModelにアクセスするような記述が必要なのではないか？要確認

`rails console`

`intro = Introduce.new(content:"My name is Tanaka") //contentが"My name is Tanaka"であるIntroduceインスタンスを作成`

`intro.save //introインスタンスをテーブルに保存`

結果）データベースのintroducesテーブルに、レコードが追加される

## データベースからのSELECT

```
intro = Introduce.first //Introducesテーブルの一番目のレコードを取得し、変数に代入
intro.content          //Introducesテーブルのcontentを表示
=>"My name is Tanaka"

intro = Introduce.all //Introducesテーブルのレコードを全件取得し、変数に代入
Introduce.all[0].content  //Introducesテーブルの0番目のレコードのcontentを取得


```

## データベースからSELECTしたデータを一覧表示

```
//Controller
def index
    @introduces = Introduce.all //Introduceテーブルのレコードを全件取得
end
```

```
//index.html.erb
<%  @introduces.each do |intro|%>
    <%= intro.content %> //レコードの中のcontentの値をeachで全件表示
```
iPhoneのSafariで表示しているページをMacのSafariでデバッグする

# iPhone実機で開いてるWebページのデバッグがしたい
開発中のWebサイトをiPhoneのSafariでアクセスしたところ、正常に動作していないことがわかりました。
WindowsやMacのブラウザでは正常に動作しているので、iPhone特有の症状のようです。

そこで、iPhone実機でデバッグする方法を調べたところ、MacのSafariを使った方法が一番簡単そうだったのでやってみました。

うまくできたので、忘れない内に記事に残します。

# iPhoneの作業

まず、 `設置` アプリを開きます。
`Safari` → `詳細` → `Webインスペクタ` をONにします。

次に、iPhoneのSafariでデバッグしたいページを開きます。

# iPhoneとMacを接続する
MacとiPhoneをUSBで接続します。

iPhone側に `このコンピュータを信頼しますか？` と表示されたら `信頼` をタップしてから、パスコードを入力します。

<img width="300px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/a8075235-7e02-f5b1-16ca-13d4df3c53ef.jpeg" alt="ios12-iphone-x-home-trust-computer-alert.jpg"/>
引用：https://support.apple.com/ja-jp/HT202778

# Macの作業

まず、 `Safari` を起動します。

メニューバーの `開発` にカーソルを合わせます。

もし、 `開発` が見当たらない場合は、メニューバーの `Safari` → `環境設定` → `詳細` → `メニューバーに"開発"メニューを表示` をONしてください。

メニューバーの `開発` にカーソルを合わせると、iPhoneのデバイス名がリストにあるので、そこにカーソルを合わせます。
すると、iPhoneのSafariで開いているページのURLがリストで表示されるので、デバッグしたいページを選びます。

そうすると、 `Webインスペクタ` というウィンドウが立ち上がります。

これで、デバッグ作業ができるようになりました。

# さいごに
簡単にできてよかったです。
SQL ServerのストアドファンクションでUnicodeエスケープする話

# はじめに
最近、SQL ServerでWebアプリを開発しているのですが、DB側の処理でユニコードエスケープする必要が出てきました。
しかし、SQL Serverにはユニコードエスケープする関数が用意されておらず自作することになりました。

# 前提
SQL ServerはUnicode文字列を保存できるデータ型や照合順序が決まっています。
もしUnicode文字列が「???」となってしまう場合は、データ型や照合順序を確認してみてください。

# 実装
Unicodeエスケープの仕組み（処理の内容）に関しては、参考となるページがたくさんあるので調べてみてください。
ここでは省略させてください。

今回使ったSQL Serverの関数は以下の通り

- COLLATE：https://docs.microsoft.com/ja-jp/sql/t-sql/statements/collations?view=sql-server-2017  
  データベースもしくはテーブルカラムの照合順序をキャストしてくれる関数です。
- SUBSTRING：https://docs.microsoft.com/ja-jp/sql/t-sql/functions/substring-transact-sql?view=sql-server-2017  
  文字列を切り出す関数です。ほかの言語でも同様の関数が良く出てきますね。
- CONCAT：https://docs.microsoft.com/ja-jp/sql/t-sql/functions/concat-transact-sql?view=sql-server-2017  
  文字列を結合する関数です。これもよく出てきますね。
- CAST：https://docs.microsoft.com/ja-jp/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-2017  
  データ型をキャストする関数です。
- LOWER：https://docs.microsoft.com/ja-jp/sql/t-sql/functions/lower-transact-sql?view=sql-server-2017  
  大文字を小文字に変換する関数です。

実際の処理は下記です。


~~~ SQL
DECLARE @target nvarchar(100) = N'対象文字１字'
DECLARE @binary int;
SET @binary = UNICODE(@target COLLATE Japanese_Bushu_Kakusu_100_CI_AS_SC);

SELECT
    CASE
        WHEN @binary >= 0x0020 AND @binary <= 0x0020 THEN @target
        WHEN @binary >= 0x0023 AND @binary <= 0x005B THEN @target
        WHEN @binary >= 0x005D AND @binary <= 0x007A THEN @target
        WHEN @binary > 0xFFFF THEN CONCAT('\u',LOWER(CONVERT(VARCHAR(8), CAST((@binary - 0x10000) / 0x0400 + 0xd800 AS VARBINARY(2)), 2)),
            CONCAT('\u',LOWER(CONVERT(VARCHAR(8), CAST((@binary - 0x10000) % 0x0400 + 0xdc00 AS VARBINARY(2)), 2))))
        ELSE CONCAT('\u', LOWER(CONVERT(VARCHAR(8), CAST(@binary AS VARBINARY(2)), 2)))
    END
~~~

ユニコードエスケープの処理自体が、言語によってまちまちなので、CASE文の分岐に関しては、もう少しパターンがあるかもしれません。
また、今回はアルファベットや半角数字などエスケープする必要がないものはエスケープ対象外としています。

# さいごに
今回、ユニコードエスケープをSQL Serverの処理だけで実現するために、結構苦労しました。
検索してみても、あまり同じようなことをしようとしている人がいないので、そもそもこういう設計になっているのがおかしいのかもしれません。
Xcodeを過信してたらRubyから苦情もらった（docker-sync動かないorz）

## はじめに
先日のXcodeのアップデートを受け入れた結果、docker-syncが動かなくなる事態にorz
↓こんな感じのエラー吐いた

```
$ docker-sync start
mkmf.rb can't find header files for ruby at /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/include/ruby.h
```

一旦解決したので、備忘録としてまとめます。

## Rubyの管理ちゃんとしよう
今までXcodeを入れておけばRubyが一緒についてくるから別に気にしなくていいや！と放置してましたが、今回のこの問題を解決するのにちゃんと見ててあげなきゃダメなんだなぁと思いました。
なんでかって？

```
ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.3.0 directory.
```

（察してください）

## rbenvのインストール
Google先生の力を借りてRubyのバージョン管理ツール検索したら一番上にrbenvが出てきたのでとりあえずインストール（こっちの管理ツールの方が良い！とかあれば教えてください）

```
$ brew update
$ brew install rbenv ruby-build
```

（brewコマンド使えない人はhomebrewで検索！）

## Rubyのインストール
インストールしたらRubyのバージョンリストをチェック（[Rubyの公式](https://www.ruby-lang.org/ja/downloads/)で安定版のバージョン見た方がいいかも）

```
$ rbenv install -l
```

インストールしたいバージョンを指定し、インストール開始。

```
$ rbenv install 2.6.4
```

インストールしたら使用バージョンに指定し、バージョンチェック

```
$ rbenv global 2.6.4
$ rbenv versions
  system
* 2.6.4 (set by /Users/admin/.rbenv/version)
```

最後にシェルにrbenvのパスを通して完了！シェルを再起動。

```
[[ -d ~/.rbenv  ]] && \
  export PATH=${HOME}/.rbenv/bin:${PATH} && \
  eval "$(rbenv init -)"
```

## あとはgem先生お願いします
まずはパスをチェックしてgemとrubyがどこ向いているのかを確認（rbenv向いてればOK）

```
$ which gem
/Users/admin/.rbenv/shims/gem
$ which ruby
/Users/admin/.rbenv/shims/ruby
```

最後にgem listを確認。おそらくdocker-composeもdocker-syncもいないと思うので、インストール。

```
$ gem list
$ gem install docker-compose
$ gem install docker-sync
```

これでdocker-syncも...動いた！！！！

## まとめ
Rubyでの開発をしてこなかったので、アプリケーションが使っているのは知っていても放置していました。
が、ちゃんと理解しておかないとなーと改めて思いました。
バージョン通知ライブラリSirenを使う

##はじめに
appstoreにあるアプリのバージョンと、ユーザのインストールしている既存アプリのバージョンを比較して、
appstoreのバージョンが新しい場合にアプリ上で通知をしてくれるライブラリSirenを使う。

##開発環境
Xcode11
Swift4.2
iOS13
Siren5.2.1

##注意点
iOS13で実行すると、通知が出てすぐに消えてしまうSirenのバグがある。
最新版5.2.1では修正されている。

##Sirenの使い方
```AppDeligate.swift
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: 
    [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
       // 任意アップデート
       let siren = Siren.shared
       siren.presentationManager = PresentationManager(forceLanguageLocalization: .japanese)
       siren.rulesManager = RulesManager(globalRules: .annoying)
       siren.wail()
       
       return true
  }
    
```

globalRules: .annoying
というのは、
頻度は即時バージョンチェックをして、アラートタイプはオプションにしてね
という条件付け。

アラートタイプ.オプションというのは、
通知ダイアログに、アップデートと次回を選べるボタンが付いている。

```Pods/Siren/Rules.swift
    public static var annoying: Rules {
        return Rules(promptFrequency: .immediately, forAlertType: .option)
    }
```
 Rules.swiftには他にも頻度とアラートタイプが記述してあるので、
プロジェクトにあった物を選ぶ。
VMware ESXi のセッションタイムアウトを無効化する

# 概要

VMware ESXi のクライアントアプリケーションはブラウザーベースになっていますが、ログイン後に少し経過すると勝手にログアウトが行われてしまいます。

ログアウトの時間が短すぎて不便なのでセッションタイムアウトを無効化する手順を紹介します。

# セッションタイムアウトのデフォルト値について

デフォルト値は900秒(15分)で設定されています。

# 無効化のための手順

## 1. 管理画面へのアクセス

VMware ESXi にアクセスしてrootユーザーで管理画面にログインします。

`https://(VMware ESXiのIPアドレス)/ui/#/login`

## 2. 詳細設定の変更

`ホスト` - `管理` - `システム` - `詳細設定` を表示してキーの一覧から `UserVars.HostClientSessionTimeout` を確認します。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278145/ea8f9f9f-c94f-3976-489b-2028891ef571.png)

デフォルト値は900(15分)となっています。

セッションタイムアウトを無効化する場合はキーの一覧から `UserVars.HostClientSessionTimeout` を選択した状態で `アクション` - `オプションの編集` メニューを表示して `0` に変更します。

変更内容は次回のログイン以降から反映されます。
行コンテキストとフィルターコンテキストについて 1（PowerBI/PowerPivot/DAX）

PowerBI/PowerPivot（以下、総称してDAXと呼びます）における重要な要素として、計算列とメジャーについての[記事を書きました。](https://qiita.com/zaboom/items/4076337b5a3846d1bfd4)この記事内では、計算列は行レベルで値を参照し、メジャーはテーブルの集計として主に機能する、と書いています。
厳密に言えば、これらは、「行コンテキスト」と「フィルターコンテキスト」という2つの異なるコンテキストで評価されている、ということになります。DAXを理解するうえで重要な2つのコンテキストについて、少し書いてみたいと思います。

## 評価コンテキストについて
DAX式は常にコンテキストに沿って評価されます。式が評価される環境、と考えることができます。
例えば、次のような式を考えてみます。

[売上額] = SUMX('売上明細',[販売数量] * [販売単価])

これは、売上テーブルの数量の全ての値に商品価格を掛けた合計です。この式をメジャーで使用すると、売上の総計になります。
このメジャーを適用したままテーブルにフィルターを掛けると、この売上合計（売上額フィールド）の値は総合計ではなく、フィルターに影響を受けた数値になります。このことは直感的に理解できると思います。
すなわち、上記の式は、「現在のフィルターによって表示される売上の合計」として解釈することができます。

![フィルターコンテキスト1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499774/bf69f7b9-f387-9979-4ff3-6fc3ff866b7a.png)



今度は、次のような式を考えてみます。計算列として下記のDAX式を定義します。

[粗利]= [定価] - [原価]

この式も直感的に理解できると思います。定価列の値から原価列の値を減算して粗利を計算するものです。
しかし、振り返って考えてみると、どの行の値を参照するべきかを指示していません。参照する行は暗黙的に決定されています。すなわち、計算列のなかでは、テーブルを行単位で反復評価し、現在の行を自動的に参照しているということが分かります。

![行コンテキスト1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499774/2d7651a0-6190-ca04-5325-738207fbdeaf.png)


ここまではとても当たり前の話であり、わざわざ分けて考えることでもないと感じるかもしれません。ですが、より深くDAX式を駆使するためには、フィルターコンテキストと行コンテキスト、これら2つのコンテキストのうちどちらで式が評価されるかという意識を持つことが非常に重要です。

## 計算列での集計
次のような式を計算列として定義します。

[売上合計（計算列）] = SUM('売上明細',[販売数量] * [販売単価])

計算列であるため、行別に評価されます。テーブルの各行において、販売数量と販売単価を掛けて売上合計を算出しようとしています。が、結果として、この式はうまく機能しません。各行に表示されるのは「売上額の総合計」になってしまいます。なぜでしょうか。
SUM関数はフィルターコンテキストで評価されます。行単位で評価されません。これを計算列で使用するとDAXは行コンテキストを無視して、フィルターコンテキストで評価します。そのため、表示される値は売上高の総合計になってしまいます。

![行コンテキスト2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499774/f271890b-6730-bf9e-30bd-a5a3cf1ad9bf.png)


これを意図通りに計算したければ、次の式を定義すれば解決します。

計算列を次のように作成します。
[売上] = [販売数量] * [販売単価]

そして、メジャーで次のような式を定義します。
[売上額] = SUM([売上])

こうすると各行で意図通りの売上額が表示されます。

![フィルターコンテキスト2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499774/05613018-ff73-26a0-1e8d-32ff17c174c2.png)


しかし、よく考えると、この式では各行の評価はなされていないはずです。それなのに、表示される結果はちゃんと商品カテゴリ別に細分化された合計額になっています。
この点についても、フィルターコンテキストで評価されているという点を振り返れば理解しやすくなります。つまり、「合計」の値からスタートして、それがフィルターによって細分化された合計値が各行に表示されていると理解することができます。

![フィルターコンテキスト3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499774/92ad03b6-6fea-ec45-4837-94aee29216ec.jpeg)


## メジャーでの列参照
今度は、次の式をメジャーとして定義します。

[粗利] = [定価] - [原価]

これは計算列では意図通りに計算できました。メジャーではどうでしょうか。結果は、メジャーではこの式はエラーになってしまいます。
メジャーの中では、基本的にはフィルターコンテキストで評価されます。そのため、暗黙的に「現在の行」を取得することができないのです。この式をメジャーで正しく動作させるには、次のように書き直す必要があります。

[粗利] = SUM([定価]) - SUM([原価])

この書き方でも、各行の値は正確に表示されます。SUMによって合計されていますが、結果的にはフィルターによって各行の値（各行単位のフィルターによって絞り込まれた項目の合計値）になっています。



フィルターコンテキストと行コンテキストについて、少し細かく見てみました。直感的に理解できていることをあえて難しく書いているように思われるかもしれません。
「繰り返し処理」や「コンテキストのネスト」を使った処理を行う際には、これらのコンテキストについての理解が必要になってきます。式のなかでどのようなコンテキストが使われているかをある程度意識しながら計算式を組み立てることができれば、さらにDAXを使いこなすことができます。
vue.jsで確認ダイアログを表示する

# vue.jsで確認ダイアログを表示する

axiosでtask削除をリクエストする際、確認ダイアログを表示したい。

axiosの手前にconfirmを書けばOK。

```js:component.js
deleteTask: function(task_id) {
  if(confirm('削除してよろしいですか?'))
  axios
    .delete('hoge/:id')
    省略
```
麻里子さまのおりこうさま！に投稿できなかった話

正確には、エラー原因を探って何とか投稿した話です。

# 経緯

[麻里子さまのおりこうさま！](https://ja.wikipedia.org/wiki/%E9%BA%BB%E9%87%8C%E5%AD%90%E3%81%95%E3%81%BE%E3%81%AE%E3%81%8A%E3%82%8A%E3%81%93%E3%81%86%E3%81%95%E3%81%BE!) とは、毎回 決められたテーマについて、
１５０字以内で解説するテレビ番組です。（現在 番組は終了。）

その時は「ＮＰＯ」の解説を募集していました。
視聴者からの投稿を受け付けるｗｅｂの「フォーム」があり、
私もそのフォームから投稿しようとしました。

麻里子さまに「おりこうさま」されたくて、解説文を何度も書き直し、
文字数制限ギリギリの１４５字くらいにまとめました。
ハンドルネーム等の必要事項を入力し、いざ投稿ボタンを押しました。

**エラー「１５０字以内にしてください」**

おっかしいなぁ。たしかに１５０字以内に まとめてるんだけど。

# 調査

半角文字が まぎれているのか？
いや それはない。すべて全角文字だ。

じゃ、UTF-8 の３バイトや４バイト文字が入っているのか？
ありえない。Shift_JIS で普通に文章を書いているのだから。

しばし考えた後、ある仮説が浮かび上がる。

「改行文字をカウントしてる・・・？」

いや、それは なかろう。ふつう１５０字といったら印字可能な文字数だ。
改行文字など数えない。第一、ＮＨＫの投稿フォームだぞ。
こんなエラー出てたらクレームですぐ修正するだろう。

私は半信半疑で、改行だけを消して投稿してみました。

```
ＮＰＯとはかくかくしかじか。
だからＮＰＯとはかくかくしかじか。
つまりＮＰＯとはかくかくしかじかなのです。
```

↓このように修正

```
ＮＰＯとはかくかくしかじか。だからＮＰＯとはかくかくしかじか。つまりＮＰＯとはかくかくしかじかなのです。
```

あらためて投稿！

・・・正常に投稿されました。

やはり改行文字をカウントしていたようです。
（なんてこった :dizzy_face:）

# 改行を省いた文字数チェック？

上記のフォームはもう存在しませんが、
仮にＰＨＰだったとすると、改行除去はこんな感じ。

`preg_replace('/[\r\n]/','',$data)`

ただ この方法の場合、ちょっと不安です。
文章に大量の改行が含まれていてもＯＫだからです。

```
：
(大量の改行)
(大量の改行)
(大量の改行)
あいうえお
(大量の改行)
(大量の改行)
(大量の改行)
：
```

文字数チェックの後、元々の文章をＤＢ等に保存するはずなので、
改行だらけの文章が通ってしまいます。

# 別の方法を探る

システム側の都合ですが、１５０字というのを、
改行を含めたチェックにしたらどうでしょう？

注意書きに
`１５０字（改行含む）`
として、運用で逃げたほうが楽です。
テキスト入力が身近になった現代ならＯＫかも・・・

いや、やはりダメです。
ＰＨＰで試すと、改行１つを**２文字**でカウントしてしまいます。
（ CR と LF で２文字。）

改行するたびに２文字も余計に加算されます。
さすがに これは文字数の無駄です。
せめて１文字でカウントされるなら運用で逃げるのに。

# まとめ？

結局、テキストの文字数チェックは、

・改行を省いて文字数チェックする。
・必要なら、改行を含む全体のバイト数もチェックする。

というのが一応の解決策ですかねぇ・・・。

# 参考

[ツイートの文字数を厳密に数える方法](https://qiita.com/PND/items/17e87b8839c9099d2e70)

[Railsの文字数のバリデーション問題を解決する 改行文字が2文字と換算されてしまう場合の対処方法](https://kyoto-diary.com/rails-length-validation/)