OmniAICreator/Qiita-1.07M huggingface dataset:
Helmの使い方まとめ | Kubernetesパッケージマネージャー 

# Helm の charts をカスタマイズする方法

例として、stable/redisをカスタマイズしてみます。
(なぜならこの記事の編集時点で正しくインストールできなくなってるので;)

## local に charts を取得する

以下のコマンドを実行して、cahrts をローカルに取得します。

```
$ helm fetch stable/redis
```
```
$ ls 
redis-9.4.1.tgz
```

## charts の編集
tgzを展開して任意のフォルダに置き、
編集したいファイルを編集します。

```
$ ls ./redis
Chart.yaml  ci  README.md  templates  values-production.yaml  values.yaml
```

## 独自の charts の作成

ディレクトリを指定して、オリジナルの charts を作成します。

```
$ helm package redis
Successfully packaged chart and saved it to: redis-9.4.1.tgz
```
上記のコマンドはでディレクトリ(redis)を指定して、chartsを作成しています。

## 独自の charts のインストール
installコマンドにtgzを指定してインストールします。

```
$ helm install redis-9.4.1.tgz
```
[swift] カスタムセルから親のcollectionViewとViewControllerの取得

カスタムセルから親にあたるコレクションビューとビューコントローラーを取得したかった


#親子関係
ViewController
　|
　collectionView
　　|
　　customCell

#方法
以下でOk

```CustomCell.swift
let collectionView = (self.superview as! UICollectionView)
let iewController = ((self.superview as! UICollectionView).delegate as! ViewController)

```
tf.map_fnの使い方

