OmniAICreator/Qiita-1.07M huggingface dataset:
【備忘録】deviseの導入

# deviseとは？
Railsアプリケーションに認証機能（ユーザー登録機能、ログイン機能、ログアウト機能）を実装することができるgemです。数回のコマンドを実行するだけで簡単に認証機能を実装することができます。

# 導入の流れ


### １. Gem導入
Gemfileに追記。

```Gemfile.
gem 'devise'
```

bundle install実行。

```
bundle install
```


### 2. インストール
アプリケーションにdeviseをインストール。ここは忘れがちなので注意！

```
rails g devise:install
```


### 3. Userモデルの作成
```
rails g devise user
```

モデル作成と同時に、マイグレーションファイルやルーティングも自動的に作成されます。


### 4. 必要に応じてカラムを追加
deviseを介してモデルを作成した場合、emailとpasswordはデフォルトで用意されているので、他に必要なカラムがある時は追加します。


### 5. マイグレーション実行
マイグレーションファイルの内容をテーブルに反映させます。

```
rails db:migrate
```


### 6. ビューの作成
新規登録・ログイン用のビューを作成します。

```
rails g devise:views
```

こんな感じのビューが出来上がります⬇️

#### 新規登録画面
[![Image from Gyazo](https://i.gyazo.com/c60ada275bd2805915fe6f50db75b202.png)](https://gyazo.com/c60ada275bd2805915fe6f50db75b202)


#### ログイン画面
[![Image from Gyazo](https://i.gyazo.com/39fb4576be2b37fb4b530223da3160a7.png)](https://gyazo.com/39fb4576be2b37fb4b530223da3160a7)
Linux netstat

#【Linux netstat】

CentOS 7 以降では、netstatは非推奨であり、ss（socket statistics）が推奨。
netstatとssに大きな違いはない。

##netstatコマンド

<strong>TCP/IP関連のトラブルシューティング</strong>

主にTCPの通信状態を調べる。
UDPのサービスポートやUNIXドメインソケットの状態、ルーティング情報なども調べる。

###netstatのオプション

```bash
-a （--all） 　      すべてのプロトコルを表示
-l （--listening） 　接続待ちのソケットを表示
-n （--numeric） 　  ホスト、ポート、ユーザなど名前を解決せず、数字のアドレスで表示
-p （--program） 　  ソケット、ポートをオープンしているプログラムのPIDと名前を表示
-r （--route） 　    ルーティングテーブルを表示
-s （--statistics）　統計情報を表示
-t （--tcp） 　      TCPソケットを表示
-u （--udp） 　      UDPソケットを表示
-x （--unix） 　     UNIXソケットを表示

※オプションなしは、TCPポートのLISTEN以外のESTABLISHEDなどの状態とUNIXドメインソケットの状態を表示
```
SAMを使った環境毎のデプロイ方法のまとめ


### はじめに

SAMを使ったサーバーレス環境の構築時に、1つのtemplate.yamlを使って、develop, staging, production毎に環境変数を切り替える方法を忘れるため、備忘もかねて記事にしました

### 目的

SAMのtemplateを使って、各環境毎に変数値を変えてlambdaを実行できるようにする

### どうやるのか?

SAMテンプレートの中の、ParametersとMappingsを使うと、一つの環境変数でKey-Value方式で、複数の値を切り替えることができる

### 実例

まず、ParametersとMappingを記述する

```yaml
Parameters:
  Environment:
    Type: String
    AllowedValues:
      - development # 開発環境
      - staging # ステージング環境
      - production # 本番環境
    Default: development

Mappings:
 EnvironmentMap:
   development:
     HELLO: 'developmen Hello World'
   staging:
     HELLO: 'staging Hello World'
   production:
     HELLO: 'production Hello World'
```

それを使いたい時は、以下のように指定すれば、環境変数がKeyになり、Valueが取得できる

```yaml
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs12.x
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get
      Environment:
        Variables:
          SAMPLE_ENV: !FindInMap [ EnvironmentMap, !Ref Environment, HELLO]
```

### 動作確認

```bash
# ビルド
sam build

# 実行
sam local start-api --parameter-overrides Environment={書き換えたい環境変数}
```

アクセスして確認する

```
curl 'http://localhost:3000/hello'
```

### CI/CDをどうするか？

CIに関しては、一つのtemplate.yamlをビルドするだけで良い
CDの時に、 `--parameter-overrides` を使って、Parametersを書き換えてデプロイするフローになる

```bash
❯ sam deploy --guided

Configuring SAM deploy
======================

        Looking for config file [samconfig.toml] :  Found
        Reading default arguments  :  Success

        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [SAMPLE-ENV]: 
        AWS Region [ap-northeast-1]: 
        Parameter Environment [staging]: ← ここで使いたい環境を指定するだけで良い
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
---- 省略 ---- 
```



### まとめ

かなり雑にまとめてしまいましたが、templateのParametersだけを使う場合だと、環境変数が多くなると管理が大変になるので、Mappingsを活用すると使いたい環境を指定するだけで、セットアップができる

誰かのご参考になれば幸いです
laravelでフォローしたユーザーの投稿を取得する

フォローしたユーザーの投稿を取得します
以下にテーブル構造やモデルの設定を簡単に示しておきます

以前にもフォロー機能作成記事を書いているので詳しくはそっちで
https://qiita.com/mitsu-0720/items/0c2fcdd367e8a6c5999c

```XXXX_XX_XX_XXXXXX_create_follow_users_table.php

 Schema::create('follow_users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('followed_user_id')->index();
            $table->unsignedBigInteger('following_user_id')->index();
            $table->foreign('followed_user_id')->references('id')->on('users')->onDelete('cascade');
            $table->foreign('following_user_id')->references('id')->on('users')->onDelete('cascade');
            $table->timestamps();
        });

```

```User.php

// フォロワー→フォロー
    public function followUsers()
    {
        return $this->belongsToMany('App\User', 'follow_users', 'followed_user_id', 'following_user_id');
    }

    // フォロー→フォロワー
    public function follows()
    {
        return $this->belongsToMany('App\User', 'follow_users', 'following_user_id', 'followed_user_id');
    }

```

```PostController.php

public function timeline() {
        $posts = Post::query()->whereIn('user_id', Auth::user()->follows()->pluck('followed_user_id'))->latest()->get();
        return view('posts.timeline')->with([
            'posts' => $posts,
            ]);
    }

```

$posts = Post::query()->whereIn('user_id', Auth::user()->follows()->pluck('followed_user_id'))->latest()->get();
について

日本語で解説してみると
Post：：query()　ポストモデルの中の
whereIn('user_id')　user_idが
Auth::user()->follows()->pluck('followed_user_id')　自分がフォローしているユーザーの中でフォロワーが自分であるユーザーを取得して
latest()->get()　最新順に取得する

といった感じになります

whereInはまだ自分も理解が浅いのですが第二引数が配列となる場合はこっちを使わないと想定した結果を取得できないイメージ
今回みたいに条件指定が複雑な場合はwhereよりwhereInを使った方がいいと思います
実際このtimeline()関数もwhereだと何も取得できませんでした

pluckメソッドは引数の値だけを取得できるメソッド
今回はフォローしてるユーザーのIDだけを取得したかったのでpluck('followed_user_id')でIDのみを取得しています

つまり今回自分がuser_id１、２、３のユーザーをフォローしているとすると上の関数は
Post::query()->whereIn('user_id', [1,2,3])->latest()->get();
といった意味を持ちます

##ハマった点

以前自分が書いたメソッドはこう

```PostsController.php

$posts = Post::query()->whereIn('user_id', Auth::user()->follows()->pluck('following_user_id'))->latest()->get();

```

フォローしてるユーザーのIDが欲しいんだから取得するのはfollowed_user_idではなくfollowing_user_idや！
と思ってdd($posts)してみたところ取得されたのは自分自身の投稿のみだった

当時は、は？？？？？？？？？？？？？なんで？？？？？？？？？？？？？？？？？？
ってなってましたが今考えればそれもそのはず

フォローユーザーは自分なのだからフォローしているユーザーのidを取得しても自分のIDしか取得できないのだ

##まとめ

フォローしているユーザーの投稿を取得したいのだからフォロワーのIDなんか使わないだろうと頭でっかちになって考えていたが
「フォロワーが自分であるユーザー」を取得することにより結果的に「自分がフォローしているユーザー」を取得できるという結論になったのはいい経験になった
プログラミングの面白さをしれたいい経験でした

##おまけ

「フォローしているユーザー」+「自分自身」の投稿を取得したい場合

```PostsController.php

$posts = Post::query()->whereIn('user_id', Auth::user()->follows()->pluck('followed_user_id'))->orWhere('user_id', Auth::user()->id)->latest()->get();

```
GNOME screenshot の保存フォルダを変える(できないかも)

バージョンごとにやり方が違ってめんどいです

https://askubuntu.com/questions/114429/how-can-i-specify-the-default-save-directory-for-gnome-screenshot

18.04 以降は dconf での設定は反映されず, extension を使うことになりそうです(が, 18.04.5 ではうまくいかなかった)

https://extensions.gnome.org/extension/1179/screenshot-locations/
error TS1086: An accessor cannot be declared in an ambient context.

ng s --o実行時に「 error TS1086: An accessor cannot be declared in an ambient context.」というエラーが発生。

＠ng-bootstrapとのバージョンに互換性が無かったので下記コマンドでAngularをupdate。

```
ng update angular/core@{{更新後のバージョンナンバー}} angular/cli@{{更新後のバージョンナンバー}}
```

*
「--force」「--allow-dirty」が必要なケースもあります。

[参考]
https://stackoverflow.com/questions/60131331/error-ts1086-an-accessor-cannot-be-declared-in-an-ambient-context-in-angular-9

https://angular.io/cli/update
【Vue.js】基本的なディレクティブまとめ

#はじめに
**``Vue.js``**で使用する基本的なディレクティブをまとめました。
[Vue.js v3.0](https://v3.vuejs.org/api/directives.html)の公式ドキュメントを参考としています。

V-onやV-bindは様々な使用法があるため、詳細は今後の記事で書きます。

#V-text

```html
<span v-text="message"></span>
<!-- 両者同様 -->
<span>{{　message　}}</span> Hello Vue!
```

以下のように文章の一部をプロパティで表示したい場合は`”Mustache” 構文(二重中括弧)を利用`することが推奨されています。

```html
<span>Message: {{ message }}</span>
```

```javascript
const app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!',
  },
});
```

#V-html
DOM 要素の内側を innerHTML として書き換えます。
v-html には XSS の危険性があるため信頼できるコンテンツだけに利用します。

```html
<div v-html="html"></div>
```

```javascript
var app = new Vue({
  el: '#app',
  data: {
    html: 'Hello <strong style="color: red">Vue!</strong>',
  },
});
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512863/491db26e-4272-231e-0bec-d6a0dfa3f7f3.png)

#V-show
参照する値が true として評価され場合は表示し、false として評価される場合は display:none 等のスタイルが付いて非表示になります。

```html
<h1 v-show="hello">Hello!</h1>
```

```javascript
const greeting = new Vue({
  el: '#app',
  data: {
    hello: 1,
  },
});
greeting.hello = 1; // Hello!
```

#V-if
バインドした値が true 評価であれば DOM 要素が生成され、false であれば破棄されます。

```html
<h1 v-show="hello">Hello!</h1>
```

```javascript
const greeting = new Vue({
  el: '#app',
  data: {
    hello: 1,
  },
});
greeting.hello = 1;
```

# `v-if`と`v-show`の違い

v-if は初期表示において`false`の場合、何もしません。条件付きブロックは、条件が最初に`true`になるまで描画されません。

一方、`v-show`ではは要素は初期条件に関わらず常に描画され、シンプルな`CSSベースの切り替え`として常に要素が DOM に保存されます。

一般的に、`v-if`はより高い切り替えコストを持っているのに対して、 `v-show`はより高い初期描画コストを持っています。 そのため、切り替えの頻度が低ければ`v-if`切り替えの頻度が高ければ`v-show`という使い分けをします。

#V-else

`v-if`の後続分岐処理として`v-else`を使用できます。

```html
<div v-if="Math.random() > 0.5">Hello!</div>
<div v-else>Morning!</div>
```

#V-else-if

```html
<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else-if="type === 'C'">C</div>
<div v-else>Not A/B/C</div>
```

#V-for
このように v-for を用いて numbers の各要素を仮変数（エイリアス）num として取り出して、num を li 要素の内部に入れて表示させることができます。

```html
<div id="app">
  <ul>
    <li v-for="num in numbers">{{ num }}</li>
  </ul>
</div>
```

```javascript

new Vue({
  el: "#app",
  data: {
    numbers: [
      1, 2, 3, 4, 5
    ]
  });

```

#V-on
DOM要素にイベントリスナーを登録できます。

```html

<div id="app" v-on="click: alert">ClickHere!</div>
```

```javascript

new Vue({
  el: "#app",
  methods: {
    alert: function(){
         alert('clicked!');}
  });

```

#V-bind
aタグのhref属性やimgタグのsrc属性などを動的に変更することができます。

```html

<img v-bind:src="imageSrc" />
<!-- 省略記法 -->
<img :src="imageSrc" />

```

```javascript

new Vue({
  el: "#app",
  data: {
    imageSrc: "http://example/example"

```

#V-model
HTMLのinput要素やselect要素などのユーザーが入力した値を受け取りたい場合、v-bindディレクティブを用いることで実現しますが、``v-model``を使うことでより簡潔に書くことができます。

```html:v-bindとv-onを使った場合
<div id="app">
   名前をここに入力する
    <input  v-bind:value="name"  v-on:change="name = $event.target.value" />
</div>
```

```html:v-modelを使った場合
<div id="app">
   名前をここに入力する
    <input v-model:value="name"/>
</div>
```

```javascript
new Vue({
   el: "#app",
   data: {
       name: ''
   }
})
```

#参考
[Vue.js Directives](https://v3.vuejs.org/api/directives.html)
Svelteで複数のページを管理する ~SPA~

# 概要

最近触ったSvelteで複数のページを管理したいときはどうすればいいのか調べて理解したことをまとめてみました

> 「SPA」=「Single Page Application」を最近知りました😇

# 準備

spaの実装に必要なライブラリをインストールします

```bash
npm install svelte-spa-router
```

# 作るもの

spaの実装の仕方を理解するためにごく簡単なものを作ります

トップページ

![Screen Shot 2020-12-07 at 21.18.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/0d432e73-813a-9559-e416-18b136f9f736.png)

helloの部分をクリックすると

![Screen Shot 2020-12-07 at 21.19.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/cddfc374-a8c7-9341-c6e2-79566b5169c7.png)

「Hello,」のみが表示されてパスが「/」→「/#/hello」に変わる

# 実装 ~コンポーネント~

コンポーネントで意識するのは

- `svelte-spa-router`の`push`をimportして
- 画面遷移をさせたいイベントで`push`を呼び出す
- `push`の引数には遷移時のパス（「/#/hello」の「/hello」にあたる部分）を指定する

作るコンポーネントは

- Hello：「Hello,」を表示
- Svelte：「Svelte！」を表示
- Home：「Hello, Svelte!」を表示（HelloとSvelteコンポーネントの表示）

```html:Hello.svelte
<script>
    import { push } from 'svelte-spa-router'
</script>

<div on:click={() => push('/hello')}>Hello,</div>
```

```html:Svelte.svelte
<script>
    import { push } from 'svelte-spa-router'
</script>

<div on:click={() => push('/svelte')}>Svelte !</div>
```

```html:Home.svelte
<script>
    import Hello from "./Hello.svelte";
    import Svelte from "./Svelte.svelte";
</script>

<Hello/><Svelte/>
```

# 実装 ~ルーティング~

ルーティングは`App.svelte`で実装してみます

実装ポイントは

- パスとコンポーネントのmapを作成し（ここでいうroutes）
- `Router`タグに`routes`プロパティとして引き渡す

```html:App.svelte
<script>
    import Router from 'svelte-spa-router'
    import Home from "./components/Home.svelte";
    import Hello from "./components/Hello.svelte";
    import Svelte from "./components/Svelte.svelte";

    const routes = {
        '/': Home,
        '/hello': Hello,
        '/svelte': Svelte,
        '*': Home
    };
</script>

<Router routes={routes}/>
```

これで完成！！！🙌 🙌 🙌
ラグランジュの補間多項式をプログラミングで解いてみる

#概要
#####ラグランジュの補間多項式
ラグランジュの補間多項式は、点`(x, y)`が与えられたとき、その点を通るn次関数の式を求められます。
#####プログラムについて
今回作成したプログラムは、与えられた点`(x, y)`について、それぞれが対応するリストを作成し、それらを基に関数`f(x)`を導くプログラムになります。
`f(x)`を求める際、`x`を不定元として認識させる必要や、式を簡易化する必要があるため、`sympy`というパッケージを利用します。

#プログラム
```Lagrange.py
# -*- coding: utf-8 -*-
#!/usr/bin/env python3
import sympy

X = [-2, -1, 3]
Y = [4, 1, 9]

def ragrange (lx, ly):
    x=sympy.symbols('x')
    f = 0
    for i in range(len(lx)):
        z = 1
        for j in range(len(lx)):
            if j != i:
                z = z * ((x - lx[j]) / (lx[i] - lx[j]))
        f += z * ly[i]
    return sympy.simplify(f)

print("f(x) =",(ragrange(X,Y)))
```

#実行結果
はじめに、上のプログラムで示したデータ`X, Y`で実行します。
このデータは`f(x)=x**2`の内の3つの点を抜粋したため、`f(x)=x**2`が正しい答えとなります。

```
X = [-2, -1, 3]
Y = [4, 1, 9]

#結果
f(x) = x**2
```
次に適当な4つのデータを与え3次関数を求めてみます。

```
X = [-3,-2, -0, 1]
Y = [-6,-1, -3, 2]

#結果
f(x) = x**3 + 3*x**2 + x - 3
```

#まとめ
(n+1)個のデータを与えることでn次関数が求めることができました。

#おわりに
今回の記事はここまでになります。
質問・アドバイス等あればコメント欄にてお願いいたします。
最後までお付き合い頂きありがとうございました。
Providerを3本書いて思ったこと

これは [terraform Advent Calendar 2020 - Qiita](https://qiita.com/advent-calendar/2020/terraform) の12/8(火)の記事です。

## TL;DR;

APIを操作するなら、独自スクリプトよりTerraformのCustom Providerを書こう！

## 課題・背景

**Go書きたい！** という思いと、 **OpenAPI(Swagger)分かる！** という自信から、APIに関するサーバかクライアントを書いていくかぁと考えました。
その中でAPIを操作すると言ったら、Terraformでしょってことになりました。

つまり、`Go書きたい！ x OpenAPI(Swagger)分かる！ = Terraform Custom Provider 書く！！`

なので、○○な課題や問題があってその解決のためにTerraformを使ったとかではありません。

それと、上記の思いの中で初めてTerraformを触ったので使い方にめちゃめちゃ詳しいとか言う訳でもありません。
何かのIaCをやるためのTFファイルを書いた行数よりも、Providerを書いた行数の方が多いです。

## どうだったのか

その時にちょうど自分が使う社内ツールのAPIを題材に、1つ目のProviderを書いてみました。
内容は「[Implement Create | Terraform - HashiCorp Learn](https://learn.hashicorp.com/tutorials/terraform/provider-create?in=terraform/providers)」をやった程度です。

結果、 **Terraform Custom Providerって簡単に書けるんだなぁ** って感じと **Terraformってめっちゃ便利じゃん** って感じでした。

## 2〜3本目とProviderを書いてきて

こちらも懲りなく社内ツールのAPI向けにProviderを書きました。
こっちは元々独自のスクリプトでAPIを操作できていたのですが、起動オプションだったりが覚えられなくて、Providerで書き換えました。

結果、個人的に **カレントディレクトリにTFファイルがあればAPIを操作できるので簡単で良い** 感じでした。

## まとめ

Providerを3本書いて思ったことは、独自スクリプトでAPIを操作するよりもTerraformProvider化することでメリットが多々あるぞ、と言うことです。

### メリット

- 起動オプションが要らなくなる
- 設定ファイル(TF)が構造化されてわかりやすい
  - TFファイル自体もバージョン管理できる
- Terraformという仕様に従うので、 **他の人も仕様を把握しやすい**
- 仕様に従うとやれることが限られるので、 **変な作り込みも減る**
  - 実はここが大事だと思っていて、独自スクリプトで便利そうだと思い頑張って作った機能が実はあまり使われないなんてことがよくあるが、それを防止できる

### デメリット

- 新規で作る場合はいいが、車輪の再開発になるのでコストと相談

## 余談

Terraformの `0.12` 系を使っていたが、 `0.13` 系からProvider周りの変更が入り動かなくなったので早くどうにかしないといけない（この辺はこれが本業ではないので、疎かにしている）
QGISで3D巨大都市（の一部）を召喚する

## はじめに

![mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203944/51c2b589-0db4-bfbf-e561-791a9b5883fa.gif)

皆さんはふとした瞬間に「あっ、３Dでベル・ハーバー召喚してーな」って思うことありますか？

僕はありません。

いやいや、そもそもそれなんやねんっていう声が聞こえてきますが

それっ!!!

![mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203944/59c263e7-8368-4a84-3dce-53134d734849.gif)

ここ！ベルハーバー！！！

![](https://i.imgur.com/bXFoXkF.png)

この辺らしいです。

## 何召喚すんの

今回はCityGMLという形式のファイルを取り扱って、このあたり一帯の建物をQGIS上に召喚していきます。

CityGMLはOCG（Open Geospatial Consortium）標準規格で3D都市モデルの標準データ形式になりますが、都合よく各国のオープンなCityGMLのデータを取り扱っているサイトがありますので[こちら](https://3d.bk.tudelft.nl/opendata/opencities/)から拝借してきましょう。

今回はこの中からNYのデータを選択していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203944/37bb16ae-5af9-617f-c425-29ae4bf2718d.png)

クリックすると以下のページに飛ぶと思いますので、CityGMLを選択してダウンロードしていきましょう。
（※zip圧縮時：約900MB、解凍後：約20GBとインパクトのあるデータなので取り扱いに注意しましょう！）

https://www1.nyc.gov/site/doitt/initiatives/3d-building.page
![](https://i.imgur.com/4DtC8qy.png)

ダウンロードしたzipを解凍して`.../DA_WISE_GML/DA_WISE_GMLs/`フォルダに格納されている.gmlファイルがCityGML本体になります。

## CityGMLをCityJSONに変換する

意気揚々とCityGMLをダウンロードしたはいいものの、このままではQGISで読み込めないのでCityJSONに変換していきましょう。
（詳しくは[こちら](https://www.cityjson.org/about/)）

親切丁寧に公式変換ツールが用意されているので、ありがたく頂戴しましょう。

- [https://github.com/citygml4j/citygml-tools/releases](https://github.com/citygml4j/citygml-tools/releases) へアクセス
- 以下のファイルをダウンロードして解凍

![](https://i.imgur.com/6DTHL1f.png)

ダウンロードが終わったらツールの格納先ディレクトリに移動してツールを実行しましょう

```bash
% cd .../citygml_cesium_sample/tools/citygml-tools-1.4.1
% ./citygml-tools to-cityjson .../citygml_cesium_sample/assets/DA_WISE_GML/DA_WISE_GMLs/DA1_3D_Buildings_Merged.gml
```

Javaを利用したツールのようなので、インストールされていなければ`No Java runtime present, requesting install.`と怒られます。
そんな時は素直にJDKをインストールしましょう。

JDKのインストールが終了してプログラムを再実行すると、gmlと同ディレクトリに同名JSONが生成されます。

変換後のファイルサイズを見てみると約1/5まで圧縮されてだいぶ取り扱いやすくなりました。

- 変換前：250MB
- 変換後：50MB

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203944/972469f9-0fb0-8778-d5f5-e0c4b09b711f.png)

## QGISでCityJSONを召喚

ここまできたらあとはチョチョイのジョイやで。

偉大な先人がプラグインを作成なされておりますので`CityJSON Loader`を検索してをインストールしましょう。

![](https://i.imgur.com/hDuNmdj.png)

インストール後、CityJSONのアイコンをクリックしてプラグインを起動します。
（ベクタ→CityJSON Loaderでも良い）

![](https://i.imgur.com/tTaMmcg.png)

CityJSONを選択し、OKをクリックします。
（CRSとかは自動で読み込まれるはずなのでそのままで良いと思います。）

![](https://i.imgur.com/fMmEeDR.png)

この段階で建物データがポリゴンとしてレイヤに読み込まれていると思いますが、物足りないですね。

そうです。3Dです。

![](https://i.imgur.com/XuQZbii.jpg)

「ビュー→新しい3Dマップビューを選択」を選択して華麗に3次元表示していきましょう。

![](https://i.imgur.com/BFpuKNu.png)

![mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203944/51c2b589-0db4-bfbf-e561-791a9b5883fa.gif)


できた。すげぇ。

アメリカ全土のデータがあるっぽいので次は自由の女神とか召喚したい。

完
Photon×WebGL（3）Cubeを操作

###やりたいこと
・Cubeを方向キーで動かすとこまで

--

利用したバージョン
Unity 2020.1.9f1

--


<dl>
<dt>・移動させるスクリプト追加</dt>
<dd>・対象動画参照してコピペ14：50くらい</dd>
</dl>
```C#
    void Update()
        {
            float x = Input.GetAxis("Horizontal");
            float y = Input.GetAxis("Vertical");

            transform.position += new Vector3(x, y, 0);
        }
```
<dl>
<dd>・プレファブに動かすスクリプトをつける</dd>
<dt>・設定</dt>
<dd>・ネットワークオブジェクトにPhotonTransformViewを設定</dd>
<dd>・PhotonViewにドラッグドロップするのだけれど、入れれない時ObservavedSearchを「Manual」に変更してこじあける</dd>
<dt>・位置情報同期</dt>
<dd>・PhotonTransformViewはインスペクタの「transformPosition」のみをとりあえず同期させる</dd>
</dl>

![001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232643/6c6c10be-2d32-704a-770d-68efac24b814.jpeg)

<dl>
<dt>・実行すると同じ方向に動くエラーを解決する</dt>
</dl>
```C#
    void Update()
    {
        //ここに追加
        if (photonView.IsMine)
        {
```
--

![002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232643/892320f5-e97d-cd77-576a-862faa106a8e.jpeg)

--

次回：Cubeをオブジェクト（ゾンビ）に変更（★）
次回の次：1人称カメラ視点にトライ（★★）
次回の次の次：チャット（日本語入力対応）（★★★）

（対象動画）
[Unityでオンラインゲーム開発Photon Unity Networking 2の導入](https://www.youtube.com/watch?time_continue=12&v=S20gzSh14CM&feature=emb_logo)
accepts_nested_attributes_for メソッド：編集画面不具合の原因は。

[前回](https://qiita.com/HIROKOBA/items/35b636005311b8384278)に引き続きaccepts_nested_attributes_for メソッドについての記事です。Ruby on Rails を使っての開発になります。
####結論
「accepts_nested_attributes_for を使うときは、controller の strong parameter に注意。permit の中に関連づけたメソッドの id を追加しておく」という結論になります。

####起きていた現象
Railsで accepts_nested_attributes_for メソッドを使い作成したWebサービスにて。

index、new、show、deleteなどは問題なく行えるが、編集画面(edit, update)での挙動で異常が発生。[前回](https://qiita.com/HIROKOBA/items/35b636005311b8384278)の記事でいうと、編集画面を表示させるたびに、子メソッドの タイトル(title), 記事内容(content), ブログ番号(blog_num)がデーターベースに２重に登録され、同じ記事が２つずつ登録されてしまうのです。

####確認したこと
ヒントを探してターミナルを確認。すると、今回は早速それらしき内容が表示されていました。

>Unpermitted parameter: :id

これは、[以前の記事（画像アップロードでエラーメッセージの重要性を再認識した話）](https://qiita.com/HIROKOBA/items/152cb2b16295f4531244)と同じエラー、つまりstrong parameter で id という要素が許可されていないみたいです。

確かに、strong parmeter をチェックしても、、、

```user_controller.rb
  def user_params
    params.require(:user).permit(:name, :address, :age, blogs_attributes: [:title, :content, :blog_num])
  end
```

:id と言う記述をしていません。

####エラーを修正
不具合が発生しているのが子メソッドなので、strong parameter の小メソッド（blogs_attributes）の中に :id と言う記述を追加します。

```user_controller.rb
  def user_params
    params.require(:user).permit(:name, :address, :age, blogs_attributes: [:id, :title, :content, :blog_num])
  end
```
これで子メソッドの同じ記事が２回ずつ登録される不具合は解消しました。

####不具合の背景
この不具合、accepts_nested_attributes_for メソッドを使う場合に起こりがちらしいのですが、なぜこのような不具合が起きるのか、公式リファレンスの類にははっきりした解説のようなものはありませんでした。

私の調べた限り分かったことは「 accepts_nested_attributes_for を使用した場合、 パラメーターに :id が含まれているかどうかで create アクションか update アクションかが決まるらしい」ということです。

「update アクションの時にはパラメーターに id を含める」と覚えてしまうことで乗り切ろうと思います。

はっきりした原因を解説できるようになったら、またその時に解説記事を。
条件分岐　? : 　の使い方

#はじめに
この書き方を見た時に、こんな書き方もあるんや！って思ったが、
この書き方を調べてもわからなかった（？：と調べてもわからなかった）ので、自分なりに一旦まとめていこうと思います。
色々わかり次第、情報を追加していこうと思います。
#使われ方
`条件式　？　式か値①　：　式か値②`
説明すると、条件式がtrueなら？の後ろの①、falseなら：の後の②を実行すると言うもの。
#試してみた
switchを用意してisOnがtrueの時とfalseの時を比較して見た。

```swift
let switch1 = UISwitch()
let switch2 = UISwitch()

switch1.isOn = true
let number1 = 1 * (switch1.isOn ? 1 : -1)   //1 * 1が実行され、number1 = 1

switch2.isOn = false
let number2 = 1 * (switch2.isOn ? 1 : -1)   //1 * -1が実行され、number2 = -1
```

このように、trueの時に？の後が実行され、falseの時には：の後の処理が行われる。
【SAP BAS】Git ProjectからCloneする方法

SAP Business Application Studio(BAS)にて、Git リポジトリからプロジェクトをクローンする方法。
**まあようするに`Git Clone`しているだけ。**

今回は↓をクローンする。
https://github.com/Auggie9010/fiori_salesorder_list.git

開発スペースを作成し、何もないBASを立ち上げる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/0b56fe24-8f4c-3f85-c678-aece47fc9c3a.png)

Welcomeタブから`clone from Git`を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/ab72e326-98d9-de88-0512-6e850c01f900.png)

CloneしたいGitのURLをコピー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/bcaf66ac-6563-6423-a5f6-b4b5e0aaf061.png)

表示されたウインドウに↑でコピーしたURLを貼り付ける。
Terminalで以下のコマンドが走る。（最初からTerminalでコマンドを実行してもよい？）

```zsh
user: user $ git clone https://github.com/Auggie9010/fiori_salesorder_list $HOME/projects/fiori_salesorder_list/
Cloning into '/home/user/projects/fiori_salesorder_list'...
remote: Enumerating objects: 74, done.
remote: Counting objects: 100% (74/74), done.
remote: Compressing objects: 100% (55/55), done.
remote: Total 74 (delta 12), reused 70 (delta 11), pack-reused 0
Unpacking objects: 100% (74/74), done.
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/d0c6fc30-50a4-fe1a-0414-8d44b808a7e9.png)

コマンドが正常終了したら、`Open WorkSpace`をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/c313a94b-c136-6511-d073-c621905919cb.png)

プロジェクト名を選択してOpenをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/0bbd6185-5b74-7881-29a0-2f993db04947.png)

プロジェクトのファイルが展開される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378457/5871d80c-e192-467f-4eaf-a87f782f226f.png)

以上
畳み込みとプーリングについてのメモ

Pytorchを使ってDLを組んでるときに、畳込みとプーリングが曖昧な理解だった気がするので、
忘れたら見に来れるようにメモる
## 局所受容野

視覚野のニューロンが反応する範囲のことを受容野と呼ぶらしく、
ニューロンが入力のごく一部にだけ応答する性質を**局所受容野**というらしい
詳しい定義は[こちら](https://bsd.neuroinf.jp/wiki/%E5%8F%97%E5%AE%B9%E9%87%8E)

**局所受容野**のニューロンには２種類あり「単純型細胞」と「複雑型細胞」
この2つに対応してるのが**畳み込み**と**プーリング**
単純型細胞はイメージ通りある特定の形状に反応する細胞で、その形状がずれると反応しない
ただ、いろんな形状に対応した単純型細胞が連携すれば複雑な形状の物体を認識することができる。

一方の複雑型細胞は形状の空間的なズレを抜き取る。
単純型は形状が変わると別の細胞の形状になってしまう。
複雑型細胞は空間的な位置ずれを抜き取り、同一形状と見なせるように働く
そうすることで空間的な位置ずれがあっても同じ形状で認識することが可能

## 畳み込み層
まず大雑把にまとめると畳み込み層とプーリング層では入力のニューロンの一部の領域を絞り、限定的(局所的)に次の層へ対応付していきます。
畳み込み層は単純型細胞をモデルにし、この特定の形状に対応するように構成されており、**フィルター**と呼ばれる
例えば、数値を認識する際の手がかりは数値の直線や曲線であり、それを**フィルター**として設定する
ということは、フィルターの数が多いとそれだけ、様々な形状を持つことになる


畳み込みネットワークの構造は、最初の入力層で**画像の１ピクセルが１ニューロンに対応**し、
次に単純型細胞に相当する畳み込み層、そして複雑型細胞に相当するプーリング層と続く。
そのあとは、全結合層と出力層につながる。

- 局所受容野  
 - 単純型細胞 <-> 畳み込み　　 
 - 複雑型細胞 <-> プーリング

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/836394/1ff61762-d079-c58d-cefb-00ad9072a3e6.png)
>[引用元](https://www.imagazine.co.jp/%E7%95%B3%E3%81%BF%E8%BE%BC%E3%81%BF%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AE%E3%80%8C%E5%9F%BA%E7%A4%8E%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%80%8D%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99/)


フィルターと一部の入力画像を対応させて、そのフィルターが局所受容野に見つかれば畳み込み層のニューロンが発火する



入力層と畳み込み層の間の結合を数式で表すと、

```math
\sigma(b+\sum_{l=0}^{2}\sum_{m=0}^{2}w_{l,m}x_{{j+l}, {k+m}})
```

ｘが入力画像の各ピクセルの値、ｗが重み、ｂがバイアス、σが活性化関数
この数式のチューニング対象になるのは、wとbで、
NNと同様にCNNの出力値と正解の値との差が小さくなるようチューニングされる。

このｗはフィルタで、判別に必要な形状になっている。
フィルタを複数構成することで識別性能があがりやすい
なぜなら、特定の形状に対応したフィルタを複数持てるので、
より正しく識別できそうなのは感覚的にわかる。
各フィルタに対応する畳み込み層内のニューロンセットを**チャネル**という

畳み込みの計算方法についてわかりやすかった例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/836394/b36b18af-22ce-5466-804e-793663cf27f0.png)
[引用元](https://products.sint.co.jp/aisia/blog/vol1-16#toc-1)


## プーリング層

プーリング層は複雑細胞をモデル化したもの。
入力画像のフィルタ形状の位置ずれを抜き取る機能
目的は**特徴をより強調すること**
プーリング層の各ニューロンの出力が、畳み込み層のニューロンの出力値のなかで最大値を設定する
仕組みはプーリング層のニューロンの発火が、対応する畳み込み層のニューロンのどこかが発火したことを意味する。
入力データをより扱いやすい形に変形するために、情報圧縮を行い、ダウンサンプリングする。
圧縮する効果は
- 微小な変化位置に対して敏感になる
- ある程度の過学習を抑制できる
※随時更新

# 参考

ここでは自分が調べたこと覚えておきたいことを限定的に記述してます。
なので、話の流れが掴みにくいと思うので、個人的に
おすすめのサイトを貼っておきます。
[CNNの理解のために先行研究も記述してくれてる](https://ml4a.github.io/ml4a/jp/convnets/)
※随時更新
NeosVRのProcedualAudioのノイズ

#はじめに

NeosVRでノイズを鳴らす方法の紹介します。
Logixは出てこないです。

まずは、こちらのBoxをつくってインスペクタを出すところまでは一緒ですので、そこまで進めてから戻ってきてください。

[NeosVRではじめてのBoxの大きさを変えるLogix](http://qiita.com/tatmos/items/cfe4498fc74d6067fedb)

#音の出し方

![71EAB0BD-6C89-4F7D-A6EB-2F174F93E658.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/45e56dcd-2e33-a8b3-35af-51472b728c7d.png)



##まずオーディオ出力を用意する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/dd693f99-956c-676f-3d02-630b40913b1c.png)
Attach Componentから
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/5b742caf-f47b-5d3c-affa-e1e2e7879ae9.png)
Audio>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/a6d1d62a-7ece-57ea-4288-f079a06a40c9.png)
AudioOuputをアタッチする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/03fea3cf-1cc9-e2d8-7f02-a3f87b1eaac7.png)

AudioOutputが追加されます。

##AudioClipPlayerを用意
同じように
Audio>AudioClipPlayerをアタッチします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/f64b9724-fba3-85c8-ac11-c5b847454665.png)

追加されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/f4686218-170c-ec32-60ef-4700521fdf64.png)

##ノイズを用意
同じように
一番上の
Assets>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/9c77471c-c41f-f090-6e01-ed2c998bf408.png)
Procedual Audio Clips > 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/615c6019-5c74-4347-f14a-b985bcd2578b.png)
ValueNoiseClipをアタッチする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/8e018d41-a252-9e5b-40e3-6916ee004c5d.png)
ValueNoiseClipが追加されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/1b15a47f-6bc3-dc1e-f2ec-137f25593bc5.png)

## それぞれつなぎます
AudioClipPlayerをつかんで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/86a4a3dd-b5da-335e-e27c-4041420cdf64.png)
AudioOutputのSourceにドロップします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/761e2da1-4ddc-ea4d-5d15-7bfadd55993b.png)

