OmniAICreator/Qiita-1.07M huggingface dataset:
[AWS Q&A 365][Secret Manager]Daily Five Common Questions #27

# 1. What is AWS Secrets Manager? 
AWS Secrets Manager is a service offered by Amazon Web Services that enables users to store and retrieve secrets such as database credentials, API keys, and other sensitive information. It allows users to encrypt their secrets using their own keys and manage access to their secrets using AWS Identity and Access Management (IAM). 

# 2. What are some of the features of AWS Secrets Manager? 
AWS Secrets Manager allows users to programmatically retrieve encrypted secret values at runtime, store different types of secrets, encrypt their secret data, automatically rotate their secrets, control access to secrets, and comply with standards. It also has a user-friendly console, command line tools, and AWS SDKs for ease of use. 

# 3. How can users control access to secrets in AWS Secrets Manager? 
Users can control access to secrets in AWS Secrets Manager by using AWS Identity and Access Management (IAM). They can create IAM policies to allow or deny access to secrets based on specific criteria such as user identity, time of day, or IP address. They can also use tags to control access to secrets. 

# 4. How does AWS Secrets Manager comply with standards? 
AWS Secrets Manager complies with several industry standards such as HIPAA, PCI DSS, and SOC. It uses encryption to protect secrets at rest and in transit, and provides audit trails to track access to secrets. It also allows users to set up automatic rotation of secrets to ensure compliance with standards that require frequent rotation of credentials. 

# 5. How can users create a secret in AWS Secrets Manager? 
Users can create a secret in AWS Secrets Manager using the console, command line tools, or AWS SDKs. They can specify the secret name, description, and value, and choose the encryption key and rotation schedule. They can also add tags for better organization and control access to the secret using IAM policies.
Arduino Opta 備忘録

Arduino Optaで何か作りたいので新発見があったらちょいちょい書き足しています

# ソフトウエア
## Arduino PLC IDEはどこの会社が作ったソフトウェアなのか。
Axel softwareのLogicLabがベースのようです。
たまに見かけるAlなんとかみたいなのは、Axelの略語なのかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/c3871a58-6761-e85d-79e3-3da31cf9d70e.png)


https://www.axelsoftware.it/en/logiclab/
## アクティベーションできない
Arduino OptaにはArduino PLC IDEのライセンスが購入しなくても付属しているので、ネットでアクティベーションすれば使えます。
しかしうまくいかないケースがあるようです。
シリアルモニタで接続すればアクティベーションエラーのログが取れるらしいのでサポートに問い合わせすると解決が早いかも。

https://forum.arduino.cc/t/could-not-activate-licenses-for-the-opta/1112811/3

## 動作がおかしいときはまずソフトのバージョンアップをする
Arduino PLC IDEは不安定なのでバージョンアップされてないかチェックして常に最新版を使いましょう。
ひっそり更新されています更新内容は公開されていないようです（？）
またArduino PLC IDE Toolsも必要です。

https://www.arduino.cc/en/software#arduino-plc-ide

## Connectを押してもつながらず砂時計になる。
1分程度我慢して待てばつながることがあります。

## 接続できない。壊れてるのか？
以下を確認してみる
・リセットボタン2回押しでブートローダーモードになります。
・Arduino IDEでサンプルプログラムを転送して反応があるか。

https://forum.arduino.cc/t/plc-ide-cannot-connect-to-opta/1106031/12

## イーサネットポートからのプログラム書き込み
できるらしいのですが制約事項があるようです。

https://forum.arduino.cc/t/download-to-opta-using-ethernet/1107931/11


# 仕様

## リレーが動作しない
リレーの動作にはDC12～DC24Vの電圧供給が必要です。
USB-Cだけで接続した場合動作しません。

## 入力ピンの電圧入力範囲
説明書を見るとアナログ入力レンジ0～10V,デジタル入力 VIL=4V VHL=5.9V
なので一般的なPLCのように24V入力はできないのかと思われるが24V入力も可能のようです
(Forum書き込み参照)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2146151/de5976d7-882f-19bf-6aae-cf763042aee4.png)

https://forum.arduino.cc/t/dig-an-input-range/1112357/6

## ピン配列

https://content.arduino.cc/assets/AFX00001-pinout.pdf

https://content.arduino.cc/assets/AFX00003-pinout.pdf


## LED USER(BLUE LED)が点灯しない
LED USER(BLUE LED)はWiFiモデル(AFX00002)にのみ実装されています。

https://forum.arduino.cc/t/does-led-user-light-up/1103228/10

# プログラム
## Modbus TCP Masterの使用方法

https://qiita.com/fa_yoshinobu/items/7d29e01631add5c0b937

# そのほか
## 内部構造

https://qiita.com/fa_yoshinobu/items/a6f771c176f49c88b754

## 入手方法
秋月電子(WiFiモデルは技適がないので当分日本では発売されそうない…)

https://akizukidenshi.com/catalog/g/gM-17627/

https://akizukidenshi.com/catalog/g/gM-17628/

## 公式フォーラム
Hardware Opta

https://forum.arduino.cc/c/hardware/opta/179/

Software PLC IDE

https://forum.arduino.cc/c/software/plc-ide/187


# 調べること/確認すること
・割り込み
・停電保持デバイスの作り方
・
OpenAI ChatGPTのAPI(gpt-3.5-turbo)を使ってGmailの自動返信機能を実装した。

# 初めに
ChatGPT APIを用いて何か作ってみたいということで、今回はGmailの未読メールに対して返信内容をChatGPTに考えてもらい、自動で返信する機能をgasで実装しました。

