OmniAICreator/Qiita-1.07M huggingface dataset:
スクロールイベント

#画面のスクロール位置を取得
```php	
  $(window).scroll(function() {
  console.log($(this).scrollTop());
})
```

# scroll()


```php
<!DOCTYPE html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
</head>

<body>
  <p>位置：<span id="position">0px</span></p>
  <div id="box">
    <div id="contents">スクロールしてください</div>
  </div>
</body>

<!--CSS-->
<style>
#box {
  overflow: scroll;
  height: 200px;
  border: 3px solid gray;
}
#contents {
  height: 1000px;
}
</style>

<!--jQuery-->
<script>
  $(window).scroll(function() {
  console.log($(this).scrollTop());
})
  $('#box').scroll(function() {
    $('#position').text($(this).scrollTop() + 'px');
  });
</script>
</html>  
```
（備忘録）AWS認定試験テキストAWS認定クラウドプラクティショナーのデモ(ストレージサービス)

# 1. はじめに
2021年5月6日に[ヤマムギ](https://yamamugi.connpass.com/)様主催にて開催された[vol.20 AWS認定試験テキストAWS認定クラウドプラクティショナーのデモ(ストレージサービス)](https://yamamugi.connpass.com/event/211614/)でのAWS学習内容について、自分への備忘録としてまとめてみました。ご参考になれば幸いです。

# 2. 学んだ内容
- EBS
- EBSボリューム
- ボリュームタイプ（gp2、gp3、io1、io2、sc1、st1、standard）
- S3
- パブリックアクセスブロック

# 3. 学習サイト
- [YouTube：Amazon S3基本のデモ](https://youtu.be/6gLmtHvsss8)

# 4. 参考サイト
- [One Page Website Template](https://tympanus.net/codrops/2015/08/11/freebie-sedna-one-page-website-template/)
- [404](https://yamamugi-20210506.s3.amazonaws.com/index.html)

# 5. ハンズオンで得た豆知識
- EC2 Windowsサーバから2つのEBSボリュームにアタッチ
- アクションメニューからボリュームの変更（容量変更）が可能
- ボリュームタイプはgp3を選ぶとよい
- ボリュームタイプ マグネティク（standard）は古いので選ぶ必要はない
- lopsは読み込み速度のこと
- EBSはアベイラビリティゾーンに保存されている
- スナップショットを定期的にとるとよく、内部的にリージョンのS3に保存されている
- スナップショットはポリシースケジュールにて、自動保存可能
- 暗号化はサーバサイトで暗号化される
- インスタンスストアという、EC2内部ストレージが扱えるインスタントタイプもある
- EBSには、サーバダウン時にも保存しておきたいデータを保存する
- インスタンスストアには、サーバダウン後にアクセスできないことを理解しておくこと
- S3は容量確保の必要はなく、使用容量に課金され無制限で利用できる
- S3はリージョン上の3つのアベイラビリティゾーンで保存されている
- S3 → アクション → 公開
- インラインポリシー（S3:ListBacket）

```
// EC2 Linux から S3 へファイルアップロード
cd ~
ls 
python3 s3upload.py
```

# 6. おわりに
AWS学習の参考になれば幸いです。
ハンズオン開催してくださいました[ヤマムギ](https://yamamugi.connpass.com/)様、感謝いたします。

2021/05/06 NISHIZONO Takahiro
Pythonでお手軽テキスト全文検索 shellinford-python の紹介

ちゃお……†

今回はPythonでお手軽にテキスト全文検索出来るライブラリ shellinford-python を紹介します。

こちらは@echizen_tmさんの [shellinford](https://github.com/echizentm/shellinford) をSWIGでPythonで動作させるようにしたのと、若干の機能追加したものです。Python環境さえあれば簡単にシンプルな全文検索出来るのでお手軽かと思います。

# FM indexとは
バイオインフォマティクスなんかで使われる検索アルゴリズムです。わたしが説明するより良い説明を見つけたので以下に引用します。

> シークエンサーのデータを解析するとき、リードをリファレンス配列にマッピングすることが第一歩である。一般にシークエンサーのリードは数百万個以上で、また、リファレンス配列の塩基数は数億にも及ぶ。これらの数百万のリードを、数億塩基からなるリファレンス配列にマッピングする際に、高速な文字列検索アルゴリズムが必要される。このようなアルゴリズムとして、FM index がある。実際に、現在のマッピングプログラムのほとんどは、FM index アルゴリズムを中心に使用してマッピングを行なっている。なお、FM index は完全一致でしか検索できない。そのため、ほとんどのプログラムでは、まずリードの一部分だけをリファレンスに対して完全一致で検索する。そして、完全一致でヒットした箇所で、リードの残った部分をリファレンスに対して Smith-Waterman アルゴリズムでアライメントを行う。
https://bi.biopapyrus.jp/rnaseq/mapping/bwt.html

# shellinford-pythonの使い方
## インストール
```
pip install shellinford
```

PYPIでWindows用のwheelを配布しているのでWindowsでのC++11コンパイル環境がなくても使えると思います。その他のOSではC++11コンパイル環境が必須です。

## インスタンスを生成
``` python
import shellinford
fm = shellinford.FMIndex()
```

> shellinford.FMIndex([use_wavelet_tree=True, filename=None])

`filename` パラメーターに `str` を与えた場合は、パスにある `FMIndex` モデルのファイルをロードします。

## FM-index モデルを作る
```python
fm.build(['Milky Holmes', 'Sherlock "Sheryl" Shellingford', 'Milky'], 'milky.fm')
```

> FMIndex.build([docs, filename])

`docs` には `str` 型の `list` を与えます。 `filename` に `str` を与えるとそのパスにモデルを保存します。

上記の例では、下記のドキュメントを 'milky.fm' に保存します。

```
Milky Holmes
Sherlock "Sheryl" Shellingford
Milky
```

## FM-index モデルから指定した文字列が含まれているドキュメントを検索する
> search(query, [_or=False, ignores=[]])

`query` パラメーターは `str` あるいは `str` の `list` です。 `_or` パラメーターに `True` を与えるといわゆるOR検索を行います。デフォルトではいわゆるAND検索です。`ignores` は `str` の `list` で、検索対象から除外したい文字列を指定できます。

注意点として `search` メソッドは、FM-indexモデルを生成した後かロードしたのみ使えます。

### 1つのキーワードで検索する例
```python
>>> for doc in fm.search('Milky'):
>>>     print('doc_id:', doc.doc_id)
>>>     print('count:', doc.count)
>>>     print('text:', doc.text)
doc_id: 0
count: [1]
text: Milky Holmes
doc_id: 2
count: [1]
text: Milky
````

### 複数のキーワードでAND検索する例
```python
>>> for doc in fm.search(['Milky', 'Holmes']):
>>>     print('doc_id:', doc.doc_id)
>>>     print('count:', doc.count)
>>>     print('text:', doc.text)
doc_id: 1
count: [1]
text: Milky Holmes
```

## 指定した文字列を含むドキュメントの数をカウントする
```python
>>> fm.count('Milky'):
2

>>> fm.count(['Milky', 'Holmes']):
1
```
> count(query, [_or=False])

こちらも`query` パラメーターは `str` あるいは `str` の `list` です。 `_or` パラメーターに `True` を与えるといわゆるOR検索を行います。デフォルトではいわゆるAND検索です。カウントしたいだけの場合は、`count` メソッドの方が `search` メソッドより少し処理が速いです。

注意点として `count` メソッドも、FM-indexモデルを生成した後かロードしたのみ使えます。

## ドキュメントを追加する
```python
>>> fm.push_back('Baritsu')
```
> push_back(doc)

`doc` パラメーターは `str` です。

注意点として `push_back` メソッドは、 `build` メソッドでFM-indexモデルをビルドするまで検索に反映されません。


## ファイルからFM-indexモデルをロードする
```python
>>> fm.read('milky_holmes.fm')
```
> read(path)

`path` は `str` でモデルのパスを指定します。

## FM-indexモデルをファイルに書き込む
```python
>>> fm.write('milky_holmes.fm')
```
> write(path)

`path` は `str` でモデルのパスを指定します。

## FM-Indexに文字列が含まれているか確認する
```python
>>> 'baritsu' in fm
True
```
【Rails】WIndows環境でrails db:resetしたとき、Couldn't drop database 'db/development.sqlite3'のエラーの対処法

<h2>症状</h2>
Windows環境でrails db:resetしたとき、下記エラーが表示されてしまいました。
マイグレーションファイルを更新して、データベースにあるテーブルの内容を更新したく、rails db:resetを実行しました。

```terminal:ターミナル
rails db:reset
Permission denied @ apply2files - C:/Users/ユーザー名/environment/sampleApp/db/development.sqlite3
Couldn't drop database 'db/development.sqlite3'
rails aborted!
Errno::EACCES: Permission denied @ apply2files - C:/Users/ユーザー名/environment/sampleApp/db/development.sqlite3
bin/rails:4:in `<main>'
Tasks: TOP => db:drop:_unsafe
(See full trace by running task with --trace)
```

以下のコマンドで検索すると、どうやらRails自体のバグがあるようで、Windows環境で特定のコマンドを実行しようとすると、上記のようなエラーが発生するようです。
該当コマンドは以下です。

```terminal:対象コマンド
rails db:drop
rails db:reset
rails db:migrate:reset
```

今回はrails db:resetが該当します。

<h2>解決方法</h2>
railsのdbのフォルダに移動し、手動でデータベースを削除する必要があるとのこと。
実際にやってみると、正常にデータベースが削除できました。

```
del development.sqlite3
```

migrationファイルを編集し、下記コマンドを実行すると正常にテーブルが更新できました。

```
rails db:migrate
```

<h2>参考</h2>
【Ruby on Rails】rails db:dropコマンドを実行したとき、エラーメッセージ「Couldn’t drop database ‘db/development.sqlite3’ rails aborted!」が表示されてしまう原因と解決策をお伝えします
https://www.tairaengineer-note.com/rails-couldnt-drop-database/
【AWS】ElastiCacheのMemcachedとRedisの比較

#プログラミング勉強日記
2021年5月6日

#ElastiCacheの特徴
　ElastiCacheはデータをノードのメモリに保存する。これによって高速でデータの出し入れを行うことができる。
　ただ、メモリにデータを保存しているため再起動などでノードが落ちるとデータがなくなってしまうので、注意が必要。

#Memcachedとは
　Memcachedのクラスタは単純にノードを追加・削除して負荷を分散できる。しかし、これは自動検出の機能に依存している。
　Memcachedはノードの状態をポーリングしてノードにアクセスをする。

> ポーリングとは、「サーバーとクライアント」や「主システムと周辺機器」といった複数の機器を円滑に連携させる方法のひとつです。主に通信などの競合を回避するために、ホスト側が各機器に対して定期的に問い合わせを行い、条件を満たした場合に送受信や各種処理を行います。
引用：https://blogs.manageengine.jp/itom_what_is_polling/

　Memcachedはマルチスレッドで動作するため、CPUのコア数を上げれば性能を上げられる。シンプルなデータしか扱うことができないので、複雑なデータを扱う場合はアプリ側で格納できる型に変更する必要がある。また、扱えるコマンドも少ない。

#Redisとは
　Redisにはいくつかの種類があるが、Memcachedクラスターとの違いはクラスターのエンドポイントを持っていること。Redisクラスターもノードの数を加減することで負荷の分散ができる。
　Redisはクラスターがエンドポイントを持っているので、アプリ側でポーリングする必要がない。

　Redisはシングルスレッドで動作するため、CPUのコア数を上げてもMemcachedほどパフォーマンスの向上を期待できない。Redisは豊富なデータ型を使うことができるだけでなく、正規表現を用いたキーの検索などget/setにも機能が豊富。


#MemcachedとRedisの使い分け

##Memcachedを使うとき

- 単純なデータ型でいい場合
- マルチスレッドを使用する場合
- オブジェクトをキャッシュする必要がある場合


##Redisを使うとき

- 複雑なデータ型が必要な場合
- フェイルオーバーが必要な場合
- 永続化が必要な場合


#参考文献
[Memcached と Redis の比較](https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/mem-ug/SelectEngine.html)
[ElastiCacheはMemcachedとRedisのどっちを選ぶ？](https://dev.classmethod.jp/articles/which-choice-redis-memcached/)
Nuxtjs × Netlify Functionsを始める際のメモ


## まずはNuxtjs

https://ja.nuxtjs.org/docs/2.x/get-started/installation

```
yarn create nuxt-app <project-name>
```

`axios` にはチェックを入れておく

```
cd <project-name>
yarn dev
```
## Netlify Functionsを使えるように

### インストール

```
npm i netlify-lambda
```

### package.jsonに追記

```json
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "serve": "netlify dev"
  },
```

serveの行を追加した

毎回 'netlify dev' で実行でもいいけどやっぱり忘れるし…

`netlify` コマンドがないって言われたら

```
npm install netlify-cli -g
```

ちなみにnpxだと失敗した

試しに実行する際は、

```
npm run serve
```

で開発していくとよかった

Netlify Functionsも実行できるし、Nuxtもローカルで動いた

### tomlファイルの作成

`netlify.toml` という名前のファイルを新しく作って、

```
[dev]
   command = "yarn dev"

[build]
  command = "yarn generate"
  publish = "dist"
  functions = "functions"
```

としてみた。
（たぶん余計なものとかまだ削れきれてないだろうなぁ）

### functionsフォルダの作成

functionsフォルダを作成し、中にNetlify Functionsのコードを書いていく

例えば 'hello-world.js' というファイル名で

```js:hello-world.js
exports.handler = function (event, context, callback) {
  callback(null, {
    statusCode: 200,
    body: 'Hello, World',
  })
}
```

```
npm run serve
```

で自動的に立ち上がった 'localhost:8888' にNuxtのページが見れる

各functionsへは

```
http://localhost:8888/.netlify/functions/<functionのファイル名>
```

例えば

```
http://localhost:8888/.netlify/functions/hello-world
```

URL内にドットがあると嫌です？
まぁまぁ、Nuxtのページとバッティングせずにいいじゃないですか…

どうしてもって場合は多分tomlファイル内での設定です。がんばってください（未来への自分へ…）
fontforgeで空白文字除去

fontforgeのバージョンはwindows版の20201107です。

```py
SelectFewerSingletons(0u9,0ua,0ub,0uc,0ud,0u1c,0u1d,0u1e,0u1f,0u20,0ua0,0u11a3,0u11a4,0u11a5,0u11a6,0u11a7,0u1680,0u180e)
SelectFewerSingletons(0u2000,0u2001,0u2002,0u2003,0u2004,0u2005,0u2006,0u2007,0u2008,0u2009,0u200a,0u200b,0u202f,0u205f,0u3000,0u3164,0ufeff)
SelectFewerSingletons(0u34f,0u200c,0u200d,0u200e,0u200f,0u2028,0u2029,0u202a,0u202b,0u202c,0u202d,0u202e,0u2061,0u2062,0u2063)
SelectFewerSingletons("uni3000.vert")
Clear()
```

初回

1. ↑を適当な名前をつけて拡張子「pe」で保存。
1. 「ファイル＞環境設定＞スクリプトメニュー」で1のスクリプトを指定。
1. 「編集＞選択＞空白グリフ」で空白文字を選択。
1. 「ファイル＞スクリプトメニュー」で2で指定したスクリプトを実行。

次回からは3と4でOK。

fontforgeの機能で空白文字を選択した後、必要な空白（スペース）をなるべく除外して削除しています。
too many argumentsと言われちゃいましたので3回に分けて除外してます。
これ抜けてるぞというのがあったら教えて頂きたく。

##参考

https://cockscomb.hatenablog.com/entry/2013/04/23/201828

メタ坊主さんのコメントのお陰で空白グリフ選択に気づけました。

https://fontforge.org/docs/old/ja/scripting.html

https://fontforge.org/docs/scripting/scripting.html

http://anti.rosx.net/etc/memo/002_space.html
Spring Boot Starter for Azure Storage を使ってみる

# Spring Boot Starter for Azure Storage を使ってみる

自身でもちょっと混乱したので、備忘録代わりの記事です。Spring Boot for Azure Storage で検索すると、以下のサイトがヒットしたりしますが、この `spring-starter-azure-storage` ライブラリはすでに **Deprecated** です。

[Azure Storage 用の Spring Boot Starter の使用方法 | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/developer/java/spring-framework/configure-spring-boot-starter-java-app-with-azure-storage)

最新は名前も変って `azure-spring-boot-starter-storage` となってます。現在の最新のライブラリは、基本的に `azure-spring-boot-starter` で始まっています（一部古いものもありますが）

# 使ってみる

このライブラリでは、`BlobServiceClientBuilder` を DIする方法と、`Value`アノテーションを使って、リソースをDIする方法が提供されています。はじめに、`BlobServiceClientBuilder` を DI する方法を試してみましょう。

https://start.spring.io/ からの生成に対応しているので、そちらを使うと便利ですが、`pom.xml` の 依存関係には以下が必要です。

```xml
        <dependency>
            <groupId>com.azure.spring</groupId>
            <artifactId>azure-spring-boot-starter-storage</artifactId>
        </dependency>
```

そして、`application.properties` には、 ストレージアカウント名、アカウントキー、エンドポイント名が必要です。

```properties
azure.storage.accountName=<<your account name>>
azure.storage.accountKey=<<your account key>>
azure.storage.blob-endpoint=https://<<account name>>.blob.core.windows.net/
```

コンストラクタインジェクションでも、フィールドインジェクションでもどちらも構いません。以下はコンストラクタインジェクションで試しています。`BlobServiceClientBuilder` からクライアントインスタンスをビルドするのですが、同期クラアントでも非同期クライアントでもどちらでもよいでしょう。Sprinb Boot WebFlux は、Project Reactor による非同期プログラミングをサポートしているので、以下では非同期クライアントをビルドしています。Azure Storage SDK for Java 自身が、Reactorによる非同期に対応しているので、相性は良いと思います。

以下は、ザックリとコンテナ一覧を表示している例です。`listBlobContainers` して コンテナ名を返しているところです。戻り値が、`Mono<List<Strting>>` で、`Flux<String>` ではないのは、WebFluxの仕様上の話です。`Flux<String>` で返すと、JSONのチャンクとして扱われてしまうようで、少しハマリました。

```java
RestController
public class BlobController {

    private final BlobServiceAsyncClient blobServiceAsyncClient;

    public BlobController(BlobServiceClientBuilder builder) {
        this.blobServiceAsyncClient = builder.buildAsyncClient();
    }

    @GetMapping(value = "/containers", produces = MediaType.APPLICATION_JSON_VALUE)
    public Mono<List<String>> listContainers() {
        return this.blobServiceAsyncClient
            .listBlobContainers()
            .map(c -> c.getName())
            .collectList();
    }
}
```

もう1つの `Resource` に差し込む方法として、以下のように`Value` アノテーションで、DIすることができます。形式は、`azure-blob://コンテナ名/ブロブ名` になります。以下は、プロパティファイルで置換しています。

```java
    @Value("azure-blob://${containerName}/${blobName}")
    private Resource blobFile;

    @GetMapping("/blob")
    public String hello() throws IOException {
        return StreamUtils.copyToString(
            this.blobFile.getInputStream(),
            Charset.forName("UTF-8"));
    }
```

ちなみに、`blobFile.getInputStream()` を呼ぶと、ライブラリ側で`block()` されているらしく、WebFlux 上では例外が出て動きませでしたので注意が必要です。

イマイチ使いどころが分りませんが、もう少しpring フレームワークを知れば、なにか使いどころがあるのかもしれません。

# まとめ

プロパティに、ストレージキーが書かれていますが、Managed IDに対応しているかは、GithubのREADMEには書かれていませんでしたので不明です。時間があれば試してみたいと思います。

あと、サービス毎にストレージ分けたりした場合、複数のアカウントに対応してないっぽいので、それも使いにくいかもしれません。そのあたりのサービスはさくっと実装してもあまり手間がない気もします。
数当てゲームの改良版

数当てゲームを改良して、正解、不正解でブラウザ上に表示する文言を変えました

```HTML
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>数当てゲーム</title>
<style>
    h1 {
        color:plum;
        font-size:100px;
    }
    h2 {
        color:#4f7911;
        font-size:50px;
    }
    body {
        background-color:whitesmoke;
    }
</style>
</head>
<body id = "test">
<header>
<div class="container">
<h1>数当てゲーム</h1>
<h2>数を当ててみよう</h2>
</div><!-- /.container -->
</header>
<main>
<div class="container">
<section>
    
</section>
</div><!-- /.container -->
</main>
<footer>
<div class="container">
</div><!-- /.container -->
</footer>
<script>
'use strict';
let message;
let count = 1;
let flag = 0;
//乱数を発生させる。0~49まで数字がランダムに表示されるので1を足す。
const number = Math.floor(Math.random() * 50) + 1;
//数当てゲームは5回挑戦できるようにする。
while (count <=5){ 
    const answer = parseInt(window.prompt('数当てゲーム。1〜50の数字を入力してね。5回まで挑戦できます'));
    window.alert(count + "回目です。")
    //正解、数が小さい、数が大きい、1から50以外の数字が入った時の条件式
    if(answer === number) {
        message = 'あたり！';
        window.prompt(count + "回目で正解しました。おめでとうございます!");
        document.querySelector("h1").innerHTML = "<h1>数当てゲーム、正解です!</h1>";
        document.querySelector("h2").innerHTML = "<h2>おめでとうございます！</h2>";
        flag = 1;
        break;
    } else if((answer < number) && (answer >= 1)) {
        message = '残念でした！もっと大きい';
    } else if((answer > number) && (answer <=50)) {
        message = '残念でした！もっと小さい';
    } else {
        message = '1〜50の数字を入力してね。';
    }
    //入力した数字に応じてメッセージを出力する。
    window.alert(message);
    //
    count = count + 1;
}
//3回挑戦して不正解だったら正解をアラートで表示し、HTMLに表示するメッセージを変更する。
if (flag === 0){
    window.alert("正解は" + number + "です");
    document.querySelector("h1").innerHTML = "<h1>残念でした!</h1>";
    document.querySelector("h2").innerHTML = "<h2>また挑戦してください！</h2>";

}         
</script>
</body>
</html>
```
Kotlin+Roomを使ったモジュールがライブラリにある場合のスキーマ出力設定

Roomに依存するデータベース処理をモジュール**mylibraryB**が持っており、アプリのモジュール**appA**がそれに依存している。

構成的にはこんな感じ。

```console
├── appA
│   ├── build.gradle
│   └── src
├── build.gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
├── mylibraryB
│   ├── build.gradle
│   └── src
└── settings.gradle

```

そんな場合で、かつKotlinの場合に、Roomのマイグレーション用スキーマファイルの出力に試行錯誤したので、覚え書きです。

# 環境など

|ツールなど|バージョンなど|
|:--|:--|
| MacbookPro |macOS Catalina 10.15.7|
|Android Studio |4.1.2|
|Java(JDK) | openjdk version "11.0.10" |
|Room | 2.2.6 |
|Robolectric | 4.3.1 |

# 対応方法
基本的な対応方法は以下などにあり、ライブラリになっていない場合はこの通りで問題ないはずです。
https://medium.com/androiddevelopers/7-steps-to-room-27a5fe5f99b2

ライブラリモジュールに実際のDAOなどの定義がある場合は、このままだと上手くいきません。

## ライブラリ側のbuild.gradleへの変更

ライブラリモジュール側のbuild.gradleに以下のように設定します。

```mylibraryB/build.gradle
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt' // 追加

android {
    //...

    defaultConfig {
        //...

        // schemaを出力する先を設定
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation":"../appA/schemas".toString()]
            }
        }
    }
    // ...
}
dependencies {
    //...

    // Room用に以下を追加
    def room_version = "2.2.6"

    api "androidx.room:room-runtime:$room_version"
    kapt "androidx.room:room-compiler:$room_version"
    // optional - Kotlin Extensions and Coroutines support for Room
    api "androidx.room:room-ktx:$room_version"
}
```

ライブラリなので、Room関連の依存は`implementation`ではなく`api`にしています。
この設定ですと、appAモジュールの以下の場所に`schemas`ディレクトリが作られ、その配下にjsonが吐き出されます。

```console
├── appA
│   ├── build.gradle
│   └── src
│   └── schemas
```

## アプリ側のbuild.gradleへの変更

```appA/build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'

android {
    //...
    defaultConfig {
        //...

        //schemaファイル読み出しパスを追加
        sourceSets {
            debug.assets.srcDirs += files("$projectDir/schemas".toString())
        }
    }
}

dependencies {
    //...

    // Room用に以下を追加
    def room_version = "2.2.6"
    testImplementation "androidx.room:room-testing:$room_version"
}
```

アプリ側でテストを行うため(※)、exportされたschemaファイルを読み見込めるようにします。
assetsディレクトリに先ほど指定した`schemas`フォルダを指定しています。

`debug.assets`としているのは、Robolectricでテストしたいからです。サンプルでは`androidTest.assets`となっていますが、これだとRobolectricでのテスト(testフォルダに作成する)で読み込めません。

以上の設定でスキーマが吐き出され、マイグレーションテストが出来るようになるはずです。

※実はこのappAは、ライブラリのテストコードだけがあるモジュールになっています。なのでこのように吐き出す設定と、利用する側の設定を分ける必要があったということです。ライブラリモジュール内にテストコードがある場合には、ライブラリのbuild.gradleに両方設定すればよいはずです。

# 参考サイト
マイグレーションテストの参考に。
https://medium.com/androiddevelopers/testing-room-migrations-be93cdb0d975

複雑なデータベース処理をしている場合の移行ガイド。
https://medium.com/androiddevelopers/incrementally-migrate-from-sqlite-to-room-66c2f655b377

マイグレーションサンプル
https://github.com/android/architecture-components-samples/tree/master/PersistenceMigrationsSample
※上記サンプルはJavaコードとなっています
コーディングの思想

# コーディングの思想
コーディング規約やコーディングスタイルの前に、**思想**レベルの**共有**が必要だと思い、記事を作成しました。
リーダブルコードを理解していれば、読まなくて構いません。

## 一度に1つのこと
- 抽出
- 判定
- 実行

までを1つのメソッドでやっているのであれば、**やり過ぎ**です。
抽出で1メソッド、判定で1メソッド、実行で1メソッドくらい、**細かく**してください。

観点としては、

1. **メソッド名**がつけやすいこと
1. **テストコード**がシンプルに書けること

を満たすよう心がけてください。

## 短いコードを書く
上記と重複する面もありますが、**大きい**クラスや**長い**メソッドは役割が**大き過ぎる**場合が多いので、見直してください。
ただし、理解しづらくなってまで短いコードを書け、という意味ではないです。

## 制御フローを読みやすくする
### 早期リターンを使う
例えば、引数がnullの場合それ以上**処理しない**のであれば、その時点で処理を**離脱**してください。
**else**でダラダラと**インデント**を下げると、コードも**読みづらく**なるし、「今elseの処理をしている」ことを覚えておかないといけないので、人間の**脳**のリソースも**消費**します。

### 変数宣言は使う直言に
メソッドの**先頭**で**変数宣言**すると、その変数を使うまでの間、人間がその変数のことを**覚えていなければ**いけなくなります。

## 名前に情報を詰め込む
まずですが、ネーミングに**こだわる**という意識を初めに持ってください。
どんな名前でもシステムは動きますが、人間が読む場合には**ネーミング**で理解速度に**大きな差**がつきます。

### 適当に名前をつけない
最終的には、感性や語彙力なのですが、まず一度考えてください。
初見の人は**理解できる**のか、英語の**意味はあっている**か、スペルは**間違っていない**か、一度調べてください。

### 変な省略はしない
省略することで理解できなくなるより、**理解できる**長い名前の方が**マシ**です。
dfコマンド

# ディスクが満杯になる前にファイルを削除したい
※「シス環系女子 season2 第12話」の備忘録です。

## dfコマンド

「Disk Free」の略。

以下実行結果の例

```
$ df
Filesystem    512-blocks      Used Available Capacity iused      ifree %iused  Mounted on
/dev/disk1s5   236568496  21796824  24231072    48%  487524 1182354956    0%   /
devfs                397       397         0   100%     688          0  100%   /dev
/dev/disk1s1   236568496 174417696  24231072    88%  885742 1181956738    0%   /System/Volumes/Data
/dev/disk1s4   236568496  14682840  24231072    38%       8 1182842472    0%   /private/var/vm
map auto_home          0         0         0   100%       0          0  100%   /System/Volumes/Data/home
/dev/disk1s3   236568496   1031416  24231072     5%      40 1182842440    0%   /Volumes/Recovery
```

左から、ディスクの名前、ディスクの総容量(単位:Kバイト)、使用量(単位:Kバイト)、空き容量(単位:Kバイト)、使用率、ディレクトリーツリー内でのマウント位置。

以下、「/ 」ディレクトリの空き容量だけを抜き取るコマンド
※dfの出力は特定の1文字だけで区切られているわけじゃないからcutコマンドは使いにくい。

```
$ df / | sed -E -e "s/[^ ]+ +[^ ]+ +[^ ]+ +([^ ]+).+/\1/"
Available
24587184
```

で、シェルスクリプトとかで必要なのは空き容量の数値だけなので、以下のコマンドで数値だけに絞り込む。

```
$ df / | sed -E -e "s/[^ ]+ +[^ ]+ +[^ ]+ +([^ ]+).+/\1/" | tail -n 1
24586272
```

以下、ルートディレクトリ「/」の空き容量が、10Gバイト以下になっていたら、30日以前のファイルを削除するシェルスクリプト

```
#!/bin/bash
available_size=$(df / | sed -E -e "s/[^ ]+ +[^ ]+ +[^ ]+ +([^ ]+).+/\1/" | tail -n 1)
required_size=$((10 * 1000 * 1000))

if [ $available_size -lt $required_size ]
then
  files=$(find / -ctime +30)
  for file in $files
  do
    rm "$file"
  done
fi
```

※おまけ。以下-hオプションをつけると数値に単位が付いて見やすくなる
「-human-readable」

```
$ df -h
Filesystem      Size   Used  Avail Capacity iused      ifree %iused  Mounted on
/dev/disk1s5   113Gi   10Gi   12Gi    47%  487524 1182354956    0%   /
devfs          199Ki  199Ki    0Bi   100%     688          0  100%   /dev
/dev/disk1s1   113Gi   83Gi   12Gi    88%  885707 1181956773    0%   /System/Volumes/Data
/dev/disk1s4   113Gi  7.0Gi   12Gi    38%       8 1182842472    0%   /private/var/vm
map auto_home    0Bi    0Bi    0Bi   100%       0          0  100%   /System/Volumes/Data/home
/dev/disk1s3   113Gi  504Mi   12Gi     5%      40 1182842440    0%   /Volumes/Recovery
```
【JavaScript】1+2+3+…と1ずつ加算し、【和】が1000を超えた時までの加算値と、合計値を表示せよ。

```javascript
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8">
   <title>1+2+3+…と足される数を1ずつ増やしながら足していき、和が1000を超えるときの足される数値と、合計値を表示してください。</title>
</head>
<body>
  <!-- 1+2+3+…と足される数を1ずつ増やしながら足していき、
    和が1000を超えるときの足される数値と、合計値を表示してください。 -->
<script>
        var sum = 0; 
        var i = 0;
        while (sum <= 1000) {
            i++;
            document.write('<p>' + '= ' + sum + ' +' +  '【'  + i + '】'  + '<p>');
            sum = sum + i ; //sum += i でもOK
            document.write('<p>' + sum + '</p>');
        }
        document.write('<h1>' +  '合計：' + sum  + '<h1>');
</script>
</body>
</html>
Manjaro 21.0.3 がVMWare Playerにインストールできない件について

(執筆 2021/5/6)
# Manjaro 21.0.3をVMWare Playerにインストールすると途中で止まる
　Manjaro 21.0.3は、ディスプレイ関係でVMWareと相性が悪いのか、以下の部分でインストールが止まってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/946112ed-5134-75ff-c1ea-504a2b806797.png)
　VirtualBoxでは、問題なくインストールできるのですが、インストール後、グラフィックコントローラーはVBoxSVGAを使えとメッセージが出てきます。
　VirtualBoxを使っている人は関係ないのですが、VMWare Playerを使いたい方は、Manjaro 20.2.12 をインストールするしかないようです。

# Manjaro 20.2.12 をダウンロード
　旧バージョンをダウンロードするには、https://ja.osdn.net/projects/manjaro/storage/ にアクセスして、xfce、GNOME、KDEのいずれかを選んでダウンロードします。
　インストールは、順調に終わりますので、その後、pacman -Syy を使ってアップデートすれば、 21.0.3 が出来上がります。
pyenv

# インストール

```shell
brew install pyenv
```

```shell
/usr/local/Cellar/pyenv/1.2.27/
```

# 概要

pythonのバージョン管理を行うことができるツール。

- shims

インストールしたpythonは

```shell
$HOME/.pyenv/versions/
```

に格納されている。

# コマンド

|pyenv + _option_||
|:--:|:---|
|install -l|インストールできるpythonバージョンの一覧を確認する|
|install|バージョンを指定してインストールする|
|versions|利用できるpython環境の一覧を確認する|
Arduino ESPrDeveloper Big Sur 対応

困ったのでメモです。

#ESP8266（ESPrDeveloper）に書き込めない！

https://mag.switch-science.com/2020/12/21/macos-espr-developer/

自分はインテルMacですが、書き込めなくて焦りました・・。
これで直りました！

下記、転記です。

ーーーーここからーーーー

```
~/Library/Arduino15/packages/esp8266/hardware/esp8266/2.7.4/tools/pyserial/serial/tools/list_ports_osx.py
```
をテキストエディタで開きます。
~/Library は自分のホームディレクトリの中のLibraryディレクトリのことです。キーボードのOptionキーを押しながらファインダーの「移動」を選ぶと「ライブラリ」というのが選べます。

list_ports_osx.pyの29、30行目に

```
iokit = ctypes.cdll.LoadLibrary(ctypes.util.find_library('IOKit'))
cf = ctypes.cdll.LoadLibrary(ctypes.util.find_library('CoreFoundation'))
```
という記述があるので、その行の先頭に「#」を足してコメントアウトします
その直後(31行目)に

```
iokit = ctypes.cdll.LoadLibrary('/System/Library/Frameworks/IOKit.framework/IOKit')
cf = ctypes.cdll.LoadLibrary('/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation')
```

を追加して保存します。

ーーーーここまでーーーー


Switch Science様、ありがとうございます！！
動作がうまくいかない時（初投稿）

<h2>今回の目的</h2>
<p>今回は初投稿ということでIT初学者（自分も含めて)に向けて
動作が上手くいかない時の対処法について一つアドバイスをしておきたいと思う。
それはズバリ</p>
<h2>とりあえず再起動してみる</h2>
<p><br>
webサイトや教科書と同じようにしていて、自分の設定はうまくできているはずなのに、<br>
なぜかwifiが見つからなかったり、ブラウザが開かなかったり、サーバーと繋がらなかったりすることがある。<br>
こうした原因不明の事態が調べても原因がわからないことが多く、
初学者を苦しめる要因になっている。<br>
そんな時はとりあえず<b>再起動してみる</b>。<br>
すると、なぜかは知らないが突然問題が解決して次のステップに進めるようになることがある。</p>
<h2>ITを学習していくための考え方</h2>
<p>ここで話が逸れるがITを学習する上で大事な考え方について紹介したいと思う。
</p>
>Done is better than perfect.
>完璧よりもまずは完了させろ
>Mark Elliot Zuckerberg  -Facebook共同創業者兼会長兼CEO-

<p>ITは奥が深すぎる。<br>
オープンソースやツールがほぼ自由に使えるがその仕組みを１から全て理解しようとすると果てしない時間がかかる。<br>
一般人である我々にITの天才たちが考え抜いたコードがそう簡単に理解できるはずがないからだ。<br>
そうした中で我々が技術や知識を身につけていくためには全てを理解するのではなく、とにかく手を動かして次に進んでいきその技術の一端を感じることが重要なのである。
</p>
<h2>最後に</h2>
<p>今回の対処法についても知っておくだけで次に進めるかもしれない。<br>
とにかく次に次に進んでいって最終的に自分のツールとして使えることを目指していこう。<br>
拙い文章でしたが最後までありがとうございました。<br>
</p>
Androidエミュレーターのhostsを変更する（hostsがread onlyで編集できない場合）

Flutterでアプリの開発中にホスト名でローカルサーバーを参照させるためにhostsファイルを編集する必要が出てきました。hostsファイルの書き換え手順については色々情報があったのですが、hostsがread onlyで書き換えられない問題で暫くハマってしまったので、書き換え時の一連の流れと解決策を書き留めておきます。

ちなみに、Macでは/etc/hostsを書き換えるだけで素直に読み込んでくれますので非常に楽です。Androidエミュレーターもそういう仕様にして欲しいところです。

#hostsがread onlyで書き換えられない場合の解決策
最初に解決策ですが、SDK PlatformでAPI28以下のものを使用すればできました。現時点では30と29がありますが、そのどちらでも下記のエラーが出ました。

```
adb: error: failed to copy 'hosts' to '/system/etc/hosts': remote couldn't create file: Read-only file system
```

##SDK PlatformをAPI28にする
Android studioのConfigureからSDK Managerを開きAndroid 9.0を選択してインストールします（インストールは暫く時間がかかります）
![SDK.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/930440/706133a2-3856-a2f7-f1f9-c39d1907c250.png)


##デバイスを登録する
Android studioのConfigureからADV Managerを開き、Create Virtual Deviceからインストールしたデバイスを登録します。
![ADV.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/930440/8daf048f-eb99-68a6-3d2f-0d429cf20779.png)

#hostsの書き換え手順
以上の手順が完了したらhostsの書き換えに移ります。以下、Windowsの例です。

コマンドプロンプトを開き、エミュレーターをWritableモードで起動する。

```
> cd C:\Users\ユーザー名\AppData\Local\Android\Sdk\emulator
> emulator -writable-system -avd Pixel_3a_XL_API_28
```

別のコマンドプロンプトを開き、hostsファイルをダウンロードする。

```
> cd C:\Users\ユーザー名\AppData\Local\Android\Sdk\platform-tools
> adb root
> adb remount
remount succeeded

> adb pull /system/etc/hosts hosts
/system/etc/hosts: 1 file pulled, 0 skipped. 0.0 MB/s (56 bytes in 0.002s)
```

この時点でplatform-toolsフォルダにhostsファイルがダウンロードされていると思いますので、最後の行に必要なIPとホスト名を追加します。

hostsファイルを編集したhostsで上書きする。

```
> adb push hosts /system/etc/hosts
hosts: 1 file pushed, 0 skipped. 0.1 MB/s (99 bytes in 0.001s)
```

以下のコマンドでhostsが正常に書き換えられたか内容を確認することができます。

```
> adb shell
> cat /etc/hosts
```

#保存したhostsが元に戻る問題
エミュレーターを再起動するとせっかく変更したhostsファイルが元に戻ってしまいます。これについてはネットで質問している人を見かけましたが、まだ解決策は無いようです。
解決策が見つかったらこの記事で紹介します。面倒ですが、当面はできる限りエミュレーターを起動したままにしておくことで回避することにします。
ディレクトリを作成して作成したディレクトリに移動するコマンドを追加する

# 目的

- ディレクトリを作成してそのディレクトリに移動するコマンドを登録する方法をまとめる

# 条件

- エイリアスファイルが作成されていること。
- .bash_aliasesファイルの読み込みの記載が.bash_profileなどに記載されていること。

# 方法

1. 下記コマンドを実行してエイリアスファイルを開く。

    ```terminal
    $ vi ~/.bash_aliases
    ```

1. 下記の記載をする。

    ```~/.bash_aliases
    function mkcd() {
        mkdir $1;
        cd $1;
    }
    alias mkcd=mkcd
    ```

1. 下記コマンドを実行してエイリアスファイルを読み込む

    ```terminal
    $ source ~/.bash_aliases
    ```
【学习笔记】Leadership: Practical Leadership skills

# 概要
Udemy的关于Leadership的课程。
正好从2020.10开始做PO，合适的时间遇到了合适的课程

https://www.udemy.com/course/practical-leadership/learn/lecture/3665944#overview

# 记忆点
- Captain
    - 身为船长不能全部都顾，而要注重航向，暗礁，冰山等大方向
    - 船长就算被投海，船依然不会在短时间之内失控
- Delegation
    - 各种好处
    - 不这样做的理由
        - 怕手下的人成长超过自己 -> 手下不理应超越自己嘛
        - 自己想做 -> 嘛，的确
        - 其他，，忘了
    - Step
        - Goal。What to do
        - Why important
        - Why you
        - The Limitation
        - Process of going
        - Support anytime
        - Are you OK
        - You can do it
- Style
    - Praise. 称赞实力不够的人
    - Thank. 感谢有实力的人

# 理论
- Maslow
    - 经典金字塔： Survival， Security, Social, Status/Respect， Self actualization
    - 详细: [自己実現理論](https://ja.wikipedia.org/wiki/%E8%87%AA%E5%B7%B1%E5%AE%9F%E7%8F%BE%E7%90%86%E8%AB%96)
- Potatos
    - 作者自创的理论
    - 不同于Maslow的金字塔形状。核心观念是人就像一个番薯好的坏的都有
    - 佐证：梵高，都没有满足Physiological needs，却自我实现了
- Freedom Ladder
    - 有自控能力的人，拥有与之相符合的自由工作的机会

# 推荐的书
- The one Minute Manager
- Don't take the monkey
【JavaScript】1から100までの間で、3の倍数（3〜99）の数だけを足した合計値を表示せよ

```javascript
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8">
   <title>1から100までの間で、3の倍数の数だけを足した合計値</title>
</head>
<body>
<script>
    var sum = 0; 
    for (var i = 1; i <= 100; i++) {
        if (i % 3 === 0) {
        document.write('<p>' +  sum + ' + ' + '【'  + i + '】'  + '</p>');
        sum = sum + i ; //sum += i でもOK
        document.write('<p>' + '= ' + sum + '<p>');
        }
    }
    document.write('<h1>' +  '合計：' + sum  + '<h1>');
</script>
</body>
</html>
```
hashCode が同じはずの自作クラスが HashSet 内で重複してしまう

# TL;DR
HashSet で自作クラスを使用する場合、 `hashCode` メソッドだけでなく `equals` メソッドも準備する必要があります。

# 確認した JDK
```
openjdk version "1.8.0_265"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_265-b01)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.265-b01, mixed mode)
```

# 動かしてみる
次のように、各プロパティフィールドが同じ値を持つ場合は `hashCode()` の結果が同じになるようにしつつ、 `equals` は true とならないクラスを準備します。

```java
public class MyModel {
    private String name;
    private int age;

    public MyModel(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        return false; // ちょうどよいサンプル書くのめんどうなので無理やり false します。
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }
}

```

```java
import org.junit.Test;

import java.util.HashSet;

import static org.junit.Assert.*;

public class MyModelTest {

    @Test
    public void testHashSet() {
        HashSet<MyModel> set = new HashSet<>();

        // 同じプロパティを持つオブジェクトを2つ放り込む
        set.add(new MyModel("taro", 10));
        set.add(new MyModel("taro", 10));

        // hashCode が同じなのでサイズは 1 つになるはず
        assertEquals(1, set.size());
    }

}
```

しかし結果はこうなります。

```
java.lang.AssertionError: 
Expected :1
Actual   :2
```

なので `hashCode` と同じ挙動になるように `equals` をちゃんと実装すると、サイズは1になります。

```java
public class MyModel {
    private String name;
    private int age;

    public MyModel(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        MyModel myModel = (MyModel) o;

        if (age != myModel.age) return false;
        return name != null ? name.equals(myModel.name) : myModel.name == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }
}

```

# なぜ

Java SE 上ではあくまで「このセット内に、`(e==null ? e2==null : e.equals(e2))` となる要素e2がない場合は、指定された要素eをこのセットに追加します。」というように、 `hashCode` でなく `equals` となってるようです。 "Hash"Set なのに…

https://docs.oracle.com/javase/jp/8/docs/api/java/util/HashSet.html#add-E-

OpenJDK では HashSet は内部で HashMap を使用しており、セットする値は HashMap の key として取り扱っています。
なので HashMap の put の実装に依存するわけですね。
このあたりです。

- HashSet::add

https://github.com/openjdk/jdk/blob/jdk8-b120/jdk/src/share/classes/java/util/HashSet.java#L219

- HashMap::putVal

https://github.com/openjdk/jdk/blob/jdk8-b120/jdk/src/share/classes/java/util/HashMap.java#L633-L634
[Kotlin]FuelでPatchリクエストはデフォルト状態では勝手にPostになる

### 事象

とあるAPIがPATCHメソッドを受け付けるので、FuelのPatchメソッドでリクエストしたのですが 400 Bad Requestが返ってきました。

```kotlin
import com.github.kittinunf.fuel.Fuel

Fuel.patch("https://~~~~~~/api/v2/~~~~~~").responseString()
-> 400エラー
```

同じ形式でCURLで叩くと通るので、Fuel側が悪さをしていそうなので調べてみると

> FuelのHttpClientは、PATCHをサポートしていない。
> 内部的にPOSTで送信している

https://ja.getdocs.org/kotlin-fuel/

とのこと。

```kotlin
Fuel.patch("https://httpbin.org/patch")
    .also { println(it) }
    .response { result -> }
```

これで送信すると、

```
/* --> POST (https://httpbin.org/post)
 * "Body" : (empty)
 * "Headers : (3)"
 * Accept-Encoding : compress;q=0.5, gzip;q=1.0
 * Content-Type : application/x-www-form-urlencoded
 * X-HTTP-Method-Override : PATCH
 */
```

こんな感じでPOSTで内部的に送信してしまっているらしいです。
HTTPメソッドが違うので400リクエストを返してきたわけですね。

### 解決方法
公式ドキュメントに書いてありました。

https://github.com/kittinunf/fuel/tree/master/fuel

1.16.x 以降のバージョンで、 `FuelManager.instance.forceMethods = true` を指定

```kotlin
import com.github.kittinunf.fuel.Fuel
import com.github.kittinunf.fuel.core.FuelManager

FuelManager.instance.forceMethods = true
Fuel.patch("https://~~~~~~/api/v2/~~~~~~").responseString()
-> 200 OK
```

これでPatchで送信ができました

```
/* --> PATCH ()
 * "Body" : (empty)
 * "Headers : (3)"
 * Accept-Encoding : compress;q=0.5, gzip;q=1.0
 * Content-Type : application/x-www-form-urlencoded
 */
```
【python】関数の中に関数、引数がないやんけ～クロージャとの出会い～

未だに初心者抜け出せないウーマンです。
久々になんじゃこりゃとなった書き方に出会ったので備忘録として記事にします。

#関数の中に関数、引数がないやんけ。。。
こんな書き方してるコードに出会いました。

```python:
def function_a(x):
    def function_b(y,z):
        ー中略ー
        return b_return
    return function_b
```

function_aの返り値がfunction_bやけど、function_bのところに引数ないやん？？？？
これは何？？？？？？？
無論、function_bという定数がほかのところにあるわけではありません。

そんなわけで調べました。
「python 関数の中に関数 引数 ない」
みたいなかんじで。

当然そんな感じじゃ出てこなかったんですけど、答えは見つかりました。
ありがとう、グーグル先生。

#クロージャというらしい
こういう書き方するやつのことを、「クロージャ」というらしいということがわかりました。
調べを進めていきます。

こういうときはウィキペディアの解説が一番わかりやすかったりするので参照します
[https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3)
が、
今回はなにやら難しいことがいっぱい書いてあります。

その他いろいろ読みましたがjavascript用の解説が多いように感じます。
みんな引っかかるようなものなのかな？

ざっくり以下のようなものだと理解しました

 - 関数の中に関数を書く
 - 状態を保持できる関数

まだまだ理解が追い付いていないので、pythonではどうなんか、ってことを見つつ勉強していきます。

#pythonにおけるクロージャーの使い方って
勉強させていただいたのはこのページです。
ほんとわかりやすいので私のつたない文書読む前にまず読んでほしい。
[https://pg-chain.com/python-closure](https://pg-chain.com/python-closure)

初めのコードを具体化してみていきます。

```python:
def function_a(x):
    def function_b(y,z):
        b_return = x + y + z
        return b_return
    return function_b
```

単純に足し算して値を出してくれるような関数です
これを使う時どうするか、という話ですが、
まずはfunction_aを普通に使う時みたいに書いてみます。

```python:
closure = function_a(10)
```

これだけ見ると定数closureにfunction_aの答えを入れたように見えるのですが
クロージャの場合は違ってきます。
このclosureは「クロージャ変数」というものになっている、とのことです。
だってyとzの値まだわかってないし、答えだせないですよね。
このときclosureはx=10という状態を保持したクロージャ変数になっています。

そしてここからどうするか。

```python:
ans = closure(1,2)
print(ans)
# ans = 13

ans = closure(2,3)
print(ans)
#ans = 15
```

クロージャ変数closureに引数を渡して実行しちゃう！
なんじゃそりゃ！
でも、そう使うんだそうです。

この時closure(1,2)を実行するとfunction_b(1,2)を実行したのと同じこととなって
x+y+zは10+1+2となり答えは13となります。
また、
x = 10という値は保持された状態になっているのでもう一度closureを呼び出し、
ans = closure(2,3)とすると答えは15となるんですねえ。

便利！なのかな？
使い方はわかった！

状態を保持して置けること、
実行したいタイミングをずらせること
なんかが嬉しかったりするのかな。

#終わりに
私と同じように
「python 関数の中に関数 引数 ない」
と検索した人がこの記事にあたって
偉大なる参考ページ様で理解を深められることを祈っております。
azure functionでJSONとかHTMLとかを文字列から返す

## Azure Functionsの例

``` ex.cs
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace LocalFunctionProj
{
    public static class HttpExample
    {
        [FunctionName("HttpExample")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            return name != null
                ? (ActionResult)new OkObjectResult($"Hello, {name}")
                : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
        }
    }
}
```

こんな感じで`OkObjectResult`から何か返すのか、と思ってやっていた。
オブジェクトをJsonに勝手にしてくれたりで便利ではあるが、ファイルからJSON読み込んで、String型を放り込むと、
勝手に`text/plain`になったりして困った。

### `ContentResult`を使う

つまりこういう感じ。

``` ex.cs

namespace LocalFunctionProj
{
    public static class HttpExample
    {
        [FunctionName("HttpExample")]
        public static async Task<IActionResult> RunAsync(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)]
            HttpRequest req, ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");
            
            string text = System.IO.File.ReadAllTextAsync(@"./some_file.txt").Result;
            
            return new ContentResult(){Content = text, ContentType = "application/json"};    
        }
    }
}
```

`ContentResult`を使うと`ContentType`も指定できるので、JSONだろうがHTMLだろうが何でも返せるようになる。
Ruby lastメソッド

# lastメソッドとは
lastメソッドは配列の要素を取り出すときにその配列の中の最後の要素を取得するメソッド。
配列の要素がない場合は`nil`を返す。

 
     
       
## lastメソッドの書き方

```ruby
配列名.last
配列名.last(引数)
```


```ruby
colors = ["red", "blue", "yello", "black"]
puts colors.last
puts colors.last(3)
```

[![Image from Gyazo](https://i.gyazo.com/15ec858e8e7e8cf8151cf56796be3059.gif)](https://gyazo.com/15ec858e8e7e8cf8151cf56796be3059)
情報セキュリティ 【重要用語】

#【情報セキュリティ】

セキュリティとネットワーク大切ですよね。

##ファイアウォール（FW）

外部ネットワークと内部ネットワークの境界に配置し、外部から内部への不正な通信の侵入を遮断する。

##DMZ（非武装地帯）

外部ネットワークや内部ネットワークからも隔離された領域のこと。

外部に公開するサーバをDMZに置けば、外部からの不正アクセスをFWによって遮断できる。
仮にウイルスに感染しても、内部ネットワークにまで被害は及ばない。

##プロキシサーバ（代理サーバ）

LANとインターネットの境界に配置されるサーバのこと。

LAN内のPCの代わりにプロキシサーバ自身のIPアドレスを使用して、インターネットと接続する。
このことによるメリットは、
　・内部ネットワークPCの秘匿化
　・受信したWebページをキャッシュし、通信を高速化
　・キャッシュされた保存ファイルのマルウェアの検出も可能。
　・予め認証されたユーザのみを通信可能にし、フィルタリングの設定も可能。
　・ユーザからの情報を一元管理することも可能。

###リバースプロキシ

インターネットとWebサーバの境界に配置されるサーバのこと。

Web閲覧者からの通信要求をリバースプロキシがWebサーバの代わりに接続を処理する。
このことによるメリットは、
　・インターネットからWebサーバへの接続による外部からのWebサーバへの直接攻撃を防ぐ。
　・処理に時間がかかる暗号化通信のWebサーバの負荷を軽減。
【メモ】環境変数について

#はじめに
Railsでメール認証機能を実装した際、無駄に環境変数を設定してしまったためいらないものを削除したい。

#編集方法
vimで編集する。

```
vi ~/.bash_profile
```

これを実行すると次の様に〜がたくさん出てくるので"i"を押して編集する。

```
export SECRET_KEY='secret'
~
~
~
~
# "i"を押すとINSERTと表示される。
```

編集したら`Esc`を押して、`:wq`と入力し終了する。

環境変数を適用させるには次の様に実行する。

```
source ~/.bash_profile
```

これで環境変数が使える様になる。

```
ENV["SECRET_KEY"]
```

使える環境変数は次のコマンドで確認できる。

```
printenv
```


#削除方法

１ echoで設定されている値を確認

```
echo $PASSWORD
```

2 env, grepコマンドで設定されている値を表示

```
env | grep PASSWORD
```

3 unsetコマンドにより設定されていた値を削除

```
unset PASSWORD
```

4 env, grepコマンドで削除されていることを確認

```
env | grep PASSWORD
```

5 echoコマンドにより削除されていることを確認

```
echo $PASSWORD
```

以上。
Staticプロパティ　swift


#■staticプロパティ(タイププロパティ)とは
同じクラスから生成された複数のインスタンスで同じ定数を使えるようにするもの。

■インスタンスとは

``` swift
class Abc {
   var name = ""
  static sInt = 0
}

//下記のabcにあたる部分  クラスAbcをインスタンス化してインスタンスabcが誕生してる。
var abc = Abc()
var abc2 = Abc()

//これで同じクラスから生成された複数のインスタンスが生まれた
//abcとabc2の事ね
```

これを踏まえて下記を見ていきましょう！

``` swift
class Abc {
   var name = "名前なし"
  static sInt = 0

 func aaa() {
  print("\(name)は\(Abc.sInt)歳です。")
 }
}

var abc = Abc()
var abc2 = Abc()

abc.name = "佐藤健"
Abc.sInt = 100

abc.aaa()
//結果: 佐藤健は100歳です。

abc2.aaa()
//結果: 名前なしは100歳です。

```

なぜこうなる？

■インスタンスプロパティはインスタンスを呼んで値を代入する。
abc.name = "佐藤健"

その場しのぎ
今回の場合はabcのインスタンス内でのみ変更されている。

■staticプロパティは直接型(ここではAbc)を呼んで値を代入している。
Abc.sInt = 100
というような書き方になる。

直接型を呼んで代入してるので
abcのインスタンスがなんや関係なく
とりあえずclassAbcの中のstaticプロパティそのものを変更してる。

___
これを踏まえると
abc2のインスタンスでaaaメソッドを呼んだ時
以前にstaticプロパティのそのものが100に変えられていたので
結果: 名前なしは100歳です。
と言う結果となった。

つまり
同じクラスから生成された複数のインスタンスで同じ定数を使えるようになった。


#■これを応用してちょっとだけ本格的にstaticを使う。
準備
このような画面を作ったとっする。
Buttonを押せばオレンジの画面から青い画面に遷移する。
![スクリーンショット 2021-05-06 17.12.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1099804/3f3aef9b-6341-84a9-4313-f11bfa95969d.png)

■class Akunを準備する。

``` swift
class Akun {
    
    var name = "名前なし"
    static var sInt = 0  
}
```

オレンジ上のラベルをnameLabelとして紐づける。
オレンジ下のラベルをintLabelとして紐づける。
下記のようにコードを書く
![スクリーンショット 2021-05-06 17.24.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1099804/15412a22-202e-32c4-de3f-10535b0dc95c.png)



青い画面のコード

青い上のラベルをnameLabelとして紐づける。
青い下のラベルをintLabelとして紐づける。
下記のようにコードを書く

![スクリーンショット 2021-05-06 17.23.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1099804/220ef625-f1f3-0318-1d0b-d513c61cb799.png)


■結果
オレンジ画面
nameLabelは佐藤健
intLabelは100
![スクリーンショット 2021-05-06 17.26.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1099804/507b99a9-2310-d0ad-ed44-3f35448960da.png)

Buttonを押して青い画面に遷移
nameLabelは名前なし
intLabelはstaticプロパティ使ってて
以前に100に直接値変えられているので100になった。

![スクリーンショット 2021-05-06 17.26.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1099804/297773b3-fd15-5177-ad40-1349a55b6094.png)


同じクラスから生成された複数のインスタンスで同じ定数を使えている。

これがstaticプロパティ!!!!!!!!!
1500円ZYNQ基板のXADCを使えるようにする

#はじめに
1500円 ZYNQ 基板( EBAZ4205 )で、内蔵 A/D コンバータ XADC の回路を修正して、使用できるようにします。

Xilinx の 7 シリーズ以降の FPGA (ZYNQ-7000 も含む)では、XADC を使って、内部温度や電圧がモニタできるようになっています。

標準で装備されている機能なので、XADC の回路を FPGA で作らなくても読めるはずなのですが、EBAZ4205 では読めません。
電圧はいつどれを計っても 0V ですし、温度は絶対零度(-273.1℃)を示します。
![0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/211ed794-e918-d6a6-72dd-674b9e5c84f2.png)

基板を修正して、正しく読めるようにしたいと思います。

#使用環境
1. Windows10 Pro (20H2)
2. Vivado 2020.1 (Windows 版)
3. EBAZ4205


#参考資料
[UG480 7 Series FPGAs and Zynq-7000 SoC XADC Dual 12-Bit 1 MSPS Analog-to-Digital Converter](https://www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf)


#XADC が使えない原因
UG480 の Figure 1-2 に、XADC の回路例が記載されています。

・ADC の基準電圧に、高精度の外部電圧源(±0.2%)を使う方法 (左)
・FPGA 内部の基準電圧源(on-chip reference、±1%)を使う回路 (右)

2種類のどちらかの回路で使用します。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/2e7c158b-030e-25a2-54c3-40e29dac0b96.png)

EBAZ4205 の回路図を確認してみると、XADC の電源端子(VCCADC_0 = J9 ピン)に、電源が供給されていません。
下図で、C327 の 100nF だけが接続されています。

電源が供給されていないため、XADC が動作しなくなっています。
外部基準電圧源の回路も用意されていますが、部品は搭載されていません。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/185c76e1-f354-9e48-af4f-0106256ecd2e.png)


#回路の修正方法
今回は、内部の基準電圧源を使う回路で、XADC を動かします。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/08c69033-c0fa-6a8e-0f17-75f3e6ea7a19.png)

VCCADC_0 には 1.8V のアナログ電源を供給する必要があります。
基板上では、VCCA として 1.8V が生成されていますので、ここから供給します。

VCCADC_0(J9) ピンにアクセス可能なのは、C327 だけです。
ここに 1.8V 電源を接続します。

1.8V の供給元は、基板上で C327 の隣にある C2354 か R1493 が適当です。
例では、C2354 からジャンパで接続しました。

VREFP_0 と VREFN_0 の間も C664 で分離されてしまっています。
Figure 1-2 に合わせて、VREFP_0-VREFN_0 間を直結にします。
例では C664 の上からジャンパでショートしています。
(C664 を 0Ω 抵抗に交換しても良いです)

基板の改造例を示します。
![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/488d364d-a30a-fc59-ca77-99e1aba2d1b9.jpeg)



#XADC の動作確認
基板が改造できたら、動作を確認します。

システムモニタが有効になるのは、FPGA にダウンロードが完了してからです。
PetaLinux が起動すると、見えなくなってしまいます。
u-boot で止めるか、PetaLinux を起動せずに適当な .bit をダウンロードして観察します。

Vivado で Open Hardware Manager して、ダウンロードケーブルとデバイスを認識させると、右側の dashboard にシステムモニタのグラフが表示されます。
初期状態だと温度表示だけですが、各電圧の項目を追加することができます。

下は、u-boot で止めて、何もしていない時の温度と電圧の推移です。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/0b5d0d66-cb10-1eab-2740-0e999a4eeaec.png)

・VCCINT/VCCBRAM/VCCPINT が 1.0V 付近
・VCCO_DDR が 1.5V 付近
・VCCAUX/VCCPAUX が 1.8V 付近
・温度が 44.7℃

となっていて、正しい値を示しています。

FPGA に何か処理させると、消費電流が増えて電源電圧が少し下がるのと、内部温度が上昇します。

---

下記は、EBAZ4205 で Zybo Z7-10 の HDMI デモを動かした時のシステムモニタ表示です。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/e26d92b8-7645-5a80-8119-2c0da1bc9622.png)
電源電圧がそれぞれ少しづつ低くなり、温度は 60.2℃ を示しています。

グラフは 1 秒毎に更新されます。
FPGA 表面を指で触れると熱が吸収されて、すぐに表示温度が下がるのが観察できます。



#まとめ
EBAZ4205 基板を改造して、XADC が使用できるようになりました。
【Node.js & Windows10】プログレスバー付のトースト通知を表示する

# この記事の目的
Node.js経由でWindows10 のプログレスバー付のトースト表示を表示させる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1123247/d024012d-6c3d-92ce-fdbb-16b46e06fb4a.png)

# 前提条件
以下のモジュールがインストールされていることを前提とします。

* @nodert-win10-rs4/windows.ui.notifications
* @nodert-win10-rs4/windows.data.xml.dom

今回はnodert-win10-rs4でテストしていますが、`nodert-win10-20h1`など、別のバージョンでも動くと思います。
NodeRTのインストールは一筋縄では行かないことがありますが、他のQiita記事等を参照することで解決できます。
# コード
## トーストの作成
```js
  const xml = require("@nodert-win10-rs4/windows.data.xml.dom");
  const {
    ToastNotification,
    ToastNotificationManager,
    NotificationData,
  } = require("@nodert-win10-rs4/windows.ui.notifications");

  /* トーストのXML　参照： https://docs.microsoft.com/en-us/uwp/schemas/tiles/toastschema/schema-root */
  const msgTemplate = `<toast>
	<visual>
		<binding template="ToastGeneric">
			<text>通知テスト</text>
			<progress value="{progressValue}" valueStringOverride="{progressValueString}" status="{progressStatus}"/>
		</binding>
	</visual>
</toast>`;
  /* アプリケーションID */
  const appId =
    "{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\\WindowsPowerShell\\v1.0\\powershell.exe";

  /* トーストのTag, Group */
  let tag = "tag";
  let group = "group";

  let toastXml = new xml.XmlDocument();
  toastXml.loadXml(msgTemplate);
  let toast = new ToastNotification(toastXml);
  toast.tag = tag;
  toast.group = group;
  /* 作成したトーストのイベント */
  toast.on("activated", function (sender, eventArgs) {
    // onActiviation();
  });

  toast.on("dismissed", function () {
    //  onDismissal();
  });

  /* プログレスバーの設定*/
  let d = {};
  d["progressValue"] = 0.2;
  d["progressValueString"] = "文字";
  d["progressStatus"] = "ステータス";
  toast.data = new NotificationData(d, 1);
  /* トースト表示 */
  ToastNotificationManager.createToastNotifier(appId).show(toast);
```
`msgTemplate`はトーストの内容を定義するXMLです。XMLを変更すれば、画像やボタンを追加することができます。
[https://docs.microsoft.com/en-us/uwp/schemas/tiles/toastschema/schema-root](https://docs.microsoft.com/en-us/uwp/schemas/tiles/toastschema/schema-root)などを見ながらXMLを作成することができますが、Visual Studioで`ToastContentBuilder`を使ってトーストを作った後、`GetXml()`でXMLを出力して貼り付けた方が早いかもしれません。

`appId`は、`アプリケーションユーザーモデル ID`を渡します。このIDは実際にWindows 10上にインストールされているアプリケーションのIDを渡さないと通知されないようです。
このIDはPowershellで`get-AppxPackage`コマンドを実行すると取得できます。先に挙げたコード例では、PowershellのIDを設定しています。

## トーストの更新
以下のコードを呼び出すことでトーストを更新することができます。

```js
  let d = {};
  d["progressValue"] = 0.9;
  d["progressValueString"] = "文字2";
  d["progressStatus"] = "ステータス2";
  ToastNotificationManager.createToastNotifier(appId).update(
    new NotificationData(d, 2),
    tag,
    group
  );
```

# Electronでの通知
例えばElectronでは、OSで実装されている通知機能を用いて通知を作成することができます。実際に通知を行ってみると、Windows 10では以下のようなトースト表示が行われます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1123247/1f139201-b7f0-8fdf-833e-e4db0b7ae509.png)

しかし、これ以上に機能を拡張したトーストを表示することはできません。もしも画像やプログレスバーを付加したトーストを表示させたい場合は、今回のような方法で実現可能です。
ただし、` electron-rebuild`を用いて、トースト表示に必要なモジュールをリビルドする必要があります。
Ruby firstメソッド



# firstメソッドとは
firstメソッドは配列の要素を取り出すときにその配列の中の最初の要素を取得するメソッド。
配列の要素がない場合は`nil`を返す。

## firstメソッドの書き方

```ruby
配列名.first
配列名.first(引数)
```

引数がある場合は配列の中の最初の要素からその引数の数の要素を配列で返す。

```ruby
foods = ["sandwich", "tacos", "sushi", "nuts", "pasta"]
puts foods.first
puts foods.first.(2)
```

[![Image from Gyazo](https://i.gyazo.com/0735af075c787ddb46e944f11c1eb876.gif)](https://gyazo.com/0735af075c787ddb46e944f11c1eb876)

> 参考サイト
[TechAcademy](https://techacademy.jp/magazine/20570)