OmniAICreator/Qiita-1.07M huggingface dataset:
タケルが今日学んだこと（初心者向け：docker-compose.ymlの中身をいじってみた）

<h1>学んだこと

本日は、docker-compose.ymlの中身をいじってみました。

ファイルの中身は、正直何が書いてあるかわかりませんでした。
しかし、今日はファイルの中身が、どのようになっているのか克服することができたので、
その学び方をレクチャーしたいと思います！

<h1>ファイルの中身の学び方

今回は、サンプルコードを使って説明していきます。


``` 
(サンプルコード)
app:
    container_name: app
    build:
      context: ./docker/app/
    volumes:
```

今回はこのようなコードとした時に、正直初心者だとみたくないですよね。。。
しかし、理解できないと一生一人前のエンジニアになれないと思います。

そこで、まずは一つ一つ調べていくことにしてみました！

```
app:
```
これは、文字列になります。今回は、appと書いてあるので、アプリケーションソフトウェアになります。
文字列とは何ぞやということですが、書式または表示形式を表しています。


```
container_name: app
```
 `container_name`は起動するコンテナ名という意味です。次に書いてある`app`は、アプリケーションソフトウェア
なので、アプリケーションソフトウェアを起動するということになります。


```
build
```
これはこのままの意味で、組み立てる、作り上げるという意味になります。


```
context: ./docker/app/
```
`context`とは、判断材料や条件を示す意味になっています。
`/docker/app/`と書いてあるので、今回はdockerの中のappが記されているということになります。

```
volumes:
```
`volumes`とは、データを永続的化できる場所です。
パッとしないと思いますので、https://qiita.com/gounx2/items/23b0dc8b8b95cc629f32
こちらで調べさせていただきました。丁寧にまとめてあったので見てみるといいと思います！
ちなみに、外部記憶装置に反対は、主記憶装置と言ってメモリのようなものらしいです。


<h1>まとめ

このように、一つ一つ調べていくとどのようなことが書いてあるのかが少しづつ理解していけると思います。
初心者だと調べ方がわからなかったり、どれを調べればいいのかわからなかったりと何から手をつけていいかわからないことが多々あります。最初のうちは、時間をかけて調べることが私は大切だと思います。

今回は、調べ方の説明にはなってしまいましたが参考にしていただければ嬉しいです。
明日からも学んだことをアウトプットできるように勉強していきます！
SQLで日付を出力してみよう [current_date,current_timestamp,extract]

