OmniAICreator/Qiita-1.07M huggingface dataset:
shellscriptのif文

shellscriptのif文を勉強したのでまとめます。

*varという変数がある程で書きます。
#条件文の書き方
・**if**
1. if test 条件文;
2. if [ 条件文 ];  ←スペース必須
3. if [[ 条件文 ]];

1~3のどの書き方でも最後に```fi```をつけないとエラーになる。

・**elif**
 ifと同様の3パターン
・**else**
 ifと同様の3パターン

・**then**
 条件が一致していた際の処理を書く。

```if_sentence.sh
#!/bin/bash
if  test $var = 'text' ;
    then
        echo 'いぇい'
elif [ $var = 'sample' ];
    then 
        echo 'やったー'
else
    echo '俺か俺以外か'
fi
```
```then 処理```を1行にまとめて書くこともできるけど見づらいかやめたほうがいいかも。
細かいことを言うと条件に一致していた場合、exit status 0を返しthenの中が実行される。　

#比較演算子
###文字列の比較
= : 条件が等しいか
!= : 条件が等しくないか

###数値の比較
-eq : =と同じ意味
-ne : !=と同じ意味
-lt : less than ```<```のこと。
-le : less equal ```≦```のこと。
-gt : great than ```>```のこと。
-ge : great equal ```≧```のこと。

```if_sentence.sh
#!/bin/bash
if [ $var -eq 10 ];
    then 
        echo 'ten'
elif [ $var -lt 20 ];
    then 
        echo 'less than twenty'
elif [ $var -ge 20 ];
    then
        echo 'great equal twenty'
fi
```
文字列は簡単だけど数値は面倒くさそう。

#andとorと否定
###and/or
andとorは```&&/||```もしくは```-a/-o```のどちらか。
1. if [ 条件文1 ] &&/|| [ 条件文２ ];
2. if [ 条件文１ -a/-o 条件文２ ];
3. if [[ 条件文１ &&/|| 条件文２ ];
4. if test 条件文１ &&/|| test 条件文２;

###否定
1. if ! test 条件文
2. if [ ! 条件文 ]
3. if [[ ! 条件文 ]]

**否定文の最後はセミコロン```;```をつけない!**

```if_sentence.sh
#!/bin/bash
    #and/or  
if [ $var1 -ne 100 ] && [[ $var1 -ge 1 || $var2 -lt 10 ]];
    then ...
fi
    #否定文
if [ ! $var1 != 'hello world' ]
    then ...
fi
```
面倒くさい書き方をしたけど```$var1は1以上で100でない時```もしくは```$var2は10より小さいかつ$var1が100でない時```にthenの処理が実行される。

###ファイルチェック
-e : ファイルまたはディレクトリが存在しているか。
-d : ディレクトリの存在チェック。
-f : ファイルの存在チェック。
-nt : newer than ファイルが新しいか。
-ot : older than ファイルが古いか。

```file.sh
#!/bin/bash
if [ -d 'dir' ] && [ -f 'file' ];
    then ...
fi

if [ file1 ] -nt [ file2 ];
    then ...
else
    ...
fi

```
###空白チェック
-zを用いると空白をチェックできる。

```file.sh
read var

if [ -z $var ];
then
    ...
fi
```
readで読み取った値が空白の場合(文字列の長さが0の場合)、thenの中が実行される。

#case文
###参考
https://www.atmarkit.co.jp/ait/articles/1811/21/news009_2.html

var変数があるとして
```case $var in```と書き始めて、```esac```で閉じる(if文のfiと同じ)。

```
ケース1 )
    処理 ;;
ケース2 )
    処理 ;;
*)
    処理 ;;
```
のような感じで書く。
*)はif文でいうelseと同様にパターンにマッチしない場合の処理を書く。

ケースはパターンなどを書くこともできる。

```file.sh
case $var in
    'hello' )
      echo 'hello';;
    [a-z] )
      echo 'while a-z';;
    *)
      echo 'other word';;
esac
```
また、```shopt -s nocasematch```と書くと、このスクリプト内でのみ大文字と小文字の区別をなくせる。(shoptはbashの組み込みコマンド)

```file.sh
shopt -s nocasematch

case $var in
...
```

###bashの変数展開を利用してcase文を書く。

```file.sh
case ${var ,,} in ... #変数内の要素を全て小文字に

case ${var ^^} in ... #変数内の要素を全て大文字に

case ${var ^} in ... #最初の1文字を大文字に
```
参考記事でわかりやすく説明されています。
詳しくはそちらを。

**間違いがありましたらご指摘ください。**
Tailwindcssをbuildし、PargeCSSで圧縮する方法

今回はTailwindcssについて書いていきます。

