OmniAICreator/Qiita-1.07M huggingface dataset:
【メモ用】Mavenのプロキシ設定

###背景
  現在のチームはプロキシ（サーバ）を活用しているため、Mavenのプロキシ設定しないと、ビルド出来ない状態になるかもしれません。
下記のようなエラーが出てくる。
![build error.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225740/3ff5dd93-2a1c-06e2-ef02-27dc003e1a71.png)

###プロキシ設定
  先ずはMavenのインストールディレクトリに入ります。分からなかったら、下記のCMDで探してましょう。
> mvn -v

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225740/16657f2c-dbae-76ef-46f3-ea4bc6b655f4.png)

confフォルダに入り、settings.xmlファイルを開く。
proxiesタグを探して、自分のプロキシ情報を合わせて設定します。

```xml:setting.xml
  <proxies>
    <proxy>
      <id>optional1</id>
      <active>true</active>
      <protocol>http</protocol>
      <!-- 認証がなければ、外していい -->
      <username>proxyuser</username>
      <password>proxypass</password>
      <host>あなたのプロキシホスト</host>
      <port>あなたのポート</port>
      <!-- 設定しなくてもいいです -->
      <nonProxyHosts>127.0.0.1(設定しなくてもいいです)</nonProxyHosts>
    </proxy>
    <proxy>
      <id>optional2</id>
      <active>true</active>
      <protocol>https</protocol>
      <!-- 認証がなければ、外していい -->
      <username>proxyuser</username>
      <password>proxypass</password>
      <host>あなたのプロキシホスト</host>
      <port>あなたのポート</port>
      <!-- 設定しなくてもいいです -->
      <nonProxyHosts>127.0.0.1</nonProxyHosts>
    </proxy>
  </proxies>
```

ここまで、OKだと思います。
【Rails】saveやcreateメソッドでのエラーが発生した時のエラーメッセージの出し方

#saveメソッド

```
irb(main):005:0> user.save
   (0.3ms)  BEGIN
  User Exists (7.7ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` IS NULL LIMIT 1
   (0.2ms)  ROLLBACK
=> false
```
saveのみだとfalseが返されるのみ。エラーメッセージが出てこないので、エラー原因が特定できない。そういった場合saveの後に「!」をつけるとエラーメッセージが表示される。

```
irb(main):006:0> user.save!
   (0.3ms)  BEGIN
  User Exists (0.4ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` IS NULL LIMIT 1
   (0.1ms)  ROLLBACK
Traceback (most recent call last):
        1: from (irb):6
ActiveRecord::RecordInvalid (バリデーションに失敗しました: パスワードは3文字以上で入力してください, メールアドレスを入力してください, 名を入力してください, 姓を入力してください)
```

#createメソッド
saveメソッドに！マークをつけるとエラーメッセージが出てくることを書いている記事は多いが、createメソッドについても同様に！マークをつけると、エラーメッセージが出る。

```
irb(main):008:0> User.create
   (0.1ms)  BEGIN
  User Exists (0.3ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` IS NULL LIMIT 1
   (0.1ms)  ROLLBACK
=> #<User id: nil, email: nil, crypted_password: nil, salt: nil, created_at: nil, updated_at: nil, first_name: nil, last_name: nil>
```
！マークを付けた場合エラーメッセージが出てくる。

```
irb(main):009:0> User.create!
   (0.2ms)  BEGIN
  User Exists (0.4ms)  SELECT  1 AS one FROM `users` WHERE `users`.`email` IS NULL LIMIT 1
   (0.1ms)  ROLLBACK
Traceback (most recent call last):
        1: from (irb):9
ActiveRecord::RecordInvalid (バリデーションに失敗しました: パスワードは3文字以上で入力してください, メールアドレスを入力してください, 名を入力してください, 姓を入力してください)
```
AWS AthenaでS3に生成されたアクセスログを検索する

# 目的

S3に生成されたアクセスログをAthenaで検索するには、どうすればよいか

# 使い方

Athenaでアクセスログ用のDBを作成し、S3のアクセスログのファイルをテーブルに流し込んで
テーブルを作成した後、検索を行います。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/analyze-logs-athena/

```
create database s3_access_logs_db
```
```
CREATE EXTERNAL TABLE IF NOT EXISTS s3_access_logs_db.mybucket_logs(
         BucketOwner STRING,
         Bucket STRING,
         RequestDateTime STRING,
         RemoteIP STRING,
         Requester STRING,
         RequestID STRING,
         Operation STRING,
         Key STRING,
         RequestURI_operation STRING,
         RequestURI_key STRING,
         RequestURI_httpProtoversion STRING,
         HTTPstatus STRING,
         ErrorCode STRING,
         BytesSent BIGINT,
         ObjectSize BIGINT,
         TotalTime STRING,
         TurnAroundTime STRING,
         Referrer STRING,
         UserAgent STRING,
         VersionId STRING,
         HostId STRING,
         SigV STRING,
         CipherSuite STRING,
         AuthType STRING,
         EndPoint STRING,
         TLSVersion STRING
) 
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
         'serialization.format' = '1', 'input.regex' = '([^ ]*) ([^ ]*) \\[(.*?)\\] ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) \\\"([^ ]*) ([^ ]*) (- |[^ ]*)\\\" (-|[0-9]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\") ([^ ]*)(?: ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*))?.*$' )
