OmniAICreator/Qiita-1.07M huggingface dataset:
[Android]中央でピタッととまるカルーセルの作り方

中央でピタッととまるカルーセルの作り方の解説します。ハマりどころがあるので記事にしました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196890/71f2af16-5e3d-3c42-918a-0623c29b4c76.gif" width="150" />

## 実装手順
### Step 1. 依存ライブラリの記述

RecyclerViewと[GravitySnapHelper](https://github.com/rubensousa/GravitySnapHelper)というライブラリを使います。build.gradleに以下を記述します。

```gradle:app/build.gradle
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.github.rubensousa:gravitysnaphelper:2.2.1'
```

### Step 2. 水平方向にスクロール可能なRecyclerViewを追加する

水平方向にスクロール可能なRecyclerViewでカルーセルは大体実現できます。

```kotlin
val carousel = findViewById<RecyclerView>(R.id.carousel)
carousel.apply {
    // RecyclerViewを水平方向にスクロールできるように設定
    layoutManager =
        LinearLayoutManager(this@MainActivity, LinearLayoutManager.HORIZONTAL, false)
    // サンプルAdapter
    adapter = MyAdapter((0..30).map { it.toString() }.toTypedArray()) 

    // カルーセルの両端が中央に表示されるようにRecyclerViewの両端にPaddingを入れる。
    val itemWidthDp = 96 // 各項目の幅。サンプル値。
    val itemWidthPixels = (itemWidthDp * resources.displayMetrics.density  + 0.5).toInt()
    val paddingH = (resources.displayMetrics.widthPixels - itemWidthPixels) / 2
    setPadding(paddingH, 0, paddingH, 0)
    clipToPadding = false
    setHasFixedSize(true)
}
```

ポイントは2つです。
1. 左右両端にPaddingを入れつつclipToPaddingをfalseにすることで、左右両端の項目を中央に表示させる
2. setHasFixedSize(true)を設定する

Web検索をすると、左右両端の項目にItemDecoratorを使って余白を入れる方法をしばしば見かけますが、それだと項目の削除がある場合には上手く対処できません。末尾項目を削除したとき、中間状態として末尾のItemDecoratorが消えます。その状態で表示位置の調整が行われることで、表示位置が不正になる問題が起きます。なお、画面の表示中にカルーセルの項目を変化させないなら、ItemDecoratorの方法も使えます。

setHasFixedSize(true)を設定するのも、カルーセルの項目数が変化したときに表示位置が不正になる問題を回避するのためです[^1]。

### Step 3. カルーセルの項目が丁度良い位置に止まるようにする
GravitySnapHelperを使います。RecyclerViewに付属しているLinearSnapHelperは、中央に表示されている位置(この記事では以下、Snap位置と呼びます)の変化を検知するAPIがないので不便だからです。

```kotlin
val snapHelper = GravitySnapHelper(Gravity.CENTER, true)
snapHelper.attachToRecyclerView(carousel)
```

これでカルーセルの項目が丁度良い位置に止まるようになります。

### Step 4. Snap位置の変化を検知する
GraivitySnapHelperのAPIに位置変化リスナーがあるので、それを使います。カルーセルの位置をTextViewに表示するサンプルコードを示します。

```kotlin
val textView = findViewById<TextView>(R.id.textView)
textView.text = "0" // 最初はリスナー呼ばれないので、初期表示は自分で設定する必要がある
snapHelper.setSnapListener {
    textView.text = it.toString() // it = Snap位置
}
```

### 番外. プログラムからSnap位置を設定する
GraivitySnapHelper#smoothScrollToPositionを使います。ここまでの手順だけだと、各項目をタップしたときにその項目が中央に表示されません。項目のクリックイベントを拾う + smoothScrollToPositionを呼ぶことで、タップした項目を中央に表示できます。

```kotlin
snapHelper.smoothScrollToPosition(position)
```

smoothでない方のSnap位置設定のAPIもありますが、期待どおりに動作しない場面がしばしばあるので、smoothの方を使うのが無難だと思います(動作しない理由は不明)。

## サンプルコード

https://github.com/KamikazeZirou/CenterSnapCarouselSample



[^1]: カルーセルを作る場合、項目のサイズに応じてRecyclerViewの幅が変化することはないと思うので、基本的に設定できると思います。描画パフォーマンスも上がります。
【NeosVR】LogiXとUIで巨大化【基礎練習】

はじめに
---
この記事は「[NeosVR Advent Calendar 2020](https://adventar.org/calendars/5277)」の15日目です！
昨日は、ChameleonO2さんの「[NeosVR始めてわからんかったことまとめ](https://nanasai.hatenablog.jp/entry/2020/12/14/181609)」でしたω

---
僕(https://twitter.com/TewiEwi_no96) がNeosVRで人にモノづくり教える時に説明する内容を記します。
NeosVRが好きになるキッカケになってもらえると嬉しいです。
必要知識
---
・デブチップの使い方(https://neosvrjp.memo.wiki/d/DevToolTip)
・ロジックスチップの使い方(https://neosvrjp.memo.wiki/d/LogiX)

---
デブチップのコンテキストメニューから新規作成。
オブジェクトのNeosUIから下記入力オブジェクトを生成し

以下のような階層構造にしてください。
Scale
┣Visual
┃┣Text Field
┃┣Button
┃┣Button
┃┣Numeric UpDown
┃┣Numeric UpDown
┃┣Basic
┃┗Basic
┗Moduals
　┗SetUserScale
![20201206191405_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556177/b1c3ac0f-0c9a-ac2a-168a-1307d3733b1f.jpeg)

見た目
---
デブチップから新規作成で以下のようなUIを生成してみましょう！
![2020-12-06 17.31.27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556177/2a9a217d-346c-d9f6-7af8-3324eb894994.jpeg)


LogiX
---
ノードブラウザを開いて以下のようにつないでみましょう！
Interaction -> ButtonEvents
Operators -> Parsing -> ParseFloat
Users -> UserFromUsername
Users -> UserUserRoot
Users -> UserRoot -> SetUserScale

![2020-12-07 12.33.04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556177/4c032f85-cc39-71f2-82d8-e24f6308dace.jpeg)

オブジェクトのSet User Scaleにロジックスチップを装備してパッキングすれば完成です！

お疲れ様でしたω

FUNBOXで支援してもらえると記事を書く励みになります。
---
https://frick.fanbox.cc

終わりに
---
明日は、銀鮭さんの[xxx]()です！
classjsアコーディオン

``` javascript.js

(() => {
  /**
   * アコーディオンclass
   */
  class Accordion {
    // 初期化
    constructor(obj) {
      const $elm = document.querySelectorAll(obj.hookName);
      const elmLen = $elm.length;
      let j = 0;
      while (j < elmLen) {
        const $trigger = $elm[j].getElementsByTagName(obj.tagName);
        const triggerLen = $trigger.length;
        let i = 0;
        while (i < triggerLen) {
          $trigger[i].addEventListener("click", (e) => this.clickHandler(e));
          i++;
        }
        j++;
      }
    }
    /**
     * クリックしたら実行される処理
     */
    clickHandler(e) {
      e.preventDefault();
      const $target = e.currentTarget;
      const $content = $target.nextElementSibling;
      if ($content.style.display === "block") {
        $content.style.display = "none";
      } else {
        $content.style.display = "block";
      }
    }
  }

  const addAccor = new Accordion({
    hookName: "#accordion",
    tagName: "dt",
  });
  const addAccora = new Accordion({
    hookName: ".accordion",
    tagName: "dt",
  });
})();

```
JavaScript6, Jsからhtmlにクラスを追加する,classList,add,remove, toggle,初心者向け

6,クラスの切り替え

Jsからhtmlにクラスを追加する
JS（JavaScript）コーディングでよく使う、クラスの切り替えについて説明しています。
classListのadd, remove, toggleを使い分けて、様々な処理ができるようになりましょう！



```
document.getElementById("test").addEventListener("click", function() {
  document.getElementById("test").classList.add("test2");
})
↓
document.getElementById("test").addEventListener("click", function() {
  this.classList.add("test2");
})
```


  document.getElementById("test").classList.add("test2");
ここのクラスにtest2を追加する

  this.classList.add("test2");
今イベントが起きてる要素ならthisで代用できる

  this.classList.remove("test2");
.removeは逆でその要素を取り除く

  this.classList.toggle("test2");
ついてる時に取って、ついてない時に付ける
【SAP CP】CF環境にpythonで作るWebAPI

# はじめに
この記事は SAP Advent Calendar 2020 の12月15日分の記事として執筆しています

今回は、Phthon で WebAPI を作成して、CF環境上で動かしてみたいと思います。
python歴３日くらいでも WebAPI が作成できました。

# STEP 1： WebAPI を Python で作ろう

今回のプログラムで使用するモジュールのインストール準備をします。

まずは、一括インストール用に「requirements.txt」を準備します。
このファイルを利用すると、異なる環境間でのPython パッケージを管理し
必要に応じてインストールすることが出来ます。

```requirements.txt
Flask==0.12.2
flask-cors
```

requirements.txt を保存後は、python の パッケージ管理ソフトを使用して
必要なモジュールのインストールをします。

```bash
$ pip install -r requirements.txt
```

CF環境で使用するPython のバージョンを指定します。

```runtime.txt
python-3.6.12
```

CF環境のデプロイ定義ファイルを作成します。
<アプリ名> には、CF環境へデプロイ時のアプリケーション名を指定します。

```yaml:manifest.yml
applications:
- name: <アプリ名>
  path: .
  memory: 256M
  command: python server.py
```


WebAPI をPython で作りたいと思います。
以下にコードを記載しています。

```python:server.py
import os
import json
import pickle
from flask import Flask, request, abort
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

port = int(os.environ.get('PORT', 3000))


@app.route('/')
def hello():
    return "Hello World"


@app.errorhandler(404)
def error_not_found(error):
    result = "{\"message\": \"pickle file not found\"}"
    return result, 404


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=port)
```

# STEP 2： CF環境へデプロイ

CF環境へ作成したプログラムをデプロイします。
ここでは、トライアル環境へアップしてみます。

実行環境を指定してログインします。

```bash
$ cf api <APIエンドポイント>
```
ここで指定する <APIエンドポイント> は、SAP Cloud Platform Cockpit から確認出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303235/cfacbcc2-afbd-79c8-310d-07979f31ec83.png)

接続に成功すると、email とパスワードで認証が入ります。
登録した email とパスワードを使用してログインします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303235/5aedbae1-969e-5448-0e14-3a5a455b16dd.png)

接続先の組織を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303235/a7b6f50b-8cba-5313-e2e3-3065f2bdd599.png)

ここで指定する <組織> も、SAP Cloud Platform Cockpit から確認出来ます。

デプロイ先のCF環境が指定できましたので、CF環境へデプロイします。

```bash
cf push <アプリ名>
```

# STEP 3: 実行
デプロイに成功すると、SAP Cloud Platform Cockpit にアプリケーションが追加され
Status が `RUNNING` と表示されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303235/f70620b8-dcbf-21ab-a685-33ec307bf354.png)

では、作成したAPIを実行しましょう。
Application Routes に記載された URL をクリックします。

今回は '/' へアクセスすると動くように作成しているので
成功すると以下のような画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303235/0de00a54-2903-e539-919e-cda26b5fb6d1.png)

# 最後に
今回は Python3.6.12 を使用していますが、CF環境で利用できる PHPのバージョンは変動するようです。
過去に自分が試作したときは、Python3.5.10 を使用していたのですが
今回の投稿に向けて、CF環境へ同じプログラムのデプロイを試みようとしたところ、Python3.5.10 は利用出来なくなっていました。
あまり古いバージョンのPythonは、利用しないほうが良いかもしれません。

# 参考URL
https://docs.cloudfoundry.org/buildpacks/python/index.html
JSONFormatElements関数の配列の順序

[FileMaker Advent Calendar 2020](https://qiita.com/advent-calendar/2020/filemaker) の15日目の記事です。  

# はじめに  


みんな大好きJSON関数。今日はその中のJSONFormatElements関数について考察したいと思います。  

# JSONFormatElements関数とは  

ヘルプページ、[JSONFormatElements](https://fmhelp.filemaker.com/help/18/fmp/ja/index.html#page/FMP_Help%2Fjsonformatelements.html%23ww1298671)によると次のように記載されています。  
> JSON データ内の要素を読みやすい形に書式設定します。  

また、[JSON 関数の使い方](https://fmhelp.filemaker.com/help/18/fmp/ja/index.html#page/FMP_Help%2Fjson-functions.html%23ww1155067)には

> メモ 
•JSON パーサは配列内の要素の順序は維持しますが、オブジェクト内の要素の順序は維持しません。そのため、JSON 関数は指定した順序とは異なる順序でオブジェクトの要素を返すことがあります。  

と、最下段にメモとして記載があります。これは[json.org](https://www.json.org/json-ja.html)に書かれたJSONの仕様についての記述だと思われます。  

# 要素の順序
さて、ここでは**パーサ**と書かれていますが、FileMakerの標準機能でのパーサは**JSONFormatElements関数**になるでしょう。  

JSONの仕様ではオブジェクト内の要素の順番は維持されないとあります。では、JSONFormatElementsではどうでしょうか？  

[JSON 関数の使い方](https://fmhelp.filemaker.com/help/18/fmp/ja/index.html#page/FMP_Help%2Fjson-functions.html%23ww1155067)ページの一例を使って見ていきましょう  

### 配列内の要素

``` JSON:JSONFormatElements前
{
	"ベーカリー" : 
	{
		"製品" : 
		[
			{
				"id" : "FB1",
				"名前" : "ドーナツ",
				"価格" : 1.99,
				"在庫" : 43,
				"カテゴリ" : "パン",
				"特売" : true
			},
			{
				"id" : "FB3",
				"価格" : 3.95,
				"名前" : "バゲット",
				"在庫" : 34,
				"カテゴリ" : "パン", 
				"特売" : true
			},
			{
				"id" : "FB2",
				"価格" : 22.5,
				"名前" : "チョコレートケーキ",
				"在庫" : 23,
				"カテゴリ" : "ケーキ", 
				"特売" : true
			}
		]
	}
}
```  
※ヘルプページの例とは配列内の順番を変えています
</br>

すでに展開された状態ですが、JSONFormatElementsを使って整形します。

``` JSON:JSONFormatElements後
{
	"ベーカリー" : 
	{
		"製品" : 
		[
			{
				"id" : "FB1",
				"カテゴリ" : "パン",
				"価格" : 1.99,
				"名前" : "ドーナツ",
				"在庫" : 43,
				"特売" : true
			},
			{
				"id" : "FB3",
				"カテゴリ" : "パン",
				"価格" : 3.95,
				"名前" : "バゲット",
				"在庫" : 34,
				"特売" : true
			},
			{
				"id" : "FB2",
				"カテゴリ" : "ケーキ",
				"価格" : 22.5,
				"名前" : "チョコレートケーキ",
				"在庫" : 23,
				"特売" : true
			}
		]
	}
}
```


> 配列内の要素の順序は維持しますが、  


```JSON:JSONFormatElements後
{
	{"id" : "FB1"},
	{"id" : "FB3"},
	{"id" : "FB2"}
}
```
ご覧のように配列内の順序は維持されています。（他の要素は省略）  
</br>

### オブジェクト内の要素
続いてオブジェクト内の要素も見てみましょう。


> オブジェクト内の要素の順序は維持しません。

メモにはこうあります。

```JSON:JSONFormatElements前
{
	"id" : "FB1",
	"名前" : "ドーナツ",
	"価格" : 1.99,
	"在庫" : 43,
	"カテゴリ" : "パン",
	"特売" : true
},  
```
```JSON:JSONFormatElements後
{
	"id" : "FB1",
	"カテゴリ" : "パン",
	"価格" : 1.99,
	"名前" : "ドーナツ",
	"在庫" : 43,
	"特売" : true
},
```

keyの順序が変わっています。さらに言うと、名前順でソートされているようです。  
日本語だとわかりにくいので英語版のヘルプのJSONで見てみましょう。 

```JSON:JSONFormatElements前
{
	"id" : "FB1",
	"name" : "Donuts",
	"price": 1.99,
	"stock" : 43,
	"category" : "Breads",
	"special" : true
},
```

```JSON:JSONFormatElements後
{
	"category" : "Breads",
	"id" : "FB1",
	"name" : "Donuts",
	"price" : 1.99,
	"special" : true,
	"stock" : 43
}
```

アルファベット順にソートされていますね。  

# まとめ  

FileMakerのJSONFormatElements関数では、オブジェクト内の要素の順序はKeyの名前順でソートされると考えてよさそうです。  
ただ、ヘルプに記載があるわけではないのでいつ仕様がかわるかはわかりませんが……（ソートされるの前提で書いたスクリプトがあるから変更されないでほしいな〜〜）

以上、ヘルプにはないJSONFormatElements関数の考察でした。

なんて書いたけど巷では常識だったりして……
FirebaseUiでユーザー作成時に、認証プロバイダのサムネイルを引き継ぐ方法

## Firebase UI
FirebaseにはFirebaseUIという、ユーザー認証を素晴らしく楽にさせてくれる素晴らしいシステムがあります。

少しコードを書くだけで、googleアカウントはもちろんfacebookやtwitter、github、SMS認証、メール認証なども網羅しているすごいやつです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266081/2d26c94f-980b-9093-60b1-ca0478c356b8.png" width="300px"/>
(※firebase.google.comより引用)

本記事では、Firebase UI を利用してユーザー登録を行なった際に、利用したプロバイダに登録している画像を取得・保存する実装について書いていきます。


## 概要
Functionsにて、`authenticate`でユーザーが作成される事をフックして、Firestoreにユーザー情報を取得すると同時に、Storageに認証プロバイダのユーザーアイコンを保存するといった仕組みを撮りました。

## 実装

必要なモジュールたちをインポートします。

```js:functions/index.js
const functions = require('firebase-functions')
const admin = require('firebase-admin')
const axios = require('axios') // いつもの子
const path = require('path') //////
const os = require('os') // ここら辺を使って画像取得、送信準備をおこないます。
const fs = require('fs') ///////
const STORAGE_BUCKET = 'XXXXX-YYYYYYYY-ZZZZZZZ' // 自分のfirebaseアプリ名が含まれた？、storageのバケット名です。

admin.initializeApp()
const db = admin.firestore()
```

ユーザの作成イベントをフックしてfirestoreにデータを保存する処理です。storageへの保存は非同期でおこないました。

```js:functions/index.js
exports.userCreated = functions.auth.user().onCreate(async (user) => {
  const encodedPath = encodeURIComponent(`/images/users/thumbnails/${user.uid}.jpg`)
  uploadThumbnail(user)
  
  db.collection('users').doc(user.uid).set({
    name: user.displayName,
    // getSignedUrlを利用するのが本来のやり方のようですが、いまいちうまくいかないので、非公式ではありますが
    // 色々なサイトに書かれている方法でstorage画像へのパスを保存しました。
    thumbnail: `https://firebasestorage.googleapis.com/v0/b/${STORAGE_BUCKET}/o${encodedPath}?alt=media`,
    updated_at: new Date(),
    created_at: new Date(),
  })
```

`user.photoURL`の中にプロバイダのユーザーアイコンが入っているため、そこからごにょごにょしてからstorageに送信する処理です。
(`arraybuffer`のままstorageに送れたかもです。知ってたらおしえてください :bow:)

```js:functions/index.js
async function uploadThumbnail (user) {
  const bucket = admin.storage().bucket()
  const tmpFile = path.join(os.tmpdir(), `tmp_${user.uid}.jpg`)
  const res = await axios.get(user.photoURL, {responseType: 'arraybuffer'})
  fs.writeFileSync(tmpFile, new Buffer.from(res.data), 'binary')

  const filePath = `images/users/thumbnails/${user.uid}.jpg`
  bucket.upload(tmpFile, { destination: filePath }).then(res => {
    return 'success'
  }).catch(e => {
    console.log(`[ERROR]: at uploadThumbnail --- ${e}`)
  })
  return ''
}
```

これでユーザーのアイコンがプロバイダから引き継げました！！
関係ないですが、authのフックをするのが至極簡単で本当に素晴らしきですね。。。

## 終わり！
ユーザー認証の際に認証に利用したプロバイダに登録してあるアイコンを引き継ぐ方法でした!
著作権とかあるとおもうので、引き継ぐか否かとかはユーザーに確認取った方がいい、かも、、、？

ありがとうございました！
Laravelのmodelでphp-enumをいい感じに使う

# はじめに
Laravelでenumを扱おうとすると、よく出てくるのがこの三つのライブラリです。

* [myclabs/php-enum](https://github.com/myclabs/php-enum)
* [BenSampo/laravel-enum] (https://github.com/BenSampo/laravel-enum)
* [nasyrov/laravel-enums] (https://github.com/nasyrov/laravel-enums)

このうち、下二つはLaravel用のライブラリなので、親和性は高いと思うのですが、他PHPフレームワークを使う時に応用が効かないかなと思って、個人的にはphp-enumを推しています。(そもそもphp-enum以外は使ったことがないので、こっちのがいいぜ！という時は教えていただけるとありがたいです）

そういう訳で、laravelでphp-enumを使う時の個人的なベストプラクティスを紹介します。

| ライブラリ | バージョン |
|:-:|:-:|
|  laravel | 6.18   |
| php-enum | 1.7 |


# やり方

## enumの定義

php-enumでは、`MyCLabs\Enum\Enum`クラスを継承したクラスに、定数を定義することで、num値を定義します。このような感じです。

```php
<?php

declare(strict_types=1);

namespace App\Enums;

use MyCLabs\Enum\Enum;

class RoleType extends Enum
{
    public const SUPER_ADMIN = 'SUPER_ADMIN';

    public const ADMIN = 'ADMIN';

    public const USER = 'USER';
}
```

## マイグレーションの作成

マイグレーションファイルを作る時は、`Blueprint`の`enum()`メソッドを使います。第二引数にはenumとして許可する値の配列を渡します。php-enumでは、`values()`メソッドでそのenum内で定義されている値の配列を得ることができるので、この値を渡します。


```php
class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('users', function (Blueprint $table): void {
            $table->enum('role', RoleType::values());
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('users');
    }
}
```

## モデルの定義


`User`モデルに`RoleType`を持たせる時、今の状態では`$user->role`としても`RoleType`のインスタンスは取れず、DB上にあるスカラー値しか取れません。また、`$user->role`に`RoleType`をそのままセットすることもできず、スカラー値に変換してからセットする必要があります。

```php

$role = RoleType::ADMIN();
$user = new User();

$user->role = $role->getValue();
$role = new Role($user->role);

// NG
// $user->role = $role;
```

プロパティの値を使う度に変換を行うのは手間なので、Laravelのミューテタ[^muteta]を使います。
以下のように`getRoleAttribute〇〇()`, `setRoleAttribute〇〇()`メソッドを定義しておくことで、laravelがよしなに変換をしてくれます。

```php

<?php

declare(strict_types=1);

namespace App\Models;

use App\Enums\AnaUserRole;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['role'];

    public function getRoleAttribute(string $value): RoleType
    {
        return new Role($value);
    }

    public function setRoleAttribute(RoleType $role): void
    {
        $this->attributes['role'] = $role->getValue();
    }

}
```

このようにかけます。

```php

$role = RoleType::ADMIN();
$user = new User();

$user->role = $role;
// $roleはRoleTypeのインスタンス
$role = $user->role;
```

以上！

# 参考文献
[^muteta]: https://readouble.com/laravel/6.x/ja/eloquent-mutators.html
ubuntu cloud image の見分け方

ubuntu cloud image を専ら libvirtd 環境で使っているのですが、イメージで選択で悩んだのでメモ。

OS としては同じものなのだけど、配付形式の都合でちょっとづつ違うイメージ達。例えば今書いている時点では focal amd64 では suffix に次のようなものがあります。

- azure.vhd.zip
- disk-kvm.img
- lxd.tar.xz
- root.tar.xz
- vagrant.box
- wsl.rootfs.tar.gz
- img
- ova
- squashfs
- tar.gz
- vmdk

それぞれが何なのかは、例えば[記事](https://gihyo.jp/admin/serial/01/ubuntu-recipe/0565)にある通りなのですが、悩んだのは disk-kvm.img です。

img は qcow2 形式です。disk-kvm.img も qcow2 形式です。違いは何かと結論からいくと、インストールされているパッケージが異なりました。それは .manifest ファイルの差分を見ると分かります。

```diff
--- focal-server-cloudimg-amd64.manifest        2020-12-10 14:21:09.000000000 +0000
+++ focal-server-cloudimg-amd64-disk-kvm.manifest       2020-12-10 14:19:23.000000000 +0000
@@ -354,14 +354,13 @@
 libyaml-0-2:amd64      0.2.2-1
 libzstd1:amd64 1.4.4+dfsg-3
 linux-base     4.5ubuntu3.1
-linux-headers-5.4.0-54 5.4.0-54.60
-linux-headers-5.4.0-54-generic 5.4.0-54.60
-linux-headers-generic  5.4.0.54.57
-linux-headers-virtual  5.4.0.54.57
-linux-image-5.4.0-54-generic   5.4.0-54.60
-linux-image-virtual    5.4.0.54.57
-linux-modules-5.4.0-54-generic 5.4.0-54.60
-linux-virtual  5.4.0.54.57
+linux-headers-5.4.0-1026-kvm   5.4.0-1026.27
+linux-headers-kvm      5.4.0.1026.24
+linux-image-5.4.0-1026-kvm     5.4.0-1026.27
+linux-image-kvm        5.4.0.1026.24
+linux-kvm      5.4.0.1026.24
+linux-kvm-headers-5.4.0-1026   5.4.0-1026.27
+linux-modules-5.4.0-1026-kvm   5.4.0-1026.27
 locales        2.31-0ubuntu9.1
 login  1:4.8.1-1ubuntu5.20.04
 logrotate      3.14.0-4ubuntu3
```

generic と kvm の違いのようです。ちょうど[azure 向けに kernel が調整](https://ubuntu.com/blog/microsoft-and-canonical-increase-velocity-with-azure-tailored-kernel
)されたりしているのと同様で、深くは追っていないのですが、[KVM の guest 向けのチューニング](https://www.linux-kvm.org/page/Tuning_Kernel#Kernel_for_guest_with_paravirtualization) が適用されているのでしょう。kvm/libvirtd 向けであれば、こちらのほうが良さそうです。

ただし、NIC を **virtio** にするのをお忘れなく。

```xml
<interface type="network"><model type="virtio"/></interface>
```
chaiのassertをtry-catchするときに注意！

# 概要
AssertionErrorはtry-catchでcatchされるので気をつけましょう（自戒）という話です。
当たり前といえば当たり前かもしれません。。。

# 普通に失敗させる
tey-catchなしでassert.fail()させます。
AssertionErrorが発生して、結果はfailing(失敗)となります。

```typescript:例
describe("test", () => {
  it("assertion without try-catch", () => {
    assert.fail("failed!!!");
  });
});
```

```text:結果
  test
    1) assertion in try-catch

  0 passing (209ms)
  1 failing

  1) test
       assertion in try-catch:
     AssertionError: failed!!!
```

# try-catchしてみる
assert.fail()をtryで囲って、catchします。
すると結果はpassing(成功)なります。
assert.fail()で発生したAssertionErrorがcatchされるためです。

```typescript:例
describe("test", () => {
  it("assertion in try-catch", () => {
    try {
      assert.fail("failed!!!");
    } catch (e) {
      console.log("AssertionError is caught : " + e.message);
    }
  });
})

```

```text:結果
  test
AssertionError is caught : failed!!!
    √ assertion in try-catch

  1 passing (221ms)
```

# エラーが出ることをテストしたいこともあるよね
ここまではなんだか当たり前のような気がしますね。
ここからが本題です。（遅い）
異常系のテストでは正しくエラーが出ることを確かめたいのです。

次の例では、throwMyError()関数がエラーを出すことを確かめるテストをしようとしています。

```typescript:例
describe("test", () => {
  it("an error occurs", () => {
    try {
      throwMyError();
      assert.fail("Failed because no error has occurred.");
    } catch (e) {
      //Success because an error occurred.
      console.log(e.message);
    }
  });

  const throwMyError = () => {
    throw new Error("My error has occurred.");
  };
});
```

```text:結果
  test
My error has occurred.
    √ an error occurs

  1 passing (218ms)
```

エラーが出ればcatchされて成功していますね。
では、エラーが出なければassert.fail()で失敗するでしょうか？
試しにthrowMyError()でエラーを出さないようにしてみましょう。

```typescript:例
describe("test", () => {
  it("an error occurs", () => {
    try {
      throwMyError();
      assert.fail("Failed because no error has occurred.");
    } catch (e) {
      //Success because an error occurred.
      console.log(e.message);
    }
  });

  const throwMyError = () => {
    console.log("We have no error...");
  };
});

```

```text:結果
  test
We have no error...
Failed because no error has occurred.
    √ an error occurs

  1 passing (212ms)
```

というわけで成功していますね。
前述のとおり、assert.fail()が結局catchされてしまいます。

# エラーがあることを確かめるテストの実装例
ここまでたどり着いた私たちはフラグを使うことにしました。
エラーの出るべきところでエラーが出なかったときに、hasErrorフラグをfalseに切り替えて、**catchの外で**フラグを見てassert.fail()とすることでAssertionErrorがcatchされることなく失敗となります。

```typescript:例
describe("test", () => {
  it("an error occurs", () => {
    let hasError = true;
    try {
      throwMyError();
      hasError = false;
    } catch (e) {
      //Success because an error occurred.
      console.log(e.message);
    }
    if (!hasError) {
      assert.fail("Failed because no error has occurred.");
    }
  });

  const throwMyError = () => {
    console.log("We have no error...");
  };
});
```

```text:結果
  test
We have no error...
    1) an error occurs

  0 passing (212ms)
  1 failing

  1) test
       an error occurs:
     AssertionError: Failed because no error has occurred.
