OmniAICreator/Qiita-1.07M huggingface dataset:
VMware Fusionで動いているWindows7をWindow10にアップグレードしてみた

# はじめに

macbook airのVMware Fusionで動かしていたパッケージ版Windows7 Professional 32bit版を、Windows10にアップグレードしてみました。この作業は実施する時期によって対処方法などが異なってくるはずです。できるだけ新しい情報を参考にして進めることをお勧めします。

2020年1月時点では、VMの設定でOS種別をWindows7からWindows10に変更し、不要なアプリケーションをアンインストールすることでアップグレードツールの対応はできるはずです。

## 環境

* VMware Fusion 11.5.1
* macos 10.15 Catalina
* 【Virtual Machine】Windows7 Professional 32bit

今回は32bit版のWindows7から、同じく32bit版のWindows10に https://www.microsoft.com/ja-jp/software-download/windows10%E3%80%80 の「このツールを利用して、このPCをWindows10にアップグレードする」に書かれている方法に従ってアップグレードを行ないます。

# 遭遇した課題

Windows7は標準的な方法でインストールしたと思うのですが、Windows10にアップグレードする際には次のような課題がありました。

1. HDDがSCSI接続(LSI Logicドライバ)されており、Windows10ではドライバのサポートがないと警告がでる
2. VMware SVGA 3Dドライバが原因でアップデートできないと警告がでる
3. Microsoft Security Essentialsに互換性がないとの警告がでる

またこの作業の直前にmacos 10.15 Catalinaにアップグレードしましたが、、バージョン11以前の古いVMware Fusionでは、Windows7の画面が黒くなって正常に動作しない問題にも遭遇しました。ライセンスはあったのでVMware Fusion 11.5.1にアップグレードしてからWindows10アップグレードの作業を開始しています。

# References

* https://www.microsoft.com/ja-jp/software-download/windows10%E3%80%80
* https://kb.vmware.com/s/article/2126929?lang=ja


## SCSI接続されているHDD と VMware SVGA 3Dドライバ

VMwareのKnowledge Baseに回答がありますが、VMware Toolsをアンインストールし、ゲストOSの設定をWindows7からWindows10に変更してWindows7を起動します。この状態であればWindows10アップグレードは警告はでますが、アップグレードの作業は継続できます。

古い情報では、SCSIドライバからIDEドライバ(最新のVMWareであればSATA,NVMeドライバ)に変更するものもありましたが、SCSIデバイスしか接続していないWindows7の場合、SATAやNVMeデバイスにタイプを変更してしまうと、対応するドライバが存在せずに起動しない問題が発生します。（これはVistaからWindows7にアップデートした経緯が影響しているかもしれません。）もしSCSIからSATAにドライブ形式を変更したいのであれば、あらかじめ2台目のSATAドライブを作成し、接続してWindows7を起動する事でSATAドライバが組み込まれますので、起動しないエラーにはならないはずです。

## Microsoft security Essentials

Windows7固有のアプリケーションはいろいろあります。VMware上ではメーカー固有のツールがインストールされている事はないと思いますが、Windows10では互換性のないアプリケーションが様々あります。利用しているアプリケーションでも警告が出たソフトウェアはアンインストールして利用しましょう。

この他にも**Google日本語入力**を導入したままアップグレードすると、正常に動かず、アンインストールもできない状態になります。この場合でも、改めてGoogle日本語入力をWindows10でインストールすることで前述の不具合は解消され、正常な状態になるようです。

# Windows10アップグレード後の課題

Windows7の段階でVMware Toolsをアンインストールせずに、Windows10へアップグレードした場合、次のような現象が発生します。

* デバイスマネージャーに不明なデバイスが表示される
* ディスプレイドライバがVMware SVGA 3Dではなく、標準デバイスになっている


## 対策

1. デバイスマネージャーで不明なデバイスが表示されている場合は、そのデバイスをアンインストール
2. VMware Toolsをアンインストールし、再起動後、再度インストール

この作業の結果、無事に不明なデバイスはなくなり、ディスプレイデバイスもVMware SVGA 3Dになっています。

# ライセンスについて

Windows7からWindows10に無償アップグレードできる期間はWindows10が発売された後の1年間とされ、2016年7月29日に終了することがアナウンスされていました。しかし、『Windows Update経由では1年間だったが、Windowsメディア作成ツール経由ではまだ可能である』、『1年間の期間はマーケティング上の戦略で、技術的には今でもアップグレード可能で問題ない』、『Microsoftに問い合せたところ、2016年7月29日以降はWindows10の正規ライセンスが必要である旨の回答があった』、等の情報が流通しています。

Microsoftの公式見解は、https://support.microsoft.com/ja-jp/help/12435/windows-10-upgrade-faq に掲載されていて、Windows10のライセンスが必要だと明記されています。購入したPC付属のOSがWindows7でも、Windows10のライセンスが付属していてダウングレード権を行使したものがあるなど、ライセンスの構造は複雑です。よく調べてライセンス上の問題が発生しないように対応することが必要です。

以上
関数内で例外が発生した場合、呼び出し元へ伝わる1

```py:1
def test_exception(num):
    print(1)
    answer = 100 / num
    return answer
    print(2)
    
print('start')
try:
    test_exception(1)
    print(4)
except ZeroDivisionError as e:
    print(3)
    print(e)
finally:
    print('end')
```

```:1の実行結果
start
1
4
end
```
print('start')を
最初に実行。

次に、
tryブロックを実行する。
tryブロック1行目のtest_exception関数に引数1で入る。
なので、
print(1)を実行し、
answer = 100
となり100を返す。
retrunしているので、
その下のprint(2)は実行されない点に注意。
tryブロックのtest_exception関数が終わったので、
その続きでprint(4)を実行。

ZeroDivisionErrorは発生していないので、
exceptブロックは実行せず、とばす。

最後にfinallyブロックを実行する。


test_exception関数の引数を0にすると、

```py:2
def test_exception(num):
    print(1)
    answer = 100 / num
    return answer
    print(2)
    
print('start')
try:
    test_exception(0)
    print(4)
except ZeroDivisionError as e:
    print(3)
    print(e)
finally:
    print('end')
```

```:2の実行結果
start
1
3
division by zero
end
```
print('start')を
最初に実行。

次に、
tryブロックを実行する。
tryブロック1行目のtest_exception関数に引数0で入る。
なので、
print(1)を実行し、
answerが100を0で割る事になりエラー発生。
この場合も、
retrunしているので、
その下のprint(2)は実行されない点に注意。
tryブロックのtest_exception関数でエラーが発生した為、
その続きは実行されない。

ZeroDivisionErrorが発生しているので、
exceptブロックを実行する。

最後にfinallyブロックを実行する。
【Python】MotoでモックしたAWSリソースをpytestフィクスチャ化する

motoとは AWSサービスをモック化できる非常に便利なツール。

