OmniAICreator/Qiita-1.07M huggingface dataset:
【Vue.js】ローディング画面を実装する

##はじめに
[vue-loading-templateモジュール](https://github.com/jkchao/vue-loading)を用いて、Vue.jsのアプリにローディング画面を実装しました

Vue.jsのアプリにはVuetifyを使用しています

![loading.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009493/29545866-9bd8-9488-94ea-bb4cbec949e5.gif)


適用したVue.jsのアプリはこちら↓

https://komekami.info/

##. vue-loading-templateのインストール
```
$ npm add vue-loading-template
```

##src/App.vue
```vuejs:App.vue
<template>
  <v-app id="inspire" :style="{background: $vuetify.theme.dark}" >
　　<!-- ローディング -->
    <Loading v-show="isLoading"></Loading>
    <v-main
      :style="{width:'90%', margin: '3vh auto'}"
      v-show="!isLoading"
    >
      <!-- 省略 -->
    </v-main>
    <v-footer
      color="grey darken-2"
      padless
      v-show="!isLoading"
      >
      <v-col
        class="text-center white--text"
        cols="12"
      >
        {{ new Date().getFullYear() }} — <strong>Komekami</strong>
      </v-col>
    </v-footer>
  </v-app>
</template>

<script>
// Loadingコンポーネントの読み込み
import Loading from '@/components/Loading'
export default {
  data: () => ({
    isLoading: true,
    drawer: null,
    items: [
      { title: 'Top', icon: 'mdi-view-dashboard', link: '/' },
      { title: 'Profile', icon: 'mdi-account', link: '/profile' },
      { title: 'Gallery', icon: 'mdi-image', link: '/gallery' },
      { title: 'Contact', icon: 'mdi-forum', link: '/contact' }
    ],
    right: null
  }),
  // Loading切り替え処理
  mounted () {
    setTimeout(() => {
      this.isLoading = false
    }, 1000)
  },
  components: {
    Loading
  }
}
</script>
```

###Point
* ローディング画面コンポーネントを**Loading**として読み込んでいます

* **変数isLoading**を用いてtrueかfalseかでローディング画面の表示/非表示を行っています。

* **mounted**を使用し切り替えを行っています。

* mountedはDOMの作成完了時にisLoading=falseとなり、ローディング画面が非表示になります。

* メイン部(v-main)とフッター部(v-footer)は変数isLoadingがfalseで描画(v-show)されます。

##src/components/Loading.vue
ローディング画面のコンポーネントです。

```vue:Loading.vue
<template>
  <div v-show="isLoading">
    <div class="fullview">
      <div class="loading-spacer"></div>
        <vue-loading
          type="beat"
          color="#304686"
          :size="{ width: '100px', height: '100px' }"
          >
        </vue-loading>
    </div>
  </div>
</template>

<script>
import { VueLoading } from 'vue-loading-template'

export default {
  name: 'isLoading',
  data () {
    return {
      isLoading: true
    }
  },
  components: {
    VueLoading
  }
}
</script>

<style>
.fullview {
  width: 100%;
  height: 100%;
  background:black;
  position: fixed;
  top: 0;
  left: 0;
}
.loading-spacer {
  height: 40%;
}
</style>
```

###Point
* VueLoadingをインポート
* ```<vue-loading>```内でLoadingの各種設定を行っています

>今回はローディングの動き方をtype="beat"にしました
>他にも色々typeがあるので[vue-loading-template](https://github.com/jkchao/vue-loading)をチェックしてみてください

##さいごに
モジュールをインストールすることで簡単にローディング画面を実装することができました。

SPAは初回読み込み時に時間がかかりがちなので、ローディング画面を実装するとサイト訪問者のストレスも軽減されるのではないかと思います。

##参考

https://qiita.com/terufumi1122/items/214d82f74370ef377aa2

https://qiita.com/showy/items/38747e6cebfd7f89cff3

https://github.com/jkchao/vue-loading
クーポンコレクター問題：どうぶつの森で73種類の化石コンプリートには何日かかる？

## はじめに

どうぶつの森の化石を1日1つ採取するとき、73種類をコンプリートする日数の分布は次のようになる。この分布から、コンプリートには約300日かかることが分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/b9a8f254-8890-5f25-159a-29e23d8708d8.png)

この分布を計算機的・数学的に求める。

## 計算機的な方法

```python
import numpy as np
import collections
import matplotlib.pyplot as plt
import random


# randomモジュールの関数randint(a, b)はa <= n <= bのランダムな整数intを返す。
# 73個全ての化石の所有数が1以上になったときにwhileループを抜け、それまでにかかった日数を返す関数
def get_days(k):
    fossil_list = [0] * k
    days = 0
    while min(fossil_list) == 0:
        num_fossil_per_day = 1
        for i in range(num_fossil_per_day):
            fossil_list[random.randint(0, k - 1)] += 1
        days += 1

    # print(sorted(fossil_list))
    return days

# かかった日数をnum回取得して分布を取得する。numが大きいほど分布は正確になる
def days_plot(k=73, num=10000):
    days = [get_days(k) for i in range(num)]

    c = collections.Counter(days)
    key = list(c.keys())
    value = list(c.values())

    # print("最短でコンプリートできる日数:", min(key))
    left = np.array(key)
    height = np.array(value) / sampling_num
    plt.title('number of samples: {}'.format(num))
    plt.xlabel('number of days for complete')
    plt.ylabel('probability')
    plt.bar(left, height)
    plt.show()


# どうぶつの森の化石73種類
k = 73
# データサンプル数
sampling_num = 10000

# 横軸が日数、縦軸が N日目に初めて73種類の化石をコンプリートする確率分布
days_plot(k, sampling_num)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/bafcbbe3-9cc7-4611-0dde-fb37d27453e5.png)



## 数学的な方法

```python
from sympy.functions.combinatorial.numbers import stirling
import matplotlib.pyplot as plt
import math

# 第二種スターリング数を活用
# 詳しくは以下のwebサイトへ
# http://peng225.hatenablog.com/entry/2019/03/15/085054
k = 73
numTrial = 900
x = []
y = []
for n in range(1, numTrial+1):
    stir = stirling(n-1, k-1, kind = 2)
    prob = math.factorial(k) * stir / (k**n)
    x.append(n)
    y.append(prob)

plt.xlabel('number of days for complete')
plt.ylabel('probability')
plt.plot(x, y, label='k = {}'.format(k))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/b9a8f254-8890-5f25-159a-29e23d8708d8.png)

## おわりに
分布をみると、1日1個化石が採れると仮定して、73種類をコンプリートするのに、200日目から300日目にかけて急峻に確率が上がり、そこからはなだらかに下がっていた。
ここから、73個の化石をコンプリートするには1年近くかかること、そして数％の人は600日以上もかかってしまうことが分かった。
Visual Studio Code　保存時のBeautifyが完了しない問題

Visual Studio Codeのコード整形用拡張機能「Beautify」を使っていて、保存時に自動整形する設定をしている。

とあるHTMLを編集していざ保存しようとすると、

>**〇〇〇.htmlを保存しています:'Beautify'フォーマッタ(構成)を実行しています。**

とメッセージが出たままいつまでたっても整形が完了しない。（保存は完了する）
さらに、このエラーが一度発生すると以降どのファイルを開いても同じ状況に陥り、VSCodeを再起動することでしか解消できない。

何かソースに問題あるのか調べたところ、metaタグの書き方がXHTML形式（>の前に/がある）だ
と再現することが判明。

```html:問題が発生する書き方
<meta name="Description" content="xxxxxxxxxx" />
```

末尾のスラッシュを取ったところ、発生しなくなった。

```html:末尾の/を取ると発生しなくなった。
<meta name="Description" content="xxxxxxxxxx">
```

metaタグの>前に、スラッシュを入れる事はHTML5の文法的には間違っていない（非推奨ではない）のに、なぜ整形エラーになるのかは謎。
webpack + Babel を使ってIE対応したつもりが、アロー関数が残っていてIEで実行できなかった件

あるプロジェクトで、webpackでVue.jsの環境構築をしました。
Babelを導入しトランスパイルの設定もしたので、Internet Explorer (IE11) でも動くだろうと思っていました。
しかし、実際にIE11で確認してみると、Vue.jsで作ったアプリケーションが全く動かない。。
コンソールを見てみると、JavaScriptのエラーが出ていました。
なんでだろうと思い、コンパイル後のファイルを覗いてみると、、

```app.js
(()=>{ ... })();
```

いや、アロー関数残ってるやないかーい！！
IE11はいまだにアロー関数に対応してないので、これだとエラーになってしまいます。

## (2022年8月追記) 本質はwebpack 4 → 5の変更点でした
当時は本質を理解しないまま記事を書いてしまったことをお詫び申し上げます :bow: 
本当の原因は、 webpack5 から出力ターゲットがデフォルトで ES2015 以降になっていることでした。
なので、ターゲットを ES5 にすることでうまくいきます。