```

#### 今後気をつけます。以上自戒でした。
FreeCADのちょっといい話（＝バッドノウハウ）

# 環境

FreeCAD 0.18.4 Windows版

# なに、DXFがスケッチとして読み込めない？

　おそらくバグ。Shapeをたくさん読み込んでしまう。これを変換・マージしてスケッチにすると、異常なBrepができて地獄めぐりをさせられる。

　Fusion 360で読み込んで押し出す
→STEPファイルに書き出す
→FreeCADでインポート
→DraftワークベンチでShape 2D view
→できたShape2DViewオブジェクトをDraft to Sketch

　こうして得たスケッチは、正常なBrepが作れる。
Create React Appで生成したプロジェクトで開発時のみESLintを（ほぼ）無効化する

元ネタはこのissueです。
https://github.com/facebook/create-react-app/issues/9929

# Create React AppのESLintに対する姿勢
Create React Appのリポジトリでは度々ESLintを無効化したい、というissueが立ってきました。例えば[#808](https://github.com/facebook/create-react-app/issues/808)はこの件について触れられています。
2020年12月現在の最新バージョン4.0.1でも、公式に対応するための設定は用意されていません。これは意図的なもので、[disable eslint #2157](https://github.com/facebook/create-react-app/issues/2157)によれば

```
Our rules are specifically picked to not enforce style, and to only find logical mistakes.
```

とのことです。しかしながら、ファイル数が膨大になっている場合、ESLint自体がホットリロードのパフォーマンスに深刻な影響を与え、DXを著しく低下させます。TypeScriptやPrettier周りのルールを多く設定している私のプロジェクトでは、保存のたびに10～20秒程度待たされていました。

# `.eslintrc.js`の利用
ESLintの設定ファイルは通常JSON形式で指定しますが、webpack等他の多くの例に漏れず、JavaScriptで記述することもできます。環境変数で分岐させれば、開発時のみESLintを無効化（無力化）させることが可能になりますね。

```javascript:.eslintrc.js
/** @type {import('eslint').Linter.Config} */
const config = {
  // 設定の内容
};