[spulec/moto - GitHub](https://github.com/spulec/moto)

これをpytestのフィクスチャと組み合わせれば`conftest.py`のsetUpで自動的にAWSサービスをモックできる。

参考 - [Issue with Moto and creating pytest fixture #620](https://github.com/spulec/moto/issues/620)

SQSの例

- SQSのモックキューを作成
- モックキューにメッセージ送信
- モックキューのメッセージを検証

```python
import boto3
import pytest
from moto import mock_sqs
import json


@pytest.fixture()
def mock_fixture():
    """キューを作成してメッセージを1件送信する"""
    mock = mock_sqs()
    mock.start()  # モックの開始
    client = boto3.client('sqs')
    # モックキューを作成
    response = client.create_queue(QueueName='example')
    queue_url = response['QueueUrl']
    # メッセージを送信
    client.send_message(QueueUrl=queue_url,
                        MessageBody=json.dumps({'msg': 'hello'}))
    yield client, queue_url  # ここでテストに遷移する
    mock.stop()  # モックの終了


def test_moto_sqs(mock_fixture):
    """フィクスチャのテスト"""
    client, queue_url = mock_fixture
    messages = client.receive_message(QueueUrl=queue_url)['Messages']
    assert messages[0]['Body'] == '{"msg": "hello"}'
```

ポイントは3点。

- `mock.start()`
- `mock.stop()`
- `yield`によるフィクスチャ生成がポイント。

`yield`ではなく`return`にしてしまうととティアダウン処理（上記の`mock.stop()`）は実行されない。
PostgreSQL テーブルなどの権限一覧SQL

Postgresに不慣れなため、書き溜め中。

情報スキーマを使用して、取得しています。
シーケンス等の情報も取れるようにしてます。

```sql
SELECT
  object_name,
  grantee,
  "privileges"
FROM (
  SELECT
    table_name as "object_name",
    grantee,
    string_agg(privilege_type, ', ') AS "privileges"
  FROM
    information_schema.role_table_grants
  GROUP BY
    object_name,
    grantee
UNION
  SELECT
    object_name,
    grantee,
    string_agg(privilege_type, ', ') AS "privileges"
  FROM
    information_schema.role_usage_grants
  GROUP BY
    object_name,
    grantee
  ) tmp
WHERE
  object_name in ('tableName')
ORDER BY
  object_name;
```


これでも良いかも。。。

```sql
SELECT r.oid, r.rolname, c.relname,
       has_table_privilege(r.oid, c.oid, 'SELECT') AS "SELECT",
       has_table_privilege(r.oid, c.oid, 'INSERT') AS "INSERT",
       has_table_privilege(r.oid, c.oid, 'UPDATE') AS "UPDATE",
       has_table_privilege(r.oid, c.oid, 'DELETE') AS "DELETE",
       case c.relkind when 'S' then has_sequence_privilege(r.oid, c.oid, 'USAGE') end AS "USAGE"
FROM pg_roles r, pg_class c
WHERE c.relkind in ('r', 'S')
      AND r.rolcanlogin = true
      AND relnamespace IN 
        (SELECT oid 
          FROM pg_namespace 
          WHERE nspname not like 'pg%')
and r.rolname in ('roleName')
and c.relname in ('objectName')
ORDER BY r.rolname, c.relname;
```
OPTPiX IconizerでPVRファイルをMacのFinderで表示できるので便利！

macOSで「PVR」形式のファイルを確認しようとすると
一部のファイルはサムネイルなどで表示することや
スペースキーでクイックルック表示することができませんでした。

それがWebTechnologyの以下のツールを入れるとMacのFinderで確認できるようになります。


<img width="971" alt="スクリーンショット 2020-01-16 11.58.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/511f056b-5d29-c775-a80d-5a0056d1155a.png">
packageも無料で提供されていますしインストールも簡単なので便利！

https://www.webtech.co.jp/iconizer/
【SeleniumBasic】ウェブページの要素の存在を判定するには？

この記事は、Excel+SeleniumBasic+GoogleChromeでスクライピングしている方に向けた記事です。

#結論：**.IsElementPresent**を用いればよい。
SeleniumのChromeDriverに用意されている「**.IsElementPresent**」メソッドは、
現在のウェブページ上に任意の要素が存在するか否かズバリをBoolean型で返す。

    if driver.IsElementPresent(myBy.ID("hogehoge")) Then

###経緯
IsElementPresentを私が知る以前は、ページの要素の存在のチェックはFindElementsBy云々で
取得したオブジェクトの要素数をチェックすればいいと思った。しかし、

    if driver.FindElementsById("任意のID").Count > 0 Then

と記述したら「NoSuchElement……以下略」が表示されVBAマクロが中断されてしまった。
つまり「そんな要素ないんだけど？」というエラーがSeleniumから返ってきてVBAの処理が止まってしまうらしい。

そこでエラーを無視せず正攻法でウェブページの要素の存在判定する方法を探すことにした。
VBAオブジェクトブラウザを探っていると**IsElementPresent**というそれっぽいメソッドを見つけた。
![IsElementPresent.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441999/4a4d10f2-3983-609a-78ca-6f13de81a5e4.png)


説明文に
>Inicates whether a WebElement is present using the given method.

=「指定されたメソッドを使用してWebElementが存在するかどうかを示します。(Google翻訳)」とあった



###.IsElementPresentの使い方

```IsElementPresentの基本.vba
    driver.IsElementPresent(by As By)
```

「たぶんこんな風だろう」と予想して、とりあえず試してみる。

```test.vba
    Sub test()
        Dim driver As New ChromeDriver
        Dim myBy As New By
    
        URL = "https://www.google.com/?hl=ja"
    
        driver.Get URL
        MsgBox driver.IsElementPresent(myBy.ID("hogehoge"))
    End Sub
```
上記コードを実行すると「NoSuchElement……以下略」エラーポップアップすることなく"False"の**メッセージを表示した**(=正常終了)。
つまり、要素の存在判定は下記コードで実装すれば良い。

    if driver.IsElementPresent(myBy.ID("hogehoge")) Then


ところで、引数の **By** クラスとは、Seleniumに搭載されたクラスである。
ByのインスタンスmyByを作ってmyByの中の「.id」メソッドを使って抽出用のタグやキーワードを指定する仕組みだ。

###Byクラスのメソッドたち
Byクラスは
>Provides a mechanism by which to find elements within a document.

=「ドキュメント内の要素を検索するメカニズムを提供します。(Google翻訳)」というオブジェクトである。

このByクラス、「.id」のほか
・.Xpath
・.Class
・.Css
・.Tag
・.linktext
・.partiiallinktext
・.Any
・.name
などがある。
![By.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441999/6692380f-8f9f-0b6f-ff49-a702896b2eb2.png)
今後これらを必要に応じて試してみたい。

「IsElementPresent」の記事は以上です。
Dockerコンテナに好きなフォントをインストールする方法

## 概要
dockerコンテナをビルドしただけでは当然フォントが全然入っていない
つまりcssでフォントを指定しようとしても、デフォルトで入っているものを使う or webフォントを使う 等しないと文字化けしたりしちゃう
webフォントで無駄にパフォーマンス落としたくないのでインストールしたい

## 1. フォントファイルを用意しよう
当然フォントファイルが必要なので、入れたいフォントのフォントファイル(`.ttf`なり`.otf`なりいっぱい種類あります)を用意する

## 2. コンテナ内から参照できる場所に置こう
1でホストPCにダウンロードしてきたファイル（あるいはディレクトリごとでも可）をコンテナ内に持っていく
dockerの環境はそれぞれだと思うのでここでは割愛
とにかくコンテナから見られるところに置くのです

[自分用メモ]
- docker-syncでsyncされるところに置けばOK
- とりあえず assets 配下とかでいいんじゃない

## 3. インストール
インストールというかただ配置するだけなんです。
インストールされているフォントはOSによって場所は異なりますが、
`~/.fonts` や `/usr/share/fonts` などに入っています。これは調べればすぐ出ます。
つまり用意したフォントファイルをここに置いてあげればそれで使えるようになります。

（Windowsにしか入っていないフォント（MSゴシックとか）も、Windowsからフォントファイルを抜いて持って来れば入る。多分ライセンスとか的にアウトかも。）

それをコンテナビルド時にやりたいので

```Dockerfile

# フォントをインストール
RUN mkdir -p /usr/share/fonts
COPY app/assets/fonts /usr/share/fonts
```

こんな感じで書いておけば入る

## 0. いいコマンド
- `fc-list`  
インストールされているフォント一覧を表示してくれる  
ファイルの在り処、cssで指定する名称も出してくれるので最高

## 感想
コンテナビルド時にフォントファイルのダウンロードもできるようにすればスマートですな
SQL*LoaderでXMLデータ列を追加していく

# はじめに
OracleDBにXMLデータを列として持つテーブルを作成したい、そしてその列をいちいち手で追加するのは大変だからSQL*Loaderなるものを使って楽をしたい。
しかし、[公式DocにあるSQL*LoaderのXML文書のロードのページ](https://docs.oracle.com/cd/E16338_01/appdev.112/b70200/xdb25loa.htm)が分かってる人向けすぎて何が何やら分からず大変困ってしまいました。
そのため次回混乱しないようにメモを残します。
# テーブル構成・ファイル等
## 作りたいテーブルの形
以下のように通し番号、フォルダ名、中身を持つテーブル（DATATABLE）を作ります。

| ID（通し番号）    | foldername |    data（XMLデータ）    |
|:-----------------|------------------:|:------------------:|
| 1             |   AAAAAAAA | \<Data>...\</Data>  |
| 2           |  BBBBBBBB | \<Data>...\</Data>  |
| ...     | ...| ...  |

SQL文は以とします。

```
CREATE TABLE DATATABLE
(
	ID number NOT NULL,
	foldername char(9) NOT NULL,
	data xmltype,
	PRIMARY KEY (ID)
);
```

##DATファイルの用意
公式ページのDocに従い、読み込みたいXMLファイルの一覧をDATファイルとして用意します。

```filelist.dat
AAAAAAAA/data.xml
BBBBBBBB/data.xml
...
```
このようにフォルダ以下のXMLファイルの名称は同じなので、テーブルではフォルダ名称だけを使いたいわけです。

# ctlファイル
上記を実現するctlファイルはこうです。

```load_data.ctl
LOAD DATA CHARACTERSET AL32UTF8 
INFILE 'filelist.dat'
BADFILE 'failedRecord.csv'
APPEND
INTO TABLE DATATABLE
(
 ID SEQUENCE( MAX ),
 foldername position(1:8) char,
 filename filler position(1:18),
 data lobfile(filename) terminated by eof
)
```
XMLデータに日本語が含まれるため文字コードをAL32UTF8に指定しています。
これにより「filelist.dat」の中身を一行ずつ読み込み、DATATABLEに入れていきます。
・ID SEQUENCE( MAX ),
　通し番号の指定です。ここはfilelist.datの中身には関係ありません。
・foldername position(1:8) char,
　foldername列に、今読んでいる行の1文字目～8文字目を使えという指定です。
・filename filler position(1:18),
　XMLデータ本体を読み込むためにはfoldernameだけだと駄目なので、一行丸々使いたい、だけど一行丸々のデータはテーブルには要らない…ということで「filler」として、このfilenameという変数はテーブルには入れないよという宣言をします。
　position(1:18)と改めて頭から指定してフルパスを取得します。
　一行丸々なのでそのままchar(18)としようとすると「/data.xml」部分だけになってしまいます。
・data lobfile(filename) terminated by eof
　data列にfilenameを読み込みます。

これを
```sqlldr userid=***/***@**.***.***.***:1521/*** control=load_data.ctl```
として実行すれば完了です。
もっとスマートなctl文の書き方もあるとは思いますが、一応これで想定通りです。

## 詰まっていた点
はじめ、公式Docのctlにある```xmltype(XMLDATA)```を信じて```xmltype(data)```と書いたら```SQL*Loader-588```というエラーが出るうえに、このエラーをググってもエラーコード詳細が出てきませんでした。
```SQL*Loader-00588```でググればいいということに中々思い至らず大変困っておりました。
このエラーを読むと「このテーブルはXML型ではない」とあるので、今回のように色々な型を使いたい場合は使えない指定のようでした。
Amazon Transcribeで日本語のカスタム語彙を作成してみた

Amazon Transcribeが日本語に対応しましたね！
これで日本語の音声をテキストに変換することができますが、一般的でない固有名詞などを認識させたい場合のためにカスタム語彙を試してみました。

##カスタム語彙とは
>カスタム語彙を作成して、入力ファイルの音声を処理する方法について Amazon Transcribe により詳細な情報を与えることができます。
>カスタム語彙は、オーディオ入力で Amazon Transcribe に認識させたい特別な語句のリストです。
>これらは通常、Amazon Transcribe が認識しないドメイン固有の語句や適切な名詞です。

https://docs.aws.amazon.com/ja_jp/transcribe/latest/dg/how-vocabulary.html

##カスタム語彙ファイルを作る
カスタム語彙の作成方法はリストとテーブルの2種類がありますが、今回はテーブルを使用して作成してみました。
カスタム語彙に登録する語句は「奈良萬」です。奈良萬は日本酒の銘柄で、「ならまん」と読みます。とっても美味しいので、ぜひ飲んでみてください！

以下の2行をファイルに記載し、custom-vocabulary.txtという名前で保存します。
※保存するときに文字コードをShift-JISにしたらCreate vocabularyが失敗したので、UTF-8で保存し直しました。

```
Phrase[TAB]IPA[TAB]SoundsLike[TAB]DisplayAs
ならまん[TAB][TAB][TAB]奈良萬
```

##カスタム語彙を登録する
マネジメントコンソールからカスタム語彙を登録します。
事前に上で作成したカスタム語彙のファイルを任意のS3バケットにアップロードしておきます。

Amazon Transcribe>Custom vocabularyを選択し、Create vocabularyをクリックします。
![Transcribe-001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/cf6da26c-9eed-a997-149d-72274a19b109.png)


Nameに任意の名前を入力し、Languageは「Japanese(Japan)」、Vocabulary input sourceは「S3 location」を選択し、Vocabulary file location on S3にはファイルのアップロード先を指定します。
その後、Create vocabularyをクリックします。
![Transcribe-002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/e0688d16-922f-f599-2f0e-5815fea9ec15.png)

ステータスがReadyになったらカスタム語彙登録成功です。
![Transcribe-003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/6bf0ab12-06a2-806f-d875-9ca91d597d84.png)


##Amazon Pollyでテスト用の音声ファイルを作る
Amazon Pollyでプレーンファイルに「私の好きな日本酒はならまんです。」と入力し、音声ファイルをダウンロードします。
「私の好きな日本酒は奈良萬です。」と入力したところ、「奈良萬」を「ならいちまん」と読み上げてしまったので、銘柄名はひらがなで入力しました。
![Transcribe-004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/1766aa07-88d5-a509-51bd-4bceb8684a0d.png)

音声ファイルはカスタム語彙のファイルと同じく任意のS3バケットにアップロードしておきます。

##カスタム語彙を使って音声認識させる
Amazon Pollyで作成した音声を認識させます。
ちなみにカスタム語彙を指定しない場合、認識結果は「私 の 好き な 日本 酒 は なら ま ん です」になりました。
![Transcribe-005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/b1047246-aa0a-4b05-8a82-cb05ff534969.png)

Amazon Transcribe>Transcription jobsを選択し、Create jobsをクリックします。
![Transcribe-006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/2f923362-ea69-c3a6-1014-f43843d1738d.png)

Nameに任意の名前を入力し、Languageは「Japanese(Japan)」を選択し、Input dataに音声ファイルのアップロード先を指定してNextをクリックします。
![Transcribe-007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/bef76bf3-bc8a-a506-032c-f5aee811d092.png)

CustomizationのCustom vocabularyをクリックし、先程登録したカスタム語彙を選択してCreateをクリックします。
![Transcribe-008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/2c652c28-b4ee-47fc-9403-361f9fa17193.png)

しばらくするとStatusがCompleteになりました。
![Transcribe-009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/e9038b50-1dfd-79cc-f6ed-554499d186de.png)

認識結果を見てみると…
![Transcribe-010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398131/b3c0a820-4edc-cbfc-399b-e680f880c31c.png)

期待通り認識結果が「私 の 好き な 日本 酒 は 奈良萬 です」になっていました！

以上、どなたかのお役に立てれば幸いです。
GASで定例ミーティングの議事録を自動生成する


フォーマットの決まった定例mtgの議事録を毎回作るのが煩わしかったのでGoogle Apps Script（GAS）で簡易に自動化しました。
ソースコードコピペで動作しますので、同じような環境、悩みを持っている方の参考になれば幸いです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221497/ae3d9d02-e607-bf0d-819a-4ab24d1591f6.png" width="300px">

https://developers.google.com/apps-script

## 前提条件

* GSuiteを導入していること
* 頻度の決まったMTGがあること（曜日固定など）
* そのMTGのフォーマットが決まっていること

## 動作イメージ

こんな感じで動きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221497/7b59412d-4acb-c034-472b-0a8f33edb391.png)

## ソースコード

xxxxxxの部分を適切に変えるだけで動作します。

* sourceId：Google DriveのファイルID。スプレッドシートの場合、`https://docs.google.com/spreadsheets/d/この部分`
* webhookURL：SlackのwebhookURL

※ Slackに通知しない場合は `//slackポスト用の...`以下を削除します。
※ 曜日固定のmtgを想定しています。GASのトリガー設定で曜日を選択すると、mtgの翌日の曜日に議事録が自動生成されます。

```javascript

//　来週分の議事録を生成（定例mtgが毎週同じ曜日にあることを想定している。）定例mtgの曜日が変わった場合は、マイトリガーから設定をする。
function makeMinute() {

  sourceId = "xxxxxx"; // 議事録テンプレートのID（Google Drive）

  // 来週のmtgの日付を取得、議事録のタイトルを生成
  var today = new Date();
  today.setDate(today.getDate() + 6); // 来週の日付に設定
  var year = today.getYear();
  var month = ("0" + (today.getMonth() + 1)).slice(-2);
  var day = ("0" + today.getDate()).slice(-2);
  targetName = "定例mtg_" + year + month + day;

  // 議事録マスタをコピーし、上で生成したタイトルに変更、その他共有設定をする。
  targetFile = DriveApp.getFileById(sourceId).makeCopy(targetName);
  targetFile.setSharing(DriveApp.Access.DOMAIN_WITH_LINK, DriveApp.Permission.EDIT)
  targetURL = targetFile.getUrl().replace('?usp=drivesdk', '');

  // slackポスト用のメッセージ、オプションの設定
  var body =
      {
        "attachments" : [
          {
            "fallback": "定例MTGの議事録を作ったよ！",
            "pretext": "定例MTGの議事録を作ったよ！来週までに記入よろしくね！ \n" + targetURL,
          },
        ]
      };
  var webhookURL = "xxxxxx";
  var options = {
        'method' : 'POST',
        'contentType' : 'application/json',
        'payload' : JSON.stringify(body),
  };

  // slackへのポスト
  UrlFetchApp.fetch(webhookURL, options);
}
```

## おわりに

こんな感じに動きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221497/d199fdb6-b1d2-056e-ed5e-2a8d9ef15945.png)
AWS CLIで複数アカウント(認証情報)を簡単に切り替える方法

# はじめに
以下の状況を踏まえ、備忘録を兼ねてアカウント切替え方法をまとめます。

- 異なるアカウントで操作する機会が増えた
- **aws configure**で認証情報を毎回入力して切替えるのが煩わしい

#Profileを作成する
```ruby:コマンド
aws configure --profile [profile名]
```
↓↓↓ 作成サンプル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440367/a43f576f-95bb-7048-e078-d373a22589ef.png)

