OmniAICreator/Qiita-1.07M huggingface dataset:
GoogleMapAPIを利用する

##はじめに
Maps JavaSctipt APIを使用することで、JavaScript上で独自の画像やコンテンツを使ってカスタマイズしたGoogleマップを画面に描画できたり、Googleマップ上にマーカーを表示したりなど、マップの幅をグッと広げることができます。
[Maps JavaScript API](https://developers.google.com/maps/documentation/javascript/reference/map?hl=ja#:~:text=%E3%82%A6%E3%82%A7%E3%83%96-,Maps%20JavaScript%20API,-%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB)のリファレンスを参照すれば色々な使い方やできることができることがわかると思いますが、今回は、基本となる、Google Mapを画面に描画させる方法を紹介します。

##コード紹介

```Google_Maps_API.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Practice</title>
  <style>
    #target {
      width: 600px;;
      height: 400px;
    }
  </style>
</head>
<body>
  <div id="target"></div>

  <script src="https://maps.googleapis.com/maps/api/js?language=ja&region=JP&key=[自分のAPIキー]&callback=initMap" async defer>
  </script>
  <script src="js/main.js"></script>
</body>
</html>
```

```main.js
'use strict'
let map
let target = document.getElementById('target')

function initMap(){
  // google.map.Mapクラス呼び出し
  map = new google.maps.Map(target, {
    // マップの中心を指定
    center:{
      lat:1.283653,
      lng:103.859108
    },
    // マップの初期ズームレベル
    zoom:15
  });
}
```
とすると、
![googlemap](https://i.gyazo.com/e98fcf413f85b5fa738d66e0381fb57d.png)

このようにGoogle Mapが表示されます。

簡単な操作手順は以下の通りです。

######※コードを書く前に
Google Maps APIを使用するために、請求先アカウントの設定が必要になります。(少しの使用なら無料で使えるので支払う心配はありません、詳しくは調べてみてください。)API Consoleで作成したプロジェクトに対して請求先アカウントを紐付けてください。プロジェクトの作成は、最後にあります[Maps JavaScript APIを取得する方法]で説明しています。
######HTML
1. htmlでは、マップを入れ込むための要素を```div```で作り、JSで操作しやすいようid属性を設定しています。

2. ```scriptタグ ```を使用してMapsJavaScriptAPIをロードします。コードないの```[自分のAPIキー]```の部分に取得したAPIキーを記入します。APIの取得方法は、最後に記載しています。
3. ```scriptタグ ```のsrc属性に```callback=initMap```とすることで、```init関数```を呼び出しています。

######JS
1. ```initMap関数 ```内で、```google.map.Mapクラス```を呼び出しています。このクラスを使用することで、指定されたHTML要素内にマップを作成します。
第一引数にはマップを埋め込む場所（今回は```id=targetのdiv````)、第二引数には、マップに関するオプション(MapOptions)を関数で渡しています。

2. MapOptionsには様々なプロパティがあります。```center```は、表示されるマップの中心を緯度と経度でしてするためのプロパティです。```zoom```はマップの初期ズームを指定できます。0から始まり、数が大きくなるごとに拡大されていきます。

以上がGoogle Mapを画面に描画させる方法になります。

######Maps JavaScript APIを取得する方法
1. [Google Developers Console](https://console.developers.google.com/?hl=JA)から、[プロジェクトを作成する]を選択します。

2. プロジェクト名、を指定し、[作成]ボタンを押して、プロジェクトを作成します。

3. Maps JavaScript APIを有効にするために、[[Google Cloud Platform]] 
(https://console.cloud.google.com/home?hl=ja&project=massive-anagram-308701)→[ナビゲーションメニュー]→[APIとサービス]→[APIとサービスの有効化]から、APIライブラリを開きます。

4. 「Maps JavaScript API」を選択肢、[有効にする]ボタンを押し、APIを有効にします。

5. [ナビゲーションメニュー]→[APIとサービス]→[認証情報]→[APIキーを作成]とすることで、APIキーを取得することができます。
【Tips】CodeBuildでPostgreSQLのコンテナを起動してテストする

# はじめに
CodeBuildでアプリケーションのCIをするために、実物のAuroraに接続するのが面倒だったのでPostgreSQLをローカルでコンテナ起動してそこにデータを投入してテストをしようとしたら意外と大変だったのでメモっておく。

なお、CodeBuildのイメージは
- aws/codebuild/standard:5.0
- aws/codebuild/amazonlinux2-x86_64-standard:3.0
それぞれで使えるようにした。
DBについては、PostgreSQL12.Xを使用している。

前提知識としては、DockerやCodeBuildについてある程度経験があるといったあたりをターゲットにしている。

# 事前準備
Dockerを起動するので、CodeBuildの特権モード(Privilegeモード)はONにしておく。
※これをしておかないとDockerデーモンが起動しない。

# PostgreSQLの起動設定
Dockerイメージはどちらでも共通で使える。以下のファイルを用意しておこう。

```YAML:docker-compose.yml
version: '3'

services:
  postgres:
    image: public.ecr.aws/docker/library/postgres:12.7-alpine3.14
    restart: always
    environment:
      POSTGRES_USER: [ユーザ名]
      POSTGRES_PASSWORD: [パスワード]
      PGPASSWORD: [パスワード]
      POSTGRES_DB: [DB名]
      TZ: "Asia/Tokyo"
    ports:
      - 5432:5432
    volumes:
      - postgres:$PWD/pgdata

volumes:
  postgres:
```

# クライアントインストール Standard(Ubuntuイメージ)編
Ubuntuイメージの場合、4.0以前だと

```YAML:buildspec.yml(抜粋)
phases:
  install:
    runtime-versions:
      docker: 19
```

が必要になるが、5.0では標準でDockerが起動かのうになっているらしいので、上記は不要である。
デフォルトのイメージではpostgresql12のクライアントが入っていないのでインストールする。

```YAML:buildspec.yml(抜粋)
phases:
  install:
    commands:
      - apt-get update
      - apt-get install -y postgresql-client-12
```

# クライアントインストール AmazonLinux2編
AmazonLinux2のイメージでは、Dockerを使用する場合は下記のランタイム設定が必要になる。

```YAML:buildspec.yml(抜粋)
phases:
  install:
    runtime-versions:
      docker: 19
```

AmazonLinux2では、PostgreSQL12のクライアントはamazon-linux-extras([詳細は公式のナレッジセンター参照](https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-install-extras-library-software/))に入っているのだが、なぜかCodeBuildのイメージにはインストールされていない。遠回りだが、まずはamazon-linux-extrasからインストールしよう。

```YAML:buildspec.yml(抜粋)
    commands:
      - yum update -y --skip-broken
      - yum install -y amazon-linux-extras
      - ln -s /lib/python2.7/site-packages/amazon_linux_extras ~/.pyenv/versions/3.9.5/lib/python3.9/site-packages/
      - amazon-linux-extras enable postgresql12
      - yum install -y postgresql.x86_64
```

ここで、シンボリックリンクを作っているのは、amazon_linux_extras がデフォルトでPython2.7配下にインストールされるためだ。
なぜかこれだけは最新になっておりPython3.9から参照できるようにする。


# Docker起動
あとは、docker-composeでコンテナを起動してSQLで初期データを投入しよう。
接続情報は、最初に書いたdocker-compose.ymlと合わせよう。
起動完了の待ち合わせをするのは、起動直後にpsqlでデータを放り込もうとすると、おそらくReadyになり切っていなくてエラーになるためだ。

```YAML:buildspec.yml(抜粋)
env:
  variables:
    PGPASSWORD: [パスワード]
```
```YAML:buildspec.yml(抜粋)
 
  pre_build:
    commands:
      - docker-compose up -d
      # 起動完了を待ち合せてからロードする
      - sleep 5
      - psql -h localhost -U [ユーザ名] -d [DB名] -f ./[初期投入用のSQLファイル].sql 
```

ここまでやれば、あとはアプリケーションからローカルホストに向けてテストを実行してやればよい。
これだけのことなのだが、CodeBuildの拡張パッケージのインストールに思ったよりも苦戦してしまった……。
ラズベリーパイで小型Webサーバーをつくってみる。(その2)

[前回](https://qiita.com/iizuka-youhei/items/eec7aba5f4d3ae45521c)はラズベリーパイにnginxをインストールして、ブラウザ上で静的なページを表示しました。
今回はphpをインストールして動的なページを表示してみます。
## PHPをインストール
```
sudo apt install php7.3-fpm
```

## nginx上での設定
PHPをインストールしたら次はnginx上でPHPを利用するための設定をします。
``/etc/nginx/sites-available/default``を編集します。
```
sudo mousepad /etc/nginx/sites-available/default
```
エディタを開いたら、「#ADD index.php to the list if you are uging index.php」と書かれた場所を探し、index.phpを追加します。
![スクリーンショット 2022-02-26 20.51.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353901/96eb798a-af88-349f-0689-366eea231394.png)

次に、「location」と書かれた場所を探し、}までの#を削除して下の画像のようにします。
``fastcgi_pass 127.0.0.1:9000;``と書かれた部分の#は削除しないので注意してください。
![スクリーンショット 2022-02-26 20.56.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353901/a4048b96-21ce-afb9-d783-30c57660c6ae.png)

完了したら保存して、次は「/etc/php/7.3/fpm/php.ini」を編集します。
```
sudo mousepad /etc/php/7.3/fpm/php.ini
```
control + Fで「cgi.fix_pathhinfo」と検索し、「cgi.fix_pathhinfo = 1」を「cgi.fix_pathhinfo = 0」に変更します。
![スクリーンショット 2022-02-26 21.01.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353901/2221c28f-cf43-45da-da93-0eca6345b394.png)

変更したら保存して、phpとnginxを再起動します。
```
sudo systemctl restart php7.3-fpm
sudo systemctl restart nginx
```

最後に``/var/www/html/``にてphpファイルを作成してみます。

```
sudo mousepad /var/www/html/test.php
```
現在時刻を表示してみましょう。
```php
<?php
echo date("Y/m/d H:i:s");
?>
```

ブラウザで/test.phpにアクセスすると現在時刻が表示されました！
``http://ラズベリーパイのIPアドレス/test.php``
![スクリーンショット 2022-02-26 21.49.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353901/ac35300d-5cbd-3472-8a96-63d710f4bd0b.png)
pipのキャッシュを削除

# 説明
pythonに関するキャッシュクリア関連の方法のメモ。

# pip
pip 20.1以降でキャッシュ削除用のコマンドが実装されたらしい。
なので20.1より前はキャッシュフォルダ(OSごとに異なる)の場所を指定して直接削除する、それ以降の場合はコマンド(OS共通)を利用する。

## pip```20.1```より前の場合
- LinuxやUnixの場合
``` bash
rm -rf ~/.cache/pip
```
- OS X
``` bash
rm -rf ~/Library/Caches/pip
```
- Windows
```
rm -rf %LocalAppData%\pip\Cache
```

## pip```20.1```以降の場合
- matplotlibに関連するすべてのwheelキャッシュファイルをpipから削除
```
pip cache remove matplotlib
```
- すべてのwheelキャッシュファイルをpipから削除s
```
pip cache purge
```

## 参考
- [Removing pip's cache? -stackoverflow](https://stackoverflow.com/questions/9510474/removing-pips-cache)
スクリプトへんすう「こども向けのSnap!かいせつ」

「へんすうをつくる」ボタンで作るグローバルへんすうのようなへんすうは、プロジェクトが続くかぎりなにかのあたいが入っています。ゲームの点数などのあたいを入れておくといった使い方ができます。
しかし、時にはへんすうをあるスクリプトが動いている「その時だけ」使いたいことがあります。
それが「スクリプトへんすう」というものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671164/71af0edd-8cc3-cbc5-af75-5680acc46c38.png)
このスクリプトを動かすと、やじるしがいろんな方向に動き回るところを見ることができます。
forブロックの中のへんすう「i」と同じように、「スクリプトへんすう」ブロックのオレンジ色の丸いブロックをクリックすると、名前を変えることができます。そして、オレンジ色の丸いブロックをドラッグすると、そこから続くスクリプトだけでそのへんすうを使うことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671164/8ebea45b-b7f6-99d6-43e2-04931d22e707.png)
オレンジ色のブロックの右がわの三角をクリックすると、へんすうを増やすこともできます。

<a href="https://qiita.com/wordplugin/items/102d2cac8e4c8c3bbbb9">戻る</a>
リーダブルコード ざっくり解説

へい、豚野郎です。
最近、「Qiitaの更新がないですね」と言われますが、僕にも僕にも事情があるのだ（適当）。

と、いうわけで書いてない間に何をしていたかというと、
「リーダブルコード」という本を読んでいました。


専門学校時代、先生とか「この本は素晴らしい本だ！」って言ってた（気がする）ので
買って読んだのですが、PHPerの僕にはちょっとわからない（言い訳）なところもあり
解読に時間がかかってしまいました。
それがQiitaを放置していた原因です（言い訳）。

ただ、未だにわかっていないところもあるので
それは今後のエンジニアとしての経験で補っていつかわかる日が来る様にします。

そのため、「ざっくり解説」です。
詳しい内容は是非、買って読んでください。

# 1. コードは読みやすく・理解しやすく
【ポイント】
・バグが見つけやすくなる。
・自分のコードが流用される可能性がある。
・他の人がわかるようにするため。
・他の人が理解する時間を短くする。


# 2. 名前の情報はわかりやすく
【ポイント】
・明確な単語を使う。
・汎用的な名前は避ける。
・具体的にわかるようにする。
・接尾辞・接頭辞をつけるとよい。
・文字の長さを決める。
・名前のフォーマットで情報を伝える。

変数の意味を間違えると、読み手の誤認に繋がります。
get・size・clipなど、読み手によって受け取り方が変わるので注意が必要です。


# 3. 美しいコード設計
【ポイント】
・読み手が慣れているパターンと一貫性のあるレイアウトを使う。
・似ているコードは似ている様に見せる。
・関連するコードはまとめてブロックにする。

読み手の読む時間が短くなります。


# 4. コメント
【ポイント】
・見ればわかることはコメントしない。
例. ○○を設定する。
・汚い関数名をつけてコメントするくらいなら、関数名を直す。
・自分の考えを記録する。
・コードの欠陥には恥ずかしがらずにコメントを付ける。
・意図を書く。

プロジェクトに配属されたばかりの人など、読み手はプロジェクトを熟知していません。
優れたコメントより、優れたコードを書きましょう。


# 5. 制御フローとループ
【ポイント】
・If文は以下の場合、
①. if( ○ > ○)
②. if( ○ < ○)
左が調査対象で、右が比較対象にした方がわかりやすい。
if()の括弧の中は否定形(!)より肯定型を使った方がよい。
・? a : bの様に省略形はわかりにくいので、普通に書いた方が読み易い。
・do/whileやgotoはあまり使わない方がよい。


# 6. コードを読みやすくする
【ポイント】
・無駄な変数は削除する。
・グローバル変数はあまり使わなければ避ける。
・定数は使う直前に書く。

変数の中身をあまり何度も変更しないとよいです。


# 7. 汎用的なコードは関数でまとめた方がよい
【ポイント】
・テストしやすくなる
・プロジェクトから独立したプログラムはUtilなどの名前で分けるとよい。

汎用的なコードは関数でまとめた方がよいが、ケースバイケースです。
やりすぎには注意してください。


# 8. 言葉で簡潔に説明できるコードにする


# 9. プロジェクトが成長すれば、コード量も増える
【ポイント】
・いらないコードは消し、重複コードを減らす。
・軽量化に機敏になる。

# 10. テスト
【ポイント】
・どういう振る舞いから、どういう動きを期待するか。
・丁寧にやりたければ1機能に1テスト。
・テスト名にtest1、test2などNG。
内容がわかるようにする。
・やりすぎてテストコードだらけで、本物のコードがわからなくなることに注意する。
・テストコードはなるべく簡潔に書く。


# 感想
さすが専門学校の先生・技術力の高かった生徒が勧めた内容だなぁと思いました。
仕事でも見たことあるものも見られました。

学生さんから現役エンジニアまで勧められる1冊です。
AWSでのSaaS事例とか

# はじめに

AWSでのSaaS事例を、AWSのサービスを使ったSaaS事例、パッケージをSaaS化した事例と、それに関連するAWSリファレンスを載せています。あと、AWSのSaaSに関連するホワイトペーパーやドキュメントを載せています。少しづつ更新していきます。

# AWSのサービスを使ったSaaS事例

## QuickSight

#### QuickSightでSaaSにダッシュボード埋め込み事例

* [リブパス/Redfox：2020年 「QuickSight事例祭り」の資料](https://aws.amazon.com/jp/blogs/news/amazon-quicksight-matsuri-20200812/)

* [ソフトブレーン：2020年 「QuickSight事例祭り」の資料](https://aws.amazon.com/jp/blogs/news/amazon-quicksight-jirei-matsuri-saas-2020/)

## Private Link

#### Private Linkを使ったSaaS提供事例
* [Works Human Intelligence AWS公式ページでPrivateLink対応](https://partners.amazonaws.com/jp/partners/0010h00001d3w88AAA/Works%20Human%20Intelligence%20co.,ltd.)

# SaaS化事例

* [MOTEX：「オンプレミスのパッケージ製品からマルチテナントのSaaS製品へ」というタイトルで SaaS on AWS Day 2022 に登壇しました](https://tech.motex.co.jp/entry/2021/12/22/135541)

# AWSのSaaS関連ドキュメント

### ホワイトペーパー

* [SaaS Storage Strategies](https://d1.awsstatic.com/whitepapers/Multi_Tenant_SaaS_Storage_Strategies.pdf)
* [SaaS Tenant Isolation Strategies](https://d1.awsstatic.com/whitepapers/saas-tenant-isolation-strategies.pdf)
* [Patterns for Ingesting SaaS Data into AWS Data Lakes](https://d1.awsstatic.com/whitepapers/patterns-for-ingesting-saas-data-into-aws-data-lakes.pdf)

### [AWS Prescriptive Guidance](https://docs.aws.amazon.com/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/welcome.html)
Implementing managed PostgreSQL for multi-tenant SaaS applications on AWS

### マルチテナント認証

* AWS 上のマルチテナント SaaS 環境におけるセキュリティプラクティス [AWSブログ](https://aws.amazon.com/jp/blogs/news/security-practices-in-aws-multi-tenant-saas-environments/)

### マルチテナントDB

* PostgreSQL の行レベルのセキュリティを備えたマルチテナントデータの分離 [AWSブログ](https://aws.amazon.com/jp/blogs/news/multi-tenant-data-isolation-with-postgresql-row-level-security/)

* マルチテナント化で知っておきたいデータベースのこと [SlideShare](https://www.slideshare.net/AmazonWebServicesJapan/20220107-multi-tenant-database)
  * マルチテナントをする時のデータベースエンジンの特徴を知る

### SaaS BI

* QuickSight埋め込み方法をちょっぴりDiveDeep [SlideShare](https://www.slideshare.net/AmazonWebServicesJapan/20220225-choppiri-dd-quicksight-embed)
  * SaaSで表示するグラフ/ダッシュボードをフルマネージドなQuickSightで安価に実現。事例もいっぱい

### SaaS コスト関連

* AWS SaaSテナント毎コストの把握に便利なApplication Cost Profilerの紹介 [SlideShare](https://www.slideshare.net/AmazonWebServicesJapan/20220225-choppiri-dd-application-cost-profiler-251327996)
  * マルチテナントの料金を、AWSタグではなく、テナントごとの利用時間で算出

### パッケージの簡単SaaS化

* パッケージソフトウェアを簡単SaaS化!?既存の資産を使ったSaaS化手法の紹介 [SlideShare](https://www.slideshare.net/AmazonWebServicesJapan/20211209-saas-on-aws-day-a4-appstream2-for-saas)
  * パッケージをAppStream2.0で簡単にSaaS化
  
### SaaSにおける通信

* 機密データとSaaSは共存しうるのか！？ [SlideShare](https://www.slideshare.net/AmazonWebServicesJapan/20211209-saas-on-aws-day-a5-privatelink-for-saas)
  * P37から、マネーフォワードやWorksApplicationsで、SaaSにおけるPrivateLinkを使ったセキュアな接続事例が掲載
【rails】登録日の表示について

はじめに
---
今回はdeviseというgemを使った環境だったのでcreated_at（登録日）というカラムが最初から入っていました。
なのでそれを使います。

結論
---
```rails:index.html.erb
<span class="scoreStatus_list_label registration_date">
   登録日
  <%= current_user.created_at.strftime('%Y/%m/%d') %>
</span>
```
こちらのコードを表示させると

![スクリーンショット 2022-02-26 21.26.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340036/5d8deea6-d92f-adfb-8b29-5e36e878899e.png)

こうなります！

注意点
---
ログイン（新規登録）してからじゃないと、current_userがエラーを起こしますのでご注意を！
pythonでプロットしてみる#1

RPLiDARで取得したx,y,z座標の情報をmatplotlibで散布図として表示してみたい

データの取得は前回の”二次元データの並び替え”を参照してほしい

# 実際にプロットしてみる
```pts.py
import matplotlib.pyplot as plt
import math
for i in range(len(x_list)):
    plt.plot(float(x_list[i]),float(y_list[i]),marker='*')
plt.xlim(0,math.ceil(float(max(x_list))))
plt.ylim(0,math.ceil(float(max(y_list))))
plt.title('Title',fontsize=15)
plt.xlabel('X',fontsize=10)
plt.ylabel('Y',fontsize=10)
```

# 実際にプロットした結果
![pts.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1496349/d73da101-82ec-a793-5fd4-4b5487314153.jpeg)

 ちゃんと指定した点の形でプロットされている！
標準入出力についてまとめてみた

# 標準入出力

<dl>
 <dt>標準入力(stdin)</dt>
 <dd>プログラムの標準的な入力。通常はキーボードが使用される。</dd>
 <dt>標準出力(stdout)</dt>
 <dd>プログラムの標準的な出力。通常は端末ディスプレイが使用される。</dd>
 <dt>標準エラー出力(stderr)</dt>
 <dd>プログラムのエラーメッセージを出力するための標準的な出力。<br>
標準出力と同じく端末ディスプレイが使用される。</dd>
</dl>

難しく聞こえるがキーボードでコマンドを入力することや、
入力結果が出力されることを言っている。

少しイメージをしやすいように例えるなら

- Googleの検索フォームにキーワードを入力（標準入力）する
- 検索結果がブラウザに表示（標準出力）される
- 検索結果の1番上のURLをクリック（標準入力）する
- 404エラーページが返ってくる（標準エラー出力）
> 404エラーページが返ってくる（標準エラー出力）

ここ自信ないので間違ってたらご指摘いただけると嬉しいです😅

この3つを合わせて**標準入出力**と呼ぶ。

それぞれの入出力先はこちらが何も指定しないと、
> 通常はキーボードが使用される。
> 通常は端末ディスプレイが使用される。

.. となるが、柔軟に変更することが可能。
そして入出力先を変更することを**リダイレクト**と呼ぶ。


## リダイレクト
標準入出力先を変更する機能のこと。

リダイレクトがあると嬉しいこと

- コマンドの出力結果（標準出力）をコマンドの入力（標準入力）に繋げることで複雑な処理を実現できる
- 出力結果をファイルに書き込むことができる 

そしてLinuxの各コマンドは実行結果が必ず標準入出力になるように設計されており、各標準入出力は数値として管理されている。

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

こちらは今回あまり詳しく記載しませんが後ほど少々使用するためご紹介。

### 実際にやってみる

#### 標準出力のリダイレクト
リダイレクトなし（出力先 -> ディスプレイ端末）
```
% echo HelloWorld
HelloWorld
```
リダイレクトあり（出力先 -> テキストファイル）
```
% echo HelloWorld > helloworld.txt
% cat helloworld.txt
HelloWorld
```

入力した`HelloWorld`がファイルに書き込まれています。
出力先を存在するファイルにする場合、上記では上書きされてしまいます。
内容の追記を行いたい場合は`>>`を使用してリダイレクトします。
```
% echo HelloWorld2 >> helloworld.txt
% cat helloworld.txt
HelloWorld
HelloWorld2
```

#### 標準エラー出力のリダイレクト
試しに存在しないファイルを`cat`の引数に与えてみる。
```
$ cat helloworld2.txt
cat: helloworld2.txt: そのようなファイルやディレクトリはありません
```
期待通りの結果ですね。
上記を標準出力のリダイレクトと同じ方法でファイルに書き込んでみる。
```
% cat helloworld2.txt > error.txt
% cat: helloworld2.txt: そのようなファイルやディレクトリはありません

% cat error.txt
%
```
おや...期待する挙動ではないですね。そもそも...
> 上記を標準出力のリダイレクトと同じ方法でファイルに書き込んでみる

を行った際に通常の出力先（端末ディスプレイ）に結果が返ってきてました。
```
$ cat helloworld2.txt
cat: helloworld2.txt: そのようなファイルやディレクトリはありません
```

なぜか？
標準出力エラーの場合は数値の`2`として管理されていて、
標準出力と同じ方法ではリダイレクトが行えません。

でもエラーメッセージをファイルに書き込みたい...そんな時はこうします。

```
% cat helloworld2.txt 2> error.txt
% cat error.txt
cat: helloworld2.txt: そのようなファイルやディレクトリはありません
```
うまくいきました。
`2>`は標準エラー出力をファイルにリダイレクトしてねということになります。

#### 標準入力のリダイレクト
引数にキーボードでの入力ではなくファイルを渡してみます。
```
% cat < helloworld.txt
HelloWorld
HelloWorld2
```
期待通りに動いています。
ちなみに`<`がなくても同じ結果が得られます。

```
% cat helloworld.txt
HelloWorld
HelloWorld2
```

一見全く同じように見えますが、前述の標準入出力の数値が変わります。
この違いはいつかご紹介する`|`（パイプ）を使用する際に重要になってきます。

### 最後に
今回紹介したリダイレクトの種類をまとめておきます。
他にもあるので気になる方は調べてみてください。

| コマンド        | 実行結果 |
| ------------ |---- |
| command > file | コマンドの出力結果をファイルへ書き込み|
| command < file | ファイルの中身をコマンドの標準入力へ切り替え|
| command >> file | コマンドの出力結果をファイルへ追記|
| command 2> file | エラー出力をファイルへ書き込み|
| command 2>> file | エラー出力をファイルへ追記|
グローバルへんすう「こども向けのSnap!かいせつ」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671164/2c8d3b3d-8d9b-00cf-8bd4-c9db450aa5c9.png)
パレットエリアの「へんすうをつくる」ボタンを押すと、いくつでもへんすうを作ることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671164/468ce2dd-bdeb-4125-75bc-dc12f4ac9d56.png)
「へんすうをつくる」ボタンを押すと、へんすうの名前をいれるダイアログが出てきます。
このダイアログでは、へんすうがすべてのスプライトで使われるようになるか、今スクリプトエリアにひょうじされているスプライトだけで使えるのかを選ぶことができます。

もし、「点数」というへんすうを作ったらこのように見えるはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671164/26787d6f-676a-8ee9-2640-1568de1ee4d7.png)

それでは「へんすうをさくじょ」ボタンを押してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671164/e32c7a0c-7440-77a2-ecd9-a1fac26b385d.png)
へんすうの名前がでてきますから、消したい名前を押すと、へんすうを消すことができます。

forブロックの中のへんすうと同じように、パレットエリアからへんすうの丸いブロックをスクリプトエリアにいどうさせると、そのへんすうを使うことができます。
へんすうの丸いブロックのとなりのチェックボックスにチェックが入っていると、ステージエリアにへんすうの名前とオレンジ色のボックスがひょうじされているはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671164/b7117cb0-346c-b3ee-2a28-c55c83e79dfb.png)
このオレンジ色のボックスに入った数字や文字がへんすうのあたいです。

へんすうにあたいを入れるには、「［］を0にする」ブロックをスクリプトエリアにいどうさせ、三角のところを押して、あたいを入れたいへんすうの名前を選びます。そして、「0」のところにへんすうにいれたいあたいを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671164/3cb7e44f-241f-d5dc-1a50-18cfb9bcd870.png)

もし「へんすうをつくる」ボタンを押した後のダイアログで、「このスプライトよう」をえらぶと下のように名前の前にマークが入ります。このへんすうは、別のスプライトをえらぶと出てきません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671164/1e8983c5-27ac-aa9b-41ed-e579f77f6793.png)


<a href="https://qiita.com/wordplugin/items/102d2cac8e4c8c3bbbb9">戻る</a>
Node.jsのMySQLモジュールを使った値のエスケープでハマった話

## はじめに
こんにちは。ブログとQiitaの使い分けがいまいちできない鮎月(あゆつき)です。
Qiitaの投稿は2つ目になりますが、タイトル通りの話です。

一応確認ですが、このモジュールについてのお話です:

https://www.npmjs.com/package/mysql

https://github.com/mysqljs/mysql

## 2つのエスケープ方法
Node.jsのMySQLモジュールには、2つのエスケープ処理の方法があります。

### connection.escape()
例としてこんな感じになります (公式Docより)
```js
var userId = 'some user provided value';
var sql    = 'SELECT * FROM users WHERE id = ' + connection.escape(userId);
connection.query(sql, function (error, results, fields) {
  if (error) throw error;
  // ...
});
```
ちなみに公式Docには次のような説明も。
> In order to avoid SQL Injection attacks, you should always escape any user provided data before using it inside a SQL query. You can do so using the mysql.escape(), connection.escape() or pool.escape() methods:

意訳) SQLインジェクション回避したいなら `connection.escape()`とか使ってな

### 疑問符プレースホルダー
普通はこっち？
またまた公式Docのサンプルコードです
```js
connection.query('SELECT * FROM users WHERE id = ?', [userId], function (error, results, fields) {
  if (error) throw error;
  // ...
});
```
またまた公式Docより引用:
> Alternatively, you can use ? characters as placeholders for values you would like to have escaped like this:

意訳) 「?」をプレースホルダーとして使えるで

> This looks similar to prepared statements in MySQL, however it really just uses the same `connection.escape()` method internally.

DeepL訳) これは MySQL のプリペアドステートメントに似ていますが、**実際には内部で同じ `connection.escape()` メソッドを使用しているだけです**。 

この一文のせいです。
こいつのせいで当時(今でも)MySQL初心者の私はドツボにハマりました。

## 今までに使っていたエスケープ処理
最初は、`connection.escape()` を用いたエスケープをしていました。
公式Docにもこれが最初に書かれてたし、疑問符プレースホルダーはあまり使われないのかなーなんて思ってました。(DB触るの初めてだったから)
しかし、これを使うと文字列が面白い形で格納されます。
というのも、文字列が`'`で囲まれます。

公式Docによると
> Strings are safely escaped

訳) 文字列は安全にエスケープされます
だそうです。

公式Docには、先ほどの「実際には内部で同じ `connection.escape()` メソッドを使用しているだけです」とあったので、正直こういう仕様なのかと思ってました。
疑問符プレースホルダーでもこうなるのかと。

## そんなことはなかった
先日ふとした思いつきで、疑問符プレースホルダーを試してみました。
なぜ初めて触る時に試さなかったのかは聞かないでください。

するとどうでしょう。
なんの記号で囲まれることもなく、素直に格納されました。

発狂した。

## つまり
内部的には `connection.escape()` と同じとか書いてありましたが、実際は若干違います。
面白いことを起こしたくないなら何が何でも疑問符プレースホルダーを使いましょう。

って1年前の私に言いたい。

そんな話なので、Node.jsでMySQLを触ろうとしている人はちょっと注意してください。
それでは。
【Scala】BooleanProperty を反転させる

JavaFX で、「フルスクリーンの時にツールバーを表示する」ということを実現したい場合、 `bind()` を用いて以下のようにコードを書けばよい。

```scala
toolBar.visibleProperty().bind(primaryStage.fullScreenProperty())
toolBar.managedProperty().bind(primaryStage.fullScreenProperty())
```

一方、「フルスクリーン**でない**時にツールバーを表示する ＝ フルスクリーンの時にツールバーを非表示にする」ということを実現したい場合は、 `.not()` を用いて BooleanProperty を反転させればよい。

```scala
toolBar.visibleProperty().bind(primaryStage.fullScreenProperty().not())
toolBar.managedProperty().bind(primaryStage.fullScreenProperty().not())
```
ラズベリーパイで小型Webサーバーをつくってみる。

## nginxを導入
まずは恒例のupdateとupgrade
```
sudo apt update
```

```
sudo apt upgrade
```

その後にnginxをインストール。

```
sudo apt install nginx
```

インストールが完了したら以下のコマンドを実行して、nginxを起動。
また、再起動したときnginxが自動で起動するようにします。
```
sudo systemctl start nginx
sudo systemctl enable nginx
```

ラズベリーパイと同一のネットワーク内にあるPCでブラウザを起動。
そして、``http://ラズベリーパイのIPアドレス``と入力してEnterを押すと、「Welcom to nginx」と書かれたページが表示されます。
![スクリーンショット 2022-02-26 19.40.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353901/23f79a40-ef1a-6a7e-7602-1abc93e255bb.png)

nginxではデフォルトで「var/www/html/」がドメインルートになっている。
この中にindex.htmlファイルを作成して編集。

```
sudo mousepad /var/www/html/index.html
```

適当にコーディングして表示してみる。
![スクリーンショット 2022-02-26 20.08.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353901/2ee820f5-bcc7-b0f3-8e6c-d51e8503e6f0.png)

先程の「Welcom to nginx」と書かれたブラウザをリロードすると表示されました!
IBM Cloud Professional Architect v5 受験体験記

# IBM Cloud Professional Architect v5について
IBM Cloud Professional Architect v5は、アーキテクトを対象としたIBM Cloudの中級レベルの認定試験として、昨年の8月にリリースされました。

https://www.ibm.com/training/certification/C0001403

# 筆者の前提スペック
- IBM Cloudは普段の業務でOpenShift, Watson, DBを使っている程度のライトユーザー
- 初級レベルの認定試験である[Advocate v1](https://qiita.com/yukinocist/items/e337931dbd8920ba6ebf)と[Technical Advocate v3](https://qiita.com/yukinocist/items/70b3db416bd8b184ccbd)は昨年合格済
- 英語があまり得意ではない

# 学習教材

### 模擬試験
有料の模擬試験です。試験勉強前に腕試しも兼ねて受験してみましたが、それなりに難易度が高くギリギリ合格でした。
試験終了後にスコアと合わせて、各出題分野における正答率が表示されるため、自分が理解できていない分野を把握するのにもちょうどよいのではないかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134250/3d5ad177-0653-f712-24bf-84860ff057e2.png)

### ラーニングパス
ラーニングパスが公開されており、こちらに沿って学習を進めていけば問題なく合格できると思います。

https://www.ibm.com/training/path/ibmcloudprofessionalarchitect

# 学習方法
だいたい1か月くらいかけて、下記のような流れで学習をすすめました。
1. とりあえず模擬試験を受験して、出題範囲や傾向などをざっくり把握する
2. ラーニングパスをひととおり眺めて、知らなかった部分や重要そうな部分はメモしておく
3. よくわからなかった部分は実際に触ってみる
4. 自分が触ったことない部分や模擬試験でわからなかった部分をStudy Guideで重点的に見直す（私の場合、VMwareやDirect Linkなど）
5. Study Guideに記載されている問題をひととおり解いてみる

# 試験結果
オンラインで受験し、無事に合格することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134250/0af289f1-9ff2-50b8-2539-041bec894cba.png)