ValueNoiseClipをつかんで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/e00009c3-5a5d-7e1b-8757-86b8d194141c.png)
AduioClipPlayerのClipにドロップします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/49776773-0bf3-3c69-53c9-5e6fd0eebdde.png)

##音を鳴らす
AudioClipPlayerの再生ボタンを押すと音が鳴ります。

右端の→のボタンを一回押すとループ再生になって、鳴り続けるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/988e22d6-8807-cac3-5aa6-919adc4aa9bd.png)

#duration,Seedを弄る
ただ鳴らすだけだとホワイトノイズっぽいのですが、

durationを小さくし、
Seedを弄ると
いろんなノイズがだせます。

## durationを短くしていく＝　音が高くなる

波形はノイズだけど、短周期ノイズといって、周期性がでてきて、それが音程に聞こえてきます。

## Seedを弄る＝　波形が変化する

波形の形が変われば、音色もかわります。


ノイズっていろんな音がするので、面白い。

参考動画：
http://youtu.be/zydTUVgQFpA?t=83


#NeosFestaにノイズ使ったものあげてます

tatmosであがっているのでよかったら見ていってね
四角いキューブの高さでノイズの感じが変わるようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/ec8ae9f4-4800-d69d-2865-f3f1631d5260.png)
【Swift】オプショナル型の何が嬉しいのか