前回、[もう生のCSSを書くのはやめようぜ。。。TailwindcssでCSS記述時間を圧倒的に減らす方法](https://qiita.com/akki-memo/items/5768b02971f877462a60)でTailwindcssを使用する方法をおさらいしました。

Tailwindcssに触れたことが無いよと言う方は上記の記事をご覧ください。

さて、今回はTailwindcssの容量がかなり大きいので、まずは自作の``tailwind.css``をbuildし、本番環境用に``npm run build``をする際に使っていないCSSを消して容量を軽くするといった流れになります。

また、お使いのフレームワークのテンプレート内にて使っていないCSSもある場合、PurgeCSSを使うことでこれらのCSSを自動的に消去してくれます。

凄く便利なので、PurgeCSSの使い方もぜひ覚えましょう！

それでは説明していきます！

#tailwind.cssのビルド#

まずは名前はそれぞれによって違うと思うので以下のコードのファイルがあるか確認してください。

```javascript
@tailwind base;
@tailwind components;
@tailwind utilities;
```

このファイルをまずはビルドしてあげます。

``pakage.json``の``script``プロパティで以下のようにコマンドを設定します。

```pakege.json
{
  "scripts": {
    "tailwind": "npx tailwindcss-cli@latest build ./tailwind.css -o ./src/assets/output.css",
  },
}
```

``./tailwind.css``、``./src/assets/output.css``ともに任意のパスを記述。

そしたらコマンドの実行。

```
yarn tailwind

yarn run v1.22.10
$ npx tailwindcss-cli@latest build ./tailwind.css -o ./src/assets/output.css
npx: 89個のパッケージを30.659秒でインストールしました。

   tailwindcss 2.0.4

   � Building: tailwind.css

   ✅ Finished in 5.16 s
   � Size: 1.71MB
   � Saved to src/assets/output.css

Done in 40.36s.
```

このような結果が返ってくればOK！

そしたら、このビルドしたCSSを``main.js``にて読み込みましょう。

ここで、注意なのですが``index.html``にて``link``タグとして読み込むと、いくつかのCSSが読み込まれないため、**必ず**``main.js``にて読み込んでください。

```main.js
import './assets/output.css'
```

#PurgeCSSの有効化#

Tailwindは今ではデフォルトでPurgeCSSの機能が携わっているので、パッケージのインストールは行いません。

``tailwind.config.js``で設定を行います。

```tailwind.config.js
const colors = require('tailwindcss/colors.js')
module.exports = {
  // ここから
  // 対象ファイルを配列として格納
  purge: ['./src/**/*.{vue,css}'],
  preserveHtmlElements: false,
  options: {
    defaultExtractor: (content) => {
      const contentWithoutStyleBlocks = content.replace(/<style[^]+?<\/style>/gi, '')
      return contentWithoutStyleBlocks.match(/[A-Za-z0-9-_/:]*[A-Za-z0-9-_/]+/g) || []
    },
    whitelist: [ /-(leave|enter|appear)(|-(to|from|active))$/, /^(?!cursor-move).+-move$/, /^router-link(|-exact)-active$/ ],
  },
  // ここまで追加
  theme: {
    screens: {},
    colors: {},
    extend: {},
  },
  variants: {},
  plugins: [],
}
```

ここで大切なのが``purge``です。

ここで、使っていないCSSを消去する対象を選択しています。

今回は例として``.vue``と``.css``の拡張子をもつファイルを対象としています。他のフレームワークをご利用の方は適時変えて下さい。

``prederveHtmlElements``はよく分かんないっす。

``options``に関しては公式ドキュメントに書いてあったのでそのままコピペしました。

これでビルドしたときにPurgeCSSが動きます。

それではビルドして見ましょう！

ここで注意なのですが、``postcss.config.js``が存在する方は必要ないので消してください。

これがあるとビルド時にエラーが起きます。

```powershell
yarn build

...

  dist\js\chunk-vendors.cd9c853b.js      1532.20 KiB             525.47 KiB
  dist\js\app.856a4aed.js                18.21 KiB               6.00 KiB
  dist\css\app.c6327dec.css              1726.00 KiB             194.06 KiB
  dist\css\chunk-vendors.08a0794a.css    381.06 KiB              46.12 KiB
```

小さくなっているはず。。。

こんな感じでPuregCSSを使えば容量を削減できます！

大きなプロジェクトでは活躍しそうですね。

以上、「Tailwindcssをbuildし、PargeCSSで圧縮する方法」でした！

Thank you for reading
【SpringBoot】簡単なアプリを作ってみよう！(3/3) ~DB操作（SpringDataJPA）~

この記事は以下の続きです。
[SpringBoot2で簡単なアプリを作ってみよう！(2/3) ~画面表示~](https://qiita.com/nmaolks/items/95d1fe42809642167f27)

第3回目はJPAを使ってDB操作をしていきたいと思います。
#SpringDataJPAとは
一言で言えば、SQLをより扱いやすくするためのライブラリです。
個人的な意見としてのメリット、デメリットは以下となっております。
#####メリット
・SQLを書く必要がない（場合によりますが）
・DB移行時影響が少ない（Oracle→MySQLなど）
・JPAの記述、管理がしやすい

#####デメリット
・動的SQLが初心者には難しい
・副問合せ（サブクエリ）が少し苦手

まずはコードを書いてみて雰囲気をつかんでいただければと思います。

##各クラスを作成する
とりあえず前回同様プロジェクトはこんな感じです。
![スクリーンショット 2021-03-27 22.25.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234354/ba64cc5b-3f32-aa07-19aa-1b0fde19b574.png)
今回はEntityクラス,Repositoryクラス,Serviceクラスを作成していきます。
JPAを利用する場合こちらの三つのクラスを基本的に作成します。
####Entityクラスを作成する
EntityはDBのテーブルと対になっているものを作ります。
役割としては、DBからのレコード取得、アプリ側からのレコード送信の為のデータ保管場所となります。MVCモデルでいうところのM（モデル）です。

```java:Product.java
@Entity
@Data
@Table(name="product")
public class Product implements Serializable{
	private static final long serialVersionUID = 1L;
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer id;
	
	private String productName;

	private int productNum;
}
```
####Repositoryインターフェースを作成する
RepositoryインターフェースはJpaRepositoryを継承して作成します。
<>の中は\<Entity,EntityIdの型>になります。
このインターフェースでSQLの作成を行います。

```java:ProductRepository.java
@Repository
public interface ProductRepository extends JpaRepository<Product,Integer > {
}
```

####Serviceクラスを作成する
MVCモデルを勉強したばかりだとControllerとServiceの区別がつきにくいと思いますが、
Controllerクラスはあくまで指令をする役割、Serviceクラスは煩雑な処理等を担当します。

下記コードのfindAllメソッドではレコード全件取得、insertメソッドではレコード登録を行っております。

```java:ProductService.java
@Service
public class ProductService {

	@Autowired
	ProductRepository repository;
	
	public List<Product> findAll(){
		return repository.findAll();
	}
	
	public Product insert(){
		Product item = new Product();
		item.setProductName("name");
		item.setProductNum(100);

		return repository.save(item);
	}
}
```


ここまでできましたら、ControllerとHTMLに追記をしていきます。

####Controller追記
`@Autowired`を使うことでDIコンテナに登録されているクラスをnewしなくても呼び出すことができます。
`productService.findAll()` データ全件取得
`model.addAttribute`　画面に値を渡す

```java:AdminController
@Controller
public class AdminController {

	@Autowired
	ProductService productService;
	
	@GetMapping("/")
	public String index(Model model) {
		List<Product> productList = productService.findAll();
		model.addAttribute("productList",productList);
		return "productManage";
	}
}

```
####HTML追記
`th:each`をつけることでループすることができます。


```html:productManage.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
	<title>商品管理</title>
</head>
<body>
	<p>商品管理</p>
	<table>
		<tr>
			<th>商品名</th>
			<th>商品数</th>
		</tr>
		<tr th:each="p : ${productList}">
			<td>[[${p.productName}]]</td>
			<td>[[${p.productNum}]]</td>
		</tr>
	</table>
</body>
</html>
```

ここまでできたら画面を確認してみましょう！
http://localhost:8080/

以下の画面が表示されれば正常に動いてます！

####◇画面イメージ
![スクリーンショット 2021-04-02 8.27.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234354/283d7bbb-5ed7-2d96-1548-ed2d7d213495.png)
JavaScriptのthisについて

## JavaScriptのthisについて改めて復習したのでまとめる

1. new演算子をつけて呼び出す <br>new演算子は、new演算子をつけたその関数のprototypeオブジェクトをコピーして新規にオブジェクトを作り、それを関数に暗黙の引数`this`として渡し、最後に`return this`を実行する。<br>

2. メソッドとして実行されたとき<br>Python同様、メソッドとして実行されたとき、アクセス演算子`.`の前のオブジェクトが`this`をして渡される。

>const foo ={
  name: 'Foo Object',
  dump() {
   console.log(this).
),
}

>foo.dump();  //{name:'Foo Object', dump[Function:dump]}

3.　1,2以外の関数[非Strictモード]：グローバルオブジェクト<br>JavaScriptにおけるトップレベルの実行環境は必ず何かの`グローバルオブジェクト`になっている。そのため、デフォルトでthisはそのグローバルオブジェクトを参照している。そのため、メソッドではない関数、及びnew演算子をつけずに実行される関数は、グローバルオブジェクトがthisとして引き渡される。

> const dump=function(){console.log(this);};
>dump();
//ref *1 Object [global]{
global:[Circular*1],
...
}

4 .1,2以外の関数[Strictモード]:undefined<br>元々のJavaScriptでは簡単にグローバルオブジェクトに対しての汚染が起こってしまっていた。そこでES5で「Strictモード」というものが追加された。これによって、古い仕様に含まれるいくつかの安全ではない構文や機能を禁止することができる。

このStrictモードによって、関数がメソッドでない、任意のオブジェクトのコンテキストになかった場合、`this`には`undefined`が入る。

## 参考文献
[りあクト！ TypeScriptで始めるつらくないReact開発 第3版【Ⅰ. 言語・環境編】] https://oukayuka.booth.pm/items/2368045

こちらを参考にさせていただきました。<br>ありがとうございます。
性別を表示する

ユーザーの性別を表示する方法を考えたので記録を残します。



###カラムのデータ型をinteger、boolearn型にした場合

enumを利用するのが良いかなと思います。

[enumチュートリアル](https://pikawaka.com/rails/enum#boolean%E3%81%AE%E5%A0%B4%E5%90%88)


###カラムのデータ型をstring型にした場合(私はこれにしました)

Form

```ruby
  <%= markup do |m| 
    p = FamilyFormPresenter.new(form, self)
    m << p.gender_field_block
    end %>
```
htmlビルダーとプレゼンターを利用してフォームに組み込んでいます。

[htmlビルダーについて]
(https://www.oiax.jp/rails/tips/nokogiri_html_builder.html)

[プレゼンターについて]
(https://www.oiax.jp/rails/tips/decorators_and_presenters.html)


Presenter

```ruby
  def gender_field_block
    markup(:div, class: "radio-buttons") do |m|
      m << decorated_label(:gender, "性別")
      m << radio_button(:gender, "male")
      m << label(:gender_male, "男性")
      m << radio_button(:gender, "female")
      m << label(:gender_female, "女性")
    end
  end
```


以下のhtmlが生成されます。

```
<label>男性</label>
<input type="radio" value="male" name="family[gender]" id="family_gender_male">
<label>女性</label>
<input type="radio" value="female" name="family[gender]" id="family_gender_female">
```
ラジオボタンで男性を選択した場合、"male"、女性を選択した場合に"female"が保存されます。



ヘルパーに男性か女性を返すメソッドを作成します
/application.helper

```ruby
#男性か女性を返す
  def judge_gender(gender)
    case gender
    when "male"
      "男性"
    when "female"
      "女性"
    else
      ""
    end
  end
```

/view

```ruby
<%= judge_gender(@family.gender)%>
```
引数に性別属性を渡しています。
bundle install できない

##bundl　installできない
EC2でbundle install を行った際に以下のエラーが発生しました。

```
Your bundle is locked to mimemagic (0.3.5), but that version could not be found
in any of the sources listed in your Gemfile. If you haven't changed sources,
that means the author of mimemagic (0.3.5) has removed it. You'll need to update
your bundle to a version other than mimemagic (0.3.5) that hasn't been removed
in order to install.
```

原因としてはactivestorageと関連しているmimemagicが問題となっているようです。

##対処法

まずはrails を最新にアップデートしました。

```ruby
-gem 'rails', '~> 6.0.0'
+gem 'rails', '~> 6.1.3.1'
```


```ruby
$bundle install
```

しかしこれでもエラーは解決しませんでした。

次はmimemagic をアップデートします。

```ruby
$ bundle update mimemagoc
```

```ruby
$ bundle install
```
すると

```
=> Bundle complete! 31 Gemfile dependencies, 126 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
```

bundele installが成功しました。




参照: [mimemagicの最新動向](https://hackmd.io/@mametter/mimemagic-info-ja)
初めてHuawei端末でAndroidStudioの実機デバッグをするときの手順

　windows PCのOSを再インストールして、久しぶりにAndroidStudioを使用した際に、huaweiの実機でデバッグするための設定に手間取ったので、その手順をまとめます。
　本手順は、huaweiの端末に特化していると思われます。

１．環境
PC OS：windows10
AndroidStudio4.1
Android端末：Huawei P10 lite WAS-LX2J
　　　　　　　　　　Nova CAZ-TL10

２．手順
(1)PCとandroid端末をUSBケーブルで接続する。

(2)USB接続したら、エキスプローラを開き、PCを選択し、デバイスとドライブにあるCDドライブ![HiSuiteを閉じる.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501068/b410211f-70a9-b6de-1e34-7e6684d11061.png)
をダブルクリックする(このCDドライブは、端末に仕込まれたフォルダである)。

![端末をCDドライブに見立てるアイコンが表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501068/116d8f68-cb0a-d3c3-a442-2f314c72ecfb.png)

　ダブルクリックすると、HiSuiteというアプリケーションソフトがPCにインストールされます。HiSuiteはPCとhuaweiのアンドロイド端末の間でファイルをやり取りするためのアプリです。HiSuiteをインストールすることにより、Huaweiのアンドロイド端末とPCが通信するためのドライバーがインストールされるそうです（参考：[Yahoo知恵袋](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10173036575)）。
　インストーラに従って、HiSuiteをダウンロードしインストールします。

![HiSuiteインストール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501068/c4dd615d-5967-22ce-c4e4-fb0fc8e70380.png)
　
(3)インストールが完了するとHiSuiteが開きますが、AndroidStudioの実機デバッグでは使わないので、閉じます。

![HiSuiteを閉じる.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501068/af1d0b5f-eb2a-b50a-cbaa-fa47d722558d.png)

(4)HuaweiのAndroid端末の上部の通知パネルを引っ張り、
![USB接続アイコン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501068/aa0f6222-d0ec-c846-c493-015a7dfa2746.png)

[USB設定]をタップし、

![WeChat Image_20210402193001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501068/c8a4fe60-fdbe-3310-fa11-aa55bbbb3e43.jpeg)

[ファイルの転送]を選択します。

![WeChat Image_20210402202338.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501068/5832838c-d6bf-b4aa-56e7-74ab02376a4e.jpeg)

(5)以下の手順を実行して、充電専用モードでADBデバッグを許可する を有効にします。（参考：[HuaWei Q&A　USBデバッグ スイッチをオンにできません](https://consumer.huawei.com/jp/support/content/ja-jp00407281/)）
a.設定（歯車マーク⚙） > システム > 端末情報 に移動し、ビルド番号 を7回続けてタップすると（必要に応じてロック画面のパスワードを入力する）、「これでデベロッパーになりました！」というプロンプトが表示されます。（初回のみ）

![ビルド番号.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501068/83a54652-640d-f0cf-7a60-e4ecd4b38bec.jpeg)

b.開発者オプションをオンにする。
![開発者オプションｏｎ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501068/74aed7cf-935b-2a02-54ac-a4c1ae14a82d.jpeg)

c.設定（歯車マーク⚙） を開き、開発者向けオプション を探してアクセスし、充電専用モードでADBデバッグを許可する を有効にします。さらに、USBデバッグ を有効にし、表示された USBデバッグを許可 ウィンドウで OK をタップします。（毎回）
![デバッグモード.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501068/1a6d64b7-b264-7cde-9524-cef9a0be36f6.jpeg)

(6)以上の設定で、AndroidStuido上で実機が使用できる環境が整う。
![androidSTUDIO.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501068/afd7c310-1b4f-5b26-9f65-ce03ec0b05c5.png)
【Ruby】文字列を置換するgsubメソッドの使い方

#プログラミング勉強日記
2021年4月2日

#gsubメソッドとは
　文字列を別の文字列に置換するメソッド。正規表現を用いて置換・削除することもできる。
　メソッド名の最後に!(ビックリマーク)を付けて破壊的メソッドを使用することもできる。`gsub!`メソッドを使うと、置換した文字列を元の文字列に書きかえる。


```ruby:使い方
# 正規表現を使わない場合
"文字列".gsub("置換したい文字列", "置換後の文字列")
# 正規表現を使う場合
"文字列".gsub(/正規表現/, "正規表現に該当した箇所を置換した後の文字列")
```

#サンプルプログラム

```ruby
"abcdefg".gsub("def", "aa")
#=> "abcaag"

"abcdefg".gsub(/def/, "aa")
#=> "abcaag"

"abcabc".gsub(/b/, "<<\&>>")
#=> "a<<b>>ca<<b>>c"
```

#参考文献
[instance method String#gsub](https://docs.ruby-lang.org/ja/latest/method/String/i/gsub.html)
[instance method String#gsub!](https://docs.ruby-lang.org/ja/latest/method/String/i/gsub=21.html)
学習記録

こんにちはtaroです！

今日のアウトプットはシステム開発の流れです！
システム開発は以下の順番でやっていくそうです！

１企画　（スケジュール、体制、リスク分析、費用対効果、適用範囲）

２要件定義　　（どんな機能が必要かを決める）
　　　　　　　　
３開発　（プログラミング）
　　　　　　　　
４運用　（完成したシステムを使う）
　　　　　　　　
５保守　（定期的にメンテナンスを行う）

私はこの開発の流れを見ていて思うのですが、他の業界でも
製品を生み出す時の流れは似ていると思いました。
vm.swappiness について

AWS の s3 へデータを sync コマンドによりコピーしていたら、かなりの swap が発生してしまいました。
メモリの使用量よりも、swap の方が多くなってきています。

vm.swappiness の設定は、デフォルトの 60 となり、swap を積極的に活用していく設定となっています。
この設定を、変えてみます。0 から 100 までの値を設定できるようですが、今回は、1 にしてみます。

```
# vim /etc/sysctl.conf
====
vm.swappiness=1
====

# sysctl -p
# sync
# echo 3 > /proc/sys/vm/drop_caches
# swapoff -a && swapon -a
$ free
```

swap が　0　となり、メモリの利用がほとんどとなりました。

（参考）
https://linuxize.com/post/how-to-change-the-swappiness-value-in-linux/

https://access.redhat.com/solutions/103833
LeetCode 【#14 Longest Common Prefix】のGo言語解法

# 概要

## 問題詳細

```
Write a function to find the longest common prefix string amongst an array of strings.

If there is no common prefix, return an empty string "".

 

Example 1:

Input: strs = ["flower","flow","flight"]
Output: "fl"
Example 2:

Input: strs = ["dog","racecar","car"]
Output: ""
Explanation: There is no common prefix among the input strings.
 

Constraints:

0 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i] consists of only lower-case English letters.
```
## 解説

### 要件

文字列の配列で一番長いの共通の接頭辞を探し出すの要件です。
まとめることは、
1, 接頭辞
2, 共通
3, 一番長い

# 解法

## 一番簡単な状況をまとめます

```
func longestCommonPrefix(strs []string) string {
  size := len(strs)
  if size == 0 {
    return ""
  }
  if size == 1 {
    return strs[0]
  }
  ...
}
```

## Goで接頭辞の判断

```
strings.HasPrefix(str1, str2)
```

ref: https://golang.org/pkg/strings/#HasPrefix


## 変数の初期化

```
common := strs[0]
length := len(common)
result := ""
```

要件によって、結果は最初の文字列にも必ず含まれているので、まず頭の文字列を選択します。
結果変数はまず空に初期化する。


## 接頭辞の循環

```
for j := 1; j <= length; j++ {
  current := common[0:j]
  ...
}
```

接頭辞の長さは頭の文字列の長さに限られているので、上記の循環を設計しました。

## 配列の循環

```
for k := 1; k < size; k++ {
  ...
}
```

### 接頭辞を判断する

```
for k := 1; k < size; k++ {
  if !strings.HasPrefix(strs[k], current) {
    break
  }
  ...
}
```

接頭辞の判断がfalseの場合は、循環を中止します。

```
for k := 1; k < size; k++ {
  if !strings.HasPrefix(strs[k], current) {
    break
  }
  if (k == size && len(result) < len(current)) {
    result = current
  }
}
```

- `k == size` の判定がtrueの場合は、今の接頭辞currentが共通と判断する認識です。
- `len(result) < len(current)` の判定がtrueの場合は、今の接頭辞currentが一番長いと判断する認識です。

## 成果物

```
func longestCommonPrefix(strs []string) string {
  size := len(strs)
  if size == 0 {
    return ""
  }
  if size == 1 {
    return strs[0]
  }
  common := strs[0]
  length := len(common)
  result := ""
  for j := 1; j <= length; j++ {
    current := common[0:j]

    var k int
    for k = 1; k < size; k++ {
      if !strings.HasPrefix(strs[k], current) {
        break
      }
    }
    if (k == size && len(result) < len(current)) {
      result = current
    }
  }

  return result
}
```

# submit結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199563/b33c66aa-7f44-1bc2-10c5-86b0fec4fd94.png)

# 結論

接頭辞の制限があるので、難易度は低くなると思います。
Laravelでバリデーションを利用する

#Laravelでリクエストパラメータのバリデーションを実装します
Laravelのベストプラクティスとしてスリムコントローラーが推奨されていますので、
コントローラーでリクエストパラメータのチェックを行うのではなく、バリデーションを利用した方が良いと考えています。
例としてメールアドレスとパスワードを入力するログイン画面におけるバリデーションのケースで考えてみましょう

#Requestオブジェクトが提供するvalidateメソッドを使用するケース

Illuminate\Http\Requestオブジェクトが提供する、validateメソッドを使って簡単にバリデーションを実装することができます。
次のコードはリクエストパラメータのmail(メールアドレス)とpassword(パスワード)の必須チェックです。

```
class LoginController extends Controller
{
    public function login(Request $request)
    {
        $request->validate([
            'mail' => 'required',
            'password' => 'required',
        ]);
    }
}

```

バリデーションエラーになった場合は遷移元にリダイレクトしてくれます。
エラーメッセージはビューの中で$errors変数に格納されているため次のように表示します。

```
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif
```

表示されるメッセージの内容に関しては言語ごとのvalidation.phpに定義されています。
例えば英語の場合requiredはこのように定義されています。

```
'required'             => 'The :attribute field is required.',
```

:attributeの所にパラメータの名前がプロットされます。
The mail field is required.
のように表示されることになります。

パラメータの名称を定義する場合は同じファイル内に定義されている
'attributes' => [],に追記します。

```
    'attributes' => [
        'mail' => 'mail address'
    ],
```
このようにすることで、
The mail address field is required.
と表示させることが可能です。

##フォームリクエストバリデーションを使用するケース
より複雑なバリデーションを実装することができます。
個別にエラーメッセージ、リクエストパラメータの名称を定義することができます。
まずは次のコマンドでRequestクラスを生成しましょう。

```
php artisan make:request LoginRequest
```

App\Http\Requests\LoginRequestが生成されます。

```
class LoginRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        // ここにバリデーションルールを記述してください
        return [
            'mail' => 'required|email|exists:users,mail',
            'password' => 'required',
        ];
    }

    public function attributes()
    {
        // attributesメソッドをオーバーライドすることでリクエストパラメータの名称を個別に定義できます
        return [
            'mail' => 'メールアドレス',
            'password' => 'パスワード',
        ];
    }

    public function messages()
    {
        // messagesメソッドをオーバーライドすることでエラーメッセージを個別に定義できます。
        return [
            'mail.required' => ':attributeは必須です',
            'mail.email' => ':attributeの形式が正しくありません',
            'mail.exists' => ':attributeまたはパスワードが正しくありません',
            'password.required' => ':attributeが入力されていません',
        ];
    }
}
```

コントローラーは次のようになります。

```
use App\Http\Requests\LoginRequest;
class LoginController extends Controller
{
    public function login(LoginRequest $request)
    {
        // バリデーション処理を記述する必要はなく、検証OKの時に通常の処理が実行される
    }
}
```

フォームリクエストバリデーションを使用するとクラスが増えるという面がありますが、
より複雑なバリデーションに対応することができ、コントローラーがすっきりします。
アプリケーションとしてエラーメッセージの形式はなるべく統一しておいた方が実装もシンプルになって良いと思いますが、
状況に応じて使い分けるといいかもしれません。
【React】フック（hooks）

# フックとは
- 関数コンポーネントに `state` やライフサイクル等のReactの機能を接続するための関数
- Reactをクラスなしで使うための機能（フックはクラス内では使用不可）

## フックの種類
### useState
- ステートフルな値と、それを更新するための関数を返す
- 初回のレンダー時に返される `state` は 第1引数として渡された値（`initialState`）

```tsx
const [state, setState] = useState(initialState);
```

- `state` の更新は `setState` 関数を使用する

```tsx
setState(newState);
```

- `state` 更新時に再レンダーを行う

### useEffect
- `useEffect` に渡された関数（`didUpdate`）はレンダーの結果が画面に反映された後に実行される

```tsx
useEffect(didUpdate);
```

- `useEffect` の第2引数として渡した配列の値（`props.source`）が変化した時のみ関数（`didUpdate`）が実行される

```tsx
useEffect(didUpdate, [props.source]);
```

- 空の配列（`[]`）を渡した場合、更新時には関数（`didUpdate`）は実行されない

```tsx
useEffect(didUpdate, []);
```

### useContext
- コンテクストオブジェクト（`React.createContext` からの戻り値）を受け取り、そのコンテクストの現在値を返す

```tsx
const value = useContext(MyContext);
```

- `useContext` を呼び出すコンポーネントはコンテクストの値が変化するたびに毎回再レンダーされる

### useRef
- `.current` プロパティが渡された引数（`initialValue`）に初期化されているミュータブルな `ref` オブジェクトを返す

```tsx
const refContainer = useRef(initialValue);
```

- `.current` プロパティを書き換えても再レンダーは発生しない
家庭用Microsoft365 Personalの個別インストール時の設定xmlのProduct IDは"O365ProPlusRetail"でいいの？

# 結論
O365ProPlusRetailでも問題ありませんでした。
# 環境
Windows10 Home
家庭用サブスクリプションであるMicrosoft365 Personalを契約中
現在インストールしているOfficeの内、全く使わないPublisherのみアンインストールしたい。
# 手順
[Office製品を個別にインストールする方法【Office365,2019,2016,2013対応】](https://hackers-high.com/software/office-selective-installation/)
上記の通り進めました。

この際、xmlで指定するProduct IDに製品名を指定するとありますが、Microsoft 365 Personal をピンポイントで記述している記事は調べても見つけられませんでしたが、変更することなくO365ProPlusRetailでいけました。

※Office365でPublisherのような不要なアプリがインストールされている場合、まずOfficeごとアンインストールする必要があります。
→その後、configuration内容を書いたxmlを参照してsetup.exeを実行します。

```powershell:インストール
.\setup.exe /configure myconfiguration.xml
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347189/53c9497a-d16d-fc5d-eef4-1bfa7d9cb114.png)
インストール中画面でPublisherが含まれていないことを確認


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347189/df977321-8d22-b17f-dce8-4434e840e422.png)
この手順でインストールされたOfficeソフトは、コントロールパネル>プログラムと機能でMicrosoft 365 Apps for Enterprise と表記されました。家庭用なのでEnterprise表記は違和感ありますが、使用する分には問題なさそう？

間違い等あれば修正または記事の取り下げをいたしますのでよろしくお願いします。
PowerShellでIISの仮想ディレクトリを作成

PowerShellを使用すればIISのあらゆる操作がコマンドで実行可能です。
環境構築の自動化・効率化に是非活用してください。

IISでアプリケーションとは別に「仮想ディレクトリ」を作成したい場合は以下のコマンドで実現できます。

```powershell
New-WebVirtualDirectory 
    -Site "Default Web Site"           #サイト名
    -Application "yourApp"             #アプリケーション名
    -Name "virtualDir"                 #仮想ディレクトリ名
    -PhysicalPath "C:\inetpub\realDir" #実フォルダのパス
    -Force                             #確認なしで実行
```
「http://◯◯◯◯/yourApp/virtualDir」という仮想ディレクトリが作成されます。
コメントを記載するため改行しましたが、一行で書くほうが好みです。

参考：公式ドキュメント
https://docs.microsoft.com/ja-jp/powershell/module/webadministration/new-webvirtualdirectory?view=windowsserver2019-ps&viewFallbackFrom=win10-ps
サーブレット、jsp、pageが正常に表示されない時のまとめ【Java】

#目的
サーブレット、jspなどのWeb page作成で上手くページが表示されない時のまとめ

#環境
eclipse2020-12 (4.18.0)
tomcat8.5
#Web pageを開いたら・・・・

■このサイトにアクセスできませんlocalhost で接続が拒否されました。

・サーバーに何か原因があるのかも
・今までアクセス出来ていたなら
　　→全てのサーブレットファイルのアノテーションを確認
　　/を忘れてないか？

```java:
@WebServlet("/MainServlet")
```


■HTTPステータス 404 – 見つかりません。
ファイルがありません

・フォワード、リダイレクト、リンク先など転送先のファイルがあるか、ファイル名が正く指定されているか
・本当にファイルはあるのか

```java:
	    RequestDispatcher dispatcher = request.getRequestDispatcher(
	            "/WEB-INF/jsp/main.jsp");
	        dispatcher.forward(request, response);
```



■HTTPステータス 405 – Method Not Allowed

・サーブレットでリクエストメソッドに対応した、メソッドが必要
・サーブレットクラスが実行される場合はdoGet（）が必要
・サーブレットにPOST処理を行う場合はdoPost()が必要

■HTTPステータス 500 – Internal Server Error
・原因は様々なので、メッセージやスタックトレースで原因の確認をお願いします。


■htmlのダウンロードページが表示される
・contentTypeはHTMLになっていないのかも
・jspの頭に下記のコードを加えてる


```jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
```

■データーベースで日本語が文字化けする
・文字コードの設定が必要
・Dao　fileの接続先DBurlの最後に文字コードをセットする必要があるのかも

```java:
String dbUrl = "jdbc:mysql://・・・・・?useUnicode=true&characterEncoding=utf8";
```

■jsp fileで画像が表示されない
・contextPathで絶対パスでやるとうまくいくかも


```java:
<img src="${pageContext.request.contextPath}/pic/○○.jpeg">
```

#終わりに

本記事でお役に立てないケースも、たくさんあると思いますが
エラーと向き合っている人々を応援はしていきたい
もし新たな、例外やエラーがありましたら、追加はしていきます。
Think Java エクササイズ

#Think Java Chapter 8 
##語彙
array
element
index
reference
alias
traversal
search
reduce
accumulator
deterministic
nondeterministic
pseudorandom
histogram
enhanced for loop

```java:ex8_2
public class ex8_2 {
    //パラメータは配列a
    //配列の数分ループを回す
    //kiwiとかけていきます。
    //Kiwiを出力します。
    public static int banana(int[] a) {

        int kiwi = 1;
        int i = 0;
        while (i < a.length) {
            kiwi = kiwi * a[i];
            i++;
        }
        return kiwi;
    }
    // 配列aをループ分回す
    // 配列aのi番目がgrapeだった時　iを返す
    // そうでなかった場合 -1を返す。
    public static int grapefruit(int[] a, int grape) {
        for (int i = 0; i < a.length; i++) {if (a[i] == grape)
        {
            return i;
        }
        }
        return -1;
    }

    // 配列aをループ分回す
    // 配列aのi番目がappleだった時　加算する。
    // 最終的にpearを返す。
    public static int pineapple(int[] a, int apple) {
        int pear = 0;
        for (int pine: a) {
            if (pine == apple) {
                pear++;
            }
        }
        return pear;
    }
ex8_4
 public static int indexOfMax(int[] a) {
        int l = 0;
        for (int i = a.length - 1; i > 0; i--) {
            if (a[l] < a[i]) {
                l = i;
            }
        }
        return l;
    }

ex8_6

 public static boolean areFactors(int n, int[] array) {
        boolean r = false;
        for (int i = 0; i < array.length - 1; i++) {
            if (array[i] == n) {
                r = true;
                return true;
            }else{
                r = false;

            }
        }
        return r;
    }

ex8_8

 public static int maxInRange(int[] integers, int lowIndex, int highIndex){
        if (lowIndex == highIndex){
            return integers[lowIndex];
        }
        int mid = (lowIndex + highIndex) / 2;
        return 
public static int max(int[] integers){
        return maxRange(integers, 0, integers.length-1);
    }


```
##コメント
他の教材でスラスラかける練習はした方がいいかも。
だいぶ考えました。ex8_8は答えを写経しました。再帰は勘弁してほしい。
WSLでWindowsのホームディレクトリ環境変数を設定


## Windows10の現在のユーザ名を取得

以下のコードより、Windows10のUSERNAME環境変数をWSLの環境変数として設定できる。
Windows10の改行コードは"CR+LF"であるが、Linuxの改行コードは"LF"である。
そのため、sedコマンドを使い、改行コードの変換を行う。
"^M"は"Ctrl+v"を押して,"Ctrl+m"を押すことで入力できる。

``` zsh:~/.zshrc
export WIN_USERNAME=$(powershell.exe '$env:USERNAME' | sed -e 's/^M//g')
```

## Windows10のホームディレクトリを取得

上記の環境変数を使い、Windows10の現在のユーザのホームディレクトリを示す
環境変数も追加できる。

``` zsh:~/.zshrc
export WIN_USERHOME=/mnt/c/Users/$WIN_USERNAME
```

すぐに、Windows10の現在のユーザのホームディレクトリに移動できるので、
便利だと思う(小並感)。

``` zsh
$ cd $WIN_USERHOME
$ pwd
/mnt/c/Users/[Windowsのユーザ名]
```

## おすすめの設定

WSLのほかの環境でもrcファイルを共有している場合は以下のように書くとよい。

``` zsh:~/.zshrc
if [ "$(uname 2> /dev/null)" = Linux ]; then
  if [[ "$(uname -r 2> /dev/null)" = *microsoft* ]]; then
    export WIN_USERNAME=$(powershell.exe '$env:USERNAME' | sed -e 's/^M//g')
    export WIN_USERHOME=/mnt/c/Users/$WIN_USERNAME
    export WIN_USERDESK=$WIN_USERHOME/Desktop
  fi
fi
```

## References

* [[shell] WSL かどうかを判別する](https://moyapro.com/2018/03/21/detect-wsl/)

* [How do I get windows ENV from WSL bash script? | Stackoverflow](https://stackoverflow.com/questions/48413936/how-do-i-get-windows-env-from-wsl-bash-script)

* [テキストファイルの行末に^Mが表示される](https://www.atmarkit.co.jp/flinux/rensai/linuxtips/164linendm.html)
[Swift] AVAudioPlayerをSingletonにする

```AudioPlayer.swift
import AVFoundation

class AudioPlayer {
    static let shared = AudioPlayer()
    private init() {}

    private var player = AVAudioPlayer()

    func playAlarm() {
        let url = Bundle.main.url(forResource: "alarm", withExtension: "wav", subdirectory: "raw")!
        do {
            try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)
            try AVAudioSession.sharedInstance().setActive(true)
            player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue)
            player.play()
        } catch {
            print(error.localizedDescription)
        }
    }
}
```

呼び出し方

```test.swift
AudioPlayer.shared.playAlarm()
```

# 参考

- https://stackoverflow.com/a/32036291/4791194
- https://medium.com/swift-column/singleton-398078bcc58d
- https://developer.apple.com/documentation/swift/cocoa_design_patterns/managing_a_shared_resource_using_a_singleton
UnityでSystem.Drawingを使用する

# 通常の状態ではUnity内にSystem.Drawing.dllは含まれていない。

下記のパスからコピーして持ってくる。ちなみに.Netのフォルダから持ってくると名前解決はできるが、実際に呼び出しなどを行うとUnityエディタが強制終了する不具合が発生することがある。

> C:\Program Files\Unity\Hub\Editor\ **[Unityバージョン]** \Editor\Data\MonoBleedingEdge\lib\mono\4.5

csc.rspを記述する方法も考えたが、製品にビルドする際にエラーが出てしまう。[^1]

#参照

[Unity Forums](https://forum.unity.com/threads/using-system-drawing-image-works-but-shows-as-error.653848/)
[^1]:[Unity Answers - csc.rsp works in editor but throws an error when building](https://answers.unity.com/questions/1724720/cscrsp-works-in-editor-but-throws-an-error-when-bu.html)
[Unity]Zenject(Extenject)を練習してみた

# 最初に
この記事は先達の方々の記事をなぞった過程をまとめただけの記事です。僕と同じように「Zenjectをとりあえず触ってみたい」と思った方のちょっとした道しるべになればと思い記事にしました。
今回、Zenjectを理解する為に３つの記事を参考にして動作確認できるプロジェクトを作りました。
# Extenjectについて

Zenjectは更新が止まってしまいUnityAssetStoreでの公開は終了しています。代わりに今回はExtenjectを使用しました。Package Managerからインポートできます。
![スクリーンショット 2022-12-21 6.51.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/4fb47948-3c29-077f-e140-93c0af09707d.png)

参考記事：「Extenjectとは」の項
https://qiita.com/4_mio_11/items/4306732bc47780802b74#extenjectとは
# Dependency Injectionについて
Zenjectを使用するとDependency Injectionというデザインパターンを実現する事ができます。
Dependency Injectionのイメージはこの図がわかりやすいと思います
参考記事：「Dependency Injectionとは」の項
https://note.com/thedesignium/n/n771fb79ab263
# 実際に作ってみる
参考記事
https://light11.hatenadiary.com/entry/2019/02/16/225023
実際の動作確認はこの記事に従うと簡単に出来ると思います。
記事ではZenjectを使用していますが、上にも書いた通りUnityAssetStoreでの公開は終了しています。Extenjectをインポートしていてもコードの変更は一切必要なく動作しました。
# 補足
Zenjectは参考にできる資料がとても少なかったです。
とりあえず僕と同じように「難しぃ～」と感じてる方は上記３記事を渡り歩くと理解が深まると思います。
# さらに理解を深めるために
Unity開発で使える設計の話＋Zenjectの紹介
https://www.slideshare.net/torisoup/unityzenject
<Swift> Documentsディレクトリ内へファイルの保存処理と取得処理

# はじめに
前の記事を見ると"はじめてに"という誤植がありました。。。恥ずかし。。。
Documentディレクトリについてお仕事でつまずいたのでまとめます。備忘録です。

# Documentsディレクトリ
アプリ内で保有しているフォルダの一つでユーザ作成のコンテンツ(文書や画像、動画など)を保存しているのに適しています。

### ディレクトリ操作に関する注意点
Swiftでアプリ内のファイル操作には、ファイルをString型のパスで指定する方法と、URL型のファイルURLで指定する方法の2通りがあります。
※ファイルURLは パスの先頭に”file://” が付加されているため、ファイルURLをパスに変換する場合、単純にキャスト(ファイルURL.absoluteString)しても上手くいかないです。

### Documentsディレクトリ内に写真ファイルを保存する

まずは、以下のとおりDocumentsディレクトリ のファイルURLを取得します。

```swift
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
```

次に、保存する写真データの名前を付けます。※名前が重複すると保存できない。撮影した年月日時間を名前に入れてあげるなど工夫が必要です。

```swift
​let fileName: String? = "IMG.jpg"
```
ディレクトリのパスにファイル名をつなげてファイルのフルパスを作成しましょう。

```swift
let fileURL = documentsURL.appendingPathComponent(fileName!)
```

写真ファイルをDocumentsディレクトリへ保存します。
※名前が重複すると保存できないです。撮影した年月日時間を名前に入れてあげるなど工夫が必要です。

```swift
let jpgImageData = image.jpegData(compressionQuality:0.5)

do {
try jpgImageData!.write(to: fileURL, options: .atomic)
} catch {
print(error)
}
```

### Documentsディレクトリ内のファイルを全て取得する

まずはDocumentsディレクトリ のファイルURLを取得します。

```swift
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
```

次にDocuments ディレクトリ配下のファイル一覧をURL型で取得します。
※FileManager.default.contentsOfDirectory(at: documentsURL)の場合、ファイル名の一覧が取得できます。（["file1", "file2", "directory1"]）

```swift
do {
let contentURLs = try FileManager.default.contentsOfDirectory(at: documentsURL, includingPropertiesForKeys: nil)
} catch {
print("error")
}
```

## 参考記事
以下を参考にさせていただきました。ありがたや。
・【Swift4】コピペで出来るDocumentsフォルダの操作方法(画像の保存編)
　　https://qiita.com/ryomaDsakamoto/items/ab8e5cd9da1ea70f3302
・【iOS】デバイス(ローカル)にデータを保存する方法
　　https://qiita.com/shiz/items/c7a9b3218269c5c92fed
・[Swift3.0] パスとファイルURLの違いと相互変換の方法
　　https://joyplot.com/documents/swift-fileurl-path/
・撮影した動画ファイルを iOS アプリ内に保存し、任意のタイミングでフォトライブラリに書き出す Swift コード
　　https://neos21.net/blog/2019/01/11-02.html
・【Swift】テキストファイルの読み書き
　　https://capibara1969.com/2836/#toc13
・[iOS][Swift]指定したディレクトリにあるファイルの一覧を取得する
　　https://egg-is-world.com/2017/08/13/ios-swift-file-list/
・【Swift】URLでパスを扱うときに便利なプロパティとメソッド
　　https://qiita.com/toshi586014/items/52b87c034e411681ca7b
大自然の掟　という詠み方

#初めに
世界には色々な人がいます。
その人々は海に大地を建て山を作り川を通し沢にたどり着きました。
彼らの所業は大自然がしっかり記憶しておりそれを好む側面があるのです。
その読み方です。

#エレメント
山、川、野、池、海、磯。等々。
これ等に住む人々には欲求がありそれが形骸化して詠むことが可能になりました。

#一例
山の人は野や川や町、村、坂などを通って海につきます。
そこに行って物々交換をして、それを収穫としたことによって山に帰ります。
これは大自然の掟では、人に問うときに「あなたは今どこら辺似ますか？山の人」というと、返答があります。
村だったら、「その村では何をやっている」という感じで聞いていくと細部を詰めることが可能です。
それを俯瞰して、「あなたの欲求はこれですね」ということを現在にリマップすることで解を得られるでしょう。

#所在
大自然の掟で使われる主体はかなりの数があります。一説には50以上あるんじゃないかというくらいにあります。
海の人もまた活動をしていて色々回って帰ってきます。
そこに住む人にはそこの人の正しさが形成されて形骸化しています。それを使って詠ませてもらうのです。
日本人は大体どこかのリージョンに属していてそれに付随する欲求を持っています。
それを活用しているのです。

#終わりに
雑文になってしまいましたが、一応メモ程度に書いておきました。
大自然の掟を使うことで問題の本質をおしえてもらうことができるようになります。
共通理解は人を豊かにしますね。

では、それで。
インライン要素の動画をボタン一つでどの端末でも全画面再生にする方法【Fullscreen APIがきかない場合の対応】

こんにちは、[Yui](https://twitter.com/yui_active)です。

今回インライン要素で表示している動画を、ボタン一つで拡大再生させる方法について書きます。

## 背景
playsinlineを指定しているビデオタグに対して、クリックアクションで全画面再生をさせたい場面があり、[Fullscreen API](https://developer.mozilla.org/ja/docs/Web/API/Fullscreen_API)を読むとそれぞれメソッドがブラウザごとに違うらしいので、条件分岐で対応しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670446/9cd6b3f3-0b20-6942-7e9f-966f59a9ae75.png)

また、公式ではIE非対応らしく書いているますが、どうやらIE11からサポートされたらしい（参考[特定の要素を全画面(フルスクリーン)にするFullscreen API](https://w3g.jp/blog/html5_fullscreen_api)）ので、以下のように書きました。（IE10以前はもう知らん..）


```vuejs
<video ref="video" src="sample.mp4" playsinline />
<button @click="fullScreen">全画面再生</button>
<script>
export default {
  methods: {
    fullScreen() {
      const video = this.$refs.video;
      if (video.webkitRequestFullscreen) {
        video.webkitRequestFullscreen();
      } else if (video.mozRequestFullScreen) {
        video.mozRequestFullScreen();
      } else if (video.msRequestFullscreen) {
        video.msRequestFullscreen();
      } else if (video.requestFullscreen) {
        video.requestFullscreen();
      } else {
        alert("全画面再生できません。");
      }
    },
  },
};
</script>
```

ただ、これだとスマートフォン非対応なので、スマートフォン用のメソッドを追加する必要がありました。

## 解決策
[アップルのドキュメント](https://developer.apple.com/documentation/webkitjs/htmlvideoelement/1633500-webkitenterfullscreen)をしっかり読むと書いてました。
``webkitEnterFullscreen``というらしいです。
そこでこう書き換えて終わり。

```vuejs
<video ref="video" src="sample.mp4" playsinline />
<button @click="fullScreen">全画面再生</button>
<script>
export default {
  methods: {
    fullScreen() {
      const video = this.$refs.video;
      if (video.webkitRequestFullscreen) {
        video.webkitRequestFullscreen();
      } else if (video.webkitEnterFullscreen) {
        video.webkitEnterFullscreen();
      } else if (video.mozRequestFullScreen) {
        video.mozRequestFullScreen();
      } else if (video.msRequestFullscreen) {
        video.msRequestFullscreen();
      } else if (video.requestFullscreen) {
        video.requestFullscreen();
      } else {
        alert("全画面再生できません。");
      }
    },
  },
};
</script>
```

Androidに関しては調べられなかったのですが、stack overflowでの[この質問と回答](https://stackoverflow.com/questions/29363665/force-full-screen-html5-video-playback-on-ipad-and-android-tablets)を読む限りAndroidでも動くっぽいですね〜。

## 感想
やむなしな気もしますが、条件分岐が多くて気持ち悪いですね。
他にもっと良い書き方あれば教えて下さい〜。
fish shell のタブ補完がやたら遅くなったなと思ったら。

表題のことを、去年から思っていたが、仕事が忙しく調べるのを後回しにしていた。

調べてみると、 big sur でそういった事象が発生していたらしく、バージョンを `3.2.0` にすると直るらしい。

https://qiita.com/geekduck/items/9a935b755d341002b1e7


```sh
fish -v
3.0.2
```

```sh
brew update
brew upgrade fish
```

```sh
fish -v
3.2.1
```

直った。
めでたしめでたし。
え、まだsetup.py使ってるの? pyproject.tomlとsetup.cfgで宣言的パッケージング

というタイトルは煽りで、個人的にはまだ時期尚早な感じもあると思いますが。
いずれはこちらが標準になるでしょうし。なんだかんだで結構苦労したので、`setuptools`を使うが`setup.py`は使わずに`pyproject.toml`と`setup.cfg`を使ってパッケージを作る方法をメモしておきます。

# `pyproject.toml`って?
ざっくりいうと、みんな`setup.py`を書いたり動かしたりするのに疲れたのだと思います。

`pyproject.toml`について規定している[PEP 518](https://www.python.org/dev/peps/pep-0518/)では、`setup.py`自体を動かすために必要な依存パッケージを定義する標準的な方法がないことがモチベーションとされています。個人的には、`setup_requirements.txt`でも用意すればいいのでは、と感じましたが。まぁ、みんな`setup.py`に疲れたのだと思います。

いずれにせよ、`setuptools`の他にも、`poetry`や`flit`などのビルドツールもあるらしく、今は`setuptools`がデファクトスタンダードだけど、ずっと主流とは限らないよねー、標準的な方法を作っておきたいねー、ていうか、`setup.py`に疲れたんだよ、ということだと思います。

# `pyproject.toml`で`setuptools`を使うには

`pyproject.toml`を以下のようにします。

```toml:pyproject.toml
[build-system]
requires = ["wheel", "setuptools"]
build-backend = "setuptools.build_meta"
```

# `setup.cfg`を書こう
続いて、`setup.py`の代わりに`setup.cfg`を作ります。
ぶっちゃけこれは、`setuptools.setup()`の引数を設定ファイルの形式にしただけですが、`[metadata]`と`[options]`に項目を分けて書かなければいけません。

setuptools公式ドキュメントの[Quick Start](https://setuptools.readthedocs.io/en/latest/userguide/quickstart.html#basic-use)と[Configuring setup() using setup.cfg files](https://setuptools.readthedocs.io/en/latest/userguide/declarative_config.html)に詳細が載っています。

参考までに、[私の関わっているプロジェクト](https://github.com/Blueqat/braket-backend/blob/d85c29c1cce490f5c41ba8ba4182419d15beab69/setup.cfg)の`setup.cfg`を以下に示します。

```text:setup.cfg
[metadata]
name = braket-backend-blueqat
version = 0.0.1-pre
description = Braket backend for blueqat
long_description = file: README.md
long_description_content_type = text/markdown
license = Apache-2.0
author = gyu-don
author_email = kato@blueqat.com
classifiers =
    Development Status :: 3 - Alpha
    License :: OSI Approved :: Apache Software License
    Programming Language :: Python :: 3.7
    Programming Language :: Python :: 3.8

[options]
packages = find:
install_requires =
    blueqat >= 0.4.2
    amazon-braket-sdk >= 1.5.13
```

ほとんど`setup.py`と同じですね。

なお、`attr:`や`file:`など、いくつか、設定を書く際に便利なものがあります。`setup.py`で`README.md`の中身を読んでいたのとかが詳細はやはり[ドキュメント](https://setuptools.readthedocs.io/en/latest/userguide/declarative_config.html#specifying-values)に書かれています。

なお、`version`の指定に`attr:`を使うことも考えたのですが、その場合、一旦自分自身を`import`することになるので、ビルド環境に自分自身の`install_requires`が必要となり、それは面倒なのでやめました。
代わりに[GitHub Actionsを使ってsetup.cfgをもとに_version.pyを更新する](https://qiita.com/gyu-don/items/c047098e1a58dc8d8d96)ことで解決しています。

# ビルドをしよう

`python -m build` で、忌々しい`setup.py`なしでビルドができます。

`No module named build` というエラーが出る場合は `pip install build`をしてから、再度`python -m build`をしてください。


# `setup.cfg`があれば`setup.py`も簡単に書ける

せっかく`setup.py`を消し去ったのになぜ、、、という気もするのですが。もし`setup.py`も欲しい場合、`setup.cfg`があれば`setup.py`は以下だけで構いません。

```py:setup.py
from setuptools import setup
setup()
```

なお、`setup.py`が必要となる場面のひとつに、editableなインストールがあります。`pip install .`は`setup.py`がなくてもできるのですが、`pip install -e .`は`setup.py`がないと対応していないようです。

# いかがでしたか
よきPythonライフを！
Microsoft Teamsのキャッシュクリアスクリプト(Mac)

## 環境

- OS：macOS Catalina 10.15.7
- Teams：1.4.00.7175

## スクリプト

```bash:clear_cache_of_teams.sh
rm -rf ~/Library/Application\ Support/Microsoft/Teams/
rm -rf ~/Library/Application\ Support/com.microsoft.Teams/
rm -rf ~/Library/Caches/com.microsoft.teams/
rm -rf ~/Library/Caches/com.microsoft.teams.shiplt
rm -rf ~/Library/Preferences/com.microsoft.teams.plist

```

## 備考

- 私の環境に `~/Library/Caches/com.microsoft.teams.shiplt` はなかった
【一対一対応で分かる！】Railsインストールからブラウザにhello,world!を表示するまでの全手順

※環境は、AWSのCloud9を使っています。

(1)Railsインストール

```
$ gem install rails -v 6.0.3
```

(2-1)yarnのインストール

```
$ source <(curl -sL https://cdn.learnenough.com/yarn_install)
```

(2-2)yarnがインストールできなかった場合

```
$ yarn install --check-files
```

(3)アプリの作成

```
$ rails _6.0.3_ new hello_app
```

(4)gemfileを一新する

```gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

gem 'rails',      '6.0.3'
gem 'puma',       '4.3.6'
gem 'sass-rails', '5.1.0'
gem 'webpacker',  '4.0.7'
gem 'turbolinks', '5.2.0'
gem 'jbuilder',   '2.9.1'
gem 'bootsnap',   '1.4.5', require: false

group :development, :test do
  gem 'sqlite3', '1.4.1'
  gem 'byebug',  '11.0.1', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  gem 'web-console',           '4.0.1'
  gem 'listen',                '3.1.5'
  gem 'spring',                '2.1.0'
  gem 'spring-watcher-listen', '2.0.1'
end

group :test do
  gem 'capybara',           '3.28.0'
  gem 'selenium-webdriver', '3.142.4'
  gem 'webdrivers',         '4.1.2'
end

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
```

(5)hello_appに移動する

```
$ cd hello_app/
```

(6-1)gemインストール

```
$ bundle install
```

(6-2)エラーが起こった場合

```
$ bundle update
```

(6-3)もう一度gemインストール

```
$ bundle install
```

(7)application_controller.rbの書き換え

```app/controllers/application_controller.rb
class ApplicationController < ActionController::Base

  def hello
    render html: "hello, world!"
  end
end
```

(8)routes.rbの書き換え

```
Rails.application.routes.draw do
  root 'application#hello'
end
```

(9)ローカルサーバーへの接続を許可のためにconfig.hosts.clearをRails.application.configure do内に含める

```config/environments/development.rb
config.hosts.clear
```

(10)サーバーの立ち上げ

```
$ rails server
```

(11)ブラウザに表示

![share_workspace.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1270404/18853201-3e9e-a503-32c2-c8b81d8c85fd.png)

![full_browser_window.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1270404/7c0e2a6a-1ed7-f0d1-aa34-139a133d9a09.png)

(12)サーバーを閉じる

Ctrl + C
Google Drive File Streamがタスクトレイから消えた。エクスプローラーの同期も切れた。

#症状
Google Drive File Streamがタスクトレイから消えた！
エクスプローラーの同期も切れた！

アホみたいな内容ですが、
数カ月に一度くらいの頻度で起こるので。

設定のしなおしを、備忘録として。

#環境
Windows 10

#手順
###Google Driveアプリを起動しなおす
1. 「スタートメニュー」（タスクバー一番左のWindowsのアイコン）をクリック
2. 「Google Drive」を選択して起動
3. アカウントを入力

以上。


##終わりに
私の場合は、**アプリが落ちていたことが原因**だったようです。
おかげで簡単に直せました。

もし同じ症状に陥ってしまったときは、
まずはこの方法をお試しいただければと思います。

この方法でも直らなければ他の原因かもしれません。
その際は、お手数ですがご自身でお調べください。

私的、備忘録でした。

それでは。
PHP DateTimeについて　〜フォーマット文字など〜

#フォーマット文字についての基本

詳細は：[フォーマット文字](https://www.php.net/manual/ja/datetime.format.php)

###日付（ j, d)
**j： 1~31**
**d：01~31**

###曜日（ D )

**D：Mon~Son**

###月（ n, m )
**n： 1~12**
**m：01~12**

###年（ y, Y )
（2021年）
**y： 21**
**Y：2021**

###時間（ g, G )
**g：1~12**
（1~12の12時間表示）

**G：0~23**
(0~23の24時間表示）

###分（ i )
**i：00~59**

###秒（ s )
**s：00~59**


##使用例（2021年4月2日（金）9時34分23秒）

```php
<?php 
//2021年4月2日（金）９時34分23秒
$now = new DateTime();
$now2 = new DateTime();
$now3 = new DateTime();
$now4 = new DateTime();
print $now->format('n/j/Y')."\n"; //4/2/2021
print $now2->format('m/d/y')."\n"; //04/02/21
print $now3->format('g:i:s')."\n"; //9:34:23
print $now4->format('M:D:Y')."\n"; //Apr:Fri:2021
```
JavaのExecutorServiceを正しく終了する

追記:

Java 19 から [ExecutorService#close](https://docs.oracle.com/javase/jp/20/docs/api/java.base/java/util/concurrent/ExecutorService.html#close()) を使えばよさそうです。

---

# コード

ExecutorServiceを停止するユーティリティ的な（Kotlin）

```kotlin
object ExecutorServiceUtils {

  val log by logger()

  /**
   * [ExecutorService]を正しく終了する。
   * 実行中のタスクがある場合は終了を待機する。
   * 一定時間待機しても終了しないタスクがある場合はキャンセル（interrupt）しようとする。
   *
   * @param pool          [ExecutorService]
   * @param waitTimeout   実行中のタスクの待機時間
   * @param cancelTimeout 実行中のタスクをキャンセルするときの待機時間
   */
  fun shutdownAndAwaitTermination(
      pool: ExecutorService,
      waitTimeout: Duration,
      cancelTimeout: Duration
  ) {
    pool.shutdown() // 新しいタスクの受付を停止
    try {
      // 実行中のタスクの終了を待機
      if (!pool.awaitTermination(waitTimeout.toMillis(), TimeUnit.MILLISECONDS)) {
        // 待機がタイムアウトしたとき
        log.warn("一定時間待機したが終了しないタスクがあるので、実行中のタスクをキャンセルする")
        pool.shutdownNow() // 実行中のタスクをキャンセルする
        // 実際に停止するまでもう一回待機
        if (!pool.awaitTermination(cancelTimeout.toMillis(), TimeUnit.MILLISECONDS)) {
          // 待機がタイムアウトしたとき
          log.warn("実行中のタスクをキャンセルできない")
        }
      }
    } catch (ie: InterruptedException) {
      // 現在のスレッドが割り込みされたとき、実行中のタスクを（もう一度）キャンセルしておく
      pool.shutdownNow()
      // interruptedのステータスを保持
      Thread.currentThread().interrupt()
    }
  }
}
```

## 解説
### `shutdown()`

シャットダウンを開始する

- 新しいタスクを受け付けないようになる
- 実行中のタスクがある場合はそのまま実行される
- 実行中のタスクの完了を待機しない。待機したい場合は`awaitTermination`を使う

### `awaitTermination(long, TimeUnit)`

実行中のタスクが終了するまで待機する（処理をブロックする）

- 実行中のタスクがない場合は特になにもしない
- 指定したタイムアウト時間経っても終了しない場合は`false`を返す
- 待機している間に現在のスレッドに対して割り込み（interrupt）があった場合は`InterruptedException`がスローされる

### `shutdownNow()`

実行中のタスクの停止（キャンセル）を試みる

- タスクを停止できるとは限らない（`Thread.interrupt()`するだけなので。タスク側の処理を停止可能なように作っておく必要がある）
- 停止完了まで待機しない。待機したい場合は`awaitTermination`を使う

## このサンプルコードの注意点
1つのアプリケーションの中で複数の`ExecutorService`を扱う場合、サンプルコードのログ出力ではどの`ExecutorService`に関するログなのか判断できない。

## 参考
[ExecutorService (Java Platform SE 8)](https://docs.oracle.com/javase/jp/8/docs/api/java/util/concurrent/ExecutorService.html)
機械学習初心者がデータサイエンスを学んでみた

# はじめに
オンライン学習サイトにて、実践データサイエンス講座（3か月間）を受講したことをまとめてみた。
受講期間：2021/1～2021/3

# 本記事の概要
・自己紹介
・受講理由
・学習内容
・受講後の感想

# 自己紹介
・30代後半
・Javaの開発経験あり
・python、機械学習は未経験

# 受講理由
・データ分析業務関連の部署に異動し、自社内外の方とデータの利活用について企画検討する機会が発生
・自身でデータ分析するまでのスキルは必要とされないが、機械学習の概論を抑えデータサイエンティストと気持ちよく仕事ができるようになりたい
・書籍や講義だけでなく実践を通してデータサイエンス力をつけたい

# 学習内容
・Python入門
・Numpy
・Pandas
・Matplotlib
・機械学習概論
・データクレンジング
・教師あり学習（回帰）
・教師あり学習（分類）
・教師なし学習
・タイタニック号
・住宅価格予想

# 受講後の感想
受講を通してPythonの基礎、機械学習の概略を学ぶことができた。
Kaggleでも通用する能力まではより学習時間の確保が必要だが、受講後もダウンロードした研修資料を基に復習可能であることから継続的に自習に励むことができる。
夕方以降ではあるが、Slackによるサポートが受けれれることと、練習問題、演習問題を通じて短期間に機械学習の概要を理解することができる。
これから機械学習を始める人や、企業の機械学習カリキュラムの一環として導入する方には体系的に学習でき基礎知識が身につくと思う。
データサイエンティストとして活躍するには、本学習以外にもビジネス力をどのように身に着けていくか。このあたりは別の講習で学習が必要だと感じた。
Javascriptでポップアップウィンドウを自作

##完成品

###HTML
```html:html
<div id="popup">Click</div>
<div id="popWin">
    <div class="pop-win">
        ポップアップウィンドウ
        <div id="close">閉じる</div>
    </div>
</div>
```

###CSS
```css:css
#popup {
  text-align: center;
  font-weight: bold;
  display: block;
  width: 100px;
  padding: 10px;
  border: solid;
  border-radius: 8px;
  margin: 0 auto;
  cursor: pointer;
}
#popWin {
  position: fixed;
	top: 0;
	left: 0;
	width: 100vw;
	height: 100vh;
	z-index: 0;
	display: none;
	justify-content: center;
	align-items: center;
	background-color: rgba(0,0,0,.5);
}
.pop-win {
	width: 50vw;
	height: 50vh;
	background-color: #fff;
}
#close {
	color: #fff;
	position: absolute;
	top: 20px;
	right: 20px;
	cursor: pointer;
}
```

###Javascript
```javascript:javascript
const popup = document.getElementById('popup');
const close = document.getElementById('close');
const popWin = document.getElementById('popWin');
popup.addEventListener('click', () => {
    popWin.style.display = 'flex';
});
close.addEventListener('click', () => {
    popWin.style.display = 'none';
});
```

###サンプル
<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="css,result" data-user="sugoi-reirei" data-slug-hash="wvgJxEb" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="pop-up_window">
  <span>See the Pen <a href="https://codepen.io/sugoi-reirei/pen/wvgJxEb">
  pop-up_window</a> by reirei (<a href="https://codepen.io/sugoi-reirei">@sugoi-reirei</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>