OmniAICreator/Qiita-1.07M huggingface dataset:
ATtiny1616 と ATtiny1617実験ボードのピンアサイン

### ATtiny1616 Board(AYA065-1)ピンアサイン
![スクリーンショット 2020-08-14 10.19.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/1eb355cb-eeea-89b2-8519-6b066d7d1157.png)

### ArduinoにおけるATtiny1616のポート情報
![スクリーンショット 2020-08-14 10.21.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/94182fa5-3c3e-06f7-0602-68f38f4581a1.png)

### ATtiny1616 Board サンプルスケッチ
Board上のPA7に接続されたLEDを点灯させます。

```c++
//　Port名で設定
void setup() {
  pinMode(PIN_PA7, OUTPUT);  
  digitalWrite(PIN_PA7,LOW);
  digitalWrite(PIN_PA7,HIGH);
}
void loop() {
}
```
```c++
// ArduinoPin番号で設定
void setup() {
  pinMode(3, OUTPUT);  
  digitalWrite(3,LOW);
  digitalWrite(3,HIGH);
}
void loop() {
}
```
```c++
// PORTマクロで設定
#define PA7 7
#define LED (1<<PA7)

void setup() {
  PORTA.DIR = PORTA.DIR | LED; 
  PORTA.OUT = PORTA.OUT & ~LED;  
  PORTA.OUT = PORTA.OUT | LED;
}  
void loop() {
}
```


### ATtiny1617 Board(AYA066-1)ピンアサイン
![スクリーンショット 2020-08-14 10.20.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/e9b5b841-0b1b-b0ae-7acc-c8fba16e59e2.png)

### ArduinoにおけるATtiny1616のポート情報
![スクリーンショット 2020-08-14 10.22.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/00f6cba6-8524-5781-9116-691e74a6b30d.png)

### ATtiny1617 Board サンプルスケッチ
Board上のPA7に接続されたLEDを点灯させます。

```c++
//　Port名で設定
void setup() {
  pinMode(PIN_PA7, OUTPUT);  
  digitalWrite(PIN_PA7,LOW);
  digitalWrite(PIN_PA7,HIGH);
}
void loop() {
}
```
```c++
// ArduinoPin番号で設定
void setup() {
  pinMode(3, OUTPUT);  
  digitalWrite(3,LOW);
  digitalWrite(3,HIGH);
}
void loop() {
}
```
```c++
// PORTマクロで設定
#define PA7 7
#define LED (1<<PA7)

void setup() {
  PORTA.DIR = PORTA.DIR | LED; 
  PORTA.OUT = PORTA.OUT & ~LED;  
  PORTA.OUT = PORTA.OUT | LED;
}  
void loop() {
}
```
PulumiでGoogle Cloud FunctionsにTypeScriptの関数をデプロイする方法

Pulumiはインフラ構成をTypeScriptなどのプログラミング言語で定義でき、AWSやGoogle Cloud Platformへのデプロイを自動化できるツールです。この投稿では、Google Cloud FunctionsにTypeScript製の関数をデプロイする際に、Pulumiを使う方法を紹介します。

## Pulumiはインフラとアプリを一体化できるのが特徴的

Terraformなどのインフラ構成管理ツールで、Google Cloud Functionsに関数をデプロイする場合、インフラ構成の定義と、Functionsなどのアプリケーションコードは別々のファイルになるのが普通です。

Pulumiは一風変わっていて、インフラ構成と関数をひとつのファイルに書くことができるのが特徴的です。インフラ構成をTypeScriptで定義して、Cloud FunctionsもTypeScriptで実装すると、インフラとアプリを一体化したシームレスなコードにできます。

## PulumiでCloud Functionsをお手軽にデプロイする

PulumiでCloud Functionsをデプロイする最も手軽な方法は、インフラ構成定義に関数の実装も混ぜて書くパターンです。そのパターンでは、次のようなコードになります:

```index.ts
import * as gcp from "@pulumi/gcp";

// Cloud Functions APIを有効化する
const cloudFunctionsService = new gcp.projects.Service(
  "cloudFunctionsService",
  {
    disableDependentServices: true,
    service: "cloudfunctions.googleapis.com",
  }
);

// デプロイする関数のアプリケーションコード
const helloWorld: gcp.cloudfunctions.HttpCallback = (req, res) => {
  res.send("Hello World!");
};

// デプロイする関数のインフラ構成定義
const helloWorldFunction = new gcp.cloudfunctions.HttpCallbackFunction(
  "helloWorldFunction",
  {
    runtime: "nodejs12",
    callback: helloWorld,
  },
  { dependsOn: cloudFunctionsService }
);

// デプロイ後に表示する情報
export const functionUrl = helloWorldFunction.httpsTriggerUrl;
```

抜粋して説明すると、次の`helloWorld`という変数に代入した部分がアプリケーションコード、つまり関数の実装になります:

```ts
const helloWorld: gcp.cloudfunctions.HttpCallback = (req, res) => {
  res.send("Hello World!");
};
```

次に、`helloWorldFunction`がインフラの構成定義になります。

```ts
const helloWorldFunction = new gcp.cloudfunctions.HttpCallbackFunction(
  "helloWorldFunction",
  {
    runtime: "nodejs12",
    callback: helloWorld,
  },
  {/*...*/}
);
```

ここで注目したいのが、上で定義したアプリケーションコードの`helloWorld`をそのまま代入できているところです。これが、Pulumiの最大の特徴で、インフラとアプリを一体化できるところです。

この構成で`pulumi up`し、デプロイすると、関数のURLが発行されるので、すぐに関数を利用できます。

```bash
$ curl https://asia-northeast1-${PROJECT}.cloudfunctions.net/helloWorldFunction-af3d854
Hello World!
```

## まとめ

Pulumiを使うと、TypeScriptでインフラ構成を定義しながら、Cloud Functionsの実装もそれに埋め込むかたちでデプロイすることができます。インフラとアプリを一体化できるので、よりシームレスな運用ができるようになるのが特徴です。Terraformと比べると、インフラ構成管理のために別の言語を覚える必要がありません。

加えて、TypeScriptエコシステムの恩恵を享受できるメリットもあります。IDEではコード補完が効き、デプロイ前には型による静的チェックができたりと、アプリ開発と似たような開発体験が得られます。

PulumiはTypeScriptプログラマがインフラを扱うシーンに相性のいいツールになると思います。

---

最後までお読みくださりありがとうございました。Twitterでは、Qiitaに書かない技術ネタなどもツイートしているので、よかったらフォローしてもらえると嬉しいです:relieved:→[Twitter@suin](https://twitter.com/suin)
下請法で禁止されること

平成31年春期 午前問題79

ソフトウェア開発を下請事業者に委託する場合，下請代金支払遅延等防止法に照らして，禁止されている行為はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/1ba5d1c6-7866-fd54-df5d-8cd3947e4679.png)


下請代金支払遅延等防止法(下請法)は、事業者による下請け業者に対する優越的地位の乱用行為を取りしまるために制定された法律です。
法律には「下請け代金の支払い確保」のほかにも親事業者の遵守事項などが条文化されており、親事業者の下請事業者に対する取引を公正に行わせることで、下請け業者の利益を保護することを目的としています。

この他にも以下のような行為が下請法で禁止されています。
1.受領拒否
下請事業者に対して委託した給付の目的物について，下請事業者が納入してきた場合，親事業者は下請事業者に責任がないのに受領を拒む行為

2.下請代金の支払遅延
物品等を受領した日（役務提供委託の場合は，役務が提供された日）から起算して**60日以内**に定めた支払期日までに下請代金を全額支払わない行為

3.下請代金の減額
発注時に決定した下請代金を「下請事業者の責に帰すべき理由」がないにもかかわらず発注後に減額する行為

4.返品
下請事業者から納入された物品等を受領した後に，その物品等に瑕疵があるなど明らかに下請事業者に責任がある場合において，受領後速やかに不良品を返品するのは問題ありませんが，それ以外の場合に受領後に返品する行為

5.買いたたき
発注に際して下請代金の額を決定するときに，発注した内容と同種又は類似の給付の内容（又は役務の提供）に対して通常支払われる対価に比べて著しく低い額を不当に定める行為

6.購入・利用強制
下請事業者に注文した給付の内容を維持するためなどの正当な理由がないのに，親事業者の指定する製品（自社製品を含む）・原材料等を強制的に下請事業者に購入させたり，サービス等を強制的に下請事業者に利用させて対価を支払わせたりする行為

7.報復措置
下請事業者が親事業者の下請法違反行為を公正取引委員会又は中小企業庁に知らせたことを理由として，その下請事業者に対して取引数量を減じたり，取引を停止したり，その他不利益な取扱いをする行為

8.有償支給原材料等の対価の早期決済
下請事業者の給付に必要な半製品，部品，付属品又は原材料を有償で支給している場合に，下請事業者の責任に帰すべき理由がないのにこの有償支給原材料等を用いて製造又は修理した物品の下請代金の支払期日より早い時期に当該原材料等の対価を下請事業者に支払わせたり下請代金から控除（相殺）したりする行為

9.割引困難な手形の交付
下請事業者に対し下請代金を手形で支払う場合，支払期日までに一般の金融機関で割り引くことが困難な手形を交付する行為

