OmniAICreator/Qiita-1.07M huggingface dataset:
Raspberry Piを野外で使う際のコンソールの検討(続報)

[前回](https://qiita.com/tomoto335/items/c71b87730db413a8edbb)、Raspberry Piを野外で使うためにスマフォにテザリング的手法で接続してVNCを使う方法を紹介した。ところが最近のAndroidのバージョンアップにより、スマフォ側のDHCPで割り当てられるネットワークアドレスが変動するようになり、RPi側のIPアドレスを決め打ちする方法が常に動くとは限らなくなってしまった。まぁ特に驚きはしない、というか今時分あんなやり方で動いていたことの方がむしろ驚きなのだが、このままでは困るので回避策を考えてみようと思う。

前回紹介した接続方法のうち、動かなくなったのはUSBテザリングとWiFiホットスポットである。Bluetoothテザリングのアドレスは依然として固定であり、そのまま動いている。これは不幸中の幸いであるが、いつ突然動かなくなるかわからない。とりあえず `/etc/dhcpcd.conf` からusb0とWiFiホットスポットの静的IPアドレス指定をはずし、IPアドレスが変動する前提でどうすればいいかを考える。

## トライ1: Bonjour Service Discoveryの使用

[MultiVNC](https://play.google.com/store/apps/details?id=com.coboltforge.dontmind.multivnc)というAndroid用VNCビューワは、Bonjour Service Discoveryをサポートしているらしい。つまりRPiの方からVNCサーバをBonjourサービスとしてアドバタイズすれば、IPアドレスが変動しようがMultiVNCからRPi上のVNCサーバを発見して接続できるはずである。これが期待通り動けば理想的だ。

ではVNCサーバのアドバタイズの設定をしてみよう。まずavahi daemonが動いている必要があるが、既にmDNSを有効にしてあるのでここはクリア済みとする。次に[このあたり](https://gettingstartedwithraspberrypi.tumblr.com/post/24400361937/finding-your-vnc-server-using-bonjour)を参考に以下のような `/etc/avahi/services/rfb.service` を書く。

```
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
  <name replace-wildcards="yes">%h</name>
  <service>
    <type>_rfb._tcp</type>
    <port>5901</port>
  </service>
</service-group>
```

これだけでMultiVNCからVNCサーバを発見、接続することができた！…と喜んだのも束の間、発見できるのはスマフォとRPiがWiFiネットワークでつながっているときだけで、テザリング用にぶらさがっているアドレスに対しては検索が行われないようである。MultiVNCのソースコードを見に行くと、確かに[このへん](https://github.com/bk138/multivnc/blob/baf8a827bad372bd4bf7388af94d0e3867e7b0f2/android/app/src/main/java/com/coboltforge/dontmind/multivnc/MDNSService.java#L214
)を見る限りWiFi限定になっているようだ。issue切ったりPR切ってもいいのだが、ユースケースがトリッキーなのでなんか気の毒な気がする。

というわけで、この方法は惜しくも問題を解決しないことが判明。

## トライ2: Service Browserの使用

VNCサーバをBonjourサービスとしてアドバタイズするようにできたのだから、Android上のBonjourサービスブラウザを使えばIPアドレスくらいわかるんでないの？というわけで、[Service Browser](https://play.google.com/store/apps/details?id=com.druk.servicebrowser)を試してみた。結論から言うと、これがほぼ期待通りであった。

Service Browserは非常にそっけない、いかにも開発者ツール然としたアプリだが、USBテザリングやWiFiホットスポットで接続したRPi上のVNCサーバを `_rfb._tcp. (Remote Framebuffer)` として発見し、そのIPアドレスを見ることができる。なぜかBluetoothテザリングの場合は発見できないこともあるのだが、Bluetoothテザリングはまだアドレス固定なので困らない。

別のアプリに[Bonjour Browser](https://play.google.com/store/apps/details?id=de.wellenvogel.bonjourbrowser)というのがあるが、これはサービスタイプがHTTPのものだけを発見するものである。これは、`type` を `_http._tcp` にしたサービス定義を `/etc/avahi/services/` に作っておけば同様に使える。IPアドレスを見たいだけなので実際にHTTPサーバを立てる必要はない。

Service BrowserでIPアドレス確認⇒VNC Viewerにそのアドレスを入力して接続という面倒なステップを踏む必要があるが、まぁ使えるのでよしということにする。
フォルダ内の画像ファイルをまとめてWord内に貼り込む


# 写真のサムネイルを紙で印刷したい
もはや、プライベートで撮った写真の一覧を紙でわざわざ見たいなんてことはほとんどありませんが、仕事では結構未だにあります。特に証拠写真みたいなものはちゃんと紙で残さなければならないわけです。でもその写真が数枚であれば手作業で挿入を繰り返して文書内にレイアウトしますが、何百枚とあるときにはゾッとしますよね。というわけで作ったWordマクロです。

## 作り方
下記のコードをWord（マクロ有効ファイル）に貼り付けて下さい。A4ページ2段組を想定してサイズの初期設定をしています。

``` VB
Sub サムネイル貼り込み()
 
Dim myFolderPath,myFileName,myFilePath,myExtension,myDoc As String
Dim FSO As Object

Set myDoc = ActiveDocument
Set FSO = CreateObject("Scripting.FileSystemObject")
myFolderPath = myDoc.Path
  
myFileName = Dir(myFolderPath & "\", vbNormal)
Do While myFileName <> ""
    myExtension = LCase(FSO.GetExtensionName(myFileName))
        Select Case myExtension
            Case "jpg", "png"
            myFilePath = myFolderPath & "\" & myFileName
            With myDoc.Bookmarks("\EndOfDoc").Range
                .InlineShapes.AddPicture FileName:=myFilePath
                .InsertAfter Text:=vbCr & myFileName & vbCr
            End With
            Case Else
       End Select
    myFileName = Dir()
Loop
Set FSO = Nothing
Set myDoc = Nothing

Dim Shp As InlineShape
    For Each Shp In ActiveDocument.InlineShapes
        With Shp
            .LockAspectRatio = msoTrue
            .Height = Application.MillimetersToPoints(48.5)
            .Width = Application.MillimetersToPoints(64.7)
        End With
    Next
End Sub
```
python3: bottle の使い方 (template)

template の使い方です。

フォルダー構造

```text
$ tree
.
├── template.py
└── views
    └── sample.html
```

```py:template.py
#! /usr/bin/python
#
#	template.py
#
#						Nov/12/2020
#
# ------------------------------------------------------------------
from bottle import run, route, template

# ------------------------------------------------------------------
@route("/")
def index():
    username = '夏目漱石'
    return template('sample', username=username)
# ------------------------------------------------------------------
@route('/hello/<name>')
def hello(name="Stranger"):
    return template("Hello, {{ name }}.  How are you?", name=name)
# ------------------------------------------------------------------
if __name__ == "__main__":
    run(host='localhost', port=8080, reloader=True, debug=True)
# ------------------------------------------------------------------
```

```html:views/sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8" />
<title>テンプレートエンジン</title>
</head>
<body>
<h2>こんにちは: {{ username }}</h2>
Nov/12/2020<br />
</body>
</html>
```

サーバーの実行

```text
$ ./template.py 
Bottle v0.12.18 server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.
```

クライアントでアクセス
http://localhost:8080/
![template01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/f41fbe6b-497b-c7c6-6872-0893c2e62142.png)

http://localhost:8080/hello/太郎
![template02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/6be69e79-778e-ad67-c916-b778830aaf2c.png)

次のバージョンで確認しました。

```text
$ python --version
Python 3.9.5

$ python -m bottle --version
Bottle 0.12.19
```
文字列に変数を混ぜる方法を言語ごとにまとめてみた

ゆるっと Advent Calender 2020 の初日に参加させていただきましたー。
よろしくお願いします。

初日にふさわしいかわかりませんが、ゆるゆる仕事してたら恥をかいた件を書きますね。

先日先輩にレビューしてもらったとき、文字列の中に変数を足しこむやり方を、＋演算子を使ってやっていたら先輩に『ダサい』と一蹴されました。(*'▽')ｶﾞﾌｯ

```js:string.js
const word = "hogehoge";
const text = "彼はおもむろにこう言った。\n『 " + word + " 』、と。";
console.log(text);
```

```
彼はおもむろにこう言った。
『 hogehoge 』、と。
```

勉強不足でごめんなさい。( ;∀;)
あと、ユニク〇ばかり着ててごめんなさい。

反省したので自分の学んだことのある言語での書き方や名称をまとめたい思います。

# Javascript, Node.js, GoogleAppsScript

Javascript および Node.js および GoogleAppsScript では[テンプレートリテラル](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Template_literals)という名称になっています。 

文字列をグレイヴ・アクセント（`）で囲み、変数を入れるときはドル記号と波括弧でくくります。

```js:templateLiterals.js
const word = "hogehoge";
const text = `彼はおもむろにこう言った。\n『 ${word} 』、と。`;
console.log(text);
```

```
彼はおもむろにこう言った。
『 hogehoge 』、と。
```

# Python

Python では[フォーマット済み文字列リテラル](https://docs.python.org/ja/3/reference/lexical_analysis.html#formatted-string-literals)という名称になっています。

`f` または `F` を先頭に書いてから文字列を書いていきます。
変数を入れるときは波括弧で区切ります。

```python:formattedStringLiteral.py
word = "hogehoge";
text = f"彼はおもむろにこう言った。\n『 {word} 』、と。";
print(text);
```

```
彼はおもむろにこう言った。
『 hogehoge 』、と。
```

# Java

**ない。**

強いて言うなら `String.format()` を使うとできる。

```java:stringFormat.java
String word = "hogehoge";
String text = "彼はおもむろにこう言った。\n『 %s 』、と。";
String output = String.format(text, word);
System.out.println(output);
```

```
彼はおもむろにこう言った。
『 hogehoge 』、と。
```

# C♯

C# では[文字列補間](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/tokens/interpolated)という名称になっています。 

`$` を先頭に書いてから文字列を書いていきます。
変数を入れるときは波括弧で区切ります。

```c#:stringInterpolation.cs
string word = "hogehoge";
string text = $"彼はおもむろにこう言った。\n『 {word} 』、と。";
System.Console.WriteLine(text);
```

```
彼はおもむろにこう言った。
『 hogehoge 』、と。
```

# おわりに

Java にはなかったもんなー( ﾟДﾟ)

知らなかったの私だけかもしれませんが、実践に勝る経験はありませんね。

この記事が誰かの助けになれば幸いです。|дﾟ)

自身のメモ用でもあるので、新しい言語を使うときには更新していきますー。

ではまた！(^^)/

# 参考にさせていただきましたm(_ _)m

[MDN - テンプレートリテラル](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Template_literals)
[Python documentation - フォーマット済み文字列リテラル](https://docs.python.org/ja/3/reference/lexical_analysis.html#formatted-string-literals)
[.NET documentation - 文字列補間](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/tokens/interpolated)
超個人メモ htmlファイルで`<`や`>`を文字列として表示したい時の話

- `<`を文字列として表示したいときは下記のように記載することで表示する事ができる。

    ```html
    &lt;
    ```
- `>`を文字列として表示したいときは下記のように記載することで表示する事ができる。

    ```html
    &gt;
    ```
- その他にhtmlで特殊文字列として扱われているものを文字列として表示したいときは下記サイトのコード表を参考にすると良いかもしれない。
    - [http://www.shurey.com/js/labo/character.html](http://www.shurey.com/js/labo/character.html)
Xcode で Canvas を上手に利用するための Tips

##記事内容


Xcode 12 では Canvas の機能を使って、コーディングしながらリアルタイムにデバイスの画面がどのように表示されるのかを確認できます。

この記事では、その便利な Canvas をさらにより良く使いこなすための Tips（ヒント）を掲載します。良い Tips があれば随時追加していく予定です。


##もくじ

- @EnvironmentObjectのプロパティを持つViewを表示するには
- @Bindingのプロパティを持つViewを表示するには
- Viewを必要最低限のサイズで表示するには
- 複数デバイスのPreviewを表示するには ・・・2020/12/06追加
- ライトモード、ダークモードを指定して表示するには・・・2020/12/13追加







##@EnvironmentObjectのプロパティを持つViewを表示するには

ObservableObject クラス内の @Published 付きプロパティの値を 他のView から常に参照するために、そのクラスのインスタンスを @EnvironmentObject プロパティラッパーをつけて View 内に作成している場合、そのViewのプレビューには、以下のようにViewのインスタンスに、.environmentObject(_ClassName_())モディファイアをつける必要があります。これをつけないと Resume ボタンをクリックしても Canvas に表示されず、エラーになります。

```swift
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environmentObject(Manager())
    }
}
```



##@Bindingのプロパティを持つViewを表示するには

@Bindingプロパティラッパーが付いているプロパティを持つ構造体の場合、そのプロパティはデータ型だけ指定され、値は代入されていません。例えば以下のように。

```swift
@Binding var name: String
```
このようなプロパティを持つ構造体のプレビューをCanvasに表示したい時、イニシャライズ時に適当な引数を入れてもエラーになります。このような場合は以下のように、引数として.constant()を指定するとうまく表示されます。これはView内のあらゆるバインディングで、何か値を仮に入れたい場合に使えます。プレビューのコードは以下のようになります。

```swift
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(name: .constant("Hoge Fuga"))
    }
}
```

Paul Hudson さんの Hacking with Swift もご参照ください。
https://www.hackingwithswift.com/quick-start/swiftui/how-to-create-constant-bindings




##Viewを必要最低限のサイズで表示するには
メインのViewに配置するコンポーネント用のView（画面のパーツ）を作成している場合、コンポーネント用のView単体をデバイススクリーン大のCanvasに表示するより、そのコンポーネント用Viewのみをジャストサイズで表示したい場合は、以下のように .previewLayout(.sizeThatFits) モディファイアをつけるとViewのジャストサイズになります。

```swift
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environmentObject(Manager())
            .previewLayout(.sizeThatFits)
    }
}
```



##複数のデバイスモデルのPreviewを表示するには
Canvas に複数のデバイスモデル（例えば、iPhone 12 mini と iPhone 12 Pro と iPhone 12 Pro Maxなど）を同時に表示させたい場合、ForEachを利用しつつ、特定のモディファイアを表示したいViewにつけてあげると良いです。

追加すべきモディファイアは以下の2つです。

```swift
.previewDevice()
.previewDisplayName()
```
実際のコードは以下のようになります。

```swift

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ForEach(["iPhone 12 Pro", "iPhone 12 mini", "iPhone 12 Pro Max", "iPhone 8", "iPod touch (7th generation)"], id: \.self) { deviceName in
            ContentView()
                .previewDevice(PreviewDevice(rawValue: deviceName))
                .previewDisplayName(deviceName)
        }
    }
}
```


##ライトモード、ダークモードを指定して表示するには

以下のモディファイアと引数（.light / .dark）を指定してあげるとライトモードもしくはダークモードを指定してCanvasにプレビューを表示できます。

```swift
.environment(\.colorScheme, .light)
.environment(\.colorScheme, .light)
```

プレビューの全体のコードは以下のようになります。

```swift
struct ContentView_Previews: PreviewProvider {
   static var previews: some View {
      Group {
         ContentView()
            .environment(\.colorScheme, .light)

         ContentView()
           .environment(\.colorScheme, .light)
   }
}
```
composer様という依存性管理パッケージツールのありがたみ

# はじめに
最近、チームで開発することになりPHPのフレームワークのLaravelを使用しているのですが、その時に使用するcomposerが改めて便利だなと思った話。

1. composerとは
2. composerを使用してみよう
3. まとめ

# composerとは

composerは依存管理パッケージツールと呼ばれています。どういう意味かというと

> Aというライブラリを使用しようとすると、他にBが必要でBを使用するとCが必要でと、どんどん必要なものが増えていきます。

そんな、面倒なことを一気に解決してくれるのがcomposerです。

### composerの利点
**composer.lock**があるのでチームでの開発が楽になる。composer.lockにはcomposer.jsonに書かれたライブラリを取得するために、どのようなファイルを落としてきたかだまとめられているファイルです。なのでチームで開発する時に、composer installというコマンドを入力すると他のチームと同じ開発の環境にしてくれます。

**オートロード機能**がある。例えば、ライブラリを使用したいとしてこのファイルとこのファイルを読み込みといったことをしなくてよく。``/vendor/autoload.php``を読み込んであげるとそんなめんどくさいことをしなくよくなります。

このように利点がいくつかあります。

# composerを使用してみよう

それでは、実際に使用してみましょう。始める方法は沢山あるのですがそのうちの一つを今回はやります。
<font color="Red">(composerはあらかじめ自分の環境で使用できる状態にして下さい)</font>

最初に、自分が作業するフォルダに移動しcomposer.jsonというファイルを作成します。

```json
{
   "require": {
      "phpmailer/phpmailer": "*"
   }
}
```
そして、上記の内容を記述して下さい。
### composer.json
まず、``composer.json``には自分が取得するライブラリの名前をrequireに記述します。**ベンダー名/プロジェクト名:バージョン**になります。バージョンには今回はワイルドカードを設定します。
次にコマンドで``composer install``を入力します。するとフォルダ内にvendorとcomposer.lockが作成されました。

### composer install
``composer install``は、composer.jsonに記載されている内容もしくはcomposer.lockに記載されている内容に従って、パッケージをインストールします。


### composer.lock
``composer.lock``はcomposer.jsonにあるライブラリを取得するために、どのようなファイルを落としてきたかが書かれています。
``vendor``にはインストールしたライブライが入っています。

後は、自分が作業しているファイルにライブライを読み込んであげることで使用することが出来ます。

```php
<?php

require '/vendor/autoload.php';

#自分が使用したいライブライを使用

?>

```


# まとめ
このように、composerがあるおかげてチームで開発するのも楽になります。また、依存関係を気にせずに自分の環境にライブラリを落とすことができます。

# 参考文献
https://getcomposer.org/
Jw_cadでPythonを活用するには(その1 外部変形とは)

20201221：見返すと言葉足らずであったため、一部修正・追記
#Jw_cadでPythonを活用するには(その1)
建築設備(電気)の設計をしているのだが、
Jw_cadというフリーソフトウェアを使用して設計図を作図している。
基本的に"楽に仕事したい"と考えているので、
Jw_cadとPythonを連携させて、業務負担を減らしたい。~~仕事休みたい~~

足がかりとして、Jw_cadの【外部変形】という機能を使ってPythonを活用してみる。

#【外部変形】とは
Jw_cadで行えない事を他アプリケーションで処理、Jw_cad上に反映するという機能である。

動作的には
1. 「Jw_cad上から外部変形ファイル(.bat)選択・実行」
2. 「.batファイル内記載の通りに処理」・「JWC_TEMP.TXT作成」
3. 「JWC_TEMP.TXT内の座標データを編集・追記」
4. 「JWC_TEMP.TXTの通りJw_cad上に反映」

ここでPythonをどう挟むかというと、
1. 「Jw_cad上から外部変形ファイル(.bat)選択」
2. 「.batファイル内で**"Python"**を実行し**"JWC_TEMP.TXTを編集"**」
3. 「Jw_cad上に反映」
という流れ。

このページでは、`外部変形ファイルの作成～実行`までを解説。

#【外部変形】の.batファイルを作成
まず、.batファイルを簡単に説明すると、
.batファイル内に記載されているコマンドを元にJWC_TEMP.TXTが作成される。
(今回はJWC_TEMP.TXTの解説はしません。~~なんせ複雑だから~~　その2で解説予定)

メモ帳で下記の内容を打ち込み、名前をつけて保存で`hogehoge.bat`で保存。

```
@echo off
REM 外部変形起動(hello world!!)
REM #jww
REM #cd
echo hello world!!　
pause >nul
```
2行目**"REM 外部変形起動(hello world!!)"**は、Jw_cadで外部変形を選択する際の表示名称。
3行目**"REM #cd"**はhogehoge.batが保存されている場所にJWC_TEMP.TXTを作成。
4行目**"REM #jww"**は、.jwwのファイル形式だよ！の意味

Jw_cadでは`REM #~~~`という記載はJw_cad内のみで動作するコマンドとなる。

#【外部変形】hogehoge.batを実行
上記の文字列はJw_cadで`hogehoge.bat`を選択すると
コマンドプロンプト上に`hello world!!`と表示される外部変形ファイル。

Jw_cadでの外部変形ファイルの開き方は、[その他] → 外部変形(G) → hogehoge.batを選択
![外部変形.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/845477/69704e57-6908-8258-6636-573ee3f88403.png)
hogehoge.batを選択するとコマンドプロンプトで`hello world!!`と表示されるだけだが、
外部変形ファイル(.bat)を保存している同じ場所にJWC_TEMP.TXTが新規作成されているはず。
(もしJWC_TEMP.TXTが作成されていなければ、Jw_cadがインストールされているフォルダに保存されているかも？)


#まとめ
このページではPythonの動作する下地として
外部変形の.batファイルの作成、Jw_cad上からの実行までを解説した。
(その2)では、外部変形.batファイルで記述するREM #~~~の解説などを行いたい。

##参考文献・ソフトウェア
[Jw_cadのページ](https://www.jwcad.net/index.htm)　← Jw_cadの公式ページです。
[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)　← Qittaの書き方で参考にさせてもらいました。
AWSを勉強する - EC2

#Amazon Elastic Compute Cloud（EC2）
従量課金で利用可能な仮想サーバー。
起動、ノード追加、削除、マシンスペック変更
任意のAZにインスタンスを立ち上げてサーバーとして利用する。


###EC2のセッティング

1. 利用するAMIイメージ（OSセッティング）を選択
2. インスタンスタイプを選択
3. ストレージを選択
4. セキュリティグループを選択
5. SSHキーペアを設定


#AMIイメージ
インスタンス起動用のOSイメージのこと（WindowsとかLinuxとか）。

下記の中から用途に合わせたAMIイメージを選択する

- AWSが用意して提供しているAMI（Windowsとか）
- 誰かが作成した有料のAMI
- AMIを自作する

#インスタンスタイプ
CPU・メモリ、ストレージ、ネットワークキャパシティなどのスペックを選択。
個々の設定でより低コストで最適なパフォーマンスを出せるセッティングが必要。
通常は、オンデマンドでインスタンスを購入する。

名前の構成↓
(ファミリー)(世代).(インスタンスの容量)
例）t2.nano

###インスタンスファミリー

- M5：汎用
- T2：汎用
- C5：コンピューティング最適化
- H1：ストレージ最適化
- D2：ストレージ最適化
- R4：メモリ最適化
- X1：メモリ最適化
- F1：FPGA
- G2：GPU

その他、詳細：https://aws.amazon.com/jp/ec2/instance-types/

##リザーブドインスタンス
利用期間を長期指定して利用する形式。

|  | スタンダード | コンバーティブル |
|:-:|:-:|:-:|
| 利用期間 | 1年（40%割引）<br>3年（60%割引） | 1年（31%割引）<br>3年（54%割引） |
| AZ／インスタンスサイズ／<br>ネットワークタイプ変更可否 | 有 | 有 |
| インスタンスファイリー／OS／<br>テナンシー／支払いオプションの変更可否 | なし | 有 |
| リザーブドインスタンス<br>マーケットプレイスでの販売可否 | 可能 | 今後可能となる予定 |

ユースケース

- 一定した状態または使用量が予測可能なワークロード
- 災害対策などキャパシティ予約が可能なアプリケーション

##スポットインスタンス
予備のコンピューティング容量をオンデマンドインスタンスに比べて割引で利用できるEC2インスタンス

- 予備用を入札式で利用するため安い
- 起動に通常より少し時間がかかる
- 予備用のため途中で削除される可能性がある（一時的な拡張などの用途で利用）

##Saving Plan
1~3年の期間に一定の使用量を守ることによりAmazon EC2コストを削減する。

#ストレージ
基本的にはEBSを選択する。

- インスタンスストア
    - ホストコンピュータに内蔵されたディスクでEC2と不可分のブロックレベルの物理ストレージ
    - EC2の一時的なデータが保持され、EC2の停止・終了をともにクリアされる
    - 無料
- Elastic Block Store（EBS）
    - ネットワークで接続されたブロックレベルのストレージでEC2とは独立して管理される
    - EC2をTerminate（接続を遮断）してもEBSは保持可能で、SnapshotをS3に保持可能
    - 別途EBS料金が必要

#セキュリティグループ
インスタンスへのトラフィックのアクセス可否を設定するファイアーウォール機能を提供
アクセスする範囲を設定することで安全性を高める。

#キーペア
キーペアを利用して自身がダウンロードした秘密鍵とマッチした公開鍵を有するインスタンスにアクセスする。

#EC2のバックアップ
EC2インスタンスは定期的にバックアップすることが重要。

- 定期的にバックアップを取る
- 定期的にリカバリプロセスを確認する
- 複数のAZに重要なアプリケーションをデプロイすること
- フェイルオーバー対応を準備すること
- イベントをモニタリングして対応できるようにすること
- インスタンス起動時に動的IPアドレス処理の設定を行うこと


#参考
- [AWS認定資格試験テキスト AWS認定 ソリューションアーキテクト-アソシエイト (日本語) 単行本](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-AWS%E8%AA%8D%E5%AE%9A-%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/479739739X)
- Udemy
ファイル内の文字列を検索する

## この記事は

- タイトル通りです。
- ググればわかることしか書いてません。
- かんぜんに個人メモです。

## 自己紹介

Java（Spring Boot）のWebアプリ開発を主にやってます。

## ファイル内の文字列を検索する
カレントディレクトリ配下のファイル内に文字列'hoge'があるかを検索する

```bash
find ./ -type f -print | xargs grep 'hoge'
```

## 最後に

以上です！
【windows】タスクスケジューラ 一覧の取得コマンド

タスクスケジューラの一覧は、コマンドプロンプトから指示します。

##基本コマンド
```schtasks /query```
（タスク名、次回の実行時刻、状態）

##詳細情報まで出力
```schtasks /query /V ```

##CSV形式で出力
```schtasks /query /FO CSV > d:\tasklist.csv```

##他に知りたいコマンドがある時
```schtasks /query /? ```
Android カスタムView

Android カスタムViewを作成する際は、下記コンストラクタを記述すること
AttributeSet attrsが必要

```
MyView.java

public class MyView extends View {
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
       
    }
}
```


```
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.test.android.viewtest.MyView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</LinearLayout>
```
RAW(PCM)フォーマットからFLACへ変換

# FLACツールのオプションメモ

- ダウンロード元
[FLAC - download](https://xiph.org/flac/download.html)　

```cmd
flac.exe --force-raw-format --channels=1 --bps=16 --sample-rate=16000 --endian=little --sign=signed --delete-input-file -f target.pcm
```

下記はなくてもよい
- 成功時元ファイルを消すオプション: --delete-input-file
- 上書き許可オプション: -f

```cmd
for /r %i in (*.pcm) do @flac.exe --force-raw-format --channels=1 --bps=16 --sample-rate=16000 --endian=little --sign=signed --delete-input-file -f %i
```

フォルダ内のPCMファイルを一括でFLACへ変換。
[Flutter] Integration TestでTextfieldのonEditingCompletedを発火させる方法

# はじめに
テスト、書いてますか(ﾆｺｯ
私は転職してからテストをたくさん書くようになりました。

Integration Testを実装中にTextfield周りでハマってしまい、
FlutterのIssuesを漁ってようやくそれっぽいものを見つけて解決したので、
日本語の記事も特になかった為せっかくなら記事にしようと思った次第です。
ある程度Flutterの知識がある前提で進めていきます。

# 今回の問題
検索画面のテストの実装で、TextFieldに文字をInsertしてonEditingCompletedを呼ぼうとしたが
Flutter Driverだけではキーボード周りのメソッドを呼ぶことはできないためonEditingCompletedが発火しない。

キーボードの検索を押す以外にも別で検索ボタンみたいなものがあれば問題なかったんですけどね...
ないものはないので、頑張って実装しないといけません。

# 実装
flutter_testの機能を使うことにしました。
hoge.dart側で`enableFlutterDriverExtension()`を呼び出す際に引数に、
flutter_testのキーボード周りの処理を用意してDataHandlerを渡しておきます。
hoge_test.dart側でFlutterDriverの`requestData(message)`メソッドを使って、
DataHandlerに用意してあるメソッドを呼び出します。

コードは以下になります。

``` hoge.dart
void main() {
  final textInput = TestTextInput();
  final handler = (String message) {
    switch (message) {
      case 'prepare':
        textInput.register();
        break;
      case 'enterText':
        textInput.enterText('hoge');
        textInput.receiveAction(TextInputAction.done);
        textInput.unregister();
        break;
      default:
        break;
    }
  };
  enableFlutterDriverExtension(handler: handler);
  app.main();
}
```

``` hoge_test.dart

test('', () async {
  driver = await FlutterDriver.connect();
  await driver.requestData('prepare');
  await Future<void>.delayed(const Duration(seconds: 3));
  await driver.tap(find.byValueKey('TextField')); // onEditingCompletedを実装済みのもの
  await Future<void>.delayed(const Duration(seconds: 3));
  await driver.requestData('enterText');
  await Future<void>.delayed(const Duration(seconds: 5));
});
```

`await driver.tap(find.byValueKey('TextField'));`で対象のTextFieldをFocusしておきます。
その後`driver.requestData('enterText')`でhandlerに用意してある以下のコードを呼び出して、
無理やりキーボードの検索を押した際の処理を行います。


``` dart
case 'enterText':
  textInput.enterText('hoge'); // TextFieldにhogeを入力
  // TextFieldに完了を通知 => onEditingCompletedが発火
  textInput.receiveAction(TextInputAction.done); 
  textInput.unregister(); 
  break;
```

上記みたいなコードを書いて`flutter drive`コマンドを叩くと、
いい感じにテストが進んでいってonEditingCompletedを動かすことができました。
結構ざっくりとした感じになってしまいましたが以上です。

# 最後に
久しぶりに文章を書きました。日本語難しいですね。
deviseの実装の自分まとめ

<p>🔰初めての投稿です。</p>
<p>🔰インプット回数は多くアウトプットに時間を費やしていないことに気づき<br>思考整理のため定期的に書いていこうと思います。<br>現在ポートフォリオ作成中でdeviseの実装をまとめてみました！</p>
<p>手順</p><br>
<p>1．$gem install rails -v5.2.3
<br>（railsの最新版 gemをインストールする）</p>
<p>2．$rails -v
<br>（バージョン確認を行いインストールできているのか確認）</p>
<p>3．$rails new アプリケーション名</p><br>
<p>4．$cd アプリケーション名
<br>（ディレクトリ移動を行う）</p>
<p>5．$rails s
<br>（作成したアプリケーションのサーバーが動いているのか確認）</p>
<p>6. gem 'devise'
<br>（gemfileに追記する　deviseというgemを使うということ）</p>
<p>7. $ bundle
<br>（追記したgemを保存する）</p>
<p>8. $ rails g devise:install
<br>（deviseをインストールする）</p>
<p>→ これによりログイン📦ログアウト📦の機能の箱が出来上がった</p>
<p>→ しかし機能を使うための部品、ものがないので揃えていく（イメージ）</p>
<p>9. $ rails g devise:views
<br>（deviseで生成された機能ファイルに対しファイルを作成する（イメージ））</p>
<p>10. $ rails g devise User
<br>（deviseのなかにUserクラスのデータを作っていくためのもの（イメージ））</p>
<p>→ routes.rbにdevise_for :usersが追記される</p>
<p>→ modelsファイル・migrateファイルが生成される<br>（migrateファイル=>usersテーブル生成され、devise機能に組み込まれているカラムがすでに記述されている）</p>
<p>→マイグレーションにカラムを追加すること可能<br>usersはユーザに必要な情報を管理するのでユーザに関する情報は追記していく<br>（生年月日など）</p><br>
<p> 11. $rails db:migrate
<br>（これにより$rails g devise Userで生成されたデータベース関連のものが読み込まれて、
<br>追記したカラムもデータベースに反映される）</p>
<p> 12. $rails g devise:controllers users
<br>（コントローラーの追加を行う）
<br>→deviseのクラスを継承したコントローラファイルを作成する
<br>（デフォルトのコントローラのままだと追加した機能のアクション実行が行えないため、
<br>デフォルトを継承したUserコントローラーを作成している）
<br>（viewsに対応したものが作られる）
</p>
<p> 13.下記を追記しルーティング設定を行う
<br>（○のように書き直す）
<br>devise_for :users
<br>↓
<br>
 ○devise_for :users, :controllers => {<br>
    :registrations => 'users/registrations',<br>
    :sessions => 'users/sessions'<br>
 }

</p>
<p> ここまでが機能を実装のみの工程です！
<br>あとはhome topを作成していき実際に画面表示します</p>
<p>余談ープログラミングを実装していくだけではなく、わかりやすく伝える質問する力、語彙力、PCの様々な機能の使い方などプロブラミング以外にも必要なことがたくさんあり日々学びが多く、苦戦する日々ですが技術だけでは無くいろんな力を身につけてコツコツがんばれたらいいなと思いました。</p>
インフラエンジニアになりました

# はじめに

私は世間で活躍するエンジニアのように高度な能力は持ち合わせていませんが、なるべく楽しく充実させたいと日々考えています。
エンジニアになる前に別業種で失敗をしたりもしましたが、エンジニアになってからは緩く上向きになっているので、同じような境遇の人に届けばと思っています。

# この記事の対象者
・**IT業界に未経験から転職したい人**
　今の業界、職種から脱したいなどの理由も歓迎です。

・**漠然とインフラエンジニアになりたいと考えている人**
　特に理由はないけれど、将来性はありそうだしなんとなくIT業界に入りたいなど。

# 自己紹介
元営業で、法人の新規開拓を担当していました。
そこで成績が同期の中で最下位となり、苦痛から逃れるために辞めてしまいました。
その後は暇な時間になんとなくプログラミングスクールに通い、プログラミングには挫折したものの、インフラエンジニアという道を紹介されて就職しました。

# インフラエンジニアとはなにか
一言でインフラエンジニアを表現するのは、その多岐にわたる役割のため難しいです。
ただ言葉の通りITの何かしらのインフラに関わっているエンジニアであるのは間違いないです。
そのITインフラのシステムを作ったり運用したりといった仕事です。
また、**インフラエンジニアの特徴として仕事組織の仕組みがあげられます。**
詳細は「**SES**」と調べてほしいのですが、必要な時に必要な人員(派遣のようなもの)を集めて、プロジェクトが完遂すると解散するという形態です。
これにより、システム制作などを受注する元請の企業は必要最低限の人員コストで済み、そこに人員を送り込む企業が数多く存在します。
未経験である私たちはその送り込まれる人員になる可能性が高いです。

# なぜインフラエンジニアになったか
自分に合っていると感じたからです。
2019年下旬のインフラエンジニア就職の状況
・**仕事があふれていて、売り手市場である**(コロナで状況は変わりました)
　　働く側に選択肢があり、ブラックな職場は淘汰されつつありました。
・**未経験でも比較的受け入れてくれる企業が多かった**
　　上記の理由もあり人手不足だったため業務未経験でも受け入れがありました。
・**ガツガツした雰囲気がなく緩く働けそうだった**
　　アプリ開発などの対比になりますが、落ち着いた雰囲気がありました。
・**高給ではないが残業時間が短い場合が多い**
　　残業なしが自分が求めていた最大の条件でした。

# インフラエンジニアのなり方
今回は当然未経験からというのを前提に考えていきます。
そのため、上記の「SES」と呼ばれる形態の企業に就職する想定です。
SIerやベンダーは就職難易度が高いため、新卒やある程度の経験、ポテンシャルがないと厳しいです。
私はSES企業には比較的簡単に就職できると考えていますが、条件が二つあります。
・**四大卒以上であること**
・**二十代であること**
とくに後者の二十代であるというのは恐らく未経験でインフラエンジニアになるための一番有利な条件です。
SES企業は年齢を選考基準に設けている企業が多く、20代限定で求人を出しているのも珍しくないです。
経験者であればスキルが選考基準ですが、未経験であればやる気と年齢が選考基準になる場合が多いようです。
あとは面接で学習意欲があるようにアピールできれば採用される確率は高まると思います。

# 選んではいけないと感じた会社
就職活動の中で、ここを選んだら危なさそうだと感じたものを紹介します。
・**研修がない、アピールポイントにしていない**
　　これは社員を育てる気はない、もしくは即戦力しか求めていないということです。
　　未経験者には誰でも参画できる安価な案件のみ紹介をするので、スキルや給料は上がりません。

・**みなし残業が長い**
　　みなし残業はある程度諦めるしかないです。
　　しかしそれが30～40時間というのはあまりにも危険だと思います。
　　せめて20時間以内を選びましょう。

・**ネットの退職者からの評判が悪すぎる**
　　仕事や体制への不満が多く並べられている会社は危険度が高いと思います。
　　エンジニアを大切にしない企業は待遇が悪く、スキルを伸ばす機会も与えられない可能性があります。

# まとめ
長々と書いてしまいましたが、どれも調べればすぐに出てくるような内容ですみませんでした。
ただ、インフラエンジニアはSESという働き方を中心に構成されているため、どうしてもネガティブな紹介をされていると感じています。
確かに向上心がかなり高い方にとっては魅力的な選択肢ではないかもしれません。
給料はIT業界の中では低いほうですし、ボーナスなし、退職金なし、みなし残業など珍しくありません。
しかし、私のように労働時間はなるべく短く、仕事に対しては緩く向き合いたい人にとっては天職だと思います。
また、自分と相性の良いサービス、役割を見つけることができれば、エンジニアとして安定します。
もちろん安易に就職先を選ぶと酷い環境かもしれないですが、しっかり吟味すれば回避することも十分可能です。
インフラエンジニアを志す誰かの参考になれば幸いです。
Rails API

# はじめに
RailsのAPIモードを利用してAPIを作成する手順をまとめました。

# 手順
1.　APIモードでRailsアプリの作成
2.　モデル・コントローラの作成
3.　名前空間を意識したルーティングの設定
4.　コントローラの設定
5.　ブラウザで確認

# APIモードでRailsアプリ作成
```
$ rails new api-task --api
```
通常のrails newコマンドの末尾に--apiをつけることでAPIモードでアプリを作成することができます。
(APIに必要ない部分をデフォルトで作成しなくなります。)

# モデル・コントローラーの作成
通常のRailsアプリ同様モデルとコントローラを作成します。

```
rails g model category name:string
rails g model idea category_id:bigint body:text
$ rails db:create
$ rake db:migrate
```
#名前空間を意識したルーティングの設定
最初から以下の様にバージョンで名前空間を作成しておくことで今後のAPIのバージョン管理が容易になります。

```config/routes.rb
Rails.application.routes.draw do
  namespace 'api' do
    namespace 'v1' do
      resources :posts
    end
  end
end
```
##コントローラーの設定
ルートで設定した名前空間に合わせてディレクトリの構成は以下のようになります。

```
---- controllers

      --- api

        -- v1

         - ideas_controller.rb
         - categories_controller.rb
```

![スクリーンショット 2020-11-10 20.29.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752006/84e6cf34-b75e-7c66-c39d-39c8b595c7a1.png)


```
class IdeasController < ApplicationController
  def index
    @ideas = Idea.all

     render json: @ideas
  end

  def create
     @idea = Idea.new(idea_params)

    if @idea.save
      render json: @idea, status: :created, location: @idea
    else
      render json: @idea.errors, status: :unprocessable_entity
    end
  end


  private

  def idea_params
    params.require(:idea).permit(:catagory_id,:body)
  end
end

```
```
class CategoriesController < ApplicationController
  def index
  end

  def create
    @category = Category.new(idea_params)

    if @category.save
      render json: @category, status: :created, location: @category
    else
      render json: @category.errors, status: :unprocessable_entity
    end
  end

  private

  def category_params
    params.require(:category).permit(:name)
  end
end
```
## ブラウザで確認
Ideaをいくつか作成してブラウザで確認
Get(http://localhost:3000/api/v1/ideas)

![スクリーンショット 2020-11-12 11.03.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752006/2782a397-2c51-035d-fbd6-fdcbbd4393e8.png)



上記のように表示されればOK！!
【Visual Studio Code】編集画面を分割したときに便利な機能

#画面分割時の便利機能
画面分割時に編集したいファイルの画面領域を大きくする場合、そのファイル名をダブルクリックで大きくなります。
元に戻すときは、同じファイル名をもう一度ダブルクリックします。

![vscode.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854121/5bc06bfe-db99-41a6-4ee7-e62cf7268dc6.gif)
【入門者向け】Canvas入門講座#6 五角形を塗りつぶそう【JavaScript】

#問題6
点(100, 100)、(300, 200)、(250, 250)、(170, 280)、(50,150)を結ぶ五角形を塗りつぶしなさい。
塗りつぶす色は緑色(#00ff00)であること。
なお、以下のHTMLを使うこと。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>問題6</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => {
    // ここにプログラムを書く
});
</script>
</head>
<body>
<canvas id="my-canvas" width="500" height="300"></canvas>
</body>
</html>
```

#答え

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>問題6</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => {
    // コンテキストを取得
    const ctx = $('#my-canvas')[0].getContext('2d');

    // 塗りつぶしの色を緑色にする
    ctx.fillStyle = '#00ff00';

    ctx.beginPath();        // 現在のパスをリセットする
    ctx.moveTo(100, 100);   // パスの開始座標を指定する
    ctx.lineTo(300, 200);   // 座標を指定してラインを引く
    ctx.lineTo(250, 250);   // 座標を指定してラインを引く
    ctx.lineTo(170, 280);   // 座標を指定してラインを引く
    ctx.lineTo(50, 150);    // 座標を指定してラインを引く
    ctx.closePath();        // パスを閉じる
    ctx.fill();           // 現在のパスを塗りつぶす
});
</script>
</head>
<body>
<canvas id="my-canvas" width="500" height="300"></canvas>
</body>
</html>
```

五角形が緑色で塗りつぶせました!
![ダウンロード (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/1712a71c-dea7-6aa9-b3f2-2b683cae328c.png)

#解説
コンテキストを取得します。これは問題1と同じです。

```js
// コンテキストを取得
const ctx = $('#my-canvas')[0].getContext('2d');
```

次に線の色と太さを指定します。
塗りつぶしの色は<b>fillStyle</b>で指定します。

```js
// 塗りつぶしの色を緑色にする
ctx.strokeStyle = '#00ff00';
```

後はパスを作成し、最後にfillを呼びます。

```js
ctx.beginPath();        // 現在のパスをリセットする
ctx.moveTo(100, 100);   // パスの開始座標を指定する
ctx.lineTo(300, 200);   // 座標を指定してラインを引く
ctx.lineTo(250, 250);   // 座標を指定してラインを引く
ctx.lineTo(170, 280);   // 座標を指定してラインを引く
ctx.lineTo(50, 150);    // 座標を指定してラインを引く
ctx.closePath();        // パスを閉じる
ctx.fill();           // 現在のパスを塗りつぶす
```
【Ansible】1.Ansibleのインストール

##はじめに
AnsibleはOSの設定や構成管理を自動化するオープンソースのツールです。
主にLinuxで利用されていますが、モジュールを追加することによりWindows、vSphere
さらには、パブリッククラウド環境でも利用することが出来ます。
##インストールの準備
ますは、Ansibleをインストールしてみましょう。
管理する側を**コントロールノード**と言い、CentOSやRedhatなどの主要なLinuxディストリビューションにインストールすることが出来ます。
今回は下記のOSをコントロールノードとして利用しています。

```
[root@centos8 ~]# cat /etc/redhat-release
CentOS Linux release 8.2.2004 (Core)
```

python、モジュール管理ツールpipをインストールしておきます。

```
[root@centos8 ~]# dnf install python38 -y
[root@centos8 ~]# cat << EOS >> .bash_profile
> alias python=python3
> EOS
[root@centos8 ~]# source .bash_profile
[root@centos8 ~]# python --version
Python 3.8.0
[root@centos8 ~]# curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
[root@centos8 ~]# python get-pip.py --user
[root@centos8 ~]# cp /root/.local/bin/pip /usr/local/bin
```
##インストール
ansibleのインストールには下記の方法があります。

+ パッケージマネージャから
+ pipから
+ ソースコードから

今回はパッケージマネージャからインストールします。
インストールにあたりEPEL(Extra Package Enterprise Linux)を有効にします。

```
[root@centos8 ~]# dnf install epel-release -y
[root@centos8 ~]# dnf install ansible -y
[root@centos8 ~]# ansible --version
ansible 2.9.15
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Apr 16 2020, 01:36:27) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
```

##インストールの確認
Hello worldを出力する簡単なplaybookを作成し、動作確認とします。

```
[root@centos8 ~]# mkdir ansible
[root@centos8 ~]# cd ansible/
[root@centos8 ansible]# cat inventory
[target]
localhost
[root@centos8 ansible]# cat main.yaml
- hosts: target
  gather_facts: no
  tasks:
    - name: Test ansible-playbook
      debug: msg="Hello world"
[root@centos8 ansible]# ansible-playbook -i inventory main.yaml

PLAY [target] **************************************************************************************

TASK [Test ansible-playbook] ***********************************************************************
ok: [localhost] => {
    "msg": "Hello world"
}

PLAY RECAP *****************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```
【入門者向け】Canvas入門講座#5 五角形を描こう【JavaScript】

#問題5
点(100, 100)、(300, 200)、(250, 250)、(170, 280)、(50,150)を結ぶ五角形を線分で描画しなさい。
線分は赤色(#ff0000)で太さが5であること。
なお、以下のHTMLを使うこと。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>問題5</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => {
    // ここにプログラムを書く
});
</script>
</head>
<body>
<canvas id="my-canvas" width="500" height="300"></canvas>
</body>
</html>
```

#答え

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>問題5</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => {
    // コンテキストを取得
    const ctx = $('#my-canvas')[0].getContext('2d');

    // 線の色を赤色にする
    ctx.strokeStyle = '#ff0000';
    // 線の太さを5にする
    ctx.lineWidth = 5;

    ctx.beginPath();        // 現在のパスをリセットする
    ctx.moveTo(100, 100);   // パスの開始座標を指定する
    ctx.lineTo(300, 200);   // 座標を指定してラインを引く
    ctx.lineTo(250, 250);   // 座標を指定してラインを引く
    ctx.lineTo(170, 280);   // 座標を指定してラインを引く
    ctx.lineTo(50, 150);    // 座標を指定してラインを引く
    ctx.closePath();        // パスを閉じる
    ctx.stroke();           // 現在のパスを描画する
});
</script>
</head>
<body>
<canvas id="my-canvas" width="500" height="300"></canvas>
</body>
</html>
```

五角形が描画できました。
![ダウンロード (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/7ad86ed2-f319-a407-4c32-7c7130a69b8b.png)

#解説
コンテキストを取得します。これは問題1と同じです。

```js
// コンテキストを取得
const ctx = $('#my-canvas')[0].getContext('2d');
```

次に線の色と太さを指定します。
線の色は<b>strokeStyle</b>で指定します。
線の太さは<b>lineWidth</b>で指定します。

```js
// 線の色を赤色にする
ctx.strokeStyle = '#ff0000';
// 線の太さを5にする
ctx.lineWidth = 5;
```

後はパスを作成し、最後にstrokeを呼びます。

```js
ctx.beginPath();        // 現在のパスをリセットする
ctx.moveTo(100, 100);   // パスの開始座標を指定する
ctx.lineTo(300, 200);   // 座標を指定してラインを引く
ctx.lineTo(250, 250);   // 座標を指定してラインを引く
ctx.lineTo(170, 280);   // 座標を指定してラインを引く
ctx.lineTo(50, 150);    // 座標を指定してラインを引く
ctx.closePath();        // パスを閉じる
ctx.stroke();           // 現在のパスを描画する
```
【Java】マルチスレッド処理


##結論
* プロセスとスレッドの違いは重要
* マルチスレッドの意義は**独立に動かし、かつ同じプロセス内のメモリ空間を共有する**ことができること

##スレッドとは
* プログラムを**実行する処理の最小単位**
* アプリは**メインスレッド**という単一スレッドで動く
* しかし**単一スレッド**では、ネットワーク通信時などで、アプリ利用者は次の操作を通信終了まで待たないといけなくなる
* スレッドが複数ある（=**マルチスレッド**）と、<br>ネットワーク通信はバックグラウンドで他のスレッドが実行し、**通信中でもメインスレッドで処理を並行して実行することができる**


##プロセスとは
* **プログラムのインスタンスそのもの**
* 新**プロセス起動にはCPUとメモリの割り当てが必要**
* プロセスは**1つ以上のスレッドを持つ**
    * 1対1..n（1以上のn）関係
* UML表記では、プロセス側から見てスレッドは 1…n 個

　プロセス　1
　　　|
  　スレッド　1..n


##メモリ構成
* **プロセス**：Main関数で動いているプログラム
* プロセスという大きい箱のなかに**スレッド**がある
    * Main関数は1スレッドでうごいている
    * あるプロセスは1個以上のスレッドを持たないといけない（**mainスレッド**）
    

![1111_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282755/cb391a10-a1ae-2f6e-a9c4-3eb7deac0a0b.png)


##スレッドの特徴 - 独立・メモリ空間共有
* スレッド同士は**お互い独立**して動く
    * 1個止まってもバックグラウンドで動くスレッドは独立して稼働
    * メインスレッドで通信処理をしていると通信して答えが返ってくる間止まってしまうので、 その間も処理させるために並列処理させる
* マルチスレッドで3スレッド立ち上げたときに1プロセス内にある理由は**メモリ空間を共有するため**
    * Mainスレッド内に変数を定義したら**全スレッドがアクセスできる**


```java
public class Main {
    String hoge = "hoge"; //この変数は共有される
    public static void main(String[] args) {
        new Main().run();
    }
    private void run(){
        while (true) {
            System.out.println("1"); //Mainスレッド
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("2");
        }
    }
}
```

##スレッド生成・実行
* Threadクラスを継承
* Runnableインターフェース実装

###Threadクラスを継承
* Thread派生クラスでは**絶対runメソッド（呼び出すエンドポイント）をオーバーライド**する
* Thread派生クラスのメソッド
    * **currentThread**：実行中スレッド取得
    * **getId**：スレッドID取得
    * **isAlive**：スレッド生存確認
    * **join**：スレッド終了するまでms待機
    * **setPriority**：優先順位設定
    * **sleep**：スレッド実行休止

```java
public class MyThread extends Thread {
//スレッド実処理はThread派生クラス
  @Override
  public void run() {
    for (var i = 0; i < 30; i++) {
      //getNameでスレッド名取得
      System.out.println(this.getName() + ": " + i);
    }
  }
}
```

```java
public class ThreadBasic {

  public static void main(String[] args) {
    //インスタンス化しスレッド生成
    var th1 = new MyThread();
    var th2 = new MyThread();
    var th3 = new MyThread();
    //startメソッドでスレッド開始
    th1.start();
    th2.start();
    th3.start();
  }
}
```

###Runnableインターフェース実装
* 継承ではなく**実装**（implements Runnable）
    * 関数型インターフェースである
* スレッド名に直接アクセスできないので`Thread.currentThread()`静的メソッドで現スレッドを取得し、getNameメソッドにアクセス
* インスタンス化にはThreadコンストラクターにRunnable実装クラスのインスタンスを渡す


```java
public class MyRunner implements Runnable {
  //スレッド実処理
  @Override
  public void run() {
    for (var i = 0; i < 30; i++) {
      System.out.println(Thread.currentThread().getName() + ": " + i);
    }
  }
}
```
```java
public class RunnableBasic {

  public static void main(String[] args) {
    //スレッド生成
    var th1 = new Thread(new MyRunner());
    var th2 = new Thread(new MyRunner());
    var th3 = new Thread(new MyRunner());
    //スレッド開始
    th1.start();
    th2.start();
    th3.start();
  }
}
```
fastlaneでホワイトスペース(空白)を含んだパスを指定する


# 結論

`\\ `でok

# 書いてあること

- CircleCIのconfigをfastlaneのFastfileに移行する方法
- その際、ホワイトスペースを含む記述のエスケープシーケンス

# 使い所

fastlaneでホワイトスペース (空白) を扱うのに苦労しました。

ここでは、CircleCIで以下のように記述していたものを、fastlaneのFastfileに移動したときに発生。

```sh
# .circleci/config
- run:
  command: |
    rm ~/Library/MobileDevice/Provisioning\ Profiles/*
```

CircleCIだとPathにホワイトスペースがあっても上記のように記述できます。
ホワイトスペースのエスケープシーケンスは`\ + WhiteSpace`だと想定。


そもそもFastfileでコマンドを実行したい要望が今まで無かった…

どうやらshコマンドを使う模様
https://docs.fastlane.tools/actions/sh/

# 失敗談

記述のサンプル見ると以下のように記載されています。

```sh
sh("git", "commit", "-m", "My message")
```

そこで、以下のように書いて試していましたが、これではホワイトスペースが扱えないようでした。

```sh
# fastlane/Fastfile

# Example of failures
sh("rm", "~/Library/MobileDevice/Provisioning Profiles/*")
sh("rm", "~/Library/MobileDevice/Provisioning\ Profiles/*")
sh("rm", "~/Library/MobileDevice/Provisioning\\ Profiles/*")
```

# 成功

セパレートせずまとめて書くことで期待動作しました。

```sh
# fastlane/Fastfile
sh("rm ~/Library/MobileDevice/Provisioning\\ Profiles/*")
```
http://localhost:3000/ に自分の表示したいページを設定する（routes.rb を編集して）

**http://localhost:3000/ で自分が表示したいページを設定するには**


```config/routes.rb
root to: 'コントローラ名#アクション名'
```


例えばブログコントローラの一覧を表示したかったら


```config/routes.rb
root to: 'blogs#index'
```

とすれば良い！


* * *

こちらの記事を参考にさせていただきました！
https://qiita.com/higu1988/items/0287fffe5ee54d325919

* * *


プログラミング初学者です。間違いがありましたらお教え頂けるとありがたいです:robot:
3分アジャイル XPでの設計

- インクリメンタルな設計
- 熟考した設計は不要ではないか？
- 状況に応じて素早い設計（すぐに取り掛かる）を判断する

---
## 設計と重複
- 重複をまとめて改善
- 重複は悪
- リファクタリング

---
## DBマイグレーション

- 空のデータベースから始める。
- 自動スクリプトでテーブルやカラムを追加する。
- 必要に応じて既存のデータを移行する。
- スクリプトには連番をつけておく。スクリプトを実行することにより、後期のデータベースに追従することができる。

---
## 設計の決定時期
- 設計の決定をずらす
- 設計がなくても進めることがあるのではないか
- 熟考した設計が必要な場面ではないか


---
## デイリー

- 開発チームがスプリントゴールを達成するために、私が昨日やったことは何か？
- 開発チームがスプリントゴールを達成するために、私が今日やることは何か？
- 私や開発チームがスプリントゴールを達成する上で、障害となる物を目撃したか？

---

## 出典

第14章設計：時間の重要性

ＫｅｎｔＢｅｃｋ,ＣｙｎｔｈｉａＡｎｄｒｅｓ. エクストリームプログラミング (Japanese Edition) (Kindle Locations 2242-2243). Kindle Edition.
データのインポート関係

データのインポートについて、ヘルプがあったので忘れないようにまとめておきます。


・[メモおよび添付ファイルのインポート](https://help.salesforce.com/articleView?id=000321698&type=1&mode=1)
・[データローダを使用して ContentNote オブジェクトにメモをインポート](https://help.salesforce.com/articleView?id=000339316&type=1&mode=1)
・[メモの所有者を更新する(英文)](https://help.salesforce.com/articleView?id=000313695&type=1&mode=1)


個人的にはBulk APIに向けてシェルを走らせる方法を取っていますが、オブジェクト毎に注意するポイントがあるので
気が付いたらまとめていきたいと思います。何度も繰り返せるようにupsertがお勧めです。


データのインポート作業は
1.何かしらの元データを用意する(Excel,csv,固定長テキストなど）
2.目的のオブジェクトに合わせて加工する。
3.文字コードをUTF-8に変換する(特にWindowsで作ったcsvファイルは要注意です）
4.Bulk APIを使ってインポートする。(実際はupsert）

という流れだと思いますが、シェルで行えば1～4のステップを同じ環境で行えるし
自動かもできます。特に文字コードの変換はコマンドが用意されているLinux(Unix)が便利です。
xlsxファイルもPythonに便利なライブラリopenpyxlがあるので対応できます。
初心者でも無料でSplatoon2の戦績をstat.inkに定期投稿できるdisocrd bot


## はじめに

PC初心者でも、スマホしかない人でも、**stat.inkにSplatoonの戦績を自動アップロードするdiscord bot**を作れるようにしたいなというのが、基本的な考えです。

**とりあえず無料でstat.inkに戦績を投稿するDiscord Botを作りたい・使いたいという人は、準備方法や使い方については[GitHub Repository](https://github.com/TomoTom0/DiscordBot_Heroku_Stat.ink)のREADMEに詳しく書いたので、そちらをご確認ください。**

この記事ではHerokuで稼働するDiscord Botについて工夫した点をお話します。

### 作成するdiscord botの機能

- `splatnet2stat.py`を利用してstat.inkに複数アカウントの戦績を自動アップロードする。
- discord botを起動後に**botの機能だけでiksm_sessionの取得(自動アップロードの準備)ができる**
- bot起動準備を含めて**スマホだけですべての作業が完結**できる (PCを使える方が便利とはいえ)

## 問題点と解決策

Herokuではファイル作成・書き込みに制限があります。

- 一時ファイル作成用の`/tmp`にしかファイルを作成できない。(※もともとのファイルは`/app`以下に入っている。)
    - さらに`/tmp`の中も一定時間(最大24時間)ごとにリセットされる。
- つまり**Bot起動後に生成されるファイルを継続的に保存できる場所はない**。

これに付随する問題は2点あります。
### iksm_sessionの保存場所
> discord botを起動後に**botの機能だけでiksm_sessionの取得(自動アップロードの準備)ができる**

上の機能の仕様上、iksm_session(厳密にはconfig.txtの中身)はbotをherokuで実行した後に取得されます。
それらのデータを永遠に保存しておくために、今回はHerokuの環境変数を利用しました。

Herokuの環境変数はHeroku管理画面から設定できますが、HerokuのREST APIからも更新できます。つまり**Herokuで実行されているBot内から環境変数に出力し、データを継続的に保存することが可能**です。
-> 詳しくは[Platform API Reference #config-vars-update](https://devcenter.heroku.com/articles/platform-api-reference#config-vars-update)

```Python
app_name=os.getenv("HEROKU_APP_NAME", "app-splat") #HEROKU_APP_NAME
if app_name=="":
    print("環境変数のHEROKU_APP_NAMEが定義されていません。")
    return
patch_url = f"https://api.heroku.com/apps/{app_name}/config-vars"
headers= {"Authorization": f"Bearer {os.getenv('HEROKU_APIKEY')}",
    "Content-Type":"application/json",
    "Accept":"application/vnd.heroku+json; version=3"}
res=requests.patch(patch_url, headers=headers, json=new_envs)
```

環境変数更新後にdynoは一度再起動されます。
また、注意点として**Herokuの環境変数は合計で32KBまで**しか利用できません。

### 戦績アップロード実行時のconfig.txtの位置

`splatnet2statink.py`はiksm_sessionなどが記されたconfig.txtが同じディレクトリに置かれていることを想定されています。
そのままですが、`config_path`を書き換えます。

なお、localでの実験も想定して、環境変数はHerokuでデフォルトで設定される`os.getenv("DYNO")`の有無で使い分けます。

```Python:splatnet2statink
## splatnet2statink/iksm.py
config_path="/tmp/config.txt" if os.getenv("DYNO", False) else f"{os.path.dirname(__file__)}/../tmp/config.txt"
## splatnet2statink/splatnet2statink.py
config_path=iksm.config_path
```



他の問題点として以下があります。
### なぜかjson.loads()がstringになる
これは別記事に書きました。-> [HerokuでPythonのjson.loads()がstrを返す問題](https://qiita.com/Tom0/items/9a24d190e02f9154c6dd)
stringにならない場合もあるので、今はtypeの判別を挟んでいます。

```Python:Heroku
loaded_tmp=json.loads(dumped_string)
loaded_dict=eval(loaded_tmp) if (loaded_tmp)==str else loaded_tmp
```

## GitHub Repository
- GitHub Repository: [DiscordBot_Heroku_Stat.ink](https://github.com/TomoTom0/DiscordBot_Heroku_Stat.ink)
【入門者向け】Canvas入門講座#4 三角形を塗りつぶそう【JavaScript】

#問題4
点(100,100)と点(300,200)を点(50,150)結ぶ三角形を塗りつぶしなさい。
なお、以下のHTMLを使うこと。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>問題4</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => {
    // ここにプログラムを書く
});
</script>
</head>
<body>
<canvas id="my-canvas" width="500" height="300"></canvas>
</body>
</html>
```

#答え

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>問題4</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$(() => {
	// コンテキストを取得
    const ctx = $('#my-canvas')[0].getContext('2d');

    ctx.beginPath();		// 現在のパスをリセットする
	ctx.moveTo(100, 100);	// パスの開始座標を指定する
	ctx.lineTo(300, 200);	// 座標を指定してラインを引く
	ctx.lineTo(50, 150);	// 座標を指定してラインを引く
	ctx.closePath();		// パスを閉じる
	ctx.fill();           // 現在のパスを塗りつぶす
});
</script>
</head>
<body>
<canvas id="my-canvas" width="500" height="300"></canvas>
</body>
</html>
```

三角形が塗りつぶせました！
![ダウンロード (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163605/09723869-9605-f7e7-1b3e-769aa9cda522.png)


#解説
コンテキストを取得します。これは問題1と同じです。

```js
const ctx = $('#my-canvas')[0].getContext('2d');
```

問題3と異なり、最後に<b>fillを呼んで塗りつぶしています。

```js
ctx.beginPath();        // 現在のパスをリセットする
ctx.moveTo(100, 100);   // パスの開始座標を指定する
ctx.lineTo(300, 200);   // 座標を指定してラインを引く
ctx.lineTo(50, 150);    // 座標を指定してラインを引く
ctx.closePath();        // パスを閉じる
ctx.fill();           // 現在のパスを塗りつぶす
```
2020年になってNexus 6Pに古いAndroidバージョンのFactory Imageを焼こうとしたら妙に苦戦したのでメモを残す

# 経緯
- Unity 2018.4.27f1＋特定SoC＋Android 8.0未満でsubmeshのBlendShapeが正常に動かない問題が出た
- 動かないならまだいいが、おかしな値が入って画が崩れる（泣）
- SoCは今のところ Snapdragon 430, 617, 810が該当してそう
- Unity 2018.2.20f1では出てなかった
- 原因はわかっていない
- 本件はバグに関連して、Snapdragon 810搭載のNexus 6PをAndroid 8.0未満にすべく、古いイメージを焼こうとした
- 妙に苦戦したのでメモを残しておく

# 手順
## 1. Factory Imageのzipをダウンロードする
Factory Images for Nexus and Pixel Devices
https://developers.google.com/android/images

## 2. 手順通りだとエラーになる
```
archive does not contain 'boot.sig'
fastboot: error: Couldn't parse partition size '0x'.
```
- boot.sigがないのはzipを展開して直接fastboot flashすると回避できる模様
- 参考：https://qiita.com/ytabuchi/items/28d66b7e69146086fe13
- partitionが見つからないのは `flash：raw` という生焼き（？）コマンドで回避できる模様
- 参考：https://forum.xda-developers.com/nexus-6p/help/getting-fastboot-error-parse-partition-t4156777

## 3. flash-all.shを以下のように書き換えて実行する

- 中に入ってるzipもフラットに展開する
- vendor.imgがあるのでそっちを焼くコマンドも足す
- boot.imgはflashではなくてflash:rawにする
- bootloaderやradioのバージョンはダウンロードしたFactory Imageによって違うので適宜差し替えて読むこと

```
fastboot flash bootloader bootloader-angler-angler-03.62.img
fastboot reboot-bootloader
sleep 5
fastboot flash radio radio-angler-angler-03.78.img
fastboot reboot-bootloader
sleep 5
# fastboot -w update image-angler-nmf26f.zip
fastboot flash vendor vendor.img
fastboot reboot-bootloader
sleep 5

fastboot flash recovery recovery.img
fastboot flash:raw boot boot.img
fastboot flash system system.img
fastboot flash cache cache.img
fastboot flash userdata userdata.img
fastboot reboot
```
引数の概念がわからないので自分なりに噛み砕いてみた。

関数を作成するとき「引数」を使うがどうしても私はその概念が理解できない。

なので今回、引数の概念をしっかりと理解するようにしてみた。

#引数とは

関数は入力をすると、出力（戻り値という）される。

引数とはその一連の流れの中で「入力」に相当するものである。

例）関数＝人　　　引数＝食べ物　　戻り値＝排泄
　人が食べ物を食べると排泄をする。

一連の流れとしてはこのようなものになる。

#実際のコードで引数を見てみる

```
public function test($people){
   return ($people);
}

echo test('鈴木くん');

```
とすると　　出力結果は　鈴木くんが出るということになる。
オンプレミスADからAzureActiveDirectoryへの同期を強制的に実行する

## 強制同期

```Powershell
Start-ADSyncSyncCycle
```

## 同期確認

```

PS C:\Users\testadmin> Get-ADSyncScheduler


AllowedSyncCycleInterval            : 00:30:00
CurrentlyEffectiveSyncCycleInterval : 00:30:00
CustomizedSyncCycleInterval         :
NextSyncCyclePolicyType             : Delta
NextSyncCycleStartTimeInUTC         : 11/12/2020 1:32:11 AM
PurgeRunHistoryInterval             : 7.00:00:00
SyncCycleEnabled                    : True
MaintenanceEnabled                  : True
StagingModeEnabled                  : False
SchedulerSuspended                  : False
SyncCycleInProgress                 : False

````
JSONの比較

Model層のCodableなどのテストコードを書いていて期待値のJSON文字列を比較したい場合がある。
しかし、JSONなどKeyValue形式のフォーマットは順不同で単純に文字列比較することができない。

そこで思いついたのがDictionary型にして比較する方法。

```Swift
extension String {
    func jsonDictionary() throws -> [String: AnyHashable]? {
        guard let data = self.data(using: .utf8) else { return nil }
        return try data.jsonDictionary()
    }
}

extension Data {
    func jsonDictionary() throws -> [String: AnyHashable]? {
        return try JSONSerialization.jsonObject(with: self, options: []) as? [String: AnyHashable]
    }
}
```

Dataのextensionとして `JSONSerialization.jsonObject` した結果を返すfuncを用意しておき、Stringのextensionでもそれを通すfuncを追加しておくと例えば以下のようなテストコードでもXCTAssertEqualで評価することができる。

```Swift
    func test_HogeEncode() {
        let object = Hoge(value: 123, flag: true)
        let expectation = """
            {
                "value": "123",
                "flag": "true"
            }
        """
        let data = try? JSONEncoder().encode(object)
        XCTAssertNotNil(data)
        
        XCTAssertEqual(try? expectation.jsonDictionary(), try? data!.jsonDictionary())
    }
```