参考記事: [最新版で学ぶwebpack 5入門 - Babel 7でES2021環境の構築(React, Vue, Three.js, jQueryのサンプル付き) - ICS MEDIA](https://ics.media/entry/16028/)

```webpack.config.js
module.exports = {
  // （略）
  target: ["web", "es5"],
}
```

↓ 以下、当時の格闘ログを残しておきます。

## うまくいかなかったときのwebpackの設定
当初、webpackの設定ファイルの中身はこんな感じでした。

```webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
  entry: {
    app: './src/app.js',
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist'
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin()
  ],
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    },
  }
}
```

ちゃんとBabelインストールして設定したのに、何がいけないの？　って感じでした。
Babelの設定の問題だと思い、いろいろ試し、何時間も格闘しました。
が、原因はBabelではありませんでした。

## 改良後のwebpackの設定
改良後のwebpackの設定ファイルはこんな感じです！

```webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
  entry: {
    app: './src/app.js',
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist',
    environment: {
      arrowFunction: false
    }
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin()
  ],
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    },
  }
}
```

さて、みなさん、何が変わったかお気づきでしょうか？
なんと、たった3行追加しただけです！

```JavaScript
    environment: {
      arrowFunction: false
    }
```

この3行をoutputの中に入れただけです！
よく見ると、webpackの公式ドキュメントに、さらっと書いてあります。さらっと。。
https://webpack.js.org/configuration/output/#outputenvironment
こんなのわかるわけないじゃないか！！

上記の設定をすることで、webpackがアロー関数を出力しないよう制御できるみたいです。
結果、コンパイル後のファイルを見てみると…

```app.js
!function(){ ... }();
```

やった！　やっと関数がfunctionになったぞ！
IEで確認してみると、、
無事に動きました！！

めでたしめでたし

みなさんも、Babel導入してちゃんと設定したのにアロー関数が残っているなーと思ったら、上記設定を試してみてください。
僕みたいに無駄に格闘して消耗する被害者が減ることを願っています。
【CSS】li要素を横並びにする主な方法

##はじめに
サイト模写を行っていた時に、li要素を横並びにする方法がわからなかったのでまとめました。
今回紹介する以外にも[横並びにする方法](https://qiita.com/katsunory/items/99a417f4e1a763477a09)はありますが、今回は私が調べて使ってみた方法について書いています。

li要素を横並びにする主な方法

* float: left;
* inline-block化

##float: left;
li要素をfloat:leftで横並びにする

```css
li{
  float: left;
}
```

このとき、li要素が浮くのでulにclearfixをする
```HTML
<ul class="sample clearfix">
  <li>hoge</li>
  <li>hoge</li>
</ul>
```

```css
.clearfix::after{
  content: "";
  display: block;
  clear: both;
}
```

##inline-block化
li要素をinline-block化する

```css
li{
  display: inline-block;
}
```

このときli要素同士に余白ができるのでulでfont-size:0;
liでfont-sizeを指定する

```css
ul{
  font-size: 0;
}
li{
  font-size: 13px;
}
```

###おまけ：displayとは
CSSのプロパティであり、要素の表示形式を決める

displayには主に4種類ある

* block:  要素が横いっぱいに広がり、縦に並ぶ
* inline: 要素が平べったく横に並ぶ
* inline-block: 並びはinline,中身はblock
* none: 非表示

それぞれの特徴について(noneを除く)

|  | block | inline | inline-block |
|:-----------:|:-----------:|:------------:|:------------:|
| 改行と並び | 前後に改行が入る       | 横に並ぶ       | 横に並ぶ         |
| 幅・高さの指定 | 幅と高さが指定できる     | 幅と高さが指定できない      | 幅と高さが指定できる     |
| 余白の指定 | margin,paddingが指定できる | 左右のmargin,paddingが指定できる        | margin,paddingが指定できる         |
| text-align | 指定できない         | 指定できる          | 指定できる           |
| vertical-align | 指定できない       |　指定できる       | 指定できる       |


##さいごに
clearfixとクラスを指定するだけでよいのでfloat:left;のほうが使い勝手がよいと思った。
displayプロパティについても知ることができたので勉強になった。

##参考

https://illbenet.jp/view/css-howto_li_side_by_side

https://qiita.com/katsunory/items/99a417f4e1a763477a09

https://saruwakakun.com/html-css/basic/display
Laravelのコントローラー解説(編集中)

コントローラとは、

ルーティングからリクエストを受け取り、適切なレスポンスを返すため、各種のデータ処理を行った上でビューに必要な変数を渡す役割を持った物です。


```PHP

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
 
class SampleController extends Controller
{
    public function sampleAction(){
        $title = 'コントローラーのアクションを利用';
        return view('samples.blade_example',[
            'title' => $title,
        ]);
    }
}
```


```PHP

<?php
 
namespace App\Http\Controllers;
 
use Illuminate\Http\Request;
 
class SingleAction extends Controller
{
    function __invoke(){
        $title = 'シングルアクションのサンプル';
        $description = 'シングルアクションコントローラを利用しています。';
        return view('samples.single_action', [
            'title' => $title,
            'description' => $description,
        ]);
    }
}
```
RSpecでログイン状態にする方法(sign_inヘルパー)

# 今回のテストを行うアプリの流れ
ログイン
⬇️
目標を決める
⬇️
正常に目標が保存されたら、トップページへ遷移する

RSpecでnewアクション機能の一連の流れをテスト（総合テスト）するにあたり、
ログイン状態にさせてから目的の実装を行うための方法をまとめました。

私自身が初学者のため、同じような方向けの内容となっています。

# 環境
Ruby 2.6.5
Rails 6.1.3.1

以下インストール済み
Devise 4.8.0
RSpec 3.10.0
FactoryBot
Faker

# 前提
devise導入後、authenticate_userを使って、
applicationコントローラーのlpアクション以外に__非ログイン状態__でアクセスすると、
ログイン画面にリダレクトされるようにしています。

```application_controller.rb
class ApplicationController < ActionController::Base
  #ログインしていない場合はログイン画面へ強制的に遷移する
  before_action :authenticate_user!, except: [:lp]
  before_action :configure_permitted_parameters, if: :devise_controller?

~中略~

end
```

# テストコード書き方
### RSpecでDeviseを使えるようにする

```spec/rails_helper.rb
RSpec.configure do |config|

~中略~
  #下のコードを追記
  config.include Devise::Test::IntegrationHelpers, type: :system
end
```

こちらをrails_helper.rbに記述することで、systemテスト時にdeviseのヘルパーを呼び出すことができます。
※system以外のrequestなどでも同様に使用できます。

### テスト用データを用意
FactoryBotを使ってユーザーのテスト用データを用意します。
今回はユーザーデータと目標データの2つが必要なので2つのデータを作りました。

```spec/factories/users.rb
FactoryBot.define do
  factory :user do
    nickname              { 'Taro' }
    email                 { Faker::Internet.free_email }
    password              { 'aaBB1234' }
    password_confirmation { password }
    family_name           { '田中' }
    given_name            { '太郎' }
    birth_day             { '1999-01-01' }
  end
end
```

```spec/factories/goals.rb
FactoryBot.define do
  factory :goal do
    saving_goal { '500000' }
    purpose     { '海外旅行を行くため' }
    period      { '2040-01-02' }

    association :user
  end
end
```

ユーザーモデルにfamily_nameカラムなどを追加している場合は追加したカラムのデータも記述します。
emailカラムはFakerを使ってダミーデータを生成してみました。

### 総合テスト用ファイルを作る

```spec/system/goal_spec.rb
require 'rails_helper'

RSpec.describe 'ゴール新規登録', type: :system do
  before do
　　#テスト用データを読み込む
    @goal = FactoryBot.build(:goal)
    @user = FactoryBot.create(:user)
  end

  context '新規登録できること' do
    it '正しい情報を入力すればゴール新規登録ができてトップページに移動する' do
     # 【sign_in @user】　によって、ログイン状態にする
      sign_in @user
      visit new_goal_path
      fill_in 'goal_saving_goal', with: @goal.saving_goal
      select '2022', from: 'goal_period_1i'
      select '12', from: 'goal_period_2i'
      select '12', from: 'goal_period_3i'
      fill_in 'goal_purpose', with: @goal.purpose
      expect do
        find('input[name="commit"]').click
      end.to change { Goal.count }.by(1)
      expect(current_path).to eq(root_path)
    end
　end
```

先ほどrails_helperにDeviseをincludeしたので__sign_in__というヘルパーが利用できます！
sign_inによってログイン状態を作ることができるので、ログインしている場合の総合テストが簡単に実装できるはずです。

# 最後に
ご覧いただき、ありがとうございます。
私はこの方法で実装できましたが、うまくいかないこともあるかと思います。
sign_inヘルパーを使用しなくとも、before do~end内で行う実装方法も見つけたため、
[こちら](https://teratail.com/questions/280085)も残しておきます。参考になれば、嬉しいです。

# 参考
[Rails RSpec コントローラーテストでログイン状態にする](https://qiita.com/kaichi_lvg/items/ca538e196fe1d2c31784)
SCPコマンドでssh接続先にファイルを転送

こんにちは。今日はSSH接続をした先のサーバーに自分の今いるディレクトリの中にあるファイル(またはディレクトリ)を転送するscpコマンドを紹介します。

SSH接続はサーバーにログインする時に使ったコマンドでした。
![スクリーンショット 2021-06-06 11.37.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227633/43c9a264-b697-c622-08bc-cfb07df9d45f.png)

今からSCPコマンドを用いてSSH接続した先のサーバーに自分のローカルデスクトップにあるファイルを転送します。

![スクリーンショット 2021-06-06 11.37.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227633/c5c4e48f-0a4a-f38e-3748-effaf7e0118c.png)
上記の通り現在ローカルPCのデスクトップにいますね。

![スクリーンショット 2021-06-06 11.42.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227633/9839eb1d-fc81-88b1-0636-24fd016ef1d7.png)

scpコマンドの文法は
「scp -i (ログインに必要な鍵) (転送したいファイル名) (接続先のIPアドレス):(接続先にてファイルを配置したいディレクトリのパス)」です。転送するものがファイルではなくディレクトリの場合は -r を直前につけます。

では、実行して見ましょう。

![スクリーンショット 2021-06-06 11.44.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227633/a8bb195d-5b43-7699-c90b-3866f2ef250e.png)

実際にファイルを転送できたかsshでサーバーにログインして確かめます。

![スクリーンショット 2021-06-06 11.45.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227633/6f35abb6-50e1-6f46-c41b-421144dbac18.png)

きちんとtest.htmlがありますね。
無事転送ができているようです。

以上scpコマンドでした！
M5Stackでスクロールグラフ M5GFX版

M5StackCore2でグラフ表示するdemoプログラムできました。
LovyanGFXでスプライトを使っているうちに高速スクロールができたので共有

https://twitter.com/panda728/status/1400076721693417472

##ソースコード

M5GFXで
ソースコードはこちら
https://gist.github.com/panda728/01a314b66890d8060b61efaef4b272ee


##概要
SwithBot温湿度計など複数台のデータを登録してグラフ表示する形を想定しています。

過去5時間を表示します。
画面構成上、最大6台までグラフ化します。

十分な数の計測ログがあれば、スクロールさせながら表示できます。

##基本動作
setupでBLEアドレスのリストとグラフ番号を設定します。（最大6件）（未設定の場合、登録された順になります）
https://gist.github.com/panda728/01a314b66890d8060b61efaef4b272ee#file-main-cpp-L447

計測データを用意(void loop内)
https://gist.github.com/panda728/01a314b66890d8060b61efaef4b272ee#file-main-cpp-L463

計測データを内部データに展開（Logger::push）
https://gist.github.com/panda728/01a314b66890d8060b61efaef4b272ee#file-main-cpp-L513

グラフ表示(ScrollGraphPanel::showDisp)
https://gist.github.com/panda728/01a314b66890d8060b61efaef4b272ee#file-main-cpp-L516

計測データは1分単位で丸めて時系列データに保存
最終データから過去5時間分のデータをグラフ（点）で描画します。

##応用
SwithBotの複数台からデータを収集してグラフ表示
収集データはAmbient Iotにアップロードして保存
といった用途に使います。

https://twitter.com/panda728/status/1401077726698622980

##（余談）リセット対策
電源が消えるとログも消えるので最初から計測になります。
以下のデータをsave loadする機能を追加すれば、リセットされてもグラフが消えないものになります。

Logger::logs
Logger::keys


##補足
namespace Logger　グラフ表示用のデータ管理
namespace ScrollGraphPanel　グラフ表示処理
namespace GraphUtil グラフ表示関連の計算処理

BLEがメモリを使うのでスプライトを抑えるため10分割にしています。
https://gist.github.com/panda728/01a314b66890d8060b61efaef4b272ee#file-main-cpp-L410

drawBodyでグラフ以外の表示を行っています
y座標をすべて-yOffすることで、スプライト上に必要な部分の描画を行います。(領域外の描画は無視される)
https://gist.github.com/panda728/01a314b66890d8060b61efaef4b272ee#file-main-cpp-L256
WSL2にCUDAをインストールしたが、GPUにアクセスできなくなった時

# When cuda don't work ( cuda is not recognized) in wsl2
## reference url
- https://answers.microsoft.com/ja-jp/insider/forum/insider_wintp-insider_devices-insiderplat_pc/wsl2%E4%B8%8A%E3%81%A7gpu%E3%81%8C%E8%AA%8D/b06602db-49ce-4818-adfb-3898433669ec

## solution
- Reinstalling Nvidia Driver for wsl2 cures it each time.
- wsl2用のnvidia-driverを再インストールしたら、再びGPUにアクセスすることが出来ました。

##　まとめ
- 他にも認識しない際の解決法がありましたら、追記していきます
フォローしてない鍵垢のフォロワーをまとめてブロックする

# フォローリクエストに応えない不気味な鍵垢を一掃する
## 環境の切り替え
```python
import sys
import argparse

def args():
    parser = argparse.ArgumentParser(description='environment name')
    parser.add_argument('-e', '--env', metavar='env', type=str,
                        help='environment name', default="")
    args = parser.parse_args()
    print(args)
    if args.env == "":
        print("No Argument")
        sys.exit()
    envName = args.env
    return envName
```

## 認証
```python
import tweepy
import configparser

def auth_api(envName):
    config = configparser.ConfigParser()
    config.read('setting.ini')
    print("envName is " + envName)
    consumer_key = config.get(envName, 'consumer_key')
    consumer_secret = config.get(envName, 'consumer_secret')
    access_key = config.get(envName, 'access_key')
    access_secret = config.get(envName, 'access_secret')
    auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
    auth.set_access_token(access_key, access_secret)
    api = tweepy.API(auth)
    return api
```

## 実行部分
```python
def main():
    meId = api.me().screen_name
    followerIds = api.followers_ids(meId)
    friendsIds = api.friends_ids(meId)
    for i in followerIds:
        try:
            user = api.get_user(i)
        except Exception as e:
            print(e)
        if user.protected == True and user.id not in friendsIds:
            print([user.screen_name, user.name])
            try:
                api.create_block(user.screen_name)
            except Exception as e:
                print(e)
```

### 余談
- 寝ぼけて`user.protected == "True"`にしてたら、Trueがstr扱いでboolじゃないのに10分くらい気が付かなくてキーボード破壊するところだった。
VPNとは何か ～IPsec-VPNとSSL-VPNについて～

# 初めに

VPN について勉強したことをまとめました。間違っている点がありましたらご指摘頂ければ幸いです。

# VPN について

**VPN（Virtual Private Network）**とは、インターネットを利用した仮想的なプライベートネットワークのことである。**専用線**（2地点間を直接結ぶプライベートネットワークのこと）との違いは、**インターネットを利用**する点である。VPNでは**暗号化や認証技術**を用いてセキュリティの確保を行う。VPN には主に **IPsec-VPN** と **SSL-VPN** がある。IPsec-VPN と SSL-VPN では暗号化の仕組みが異なる。IPsec-VPN は **IPsec** を利用した VPN 、SSL-VPN は **SSL/TLS** を利用した VPN である。

## IPsec-VPN の暗号化の仕組み

- 暗号化・認証情報の作成
  - データを暗号鍵で暗号化する。暗号化ヘッダを挿入する。
  - 暗号化データ + 暗号化ヘッダ + IP ヘッダ（ESP: Encapsulated Security Payload）に対して認証鍵で認証ヘッダ（AH: Authentication Header）を作成する。
  - 認証ヘッダを暗号化ヘッダと IP ヘッダの間に挿入する。
  - 作成したパケット（暗号化データ + 暗号化ヘッダ + 認証ヘッダ + IP ヘッダ） を送信する。

- 復号・認証情報のチェック
  - 受け取ったパケットから AH を除く。認証鍵を用いて ESP から新たに AH を作成し、除いた AH と比較する。
  - ESP から 暗号化ヘッダの情報に基づき暗号鍵を用いて復号する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/857733af-3203-3030-d6b7-b64b1c0c7e84.png)

## SSL-VPN の暗号化の仕組み

SSL/TLSでは、暗号化通信を行う前にハンドシェイクを行う。ハンドシェイクでは公開鍵暗号方式を使用して共通鍵を共有する。暗号化通信では、共通鍵暗号方式を利用する。

-  クライアントとサーバ間で暗号アルゴリズムとプロトコルバージョンを決定する
- サーバ証明書によってサーバの認証を行う
- そのセッションで利用するセッション鍵を共有する


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/7ad2091a-d9a6-5f31-8173-474fd5d4ce68.png)



# 用語

- VPN（Virtual Private Network）とは、インターネットを利用した仮想的なプライベートネットワークのこと。

- 専用線とは、2地点間を直接結ぶプライベートネットワークのこと。

- IPsec とは、ネットワーク層（OSI参照モデル）のプロトコルであり、IPパケット単位での暗号化・認証を提供する。

- SSL/TLS とは、セッション層（OSI参照モデル）のプロトコルであり、通信の暗号化、データ完全性の確保、サーバ（場合によりクライアント）の認証を行うことができる。

# 参考

- 6-1-応. 暗号化に関する知識

https://www.ipa.go.jp/files/000056109.pdf

- TLS 暗号設定ガイドライン Ver. 3.0.1

https://www.ipa.go.jp/security/ipg/documents/ipa-cryptrec-gl-3001-3.0.1.pdf

- マスタリング TCP/IP 入門編 第6版 

https://www.amazon.co.jp/%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0TCP-IP%E2%80%95%E5%85%A5%E9%96%80%E7%B7%A8%E2%80%95-%E7%AC%AC6%E7%89%88-%E4%BA%95%E4%B8%8A-%E7%9B%B4%E4%B9%9F/dp/4274224473/
基本技術者試験(CBT形式)を受験して


#はじめに
本年2月に基本情報技術者試験をCBT形式で受験にあたり、
通例の試験形式と変更になった事をまとめました。

#CBT形式とは？
 CBT(Computer Based Testing)の略証で、コンピュータを経由して受験をする仕組みである。
 マウス/キーボードで選択/記述し、内容を途中で変更が出来る
 全国各地にある試験センターに配置されているコンピュータ、また個人で所有しているコンピュータで受験が可能
 
#受験に必要なもの
 基本情報技術者試験の受験の場合、プロメトリックサイトで受験申込が必要
 
 ■プロメトリックとは？
  資格試験の運営のサポートする民営の企業
  IT関連や教育、企業、金融等の資格試験の運営/管理を行っている会社
 
 申込時に必要なもの
 ・プロメトリックID
　※初めてプロメトリックを経由して試験で受験する場合は、新規に取得する事
　　過去にプロメトリックを利用し、IDを持っている場合は、そのIDを利用する事
 
 ・受験費用
 　5,700円 (消費税込み) 通例の受験料と同じ
   
 ・受験日
　通例では4月、10月と固定されているが
 　<font color="Red">CBT形式の場合は、受験者が受験日を決める事が出来ます。</font>
  
　※参考までに受験申込ページを下記になります。
　　http://pf.prometric-jp.com/testlist/fe/online.html

#試験について
■問題の内容は？
　今回は午後問題のみ受験(免除試験)でしたので、午後問題のみ説明します。
　通例の午後問題では13問中7問解答する形式でしたが、
　今回からは、午後問題は11問中5問を解答する、という形式でした。
 
　・午後問題内容
　　✓問1:情報セキュリティ問題
　　✓問2～5:選択問題(2問選択)
　　✓問6:データ構造及びアルゴリズム問題
　　✓問7～11:プログラミング問題(1問選択)
　　　制限時間:150分
  
　・午後問題配点率
　　✓問1:20％
　　✓問2～5:各15％(=30％)
　　✓問6:25％
　　✓問7～11:25％
　　　合格基準:合計60％以上解答出来る事

■勉強方法
 <font color="Red">上記の配点率の様に、問6、及び問7からのプログラミング問題の配点率が高い為、
 その部分で得点を稼げる様に、対策をしました。</font>
 
 ✓試験2ヶ月前:
　データ構造及びアルゴリズム問題、プログラミング問題(私は「Java」を選択)の過去問を中心に解答
　問題の内容を図や一覧に表す等し、問題の内容を整理出来る様に対策をした
  
 ✓試験1ヶ月前:
　本番の試験を想定し、制限時間を設け、模擬試験を繰り返し実施
　解答出来ていなかった部分、及び他の選択肢が誤りとなる理由を含めて、勉強
  
 勉強して思った事は、
<font color="Red">午前問題の延長線上に午後問題があるので、午前問題を熟知した上で午後問題を勉強すると、理解度が高く効率良く吸収できました。</font>
 
#受験日当日
 私は試験センターで受験を選択し、当日は指定した試験センターで受験しました。
 予約した時間に試験センターで向かい、受付を済ました後に受験部屋に案内され、
 入室前に、手持ちの荷物をロッカーに預ける必要があります。
 <font color="Red">※財布、携帯も持込厳禁なので、カバンを持参する事をお勧めします。</font>
 またメモ用として、ペンが用紙が支給されるので、筆記用具の持参は不要でした。

#受験をして感じた事
 過去問題を解いて対策をしていたのですが、問の中にある小問題の数は過去問題と同じ印象でした。
 問の数が変化し、配点率が変化したのみで、過去問題を解くだけでも十分な対策になりました。
 
#最後に・・・
 受験方式が変わり、慣れない部分もあるかもしれませんが、
 過去問題を解き、用語の意味をとらえられる様になると、十分解答が出来ます。
 また独学で合格が難しいと考える場合は、「午前免除」を利用もおすすめします。
 「午前免除」を受ける場合、セミナー受講が必要になり、その分費用も掛かりますが、
 情報系の授業は受けた事はないが、絶対に合格したい、と思う人にはおすすめです。
 下記に私が「午前免除」を受けるにあたり利用した環境のURLを記載しますので、ご参照までに。
 
 ・独習ゼミ
  https://www.seplus.jp/dokushuzemi/fe/
「料金設定が月単位」「課金が秒単位」のAWS EBSの料金計算

# 概要

AWS EBSのストレージ/ボリュームのサイズに対する料金は**秒単位で課金**されます。料金は月額で設定されていますが、**月額÷その月の日数÷86,400秒（24時間）が1秒当たりの料金**になります。月によって1秒当たりの料金は少しだけ上下します。

# AWS EBSの料金設定と課金の単位

AWSには料金設定と課金単位の粒度が違うサービスがあります。例えば[EBSの料金](https://aws.amazon.com/jp/ebs/pricing/)は次のように「GB 月」と月額で設定されています（金額は2021年6月1日時点の東京リージョン）。

|ボリュームタイプ|料金|
|---|---|
|汎用SSD（gp3）-ストレージ|0.096USD/GB 月|
|汎用SSD（gp2）ボリューム|1か月にプロビジョニングされたストレージ1GBあたり0.12USD|

しかしEBSのデータ量に課金は、実は秒単位です（ただし最小で60秒分は課金されます）。次のように書かれています。

* gp3 ボリュームのプロビジョンドストレージ、プロビジョンド IOPS、およびプロビジョンドスループットは、1 秒ごとに課金されます (最小課金時間は 60 秒)。
* gp2 ボリュームのプロビジョニング済みストレージは、1 秒ごとに課金されます (最小課金時間は 60 秒)。

# 実際に適用される「秒単価」

この時、料金計算には「今月の1秒当たりの料金（秒単価）」が必要になります。秒単価は、その月の秒数によって、つまりその月の日数によって変わります。次のように書かれています。

> 例えば、お客様が **1 か月 30 日間の期間**に 12 時間 (43,200 秒) 2000 GB のボリュームをプロビジョニングしたとします。GB/月につき 0.08 USD 課金されるリージョンでは、そのボリュームに対して 2.667 USD (GB/月につき 0.08 USD x 2000 GB x 43,200 秒 / (86,400 秒/日 x **30 日/月**)) が課金されます。

0.096USD/GB 月で1,000GBを使用した時、次のような単価になります。

* 1月など**31日**までの場合 … (0.096USD/GB 月)÷（86,400秒/日 × **31日/月**）=0.000000035842USD/GB 秒
* 4月など**30日**までの場合 … (0.096USD/GB 月)÷（86,400秒/日 × **30日/月**）=0.000000037037USD/GB 秒 
* うるう年の2月で**29日**までの場合 … (0.096USD/GB 月)÷（86,400秒/日 × **29日/月**）=0.000000038314USD/GB 秒
* それ以外の2月で**28日**までの場合 … (0.096USD/GB 月)÷（86,400秒/日 × **28日/月**）=0.000000039683USD/GB 秒

月によって微妙に秒単価は上下します。

# 実際の料金計算

実際の料金計算は、秒単価を使うより次のような式で行う方がよいでしょう。

* サイズ × 月額 × 利用秒数 ÷ 86400 ÷ その月の日数

利用期間を秒数ではなく日数で計算するなら、もっと簡単です。

* サイズ × 月額 × 利用日数 ÷ その月の日数

利用しない期間はEBSボリュームを削除して利用開始時にデプロイするなど、一定サイズで利用時間を短くする場合の概算なら、月額に割合を掛けてしまう方が考えやすいことが多いです。

* 平日だけ（週**7日のうち5日**だけ）利用 … サイズ × 月額 × **5/7**
* 定時内だけ（1日**24時間のうち8時間**だけ）利用 … サイズ × 月額 × **8/24**

# まとめ

AWS EBSのストレージ/ボリュームのサイズに対する料金は**秒単位で課金**されます。料金は月額で設定されていますが、**月額÷その月の日数÷86,400秒（24時間）が1秒当たりの料金**になります。月によって1秒当たりの料金は少しだけ上下します。AWSの料金を考えるうえで、以下の二点は意識しておきたいと思いました。

* 時間課金の料金確認時には、**料金設定単位、課金単位、最小課金時間**の情報を揃える
    * 料金設定は月間（月額）だけど、課金単位は時間単位や秒単位などのサービスがある
    * 課金単位は秒だけど、最小課金時間が60秒などのサービスがある
* 日割り計算をする際は、当月の日数を意識する（1月なら31日、4月なら30日など）

料金設定単位、課金単位、最小課金時間が揃わないものとしては、例えば身近なものに[EC2のオンデマンドインスタンスの料金](https://aws.amazon.com/jp/ec2/pricing/on-demand/)があります。料金は時間単価で設定されています。課金も基本的には時間単位ですが、一部のLinuxインスタンスでは秒単位になります。この時、最小課金時間も別の数字になります。

> オンデマンド、リザーブド、スポット形式で起動したLinuxベースのインスタンスによるAmazon EC2の使用において、**請求が1秒単位 (最低60秒)** で行われるようになりました。Amazon EC2 Elastic GPUとAmazon EBSボリュームも、1時間ごとの請求モデルから1秒あたり (最低60秒) の請求モデルに変更されます。（略）時間単位による請求が課せられているMicrosoft WindowsやLinuxディストリビューションを実行しているインスタンスには、秒単位による請求が適用されません。  
>（[Amazon EC2 で 1 秒あたりの請求が可能に](https://aws.amazon.com/jp/about-aws/whats-new/2017/10/announcing-amazon-ec2-per-second-billing/)）

他のサービスについても、利用期間に対する料金を確認する際には、上記の3項目を見つけることを意識するとよさそうです。

# 参考

* [Amazon EBS の価格 – アマゾン ウェブ サービス](https://aws.amazon.com/jp/ebs/pricing/)
* [オンデマンドインスタンスの料金 - Amazon EC2 (仮想サーバー) | AWS](https://aws.amazon.com/jp/ec2/pricing/on-demand/)
* [Amazon EC2 で 1 秒あたりの請求が可能に](https://aws.amazon.com/jp/about-aws/whats-new/2017/10/announcing-amazon-ec2-per-second-billing/)
【第2章】Railsチュートリアルでユーザーの最初のマイクロポストが表示できない時にやったこと

[Railsチュートリアル第2章](https://railstutorial.jp/chapters/toy_app?version=6.0#cha-a_toy_app)の演習でユーザーの最初のマイクロポストを表示してみると、想定とは違った。

# やったこと① @user.micropostsを追加した
まず、show.html.erbに以下を追加した。

```
<p>
  <strong>First Post:</strong>
  <%= @user.microposts %>
</p>
```
するとエラーは発生しないものの、
First Post: #<Micropost::ActiveRecord_Associations_CollectionProxy:0x00007efe7ad4d670>
が表示された。

# やったこと② @user.microposts.firstを追加した
これではマイクロポストをすべて表示しようとしてしまうのだろうと思い、以下に変更

```
<p>
  <strong>First Post:</strong>
  <%= @user.microposts.first %>
</p>
```

すると、
First Post: #<Micropost:0x00007efe7ae95e88>
となった。

# やったこと③ @user.microposts.first.contentを追加した
②で合っているのでは…？と思っていたので、正解/不正解の判断が付かず、検索するといくつも解答例の記事が存在した。
https://kojimanotech.com/2018/06/17/63/ を参考に以下に修正。

```
<p>
  <strong>First Post:</strong>
  <%= @user.microposts.first.content %>
</p>
```
画面を開くと、想定したマイクロポストが表示された。
First Post: First micropost!

②の状態では最初のマイクロポストのidやuser_idも含まれるということか。

#まとめ
やったこと①②③の流れで解決できた。
[GitHub] Deprecation Noticeの対応でhttpsをsshに変更する

# この記事の目的

- [GitHub] Deprecation Noticeとgithubからメールが来た
- 内容的にはhttpsでremoteの接続をしているが近い将来廃止になるのでsshに変更してくれとのこと
- 上記の対応をまとめていく

# sshとは

SSHとは？仕組みとSSHサーバーの設定をわかりやすく解説します！
https://www.kagoya.jp/howto/rentalserver/ssh/

上記記事がわかりやすかった。ちゃんと誰かわかっている端末からのみ接続を許可するために端末側の暗号と突き合わせて認証が通れば初めて接続を許可するというもの。

githubは今までhttpsだったら許す形でこれは通信内容を保護はできるが通信する相手が誰か認証するのは強くないのでここをセキュリティ強化しようとしている。

## ~/.ssh/known_hostsとは

> 一度接続したことのあるサーバのSSHサーバ証明書は、クライアント側のホームディレクトリの中、~/.ssh/known_hostsに格納されます。

https://qiita.com/suzuki-koya/items/af4b511d40b6362da60a

# sshを作成

お前らのSSH Keysの作り方は間違っている
https://qiita.com/suthio/items/2760e4cff0e185fe2db9

```
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
```

your_email@example.comはgithubに登録しているものを使った

```
Enter file in which to save the key (/Users/you/.ssh/id_rsa): [Press enter]
```

enterでよし

```
Enter passphrase (empty for no passphrase): [Type a passphrase]
```

passwordを入力

# githubへの登録

https://qiita.com/suthio/items/2760e4cff0e185fe2db9#github%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%ABssh-key%E3%81%AE%E7%99%BB%E9%8C%B2

上記が詳しい
累積和を解説

#はじめに
　本記事では、競技プログラミング初心者向けに累積和の使い方を解説します。累積和はABCのC問題くらいから必要になる知識なので、AtCoderを始めた人はぜひ知っておきましょう。
　この記事では前半で累積和の考え方について説明した後、後半では[ABC037C問題](https://atcoder.jp/contests/abc037/tasks/abc037_c)を例題に実際にコードを書いて累積和を使ってみようと思います。



#累積和を使ってできること
　長さ$n$の数列$ a_0, a_1, a_2, \ldots, a_{n-1} $のある区間の和を求めたい時どれくらいの回数の足し算が必要になるでしょうか。例えば、$a_3$から$a_{10}$までの和（ただし$10<n$）を求める場合$7$回の足し算が必要です。一般的に、$a_s$から$a_t$までの和（ただし$s \leqq t < n$）を求めるためには、$t-s$回の足し算が必要になります。累積和を使用すると、適切な前処理を行うことで数列の任意の区間の和を定数時間で（つまり非常に高速で）求めることができます。

# 累積和の考え方
## 前処理
　数列$ a_0, a_1, a_2, \ldots, a_{n-1} $の任意の区間の和を高速で求めるため、数列$ b_0, b_1, b_2, \ldots, b_{n-1}, b_n $を次のように定義します。

```math
\begin{align}
b_0 &= 0 \\
b_i &= \sum_{j=0}^{i-1} a_j \ (i=1,2,3,\cdots, n-1,n) \\
&= b_{i-1} + a_{i-1}  \\
\end{align}
```

　数列$\lbrace b_i \rbrace$の値を求めるために必要な足し算の回数は$n$回です。

## 区間和の計算
　$\lbrace b_i \rbrace$を用いて$\lbrace a_i \rbrace$の$[s,t)$における和を求めます。ただし$[s,t)$は、$s$以上$t$未満の区間を表します。

```math
\begin{align}
\sum_{i=s}^{t-1}a_i &= \sum_{i=0}^{t-1}a_i - \sum_{i=0}^{s-1}a_i \\
&= b_t - b_s \\
\end{align}
```

　一回の引き算で$\sum_{i=s}^{t-1}a_i$の値が求まるため非常に高速です。

# 使用例
[ABC037C問題](https://atcoder.jp/contests/abc037/tasks/abc037_c)を累積和を使って解きます。

```C++:program.cpp
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

typedef long long LL;
typedef vector<LL> VLL;

int main(void) {
	//入力
	LL n, k;
	cin >> n >> k;
	VLL a(n);
	for (LL i = 0; i < n; i++) {
		cin >> a[i];
	}

	//累積和の前処理
	//b[i] = a[0] + a[1] + … + a[i-1]
	VLL b;
	b.push_back(0);
	for (LL i = 0; i < n; i++) {
		b.push_back(b[i] + a[i]);
	}

	//出力する値を計算
	LL sum = 0;
	for (LL i = 0; i < n - k + 1; i++) {
		sum += b[i + k] - b[i];
	}

	//出力
	cout << sum << endl;

	return 0;
}
```

# 最後に
　分かりにくい箇所も多々あるかと思いますので質問や提案等を頂ければできる限り改善していきたいと思っています。ご覧いただきありがとうございました。
git push -u origin masterした際のエラーの対処法

##エラーの対処
先日、GitHubにpushしようとすると、以下のようなエラーが出現。

```
$git push -u origin master

git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
```

####翻訳してみると、、

```Permission denied (publickey)```
→許可が拒否されました (公開鍵)

```fatal: Could not read from remote repository```
→致命的: リモート リポジトリから読み取れませんでした

```Please make sure you have the correct access rights
and the repository exists.```
正しいアクセス権を持っていることを確認してください
そしてリポジトリが存在します

調べていくと、**SSH接続**という単語が出てくる。

###SSH接続とは
SSHとは「Secure Shell」の略で、ネットワークに接続された機器を遠隔操作し、管理するための手段。
各種サーバー機器は、ほとんどの場合、操作をする人から離れた場所にある。そのため、この操作をする人だけが安全にインターネット経由で接続できる手段が必要になる。

GitHubにSSH接続する為には、公開鍵と秘密鍵が必要になる。

###公開鍵
サーバー側に持たせておく鍵。
作ったときには「id_rsa.pub」という名前で作成される。
###秘密鍵
クライアント側で保有しておく鍵。
誰にも渡してはいけない。

##公開鍵と秘密鍵の生成
まずは、公開鍵と秘密鍵のペアの作成

```
$cd ~/.ssh
```

ファイルが何もないか確認

```
$ls
```

何もないことが確認できたら、鍵の生成

```
$ssh-keygen -t rsa
```

何か聞かれたら3回エンターを押せば、
```id_rsa（秘密鍵）```と```id_rsa.pub（公開鍵）```の2つの鍵が生成されます。
既にid_rsaが存在する人は上書きされてしまうので注意です。


id_rsa.pub（公開鍵）のファイルの中身をコピー

```
$ cat ~/.ssh/id_rsa.pub
```

##公開鍵をGitHubにアップ
GitHubのページに行き、右上をクリック後「settings」をクリック。
Your Profile画面に行くので、「SSH and GPG keys」をクリック。
New SSH keyをクリックし、公開鍵をアップ。


「title」に公開鍵名、「key」に公開鍵を入れる。
<img src='https://i.gyazo.com/9b3c4462f514525f498bbb10e133eb1b.png'>

###接続を確かめる

```
$ ssh -T git@github.com
```

Hi (account名)! You've successfully authenticated, but GitHub does not provide shell access.
上記のような文言が返ってきたら接続完了

再びGitHubにプッシュし、完了。

##参考資料
https://qiita.com/shizuma/items/2b2f873a0034839e47ce
[Laravel]フォームリクエストでバリデーション

フォームリクエストを活用したバリデーションの仕方。
一度実装していたのに忘れていて時間食ったのでまとめときます。
自分用に書いてるところあるので雑だったらすみません。(笑)

#Requestを作る
```
php artisan make:request PostRequest
```

#PostRequestの中身
```laravel:App/Http/Requests/PoseRequest
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class PostRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'user_id' => 'required|integer',
            'title' => 'required|string|max:30',
            'content' => 'string',
        ];
    }
}

```

authorizeのreturnがデフォルトではfalseになっていますが、trueに変えておきます。
ここがfalseのままだとコントローラーにリクエストが通りません。
rulesの部分にバリデーションルールを設定していきます。

#PoseControllerの中身(storeアクション)

PostControllerからStoreを抜粋しました。

```larave:App/Http/Controllers/PostController
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Post;
use Auth;
use App\Http\Requests\ReviewRequest;

 〜省略〜

/**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(PostRequest $request)
    {
        $post = new Post();
        $post->fill($request->all())->save();
        return redirect()->route('post.show', ['post'=>$post]);
    }
```

use App\Http\Requests\ReviewRequest;の部分で先ほど作成したリクエストを読み込んでます。
storeアクションの引数にPostRequestを使用することでStoreアクション宛のリクエストがPostRequestを通ってくるので、そこでバリデーションが適応されます。

今回はデータの保存にfillを使用しているのでPostModelも編集しておきます。

#PostModelの中身

```laravel:App/Models/PostModel
〜省略〜

class Review extends Model
{
    use HasFactory;

    〜省略〜

    protected $fillable = [
        'user_id',
        'title',
        'comment',
　　];
}
```

fillableで指定した値のみがDBに保存することを許可します。
この設定をしないとfillを使用する場合はなにも保存できなくなるので。


以上でRequestを使用したバリデーションが使用できるはずです。

#参考記事

https://qiita.com/n_mogi/items/57a946205df2a69889c2

https://qiita.com/kiwatchi1991/items/fd0e9cfae0e1bdcf1121
valid_email2というgemについて

# valid_email2とは
メールの正規表現を提供するgemのことです。ドメインに MX レコードがあることをさらに検証します。

# インストール方法
Gemfileに以下を記載し、`budle install`を実行する。

```ruby
gem  "valid_email2"
```

# 基本的な使い方
有効なメールアドレスであることを確認する

```ruby
validates :email, presence: true, 'valid_email_2/email': true
```

## 用途別使い方

### ドメインに MXレコードまたはAレコードがあることを確認したい場合

```ruby
validates :email, 'valid_email_2/email': { mx: true }

# MXレコードがあることを厳密に検証する場合
validates :email, 'valid_email_2/email': { strict_mx: true }
```

### ドメインが使い捨て電子メールではないことを確認したい場合

```ruby
validates :email, 'valid_email_2/email': { disposable_domain: true }
```

### 電子メールがサブアドレス指定されていないことを確認したい場合

```ruby
validates :email, 'valid_email_2/email': {  disallow_subaddressing : true  }
```

### 電子メールの @ の前にドットが含まれていないことを確認したい場合

```ruby
validates :email, 'valid_email_2/email': {  disallow_dotted : true  }
```

### 独自のカスタムメッセージの作成をしたい場合

```ruby
validates :email, 'valid_email_2/email': {  message : "有効なメールではありません"  }
```

### 複数のアドレスをコンマで区切って許可したい場合

```ruby
validates :email, 'valid_email_2/email': { multiple: true }
```

### モデル以外での使用例

```ruby
address = ValidEmail2::Address.new("sample@gmail.com")
address.valid? => true
address.disposable? => false
address.valid_mx? => true
address.valid_strict_mx? => true
address.subaddressed? => false
```

# 参考
[公式ドキュメント]
(https://github.com/micke/valid_email2)
Symbol-ETL Part.3 Aggregate Transaction編

複数のTransactionを一つにまとめるAggregate Transaction。

#Transaction
```json
{
	"meta": {
		"height": "663",
		"hash": "91B4DEB41A401D124A8B2C5643ABE32F99B92096FA2DB548F6DF7FC06D1490A0",
		"merkleComponentHash": "91B4DEB41A401D124A8B2C5643ABE32F99B92096FA2DB548F6DF7FC06D1490A0",
		"index": 11
	},
	"transaction": {
		"size": 432,
		"signature": "A8677FE81F829929C54EEEA1A3B45689214C0A45DF61BE0BEE0486F2954EED5A17993FDF80BB7AC5C76DD5520C039D1C281214C5CC64481DC9568F1D8C058904",
		"signerPublicKey": "7CF5D7E51339EB03C35321421FAEABC49E78393D04257B9E019E1EBC3CEEFD3B",
		"version": 1,
		"network": 104,
		"type": 16705,
		"maxFee": "1000000",
		"deadline": "111808702",
		"transactionsHash": "7BA5DB18377F4ACBF7DEE333FD1F70B0BE30695F2E3C04410A50A20CA807B6EC",
		"cosignatures": [],
		"transactions": [
			{
				"meta": {
					"height": "663",
					"aggregateHash": "91B4DEB41A401D124A8B2C5643ABE32F99B92096FA2DB548F6DF7FC06D1490A0",
					"aggregateId": "60B778CEEE046621FC1CB520",
					"index": 0
				},
				"transaction": {
					"signerPublicKey": "7CF5D7E51339EB03C35321421FAEABC49E78393D04257B9E019E1EBC3CEEFD3B",
					"version": 1,
					"network": 104,
					"type": 16716,
					"linkedPublicKey": "C6F65B8ECF5CEBC3E8EF21DF99EEBCF5F5C5E57891B9F2EF447648BFF24EDBDE",
					"linkAction": 1
				},
				"id": "60B778CEEE046621FC1CB521"
			},
			{
				"meta": {
					"height": "663",
					"aggregateHash": "91B4DEB41A401D124A8B2C5643ABE32F99B92096FA2DB548F6DF7FC06D1490A0",
					"aggregateId": "60B778CEEE046621FC1CB520",
					"index": 1
				},
				"transaction": {
					"signerPublicKey": "7CF5D7E51339EB03C35321421FAEABC49E78393D04257B9E019E1EBC3CEEFD3B",
					"version": 1,
					"network": 104,
					"type": 16963,
					"linkedPublicKey": "D7673EE552EF6152260EB01F28DDF2E816F6E0873CBD2E202F1F9535284FAB03",
					"linkAction": 1
				},
				"id": "60B778CEEE046621FC1CB522"
			},
			{
				"meta": {
					"height": "663",
					"aggregateHash": "91B4DEB41A401D124A8B2C5643ABE32F99B92096FA2DB548F6DF7FC06D1490A0",
					"aggregateId": "60B778CEEE046621FC1CB520",
					"index": 2
				},
				"transaction": {
					"signerPublicKey": "7CF5D7E51339EB03C35321421FAEABC49E78393D04257B9E019E1EBC3CEEFD3B",
					"version": 1,
					"network": 104,
					"type": 16972,
					"linkedPublicKey": "B48D33CF69F57DB59889062B6DEF057F5FBD54AF0474D8FAFC89E6BCDB81E9FB",
					"linkAction": 1
				},
				"id": "60B778CEEE046621FC1CB523"
			}
		]
	},
	"id": "60B778CEEE046621FC1CB520"
}
```

##項目の説明
| field | description |
|:-:|:-:|:-:|
| hash | これがInner Transactionも含んだAggregate TransactionのHash。これをキーにInnner Transactionとの紐付けが出来る。 |
| signerPublicKey | Aggregate Transactionに対する署名者のPublic Key |
| type  |  16705は0x4141なのでAggregateCompleteTransaction |
| transactionsHash  | これはこのWrapper Transaction自身のHash。 |
|  cosignatures | inner transactionに対する署名。このサンプルの場合、一人で全てやっているため空欄。  |
|  transactions | innner transaction  |
|   |   | 

#Recipient
Inner Transactionの種類によっては発生することはあるものの、1Aggregate Transactionだから必ず発生するようなRecipinetはなし。
VirtualBoxを使ってMacにCentOS8の仮想環境を構築する

# 概要
- MacにCentOS8の仮想環境を構築する
- 環境構築にVirtualBoxを活用する

# 目次
- 目的
- 背景
- 参考
- ハマりポイント
- 解決方法

# 目的
- サーバー向けOS(Linux)の学習
- 2021/06/06時点での最新情報を共有

# 背景
- 自分がハマったポイント(後述）に沿った記事がなかったため、寄稿。

# 参考ページ
大まかな手順は下記を参照した
https://zenn.dev/yuta88/articles/20b3fa7d4dd0cff391ff

# ハマリポイント
- ダウンロードしたはずのCentOSファイルが、起動ディスク選択時に出てこなかった（ad-hoc.visoしか出てこない)
　※画像参照。フォルダ選択しても出てこない

![ハマりポイント.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/761780/a10ba8b3-9ef7-5810-2173-f1c5500ac85d.jpeg)

# 解決方法
- VirtualBoxを起動後、「設定」→コントローラー:IDE→ディスクマークを選択したら出てきた

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/761780/159bf068-5607-935b-3176-8a7952e83cc2.png)
![Untitled (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/761780/0046e9e3-8c8e-df23-a23e-eb9c421ee9eb.png)

Linux超初心者の自分への備忘録と、同じことでハマった方への一助になりますと幸いです。
OS初学者の学習記録 〜1. OSの概要〜

# システムの階層(上にいくほど高レイヤー)
* アプリケーションプログラム
* ユーザーインターフェース (GUI, CUI)
* OS
* ハードウェア


# 2つの動作モード(@プロセッサ)

### カーネルモード
* OS以下はこのモードで動作
* すべてのハードウェアにアクセス可能
* すべての命令を実行可能

### ユーザーモード
* ユーザーインターフェース以上はこのモードで動作
* 他のプログラムに影響が出る命令が禁じられている


# OSの2つの役割
### 仮想マシンを実現
一連のハードウェアに対する処理をパッケージ化して、仮想的なハードウェアを提供。

メリット
* ハードウェアの詳細な状況を意識せずにプログラムを作成できる
* パッケージ化した一連の手続きを抽象化できる (例：ファイル操作)

### リソースマネジメント
1つのプログラムだけを実行するだけでは、利用されないリソースが出る。
プログラム実行を効率化するために、複数のプログラムを同時実行し、OSがその取りまとめを行う。
(=資源の多重化)

# ハードウェアの概要

### プロセッサ(CPU)
* レジスタ(記憶素子)
* デコードユニット(命令解読機)
* 実行回路

### メモリ
<dl>
  <dt>　階層</dt>
  <dd>レジスタ</dd>
  <dd>キャッシュ</dd>
  <dd>メインメモリ</dd>
  <dd>ハードディスク</dd>
  <dt> 種類</dt>
  <dd>HDD</dd>
  <dd>SSD</dd>
  <dd>DVD-R</dd>
  <dd>etc..</dd>
</dl>

### 入出力デバイス
OSは入出力デバイスも管理しないといけない。
ただ、通常デバイス制御命令は非常に煩雑になっている事が多い、、
→「コントローラー」というOSをデバイスの中間的なインターフェースがムズいところは吸収してくれる。デバイス制御のためのソフトウェアを「デバイスドライバ」という


### バス
プロセット、メモリ、その他の入出力デバイスが、お互いにデータのやり取りをするために必要な共通の信号線。

プロセッサとキャッシュ、プロセッサとメモリの間にはそれぞれ専用バスが使用されている。

入出力デバイスでいえば、
* USB (universal serial bus)
* IEEE1394
* Thunderbolt
とかがあるみたい。

# OSの基本要素

### プロセス
* プログラムの実行単位。
* 制御に必要な情報を取りまとめるために必要。

### メモリ空間
* お互いのプログラムは、独立したメモリ空間を割り当てる必要がある
* 仮想的なメモリ空間を提供することで、自身のプログラムに必要なデータがどこにあるのかを都度物理的なアドレスで確認しなくても良くなる

### ファイル(ファイルシステム)
* ファイルをひとまとめにしたディレクトリという概念で構造化
* このようにファイルとディレクトリという概念を使って、データの構造化を実現する仕組みを「ファイルシステム」という

### 入出力
＊ 入出力デバイスの管理もOSが担当
* 複数ユーザーが使用するときには調停を担当

### 保護機能
* マルチユーザーシステムにおいての、「権限」の仕組み
* 「権限」はデータ閲覧、プログラムの実行などに対して設定される

# システムコール
OSが用意したインターフェース。(OSが管理する資源をユーザープログラムから使用際に使用)
プログラム言語の関数のような形で定義されている。

### ユーザープログラムの「関数」との違い
ユーザープログラムの関数は、ハードウェアの目線から見れば「実行する位置アドレスの変更」にすぎない。

それに対して、システムコールが呼ばれる際には、ユーザープログラムはその処理の状況を保存して終了する。
その後、システムコールハンドラ(システムコールのプログラム)がプロセッサをカーネルモードに変更してから、処理を実行する。

### 性質
システムコールは、基本的に複数のプログラムから同時に呼び出すことができない。
→これにより、プログラム同士の干渉が起こるのを防ぐ

### システムコールの仕様について
システムコールとして用意される処理の種類は、OSそのものの機能に関連するものなので大体同じ。
↓
しかし細かい仕様は、OSの設計思想によって異なる。
システムコールが異なると、実装に影響が出てしまう。
↓
仕様を共通化する動きがある。代表的なものは、「POSIX」。


# 言語と単位

### 使用されている言語
ハードウェアに近い処理は、一部アセンブラで書かれていることもあるが、だいたいC言語が使われている。

### 単位
* bps (bit per second)：通信速度
* rpm(revolution per minute)：ディスクの1分あたりの回転数
とか。
テストの平均点の出し方

#平均点を出す方法

##学校の各教科のテスト点数を変数化する
国語：55点
数学：72点
理科：89点
社会：63点
英語：75点
であったとする。
これらの点数を変数化してみる。

```
japanese_score = 55
math_acore = 72
science_score = 89
society_score = 63
english_score = 75
```

##平均点を変数化する
各教科の点数を変数化したので、今度は平均点を変数化する。

```
average_score = (japanese_score + math_acore + science_score + society_score + english_score) / 5
```

##平均点をターミナルに出力する
```
puts "テストの平均点は、#{average_score}です。"
```

##まとめ
このように各情報を変数化することで、コードが見やすくなる。
また、点数の変更があった場合、コードの修正も少なく済む。
VSCodeの拡張機能と設定を開発メンバーで共有する方法


## はじめに

こんにちわ、dtakkiyです!

今回は、VSCodeの拡張機能と設定を開発メンバーで共有する方法を紹介します。
この方法を使うと、開発にVSCodeを使用する際、開発メンバーにインストールして欲しい拡張機能や設定を簡単に共有することができます。

設定を共有することで、新人さんなど新たにプロジェクトに参画する方もスムーズに開発に着手することが可能となります。

## 設定方法

設定は簡単です。
プロジェクトのルートに`.vscode`フォルダを作成し、gitなどで共有します。

最終的に以下のようなフォルダ構成になります。
`extensions.json`に拡張機能、`settings.json`に設定内容を記述します。

![ 2021-06-05 21.47.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166484/4844e56f-55fe-2065-94df-fb09cff7a611.png)

### .vscodeフォルダの作成

1. まず.vscodeフォルダをプロジェクトのルートに作成しましょう。

```bash

$ mkdir .vscode

```

### 拡張機能

1. `.vscode`フォルダ下に`extensions.json`ファイルを作成します。

```bash

$ touch extensions.json

```

2 . 作成したjsonファイルに`recommendations`キーを追加し、オススメしたい拡張機能名を記述します。

下記の例ではstyleのlintと全角スペースを可視化する２つの拡張機能を登録しています。

```json

{
  "recommendations": [
    "stylelint.vscode-stylelint",
    "mosapride.zenkaku"            
  ]
}

```

登録する拡張機能名は、各拡張機能のプレビュー画面で確認することができます。
画像の赤丸の箇所が拡張名となります。

![xxxxx.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166484/84a88568-741c-3a36-ebe8-33321bb92346.jpeg)


### 拡張機能のインストール

ただ拡張機能は、あくまで`recommendations`（推奨事項）なので、各々の開発者の環境に強制的あるいは自動的にインストールされるわけではありません。
開発者がプロジェクトフォルダをVSCodeで開いた際、画面右下にインストールを促すポップアップ表示がされます。

![qqqqqqq.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166484/c7c45e40-3258-f6bc-fedc-29d448523709.png)

もし登録された拡張機能がインストール済みの場合は、ポップアップは表示されません。

詳細については[公式ページ](https://code.visualstudio.com/docs/editor/extension-marketplace#_workspace-recommended-extensions)を参照下さい。

### 設定の共有

ここでは設定の共有について説明します。
設定を共有することで

- 改行コードの指定
- 行番号の表示
- ミニマップの表示
- ハイライト表示
- ファイルの自動保存
- フォーマッターの指定
- タブサイズ

などが行えるようになります。

VSCodeの設定項目は多岐に渡るため、詳細については、[公式ページ](https://code.visualstudio.com/docs/getstarted/settings)を参照下さい。


1. `.vscode`フォルダ下に`settings.json`ファイルを作成します。

```bash

$ touch settings.json

```

2 . 作成した`settings.json`ファイルに設定項目を記述します。

例えばタブサイズやハイライト表示、折返しの設定を共有する場合は以下のように記述します。

```json

{
  "[scss]": {
    "editor.tabSize": 4,               //scssのtabのサイズを4に
  },
  "editor.renderLineHighlight": "all", //現在の行をハイライト表示
  "editor.wordWrap": "on",             //テキストを折り返し設定に
}

```


### gitへの登録

最後に作成した設定ファイルをgitなどに登録し、開発メンバーと共有します。

```bash

$ git add .vscode
$ git commit -m "feat: VSCode設定を共有"
$ git push origin HEAD

```

以後、開発メンバーがVSCodeを開くと拡張機能と設定が利用できるようになります。

## おわりに

いかがだったでしょうか？
おすすめの拡張機能や設定を開発メンバーと共有し、開発効率をあげていきましょう！
【初心者でもわかる】疑似要素でアイコンを付けたらテキストと微妙にズレる時の対処法

#どうも7noteです。疑似要素でテキストの横にアイコンを付けると微妙に位置がズレてしまう場合の対処法について解説

このように、テキストの前にアイコンを付けると微妙にズレてしまう場合に、いい感じに上下中央にもっていく方法を解説します。

**「ちょっとズレてしまった例」**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/4765fbf3-b28a-c717-859a-c87816dbb160.png)


## ソース

```index.html
<p>テキスト</p>
```

```style.css
p::before {
  content: '';
  width: 16px;
  height: 16px;
  background: url(icon.png) no-repeat;
  margin-right: 10px;
  display: inline-block;
  transform: translateY(3px); /* 上下方向の位置を微調整する */
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/ffefec5e-ff37-8f1b-003d-c883c070e55d.png)


## 解説

上下方向でズレがおこるので、`transform: translateY()`を使い、上下の位置を調整します。
それだけですね、簡単です。

## まとめ

position指定で位置を相対位置に指定する方法もありますが、単純にテキストの前にアイコンを設置するだけであれば、beforeを使った今回の方法が一番簡単かなと思います。
imgにして画像で設置する方法もありますが、個人的には疑似要素を使ったこの手法がオススメです。htmlがスッキリするので。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
最低限知っておくと良さそうなLinuxのコマンドとコントロールキー

# コマンドとオプション
## pwd
カントディレクトリを表示できます。

```
$ pwd
/home/linux
```

## ls
ディレクトリ内のファイルを表示できます。

```
$ ls
bin dev home lib64 mnt proc run
sys usr...
```
-lオブションをつけると、ファイル属性など詳細な情報を同時に表示できます。
-aオプションをつけると、隠しファイルも含めて表示されます。

## cd
カントディレクトリを変更できます。

```
$ cd /bin
```

# ファイル操作
## mkdir 
ディレクトリを作成できます。

```
$ mkdir workspace
```

親ディレクトリも含めてディレクトリを一気に作成できます。

```
$ mkdir -p workspace/practice/practice01
```

## touch
ファイルを作成できます。

```
$ touch test
```

## cat
ファイルを表示できます。

```
$ cat test
```

## rm
ファイルを削除できます。

```
$ rm testdir
```

ディレクトリを削除できます。

```
$ rm -r testdir
```

## rmdir
空のディレクトリを削除できます。

```
$ rmdir test
```

## cp
ファイルをコピーできます。
※file1をfile2という名前でコピーできます。

```
$ cp file1 file2
```

## mv
ファイルを移動する。
※fileというファイルをdirというディレクトリに移動できます。

```
$ mv file dir
```

# 補完機能
補完機能は、Tabキーを押すことで使用できます。
複数の候補がある場合は、2回Tabキーを押すとコマンドのリストが表示されます。

# コントロールキー

## Ctrl + a
先頭に移動できます。

## Ctr + e
行末に移動できます。

## Ctr + b
後方に一文字分移動できます。

## Ctr + f
前方に一文字分移動できます。

## Ctr + l
プロンプトの画面消去ができます。
[Rails]field_for 配下の各オブジェクトを取得する方法

#課題
fields_for配下の各オブジェクトを取得する方法を知らなかったのでメモ。

```erb:
<%= form_with model: @user, local: true do |f| %>
  <%= f.text_field :name %>

  <%= f.fields_for :sales do |ff| %>
    <%= ff.text_field :amount, class: 'form-control' %>
  <% end %>
  <%= submit_tag 'submit' %>
<% end %>
```
上記のようにネストされたフォームで、各子レコードを取得したい。

#結論
ff.object で取れる

```ruby:コンソールで検証
irb(main):001:0> ff.object
=> #<Sale id: 1, amount: 1000 >
```
#参考情報
fields_forの上手な使い方
https://qiita.com/kouuuki/items/5daf2b5f34273d8457f7
Amplify +GraphQL+DynamoDBでリストの並びを時系列順にする

#はじめに

私はAWSのサービスで一番最初に触ったのがAmplifyでした。
AWSのサービスを何も知らなかったのでドキュメントを読みつつ実際に手を動かし、トライアンドエラーしたことでAmplifyとAWSについて少しは理解ができたかなと思います。

その中で振り返ってみて個人的にかなり苦戦した、データを時系列順で取得する方法について、記事にしたいと思います。
※ちなみに以前も同じような内容の記事を書きました。その時は曖昧な理解でしたので、理解が深まったこのタイミングで改めて記事にしています。

私が把握している時系列順にデータを取得する方法は以下の二つです。
①GraphQLのスキーマ定義時にsearchableを使う
②GraphQLのスキーマ定義時にkeyを使う

①はElasticsearchを使用するので②に比べて費用がかかってしまいます。
なので今回は②の方法にします。


#方法

上でも記載しましたが今回はGraphQLのスキーマ定義時にkeyを使う方法でやってみたいと思います。
と言ってもかなり簡単に実装出来ます。

```
type Todo 
 @model
 @key(name: "SortByTime", fields:["type", "createdAt"], queryField: "listTodosSortedByTime" )
{
    id: ID! 
    name: String!
    type: String!
  //このtypeに固定値をいれる。
    content: String!
    updatedAt: AWSDateTime 
    createdAt: AWSDateTime 
}
```

↑のようにスキーマ定義時にkeyを持たせるだけです。
nameセカンダリインデックスを指定可能。
fieldはパーテンションキーやソートキーを指定可能。
queryFieldを設定することで、セカンダリインデックスを使ったクエリでの検索が可能。

今回の例ではtype（filedsの第一引数)をパーテンションキーに指定しています。
なので、typeに常に同じ値を入れるようにすれば、リスト全体が範囲になります。
そのリスト全体の範囲に対してcreatedAt（filedsの第二引数)でソートすることが可能です。

あとはqueryで呼び出す際に下記のようにすれば、リスト全体を時系列順で取得することができます。

```
  API.graphql(graphqlOperation(listPostsSortedByTimestamp, {
    type: "todo",
//今回の例では常にtypeにはtodoを入れる
    sortDirection: 'DESC',
//降順
    limit: 20, 
//取得件数（デフォルトは10件）
    nextToken: nextToken,
  }));
```

↑の例ではtypeにtodoを入れていますが、そこはお好みの値がOKです。
また、typeではなくownerをfiledsの第一引数にすれば、投稿した人（オーナー）を時系列順で取得できます。


#最後に
このようにまとめてみると何故苦戦したのか分からない程、簡単に実装できたなと思います。
もし他にも方法があれば教えていただけると幸いです！