if (process.env.DISABLE_ESLINT) {
  config.ignorePatterns = ["**/*.ts", "**/*.tsx"];
}

module.exports = config;
```

JSDocを記述しておくとIDEの補完が効くのでお勧めです。

```json:package.json
{
  "scripts": {
    "start": "DISABLE_ESLINT=1 react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test"
  }
}
```

注意点として、すべてのファイルが`ignorePatterns`にマッチするとLint対象がない、という旨のエラーになってしまいます。適当なglobパターンを指定するようにしましょう。
Intune Data Warehouseという Power BI コネクタがあったので遊んでみた

Advent Calendar のネタ何にしようか悩んでて、ふとコネクタを見てたら、こんなの見つけたんですよね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/be19a0f4-0d8c-801c-8d8e-3d8fdc82d531.png)

Intune のデータを取得することができるみたいなコネクタみたいです。
なんか面白そうだなーと思いまして試してみました。

# 資格条件

このコネクタを使用する場合は以下のいずれかのアカウントが必要です。

* Azure AD 全体管理者
* Intune サービス管理者

# 実際に使ってみる

とりあえず、使ってみましょうってことで、接続をしてみます。
ベータ版なのでーっていうお断りメッセージが表示されるので、続行しときます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/1d16a57d-a305-abc2-c110-56727aca5ce7.png)

取得する履歴データの日数を指定できるみたいで、最大60日分取得できるみたいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/77ce711d-c420-6307-e788-9c0329c5412f.png)

サインインする組織アカウントを求められます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/b1ca90ac-a474-2767-ae4c-87f8b2654ce0.png)

接続したいテナントのアカウントで認証を行いましょう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/0c4b5d3f-db50-5df3-5ba0-5d651e3a46b0.png)

問題なければ、接続します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/50a49006-4ffa-c9ba-47f1-b4a71c1cf2f8.png)

テーブル一覧はこんな感じですね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/d140026d-1cdf-18ce-2f72-e4781424e05f.png)

# 簡単なレポートを作ってみた

試しに主要なテーブルをいくつかピックアップして。簡単なレポートを作ってみました。
おお！結構わかりやすい！！（個人的な感想）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/e163e3e8-7d16-9eed-97ef-14ee3d1530a6.png)

参考までに、Intuneのダッシュボードはこんな感じです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/ef989a8f-78c9-339f-77d2-7449a686f3c2.png)

会社全体のデバイス管理は、Intune側でもいいかもしれませんが、ユーザー個別とか、端末別にとかでいろいろ管理していきたい場合は、こちらを使ってみたほうがめちゃくちゃわかりやすいと思いました。

端末管理してるけど、ちょっとわかりづらいんだよねーってお嘆きのそこの情シスのあなた！
是非 Power BI で分析してみてはいかがでしょうか？？
マンガでわかる切り貼りプログラミングアンチパターン

![C1535D3D-BCB4-4023-83CA-20586CA1C0C4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11525/8924e14e-5d77-d259-1403-a239018dc52d.png)
http://wiki.c2.com/?CopyAndPasteProgramming

コピーペースト機能を使って書かれたコードに関するアンチパターンです。一般にコピペプログラミングは良くないと言われますが、勘違いしてはいけないのが、このアンチパターンは、コピーペーストする行為そのものを禁止しているわけではないということです。コピペプログラミング禁止の真意は、[DRY 原則](https://ja.wikipedia.org/wiki/Don%27t_repeat_yourself) と同じです。

既存のプログラムとわずかに仕様の異なるプログラムが必要なとき、あるいは、すでに作られたものと同じ処理が別の箇所にも必要になったとき、安易にコピーして部分修正で仕事を進めてしまうと、非常に無駄の多いプロダクトが出来上がります。

プログラムは、たんに動けばいいわけではありません。冗長で重複が多いコード群は、その量的な無駄だけでも、メンテナンスを困難にします。コードの読みやすさはスクロール量に驚くほど反比例します。

しかも、もしコピーされたコードにバグが含まれていると、一箇所直すだけでは済まなくなります。コピー先を同じように修正すると、その場での書き換え内容と矛盾して、新たなバグを生むこともあります。

手続きをコピーするとき、せっかく何らかの意図で再利用されるものなのに、名前を与えるチャンスをみすみす逃してしまうことも問題です。どんなに優秀なプログラマーでも、いちいちコメントと手続きを読むのは苦痛です。適切なクラス名やメソッド名ほど、コードの可読性に貢献するものはありません。

コードを再利用するときは、いったんはコピペしても良い (初回単体テストをクリアするためだけ、などの目的で) けれど、かならずその意味を理解し、意味のある名前を与えて、共通化・一般化されたかたちにリファクタリングしましょう。
Biduleによるオーディオプログラミング例

Bidule
===

[オーディオプログラミング言語 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/audiolang)

# 概要

https://www.plogue.com/products/bidule.html
https://www.plogue.com/bidule/help/index.html

インタラクティブなコンピューター音楽とマルチメディアを作成するための商用ソフトウェアアプリケーション。MaxやPure Dataのようにノードを接続してプログラミングするビジュアル言語。MIDI、OSCによる通信、ReWireデバイスとしてDAWとの連携、VST2、VST3、AUプラグインのホストといった機能を持っている。また、VSTプラグインとして機能するプラグインバージョンも用意されている。

開発はPlogue Arts and Technology社(カナダ)
モントリオール大学でコンピュータサイエンスの学位を取得したDavid ViensとSébastien Beaulieuは、2000年にPlogue社を起業してVSTプラグインを制作する。その過程で使いやすいモジュラー式VSTホストの必要性を感じBiduleが開発された。最初のリリースは2002年。

# 実装例

## サイン波生成

OscillatorノードにConstantノードでパラメータを与えてOutputに接続すると音が鳴ります。

![sine.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22455/75f9ef89-d4a5-c103-b7ae-601ee03db53a.png)


## Delayエフェクト

Audio File Playerノードでwavファイルを再生することができます。Stereo DelayノードはWet GainがないのでDry GainをゼロにしてミキサーでDry/Wetのバランスを調整できるようにしました。

![delay.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22455/9b9e4105-f3d9-514a-1df7-e2f261b1c1bf.png)



# 感想

商用製品だけあって、ReWire、VST、AUなどのサポートが充実しています。現在も頻繁にバージョンアップされており、最新のOSにも対応しています。2002年から現在まで継続的に開発されてきたソフトウェアであるためユーザー数は比較的多く、ユーザーフォーラムのコミュニケーションも盛んにおこなわれています。

シンプルでわかりやすい反面、ノード型ビジュアル言語としてはさほど独自性はなく、今回作成したようなプログラムではMax、REAKTORなどに対する明確な優位性は感じられませんでした。公式ページの情報によると、FFTで周波数領域に変換した後の操作や、マルチチャンネル、アンビソニックなどに強いことが売りのようです。また、開発当初Biduleの技術は高く評価されており、Garritan、Sibeliusといったメジャーな商用音源デベロッパーにライセンス供与され、後のPlogueとGarritanによるARIAエンジン開発につながります。

販売価格は日本円で1万円程度。バージョンアップ時に試用版も一定期間公開されます。期間限定のため時期によっては試用版をダウンロードできないことがあります。

[オーディオプログラミング言語 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/audiolang)
ノーコードでBigQueryの結果をDatastoreへ入れる

Fringe81アドベントカレンダー2020の14日目の記事です.

突然ですが、dataflow使ってますか？ 
GCPをお使いの方なら聞いたことあるかも...という方は多いと思いますが、使ってるよ！という人は少ない？
dataflowはその名の通りよしなにデータを移すことができる実は使い勝手豊富なソリューションです。
非エンジニアの方でもコードを書かずに実行できます❗️
ここではその実力の一端をサクッと紹介したいと思い記しました。

## やること
サービスで使うには強力だけど、機能がシンプルな故にデータの出し入が気軽でない(コードを書く必要ある)代表として、NoSQLのdatastoreに手軽にデータを入れる方法を試します。
手軽に扱えてI/O周りの機能も充実しているBigQueryをハブとして使うと便利かなと考えました。
(動作確認テストのため、bqクエリで整合性を担保したデータを作成してdatastoreへ入れるケースを想定)

## ザックリとした流れ
### bq
- member
![スクリーンショット 2020-12-15 0.06.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26997/57d2d176-2d95-f15b-4519-43a0be689d34.png)

- team
![スクリーンショット 2020-12-15 0.06.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26997/482a7769-7d7b-aa10-bb79-7be8faf87e69.png)

__クエリで結合して↓__ 

### datastoreエンティティ作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26997/325c827c-275b-646a-5ffb-1260288be075.png)

### DAG(dataflow)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26997/3e9312a1-0be1-6b7b-2413-6d6cb128319f.png)


## 実行について(概略)
下記3ステップで実現できました。
- 1. BigQueryへデータを作成する
- 2. input(Source)をbqクエリとし、output(Sink)をdatastoreとするテンプレート(json)を作成しgcsへ配置
- 3. dataflow実行(flextemplate)

## ポイント
### bqクエリを書くだけでデータ作成
手動で整合性を担保したデータを大量に作ってNoSQLへ取り込むコード書くのは手間がかかるが、
データ作成をbqの強力なクエリで代行できます。
### jsonで定義を書くだけで様々なinput(Source)、output(Sink)パターンを設定可能。
今回は近日新規公開された [Mercari Dataflow Template](https://github.com/mercari/DataflowTemplate) を活用させていただきました。

## テンプレート(json)
- config_bq2ds.json

```json