↓↓↓ 作成先は以下の2ファイル
・C:\Users\[ユーザー名]\.aws\credentials

```ruby:credentials
[test]
aws_access_key_id = test
aws_secret_access_key = test
```

・C:\Users\[ユーザー名]\.aws\config

```ruby:config
[profile test]
output = test
region = test
```
#Profileを切り替える


```ruby:AWS_DEFAULT_PROFILE
set AWS_DEFAULT_PROFILE=[Proflie名]
```
↓↓↓ 実行サンプル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440367/499806f7-a875-06a9-b4c1-756106621dd8.png)

#コマンド補足
```ruby:コマンド
`認証状況`
aws configure list
```
kubectlから利用できるkustomizeのバージョン

https://github.com/kubernetes-sigs/kustomize/blob/master/docs/fields.md に記載されているkustomizeの仕様を読んでいたのですが、どうもおかしいな、、と思い調査しました。

# kubectlに対応するkustomizeのバージョン

https://github.com/kubernetes-sigs/kustomize#kubectl-integration に記載がありました。

> | kubectl version | kustomize version |
|---------|--------|
| v1.16.0 | v2.0.3 |
| v1.15.x | v2.0.3 |
| v1.14.x | v2.0.3 |

kubernetes v1.16.xを使っている場合はkustomizeはv2.0.3のようです。
kustomizeの最新版がv3.3.1とかなので結構古い・・