# 何が嬉しいのか

**nilを参照することができる。**
つまり、例えば `if` とかで「**もしnilならば**」という条件を使うことができる。

## 定義してみる

先に正解を言っておくと

```swift
var hoge: String?

print(hoge)

// 出力は nil
```

こう書けば `nil` が出力される。
しかし `?` を付けずに書いたり

```swift
var hoge: String

print(hoge)

// エラー
```

こう書いたりしてもエラーになる。

```swift
var hoge: String

hoge = nil

print(hoge)

// エラー
```

[paiza.io](https://paiza.io/ja)とかで気軽に試すことができる。
次回はこのオプショナル型の `hoge` を活用する方法を書く。
FastAPIを使ったgraphQL

はじめましてこんにちは、サーバーエンジニアのhrstgwです。

8月に開催されたPyCon JP 2020 Onlineではアイリッジはゴールドスポンサーとして参加しました。

PyCon JP 2020 Onlineの様子はコチラ
https://iridge-tech.hatenablog.com/entry/2020/09/16/103000


前夜祭でもある"Python Charity Talks in Japan"ではLTとしてFastAPIの紹介をしましたが、惜しくも時間切れとなってしまいました・・・・。なので今回は改めてFastAPIの紹介と簡単にgraphQLを実装してみたのでご紹介します。

# FastAPIとは
公式：https://fastapi.tiangolo.com/

- 高速（Go/NodeJS並）且つ軽量なpython製webフレームワーク。
- 使いやすく、習得しやすいように設計されています。ドキュメントを読む時間が短縮されます。
- 標準でSwaggerが搭載されているので、手軽にAPI開発＆動作確認が可能。

その他FastAPIの紹介
[![thumbnail](https://image.slidesharecdn.com/eygzepmpriezf0erw48w-signature-4d5b620db5ea5565716e00d9577ec79df32a1730624fa412ed6b3f20e225889f-poli-201207084102/95/python-charity-talk-in-japan-fastapi-introduction-1-638.jpg?cb=1607330543)](https://www2.slideshare.net/ssuserc75dc7/python-charity-talk-in-japan-fastapi-introduction)

LTでは詳しく触れませんでしたが、[Starlette](https://www.starlette.io/)が搭載されているためgraphQLの構築も手軽にできます。

# graphQLとは
参考：https://eh-career.com/engineerhub/entry/2018/12/26/103000

# とりあえず動かしてみた
- Graphene導入

```shell:shell&#x20;pip　(1)
pip install '"graphene>=2.0"'
```

- コントーラー実装

```python:fastAPI&#x20;controller.py　(1)
import graphene
from fastapi import FastAPI
from starlette.graphql import GraphQLApp


class Query(graphene.ObjectType):
    hello = graphene.String(name=graphene.String(default_value="hogehoge"))
    bye = graphene.String(name=graphene.String(default_value="hugahuga"))

    # hello クエリのリゾルバ
    def resolve_hello(self, info, name):
        return "こんにちわ！ " + name

    # bye クエリのリゾルバ
    def resolve_bye(self, info, name):
        return "さようなら！！ " + name


# fastAPIインスタンス
app = FastAPI()
# graphQlのエンドポイント（）
app.add_route("/hello", GraphQLApp(schema=graphene.Schema(query=Query)))
```

- localhostにアクセス
![スクリーンショット 2020-12-07 21.03.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921958/4410b12e-6a9c-024a-ed0a-ee057482cf7d.png)


- データ（クエリ）を与えてみる

```
{
  hello(name: "太郎さん！")
  bye(name: "太郎さん！")
}
```

- 結果

![スクリーンショット 2020-12-07 21.04.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/921958/56c67c0b-d5f7-e931-24bb-17188d15541c.png)


# まとめ
- エンドポイントは１つなので、わかりやすい。しかもschemaの存在によって一回の問合せで複数データを取得することができるので便利。
- 複雑なGETAPIが大量にあったら便利かもしれない・・・！
CentOS7にSFTPアクセスできるユーザーを作成する


Centos7にSFTPユーザーで特定ディレクトリに編集権限を割り当てる方法について記載。


1.ユーザー作成

```
useradd sftp-user
passwd sftp-user
```

2.homeディレクトリにsftpユーザー用のディレクトリを作成

```
mkdir /home/chroot-sftpuser
```

3.chroot-sftpuserディレクトリの所有権はroot、他のユーザーに書き込み権限がない状態でないとSFTPで入れないので権限を以下のように設定（rootでディレクトリを作っていればそのまま）

```
drwxr-xr-x   4 root     root       50 12月  5 13:45 chroot-sftpuser
```

4.Webサーバ用などの公開用ディレクトリを作成
（SFTPでファイルやりをしたいディレクトリ）

```
mkdir /var/www/public_html/hoge.co.jp
```

5. SFTPユーザーが編集可能なディレクトリを作成、所有者をsftp-userに設定

```
mkdir /home/chroot-sftpuser/hoge.co.jp
chown sftp-user /home/chroot-sftpuser/hoge.co.jp

```

6.5で作ったディレクトリと公開用ディレクトリをマウントする

```
mount -B /var/www/public_html/hoge.co.jp /home/chroot-sftpuser/hoge.co.jp

```

7.sshd_configを編集して、下部にsftp-userの記述を追加

```
 vi /etc/ssh/sshd_config
```

```
#Subsystem sftp /usr/libexec/openssh/sftp-server
Subsystem       sftp    internal-sftp

Match User sftp-user
    ChrootDirectory /home/chroot-sftpuser/
    ForceCommand internal-sftp -u 002
```


8.sshdを再起動、これでsftp-userでSFTP接続できるようになっているはず。
/var/www/public_html/hoge.co.jpで編集できるか確認する。

```
systemctl restart sshd
```

補足.
再起動時にもマウントするように/etc/fstabに設定を追加。

```
vi /etc/fstab
```

```
/var/www/public_html/hoge.co.jp /home/chroot-sftpuser/hoge.co.jp
 none bind 0 0
```


以上
Reactで画像を表示させる方法

近頃Reactでいいサイトを作ろうとしているのですが、画像を表示させるのに3日かかってしまったのでたどり着いたコードを書いていきます。
#表示のさせ方
```react:test.react
import ReactDOM from 'react-dom';
import Icon from './logo.png';
const IconComponent = () =>{
  return <img src={Icon}  alt="アイコン" />
}
const rootElement = document.getElementById("root");
ReactDOM.render(
  <IconComponent />,rootElement
);
```
こんな感じになりました。
import Icon from ''でパスを指定するとそのものがIconに
入るみたいです。
const rootElement = document.getElementById("root");
をしてからReactDOM.renderで、
<IconComponent />,rootElement
としないとTarget container is not a DOM element
と出ます。ここら辺の理解はまだまだなのでこれから調べます。
#終わり
[Laravel] 独自のバリデーションを作成してメッセージを定義したとき、名前間違ってないのに何故か表示されないとき

## 状況
●以下の例は、別にRequest系のファイルの中でregex使ってしまえばいいが、今回はあえてオリジナルのバリデーションを定義するためだから、許してクレメンス

## 独自バリデーションファイルの中身

```php:OriginalValidation.php
    public function validateCheckPhoneNo($attribute, $value, $parameters)
    {
        return preg_match('なんか正規表現', $value);
    }
```

## リクエスト系ファイルの中身

```php:HogeRequest.php
    public function messages()
    {
        return [
            'phone_no.checkPhoneNo' => '電話番号のエラーメッセージやで',
        ];
    }
```

## 原因
独自バリデーションで定義したバリデーション名とフォームでのnameの名前が同じ、あるいは含まれているからです(謎仕様)
フォームのnameの値がスネークケースで独自バリデーション名がローキャメルケースで形が異なっていても、何故か名前が同じだったり含まれていたりすると、エラーメッセージが正しく表示されない。
ここほんと謎仕様

## 解決方法
**フォームのinputタグのnameの値と独自バリデーション名を一致もさせず、含まれている感じもしないような名前で、独自バリデーションの名前をつける**

なので、上記の独自バリデーション名を「phone」だけにするとうまくいく。また、全くかすりもしない「hoge」でもうまくいく。
Classiのエンジニアメンター制度

[Classi Advent Calendar 2020](https://qiita.com/advent-calendar/2020/classi) の8日目の記事を担当する @nagatashinya です。
2018年10月からClassi株式会社に入社し、PHPでのプロダクト開発など担当していました。今年度からプロダクト開発部の部長として採用や組織開発に携わっています。
つい最近のことですが、エンジニアメンターという制度をスタートしたので、その取り組みを紹介したいと思います(内容は2020年12月8日時点のものです)。

## エンジニアメンターとは
### 目的
- 部内でのチームを超えた斜めのメンター制度です。気軽に相談できる環境を作り、日々安定して楽しく活躍できることを目的としています

### 役割
- メンティーの相談事を引き出す、受け取る
- 伸ばしたいこと、やりたいことのサポート
- エンジニアメンター自身で解決しきれない場合、適切な部署やチームに連携を取ったり、部長やVPoEに判断を仰ぐ

### 実施の背景
- 本来は、部長の私が上記の役割を担うところですが、部のメンバー数も約70名と増え、1人1人から悩みや相談事を受け取ることができていない課題感がありました
- また、コロナ禍において大半が在宅ワークをしている状況で、チーム外の交流の機会が減っていることにも何かアクションが取れないかと考えていました
- そのため、今回エンジニアメンターという役割を置いて、ちょっとしたことでも気軽に話せる人がチーム外にいるという安心感を作れればという思いです
- 入社年次や役職に関わらず部の全員がいきいきと働けるような環境づくりをしていきたいと考えており、その第一歩として制度を開始しました

### メンターの選出基準
- 明確なものではないですが、ある程度基準を決めました
- 所属チーム以外であることが望ましい
    - チーム内では言いにくいことも話せるような関係性にしたい
- メンティーが興味があることに話が合いそうな人
- コミュニティの広がりを求めているメンティーには、普段関わりが少ない人
- メンティーがイメージするキャリアパスに近い人

## 実施内容
### いつ何をどれぐらいどのようにするのか
- メンターそれぞれの考え方があったので、すり合わせのため5W1Hを整理しました
- 誰のためにやるのか
    - メンティーのため
    - 部を良くするため(みんなのため)
- 何のためにやるのか
    - 現状把握、悩み相談、共感、問題解決、キャリア支援
- メンター/メンティーのマッチング
    - 現在：[メンターの選出基準](#メンターの選出基準)に沿って部長がアサイン
    - 今後：性格診断などを通してタイプごとにマッチングすることも検討
- 初回にメンターからメンティーに伝えておくこと
    - 個人情報の取り扱い
    - [メンターを代えたいときのオペレーション](#メンターを代えたいとき)
- 1on1など話を聴く場を設定する
    - 入社1年以内もしくは新卒入社メンバーは最低月1で2週間に1回を推奨。以降はメンティーと相談しながら永続的にタッチポイントを確保
    - 関係性構築のため、雑談、ランチ、ペアプロ、社外勉強会に行くなど1on1以外の方法でもOK
- フィードバックをもらう
    - 四半期ごとにメンティーからFBをもらったり振り返りを実施

### 情報のストックについて
- 個人情報の取り扱いと情報のストックのバランスを考えて一旦決めましたが、今後ブラッシュアップしていく予定です
- 目的：共通する課題感を優先順位を上げてを解決していくアクションを取るため
- メンターとメンティーで話したメモは残す(非公開)
    - 前回話した内容の振り返りのため
- エンジニアメンター定例で共有して良いものは、Googleドライブに格納
    - 共有してほしくないものは必ず確認
- 定例では共有できないけど、エスカレが必要なものはGoogleフォームから投稿
    - メンターが判断する

### 定例MTGなど
- エンジニアメンター定例
    - 頻度：週次で30分〜1時間
    - 内容
        - メンターの悩みを共有して解決したり、Tipsを共有する
        - メンター/メンティーのアサインの共有や意思決定
        - 制度の進め方のディスカッション
- 研修(振り返り)
    - 頻度：月次で1〜2時間
    - 内容
        - 研修でのインプットを実践してみて、さらに良いものにしていく振り返りの場

## メンター/メンティーのアサインについて
- アサインに関して、要望や相談がしやすいように窓口担当を決めました
- 内容によっては部外の人の方が話しやすいこともあるため、HR担当にも協力してもらっています

### メンターをやめたいとき
- 窓口：部長
- 意思決定：本人と部長で相談の上
- 共有先：部全体

### メンターになりたいとき
- 窓口：メンター定例メンバー誰でも ＋ HR
- 意思決定：メンター定例での合意
- 共有先：部全体

### メンティーを代えたいとき
- 窓口：メンター定例
- 意思決定：メンター定例で上げてもらい、メンティーにも意思をヒアリング。相互の話を聞いた上で決定
- 共有先：メンターメンバー、担当メンティー

### メンターを代えたいとき
- 窓口：HR
- 意思決定：HR、担当メンター、部長、新しいメンター候補
- 共有先：部長と担当メンター → 他のメンターメンバー

### 新しく入社した方のメンター決め
- 窓口：部長
- 意思決定：メンター定例
- 共有先：部内 ＋ オンボーディングを担当している部署

## FAQ
- メンバーからの質問やこれから決めることはFAQにリストアップしています
- メンター制度における部長とVPoEの役割の違いは何ですか？
    - 日々の運用は部長で、VPoEが関わるのは下記のイメージ
        - メンターがメンティーからもらってきた相談のうち、組織的な問題であればその解決
        - メンター制度自体に課題があれば、その課題を解消するための仕組みをつくる
- エンジニアメンター1人あたりが受け持つメンティー数の制限はありますか？
    - 現時点では、1人あたり5〜6名を担当
    - 1on1の頻度を調整したり、メンターを増やしたりして増減に対応できるようにしていく予定です

## さいごに
- 入社年次や役職に関わらず部の全員がいきいきと働けるような環境づくりをしていきたいと考えており、その第一歩としてエンジニアメンター制度を開始しました
- 部として新たな取り組みのため、うまくいかないこともかもしれませんが、社内外からご意見いただきながら改善していきたいと思っています
Ruby インスタンス変数を外部から操作する

ゲッターや、セッターを調べていたら
まずインスタンス変数の外部操作がでてきたので
そこをまず調べてみる

##インスタンスメソッドの定義
クラス構文の内部でメソッドを定義すると、そのメソッドは
`インスタンスメソッド`になります
そのクラスのインスタンスに対して、呼び出すことができるメソッドのこと

```rb
class User
  def hello
    "Hello!"
  end
end

user = User.new
user.hello #=> "Hello!"
```

##インスタンス変数とアクセサメソッド
クラスの内部では、インスタンス変数に使うことができます
インスタンス変数とは、同じインスタンスの内部で共有される変数のこと

```rb
class User
  def initialize(name)
    @name = name
  end

  def hello
    "Hello, I am #{@name}"
  end
end

user = User.new('太郎')
user.hello #=> "Hello I am 太郎"
```

ローカル変数では、値を代入する前にいきなり参照してもエラーにならない

```rb
class User
  def initialize(name)
    # インスタンス変数の代入をコメントアウトしてみる
    # @name = name
  end

  def hello
    "Hello, I am #{@name}"
  end
end

user = User.new('太郎')
#@nameを参照すると、「nil」になる、つまり名前の部分に何も出力されない
user.hello #=> "Hello I am "
```
なので、タイポとかにも気をつける

###参照用メソッド、「ゲッターメソッド」
インスタンス変数は、クラスの外部から参照できない
もし、参照したい場合は参照用のメソッドを作成する必要がある

インスタンス変数をクラス内から参照するメソッドが「ゲッター」です。

```rb
class User
  def initialize(name)
    # インスタンス変数の代入をコメントアウトしてみる
    # @name = name
  end

  #@nameを外部から参照するメソッド、ゲッター
  def name
    @name
  end
end

user = User.new('太郎')
user.name #=> "太郎"
```

###変更用メソッド、「セッターメソッド」
また、インスタンス変数の内容を外部から変更したい場合も
変更用のメソッドを定義する必要がある

インスタンス変数をクラス内で更新するメソッドが「セッター」です。

```rb
class User
  def initialize(name)
    # インスタンス変数の代入をコメントアウトしてみる
    # @name = name
  end

  #@nameを外部から参照するメソッド
  def name
    @name
  end

  #@nameを外部から変更するメソッド
  def name=(value)
    @name = value
  end
end

user = User.new('太郎')
#変数に代入しているように見えるが実際には、メソッドを呼び出している
user.name = 次郎
user.name #=> "次郎"
```

##参考記事、書籍
チェリー本
QUBEという取り組み


[QualiArts Advent Calendar 2020](https://qiita.com/advent-calendar/2020/qualiarts) 8日目の記事になります。
初めまして。バックエンドエンジニアの朝倉が、QualiArtsのQUBEという取り組みについて紹介します。

# QUBEとは

QualiArtsでは、QUBEというチームを作って「エンジニアの成長が加速し、継続的に事業成果があげられるエンジニア組織」という目標に取り組んでいます。
2019年に4月から活動が始まり、現在、私を含め4名で活動しています。
QUBEの活動とちょうど同じころに、サイバーエージェント全社で技術者の評価制度「JBキャリアプログラム」が始まったこともあり、特に目標設定や技術評価に注力して取り組んでいます。
今回はQUBEで取り組んできたことについて紹介したいと思います。

# JBキャリアプログラムの詳細化
サイバーエージェント全社の評価制度「JBキャリアプログラム」では、13のグレード×5つの職能（専門性、戦略性、業務遂行力、オーナーシップ、コミュニケーション）で定義されています。
JBキャリアプログラムはサイバーエージェント全社の様々な事業ドメインや職種、役割を包括した定義となっているため、各エンジニアが具体的な目標設定や評価に落とし込む難しさがありました。
QUBEでは、エンジニアの目標設定や評価のブレを少なくするため、JBキャリアプログラムの定義を踏襲しつつ、QualiArtsの業務内容に即した形で詳細化を行いました。

例えば）
サイバーエージェント全社のJBキャリアプログラムでは、あるグレードの専門性が
「担当領域のベストプラクティスを実践できる」
と定義されています。

QualiArtsでは、上記の定義を踏襲しつつ、
「既にあるものを参考にして2週間ほどの機能追加がフォローありで行える」
「既にあるものを参考にして2週間ほどの機能追加が行える（フォローなし）」
「1ヵ月ほど必要な機能追加が行える。コードレビューで品質を担保することができる」
と詳細化をしています。

# 目標設定と評価
エンジニアのキャリア実現や能力成長を目的に、職能の目標設定と評価も半期ごとに実施するようになりました。
（QUBEでの取り組みが始まる前から、QualiArtsでは事業成果の目標設定と評価を半期ごとに実施しています。）

職能の目標設定（JB目標設定）では、全社のJBキャリアプログラムの職能を踏襲し、「専門性」「戦略性」「業務遂行力」「オーナーシップ」「コミュニケーション」の目標と半期、中長期のキャリアを技術評価者と設定してもらいます。
JB目標設定から約3ヵ月後に中間面談を実施し、3ヵ月の振り返りを行なっています。この際、プロジェクト異動などミッション変更がある場合は、中間面談で次の3ヵ月の目標を再設定しています。
半期の終わりには、エンジニアと技術評価者で振り返り面談を実施し、半期の成果とその評価のすり合わせを行なっています。サイバーエージェント全社で活動していたり、高度な専門性を判断する必要があるなど技術評価者1名だけで評価が難しい場合は、複数の技術評価者が同席するようにしています。

JB目標設定シートもアップデートを重ね、現在のJB目標設定シートは下記のようになっています。
![スクリーンショット 2020-12-05 11.04.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534842/dfe9842f-a7d5-f9e3-2cec-2e4b3abf520c.png)

# 目標キャリブレーション
各エンジニアに設定してもらったJB目標は、技術評価者で目標のキャリブレーションを行なっています。
目標キャリブレーションは、エンジニアのグレードと職種によってカテゴリ分けして実施しています。

グレードに対する目標が妥当か技術評価者で議論し、必要あれば目標を再設定してもらいます。
目標の精度をあげることによって、よりエンジニアの成長を後押しできればと考えています。

また、技術評価者間で議論することにより、技術評価者の引き出しを増やしたり、判断基準を合わせたりなど技術評価者のレベルアップも目指しています。

# 評価キャリブレーション
半期の終わりに、技術評価者に職能の評価してもらったあとに、技術評価者による判断のブレやプロジェクト・職種などのバイアスがかかっていないかなどを是正するための評価キャリブレーションを実施しています。
評価キャリブレーションのメンバーは、職種やプロジェクトなどを幅広くカバーできるように選出しています。

技術評価者からの評価内容をもとに、各グレードごとの職能の基準を満たしているかを確認し修正しています。2年ほど前から実施していますが、回数を重ねるたびに各技術評価者の判断基準も統一されてきていて、評価を修正するケースも少なくなっています。

# 1on1
技術評価者によって1on1を実施している人もいれば、業務上のコミュニケーションのみだったり、技術評価者によって評価者とのコミュニケーションはまちまちでした。

弊社でもリモートワークが増えたことによって、技術者と技術評価者とのコミュニケーションが少なくなり、技術者の状況変化をキャッチアップできなくなる懸念が湧いてきました。そのため、今期から技術者と技術評価者の月1回の1on1をルール化して取り組んでいます。
1on1では、なるべく業務の進捗報告ではなく、目標達成のための課題解決やキャリアの実現などの話をするようにしています。

まだ1on1を始めたばかりなので、これからやり方をブラシュアップしていき、技術者のキャリア実現を後押しできるような取り組みにしていければと思っています。

# まとめ
今回は、QualiArtsのQUBEという取り組みを紹介しました。
今後もQUBEでは、「エンジニアの成長が加速し、継続的に事業成果があげられるエンジニア組織」というミッションの実現のため色々取り組んで行こうと考えています。
今後の取り組みについても、機会があれば皆様に紹介していきたいと思います。
shopifyアプリの「Hide Collection」を使うなら全体公開されないように考慮が必要

# 目的 
- 「Hide Collection」を導入してみて、考慮しないといけ部分が多かったので忘れないように記述

# 前提条件
- 同じ商品でも、得意先によって違う料金で提供したい
- 会員登録を通さずに表示を切替えたい
- パスワード入力を省略したい

# 「Hide Collection」とは？（ざっくりとできることを説明）
- 特定のコレクションを非表示（実際にはアクセス権限をなくす）になり、発行したURLを知っている人しかページを参照できないようにする
- パスワードが必要ない

## 発生した現象
1. Hide Collectionに登録した商品が検索に表示される
    - デモで現象を確認できます
        - [hidden-collection](https://apps.shopify.com/hidden-collections?locale=ja)のページへ遷移
        - 「サンプルストアを表示する」というボタンがあるので、そこからサンプルストアページへ遷移
        - 「View Secret Collection」ボタンを押下後、登録されている商品を確認（先頭に「Hidden」と記載）
        - トップページへ戻り、検索から「Hidden」と検索するとシークレットページの商品が表示される
        - 料金の違う商品があるのがバレる！
- Collection一覧に表示される
    - シークレット対象のCollectionを押下してもアクセスはできないが、そういうページがあるというのがバレる！
 
## 対応
### 1. 「Metafields Guru」というアプリを導入してサイト内検索ヒットさせる
[![Image from Gyazo](https://i.gyazo.com/6be3be0a2680dd4ac2105ee345add93f.png)](https://gyazo.com/6be3be0a2680dd4ac2105ee345add93f)

#### 手順２. 「Products & Variants」を押下
[![Image from Gyazo](https://i.gyazo.com/56fa13b0e5e3a087f081cca87398f0c5.png)](https://gyazo.com/56fa13b0e5e3a087f081cca87398f0c5)

#### 手順3. 対象の商品を押下
[![Image from Gyazo](https://i.gyazo.com/70c40f5ae5e7593d90c4e57235227e90.png)](https://gyazo.com/70c40f5ae5e7593d90c4e57235227e90)

#### 手順4. 「Create metafield」ボタンを押下し、設定後保存。
[![Image from Gyazo](https://i.gyazo.com/cfbe191772ffefc0fb6ab3ddc8ff09f2.png)](https://gyazo.com/cfbe191772ffefc0fb6ab3ddc8ff09f2)

以下を入力。

| 項目 | 値 |
|:-----------:|:------------:|
| key | hidden |
| namespace | seo |
| value_type | integer |
| value | 1 |

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

#### 手順4. 完。👍
[![Image from Gyazo](https://i.gyazo.com/1a19c1f9effc705ae70c2d4af7f1833b.png)](https://gyazo.com/1a19c1f9effc705ae70c2d4af7f1833b)

### ２. URLの独自ルール（キーワード）を設定し、それに該当する場合は、非表示にする

私の場合はURLに「hidden」を含んでいると非表示になるように設定しました。
ルールとしては先頭に「hidden」をつけるようにしました。

```liquid:
{% unless collection.handle contains 'hidden' %}
  {% include 'collection-list-item' %}
{% endunless %}
```

# 所感
条件を満たすのが「Hide Collection」ぐらいしかなかったのですが、使い勝手悪いです😅

# 関連URL
- [Metafields Guru](https://apps.shopify.com/metafields-editor-2)
- [Object handles
](https://shopify.dev/docs/themes/liquid/reference/basics/handle)
IBM Cloud、ベアメタルサーバーCPUの選び方

 IBM Cloudの特徴の一つはなんといってもベアメタルサーバー。性能が要求されるアプリを使う場合はこのベアメタルサーバーを使いたいですよね。さて、このベアメタル用のCPUですがちょっとどれが最新のCPUなのかわかりにくくないでしょうか？
例えば以下のようの中から最新世代のCPUはどれでしょう？　答えは後で
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59741/41d5b14f-1aad-10ff-1444-0d00b6bcdb21.png)

まずはインテルCPUのロードマップを以下のようにまとめてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59741/69ff3643-f6c3-9427-028c-f4cd208651da.png)


　上からパソコン用CPU, サーバー用CPUは１ソケット、２ソケット、４ソケット用と分けました。
右側が最新CPUとなります。赤い字でかいたのがIBM Cloudで選べるCPUモデルです。
各世代での拡張命令も入れておきました。拡張命令をどのようにうまく使えるか？ちょうどワークショップをやっているのでぜひ参加ください。　https://ibm-developer.connpass.com/event/190153/

これを下にIBM Cloudでの１、２、４ソケットのCPUの選択肢をみてみましょう。
まずはシングルプロセッサーです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59741/f2d10bed-b9ff-0802-0b1a-cd722cd4c207.png)
　E-2174Gがコード名Caffe Lakeの最新、次がE3 v6になります。名前だけ見るとv6が最新に見えちゃったりもするので注意が必要ですね。

次がディアルプロセッサーです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59741/f748d80f-2f1d-c643-6085-784885ffd566.png)
　Cascade LakeのCPUが最新CPUです。Xeonの42**, 52**, 62** がそうですね。一つ前が Xeonの　41**, 51**, 61**ですね。一番古いのがE5-2620 v4です。これもなんとなくv4が一番新しいかなと思ってしまいますよね。名前だけだと
最後がクワッドプロセッサーです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59741/bb529ef3-8ea5-a46c-9e44-7530e85485ba.png)

これもv4は古い方なのです。　ベアメタルのCPUを選ぶ場合は参考にしてください。
Twitterもどきを５分で作ってみた

XTechグループ Advent Calendar 2020の10日目は、
iXIT株式会社 MVP開発 x DX担当 岡崎がお送りします。

#はじめに
リリース直前、ほぼ完成したタイミングで、
　欲しかったのはこれじゃない・・・
　この機能を追加しないと使い物にならないから、急ぎで・・・

実際に使ってみて、やっとイメージできたってよく聞く話です。

ただ、プロトタイプ作るにもお金も時間もかかる。。。

そんなときにノーコードでサクッと作ってみませんか。

今回は、Twitterもどきを5分以内で作っていきます。
#環境
・ノーコードのサービス https://bubble.io/ 
　無料の【Hobby】アカウントでも提供される開発開発、サーバー環境を使います。
・ブラウザ
　画面を翻訳出来るのでchromeを使いましたが他のブラウザでも問題無いです。

#5分でできるもの
###ユーザー関連
　・登録（メールアドレス、パスワード、名前、アイコン）
　・ログイン、ログアウト
　・パスワードリセット

### 主な機能
　　・Tweet投稿　　（投稿テキスト入力、投稿ボタン）
　　・Tweet一覧表示（投稿者のアイコン、名前、投稿時間、投稿テキスト）

###今回作った実際のサンプルの簡単な使い方
1)次のURLを表示
　 https://okazaki07.bubbleapps.io/version-test
<img width="150" alt="今回作った実際のサンプル" src="//s3.amazonaws.com/appforest_uf/f1607547905434x849476981860510000/QR.png">
2)右上の「SIGN UP OR LOGIN」からユーザー登録。
　メールアドレス、パスワード、名前、アイコンを登録。
　<img width="300" alt="今回作った実際のサンプル" src="https://s3.amazonaws.com/appforest_uf/f1607550881986x408300731859183170/FireShot%20Capture%20079%20-%20Okazaki07%20-%20okazaki07.bubbleapps.io.png">
3)コメントを投稿
　テキストボックスにコメントを入れて、「ツイートする」をクリック。
　<img width="300" alt="今回作った実際のサンプル" src="https:////s3.amazonaws.com/appforest_uf/f1607550826826x282134599037820130/FireShot%20Capture%20076%20-%20Okazaki07%20-%20okazaki07.bubbleapps.io.png">
　※この時、別のブラウザでも同じ画面を開いておくと、
　　リロード無しで別のユーザーの画面に反映されているのも確認できます。

#作り方　約4分30秒
###※<a href="https://www.youtube.com/watch?v=nZRP3tt0L4w">実際に作ったときの画面動画</a>

※事前にbubbleのアカウント登録をお願いします。
　https://bubble.io/ にアクセスして右上のメニューから[Sign up]をクリック
　無料の【Hobby】アカウントで十分です。

～～　ここから時間を測ります　～～
###アプリ環境構築　約30秒　
　<img width="300" alt="今回作った実際のサンプル" src="https://s3.amazonaws.com/appforest_uf/f1607558720000x741088650065749200/%E2%91%A0FireShot%20Capture%20092%20-%20My%20Apps%20-%20Bubble%20-%20bubble.io.png">

　　１．アプリ名等を登録
　　２．言語設定を日本語に設定
　　
　　ここまでで、テスト環境、本番環境として
　　　Webサーバー、アプリケーションサーバー、データベース
　　が用意されます。
　　もちろん、SSL設定も終わっています。

###データベース設定  　約30秒
<img width="400" alt="今回作った実際のサンプル" src="//s3.amazonaws.com/appforest_uf/f1607558826500x603690421738378200/%E3%89%92FireShot%20Capture%20107%20-%20Okazaki07%20-%20Bubble%20Editor%20-%20bubble.io.png">
　　・Userテーブルに項目追加
　　　　name：text形式
　　　　icon：image形式

　　・Tweetテーブルを作成
　　　　tweet_text：text形式

###画面作成　3分30秒
　　　<img width="400" alt="今回作った実際のサンプル" src="https://s3.amazonaws.com/appforest_uf/f1607558836133x740145355444473000/%E3%89%9DFireShot%20Capture%20110%20-%20Okazaki07%20-%20Bubble%20Editor%20-%20bubble.io.png">
　　・Sign up画面修正　約60秒
　　　　name ： Input 文字入力
　　　　icon ： Picture Uploader 画像ファイルのアップロード（画像のみ）
　　　　
　　　　アカウント追加のWorkflowにnameとiconの保存処理を追加

　　・Tweet投稿部分の作成　約60秒
　　　　投稿テキスト入力： Multiline Input 複数行の文字入力
　　　　投稿ボタン　　　： Button ボタン
　　　　投稿ボタンのWorkflowにTweetの保存処理を追加

　　・Tweet一覧表示　約90秒
　　　　Tweet一覧の枠　　： Repeating Group 繰り返し使うグループ
　　　　投稿者のアイコン　： Image 画像
　　　　投稿者の名前、投稿時間　： Text 文字
　　　　投稿テキスト　　　： Text 文字


～～　ここまでで約4分30秒　無事5分以内に完成　～～

#まとめ
無事5分以内に完成させることができました。

ノーコードを使えば簡単なものは、すぐ出来るようになります。
是非試して下さい！

詳しく知りたいかたは、下記の２つのサイトがお勧めです！

　　①動画で一通り何ができるかを知る
　　　[NoCode School - ノーコードスクール - Bubbleの使い方](https://www.youtube.com/watch?v=XqJIZ9OIY9E&list=PLiDMHhMXhuXRfwx-sRoBCrClO5V6sEclj)

　　②どんな事ができるかを知る
　　　[ノーコードラボ](https://blog.nocodelab.jp/links)



XTechグループのアドベントカレンダーはまだまだ続きます。
明日の執筆担当は @naka_sho さんです。引き続きお楽しみください。