10.不当な経済上の利益の提供要請
下請事業者に対して，自己のために金銭，役務その他の経済上の利益を提供させることにより，下請事業者の利益を不当に害する行為

11.不当な給付内容の変更及び不当なやり直し
下請事業者に責任がないのに，発注の取消若しくは発注内容の変更を行い，又は受領後にやり直しをさせることにより，下請事業者の利益を不当に害する行為


基本は、下請け業者の責任ではないと、代金支払い遅延は許せんませんとのことですね。

下請け業者の責とは、
１、要員不足が原因で開発が遅れている
２、ソフトウェアに不具合がある
３、開発途上で発生した仕様変更の内容，対価などを下請業者と合意していたが，受領したプログラムには仕様変更が反映されていなかった
４、一般にソフトウェアの瑕疵担保責任期間は商法第525条に記されている6カ月～民法637条の1年程度である以内に、バグ発見した。
５、など。

下請け業者の責ではないの例とは、
１、親事業者と顧客との間の委託内容が変更になる
２、親事業者がソフトウェアの仕様を変更したい
３、など



参照：

下請代金支払遅延等防止法ー違法となる行為
https://qiita.com/lymansouka2017/items/21a742ad4d1ba2d8049c

https://www.pm-siken.com/kakomon/26_haru/am2_22.html

下請法　親事業者の禁止行為
http://www.jftc.go.jp/shitauke/shitaukegaiyo/oyakinsi.html
LaravelでQiita APIを使用し投稿した記事を取得してみた

##目的
Qiitaから投稿記事のタイトルとURL、投稿日の取得。(下記サイトのように使用しました。)
http://kudohayatoblog.com/blog_top

##アクセストークンの取得
下記ページで「新しくトークンを発行する」からトークンを発行。
https://qiita.com/settings/applications
※今回は書き込みをしないので、「read_qiita」を選択。

##API通信
今回はcURLを使用した方法と、GuzzleHttpを使用した方法を紹介します。
###cURLでの通信
```
$token = '取得したアクセストークン';
$curl = curl_init('https://qiita.com/api/v2/authenticated_user/items?page=1&per_page=10');
   $option = [
       CURLOPT_CUSTOMREQUEST => 'GET',
       CURLOPT_RETURNTRANSFER => true,
       CURLOPT_HTTPHEADER => [
                'Authorization: Bearer '.$token,
                'Content-Type: application/json',
            ],
        ];
curl_setopt_array($curl, $option);
$result = curl_exec($curl);
$decode_res = json_decode($response_body);
```
↑で取得できたので、後はforeachなどで取得できます。

```
foreach ($decode_res as $res_data) {
     $url = $res_data->url;  //urlの取得例
}
```

###GuzzleHttpでの通信
下記コマンドでGuzzleのインストール。

```
composer require guzzlehttp/guzzle
```

```
use GuzzleHttp\Client;

$client = new Client;
$token = '取得したアクセストークン';
$result = $client->request('GET', 'https://qiita.com/api/v2/authenticated_user/items?page=1&per_page=10', [
    'headers' => [
        'Authorization' => 'Bearer '.$token,
        'Accept' => 'application/json',
    ],
]);
$response_body = (string) $result->getBody();
$decode_res = json_decode($response_body);
```

先ほどと同様foreachなどで取得できます。

```
foreach ($decode_res as $res_data) {
     $url = $res_data->url;  //urlの取得例
}
```

###最後に
API認証について、Laravelの公式ドキュメントでは以下のように記載されていますが、ここの$clientが何なのかよくわからなかったのでGuzzleを使用しました。
わかる人がいれば教えてください！

```
$response = $client->request('POST', '/api/user', [
    'headers' => [
        'Authorization' => 'Bearer '.$token,
        'Accept' => 'application/json',
    ],
]);
```
モバイルっぽいハンバーガー・メニューのテンプレ


# はじめに

モバイルっぽいハンバーガー・メニューのテンプレ（HTML/CSS/JS）を作ってみた

# スクリーンショット

