OmniAICreator/Qiita-1.07M huggingface dataset:
Javaで30行程度のスクレイピングをやってみる(CSV出力)

#スクレイピングとは
ウェブサイトから情報を抽出するコンピュータソフトウェア技術のこと。
スクレイピングするにあたって色々グレーゾーンがあるので気をつけたい。
参考：[スクレイピングと法律](https://it-bengosi.com/blog/scraping/
)

#目的
スクレイピングをつかって何ができるのかという話をしたい。
ここでは一部の具体例だが

- 機械学習用のデータ収集
- 企業のマーケティング用のデータ分析
- アプリで使用するデータ収集

などなど様々な使い方がある。

#ソースコード

```java:scraping.java
//インポート文は省略
public class scraping {
    public static void main(String[] args){
        //ファイルの用意
        PrintWriter p = null;
        try {
            p = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("出力先パス/sample.csv"),"Shift-JIS")));
            // ヘッダーを指定する
            //ここは自由に変更可能です
            // 列を増やしたい場合は,と列名をセットで追加してください
                p.print("列１");
                p.print(",");
                p.print("列２");
                p.println();
            //今回は列のキーとして使ってます
                int num = 1;
                Document document = Jsoup.connect("対象url").get();
                //クラス名やid名、タグ名など色々設定できます
                Elements elements = document.select("対象エレメント");
                //対象エレメントが複数ある場合取り出し
                for (Element element : elements) {
                    // 内容をセットする
                    p.print(num);
                    p.print(",");
                    p.print(element.text());
                    p.println();    // 改行
                    num++;
                }
               
            } catch (IOException e) {
                    System.out.println(e);
            }finally {
                p.close();
            }
        System.out.println("ファイル出力完了！");

    }
}
```

##メソッド

####document.select

>Elements elements = document.select("対象エレメント");

対象エレメントには

- body、pなどのタグ
- .classなどのクラス名
- #idなどのID名

を指定できる。
また、

- document.select("p .name");

のようにpタグのnameクラスのような指定方法もある。

####element.text
>for (Element element : elements) {
                    // 内容をセットする
                    p.print(num);
                    p.print(",");
                    p.print(element.text());
                    p.println();    // 改行
                    num++;
                }

- textメソッドを使うことで中身を取り出すことができる


#まとめ

結果的に30程度でjavaでスクレイピングを実現できた。
個人的にjavaが好きなのでやってみました。
マイクロサービスに関する個人的なメモ

自社でマイクロサービスの導入を検討してて、色々調べたり下記のイベントで話を聞いた内容を元に個人的にまとめてみました。

https://flexy.connpass.com/event/127599/

## マイクロサービスとは？

1つの事業を構成する各機能(例:ログイン、通知、認証、etc)を、機能単位で独立したサービスとして実装したもの。

## なんで流行ってんの？

エンジニア組織のスケールに伴い、多数のチームで一つのモノリスシステムを扱うにはリリース調整や品質保証などの本質的でない部分のコストが増加してしまう。

マイクロサービスの場合、モノリスとは異なり他チームとの調整にかかる手間が少なく、品質についてもモノリスより限定された範囲のみを保証すれば良いのでテストがしやすいため、リリース調整や品質保証などのコストを抑えつつ、本質的な機能の開発に注力できるようになる。

そのため、組織の拡大を見据えて、マイクロサービスを導入する企業が増えてきている。

## マイクロサービス導入企業

- Google
- Netflix
- Amazon.com
- LINE
- cookpad
- メルカリ
- etc

## マイクロサービスのメリット

- リリース単位が小さくなりリリースサイクルが早まる=改善が速くなる
    - テスト範囲が小さくなるのでテストの実行速度も上がる
- チームメンバーがプロダクトに対するオーナーシップ(当事者意識)を持ちやすくなる
    - フィードバックループが回しやすくなる
- 認証などの共通機能をマイクロサービス化することにより再利用性が向上する
    - 新規のプロダクトが増える場合などに恩恵あり
- コミュニケーションコストの改善(マイクロチームになった場合)
    - 関心と責務の範囲がサービス内で閉じられるので他サービスとの調整コストが不要
- サービスごとの最適技術適用
    - リソース、セキュリティレベル等に応じて得意な技術を選択することができる
- 一時的なアクセスの集中などにたいして必要な部分だけを最適な形でスケール可能
- モノリスに比べ、本質的な部分の開発にかけられる工数が増える
    - リリース調整や品質保証などのコストが抑えられるため
- 一つのチーム内でアプリケーションの実装だけでなくインフラも含めた管理ができる（共通基盤チームがない場合）
    - アプリケーション以外の改善手段も選択肢として選択しやすくなる
    - アプリケーション以外も触る機会ができ、エンジニアの育成のつながる

## マイクロサービスのデメリット

- 分散トランザクション管理
    - 課金サービス、ポイントサービス等で別れてた際のトランザクションの管理
        - どっちかのサービス失敗したらもう一方のサービス戻すとかの仕組みが必要
    - サービス内でトランザクションが完結される(できる)なら考慮せずに済む
- 運用管理の複雑化
    - CI/CDや自動化による効率化にかけるコストが必要
    - なるべく共通の運用管理手法をサービスで共有した方がいい
        - サービスごとの最適技術適用とは相反するが
        - コンテナクラスタだとやりやすい
    - サービス分割の単位誤ると運用管理コストだけ増えて死ぬ
- 障害解析のコスト
    - 障害箇所の特定のためにサービスをまたがることも
    - モニタリング、ロギング重点
- マイクロチーム化によりチーム間の関係が疎になる
    - 担当しているサービス以外の修正に関してはやりづらくなる
- マイクロサービス間通信コストによるパフォーマンス低下
- チーム数、サービス数が増えるため統制のコストが発生
- 機能によっては開発するやりがいが失われる
    - 限定的な部分にのみ関わることになり、ビジネスへ貢献できているかがわかりづらくなる可能性がある

## マイクロサービスの導入タイミング

- 事業がスケールする手前
- 事業の多角化
- 新規機能の作成

## 既存のモノリスのシステムからマイクロサービスを分割するコツ

- モデルの境界(≒マイクロサービスの境界)を見つけるまでモデリングを繰り返しやる
- 各サービスごとの目的(KPI)が明確になるようにする
    - ビジネスへの貢献できていることを理解できるようにして、開発者のモチベーションをあげるのにもつながる

## マイクロサービスの注意点

### データストアの切り分けは慎重に
    
- モノリスなシステムからデータストアなどを切り出してマイクロサービスを作る場合、一度データストアを切り出してしまうとロールバックが難しいため、事前のデータモデリングに時間をかけて慎重に設計した後で切り分けたほうが良い

### 分割する意味があるのか考える

- 例えば、これ以上の成長が難しい、これ以上の機能拡充が見込めないようなビジネスの奥行きがない事業の場合、マイクロサービスに分割したからと言ってそのメリットを享受しづらい

### 導入にはビジネスサイドの協力が必須
    
- モノリス→マイクロサービスへの移行にはエンジニアの工数等のコストがかかる
- そのコスト分がすぐにビジネスへ還元されるわけではないため、マイクロサービスへの移行時にはその目的と長期的に見た際のビジネスへの貢献などを説明した上で、ビジネスサイドからの同意を得る必要がある
    - ただ、新規機能で試す場合は同意いらないかも
- マイクロサービスの改善速度を最大化する際には組織（エンジニア以外も含む）もマイクロサービスに合わせる必要があるため、その場合にもビジネスサイドの協力は必須
proxy pattern

# proxy pattern
## ケース
### remote proxy
別空間にあるオブジェクトのローカル代理。

### virtual proxy

重いオブジェクトの生成(処理)を遅延させる。

### protection proxy

アクセス権の制御

### stamrt reference

オブジェクトアクセス時にフックを挟む。
参照のカウントなど

## 実装対象

インターフェイス SubjectInterface
SubjectInterface を満たすRealSubjectクラス
SubjectInterface を満たすProxyクラス

## example

```
protocol ImageProtocol {
    func processFilter() -> Image
}

class Image: ImageProtocol {
    func processFilter() -> Image {
        // filter self and return
    }
}

class ImageProxy: ImageProtocol {
    private var image: Image?

    func ProcessFilter() -> Image {
        if image == nil {
            self.image = Image()
        }

        return image.processFilter()
    }
}
```
Enzymeでwindow.alertのunit testを実装してみる

window.alertにjest.fn()を代入してtestを進めることで実現可能

```javascript
it('trigger window.alert on click button', () => {
  window.alert = jest.fn()
  const wrapper = shallow(<Button onClick={window.alert('hogehoge')} />)
  wrapper.simulate('click')
  expect(window.alert.mock.calls.length).toBe(1)
  expect(window.alert).toHaveBeenCalledWith('hogehoge')
})
```

## 参考

