OmniAICreator/Qiita-1.07M huggingface dataset:
TypeScript+Reactでpropsを使ってコンポーネントにデータを渡す流れ

Reactでコンポーネントにデータを渡す流れのメモ。
ソースは[こちら](https://github.com/captain-blue210/react-study)

## サンプル概要
- 書籍の一覧を表示する
- 表示するのは、書籍名と著者名
- 書籍のデータは決め打ちとする

## コンポーネント概要
- App.tsx
- Book.tsx・・・書籍情報（書籍名と著者名）を表すコンポーネント
- BookList.tsx・・・Bookコンポーネントを一覧で表示するコンポーネント

## propsを使ってコンポーネントにデータを渡す

- コンポーネントにデータを渡すためのpropsに使う型（Book.tsx）を定義する

```react:Book.tsx
export type Book = {
    id: number;
    name: string;
    author: string;
}

```

- `BookList`コンポーネントのpropsの型として、上記で作成した型を指定する

```react:BookList.tsx
import React, { FC } from 'react';
import { Book } from './Book';
import { Item } from 'semantic-ui-react';

type bookProps = {
    books: Book[];
}

const BookList: FC<bookProps> = (bookProps) => {
    const { books } = bookProps;

    return (
        <Item.Group>
            {books.map((book) => (
                <Item key={book.id}>
                    <Item.Content>
                        <Item.Header>{book.name}</Item.Header>
                        <Item.Meta>{book.author}</Item.Meta>
                    </Item.Content>
                </Item>
            ))}
        </Item.Group>
    );
};

export default BookList;

```

- Appコンポーネントにて書籍情報をBookListコンポーネントに渡す

```react:App.tsx
import React, { FC } from 'react';
import { Book } from './Book';
import BookList from './BookList';
import './App.css';

const App: FC = () => {
  const books: Book[] = [
    {
      id: 1,
      name: '独学大全',
      author: '読書猿'
    },
    {
      id: 2,
      name: '数学ガールの秘密ノート／場合の数',
      author: '結城浩'
    },
    {
      id: 3,
      name: 'アジャイルサムライーー達人開発者への道',
      author: 'Jonathan Ramusson, 西村直人'
    }
  ];

  return (
    <div className="container">
      <header>
        <h1>書籍一覧</h1>
      </header>
      <BookList books={books} />
    </div>
  );
}

export default App;
```
【Ruby】　returnの使い方について



#returnとは？？

メソッドの戻り値を返す方法。制御構造に分類される。Rubyにおいては、`return`をわざわざ使用せずとも、定義したメソッドにおいて、最後に処理された値が返ってくる。

しかし、途中で処理を抜け出したい場合は、`return`を使用することで、強制的に値を返すことができる。

##例題

###■returnを使用しない場合

```
def total
  price = 1000
  num = 10

  "#{price}円の服を#{num}枚購入したので、合計は#{price*num}円になります。"
  "1枚返品したので、合計は#{price*(num-1)}円になりました。"
end
p total
```

###結果

```
1枚返品したので、合計は9000円になりました。
```
`return`を使用しない場合、最後に定義した文言が出力されます。


###■returnを使用する場合

```
def total
  price = 1000
  num = 10

  return "#{price}円の服を#{num}枚購入したので、合計は#{price*num}円になります。"
  "1枚返品したので、合計は#{price*(num-1)}円になりました。"
end
p total
```

###結果

```
1000円の服を10枚購入したので、合計は10000円になります。
```

`return`を使用すると、`return`後に定義した文言が出力されました。

このように、もし途中で処理を抜けたい場合は`return`を活用すると良いでしょう。
ちなみにまだ私は`return`を使用する場面には遭遇していません、、、笑
【rails】first_or_initialize

first_or_initializeについて学習したため、アウトプットいたします。

first_or_initializeとは？
first_or_initializeの使い方は？

の順に記述します。

#first_or_initializeとは？
whereで検索した条件のレコードが存在すればそのレコードのインスタンスを返し、存在しなければ新しくインスタンスを作るメソッドです。

と言ってもなかなかわかりませんよね。
詳しく説明します。

例えば、
studentというテーブルがあったとして、そこのデータベース上に１０人の名前がそれぞれ登録されていたとします。

first_or_initializeメソッドは、
そのデータベース上にそのstudentがいなかった場合→そのstudentを新規登録します。
一方、
studentがすでに登録されていた場合→その生徒の情報を取ってきます。

少しづつわかってきましたか？

すなわちこのメソッドの特徴は
「データの重複を避けること」なんです。

ではどうやって使うのでしょうか？

#first_or_initializeの使い方

```csharp

student = Student.where(name: "佐藤").first_or_initialize
```

存在しなければ新しくインスタンスを作りたいオブジェクトを定義し、
その後に
where(条件）.first_or_initialize
とすると完成です。

上記の例では、
そのデータベース上に佐藤さんがいなかった場合→その佐藤を新規登録します。
一方、
佐藤さんすでに登録されていた場合→佐藤さんの情報(id, age等定義したもの)を取ってきます。
メソッドについてのアウトプット　その２です

#メソッドのアウトプット　その２　引数です

その１ではメソッドをの中でif文を使用してみました。

####※前回の記事です。[メソッドについてのアウトプットです　その１](https://qiita.com/yuzo-taguti/items/356385d3fd3a5b0a0d6e)

今回は引数を使って、もう少しコードをすっきりしたいと思います！

前回のコードです。

```sample.rb
def register
  eraser = 110
  pen = 150
  bill = eraser + pen
  if bill >= 200 #200円以上のお買い上げは10%off!!
    bill * 0.9
  end
end
  puts register　#registerメソッドを呼び出す。
```

こちらの
`` eraser と pen ``の数値をメソットの外で定義してみます。

```sample.rb
def register
  eraser = 110　#　ここの数値
  pen = 150 # ここの数値
  bill = eraser + pen
  if bill >= 200
    bill * 0.9
  end
end
  puts register
```
``def register``の後ろに``()``を追加してその中に
`` eraser `` と `` pen `` を入れてあげます。

```sample.rb
def register(eraser, pen) #　eraserとpenの間に　カンマ(,)と半角スペース
  # eraser = 110 ここは削除
  # pen = 150　ここは削除
  bill = eraser + pen
  if bill >= 200
    bill * 0.9
  end
end
  puts register(150, 100) #　ここに数値をいれる
```

`` puts register(150, 100) `` この二つの数値は
`` def register(eraser, pen) `` ここに送られます。
それぞれ　`` eraser `` には　`` 150 ``
`` pen `` には `` 100  ``
が送られます。

```sample.rb
def register(eraser, pen)
  bill = eraser + pen
  if bill >= 200
    bill * 0.9
  end
end

puts register(150, 100)
```

すこしだけすっきりしましたね！（多分）

今日のアウトプットでした。:sweat:
【Android Studio】アプリからメーラーを起動するやり方が変わっていたので対応した【Kotlin】

こちらの教本を参考にアプリからメーラーを起動しようとしたのですが、うまくいかなかったので、調べたことをメモ。
[[作ればわかる！Androidプログラミング Kotlin対応 10の実践サンプルで学ぶAndroidアプリ開発入門](https://amzn.to/2TqSwIu)]



#【環境】
Mac OS Catalina 10.15.7
Android Studio 4.0.1

#【やったこと】
教本に載っていたいやり方はこちら。(文の内容は変更しています）

```kotlin:MainActivity.kt
val subject = "${getString(R.string.app_name)}から送信します"
val text = "本文です。"
val uri = Uri.fromParts("mailto","someone@gmail.com", null)
val intent=Intent(Intent.ACTION_SENDTO,uri)
    intent.putExtra(Intent.EXTRA_SUBJECT,subject)
    intent.putExtra(Intent.EXTRA_TEXT,text)
if(intent.resolveActivity(packageManager)!=null){
    startActivity(intent)
}
```

実機でRunしてみるもメーラーが起動できず...
調べてみると、同じ症状について書かれている方を発見しました。
[[いつの間にかメーラーを起動するIntentの推奨形式が変わっていて件名や本文が入力されなくなっていたので対応した](https://qiita.com/masaibar/items/4edcc9c7d2df11fe6e79"いつの間にかメーラーを起動するIntentの推奨形式が変わっていて件名や本文が入力されなくなっていたので対応した")]

他にも。
>はっきりとしたドキュメントはないのですが、API29というかAndroid 10からIntentの扱いが大きくかわったようです。このメーラーもIntentで簡単にメールを送信する方法なので以前の方法とは異なっています。
[[Android] アプリに mailer 呼び出しを設定する](https://akira-watson.com/android/mailer.html)

デベロッパーガイドを読んでみると、確かに書き方が変わっていました。
https://developer.android.com/guide/components/intents-common?hl=ja#ViewContact


ガイドを参考に修正した内容がこちらです。

```kotlin:MainActivity.kt
val intent = Intent(Intent.ACTION_SENDTO).apply {
    data = Uri.parse("mailto:")//メールアプリのみで処理したい時に記述
    val subject = "${getString(R.string.app_name)}から送信します"
    val text = "本文です。"
    putExtra(Intent.EXTRA_EMAIL, arrayOf( "someone@gmail.com" ))//第二引数はArrayにしないと入力されないので注意
    putExtra(Intent.EXTRA_SUBJECT, subject)
    putExtra(Intent.EXTRA_TEXT,text)
}
    if(intent.resolveActivity(packageManager)!=null) {//インテントを処理できるアプリが存在するか確認
     tartActivity(intent)//処理するアプリがいないのにstartActivityするとアプリが強制終了するので注意
}
```
#【結果】
メーラーが起動できるようになりました！
（「Our Menu」はアプリ名です）
![Screenshot_20201027-224836.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704563/c3f9fa78-49ee-3f3d-b08b-c5db0c91a8e4.jpeg)
Windows10へのGoogle Cloud SDKインストール失敗

Google Cloud SDKをWindows10に最新のインストーラー（今現在、2020/10)からインストールしようとすると、インストールが途中で止まります。
最新のインストーラーだと、ネットにあった解決法を試みてもすべて失敗したので、先人が解決したのと同じ古いバージョンに戻して解決しました。

①https://qiita.com/qrusadorz/items/264b5a9f1d8b5ea90416
　このサイトにあるように、google-cloud-sdk-273.0.0-windows-x86_64-bundled-python.zip
　をダウンロードする。
　ダウンロードしたzipファイルは、C:\Program Files (x86)\Google\Cloud SDK以下に展開した。
　最初はC:\Users\〇〇\AppData\Local\Google\Cloud SDKに展開したが、〇〇が日本語名であり、
　インストール時に日本語名が文字化けしてエラーになったので、C:\Program Files (x86)\・・・
　に展開した。

②https://qiita.com/hirocueki2/items/1789998804c4e7ec1ef3
PowerShellで環境変数を設定

```
$env:CLOUDSDK_PYTHON="C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\bundledpython\python.exe" 
```

C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\bundledpython\Lib\site-packagesに下記を置く

```ruby:sitecustomize.py
import sys
sys.setdefaultencoding('shift-jis')
```
③https://qiita.com/yuxzux/items/b14d55311b7826cdde7c
C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\install.bat
47行目あたりを書き換える

`修正前`
　SET CLOUDSDK_PYTHON=%%i
`修正後：日本語を入れるとエラーが起きたので、相対パスで`
　SET CLOUDSDK_PYTHON=".\platform\bundledpython\python.exe"

④インストールを行う

```
cd "C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk"
.\install.bat
```

⑤環境変数を書き換える（これをやらないと、後に実行するgcloudコマンドがエラーになる）

```
 $env:CLOUDSDK_PYTHON_SITEPACKAGES="C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\bundledpython\Lib\site-packages"
```
フォルダ内のcsvファイルを全て読み込み

#概要
csvファイルが時期毎や属性毎に分かれていたりする場合があり、それらのファイルを一行で読み込めるようにするべく、実装しました。
目的の機能は以下の通りです。
・フォルダ内のcsvファイルを全て読み込む。
・指定の文字を含むcsvファイルのみ対象とすることも出来るようにする。
・下位ディレクトリも含められるようにする。

#実行環境
・Windows10 64bit
・Python 3.8.3
・pandas 0.25.3
・seaborn 0.11.0

#実装
##1.データ準備
irisデータ（150件）を4分割して、csvファイルとして保存（Eドライブ直下の"main"フォルダ）。また、"main"フォルダ内の”sub”フォルダにも同じファイルを保存。

```python
import seaborn as sns
data = sns.load_dataset('iris')

import os
os.makedirs(r'E:\main', exist_ok=True)
for i in range(4):
    st = int(0 if i==0 else (len(data)/4)*i)
    en = int((len(data)/4)*(i+1))
    
    data.iloc[st:en].to_csv(r'E:\main\iris{}.csv'.format(i), encoding='cp932', index=False)
    

os.makedirs(r'E:\main\sub', exist_ok=True)
for i in range(4):
    st = int(0 if i==0 else (len(data)/4)*i)
    en = int((len(data)/4)*(i+1))
    
    data.iloc[st:en].to_csv(r'E:\main\sub\iris{}.csv'.format(i+4), encoding='cp932', index=False)
```

##2.csvファイル読み込み
結果としては、以下の関数にて実装しました。

```python
import glob
import pandas as pd
def read_csv(path, encode, sub_check=False, target_name=None):
    #フォルダ内全てのcsvファイルのパスをlistで取得
    #sub_check=Trueならサブフォルダまで対象
    target_files = glob.glob(path+r'\**\*.csv', recursive=True) if sub_check else glob.glob(path+r'\*.csv')

    #結合後のファイル格納用
    merged_file = pd.DataFrame()

    #対象のcsvファイルを全て結合
    for filepath in target_files:
        
        #ファイル名に指定の文字を含まなければ対象外とする
        filename = filepath.split('\\')[-1]
        if target_name!=None and target_name not in filename: continue        
    
        #一つのcsvファイルを読み込み
        input_file = pd.read_csv(filepath, encoding=encode, sep=",", engine='python')
        
        #一つのcsvファイルを今までに読み込んだcsvファイルへ結合
        merged_file = pd.concat([merged_file, input_file], axis=0)

    #結合後のDataFrameのindexをリセット
    merged_file = merged_file.reset_index(drop=True)
    
    return merged_file
```

#動作確認
##1.一つのフォルダ内のcsvファイル読み込み
一つのフォルダ内のcsvファイル（150件）を全て読み込めました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667730/178fb35b-768e-7d03-7d86-21a815f4c602.png)

##2.一つのフォルダ内のcsvファイルで指定ファイルのみ読み込み
target_nameに"1"を指定すると、名前に”1”を含むcsvファイル（38件）を読み込めました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667730/d84f8df8-70e6-3f00-46fe-bbbaa8ebdc1f.png)

##3.下位ディレクトリも含めてファイル読み込み
sub_check=Trueとすれば、下位ディレクトリの"sub"フォルダも含めて、csvファイル（300件）を全て読み込めました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667730/3d7ba7ac-d105-7487-cbbe-900cd389d233.png)

#　
以上、閲覧頂きありがとうございました。
Tigを導入して今日から君もSourceTree離れしよう！！

# この記事の対象者

普段からSourceTreeを使用している方

## Tigとは

Gitの履歴や差分を可視化してくれる超絶便利な機能です。
https://github.com/jonas/tig

Homebrewを導入している場合は、`brew intall tig`でインストールすることができます。

## SourceTreeから離れてTigを使おうと思ったきっかけ

1. リポジトリの容量が重いとSourceTreeがフリーズする
2. SourceTreeの起動速度が遅い
3. SourceTreeが度々モサモサする
4. 最初の初期設定云々がめんどくさい
5. めんどくさい
6. Dockerの中に入っているフォルダがSourceTreeで管理できないことがあった（設定でできる様です）
7. VSCodeからそのままGIT操作がしたかった
8. なんかカッコいい
9. なんか黒い画面から操作してるとカッコいい
10. スタバとかで黒い画面操作してるとカッコいい

## そもそもSourceTreeでは大した操作はしていなかった

普段の操作例

- コミット
- プッシュ
- フェッチ
- プル
- チェックアウト
- マージ
- リセット

ぐらいでした。

これをコマンドで入力すると

```terminal
コミット
git commit or git commit -m "コミット内容"

プッシュ
git push （リモートと紐付けできていればこれでOK）

フェッチ
git fetch

プル
git pull

チェックアウト
git checkout <branch>

マージ
git merge <branch>

リセット
git reset --soft HEAD^
```

結構簡単ですね！！

## 具体的にTigを使用すると何ができるのか

コマンド入力例から見てみましょう！

`tig`を入力すると現在のブランチの履歴がターミナルから閲覧できます。
![スクリーンショット 2020-10-27 22.32.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497005/b3560483-6ade-9207-b680-b663309efe5c.png)

キーボードの矢印もしくは`J,K`で上下することができEnterを押すと詳細な変更点を閲覧することができます。
![スクリーンショット 2020-10-27 22.36.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497005/b780270a-38a2-7f74-7140-cbd63cd9b687.png)

一枚目のスクショのときに`cmd+s`で`untracked, changed, commited`のファイルをそれぞれ閲覧することができ、commitedにしたい時は`u`でcommitedにすることができます。ファイルの上でEnterを押すと詳細な変更点を閲覧することができます。
![スクリーンショット 2020-10-27 22.38.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497005/614b1732-81e5-2c9c-5447-48d6cf1919f9.png)

commitしたいファイルをcommitedに移動したら`cmd+c`でコミット画面を表示することができます。
![スクリーンショット 2020-10-27 22.42.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497005/59f144e6-70ff-dab3-7ba8-5aa9b06a22d5.png)

vimの操作で`i`で編集モードに入り、`control+c`で編集を終了します。
コミット内容に問題がなければ`:wq`でコミットを確定します。

その後はターミナルから`git push`でリモートにpushすることができます。

初めのうちはTigの操作というよりはVimの操作に手こずりますが、Vimを覚えておくとDockerの中のファイルを編集したりするときにスムーズに作業が完了するので覚えておいて損はないとおもいます。

## ターミナルからGIT操作することに何を抵抗を感じるのか

私もそうだったのですが、なんとなく色付きでリッチに履歴を見たい！
GUI操作のほうが簡単！
周りの人はみんなSourceTreeを使っているから！！
なんかこわい。
コマンド操作が分からない。
なんか黒い画面がこわい。

というのが主な理由でした。

## 最後に

最初はSourceTreeから離れるのが不安だと思います。
その場合はSourceTreeとターミナルを併用して両方からGit操作することをオススメします。
徐々にターミナルを使用することで抵抗感なく移行することができるようになるとおもいます。
複数のGithubアカウントの運用方法

私は今、Githubのアカウントを会社用とプライベート用で2つ管理しています。

複数管理していて困ることは、このプロジェクトはプライベートアカウントで管理したいけどどうすればいいんだっけ:dizzy_face:ってなるので管理方法を説明していきたいと思います。

## global設定の確認
global設定というのは、全てのGitコミットに使われるメールアドレスとユーザー名などの情報です。
基本的にプロジェクトを作成し、何も設定を変えずにコミットするとこの情報でコミットが作成されます。

```
> git config --global --list
user.name=hogehoge
user.email=hoge@example.com
ui.color=auto
push.default=current
```

このコマンドを実行することでglobal設定を確認することができます。
ここはよく使うアカウントの情報を設定しておくのがいいと思います。設定を更新するには

```
git config --global user.name "fuga"
git config --global user.email "fuga@example.jp"
```
とすると変更できます。

## local設定を行う（プロジェクトごとにGithubのアカウントを変える）
global設定のアカウントと異なるアカウントでGitを管理したいプロジェクトのディレクトリで以下のコマンドを実行します。

```
git config --local user.name "fuga"
git config --local user.email "fuga@example.jp"
```

設定が変更されたかを確認する場合は

```
git config --local --list
```

これでプロジェクトごとにアカウントを切り替えることができます。

## シェルの作成
ただ、毎回プロジェクト作成時に上記のコマンドを打つのが面倒なためシェルを作成しています。

1. シェルファイルを作る
自分のわかりやすいディレクトリで(私はsettingフォルダを作ってそこに置いています）

```
touch gitSetting_private.sh
```

これで空のシェルが作れます。

2.コマンドを羅列する
先ほど作ったファイルにコマンドを書き保存します。このシェルを実行することでここに記述したコマンドが実行されるようになります。

```gitSetting_private.sh
git config --local user.name "fuga"
git config --local user.email "fuga@example.jp"
```

3.シェルの実行
プライベートアカウントで管理したいプロジェクトのディレクトリに移動し、シェルを実行します。

```
// 権限を付与しないと実行できないため、権限を付与する
> chmod +x ~/work/setting/gitSetting_private.sh
// シェルの実行
> ~/work/setting/gitSetting_private.sh
```

設定ファイルを作成しておくことで以降はこのシェルを実行すれば設定することができます。
そのため、プライベート用と会社用の2つのシェルを準備しておけば便利かと思います！
syslog (rsyslog) の出力をコマンドに送る

最も単純な例。

```shell:/usr/local/bin/hoge.sh
echo "# $1 #" >> /var/log/hoge.log
```

にログを送りたい場合。

```conf:/etc/rsyslog.d/hoge.conf
$template sample_templ, "%msg:2:$%"
auth,authpriv.*    ^/usr/local/bin/hoge.sh;sample_tmpl
```

とすると、/var/log/auth.log に送られる内容が hoge.sh にも送られる。

* template を使用しないと、最後に改行がつく
* %msg% の先頭に1文字空白が入っているので、2文字目以降を出している

```text:/var/log/auth.log
Oct 27 22:28:36 EXELION-X1 su: (to ken) root on tty2
Oct 27 22:28:36 EXELION-X1 su: pam_unix(su:session): session opened for user ken by (uid=0)
Oct 27 22:28:36 EXELION-X1 su: pam_unix(su:session): session closed for user ken
```
```text:/var/log/hoge.sh
# (to ken) root on tty2 #
# pam_unix(su:session): session opened for user ken by (uid=0) #
# pam_unix(su:session): session closed for user ken #
```

^ を使うより "omlog" を使うほうが今風らしい。
https://www.rsyslog.com/doc/master/configuration/modules/omprog.html
クラウドネイティブPCを試してみよう①　～クラウドネイティブPCとは～

# はじめに
現在ほとんどのお客様は、**社内ネットワークを整備してそこに PC をつなぐ**、という IT 環境をご利用しているかと思います。しかし近年、クラウド利用の急増によるパフォーマンスの低下やコストの上昇、標的型攻撃による侵入など、社内ネットワークに起因する問題も多く見られるようになってきています。

このため、最近はこれらの問題を解決すべく、**PC を社内ネットワークではなく、インターネットに直接つなぐ**、という構成（これを**クラウドネイティブPC**と呼んでいます）を推奨しております。これまでセキュリティ上実装が難しかった構成ですが、Microsoft 365 の最新機能を利用することで実現可能となっております。

本稿ではその第一歩として、**クラウドネイティブPCを実際に構築し、動作を確認する**を実際に作ってみる手順をご紹介いたします。本稿がクラウドネイティブPC検討の一助となれば幸いです。



##目次（計画編）
[その１　キックオフ](https://qiita.com/nextread/items/d889c77bf415e2632fb3)
[その２　環境準備](https://qiita.com/nextread/items/a828f8b745d64b34d942)

##目次（構築編）
[その１　デバイス登録](https://qiita.com/nextread/items/76fe970a27c540619552)
[その２　エンドポイントセキュリティの設定](https://qiita.com/nextread/items/373eadcf30f897528dbf)
[その３　認証セキュリティの設定](https://qiita.com/nextread/items/efc0017329fd0fa16d4d)
[その４　クラウド　アプリ　セキュリティの設定](https://qiita.com/nextread/items/7a19088af643682c31bb)
CodeBuildのキャッシュ方法について

##はじめに

CodeBuildを使ってビルドシステムを作る際にキャッシュ周りについて調べたのでそれについて記載していきます。

今回調査した時は中間生成データをまるっとキャッシュしたかったのでS3キャッシュとカスタムキャッシュモードの調査をしました。

ちなみに結論としてはS3キャッシュを使う方法が採用されました。

##対象読者

CodeBuild使ってみようと思う人。

##内容

### キャッシュ方法

以下の通り。

#### S3キャッシュ

- buildspecに指定した対象をS3にキャッシュする
- S3との通信が発生するため、中規模以上で低頻度でビルドをするプロジェクト向け
  - キャッシュ対象物がそもそも少ないとキャッシュから復元する方が時間がかかったりする
- S3にキャッシュするので複数のCodeBuild間で利用できる

#### ローカルキャッシュ

##### ソースキャッシュモード

- Gitのメタデータをキャッシュするモード
- キャッシュ後はコミット間の変更のみが適用される

##### Docker レイヤーキャッシュモード

- Docker Imageのキャッシュをしてくれる
- Linuxでのみ利用可能
- privilegedフラグを設定するようにする必要がある

##### カスタムキャッシュモード

- S3同様にbuildspecで指定した**ディレクトリ**がキャッシュされる
- キャッシュされたディレクトリはシンボリックリンクでリンクされる
  - ソースのダウンロードよりも先なので同じ名前のものをキャッシュしていると上書きされる
- 単一のCodeBuild内でのみ利用が可能

### 使い方

buildspecの参考は以下。

大事な点はパスの指定の仕方。

公式は[こっち](https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-spec-ref.html#build-spec-ref-syntax)。

```yaml
version: 0.2

phases:
    install:
        commands:
        	- echo test

cache:
    paths:
        - ./example/**/* # recursiveに設定しないとディクレトリだけがキャッシュされる
```

### 注意点

S3キャッシュとローカルキャッシュの併用はできないので、キャッシュしたいものについてはしっかり精査する必要がある。

##終わりに

ローカルキャッシュも使おうとしたがどうもうまく動作せず。

ドキュメントにも動作する条件が書いてなくて、Stack Overflowに[有志が調べた条件的なの](https://stackoverflow.com/a/59070807)があるけども確認できてない。
RubyOnRails Udemyの無料講座でエラーが発生、それを解決、最後まで貫く

# RubyOnRails Udemyの無料講座でエラーが発生、それを解決、最後まで貫く

RubyOnRails学習をはじめた人で以下のUdemyの無料講座を受講したが、エラーで躓き最後まで修了できなかった方々のために、身をもって経験したエラーと解決方法を共有します。

[【最短30分でできる!】Ruby on Rails入門: 初心者でも簡単! ブラウザ](https://www.udemy.com/course/paizacloud-ruby-on-rails/)

##エラーが発生した時点-1
1.「14. 画像ファイルの追加、編集機能の追加」のコース
![スクリーンショット 2020-10-27 200600.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/31674e0c-a921-9d18-a29e-740a68c862f0.png)

2. ターミナルにて「rake db:migrate」を打ち込んだ時点でターミナルにエラーが発生した。
![スクリーンショット 2020-10-27 212832.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/0c07c5bb-71e1-5302-2ff0-ed01adf3f9e7.png)

3. localhost:3000 にても「ActiveRecord::PendingMigrationError」というエラーが発生した。
![スクリーンショット 2020-10-27 213027.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/dfcf97de-2adf-5229-e470-ba6c8f44d1b1.png)

##原因、解決方法-1
原因は'paperclip'がrailsのバージョンに依存しているからだ。
よく確認したところ、講座はRubyonRails 5.2をベースにしているとの記載があった。
僕の方だと、現時点でPaizaCloudはRubyonRails 6系が標準になっていた。

1.ターミナルにて「gem list rails」を打ち、railsのバージョンを確認しよう。
![スクリーンショット 2020-10-27 211106.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/067fb8e4-81fa-7bc8-9ccb-7c767b3f87bc.png)
＊僕の場合のバージョンは
　6.0.2.1,
　5.0.7.2,
　5.0.6
だった。 

2.プロジェクトを新たに作成しよう。
＊講座としては、「9.プロジェクトの作成」に戻ろう。
![スクリーンショット 2020-10-27 210901.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/01f8bb98-e2db-499b-889c-686c7a7aa1e4.png)

3.ターミナルにて、「rails _(version)_ new boardgame-app --database=mysql」を打ち、RubyOnRails 5系を使用するプロジェクトを作成する。
![スクリーンショット 2020-10-27 211203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/a694cd5c-8425-bd39-ca2f-1ae3155db524.png)
＊僕の場合は、RubyOnRails 5.0.7.2 を使用した。

##動作確認-1
1.講座の通り進もう。

2.「14. 画像ファイルの追加、編集機能の追加」のコースにて、動作を確認したところ、エラーなく進行された。localhost:3000 にても問題なし。
![スクリーンショット 2020-10-27 195849_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/c1d4a84c-021c-7b69-dc09-97c523e9595a.png)

ーーー

##エラーが発生した時点-2
1.「14. 画像ファイルの追加、編集機能の追加」のコース
![スクリーンショット 2020-10-27 200405.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/b39b0791-07f8-820b-a03d-bd13c13a304a.png)

##原因、解決方法-2
原因は不明だが、他と違って「<%= from...」を使っていることが原因のようだった。
![スクリーンショット 2020-10-27 200428_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/0a6a8628-ed57-6a24-7aa3-6e75c42b92cc.png)

1.「<%= from...」を「<%= f...」に書き換える。
![スクリーンショット 2020-10-27 200443_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/f11740c2-028a-5c47-0fb0-9eabf4a06183.png)


##動作確認-2
1. localhost:3000にて問題なく表示された。

ーーー

**Laravelも同じだと思うが、バージョンによる予期せぬ不備（記述方法が異なったり、packageが使えなくなったりする等）が多々あった。エラーに遭っても挫折せず、皆が力を合わせ取り組んで解決したら良いと思う。**

無料講座はエラーに遭遇した時でも、講師に質問ができないことがある。
本投稿がRubyOnRailsを学習始めている方々が諦めずに最後まで貫くための原動力になることを祈る。
Java SE Bronze 試験番号： 1Z0-818 （ループ文　編）（2020年10月）

公式サイト: [Java SE Bronze](https://education.oracle.com/java-se-bronze-available-only-in-japan/pexam_1Z0-818 "Bronze")


![oracle.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/00aa6754-3fc9-7b81-c61d-644274046f99.png)

#目的
:cherry_blossom: **Java Bronze SE 合格** :cherry_blossom:
#目次


> 1, [while](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/while.html)文の使用
> 2, [for](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html)文および拡張for文の使用
> 3, [do-while](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/while.html)文の作成と使用
> 4, ループのネスティング

![oracle java.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/c177205a-569d-647a-980e-d44a0df71bf4.png)
公式サイト: [The Java™ Tutorials](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/flow.html "Bronze")

#1, [while](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/while.html)文の使用

>while文　while(**条件**）：条件が**true**である限り、無限ループします。

```ruby:WhileDemo.java
class WhileDemo {
	public static void main(String[] args) {		
		int count = -10;
		while(count < 1) {
			System.out.println("Count is : " + count);
			count++;
		}
	}
}
```

# 2, [for](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html)文および拡張for文の使用

>for文

```ruby:ForDemo.java
class ForDemo {
	public static void main(String[] args) {		
		for(int i = 0; i < 11; i++) {
		System.out.println("Count is : " + i);
	}
}
```

>拡張for文

```ruby:EnhancedForDemo.java
class EnhancedForDemo {
	public static void main(String[] args) {
		
		int[] numbers = {1,2,3,4,5,6,7,8,9,10};
		for(int item : numbers) {
			System.out.println("Count is : " + item);
        }
	}
}
```

# 3, [do-while](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/while.html)文の作成と使用

>do-while文　条件に関わらず、一度は表示する。

```ruby:DoWhileDemo.java
class DoWhileDemo {
	public static void main(String[] args) {		
		int count = 1;
		do {
			System.out.println("Count is : " + count);
			count++;
		}while(count < 11);	
	}
}
```

#4, ループのネスティング

>ネスティング　for文の中にfor文を記述。下記のソースコードは九九を表しています。

```ruby:Nesting.java
class NestingDemo {
	public static void main(String[] args) {		
		for(int i = 1; i < 10; i++) {
			for(int j = 1; j < 10; j++) {
				System.out.print((i * j) + ",");	
			}
			System.out.println("");	
	}
}
```

#備考
1, [データの宣言と使用　編](https://qiita.com/iwasaki-hub/items/785572dfa89c60d3bdcb)
2, [ループ文　編](https://qiita.com/iwasaki-hub/items/fdbcb6b3acc75776a906)
Firefox/Chrome拡張機能のポップアップ内ではOnclickは働かないので他の方法を使おう

## 概要
拡張機能アイコン(ツールバーにあるやつ)をクリックして出てくるポップアップは、`browser_action`内の`default_popup`にHTMLファイルを指定することによって作る。

```manifest.json
"browser_action":{
    "default_icon": {
        "48" : "48.png"
    },
    "default_popup": "popup.html"
}
```

だがこのHTMLファイル内においては、`Onclick`は使えない。
ポップアップ内において、インラインのJavaScriptは許可されていないのだ。

## 対処法
`DOMContentLoaded`を使う。
まずHTMLファイル内の`Onclick`を動作させたかったタグにIDを割り振る。
以下に例を示す。

```html
<!--置換前-->
<a Onclick="hoge()">hoge</a>

<!--置換後-->
<a id="hoge">hoge</a>
```

JavaScriptのコードは外部ファイル(ここでは`hoge.js`とする)に以下のように書く。HTMLファイル内に`<script src="hoge.js"></script>`を書くのを忘れないよう注意。

```hoge.js
document.addEventListener("DOMContentLoaded", function(){
    var hoge = document.getElementById("hoge");
    hoge.addEventListener("click", function(){
        // ここに処理を書く
    });
});
```

ちなみにこのJSファイルは`manifest.json`内の`content_scripts`に書かなくても動く。

## 参考
https://stackoverflow.com/questions/13591983/onclick-or-inline-script-isnt-working-in-extension
https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy
MAC Linux　環境構築　エラーメモ

#目的

Linux導入時にでたエラー
#環境

・Mac OS catalina ver10.15.7
・VirtualBox　ver6.0.14
・Vagrant 

#使用したアプリケーション



・iTerm2

https://www.iterm2.com/

・VirtualBox　ver6.0.14
https://www.vagrantup.com/ 

#エラー箇所
```

vagrant box add ubuntu/bionic64 --box-version 20200130.1.0
```
installを行うとセキュリティーとプライバシーから機能拡張からブロックされました
と表示されるので”セキュリティー”環境設定から開き

![スクリーンショット 2020-10-27 20.58.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/777595/82042af9-31fb-117a-d51c-374a56eb2861.png)

閉じちゃった時は🍎マークからシステム環境設定へ

許可をしておかないとinstallに失敗しこんなエラーがでた

```
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["startvm", "06d68c13-7910-4f8f-a263-e9424395d7cf", "--type", "headless"]

Stderr: VBoxManage: error: The virtual machine 'username_default_1549175601821_34118' has terminated unexpectedly during startup with exit code 1 (0x1)
VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component MachineWrap, inter
```
許可しておく事で解決しました。





この記事は以下の情報を参考にして執筆しました。
> 引用
[Vagrant upでエラーが出て躓いた時の解決方法](https://qiita.com/nemui_/items/e6eb45210c173651b6ff)

まとめ
---
・調べて先人様の知恵を参考にさせていただきました
・エラー文をよく読んで考える
JavaScriptの魅力をなるべく簡単にまとめてみた！

この記事は、初心者である私が「jsの魅力、伝えたいなぁ」と思って書いた記事です。
一応初心者にも理解できるようにはしていますが、多分以下の知識を持っている人じゃないと完全に理解できないと思います。

+ HTMLをある程度記述できる
+ ある程度ITについての知識がついている(P検3級程度)

これがわからなくても、できる限りわかるようにはしているので、わからない部分はネットで調べてより詳しい情報をみて理解していってください()
<br>
さて、先ほども言ったように、私は初心者な訳です。
初めてプログラム言語を触ったのは、今から1年半ぐらい前になりますかね。まぁ、プログラム言語を学ぶにあたって、自分が使うプログラム言語を決める必要があるのですが、ネット上では
「JavaScript(以下、js)がおすすめだよ！」
という声が多いと感じましたし、私も一番最初はjsをいじりました。
<br>
まぁしばらくはいろんなプログラム言語を触った訳なんですが、やっぱりjsに戻ってきましてね。せっかくだし、jsの参考書でも購入するかということで、買ってみたんですが、その参考書が結構当たりだったんです。今まで当たり前だと思ってたものが違ってたり、その逆もあったり。また、コードの行数を減らすためのテクニックとか、色々なことが書いてあったんです。
<br>
そこで今回は、その参考書からも多少抜粋して、jsの代表的な特徴について紹介してきます。
<br>
# 1,書いてすぐに動かせる
よく、「jsは初心者向けプログラム言語だよ」と言われるのですが、その根拠のひとつがこれだと感じます。
例として、C言語はコンパイラ言語ですので、一度書いたコードはコンパイルして、その後、コンパイルし終わったファイルを実行する訳ですが、ここまでの作業がめんどくさいという人もいるかも知れません。
もっと極端な話、C言語はコンパイラとかデバッガとか、IDE(統合開発環境)が必要になってくるんですが、jsはこれといったものは必要ありません(厳密には違いますが。後で説明が入ります)。まぁ、エディタぐらいは必要でしょうけど。
<br>
じゃあjsはどうやってコードを動かしてるんだ、って話になると思うんですよね。
答えは、__ブラウザの中のエンジン__で動かしているんです。
詳しく言っちゃうと、例えば皆さんが使っているであろうsafariやgoogle Chrome、fire foxなど、俗にいう「Webブラウザ」がありますよね？実は、そのブラウザの中には__jsを実行するためのエンジンがある__のです。それはブラウザによって変わってくるので、例えばsafariでできることが、google Chromeになるとできないなど、ちょっとした差はあります。
まぁ要するに、__ブラウザの中でjsが動くから、コンパイラとかも必要ないよ__ということです。
さらにいっちゃえば、__jsにとってのIDEはブラウザ__ということになります。
<br>
# 2,動的型付け言語
初心者からしてみたら、「何その単語」となりますよね。
簡単にいうと、動的型付け言語とは、
「__プログラムを動かす時にデータ型決めておくよ__」
という言語を指します。
つまり、データ型をつける必要がないということです。これが、多分「初心者におすすめのプログラム言語」と言われる所以なのではないでしょうか。
<br>
ここからは自論なのですが、正直この機能については初心者向けとは思えません。というのも、データ型を指定しないということは、その変数はどんなデータ型にもなれるということです。それが論理エラーを招く可能性もありますし、プログラマーからしてみても、「この変数はこのデータ型を持っているのか」というのが視覚的に判断できないので、混乱が生じる可能性もあります。
<br>
初心者だからこそ、データ型について詳しく触れる必要があるのではないのか、と思ったり思わなかったり
<br>
# 3,HTMLの操作が非常に楽
先ほども言ったように、jsはWebブラウザで動作するプログラム言語です。
HTML[^1]とはWebブラウザにおいて、文書を生成するためのマークアップ言語なのですが、同じWeb上で動作するので、HTMLに対する操作が非常に楽です。
例えば、
「ボタン"userButton"が押されたら、id="Text"のpタグの文章を変える」
という処理は、以下の通りで実現できます。

```javascript:test1.js
document.getElementById("userButton").onclick = function{    //ボタンを押したら...?
    //id"Text"のpタグに文字列を代入
    document.getElementById("Text").innerHTML = "Hello JavaScript!";
}
```

これで完了です。至って簡単ですね。
「は？簡単じゃないし？」と思う方もいるとは思いますが、しばらくjsに触れればこれも理解できます。
<br>
# 4,イベント処理
そもそもイベントとは、__ユーザがサイトに対して何かをしたアクション__のことを指します。
例えば、
「"A"のキーが押されたらメッセージを出力したい」
という処理があるとすると、そのコードは以下の通り。

```javascript:test2.js
document.addEventListener("keydown",event =>{
    let key = event.key;        //キーの値を取得
    if(key == "A") console.log("Aが押されました!!");    //キーがAならば
});
```

こんな感じで、簡単にイベント処理を行うことができます。ついでに、test1.jsの、「ボタンが押されたら....」という処理も、イベント処理の一種になります。
<br>
# まとめ
jsは様々な機能がありますが、基本はWeb環境で動くことのできる、Web特化のプログラム言語です。ただ、Web以外にも、様々な場所で活躍している、プログラム言語の代表的な言語になります。また、ここで紹介できなかったjsの魅力もあります。詳しくは下にある参考文献を購入して見てみてください。
<br>
昔は、「toy language(おもちゃの言語)」と言われていたらしいですが、今はそんなことないので、ガシガシ勉強しましょう！
<br>

>参考文献：[初めてのJavaScript 第3版 | オライリー](https://www.oreilly.co.jp/books/9784873117836/)

[^1]: HTMLとは、「Hyper Text Markup Language」の略で、Webの文書の書式を定義する為の、一種のマークアップ言語です。簡単にいうと、Web上の文書を作成する為の言語です。jsをいじるならばこの言語も知っておいた方がいいですね
Javascript データ型の基本

#はじめに
Javascript初心者です。
データ型を学んでいて、重要だと思ったことをアウトプットしていきます。
なお、筆者はJava,c#,rubyをちょっとだけ学んでいるので、そういった言語との
違いなどについても述べていければと思います。

<strong>※ 注意</strong>
記事の内容は誤っている箇所がある可能性があります。
お気づきになられた方はご指摘頂けると大変ありがたいです。
何卒よろしくお願いします。

#Javascriptのデータ型の種類
※ECMAScript6~の型

- string
- number
- boolean
- null
- undifined
- symbol
- object

string~symbolは<strong>プリミティブ型、基本型</strong>と呼ばれています。
objectは<strong>オブジェクト型、参照型</strong>と呼ばれています。
プリミティブ、オブジェクトの違いについてはほとんどのプログラミング言語で
定義が似ていると思うのでググってみてください。
それぞれ解説していきます。

##string
文字列を扱う文字列型です。
ダブルクォーテーション(""),シングルクォーテーション('')で囲んで表現されます。

##number
数値を扱う数値型です。

ちなみに、'数値'と'数字'は多くの場合、別物とみなされます。

##boolean
正か負か、又は0か1かを表す真偽値型です。（論理型とも呼ばれます）
true,falseという名前で表現されます。

##null
「何も存在していない」ことを表現します。
※多言語では、”存在しないオブジェクトへの参照”などと表される場合もありますが
Javascriptにおいてnullはそうではありません。

##undifined★
「定義されていない」を表現します。
Javascript固有の型となっています。"宣言したけど値は未定義"
のような変数に対してundifinedが割り当てられます。

##symbol★
ユニークで不変な「識別子」を表現します。
Object型の中のデータ構造に使用されたりします。
Rubyでいうsymbolとは異なります。
※ECMAScript6より登場しました。


##object
データおよびそのデータを操作する命令が入ったデータ構造です。
その名の通り、現実の「モノ」に例えられます。
上記のプリミティブ型以外で`new`キーワードで変数に格納されるものがこれにあたります。

#ちょっとしたTips
string ⇄ numberのデータ型変換
paizaとかでも意外と変換忘れがちなので注意したいところです...

```javascript

// ■ string → number
let str = "1000"; 
let num1 = +str;  // 方法①
let num2 = Number(str); // 方法②
console.log(typeof(num1),typeof(num2));
//=> "number" "number"

// ■ number → string
let num = 1000;
let str1 = num + "";
let str2 = String(num);
console.log(typeof(str1),typeof(str2));
//=> "strng" "string"

```

#参考
[javascript.info_プリミティブのメソッド](https://ja.javascript.info/primitives-methods)
[MDN web docs_データ型とデータ構造](https://developer.mozilla.org/ja/docs/Web/JavaScript/Data_structures)
カウントダウン機能の作成

### カウントダウン機能の作成
初期値120秒から1秒ずつカウントダウンする機能の作成。

```html
<body onload="init()">
  <p>COUNT DOWN: <span id="time"></span></p>
</body>
```

ページを読み込んだときにperformance.nowで変数startTimeにその時点の時間をミリ秒で代入します。
setIntervalメソッドで1秒ごとに関数tickを呼び出します。

```javascript
  <script>
    let startTime;

    function init() {
      startTime = performance.now();
      setInterval(tick, 1000);
    }
```

tick関数内は、まず変数nowTimeに関数tickが呼び出されたときの時間をperformance.nowで代入します。
body要素内のspan要素を取得してページを読み込んだときから経過した時間を120秒からカウントダウンする形式で表示します。
performance.nowはミリ秒で取得するので、1秒ごとにカウントダウンするように差分の時間を1000で割ります。

```javascript
    function tick() {
      const nowTime = performance.now();
      const time = document.getElementById("time");
      time.textContent = 120 + Math.floor((startTime - nowTime) / 1000);
    }
  </script>

```


下記のコードをコピーしてファイルに貼り付ければ試せます。

```html
<!DOCTYPE html>

<html>

<head>
  <meta charset="utf-8">

  <script>
    let startTime;

    function init() {
      startTime = performance.now();
      setInterval(tick, 1000);
    }

    function tick() {
      const nowTime = performance.now();
      const time = document.getElementById("time");
      time.textContent = 120 + Math.floor((startTime - nowTime) / 1000);
    }
  </script>
</head>

<body onload="init()">
  <p>COUNT DOWN: <span id="time"></span></p>
</body>
</html>
```
catkin buildの際のCMakeエラー集

## 経緯
最近、CMakeLists.txtを自分で書いたりするのですが、その際にエラーに割と出くわすので、自分が出くわしたエラーとその対処法をまとめようと思います。エラーに出くわすたびに随時更新していきます。同じエラーに出くわした方が、無駄な時間を過ごさないことを願います。

## 1. CMakeList.txt内のコマンドの順番違い

```
catkin build パッケージ名
```

上のコマンドを打つと、下のようなエラーが発生しました。

```
Errors     << sample2:cmake /home/nvidia/catkin_ws/logs/sample2/build.cmake.002.log
CMake Error at /home/nvidia/catkin_ws/devel/share/sample1/cmake/sample1Config.cmake:173 (message):
  Project 'sample2' tried to find library 'sample1_lib'.  The library is
  neither a target nor built/installed properly.  Did you compile project
  'sample1'? Did you find_package() it before the subdirectory containing
  its code is included?
Call Stack (most recent call first):
  /opt/ros/melodic/share/catkin/cmake/catkinConfig.cmake:76 (find_package)
  CMakeLists.txt:17 (find_package)
```

これは、sample2というパッケージ内で、sample1_libを使おうとしているのですが、見つからないよと言っています。sample1のCMakeLists.txtで、catkin_package()でライブラリをexportしたはずなのですが、sample2で見つからないと言われたので、ちょっとハマってしまいました。
**原因は、CMakeLists.txtにはビルドする上で、各コマンドに順番があるためでした。**下のような順番に従わないといけません。自分の場合は、add_library()の後に、catkin_package()を書いてしまっていたので、エラーになっていました。書き方の詳細は[こちら](http://wiki.ros.org/catkin/CMakeLists.txt)に書いてあります。
![Screenshot from 2020-10-27 21-37-40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663246/95eaf3c1-9945-89d1-d8de-c4bed703a262.png)

**間違いや質問、ご意見等ありましたらお気軽にコメントください。頑張って答えますので(笑)。**
【HTML】n乗などの上付き文字をHTMLで表す方法

#プログラミング勉強日記
2020年10月27日
`10cm^2`といった表記よりも`1cm²`といった上付き文字で表示した方がわかりやすいので、その方法を簡単にまとめる。

#sup要素を使う方法
　superscript(右肩文字・上付き文字)の略である`<sup>`タグを使用する。ただし、sup要素は特定の意味を持つ表記方法のために使用する要素で、単に文字が上付きになるという表示の目的として使ってはいけない。使い方は以下のようになる。  
 sup要素は注釈の存在や脚注番号を載せるときに使用してもいい。

```html:HTML(例)
30km<sup>2</sup> (平方キロメートル) <br>
51cm<sup>3</sup> (立方センチメートル) <br>
x<sup>10</sup>＋y<sup>7</sup> (xの10乗+yの7乗) <br>
x<sup>a</sup>＋y<sup>b</sup> (xのa乗+yのb乗)
```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/a68a7750-e469-c89b-6bc5-2d025ada9188.png)

#文字実体参照を使う方法
　<b>1乗・2乗・3乗の3種類のみ</b>は特殊な文字を表示するために使われる文字実体参照という方法で表すことができる。
　文字実体参照はすべて半角文字で`&`から始まって`;`で終わる書き方のこと。使い方は下記のようになる。

```html:HTML(例)
x&sup1; (xの1乗) <br>
12km&sup2; (平方キロメートル) <br>
80cm&sup3; (立方センチメートル)
```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/601cd4aa-b4c8-3251-f036-afa8ea4b54e5.png)



#参考文献
[上付き文字を表示する](http://www.htmq.com/html5/sup.shtml)
[2乗や3乗などのn乗をHTMLで表示する方法](https://allabout.co.jp/gm/gc/23894/)
正規表現でインデントのスペースの個数を置換する

https://stackoverflow.com/a/30304686 より。

4スペースでインデントされているファイルを正規表現で2スペースに置換したい、あるいはその逆の場合は`\G`を使えばできる。
`\G`は.NET, PCRE (C, PHP, R…), Java, Perl, Rubyでサポートされている。

Rubyを使うなら:

```
ruby -pe '$_.gsub!(/(^|\G) {4}/, " "*2)' < {ファイル名}
```

Vim内でやるなら:

```
%!ruby -pe '$_.gsub\!(/(^|\G) {4}/, " "*2)'
```

## 解説

`\G` は
1. 文字列の先頭
2. 前のマッチの直後の位置
のいずれかにマッチする。

他にも例えば

```
Tarzan A:33 B:32 C:36 Jane A:35 B:33 C:31
```

という文字列からJaneのスコアをパースして取り出したいというような場合にも使える:

```
irb(main):002:0> "Tarzan A:33 B:32 C:36 Jane A:35 B:33 C:31".scan(/(?:Jane|\G) \w+:(\d+)/)
=> [["35"], ["33"], ["31"]]
```

下記ページで解説されている。
http://www.rexegg.com/regex-anchors.html#G
[Rspec] Rspecを導入してモデルの単体テストコードを書くまでの流れ

今回はテストコードを書く時にRspecを導入する手順を忘備録代わりにメモします。

# Gem導入
テストで使うgemを３種類導入します。
`group :development, :test do ~ end`の処理内に記述します。

```:Gemfile
group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'rspec-rails
  gem 'factory_bot_rails'
  gem 'faker'
end
```
記述したら`bundle install`して、ローカルサーバーを再起動します。

# Rspecに必要なファイルをインストールする

```:ターミナル
% rails g rspec:install
```

# テスト結果のログを可視化する

```:.rspec
--require spec_helper
--format documentation # => 追記
```

# エラーメッセージを英語に設定（任意）
テストのエラーメッセージを英語で表示させたい場合は設定します。
`RSpec.configure do |config|`の上に追記。

```spec/rails_helper.rb
# 中略
I18n.locale = "en"

RSpec.configure do |config|
# 中略
```

# FactoryBotのファイル作成
- specディレクトリの中に、`factories`ディレクトリを作成します。
- そして、その中にテスト用のFactoryBotを生成するファイルを作成する。
- 名前は`モデル名s.rb`。今回はuserモデルのテストコードを書きたいので`users.rb`とします。

# ユーザー情報をFactoryBotで生成

```spec/factories/users.rb
FactoryBot.define do
  factory :user do
    name {Faker::Name}
    email {Faker::Internet.free_email}
    password = Faker::Internet.password(min_length: 6)
    password {password}
    password_confirmation {password}
  end
end
```
# FactoryBotが生成できていることを確認

```:ターミナル（コンソール)
pry(main)> FactoryBot.create(:user)
```

###エラーが発生した時は
- 私は上記のコマンドでエラーが発生しました。その時は、Springが裏で動いていることが原因みたいなので`spring stop`コマンドでSpringを停止させます。
- `Spring stopped.`と出れば正常にSpringが停止できています。
- そして再度コンソールで`FactoryBot.create(:user)`とコマンドを打って生成を確かめましょう。

```:ターミナル`
# exitでコンソール終了

% spring stop
```

# テストコードを記述するファイルを準備
- 下記のコマンドで`spec/models/user_spec.rb`というファイルが生成されます。
```:ターミナル
% rails g rspec:model user
```

# テストコード記述
こんな感じでどんどんテストコードを書いていきます。

```spec/models/user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  pending "add some examples to (or delete) #{__FILE__}"# => 元々の記述は削除

describe 'ユーザー新規登録' do 
    before do
      @user = FactoryBot.build(:user)
    end

   it "name, email, password, password_confirmationが全て入力されれば保存されること" do
      expect(@user).to be_valid
   end
   
  end
end
```

# テストコードを実行する時は
以下のコードを実行します。

```:ターミナル
% bundle exec rspec spec/models/user_spec.rb
```

###Fakerの書き方について参考サイト
https://rubydoc.info/gems/faker/1.3.0/frames
http://railscasts.com/episodes/126-populating-a-database
https://github.com/takeyuweb/trygems/blob/master/try-faker/faker.md

__Faker::Japanese__
https://github.com/tily/ruby-faker-japanese
Mapbox で点をスムースに移動させる

[Mapbox で移動する点を描く](https://zenn.dev/amay077/articles/1a849f39c534a4bd8fec) では、連続した点を単純に描画してみました。
が、パカパカ移動するので何だかつまらないしありきたりです。
なので、Uber アプリのようにもっとスムースにシンボルを移動させます。

完成形は↓です。

![cap.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8227/7c17551b-b2b0-2635-843f-2c3730e8ecd2.gif)

## はじめに

- [Animate a point along a route | Mapbox GL JS | Mapbox](https://docs.mapbox.com/mapbox-gl-js/example/animate-point-along-route/)

で例が示されているので、これを改造します。

また、この機能を実現させるのに、turf.js という地理空間図形や座標の計算を行ってくれるライブラリを使用します。

- [Turf.js | Advanced geospatial analysis](https://turfjs.org/)

## index.js

処理の要点は2つです。

1．``requestAnimationFrame`` を使ってフレーム毎に描画を行う
2. ルートの「開始点からｎメートル進んだ点」を turf.js で計算する

移動する速度(km/h)はここでは固定とします。
``requestAnimationFrame`` で描画のハンドラ関数を再帰で繰り返し呼び出し、前回の描画から今回までにかかった時間(ミリ秒)で何ｍ進むのかを計算します。
進んだ距離を加算しておき、turf.js を使って「開始点から Nｍ 進んだ座標」を取得して、DataSource を更新→画面を更新します。

```javascript
const waypoints = [
  [136.53890132904053,34.844644908488974],
  [136.54332160949704,34.840242190008105],
  // 中略 //
  [136.5387511253357,34.84480340196252]
];

// Symbol Layer
const symbolData = {
  'type': 'FeatureCollection',
  'features': []
};
map.on('load', function() {
  map.loadImage(
    'https://img.icons8.com/material/32/0000FF/marker--v1.png',
    (error, image) => {
      // 中略 //

      time = new Date().getTime();
      animate();
    }
  );
});

const line = turf.lineString(waypoints);
const lineLength = turf.length(line, { units: 'meters' });

const kph = 600; // 600km/h
let time = null;
let distance = 0;

function animate() {
  // 1フレームで移動する距離を算出
  const now = new Date().getTime();
  const offset = now - time;
  time = now;
  const movingInMeters = ((kph / 60 / 60 / 1000) * offset) * 1000;
  
  // 移動距離加算
  distance = distance + movingInMeters;

  // 移動した点を計算
  const options = {units: 'meters'};
  const movedPoint = turf.along(line, distance, options);

  // 更新
  symbolData.features.splice(0);
  symbolData.features.push({
    'type': 'Feature',
    'geometry': {
      'type': 'Point',
      'coordinates': movedPoint.geometry.coordinates
    }
  });
  const dataSource = map.getSource('point');
  dataSource.setData(symbolData);
  
  // repeat
  if (distance >= lineLength) {
  	distance = 0;
  }
        
  requestAnimationFrame(animate);
}
```

## DEMO

時速600km の設定なので F1 よりも相当速いです。

- https://jsfiddle.net/amay077/6q4uvog7/

## See Also

- [Animate a point along a route | Mapbox GL JS | Mapbox](https://docs.mapbox.com/mapbox-gl-js/example/animate-point-along-route/)
- [Animate a marker | Mapbox GL JS | Mapbox](https://docs.mapbox.com/mapbox-gl-js/example/animate-marker/)
- [Animate a line | Mapbox GL JS | Mapbox](https://docs.mapbox.com/mapbox-gl-js/example/animate-a-line/)
Mapbox で移動する点を描く

よくある「スマートフォンなどの位置情報を受信して、その位置を地図上に示す」を Mapbox で行います。

[Mapbox でのピン表示について考える](https://zenn.dev/amay077/articles/a6a020c50ff4b5b0c1da) で書いたとおり、「頻繁なアニメーションが伴う場合は Symbol Layer」がふさわしいと考えるので、今回はそちらを使用します。

とは言っても、ここではダミーデータとして緯度経度のリストを走査してシンボルを移動させているだけなので、ただのシンボルの再描画の例になります。

## index.js

事前準備が長いですが、重要なのは最下部 ``setInterval`` の中で行っている ``dataSource.setData()`` で、これを行うと地図(上のレイヤ)が更新されます。

ところどころ省略しているので、完全版は DEMO を見てください。

```javascript
const map = new mapboxgl.Map({
  container: 'map',
  center: [136.53890132904053,34.844644908488974],
  zoom: 14,
  style: {
    //  中略 //
  },      
});

const waypoints = [
  [136.53890132904053,34.844644908488974],
  [136.54332160949704,34.840242190008105],
  // 中略 //
  [136.5387511253357,34.84480340196252]
];

// Symbol Layer
const symbolData = {
	'type': 'FeatureCollection',
	'features': []
};
map.on('load', function() {
  map.loadImage(
    'https://img.icons8.com/material/32/0000FF/marker--v1.png',
    (error, image) => {
      if (error) {
        throw error;
      }
      map.addImage('iconA', image);
      map.addSource('point', {
        'type': 'geojson',
        'data': symbolData
      });
      map.addLayer({
        'id': 'points',
        'type': 'symbol',
        'source': 'point',
        'layout': {
          'icon-image': 'iconA',
          'icon-size': 1,
          'icon-allow-overlap': true,
          'icon-ignore-placement': true,          
        }
      });
      
      let counter = 0;
      setInterval(() => {
        symbolData.features.splice(0);
        symbolData.features.push({
          'type': 'Feature',
          'geometry': {
            'type': 'Point',
            'coordinates': waypoints[counter % waypoints.length]
          }
        });

        const dataSource = map.getSource('point');
        dataSource.setData(symbolData);
  
      	counter = counter + 1;
      }, 1000);      
    }
  );
});
```

## DEMO

- https://jsfiddle.net/amay077/xozL8tj0/
AWS CloudFormationを動かすためのAWS CLIの設定

# はじめに
AWS CloudFormationを動かすための事前準備として、AWS CLIの設定が必要です。

# 設定方法
  - Amazon Linux 2
    ※デフォルトでAWS CLIが利用できます。
    1. AdministratorAccessポリシー関連付けたIAMロールを作成し、EC2インスタンスにアタッチします。
    2. ~/.bashrcに```export AWS_DEFAULT_REGION=ap-northeast-1```を追記します。
    3. ```source ~/.bashrc```を実行してください。

  - Mac
   1. ```brew install awscli```を実行し、AWS CLIをインストールします。
   2. IAMユーザーを作成し、アクセスキーとシークレットキーを発行しましす。
   3. ```aws configure```を実行します。

        ```sh:ターミナル
$ aws configure
AWS Access Key ID [None]: {アクセスキー}
AWS Secret Access Key [None]: {シークレットアクセスキー}
Default region name [None]: ap-northeast-1
Default output format [None]: json
   ```
Mapbox で初期表示位置(中心とズームレベルまたは範囲)を指定

初期位置を指定したい、しかもクエリパラメータなどで動的に、「中心とズームレベル」または「指定した範囲」を初期位置としたい場合は、``new mapboxgl.Map({...})`` で直接指定するのではなく、変数にしておいて ``center``, ``zoom`` のペアまたは ``bounds`` を設定するとよいです。

``center`` は ``LngLatLike`` であり [経度, 緯度] という degree の配列、``bounds`` は ``LngLatBoundsLike`` であり、``LngLatLike`` の配列（[[西南], [東北]]）です。

## index.js

```javascript
const opt = {
  container: 'map',
  style: {
    // 省略 //
  },      
};

// ランダム(時刻)で、富士山(中心とズームレベル) か 琵琶湖(範囲) を切り替え
if (new Date().getTime() % 2 == 0) {
  opt.center = [138.73072, 35.36286];
  opt.zoom = 13;
} else {
  opt.bounds = [[135.856934, 34.981346], [136.282654, 35.531947]]; // [[west, south], [east, north]]
//  opt.bounds = [135.856934, 34.981346, 136.282654, 35.531947]; // [west, south, east, north] でも ok
}

const map = new mapboxgl.Map(opt);
```

## DEMO

- https://jsfiddle.net/amay077/e6Lvwpj8/

## See Also

- [LngLatLike - Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js/api/geography/#lnglatlike)
- [LngLatBoundsLike - Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js/api/geography/#lnglatboundslike)
Mapbox で OpenStreetMaps を表示するだけ

Mapbox のアクセストークンを取得して埋め込むのも面倒なアナタに。

## import する js/css

```
https://api.mapbox.com/mapbox-gl-js/v1.6.1/mapbox-gl.js
https://api.mapbox.com/mapbox-gl-js/v1.6.1/mapbox-gl.css
```

## index.html

```html
<div id="map"></div>
```

## index.js

```javascript
const map = new mapboxgl.Map({
  container: 'map',
  center: [134, 35],
  zoom: 10,
  style: {
    version: 8,
    sources: {
      OSM: {
        type: "raster",
        tiles: [
          "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png",
        ],
        tileSize: 256,
        attribution:
        "OpenStreetMap",
      },
    },
    layers: [{
      id: "BASEMAP",
      type: "raster",
      source: "OSM",
      minzoom: 0,
      maxzoom: 18,
    }],
  },      
});
```

## DEMO

- https://jsfiddle.net/amay077/zx2o13y5/
PRML　演習問題 7.2（基礎）　解答 

## 問題
> 制約式（7.5）において、右辺の1を任意の正数$\gamma$で置き換えても、マージン最大の超平面は変化しないことを示せ。

> 
```math
\begin {align*}
t_{n}\left(\mathbf{w}^{\mathrm{T}} \phi\left(\mathbf{x}_{n}\right)+b\right) \geqslant 1, \quad n=1, \ldots, N
\tag{7.5}
\end {align*}
```  

## 方針
この問題は(7.5)における右辺を任意の整数に置き換えてマージン最大の超平面を求め、元の(7.5)を用いて求めたマージン最大の超平面と比較することで証明できる。

## 解答
(7.5)の右辺を$r$に置き換えると、

```math
\begin {align*}
t_{n}\left(\mathbf{w}^{\mathrm{T}} \phi\left(\mathbf{x}_{n}\right)+b\right) &\geqslant r \\
\frac{t_{n}\left(\mathbf{w}^{\mathrm{T}} \phi\left(\mathbf{x}_{n}\right)+b\right)}{r} &\geqslant 1, \quad n=1, \ldots, N
\tag{7.5'}
\end {align*}
```  

となる。元の(7.5)の条件式をもとにしてマージンの最大化を行い、求められた解を$\mathbf{w}^{\star}$、$b^{\star}$とおくと、新しい(7.5')の条件式をもとにしてマージンの最大化を行い、求められた解は${r}{\mathbf{w}^{\star}}$、${r}{b^\star}$と書ける、
この時のマージンは(7.5)(7.5')双方において、

```math
\begin {align*}
\frac{t_{n}\left(\mathbf{w}^{\star\mathrm{T}} \boldsymbol{\phi}\left(\mathbf{x}_{n}\right)+b^\star\right)}{\|\mathbf{w}^\star\|}
\tag{7.2}
\end {align*}
```  
となる。よって、制約式（7.5）において、右辺の1を任意の正数$\gamma$で置き換えても、マージン最大の超平面は変化しない。

参考：https://tips-memo.com/prml-7-2
Rubyの条件分岐(case,while,無限ループ,break)

#Rubyの条件分岐
#case文
##条件分岐を表現するための文法。複数の条件を指定する時に、if文のelsifを重ねるよりもシンプルにコードを書くことができる
```java:sample
case 対象のオブジェクトや式
when 値1
 # 値1に一致する場合に実行する処理
when 値2
 # 値2に一致する場合に実行する処理
when 値3
 # 値3に一致する場合に実行する処理
else
 # どれにも一致しない場合に実行する処理
end
```
#while文
##繰り返し処理を行うためのRubyの構文。指定した条件が真である間、処理を繰り返す
```java:sample
number = 0

while number <= 10
 puts number
 number += 1
end

# ターミナル出力結果
# 0
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
# 10
```
#無限ループ
##処理が永遠に繰り返されること
```java:sample
number = 0

while true
 puts number
 number += 1
end

# ターミナル出力結果
# 0
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
# 10
# .
# .
# .
```
##上記のコードは条件式の部分にはじめからtrueと書くことによって意図的に無限ループを発生させている
#break
##eachメソッドやwhile文などのループから脱出するために使われる
```java:sample
number = 0

while number <= 10
 if number == 5
   break
 end
 puts number
 number += 1
end

# ターミナル出力結果
# 0
# 1
# 2
# 3
# 4
```
##このようにif文などの条件分岐とbreakを使うと、特定の条件のときにループを脱出することができる
#現場からは以上です！
【初心者向け】aタグの効果を無効化させる時によく使う系のCSSまとめ

# どうも7noteです。aタグのカーソルやイベントを無効にする系のCSSまとめ記事です。

どうも7noteです。
この記事は以下へ引っ越しました。

https://naruweb.com/coding/a-invalid/
【Python】datetime 型のリストを作成

## 注意事項

- 自分用の簡単なまとめであり，説明はほとんどありません．
- 内容は時間があるときに補充します．

## 心の声

- datetime パッケージにデフォルトで用意されていれば良かったのに...

## 使用コード

```py
import datetime

def list_date(start_date='2020-01-01', end_date='2020-01-31'):

    # str型をdatetime型に変換する．
    start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d')
    end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d')

    # 開始日と終了日の間隔を計算する．
    days = (end_date - start_date).days

    # 間隔の分だけfor文を回し，日を追加する．
    tmp_date = start_date
    date = [tmp_date]
    for i in range(days):
        tmp_date += datetime.timedelta(days=1)
        date.append(tmp_date)

    return date
```

## 使用例

```py
date = list_date(start_date='2020-01-01', end_date='2020-01-05')
print(date)
```

```text:実行結果
[datetime.datetime(2020 1, 1, 0, 0),
 datetime.datetime(2020 1, 2, 0, 0),
 datetime.datetime(2020 1, 3, 0, 0),
 datetime.datetime(2020 1, 4, 0, 0),
 datetime.datetime(2020 1, 5, 0, 0)]
```

## コメントより

- ジェネレータ関数として実装する書き方を@shiracamus さんから教えていただきました．
  - ジェネレータ関数なので，yield の部分で関数が一時停止し，呼び出し元に処理が戻ります．
    - cf) range 関数
- 引数 step には，timedelta 関数の引数が入ります．
  - weeks / days / hours / minutes / seconds / milliseconds / microseconds
    - ex) days=1
- for 文で range 関数のように使うこともできますし，リスト関数でリストに格納することもできます．

```py
import datetime

def date_range(start_date='2020-01-01', end_date='2020-01-31', **step):

    # str型をdatetime型に変換する．
    start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d')
    end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d')

    # timedelta型の間隔を定義する．デフォルトは1日おき．
    step = datetime.timedelta(**(step or dict(days=1)))

    # while文を回し，yieldでジェネレータを返す．
    date = start_date
    while date < end_date:
        yield date
        date += step
```

## 使用例

```py
date = list(date_range('2020-01-01', '2020-01-05', days=1, hours=12))
print(date)
```

```text:実行結果
[datetime.datetime(2020, 1, 1, 0, 0),
 datetime.datetime(2020, 1, 2, 12, 0),
 datetime.datetime(2020, 1, 4, 0, 0)]
```