OmniAICreator/Qiita-1.07M huggingface dataset:
【Vue.js】データが変化したときのcomputed / watch

今回は、算出プロパティと、監視プロパティについて、何が違うのかまとめてみたいと思います。

# computedとwatchの違い

いずれも、コンポーネントのデータの中身に変化があった時に発動するものだが、**その動作に違いがある**

| プロパティ | データに変化があった時 |
|:-:|:-:|:-:|
| computed  | データの中身を変化させたものを表現できる | 
| watch  | データの中身を変える以外の何らかの処理を発動する  | 


# 算出プロパティ　computed

```javascript:
let vm = new Vue({
  el: '#app',

  data: {
    newItem: '',
    todos: [
      { title: 'task1', isDone: false },
      { title: 'task2', isDone: false },
      { title: 'task3', isDone: false },
    ]
  },

  computed: {
    remaining: function(){
      let remainItems = this.todos.filter(function(todo){
        return !todo.isDone;
      });
      return remainItems.length;
    }
  }
})
<span>{{ remaining }}/{{ todos.length }}</span>

```

1. todosの中でも、isDoneがfalseの要素のみを抽出する（remainItems）
2. 抽出したremainItemsの数を格納する（remaining）
3. 残ったタスク / タスクの総数としてブラウザに表示させる



#監視プロパティ　watchキー

```javascript:
let vm = new Vue({
  el: '#app',

  data: {
    newItem: '',
    todos: [
      { title: 'task1', isDone: false },
      { title: 'task2', isDone: false },
      { title: 'task3', isDone: false },
    ]
  },

  watch: {
    todos: {
      handler: function(){
        localStorage.setItem('todos', JSON.stringify(this.todos));
      },
      deep: true
    }
  }
})
```

1. 今回の監視データは、todosを指定している。
2. handler内で、変化があった時の処理を行う（ローカルストレージにJSON形式でtodosに、変化後のtodosを保存(setItem)している。）
3. deepオプションで、データの中身の部分まで監視することができる。


##deep watcherの監視範囲

|  | deep: true | deep: false |
|:-:|:-:|:-:|
|  配列要素の変更 | 監視できる  |  監視できる |
|  配列要素となるオブジェクトの中身の変更 |  監視できる | 監視できない  |
AWSクラウドプラクティショナー 直前対策

#【AWSクラウドプラクティショナー 直前対策】

10/24に試験を受けます。
自分の直前対策用です。

##Amazon CloudWatch Logs⇔AWS CloudTrail

###・Amazon CloudWatch Logs

AmazonEC2インタンス、AWS CloudTrail、Route 53、およびその他のソースのログファイルを監視、保存、アクセスできる。

###・AWS CloudTrail

AWSアカウントのガバナンス、コンプライアンス、運用監査、リスク監査を行うためのサービス
AWSインフラストラクチャ全体でアカウントアクティビテイをログに記録し、継続的に監視し、保持できる。
→取得するログはユーザーアクティビティに関するものである。EC2インスタンスのログを取得することはできない。

##EBS⇔インスタンストア

###・EBS

EC2インスタンスにアタッチ。
AZ内に自動レプリケート。
スナップショットは、S3に保存される。

###・インスタンストア

ホストのローカルストレージ。
インスタンス状態に依存するため、一時的。

##DynamoDB⇔RDS

###・DynamoDB

水平スケーリング（スケールアウト、スケールイン）
リージョン選択、AZ気にしない。
RDSより管理範囲が狭い。

###・RDS

垂直スケーリング（スケールアップ、スケールダウン）

##セキュリティグループ⇔ネットワークACL

###・セキュリティグループ

ステートフル。
インスタンス単位。
EC2インスタンスとの通信を行う時のトラフィックを制御する仮想ファイアウォール

###・ネットワークACL

ステートレス。
サブネット単位。
サブネットに対しての仮想ファイアウォール

##Sから始まるややこしい４種

###・Amazon SNS　（Simple Notification Service）

マイクロサービス、分散型システム、およびサーバーレスアプリケーションの分離を可能にする、
高可用性で耐久性に優れたセキュアな完全マネージド型 pub/sub メッセージングサービスである。
プッシュ方式でコンポーネント間のメッセージングを処理することができる。

###・Amazon SES　（Simple Email Service）

デジタルマーケティング担当者やアプリケーション開発者がマーケティング、通知、トランザクションに関するEメールを送信できるように設計されたクラウドベースのEメール送信サービス。

###・Amazon SQS　（Simple Queue Service）

完全マネージド型のメッセージキューイングサービス
マイクロサービス、分散システム、およびサーバーレスアプリケーションの切り離しとスケーリングが可能
プッシュ方式ではなくポーリング処理による通知を実施

###・AWS SMS　（Server Migration Service）

オンプレミスの VMwarevSphere, Microsoft Hyper-V/SCVMMなどのAWSクラウドへの移行を自動化

##AWSで提供されているデータベースサービス

RDS、Redshift、ElastiCache Redisには自動バックアップ(自動スナップショット)の機能がある。
基本的にはバックアップ運用をAWSに任せられる。
バックアップサイクル等の設定についてはサービス毎に差異がある。

Amazon Auroraの DBインスタンスでは常に自動バックアップが有効。
バックアップはデータベースのパフォーマンスに影響を与えない。

##RDS　

S3にDBインスタンスの自動バックアップは取得され、指定した期間保存される。
スナップショットも可。保存データやスナップショット、インスタンスを暗号化することができる。
オブジェクトは利用していない。
利用途中でインスタンスタイプを縮小することも可能。

リードレプリカによって、データの冗長性を実現し、コスト最適に災害復旧対応を実現させる。（データ）
マルチAZ構成によって、プライマリデータベースが応答しない場合に自動フェールオーバーを実行する。（システム）

AutoScalingによるキャパシティを自動向上させることはできない。
データ容量に限っては、スケーリングが可能。

##Route 53

アプリケーションとWebサーバーおよびその他のリソースのヘルスとパフォーマンスを監視するヘルスチェックを提供
ヘルスチェックに基づいて、Route 53は正常なエンドポイントのみにトラフィックをルーティングして、アプリケーションのフォールトトレランスのレベルを高める。

##EFS

EC2インスタンスからLAN上にあるNASとして利用できる共有ファイルストレージ
複数のEC2インスタンスから接続・共有可能なストレージとして機能する。
インターネットからアクセスができない。（S3は、インターネットからアクセス可能。直リージョン）
完全な内部サーバー向けのストレージとしてセキュリティを強化することができる。

##初めからマルチAZ構成のフォールトトレランス考慮

DynamoDB、S3
DateAndTime APIを用いた日時取得方法

### 概要
Date and Time APIで以下のパターンをJavaとKotlin(ほぼ同じ)で実装する。

- 日時の変更
- 独自フォーマット
- ISOフォーマット
- 月初日時
- 月末日時

### 実装例

JavaのUtilsクラスだとこちら。

```java:LocalDateUtils.java
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;

public class LocalDateTimeUtils {
    private static final DateTimeFormatter YYYYMM_FORMAT = DateTimeFormatter.ofPattern("yyyyMM");

    // 日時の変更
    public static LocalDateTime getDateTimeAfterOneYear(LocalDateTime dateTime) {
        return dateTime.plusYears(1);
    }

    // 独自フォーマット
    public static String getYearAndMonth(LocalDateTime dateTime) {
        return dateTime.format(YYYYMM_FORMAT);
    }

    // ISOフォーマット 例)2011-12-03
    public static String getIsoLocalDate(LocalDateTime dateTime) {
        return dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE);
    }

    // 月初日時
    public static LocalDateTime getFirstDayDateTime(LocalDateTime dateTime) {
        return LocalDateTime.of(dateTime.with(TemporalAdjusters.firstDayOfMonth()).toLocalDate(), LocalTime.MIN);
    }

    // 月末日時
    public static LocalDateTime getLastDayDateTime(LocalDateTime dateTime) {
        return LocalDateTime.of(dateTime.with(TemporalAdjusters.lastDayOfMonth()).toLocalDate(), LocalTime.MAX);
    }
}
```

Kotlinの拡張クラスだとこちら。

```kotlin:LocalDateTime.kt
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.format.DateTimeFormatter
import java.time.temporal.TemporalAdjusters

private val YYYYMM_FORMAT = DateTimeFormatter.ofPattern("yyyyMM")

// 日時の変更
fun LocalDateTime.getDateTimeAfterOneYear(): LocalDateTime = plusYears(1)

// 独自フォーマット
fun LocalDateTime.getYearAndMonth(): String = format(YYYYMM_FORMAT)

// ISOフォーマット 例)2011-12-03
fun LocalDateTime.getIsoLocalDate(): String = format(DateTimeFormatter.ISO_LOCAL_DATE)

// 月初日時
fun LocalDateTime.getFirstDayDateTime(): LocalDateTime = LocalDateTime.of(with(TemporalAdjusters.firstDayOfMonth()).toLocalDate(), LocalTime.MIN)

// 月末日時
fun LocalDateTime.getLastDayDateTime(): LocalDateTime =  LocalDateTime.of(with(TemporalAdjusters.lastDayOfMonth()).toLocalDate(), LocalTime.MAX)
```
pythonでシーザー暗号を作成、復号する