[Unit testing your React application with Jest and Enzyme](https://medium.com/wehkamp-techblog/unit-testing-your-react-application-with-jest-and-enzyme-81c5545cee45)
重い腰をあげて vue init pwa で作ったサービスをwebpack4にアップデートした件

# 戦略
- まず主要packageを一括で更新して、buildエラーを見ながら修正していく

# パッケージ更新
- package.jsonのwebpack系とbabel系を@latestで一気に更新
- 下記は見やすいよう複数に分けてますが、実際はワンライナーでやった

```
yarn add -D webpack@latest webpack-cli@latest webpack-merge@latest
yarn add -D webpack-dev-middleware@latest webpack-hot-middleware
yarn add -D html-webpack-plugin@latest mini-css-extract-plugin@latest
yarn add -D optimize-css-assets-webpack-plugin@latest
yarn add -D @babel/core@latest @babel/preset-env@latest
```

# TL;DR;
- 下記のような設定になった
- webpack.prod.conf.js
 - https://gist.github.com/yazashin/ff857943a48bba04bc0d13e09594af9a

- webpack.dev.conf.js
 - https://gist.github.com/yazashin/1bd3393702fd2bdad2a22f438f27721f

- utils.js
 - https://gist.github.com/yazashin/1196f4130ba64e9f96c1211dcfacd690
 - 私は下記の``MiniCssExtractPlugin``の設定が最初わからず30分近くハマってた..

```build/utils.js
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
  return ['vue-style-loader', MiniCssExtractPlugin.loader].concat(loaders);
} else {
  return ['vue-style-loader'].concat(loaders)
}
```


# 以降は興味がある人向け
## buildしてエラー見ながら潰した際のメモ
- ``yarn build``してエラーが沢山でてきたので、地道に対応する

### `webpack.optimize.UglifyJsPlugin has been removed, please use config.optimization.minimize instead.`
-   mode 'producetion'を設定する
-   webpack.prod.conf.jsから、UglifyJsPluginに係る項目を消す


##  `webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks`
-   既存のCommonsChunkに関する記述を消す
-   下記を変わりに記述する

```js
    optimization: {
      splitChunks: {
        cacheGroups: {
          vendor: {
            test: /node_modules/,
            name: 'vendor',
            chunks: 'initial',
            enforce: true
          }
        }
      }
    },
```

## `` Use Chunks.groupsIterable and filter by instanceof Entrypoint instead``

- extract-text-webpack-pluginパッケージを最新化するとこのエラーは消えるが、別なエラーがでる。
- ``mini-css-extract-plugin``を使うと解消される(後述)
- 使わないので削除しておく

```
yarn remove extract-text-webpack-plugin
```

## ``Error: Plugin/Preset files are not allowed to export objects, only functions. In /node_modules/babel-preset-stage-2/lib/index.js``

- ``babel-*``関連を、一律アップデートした
- 一例として

```
yarn add -D @babel/core@latest @babel/preset-env@latest
```

## ``Please remove the `import 'babel-polyfill'` call or use `useBuiltIns: 'entry'` instead.``
- 素直に設定変更する

```text:.babelrc
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "browsers": ["last 2 versions", "IE >= 11"]
        },
        "useBuiltIns": "entry",
        "corejs": 3
      }
    ]
  ]
}
```

## `` Path variable [contenthash] not implemented in this context: static/css/[name].[contenthash].css``
- don't use ETWP plugin for extract CSS for webpack@4. Use https://github.com/webpack-contrib/mini-css-extract-plugin for extract css.

```js

// extract css into its own file
new MiniCssExtractPlugin({
  filename: utils.assetsPath('css/[name].[contenthash].css')
}),
```

# 大変参考になったページ
- 作業終盤に見つけた。もっと早く見つければよかった..
- https://uuka.hatenablog.com/entry/2018/09/30/015713
decorator pattern

# decorator pattern

補助的な処理を追加する。

## 結果
### pros 
オブジェクト単位で拡張できる。
継承より手軽

### cons
元のオブジェクトとデコレートされたものは同一オブジェクトではなくなる

## 実装対象

修飾対象のインターフェイス ComponentInterface
修飾対象のクラス Component
実際の修飾するクラス ConcreteDecoratorA

## example

```
// Component
// 修飾範囲を小さく保つためにprotocol。
protocol PriceText {
    var priceText: String
}

class Product: PriceText {
    let priceText: String
    let name: String
}

// decorator
class JPUnitPriceTextDecorator: PriceText {
    var priceText: String {
        return "\(component.priceText) 円"
    }
    let component: PriceText

    init(component: PriceText) {
        self.component = component
    }
}

let product = Product()
let decoratedProduct = JPUnitPriceTextDecorator(component: product)
// この型はnameを公開してないことに注意。
decoratedProduct.priceText
```

## 注意
ComponentとDecoratorはインターフェイスが一致する。
そのためComponentクラスが大きい場合strategyパターンが良い。
decorator -> 殻の変更
Strategy -> 中身の変更

修飾範囲を小さく保つのがコツそう。
ruby なら全部親にデリゲートすれば良いので気にしなくて良い。
vue.js で canvas 画像を サーバーに 保存

canvasで生成した画像をサーバーに保存したい。
例えば vue-chart.js などで生成した画像ね。


canvas タグ 0 個目のものを保存。
ゴミテキストを削除して送る

```graph.vue

        methods: {


            // グラフを 画像にして保存
            saveCanvas(){
                var canvas = document.getElementsByTagName('canvas')[0].toDataURL();
                canvas = canvas.replace(/^data:image\/png;base64,/, '');

                let dataform = new FormData();
    
                dataform.append('canvas',canvas);
                dataform.append('fortuneresult_id',5);

                axios.post('/fortuneresult/upload/', dataform).then(e => {

                    console.log("成功");
                }).catch((error) => {
                    console.log("エラー");
                });

            },

```


サーバー側

```fortuneresultController.php

    public function upload(Request $request)
    {

        // /var/www/html/uranaibako.com/public/tmp/example.png
        $filename = public_path().'/tmp/example.png';
        $fp = fopen($filename, 'w');
        fwrite($fp,base64_decode($request->canvas));
        fclose($fp);

        Log::debug(public_path().'/tmp/example.png');
        
    }


```


これで保存される。
あとは、好きにしてっ♪
クロムブックで Web サーバーを動かす

クロムブックで Web サーバーを動かす方法です。

1) Nginx  をインストールします。

```bash
sudo apt install nginx-full
```

/var/www/html/index.html がディフォールトのページになります。

2) ip addr で Linux の IP アドレスを調べます。

私の場合は、100.115.92.194 になりました。

3) http://100.115.92.194/ にアクセス
![Screenshot 2019-05-14 at 11.13.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/60b4c8bf-68c2-95c0-5561-f1e6bc385633.png)

４）/var/www/html/index.html を編集して、変更が反映されることを確認します。
「We're sorry, but something went wrong」herokuにデプロイしたらエラー表示が出た

herokuにデプロイしたら、`We're sorry, but something went wrong`というエラー表示が出てしまった。

## 前提
- 最初にデプロイした時は正常だった
- 新しいModelやDatabaseを作成した

## 解決策

解決策を調べてみて、下記を参考にしました。
<https://qiita.com/ryosuketter/items/f7997be31f079c96f66e>

### 「PostgreSQL」アドオンの追加

```
$ heroku addons:create heroku-postgresql:hobby-dev
```
`heroku addons:create` はアドオンを追加するコマンド
`hobby-dev` はheroku-postgresqlの唯一の無料プラン

### マイグレーション

```
$ heroku run rails db:migrate
```

### 確認

これで動作確認をしたところ、無事にデプロイが完了しました。
C++ Builder 10.2 Tokyo > SubString() > 「公式」ドキュメントの記載不備 > SubString()インデックスは0始まりか、1始まりか? > 1始まり



### 公式ドキュメント

http://docwiki.embarcadero.com/Libraries/Rio/ja/System.UnicodeString.SubString

> 部分文字列には、index の文字インデックスから始まる count 文字分の文字が含まれます。 

### 疑問点

indexの文字インデックスは

- 0始まりのインデックス
- 1始まりのインデックス

いつも悩むところ。

公式ドキュメント。

### Pos

http://docwiki.embarcadero.com/Libraries/Rio/ja/System.UnicodeString.Pos

> 1 は最初の文字のインデックス、2 は 2 番目の文字のインデックス、のようになります。

PosとSubStringが関係するという類推では

- 1始まりのインデックス

がSubString()なのだろう。

(あとで調べてみる)。

### ドキュメントの不備

数年前から内容が変わらないドキュメント。

ドキュメントについての改善点がフィードバックされないと、情報不足はいつまでたっても情報不足のままだろう。

そういう情報は各人がブログやどこかのサイトにひっそり書いていて、その情報に助けられるユーザがいることだろう。


### コードでの確認


```cpp
String astr = L"12345";
String wrk = astr.SubString(1, 2); // 12
```

上記のwrkは"12"となった。