{
  "sources": [
    {
      "name": "bigquery",
      "module": "bigquery",
      "parameters": {
        "query": "SELECT m.Id AS MemberId, t.Id AS TeamId, sum(m.Point) AS Point, t.TimeZone AS TimeZone  FROM exp_dataflow.member m INNER JOIN exp_dataflow.team t ON m.TeamId = t.id Where Point <= t.LimitPoint GROUP BY MemberId, TeamId, TimeZone;"
      }
    }
  ],
  "sinks": [
    {
      "name": "bq2ds",
      "module": "datastore",
      "input": "bigquery",
      "parameters": {
        "projectId": "{projectId}",
        "kind": "exp_memberTeam"
      }
    }
  ]
}
```



## dataflowについて
- 具体的なユースケースは[GCPUG勉強会](https://www.youtube.com/watch?v=yYBm-D9nPAo)のセッションが大変参考になりました（^人^）
BlenderとPythonでラクラクモデリング

#前書き
Blenderは無料なうえにとてもたくさんの機能が存在するので~~初見殺しとよく言われています~~モデリングをするのに持ってこいのソフトです!
とは言えいきなりたくさんの機能を使ってモデリングしようにも何からやればいいかわかんないですよね…
#そこで!
今回はたった一つの機能を使ってモデリングしていこうと思います。

#それは…
**「Pythonが書ける」**機能です!今回はこれを使っていろんなことをしていこうと思います。~~頭悪い~~
#環境設定
ここはさらっと説明します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542948/6f043b82-659f-bde8-956a-ddaf07e7a141.png)

ね!簡単でしょ

あっインストールはここです。
https://www.blender.org/





ではここからはいろんなものを作っていこうと思います
#
#プレステ2の起動時に出てくるやつ
いったい何のことって思う人もいるかもせれませんが…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542948/964fbaab-c4b8-4452-8feb-f37c26611304.png)
こんな感じのやつです

```
import bpy
import random