```python
# substitute PLAIN the letter
PLAIN = "EBG KVVV vf n fvzcyr yrggre fhofgvghgvba pvcure gung ercynprf n yrggre jvgu gur yrggre KVVV yrggref nsgre vg va gur nycunorg. EBG KVVV vf na rknzcyr bs gur Pnrfne pvcure, qrirybcrq va napvrag Ebzr. Synt vf SYNTFjmtkOWFNZdjkkNH. Vafreg na haqrefpber vzzrqvngryl nsgre SYNT."

for i in range(26):
    KEY = i
    enc = ""

    for char in list(PLAIN):
        ASCII = ord(char)
        if (ASCII == 32):                   # if ASCII is SPC, make space.
            enc += " "
            continue
        if (122 >= ASCII and ASCII >= 97):  # if ASCII is lower
            num = ASCII - 97
            num = (num + KEY) % 26
            ASCII = num + 97
            enc += chr(ASCII)
        elif (90 >= ASCII and ASCII >= 65): # if ASCII is upper
            num = ASCII - 65
            num = (num + KEY) % 26
            ASCII = num + 65
            enc += chr(ASCII)
        else :                              # if ASCII is symbol
            enc += chr(ASCII)

    print(f"--------- Shifted {i} character ---------")
    print(enc)
    print("")
```

使いたい方はこのコードをコピーし、適当な名前を付けて保存してください。拡張子を「.py」にするのをお忘れなく（例、test.py）

そのあと、コードの一番上にあるPLAIN変数の中身を暗号にしたい文字や解読したい文字にしてください。（例、PLAIN = "hogehoge"）

その状態で保存し、実行しします。

```
# python test.py
```

そうすると、１～２５文字ずらした文字列を表示されます。（アルファベットは全部で２６文字です。）
DynamoDBでのデータ検索で、日付を条件にして検索

#やっぱり厄介なDynamoニキ
●Dynamoには、日付型•時刻型が無い。
なので、UNIX時間か日時のフォーマットで文字列として持つかして登録してあるのが前提条件とします。(自分はUTCで登録)

●また、Dynamoはscan以外でデータを取得する場合、ハッシュ値を必ず指定しなくてはならない。
その対策については最近記事として書いたのでよかったら見てみてくださいなんでもしますから(なんでもするとは言ってない)
https://qiita.com/A-Kouki/items/ab34c27856d203cdfff0


## TypeScriptでデータを取得するコード
以下のコードは、グローバルセカンダリインデックスを利用したテーブル定義をしていることが前提となります。

以下の作ってみたfunctionでは、インデックス、カラム名(Dynamo的には属性と呼ぶ)、比べる対象の日付オブジェクトを引数で指定する。

ここで重要なのが、**DateオブジェクトをUTCの文字列で指定したい場合は、toJSON()をする。**

変数名はてきとーなので許してクレメンス

```typescript:anime-suko.ts
const getReceptionNoFromDateTime = async (
  index_name: string,
  column_name: string,
  target_datetime: Date
) => {
  const params = {
    TableName:’hogeTable’,
    IndexName: index_name,
    ExpressionAttributeNames: {
      '#sc': column_name,
      '#gi': 'gsiVal',
    },
    ExpressionAttributeValues: {
      ':target_datetime': target_datetime.toJSON(),
      ':gsi_value': '1',
    },
    KeyConditionExpression: '#gi = :gsi_value and #sc <= :target_datetime',
  }
  const record = await documentClient.query(params).promise()
  const hogeDataList = record.Items
  const targetNameList = hogeDataList.map(
    (value) => value.name
  )
  return targetNameList
}


```

## 日付で期間を条件にする場合
プログラムの条件式みたいに、start_time >= 比較する日時　and 比較する日時　<= end_date
みたいに出来そうだと思ったらエラー出て出来ない。
これもDynamoの決まりでこんな感じでandでの指定出来ない。その代わりとして用意されてるのが「BETWEEN」である。

以下のように書けばいける。

```
#{カラム名} Between :{日付1} and :{日付2}
```

## まとめ
Dynamoのメリットってなんなん？(ググったら負け)
アップデート処理のときに存在しないカラム(属性)を指定したら、エラー出ずに勝手にカラム作成されてデータ追加される始末。悪い意味で便利すぎてめっちゃ不便(語彙力)
Webサービスの設計思想について




##アーキテクチャとは
アーキテクチャとは、Webサービスや設計を形作る構造のこと。
Webで例えると、ブラウザやHTML・CSSなどで構成されている為、これらがWebのアーキテクチャと言うことになるそうです。
構造と言われると分かりづらいかもですが、部品とか元になってるものってニュアンスに近いんじゃないかと思います。



Webサービスは独自の考えで作っていくのではなく、設計指針を決めて実装していく。

その指針のことを、アーキテクチャスタイルと言う。

名前が似ていてややこしいですが、違いは

「構造」と「設計指針」と言う点で異なります。
アーキテクチャは、アーキテクチャスタイルの設計指針に基づいて、組み合わせていくものです。

家で例えると

アーキテクチャスタイルは、どのような家にするのか方針を定めるもので

アーキテクチャは、方針に基づいた、トイレ・キッチン・玄関・リビングなど家の構成一つ一つを指します。



##REST
(Representational State Transfer)の略。
Webのアーキテクチャスタイルの一つです。

RESTは、クライアント/サーバーから派生したもので、これにいくつかの構成を加えることでRESTというアーキテクチャスタイルが成立します。


####リソース
RESTに関連する言葉で、Web上で名前を持ったあらゆる情報のこと。
無数のリソースは、URLで場所を特定しURLを使うことでリソースの閲覧などができる。

RESTは、クライアントとサーバーの間で実際にリソースをやりとりする時、クライアントからURLにHTTPメソッドを加えた情報でリクエストします。


RESTは6つの中身がある！


###ステートレスサーバー
クライアントの状態を保持しないサーバーのこと。
ステートレスは、状態がないということを意味しています。

サーバー側で状態を管理しない為、クライアントはリクエストごとに全ての情報を送信します。


メリットとしては、サーバ側の実装が簡単になること！


###キャッシュ
一度得たリソースをクライアント側で保存しそれを使い回す仕組みのこと。

メリットは、クライアントとサーバ間の通信を減らすことで処理時間の短縮と効率化に繋がります。

デメリットは、古いキャッシュを利用することで情報の信頼どが下がることがある点。


###統一インターフェース
使用するメソッドを固定すること。
RESTの中で最も特徴的なアーキテクチャスタイルです。
例えば、HTTPメソッドでは、URLで指し示したリソースをGETやPOSTなど限定することで、全体がシンプルになります。



###階層化システム
名前の通り、システムを階層に分けることです。
これは統一インターフェースにより受けられる恩恵になります。
クライアントとサーバ間に階層を分割するものを設け、負担を分散したりします。



###コードオンデマンド
プログラムをクライアント側で実行することです。
javascriptがこれに当たります。

メリットはクライアントは後から新しい機能を追加していけます。
デメリットはクライアント側での実行が増えるので、サーバとやり取りされるリソースの内容が明確ではなくなくなります。



全部適用しなくてもいくつか除外しても問題はないみたいです。
指針を決めつつも臨機応変に対応しユーザーに価値を提供できるサービスを作ることが重要になります。

##終わりに
その他にもあるそうですが、今日はこのへんで。
言語以外の学習も大切なことなので少しずつでも学んで行きます。
Gatsby.jsのサイトにNetlifyのformsを導入する

シンプルなお問い合わせフォームをGatsby.jsの静的サイトに導入してみました。

```html
<form
  name="contact"
  method="post"
  data-netlify-honeypot="bot-field"
  data-netlify="true"
  autocomplete="off"
  action="/thanks"
>
  <input type="hidden" name="form-name" value="contact" />
  <p hidden>
    <label>
      Don’t fill this out if you're human:
      <input name="bot-field" />
    </label>
  </p>
  <div>
    <label>名前</label>
    <input id="name" type="text" name="name" />
  </div>
  <div>
    <label>メール</label>
    <input id="email" type="email" name="email" />
  </div>
  <div>
    <label>メッセージ</label>
    <textarea id="message" name="message"></textarea>
  </div>
  <div>
    <button type="submit">送信</button>
  </div>
</form>
```

formタグの中に`action="/path-to-thanks-page"`と記載することで、送信ボタンを押したあと自動的に用意したページに遷移することが出来ます。

これだけで簡単にフォームが生成できるのすごいですね。
Laravel:バリデーションの検証ルール

【概要】
----------------------------------------
<b>1.バリデーションの主な用意されている検証ルール</b>

<b>2.その他の用意されている検証ルール</b>

<b>3.開発環境</b>



1.バリデーションの主な検証ルール
----------------------------------------

