OmniAICreator/Qiita-1.07M huggingface dataset:
環境構築について



# Document Link

-   [マルチスケールシミュレーション特論まとめ](https://qiita.com/evendemiaire/items/25f459daa57ab8875ba6)


# 環境構築


## rubyとかもろもろ

-   Windows: ['wsl + emacs + ruby + qiita + git'](https://qiita.com/daddygongon/items/a376c66a6e7579601065)
-   Mac    : ['brew + emacs + rbenv + qiita + git'](https://qiita.com/nakagawa1017/items/b0ac953f3448a46899fb)
-   Linux  : 'emacs + ruby + qiita + git'

それぞれリンク貼ってるので(授業資料と同じ)，それでやってください．

Linuxユーザは．．．，まぁできるでしょ．


## Editor

エディタはemacs指定ですけど，vimでもnanoでも好きなの使ってください．(当方これを機にemacs勉強中)

有志の知恵を拝借

-   [Emacs教習所に行ってきた(チートシート付き)](https://qiita.com/namn1125/items/5cd6a9cbbf17fb85c740)
-   [突然だがEmacs を始めよう](https://qiita.com/bussorenre/items/bbe757ef87e16c3d31ff)


## my\_help(ユーザメモソフト)

my\_helpについての記事を発見

-   西谷研究室では，ユーザーメモソフトのmy\_helpが使用されている．
-   my\_helpを使用することで，ゼミのノート取りや，自身の課題などの進捗状況を，自分の言葉で書き込むことができている．などなど

詳しくは研究室生の書いた記事，或いは[my\_helpの使い方](https://github.com/daddygongon/my_help/blob/master/README.org)(現在リンク先の記事がおかしいため，Githubのリンクを貼付)を見てください．

install+settingについて

    $ gem install my_help
    $ my_help set_editor editor_name #(初期はemacs？)


## github

githubのアカウントを作成してください．

調べればできる．


## ssh

githubのRepositoryを自分のPCにCloneするために，今回はsshを使用するので(wgetでもええけど)，sshの鍵を作成してgithub側で設定．

こちらも有志の力を借りる．

-   [GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~](https://qiita.com/shizuma/items/2b2f873a0034839e47ce)

（記事内，$ ssh-keygen (-t rsa)は指定しなくてもいいかな）


## ruby\_docs

上記の設定ができていれば，あとはクローンするだけ．

Repositoryのruby\_docs内，画面のCodeのClone方法からsshを選択，アドレスコピーして，

    $ git clone [address]

で完了．

入力したディレクトリ内にruby\_docsがあるはず．


## qiita

qiitaのアカウントはgithubと連携できるので，それでSign inしてください．

qiitaへの記事の投稿には，org-modeの記事を投稿できるみたい．

-   [org-modeのテキストをqiitaに投稿するgemを作ってみた](https://qiita.com/yamatoken/items/858692178d288c40714d)

記事内にインストール方法や，qiitaでの設定など諸々書いてくれています．


# 締め

とりあえず，準備はこれくらいかな？

次回，[qiitaへの記事の投稿とgituhubへの共有について](https://qiita.com/evendemiaire/items/e9f8fc12ec62e82f5b7a)



------
 - **source** ~/school/multi/my_ruby/grad_members_20f/members/evendemiaire/post/build.org
【JavaScriptの超基本】コールバック関数について簡単に解説

#概要

この記事では、JavaScriptで少し理解が難しいコールバック関数について、超基本的な知識をメモ的にまとめています。
自分用の備忘録なのであしからず。




#目次
- [コールバック関数とは](#コールバック関数とは)
    - [JavaScriptは関数も値](#JavaScriptは関数も値)
    - [関数の呼び出し方と渡した方](#関数の呼び出し方と渡した方)
    - [引数で関数を定義する](#引数で関数を定義する)
    - [関数の引数](#関数の引数)
- [まとめ](#まとめ)




#コールバック関数とは

コールバック関数とは、どのような関数のことを言うのでしょうか。以下MDN web docsからの引用です。

>コールバック関数は他の関数に引数として渡される関数で、外側の関数で何らかの処理やアクションを実行します。
引用 : [Callback function (コールバック関数)](https://developer.mozilla.org/ja/docs/Glossary/Callback_function)

引数として渡される関数。。。

関数って引数で渡せるの？って感じで少しイメージが湧きにくいですね。

順序立てて解説していきます。




##JavaScriptは関数も値

コールバック関数について詳しくみていく前に、「**JavaScriptでは関数も値**」と言う話をします。

以前関数を定義する際に、定数に代入することができること(関数式)を学びました。
(関数について詳しくまとめている記事は[こちら](https://qiita.com/ta1fukumoto/items/981a0b766af17ed1a170)から)

これが意味していることを考えます。

結論から言うと、JavaScriptでは、関数を定数に代入できるため「**関数は値の一つとして扱うことができる**」と言うことです。
JavaScriptにおける関数は、文字列や数値、配列、オブジェクトと言った値と同じように値として扱えます。

よって、定数が引数として関数に渡されるように、関数もまた引数として渡されます。

まずはここを理解しましょう。




##関数の呼び出し方と渡した方

以下のコードを見ながら解説していきます。

```index.js
//関数introduceを定義
const introduce = () => {
    console.log('私の名前はたいちです');
};

//関数callを定義
const call = (callback) => {
    console.log('こんにちは！');
    callback();
};

//introduceをコールバック関数としてcallに渡す
call(introduce);

//以下、出力結果
//こんにちは！
//私の名前はたいちです
```

ここでは、`introduce`と`call`が関数として定義されています。
また、`introduce`は引数として`call`に渡されています。

関数を渡すときは、関数名の後ろに`()`は要りません。`()`がない場合は関数の定義そのものを指します。（関数名の後ろに`()`があると関数は呼び出されます。）

コールバック関数の流れとしては、まず引数として`introduce`が渡され、`call`が呼び出されます。
次に引数である`introduce`は`callback`に代入され、`call`内の処理に書かれてる`callback`に代入されます。コールバック関数を呼び出す際には、`()`をつけます。

この流れで処理が実行されます。

この例でわかるように、JavaScriptでは関数を引数に渡すことができます。そして、この引数になっている関数のことを**コールバック関数**と呼びます。




##引数で関数を定義する

前の例では、既に定義してある関数をコールバック関数として渡しましたが、関数を直接引数の中で定義することもできます。

```index.js
const call = (callback) => {
    console.log('こんにちは！');
    callback();
};

//引数の中で関数を定義
call(() => {
    console.log('私の名前はたいちです');
});

//以下、出力結果
//こんにちは！
//私の名前はたいちです
```

`introduce`に代入していた関数をそのまま`call`の引数として記述します。

このように直接定義することも可能です。




##関数の引数

コールバック関数には、普通の関数と同様に引数を渡すことができます。

```index.js
//コールバック関数に引数を渡す
const call = (callback) => {
    console.log('こんにちは！');
    callback('たいち');
};


call((name) => {
    console.log(`私は${name}です`);
});

//以下、出力結果
//こんにちは！
//私の名前はたいちです
```

一気にわかりにくくなりましたね笑
処理の流れを見ていきましょう。

まず関数`call`を定義しています。関数`call`は、コールバック関数`callback`を引数に取ります。

関数`call`を呼び出す際に、引数で直接``(name) => {console.log(`私は${name}です`);}``と言う関数を定義しています。
ここで定義されている関数は、引数に`name`を取ります。

では、この引数`name`はどこから渡されるかと言うと、関数`call`を呼び出した際に実行される`callback('たいち')`の部分で渡されます。

このような流れで処理が実行されます。

どこから値が渡されるのかわかりにくいので、難しいですね。




#まとめ

今回は、コールバック関数について簡単に解説してみました。コールバック関数は、非常に使用頻度が高めなのでしっかりと理解しておきたいところです。

最後まで読んでいただきありがとうございました。ではまた。
reactでhooksを使っているコンポーネントの呼び出す時のエラー

# エラー内容

- Warning: React has detected a change in the order of Hooks called by...
- Error: Rendered more hooks than during the previous render.

# 原因1

エラーにあるように、前回のレンダリングに比べてHooksの数が異なる

例えば以下の場合、１０回クリックするとHooksの数が１から２になってしまう

```tsx:10回クリックするとエラーになる
function App() {
  const [count, setCount] = useState(0);
  if (count < 10)
    return (
      <button type="button" onClick={() => setCount((count) => count + 1)}>
        count is: {count}
      </button>
    );

  const [] = useState(); // ダミー
  return <div>You clicked more than 10 times !</div>;
}
```

Hooksは関数の初めに定義しておく

```tsx:エラーにならない
function App() {
  const [count, setCount] = useState(0);
  const [] = useState();

  if (count < 10)
    return (
      <button type="button" onClick={() => setCount((count) => count + 1)}>
        count is: {count}
      </button>
    );
  return <div>You clicked more than 10 times !</div>;
}
```

# 原因2

関数形式でコンポーネントを呼んでいる

```typescript:hooksは使えない
return SomeComponent(someProps)
```

ちゃんとcreateElementをするか、jsxで記述する

```typescript:createElementを使う
import {createElement} from 'react';
...
return createElement(SomeComponent, someProps)
...
```

```typescript:jsxを使う
import React from 'react';
...
return <SomeComponent {...someProps} />
...
```
サーバのバックアップ

社員さんから、「共有フォルダのデータ削除してしまったのですが、復元できませんか。。。」と無理な依頼が来たので、対策の一つとしてファイルサーバをバックアップを取ることにしました。
ファイルサーバは、社内にあるオンプレミス型のファイルサーバなので、VMWareなどの仮想サーバのようにスナップショットが取れない為、batとタスクスケジューラで定期的なバックアップを取る仕組みにしています。

##バックアップbatの機能として必要な項目
ファイルをバックアップする為には、最低必要になるだろう項目をまとめてみました。
　・バックアップ保存先のフォルダには、バックアップをした日付を入れる。
　・実行結果のログを残す。
　・元フォルダからバックアップフォルダにコピーをする。
　・バックアップ保存先フォルダはバックアップを取らない。
　・1週間経過したら、ファイルを削除する。

本記事は、項目ごとに簡単にコード説明をしています。

##バッチのコード
必要な項目ごとのコード説明する前に全体のコードを先に記載します。
コードだけが必要だ！！の方は、ここと「4．1週間経過したら、ファイルを削除する。」だけを確認して欲しいです。


```bat:FileBackup.bat
rem 日付のｾｯﾄ
Set today=%date:~0,4%%date:~5,2%%date:~8,2%

REM ----ログファイルの作成----
Set Logfolder=%~dp0Log
md %Logfolder%
Set Logfile=%Logfolder%\FBU_%today%.log

REM ----コピー先の指定----
REM コピー先のフォルダ指定
set CopyFolder="コピー先フォルダ"
REM コピー先のフォルダ指定 日付付け
Set Copy1=%CopyFolder%\%today%
md %Copy1% | echo %Copy1%を作成しました。>> %Logfile%


REM ----フォルダーコピー----
For /d %%f in ("指定コピーフォルダ") do (
	if %%f neq “除外コピーフォルダ“ (
		set tergetCopy=%Copy1%%%f
		set tergetCopy=%tergetCopy:~4%
		REM コピーコマンド
		xcopy /D /S /R /Y /I /K %%f %Copy1%
		echo 『%%f』 → 『%Copy1%』 コピーしました。>> %Logfile%
	)
)

rem ----7日前の日付を取得----
call %~dp0Day.bat
echo %DT%です。
set DT=%CopyFolder%\%DT%
REM ----7日前のファイル削除----
For /d %%d in (%CopyFolder%\*) do (
	if %%d equ %DT%  (
		rd /s /q %%d|echo 2週間経過したため、「%%d」のファイルを削除しました。
	)
)

```

##１．バックアップ保存先のフォルダには、バックアップをした日付を入れる。
初めに変数でバックアップした日付を取得します。
この日付は、バックアップフォルダの格納フォルダ名になります。

```bat
rem 日付のｾｯﾄ
Set today=%date:~0,4%%date:~5,2%%date:~8,2%
```

##２．実行結果のログを残す
実行ファイルと同階層に「Log」フォルダを作成し、その中に簡易的な実行結果を記録されるようにしています。

```bat
REM ----ログファイルの作成----
Set Logfolder=%~dp0Log
md %Logfolder%
Set Logfile=%Logfolder%\FBU_%today%.log
```

##３．元フォルダからバックアップフォルダにコピーをする、バックアップ保存先フォルダはバックアップを取らない
『set CopyFolder="コピー先フォルダ"』で指定のバックアップ保存先フォルダを指定します。
『md %Copy1% | echo %Copy1%を作成しました。>> %Logfile%』では、パイプを使うことで保存先フォルダが作成できた際にログに残すようにしています。

```bat
REM ----コピー先の指定----
REM コピー先のフォルダ指定
set CopyFolder="コピー先フォルダ"
REM コピー先のフォルダ指定 日付付け
Set Copy1=%CopyFolder%\%today%
md %Copy1% | echo %Copy1%を作成しました。>> %Logfile%
```
今回除外フォルダが一つだけだったので、if文一つで指定の除外フォルダを指定していますが、
複数ある場合、その分if文を追加する必要があります。

フォルダ毎コピーする為『xcopy』を使用しています。
『echo 『%%f』 → 『%Copy1%』 コピーしました。>> %Logfile%』
はログ残しように追加した行だが、コピーが失敗しても表示される為、正直センスがないので省いても良いと思う。。。


```bat
REM ----フォルダーコピー----
For /d %%f in ("指定コピーフォルダ") do (
	if %%f neq “除外コピーフォルダ“ (
		set tergetCopy=%Copy1%%%f
		set tergetCopy=%tergetCopy:~4%
		REM コピーコマンド
		xcopy /D /S /R /Y /I /K %%f %Copy1%
		echo 『%%f』 → 『%Copy1%』 コピーしました。>> %Logfile%
	)
)
```
##４．1週間経過したら、ファイルを削除する。
1週間前の日付を取得し、その日付同じフォルダ名のバックアップフォルダを削除するようにしています。
ただ、月を跨ぐ日付の場合一癖ある為、下記のURLに掲載されていた「バッチで日付の操作」を参考に別batを作り、
callで7日前の日付データを取得するようにしています。
[ブログ（バッチもん研究所blog）](http://pachimon.life.coocan.jp/batch/date.html)

　
削除は、フォルダパスが完全一致な物を削除する為、**7日以上前のフォルダは削除することができません。**
しかし、毎日稼働するので問題が無いと考えています。


```bat
rem ----7日前の日付を取得----
call %~dp0Day.bat
echo %DT%です。
set DT=%CopyFolder%\%DT%
REM ----7日前のファイル削除----
For /d %%d in (%CopyFolder%\*) do (
	if %%d equ %DT%  (
		rd /s /q %%d|echo 2週間経過したため、「%%d」のファイルを削除しました。
	)
)
```

##最後に
コードの作り的に汚いところがあると思いますが、『誰かの参考に』、『今後の自分の参考に』と思いで書きました。
「ここをこのようにしたほうが良いよ」や「ここはいらないんじゃない」など、ご指摘頂ければとても嬉しいのですのでコメントして頂ければと思います。
Tomcatのバージョンを8.5.50から9.0.37に上げると、Embedded TomcatでAJPプロトコルが通らなかった時の対処方法

Tomcatのバージョンを8.5.50から9.0.37に上げたら、ApacheからのAJP通信が通らなくなった...。

```shell
$ docker exec -it apatche_container bash
$ vi /usr/local/apache2/logs/error_log_www.ginsara
[Mon Nov 09 13:11:30 2020] [error] (111)Connection refused: proxy: AJP: attempt to connect to 172.20.0.6:8009 (ap-front) failed
[Mon Nov 09 13:11:30 2020] [error] ap_proxy_connect_backend disabling worker for (ap-front)
[Mon Nov 09 13:11:30 2020] [error] proxy: AJP: failed to make connection to backend: ap-front
[Mon Nov 09 13:11:30 2020] [error] proxy: AJP: disabled connection for (ap-front)
```

[Tomcat 9.0.31からセキュリティ設定が必要になった](http://tomcat.apache.org/tomcat-9.0-doc/changelog.html#Tomcat_9.0.31_(markt))模様


> Rename the requiredSecret attribute of the AJP/1.3 Connector to secret and add a new attribute secretRequired that defaults to true. When secretRequired is true the AJP/1.3 Connector will not start unless the secret attribute is configured to a non-null, non-zero length String. (markt)

下記のようにsetSecretRequiredとsetAddressを追加すれば通信が通るようになる。

```
package jp.co.rex.wos.ginsara;

import org.apache.catalina.connector.Connector;
import org.apache.coyote.ajp.AbstractAjpProtocol;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Optional;

@Configuration
public class AppConfig {

  @Bean
  public WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletContainer() {
    // Set Embedded Tomcat configuration.
    return server ->
        Optional.ofNullable(server)
            .ifPresent(s -> s.addAdditionalTomcatConnectors(redirectConnector()));
  }

  private Connector redirectConnector() {
    Connector connector = new Connector("AJP/1.3");
    connector.setPort(9009);
    connector.setRedirectPort(8443);
    connector.setMaxParameterCount(20000);

    // 追加
    ((AbstractAjpProtocol) connector.getProtocolHandler()).setSecretRequired(false);

    InetAddress ip;
    try {
      ip = InetAddress.getByName("0.0.0.0");
    } catch (UnknownHostException e) {
      e.printStackTrace();
    }

    // 追加
    ((AbstractAjpProtocol) connector.getProtocolHandler()).setAddress(ip);
    return connector;
  }
}
```

## 参考

http://blog.onodera.asia/2020/04/apachetomcatsecretrequiredfalse.html
discord.pyのtimestampにはUTCを指定しなきゃいけないってお話

# 経緯
先日こんな質問を受けました。曰く、
> embedのタイムスタンプが、何故か9時間先に進んだ時刻になってしまう

と。
ちょっと検証してみましょう。

```py
from datetime import datetime

# 中略

embed = discord.Embed(title="hoge", description="fuga", timestamp=datetime.now())
await message.channel.send(embed=embed)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510912/763f47c3-769a-dff6-034e-f98855fb8753.png)

:thinking:確かにおかしいですね
今回はこの件についてまとめてみました。

# 解決法
解決法はいくつか在るので3つほど提示してみます。

## UTCでの時間を取得する
[datetime.utcnow Python公式ドキュメント](https://docs.python.org/ja/3/library/datetime.html#datetime.datetime.utcnow )

`datetime.utcnow`を用いてUTCでの時間を取得する方法です。
提示する方法の中で一番単純なのでこれをおすすめします。

```python

from datetime import datetime

# 中略

embed = discord.Embed(title="hoge", description="fuga", timestamp=datetime.now())
```
このコードを

```diff_python

- embed = discord.Embed(title="hoge", description="fuga", timestamp=datetime.now())
+ embed = discord.Embed(title="hoge", description="fuga", timestamp=datetime.utcnow())
```
このように変更すれば解決できます。(`timestamp=datetime.now()`を`timestamp=datetime.utcnow()`へ書き換えてください。)

## UTCでの時間を取得する(2)
[datetime.now Python公式ドキュメント](https://docs.python.org/ja/3/library/datetime.html#datetime.datetime.now )

`datetime.now()`は引数を指定しないとマシンのタイムゾーンでの現在時間を返しますが、タイムゾーンを指定して取得することもできます。
UTCの時間を渡してあげればいいので、引数に`timezone.utc`を渡してあげましょう。

```py
from datetime import datetime, timezone

# 中略

embed = discord.Embed(title="hoge", description="fuga", timestamp=datetime.now(timezone.utc))
await message.channel.send(embed=embed)
```
こんな感じ。

## 手動で時間を引いてみる
[datetime.timedelta Python公式ドキュメント](https://docs.python.org/ja/3/library/datetime.html#datetime.timedelta )

`datetime.timedelta`を使えば特定の時間から、特定の時間前や時間後のdatetimeオブジェクトを取得することができます。
例えばJSTならUTCから9時間進んでいるため、`datetime.now`から`datetime.timedelta(hours=9)`を引いてやればUTCに変換できます。

```py
from datetime import datetime, timedelta

#中略
JST_time = datetime.now()
UTC_time = JST_time - timedelta(hours=9)

embed = discord.Embed(title="hoge", description="fuga", timestamp=UTC_time)
await message.channel.send(embed=embed)
```

# 原因
[datetime.now Python公式ドキュメント](https://docs.python.org/ja/3/library/datetime.html#datetime.datetime.now )
> 現在のローカルな日時を返します。

と在るように、実行しているマシンのタイムゾーンでの現在時刻を返します。
しかしembedのtimestampは、UTCで時間が渡されることを想定しているようで、UTCをマシンのタイムゾーンに変換する処理をdiscordクライアント側が自動で行ってしまうようです。そのため、タイムスタンプが未来になってしまっていたという事ですね。
原因がわかれば解決は簡単です。最初に提示した方法を用いてみて、、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510912/b00e8717-abe8-e2cd-5300-78296ae5c4bb.png)
よし、ok！

# 最後に
今回は初めての試みとして、質問された内容を記事としてまとめてみました。
少しでもbot開発者の助けになったら幸いです。
RaspberryPi で castv2-client を使ってGoogleHomeをしゃべらす

HOYA提供のVoideTextが無料ではなくなりました。以下は備忘で残しておきますがもう使用できません。2025/04/04

# はじめに
これまでは google-home-notifier を使って RaspberryPi からGoogleHomeをしゃべらせていたのだが、RaspberryPi を構築しなおしたら全く動かん！色々調べてみたら動かない記事が沢山あって皆さん苦労しているようだ。castv2-client なるものでも GoogleHomeをしゃべらすことができるらしいのでやってみた。

# 環境
- RaspberryPi 3B
- GoogleHome (私のはminiです)
- 母艦(Windowsマシン。何でも良い)


## Raspberry Pi OS
RaspberryPiのインストールは済んでいるもとします。

```bash
~ $ cat /proc/device-tree/model
Raspberry Pi 3 Model B Rev 1.2

~ $ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 10 (buster)
Release:        10
Codename:       buster
```

[Raspberry Pi OS：Buster(2020-05-27-raspios-buster-armhf)] (https://qiita.com/nori-dev-akg/items/38c2dfb108edb0d73908)


## Node.js & npm
Node.js/npm が入っていなければインストール。

```bash
~ $ sudo apt-get update
~ $ sudo apt-get upgrade
~ $ sudo apt-get install -y nodejs npm
~ $ sudo npm install n -g
~ $ sudo n stable
# ターミナルを一旦再起動する PATHが再設定される※
~ $ logout

~ $ npm -v
6.14.8
~ $ node -v
v14.15.1

```

ちょっと古い node が入ると思うんで ```sudo n stable``` で 上げた。
v10.21.0 → v14.15.1
*※バージョンが上がっていない場合は ターミナルを再起動すること*

# VoiceText Web API
文字列を合成音に変えてくれるTTS(TextToSpeech)エンジン。
google-tts-api は発声が遅くてよろしくないが VoiceText はクリアでとっても良い！

VoiceText は無料だがAPIキーが必要。メールアドレスだけで取得できる。
[VoiceText Web API](https://cloud.voicetext.jp/webapi)

# モジュールの取得
今回作成したモジュールをgithubに上げてあるので取得する。
https://github.com/nori-dev-akg/castv2-googlehome

```bash
~ $ git clone https://github.com/nori-dev-akg/castv2-googlehome
~ $ cd castv2-googlehome #カレントを移動しておく
~/castv2-googlehome $ npm init --yes #作業用ディレクトリ初期化
#以降、作業用ディレクトリで行う
```

# ライブラリモジュールのインストール
- castv2-client
- voicetext
- express fs
- forever

```bash
~/castv2-googlehome $ npm install voicetext castv2-client express fs
#foreverは sudo でグローバルへ入れておく
~/castv2-googlehome $ sudo npm install -g forever
```
# 設定
api.js は常に実行させておく必要があるので forever する。

```bash
~/castv2-googlehome $ forever start api.js
```

speech.js ファイルを修正する。

- RaspberryPi のIPアドレス
- GoogleHome のIPアドレス
- VoiceText APIキー
- speaker：任意
- 発声テキスト：任意

~/castv2-googlehome/speech.js

```js
const Castv2GoogleHome = require('./castv2-googlehome.js');

const rapsberrypi_ip = '192.168.0.31';
const googlehome_ip = '192.168.0.200';
const voicetext_key = 'xxxxxxxxxxxxx';

const c2gh = new Castv2GoogleHome(rapsberrypi_ip, googlehome_ip, voicetext_key);

// speaker: 'show', 'haruka', 'hikari', 'takeru', 'santa', 'bear'
c2gh.speech('こんにちは。私はグーグルホームです', 'haruka');

```
# しゃべらせてみる
```bash:
~/castv2-googlehome $ node speech.js
```

GoogleHomeから「こんにちは。私はグーグルホームです」と聞こえれば完成！
上記では haruka にしていますが、hikari の方がイントネーションは良いように思われます。「ホ」の部分。show は例の声ですｗ。

# おわりに
モジュール化したので汎用的に使えると思う。
VoiceText の API キーを取得するという手間があるが、「モヤさま」の showくん の声が聞けるのでそれだけの価値はあるかとｗ。
AnsibleでCentOS 8にAmazon Corretto 8をインストールする時の書き方。

下記[Amazon Corretto 8をインストールするコマンド](https://docs.aws.amazon.com/ja_jp/corretto/latest/corretto-8-ug/generic-linux-install.html)をAnsibleで実行したい。

```
$ sudo rpm --import https://yum.corretto.aws/corretto.key
$ sudo curl -L -o /etc/yum.repos.d/corretto.repo https://yum.corretto.aws/corretto.repo
$ sudo yum install -y java-1.8.0-amazon-corretto-devel
```

下記のように書けばインストール出来る。

```playbooks/roles/server/tasks/main.yml
- name: Import rpm key.
  rpm_key:
    key: https://yum.corretto.aws/corretto.key

- name: Add corretto repository.
  yum_repository:
    name: corretto
    description: "Amazon Corretto repository"
    baseurl: https://yum.corretto.aws/$basearch

- name: Install Amazon Corretto 8.
  yum:
    name: java-1.8.0-amazon-corretto-devel
    state: present
    enablerepo: corretto
```

インストール確認

```
$ docker exec -it server_container bash
[root@target /]# java -version
openjdk version "1.8.0_275"
OpenJDK Runtime Environment Corretto-8.275.01.1 (build 1.8.0_275-b01)
OpenJDK 64-Bit Server VM Corretto-8.275.01.1 (build 25.275-b01, mixed mode)
```

baseurlとenablerepoの設定に気が付かず、多少ハマった。
また、CentOS 8内部では、yumではなく[dnfが動いている様子](https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/facts/system/pkg_mgr.py#L94)。
タダ飲みコーヒー

#[Ruby] タダ飲みコーヒー
#問題
・コーヒーをお買い上げした際に、次のお買い上げの値段を更に P% off!
・毎回の値下げにおいて小数点以下切り捨て

あなたは値下げが累積する事に目をつけました。
コーヒーを何回も飲んでいれば、タダでコーヒーを飲めるようになるのです。
タダで頼みたいあなたは、何円払えば以後タダで注文できるのか計算したくなりました。
実際にプログラムを書いて計算してみましょう。
#入力される値
入力は以下のフォーマットで与えられます。

X P
・コーヒーの価格を示す整数 X と 割引き率を示す整数 P が、この順に半角スペース区切りで与えられます。
・入力は 1 行となり、末尾に改行が 1 つ入ります。
#期待する出力
以後タダで注文するのに必要な金額を出力してください。
#入力例1
300 50
#出力例1
596
#入力例2
1000 99
#出力例2
1010
#私の答え
```java:
a,b = gets.split(' ').map(&:to_i)
s = 100 - b
int = a
while a.floor > 0 
    a = (a*s/100).floor
    int += a
end

puts int
```
##このコードはほぼ丸パクリしたのですがなるほどという感じです。while文の中身は説明できませんが、a変数(floor)が0になるまで繰り返しているのでしょう。繰り返し文が苦手だという事が分かりました。
#以上！悔しい
Rubyのお勉強＜変数とMethod＞



# Document Links

-   [マルチスケールシミュレーション特論まとめ](https://qiita.com/evendemiaire/items/25f459daa57ab8875ba6)
-   [チャート式ruby-II(variable and method)](https://qiita.com/daddygongon/items/c51f3e0695174bb3c508)


# 変数

受けとった引数ARGV[0]を適当な変数に代入して出力せよ．

前回もそれっぽいことした気が&#x2026;

```ruby
name = ARGV[0]
puts name       #puts "#{name}"でも可
```

実行結果

    $ ruby name.rb Dora
    Dora

~~RubyではPython同様，変数の型宣言は必要なくて，文脈に合わせて適当に定められる（楽〜）．~~

＊上記についてコメントをいただいた．

正確にはRuby の変数は，「型宣言が必要ない」のではなく「型を持たない」のである．

ローカル変数，インスタンス変数，グローバル変数だけでなく，

-   定数
-   メソッドの仮引数
-   ブロックのブロックパラメータ

も型を持たない．

数字の計算がしたいなら，

```ruby
num = ARGV[0].to_i
sum = num + num
puts sum
```

実行結果

    $ ruby name.rb 1
    2


# Method

function(関数)やprocedure(手順)などのまとまりはmethodを定義することになる．

例えば，

```ruby
def name(moji1,moji2)
    puts "#{moji1} #{moji2}"
end

hoo1 = "hello"
hoo2 = "world"
name(hoo1,hoo2)
```

実行結果

    $ ruby def.rb
    hello world

キーボードから文字を受け取りたかったら，

```ruby
def name(moji1,moji2)
    puts "#{moji1} #{moji2}."
end

hoo1 = ARGV[0]
hoo2 = ARGV[1]
name(hoo1,hoo2)
```

実行結果

    $ ruby def.rb hello world
    hello world.

詳しくは前回の記事を見るのじゃ．[Rubyのお勉強＜入出力編＞](https://qiita.com/evendemiaire/private/fc2d94179d0384ca4d55)


# 締め

今回は変数とmethodについて学んだ．

次回，[条件処理＜Ifとか＞](https://qiita.com/evendemiaire/items/4f9550981bd3d6017cdd)



------
 - **source** ~/school/multi/my_ruby/grad_members_20f/members/evendemiaire/post/var_met.org
Rubyのお勉強＜入出力編＞



# Document Links

-   [マルチスケールシミュレーション特論まとめ](https://qiita.com/evendemiaire/items/25f459daa57ab8875ba6)
-   [チャート式ruby-I(puts)](https://qiita.com/daddygongon/items/1b0f0ff3fb9d60418289)


# Rubyのお勉強＜入出力編＞


## 出力編

とりあえず，出力させますか．

まぁ，おなじみ"print("Hello World")"ですか？

```ruby:print.rb
print("Hello World")
```

実行結果

    $ ruby print.rb
    Hello World$

改行されない．．．

調べると，Rubyの出力方法はいろいろある．

| method |                       |
|:-------|:----------------------|
| print  | 引数に指定した値を出力|
| puts   | 引数に指定した値を出力(自動改行)|
| p      | 値と共に型情報を出力(debugに使える)|
| printf | 書式を指定して出力(Cと同じ)|

他にも，"pp"とか"sprintf"とかあるみたい．

"puts"を試してみる．

```ruby:puts_hello_world.rb
puts "hello world"
```

実行結果

    $ ruby puts.rb
    Hello World
    $ 

改行されている．

調べていると，

```ruby
print "Hello World"
puts "Hello World"
```

と全員書いている．．．，python2系の書き方でも大丈夫みたい(むしろそっちが主流？)．


## 入力編

次は入力編です．

入力方法を調べてみる．

| method         |                          |
|:---------------|:-------------------------|
| ARGV[引数番号] | ruby code.rb 引数        |
| gets()         | キーボードから取得(文字列)|
| gets.to\_i()   | キーボードから取得(整数) |
| gets.to\_f()   | キーボードから取得(浮動小数点)|

"gets()"は丸括弧あってもなくても大丈夫

実際に使ってみる．

-   ARGV[]

```ruby:ARGV.rb
puts "Hello #{ARGV[0]}"
print "#{ARGV[1]}#{ARGV[2]}\n"
```

実行結果

    $ ruby ARGV.rb World 今日は 水曜日
    Hello World
    今日は水曜日 

-   gets()

```ruby:gets.rb
moji = gets()
puts "moji:#{moji}"
```

実行結果

    $ ruby gets.rb
    Hello World
    moji:Hello World

~~ちなみにARGV[]とgets()の併用は駄目みたい~~

＊コメントで指摘をいただいた．

-   *gets()に引数を指定すると標準入力からの文字列取得ではなくなる*

**併用が原因ではない**

ARGV[]とgets()を併用したいなら，

```ruby:ARGV_gets.rb
puts "Hello #{ARGV[0]}"
moji = STDIN.gets()
puts "moji:#{moji}"
```

出力をtxtなどに保存したい場合

    $ ruby gets.rb > out.txt
    Hello World
    $ cat code.txt
    Hello World


# 締め

基礎の入出力についてお勉強．

次回，[変数とかmethodについて](https://qiita.com/evendemiaire/items/8d6bfc813a1ce5534b02)



------
 - **source** ~/school/multi/my_ruby/grad_members_20f/members/evendemiaire/post/ruby_put.org
Rubyのお勉強＜制御構造_Ifとか＞



# Document Links

-   [マルチスケールシミュレーション特論まとめ](https://qiita.com/evendemiaire/items/25f459daa57ab8875ba6)
-   [チャート式ruby-appendix-III(bundler)](https://qiita.com/daddygongon/items/14218c96df5cbcf35c62)
-   [チャート式ruby-III(if, case, array, each by leap year)](https://qiita.com/daddygongon/items/a550bde1ed6bff5217d8)


# bundler

Rubyの制御構造に入る前に．．．

講義資料にもあるがbundlerがなんとかかんとか．．．

説明できるほどはわからないので，詳しくは講義資料を見てください．


# if-elsif-else-end

[Rubyリファレンスマニュアル](https://docs.ruby-lang.org/ja/index.html)でif文の文法は，

```ruby
if 式 [then]
  式 ...
[elsif 式 [then]
  式 ... ]
...
[else
  式 ... ]
end
```

と記述されている．


## 閏年判定(単年)

もし閏年なら"true"を返すようにするには，

```ruby
p year = ARGV[0].to_i

if year % 4 == 0
  p true
end
```

実行結果

    $ ruby check_leap.rb 2004
    2004
    true

では，閏年以外なら"false"を返すようにするなら，

```ruby
p year = ARGV[0].to_i
if year%4 == 0
  p true
else
  p false
end
```

実行結果

    $ ruby check_leap.rb 1999
    1999
    false

閏年の条件は４年に一度だけじゃないみたい，

-   西暦年号が4で割り切れる年をうるう年とする．
-   西暦年号が100で割り切れて400で割り切れない年は平年とする．

では，その条件も含めると，

```ruby
p year = ARGV[0].to_i
if year%400 == 0
  p true
elsif year%100 == 0
  p false
elsif year%4 == 0
  p true
else
  p false
end
```

実行結果

    $ ruby check_leap.rb 1900
    1900
    false
    $ ruby check_leap.rb 2000
    2000
    true


## 閏年判定（複数年）

複数年を判定するときに何度も打つのが面倒なら，配列にしてloop回すだけ．

```ruby
[2004,1999,1900,2000].each do |year|
  p year
  if year%400 == 0
    p true
  elsif year%100 == 0
    p false
  elsif year % 4 == 0
    p true
  else
    p false
  end
end
```

実行結果

    $ ruby check_leap_year.rb
    2004
    true
    1999
    false
    1900
    false
    2000
    true

判定部分をmethodにしますか，

```ruby:check_leap_year.rb
def leap?(year)
  if year % 400 ==0
    p true
  elsif year % 100 ==0
    p false
  elsif year % 4 == 0
    p true
  else
    p false
  end
end

[2004,1999,1900,2000].each do |year|
  p year
  leap?(year)
end
```

＊コメントで指摘していただいたので修正する．

講義資料にも書かれていたが，

-   true falseを返して，main loopでpする方がいいです．

とのこと，なので，

```ruby:check_leap_year2.rb
def leap?(year)
  if year % 400 ==0
    true
  elsif year % 100 ==0
    false
  elsif year % 4 == 0
    true
  else
    false
  end
end

[2004,1999,1900,2000].each do |year|
  p year
  p leap?(year)
end
```

詳しくはコメント欄で，非常に丁寧な解説をしていただいています．


# case

[Rubyリファレンスマニュアル](https://docs.ruby-lang.org/ja/2.5.0/doc/index.html)のif文の下の方に，caseについて載っている．

caseを使って，より美しくするなら，

```ruby:check_leap_year_case.rb
def leap?(year)
  case
  when year % 400 ==0 ; true
  when year % 100 ==0 ; false
  when year % 4 ==0 ;   true
  else ;                false
  end
end

[2000, 1900, 2004, 1999].each do |year|
  p year
  p leap?(year)
end
```

てな感じにもできるみたい．


# 締め

今回は条件処理について学んだ．

次回，[Rakeで自動化&Export](https://qiita.com/evendemiaire/items/4dbcfb1819fc23ac8ba9)



------
 - **source** ~/school/multi/my_ruby/grad_members_20f/members/evendemiaire/post/if_case.org
CakePHP 複数レコードを一括保存するsaveAllの使い方

ビュー

```form.ctp
echo $this->Form->create ( 'User', array (
    'type' => 'post',//POSTとGETの設定
    'controller' => 'users',//コントローラーの設定
    'action' => 'edit',//アクションの設定
) );
 
echo $this->Form->input ( 'User.0.name.');
echo $this->Form->input ( 'User.0.age');
 
echo $this->Form->input ( 'User.1.name');
echo $this->Form->input ( 'User.1.age');
 
 
echo $this->Form->input ( 'User.2.name');
echo $this->Form->input ( 'User.2.age');
 
echo $this->Form->end('送信');
```

$this->request->data;の中身

```.php
$data = array(
	'User' => array(
		0 => array(
			'name' => '太郎',
			'age' => 10
		),
		1 => array(
			'name' => '花子',
			'age' => 8
		),
		2 => array(
			'name' => '二郎',
			'age' => 5
		),
	)
);
```

$data["User"]というように$dataの後ろにモデル名を指定するところがポイントです。

```.php
$this->User->saveAll($data["User"]);
```
jQuery 備忘録

・js側で値の受け渡し方法

```html:index.html
<form id="modal-form">
　<input type="hidden" id="modal-value-1" /> //値を入れたいhidden
</form>
<input type="text" id="modal-input-1" name="data[User][name]" /> //値を受け取るinput
```

```javascript:index.js
var inputVal = $("#̲modal-input-1").val(); //一度変数に受ける
$("#modal-value-1").val(inputVal);
```
***

data属性を使って値を設定すれば、あらゆることに利用できる。

```html:form.html
<button class="add mon" data-daynum="1">
<button class="add tue" data-daynum="2">
<button class="add wed" data-daynum="3">
.....
```

```javascript:form.js
$(document).on("click", "クラス名", function(){
　let daynum = $(this).attr("data-daynum"); //daynumに曜日番号が入る
　以下いろいろな処理
});
```
Spring開発環境構築 For Mac

#はじめに
Springの開発環境の構築方法をまとめました。
流れは以下になります。

①STSのインストール
②Pleiadesのインストール
③Lombokのインストール
#STS(Spring Tool Suite 4)のインストール
[STSダウンロードサイト](https://spring.io/tools "Lombokダウンロードサイト")にアクセスします。
Spring Tools 4 for Eclipseの欄から「4.8.0-MACOS 64-BIT」をクリックしてください。
※バージョンは2020年10月時点で最新の4.8.0を利用します。
するとSTSが入ったzipファイルのダウンロードが始まります。
![スクリーンショット 2020-10-19 23.43.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703431/fd20f3b0-5c7c-13af-eaa6-4a89b7b7e408.png)
ダウンロードしたzipファイルを解凍します。
以下の画面が表示されたらSpringToolSuite4.appをApplicationsファイルにドラッグアンドドロップしてください。
![スクリーンショット 2020-10-20 0.58.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703431/5ec0222b-a42f-3eec-9170-c1b5ce178e38.png)
以上でインストール完了です。

#Pleiadesのインストール
STSに日本語化プラグインを入れます。
[Pleiadesダウンロードサイト](https://mergedoc.osdn.jp/ "Pleiadesダウンロードサイト")にアクセスします。
![スクリーンショット 2020-10-20 1.14.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703431/c8224bf1-c640-5edc-149f-10d3d802b219.png)
Pleiades プラグイン・ダウンロードからMacOSをクリックし、Preparing to download Eclipse Pleiades pluginの下のリンクからzipファイルをダウンロードします。
zipファイルを解凍し、setup.appを起動（クリック）します。
※「“setup.app”は、開発元を検証できないため開けません。」とエラーが出た場合は以下の記事を参照してみてください。
https://github.com/ko-ichi-h/khcoder/issues/100
以下の画面が表示されたら「選択」をクリックしてアプリケーションファイルに移したSTSを選択します。
![スクリーンショット 2020-10-20 3.08.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703431/1ce5133b-3bc2-3e13-94b0-28e7cb5ac54f.png)
「日本語化する」をクリックします。
以上でインストール完了です。

#Lombokのインストール
Lombokとは、setterやgetterを自動的に実装してくれる便利ツールです。
現場でよく使われるらしいので、入れておきましょう。
[Lombokダウンロードサイト](https://projectlombok.org/download "Lombokダウンロードサイト")にアクセスします。
ダウンロードしたlombok.jarを/Applications/SpringToolSuite4.app/Contents/MacOSにコピーします。
lombok.jarを起動し、Specify location...をクリックします。
/Applications/SpringToolSuite4.app/Contents/Eclipse/にあるSpringToolSuite4.iniを選択します。
![スクリーンショット 2020-10-20 3.28.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703431/0813cc23-e54f-026c-59e4-617bf10d3623.png)
「install/Update」「Quit Installer」と順にクリックします。
インストールが完了すると、STSのフォルダ内にlombokが入ります。
以上でインストール完了です。
TermuxでVSCode Remote

# TermuxとVSCodeとprootとUbuntu

TermuxはAndroidにaptとターミナルをつけてくれるが、仮想環境ではない。libcはbionicだったりする。そのためVSCodeのリモート接続が使えない。

Termux内にUbuntuの仮想環境を入れるにはproot。具体的な方法はいろいろあるらしいが、今回はUbuntu-in-Termuxを使った。

[https://github.com/MFDGaming/ubuntu-in-termux](https://github.com/MFDGaming/ubuntu-in-termux)

# しかし、Ubuntuのsshdがうまくいかない

Ubuntuの仮想環境内で`apt install -y openssh-server`して、（Androidが非root端末なら）ポート番号を1024以上にして、sshdを立ち上げれば、Ubuntuの仮想環境のシェルに入れるはず、なのだが入れない。認証は通るが、リモートのシェルとつながらない。原因究明は諦めた。

# 回避策：Termux側の`sshd_config`でprootを設定する

`$PREFIX/etc/ssh/sshd_config`を編集して、以下の1行を末尾に追加する。

```
ForceCommand /data/data/com.termux/files/home/ubuntu-in-termux/startubuntu.sh
```

sshdを立ち上げ直せば、VSCodeのリモート接続はUbuntuの仮想環境とつながる。
[CSS]画像の上にグラデーションフィルター

カードデザインやセクションの背景に、画像＋グラデーションフィルターを敷きたいときの備忘録です。


# 手順
1. 「background-image:url()」の前後どちらかに「,」区切りで`linear-gradient(グラデーションの方向,  開始色, 終了色);`をプロパティを追加して色を設定する
2. `background-blend-mode: screen;`をプロパティを追加してブレンドする

※ [linear-gradient(グラデーションの方向,  開始色, 終了色);をもっと知りたい方はこちら](https://qiita.com/nakamurashun0621/items/c0de710233a5a351d984)

# 加工前
![スクリーンショット 2020-11-18 12.37.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825124/f9e6b21a-0078-ad93-aa7b-ae8186e4e84c.png)


```html
<!-- 画像部分のみ抽出 -->

<div class="card__picture">
   <div class="card__imge"></div>
</div>                                                        
```

```css
/* ------- 画像 スタイル ------- */

.card__picture{
    width: 500px;
    height: 250px;
}

/* 画像の設定 */
.card__imge{
    height: inherit;
    background-image: url(../img/coverSample.jpg);
    background-size: cover;
    background-position:center;
    background-repeat: no-repeat;   
}
```



# 加工後
![スクリーンショット 2020-11-18 12.47.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825124/d42f4269-2af5-26a5-7d36-f226ee8f2777.png)

```css
/* ------- 画像 スタイル ------- */

.card__picture{
    width: 500px;
    height: 250px;
}

/* 画像の設定 */
.card__imge{
    height: inherit;
    background-image:url(../img/nat-1-large.jpg), linear-gradient(to right,  red, blue); /* 一部追加 */
    background-size: cover;
    background-position:center;
    background-repeat: no-repeat;
    background-blend-mode: screen; /* 追加(継承するため親要素に当ててもOK) */
}
```

# おまけ(部分グラデーション)
後半に出てくるサンプルBはWEBデザインでものよく出てくるため、CSSで書いた方が保守性アップ。
また、上記もそうだが`１つのdivタグ、1つのセレクタで背景画像＋変形フィルターができるのでソースもすっきり。`

事前知識
[linear-gradient(グラデーションの方向,  開始色, 終了色);をもっと知りたい方はこちら](https://qiita.com/nakamurashun0621/items/c0de710233a5a351d984)

### 手順
1. 全体の何％にグラデーションにするかを決める。
2. その％で色を分配し、色の後に`transparent 0%`を記述。

サンプルを見た方が早いので以下参照。

### サンプル
サンプルA(２色グラデーション)

```css
/* 画像の設定 */
.card__imge{
    height: inherit;
    background-image:url(../img/nat-1-large.jpg), linear-gradient( purple 25%,blue 50%, transparent 0%);
    background-size: cover;
    background-position:center;
    background-repeat: no-repeat;
    background-blend-mode: screen;
}
```

![スクリーンショット 2020-11-18 17.37.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825124/026c6115-aa53-0656-5d71-118c190cd484.png)

サンプルB(1色ななめ)

```css
/* 画像の設定 */
.card__imge{
    height: inherit;
    background-image:url(../img/nat-1-large.jpg), linear-gradient(120deg,green 50%, transparent 0%);
    background-size: cover;
    background-position:center;
    background-repeat: no-repeat;
    background-blend-mode: screen;
}
```
![スクリーンショット 2020-11-18 17.39.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825124/a65ce217-d410-a926-894e-4483b6e4424f.png)


# 参考記事
background-blend-modeはプロパティ値によって様々な加工モードが存在し、手軽に印象を変化さることができます。(詳細は以下参照)
https://www.webcreatorbox.com/tech/css-blend-mode

# 次回
[[CSS]background-image:linear-gradient();で背景グラデーション/複数色で区切る/文字グラデーションの３パターン](https://qiita.com/nakamurashun0621/items/c0de710233a5a351d984)
React@16以降のref(createRef)でのtypescriptの書き方 備忘録

#Reactv16以降のref

typescriptでrefを使う際に悩んだので備忘録として残す

## 昔の書き方

以前のrefはこんな感じに書いていた（多分）

```tsx

export class SampleComponent extends React.Component<Props, State> {
  private inputElement: HTMLInputElement
  constructor(props: Props) {
    super(props);
    this.inputElement = ""
  }
  render(){
    return(
      <input ref={input => this.inputElement = input} />
    )
  }
}
```


## 最近の書き方

Reactv16以降での新しい `createRef` をしようした場合
RefObjectに型を入れることでチェックできる


```tsx
import * as React from 'react';

export class SampleComponent extends React.Component<Props, State> {
  private inputElement: React.RefObject<HTMLInputElement>
  constructor(props: Props) {
    super(props);
    this.inputElement = React.createRef();
  }
  render(){
    return(
      <input ref={this.inputElement} />
    )
  }
}
```


まぁ、あんまりrefは使いたくないのが本音だけど、
現場によっては使っているので対応が必要
Failed to load OVRPlugin.dll

##OculusQuest2をUnityの新しいバージョン2020で動作させようとしたらUnityがクラッシュして、はまったので忘れない様メモ。
　Failed to load OVRPlugin.dll　
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232643/bfa5e269-3eb7-8bb7-e223-ad7dfa335798.png)
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232643/9412056d-b55a-8b9e-92fe-883f528d9f25.png)


##やりたかったこと
・OculusQuest2をUnityの新しいバージョン2020で利用したい


###制作環境
・OculusQuest2
・Unityバージョン2020(2020.1.9f1)で利用したい
・Windows
・OculusLinkで接続


--

###その流れと状態
開発環境の構築は割愛しますが、、、手順を一応
・Build Settingsして
・Player Settingsして
　Company Name--->XR-Plugin設定が終了した後くらいまでは大丈夫。

・Oculus  Integration入れたあとの
・ポップアップのプラグインアップデートから再起動すると、、、

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232643/c2cf3b15-bc18-8491-d97c-7db4aab94456.png)


これがでる。まだ何もしていないいのに。。
Failed to load OVRPlugin.dll
UnityEngine.Debug:LogError(Object)
Unity.XR.Oculus.OculusLoader:EditorLoadOVRPlugin() (at Library/PackageCache/com.unity.xr.oculus@1.5.0/Runtime/OculusLoader.cs:189) 

###発生している人たちは、、、
・同環境でもこの現象が起こっている人少ない
・よって、解決策がググってもない感じ

###色々調べてみた結果
・開発環境の構築手順--->正しい
・各種バージョンの問題（OculusIntegration、Oculus XR）--->でもなさそう

##色々やってみた結果
下図の通りです。。
プロジェクトを作成する場所に日本語が入っているのが原因でした。なんだそんな事かと。
Cドライブ直下にプロジェクトを置くと解決しました。
でもOculusQuest1でUnity2019バージョンで作成したプロジェクトは、ドキュメントフォルダ直下でも問題無く現在も稼働しているので突然なんで？？ってなってる人いるかも。

![キャプチャ01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232643/8d55a9ee-f106-1ea6-8c2c-3aa23f258628.jpeg)
ファイルまたはディレクトリが壊れているため、読み取ることができません

　この記事では、「にアクセスできません。<a href="https://jp.bitwar.net/howto/windows/2633.html">ファイルまたはディレクトリが壊れているため</a>、読み取ることができません。」という問題を修復する4つの方法を紹介します。

　「ファイルまたはディレクトリが壊れているため、読み取ることができません。」は、SDカード、ハードドライブ、外部ハードドライブ、フラッシュドライブなどの外部ストレージデバイスで発生する典型的なWindowsエラーです。このエラーが発生すると、ハードドライブデバイスにアクセスできなくなり、そのデバイス上のデータを使用および処理できなくなります。したがって、この問題を解決する必要があります！


　<b>「ファイルまたはディレクトリが壊れているため、読み取ることができません」の原因</b>


　論理的問題と物理的問題の両方が原因で、ファイルまたはディレクトリが破損して読み取り不能になる可能性があります。


      ●ハードドライブの安全でない取り出し

      ●停電

      ●RAWファイルシステム

      ●ウイルスまたはマルウェアの攻撃

      ●物理的な損傷


　「ファイルまたはディレクトリが壊れているため、読み取ることができません。」エラーを解決する前に、まず間違ったデバイスの正中線からすべての貴重なファイルを回復できることを知っています。次に、このエラーを修正します。


<b>紛失または到達不能なファイルを最初に回復する</b>

　現在最も信頼性の高いファイル回復ソフトウェアであるBitwar Data Recoveryを使用してファイルをレスキューします。使いやすいウィザードインターフェイスを備えており、コンピューターの操作に慣れていない場合でも、削除、誤ったフォーマット、または失われたファイルデータを簡単に回復できます。 。以下のボタンをクリックして、この使いやすいソフトウェアをダウンロードしてインストールするか、https://jp.bitwar.net/data-recovery-software/の公式Webサイトからダウンロードしてインストールできます。

　「ファイルまたはディレクトリが壊れているため、読み取ることができません。」を修正するソリューション


<b>解決策1：ディスクを再マウントしてエラーを修正する</b>

　ステップ1：「ディスクの管理」に進み、エラーエラーのあるドライブを見つけ、ディスクを右クリックして「アンインストール」オプションを選択します。
　ステップ2：ディスクをアンインストールした後、ハードウェア変更のスキャンをクリックして、再インストールのために、アンインストールまたはアンインストールされたドライブのあるドライブを検出します。
　ステップ3：ここで、コンピューターを再起動し、ドライブに再度アクセスしてみます。

<b>解決策2：ディスクチェックを実行して問題を解決する</b>


ステップ1：フォルダー内の破損したドライブを検索し、[コンテンツ]を選択します。
ステップ2：[ツール]タブを選択し、[エラーのチェック]の[チェック]ボタンをクリックします。このオプションを適用して、ドライブのエラーを確認できます。
ステップ3：次に、「ドライブのスキャン」をクリックして、影響を受けるドライブのディスクチェックを実行します。

<b>解決策3：ドライブをフォーマットしてエラーを修正する</b>

ステップ1：コンピューターの検索ボックスに「diskmgmt.msc」と入力して、[ディスクの管理]を開きます。
ステップ2：破損したパーティションを見つけてマウスで右クリックし、「フォーマット」を選択します。
ステップ3：開いた新しいウィンドウで、ファイルシステム、ボリュームラベル、クラスターサイズなどの情報をカスタマイズし、[OK]をクリックしてフォーマットプロセスを開始します。


<b>解決策4：デバイスを再接続してエラーを修正する</b>

　「ファイルまたはディレクトリが破損しており、読み取ることができません」というエラーが発生した場合は、再起動後にWindowsを再起動して修復を試みてください。内蔵ドライブが障害を引き起こしている場合は、まずシステムをシャットダウンしてから、マザーボードとHDDを接続しているすべてのケーブルを外し、検査のためにワイヤーを再接続することをお勧めします。

　詳しくは、「<a href="https://jp.bitwar.net/howto/windows/2633.html">4つの修復方法「ファイルまたはディレクトリが壊れているため、読み取ることができません</a>」をご参照ください。
Warning: Unrecognised configuration nameとなった時の対応方法


# 事象 : 言語で日本語を指定したら怒られた
- 環境
    - Windows10 64bit バージョン1909
    - Python 3.8.5
    - mkdocs, version 1.1.2

```bash
$ mkdocs build
WARNING -  Config value: 'language'. Warning: Unrecognised configuration name: language
INFO    -  Cleaning site directory
INFO    -  Building documentation to directory: C:\path\to\mkdocs\docs\site
INFO    -  Documentation built in 0.19 seconds
(mkdocs)
```

参考 : [Configuration - MkDocs](https://mkdocs.readthedocs.io/en/stable/user-guide/configuration/#lang)

```yml
# ...省略...
theme:
  name: 'rtd-dropdown'
language: ja
# ...省略...
```

## 原因 : インデントがない
参考 : [プロジェクトドキュメント構築向け静的サイトジェネレータ『MkDocs』及び『Material for MkDocs』の個人的導入＆設定まとめ | Developers.IO](https://dev.classmethod.jp/articles/mkdocs-and-material-for-mkdocs-tips-matome/#toc-10)

`theme`の下の階層で指定するようだ・・・いまいちどの下の階層に設定するとかがわからない。


### 対応 : 階層を下げる

```yml
# ...省略...
theme:
  name: 'rtd-dropdown'
  language: ja
# ...省略...
```

```bash
$ mkdocs build
INFO    -  Cleaning site directory
INFO    -  Building documentation to directory: C:\path\to\mkdocs\docs\site
INFO    -  Documentation built in 0.20 seconds
(mkdocs)
```
Webminの「ホスト名」はどこを参照しているか


#結論
/etc/sysconfig/network でした。

#環境
Webmin 1.962
CentOS 7

#起きたこと
さくらVPSで独自のセットアップスクリプトを使ってホスト名を設定したつもりが、Webminのシステムインフォメーション画面に表示されるホスト名に反映しない。
![(1) Dashboard — Webmin 1.962 (CentOS Linux 7.8.2003)-2020-11-18 12_14_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155025/eef98aa4-ad9c-6a91-9455-d450fdd2615c.png)

#やっていたこと

```
HOSTNAME="test01"
DOMAIN="testdomain"
HOSTFQDN="${HOSTNAME}.${DOMAIN}"
hostnamectl set-hostname ${HOSTFQDN}
```

#現状を確認

```
# hostname
test01.testdomain
# cat /etc/hostname
test01.testdomain
# hostnamectl status
   Static hostname: test01.testdomain
```

#もしかして：CentOS 6

昔はここで変えていたような・・・

```
# cat /etc/sysconfig/network
NETWORKING=yes
NETWORKING_IPV6=yes
HOSTNAME=localhost.localdomain
#IPV6_DEFAULTDEV="eth0"
#IPV6_DEFAULTGW="fe80::1"
```

ビンゴ。

#Webminからホスト名を変更
![(1) Dashboard — Webmin 1.962 (CentOS Linux 7.8.2003)-2020-11-18 12_44_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155025/0277c9d4-8668-32b5-8211-e5295e3bd017.png)

#確認
```
# cat /etc/sysconfig/network
NETWORKING_IPV6=yes
NETWORKING=yes
HOSTNAME=test01.testdomain
```

変わった。

#やったこと

今回のように、/etc/sysconfig/network を参照している何かのために、sedで/etc/sysconfig/networkのHOSTNAME行をまるっと書き換えるようにした。

```
HOSTNAME="test01"
DOMAIN="testdomain"
HOSTFQDN="${HOSTNAME}.${DOMAIN}"
hostnamectl set-hostname ${HOSTFQDN}
sed -i -e "/HOSTNAME=/c\HOSTNAME=${HOSTFQDN}" /etc/sysconfig/network
```

以上。
CakePHP3.6でcsvをダウンロードする


##### code

```download.php
$this->response = $this->response
    ->withType('csv')
    ->withHeader('Content-Disposition', 'attachment')
    ->withDownload('file.csv');
```

##### ver
PHP 7.4.10
CakePHP 3.6.15

##### about
[【PHP】【CakePHP】CSVダウンロード - Qiita](https://qiita.com/kazu56/items/d2df449eb58e4ef9410e)
[【CakePHP】ファイルダウンロード - Qiita](https://qiita.com/kazu56/items/5667f963624b603f9277)
あたりを読んで、動かない動かないとハマっていたので。
v3.4からメソッド名が一新されていた。

##### reference
[CakePHP3.4が PSR-7に対応していた話（と、ミドルウェアの話） | バシャログ。](http://bashalog.c-brains.jp/17/08/23-100000.php)
[3.4 移行ガイド - 3.9](https://book.cakephp.org/3/ja/appendices/3-4-migration-guide.html)
[リクエストとレスポンスオブジェクト - 3.9](https://book.cakephp.org/3/ja/controllers/request-response.html)
dnfでプロキシを設定する

CentOS 8になって、パッケージマネージャーが`yum`から`dnf`になってプロキシ設定はどうするんだろう？とちょっと困ったので。

`dnf`の場合、`dnf.conf`の`main`セクションに記述します。

`/etc/dnf/dnf.conf`

```shell
[main]
...
proxy=http://[your-proxy-host]:[your-proxy-port]
```

なお、`yum`の時は`yum.conf`でした。

`/etc/yum.conf`

```shell
[main]
...
proxy=http://[your-proxy-host]:[your-proxy-port]
```

`dnf`になって、パスの階層が変わっていたので、ということでメモでした。

ちなみに、`/etc/dnf.conf`というファイルはあったりします。  
最初、ここに書くのかと思いました…。

# aptの場合は？

aptの場合は、こちらへ。

https://qiita.com/charon/items/1587f0092d085371d15d
[CSS]画像の上に単色フィルター

カードデザインやセクションの背景に、`画像＋何かしたの色付きのフィルターを敷きたいとき`の備忘録です。

# 手順
1. background-imageプロパティが当たっているclassのhtmlの要素の`小要素をつくる`
2. `background-color: rgba(0,0,0,0.5);`と`height: inherit;`をプロパティを当てる

※ 黒色フィルターの場合です。rgbaを変更すればもちろん他の色でも可です。

# 加工前
![スクリーンショット 2020-11-18 12.37.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825124/f9e6b21a-0078-ad93-aa7b-ae8186e4e84c.png)


```html
<!-- 画像部分のみ抽出 -->

<div class="card__picture">
   <div class="card__imge"></div>
</div>                                                        
```

```css
/* ------- 画像 スタイル ------- */

.card__picture{
    width: 500px;
    height: 250px;
}

/* 画像の設定 */
.card__imge{
    height: inherit;
    background-image: url(../img/coverSample.jpg);
    background-size: cover;
    background-position:center;
    background-repeat: no-repeat;   
}
```



# 加工後
![スクリーンショット 2020-11-18 12.36.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825124/8065b857-5283-672b-0d85-49cb3b57e19e.png)



```html
<!-- 画像部分のみ抽出 -->

<div class="card__picture">
   <div class="card__imge">
　　　<div class="filter--black"></div>  <!-- このdivを追加(小要素) -->
　　</div>
</div>                                                        
```

```css
/* ------- 画像 スタイル ------- */

.card__picture{
    width: 500px;
    height: 250px;
}

/* 画像の設定 */
.card__imge{
    height: inherit;
    background-image: url(../img/coverSample.jpg);
    background-size: cover;
    background-position:center;
    background-repeat: no-repeat;   
}

/* このセレクタを追加 */
.filter--black{
    background-color: rgba(0,0,0,0.4);
    height: inherit;
}
```

# 参考記事
https://momijitan.hatenablog.com/entry/2018/01/12/000905

# 次回
[[CSS]画像の上にグラデーションフィルター](https://qiita.com/nakamurashun0621/items/a9fc0f1a6f2d94fb0cda)
Ubuntu20.04LTS と Windows10 のデュアルブートで Intel RST(Rapid Storage Technology) が邪魔した時の対策

#はじめに
新しいWindows搭載ノートPCを購入し，「さぁ，Ubuntu入れてデュアルブートにするぞー！」と意気込み早速インストール．
すると，「Turn off RST」の警告と QR コードが出現．
最初は「まぁ，適当に緑のボタン押せばええやろ！」と思い，何も考えずRestartボタンを．
するとエラーが発生．
Ubuntuのインストールに失敗．

「しかたない」と Intel RST を BIOS でオフに．
すると Ubuntu のインストールには成功したものの，今度は Windows が起動しない！

「なんだこれは！！！」
試行錯誤したのち Windows が壊れたのか仕方なく工場出荷状態に戻す羽目に。。。
買ったばかりの PC だったのでなくなって困るデータもなく，事なきを得たのですが，これによりデュアルブートをあきらめかけました．

しかし，下記 URL に同じ状況に陥り助けを求めている方を発見．
https://askubuntu.com/questions/1233623/workaround-to-install-ubuntu-20-04-with-intel-rst-systems
この回答に書いてある内容を再現したら，RST をOffにした状態で Windows が通常通り起動！
つまり，Windows と Ubuntu のデュアルブートに成功！

同じ状況に遭遇し，Windows と Ubuntu のデュアルブートをあきらめる方もいるのではないかと思い，日本語で僕がやった対策をここに記録します．

#詳細情報
PC: Dell XSP15 9500
CPU: Intel Core i7-10750H
RAM: 16GB
GPU: Nvidia GTX 1650Ti
Storage: SSD1 512GB(Windows10), SSD2 512GB(Ubuntu 20.04LTS)

#注意事項
Windows を破損させたくない方はリカバリーメディアを作っておくことを推奨します．
僕の環境では下記作業中その必要はありませんでしたが，万が一があるので．
作っておいて損はないので是非！
また，データのバックアップもしておくことを強くお勧めします．

#作業内容
このURLに書いてあることを実行します．
http://triplescomputers.com/blog/uncategorized/solution-switch-windows-10-from-raidide-to-ahci-operation/

1. Windows でコマンドプロンプトを管理者権限で起動
2. 次のコマンドを入力`bcdedit /set {current} safeboot minimal`これでエラーが出たら`bcdedit /set safeboot minimal`
3. PC を再起動，BIOS で RST をオフに(これについては次のURLを参照：http://pineplanter.moo.jp/non-it-salaryman/2020/06/25/ubuntu-in-lenovo/)
4. Windows をいつも通り起動(ここでセーモードが起動する．)
5. セーフモードの状態でコマンドプロンプトを管理者権限で起動
6. 次のコマンドを入力
`bcdedit /deletevalue {current} safeboot`これでエラーが出たら`bcdedit /deletevalue safeboot`
7. 再起動(これで，Windows は通常起動する．)

以上の作業で Windows が通常起動したら，後はいつもどおり Ubuntu をインストールするだけ．

#まとめ
本件では，Windows10 と Ubuntu20.04LTS のデュアルブートの方法について，Intel RST が邪魔した際の解決方法の1つを紹介しました．

これですべての場合において上述の問題が解決するかはわかりませんが，試す価値はあると思います．
ただし，最悪の場合，プリインストールされている Windows の破損にもつながるかもしれないのでリカバリー対策とデータのバックアップはした上で，あくまで自己責任でよろしくお願いします！
【Java】GUIの開発フレームワーク

#プログラミング勉強日記
2020年11月18日
swingを使っているが、他にGUIのフレームワークがないか気になったのでまとめる。

#GUIとは
　Graphical User Interfaceの頭文字をとったもので、操作対象が画像や図形などで、キーボードからの入力やマウスのクリックといった直感的にコンピュータを操作できる。
　コマンドプロンプトを使ってjavacやjavaのコマンドでコンパイルや実行するのをCUIといい、CUIの場合はコマンドを覚える必要があるが、GUIの場合はコマンドを知らなくても画像や図形を使うことで直感的に操作できる。GUIはEclipseといった統合開発環境(IDE)を使って開発する。([統合開発環境(IDE)について](https://qiita.com/mzmz__02/items/57f14352bd463666347e)はこちらの記事で扱った)


#GUIのフレームワーク
　GUIを開発するためにはフレームワークを使用する。

##AWT
　AWTはAbstract Window Toolkitの頭文字をとったもので、Java 1.0のころから使用されているGUIフレームワーク。ボタンなどの部品はウィンドウシステムのネイティブ部品が使われているので、Windows上ではネイティブなWindowsアプリと似ていて、Mac上ではネイティブなMacintoshに似ていて、OSに依存する。

##JavaFX
　JavaFXはJava8以降でJava SEの標準GUIフレームワークで、FMXLと呼ばれるXMLとCSSを併用してデザインを記述し、デザイン処理と処理クラスの記述を分離できる。

##Swing
　Javaで書かれたGUIのフレームワークで、どのOSで動かしても見栄えが同じになる。AWTに起因する限界もあって、Java8以降はJavaFXに置き換えられている。
　

#参考文献
[【Java入門】GUIの開発フレームワークまとめ(Swing、JavaFx、AWT)](https://www.sejuku.net/blog/60411)
404エラーを返すWordPress投稿を修正する方法

WordPressは強力なCMSですが、わずかな調整によりWebサイトにアクセスできなくなる場合があります。ただし、WordPressの問題の解決策を見つけるのは非常に簡単です。WordPressユーザーが直面する最も一般的な問題のいくつかあります。例えば内部サーバーエラーまたはデータベース接続の確立エラーなどです。そして、ほとんどのWordPressユーザーがいつか直面するもう1つの一般的な問題は、WordPressの投稿が404エラーを返すことです。この記事では、404エラーを返すWordPressの投稿を修正する方法を紹介します。
___

通常、ユーザーはブログのメインページであるWordPress管理エリアにアクセスできますが、単一の投稿にアクセスすると、404 Notfoundエラーが発生する場合があります。そういった場合でもほとんどの場合、慌てる必要はありません。そういった時の原因は主に２つです。

**①htaccessファイルが削除された**
**②書き換えルールに問題が発生した**

そこで行うべきアクションは**パーマリンク設定を修正することです**

「設定」⇨「パーマリンク」に移動し、「設定を保存」をする。ただこれだけ。


これにより、パーマリンク設定が更新され、書き換えルールがフラッシュされます。ほとんどの場合、このソリューションはWordPressの投稿404エラーを修正します。ただし、それが機能しない場合は、.htaccessファイルを手動で更新する必要があります。

FTPを使用してサーバーにログインし、/ wp-content /や/ wp-includes /などのフォルダーと同じ場所にある.htaccessファイルを変更します。最も簡単な方法は、アクセス許可を666に変更して、ファイルを一時的に書き込み可能にすることです。次に、元の解決策を繰り返します。権限を660に戻すことを忘れないでください。次のコードを.htaccessファイルに手動で追加することもできます。


    BEGIN WordPress
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
    </IfModule>
    # END WordPress

#ローカルサーバーの修正
多くの場合、デザイナーや開発者は、テスト目的でローカルサーバーを使用してコンピューターにWordPressをインストールします。綺麗なパーマリンクを使用したい場合は、MAMP、WAMP、またはXXAMPのApache構成でrewrite_moduleを有効にする必要があります。

以上が404エラーに対しての処理になります。もしよろしかったらコメント待っています。
Dartの型について

## Dartの型の種類

- int      →　整数
- double   → 小数
- String   → 文字
- bool     → 真偽値
 
## 型推論について

- var(let)  → 自動で型推論してくれる
- dynamic  → 何型でも良い
- final　→ 後から変更できない
- const　→ 後から変更できない(コンパイル時に値が決まる)
 
### var (let)
var a = 100;
aは数値になる

a = 'あああ'
文字列を入れようとするとエラーになる

### daynamic
dynamic b = 100;

b = 200;
b = 'こんにちは';

エラーにならない

### final 
final c = 100;

c = 200;
エラーになる

### const
const d = 100;

d = 300;
エラーになる
VSCodeでERBの式入力タグを挿入できるようにする拡張機能

##はじめに

VSCodeでERBファイルを編集する際に、式出力タグの入力が面倒だったので、スニペットを登録しようかと考えていたのですが、ちょうどいい拡張機能を教えてもらえたのでこちらで紹介します。

[Simple Ruby ERB]
(https://marketplace.visualstudio.com/items?itemName=vortizhe.simple-ruby-erb)

###使い方
-----------
``Shift⇧ + Ctrl⌃ + ` `` でタグを挿入、押すたびに種類が切り替わります。
![demo](https://i.gyazo.com/16681b8a167f4be49c71b5119d1316a5/raw)
すごい楽。