OmniAICreator/Qiita-1.07M huggingface dataset:
[python] 配列のコピー時の注意

#Pythonはオブジェクト指向あるよ


```python:
list1=list2
```
list2の中身をlist1に移行しよう!なんて考えてこう書くと終わりです
(指し示すオブジェクトが同じになってしまうっぽい)
#正しい書き方
**copy.deepcopy**を使うといいぽい

```python:
import copy
list1=list2#ダメ
list1=copy.deepcopy(list2)#いい感じ
```

覚えておこうと思いました
【React】Store階層が深いときのReducerの書き方

# Reducer の書き方について
皆さん、初めまして！
エンジニアの t-77 と申します。
日々開発をしている中で、疑問に思ったことや分からなかったことをつらつらと書いていこうと思っています。
今回は、Storeの階層が深い場合のReducerの書き方です。

## Store と Reducer の構造
早速コードですが、「Const defaultState = {}」が、Store構造になっています。
その下の「export default function (state = defaultState, action) {}」が、Storeを更新するための記述になります。

```ruby:Reducer.js
import * as ActionTypes from '../constants/ActionTypes';
  const defaultState = {
		 cars: {
		   carA: '',
		   carB: '',
		 },
		 animals: {
		   dogs: {
		     dogA: '',
		     dogB: '',
		   },
		 },
  };
  export default function (state = defaultState, action) {
    switch (action)
    /* Storeの階層が2段階のとき*/
    case "CARS_NAMES_UPD":
      return {
        ...state,
        cars: {
          ...state.cars,
          /* carA・carBに対して、更新したい値をそれぞれ直接渡しているパターン*/
          carA: 'lamborghini',
          carB: 'jeep',
        },
      },
    };
    /* Storeの階層が3段階のとき*/
    case "DOGS_NAMES_UPD":
      return {
        /* 階層に従って、更新する情報を記述する*/
        ...state,
        animals: {
          ...state.animals,
          dogs: {
            ...state.animals.dogs,
            /* dogA・dogBに対して、更新したい値をそれぞれactionを介して渡しているパターン*/
            dogA: action.dogA,
            dogB: action.dogB,
          },
        },
      },
    }; 
  default:
    return state;
    }
  }
```

最も注意すべきことは、「**Store の階層通りに配置すること**」です。
Storeの階層が３段階になっているにも関わらず、階層を1つでも飛ばして記述してしまった場合、PropsやStateの構造が壊れてしまい、正しく値を利用できなくなってしまいます（自分は、この現象でだいぶ苦しみました）。

また、下のコードのように「...state,」を何度も繰り返して記述してしまうと、その都度Stateが書き換えられ、先にdefauへ登録した値やdefaultStateが消えてしまうといった事態が起こります。絶対にやめましょう。

```ruby:Reducer.js
  export default function (state = defaultState, action) {
    switch (action)
    /* Storeの階層が3段階のとき*/
    case "DOGS_NAMES_UPD":
      return {
        ...state,
        animals: {
          ...state.animals,
          ...state,
          dogs: {
            ...state.animals.dogs,
            dogA: action.dogA,
            dogB: action.dogB,
          },
        },
      },
    }; 
  default:
    return state;
    }
  }
```

# まとめ
- **Store の階層通りに、case の return 内を構成すること**
- **「...state,」の記述は、1つの階層の流れにつき、1度だけ**

今回は、以上になります。ご覧いただき、ありがとうございました！
ご指摘などありましたら、ぜひお願いいたします。
Java 8 ドキュメントまとめ

主に公式 (または公式に準ずる) ドキュメントへのリンクをまとめる。

## 日本語ドキュメント