for i in range(30):
    for j in range(30):
        bpy.ops.mesh.primitive_cube_add(location=(i-15,j-15,0),scale=(1,1,random.randint(1,10)))

```
こんな感じになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542948/f97b75ce-a648-44c3-6618-58a0f47dfed2.png)

#某・〇・リング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542948/4638b63f-e486-c3d6-75dd-77b620f64229.png)
上のようなドーナッツを作っていきましょう

```
import bpy
import math

for i in range(8):
    bpy.ops.mesh.primitive_uv_sphere_add(location=(2*math.cos(math.pi*i/4),2*math.sin(math.pi*i/4),0))
```

location=(x座標,y座標,z座標)のx座標とy座標にcosとsinを代入しました。
要するに円周上に球を八個等間隔に並べたってことです。
これでポンッ…某リングが完成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542948/d4430d17-31ab-0737-bf8b-e3bd5081de73.png)

#グラフ(線)
今度はグラフを作りましょう。

```
import bpy
import math

for i in range(180):
    bpy.ops.mesh.primitive_cube_add(location=(i,10*(math.pow(math.log(0.05*i+1)+math.sin(math.pi*i/30),3))*math.cos(math.pi*i/90),10*(math.pow(math.log(0.05*i+1)+math.sin(math.pi*i/30),3))*math.sin(math.pi*i/90)))