v1.17.xではどのバージョンなのか書かれていないが、ソースコードを見てみると

https://github.com/kubernetes/kubectl/blob/kubernetes-1.17.0/go.mod#L48

> sigs.k8s.io/kustomize v2.0.3+incompatible

まだv2.0.3のようです。

# kustomize v2.0.3の仕様
2つの方法がありました

## kustoimze公式ドキュメントの古いバージョン

- https://github.com/kubernetes-sigs/kustomize/tree/v2.0.3/docs から古いドキュメントを参照できます
  - サンプルkustomization.yamlにコメントが丁寧に書いてあるので参考になりますhttps://github.com/kubernetes-sigs/kustomize/blob/v2.0.3/docs/kustomization.yaml

## kubectlのドキュメント(こちらの方が読みやすい！）

- kubectlのドキュメントのkustomization.yamlのページ
  - https://kubectl.docs.kubernetes.io/pages/reference/kustomize.html


これらに気づかず下記v3.3.1の仕様を読んでいて少しハマりました。

# kustomize v3.3.1の仕様

先に調べてしまいましたが、この仕様はv1.17.0までのどのkubectlでも実行できません。
利用するにはkustomize v3.3.1をインストールする必要があります。

以降のドキュメントは https://github.com/kubernetes-sigs/kustomize/blob/master/docs/fields.md を読みながらのメモです。

## Resources

- resources
  - yamlファイルまたはkustomizaton.yamlを含むディレクトリ
  - `bases`の方はv2.1.0から廃止
- CRDS
  - CRDに含まれるリソース名なども適切に変換するような仕組みがあるらしい

## Generators

- configMapGenerator
  - ファイルからConfigMapを作る
  - オブジェクトの名前に適切なハッシュを混ぜてくれる
- secretGenerator
  - ファイルからSecretを作る
  - オブジェクトの名前に適切なハッシュを混ぜてくれる
- genaratorOptions
  - Generator周りの設定
    - ラベル、アノテーション、ハッシュを名前につけるか
- generators
  - pluginの設定

## Transformers

- commonLabels
  - 全てのリソースにつける共通のラベル
- commonAnnotations
  - 全てのリソースにつける共通のアノテーション
- images
  - コンテナイメージをさしかえる
- inventory
  - kustomizeの実行結果を入れておくためのオブジェクトを指定する。
  - 通常ConfigMapを使うようだ
  - これを設定しておくとmanifestが変更された際に適切にpruneされるようになる予定
    - 現状cli-experimentalでその実装が行われている
  - last-applied-configrationと近い動きをしている
- namespace
  - 全てのリソースにつけるNamespace
- namePrefix
  - 全てのリソースにつけるPrefix
- nameSuffix
  - 全てのリソースにつけるSuffix
- replicas
  - 特定の名前のリソースのreplicaの上書き
- patches
  - 特定のリソースに対するpatch
- patchesStrategicMerge
  - 特定のリソースに対するpatch
- pathesJson6902
  - 特定のリソースに対するpatch
- transformers
  - pluginの設定

## Meta

- vars
  - マニフェストから参照できる変数を定義できる。定義は別のオブジェクトの特定のフィールドの参照という形で行う
  - varは 変数名、オブジェクトへの参照、フィールドへの参照のタプルである
  - varで参照できるのはstring型のみ。intやbool、arrayはできない
  - 変数の参照は`'$(FOO)'`という形で行うが、これはkustomize内部で定義された特定のフィールドでのみ利用可能
- apiVersion
  - kustomization.yamlのバージョン
  - 今は`kustomize.config.k8s.io/v1beta1`
- kind
  - `Kustomization`で固定


# まとめ

(kubernetes v1.17.x現在)kubectlから利用できるkustomizeは古いので気をつけましょう。
2020/1/15 から Maven の Central Repository が HTTPS になってハマったよ！

Central 501 HTTPS Required
https://support.sonatype.com/hc/en-us/articles/360041287334-Central-501-HTTPS-Required

The Central Repository is Moving to HTTPS
https://blog.sonatype.com/central-repository-moving-to-https

Central Repository に以下の設定をしている方は https://~ に変更必要みたいです。

http://repo1.maven.org/maven2/ → https://repo1.maven.org/maven2/
http://repo.maven.apache.org/maven2/ → https://repo.maven.apache.org/maven2/

僕のほうはちょっとプロキシとかなのかHTTPSの設定がうまくいかないので、いったん

http://insecure.repo1.maven.org/maven2/

こっちに変更したらうまくいきました。

英語のサイトちゃんと読めて、ちゃんとした記事をかける拡散力のある人あとはよろしくお願いいたします。
【備忘録】ハード・ソフト・ミドル・ファームウェア

#はじめに#
いろんなウェアがあるのでメモです。

#ハードウェア#
>ハードウェアとは、システムの構成要素のうち、回路や装置、機器、設備、施設など、物理的な実体を伴うもの。「HW」「H/W」などの略号で示されることもある。

>コンピュータの場合、処理装置や記憶装置、入出力装置、電子基板、ケーブル類、筐体などの部品や部材、およびその総体として物理的実体としてのコンピュータのことをハードウェアという。
>http://e-words.jp/w/%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A7%E3%82%A2.html

つまり物理的な実体があるものがハードウェアってことですね。

#ソフトウェア#
>ソフトウェアとは、コンピュータを動作させる命令や処理手順のまとまり（コンピュータプログラム）。広義には、その処理の対象となるデータなどを含む。

>それ自体は形を持たないプログラムやプログラムの扱うデータなどをソフトウェアという。
>http://e-words.jp/w/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2.html

つまりプログラムやデータってことですね。
ちなみに

>ソフトウェアはその役割により、ハードウェアの制御や利用者への基本的な操作手段の提供などを行なうオペレーティングシステム（OS：Operating System、基本ソフトとも呼ばれる）と、特定の機能や目的のために作られたアプリケーションソフト（application software、応用ソフトとも）に大別される。
>http://e-words.jp/w/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2.html

ソフトウェアにはOSとアプリがあるってことですね。
アプリってのはwordとかfirefoxみたいなやつのことです。

#ミドルウェア#
>ミドルウェアとは、ソフトウェアの種類の一つで、オペレーティングシステム（OS）とアプリケーションソフトの中間に位置し、様々なソフトウェアから共通して利用される機能を提供するもの。OSが提供する機能よりも分野や用途が限定された、具体的・個別的な機能を提供する場合が多い。