- [Java Platform Standard Edition 8ドキュメント](https://docs.oracle.com/javase/jp/8/docs/)
- [Javaプログラミング言語の拡張機能](https://docs.oracle.com/javase/jp/8/docs/technotes/guides/language/enhancements.html)
- [JDK 8の新機能](https://www.oracle.com/technetwork/jp/java/javase/overview/8-whats-new-2157071-ja.html)
- [Java(tm) Platform, Standard Edition 8 API仕様](https://docs.oracle.com/javase/jp/8/docs/api/)

## 英語ドキュメント

- [Java Platform Standard Edition 8 Documentation](https://docs.oracle.com/javase/8/docs/)
- [Java™ Platform, Standard Edition 8 API Specification](https://docs.oracle.com/javase/8/docs/api/)

## 言語仕様

- [The Java® Language Specification, Java SE 8 Edition](https://docs.oracle.com/javase/specs/jls/se8/html/)

## JVM 仕様

- [The Java® Virtual Machine Specification, Java SE 8 Edition](https://docs.oracle.com/javase/specs/jvms/se8/html/)

## リリースノート

- [JDK 8 Update Release Notes](https://www.oracle.com/technetwork/java/javase/8u-relnotes-2225394.html)

## OpenJDK

- [JDK 8](https://openjdk.java.net/projects/jdk8/)
- ソースコード: [jdk8/jdk8: log](https://hg.openjdk.java.net/jdk8/jdk8/)
- ソースコード: [jdk8u / OpenJDK Mercurial Repositories](https://hg.openjdk.java.net/jdk8u)

## その他

- [Java SE の概要](https://www.oracle.com/technetwork/jp/java/javase/overview/index.html)
- [Java SE　日本語ドキュメントアーカイブ](https://www.oracle.com/technetwork/jp/java/java-sun-1440465-ja.html)

- Oracle JDK 8
  - リリース: 2014年3月18日
  - 一般ユーザー (Commercial Use) 向け期限: 2019年1月
  - 個人ユーザー (Non Corporated Desktop Use) 向け期限: 2020年12月
  - Premier Support 期限: 2022年3月
  - Extended Support 期限: 2025年3月
  - Sustaining Support 期限: 無期限
  - [JDKの新しいリリース・モデル、および提供ライセンスについて](https://www.oracle.com/technetwork/jp/articles/java/ja-topics/jdk-release-model-4487660-ja.html)
  - [Oracle Java SE サポート･ロードマップ](https://www.oracle.com/technetwork/jp/java/eol-135779-ja.html)
  - [Lifetime Support Policy \| Oracle Support \| Oracle 日本](https://www.oracle.com/jp/support/lifetime-support/)
  - [日付別のJava 7およびJava 8リリース](https://www.java.com/ja/download/faq/release_dates.xml)

- RedHat 提供 OpenJDK 8 バイナリ (Red Hat Enterprise Linux, Windows Server で動作する)
  - サポート期限: 2023年6月
  - [OpenJDK Life Cycle and Support Policy \- Red Hat Customer Portal](https://access.redhat.com/articles/1299013)
  - [OpenJDK ライフサイクルおよびサポートポリシー \- Red Hat Customer Portal](https://access.redhat.com/ja/articles/1457743)

- Amazon Corretto 8 (Linux, Windows, macOS, Docker で動作する Amazon 提供 OpenJDK 8 バイナリ)
  - サポート期限: 最短でも2023年の6月まで
  - [Amazon Corretto（本番環境に対応したOpenJDKディストリビューション）\| AWS](https://aws.amazon.com/jp/corretto/)
  - [よくある質問 \- Amazon Corretto \| AWS](https://aws.amazon.com/jp/corretto/faqs/)
apache配下でLaravelを動かしてみる

2019年8月9日

環境構築自体は以下の記事を見てね。

[centos7にLAMP環境を作ってみる](https://qiita.com/apricotcomic/items/e0e44515e9bb371bcfeb)
[Laravelをインストールしてみる](https://qiita.com/apricotcomic/items/9b25a4447a1a8bffc9ca)

#Laravelをapache配下にインストールする
apacheで動かすため、Laravelを/var/www配下にインストールする。

```
$ cd /var/www　←　/var/wwwに移動
$ composer create-project laravel/laravel laratest　←　「laratest」というプロジェクトを作成
```

「application key set successfully.」まで表示されれば完了。

#apacheにvirtual hostを設定する
なんとなくapache全体をlaravel用にしてしまうのがあれなので、virtual hostの設定をして、laratest用のサブドメインを設定する。

###virtual host用のconfファイル作成
/etc/httpdの下にvirtual host設定用のconfファイルを格納するディレクトリを作成する。

```
# mkdir /etc/httpd/vhost.d
```

virtual hostをconfファイルに設定する。

```conf:laratest.conf
<VirtualHost *:80>
  DocumentRoot /var/www/laratest/public
  ServerName test.lalatest.com
</VirtualHost>
```

vhost.dに保存したconfファイルを取り込むように、httpd.confを変更する。

```conf:httpd.conf

(最終行に追加）
include /etc/httpd/vhost.d/*conf
```

これで、vhost.dに格納されているconfファイルがhtpd.confに取り込まれるようになる。
httpd.confを変更したらhttpdを再起動すること。

本当はServerNameに設定したurlはDNSサーバーに設定しておいて、そのurlでVirtual hostにアクセスするのがいいのだが、そこまでするのも面倒なので、アクセスはipアドレス直でアクセスする。
本気で複数のurlに分けたい場合は、ポートを分けるかちゃんとDNSで名前解決するようにするかする。

##!!Attention!!logが書けない
上記設定でゲストOSのIPアドレスにアクセスすると、laravelにつながるが、「The stream or file "/var/www/laratest/storage/logs/laravel-2019-08-10.log" could not be opened: failed to open stream: Permission denied」こんなメッセージが出る。
LOGのパーミッションがよろしくないのね、と下記サイトを参考に修正したが、状況変わらず。
[CentOS/Apache/Laravel使用時のpermission設定方法](https://qiita.com/Todate/items/d0d5c38f62621711a79b)

この設定を追加したら、上手くアクセスできた。
[laravel5のインストールで、ファイルパーミッションエラー](http://momoiro-tj.hateblo.jp/entry/2016/01/12/221657)

整理すると、たぶんこんな感じ。
・laravelの下記ディレクトリについて、アクセスできるグループとパーミッションを確認する。
  ./storage
  ./bootstrap/cache

それでもパーミッションエラーになる場合、selinuxに邪魔されている可能性大。
下記コマンドでコンテキストを設定する。

```
# semanage fcontext -a -t httpd_sys_rw_content_t "[laravel projectのディレクトリ]/storage"
# semanage fcontext -a -t httpd_sys_rw_content_t "[laravel projectのディレクトリ]/bootstorage/cahce"
```

ちなみに通常apacheで使用するディレクトリには、「httpd_sys_content_t」が設定されているが、上記のディレクトリには「httpd_sys_**rw**_content_t」を設定しないといけない。
しかしselinuxはろくなことしないな…

#アクセス確認
ゲストOSのipアドレスでアクセスすると、laravelのページが表示される。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/98498f6c-2e5a-9f7c-188b-de5059f932b6.png)|
|:-:|

#Appendix 複数のLaravel環境を動かいしたいとき
以下のサイトが参考になりました。
[HomesteadでLaravelのプロジェクトをローカル開発環境に2つ作りたいが'homestead-7'は既に存在しているというエラーが出る解決済](https://teratail.com/questions/86362)
[Homesteadを使って複数のLaravelプロジェクトを作成する簡単な方法](https://qiita.com/Yorinton/items/08ec8fefcbec71513399)
便利ページ：Javascriptで暗号化など追加

[便利ページ：Javascriptでちょっとした便利な機能を作ってみた](https://qiita.com/poruruba/items/6c67c7eef34ed302feb3) のシリーズものです。

今回は、[WebAuthnを使ったFIDOサーバを立ててみた](https://qiita.com/poruruba/items/243d39c8b77b98a99bab) の実装をしていたところ、何かと便利になりそうなことがありそうだったので、追加してみようと思いました。

* バイナリのBase64エンコード
* Base64URLエンコード
* 文字列のバイト配列変換
* HMAC(SHA256)生成、AES暗号化

毎度の通り、デモページとGitHubです。

GitHub
　https://github.com/poruruba/utilities

デモページ
　https://poruruba.github.io/utilities/

# バイナリのBase64エンコード

画像などのバイナリデータをJSON等で送る場合によく使われているようです。確かに、16進数文字列にするより、サイズ的に効率的ですね。

Webにたくさん転がっていましたので、盲目的に採用させていただきました。

```js
function bufferToBase64(buf) {
    if( buf instanceof ArrayBuffer )
        buf = new Uint8Array(buf);
    if( buf instanceof Uint8Array )
        buf = Array.from(buf);

    var binstr = buf.map(b => String.fromCharCode(b)).join("");
    return btoa(binstr);
}

function base64ToBuffer(b64) {
    var binstr = atob(b64);
    var buf = new Uint8Array(binstr.length);
    Array.from(binstr).forEach((ch, i) => buf[i] = ch.charCodeAt(0));
    return buf;
}
```

# Base64URLエンコード

BASE64URLとは、Webにおいて主にバイナリデータの送受で使われているようで、Base64エンコードに対して、Webで扱いやすいように、「+」を「-」に、「/」を「_」に置き換え、パディングも省略されたもののようです。
以下のモジュールを使わせていただきました。

Base64URL-ArrayBuffer
　https://github.com/herrjemand/Base64URL-ArrayBuffer

# 文字列のバイト配列変換

これも、Web上にたくさん情報がありますが、使いたい時にさっと使えるように、便利ツールに追加しました。

```js
var encoder = new TextEncoder('utf-8');
output = encoder.encode('文字列');
var decoder = new TextDecoder('utf-8');
output = decoder.decode(バイト配列);
```

# HMAC(SHA256)生成、AES暗号化

暗号演算には、以下のモジュールを使わせていただきました。

crypto-js
　https://github.com/brix/crypto-js

以下に、使い方の説明ページがあったので、すんなり実装できました。
　https://cryptojs.gitbook.io/docs/

具体的には、ソースコードを見ていただくとして、なぜ便利ツールに追加したかというと、AWS Cognitoのカスタム認証フローにSECRET_HASHなる仕様で必要だったためです。実装したものの、あまり使う機会がなく、忘れてしまいそうでした。

今回とはちょっと横道にそれますが、こんな感じだそうです。

```js
function makeSecretHash(username, client_id, client_secret){
    var hash = CryptoJS.HmacSHA256(username + client_id, client_secret);
    var result = wordarray_to_uint8array(hash);
    return bufferToBase64(result);
}

var secretHash = makeSecretHash(this.username, UserPoolClientId, UserPoolClientSecret);
var params = {
  AuthFlow: 'CUSTOM_AUTH',
  ClientId: UserPoolClientId,
  AuthParameters: {
    'USERNAME' : this.username,
    'SECRET_HASH' : secretHash
  }
};
do_post_aws(CognitoUrl, params, 'AWSCognitoIdentityProviderService.InitiateAuth' )
```

以上
Spring Boot で Rest API 構築

# Outline

- 手探りで Spring Boot を勉強しながら Rest API を構築していく
- Qiita にはやった分だけ投稿していく

# Create New Project

IntelliJ の Spring Initializr を使う
![190817-0003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21296/d8582bd0-5ae4-4b3a-ca41-16934f10dbe5.png)

## Spring Initializr

Project SDK: 1.8
Choose Initializr Service URL: Default (https://start.spring.io)

## Project Metadata

Group: com.example
Artifact: spring-boot-rest-api
Type: Gradle Project (Generate a Gradle based project archive)
Language: Java
Packaging: Jar
Java Version: 8
Version: 0.0.1-SNAPSHOT
NAME: spring-boot-rest-api
Description: Demo project for Spring Boot
Package:  com.example.springbootrestapi

## Dependencies

Developer Tools: Spring Boot DevTools, Lombok
Web: Spring Web Starter
SQL: Spring Data JPA, MySQL Driver

## Project Settings

Project name: spring-boot-rest-api
Project location: 適宜

## Import Module from Gradle

一旦デフォルト設定のまま
OKでプロジェクト作成が完了

# IntelliJ で Lombok 有効化

こちらを参照
https://reasonable-code.com/intellij-lombok/

# 設定ファイルを yml に変更

`spring-boot-rest-api/src/main/resources/application.properties`

リネームする

`spring-boot-rest-api/src/main/resources/application.yml`

# とりあえず起動してみる
Run ボタンを押す
![190817-0005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21296/202acab2-bbdd-8176-5c02-bc266eb0c964.png)

エラーになった

```
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-08-17 23:19:54.141 ERROR 29198 --- [  restartedMain] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class


Action:

Consider the following:
	If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
	If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).


Process finished with exit code 0
```

# 続きの予告

- [エラーの調査](https://qiita.com/sawa-@github/items/37d8d5679cf7f9533a4d)
- [Docker で MySQL 構築](https://qiita.com/sawa-@github/items/09d108f7b540ff86b2dc)
- Swagger を使って API の設計を行う
Python3のprint関数で改行しない方法、sleep併用の時

## Python3のprint関数で徐々に表示したいとき

引数flushを使います。実践的にはプログレスバー的な表示をしたいときなど。

```
print("hello", end='', flush=True) 
```

元々やりたかったのは、こんな感じで進行状況を示す表現。

```
i = 0
while i < 10:
    print(".", end='', flush='True')
    time.sleep(1)
    i += 1
print("ok!")

..........ok!
```

デフォルトで改行時にバッファから一気に出力する設定なので、バッファをフラッシュ、即時出力させる設定に変えるとうまくいきます。こういう、依存関係のあるオプションは落とし穴だ。。




# 以下、蛇足

Python3のprint関数、普通に書くと改行します。

```
print("Hey,")
print(" hello")
print(" world!")

Hey,
 hello
 world!
```

改行したくない時、引数endを設定する方法があります。

```
print("Hey,", end='')
print(" hello", end='')
print(" world!")

Hey, hello world!


うまくいきました。デフォルト値としてend='\n'が設定されているので、何も指定しないときには改行していたのです。
```

では、この1行を1ワードづつ区切りながら、くりかえしてみよう。。あれ？

```
import time
while True:
    print("Hey,", end='')
    time.sleep(1)
    print(" hello", end='')
    time.sleep(1)
    print(" world!")
    time.sleep(1)

Hey, hello world!
3秒後
Hey, hello world!
3秒後
Hey, hello world!
：

1ワードずつ表示したかったのに、3秒毎に、1行全部が表示されます。
```

これは、デフォルトで「flush='Flase'、バッファに貯めておいて、改行が来たら一気に表示する設定」になっているからです。改行しない設定のために途中経過が見られなくなってしまいました。



では、```flush='True'```を使って、、

```
import time
while True:
    print("Hey,", end='', flush='True')
    time.sleep(1)
    print(" hello", end='', flush='True')
    time.sleep(1)
    print(" world!", flush='True')
    time.sleep(1)

思い通り、1ワードづつ区切りながら、くりかえして表示できました。
```

## 公式ドキュメントで調べる

Python3のprint関数、他にも引数があります。
https://docs.python.org/ja/3/library/functions.html#print


```
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)


print("hello") とだけ書くと、こういうこと。
print("hello", sep=' ', end='\n', file=sys.stdout, flush=False)

```

sepは、separation、コンマ区切りのときの間の文字。デフォルトではスペース。
file= sys.stdoutは、出力先。デフォルトでは、システムの標準出力。

```
print(1,2,3)
1 2 3

print(1,2,3, sep=' - ')
1 - 2 - 3
```

以上。
JavascriptのPromiseを理解して、非同期処理を読み解く


#はじめに

最近、ブロックチェーンプラットフォームのHyperledger Fabricを勉強しています。

そこで、勉強のためにNode.jsで書かれているサンプルコードを読んでいたのですが、コードの端々に出てくる「await」って奴が何か分からず、調べてみることにしました。

ちなみに読んでいたのはサンプルコード「Fabcar」の「query.js」です。
URL：https://github.com/hyperledger/fabric-samples/blob/release-1.4/fabcar/javascript/query.js


#awaitとは何か？

まずは簡単にググってみると、どうやら**Promiseによる非同期処理をより簡潔に記述できる方法**らしいのです。

ふーん、なるほど！

って、恥ずかしながらPromiseがなんなのかを知りません。これはPromiseを理解する必要がありそうですね。


#promiseとはなにか？

まずJavaScriptには**非同期処理**といって、前の処理の終了を待たずに次の処理が動くという性質があります。

でもそれでは都合の悪い場合もあるので、「非同期じゃなくて、この順序通りにやってほしい」という場合には、**コールバック関数**というものを使っていました。

ところがコールバック関数で記述すると、どんどん処理がネストしていっちゃって、物凄く読みにくいんですよね。

そんな困った問題を解決してくれたのが、**Promise**という訳です。


と、ここまでは良かったのですが、実際の記述については、ネットではなかなかまとまった情報が見つからず苦戦しました。そんな中で、以下のサイトは群を抜いて分かりやすく体系的な説明がされていて、とても参考になりました。おすすめです！

**Javascript Promiseの本**
https://azu.github.io/promises-book/#chapter1-what-is-promise


以下で、大事そうなところを、自分なりにまとめてみます。

##Promiseの特徴
Promiseオブジェクトを使用して非同期処理を書くことで、コールバック関数を使用した非同期処理よりも、すっきりと直感的に同期処理を記述できる。

##Promiseを使った処理の流れ

1. コンストラクタで、Promiseオブジェクトを作成する（オブジェクト内に非同期処理を記述）
2. 作成したPromiseオブジェクトに対し、.thenメソッドで正常処理を記述する（異常処理は.chatchメソッドで記述できる）


##Async Function

>Async Functionは通常の関数とは異なり、必ずPromiseインスタンスを返す関数を定義する構文です。Async Functionは次のように関数の前にasyncをつけることで定義できます。

つまり、asyncを関数の頭につけると、関数の戻り値はかならずPromiseインスタンスでなくてはならない。またresolveでなく、returnで値を返却することができる。

##wait式

>wait式は右辺のPromiseインスタンスがFulfilledまたはRejectedになるまで、その行（文）で非同期処理の完了を待ちます。 そしてPromiseインスタンスの状態が変わると、次の行（文）から処理を再開します。

つまり、**完了するまで次の行を実行して欲しくない場合に、awaitをつければ良い。**


#結論

非同期がらみの部分って複雑で、今まで敬遠してしまっていましたが、Awaitを使えば直感的にコードを書けるようになりそうです。

また、当初の問題だった「Fabcar」の「query.js」も、PromiseとAwaitを理解したら、きちんと読めるようになりました！
作業用ブランチで作業していたつもりがmasterブランチで作業してしまった時の対処法

#対処法

###1.Commitする前に変更内容を一旦退避

```
$ git stash (save)
```
`stash`(退避場所)へ移す。`save`は省略可。
masterブランチは作業前の状態に戻り、`git status`で確認すると修正内容は消えている。



###2.本来作業予定だったブランチへの切り替え
```
$ git checkout <切り替えたいブランチ名>
```
ブランチの切り替え、新規作成の場合は`checkout -b　ブランチ名`

###3.退避させていた変更内容を適用
```
$ git stash pop #stashを適用後、ファイルを削除
$ git stash apply #stashを適用後、ファイルを残す
$ git stash pop stash@{N} # N番目のスタッシュを適用後、ファイルを削除
```
Nは`git stash list`で確認。

#masterブランチでCommitまで済ませてしまった場合の対処法

###1.Commit前の状態に戻してから、前述の「対処法」１〜３を実行
```
$ git reset --soft HEAD^
```
`--soft`：変更内容を残す
`HEAD^`：直前のコミット

#その他`stash`関連コマンド
```
$ git stash show stash@{N} # N番目にスタッシュしたファイルの一覧表示
$ git stash show -p stash@{N} # N番目にスタッシュしたファイルの変更差分を表示
$ git stash drop # 最新のスタッシュを削除
$ git stash drop stash@{N} # N番目のスタッシュを削除
$ git stash -k # unstage ファイル全てスタッシュ
$ git stash -u # untrackファイルも含め全てスタッシュ
$ git stash clear # スタッシュを全削除
```
Java 11 ドキュメントまとめ

主に公式 (または公式に準ずる) ドキュメントへのリンクをまとめる。

## 日本語ドキュメント

- [JDK 11ドキュメント \- ホーム](https://docs.oracle.com/javase/jp/11/)
- [Java Platform, Standard Edition Oracle JDK 移行ガイド,リリース11](https://docs.oracle.com/javase/jp/11/migrate/) 
- [Java® Platform, Standard Edition & Java Development Kit バージョン11 API仕様)](https://docs.oracle.com/javase/jp/11/docs/api/)

## 英語ドキュメント

- [JDK 11 Documentation \- Home](https://docs.oracle.com/en/java/javase/11/)
- [Java® Platform, Standard Edition & Java Development Kit Version 11 API Specification](https://docs.oracle.com/en/java/javase/11/docs/api/)

## 言語仕様
- [The Java® Language Specification, Java SE 11 Edition](https://docs.oracle.com/javase/specs/jls/se11/html/index.html)

## JVM 仕様

- [The Java® Virtual Machine Specification, Java SE 11 Edition](https://docs.oracle.com/javase/specs/jvms/se11/html/index.html)

## リリースノート

- [JDK 11 Release Notes](https://www.oracle.com/technetwork/java/javase/11-relnotes-5012447.html)
- [JDK 11 Release Notes, Important Changes, and Information](https://www.oracle.com/technetwork/java/javase/11-relnote-issues-5012449.html)
- [Java Development Kit 11 Update Release Notes](https://www.oracle.com/technetwork/java/javase/11u-relnotes-5093844.html)

## OpenJDK

- [JDK 11](https://openjdk.java.net/projects/jdk/11/)
- ソースコード: [jdk/jdk11: log](https://hg.openjdk.java.net/jdk/jdk11)
- [Dashboard \- OpenJDK Wiki](https://wiki.openjdk.java.net/)

## その他

- [Java SE の概要](https://www.oracle.com/technetwork/jp/java/javase/overview/index.html)
- [Java SE　日本語ドキュメントアーカイブ](https://www.oracle.com/technetwork/jp/java/java-sun-1440465-ja.html)
- [Java Platform, Standard Edition 11 Reference Implementations](http://jdk.java.net/java-se-ri/11)
- [Java SE 11 \(18\.9\) \( JSR 384\)](http://cr.openjdk.java.net/~iris/se/11/latestSpec/)

- Oracle JDK 11
  - リリース: 2018年9月
  - 2020年12月末
  - Premier Support 期限: 2023年9月
  - Extended Support 期限: 2026年9月
  - Sustaining Support 期限: 無期限

- RedHat 提供 OpenJDK 11 バイナリ (Red Hat Enterprise Linux, Windows Server で動作する)
  - サポート期限: 2024年10月
  - [OpenJDK Life Cycle and Support Policy \- Red Hat Customer Portal](https://access.redhat.com/articles/1299013)
  - [OpenJDK ライフサイクルおよびサポートポリシー \- Red Hat Customer Portal](https://access.redhat.com/ja/articles/1457743)

- Amazon Corretto 11 (Linux, Windows, macOS で動作する Amazon 提供 OpenJDK 11 バイナリ)
  - サポート期限: 最短でも2024年8月まで
  - [Amazon Corretto（本番環境に対応したOpenJDKディストリビューション）\| AWS](https://aws.amazon.com/jp/corretto/)
  - [よくある質問 \- Amazon Corretto \| AWS](https://aws.amazon.com/jp/corretto/faqs/)
プリエンプティブインスタンスの停止(起動)をslackでお知らせできるようにする

# 概要
普段kaggleでGCEを使うときにプリエンプティブインスタンスを使うのですが, プリエンプティブインスタンスは24時間以内に停止させられてしまいます.
停止させられたら「停止したよ」ってお知らせできるようにしたいなと思って, GCEだとそれが簡単にできることがわかったのでそれの覚書です.

こんなふうにできるよー(かわいい...)
<img width="397" alt="スクリーンショット 2019-08-17 22.25.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139991/68f0f563-6005-8781-ce6e-8f29ba1ee3f3.png">


# 事前準備
まず事前準備として通知したいslackのチャンネルなどのwebhookを設定してください.[こちらの記事](https://qiita.com/ysti/items/24cf3d2c577f8abbcd2d)がわかりやすくまとまっています.

では以下で説明しやすいようにwebhookのurlを`https://hogehoge`として, 自分宛てにメンションを飛ばすように自分のユーザー名を`hoge`とします.

# シェルスクリプトでの動作確認
慎重に行うためにまずはシェルスクリプトでの動作確認をしてみます.
以下のようなシェルスクリプトを作ってください.これを`tmp.sh`とします.

```sh

#bin/bash

WEBHOOK_URL="https://hogehoge"
JSON="{\"text\": \"<@hoge> インスタンスが停止しちゃったよ!\"}"
curl -s -X POST -H 'Content-Type: application/json' -d "$JSON" $WEBHOOK_URL
```
メンションは`<@hoge>`とするとできますよ.
さ, これを叩いてみて実際に自分のところにメンション付きできたのを確認できたら次に進みましょう.

# インスタンスの設定
さ, もう一歩です.
自分のGCEのインスタンスの設定を編集したいのでインスタンス名を押すと以下の画像のようにインスタンスの編集を行うボタンが現れるので押します.
<img width="856" alt="スクリーンショット 2019-08-17 22.09.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139991/ef29e1d1-8848-4db4-6b80-12b7b7ebfb3d.png">

すると`カスタムメタデータ`という項目があるので`項目を追加`を押して, キーに`shutdown-script`と入れます.
値にはさきほどの`tmp.sh`の内容をまるっとコピペします.
以上で完了です! ちなみに`shutdown-script`の部分を`startup-script`にすると起動したタイミングで通知させることができます.
こんな感じです.
<img width="456" alt="スクリーンショット 2019-08-17 22.21.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139991/bcc4043f-bd87-3727-be5c-d6544abec671.png">

# まとめ
- まずはwebhookのurlを取得しよう
- シェルスクリプトから立たけるようにしよう
- GCEのカスタムメタデータのキーに`shutdown-script`と入れよう
- GCEのカスタムメタデータの値にさっきのシェルスクリプトの内容を貼り付けよう
Windows10でWinshotを使用するとキャプチャーがずれる場合の対処法

**Windows10**で、**WinShot**を使用してキャプチャーを取得しようとすると思いっきりずれる現象が発生した。ここではこの現象に対する対処方法を紹介します。

# 1. 現象
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292434/9744c38a-2ae5-e04a-f47a-d544c9d24e23.png)

ここで、**WinShot**の「コントロール／クライアント」でキャプチャを取得しようとすると・・・
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292434/8ee24365-e02c-dcc6-af0c-d761aab3faad.png)

画面サイズがでかくなり（解像度が小さくなり）、取得したいキャプチャーの対象ウィンドウとキャプチャー取得の赤線がずれる。

# 2. 環境
- Windows10 Home
- WinShot1.53a

# 3. 対処方法
- `Winshot.exe`を右クリックし、「プロパティ」を選択する。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292434/fba57216-412f-e521-0c42-823c0e1830b8.png)

- 「互換性」タブを選択する。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292434/d3a0ec70-66dd-39b0-6b47-83f307e9b8c4.png)

- 「高DPI設定の変更」をクリックする。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292434/5ffa4201-0968-b3e1-8125-ef58aceaa706.png)

- 「高いDPIスケールの動作を上書きします。」をチェックし、「OK」をクリックする。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292434/cba842b0-cf53-2ae8-ae9f-b76ff0432ab5.png)

# 4. 結果
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292434/f85154e7-ceab-c256-6aa9-8e3a81c2b21f.png)

**WinShot**を起動（再起動）し、もう一度「コントロール／クライアント」でキャプチャを取得しようとすると・・・

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292434/16b339cc-3945-5bbd-0aba-a10b36d44ca2.png)

うまくいきました。

以上
ImageDataメモ

## 概要

ImageDataインターフェースのメモ

## ImageDataインターフェース

`CanvasRenderingContext2D.getImageData()`で取得したデータの形式

### プロパティ

#### height

高さのピクセル数
型は`unsigned long`とのことだが、JavaScriptでは`number`

#### width

幅のピクセル数
型は`unsigned long`とのことだが、JavaScriptでは`number`

#### data

画像データの一次元配列。
RGBAの順番でデータ（[Uint8ClampedArray](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray)）が格納されている。

- R: Red
- G: Green
- B: Blue
- A: Alpha ※ 透過度 (数が小さいほど透過度が高い)

イメージ画像（3x3の画像の場合）
![9B2D2536-1C5D-489E-90E1-8498F630EBB1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65939/1e2b155f-350a-ca68-e5ea-292095498905.jpeg)

## 参考

[ImageData](https://developer.mozilla.org/ja/docs/Web/API/ImageData)
[HIG] アクセシビリティ - 視覚効果とモーション

この記事は Apple の Human Interface Guideline の Accessibility - [Appearance Effects and Motion](https://developer.apple.com/design/human-interface-guidelines/accessibility/overview/appearance-effects/) の部分を翻訳したものになります。正確な情報は公式ページを御覧ください。なお、言葉遣いには気をつけているつもりですが、不適切な部分がありましたら編集リクエストをください。

# 視覚効果とモーション

ぼかし、透過、動きなどの効果は情報を伝える手段の一つではありますが、一部の人にとっては気が散ったり、不快感を覚えたり、効果が全く感じられない場合もあります。デバイスの使い方によらずアプリを楽しめるよう、重要な情報を伝える唯一の方法として視覚効果を使用することは避けてください。

# 透過とぼかし

**ユーザが透明度を下げる機能をオンにした場合は、ぼかしと透明度が下がるようにしましょう。**例えばブラーがかかっていたり半透明なコンテンツはほとんど不透明になるはずです。一番良いのは、ブラーがかかっていたり不透明なエリアの場合は、機能がオンになったらオリジナルの色とは異なる色を使うことです。

# モーション

**アプリの目的に必要不可欠でない限り、アニメーションは必須ではありません。**一般的に、アニメーションに頼らずともアプリを使うことはできます。

**視覚効果を減らすモードがオンの場合、無駄のないアニメーションを再生しましょう。**ズームやスケーリング、回転、端の動きなどの効果を含むアニメーションを見る時にめまいや吐き気に襲われやすい場合、ユーザは視覚効果を減らすモードをオンにすることができます。この設定に応じて動きを抑えつつも表現豊かで魅力的な物理アニメーションになるよう、洗練させてください。例えば

* バネのバウンス効果を減らしたり、ユーザの指に追随するようにする
* Z軸レイヤーで深度の変化をアニメーションさせるのを避ける
* 「ぼけ」や「にじみ」などのアニメーションを避ける
* 動きをなくすために、スライドからフェードに置き換える

**ユーザがビデオやその他のモーションエフェクトをコントロールできる状態にしてください。**制御できるボタンやその他アフォーダンスも提供せずに、ビデオやその他エフェクトを自動再生させないでください。

**移動、点滅する要素を表示するときは注意してください。**ちょっとした動きや点滅はユーザの気を引くことができますが逆に気を散らす可能性があり、視覚障害のある人にとっては役に立ちません。さらに悪いことに、点滅する要素はてんかん発作を引き起こす可能性があります。どんなケースにしろ、情報を伝える唯一の手段として動きや点滅を使用することは避けてください。
【Java】文字列最後の空白を消したい

配列の要素を文字列連結して出力。
その際、要素と要素の間にスペースを入れたいが、末尾に空白が残ってしまう。

```java

	public static void main(String[] args) {
				
		String arr[] = {"orange","apple","cherry","melon","grape"};
		
		String ret = "";
				
		for (int i = 0; i < arr.length; i++) {
			ret += arr[i] + " ";
			
		}
		System.out.println("【" + ret + "】");
	}//出力結果【orange apple cherry melon grape 】
```

メソッドtrim()を使って空白を削除

```java
System.out.println("【" + ret.trim() + "】");
//出力結果【orange apple cherry melon grape】
```

trim()は頭と末尾の空白を削除した文字列を返します。
MacBook Airのターミナルについて調べてみる

##目標

MacBook Airをの使い方を調べてみる　(ターミナル編)

Linux初心者です。諸般の事情によりMacを使うことになったのでいろいろやってみてます
正直、Macでは色々とできるらしいが、やり方がよくわからない。
なので、ちょっとずつでも使えるようにしていく予定です

##参考にさせて頂いたページ
[ターミナルユーザガイド](https://support.apple.com/ja-jp/guide/terminal/trmlshtcts/mac)
[Macのウインドウ切り替え方法！同一アプリ内で切り替えるショートカットキーは？](https://applica.info/mac-window-switching)

##準備
- OSのバージョン
  - macOS Mojave v10.14.6
   
- Macメモ
  - Deleteボタンがないので、前方削除は fn+⇦(バックスペース)キー
  

###アプリケーション共通
 - アプリケーションの切り替え `command + tab`
 - 同一アプリケーション内でのウィンドウの切り替え `command + F1` なにっ！(◎_◎;) ビックリな事実です。
 - あと、`command + tab`で対象アプリを選んだ状態で `↓(下矢印` か `↑(上矢印)` を押下するとMission Controlのアプリケーション版が表示され、クリックか矢印キーで選べます
 - アプリケーション終了 `command + Q` これは基本ですね


###ターミナル
  - 字(フォント)が小さい
    - 小さくて目を細めて確認しながらコマンドを打っている。なので大きくしたい
    - `command + shift + "+"` で大きくなった。うむ、見やすい。小さくするには`command + "-"`
  - ターミナルのウィンドウを増やしたい
    - ひとつのウィンドウだけだとい色々できないよね
    - `command + N` うぉ もうひとつウィンドウが出てきた。でもフォントが小さい。。。
  - タブを増やす
    - ターミナルが一つだと不便　タブが使いたい
    - `command + T` おおおお 増えた
    - タブの移動 `control + tab`と`control + shift tab` あと、`command + 数字` 数字で指定したタブに移動
  - アクティイブなタブを閉じる
    - ` command + W` おおお 閉じた
  - ウィンドウ分割
     - `command + D` で上下に分割されます。`command + shift + D` で戻ります
  - ウィンドウをすべてて閉じる 
    - `Option ＋ Shift ＋ Command ＋ W` というか、`command + Q` でよくね?
  - 「新規ウィンドウ」
    - ``Command ＋グレイヴアクセント記号（  `）``。。。理解の範疇を超えました。Qiitaに投稿しているので`` (`) ``は知っていますが、これはどういったキーの組み合わせなのでしょうか。。。
    - その他の記載に`Command ＋ Shift ＋ティルダ記号（~）` で「前のウィンドウ」というのがありましたが、わかりません。やり方が。
  - ターミナルウィンドウに名前をつける
     -  `Shift + Command + I` ターミナルウィンドウの上のバーに名前を着けるためのダイアログが表示されます。デフォルトで `<ユーザー名>ー -bash ー80x24` のユーザー名の後に設定した名前が表示されます。`<ユーザー名>ー てすと ー -bash ー80x24` これは何気に便利かも
  - 画面が野暮ったい 
      - 背景色を変更 `Option ＋ Command ＋ I` で色設定のダイアログが表示されます。。。普通に設定画面でイジった方がよいと思います
  - 標準テキストをコピーする
    - これは便利そうなので書いておこう `Option ＋ Shift ＋ Command ＋ C`　。。。指がつるわ

##おわりに
これからお世話になるだろうターミナルについて調べてみました
まだまだいっぱいコマンドがありましたが、私のMac&Linuxレベルではこれくらいからのスタートが精一杯です。

Windowsユーザーのみなさんの参考になればと思います。
VSCode インテリセンスで表示されるアイコンの意味

備忘録です

#ドキュメントアイコンの一覧
マイクロソフトのページから引用。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389667/d89c4b90-8f24-9cb1-3ad1-d499d45fd49d.png)


#参考
[types-of-completions](https://code.visualstudio.com/docs/editor/intellisense#_types-of-completions)
WordPress 管理画面で発生するプラグイン Ajax エラーを解消

# 環境
[1時間で出来る！最強のWordPress環境構築(永久無料)](https://qiita.com/ryuta69/items/dbb0db5cf7099b7a7cc4) を参考に Google Cloud Platform 上に
WordPress 環境を構築。

当方の設定過不足が原因かと思われますが、メモとして残します。

# 症状
WordPress 管理画面にてプラグイン IP Geo Block の設定ページを開くと以下のエラーアラートが表示される。
<img width="450" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/211b0b95-dcb9-b331-7b17-6bebd3395c51.png">

> Ajaxコマンド `ip_geo_block` の実行中にエラーが発生しました。 (0)

Chrome の Console を確認すると `admin-ajax.php` で POST エラーが発生していることがわかる。

# 作業
プラグインからの `admin-ajax.php` へのアクセスを許可する為に `htaccess` 設定を行います。

Bitnami の WordPress ではセキュリティおよびパフォーマンス上の理由から `.htaccess` ファイルが無効に
設定されているので `htaccess.conf` を使用します。
https://community.bitnami.com/t/how-to-access-the-htaccess-conf-file/38410/2

---

Google Cloud Platform -> Compute Engine -> VMインスタンス
接続 欄の SSH をクリックしてコンソールを起動して `htaccess.conf` を編集する。

```bash
$ cd /opt/bitnami/apps/wordpress/conf/
$ sudo vi htaccess.conf
```

```conf:htaccess.conf
<Directory "/opt/bitnami/apps/wordpress/htdocs/">
    <FilesMatch "(admin-ajax.php)$">
        Satisfy Any
        Order allow,deny
        Allow from all
        Deny from none
    </FilesMatch>
</Directory>
```

サーバーを再起動する。

```bash
$ sudo /opt/bitnami/ctlscript.sh restart nginx
Unmonitored nginx
/opt/bitnami/nginx/scripts/ctl.sh : Nginx stopped
/opt/bitnami/nginx/scripts/ctl.sh : Nginx started
Monitored nginx
```

WordPress 管理画面にてエラーが解消されていることを確認する。

# 参考
https://blog.systemjp.net/entry/2017/08/12/001704
https://kimiyakitani.wordpress.com/2014/02/13/how-to-resolve-admin-ajax-error/
https://www.d-wood.com/blog/2016/05/25_8076.html
https://www.radia.jp/archives/319
PySparkでParquetを作るとTimeStampが勝手に時刻補正される

以前、PySparkを利用してParquetファイルを作成した。
このとき、「TimeStamp型」の値が勝手に変更される事象に出くわしたので、解決方法をメモ。

#目次
 1. 事象
 2. 解決策
 3. 結果
 4. 参考

##1. 事象
分かりやすく対象表を。
Parquet変換前のTimeStampをそのまま出力したいのに、
なぜか+9時間されて作成されてしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389667/3940f735-3727-cf5a-b72e-3a045b4e8a86.png)

この手の問題は、タイムゾーンが絡んでいることが多いが
今回もタイムゾーンの設定が原因だった。
  

##2. 解決策
spark-defaults.confというファイルに
タイムゾーンを記述しているコメント部分があるが、このコメントを外す
※confファイルは、sparkをインストールしたディレクトリ\spark-2.x.x-bin-hadoopx.x\conf\ 内にある

```text:spark-defaults.conf（変更前）
# spark.driver.extraJavaOptions      -Duser.timezone=UTC
# spark.executor.extraJavaOptions    -Duser.timezone=UTC
```
```text:spark-defaults.conf（変更後）
spark.driver.extraJavaOptions      -Duser.timezone=UTC
spark.executor.extraJavaOptions    -Duser.timezone=UTC
```
コメントを外したら上書き保存し、一度再起動すると良い
※僕の環境では、再起動するまで挙動がおかしかったため


##3. 結果
spark-defaults.confを書き換えたら、タイムスタンプが変換されなくなりました。


##4. 参考
[Spark Strutured Streaming automatically converts timestamp to local time](https://stackoverflow.com/questions/48767008/spark-strutured-streaming-automatically-converts-timestamp-to-local-time)
【AWS】関東地区、平均視聴率10%程度のTV番組に耐える負荷対策

再び、TV放送があったので対策と結果、考察を記事にしてみました。
[前回](https://qiita.com/free_man/items/13f49fe96897e2a3c5dc)記事と構成はほとんど一緒ですが、今回の方がアクセス数が高いです(視聴率5%→10%、放送時間60秒→120秒のため)。

## ①アクセス数の予測

計算方法詳細は[こちら](https://qiita.com/free_man/items/13f49fe96897e2a3c5dc#%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E6%95%B0%E3%81%AE%E4%BA%88%E6%B8%AC)

```
総アクセス数 = テレビ局のリーチ人数 × 視聴率 × Web検索する人の割合 (=総アクセス人数) × 一人あたりの平均閲覧ページ数
```

```
総アクセス数 = 4,000万(テレビ局のリーチ人数) × 10%(視聴率) × 1%(Web検索する人の割合) × 2(一人あたりの平均閲覧ページ数) = 8万アクセス
```

```
出演時間のQPS = 8万アクセス ÷ 120秒 = 平均 666 QPS
* OPS(平均リクエスト数)
```

## ②行った負荷対策

**1. キャッシュの設定**
TOPページ→アクションキャッシュ
使い方、会社概要→CDN(Cloudfront)の設定

**2. Auto Scaling(インスタンス数の最適化)**

| 変更前 |    変更後   |
|:-----------------:|:------------------:|
| t2.medium×2~5(通常2台稼働) |   t2.medium×5~10(通常5台稼働)   |

```
t2.medium = 2vCPU×5 = 1000(最大2000) OPS > 666 OPS(予測)
```


## ③結果

放送当日は

### 最大約1000req/sec

のアクセスがありました！！
ヽ(￣д￣;)ノ=3=3=3

一応2000req/secまでは耐えられと思っていたけどテレビすごいですね。。
対策なしではサーバー落ちていた可能性高いです。


| 予想 |    実際   | 誤差  |
|:-----------------:|:------------------:|:------------------:|
| 約666req/sec |   約1000req/sec   |  334 |

今回は大幅にずれ込んでしまいました。

誤差の原因としては

* 夏休みなどの長期休みにより、視聴者が増加
* 番組の視聴者層がターゲットに近い・ターゲットだった

特に後者の考慮が足りていないように思いました。
[HIG] アクセシビリティ - 色とコントラスト

この記事は Apple の Human Interface Guideline の Accessibility - [Color and Contrast](https://developer.apple.com/design/human-interface-guidelines/accessibility/overview/color-and-contrast/) の部分を翻訳したものになります。正確な情報は公式ページを御覧ください。なお、言葉遣いには気をつけているつもりですが、不適切な部分がありましたら編集リクエストをください。

---

**オブジェクトを区別したり重要な情報を伝える時に、色だけに頼らないでください。**アプリ内で色を通して情報を伝達している場合は、色覚障害を持つユーザでも理解できるよう、テキストラベルやグリフを提供するようにしてください。

**テキストにはできるだけシステムカラーを使用してください。** [UIColor](https://developer.apple.com/documentation/uikit/uicolor) もしくは [NSColor](https://developer.apple.com/documentation/appkit/nscolor) で定義された色を使用してテキストの色付けを行うと、色反転やコントラスト強化などのアクセシビリティ設定に正しく反応します。

**色覚障害のことを意識してください。**例えば多くの色覚障害者は赤と緑（加えて赤と灰色、緑と灰色）、青とオレンジを区別するのが難しいとされています。2つの状態や値を区別する唯一の方法としてこれら2つの色の組み合わせを使うのは避けてください。例えば、赤と緑の円を使用してオンラインかオフラインかを示すのではなく、赤い四角と緑の円を使用するなどの方法を取りましょう。一部の画像編集ソフトウェアには色覚障害を判別するのに役立つツールが組み込まれています。

**色反転に正しく対応しましょう。**暗い背景でアイテムを表示したい時、色反転機能をオンにすることができます。色反転のスマート反転モードでは、画像、ビデオ、フルカラーアイコン（アプリアイコンや非テンプレート画像など）は反転しないし、暗いUIも暗いままです。

**十分な色コントラスト比を確保してください。**アプリ内にある要素間に強いコントラストを使うと、より知覚しやすくなります。オンライン上のカラーコントラスト測定ツールを使うと、アプリのカラーコントラスト比を正確に分析し、適切な基準を満たしているかどうかが確認できます。少なくとも4.5：1のコントラスト比を確保する必要がありますが、より厳しいアクセシビリティ基準を満たすためには7：1のコントラスト比を確保してください。

**コントラスト比を決定するときに、テキストサイズも参考にしてください。**一般的に読みやすくするためには、小さいテキストや細いウェイトになればなるほどコントラスト比を強くする必要があります。目安として次の値を使用しましょう。

<img width="700" alt="スクリーンショット 2019-08-13 12.15.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100736/3a256b4d-0aee-cb4a-5a36-a9db3760c2f4.png">
※[Color and Contrast](https://developer.apple.com/design/human-interface-guidelines/accessibility/overview/color-and-contrast/)の画面下部の図を引用。

アプリ内のテキストをすべてのユーザがアクセス可能にする方法についてより詳しく知りたい方は、[Text Size and Weight](https://developer.apple.com/design/human-interface-guidelines/accessibility/overview/text-size-and-weight/) を御覧ください。
とにかく簡単にLiveDataまとめ

#〇前置き
前回の続編です。
[とにかく簡単にViewModelまとめ](https://qiita.com/KIRIN3qiita/items/7d833e2c010c0b2c02d9)
ViewModelを会得している人はそのままどうぞ。

#〇LiveDataって何？
JetPackのコンポーネントの一つ。
簡単に書くとViewModelクラス内のデータの更新をアクティビティやフラグメントが監視して、更新時にViewの変更などができます。

#〇参考URL
・[公式]
https://developer.android.com/topic/libraries/architecture/livedata?hl=ja
・【Android Architecture Components】LiveData 和訳
https://qiita.com/oya-t/items/f908a358a2a615ce936d
・ViewModels and LiveData: Patterns + AntiPatterns
https://medium.com/androiddevelopers/viewmodels-and-livedata-patterns-antipatterns-21efaef74a54

#〇プログラム
###・GitHub
https://github.com/KIRIN3git/ViewModel-LiveData

###build.gradle[app]
ViewModelと同じく、android.arch.lifecycle:extensionsが必要。

```build.gradle:build.gradle[app]
dependencies {
    implementation 'android.arch.lifecycle:extensions:1.1.1'
}
```
###activity_main.xml
前回と同じなので割愛。

###CountViewModel.kt
変更を監視したい値をMutableLiveData<>で宣言。
<>の中は型を指定。

```kotlin:CountViewModel.kt
class CountViewModel : ViewModel() {
    // ViewModelに属するカウンター
//    var counterB: Int = 0

    // Int型のLiveViewを作成
    val counterB: MutableLiveData<Int> by lazy {
        MutableLiveData<Int>()
    }
    // 初期値を0に設定
    init{
        counterB.value = 0
    }
}
```

###MainActivity.kt
オブザーバーを設置し、ViewModelの値は更新を受け取ったらViewを更新する

```kotlin:MainActivity.kt
import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // アクティビティに属するカウンター
        var counterA = 0

        // インスタンスを作成
        val viewModel: CountViewModel = ViewModelProviders.of(this).get(CountViewModel::class.java)

        val text1 = findViewById(R.id.text1) as TextView
        val text2 = findViewById(R.id.text2) as TextView

        val button = findViewById(R.id.button) as Button
        button.setOnClickListener {
            counterA++
            text1.setText(counterA.toString())

            // ViewModelの監視対象のメンバ変数を+1
            // 値を取り出す場合は[value]
            viewModel.counterB.value = viewModel.counterB.value!! + 1
        }

        // UI更新用のオブザーバー（監視役）を作成
        val countObserver = Observer<Int> { counter ->
            // 更新を受け取ったらTextViewを更新
            text2.text = counter.toString()
        }

        // LiveDataを監視し、このアクティビティをLifecycleOwnerおよびオブザーバーとして渡す
        viewModel.counterB.observe(this, countObserver)
    }
}
```

#起動

COUNTを3回クリック。
![Screenshot_1566005631.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252283/70165823-51c5-d730-4a7c-c27c7fb7fd2f.png)

横にする。
![Screenshot_1566010212.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252283/7e41b68d-369c-67c1-f5fa-1b9f5088d4bf.png)

カウントが増えても反映されるし、アクティビティが更新されてもデータを確認してくれてますね。
しかし、このままではアクティビティのソースは複雑になってしまいます。
データ管理の責任をアクティビティ、フラグメントから分離するためにDataBindingに続く。

[とにかく簡単にDataBindingまとめ](https://qiita.com/KIRIN3qiita/items/4a2b16b4ce3c9b1cffd5)
SONY Spresense をLPC-Link2(CMSIS-DAP)でデバックしよう 

SONYのSpresenseでデバック出来ないという話があったので、今回やり方を書きました。

##3.14. JTAGデバッガの使用方法
https://developer.sony.com/ja/develop/spresense/developer-tools/hardware-documentation

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/f7b3647a-da53-5f2a-b9f0-d6a0e60880d4.png)

ピンヘッダは、秋月電子で購入可能です。
[C-10904]　ピンヘッダ　２×５（１０Ｐ）　表面実装用　１．２７ｍｍピッチ　PH127-2x5MG-1.5
http://akizukidenshi.com/catalog/g/gC-10904/
![J-Link2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/da1c97a3-c594-b672-cfe0-3cc8175e8ae5.jpeg)

#10.1. Eclipse IDEでのデバッグ方法
##10.1.1. ハードウェア
###CMSIS-DAP 準拠デバッグアダプタ (ICE)
###Keil ULINK2 (http://www.keil.com/arm/ulink2/)
###NXP LPC-Link2 (https://www.nxp.com/jp/support/developer-resources/software-development-tools/lpc-developer-resources-/lpc-microcontroller-utilities/lpc-link2:OM13054?lang=jp&lang_cd=jp&)

###SWD connector

https://developer.sony.com/ja/develop/spresense/developer-tools/get-started-using-nuttx/nuttx-developer-guide#_%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A7%E3%82%A2

NXP LPC-Link2は、こちらで購入可能です。
##[M-06706]　LPC-Link2[OM13054]
秋月電子で2800円（2019根8月17日現在）で販売中。
http://akizukidenshi.com/catalog/g/gM-06706/

![J-Link.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/837c96a4-9d66-bbb6-e4f2-6f23c788506b.jpeg)

ということで、どちらも秋月電子で購入可能です。
Speresenseでデバックしたい方はどうぞ

スパムじゃないのに、スパム判定されました。
理由を確認したが、返事が無いのはなぜなのでしょうか？
Windows 10 shortcut keys cheat sheet

# よく使うショートカットたち
Windowsはマウスで操作するのが一般的だが、キーボードだけでもそれなりに使える。ただ、ショートカットを覚えまくって、使いまくっても効率がいいかというと、やや疑問。だけど、知っておいたほうが便利だなぁ、と個人的に思っているショートカットはやっぱりある。という事で、まとめてみた。

|キー            |目的                                   |備考|
|----------------|---------------------------------------|----|
|Ctrl+C          |選択した項目をクリップボードにコピー       ||
|Ctrl+V          |クリップボードの内容をペースト            ||
|Ctrl+Shift+V    |クリップボードの内容を書式なしでペースト   |便利。|
|Ctrl+Z          |直前に実行した操作のUndo                 ||
|Windows+E       |エクスプローラの起動                     |IEのことじゃないよ|
|Windows+D       |デスクトップの表示                       ||
|Windows+R       |[ファイル名を指定して実行] ダイアログを開く||
|Windows+V       |クリップボードの表示                     |Windows 10 October 2018 Update（Version 1809）以降で使用可能|
|Windows+Shift+S |スクリーンキャプチャ                     |Windows 10 October 2018 Update（Version 1809）以降で使用可能|
|Alt+Print Screen|アクティブウィンドウのスクリーンキャプチャ ||
|F5              |アクティブウィンドウを最新の情報に更新する ||
|Alt+F4          |アクティブウィンドウの終了                ||
|Alt+Tab         |アクティブウィンドウの切り替え            ||

# リンク
[Windows のキーボード ショートカット](https://support.microsoft.com/ja-jp/help/12445/windows-keyboard-shortcuts)
Microsoftのページ。ここ見ればいいんじゃね、と思った君！正解です。

[PowerToys](https://github.com/microsoft/PowerToys/releases)
PowerToysに含まれている**Windows Key Shortcut Guide**は、Windowsキーと組み合わせて使うショートカットキー一覧を表示してくれる。全てのショートカットキーを表示してくれるわけではないが、それなりに使える。
C#のビルド＆実行をバッチファイル化したら途中で止まる問題[Mono]

## C#実行環境

* OS: **windows 10 home**
* コンパイラ、動作環境: **Mono**
* エディタ: **Visual studio code**

## 概要

　競プロ用に、Visual studio codeにC#(mono)のビルド環境を作成した。
　ビルドと実行をコマンドで入力するのが面倒なので、処理をまとめてバッチファイル化してみた。

```cmd:csrun.bat
csc -out:out.exe test.cs　
mono out.exe
```
 
 **　が、上記の場合1行目のビルドのみが実行され、2行目以降の処理が実行されなかった。**

## 原因と解決法
　ビルド時の実行されるcscコマンドの実体を見てみると、どうやらこれもbatファイル。
<img width="550" alt="mono.img" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284450/1302230c-cc4d-0103-32bc-920e9074db92.jpeg">

　**バッチファイルの中で別のバッチファイル（子バッチ）をそのまま呼び出した場合、子バッチ実行後に終了してしまう。**
　そのため、実体がbatファイルであるcscコマンドをそのまま実行した場合、それ以後の処理が行われなかった。

　子バッチファイルを呼び出す場合は、**「call 子バッチファイル」**のように記載する必要がある。
　よって下記のように修正すればよい。

```cmd:csrun.bat
call csc -out:out.exe test.cs
mono out.exe
```

## 余談(VScodeのRunnerと連携するために)
 
　上記の話も踏まえて、私が実際に使用しているbatファイルを置いておきます。

　Visual studio codeの拡張機能Runnerを入れると、
　特定の言語に対して特定のファイルを実行してくれるショートカットキー(Ctrl+B)が使用できる。
　Runnerと連携時に実行されるbatファイルを下記のように設定してます。

```cmd:csrun.bat
call csc -out:out.exe %~dpnx1
start /w cmd /c "mono out.exe & pause"
del out.exe
```

**解説**
1行目: runnerで呼び出されるバッチはファイル名が第一引数となるので、%1でファイル名を受け取る。
2行目: プログラム実行後に標準入力を受け取るためには、新たにwindowを開く必要があるため、
startコマンドにより新たにwindowを開いている。その後、monoコマンドで実行を行う。
3行目: 実行後は実行ファイルを削除、2行目で/wオプションがあるので、2行目の実行後に削除が行われる。
certbot-autoでNo matching distribution found for certifi==2019.3.9エラーが発生した時の対処法

# 問題
## 環境
- centOS 7.6.1810 Core

certbotをcloneして実行したときにpip側でエラー発生．

```
# git clone https://github.com/certbot/certbot
# cd certbot
# ./certbot-auto certonly --standalone -t

Bootstrapping dependencies for RedHat-based OSes... (you can skip this with --no-bootstrap)
yum is /bin/yum
yum is hashed (/bin/yum)
Loaded plugins: fastestmirror
...(省略)
pip prints the following errors:
=====================================================
Collecting ConfigArgParse==0.14.0 (from -r /tmp/tmp.p57ONgbkAA/letsencrypt-auto-requirements.txt (line 7))
  Downloading http://jp.mirrors.cloud.aliyuncs.com/pypi/packages/55/ea/f0ade52790bcd687127a302b26c1663bf2e0f23210d5281dbfcd1dfcda28/ConfigArgParse-0.14.0.tar.gz
Collecting asn1crypto==0.24.0 (from -r /tmp/tmp.p57ONgbkAA/letsencrypt-auto-requirements.txt (line 9))
  Downloading http://jp.mirrors.cloud.aliyuncs.com/pypi/packages/ea/cd/35485615f45f30a510576f1a56d1e0a7ad7bd8ab5ed7cdc600ef7cd06222/asn1crypto-0.24.0-py2.py3-none-any.whl (101kB)
Collecting certifi==2019.3.9 (from -r /tmp/tmp.p57ONgbkAA/letsencrypt-auto-requirements.txt (line 12))
  Could not find a version that satisfies the requirement certifi==2019.3.9 (from -r /tmp/tmp.p57ONgbkAA/letsencrypt-auto-requirements.txt (line 12)) (from versions: 0.0.1, 0.0.2, 0.0.3, 0.0.4, 0.0.5, 0.0.6, 0.0.7, 0.0.8, 1.0.0, 1.0.1, 14.5.14, 2015.4.28, 2015.9.6, 2015.9.6.1, 2015.9.6.2, 2015.11.20, 2015.11.20.1, 2016.2.28, 2016.8.2, 2016.8.8, 2016.8.31, 2016.9.26, 2017.1.23, 2017.4.17, 2017.7.27, 2017.7.27.1, 2017.11.5, 2018.1.18, 2018.4.16, 2018.8.13, 2018.8.24, 2018.10.15, 2018.11.29)
↓↓↓ 問題発生
No matching distribution found for certifi==2019.3.9 (from -r /tmp/tmp.p57ONgbkAA/letsencrypt-auto-requirements.txt (line 12))
↑↑↑ 問題発生
=====================================================
...(省略)
```

`certifi==2019.3.9`が見つからないらしい．

# 解決方法
https://community.letsencrypt.org/t/certbot-auto-installing-python-packages-failed/95847

```
# rm -f /root/.pip/pip.conf
```

`/root/.pip/pip.conf`を認識させないようにすればよい．
とあるURLの表示内容を5分間隔で確認したい

とあるURLの表示内容を5分間隔で確認したい。

```bash
# watch_url.sh

URL=https://example.com/foo/bar # 監視対象のURL
INTERVAL=300 # 監視間隔

# Macのデスクトップ通知
function notify_desktop () {
  title=$1
  message=$2
  osascript -e "display notification \"$message\" with title \"$title\""
}

MD5HASH_OLD=''
while :
do
  # CURLでページの内容を取得、MD5を算出
  # 前回と比較して異なっていたら、デスクトップに通知
  MD5HASH_NEW=`curl /dev/null $URL 2> /dev/null | md5`
  if [ "$MD5HASH_OLD" != "$MD5HASH_NEW" ]; then
    notify_desktop "ページ監視" "更新されました"
    MD5HASH_OLD=$MD5HASH_NEW
  fi
  echo -n .
  sleep $INTERVAL
done
```

あとは実行するだけ。
やめるときは `CTRL+C` で。

```console

$ bash watch_url
.....
```

なんかあると、こんなふうに出る。

![通知](https://cdn-ak.f.st-hatena.com/images/fotolife/k/ken1flan/20190817/20190817204623.png)

## やっていないこと

いつもいつも使うものじゃないから、がんばらなくていいかと思って、ほったらかしてる。

- 対象のURLや監視間隔を引数にする
- 起動直後に「更新されました」が出ないようにする
RaspberryPiの初回セットアップ手順

RaspberryPiを最初からセットアップする機会がありましたので、自分の初回セットアップ手順をまとめます。
本記事にはOSを入れて、ネットワークに接続して、日本環境用の設定をして、などの"最初に1回だけ実施する設定"だけを記載します。

# セットアップのポイント

- RaspberryPiに電源以外のケーブルを1度も挿さずにセットアップ
- CUIのみ
- SSH接続で操作

# 環境

- 端末: Raspberry Pi 3 Model B
- OS: Raspbian Buster Lite 4.19 (Release: 2019-07-10)

# 手順

## Raspbian(OS)のダウンロード

[公式のダウンロードページ](https://www.raspberrypi.org/downloads/raspbian/)からRaspbianをダウンロードします。
今回はCUIでいいので「Raspbian Buster Lite」を選択します(執筆時点の場合)。

なお、公式は海外で重いため日本のミラーサーバからダウンロードするのがおすすめです。
ダウンロード先については以下の記事がとても参考になりました。

[Raspbianのダウンロードが遅いとき、または古いバージョンを使いたい時はミラーサイト](https://raspberrypi.mongonta.com/f363-raspbian-mirror-site/)

## RaspbianをMicroSDに書き込む

環境や好みによって手順が異なってくる部分のため割愛します。
ちなみに自分はWindows環境で「Win32 Disk Imager」というソフトを使って書き込みました。

## 無線LAN設定

まだMicroSDをRaspberryPiに挿しません。
RaspberryPiが初回起動時から無線LANに接続されるように設定を行います。

無線LANのSSIDとパスワードを用意し、Unix系端末で`wpa_passphrase`コマンドを実行します。
`ssid`、`password`は各自のアクセスポイントの情報に書き換えて実行してください。

```sh
$ wpa_passphrase ssid password
network={
        ssid="ssid"
        #psk="password"
        psk=44116ea881531996d8a23af58b376d70f196057429c258f529577a26e727ec1b
}
```

`wpa_passphrase`コマンドが未インストールの場合は`apt install wpasupplicant`みたいにしてインストールしてください

そして、MicroSDのルートディレクトリに`wpa_supplicant.conf`を追加します。
`network`の中は`wpa_passphrase`コマンドで取得した値に書き換えてください。

```sh
# wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=JP

network={
  ssid="ssid"
  psk=44116ea881531996d8a23af58b376d70f196057429c258f529577a26e727ec1b
}
```

ちなみに、`psk`には平文(暗号化されていないパスワード)を設定することも可能ですが、
なんとなく抵抗があるので、一応きちんと`wpa_passphrase`によって暗号化した方がいいと思っています。

## SSHの有効化

初期設定ではSSHが無効になっているため、有効化します。
MicroSDのルートディレクトリに`ssh`(空のファイル)を配置します。

![ここまでで作成した2ファイル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231426/169e93a3-770c-06da-9269-55013e237ae6.png)

このように2ファイルが配置されていればOKです。
ここまできたらMicroSDをRaspberryPiに挿し込み、電源を入れます。

## RaspberryPiにSSH接続

起動後2～3分くらい経ったらSSH接続してみます。
RaspberryPiの初期の接続情報は以下です。

- 接続先:
 raspberrypi.local
- アカウント名:
 pi
- パスワード:
 raspberry

```sh
# SSHコマンドで接続する場合
$ ssh pi@raspberrypi.local
raspberrypi
```

うまく接続できない場合、とりあえずpingを飛ばして原因の切り分けを行いましょう。

```sh
ping raspberrypi.local
```

- 応答あり: SSHが有効になっていない、SSH接続のやり方が悪い、etc
- 応答なし: 無線LANに接続できていない、RaspberryPiが正常起動していない、etc


## ロケール情報の変更

以降の設定はSSH接続したRaspberryPiで実施します。
まずはロケールを日本語に変更します。

```sh
$ sudo localedef -f UTF-8 -i ja_JP ja_JP
```

## Timezoneを変更

タイムゾーンを日本時間に変更します。

```sh
$ date
Sat 17 Aug 11:53:50 BST 2019
$ sudo timedatectl set-timezone Asia/Tokyo
$ date
Sat 17 Aug 19:54:52 JST 2019
```

## ホスト名の変更

以下のファイルに記載の`raspberrypi`を任意のホスト名に書き換えます。

- /etc/hosts
- /etc/hostname


## 固定IP化

固定IPを設定します。
以下に記載のIPなどは環境に合わせて変更してください。
なお、設定は再起動後に有効になります。

```sh
# /etc/dhcpcd.conf
# 末尾に追記(既存は変更しない)
interface wlan0
static ip_address=192.168.1.80/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1
```

## エディターをvimに変更

この項目の実行は任意です。
RaspberryPiの初期エディタはnanoですが、個人的に好きでないためvimに変更します。

```sh

sudo update-alternatives --set editor /usr/bin/vim.tiny
```

# 設定完了。そして

これで自分がやりたいことが開始できる環境が整ったと思います。
この先はセンサーを繋いだり、自宅サーバにしてみたり、etc。
ソートされた配列から対象となる数値の範囲を取得する

# 問題
ソートされた重複のある配列が与えらる。この配列から対象となる数値の最初から最後までの配列のインデックスを返しなさい。
対象の数値がない場合は-1を返す

Input: A = [1,3,3,5,7,8,9,9,9,15], target = 9
Output: [6,8]

Input: A = [100, 150, 150, 153], target = 150
Output: [1,2]

Input: A = [1,2,3,4,5,6,10], target = 9
Output: [-1, -1]

.
.
.
.
.
.
.
.
.
.
.
.
# 回答

JavaScriptで回答する。
普通に配列の最初から探索すると計算量O(N)で範囲を取得できる。

が今回の場合はソート済みの配列が与えられるためもう少し効率の良い方法が考えられる。バイナリサーチだとO(logN)で計算できるので、バイナリサーチを使ったほうが良さそう。
対象の要素を見つけたらそこから範囲を絞れば良い。

```js
function getRange(nums, target) {
    let left = 0
    let right = nums.length - 1

    while (left <= right) {
        const center = Math.floor((right + left) / 2)
        if(nums[center] === target) {
            let start = center
            let end = center
            while(nums[center] == nums[start]) {
                start -= 1
            }
            while(nums[center] == nums[end]) {
                end += 1
            }
            return [start + 1, end - 1]
        } else if (nums[center] < target) {
            left = center + 1
        } else {
            right = center - 1
        }
    
    }

    return -1
}
```

ということで単なるバイナリサーチの応用だった

計算量: O(logN)
メモリ: O(1)