![mobile-app-template](https://user-images.githubusercontent.com/4873581/90200050-6cd61080-de11-11ea-91a3-2a3005da9074.gif)

# コード

- [GitHub](https://github.com/narutaro/mobile-app-template) 
- [Codepen](https://codepen.io/narutaro-the-reactor/pen/OJNMmzw)

## メモ

- ハンバーガーメニューを引き出す → メイン画面の幅が短くなる → テキストがあると、めっちゃ折り返す → かっこわるい → **メイン画面もスライドさせた**

```javascript:メニューに合わせてメイン画面もスライド
function openNav() {
  document.getElementById("mySidenav").style.width = "180px";
  document.getElementById("main").style.left = "180px"; 　// ここ
  document.body.style.backgroundColor = "rgba(0,0,0,0.4)";
}
```

- 初回のハンバーガーメニュークリック →　ハンバーガーメニューを引き出すときのアニメーションに `0.3s` の `delay` があるが、その間にメイン画面がだけが先に動いてしまう（スライドのアニメーションをしない）[^1] → メニューの `0.3s` 遅れの間、背景の白が見えてしまう → かっこわるい → **アニメーション前の初期値を入れて解決**

```css
#main {
  position: relative;
  transition: 0.3s;
  left: 0; /* ここ */
}
```

[^1]: [CSSのtransitionがうごかなかった失敗談](http://m77.hatenablog.com/entry/2016/07/14/005532) の内容でした。ありがとうございます

# 学び

- これくらいであれば、CSSフレームワークを使わない方が良い（Flexboxすらわかっていない初心者がリッチなフレームワークを下手に使うとかえって時間がかかる）
- 初心者がこういうのを作ろうとしたときに、そもそも名前がわからないのでサンプルコードをググることすらできない。今回のようなメニューを `Drawer Menu` `Off Canvas Menu` というらしく、これでググるとよい


# お世話になったサイト

- [How TO - Off-Canvas Menu](https://www.w3schools.com/howto/howto_js_off-canvas.asp) → 今回のベースはこれ
- [flexboxを使ってheaderメニューを作る【学習メモ】](https://qiita.com/bp_pk/items/5f8352abcc4b261d04d0)
- [【CSS】Flexboxで実装する、実践的なヘッダーのレイアウト3つ](https://www.ameamelog.com/css-flex-header/)
- [ヘッダーでよく見るレイアウトの作り方（Flexboxとmargin:autoを使用）](https://taneppa.net/flex_header_auto/)
- [【考え方】flexboxを使用したヘッダーの記述について
](https://teratail.com/questions/175859)

# 今後

- モバイルのWebアプリつくる
- テンプレはもう少し汎用性を高める
- `Overscroll.js` あたり盛り込みたい
dictの欠損キー対処の4つの方法


[Effective Python 第2版――Pythonプログラムを改良する90項目](https://www.oreilly.co.jp/books/9784873119175/) が本当にすばらしいので泣きながら読み進めています。

その中に、dictの欠損キーに対する対処方法の項目があったため、詳細内容は本書を読んで頂きたいのですが、それぞれの処理時間が気になったため計測しました。


今回はかなり簡単ですが、ある文字列の出現文字をカウントする処理を書きます。
実行環境はGoogle Colabのデフォルトです。


まず必要なライブラリをインポートします。

```python
import time, defaultdict
```

適当な文字列を集計用の対象にします。

```python
target = 'super_string_of_my_passages. but this does not make sense at all. because this is nothing'
```

なお最後に、出現数でsortしたkey-valueを出力しており、想定される結果は以下です。

```
[('s', 13),
 (' ', 12),
 ('e', 8),
 ('t', 7),
 ('a', 6),
 ('i', 5),
 ('n', 5),
 ('_', 4),
 ('o', 4),
 ('u', 3),
 ('g', 3),
 ('h', 3),
 ('p', 2),
 ('r', 2),
 ('m', 2),
 ('.', 2),
 ('b', 2),
 ('l', 2),
 ('f', 1),
 ('y', 1),
 ('d', 1),
 ('k', 1),
 ('c', 1)]
```

## if文でinを使った場合
if文でキーが存在するかチェックし、Trueを返すin式を使うことで欠損キーに初期値を与える。おそらく最初に考えつくシンプルな方法。

```python
%%time
ranking = {}
for key in target:
    if key in ranking.keys():
        count = ranking[key]
    else:
        count = 0
    ranking[key] = count + 1
sorted(ranking.items(), key=lambda x: x[1], reverse=True)
```
`CPU times: user 45 µs, sys: 9 µs, total: 54 µs
Wall time: 56.3 µs`



## try文でKeyErrorを使った場合
try-except文を使って、エラーの原因であるKeyErrorを想定されるエラーとしてハンドリングする。

```python
%%time
ranking = {}
for key in target:
    try:
        count = ranking[key]
    except KeyError:
        count = 0
    ranking[key] = count + 1
sorted(ranking.items(), key=lambda x: x[1], reverse=True)   
```
`
CPU times: user 59 µs, sys: 11 µs, total: 70 µs
Wall time: 78.2 µs
`

## getメソッドを使った場合
組み込み型dictに用意されているgetメソッドを使う。

```python
%%time
ranking = {}
for key in target:
    count = ranking.get(key, 0)
    ranking[key] = count + 1
sorted(ranking.items(), key=lambda x: x[1], reverse=True)   
```

`CPU times: user 43 µs, sys: 8 µs, total: 51 µs
Wall time: 53.6 µs`

## defaultdictを使った場合
```python
%%time
ranking = defaultdict(int)

for s in target:
    ranking[s] += 1
sorted(ranking.items(), key=lambda x: x[1], reverse=True)
```
`CPU times: user 36 µs, sys: 8 µs,　total: 44 µs　
 Wall time: 47.2 µs`


## 結論
defaultdictがイイかも！(*^^)
*defaultdictは万能ではなく想定しないエラーの原因にもなり得るため注意して使う。
参考: (http://yoshidabenjiro.hatenablog.com/entry/2017/09/05/012828)

## 番外編
本書で扱われてる手法は以上ですが、
おいおいこんな処理ならあいつを使ってもええがな！忘れてまへんか〜？
と突っ込まれそうなので番外編として記します。
このような単純なケースではcollectionsライブラリのCounterクラスを使ってもいいと思います。
各要素における出現回数をカウントしてくれる便利なものです。
なお個数順にsortしてくれるmost_commonメソッドが用意されているのでそれを使います。

```python
from collections import Counter

%%time
ranking = Counter(target)
ranking.most_common()
```

`CPU times: user 53 µs, sys: 0 ns, total: 53 µs
Wall time: 56.5 µs`



ありがとうございました！
JetsonNanoでdlibがインストールできないとき

# はじめに
JetsonNanoを使って画像認識をするべく, [face_recognition](https://github.com/ageitgey/face_recognition)をインストールしていたところ, その依存モジュールのdlibがなかなかJetsonNanoに入らなかったため, その備忘録を書いておく.

# やったこと
<!-- wp:paragraph -->
<p>現在, NvidiaのCUDAライブラリに<a href="https://forums.developer.nvidia.com/t/issues-with-dlib-library/72600/16" target="_blank" rel="noreferrer noopener">バグ</a>があり, dlibに少し手を加えてからインストールする必要があります.</p>
<!-- /wp:paragraph -->

<!-- wp:luxe-blocks/syntaxhighlighter -->
<pre class="wp-block-luxe-blocks-syntaxhighlighter"><code>#dlibのソースを取得
wget http://dlib.net/files/dlib-19.17.tar.bz2 
tar jxvf dlib-19.17.tar.bz2
cd dlib-19.17

#バグ対策のための編集
sudo gedit dlib/cuda/cudnn_dlibapi.cpp</code></pre>
<!-- /wp:luxe-blocks/syntaxhighlighter -->

<!-- wp:paragraph -->
<p>forward_algo = forward_best_algo;を検索後, コメントアウトしてください.</p>
<!-- /wp:paragraph -->

<!-- wp:luxe-blocks/syntaxhighlighter -->
<pre class="wp-block-luxe-blocks-syntaxhighlighter"><code>//forward_algo = forward_best_algo;</code></pre>
<!-- /wp:luxe-blocks/syntaxhighlighter -->

<!-- wp:paragraph -->
<p>上記の変更を保存後, 以下を実行.</p>
<!-- /wp:paragraph -->

<!-- wp:luxe-blocks/syntaxhighlighter -->
<pre class="wp-block-luxe-blocks-syntaxhighlighter"><code>sudo python3 setup.py install</code></pre>
<!-- /wp:luxe-blocks/syntaxhighlighter -->

<!-- wp:paragraph -->
<p>これでdlibが正常にインストールされます.</p>
<!-- /wp:paragraph -->
Visual Studio Code codeコマンドが存在しないと言われる (パス通し)

# 目的

- codeコマンドが存在しないと言われ他の方の解決策では解決しなかったので独自？の方法をまとめる

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| Visual Studio Codeバージョン | 1.47.3 | こちらの方法で導入→[Mac Visual Studio Code 導入方法 VSCode ダウンロードから日本語化対応まで～画像付き導入解説～](https://qiita.com/miriwo/items/4ed96b54b4421fe9d275) |

# 前提情報

- 下記で紹介しているプラグインを用いて開いたVisual Studio Codeのターミナルにて`$ code`コマンドが存在しないとされた。
    - [Visual Studio Code プラグインを使ってssh接続先のファイルを接続元のウインドウで開く](https://qiita.com/drafts/602f7f90c7e66d2e318a/edit)
- Remote Developmentを用いたssh接続先でcodeコマンドが使えなかった問題の解決策を記載する。
- ssh接続先はAWS EC2 AmazonLinux2インスタンスである。

# 問題までの経緯

1. Visual Studio Codeで開きたいファイルをVisual Studio Codeのターミナルから下記コマンドで開こうとした。

    ```terminal
    $ code ファイル名
    ```

# 問題

1. 下記のエラーが発生し`$ code`コマンドでファイルを開くことができない。

    ```terminal
    bash: code: command not found
    ```

# 問題解決までの経緯

1. 下記の方法を用いて`$ code`コマンドを使用できる様にしたが相変わらず「bash: code: command not found」のエラーが出る。
    - [bash: code: command not foundと言うエラーが出た話](https://qiita.com/miriwo/items/793ac37650bbaccb192d)
1. 何度実施しても前述の方法では解決しない。ssh接続先の再起動、ssh接続元の再起動なども実施した。
1. コマンドパスを.bash_profileに記載することにした。
1. codeコマンドが格納されている場所を探す。ssh接続先にそれらしいパスを発見した。コマンドまでのフルパスを下記に記載する。

    ```terminal
    /home/ec2-user/.vscode-server/bin/91899dcef7b8110878ea59626991a18c8a6a1b3e/bin/code
    ```
1. 下記コマンドを実行してファイルが開くことができるか確認し、目測通りtest.txtをVisual Studio Codeのウインドウで開くことができた。

    ```terminal
    $ /home/ec2-user/.vscode-server/bin/91899dcef7b8110878ea59626991a18c8a6a1b3e/bin/code ~/test.txt
    ```
1. コマンドが格納されているフルパスがわかったので.bash_profileに情報を記載しパスを通す。
1. 下記コマンドを実行して.bash_profileのバックアップを用意する。

    ```terminal
    $ cp ~/.bash_profile ~/.bash_profile_org
    ```
1. 下記コマンドを実行して.bash_profileを開く。

    ```terminal
    $ vi ~/.bash_profile
    ```
1. 下記の内容を追記する。

    ```.bash_profile
    export PATH=$PATH:/home/ec2-user/.vscode-server/bin/91899dcef7b8110878ea59626991a18c8a6a1b3e/bin
    ```
1. 下記コマンドを実行して.bash_profileを読み込む。

    ```terminal
    $ source ~/.bash_profile
    ```
1. 下記コマンドを実行して`$ code`コマンドが使える様になったのか確認する。

    ```terminal
    $ code 開きたいファイル名
    ```

# 補足情報

- 本方法はプラグインを用いたssh接続先で`$ code`コマンドが使用できない問題に関しての記事である。
- MacなどでもVisual Studio Codeのシステムファイル内のbinディレクトリ直下のcodeコマンドまでのパスを.bash_profileに記載してあげることで`$ code`コマンドまでパスを通すことは可能である。
- Visual Studio Codeのウインドウ上からの`$ code`コマンドのアクティベートに失敗する場合は一度試してみるといいのかもしれない。
AmazonのAWS , EC2とは？未経験者が解説します。

**AWS（ Amazon Web Services ）**  
AWSとはAmazon Web Servicesの略で、Amazonが提供している100以上のクラウドコンピューティングサービスの総称です。

他には  
_Microsoft Azure（アジュール）_  
_Google Cloud Platform（GCP）_

この３社が超大規模クラウドベンダーとしてグループを構成しているのが現状です。

>**そもそもクラウドコンピューティングとは？**  
_インターネット上のサーバーにあるコンピューターが提供している機能を、インターネット経由で利用する仕組みのことを指します。わかりやすく言うと、「インターネット上でアプリケーション込みでも利用できるサービス」のことです。GmailやYahoo！メールなどを例に挙げると、イメージしやすいかもしれません。
通常は、ローカル環境にあるコンピューター（PC）内にさまざまなアプリケーションをインストールして利用します。会社で使用するPCであれば、WordやExcel、Outlookといったアプリケーションがインストールされている状態です。
一方で、クラウドコンピューティング形態で提供するサービス（以下クラウドサービス）の場合は、自身のPCにアプリケーションをインストールする必要はありません。インターネットに接続できる環境があれば、サーバー上で提供している機能やサービスを利用することができます。会社のPCからでも、自宅でスマホからでも、同一のデータにアクセスでき、同一のサービスを利用できることが特長です。
ちなみに、クラウドとは「雲」のことです。インターネットを図式化する際に雲の図柄で表すことから、インターネット上の環境のことをクラウドと呼んでいます。さらに、クラウドコンピューティングという言葉が普及したことで、今まで使っていたローカルのサーバー環境は「オンプレミス」と呼称されるようになりました。（クラウド実践チャンネル内の記事より引用　https://www.cloud-for-all.com/ ）_


## EC2とは？
Amazonが提供している仮想サーバー構築サービスです。EC2を利用することで、OSを乗せた仮想環境をクラウド上にすばやく作ることができます。 

## インスタンスとは
Amazon EC2の中心となる仮想サーバーです。
インスタンスはインスタンスタイプと呼ばれるOSやCPU、メモリ、ストレージなどの構成から選んで作成します。
インスタンスは管理コンソールで起動や停止、セキュリティ等各種設定などを行います。
インスタンスは複数作成して実行することもできます。
例えば、アプリケーションサーバーとデータベースサーバーなど、合計で2つのサーバーが必要な場合は、インスタンスを2つ作成して対応できます。 必要に応じて複数のインスタンスを立ち上げることで、柔軟なインフラ構築ができるのがAmazon EC2の強みです。


## EC2の優れているところ

#### 構築にかかる時間が短縮できる
EC2を利用する利点は、とにかくシステム構築にかかる時間が短いという点です。
サーバーを購入する場合は購入してから受け取るまでの間、何も作業が進められません。一方で、AWSのEC2上でインスタンスを立ち上げるには、ほんの数分あれば事足ります。

#### 冗長化が簡単にできる
冗長化する手間がかからないのも、魅力的なポイントです。 サーバーをローカルで作成する場合、サーバーの設定だけではなくネットワーク設計も必要になります。AWS EC2では、ネットワークを仮想ネットワーク構築するサービスが提供されており、インスタンスと組み合わせることで、簡単かつ短時間でサーバーの冗長化が実現できます。

>**冗長化とは？**  
_「冗長」とは元々、文章表現などが長たらしくむだのある“望ましくない”状態を指す言葉ですが、ITの世界ではまったく反対に“望ましい”状態を指す表現となります。ITシステムにおける冗長化は、ハードウェアの二重化（多重化）を意味します。一番単純なものでは、今使っているPCと同じPCをもう1台、予備機として用意しておくなど。_

#### スペックの変更が柔軟に対応できる
サーバーをローカルで構築する場合に悩ましいことの1つとして、ハードディスクやメモリ不足の対応が挙げられます。 例えば、データベースサーバーを長年運用していると、データを削除しない限りはデータ容量が増え続けます。そのためデータを保持し続けるには、ハードディスクを増設するという対応が必要です。この場合もサーバー構築時と同様に、増設するハードディスクやらメモリを購入してセットする必要があります。 一方、AWS EC2を使えば、画面上で設定するだけでハードディスクやメモリの増設が簡単に行えます。


## EC2の料金体系
AWS EC2の料金プランは、大きく分けて3つあります。

#### オンデマンドインスタンス
サーバーを立ち上げている時間または秒単位 (最低 60 秒) によって料金が発生するプランです。短時間のみ利用したい、週末や月に1回だけ使いたい場合に有益です。

#### リザーブドインスタンス
あらかじめ稼働期間を決めておき、先支払いする方式です。常時インスタンスを立ち上げていたい、長期間稼働させ続ける必要がある場合に使いやすいプランです。1ヶ月分バスの通勤定期券を購入した場合を想像すると良いかもしれません。乗車の度に運賃を支払うよりは安く済むことがほとんどです。
「オンデマンドインスタンスの利用料金を割り引いてもらえる定期券を購入すること」と考えるとわかり易いのではないでしょうか。

#### スポットインスタンス
スポットインスタンスは、オークション形式でインスタンスを入札し、自分の価格より高く使いたいユーザーが出たときなどに停止＆削除される代わりに非常に安い値段でインスタンスを利用する手段です。
スポットインスタンスは一時的な利用に限ります。自分の入札金額がスポットインスタンスの現在価格より下回ると削除されます。
そのため、短期間でコピー環境を作ってテストしたい場合や、負荷が上がる時間帯にスケールアウト(or スペックアップ)したい場合などで使うことができます。
入札金額はオンデマンド(通常料金)の金額が上限でオンデマンドよりも高い金額を払うことはありません。ただし、スポットインスタンスの価格がその金額まで達した場合には、削除されます。
<br />
<br />
<br />
#### 初期費用ゼロ、低運用コスト
物理サーバーであれば、構築の前にハードウェア機器の購入やネットワーク回線の敷設が必要であり、膨大な初期費用が必要です。
Amazon EC2の場合初期費用は発生しません。
仮想サーバー（インスタンス）を作成しただけでは費用は発生せず、インスタンスを稼働させてからはじめて費用が発生します。
また、運用コストもインスタンスを稼働させた時間に応じた従量課金制です。
Amazon EC2は競合他社と比較優位になるように、これまで多くの値下げを行ってきており、仮想サーバーとしてはほぼ最安値といって良い運用コストで利用可能になっています。

_（TECH PLAY　コラムからの引用あり　https://techplay.jp/）_
個人情報保護法における要配慮個人情報

平成31年春期 午前問題78

個人情報のうち，個人情報保護法における要配慮個人情報に該当するものはどれか。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/02034113-827a-6924-1bf5-ba92ea67058a.png)


１、要配慮個人情報とは、
個人情報保護法では、本人の人種、信条、社会的身分、病歴、犯罪歴などの不当な差別や偏見その他の不利益が生じかねない個人情報について、その取扱いには特に配慮を要すること。

要配慮個人情報は、原則として、あらかじめ本人の同意を得ないで取得することが禁止されています。


個人情報保護法及び同法施行令では、要配慮個人情報として11つの例を定めています。
・人種（単純な国籍や"外国人"という情報は含まない）
・信条
・社会的身分（職業的地位や学歴は含まない）
・病歴
・犯罪の経歴
・犯罪により害を被った事実
・身体障害、知的障害、精神障害等
・医師等の健康診断等の結果
・医師等による指導・診療・調剤
・刑事事件に関する手続
・少年の保護事件に関する手続

つまり、他人に知られたくないことですね。

２、通常の個人情報
特定の個人を識別できる情報です。

例え：
・個人に割り当てられた，運転免許証，クレジットカードなどの番号
・生存する個人に関する，個人を特定するために用いられる勤務先や住所などの情報
など

参照：
https://www.ap-siken.com/kakomon/31_haru/q78.html
dockerからローカルにファイルをコピーしたい

<img width="750" alt="スクリーンショット 2019-07-18 20.23.40 (1).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436942/42f1a41e-2eae-9daa-a778-4501a16716d7.png">
<img width="750" alt="スクリーンショット 2019-07-18 20.24.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436942/0fcbdde8-547d-e79a-7554-9466c38852b4.png">

まず、dockerの中に入る。

docker psでコンテナの情報を取得
docker cp コンテナid:コピーしたいファイルの場所　コピー先の場所
Macでpipを使えるようにする (easy_install is deprecated)

新しいMacにpipがなかったのでpipコマンドを使えるようにしたいがなかなｋできなかったのでメモとして残しておきます。

```sh
$ pip install selenium
-bash: pip: command not found
```

[Macでpipを使えるようにする](https://qiita.com/sf213471118/items/3ee4ebd5d39856345682)を参考にしようとするが、easy_installがdeprecatedらしいので他のやり方を模索しました。

色々と試しましたがなかなかうまく行かなくて、最終的にできたのがこちらの記事を参考にしたときです。

[bash: pip: command not found](https://stackoverflow.com/questions/9780717/bash-pip-command-not-found)

https://bootstrap.pypa.io/get-pip.py のサイトから get-pip.py をダウンロードします。

```sh
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
```

pythonでget-pip.pyを実行します。

```sh
$ sudo python get-pip.py
```

pip を使えるかバージョンを確認します。

```sh
$ pip --version
```

インストールできたら get-pip.py は不要なので削除します。

```sh
$ rm get-pip.py
```

これでpipコマンドが使えるようになりました。

## 宣伝

個人ブログを新しくリニューアルしました。

https://tamappe.com/

こちらでFlutterとかSwiftUIの勉強記録を載せています。
記事が参考になりましたらツイッターのフォローお願いします。

https://twitter.com/tamapppe
Dockerで計算用途で使うときのオプションのまとめ

Dockerでよく計算をすることがあるので、その時に使うオプションをまとめます。

## GPUを使うとき
`--gpus=<number>`でGPUの個数を指定する。
使うGPUのIDは環境変数`NVIDIA_VISIBLE_DEVICES`へ`0,1`や`all`などと指定する。
### `NVIDIA_DRIVER_CAPABILITIES`について
使いたい機能に応じて環境変数を指定する必要がある。デフォルトではnvidia-smiやNVMLが使えるutilityのみ。カンマ区切りで複数指定可能。
#### Supported driver capabilities(https://github.com/NVIDIA/nvidia-container-runtime/blob/master/README.md より)
* `compute`: required for CUDA and OpenCL applications.
* `compat32`: required for running 32-bit applications.
* `graphics`: required for running OpenGL and Vulkan applications.
* `utility`: required for using `nvidia-smi` and NVML.
* `video`: required for using the Video Codec SDK.
* `display`: required for leveraging X11 display.

## シェルを起動しているUserを引き継いで実行したいとき
nfsマウント等していて、特にユーザを一致する必要があるときに使います。
`-v /etc/group:/etc/group:ro -v /etc/passwd:/etc/passwd:ro -u $(id -u $USER):$(id -g $USER)`を使う。

## GUIを使いたいとき
` -e DISPLAY=$DISPLAY --net host -v /tmp/.X11-unix:/tmp/.X11-unix:ro -v $HOME/.Xauthority:/root/.Xauthority:ro`
(GUI周りはsshからX11 forwardingをしたほうがいいかも。今は面倒屋なので直接シェルを使っています)

## ホームディレクトリをバインドマウントしたいとき
`-v $HOME:$HOME`を使う。 

## 共有メモリの上限を増やすとき
特にGPUを使うアプリケーションでは共有メモリが足りなくなりがち。`[size]`には16gなどと指定する。
`--shm-size=[size]`

## シェルをその場で使いたいとき
`-it`をつけるとシェルが使える。



## よく使う組はエイリアスはっちゃえ！
- ユーザの設定
- X11のディスプレイの設定
- ホームディレクトリと共有NASのマウント設定
- 共有メモリの設定(16g)
- シェル

をまとめておきます。

```sh
alias docker-run-it="sudo docker run -v /etc/group:/etc/group:ro -v /etc/passwd:/etc/passwd:ro -u $(id -u $USER):$(id -g $USER)  -e DISPLAY=$DISPLAY --net host -v /tmp/.X11-unix:/tmp/.X11-unix:ro -v $HOME/.Xauthority:/root/.Xauthority:ro -v /data02/$USER/:/data02/$USER -v $HOME:$HOME:Z  --shm-size 16g -it"
```

こんなことになるくらいなら`singularity`とかも使ってみたいですね。もっと簡単になってルート権限も不要らしい。
FlutterのProviderを使ってみた

業務でFlutterを使うになり、 Providerパッケージを使ったので
その備忘録として残しておきます。

Providerが何かに関しては名前の通り変数やメッソドを供給するやつくらいの認識でとりあえず大丈夫です.

以下がコードになります

```dart
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';

import 'MyPageChangeNotifier.dart';
import 'package:talent/view/screen/myPage/component/Profile.dart';
import 'package:talent/view/screen/myPage/component/RequestStatus.dart';
import 'package:talent/view/component/Header.dart';
//import 'package:talent/view/component/NavigationBar.dart';
import 'package:talent/view/screen/myPage/component/NoticeItem.dart';
import 'package:talent/view/component/BorderedText.dart';

class MyPageScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<MyPageChangeNotifier>(
      create: (context) => MyPageChangeNotifier(),
      child: Scaffold(
        // appBar: Header(),
        // bottomNavigationBar: NavigationBar(),
        body: Consumer<MyPageChangeNotifier>(
          builder: (context, value, child) {
            return SingleChildScrollView(
              child: Column(
                children: <Widget>[
                  Container(
                    color: Color(0xffF5F6F9),
                    child: Padding(
                      padding: EdgeInsets.only(top: 40.0, bottom: 60.0, right: 40.0, left: 40.0),
                      child: Column(
                        children: <Widget>[
                          Profile(),
                          SizedBox(height: 20.0),
                          RequestStatus(),
                        ],
                      ),
                    ),
                  ),
                  Padding(
                    padding: EdgeInsets.only(top: 40.0, right: 24.0, left: 24.0, bottom: 63.0),
                    child: Column(children: <Widget>[
                    BorderedText(text: "お知らせ"),
                    SizedBox(height: 24.0),
                    NoticeItem(text: value.text, date: value.date),
                    SizedBox(height: 20.0),
                    NoticeItem(text: value.text, date: value.date),
                    ]),
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );
  }
}
```
```dart

import 'package:flutter/cupertino.dart';

class MyPageChangeNotifier with ChangeNotifier {
  String _date = "2020.XX.XX";
  String _text = "お知らせお知らせお知らせお知らせお知らせお知らせお知らせお知らせお知らせお知らせお知らせお知らせ。";

  get date => _date;
  get text => _text;
}

```
ITパスポートの学習方法を振り返ってみた

#受験した背景

IT業界に転職して、最初に入った会社の上司から基本を身につけるためにITパスポートの習得を勧められたのでその時の勉強法を振り返ってみようと思います。

業界について基本知識を少しでも押さえたいといいう考えがあったのが受験しようと考えた主な理由です。


#出題範囲

試験内容は下記の通りです。（2020年8月14日現在）

以下ITパスポート試験より抜粋
>
試験時間	120分
出題数	小問：100問（*1）
出題形式	四肢択一式
出題分野	ストラテジ系（経営全般）：35問程度
マネジメント系（IT管理）：20問程度
テクノロジ系（IT技術）：45問程度
合格基準	総合評価点600点以上であり、かつ分野別評価点もそれぞれ300点以上であること
総合評価点
      600点以上／1,000点（総合評価の満点）
分野別評価点
      ストラテジ系　　300点以上／1,000点（分野別評価の満点）
      マネジメント系　300点以上／1,000点（分野別評価の満点）
      テクノロジ系　　300点以上／1,000点（分野別評価の満点）




#私が行った勉強法

あまり時間を掛けたくなかったので、1カ月程での取得を目標に学習を開始しました。
下記の参考書及びサイトの内容をとにかく理解できるようにしました。

・かんたん合格 ITパスポート教科書

・最強WEB問題集ITパスポート

このテキストの用語を覚え、問題を全て溶けるようにしました。
基本は上記の参考書の内容です。あとPing-tのITパスポートの項目を少々解けるようにしました。
この方法で試験では７割ほど回答でき、合格。

色々な本に手を出すのではなく、一冊決めて繰り返し読んで理解することが大事だと思いました。

必須の資格ではありませんが、業界の知識を知ることができ役に立ちました。
ブラウザでFelicaLiteSの非暗号化領域を読む

# カードリーダー
https://www.sony.co.jp/Products/felica/consumer/products/RC-S380.html
RC-S380/S
アマゾンで買えます
# デモ
https://yusukem99.github.io/FelicaReader/example/

# FelicaReaderのインストール

ライブラリを作りました。
https://github.com/yusukem99/FelicaReader
RC-S380/Sのどちらでも動作確認済みです。

# 各OSの必要な設定

## Linux

udevのUSBカードリーダー許可設定
udevの設定変更が必要です。設定後udevを再起動する必要があります。
usernameをユーザ名に変更してください。

```/etc/udev/rules.d/90-nfc.rules
SUBSYSTEMS=="usb", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="06c1", ACTION=="add", GROUP="username", MODE="660"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="06c3", ACTION=="add", GROUP="username", MODE="660"
```

# Windows
ドライバを汎用ドライバに変更する必要があります。

# 読み取り

```js
const reader = new FelicaReader();
await reader.getDevice();
await reader.deviceInit()
let data = await reader.readWithOutEncryption();
```
カリー化チートシート

拙作記事『[カリー化チートシート](https://qiita.com/ytaki0801/items/a0c18a78f6f8f5c8fe2a)』について，対応言語や補足追記が増えるにつれ，チートシートというよりは解説記事と化してきたので，あらためて記述例一覧版を作成．しばらくしたら，元記事タイトルを『カリー化記述まとめ』に変えて，こちらを『カリー化チートシート』にするかも．【2020-09-17追記】しました．

#記述例一覧
複数の記法が可能な言語は，最新バージョン＆カリー化メソッド未使用の場合の，最も短い書き方のみを掲載．その他の記法やバージョン等による違いは[元記事](https://qiita.com/ytaki0801/items/a0c18a78f6f8f5c8fe2a)を参照．

| 言語 | (λxy.(真, if x＞y; and 偽, if x≦y)) 10 20 |
|:-:|:-:|
| Haskell | `(\x y -> x > y) 10 20` |
| Scheme | `(((lambda (x) (lambda (y) (> x y))) 10) 20)` |
| Python | `(lambda x: lambda y: x > y)(10)(20)` |
| Ruby | `-> x { -> y { x > y } }[10][20]` |
| JavaScript | `(x => y => x > y)(10)(20)` |
| Scala | `((x: Int) => (y: Int) => x > y)(10)(20)` |
| Perl | `sub { my $x = shift; return sub { my $y = shift; return $x > $y }; }->(10)->(20)` |
| Go言語 | `func(x int) func(int) bool { return func(y int) bool { return (x > y) } }(10)(20)` |
| PHP | `(fn($x) => fn($y) => $x > $y)(10)(20)` |
| Standard ML | `(fn x => fn y => x > y) 10 20` |
| Julia | `(x -> y -> x > y)(10)(20)` |
| Emacs Lisp, Common Lisp | `(funcall (funcall (lambda (x) (lambda (y) (> x y))) 10) 20)` |
| R言語 | `(function(x) { function(y) { x > y } })(10)(20)` |
| C++ | `[] (int x) { return [x] (int y) { return x > y; }; }(10)(20)` |
| Java | `((Function<Integer, Function<Integer, Boolean>>) x -> y -> x > y).apply(10).apply(20)` |
| ErLang | `fun(_x) -> fun(_y) -> _x > _y end (20) end (10).`|
| Clojure | `(((fn [x] (fn [y] (> x y))) 10) 20)` |

#更新履歴
* 2020-12-09：Clojureの例を追加
* 2020-12-02：Erlangの例を追加
* 2020-12-01：Standard MLの例を追加
* 2020-09-29：Javaの例について引数即時適用の記述に修正（コメントより）
* 2020-09-17：記事タイトルから『記述例一覧版』を削除し，元記事を『記述まとめ』に変更
* 2020-08-28：C++，Javaの例を追加
* 2020-08-14：大きい方の値ではなく真偽値を返す記述例に変更
* 2020-08-14：初版公開（Haskell，Scheme，Python，Ruby，JavaScript，Scala，Perl，Go言語，PHP，Julia，Emacs Lisp/Common Lisp，R言語）
ATtiny1617のシリアル通信（送信のみ）

###接続図
ATtiny1617 Boardにはシリアル通信用のコネクタがありますのでTTL-USB変換器を接続します。
今回は、isolation Smile Writer（AYA032-2)の絶縁TTL-USB変換器部分を使用しました。
![スクリーンショット 2020-08-14 8.16.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/2e2ebaac-a4e6-fae7-2b4c-d758ce156f5b.png)

ArduinoNANOはjtag2UPDIとなっています。
UPDIの接続I/Fですがリセット回路に取り付けているコンデンサは公式？は電解コンデンサですが
ちょうどよいのが無かったので、1uFのセラミックコンデンサを取り付けました。
（書き込めているようです）
![スクリーンショット 2020-08-14 8.17.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/f499833d-a608-7395-a577-bb47f7a23239.png)

右からisolation Smile Writer（AYA032-2)、ATtiny1617 Board(AYA066-1)
SmileDecoderTesterです。
jtag2UPDIへの赤線がブレッドボードの端によけてありましたね。書き込む時はArduinoNANOの
+5Vに接続します。
![スクリーンショット 2020-08-14 8.31.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111210/6c3e1b48-588c-84e2-df92-7beb7e2bf144.png)


###スケッチ
シリアルポートにhello ATtiny1617と表示されるサンプル。

```C++
void setup() {
  Serial.begin(115200);
  Serial.println("hello ATtiny1617");
}
void loop() {
}
```

###最後に
ATtiny1617(ATtiny1616)でシリアルデバックをする為に必要になりますので接続図等を残しておきました。
スケッチもArduinoUNO/NANOと変わらずにコーディングできることがわかりました。
自作マニュアルを作る。【linux】【man】

###環境
- ubuntu20.04 LTS

##やろう

`Ctrl+Alt+t`で端末を起動します。
以下のコマンドを入力してください。(manlは何でもいい)

```sh
$ mkdir man 
$ cd man 
$ mkdir manl 
$ cd manl
```

そうしたらテキストエディターでmanの中身を書きます。qiitaのマークダウンみたいに書式があります。

自作コマンドの作り方

[自作のコマンドを作成した - qiita](https://qiita.com/yoshiken/items/2b8e6c24d6b95e65b625)

自作コマンドのmanを書きます。

自作コマンドの中身:

```sh:lock.sh
#!/bin/sh
#chmod=アクセス権限を変更する
#a-rwx=すべての人に読み込み・書き込み・実行の権限を削除する
#$1=引数の取得(引数=a-rwxするファイル名)
chmod a-rwx $1
```


```lex:lock.l
.\"この行はコメントです。
.TH lOCK
.SH 名前
.\"名前と一言で言う説明を書きます。
lock \- ファイルの読み込み・書き込みのアクセス権を削除する
.SH 書式
.B lock 
[ ファイル名 ]
.SH 説明
.\"説明を書きます。
lockはテキストファイルや画像ファイル,などのアクセス権限を削除します。

.\"作者と著作権を書きます。
.SH 作者
作者 ichiri sato.
.SH 著作権
(c) 2020 ichiri sato. 
```

`-M`引数を使って自作manを表示します。

```sh
$ man -M ~/man lock.l
```

```text:表示結果
lOCK()                                                                 lOCK()

名前
       lock - ファイルの読み込み・書き込みのアクセス権を削除する

書式
       lock [ ファイル名 ]

説明
       lockはテキストファイルや画像ファイル,などのアクセス権限を削除します。

作者
       作者 ichiri sato.

著作権
       (c) 2020 ichiri sato.
                                                                       lOCK()

~
~
~
~
~
(省略 (ずっと ~ ~ ~) )
```

##参考記事
- [独自のmanページを作成するには － ＠IT](https://www.atmarkit.co.jp/flinux/rensai/linuxtips/840makeorgman.html)
GASのタイムゾーンから日付データ部分を抜き出したい（時刻部分の削除)

グーグルフォームを利用時に自動作成されるスプレッドシートにででてくるタイムゾーン。
GASで別シートへのデータの抜き出し処理をするときに、タイムゾーンの形式のままだと、時刻部分が邪魔なので、時刻部分を削除して日付データのみにする方法のメモです。

結論
##■Utilities.formatDate(date, timeZone, format)
date→Date型　フォーマット対象の日付
timeZone　→　タイムゾーン
format　→　日付のフォーマット　ここでは時刻無しにフォーマットします。

■Utilities.formatDate公式サイトのURLは↓
https://developers.google.com/apps-script/reference/utilities/utilities#formatDate(Date,String,String)

####■タイムゾーンは
Logger.log(Session.getTimeZone());　で出力できます。
もしくは
グーグルスプレッドシートのファイル→Googleスプレッドシートの設定タイムゾーンで確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369082/9b3bcdf9-6437-1f03-deab-dfeed184102a.png)


####■フォーマットはJavaのSimpleDateFormatと同じ
https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
今回は時間部分の削除なのでシンプルに yyyy/MM/ddでOKでした。

以上を考慮し
スプレッドシートのタイムゾーンから時間部分を削除します。

```:GoogleAppsScript

var hizuke="2020/07/30 5:44:25";　　　//セルからタイムゾーンを取得します。
var d2 = new Date(hizuke);           //日付をDate型にします。  
  
Logger.log(Utilities.formatDate(d2,"GMT+09:00","yyyy/MM/dd"));
Logger.log(Utilities.formatDate(d2,"Asia/Tokyo","yyyy/MM/dd"));


```

とても簡単なのですが、
一番調べたのがタイムゾーンの箇所
シンプルにそのまま文字列を記述すればよいのですが、なんかしっくりこなくて、多少時間がかかりました。

でも時間部分を削除することでスプレッドシートのフィルタがシンプルになったのでよかったです。
Spring Boot 2.3 x Spring Batch 4.2のチャンクモデルで雛形として使えそうなHello Worldなプロジェクトを作ってみた

## はじめに
初心者向けの入門系記事です。

チャンクモデルで何かバッチを作るときに雛形として使えるようにHello Worldなプロジェクトを作ったので、その提供と超簡単な解説をします。

というのもSpring Batchはヘビー級で最初の一歩を踏み出すのが大変です（私がそうでした）。
Spring Batchのアーキテクチャを理解し、最小構成（に近いもの）で最後まで動かすまでの難易度が高いと感じたのですが、一度動きだせば多少は難易度が下がった気がしたので、他の皆様にとってのその足がかりになるような記事になればと思い公開します。

なお、本記事ではチャンクモデル選定基準や各クラスの詳細の用途の解説・紹介はしません（というかそこまで詳しくないのでQiitaでは自信をもって解説できません）。

チャンクモデル選定基準については、参考になったTERASOLUNA記事だけここに貼っておきます。
[チャンクモデルとタスクレットモデルの使い分け](https://terasoluna-batch.github.io/guideline/current/ja/Ch03_ChunkOrTasklet.html)


## 技術スタック
- spring boot 2.3.x
- spring batch 4.2.x
- kotlin 1.3.x

## Hello World Example by Spring Boot Batch
さっそくですがサンプルコードはこちらです。

[hello world example by spring boot batch](https://github.com/kogayushi/spring-boot-batch-hello-world)

## Chunk Model Activity Diaglam

ただコードを共有されても、チャンクモデルがどう動いているのか把握しづらいので簡単なアクティビティ図を記載します。
もしかしたら細かいところ間違えているかもしれません[^1]が、アクティビティ図にするとこんな感じで動いているようです。

![SpringBatchアクティビティ図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306730/f806a9a9-e7b5-1431-e178-541b5e5b2c3a.png)


エラー発生時に`ChunkListener#afterChunkError`が呼び出されますが、この図に反映していません。
エラーが発生したらその直後に呼び出され、ステップ自体が中止されたのち、`StepExecutionListener#afterStep`が呼び出されるようです。

アクティビティ図にするとこんなふうに動いていました。

![SpringBatchアクティビティ図 エラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306730/a69fa41b-91dc-7e52-f618-4c229c1bb292.png)



## 登場している用語の説明
アクティビティ図だけ見ても各処理が何を意味するのかわからないとおもうので用語の簡単な解説をしておきます。

| 用語 | 説明 | 例 |
| :-- |:--  | :-- |
| Job | バッチの実行単位、タスク（ステップ）のまとまり。一般的なバッチジョブと同義。 | |
| Step | ジョブを複数に分割する必要がある場合に、その分割したまとまりのこと | |
| Chunk | reader -> processor -> writerのサイクルを回すまとまり（＝何件処理するごとにコミットするか）のこと。 | 100件のデータに対してチャンクサイズ10を指定すると10のチャンクが発生。10回に分けてコミットする。 |
| ItemReader | 処理対象となるデータを入力する | csvから読み込む、DB検索する |
| ItemProcessor | 入力データを加工する。<br>加工が必要ない場合は、パススルーも可能 |  データの加工 |
| ItemWriter | ItemProcessorで加工したデータに対して最終処理を行う | DBへの永続化 |
| JobExecutionListener | ジョブ実行前後に処理を挟む | ログの出力、slackへの通知 |
| StepExecutionListener | ステップ実行前後に処理を挟む | ログの出力、slackへの通知 |
| ChunkListener | チャンク実行前後とエラー発生時に処理を挟む | ログの出力、slackへの通知 |


## 最後に
本記事で紹介したものはSpring Batchの機能のごく一部です。

実際にはStepの結果で分岐したり、並行実行したり、DBから読み込むItemReaderだったりファイルから読み込むItemReaderがあったり、複数のitemProcessorを合成する方法だったり、、、多岐にわたる機能があり短時間で仕様の全体像を把握するのはとても難しいと思います。

そのため、まずは今回の記事で共有したようなハローワールドレベルのプロジェクトを足がかりに必要な機能を調べて足していってはいかがでしょうか？


[^1]: 間違いに気づいた人はぜひコメントでご指摘頂けると嬉しいです。
Ubuntu 20.04 で Bio-Formats の使い方

[Bio-Formats](https://www.openmicroscopy.org/bio-formats/)の使い方です。

1) コマンドラインツールのダウンロード

```bash
wget https://downloads.openmicroscopy.org/bio-formats/6.5.1/artifacts/bftools.zip
```
解凍して、例えば、$HOME/bin/bftools とする

Path を通す

```text:.bash_profile
（省略）
export PATH=$HOME/bin/bftools:$PATH
```

2)　ij.jar のダウンロード

```bash
wget http://wsr.imagej.net/distros/linux/ij153-linux64-java8.zip
```

解凍して、ij.jar を $HOME/bin/bftools に入れる

3) サンプルデータのダウンロード

```bash
wget https://downloads.openmicroscopy.org/images/OME-TIFF/2016-06/tubhiswt-2D.zip
```

解凍すると次の２つのファイルがある

```text
$ tree tubhiswt-2D
tubhiswt-2D
├── tubhiswt_C0.ome.tif
└── tubhiswt_C1.ome.tif
```

4) 画像の表示

```bash
showinf tubhiswt_C0.ome.tif
```

![show_inf_aug14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/5d9cd583-ead9-8e2a-b11d-a90b0eeb46f3.png)

5) ImageJ で画像の表示

```bash
ijview tubhiswt_C0.ome.tif
```

![ijview_aug14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/d505fc09-cdbb-f2b5-a17c-71950c979ad1.png)
[SeerviceNow] Script Includeに定数を持たせる

# きっかけ
Scopedアプリケーションのテーブル名が長くてタイプが面倒。
アプリケーションのプロパティを覚えられない。
ステータスの値が覚えられない。
Studioの中でまとまっているからそこまで探すのは大変ではないけれど、使用頻度が上がるとやっぱり一箇所にまとめたい。
つまり、衰えゆく記憶力や腕力を経験値でカバーしたい。

誰でも知ってることを今さら知っただけなのかもしれないけれど共有。

## 例
あえて冗長に書いていますが例えばこういうコード

```before.js
var defaultValue = 'x_322048_ngmapp_test_table';
var targetTable = gs.getProperty('x_322048_ngmapp.target_table_name', defaultValue);

var gr = new GlideRecord(targetTable);
```

# やり方

## Script IncludeにConstantsを定義する

![スクリーンショット 2020-08-13 19.47.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676866/2484d4a3-c8c2-a4d5-5a22-c82e67e8c7f3.png)

## 変更後

```after.js
var gr = new GlideRecord(Constants.TABLE_PROPERTY);
```


繰り返し使う定数はこうするよう心がけようと思う。


参考URL
https://youtu.be/B94UUQPDyDg
TFCoreMLで変換したモデルの出力がおかしい時の対処法

WWDC2020あたりを境に、tfcoremlで変換したGANの出力が全部真っ白になりました。
##対処法
Core ML Tools 4.0をインストールして変換し直す。

```shell
pip install coremltools==4.0b2
```

tfcoremlに比べて、変換メソッドのオプションがシンプルに変わっています。

```python
import coremltools as ct
image_input = ct.ImageType(shape=(1, 256, 256, 3,),
                             scale=2/255,bias=[-1,-1,-1])

coreml_model = ct.convert(
        yourmodel,
        inputs=[image_input],
        )
coreml_model.save("yourmodel.mlmodel")
```

これで出力されました。

<img width="256" alt="IMG_8701.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/27871061-de86-686c-acec-f50eb7c292e0.jpeg">

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[MLBoysチャンネル]
(https://www.youtube.com/channel/UCbHff-wfjTnB3rtXIP6y0xg)
[Medium](https://medium.com/@rockyshikoku)

[相棒](https://twitter.com/oka_yuuji)
[note](https://note.com/oka_yuuji)
Laravel x GAS API で Spreadsheet 自動作成してみた

# はじめに
実務で、GAS(Google Apps Script)を使って Spreadsheet 作成APIを作ったので、そのやり方を書く。
今回は、Laravel の Guzzle を使って APIを叩いたので、そのテンプレも書くことにした。

ここでは、clasp などのコマンドラインでの作業の説明は割愛する。

# Guzzle テンプレート

```php
$client = new \GuzzleHttp\Client();

url = https://script.google.com/a/XXXX.co.jp/macros/s/XXXXXXXXXXXXXXXXXXXXXXXX/exec

$sheets = ['[シート名]' => [['名前', 'Soma', 'Sekimoto'],['住所', 'Tokyo', 'Suginami'], ['年齢と性別', '　23歳', '男']]]

$res = $client->post(
            $url,
            [\GuzzleHttp\RequestOptions::JSON => [
                'title' => 'スプレッドシートタイトル',
                'sheets' => $sheets,
                'spread_sheet_id' => '[スプレッドシート ID]',
                'startPositions' => ['startRow' => 3, 'startColumn' => 2],
            ]]);
```


# GAS(Google Apps Script) API

```js:CreateSheet.js
function doPost(e) {
    // 引数で送られてきたパラメータを取得する
    var c = e.postData.contents
    var contents = JSON.parse(c)

    // パラメーターをそれぞれの変数に格納
    var title = contents.title
    var sheets = contents.sheets
    var startPositions = contents.startPositions
    var startRow = startPositions.startRow
    var startColumn = startPositions.startColumn
    var spreadsheetId = contents.spread_sheet_id

    var spreadsheet = spreadsheetId ? SpreadsheetApp.openById(spreadsheetId).copy(title) : SpreadsheetApp.create(title);
    // Parameter に spread_sheet_id がない場合は、新しいスプレッドシートを作るようにする。

    i = 0
    for (var sheet_name in sheets) {
        if (i >= spreadsheet.getSheets().length) {
            spreadsheet.insertSheet()
        }
        // シートが足りなくなった時は新しいシートを追加させる。

        var sheet = spreadsheet.getSheets()[i]
        var rows = sheets[sheet_name]
        sheet.getRange(startRow, startColumn, rows.length, rows[0].length).setValues(rows)
        sheet.getRange(startRow, startColumn, rows.length, rows[0].length).createFilter()
        sheet.setName(sheet_name)
        i += 1;
    }
    spreadsheet.addEditor("/xx/domain/XXXX.co.jp")
    // 編集者を付与できる。

    return ContentService.createTextOutput(JSON.stringify({url: spreadsheet.getUrl()})).setMimeType(ContentService.MimeType.JSON);
    // 作成したシートの URL を返す。 
}
```

これでスプレッドシート自動作成API完成！！！！


# おわりに

既存アプリ x GAS APIの無限大の可能性を利用すれば、最強のAPIレポジトリを完成させることも夢ではありません。みなさんの参考になれば幸いです。

もっとこうした方がいい！！、ここは間違ってる！！　等ございましたら遠慮なくお申し付けください！
もっとスマートなコードの書き方あると思うので、思いつく方いらっしゃいましたらご教授お願いします！
kaggle：「Maximum interactive GPU session count of 1 reached.」と出たときの対処法

2020-08-14　kaggle：「Maximum interactive GPU session count of 1 reached.」と出たときの対処法

## [問題点]

kaggleで遊んでいると、次のようなメッセージが出た。
> <font color="Red">Maximum interactive GPU session count of 1 reached.</font>

こんな感じで。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204186/110a7e89-66a1-674f-015a-df576be8d212.png" width="400">

ほっといても良いのだが、このままだと実行速度が遅くなるので、可能なら対処したほうがよろしいと思う。

## [対処方法]

まず右上のここをクリックしてメニューを表示させる
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204186/de3965f3-fdab-940a-10bb-40e6697115d6.png" width="400">

そしてここをクリックして更にメニューを降りていく

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204186/43e52160-38ac-99d0-4daa-37279dafca3d.png" width="400">

保有しているGPUは全て使用中ってことですね。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204186/7b6d2758-c26f-1d6a-a76e-6a6bb58dda7d.png" width="400">

そのGPUを使用しているNotebookはこれですね。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204186/7d83c82b-caef-67a0-963a-99cd40eb83cf.png" width="400">

右端のアイコンにカーソルを当てるとこのようなメッセージが。。。
> This will stop your external running session.
[意訳]このボタンを押すと他のNotebookで実行しているセッションを止めるよ。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204186/46ace2a9-c2db-2e12-6e21-b1cddaab2f7a.png" width="400">

クリックしたら消えた。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204186/cb3c9536-b4a3-e119-c79e-7ceebf0184ce.png" width="400">

上部の注意のメッセージも消えた^^
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204186/891169c0-e5f9-6ecf-d1b1-6072b27ed52d.png" width="400">

Enjoy!

以上
PlatformIO + Teensy3.2 +VScode で書き込めない時



![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) Arduinoには普通に書き込めたのになぁ

##やること
目下、純正のArduino IDEもPlatformIO + Atom も手元の環境では調子がわるいので
PlatformIO + Teensy3.2 + VScodeに変えてみました。
が、Teensy3.2への書き込みがうまくいかずちょっと困りました。
そもそもビルドできていない感じ。これを解決します。

##結論


main.cppのスケッチの冒頭に

```cpp:

#include <Arduino.h>
```
の一行を追加したら書き込めるようになりました。

### 補足
その他の基本的な使い方は他の記事を参考にしてください。
ちなみにPlatformio.iniの内容ついては、デフォルトの

```cpp:
[env:teensy31]
platform = teensy
board = teensy31
framework = arduino
```
のままで大丈夫でした。
vistaでquartus その24

#概要

vistaでquartusやってみた。
signaltapやってみた。


#写真

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/7ee9bab1-50d2-cc7c-5b22-fb5ffb2be831.png)


#環境

windows vista 32bit
quartus ii v13.0
ep2c5t144ボード

#手順

- qsfファイルに、以下を追加。


```
set_global_assignment -name INCREMENTAL_COMPILATION OFF

```

- signaltapをsetup

- コンパイル

- アップロード

- signaltapで波形を見る。

以上。
LaravelのFormRequestのテストをちゃんと書く


## はじめに

以前に[LaravelのFormRequestの単体テストのやり方](https://qiita.com/wim/items/e3f67424a633596e3692)という記事を書きましたが、この方法だと`prepareForValidation()`や`passedValidation()`のメソッドは使われないので、これらのメソッドに処理を記述している場合はテストができないということになります。

なので、これらのメソッドも実行されるようなFormRequestのテストの書き方を書いていきます。

## テストする

そもそも`prepareForValidation()`や`passedValidation()`はprotectedなのでメソッド単位でテストすることができないので、FormRequest全体の流れをテストします。

```php
public function test_()
{
    $parameters = ['key' => 'value'];

    $request = Request::create('', 'GET', $parameters);
    app()->instance('request', $request);
    $formRequest = app(HogeFormRequest::class);

    $this->assertSame('value2', $formRequest->get('key'));
}
```

`$parameters`に実際送信するパラメーターを連想配列で記述してください。

注意点は`app(HogeFormRequest::class);`で解決した時点でバリデーションを含む一連の処理が完了してます。
Railsでいいね機能を実装する方法

Railsでいいね機能を実装する方法をご紹介いたします。
完成系は以下のような感じです。
![いいね１.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654387/67853d37-6134-9f87-814c-f807ca210111.gif)


# 環境
- Ruby 2.5.7
- Rails 5.2.4

# 前提
- deviseによるログイン機能が実装できていること
- ユーザーのテーブルは"users"、記事のテーブルは"posts"、いいねの中間テーブルは"likes"とする。
- postsのカラムはtitleを追加する

# Likeモデルを追加
```
$ rails g model like user_id:integer post_id:integer

$ rails db:migrate
```
# アソシエーションを設定
それぞれ以下を記述し、アソシエーションを設定します。

```ruby:like.rb
  belongs_to :user
  belongs_to :post
```

```ruby:user.rb
  has_many :likes, dependent: :destroy
```

```ruby:post.rb
  has_many :likes, dependent: :destroy
```

# ルーティングを設定する

```ruby:routes.rb
  resources :posts, shallow: true do
    resources :likes, only: [:create, :destroy]
  end
```

# liked_by?メソッドを作成

```ruby:post.rb
  def liked_by?(user)
    likes.where(user_id: user.id).exists?
  end
```

# controllerの記述

```ruby:likes_controller.rb
  def create
    like = Like.new(user_id: current_user.id, post_id: params[:post_id])
    @post = like.post
    like.save
    redirect_back(fallback_location: posts_path)
  end

  def destroy
    like = Like.find(params[:id])
    @post = like.post
    like.destroy
    redirect_back(fallback_location: posts_path)
  end
```

# Bootstrapを導入
```ruby:Gemfile
gem 'bootstrap-sass', '~> 3.3.6'
gem 'jquery-rails'
```

```
$ bundle install
```
### application.cssのファイル名をapplication.scssに変更する

```
$ mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss
```

### Bootstrapをscssに読み込ませる
application.scssの一番下に以下を記述

```scss:application.scss
@import "bootstrap-sprockets";
@import "bootstrap";
```

### application.jsを編集する

application.jsの以下の部分を

```js:application.js
//= require rails-ujs
//= require turbolinks
//= require_tree .
```
から

```js:application.js
//= require rails-ujs
//= require jquery
//= require bootstrap-sprockets
//= require_tree .
```
に書き換えます。

# index.html.erbを編集
```html:index.html.erb
<div class="container">
  <h1>記事一覧</h1>
  <table class="table">
    <% @posts.each do |post| %>
      <tr>
        <td><%= post.title %></td>
        <td>
          <% if post.liked_by?(current_user) %>
            <% like = Like.find_by(user_id: current_user.id, post_id: post.id) %>
            <%= link_to like_path(like), method: :delete do %>
              <span class="glyphicon glyphicon-heart" aria-hidden="true" style="color: red;">
              <span><%= post.likes.count %></span>
            <% end %>
          <% else %>
            <%= link_to post_likes_path(post), method: :post do %>
              <span class="glyphicon glyphicon-heart" aria-hidden="true" style="color: gray;">
              <span><%= post.likes.count %></span>
            <% end %>
          <% end %>
        </td>
      </tr>
    <% end %>
  </table>
</div>
```
これで完成です。

# 参考記事
https://qiita.com/soehina/items/a68ab66da3ea1d260301
STM32F4のバックアップSRAM

STM32F4には4KiBのバックアップSRAM(BKPSRAM)が搭載されている。VDD or VBATから電力を受けて、「バックアップバッテリが接続されていればEEPROMと同様に扱える」メモリ。
RTCにもバックアップレジスタが実装されているが、こちらは20ワード(80バイト)しか無い。その代わりにタンパ検出(筐体の分解等を検出してデータを破棄する機能)がついている。
大きなデータはバックアップSRAM、小さなデータ(あるいはバックアップSRAMの暗号鍵)はRTCレジスタ、みたいな使い分け?

***

アドレスは`0x40024000`だが、`BKPSRAM_BASE`マクロが定義されているので、これを使うと便利。

BKPSRAMにアクセスするにはいくつかの手順が必要になる。読み出しには、電源コントローラ(PWR)の有効化、BKPSRAMインターフェースの有効化、が必要。書き込みにはライトプロテクトの解除も必要。

電源コントローラの有効化は`__HAL_RCC_PWR_CLK_ENABLE();`で行えるが、CubeMXでコードを生成すると`SystemClock_Config`の中で呼ばれているので、あまり気にする必要はないはず。

インターフェースの有効化には`__HAL_RCC_BKPSRAM_CLK_ENABLE();`を、解除には`__HAL_RCC_BKPSRAM_CLK_DISABLE();`を呼ぶ。
このインターフェースはマクロ名の通りSRAMインターフェースのクロックを有効化/無効化するもの。有効化しておかないと有効な値を読み取れなくなる。ただし、インターフェースが無効な状態で読み出すと、最後に読みだしたワードに含まれるバイトが読み出される仕様らしい。ゼロ埋めとかが出てくるわけじゃないのでデバッグ中は注意。なぜかうまく動かない、というときはクロック周りを疑うべし(って、これはARM全般に言えるか)。

書き込み時はインターフェースに加え、プロテクト解除が必要。プロテクト解除は`HAL_PWR_EnableBkUpAccess();`を、プロテクト有効化には`HAL_PWR_DisableBkUpAccess();`を呼ぶ。アクセス時のEna/Disはインターフェースと逆なので注意。

アクセス時は、`uint8_t *const bkpsram = reinterpret_cast<uint8_t *>(BKPSRAM_BASE);`のようにポインタを宣言してやれば、そのまま`printf("%02hhX\n", bkpsram[10]);`としてみたり、`bkpsram[4095] = 0xAA;`という感じで使える。もちろん、好きな構造体を経由してもいい。

バックアップSRAMは、電源がなくなるとランダムなデータが入るらしい。RAMの中身が有効なデータかは自分で判断する必要がある。例えばSTM32にはCRC計算機が入っているので、BKPSRAMのCRCをRTCバックアップレジスタに入れておいて、BKPSRAM書き込み時にはCRCも計算し、読み出し時はCRCが一致しなければエラーとして扱う、というような挙動が考えられる(もちろんCRC自体をBKPSRAMに入れてもいい)。CRCが過剰であればチェックサムを使うことも考えられる。