OmniAICreator/Qiita-1.07M huggingface dataset:
Bootstrapざっくり入門 - 3

## 列の自動レイアウト

### 等幅カラム
行内のカラムを等幅にするには、colクラスを使用するのがもっとも簡単です。
1行を2列にしたい場合は、colクラスを指定した要素を2つ、3列にしたい場合は3つ配置します。
colクラスを使用した場合は、1行に入る各カラムは自動的に等幅でレイアウトされます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310302/b553e7af-062b-4616-7e2a-8852992704ec.png" width=100%>

```html
<div class="container">
    <div class="row"><!-- row : 1行目 -->
        <div class="col">1列目</div><!-- col : 等幅カラム -->
        <div class="col">2列目</div><!-- col : 等幅カラム -->
    </div>
    <div class="row"><!-- row : 2行目 -->
        <div class="col">1列目</div><!-- col : 等幅カラム -->
        <div class="col">2列目</div><!-- col : 等幅カラム -->
        <div class="col">3列目</div><!-- col : 等幅カラム -->
    </div>
</div>
```

### 指定幅カラム
カラムの幅を指定するには、col-*クラス(「\*」には1~12までの数値が入ります)を使用します。
*に入る数字は、合計12(グリッド12列分のカラム)になるように、使用したい列分の数を指定します。
等幅カラムにしたい場合は、colクラスを指定した要素を3つ配置する代わりにcol-4クラスを指定した要素を3つ配置しても、4列カラム×3=12カラム列分となり、3つの等幅カラムになります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310302/cb837e88-f158-c459-3c9a-41a4a0e0c255.png" width=100%>

```html
<!-- 1列カラム × 12 = 12列分 -->
<div class="container"><!-- container : 箱 -->
    <div class="row"><!-- row : 行 -->
        <div class="col-1">co-1</div><!-- col-1 : 1列分のカラム -->
        <div class="col-1">co-1</div><!-- col-1 : 1列分のカラム -->
        <div class="col-1">co-1</div><!-- col-1 : 1列分のカラム -->
        <div class="col-1">co-1</div><!-- col-1 : 1列分のカラム -->
        <div class="col-1">co-1</div><!-- col-1 : 1列分のカラム -->
        <div class="col-1">co-1</div><!-- col-1 : 1列分のカラム -->
        <div class="col-1">co-1</div><!-- col-1 : 1列分のカラム -->
        <div class="col-1">co-1</div><!-- col-1 : 1列分のカラム -->
        <div class="col-1">co-1</div><!-- col-1 : 1列分のカラム -->
        <div class="col-1">co-1</div><!-- col-1 : 1列分のカラム -->
        <div class="col-1">co-1</div><!-- col-1 : 1列分のカラム -->
        <div class="col-1">co-1</div><!-- col-1 : 1列分のカラム -->
    </div>
</div>
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310302/8da8f5e3-391d-3597-2f75-5f1063fb6042.png" width=100%>

```html
<!-- 2列カラム + 4列カラム + 6列カラム = 12列分 -->
<div class="container"><!-- container : 箱 -->
    <div class="row"><!-- row : 行 -->
        <div class="col-2">co-2</div><!-- col-2 : 2列分のカラム -->
        <div class="col-4">co-4</div><!-- col-4 : 4列分のカラム -->
        <div class="col-6">co-6</div><!-- col-6 : 6列分のカラム -->
    </div>
</div>
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310302/73433fa2-d33a-5331-b147-367ced4ba55e.png" width=100%>

```html
<!-- 5列カラム + 7列カラム = 12列分 -->
<div class="container"><!-- container : 箱 -->
    <div class="row"><!-- row : 行 -->
        <div class="col-5">co-5</div><!-- col-2 : 5列分のカラム -->
        <div class="col-7">co-7</div><!-- col-4 : 7列分のカラム -->
    </div>
</div>
```

## インデックス
<a href="https://qiita.com/white_tiger/items/f3823fbc7bcee266f2c7">Bootstrapざっくり入門</a>
<a href="https://qiita.com/white_tiger/items/b394eed6c8de47e1661a">Bootstrapざっくり入門 - 2</a>

## あとがき
最後までご高覧いただきましてありがとうございます。（＾人＾）感謝
SQS へメッセージの送受信 in Python

# はじめに

Amazon SQS に Python を使って、メッセージの送信・受信をやってみます。備忘録的なメモ記事です。



# SQS Queue 作成

Create queue

![image-20210221232528144.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/e0bcb62e-4dd6-92a3-9552-3b3454fff234.png)



test queue で、それ以外はデフォルトのまま Create

![image-20210221232744295.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/db69d77a-ea72-f2a8-5106-b712fc6d6cb0.png)



作成完了 URL も表示されている

![image-20210221235327143.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/fb6f509a-129f-71de-3ec8-a9e9e9e49610.png)



# SQS に送信 in Python

SQS へメッセージを送付する、Python のソースコードです。作成した Queue の名前を指定して、3つのメッセージを送っています。

```python
import boto3

name = 'test-queue'
sqs = boto3.resource('sqs')
try:
    queue = sqs.get_queue_by_name(QueueName=name)
except:
    queue = sqs.create_queue(QueueName=name)

msg_num = 3
msg_list = [{'Id' : '{}'.format(i+1), 'MessageBody' : 'msg_{}'.format(i+1)} for i in range(msg_num)]
response = queue.send_messages(Entries=msg_list)
print(response)
```



実行例

```
> python3 testsqs.py 
{'Successful': [{'Id': '1', 'MessageId': '526c59a9-61c6-4c22-88ad-4f43df540f6f', 'MD5OfMessageBody': '9980c8a9248139f14f4165e5d53088aa'}, {'Id': '2', 'MessageId': 'cc2b7d8d-06c5-4586-8887-1b18ce8c99a9', 'MD5OfMessageBody': '0fd4e86b2daa009cd9929641dbd7dab6'}, {'Id': '3', 'MessageId': '1064603c-a4bc-4761-bd35-58eca3146dd9', 'MD5OfMessageBody': '8b30166735242c192258d4974f662a5f'}], 'ResponseMetadata': {'RequestId': '9b52941c-bdc9-5486-b679-ccb0c3d02499', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '9b52941c-bdc9-5486-b679-ccb0c3d02499', 'date': 'Sun, 21 Feb 2021 15:27:21 GMT', 'content-type': 'text/xml', 'content-length': '861'}, 'RetryAttempts': 0}}
```



Python のプログラムから送付したのちに、マネージドコンソールから確認します

![image-20210222000307322.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/00c2ced6-a2d2-4438-4d06-54d9943448b1.png)



Poll for messages

![image-20210222000332729.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/73178e02-3627-6673-6ea3-d40183ca9328.png)



3 つメッセージが送信されています

![image-20210222000359010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/facf0625-64ce-9297-48af-0c31c5af9249.png)



Body も確認できます

![image-20210222000434512.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/00441c82-a6f6-e874-1206-ec41843f3e49.png)



# SQS から受信 in Python

SQS からメッセージを受信する、Python ソースコードです。受信したあとに、`message.delete()` で削除しないと、メッセージはキューに残り続けます。

```python
import boto3

name = 'test-queue'
sqs = boto3.resource('sqs')
queue = sqs.get_queue_by_name(QueueName=name)
while True:
    msg_list = queue.receive_messages(MaxNumberOfMessages=10)
    if msg_list:
        for message in msg_list:
            print(message.body)
            message.delete()
    else:
        break
```



実行例

```
> python3 testsqs.py 
msg_3
msg_1
msg_2
```



# 参考URL

https://dev.classmethod.jp/articles/boto3_sqs_lambda_schedule_trial/
【HTML/CSS】 初心者向け！画像をリンク先に指定する！

はじめに
---
画像がURLのリンクになっており、さらに画像に文字を重ねるというものを今回実装しました。
制作に際し、なかなか上手く出来ず悩むこともありましたので、自身の備忘録及び今後実装を考えている方の参考になればと思い、投稿させて頂いております。
<br>

開発環境
---
ruby 2.6.3
Rails 5.2.4.4
<br>

見本
---
<img width="1000px" alt="スクリーンショット 2021-02-21 22.14.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942338/9aed9eb1-e052-ddb4-3538-404599499afb.png">
<br>

HTML
---
流れとしては、以下の３点になります。
① ６個のBOXを囲う大枠のdiv classを作成する。

② ①の中にdiv class="box"を6個作成する。

③ 更に②の中にリンク先と画像に載せる文字を用意する。


```html:index.html.erb
<div class="genre-content">
  <div class="box">
    <%= link_to genres_cake_path do %>
      <p class="genre-name cake">ケーキ</p>
    <% end %>
  </div>
  <div class="box">
    <%= link_to genres_macaron_path do %>
      <p class="genre-name macaron">マカロン</p>
    <% end %>
  </div>
  <div class="box">
    <%= link_to  genres_chocolate_path do %>
      <p class="genre-name chocolate">チョコレート</p>
    <% end %>
  </div>
  <div class="box">
    <%= link_to genres_parfait_path do %>
      <p class="genre-name parfait">パフェ</p>
    <% end %>
  </div>
  <div class="box">
    <%= link_to  genres_cafe_path do %>
      <p class="genre-name cafe">カフェ</p>
    <% end %>
  </div>
  <div class="box">
    <%= link_to genres_shaved_ice_path do %>
      <p class="genre-name ice">かき氷</p>
    <% end %>
  </div>
</div>
```