LOCATION 's3://[バケット名]/[検索対象のディレクトリパス]'
```
C言語　再帰的に階乗を計算する

##正しくは、書き直した記事を上げました。こちらを参照ください。
C言語　階乗を求めるコード - Qiita
https://qiita.com/Kchan_01/items/594a49508d13999d0bb1

##以下は記録用、間違ったコード

自分のコード(間違いがあります、詳しくはコメント欄を参照）

```c
int factorial(int n){
    if(n > 0){
        return n * factorial(--n);
    } else {
        return n + 1;
    }
}
```

解説のコード

```c
int factorial(int n){
    if(n == 1){
        return 1;
    } else {
        return n * factorial(n - 1);
    }
}
```

##所感
_※解釈に間違いがあったので、注釈やコメント欄を参照してください。_

解説のコードn == 1というのが階乗のゴールを表していて、わかりやすい[^1]。__ベースケース__を意識して書かれている。
最大の数、最小の数を意識して、全体像を見通して書くことで、綺麗に書ける。

自分のコードの場合は、階乗の０の場合もループしているので、ループの数が１回多くなっている。
そのため、return n + 1というイマイチな書き方になっている。

インクリメントで書くのもよいが[^2]、この場合はn-1としたほうが、見た的にわかりやすかったと思う。

##まとめ
再帰を使う場合は、関数を終了する停止点である__ベースケース__を意識すること。



[^1]: このコードは再帰をわかりやすく示すためにn == 1とされているが、実際再帰やループを使う処理は上限、下限で設定したほうが安全なコードが書ける。
[^2]: 副作用完了点を踏まえて書くようにとご指摘いただいた。インクリメント演算子を使用する場合は気をつける必要がある。
Android studio でのメモ

#Android studio
・テキストの編集
編集したいテキストをクリックし、画面右側のattributes内の項目から編集する。

##java
・値等を扱う場合、値の種類を明確にする必要があり、型に入れる必要がある。

| 型の名前 | サイズ | 値の範囲 |
|:--|:--|:--|
| byte | 1 バイト | -128 ~ 127 |
| short | 2 バイト | -32768 ~ 32767 |
| int | 4 バイト | -2147483648 ~ 2147483647 |
| long | 8 バイト | -9223372036854775808 ~ 9223372036854775807 |

入れる値が小さいからといって、積極的に byte や short を使う必要はない。
普通の整数には int、非常に大きな数になることがある場合には long、という程度の使い分けでいい。
更に、小数を扱う場合には、浮動小数点数を表す型を使う必要がある。

| 型の名前 | サイズ |
|:--|:--|
| float | 4 バイト |
| double | 8 バイト |

float と double どちらも同じように使えるが、 float よりも double の方が、より巨大な数、より細かい数を表現することができる。

int x = 0.3;    // これはエラー
double y = 0.3; // 
このように float や double を使うこと
真偽値を表現するためには boolean 型を使う。

boolean flag = false;
文字列には String 型を使う。S は大文字なので注意。

また、文字列をソースコード中に記述するときには、ダブルクオーテーション " を使わなければならない。

String message = "Hello";

・演算子

| 演算子 |  |
|:--|:--|
| + | 足し算 |
| - | 引き算 |
| * | 掛け算 |
| / | 割り算 |
| % | 割り算の余り |
| && | 論理積（かつ） |
| II | 論理和（または） |
| ! | 否定（ではない） |
| < | より小さい（未満） |
| > | より大きい（超過） |
| <= | 以下 |
| >= | 以上 |
| == | 等しい |
| != | 等しくない |
[rails] http ステータスコードのsymbol一覧確認方法メモ

rspecでレスポンス結果200のhttp statusである、という場合は下記のように書ける

```ruby
expect(response).to have_http_status(200)
expect(response).to have_http_status(:ok)
```

下の:okといったsymbolのステータスコードを指定する場合、どんな値が定義されているか分からず都度調べたりしていたが、下記の定数に定義されているらしい

```ruby
[5] pry(main)> Rack::Utils::SYMBOL_TO_STATUS_CODE
=> {:continue=>100,
 :switching_protocols=>101,
 :processing=>102,
 :ok=>200,
 :created=>201,
```

そもそもドキュメントの頭に書いてあったし、Railsでも使っているよね。。。

参考
https://relishapp.com/rspec/rspec-rails/docs/matchers/have-http-status-matcher
スプレッドシートの初期表示シートについて

スプレッドシート（スプシ）のシートに年月シートを作る運用をしていて、月が替わって当月分のシートを作成して開き直した時に、「あれ？前月のシートのままだぞ？」といった場合に有用な手段。

>【変更前】
https://docs.google.com/spreadsheets/d/xxxxxx/edit#gid=12345678

⇒ gidでシートが指定されて開く

以下のようにURLの”edit”以降を削除すると、

>【変更後】
https://docs.google.com/spreadsheets/d/xxxxxx/edit

スプシを開いた時に一番左のシートが選択された状態で開く。
※　ちなみに「gid=0」にしても一番左シートにはならないことを検証済み。
C言語の動的メモリ確保時の null チェック

# メモ

udemy で、C言語のポインタを学習している際に、警告が出てきたので対応方法のメモ

# 開発環境

Visual Studio 2019 Community
Windows 10 

# ダメなコード

```C
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3
void main() {
	int* p1 = NULL;
	double* p2 = NULL;
	int i;
	// 動的にメモリ確保
	p1 = (int*)malloc(sizeof(int) * SIZE);
	p2 = (double*)malloc(sizeof(double) * SIZE);

	// 値のセット
	for (i = 0; i < SIZE; i++)
	{
		p1[i] = i;
		p2[i] = i / 10.0;
	}
	// 値の表示
	for (i = 0; i < SIZE; i++)
	{
		printf("p1[%d] = %d, p2[%d] = %lf\n", i, p1[i], i, p2[i]);
	}
	// メモリ領域の解放
	free(p1);
	free(p2);
}
```
上記のサンプルコードの場合、VS2019 環境ではエラーが発生する

> NULL ポインター 'p1' を逆参照しています。
> NULL ポインター 'p2' を逆参照しています。

エラーコード：[C6011(Microsoftサイトへのリンク)](https://docs.microsoft.com/ja-jp/cpp/code-quality/c6011?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev16.query%3FappId%3DDev16IDEF1%26l%3DJA-JP%26k%3Dk(C6011)%26rd%3Dtrue&view=vs-2019)

# 原因

> NULL かもしれない変数に値を入れようとしているから、エラーになる。変数を使う前に、NULLかどうかのチェックを入れれば、OK

# エラーが起きないコード

```C
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3

void main() {
	int* pointer_int = NULL;
	double* pointer_double = NULL;
	int i;
	// 動的にメモリ確保
	pointer_int = (int*)malloc(sizeof(int) * SIZE);
	pointer_double = (double*)malloc(sizeof(double) * SIZE);
	// 値のセット
	for (i = 0; i < SIZE; i++)
	{
		if( pointer_int != NULL ) 
			pointer_int[i] = i;
		if( pointer_double != NULL) 
			pointer_double[i] = i / 10.0;
	}
	// 値の表示
	for (i = 0; i < SIZE; i++)
	{
		if (pointer_int != NULL && pointer_double != NULL)
		{
			printf("pointer_int[%d] = %d, pointer_double[%d] = %lf\n", i, pointer_int[i], i, pointer_double[i]);
		}
	}	
	// メモリ領域の解放
	free(pointer_int);
	free(pointer_double);
}
```

ポインタ変数を使用する前に、変数の中身をチェックする。
Nuxt + Vue Property Decorator で ルーティングのパラメーターをバリデーションする

`TypeScript + Nuxt + Vue Property Decorator` で開発していたところ､ルーティングのパラメーターバリデーションでハマったので備忘録として残します｡

# 問題点

`Nuxt.js` でルーティングのパラメーターが数値であれば表示､それ以外なら `Not Found` とする､という処理を実現したい場合､以下のように記述すれば期待通りの結果になります｡

```js
export default {
  validate ({ params }) {
    return /^\d+$/.test(params.id)
  }
}
```

これを `TypeScript + Vue Property Decorator` を使って書く場合はどうすればいいでしょうか｡
素直に以下のように記述すると､`validate` はユーザー定義のメソッドとして扱われてしまうため､動作してくれません｡

```typescript
import { Vue, Component } from 'vue-property-decorator';

@Component
export default class Index extends Vue {
  validate({ params }: { params: any }) {
    return /^\d+$/.test(params.id);
  }

  // その他処理
}
```

# Vue Router 固有のメソッドを設定する

`Component.registerHooks` に `validate` を追加すれば期待通りの動作をしてくれます｡

```typescript
import { Vue, Component } from 'vue-property-decorator';

// 追加
Component.registerHooks(['validate']);

@Component
export default class Index extends Vue {
  validate({ params }: { params: any }) {
    return /^\d+$/.test(params.id);
  }

  // その他処理
}
```

`vue-property-decorator` の `Component` に認識させたい `Vue` プラグインのメソッドを追加すればOK
簡単ですね｡

# 別解

別解というか､ `Nuxt + TypeScript` で開発する場合､こちらのほうがベターなのかもしれませんが､ `vue-property-decorator` の代わりに､ `nuxt-property-decorator` を利用します｡

```bash
npm i -S nuxt-property-decorator
```

```typescript
import { Vue, Component } from 'nuxt-property-decorator';

@Component
export default class Index extends Vue {
  validate({ params }: { params: any }) {
    return /^\d+$/.test(params.id);
  }

  // その他処理
}
```

`Nuxt Property Decorator` は `Vue Property Decorator` のラッパーであり､[内部でプラグインメソッドを設定](https://github.com/nuxt-community/nuxt-property-decorator/blob/master/src/nuxt-property-decorator.ts#L18-L34)しているので､ `registerHooks()` を記述する必要がなくなりました｡

特に理由がないのであれば､ `Nuxt Property Decorator` を利用するほうが良さそうです｡

# 参考

- [Additional Hooks | Vue Class Component](https://class-component.vuejs.org/guide/additional-hooks.html)
- [nuxt-community/nuxt-property-decorator](https://github.com/nuxt-community/nuxt-property-decorator)
SSHJ使用時のSLF4Jに関する警告メッセージを抑止する

## やりたいこと
SSHJを使用した時に出力される警告メッセージを抑止することです。

## 問題概要
SSHJのSSHClientクラスをnewした時に警告メッセージが出力されます。

## 問題詳細
SSHJのSSHClientクラスをnewした時に以下の警告メッセージが出力されます。

```
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
```

警告が出力されても、SSHJは問題なく使用できます。
たぶん、ログ出力ができないだけなのではないかと思います。

## 解決策
まずは素直に、警告メッセージに示されているサイトを参照します。
すると、

- "org.slf4j.impl.StaticLoggerBinder"クラスがメモリにロードできなかった時に出力されるメッセージであること
- クラスパスに、slf4j-nop.jar、slf4j-simple.jar、slf4j-log4j12.jar、slf4j-jdk14.jar、または、logback-classic.jarのいずれか1つを配置することで問題が解決すること

が書かれています。
ということで、実行環境のクラスパスに、`slf4j-nop-x.x.x.jar`を配置することで警告メッセージを抑止することができました。
`x.x.x`の部分はバージョン番号になります。

ちなみに、EclipseのMavenプロジェクトをコンパイル/デバッグするような場合は`pom.xml`に以下のように記述しておけば良さそうです。

```xml:pom.xml
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-nop -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-nop</artifactId>
    <version>1.7.7</version>
</dependency>
```

なお、上の例でバージョンに`1.7.7`を指定しているのは、SSHJが`slf4j-api`の`1.7.7`を必要としているようだったので、そのバージョンと合わせてみました。

-- 以上--
Get IP Address using Host header Using Golang

This golang tutorial help to find IP address from the HTTP request in GO.Sometimes we need to get host ip for filter or anything else.

I ll let you know how to get the IP address of incoming HTTP requests in Go.We can find proxy behind the http request in golang using X-FORWARDED-FOR.

https://www.golanglearn.com/get-ip-address-using-host-header-using-golang/
C++勉強メモ帳


参考資料
https://www.runoob.com/cplusplus/cpp-intro.html

C++ 简介
C++ 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言，支持过程化编程、面向对象编程和泛型编程。

C++ 被认为是一种中级语言，它综合了高级语言和低级语言的特点。

C++ 是由 Bjarne Stroustrup 于 1979 年在新泽西州美利山贝尔实验室开始设计开发的。C++ 进一步扩充和完善了 C 语言，最初命名为带类的C，后来在 1983 年更名为 C++。

C++ 是 C 的一个超集，事实上，任何合法的 C 程序都是合法的 C++ 程序。

注意：使用静态类型的编程语言是在编译时执行类型检查，而不是在运行时执行类型检查。

面向对象程序设计
C++ 完全支持面向对象的程序设计，包括面向对象开发的四大特性：

封装
抽象
继承
多态


标准库
标准的 C++ 由三个重要部分组成：

核心语言，提供了所有构件块，包括变量、数据类型和常量，等等。
C++ 标准库，提供了大量的函数，用于操作文件、字符串等。
标准模板库（STL），提供了大量的方法，用于操作数据结构等。
ANSI 标准
ANSI 标准是为了确保 C++ 的便携性 —— 您所编写的代码在 Mac、UNIX、Windows、Alpha 计算机上都能通过编译。

由于 ANSI 标准已稳定使用了很长的时间，所有主要的 C++ 编译器的制造商都支持 ANSI 标准。
転職日記１０日

久しぶりの更新になります。

サボっていたと言われても仕方がないのですが、引っ越しなどに時間を割いていたと言い訳させていただきます。

面接もしていますが、ネットで見かける未経験でwebエンジニアになれましたという方々の凄さを実感しています。

私自身まだ諦めてはいないのですが、どこかで、早く就職しなきゃ、

面接したときに今までの職歴の延長のようなところを受けた方がいいとか言われて

凹んだりする日も多いです。

これからはまたプログラミングを勉強できるので、諦めずに食らいついていこうと思います。

自分はこのような未経験でwevエンジニア目指すと行った部類では最低辺だと思っております。

これを自覚して、前に進んで、同じように思っている皆様の道筋になっていきたいと思います
Azure Pipelines で GnuPG 署名を自動化する方法

Azure Pipelines に限った話ではなく、 CI で GnuPG による署名を自動化する話です。

# パスフレーズ入力の自動化

`gpg` コマンドのオプションで `--passphrase` オプションを使えば、とりあえずパスフレーズを渡せるのですが、最近の GnuPG だと `--batch` と `--pinentry-mode loopback` を使わないと有効にならなかったり、対話的に署名したい場合とコマンドを使い分けが必要だったりするので別の方法を考えました。

そこで注目したのが [`gpg-preset-passphrase` コマンド](https://www.gnupg.org/documentation/manuals/gnupg/gpg_002dpreset_002dpassphrase.html)。 GnuPG のパスフレーズをキャッシュに事前設定するコマンドです。

ドキュメントによると、引数の cacheid は GnuPG 鍵の ID ではなくて keygrip を指定するとのこと。 keygrip はとりあえず次で取れることを確認。

```sh
keygrip=`gpg --list-secret-keys --with-colons '鍵の ID' | \
    awk -F : '$1 == "grp" { print $10 }'`
```

なお `gpg-preset-passphrase` コマンドを利用するには、 `gpg-agent` を `--allow-preset-passphrase` オプション付きで実行する必要があるので、 `gpg` を最初に使う前に**一度だけ**以下を実行しておきます。

```sh
echo allow-preset-passphrase >> $HOME/.gnupg/gpg-agent.conf
```

最後に、 `gpg-preset-passphrase` を次のように実行すれば準備完了。

```sh
echo 'パスフレーズ' | \
/usr/lib/gnupg/gpg-preset-passphrase --preset "$keygrip"
```

以上で、 `gpg` コマンドがパスフレーズを尋ねてこなくなりました。めでたしめでたし。
【プログラミング初心者】プログラミング用語　変数・定数について

#はじめに
プログラミングの学習を始めて3ヶ月ほど経過した駆け出しエンジニアです。
プログラミングの学習を始めたばかりの頃は、新しい用語が出てきて理解するのが大変でした。3ヶ月たった今でも、次々と始めて聞く用語が襲撃してきます笑笑
ですが、それに立ち向かうのがエンジニアの宿命だと受け入れ日々奮闘中です。

今回は変数・定数についてまとめました。
プログラミング初心者の役にも立てれば幸いです。

#プログラミングとは
簡単に言うと、**コンピュータへの指示を書くこと**です。

コンピューターに指示を出すためには、プログラム（コンピューターが作業を実行する順番）を作成します。
コンピューターは人間の言葉を理解できません。そのため、コンピューター語を使用して指示を出す必要があります。

コンピューターは**プログラムを使用して命令を出さない限りただの怠け者**なんです笑笑

#変数
変数とはズバリ、**データを一時的に保存するための箱**です。

変数につけた名前を**変数名**、保存されているデータを変数の**値**と呼びます。
値だけだと、なんの値かがわかりにくく、プログラムを書いているとたくさん値が出てきてどれがどの値かが混乱します。

ですが、その値を変数名をつけて変数として保存すると、**その値がどの値でどのような役割を果たしているか**がわかります。

```:変数の例
200
300
500
```
例えば、上記のように、`200`、`300`、`500`の３つの値がありますが、なんのための値かがわかりません。それを解決するために変数を使います。

```:変数の例
applePrice = 200　  # リンゴの値段  
bananaPrice = 300　 # バナナの値段
totalPrice = 500 　 # 合計金額
```

上記のようにそれぞれの値に変数名をつけると、なんのための値かが一目でわかります。
`200`リンゴの値段、`300`はバナナの値段、`500`は合計金額。

このように、変数を使用して値の役割を可視化することで、値の再利用や値の行方不明などを未然に防ぐことができ、情報共有もスムーズに行えます。

#定数
定数の考え方は、変数と同じで**データを一時的に保存するための箱**です。

ですが、**決定的な違い**があります。名前からわかるように変数は**変わる数**、定数は**定まっている数**です。

- 変数は、**中身の値を変更する**ことができる
- 定数は**中身の値を変更する**ことができない

定数は、一度値を設定してしまうと後で**変更が効かない**のです。

こう聞くと、定数のような頑固者より、変数のような柔軟に対応出来る奴の方が便利でええやんっと思うかもしれませんが、**頑固者にも活躍する場**はあるのです。

例えば、円周率のような一定で変わらない値を使う場合、変数にその値を入れてしまうと手違いで**値が変わってしまう可能性**があります。こういったシチュエーションに、**定数が大活躍**するんです！！！

先ほど述べたように定数は新しい値がきても受け入れず追い返します。つまり、定数を使用することで**値が変わってしまう可能性をなくし、値が変ってしまうことを未然に防ぐ**ことができます。

このように、それぞれの特性を理解し使いこなすことで予期せぬエラーを防ぐことができます。

#まとめ
- **プログラミングとはコンピューターへの指示を書くこと**
- **変数・定数を使用して値の役割の可視化**
- **変数は値を変更でき、定数は値を変更できない**
- **値が変わってほしくない場合に定数を使用**

使用する言語により定数がない場合（例えばPython）があります。さらにそれぞれの言語で書き方も変わってきますが、考え方は一緒です。

今回は変数・定数について書きましたが、これからも初心者なりにどんどんいろんな用語の解説をしていきたいと思います。

###（追記）
- Pythonの場合、変数は箱ではなく**名札（ラベル）**
- 変数には、**プリミティブ型**と**参照型**の２種類がある
AutoML Visionを一ヶ月1ノード起動して遊んでたら破産しかけた話

## 話はカードの請求連絡から始まりました
<img width="400" alt="Screen Shot 2020-03-05 at 13.39.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559103/7590ee94-1b28-022b-34c5-03e1d702c7b4.png">

ナチュラルにフィッシング系の架空請求かと思いました。
すぐさまGCPのコンソール確認するとこんな感じ

![Screen Shot 2020-03-05 at 11.19.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559103/6093df9e-d7c4-0987-879e-865adea40665.png)

$1,231.25っていくらになるんだー・・・・・・？と現実逃避気味に
普通にたっけえですよね。
何かAPI_KEYでも漏洩したかなとすら思いました笑
笑ってる場合じゃねえんですけどね。

## 金額が高額になった理由
ということで、そんな金額になった理由を確認しました。

[こちら](https://cloud.google.com/vision/automl/pricing)「トレーニングとオンライン予測それぞれに 40 時間の無料ノード時間」にあるように40時間の学習は無料でしたのであまり気にしてませんでした。

それでもって、オンライン予測は学習よりコストが安いと思ってましたし、実際にそう書いてあるのを見た気でいたのですが、、、今読んだら「1 ノード時間あたり $1.82」って書いてありますね。本当に無事死亡です。
~引用~
```（1 ノード時間あたり $1.82）*（1 ノード）*（1 日あたり 24 時間）*（30 日）= $1,310.40（デプロイメントと予測）```
~~

でもやっぱり書いてあったなーって思って思い返すと[Cloud Vision API](https://cloud.google.com/vision/product-search/pricing?hl=ja)ですね。
画像1,000枚までは無料なんだなって思っていて、調査、研究目的だったら1000回程度で足りるだろうと思ってました。

ちなみにCloud Vision APIとAutoML Vision APIの用途の違いはざっくりこんな感じです
・**Cloud Vision API**：特定の条件で学習済みの画像認識API
　→顔の検出やテキストの読み取りなど
・**AutoML Vision API**：学習データを任意で用意・学習させる画像認識API
　→柴犬の写真とビーグル犬の写真を学習させ、犬というカテゴリではなく、犬の写真からどちらの犬種か判定するなど

結論としてはAutoML Vision APIはデプロイしたノード数の起動時間に対して課金されるので、
<font color="Red">**使用してもしなくてもデフォで月10万以上はかかる**</font>シロモノです。

AutoML Vision APIで遊ぶ時は金銭的に大人の遊び？になるので気をつけましょう
RSpec&Rails少し複雑なテストのチートシート


RSpecでテストカバレッジを上げつつRailsのリファクタリングをしたい場合によく使います。

関数のパラメータをチェック
--------------------------

```test.rb
it '#functionにパラメータparamを渡すこと' do
  allow(TargetClass).to receive(:function) {
    |object, param1|

    expect(param1).to eq 'this is parameter'
  }

  TargetClass.function('this is parameter')
end
```

パラメータが複数ある場合は `|object, param1, param2, paramn|` のように追加します。
関数の引数の数と一致しなくてもエラーは出ません。


ログのチェック
--------------

スタブを使うことで実現できます。
ログレベルはテストしたいログに合わせて設定します。

```test.rb
it 'ログが出力される' do
  allow(logger).to receive(:info)

  TargetClass.output_log
  expect(logger).to have_received(:info).with('[INFO] 処理を開始しました')
  expect(logger).to have_received(:info).with('[INFO] 処理を終了しました')
end
```


参考
----

- https://relishapp.com/rspec/rspec-mocks/v/2-99/docs/method-stubs
【Android】Glideを使って画像表示後Blurをかける

## どういうときに使う？
- スクロールしたらヘッダーのイメージをぼかしたい時とか。
- 表示後に動的Blurにする必要が無いのであれば必要ない。

## 使うもの
- [glide](https://github.com/bumptech/glide)
- [glide-transformations](https://github.com/wasabeef/glide-transformations)

## コード

```kotlin
val url = "https://hogehoge"

// 初回読み込み
Glide.with(imageView.context)
     .load(url)

// Blurをかける時
Glide.with(imageView.context)
     .load(url)
     .transform(
         GrayscaleTransformation(),
         BlurTransformation(int)
     )
     .placeholder(imageView.drawable)
     .into(imageView)
```

**ポイントは`placeholder`で 既に表示されている ImageView の Drawable を指定する所**。
上記のことを忘れるとチカチカする。

Blur の他にも表示後に何かの値を変更するみたいなときとかも同じようにやればいいと思う。
CoilとかPiccasoでも同じ事ができると思う。

Seekbarとかと組み合わせて試してみて:wave:
MicrosoftGraphを使う際に行った環境設定設定

## 環境
|項目| 内容|
|---|---|
| OS | Windows 10 |
| Node.js | インストール済み |

## 準備：環境設定
- 以下のコマンドで正常にインストールできていることを確認する。

```console
$ node -v
$ npm -v
```

- 管理者権限でPowerShellを開き、以下のコマンドを実行する。

```console
$ Set-ExecutionPolicy -Scope CurrentUser Unrestricted
$ npm install --global --production windows-build-tools
$ npm config set strict-ssl false
$ node
> process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
```

- 1行目: `Set-ExecutionPolicy -Scope CurrentUser Unrestricted`
    - スクリプトの実行可能範囲の設定を変更します。
- 2行目: `npm install --global --production windows-build-tools`
    - node.jsで`microsoft-grah-client`を使用するための環境を構築します。
- 3行目: `npm config set strict-ssl false`
    - node.jsのパッケージをインストールする際に証明書がないパッケージでエラーになり止まってしまうので、確認をオフにします。
- 4行目: `process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';`
    - 3行目と同様に証明書の確認をせずにパッケージのインストールを進めるための設定です。

## 参考
- [PowerShell のスクリプトが実行できない場合の対処方法](https://qiita.com/Targityen/items/3d2e0b5b0b7b04963750)
Rails DBの関連について

DBやRailsアプリの設計書がない案件でDBの関連について調べることがあったのでそのついでのまとめ。

RailsではDBのリレーションシップを表現する場合に以下のテーブル命名規則がある。

**テーブルの命名規則**

- 外部キーは``<参照先のモデル名_id>``でなければならない
    - すなわち外部キー参照先のカラムは必ずidでなけらばならない(命名規則ではないが仕様として)
- 中間テーブル(m:nアソシエーションの表現に必要)は``<テーブル名1>_<テーブル名2>``でなけれなならない


上記を踏まえた上で、Railsではモデルで他のモデルに対する関連(アソシエーション)を定義できる。
なお、アソシエーションの利用にあたっては以下の命名規則がある。

## アソシエーションを設定するメリット
モデルAにモデルBが所属する場合、アソシエーションの設定を省くと以下のようなモデル定義のイメージになる。

```
class A < ActiveRecord::Base
end

class B < ActiveRecord::Base
  # a_id カラム持ち
end
```

これだけの定義だと、
子モデルBから親モデルAのレコードを参照するには、
``A.find(<Bのインスタンス>.a_id)`` とすることになり、
逆に、親モデルAが持つ子モデルのレコードを参照するには、
``B.find_by(a_id: <Aのインスタンス>.id)`` とすることになる。

関連の設定を含めると、以下のようなイメージになる。

```
class A do
  has_one :b
end

class B do
  # a_id
  belong_to :a
end
```

関連を設定すると、
子モデルBから親モデルAのレコードを参照するには、
``<Bのインスタンス>.a (has_oneサボると使えない)``
逆に、親モデルAから子モデルBのレコードを参照するには、
``<Aのインスタンス>.b (belongs_toサボると使えない)``

とでき、相当楽になる。

## アソシエーションの定義

**親子関係**
親モデルに子モデルが所属する場合、
子モデル側では、親モデルのidを外部キーのカラムとして持つことになる。
言い換えれば外部キーを持つモデルが子であり、その参照先のモデルが親となる

**1:1、1:nのアソシエーション定義**

定義するモデル|関連の意味|アソシエーション定義コード
---|---|---
子モデル側|親モデルに属する|belongs_to :<親モデル名(先頭小文字)>
親モデル側|子モデルに対して1:nの関係である|has_many :<子モデル名(複数形,先頭小文字)>
親モデル側|子モデルに対して1:1の関係である|has_one :<子モデル名(単数形,先頭小文字)>


**m:nのアソシエーション定義**

定義するモデル|関連の意味|アソシエーション定義コード
---|---|---
双方|m:nの関係で、親子関係がない|has_and_belongs_to_many :<関連モデル名(複数形,先頭小文字)>

なお、各モデルに対して関連を定義するコードを書くと、
関連するテーブルの対象レコード(群)を操作できる便利なインスタンスメソッドが自動で使えるようになる。

**belongs_to/has_oneアソシエーションを定義したモデル**

インスタンスメソッド|効果
---|---
.<関連先モデル名(先頭小文字)>|関連先モデルのインスタンスを取得 (``<Aのインスタンス>.b``, ``<Bのインスタンス>.a``)
.<子モデル名(先頭小文字)>=<親モデルインスタンス>|外部キーに関連先モデルの外部キー参照先カラム値を入力する (``<Bのインスタンス>.a = <Aのインスタンス>``)　※もちろん``<Bのインスタンス>.a_id = <Aのインスタンス>.id``でも同じ挙動
.build_<子モデル名(先頭小文字)>(カラム1: 値, カラム2: 値,....)|関連先モデルのインスタンスを生成(保存しない) (``<Aのインスタンス>.build_b(...)``) ※Bのインスタンスが指定したカラム値で生成されるとともに、自動的に``<Bのインスタンス>.a_id に <Aのインスタンス>.id``が入力される。
.create_<子モデル名(先頭小文字)>(カラム1: 値, カラム2: 値,....)|関連先モデルのインスタンスを生成(保存もする)

**has_many/has_and_belongs_toアソシエーションを定義したモデル**

(省略)

アソシエーション定義コードではオプションも定義できる

```
(例)dependentオプション
# 参照先のhogeモデルが削除されたら自身のモデルも削除する
belongs_to : hoge, dependent: :destroy
```

他にも色々ある
Could not find encoder for codec id 27: Encoder not found | python opencv

#  要旨
pythonのopencv-pythonでmp4形式の動画を書き出そうとした際のエラーです. 

## エラー内容
```
Could not find encoder for codec id 27: Encoder not found
````

## エラー原因 (コード抜粋)
```
video_FourCC = int(vid.get(cv2.CAP_PROP_FOURCC))
output_path = "test.mp4"
out = cv2.VideoWriter(output_path, video_FourCC, video_fps, video_size
```

video_FourCCの形式が良くなかったのが原因.
なおoutput_pathをmp4形式の際のエラーと思われます. 

## エラー修正後 (コード抜粋)

```
video_FourCC = cv2.VideoWriter_fourcc(*"mp4v")
output_path = "test.mp4"
out = cv2.VideoWriter(output_path, video_FourCC, video_fps, video_size
```

video_FourCCを上記のように書き換えると正しく動きます.
Power AutomateでTwilioから電話をかける

# TwilioをPowerAutomateから利用したい。
アクションのHTTPを追加して以下のステータスに設定してください。
![ああああ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391507/eef83cb6-39c6-1f67-0499-b91f2e53ca9c.png)

方法：　POST
URI:　https://api.twilio.com/2010-04-01/Accounts/[アカウントSID]/Calls.json
ヘッダー：　Content-Type　｜　application/x-www-form-urlencoded
本文To=[宛先]&From=[電話先番号]&Url=[実行したいREST先]


***
認証＝基本
ユーザー名＝[アカウントSID]
パスワード＝[AUTH TOKEN]

で認証が必要です。


***
訂正
画像ではToが購入した番号になっていますが、電話先の番号です。
gitでたまに使うコマンド

#概要
git関連でたまに使うコマンドリンクをまとめて見られるようにメモ

##ブランチ一括削除

https://qiita.com/satoshi03/items/c53aab17f3270477e33a

    //while
    git branch | grep <文字列> |  while read branch ; do git branch -d ${branch} ; done ;  
    //xarges
    git branch | grep <文字列> | xargs git branch -d

##特定コミット抽出して反映(cherry-pick)

https://qiita.com/ta__ho/items/8204a22a53b02ee0817e
https://img.atwikiimg.com/www8.atwiki.jp/git_jp/pub/git-manual-jp/Documentation/git-cherry-pick.html

    //-nを付けるとstageの状態で止まる
    git cherry-pick -n <コミットID>
    //マージコミットを抽出したい場合
    git cherry-pick -n -m 1 <コミットID>

##別リモートリポジトリを同じremote内に追加

https://qiita.com/chihiro/items/d018599ef13c35781412

・別リモートリポジトリを追加した時点でcherry-pickで別リポジトリから抽出は可能
・チェックアウトした別リモートリポジトリのブランチをマージすることも可能

    //同じ場所にリモートリポジトリを追加。ローカル名は何でもいい。origin_testとか。
    git remote add <ローカル名> <url>
    git fetch <ローカル名>
    
    //追加したリモートリポジトリからブランチチェックアウト   
    git checkout -b <任意のブランチ名> <ローカル名>/<抽出したいブランチ>

##submodule削除・再追加

http://takaaki-kasai-tech.blogspot.com/2014/02/how-to-remove-git-submodule-using-each-version.html
https://qiita.com/kinpira/items/3309eb2e5a9a422199e9

**※git バージョンが1.8.5以上の場合。**

    $ git submodule deinit path/to/submodule
    $ git rm path/to/submodule
    $ rm -rf path/to/submodule
    $ git submodule add 【リポジトリURL】 【追加したいディレクトリ】
    //具体例
    $ git submodule deinit -f aaa/bbb
    $ git rm aaa/bbb
    $ git submodule add https://git.git aaa/bbb

**※git バージョンが1.8.3未満は以下を個別に削除する必要がある。**

    //削除するサブモジュールの場所。
    .git/config
    .gitmodules
    //git rm でサブモジュールパス削除
    .git/modules/aaa/bbb
    //rm -rf で直接サブモジュールパス削除

##コンフリクト一方修正

https://qiita.com/nantekkotai/items/2ed17c3d774211d234a4

    //現在ブランチの修正に変更
    $ git checkout --ours AAAA.txt
    //マージする側ブランチの修正に変更
    $ git checkout --theirs fileB.txt

    //実行後はaddする
    $ git add <ファイル名>

##コミット打ち消し・修正・取消

https://qiita.com/kansiho/items/2bacecdb95d752cb38b7
https://qiita.com/ritukiii/items/74ee3274c3f218511a0c
https://qiita.com/chihiro/items/2fa827d0eac98109e7ee

・reset
・amend
・revert
・【危険】push -f

    //ローカル上で修正残して直前コミット取消
    git reset --soft HEAD^
    //ローカル上で修正含めて直前コミット取消
    git reset --hard HEAD^

    //ローカル上でコミット直後に再度直前コミットのソース修正・コメント修正等をして、同じコミットにしたい場合
    git commit --amend
    
    //取り消した内容を残してコミットする
    git revert <commit>
    
    //戻したい位置までコミット戻してリモート強制更新
    git reset --hard <commit_id>
    git push origin HEAD --force

##差分抽出

    //[1]取得ソースの branch名/hashtag/tag名
    //[2]ベースのbranch名/hashtag/tag名
    //[3]変更あるbranch名/hashtag/tag名
    git archive [１] `git diff --name-only [２] [３] --diff-filter=ACMR` -o [zipファイル名].zip

##stage から Unmerged paths,Untracked filesに戻す・削除

https://qiita.com/rch1223/items/9377446c3d010d91399b
　※戻す方法は上記にいろいろ載ってる
https://qiita.com/k0uh0t/items/ae885bf2d5e05614b80f

    //stage から Unmerged paths
    git reset <ファイル名>
    git reset .

    //変更前に戻す
    git reset HEAD <ファイル名>
    
    //gitから削除
    git rm -rf フルパス

    //Untracked filesのディレクトリ含めた削除
    git clean -fd

##コンフィグ関連

・文字コード設定とか
https://nekonenene.hatenablog.com/entry/2015/04/18/210706
・git logが見やすくなる
https://blog.toshimaru.net/git-log-graph/
・git for windows改行関連
https://qiita.com/uggds/items/00a1974ec4f115616580
アルゴリズムの基礎

##アルゴリズムの三大処理
- 順次処理
    - 処理を記述した順番に実行する。
- 分岐処理
    - 条件により処理の流れを変える。
- 繰り返し処理
    - 条件が成立する間、処理を繰り返す。

全てのアルゴリズムは、必ずこの３つの処理の組み合わせから構成される。
この３つの処理を組み合わせてプログラムを設計する方法論のことを__構造化プログラミング__という。


##アルゴリズムの性質
アルゴリズムが成立する条件として、__正当性__と__停止性__が必要。

- __正当性__
    - 与えられた課題に対して正しい結果を返すこと。
- __停止性__
    - 有限時間内で必ず正しく停止すること。

その他のキーワード

- 部分正当性
    - アルゴリズムの任意の一で、その時点で満たされるべき条件が必ず成立していること。（アサーションが成立しているという）
- 無限ループ
    - 停止性がない手順のこと。

##データ構造の基本
__データ構造__とは大量のデータを効率よく管理する仕組みのこと。データは、__データ型__によって分類されている。

整数型、実数型、文字型、文字列型、論理型

###用語
- 変数
    - データを格納するメモリ上の領域のこと
- 変数名
    - 変数同士を区別するためにつける名前
- 代入
    - 変数にデータ（値）を入れること
    - 計算のために、式中の文字に、ある特定の値を与えること。

##主なデータ構造
- 配列
    - 同じ種類のデータをくすう並べたデータ構造。
    - 一直線上に値を並べた一次元配列、縦横に値を並べた二次元配列、その他、三次元配列、多次元配列などがある。
    - 大きさは予め固定されている。
- リスト
    - 同じ種類のデータに順序付けをして並べたデータ構造
    - 配列と違い、順序を付けられる。
    - データの挿入、削除が容易。
- スタック
    - 机に本を積み上げていくように、データを管理する方法。
    - データを入れた順序と、逆順にデータを取り出すことができうｒ．
- キュー
    - スタックとは逆にデータを入れた順に取り出すことができるデータ構造
- ツリー
    - 枝先にデータを持ち、そこからまた枝分かれしていく構造




###参考
一週間で身につくアルゴリズムとデータ構造|トップページ～プログラマーなら身につけておきたい、アルゴリズムの基本。
http://sevendays-study.com/algorithm/index.html
MySQL+DjangoでSSL通信

DjangoでWebアプリ開発する際にMySQLサーバーとSSL通信する方法をまとめます

# SSL証明書の取得
SSL証明書を取得します．例えば，AWSのRDSでMySQLを使っているなら
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/ssl-certificate-rotation-mysql.html
を参照．

証明書をWebサーバの`/usr/local/ssl/`内等に置きます．証明書自体の権限は644，証明書までのディレクトリの権限は755にする必要が有るので注意．

# MySQLサーバと通信できるかテスト
SSL通信出来る状態になっていれば

```bash
mysql -h ホスト名 -u ユーザー名 -p --ssl-ca=/usr/local/ssl/証明書.pem --ssl-mode=VERIFY_IDENTITY
```
で接続可能です．

# Djangoの設定
Djangoのsettings.pyを書き換えます．具体的には，DATABASES={}内のOPTIONSに'ssl'を追加します．

```python:settings.py
DATABASES = {
    'default': {
        ...
        'OPTIONS': {
                   ...
                   'ssl': {'ca' : '/usr/local/ssl/証明書.pem'},  # 追加
                   },
        ...
    }
}

```

以上です！
Nuxt.jsでprocess.env.NODE_ENVを参照する際の挙動についてまとめてみた

Nuxtで`process.env.NODE_ENV`を参照する際にハマりがちだったので挙動をまとめました。

なお、環境は以下のとおりです。

```package.json
  "dependencies": {
    "cross-env": "7.0.0",
    "nuxt": "2.11.0"
  },
```

※この記事で記載しているファイルは内容を一部抜粋したものです。

## デフォルトの挙動

まず、何の設定もせずに`yarn dev`したときと`yarn build && yarn start`したときの値を確認します。

```package.json
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start"
  },
```

```html:pages/index.vue
<template>
  <div />
</template>

<script>
export default {
  mounted() {
    console.log(process.env.NODE_ENV);
  }
};
</script>
```

実行方法 | process.env.NODE_ENV
--- | ---
yarn dev | "development"
yarn build && yarn start | "production"

このようにデフォルトで値が入っていることがわかりました。次に、環境変数を指定した際の挙動を見ていきます。

## 環境変数を指定したとき

```package.json
  "scripts": {
    "dev": "cross-env NODE_ENV=dev nuxt",
    "build": "cross-env NODE_ENV=build nuxt build",
    "start": "cross-env NODE_ENV=start nuxt start"
  },

```

実行方法 | process.env.NODE_ENV
--- | ---
yarn dev | "development"
yarn build && yarn start | "production"

環境変数に指定した値が入ると思いきや、デフォルトの値が優先されてしまいました。これでは困るので、次に`NODE_ENV`を`nuxt.config.js`に指定したときの挙動を見てみます。

## env を指定したとき

```nuxt.config.js
  env: {
    NODE_ENV: process.env.NODE_ENV
  }
```

```package.json
  "scripts": {
    "dev": "cross-env NODE_ENV=dev nuxt",
    "build": "cross-env NODE_ENV=build nuxt build",
    "start": "cross-env NODE_ENV=start nuxt start"
  },
```
実行方法 | process.env.NODE_ENV
--- | ---
yarn dev | "dev"
yarn build && yarn start | "build"

今回はこのようにビルド時に埋め込んだ値が取得できることがわかりました。

## まとめ

というわけで、`process.env.NODE_ENV`の値を Nuxt で定義したコンポーネントから取得する際は、`nuxt.config.js`の`env`プロパティに`NODE_ENV`を指定したほうが間違いは起こりにくいかもしれません。

しかし、今回の記事では触れていませんが、例えば Nuxt を express で動かす際などは、`process.env.NODE_ENV`の値を`server.js`などのファイルから参照する関係で、予想と違う形で`process.env.NODE_ENV`の値が返ってくることがあるかもしれません。

あまりないケースかとは思いますが、そのようなことを考えると build 時とサーバー起動時に設定する`NODE_ENV`の値は同じにしておいたほうが無難っぽいです。

## 追記

Nuxt のバージョン`2.13.0`から`runtimeConfig`のサポートが入りました。これにより、環境変数の設定がより簡潔に書けるようになるかもしれません。詳しくは以下のページをご確認ください。

- [Release v2.13.0 · nuxt/nuxt.js](https://github.com/nuxt/nuxt.js/releases/tag/v2.13.0)
- [いつの間にかNuxt.jsで実行時環境変数が使えるようになっていた件](https://zenn.dev/kouchanne/articles/83466e36e1c30f174ae8)
Lambda から DynamoDB にアクセス (Node.js)

実行ロールには、DynamoDB へのアクセス権がついている必要があります。
出力結果は、CloudWatch で確認が出来ます。

テーブルの一覧

```js:list_tables.js
var AWS = require("aws-sdk");

var dynamodb = new AWS.DynamoDB({region: 'ap-northeast-1'})

var params = {    Limit: 100}

exports.handler = async (event) => {

console.log("*** start ***")

try {
	var data = await dynamodb.listTables(params).promise()
	console.log(data)
	} catch (ee) {
		console.log(ee)
	}

 
const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    }
    return response;
}
```

テーブルの説明

```js:describe_table.js
var AWS = require("aws-sdk");

var dynamodb = new AWS.DynamoDB({region: 'ap-northeast-1'})

var table = "Movies"
var params = {TableName: table}

exports.handler = async (event) => {
    
console.log("*** start ***")

try {
    var data = await dynamodb.describeTable(params).promise()
    console.log(data)
    } catch (ee) {
       console.log(ee)
    }

    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    }
    return response
}
```
Macでキーリピートが効かない場合の対処法

ちゃんとシステム設定で設定しているのに.. :thinking: 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/611/e06d8f60-8917-b4cc-0cd5-955c76c38a59.png)

ちなみに日本語入力時はリピートできるのに、英数字だけできない。。

### 環境
```
macOS Catalina
バージョン10.15.3
```

ターミナルで以下を叩いて、再起動すればOK :ok_hand: 

```sh
defaults write -g ApplePressAndHoldEnabled -bool true
```

以上 :wave: 

## 参考
- [How to Enable Key Repeating in macOS](https://www.howtogeek.com/267463/how-to-enable-key-repeating-in-macos/)
Firebase Hostingを使ってWebサイトを公開する方法

【不明点あればコメントからご質問ください】
[Firebase Hostingを使ってポートフォリオサイトを無料で公開する方法](https://webdesign-trends.net/entry/9692)
を参考に簡単なポートフォリオを公開しました。
[ポートフォリオサイト](https://portfolio-878f6.firebaseapp.com/)
Let's Encryptが証明書300万件を失効させるらしいのでリストされてるか調べた

株価ばかり気にしてたら結構インパクトの大きいイベントに気づかずに当日を迎えておりました。

https://japan.zdnet.com/article/35150260/

- 2020/3/4...って、今日！
影響を受けるのは全体の2.6%ということですが、公式からメール通知も来てないので（なので気づかなかった）問題ないとは思いますが、一応チェックしました。

- 対象がある場合、通知されるメールの件名は下記

> ACTION REQUIRED: Renew these Let's Encrypt certificates by March 4


- [caa-rechecking-incident-affected-serials.txt.gz](https://d4twhgtvn0ff5.cloudfront.net/caa-rechecking-incident-affected-serials.txt.gz)にアカウントIDでソートされた、影響を受けるすべての証明書のリストが含まれており、各エントリの構文は下記

<b>serial 0362...8fdb 131 b8dc...ed3f names: [....] missing CAA checking results for <name> at 2019-12-03 21:08:34.826011675 +0000 UTC 
</b>


- シリアル番号を調べ、失効対象がリストされているか確認し、Hitした場合は更新作業が必要です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58788/7ced37b8-ca18-4a2b-0c54-33710ea04623.png)


```sh
grep -F <serial_number> caa-rechecking-incident-affected-serials.txt
```

- 証明書更新

```sh
certbot certonly --webroot -w <document_root_path> -d example1.com <-d example2.com>
```

- 下記サイトにFQDN入力してチェックすることも可能ですが、接続多くて多分レスポンス帰ってこない気がする...

https://checkhost.unboundtest.com/


- プライベートで使用しているものも全部調べましたが、失効対象にはリストされてませんでした...!よかった...
Gsuiteを個人で導入してみた。

今回で２本目の投稿です。

さて、我が家はごくごく一般的な誤家庭です。
なのでGsuiteを個人で導入しています。
(個人事業主ではありません。Googleに個人です。と伝えると、電話で必ず聞き返されますw)


#導入の目的
今回導入にあたり決め手となったのは下記の通りです。

Gmailのプラットフォームで独自ドメインを利用してみたかった。(無料でできますが、広告がウザい)
Googleグループので独自ドメインのMLが作れる（案外便利！）
Google siteで独自ドメインが利用できるようにしてみたかった。(１００件まで？だったと思います。)
Googleドライブが30GBになるのが魅力的だった。(法人向けなので安全。)
windowsのオフィス2010がサポート切れになるので各種オフィスの代わりに最適だった。
クラウドベースになることで、リアルタイムにほしい情報がどこででも、手に入るようになった。
SLAがあるので、安心して利用できる。
Googleにお布施して見たかった。(ここ90%ぐらい。)

#効果
Gsuiteは法人向けなので無料版と違い広告が邪魔とか、感じる事が少なくなりました。
また個人的なサーバでも安定してるのでちょこちょこサーバをいじる私には安全なメールが使えるようになりました。
どうせ毎日見るメールですし、月額680円ぐらい、いいや！と思って契約してみたら色々便利で今は生活に必要不可欠な存在になりました。Google GroupのMLも家族・友人間で情報共有に使うなど以外と活躍しています。

Google ONEなどもありますが、独自ドメインが気に入ってるので・・・
Gsuite個人版(値段だけ個人価格)があればいいのになぁ・・・
EC2上でhubotをslackとchatworkの両方で動かす

まずはhubotを動かすために必要なものをインストール

```
$ sudo curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash
```
実行時の出力に環境変数の設定処理とnvmのロード処理行うコマンドが出力されるので、これを.bash_profileに追記
追記後に読み込み


```
$ vi .bash_profile

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm

$ source .bash_profile
```

nvm(node version manager)のインストールと、npm(node package manager)から必要なパッケージをインストール

```
$ nvm install 9.4.0
$ npm install -g hubot coffee-script yo generator-hubot
```

hubot用ディレクトリを作成し初回起動
起動時に色々聞かれますが例が出るのでその通りに設定していきます

```
$ mkdir hubot
$ cd hubot
$ yo hubot --adapter slack

? Owner hogehoge
? Bot name hogehoge
? Description A simple helpful robot for your Company
```

slackとchatwork用のパッケージ、永続化のためのforeverパッケージをインストール

```
$ npm install hubot-slack hubot-chatwork
$ npm install -g forever
```

起動スクリプトを作成して実行

``` start_slack.sh
#!/bin/bash
 
export HUBOT_SLACK_TOKEN="hogehoge"
export PORT="8091"

forever -w start -c coffee node_modules/.bin/hubot --adapter slack
```

``` start_chatwork.sh
#!/bin/bash

export HUBOT_CHATWORK_TOKEN="hogehoge"
export HUBOT_CHATWORK_ROOMS="123456789"
export HUBOT_CHATWORK_API_RATE="500"
export PORT="8092"
 
forever -w start -c coffee node_modules/.bin/hubot --adapter chatwork
```

起動後こうなればOK

```
$ forever list
info:    Forever processes running
data:        uid  command script                                     forever pid  id logfile                          uptime      
data:    [0] ysEB coffee  node_modules/.bin/hubot --adapter slack    4075    4085    /home/ec2-user/.forever/ysEB.log 0:0:0:5.739 
data:    [1] sEKt coffee  node_modules/.bin/hubot --adapter chatwork 4108    4118    /home/ec2-user/.forever/sEKt.log 0:0:0:3.077 
```

# エラー例1
chatworkとslackを同時に動かす場合、ポートを別にしないと競合して後に起動した方が↓のようなエラーを吐いて落ちるので起動時に指定する

``` エラー
ERROR Error: listen EADDRINUSE 0.0.0
.0:8080
```

※プロセスを確認し、いくつも動いてしまっているようならキルする

```
$ ps aux | grep node
$ killall node
```

# エラー例2
↓のようなエラーが出る場合は監視対象が多すぎる？

```
events.js:137
      throw er; // Unhandled 'error' event
      ^
Error: watch /home/hogehoge/hubot/node_modules/@slack/client/lib/data-store/message-handlers/bots.js ENOSPC
```

下記コマンドを実行した後に立ち上げ直したら出なくなった
参考 : https://qiita.com/mmmpa/items/12859d2c9ea5afc11751

```
$ echo fs.inotify.max_user_watches=582222 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
```
php artisan migrateで外部キー追加ができない

#問題
- commentsテーブルとpostsテーブルの2つを作ろうとしたがうまく行かない。

```
php artisan migrate


Migrating: 2020_03_05_085907_create_comments_table

   Illuminate\Database\QueryException 

  SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (SQL: alter table `comments` add constraint `comments_post_id_foreign` foreign key (`post_id`) references `posts` (`id`))
```


#原因
- migrationsテーブルの中にmigrate実行履歴が入っていた。
- php artisan migrateをすると、migrationsテーブルの中に実行履歴が残るようだ。
- 別の原因でphp artisan migrate:rollbackを使わずに、drop tableしたせい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/94326d66-207c-91bf-1457-680b3ad05fe8.png)


#解決
- drop tableのときに、delete from migrationsで関連する履歴を消しておく。
- あるいはちゃんとphp artisan migrate:rollbackをつかいましょう。
Rails + React + AjaxでCRUDのサンプルプロジェクト [Hello World]

React初心者が<a href="https://ja.reactjs.org/docs/hello-world.html">公式サイト</a>で基礎を学んだ後に作るReact + AjaxによるCRUD(作成/読み込み/更新/削除)のサンプルプロジェクトです。
![react_crud_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597258/58bb3725-2d2d-0a6c-df9e-57745bd37b48.png)
Twitterのように「つぶやき」を投稿可能で編集/削除もできます。

動作確認はChrome、FireFox、Microsoft Edge、IE11です。恐らくマックさんのブラウザでも動作するはずです。

## DEMO
<a href="https://www.petitmonte.com/rails-demo/react_crud">https://www.petitmonte.com/rails-demo/react_crud</a>

## ソース一式
<a href="https://github.com/TakeshiOkamoto/mpp_react_crud">https://github.com/TakeshiOkamoto/mpp_react_crud</a>

※学習用の為、ライセンスはパブリックドメイン
  
## 関連記事
<a href="https://qiita.com/petitmonte/items/e89a7c7df8cf1c5f3c24">Rails + React + AjaxでCRUDのサンプルプロジェクト [Hello World]</a>
<a href="https://qiita.com/petitmonte/items/0857ac8baf0d56187b7c">Rails + Vue.js + AjaxでCRUDのサンプルプロジェクト [Hello World]</a>
<a href="https://qiita.com/petitmonte/items/c8820525c832bb2e4664">Rails + jQuery + AjaxでCRUDのサンプルプロジェクト [Hello World]</a>
<a href="https://www.petitmonte.com/javascript/framework_comparison.html">React・Vue.js・JQueryで同じSPAを作成して比較してみた</a>
obsのストリーミングをとりあえず動作確認

nginxじゃなくてGoのプログラムに向かってobsでストリーミングをしたかったので，Goのrtmpサーバーを探しました。

https://github.com/netroby/go-rtmp-server

かなりわかりやすく動作確認することができました！

# 動機
iOSアプリからRTMPでデータをストリームしたかったので，ちゃんと動くRTMPサーバーを手に入れてわかりやすく動作を確認しようと思ったのがきっかけでした。

# OBSを入れる
https://obsproject.com/ja/download
僕はMacでやっているので，MacにOBSを入れます。

# GoのRTMPサーバーを導入する
```
go get -u -v github.com/netroby/go-rtmp-server
```
これでサーバーを導入します。
`go get`がちゃんと動作してくれないときは，Go自体の環境をつくればいいと思います。

# サーバーを起動する
```
~/go/bin/go-rtmp-server  -l :8089 -k  longSecurityKey
```

`README`に書いてある通り，これでサーバーを起動することができます。
`longSecurityKey`の部分は`ストリームキー`と呼ばれる，ストリーミングにおけるパスワードのようなものらしいので，自分の好きな文字列でもいいと思います。


# OBSから配信する
OBSの`設定`のところから`配信`を選択し，`サービス`で`カスタム`を選択してから，
サーバーのところに`rtmp://127.0.0.1/live?key=longSecurityKey`と入れます。（今回はローカルで動かします。）
そして設定を終え，入力ソースをちゃんと選択してから配信開始をします。

# 配信を確認する
`http://127.0.0.1:8089/`にブラウザからアクセスすると，obsからのストリームが受け取れていると思います！

## おわり
とりあえずこれでちゃんと動くであろうストリーミングのツールたちを手に入れることができたので，楽しく開発をすすめて行こうと思います。
Cognosのカスタム認証を使用してSSOを実装する際、HTTP_IV_USERを使用できるようにする手順


#はじめに
Cognosの認証にISAM(TAM)を使用する場合、HTTPヘッダーに埋め込まれるユーザー情報はIV_USERになります。
さらに、IHSでcgiモジュールを使用している場合は、IV_USERがHTTP_IV_USERに変換された状態でCognosにリクエストが転送されます。

Cognosが提供するサンプルのカスタムJava認証を使用した環境で、HTTP_IV_USERを使用してSSOを構成するために必要なjavaファイルの変更箇所をまとめてみました。

※現時点ではCA 11.0.13に対して机上検証のみ実施しており、実際の動作は検証できていない状態です。参考にする場合は十分に検証してください。

#修正手順
ますは修正対象のファイルを特定し、javaを修正します。その後、jarファイルをビルドしCognosに配置します。
##修正ファイルの特定
まずは、sdkのサンプルとして提供されているJDBCSample配下で”REMOTE_USER"が使用されているファイルを検索します。下記のようにコマンドを実行することで、「DBCSample.java」と「RestorableJDBCSample.java」の中で使用されていることが確認できます。

```console
[root@ JDBCSample]# pwd
/opt/ibm/cognos/sdk/sdk/java/AuthenticationProvider/JDBCSample
[root@ JDBCSample]#
[root@ JDBCSample]# grep REMOTE_USER -rl .
./JDBCSample.java
./RestorableJDBCSample.java
[root@ JDBCSample]#
```

##JDBCSample.java
このファイルでREMOTE_USERが使用されているのは2行3か所あるので、それを修正します。


```java:変更前
userNames = authRequest.getTrustedEnvVarValue("REMOTE_USER");
(中略)
SystemRecoverableException e = new SystemRecoverableException("Challenge for REMOTE_USER", "REMOTE_USER");
```

```java:変更後
userNames = authRequest.getTrustedEnvVarValue("HTTP_IV_USER");
(中略)
SystemRecoverableException e = new SystemRecoverableException("Challenge for HTTP_IV_USER", "HTTP_IV_USER");
```

##RestorableJDBCSample.java
このファイルでREMOTE_USERが使用されているのは1行2か所あるので、それを修正します。

```java:変更前
SystemRecoverableException e = new SystemRecoverableException("Challenge for REMOTE_USER", "REMOTE_USER");
```

```java:変更後
SystemRecoverableException e = new SystemRecoverableException("Challenge for HTTP_IV_USER", "HTTP_IV_USER");
```


##ビルドの実行
ファイルの修正が完了したら、ビルドを実施しearファイルを作成します。

ここからの手順は、下記リンク先にあるとおりです。
https://qiita.com/shinyama/items/5231260ab707b2231139


認証のセットアップが完了したら、ISAM(TAM)からのSSO連携が可能か試してみます。
認証環境が無い場合は、FireFoxのmodify headerなどを使用することで検証できるはずです。
さくらのクラウド超入門チュートリアル・目次



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/58e16f45-57f5-522b-bf4f-cbca9abfe243.png)