つまり

- 1始まりのインデックス

これは各ユーザが時間を取って調べる。
公式ドキュメントに記載があれば、N人のユーザの時間を無駄にしない。

一つの言語、一つのフレームワークしか使わない人であれば「覚えて」いられるかもしれないが、今はそういう時代ではない。
#Mac のライブ変換で入力をひらがなのままで確定させる ( Control + J )

# Ref

[Mac ことえりのキーボードショートカットまとめ（50種類） / Inforati](http://inforati.jp/apple/mac-tips-techniques/system-hints/how-to-use-mac-kotoeri-with-keyboard-shortcut.html)


```
「Control」＋「J」	ひらがなに変換
「Control」＋「K」	カタカナに変換
「Control」＋「L」	全角英字に変換
「Control」＋「;（セミコロン）」	半角カタカナに変換
「Control」＋「:（コロン）」	半角英字に変換
```

 # NOTE

- なぜかググってもなかなか出てこない系の情報

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1820








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【eclipse】垂直ルーラーの色変更

## はじめに
STSでデフォルトの外観だと目が痛いのでテーマをダークとかに設定するとルーラー(スクロールバーの隣)が見えづらくなるので色を変える。
特に出現箇所(メソッドとかが選択された際に参照されてる部分も色が変わるやつ)はお世話になってるけど、TODO＆ブレークポイントと色が同じで分かりにくい。

## 変更方法
設定→一般→エディタ→テキストエディタ→注釈
で、以下の項目があるので好きな色に変更する。出現箇所はオレンジとか。

- ブレークポイント
- タスク(TODO)
- 出現箇所
gem作ってみた


## 準備

```bash
# gem自信のupdate
gem update --system

# bundlerのupdate
gem update bundler

# generatorからプロジェクト作成
bundle gem new_gem -t
```

`-t`はテストも作成するoption
defaultでRSpec

他のgemと名前がかぶってはいけないので

```bash
gem search new_gem
```

で名前がかぶっていないことを確認しましょう。


雛形を作成することができたら`new_gem.gemspec`を編集します

```ruby
spec.summary       = %q{TODO: Write a short summary, because Rubygems requires one.}
spec.description   = %q{TODO: Write a longer description or delete this line.}
spec.homepage      = "TODO: Put your gem's website or public repo URL here."
```

TODOと書かれている箇所を編集していきます

summary -> サマリー
description -> 長めのサマリー
homepage -> `https://github.com/takakuda/new_gem`

といった感じです

`# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'`
と書かれている箇所は社内用のgemを外部に公開しないために公開して良いホストを指定する箇所です。
`RubyGems.org`に公開するのでごっそりこのあたりの記述は消します。

## 作成したgemをlocalで確認

new_gemを作った同じ階層にテスト用のフォルダを作成し

```bash
bundle init
```
で`Gemfile`を作成します

```
new_gem
├── Gemfile
├── README.md
├── Rakefile
├── bin
│   ├── console
│   └── setup
├── lib
│   ├── new_gem
│   │   └── version.rb
│   └── new_gem.rb
├── miura.gemspec
└── spec
    ├── new_gem_spec.rb
    └── spec_helper.rb
new_gem_test
├── Gemfile
├── Gemfile.lock
```

Gemfileでは

```
gem "new_gem", path: "../new_gem"
```
でlocalのgemをinstallします

その後に`bundle`を実行

あとはtest用のfileを作成してgemをrequireで呼べば確認できます

確認後公開用にリポジトリを作成し、https://rubygems.org/でアカウントを作成して有効な状態にすればリリースの準備は完了です

## リリース
リリースはgemspecのあるディレクトリで`rake release`を実行

自分のプロファイルページに追加されていれば完了です！
https://rubygems.org/profiles/takakuda
【個人開発】リンクをまとめて整理するWEBサービスを開発した【Ruby on Rails】

# はじめに
**リンクをまとめて整理するためのWEBサービス、「LinkClip」を開発しました。**
https://linkclip.biz
![main-pic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274383/def1d5aa-8c15-6acb-f492-90c08d9a37db.png)

このサイトを開発しようと思ったきっかけは単純で、Vimの設定ファイルを色々なサイトから引っ張ってきて自分のものとしてまとめたとき、どこからとってきたのかなーと後々困るということが多かったためです。お気に入りに入れればいいやん！となるかもしれませんが一部を引用しただけのサイトをいちいちお気に入り登録していたらお気に入りがすぐいっぱいになってしまいます。じゃあメモアプリでまとめればいいじゃん！という話になると思います。僕もそれでなんとかなるだろうと思っていたのですが、

* 単なるメモとリンクをただまとめただけのメモがごちゃ混ぜになってデータが増えすぎてしまう
* 今使っているメモアプリだと複数タグでの絞り込みができない（これについてはアプリによってはできるでしょうが...
* 複数のデバイスで共有するときに面倒臭い

こういった問題を解決するために自分でWEBサービスを作ればいいじゃないか！と思いたち、このサービスを開発しました。ソースはあまり綺麗ではないと思いますが、[github](https://github.com/kevin3314/LinkClip)で公開しているのでよければ星付けてください :)
サービス開発者としては初心者なので、色々といっていただけると嬉しいです。

## 具体的にどういうサービス？
Twitterアカウントでユーザー認証を行い、タグやURL、100文字程度のコメントを付けた記事を投稿するサービスになります。具体的には以下のような感じになります。
![スクリーンショット 2019-05-13 22.41.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274383/f1045ce2-673f-ef37-14f7-b6ae08bcae95.png)

この例でいえば、`C#`や`Rails`といったタグをURLに紐づけている、というイメージです。その中で`Rails` & `production`というタグが紐づけられているような投稿だけを絞り込む、というふうな機能を使うことができます。

![スクリーンショット 2019-05-13 22.44.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274383/43ce0e1a-507d-81bb-1208-b1ff1323ca10.png)

Twitterアカウントで認証しているのでどのデバイスからでも簡単に利用できますし、後から簡単に絞り込みができるので割と雑に色々な情報をまとめることができるかなーと思っています。

# 技術周り
## 使った技術
バックエンド: `Ruby on Rails`
フロントエンド: `React`

Ruby on Railsは前にも同じようにWEBサービスを開発したことがあったので割とスムーズに開発ができたかなと思います。Railsは最近色々言われているかもしれないですが、初心者が初心者として入門するならネットに転がっている情報量は多い方だと思うので良いフレームワークなのではないかと思います。Railsでしっかり学んでおけば他のフレームワークでもある程度ものは作れると思うので。
また、前にWEBサービスを作った時はJavascriptはほとんど使わなかったため割と寂しい見た目になっていたのですが、Reactを導入することで比較的容易に動的な見た目を作ることができたような気がします。一方で僕は**javascriptの構文をほぼ勉強したことがない**ので、Reduxとかを使って開発することを考えたらしっかりとjavascriptの基礎を抑えていきたいですね。とはいえそういった状態でも割とわかりやすくフロントエンドのパーツを書くことができたのですごい技術だなと思います。

### Railsで使ったライブラリ
Railsで使ったライブラリを紹介します。

#### RSpec
https://rspec.info/
テストを作成するライブラリです。元々のRailsのテストを作る機能でいいのでは？と思うかもしれませんが、RSpecの方がより構造的にわかりやすく、かつ構文自体もわかりやすくシンプルなので、見通しよくテストを書くことができます。


### Reactで使ったライブラリ
Reactで使ったライブラリを紹介します。

#### material-ui
https://material-ui.com 
簡単にシンプルでナウい感じのUIを構成することができます。また、アイコンがライブラリに含まれているので画像をどこからかダウンロードしてきて...という手間を踏まなくてもよいのも利点だと思います。

#### material-ui-chip-input
https://www.npmjs.com/package/material-ui-chip-input
マテリアルUIの見た目で複数のタグを入力するようなUIを提供してくれるライブラリです。タグ・URLを入力するフォームで使っています。

#### react-share
https://www.npmjs.com/package/react-share
SNSで情報をシェアするためのコンポーネントを提供してくれます。URLや内容を入力するだけなので楽チンです。

# 感想
技術的にそこまで難しいことはしていないと思いますが、Reactを書くのが思ったよりも難しくなかったように思います。関数型チックな思考で、状態を持つ部分と持たない部分とを明示的に分けるようになっているためうまく動かない時原因が特定しやすいです。
院試の勉強が始まってしまうしやることが多くなるのでなかなか手を入れられないかなーと思うのですが、ぜひ、使ってください！
アプリ開発する上でのレイアウトについて備忘録

なんとなくでレイアウト調整をおこなっていたので、
この機会に色々とレイアウトを触ってみて思ったことや気付きをまとめただけの備忘録です！

# ●レイアウトをstoryboardでやる場合
- 左から2番目のマーク<br>
描画対象の中心位置や、左右上下からどの程度離れた位置にするのかのレイアウトを設定できる。<br>
<img width="304" alt="スクリーンショット 2019-05-10 18.41.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215684/6ea11569-9b04-5b13-26aa-c6bb2fc73076.png">
- 左から3番目のマーク<br>
左右上下の位置や、幅、高さ等を設定できる。また、「Aspect Ratio」で高さと幅の比率を設定することも可能。
「Equal Width」は親viewと設定したいviewを選択すると、親viewと同じ幅に設定できたり、親viewに対して何割の幅にするのか等を設定できる。<br>
<img width="267" alt="スクリーンショット 2019-05-10 18.42.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215684/f9c551a6-884d-2046-9645-c4e1f0dfad54.png">

- 左から3番目のマーク(view指定)<br>
どのviewを基準として制約を入れることができる。「▼」マークを謳歌して基準にしたいviewを指定/確認する方が良い。(自身で思っている制約と異なる制約が入ってしまわないようにするため)<br>
<img width="446" alt="スクリーンショット 2019-05-10 18.42.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215684/1d9ec5aa-79a9-f577-f6a0-a41b9c790861.png">

- 左から4番目のマーク<br>
「Add Missing Constrains」で不足している制約を追加できる。<br>
その他で制約をリセットしたり削除したりすることができるので、制約を一括で調整したい場合は便利?<br>
<img width="240" alt="スクリーンショット 2019-05-10 18.42.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215684/8c9563b2-f24e-e413-d377-c20c2b667f03.png">

# ●レイアウトをコードでやる場合
「初めはレイアウトはstoryboardでしかできないんだなぁ」と勝手に思っていたのですが、
そんなことなく、案件に入って1番最初にコードでレイアウト調整したのが、
ボタンの角丸や枠線対応でした。

```swift:buttonTest.swift
button.layer.borderWidth = 0.2                      // 枠線の幅
button.layer.borderColor = UIColor.black.cgColor    // 枠線の色
button.layer.cornerRadius = 8.0                     // 角丸のサイズ
```

「コードでボタン角丸にしたりできるし結構簡単かも」と思っていたのですが、
ややこしいのが、コードで配置の調整ができることです。
これはかなり驚きました。。。
まずstoryboardの制約とかち合うといけないので、このプロパティをfalseにしておかないといけないようです。
なかなかコードで書いた制約が変わらず、苦労したらこのプロパティを変更するのを忘れていました。(デフォルト値はtrue)

```swift:buttonTest.swift
testView.translatesAutoresizingMaskIntoConstraints = false
```

storyboardで中心設定したり、幅や高さを調整していたりしましたが、
コードで書くと、それぞれ各行ずつ書かなければいけないと知りましたが、
オートレイアウトで行うと、コードで長文を書く必要もないので、やっぱり便利だなと思いました。

```swift:buttonTest.swift
// testViewの横方向の中心は、親ビューの横方向の中心と同じ
testView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
// testViewの縦方向の中心は、親ビューの縦方向の中心と同じ
testView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
// testViewの幅は、親ビューの幅と同じ
testView.widthAnchor.constraint(equalTo: self.view.widthAnchor).isActive = true
// testViewの高さは親ビュー高さの1/2
testView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.5).isActive = true
```

#●まとめ
- storyboardとコード両方でレイアウトの調整はできる。
- 標準ではbuttonの角丸はstoryboardでは設定できないのでコードで書く必要がある。
- コードで制約追加する場合はtranslatesAutoresizingMaskIntoConstraintsのプロパティを変更しなくてはならない。
- コードで制約をいじると管理できなくなりので、できるだけオートレイアウトを推奨。
- storyboardで背景色等の変更をしても、コードで設定した場合はコードが優先されるので、気をつける必要がある。
- やむおえず特定の条件下のみでレイアウトを変えたい、というような場合はコードで変更する方が楽かも。
日本のSalesforce資格保有者が自分の資格を確認できるのは2019年の後半になる？

日本のSalesforce認定資格保有者が自分の資格情報を[Trailhead](https://trailhead.salesforce.com/ja/content/learn/modules/trailhead_basics/get-started-with-trailhead)の「認定資格を確認」から確認できないかを[Trailhead Classes & Credentials](https://success.salesforce.com/_ui/core/chatter/groups/GroupProfilePage?g=0F9300000001oFf)コミュニティグループに聞いてみた。

# 背景

現状だと、日本の資格保有者はTrailheadの資格タブ→ 「認定資格を確認」から資格情報を確認できない状態です。

## 再現手順
### 手順1
資格タブ → 「認定資格を確認」を押下する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31622/dd403921-cc27-a890-02dc-fbb037fbd770.png)

### 手順2
* 確認するに必要な情報を入力してボタンを押下する。
* 押下後、ボットからのアクセスを防止するためのReCaptchaフォームが表示されるので「私はロボットではありません」のチェックボックスをオンにする。
* すると下部の方に英語で書かれた「あなたの資格情報がありません」的な内容が表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31622/9e4006fd-e1a3-56e3-679f-4ad301dd53cd.png)

# 原因
おそらく下記が原因ではないかと思っている。
>Webassessor は英語試験と日本語試験では異なるインスタンスで運用している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31622/202f0eb6-653a-85f4-8d50-affbeb8fdd1e.png)


