OmniAICreator/Qiita-1.07M huggingface dataset:
【DroidScript】スマホでスマホアプリを作る④ 実行ボタン

##あらすじ
DroidScriptというアプリを使うと、javascriptベースの記述でスマホアプリが作れるらしいので、練習として「電子レンジワット数で加熱時間を換算するアプリ」を作る。

##前回までのおさらい
スピンボタンとシークバーを実装し、計算に必要なデータ入力が揃った。あとは計算するだけ。
![Screenshot_20201121-154732.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708687/2fec0fe1-b3cd-dbfd-78cf-9f2f7971bf97.png)

[スマホでスマホアプリを作る① Hello World!](https://qiita.com/YasumiYasumi/items/10796071033a9cefc0b4)
[スマホでスマホアプリを作る② 背景やテキストの追加](https://qiita.com/YasumiYasumi/items/1569dcc891217a2c92d7)
[スマホでスマホアプリを作る③ スピンボタンとシークバー](https://qiita.com/YasumiYasumi/items/867000c0f6f188551fb7)

##ボタンの設置
```javascript
btn = app.CreateButton( "EXECUTE", 0.4 ); 
btn.SetMargins( 0, 0.05, 0, 0 ); 
btn.SetOnTouch( btn_OnTouch ); 
lay.AddChild( btn );
```

`app.CreateButton`でボタンを作成。括弧内でボタンに表示する文字と、画面幅に対するサイズを設定。`.SetMargins`で直前に設置したシークバーとの間隔を設定。`.SetOnTouch`でタップしたときに呼び出す関数`btn_OnTouch`を設定している。

呼び出す関数のコードがコチラ。

```javascript
function btn_OnTouch() 
{ 
  var my_wave = my.GetText(); 
  var label_wave = label.GetText(); 
  var time = skb.GetValue(); 

  time = Math.round( time * 0.2 ) / 0.2; 

  var ratio = ( label_wave / my_wave ); 
  var after = time * ratio; 

  var remain = after % 60; 
  var newmin = ( after - remain ) / 60; 
  var newsec = Math.round( remain ); 
  newsec = ( "0" + newsec ).slice( -2 ); 
 
  var ans = newmin + ":" + newsec; 
 
  app.ShowPopup( "Heat for " + ans ); 
  app.Vibrate( "0,100,30,100,50,300" ); 
}
```

ついに自分のレンジでの加熱時間を計算。

スピンボタンやシークバーで操作した数字をどうやって拾ってくるのか分からなかったけど、操作後の状態から単純に参照できた。

スピンボタンで選んだ選択肢は`.GetText()`、シークバーで合わせた数字は`.GetValue()`で参照。

シークバーを操作した時に表示されるのが５秒間隔なので、計算するためにシークバーから参照した数字も５刻みに丸める。

あとはワット数の比で加熱時間を換算し、m:ss表示に加工して`"Heat for " + ans`でポップアップ、仕上げに`app.Vivrate`でスマホを振動させ達成感を味わう。
![20201121_181900.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708687/3c969b7d-36f6-dd35-7478-827b8d6cc2ad.gif)
##補足
スピンボタンの選択肢を`.GetText`で参照しているので、受け取った数字が文字列になっていると考えて、数字型に変更するために`Number()`メソッドを使ったところエラーになってしまった。

結局、そんなことしなくてもそのまま計算できてしまうみたい^^)b

##次回
アプリ作成はこれにて終了。

次回はシリーズ目次的なまとめと、コード全文、DroidScriptのちょっとした使い方を紹介。
[スマホでスマホアプリを作る シリーズまとめ](https://qiita.com/YasumiYasumi/items/832ec009681310ecdd1c)

###つづく

##シリーズ
DroidScript電子レンジアプリ作成
[スマホでスマホアプリを作る① Hello World!](https://qiita.com/YasumiYasumi/items/10796071033a9cefc0b4)
[スマホでスマホアプリを作る② 背景やテキストの追加](https://qiita.com/YasumiYasumi/items/1569dcc891217a2c92d7)
[スマホでスマホアプリを作る③ スピンボタンとシークバー](https://qiita.com/YasumiYasumi/items/867000c0f6f188551fb7)
[スマホでスマホアプリを作る④ 実行ボタン](https://qiita.com/YasumiYasumi/items/2ae76ac5ec49e0bdb9e8)
[スマホでスマホアプリを作る シリーズまとめ](https://qiita.com/YasumiYasumi/items/832ec009681310ecdd1c)

外伝
[【GAS】電子レンジワット数で加熱時間を換算するwebアプリを作ってみた](https://qiita.com/YasumiYasumi/items/f618fcbbe8beed2db8a9)
phpUnitの練習をしたのでメモ

phpUnitの練習をしたのでメモしておく

**書いているテストは全てGreen**

## 数値関連
```php
$answer = 1 + 1;
$this->assertIsInt($answer);
$this->assertIsNotFloat($answer);
$this->assertIsNumeric($answer);
$this->assertEquals($answer,2);
$this->assertNotEquals($answer, 100);
$this->assertGreaterThan($answer, 5);
$this->assertGreaterThanOrEqual($answer, 2);
$this->assertLessThan($answer, 1);
$this->assertLessThanOrEqual($answer, 2);

```

## boolean関連

```php
$this->assertIsBool(true);
$this->assertIsBool(false);
$this->assertTrue(true);
$this->assertFalse(false);
```

## Null関連
```php
$this->assertNull(null);
$this->assertNotNull(!null);
```

## 配列関連

```php
$users = ['konan', 'sherry', 'ran', 'jin'];
$this->assertIsArray($users);
$this->assertCount(4, $users);
$this->assertNotCount(0, $users);
$this->assertContains('konan', $users);
$this->assertNotContains('kogoro', $users);
$this->assertNotEmpty($users);

$user = ['name' => 'konan', 'age' => 6];
$this->assertArrayHasKey('name', $user);

```

# まとめ
TDD頑張りたい
C++ の学習サイトを作りました

# はじめに

C++ って他の言語に比べると勉強しづらくないですか？

書籍や学習サイトの内容が古い、または少ないんですよね。ただでさえ言語仕様が複雑なのに、それを手助けする情報も少ないと初学者には辛いんじゃないかと思います。というか僕がそうでした。

そんなわけで、もう少し今風な学習サイトを作ろうと思って作成しました。

# ゼロから学ぶ C++

https://rinatz.github.io/cpp-book/

[![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315525/a62312ff-0752-2dd0-b0a2-8d8acbcf8f2f.png)](https://rinatz.github.io/cpp-book/)

ちゃんとスマホでも読めるようになっています。

C++11 をベースに作っているので、このサイトももはや古い方に入るかも知れませんが、C++20 が浸透してきたらアップデートしようと思います。

よかったらご活用下さい。

# ゼロから学ぶ Python（姉妹サイト）

『ゼロから学ぶ Python』というサイトも作成しています。あわせてご活用下さい。

https://rinatz.github.io/python-book/

# さいごに

上記のサイトはどちらも GitHub でソースコードを管理しています。
スターを付けてもらうと励みになります :relaxed:

- https://github.com/rinatz/cpp-book
- https://github.com/rinatz/python-book
コロナ渦で未経験から転職するためにyoutubeで調べたこと（自社開発系、受託開発系、SES,Sler系）

### 前提・実現したいこと

5ヶ月勉強したが、良い企業に廻り会える気がしない
未経験からエンジニアに転職したい

### 発生している問題


・自社開発系
・受託開発系
・SES,Sler

この3つの違いがよくわからない
未経験を受け入れてくれるのだろうか心配

### 自社開発系

メリット
・新しい言語を取り入れてサービスを開発する企業がある
・スーツを着なくて良い
・スタートアップ、給与があるが可能性がある

デメリット
・スタートアップ、解雇や倒産のリスクがある
・サービスが出来上がった会社だと古い言語を使っている場合もある
・納期前は深夜勤務があるかも

### 受託開発系

メリット
・言語が新しいものと古いもの両方試せる可能性がある
・いろんな自社開発系企業の受託をやりながら自社開発を行っている企業もある

デメリット
・自社に比べて給与が低い可能性がある

### SES,Sler
メリット
・未経験でも採用されやすい
・いろんな自社開発系企業で働ける

デメリット
・希望の案件を受けることが出来ず、プログラミングとは違う案件をやらないいけない企業がある
・下請けすぎると給与がなかなか上がらない企業がある

コロナ渦で自社企業に未経験者が受かる可能性1%と聞き焦ったので、
調べてみました。

この状況だと受託にいければラッキー


### 試したこと

Youtubeで調べた
順番:kentaさん、せいやさん、とだこうきさん（東京フリーランス）

### 補足情報（FW/ツールのバージョンなど）

仮でまとめてみたので、
またわかったことや追記して行きます。
【Rails・devise】複数モデルを管理する際の<<before_action>>

#はじめに
deviseを用いて一般の方とグループ（企業や団体等）で分けてログインを実装する上で、
ログインした人のみが閲覧できるbefore_actionの実装に手間取ってしまったので記録します！

#結果から
applicationコントローラーで
・グループの方がログインした場合　→　authenticate_any!が有効
・それ以外の人がログインした場合　→　authenticate_user!が有効

```ruby:application_controller.rb
class ApplicationController < ActionController::Base
  def authenticate_any!
    if group_signed_in?
        true
    else
        authenticate_user!
    end
  end
end
```

各コントローラーで必要なところで`before_action :authenticate_any!`を記載する
application_controller.rbに記載して全て制限したいのであれば
`before_action :authenticate_any!`の下で`authenticate_any!`を定義する

```ruby:posts_controller.rb
before_action :authenticate_any!
```

無事、ログインについてのRspecも通りました！

#ハマったこと
userまたはgroupがログインしている場合のみページにアクセスができるように実装したかったので、
左から順に評価し、最初に真になったものを返してくれる||を使用してみました。

```ruby:posts_controller.rb
before_action :authenticate_user! || :authenticate_group!
```

こうするとauthenticate_user!は反応するもののgroupが反応せず、
groupを作成できるもののroot_pathで`Completed 401 Unauthorized`とエラーが発生して、
弾き出されてuserのsign_inページにリダイレクトされてしまっていました。

`Completed 401 Unauthorized`でググるとCSRF トークンの不整合がでてくることが多かったので、
application_controller.rbに`protect_from_forgery with: :null_session`記載をして
対応したりもしましたが、ダメでした。。。
（これはCSDF 対策として弱くなるという意見もあるみたいなので、そもそも使わないほうがいいのかも・・・）

#学んだこと
before_actionで場合分けしたい場合は、メソッドを作成してその中で条件分けをする！

今までなんとなくbefore_actionを使用していましたが、勉強になりました！（かなり初歩的なのかとは思いますが笑）

同じようなことに困っている方のお役に立てたら嬉しいです。
データベースの種類

## データベースとは
整理された情報の集まり。蓄積、検索、更新ができる。
アドレス帳のようなもの。

## データベースの種類（5種）
### 階層型データベース
ヒエラルキー構造で管理するデータベース。組織図や樹形図。最も古い。

### リレーショナルデータベース
２次元表の形式。エクセルみたいな。

### オブジェクト指向データベース・XMLデータベース
オブジェクトとXMLという形式でデータを管理するデータベース。
XMLはHTMLに似た形の情報。

### NoSQLデータベース
SQL言語を使用しないデータベース。
リレーショナルデータベースの機能を一部捨てることで高速処理を可能にしている。
大量のデータ処理をするWebサービスと相性が良い。

## 参考文献
おうちで学べるデータベースのきほん。
Optional Chaining と Nullish Coalescing

# Optional Chaining と Nullish Coalescing

ES2020, TypeScript 3.7 から導入された記法。
node では 13系からオプション指定をすることで (--harmony)、14系からは標準で使用できるようになっている。

# 記法

| 項目 | 記法 |
|:-:|:-:|
| Optional Chaining  | `?.`  |
| Nullish Coalescing  | ??  |

# Optional Chaining

挙動: プロパティを取るチェーンの途中でエラーを出さず、最終的に取れればそれを、取れなければ `undefined` を返す

例えば以下のコードにおいて

```optionalChaining.js
const users = [
  {
    id: 1,
    name: 'sample user',
    career: {
      university: 'Hoge大',
    },
  },
  {
    id: 2,
    name: 'invalid user',
  },
]

users.forEach(user => console.log(user.name, user.career.university));
```

`users[1]` の `user.career.university` にアクセスしようとすると

```javascript
TypeError: Cannot read property 'university' of undefined
```

というエラーが起こる。
`user.career` までなら　`undefined` が帰ってくるが、`user.career.university` までアクセスしようとすると怒られる。
これを何重に行っても怒られず、そのチェーン先プロパティが存在しない場合に、常に `undefined` を返してくれるようにするのが Optional Chaining である。
最後の行の `.` を `?.` とするだけで、その挙動になる。

```optionalChaining.js
users.forEach(user => console.log(user.name, user?.career?.university));
// 実行結果
// sample user Hoge大
// invalid user undefined
```

# Nullish Coalescing

挙動: `null` か `undefined` の場合のみ右側を評価し、そうでない場合は左側の被演算子を返す

例えば以下のようなコードがあったとする。

```nullishCoalescing.js
const user = {
  id: 1,
  name: 'sample user',
  career: {
    university: 'Hoge大',
    high_school: null,
  },
}

console.log(user.career.high_school || '高校登録なし')
```

ただし、`||` は `falsy` な値すべてを `false` 扱いしてしまう。

```javascript
false
""
0
undefined
null
```

そうではなく、純粋に左側の被演算子が `null` (存在しないという意味) か `undefined` (定義されていない) の場合に、右側を評価したい場合 Nullish Coalescing が有効である。
そしてそれは先ほどのコードの `||` を `??` に書き換えるだけで完了する。

```nullishCoalescing.js
const user = {
  id: 1,
  name: 'sample user',
  career: {
    university: 'Hoge大',
    high_school: null,
  },
}

console.log(user.career.high_school ?? '高校登録なし')
// => 高校登録なし
```

# 結論

今後ネストしたプロパティにアクセスするときは Optional Chaining
null または undefined という判定をしたいなら Nullish Coalescing
を使うと、短く簡潔にかける。
Linuxコマンドライン（Ubuntu）からGIFファイルを実行する方法

ファイルがあるディレクトリに行って、次のコマンドを実行するだけ。
〈file〉の所に、実行したいファイル名を入れろ。

```
cmd.exe /C start <file>
```

以上。

これは、Linux（WSL）からWindowsツールを直接実行する方法の一つである。

参考URL
https://qastack.jp/superuser/1160419/how-can-i-open-a-file-from-wsl-with-the-default-application

https://docs.microsoft.com/ja-jp/windows/wsl/interop
Railsでの時間の表示フォーマットを変更する方法


時間の表示が以下のようになっていて、変更したいことがあると思います。

＜現状＞
2020-01-01 00:12:19 UTC

＜変更＞
2020年01年01日

変更方法として、以下の２通りの手順があります。

<h1>手順① time_formatsより設定する</h1>

<h2>time_formats.rbファイルの作成</h2>

config/initializersの直下に、time_formats.rbファイルを作成します。

<h2>時間表示のフォーマットを設定</h2>

例えば、data_jpという変数に「XXXX年○○月△△日」のフォーマットを設定するイメージです。

月と分に「M」が使用しているなどダブった時のために仕様上、年月日と時分秒によって大文字と小文字で使い分けてるってことですね。

```ruby:config/initializers/time_formats.rb
Time::DATE_FORMATS[:datetime_jp] = '%Y年 %m月 %d日 %H時 %M分'
Time::DATE_FORMATS[:datetime]    = '%Y/%m/%d %H:%M'
Time::DATE_FORMATS[:date_jp]     = '%Y年 %m月 %d日'
Time::DATE_FORMATS[:date]        = '%Y/%m/%d'
Time::DATE_FORMATS[:time_jp]     = '%H時 %M分 %S秒'
Time::DATE_FORMATS[:time]        = '%H:%M:%S'
```

<h2>時間表示の変更したい項目にフォーマットを設定</h2>

変更したい項目の後に、先ほど設定したdatatime_jpをto_sメソッドを使用して設定して完了です。

```ruby:app/views/tests/new.html.erb
tweet.start_time.to_s(:date_jp)
```

<h1>手順② strftimeより設定する</h1>

こちらでは、直接カラムの型strftimeで設定する方法です。

Date型だと手順①ではうまくいきませんでしたので、手順②で行いました。

```ruby:app/views/tests/new.html.erb
tweet.start_time.strftime("%Y年%m月%d日")
```
PythonでCoinMetricsが提供するBitcoinに関する簡単なデータ分析

**【本文】**
---

今回は少し趣向を変えて、Pythonを利用した簡単なデータ分析（可視化）の事例を紹介。
CoinMetricsが各暗号通貨（ステーブルコイン等も含む）のデータをcsv形式で提供しているので、そちらを利用して、Bitcoinのトランザクション量と価格(USD)について可視化してみた。

Pythonはデータ分析用のライブラリが豊富な為、簡単な可視化であれば、数行～数十行程度で済むのが嬉しい。
（今回の事例では、pandasとmatplotlibを利用するだけでごく簡単なコードで、何となくそれなりの可視化が可能。同じことをMS-Excelで実現しようとすると。。。）

**＜備考＞**
CoinMetricsが提供するデータは以下からダウンロード可能
（主要な暗号通貨のデータを活用できる）
https://coinmetrics.io/community-network-data/


【Pythonコード】
---

```python:getCoinMetrics
%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd

data = pd.read_csv('xxx\\btc.csv')

data['date'] = pd.to_datetime(data['date'])
data.set_index('date', inplace=True)
```

+ これでdate(日付)をベースにデータ分析が可能となる。

**＜トランザクション量の遷移を年別で可視化>**

```python
plt.plot(data.TxCnt)
```

![TxCnt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167054/170ba10a-f82d-87fc-5732-49855211add3.png)

**＜価格(USD)の遷移を年別で可視化>**

```python
plt.plot(data.PriceUSD)
```

![PriceUSD_btc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167054/e266aebd-949c-7f26-0553-146b2f3c22bd.png)

**＜トランザクション量と価格(USD)の年別遷移状況を複合グラフで表現＞**

```python
fig, ax1 = plt.subplots()
plt.plot(data.TxCnt, color='darkblue', label='TxCnt')

ax2 = ax1.twinx()
plt.plot(data.PriceUSD, color='darkorange', label='PriceUSD')

h1, l1 = ax1.get_legend_handles_labels()
h2, l2 = ax2.get_legend_handles_labels()
ax1.legend(h1+h2, l1+l2, loc='upper left')

ax1.set_xlabel('date')
ax1.set_ylabel('TxCnt')
ax2.set_ylabel('PriceUSD')
```

![TxCnt_PriceUSD_btc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167054/f3105b23-35ea-a208-a421-39fd7fbda532.png)


**＜因みに、特定の年度に絞ることも出来る（例：2014年）＞**

```python:変更箇所のみ抜粋
~
plt.plot(df_data['2014'].TxCnt, color='darkblue', label='TxCnt')
~
plt.plot(df_data['2014'].PriceUSD, color='darkorange', label='PriceUSD')
~
```

![TxCnt_PriceUSD_btc_2014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167054/c5f04794-c37d-f2f9-2769-0a3cf2141350.png)

+ トランザクション量と価格(USD)とで負の相関が見れて興味深い。この後、トランザクション量の増加傾向が続く。

**＜散布図で見てみる＞**

```python
plt.scatter(data.TxCnt,data.PriceUSD)
```

![scatter_btc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167054/abb474f3-a09c-8078-75c5-645ca3cc4ea3.png)

+ トランザクションが一定量(200,000-)に達すると、価格への影響はあまり見受けられなくなる。（と、言えそう）


以上
【Java】ファイルを削除する(Fileクラスのdeleteメソッドで消えないときの解決策)

#プログラミング勉強日記
2020年11月21日
Javaでコードを書いているときに、ファイルの削除がうまくできなかったのでその解決策とFileクラスのdeleteメソッドの使い方をまとめる。

#deleteメソッドの使い方
　Fileクラスのdeleteメソッドは指定したファイルを削除うすることができ、Boolean型の値を返す。<b>※一度実行すると取り消しができない</b>ので注意する。
　Fileクラスを使用するためには`java.io.File`をインポートする。

```java:ファイルの削除
import java.io.File;
import java.io.IOException;
 
public class Main {
    public static void main(String[] args) {
        File file = new File("text.txt");
        
        // deleteメソッドを使用してファイルを削除
        file.delete();        
    }

}
```

#ファイル削除ができない場合
　ファイルを削除できない理由は2つ考えられる。

- 書かれていないメソッドの中でファイルを使用している場合
- 他のプログラムでファイルを開いている場合

　私の場合は他のプログラムでファイルを開いていたため、ファイルの削除ができなかった。

##ファイルが削除できたか確認する方法
　最初に述べたように、deleteメソッドはBoolean型で返されるので、if文を記述することでファイルの削除ができたかどうか確かめることができる。

```java:ファイル削除の確認
import java.io.File;
 
public class Main {
    public static void main(String[] args) {
        File file = new File("text.txt");
 
        // existsメソッドを使用してファイルの存在を確認する
        if (file.exists()) {
            // deleteメソッドを使用してファイルを削除する
            if (file.delete()) {
                System.out.println("ファイル削除成功");
            } else {
                System.out.println("ファイル削除失敗");
            }
        } else {
            System.out.println("ファイルが存在しません");
        }
    }
 
}
```



#参考文献
[【Java入門】file・directoryの削除で失敗しない方法(delete)](https://www.sejuku.net/blog/20480)
[Javaでファイルの削除が上手く出来ません。](https://teratail.com/questions/160754)
「もっと見る」でページネーションを非同期（Ajax）で実装する

# はじめに

## やりたいこと

「もっと見る」を押すことで次の記事が出るようにしたい

## やってみて

JavaScriptが苦手な僕でも、簡単に実装することができました。
今回はjQueryで実装しています。

### 実装画面

![画面収録 2020-11-21 15.56.42.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771826/ff8f2862-7edb-8cde-8306-d98b52557134.gif)

### 実装例
[Output App](https://outputapp.herokuapp.com)

## 参考
[kaminari徹底入門](https://qiita.com/nysalor/items/77b9d6bc5baa41ea01f3)
[t-taira blog > Railsで「もっと見る」の実装]( http://t-taira.hatenablog.com/entry/2013/04/05/093714)

***※情報のソースが古く、かつ私のGemの理解及びjQueryの理解が乏しいため、適切ではない表現が含まれているかもしれません。***

# 手順

## Gem kaminari インストール

```ruby:Gemfile
gem 'kaminari'
```

## Controllerにメソッド追加

```ruby:controllers/items/controller.rb
class ItemsController < ApplicationController

  def index
    @items = Item.all.order('created_at DESC').page(params[:page])
  end

end
```

kaminariをインストールすると
`.page(params[:page])`
こちらの記述でページネーションを組むことができます。


## １ページ毎の取得件数を指定

### Controllerに指定する場合
```ruby:controllers/items/controller.rb
class ItemsController < ApplicationController

  def index
    @items = Item.order('created_at DESC').page(params[:page]).per(10)
  end

end
```

### Modelに指定する場合

```ruby:models/item.rb
class Item < ApplicationRecord
  paginates_per 10
end
```

## View

### each展開箇所を部分テンプレートに切り出す

```erb:views/items/index.html.erb
# @items リスト展開

<%= render "shared/item-list" %>

# // @items リスト展開
```

```erb:views/shared/_item-list.html.erb
<% @items.each do |item| %>

# 中略

<% end %>
```

### jQueryで読み込むためにidをつける

```erb:views/items/index.html.erb
# @items リスト展開

<div id='item-pagenate'>
  <%= render "shared/item-list" %>
</div>

# // @items リスト展開
```

### ページネーションリンクを作る

```erb:views/items/index.html.erb
# @items リスト展開

<div id='item-pagenate'>
  <%= render "shared/item-list" %>
</div>

<%= link_to_next_page @items, 'もっと見る', remote: true, class: 'more-link', id: 'more-link' %>

# // @items リスト展開
```

kaminariをインストールすると
`link_to_next_page`
こちらの記述でページネーションのリンクが作れます。

また、`remote: true`を付与することでサーバーに送られるデータがjson形式となり非同期通信が可能となります。

## jQuery側の処理を記述

json形式のデータを受け取り、返す処理の内容を記述します。

```erb:views/items/inde.js.erb
$('#item-pagenate').append("<%= escape_javascript(render 'shared/item-list', object: @items) %>")
$("#more-link").replaceWith("<%= escape_javascript(
  link_to_next_page(@items, 'もっと見る', remote: true, class: 'more-link', id: 'more-link')
) %>");
```

一行目で id : `'item-pagenate'`の部分に`append（引数を追加するメソッド）`を用いて`次ページ分の@itemsを渡した部分テンプレート`を挿入しています。
二行目以降では、さらに次のページ分のリンクを表示させるための記述をしています（replaceWithで元々存在しているリンクを置き換えています）


以上で、「もっと見る」スタイルのページネーションは完成です！

# おわりに

jQueryが勉強不足ゆえ、メソッドの意味を一つ一つ調べながら解説したつもりですが、間違っていたり情報が古かったらごめんなさい。

ただ、基本的にはこちらの記述で実装はできるはずなので、うまく表示されないのであれば

- jQueryの設定がそもそも出来ていない
- 部分テンプレート（renderメソッド）の記述に誤りがある

のどちらかが疑わしいと思います。

私はファイル名の誤記というシンプルなミスで無駄な時間を消費しました。

お気をつけください。

✔︎
Let's Enctyptの証明書の更新関連のコマンドのメモ

Let's Encryptの証明書の更新に関連したコマンドのメモ

### 証明書の有効期限の確認
* certbot certificates

### 証明書の更新のデモ
* certbot renew --dry-run

### 期限30日未満の証明書の更新
* certbot renew

### 期限が30日以上ある場合の証明書の更新
* certbot renew --force-renew


# まとめ
さくっと終わらせよう
HEICとか何なのかは知りません。でも、とりあえずはPNGにしよう！

# 前置き
たまに「このファイル形式は対応していません」と言われることがありません？
僕はありました。
なので、pythonで変換プログラムを作成しました。
誰かの助けになれば幸いでーす。

# 環境
- Mac
- python 3.7.1
- jupyter lab

# 使用するライブラリ
- pyheif
- pillow

# コード
```
from PIL import Image
import pyheif

heif_file = pyheif.read(image_path) # 1
data = Image.frombytes(             # 2
    heif_file.mode, 
    heif_file.size, 
    heif_file.data,
    "raw",
    heif_file.mode,
    heif_file.stride,
    )
image = data.resize(size)           # 3
image.save(save_path, "PNG")        # 4
```

# 何をやっているか
1. HEIC画像を読みます。この時に「HeifFile object」ができます。
2. それらをImage.frombytesモジュールに必要な物を打ち込みます。この時に「Image object」ができます。
3. あとはresizeして
4. saveで完了

# 最後に
- 簡単なので、大量のHEICデータがある場合は、上記のコードを関数化して、globなどで一括で読み込むと良いです！

### 参考
- [Pyheifのgithub](https://github.com/carsales/pyheif)
- [Pillow公式](https://pillow.readthedocs.io/en/stable/index.html)
【Laravel6でエラーが出た】BadMethodCallExeption: Method Illuminate¥Routing¥Rout::get does not exist.

#【Laravel6でエラーが出た】BadMethodCallExeption: Method Illuminate¥Routing¥Rout::get does not exist.

##使用環境
* windows 10 Home(COREi7)
* XAMPP 7.3.18
* Laravel 6


##背景
Laravel5.7入門の動画に沿ってLaravel6の学習をしていた。
しかしながら、ところどころ違うところも出てきており、極力、ファイルをいじらずに進め、**php artisan serve**をしようとしたところエラーが発生。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615830/1c8a8ead-bf4e-f7cf-f998-311d605603d5.png)

routesディレクトリ中のweb.phpを見てみると、以下のようになっていた。

```php
<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

use App\Http\Controllers\TaskController;
use Illuminate\Routing\Route;


Route::get('/', function () {
    return redirect('/tasks');
});

Route::get('/tasks', 'TaskController@index');
Route::post('/tasks', 'TaskController@store');
Route::delete('/tasks/{task}', 'TaskController@destroy');


```
* 解決案1

エラー文そのまま検索してみるとちょうど同じ状況に陥った人の記事を発見できた。
https://qiita.com/tatuki81/items/6384f21382c17200de0d

早速、同じことをしてみる。

```php
use App\Http\Controllers\TaskController;
use vendor\laravel\framework\src\Illuminate\Routing;
```

しかし、エラーは解決できず...

* 解決案2
* 
違う記事を見つけたので同じことを試してみる
https://teratail.com/questions/257584

まずは以下のように。

```php
use App\Http\Controllers\TaskController;
use Illuminate\Support\Facades\Route;
```


すると、```php artisan serve```できた。

内容を見てみると同じRoute.phpというファイル名でも中身は全然違う。

Illuminate\Support\Facades内のRoute.phpは以下のような内容。


```php
<?php

namespace Illuminate\Support\Facades;

/**
 * @method static \Illuminate\Routing\Route fallback(\Closure|array|string|callable|null $action = null)
 * @method static \Illuminate\Routing\Route get(string $uri, \Closure|array|string|callable|null $action = null)
 * @method static \Illuminate\Routing\Route post(string $uri, \Closure|array|string|callable|null $action = null)
 * @method static \Illuminate\Routing\Route put(string $uri, \Closure|array|string|callable|null $action = null)
 * @method static \Illuminate\Routing\Route delete(string $uri, \Closure|array|string|callable|null $action = null)


```

###わかったこと
原因は指定したファイルにメソッド(getとか使えるように書いてある)が入っていないよ！ということだったらしい。
メソッドが入っているIlluminate\Support\Facades内のRoute.phpを使うよという風にしたことでエラーが解除されたみたい。
Django ModelのForeignKey, OneToOneField, ManyToManyFieldのまとめ。

#1.Foreign KeyとOneToOneFiled

この2つはよく似ている。違いは下のやつ参照。
https://stackoverflow.com/questions/5870537/whats-the-difference-between-django-onetoonefield-and-foreignkey

簡単に言うと、
Aという車(model)があるとする。

ForeignKeyはその車に'所属している'何か(model)に使われる。
ちなみにForeignKeyはOneToManyFieldと呼ばれる。
このForeignKeyは既にある選択肢から選ぶような形をとる。
EX)タイヤ

OneToOneFieldはその車についている'たった一つの'重要な何か(model)に使われる。
EX)エンジン



#2.ManyToManyField
これは2つのmodelの関係性で何個でもつながりがあっていい時。
すでにある選択肢からいくつでも選ぶとき。
EX)courseとstudent, tagとproductなど
選択肢となるほうにManyToManyFieldをいれる。EX)course, tag
【DroidScript】スマホでスマホアプリを作る② 背景やテキストの追加

##あらすじ
DroidScriptというアプリを使うと、javascriptベースの記述でスマホアプリが作れるらしいので、練習として「電子レンジワット数で加熱時間を換算するアプリ」を作る。

##前回のおさらい
ボタンをタップすると「Hollo World!」と表示されるサンプルアプリのコードを見た。
[スマホでスマホアプリを作る① Hello World!](https://qiita.com/YasumiYasumi/items/10796071033a9cefc0b4)

どうやら`lay`にパーツを放り込むことでアプリの画面をレイアウトできそう。

```javascript
function OnStart()
{   
  lay = app.CreateLayout( "linear", "VCenter,FillXY" ); 
  app.AddLayout( lay );
}
```
と言うわけで、自作アプリに向けてレイアウトを作成していく。

##まずは完成画面
絶望的な英語力や配置センスは気にしないでいただきたい(ToT)
![Screenshot_20201121-154732.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708687/f39b0f3c-37b5-4c2b-4cf9-3abd5287e857.png)
上から
・タイトル
・ドロイド君
・自分のレンジのワット数
・温める対象のラベルに記載されたワット数
・温める対象のラベルに記載された加熱時間
・計算ボタン
となっている。

##背景とタイトル
```javascript
lay = app.CreateLayout( "linear", "VCenter,FillXY" );
lay.SetBackground( "/Sys/Img/BlueBack.jpg" );

txt = app.CreateText( "HOW MANY MIN" );
txt.SetTextSize( 22 );
lay.AddChild( txt );
```

１行目で`lay`の基本設定。括弧内の記述はサンプルコードのコピペなのでよくわからん^^;

`lay.SetBackgroud`で背景を設定。最初から用意されている`BlueBack.jpg`を使用。

タイトルの「HOW MANY MIN」というテキストを作りAddChildした。

##ドロイド君
```javascript
img = app.CreateImage( "/Sys/Img/Icon.png", 0.1 );
img.SetMargins( 0, 0.02, 0, 0 );
img.SetOnTouchDown( img_OnTouchDown );
lay.AddChild( img );
```

こちらも最初から用意されているドロイド君のアイコン`Icon.png`をAddChild。`.SetMargins`で、その前にAddChildしたパーツとの間に間隔を設ける。`.SetOnTouchDown`で、パーツをタップした時に呼び出す関数`img_OnTouchDown`を設定した。

ドロイド君をタップしたら呼び出される関数がこちら

```javascript
function img_OnTouchDown( ev )
{
  app.ShowPopup( "I will calculate the heating time!" );
  app.Vibrate( "0,100,30,100,50,300" );
}
```
何のアプリか簡単な説明をポップアップさせ、`app.Vibrate`でスマホを振動させる。

`app.Vibrate`の括弧内は、`("休止,振動,休止,振動,・・・")`で、数字はミリ秒となっているみたい。

##次回
ワット数や加熱時間を入力する部分を作成する。
[スマホでスマホアプリを作る③ スピンボタンとシークバー](https://qiita.com/YasumiYasumi/items/867000c0f6f188551fb7)

###つづく

##シリーズ
DroidScript電子レンジアプリ作成
[スマホでスマホアプリを作る① Hello World!](https://qiita.com/YasumiYasumi/items/10796071033a9cefc0b4)
[スマホでスマホアプリを作る② 背景やテキストの追加](https://qiita.com/YasumiYasumi/items/1569dcc891217a2c92d7)
[スマホでスマホアプリを作る③ スピンボタンとシークバー](https://qiita.com/YasumiYasumi/items/867000c0f6f188551fb7)
[スマホでスマホアプリを作る④ 実行ボタン](https://qiita.com/YasumiYasumi/items/2ae76ac5ec49e0bdb9e8)
[スマホでスマホアプリを作る シリーズまとめ](https://qiita.com/YasumiYasumi/items/832ec009681310ecdd1c)

外伝
[【GAS】電子レンジワット数で加熱時間を換算するwebアプリを作ってみた](https://qiita.com/YasumiYasumi/items/f618fcbbe8beed2db8a9)
WSL1が本家のWSLであってWSL2はおもてたんと違う!

2023-07-29 追記。現時点ではWSL2はだいぶ進化しているので、以下の記事はもう古い。WSL2上でのChromeもテスト用途としては十分機能する。WSLgのインストールも簡単。WSL2でいい。

VisualStudoio Codeを使ってると何かとWSL2をおすすめされる。WSL2で課題とされていたことが解決したのかと思ったがどうもそうでもなさそう。WSL1を便利に使っていたので全体的に怒り口調で書いています。

以下、課題を挙げる。

## いまだにlocalhostが共有できない（あたり前だけど）

これは仮想マシンを立ち上げた時の昔からある課題。Windows→WSLへのlocalhostは回避策があるが、WSL→Windowsへのlocalhostはアクセスできない。WSL1に比べて大幅な機能ダウン。

「WSLがサーバーでWindowsがクライアントだからそれでいいんじゃない？」って思う人もいるかも知れないが、Windows側がサーバーになることもある。例えばSeleniumなんかがそう。SeleniumにしてもChrome DevTools Protocol にしても、Windows側がlocalhostでlistenする。「WSL2はSeleniumを始めとするブラウザオートメーションが使えない」という今どきのWeb開発には致命的な不便さがある。

回避策としては、WSL2側にChromeをインストールすればいい。WSL2側でGUIまで立ち上げればもはやUbuntu完結だ。でももはやそれは「Windowsを使わない」と同義。VSCodeもChromeも全部Ubuntuでやりたかったら、最初からUbuntuをブートすりゃぁいい。普段使いのChromeをUbuntu上のプログラムから自動化してこそ「PCを自動化した」といえる。

WSL2が本流だと思ってた被害者がここにもいる。
https://neos21.hatenablog.com/entry/2020/10/13/080000#Selenium-Webdriver-%E3%81%AF%E5%87%BA%E6%9D%A5%E3%81%9D%E3%81%86%E3%81%A7%E5%87%BA%E6%9D%A5%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F
当然のことがなら、WSL2からWindows側のlocalhostでlistenしてるseleniumドライバは見えない。かわいそうに。毛布をかけてあげたい。

今どきのプロセス間通信はlocalhostのIP通信が基本なんだから、localhostが互いに共有できてない時点でもはや「一つのPC」で開発している意味なんてない。それを「Windows Subsystem」と名前をつけるので誤解を生む。素直に「軽量VM」って言えばいい。

## 当然のことながらWindowsのファイルシステムへのアクセスはWSL1が速い

WSL2は速いけど、Windowsへのファイルアクセスは遅いんだ、それは我慢してね。って話だが、それもWSLの目的をわかってない。マイクロソフト自身がWSLの目的を理解してない。WSL上でバッチを回すってのは、Chromeを自動操縦したり、ffmpegで動画を変換したり、imagemagickで静止画を変換したいからやってること。WindowsのGUIで見るものを、Ubuntu上のCUIで一括操作をしたいからこそのWSL。Ubuntu完結なら最初からLinuxマシン使ってる。

マイクロソフトはWSL2ではファイルの共有がいまいちだってことの回避策としてこんなことを言ってる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53489/cd368726-3c45-14b2-2602-a0e60ecf8d54.png)

いやいや、VS Code ってソースコードを編集するためのものであって、動画見たり静止画みたりするもんじゃないよね。Windowsでユーザが何をしているかが全然わかってない。

VS CodeはたしかにRemote開発がめちゃくちゃ便利だ。なんならWSLみたいな手元の環境だけじゃなくて、ガチのリモートサーバーでさえもローカルで開発しているかのように開発できる。
じゃもうクラウドサーバー上で開発しちゃえばいい。クラウドサーバー上のファイルは直接みれない、クラウドサーバー上でselenium動かしてもブラウザが動いてるところが見れない、だからWSL1はありがたかったのに、WSL2はその意義を消し去ってる。

## 改めてWindows周辺を自動化したい

バッチファイルでもなく、PowerShellでもなく、Linux上で育成されたオープンソースプロダクトを使って、Windows側を自動化したいというニーズに「どん」とハマっていたのはWSL1なのでした。だから尊い。

## ステージング環境は開発環境とは別

とはいえWSL1が純正Linuxではないというところはデメリットではある。Dockerが使えないとかそういうところ。ただDockerは開発を楽にするためのものと言うよりも、デプロイを楽にするための仕組み。開発環境とステージング環境を同一視するのに無理がある。手元でプロトタイプを作るのに、Rubyのバージョンのコンセンサスなんて要らない。MySQLでもMariaDBでもどっちでもいい。サクラエディタでコードを触るということだってあっていい。Windowsファイルシステム上でWinMergeを使っている人に、それは時代遅れだという気もしない。WindowsのGUIアプリもそれなりに便利なものがあって、それはすべて「開発時に」「お勉強するときに」便利なもの。当然Web開発のステージング環境ではWindows要素はゼロになるが、そんなのわかってる。

Windowsの豊富なGUIツールとLinuxの豊富なCUIツールのいいとこどりをさせてほしい。WSLは「Better Cygwin」でいい。
AdMobのapp-ads.txtファイルを自分のwordpressサイトに設置した

#はじめに
![スクリーンショット 2020-11-21 13.22.25.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/218e1ffa-8de2-96bf-a952-354eb2c16183.jpeg)

AdMobからメールと管理画面でこんなお知らせが来ていた。

#app-ads.txtとは？
色々なところで解説されてるが、結局私にはよくわらないですww

>App-ads.txtはモバイルアプリの広告枠の販売者を識別することができるツールです。つまり、ads.txt機能をMobile App向けに実現させているのがapp-ads.txtです。
app-ads.txtはモバイルアプリの広告枠を不正利用ら守るためのツールです。
https://tech-cci.io/archives/2150

と言う事らしい。。。:sweat:

#まずはapp-ads.txtファイルを作成
![スクリーンショット 2020-11-21 16.06.13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/576dd2fc-e31e-4d77-2700-743a2f558098.jpeg)

スニペットをコピーしてapp-ads.txtを作成し貼り付け

**app-ads.txtは普通にテキストファイルです。**

```tex:app-ads.txt
google.com, pub-xxxxxxxxxxxx, DIRECT, xxxxxxxxxxxxxxx
```

#デベロッパーサイトに設置
そもそも、デベロッパー サイトが何か？と言う話だが、、、

**私の場合はiOSとAndroid共に必要な「プライバシポリシーURL」のために、適当にwordpressでサイトを作成していたのでそいつを利用**
https://gengendiary.world/hcalendar-privacy/
:point_up:こんな感じ


##レンタルサーバーにapp-ads.txtをアップロード
私はロリポップをレンタルサーバーとして使っていたので、そのままロリポップFTPでファイルをアップロード！
![スクリーンショット 2020-11-21 13.16.52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/1571e9da-2f60-4e15-7a91-f987ce144c12.jpeg)

で、app-ads.txtは`https://example.com/app-ads.txt`のような感じになるよう設置しないといけない。

だから、ロリポップFTPで`mysite/app-ads.txt`のような感じで設置
![スクリーンショット 2020-11-21 13.16.22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/b95535b7-d9d3-4725-3ebf-b9118158e685.jpeg)

`https://example.com/app-ads.txt`にアクセスして、app-ads.txtファイルの内容が表示されればOK

#デベロッパーサイトのURLを各ストアに記載

##iOS
App Store Connectの**マーケティングURL**と言う部分がデベロッパーサイトのURLになるようです。
**このリンクは新しいバージョンを作成して、アプリをアップデートする時しか追加できないので要注意。**
![スクリーンショット 2020-11-21 16.02.13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/361f04d0-ffce-cd1a-7926-ef81117e69f1.jpeg)

##Android
`ストアでの表示＞ストアの設定`からウェブサイトのURLを設定して保存 
![スクリーンショット 2020-11-21 16.22.48.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/4676b58e-0a9c-9e76-d9fc-3fb0e6152fd9.jpeg)



#最後に
あとはひたすら待つだけです。。。

数日で以下のようになっていました。これで成功！！
![スクリーンショット 2020-11-23 13.41.32.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/869e8552-a367-41cc-460e-dc414d565c15.jpeg)
Dockerfileの中でgnome-terminalの実行を試みるもエラー（GDBus.Error:org.freedesktop.DBus.Error.Spawn.ChildExited: Process org.gnome.Terminal exited with status 8）

Dockerfileの中でgnome-terminalの実行を試みるもエラー

```
# gnome-terminal -e "python3 judge/timer.py"
# Error constructing proxy for org.gnome.Terminal:/org/gnome/Terminal/Factory0: Error calling StartServiceByName for org.gnome.Terminal: GDBus.Error:org.freedesktop.DBus.Error.Spawn.ChildExited: Process org.gnome.Terminal exited with status 8
```

以下を実行する事で解決

```
locale-gen ja_JP.UTF-8
export LANG=ja_JP.UTF-8
export LANGUAGE=ja_JP:jp
export LC_ALL=ja_JP.UTF-8
eval `dbus-launch --sh-syntax`
```

Dockerfileは以下のような感じに記載すれば良い

```dockerfile:Dockerfile
# environment setting
#RUN locale-gen en_US.UTF-8  
#ENV LANG en_US.UTF-8  
#ENV LANGUAGE en_US:en  
#ENV LC_ALL en_US.UTF-8
RUN locale-gen ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:jp
ENV LC_ALL ja_JP.UTF-8
RUN echo 'eval `dbus-launch --sh-syntax`' >> /home/jetson/.bashrc
```

# 参考
[gnome-terminalが機能しなくなった](https://qastack.jp/unix/231152/gnome-terminal-stopped-working)
FlaskのAPIサーバをforeverで永続化する

# 環境情報

```:環境
Raspi 3B+
OS rasbian (stretch)
pip 20.2.4
python 3.5
npm 6.14.9
forever v3.0.2
flask 0.12.1
```

各種インストール

```
$ pip install Flask
$ npm install -g forever
```

# Flaskでサーバを立てる
(参考)https://qiita.com/tomboyboy/items/122dfdb41188176e45b5

```python:hoge.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return 'Hello world'

if __name__ == '__main__':
    app.run(debug=False, host='0.0.0.0', port=5000)
```

```:実行(テスト)
$ python hoge.py
^C
```

## トラブルシュート
* 80番ポートを使用しようとすると`Permittion Deny`で弾かれるので他を利用するといい。  
(参考)https://stackoverflow.com/questions/550032/what-causes-python-socket-error
* ファイアウォール設定変更(ラズパイ内から`curl 192.168.x.x:5000`が通るが外からアクセスできない場合)  
`$ sudo ufw allow 5000`実施。

# 永続化
このままだとsshを抜ける際にプロセスが終了するのでforeverで永続化する。foreverはコマンドがデフォルトでnodeなだけで`-c`オプションを利用することで任意のコマンドを指定でき、Pythonコードも永続化できる。

```:永続化を実行
$ forever start -c python hoge.py
```

foreverのコマンドやオプションについては以下参考
https://qiita.com/disc99/items/57490f5eef3e2eb685ba

# 再起動時にforeverを実行する
上記のままでもラズパイ自体をrebootすると起動時にforeverが実行されないためサーバは死んでしまっている。

`/etc/rc.local`に以下を記述
(参考)https://584homes.com/it/raspberry-pi/rasberrypi-startup1803.html%20=

```:rc.local

sudo forever start -a --uid Hoge -c python /home/pi/hoge.py

exit 0
```
最近のOAシステムについて思う事

久々にQiitaを見たのでメモ書き程度に・・

## 最近のOAシステム導入の潮流
1.コロナ禍で在宅勤務やテレワーク導入必須となり、スマホや自宅PCでの社内システム利用が必要になった。
2.SaaSとそのクライアントアプリのセキュリティがしっかりしてきて、セキュリティに必要な業務データと個人データの分離ができるようになってきた。（一部のSaaSだけですが・・）

この1,2の条件が揃ったので、急速にSaaS利用に傾きだした気がします。
特に2について言えば、対応できているSaaSは少ないですが、特にMicrosoftがかなり頑張って、業務で利用されるOfficeアプリ中心にデバイス管理・データ保護が充実してきたので、Microsoft 365/Intune中心にOAシステムがSaaS化されてます。
MSの囲い込みがますます大きくなるのが懸念点ですが・・

ID系も、ActiveDirectoryでの実績を生かして、Azure ADが猛烈に進化していますよね。
WindowsPCを利用しているところは、結局Azure ADをIDaaSとして利用するのが一番便利で、
あとMicrosoft 365と連携して・・みたいな感じで、IDaaSもAzure ADになりつつあります。

そうすると、OA系はIDaaSがAzure ADになるから、そこに他のシステムもAzure ADにSAML連携でID認証して・・
となっているかなと。

## ゼロトラスト
簡単に言えば、どこの誰からアクセス受けるか想定できないので、常に本人と資格確認します。というセキュリティです。確認場所は、デバイス・アプリ（サーバ or クライアント）・ネットワークと、システムの各部分で実施する感じでしょうか。

・デバイスだと、例えばiPhoneならパスコードや生体認証で本人確認、WindowsPCであればWindowsログオンでパスワード、Windows Helloで生体認証、AzureADの条件付きアクセスでデバイス認証 or 二要素認証など、まあビジネス利用であれば普通にやっていると思います。

・クライアントアプリだと、サインイン/ログインでユーザ専用画面に情報表示。サインイン・ログイン中しかデータを保持しない、データの受け渡しも制限、データ暗号化、遠隔ワイプ可（実際にここまでできるアプリはあまりないですが・・）

・ネットワークだと、IDまたは証明書認証で接続制限、通信データ暗号化、トラヒック種類で制限など。まあVPN+トラヒック管理ですね（SaaS中心の利用だと、さらにCASBでテナント制御もできたらいいなくらい）

・サーバアプリだと、ID or 証明書認証・
アクセストークン・IP制限（通常VPNでIP絞って制限）で利用者・資格確認でしょうか。

上記の事は、部分では今までやってきたものの、トータルで管理する視点があまり無かったのをゼロトラストが気づかせてくれた感じですね。
【Asana】ペアチケッティングしたらものすごい効果があった話

## 普通は相手に伝わらない
起票されたチケットが分かりにくい、という問題はありませんか？

(よくある問題)
* タイトルが分かりにくい
* 本文が分かりにくい
* 何を言いたいか分からない

学校教育を振り返ってみると **「相手に伝える文章」** を書く機会というのはほとんどなく、伝える機会があったとしても、日本語が伝わっていない事を指摘するのは空気が悪くなる気がするのか **「的確な指摘をする」** 機会もほとんどなかった様に思えます。

つまりは、何らかのカイゼン活動を行わなければ、以下の様な状態になるのは **『普通』** です。

**『レビューイの文章も分からないけれど、レビュアーの指摘も分からない』**

* レビューイは『相手に伝える文章の書き方』を知らない
* レビュアーは『的確に指摘をする方法』を知らない


## 意味のないレビュー

**「意味が分からないクソな文章だ、俺ならこう書く」**

あれこれとポイントを伝えようと試みたが、相手が腹落ちしない顔をしていて一向に修正される気配がないため、罵詈雑言を並べた挙げ句、レビュー時間の残り時間を鑑みて自分で **「原型をとどめていない」** サンプルを作成して提示すると、以下の状態になります。

* レビューイの経験値は貯まらない
* レビュアーのストレスは溜まる

このレビューは全く効果も意味もありません。


## 「原型をとどめていない」理由

**「書いてあるべきこと」** と **「書かれていること」** が乖離しているから。

「読みやすい文書」の基本的な構造についてはウェブサイトや書籍で学べると思いますが、「書いてあるべきこと」を理解できるようになるための書籍というのはなかなか存在していない様に思えています。

(参考サイト / 書籍)
* [文章教室――読みやすい文章を書くために――](https://www.hyuki.com/wl/)
* [一番伝わる説明の順番](https://www.amazon.co.jp/%E4%B8%80%E7%95%AA%E4%BC%9D%E3%82%8F%E3%82%8B%E8%AA%AC%E6%98%8E%E3%81%AE%E9%A0%86%E7%95%AA-%E7%94%B0%E4%B8%AD%E8%80%95%E6%AF%94%E5%8F%A4/dp/4894519836)

## 「伝わる文書」の本質

「書いてあるべきこと」を理解できる書籍が存在しないのは、文書のフォーマットや順番に比べて一般化して伝えるのが遥かに難しいことだからではないかと想像しています。

「報告書」のフォーマットは一般化できるけれども、**報告する相手によって「書いてあるべきこと」は異なっています**。同じ進捗報告でも、経営層に報告するのか、プロジェクトのメンバーに報告するのかで、内容は全く異なります。

わたしは、この差異は、形（フォーマット）を覚えるのではなく、提出する相手を理解することで埋められるのではないかと思っています。経営したことなどないので経営層を真に理解することなどはできませんが、「報告書」という限られた接点においては、経営層が必要なものを推理することも可能だと思います。

伝わる文書の本質は **「伝える相手が理解できること」** で、そのような文書を書くためには **「伝える相手を理解すること」** だと思います。


## 思考の流れを伝える / 観察する

前述の通り、**「的確な指摘ができない」** 上に **「原型をとどめていない」** レビュー結果を返すのは不毛です。なぜか伝わった気になって次回直ってないとガッカリするのも不毛です。

ということで、ここまできてようやくタイトル回収になります。

[Asana](https://asana.com/ja)

Asanaのチケットはリアルタイムに更新され、全員が更新されているのを同時に確認できます。これを利用して以下の様なスタイルでレビューを行うことで思考を伝えることができるのではないかと考え実施しました。

1. レビュアーはレビューイに「チケット修正を行うから観察する様に」指示します
1. レビュアーは見られていることを意識して、なるべく最適な手順でチケットを修正します
1. レビューイはレビュアーに観察して感じたことを伝えます

レビューイは「何を」「どの順番で」直しているのか、つまりはレビュアーの思考の流れを確認できます。
おそらく、タイトルの見やすさ、読む人が知りたいこと、文章の構成等々、様々なノウハウが入り混じった、**指摘では伝えきれない量の情報** がそこには含まれていると思います。
レビューイより観察して感じたことを言語化して伝えさせることで、レビュアーは『レビューイの理解』を理解でき、より適切な指摘ができる可能性が高まります。

また、レビューイの観察行為は、伝える相手を理解しようとする行為そのものであり、**「相手を理解する」という難しい概念を理解したり体験したり**するのに役立つと思います。


## おわりに

テレワークになってコミュニケーションが難しいと言われますが、VS Code の Live Share など、隣に座ってペアプロするより効率がよいツールもあるのかなと思っています。

Asanaとチケットは一例であり、Googleスプレッドシートの仕様書やGoogleスライドのプレゼンテーション資料などでも同じことができると思います。
※タイトルで【Asana】を強調しているのは、Asana推し（笑）であったり、身近な細かいテーマで実践ができる可能性が高いと思ったからです。

大事なのはお互いがお互いを理解して共に成長していくことだと思います。
**コミュニケーションの質**を高めて快適なテレワークライフをエンジョイできればと思います。
Wordpressにおけるテンプレート読み込みの関数(get_template_part)

<h1>get_template_part関数について</h1>


同じコードを何度も書かないというプログラミングの常識があり、Wordpressでも
複数ファイルで、共通して使われるコードをテンプレート化して読み込む方法が、<b>get_template_part</b>となります。


<b>記述方法①(index.php内で記載)</b>

<b><?php get_template_part('template-parts/sample-file'); ?></b>　　　 

()内は読み込みをするファイルのdirectoryとファイル名を記載します。
※ファイル名の拡張子(.php)の記載は不要です。

これでsample-file.phpの内容をindex.php内で読み込めるようになります。<br>


<b>記述方法②(index.php内で記載)</b>

<?php get_template_part( $sample); ?>

$の後にtemplateファイルのSlug名を記載することで、　sample.phpファイルを読み込むことができます。
<br>


<b>記述方法③(index.php内で記載)</b>

<?php get_template_part( 'sample' , 'file' ); ?>

こちらの記載でsample-file.phpを読み込みできるようになります。<br>

<h3><b>Slugについて(補足)</b></h3>

＄Slugとは記事やカテゴリに付与される名前のことで、URLの一部になります。
日本語は使えず、英数字を使うことになります。　Slugを指定することで記事やページを指定できるようになります。
ActionView::Template::Error (Mysql2::Error: Table'heroku_(テーブルの情報？)' doesn't exist):

#heroku run rails db:migrate
タイトルにあるエラーが発生した場合は、ターミナルにて```% heroku run rails db:migrate```を行わないまま```% git push heroku master```してしまった可能性が高い。

#エラーの原因
heroku上でマイグレーションせずpushしたため、テーブルが作成されず発生した。

#エラー文の確認方法
```% heroku logs --tail --app アプリの名前```でエラー文の確認が可能。
C言語 コンパイル


windowでC言語のコードをテストするときは、WSLを使用。
Cドライブ内で実行するときは、ディレクトリを移動。

##準備　インストール
・WLS (Windows Subsystem for Linux)
・WLS に gcc をインストール

## コマンド

```
cd /mnt/c/Users/NAME/Desktop/test

gcc -o test test.c && ./test
```
laravel Log::info('ログ'); でエラー

## 動作環境
laravel 6.0
nginx

## エラーの内容
ログの出力テストをしたくて、[このサイト](https://techacademy.jp/magazine/18779)を見ながら、コントローラーに以下のコードを記載したがエラーなりnginxのエラー画面しか表示されなかった。

``` php
<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;

class LogController extends Controller
{
    //
    public function index()
    {
        Log::info('ログ');
        return 'log test';
    }
}
```

## エラーの原因
**use Log;**
を使ったら解決した。

``` php
<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Log;

class LogController extends Controller
{
    //
    public function index()
    {
        Log::info('ログ');
        return 'log test';
    }
}
```

## 結果
storage/logs/laravel_yyyy-mm-dd.logをvim等で見て以下の内容を確認した。

```
[2020-mm-dd hh:mm:ss] local.INFO: ログ
```

## 感想
**use Log;**
の記載が抜けている参考サイトが検索の上位に来ているので、気づくのに時間がかかった。
【Git】git rebaseでコンフリクトした際の対応方法

## はじめに
コマンドで操作しているときにエラーメッセージに遭遇すると、いつも以上にびっくりしちゃいますよね。
慌ててなんとかしようとすると思わぬミスをしてしまうことがあるので、まずは落ち着いて状況を判断していきましょう。

## コンフリクトが解消できそうな場合
まずは以下を参考にコンフリクトの修正をしましょう。
参考：[コマンドラインを使用してマージコンフリクトを解決する](https://docs.github.com/ja/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-using-the-command-line)

コンフリクト箇所を修正してコミットしたら、中断しているリベースを再開しなければなりません。
以下コマンドで残りのリベースを再開しましょう。

```shell
 git rebase --continue
```
参考：[Git リベース後のマージコンフリクトを解決する](https://docs.github.com/ja/free-pro-team@latest/github/using-git/resolving-merge-conflicts-after-a-git-rebase)

## リベース前に戻したい場合
自分で直すのが無理そうだったり、そもそもリベースする対象を間違えてたりする場合もあります。
そんな場合は、以下のコマンドでリベース直前の状態に戻すことができますよ。

```shell
 git rebase --abort
```
参考：[Git リベース後のマージコンフリクトを解決する](https://docs.github.com/ja/free-pro-team@latest/github/using-git/resolving-merge-conflicts-after-a-git-rebase)

## よく分からない・判断できない場合
無理せず、周囲の方に相談しましょう。

「何をしようとしたら」「どうなったのか」「どこが分からないのか」ということをお伝えすると、伝わりやすいと思います。
例：「リベースしてmasterの変更を取り込もうとしたら、hogeファイルでコンフリクトしました。。直そうと思ったのですが、どのように修正すれば良いのか分からないので教えてください。」

報連相は大事です！
VSCodeでSSH接続先サーバのファイルをサーバ上で編集する

#やること
VSCodeでサーバ上のファイルを編集する方法はQiitaでも既出で、私もここで覚えました。
ちなみに私は、以下の記事を参考にしました。
[VSCodeでサーバー上のファイルを編集する4つの方法](https://qiita.com/catopy/items/862c4707387a98afa1a6)

今回は、自身の備忘のためでもありますが、上記の記事を
さらに細かく書いて、ガチガチの監視オペレータ向けの手順書みたいにして残そうと思いますw
まあ、時間がない人は上のリンクの説明をみるほうが早いと思います。

VSCodeが入っていることと、SSH接続ができるサーバが起動していることが前提ですが、やってことないよって方は以下の記事を参考に導入してください。
[Visual Studio Code (Windows版) のインストール](https://qiita.com/psychoroid/items/7d85ae6bade4a67aedb1)
[VirtualBoxにCentOSをインストール](https://qiita.com/tamago3keran/items/260899458959d3214dcf)
#プラグインのインストール
[表示]タブの中の[拡張機能]を左クリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536529/a09891d2-b9c7-0350-a273-d1c3c28605df.png)

検索ウィンドウに`Remote-SSH`と入力し、
絞り込まれたプラグイン「Remote-SSH」の中の[インストール]を左クリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536529/5a80018a-f447-cc5c-0ee8-dcb87495540e.png)

インストールすると、プラグインの説明のタブが自動で開かれるため、閉じておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536529/60ef770b-f836-633d-8476-9f69d04f7635.png)

[表示タブ]の中の[コマンド パレット...]を左クリックする。
一応、ショートカット`Ctrl+Shift+P`でも開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536529/7b8d3642-470d-4bb1-2f68-b3ff86918464.png)

検索ウィンドウに`Remote-SSH: Connect to Host...`
※検索ウィンドウ開くと`>`がもともと入力されているので、その後ろから入力する。コピペする場合は、注意する。

そして、絞り込まれた「Remote-SSH: Connect to Host...」を左クリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536529/511de110-0387-4f88-8b1d-47bad040007f.png)

[+ Add New SSH Host...]を左クリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536529/137aa009-7683-4d31-e6d5-318d899484c1.png)

[ssh ユーザ名@ホスト名]を入力する。
※自身のサーバのユーザ名、ホスト名を入れるようにしてください。teraterm等からSSH接続するときと同じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536529/a2d9af49-dd4d-6952-ad10-b1bdbca051cd.png)

更新する設定ファイルを選択する画面が表示されるため、
選択する。
※`C:\User\{ユーザ名}\.ssh\config`を選択すれば問題ないと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536529/58a76682-0059-7049-42a8-54788eae00a3.png)

左下に画面が表示されるため[Connect]を左クリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536529/da261437-99ed-6ec0-0c29-d44273c30a85.png)

新規でVSCodeのウィンドウが開かれる。
検索ウィンドウに、サーバのログインパスワードを入力し、
`Enter`キーを押下する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536529/edac66d4-0ca6-9800-e63f-d3828d4169ac.png)

[ファイル]タブの中から[ファイルを開く...]を左クリックすると、接続先サーバのファイルを選べるようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536529/3ea9b784-7a48-337f-1b64-28805e97f809.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536529/b7f68e25-9575-358c-6b50-eb187f5296d7.png)
Pythonで画像を収集する方法

#はじめに
Deep Learning用に画像収集しようと思い、[この記事](https://qiita.com/channel-techtok/items/e77843ec20e66f741dc4)に行きついたのですが、
webページの中身が変わったのか、うまくいかなかったので、書き換えてみました。

#コード

```python:image_download.py
import requests
import urllib.request
import time
import json

def scraping(url, max_page_num):
    # ページネーション実装
    page_list = get_page_list(url, max_page_num)
    # 画像URLリスト取得
    all_img_src_list = []
    for page in page_list:
        try:
            img_src_list = get_img_src_list(page)
            all_img_src_list.extend(img_src_list)
        except:pass
    return all_img_src_list


def get_img_src_list(url):
    # 検索結果ページにアクセス
    response = requests.get(url)
    webtext = response.text

    # 元の記事ではBeatifulsoupを使っていたのですが、画像が取れなかったので、変更しています。
    start_word='<script>__NEXT_DATA__ = '
    start_num = webtext.find(start_word)
    webtext_start = webtext[start_num + len(start_word):]
    end_word = ';__NEXT_LOADED_PAGES__='
    
    end_num = webtext_start.find(end_word)
    webtext_all = webtext_start[:end_num]
    web_dic = json.loads(webtext_all)
    img_src_list = [img['original']['url'] for img in web_dic["props"]["initialProps"]["pageProps"]["algos"]]

    return img_src_list


def get_page_list(url, max_page_num):
    img_num_per_page = 20 #ここを変えるとダウンロード数が変わります。
    page_list = [f'{url}{i*img_num_per_page+1}' for i in range(max_page_num)]
    return page_list

def download_img(src, dist_path):
    time.sleep(1)
    try:
        with urllib.request.urlopen(src) as data:
            img = data.read()
            with open(dist_path, 'wb') as f:
                f.write(img)
    except:
        pass


def main():
    search_words = ["橋本環奈"] #検索したいワードをリストで渡します。
    for num, search_word in enumerate(search_words):
        url = f"https://search.yahoo.co.jp/image/search?p={search_word}&ei=UTF-8&b="
        max_page_num = 20
        all_img_src_list = scraping(url, max_page_num)
        
        # 画像ダウンロード
        for i, src in enumerate(all_img_src_list):
            download_img(src, f'./img/image_{num}_{i}.jpg') #保存先は適当に変えてください


if __name__ == '__main__':
    main()

```

imgフォルダを作って、上記をpythonで実行するとimgフォルダ内に画像が保存されます。
こんなイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697702/f025ced9-e8bc-4640-f02e-9d2f97ca10b8.png)

スクレイピングは相手のサーバーに負荷がかかるため気を付けましょう！

### 修正
コメントで指摘があったため、コードを1か所変更しました。
修正前：画質が悪くなる

```python

img_src_list = [img['imageSrc'] for img in web_dic["props"]["initialProps"]
```
修正後：良い画質の画像を取得する場合はこちら

```python

img_src_list = [img['original']['url'] for img in web_dic["props"]["initialProps"]["pageProps"]["algos"]]
```
#参考
[Pythonで橋本環奈の画像を自動収集してみた！！](https://qiita.com/channel-techtok/items/e77843ec20e66f741dc4)
なでしこでもっと美しくFizzBuzzを書く

真剣になでしこでFizzBuzz問題を解いています。
そもそもFizzBuzz問題とはなんでしょうか。

> 問題例 1から100までの数を出力するプログラムを書いてください。ただし、3の倍数のときは数の代わりに｢Fizz｣と、5の倍数のときは｢Buzz｣と表示してください。3と5の倍数の時は｢FizzBuzz｣と表示してください。

実は、既に以前[マイナビ様の連載21回目](https://news.mynavi.jp/article/nadeshiko-21/)でなでしこ真剣にFizzBuzz問題を解いたことがあります。この記事ではとても真剣にFizzBuzz問題に取り組み、プログラムの解説を書きました。

詳細は[こちら](https://news.mynavi.jp/article/nadeshiko-21/)は読んで貰うとして、今回は、解説もほどほどにいろいろなバリエーションを紹介したいと思います。

# オーソドックスな答え

[こちらの簡易エディタ](https://nadesi.com/doc3/go.php?10)を使えばWebブラウザ上でプログラムを実行できます。対象は「なでしこ3」を想定しています。

以下のプログラムはオーソドックスな答えです。問題を何も考えずに解くとこうなるでしょう。

```
Nを1から100まで繰り返す
　　もし、(N%3=0)かつ(N%5=0)ならば「FizzBuzz」と表示。
　　違えば、もし、N%3=0ならば「Fizz」と表示。
　　違えば、もし、N%5=0ならば「Buzz」と表示。
　　違えば、Nを表示。
ここまで。
```

# 関数を使って読みやすくする場合

そして、少し処理を関数化して読みやすくすると以下のようになります。

```
Nを1から100まで繰り返す
　　NでFizzBuzz処理して表示。
ここまで

●(Nで)FizzBuzz処理とは
　　もし(Nを15で割った余り)が0ならば「FizzBuzz」で戻る
　　もし(Nを3で割った余り)が0ならば「Fizz」で戻る
　　もし(Nを5で割った余り)が0ならば「Buzz」で戻る
　　Nで戻る
ここまで
```

ここまでは、上記の連載で紹介した内容です。

# もっと真剣に取り組んだ場合

もっと、真剣に日本語プログラミング言語という特徴を掴んで作るとこうなります。
ある程度、自然な日本語として読むことができているのではないでしょうか！

```
100回、回数をFizzBuzz判定して表示。

●(Nを)FizzBuzz判定とは
　　もしNがFIZZBUZZならば「FizzBuzz」で戻る。
　　もしNがFIZZならば「Fizz」で戻る。
　　もしNがBUZZならば「Buzz」で戻る。
　　Nで戻る。
ここまで。

●(Nが)FIZZとは
　　(Nを3で割った余り)が0と等しい
ここまで

●(Nが)BUZZとは
　　(Nを5で割った余り)が0と等しい
ここまで

●(Nが)FIZZBUZZとは
　　それは((NがFIZZ)かつ(NがBUZZ))
ここまで
```

以上、なでしこでもっと美しくFizzBuzzを書いてみました。

## 参考

 - [日本語プログラミング言語なでしこ](https://nadesi.com)
 - [マイナビ連載 ゼロからはじめてみるなでしこ](https://news.mynavi.jp/series/nadeshiko/)
 - [マイナビ連載21回目 真剣にFizzBuzzを解く](https://news.mynavi.jp/article/nadeshiko-21/)
Visual Studio Code で Windows アプリ開発したいんだけど？

## 先に結論

Visual Studio 2019 使いましょう。

## 本文

今日開催している Visual Studio Code Conference Japan で VS Code で Windows アプリ開発に関する質問が出てたのでさらっと書いてみようと思います。

個人的にぱっと思いつくものは以下の3つくらいが思いつきました。

- flutter
- React Native for Windows
- WPF

## flutter

前に少しだけ flutter は試したことがあるのですが拡張機能を入れて設定すると意外とサクッと動いて快適でした。

- [Flutter の開発環境を作ってみたメモ on Windows 10](https://blog.okazuki.jp/entry/2019/06/09/161005)
- [Flutter の開発環境を作ってみたメモ on macOS](https://blog.okazuki.jp/entry/2019/06/09/220343)

ただ、前に試したのはモバイルアプリ開発だけでした。最近、この flutter がデスクトップもサポートしているみたいです。ただ、現状アルファなので強い人向けっぽい空気を感じます。

https://flutter.dev/desktop

## React Native for Windows

React Native を使って開発することもできます。これは以前 Qiita に書きました。

[React Native for Windows ことはじめ](https://qiita.com/okazuki/items/38f3b94705411aab1b6e)

ただ、各種 SDK を入れる関係で Visual Studio 2019 を結局入れることにはなります。

## WPF/Windows Forms

.NET でデスクトップアプリ開発をするときには、現状 WPF や Windows Forms を使うことになります。.NET 5.0 の SDK を入れると dotnet コマンドが使えるようになります。そこで以下のようなコマンドをたたくとプロジェクトが作られます。

```
dotnet new wpf
dotnet new winforms
```

Visual Studio Code に C# 向けの拡張機能を入れた状態で上記コマンドで生成されたフォルダーを開くと実行からデバッグまでできるようになります。

C# で書く限りにおいてはインテリセンスもききます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/85118f2a-4e74-41aa-5e89-84fb1ff5ffec.png)

ただ、Windows Forms のデザイナーはありません。WPF も XAML はデザイナーもなく、現状はただの XML ファイルとして認識されるためインテリセンスが効きません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/6e0deec9-f992-da16-5ac7-08576c4a915d.png)

↑は、本当なら TextBlock という候補が出てきてほしいけど Visual Studio Code では候補が出なくて悲しい気持ちになっているところ。

ということで、デザイナーがなくてもいいなら強い気持ちで Visual Studio Code を使って WPF/Windows Forms アプリの開発は出来るようになっています。

## electron

そういえば忘れてた…、Visual Studio Code もこれで作られてる electron。

https://www.electronjs.org/

個人的に使ったことが本当に一度もないので…。どうなんでしょう？

## 未来の話

ただの個人の妄想です。

### Visual Studio Code での XAML サポート

希望的観測では XAML 向けの Language Server に対する要望はあるので無視できないくらい要望が集まればサポートされることもあるかもしれませんが、個人的には望み薄…

[Create a XAML language service](https://github.com/OmniSharp/omnisharp-vscode/issues/3338)

### MAUI

.NET 6 がリリースされる2021年11月のタイミングで Xamarin.Forms が MAUI という名前になって .NET 6 に統合されるという予定があります。
こちらは Windows アプリ開発 (ほかにも macOS, iOS, Android などもサポート) もサポート予定で VS Code での開発もサポートする予定なので 1 年後には普通に VS Code で Windows アプリ開発が出来るようになっていると思われます。

[.NET Multi-platform App UI (MAUI)](https://github.com/dotnet/maui)

## まとめ

ということで、今 Windows アプリ作るなら大人しく Visual Studio 2019 を入れて UWP or WPF or Windows Forms のプロジェクトを作るのが一番だと思います。

次点で、React Native for Windows あたり。
Ruby ①出力・変数・変数展開・if文(条件分岐)

>引用元　progate Rubyコース①

#Rubyとは
RubyはWEBアプリケーションの「システム」をつくるためのプログラミング言語

#出力方法

```Ruby
print "Hallo World!"
puts "Hallo World!" #+改行
p "Hallo World!" #デバック用
# Hallo World! Hallo World!
# "Hallo World!"
```
文字列にはクォーテーション（ ' もしくは " ）で囲むこと

```Ruby
puts 10
# 10

puts 10+20
# 30

puts "10" + "20"
# 1020
```
数値をクォーテーションで囲むと連結してしまう

```Ruby
+  # 足し算
-  # 引き算
/  # 割り算
%  # 割り算の余り
```

#変数
変数とは変数とは、値を入れておく箱のようなもの

```Ruby
name = "Mike"
puts name
# Mike
```

変数を使うのは、必ず変数を定義（変数名 = 値）した後でなければ使えない
puts "name"にした場合、nameと出力されるので注意

```Ruby
name = "Mike"
puts name + "です"
# Mikeです
```

・変数の更新

```Ruby
name = "Mike"
puts name
name = "John"
puts name
#John
```
後で代入された値で変数の中身が更新される

・変数の数値計算

```Ruby
number = 2
number = number + 3
puts number
# 5
```

省略化できる

```Ruby
number = 2
number += 3
puts number
# 5
```

#変数展開

```Ruby
name = "John"
puts "こんにちは #{name}さん"
# こんにちは Johnさん
```

ダブルクォーテーションで全体を囲むこと
シングルクォーテーションで囲むとそのまま文字列で出力されてしまう
基礎文法　"~#{変数名}~"

.変数展開のメリット
数値と文字列を足し算で連結することはできないため連結したいときに変数展開を使う

```Ruby
age = 18
puts age + "歳です"
# ERROR

age = 18
puts "#{age}歳です"
# 18歳です
```
#if文(条件分岐)

```
#基礎文法

if 条件式
　処理
end
```
条件が成立した時(true)に処理が実行される
endを忘れないこと

```Ruby
score = 95
if score > 90
　puts "よくできました！"
end
# よくできました！

score = 80
if score > 90
　puts "よくできました！"
end
# (何も表示されない)
```
比較演算子

```
 a > b  # aがbより大きい　→ true
a >= b  # aがbより大きい または　同じ → true
a <= b  # aよりbが大きい または　同じ → true
 a < b  # aよりbが大きい　→ true
a == b  # aとbが等しい時 → true
a != b  # aとbが等しくない時 → true
```