OmniAICreator/Qiita-1.07M huggingface dataset:
センチメント分析研究領域の紹介

## 1. はじめに
センチメント分析に興味を持ち調査したことがありました。その際、センチメント分析研究の動向を把握するのに役立ったレビュー論文があります。本記事ではその論文で紹介されているセンチメント分析研究の各領域の概要を紹介します。

![fig2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531352/b054f2a7-b262-15d3-416c-c3897a56ff54.png)

個人的な解釈を含む、簡単な説明しかしていないため、詳細を正確に知りたい方は[原著論文](https://arxiv.org/abs/2005.00357)をご覧ください。

## 2. センチメント分析研究の領域

### Aspect-based Sentiment Analysis
センチメントとその対象をセットで分析。文章が複数の側面から構成されていて、それらに関連して様々な感情を持っている場合がよくある。例えば、「この俳優は他の優秀なキャストに比べて明らかに劣る。」という文章があった場合、「俳優」対する否定的な感情と「キャスト」に対する肯定的な感情を持っている。このような場合に対応できるよう、各エンティティに対するセンチメントを特定することを目的とした分析。

### Multimodal Sentiment Analysis
マルチモーダルセンチメント分析。テキスト以外のデータ（モダリティ）も使ってセンチメントを分析する。
YouTubeのような動画コンテンツが増加しており、このような動画に含まれるユーザの感情を分析し、自社製品のマーケティングに活用することが期待されている。以下の図の下の例を見るとわかるようにテキストだけでなく、他のモダリティ（音声や画像）を使うことで人のセンチメントをより正しく判断できる可能性がある。

![fig6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531352/f569c47c-6756-7677-d89b-bdbdf2f51510.png)

### Contextual Sentiment Analysis
文脈を踏まえたセンチメント分析。例えば、大きいという言葉は文脈での使われ方によって逆のセンチメントになり得る。「大きい家で休暇を過ごす」という文脈では大きいはポジティブな感情を与え、「大きい家は掃除が大変」という文脈では大きいはネガティブな感情を与える。そのため、文脈を考慮することでセンチメントをより適切に判断できる可能性がある。
文脈情報は会話の時も有用で、短い発話を分類する時は顕著に有用（下図）。会話では、過去の会話を文脈とみなすことができる。

![fig8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531352/4032fcc4-2ca8-9b4b-02b7-cb17bc4694f2.png)

センチメントに影響を与える文脈は前後の言葉だけでなく、発言者の性格、文化的背景、置かれている状況、常識などもある。
例えば、注文がキャンセルされた時、嫌味な人はネガティブな感情を「great」という言葉で表現するかもしれない。あるいは、「先週から太陽を見ていない」という発言者のセンチメントは、一般的に太陽を長く見ていないことはネガティブな出来事という常識が通じるならネガティブとなる。

### Sentiment Reasoning
センチメントの根拠（または誰のセンチメントか）を分析。例えば、「映画はつまらなかった」と「ステラは映画がつまらないと思った」では、前者は発言者のセンチメントを表し、後者はステラのセンチメントで発言者のセンチメントではない。意見を述べたテキストを分析する際は、センチメントの持ち主を知ることが重要になることが多いため、誰のセンチメントか分析することは重要。
一方、スマートホンのレビューで「バッテリーの消耗が早いから嫌だ」と書かれていた場合、バッテリーに対するネガティブなセンチメントを知ることは重要だが、そのようなセンチメントになった原因を知ることも重要になるため、センチメントとその根拠を分析することは重要。


### Domain Adaptation
特定領域への適用（という訳になるかと思いますが、研究の方向性としては複数の領域に適用できるセンチメント分析というかと思います）。
特定の領域にセンチメント分析を適用する際、その領域の学習データを作成することになるが、適用したい領域が多数ある場合に学習データを作成することは容易ではない。そのような場合、複数の領域に適用できるセンチメント分析が求められる。

### Multilingual Sentiment Analysis
多言語に対応したセンチメント分析。大半の研究は英語のデータセットを使って行われてきたが、SNSの普及により多言語のデータセットが利用できる状況になった結果、多様な言語を用いた研究が増加している。ただ、複数言語が混在するテキストに対するセンチメント分析の研究はほとんど行われていない。

### Sarcasm Analysis
皮肉を判定する分析。ニュアンスや暗黙の意味を伴う比喩的な表現のため判定することは容易でない。

### Sentiment-Aware Natural Language Generation
心ある文章生成。人間のコミュニーションに見られる情緒的な文章を生成する。チャットボットなど様々なアプリケーションで求められている。

### Bias in Sentiment Analysis Systems
センチメント分析における偏り。センチメント分析結果に偏りがあると、少数派の感情が反映されず、適切な結果を得られない可能性がある。例えば、ウィキペディアが学習データとして使われることが多いが、女性の投稿は15%未満という調査結果が報告されている。そのため、ウィキペディアを学習データとして使用すると、女性の視点が過小評価される可能性がある。
TypeScriptはJavaScriptの上位互換ではない

一般に「TypeScriptはJavaScriptの上位互換であって、任意のJavaScriptコードはTypeScriptとしても動く！」とか言われていますがいや、動かないコード割とたくさんないか？というお話。

確かに機能単位で見ると98%以上の部分がそのまま動きますが、残りの2%がコードのどこかしらに入っていることが多いので、コードベース全体で見るとそのまま動くことは稀な気がするんですが。

# 互換でない部分

JavaScriptコードがTypeScriptとしてそのまま動かない部分2つを挙げます。

## オブジェクトのプロパティを後から追加する
例えば以下のJavaScript、

```js
const obj = { a: 0, b: 1 };
obj.c = 2;
```

これはTypeScriptだとエラーになります。
`tsconfig.json`でエラー扱いしないようなオプションがあれば良いのですが、私が調べた限りない。
上記のコードだと現実味がないですが、例えば

```js
function createPerson(type) {
  const obj = { type, firstName: '', lastName: '' };
  if(type === 'student') {
    obj.grade = '';
  }
  return obj;
}
```

みたいなコードを書いてる場所が割とたくさんあるので困る。

## ES2015のクラス構文でのフィールド
ES2015からはJavaScript側でもクラス構文が導入されており、今では広く使われています。しかしES2015でのクラスがTypeScriptでそのまま動くことはほぼ無いと言っていいと思います。

なぜならTypeScriptではフィールドの明示的な宣言が必要だからです。例えば以下のJavaScript、

```js
class AddNode extends Node {
  constructor(lhs, rhs) {
    super();
    this.lhs = lhs;
    this.rhs = rhs;
  }
  execute(ctx) {
    return this.lhs.execute(ctx) + this.rhs.execute(ctx);
  }
}
```

これはTypeScriptではエラーになります。TypeScriptでは以下のようにフィールドの宣言が必須です。

```ts
class AddNode extends Node {
  lhs: Node;
  rhs: Node;

  constructor(lhs, rhs) {
    super();
    this.lhs = lhs;
    this.rhs = rhs;
  }
  execute(ctx) {
    return this.lhs.execute(ctx) + this.rhs.execute(ctx);
  }
}
```

これも私の知る限り、`tsconfig.json`でエラー扱いしないようにするオプションはないです。

クラスなんて今時普通に使うし、これで上位互換というのは嘘でしょうと思いましたね。

# 私がTypeScriptに求めていたこと

私がTypeScriptに最も求めていたことは端的に言えば関数の引数と戻り値の型のアノテーションをすること、そしてその関数を使う側がそれをドキュメントとして利用しまたエディタの補完機能によって快適にコーディングができるようにすることだったんですよね。ローカル変数やクラスのプライベートフィールドにまで正確な型付けをして完璧に型安全なコードにしようとは思っていなかった。型のない言語にはコードの記述量が少なく考えのままにサクサク書ける、仕様変更に柔軟に対応しやすい等それはそれで価値があると思っています。

TypeScriptはJavaScriptの上位互換で次第に移行しながら使えるという触れ込みだったので、じゃあドキュメント的に関数等の外向きの型のアノテーションのみに使うか、と思って導入したら互換性のない箇所が結構あったので、なんだよと思ったという話でした。
【Discord Bot】結局スラッシュコマンドに移行しないといけないの？

追記（2022/5/20）：
この記事を放置していてすみません。その間に API の仕様変更が延期されたのと Discord.py が開発再開したので編集しました。ついでに私も申請したので体験談を書きました。 @gx1285JP さん編集リクエストありがとうございます！

# この記事の要約

- Bot を 100 サーバー以上に所属させないなら関係ないよ
- 100 サーバー以上に所属しているなら ~~**2022 年 4 月末までに**~~**2022 年 8 月末までに**スラッシュコマンドに移行するか Discord に Message content intent の申請しないといけないよ
- スラッシュコマンドで済むような機能では申請は通るか分からないよ

# はじめに

~~Discord.py が開発を終了したのは記憶に新しいと思います。[Danny 氏によると](https://gist.github.com/Rapptz/4a2f62751b9600a31a0d3c78100287f1)その理由の一つに Discord は Bot 開発者に既存のメッセージコマンドからスラッシュコマンドをに移行することを強いるが、 Danny 氏はそれを気に入らないというものがありました。~~
Discord.py は開発を再開しました！詳しくは[こちら](lass.admin.tus.ac.jp/up/faces/login/Com00505A.jsp)をご覧ください。

これはどういうことかと言うと、~~**2022 年 5 月 1 日**~~**2022 年 9 月 1 日**から Message content（メッセージの本文など）が**特権インテント（Privieged Intentscd**になると言うことです。

# 認証 Bot とは

2020 年の 10 月から 100 サーバー以上に所属する Bot は認証しないといけなくなりました。これは API を用いてどのような情報を使うか、また何のために使うかなどを入力したり、身分証明書を提出したりというもので、75 サーバー以上所属した時点で申請できます。

# 特権インテント（Privieged Intents）とは

認証 Bot は申請しなければ特権インテントは使えません。2021 年 12 月現在特権インテントになっているのは Presence intent と Server members intent です。

Presence intent は `Member.status`、`Member.activity` などを受け取るのに必要で、Server members intent は `on_member` で始まるイベントと、`on_user_update` を受け取るのに必要です。インテントについて詳しく知りたい方は[こちらの記事](https://qiita.com/disneyresidents/items/72741a88265107dd04d3)を参考にしてください。

そして今回、Message content intent が特権インテントになると言うわけです。Message content intent はメッセージオブジェクトの
- `content`
- `embeds`
- `attachments`
- `components`
を取得するのに必要です。ただし Bot 自身のメッセージは例外で常に取得できます。

# つまりどういうこと？

100 サーバー以上所属している Bot が従来の `message.content` を使ったコマンドを使うには申請が必要です！

# 申請って通るの？

分からないです！詳しくは[ポリシー](https://dis.gd/mcpolicy)を読んでほしいのですが、簡単に要約すると**ユニークで、その機能がある理由に説得力があり、変革的で、ユーザーのプライバシーと安全性が守られること**が要求されるらしいです。もしかしたらスラッシュコマンドで済むような機能では申請は通らないかもしれないですね…

# (追記）この前実際に申請した体験談

ガチでめんどくさかったです。まずユーザがデータの追跡からオプトアウトする機能をつけないといけなくて、さらにプライバシーポリシーも作らなければなりませんでした。しかも私が書いたプライバシーポリシーは一回ダメ出しされました（泣）まあそれだけ今までプライバシーに関して問題があったのでしょう。

# 参考にさせていただいたサイト

[Message Content: Privileged Intent for Verified Bots](https://dis.gd/mcfaq)
[Message Content Intent Alternatives/Workarounds](https://dis.gd/mcalternatives)
[Message Content Intent: Review Policy](https://dis.gd/mcpolicy)
[The Future of discord.py](https://gist.github.com/Rapptz/4a2f62751b9600a31a0d3c78100287f1)
[猿でもわかる！discord.pyのIntentsについて！](https://qiita.com/disneyresidents/items/72741a88265107dd04d3)
[On Resuming discord.py Development](https://gist.github.com/Rapptz/c4324f17a80c94776832430007ad40e6)
[Discord APIのメッセージインテントについて](https://zenn.dev/t_taku0427/articles/f6e9f123a4186b)

## この記事のライセンス
[![クリエイティブ・コモンズ・ライセンス](https://i.creativecommons.org/l/by/4.0/88x31.png)](http://creativecommons.org/licenses/by/4.0/deed.ja)
この記事は[CC BY 4.0（クリエイティブ・コモンズ 表示 4.0 国際 ライセンス）](http://creativecommons.org/licenses/by/4.0/deed.ja)の元で公開します。
typescript + lambda のInit Durationを縮める

typescript + lambda のInit Durationを縮める5つの技

これで、Init Duration 1,800msから60msまで縮めることに成功しました。

# 1 webpack入れる
まずは。
serverelss frameworkでtypescriptを生成すると、デフォで設定されるけど。

# 2 パッケージファイルサイズを減らす
webpack-bundle-analyzerを入れて分析します


```
import AWS from "aws-sdk";
import uniq from "lodash/uniq";
```

↑のように書くとパッケージがめちゃデカくなるので、↓みたいにします。

```
import S3 from "aws-sdk/clients/s3";
import uniq from "lodash/uniq";
```

# 3 source-mapを無効にする
これだけで、起動速度半分くらいになった。

# 4 遅延ロードする
一部のパターンでしから使わないライブラリは、使用するときにロードする。
ホンノチョットハヤクナル

# 5 メモリ増やす
メモリ増やす、CPU増える、早くなる
ある程度増やすと変わらなくなるので、適度に設定して様子を見る

# 6 go言語で書き直す
これは効く。
Tips: SQLで便利な構文: CASE文

この記事では、SQLを書いているときによく使う便利な構文「CASE文」を紹介します。

ちなみに例で使うSQLは以下のようなテーブルにクエリを投げている前提で記述しています

テーブル名: users

| id | age | gender | point |
|:-:|:-:|:-:|:-:|
|  1 | 10  | 0  | 40  |
|  2 | 20  | 1  | 50  |
|  3 | 30  | 0  | 60  |
|  4 | 40  | 1  | 70  |



## 条件ごとにラベルを付与したい時
CASE文を使うことで、各条件ごとにデータにラベルを付与することができます。

今回は例として、以下のようなラベルを付与したいと思います。

- ageが20以下→young
- ageが20より大きい→youth

```sql
SELECT CASE WHEN age <= 20 THEN 'young' ELSE 'youth' END　AS segment, gender, point
FROM users
```

この結果は以下のようになります。

| segment | gender | point |
|:-:|:-:|:-:|
|  'young' | 0  | 40  |
| 'young'  | 1  | 50  |
| 'youth'  | 0  | 60  |
| 'youth'  | 1  | 70  |

## 条件ごとにグループ化したい時
一つ目の例の応用として、データを定義したセグメントごとの人数などを出すことができます。


```sql
SELECT CASE WHEN age <= 20 THEN 'young' ELSE 'youth' END　AS segment, COUNT(1) AS cnt
FROM users
GROUP CASE WHEN age <= 20 THEN 'young' ELSE 'youth' END　
```

この結果は以下のようになります。

| segment | cnt |
|:-:|:-:|
| 'young'  | 2  |
| 'youth'  | 2  |


## 特定の条件の数を数え上げる
CASE文は集約関数と一緒に以下のように使うこともできます。
例として「ポイントが60以上のユーザーの数と割合」を出してみたいと思います

```sql
SELECT SUM(CASE WHEN point >= 60 THEN 1 ELSE 0 END) AS pass_count, SUM(CASE WHEN point >= 60 THEN 1 ELSE 0 END) * 1.0 / COUNT(1) AS pass_rate
FROM users
```

結果は以下のようになります。

| pass_count | pass_rate |
|:-:|:-:|
| 2 | 0.5 |

## 最後に
SQLはこのようなリファレンスには載っていないようなテクニックが多くあります。
また別の記事で紹介していければと思います。
explicit とは何なのか。

#explicit って何？
単語としての意味、**"explicit"**="明示的"
プログラムのキーワードとしての意味、**"explicit"**=「暗黙的型変換」を防止する機能です。

これだけでは意味は分からないので少し詳しく機能の説明もします。
**"explicit"**は構造体(struct)やクラス(class)のコンストラクタにつけることで**「暗黙的型変換」**を防止するキーワードです。
※キーワード：入力すると色が変わる単語(staticとか)

使用する際は引数が1つのものに使います。

*より詳しくプログラムを使用して説明します。*

```C++:c++
struct A {
	A(int);
};
struct B {
	B(A) { }
};

int main() {
	B b(1);
	return 0;
}
```
よく**"explicit"**の記事で見かける例です。

このコードで起きてる**「暗黙的型変換」**とは

```C++:c++
	B b(1);
	// B b(A(1)); と変換されている
```
**b(1) = b(A(1))**となっているのがダメだということです。
この変換を防止できるのが**"explicit"**です。
ではこの**"explicit"**の効果がどのように及ぶのか、ここで頭を悩ませました。

```
 struct A {
	A(int) { }; // explicit A(int) で B b(1)を防止できる
};
struct B {
	B(A) { };　　// explicit B(A) では B b(1)を防止できない
}; 
```
上のコードのように答えは、**"explicit A(int)"**に使用すると型変換を防止できます。
ですが不思議なことがあります。
**"explicit B(A)"**を行っても**"B b(1)"**で止めることができません。

なぜ防げないのか、私が理解できなかったのは**"explicit"**の型変換を防止するという機能を勘違いしていたからです。
最初、私は**"explicit"**の効果を
 explicit A(int) の explicit A( **INT** ) , **int**の引数の変換を防ぐと思っていました。

しかし、**"explicit"**の防止する機能の動きが違うため理解ができませんでした。

```C++:c++
struct A {
	explicit A(int);
};
struct B {
	B(A) { }
};

int main() {
	//　B b(1);	 エラー：1 を A(int) の型へ変換できないため
	return 0;
}
```
上のコードだけだとまだ勘違いしてしまいますね。

```
int main() {
	// B b(1);	 エラー：1 を A(int) の型へ変換できないため
	// A a = 1;	 エラー：1 を A(int) の型へ変換できないため
	return 0;
}
```
この一文を追加したらどうでしょう？
**"explicit"**は引数の型変換ではなく、コンストラクタ初期化やコピー初期化を防止する機能になります。

1 などの変数を 今回は **"A(int)"** に変換できなくしているわけです。
つまり、**explicit B(A)** で **B b(1)** が止められないのは
 **explicit B(A)**は **B(A)** の型変換を防ぐことはできても **A(int)** の型変換は防げないのです。

それでは、今回の説明は以上です。
Swiftでクロージャーを学ぶ

こんにちわ

今回はswiftでクロージャーについて学んだので、備忘録としてこの記事に載せていこうと思います！

#クロージャーとは
**クロージャーとは、文の中に直接埋め込む命令の塊を作ることができる機能です。**

基本の形は以下の通りです。

````exapmle.swift
//基本的な形
{(引数名: 型) -> 戻り値の型 in
    文
}

//実際例1
var Triangle = {(length: Int) -> Int in
    return length * length / 2
}

Triangle(4) //8

//実際例2

var Square = {(length: Int) -> Int in
    var width =  length

    return width * 5
}

Square(4)//20

````

このように使うことができます。

また、一文の場合はreturnを省略することもできます。

````example.swift
//returnの省略
var Square = {(length: Int) -> Int in
    length * length
}

Square(4)//16

````

##クロージャーのメリットとは

私はクロージャーを学び始めたてなのでそんなに詳しくはないのですが。

**コードが見やすくなることが１番のメリットだと考えました。**

まず関数を使った処理を見ていきましょう。

````example.swift
//関数を使った場合
func Calculation(NumOne:Int, NumTwo: Int, SumNumber:(Int,Int) -> Int) -> Int{
    return SumNumber(NumOne,NumTwo)
}

func add(NumOne:Int,NumTwo:Int) -> Int {
    return NumOne + NumTwo
}

print(Calculation(NumOne:3, NumTwo:4, SumNumber:add))

````

これにクロージャーを使うと以下のようになります。

````exapmle.swift

func Calculation(NumOne:Int, NumTwo: Int, SumNumber:(Int,Int) -> Int) -> Int{
    return SumNumber(NumOne,NumTwo)
}

print(Calculation(NumOne:3, NumTwo:4, SumNumber:{(a:Int,b:Int) -> Int in a+b}))

````

また、型を省略することができます。

````example.swift
func Calculation(NumOne:Int, NumTwo: Int, SumNumber:(Int,Int) -> Int) -> Int{
    return SumNumber(NumOne,NumTwo)
}

print(Calculation(NumOne:3, NumTwo:4, SumNumber:{(a,b) in a+b}))

````

こっちの方がスッキリしてるかもですね。


#トレイリングクロージャーとは

トレイリングクロージャーは、関数の最後の引数がクロージャーの場合、カッコの外にクロージャーを記述することができる方法です。

以下のコードを見てください。

````example.swift
func NamePrint(name: String, closure: (String)->Void) {
    closure("私は\(name)です")
}

//トレイリングクロージャーなし
NamePrint(name:"naoki",closure:{ string in print(string) })

//トレイリングクロージャーあり
NamePrint(name:"naoki") { string in print(string)}


````

メリットとしては、コードの可読性が上がり、見やすくなる事です。

#まとめ
クロージャーはコードの可読性を上げるために使う。。。。。
Yahoo! JAPANのデータ分析ツールを使ってみた！

##はじめに

皆さんはデータ分析と聞いてどんなツールを思い浮かべるでしょうか？

今回は**DS.INSIGHT**というヤフー株式会社が提供しているデータ分析ツールが便利だったので、実際の使用感を紹介したいと思います。


## 実際に使ってみた

今回は例として、ある都市の1ヶ月間（2021年10月）を対象に「電車・飛行機・船の交通手段のうち、電車で来訪する人が最も多いのではないか」という仮説を事前に立てて、それを検証するために駅・空港・港の3か所の来訪者データを比較してみます。


1ヶ月の1日当たり来訪者平均人数を見てみるとどうでしょうか。意外にも3つのエリア間で来訪者数に大差は見られませんでした。
![【１】人口総数_割合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277533/5962336a-939c-dda4-12d2-c277807804bc.png)

しかし、1日あたりの人口推移を確認してみると場所ごとに来訪者には特徴があるようです。

- 駅は毎週金曜日に来訪者数が1番多い
- 空港は土日の利用者数が平日に比べて1.3倍ほど多い
![【２】人口推移_日単位.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277533/192db159-e3cc-9678-ebd1-4dd3dcbfa2d9.png)

さらに年代別の切り口で見たときにも特徴のあるデータを見つけました。

- 駅の利用者のうち約40%を10代が占めている

![【３】年代別.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277533/5dc7b6cb-03bf-5931-8ca8-ad87361bce84.png)


このことから新たに次のような仮説を立てることができました。

- 駅の利用者は学生が多いのではないか
- 金曜日に駅の利用者が増えるのは、飲み屋目的の利用者が増えるからではないか

## まとめ

仮説に対してDS.INSIGHTを使ってデータを分析すると思いもよらなかった発見をする体験ができました！
今回は新たに立てた仮説に対して検証を行いませんでしたが、検証の際はDS.INSIGHT以外のデータも活用することになりそうです。

[DS.INSIGHTに関する情報はこちら](https://ds.yahoo.co.jp/contact/)
※本記事はヤフー株式会社様に許可を得て執筆しております。
[AWS] CloudFront + S3構成でサブディレクトリのindex.htmlを返す方法

## AWS CloudFront + S3構成について

まず、AWS CloudFront + S3で構成するパターンは下記2パターンあります。

>
1. CloudFront のオリジンにS3バケットそのものを指定する構成
2. CloudFront のオリジンにS3バケットのStatic website hostingのエンドポイントを指定する構成


ですが、現状、2のパターンはS3への直接アクセスを許可してしまうため、セキュリティとして非推奨のようです。
なので1のパターンで構成することを考えます。

「 **1. CloudFront のオリジンにS3バケットそのものを指定する構成**」ではデフォルトルートオブジェクトのファイル名(index.html)をディストリビューションで指定しているオリジンのルートにしか設定できません。
そのため、サブディレクトリへのパス`(例) xxx.com/aaa/`へアクセスすると、そのディレクトリにindex.htmlがあったとしても403エラーとなります。

これを解決するには **Lambda@Edge**を作成します。

## Lambda@Edge作成手順
Lambda@Edge作成の手順として下記のようになります。

1.  Lambda関数作成
コンソールから「関数の作成」をクリックして関数を作成する
※注意：Lambda@Edge 関数の作成は、現時点ではバージニアリージョンでしかできないようですので、us-east-1（米国東部：バージニア北部）を選択します

2.  Lambda関数のコードを実装
下記のような実装をします。（参考リンクにあるソースをそのまま使用できます）

>
CloudFrontイベント「オリジンリクエスト」イベントをハンドルし、リクエストパスの末尾が「/」で終わっているものを「/index.html」に置き換える。


3. Lambda関数を CloudFront ディストリビューションに関連付けるために必要なIAM アクセス許可の設定をする
参考：https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/lambda-edge-permissions.html


4. Lambda関数のトリガーを設定
CloudFrontを選択し、下記を設定する
- ディストリビューション：任意のディストリビューション
- CloudFrontイベント：オリジンリクエスト
- レプリケートの有効化：チェックする


これでサブディレクトリのパスにアクセスしてもindex.htmlを返すようになりました！！！

参考：
[CloudFront が、サブディレクトリからデフォルトのルートオブジェクトを返さないのはなぜですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/cloudfront-default-root-object-subdirectory/)
[Lambda@Edgeの設定例](https://aws.amazon.com/jp/blogs/compute/implementing-default-directory-indexes-in-amazon-s3-backed-amazon-cloudfront-origins-using-lambdaedge/)
[S3 オリジンへの直接アクセス制限と、インデックスドキュメント機能を共存させる方法](https://dev.classmethod.jp/articles/directory-indexes-in-s3-origin-backed-cloudfront/)


## Lambda@Edgeのログ確認方法

CloudWatch Logsで**Lambda@Edge**のログの確認ができます。

CloudWatchコンソール
https://ap-northeast-1.console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1

※CloudFrontにアクセスしたとき、Lambda@Edgeを動作させたエッジロケーションによってログ出力されるリージョンが決定されます。（Lambda@Edge作成したときに選択したリージョンに出力されるわけではないことに注意です）

参考：
https://dev.classmethod.jp/articles/where-is-the-lambda-edge-log/
【diverta2019】B - RGB Boxes をC++で解説

#初めに
　皆さんこんにちは！ 競プロの問題の理解を深めるために解説記事を書いていこうと思います！今回は **diverta2019 B** です！
 気に入っていただけたら**LGTM**して頂けるとうれしいです！
何かあれば**コメント**や[Twitter](https://twitter.com/python05238919)からお願いいたします!
#[B - RGB Boxes](https://atcoder.jp/contests/diverta2019/tasks/diverta2019_b)
####問題概要
 それぞれ$R, G, B$個の数の入った箱をそれぞれ選びちょうど$N$個になる組の数はいくつ？

####制約
・入力はすべて整数
・$1 \leq R, G, B \leq N$
##考察
####ポイント
 **全探索を工夫してみよう**
####解説
 $R, G, B$をそれぞれ1つずつ探索していくと$O(N^3)$となり，間に合いなさそうです．制約をみると$O(N^2)$なら間に合うのでループを減らすことを考えます．
　ちょうど$N$個になるときの式を考えてみると, 箱を選ぶ個数をそれぞれ$r, g, b$として
   $Rr + Gg + Bb = N$ <=> $b = \frac{N - Gg - Rr}{B}$
となり，$N - Gg - Rr$を$B$で割ったときに余りが0のとき，bは整数となるので答えの組がわかります．
　このようにして$r, g$だけ全探索することによってすべての組の個数がわかります．

それでは実装していきましょう.


#実装
for文の$r, g$の範囲はそれぞれ$0 \leq r, g \leq N / R$となります．あとは解説での式を判定して0で割り切れるとき答えの変数(`ans`)に 1 足します．

##正解コード

```C++:
#include <bits/stdc++.h>
using namespace std;

int main()
{
    //入力
    int R, G, B, N;
    cin >> R >> G >> B >> N;
    int ans = 0;

    //r, gの全探索
    for(int r = 0; r <= N / R; r++){
        for(int g = 0; g <= N / G; g++){ 
            int sumRG = r * R + g * G; //RとGのボールの総数
             if (N - sumRG >= 0 && (N - sumRG) % B == 0) ans++; 
        }
    }

    cout << ans << endl;
}

```

#類題
以下の問題は計算量を減らすことを考える問題です
・[ABC227 C - ABC conjecture](https://atcoder.jp/contests/abc227/tasks/abc227_c)
・
Javaを使用してExcelをPDFに変換する方法

##Javaを使用してExcelをPDFに変換する方法

この記事では、ExcelワークブックをJavaプログラムでPDFドキュメントに変換する方法を紹介します。今回は以下の二つの変換について詳細に説明します。

###1.  Excelワークブック全体をPDFに変換する
###2.  指定されたExcelワークシートをPDFに変換する

使用ツール：Free Spire.XLS for Java（無料版）

Jarファイルのダウンロードとインポート

公式ウェブサイトから**[ダウンロード](https://www.e-iceblue.com/Download/xls-for-java-free.html)**します。ダウンロード後、ファイルを解凍し、libフォルダー内のSpire.Xls.jarファイルをJavaプログラムにインポートします。結果は以下のようになります。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/67daec72-43a7-1ba3-549a-11c686595dee.png)

Excelのテストドキュメントは次のとおりで、2つのワークシートが含まれています。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/1882c1d0-1ff9-5a49-3f8a-7c2d1ef03b6f.png)

##【例の1】Excelワークブック全体をPDFに変換する
###コード一覧
```
import com.spire.xls.*;

public class ExcelToPDF {
    public static void main(String[] args) {
        //Excelドキュメントを作成する
        Workbook wb = new Workbook();
        wb.loadFromFile("C:\\Users\\Administrator\\Desktop\\test.xlsx");

        //呼び出し元のメソッドをPDF形式で保存する
        wb.saveToFile("ToPDF.pdf",FileFormat.PDF);
    }
}
```
変換した結果：
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/1c02ccf9-c32f-9644-578a-0172d1d5c25b.png)
##【例の2】指定されたExcelワークシートをPDFに変換する
###コード一覧
```
import com.spire.xls.*;

public class ExcelToPDF {
    public static void main(String[] args) {
        //Excelドキュメントをロードする
        Workbook wb = new Workbook();
        wb.loadFromFile("C:\\Users\\Administrator\\Desktop\\test.xlsx");

        //2番目のワークシートを取得する
        Worksheet sheet = wb.getWorksheets().get(1);

        //呼び出し元のメソッドをPDF形式で保存する
        sheet.saveToPdf("ToPDF2.pdf");
    }
}
```
変換した結果：
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/277b18f5-ead6-0ed2-1fb2-2e8921c8fe06.png)
今回のExcelをPDFに変換する記事は以上です、最後まで読んでいただきありがとうございます、もしよかったら他の内容の記事も参照してください。
GoogleAPIの使用について

GoogleAPIの使用についてちょっと嵌ったところがあったのでメモ書きと簡単なコードを紹介します。

## 目的
- 同じような問題で詰まっている方がいれば解決方法をシェアしてハッピーになってもらえればと
- GoogleAPIってどんなことが出来るの？が少しでもシェアできればと

## それでは
GoogleAPIの説明やサービスアカウント等の話は省きます。
ドキュメント読めば書いてあるのでドキュメント読んでください。

本記事では、GoogleWorkSpaceの特定ユーザーがメンバーとなっているGroupを一覧化する方法を紹介します。

## 嵌ったこと
ドキュメント通りにGCPでProjectを立ち上げ、サービスアカウントを作成、鍵(JSON)をダウンロードしてコードを実行したのですがうまくいかず、認可されていないとのエラーに悩んでました。


```
message': 'Not Authorized to access this resource/api
```

結論
GoogleWorkSpace管理上でロールを割り当ててなかったことが原因でした。

ロールを作成して、今回はグループ操作をしたので、グループのみに権限を与え（チェックを入れ）、サービスアカウントに割り当てて解決

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184018/9c549faa-efc3-afac-77ca-e4a15104ea8a.png)

## サンプルコード


```python:qiita.py
#Googleクライアントライブラリ
from googleapiclient.discovery import build
from google.oauth2.service_account import Credentials

SECRETS = '[秘密鍵].json'

SCOPES = ['https://www.googleapis.com/auth/admin.directory.group']

def Get_GoogleGroup():
    #クレデンシャルインスタンスの作成
    credentials = Credentials.from_service_account_file(SECRETS)

    #スコープの追加
    scoped_credentials = credentials.with_scopes(SCOPES)

    service = build('admin', 'directory_v1', credentials=scoped_credentials)

    results = service.groups().list(domain='hoge.com', userKey='test@hoge.com').execute()
    
    results = results['groups']

    groups = []

    for i in range(len(results)):
          groups.append(results[i]['email'])

    print(groups)

```
【Flutter】自分的、開発で使いたいパッケージ2選

# はじめに
本記事は[Flutter Advent Calendar 2021](https://qiita.com/advent-calendar/2021/flutter)の20日目の記事です。
（遅れてごめんなさい。）

この記事では私がFlutterでアプリ開発をする上で、好んで使っているパッケージを2つに絞ってご紹介します。
※有名なパッケージは他の方の記事を見ればいいので、そこまで有名ではないけどオススメであるパッケージを選んだら２つだけになりました。

# Drift
1つ目は[Drift](https://pub.dev/packages/drift)というSQLiteのORMです。
最近Flutter Favoriteの仲間入りをしたので、流行るといいなと思っています。

一度使うと、ローカルDBを使うときDriftは手放せない存在になります。

## 何が凄いか
DriftはSQLiteのORMです。
SQLiteでできることはカバーしつつ、ORMとして便利な機能を兼ね揃えています。

### Daoをサポートしている
DriftではDao(Data Access Object)の機能が標準で組み込まれています。
Daoを使うことで、良い感じにコードを管理することができます。

何も考えずにデータベース関連の処理を作成すると、一つのファイルでDatabaseの初期化や、テーブルの定義、SELECT,INSERT,UPDATE,DELETE文などが作成され、肥大化したファイルが生まれがちです。（私だけ？）

しかし、Driftが用意したルールに従えば、自ずと各役割ごとにファイルを分割するように書きたくなるので、肥大化を機械的に回避することができます。

一例ですが、以下のような構成にしたくなってきます。
>
model/db/
　├ dao/
　│　└ todo_dao.dart
　│　└ user_dao.dart
　├ entity/
　│　└ todo_records.dart
　│　└ user_records.dart
　└ database.dart

### 変更の監視/通知ができる
Driftを使っていて、これが一番最高な機能だと思うのが、変更の監視からの通知機能です。
イメージとしてはfirestoreのリアルタイムリスナーのような感じです。

Streamを使い、監視しているテーブルに対して変更があった場合、通知を受け取ることができます。
実装も非常に簡単で、以下のような記述だけで済んでしまいます。

```dart:points_dao.dart
Stream<List<PointsRecord>> watchPoints() {
  return select(pointsRecords).watch();
}
```

一度監視しておけば、テーブルを更新したときなどに再取得処理などを書かなくてもいいので、とても楽です。

## 備考
旧称は「moor」というAndroidの「Room」をもじった名前でしたが、一部地域で蔑称として使用される事がある単語であったため、「Drift」に変わりました。

なお、「moor」時代から機能として変わったところはなく、名称だけの変更です。
ただし、パッケージは変わってしまったので、最新版を追いかけるには「Drift」を使用するほうが良いでしょう。
（一応しばらくの間は、moorも更新されるようです。）

「moor」から「Drift」へ切り替えには自動移行ツールが用意されています。


# flutter_screenutil
Flutterでアプリを作るときに個人的時間がかかるランキング上位に君臨するのが、
端末ごとのWidgetサイズやテキストサイズがいい感じにならない問題です。

iPhone13では良い感じだな！
Galaxy S21はどうかな？ なんか下の方が空白だけどまあ良いか！
じゃあ昔のちょっと小さいXperiaは？
→__A RenderFlex overflowed!!!__

私も昔はExpandedやFlexible、Spacerで試行錯誤してみたり、
MediaQuery.of(context).sizeを使って、size.height * 0.2とか指定してみたりして戦っていました(テキストサイズが大変なんですよね)。

しかし[flutter_screenutil](https://pub.dev/packages/flutter_screenutil)に出会ってからは世界が変わりました。

今ではMediaQueryのサイズは使わなくなりました。
（ExpandedやFlexibleたちは今でも大活躍です。）

## 何ができる？
基本となる端末のサイズでflutter_screenutilを初期化し、例えばテキストサイズであれば"24.sp"のように指定するだけで、他の端末では基本となる端末のサイズとの差を自動で計算したサイズがテキストサイズとして設定されます。
つまり、基本となる端末と同じ表示になるように自動で計算してくれるようになります。

## 使い方
まず、以下のように通常MaterialApp等を返すときに、ScreenUtilInitクラスで囲います。
その際に基本としたい端末のサイズを設定します。ここではiPhone13 Pro MAXのサイズを指定してみます。

```dart:app.dart
import 'package:flutter_screenutil/flutter_screenutil.dart';

return ScreenUtilInit(
  designSize: const Size(428, 926), // iPhone13 Pro MAX
  builder: () {
    return MaterialApp(
      title: 'screen util',
      theme: ThemeData(
        primaryColor: kPrimaryColor,
        fontFamily: fontRegular,
      ),
      home: HomeScreen(),
    );
  },
);
```

そして、サイズを指定したい各地では以下のように指定します。
すると、基本となるiPhone13 Pro MAXでは指定した数値通りのサイズになりますが、
別の大きさの端末ではiPhone13 Pro Maxとのサイズ差から計算して、自動的にいい感じのサイズにしてくれます。

```dart:home_screen.dart
import 'package:flutter_screenutil/flutter_screenutil.dart';

Container(
  height: 100.h,
  width: 200.w,
  color: Colors.blueAccent,
  child: Text(
    'サンプル',
    style: TextStyle(
      fontSize: 24.sp,
    ),
  ),
)
```

# 終わりに
私がFlutterを使い始めたのは1年ほど前ですが、良いパッケージが続々と作成されているので、日々楽しく楽に開発させてもらえています。
今後も感謝しつつ、パッケージを使わせてもらおうと思います。
マルチディスプレイ環境（8画面）

こんにちは。清水です。
マルチディスプレイ環境の実験を投稿します。
８台の画面で、マルチディスプレイができました。夢のような環境です？

- WindowsPC　***8ディスプレイ***
- クロームブック　***３ディスプレイ*** （現在の主作業環境）

# マルチディスプレイ環境（8画面）　WindowsPC
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78212/6ba1de92-c4bb-007f-24c5-1d9e6fbf7fc3.png)
Windowsメニュー/設定/ディスプレイ


## 使用インタフェース
- DisplayPort　2台
- VGAポート　1台
- USB　１台　（USB → HDMI 変換アダプタ）
- LAN(有線)　1台　（Miracast「接続」アプリ）Windowsノート
- LAN(有線)　2台　（spacedeskアプリ）クロームブック2台 
- Wi-Fi　1台　（spacedeskアプリ）Androidスマフォ

### spacedesk Server画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78212/5ede8e51-ac77-1a01-6149-782d116673bf.png)

## 使用画面のサイズ
物理ディスプレイ　42,24,15,15インチ
spacedeskクライアント　Chromebook10,15インチ、Androidスマフォ6インチ　
Miracast「接続」クライアント　Windowsノート17インチ　

# 使用PC（HP 800G2ED SFF）
インテル® HD グラフィックス 530
オンボードグラフィックアダプタ接続可能ディスプレイ数 3
搭載メモリ 36GB (最大内蔵メモリ 64GB)


# マルチディスプレイ環境（３画面）クロームブック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78212/8f316d48-f45a-d6fd-88cc-0e51f740560e.png)

クロームブックメニュー／設定／デバイス／ディスプレイ
## 使用インタフェース
USB-C 2台　（USB-C → HDMIアダプタ）
本体ディスプレイ

## 使用画面のサイズ
物理ディスプレイ　42、24インチ
本体ディスプレイ　15インチ

## 使用クロームブック
Chromebook ASUS C523NA 外部2画面出力可
インテル Celeron N3350 / メモリ:8GB eMMC:64GB / インテル HD グラフィックス 500

**クロームブックの機種により、接続できる外部ディスプレイ数が決まる。**

## LAN接続ディスプレイ　NG
- spacedesk クライアントのみでサーバ機能なし
- Miracast　機能なし
- Google Cast（Chromecast）　画像を転送できるが、仮想ディスプレイにはならない

# おわりに
複数の画面はつぎのように使う？

- 主作業画面
- 作業時の参照用画面
- 検索画面
- ウィンドウの一時退避用画面
- 音楽やラジオ用の画面
- メール等のコミュニケーション画面
- スケジュールやタスク等の表示用画面
- システム状況表示画面
- ニュース、雨雲などの表示画面

# 付録
## ディスプレイ解像度（ピクセル）

|規格名	|解像度	|備考　|
|:-------------|:-------------:|:-------------|
|VGA|640×480||
|XGA|1024×768|- 15インチディスプレイ|
|HD<br>(High Definition)|　1280×720|高精細度ビデオ<br>ハイビジョン|
||1600×720|- 6インチスマフォ|
|Full HD|**1920×1080**|- 24インチディスプレイ<br>- Chromebook15インチ<br>- Windows１７インチ|
| |1920×1200|- Chromebook10インチ<br>(spacedesk 3072x1920)<br>(外部1440x900)|
|**4K**|**3840×2160**|- 42インチディスプレイ|
|8K|7680×4320||
　https://ja.wikipedia.org/wiki/画面解像度

## 映像出力端子の規格

|端子	|最大解像度	|最大Hz　|
|:-----------------|:------------------:|:------------------|
|HDMI 1.4b	|4096 × 2160（30Hz）	|1920 x 1080（120Hz）|
|HDMI 2.0	|4096 × 2160（60Hz）	|1920 x 1080（144Hz）|
|DVI-I	|3840 × 2400（33Hz）	|1920 x 1080（144Hz）|
|DVI-D	|3840 × 2400（33Hz）	|1920 x 1080（144Hz）|
|DisplayPort 1.2	|5120 x 2880（30Hz）	|1920 x 1080（240Hz）|
|DisplayPort 1.4	|7680 x 4320（60Hz）	|1920 x 1080（240Hz）|
|USB Type-C	|3840 x 2160（60Hz）	|1920 x 1080（144Hz）|

　「HDMI、DVI、DisplayPortの違いは？ゲーミングPCの映像出力端子はどれが人気か調べました」より　(http://xn--pc-mh4aj6msdqgtc.com/column/video-output-types.html)


# 参考資料

## Miracast  (Windowsのアプリ「接続」)
余ったWindows 10ノートがサブディスプレイに早変わり!
https://pc.watch.impress.co.jp/docs/column/yajiuma-mini-review/1251697.html

Windows 10 接続 アプリが消えてて焦った
https://shinoblogavi.wordpress.com/2019/10/16/win10connect/

Google、「Chromecast」アプリを「Google Cast」に改名　対応端末拡充を反映　（2016年03月）
https://www.itmedia.co.jp/news/articles/1603/23/news080.html
子供の夢をそっと守る優しいTwilioの話。

メリークリスマス。

こんにちわ、クリスマスイブですね。

まだ、純真だった数十年前、サンタさんに、ほしいプレゼントの手紙書いた記憶が蘇りました。自分はまだ子供いないんですが、自然にクリスマス欲しいものを聞き出すのって結構テクニックいりませんか？自分だったら、「ところで話は変わるけど、サンタさんにクリスマスプレゼント何お願いしたのかな？」とか、脈絡なく聞きそうで子供の夢を守ってあげることができるのか、演技下手だから、ハードル高いなーと思っています。

そんな演技はダメな私ですが、システムエンジニアなので、Twilioを使って、優しく子供の夢を守る方法を考えたので、投稿させてください。

# サンタさん（Twilio）と電話できるサービス

~~今日の今日、思いついたので、システム組むとこまで行けませんでした、フロー図で勘弁してください。~~ イケるか？と思ったらイケました。簡単に実装できるTwilioさん、マジスゴい。（所要時間52分、サンタ音声録音込み）

![クリスマスだしね.drawio (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277180/60ebf185-af38-258d-ab81-503d96823dff.png)

# 解説

digits 入力を求めつつも、敢えて、timeout時に子供向けのメニューを展開することを想定しております。最初、子供にdigits入力させようと思ったのですが、何か、ちょっと冷めそうだなと。隠しメニューとして仕込むんだったら、親が電話したときだけ、digits入力をさせ、子供はtimeoutで、次の処理に行くくらいがわかりやすくて良いかなと思い、フロー書き直しました。

ちなみに、Twilioだと、こういうフローから簡単にシステム組めるのと、実装を柔軟に行えるので、こういうライトなシステムを作るのに向いていると思います。

# 終わりに

Twilioを使えば、子供の夢を守れる！　こういうサービスもあって良いんじゃないでしょうか。だって、クリスマスだもの。
Railsでエラーメッセージを表示させる方法

##手順
①バリデーションの定義
②エラーメッセージの記入
③エラーメッセージを日本語化

##①バリデーションの定義
エラーメッセージはエラーが発生すると、error.full_message内に格納される。

バリデーションはモデル内で定義。
以下のように書くと、nameかemailを空白で登録した際は登録できないようにするバリデーションを追加することができる。

```
class User < ApplicationRecord
  validates :name, presence: true
  validates :email, presence: true
end
```

##②エラーメッセージの記入
エラーメッセージを記入する前に、前提として以下の３つを注意する。

``・エラーメッセージ表示部分をformのテンプレートに記載せず、専用のパーシャルが作られていること。``

``・特定のモデルに依存せず汎用的なつくりにする必要がある。格納場所はshared配下にすること。``

``・エラーメッセージの表示方法はアプリケーションごとに異なるため、エラーメッセージを直接生成するようなビューヘルパーはRailsに含まれてない。 表示が必要な場合はパーシャル化して、汎用的に使えるようにする。``

**記入例**

```
#shared/_error_messages.html.erb

<% if object.errors.any? %>
  <div class="alert alert-danger">
    <ul class="mb-0">
      <% object.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
    </ul>
  </div>
<% end %>
```

```
#app/views/boards/_form.html.erb(パーシャルを呼び出し)

<%= form_with model: board, local: true do |f| %>
  <%= render 'shared/error_messages', object: f.object %>※
  <div class="form-group">
    <%= f.label :title %>
```

``f.objectとは``
f.objectのobjectは、form_withやform_forなどのオプションであり、formのブロック変数に対して使用する事で``ブロック内でモデルオブジェクトを呼び出す事が出来る。``
同じコードを流用する際に、``変数を変える必要が無くなる。``

##③エラーメッセージを日本語化
エラーメッセージを入れる前に、railsアプリを既に日本語化していた場合は特に必要なし。


・config/application.rbに``config.i18n.default_locale = :ja``を追加。
・``gem 'rails-i18n'``をインストール。
・``activerecord/ja.yml``にモデルの日本語化を記入。

```
例：
ja:
  activerecord:
    models:
      user: ユーザー
    attributes:
        user:
          first_name: 名
          last_name: 姓
          email: メールアドレス
          password: パスワード
          password_confirmation: パスワード確認
```
これらを設定すると、「タイトルを入力してください」「本文を入力してください」のようなエラーメッセージが表示される。

##参考記事
[Ruby on Railsでエラーメッセージを表示する方法【初心者向け】](https://techacademy.jp/magazine/10024)
[Rails フォーム入力時エラー情報を個別表示(f. objectについて)](https://yama2-0506.hatenablog.com/entry/2020/12/11/083007)
[Rails6 エラーメッセージの日本語化](https://qiita.com/mumucochimu/items/ac96f6864609ecf21be3)
How to start IM-Juggling/eBuilder in English language?

# Ojective

Change default language of IM-Juggling or eBuilder to English mode.

# Background

I often forget how to configure this.
So try to keep it in the article.

# IM-Juggling

Find juggling.ini and add 2 lines below in the end of the file.

```
-Duser.language=en
-Duser.country=JP
```

The "user.country" would be your location country code. (e.g. US, CN, TH, etc)

Example )

```
-startup
plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.100.v20110502
-vmargs
-Xmx1024m
-XX:MaxPermSize=128m
-Dfile.encoding=UTF-8
-Dosgi.instance.area.default=@user.home/juggling/workspace
-Duser.language=en
-Duser.country=JP
```


# eBuilder

Find eBuilder.ini and add 2 lines below in the end of the file.

```
-Duser.language=en
-Duser.country=JP
```
LINE WORKS と Office 365 のメールを併用する

LINE WORKS の上位プランではインターネット メールが利用できます。

社内で一部のユーザーは既存のメール サービス、他のユーザーは LINE WORKS のメールを利用するといった場合、双方のルーティング設定を工夫する必要があります。

ここでは、LINE WORKS と Office 365 のメールの併用方法を考えてみます。

既存のメール環境は Office 365 で MX レコードは Office 365 に向いている。
全社で LINE WORKS を利用するが、一部のユーザーは引き続き Office 365 のメールを使う。
こんな環境を想定しています。

#Office 365 側の設定
Exchange 管理センターで、対象のインターネット ドメインを "内部の中継" に設定します。

![l_1517737_1540_1640313085484.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/e1f80b26-4a8c-2f8f-847d-1079fa41a03f.png)

Exchange 管理センターで、LINE WORKS に向けた送信コネクタを作成します。
![l_1517737_1541_1640313466058.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/c9bb9b24-2bbf-d99a-e859-07c210ad079b.png)

これらの設定で、Office 365 にメールボックスが無いユーザー宛てのメールは LINE WORKS へ配信できます。

#LINE WORKS 側の設定
LINE WORKS で利用するインターネット ドメインの MX レコードが、Office 365 を指している場合は、LINE WORKS ユーザーが、そのインターネット ドメインのメール アドレス宛てに送信したメールは、MX レコードに従って Office 365 に配信されます。

LINE WORKS の管理画面で受信ゲートウェイを設定しておきます。
![l_1517737_1542_1640315204627.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/166a6b60-fef0-1522-ff04-c4732c8c18b4.png)

#動作の確認
組織内外間でのメールの配信が正しく行われることを確認します。
fish $PATHの設定方法がわからん

環境構築した際、これで躓いたのでメモついでに書きます

zsh bash etc　
export PATH=\$HOME/hoge:\$PATH

で環境変数に設定できると思うのですが、
fishで同じ書き方をすると、、、
echo \$PATH
>/usr/local/bin /usr/bin /bin /usr/sbin /sbin

はい。うざいですね。

そんな時はdocumentを見に行きましょ

https://fishshell.com/docs/current/tutorial.html#path

時間ない人へ
>set PATH \$HOME/hoge /usr/local/bin /usr/sbin \$PATH

が正解らしい

なんだこの書き方は、、、
初めて見た時ビビりました

複数設定したい場合はどういう風に書けばいいのか、、

そんな時はdocumentをみにいきましょー

https://fishshell.com/docs/current/tutorial.html#lists

どうやらPATHをリストで扱えるらしいです

```
for val in $PATH
    echo "entry: $val"
end

結果
entry: /usr/bin/
entry: /bin
entry: /usr/sbin
entry: /sbin
entry: /usr/local/bin
```
スクリプト組みたい方にしたら便利かもしれないですね！

そんなわけで解決解決〜〜

よきfishライフを！！
令和最新版の輪読会、音読会のススメ

[Unipos Advent Calendar 2021](https://qiita.com/advent-calendar/2021/unipos)の24日目、本日はクリスマスイブですね！
輪読会の運営の話です。

今年は社内で色々な輪読会が開催されました。
僕も4月中旬から輪読会を開催していて、半年以上継続し現在4冊目に突入しています。
継続させる型が整ってきたので紹介したいと思います。
輪読会が継続しなくて悩んでいる運営の人の参考になればと思います。

# 会の型
こんな形でやっています！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27773/b79349ce-764c-8254-1f03-254b3b6c4432.png)

一般的な輪読会は、章単位とかで担当を決めて纏めを作ったり他の参加者は予習したりとかの事前準備をしておいて、会自体ではなるべく議論の時間を長くすると思います。
僕が運営している輪読会は、**事前準備なしの音読会**という形にしています。
読むパートで皆が順番に本を音読するので、このパートに時間を一番割いています。

ちなみに締めるパートは遊びのパートです。なんか適当にトークしてもらって、その日の会を終わらせてもらうだけです。
今日読んだ内容を話すとか、そんな真面目なことは一切やっていなです。
今どきの言葉でいうと、心理的安全性のパートです。

この型で週1回、長くて90分くらいで運営しています。
今のところ脱落者はゼロで、むしろ参加者が微増しています。

この型であれば気軽に始められるし、継続性も高く保てるのではないかと思います。

# なぜこの型に至ったのか
ここからはなぜこの型に落ちつたいのかです。

## 始めたモチベーション
知識を得るとか知識レベルを揃えるとかという目的があって、輪読会を始めることが多いのかなと思います。
僕の場合もそういう気持ちはありましたが、**積読を解消する**、これが最もやりたかったことです。

積読が溜まるが読む気力がそんなに湧かず。とはいえ、技術の準備は普段からしておきたいお気持ちだけは持っています。
そこで、**自分の積読を解消する手段**として輪読会を始めることにしました。

## 会の設計で大事にしたこと
自分の**積読を解消する**ことが大目的なので、始めから**継続性を一番大事**にして会を設計しています。
継続するためには負担を限りなく減らす必要があると考えました。何が負担かというと結局準備なんですよね。
準備は運営者にも参加者にもそこそこの負担を強います。
僕は他の輪読会にも参加したかったので、自分の運営する輪読会で負担を増やして結果どれにも参加しなくなるのは避けたい思いがありました。

この辺を考えて**事前準備なし**の会にしました。これなら関係者全員の負担が限りなく少なります。

## 初期の参加者
方向性を決めたとはいえ具体的なところは何も決めていなかったので、しばらくはトライ&エラーを覚悟し、それにつきあってくれそうな少数の人数に声がけしました。
僕の目的は隠さず伝えつつ、皆は自分のために有効活用してみませんか？という感じで声がけしています。

参加者が多い方が視点が増えるし盛り上がって良いのですが、型が定まっていない中で自分の負担を増やす行為は継続性を阻害することになります。

今も積極的に宣伝はしてないですが、参加したいならウェルカムというスタンスでやっています。

## 型が固まるまでに試したこと
音読会の型になるまでに試した施策は実は少なく、早い段階で今の型の原型に行き着きました。

当初は音読パートを**黙読パート**にしていました。各々が黙読してポイントをメモって、議論パートに突入的な。
読み切れない人が出たり、寝ちゃう人がでてきたので辞めました。

そこから音読にしました。その時は皆が音読して僕がポイントをメモることをやっていたのですが、メモるのが音読の速度についていけなくなったので辞めました。
あとで見直すことができるアウトプットを残すよりも、頭に軽くインデックスが作る方を重視した割り切りです。

# 書籍の決め方
せっかくなので、書籍の決め方も紹介します。

僕の積読解消が大目的なので、1冊目は僕が決めました。
2冊目以降は参加者の積読書籍も候補に入れて多数決で決めています。

4冊目を決める時はプレゼン大会にして決めましたが凄い盛り上がりました。
積読書籍をなぜ読みたいのかを熱い想いでプレゼンするので、全員「なんで読んでないんですか？」という質疑応答になったりして。

遊び要素強めですが、決めるプロセスに参加者が積極的に関与する機会を作るだけで、普段の会も安定してきます。

# 音読会のデメリット
気軽に始められるところがメリットだとして、デメリットも結構あると思います。

- 議論の時間が少ない
- 理解を深めにくい
- ボリュームのある書籍は辛い
- プログラミング系は難しそう
- 多人数には向かないかも

多人数に関しては、毎回参加者数に応じてその場で少数のグループを何個か作っていけばいけそうな気がしています。
他は目的に合わせて考えていくしかないですね。

# 最後に
輪読会を継続するのはなかなか難しいと思いますが、一旦継続を目指して音読会にするのはありだと思います。
2022年は令和最新版の輪読会、音読会をはじめてはいかがでしょうか？

では良いクリスマスイブを！！
プッシュ通知誤爆の二次災害を最小限にする方法

# はじめに
iOSアプリ、Androidアプリのグロースには欠かせないプッシュ通知ですが、今月はプッシュ通知の誤配信が多いように感じます。
プッシュ通知誤配信そのものも「やってしまった」という精神的ダメージがありますが、配信データをちょっと工夫することで二次災害は防げるのではないかと思い記事を書くことにしました。

# この記事で伝えたいこと
プッシュ通知の検証をする場合、検証環境（staging,test）であっても無難なものにしておきましょう。
プッシュ通知に限らず「テストデータはワンチャン漏れる」という意識で、本番環境で配信しても良い内容だとより良いです。

# 事例と考えられる対応策

## 1. 「テストです」

https://www.itmedia.co.jp/news/articles/2112/17/news143.html

https://www.itmedia.co.jp/news/articles/2112/03/news169.html

### 何が問題（二次災害）か
「テストです」という見慣れない文言を見ると、多くの人はついタップしてしまいます。
多くの人がついタップして、多くのユーザーを抱えているサービスほどアクセスが集中します。
その結果サーバーが繋がりにくくなりやすいです。

### こうすると良さそう
本番環境で最悪流れてもよく、常日頃から促したい行動につながる通知が良さそうです。

例えば
d払いなら、「オトクなキャンペーンをアプリからチェック！」
PASMOなら、「チャージも定期券の購入も、アプリなら並ばず可能！」
のような通知だと二次災害が少なくなりそうです。

### 気をつけること
テストだからといって自分やチームメンバーの名前を入れてはいけません。
ネットニュースなどに晒されてしまうためです。


## 2. 「【政府発表】[配信テスト][dev]ゲリラや特殊部隊による攻撃が発生しました。（14時06分）」

https://news.yahoo.co.jp/pages/notice20211222

### 何が問題（二次災害）か

- 一瞬、本当のことだと思ってしまう
信頼できるサービスからの通知であるほど、嘘でも一瞬信じてしまいやすいです。

- 通知内容が無駄に怖い
テストデータはワンチャン本番に出てしまうかもしれない・・

### こうすると良さそう

1. ありえない内容だとすぐに分かるようにする
「ネコが世界を征服しました」
少し苦しいですが、ありえないと思えるほど二次災害が減りそうです。

2. 訓練としての通知にする
「こちらは訓練用の通知です。」
見た人がパニックにならないという意味では有効そうです。

## おわりに
DevOpsが一般的になってきたおかげで、開発者・テスターの冷や汗をかくような作業は減らしやすくなってきました。その一方で、まだプッシュ通知検証のようなヒヤヒヤしてしまう作業は残っています。
開発者、テスターも人間なので12月末までになんとか間に合わせようとして焦ってしまうこともあるかと思います。
ポストモーテムの考え方にあるようにミスを責めるのではなく、どうしたら（できるだけがんばらない方法で）再発を防げるのか、起こしてしまっても前よりマシな状況にできるかという仕組みづくりに力を入れていけると良いなと思いました。

こういった悲しい障害は少しでも軽減できればと思っているので、より良いアイデアがあればぜひ教えていただけると助かります。
ビジュアルのデータポイントを選択したときの、メジャーのフィルターコンテキストを見ていく①

# 概要

Power BIでは、棒グラフやテーブルの値（データポイント）をクリックすると、相互作用でレポートページ上の他のビジュアルにフィルターをかけることができます。
そこで、ビジュアルをクリックしたときにかかるフィルターが、メジャーにどのように働くかを図を使って考えてみます。

# データモデルとレポート

私が作った架空の身長、体重のサンプルデータです。（今回、体重は使っていません）

## データ

体重は使いませんでしたので、テーブル名をシンプルに身長表としてます。

### 身長表テーブル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/738d84be-bf94-e027-d2d0-c95ccd16fda6.png)
性別 : 男性 = 1 、女性 = 2　
ビンのサイズ : 5 として身長フィールドをグループ化

### genderテーブル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/4717f8cb-7239-12ff-18c9-d3fe76a12da2.png)

## モデリング

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/f9304f5a-18bc-3548-19cc-fbadb82362d3.png)

genderテーブルの性別Keyと、身長表の性別でリレーションシップを貼ったシンプルなデータモデルです。

## レポート

解説に使うレポートページです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/f6871aee-f592-6fae-69fa-e930f643b64a.png)


* 身長（ビン）及び性別による身長のカウント（積み上げ縦棒グラフ）
    * [軸] 身長のビングループ
    * [値]身長フィールド

→　以下、棒グラフと呼びます。

* 性別による集計（身長表テーブルのフィルターの影響を除く）

→　以下、テーブル➀と呼びます。

* 性別による集計

→　以下、テーブル➁と呼びます。

他のビジュアルは、今回は無視します。
では、本題に入ります。

# ビジュアルのデータポイントを選ぶ

棒グラフの150～154までの範囲を選び、クリックしてみます。（↓図１）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/f3ef5163-c4e8-c444-fd4f-1f6572b087c3.png)

そうすると相互作用により、他のビジュアルにフィルターがかかり、結果が変わります。（↓図２）
テーブル➁を見てます。データポイントをクリックすると、図１と比べ数値が変化しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/fec06f0b-88dc-4bdf-0596-ee512b983710.png)

テーブル➁には、以下のようなDAX式によって集計されています。（↓図３）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/b529f9ad-f289-f9df-373a-6a124777fc44.png)

データポイントによるフィルターがかかっているからです。（↓図４）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/3dfe37a5-bae4-4aa8-3f4a-73469595207a.png)

データポイントによるフィルターによって、フィルターコンテキストが変更されました。（↓図５）
それを日本語で書くとこのようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/b34781d7-f00e-7078-3de7-6fa4840d4ad3.png)

男性の平均身長は、「性別キーが1（男）で、性別が女」はひとりもいないので、集計結果がゼロになっている、というわけです。（↓図６）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349908/daebe593-efcd-c55a-a834-6e9f5c82a0d6.png)

# まとめ

非常にシンプルかつ初歩的な内容ですが、フィルターコンテキストを理解する第一歩な内容だと思っています。
次回は、ALL、ALLEXCEPT、ALLSELECTEDによるフィルターコンテキストの動きを見ていきたいと思います。
ブラウザにデータを保存する際に検討すること



ユーザーの閲覧履歴やお気に入りなどのデータをブラウザに保存したい時、どのような方法で保存しているでしょうか。
Cookieを使うのかlocalStorageを使うのか、容量や有効期限の違いもあるので要件によって様々だと思います。
先日、CookieやlocalStorageについて改めて調べる機会があったので、備忘録を兼ねて近年のITPの動向を踏まえておさらいしておこうと思います。

### ITPとは

ITPとはIntelligent Tracking Preventionの略で、Appleが定めている広告トラッキング防止機能のことです。
インテリジェントトラッキング防止とは...
> オンラインショッピング中に見た商品が、突然あらゆるウェブサイト上に表示されるようになる。それは様々なウェブサイト上であなたに広告を見せるために、第三者がCookieやほかのウェブサイトデータを追跡している時に起こります。

とAppleの公式サイトで説明されている通り、ユーザー行動をトラッキングすることで実現するリターゲティング広告などからユーザーのプライバシーを守るための機能です。
2017年9月にITP1.0がAppleから発表されて以来、ITP1.1、ITP2.0、ITP2.1、ITP2.2、ITP2.3とアップデートされていき、その規制内容も徐々に強まっていきました。
ITPの対象となるのは、Apple社のSafariを利用しているユーザーになります。日本国内のモバイルのWEBブラウザのシェア率は、2021年10月時点でSafariがおよそ60%を占めているので無視することは難しそうです。
現在はITP2.3を基準に、CookieやlocalStorageの利用を検討する必要があります。


### Cookie

Cookie（HTTP Cookie）は、webサーバとブラウザ間で情報をやり取りするための仕組みの一つで、ブラウザに情報が保存され、HTTPリクエスト時にヘッダ情報としてサーバに送信されます。
ログイン機能などのセッション管理や、ユーザーのパーソナライゼーション、ユーザー行動のトラッキングなどに広く用いられています。

Cookieを保存できる容量は**4KB**です。
Cookieはドメインに関連づけられますが、発行元の違いによって「1st party Cookie」と「3rd party Cookie」に分類されます。
関連づけられたドメインが閲覧しているページのドメインと同じ場合に1st Party Cookieと呼び、ドメインが異なる場合（発行元がそのサイトの管理者ではない場合）に、3rd Party Cookieと呼びます。
リターゲティング広告などのサイト越えトラッキングは、3rd Party Cookieを利用したもので、ITP2.3ではこの3rd Party Cookieを完全ブロックすることで、ユーザーのプライバシーを向上させています。

ITP2.1（IOS12.2以降）では、JavaScriptを用いて生成された1st party cookieが**7日間**で削除されるようになりました。
保存する情報が7日間で消えてしまっては困る場合、JavaScriptではなくサーバーサイドで発行したCookieを利用する必要があるので注意が必要です。
また、Cookieは後述のlocalStorage, sessionStorageと異なりHTML4にも対応しているため、古いブラウザなどでも利用することが出来ます。

### localStorage（ローカルストレージ）

localStrageは、HTML5から導入されたテキスト情報をブラウザに保存する仕組みで、JavaScriptで保存します。
後述のsessionStorageと合わせてwebStorageとも呼ばれます。

```javascript
// 値のセット
localStorage.setItem('key', 'value')
// 値の取り出し
localStorage.getItem('key')
// 削除
localStorage.removeItem('key')
// 初期化
localStorage.clear()
```

保存できる容量はブラウザによって異なりますが、大抵のブラウザで**5MB**ほど保存することができます。Cookieの4KBと比較するとかなり大容量で、色々な情報をまるっと保存することが可能ですね。
ITP2.3では、localStorageも制限の対象になりました。

以下条件すべてを満たす場合に、localStorageは即時削除されます。
> ・トラッキングドメイン経由からの流入の場合
・URLにパラメータやフラグメントが付与されている場合
・サイト流入後にページで操作（クリック・タップ・テキスト入力）がない場合

上記を満たさない場合でも、サイトアクセス後**7日間ユーザーの操作がない場合**にlocalStorageは削除されます。
例えばよくあるユーザーの閲覧履歴やお気に入り機能ですが、localStorageに保存している場合はそのユーザーが7日間サイトにアクセスしなかった場合に情報が削除されてしまうので注意が必要です。

### sessionStorage（セッションストレージ）

sessionStorageはlocalStorageと似たような機能で、容量も同様の5MBほど保存が可能です。

```javascript
// 値のセット
sessionStorage.setItem('key', 'value')
// 値の取り出し
sessionStorage.getItem('key')
// 削除
sessionStorage.removeItem('key')
// 初期化
sessionStorage.clear()
```

localStorageとの違いですが、ライフサイクルの違いがあります。
localStorageはブラウザやタブを閉じても有効ですが、sessionStorageはブラウザやタブを閉じるとその時点で削除されます。
一定期間以上保持しておきたいデータの保存には使えませんが、ページ遷移時に次のページに情報を持っていきたい場合などに利用できそうです。
Cookieと違いHTTPリクエストヘッダに含まれないので、大きめのデータを保存してもパフォーマンスに影響が出る心配はありません。


### まとめ

ブラウザにデータを保存する際にどの方法を使うのがいいかは、要件によって判断してうまく使い分ける必要があります。
例えば7日間ユーザーの操作がない場合に内容が削除されてしまってもいい場合は、容量の上限をあまり考えなくても良いlocalStorageを使うのが便利そうです。
それが許容できない（＝データを半永久的に保持したい）場合は、Cookieをサーバサイドで発行して利用することになりそうですが、容量が4KBしかないため多量の情報をブラウザに保存することができません。そのためサーバサイドのデータベースなどと組み合わせるなど、工夫が必要になります。

### 参考

https://www.apple.com/jp/privacy/features/
https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies
Vue.js(Nuxt.js)で使用するref属性とは何か

## 概要
Nuxt.jsについて調べているとたまに`ref`という属性を見かけることがあります。
そんな`ref`属性について自分なりに理解して備忘録としてアウトプットします。

## ref属性とは
`ref`属性とは、特定のHTML要素を参照するために使用するものです。

#### 使用例
例えば、ページのマウント時に`input`タグにフォーカスを当てたい場合


```vue
<!-- Component.vue -->
<template>
  <input ref='sample' />
</template>

<script>
export default {
  methods: {
    inputFocus() {
      this.$ref.sample.focus()  // "this.$ref.参照名"でref属性を定義した要素を取得できます
    }
  },
  mounted() {
    this.inputFocus
  }
}
</script>
```

`ref`属性を使用することで、特定の要素を取得して操作することができるようになる。
また、子コンポーネントタグに`ref`属性を指定することで
親コンポーネントから操作することもできる。

```vue
<!-- index.vue -->
<template>
  <Component ref='inputComponent' />
</template>

<script>
export default {
  mounted() {
    this.$ref.inputComponent.inputFocus
    // 子コンポーネントであるComponent.vueのinputFocus()メソッドを実行している
  }
}
</script>
```

## 参考文献
[公式ドキュメント](https://v3.ja.vuejs.org/guide/component-template-refs.html)
Vue.js関連のメモ

この記事は、Vue.jsに関する全くの個人用メモとして残すものです。随時追記！

## 1. Vue-cliでプレジェクトを作るときのメモ

☞ まだインストールしていなかったら。。。

```
npm install -g vue-cli
```

プロジェクトを作るとき。xxxは自分のプロジェクト名。

```
vue init webpack xxx
```

自分のプロジェクトに移動した後に、

```
npm run dev
```

## 2. Vue-cliでトップ画面を設定するときのメモ

\src\router\index.jsファイルの、『import HelloWorld from '@/components/HelloWorld'』となっているところを変更する。同様に以下のHelloWorld部分も変更する。

```
export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    }
  ]
})
```

## 3. styleについて

・　\<style scoped>は、ファイル内の要素にだけスタイルが適用される。
・　src/App.vue内のスタイルは、プロジェクト内全てのファイルに適用される。

## 4. Vue.cliでさくらのレンタルサーバにアップするときの注意点メモ

<b>npm run build</b>で作成されたdistフォルダの中身を、ルートフォルダではなくて、別のフォルダをルートとしてアップロードした時には、<b>config/index.js</b>ファイルの、<b>「build」</b>の設定項目内、<b>assetsPublicPath</b>の値を、<b>『/』</b> から <b>『./ 』</b> に変える。
詳しいことは以下のサイトを参照。

https://myscreate.com/komakee-vue8/
Webブラウザから簡単にDNSサーバの接続確認（digテスト）をしてみよう

![qiita_pic-title.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2106206/bf5b7aa3-f726-a3ae-6323-a55190b9c005.png)

<h1>はじめに</h1>

本記事はド素人向けです。記事を書いているのもド素人です。
詳しい説明は割愛し、何をすればどの結果を見れるのかを簡単にまとめました。

まず、digコマンドとは、domain information groperの略で、直訳すると「ドメイン情報の手探りツール」という意味です。ネームサーバに対して問い合わせを行い、その応答結果を表示するコマンドです。

ド素人からすると、なんのこっちゃで、真っ黒い画面に良く分からない文字を打たないと調べられないの？と一度は思った方もいるかなと。

でも大丈夫。Webブラウザ上からGUIで簡単にDNSサーバの接続確認（digテスト）をすることができます。


<h1>今回使用するWebツール</h1>

https://www.cman.jp/network/support/nslookup.html

<h1>【実践】MXレコードを確認してみる</h1>

<h2>①～③の通りやってみてください</h2>
①digテストを行いたいドメイン（ホスト名/FQDN）を入力
②``MX：メール交換``（どのレコードを確認したいか）を選択
③``dig実行``をクリック

![qiita_pic1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2106206/9297d227-d036-c97d-6dad-ed5593bac3a4.png)

<h2>結果が出ました</h2>

![qiita_pic2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2106206/abce76ce-c4e0-209b-42ae-ae06525573c2.png)

```ruby:dig&#x20;MX&#x20;@&#x20;zeroichibank.jp
;; ANSWER SECTION:
zeroichibank.jp.    600 IN  MX  10 mx01.lolipop.jp.
```

つまり、DNSサーバへ問い合わせた応答結果（ANSWER SECTION）として、``zeroichibank.jp``の **MXレコード** は``mx01.lolipop.jp.``を向いているようです。

ちなみに、``mx01.lolipop.jp.``がどこのサーバ事業者を指しているのかは、Webブラウザより「mx01.lolipop.jp.　サーバ」などで検索してみてください。

![qiita_pic3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2106206/bdabb90a-b753-afba-5de2-4f8e2913f96b.png)

今回の場合、検索結果を見ると、GMOペパボ社が提供するレンタルサーバサービス「ロリポップ」がHITしています。
つまりは、メールサーバとして、ロリポップのレンタルサーバを使用しているということになります。

他にも、「NSレコードを確認したい」「Aレコードを確認したい」という時も、同じ要領で確認していただけます。

<h1>【参考】digコマンドのクエリタイプ</h1>

| タイプ | 意味 |
|:------------:|:------------:|
| A         |  ネットワークアドレス （デフォルト）         |
| ANY         | 指定されたドメインの全て／任意の情報         |
| NS         | ネームサーバ         |
| MX         | メールサーバの情報、メール交換情報        |
| SOA         |  ゾーンの権威者を表すレコード         |
neosでlogix その39

#概要

niosでlogixやってみる。
Neos UIのText Fieldを使ってみた。

#写真

![2021-12-24 02.00.42.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/a508b2f5-20b3-5b90-dfab-a96cbf0df50c.jpeg)


#手順

- 新規->Neos UI->Button
- 新規->Neos UI->Text Field
- インスペクターを開く
- Buttonのインターフェースを取り出す
- Text Fieldのインターフェースを取り出す
- ノードブラウザを表示
- Button Eventsをスポーン
- Witeをスポーン
- Stringをスポーン
- つなぐ

以上。
CSSスプライトを使って画像読込を効率化したい

この記事は [ミライトデザイン Advent Calendar 2021](https://qiita.com/advent-calendar/2021/miraito-inc) 16日目の記事です。

## やりたいこと

Webページ上でアイコンのような小さな画像ファイルをたくさんロードするのは通信が非効率になりがち。
これらのファイルを1つのファイルにまとめて出力したい！
ということでCSSスプライト＆結合済画像ファイルを自動で生成しよう。

今回はnpmモジュールの [spritesmith-cli](https://github.com/bevacqua/spritesmith-cli) を使って変換している。

## 準備

### 変換用JSコード

spritesmith-cli を使って変換するためのコード。
ファイルは必ず `.spritesmith.js` という名前で保存しよう。

```js:.spritesmith.js
'use strict';

const util = require('util');

module.exports = {
  cssTemplate: '.spritesmith.css.handlebars',
  destImage: 'images/hoge.png',
  destCSS: 'css/_hoge.scss',
  imgPath: '/images/hoge.png',
  padding: 2,
  src: 'data/hoge/*.png'
};
```

- cssTemplate: テンプレートファイル（後述）のファイルパス
- destImage:　スプライト画像の出力先ファイルパス
- destCSS: スプライト画像を利用するためのCSSの出力先ファイルパス
- imgPath: スプライト画像をWeb上から読み出すためのパス
- padding: 画像ごとのパディング（少しとっておくと隣の画像が表示される事故が起きない）
- src: 元画像ファイルのパス

### 変換用CSSテンプレート

以下.scssを出力するためのサンプル。
今回Retina対策として画像は倍サイズのものを用意して1/2で表示している。

```scss:.spritesmith.css.handlebars
.icon {
{{#items}}
  &.icon-{{name}} {
    &:before {
      content: "";
      background-image: url({{{escaped_image}}});
      background-position: ({{px.offset_x}} / 2) ({{px.offset_y}} / 2);
      background-repeat: no-repeat;
      background-size: ({{px.total_width}} / 2) ({{px.total_height}} / 2);
      width: ({{px.width}} / 2);
      height: ({{px.height}} / 2);
    }
  }
{{/items}}
}
```

### 変換方法

以下コマンドを実行すると.scss/.pngファイルが自動生成される。
適当に組み込んでビルドして使おう。

```
npx spritesmith-cli
```

### 使い方

以下のようにHTMLを記述することで画像を表示できる。

```html:index.html
<i class="icon icon-xxx"></i>
```