これから「さくらのクラウド」を使い始める人が、最短で理解し、便利な機能を使いこなせるようになるのを目指すチュートリアルです。内容が分かりづらかったり、間違いがありましたら、お気軽にコメントや編集リクエストをお寄せください。

# はじめてご利用の方へ

- [新規アカウント開設編](https://qiita.com/zembutsu/items/1d8cc60b09ac2aa003ed)

# クラウド基礎の基礎

- [コントロールパネルへのログイン- さくらのクラウド超入門(1)](https://qiita.com/zembutsu/items/eb91a8befb473ead0232
)
- [コントロールパネル「ホーム」画面の見方 - さくらのクラウド超入門(2)](https://qiita.com/zembutsu/items/8d1ffa2b430212331103)

# サーバ編

- [サーバの作成と起動 - サーバ編(1)](https://qiita.com/zembutsu/items/fe4686cde8a0cd50f2b0)
- [TCP Wrapper で SSH のアクセス制限 - サーバ編(2)](https://qiita.com/zembutsu/items/c432a3e096729e181df9)
- [DockerのインストールとWordPressの起動 - サーバ編(3)](https://qiita.com/zembutsu/items/b345b9b820ad82e9b3d1)
- [サーバのスペック（処理能力）変更方法 - サーバ編(4)](https://qiita.com/zembutsu/items/faaf87dd1f68a5f9547c)
- [「クローン」機能でサーバを増やす方法 - サーバ編(5)](https://qiita.com/zembutsu/items/62bc90822d6e26f5e746)
- [「アーカイブ」をVMイメージのテンプレートとして使う方法 - サーバ編(6)](https://qiita.com/zembutsu/items/a3344a391d10762adb5a)


以下続く予定


# VPCルータ編

- [VPCルータでインターネット上に安全なサーバ環境を作る(1) - VPCルータ編](https://qiita.com/zembutsu/items/4d8986c88d38730c2c9e)
- [VPCルータでインターネット上に安全なサーバ環境を作る(2) - VPCルータ編](https://qiita.com/zembutsu/items/f55289f65d3514e38c83)
- [リモートアクセス(VPN)用アカウントを作成して接続する - VPCルータ編(3)](https://qiita.com/zembutsu/items/05513e59918dd2b7f146)

以下続く予定

# DNS （アプライアンス）編

- [ドメイン名（ゾーン情報）を登録するには - DNS アプライアンス編(1)](https://qiita.com/zembutsu/items/a131d62ceb323b7b18c1)
- [ホスト名（DNS レコード）をサーバに割り当てるには - DNS アプライアンス編(2)](https://qiita.com/zembutsu/items/6be7b857219a5ba929df)



# GSLB 編

- [www のアクセス先を振り分ける設定 - GSLB編 (1)](https://qiita.com/zembutsu/items/75a27046d9cf734af7b3)
- [サイトが応答できない時、自動的に別サイト（ソーリーサーバ）に誘導 - GSLB編(2)](https://qiita.com/zembutsu/items/5b6b132f62abb093c90d)


# ウェブアクセラレータ編

- [画像をキャッシュする Docker チュートリアル - ウェブアクセラレータ編(1)](https://qiita.com/zembutsu/items/3e9d99728a0410d9c13e)



# 知っておくと便利な Tips（便利技）

- [コンテナレジストリ(Lab)でDockerイメージを保存・配布する方法](https://qiita.com/zembutsu/items/4c5e58918249c1eae8c8)
- [さくらのクラウド「アーカイブ共有機能」で仮想マシンイメージを別ゾーンにコピー](https://qiita.com/zembutsu/items/4d57da10ae219807889f)



# 参考情報

- [さくらのクラウド公式ドキュメント](https://manual.sakura.ad.jp)
- [さくらのクラウドチュートリアル（公式）](https://manual.sakura.ad.jp/cloud/tutorial/index.html)
基本的なデータ構造まとめ

##データ構造とは？
データ構造は、データをコンピュータの中で扱う際にデータを格納する一定の形式のこと。

##代表的なデータ構造
Bag、Sequence、Tree、Mapの4つの構造がある。

###Bag
データを格納した順序付けはなく、重複したデータを格納することができる。
Bagの中で重複を許さないものをSetという。

- Bagは重複データを扱える
    - 延べ人数を記録するようなデータにむいている。
- Setは重複を除ける
    - ユニークな人数を記録するようなデータに向いている。

###Sequence
データが順に並んでいるような構造をSequenceという。
データの格納順をインデックスとして記録できるため、特定の要素を指定して参照したり、取り出したりといった操作が可能。
Sequenceの実装方法として、主に配列とリストがある。

####配列　Array
同じ型のデータをインデックスをもとに格納していく。
この時、型とは数値や文字列といった個々のデータに対する型のこと。

要素数をあらかじめ決めてからデータを格納するため、領域の拡張ができない。
データを確保するには、予め余分に領域を確保するか、より大きい配列を新しく作成し、現在の内容をコピーして移す必要がある。
データにアクセスする際の計算量は、インデックスをもとに直接指定の要素アクセスができるので、__O(1)__、データ探索はインデックスをたどる必要があるので、__O(n)__。


####リスト　List
リストは各要素に次の要素のリンクを保持させる。チェーンみたいな構造。
最後の要素はリンクを持たせないことで表現する。
2種類ある

- 単方向リスト
    - 一定の順序でしかアクセスできないもの
- 双方向リスト
    - 前後のリストを保持しているもの

リストはあらかじめ要素数を決めておく必要がなく、データの増減に合わせて調整することができるので、データを記録するためのメモリ効率が良いというメリットがある。
しかしデータを取り出す際には、最初の要素から順にリンクを辿って行かなければならないため、計算量は__O(n)__と要素数に合わせて増えてしまう。
追加する際は直接挿入したい場所に追加できるので、計算量は__O(1)__。

###Tree
木構造。階層関係を表すことができる。PC内のfolderもこの構造。概念の上下関係（親子関係）があるような関係を階層関係という。
木構造では、ひとつひとつの要素をノードという。親に当たるノードを持たないノードをルートといい、子に当たるノードを持たないノードをリーフという。
それぞれのノードをつなぐ枝はエッジという。

####二分探索木
木構造にも様々な種類があるが、二分探索木を例に考える。
ルートノードの任意の値に対して、左のノードはルートノードよりも小さく、右のノードはルートノードよりも大きいという関係が成り立つように値を入れていく。これを下の階層のノードでも繰り返します。
データを取り出す際には必ずルートから順にノードを探索する必要がある。
計算量は木構造の階層の数に比例し、__O(log n)__となる。
ただし、木構造の一方にノードが集中して偏った構造になる場合__O(log n)__よりも遅い__O(n)__に近づいて遅くなる傾向がある。


###Map
Mapの最大の特徴はひとつの要素内に、データの場所表す「キー」と、データの「バリュー」を対応づけて格納すること。
データの保管場所をキーとすることで、SequenceでもTreeでも実装することができる。
####ハッシュ　Hash
キーとの結びつけをハッシュ関数という計算式によって行います。
まず格納するデータからハッシュ関数を用いて、ハッシュ値という値を得ます。その値をキーとしてでデータを格納する場所を決めます。

しかし、別々のデータから計算したハッシュ値が等しくなることがある。これを__衝突__という。

#####衝突の解決策
- クローズドハッシュ法
    - ハッシュ値を求め直して格納場所を移動させる方法
- オープンハッシュ法
    - 同じ要素の中でリスト構造を作りデータを追加していく方法


その際に、ハッシュ値を求め直して格納場所を移動させることをクローズドハッシュ法という。
また、同じ要素の中でリスト構造を作りデータを追加していく方法

##まとめ
計算量を少なくするには、コードのアルゴリズムだけでなく、データ構造との関係性が重要になってくる。




###参考
開発新卒に捧ぐ、データ構造の基本と特徴 | TECHSCORE BLOG
https://www.techscore.com/blog/2016/10/05/%E9%96%8B%E7%99%BA%E6%96%B0%E5%8D%92%E3%81%AB%E6%8D%A7%E3%81%90%E3%80%81%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%A8%E7%89%B9%E5%BE%B4/
あるGameObjectのワールド座標を指定したものと一致させる


こちらを参考にしました。

UnityのTransformのワールド空間とローカル空間について
参考URL：https://gametukurikata.com/basic/worldlocal


スクロール内のセル内の区切り線と
スクロールの上にあるヘッダーの区切り線を合わせたいので、
スクロール内のセルの区切り線の絶対座標を取得して、
ヘッダーの区切り線に入れたところ一致した。
(Vertical Layout Group で Child Force Expand しているので、
　都度１セル当たりの横幅が変化するため、このような事を行っている。
　高速スクロールを実現するためにEnabledはTrueにしてからFalseに必ず戻す)



名前　｜　数　｜　値段
あ　　｜　１　｜　１００　　← 解像度対応で縦棒がVertical Layout GroupのEnabledをTrueにするたびに変化
い　　｜　２　｜　２００　　← 解像度対応で縦棒がVertical Layout GroupのEnabledをTrueにするたびに変化



```
        /// <summary>
        /// スクロールする１セル最初の区切り棒のワールド座標
        /// </summary>
        [SerializeField]
        private Transform CellFirstColumnWorldPosition;

        /// <summary>
        /// スクロールする１セル２つ目の区切り棒のワールド座標
        /// </summary>
        [SerializeField]
        private Transform CellSecondColumnWorldPosition;

        /// <summary>
        /// スクロールヘッダー最初の区切り棒のワールド座標
        /// </summary>
        [SerializeField]
        private Transform HeaderFirstColumnWorldPosition;

        /// <summary>
        /// スクロールヘッダー２つ目の区切り棒のワールド座標
        /// </summary>
        [SerializeField]
        private Transform HeaderSecondColumnWorldPosition;

```

```
// １つ目のヘッダーのX座標
HeaderFirstColumnWorldPosition.position = 
    new Vector3(CellFirstColumnWorldPosition.position.x, 
                HeaderFirstColumnWorldPosition.position.y, 
                HeaderFirstColumnWorldPosition.position.z);

// ２つ目のヘッダーのX座標
HeaderSecondColumnWorldPosition.position = 
    new Vector3(CellSecondColumnWorldPosition.position.x, 
                HeaderSecondColumnWorldPosition.position.y, 
                HeaderSecondColumnWorldPosition.position.z);

```
アンドロイドアプリでスマートニュース風のタブを実装する

これだけでした。

```
tabs.setTabMode(TabLayout.MODE_SCROLLABLE);
```


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">スマートニュース風タブメニュー <a href="https://t.co/8qfpI1qFLY">pic.twitter.com/8qfpI1qFLY</a></p>&mdash; Tetsuji Okuno (@tetsujiokuno) <a href="https://twitter.com/tetsujiokuno/status/1235421358105841664?ref_src=twsrc%5Etfw">March 5, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>