## 概要
tensorflowライブラリの`map_fn`という関数について紹介します．
`map_fn`がどう動くのかを中心に書きます．
公式ドキュメントは「[こちら](https://www.tensorflow.org/api_docs/python/tf/map_fn)」です．

## 内容
ある関数にテンソルの要素を一つ一つ与えたいときに使います．
mapは「写像」を意味していると思われます．

```.py
tf.map_fn(
    fn,
    elems,
    dtype=None,
    parallel_iterations=None,
    back_prop=True,
    swap_memory=False,
    infer_shape=True,
    name=None
)
```

`elems`に入力テンソルを指定し，`fn`に適用する関数を指定すると，`elems`の要素が連続的に`fn`に与えられます．
`elems`はリスト，タプルにすることも可能ですが，最初の次元は一致させる必要があります．

### 1つのテンソル
簡単な例を次に示します．

```test.py
import numpy as np
import tensorflow as  tf

def func(x):
    return x*x

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

elems = np.array([1,2,3,4,5,6])
op = tf.map_fn(func, elems)
result = sess.run(op)
print(type(result)) # <class 'numpy.ndarray'>
print(result.shape) # (6,)
print(result) # [ 1  4  9 16 25 36]
```

1つのテンソルに対して，関数が適用されていることが分かります．
しかし，これは`func(elems)`のように，関数に引数を与えるときと変わりません．

`map_fn`の挙動は次の例を見てもらえれば分かると思います．

```test2.py
import numpy as np
import tensorflow as  tf

def func(x):
    return 1

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

elems = np.array([1, 2, 3])
op = tf.map_fn(func, elems)
result = sess.run(op)
print(type(result)) # <class 'numpy.ndarray'>
print(result.shape) # (3,)
print(result) # [1 1 1]
```

1つのテンソルに対して，関数が適用されています．
テンソルは3つの要素を持っており，そのそれぞれに対して「1」が返り値として与えられ，結果として`array([1, 1, 1])`が`result`に入ります．

### 複数のテンソル
2つのテンソルをタプルで`elems`に渡したときの例です．

```test3.py
import numpy as np
import tensorflow as  tf

def func(x):
    return 5,6

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

elems = (np.array([1, 2, 3]), np.array([4,5,6]))
op = tf.map_fn(func, elems)
result = sess.run(op)
print(type(result)) # <class 'tuple'>
print(result) # (array([5, 5, 5]), array([6, 6, 6]))
```

2つのテンソルのそれぞれの要素に対し，順番に関数が適用され，1つ目のテンソルには「5」を，2つ目のテンソルには「6」を返しています．

返り値の形や型が，`elems`と異なる場合は，`dtype`で指定します．

```test4.py
import numpy as np
import tensorflow as  tf

def func(x):
    return x[0] * x[1]

def func2(x):
    return x[0]+1, x[0]+2, x[1]+1, x[1]+2

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

elems = (np.array([1, 2, 3]), np.array([4,5,6]))

op = tf.map_fn(func, elems, dtype = tf.int32) # dtypeで指定
result = sess.run(op)
print(type(result)) # <class 'numpy.ndarray'>
print(result) # [ 4 10 18]

op2 = tf.map_fn(func2, elems, dtype = (tf.int32, tf.int32, tf.int32, tf.int32)) # dtypeで指定
result2 = sess.run(op2)
print(type(result2)) # <class 'tuple'>
print(result2) # (array([2, 3, 4]), array([3, 4, 5]), array([5, 6, 7]), array([6, 7, 8]))
```

### おまけ
2次元テンソルの場合でも要素が一つずつ順に渡されていることが分かります．

```test5.py
import numpy as np
import tensorflow as  tf
import sys

def func2(p, q):
    return np.dot(p, q)

def func(x):
    a, b = x
    return func2(a,b)

init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

elems = (np.array([[1, 2, 3],[4,5,6]]), np.array([[10, 20, 30],[40,50,60]]))
op = tf.map_fn(func, elems, dtype = tf.int32)
result = sess.run(op)
print(type(result)) # <class 'numpy.ndarray'>
print(result) # [[ 10  40  90] [160 250 360]]
```
df.corr()を一列に変換する [pandas]

例えば、irisデータセットに対してpandasのcorrメソッドを使うと、こんな風に相関係数行列が出てくると思います。

```python:python
df.corr(method='pearson')
```

<img width="507" alt="スクリーンショット 2019-10-23 午後2.45.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178570/3f7f14b9-2be2-8f54-dd42-454e08c24962.png">

ただ、相関係数のランキングを作りたい場合は、こんな感じで1列に並んでいた方が扱いやすかったりします。

<img width="279" alt="スクリーンショット 2019-10-23 午後2.46.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178570/0e6aa0d1-2c64-c6f5-83f0-781ee793182b.png">

そこで、相関係数を上の様に出力する関数を作ってみました。

```python:python
import numpy as np
import pandas as pd

# 引数は、相関係数を作成したいdf
def calc_corr(df):
    # 相関係数行列を作成
    corr_mat = df.corr(method='pearson')

    # 行（列）サイズを取得
    n = corr_mat.shape[0]
    
    # 項目名を取得
    columns = corr_mat.columns.tolist()
    
    # 変数名1, 変数名2, 値を一つの配列に入れたものを作成
    # 相関係数行列の下三角部分（対角成分除く）だけ
    corr_ary = []
    var1_ary = []
    var2_ary = []
    for i in range(n):
        for j in range(i):
            if i == j:
                continue
            corr_ary.append(corr_mat.iloc[i,j])
            var1_ary.append(columns[i])
            var2_ary.append(columns[j])

    # dfにする
    df_new = pd.DataFrame([])
    df_new["var1"] = var1_ary
    df_new["var2"] = var2_ary
    df_new["corr"] = corr_ary
    
    return df_new
```

使用例は以下の通りです。

```python:python
from sklearn import datasets

iris = datasets.load_iris()
df = pd.DataFrame(data=iris['data'], columns=iris['feature_names'])
corr(df)
```

これでさっきのdfが得られます。

<img width="279" alt="スクリーンショット 2019-10-23 午後2.46.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178570/0e6aa0d1-2c64-c6f5-83f0-781ee793182b.png">
Golang構成参考リンク

>Goのpackage構成と開発のベタープラクティス - Tech Blog - Recruit Lifestyle Engineer
https://engineer.recruit-lifestyle.co.jp/techblog/2018-03-16-go-ddd/

>go言語でクリーンアーキテクチャっぽいもの | IIJ Engineers Blog
https://eng-blog.iij.ad.jp/archives/2442

>Goでクリーンアーキテクチャを試す | POSTD
https://postd.cc/golang-clean-archithecture/

>Go × Clean Architectureのサンプル実装 - 爆速でGo！
http://nakawatch.hatenablog.com/entry/2018/07/11/181453

>golang のレイヤ構造において、他のコードに影響なくインフラレイヤのデータソース実装を差し替えることは可能か? - pospomeのプログラミング日記
https://www.pospome.work/entry/2017/11/24/163149

>Goとクリーンアーキテクチャとトランザクションと - Qiita
https://qiita.com/miya-masa/items/316256924a1f0d7374bb
vue.js 全ページ遷移時にページTOPへスクロールさせる

# 全ページ遷移時にページTOPへスクロールする

ページ遷移時、遷移前の表示位置のまま、新しいページに遷移してしまう。

ページ遷移時にはページTOPへスクロールさせたい。

## やり方

```
scrollBehaivor () {
  return { x: 0, y: 0 }
}
```
を使う。

```js:router.js
export default new VueRouter({
  routes: [],
  scrollBehaivor () {
    return { x: 0, y: 0 }
  }
}
```

いちいちscrollTop(0, 0)の関数を作って呼び出す必要はなかった。

リファレンス
https://router.vuejs.org/ja/guide/advanced/scroll-behavior.html
Postico の "Resolving localhost failed. Hostname not found"  というエラー

PosticoでAWS上のDBを見ようとしたら `Resolving localhost failed. Hostname not found` というエラーが出た。

## Postico User Guide によると
https://eggerapps.at/postico/docs/v1.1/connection-issues.html

```
This message is usually caused by a problem in your /etc/hosts file. The default contents of this file are (on OS X 10.11):

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1	localhost
255.255.255.255	broadcasthost
::1             localhost 
Reverting changes to /etc/hosts should fix this connection issue.
```

*"大体 `/etc/hosts` ファイルに問題があるせいでこのメッセージが表示されるんだよ"*
的なことが書いてある。

でも昨日までは問題なく見れていて、 `/etc/hosts` ファイルを編集した覚えもないのになぁ...と思っていた。

## 原因
どうもAWSで障害起きているようで、私以外の人も同じく Postico が見れないようです。
（2019/10/23 14:30現在）
AWSの障害が治ったら解決しそうなので、解決次第また追記します。

### 追記
AWSの障害が治っても解決しなかったんですが、ネットワークを変えるとなおりました。
AWSの障害が起こったときに使っていたネットワーク自体がキャッシュを持っているらしく、障害が治ってもそのキャッシュが消えない限りは状況が変わらないそう
（24時間ぐらいでキャッシュも消えるらしい）
三項演算子を使って、数値の往復処理をちょっと綺麗に書く

## まえがき
ある数値が下限に達したら増え、上限に達したら減るという処理を綺麗に書けたらいいなという記事です。
軽い内容なので休憩程度に読んでいただけたらと思います。

## コード
```javascript
let targetNum = 0
let status = 0
const max = 100
const min = -100

status === 0
  ? targetNum !== max
    ? targetNum++
    : status = 1
  : targetNum !== min
    ? targetNum--
    : status = 0

//if文で書いた場合こうなる
if (status === 0) {
  if (targetNum !== max) {
    targetNum++
  } else {
    status = 1
  }
} else {
  if (targetNum !== min) {
    targetNum-- 
  } else {
    status = 0
  }
}
```

### 説明
見ての通り、「targetNumが、max・minに達していなければ増減させ、達していればstatusを切り替える」というシンプルな処理を、三項演算子のネストを用いて書いています。（蛇足ですが個人的には、ネスト1階層までなら実用的かなと考えています）

今回はわかりやすく整数を使い、上限値、下限値を超える想定もしていないコードですが、条件式の部分をいじれば色々応用は効くかと思います。

それでは！
BigQueryで分割テーブルを作る際にハマったこと

BigQueryで分割テーブルを作った際にエラーになった現象について

# 3行で
- Bigqueryで2000日を超える分割テーブルを作成しようとするとエラーになる
- だから時系列データが約６年を超えそうならテーブル自体を分けて管理する必要がある
- 分割テーブルの設定有無で課金額が変わってくるので重要


# そもそも分割テーブルはなぜ必要か
BigqeuryはRedshiftとは違ってクエリ単位での課金なので、「自分が使った分だけ」請求が来る。
ただ、この「使った分」の定義は**列単位**での課金なので、次のような問題が起こる。

1. `Limit`で行を制限してもフルスキャンするので**テーブル全体**に対して課金される
2. `Where`で行を制限してもフルスキャンするので**テーブル全体**に対して課金される

ワォ。。。

列課金だからね、しょうがないね。。。

なので、普通のRDBやRedshiftを使い慣れた人が、数TBあるトランザクションデータで集計しようとしたとき

「特定の期間の特定の製品の販売実績を抽出したから大した課金額にならんやろ」

と思っていてもかなりの金額が課金される可能性がある。

上記のような状態を防ぐためにもBigQueryでは

1. 時系列の分割オプション（さらにクラスタオプションも）を指定して走査範囲を限定する
2. クエリする際に日付部分をワイルドカードで指定して取り出すことで１テーブルあたりのデータ量を小さくする

といった工夫が必要になる。

# エラーの原因は何か
私も一部のデータを集計したいのに毎回全件課金されるのは防ぎたかったので、分割テーブルを作成することに。

[公式のリファレンス](http://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language?hl=ja#creating_a_new_table_from_an_existing_table)を調べたところ、
`CREATE TABLE [PJNAME.DATASETNAME.TABLENAME] AS SELECT`で既存のテーブルから新規テーブルが作れるっぽかったので早速実行。

元々のデータは時系列の分割パーティションが適用されていない株価データ１０年分だったので、日付としては365*10=3650と3650日分の分割が実行されるはずだった。

```sql
 -- Create table from stock data
 CREATE TABLE `[PJNAME].[DATASETNAME].[NEWTABLE]`  
 PARTITION BY date
 AS
 SELECT
     date
     open
     high
     low
     close
FROM `[PJNAME].[DATASETNAME].[EXISTTABLE]`
;

```

しかし、下記のエラーが返ってきた。。。

`Too many partitions produced by query, allowed 2000, query produces at least 4418 partitions`

さらに[公式のリファレンス](https://cloud.google.com/bigquery/quotas#partitioned_tables）)を調べたところ、分割パーティション可能なのは**2000**
までとのこと

え、

そうなん？？

少なくない？？

# じゃあどうすればいいのか？

つまるところ、日付が2000日を超えなければ良いわけなので、エラーが出ないように期間を絞ることに

```sql
 -- 期間を絞ってテーブルを作成
 CREATE TABLE `[PJNAME].[DATASETNAME].[NEWTABLE]`  
 PARTITION BY date
 AS
 SELECT
     date
     open
     high
     low
     close
FROM `[PJNAME].[DATASETNAME].[EXISTTABLE]`
WHERE
date between "2015-01-01" and "2018-12-31"
 ;

```
こうすると確かにテーブルが作成できた。原因はやはり分割テーブルで指定した日付が２０００を超えたことが原因であるらしい。

でも、これだと５年以上の長めの時系列データを１つのテーブルで管理できなくて不便。。。

## ワイルドカードと分割テーブルを組み合わせる
１つのテーブルで2000日のデータをぶち込もうとするから問題が起こるわけなので、BQの機能をいい感じに使うのならワイルドカードと分割テーブルを組み合わせるのが良いのでは？？と考えている

今回のケースであれば、１年ごとにテーブル自体を分けることで対応（１年は365日なので2000日に収まるし）

こんな感じ

```sql
 -- テーブル名に2015から2017までのサフィックスを付けて３つテーブルを作成する
 CREATE TABLE `[PJNAME].[DATASETNAME].[TABLE_PREFIX]_{2015,2016,2017}`  
 PARTITION BY date
 AS
 SELECT
     date
     open
     high
     low
     close
FROM `[PJNAME].[DATASETNAME].[EXISTTABLE]`
WHERE
--2015年ならば
date between "2015-01-01" and "2015-12-31"
/*
date between "2016-01-01" and "2016-12-31"
date between "2017-01-01" and "2017-12-31"
*/
 ;
```

で、年を跨いで任意の期間のデータ取得する場合はこんな感じでアクセスする

```sql
SELECT
     date
    ,open
    ,high
FROM
    `[PJNAME].[DATASETNAME].[TABLE_PREFIX]_*`
WHERE
     date between "2016-01-01" and "2017-05-31"
LIMIT 1000 --別に課金には影響しないけど一応付けておく
;
```


おしまい
Excel マクロ VBA Macro Ping ネットワーク監視 / 記録シートの例

This article explains how Excel macro VBA may be used to monitor servers or network and automatically save status into the Excel file.

Excelで多数のサーバー、ネットワーク機器のpingを監視し自動上書き保存するVBAマクロの例です。高価な監視ツールに頼ることなく興味があるシステムのみに絞り込みExcelなのでコメントを追記できますし管理者権限も入りませんから定期チェックやシステム変更作業前後にご利用ください。

前提条件：
・Sheet1というシート名があること
・B3セルから下方向にサーバー名またはIPアドレスが途切れることなく列挙されていること
・C3セルからC999セルまでが結果の記録セルで毎回記録内容のリセットがされること
・A2セルに最終更新日を書き込むこと
・ファイルは自動上書き保存されること

C列の3行目以降で最終行までは表示条件設定を行い文字列が Connected の場合には水色の背景、そうでなければ赤色の背景にすることで目立たせることをお勧めします。

条件は必要に応じ書き換えください。


##マクロ VBA の例

```
Function GetPingResult(Host)
   Dim objPing As Object
   Dim objStatus As Object
   Dim Result As String

   Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}"). _
       ExecQuery("Select * from Win32_PingStatus Where Address = '" & Host & "'")

   For Each objStatus In objPing
      Select Case objStatus.StatusCode
         Case 0: strResult = "Connected"
         Case 11001: strResult = "Buffer too small"
         Case 11002: strResult = "Destination net unreachable"
         Case 11003: strResult = "Destination host unreachable"
         Case 11004: strResult = "Destination protocol unreachable"
         Case 11005: strResult = "Destination port unreachable"
         Case 11006: strResult = "No resources"
         Case 11007: strResult = "Bad option"
         Case 11008: strResult = "Hardware error"
         Case 11009: strResult = "Packet too big"
         Case 11010: strResult = "Request timed out"
         Case 11011: strResult = "Bad request"
         Case 11012: strResult = "Bad route"
         Case 11013: strResult = "Time-To-Live (TTL) expired transit"
         Case 11014: strResult = "Time-To-Live (TTL) expired reassembly"
         Case 11015: strResult = "Parameter problem"
         Case 11016: strResult = "Source quench"
         Case 11017: strResult = "Option too big"
         Case 11018: strResult = "Bad destination"
         Case 11032: strResult = "Negotiating IPSEC"
         Case 11050: strResult = "General failure"
         Case Else: strResult = "Unknown host"
      End Select
      GetPingResult = strResult
   Next

   Set objPing = Nothing

End Function

Sub GetIPStatus()

  Dim Cell As Range
  Dim ipRng As Range
  Dim Result As String
  Dim Wks As Worksheet

Set Wks = Worksheets("Sheet1")

Set ipRng = Wks.Range("B3")
Set RngEnd = Wks.Cells(Rows.Count, ipRng.Column).End(xlUp)

Range("C3:C999").ClearContents


Set ipRng = IIf(RngEnd.Row < ipRng.Row, ipRng, Wks.Range(ipRng, RngEnd))

  For Each Cell In ipRng
    Result = GetPingResult(Cell)
    Cell.Offset(0, 1) = Result
  Next Cell

Range("A2").Value = Date

ActiveWorkbook.Save

End Sub

```
AWSでサーバレスな動画解析(Amazon Rekognition)


こんにちは。
日々の業務ではインフラエンジニアをやっています。@hayaosatoです。

最近は動画解析などの技術も流行っていてそれらのSaaSも提供されていますね。
AWSでは[Amazon Rekognition](https://aws.amazon.com/jp/rekognition/)(以下、Rekognition)というサービスが提供されています。
本記事ではこのRekognitionを使うためのサーバレスアーキテクチャを構築してみたいと思います。

### 構成
構成図は以下の通りです。
![Untitled Diagram.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312728/d5399d18-10c1-a0a7-c166-d7ef55d7291e.jpeg)
Rekognitionで動画解析を行うと、動画の長さによりますが解析時間がかかってしまいます。
Rekognitionでは解析時間の完了をAmazon SNS(以下、SNS)のトピックを発行することで通知してくれます。
今回はS3に動画がアップロードされたことをトリガにAWS Lambda(以下、Lambda)からRekognitonの動画解析開始
Rekognitionの動画解析完了後SNSトピックからLambdaを呼び出し、LambdaからRekognitonの解析結果を取得する
というアーキテクチャを作ってみます。

### S3 -> Lambda
Lambdaファンクションを作成し、トリガを設定します。
この際に注意すべきは動画はファイルサイズが大きくなりがちなので、
マルチパートアップロードの完了時もちゃんとトリガが飛ぶようにしておきましょう。

### Lambda -> Rekognition -> SNS
Rekognitionで解析を開始するためのLambdaファンクションを作成します。
言語はPythonにしました。ドキュメントは[こちら](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rekognition.html)。
今回は顔認識を使ってみることにしたので、`start_face_detection`を使用します。

```python
response = client.start_face_detection(
    Video={
        'S3Object': {
            'Bucket': 'your-bucket-name',
            'Name': 'your-video-name'
        }
    },
    ClientRequestToken='string',
    NotificationChannel={
        'SNSTopicArn': 'your-sns-topic-arn',
        'RoleArn': 'your-role-arn-for-rekognition'
    }
)
```

ここで、`NotificationChannel`にSNSとROLEのARNを指定しています。
`SNSTopicArn`はその通りRekognitionが解析完了した際に通知を飛ばすためのSNSトピックのARNです。
`RoleArn`はRekognitionがSNSトピックを飛ばすためのRoleを与える必要があります。


### SNS -> Lambda -> Rekognition
Rekognitionから発行されたSNSトピックからLambdaが呼び出されるようにサブスクリプションを作成したら、
最後にLambdaからRekognitionに対して動画解析の結果を取得します。

Lambdaに届くeventの'Sns'キーのValueは以下のようになっています。

```event['Records'][0]['Sns'].py
{
    'Type': 'Notification',
    'MessageId': 'xxxxxxxx',
    'TopicArn': 'arn:aws:sns:your-region:your-account-id:your-topic-arn',
    'Subject': None,
    'Message': '{"JobId":"xxxxxxxxxx","Status":"SUCCEEDED","API":"APINAME","Timestamp":1571799891913,"Video":{"S3ObjectName":"your-video.mp4","S3Bucket":"your-video-bucket"}}',
    'Timestamp': '2019-10-23T03:04:52.660Z',
    'SignatureVersion': '1',
    'Signature': 'xxxxxxxxx'
    'SigningCertUrl': 'https://sns.ap-northeast-1.amazonaws.com/SimpleNotificationService-xxxx.pem',
    'UnsubscribeUrl': 'https://sns.ap-northeast-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:xxxxxx',
    'MessageAttributes': {}
}
```
このようにして、Messageを取り出すことでRekognitionから結果を抜き出すための情報が揃います。
Messageから`JobId`を抜き出して、

(NextTokenは省略しています。)

```python
response = client.get_face_detection(
    JobId='xxxxxx'
)
```
Rekognitionから解析結果のJSONを受け取りことができます。

### まとめ
このようにして、Rekognitionを利用してサーバレスなアーキテクチャを作成してみました。
サーバレスでイベントドリブンってやっぱりいいですね
コードは[こちら](https://github.com/hayaosato/rekognition-batch)
nixOSでWPA-EAPなWiFiに接続する

# 対象読者のスキル

コマンドライン操作ができること
英語がちょっと読めること

# 前提

無線カードのドライバがインストールされており，認識されている
無線LANのSSIDとログインに必要な情報を持っている
wpa_supplicantがインストールされている

# 使用環境

動作確認した環境は以下の通り

- nixOS 19.09.716.88bbb3c809
    - Kernel 4.19.78
    - wpa_supplicant v2.9
- Let's note CF-MX3
    - CPU: Intel i5-4200U
    - RAM: 4GB
    - SSD: 128GB

# 問題

[公式のインストールマニュアル](https://nixos.org/nixos/manual/index.html)に記載されている無線LAN設定はWPA-PSKを前提としているため，IDとパスワードの入力を必要とするWPA-EAPな無線LANに接続できない

# それっぽい情報を見つけた
こんな感じで`/etc/nixos/configuration.nix`のネットワークを設定すると繋がった

```
networking.wireless.networks = {
  "eap wifi" = {
     auth = ''
         key_mgmt=WPA-EAP
         eap=PEAP
         identity="user_name"
         password="user_password"
     ''
  };
};
```

# 参考リンク
https://github.com/NixOS/nixpkgs/issues/29622
https://wiki.archlinux.org/index.php/WPA_supplicant
ParaViewがCSVファイルを読み込んで「Could not determine array range」とエラー表示したら

研究でParaViewを使っているのですが、先日いつものようにCSVデータを3D表示してスカラ値で色分けしようとしたらエラー表示されました。

ネット上で探してもあまり解決策が記載されてなかったので、記事にしておきます。

【問題】

CSVデータをTable to Pointsで3D表示し、Coloringをスカラ値で色分けしようとするとエラー「Error Could not determine array range」と表示される。

【解決】

CSVのフォーマットを確認したところ「CSV UTF-8」となっていました。
このフォーマットを「CSV」に変更することで問題が解消されました。
フォーマットの変更はExcelの名前を付けて保存をしたときの「ファイルの種類」から選べます。

 

上記の解決策でもダメな時は分かりません。
画像を円形に表示　#object-fit #CSS #Ruby on Rails  #Progate 

#やりたいこと
・画像を円形に表示したい
・画像を表示するスペースに合わせて画像を縮小or拡大したい
・表示する画像の縦横比は変えないで実現したい

#経緯
・ProgateでRuby,Ruby on Rails,HTTM&CSSを学習し、現在tweet_appを再現中！
その中でつまずいた箇所の備忘として。


#解決方法
①画像を加工　→面倒臭そう・・・なので今回は無視しました
②cssで指定　→今回はこれでやります


まずHTMLで画像を表示します。

```ruby:HTML
img(src="sample.jpg")
```
次にCSSで設定していきます。

```ruby:CSS
img {
  border-radius: 50%;  /* 角丸半径を50%にする(=円形にする) */
  width: 100px;  /* 縦横を同じ値にする */
  height: 100px;  /* 縦横を同じ値にする */
  object-fit: cover; /* 縦横比固定したまま上2つの縦横の範囲内に収まるように配置する */
}
```

これだけ！簡単！
ただ、
border-radiusを50%にすると円になるのはなんで？
object-fitってなに？ないとどうなるの？
という疑問が湧いてきたので少し調べてみました。

#解説
※初心者が調べて解釈した結果になります。訂正・追加があればぜひコメントください！

```
border-radius: 50%;
```
・50%の場合、四角い画像が正方形になる
・pxで指定する場合は、widthとheightで指定したpx値の半分にする(100pxの場合は50px)。
・0%（0px)に近づけるほど、円ではなく四角に近づく
・考え方：四隅にくっつく円を4つ作り、直角の代わりに円の一部分（四角と円の接点から接点までの弧）を表示する。円の半径が小さいほど四角に近づき、大きいほど（ただしMAX50%)円に近づく
・Progateでは、border-radiusを使ってボタンの角を少しだけ丸にしていた

```
width: ◯◯px; 
height: ◯◯px;
```
・画像の大きさを決める（値が大きいほど大きな円になる）
・幅と高さは同じ値にする（円なので）

```
object-fit: cover;
```
・object-fitでは、widthとheightで定めたスペースへの”はめ込み方”を決めることができる
・今回は　はめ込むスペースに合わせて画像を縮小or拡大する、縦横比は変えない、多少カットされても良いからなるべく大きく表示する、の３つを満たしたかったのでcoverとしました。[こちら](https://developer.mozilla.org/ja/docs/Web/CSS/object-fit)がとてもわかりやすかったです。
・border-radius,width,heightだけでも画像を円にできるが、指定したwidthとheightのpxと画像のpxに差がある場合はおすすめできない（画像の一部しか表示されないor画像がかなり小さくなってしまう）

◆参考サイト
https://www.nishishi.com/css/trim-image-to-circle.html
https://developer.mozilla.org/ja/docs/Web/CSS/object-fit
【勉強用】OSとLinuxについて初心者視点から

##免責事項
この記事は初心者視点でザックリとした説明をしています。正確性に欠ける可能性がございますが、ご了承ください。「明らかに違うよ」ということがありましたら、ご指摘くださると幸いです。

##目次
1. OSとは
2. Linuxとは


#1. OSとは
OSとはOperating System （オペレーティング・システム）の略で、 人間がコンピュータを使う上で便利にしてくれるものです。

スマートフォンで言えば、
iPhoneではiOS、AndroidではAndroidOSが使われています。
パソコンで言えば、
WindowsではWindowsOS、MacではmacOSが使われています。

###OSの機能
OSの役割はプログラムの実行と管理を行うことです。
その役割上で、ザックリと以下の4つの管理を行います。
####①ファイルの管理
ファイルとは、PC上で情報を書くための紙のようなものです。.htmlや.txtや.jsonなどと付いているものがファイルと思ってください。ちなみに、ファイルをまとめるものをディレクトリ（フォルダ）と言います。
####②メモリの管理
ゲームキューブやプレステ2でメモリースティックというものを使いました、これを外部メモリと言いますが、ここで言うメモリはパソコンの内部メモリのことです。
スマートフォンやパソコンでアプリをたくさん使うと動きが遅くなりますよね。これはメモリがいっぱいになっている状態です。
####③GUIの管理
GUIとはグラフィカル・ユーザー・インターフェースの略で、パソコンやスマートフォンの見える部分です。見える部分とはこれです。
![スクリーンショット 2019-10-23 12.57.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374924/a16a113c-3c27-f343-49e1-4e83d2b0975f.png)
パソコンは本来、専門的な人だけが使えるものでしたが、誰もが使えるようにこのような見やすい画面を採用しました。

※WindowsやMacのGUIはOSが管理しているものですが、Linuxでは別のアプリを用意しないとGUIを使うことができません。
####④ネットワーク管理
ネットワークはパソコン同士をつなぐものです。これがなかったらパソコン同士で通信は行えません。

#2. Linuxとは
LinuxとはOSの1つです。正確に言うとOSの中のカーネルという部分を差しますが、ここではOSとして扱います。

###Linuxの機能
Linuxの機能はWindowsOSやmacOSとほとんど変わりません。
ディストリビューションというOSの機能がまとまったものを使えば簡単にたくさんの機能を使うことができます。

###なぜ使うのか（自分なりの解釈）
####①どの環境でも使えるから
Linuxは仮想環境を使えば、macやWindowsなどのどのようなパソコン上でも使うことができます。そのためエンジニアが各々の好きなPCで利用することができるため使われています。
####②無料で使えるから
mac上にwindowsを使うにはお金がかかりますが、Linuxを使う場合はお金はかかりません。
####③サーバーとして使いやすいから
企業がアプリを世の中に出すときにはサーバーというものが必要です、サーバーを立てる際にLinuxは比較的高速であり、どんなPC（環境）でも使えるためよく利用されています。サーバーを借りるにしても、自社製にするとしても30%ほどのサーバーでLinuxが使われています。また最近ではIaasクラウドなどでもLinuxが利用されています。

##参考
「N予備校 プログラミングコース」
https://www.nnn.ed.nico/
「サーバーOSとは？UNIX系とWindows系の違いをわかりやすく解説します」
https://www.kagoya.jp/howto/rentalserver/serveros/
「【初心者向け】3分でわかるLinuxでできることまとめ 10選」
https://eng-entrance.com/you_can_do_linux
「Linuxってなに？ WindowsやMacとの違いや使い方までお答えします」
https://www.lifehacker.jp/2017/11/171105-how-to-get-started-with-the-linux-operating-system.html
Singing Synthesis 論文のメモ

Sequence-to-sequence Singing Synthesis Using the Feed-forward Transformer
https://mtg.github.io/singing-synthesis-demos/transformer/

昨今流行りの FFT(Feed-forward Transformer)を使って歌声生成


上と同じ研究室の既存研究

A Neural Parametric Singing Synthesizer
https://mtg.github.io/singing-synthesis-demos/
Visual Studio Code の拡張機能「vscode-reveal」で reveal.js を使ってみる

# reveal.js とは

**Markdown** に対応した、プレゼン資料を手軽に作成できるツール
VSCode の拡張機能「[vscode-reveal](https://marketplace.visualstudio.com/items?itemName=evilz.vscode-reveal)」を利用すれば手軽に動作を試せます。
ライトニングトークや上司に軽いプレゼンをしたい時にオススメ

## どんなことが出来るのか

[reveal.js 公式デモ](https://revealjs.com/#/)
こんな感じの資料が Markdown で作れます

## 環境設定

### 拡張機能のインストール

※Visual Studio Code の基本的な操作方法は省略します。

1. Visual Studio Code を起動する。  
2. 拡張機能で [reveal] を検索する。  
3. [vscode-reveal] が検索結果に表示されたら [インストール] ボタンをクリックする。
![vscode-reveal.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259465/c6ec9ca4-e883-6339-2fc2-cf609d4effbe.jpeg)
4. [インストール] ボタンの表示が [再読込] に変わったら [再読込] ボタンをクリックする。  
5. Visual Studio Code が再起動したら環境設定は終了。

## 動かしてみる

1. ↓のテキストを Visual Studio Code に Markdown 形式で貼り付け

```md
---
theme : "white"
transition : "default"
---

# reveal.js 試してみた

Markdown で書いてみた

---

## 縦スクロール

キーボードの ↓ を押す(vim の hjkl も使える

--

## これは

- reveal.jsを利用した   
- デモになります。

---

## 終わり

ありがとうございました。
```

 [reveal.js] をインストールしたので [エクスプローラー] にスライド一覧が表示されるようになっている  
 クリックすると Markdown を記載してる場所にジャンプする
![slide.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259465/dafe5b5f-7d63-4ff9-1162-768c2aa75a8f.jpeg)

2. コマンドパレットで [reveal] を検索する。 
![command.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259465/7c42d9f7-3332-be35-59e6-854330b08cf1.jpeg)
3. [Open presentation in browser] をクリックする。  
   ※他のコマンドで PDF出力、HTML出力、Visual Studio Code 上でのプレビューも可能
4. ブラウザが起動して作成した資料がプレビューされる。

![white.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259465/a132b2ae-a2d5-6b92-d9c5-10dd9a52e2e6.jpeg)


### テーマ色を変えてみる

この部分を

```md
theme : "white"
```
"black" に変えるだけで黒背景に対応

![black.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259465/e4f28d54-8a55-98ee-b16c-74a68888133a.jpeg)

## 詳細な使い方や設定

[公式のREADME](https://github.com/hakimel/reveal.js/blob/master/README.md) を読むと他にも色んな表現が出来るようになります。
VSCode が動く環境であれば、どこでも使えるという点も便利です。

### 参考リンク

[vscode-reveal - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=evilz.vscode-reveal)
[reveal.js - GitHub](https://github.com/hakimel/reveal.js/)
[reveal.js 公式デモ](https://revealjs.com/#/)
PythonでTwitter APIを使ってTerminalからツイートする

Twitter APIを使ってみようという事で、ターミナルからツイートするアプリを作りました。
この記事を見る方は、Twitter APIを初めて使う方が多いと思うので入門にオススメの記事の紹介もしておきます。
紹介した記事を見れば、私が書いたコードは理解できると思うので説明は省きます。
まずは、コピペして動かしてみてTwitter APIを楽しんでください！

#はじめに
予め読んでおいて欲しい記事を紹介します。
1. Twitter APIの申請手順 -> [kngsym2018様の記事](https://qiita.com/kngsym2018/items/2524d21455aac111cdee)
2. APIって何？ドキュメントってどうやって読むの？ -> [masahiro_isonoさんの記事]
 (https://qiita.com/masahiro_isono/items/a6cfdd073686100f0ef1)
3. 公式ドキュメント -> [Twitter Developers]
(https://developer.twitter.com/en/docs)
4. 環境変数確認とパスの追加 -> [FJHoshi様の記事]
(https://qiita.com/FJHoshi/items/c847ad51af388d2dbb4a)

#コード
コマンドライン引数にツイートしたい文を打ち込み、プログラムを実行する事でツイートするプログラムです。

```Python3:tweet.py
import sys, config
from requests_oauthlib import OAuth1Session

CK = config.CONSUMER_KEY
CS = config.CONSUMER_SECRET
AT = config.ACCESS_TOKEN
ATS = config.ACCESS_TOKEN_SECRET
twitter = OAuth1Session(CK, CS, AT, ATS)

url = 'https://api.twitter.com/1.1/statuses/update.json'

tweet = ' '.join(sys.argv[1:])
params = {'status': tweet}
res = twitter.post(url, params=params)

print('status: {}'.format(res.status_code))

```
同階層にconfig.pyを作り、そこにAPI Keyとアクセストークン情報が書いてあります。

#環境変数
以上のコードの実行は以下です。

```terminal:terminal
$ python tweet.py hogehoge 
```
ツイートする度にこれをいちいち打つのはめんどくさいですね。
そこで[python tweet.py]の部分を.bash_profileに環境変数として書いちゃいましょう。
[tweet.pyのフルパス]に括弧を消してプログラムファイルのフルパスを入れてください。
詳しくは、紹介した記事の４をみてください。

```terminal:terminal
$ echo export tweet=python\ [tweet.pyのフルパス] >>~/.bash_profile
```
毎回打たなければいけない部分を環境変数にしたことで以下のように簡単にツイートすることができるようになります。
*環境変数を使用する際は、変数名の前に$をつける必要があります。

```terminal:terminal
$ $tweet hogehoge
```

以上でTwitter APIを使ってTerminalからツイートすることができました。
なお、ツイートすると何を使ってツイートされたかが表示されるようになりましたが、APIを通してツイートした場合はアプリ名がそこに表示されるのでくれぐれも変な名前にしてしまわないように気をつけてください。
【備忘録】インターネットサイトから音源を取り出したいときにすること

1.Chromeであれば、⌘コマンド+shift+cでデバッグ画面を開く
2.Sourcesを開き拡張子がmp３のデータを探す。
3.あれば右クリックしてダウンロード

4.なければNetworkを開く。
5.通信データをサイズ順に並べ替えて、大きい方のデータをみる。
動画、音声、画像の順でデータが並ぶと思うのでそれに従って探す。
6.該当データのrequestURLをコピーしそのままブラウザに貼る。
完了
【PHP】オーバーライドについて


親クラスで定義されているメソッドを子クラスで同じ名前のメソッドを作って定義し直す（再定義）することです。
例えば
 
```php
// 親クラス

class Goku {
  public function skill($name, $damage){
    print "名前 = {$name} : ダメージ = {$damage}". '<br>'; 
  }
}

// 子クラス 

class Gohan extends Goku {
  public function skill($name, $damage){
    print "悟飯の必殺技！名前は、{$name}!なんと{$damage}ダメージも敵に与える事ができるんだ！"; 
  }
}

```

子クラスのskill()メソッドをオーバーライドすることにしました。親クラスでは簡潔な情報のみを表示する冷めたメソッドから,子クラスではコロコロコミックの説明文みたいな情報を表示する熱いメソッドに定義し直すことにしました。

ではメソッドを実行します。

```php
$dragonball = new Goku();
$dragonball->skill('かめはめ波', '500');
$dragonballZ = new Gohan();
$dragonballZ->skill('かめはめ波', '500');
```
すると結果、

```
名前 = かめはめ波 : ダメージ = 500
悟飯の必殺技！名前は、かめはめ波!なんと500ダメージも敵に与える事ができるんだ！
```

となります。最初の一行目が親クラスのskill()、その下が子クラスのskill()となっております。オーバーライドされていますね。

オーバーライドの利点ですが、色々な子クラスを作ってオーバーライドしたメソッドを用意しておけば、様々な状況に対応できるみたいです。

しかしオーバーライドをしてしまうと、同じ名前のメソッドが複数存在することになってしまいます。なんか紛らわしいし、目当てのメソッドを呼び出しそうとしたら違うメソッドを呼び出してしまうかもしれないとか思ってしまわれるかもしれません。しかし心配ご無用。特に変わった処理は必要ありません。上記のように普通にクラスのインスタンスを生成してメソッドを結びつけて呼びだすだけでいいそうです。

参考文献
PHPサーバーサイドプログラミングパーフェクトマスター　
著者　金城　俊哉
Openpyxlで保存したブックがXMLエラー

未解決のため、調べたこと、試したことが増え次第、**随時更新予定**です

#環境
windows 10
Microsoft Excel for Office365
Python 3.7.3
openpyxl 2.6.2

#事象

xlsをxlsxとして保存し、openpyxlで別ブックとして保存したとき、xmlエラーが発生する

####エラーメッセージ
```:error.xml
置き換えられたパーツ: /xl/worksheets/sheet1.xml パーツに XML エラーがありました。  
読み込みエラーが発生しました。場所は、行 5、列 0 です。
```

#事象発生までの流れ
####xls→xlsx
xlsファイルをExcelで開き、「名前を付けて保存」でxlsx(Excelブック)として保存
例)input.xlsを開き、「名前を付けて保存」でinput.xlsxで保存

####openpyxl
```python
import openpyxl as px
#inputファイルのpathをコンソール上にドラッグ&ドロップで取得
origin=input()
#openpyxlでxlsxファイルを開く
wb=px.load_workbook(origin)
ws=wb.active
#保存先ファイルとして別名に変更
origin=origin.rstrip(".xlsx")
origin+="px.xlsx"
#inputファイルを別ブックとして保存
wb.save(origin)
```
例)input.xlsxをopenpyxlを通してinputpx.xlsxで保存

####Excelで開く
作成されたxlsxブックをExcelで開くと、

```
'inputpx.xlsx'の一部の内容に問題が見つかりました。
可能な限り内容を回復しますか？
```
とダイアログが出て、
「はい」をクリックすると、

```
'inputpx.xlsx'の修復
読み取れなかった内容を修復または削除することにより、ファイルを開くことができました。

置き換えられたパーツ: /xl/worksheets/sheet1.xml パーツに XML エラーがありました。  
読み込みエラーが発生しました。場所は、行 5、列 0 です。
```
と出る。
開かれたxlsxファイルはすべて空白のセル(新規作成のような状態)になっていた

#調べたこと、気づいたこと

####xls,xlsxについて
- xlsはBIFF（Binary Interchange File Format）,xlsxはxml
- xlsxは拡張子をzipに変えると、そのxlsxを構成するxmlを見ることができる
- 一般に、sheet1に対応するxmlは\xl\worksheets\sheet1.xml
- zipに変えたものをxlsxに戻して開くと「ファイルが壊れています」となり、開けない

- エクスプローラーの「名前の変更」で拡張子をxls→xlsxに変えても、ファイルの中身はxlsのため、開こうとしたときにエラーで開けない

####error.xmlについて
xmlを見たとき自分が気づいた点として、
正常に開けるファイル(openpyxlのinput側ファイル)の先頭にある

```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
```
がxmlエラーを起こすファイルにない

#試したこと
- もともとのxlsファイルの書式を調べる
 
自分が確認できた範囲で、
セル結合、塗りつぶし、データの入力規則(プルダウン)、改ページプレビュー表示

自分の学習範囲で、openpyxlで編集できる書式としてセル結合、塗りつぶしが挙げられる。
塗りつぶしが悪さをするだろうか…と思ったのと、
過去の経験から、pythonでExcelファイルを扱うとき、セル結合はとても厄介だったため、セル結合あり/なしで検証した

---

1. xlsxブックを新規作成,openpyxlを通して別名保存
結果:正常に開ける

1. xlsxブックを新規作成(セル結合あり),openpyxlを通して別名保存
結果:正常に開ける

1. xlsブックを新規作成,xlsxで保存後,openpyxlを通して別名保存
結果:正常に開ける

1. xlsブックを新規作成(セル結合あり),xlsxで保存後,openpyxlを通して別名保存
結果:正常に開ける

以上の結果から、xls→xlsxの変換、セル結合あり/なしは正常に開けるかどうかに影響しないことが言えそう

---


1. "気づいたこと"より、正常に開けないファイルのxmlにないものを追加してみる

結果:
> - zipに変えたものをxlsxに戻して開くと「ファイルが壊れています」となり、開けない

のため、xmlを編集したものをxlsxとして開くことはできなかった

#とった対処法
"試したこと"から、新規作成したxlsxファイルについては問題なく開けたため、
もともとのxlsファイルと同じものをxlsxで新規作成(手作業)して、それをinputファイルとすることで、
やりたかった作業をpythonで行うことができた。

#考察

1. openpyxlのバグ？
2. openpyxlはもともとxlsxファイル対応のため、xlsが絡むファイルについてうまく扱えないことがある？
3. そもそものxlsファイルに異常が隠れている？


#今後
 未解決のため、今後も調査、検証を行っていくつもりです。
解決法をご存知の方がいらっしゃいましたらご教示いただけると幸いです。
タブレット非対応apkをタブレットにインストールする

スマホで使っているアプリで、「大画面で見たいからタブレットに入れたいな」と思うことがあります。
しかし、タブレットでGooglePlayを開いて検索しても検索結果に出てこず、アプリページのリンクを直接タブレットで開くと「お使いのデバイスはこのバージョンに対応していません。」の表示が。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192408/9e1927ab-3398-6e2a-654f-fc5055dcd20d.png)


ただ、諦めるのはまだ早いです。
OSが対応している場合はインストールできる可能性があるので、その方法を記したいと思います。

# 仕組み
インストールできるOSは、アプリコードのminSDKVersionで決まります。
なので、対応していないOSの場合はapkのインストール時に弾かれるため、インストールすることはできません。
一方、OSは対応している場合は、制作側がGooglePlayコンソールで対応アプリから除外している可能性があります。

- タブレット端末で使われる想定をしていないアプリ
- 対象CPUが限られている場合
- 検証が十分にできていない場合
- 特定の機能が入っていない場合(位置情報やマイク・カメラなどなど)
- 端末固有の不具合が発生する場合

必要な機能が入っていない場合やCPUが対応外、不具合がある場合はインストールできたとしても使えないかもしれませんが、他の理由の場合はインストールして使うことができる可能性があります。

# 注意
**`制作側が意図して除外していると考えられるため、なにか不具合が生じても自己責任です。
制作側に問い合わせたり、うまく動かないとレビューするのはやめましょう。
あくまで、個人的にちょっと快適に使えたらなということで、備忘録がてら記事にしています。`**

# インストール手順
3行で言うと

[1. apkを探して持ってくる](#1-apkを探して持ってくる)
[2. 追加ファイルをコピーする(必要があれば)](#2-追加ファイルをコピーする必要があれば)
[3. インストールして追加ファイルを配置する](#3-インストールして追加ファイルを配置する)

です。
簡単ですね。

## 1. apkを探して持ってくる
まずは、スマホにapkをインストールします。
この時、パッケージ名をメモっておきましょう。
GooglePlayのurlから調べることができます。
`https://play.google.com/store/apps/details?id=パッケージ名`
今回は、`example.hoge.fuga`とします。

インストールできたら、端末をPCと接続して、adbコマンドを実行し、パッケージ名とapkの保存場所を調べます。

```
adb shell pm list packages -f example.hoge.fuga
```
すると、検索結果が出力されます。

```
package:/data/app/example.hoge.fuga中略==/base.apk=example.hoge.fuga
```
base.apkというのがapk本体なので、これをPCに持ってきます。

```
 adb pull /data/app/example.hoge.fuga中略==/base.apk
```
こうすると、今のディレクトリにbase.apkがコピーされます。
(分かりづらいので名前を変更すると分かりやすいです)

##2. 追加ファイルをコピーする(必要があれば)
100MBを超えるアプリの場合、obbという仕組みを利用して、apkとは別に拡張ファイルがスマホに入っています。
`Android/obb/パッケージ名`
ファイルエクスプローラーやターミナルで見られるので、探してフォルダごとPCにコピーします。

##3. インストールして追加ファイルを配置する
ファイルが揃ったのでインストールします。
今回はタブレットに入れるのが目的だったので、タブレットを接続して下記コマンドを実行します。

```
adb install base.apk
```
apkのインストールは完了です。

追加ファイルがある場合には、ファイルエクスプローラーやターミナルを使い、先程コピーしてきたobbのフォルダをタブレットの
`Android/obb`
にコピーすればOKです。

タブレットにアプリが表示されるはずなので、起動して成功すれば完了です。

# 備考
GooglePlayからの配信形式がapkではなくaabの場合は、スマホにインストールした時点で解像度やCPUに最適化されたリソースだけがインストールされるため、タブレットで動かない可能性があります。

# 最後に
以上、タブレット非対応apkをタブレットにインストール方法でした。
あまりやる機会はないかもしれませんが、大画面で使いたいアプリが使えるようになるのは便利です。
なにか不具合が起こったとしても自己責任で、制作側にはなんの責任も落ち度もないため、試す場合はそれを理解した上で行っていただければと思います。
また、不具合が起きた場合はすぐアンインストールし、以後使わないようにしましょう。
アプリによっては制作側が不具合のログを取っている場合があり、それに雑音が加わる場合がありますので。
脱出ゲームの作り方　 ５ 電球のON/OFF

###スクリプトの作成

LightstandManagerを作成し、LightstandPanel（オブジェクト）に張り付ける。

:page_facing_up:LightstandManager.cs

using UnityEngine.UI;を追加する。

lightON、lightOFF、の画像を用意
image型の変数image（画像を入れる）

    [SerializeField] Sprite lightON;
    [SerializeField] Sprite lightOFF;
    [SerializeField] Image image;


スイッチのON/OFFで画像を差し替える

```csharp

   public void LightSwitch(bool isON)
    {
        if (isON)                 //isONがtrue
        {
            image.sprite = lightON;  //imageの画像をlightONにする
        }
        else                           //そうでなかったら
        {
            image.sprite = lightOFF;   //imageの画像をlightOFFにする
        }
    }
```


※テスト
ItemBoxの左から１つ目のボックスをクリックしたら点灯し
２つ目のボックスをクリックしたら消灯する

InspectorでItemBoxのButtonコンポーネントの On Click() にLightstandPanel（オブジェクト）をセットして、
LightstandManagerに表示される関数をからLightSwitch()を設定する。チェックをつけてtrueにする。

InspectorでIItemBox (1)のButtonコンポーネントの On Click() にLightstandPanel（オブジェクト）をセットして、
LightstandManagerに表示される関数をからLightSwitch()を設定する。チェックなしでfalseにする。


:point_up:
全画像でこのような表示にになっていて、今回はここを使わないので特に関係ない。
![Images_q.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144922/19b6313f-a805-f48c-5be8-245db6f27346.png)



##教材
**Unityゲームスタジオ スタジオしまづ**
**【Unity】初心者からの脱出！？　脱出ゲームの作り方　その５ 電球のON/OFF**
https://youtu.be/S8G9LE0LNq8
Nasted VM on Azure で Internal Network を構築し KMS 認証を通す

仕事で Nasted VM on Azure を扱うシーンがあり、 KMS 認証の手順が少し特別だったので、今回の記事では Internal Network を構築する方法、実際に Win10 on Nested VM の KMS 認証を通す方法を纏めます。
以下の記事では、VM on Azure のことを「Host VM」、VM on Host VM のことを「Nested VM」と呼ぶことにします。また前提として、Host VM の Hyper-V で Windows 10 を実行していることを前提としています。

#Internal Network を構築する
まず Nested VM でもインターネットに接続できるようにネットワークを構築します。Host VM に Internal Network を構築し、その IP アドレスを Hosted VM に割り当てることでインターネットに接続できるようになります。(検証環境等でこの方法は使います。)

まずは Host VM にて Internal Network を構築します。Host VM の Hyper-V Manager より、[Virtual Switch Manager] を開き、"Internal" を選択し、[Create virtual Switch] します。名前は任意ですが、サンプルとしてここでは Internal Azure と名付けました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/6163fe70-3fd0-98f8-497e-e4bb377b88e1.png)

InternalAzure というネットワークを構成したら、NestedVM 側で以下の PowerShell コマンドを実行します。この二つのコマンドは、NAT 作成と"InternalAzure" 仮想ネットワーク アダプターに対して、IP アドレスを設定しています。

```
New-NetNat –Name myNAT –InternalIPInterfaceAddressPrefix "172.16.1.0/24"
Get-NetAdapter "vEthernet (InternalAzure)"| New-NetIPAddress -IPAddress 172.16.1.1 -AddressFamily IPv4 -PrefixLength 24
```

#Nested VM を Internal Network に参加させる
上記の手順でネットワークを構築したら、Nested VM を Internal Network に参加させます。まずは Hyper-V の Nested VM の Setting を開き、ネットワークアダプターの設定で、先ほど構築した「InternalAzure」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/18e32bd7-5a43-96be-608e-791b5a02d104.png)

次に Nested VM のネットワークの環境設定にて、以下の情報を手動で割り振る設定をします。NIC のプロパティから IP アドレスを手動で設定します。この例では以下のように設定しました。

>IP アドレス: 172.16.1.5 <任意のものでOK>
サブネット マスク: 255.255.255.0
デフォルト ゲートウェイ: 172.16.1.1
DNS サーバー: Azure標準のもの

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/ee5ddbae-32d1-3504-2c6a-ba8b44a83bc5.png)

上記2つを実施すると、Nested VM が外のインターネットに接続することができます。

#KMS 認証を実施する
KMS 認証は時々走るライセンスに不正がないか確認するための認証です。この認証をあらかじめ実施するサーバーを決めておくことで、認証が正常に通ったと認められることができます。例えば、Active Derectory の Domain に参加する際には KMS 認証が通っていることが前提となりますので、DC 参加をする際に KMS 認証が通っていないと参加に失敗します。KMS 認証はそんな難しくなく、コマンドで実行することが出来ます。

```
//System32 まで移動
cd \Windows\System32
cscript slmgr.vbs /ato
```

これで認証が走ります。実際に KMS サーバーを指定する前に認証を走らせるとどのようなことが起きるでしょうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149921/fc8272af-ac3c-1669-a06b-9fb9afdaf99a.png)

上記のように認証が走りますが、KMS サーバーがないので認証を走らせることができないと怒られます。
KMS サーバーを指定するために、Host VM のコマンドで以下を実行します。

```
//System32 まで移動
cd \Windows\System32
cscript slmgr.vbs /dlv
```
これを実行すると Host VM のライセンスが通っている KMS サーバーの IP アドレスを見つけることができます。この IP アドレスを Nested VM の KMS 認証サーバーに指定してあげればよいのです。指定の方法は以下コマンドを実行します。(もちろん Nested VM 側で)。

```
//System32 まで移動
cd \Windows\System32
cscript slmgr.vbs /skms
cscript slmgr.vbs /ato
```

これで無事 KMS 認証が通ります。(何回か実行すると成功する場合もあります)
ここまでできれば、あとは DC に参加させたり、色々実施することが可能です。

#参考
Nested Hyper-V の VM からの外部への通信について
https://blogs.technet.microsoft.com/jpaztech/2018/04/16/connectivity_from_nested_vm/
KotlinのExtensionでNoSuchMethodError

KotlinのExtension機能で詰まったのでメモ。
OS側のクラスを拡張して作ったんですが「そんなメソッドねぇよ！」と怒られるの巻。

## 環境

Android, Kotlin 1.3.50

## 背景

`android.os.Parcel` にBooleanを書くメソッドがないので
`Parcel.readBoolean`, `Parcel.writeBoolean` として作った

```kotlin
fun Parcel.writeBoolean(value: Boolean) {
    if (value) {
        this.writeByte(1)
    } else {
        this.writeByte(0)
    }
}

fun Parcel.readBoolean(): Boolean {
    return this.readByte() == 1.toByte()
}
```

## 現象

|OS ver|device|result|
|:--|:--|:--|
|Android10|Pixel3|問題ない|
|Android9|Pixel3a|Parcelで落ちる|
|Android7|HUAWEI honor 8|Parcelで落ちる|
|Android6|Galaxy Grand Prime|Parcelで落ちる|

## エラー

Parcelの拡張関数としてアプリで定義しているのに、なぜかOS側のjarを読み込もうとして落ちている

```
Fatal Exception: java.lang.NoSuchMethodError: No virtual method writeBoolean(Z)V in class Landroid/os/Parcel; or its super classes (declaration of 'android.os.Parcel' appears in /system/framework/framework.jar!classes2.dex)
```


## 対応内容

`readCustomBoolean`, `writeCustomBoolean` にRenameした

## 反省

めちゃ一般的な名前はやめよう、、、

## 参考

Kotlinの拡張関数のガイドライン
https://dev.classmethod.jp/smartphone/kotlin-extensions-guideline/
neovim インストールから使えるようにする

# neovim インストールから使えるようにする

## はじめに
再インストールついでに駆け出しさん向けに手順を残しておくことにしました。

## 手順
1. neovim インストール
2. viコマンドをaliasで置き換え
3. 初期設定
    4. init.vim の編集
    5. dein.toml の編集
    6. dein_lazy.toml の編集

## neovim インストール
```bash
brew install neovim
```
## viコマンドをaliasで置き換え
```bash
echo alias vi=`which nvim` >> .bash_profile
```
vim も置き換えるなら要領は同じ
## 初期設定
### init.vim 
```bash
mkdir -p ~/.config/nvim
cd ~/.config/nvim
vi init.vim
```

```vim:~/.config/nvim/init.vim
set fenc=utf-8
set noswapfile
set autoread
set showcmd

set number
set cursorline
set cursorcolumn
set virtualedit=onemore
set smartindent
set showmatch
set statusline=2

set wildmode=list:longest

nnoremap j gj
nnoremap k gk

set list listchars=tab:\▸\-
set expandtab
set tabstop=2
set shiftwidth=2

set ignorecase
set smartcase
set incsearch
set wrapscan
set hlsearch
nmap <Esc><Esc> :nohlsearch<CR><Esc>

if &compatible
  set nocompatible
endif
" Add the dein installation directory into runtimepath
set runtimepath+=~/.cache/dein/repos/github.com/Shougo/dein.vim

if dein#load_state('~/.cache/dein')
  call dein#begin('~/.cache/dein')

  call dein#add('~/.cache/dein/repos/github.com/Shougo/dein.vim')
  call dein#add('Shougo/deoplete.nvim')
  if !has('nvim')
    call dein#add('roxma/nvim-yarp')
    call dein#add('roxma/vim-hug-neovim-rpc')
  endif

  " toml
  call dein#load_toml('~/.config/nvim/dein.toml', {'lazy':0})
  call dein#load_toml('~/.config/nvim/dein_lazy.toml', {'lazy':0})

  " auto install
  if dein#check_install()
    call dein#install()
  endif

  call dein#end()
  call dein#save_state()
endif

filetype plugin indent on
syntax enable

colorscheme molokai
```
* プラグインの管理は、tomlファイルに
* 起動時にプラグインを自動インストール

### dein.toml < 起動時に読み込みたいプラグインはこっち
```file:~/.config/nvim/dein.toml
[[plugins]]
repo = 'cespare/vim-toml'

[[plugins]]
repo = 'tomasr/molokai'
```
### dein_lazy.toml < 条件成立時に読み込みたいプラグインはこっち
```file:~/.config/nvim/dein_lazy.toml
[[plugins]]
repo = 'haya14busa/dein-command.vim'
on_cmd = 'Dein'
```

## 参考にさせていただいた記事
[NeoVim と dein.vim を使ってみる!](https://qiita.com/Ress/items/7e71e007cf8d41a07a1a)
[https://github.com/Shougo/dein.vim](https://github.com/Shougo/dein.vim)
[Neovim の設定を綺麗に整理してみた](https://qiita.com/tamago3keran/items/cdfd66b627b3686846d2)
[何も考えず~/.vimrcにこれを書くんだ！ 〜vim初心者によるvim初心者のためのvim入門〜](https://qiita.com/morikooooo/items/9fd41bcd8d1ce9170301)
electron-packagerをHTTPS Proxy環境下で

https-proxy-agentを明示的に与えればいいのだけど、オプションが面倒なのでメモしておく。

https-proxy-agentのインストール

```sh:npm
npm install https-proxy-agent --save-dev
```

```sh:yarn
yarn add --dev https-proxy-agent
```

設定は.jsに外部化する。npm scriptの場合は例えばこんな感じ。

```js:build.js
const packager = require('electron-packager');
const config = require('./package.json');
const HttpsProxyAgent = require('https-proxy-agent');

const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy;
if (httpsProxy) {
  const download = {
    downloadOptions: {
      agent: new HttpsProxyAgent(httpsProxy)
    }
  };
}

packager({
  ... 
  download: download,
  ...
}, function done (err, appPath) {
  if (err) {
    throw new Error(err);
  }
  console.log("Done: " + appPath);
});
```
#VsCode で複数行を1行にまとめるには標準機能の Join Lines コマンドがあるじゃないか ( Macならショートカットは Ctrl  + J ) ( もう SublimeText は必要ない )

範囲選択してコマンドパレットから Join Lines を選ぶ。ショートカットもここで確認可能。

![image](https://user-images.githubusercontent.com/13635059/67348339-8b67d400-f57f-11e9-86c2-51bb5d63a8fc.png)
![image](https://user-images.githubusercontent.com/13635059/67348340-8c006a80-f57f-11e9-9243-edbd2f2d115e.png)
![image](https://user-images.githubusercontent.com/13635059/67348341-8c990100-f57f-11e9-9009-8b35148de346.png)

今までSubliemeTextのようなマルチライン選択モードがVsCodeでやりづらくて辛かったけど、そもそも必要なかった！

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2622








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
AWSのDNS障害でDebianパッケージがインストールできなかった話

# やろうとしたこと
Dockerファイルをビルドしようとしていました。

```Dockerfile
FROM php:7.1.11-fpm

WORKDIR /var/local

RUN apt-get update && apt-get install -y \
    apt-transport-https \
    lsb-release \
    ca-certificates \
    wget
...
```

# エラー発生
```
Step 3/13 : RUN apt-get update && apt-get install -y     apt-transport-https     lsb-release     ca-certificates     wget
 ---> Running in 50a658d96e1f
Get:1 http://security.debian.org jessie/updates InRelease [44.9 kB]
Err http://deb.debian.org jessie InRelease
Err http://deb.debian.org jessie-updates InRelease
Err http://deb.debian.org jessie Release.gpg
  Could not resolve 'cdn-fastly.deb.debian.org'
Err http://deb.debian.org jessie-updates Release.gpg
  Could not resolve 'cdn-fastly.deb.debian.org'
Get:2 http://security.debian.org jessie/updates/main amd64 Packages [893 kB]
Fetched 938 kB in 4s (192 kB/s)
Reading package lists...
W: Failed to fetch http://deb.debian.org/debian/dists/jessie/InRelease
W: Failed to fetch http://deb.debian.org/debian/dists/jessie-updates/InRelease
W: Failed to fetch http://deb.debian.org/debian/dists/jessie/Release.gpg  Could not resolve 'cdn-fastly.deb.debian.org'
W: Failed to fetch http://deb.debian.org/debian/dists/jessie-updates/Release.gpg  Could not resolve 'cdn-fastly.deb.debian.org'
W: Some index files failed to download. They have been ignored, or old ones used instead.
Reading package lists...
Building dependency tree...
Reading state information...
Package lsb-release is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
E: Package 'lsb-release' has no installation candidate
The command '/bin/sh -c apt-get update && apt-get install -y     apt-transport-https     lsb-release     ca-certificates     wget' returned a non-zero code: 100
make: *** [build] Error 100
```

# 原因調査
deb.debian.orgのサーバーが死んだのかな？と思いきや、エラーメッセージに下記を発見。

```
Could not resolve 'deb.debian.org'
```

ネームサーバー変わったのかなと思っていたら、社内のエンジニアからSlackが飛んできました。
AWSでDNS周りの障害が起きていたみたいです。

https://www.theregister.co.uk/2019/10/22/aws_dns_ddos/

その障害によって、deb.debian.orgの名前解決ができず、パッケージのダウンロードができなくなっていたんですね。

# 障害復旧後
下記のステータスを、AWSで確認しました。

```
[RESOLVED] Intermittent DNS Resolution Errors
Between 10:30 AM and 6:30 PM PDT, we experienced intermittent errors with resolution of some AWS DNS names.
Beginning at 5:16 PM, a very small number of specific DNS names experienced a higher error rate. These issues have been resolved.
```
https://status.aws.amazon.com

その後再ビルドすると、無事にdebianパッケージもインストールされ、ビルドできました！

# 考察
おそらくdeb.debian.orgはRoute53あたりを使っているんでしょうか。
今後debianパッケージ取得の際に名前解決関係のエラーが出たら、AWSの障害を疑ってみることも一つの手ですね。
GCPのGCRとAWSのECR併用時に no basic auth credentials エラー

### 環境

* MacOS
* docker desktop community 2.1.0.1(37199) stable
* aws-cli/1.16.166 Python/2.7.15 Darwin/18.7.0 botocore/1.12.156

### 事象

以下のコマンドでECRにログインする。

```
$ $(aws ecr get-login --no-include-email --region ap-northeast-1) 
```

そして、docker buildしようとすると以下のようなエラーメッセージが出た。

```
no basic auth credentials
```

### 原因

結論から言うと、その前にGCPのGCRにログインしていたことが原因だった。

`~/.docker/config.json`の中身を見ると、以下のようにECRとGCRの設定が混在していた。

```json
{
	"auths": {
		"xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com": {},
		"asia.gcr.io": {},
		"eu.gcr.io": {},
		"gcr.io": {},
		"https://asia.gcr.io": {},
		"https://eu.gcr.io": {},
		"https://gcr.io": {},
		"https://marketplace.gcr.io": {},
		"https://staging-k8s.gcr.io": {},
		"https://us.gcr.io": {},
		"marketplace.gcr.io": {},
		"staging-k8s.gcr.io": {},
		"us.gcr.io": {}
	},
	"HttpHeaders": {
		"User-Agent": "Docker-Client/19.03.1 (darwin)"
	},
	"credsStore": "desktop",
	"credHelpers": {
		"asia.gcr.io": "gcloud",
		"eu.gcr.io": "gcloud",
		"gcr.io": "gcloud",
		"marketplace.gcr.io": "gcloud",
		"staging-k8s.gcr.io": "gcloud",
		"us.gcr.io": "gcloud"
	}
}
```

そこで `~/.docker/config.json` を削除した後、再度 `$(aws ecr get-login --no-include-email --region ap-northeast-1) `によりログインするとうまく行った。

うまくいったときの　`~/.docker/config.json`　は以下のようであった

```json
{
	"auths": {
		"xxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com": {}
	},
	"HttpHeaders": {
		"User-Agent": "Docker-Client/19.03.1 (darwin)"
	},
	"credsStore": "osxkeychain"
}
```


もっとスマートな回避方法はあると思いますが、分かり次第追記します。
一旦内容共有まで。
dockerを使って構築した、vue.jsのアプリがデプロイした際に動かなくなった話

dockerのマルチステージビルドを使って構築した、vue.jsのアプリがデプロイした際にローカル環境では発生しないエラーが実際のサーバー上でだけ発生する事象が発生しました。
通常通りのやり方だと気づけなかったポイントなので、共有しようと思います。


# マルチステージビルドとは?
[マルチステージビルド](https://docs.docker.com/develop/develop-images/multistage-build/)はdockerのimageを作成する際、`docker build`時にだけ立ち上がるコンテナでそこでできた生成物を実際のイメージに配置するみたいなことができます。
どこかの環境で(jenkins等)`node.js`をbuildしてその生成物を配置するみたいな必要がなくなりdockerだけで完結できるようになるので**Vue.js** の[公式](https://jp.vuejs.org/v2/cookbook/dockerize-vuejs-app.html)も推奨しているデプロイ方法になります。


# ハマったポイント
ローカルで`npm install` したときに生成される `node_modules` と サーバーのコンテナ上で生成される `node_modules` に差分があり、**ローカル環境でうまく実行できていたものがサーバーのコンテナ上ではうまく実行されず**エラーになってしまった。



# 原因
ローカル環境で `Vue.js`の開発をするときは、`npm run dev` 等で ローカルのサーバーを立てて開発することが多いと思います。
そのため、 `node_modules` や `dist` ファイルは`同じプロジェクト内にローカル環境だけは共存している形になると思います。
ローカルで以下のようなdockerfileをもとにvue.js のプロジェクトをbuildしたのですが、

``` :Dockerfile
COPY ./vue ./
RUN npm install
RUN npm run build
```



このときの `COPY` の挙動ではローカルに含まれる`node_modules` や `dist` ファイルも一緒にコンテナ内に配置されてしまいます。
そのため、`RUN npm install` が実行されても、新規で`node_modules`が生成されることがなく baseimageのversionとローカルのversionの差分等があるとうまく生成されないというような事象が発生してしまっていました。


# 対処方法
[.dockerignore](http://docs.docker.jp/engine/reference/builder.html#dockerignore-file)と呼ばれるdockerから無視させるファイルリストを追加する方法があるので、このファイルに以下のように無視ファイルの対象として追加する。

```
./vue/dist/
./vue/node_modules/
```
※ディレクトリ階層は使っているものに合わせてください。

追加することで、`docker build` 時は毎回新規で `npm install` が走るようになるので、サーバーだろうがローカル環境だろうが同じ状態にすることができ、問題を解決することができました。


# さいごに
今回のミスは、たまたまアプリを起動するときに出てくるエラーで動作の一部ができなくなるという感じのエラーではなく気づくことができましたが、ほんとに一部でしか使っていない動作でのエラーとかだとリリースしてからエラーが発生する等の問題になりかねないので注意が必要ですね。

あと、今回差分が発生してしまった一番の大きな原因は dockerの `baseimage`のversionが `node:6.4` とかだったのに対して、ローカル環境が `10`くらいになっていたことだったので、プロジェクトの生成からdockerのコンテナ内でやったほうが幸せになれると思いました。 Rubyとかは記事とかそこそこあるんですけどね…