# 受験した感想
- 問題文が英語という意味でもそうですが、選択肢が非常にわかりづらく、シンプルに難しかったです。
- 問題を解いた体感としては、自信がある問題3割、たぶんあってる問題4割、あまり自信がない問題2割、何を聞かれてるのかよくわからない問題1割という感じでした。
- 受験対策として、ラーニングパスをひととおりやりましたが、正直Study Guideだけでよかったかも？と思いました。
- 昨年AWS SAAを受験したのですが、SAAでは、アーキテクチャのベストプラクティスに関する問題（プライベートサブネットからインバウンド接続を許容しないでインターネット接続するには何が必要？みたいな問題とか）が頻出していたように感じていましたが、同じくアーキテクトを対象とした中級試験である本試験では、そういった問題は少なく、どちらかというとサービスの特徴やユースケースを問う問題が圧倒的に多かったと感じました。

# 参考文献
* IBM Cloudの新認定試験IBM Cloud Professional Architect v5を受けてみた

https://qiita.com/teruq/items/54c66a3f02cdad7faab6
yarn start できなくなった

# yarn start　できない
command failed with exit code 127.
が表示されている
## 試したこと
### yarn install
何も変わらず
### rm -rf node_modules　後に　npm install
何も変わらず
### yarn add yarn
できた！