>どのようなソフトウェアがミドルウェアとして提供されるかは分野によって大きく異なり、ネットワークサーバなどではデータベース管理システム（DBMS）や、TPモニタ（トランザクションモニタ）、アプリケーションサーバなどがミドルウェアとなることが多いが、組み込みシステムではOSの機能が大きく限定されているため、ファイルシステムやGUI（Graphical User Interface）などパソコンならOSが提供するような機能がミドルウェアとなることもある。
>http://e-words.jp/w/%E3%83%9F%E3%83%89%E3%83%AB%E3%82%A6%E3%82%A7%E3%82%A2.html

つまりはOSとアプリの間にいるソフトウェアで, OSで提供されてないけどよく使う機能を提供するえらい子ってことですね。

#ファームウェア#
>ファームウェアとは、コンピュータなどに内蔵されるソフトウェアの一種で、本体内部の回路や装置などの基本的な制御を司る機能を持ったもの。機器内部に固定的に組み込まれ、あまり内容の変更が行われないことから、ハードウェアとソフトウェアの中間的な存在としてファームウェア（firm：堅い、固定の）と呼ばれている。
>http://e-words.jp/w/%E3%83%95%E3%82%A1%E3%83%BC%E3%83%A0%E3%82%A6%E3%82%A7%E3%82%A2.html

つまりはハードウェアを制御するソフトウェアってことですかね。

#何が違うのか#
ハード・ソフト・ファームは何が違うのか見てみましょう。

##例##
まずは具体例で見てみましょう。

|  ハード      |       ソフト |    ファーム    |
|:-----------------|------------------|:------------------|
| コンピュータ本体<br>入力装置  |word<br>firefox  |     BISO<br>Arduinoにかくプログラム   |

##つまり何が違うのか##
上記での説明や具体例から結局何が違うのかというと

|ウェア|説明|
|:----|:--|
|ハード   |物理的なモノ, 装置そのもの|
|ファーム|ハードを直接制御するプログラム|
|ソフト   |ハードを直接制御しないプログラム, 普段接する機会の多いプログラム|

>参考
>http://tooljp.com/windows/chigai/html/IT/hardware-software-farmware-chigai.html


#参考になるサイト#
https://www.yamanjo.net/knowledge/program/program_04.html
#Ruby Error class message / raise second args or Error class initialized message

```rb
raise StandardError.new('ERROR in class')
# StandardError: ERROR in class

raise StandardError, 'ERROR in raise arg'
# StandardError: ERROR in raise arg

raise StandardError.new('ERROR in class'), 'ERROR in raise arg'
# StandardError: ERROR in raise arg

```

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
為什麼 { get } 可以 assign?!

這篇是關於 `{ get }` 和 `{ get set }` 的基礎筆記。

## 問題點

最近發現為什麼被定義成 `{ get }` 的屬性為什麼還可以被 assign 值覺得不可思議，因此再次幫自己舉例釐清到底為什麼。

而這個原因（可以被 assign）雖然看起來理所當然，但是在實踐 pop 的時候可能因為覺得太過理所當然會不小心忽略，或是在指定成 protocol 型別之前就先被拿來當成繞過 protocol 限制的方法，姑且不論好壞，就先決定記下來。

## 例

像是以這樣的定義

``` swift
protocol A: class {
    var a: String! { get }
}

class AClass: A {
    var a: String!
    init() {}
}
```

發現可以被 assign 值的實作是這樣：

``` swift
let a1 = AClass()
a1.a = "some text"
```

這樣 Xcode 的編輯器不會抱怨， runtime 也一樣照樣過。
原因就是在 a1 雖然用了有 `A` 成分的 `AClass` ，但是對編譯器來說他還是 `AClass` ，protocol `A` 的優先度反而不是更高的。

不過如果這樣寫，明確的指定我的變數就是 protocol `A`

``` swift
let a2: A = AClass()
a2.a = "some text"
```

Xcode 就會如期待的抱怨了：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41979/17c4e884-e505-8b78-19b0-8be50e0cbc24.png)

## 環境

Xcode 11.3.1, Playground

## 參考

- https://docs.swift.org/swift-book/LanguageGuide/Protocols.html 的 `Property Requirements`
【未解決】Samsung端末だとFlutterの文字入力がバグる案件

