OmniAICreator/Qiita-1.07M huggingface dataset:
Alpine.jsでデータバインディング

2021/10/20
3系がリリースされていたので、サンプルコード及び記事の修正を行いました。

# はじめに

最近、Alpine.jsというライブラリを知りました。
Vue.jsに影響を受けているようで書き心地は似ているのですが、データバインディングに特化していてVue.jsよりも軽量なので、SPA用途でなくデータバインディング用途でVue.jsを使用しているという場合は、代替になり得ると感じました。
　→当時はなかったのですが最近はpetite-vueというライブラリが開発されているので、Vue.jsの代替という意味では現在はそちらを使う方が良さそうです。

Vue.jsと比較すると以下の点でメリットがあると感じます。

1. 軽量
1. データオブジェクトをPOJOで定義できるので、thisのコンテキストが明確

　→こちらもVue.js本体と比較したらの話なので、現在はpetite-vueと比較する方が良いですね。

# 試してみる

Alpine.jsは「HTMLに属性値としてJavaScriptが書ける」ことを強みにしており、属性値で書くパターンとscriptタグで分けて書くパターンがありますが、今回はscriptタグで分けて書く場合にフォーカスを絞って、サンプルを紹介できたらと思います。

# サンプルコード

```html
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Alpine.js Sample</title>
  <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
  <style>
    /*
      Alpine.jsの初期化が終わるとx-cloak属性が削除される。つまり、x-cloak属性にdisplay:noneを
      定義すると、x-cloak属性を持つタグは初期化が終わるまで非表示になり、画面のちらつきを抑えられる。
    */
    [x-cloak] {
      display: none
    }
  </style>
</head>

<body>
  <!-- データバインディングしたいタグをx-data属性で定義 -->
  <div x-data="app" x-cloak>
    <!-- Vue.jsと違いinnerTextの定義に {{ hoge }} が使えないため、x-text属性に定義する -->
    <h1 x-text="`Hello, ${fullname}!`"></h1>
    <h3 class="js_subtitle"></h3>
    <p x-text="`2way-binding: ${inputValue}`"></p>
    <!-- x-on:eventは@eventで省略可能 preventなどのmodifierも使用できる -->
    <form @submit.prevent="handleSubmit">
      <!-- x-modelによる双方向バインディングも使用可能 -->
      <input type="text" x-model="inputValue">
      <input type="submit" value="Submit">
    </form>
  </div>
  <script>
    const app = () => ({
      // プロパティはそのままリアクティブになる
      // Vue.jsにおけるdataオブジェクトに相当
      firstName: 'Taro',
      lastName: 'Tanaka',
      inputValue: '',
      // Vue.jsにおけるcomputedオブジェクトに相当
      get fullname() {
        return `${this.firstName} ${this.lastName}`;
      },
      // Vue.jsにおけるmethodsオブジェクトは、そのままメソッドとして書ける
      init() {
        // initメソッドはマウント後に実行される
        console.log('Initialize');
        // コンポーネント内のDOMを掴みたいときはthis.$elで参照できる
        this.$el.querySelector('.js_subtitle').textContent = 'This is manual binding.';
        // プロパティの変更を監視したい場合は、this.$watchのコールバックで定義できる
        // Vue.jsのwatchオブジェクトに相当
        this.$watch('inputValue', (currentValue) => {
          console.log(`updated inputValue: ${currentValue}`);
        });
      },
      handleSubmit() {
        console.log(`submited with inputValue: ${this.inputValue}`);
        this.inputValue = '';
      }
    });

    // Alpine.jsの初期化終了時にバインディング処理を実行する
    document.addEventListener('alpine:init', () => {
      // x-data="app" に対してバインディング
      Alpine.data('app', app);
    });
  </script>
</body>

</html>
```
x-ifやx-forをtemplateタグ内に書く必要があったりと、Vue.jsと微妙に違う点がいくつかありますが、この例をベースにドキュメントを読み進んで頂ければ、理解の助けになるかと思います。

# 良いと思った点
Vue.jsと違いデータオブジェクトがプレーンなので、thisのコンテキストをエディタが推論可能になります。
今回はVSCodeを使用して書きましたが、拡張機能の追加なしにthisのプロパティやメソッドが推論されるのは良いですね。
メソッドがそのまま定義できますし、ゲッターを使用したcomputedの処理も直感的に感じます。

今後、画面の一部でデータバインディングを使用したくなった際は、積極的に採用してみたいですね。
Delphi TVirtualStringTree で表示内容に合わせてセルの高さを調整する。

#デフォルトではこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625152/04bff17e-a13a-9b10-56af-fe2cbad9d4a6.png)

#セル高さを調整後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625152/376dfcd0-b106-ee4b-d45b-999d27c66ae8.png)

#指定方法
 ・TreeOptions.MiscOptions.toVariableNodeHeight をTrueにする。
 ・MeasureItemイベントへ記述
　  Sender.MultiLine[node] をTrueにする
　  ComputeNodeHeightメソッドを使ってNodeHeightを設定する。

#サンプルソース
```Pascal
  private
    { Private 宣言 }
    value : array[0..4] of string;

procedure TForm1.FormCreate(Sender: TObject);
begin
  value[0] := 'あいうえお';
  value[1] := 'あいうえおかきくけこ';
  value[2] := 'あいうえおかきくけこさしすせそ';
  value[3] := 'あいうえおかきくけこさしすせそたちつてと';
  value[4] := 'あいうえおかきくけこさしすせそたちつてとなにぬねの';
  VirtualStringTree1.TreeOptions.PaintOptions := 
    [toShowHorzGridLines,toShowVertGridLines];
  VirtualStringTree1.TreeOptions.MiscOptions := 
    VirtualStringTree1.TreeOptions.MiscOptions +
    [toVariableNodeHeight];
  VirtualStringTree1.RootNodeCount := 5;
end;

procedure TForm1.VirtualStringTree1GetText(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
  var CellText: string);
begin
  CellText := value[node.Index];
end;

procedure TForm1.VirtualStringTree1MeasureItem(Sender: TBaseVirtualTree;
  TargetCanvas: TCanvas; Node: PVirtualNode; var NodeHeight: Integer);
begin
  Sender.MultiLine[node] := True;
  NodeHeight := 
     VirtualStringTree1.ComputeNodeHeight(TargetCanvas,node,0,value[node.Index]) + 8;
end;

```
railsでbootstrapを使う

#bootstrapとは

洗練されたWebデザインとユーザーインターフェイス要素を簡単に導入できるCSSのフレームワーク。
最大の特徴はアプリケーションをレスポンシブデザインにできること。