#####● 一塊のdivの内の構成
```html:index.html.erb
<div class="box">
  <%= link_to (リンク先指定) do %>
    <p class="genre-name ice">(画像に載せたい文字)</p>
  <% end %>
</div>
```
<br>

SCSS
---
今回SCSSで作成しておりますが、CSSでも問題なく作成できます。

```.css:homes.scss

.genre-content {
  display: flex;
  flex-wrap: wrap; # 画面幅が小さくなった時に折り返しする
  justify-content: center; # 子要素のboxを中央寄せにする
  margin-bottom: 50px;
}

.box {
  width: 160px;
  height: 160px;
  margin-right: 10px;
}

.box:last-child {
  margin-right: 0px; # 最後のboxの余白を0にしないと、中央寄せが微妙にずれてしまう
}

.genre-name {
  text-align: center; # 左右の中央寄せ
  line-height: 160px; # 上下の中央寄せ
  font-size: 26px;
  font-weight: bold;
  color: #fff;
  background-size: cover;
}

.cake {
  background-image: image-url("******.jpg");
}

.macaron {
  background-image: image-url("******.jpg");
}

.chocolate {
  background-image: image-url("******.jpg");
}

.parfait {
  background-image: image-url("******.jpg");
}

.cafe {
  background-image: image-url("******.jpg");
}

.ice {
  background-image: image-url("******.jpg");
}

```


終わり
---
今回初めてのHTML、 CSS投稿をさせていただきました。
私自身もプログラミング初心者ですが、同じ様な立場の方に少しでも参考になればと思います。
また、もし内容に誤りなどがございましたら、ご指摘いただけますと幸いです。
Railsのポリモーフィック関連付けを理解する

## これは何？
Railsの課題を実施しています。ポリモーフィック関連付けを用いるという指定があったのですが、そもそも**「ポリモーフィック関連付けとは何か」**が理解できていなかったので、学んだことをノートにまとめることにしました。

なお、対応するRailsのバージョンは`5.2.3`です。

## 概要

polymorphicとは「多形性の、多型の」という意味で、学術的な分類によく使われる単語のようです。