#どういうバグなんですか？
入力してない文字がガンガン入ってくる
![72007589-4020a180-320f-11ea-87fc-4393229842e8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154354/9b4b5f18-9add-7228-49ba-a283b129c676.gif)
[ソース元](https://github.com/flutter/flutter/issues/31512#issuecomment-572211416)

#Q.一般開発者に出来る対応は？ A.ほぼ無い
マジで勘弁してください（白目

##バグの発生原因
Samsung端末の **予測変換** 機能に問題があるとのこと。
OS周辺のブラックボックスに起因しているのがキツい

##英数字限定のTextFieldにだけ使える対応
予測変換がバグの温床なんだから、予測変換使わなきゃいいじゃん？
ということで、そういう設定の仕方があるみたいです。

1.まず **device_info** ライブラリをインストールします
https://pub.dev/packages/device_info

2.こういう感じでサムスン端末判定を行う

```dart
bool samsungKeyboard = false;
if (Platform.isAndroid) {
  var info = await DeviceInfoPlugin().androidInfo;
  samsungKeyboard =
    (info?.manufacturer?.toLowerCase()?.contains("samsung") ?? false);
} else {
  samsungKeyboard = false;
}
```

3.サムスン端末判定で keyboardType の設定を変える

```dart
TextField(
  keyboardType: samsungKeyboard ?
    TextInputType.visiblePassword : 
    TextInputType.emailAddress,
  autoFocus: false,
)
```

###この対応が根本的な改善にならない理由
1. 全部の TextField にこれ対応するの単純にキツイし漏れやすい
2. 予測変換の禁止強制、ユーザビリティ最悪ですよねこれ
3. 複数行入力に対応しようとすると

```dart
TextField(
  keyboardType: TextInputType.multiline,
  maxLines: null,
)
```
を設定する必要がある([引用元](https://qiita.com/superman9387/items/15757a2c40b7776138b1))ので、keyboardTypeが重複して駄目

という感じで、現実的にどうにもならないです。

#Flutter公式側の動向
~~https://github.com/flutter/flutter/issues/42273
対応自体は行ってくれているみたいですが、2020/01/16現在、
対応マイルストーンは2020年の2月および5月とそれなりに長めの設定。
微妙に遠いなぁ……（遠い目~~

[2020/4/2にmasterブランチにマージされた](https://github.com/flutter/engine/pull/17426)ようです。
で、同日にhotfix9がリリースされてますが……
マージが午前10時で、[通知ツイートが午前8時](https://twitter.com/FlutterReleases/status/1245484874720522240)なので、安定版には多分まだ修正入ってない気がします。
AWS EC2インスタンスの複製をしてみた。その4（備忘録）

前回の続きです。https://qiita.com/Bikeiken-IT/items/d8b1f731334c4f179447

![step20-httpd-start.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550376/d4e0ddde-8f34-d339-d616-42b82b6771bb.png)
インストールしたApacheサーバーを起動します。
"service httpd start"と入力してください。
Apacheサーバーの起動を確認したら、ホストのEC2インスタンスのパブリックIPをブラウザに入力します。
![step21-test-page.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550376/76097034-cf4f-8616-2f11-267a821d0b68.png)
上記の画面がブラウザに表示されることで、作成したEC2インスタンスのApacheサーバーの動作を確認することができます。
![step22-cd-nano.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550376/37d20895-e52f-c787-cc31-8d3a7ee1ad5e.png)
先ほどのTeraTermの画面に戻ります。
"cd /var/www/html"と入力して、htmlフォルダに移動してください。
htmlフォルダに移動したらHTMLファイルを作成します。
"nano index.html"と入力します。これでindex.htmlファイルが作成されます。
![step23-gnu-open.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550376/43aceabe-4df1-45dd-7900-4d1ed0851cca.png)
"nano index.html"と入力すると、index.htmlファイルの編集画面が表示されます。
![step24-code.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550376/612eea5a-dfae-b26c-cf6e-1c247387dcda.png)
index.htmlファイルの中身を書きました。
![step25-save.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550376/bca5aa10-2ac6-600f-e413-89f25bf5402c.png)
CtrlキーとXを同時に押すと、保存を選択することができます。
保存後にEnterキーを押すと、元の画面に戻ります。
![step26-restart.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550376/610934be-ef8e-f90e-aef4-d35f7621441d.png)
そして、改めてApacheサーバーをリスタートします。
"service httpd restart"と入力してください。
もう一度、ブラウザに作成したEC２インスタンスのパブリックIPアドレスを入力してください。
![step27-browser.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550376/bb26a21e-61e7-b3ea-4fe0-30fe0334a7e7.png)
先ほど編集したindex.htmlファイルの内容が反映されていることが確認できました。

次回以降は、このEC2インスタンスをAMIとSnapshotを使って複製したいと思います。

その５に続きます。https://qiita.com/Bikeiken-IT/items/6c885d40fd92b1a6dee9
rails g migrate で外部キーを追加する


ポートフォリオ作成中に後から外部キーを追加しよとしたら、コマンドに詰まったので忘れないために記事にしておく。

articleテーブルにuser_idを追加する

```
rails g migration AddUserRefToArticles user:references
```

成功したら

```
rake db:migrate
```
を実行する。
setTimeoutを使って指定時間後に処理を行う際はスリープに注意

setTimeoutで数秒ではなく数十分など長めに設定した場合に、上手く挙動しなかったことがありました。

##setTimeout
指定時間後にJavaScript関数を実行するsetTimeout。
ページを開いたまま20分経過したら自動で指定ページに遷移させようとしました。

```javascript
setTimeout(function(){
   window.location.href = 'https://xxx.ne.jp/';
}, 20 * 60 * 1000);
```

普通思い浮かぶであろうこのコードでなんの問題もなく処理が動きそうです。（と思ってました...）

ただ、この**setTimeout**はAndroidやiOSといったスマホ・タブレット端末のWebブラウザでは注意する必要があります。
スマホ・タブレット端末では、アプリがバックグランドに入る**スリープの概念**があり、この状態では**setTimeout**の呼び出し（JavaScriptの実行そのもの）も保留されてしまいます。
スリープ中に止まったタイマーが完了するのは、1分後かもしれないし10分後、1時間後かもしれません...。

##経過時間をチェックしてスリープ対策
スマホユーザーが多いサービスがゆえにスリープ対策をどうしてもしなければならなかったので、**setInterval**で「ページを開いてから20分経過したか」を定期的にチェックし続ける処理を入れることにしました。

- setTimeout関数 ・・・ 指定した時間経過後に処理を実行する
- setInterval関数 ・・・ 指定した時間ごとに処理を実行する
- clearTimeout関数 ・・・ setTimeoutで設定したタイマーを取り消す
- clearInterval関数 ・・・ setIntervalで設定したタイマーを取り消す

※時間の指定単位は「ミリ秒」

```javascript
// 20分後指定URLにリダイレクト
const setTime = Date.now() + (20 * 60 * 1000);

const timer_Id = setInterval(() => {
if (Date.now() > setTime) {
  clearInterval(timer_Id);
  window.location.href = 'https://xxx.ne.jp/';
}
}, 500);
```
この処理だと、途中でスリープしていた場合でも

- ページを開いてから20分後に処理が走る
- スリープ中に20分を過ぎていたら復帰した瞬間に実行される

今回は1秒だと微妙だったので0.5秒（500ミリ秒）でIntervalを指定しました。

##最後に
「Webブラウザがバックグラウンドに回ってスリープ状態になり処理が止まる」という事象はPCでは起こりにくいので、AndroidやiOSで挙動が変わることがあるという点は注意すべきところですね。
WindowsにsqliteでFAQサイト（phpMyFaq）を構築する

# インストール環境
今回は以下の環境にphpMyFaqをインストールする手順を紹介します。

- OS：Windows10
- IIS:10.0
- PHP:7.3
- phpMyFaq:2.9
- SQLite:3.30


#事前作業
以下の作業は完了しているものとして説明を割愛します。
調べればいくらでも手順が見つかるので…


- IISのインストール、およびCGIの有効化
- PHPのインストール、php.iniの作成
- SQLiteのインストール、パスの追加

# 手順
## php.iniの設定変更
phpMyFaqを使用するために設定を変更します。
拡張モジュールの追加と、phpMyFaqインストール時に実行するセットアップスクリプトがタイムアウトしないようにするための設定を変更します。
処理がタイムアウトしてしまうとインストールが中途半端な状態で終わってしまうため、作業をやり直す羽目になります…注意してください！


■既存設定の変更（10時間に変更）
max_execution_time = 36000

■コメントアウトしている箇所を有効化
extension_dir = "ext"
extension=curl
extension=fileinfo
extension=gd2
extension=pdo_sqlite
extension=sqlite3

## phpMyFaqをダウンロードして、IISの公開ディレクトリに展開する
[公式サイト](https://www.phpmyfaq.de/download)からzipファイルをダウンロードします。
zipファイルは解凍してリネームします。以下の手順では"faq"というフォルダ名に変更したことにします。

IISの公開ファイルを保存しているフォルダ（デフォルトではC:\inetpub\wwwroot）にリネームしたフォルダを移動します。
phpMyFaqのセットアップスクリプトがフォルダ内のファイルを変更するので、アクセス許可の設定は緩めにしておくとトラブルがなくて済むと思います。

## faqフォルダ内に空のフォルダを追加する
faqフォルダ配下に下記のフォルダを作成します。

- images
- attachments
- data

## IISマネージャからphpのモジュールマップの追加
IISマネージャを起動します。
すでにIISでPHPが実行可能な状態であれば、この項目はスキップしてください。
左ペインにあるツリーから、サーバ名 > サイト > faqの項目をクリックして、中央ペインにある「ハンドラーマッピング」をダブルクリックします。
右ペインにある「モジュールマップの追加」をクリックして、以下のように設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223632/e24603ac-2a5d-a38a-0cc4-42198880e1cc.png)
実行可能ファイルのパスはphpをインストールしたフォルダを指定してください。
名前は適当でOKです。

## IISマネージャからFastCGIの設定を変更
左ペインのサーバ名の項目をクリックして、中央ペインの「FastCGIの設定」をダブルクリックします。
先程追加したphpの項目が追加されているのでダブルクリックして、"アクティビティタイムアウト"と"要求タイムアウト"の設定を36000（10時間に変更）にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223632/0f5ff047-bfef-61ea-f76c-95ddf7ee8408.png)


## SQLiteのデータベース作成
コマンドプロンプトを起動して、データベースを作成するフォルダに移動します。
sqliteコマンドを実行して、データベースファイルを作成します。

管理が面倒だったので、phpMyFaqのアプリケーション配下に"phpmyfaq.sqlite3"というファイル名で作成しています。
ファイルの置き場所としてはセキュリティ上あまり良くないと思います…
インターネットに公開するサイトにする場合は注意してください。

```
cd C:\inetpub\wwwroot\faq
sqlite3 phpmyfaq.sqlite3
```

ここで作成したデータベースファイルはphpMyFaqのセットアップ時に入力するので、フルパス(C:\inetpub\wwwroot\faq\phpmyfaq.sqlite3)をメモしておいてください。

## 初回セットアップスクリプトの実行
phpMyFaqのトップページ(http\://localhost/faq)にアクセスして、セットアップスクリプトを実行します。
SQLite database fileのデータベースファイルは先程作成したものを指定します。
phpMyFAQの設定は適宜入力してください。
また、LDAPのモジュールがphpで読み込まれているとLDAPの設定項目が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223632/b6f2ddfa-b39d-c6a6-face-1645f3c5f235.png)

ここまでできたらあとはインストールボタンを押すだけです。お疲れ様でした！
Dataikuでプラグインを利用する

# はじめに

Dataiku Data Science Studio（DSS）とは、[Dataiku社](https://www.dataiku.com/)が提供するデータ分析ツールです。
[Dataiku DSSをVirtual Boxを使って利用する方法](https://qiita.com/goya1021/items/0b244ffec4a971b0f736)では、Dataiku DSSのインストール方法を紹介しました。
ここでは、Dataiku社から提供されているプラグインをインストールする方法を紹介します。

# Dataikuプラグインとは

Dataikuプラグインを用いると、Dataiku DSSに新たな機能をアドオンすることができます。
Dataiku社の[Pluginsサイト](https://www.dataiku.com/product/plugins/)でさまざまな機能のプラグインが提供されています。
また、自分で独自の機能を持つプラグインを作ることもできます。例えば、他の人と共有したい機能があれば、プラグインを作って提供することができます。
プラグインの作り方は[こちら](https://doc.dataiku.com/dss/latest/plugins/index.html)を参照してください。

# Dataikeプラグインを利用する

Dataikuプラグインを利用するには、プラグインをインストールする必要があります。ここでは、試しに、[Reverse Geocoding/Admin maps](https://www.dataiku.com/product/plugins/geoadmin/)をインストールします。
[Reverse Geocoding/Admin maps](https://www.dataiku.com/product/plugins/geoadmin/)は、逆ジオコーディングの機能を提供します。例えば、IPアドレスから都市の情報を導出したりすることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417992/743ef02a-b56c-a0b1-5e31-9e4da2a255e5.png)

## インストール手順

[Reverse Geocoding/Admin maps](https://www.dataiku.com/product/plugins/geoadmin/)をインストールするには次の手順で行います。

1. Dataiku DSSにログイン後、画面右上にあるAppsアイコン（キューブの形）をクリックして、［Plugins］メニューをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417992/a9ab2627-9ab4-6bc6-95e5-682fc1656d42.png)
2. 画面左上にある検索で「Reverse Geocoding」を入力すると、画面右側に「Reverse geocoding」のプラグインが表示されます。この「Reverse geocoding」の［INSTALL］リンクをクリックします。「Install Reverse geocoding」のメッセージが表示されるので［CONFIRM INSTALL］ボタンをクリックします。インストールが開始されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417992/e2df2a83-c9ea-5514-eee4-5bb7d2c5004f.png)
3. インストールが完了すると、次のメッセージが表示されます。［RESTART DSS］ボタンをクリックして、Dataiku DSSを再起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417992/b13c5e33-ad35-29d3-decf-836628f84885.png)
4. 再起動が終わると、[Reverse Geocoding/Admin maps](https://www.dataiku.com/product/plugins/geoadmin/)の機能を利用することができます。[Reverse Geocoding/Admin maps](https://www.dataiku.com/product/plugins/geoadmin/)の利用の仕方は[こちら](https://doc.dataiku.com/dss/latest/preparation/geographic.html)を参照してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417992/ee3b389d-225e-4825-8281-b85762f014ca.png)

# おわりに

Dataikuプラグインを利用すると、新しいデータ項目の追加や、時系列分析など便利な機能を利用することができます。また、独自のデータ分析処理をプラグインとして作成すると、他の方に共有することもできます。
よろしければ活用してみてください。
A=Bなbash variablesファイルをexportでenvにする方法

# やりたいこと
```
# アレのパスワード
ID=abc
PASSWORD=123
```

こういう .env ファイルをflask実行するとき、docker-composeにenv_fileするときとかで使ってるんだけど、bashから直で叩きたい時に不便（）環境変数として入れとかないといけない）

# command

これよさげ！ macで動いた。

```
 env $(sed -e '/^\#/d' flask.env ) | rails
```

## 解説 
ただのcatだとコメント行(#)でエラー出しちゃうので、sedでコメントは消してる。

railsが何やってるのかはわかってない

## 追記

railsなくても入るやん

```
 env $(sed -e '/^\#/d' flask.env )
```

# reference
https://stackoverflow.com/questions/19331497/set-environment-variables-from-file-of-key-value-pairs/19331521
【R】Rのインストール

##ことの顛末##
そもそもこんなこと書く必要ないじゃん！？って思われる方は多いと思います。
ええ、多分自分も何も知らずに見たらそう思うでしょう。

この記事は、自分が他の記事に対してオブジェクト指向で記事を作成するための記事です。

##Rのインストール##

```
[root@localhost ~]# yum -y install epel-release
[root@localhost ~]# yum -y install R
```

これだけです(´・ω・`)
Drupal8 キャッシュ無効化（開発モード）

#  ①sites/example.settings.local.php
　sites/example.settings.local.phpをリネームし、sites/default/settings.local.phpに移動
　※フォルダ移動が必要！

# ②sites/default/settings.local.php設定変更
　次の行のコメントを解除

```
$settings['cache']['bins']['render'] = 'cache.backend.null';
$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.null';
$settings['cache']['bins']['page'] = 'cache.backend.null';
```

# ③sites/development.services.yml、以下の設定変更

```
parameters:
  twig.config:
    debug: true
    auto_reload: true
    cache: false
services:
  cache.backend.null:
    class: Drupal\Core\Cache\NullBackendFactory
```

# ④sites/default/settings.php設定変更
　次の行のコメントを解除

```
  if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
  　include $app_root . '/' . $site_path . '/settings.local.php';
　}
```

# ⑤手動でキャッシュクリア
  パフォーマンスページでキャッシュクリアするか、以下のURLでクリア
  http://{website}/core/rebuild.php

 **設定ファイル変更や、TWIGファイル追加時、手動でキャッシュクリアする必要がある**


##必要ないメニュー削除CSS
```
#toolbar-item-administration-tray .visually-hidden ,
#toolbar-bar > .visually-hidden {
	display: none;
}
```
WinSCPの半自動化(スクリプト作成) 日本語で落ちる場合

# WinSCPのスクリプト作成
WinSCPのスクリプトを作成することにより、ファイルの配置やDL等を自動化します。
コマンドは下記サイトを参考にしました。

[WinSCPスクリプト](https://ja.osdn.net/projects/winscp/wiki/scripting)


## スクリプトに“”で囲っても日本語があると起動できずに落ちる問題発生

スクリプトファイルの文字コードをUTF-8にすることで
落ちなくなりました


使ったコマンドは別途更新します。
🍰【CakePHP2】処理の中で別のDB設定ファイルを読み、その内容にてDB再接続をする


## 環境
PHP 7.2.21
CakePHP 2.10.18
MySQL 5.7.27

## やりたいこと
CakePHPの処理中にて別のDBからデータを取得するためにDBの再接続を行いたい
前の記事にて別のDB設定ファイル読込み関数を用意したのでそれと合わせてControllerからDB切替えを行う

## やったこと
ビヘイビアに別のDB情報を読み込む関数を用意し
ModelでactAsでビヘイビアを指定

Modelには更にDB再接続の関数を追加しておいてControllerで呼び出す

### Model

```Model/AppModel.php
<?php
App::uses('AppBaseModel', 'Model');

/**
 * AppModel
 */
class AppModel extends AppBaseModel {
    /**
     * Hogeビヘイビアを使うためactAs追加
     */
    public $actsAs = [
        'Hoge',
    ];

    /**
     * 指定した設定ファイルを読込んでdataSourceを変更しDB再接続
     * @param $dbFileName 読み込むdatabase.phpファイル名
     * @param $dBConfig   database.php内DBの参照情報
     */
    public function connectAnotherDatabase($dbFileName, $dBConfig = 'default') {
        if (!empty($dbFileName)) {
            // $dbFileNameからDB情報呼び出し
            $dbc = $this->readDatabaseValue($dbFileName);
            // 前の処理でインスタンス化したClassを破棄
            ConnectionManager::drop($dBConfig);
            // DB再接続
            $db = ConnectionManager::create($dBConfig, $dbc);
            $db->reconnect($dbc);
            $this->setDataSource($dBConfig);
            return true;
        } else {
            return false;
        }
    }
}
```

### Behavior

https://qiita.com/eltociear/items/55d45a35a8891c52c126
設定ファイル読み込み関数は↑記事と同じものを使用

```Model/Behavior/HogeBehavior.php
<?php
/**
 * Hoge behavior
 */
class HogeBehavior extends ModelBehavior {
    /**
     * 別のDB情報を環境database.phpから読込み
     *
     *@param Model  $model
     *@param string $dbFileName 読み込みたいdatabase.phpファイル名
     *@return array 取得情報
     */
    public function readDatabaseValue(Model $model, string $dbFileName) {
        $cnt = 0;
        $flg = false;

        // 読み込みたいdatabase.phpのフルパス
        $filePath = ROOT . DS . 'app' . DS . 'Config' . DS . $dbFileName;
        if (file_exists($filePath)) {
            $fdata = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
            foreach ($fdata as $line) {
                $line = preg_replace("/( |,|')/", "", $line);
                $data = explode('=>', $line);
                if (strpos($line, 'public') !== false) {
                    $cnt++;
                    $flg = false;
                }
                if ($cnt == 1 && $flg == true) {
                    $result[$data[0]] = $data[1];
                }
                $flg = true;
            }
        }

        return [
            'datasource' => $result['datasource'],
            'persistent' => $result['persistent'] === 'true' ? true : false,
            'host'       => $result['host'],
            'login'      => $result['login'],
            'password'   => $result['password'],
            'database'   => $result['database'],
            'prefix'     => $result['prefix'],
            'encoding'   => $result['encoding'],
        ];
    }
}
```
### Controller

別DBに再接続したい処理のあるControllerに設定ファイル名と上記で指定した関数呼び出しを記述

```Controller/HogeController.php
// 再接続対象のDB情報がかかれた設定ファイル
$dbFileName = 'Neko.php';
// AppModelをextendsしたModelを使い別のDBに再接続
$this->Users->connectAnotherDatabase($dbFileName);
```

## 結果

変数で対象のDB設定ファイルを指定できるので再接続対象を動的にも指定できます
OCI Computeでのシェイプ変更方法


2020年1月13日からOCI Computeでシェイプの変更ができる機能が追加されました。
https://docs.cloud.oracle.com/iaas/releasenotes/changes/22dfb8e4-3d2e-4fec-b9ad-2505cf7fc30b/

## OCI Computeでのシェイプ変更方法

VM.Standard2.1 から VM.Standard2.2に変更してみます。
変更前のVirtual Processorsは「2」です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23861/88ff69be-ba8d-1c23-5a2c-5ce0949dd50c.jpeg" width=70%>

1. インスタンス詳細画面の「アクション」に「インスタンスサイズの変更」が追加されています。
![oci1a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23861/a079609d-a280-3208-8ac1-42dbf26c8f75.jpeg)

2. 変更したいシェイプ（ここではVM.Standard2.2）をチェックし、「インスタンスのサイズ変更」をクリック
![oci2a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23861/f2c9b8ee-7418-e9f3-e1bd-5ec791e00e16.jpeg)

3. ステータスが「停止中」になり、インスタンスがシャットダウンされます。
この時点ではまだ「VM.Standard2.1」です。
![oci3a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23861/1d0f0059-5715-0015-ceeb-81c640ca0f39.jpeg)

4. 2分程すると「起動中」になります。シェイプが「VM.Standard2.2」に変わっています。
![oci4a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23861/4619fcf7-a25a-7612-3743-7241e0329457.jpeg)

5. さらに1分程すると「実行中」になり、インスタンスにログインできます。
![oci5a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23861/898427cc-34d2-7b92-1b66-ff0c6ff756a1.jpeg)
　
変更後のVirtual Processorsは「4」になりました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23861/a84eb6ec-0b50-d134-82ee-374f0409bbb6.jpeg" width=70%>
MySQLを起動しようとすると『ERROR! The server quit without updating PID file』と表示される。

## MySQLが起動できない
HomebrewでインストールしたMySQL5.7を起動しようとすると以下のエラーが表示される。

```
% mysql.server start                                                                                   
Starting MySQL
. ERROR! The server quit without updating PID file (/usr/local/var/mysql/xxxxx.local.pid).
```

## 解決策

MySQLを一度アンインストールして`/usr/local/var/mysql`内のファイルを全削除した後、再インストールする。

```
% brew uninstall mysql@5.7
% cd /usr/local/var/mysql

# カレントディレクトリ内(/usr/local/var/mysql)の全フォルダとファイルを削除します。
% rm -rf *
% brew install mysql@5.7 
```

以下のように表示されれば成功。

```
% mysql.server start      
Starting MySQL
. SUCCESS! 
```

## 原因
MySQLの他のバージョンを使っていたために、ファイルの競合が起こっていた模様。

#### 参考にさせていただいた記事
「ERROR! The server quit without updating PID file」となり、MacOSでmysqlにアクセスできない。
https://qiita.com/furafura_nau/items/7d8f5370899df125d459
AWS EC2インスタンスの複製をしてみた。その3（備忘録）

前回の続きです。https://qiita.com/Bikeiken-IT/items/5cf4bb3203ce27faf567

TeraTermからEC2にアクセスします。
![step14-tera-host-ip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550376/67c591b0-a17f-adb4-45e7-27fb68323feb.png)
TeraTermの接続画面に、先ほど作成したEC2インスタンスのIPv4のパブリックIPをホストのIPアドレスとして入力します。
![step15-serurity-msg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550376/abd4292f-ce13-bb83-798d-e07646e4f59a.png)
続いて、セキュリティ警告の画面が現れますが、無視して続行のボタンを押してください。
![step16-ssh-modify.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550376/4045cc83-dd96-3565-34d8-747dc553ddae.png)
続いて、認証の為にユーザー名の入力とキーペアの指定（pemファイル)を行います。
![step17-ec2-connect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550376/c6b55437-690c-5422-3976-f4d4a12267af.png)
TeraTermからEC2への接続が出来ました。
![step18-sudo-update.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550376/59d7790b-0018-d241-4fb2-fe4ee6ce40b3.png)
続いて、管理者権限に移行します。
Bashコマンドで"Sudo su -"と入力してください。

続いて、ファイルのアップデートを行います。
"Yum update -y"と入力してください。
![step19-httpd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550376/c1c1c86f-213d-108b-f244-30daea4399cb.png)
アップデートが完了したら、次にApacheサーバーをインストールします。

その４に続きます。https://qiita.com/Bikeiken-IT/items/5b6d1e3ab5573c081ba8
2020-01-16 Microsoft Edge > PDFリンダリング > Version 79.0.309.65 (Official build) (64-bit)で成功するように

```txt:動作環境
Windows 10 Pro (v1909)
Microsoft Edge Version 79.0.309.65 (Official build) (64-bit)
```

従来のEdge (Microsoft Edge 44.18362.449.0)においては一部のPDFファイルのレンダリングが失敗していた (白紙になる)。

2020-01-16最新のEdgeを試したらところ、同じPDFファイルのレンダリングに成功するようになった。

他のPDFファイルは未検証ではあるが、ようやくまともになってきたか。

### 旧情報

下記の情報はもう古く、最新版には合っていない。

- [2016-09-13 Microsoft Edgeが対応しているPDF規格について](https://answers.microsoft.com/ja-jp/edge/forum/all/microsoft/fbfd37f3-0a48-43ca-863b-e5a671c84b70)

質問がロックされているので、追加情報も書けない。
neovimをUnityの外部エディタにする(macOS)

Unityの外部スクリプトエディタ(External Script Editor)にneovimを登録するためにやったことをまとめます。

## やりたいこと
Unity Editorでソースファイルやエラーメッセージをダブルクリックしたとき、

* 端末(iTerm2 + tmux)上で起動済みのneovimにそのファイルを開かせる
* カーソルを指定の行に合わせる
* neovimのカレントディレクトリをUnityのプロジェクトパスに変更する

## 実行環境
* macOS Mojave(10.14.3)
* iTerm2
* tmux
* neovim v0.4.3
* Unity 2018.3.0f2

## 実現方法
### neovim-remoteによる遠隔起動
https://github.com/mhinz/neovim-remote
neovimは起動時に遠隔指示を受け付けるサーバを立ち上げてくれます。neovim-remoteはそれを利用して、起動済みのneovimに指定のファイルを開かせるコマンドです。
これを使って上記の挙動を実現すると次のようになります。

```sh
nvr --remote +(行番号) (ファイル名) -c 'cd (プロジェクトパス)'
```
となれば、あとはnvrを外部エディタとして登録し、引数をUnity側で設定してあげればOK……ではありません。nvrを外部エディタとして登録することができないからです。

### Automatorで.App化する
macOS版Unity Editorに登録できる外部エディタはCocoa App形式に限られます。つまりnvrそのものや、nvrを実行するシェルスクリプトはそもそも登録することができなくなっています。
ではどうするか？幸いmacOSにはAutomatorがあるので、これを使いましょう。内部的にシェルスクリプトを実行するAppを作成することができます。

次のようにAutomator Applicationを設定します。

* 新規Applicationを作成する
* 「シェルスクリプトを実行」を追加し、次のように記述する。また、入力の引き渡し方法は「引数として」を選ぶ。

  ```sh:シェルスクリプトを実行
eval "/usr/local/bin/nvr" "--remote" $@
  ```
* 上記Applicationを保存する
* Unity側でPreferencesを開き、External Tools画面のExternal Script Editorに上記Applicationを指定する
* 同画面のExternal Script Editor Argsに下記を指定する

```
"+$(Line) $(File) -c 'cd $(ProjectPath)'"
```

これで完成です！Unity Editor上でC#スクリプトやシェーダファイルをダブルクリックすると、neovimが起動済みであればそちらで開かれます。

## 今後の課題
ファイルを開いたときにneovim(を起動しているiTerm2)にフォーカスを移したいのですが、これは上記Automator Applicationに追加処理を記述することで実現できそうです。
また、今回はneovimがすでに起動していることが前提になっており、neovim未起動の状態でファイルを開こうとするとエラーになります。ここはどうにか改善したいところです。

以上です。
Link: WPS > NCL > metgridで使う中間ファイルのRead/Writeサンプル

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2 
32GB RAM 
CentOS Linux release 7.7.1908 (Core)
NCAR Command Language Version 6.5.0
```

WRF (Weather Research and Forecasting Model)関連。
前処理のWPSについて。

Reynolds SSTの提供が終了してしまい、代わりのOI SSTを使う検討をしている。
その場合、OI SSTファイルをWPSで使えるように変換する必要がある。
metgrid用に中間ファイルを作成する、というのが一つの手である。

### NCL > metgridで使う中間ファイルのRead/Writeサンプル

- [wrf_wps_read_int](https://www.ncl.ucar.edu/Document/Functions/Built-in/wrf_wps_read_int.shtml)
    - Reads data from a WPS intermediate file. 
- [wrf_wps_write_int](https://www.ncl.ucar.edu/Document/Functions/Built-in/wrf_wps_write_int.shtml)
    - Writes data to a WPS intermediate file.