```php:app/Http/Controllers/XXXXController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class XXXXController extends Controller
{
  public function post(Request $request)
    {
      $validate_rule = [
        'name' => 'required' , #---❶
        'mail' => 'email' , #---❷
        'age' => 'numeric|between:0,150' , #---❸
        ];
    }
}
```

❶："required"は、必須項目であることを示します。値がnull,空文字列（NULLとは違う)、
❷："email"は、形式チェックのみで実際に使用できるかどうかはチェックしません。
❸："numeric"は、値が数値であるかをチェックします。"integer"は整数であるかをチェックします。"between:最小値,最大値"は、最小値〜最大値の範囲内であるかをチェックします。"|"を使用することで複数検証ルールを実装することができます。

※今回はバリデーションの説明なので、 return view('XXXX.index' , ['XXX'=>'XXXX']);等々の記載は省いています。
<br>

2.その他の検証ルール
----------------------------------------

```php
=> 'alpha' #入力したすべてがアルファベットがチェック
=> 'alpha-num' #入力したすべてがアルファベットと数字かチェック
=> 'boolean' #true,false,0,1といった真偽値可動かをチェック
=> 'filled' #空欄でないかをチェック
=> 'present' #値が存在しているかのチェック。値はnull存在していれば問題なし。
=> 'string' #文字列かチェック
=> 'unique:テーブル名, カラム名' #データーベースにあるテーブルの該当カラムと重複していないかのチェック。emailと併用して使うことが多いです。
```
<br>


3.開発環境
----------------------------------------
PHP 7.4.10
Laravel 8.9
<br>
Javaで昇順の並べ替え(バブルソート:単純交換法のアルゴリズム)

#Javaで昇順の並べ替え(バブルソート:単純交換法のアルゴリズム)
Javaの基礎を学ぶ中でアルゴリズムに関する問題にあたったので、思考整理のため記載しました。

昇順に並べ変える(例：2,5,3,4,1→1,2,3,4,5)
ちなみに降順(5,4,3,2,1)

イメージは左から1つずつ順番にfor文で比較し、並べ替える。
(比較例：2と5、2と3、2と4、2と1…。)

書き方はいろいろありますが、下記コード例

```
1 int[] date =　{2,5,3,4,1};
2 for (int i = 0; i < date.length - 1; i++) {
3	for (int j = i + 1; j < date.length ; j++) {
4		if (date[i] > date[j]) {
5			int a = date[i];
6			date[i] = date[j];
7			date[j] = a;
8		}
9	}
10}
11for (int i = 0; i < date.length; i++) {
12	System.out.print(date[i] + " ");
13}
```
2行目のfor文で比較元となる１つ目の要素を取得するために条件式を指定します。

```
初期値i = 0;条件式(i < date.length - 1);次の一歩 i++
```

一つの要素が比較する値の数を```date.length - 1```で取得します。
並べ替える数が増えても問題ありません。

```
比較する値の数とは、例：2,5,3,4,1のうち
2と5,2と3,2と4,2と1の4回
```

3行目のfor文で比較対象となる2つ目の要素を取得するため初期値`j = i +i`の形で条件式を記述します。

```
初期値(j = i +i);条件式(j < date.length);次の一歩 j++
```

4〜8行目のif文で条件に当てはまる値の比較を行い、並び替えを行います。

```
if (date[i] > date[j]) {
    int a = date[i];
    date[i] = date[j];
    date[j] = a;
}
```

並べ変え後のdateの表示