# 実装
## Open AIのAPI keyを取得
[Open AI](https://platform.openai.com/)
上記のリンクから会員登録を行い、API keyを取得してください。
右上のプロフィールボタンの「View API keys」から生成できます。

:::note info
無料枠として5ドル分の利用することが出来ます。
:::

## gasの実装
[Google Apps Script](https://script.google.com/home)
### 新しいプロジェクトの作成
画面左上の「新しいプロジェクト」をクリックしてください。
### サービスの追加
![スクリーンショット 2023-04-12 21.40.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2854023/7df0ec9b-1858-e27b-7187-06997964c11e.png)
「サービス」の+ボタンをクリックし、Gmailを追加してください。
### コードを記述
```javascript:gmail_autosend.gs
function autoReply() {
  // OpenAI APIキー
  var apiKey = "取得したAPIkeyを記述";

  // Gmailの受信トレイを取得
  var threads = GmailApp.search("label:inbox is:unread");
  threads.forEach(function (thread) {
    var message = thread.getMessages()[0];
    var text = message.getPlainBody();
    var sender = message.getFrom();
    var senderEmail = sender.match(/<(.*?)>/)[1];
    var prompt = `届いたメールに対して適切な表現を用いて返信文を考えてください。以下は実際に頂いた文面です。${text}`;

    // OpenAI APIにリクエストを送信
    var response = UrlFetchApp.fetch(
      "https://api.openai.com/v1/chat/completions",
      {
        muteHttpExceptions: true,
        method: "POST",
        headers: {
          Authorization: "Bearer " + apiKey,
          "Content-Type": "application/json",
        },
        payload: JSON.stringify({
          model: "gpt-3.5-turbo",
          messages: [
            {
              role: "user",
              content: prompt,
            },
          ],
          max_tokens: 1024,
          temperature: 0.9,
        }),
      }
    );

    // 返信文を生成
    var data = JSON.parse(response.getContentText());
    var reply = data.choices[0].message.content;

    // 返信メールを送信
    GmailApp.sendEmail(senderEmail, "自動返信メール", reply);
    GmailApp.markThreadRead(thread);
  });
}

```
`GmailApp.search("label:inbox is:unread")`は未読メールを取得するコードです。

モデルは「gpt-3.5-turbo」を使用しています。
「text-davinci-003」に比べてコストが1/10になっています。

`message`の`content`が入力するプロンプトです。
今回はシンプルに`届いたメールに対して適切な表現を用いて返信文を考えてください。以下は実際に頂いた文面です。${届いた文面}`としています。

`max_tokens`は生成されるトークンの最大数を指定しており、`temperature`はランダム性を制御しています。

## 定期実行
「エディター」を「トリガー」に変更し、新たにトリガーを追加します。
実行する関数を選択し、以下の項目を設定してください。
イベントのソースを選択：時間手動型
時間ベールのトリガーのタイプを選択：分ベースのタイマー
時間の間隔を選択(分)：1分

本来はメールが届いたら実行という形にしたかったですが、方法が分からなかったため1分に1度未読メールを確認し、未読メールがあれば返信するといった実装にしました。

記述したコードでは、未読メールが無かった時の処理を記述していないので、未読メールがない場合はエラーとして扱われます。

# 最後に
実際に何回か試しに使ってみましたが、実用的に使うにはプロンプトの工夫や学習データが必要だと実感しました。お遊びで使う分には、面白いと思います。

優れた返信メールを記述してくれるプロンプトがありましたら、ぜひ教えてください。
[備忘録] PupSQLiteで開いているファイルと別ファイルのデータベースを結合する方法

## やり方
* Aテーブルを開いていて、file_nameのBテーブルをJoinしたい状況
```sql
ATTACH DATABASE file_name AS B;

SELECT * FROM A LEFT JOIN B ON A.f = B.f
```
参考
> https://www.sqlitetutorial.net/sqlite-attach-database/
> https://www.sqlitetutorial.net/sqlite-left-join/
オフライン環境に Embeddable Python環境を構築する（get-pip.py を使わずに）

Pythonプログラムを配布するにあたり、インターネットに接続できない かつ PythonをインストールできないWindows環境で使用するには、`Windows embeddable package` を使用します。
しかし、`Windows embeddable package` には `pip` が同梱しておらず、`pip` をインストールするために インターネット環境で [get-pip.py](https://bootstrap.pypa.io/get-pip.py:get-pip.py) を入手・実行する手順しか見当たりませんでした。

そこで(正しいか不明ですが)、完全オフラインでEmbeddable Python環境を構築する手順を公開します。


## インターネット環境でやること 

+ 任意のバージョンの `Windows embeddable package` をダウンロード
  https://www.python.org/downloads/windows/
+ pip の WHL (Wheel) ファイルをダウンロード
  https://pypi.org/project/pip/#files
+ その他、オフライン環境で使いたい Wheel ファイルを入手（割愛）
+ get-pip.py は不要。

```cmd.exe
curl -o python3.10.11.zip https://www.python.org/ftp/python/3.10.11/python-3.10.11-embed-amd64.zip
curl -o pip-23.0.1-py3-none-any.whl https://files.pythonhosted.org/packages/07/51/2c0959c5adf988c44d9e1e0d940f5b074516ecc87e96b1af25f59de9ba38/pip-23.0.1-py3-none-any.whl
```


## オフライン環境でやること
+ `Windows embeddable package` を解凍
+ `current.pth`を作成、`python〇〇._pth`を編集
+ pip-xxxx.whl を解凍し、pipフォルダをカレントフォルダに配備
+ `python〇〇/python -m pip install pip --upgrade --no-index pip-xxxx.whl` で pip をインストール

```cmd.exe
rem 解凍コマンドとして 7z.exe にパスが通っているものとする。
dir /b
  pip-23.0.1-py3-none-any.whl
  python3.10.11.zip

7z x python3.10.11.zip -opython3.10.11
7z x pip-23.0.1-py3-none-any.whl -i!pip/
echo import sys; sys.path.append('')> python3.10.11\current.pth
echo import site>> python3.10.11\python310._pth
python3.10.11\python -m pip install --force --upgrade --no-index --no-warn-script-location pip-23.0.1-py3-none-any.whl
```

以上でオフライン環境下で Embeddable Python に pip が導入されます。
必要なモジュールは `--no-index` をつけてあげれば、オフライン環境でも入れ放題。
インストールもしていないので、Pythonフォルダごと持ち運んだりバッサリ捨てたりできます。

enjoy!
sanitize-htmlとは

## sanitize-htmlとは
**ユーザーが入力したテキストを安全な形式に変換するライブラリ**です。ユーザーが入力したテキストをHTMLとして表示する際、セキュリティ上の問題が発生する可能性があります。悪意あるユーザーからのクロスサイトスクリプティング攻撃（XSS攻撃）などです。 sanitize-htmlは不正なタグや属性を削除することができ、脆弱性を減らせます。

:::note info
**XSS攻撃**
悪意のあるスクリプトを埋め込み、ページを閲覧しているユーザーのブラウザに実行させる攻撃手法です。入力されたデータを書き換えたり、ブラウザで実行されるスクリプトを埋め込んだりすることで、攻撃します。

例えば、攻撃者が書き込んだコメント欄に悪意のあるスクリプトを埋め込んでおき、Webページを閲覧したユーザーのブラウザがそのスクリプトを実行してしまうと、攻撃者はユーザーのCookie情報を盗み取ることができてしまいます。
:::
sanitize-htmlは、このようなXSS攻撃を防ぐために開発されたライブラリの一つであり、HTMLやCSSなどのコードに含まれる悪意のある部分を削除し、安全な形に変換することができます。

## sanitize-htmlのユースケース
主にWebアプリの開発で使用されます。例えば、ユーザーが入力したコメントや投稿内容などをHTMLとして表示する場合、sanitize-htmlを使用することで、不正なスクリプトが含まれていた場合に安全な形式に変換することができます。

また、sanitize-htmlはセキュリティ面だけでなく、デザイン面においても活用でき、ユーザーが入力したテキストを表示する場合、フォントや色、スタイルなどを一元管理することができます。

## sanitize-htmlの特徴
XSS攻撃を防げる上に、テキストのデザインを一元管理することができるため、コードの見通しが良くなります。一方で、入力テキストを変換するための処理が追加されるので、レスポンス時間が遅くなります。

## sanitize-htmlの書き方
ドキュメントより

https://github.com/apostrophecms/sanitize-html

#### インストール
```npm:npm
$ npm i sanitize-html -D
$ npm i @types/sanitize-html -D
```

```js:sanitize.js
import * as sanitizeHtml from 'sanitize-html'

const html = "<strong>hello world</strong>";
console.log(sanitizeHtml(html));
console.log(sanitizeHtml("<img src=x onerror=alert('img') />"));
console.log(sanitizeHtml("console.log('hello world')"));
console.log(sanitizeHtml("<script>alert('hello world')</script>"));
```
sanitizeHtml関数(importで呼び出している)に引数としてHTMLコードを渡し、不正なスクリプトを取り除いた結果をログに出力しています。

`console.log(sanitizeHtml(html));` : "hello world"の文字列が出力されます。sanitizeHtml関数が安全なHTMLとして認識したためです。

`console.log(sanitizeHtml("<img src=x onerror=alert('img') />"));` : onerror属性を利用して悪意のあるスクリプトを実行しようとしていますが、sanitizeHtml関数はこのスクリプトを取り除いたため、ログ出力されるのは空の文字列です。

`console.log(sanitizeHtml("console.log('hello world')"));` : `console.log('hello world')`を実行しようとしていますが、sanitizeHtml関数はscriptタグ自体を取り除くため、ログ出力されるのは空の文字列です。

`console.log(sanitizeHtml("<script>alert('hello world')</script>"));` : `alert('hello world')`を実行しようとしていますが、sanitizeHtml関数によってこのスクリプトが取り除かれているため、ログ出力されるのは空の文字列です。

このように、XSS攻撃を防いでいるわけですね。
[Linux]標準入出力とパーミッション

# 標準的入出力とは?
標準入力、標準出力、標準エラー出力の3つを合わせて、標準入出力と呼びます。

まずは、入力と出力を見ていきます。
出力は、コマンドやプログムの実行結果を外に向かって出すことを言います。入力は、キーボードから入力したものをコンピューターに引き渡すことを言います。

では標準とはなんでしょうか?
入力元と出力先は、指定することで変更することができますが、特に指定がないままだと、デフォルトつまり標準が適用されますが、そのデフォルトの設定が、入力は「キーボード」で出力は「ディスプレイ」になります。

最後に、標準エラー出力は入力によってコマンドを実行した後に、エラーが出た場合は、標準出力ではなく、エラーメッセージを返す出力をすることです。例えば、Webサービス上でエラーが起こり、それがWeb画面上にユーザーにエラー出力をするのではなく、エラーは全てLog上で管理するなどです。

Linuxでは、コマンドの入出力先を抽象化することで、入出力先を柔軟に変更できます。つまり、コマンドの結果を別な入力コマンドに置き換えることもできる上に、コマンドを組み合わせることによって、複雑な処理を実現することも可能です。

# リダイレクト
リダイレクトは、入出力先を変更する機能になります。

## 入力のリダイレクト
/etc/hostsファイルを入力元にしてcatコマンドを実行する例。
```
$ cat < /etc/hosts
```

## 出力のリダイレクト
lsコマンドの出力先をls.txtと言うファイルに保存する例。
```
$ ls > ls.txt
```
## エラー出力のリダイレクト
エラー結果を画面上に表示するのではなく、ファイルに保存する例。
```
$ ls /hoge 2> error.txt
```
エラーを出力には「2>」を使いますが、他にも標準入出力をOSが識別するための識別子が存在します。

|入出力|数値|
|:--:|:--:|
|入出力|0|
|標準出力|1|
|標準エラー出力|2|

Linuxには、出力とエラー出力をまとめることができます。以下のようにすることで、lsコマンドの出力結果とエラー出力を、output.txt内に保存します。

```
$ ls / /hoge > output.txt 2>&1
```
また、リダイレクトで追記することもでき、「>」でファイルの上書きをし、「>>」でファイルに追記を行います。
```
$ echo Hello >> output.txt
```
# パイプライン
複数のコマンドを連携させるコマンドです。コマンドの標準出力を別のコマンドの標準入力に繋げることができます。

```
$ ls /bin | less
```
「ls /bin」の出力結果を「less」に引き渡していることを表しています。これによって、/bin以下のファイルやディレクトリ一覧をlessコマンド表示で見ることができます。

# パーミッション
ファイルの権限を付与、制限を行うことです。

Linuxには、複数のユーザーがログインして作業することが前提として作られているため、管理者と一般ユーザーといったようにユーザーによって、アクセス権限を制限することで、システムを安全に管理することができます。

## 権限と管理
ファイル全てに、権限を管理することができます。オーナー(ファイル所有者)とグループ(ファイル所有グループ)が設定できます。オーナーは、ファイルそれぞれに、ユーザー権限を与えるのに対し、グループはあらかじめアクセスを制限したグループを作成した後に、ユーザーをそのグループに追加していくなどといった、使い方ができるため、複数のユーザーを一括で管理することができます。

(確認方法)
```
$ ls -l /etc/less
   -rwxr-xr-x. 1 root root 158240 7月 31 2015 /bin/less
```
「ls -l」コマンドを実行することによって、最初のrootがオーナーを示しており、２番目のrootがグループになります。

また、上記のパーミッションも確認していきます。
「-」 ・・・ ファイルタイプ(今回はファイル)
　※「d」ならディレクトリ、「l」ならシンボリックリンクを表します

「rwx」 ・・・ オーナーのパーミッション

「r-x」 ・・・ グループのパーミッション

「r-x」 ・・・ その他のユーザーのパーミッション

rは読み取り、wは書き込み、xは実行を表しています。

## ファイルやディレクトリの権限の設定
権限の設定を行うのに、Linuxには「chmod」コマンドが用意されています。権限の設定の際には、ユーザーもしくわグループといった権限の対象、そして権限の追加や削除といった権限の有無の指定が必要になります。

(権限の対象)
|記号|内容|
|:--:|:--:|
|u|オーナーの権限|
|g|グループの権限|
|o|その他のユーザーの権限|
|a|全ユーザーの権限|

(権限の有無)
|記号|内容|
|:--:|:--:|
|+|権限を追加|
|-|権限を削除|
|=|記述した権限にする|

(例)
```
$ chmod u+r file
```
このコマンドによって「file」のオーナーに、読み取り権限を付与することを意味します。

またパーミッションは、8進数の数字でも表すことができます。
|パーミッション|数値|
|:--:|:--:|
|r(読み取り)|4|
|w(書き込み)|2|
|x(実行)|1|

(例)
```
$ chmod 755 file
```
「file」のオーナーに「rwx」、グループに「r-x」、その他のユーザーに「r-x」の権限を設定することを意味しています。

# スーパーユーザー(ルートユーザー)
管理者権限を持つ特別なユーザーのことで、システムの根幹に関わる作業などは、スーパーユーザーだけが行われるようにします。

(例)パッケージのインストール(gitのインストール)
```
$ sudo yum install git
```


# 参考
https://www.udemy.com/course/unscared_linux/
クロージャについて

#クロージャとは
---
関数とその関数が宣言された時の外側にあった環境（変数など）を合わせて指す用語です。
下の例では、numAの値は、返り値である関数の中に同封（enclosed） →　 クロージャ されます。
```
function add(numA) {
  return (numB) => numA + numB;
```
#なぜクロージャが重要なのか、どんな時に活用できるのか
---
クロージャを活用すると、変数の値を維持することができるプライベート変数を作成することができ、外部から変数を参照することはできなくなります。
グローバルスコープにある変数だと、変数が意図せず変更されないか気を使わないといけないですよね。

#クロージャの例
---
```
const countUp = () => {
  let count = 0;
  return {
    addOne: () => {
      count++;
    },
    show: () => {
      console.log(count);
    }
  };

})();

countUp.show(); // 0

countUp.addOne();
countUp.show(); // 1

```
HP EliteDesk 800 G6 SFF 　BIOSアップデート

# HP EliteDesk 800 G6 SFFにてBoot Device not found
Boot Device not foundが発生する理由は主にドライブの認識不良。
こちらは割と検索するだけで解決策が出てくる。
今回のケースは[HP EliteDesk 800 G6 SFF]の一部ロット??に適用できる解決策...になる可能性がある方法を参考程度に記載。

# BIOSアップデートで何が変わるか 
※後日記載※

# BIOS USBドライブを使用したアップデート 
bootdeviceが見つからない。という状態なので、もちろんwindows内から更新exeを実行することはできない。
このような場合は、もう１台の正常起動しているPCにてBIOS更新exeを実行し、USBリカバリメディアを作成。
こちらのメディアを使用して、起動しないPCのBIOS更新を行うことになる。

メディアの作成について、流れ自体は公式に記載はある。が、ノートブック用として記載されている様子。
参照　https://support.hp.com/jp-ja/document/c02211620

流れは最近のHPPCであれば大体適用できるはず。
【Rails】スライドショー縦並びになる解決方法

# スライドショー「リロードしないとjQueryが動かない！！」

以前スライドショーを作ったのですが…
リロードしないとjQueryが動かない！！！
となって困ってました…

何とか解決したいと思い色々調べて何とか解決できたので
書いていきたいと思います。


# 解決方法　「Turbolinksを無効化する」
Turbolinksが関係しているらしく、これを無効かすればいいらしいです。
これを追加すれば解決できました！！


```php:javascript/packs/application.js

$(document).on('turbolinks:load', function() {
.
.
.

});    ☜これは本当に忘れがち!!!
```

※ちなみに私は最後の　`});  `　閉じカッコを忘れてて数分悩んでました。
わすれないようにしましょう！！！
【コード管理/GitHub】dbtとGitHubを連携してSnowflakeのコード管理をする

# 今回の課題
今回は、以前下記の記事で使用した、
S3からSnowflakeにデータをロードするためのクエリをGitHubで管理できるように、
Snowflakeのworksheetではなく、dbtでクエリを実行するように実装した。

<font color="red">※ストレージ統合`CREATE STORAGE`や外部ステージ`CREATE STAGE`の作成のための、
　クエリはdbtではなくSnowflakeのworksheet上で実行する必要があったため、
　dbt経由でGitHubにpushしてコード管理することはできなかった。<font>


#### ◼︎前回の記事
前回の記事までで、実装している内容は下記。
* S3データをロードする用のdatabase, schema, tableの作成
* ステージとファイルフォーマットの定義
* S3データをロードする用のtableにS3のデータを格納

https://qiita.com/Ayumu-y/items/d6713e09b0a409d1bd25

## 今回実装した手順

### 1)generate_schema_nameマクロの定義を変更する
dbt projectの`macros`ディレクトリ直下に、`get_custom_schema.sql`ファイルを作成して、
下記のように記述してマクロの定義を変更した。

```jinja
{% macro generate_schema_name(custom_schema_name, node) -%}

    {%- set default_schema = target.schema -%}
    {%- if custom_schema_name is none -%}

        {{ default_schema }}

    {%- else -%}

        {{ custom_schema_name | trim }}

    {%- endif -%}

{%- endmacro %}
```
#### generate_schema_nameマクロとは
デフォルトで定義されているマクロで、dbtがスキーマを生成する時のロジックが記述されているマクロのこと。

デフォルトでは、全ての`model`はターゲットで指定されたスキーマに対してビルドされているため、
上記の`macro`では、作成したデータロード用のschemaにデータがロードされるようにマクロの内容を書いている
※ターゲットで指定されたスキーマ以外のことを**カスタムスキーマ**と言う。

dbt Cloud IDEの場合、下記の画像のようにターゲットの定義は、
`Your Profile`>`Credentials`をクリックして出てくる`Connection Details`から確認することができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/b01e3071-6ca0-2fdf-4e50-1910c9be10b4.png)

### 2)dbtを使ってロードする
#### 2)-1.データをロードするためのmodelを格納するディレクトリを作る
`models`ディレクトリの配下に`load`というディレクトリを作成し、
`dbt_project`を下記のように変更する。
```yml
models:
  my_new_project:
    # models/load/配下のmaterializedをtableに定義しておく。
    load:
      materialized: table
```
### 2)-2.loadディレクトリ直下にロードするためのmodelを作成する
※こちらを`dbt run`すれば、Snowflakeの指定のテーブルにデータがロードされる。
```sql
SELECT 
    $1:dt::varchar
    , $1:order_id::varchar
    , $1:user_id::varchar
    , $1:purchase_amount::varchar
FROM -- ここでのEXTERNAL_TABLEは外部ステージの名前のこと。
    @DEMO_DB.PUBLIC.EXTERNAL_TABLE/mysnapshot20230402043959/rails_test_app_test/rails_test_app_test.purchase_log/1/part-00000-cc307475-00bf-4e8f-a351-b358a1636058-c000.gz.parquet
(file_format => 'parquet')
```
### 3)Git Hubにpushする
dbtの右上の`Commit and sync`をクリックして、GitHubに簡単にpushできる。
![eaf1ee4768c223f92661e848244f1dad.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/e54cf7c9-f312-a702-5366-bc869c7d9177.png)

以上！

# まとめ
dbtは簡単にGitHubと連携できる機能があるので、
その機能を使えば、GitHubで簡単にクエリ履歴の管理をすることができることが分かった。
dbtでETLをしたクエリであれば、簡単にGitHubでクエリ履歴の管理ができるので便利だと感じた。

**外部ステージ作成や統合ストレージの作成は、Snowflake内のworksheetでクエリを実行する必要があり、dbt経由ではクエリの管理ができないというところが気になった。**

#### 参考記事

https://dev.classmethod.jp/articles/snowflake-load-data-from-dbt/

https://zenn.dev/gak_t12/articles/34bceec8492019
npmパッケージに関するメモ

# 始めに
vue2系から3系に上げるにあたり
npmパッケージに関して理解深めれそうなのでそのメモ

# npm とはなんぞや

>npm（Node Package Manager）は、Node.jsのパッケージ管理ツールです。npmは、JavaScriptのコードやライブラリを共有、再利用、更新、管理するための仕組みを提供します。npmは、オープンソースのJavaScriptパッケージ（モジュール）の登録、検索、インストール、アップデート、削除を行うことができます。
>
>npmには主に2つの要素があります。
npm CLI（Command Line Interface）：
これは、コンピュータにインストールされたコマンドラインツールで、npmで利用可能なパッケージを管理できるようにするものです。これにより、開発者はプロジェクトにパッケージをインストールしたり、依存関係を管理したり、パッケージを公開したりすることができます。
>
>npm Registry：
これは、パブリックおよびプライベートのJavaScriptパッケージをホストするオンラインデータベースです。開発者はnpm CLIを使って、npm Registryからパッケージをインストールしたり、自分のパッケージを公開したりすることができます。
>
>npmは、JavaScriptおよびNode.jsのエコシステムで最も広く使われているパッケージ管理ツールであり、何万ものパッケージが登録されています。これにより、開発者は簡単に便利なライブラリやフレームワークを利用して、プロジェクトの開発を効率化できます。

ほうほう
npm CLIは普段使っている`npm hogehoge`みたいなコマンド群のことぽいですね。

npm Registryは`npm install vue`とかでインストールされるコードが保管されてる場所ですかね。
[npm](https://www.npmjs.com/)
ここに世界中の天才達がアップロードしてくれてるんですかね。

# package.json とはなんぞや

>package.jsonは、Node.jsプロジェクトのメタデータ、依存関係、スクリプト、設定を記述するJSON形式のファイルです。プロジェクトのルートディレクトリに配置され、プロジェクトに関する重要な情報を提供します。このファイルは、npm（Node Package Manager）と連携して、パッケージ管理とプロジェクト設定を効率的に行います。

ふんふん
npm CLIによってインストールしたパッケージが記載されているファイルで
パッケージを管理するための設計書みたいなものですね。

ここに書かれているパッケージをnpm Registryからインストールしてきて
node_modules配下に入れてくれるんですね。

## package.jsonの構文
[ドキュメント](https://docs.npmjs.com/cli/v9/configuring-npm/package-json)

詳しくはドキュメントや他の記事をみるとして
プロジェクトで使っているについてメモする
scripts・devDependencies・dependencies
### scripts
>package.jsonファイル内のscriptsセクションは、プロジェクトに関連するコマンドやタスクを定義する場所です。これらのスクリプトは、ショートカットやエイリアスのように機能し、プロジェクトのビルド、テスト、デプロイなどの一般的なタスクを簡単に実行できるようにします。

なるほど、ここはコマンドを定義する場所なんですね
`npm run [定義したコマンド]`
で実行します

### devDependencies
>devDependenciesは、package.jsonファイル内で定義されるオブジェクトで、プロジェクトの開発環境でのみ使用される依存関係を指定します。これらの依存関係は、テスト実行、ビルドプロセス、ローカル開発サーバーの起動など、開発作業やビルド時のタスクをサポートするために使用されます。

### dependencies

### 参考記事
https://kosuke-space.com/package-json-npm

# package-lock.json とは?
>package-lock.json は、プロジェクトの依存関係の正確なバージョンとその依存関係のツリーを記録するファイルです。npm installが実行されると、package-lock.jsonが自動的に生成または更新されます。このファイルにより、開発者が同じ依存関係のバージョンを共有し、再現性のあるビルドを確保できます。

package.jsonに記載したパッケージをインストールすると
実際にはそのパッケージだけでなく、そのパッケージを構成する他のパッケージも同時にインストールされますね。
いわゆる依存関係というもので依存関係のあるパッケージやそのバージョンなど
実際にnode_moduleにインストールされるパッケージの情報が入っている。

例えば`npm install vue`でインストールしたvueパッケージ(node_module>vue)を見てみるとpackage.jsonがあってここに依存関係のあるパッケージ情報などが記載されてて
これをもとに他のパッケージもインストールされるっぽいですね。

![スクリーンショット 2023-04-12 20.06.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346005/2ec91002-1e6f-efe7-b44d-a3d7f091ea49.png)
【Mac】ターミナルにサジェストを表示する

# はじめに
「[【GitHub】GitHubでコードを見るときは](https://qiita.com/SNQ-2001/items/0467aa99fb9430353e1b)」に引き続き、
またまた@Shota-Abeにいいことを教えてもらったので記事にします

# こんな感じ
ターミナルにサジェストが表示される！！
![スクリーンショット 2023-04-12 20.14.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/4cf5109c-fca8-e9b4-893e-b47210fc47a2.png)

# Homebrewのインストール
```:ターミナル
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

# Homebrewのセットアップ
```:ターミナル
touch .bash_profile
open .bash_profile
```

```:.bash_profile
export PATH="$PATH:/opt/homebrew/bin"
```

```:ターミナル
source ~/.bash_profile
```

# figをインストール
```
brew install fig
```

# figのセットアップ
ターミナルで以下のコマンドを打ちます
```:ターミナル
fig
```

① 「開く」を選択します
![スクリーンショット 2023-04-11 12.39.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/ea86bcef-4d50-ec50-9d47-8ed2e65ac0c1.png)

② サインインをします(私はGitHubでサインインをしました)
![スクリーンショット 2023-04-11 12.42.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/47f846e9-77bb-ebba-cae5-3754dec8c4da.png)

③ 「Figを開く」を選択します
![スクリーンショット 2023-04-11 12.45.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/bf6941fa-8a13-1b85-7b56-8570c88b4ddb.png)

④ ユーザー名を入力します
⑤ 「Set Username」を選択します
![スクリーンショット 2023-04-11 12.46.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/0d5e4ba4-1c01-ee3f-b55e-1d3426a46c74.png)

⑥ 「Skip」を選択します
![スクリーンショット 2023-04-11 12.48.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/bef3b39f-daac-271b-5399-c551a3a1bdb2.png)

⑦ 「Install CLI」を選択します
![スクリーンショット 2023-04-11 12.49.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/b4b1e643-6cd9-d252-8d14-60de27ebff84.png)

# 設定アプリで権限を与える
設定アプリを開きます
① 「プライバシーとセキュリティ」を選択します
② 「アクセシビリティ」を選択します
![スクリーンショット 2023-04-09 20.52.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/802f8ff1-ce52-5b49-fbb6-84253ea97a8d.png)

③ 「Fig」をオンにします
![スクリーンショット 2023-04-09 20.55.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/2b2e4a6d-0543-90f6-c8d2-99c3dcc8c44f.png)

④ ロックを解除します
![スクリーンショット 2023-04-09 20.58.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/8e9e8ace-a042-fec7-49b0-a0182b9be1fc.png)

完成！！

![スクリーンショット 2023-04-12 20.17.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/db8b7984-607f-17ae-0189-b06bbda7124b.png)

# おわり
これめっちゃ快適です

# 公式サイト
https://fig.io/

# 参考記事
https://it-jog.com/cmd/install-fig
Xcode14.3にしたらCocoaPodsで入れたライブラリがビルド失敗する


# 起こったこと
Xcodeを14.3にアップデートしたら、CocoaPodsでインストールしていたライブラリがビルド時にこけるようになった。

```
File not found: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneos.a
```

# 解決

podfileの`post_install`でMinimum Developmentsのバージョンを一気に上げる方法がstackoverflowで紹介されていたので、記述して再度`pod install`を実行

```ruby
post_install do |installer|
  installer.generated_projects.each do |project|
    project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
      end
   end
  end
end
```

ちなみに、Xcode上だとここが変わります。

![スクリーンショット 2023-04-12 19.57.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116677/2fd6cfaa-e4cb-d7fc-fed5-9328f192868b.png)

ビルドが通り、無事解決！

# 参考

https://stackoverflow.com/questions/75574268/missing-file-libarclite-iphoneos-a-xcode-14-3
【LINE BOT】画面をタップするだけでカフェやニュース検索ができるBOTを作りました【Rails】

# はじめに

こんにちは

今回作成したLINE BOT、『**ふらりトピック**』は、ふらっと寄り道したい時やひまつぶししたい時に、画面タップのみで近隣のお店を検索できたり、ひまつぶしできるニュースや動画を紹介するBOTになっています。時間を効率的に、そして有効的に使えるような仕組みをITの力で作っていきたいと考え、こちらのアプリを開発させていただきました。

:coffee:ふらりトピック:coffee:
[友だち追加](https://liff.line.me/1645278921-kWRPP32q/?accountId=440otyaw)

# サービス概要

【使用技術】

・　Rails 6.1.4.1
・　LINE Messaging API SDK for Ruby
・　mechanize
・　[YouTube Date API](https://developers.google.com/youtube/v3/docs?hl=ja)
・　[ホットペッパーWebサービス](https://webservice.recruit.co.jp/)
・　[HeartRails Express API](http://express.heartrails.com/api.html)
・　[Render](https://render.com/)（デプロイ先）
・　[UptimeRobot](https://uptimerobot.com/)（サーバーのスリープ防止）

後述のTogetterまとめ記事の取得はRubyGemの mechanize を利用し、スクレイピングしています。

また、デプロイ先は当初Herokuを予定してましたが、Herokuのフリープランの終了に伴い、Renderのフリープランでのデプロイに変更しました。Renderのフリープランのみの利用だと15分でスリープモードに入ってしまい起動が遅くなるため、UptimeRobotというサーバーのスリープ防止機能で5分ごとにリクエストを飛ばすようスケジューリングし、課金せずにスリープを防止しています。



## ①カフェ検索

![20230403_225143](https://user-images.githubusercontent.com/77098696/229530419-c2d4b3f2-d1b1-402b-844a-750891ec1b3c.gif)

上記動画のように、画面下部のリッチメニューをタップするだけで近隣のカフェを検索できるよう設定しました。
こだわった点としては、すべて画面タップだけで誘導し完結できるようにしたところです。文字入力も可能ですが直感的で簡単に使える、あくまで**ひまつぶし**をコンセプトとしているため使い方を模索している合間につぶす暇がなくなったり、もういいやと思わないようにするために『**タップで完結**』する点にはこだわってます。

## ②ニュース　動画検索

![20230404_214726](https://user-images.githubusercontent.com/77098696/229796845-d513f7e9-8de2-4574-bffe-0a4576cfffaf.gif)

同じくニュースや動画の検索でもタップだけで検索できるように設定しました。
ニュースはTogetterまとめのサイトをスクレイピングし取得。動画はYOUTUBEのAPIを利用しこちらは急上昇にあがってきた動画を取得しています。
文章中心のTogetterまとめはテキスト形式でランキングにして表示し、動画はサムネイルが見えるようフレックスメッセージ形式にして表示するなど用途によって変えています。

# なぜLINE BOTにしたか

このアプリの最大のこだわりでもある、**直感的で簡単**を叶えるためにWEBアプリではなく、LINE BOT形式にしました。

・　使い方を説明しなくてもすぐ使えるデザイン
→LINEなら使い方の説明はほぼ不要

・　スマホ利用しやすいアプリにすること
→視認性と操作性の観点から、スマホ利用向けの方が目的に合っていると考えた

・　ダウンロードの手間を省く

・　軽くてサクサク動く
→あえてログインログアウト機能をつけず、データベースも使わずに開発したことでロード時間を減らしサクサク動くアプリにした

特に以上の観点にはこだわっています。

# 苦労した点

とにかくLINE BOTの作成をしたことがなく、また参考になる記事も少なかったため全て苦労したといっても過言ではないのですが、LINE BOT特有のJSON形式でのコードの記述や、カフェ検索に関してはいくつも条件分岐を行ったため、そのたびエラーが続出し解決に非常に苦労しました。
また、JSONの記述ミスはローカルサーバー上でエラーメッセージが出ないため、そのエラー原因を探るために何日もLINE上にメッセージを送り続けて探していました。

# 今後の改善点

コードのリファクタリングはもちろんのこと、急上昇動画をユーザーひとりひとりに合ったものに変更できたらいいなと思っています、また、機能としてはYahoo!のニュースなども追加できたらする予定です。
もし、気になる部分や欲しい機能がありましたら、LINE上リッチメニュー右下のお問合せからご連絡いただけるとありがたいです。

# 最後に

はじめての自力でのアプリ作成、LINE BOT作成でとても大変ではありましたが、エラーが解決し機能実装がかなった時の喜びはひとしおで、もっと作りたいなと思える瞬間でした。これからもITの力で課題解決できるよう、努めて参りたいと思います。
シンボルと文字列は何が違うのか

## はじめに
プログラミング初学者です！
現在Rubyを学習中なのですが、シンボルと文字列の違いについて少し悩んだので本記事を通して整理していければなと思います。

## シンボルについて
現在ハッシュのキーには文字列を使っていますが、シンボルを使うことが推奨されているみたいです。
Rubyにおける**シンボル**って一体なんなんでしょうか？
公式リファレンスによると、
> シンボルを表すクラス。
シンボルは任意の文字列と一対一に対応するオブジェクトです。
文字列の代わりに用いることもできますが、必ずしも文字列と同じ振る舞いをするわけではありません。同じ内容のシンボルはかならず同一のオブジェクトです。

う〜ん。。。
なんだかわかったような、わからないような・・・

コードで見ると以下のような感じです。
```ruby
:シンボルの名前

# シンボルの例
irb(main):001:0> :name

# シンボルクラスのオブジェクト
irb(main):002:0> :name.class
=> Symbol
```
まあ要するに、**シンボルは、コロン(:)を使って任意の名前を定義します(シンボルリテラル)。
シンボルは、Symbolクラスのオブジェクト**のことです。

## 文字列について
次に**文字列**についてです。
文字列といったらシングルクオート(')、ダブルクオート(")で囲って完成！みたいなイメージですけどどうなんでしょうか・・・？
公式リファレンスによると
>文字列のクラスです。ヌル文字を含む任意のバイト列を扱うことができます。文字列の長さにはメモリ容量以外の制限はありません。
文字列は通常、文字列リテラルを使って生成します。

となっていますが、これも見た方が早いですね。

```ruby
'これは文字列です'
"これは文字列です"

# 文字列の例
irb(main):001:0> name = "アグエロ"
=> "アグエロ"

# シンボルクラスのオブジェクト
irb(main):002:0> name.class
=> String
```
上記から、**文字列オブジェクトはダブルクオート（シングルクオートでも可）で囲うと定義できる**ということがわかりました。

## シンボルと文字列の違いは？
結局何が違うのか？ということなんですが、主に3つ違いがあります。

- 1つ目は**シンボルは同値ならば必ず同一**という特徴になります。
以下のコードを見てください。
```ruby
#　シンボルの例
irb(main):003:0> :apple.object_id
=> 1516828
irb(main):004:0> :apple.object_id
=> 1516828

# 文字列の例
irb(main):005:0> 'apple'.object_id
=> 2664429360
irb(main):006:0> 'apple'.object_id
=> 2664423780
```
シンボルにおいて**同値の場合は同じobject_idが割り当てられ、同じオブジェクトを指します**。
文字列は2つとも**異なるobject_idが割り当てられます**。

- 2つ目は**シンボルは書き換えられないと**いう特徴になります。 
以下のコードを見てください。
```ruby
#文字列の例
irb(main):007:0> string = 'apple'
=> "apple"
irb(main):008:0> string.upcase!
=> "APPLE"
irb(main):009:0> string
=> "APPLE"

#シンボルの例
irb(main):010:0> symbol = :apple
=> :apple
irb(main):011:0> symbol.upcase! NoMethodError (undefined method `upcase!' for :apple:Symbol)
```
文字列は**変更可能なオブジェクト**ですが、シンボルは**変更することができません**。

- 3つ目は**比較の処理はシンボルの方が高速**という特徴になります。
比較を行う際に、文字列を使う場合はその度に新しく文字列を生成する必要があり若干の面倒臭さがありますが、シンボルはその必要がないため効率がよく高速に比較することができます。

## まとめ
以上のことから、シンボルは**文字列のように破壊的な変更ができないため、「名前などの勝手に変更されては困るデータ」を取り扱う際に向いている**ということがわかりました。

## 最後に
改めて見直すと今回の記事でもいろんな発見があった気がします。
引き続きRubyの学習を継続させていきRubyマスターに俺はなる！！っていう意気込みで頑張って参りますので応援よろしくお願いいたします。笑
最後まで本記事を読んでくださりありがとうございました🙇

## 参考文献
https://docs.ruby-lang.org/ja/latest/class/String.html

https://pikawaka.com/ruby/hash
モバイルアーキテクチャについて

モバイルアーキテクチャについて書いてみる。

大きく3つに分かれるぞ。

・無線(Radio Access Network)
・コアNW (Mobile Network Core)
・サービス (Service)

端末は無線の一部だ。IMSはコアNWではなくサービスの一部だ。
IMSはコアNWではない、サービスだ。

2G,3GはVoiceとDataを提供していた。
4G,5GはDataのみを提供している。

IMSはDataの上で踊る音声提供サービスの一つである。

無線：
割愛

コアNW:
いつの時代も役割は3つある。
・Mobility Management(位置登録、ハンドオーバー、ページング）
・Session Managagement(データセッション、QoS、RANプロビジョニング）
・Subscriber Management(加入者データベースの更新）

サービス：
IMS(IP Multimedia Service)だ。
LTEではVoLteと呼ばれる、5GではVoNRと呼ばれる。

LINEもDataの上で踊るサービスの一つだろう。
PICAXEで赤外線リモコンを作り、Arduinoと赤外線通信してみる

# はじめに
[__前回__](https://qiita.com/ricepaddy/items/2b636500bc9b12738d0a)はPICAXEの書き込み環境を構築し、動作確認まで終わりました。今回は実際にPICAXEを使って赤外線リモコンを作ろうと思います。追加で必要な部品はスイッチと赤外線LED、抵抗のみ。さらには送信された赤外線信号をArduinoで読み取り、簡単な赤外線通信も試してみたいと思います。
![picaxe_ir.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/351c711d-3072-157d-ca75-1157d2a2f5be.jpeg)
# 開発環境
* Windows 11 Home 22H2 (22621.1265)
* PICAXE Editor 6.1.0.0
* Arduino IDE 1.8.13
* IRremoteESP8266 2.8.2
# PICAXE側について
## 追加で必要な部品
| 部品名 | 個数 | 参考価格 |
|:--|--:|--:|
| 赤外線LED | 1個 | 10円 |
| タクトスイッチ | 2個 | 20円 |
| 10kΩ抵抗 | 2個 | 2円 |
| 100Ω抵抗 | 1個 | 1円 |
## 赤外線信号のフォーマット
[__マニュアル__](https://picaxe.com/docs/picaxe_manual5.pdf#page=17)によるとPICAXEが出力できる赤外線信号はSIRC方式のようです。これはソニー製品で使われているフォーマットです。送信データは12ビット、15ビット、または20ビットと大きさの異なる3タイプが定義されていますが、PICAXEの場合は12ビットです。7ビットがコマンド、5ビットがアドレスに割り当てられており、アドレスの値は操作対象となるデバイスの種類を表します。ただし、ビジュアルプログラミング言語で開発する場合はアドレスの値がテレビを表す1で固定されており、コマンドの値のみ0から127まで指定できるようです。BASIC言語で開発する場合はアドレスの値も1から31まで指定できます。
## 配線図
前回作った書き込み回路を流用し、スペースが空いていた左半分を今回使いました。
![breadboard-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/09d2debc-b354-cc75-42e2-a4a8d90d6965.png)
## Blockly
入力ピンはプルアップしています。コマンドの値は左スイッチに0、右スイッチに1を割り当てました。入力ピンの状態が変化するまで待機するブロックを使うと簡単にエッジ検出できるので便利です。また、ソニー製のテレビなら操作できると思います。
![picaxe_ir_blockly.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/6a090090-58ee-dcdd-3fd0-520b4b6e1d99.jpeg)
# Arduino側について
ここからはArduinoを使って赤外線信号を読み取り、PICAXEで作った赤外線リモコンが正常に動作しているか確認してみます。
## 主に必要な部品
| 部品名 | 個数 | 参考価格 |
|:--|--:|--:|
| ESP32-DevKitC | 1個 | 1600円 |
| 赤外線リモコン受信モジュール | 1個 | 50円 |
| LED | 1個 | 10円 |
| 330Ω抵抗 | 1個 | 1円 |
## 配線図
実際とは異なる部分もあるため、適宜変更してください。
![ir_receiver_breadboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/2bef0cdb-a591-44a6-3865-05f7e87785eb.png)
## スケッチ
LEDはコマンドの値が0なら消灯、1なら点灯します。つまり、PICAXEで作った赤外線リモコンの左スイッチを押したら消灯、右スイッチを押したら点灯します。
```cpp:ir_receiver.ino
#include <IRremoteESP8266.h>
#include <IRrecv.h>

const uint16_t RECEIVE_PIN = 21;
const uint16_t INDICATOR_PIN = 23;

IRrecv receiver(RECEIVE_PIN);


void setup() {
  Serial.begin(115200);
  Serial.println("Started");

  pinMode(INDICATOR_PIN, OUTPUT);
  digitalWrite(INDICATOR_PIN, LOW);
  
  receiver.enableIRIn();
}

void loop() {
  static decode_results results;
  
  if (receiver.decode(&results)) {
    if (results.decode_type == SONY) {
      uint32_t address = results.address;
      uint32_t command = results.command;
      
      if (address == 1) {
        if (command == 0) {
          digitalWrite(INDICATOR_PIN, LOW);
        } else if (command == 1) {
          digitalWrite(INDICATOR_PIN, HIGH);
        }
      }

      Serial.printf("Address: %x, Command: %x\n", address, command);
      yield(); 
    }
    
    receiver.resume();
  }
}
```
# おわりに
今回はPICAXEで送信側、Arduinoで受信側を作り、赤外線通信を試してみました。SIRC方式の赤外線信号に限るものの簡易的な無線通信の手段としては使えそうです。
# 参考文献
https://www.sbprojects.net/knowledge/ir/sirc.php
conoha vpsの一般ユーザのssh接続でつまづいた話


## 前置き

数個前の記事にてレンタルサーバー無料期間を堪能していたんですが終了してしまったので乗り換えてきました。
レンタルサーバーだとある程度インストールされていたので簡単でしたが、それ以前の状態も触ってみたかったので今回はConoha VPSを借りることにしました。

https://www.conoha.jp/vps/?banner_id=b04_vps&utm_source=google&utm_medium=cpc&utm_campaign=brand&utm_content=vps&gclid=CjwKCAjwrdmhBhBBEiwA4Hx5gzZoj72gXNkZFnwiygm3isBBnQlpeQdMuoo8eb6Gqa-H4lyMRhFLGxoCX2wQAvD_BwE

### 仕様
- 1Gプランを3ヶ月
- OS:CentOS stream 9
- (SSLはつかない方にしたのでそのうちcertbot使います)

https://certbot.eff.org/

### つまづくまで

rootにssh接続する事はできていたのでrootからの脱却を目指していました。

https://support.conoha.jp/vps/guide/vpsstartup/?btn_id=v-useradd-sidebar_guide-vpsstartup
を見ながら
    
    # user add [user名]
    # passwd [user名]

を行い一般ユーザを作成してssh接続させようとしたのですが

https://support.conoha.jp/v/addusersshkey/?btn_id=guide-vpsstartup-sidebar_v-addusersshkey

だと一回パスワードログインを許可する必要がある記述があり、
個人開発では許されますが、許されない場合を考えて他の方法でやってみようとしてつまづきました。

## 解決編

最初にやることとしてrootにssh接続用の公開鍵(authorized_keys)は存在していたのでroot側で
~~~
# chmod 700 .ssh
# chmod 600 .ssh/authorized_keys
chown [user]:[user] .ssh
chown [user]:[user] .ssh/authorized_keys
~~~
でパーミッション関連と所有権の設定を行い一般ユーザがログインできる基盤を作りました。

その後この鍵をどの様にrootからユーザに渡そうか悩んでいたんですがディレクトリの構造をど忘れしていたのが原因で時間がかかりました。

https://qiita.com/uhooi/items/c1388f8d803641bfb8f3

ここの/homeを経由することでユーザ側に受け渡す事ができ、無事に解決しました。

(例)
~~~
mv .ssh ../home/[user]/
~~~

# 結論
素直にサポート通りに従っても良かったですが遠回りした分の知見を得られたので良かったです。
sshkeyの所有権も考慮する必要がある事も盲点だったので今回で知れて良かったです。
次はApache,DBのインストールをやっていきたいです。
【AWS】CLIでEC2やRDSの情報をCSV形式で一挙に取得する方法（jqコマンドやsedコマンドの利用方法・意味も解説）

# 概要
* AWSで使用中のEC2やRDSの情報を一覧で取得したい時ってありますよね。そんな時は、以下のコマンドをAWS CLIで実施すればすぐに取得できます。

## 前提
* aws-cli: 2.11.10
* jq: 1.5
* CSV形式で取得する前提

# AWS CLIコマンドで取得する方法
* AWS CloudShellにアクセスします。
    * AWS CLI(Command Line Interface)がインストールされており、認証情報の設定がされている方は、そちらから実施してもOKです。
* CLIで、`describe`コマンド(AWSのリソースに関する情報を取得するためのコマンド)を利用します。
    * `--query`オプションを使用して、取得する情報のフィールドを指定し、`--output`オプションを使用して、出力形式を指定できます。
    * 具体的には以下の通りです。
* 他にも色々オプションがありますが、今回は最低限のものだけ記載しておきます。
    * 例えば、`--filters`オプションを使えば、実行中のインスタンスの情報のみ取得することができます。

## EC2の情報を調べる場合
* Nameタグ, インスタンスタイプ, プラットフォーム(OS)を知りたい場合

```
aws ec2 describe-instances \
--query 'Reservations[*].Instances[*].[Tags[?Key==`Name`].Value | [0], InstanceType, PlatformDetails]' \
--output text | sed -e 's/\t/,/g'
```

* `PlatformDetails`は、インスタンスのプラットフォームがLinuxベースの場合です。
    * Windowsインスタンスの場合は`Platform`になります。
* 単純なテキスト形式で出力されるのでCSV形式に変換します。
    * `sed`：テキスト処理を行うコマンド
    * `-e`：後続する文字列がスクリプトとして解釈されることを指定
    * `s/\t/,/g`：スクリプトの中で実行される置換コマンドで、タブ文字(`\t`)をカンマ(`,`)に置換することを指定
        * `g`：全てのタブ文字を置換することを指定します。

## RDSの情報を調べる場合
* DB インスタンス ID、インスタンスクラス、ストレージ、エンジンを知りたい場合

```
aws rds describe-db-instances \
--query 'DBInstances[*].[DBInstanceIdentifier, DBInstanceClass, AllocatedStorage, Engine]' \
--output text | sed -e 's/\t/,/g'
```

* 上記はEC2の時と同様、`sed`コマンドを使用して取得する
* `jq`コマンドを利用して、以下のように取得することもできます。

```
aws rds describe-db-instances \
--query 'DBInstances[*].[DBInstanceIdentifier, DBInstanceClass, AllocatedStorage, Engine]' \
--output json \
| jq -r 'map(select(. != null) | @csv)[]'
```

* `jq`：JSONデータのフィルタリングや変換を行うコマンドラインツール
* `-r`：ダブルクォーテーションを除去
* `map(select(. != null) | @csv)[]`：配列から`null`値を除去して、カンマ区切りのCSV形式に変換

## `--output csv`で出力できないのか？
* `--output text`を`--output csv`にすればCSV形式で取得できるんじゃないの？って思いましたが、以下のようなメッセージが返ってきてしまいます。AWS CLIには存在しないオプションみたいです。できるようにしてほしいなぁ。需要ありそうだけど。。。

```
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help

aws: error: argument --output: Invalid choice, valid choices are:

json                                     | text                                    
table                                    | yaml                                    
yaml-stream 
```

## 参考記事
* [Amazon EC2 インスタンスの起動、一覧表示、および終了](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-ec2-instances.html#listing-instances)
* [EC2 インスタンス一覧を特定の条件でフィルタリングしてから特定の項目を抽出した上で CSV 形式で出力してみた](https://dev.classmethod.jp/articles/ec2-export-csv/)
clasp、npm配布パッケージをGAS上で使用 ~esbuildを用いて~


以下URLを参考にしたけど、ちょっと苦戦した部分のメモ。

https://zenn.dev/faw/articles/clasp-with-import

**buildファイル**
importではなくrequireで読み出さないとエラーになる（コピペすれば発生しない、自分の凡ミス）
- [import と requireの違い解説記事](https://qiita.com/minato-naka/items/39ecc285d1e37226a283)



**esbuildの使い方**

https://qiita.com/hedrall/items/2548718cfdf7bef3efc0
```bash:build実行
$ node build.js
```
上記コマンドを実行することで、ビルド結果のファイルを作成することができました。


## 別の方法

自分は試してないですが、`rollup` パッケージを利用してもできるらしいです。

https://qiita.com/suzukenz/items/dbe13d5f8884752a37f8
大学生が、データサイエンティスト検定リテラシーレベルに1ヶ月で合格した話【DS初学者】

データサイエンティスト検定リテラシーレベルを、初学者ながら1ヶ月かからず合格したので、ノウハウをまとめました。

この記事を読めば、
・**DS（データサイエンティスト）検定とは**
・**必要な教材**
・**合格して得られるもの**
が明確になると思います！

# 自己紹介(学習歴)
慶應義塾大学理工学部管理工学科4年生。大学では統計やAI、数理最適化、金融工学、IE、プロジェクトマネジメント、経済などを幅広く理系的な視点から学んでいる。まあ、データサイエンスとは距離が比較的近い学部だと思う。

Twitterはこちら→[@A7_data](http://twitter.com/A7_data "my twitter")
<dl>
  <dt>2022年1月</dt>
  <dd>統計の勉強を本格的に開始</dd>
  <dt>2022年4月6日　</dt>
  <dd>統計検定2級合格（優秀成績賞)</dd>
<dt>2022年6月</dt>
  <dd><a href="https://codegym.jp/academy">CODEGYM ACADEMY</a>参加。<a href="https://cs50.jp/">CS50</a>などの講義を通し、Flaskでアプリを個人開発</dd>
<dt>2022年6月14日</dt>
  <dd>データサイエンティスト検定リテラシーレベル合格</dd>
<dt>2022年8月24日</dt>
  <dd>統計検定準1級不合格</dd>
<dt>2022年9月14日</dt>
  <dd>統計検定準1級合格（最優秀成績賞)</dd>
<dt>2022年9月30日</dt>
  <dd>簿記3級合格</dd>
<dt>それ以降</dt>
  <dd>機械学習を中心に勉強中。理論を勉強しながらSIGNATEやKaggleをちょこちょこ。深層学習にも手を出してる</dd>
<dt>2022年12月</dt>
  <dd>SIGNATE Intermediateに昇格</dd>
<dt>2022年12月</dt>
  <dd><a href='https://twitter.com/DSL_Tw'>データ分析特化型学生団体DSL　
@Data_Science_League</a>に加入。日々勉強中。</dd>
<dt>2023年1月</dt>
  <dd>SIGNATE 第一回金融データ活用チャレンジ Databricks賞受賞</dd>

</dl>

# 本記事はNoteに移行しました
こちらをご覧ください

https://note.com/a7_data/n/n2c46bc2d0274
RubyでAtCoder ABC283(A, B, C, D)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC283のA, B, C, Dを解きました。備忘録として解き方をまとめていきたいと思います。

# A - Power
https://atcoder.jp/contests/abc283/tasks/abc283_a
```ruby:a-283.rb
a, b = gets.split.map(&:to_i)
puts a ** b
```

# B - First Query Problem
https://atcoder.jp/contests/abc283/tasks/abc283_b
```ruby:b-283.rb
gets
a = gets.split.map(&:to_i)
q = gets.to_i
q.times do
  t, k, x = gets.split.map(&:to_i)
  case t
  when 1
    a[k - 1] = x
  when 2
    puts a[k - 1]
  end
end
```
## 解説
問題文の通りに実装すればOKです。

# C - Cash Register
https://atcoder.jp/contests/abc283/tasks/abc283_c
```ruby:c-283.rb
s = gets.chomp
n = s.size
s = s.split("00").join
m = (n-s.size) / 2
puts s.size + m
```
## 解説
<方針と実装方法>
例えば、s=16000020であったとします。このとき、操作としては1->16->1600->160000->1600002->16000020のように計６回の操作が必要となります。
ここで、00を押したとき100倍とする操作は他のボタンと異なる操作なのでこれで切り分けることを考えます。splitメソッドを使って、切り分けると16000020は1620となります（(もとのsの大きさ-切り分けた後のsの大きさ)/2=00を押した数）。また、切り分けた後のs大きさは00以外のボタンを押す回数と一致します。以上のことから、これらの数を足した値が答えとなります。

# D - Scope
https://atcoder.jp/contests/abc283/tasks/abc283_d
```ruby:d-283.rb
s = gets.chomp.chars
arr = []
hash = {}
s.each do|i|
    case i
    when "("
        arr << i
    when ")"
        until arr[-1] == "("
            a = arr.pop
            hash[a] = false
        end
        arr.pop
    else
        if hash[i]
            puts "No"
            exit
        end
        hash[i] = true
        arr << i
    end
end
puts "Yes"
```
## 解説
（他の方の提出結果を参考にしました）
与えられた文字列の要素それぞれに対して以下の操作を行うことで実装することができます。

１．"("のとき
arrayに格納します。
２．")"のとき
arrayの末尾が"("となるまで要素を取り除き、連想配列hashにおけるそのkeyに対応するvalueをtrueにします。
３．小文字のとき
文字が箱（hash）に入っていればNoを出力して終了し、入っていなければtrueにしてarrayに格納します。最後まで、探索できればYesを出力します。

# 終わりに
D問題が解けませんでした...
また、C問題は実装に工夫が必要で苦手な系統の問題でした。めげずに頑張っていきましょう！

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166
:checked

# :checked
```:checked は CSS の擬似クラスセレクター```で、ラジオボタン (<input type="radio">)、 チェックボックス (<input type="checkbox">)、 オプションボタン (<select> の中の <option>) 要素が```チェックされていたり on の状態```にあったりすることを表します。

```css
/* すべての選択中のラジオボタン、チェックボックス、オプションボタン */
:checked {
  margin-left: 25px;
  border: 1px solid blue;
}
```

ユーザーは要素を```チェック/選択することでこの状態にする```ことができ、```要素のチェックや選択を外すとこの状態から外れます```。

# 出典
https://developer.mozilla.org/ja/docs/Web/CSS/:checked#:~:text=%3Achecked%20%E3%81%AF%20CSS,%E3%81%8B%E3%82%89%E5%A4%96%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82
SQL Serverで別名のバックアップを取る時エラーになる

SQL Serverで最初に既存のバックアップ先・ファイル名でバックアップを保存した後、今度は別ファイル名でバックアップを取ろうとした時、以下のようなエラーが出た。
>***.bakに読み込まれたメディアは1メディアファミリをサポートするようにフォーマットされていますが、バックアップデバイスの仕様では、2メディアファミリが必要です。

参考サイトを調べた所、既存のバックアップ先ファイル名を削除してから新しいバックアップ先ファイル名を指定して保存すれば良いとの事。

それで確かに保存できました。

# 参考サイト
https://xoblos.hatenablog.jp/entry/2017/10/15/220920
aws lightsail phpのバージョンを変更

参考
https://qiita.com/hamburg-love/items/3aecc7753e36013f874c
https://www.konosumi.net/entry/2023/01/22/204340

# php8.2あるか確認
```
amazon-linux-extras
```

うほっ！見つけたよぉ❤

```
68  php8.2            available      [ =stable ]
```

# まずは古いphpをすべて削除

```
# 古いphpすべて削除 (これを先にやらないと古いphpが動いてしまう)
yum remove php*

# インスコ
sudo amazon-linux-extras install php8.2

# configファイルを探す
find / -name "*www.conf*" -print
vim /etc/php-fpm.d/www.conf



```


# www.conf 変更

ESC 状態で`:set number`と入力し、行番号を表示させておくと楽


```
###変更###
;listen = 127.0.0.1:9000
listen = /var/run/php-fpm.sock

### 24行目あたり ###
# 変更前
user = apache
# 変更後
user = nginx

### 26行目あたり ###
# 変更前
group = apache
# 変更後
group = nginx

### 48行目あたり ###
# 変更前
;listen.owner = nobody
# 変更後
listen.owner = nginx

### 49行目あたり ###
# 変更前
;listen.group = nobody
# 変更後
listen.group = nginx

### 50行目あたり ###
# 変更前
;listen.mode = 0666
# 変更後
listen.mode = 0666
```

# 再起動してインスコ確認

```
systemctl restart php-fpm.service
sudo systemctl restart nginx
php -v
```

# その他のものをインスコ

```
# redis をインスコ (このやり方をしないと入らない)
amazon-linux-extras enable epel
yum install epel-release
sudo yum install -y http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
sudo yum -y --enablerepo=remi-php82 install php-pear
pecl install redis
echo "extension=redis.so" >> /etc/php.ini

# その他もろもろ
sudo yum install php-mbstring php-pdo php-gd php-mysqlnd php-xml php-opcache php-fpm

# 再起動
systemctl restart php-fpm.service
sudo systemctl restart nginx

```

なんか色々エラーが出るので composer も update
とくに carbon 。。。

```
cd /var/www/html/yourdir
composer update nesbot/carbon
vim composer.json
```


いやーめちゃくちゃ簡単にインスコできますね。
≪ クロージャ ≫

# 01.　クロージャとはなにか
クロージャとは、
- ある関数から返された関数
- 返された関数が生成された時にその外側にあった環境（変数）

が組み合わさったもの。

# 02.　なぜ重要？　/　実際の現場でどう使う？
- クロージャを使用することで関数の外側からのアクセスをブロックできるため
☞　変数の再代入による予期しないエラーを防止する

- また、同じような処理を行う場合をクロージャした関数を流用できる
☞ コードの簡略化により、可読性を上げる

# 03.　クロージャの例
```
A. クロージャした関数　：　　　　func2の"x"は外側からアクセスできない

const func1 = x => func2(y) => x + y;
const addTen = func1(10);
addTen(90)   // => 100

x = 100;     // func2の"x"に影響しない
addTen(90)   // => 100



B. クロージャしてない関数　：　　　　func3の"x"は外側からアクセスできる

let x = 10;
const func3 = y => x + y;
func3(90)    // => 100

x = 100;     // func3の"x"に影響する
func3(90)    // => 190　（100が返ってきてほしい）
```
続データーシートの読み方

RTL8366のATUサポートのためデーターシートを確認してみます。

Lookup and VLAN Table Engine Accessという記載がありますが、わけのわからないことが書いてあって、こちらもなんだか詳細不明です。

RTL8366サポートは勇士が書いたLinuxのコードと本家のコードが存在します。

githubで検索するとLinuxのコードに埋もれた結果になります。

ローカルのファイルを探してみたところ、本家のコードにrtl8366rb_api.c:rtl8366rb_getLUTUnicast()という関数があり、これがおそらく目的の処理ではないかと思われます。しかしとっても見通しが悪いです。

このコードにあるレジスタ処理はデーターシートと齟齬があります。

と思ったのですが、この処理は指定されたMACアドレスがLUTにある場合ポートを返すようです。

```
@comm
        If the unicast mac address existed in the LUT, it will
    return the port where the mac is learned and blocking state.
    Otherwise, it will return a ERRNO_API_LUTNOTEXIST error.
```

ダンプには使えなさそうです。他の関数もみてみたのですが、RTL8366RBでは一覧を拾う機能はなさそうです。

RTL8366は初期のGigaのSwitchでATUをダンプする機能をサポートする余裕がなかったのかもしれません。
UiPathインストール・バージョンアップガイド2022.10版の主な変更点

# はじめに
以下のリンクで、UiPath Studio/Robot v2022.10 のインストールガイドと、バージョンアップガイドが公開されました。インストールガイドとバージョンアップガイドで、合計80ページを超えるボリュームになっています！

https://www.uipath.com/ja/community-blog/knowledge-base/uipath-version-up-guide

※ 制作にかかわった皆さん、いつもありがとうございます！！(*´▽`人)

2022.10になって手順や考え方が従来からガラッと変わった訳ではなく、従来の考え方に一部の変更が加わった内容になっていますので、主な変更点について抜粋でご紹介します！

# インストールガイドの変更点

## インストーラの種別(P13)
32bit版の提供の廃止について記載されています。

## 接続方式について(P17~)
P17, P19: マシンキー接続、対話型サインイン接続に加えて、新たに **クライアント資格情報** を用いた接続が紹介されています。
p.31, p.32 クライアントID/シークレットを用いた接続のイメージが紹介されています。

:::note warn
**マシンキーの非推奨化**
マシンキー接続は非推奨機能となっています。非推奨の機能の利用はサポートされていますが、将来的に削除される可能性があります。詳しくは以下のURLをご参照下さい。
https://docs.uipath.com/ja/overview/other/latest/overview/deprecation-timeline
:::


# バージョンアップガイドの変更点
## サポートモデルについて(p.7)
2022.4より全てのバージョンがLTSサポートに変更されました。
※従来は4月のリリースはFTSサポートでした。

## 互換性マトリックス (p.10, p.11) 
最新のマトリックスが反映されたものになっています。

## クラシックフォルダーの廃止予定について（p.21）
v2023.4でのクラシックフォルダーの廃止予定についての説明があります。

:::note info
2023年4月以降でも、以前のバージョンの製品を使っている間はクラシックフォルダーを利用できます。ただし、いずれはサポートが切れてバージョンアップが必要になる為、その前にモダンフォルダーへの移行が必要となります。
:::

## レガシプロジェクトのマイグレーションについて (P23~)
各対応OSの説明が記載されています。また、Windowsレガシの廃止、およびWindowsへの移行時の注意点などが記載されています。

:::note warn
**Windowsへの移行後の動作について**
WindowsレガシからWindowsへの移行は移行ツールで実施可能ですが、移行後に動作が変化する場合があるので、動作確認して頂く必要があります。
:::

:::note warn
**ライブラリの互換について**
WindowsレガシとWindowsの間での互換はなく、開発中の自動化プロジェクトと異なる対応OSで開発されたライブラリを使う事はできません。また、対応OSがWindowsの自動化プロジェクトで公式アクティビティを利用する場合は、Windowsに対応したものだけをご利用頂けます。Windowsへの対応状況は下記URLでご確認下さい。
https://docs.uipath.com/ja/activities/other/latest/user-guide/introduction
:::



:::note warn
**[2023/04/13追記] Windowsレガシの非推奨化の時期について**
現時点ではWindowsレガシプロジェクトの作成に対するサポートの終了時期は明示されていません。最新の情報は以下のURLをご参照下さい。
https://docs.uipath.com/ja/overview/other/latest/overview/deprecation-timeline
:::
CSSの「-webkit-box-orient」が効かない問題の解決法

# テキストが複数行になった場合、省略の3点リーダーをつける
テキストが複数行になった場合にCSSで省略の3点リーダーをつけようと思い、2行で省略しようと、-webkit-line-clampを使って省略指定をしてみました。
```
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;//3点リーダを表示する行数を指定
overflow: hidden;
```
なぜか-webkit-box-orientだけが、反映されず消えてしまい、
3点リーダーが付かず動かないので調べたら解決法がありました。

# Autoprefixerに原因があった
__-webkit-box-orientを勝手に削除してしまうバグ__ があるらしいです。
SCSS中で直接Autoprefixerを有効・無効を指定してあげれば解決します。
```
display: -webkit-box;
/*! autoprefixer: off */
-webkit-box-orient: vertical;
/*! autoprefixer: on */
-webkit-line-clamp: 2;
overflow: hidden;
```
また、SCSSコンパイル時のoutputStyleが `compressed` になっていると、コメント自体が削除されてしまうので、 `/*! コメント */` としてください。
個人開発におけるGit, Git Hub, Issue機能を使って,main, develop, featureブランチを切って開発するやり方(自分用)

# Git Hub上でリポジトリを作成

# ローカル環境で初期化
開発したいファイルのターミナルで

    git init //初期化
    git remote add origin http://.....
    //何かしらファイルをつくる(空だと通常pushできない)
    git add .
    git commit -m "first commit"
    git push origin main

これで土台完成

# IssueをTodo形式で追加
HubのIssue機能にtodo形式で追加していく
・ボタンをつくる
・タイトルを作る
・色をつける
このとき自動で番号が割り当てられるので，それがあとでブランチを切るときfeature/番号のように使われる

# developブランチを切る

Hub上でブランチも切ることができるが，ローカルでブランチを切ってそれを同期させるやりかたで統一する.
ローカルで以下を実行

    //はじめはmainブランチにいる
    git checkout -b develop //developブランチを切って，入る.
    git push -u origin develop 
-uを付けるとorigin上の同名のブランチにdevelopを反映するという意味になるが，今は存在しないのでHub上にdevelopというブランチが作られる．

# featureブランチを切る
    git checkout -b feature/2-create-title //feature/3-create-titleというブランチを切って，入る
    git git push -u origin feature/2-create-title 
ここでfeature/2-create-titleブランチの2はIssueの番号から取る．
pushによってリモートにもブランチが追加された.
このブランチ上で開発する.

# プルリクエストを出して，マージする
featureが完成したら以下を実行して，コミットを反映させる
   
    git add .
    git commit -m "#2 add title" //#2のようにIssue番号つけるとよい
    git push -u origin feature/2-create-title

これでHub上のfeature/2-create-titleブランチに変更が反映される．
するとHub上からプルリクエストをだせるようになるので，developブランチに対してプルリクエストを出して，マージする．
この時点でローカルとHub上でdevelopブランチが異なるので，pullで最新の状態にする

    git checkout develop
    git pull origin develop //Hub上でマージされた結果が反映される
あとは使わなくなったブランチを削除し，Issueをcloseにする．

このようにしてfeatureブランチを切って，developにマージを繰り返して開発を進めていく．mainは原則触らない．