[公式サイト](https://getbootstrap.jp/)

#導入
##①gemファイルを記入

```ruby:Gemfile
source 'https://rubygems.org'

gem 'bootstrap', '~> 4.5.0'
.
.
.
```

![スクリーンショット 2021-01-23 17.22.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/879803/72d3bdec-a77c-704f-aeee-1a13861455c5.png)


##②ターミナルでbundleをインストールする

```
$ bundle install
```

##③scssファイル作成
/app/assets/stylesheets/application.scss のファイルを作成。

```scss:/app/assets/stylesheets/application.scss
@import "bootstrap-sprockets";
@import "bootstrap";
.
.
.
```

##④コードの記入

bootstrapはclassを特定のコードに書き変えると自動で色や大きさを変えてくれます。

今回はこのボタンにbootstrapを当ててみます。

![スクリーンショット 2021-01-23 17.34.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/879803/6805b294-ad68-839d-ee22-3329f3e2dea0.png)

公式サイトのCompornents →　buttons の中のこのコードを使います。

![スクリーンショット 2021-01-23 17.34.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/879803/7ab77f77-c30d-f309-740c-dfdab0f3bac8.png)

classの部分をコピーしてコードに貼り付ける。

![スクリーンショット 2021-01-23 17.44.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/879803/573c21b1-357f-dc91-3417-7fd68a523c08.png)

↓

![スクリーンショット 2021-01-23 17.44.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/879803/481928e1-b501-ded8-297e-d15fbb311937.png)

サーバーを再起動すると、、、

![スクリーンショット 2021-01-23 17.47.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/879803/70848aff-4c39-1e2c-06d4-3faa8e0a6c60.png)

指定したボタンに早変わり！！
AWSへDockerホストのプロビジョニングをする際にcredentialsがない旨のエラーが表示される

AWSへDockerホストのプロビジョニングをする際に、アクセスキーやシークレットキーを記述したcredentialsファイルを作成して、AWSにDocker Engineが動作するインスタンス作成するコマンドを実行したところ、下記エラーが出力されました。


```linux
$ docker-machine create --driver amazonec2 --amazonec2-open-port 8000 --amazonec2-region ap-northeast-1 aws-sandbox
Error setting machine configuration from flags provided: amazonec2 driver requires AWS credentials configured with the --amazonec2-access-key and --amazonec2-secret-key options, environment variables, ~/.aws/credentials, or an instance role
```

これはcredentialsのファイルがないか、もしくは作成する権限がおかしいことを意味するエラーの模様。
AWSで作成したIAMユーザの権限はadmin権限を渡しているので特に問題がないため、credentialsファイルがどうやら悪さしているみたいです。

##対策
調べたところ、credentialsファイルの置き場所が悪かったようです。
credentialsファイルはユーザのホームディレクトリ配下に作成しなければいけませんでした。

```linux
mkdir ~/.aws
vi ~/.aws/credentials
```
適当な作業ディレクトリにawsディレクトリを作成して、その配下にcredentialsファイルを作成しておりましたが、ユーザのホームディレクトリ配下にcredentialsファイルを作成してコマンドの実行ユーザに紐付けしなければ、当然AWSへインスタンス作成はできないですよね。

これで無事AWSへインスタンス作成が完了です。

```linux
$ docker-machine create --driver amazonec2 --amazonec2-open-port 8000 --amazonec2-region ap-northeast-1 aws-sandbox
Running pre-create checks...
Creating machine...
(aws-sandbox) Launching instance...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with ubuntu(systemd)...
Installing Docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env aws-sandbox
$ 
```

##最後に
教材ではサラッと流されてしまうところ、一つ一つ重要視して進めていかないとうまくいかないですね。
【Rails5】画像サイズ変更

`carrierwave`と`mini_magick`で画像をアップロードさせたけど、画像サイズが変更できなかったので、再ミス防止も兼ねて解決策を以下に書いていきます。
※`carrierwave`と`mini_magick`による画像アップロード方法に関しては、ここでは記載しておりません。

#問題
レシピ詳細ページのView作成段階

```ruby:show.html.erb
<div class="recipe_detail">
  <h3><%= @recipe.title %></h3>
  <div class="row">
    <div class="col-md-5 recipe_content1">
      <%= image_tag @recipe.image.url %>
    </div>
    <div class="offset-md-1 col-md-6 recipe_content2">
      <h5>ポイント</h5>
      <div class="catchcopy"><%= @recipe.catchcopy %></div>
      <h5 class="no_of_dish">材料(<%= @recipe.no_of_dish %>)</h5>
      <table class="table ingredients">
        <% @recipe_ingredients.each do |ingredient| %>
          <tr>
            <td><%= ingredient.ing_name %></td>
            <td class="text-right"><%= ingredient.quantity %></td>
          </tr>
        <% end %>
      </table>
    </div>
  </div>
</div>
```

上記のように記載すると、以下のように`@recipe.image.url`のサイズが`col-md-5`の範囲を超えてしまいます。
[![Image from Gyazo](https://i.gyazo.com/906cdd298c784128571a785b5143c447.jpg)](https://gyazo.com/906cdd298c784128571a785b5143c447)

#試したこと
そこで、他の記事に記載されていたような以下の方法を試してみましたが、表示は変わりませんでした。

#####トライ１
`image_tag`メソッド内に`widthタグ`を入力

```ruby
<%= image_tag @recipe.image.url, width: "300px" %>
```


#####トライ２
`image_uploaders.rb`の`process resize_to_limit`のサイズを変更

```ruby:uploarders/image_uploaders.rb
process resize_to_limit: [300, 300]
```


#解決策
シンプルですが、以下のようにしたらちゃんと画像のサイズ変更できました。

```ruby:show.html.erb
<%= image_tag @recipe.image.url, class: "recipe_image" %>
```
`image_tag`にclassを入力

```ruby:application.css
.recipe_image{
  width: 100%;
}
```
`application.css`内でサイズ指定

[![Image from Gyazo](https://i.gyazo.com/82daa43861b69b8f204f18ce9d951e6a.jpg)](https://gyazo.com/82daa43861b69b8f204f18ce9d951e6a)

ちゃんと綺麗に`col-md-5`の枠におさまりました。

単純なことかもしれませんが、参考になりましたら幸いです。
かんたんな「SemaphoreSlim」の使い方

同時に仕事をできる机（**`Task`**）の数を決めるのが、**`SemaphoreSlim`**です。
![company_syokuba_kengak:relaxed:u_business.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457922/6ab1d77c-766c-7df7-22dc-a1bf72e3be49.png)

#基本
```C#
//机を２つ用意
SemaphoreSlim ss = new SemaphoreSlim(2);

//机が１つ埋まる
ss.Wait();

//机がさらに１つ埋まる
ss.Wait();

//2つとも埋まった机のうち、１つだけ空ける
ss.Release(1);

//空いてる机の数を確認
Console.WriteLine(ss.CurrentCount);
//実行結果は、1
```
**`Wait`**で机を使う。
**`Release`**で机を空けるか、新しい机を用意する。
**`CurrentCount`**で机の数を確認

#かんたんな例
```C#
using System;
using System.Threading;
using System.Threading.Tasks;

class Program {
	static void Main(string[] args) {

		SemaphoreSlim ss = new SemaphoreSlim(0);	//最初は、机を１つも作らない
		ss.Release(1);		//机を１つだけ追加

		//机が１つしかないので、作業１だけが実行される
		Task task1 = Task.Run(() =>{ss.Wait();	Console.WriteLine("作業１");});
		Task task2 = Task.Run(() =>{ss.Wait();	Console.WriteLine("作業２");});

		//1つしかない机は、作業１で埋まっているので、0
		Console.WriteLine(	ss.CurrentCount);

		Console.ReadLine();
	}
}
```
Taskを実行しようとしても、空いてる机の数しか実行されない

#引数
```C#
SemaphoreSlim ss = new SemaphoreSlim(1, 6); 
```
第１引数は、机の数（あとから追加できる）
第２引数は、机の最大数
机は１つしかないが、最大６つまで増やせられる。

```C#
SemaphoreSlim ss = new SemaphoreSlim(1); 
```
引数は机の数（最大数は未設定なので、あとからいくらでも追加できる）

#Waitと、WaitAsyncの違い
```C#
using System;
using System.Threading.Tasks;
using System.Threading;
using System.Collections.Generic;

class Program {
	static void Main(string[] args) {
		Sub();
		Console.WriteLine("main");		//A
		Console.ReadLine();
	}
	public static async Task Sub() {
		SemaphoreSlim ss = new SemaphoreSlim(2);
		List<Task> list = new List<Task>();
		int num = 10;

		while(num-- > 0) {
			await ss.WaitAsync();		//B		Aが先に実行される（非同期）
			//ss.Wait();				//C		Aが後に実行される（同期）

			list.Add(	Task.Run(	() => {
				Thread.Sleep(100);
				Console.WriteLine("-");
				ss.Release();
			}));
		}
		await Task.WhenAll(list);
	}
}
```
Waitは、呼び出し元を待機させ（同期）
WaitAsyncは、待機させません（非同期）

Waitメソッドは入れたらTrueを返します。
既に満席で入れなかったらFalseを返します。

#キャンセル
CancellationToken　はまず　CancellationTokenSource　を生成した上で、
CancellationTokenSource.Token　より取得します。

キャンセルを要求するには　CancellationTokenSource.Cancel()　を呼びます。

つづく・・・
【Java】UTF-8同士のファイルの入出力をおこなう（文字化けさせない）

こんばんは。関東では今日夜から雪が降るそうです。
風邪をひかないようにあったかくして休みましょう。

今日は文字化けの話です。

### １．読んでいただきたい方
・Java初心者の方
・出力ファイルの文字化けに苦しんでいる方
・特にデフォルトエンコーディングがMS932の方は、僕の環境と同じなので共感できるかも知れません（調べ方は下記参照）

### ２．はじめに

前回の記事でも書いたのですが、僕はもともとvbscriptでファイルの読み書きをしていましたが、windows10から文字コードがUTF-8になり、文法も変わったのをきっかけにJavaで入出力のプログラムを作る事にしました。

どっこいこれが大苦戦・・。
自分なりにポイントをまとめておこうと思います。


### ３．ポイント
・自分の開発環境のデフォルトエンコーディングを理解する
・入力・出力の文字コードをきちんと指定する

###４．本日の作品

このようなプログラムを作成しました（utftest.java）。
デフォルトエンコーディングがMS932の方も、
以下のプログラムを実行すると、UTF-8→UTF-8のファイル入出力ができます！！

```javautftest.java
import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.io.FileOutputStream;

public class utftest{
public static void main(String args[]) throws IOException{
try{
  File file = new File("K0040d.txt");
  //BufferedReader br = new BufferedReader(new FileReader(file));
  BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));

//FileOutputStreamで文字コード・改行コードを指定(UTF-8,\n)
  PrintWriter fw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("test.txt"),"UTF-8")));


  String str = br.readLine();
  while(str != null){
    System.out.println(str);
    fw.print(str + "\n");

    str = br.readLine();
  }

  br.close();
  fw.close();
}catch(FileNotFoundException e){
  System.out.println(e);
}catch(IOException e){
  System.out.println(e);
}

}
}
```

インプットデータ（K0040d.txt）は以下。

```
2020/03/20	xxx	-100	あいうえお
```

###５．対応したこと

####５－１．自分の開発環境のデフォルトエンコーディングを理解する
以下を参照にしてみてください。
https://www.javadrive.jp/start/encoding/index1.html
　MS932：Shift-Jis
　UTF-8の場合は、UTF-8と出力されるようです。
ここで、多くの方がMS932になるようですが、この場合、UTF-8で出力する場合は、明確にUTF-8であることをプログラムに指定する必要が出てきます。

####５－２．入力・出力の文字コードをきちんと指定する
(1).入力処理

入力で使用したBufferedReaderクラスは、文字コードを指定できます。
（修正前）

```
  BufferedReader br = new BufferedReader(new FileReader(file));
```

（修正後）

```
  BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
```

UTF-8→Shift-Jisにすれば、Shift-Jis型のファイルも読み込み可能です。

(2).出力処理
最初は、出力にfileWriterを使用していました。
javaでファイル出力、とgoogle検索して出てきた方法です。こんな具合ですね。

```
FileWriter fw = new FileWriter("test.txt",true);
```

しかし、FileWriterでは、出力先の文字コードを決める事ができない事が分かりました。
（https://docs.oracle.com/javase/jp/8/docs/api/java/io/FileWriter.html）
「文字ファイルを書き込むための簡易クラスです。このクラスのコンストラクタは、デフォルトの文字エンコーディングとデフォルトのbyteバッファのサイズが許容できることを前提としています。」とありました。
つまりデフォルトエンコーディングがShift-Jisの場合、出力にはUTF-8を使うことができない事になるという事と理解して、FileOutputStreamを使うようにしました。

```
//FileOutputStreamで文字コード・改行コードを指定(UTF-8,\n)
  PrintWriter fw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("test.txt"),"UTF-8")));
```

###６．感想

正直、ここまでファイル入出力でハマるとは思いませんでしたが、前進して嬉しいです。
汎用的なクラスでできること、できないことを把握しておいた方が良いことも分かりました。

これで色々遊べるぞ・・。

ではまた。
【自分用】Amazon Lightsailの起動スクリプト

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/198767ac-1f6f-dfa5-3546-42ced137fee9.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172833/754aee00-804e-f44e-84f9-b95fef2bb76a.png)


```shell
yum update -y
yum install -y docker
service docker start
usermod -a -G docker ec2-user
sudo curl -SL https://github.com/docker/compose/releases/download/v2.28.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
yum install -y git
yum install -y jq
dd if=/dev/zero of=/tmpswap bs=1024 count=1M
chmod 600 /tmpswap
mkswap /tmpswap
swapon /tmpswap
```

https://docs.docker.com/compose/install/linux/

corret 8

```
amazon-linux-extras enable corretto8
yum install -y java-1.8.0-amazon-corretto-devel
```

correto 16

```
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-16-amazon-corretto-devel
```

corret 21

```
sudo yum install java-21-amazon-corretto-devel
```

nvmはログインしてからでないとできなかた

```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
nvm install 22
nvm use 22
```
lightsailで学ぶwebサーバの基礎

webサーバとして有名なapacheやnginxが一体どういう役割を果たしているのかがわからなかったのでまとめた。

# lightsail を申し込む
awsのサービスであるlightsailに申し込むとipアドレスをもらうことができます。
![Screenshot from 2021-01-23 17-12-32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700770/61daa88f-f74a-a77a-8db5-9dbc7f793a41.png)

# http://3.112.221.xxx でアクセスしてみる
これは表示されません。

# apacheをインストールし、起動する
https://www.digitalocean.com/community/tutorials/how-to-install-the-apache-web-server-on-ubuntu-20-04-ja
を参考にしながらサーバにapacheを導入、起動します。

# 再度http://3.112.221.xxxでアクセス
下のような画面が表示されます。どうやらリモートのページにつながったよう。
![Screenshot from 2021-01-23 17-25-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700770/71b8b310-5ad2-da14-3fc0-53d8a3e432b5.png)

# webサーバの役割
サーバにipアドレスを割り振られただけではサーバのデータにアクセスすることができません。
サーバ側が、飛んでくるhttpリクエストに対して適切な応答をするための窓口を設けてあげる必要があります。そして、その窓口の役割を果たすのがwebサーバというソフトウェアであり、webサーバを起動することで窓口が開設されます。

# apacheを入れればどんなコンピュータでもサーバーになれるのか
そう単純な話でもない。研究室のpcでapacheサーバを立ててそこにアクセスしてみた。

```
# lab pc

$ip a
*****
192.168.xx.xx      #ローカルip
*****

$curl inet-ip.info
133.11.xx.xx       #グローバルip
```
### 環境1
http://133.11.xx.xxにmacからブラウザでアクセス
->繋がらない

### 環境2
http://192.168.xx.xxにmacからブラウザでアクセス(同一のLAN内)
->つながる

### 結果
どうやら同一のLANでないと繋がらなさそうだ。じゃあなんでlightsailはグローバルにつながるのか。研究室のLAN環境はどうなっているのだろうか。
(2025/01/15 追記)
inet-ip.infoで表示されるのは、研究室のpcが属しているネットワークのパブリックipアドレスである。そこにアクセスしてもpcのサーバには、通常繋がらない。ネットワークには多数のマシンが繋がっているので、そもそもパブリックipを指定してアクセスしただけではどのpcのサーバに接続したいのかが同定できない。
アクセスするためには、NAT超えをする必要がある。
FTPをはじめとする通信プロトコルについて

## はじめに

タイトルについて記事にしました。
この記事で得る内容は以下の通りです。

・ 通信プロトコルの種類について・主なFTPソフト

HPの更新などでファイルのアップロード・ダウンロードや編集を行ったりする際に必要となります。

## 通信プロトコル

#### FTP（File Transfer Protocol）

FTPとは、ファイルを送受信する時に使う規約（通信プロトコル）です。
通信プロトコルは複数の種類があり、その内の1つがFTPです。
ホームページに必要なファイルをPCからサーバーにアップロードしたり、逆に保存していたファイルを
ダウンロードする際は、FTPソフト（FFFTPやFileZilla）が必要となります。

<font color="red">FTPは、利用者の認証情報（ユーザー名やパスワード）やファイルなど、通信する一切の情報を
暗号化せずに転送するので、情報の漏えいやコンピュータウィルスの標的にされ、多大なリスクを抱えます。</font>

#### FTPS（File Transfer Protocol over SSL/TLS）

FTPの脆弱性を補うため、転送される情報を**SSL/TLS**を利用して暗号化するプロトコルです。

##### SSL/TLS

公開鍵暗号と共通鍵暗号という暗号化技術の組み合わせで、暗号化された安全な通信を確保する仕組みです。
SSLとTLSの大枠は同じもので、SSLがバージョンアップを重ねてTLSが誕生しましたが、SSLのネームバリューから「SSL/TLS」と並列で表記されることが多いようです。
そのサイトにSSL/TLSを使われているかは、ブラウザのURL欄のアドレスバーにhttpではなくhttpsか、鍵のマークの有無で判別できます。

##### httpとhttpsの違い

httpとhttpsの違いは、<font color="red">通信内容が暗号化されるかされないか</font>です。

httpでやり取りするデータは、第三者が閲覧したり改ざんすることができます。
そこでデータを暗号化し、第三者から情報を保護する目的でhttpsが開発されました。

httpsはSSL/TLSを使い情報に鍵をかけ、サーバーとクライアントにのみ鍵を配布します。
そしてSSLサーバー証明書を発行し、サイトのサーバーにインストールすることでhttps化を行います。
サイト全体をhttps化することを<font color="red">常時SSL化</font>といい、サイト内の画像や動画、スクリプト全てが保護の対象となります。

#### SFTP（SSH File Transfer Protocol）

FTPで転送される情報を**SSH（Secure Shell）**を利用して暗号化するプロトコルのことです。

##### SSH

リモートサーバーに操作端末で通信を行う際、通信される一切の情報を暗号化するプロトコルのことです。
SSHは、LinuxにインストールされているOpenSSHや、Gitに同梱されているGit Bashで使用可能です。

#### SCP（Secure Copy Protocol）

SFTPと同様にSSHを使用しているので、セキュリティ面で安全性の高いプロトコルです。
特徴として、SFTPより通信速度が速いと言われていますが、SCPを利用するにはサーバにUNIX系のシェルが
備わっている必要があります。

## 主要なFTPソフト

#### Windows対応

##### FFFTP

![FFFTP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/5f77652e-2be2-b807-5fcd-a1db45d39745.png)


日本人が開発したFTPソフトの定番で、以下のような特徴があります。

・ FTPSを利用して暗号化したデータの送受信ができる（SFTPには未対応）
・ 大量のファイルの一括転送ができる
・ ドラッグ&ドロップでファイルのダウンロード及び、アップロードができる
・ 漢字コードの自動変換ができる
・ ミラーリング機能（転送元の内容を転送先に上書きし、転送元と転送先のファイル構成を等しくする）

■ 公式：[FFFTP Project](https://ja.osdn.net/projects/ffftp/)

##### WinSCP

![WinSCP_Logo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/d4e1f20f-7e82-d8de-d94a-a15efbb74159.png)

オープンソースで開発されているFTP/SFTP/SCPソフトです。

・ 暗号化されたデータの送受信ができる
・ ミラーリング機能がある
・ 日本語を含めたいくつもの言語に翻訳できる

■ [WinSCPとは](https://winscp.net/eng/docs/lang:jp)

#### Windows/Mac/Linux対応

##### Filezilla

![ダウンロード.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/e87cf400-ae92-cc7e-0fed-c0ecbc13b584.jpeg)

FTP/FTPS/SFTPに対応したソフトです。

・ ファイルの高速転送ができる
・ ドラッグ&ドロップでファイルのダウンロード及び、アップロードができる
・ 日本語を含めたいくつもの言語に翻訳できる

■ 公式：[FileZilla - The free FTP solution](https://filezilla-project.org/)
spring-kafkaのconsumerでjson deserialize型変換エラーをスキップ

spring-kafkaでjsonの型変換などの処理続行不可能なメッセージをskipしたい場合がある。以下はその場合に使えるかもしれない設定例。

```gradle:build.gradle
plugins {
  id 'org.springframework.boot' version '2.4.2'
  id 'io.spring.dependency-management' version '1.0.11.RELEASE'
  id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '15'
configurations {
  compileOnly {
    extendsFrom annotationProcessor
  }
}
repositories {
  mavenCentral()
}
dependencies {
  implementation 'org.springframework.boot:spring-boot-starter'
  implementation 'org.springframework.kafka:spring-kafka'
  compileOnly 'org.projectlombok:lombok'
  developmentOnly 'org.springframework.boot:spring-boot-devtools'
  annotationProcessor 'org.projectlombok:lombok'
  testImplementation 'org.springframework.boot:spring-boot-starter-test'
  testImplementation 'org.springframework.kafka:spring-kafka-test'
  implementation 'com.fasterxml.jackson.core:jackson-databind'
}
test {
  useJUnitPlatform()
}

```

まずプロパティでconsumerのdeserializerに```org.springframework.kafka.support.serializer.ErrorHandlingDeserializer```を設定し、そのdelete先を```spring.kafka.properties.spring.deserializer.value.delegate.class```プロパティで指定する。これはjson変換クラスを指定する。こうするとjson変換エラーは単にスキップされる。

```properties:application.properties
spring.kafka.bootstrap-servers=localhost:19092
spring.kafka.consumer.group-id=myGroup

spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer

spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.serializer.ErrorHandlingDeserializer
spring.kafka.consumer.properties.spring.json.trusted.packages=*

spring.kafka.properties.spring.deserializer.value.delegate.class=org.springframework.kafka.support.serializer.JsonDeserializer

```

以下は動作検証用の適当なconsumer.

```java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class KafkaSampleApplication {
	public static void main(String[] args) {
		SpringApplication.run(KafkaSampleApplication.class, args);
	}
}

```

```java
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class SampleData {
	String id;
	int value;
}
```

```java
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;

@Component
public class JsonConsumer {
	@KafkaListener(topics = "mytopic")
	public void processMessage(SampleData content) {
		System.out.println("content" + content);
	}
}
```

とはいえ、実際にはログ出したいとかエラー発生時に特殊な処理したいとか色々あるので、もうちょい細かい設定が色々必要になる。
【PHP】初中級者が解くべき過去問精選 100 問を解いてみた【3問目/100】

アルゴリズムのアウトプット

ということで、
[レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編：目指せ水色コーダー！】](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-3-%E5%88%86%E9%87%8E%E5%88%A5%E5%88%9D%E4%B8%AD%E7%B4%9A%E8%80%85%E3%81%8C%E8%A7%A3%E3%81%8F%E3%81%B9%E3%81%8D%E9%81%8E%E5%8E%BB%E5%95%8F%E7%B2%BE%E9%81%B8-100-%E5%95%8F)@e869120さん



>AtCoder で水色コーダー、つまりレーティング 1200 を少ない問題数で達成するために、茶色コーダー・緑コーダーにとって適切な教育的良問を 100 問集めました。

こちらの記事の初中級者が解くべき過去問精選 100 問
をPHPで解いていきます。

```php
<?php

$wordArr = str_split(trim(fgets(STDIN)));
$num = count($wordArr);
$max = 0;
$count = 0;
$acgt = ['A', 'C', 'G', 'T'];
for ($i = 0; $i < $num; $i++) {
    if (in_array($wordArr[$i], $acgt)) {
        $count++;
        $max = max($count, $max);
    } else {
        $count = 0;
    }
}

echo $max;
```
文字列を配列化し順番に該当する文字かどうか判定。
連続している間は足し上げていき、対象出ない場合はcountをリセットする問題。
Basic認証の導入

# 前提
Ruby2.6.5
Rails6.0.0
macOSはCatalina以降
本番環境はHeroku

# 導入方法
### 開発環境

①開発環境の環境変数にユーザー名とパスワードを設定する

```console:ターミナル
% vim ~/.zshrc

# 「i」とタイプすることでインサートモードへ移行
# 元々の記述の下に以下を追記

export BASIC_AUTH_USER='ログイン名'
export BASIC_AUTH_PASSWORD='パスワード'
```
※ログイン名・パスワードは各自考えたものを入力


② application_controller.rbに記述


```ruby:app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  before_action :basic_auth


  private

  def basic_auth
    authenticate_or_request_with_http_basic do |username, password|
username == ENV["BASIC_AUTH_USER"] && password == ENV["BASIC_AUTH_PASSWORD"]
   end
  end
end
```
### 本番環境
①Herokuで環境変数を設定

```console:ターミナル
% heroku config:set BASIC_AUTH_USER="ログイン名"
% heroku config:set BASIC_AUTH_PASSWORD="パスワード" 
```
以下コマンドで設定できているか確認できます。

```console:ターミナル
% heroku config
```

②変更したコードのHerokuへのデプロイ

```console:ターミナル
% git add .
% git commit -m "Basic認証を導入"
% git push heroku master 
```
【Git】git submodule 

#はじめに
この記事では、git sumoduleの基本的な使い方についてまとめました。
⚠️当方初学のため認識違いがある可能性大です
誤りを見つけた際はコメントにて指摘していただけると幸いです🙇‍♀️🙇‍♂️


#参考
この記事は以下の情報を参考にして執筆しました。

- [git submoduleの基礎](https://qiita.com/sotarok/items/0d525e568a6088f6f6bb)
- [7.11 Git のさまざまなツール - サブモジュール](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB-%E3%82%B5%E3%83%96%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB)


#git submoduleとは
git submoduleとは、外部のgitリポジトリを自分のgitリポジトリのサブディレクトリとして登録し、特定のcommitを参照する仕組み。


#基本的な使い方
作業中のリポジトリのサブモジュールとして既存のリポジトリを追加する。
サブモジュールを新たに追加するには以下のコマンドを実行する。
追跡したいプロジェクトのURLを引数に指定する。

```git submodule add URL
```

デフォルトでは、このコマンドでしていしたリポジトリと同名のディレクトリにサブプロジェクトのデータが格納される。
node.jsのローカルサーバーでクライアントサイドjavascriptが動かない

# はじめに
* 素人がタイトルの問題で詰まったので解決方法を残しておきます
* 解決方法の一つは@Suibari_chaさんの記事を大いに参考にさせてもらいましたが（ほぼそのままです）、「javascriptが動かない」でググると見つけづらかったので一応記載させていただきました

# 解決方法1
下記記事のSuibari_chaさんのcssを読み込む方法：[Node.jsでhttpサーバを立てた際にCSSが読み取れない場合の対処法について](https://qiita.com/Suibari_cha/items/48da8519d6f363925b6a)

と同様に、javascriptのMIMEタイプを指定します。
サーバー起動時に「.jsはJavaScriptとして扱う」
というのを教えてあげないといけないということみたいです。
（node.jsなんだからそれくらいデフォルトで分かってくれよと思いますけども）

# 解決方法2
expressを使います

まず、expressをインストール

```
npm install express
```

下記のサーバー起動のスクリプトを書いて起動します。

```javascript:index.js
// node index.js で起動
var express = require('express');
var app = express();

app.use(express.static(__dirname)); // ここに入っているjsやcssを使う

app.get('/', function (req, res) {
  //res.send('Hello World!');
  res.sendFile(__dirname + '/index.html');
});

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});
//http://localhost:3000にアクセスして確認
```

こちらではいちいちMIMEタイプを指定しなくて良いみたいです。
ポイントはここです。

```javascript
app.use(express.static(__dirname)); // ここに入っているjsやcssを使う
```

終わり
plunkerでa-frame

# 概要

plnkerでa-frameやってみた。
gltfをアニメーション表示してみた。

# 写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/0690debc-4e21-72f0-426a-6f51eba3a404.jpeg)


# サンプルコード


```
<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="lib/style.css">
    <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/donmccurdy/aframe-extras@v6.1.1/dist/aframe-extras.min.js"></script>
    <script src="lib/script.js"></script>
  </head>
  <body>
    <h1>Hello Plunker!</h1>
  <a-scene>
    <a-assets>
      <a-asset-item id = "vrm" src= "https://rawcdn.githack.com/pissang/claygl/c4f45119/example/assets/models/SambaDancing/SambaDancing.gltf"></a-asset-item>
    </a-assets>    
    <a-entity gltf-model = "#vrm" scale = "0.2 0.2 0.2" animation-mixer></a-entity>      
    <a-camera position = "0 10 30" cursor-visible = "true" cursor-scale = "5" cursor-color = "#0095DD" cursor-opacity = "1"></a-camera>      
    <a-light type = "directional" color = "#FFF" intensity = "0.5" position = "-1 1 2"></a-light>      
    <a-light type = "ambient" color = "#FFF"></a-light>
  </a-scene>
  </body>
</html>


```

# 成果物

https://embed.plnkr.co/plunk/QDY2upvSoNURbWhV

以上。
RefCellに格納した値の参照を返す方法について

Rustで連結リストを作成している際に,
連結リスト先頭から指定のインデックスの値を参照で返すのはどうすればいいのか調査したのでメモ

### 参考
https://stackoverflow.com/questions/29401626/how-do-i-return-a-reference-to-something-inside-a-refcell-without-breaking-encap

もちろん, RefCellに持たせるT型の値にCopyトレイトを実装すれば参照でなくでもよい.

### やり方
RefCell<T>のborrow()はRef<'a, T>型を返す.
Ref<'a, T>はRefCellと同じライフタイムになる.  
なので, Ref<'a, T>から取り出した値をメンバとして持ち, 
かつそのメンバと同じライフタイムを設定した構造体Aを定義すればいい.

従って, 

1. RefCellから取り出したRef<'a, T>で構造体Aを作成する
2. 構造体AはRef<'a, T>と同じライフタイムとなる
3. これを返すことで, RefCellの値をコピーせずに参照できる.
4. あとは構造体Aに適宜Derefを設定して, &Tへの参照となるようにする.

Borrow_mut()が返すRefMut<'a, T>にも同じ実装をすれば,
Re
fcellの値を変更できる可変参照が作れそう.

```rust
use std::ops::Deref;
use std::cell::{Ref, RefCell};

struct Foo {
    value: RefCell<i32>,
}

struct Foovalue<'a> {
    value: Ref<'a, i32>,
}

impl<'b> Deref for Foovalue<'b> {
    type Target = i32;
    fn deref(&self) -> &i32 {
        &self.value
    }
}

impl Foo {
    pub fn get_items(&self) -> Foovalue {
        Foovalue {
            value: self.value.borrow(),
        }
    }
}
fn main() {
    let f = Foo {
        value: RefCell::new(10),
    };
    let borrowed_f = &f;
    let items = borrowed_f.get_items();
    let v: &i32 = &items;
}

```

もちろん構造体でなくとも良い。
直接```Ref<'a, T>```に```deref```を実装しても良い.  

また, 連結リストのように目的の値を逐次探索する必要がなく, 
一発で```self```からアクセスできるのであれば, borrow()して返せば良い

### まとめ
できるけど, これ多分生ポインタでやったほうが楽だ...
生ポインタを学習しよ...
Rustの循環参照周りを正攻法で攻めるとすごい大変...
Ruby on Railsで簡単に新着マークを作る方法

#はじめに
独学で学習中の学生がこの記事を書いています。
間違っているところやこんな書き方はしないなど思われるかもしれませんが、優しく指摘してもらえるととても嬉しいです。

#作りたいもの
![677B1C4C-90FF-451F-9F2E-8A60A12F20AD_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048293/eec5de92-e8bc-93ff-1bf2-31142de543f7.jpeg)

ここで作りたいものは新着マークです。
新しい投稿があると、その投稿から7日間の間だけ表示される新着マークを作りたいと思います。(
7日経つを自動で消える)
※日数は変更可能

#前提条件
投稿機能と投稿一覧は既に実装済みということで進めていきます。

#必要になる情報
1 現在の時間
2 新規投稿された時間
3 新規投稿された時間から7日後の時間

#作成の流れ
1 現在の時間を取得(可変）
2 投稿された時間の取得(不変）
3 投稿された時間から7日後の時間を取得(不変）
4 3が1よりも先である(未来である)場合に新着マークを表示される

#1 現在の時間を取得
```app/controllers/posts_controller.rb
def index
 @posts = Post.page(params[:page]).per(10)
 @current_time = Time.current
end
```
indexアクションの1行目は、kaminariを使って既に投稿されている10記事の情報を取得しています。
2行目は、現在の時間を取得しています。Railsでは、2種類のタイムゾーンがあり、様々な現在時間の取得方法がありますが、TimeWithZoneクラスを使う方法が一番良いとされているようなので、Time.currentを使っています。(Time.zone.nowでも同じ)
詳しくは、[こちら](https://qiita.com/jnchito/items/cae89ee43c30f5d6fa2c)の記事が参考になると思います。

#2 投稿された時間の取得と3 投稿された時間から7日後の時間を取得
```app/views/posts/index.html.erb
<% @posts.each do |post| %>
 　省略〜
　<% post.created_at.since(7.day) %>         
<% end %>
```
@postsから1記事ずつ取り出し、その記事が作成された時間(2番)をcreated_atで取得、そしてそこにsinceメソッドを使い、投稿された時間から7日後の時間(3番)を取得しました。
※sinceメソッドの引数を変更すれば、新着マークの表示期間を変更可能

#4 新着マークを表示させる
```app/views/posts/index.html.erb
<% @posts.each do |post| %>
 　省略〜
　<% if @current_time < post.created_at.since(7.day) %> 
    <div class = "new-mark">新着</div>
  <% end %>        
<% end %>
```
投稿された時間から7日後の時間が現在の時間よりも先であれば(未来であれば)新着マークを表示するようにしたいので、if文を使い、その中に、表示したい内容を入れます。
これで、完成です。
※デザインの部分は省略しています。

#まとめ
今回はRuby on Railsで期間限定の新着マークを作ってみました。
おそらく、実際は、cookieを使って実装する方が、新着情報を使って他に機能を作る時など、色々な面で使いやすいと思います。
なので、次回はcookieでの実装にもチャレンジしてみようと思います。

###参考文献
・[RubyとRailsにおけるTime, Date, DateTime, TimeWithZoneの違い](https://qiita.com/jnchito/items/cae89ee43c30f5d6fa2c)
TweepyでPINベース認証する方法

TweepyでPINベース認証をやったのでメモ程度に

# 前提条件
Python 3.7.4
tweepy 3.10.0

# PINベース認証する方法
``` tewwpy_auth.py
import tweepy
import webbrowser

TWITTER_CONSUMER_KEY = 'xxxxxxxxxxxxxxxxxxxxxx'
TWITTER_CONSUMER_SECRET = 'xxxxxxxxxxxxxxxxxxxxxxxxx'

# ここで oob と入力することで、アクセス許可後にPINが表示される様になる
auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, 'oob')

# 認証用URLを取得後ブラウザで開く
authorization_url= auth.get_authorization_url()
webbrowser.open(authorization_url)

# アクセスを許可後出てきたPINを入力
print('PIN CODE >>', end='')
pin_code = input()

# PINコードを元にトークンなどを取得
auth.get_access_token(pin_code)
print(f"ACCESS_TOKEN = {auth.access_token}")
print(f"ACCESS_SECRET = {auth.access_token_secret}")

# 取得した情報を認証情報に追加
auth.set_access_token(auth.access_token, auth.access_token_secret)
api = tweepy.API(auth)
username = api.me().name
print(f"ユーザー名: {username}")
```
手近なものを使って衝突音サンプルを作ってみた／手順メモ

[物理エンジンで物体を自由落下させて、衝突時に音を鳴らすようにしてみた](https://qiita.com/kob58im/items/5d1d4acaa1fac44c8eed)
で音を鳴らしてみたのですが、ただのサイン波だとイマイチなので、ビンとか食器の衝突音を録音してみました。
（フリーのサンプルとか探せばでてくるかもですが。。）

無料で使ってるCodePenにあまり巨大なデータを置くのは忍びないので[^1]、サンプルはごく少量です。
（単純に録音に飽きた説）


[^1]: 容量についての記載ありました：[Pen Limitations - CodePen Blog](https://blog.codepen.io/documentation/limitations/)

<p class="codepen" data-height="718" data-theme-id="light" data-default-tab="result" data-user="kob58im" data-slug-hash="xxENYaR" style="height: 718px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Sound Sample (ビンや食器の衝突音)">
  <span>See the Pen <a href="https://codepen.io/kob58im/pen/xxENYaR">
  Sound Sample (ビンや食器の衝突音)</a> by kob58im (<a href="https://codepen.io/kob58im">@kob58im</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# 手順メモ

## 0. 録音機材を準備する
<b>パソコンがマイク内蔵している場合もあります。</b>（自分の持っているパソコンは内蔵してました。）
ここの選定が命な気がしますが、まず試してみる分には、ありものでいいんじゃないかなと思います。

【注意点】
自分は音響には詳しくないので、細かいことはわかりませんが、最近は<font color="red"><b>パソコンにマイク端子やスピーカー端子の挿し口がない</b></font>場合も多いので、あらかじめ確認しましょう。
あと、端子のタイプも色々あるようなので、注意が必要。

## 0'. 録音環境を準備する

極力無音の環境を準備する。（録音中はエアコンをとめておくなど。） 

## 1. 録音する

参考サイト1. [Windows 10 の「ボイスレコーダー」を使い、音声や音楽の録音を行う方法](https://www.gigafree.net/Windows/Voice-Recorder/) に詳しく書かれているので、本記事では省略します。

## 2. 加工する

参考サイト2.  [「Sazanami」老舗の無料サウンドエディター - 窓の杜](https://forest.watch.impress.co.jp/library/software/sazanami/) などの、音声波形加工ツールを使って、加工します。
加工する前に、<b>音がしっくりくるか？</b>を波形を部分再生して確認します。
波形がサチってないか（下限上限に張り付いてつぶれていないか）、小さすぎないか、についても見ておくとよいです。マイク音量を調整したり、音を鳴らす場所（マイクとの距離）を調整したりすると改善するかもしれません。

とりあえず、自分がやった点は下記です。

- 欲しい波形部分を切り出す。
- 音量を正規化する。
- 波形の立ち上がりまでの時間を極力短くする。（波形を時間軸方向に拡大して、ほかの波形との開始タイミングを一定に保つのがよい。[^2]）
- 波形の終わりを適当に決めて、切り詰める。（ここはテキトウにやってます。）
- 開始部分を選択してフェードイン加工する。
- 終了部分を選択してフェードアウト加工する。

<b>フォーマットの変換</b>
ファイルサイズを小さく抑えるためでもあるが、波形間で統一するのがよい。
※基本的には<b>フォーマット変換すると音質が劣化する</b>ので、聴くに堪えれる音質かどうかをチェックしながら決めるのがよいかと思います。
今回のサンプルは、モノラル(1ch)、8bit/サンプル、サンプリングレート22050Hzにしました。

- サンプリングレートを一定の値にする。
- 1ch(モノラル)にする。
- ビットを一定の値にする。[^3]

[^2]: 今回の波形データでは、時間を測らずテキトウにやってます。。。
[^3]: ここだけ参考サイト2のツールでのやりかたが分からず、参考サイト3で実施しました。

## 3. 不要なヘッダ情報の削除

個人情報の流出防止とか、ファイルサイズの観点から、不要なヘッダ情報（録音者とかコメントとか）は削除したほうがよいです。

加工の際に参考サイト3で変換した結果、ヘッダ情報が消えたようなので、今回はそれで兼ねている。。。（参考サイト3が保証しているわけではないので自己責任でお願いします。。。）

そのうちwavヘッダ情報について調べたいと思います。
 - [wav ヘッダ フォーマット - Google 検索](https://www.google.co.jp/search?q=wav+%E3%83%98%E3%83%83%E3%83%80+%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88)

# 参考サイト
 1. [Windows 10 の「ボイスレコーダー」を使い、音声や音楽の録音を行う方法 - ｋ本的に無料ソフト・フリーソフト](https://www.gigafree.net/Windows/Voice-Recorder/)
 - [「Sazanami」老舗の無料サウンドエディター - 窓の杜](https://forest.watch.impress.co.jp/library/software/sazanami/)
 - [Waveファイルのフォーマット変換](https://www.petitmonte.com/labo/wave-format/)
 - [ドラッグ＆ドロップされた画像や音声ファイルをインラインimgやaudioタグに変換するツールをつくってみた - Qiita](https://qiita.com/kob58im/items/0fb2b1aedf842fb836cf)
ruby silverに合格したのでまとめました(2021年1月)

## この記事ってなに？

ruby silverに合格しました。勉強法について誰かのためになるかもしれないのでまとめておきます。

## 前提

- 2020年新卒です
    - この時までプログラミング経験ありません
- rubyの開発は4ヶ月ぐらいです
- たのしいRuby一周やったぐらい

## 勉強したこと

- Ruby技術者認定試験合格教本
    - ざっと一周した後、巻末のテストを3周しました
        - 間違えてわからないことは本で調べて覚えていく感じ
        - 一回目は5割とかでした。最終的にはほぼ満点でした。
- RubyExamination
    - 5回か6回ぐらいテストしました
        - 確か最初は7割あるかないかぐらいだったかな
        - 最終的には9割ぐらいでした。


## 勉強法でのポイント

- 対策を立てる
    - 他の合格記事をみてみる
- 知らないメソッド覚える
    - 似たような問題は出るので、よく間違える問題は覚えるぐらいでいいと思います。
    - 破壊的メソッドなのかどうかを確認する
    - 同意の違う名前のメソッドを覚える
- 回答の選択肢になっているもので、挙動がわからないものはすぐ確認する

ぐらいを意識しながら勉強していました。

1日大体2時間から3時間ぐらいで休みの日は5時間か6時間ぐらいやっていたと思います。
ruby silverに向けての勉強期間は二週間弱だったと思います

## 試験当日

- 見直しめっちゃ大事（二問ミスしているのに気が付きました）
- 知らない問題多かった（このメソッドこの使い方あってる？みたいな問題も多かった）
- 一方で、やった問題もでた

## まとめ

試験に向けて、という明確な目標があってやりやすかったです
誰かの参考になれば幸いです。
[rails]繰り返した処理の回数をclassにインデックスとして付与する方法

##初めに
eachメソッドでテーブルから取得してきた値に対してそれぞれ違った処理をしたい！ときってありませんか？

例えば、、、

```
vegtables = [キャベツ,トマト,なす]
```
がデータベース上のテーブルに保存されていて、これをeachメソッドを使って値を取得し、"トマト"だけ赤色にしたい、boxの形を変更したい時など。

実装中にハマったので共有します。

##結　論
each.with_indexメソッドを使う。

##詳　細
コントローラーの記述は以下の通り

```vegtables_controller.rb
class VegtablesController < ApplicationController
  def index
    @vegtables = Vegtable.all
  end
```

なお、vegtablesテーブルのveg_nameカラムには
veg_name=[キャベツ,レタス,きゅうり,トマト,なす,ホウレンソウ,タマネギ,ジャガイモ]
が入っています。

これにそれぞれ異なるclassを与えたいとき


```index.html.erb
  <% i=0 %>
  <% @vegtables.each.with_index do |v, i| %>
    <div class="wrapper_<%= ++i %>">
      <%= v.veg_name %>
    </div>
  <% end %>
```

とすることで実装できました！

因みに、scssに書いたclassのnameは
.wrapper_0{}
.wrapper_1{}
.wrapper_2{}
・・・
などです。
JUCE: iOSでのファイルの読み書きにjuce::Fileを使うべきではない

##問題##
Mac/Windows向けのプラグインをJUCEを使って作ってきた人は、ファイルの読み書きにはまずjuce::Fileを使っていたと思うが、それはiOSではコケる。Sandbox内のファイルであればそれでも読めるのだが、Sandbox外のファイルの読み書きはできない。

##解決方法##
juce::URLを使う。とにかくURLを使わなければダメ。juce::FileChooserを使った例。

###保存(Export)###

```MainComponent.cpp
    juce::FileChooser chooser (juce::String("Export a file..."),
                               juce::String(),
                               juce::String());
    if (chooser.browseForFileToSave(true))
    {
        auto result = chooser.getURLResult();
        juce::String textToSave = "Hello!";
#if 1   // 正常に保存できる
            std::unique_ptr<juce::OutputStream> os = result.createOutputStream();
#else   // 保存できない。URLからgetLocalFile()でFileを取得するのはNG。
        juce::File file = result.getLocalFile();
        std::unique_ptr<juce::OutputStream> os = file.createOutputStream();
#endif
        auto ret = os->writeString(textToSave);
        if (!ret)
        {
            juce::AlertWindow::showMessageBox(juce::AlertWindow::WarningIcon, "Failed to write text to file.", "");
        }
    }
```

###読み込み(Import)###
```MainComponent.cpp
    juce::FileChooser chooser (juce::String("Select the program file to import..."),
                               juce::String(),
                               juce::String());
    if (chooser.browseForFileToOpen())
    {
        auto result = chooser.getURLResult();
#if 1   //  読み込める。
        std::unique_ptr<juce::InputStream> is = result.createInputStream(false);
#else   //  読み込めない。URLからgetLocalFile()でFileを取得するのはNG。
        juce::File file = result.getLocalFile();
        std::unique_ptr<juce::InputStream> is = file.createInputStream();
#endif
        juce::String text = is->readString();
        if (text.isNotEmpty())
        {
            labelText->setText(text, juce::dontSendNotification);
        }
        else
        {
            juce::AlertWindow::showMessageBox(juce::AlertWindow::WarningIcon, "Failed to read text from file.", "");
        }
    }
```

##他OSとの互換性##
Mac/Windowsでも正常に動くので、ファイルは常にjuce::URLで扱えばよいと思う。
Railsでgem 'devise'を練習した話

#1.何をしたの？
Railsを勉強している最中、ログイン機能に便利なdevise gemに出会ったので、練習がてら２段階認証が必要な簡単なログインアプリを作成することにしました。
作成したアプリはこちらです
https://github.com/yosnak13/Login_APP

devise gemの使い方はこちらの方の記事がとても参考になりました！
https://qiita.com/cigalecigales/items/f4274088f20832252374

#2.なぜそうしようと思ったのか。
自作アプリで動くメイラーを実装できないものか悩んでいたためです。

著者はrailsチュートリアルからrailsを学び、ログイン機能とメイラーの実装方法は学習しました。当時(2020年6月ごろ)チュートリアルでは、SendGridと呼ばれるherokuのアドオンを使用してメイラーを実装するようテキストに書かれていました。しかし、実際にアドオンを実行しようと思ってもメイラーが機能せず、アカウント有効化できないかSendGrid社に問い合わせたところ、「お客様が当社のプラットフォームに適していないと判断したため、アカウントを有効化することができません。」と返事がありました。SendGridアドオンは明確な商用目的がないと使用できないようです。

仕方ありません！アカウントを有効化するにあたり5つ質問に答えて欲しいと指示があったのですが、質問内容かなりガチでした（笑）。英語でのやりとりでしたがいい経験になりました。
現在RailsチュートリアルはMailgunというアドオンを使用するようにテキストが変わっていますが、そちらはどうなのかはまだチェックできておりません！

#3.やったことを羅列
備忘録を兼ねて実行したことを羅列します

__1.rails new LOGIN_APPでアプリ立ち上げ__
__2.devise gemのインストール__
__3.`rails g devise User`でUserモデル作成__
__4.db/migrate/XXXXXXXXXXXXXX_devise_create_users.rbに'name'カラムを追加(emailカラムはモデル作成時すでに存在している仕様らしく、今回は'name'のみです)してmigrate__
__5.`rails g devise:views users`でdeviseが管理するビューを作成・編集__
__6.`rails g devise:controllers users`でdeviseが管理するコントローラーを作成・編集__
__7.route設定__
__8.ログインページ、パスワード再設定ページ、アカウント作成ページを編集__
![スクリーンショット 2021-01-23 16.42.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674242/bf5514e0-8177-8b21-19d8-2ca40be021e6.png)
今回CSSなしなのでデザインはもうシンプルにこんな感じです。

__9.gmailを使ってメイラーを設定__
__10.アカウント作成後のリダイレクト先の作成、設定（route, controller, view）__
__11.ログイン後のリダイレクト先を作成、設定(route, conttoller, view)__
![スクリーンショット 2021-01-23 16.43.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674242/8855f5a8-cbd6-d315-6e1f-35f0148e5590.png)
これで完成です！！ログインしたらログインおめでとうの文字が現れます（笑）


大まかに分けるとこの１１工程になりました。

#4.メイラーについて
今回はアドオンではなく習ったばかりのgmailのサービスを使用しました。
やり方は1で紹介した記事ほぼ同じやり方してます。
ただそのままgithubにプッシュすると個人情報ばればれなので、dotenv-gemを使って定義した環境変数から呼び出す形式にし、環境変数はgitignoreに記載することで回避しています。
![スクリーンショット 2021-01-23 16.47.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674242/e35caedb-9530-877d-2ce3-e8c3268f6f8b.png)

開発環境では無事メールが飛んでくれました。以前のチュートリアルの時は飛ばなかったので少し進歩です（笑）
これでrailsチュートリアルの時に抱えていたモヤモヤがすっきりしました！
次回からログイン機構を搭載するなどメールが必要なときはこの方法を使っていこうと思います。

#5.deviseの他の機能
deviseには１０個のモジュールが搭載されていて、
今回は、ユーザーの作成、編集、削除ができる'Registerable',メールで２段階認証が搭載できる'Confirmable'を使いました。
他の機能は作るアプリによって使うかどうかというところですが、機会があれば使ってみたいですね。
検索してもなかなか出てこない一行Linuxコマンド

# 検索してもなかなか出てこない一行Linuxコマンド

## ファイルをバックアップするときの省略記法

バックアップするときのcpコマンドで2回ファイル名を入力するのは面倒なので。

```
cp index.php{,.bak}
```

###### その他

見つけるたびに追記していきます。
【Windows】圧縮ファイルからメタファイルを削除するバッチコマンドを作った

# 概要
例によってテストエビデンスとかをzipでまとめた後に

「ああっ！Thumbs.dbが入りこんじゃった。削除しなきゃ…。」

みたいなのが面倒なので、7zipの機能を使ってフォルダ内のzipファイルから一括でメタファイルを削除するコマンドを作った。

# 機能
- zip/7zファイル内に含まれている下記ファイルやディレクトリを削除する
    - Thumbs.db
    - .DS\_Store
    - \_\_MACOSX <DIR>

# 使い方
1. 7zを導入し、windowsパスを通す
2. 下記掲載ソースコードをバッチファイルにしてwindowsパスを通す
3. 下記コマンドを実施する

```console
> cd /d 【zipファイルが大量に入っているフォルダ】
> clean-zip-files start

```

# ソースコード
下記を `clean-zip-files.bat` として保存する。windowsパスを通しておくと便利だと思う。

```bat:clean-zip-files.bat
@echo off
setlocal enabledelayedexpansion

rem 引数チェック
if /i not "%1"=="start" (
    call :HELP_MSG
    exit /b 0
)

rem 前提コマンドチェック
where 7z > nul 2>&1
if not "%ERRORLEVEL%"=="0" (
    echo 7z コマンドが見つかりません。
    exit /b 1
)

for /f "usebackq delims=" %%a in (`dir /b ^| findstr /i /r /c:"\.zip$" /c:"\.7z$"`) do (
    set COMPRESSED_FILE=%%~a
    set CMD=7z d "!COMPRESSED_FILE!" "Thumbs.db" "__MACOSX" ".DS_Store" -r
    echo !CMD!
    !CMD! > nul
)
endlocal

exit /b 0

rem ------------------------------
rem ヘルプ用メッセージ
rem ------------------------------
:HELP_MSG
    echo.
    echo カレントディレクトリの圧縮ファイル（7z/zip）内から次のファイルやディレクトリを削除する
    echo     Thumbs.db
    echo     .DS_Store
    echo     .__MACOSX ^<DIR^>
    echo.
    echo usage^)
    echo     ^> clean-zip-files start
    echo.
exit /b
```

# プロダクト紹介
今まで作ったバッチコマンドはGitHubで公開している。良かったらどうぞ。
https://github.com/mahny-b/alstroemeria

以上
Udemy AI学習お勧めのコース

#おすすめのコース
[Udemy はじめての AI(Offered by Grow with Google)](https://www.udemy.com/course/google-jp-ai/)

#知った経緯
AI勉強会にて講師の先生にお勧めされた学習コンテンツの１つした。
その他にお勧めされたコンテンツとしては、[courseraのmachine-learning](https://www.coursera.org/learn/machine-learning)もありました。

#コンテンツの概要
+ 総時間 約1時間
+ AIについて、出てくるキーワードの説明
+ 機械学習とITの違い
+ ニューラルネットワークの説明
+ 機械学習応用実例

#所感
+ コンテンツ自体は少し古いですが、はじめてAIについてより知りたいという方には、内容は十分。
+ 事例として出てくるIT専門家でない方が機械学習を利用して、キュウリの選別をしたりと少し前だったら先進的な事例がでている。
+ ニューラルネットワークの仕組みについてわかりやすく説明されている。
+ 画像認識、音声認識についても簡単に説明されている。
+ これからAIについて勉強を始めていきたいと考えている方にもお勧めできる。

最後まで、お読みくださってありがとうございます。
誤植や、不適切な記述等ありましたら、ご指摘いただけますとありがたいです。
Githubを使ってHerokuへデプロイする流れ

メモとして簡易的な流れを記入しておきます。（mac OS)

# 前提
Herokuへの登録は完了しているものとします。
データベースにはMySQLを使用します。
Ruby on Railsを使用します。
Rubyはバージョン2.6.5

# 簡易的流れ
### 下準備

①Heroku CLIのインストール

```:ターミナル
% brew tap heroku/brew && brew install heroku
```

確認のためバージョンを確認

```:ターミナル
% heroku --version
```

②Herokuへのログイン

```:ターミナル
% heroku login --interactive 
```
登録したメールアドレスとパスワードを入力してログインします。

### デプロイ方法

①Heroku上にアプリケーションを作成

ターミナル上でデプロイしたいアプリケーションのタスクへ移動し、下記コマンドを実行します。
※既に登録されているアプリケーション名は使用できないので注意！

```:ターミナル
% heroku create アプリケーション名
```
下記のコマンドで設定できているか確認できます。

```:ターミナル
% git config --list | grep heroku
```
※ fatal: not in a git directoryであれば設定できていません。

②ClearDBアドオンの追加

```:ターミナル
% heroku addons:add cleardb
```

③MySQLに対応するGemについて設定を変更する

下記コマンドでClearDBのURLを変数heroku_cleardbに格納します。

```:ターミナル
% heroku_cleardb=`heroku config:get CLEARDB_DATABASE_URL` 
```

```:ターミナル
% heroku config:set DATABASE_URL=mysql2${heroku_cleardb:5} 
```

④Heroku上で環境変数を設定

```:ターミナル
% heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
```
下記で確認ができます。

```:ターミナル	
% heroku config
```

⑤Stackの指定

```:ターミナル	
% heroku stack:set heroku-18 -a アプリケーション名
```

⑥Githubのmaster情報をHerokuへプッシュ

```:ターミナル	
% git push heroku master
```

⑦Heroku上でのマイグレーション実行

```:ターミナル	
% heroku run rails db:migrate
```
### 公開の確認

```:ターミナル	
% heroku apps:info
```
上記コマンドで確認したWeb URL: のURLへアクセスして確認ができる。
docker-machineでホスト(Virtualbox)を立ち上げる際にエラーになる

とあるDockerの教材をもとに、docker-machineを使用してVirtualboxをホストとして立ち上げた際に下記エラーが出力しました。

```Linux
$ docker-machine create --driver virtualbox default
Creating CA: /Users/.docker/machine/certs/ca.pem
Creating client certificate: /Users/.docker/machine/certs/cert.pem
Running pre-create checks...
Error with pre-create check: "VBoxManage not found. Make sure VirtualBox is installed and VBoxManage is in the path"
```

###対応
単純に使用していたmacのPCにVirtualBoxが入っていなかっただけでした。
下記OracleのサイトからVirtualBoxをダウンロードしてインストールしたところ問題なく立ち上がりました。

https://www.oracle.com/virtualization/technologies/vm/downloads/virtualbox-downloads.html

```Linux
$ docker-machine create --driver virtualbox default
Running pre-create checks...
(defalut) Image cache directory does not exist, creating it at /Users/.docker/machine/cache...
(defalut) No default Boot2Docker ISO found locally, downloading the latest release...
(defalut) Latest release for github.com/boot2docker/boot2docker is v19.03.12
(defalut) Downloading /Users/.docker/machine/cache/boot2docker.iso from https://github.com/boot2docker/boot2docker/releases/download/v19.03.12/boot2docker.iso...
(defalut) 0%....10%....20%....30%....40%....50%....60%....70%....80%....90%....100%
Creating machine...
(defalut) Copying /Users/.docker/machine/cache/boot2docker.iso to /Users/.docker/machine/machines/defalut/boot2docker.iso...
(defalut) Creating VirtualBox VM...
(defalut) Creating SSH key...
(defalut) Starting the VM...
(defalut) Check network to re-create if needed...
(defalut) Found a new host-only adapter: "vboxnet0"
(defalut) Waiting for an IP...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with boot2docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env defalut
$ 
```

###最後に
しれっと教材ではVirtualBoxでホストを立ち上げてましたが、VirtualBoxをインストールしていなければ立ち上がりませんよね。基本的なことですが、いきなり出くわすと面食らっちゃいますね。
【PHP】初中級者が解くべき過去問精選 100 問を解いてみた【2問目/100】

アルゴリズムのアウトプット

ということで、
[レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【中級編：目指せ水色コーダー！】](https://qiita.com/e869120/items/eb50fdaece12be418faa#2-3-%E5%88%86%E9%87%8E%E5%88%A5%E5%88%9D%E4%B8%AD%E7%B4%9A%E8%80%85%E3%81%8C%E8%A7%A3%E3%81%8F%E3%81%B9%E3%81%8D%E9%81%8E%E5%8E%BB%E5%95%8F%E7%B2%BE%E9%81%B8-100-%E5%95%8F)@e869120さん



>AtCoder で水色コーダー、つまりレーティング 1200 を少ない問題数で達成するために、茶色コーダー・緑コーダーにとって適切な教育的良問を 100 問集めました。

こちらの記事の初中級者が解くべき過去問精選 100 問
をPHPで解いていきます。

```php

<?php
 
$num = trim(fgets(STDIN));
$answer = 0;
for ($i = 1; $i <= $num; $i++) {
    if ($i % 2 == 0) {
        continue;
    }
    $count = 0;
    for ($j = 1; $j <= $num; $j++) {
        if ($i % $j == 0) {
            $count++;
        }
    }
    if ($count == 8) {
        $answer++;
    }
}
 
echo $answer;

}
```

偶数のときはガード節使って計算量を減らすようにした。