# 問い合わせてみた
上記の背景から[問い合わせ←(問い合わせ内容のリンク)](https://success.salesforce.com/0D53A00003jZb8D)してみた。

全容は下の図を参照。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31622/fbc9b33b-bc94-7cc5-0f5e-117cadd48ee1.png)

# 結果
現時点では日本の資格保有者は「認定資格を確認」機能を使用できず、現在日本の資格保有者が「認定資格を確認」機能を使用できるように取り組んでいるとのこと。

2019年の後半に設定内容の手順が含まれるメールが来るので待ってください。
という回答をいただけました。
昨日のクソコードをリファクタリングしてみた

昨日(というか今日)書いた記事(https://qiita.com/k0gane_p/items/7dc1a013005c3884b9d1 )に「リファクタリングしよう」というコメントがあった。

実はリファクタリングという言葉をそもそも知らなかったので調べたところざっくりいうと「いろいろ工夫して綺麗にしよう！」という意味らしい。同じような構文を変数としてまとめたりだとか使う文法を変えてみたりだとか...


ちなみに昨日書いたのがこれ

```python:count.py
import sys

word = sys.stdin.read()
print("aは " + str(word.count('a')) + " 回")
print("bは " + str(word.count('b')) + " 回")
print("cは " + str(word.count('c')) + " 回")
print("dは " + str(word.count('d')) + " 回")
print("eは " + str(word.count('e')) + " 回")
print("fは " + str(word.count('f')) + " 回")
print("gは " + str(word.count('g')) + " 回")
print("hは " + str(word.count('h')) + " 回")
print("iは " + str(word.count('i')) + " 回")
print("jは " + str(word.count('j')) + " 回")
print("kは " + str(word.count('k')) + " 回")
print("lは " + str(word.count('l')) + " 回")
print("mは " + str(word.count('m')) + " 回")
print("nは " + str(word.count('n')) + " 回")
print("oは " + str(word.count('o')) + " 回")
print("pは " + str(word.count('p')) + " 回")
print("qは " + str(word.count('q')) + " 回")
print("rは " + str(word.count('e')) + " 回")
print("sは " + str(word.count('s')) + " 回")
print("tは " + str(word.count('t')) + " 回")
print("uは " + str(word.count('u')) + " 回")
print("vは " + str(word.count('v')) + " 回")
print("wは " + str(word.count('w')) + " 回")
print("xは " + str(word.count('x')) + " 回")
print("yは " + str(word.count('y')) + " 回")
print("zは " + str(word.count('z')) + " 回")
print("合計" + str(len(word)) + "文字")
```

コピペが大変だった。a~zまでの文字をカウントしたかったので作ったが、カウント対象の文字以外が全く同じなのでまとめられないか考えたところ次の記事が出てきた。

[[python] いろいろな文字種のリストを作成](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=2ahUKEwiktpnr5pniAhVTyosBHczqDtQQFjAAegQIABAB&url=https%3A%2F%2Fqiita.com%2Fokkn%2Fitems%2F3aef4458ed2269a59d63&usg=AOvVaw38GTCM2bE47AE4NRJ8LeC6)


これによると、アルファベットやひらがなも数字に変換してfor文でまとめられるらしい、知らなかった。これは便利なので使う以外ないと思ってリファクタリングしたものがこれ(+昨日のだと大文字が認識されないのでそれも修正した)

```python:count1.py
import sys

word = sys.stdin.read()
word.lower()
for i in range(97, 123):
    print( chr(i)+ "は " + str(word.count(chr(i))) + " 回")
print("合計" + str(len(word)) + "文字")
```

これを実行すると

```
Hello World
I study python
abcdefghijklmnopqrstuvwxyz
^Z
aは 1 回
bは 1 回
cは 1 回
dは 3 回
eは 2 回
fは 1 回
gは 1 回
hは 2 回
iは 1 回
jは 1 回
kは 1 回
lは 4 回
mは 1 回
nは 2 回
oは 4 回
pは 1 回
qは 1 回
rは 2 回
sは 2 回
tは 3 回
uは 2 回
vは 1 回
wは 1 回
xは 1 回
yは 3 回
zは 1 回
合計54文字
```

という感じでうまく出力できた。更に出力を見やすくするために辞書にまとめた。

```python:count2.py
import sys

word = sys.stdin.read()
word.lower()
letter = {}
for i in range(97, 123):
    letter[chr(i)] = word.count(chr(i))
letter = sorted(letter.items())
print(letter)
print(len(word))
```

これにより

```
Hello World
I study Python
abcdefghijklnmopqrstuvwxyz
^Z
[('a', 1), ('b', 1), ('c', 1), ('d', 3), ('e', 2), ('f', 1), ('g', 1), ('h', 2), ('i', 1), ('j', 1), ('k', 1), ('l', 4), ('m', 1), ('n', 2), ('o', 4), ('p', 1), ('q', 1), ('r', 2), ('s', 2), ('t', 3), ('u', 2), ('v', 1), ('w', 1), ('x', 1), ('y', 3), ('z', 1)]
54
```

こうなった、大分見やすくなったのではないかなと思う。


##　わかったこと

- コーディング後のリファクタリングの大切さ(競プロでも応用できそう)
- アルファベットやひらがなでも数字に変換することでfor文が使える
- 辞書をソートするとリストになる
もそ、プログラミングを学ぶ【PHP&Laravel】〜withメソッドを理解しよう〜


Laravel習得に向け、ソースコードとにらめっこを続ける もそ。
ポチ氏に教えを請いつつ、少しずつ仕組みや動きを

今回はwithメソッドについて。

##withメソッドとは
withメソッドは、**コントローラからビューに値を渡すことができるメソッド。**
いわゆる第一引数'・・・'内はビューで使う変数名、第二引数$・・・ にはビューに渡す値を記述します。
`with('変数名', $値)`


コードで書いてみるとこんな感じです。↓

```Controller.php

public function index()
    {
        $articles = Tweet::with('user')->orderBy('created_at', 'DESC')->paginate(5);
        return view('article.index')->with('articles', $articles);
    }
```

この辺の流れはRailsと同じですね。
むしろRailsよりもキーとバリューの記載がわかりやすいので、個人的にはLaravelの記述の方が好きかも。

Railsは"return"を記述しなくても基本的にRails側で処理して値を返してくれたりmigrateしたらDBを自動で繋いでくれたりするんですが、なんというか、**便利すぎてどういう処理になっているか分からない**んですよね。
その点LaravelはRailsと比べて記述量は増えますが、**処理の流れがわかりやすい**です。

なので毎回なにかしら新しい発見があってとても楽しい！
これは多言語を学んだ人の特権ですね。

「なんか思ったより全然理解できるし楽しいし、プログラミングの才能開花しちゃったかな〜」
なんて調子に乗りかけましたが、ビューファイルを見て疑問が生まれます。


```view.php
@extends('layout')

@section('content')
<div class="contents article">
  @foreach($articles as $article)
    <div class="content_post" style="background-image: url({{$article->image}});">
      <div class="more">
        <span><img src="/images/arrow_top.png"></span>
        <ul class="more_list">
          <li><a href="/articles/{{$article->id}}">詳細</a></li>
        </ul>
      </div>
      <p>{{ $article->text }}</p>
    </div>
  @endforeach
  {{ $articles->render() }}
</div>
@endsection
```


「...あれ？**これコントローラで記述した変数名、使ってなくね？**」
「え、じゃあ**何でコントローラでわざわざ変数名つけてるんだろ？**」

もそが何故そう考えたかというと、４行目にある
`@foreach($articles as $article)`
↑ここで**$が２回使われていたから**。


$articlesが添字配列ということはわかるのですが、これを値だと思いこんでしまいどツボにハマってしまいました...。

<img width="375" alt="無題1245.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372174/7716203c-a3ee-6816-ead9-f9628d67dc84.jpeg">


##変数名はどこ？


そこで変数名がどこで使われているかを明確にするため、先ほどの例を書き直してみました。

```Controller.php

public function index()
    {
        $articles = Tweet::with('user')->orderBy('created_at', 'DESC')->paginate(5);
        return view('article.index')->with('moso', $articles);
    }
```


```view.php
@extends('layout')

@section('content')
<div class="contents article">
  @foreach($moso as $article)
    <div class="content_post" style="background-image: url({{$article->image}});">
      <div class="more">
        <span><img src="/images/arrow_top.png"></span>
        <ul class="more_list">
          <li><a href="/articles/{{$article->id}}">詳細</a></li>
        </ul>
      </div>
      <p>{{ $article->text }}</p>
    </div>
  @endforeach
  {{ $moso->render() }}
</div>
@endsection
```

`@foreach`以下の記述は`$moso`という名前でコントローラから呼び出した添字配列で、そのなかの一つの要素`$article`を取りだしているという意味になります。

なので`@foreach〜@endforeach`内の`$article`は配列のひとつの要素、つまりレコードの一行を表しています。
`{{ $moso->render() }}`はページネーションを実装しています。


なるほど〜！

--

ファイルのディレクトリがRailsとごっちゃになったりとペーペーではありますが、いろんな処理の流れが見えてくると、実装してうまく動いたときの感動が全然ちがいます。
ものづくり好きがいい方向に動いてよかった、、
まだまだポチには追いつけませんが、がっつり話ができるようになれればいいなぁ。
...もその学習は続く。
Tex での参照を楽にする

## cleveref 

Tex で章や図を参照するときに```ref```を使えば番号は参照できるが、```章\ref{label}```や```図\ref{label}```のような書き方をしなければならない。
cleverefを使うことで、```\cref{label}```や```\cref{label}```と書けば、自動で「章」や「図」という文字を補ってくれる。

## cleveref_ja.sty をダウンロード

1. [ここ](https://gist.github.com/shuntaroy/3a9de31ce57b19338e18)よりcleveref_ja.styをダウンロードし解凍.

1. styファイルの保存場所の確認
今回はcleveref.styと同じ場所に保存するため以下のコマンドでファイルの場所を検索する.
    
    ```
    kpsewhich cleveref.sty
    ```

1. 解凍したstyファイルを先程確認したディレクトリに移動.
移動先は先程確認したディレクトリ.

    ```
    sudo mv cleveref_ja.sty /usr/local/texlive/2018/texmf-dist/tex/latex/cleveref/
    ```


1. 変更を反映させる.

    ```
    sudo mktexlsr
    ```

これでtexファイルの最初に`\usepackage{cleveref_ja}`としておけば、`\cref{label}`で参照できる。
UIViewとCALayerの関係

記事の内容はこちらを参照してください。
https://mishimay.github.io/661a6c364a67a3c12b45/
<!--


## 要点

  - すべてのUIViewはCALayerを持っている
    - UIViewは主にタッチイベントなどのインタラクションを担当
    - CALayer (=CoreAnimation) は主にアニメーションを担当
      - CoreAnimation自体は描画システムではない
      - layerはviewのcontentをbitmapへキャプチャして、graphics hardware による操作を行う
        - layerにcontentを提供する方法には以下がある (ただしviewを使っているときにはほとんど意識することはない)
          1. layer.contentsプロパティに画像オブジェクトをセット
          2. layerに描画用のdelegateオブジェクトをセット
          3. layerのサブクラスを定義して描画のためのメソッドをオーバーライドする
  - UIViewは一つのルートCALayer (=`view.layer`) を持ち、ルートCALayerは複数のサブCALayerを持つことができる
  - UIViewはルートCALayerをラップしている
    - そのためUIViewへの描画の操作でCALayerが操作される  

        ```swift
        let view = UIView()  
        view.backgroundColor = UIColor.blue  
        print(view.layer.backgroundColor) // -> blue color
        ```

## 参考

  - https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreAnimation_guide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40004514
  - https://stackoverflow.com/questions/7826306/what-are-the-differences-between-a-uiview-and-a-calayer


-->
bitnamiのGitLabを使ってGit勉強

# bitnamiのGitLabを使ってGit勉強

:::note info
今となってはDockerでGitLabを構築した方が楽です。
[Qiita: Dockerを使ったGitlabの構築](https://qiita.com/loverboy/items/638923ce4f8260bc95c4)
bitnamiをあえて使いたい場合はこの記事をお読みください。
:::


Gitに限らず、使い方を覚えるにはひたすら手を動かすのがよいと思います。その時、自分専用の、壊れてしまってもよいGitサーバがあると、気持ちが楽です。

[bitnami](https://bitnami.com/)は様々なWebアプリケーションを手軽に試すことができます。GitLabも提供されていますので、今回はGitLabを使用します。執筆時点では以下の作業が必要になります。GitクライアントとVirtualBoxは準備済み、とします。

1. [bitnami](https://bitnami.com/)からGitLabのOVAファイルをダウンロード
2. OVAファイルをVirtualBoxにインポート後、GitLabをホストするサーバのSSHを有効化
3. SSH用の公開鍵を用意してGitLab上の設定画面に登録

## Gitサーバ構築

### GitLabのOVAファイルをダウンロード

bitnamiのアプリケーションカタログから「GitLab」を検索して、OVAファイルをダウンロードします。VirtualBoxにOVAをインポートします。起動後、セットアップに時間がかかるようですので、気長に待ちます。準備が出来たら、以下のようにIPやパスワードなどがログイン画面に表示されます。Webブラウザでアクセス出来るか確認します。

![セットアップ完了後のコンソール](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326185/2e8c0e42-db26-7f45-cd12-68fe7afedb4b.png "セットアップ完了後")


### GitLabをホストするサーバのSSHを有効化

Chromeなどでアクセスするとわかりますが、bitnamiで用意されたサーバは自己証明書を用いています。自己証明書だとHTTPSでクローンできません。SSHでクローンすると、サーバ側でSSHが無効になっているため、やはりクローンできません。

SSHを有効にする方が楽ですのでSSHを有効にします[^git_protocol]。

[^git_protocol]: Gitの通信プロトコルは4種類あるようです。詳細は[こちら](https://git-scm.com/book/ja/v1/Git-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB "Git サーバー - プロトコル")から。


VM上でログイン後、コンソールで以下のコマンドを実行します。初期ユーザ名とパスワードは「bitnami」です（初回ログイン時に変更要求されます）。下記の設定方法はbitnamiの[公式ページ](https://docs.bitnami.com/virtual-machine/faq/get-started/enable-ssh/)に記載されています。

```shell-session
sudo rm -f /etc/ssh/sshd_not_to_be_run
sudo systemctl enable ssh
sudo systemctl start ssh
```

### SSH用の公開鍵を用意してGitLab上の設定画面に登録

GitLabでSSH接続するまでの手順を@kyamawakiさんが[Qiitaの記事](https://qiita.com/kyamawaki/items/07fb3332cf3c2f47728a "GitLabにSSHで接続するまでの手順")で投稿してくださっていますので、そちらを参考にしてください。

## お勉強

以下のサイトなどでコマンドを実行しながら、Gitの動きを確認します。

* [いまさらだけどGitを基本から分かりやすくまとめてみた](https://qiita.com/gold-kou/items/7f6a3b46e2781b0dd4a0)
(@gold-kouさん)
* [サルでもわかるGit入門](https://backlog.com/ja/git-tutorial/)
Craft CMS の meta タイトルやパンくずリストを配列で処理する

meta タイトルやパンくずリストなどをテンプレートで出力する場合、必要な情報を配列に用意しループ処理すれば効率的に実装できる。ここでは `ブログ` 詳細ページのテンプレートを想定したサンプルコードを備忘録を兼ねてポストしてみる。

なお、Craft CMS と同様にテンプレートエンジンに Twig を採用している場合は、ほぼほぼ同じコードで動くと思われる。

## 詳細ページのテンプレートで変数を定義

`merge` フィルタでトップページ以外の URL とページタイトルを配列 `hierarchy` に追加する。

```twig:templates/blog/_entry.twig
{#- --------------------------------
# 設定：パンくず / JSON-LD
# -------------------------------- -#}
{#- 配列を初期化 -#}
{% set hierarchy = [] %}

{#- 親ページを配列にセット -#}
{% set hierarchy = hierarchy | merge([{ 'url': siteUrl ~ 'blog/', 'title': 'blog' }]) %}

{#- 現在のページを配列にセット -#}
{% set hierarchy = hierarchy | merge([{ 'url': entry.url, 'title': entry.title }]) %}
```

次に、配列 `hierarchy` をループ処理し、区切り文字を ` | ` で連結したものを変数 `meta_title` にセットする。

```twig:templates/blog/_entry.twig
{#- --------------------------------
# 設定：meta 関連
# -------------------------------- -#}
{% set meta_title = '' %}
{% set meta_og_url = '' %}
{%- for level in hierarchy -%}
  {#- hierarchy のループ処理で、逆順にパイプで連結 -#}
  {% set meta_title = level.title ~ ' | ' ~ meta_title %}
  {#- og_url をセット -#}
  {% if loop.last %}{% set meta_og_url = level.url %}{% endif %}
{%- endfor -%}
```

ループの最後は表示中の詳細ページにあたるため、変数 `meta_og_url` にセットしておく。

## meta 情報の出力

meta 情報の出力先となる `_layout.twig` では、変数が未定の場合に初期値をセットする処理を加えておく。

```twig:templates/_layout.twig
{#- ------------------------------------------
変数が未定義の場合の上書き処理
--------------------------------------------- -#}
{%- if meta_title is not defined %}
  {#- 固定の meta タイトル -#}
  {% set meta_title = 'Craft CMS Sample' %}
{% endif -%}

{%- if meta_description is not defined %}
  {#- 固定の meta 概要文 -#}
  {% set meta_description = '概要文のサンプルテキスト。' %}
{% endif -%}


{#- ------------------------------------------
出力
--------------------------------------------- -#}
<title>{{ meta_title }}</title>
<meta name="description" content="{{ meta_description }}">
<link rel="canonical" href="{% if meta_og_url is defined and meta_og_url %}{{ meta_og_url | raw }}{% else %}{{ siteUrl }}{% endif %}">
```

あとは、マークアップの目的の箇所に対応する変数を出力する。

## パンくずリストの出力

ここでは、パンくずリストは `_partials/topic-path.twig` にモジュールとして用意しているとする。

サイトトップのように出力自体が不要なページであれば配列 `hierarchy` を定義しなければよく、ループの最後だけ a タグを付加しないようにしている。

```twig:templates/_partials/topic-path.twig
{% if hierarchy is defined %}
  <ul>
    <li><a href="/">ホーム</a></li>
    {% for level in hierarchy %}
      {% if loop.last %}
        <li>{{ level.title }}</li>
      {% else %}
        <li><a href="{{ level.url | replace(siteUrl, '/') }}">{{ level.title }}</a></li>
      {% endif %}
    {% endfor %}
  </ul>
{% endif %}
```

なお、`replace(siteUrl, '/')` でリンク URL をドメインルートからの絶対パスに置換しているが、ここはお好みで。。。
Rails minitest Mockで例外発生パターンのテスト

[@koshi_life](https://twitter.com/koshi_life) です。

Rails 標準のテストフレームワーク minitest にて Mock側で例外を発生させるテストケースの書き方の備忘です。

### 前提

- Rails 5.2.3
- Ruby 2.6.0
- minitest 5.11.3

## 検証対象モジュール

`api_client`をコンストラクタ引数で取り、テスト対象の`coutup`関数は、引数の`item_id`をAPI経由(#get)で取得し、値に1加えてAPI経由(#update)で更新する簡素な内容です。


```fuga.rb
class Fuga
  def initialize(api_client)
    @api_client = api_client
  end

  def countup(item_id)
    error_code = 0

    # APIでItem取得
    begin
      item = @api_client.get(item_id)
    rescue StandardError => e
      # Case1: テストではココの分岐に入ることを確認します
      error_code = 1
      return false, error_code
    end

    # APIでItemの値更新
    begin
      @api_client.update(item_id, item[:val] + 1)
    rescue StandardError => e
      # Case2: テストではココの分岐に入ることを確認します
      error_code = 2
      return false, error_code
    end
    return true, error_code
  end
end
```

## テストコード

`api_client`をMock化します。`api_client#get`, `api_client#update`コール時に例外を捕捉する分岐を通るケースを書いてみます。

>[Mock#expect-instance_method](https://www.rubydoc.info/gems/minitest/5.8.4/Minitest/Mock#expect-instance_method) より
>
>```
#expect(name, retval, args = [], &blk) ⇒ Object
```

の`&blk`の Procを利用して例外を発生させることができます。


```fuga_test.rb
require 'test_helper'

class FugaTest < ActiveSupport::TestCase
  test 'Case1: api_client#getで例外発生' do
    item_id = 'id-1'
    retval_get = { val: 1 }
    args_get = [item_id]

    api_mock = MiniTest::Mock.new
    api_mock.expect(:get, retval_get) do |args_update|
      raise StandardError('Mock#getで例外発生')
    end

    # 検証したいモジュールを実行します
    fuga = Fuga.new(api_mock)
    result, error_code = fuga.countup(item_id)
    assert_equal(false, result)
    assert_equal(1, error_code)

    # Mockに送信されたデータを検証します。
    api_mock.verify
  end

  test 'Case2: api_client#updateで例外発生' do
    item_id = 'id-2'
    retval_get = { val: 2 }
    args_get = [item_id]

    retval_update = nil
    args_update = [item_id, 3]

    api_mock = MiniTest::Mock.new
    api_mock.expect(:get, retval_get, args_get)
    api_mock.expect(:update, retval_update) do |args_update|
      raise StandardError('Fuga#updateで例外発生')
    end

    # 検証したいモジュールを実行します
    fuga = Fuga.new(api_mock)
    result, error_code = fuga.countup(item_id)
    assert_equal(false, result)
    assert_equal(2, error_code)

    # Mockに送信されたデータを検証します。
    api_mock.verify
  end

  test '参考: 比較用に正常系' do
    item_id = 'id-3'
    retval_get = { val: 3 }
    args_get = [item_id]

    retval_update = true
    args_update = [item_id, 4]

    api_mock = MiniTest::Mock.new
    api_mock.expect(:get, retval_get, args_get)
    api_mock.expect(:update, retval_update, args_update)

    # 検証したいモジュールを実行します
    fuga = Fuga.new(api_mock)
    result, _ = fuga.countup(item_id)
    assert_equal(true, result)

    # Mockに送信されたデータを検証します。
    api_mock.verify
  end
end
```

### 参考

- [Mock#expect with block raising Exception does not verify properly #440](https://github.com/seattlerb/minitest/issues/440)
rails serverをしてBooting pumaでエラーが出た時の対処

```
$ ./qs rails server
Starting aaaa_db_1 ... done
=> Booting Puma
=> Rails 5.2.3 application starting in development
=> Run `rails server -h` for more startup options
A server is already running. Check /app/tmp/pids/server.pid.
Exiting
```

プロジェクト内に`/tmp/pids/server.pid`があるか調べる。
`server.pid`とはサーバーが起動していると生成されるファイルなので、もし存在していたら削除をする。
削除して改めて`$ ./qs rails server`をしたら無事起動されるはず。
意識の整理2

https://qiita.com/nervebmd/items/687c214c4b420ce39181 の反論

脳細胞が一つの記憶を曖昧に機能として起動している時
脳細胞が曖昧な状態なのでどの状態でも生きたか死んだか言うことは不可能
つまり死んでいる機能しない状態でも、人間は本のような存在
#死んだら終わり
https://qiita.com/nervebmd/items/687c214c4b420ce39181 の
死んだら終わるという状態というのは、
私と死んだ私
つまり
ロボットと死んだ私は相対的に存在し、
他の生き物だから、私は生き戻ることは不可能という話
自然なことなので回避不可能

#死んでも、生き戻る
何次元を重ねて考えると
そこまで難しくない話で
いくつかの理念（意識）が存在してても機能という私は一つであってchild的な要素として力学してる（私という一つの機能を元で動いてる）

#ブラックホールを作って完全に壁を作り意識の移動を止め
https://qiita.com/nervebmd/items/687c214c4b420ce39181 では
ブラックホールのようなところでいる私を考えてこの文章を反論できると自然に思いつく
だから私はそこに私一人として存在するということ
という話が成立する。
でもブラックホールにいる私はブラックホールの中でばらばらとなって死ぬ
死んでいないとしても、死んだ状態と死んでいない状態が曖昧で
相対的にそう見えるだけとしても実際の現実では二人が一人か分からない
つまり現実では一人にすぎない夢は夢の夢つまり、幻
哲学に頼りすぎてもなにも出ない

#まとめると
人間は本のような存在ということを否定できない
でもhttps://qiita.com/nervebmd/items/687c214c4b420ce39181 のように
死んだ状態も否定できない
てっとり早い解析としては、両方存在すると見る考えも。
Field 'カラム名' doesn't have a default valueの対処法について

##　原因
MySQLのバージョンが上がったことにより、デフォルト値がないカラムに、
値なしでINSERTしていることを認めなくなったことでエラーとなってしまう。

##　対処法
エラーが出てくる各カラムのNOTNULL属性を解除する。
AWS EC2インスタンスのパブリックIP(EIP)

# AWS EC2インスタンスのパブリックIP(EIP)

## EIPから作成したパブリックIP
* EC2インスタンスへのアタッチ、デタッチが可能

## 自動割り当てされたパブリックIP
* VPC のサブネットで自動割り当てパブリックIPを有効化する
* EC2インスタンス起動時に自動でアタッチされている
* デタッチできないもよう

## 参考
* パブリック IP が外せない… [cloudpack OSAKA blog]
  * https://cloudpack.media/29286
暗号化の種類とbase64 

業務でセキュリティ高く実装する必要に迫られた。
その際に `base64` で暗号化すれば十分かと思ったが、不適切と指摘されたので暗号化について調べてみた。

# 暗号化の種類
1. keylessな暗号化
2. private keyを使った暗号化
3. pubilc keyを使った暗号化


# keylessの暗号化
- いわゆる暗号化処理のこと
- `base64`もこれ
- 一つの入力から、ランダムな文字列に置換する
- 可逆なので、元の入力を復元することができる
- 秘匿情報などを保持する際に使う

# private keyを使った暗号化
- 暗号対象の文と、秘密鍵の2つのインプットをもとにして一意なランダムな文字列を出力する


# public keyを使った暗号化
- 送り手と受け手がいることを想定
- それぞれは `public key`と `private key`を持つ
- 相手には `public key`を渡す。
- 相手の `public key`と自分の `private key`から新しい `key`を作成する。
- この `key`をもとに暗号化する

# まとめ
`base64`で暗号化するだけだと、可逆な値なので良くないことがわかりました。
また、inputも暗号化対象の文だけなので、容易にもとの値を特定されてしまうんだなと。

# 参考
https://www.marineroad.com/staff-blog/17723.html
https://www.markupdancing.net/archive/20160310.html
https://paragonie.com/blog/2015/08/you-wouldnt-base64-a-password-cryptography-decoded
Visual Studio 2017 で dotnet core 2.2 を作成しようとしたら空のプロジェクトしか選べなかったので設定したメモ

## 概要

Visual Studio 2017を使い始めようとしたら、空のプロジェクトしか選べなかったので対応した。

## 環境

* Windows 10
* Visual Studio 2017 Community

## 手順

基本的に[Visual Studio 2017 の前提条件](https://docs.microsoft.com/ja-jp/dotnet/core/windows-prerequisites?tabs=netcore2x#prerequisites-with-visual-studio-2017)の手順に従う。

### ASPNET Core Webアプリケーションプロジェクトが選べるようにする

* 空のプロジェクトしか選べない
* 探しているものが見つからない場合の、「Visual Studio インストーラを開く」リンクをクリック
![1.empty_solution.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/eb45ec09-3fab-17ce-3663-f1152b092d25.png)

### インストーラ

* インストーラが起動するが、今回のdotnet core SDKは見えないところにある。

![2.0-installer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/7a7472f8-099c-1931-f8b4-aa30f3ceef3a.png)

* スクロールすると出てくるので選択してインストール

![2.3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/503f5786-157e-445e-34cf-c5549fd81ce8.png)

* 選べるようになった

![3-choice.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/a7baa5bf-8b34-21fe-46b8-c4f68c01d205.png)

### ASPNET Core 2.2を選べるようにする

* 空のプロジェクトしか選べない問題は解決したが、Dotnet Core 2.1しか選べない問題が発生

![4-2.1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/9718d9dd-db1d-620f-d5b1-fcc7e43c8bc8.png)

* [Dotnet Core SDK 2.2](https://dotnet.microsoft.com/download)のインストーラをダウンロード

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/6721a42b-4ed3-35b1-2258-d198221ac7b5.png)

* ダウンロードしたインストーラを起動してインストール

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/dc3cba36-95eb-b25f-da58-3810da5cdee1.png)

* もう一度、プロジェクトの作成をすると、2.2が選べるようになっている

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/46dce298-59de-3062-614c-887d6212c6e8.png)
[DateRangePicker] JavaScriptでカレンダーを表示する

JavaScriptでカレンダーを表示するライブラリを紹介します。

DateRangePicker
http://www.daterangepicker.com/

```Markdown:JavaScriptライブラリ
Bootstrap: 3.3.7
jQuery: 3.3.1
DateRangePicker: 3.0.3
Moment.js: 2.24.0 
```

# ライブラリの読み込み

`daterangepicker.css`と`daterangepicker.js`を参照します。

```HTML:ライブラリを読み込む
<link rel="stylesheet" type="text/css" href="../lib/daterangepicker/daterangepicker.css" />
<script type="text/javascript" src="../lib/daterangepicker/daterangepicker.js"></script>
```

# カレンダーの表示

inputテキストボックスをHTMLに実装します。

```HTML:テキストボックスを表示する
<input class="form-control text-box single-line" type="text" id="inputText1" />
```

inputテキストボックスに対して、`daterangepicker`関数で初期化します。
`singleDatePicker`は表示するカレンダーの数を指定できます。`true`が1つ、`false`が2つとなります。`showDropdowns`は`true`を指定すると、年と月のドロップダウンリストが表示されます。

```JavaScript:カレンダーを1つ表示する
var FORMAT_YYYYMMDD = 'YYYY/MM/DD';

$('#inputText1').daterangepicker({
    singleDatePicker: true,
    showDropdowns: false,
    locale: {
        format: FORMAT_YYYYMMDD
    }
}, function (start, end, label) {
    log(moment(start).format(FORMAT_YYYYMMDD));
});
```

# カレンダーで期間を指定する

カレンダーを2つ表示すると、期間を指定することができます。
初期化時に関数を指定することで、カレンダー上で日付を選択したときの日付を取得することができます。`start`は開始日、`end`は終了日となります。

```JavaScript:カレンダーを2つ表示する
$('#inputText3').daterangepicker({
    singleDatePicker: false,
    showDropdowns: false,
    locale: {
        format: FORMAT_YYYYMMDD
    }
}, function (start, end, label) {
    log('start=' + moment(start).format(FORMAT_YYYYMMDD));
    log('end=' + moment(end).format(FORMAT_YYYYMMDD));
});
```

[デモはこちら](https://yunbow.github.io/sample-daterangepicker/01/)
[ソースファイルはこちら](https://github.com/yunbow/sample-daterangepicker/tree/master/01/)

以上です。
Vue.jsで学ぶ名前付けの重要さ

## はじめに
　昔MSXでプログラム組んでたな〜と言う第二次ベビーブーム真っ盛り世代の昭和な方々、お疲れ様です。私もその年代です。名前は重要ですよね、昔は〜〜町の一郎・花子みたいな感じだったでしょうか？
## 過去の名残
　で、名前付けですが、過去のBASICであれば`I`で始まれば`整数型`、`S`で始まれば`文字列`、`A`で始まれば`実数型`なんて勝手に型名が確定したりしました（宣言文で変える事も可能でしたが）。今でもJavaScriptでもその名残で`for (var i = 0; i < 10; i++) {}`なんて書きますよね。 

## Vue.js + JavaScript では
　とりあえず実際のソースを見ましょう。

```sample1.html
<!DOCTYPE html>
<html lang="jp">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<script>
	Vue.component('test-hello', {
		data() {
			return {
				message: 'Hello! ' + this.ariaLabel,
			}
		},
        template: '<div id="test-hello">' +
	        '    {{ message }}' +
	        '</div>',
		props: {
			'ariaLabel': {
				type: String,
				required: true,
			},
		},
	});
</script>
    <div id="app">
        <test-hello aria-label="Vue.js"></test-hello>
    </div>
<script>
	new Vue({
		el: '#app',
        data: {
        }
	});
</script>

</body>
</html>
```

### 説明

```html
    <div id="app">
        <test-hello aria-label="Vue.js"></test-hello>
    </div>
```
呼び出し元はこのように`area-label`に`Vue.js`を入れています。この`aria-label`というハイフン入りの書き方をケバブケースと呼びます。

```javascript
	Vue.component('test-hello', {
		data() {
			return {
				message: 'Hello! ' + this.ariaLabel,
			}
		},
        template: '<div id="test-hello">' +
	        '    {{ message }}' +
	        '</div>',
		props: {
			'ariaLabel': {
				type: String,
				required: true,
			},
		},
```
そしてこれが呼び出し先で`ariaLabel`という名前のプロパティに格納されます。この`ariaLabel`というハイフンや空白を外して単語の先頭を大文字にした書き方を`キャメルケース`と呼びます。
（この動作はVue.js側で自動的に行われます）
`data`節に `message: 'Hello! ' + this.ariaLabel` と書いておくと、`Hello! ` に 先ほどの`ariaLabel` を足していますので、期待される結果は`Hello! Vue.js`になります。

### 結果

```plaintext:結果
Hello! Vue.js
```
この通り、`Hello! Vue.js` と表示されました。

　`Vue.js`だと、`HTML`に記述する'パラメータと、`Vueコンポーネント`で指定するプロパティはそれぞれ`ケバブケース`と`キャメルケース`にする必要があります。最初、私もかなり戸惑いました。
　ケバブケースだと`aria-label`のように`半角小文字とハイフン`を使用します。プロパティでは`キャメルケース`という`ariaLabel`のようにハイフンを除いて二つ目以降の単語の頭文字を大文字にする必要があります。
　`ケバブ`はよくお祭りとかに出る串焼きした肉のことで、`text-name`のように`ハイフン`が串のようだからケバブケース。
　`キャメル`ってのは動物の`ラクダ`の事なので、`textName`みたいに書くと`ラクダのコブ`に似ているからそう名付けられたと思ってます（すべて私の憶測）。

　私は『なんでこんなにわかりにくい仕様なんだ？』と最初は思いました。でも、Vue.jsを使っていくうちに、『これはパラメータとプロパティをあえて区別することによって、視認しやすくしているのだ』と実感させられました。

　もしこれがケバブケースしかなかったら、こんな感じに。

```javascript:これはエラーとなり画面は空白となります。
	Vue.component('test-hello', {
		data() {
			return {
				message: 'Hello! ' + this.aria-label,
			}
		},
        template: '<div id="test-hello">' +
	        '    {{ message }}' +
	        '</div>',
		props: {
			'aria-label': {
				type: String,
				required: true,
			},
		},
```
　統一感はあるかもしれないけど、読みにくいです。（それ以前にJavaScriptだと名前にハイフンは入れられないか…）

## 今は昔…
　そう言えば、かなり昔、とある会社でプログラム書いてたのですが（当時はCOBOL言語だった気がする）、そこにアニメ好きな方がいて、変数名や関数名がすべて`アニメのキャラクター`や`アイテムの名前`というソースを実際に拝見しました。

　まぁ個人の自由といえばそれまででしょうが、『これをもし引き継いだ人がいたらどうなるんだろう？』と感じました。引き継いだ人がいたとしても『アニメ好き』かどうかはわかりませんし…。

　あと、私は英語読むのはできるけど英訳するのが下手で、『変数の意味がわからない』と実際よく言われます。最近は命名する時に[Google翻訳](https://translate.google.co.jp/)か[みらい翻訳](https://miraitranslate.com/trial/)を使わせていただいてます。
## というわけで…
　わかりやすいかどうかわかりませんが、`Vue.js`使ったら`命名する基本`がちょっと身についたお話でした。最後までよんでいただきありがとうございました。
vroidイラスト風（仮）

イラスト化テスト用



2017.4.15f1バージョンで作った
vrcには対応するか知らない
勝手に使ってください
エッチなことでもじゃないことでも使ってください

入ってるアセット
VRM
昔standard assetの一部
dynamic bone
ホストプロセス2

projectファイルダウンロード
https://ci-en.jp/creator/2537/article/57156
rails5でタグ機能をacts-as-taggable-onを用いて実装する方法

# 概要
acts-as-taggable-onを使ってタグ機能を実装する方法です。
投稿にタグを複数登録できるようにし、indexやshowでタグのリンクがクリックされた際にそれと同じタグを持つ投稿を一覧表示させるところがゴールです。
もし間違い等あればご指摘の程よろしくお願い致します。

# 開発環境
Ruby on Rails 5.2.3

# Gemfile
```ruby:Gemfile
gem 'acts-as-taggable-on'
```
```
$ bundle install
```
僕は出なかったのですが、もしエラーが出る場合は

```ruby:Gemfile
gem 'acts-as-taggable-on', :git => 'https://github.com/mbleigh/acts-as-taggable-on'
```
としてからbundle installするといいみたいです。

# テーブル作成
```
$ rails acts_as_taggable_on_engine:install:migrations
```
```
$ rails db:migrate
```
#Model
タグ機能をつけたいテーブルのmodelに

```ruby:app/models/post.rb
acts_as_taggable
```
を追記。僕の場合はpostテーブルでした。
#controllers
Strong Parametersに:tag_listを追記

```ruby:app/controllers/posts_controller.rb
def post_params
  params.require(:post).permit(:title, :content, :tag_list)
end
```
アクションの変更

```ruby:app/controllers/posts_controller.rb
def index
  if params[:tag]
    @posts = Post.tagged_with(params[:tag])
  else
    @posts = Post.all
  end
end
```

# View
## タグ用フォーム
```erb:app/view/posts/new.html.erb
<div class='field'>
    <%= f.label :tag_list %>
    <%= f.text_field :tag_list %>
</div>
```

## リンク付きタグの表示
```erb:app/posts/show.html.erb
<p>tags: <%= raw(@post.tag_list.map { |t| link_to t, tag_path(t) }.join(', ')) %></p>
```
#Routes
```ruby:config/routes.rb
get 'tags/:tag', to: 'posts#index', as: :tag
```
これでタグをクリックすると同じタグがついているデータを一覧表示できるようになります。


# 参考
https://rubyplus.com/articles/4231-Tagging-using-Acts-as-Taggable-On-in-Rails-5

https://github.com/mbleigh/acts-as-taggable-on