# まとめ
結局何が原因なのかは分かりませんでしたが、なんとかなったので、よしとします。
また、このあたりはきっちり学習しないと困る気がするので頑張ります。
40 代おっさん GASでHTML・JSONからデータを取り出す

## 本記事ついて

本記事は プログラミング初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。

## HTMLから正規表現でデータを抽出する

HTMLドキュメント全体の文字列から必要なデータのみを取り出すと言う作業が必要となる。
具体的には、StringオブジェクトのmatchメソッドでHTMLドキュメントから該当の要素を取得し、同じくreplaceメソッドでHTMLタグを取り除くという手順になる。

```javascript
function tosiki() {
  const url = 'https://tonari-it.com/scraping-test/';

  const response = UrlFetchApp.fetch(url);
  const html = response.getContentText();
  const title = html.match(/<title>.*?<\/title>/i)[0];
  console.log(removeTag_(title));

  const entries = html.match(/<h2>.*?<\/h2>/gi);
  for (const entry of entries) console.log(removeTag_(entry));
}

function removeTag_(str) {
  return str.replace(/<\/?[^>]+/gi, '');
}
```

### APIを使ってJSONデータを取得する

APIとは
ソフトウェアの機能やデータを、外部のプログラムから呼び出して利用する仕組みのこと