SQLにて、現在の時刻などを出力する際に用いるコードとして
`current_date`や`current_timestamp`などがあります。
実際にコードを見ていきます。
![スクリーンショット (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/427bb440-2179-5eee-25a2-7df286cc04f5.png)

1行目は用いるデータベースを選択
2行目は現在の時刻を表示させます。実際に表示されるクエリはこのようになります。
![スクリーンショット (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/826b4b3e-c932-cdce-48e6-0b22002b4544.png)

本日は６月２日なので、このように表示されます。
3行目は時刻を表示させるものになります。
![スクリーンショット (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/bb48cb1e-7e5e-fcc1-9f3e-fa975db61798.png)

これらを上手に活用することによって、～日後や～時間後の日付を表示させることも可能です。
それが4,5行目のクエリになります。
４行目クエリ
![スクリーンショット (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/fe9ba050-558a-2b95-6861-2a86a319dbfc.png)
５行目クエリ
![スクリーンショット (13).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/492d6fb3-b6d9-efc9-32e0-7898b72d2ed2.png)


６行目は、`extract()`用いることで特定の日付を選択させて抽出することができます。
この場合、特定の年月を選択したいので、
引数に year_monthとして、どのカラムを対象として検索するのかを選択します。
そのあとに == で特定の年月を繋げます。
抽出された結果がこちらとなっています。
![スクリーンショット (15).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/a1fd61b3-1374-ef6b-6770-86ce9c3089c8.png)

これで特定の年月を抽出することができました。

今回は、日付の扱い方について説明してきました。

### 実行環境
windows10 core-i5
XAMPP Control Panel v3.3.0
MySQL Workbench
インターネットと通信するLambda関数はプライベートサブネットに配置する必要があるという一見矛盾した話

正確には「VPC内に配置したLabmda関数がインターネットと通信する場合」の話しです。
Lambda関数をVPC内に配置するときはこうしろっていうのは検索すればすぐ出てくるのですが、理由が書かれてない記事が多いので取り上げてみました。

## 背景
Security Hubを導入したところ準拠すべきセキュリティルールの中に「Lambda関数はVPC内に配置せよ」とあったので、適当なVPCの適当なパブリックサブネットに配置した。

## 事象
EC2を自動起動停止させるLambda関数が「Task timed out after XX.XX seconds」で動かなくなった。

## 対応1 (解決せず)
タイムアウトを伸ばしてみた。→解決せず
元々タイムアウト3秒で正常に動いていたが、エラーメッセージがタイムアウトなので30秒まで伸ばしてみたが、それでもタイムアウトする。

## 原因
今回言いたかったのはこれ。
実はLambda関数はパブリックサブネットに配置してもパブリックIPが払い出されないらしい。
AWSのドキュメントに下記の記述があった。

[VPC 内のリソースにアクセスするように Lambda 関数を設定する](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-vpc.html)
>プライベートリソースにアクセスするには、関数をプライベートサブネットに接続します。関数にインターネットアクセスが必要な場合は、ネットワークアドレス変換 (NAT) を使用します。関数をパブリックサブネットに接続しても、インターネットアクセスやパブリック IP アドレスは提供されません。

このLambda関数はEC2を起動停止させるAPIを叩くために、VPC外 (AWSのAPIエンドポイント) へのアクセスが必要なのでこれに該当する。

## 対応2 (解決)
すでにNATゲートウェイを持つプライベートサブネットがあったのでそこに配置し直したら解決した。
NATゲートウェイを持つプライベートサブネットを新規に作成する場合の手順もAWSのナレッジにあるので、必要な場合はこちらをご参照ください。
[Amazon VPC に接続されている Lambda 関数にインターネットアクセスを許可するにはどうすればよいですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/internet-access-lambda-function/)

## 補足
最初にLabmda関数を配置したパブリックサブネットはデフォルトでパブリックIPを割り当てる設定 (「パブリック IPv4 アドレスを自動割り当て」が有効) になっていましたが、それでもLambda関数にはパブリックIPは割り当てられませんでした。

「Lambda関数をVPC内に配置せよ」と言われたとき、仕様を知らないと調べもせずに「この関数はインターネット通信あるからパブリックに」とやってしまうことがあると思いますが、このような落とし穴があるのでご注意ください。
sitemap generator + jsonでサイトマップ生成

SEO対策でサイトマップをGoogleに登録するため、サイトマップを生成することにしました。
ただ、Next.jsのSSRでサイトを実装していて
インデックスさせたいページの件数が膨大(50万件くらい)だったので、手動で作るのは無理です。

Railsで「sitemap generator」という便利そうなgemがあったので、
こちらを使ってサイトマップを生成してみます。
インデックスさせたいURLは、jsonで下記のような形式で用意しました。

```json
{
  {"id": "123456"}
  {"id": "234567"}
}
```

まずgemをインストール。

```
gem install sitemap_generator
```

`sitemap.rb`というファイルを作成し、下記の内容を記述します。

```ruby:sitemap.rb
require 'rubygems'
require 'sitemap_generator'

## 空配列を用意
idList = []

## jsonデータからidの値を読み込む処理を書く(本記事では割愛)
## idListという配列に入れる

SitemapGenerator::Sitemap.default_host = 'http://example.com'
SitemapGenerator::Sitemap.create do
  idList.each do |id|
    add id, :changefreq => 'monthly'
  end
end
```

これで下記コマンドを実行。
```
ruby sitemap.rb

+ sitemap.xml.gz                                           2 links /  50 Bytes
Sitemap stats: 2 links / 1 sitemaps / 0m00s
```

すると、sitemap.xml.gzが/publicに出力されます。
（ここはオプションで出力先を変えることもできるみたいです）

gzは圧縮ファイルなので、解凍して中身を確認。

```:sitemap.xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:pagemap="http://www.google.com/schemas/sitemap-pagemap/1.0" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <url>
    <loc>http://example.com/123456</loc>
    <lastmod>2022-06-02T17:37:08+09:00</lastmod>
    <changefreq>weekly</changefreq>
    <priority>1.0</priority>
  </url>
  <url>
    <loc>http://example.com/234567</loc>
    <lastmod>2022-06-02T17:37:08+09:00</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
</urlset>
```

無事サイトマップが生成されました。
超膨大(50万件)のjsonデータを読み込ませても、無事生成できました。

しかも、サイトマップはGoogleが1つのサイトマップにつき50,000件までのURLを推奨していますが、このsitemap generatorはデフォルトで50,000件以上になるときは、下記のように分割して生成してくれます。
```
── public
    └─sitemap.xml.gz  (分割して生成されたsitemap1、2のインデックス用sitemap）
    └─sitemap1.xml.gz 
    └─sitemap2.xml.gz 
```

インデックス用のサイトマップまで生成してくれるのは助かりますね。
あとはGoogleにサイトマップの送信で`sitemap.xml.gz`と、解凍した方の`sitemap.xml`を送信すればOKです。
(`sitemap.xml.gz`だけの送信でも良いようですが)

他にもいろいろオプションで設定できそうなので便利ですね！


## 参考
https://github.com/kjvarga/sitemap_generator
Androidの自動バージョンインクリメントをgradleのタスクで実行

CIなどで自動化するときにバージョンもついでに上げたくなるのでこの設定で最近は落ち着いたので備忘録メモ
ktsしたいけど、taskはまとめてgroovyにまだしてる。アプリのbuild.gradleはktsが主流なのでそっちに合わせるってことで。

appフォルダの下にversion.propertiesファイルを用意

```version.properties
VERSION_NAME=1.0.0
VERSION_CODE=1
```

build.gradleに下記のtaskを用意

```build.gradle
task updateVersion {
    doFirst {
        def pattern = "^(\\d+).(\\d+).(\\d+)"
        def versionPropsFile = file('./app/version.properties')
        def Properties versionProps = new Properties()
        versionProps.load(new FileInputStream(versionPropsFile))

        def currentName = versionProps['VERSION_NAME']
        def versionNames = (currentName =~ pattern)[0]
        def major = versionNames[1].toInteger()
        def minor =  versionNames[2].toInteger()
        def patch = versionNames[3].toInteger()
        def updateName = major + "." + minor + "." + (patch + 1)   // Default
        if (project.hasProperty("type")) {
            def type = project.property("type")
            if (type == "minor") {
                updateName = major + "." + (minor + 1) + ".0"
            } else if (type == "major") {
                updateName = (major + 1) + ".0.0"
            }
        }
        def updateCode = versionProps['VERSION_CODE'].toInteger() + 1

        println("Complete VersionName : " + updateName.toString())
        println("Complete VersionCode : " + updateCode.toString())

        versionProps['VERSION_NAME'] = updateName.toString()
        versionProps['VERSION_CODE'] = updateCode.toString()
        versionProps.store(versionPropsFile.newWriter(), null)
    }
}
```

パッチバージョンをあげる場合（デフォルト）

```
./gradlew updateVersion
```

マイナーバージョンををあげる場合

```
./gradlew updateVersion -p type=minor
```

メジャーバージョンををあげる場合

```
./gradlew updateVersion -p type=major
```

あとはCIでこれらをbuildの前にタスク実行して、コミットしてbuildすればOK
Red Hatカスタマーポータルのアカウント作成方法

# はじめに
以前、お客様とお話させていただく中で、Red Hatカスタマーポータルをご存知ないというお客様がいらっしゃいましたので、今回はRed Hatカスタマーポータルについて記載させていただきたいと思います。
Red HatのサブスクリプションをRed Hatから直接ご購入いただいていない場合、カスタマーポータルをご利用されていないケースというのはあると思います。
カスタマーポータルをご利用いただきますと、サブスクリプションの管理やナレッジの検索など大変便利です。
本記事ではまずカスタマーポータルのアカウント作成方法をご紹介させていただきます。


# 目次
[1.カスタマーポータルとは](#1-カスタマーポータルとは)
[2.アカウントの作成](#2-アカウントの作成)
[3.サブユーザとは](#3-サブユーザとは)
[4.サブユーザの作成](#4-サブユーザの作成)

# 1. カスタマーポータルとは
カスタマーポータルには様々な機能があり、お客様は主に以下の機能をご利用いただくことが可能です。
・Red Hatサポートのケース発行および報告システム
・ナレッジベース、FAQ、および公式の製品ドキュメント
・ホワイトペーパー、情報シート、およびマルチメディアを含む豊富な教育コンテンツ
・ダウンロード、アップデート、および評価
・サブスクリプションおよびアカウント管理ツール


# 2. アカウントの作成
まずはじめに、[こちら](https://access.redhat.com/ "こちら")にアクセスします。

続いて、「Register」をクリックします。
![スクリーンショット 2022-06-02 17.59.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/ef686509-9af1-63e1-0e85-4a4da4836284.png)


フォームを埋め、「アカウントを作成します。」をクリックすると、アカウントが作成されます。
![FireShot Capture 027 - 登録 - Red Hat IDP - sso.redhat.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/219ecb3a-74a9-f0b2-3ebc-7d70f70be6ec.png)

アカウント作成直後は言語が英語になっています。
言語を変更する際は、作成したユーザでログインし、画面右上のユーザアイコン（紫色の部分）をクリックし、「Account details」をクリックします。
![スクリーンショット 2022-06-01 17.10.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/9466f19d-d7a5-6c29-7b80-d74c313d4f9a.png)
![スクリーンショット 2022-06-01 17.11.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/e98789b1-ee1a-4580-dc96-f5c5703cf825.png)

画面左側の「Language & location」をクリックし、設定を変更します。
![スクリーンショット 2022-06-01 17.17.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/d400aaf1-ea69-96c8-6723-e986cacb93cb.png)





以上でアカウントの作成完了です。

# 3. サブユーザとは
2で作成したユーザアカウント内に別のユーザIDを持つサブユーザを作成することができます。
2で作成したユーザはサブユーザに対してサブスクリプションの管理など権限を与えることで、サブユーザも一緒にサブスクリプションの管理などを行うことができます。
サブユーザの使い方の一つの例として、例えばプロジェクトの代表者のアカウントを作成し、サブユーザとしてプロジェクトメンバーのアカウントを作成することで、プロジェクト代表者アカウントで購入したサブスクリプションをプロジェクトメンバーが管理することが可能になります。


# 4. サブユーザの作成
画面右上のユーザアイコン（紫色の部分）をクリックし、「ユーザー管理」をクリックします。
![スクリーンショット 2022-06-01 17.10.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/0afa0c0e-bc3f-2682-0890-4ec12b16fe08.png)
![スクリーンショット 2022-06-01 17.19.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/a2685c15-ec81-6c5d-c221-741867d21efa.png)


「新しいユーザーの追加」をクリックします。
![スクリーンショット 2022-06-01 17.21.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/b6ef8525-74dd-db2e-fcc7-09979fd85580.png)

サブユーザの情報を入力し、「保存」クリックすると、サブユーザが作成されます。
※サブユーザを作成する際に入力したメールアドレスに、サブユーザ認証のメールが送信されます。
※サブユーザの権限は「カスタマーポータルのアクセス権限」の項目で付与できます。
![FireShot Capture 026 - 新規ユーザーの作成 - Red Hat Customer Portal - www.redhat.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/193a4ba7-5852-07c4-f8f4-d52b18c75856.png)

サブユーザが作成されます。
![スクリーンショット 2022-06-01 17.32.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/95fab27c-54c9-9d3c-b826-55af5c9796a8.png)


以上となります。
Storybook + Vue.js 環境に bootstrap-vue を導入すると Storybook が正しく動作しない

# 環境
* Storybook - v6.5.6
* Vue.js - v3.2.13
* bootstrap-vue - v2.17.3

# 事象
Storybook + Vue.js 環境に Bootstrap を導入し、セットアップ後、`npm run storybook`でStorybookを起動すると、Storybook が正しく動作しない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682590/5147464a-fda4-a4d4-af7c-1d97f07eda2f.png)

開発者ツールのコンソールに以下の様なエラーログが出力される。
```console:console
Uncaught TypeError: Cannot read properties of undefined (reading 'prototype')
    at Object../node_modules/bootstrap-vue/esm/utils/config.js (config.js:6:1)
    at __webpack_require__ (bootstrap:24:1)
    at fn (hot module replacement:62:1)
    at Object../node_modules/bootstrap-vue/esm/utils/props.js (plugins.js:196:1)
    at __webpack_require__ (bootstrap:24:1)
    at fn (hot module replacement:62:1)
    at Object../node_modules/bootstrap-vue/esm/utils/model.js (memoize.js:12:1)
    at __webpack_require__ (bootstrap:24:1)
    at fn (hot module replacement:62:1)
    at Object../node_modules/bootstrap-vue/esm/components/alert/alert.js (index.js:11:1)
```

# 結論
`bootstrap-vue`([公式ページ](https://bootstrap-vue.org/docs)) が Vue.js - v3x に対応していない。

抜粋（2022/06/02時点）
> * Vue.js v2.6 is required, v2.6.12 is recommended
> * Bootstrap v4.3.1 is required, v4.6.1 is recommended
> * Popper.js v1.16 is required for dropdowns (and components based on dropdown), tooltips, and popovers. v1.16.1 is recommended
> * PortalVue v2.1 is required by Toasts, v2.1.7 is recommended
> * jQuery is not required

積んだ。おのれ国際情勢。

https://github.com/bootstrap-vue/bootstrap-vue/issues/6872#issuecomment-1055569239

# 他の方法はないか
一応、`bootstrap-vue-3`っつー非公式（OSSに公式も非公式もあんのか？）はあるらしい。

https://github.com/cdmoro/bootstrap-vue-3

https://www.npmjs.com/package/bootstrap-vue-3

一応、立ち位置として`bootstrap-vue`と互換性を保ちつつ更新していくスタンスっぽい。他にも`Vue.js - v3x`+`bootstrap - v5.x`をサポートしたパッケージはちらほらありますが、このパケージが一番良さげ。国際情勢が奇跡的に落ち着いたらどうするか考えますかねー。祈るしかないです。

了
mintを利用した時に"swift package resolve"のエラーが出る場合の対応

`mint bootstrap`を実行した時に以下のようなエラーが発生しました。
```
:seedling: Encountered error during "swift package resolve". Use --verbose to see full output
```

# 発生原因
swiftのバージョンが古くコマンドを利用出来なかったようです。
しかし、PCにはXcode13.4(Swift5.6)を入れていた為、判明が遅れました。

ではなぜバージョンが足りなかったのか、原因は`swiftenv`を利用していた為でした。
作業リポジトリに`.swfit-version`が利用されており、
そこに`5.3`の指定があった為、swiftのバージョンが古くなっていました。

# 解決方法
## その1
* `.swift-version`のバージョンを更新する
## その2
* 明示的に`swiftenv`で利用するswiftのバージョンを更新する
  * `swiftenv global 5.6`


以上
NoMethodError in ~#index （エラーの確認・対処）


# はじめに
Rails 6.0.3を使用してローカル環境にてアプリケーションを作成中にエラーに遭遇しました。本当に初歩的なミスですが、今後よく遭遇するであろうエラーとのことでしたので備忘録として記事にします。

# 環境
Ruby: 3.0.1
Rails: 6.0.3

# 設定内容
```ruby
#controllerファイルの場所
frasse_app/app/controllers/frasses_controller.rb

#frasses_controller.rbのコード(抜粋）
  def index
    @frasses = Frasse.all
  end

  def new
    @frasse = Frasse.new
  end
```
```ruby
#viewsファイルの場所
frappe_app/app/views/frasses/index.html.erb
#index.html.erbのコード（抜粋）
  <% @frasse.each do |frasse| %>
    <tr>
      <td><%= frasse.content %></td>
    </tr>
  <% end %>
```

# 発生していた問題
一覧画面のindex.html.erbの表示を実装したいと思っていたのだが、localhostで接続すると下記のエラーとなってしまった。
`NoMethodError in Frasses#index`
undefined method \`each` for nil:NilClass
とのエラー内容でした。

エラー文より`@frasse`がnilになっているとのことがわかり変数の中身が何もない(nil)になっているようでした。
この部分` <% @frasse.each do |frasse| %>`

# わかったこと
投稿内容が代入されている変数は`@frasses` **複数形**の方だったたということがわかり、` <% @frasses.each do |frasse| %>`このように変更し、エラー解消となりました。
エラー文をよく読んで理解することの大切さを日々感じております。
rbenv インストール

# Homebrew

```
xcode-select --install
```


## インストール
https://brew.sh/index_ja

```
brew doctor
```

```
brew install wget
```

# rbenv

```
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi' >> ~/.bash_profile
source ~/.bash_profile
```

```
rbenv install --list 　　 # => インストール可能なバージョン一覧の表示
rbenv install 2.6.1 # => rubyのインストール
rbenv rehash             # => rbenv の再読み込み
rbenv global 2.6.1  # => defaultで使うrubyのバージョン
```

https://qiita.com/petertakahashi/items/1447c401c928d08a040b

# その他

```
brew install rbenv ruby-build
```

```
gem install bundler
gem install rails
```
ubuntu 22.04でssh接続できなくなった時

ubuntu 22.04からssh version 8.8に上がったためいくつか接続するために修正が必要だった。
自分は以下の方法で解決した。

## rsaを許可する

対象のサーバーのsshd_configにrsaを許可する

* /etc/ssh/sshd_config

```go:sshd_config
HostKeyAlgorithms=+ssh-rsa
PubkeyAcceptedAlgorithms=+ssh-rsa
```

* sshdを再起動する

```
systemctl restart ssh
```


## 古い鍵で動いているサーバーへの接続

OpenSSH version `8.8` から古い鍵で動いているサーバーへの接続が許可されなくなった様子。

https://anton0825.hatenablog.com/entry/2022/01/30/092307

強制的に許可をする場合は以下記述することでまた接続できるようになる。

```go:~/.ssh/config
Host *
    HostKeyAlgorithms ssh-dss,ssh-rsa
    PubkeyAcceptedKeyTypes ssh-dss,ssh-rsa
```

## 新しい鍵の場合

```go:~/.ssh/config
Host *
    HostKeyAlgorithms rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp256,ssh-ed25519
    PubkeyAcceptedKeyTypes rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp256,ssh-ed25519
```

## ssh 接続時のアドレスに IPv4 のみを使うようにする

https://fishrimper.blogspot.com/2014/07/ssh-ipv6.html

```go:~/.ssh/config
Host *
    AddressFamily inet
```
Git 基礎コマンド　まとめ

まとめ
（自分が入力したことがあることのみ）

分かっている概念だから別にコマンドの定義は作成しておりません。

git　init　:　git生成
git　clone　URL　:　コードが受入
git　checkout　branch_name:ブランチ選択
git　branch　branch_name　:ブランチ生成
git　branch　-a　:　ローカルブランチリストを見る
git　branch　-m　branch_namechange_branch_name　:　ブランチ名変更
git　branch　-d　branch_name　:　ブランチ削除
git　add　path　:　修正したコードを選択
git　add　. 　:　全部選択
git　commit　-m　"commit_description":選択したコード説明書(gitcommit-m"内容")
git　pull　:　gitサーバーで最新コードを受け取ってmergeする
git　fetch　:　gitサーバーから最新コードを受け取る
git　config-globaluser.name"user_name"　:　gitアカウント名変更
git　config-globaluser.email"　:　gitアカウントメールを変更する
git　stash　/gitstashsave"description"　:　作業コードを一時保存し、ブランチを変える

git　branch-set-upstream-to=remote_path/branch_name　:　gitpullnotrackinginfoエラー解決
$ git push --set-upstream origin master
AmazonLexを使ってWebチャットボットを作ってみた

Webサイトにチャットボットを設置したいと思い、試しにAmazonLexを使って構築してみました。

:::note
AWSアカウントはすでに持っている想定で記述しています。
:::

# 手順
1. CloudFormationを立ち上げる
1. 必要な設定をしてセットアップを実行
1. 試しに使ってみる
1. スニペットを自身のWebサイトに設置
1. AmazonLexの設定を変更する

# CloudFormationを立ち上げる
GitHubにCloudFormationを使って必要なサービスをインストールする方法が載っていましたのでこちらを利用しました。

https://github.com/aws-samples/aws-lex-web-ui

GitHubページにある以下の一覧からTokyoを選択するとCloudFormationが立ち上がります。

![スクリーンショット 2022-06-02 16.53.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1926542/9b55b5af-5422-2719-9e49-5389381e95ac.png)

# 必要な設定をしてセットアップを実行
一番重要なのは、WebAppParentOriginです。
ここにチャットボットを設置したいWebサーバのドメインを設定する必要があります。
それ以外はとりあえずデフォルト値でも問題ありません。必要に応じて設定してください。
英語表記なので英語を理解できる必要があります。

# 試しに使ってみる
約30分くらい待つと必要なサービスの設定が完了します。
サービス構成は以下のようになっています。

![lex_chatbot.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1926542/9d298ece-0278-51a8-e98c-614dfcd5b56e.png)


CloudFormationの「出力」タブにあるWebAppUrlをクリックすると、フルスクリーンでチャットボットが立ち上がるので試しに使ってみるといいでしょう。

:::note
デフォルトでは英語で花を購入することを想定したチャットボットになっています。「order」などと入力するとチャットボットが反応してくれます。
:::

# スニペットを自身のWebサイトに設置
CloudFormationの「出力」タブにあるSnippetUrlをクリックすると、スニペットの設置方法が表示されます（英語）。
ここに表示されるhtmlコードをコピーして自身のサイト上に貼り付けてください。

試しに空のhtmlファイルにスニペットを貼り付けてアクセスしてみると以下のように表示されました。

![スクリーンショット 2022-06-02 17.07.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1926542/4836dad7-c2f0-ccf4-a022-5a6969c2d0ad.png)


# AmazonLexの設定を変更する
あとはAmazonLexの設定を変えて自身の希望する反応をしてくれるように変更すればOKです。
AWSマネジメントコンソールでAmazonLexを開くと「WebUiOrderFlowers」というBotができているはずなのでこの設定を自分好みに変更してください。

![スクリーンショット 2022-06-02 17.12.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1926542/66219dce-6444-795e-b117-b10134f13863.png)

# その他
チャットボットのデザイン修正やAmazonLexへの設定の詳細、日本語に完全に対応する設定などについてはここには記載していませんが、まだまだ色々できそうです。

# 参考
https://xp-cloud.jp/blog/2018/01/30/2844/#title2
postgreSQLでVARCHARとCHARを試した

バージョン：psql (PostgreSQL) 11.1

(n)なしでCHAR
```
postgres=# create table tmp1 (name CHAR);
CREATE TABLE
postgres=# insert into tmp1 values ('aaa');
ERROR:  value too long for type character(1)
postgres=# insert into tmp1 values ('aa');
ERROR:  value too long for type character(1)
postgres=# insert into tmp1 values ('a');
INSERT 0 1
postgres=#
```
(n)なしでVARCHAR
```
postgres=# create table tmp2 (name VARCHAR);
CREATE TABLE
postgres=# insert into tmp2 values ('aaa');
INSERT 0 1
postgres=#
```
CHAR(1)にしてみる
```
postgres=# create table tmp3 (name CHAR(1));
CREATE TABLE
postgres=# insert into tmp3 values ('aaa');
ERROR:  value too long for type character(1)
postgres=# insert into tmp3 values ('aa');
ERROR:  value too long for type character(1)
postgres=# insert into tmp3 values ('a');
INSERT 0 1
postgres=#
```
VARCHAR(1)にしてみる
```
postgres=# create table tmp4 (name VARCHAR(1));
CREATE TABLE
postgres=# insert into tmp4 values ('aaa');
ERROR:  value too long for type character varying(1)
postgres=# insert into tmp4 values ('aa');
ERROR:  value too long for type character varying(1)
postgres=# insert into tmp4 values ('a');
INSERT 0 1
postgres=#
```
MacでSDカードにパーティションを切る

GUIからすんなり出来なかったので、メモ書き程度に。

## 目的
128GBのSDカードを、4:6でパーティションを分けたい。

## 事象
ディスクユーティリティを使用して、パーティションを切ろうとしたが、ボタンがグレーアウトされて押せない。

## 解決策
ターミナルを使用してコマンド実行。

### 実施詳細
1.ターミナルを開く
2.diskutil listで、SDカードのIDENTIFIERを確認
```
diskutil list
```
:::note info
私の環境では「/dev/disk2」というIDENTIFIER名でした
:::

3.diskutil partitionDiskで、パーティションを分割
```
diskutil partitionDisk /dev/disk2 2 JournaledHFS+ sdcard1 40% JournaledHFS+ sdcard2 60%
``` 
:::note info
「/dev/disk2」を4:6に分割
40％がsdcard1
60%がsdcard2
:::

4.もう一度diskutil listでSDカードの状態を確認
```
diskutil list

(中略)

/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *125.1 GB   disk2
   1:                        EFI EFI                     209.7 MB   disk2s1
   2:                  Apple_HFS sdcard1                 49.9 GB    disk2s2
   3:                  Apple_HFS sdcard2                 74.7 GB    disk2s3
```
CameraXでオートフォーカスが停止する

## CameraXで継続的なオートフォーカスが停止する問題

AndroidのCameraXを利用していて何かをきっかけに継続的に動作しているオートフォーカスが停止してしまうことがありました。特に背面カメラでプレビューしている時にカメラを下に伏せて置いた後、持ち上げるとプレビューがぼやけたまま停止するケースが頻度が高いように感じました。
もしかするとスマホ（GalaxyS9）に依存した問題なのかもしれませんが、問題が解消した方法を共有しておきます。


```kotlin:CameraFragment.kt
@SuppressLint("UnsafeOptInUsageError")　// ←追記
private fun bindCameraUseCases() {

    // 以上省略

    // A variable number of use-cases can be passed here -
    // camera provides access to CameraControl & CameraInfo
    camera = cameraProvider.bindToLifecycle(
            this, cameraSelector, preview, imageCapture, imageAnalyzer)

    // ここから追加
    val camera2CameraControl = Camera2CameraControl.from(camera!!.cameraControl)
    // dynamically changes the parameters.
    camera2CameraControl.captureRequestOptions =
        CaptureRequestOptions.Builder()
            .setCaptureRequestOption(
                CaptureRequest.CONTROL_AF_MODE,
                CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_VIDEO
            ).build()
    // ここまで追加
    // 以下省略
```


### 元にしたプロジェクト
以下のCameraXBasic

https://github.com/android/camera-samples
PowerAutomateDesktopの日付算出ルーチン

日付の取得に関して、検索してもすぐに見つからなかった為よく使うであろう物を書いておきます。

| # | 欲しい日にち | 処理内容 | 
| --- | --- | --- |
| 1 | 現在日付 | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701609/7ed63186-fa05-7492-4ba6-cefaabf58999.png)| 
| 2 | 当月初日 | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701609/c0c121eb-8a39-9748-d3be-f591dba55cc4.png)|
| 3 | 来月初日 | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701609/56eaaf04-dcdf-a9d1-0755-43441ccca71b.png)|
| 4 | 今月末日 | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701609/29a19c6e-4d2d-f00b-3e3d-7f95a6794e46.png)|
| 5 | 前月初日 |![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701609/883ced0b-d85d-852f-f29b-b0f5db8f8e9f.png)|
| 6 | 前月末日 |![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701609/a37b2eca-dff5-3337-9e8b-65bb29d5b71f.png)|
【基本情報技術者】ネットワーク方式

基本情報技術者試験の分野「ネットワーク方式」についてご紹介いたします。
## LAN
**LAN**(Local Area Network)は、**ある建物内や敷地内など比較的狭い範囲内で敷設したネットワーク。** 有線LANと無線LANに大別される。
### 有線LAN
ツイストペアケーブル(LANケーブル）や光ケーブルなどの有線を使いコンピュータ同士を接続する。有線LANは、※イーサネット(Ethernet) と呼ばれ、※IEEE802.3として規格されている。イーサネットで採用されている制御方式の1つに、**CSMA/CD方式**があります。この方式は、**伝送路上でのデータ衝突（コリジョン）が発生したらタイミングをずらして再送する方式。**

※イーサネット：コンピュータをネットワークに接続する時に使う「有線LANの通信規格」。イーサネット＝有線LANと表すこともある。
※IEEE802.3：IEEE(米国電気電子学会)により規定されたLANの代表的な規格の1つ。

### 無線LAN
無線LANは、無線で接続されたLANのことです。IEEE802.11(無線LANの規格)として規格化されている。**Wi-Fi**は、IEEE802.11に準拠した無線通信技術のひとつ。相互接続性が保証されることを示す**ブランド名。**
**ESSID**は、**無線のネットワークを識別する文字列のことをいう。**

## WAN
**WAN**(Wide Area Network)は、**遠隔地にあるLAN同士などを接続する広域ネットワーク。** 

### まとめ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655909/aca261a2-32fd-e85f-eb7e-d7e642567c72.png)
**・LANは建物内の限定的なネットワーク。**
**・WANは世界中で繋がるネットワーク。**

## モバイル通信サービス
**通信事業者の電波を使って、スマートフォンやタブレット端末などでインターネットに接続するサービスのこと。** 通信事業者と契約してSIMカードを端末に挿入して通信します。
スマートフォン・タブレット（親機）にパソコンやゲーム機器などさまざまな外部機器（子機）を接続することで、通信サービスエリア内であればLAN回線のない外出先でも、それらの外部機器でインターネットをご利用できる機能を**テザリング**という。
また、**自前の回線網を持つ通信事業者の移動体通信を借用して、自社ブランドで通信サービスを提供するMVNO**(仮想移動体通信事業者)も登場している。
### キャリアアグリゲーション
**複数の異なる周波数帯の電波を束ねて、より広い帯域を使うことで無線通信の安定化を図る技術。**
### 5G
これまでの通信速度は、数Mbps(通信速度の単位)の3Gから高速で数十Mbpsの4G(LTE)に方式が切り替わってきました。さらに現在超高速な通信速度として、**5G**(第世代移動通信システム)が登場しています。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655909/c0901a95-46a5-cb01-74b0-44794b5f317a.png)
音声・動画配信、メディアタイプとは

# エンコードとデコード
インターネットでの転送時短縮のため、音声・動画ファイルも画像ファイルと同様にデータを圧縮したうえで利用されます。
データ圧縮には```コーデック(ソフトウェア)```を用いる。
圧縮することを```エンコード```という。
圧縮されたものを再生するために```デコード```と言います。

# ダウンロード配信
音声・動画の配信方法は２つある。
### ダウンロード配信
Webサーバーからファイルをダウンロードしてもらいそれを再生する

### プログレッシブダウンロード配信
ダウンロードしながら再生する

どちらの方法も配信したファイルはユーザー側に残ってしまうため、著作権のあるものには適さない。

# ストリーミング配信
上２つの方法の問題点を解決したのがこの方法だ。
ファイルを細切れにし、細切れのデータをユーザーに配信して再生する。
再生されたデータはその都度削除される。

# メディアタイプ
Webページは今の時代パソコン以外でも閲覧することができる。
テレビ、プリンター、スマホなどなど。

それらに合わせて閲覧に使う機器の種類をHTML、CSS内で指定できる。
それを```メディアタイプ```という。
タッチとスクロールを判別する

```
$('.link').on('touchend click', function(){
  //処理...
});
```

スクロール領域の内部全体にtouchendおよびclickイベントを設定した要素を置くと、タッチデバイスでのスクロール動作が、内部に対するtouchendイベントとして認識されてしまう。

##### 【候補1】windowオブジェクトによるタッチイベント対応判別
**有効ではない。** 近年タッチイベント対応かつマウス操作もできるデバイスが登場したので、イベント自体発火しなくなるおそれがある。

##### 【候補2】scrollイベントによるフラグ管理
**有効ではない。** scrollイベントが発火する前にtouchstartイベントが発火するためか誤動作の抑止にはつながらなかった。

##### 【候補3】そもそもtouchイベントを使わず、metaタグ（name="viewport"）にuser-scalable=noを設定して遅延を解消する
**有効…だけど微妙。** user-scalable=noは画面の拡大・縮小を禁止する設定。ダブルタップか否かを確認する待ち時間がなくなり、タッチデバイスでのクリックイベントが高速化する。
ただ「拡大・縮小できる」というユーザビリティを損なうことにはなる。

##### 【候補4】touchstartとイベントとtouchendイベントで要素位置を比較する方法
**有効。** 両者の位置が同一の場合、スクロール動作ではないことが判別できる。
ただこの次の解決法のがよりシンプルなのでそちらを採用。

```
let touchStartPos = '';
let touchEndPos = '';
$('.box').on('touchstart', function(){
  touchStartPos = $('.box').scrollTop();
  return false;
});

$('.link').on('touchend click', function(){
  touchEndPos = $modalScrollCnt.scrollTop();

  if(!touchStartPos || (touchStartPos && touchStartPos === touchEndPos)){
　//処理...
  }
  return false;
});
```

#### 【候補5・採用】touchstartからtouchmoveイベントがあるかを確認して発火を判別する方法
**有効。** scrollFlg（スクロールもといタッチポイントの移動を判別するためのフラグ）のほか、touchendとclickの記述をまとめて書くためのisTouchFlg（touchstartが実際に発火しているかどうかを判別するフラグ）が必要になる。
https://sterfield.co.jp/programmer/%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%B3%E3%81%A7%E3%81%AE%E3%82%BF%E3%83%83%E3%83%81%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%A8%E7%A7%BB%E5%8B%95%E3%82%92%E5%8C%BA%E5%88%A5/

```
let scrollFlg = false;
let isTouchFlg = false;
$('.box').on({
  'touchstart': function() {
    scrollFlg = true;
    isTouchFlg = true;
  },
  'touchmove': function() {
    scrollFlg = false;
  }
});

$('.link').on('touchend click', function(){
  if(!isTouchFlg || (isTouchFlg && scrollFlg)){
  //処理
  }
});
```
Databricksランタイムにインストールされているソフトウェアのバージョンの確認方法

[Databricksランタイム](https://docs.databricks.com/runtime/index.html)は[Databricksクラスター](https://qiita.com/taka_yayoi/items/c5d99cd77fe4bfcf69f0)上で動作するソフトウェアパッケージです。Python、R、Scalaなどの言語インタプリタ、それらの言語で利用する主要なライブラリがプレインストールされています。

こちらでは、ランタイムごとにインストールされているソフトウェアの一覧、バージョンを確認する手順を説明します。

1. 確認したいDatabricksランタイムのバージョンを確認します。ここではバージョン`10.5`を確認します。
1. 以下のページにアクセスします。

    [Databricks runtime releases | Databricks on AWS](https://docs.databricks.com/release-notes/runtime/releases.html)

1. 使用するランタイムバージョンを選択します。**Databricks Runtime 10.5**をクリックします。
![Screen Shot 2022-06-02 at 16.38.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1db22aa0-ec59-296d-1166-b8e7fd02edd2.png)

    [Databricks Runtime 10.5 | Databricks on AWS](https://docs.databricks.com/release-notes/runtime/10.5.html)

1. System environmentに移動します。

    [System environment](https://docs.databricks.com/release-notes/runtime/10.5.html#system-environment)

1. 言語のバージョン、ライブラリの一覧を確認することができます。
![Screen Shot 2022-06-02 at 16.40.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d0c5a6d9-ac6a-feae-fc15-bb7615028bfe.png)

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
SQLのトランザクションでデータを守る！

# なにこれ？
大事なデータを誤って削除してしまった！書き換えてしまった！なんていうことがあったら大変ですよね。
ですが人の手で操作する部分がある以上、そのリスクは0とは言い切れません。

この記事では、**データを書き換えてしまわないようにするための方法を書き記しています。**



# データ書き換えのデモができるようになる！
SQLのトランザクションを利用することで（トランザクション本来の利用目的とは少しずれますが）、**データを書き換える際のデモをチェック**することができるようになります！
そのため、期待通りのデータ操作ができた時にだけ、DBに処理を反映することができるようになります！


# データの書き換えがすぐに反映されるのはちょっと心配
大事なデータを扱っている場合、それらの大事なデータは誤って削除、追加、更新してしまうことがあってはいけません。
そのため、データを更新するときはとても慎重になってしまいます。


# トランザクションを利用してデータ更新のデモを動かす
トランザクションを利用して更新内容のデモをチェックします。

デモの結果から、DBに反映させるかどうか決めます。

DBに反映させる→**コミット**
更新せず、元のデータに戻す→**ロールバック**



# トランザクションとは？
トランザクションとは、**複数のSQLの更新処理を1つにまとめてDBに反映させる**ことです。

トランザクションを利用するのは、複数の更新処理を連続して行う時が多いです。
何らかの原因によって途中の処理がうまく反映されないときにはすべての更新処理を中断します。
逆に、連続した処理がすべてうまくいった時には処理を反映させます。


# コミット
トランザクション中の更新などのデータ処理の結果は、仮のものとして扱われ確定していません。
コミットが実行されると、**この仮だったものが確定しデータベースに結果が反映されトランザクションが終了します。**
当然、**一度コミットすると、もう処理を取り消してデータをもとに戻すことができないので十分な注意が必要です。**
また、コミットされる前の仮の状態のデータは、外部（別のトランザクション）からは見ることができません。


# ロールバック
ロールバックは実行されると**トランザクション中の処理が取り消され、トランザクション実行前の状態に戻りトランザクションが終了します。**
また、明示的に実行する以外にも、データベースとの接続が切断される等、何らかの原因でトランザクション中の処理が中断された場合にもロールバックが実行されます。


# 使い方
今回は、SQL Serverでの書き方を紹介します。ただ、他のSQLでも書き方に大差はありません。

まず、'BEGIN TRAN TRAN名'でトランザクションを開始します。
次に、処理をする文を書いていきます。
処理を反映させるときは'COMMIT TRAN名'でトランザクションの処理を反映させます。

```sql:COMMIT
BEGIN TRAN TRAN名
〜
SQL文
〜
COMMIT TRAN名
```

処理を取り消すときは'ROLLBACK'でトランザクションの処理を取り消します。

```sql:ROLLBACK
BEGIN TRAN TRAN名
〜
SQL文
〜
ROLLBACK
```



# データの取り扱いには要注意
トランザクションをマスターしてデータ取り扱いの不安を減らしましょう！
投稿機能をつける

ユーザーの方が行き詰まったので投稿機能を作成することにした。
そのためにMySQLでテーブルを作成する。
その後にモデルのファイルを作成、そこでバリデーションをかける。
その後実装する機能としては
・投稿機能
・投稿詳細ページ
・投稿一覧機能
・投稿編集
・投稿削除

# postsテーブルを作成
投稿の文章のデータ型を何にしようか？
調べてみると
```CHAR```,```VARCHAR```,```TEXT```とある。
どれを使えばいいのだろう？
### CHAR(固定長文字列)
何があっても宣言された文字分の領域を使う。
列に入れる文字列の長さが細田長に満たないばああい、文字列が最大長になるまで空きを半角スペースで埋めます。

出典 SQLゼロから始めるデータベース操作第二版　p３５

### VARCHAR(可変長文字型)
カラムに宣言されたサイズを上限として値の文字数ぶんだけの領域を使用する。
最大長に満たさなくても、半角スペースで埋めなくてもいい。
出典 SQLゼロから始めるデータベース操作第二版　p３５

大体長くなければvarchar(255)で足りる。
### TEXT型
65,535バイトを超える長い文字列を扱う。
出典 MySQL徹底入門第４版 p97 

## そもそもデータの長さとは?
バイトとは基本的な単位である。
1文字＝１バイト
このバイトを１０２４倍した単位がキロバイト
つまり
ギガバイトの場合は
1024x1024x1024の値だ。
その値分の文字を記憶できる。

出典 SQLゼロから始めるデータベース操作第二版　p188

# モデルのファイルを作成
```
class Post < ApplicationRecord
  validates :content, {presence: true, length: { maximum: 140 }}
end
```
# 投稿機能ページを作成
## ルーティングを設定
```routes.rb
get '/posts/:id',         to: 'posts#new'
```

## コントローラーを作成
```posts_controller.rb
def new
end
```

## ビューを作成
```new.html.erb```を作成。表示成功

# 投稿機能を作成
## ルーティングを設定
```routes.rb
post '/posts/create',    to: 'posts#create'
```
## コントローラーを作成
```posts_controller.rb
.
.
.
def create
    @post = Post.new(content: params[:content])
    if @post.save
      flash[:notice] = "投稿に成功しました。"
      redirect_to "/posts"
    else
      @error_message = "投稿に失敗しました。"
      render "posts/new"
    end
  end
.
.
.
```
## Routing Error
No route matches [GET] "/posts/create"
少し悩んだ。
```
redirect_to "/posts/create"
```
にしていたからだ。
GETで設定していないのに書いたからこうなった。
直したのが上のコード
## ビューを作成
```
    <%= form_tag('/posts/create', method: :post) do %>
      <p>投稿内容</p>
      <textarea name="content"></textarea>
      <input type="submit" value=保存>
    <% end %>
```
VSCでRaspberryPiにSSH接続ができない人向け

VSCでRaspberry Pi(3or4)にSSH接続する方法の記事はたくさんありますが、その通りにやってもなぜか、SSHのパスワードを打ち込む画面が出なかったり、エラーログを見ると、sshのコマンドを認識しなかったりする人がいると思います。(コマンドプロンプトではsshのコマンドを認識するのになぜかVSCでは認識しない。当然パスは通しているのに)

この状況でVSCでRaspberryPiにSSH接続できるようになる方法を備忘録で残します。

2022/06/20
JetsonのJetpackのバージョンを変更したらSSH接続できなくなったので、その対処を追記した。

# 目的
Windows10パソコンからVSCでRaspberry Pi(3or4)にSSH接続する。
(Raspberry Piに限らず、SSH接続できます。例えばJetson等)

# 手順1
Visual Studio Codeをアンインストールします。
色々拡張機能をインストールしていたと思いますが、SSH接続できない苦しみよりはましなのでアンインストールしましょう。手順は以下です。
```
1.プログラムの追加と削除からVisual Studio Codeをアンインストールする。
2."C¥Users¥ユーザー名¥.vscode"フォルダを削除する。
3."C¥Users¥ユーザー名¥AppData¥Roaming¥Code"フォルダを削除する。
4.パソコン再起動
```
# 手順2
Visual Studio Codeをインストールする。

# 手順3
以下を参考にSSH接続するための設定を行う。
https://qiita.com/c60evaporator/items/26ab9cfb9cd36facc8fd


# 追記
JetsonのJetpackのバージョンを変更したらVSCでのSSH接続できなくなったので、その対処を追記した。

# 手順1
C:¥Users¥ユーザ名¥.ssh¥config を開く。

# 手順2
known_hostsファイルをエディタで開き、JetsonのIPが表示されている行を削除する。

# 手順3
VSCでJetsonにSSH接続をする。
これで再度、接続することが可能になります。

# 終わりに
どうでしょうか。何ら問題なくSSH接続できませんでしたか？
CloudFrontでKMS.UnrecognizedClientExceptionが発生した場合の対応



## 事象
CodeBuildからS3にアーティファクトとしてフロントの成果物をアップロードした際、
以下のようなエラーが出てアクセスできなくなる
```
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>KMS.UnrecognizedClientException</Code>
<Message>No account found for the given parameters</Message>
<RequestId>RX106D4WGH79D10K</RequestId>
<HostId>ppGQtkJXf9xszYUYsUzzPlxaR/rFjoXsV5tSiTUODQbyybYjdc6VBSo0VfYWe63fYsPs92oPLYI=</HostId>
</Error>
```

## 原因

CloudFrontはKMSキーにより暗号化されたファイルに対応していないらしいが、
CodeBuildでアーティファクトを作成する場合はデフォルトで暗号化されてしまうらしい。

## 解決方法

CodeBuildの設定に

☑ アーティファクト暗号化の削除
アーティファクトを使用して静的なウェブサイトを公開したり、他のユーザーとコンテンツを共有したりする場合は、暗号化を削除します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128115/13fb8334-57b5-d602-4ad1-8772559dec8d.png)

という項目があるので、このチェックを外す。
M5Paper: 図形を描画

こちらのページを参考にしました。
[EPD Driver](https://docs.m5stack.com/en/api/m5paper/epd_canvas)

![IMG_20220602_160814.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/e786dcb1-cfb8-430f-939e-72bac2d276d3.jpeg)


```text:draw_geometries.ino
// ---------------------------------------------------------------
//	draw_geometries.ino
//
//						Jun/02/2022
// ---------------------------------------------------------------
#include <M5EPD.h>

M5EPD_Canvas canvas(&M5.EPD);

// ---------------------------------------------------------------
void setup(){
    M5.begin();
    M5.EPD.Clear(true);

    M5.RTC.begin();
    canvas.createCanvas(960, 540);
    canvas.setTextSize(5);
    int xx = 100;
    int yy = 30;
    canvas.drawString("Draw Geometries", xx, yy);
    
    canvas.drawString("Jun/2/2022 PM 16:00", xx+100, yy+400);

  int yy1 = 150;
  int rr = 60;
  for (int it=0; it<6; it++)
	{
	int xx1 = 100 + it * 150;
	canvas.fillCircle(xx1, yy1, rr, WHITE);
	int rr_s = it * 10;
	canvas.fillCircle(xx1, yy1, rr_s, BLACK);
	}

int yy2 = 250;
int ll = rr * 2;
for (int it=0; it<6; it++)
	{
	int xx2 = 50 + it * 150;
	canvas.fillRect (xx2,yy2,ll,ll,WHITE);
	int xcenter = xx2 + rr;
	int ycenter = yy2 + rr;
	int ll2 = it * 20;
	int xpos = xcenter - ll2 / 2;
	int ypos = ycenter - ll2 / 2;
	canvas.fillRect (xpos,ypos,ll2,ll2,BLACK);
	}

    canvas.pushCanvas(0,0,UPDATE_MODE_DU4);
}

// ---------------------------------------------------------------
void loop(){
}

// ---------------------------------------------------------------
```

Arduino IDE
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/e2e635d9-aba7-d19c-345c-8e0f79f8a72b.png)
solidity忘備録　crypt zombie

# lesson 1からlesson2
getterメソッドとは
ある特定のフィールドを呼び出すメソッドのこと
publicを使って誰でもPerson structとperson配列を呼び出すことができる

```solidity
//pepopleという名前の配列をPerson構造体を使って作成。注意！配列を作っている。
Person[] people;

//publicで呼び出しができるようになった。
Person[] public people;

// 新しいPersonを作る：
Person satoshi = Person(172, "Satoshi");

// それを配列に格納する：データは配列に入るのである。
//people配列にsatoshiを追加。
people.push(satoshi);

//まとめて書くとすっきり。
people.push(Person(16, "Vitalik"));

```
# パラメーターと変数の違い
パラメーターは引数を受けるために定義した変数のこと
変数は変えることができる定義された値

```solidity
//_nameと_dnaがパラメーター　のちほど具体的な値を当てはめるときの値のことを引数という。
function _createZombie(string _name, uint _dna) private {
        zombies.push(Zombie(_name, _dna));
```
# フロントエンドとバックエンドの違い
フロントエンド
HTMLなどユーザーに直接触れる言語のこと
バックエンドとは
サーバーサイドの言語のこと
python,phpなど

# mappingとは
構造体、配列と同じくデータを格納したもの
配列は構造体を元に作られ、mappingはバリューをキーに格納している。
１つ目ではuintがバリューでaddressがキー


```solidity
// 金融系のアプリの場合、ユーザーのアカウントの残高にuintを格納する：
//accountBlanceというmappingを作っている
mapping (address => uint) public accountBalance;
// もしくは、ユーザーIdを基にユーザー名を参照・格納するために使用するぞ：
mapping (uint => string) userIdToName;
```
# mappingの更新方法
上のmappingはデータが何も入っていないので実際にデータを格納する方法を書く
関数を作って、faboriteNumber mappingに_myNumberパラメーターを格納する。
##### msg.sender
グローバル変数
その関数を呼び出したユーザーのaddressを参照する
```solidity
mapping (address => uint) favoriteNumber;
function setMyNumber(uint _myNumber) public {
  // ここでは`favoriteNumber` mappingを更新して、`msg.sender`下に`_myNumber`を格納するぞ。
  favoriteNumber[msg.sender] = _myNumber;
  // mappingにデータを格納するのは、こう書くのだ
}

function whatIsMyNumber() public view returns (uint) {
  // 送信者のアドレスに格納されている値を受け取る
  // もし送信者が`setMyNumber`を呼び出さなかった場合は`0`だ
  return favoriteNumber[msg.sender];
}
```
#### lesson2 チャプター3
```solidity
Zombie[] public zombies;
    mapping (uint => address) public zombieToOwner;
    mapping (address => uint) ownerZombieCount;
    function _createZombie(string _name, uint _dna) private {
        uint id = zombies.push(Zombie(_name, _dna)) - 1;
        //ゾンビのオーナーidを関数の呼び出したユーザーに変更
        zombieToOwner[id] = msg.sender;
        //関数を呼び出したユーザーのゾンビ保有数が増えたので、オーナーの保有数も増やす
        ownerZombieCount[msg.sender]++;
        NewZombie(id, _name, _dna);
    }
```
## privateとinternalの違い
privateで定義された関数は継承されたコントラクトではエラーがでる。internalで定義しておけば、継承されたコントラクトでも使用できる。

## Lesson 2 チャプター10
dappとは
Decentrailized application　分散型アプリケーションの略

#### ineterface
外部コンストラクトのデータを読み込む方法。
新しいコントラクタを作っているのではなく、インターフェイスを定義している。
getNum関数は関数定義をしているのではなく、外部のgetNum関数を参照している。
関数定義との違いはreturnステートメント後に{}で関数定義せず、；で終わっている。

```solidity
contract NumberInterface {
  function getNum(address _myAddress) public view returns (uint);
}
```
Lesson2 チャプター11
```solidity
address ckAddress = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d;
  KittyInterface kittyContract = KittyInterface(ckAddress);
//kittyContractという名前のKittyInterfaceを作っている。インターフェイスを違う名前で作っている。
//kittyContractにラッキーナンバーで検索したアドレスを代入している。
```
AWS クラウドプラクティショナーに合格したので、使った教材と勉強時間を紹介します。

# 私のAWSスキルについて
AWS触った経験は0です。
IT系資格としては、応用情報、情報セキュリティスペシャリスト（登録セキスぺ（SC) )を保有しています。
実務経験は10年になります。

# 使用した教材と値段
[AWS Cloud Practitioner Essentials (Japanese) (日本語実写版)](https://explore.skillbuilder.aws/learn/course/1875/aws-cloud-practitioner-essentials-japanese-ri-ben-yu-shi-xie-ban)　無料

[【2022年版】この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（7回分455問）](https://www.udemy.com/share/101I2O3@GRwFyZsLhRnrBb0FlnJRdG-4wWZy2oxZc-R2VddrqNPPas4RrQNxTq9UirUuhbj4LQ==/)
1,480（Udemyのセール時に購入）

[AWS Certification Official Practice Question Sets (Japanese)](https://explore.skillbuilder.aws/learn/course/9159/aws-certification-official-practice-question-sets-japanese) 無料(AWS公式が提供している模擬試験問題)

# 勉強方法

####  1. AWS Cloud Practitioner Essentials (Japanese) (日本語実写版)をひたすら見る。(8時間)
全部の動画を一回見てAWSのサービス名と大体の機能を掴む。
動画の説明もわかりやすく、とても重要な教材でした。

#### 2. Udemyで購入した模擬試験問題集を繰り返し実施。(15時間)
基礎1,2,応用1,2,3と問題のレベルが分かれているのですが、基礎1~応用3までの問題を
理解していれば、ほぼ受かるんじゃないかなと思います。

試験問題との類似性という観点では、問題集と実際の試験問題は問題文の表現方法等、あまり類似していません。
試験範囲をカバーしているか、という観点では試験範囲以上の物を扱っています。

「最短ルート」で「クラウドプラクティショナー」を取得する。という面で考えると、他に良い教材もあるかと思いますが、試験取得の目的がAWSのスキルを身に着けることだったので、不足していなければまあいいかなと思ってます。模擬試験という目で見なければ、問題を通じて色々なサービスを知ることができたので、値段に対して得るものという意味では満足しています。

#### 3.AWS公式の模擬試験を実施(2時間)
AWS公式の模擬試験を実施して、間違えた問題は復習しました。
問題文の表現方法が実試験と同じなので、模擬試験は実施することをお勧めします。
これを受けていなかったら、Udemyの模擬試験とのギャップがあって、本番で焦っていたと思います。

# 資格を取得して
AWS案件にアサインされることになり、とっかかりとして急遽一番簡単な資格を取得したのですが。
資格を取得することで、サービス名と出来ることがなんとなく把握できたので、実務でも困ることなく
仕事が進められています。
最初に悩むのが、こんなことやりたいんだけど、何使えばいいんだろう。って部分だと思うので、
AWSの主要なサービスを大体把握するという意味では、非常に有用な資格だと思います。
Docker EC2デプロイ方法

EC2を作成した状態でDockerをインストールしていく
___
```
$ sudo yum update -y (EC2内のパッケージを最新にしておく)
$ sudo amazon-linux-extras install -y docker(Docker Engineパッケージのインストール)
$ amazon-linux-extras | grep docker (Dockerサービスを起動する)
$ systemctl status docker (Dockerサービスが起動していることを確認します)
$ sudo systemctl enable docker (Dockerサービスの自動起動を有効にします。)
$ systemctl is-enabled docker　(Dockerサービスの自動起動が有効であることを確認します。)
$ grep docker /etc/group (Dockerをインストールすると、dockerグループが自動作成されます。)
$ sudo usermod -a -G docker ec2-user　(ec2-userはsudoなしでdockerコマンドを実行できるようになります)
```
いったんEC2からログアウトし、再度EC2にec2-userでSSH接続します。
これでdockerグループのアクセス権限がec2-userに付与されます。
ec2-userでdoker infoがsudoなしで実行できることを確認します。
を実行できるようになります)
```
$ docker info
Client:
 Context:    default
 Debug Mode: false

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
略
```
Docker Composeのインストール
____
$ VER=1.29.2 (変数VERにDocker Composeのバージョンを代入します。バージョンの数字は適宜変えてください)
$ sudo curl -L https://github.com/docker/compose/releases/download/${VER}/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose(GitHubにあるDocker Composeのバイナリファイルを、/usr/local/bin/にダウンロードします。)
$ sudo chmod +x /usr/local/bin/docker-compose (ダウンロードしたdocker-compose（バイナリファイル）に実行権限を付与します。)
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose (/usr/bin/に/usr/local/bin/docker-composeへのシンボリックリンクを設定します。)
docker-compose --version (docker-composeコマンドが使用できることを確認します。)







___

※参考資料
https://kacfg.com/aws-ec2-docker/
SQLで条件付きソートを実施する(Postgres編)

## SQLで条件付きソートを実施する。
下記のようなDDLがあった場合、第１ソートキーが科目=数学,第２ソートキーが成績でソートしたい。ただ、国語や他の科目も表示したいため、Whereで絞りたくはない。

```sql: DDL
CREATE TABLE IF NOT EXISTS users(
   id serial PRIMARY KEY,
   username VARCHAR (256) UNIQUE NOT NULL
);

CREATE TABLE IF NOT EXISTS subject(
   id serial PRIMARY KEY,
   user_id int,
   name VARCHAR (256) NOT NULL,
   score int,
   date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

ALTER TABLE "subject" ADD FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE NO ACTION;
```

```sql: SQL
SELECT * from users as u INNER join subject as s on u.id = s.user_id order by name='数学' desc, score desc;

id	username	id	user_id	name	score	date
2	kkfactory	6	2	数学	89	2022-06-02 06:17:57.970721
1	koji	4	1	数学	67	2022-06-02 06:17:57.970721
1	koji	1	1	国語	86	2022-06-02 06:17:57.970721
2	kkfactory	2	2	国語	78	2022-06-02 06:17:57.970721
3	takashi	3	3	国語	56	2022-06-02 06:17:57.970721
1	koji	5	1	国語	44	2022-06-02 06:17:57.970721
```

実施するまでは悩んでるけど、やってみると意外とさっくり行ける！！SQL便利！！！
PHPのソケット通信(Client)でESP32と疎通してみる


# はじめに




各バージョンはこちら
```sh
$ apache2 -v
Server version: Apache/2.4.29 (Ubuntu)
Server built:   2022-03-16T16:53:42

$ php -v
PHP 7.2.34-28+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Nov 19 2021 06:36:36) ( NTS )
Copyright (c) 1997-2018 The PHP Group

$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.6 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.6 LTS"
VERSION_ID="18.04"
```

## ESP32の実装(Socket Server)
以前書いた[こちら](https://qiita.com/sirius1000/items/002df5f062a90ed605f0)を参考に実装します

```py
import socket #モジュールのインポート

port = 8080 #ポート指定
listenSocket = None #初期化


ip = wifi.ifconfig()[0] #自分のipアドレスを取得
listenSocket = socket.socket() #socketを作成
listenSocket.bind((ip, port)) # ソケットを特定のIPアドレスとポートに紐付け
listenSocket.listen(5) # 接続の待受を開始
listenSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,  1) #指定されたソケットオプションの値を設定

while True:
    print("accepting.....") 
    conn, addr = listenSocket.accept() #接続を受信
    print(addr, "connected") #接続した相手のipアドレスを表示　(xxx.xxx.xxx.xxx connected) 
    data = conn.recv(1024) #一度に受け取るデータのサイズを指定
    conn.close() #接続を切断
    print(data)
```

## サーバ側の実装(Socket Client)

```php
<?php
    $sendFlag = "false";
    $port = 8080;
    $result = "";
    if ($_POST['action'] == 'text'){
        $host = "<ESP32のipアドレス>";
        $msg = $_POST["msg"];
        $address = gethostbyname($host);
        echo "Sent " . strlen($msg) . " bytes : " . htmlspecialchars($msg) . "<br>";
        socket_close($sock);
    }
?>


<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
    </head>
<body>
    <form action="socket_send.php" method="post">
        <input type="textarea" name="msg" value="">
        <button type="submit" name="action" value="text">送信</button>
    </form>
</body>
</html>
```

## 動作確認

サーバ側にこのようなフォームが表示される
送信を押下するとESP32に入力した文字列が送信される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/2859448b-0335-49fd-1017-548804e90858.png)

ESP32側のコンソールを確認してみるとしっかりとデータが送信されていることがわかる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/2e5e2538-2886-037d-a0b8-0f27cda81cd4.png)


ためしに日本語も送信してみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/ee2bba8a-9004-770c-d1a1-eac15cd74b70.png)


ちゃんと送信されていたすごい！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/bdb0874d-658d-62bb-725b-3b3ce9b73b5a.png)
個人メモ：Miniconda パッケージ

必要なPython環境を作るにあたり、Apple M1 chip での試行錯誤を備忘録としてまとめておく。

今回はメインのモジュールの依存関係のために最新の　Anaconda が使えなかったため、　環境を　miniconda から作ることにした。

参考
https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#cloning-an-environment


```shell 
$ conda create -n myenv python=3.8

===
base
===
Miniconda Python 3.8

===
agama_202206
===
(base) $ conda create --name agama_202206 python=3.8
(base) $ conda activate agama_202206
(agama_202206) $ conda install -c conda-forge numpy
agama install

===
gaia_dr3-env
===
conda create --name gaia_dr3-env --clone agama_202206


===
gaia_dr3_try1-env
===
$ conda create --name gaia_dr3_try1-env --clone agama_202206
$ conda activate gaia_dr3_try1-env
$ conda install -c conda-forge ***

*** のリスト（上から順番に入れた）
scipy
matplotlib
jupyter
astropy
astroquery
corner
mpi4py
schwimmbad
pandas # already installed
wget
cython
scikit-learn
seaborn
pytest

===
gaia_dr3_try2-env
===

$ conda create --name gaia_dr3_try2-env --clone gaia_dr3_try1-env
$ conda activate gaia_dr3_try2-env

(gaia_dr3_try2-env)$ pip install cubature # これはうまく入らなかったので、pip で入れた。
```

# mwdust 

```shell
===
gaia_dr3_try3-env
===

$ conda create --name gaia_dr3_try3-env --clone gaia_dr3_try2-env
$ conda activate gaia_dr3_try3-env

(1) healpy
(gaia_dr3_try3-env)$ conda install -c conda-forge healpy

(2) mwdust
.bash_profile で
export DUST_DIR=$HOME/my_libs_3/mwdust_DATA_directory
としてから

$ sudo -E python setup.py build
$ sudo -E python setup.py install

### sudo env PATH="$PATH" python setup.py build
### sudo -E env PATH="$PATH" python setup.py install


(3) gaiadr3_zeropoint
gaiadr3_zeropoint  ダウンロードしてmy_libs_3 に展開し、
$ cd gaiadr3_zeropoint
$ python setup.py install

# sudo -E env PATH="$PATH" python setup.py install

(4) Agama

$ sudo -E env PATH="$PATH"  python setup.py install

...
>>> import agama
>>> agama.setUnits(mass=1,velocity=1,length=1)

```


```shell
===
gaia_dr3_try4-env
===

$ conda create --name gaia_dr3_try4-env --clone gaia_dr3_try3-env

(1) gdr3apcal

(2) fastkde

$ pip install fastkde
(GitHub はversionに関して文句を言われるので諦めてpipにする。)

>>> from fastkde import fastKDE
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/[user_name]/miniconda3/envs/gaia_dr3_try4-env/lib/python3.8/site-packages/fastkde-1.0.19-py3.8-macosx-11.1-arm64.egg/fastkde/__init__.py", line 1, in <module>
    from .version import version as __version__


```

```shell
===
gaia_dr3_try5-ispec-env
===

$ conda create --name gaia_dr3_try5-ispec-env --clone gaia_dr3_try5-env

(1)
(2) ispec


```

```shell
===
gaia_dr3_try5-quantile_forest-env
===

conda create --name gaia_dr3_try5-quantile_forest-env --clone gaia_dr3_try5-env

pip install quantile-forest
conda update astropy

```

(astropy が古いと、numpy<1.23 でのみ使えるnumpy.asscalar がエラーを吐く。)


```shell
===
gaia_dr3_try5-naif-env
===
conda create --name gaia_dr3_try5-naif-env --clone gaia_dr3_try5-env

conda update astropy
pip install naif
```
STM32G031とS-5851Aで温度をPA2ハードウェアシリアルに出力


x 動作確認済み2022/6/2 16:31

x OBでGPIOがわかる人むけ

x あまり正確では、ない

目的
秋月で売っている安価なS-5851A(約110円)を使って温度を出力する。

1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり



![o_con514.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6eaaa02a-93ba-12ec-7a3c-1da69c6facba.jpeg)



名前は、まだない


```c++



//I2C_5851_HS_031_2

#include <Arduino.h>
#include <Wire.h>
#include <HardwareSerial.h>

#define S5851A 0x48


//初期化
void setup()
{

  delay(3000); //not delete

  //シリアルの初期化
  Serial.setTx(PA2_ALT1);
  Serial.setHalfDuplex();
  Serial.begin(9600);

  //i2cの初期化
  Wire.setSDA(PA12);
  Wire.setSCL(PA11);
  Wire.begin(); //pa12 pa11

} //setup


//メインループ
void loop()
{

  //0番目のレジスター
  Wire.beginTransmission(S5851A);
  Wire.write(0);
  Wire.endTransmission();
  delay(1);

  //温度の読み込み
  int s = 99; //センサーの値
  Wire.requestFrom(S5851A, 1);
  while(Wire.available())  {    // 要求より短いデータが来る可能性あり
    s = (int)Wire.read();       // 1バイトを受信
  }//while
  delay(1);

  //温度の表示
  Serial.println(s);

  //1秒の待ち
  delay(1000);

} //loop


```