[Railsガイド](https://railsguides.jp/association_basics.html#%E3%83%9D%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%95%E3%82%A3%E3%83%83%E3%82%AF%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91)によると、ポリモーフィック関連付けとは

> ある1つのモデルが他の複数のモデルに属していることを、1つの関連付けだけで表現でき

...る関連付けであり、

> ポリモーフィックなbelongs_toは、他のあらゆるモデルから利用できる、(デザインパターンで言うところの)インターフェイスを設定する宣言とみなすこともできます。

ということだそうです。
また、**インターフェイス**とは、[実装にあたって参考にしたこちらの記事](https://qiita.com/itkrt2y/items/32ad1512fce1bf90c20b)によると、

> このように、「違うものがある決まった振る舞い／入出力を持つことで、同じように扱えるようにすること」をダックタイピングと呼びます。そして、その「ある決まった振る舞い」「入出力の定義」のことをインターフェースと呼びます。

ということだそうです。

## ER図

具体的なコードを見ていきたいと思います。
今回は、ユーザーに対する通知機能を実装しました。ログイン中のユーザーは自身に対し、

- 自身がフォローされたとき
- 自分の投稿にいいねがあったとき
- 自分の投稿にコメントがあったとき

に通知が送られます。
図で表すと、こんな感じで、

[![Image from Gyazo](https://i.gyazo.com/d7161965ac2a7b28150940fd8f4ceabc.png)](https://gyazo.com/d7161965ac2a7b28150940fd8f4ceabc)

例えば、`comments`と`activities`の間に、ER図の線はありませんが、`comment.activity`の形で`comments`から`activities`のインスタンスが取得できる様になります。

実際に線がないところでも自由に繋がりが生み出せるのが**`polymorphic(多形性の、多型の)`**の名前の由来なのかなと思いました。

## マイグレーション

まずはマイグレーションから作成していきます。実際に作成したマイグレーションは下記の通りです。

```rb:
class CreateActivities < ActiveRecord::Migration[5.2]
  def change
    create_table :activities do |t|
      t.references :user, foreign_key: true
      t.references :subject, polymorphic: true
      t.integer :action_type, null: false
      t.boolean :read, null: false, default: false

      t.timestamps
    end
  end
end
```

`subject`カラムの中にある`polymorphic: true`オプションがポイントです。
[Railsガイド](https://railsguides.jp/association_basics.html#%E3%83%9D%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%95%E3%82%A3%E3%83%83%E3%82%AF%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91)には、`reference`形でないマイグレーションの書き方も載っていますが、こちらは少し複雑さがましたので、今回は`reference`形にしました。

## 具体的なコード（アソシエーション）

アソシエーションはそれぞれ以下の様に定義しました。なお、ポリモーフィック関連付けに関係のない記載は除いています。

```Ruby
class Activity < ApplicationRecord
  belongs_to :subject, polymorphic: true
end

class Comment < ApplicationRecord
  has_one :activity, as: :subject, dependent: :destroy
end

class Like < ApplicationRecord
  has_one :activity, as: :subject, dependent: :destroy
end

class Relationship < ApplicationRecord
  has_one :activity, as: :subject, dependent: :destroy
end
```

上記の記述によって、例えば

```sh
$ rails c
> comment = Comment.first
> comment.activity
=> nil # activityのインスタンスがあればそれが表示される
```
のように取得できる様になりました。また、まだ`activity`のインスタンスがないので、表示できないのですが、これで

```sh
> a = Activity.first
> a.subject
# => comment や like や relationship のインスタンスが取得可能
```
...の形で親クラスが取得できます（activityを作成するメソッドを別途実装後）。

なお、**親クラスの**`as: xxxx`のところに指定した名前で、`activity（子クラス）`から親クラス(今回の場合comment, like, relationship)のインスタンスが取得できます。

ややこしいので間違えない様にしたいですね:relaxed:

今回は、これを利用して**「通知機能」**を作ったのですが、そちらのコードを記載すると記述が長くなってしまうので、詳細は次の記事に譲りたいと思います:grinning:

[追記]次の記事はこちらです！

https://qiita.com/tanutanu/items/479cb14cfea77c7429bd


ポリモーフィック関連づけについて、こんな記事を紹介して頂きました！
https://spice-factory.co.jp/development/has-and-belongs-to-many-table/
ユークリッドの互除法の理屈と実装

本稿は大きい数同士の最大公約数を素早く求めることの出来る計算方法である「ユークリッドの互除法」についてのまとめと(Python3.x系で)実装スクリプトを自分用に記事にしたものです。

勉強中のため記述内容に間違い等あるかもしれません。その場合、申し訳ありませんがコメント等でご指摘いただけると幸いです。
※[Zenn](https://zenn.dev/kumamoto/articles/0bde76bba8b0c9)にも筆者本人が転載済み。

## ユークリッドの互除法とは？

ユークリッドの「互除法」とは**「割り切れるまであまりで互いに割り（除法）続ける」**という意味。これを使って**大きな数字たちの最大公約数を素早く計算する方法。**
(計算量がなぜO(log2N)になるのかについては後日加筆予定。)

### 前提1 最大公約数とは

**2つ以上の正の整数の共通の約数のうち最大の数字。**

例えば12と18の最大公約数は6。9と120の最大公約数は3。[^1]

### 前提2 ユークリッドの互除法はなぜ成り立つのか

aとbの最大公約数をgcd(a, b)とする。[^2]

例えばgcd(12, 18) = 6

```
割り算の等式：a = b * q + r
上記が成り立つ時
gcd(a, b) = gcd(b, r)
```

上記がなぜ成り立つのでしょうか？

3段階にわけて考えればわかります。

```
割り算の等式：a = b * q + r
があるとき、gcd(a, b) = G1, gcd(b, r) = G2とします。

(1)
r = a - b * q = G1(a' - b' * q')と変形できます。
つまりrの約数にはG1があるわけです。gcd(b, r)はbとrの最大公約数なので下記が言えます。
gcd(r, b) >= gcd(a, b)
つまり、G2 >= G1

(2)
a = G2(b'' * q''　+ r'')と変形できます。
つまりaの約数にはG2があるわけです。gcd(a, b)はaとbの最大公約数なので下記が言えます。
gcd(a, b) >= gcd(r, b)
つまり、G1 >= G2

(3)
上記ふたつより、G1 = G2が言えます。

```

### 使い方

実際に3355と2379の最大公約数を求めてみるのを

紙に書いてやってみましょう。(下記は[スタディサプリさんの解説サイト](https://www.studyplus.jp/412)から引用。)

![スクリーンショット 2021-02-21 23.29.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403039/3616d060-f4e8-5fd2-2fa1-ea4bf09978f7.png)

すぐにわからない方は上記と前提で述べた条件を付き合わせて考えてみましょう。

```
a ÷ b = q あまり r ⇒ gcd(a, b) == gcd(b, r)

b ÷ r = q'あまりr' ⇒ gcd(b, r) == gcd(q', r')
```

これを上記の画像と同じ具体例に当てはめると、

```

3355 ÷ 2379 = 1 あまり 976 ⇒ gcd(3355, 2379) == gcd(2379, 976)

2379 ÷ 976 = 2 あまり 427 ⇒ gcd(2379, 976) == gcd(976, 427)

...省略

122 ÷ 61 = 2あまり0 ⇒ gcd(122, 61) == gcd(61, 0) == 61

```

遡って考えればgcd(3355, 2379) == 61。つまりgcd(a, b)は最後まで割り切ったときの割る数と等しいことがわかります。

## まずは最大公約数を普通にだす

普通に出してみましょう。これでも小さい数なら時間がかからず解けます。

```python
# first, secondのうち小さい方を最大値としてそこから-1ずつして両方を割り切れるものを探す
def boring_gcd_method(first, second):
    limit = min(first, second)
    # print("limit", limit)  # debug
    for i in range(limit, 0, -1):
        # print("i", i)  # debug
        if first % i == 0 and second % i == 0:
            return i  # int
```

## ユークリッドの互除法で出す

上記のやり方でも良いのですが、例えば239520000と1293400200の最大公約数を求めるのとかだと時間がかかって面倒そうです。

```python
# a = b * q + r, gcd(a, b) == gcd(b, r)
def euclidean_algo(first, second): # good
    while second:
        first, second = second, first % second
        # print("first, second", first, second)  # debug
    return first  # int
```

## 参考サイト

[Studyplus ユークリッドの互除法](https://www.studyplus.jp/412)

[高校数学の美しい物語 ユークリッドの互除法の証明と不定方程式](https://mathtrain.jp/euclid)

[^1]: ちなみに(今回は関係ないが)「互いに素」とは最大公約数が1である数字同士であるということ。例えば3と10は最大公約数が1なので互いに素であると言える。
[^2]: Greatest common divisorの略
dockerでubuntuとDjangoをインストールする

# はじめに

チームで始める時や、複数のPCを使用する時にdockerの設定ファイルを作成しておくと楽ちん。
そろそろPCが増えそうなので、改めてdockerの設定ファイルを作成してみました。

# dockerをインストールする

Get Started with Docker
https://www.docker.com/get-started

# docker-composeとDockerfileを作成してインストールする


Djangoのソースを置く場所を決めて、そこに以下のファイルを置く。

``` docker-compose.yml
version: '3' 
services:
 db:
   image: postgres:13
   environment:
     POSTGRES_HOST_AUTH_METHOD: 'trust'
   container_name: "postgre"
 web: 
   build: . 
   command: python3 manage.py runserver 0.0.0.0:8000
   volumes:
     - .:/code
   ports:
     - "8000:8000"
   depends_on:
     - db
```

``` Dockerfile
FROM python:3.8
# 環境変数 PYTHONUNBUFFEREDを設定 バイナリレイヤ下での標準出力とエラー出力を抑制
ENV PYTHONUNBUFFERED 1
# mkdirコマンドの実行
RUN mkdir /code
# 作業ディレクトリの設定
WORKDIR /code
# req.txtを/codeに追加する
COPY req.txt ./
# Pythonのパッケージ管理ツールのpipをアップグレード
RUN pip install --upgrade pip
# pipでreq.txtに指定されているパッケージを追加する
RUN pip install -r req.txt
# ローカルのディレクトリを/codeに追加する
ADD . /code
# ポートを開く
EXPOSE 8000
```

``` req.txt
Django>=3.1,<3.2
mysqlclient>=2.0,<2.1
gunicorn>=20.0,<21
psycopg2>=2.8,<2.9
```

Djangoのadminを作成する

```
docker-compose run --rm web django-admin.py startproject django_admin
```

# setting.pyを修正する

```setting.py
ALLOWED_HOSTS = ["*"]


DATABASES = {
     'default': { 'ENGINE': 'django.db.backends.postgresql',   
     'NAME': 
     'postgres',
     'USER':
     'postgres', 
     'HOST':
     'db',
     'PORT': 5432, 
     }
    } 
```

# 変更内容をコンテナに反映する
``` sh
docker-compose up -d
```

# djangoを開く
http://192.168.99.100:8000/

以下が表示されればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1099979/51b37f7f-fdd2-c620-8829-eb0a455b60f1.png)
【駆け出しエンジニアメモGit解説②】リモートリポジトリとローカルリポジトリの関係性を簡単に図にしてみた。

# 前回の内容
前回はGitとGitHubの違いについて書きました。Gitはバージョン管理ツールであり、GitHubはGitを利用した、開発者を支援するWebサービスでした。
前回の内容は[こちら](https://qiita.com/ShigeShigeQiita/items/958e7e3a266bd1097476)から。

# リモートリポジトリとは？
リモートリポジトリとは、リモート上にあるリポジトリのことで、いわゆるGitHubで管理されているリポジトリのことを言います。こちらも、リポジトリですので、木の枝のように枝分かれしているイメージを持つと分かりやすいです。雲の上にあり、ネットに繋がっているリポジトリですね。ネットに繋がっているので、許可されていれば他の共同開発者も一緒にその枝をい削除したり、追加したりすることができます！

# ローカルリポジトリとは？
ローカルリポジトリとは、リモートとは逆で自分のＰＣ上にあるリポジトリの事です。こちらはネットに繋がってはいないので、他の人が枝を追加したり、削除したりすることはできないです。ただし、ネットに繋がっていないと言いましたが、Gitの機能を使うことで、リモートリポジトリに自分のリポジトリを反映させたり、リモートリポジトリをコピーしてローカルリポジトリを作ったりすることができます！

# 全体の関係性とイメージ図
こちらが全体の関係性を簡単に図にしてみたものです！
汚くてごめんなさい、、、また、分かりづらかったらごめんなさい、、、
![S__18595886.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673966/3623dc37-0437-c5c5-8b33-035dc9617f31.jpeg)

# まとめ
* リモートリポジトリは、雲の上（ネット上）にあるリポジトリのこと。みんなで共有できる。
* ローカルリポジトリは、自分のPC上にあるリポジトリのこと。みんなで共有するにはリモートに上げる必要がある。

#参考サイト
https://www.r-staffing.co.jp/engineer/entry/20190621_1
https://techacademy.jp/magazine/6235


# 最後に
最後までお読みになってくださりありがとうございます。もし、参考になったり、少しでも役に立った、良い記事だなと感じていただけましたら**"LGTM"**を押してくださるととても励みになります！！！お願いします！ポチっと押してくださいー！

この記事は、駆け出しエンジニアの筆者が自分のメモと理解向上のため、自分と同じ駆け出しエンジニアでも分かるように、分かりやすく解説することを目的とした記事です。誤った記載をしてしまうかもしれませんがご了承下さい。誤ってる際はコメントにてご指摘してくださると幸いです。

少しでも駆け出しエンジニアの方の力になれると幸いです。また、同じく駆け出しエンジニアの方々、一緒に頑張っていきましょう！

Twitterもやっているのでぜひフォローしてください→https://twitter.com/EngineerShige
【SwiftUI】JSONで取得したものをList表示する方法【tutorial】

## 今回作成するアプリ
![１.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517666/28f0f0ff-6165-e224-6899-ac88b99f6fec.gif)
## はじめに
今回は初めてSwiftUIでAPIを叩いてJSONを取得し、List表示する方法をご紹介したいと思います。
よってこの記事は、SwiftUIは触ったことがあるが、APIやJSONは初めてと言う方向けの記事です。
尚、APIやJSONはなんぞやと言うことについては、様々な良記事が沢山ありますのでそちらを参照下さい。
## 環境
・ /macOS Big Sur 11.3
・ Xcode : 12.4
## サンプルJSON
今回は初めてJSONを取得し、Listで表示させる為、オーソドックスな天気APIとかではなく、様々なJSONのサンプルが用意されている[jsonplaceholder](https://jsonplaceholder.typicode.com/)を使用してきます。
またなぜこの様なサンプルを使用するかと言うと、筆者がお天気APIなどのtutorialではなかなか使用の仕方が理解できず、こちらのサンプルを使用することにより、理解を深めることができたのでその様な方もいるのでは無いかと思い、今回はこちらのサンプルを使用した使用方法を紹介していきたいと思い書いている所存です。
## jsonplaceholder
まず初めにこちらのリンクをクリックするとこの様な画面が表示されます。![スクリーンショット 2021-02-20 23.49.52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517666/3c0322b8-96a6-6181-8d0e-7810963f07d1.jpeg)
今回はこちらのサイトでは様々なJSONサンプルが用意されているのでこちらの/postsを使用してList表示していきます。
## jsonplaceholderを使用していく
jsonplaceholderは/posts、/comments、/albums、/photos、/todos、/usersに分かれており、それぞれに適したデータが用意されており、postならテキスト、その他には画像や人の写真などが用意されている。今回はテキストを抽出したいのでpostを使用していく。使用方法は下記の動画の通り進んでいき、postのURLを取得していきます。
![7qm8o-79iiw.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517666/fe77fae4-52c6-5ca8-c884-631e64254ffe.gif)



まず初めにpostsではuserid,id,title,bodyがあり、今回id,title,bodyを使用していく為以下の構造体を作ります。

```swift
struct Post: Codable, Identifiable {
    var id = UUID()
    var title: String
    var body: String
}
```
次にApiのClassを作ります。

```swift
class Api {
    func getPosts(completion: @escaping ([Post]) -> ()) {
        guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts") else { return }
        URLSession.shared.dataTask(with: url) { (data, _, _) in
            let posts = try! JSONDecoder().decode([Post].self, from: data!)
            DispatchQueue.main.async {
                completion(posts)
            }
        }
        .resume()
    }
}

```
最後にViewを以下のように作ります。

```swift
struct JsonTestView: View {
    @State var posts: [Post] = []
    var body: some View {
        List(posts) { post in
            VStack(alignment: .leading) {
                Text(post.title)
                    .font(.system(.title, design: .rounded)).bold()
                Text(post.body)
            }
        }.onAppear{
                Api().getPosts { (posts) in
                    self.posts = posts
                }
            }
        }
    }
```

以上で取得できます！
![１.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517666/b988e4f6-c35a-6e72-942e-c201bf503128.gif)

## まとめ
とりあえず入門的な記事になれば良いかなと思ったので小難しいところは端折りましたが、是非ここからimageをurlで取得して表示するにはどうしたらいいのだろうか？とか自分でDB立てて、API叩くにはどうしたらいいのだろう？などに繋げていくきっかけになって頂けたらと思います！
The server quit without updating PID fileを解決する【MySQLエラー】

#はじめに
`mysql.server start`や`mysql.server restart`の際に出るエラー、

```
ERROR! The server quit without updating PID file
``` 
このエラーにかなり手こずりました。

__・PCを再起動する__
__・touchコマンドでPIDファイルを作る__
__・ファイルの権限を変更する__
__・MySQLをアンインストールしインストールし直す__

ググッて調べた上記の方法がどれも上手くいかず途方にくれていましたが、
何とか解決できたので忘備録を兼ねて解決方法をまとめておきます。


#解決方法
###①
まずはエラー解決の過程でMySQLのインストールとアンインストール繰り返してしまい、
MySQLのpathを増やしすぎてしまったので、増えすぎたpathを整理する。

```
% cat .zshrc
#.zshrcファイルの中身を表示
```

####実行結果

```

eval "$(rbenv init -)"
export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"
export PATH="/usr/local/opt/mysql@5.7/bin:$PATH"
export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"
export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"
export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"
export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"
eval "$(nodenv init -)"
export PATH="/usr/local/opt/node@14/bin:$PATH"
export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"
export PATH="/usr/local/opt/mysql@5.7/bin:$PATH"
```
MySQL5.6とMySQL5.7のpathが多すぎるので整理する。

VSコードを使ってpathを整理する時は新規ウィンドウを立ち上げ、
「コマンド＋O」でホームディレクトリを選択。
ホームディレクトリの「.zshrcファイル」の中身を編集しMySQLのpathを一つに減らす。

####.zshrcファイル編集後
```
eval "$(rbenv init -)"
eval "$(nodenv init -)"
export PATH="/usr/local/opt/node@14/bin:$PATH"
export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"
```

その後、下記のコマンドで編集を保存する。

```
% source .zshrc
```

###②

次に不要なプロセスを確認します。
varディレクトリに移動しpsコマンドを実行。

```
var % ps -e | grep mysql 
```

###実行結果


```
534 ??         0:00.03 /bin/sh /usr/local/opt/mysql@5.7/bin/mysqld_safe --datadir=/usr/local/var/mysql
638 ??         0:11.43 /usr/local/opt/mysql@5.7/bin/mysqld --basedir=/usr/local/opt/mysql@5.7 
```

インストールしているMySQLのバージョンは@5.6なのに、@5.7のプロセスが残っていました。
これがエラーの原因であり、これをkillしてあげると解消されるはず。


```
var % kill 534
var % kill 638
```

これで不要なプロセスをkillすることができました。

```
% mysql.server start 
Starting MySQL
. SUCCESS! 
```
改めて`mysql.server start`すると上手く行きました。

#終わりに
MySQLは予期せぬエラーが多いとのことで、
MtSQLが立ち上がらない系のエラーはpathやプロセスをチェックするのがいいのかもしれません。
Tymeleafの変数周りTIPS

# 概要
Sprirng Boot + tymeleafで渡された変数値を表示するサンプル。

# 前提
表示するテンプレートにパラメータを渡しているコントローラ

```java:sampleController.java
import org.springframework.ui.Model;

@GetMapping("/sample")
public String sample(Ｍｏｄｅｌ model){
    model.addAttribute("intVar1", 1);
    model.addAttribute("strVar1", "Test");
    model.addAttribute("strVar2", "Test2");

    return "sample";
}
```
# 例
### 数値として変数展開
値が数値の場合は計算結果を表示する

```html:sample.html
<p th:text="${intVar1}">
<p th:text="${intVar1} + ${intVar1}">

```
##### 実行結果

``` web
1

2
```

### 文字として変数展開
文字列は連結して表示も可

```html:sample.html
<p th:text="${strVar1}">
<p th:text="${strVar1} + ${strVar1}">
```
###### 実行結果

``` web
Test

TestTest
```

### 変数名を動的に生成
変数を文字列として表示したり、変数の値を表示したり

```html:sample.html
<!-- 文字列:strVarと, 数値:1を連結した文字列:strVar1をtmpVar変数に設定 -->
<div th:with="tmpVar='strVar' + 1">

    <!-- tmpVarの設定値を単なる文字列として表示-->
    <p th:text="${tmpVar}"></p>

    <!-- tmpVarの設定値を、変数とみなしてその値を表示 -->
    <p th:text="${__${tmpVar}__}"></p>    
</div>
```
###### 実行結果

``` web
strVar1

Test
```

### 変数名を動的に生成（ループを使う場合）
変数名に連番サフィックス（strVar1, strVar2, …, strVarn)を使っている場合にループで処理したい場合など。

```html:sample.html
<div th:each="i : ${#numbers.sequecnce(1,2)}" th:with="tmpVar='strVar' + ${i}">
    <p th:text="${__${tmpVar}__}"></p>    
</div>
```
###### 実行結果

``` web
Test

Test2
```
そうだ、SQLを勉強しよう15

#はじめに
表計算にはできない、SQLのメリットを実感してきました。

##テーブルの結合

```sql
SELECT 選択列
FROM テーブルA
JOIN テーブルB
ON 両テーブルの結合条件
```
###ポイント
テーブルAが基準となるテーブルです。そこに、テーブルBをくっつけるイメージです。

###結合条件に記述する内容
テーブルAの列名とテーブルBの列名どれをくっつけるか。
テーブルBの主キーをテーブルAに記述しているのであれば、

```sql

そのテーブルAに記述しているテーブルBの主キー列 = テーブルBの主キー
```

###最後に
テーブルを分けることで、値を変更したいときに処理が少なくて済むメリットがあります。
[簡単]QiitaやREADMEに画像を貼り付ける[Gyazo]

#画像の貼り付け方
Gyazoで撮影した画像をQiitaや、READMEに添付する方法を書いていきます。
他の方の記事で見つけたものより簡単だったので是非ご覧ください。

#方法

まずGyazoを使い撮影します。

[![Image from Gyazo](https://i.gyazo.com/5125de27b30fa4261cdb05b91a574647.png)](https://gyazo.com/5125de27b30fa4261cdb05b91a574647)

撮影後自動でブラウザに遷移するので、画像を参考に「マークダウンをコピー」を押してください。その後コピーしたものをQiitaやREADMEに貼り付けて完了です。

#まとめ

Qiitaや、READMEはマークダウン記法を採用しているので、「これでいけるんじゃね？」と思いやってみたら、ものすごく簡単にできました。
ご覧いただきありがとうございました。
githubにterraformのコードを上げようとしたらpre-receive hook declinedのエラーメッセージが出た

terraformで書いたコードをgithubにプッシュしようとしたら下記のエラーメッセージが出てpushが出来ない。

```
git push
Enumerating objects: 19, done.
Counting objects: 100% (19/19), done.
Delta compression using up to 4 threads
Compressing objects: 100% (15/15), done.
Writing objects: 100% (19/19), 39.93 MiB | 3.24 MiB/s, done.
Total 19 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
remote: error: Trace: beb5f985c2fbc28e5aa48d6a98099ff68c87a2d132d8727288572ca774c35478
remote: error: See http://git.io/iEPt8g for more information.
remote: error: File ec2-create/.terraform/plugins/darwin_amd64/terraform-provider-aws_v3.29.0_x5 is 196.78 MB; this exceeds GitHub's file size limit of 100.00 MB
To https://github.com/atsushi-815/terraform-practice.git
 ! [remote rejected] master -> master (pre-receive hook declined)
```

# 原因

`terraform init`した時に作成された`.terraform`フォルダにある一部ファイルが100MBを超えていて、githubの制限に引っかかっていた。

# 解決方法
`.terraform`は自分でいじらないからコード管理する必要は基本無いので、`.gitignore`でコード管理の対象外にして解決。
私の場合、一度commitしてしまって戻すのが面倒だったので、別場所で新たにcloneして、そこに変更内容を持って行って、`.gitignore`を使用、`.terraform`を対象外にしてpush。次はエラーなくpush出来た。
Could not resolve hostname server: nodename nor servname provided, or not knownを解決する

初学者です。
理解が曖昧なところも多いため、ご指摘等ありましたらご連絡いただければ幸いです。

今回はssh接続ができなくなり、デバックを確認したところ
`Could not resolve hostname server: nodename nor servname provided, or not known`
が出たのでその解決方法を記録として残します。


## SSH接続をしようとしたらエラー

さっきまで出来ていたSSH接続をするために

```PHP:ターミナル
ssh -i ~
```

と入力したら

```PHP:ターミナル
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
```

とエラーが出て接続出来なくなってしまいました。


## デバックで確認する

こういう時はデバックを見るべきとのことなので

```PHP:ターミナル
ssh -vvv user@server
```

と入力すると

```PHP:ターミナル
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 47: Applying options for *
debug1: Connecting to server port 22.
ssh: Could not resolve hostname server: nodename nor servname provided, or not known
```

と出てきました。


## 解決方法

すみません。工事中です.....
PHP学習

# PHPについて
個人的なアウトプットとしての記事です。
私がPHPについて学習したことについて記述していきます。

##PHPとは

### アウトプット
21/02/21
関数
・var_dump()
　引数に指定した変数の型を表示する
　デバッグによく使う

・intval()
　引数に指定した変数を数値に変換する
　同義？に　(int)"文字列"　がある。こちらも文字列部分を数値に変換する。

・strval()
　引数に指定した変数を文字列に変換する
　同義？に　(string)数値　がある。こちらも数値部分を文字列に変換する。


21/03/06
HTML
・formタグの属性
method →　GET,POST他
action　→　処理をするページファイルののURL（同ページなら同じページのファイル名）


php
・スーパーグローバル変数
```$_GET```のようなものmethodに指定されたGET,POSTなどに対応していて連想配列で値が返される
phpでは９種類
```$GLOBALS、$_SERVER、$_GET、$_POST、$_FILES、$_COOKIE、$_SESSION、$_REQUEST、$_ENV```

GET　→　URL末尾に```?~```といった形で表示される
POST →　GETとは違いURLに表示されないがデータは送られる

HTML内でのif の記述
・行を跨ぐ場合

```
<?php if(条件式){ ?>
  条件式がtrueだった時の処理
<?php } ?>
```

上記だとifの終わりが分かりにくいので、
以下で記述可能　以下の方が可読性が高い
 違いは```{}```部分を ```:``` と　```endif;```にしている

```
<?php if(条件式) : ?>
  条件式がtrueだった時の処理
<?php endif; ?>
```

### セキュリティについて

セキュリティについて、
XSS,CSRFなどなど。

XSS：```<script>```タグでユーザーが意図せず個人情報などをformで送信するように誘導するもの

CSRF：偽のinputリンクで意図しないURLに遷移させるもの
[Python]機械学習で使えるサイトまとめ

# 概要
機械学習で勉強をする際に参考にしようと思っているサイトをまとめました。
メモ的に使ってますが、なにかよいさいとなどあれば教えていただけると幸いです。

# 機械学習の勉強

[【保存版・初心者向け】独学でAIエンジニアになりたい人向けのオススメの勉強方法](https://qiita.com/tani_AI_Academy/items/4da02cb056646ba43b9d)


[数学に強いエンジニアむけの機械学習勉強法](https://medium.com/@hayato.iida.0213/%E6%95%B0%E5%AD%A6%E3%81%AB%E5%BC%B7%E3%81%84%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%82%80%E3%81%91%E3%81%AE%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E5%8B%89%E5%BC%B7%E6%B3%95-e3f4bd7a7cf9)

[SIGNATE](https://quest.signate.jp/quests)

[Kaggleに登録したら次にやること ～ これだけやれば十分闘える！Titanicの先へ行く入門 10 Kernel ～](https://qiita.com/upura/items/3c10ff6fed4e7c3d70f0)

[keras本などのソースコード](https://qiita.com/AnchorBlues/items/847d202e26d0586b5cca)

# ベースラインの作り方

[データ分析初心者がチュートリアルから卒業するための特徴量生成の考え方](https://jpn.nec.com/ai/consulting/analyst/column/20201120.html)

# 機械学習のアプリ

[あなたのポートフォリオを目立たせる8つの機械学習/AIプロジェクト](https://ainow.ai/2020/09/18/227825/)

[TensorFlow.js で機械学習Webアプリを作る](https://avinton.com/blog/2019/07/tensorflow-js/)

# GCPの環境づくり

[GPUの割り当て方](https://qiita.com/kazunori279/items/b17d16a2bfbec5e72984)

[基本的な操作](https://qiita.com/yota-p/items/affe6d970ac4896d6e70)

[割り当てられない問題](https://qiita.com/y_kani/items/ddb7c4a5ca6fdf36cac4)

# 画像処理
[画像処理100本ノック](https://github.com/yoyoyo-yo/Gasyori100knock)

# 自然言語処理
[自然言語処理100本ノック](https://www.cl.ecei.tohoku.ac.jp/nlp100/#ch5)

# 画像コンペ
[Kaggleの画像コンペに初めて挑んでみた](https://sinchir0.hatenablog.com/entry/2019/11/21/231502)

# kaggle上位のとり方
[Kaggleの概要を理解する（Titanicの次に向けて）
](https://nehori.com/nikki/2020/01/06/kaggle-3/)

[AIプログラミングスクール卒業生の初心者がkaggle Expertになるまでの軌跡(riiidコンペ体験記)](https://programming-info.dream-target.jp/kaggle_expert)

# 画像の取り込み方

↓のimg_loadの部分
[Keras：VGG16、VGG19とかってなんだっけ？？](https://qiita.com/MuAuan/items/86a56637a1ebf455e180)
Polacode, Carbonでイイ感じのコード画像を作る

## コード画像？そんなんスクショで事足りるんじゃね？

そうですねw でもスクショだと画像が荒いときとかありますよね。
用途としては一定の画質を担保してコードが見やすい画像にしたいとき→LTとかのスライドにコード載せるときとか、Twitterに投稿するときとかですかね。

## Polacodeってなに？

これですね。
https://marketplace.visualstudio.com/items?itemName=pnp.polacode

![polacode.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74725/8e27c4e3-4f98-d115-624b-3b409832bbc7.gif)


### どうやるの？

VS CodeでVS Codeにぶち込む。

![スクリーンショット 2021-02-21 22.33.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74725/40f165ba-51d8-202b-e4ee-2fb656ff5b36.png)



あとは動画の通りです、、と言いたかったのですが、↑のgitだとマウスのドラッグとPolacodeエディタが連動しているのですが私が試した限りではコピペが必要でした。。

## Carbonってなに？

これですね。
https://carbon.now.sh/

![スクリーンショット 2021-02-21 22.36.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74725/659c00a3-b250-6696-f172-d4d3010cc98c.png)

### どうやるの？

エディタ等からコピーしたコードをぶち込む。

オプションは、

![スクリーンショット 2021-02-21 22.39.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74725/66eeb0fa-f587-ca6c-0ca4-08f47d69cba2.png)

* テーマ（背景色やシンタックスハイライト）が選べる
* 言語は自動で識別。選択も可。
* エディタ周りの背景色も選択可。

![スクリーンショット 2021-02-21 22.42.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74725/103a1dc0-42e8-4ddd-857c-64ff1dfaad3d.png)


* 詳細設定でいろいろ詳細に設定できる。
* 貼り付けたコードをコピーするボタン付いてる（需要ある？ｗ
* ツイートできる

![スクリーンショット 2021-02-21 22.47.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74725/38dfeb71-9ada-8c29-2d09-aadbc1f4ab32.png)


* えくすぽーとできる。ファイル名、サイズ、画像形式選べる。

## 以上

小ネタでした。
[メモ] カラムとは別名の外部キーをマイグレーションで設定する

userは〜円のギフトをprofileから贈れる

```ruby:gift.rb
class CreateGifts < ActiveRecord::Migration[6.0]
  def change
    create_table :gifts do |t|
      t.integer    :price,    null: false
      t.references :giver,    foreign_key: { to_table: :users }
      t.references :receiver, foreign_key: { to_table: :profiles }
      t.timestamps
    end
  end
end
```
【Swift】Compact状態のDatePickerに戻る処理を行う

##新しいDatePicker
iOS14からどうやらDatePickerの挙動が変わったらしく、今までのドラムロール式の日付・日時選択からカレンダー表示の様な選択方法が選べるようになりました（従来のDatePickerも引き続き使用出来る）。
しかしこのポップアップされるDatePickerは日付を選択時に一つ前に戻る機能が備わって居らず自分で書いて選択時に戻る処理を入れてあげる必要がある。
![CompactDatePickerが表示されたiPhoneSimulator](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176908/d9a5c518-76be-c63c-bab2-bc7c2d0b940b.png)

##コード
```Swift:ViewController
@IBAction func CompactDatePicker(_ sender: UIDatePicker) {
    // 日付選択時に選択前の画面に戻る
    self.dismiss(animated: true, completion: nil)
}
```
【LPIC】LPIC-2 201を受ける方へ

#はじめに
LPIC201に合格したので、私の勉強方法についてまとめます。
私自身、他の方の合格体験記を励みに勉強していたので、これから受験する方の一つの参考になれば幸いです。

#LPIC201とは
ここに訪れている方には説明不要かと思いますが、簡単にご説明します。
LPICとは、LINUX OSに対する知識を問う認定資格です。
LPICにはLevel1〜3まであり、Level3までいくためには、Level1から順次取得していく必要があります。
Level2の認定を受けるために当記事の試験である201および、202の二つの試験に合格する必要があります。

#筆者スペック
個人的に、合格体験記に筆者スペックが書いてあると自分と照らし合わせて考えられるので、結構好きな欄です。このくらいのバックグラウンドの人が、このくらい勉強して合格したんだな、といった指標にもなると思うので、一つのサンプルとしてご査収ください。

|項目|内容|
|:---|:---|
|職業|独立系SIer勤務3年目。|
|Linux経験|業務で一年ほど。Linuxベースシステムのミドルウェア開発。|
|他経験|制御系システム開発（C言語）。最近はパブリッククラウドの設計・構築。|
|学歴|地方国立理系（非情報分野）|
|年齢|27歳|
|保有資格|基本情報技術者 / LPICLevel1 / AWS系 / Azure系|

#勉強期間
大体１ヶ月です。
１日の勉強量は測定していませんが、1〜3時間くらいだったと思います。
時間ではなく、今日はここまで、と目標を区切ってやりました。

#勉強方法
|#|内容|期間|
|:---|:---|:---|
|1|小豆本を読む|１週間|
|2|Ping-t 一周目(全てヒット)|２週間|
|3|Ping-t 二周目(全てコンボ）|５日|
|4|Ping-t コマ問一周|２日|


###1.小豆本を読む（約1週間）
まずはLPICお馴染みの小豆本で、内容をさらっと理解します。
**ここでは、内容の完璧な理解は意識していなくて、こんなものがあるんだなーくらいで全体像を掴むことを意識しました。**
1日1章のペース進めました。

###2.Ping-t 一周目(全てヒット)(約2週間)
LPICお馴染みのPing-t。このサイトは本当に素晴らしいと思います。
各章ごとに、10問ずつを1セットとして解いていきました。**最初は全然解けないかもしれませんが、心配はいりません。**ここで重要なのは、解説までしっかりと目を通すことです。問題の暗記だけでは合格難しいと思います。
1日0.5章くらいのペースで進めました。
0.5章/日というペースはあまり負担になることのないペースでした。また、2日かけて1章を完了するので、2日目に1日目の復習ができたのがよかったと思います。

###3.Ping-t 二周目(全てコンボ)(約5日)
一周目は各章ごとに行いましたが、今回は全章をランダムに10問を1セットとして解いていきました。前半の章などは結構忘れてしまったりするので、解説もそれなりに目を通します。
大体1日100問強をコンボにしていきました。

###4.Ping-t コマ問一周(約2日)
**意外とやらないがちですが、私としてはこれに毎度助けられている気がします。**
コマ問は、各章ごとに一周で良いのでやった方がいいと思います。ここまでの選択式の問題だと、コマンドやパスなどが曖昧な記憶になってしまいがちかと思います。コマ問を一周するだけで頭の整理と記憶の定着が出来た感がありました。もちろん最初は全然解けないかもしれませんが、それだけ記憶が曖昧だったと自覚して、頑張って一周はしましょう。


ここまできて、模擬試験を2回実施し、共に9割超え出来ていたので、本番試験に臨みました。

#結果
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">LPIC201合格しました。<br>勉強期間1ヶ月。CBT方式の試験にもいよいよ慣れてきた。<br>次は最難関と言われている、202。 <a href="https://t.co/U2C0h5ZNRt">pic.twitter.com/U2C0h5ZNRt</a></p>&mdash; 村上 (@rocketboy555) <a href="https://twitter.com/rocketboy555/status/1363301339980173312?ref_src=twsrc%5Etfw">February 21, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
590/800点で合格でした。
偉そうに書いてる割には点は伸びていないですね。
本番中は見たことあるような問題が多かったので、かなりリラックスして臨めました。（正直もっと取れていると思いましたが・・・。）
見たことないような問題も出ましたが、最初から覚悟していたのでパニックにはならずに済みました。
コマンドの問題は6,7問くらいだったと思います。Ping-tのコマ問よりは圧倒的に簡単でした。オプションは問われることはなく、コマンド単体を答えるだけのものが多かった印象です。


#おわりに
冒頭にも書きましたが、今後201試験を受ける人の参考になればと思います。
年内にLevel3まで取得する予定です。
Tips: Treasure Workflowを用いてクエリを実行するときに、クエリ結果をエクスポートする方法

TreasureDataのコンソールでクエリを記述する際、「Result Export」の設定が項目として存在していると思います。
これをTreasure Workflow （トレジャーワークフロー） を用いた時にどのように設定するのかがわからず、詰まったので備忘録として残しておきます。

なお、Treasure Workflow自体については

https://qiita.com/kajuki1113/items/aefc76c650ff02e12d10

https://qiita.com/reflet/items/82a5889a9a8b98021a0d

https://qiita.com/bwtakacy/items/19d45991022b6b7a88ce

などで詳しく書かれています。

## 結論
digdagファイルに以下のような設定を書けばできます（datatankにエクスポートする例）

```digdag
+export_data:
  td>: query.sql
# 以下の設定がエクスポートの設定
  result_connection: datatank
  result_settings:
      database: datatank
      table: example_table
      mode: replace
      keys: id
```

設定する項目は以下のようなものです。

- `result_connection`→エクスポート先のコネクターの指定（DataConnectorで定義した名前）
- `result_settings`→コンソールで設定する際の設定と同じ項目（DataConnectorごとに異なるので一度コンソールでエクスポートの設定をしてみると良さそう）


同様に詰まった方の参考になれば幸いです。

## 参考文献
https://docs.digdag.io/operators/td.html
 
https://qiita.com/reflet/items/82a5889a9a8b98021a0d
 
https://qiita.com/bwtakacy/items/19d45991022b6b7a88ce
Ubuntu MATE で Fcitx の挙動がおかしくなった時の対処方法



# Ubuntu MATE で Fcitx の挙動がおかしくなった時の対処方法


投稿日：2021年02月21日


## 概要

Ubuntu MATE の環境下で、 Fcitx の挙動がおかしくなった時の対処方法。

１年に数回程度の頻度で、Fcitx の挙動がおかしくなる時があります。


## 対処に至った経緯

・文字を入力するプレビューウィンドウの表示位置がおかしい。位置がズレる。

・文字変換する際のキー割り当ての挙動がおかしくなった。

・挙動が不安定


## 環境
Linux Mint 20 Ulyana 64bit


## 解決

基本的に、Fcitx の設定ファイルを削除して、OSを再起動すれば大抵の場合は直ります。

まず、最初に、画面下のタスクバーの右下辺りにある、Fcitx のアイコン(キーボードのような絵)を
右クリックして、"閉じる" を選択して Fcitx を終了させます。

次に、下記のパスにある、Fcitx の cofig フォルダを全て削除します。

	"~/.config/fcitx"

そして、OS を再起動すれば、Fcitx のプレビューウィンドウの位置ズレが治りました。

※ Linux では、"." で始まるフォルダは、隠しファイル扱いになっている為、
ファイルマネージャを使って上記フォルダを探す場合、"隠しファイルを表示する" の設定が必要です。


## 結論

Fcitx には、稀に、使用中に config ファイルの設定がおかしくなる不具合が発生することがあります。
その場合、前述のように、一度、Fcitx の config ファイルを全て削除してから、
OS を再起動すれば、基本的に大抵の不具合が治るようです。
私が経験した Fcitx 関連の不具合は、全て、上記のやり方で修復することが出来ています。
WebAudioAPI調べ中

# ここでは
私が調べたことについての備忘録です。
内容は徐々に増えると思います。

内容について、
調べたことをメモに近い形で記述していきます。
検証が出来ていないことも多々あると思います。
認識の間違いなどあればご指摘、ご教授いただけると幸いです。

# WebAudioApiについて
### WebAudioApiとは
現在の認識は、
"JavaScriptを用いて、HTMLが持つ既存のAudio要素を細かく操作する技術"
といった感じ。

### audioContextインスタンス
audioContextはブラウザ上でオーディオデータを扱う際に始めに生成するべきインスタンス
audioContextを生成することで、ブラウザ上のオーディオデータへのアクセスが容易になると言うイメージです。

audioContextを利用する際の仕組みというか、流れの部分には、
input　→　処理　→　output
という流れがあるということ。

inputは、以下のようなものかと思われる
・自身のPC上のファイル　
・生成するオシレーター音源　
・URLから取得してくるファイル

取得したオーディオデータを、処理(フィルターをかけたり)して、
outputに接続すると音声が出力される

といった感じかと。



### JavaScriptでのクラス
WebAudioApiを扱うにあたって、そもそもJavaScript(以下"JS")の知識が必要と思われました。
わかりやすそうなコードを参考にさせていただき、読み解く中で、
最初にぶち当たったのが、class と constructerの記述。

クラスについては、Rubyなど、オブジェクト指向と呼ばれる言語で利用するもので、
"車でいうところの設計図"　"人間で言うところの個人と言う概念"
のような例えをされると思います。
扱いたいデータで、「同じ属性で何種類も出現する可能性があるもの」に使うのかな　程度の認識です。

正直、筆者はクラスの使いどころが曖昧である。

で。

JSではclass ~　でクラスを用意して、
classの中で、constructor()メソッドを定義、　
classがnewされる際に、constructor()で定義したデータの属性？をインスタンスのデータとして取得してインスタンスを利用していく
と言う流れになるのかなと思う。

## 余談と言うか、メモ

JSではclassと言う機能はなく、「クラスっぽい書き方ができるよ。」って感じ。らしい。
JSではclassと言う機能に、クラスっぽい機能が働くようなコードが親にある。それをclassってのにまとめてるだけ。
なので、物によってはclass使うよりサッパリかけることもある。　のかな？
Kubuntu20.10(KVM)でオンボードWifi IFをパススルー

#Kubuntu20.10(KVM)でオンボードWifi IFをパススルー

所有のマザーボード(AMD B550)でオンボードのWifiデバイスをPCIパススルーしたいと思いました。
が、同じIOMMUグループに他いろいろなPCIデバイスが含まれていてました。
そんなわけでACSオーバーライドパッチ(カーネル)を試して見ることにしました。
**参考:https://benisnous.com/easy-acs-kernel-patch-guide-for-ubuntu-20-04/**

##ACSオーバライドカーネルのインストール
```bash:ACSオーバライドカーネル配布サイト
	https://queuecumber.gitlab.io/linux-acs-override/
```

```bash:ACSオーバーライドカーネルのインストール
	# dpkg -i linux-headers-5.8.18-acso_5.8.18-acso-1_amd64.deb
	# dpkg -i   linux-image-5.8.18-acso_5.8.18-acso-1_amd64.deb
```

###GRUBの設定
カーネルパラメータに***pcie_acs_override=downstream,multifunction***の追加
私の環境では***multifunction***もないとだめでした。

```bash:GRUBの設定
	# vi /etc/default/grub
		:
		GRUB_CMDLINE_LINUX_DEFAULT="amd_iommu=on iommu=pt pcie_acs_override=downstream,multifunction"
		:
	# update-grub
```
確認のため**再起動**
再起動後、1PCIデイバス,1IOMMUグループ(ほぼ)になるはずです。

##vfioデバイスドライバ設定
**参考:https://github.com/pavolelsig/passthrough_helper_ubuntu**

```bash:vfioドライバ設定スクリプト
	# vi /etc/modprobe.d/vfio-pci-override.sh
		#! /bin/sh
		#
		# パススルーしたいベンダID:デバイスIDを設定
		export DEVICE="8086:24FB"
		#
		for i in $( find /sys/devices/pci* -type f -name uevent -print ); do
			for j in ${DEVICE}; do
				grep -l $j $i && echo "vfio-pci" > $(busybox dirname $i)/driver_override
			done
		done
		modprobe -i vfio-pci
	# chmod +x vi /etc/modprobe.d/vfio-pci-override.sh
```

```bash:Wifiドライバ無効化とvfioドライバ設定スクリプト呼び出し設定
	# vi /etc/modprobe.d/vfio-pci-override.conf 
		blacklist iwlwifi
		install vfio-pci /etc/modprobe.d/vfio-pci-override.sh
```
```bash:vfioドライバ設定
	# cat /etc/modules-load.d/vfio-pci-override.conf 
		vfio-pci
		:
	# update-initramfs -u
```
**再起動**
これで仮想マシンに「PCIホストデバイスの追加」してやれば、Wifi IFがパススルーできるはず。
touchdsignerで鏡や水のような反射を表現するには、

**ウユニ塩湖**をご存じでしょうか。
ウユニ塩湖は南米にあるその名の通り塩分の高い湖で観光スポットとして大有名！
湖が空を**反射**し宙に浮いてるかのような幻想的な写真を撮ることができます。
これを聞いたそこのあなた！

今こう思いましたよね？

**おい、これtouchdesignerで実装できねーのかよ！**

落ち着いてください
正確ではありませんが疑似的に実装しましょう（笑）
#reflection
今回作るものは、こちら！！
![reflection_thumbnail.0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704869/c83e2366-e9e8-8648-dc77-015b3bb5d2df.jpeg)
まあまあきれいじゃない？

正八面体と反射する床、`sphere map(inside)`を貼ったsphereで構成されています。
このチュートリアルは、動画で見てもらったほうが早いと思うんで以下のリンクから**youtube**に飛んでいきますのでそちらからどうぞ！
[![youtube_link.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704869/ba5e13fa-c73c-4d56-95b1-e2b752798b0d.jpeg)](https://www.youtube.com/watch?v=toObgrxKTlU)


#解説
##ふたつのカメラ
EXILEの歌でふたつの唇って曲ありましたね、カラオケ行ったら十九番として歌います。
そもそもカメラ(目)から見た**反射**がどういう風になっているのかを考えます
たぶんこう、
![camera_reflection.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704869/c0e8bd79-8b57-eaab-9ddf-9e522c5a82a2.jpeg)

このreflectionとして映る景色が板のジオメトリ(`gridSOP`)を介して見ているわけです。
ちゅーことは、この景色(`reflection`)を見るカメラ(目)があればいいってことなんで
**カメラをもう一個置き、反射カメラ**と呼ぶことにします。

名前からして「カメラ回してないやろな？」と脅しが来そうですが、
**今回は回してください。**
反射する景色を映すように位置と回転を設定します(**Y軸反転、Z軸に180°回転**)。
`geometry viewer`で確認すると、確認できましたね
`NullCOMP`作ってカメラの`LookAt`に入れましょう。
これで、同じ場所を見る対称なカメラたちができました。いぇい！
![twoCamera.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704869/b9baa4f7-0f55-247c-c919-a57a40f1c587.png)


##textureの貼り付け
今回反射を実装している板、`gridSOP`について解説していきます。
まずは`textureSOP`にて反射カメラからの画角を投影するように下記のように設定しています。
![textureSOP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704869/3804e9c9-7e4b-2c99-1b85-ec9c1e70c05c.png)


そして`renderTOP`にて**本物のカメラと反射カメラからの画角を分けます。**
反射カメラのほうだけ、textureを貼るgridはレンダリングしないでください。
景色見えなくなっちゃいますからね。
そしたらそのTOPをgridの`PBRマテリアルのEmit Map`に貼りましょう。`Emitの値`を大きくすると
ほら、
見えてきましたね。
![emitMAT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704869/536c655a-a1ad-aafb-56c6-c64c6034ccc0.png)


#作品例
このgridにより水っぽく見せるために**波紋**を追加したものがこちらからリンク飛べます
[![「touchdsignerで鏡や水のような反射を表現するには、」を編集 - Qiita - Google Chrome 2021_02_21 21_50_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704869/35f8a87f-043a-f86e-dac1-568ce3c07f69.png)](https://www.instagram.com/p/CKOgfXLh0UT/?utm_source=ig_web_copy_link)


**やり方知りたい！！**と思った方はDMしてくだせえ
**こんなんできるわ！われい！**と思った方はフォローしてくだせえ
ほな!
go testで"go: cannot find main module; see 'go help modules'"が出てきたとき

Goのバージョンをアップデートした後にgo testを実行したら，

```
go: cannot find main module; see 'go help modules'
```

と出てきて，先に進まない

調べてみると，GO111MODULEという環境変数が問題らしい
この環境変数が'on'になっているのが問題だと書いてあるところが多いのだが，私の場合は何も入っていなかった
## 対処方法
GO111MODULEを'auto'と設定するとうまくいった

go1.13以降だと，go env コマンドに -w オプションを付けて環境変数を設定できる

```bash
go env -w GO111MODULE=auto
```

ok.

## 参考文献
[Go 言語の環境変数管理](https://text.baldanders.info/golang/go-env/)
[VSCodeでGo開発、”cannot find main module;”](https://www.takunoko.com/blog/vscode%E3%81%A7go%E9%96%8B%E7%99%BA%E3%80%81cannot-find-main-module/)
RaspberryPi/Ubuntuで3相ブラシレスDCモーターを制御する

DIY自動運転車用のインホイールモーターを動かすための練習で、まずは小型のブラシレスモーターを動かしてみる。

参考：
https://shizenkarasuzon.hatenablog.com/entry/2019/03/04/002326
[ブラシレスモータをRaspberry PIやArduinoで制御してみる](http://mimono.wpblog.jp/2016/03/10/%E3%83%96%E3%83%A9%E3%82%B7%E3%83%AC%E3%82%B9%E3%83%A2%E3%83%BC%E3%82%BF%E3%82%92%E3%83%A9%E3%82%BA%E3%83%99%E3%83%AA%E3%83%91%E3%82%A4%E3%81%A7%E5%88%B6%E5%BE%A1%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B/)

# 物品
ブラシレスDCモーターはアマゾンで1000円くらい。
https://www.amazon.co.jp/gp/product/B01DBGY6OA/

ESCも700円くらい。30A。
https://www.amazon.co.jp/gp/product/B016MNN7EE/

# 配線
ラズパイのGPIO-4、GNDに接続。その他は適当にギボシ端子で結線。
![IMG_5215.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80263/5b0fc6c1-75b5-fa14-a929-a1d3ff7c10b1.jpeg)
![quad_motor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80263/20eb6b17-6bba-8319-fc61-a6a653fcb98e.png)

# pigpioのインストール
ラズパイのGPIOでPWM制御をするためのライブラリ。
公式サイトに従ってインストール。
http://abyz.me.uk/rpi/pigpio/download.html

```
wget https://github.com/joan2937/pigpio/archive/master.zip
unzip master.zip
cd pigpio-master
make
sudo make install
```

デーモンも稼働させておく。

```
sudo pigpiod
```

# Pythonコード
```python
import time
import pigpio
motor_pin = 4

pi = pigpio.pi()

pi.set_servo_pulsewidth(motor_pin, 2000)
print("max")
time.sleep(2)
pi.set_servo_pulsewidth(motor_pin, 1000)
print("min")
time.sleep(3)

for i in range(3):
        pi.set_servo_pulsewidth(motor_pin, 2000)
        time.sleep(2)
        pi.set_servo_pulsewidth(motor_pin, 1200)
        print("1200")
        time.sleep(2)

pi.set_servo_pulsewidth(motor_pin, 0)
pi.stop()
```

モーターが無事回った。もっと低速で回したいが、モータースペックのためか、1000以下だとうまく回らず。
SAP DataWarehouseCloudを触ってみた①　〜テーブル作成,CSVインポート〜

#はじめに
業務の中でSAP Data Warehouse Cloudに携わる機会があったので
Trialを使用し、実際に触ってみた内容をまとめました。
#１．スペースの作成
下記サイトを、参考にSAP Data Warehouse Cloud の Free Trialの登録、
スペースの作成、ユーザ追加を行います。
[はじめてのSAP Data Warehouse Cloud : Part 1～ Free Trial環境でSAP Data Warehouse Cloudを体験してみよう !! ](URL"https://blogs.sap.com/2020/05/26/%E3%81%AF%E3%81%98%E3%82%81%E3%81%A6%E3%81%AEsap-data-warehouse-cloud-part-1-%EF%BD%9E-free-trial%E7%92%B0%E5%A2%83%E3%81%A7sap-data-warehouse-cloud%E3%82%92%E4%BD%93%E9%A8%93%E3%81%97%E3%81%A6/")
#2.CSVのインポート
左のメニューの「Data Builder」をクリックし、作成したスペースをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656065/39e86499-e870-1e35-bd5f-7a76abe216f1.png)

「Import」メニューから、「CSV Import File」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656065/a225e906-680b-dff2-9161-a43031288b45.png)

「Select Source File」をクリックし、ローカルからインポートするファイルを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656065/3488b279-340c-a9ac-181d-56f05e564e4e.png)

「Upload」を選択します。
※「Use first row as column header」にチェックを入れると、CSVの1行目をカラム名として認識してくれます。
※「CSV Delimiter」のコンボボックスで、CSVの区切り文字を設定することが可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656065/25d3c39a-2ad7-4b43-2b89-d8819f6e709e.png)
「OverView」からキューブマークをクリックし、各項目の型の設定を行ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656065/5c2d2cf0-760c-898a-c084-793797523efb.png)
・Column Detail：カラム名の変更ができます。
・Date Type：Columnの型を設定できます。
（設定可能な型：Date,Integer,Number,String,Time,Date and Time,Boolean）
・Set as Key：チェックを入れることで、主キーに設定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656065/d6cb8e41-4de8-599c-0729-ca7d91c3a0a8.png)
全ての項目の型の設定後、「Deploy」ボタンをクリックし、テーブルの「Business Name」と「Technical Name」を入力し「Deploy」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656065/e0411a1f-9233-1400-e5a5-a7c32d079c1a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656065/23781229-b6d7-f354-fb83-716105288e72.png)

デプロイが完了後、テーブル一覧に作成したテーブルが表示されます。
表示されているテーブルをクリックし、テーブル設定画面に遷移します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656065/5f162685-ba41-35f5-9c93-982579be46b8.png)

「Table Services」＞「In-Memory Strage」のチェックを入れ、
画面上部の「Save」アイコンをクリックし保存後、「Deploy」アイコンをクリックしデプロイします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656065/42fc27fc-6bb2-40ea-287f-86e89648a479.png)
pip installに失敗した時の対処法(ERROR: Command errored out with exit status 1:)

t-SNEを試すためにbhtsneをインストールしようとして失敗しました。
#使用環境
- Mac OS Big Sur
- Anaconda

#エラー内容

```:入力
!pip install bhtsne
```
```:出力
Using cached bhtsne-0.1.9.tar.gz (86 kB)
Requirement already satisfied: numpy in /Users/apple/opt/anaconda3/envs/Test1/lib/python3.8/site-packages (from bhtsne) (1.19.2)
Requirement already satisfied: cython in /Users/apple/opt/anaconda3/envs/Test1/lib/python3.8/site-packages (from bhtsne) (0.29.22)
Building wheels for collected packages: bhtsne
  Building wheel for bhtsne (setup.py) ... error
  ERROR: Command errored out with exit status 1:
......
(省略)
......
　error: command 'gcc' failed with exit status 1
```

#解決策
原因はXcodeのセットアップツールがインストールされていないことだったようです。
Xcodeを起動してインストールするか、Terminalで```xcode-select --install```を入力・実行する。
私は後者を実施して解決しました。
routingをドメインごとに切り替える

まず任意のドメイン名を追加します。
参考リンク
・https://qiita.com/tatsumin0206/items/8b4d0930c0f58cef7813


##ホスト名に制約を加える
設定ファイルが自動的に読み込まれるようにconfig/initializerにhosts.rb(任意)を作成。

```
Rails.application.configure do
  config.admin1 = {
    admin: { host: "admin.example.com", path: "" }
  }
end
```

admin1というキーに対し、ハッシュをセットしています。

これを参照するには次のように書きます。

```
Rails.application.routes.draw do
  constraints host: config[:admin][:host] do
    namespace: :user, path: config[:admin][:host] do
      root "top#index"
      resources :session, only: [:create, :destroy]
    end
  end
end
```
 constraintsは**指定されたホスト名のみ**のアクセスを許可しています（ホスト名による制約）
 namespaceでホスト名へのパスを設定しています。

namespaceを設定した時は以下の３つが追加されます。
1.URLのパスの先頭にadminが追加される
2.コントローラーの先頭にadminフォルダが付加される
3.ルーティングの先頭にadminが付加される




#Rspecでのテストを実行
```
require "rails_helper"

describe "ルーティング" do
  example "管理者トップページ" do
    
    config = Rails.application.config.admin1 
    url = "http://#{config[:staff][:host]}/#{config[:staff][:path]}"
    expect(get: url).to route_to(
      host: config[:staff][:host],
      controller: "staff/top",
      action: "index"
    )
  end
end

```
簡単に解説します。

```
config = Rails.application.config.admin1
```
設定したファイルをconfigに代入しています。


```
url = "http://#{config[:admin][:host]}/#{config[:admin][:path]}"
```
②で設定したハッシュのキーをurlに指定しています。

```
 expect(get: url).to route_to(
      host: config[:admin][:host],
      controller: "admin/top",
      action: "index"
    )
```

route_toはルーティングの**マッチャー**です。
getリクエストでroute_to以下をハッシュで指定しています。
このホストにgetリクエストを送るとstaff/topコントローラーが指定され、indexアクションが働くという意味になります。


参考文献
Ruby on Rails6実践ガイド