REST APIとは
APIの形式の１つで、特定のURLに対してHTTPリクエストを送ることで、外部から操作ｓることが出来る

例として郵便局のAPI

```javascript
http://zipcloud.ibsnet.co.jp/doc/api
```

このAPIは以下の定められたリクエストURLを送信することで、JSON形式でレスポンスを受け取ることができる。

```javascript
https://zipcloud.ibsnet.co.jp/api/search?zipcode={izipcode}
```

{izipcode}には、７桁の郵便番号を配分なしで指定
このURLをリクエストすることにより、指定した郵便番号に対する住所データをJSON形式で取得できる。

```javascript
function tosiki() {
  const zipcode = '7830060';
  const url     = 'https://zipcloud.ibsnet.co.jp/api/search?zipcode=' + zipcode;
  const response = UrlFetchApp.fetch(url);

  const obj = JSON.parse(response.getContentText());
  console.log(`ステータスコード： ${obj.status}`);

  const result = obj.results[0];
  const {address1, address2, address3} = result;
  console.log(`都道府県名： ${address1}`);
  console.log(`市区町村名:　${address2}`);
  console.log(`町域名:　${address3}`);
}
```

## 参考資料

<https://www.amazon.co.jp/%E8%A9%B3%E8%A7%A3-Google-Apps-Script%E5%AE%8C%E5%85%A8%E5%85%A5%E9%96%80-%E7%AC%AC3%E7%89%88/dp/4798064742>
フローでApexアクションからコレクション変数を受け取る