```

今回は$10\times log_e(0.05\times x+1)+\sin({x\pi/30})$という極形式を縦軸成分と横軸成分に分解してθを媒介変数としたグラフになっております

ちなみにこんな感じのグラフになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542948/1b4c0b93-cb82-ed58-094c-c1a4fac89e9c.png)
全体図と各軸から見た図



このソースコードどっかで見たことがあるって?~~[君のような勘のいいガキは嫌いだよ](https://qiita.com/Emmomi1/items/84a6b1edf15de5384d05)~~

#グラフ(平面)
さて次はこれを平面にしましょう。

```
import bpy
import math

for i in range(30):
    for j in range(20):
        bpy.ops.mesh.primitive_cube_add(location=(i,20-j+10*(math.pow(math.log(0.05*i+1)+math.sin(math.pi*i/30),3))*math.cos(math.pi*i/90),j+10*(math.pow(math.log(0.05*i+1)+math.sin(math.pi*i/30),3))*math.sin(math.pi*i/90)))

```
先程の式の横軸に等間隔に並べ縦軸はキューブ同士の間隔を少し開けました。
なおこんな感じのグラフになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542948/115e0471-7f21-52e5-610f-1b5434ba2116.png)

#終わりに
今回はPythonで簡単にモデリングする方法をいろいろ書きました。他にもいろんなことに使えるので是非やってみてくださいね!
position:absolute;の要素中央寄せ


画像の上にテキストボックスの要素を作り、`position: absolute;`　を指定した時、重ねた要素を中央寄せにしたかったのですが、どうやるんだっけ？となってしまったので、忘れないよう自分用にメモしておきます。

**イメージ**
![WS000000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/952495/142923b4-6691-108b-d15d-2e1c7160b8f8.jpeg)

ちなみにこれは、要素を上に重ねて中央寄せにした後、
`top: -〇〇%`とマイナスに配置しています。


## 左右を中央寄せにする場合
```CSS:CSS
.example {
    position: absolute;
    left: 0;
    right: 0;
    margin: auto;
}
```

左右のポジションを0にして、marginで中央に寄せている、という感じです。

もしくは、

```CSS:CSS
.example {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
}
```

でも可能。
`transform`プロパティを使用して、表示位置のX軸を-50%分移動させています。



## 上下を中央寄せにする場合
```CSS:CSS
.example {
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto;
}
```
これも、さっきの逆で同じ考え方です。
上下のポジションを0にして、marginで中央に寄せています。

もしくは、

```CSS:CSS
.example {
    position: absolute;
    top: 50%;
    left: 0;
    transform: translateY(-50%);
}
```

でも可能。
`transform`プロパティを使用して、表示位置のY軸を-50%分移動させています。


## 上下左右を中央寄せにする場合
```CSS:CSS
.example {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: auto;
}
```

上下左右のポジションを0にして、marginで中央寄せ。

もしくは、

```CSS:CSS
.example {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
```

でも可能。
`transform`プロパティを使用して、表示位置の上下左右-50%分移動させています。


　


## まとめ
top、left、right、bottomの指定だとうまくいかないこともあるので、その時は`transform`プロパティを使用してみるといいです。
上下左右の中央寄せは結構使うので、このメモが誰かの役に立てばいいな、、笑


## 参考リンク
[position: absolute;を中央寄せする方法](https://cotodama.co/position-absolute-center/)
[position: absoluteで中央に要素を寄せる最新の方法【css】(上下左右、上下、左右)](https://arts-factory.net/position/)
Notionでボードの並び順を固定する

アルプ株式会社でエンジニアをしています、集約のエンティティ@pictinyです。
これは[Notion Advent Calendar 2020](https://qiita.com/advent-calendar/2020/notion) 14日目のエントリです。
13日目は[NotionでKPTボードを作る](https://qiita.com/pictiny/items/d2a3774d6eeadcb2c2e5)でした。

# ボードの同時編集
データベースのボードを複数人で同時編集すると、同期処理の遅延が起こりカードの順番が突然入れ替わることがあります。

## ソート
ボードの並び順は、右上の `Sort` ボタンから固定することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/6a44dd3e-a514-57ae-14f9-06dddc991978.png)

ソート設定をしない場合、カードをドラッグアンドドロップすることで順番を入れ替えることができます。
カードの並び順は[View](https://qiita.com/pictiny/items/d2a3774d6eeadcb2c2e5#kpt%E3%83%9C%E3%83%BC%E3%83%89)に保存されるため、プロパティに従わない順番を保持したい場合にはソートを設定しない方がよいでしょう。

## まとめ
[KPTボード](https://qiita.com/pictiny/items/d2a3774d6eeadcb2c2e5#kpt%E3%83%9C%E3%83%BC%E3%83%89)のような複数人が同時編集するボードでは、作成日時によるソート設定を入れておくとよいでしょう！

公式ドキュメントは[Sort](https://www.notion.so/Intro-to-databases-fd8cd2d212f74c50954c11086d85997e#a56d7f3ad50f43bb9a0b7af8d6cb22e5)にありますので、そちらもご覧ください。
コミットするしないを任意に選択できるテク

#はじめに
　現在、アプリケーションの作成において、バージョン管理をGit、GitHubを使っています。さらに、コミット等を簡単にするGitHub Desktopを使っています。

##コミットするファイルを選択できる


![](https://i.gyazo.com/a42c7608009c7d3f86263ca359d31d64.png)

左のチェックを外すことで、外したファイルはコミットされない。
つまり、一度に大量にエディタで編集や追加を行っても、ファイルが違えば、GitHub Desktop上でコミットしたいファイルを選択することができる。コミットする順番も任意にできる。
ただし、同じファイルの中でコミットのするしないの選択はできないので、そこだけは注意が必要です。
コメントの即時更新機能について

## Action Cable
　メッセージの即時更新機能を実装するためには、**Action Cable**というフレームワークを使用します。このフレームワークは通常のRailsのアプリケーションと同様の記述で、即時更新を実装できます。

## Channel（チャネル）
　コメントなどを即時に表示させるために、データの経路を設定したり、送られてきたデータを表示させるJavaScriptを記述するのですが、これらの役割を担っているのが**Channel（チャネル）**です。即時更新機能を実現するサーバー側の仕組みのことをいいます。

## 実装方法
#### ①チャネルの作成

```ruby
% rails g channel comment
```
　このコマンドをターミナルで実行すると以下のファイルが作成されます。

```ruby
Running via Spring preloader in process 11084
      invoke  test_unit
      create  test/channels/comment_channel_test.rb
      create  app/channels/comment_channel.rb
   identical  app/javascript/channels/index.js
   identical  app/javascript/channels/consumer.js
      create  app/javascript/channels/comment_channel.js
```

#### ②comment_channel.rbの編集
　このファイルは、サーバーとクライアントを繋ぐファイルで、**stream_from**メソッドを用いて、サーバーとクライアントの関連付けを設定します。

```ruby
class MessageChannel < ApplicationCable::Channel
  def subscribed
    stream_from "comment_channel"
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end
end
```

#### ③comments_contorller.rbの編集
　コメントの保存が成功した時に、**broadcast**を介してコメントを送信されるように記述する。

※broadcastとは、サーバーから送られるデータの経路のこと。

```ruby
class CommentsController < ApplicationController
  def new
    @comments = Comment.all
    @comment = Comment.new
  end

  def create
    @comment = Comment.new(text: params[:comment][:text])
    if @comment.save
      ActionCable.server.broadcast '@comment_channel', content: @comment
    end
  end
end
```

#### ④comment_channel.jsの編集
```ruby
import consumer from "./consumer"

consumer.subscriptions.create("CommentChannel", {
  connected() {
    // Called when the subscription is ready for use on the server
  },

  disconnected() {
    // Called when the subscription has been terminated by the server
  },

  received(data) {
    const html = `<p>${data.content.text}</p>`;
    const comments = document.getElementById('comments');
    const newComment = document.getElementById('comment_text');
    comments.insertAdjacentHTML('afterbegin', html);
    newComment.value='';
  }
});
```
チェックリストの牢獄から抜け出すために


[闇の魔術に対する防衛術 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/yaminomajutu) 16日目の記事です。

# はじめに
いまだに少なくないシステム開発現場の最前線で品質を守っている『チェックリスト』。
プロダクトが長く続くにつれ肥大化していくチェックリストはディメンターの如く活力を奪っていくものです。
そんな『チェックリストの牢獄』から脱獄するための改善方法についてつらつらと書いてみたいと思います。

※ この記事における『チェックリスト』について
　レビューなど成果物のチェックを行う際のポイントが記載されたものを指します

# 対象とする読者
チェックリストの量がすさまじい。
むだっぽいチェック項目が多くてうんざりしている。
なんかいけてないチェックリストを使っている。

# 脱獄するには
とにかくチェックリストをより良いものにし、数を減らしていくしかありません。
しかし不用意に減らして不具合を起こしてしまっては本末転倒。
今までの私の経験から、有効と思えるチェックリスト対策を以降で書いていきたいと思います。

# 改善１．チェックリストのターゲットを明確にする
どの成果物に対して、誰が使うのかを明確にしましょう。
例えば『コーディングチェックリスト（Java・実装担当者向け）』のようにです。
また、使う人のレベルも想定していることが望ましいです

行った作業に対して必要最低限のチェックとなれば自然と作業効率は向上します。

私が過去にいた現場では、CとJavaとbashが入り乱れていました。そして、なぜかチェックリストも共通になっていました。
『Q.インクルードヘッダの重複チェックは行ったか？　A.対象外：Javaのため』ほんとうに無益です。

# 改善２．チェックリストの内容を明確にする
定めたターゲットが理解でき、判断結果がぶれない表現にしましょう。
考える時間や無駄な悩みを減らすことができます。

誰も理解できないような項目があれば、それは消すしかないでしょう。
また、可能な限り～のような努力項目は多くの場合『可能ではありませんでした』と扱われるでしょう。消すか徹底するか決めた方がよいです。
妥協の基準を明確にしてもよいです。

経験則からすると、理解できない項目は「OK」または「対象外」とされてしまいます。
『あ～、その項目はとりあえずOKにしとけばいいよ』なんて扱われる項目はもう要らないでしょう。

# 改善３．チェックリストの運用を定める
チェックリストをどう使うか決めましょう。
ポイントは下記です。

- いつ使うか
- いつ見直すか

## 改善３－１．いつ使うか
作業のどのタイミングで使うかを明確にしましょう。
作業のはじめに目を通しておき、おわりに成果物と照合する運用が手戻りも防げて効率的です。
ドキュメントにするなどして、必ずこれが守られる運用を構築することが重要です。

顧客とネゴった内容がチェックリストに反していたとき、変更を受け入れて貰うのは精神的にも顧客の心情的にも非常に厳しいものがあるでしょう。
実装などでも同様で、さんざん作ったあとにチェックNGですべて作り直し。これでは目も当てられません。
『手戻りに大変ですし、今回だけそのチェック項目無視しましょう』なんて言いがちですが**今回だけ**にはならないでしょう。


## 改善３－２．いつ見直すか
チェックリストの見直しタイミングを明確にしましょう。

案件の終わりでも、3か月置きでもよいです。誰がいつ見直すかを決めておくことでチェックリストの陳腐化が防げます。
無意味なチェックが並んでいるとチェックリストが軽視され、チェック漏れやみなしOKが多発します。

『記載内容が古いんで使われてないと思って、適当にOKにしてました～(^^)』とリスペクトされないチェックリストは無意味です。

# 改善４．チェックリストの内容を減らす
脱チェックリストです。最終目標でもあります。

* 勉強会を定期開催して知識定着させることで項目を減らす
* 自動化により項目を減らす
* チェックリストの必要な作業自体を何らかの方法で消す

方法は色々とあるはずです。改善１，２によって各項目が理解できていれば、消す方法はいくつか浮かんでくると思います。
『チェックリストは使ってたんですけど……。その、項目が多くて見逃しました』何のためのチェックリストなのか。ザ・本末転倒。


# まとめ
少しでもチェックリストを『まとも』に近付ける方法について書いてみました。

1. ターゲットを決める
1. 内容をわかりやすくする
1. 運用する
1. 減らす
畳み込みニューラルネットワークのメリットについて

この記事はゼロから作るDeep Learning7章の一部の内容について、自分自身の学習後のまとめとして書いています。

今まではニューロンが全結合したニューラルネットワークについて扱ってきましたが、ここからは畳み込みのニューラルネットワークの実装について学んでいきます。

そこで、多くの人が疑問に思うところが、

「なんでわざわざ畳み込みニューラルネットワークを学ぶの？今までのニューラルネットワークじゃダメなの？」

というところ、

僕も思いました。

しかし、畳み込みにすることでメリットがあります。

今までのニューラルネットワークでは一つの画像の配列を１次元に変換してからニューラルネットワークに入力を行なっていました。

この1次元にすることに問題があります。

この問題とはズバリ、「データの形状が無視されてしまう」ということです。

一般に画像データというものは空間的に近いピクセル同士が似たような値をとるはずなんです。

具体的にいうと、木の画像などを扱う時に葉っぱを表している部分は局所的に緑の色が集中するはずです。

しかし、これを1次元に直してしまうと近くのピクセル同士の関連性を壊してしまいます。

だから、畳み込みニューラルネットワークを学ぶんです。

畳み込みニューラルネットワークは画像データを3次元や４次元の構造のままニューラルネットワークに入力することができるんです！

では、具体的にどのようなレイヤを入れることで今までのニューラルネットワークとの違いが生まれているかというと、それは「畳み込み層(Convolutionレイヤ)」と「プーリング層(Poolingレイヤ)」です。

今までのニューラルネットワークでは「Affineレイヤ」と「ReLUレイヤ」を組み合わせることで層を作っていましたが、

畳み込みニューラルネットワークでは「Convolutionレイア」→「ReLUレイヤ」→「Poolingレイヤ」（Poolingレイヤは省略されることもある。)で層を作っています。

各層で行われている演算のまとめは次回まとめていこうと思います。
[Python] pytest mocker.patchがやっと動いたので、わかったことを勢いだけで書いておく

Pythonの`import`は、自名前空間に名前を導入するものだと、頭ではわかっていました。
それがやっと実地でもわかるようになりましたので、忘れないように書いておきます。すごい勢いで。

# ファイル構成

このようなファイル構成になっています。
ex_mockモジュールの下に、ExMockクラスやその他のクラスがあります。

```
.
├── README.md
├── ex_mock
│   ├── __init__.py
│   ├── __main__.py
│   ├── creator.py
│   ├── exmock.py
│   ├── greeter.py
│   └── outputter.py
├── poetry.lock
├── pyproject.toml
└── tests
    ├── __init__.py
    ├── test_ex_mock.py
    ├── test_exmock.py
    └── test_greeter.py
```

# テスト対象

テスト対象のクラスです。
コンストラクタのなかで、`Greeter`クラスと`Outputter`クラスをインスタンス化しています。

```python:exmock.py
from ex_mock.outputter import Outputter
from ex_mock.greeter import Greeter


class ExMock:
    def __init__(self):
        self.__greeter = Greeter('Hello', Outputter())

    def exec(self, name):
        self.__greeter.greet(name)
```

# テストクラス

テストクラスです。
`ExMock`をインスタンス化し、`Greeter`クラスと`Outputter`クラスが呼ばれていることをテストしています。

```python:test_exmock.py
from ex_mock.exmock import ExMock


class TestExmock:
    def test_init(self, mocker):
        # Given
        outputter = mocker.patch('ex_mock.exmock.Outputter')
        greeter = mocker.patch('ex_mock.exmock.Greeter')

        # When
        instance = ExMock()

        # Then
        outputter.assert_called_once()
        greeter.assert_called_once()
```

# 試したこと

`mocker.patch`の書き方を色々試しました。

## NGなパターン 1

実際にあるクラス名にしました。

```python
outputter = mocker.patch('ex_mock.outputter.Outputter')
```

モックは作成されましたが、`assert_called_once()`で失敗しました。

## NGなパターン 2

それではと、モジュール名+クラス名にしました。

```python
outputter = mocker.patch('ex_mock.Outputter')
```

モック作成時に、そんなもん存在しないぜとエラーになりました。

## NGなパターン 3

クラス名だけにしてみました。

```python
outputter = mocker.patch('Outputter')
```

ターゲットパス名がよろしくないぜとエラーになりました。

## NGなパターン 4

パスにしてみました。

```python
outputter = mocker.patch('.Outputter')
```

モジュール名が空だとエラーになりました。


## OKなパターン

モジュール名 + importが書いてあるファイル名 + クラス名にしました。

```python
outputter = mocker.patch('ex_mock.exmock.Outputter')
```

うまくいきました。


# わかったこと

Pythonの`import`は、名前を導入するものだということです。

テスト対象クラスにある下記`import`は、モジュール名+ファイル名であるところの`ex_mock.exmock`に`Outputter`という名前を導入しています。

```python:exmock.py
from ex_mock.outputter import Outputter
```

したがって、テストクラスの中では`ex_mock.exmock.Outputter`という名前で参照することになるのです。

# ということは？

もしかして、`import`の書き方によって、`mocker.patch`の書き方も変わる？

# 以上です

勢いだけでお届けしました。
Pythonを知っている人にとっては、常識的な話なんでしょうか？
プログラムの中から自分自身の構文木をいじれる言語っておもしろいですね。

# ソースコード

ソース全体は github に置いてあります。何かの参考になれば。

https://github.com/sengokyu/python-pytest-mock
Blockchainを初めに理解するためのキーワードをまとめてみた

# はじめに
<!-- 発端や概要を記載 -->
[Global Mobility Service Advent Calendar 2020](https://qiita.com/advent-calendar/2020/global-mobility-service)の14日目です。

今年からGlobal Mobility Serviceというグローバルベンチャーでエンジニアとして働いています。

少し前からBitcoinなどと関連して*Blockchain*に興味があって調べていましたが、最初の概要理解するための情報が少ないと感じたので、これから調べる方にとって理解の助けになると幸いです。

# Blockchainで調べてもよくわからない問題
まず、この記事を書こうと思った理由は、blockchainをキーワードにググってもよく分からなかったからです。
よくある説明はこういうもの。
>ブロックチェーンとは、分散型ネットワークを構成する複数のコンピューターに、暗号技術を組み合わせ、取引情報などのデータを同期して記録する手法。一定期間の取引データをブロック単位にまとめ、コンピューター同士で検証し合いながら正しい記録をチェーン（鎖）のようにつないで蓄積する仕組みであることから、ブロックチェーンと呼ばれる。別名「分散型台帳」。ビットコインなどの仮想通貨（暗号通貨）に用いられる基盤技術である。

また、Blockchainを理解するために「実装してみた」という記事は見かけるのですが、
そもそもどういう活用ができるかをイメージできてないと、それを習得してどう活用するかが最初は分かり辛い印象でした。

<!-- 各チャプター -->
<a id="#BlockchainとWeb3.0"></a>
# キーワード1. Web3.0
まずWeb1.0からWeb2.0、そしてWeb3.0という大きな流れの中でのBlockchainの位置付けです。

## Web1.0 ソフトウェア
![スクリーンショット 2020-12-12 0.06.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/803671/6e7d215c-c00e-cca9-e138-3e7ad55f1693.png)
- 環境   : ローカル
- データ  : クライアント
- 構造   : 単方向 (事業者 → ユーザ)

## Web2.0 アプリケーション
![スクリーンショット 2020-12-12 0.08.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/803671/546aa9a3-26df-5c1c-94ea-d39ef1ef23ab.png)
- 環境   : オンライン
- データ  : サーバー
- 構造   : 双方向 (事業者 ⇄ ユーザ)

## Web3.0 DApps
![スクリーンショット 2020-12-12 0.11.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/803671/f2fbb69c-0874-f724-90b8-d5f0fd881263.png)
- 環境   : オンライン＆オンチューン
- データ  : クライアント&ネットワーク 　　　←Blockchainの位置付け
- 構造   : 双方向 (ユーザ ⇄ ユーザ)

## つまり
注目するのは「データ」です。
現在のWeb2.0のように、データは各サービス事業者によって、サーバーで管理されるのが一般的です。
しかし今後のWeb3.0の時代では、クライアント全員が持つということが一番の特徴となります。
ここにBlockchainという技術が活用されているということになります。

<a id="#BlockchainとDApps"></a>
# キーワード2. DApps
「Decentralized application」の略で、分散型アプリケーションと呼ばれています。

![スクリーンショット 2020-12-12 0.35.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/803671/5dd5d899-aba5-5718-5bfc-e63ec15c2494.png)
例えば、SNSでは今までは投稿された記事は中央のサーバーに保存されます。
しかし、DAppsでは分散ストレージに書き込まれます。



<a id="#まとめ"></a>
# まとめ
今回ご紹介したDAppsはまだ日本ではpopularではないですが、今回紹介したSNSだけでなく、他の様々なサービスでも大きな変革をもたらす可能性があると感じました。
Blockchainとも合わせて引き続き注目していきたいと思います。


<a id="#reference"></a>
# 参考文献
- [ブロックチェーン(blockchain)の基礎知識](https://www.coindeskjapan.com/keywords/blockchain/)
- [web3.0世代のソーシャルメディア「akasha」をざっくり紹介！](http://neko-currency.hatenablog.com/entry/2018/02/17/%E8%A9%B1%E9%A1%8C%E3%81%AE%E3%80%8Eakasha%EF%BC%88%E3%82%A2%E3%82%AB%E3%82%B7%E3%83%A3%EF%BC%89%E3%80%8F%E3%81%A8%E3%81%AF%EF%BC%9F%EF%BC%9Fweb3.0%E4%B8%96%E4%BB%A3%E3%81%AE%E3%82%BD%E3%83%BC)