```
for (int i = 0; i < date.length; i++) {
	System.out.print(date[i] + " ");
}
```
```
コンソール表示
1 2 3 4 5
```
###参照
---
[【Java】配列を使って並び替えをする（バブルソート編）](http://tokihano.jugem.jp/?eid=26)
【CakePHP3】クエリービルダーのCASE WHENで条件分岐

CakePHP3のクエリービルダーでif文みたいな分岐するクエリ文を書きたいな〜と思う場面があった。

そこで、「商品リストを作ろう！」となった際、カテゴリー名も併せて表示させたいな〜となった時の例えを下に書きますね。

**商品 (product)**

|id|product_name|product_category|
|:---|:---|:---|
|1|ランタン|2|
|2|テント|2|
|3|プロジェクター|3|

**商品カテゴリー (product_category)**

|id|product_category_name|
|:---|:---|
|1|雑貨|
|2|アウトドア|
|3|電化製品|

**【結果】**

|商品名|カテゴリー|
|:---|:---|
|ランタン|アウトドア|
|テント|アウトドア|
|プロジェクター|電化製品|

``````PHP:ProductsController.php
public function productsList {
 $query = $this->Products->find()
 ->select([
      'product_name' => 'Product.product_name',
      'product_category_name' => 'CASE WHEN Product.product_category = 1 THEN "雑貨",
                   WHEN Product.product_category = 2 THEN "アウトドア",
                   WHEN Product.product_category = 3 THEN "電化製品" END'
 ])
 ->innerJoinWith('ProductCategory');
}
```
[前回の記事]:https://qiita.com/n0te25e1f/items/7df6473c03fc79aa11b4
[前回の記事][]を見ていただくとわかるのですが、今回の例えも`product_category`はIDが格納されている、すなわちint型なのでエイリアス名を変えないといけないので変えました。

ちなみに既に気づいた方がいると思いますが、都道府県名とかたっくさん分岐がある場合は使い物になりません。
GitHub Actionsユーザーは今すぐDocker Hubのpull回数制限に備えよう

# 2021/06/19 追記

[こちらのissueへのコメント](https://github.com/actions/virtual-environments/issues/1445#issuecomment-713861495)の通り、**本対応は不要**になりました。この記事の情報は古いです。

# 発生する問題

2020年11月より、Docker Hubがログインしていないユーザーに対してPullの回数を制限します。というか、すでに段階的に始まっています。 

- [公式アナウンス（英語）](https://docs.docker.com/docker-hub/download-rate-limit/)
- [Docker HubのPull回数制限はすでに始まっている](https://qiita.com/zizi4n5/items/7b9676aa2cfc9c5679ae)

GitHub Actionsについても、

`toomanyrequests: Too Many Requests. Please see https://docs.docker.com/docker-hub/download-rate-limit/`

というエラーでDockerイメージのpullに失敗し、ワークフローがエラーになりそうです（私はまだエラーになったことがない）

※ IPアドレスでのrate-limitのため、自分のpull回数に関わらずエラーが起こりえます。

# 対応策

[公式アナウンス（英語）](https://docs.docker.com/docker-hub/download-rate-limit/)で紹介されている通り、[docker/login-action](https://github.com/docker/login-action#dockerhub)を使ってみましょう。

### 対応後のyaml

```workflow.yml
jobs:
  HogeHogeJob:
    name: HogeHogeJob
    runs-on: ubuntu-latest
    steps:
      # この5行を追加する
      - name: Login to DockerHub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      # あとは今まで通りで良い
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup python
        uses: actions/setup-python@v2
        with:
          python-version: 3.7
```

`DOCKERHUB_USERNAME`と`DOCKERHUB_TOKEN`は、あらかじめsecretsとしてGitHubに登録しておきましょう（[公式Doc](https://docs.github.com/ja/free-pro-team@latest/actions/reference/encrypted-secrets#%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%81%AE%E6%9A%97%E5%8F%B7%E5%8C%96%E3%81%95%E3%82%8C%E3%81%9F%E3%82%B7%E3%83%BC%E3%82%AF%E3%83%AC%E3%83%83%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90)）

注意点として、**`DOCKERHUB_TOKEN` にはパスワードではなくAccess Tokenを使うことが推奨されています**。パスワードでも動きますが、ちゃんとAccess Tokenを発行しましょう。

# Access Tokenの発行方法

1. https://hub.docker.com/ にログイン
2. 右上のユーザー名から Account Settings
3. Security -> New Access Token -> あとは流れに乗る
![スクリーンショット 2020-10-21 20.28.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502255/ad72b378-c66a-20c7-6c20-76b3ddb3e5d5.png)

発行されたAccess Tokenを`DOCKERHUB_TOKEN`として登録すれば完了。docker/login-actionでログインできるようになります。
buildpacksとは何なのか？


# Overview
任意の言語やソースコードからライブラリやフレームワークを読み取りベストプラクティスに則ってDockerfileすら書かずにイメージを生成してくれる。
Googleがオープンソースとして作成し、GCPではデフォルト使えるようになっている模様

# 実際に使ってみた感想
https://github.com/GoogleCloudPlatform/buildpacks
公式のチュートリアルに則って使ってみたのですが本当にコマンド一髪で生成されました。

正直凄いと言うより、不思議です。


# 構成
と言うわけでbuildpackの中身をみていきましょう。
buildpackはbuilderと言う実際にイメージを生成するツールが存在しています。
自分のソースコードに合わせた適切なbuilderを使うことでimageを作ることができるのです。


## builder
builderはビルドするための情報や方法が格納されたイメージ,以下の部品によって構成されています。

* buildpack
* lifecycle
* stack

### buildpack
ソースコードを検査し、ビルド計画をするための作業単位
最低以下のファイルが必要になる

* buildpack.toml – buildpackのメタデータ?
* bin/detect – buildpackが実行できるかどうかを検証
* bin/build – buildpackを実行するロジック

フェーズとしては以下の二つ

* detect
		
buildpackの内容と実際のソースコードが合致しているかどうかを逐次的にみていく
例えばnpm buildpackならpackage.jsonを見る
	
* build
buildpackが実際にimageを作っていく。この時に、環境変数を設定し、バイナリを埋め込み(ruby,python,php),依存関係を解決する(bunble installなど)

### lifecycle
複数のbuildpackを連携させて最終的なimageを作り出す

フェーズは以下の４つ

* Detection – buildするためにbuildpackのグループを探索する
* Analysis – build か export フェーズに最適化に使うかもしれないファイルを復活させる  ---?
* Build – コンテナの中で実行可能なパッケージとしてソースコードを変換する
* Export – 最終的な OCI(open container initiative) image　を作る。 (OCIとはコンテナイメージのフォーマットの模様)

### stack
実行環境やビルド時に使用する lifescycleを提供する機能


## つまり
ソースコードを解析にそれに該当するbuildpackのグループがコードをコンテナ中で実行可能な形に変換していく。
それを元にして、環境変数やビルド時に情報を埋め込みながら最終的なイメージへ出力していくと言う感じっぽいです。

逆に言うと、解析できるbuilderがないとイメージへの変換が出来ないようです。
そのため。OSSのbuilderも存在しているようです。
https://github.com/cloudfoundry/ruby-buildpack

# 最後に
雑にまとめましたが、対応している言語であれば普通に使えそうです。
試していませんが、buildpackでimageを焼いてそれを元にdocker-composeを使って異なるコンテナ間の処理をかけばさくっとローカル環境が構築できそうです。
PowerBIでツイートの内容を取り込んでみた

じゃんけんげーむの続きではないです・・・

#目的
自分用の備忘録として書いています

#本記事の内容
・Twitterのデータの取得方法（CSV）
・PowerBIでのデータの取り込み方
・PowerAutomateを使ってTwitterのデータを自動的にOneDriveのExcelファイルに取り込む方法

#Twitterのデータの取得方法（CSV）
自分のアカウントでTwitterにログインし、アナリティクスからCSVデータをエクスポートする。
![csv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/7e1be7dd-7e09-8eb0-0d9f-760561ce2a21.png)

#PowerBIでのデータの取り込み方
PowerBIDesktopを起動

![powerbi1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/2897fa14-ff0d-b819-8af0-a2b1025179f9.png)
データの取得からCSV/TXTデータを選ぶ

![powerbi2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/73384e77-0700-c5af-ab63-6849de340f0a.png)
文字化けってるうううう！！！
※文字コードがUTF-8では文字化けってるのでANSIに変更します
参考：https://auto-worker.com/blog/?p=285


![powerbi3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/85b29e73-0975-f1da-ae4b-019cef5aa891.png)

一旦テキストで開き、文字コードをANSIに変更して保存・・・

再度PowerBIでCSVを取り込み・・

![powerbi4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/8b81f94e-f35d-f3da-9742-4cb2415c8703.png)

文字化け解消！！

![powerbi5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/23995be4-d8e6-e818-145d-9e572d4bf3b3.png)

できた！！！
あとはデータを好きなように分析～～

#PowerAutomateを使ってTwitterのデータを自動的にOneDriveのExcelファイルに取り込む方法
設定したキーワードがツイートされた時をトリガーにOneDriveに保存しているExcelにツイートデータを保存するフローを作成していく

まずは下準備

![excel1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/81ee324f-8e00-a5fb-21cf-395553efa0c4.png)
データを格納するExcelファイルにテーブルを作成し保存する。
そのファイルをOneDriveに格納。
下準備はここまで
以下からPowerAutomateでフローを作っていく


![automate1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/ccd29e46-09d6-f50d-7951-916c02632b27.png)
Power AutomateのTwitterコネクタの「新しいツイートが投稿されたら」をトリガーにフローを作っていく


![automate2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/46ec132e-c8c6-d91b-f1ea-43486bcb098d.png)
私がやっているゲームの「FF14」というキーワードを含むツイートが投稿された時
OneDriveの指定の場所にあるエクセルファイルに行を追加するというフローを作成


![automate4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/db58ffb1-e492-5107-5556-93a2384c50ab.png)
フローを保存し、管理画面で実行履歴を見るとちゃんと動いていることが確認できた。


![automate3 - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/301050/12292545-218e-db33-2afb-fabfa48c96e7.png)
エクセルファイルをのぞいてみるとちゃんとデータが出力されている！

あとはエクセルをダウンロードしてPowerBIに取り込めば分析できる
（直接OneDriveのエクセルをPowerBIで見に行こうとしたけどできなかった）


#今日はここまで
次回はツイートのデータをDBにぶち込んでみます
【備忘録】Rspecのはじめ方

#本稿を作るにあたり
RubyonRailsでアプリケーションを開発した後、別のアプリケーションに用いる際の備忘録（2020年10月21日時点Mac）

自分は取り掛かるまでが長かったので、ひとまず感覚を掴むためによかったらやってみてください。

※詳細な内容について、別記事を参照されたし

##Rspecを行う際、使用したGem
```ruby:Gemfile
group :test do
  gem 'capybara', '>= 2.15'
  gem 'rspec-rails'
  gem "factory_bot_rails"
  gem 'faker'
end
```

```terminal:ターミナル
bundle install
```
###rspec-rails
Rspecを実行するためのGem
Ruby on Rails のテストフレームワーク RSpec 事始め
https://qiita.com/tatsurou313/items/c923338d2e3c07dfd9ee

###capybara
ドライバの設定をしないとRspecが動かなかったため、導入したGem
Capybaraチートシート
https://qiita.com/morrr/items/0e24251c049180218db4

###faker
データを作成するためのGem。主にRspecを実行している際の画面を入力テストのテストデータをGem内のライブラリを用いてランダムに作成していくれる。seedファイルで仮データも入力でき、便利。
Fakerを使ってみました！（使い方と実行例）
https://qiita.com/ginokinh/items/3f825326841dad6bd11e

###factory_bot_rails
先にテストデータを作成しておけるGem、主にModelのデバックに使いました。
【Rails】factory_botの使い方メモ
https://qiita.com/at-946/items/aaff42e4a9c2e4dd58ed

##Rspecのインストール
```terminal:ターミナル
rails generate rspec:install
```

インストールすると下記ファイルが作成されます。

```terminal:ターミナル
  Running via Spring preloader in process 9045
      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb
```

##spec_helper.rbにドライバの設定
仕組み的なところは未理解、おそらくここの設定のおかげでブラウザと同じ環境でプログラムを走らせることができる。

```ruby:spec_helper.rb
require 'capybara/rspec'
RSpec.configure do |config|
	config.before(:each, type: :system) do
    #driven_by :selenium_chrome_headless
    driven_by :rack_test
	end
end
```

###以後実際にテスト用のプログラムを記述
factoriesフォルダで作成するデータを作成、modelがバリテーション等のテストができ、sysyemで実際の画面上の動作をテストできる。参考までにコードを記載
※deviseを用いた新規ユーザー登録のチェックを想定
![スクリーンショット 2020-10-21 20.58.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810435/74fb0923-adc0-e853-ac76-5eeb64c76ca9.png)


```ruby:factories/users_spec.rb
FactoryBot.define do
  factory :user do
    email { Faker::Internet.email }
    password { 'password' }
    password_confirmation { 'password' }
  end
end
```

```ruby:model/user_spec.rb
require 'rails_helper'

RSpec.describe 'Userモデルのテスト', type: :model do
  before do
    @user = build(:user)
  end

  describe 'バリデーション' do
    it 'emailが空だとNG' do
      @user.email = ''
      expect(@user.valid?).to eq(false)
    end
  end
end
```

```ruby:system/user_spec.rb
require 'rails_helper'

describe 'ユーザー認証のテスト' do
  describe 'ユーザー新規登録' do
    before do
      visit new_user_registration_path
    end
    context '新規登録画面に遷移' do
      it '新規登録に成功する' do
        fill_in 'user[email]', with: Faker::Internet.email
        fill_in 'user[password]', with: 'password'
        fill_in 'user[password_confirmation]', with: 'password'
        click_button "sign in"                       #ボタンに表示されている文字
        expect(page).to have_content 'successful'   #ログイン後に表示されるメッセージを指定してください
      end
    end
  end
end
```

##Rspecを実行
下記コマンドでspecフォルダ内のテストが全て実行され、成功したものが緑、失敗したものが赤でターミナル上に表示される。

```terminal:ターミナル
bundle exec rspec spec/ --format documentation
```

ESpecチートシート
https://qiita.com/morrr/items/6ed889d17abbfd352649

以上、お疲れ様でした。
特定のファイルのみベーシック認証をはずす(さくらのレンタルサーバー)

さくらのレンタルサーバー内で旧サイトから新サイトへ移行したときの話（プラン変更した）
旧サイトは閉鎖です。ただし解約しないでしばらく検証用や確認用に保存することに。
なので旧サイトにはさくらのレンタルサーバーで無料で使えるサブドメインをあてました。
旧サイト全体にはベーシック認証をかけました。

ここでひとつ困ったことが。
初期ドメインでのリンクが残っていた。
具体的には〇〇〇.sakura.ne.jp/test/test.pdf　みたいな。
初期ドメインのリンクは
ベーシック認証ではじかれてしまいます。そのせいで新サイトへのリダイレクトもできないです。

どうしようと悩んでいたところ
初期ドメインのリンクはすべてPDFファイルであることに気が付きました。

##結論
PDFファイルのみベーシック認証を外す。


##前提
・サイト全体にベーシック認証がかかっている
・初期ドメインでのリンクはすべてPDFファイル
・ベーシック認証の記述はさくらのレンタルサーバーのファイルマネージャで作成　※下記参照

すでにあるベーシック認証の一番下に以下の３行を追加するだけでPDFファイルのみベーシック認証が外れました。

```
<FilesMatch "\.pdf$">
  Satisfy Any
</FilesMatch>

```

##解説

さくらのレンタルサーバーベーシック認証の解説は以前記事にしたのでそちらを参考にしてください。
https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1

```:ページ全体のベーシック認証+PDFファイルはベーシック認証しない
DirectoryIndex index.html index.htm index.shtml index.php index.cgi
Options -Indexes
AuthUserFile /home/〇〇〇/www/.htpasswd
AuthType Basic
AuthName "Web access"
Require valid-user
Satisfy all
Order deny,allow
##ここにPDFファイルを除外する設定を追加するのみ
<FilesMatch "\.pdf$">
  Satisfy Any
</FilesMatch>
RewriteEngine on
#リダイレクトしたい場合はここからリダイレクトの記述をする

```
###　FileMatchの記述について
FileMatchの記述は環境により異なります。


|  |  |  |
|:-----------|:------------|:------------:|
| \<FilesMatch ".pdf$"\> | 末尾が.pdfで終わるファイルに対する命令を書きますよ|[詳細](https://httpd.apache.org/docs/2.4/ja/mod/core.html#filesmatch)|
| Satisfy Any |ホストによる制御とユーザー認証による制御どちらか一方を満たせばよいということ。さくらのレンタルサーバーの場合、外国からのアクセスを制限しています。（ホストによる制御）ということは国内からのアクセスの場合ホストによる制御を満たしているということなので、どちらか一方を満たしているということになります。 満たしているのでアクセスできるつまり、ベーシック認証のダイアログがでないということです。| [詳細](https://httpd.apache.org/docs/2.4/ja/mod/mod_access_compat.html#satisfy)   |
| RewriteEngine on  |RewriteRuleでリダイレクト処理しますよと宣言する|[詳細](http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriteengine)|


※環境により
\<FilesMatch "\.pdf$">
  Satisfy Any
\</FilesMatch>
の記述はことなるかと思います。

学び
さくらのレンタルサーバーで初期ドメインを使うのはやめよう。
困ったらググればいいんだよ

# 概要

プログラミングをしていると、エラーや思い通りにプログラムが動かなくてつまずいてしまうこと多いですよね。
そんな時でも諦めずに正しくググることで必ず答えに辿り着くことができます。

この記事では、しまぶーのITチャンネルさんのググり方等を参考にしてググり力がついたのでその方法の一覧を紹介します。
記事の最後に参考記事としてチャンネルのリンクが貼ってあってすごいわかりやすいので是非ご覧ください。

## ググり方一覧
ググり方の一覧は以下のようです。

| ググり方 | 効果 | 難易度 |
| :---: | :---: | :---: |
| エラーメッセージ | ★★★ | ★☆☆ |
| リファレンス | ★☆☆ | ★★★ |
| 英語 | ★★★ | ★★☆ |
| Github | ★★☆ | ★★★ |


それぞれについて簡単に詳細を述べます。

# エラーメッセージでググる
プログラムのエラーメッセージで関連のあるところをそのままGoogleで検索をかける方法で、一番オーソドックスなググり方です。
自分にでたエラーは他の人も経験したことがあるものなので、ほとんどの場合解決することができます。
しかし、ネットに転がっている情報が本当に正しいかどうかはわからないのでそこは注意が必要です。

# リファレンスでググる
プログラミング言語にはリファレンスという仕様書のようなものがあり使い方が記されています。
リファレンスなだけあり、わかりやすく書かれてはいないものの公式が出しているため間違いはありません。
プログラミングに慣れてきたらこちらの方法を使うのもありでしょう。

例えばpythonやrubyのリファレンスは以下です。

**python**
https://docs.python.org/ja/3/reference/

**ruby**
https://docs.ruby-lang.org/ja/

# 英語でググる
日本語ではなく調べたい内容を英語を使ってググる方法です。
日本語に比べて英語のプログラミングの情報量は何倍もあります。
そのため、英語でググることで日本語の時では至らなかった回答に至る可能性があります。
今ではgoogle翻訳などの翻訳サービスが充実しているため英語をあまりわからなくても簡単に検索することができます。

例えば、最近研究でlstmを扱っているのですが、lstmの使い方を調べたい時

`python lstm　使い方`  →約 19,200 件

なのに対し、

`how to use lstm in python`　→約 3,720,000 件

と、150倍程度情報に差があることが確認できます。

# Githubでググる
最後にGithubでググるという方法もあります。
Githubはソースコードを載っけるだけではなくググるために使うこともできます。
検索した後で、

・Code ← これをほとんど使う
・Commits
・Discussions

のいずれかを見れば良いと思います。

# それでも答えが見つからなかったら
ググりまくっても答えが見つからない場合、質問掲示板等で質問をするのも一つの手です。
例えば、現在使っているqiitaにも質問機能があるのでそこで質問をすることができます。

・[Qiita](http://qiita.com)
・[terateil](https://teratail.com/)
・[stack overflow](https://stackoverflow.com/) ←英語のため難しいが情報量がえぐい

質問をする際には、答え手に対してどのようなエラーが起きているか具体的に説明する、どのような環境で開発しているのか、現在の自分のレベルなどを詳しく書くようにしましょう。




## 参考記事

・**しまぶーのITチャンネル**
https://www.youtube.com/watch?v=kNiD4rfNkFA
cloud9からlambdaを動かす際の注意点(No module named ~のエラーなど)

#はじめに
AWS関連で、cloud9からlambdaを動かす際に少し躓いたことがあったのでその辺をまとめていきます。lambdaはサーバーレスでプログラムを実行してくれるので非常に便利で、私もスクレイピング等の定期実行のために使いはじめました。
この記事は主に初めてcloud9、lambdaを使う方向けになると思います。
#実践
まず新しくcloud9の環境を作成。名前はexampleにしておきます。
![2020-10-21 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/806955/13bf3056-bb4e-999a-91b8-062019841120.png)
これが終わると下のような画面に移ります。画面右に表示されている漢字の「入」のようなボタンをクリック、さらにCreate a new Lambda function(画像のオレンジ色の部分)をクリックしてlambda-functionを作成できます。
![2020-10-21 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/806955/e308dceb-e334-08de-fab4-64d275a2fe8e.png)
function名は適当に決めてあげて(ここではsample)、Select runtimeのところで使用する言語を選びます。(下の画像)今回はpythonを使ってスクレイピングに使用するBeautifulSoupライブラリのimportが成功するまでを書いていくので、「python3.6」を選びます。そのほかの設定は特にいじらなくて大丈夫だと思います。![2020-10-21 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/806955/2c7031ed-8924-dad9-fb0b-5288454ffb29.png)
home/ec2-user/environmentにsampleディレクトリが出来ていると思います。
次にhome/ec2-user/environment/sample/sampleにあるlambda_function.pyを開いてみてください。ここにプログラムを実行していくコードを書いていくことになります。

```lambda_function.py
from bs4 import BeautifulSoup

def lambda_handler(event, context):
    
    return 'success'
```
今回は練習なのでこれだけ書きます。bs4からBeautifulSoupをimportすることが出来ていたらsuccessが返ってきます。

ではbs4をinstallしていきます。
まずは

```
sudo pip install --upgrade pip
```
でpipを最新のバージョンにupgradeしましょう。

次に

```
pip install bs4
```
を実行。(Permission deniedのエラーが出るときは末尾に --userを付け加えます)

無事インストールが成功しました。

早速、lambda_functionを実行してみます。画面右のLocal Functions でsampleを選択し、Run the selected Lambda functionをクリックしましょう。
![2020-10-21 (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/806955/3d5169da-d841-761b-7f79-e1c1490236f6.png)

すると Unable to import module 'sample/lambda_function': No module named 'bs4'
とエラーが出てしまします。bs4のinstallは成功しているはずなのにbs4が見つからないと言われています。なぜでしょうか。

答えとしては、lambdaはサーバーレスで動くので、lambdaの作業用ファイル(sample)内で完結している必要がある（使用するライブラリはファイル内に入れておかなければならない)からです。
解決策するために

```
cd sample
pip install bs4 -t .
```
を実行します(-tとディレクトリ名でinstall先を指定)

もう一度lambda_functionを動かしてみてください
successと返ってきたら成功です。

最後にremoteにlambdaファイルをデプロイすれば終了です。(画面右上)
![2020-10-21 (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/806955/6f37b2a4-875b-24b4-56b8-ac0063d6d1d4.png)
プログラムの定期実行を行いたいときはAmazon EventBridgeから設定することが出来ます。

#おわりに
pipコマンドの　-t は忘れそうだったので記事にしてみました。少額ですが実行時間に応じてお金がかかるので、実行時間が長く頻繁に動かすなら注意した方がいいですね。
サブ記事: GNU, Linux周辺知識整理

# GNU.orgについて

GNU  【 GNU is Not Unix 】 
フリーソフトウェア（特に、オープンソースソフトウェア）のみでUNIX風のOSと関連するソフトウェア群を開発・公開するプロジェクト。

## Linux OSについて
Debian系

|  名  |    |  説明  |
| ---- | ---- | ---- |
|  Kali Linux  |    |  Debian派生の1DVD型。侵入テスト目的に特化していることが特徴。  |
|  Ubuntu  |    |  6ヶ月ごとの更新と商用の保守を掲げる。デスクトップ環境としてGNOMEを採用している。パソコン雑誌に雑誌社特製のLive CD/DVDとして付属される場合がある。多彩な派生版が存在。  |

Red Hat系

|  名  |    |  Initial release  |
| ---- | ---- | ---- |
|  Red Hat Linux  |    |  商用および個人用。開発終了。個人用はFedora Coreへ事実上開発を引き継ぎ。商用版は後継版のRed Hat Enterprise Linuxで、Fedora Projectによるテスト済みのFedoraを母体とし安定させたもの。  |
|  CentOS  |    |  Red Hat Enterprise Linuxの無償版。  |
|  Fedora  |    |  Red Hat Linux 後継のコミュニティFedora Projectによる実験要素が強い。  |

Arch系
	
|  名  |    |  Initial release  |
| ---- | ---- | ---- |
|  Arch Linux  |    |  パッケージ管理システムにPacmanを使用。  |

Gentoo系
	

|  名  |    |  Initial release  |
| ---- | ---- | ---- |
|  Chrome OS  |    |  Chrome OS[28][29]は、Googleが開発しているOS。2010年2月に、母体となるOSをubuntuからGentooに変更した。Chromium OSは、Google Chrome OSのオープンソース版。  |

独立系

|  名  |    |  Initial release  |
| ---- | ---- | ---- |
|  Android  |    |  Android は Google が開発したモバイル端末向けOS。x86(64)版は、androidをpc上で動かすためのLive CD。64bit cpuのための物はx64と呼ばれる[31]。CyanogenMod/CyanogenOS	CyanogenMod は開発終了した携帯端末向け OS。Androidから派生。  |
|  Firefox OS  |    |  Firefox OSは、Mozillaと外部の貢献者によって設計された、スマートフォン、タブレットコンピューター、スマートTV向けに作られた廃止されたオープンソースオペレーティングシステムです。  |

<!--
|  名  |    |    |
| ---- | ---- | ---- |
|    |    |    |
|    |    |    |
-->

## Linux構成


LinuxディストリビューションはLinuxカーネルとその他ソフトウェア群を1つにまとめ、利用者が容易にインストール・利用できるようにしたものである。

Linuxカーネルはプロセスやソケット通信などの機能を提供する。これらは様々なソフトウェアを動作させるうえで基礎となる重要な機能であるが、ユーザーが利用する機能としては非常にプリミティブである。例えばカーネルそのものにはOS起動時のデーモン自動起動機能は存在しないし、Bashのようなインタラクティブコンソール機能も存在しない。これらの機能はすべてLinuxカーネルを利用するGNUなどによって作られた個別のソフトウェアによって実現されている。


ユーザーの利便性を高めるためにLinuxカーネルとこれらソフトウェア群を1つのパッケージにしたものがLinuxディストリビューションである。



#### コンポーネント

GNU/Linux Distro Timeline, 様々に派生したLinuxディストリビューションのタイムライン。
カーネルの他、基本的なUNIXのツールやユーティリティ、その他サーバ向けやデスクトップ環境向けのソフトウェアを集め、ビルドしてバイナリパッケージを作成し提供している。バイナリパッケージを利用するという形態のために、rpmやdebなど、何らかのバイナリパッケージシステムの採用がほぼ必須であり、aptやyumなどより上位のパッケージ管理システムも、現代ではほぼ必須である。

・Linuxカーネル

・必須なツールやユーティリティやライブラリ

|  名  |    |
| ---- | ---- |
|  util-linux  |  （en:Util-linux）  |
|  GNU Core Utilities  |  （coreutilsとも。昔のfileutils, shellutils, textutilsは全てcoreutilsに取り込まれた）  |
|  Bourne Shell  |   互換シェル（他のシェルと違い /bin/sh として必須である(Debian系ではDashが/bin/shに使われることも多い)）  |
|  Unixシェル  |    |
|  glibc  |  GNU Cライブラリプロジェクトは、 GNUシステムとGNU / Linuxシステム、およびLinuxをカーネルとして使用する他の多くのシステムのコアライブラリを提供します。これらのライブラリは、ISO C11、POSIX.1-2008、BSD、OS固有のAPIなどを含む重要なAPIを提供します。これらのAPIには、open、 read、write、malloc、printf、 getaddrinfo、dlopen、pthread_create、 crypt、login、exitなどの基本的な機能が含まれています。GNU Cライブラリは、下位互換性があり、移植性があり、高性能のISOCライ​​ブラリになるように設計されています。  |
|    |    |


・起動に必要なもの
init
/etc などの基本的なファイル群
GRUBやLILOのようなブートローダー

・エディタ
Emacs
nano
vim

・コンパイラ等
GNU Binutils (binutils)
GCC


・スクリプト言語
awk
perl
python
sed

・GUI関係
X11のフリーな実装であるXFree86、XOrg
デスクトップ環境としてGNOME、KDE、Xfce、LXDE
ウィンドウマネージャ

・デスクトップ向けアプリケーション
ウェブブラウザ
電子メールクライアント
テキストエディタ
オフィススイート
マルチメディア
ゲーム

・サーバ向けアプリケーション
メールサーバ
Webサーバ
データベース管理システム

これらはソフトウェア構成の例であり、
他にも様々なソフトウェアをインストールできる。
Nuxt.js v2.12 から v2.13 / v2.14 へのバージョンアップ注意点

Nuxt.js v2.12 から Nuxt.js v2.13, v2.14 へバージョンアップした時の注意点や
変わったと感じたことまとめます。
各バージョンの大きな特徴として、v2.13 では静的ビルドが強化され、
v2.14 ではビルド周りの整理・高速化が行われました。

この記事では、下記のバージョンで検証を行っています。

- Nuxt.js v2.13.3
- Nuxt.js v2.14.6


## Nuxt.js v2.13 からは dotenv がランタイム構成に含まれる

Nuxt.js v2.13 から dotenv がランタイム構成に含まれるようになりました。
https://nuxtjs.org/blog/moving-from-nuxtjs-dotenv-to-runtime-config

この機能によって .env ファイルをプラグインなしで自動で読み込んでくれます。
ただ、**.env というディレクトリ** 配下に development.js などで環境変数を設定している場合、
.env ディレクトリをファイルとして読み込こもうとしてエラーになります。
（ここでハマりました。。）
これの解消方法は、単純に環境変数を格納するディレクトリを ```.env``` にしなければ大丈夫です。


## 環境変数をビルド後のソースコードから隠微できる（SSG のみ）

process.env や nuxt.config.js の env に環境変数を書いていた場合、
webpeck でコンパイルするとソースコードに残ってしまっていました。

<img width="490" alt="スクリーンショット 2020-08-06 14.49.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131281/30308bc6-be8e-1edd-4cc0-eebbe2c25d7b.png">

これは v2.12 でも v2.13 でも同様です。

参考：
上記の [https://nuxtjs.org/ の記事](https://nuxtjs.org/blog/moving-from-nuxtjs-dotenv-to-runtime-config) と
[NuxtのJamstack構成におけるAPIキーの隠蔽方法について](https://microcms.io/blog/nuxt-secure-api-key/)

v2.13 から nuxt.config に **publicRuntimeConfig** と **privateRuntimeConfig** という項目が追加されました。
privateRuntimeConfig は SSG のときのみ利用され、フロントのソースには残りません。

### フロントで使う環境変数を隠微したいとき
これで環境変数を隠微できたように見えますが、検索 API などフロントからは環境変数を使うときは privateRuntimeConfig が使えません。
Algolia の Application ID など、見えて困るものはサーバ側で処理を挟む必要があります。

参考：[microCMSとNuxtでプレビュー画面を作成する_API-KEYを隠す方法](https://microcms.io/blog/nuxt-jamstack-preview#h017e584005)


## generate が v2.13 でなくなって v2.14 で復活した

Nuxt v2.12 では静的ビルドのコマンドが

 ```
$ nuxt generate
```
でしたが、v2.13 から

```
$ nuxt build && nuxt export 
```
に変わりました。

それが v2.14 では再び

 ```
$ nuxt generate
```
で静的ビルドができるようになりました。


## v2.14 で nuxt-property-decorator の watchQuery が使えなくなった？

これは見出しそのままなのですが、v2.13 で nuxt-property-decorator の watchQuery でクエリ変更を監視していたのですが、v2.14 の static ビルドでうまく動かなくなりました。

nuxt-property-decorator のバージョンは 2.8.8 で Nuxt.js v2.14 以降の版です。
解消方法が見当たらなかったので nuxt-property-decorator でなく
composition-api の watch でクエリを監視する方法で解消しました。

もしかしたら、ちゃんと解消方法があるのかもしれない（もしくは watchQuery 対応についてのドキュメントがあるかも）のですが、
見つけられずこのような対応になりました。



## まとめ

Nuxt.js の v2.12 は長く安定していた記憶があるのですが、
v2.14 は周辺のプラグインの対応も含めて知識のアップデートが必要そうです。

内容が薄くてすみません:bow:
DockerでSparkを動かしたらlocalhost:4040にアクセスできない件について

Sparkの`Spark Web UI` (localhost:4040)だけが何故か接続できなかったので、色々調べていたのですが解決策が乗っておらず、慣れていない人であれば同じ悩みを抱えている人がいると思ったので、初投稿します。また業務中に起きたエラーのため、コードなどは一切載せていませんのでご理解のほどよろしくお願いいたします。

# 環境
DockerでPythonのコンテナとSparkのコンテナ(wokerを接続している)をBridgeしている
どちらの環境にも`Pyspark`、`java`の環境がインストールされている。

## 環境構築の参考
SparkのMaster1つとWorker1つをdocker-composeで上げてpysparkを動かすまで
https://qiita.com/hrkt/items/fe9b1162f7a08a07e812

# ゴール
PythonのDockerの中に入って(docker exec...) spark-submitを行い、処理を行っている間にlocalhost:4040に接続してWebUIを確認したい。

# 問題について
起動してからlocalhost:8080はつながるのになぜか4040は接続ができない

# 解決策
1. Sparkが処理中時にのみlocalhost:4040にアクセスできる
2. docker-compose.ymlのSparkのコンテナにport 4040:4040と書いていたが、Job管理をするPython側にport 4040:4040を書く必要があった。(今回はこれが該当)

# まとめ
StackOverFlowなどを読んでも全く分からなかったが、先輩に聞いたら一発で解決した。インフラにもっと強くなりたいです。

# おまけ
sparkの中でサンプルコードを動かしていたが、`df.show()`すると
`initial job has not accepted any resources; check your cluster ui to ensure that workers are registered and have sufficient resources`と出て止まってしまう。リソースが足りないとのことで、メモリ設定などを変えたが解決しなかった。

サンプルコードはこちらから借りてきました。

PySpark のスクリプトファイルで引数を扱う
https://blog.amedama.jp/entry/2018/03/17/113516

参考にしたサンプルコード

```
from pyspark import SparkConf
from pyspark import SparkContext
from pyspark.sql import SparkSession
def main():
    conf = SparkConf()
    conf.setAppName('example')
    sc = SparkContext(conf=conf)
    spark = SparkSession(sc)
    df = spark.sql('SELECT "Hello, World!" AS message')
    df.show()
```

解決策  

```
conf = SparkConf().setMaster('local')
【HTML】セレクトボックスを使ってみた

#プログラミング勉強日記
2020年10月21日
今までHTMLを勉強してきたが、セレクトボックスを使ったことがなかったので使い方をまとめる。

#セレクトボックスの基本的な書き方
　select要素でセレクトボックスを作成することができる。メニューの選択肢はselect要素内に配置するoption要素で作成する。
　select要素はname属性には部品の名前を指定し、size属性で表示行数を指定する(初期値は1)、multiple属性は複数選択を可能にする。
　option要素はvalue属性には送信される文字列を指定し、label属性は選択肢として表示されるテキストを指定し、selected属性では選択された状態を指定する。


　基本的な書き方は以下のようになる。

```html:html
<select name="example">
  <option value="サンプル1">サンプル1</option>
  <option value="サンプル2">サンプル2</option>
  <option value="サンプル3">サンプル3</option>
</select>
```
実行結果(矢印をクリックするとサンプル2とサンプル3が出る)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/bec7c991-2744-8804-9359-9ff00e2bbc37.png)
 


#特定の選択肢を選択済みにするサンプルコード
　option要素にselected属性を指定する。

```html:html
<select name="example">
  <option value="サンプル1">サンプル1</option>
  <option value="サンプル2"  selected>サンプル2</option>
  <option value="サンプル3">サンプル3</option>
</select>
```

実行結果(サンプル2がすでに選択されていて、クリックすると3つ表示される)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/3c60dda2-68c2-74b1-05a6-5efe98623b9f.png)

#リスト形式で表示させるサンプルコード
　select要素にsize属性を指定する。

```html:html
<select name="example" size="3">
  <option value="サンプル1">サンプル1</option>
  <option value="サンプル2">サンプル2</option>
  <option value="サンプル3">サンプル3</option>
</select>
```

実行結果(以下のようにリストになる)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/1b29a59b-3ffa-28c2-2bf5-313857900d25.png)


#参考文献
[HTMLでのselectedによる初期値の設定方法を現役エンジニアが解説【初心者向け】](https://techacademy.jp/magazine/48564)
[セレクトボックスを作る](https://www.tagindex.com/html_tag/form/select.html)
続・データベースになくても、データとして扱える活動的なハッシュ　〜表示編

#はじめに
　ActiveHashの使い方については以前投稿した、[こちら](https://qiita.com/TerToEer_sho/items/9b6fa469e1808f015582)を参考にしてください。


##ActiveHashの文字列を取り出す方法

ActiveHashに入れて保存されているデータを、ビューに表示させたいときは、カラム名だけでは、数値が表示されるだけなので、

```ruby:ex)
item.prefecture.name
```
とカラム名の後に`name`とつけると、idに紐づいた文字列が表示されるようになる。
Slim4をサブディレクトリで走らせる方法

軽量なPHPフレームワークで有名なSlim4を、ルートディレクトリより下のディレクトリで走らせる方法です。[このページ](https://akrabat.com/running-slim-4-in-a-subdirectory/)を元に書いてます。つまり雑な英訳≒要約です。

次のようにApacheサーバーが動いているとします。

- Rootディレクトリが`/var/www/public/`
- URLが`https://example.com/`

こんなウェブサイトがあったときに、

- Slim4を`/var/www/public/test/`ディレクトリに展開して、
- `https://example.com/test/`としてアクセスしたい。

そんな状況です。

## Apacheの設定

`/var/www/public/test/.htaccess`を作成します。

```ApacheConf
# Rewrite URL
RewriteEngine on

# redirect to /index.php
RewriteBase /test
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [L,QSA]
```

ポイントは`RewriteBase /test`を追加すること。
それと`RewriteRule`のファイル名を`index.php`とすること（最初にスラッシュを書かない）。
かな。

## Slim4の設定

次に、`/var/www/public/test/index.php`で、Slim4を動かします。

ここでアプリに、サブディレクトリで走っていることを教えてあげます。


```php
$app = AppFactory::create();
$app->setBasePath('/test'); // ←この一行を追加！
```

`$app->setBasePath()`関数でサブディレクトリ名を指定します。

これで、`/test`を書かずにルート設定などが可能になります。


### 自動でBasePathを取得する方法

ベースパスを自動で取得する方法が参考ページにありましたので、興味ある方はそちらを御覧ください。

## 最後に

ウェブサイトの一部だけをSlim4で作る・作り直すというケースがありそうかなと思って調べてみました。
サブ記事: Microsoft, Visual Studioについて


# Microsoft

## .NET
フリー。 クロス プラットフォーム。 オープン ソース。
Web、モバイル、デスクトップ、ゲーム、IoT など、あらゆるアプリを構築するための開発者用プラットフォームです。 Windows、Linux、macOS でサポートされています。


## Visual Studio
##### 対応プログラミング言語
Visual Studio 2019における、対応プログラミング言語は以下の通り。

C++, C#, Visual Basic, F#, Python, Node.js, HTML/JavaScript, TypeScript

##### 含まれる製品

・Visual C++
C/C++処理系のマイクロソフト実装であり、コンパイラやライブラリ、その他の開発ツールを含んだものである。n32/Win64アプリケーションやCOMの開発で利用されており、Microsoft Foundation ClassなどのVisual C++専用ライブラリ／フレームワークが存在する。
コンパイラとして、Windows用バイナリを生成するMSVCのほか、他プラットフォーム用バイナリを生成するClangもサポートする。

・Visual C#
C#処理系のマイクロソフト実装である。 FormsやWPFなど、様々なフレームワークやRADに対応している。

・Visual F#
F#処理系のマイクロソフト実装である。Visual Studio 2010以降に含まれている。

##### VIsual studioでのBuild


VISUAL STUDIO でのコンパイルとビルド


###### IDE
ビルドを即座に作成してデバッガーでテストできます。
- マルチプロセッサ ビルドを実行します (C++ や C# のプロジェクトの場合)。
- ビルド システムのさまざまな面をカスタマイズできます。

###### CMake
CMake ツールを使用してプロジェクトをビルドします
- Linux および Windows プラットフォーム全体で同じビルド システムを使用します。

###### MSBuild コマンドライン
Visual Studio をインストールせずにプロジェクトをビルドできます。
- すべてのプロジェクト タイプでマルチ プロセッサ ビルドを実行できます。
- ビルド システムのほとんどの部分をカスタマイズできます。

###### Azure Pipelines
ビルド プロセスを継続的インテグレーション/継続的デリバリー パイプラインの一部として自動化できます。
- 自動テストをすべてのビルドに適用します。
- クラウド ベースのリソースをほぼ無制限にビルド プロセスに使用できます。
- ビルド ワークフローの変更やビルド アクティビティの作成が可能です。実行するタスクを大幅にカスタマイズできます。
MySQL初心者の私がよく書き込みでハマるポイント

pythonからMySQLに書き込みを行う時、いつもハマる。
今回こそハマりどころメモしておく。

## 実施内容のイメージ
Pythonを使ってローカルのcsvをローカルにたてたMySQLやGoogle Cloud PLatformのMySQLにデータを書き込む。

## 環境
Python3
mysql-connector
GCPのCloud SQL(MySQL)(今回は)
接続方法やSSL化については今回は省略。純粋にSQL文のハマりどころについてです。

## 書き込む際のコード

```main.py
# -*- coding: utf-8 -*-
import os
import sys
import time
import glob
import shutil
import datetime
import logging
import traceback
import pandas as pd
import mysql.connector
import ssl
ssl.match_hostname = lambda cert, hostname: True
                
def insert_sql():
    schema = 'hogehoge2'#db名のこと
    connection = mysql.connector.connect(
                        port="3306",#基本はこのポートを使うことが多い
                        host='**.**.**.**',#gcpのIP
                        user='hogehoge',
                        password='fugafuda',
                        db=schema,
                        charset='utf8',
                        ssl_ca="./cloudstorage_cert/server-ca.pem",#証明書を使いたいので今回はこのフォルダにおいて指定
                        ssl_cert="./cloudstorage_cert/client-cert.pem",
                        ssl_key="./cloudstorage_cert/client-key.pem"
    )
    
    df = pd.read_csv(filename,engine="python")
    for r in range(df.shape[0]):
        cur = connection.cursor()
        sql = "insert into schema.table (col1,col2,col3,col4) values ('%s','%s',%s,%s);"%(
                    datetime.datetime.now(),
                    str(datetime.datetime.now()),
                    100,
                    1.5
                )
        print(sql)
        cur.execute(sql)
        cur.close()
        connection.commit()
    connection.close()
    print("done")

if __name__ == '__main__':
    insert_sql()
```

## 注意ポイント

### 1.テーブルを指定するとき、ちゃんとスキーマ（db）を記載する

```my.sql
ダメな例
insert into mytable (datetime,col2,col3,col4) values ('2020-10-20 10:39:13.252105','2020-10-20 10:39:13.252105',100,1.5);
いい例
insert into myshema.mytable (datetime,col2,col3,col4) values ('2020-10-20 10:39:13.252105','2020-10-20 10:39:13.252105',100,1.5);
```


### 2. 文字列や時間など数字ではないものは、SQL文の中でシングルクオートで囲む

```example.py
#ダメな例
sql = "insert into myshema.mytable (datetime,col2,col3,col4) values (%s,%s,%s,%s);"%(
                    temp.loc[r,"DateTime"],
                    str(temp.loc[r,"DateTime"]),
                    100,
                    1.5
                    )
#いい例
sql = "insert into myshema.mytable (datetime,col2,col3,col4) values ('%s','%s',%s,%s);"%(
                    temp.loc[r,"DateTime"],
                    str(temp.loc[r,"DateTime"]),
                    100,
                    1.5
                    )
```

### 3. connectionに対してcommit()しないとデータが反映されない

connection.close()は忘れないのだが、connection.commit()を忘れてデータが更新されないことがある。cur.commit()はしない。connectionでcommit()することに注意。

以上のあたりでよくハマる。sql文の最後の;はあってもなくても動作した
【React + TypeScript】プロジェクト開始時tsconfig.jsonに追記しておくべき設定2点

#はじめに
TypeScriptでReactアプリを作成する際、TypeScript設定ファイルの「tsconfig.json」に追記しておくと良い設定について記録しておきます。

アプリはnodeインストール済みの環境で以下コマンドを発行して作成したものとします。

```cmd
npx create-react-app hello-world --template typescript
```

#追記後のtsconfig.json
「**"baseUrl": "src"**」と「**"downlevelIteration": true**」を追記しています。


```hello-world/tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react",
    "baseUrl": "src",
    "downlevelIteration": true,
  },
  "include": [
    "src"
  ]
}
```

###"baseUrl": "src"
追記しておくと、`node-modules/`にインストールされていないモジュールをインポートする時（src配下に自分で作成したモジュールなど）、`src/`を起点としたパスで指定することができます。

例として`src/components/pages/home.tsx`から`src/components/atoms/button.tsx`を参照する際、この設定が無い場合相対パスをつなげて書かなければならないですが

```src/components/pages/home.tsx
import * from '../../atoms/button'
```

この設定を追記することで

```src/components/pages/home.tsx
import * from 'components/atoms/button'
```

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

###"downlevelIteration": true

コンパイルターゲットをES5以前に設定している場合（「**"target": "es5"**」）でも、ES2015から導入された便利な記述をES5以下で実行できるようよしなに書き下してくれます。
この設定が無ければ新機能を使用した記述によるコンパイルエラーが発生してしまう可能性も有るので、最初から有効にしておくと良いです。
　
　
　

以上です。お疲れ様でした:cat2:
Alpine.jsでTODO

## 概要
遅ればせながらAlpine.jsというものの存在を知ったので触りがてらTODOサンプルアプリを作ってみました。

## 完成
![Screen Shot 2020-10-21 at 20.21.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469184/805b3afe-8544-4e50-287c-a99d96bede00.png)

## コード
```html:index.html
<body>
    <main class="w-10/12 m-auto text-gray-700">
        <h1 class="p-1 font-bold">Alpine.js TODO</h1>
        <div class="todo-list" x-data="{ 
                todoList: [],
                newTodo: ''
            }" x-init="getToDo()
                    .then(response => response.json())
                    .then(list => todoList = list)">
            <ul>
                <template x-for="todo in todoList" :key="todo.id">
                    <li
                        class="w-auto flex text-center text-gray-700 bg-gray-200 hover:bg-gray-300 p-4 outline-none hover:shadow-outline mt-1">
                        <div class="w-1/2 flex-1 break-words" x-text="todo.title"></div>
                        <div class="w-20 flex-1">
                            <label>Done</label>
                            <input type="checkbox" class="form-checkbox bg-teal-500 mt-1" :checked="todo.done">
                        </div>
                        <div class="w-20 flex-1">
                            <button
                                class="h-8 bg-pink-300 hover:bg-pink-600 focus:outline-none focus:shadow-outline rounded pr-1 pl-1 pb-1"
                                @click="todoList = todoList.filter(t => t.id !== todo.id)">remove</button>
                        </div>
                    </li>
                </template>
            </ul>
            <div class="add-todo flex justify-end mt-1">
                <input type="text" placeholder="write a thing to do" x-model="newTodo"
                    class="bg-gray-200 hover:bg-gray-300 hover:border-gray-300 outline-none hover:shadow-outline rounded-lg mr-1 pl-2" />
                <button class="bg-teal-500 hover:bg-teal-600 focus:outline-none focus:shadow-outline rounded p-1"
                    @click="if (!newTodo) return;
                                todoList.push({
                                    id: Math.max.apply(null, todoList.map(t => t.id)) + 1,
                                    title: newTodo,
                                    done: false    
                                });
                                newTodo = '';
                            ">Add</button>
            </div>
        </div>
    </main>
</body>
```

Vue.jsと似てるのでそれほど苦もなく使えそうです。
難点はHTML直書きなのでロジックが追い辛い点ですかね。

ポイントとしては
・ 外出しした関数などはGlobalに置く
・ x-dataのネストには未対応
という点だと思いました。

サンプルコードをあげているのでよかったらどうぞ。[link](https://github.com/SakaiBorder/alpine-todo)

## 参考
[Alpine.js](https://github.com/alpinejs/alpine)
[Alpine.js - nested components](https://stackoverflow.com/questions/61851410/alpine-js-nested-components)