## 前置き
Spring'22もフローが大きく強化され、ますます使い勝手があがってきました。
またこれまで自動化ツールとしてよく使われていたワークフロールールやプロセスビルダーも将来的に使えなくなるとのことからフローの注目度も高まってきているように思います。

今回はApexアクションとフローを組み合わせたレコードに添付されたファイルを削除する画面フローをご紹介していきます。

特にコレクション変数をどうやってフロー側に渡すかご紹介していきます。

## 大まかなファイル削除フローの説明
![フロー１.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510376/0e65110b-722d-b2b1-7cbc-5092b663937c.png)


1.添付ファイルを取得するApexアクションを実行
2.決定要素で１に添付ファイルがある場合は「ある」へ進み、削除したいファイルを選択する
　「ない」の場合は「添付ファイルがありません」と表示して終了
3.２で選択された添付ファイルを削除して、アクションを実行して成功トーストを表示する

## Apexアクション「添付ファイル取得」
まずはサンプル的に書いたコードは以下の通りです。

~~~FileDelete.cls
global class FileDelete{
    @InvocableVariable(required=true label='recordId')
    public Id recId;

    @InvocableMethod(label='添付ファイル取得' description='添付ファイル削除')	
    public static List<List<ContentDocument>> getContent(List<Id> recId){
        List<List<ContentDocument>> cdList2= new List<List<ContentDocument>>();
        List<ContentDocument> cdList = new List<ContentDocument>();
        List<Id> cdIdList = new List<Id>();
        
        List<ContentDocumentLink> cdlList = 
            [
                SELECT ContentDocumentId, LinkedEntityId
             	FROM ContentDocumentLink
             	WHERE LinkedEntityId =:recId
            ];
        
        if(cdlList.size() > 0){

            for(ContentDocumentLink cdl : cdlList){
                cdIdList.add(cdl.ContentDocumentId);
            }
            
            cdList = [SELECT Id,title FROM ContentDocument WHERE ID IN :cdIdList];           
            cdList2.add(cdList); 
        }
        
        return cdList2;
        
    }
}

~~~


ポイントはフローへコレクション変数を渡したい場合はメソッドの戻り値を `「List<List<>>」`  とすることです。直観的には「List<>」ではないかと考えがちですが、「List<>」とするとフローには戻り値として単一の変数が戻ってきます。


## 画面「添付ファイル削除選択画面」
![フロー２.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510376/ad1339a2-f67e-7c0b-f468-fd9635b81119.png)

「添付ファイル取得」でApexからコレクション変数を受け取ったところでこれを選択リストに設定します。Spring'22からこのようにコレクション変数を選択肢として使用できるようになったので表現の幅が広がったと思います。
![フロー３.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510376/77ad544c-6aaf-0e81-0e21-f43ba97b0284.png)


あとは選択したファイルを削除するようにし、アクションとして成功トーストを表示させれば完了です。

成功トーストの参考は以下となります。
[フローでレコードをリダイレクトしてメッセージ表示をさせてみた](https://qiita.com/DEKA_PIYO/items/85edf7804f15d056d738)

:::note info
補足
ファイルの削除はシステム管理者かそのファイルの所有者しかできないので注意が必要です。
:::
ラズベリーパイをMac上で操作できるようにする方法について

## やりたいこと
ラズベリーパイ4にマウスとかキーボードとかモニターとか繋がずにMacから操作がしたい。
デスクのスペースは有限です。ラズベリーパイには電源ケーブルのみつないだ状態で使いたいときにMacで接続して操作ができたら省スペース化になりそうなので…

## 必要なこと
### Raspberry Piでの操作
Raspberry Piの設定からインターフェイスを開く。
<img width="400" alt="スクリーンショット 2022-02-26 15.07.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353901/f69ac0e8-5c6e-a454-d346-a198e4ff21b0.png">
インターフェイスのSSHとVNCを「有効」にします。

<img width="400" alt="スクリーンショット 2022-02-26 15.09.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353901/1205bf63-2663-696d-46be-b653c5014ca3.png">

VNCサーバーが起動すると、画面右上のアイコンにVNCのアイコンが表示される。
![スクリーンショット 2022-02-26 15.10.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353901/ffb3f88c-6b2d-3d61-98d3-f605ef4d3d6a.png)
アイコンをクリックするとIPアドレスが表示され、このIPアドレスはMacからの接続時に必要になります。

### Macでの操作
Macに「VNC Viewer」をダウンロードする。
ダウンロードサイト：https://www.realvnc.com/en/connect/download/viewer/

VNC Viewerを起動したら、Raspberry　PiのIPアドレスを入力してEnterキーを押します。
<img width="500" alt="スクリーンショット 2022-02-26 16.10.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353901/c80fd4c3-6c9a-0c49-1092-0b29e5099c86.png">

もし確認メッセージが表示されたら、「Continue」をクリックしてください。

ラズベリーパイのUsernameとPasswordを入力。

![スクリーンショット 2022-02-26 16.10.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353901/346534b4-5edb-cc0b-29c4-7c2c7b8150cb.png)


Raspberry Piのデスクトップがウィンドウ内に表示がされて、操作ができるようになります。
![スクリーンショット 2022-02-26 19.10.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353901/813f0686-7a80-c3e8-5ef2-4653261d60b0.png)



## VNC Viewrを起動したときに「Cannot currently show the dekstop」と表示されるときは…
![スクリーンショット 2022-02-26 19.05.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353901/21bd9418-0857-f0bb-4dc1-0772b3f252fd.png)

ラズベリーパイをHDMIケーブルでモニターに繋いでいないときに、「Cannot currently show the dekstop」と表示され、Mac上から操作ができなくなってしまいました。

### 解決方法

ラズベリーパイにモニターを繋いでターミナルを開くか、Mac上からsshでラズベリーパイに入ります。
今回はssh接続します。
@以下にはipアドレスを入力してください。
```
ssh pi@xx.xx.xx.xx
```

パスワードを入力して、ラズベリーパイに接続できたら以下のコマンドを入力してEnter。
```
sudo nano /boot/config.txt
```

このコマンドを実行すると、設定について書かれたファイルが開くので、その中から「# hdmi_force_hotplug=1」と書かれた部分を探します。
<img width="500" alt=スクリーンショット 2022-02-26 18.50.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1353901/50613c7e-ba87-9bb0-60d4-4dac85b8f0e9.png">

見つけたら先頭の#を削除します。

削除したら以下の操作をして保存して終了。
control + o ⇒ enter ⇒ control + X(commandではなくcontrolなので注意)

最後に「sudo reboot」で再起動をして、リモート接続をしてみましょう。

```
sudo reboot
```
タグ別ビューステートサイズ実験結果

## Visualforceタグ

本記事は[こちら](https://qiita.com/xQIEBo4zFWKZ0ig/items/a990a21a3969dfadb33c)

一部ダークモードでのスクショが混じってますが、ご了承ください🙇‍♂️

### apex:commandButton1個
![1 commandButton1個.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690075/ee29fccd-fe62-3b59-c848-6e0e07acdcd8.png)

### apex:commandButton1000個
![2 commandButton1000個.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690075/713c8dfa-44ed-6892-8e08-1d9707dfb4d1.png)

### apex:actionFunction1000個
![3 actionFunction1000個.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690075/dbdddfbf-6590-2ded-ba0a-e2f7f16460a1.png)

### apex:outputText1000個
![4 outputText1000個.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690075/a82c7e7a-597e-e48d-f744-a2be05be6014.png)

## Apex変数

### public変数1000個（代入あり）
![6 public1000個（代入あり）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690075/0e07e58f-0d5f-7853-731c-1b294d1f7c46.png)

展開すると、こんな感じで各変数のビューステートが保持されていました。
![6 public1000個（代入あり 展開ver）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690075/751ce55d-d67d-dc7d-750d-b3b6857bf3e6.png)

## 標準HTMLタグ

### pタグ1000個
![7 pタグ1000個.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690075/aacf78e4-f58f-fc0f-e758-dd54cff03f04.png)
【暗号化】AES256について個人的メモ

暗号化でよく使うAES256の設定についてまとめておきます。

◇よく使う設定
・暗号利用モード（CBC)
・パディング方式（PKCS#7 Padding）
・共通鍵
・初期化ベクトル

### 暗号利用モード（CBC)
ブロックごとに暗号化するメカニズム。
最初のブロックについては初期化ベクトルを使用して暗号化。
次のブロックからは、前のブロックと該当ブロックをXOR計算した結果を返す

※ブロックとは
AES256だと256バイト＝32文字となるので32文字で1ブロック

### パディング方式（PKCS#7 Padding）
分割する際にブロックを割り切れない場合、穴埋めする

### 共通鍵
AES256の場合、32桁の文字列。

### 初期化ベクトル
16桁固定の文字列
TypeScriptにおける抽象クラス(abstract)不要論?

オブジェクトの型を指定するインターフェースに関してですが、クラスに関しても使えるということで、特に抽象クラスの定義について色々と調べてみました。


## TypeScriptにおけるクラスとは

実はTypeScriptでは、JSよりも前にクラスを備えていました。
特徴として、TypeScriptのクラス構文では2つの異なる側面を併せ持ちます。

### インターフェースとしての型宣言となる
型のコンテキストにおいてはインターフェースとして扱われます。

### コンストラクタ関数(通常のクラスとして)
コンストラクタ関数とかくとややこしいですが**要は普通のクラス構文**として振る舞うということです。JavaScript, TypeScriptではクラスはシンタックスシュガーであり、その実態はプロトタイプオブジェクトを継承してオブジェクトインスタンスを生成するための独立した関数となっています。

## 抽象クラスの定義
クラスが宣言されたとき、インターフェースとしての側面と通常のクラスとしての側面を併せ持つと言いました。よって抽象クラスにも2つの定義の仕方が存在します。
抽象クラスとはそれ自身がインスタンスを生成できず、継承されることを前提としたクラスです。

### abstract修飾子
まずは通常のクラスの扱いとしての見慣れているやり方ですね。抽象クラスをabstract修飾子で定義し、それをextendsによって継承して実装するというものです。

```typescript
abstract class Rectangle {
  sideA: number;
  sideB: number;

  constructor(sideA: number, sideB: number) {
    this.sideA = sideA;
    this.sideB = sideB;
  }

  getArea = (): number => this.sideA * this.sideB;
}

class Square extends Rectangle {
  side: number;
  constructor(side: number) {
    super(side, side);
  }
}
```
ポイント
- 実装の詳細を抽象クラスでかけてしまう
- 継承先で再実装しなくてもエラーにならない

### interface
初めに、クラスを定義したときはそれは型のコンテキストではインターフェースの定義と同等となるという説明をしました。
つまりクラスはinterfaceを継承することができます。
implementsを使用します。

```typescript
interface Shape {
  readonly name: string;
  sideA: number;
  sideB?: number;
  sideC?: number;
  sideD?: number;
  getArea: () => number;
}

class Rectangle implements Shape {
  readonly name = 'rectangle';

  sideA: number;

  sideB: number;

  constructor(sideA: number, sideB: number) {
    this.sideA = sideA;
    this.sideB = sideB;
  }

  getArea = (): number => this.sideA * this.sideB;
}

```

インターフェースはもともとオブジェクトの型定義に使用されるものですがJavaScriptのスーパーセットであるTypeScriptではJavaScript同様にクラスとオブジェクトの間に本質的な区別はないからです。
クラスももとを辿ればオブジェクト。なのでインターフェースで型定義することができ、またそれを継承することができます。

ポイント
- 型だけを定義し、実装漏れを確実に防ぐ
- ？によって柔軟性をもたせることができる
- 実装の詳細を継承元で書かなくて済む

## 抽象クラスの弱点と　interfaceの良さ

abstract修飾子は、実は実装の詳細を含むことができてしまいます。本当は実装すべきメンバの型だけを定義したいのにも関わらずです。これが唯一のabstract修飾子による抽象クラス定義の弱点でしょうか。

DRYでコードを書くことはRubyでも口酸っぱく言われていますが、継承というのは親に強く依存してしまいバグの発見がしづらくなるという理由から「継承よりも合成を使う」という考え方のほうが主流になりつつあるようです。
比較的新しい言語であるGoやRustでは実装を伴った継承がそもそも存在しません。

その点インターフェースでは実装を伴わない型のみの定義が可能であり、抽象クラスの定義として優れています。

## 結論
よほどのことがない限り、クラスの定義はinterfaceを使ったほうが良いのではないのでしょうか。
その「よほどのこと」というのも現時点では私の中では出てきていないので、もしユースケースがあれば教えていただきたいです！

ではでは、キラキラTypeScriptライフをお過ごしください。
MessagingAPIでクイックリプライを使ってみよう！

# はじめに
LINEのMessagingAPIの中にクイックリプライというものがあります。
クイックリプライは、Botのメッセージに対してあらかじめリプライを設定しておくことで、ボタンをタップするだけで簡単に返信ができます。

今回はGAS　＋　MessagingAPIを用いてシンプルなクイックリプライを実装していきます。

https://developers.line.biz/ja/docs/messaging-api/using-quick-reply/#using-quick-reply-introduction

以前に投稿した記事もよかったらぜひ
[MessagingAPI + GASでメッセージ送信（+定期実行設定）](https://qiita.com/sasao3/items/2c9594a0e5d120f8e354)

# 実装

```javascript
const TOKEN = "自分のアクセストークン";
const HEADERS = {
  "Content-Type": "application/json; chrset=UTF-8",
  "Authorization": "Bearer " + TOKEN
}
const LINE_PUSH_ENDPOINT = "https://api.line.me/v2/bot/message/push";

function quickReply() {
  const postData = {
    "to": "USERID", //対象ユーザーのUserId
    "messages": [{
      "type": "text",
      "text": "クイックリプライを使ってみよう！",
      "quickReply": {
        "items": [
          {
            "type": "action",
            "action": {
              "type": "message",
              "label": "クイックリプライボタン1",
              "text": "ボタン1メッセージ"
            }
          },
          {
            "type": "action",
            "action": {
              "type": "message",
              "label": "クイックリプライボタン2",
              "text": "ボタンメッセージ2"
            }
          }
        ]
      }
    }]
  }

  const params = {
    "methods": "POST",
    "headers": HEADERS,
    "payload": JSON.stringify(postData)
  };

  UrlFetchApp.fetch(LINE_PUSH_ENDPOINT, params);
}
```

## メッセージアクション
メッセージアクションは、クイックリプライのボタンがタップされると、`text`プロパティに設定した文字列をユーザーからのメッセージとして送信します。

詳細は以下の公式ドキュメントを見るといいかと思います。

https://developers.line.biz/ja/reference/messaging-api/#message-action

また、画像URLを指定することでリプライボタンの先頭に画像を表示させることもできます。


メッセージアクション以外にも様々なアクションを指定することができます！

 - ポストバックアクション
 - メッセージアクション（今回使用したアクション）
 - URIアクション
 - 日時選択アクション
 - カメラアクション
 - カメラロールアクション
 - 位置情報アクション


# 実行結果
今回の実装例の場合、以下のようになります。

![IMG_1922.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/1340fe47-6204-3649-5b3c-bcd216911324.jpeg)

quickReply()を実行すると、対象のユーザーに「クイックリプライを使ってみよう！」とメッセージが送信され、そのメッセージ下にクイックリプライボタンが表示されます。

このボタンをタップすると、ボタンに設定したメッセージが送信されます。


# 参考
https://developers.line.biz/ja/docs/messaging-api/using-quick-reply/#set-quick-reply-buttons

https://developers.line.biz/ja/reference/messaging-api/#message-common-properties
UnityでAndroidアプリをリリースする下準備

# 本記事のゴール🏁
- UnityでGoogle Play StoreにリリースできるAndroidアプリビルド環境設定を行うことです。

# 環境
- Unity 2020.3.27f1を使用しました。

# 環境準備に参考にした資料
1. https://learn.unity.com/tutorial/publishing-for-android#
    1. 上記のUnity Learnの"Publishing for Android"という記事に従い、Unity用のAndroid設定を行いました。上記ページで使用されているUnityのバージョンが、私が使用しているUnity 2020.3.27f1よりも少々古かったので、所々UIが違いましたが(特にUnityHub)、似たような項目を探して何とかなりました。

## Unity Learnに従って準備→Google Play Store申請時に嵌ったこと
1. Google Play Storeにリリースする際に.aabファイルが必要なので、以下のように"Build App Bundle (Google Play)"のチェックを有効化する必要がありました。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33458/06cff2e7-76af-5fc5-b1d4-9a8fdb16fc30.png)
1. 上記の.aabファイルを申請時に提出したところ、32bitアプリはダメ、といったようなニュアンスのエラーが出て申請がエラーになりました。これは[この記事](https://developer.android.com/distribute/best-practices/develop/64-bit?hl=ja)のように、Androidアプリの64bit対応が必須になっているためで、.aabファイルを64bitビルドする必要があります。<br/>このため、「Build Settings->Player Settings...->Player->Configuration」で行ける、「Scripting Backend」をデフォルトの「Mono」から「IL2CPP」に変更し、「Target Archtectures」に「ARM v7」「ARM64」のみをセットしておく必要がありました。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33458/e9956773-6f7b-6ac4-157f-043730d3d98b.png)
1. 上記の修正を入れた後、新しい.aabファイルをアップロードしようとしても、そのバージョンコードは既に使用されている、といったエラーが出て提出できず、先程のスクショのVersionを変更しても同じエラーが出て困ってしまいました。<br/>解決方法としては、Versionではなく、以下の「Bundle Version Code」を今まで一度も提出していないものにする必要があったということで、これは修正前の.aabファイルを消した場合でも当てはまる、ということでした。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33458/179d3161-473c-48b3-6951-c1419e358c96.png)

### その他
- UnityとAndroidアプリの勉強を最近し始めているので、自分のメモも兼ねてこんな感じの記事を書いていこうと思います。
- 上のスクショでちらっと出ていたPackage Nameで、先日以下のゲームアプリをリリースしました。UnityでAndroidアプリを作ってGoogle Play Storeにリリースするという一連の流れを、出来るだけ早く経験するためにサクッと作っただけのものなので、クオリティはお察し下さい。。。
    - https://play.google.com/store/apps/details?id=com.tokagetechnologies.ballbounce
GitHubアカウントを複数設定するためやったこと

# はじめに
1台のPCで複数のGitHubアカウントを設定するために行なった手順を記載します。

# 手順

### 1.バージョン管理開始
プロジェクト最上位のディレクトリでバージョン管理を開始する。
```
$ git init
```

### 2.リモートリポジトリを設定
SSHの場合
```
$ git remote add origin git@github.com:<サブのGitHubアカウントのユーザー名>/<リポジトリ名>.git
```
HTTPSの場合
```
$ git remote add origin https://github.com/<サブのGitHubアカウントのユーザー名>/<リポジトリ名>.git
```
確認用コマンド
```
$ git remote -v
```

### 3.メインのGitHubアカウントのユーザー名とメールアドレスを登録
```
$ git config --global user.name "<メインのGitHubアカウントのユーザー名>"
$ git config --global user.email <メインのGitHubアカウントのメールアドレス>
```
`~/.gitconfig`を確認する。
```
$ cat ~/.gitconfig
```

### 4.サブのGitHubアカウントのユーザー名とメールアドレスを登録
```
$ git config user.name "<サブのGitHubアカウントのユーザー名>"
$ git config user.email <サブのGitHubアカウントのメールアドレス>
```
`~/・・・/プロジェクトディレクトリ/.git/config`を確認する。
```
$ cat .git/config
```

### 5.指定プロジェクトでGitHubアカウントを自動的に切り替える設定
`~/.gitconfig`を編集する。
```
[includeIf "gitdir: <プロジェクトディレクトリへのパス>"]
path = ~/<ファイル名>
```
私のPCでは下記のように設定した。
```
[user]
	name = <3で設定したユーザー名>
	email = <3で設定したメールアドレス>

[includeIf "gitdir:~/・・・/<プロジェクトディレクトリ>/.git"]
path = ~/config
```
このように編集することで、このリポジトリではサブで使用するGitHubに切り替えることができる。

### 6.アクセストークンを作成
[こちら](https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)を参考に、サブのGitHubアカウントでアクセストークンを作成する。

### 7.設定ファイルにユーザー名とアクセストークンを挿入
`~/・・・/プロジェクトディレクトリ/.git/config`を下記の通りに編集する。
```
[remote "private"]
	url = https://<サブのGitHubのユーザー名>:<6で作成したサブのGitHubのアクセストークン>@github.com/<サブのGitHubのユーザー名>/<リポジトリ名>.git
```

### 8.サブのGitHubのリモートリポジトリにプッシュ
```
$ git add .
$ git commit -m 'first commit'
$ git push origin master
```

# おわりに
`The requested URL returned error: 403`を解消するのに苦労したので、備忘録として記事にまとめてみました。
参考になれば幸いです。

# 参考URL
- [【git】既存のフォルダをgit管理にしてリモートリポジトリと紐づける](https://www.sukerou.com/2019/12/git-tipsgit.html)
- [Gitの「The requested URL returned error: 403」の対処法！](https://qumeru.com/magazine/613)
- [第16話　Gitユーザー名とメールアドレスをリポジトリごとに変更したい　【連載】マンガでわかるGit　～コマンド編～](https://www.r-staffing.co.jp/engineer/entry/20200918_1)
- [別のGithubアカウントのリポジトリにpushしたい remote: Permission to xxx denied to yyy.](https://blog.vtryo.me/entry/different-github-account-push)
- [複数のGitHubアカウントを使い分けたい時の設定方法とTips](https://zenn.dev/taichifukumoto/articles/how-to-use-multiple-github-accounts)
- [突然GitHubにpushできなくなった。The requested URL returned error: 403の解決方法](https://qiita.com/anaqe3/items/018c6fc24c9658ea2250)
SPAでページアクセス時のHTTPヘッダーを取得(Next.js)

今回もNext.js関連です。

もともとReactで開発していましたが、
ページにアクセスしたときのHTTPリクエストヘッダーを取得できなくて、
Next.jsに変更せざるを得なくなったので。

### 環境

Next.jsなどのバージョンはpackage.jsonをそのまま貼り付けておくのでご参考に。

```json:package.json
{
  "dependencies": {
    "next": "12.1.0",
    "nookies": "^2.5.2",
    "react": "17.0.2",
    "react-dom": "17.0.2"
  },
}
```

※今回はHTTPヘッダーを取得したらそれをそのままcookieに保存したかったので、
　「nookies」というライブラリをインストールしています。
https://github.com/maticzav/nookies

### それではやっていきます
_app.jsにgetInitialPropsを記述します。

```jsx:_app.js
import App from 'next/app';
import nookies from 'nookies';

const MyApp = ({ Component, pageProps }) => {
  return (
    <>
      <Component {...pageProps} />
    </>
  );
}

MyApp.getInitialProps = async (appContext) => {
  const appProps = await App.getInitialProps(appContext);
  const { ctx } = appContext;
  const isServer = !!ctx.req;
  if (isServer) {
    console.log(ctx.req.headers.host);
    nookies.set(ctx, 'host', ctx.req.headers.host);
    nookies.set(ctx, 'aaa', ctx.req.headers['aaa']);
  }
  appProps.pageProps = { ...appProps.pageProps };
  return { ...appProps };
}

export default MyApp
```

以上です。(笑)

### ちょっと解説します

まず、getInitialPropsはサーバサイドでもクライアントサイドでも両方動くので注意が必要です。
サーバサイドの場合、appContext.reqが存在するので、
まずはreqを見てサーバサイドかどうかを判定しています。（isServerに入れている）

サーバサイドであれば、req.headersの中の必要なヘッダーを取得できるというわけです。
「Host」の値であれば`ctx.req.headers.host`、
カスタムヘッダー「aaa」の値であれば`ctx.req.headers['aaa']`とします。

上記のコードでは、`nookies.set`でcookieに保持するところまでやっています。
（nookiesの使い方は割愛します）

_app.jsに上記を仕込むことで、どのページからアクセスしても
全画面共通でこの処理をやってくれます！

### さいごに
SSRの時だけ実行したかったので、getServerSidePropsでやろうとしましたが、
うまくいかずに断念しました。
この辺りはまだ勉強中なので、何か分かったらまた更新します。
Google App ScriptをVScode+Typescriptで書く時の環境構築法

作成日：2022年2月26日

# どういう記事か
この記事では、Google App Script(以下GAS)をVScodeとtypescriptで開発をする際の環境構築の手順を示します。なおnpmは既にインストールされており、claspとtypescriptはグローバルでインストール済みの状況で実行するので、上記のインストールに関しての言及はありません。

# 実行環境
```
windows10
npm: 8.3.1
VScode: 1.64.2
```
npmには以下のパッケージがグローバルでインストールされています。
```
google/clasp@2.4.1
typescript@4.5.5
```

# 環境構築
この記事ではデスクトップにtestというフォルダを置き、その中にプロジェクトを作成します。

## step1: npmプロジェクトの作成
`npm init`してpackage.jsonを生成します。色々聞かれるので適当に設定します(この段階でentory pointはindex.tsとかにしておくと後から楽ですね)。後から編集できるので、適当で良い気がします(しらんけど)。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327331/9fa251cf-6378-8a47-dc90-0e7caa3d4684.png)

## step2: app scriptの型情報のインストール
`npm i -S @types/google-apps-script`します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327331/aa5e4489-7160-8b09-5d3a-7c24b4d49aee.png)


## step3: claspでapp scriptのプロジェクトを作成 or clone
今回は新規でapp scriptのプロジェクトを作成します。testディレクトリにて
`clasp create`します。どのタイプのスクリプを作成するのか聞かれるので、今回は`sheets`を選びました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327331/1934135b-6448-548f-06bd-d38d7c4fd35e.png)

cloneするは`clasp clone <project ID>`で、`appscript.json`と関連するコードが引っ張ってこられるので同じファイル構成になると思います。

## step4: スクリプトの作成
`index.ts`をtestディレクトリに作成し、package.jsonのentory pointをindex.tsに変えておきます。
ここでは適当に以下のようなものを入れておきます。

```index.ts
function greet() {
  Logger.log("hello world");
}
```

### VScodeの自動補完について
この段階で自動補完が効くこともあれば、効かないこともあります。詳しいところまでは調べていませんが、VScodeが開いているフォルダがpackage.jsonのルートディレクトリでない場合、出ないのかなと思っています。
プロジェクトのルートディレクトリでVScodeを開きたくない場合、package.jsonと同じフォルダにjsconfig.jsonを作成し、以下の内容を記述することで、自動補完が効くことがあります。jsconfig.jsonを作成しても自動補完が効かなかったり、jsconfig.jsonの方にエラーが出る場合、VScodeを再起動するとエラーが治ることがありました。`target`等はお好みで変更してください。

```jsconfig.json
{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es2020",
    "jsx": "preserve",
    "strictFunctionTypes": true
  },
  "include": [
    "node_modules/@types/google-apps-script"
  ]
}

```
jsconfig.jsonに関して詳しくは以下を参照してください。

https://code.visualstudio.com/docs/languages/jsconfig

## step5: コードのpush
現在のファイル構成はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327331/25e2256d-8d7d-5c07-87cc-c05170790fc9.png)

ここで`clasp push`すると、`appscript.json`と`index.ts`をapp script側に送ってくれて、実行することが出来るようになります。`index.ts`はこの時にトランスパイルされます。


以上です。
【Scala】TreeSetに格納した値をindex指定で取り出す

## 概要
TreeSetは[【Java】TreeSetの特徴を分かりやすく解説します。](https://www.tairax.com/entry/study/Java/TreeSet)の記事で紹介されている通り、要素の重複を排除し、要素が自動で整列されるコレクションオブジェクトです。値を追加の度にソートしてくれるので、ソート処理を書かなくてよく便利なのですが、TreeSetからは直接index指定で値を取り出すことができないようです。
今回はこのTreeSetを元に、index指定でどうやって値を取り出すか記事を書いてみます。

## 対応方法
[Java Program to Get the TreeSet Element By Index](https://www.geeksforgeeks.org/java-program-to-get-the-treeset-element-by-index/)の記事にある通り、色々やりようはあるのですが、個人的には「Method 2: Using .toArray() Method」にある配列に変換する方法が、シンプルかなと感じました。一度配列に格納した上で、index指定で値を取り出します。


## 実装サンプル
Javaでは上記の記事にあるような実装でいけますが、ここではScalaで配列に変換する実装サンプルを紹介します。実装のやり方はJavaとほぼ同じですね。

```scala
import scala.collection.immutable.TreeSet

object TreeSetToArray extends App {
  // 降順に設定する
  val ordering = Ordering[Int].reverse
  val sampleTreeSet = TreeSet(3, 4, 1, 2)(ordering)
  // 4, 3, 2, 1の順になる
  println(sampleTreeSet)

  // 配列に変換
  val sampleArray = sampleTreeSet.toArray
  // index1を指定した場合は「3」が返る
  println(sampleArray(1))

}

```
M1 Macにtensorflowをinstallする

# 目的

m1搭載MacBookにいつも通りtensorflowを導入しようとしたらエラーになったので導入手順を忘れないようにメモ.
cpuがm1チップだからだと思うけど、だとするとどうしようもないので諦めていたらappleがちゃんとinstallできるパッケージを配布していた。さすが。

レポジトリにymlファイル等をまとめたので[レポジトリ](https://github.com/yushikmr/m1mac_tensorflow)をcloneしてください。

# M1チップ用のtensorflow

[Appleが作ってるmacos用のtensorflow](https://github.com/apple/tensorflow_macos)レポジトリにパッケージがある。リリースの欄をクリックしてassetにあるパッケージファイルを使用する。

# 構築手順

## 事前準備

anacondaとかminicondaとかをinstallしてcondaコマンドが使用できる状態にしておいてください

`git clone git@github.com:yushikmr/m1mac_tensorflow.git`でinstall用のレポジトリをinstallしてください

## tensorflow導入

レポジトリ内で以下のコマンドを実行

`conda env create -f enviroment.yml`

上記のymlファイルには

- tensorflow
- jupyter lab
が入っています。想定するpython versionは3.8です。

続いて

`conda activate m1mac_tensorflow`

でconda環境を有効にしてください

### m1用tensorflowの導入

以下のコマンドを実行してください
`pip install --upgrade --force --no-dependencies https://github.com/apple/tensorflow_macos/releases/download/v0.1alpha3/tensorflow_addons_macos-0.1a3-cp38-cp38-macosx_11_0_arm64.whl https://github.com/apple/tensorflow_macos/releases/download/v0.1alpha3/tensorflow_macos-0.1a3-cp38-cp38-macosx_11_0_arm64.whl`

`pip install --upgrade --force --no-dependencies`

で後続するurlにあるファイルのソースファイルからパッケージをインストールできます。m1用のtensorflowパッケージは現時点(2022/02/26)では
`https://github.com/apple/tensorflow_macos/releases/download/v0.1alpha3/tensorflow_addons_macos-0.1a3-cp38-cp38-macosx_11_0_arm64.whl`が使用できます。

最新のバージョンはここを確認してください [guthubレポジトリ](https://github.com/apple/tensorflow_macos)

## jupyterで作成した仮想環境を実行できるようにする

以下のコマンドで作成した仮想環境をjupyter kernelに追加してください
`ipython kernel install --user --name=m1mac_tensorflow --display-name=m1mac_tensorflow`

## 環境の起動をtensorflowの使用

`jupyter lab`でjupyterlabを起動し、sample.ipynbを開いてください

select kernelでm1mac_tensorflowを選択すれば
`import tensirflow as tf`が実行できます。
Laravel+React環境でホットリロード

# 経緯
Laravel+React環境にてsrcを修正するたびにランデブするのがリズムに乗れないと思っていた中、
たまたま見つけたのでもう少しわかりやすいタイトルで記載しなおします。

# やり方
新しいターミナルを開き、以下コマンドを打つ。


~~~:コマンド
npm run watch
~~~

src修正する度に反応してくれます。もちろんビルドエラーも出ます。

# 感想
Laravel+React環境でホットリロードで検索してもさらっと答え出ないんですよね。
[Flutter/Android]「uses-sdk:minSdkVersion XX cannot be smaller than version YY declared in library」のエラー解消

# 環境
Windows 10 Home
Flutter 2.10.2
Dart 2.16.1
Android Studio 4.0.1

# エラー内容
Androidのエミュレータにてビルド時に下記のエラーが発生。

>uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library

「SDKのバージョン19以上じゃないとだめなので(今は16)、`minSdkVersion`を上げてね」ということでした。

# 解決方法
`android/app/build.gradle`の`defalutConfig`の中に、`minSdkVersion`を指定できるのでそこを変更しましょう。

```gradle:android/app/build.gradle｜変更前
    defaultConfig {
        // ...略
        minSdkVersion 16
        // ...略
    }
```

```gradle:android/app/build.gradle｜変更後
    defaultConfig {
        // ...略
        minSdkVersion 19
        // ...略
    }
```

変更前の段階で`minSdkVersion flutter.minSdkVersion`と入っている場合も気にせず数値指定でOKです。
今回は変更後のminSdkVersionを19としましたが、自分のエラーに合わせて最適なminSdkVersionを指定すればOKです。