OmniAICreator/Qiita-1.07M huggingface dataset:
Android, Kotlin: JavaMailでメール送信 (gmail)

メール送信をするAndroidアプリを開発しましたので、最低限の実装を記録しておきます。
gmailにてメール送信する際の設定もあわせて記載します。

この２つの記事を参考に作成しました。

- https://qiita.com/Rabbit_Program/items/9df03bf2c1885561a5bd
- https://it-engineer-info.com/language/android-app/2142/



## gmailの設定

gmailはAPIで送信することが推奨されているらしいですが、今回はSMTPでという要件でした。
その際はgmail(googleアカウント)の設定にて「安全性の低いアプリのアクセス」を有効にする必要があります。

1. https://myaccount.google.com/ にアクセス（対象のアカウントでログインする）
1. 「セキュリティ > 安全性の低いアプリのアクセス」を有効にする


## JavaMail のインストール

Android Studio のgradleにJavaMailを追記します。

```gradle:bundle.gradle(app)
implementation 'com.sun.mail:android-mail:1.6.5'
implementation 'com.sun.mail:android-activation:1.6.5'
```

バージョンは、1.6.5が最新ではありませんでしたが、参照にした記事がこのバージョンだったのでそのまま使いました。

## パーミッションの追加

通信をするアプリなのでマニフェストにパーミッションを追加します。

```xml:AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
```


## 実装

あとは実装するだけです。
レイアウトは省略します。ボタンが一つあるだけです。
MailServiceはメールを送信するクラスです。Serviceという名前はAndroidではややこしいのですが、最近までSpringのプロジェクトやっていたので勢いでこの名前にしてしまいました。
エラー処理もしていません。送信処理のところでExceptionをキャッチしないとパスワード間違えただけでアプリが落ちます。


```kotlin:MainActivity
package jp.co.sankosc.javamail

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button

class MainActivity : AppCompatActivity() {
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(R.layout.activity_main)

		findViewById<Button>(R.id.button).setOnClickListener {
			val service = MailService()
			service.send()
		}
	}
}
```

```kotlin:MailService
package jp.co.sankosc.javamail

import java.util.*
import javax.mail.*
import javax.mail.internet.InternetAddress
import javax.mail.internet.MimeMessage
import kotlin.concurrent.thread

class MailService {
	fun send() {
		thread {
			val property = Properties()
			property.put("mail.smtp.host", "smtp.gmail.com")
			property.put("mail.smtp.auth", "true")
			property.put("mail.smtp.starttls.enable", "true")
			property.put("mail.smtp.port", "587")
			property.put("mail.smtp.debug", "true")

			val message: Message = MimeMessage(Session.getDefaultInstance(property, object: Authenticator() {
				override fun getPasswordAuthentication(): PasswordAuthentication {
					return PasswordAuthentication("[gmailのアカウント]", "[gmailのパスワード]")
				}
			}))
			message.setFrom(InternetAddress("[送信元メールアドレス]", "[表示名]"))
			message.setRecipient(Message.RecipientType.TO, InternetAddress("[送信先メールアドレス]", "[表示名]"))
			message.subject = "タイトル"
			message.setText("こんにちは")
			Transport.send(message)
		}
	}
}
```
Windowsで日本語入力が出来なくなった場合の対応

#問題
MS Windowsを利用していて日本語変換キー「半角／全角漢字」キーを押下しても入力モードが変えられない。

#対象手順
1. タスクマネージャーを開く<br/>①「Ctrl」+「Alt」+「Delete」キーを同時に押下する<br/>②「タスクマネージャー」を選択
1. 「詳細」タブを選択<br/>![ime_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/ac24624e-4ac7-7e14-6aec-46565aa8ac5b.png)
1. cfmon.exeを再起動する<br/>①「cfmon.exe」を選択<br/>①「タスクの終了」ボタンを押下<br/>③タスクマネージャーを閉じる<br/>![ime_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/01bc6b3b-55ee-1b01-1a0b-5ed031303fe1.png)
1. cfmon.exeは自動的に再起動されて日本語が入力できるようになるはずです

以上
[備忘メモ]Eclipseで全角スペースと半角スペースを見分ける設定

# 環境
・Windows10
・Eclipse IDE Version: 2021-06 (4.20.0)
・Gradle 6.7
・Spring Boot: 2.5.4
・MySQL5.7


# Eclipseで全角スペースと半角スペースを見分ける設定
デフォルトだと全角スペースと半角スペースが見た目では判別つかない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879666/faa50029-964a-ee0c-c6f0-41fe71e5df32.png)

そこで、以下の設定を行う

一般＞エディター＞テキスト・エディター
空白文字を表示にチェックを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879666/bf5d8486-3b29-12f0-3d36-e78828b63af1.png)

すると、以下のように全角スペースと半角スペースの見分けが付くようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879666/fe831eb3-3a63-08b4-cdbe-71a950ee50ec.png)

1行目に全角スペースがあることがわかる。
ただこれだと半角スペースも表示されてみづらいので、全角スペースだけが表示されるようにする。
詳細な設定は同メニューの「可視性の構成」から行う。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879666/d27e55b4-415d-e6e3-b1fa-d17ba87069aa.png)

・空白の先頭と囲いのチェックを外す
・末尾の半角スペースは気になりがちなので、チェックする
・私の場合、全角スペースと同様に改行コードの違いでハマることもありそうなので、末尾の改行コードもチェックする


これで、全角スペースだけが表示されて見分けがつくようになった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879666/233c377c-69dc-b4dc-61e6-8c0e84987dee.png)



sqlの文法エラーの原因がわからず、色々調べた挙句全角スペースが原因であることがわかったので、備忘と自戒のために記録しておく。
JUnitでthrows Exceptionしないのは人道に反する

こういうのやめてほしいんです。疲れました。

```java:
@Test
public void testMethod_001 () {
    try {
        Foo foo = new Foo();
        Object result = foo.method();
        assertEquals(0, result);
    } catch (Exception e) {
        // ★☆★なんでこういうことするの★☆★
        e.printStackTrace();
        fail("テスト実行時に例外が発生しました");
    }
}
```

単体テストがどうあるべきかとか、日常生活の中で考えたりしないんですかね？
メンテナンス不能です。こんなの。

コンソール出力を見ないとどこで例外が起きたかわかりません。
どこの現場に行っても、何回指導しても直らなくてうんざりしています。誰かがそういう風に教育しているなら改めてほしいです。

そもそも、単体テストの結果って３通りあると思うんです。

* 成功　…　正しく動いた
* 失敗　…　動いたけど結果が正しくない
* 例外　…　そもそも動かない

失敗と例外は別物です。この２つを丸めてはいけません。例外は例外として通知しましょう。
テストケースが例外を投げたらレポートにもちゃんと例外の詳細が出力されるので、わざわざ `Exception#printStackTrace()` なんかせずにJUnitに任せてしまうべきです。

ということで、ちゃんと例外を通知するならこうです。

```java:
@Test
public void testMethod () throws Exception {  // throws句を足した
    Foo foo = new Foo();
    Object result = foo.method();
    assertEquals(0, result);
}
```

もちろん、 `Foo#method()` が検査例外を返さないのであれば `throws Exception` 無しでもいいです。何でもかんでも `try` ～ `catch` するなって話です。

例外が発生することをテストしたいなら `try` ～ `catch` してくれて構いませんが、ここもやはり最小限とすべきでしょうね。

```java:
@Test
public void testMethod_001 throws Exception () {
    Foo foo = new Foo();
    try {
        Object result = foo.method();

        // 例外が発生していないので失敗
        fail(result);
    } catch (FooException e) {  // 何でもかんでもcatchしない
        assertEquals("E001", e.getErrorCode());
        assertEquals("氏名が入力されていません", e.getErrorMessage());
    }
}
```
「SQLだけで済むので...」？先輩のコメントからany?とexists?の違いを学ぶ（Ruby,Rails）

先輩からちょいと指摘された行ったリファクタリングが、ちょいと深くておもしろかったのでメモ。

## 背景とやりたいこと
ゲームのコースのデータを管理するgameモデルがあるとします。
ゲームにはstage1, 2があり、各コースにはnormal, specialの２つの種類（kind）があります。

```ruby:app/models/game.rb
# == Schema Information
#
# Table name: games
#
#  id                 :bigint           not null, primary key
#  name               :text             not null
#  stage              :integer          not null
#  kind               :integer          default("first_normal"), not null

class Game < ApplicationRecord
  exnum stage: { first: 1, second: 2 }, _prefix: true
  exnum kind:  { normal: 10, special: 20 }, _prefix: true
```

やりたいこと→**各stageにkind_specialがあるかを判定するモデルメソッドを作りたい**です。

## 実装！

まずは僕が書いたコードと、先輩に提示されたコードを。

### 自分のコード

```ruby
class Game < ApplicationRecord
  def self.stage_has_special?(stage)
    send("stage_#{stage}").any?(&:kind_special?)
  end
end
```

### 先輩のコード

```ruby
class Game < ApplicationRecord
  def self.stage_has_special?(stage)
    send("stage_#{stage}").kind_special.exists?
  end
end
```

上の二つのコードどちらでも、「各stageにそれぞれkind_specialがあるかを判定する」というやりたいことは実現できます。

「なんでこのリファクタリングが必要なんだろう、可読性が上がるから？」としか気付けなかった僕はまだまだなようで、先輩からは「**SQLだけで済むからです**」と返ってきました。

## 「SQLだけで済む」とは？

２つのプログラムのログを見比べつつ、それぞれどんな挙動になるのか整理してみました。

#### 僕コードのSQL

```sql
Game Load (1.1ms)
SELECT
  "games".*
FROM
  "games"
WHERE
  "games"."stage" = \ $ 1 [["stage", 1]]
```

僕のSQLは特定のstageのgamesを全て取得してきているだけです。
ということは、ログには現れませんが、**この後にRubyのコードが走っている**ということになります。
any?でループが回ります。

#### 先輩コードのSQL

```sql
Game Exists ? (1.4ms)
SELECT
  1 AS one
FROM
  "games"
WHERE
  "games"."stage" = \ $ 1
  AND "games"."kind" = \ $ 2
LIMIT
  \ $ 3 [["stage", 2], ["kind", 15], ["LIMIT", 1]]
```

先輩のコードは、特定のstageのgamesを条件付きで取得します。
その条件とは、どのstageか、kind_specialかなので、**一度SQLを発行して終了**です。
先ほどと違って、この後にRubyは動きません！
`exists?`メソッドはSQLで`LIMIT 1`を発行してくれるので、見つかった時点でBooleanを返してくれます。

確かにSQLだけで済んでいます！SQLだけで同じことを実現しています。エコ！:earth_asia:

## any?とexists?まとめ
具体的には`Enumerable#any?`と`ActiveRecord::FinderMethods#exists?`のまとめです。

ここで出てきた`any?`はRubyのEnumerableモジュールのインスタンスメソッドでRubyを動かすメソッド。
`exists?`はActiveRecordのメソッドで、SQLを発行するメソッドです。Rubyは動きません（ハズ）。

どちらのメソッドもデータの存在を尋ねるという意味ではとても似ていて、RailsガイドのActive Recordのページ「[20 オブジェクトの存在チェック](https://railsguides.jp/active_record_querying.html#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E5%AD%98%E5%9C%A8%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF)」という章で、「モデルやリレーションでの存在チェックにはany?やmany?も使用できます。」と書いてあって、浅読みすると「exists?の代わりにany?も使えるよ！」と勘違いしそうですが、ここでいう`any?`は`Enumerable#any?`ではなく、ActiveRecordで定義されている`any?`メソッドのことのようで、この記事で見てきたany?とは別物のようです。

ドキュメントで言うとこの辺の`any?`でしょうか↓
https://api.rubyonrails.org/classes/ActiveRecord/Associations/CollectionProxy.html#method-i-any-3F
https://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-any-3F

参考までに`exists?`のドキュメント↓
https://api.rubyonrails.org/v6.1.3.1/classes/ActiveRecord/FinderMethods.html#method-i-exists-3F

## 最後に
とある実業家と「ベンチャー女優」が出演するYouTubeで「プログラミングは動けばいいんですよね:star2:」と語られていて:open_mouth:となりましたが、この課題に見られるように、僕はその段階からステップアップして、プログラムがどう動くかを気遣えるようになりたいと思ったりとか。

@Kta-M に感謝！
SyntaxError: (unicode error) 'utf-8' codec can't decode bytes in position 0-1: unexpected end of data

突然、pandas のエラーが発生した。
SyntaxError: (unicode error) 'utf-8' codec can't decode bytes in position 0-1: unexpected end of data


> pip uninstall pandas 
> pip install pandas 

で対応した。

原因は分かりませんが、突然のエラーでした。参考までに。




> Traceback (most recent call last):
  File ".\RealTime_object_detect.py", line 5, in <module>
    import pandas as pd
  File "C:\Users\e13736\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\__init__.py", line 51, in <module>
    from pandas.core.api import (
  File "C:\Users\e13736\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\core\api.py", line 31, in <module>
    from pandas.core.groupby import Grouper, NamedAgg
  File "C:\Users\e13736\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\core\groupby\__init__.py", line 1, in <module>  
    from pandas.core.groupby.generic import DataFrameGroupBy, NamedAgg, SeriesGroupBy
  File "C:\Users\e13736\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\core\groupby\generic.py", line 65, in <module>  
  File "C:\Users\e13736\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\core\frame.py", line 119, in <module>
    from pandas.core import algorithms, common as com, generic, nanops, ops
  File "C:\Users\e13736\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\core\generic.py", line 2800
    """
    ^
SyntaxError: (unicode error) 'utf-8' codec can't decode bytes in position 0-1: unexpected end of data
【Java】ポリモーフィズムについて復習していく

#目的

* ポリモーフィズムの理解を深める

#実際の手順と実例
###1.ポリモーフィズムとは

同じクラスを継承した別々のクラスのオブジェクトの同じメソッドを呼び出した時に、それぞれのオブジェクトの振る舞い（処理）を変えることです。

下記の例をもとに見ていきます。


###2.例題

サンプルを作成しました。

まずは親クラスの作成をします。

```Jump.java
package practice.jump;

public class Jump {
//	フィールドメソッドを定義
	private String name;
	protected String dream;

//	コンストラクタを作成
	public Jump(String name, String dream) {
		this.name = name;
		this.dream = dream;
	}
	
//	final修飾子をつけることで他で使えなくする（オーバーライド禁止）
	final public String getName() {
		return this.name;
	}
	
//	それぞれ子クラスで使うメソッドを作成
	public String getDeream() {
		return this.dream;
	}
	
	public String getProfile() {
		return "俺の名は" + this.name + "!" + this.dream + "に俺はなる！！";
	}
}

```

続いて子クラスを２つ準備します。

```Onepiece.java
package practice.jump;

//親クラスを継承
public class Onepiece extends Jump{
//	新たにフィールドを宣言
	private int count;

//	コンストラクタを作成
	public Onepiece(String name, String dream, int count) {
		super(name, dream);
		this.count = count;
	}
	
//	メソッドを作成
	public String getProfile() {
//		ここで新たに値を作成（異なる結果になる値）
		String profile = super.dream + "に俺はなる！！";
		profile += "仲間" + this.count + "人は欲しいな";
//		戻り値を設定
		return profile;
	}
}

```

```Naruto.java
package practice.jump;

public class Naruto extends Jump {
	private String skill;

	public Naruto(String name, String dream, String skill) {
	        super(name, dream);
	        this.skill = skill;
	    }

	public String getProfile() {
		String profile = super.dream + "に俺はなる！！";
		profile += "世界を救った術は" + this.skill;
		return profile;
	}
}

```
最後に実行ファイルを作成します。

```Jump01.java
package practice.jump;

public class Jump01 {
	public static void main(String[] args) {
//		子クラスでで意義したデータ型に当てはめる
		Jump hero1 = new Onepiece("ルフィ", "海賊王",10);
		System.out.println(hero1.getProfile());
		
//		それぞれ子クラスで定義したデータが出力される
		Jump hero2 = new Naruto("ナルト", "火影","逆ハーレムの術");
		System.out.println(hero2.getProfile());
	}

}
```

実行結果は以下の通り、
同じメソッドで呼び出しているのに
オブジェクトの処理がそれぞれ変わりました！


```
海賊王に俺はなる！！仲間10は欲しいな
火影に俺はなる！！世界を救った術は逆ハーレムの術
````
Slackをtwitter化したい　2回目

# Summary
- メッセージ全取得は events api じゃないと厳しそうだった
- conversations.list の webAPiだとともかく新しい発言を探すのが難しい

悩んでしまったので整理して比較する。
# 比較
**events api**
Pros

- 新しい発言を取得するのにslackが用意したAPIの中で最適
- サーバーを立ち上げる必要があるがゆえにできることは増えそう

Cons
- 利用者がサーバーを立ち上げる必要がある。
- デスクトップアプリは他人に進めるのに敷居が高い

・web api

Pros

- vueだけで完結する

Cons

- WebAPIだけですべての新しい発言をとってくるのは用意されていない
- 何かしらのアルゴリズムを検討する必要がある
- いずれにせよAPICallの制限があるのでスケールもしない


## 結論
EventsApiのほうに倒す
Slack <(1)-(1)> サーバー（golang） <(1)-(N)> クライアント（vuejs） が成立するようにする
→もともとエンジニア一人が必須と考えていたためインストールの難易度が少し上がっても気にしない。

## 検証
アプリ作って必要な権限をつける
https://api.slack.com/events/message

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2103758/0c897a77-cd21-c96d-7443-ec2fd88f8c6f.png)
こんな感じかな？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2103758/b6000500-892b-23d2-2195-6362dd48f33d.png)
やっぱりこうなった。

適当にWebサーバーたてて、ポート開放して動作確認したら接続できず。
ルーターの説明読んだら👇のようなことが書いてあった。
>LAN側にWebサーバを設置し、同じLAN内に設置している別のパソコンからWAN側のIPアドレス（グローバルIPアドレス）に接続してもアクセスできません。
一時的に別の回線で接続するなどして動作確認してください。


う～ん、使ったことないけど heroku なるものでチャレンジしてみるか。

次回：Slack Events Api + heroku + golang で wssに挑戦
gitレポジトリの全履歴からファイルを削除する

## ファイルを削除

```bash
git filter-branch -f --tree-filter "rm -f 消したいファイルのパス(hoge/fuga.tar.gz)" HEAD
```

## GCを実行

```bash
git gc --aggressive --prune=now
```

## push

```bash
git push -f
```

## cloneしなおし

push後はpullではなくcloneし直す。
ReactからNext.jsへの移行方法

# はじめに
今回、ReactのプロジェクトをNext.jsにreplaceする機会があったので、忘備録として記録しました。

# 1. Next.jsのインストール
（前提）npx create-react-appにてReactプロジェクトを作成している場合
プロジェクト直下にて

```
yarn add next
```

# 2. ファイル構造を変更
以下のように変更。

```diff
frontend/
    public/
-       index.html
    src/
        ...
+       pages/
+               _app.js
+               _document.js
+              (必要なページ分jsxファイルを作成する)
-       index.js
-       App.js
        ...
```
Reactでは、index.html -> index.js -> App.js と読み込まれるが、
Next.jsでは、
**_app.js**：　全ページで共通して実施させたい処理を記述
**_document.js**：　 全体の文書構造をカスタマイズ
をベースとして、それぞれのPageが読み込まれる。
<br/><br/>
以下の記事参考にさせて頂きました。
https://qiita.com/tetsutaroendo/items/c7171286137d963cdecf
<br/><br/>
ルーティングはpagesのファイル構造を反映する。

```
pages/
    _app.js
    _document.js
    index.jsx
    login.jsx
    users/
          index.jsx
          [id].jsx
```

上記のファイル構造の場合、以下のルーティングになる。

```
/ (ルートパス) =>      index.jsx
/login =>           login.jsx
/users =>           users/index.jsx
/users/:id =>       users/[id].jsx
```

# 3.Next.jsのLinkコンポーネントに置き換える
既にreact-route-domでのLinkコンポーネントを使っている場合、
next.jsのLinkコンポーネントに置き換える。

```
import Link from 'next/Link'
```

Linkコンポーネントは以下の様に書く。

```
<Link href='/users'><a>ユーザー</a></Link>
```

これによりClient Side Navigationが実現できる。
（JavaScriptによってページを切り替える仕組み。ページの再読み込みが不要。クライアントの状態を保ってページ遷移。）
また、ページにLinkコンポーネントがある場合、そのLink先のコードを事前に取得(prefetch)する。


# 4.CSSを反映させる
### styled-component
パッケージを追加。

```
yarn add -D babel-plugin-styled-components
```

プロジェクト直下に以下のファイルを作成。

```.babelrc
{
  "presets": [
    "next/babel"
  ],
  "plugins": [
    [
      "styled-components",
      {
        "ssr": true,
        "displayName": true
      }
    ]
  ]
}
```

### @material-ui/core/styles
_document.jsのgetServerSidePropsを以下のように記述。

```
import React from "react";
import Document, { Html, Head, Main, NextScript } from 'next/document'
import { ServerStyleSheets } from "@material-ui/core/styles";

import CssBaseline from '@material-ui/core/CssBaseline'

const MyDocument = () => {
  return (
    <Html>
      <Head />
      <body className="custom_class">
        <CssBaseline/>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

MyDocument.getServerSideProps = async (ctx) =>  {
  const sheets= new ServerStyleSheets();
  const originalRenderPage= ctx.renderPage;
  ctx.renderPage = () => originalRenderPage({
    enhanceApp: (App)=> (props)=> sheets.collect(<App {...props} />)
  });
  const initialProps = await Document.getInitialProps(ctx)
  return {
    ...initialProps,
    styles: [
      ...React.Children.toArray(initialProps.styles),
      sheets.getStyleElement()
    ]
  }
}

export default  MyDocument
```

# 5. 環境変数を.envにて管理している場合
クライアントサイドで使用するには定義する変数名のプレフィックスにNEXT_PUBLIC_をつける。

```.env
NEXT_PUBLIC_REACT_APP_GO_API_URL=http://localhost:8080
```

以下のように呼び出せる。

```
process.env.NEXT_PUBLIC_REACT_APP_GO_API_URL
```
Electron - exeの作成

Electronのアプリをexeにしてみます。

※検証環境
Windows 10 Home, Node.js:v14.17.4, Electron:v15.0.0

# ツールの選択

electron-builderも人気のようですが、公式サイトの推奨(?)にそってelectron-forgeを使ってみます。

# electron-forgeの導入

実行にはGitが必要なので事前にインストールします。

https://gitforwindows.org/

exe化したいプロジェクトにelectron-forgeをインストールします。

```
> npm i -D @electron-forge/cli
```

※2021/10/1現在、依存先のtrim-newlinesの脆弱性を指摘されますが、実際にこのライブラリが呼び出されることはないようです（下記参照）。ということでいったん続行します。

https://github.com/electron-userland/electron-forge/issues/2377

# exeの作成

## author,descriptionの設定

exeファイルを作成するにはパッケージの`author`,`description`を設定する必要があります。
package.jsonの該当部分を確認し、空の場合は編集します。

```json:package.json
 ...
 "author": "fumi-410",
 "description": "hello world application",
 ...
```

## exeの作成

まず、electron-forgeの`import`コマンドを実行します。

```
> npx electron-forge import

√ Checking your system
√ Initializing Git Repository
√ Writing modified package.json file
√ Installing dependencies
√ Writing modified package.json file
√ Fixing .gitignore

We have ATTEMPTED to convert your app to be in a format that electron-forge understands.

Thanks for using "electron-forge"!!!
```

`make`コマンドでexeファイルを作成します。

```
> npm run make
...
√ Checking your system
√ Resolving Forge Config
We need to package your application before we can make it
√ Preparing to Package Application for arch: x64
√ Preparing native dependencies
√ Packaging Application
Making for the following targets: squirrel
√ Making for target: squirrel - On platform: win32 - For arch: x64
```

プラットフォームによりますが、`.\out\xxx-win32-x64` 配下にexeが作成されていれば成功です。
exeファイルをダブルクリックし、ウィンドウが表示されることを確認します。

また、`.\out\make\squirrel.windows\x64` 配下に配布可能なセットアップ用exeが作成されます。

# 参考

Electron クイックスタート
https://www.electronjs.org/docs/tutorial/quick-start
React応用 - PartX - React > Netlify > Lambda > Python > MySQLどこまでいけるんだろう

# タイトルの件

妄想してみました。
どこまで出来るか試してみたいと思います。

# React ⇒ Netlify

いつものように`create-react-app`

```
npx create-react-app プロジェクト名 --template typescript
```

いつものように`yarn start`でReact初期画面を`localhost:3000`で表示されることを確認します。

```
cd プロジェクト名
yarn start
```

gitにコミット＆プッシュ
※git@github.comXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXは、後述のGitHubで新しいリポジトリ作成の際に表示されるものを入力します。

```
git init
git remote add origin git@github.comXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
git push -u origin master
```

Githubで新しいリポジトリを作成した際に表示されるURLみたいなやつ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/d7d0b123-685d-8232-79a6-c66bfafa360d.png)


こんな風にGithubにアップされました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/e008140f-9ed0-8074-4665-7302150ea670.png)


あとは、[このへん](https://qiita.com/suin/items/743fe6252ad8af425c5e)を参考にしました。

新しいサイトを作り、そのネタは、GithubからにすればOK

そしてアクセスするとLearn React画面が出ました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/d2353fab-b307-28fb-b46e-907a1077fc60.png)

# LambdaとAmazon API GateWayでの設定

[ここ](https://qiita.com/takuma-jpn/items/341f6eae13b7165f1221)を参考にLambda関数とAPI Gatewayを作ります。

# React ⇒ Lambda

[ここでやったように](https://qiita.com/yokowake12345/items/2c7cbf34f1c69af52b83)axiosをインストールします。

```
npm install axios
```

[同じくここでやったように](https://qiita.com/yokowake12345/items/2c7cbf34f1c69af52b83)以下のようにソースを修正します。
<font color="red">urlの部分はAWS API Gatewayのやつを指定してください。</font>

```typescript
import React, { useState, useLayoutEffect } from "react";
import axios from "axios";

export const App: React.FC = () => {
  const url = `https://rsejkxw59a.execute-api.us-east-2.amazonaws.com/testLambda`;
  // データを保存するやつ
  const [data, setData] = useState();

  useLayoutEffect(() => {
    axios.get(url).then((res) => {
      setData(res.data);
    });
  }, [url]);

  /** レンダー部分 */
  return <>{JSON.stringify(data)}</>;
};

export default App;
```

以下のcorsの設定をしないとブラウザのコンソールログにエラーが出てました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/742bc7b8-68a4-8cfb-8e7d-9bf60068634c.png)







<font color="red">2021.10.01 いまんとこここまで達成！ここから先はDBにお金がかかりそうなのでちょっと調べてからまた更新します。</font>


<!--
あと、今回は、[ここを参考に](https://zenn.dev/brachio_takumi/articles/20210226-react-query)React Queryなるものを導入してみます。

```
npm install react-query
```
-->
論文まとめ：TRB: A Novel Triplet Representation for Understanding 2D Human Body

# はじめに　
ICCV 2019 から以下の論文
[1] H. Duan, et. al. "TRB: A Novel Triplet Representation for Understanding 2D Human Body"
のまとめ

arXiv:
https://arxiv.org/abs/1910.11535

著者らが用いた MP2 dataset に対するアノテーションはこちら
https://github.com/kennymckormick/Triplet-Representation-of-human-Body
にある

日本語のまとめ:
DeNA 加藤直樹 (@nk35jk) によるざっくりしたまとめはこちら
https://engineer.dena.jp/2019/11/cv-papers-19-2d-human-pose-estimation.html

<font color='red'>書きかけのまま数年間放置されてたのでいったん投稿</font>

# 概要 
- 2Dの姿勢推定と輪郭抽出を同時に行うモデル
- Triplet Representation for Body (TRB) なるものを導入
- 新しいアプローチなので、dataset も新たに作成し、公開している

出力はこんな感じ。

<img width="695" alt="TRB_img00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/ca3eeef0-a7c4-46f4-3e63-0b4dc802a41a.png">


# 背景
ありがちな姿勢推定では、各関節を推定し骨格を形成する。しかしその方法だと人の輪郭的な情報が無くなってしまう。

もし輪郭も同時に抽出できると、そこにアバターをはめ込んだり等、面白いアプリに応用できるだろう。

一方で輪郭のみを抽出する手法は従来からあるが、人の領域をセグメントするような手法であり、骨格情報が欠如してしまう。

本手法は骨格も捉えながら、輪郭も抽出できる新しいアウローチ。

# モデルの全体像
全体像の図は以下。

<img width="984" alt="TRB_img02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/e9b711a0-4cd2-c0ab-9978-781caebf9b62.png">

まず、ありがちだが全体は多段になっていて、段階（stack）を経るごとに refine されていく。

なので、１つの stack に注目する。

<img width="484" alt="TRB_img02_01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/7828dcd0-77b3-0099-8685-42d109be7e33.png">

そうすると、ざっくり以下のような流れ。

（１）左から人の写った画像を入力し、まず Feature Extractor で特徴量を抽出する。

（２）その右、２つある MS block （multi-scale feature extraction) のうちの上側で骨格の heatmapを推定し、下側で輪郭の heatmapを推定する

（３）各 heatmap は stack ごとに loss を取る

（４）両方の heatmapを MP block (X-structured Message Passing Block)なるものに入れ、相互作用させ、次のstackに送る

# MP (X-structured Message Passing Block) 
MP は骨格に関する特徴量と輪郭に関する特徴量を相互に入れ替えることで関連性を強化する。

例えば、輪郭の位置は骨格が基準になっているので、骨格の情報を入れることで輪郭の位置も確かになるだろう。

以下の３種類が提案されている。

<img width="992" alt="TRB_img03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/ce9b1a80-40c7-aae0-29e4-fa3419789a00.png">
【Docker】[failed to load cache key: invalid empty config file resolved] を解決した方法 (備忘録)

# 結論

ビルド前に予め

```
$ docker pull docker/whalesay
```

のコマンドを実行して、イメージを pull しておく。
　　
※ 上記コマンド実行時に
`Error: remote trust data does not exist for docker.io/docker/whalesay`
というエラーが出た際には、
こちらの [dockerでWhalesayイメージがpull(run)できない時の対処法](https://qiita.com/nasuB7373/items/92166d7958044ab8d450) を参照してください。


# エラーが出た場面

Udemy の
[ゼロからはじめる Dockerによるアプリケーション実行環境構築](https://www.udemy.com/course/docker-k/learn/lecture/8653606) にて、
イメージビルドができない場面に出くわした際の解決方法です。
[34. Dockerfileを使用したイメージビルドの実行] ← ココです。


# 参考にした情報
https://github.com/moby/buildkit/issues/2033
Cisco機器をずっとさわってきたネットワークエンジニアが、急にJuniperやalcatel(NOKIA)機器をさわることになり基本コマンドに苦労した話


10年以上Ciscoスイッチやルータをさわっていた私が、急にJuniperや Alcatel-Lucent(現NOKIA)のスイッチやルータをさわることになり、コマンドや思想の違いに苦労しました。
代表的なコマンドを下記に列挙します。

ネットワークエンジニアだからと言って、"同じスイッチだからわかるでしょ"とか言うな。

------------------------------------------------------------------------

Cisco : IOS
Juniper : JUNOS
Alcatel : ???

------------------------------------------------------------------------

＜表示方法設定＞
Cisco : ter len 0
Juniper : set cli screen-lengh 0 / set cli screen-width 0
Alcatel : enviroment no more

＜稼働コンフィグ表示＞
Cisco : show run
Juniper : show configuration (階層表示)
　show configuration | display set（set形式表示）
Alcatel : admin display-config

＜物理ポート、物理インターフェース＞
Cisco : show interface ～ / show interface status
Juniper : show interface ～ / show interface terse
Alcatel : show port ～

＜保存＞
Cisco : wr  mem
Juniper : commit , commit sync
Alcatel : admin save

＜exit,logout＞
Cisco : exit
Juniper : exit
Alcatel : logout

------------------------------------------------------------------------

※Juniper便利なコマンド
commit check
 commit前にコンフィグの正当性チェック
show | compare
 commit前であれば変更したコンフィグ差分を表示する。
Python matplotlibのhist(bins=int)とRのhist(breaks=integer)の違い


Pythonの`hist(bins=int)`とRの`hist(breaks=integer)`。いずれも、区間数を指定すると区間幅の設定が自動で行われる機能である。しかし、 **区間の上限下限の設定が異なる。**

## R

breaksが数値の場合(`hist(VEC,breaks=BREAKS)`)、集計範囲は

```R
pretty(range(VEC), n=BREAKS)
```

によって(おおよそ100やら1000やらの単位になるよう)算出される[^1]。

## Python (matplotlib)

binsが数値の場合(`plt.hist(VEC,bins=BINS)`)、集計範囲は

```py
(min(VEC), max(VEC))
```

によって算出される[^2]。上限下限を切りの良い数値にしたい場合、たとえば

```py
plt.hist(VEC,bins=BINS,range=(-1000,1000))
```

のように明示的にrange=を指定する必要がある。

## 終わりに

特に拡大比率を変えて複数のヒストグラムを描く場合は、分布が変化してしまいうるのでご注意下さい…

[^1]: https://svn.r-project.org/R/trunk/src/library/graphics/R/hist.R
[^2]: https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/axes/_axes.py
DNSサーバーとは

# はじめに
本記事では、DNSサーバーについて記述します。

# DNSサーバーとは
`Domain Name System`の略。
インターネット上で`ドメイン名`を管理・運用するために開発されました。

また、`IPアドレス`と`ドメイン名`を変換する仕組みを提供するサーバーです。

`IPアドレス`と`ドメイン名`を確認します。


### IPアドレス
インターネット上にある`アドレス`のような認識です。

サーバー、パソコンやスマートフォンなど`ネットワーク上の機器を識別している`のは`IPアドレス`です。
数字の羅列です。

```
172.217.175.35

これを検索してみると「Google」に繋がります。
これを「IPアドレス」と言います。
```

インターネット上における通信は、
相手先のIPアドレスが指定されることにより行われます。

### ドメイン
サーバー、パソコンやスマートフォンなど`ネットワーク上の機器を識別している`のは
`IPアドレス`という数字で住所を判断しますが、
上にもあった通り、`172.217.175.35`が`Google`に繋がるということは分からないです。

そこで、アドレス`172.217.175.35`を`文字`にしたものが`ドメイン`ということになります。

`google.com`という形になります。

# DNSとは`ドメイン名`に対応する`IPアドレス`を教えてくれる
例えば`google.com`とブラウザのアドレスバーに入れると、
DNSに問い合わせを行い、IPアドレス`172.217.175.35`を教えてくれます。

DNSサーバーは２つの種類があります。 
- `このドメインのIPアドレスは何なのか`をまとめる`キャッシュDNSサーバー`
- `これやで`と名前解決結果を返答する`権威DNSサーバー`

### キャッシュDNSサーバー
DNSによる`ドメイン名に対応するIPアドレス`の結果を一定期間保存し、
短期間に繰り返し同じ`問い合わせ`を同じサーバーに送らないようにする仕組みです。 

効率的かつ権威DNSの負担を減らしています。

### 権威DNSサーバー
`IPアドレス`と`サーバー名`などを対応させるレコードを持ち、
`キャッシュDNSサーバー`から来る`問い合わせ`に対して、返答を返してくれます。 

また、キャッシュDNSサーバーは、保存されている結果を、
一時的に保存するので、キャッシュDNSサーバーが返答したりするので、
`権威DNSサーバーの負担`は`減る`ことになります。

以上です。

# 終わりに
Wi-Fiの接続にしか聞いたことがなかったので、
改めて調べてみました。

IT用語は他にも知ってそうで知らない単語が多いので、
広く知っていこうと思います。

以下参考サイトです。
[意外と知らない？ITトレンド用語](https://www.ntt.com/bizon/glossary/e-d/dns-server.html)
[DNSって何？DNSレコードって？イチから理解しよう！](https://remacre.jp/column/homepage/8786/)
[DNSとは](nic.ad.jp/ja/basics/beginners/dns.html)

明日も頑張ります！！
HAVING句でデータの歯抜けを探す方法を見ながら、集合思考言語と手続き型言語の違いを考える（1/2）

## はじめに

HAVING句でデータの歯抜けを探す方法を見ながら、集合思考言語と手続き型言語の違いを考えてみます。

Schema (MySQL v8.0)

```sql
CREATE TABLE members (
  id INT NOT NULL PRIMARY KEY auto_increment,
  name TEXT
);

INSERT INTO members VALUES
    (1, 'brown'),
    (2, 'rally'),
    (3, 'boggie'),
    (5, 'tashiro'),
    (6, 'yamada'),
    (8, 'takeda');
```

Result

| id  | name    |
| --- | ------- |
| 1   | brown   |
| 2   | rally   |
| 3   | boggie  |
| 5   | tashiro |
| 6   | yamada  |
| 8   | takeda  |

このデータの歯抜けをどう探しますか？

仮に、このテーブルがファイルで、手続き型言語を使って調べるなら...

- ソートする
- ソート順にループさせて、1行づつ次の行と比較

ファイルのレコードは**順序**を持ち、それを扱うためのプログラミング言語もソートを行えます。

一方、テーブルの行は順序を持ちませんし、SQLもソートの演算子を持っていません。

ORDER BY 句はSQLの演算子ではなくカーソル定義の一部です。

> ORDER BY は、結果を表示する目的には便利だが、それ自体はリレーショナル演算子ではない。

引用👇（15のページに記載）

https://www.amazon.co.jp/dp/4873112753

### SQLではどう表現するか

複数行を1つにまとめて集合として扱います。

query

```sql
SELECT '歯抜けあり' AS gap
FROM members
HAVING COUNT(*) <> MAX(id)
```

`<>`は、jsでいう`!==`で、等しくないという意味です。

results

| gap   |
| ----- |
| 歯抜けあり |

このクエリは、1行返れば「歯抜けあり」が返るが何も返らなければ連番であるということになります。

図解するとこういう感じです。

![IMG_72EFC2BE915B-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/9d458c90-ce5c-ff6c-b045-3be30d7fa5d8.jpeg)

つまり、**一方の集合は他方の写像であることをテストしていることになります。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/9663c3c3-4a97-1f97-4ee0-e64f80b2ba43.png)

https://ja.wikipedia.org/wiki/%E5%86%99%E5%83%8F#:~:text=%E5%86%99%E5%83%8F%EF%BC%88%E3%81%97%E3%82%83%E3%81%9E%E3%81%86%E3%80%81%E8%8B%B1%3A,%E7%94%A8%E3%81%84%E3%82%89%E3%82%8C%E3%82%8B%E3%81%93%E3%81%A8%E3%82%82%E3%81%82%E3%82%8B%E3%80%82

上記のクエリは、歯抜けが存在する場合、絶対不一致になりますね。

### HAVINGはGROUP BY と併用しなければいけないわけでは無い

現在の標準SQLでは、**HAVING句を単独で使える**そうです。

ただし、SELECT句で元テーブルの列を参照できなくなるので、上記SQLのように、定数を返すようにするか、以下のように集約関数を使う必要があります。

```sql
SELECT SUM(*) FROM ...
```

本日は、以上です。

## 参照

https://www.amazon.co.jp/dp/4798157821/

105 - 109p

## アウトプット100本ノック実施中

https://qiita.com/ryosuketter/items/713474dbd009870e4103
FlutterでXFileとFileを変換する方法

# はじめに
私はFlutter初心者です。
この記事は、Flutter初心者が「こうやれば自分のしたいことができたんだ！」と思ったことを備忘録を兼ねて書いたものです。
あと日本語記事が見つからなかったので、書いているっていうのもあります。
そのため、間違っている部分があればコメント等で指摘いただければ助かります。

# XFileからFileに変換する方法
```Dart
XFile xfile = XFile(file.path);
```

# FileからXFileに変換する方法
```Dart
File file = File(xfile.path);
```
# おわりに
やってみたら簡単でした。
おまけとして、そもそもXFileとFileって何か、XFileとFileは何が違うかっていうのを書こうと思ったのですが、調査不足と時間不足により、後日書くことができれば書きます。

# 参考にしたサイト
[How to convert a XFile to File in Flutter](https://stackoverflow.com/questions/66185696/how-to-convert-a-xfile-to-file-in-flutter/66185959)
AtCoder Beginner Contest 211

##[A - Blood Pressure](https://atcoder.jp/contests/abc211/tasks/abc211_a)

O(1)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    
    int A, B;
    cin >> A >> B;
    cout << (double)(A - B) / 3.0 + (double)B << endl;

    return 0;
}
```

##[B - Cycle Hit](https://atcoder.jp/contests/abc211/tasks/abc211_b)

O(1)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {

    map<string, int> m;

    rep(i, 4){
        string s;
        cin >> s;
        m[s]++;
    }

    if(m["H"]>0 && m["2B"]>0 && m["3B"]>0 && m["HR"]>0) cout << "Yes" << endl;
    else cout << "No" << endl;

    return 0;
}
```

##[C - chokudai](https://atcoder.jp/contests/abc211/tasks/abc211_c)

O(N*8)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int dp[100010][9];
string t = "chokudai";

int main() {
    string s;
    cin >> s;

    int n = s.size();
    rep(i, n) dp[i][0] = 1;

    rep(i, n) rep(j, 8){
        if(s[i] != t[j]){
            dp[i+1][j+1] = dp[i][j+1];
        }else{
            dp[i+1][j+1] = (dp[i][j+1] + dp[i][j]) % 1000000007;
        }
    }

    cout << dp[n][8] << endl;

    return 0;
}
```
[Python] 別ディレクトリにある同じ名前のcsvファイルを自動結合した。

# 課題内容

以下のように、同じディレクトリ配下にサブディレクトリが二つ。
サブディレクトリの中にあるファイル名は同一だが、中身は異なる。
ファイル名が同一のものだけを結合して出力したい。
\#備忘録なので、コードの正確性, 解説の精度に関してはご容赦ください。

**想定するディレクトリ状況**
>Main_dir/
　├ sub_dirA/
　│　　├ file1.csv
　│　　└ file2.csv
　└ sub_dirB/
　　　 　├ file1.csv
　　　　 └ file2.csv

**求める結果**
>Main_dir/
　├ sub_dirA/
　│　　├ file1.csv
　│　　└ file2.csv
　├ sub_dirB/
　│　　　├ file1.csv
　│　　　└ file2.csv
　├ file1.csv　(dirAとdirBの結合結果)
　└ file2.csv　(dirAとdirBの結合結果)

## 類似した既知の課題
下の様に、同じディレクトリ配下にある```file1.csv```と```file2.csv```を結合して、新たな```file3.csv```とするコードは既にある。
>
Main_dir/
　├ file1.csv
　├ file2.csv
　└ file3.csv

->[pythonで複数のcsvファイルを1つのcsvファイルにまとめる(ヘッダーが1行だけの前提): 有志のQitta](https://qiita.com/minamini1985/items/60047ea416cd49721cf3)

## 今回の課題に対するアプローチ

1. ```input()```を用いて操作するディレクトリを把握させる。
2. ```os.walk```を用いてディレクトリ状況を把握させる。
3. ファイル名が同じ場合に結合するため、1番最初のディレクトリのファイル名のみ取得させる。
4. 1, 2で習得した情報を基に```pandas```を用いてファイルを結合する。
5. 結合したファイルをcsvとして適当な場所に出力する。

## 前提条件
・Python 3.9.7
・pandas

# 結論
```python:combi_csv.py
import pandas as pd
import os

print("パスを入力")
main_dir = input()

all_dirs=[]
for curDir, dirs, files in os.walk(main_dir):
	for now_dir in dirs:
		all_dirs.append(now_dir)

all_files=[]
for curDir, dirs, files in os.walk(all_dirs[0]):
	for file in files:
		all_files.append(os.path.join(file))

counter=0
for now_file in all_files:
	df1 = pd.read_csv(all_dirs[counter] +'/'+ now_file)
	df2 = pd.read_csv(all_dirs[counter+1] +'/'+ now_file)
	df = pd.concat([df1,df2])
	df.to_csv(main_dir + '/' + now_file)
```

## 解説
**事前知識**
**```pandas```の動作に関して**
->[[Python] 複数のcsvファイルを結合する方法: 外部サイト](https://hack-le.com/pandas-append/)

**```os.walk```について**
->[os.walkを使ってディレクトリ走査: 外部サイト](https://www.sejuku.net/blog/63816)

**```.append```について**
->[Pythonでリスト（配列）に要素を追加するappend, extend, insert](https://note.nkmk.me/python-list-append-extend-insert/)

```python:combi_csv_with_comment.py
import pandas as pd
import os

print("パスを入力")
main_dir = input()
#走査したいディレクトリを習得する。

all_dirs=[]
#スコープで消えてしまうので、外で定義。
for curDir, dirs, files in os.walk(main_dir):
#指定したディレクトリを走査する。
	for now_dir in dirs:
		all_dirs.append(now_dir)
#ここで配下のディレクトリを空のリストにアペンドすることで、ディレクトリが入ったリスト(all_dir)を作成する。

all_files=[]
#スコープで消えてしまうので、外で定義。
for curDir, dirs, files in os.walk(all_dirs[0]):
#ファイル名の入ったリストを作成するが、ファイル名が同じなので一つのディレクトリだけを見れば十分。
	for file in files:
		all_files.append(os.path.join(file))
#ここで配下のディレクトリを空のリストにアペンドすることで、ファイル名が入ったリスト(all_files)を作成する。

counter=0
for now_file in all_files:
	df1 = pd.read_csv(all_dirs[counter] +'/'+ now_file)
#獲得してきた0番目のディレクトリとファイル名を組み合わせることで、パスを作成し、csvとしてdf1に読み込む。
	df2 = pd.read_csv(all_dirs[counter+1] +'/'+ now_file)
#獲得してきた1番目のディレクトリとファイル名を組み合わせることで、パスを作成し、csvとしてdf2に読み込む。
	df = pd.concat([df1,df2])
#df1とdf2をconcatで結合してdfに入れる。
    df.to_csv(main_dir+'/'+now_file)
#dfを元のディレクトリをファイル名を組み合わせて、新規ファイルのパスを決めて、出力する。
```
ホバーで画像を変える

##ホバーでイメージタグの画像を変える


```jquery:jquery
var iniSrc = $("#targetOne").attr("src");
$(".target").hover(
    function () {
        var dataSrc = $(this).attr("data-src");
        $("#targetOne").attr("src", dataSrc);
    },
    function () {
        var dataSrc = $(this).attr("data-src");
        $("#targetOne").attr("src", iniSrc);
    }
);

```


いろんなやり方があるとは思いますが、
jqueryでsrcを書き換えるやり方



ーーーーーーーーーーーーーーーーーーーーーーーーーーーー

参考にしました


https://www.sejuku.net/blog/40005


https://into-the-program.com/attr-img-src/
VBA 特定処理の自動化サブルーチン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637823/cfa9cf6a-e5d2-8a47-55b9-2eda55dcfe3f.png)


```vb
Option Explicit
Sub main()
  Dim tW As Worksheet
  Dim keyword As Range
  Dim keywordRow As Long
  Dim keywordCol As Long
  Dim testRow As Long
  Dim testCol As Long
  Dim processValue As Range
  Dim testRange As Range
  Dim processRange As Range
  Dim processRow As Long
  Dim i As Variant
  
  Set tW = ThisWorkbook.Worksheets(1)
  Set keyword = ActiveCell
  Set processValue = tW.Range("B2")
  keywordRow = keyword.Row
  keywordCol = keyword.Column
     
  'キーワード確認
  Call checkKeyword(keyword)
    
  processRow = tW.Range("B1")
  testRow = keywordRow
  testCol = keywordCol
  Set testRange = Cells(testRow, testCol)
  
  For i = keywordCol To endCol(keywordRow)
     Set testRange = Cells(testRow, testCol)
     
     '処理内容の実行
     If testRange = keyword Then
        Set processRange = Cells(processRow, testCol)
        processRange.Select
        Call selectProcess(processValue)

     End If
     
     testCol = testCol + 1
  Next
    
    Call postingValue(True)
  
End Sub
```
```vb
Function endCol(keywordRow As Long) As Long

  endCol = Cells(keywordRow, 10000).End(xlToLeft).Column

End Function
Function endRow(keywordCol As Long) As Long
  Dim tW As Worksheet
  Set tW = ThisWorkbook.Worksheets(1)
  
  endRow = tW.Cells(10000, keywordCol).End(xlUp).Row

End Function
```
```vb
Function checkKeyword(keyword As Range)
  Dim answer As Long
  
    answer = MsgBox("キーワードは「" & keyword & "」でよろしいですか？", vbYesNo, "確認")
    If answer = 6 Then
    Else
      'MsgBox "処理を中断します"
    End
    End If
    
End Function
```
```vb
Function selectProcess(processValue As Range)
  Select Case True
    Case processValue Like "*赤*"
      Call drawRed
    Case processValue Like "*オレンジ*"
      Call drawOrenge
    Case processValue Like "*転記*"
      Call postingValue(False)
  End Select
  
End Function
```
```vb
Function drawRed()
  With Selection.Interior
    .Pattern = xlSolid
    .PatternColorIndex = xlAutomatic
    .Color = 255
    .TintAndShade = 0
    .PatternTintAndShade = 0
  End With
End Function
```
```vb
Function drawOrenge()
 With Selection.Interior
  .Pattern = xlSolid
  .PatternColorIndex = xlAutomatic
  .ThemeColor = xlThemeColorAccent4
  .TintAndShade = 0
  .PatternTintAndShade = 0
  End With
End Function
```
```vb
Function postingValue(fin As Boolean)
  Static dataCount As Long
  Dim tW As Worksheet
  Dim endDataRow As Long
  Dim endDataCol As Long
  Dim postingData As Range
  Set tW = ThisWorkbook.Worksheets(1)
  endDataCol = tW.Cells(5, 100).End(xlToLeft).Column
  endDataRow = endRow(1)
  
  dataCount = dataCount + 1
  
  Set postingData = tW.Range(tW.Cells(5, dataCount), tW.Cells(endDataRow, dataCount))
  
  
  If fin = False Then
    postingData.Copy Selection
  
  Else
    dataCount = 0
  End If
    Debug.Print dataCount

End Function

```
ラズパイ4を5GHzのWiFi APとして起動する

# 環境
- Raspberry P 4B 8GB

# 目標
- 802.11ac 5GHzで起動する
- 80MHz (433Mbps)の帯域

# 制限
- ルーティングやブリッジの設定は行っていないので外部ネットワークにアクセスはできません

# 注意
JPの国コードでは指定できない設定を行うため日本の屋外では使用しないこと。

# 手順
APソフトウェアのインストール

``` 
$ sudo apt-get install hostapd
``` 

AP機能の有効化とブート後の自動起動

```
$ sudo systemctl unmask hostapd
$ sudo systemctl enable hostapd
```

DNSサーバー兼DHCPサーバーのインストール

```
$ sudo apt-get install dnsmasq
```

ファイヤーフォール設定を保存してブート後に設定を適用するようにする

```
$ sudo DEBIAN_FRONTEND=noninteractive apt install -y netfilter-persistent iptables-persistent
```

Wi-FiインターフェースのIPアドレス設定

```
$ sudo vi /etc/dhcpcd.conf
```
```diff:/etc/dhcpcd.conf
+ interface wlan0
+    static ip_address=192.168.1.1/24
+    nohook wpa_supplicant
```

DHCPサーバーの設定

```
$ sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig
$ sudo vi /etc/dnsmasq.conf
```
```diff:/etc/dnsmasq.conf
+ dhcp-range=192.168.1.2,192.168.1.20,255.255.255.0,24h
+ domain=wlan
+ address=/gw.wlan/192.168.1.1
```

APの設定

```
$ sudo vi /etc/hostapd/hostapd.conf
```
```diff:/etc/hostapd/hostapd.conf
# 使用するインターフェース名
interface=wlan0

# ドライバインターフェースタイプ (hostap/wired/none/nl80211/bsd)
# デフォルトはhostap
# nl80211はLinux mac80211ドライバで使われている。
driver=nl80211

## 802.11関連の設定

# WiFiのSSID名（自由に変更する）
ssid=raspi-ap

# 国コード
# この値によってその国の無線規制に合った機能の制限が行われる
# 例えば使用できるチャネルや出力電力が制限される。
country_code=US

# 国コードにや使用できるチャネル、出力電力をアドバタイズする。
# デフォルト: 0
ieee80211d=0

# レーダー検知とDFSサポートを有効化する
# ほとんどの国では屋外での5GHz帯の利用にDFSサポートが必要
# この機能を有効化するにはieee80211dが有効化されている必要がある
# デフォルト: 0
ieee80211h=0

# 動作モード (a = IEEE 802.11a (5 GHz), b = IEEE 802.11b (2.4 GHz),
# g = IEEE 802.11g (2.4 GHz), ad = IEEE 802.11ad (60 GHz))
# IEEE 802.11n (HT)はa/gオプションを使用
# IEEE 802.11ac (VHT)はaオプションを使用
# IEEE 802.11ax (HE)の6 GHzはaオプションを使用
hw_mode=a

# 使用するチャネル番号
# 2.4GHzでは1-13
# 5GHzではW52(36-48), W53(52-64), W56(100-104)
# W53とW56はDFSとTPCのサポートが必要
# ラズパイではW52しかサポートしていないので36か44だけが選択可能
# 帯域80MHzを使う場合は36しか選べない
channel=36

# 認証アルドリズム
# 0: 認証なし, 1: WPA, 2: WEP, 3: WPA&WEP
auth_algs=1

## 11nの設定(11acを使うにあたってこれは省略できない)

ieee80211n=1
require_ht=1
ht_capab=[MAX-AMSDU-3839][HT40+][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40]

## 11acの設定

# 11acの有効化
ieee80211ac=1

# [MAX-AMSDU-3839]: 
# [SHORT-GI-80]: 80GHzショートGI
vht_capab=[MAX-AMSDU-3839][SHORT-GI-80]

# ステーション側が11acをサポートしていなければ接続を拒否する
require_vht=1

# チャネル幅
# 0: 20/40 MHz
# 1: 80 MHz
# 2: 160 MHz
# 3: 80+80 MHz
vht_oper_chwidth=1

# 中心周波数
# 5Ghz+(5*index)
# channel+6を指定すればいいらしい
vht_oper_centr_freq_seg0_idx=42

## WPA/80211i設定

# 1:WPA, 2:WPA2 (11i/RSN)
wpa=2

# wpa-pskのパスフレーズ (自由に変更する)
wpa_passphrase=12345678

# WPA-PSK: WPA-Personal/WPA2-Personal
wpa_key_mgmt=WPA-PSK

# RSN/WPA2用サイファースイート
# CCMP: AES with 128ビットCBC-MAC
# TKIP: TKIP
# CCMP-256: AES with 256ビットCBC-MAC
rsn_pairwise=CCMP
```

再起動してWi-Fiが立ち上がっていれば成功

```
sudo reboot
```


# 参考サイト
https://www.raspberrypi.org/documentation/computers/configuration.html#setting-up-a-routed-wireless-access-point

https://w1.fi/cgit/hostap/plain/hostapd/hostapd.conf

http://jotmemo.blog65.fc2.com/blog-entry-41.html

https://www.raspberrypi.org/forums/viewtopic.php?t=265646
SIGNATEの【練習問題】”天秤のバランス分類”をやってみた


###必要なライブラリのインポート
```python
#必要なライブラリのインポート
import pandas as pd
```

###ファイル取得
訓練データと検証データをそれぞれ読み取る。

```python
#訓練データはtrain,検証データはtest
train = pd.read_table('train.tsv', index_col=0)
test = pd.read_table('test.tsv')
```

testは後々の操作のためにindex_colを設定していない。

  
     
### データ形式の確認
##### train
![SS 2021-10-01 0.19.52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551936/56c629db-8839-0cb8-933f-e7131f3e274e.jpeg)

##### test
![SS 2021-10-01 0.22.39.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551936/0cc9eac5-d4f5-707c-0ddf-38e9138157c3.jpeg)

### 分類用の関数を作成
(距離)×(重さ)が左右のどちらに寄っているか、で分類した。平衡は”1”、左は”0”、右は”2”。

```python
def position_judge(l_weight,l_distance,r_weight,r_distance,results_list):
    left = l_weight*l_distance
    right = r_weight*r_distance
    #平衡
    if left == right:
        results_list.append(int(1))
        pass
    #左
    elif left > right:
        results_list.append(int(0))
        pass
    #右
    elif right > left:
        results_list.append(int(2))
        pass
```

### 結果をリストに格納

```python
# print(train.iloc[c]["left_distance"])
results = []
for c in range(len(test)):
    position_judge(test.iloc[c]["left_weight"],test.iloc[c]["left_distance"],test.iloc[c]["right_weight"],test.iloc[c]["right_distance"],results)

```

### idと結果をまとめて1つのDataFrameにする
```python
#結果リストをDataGrame型に変換
df_result = pd.DataFrame(results)
#testのid
zero_index = pd.DataFrame(test.iloc[:,0])

#idと結果を一つのDataFrameにして、カラム名を整理
df_results = pd.concat([zero_index,df_result],axis = 1)
df_results = df_results.rename(columns={0:1,'Unnamed: 0': 0})

```


#### 結果をcsvファイルに出力
```python
df_results.to_csv('results.csv',index = False,header = False)
```
　　

　　
結果は評価関数Accuracyで1.0000000でした。
『HAKOGAKI』プロットと本文を同時に書けるアプリを作りました。

# はじめに
小説や脚本を書くときプロットを作る人は多いと思いますが、以下のような悩みはないでしょうか？

- プロットと本文を同時見たい。。。
- プロットと本文を１つのファイルで管理したい。。。
- 本文書いてたらプロットも直したくなる。。。

自分はこの悩みを感じていました。
ツールを探してみたのですが、機能が違ったり、リッチすぎたり、ぴったりはまるものが見つかりませんでした。
そこで、HAKOGAKIというアプリを作りました！

[HAKOGAKI](https://hakogaki.vercel.app/)
※ 現在はPCでの利用を想定していて、スマホだと見にくいと思います

# サービス概要
HAKOGAKIには
- シナリオモード
- プロットモード
の２つのモードがあります。

## シナリオモード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362731/4a3af8ba-792d-2d7b-aee9-1f7f3d056ba4.png)


主に本文を書くためのモードです。
段落ごとに分かれていて、段落内には
- 段落タイトル
- 本文
- Todo
- メモ
があります。

本文を書きながら、Todoを完了させて、気になったところをメモに残して・・・みたいな使い方ができます。段落やTodoは好きなだけ追加できますし、本文やメモのスペースは伸縮できます。

上の「シナリオ」というボタンを押すとプロットモードに切り替わります。

## プロットモード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362731/0f3f571b-bb98-736f-76d5-031cdc60f5a0.png)


全体構成を作るためのモードです。

データはシナリオモードと同期していますので、段落構成、段落タイトル、Todo、メモは同じものが表示されますし、編集したらシナリオモードに反映されます。

プロットモードは
- 全体メモ
- 段落
の２つが表示されています。
シナリオモードと違い段落には段落タイトル、Todo、メモだけ表示していて一覧性を高めています。

# こだわったポイント
- データの保存方法
- 進捗機能
- シンプルさ

### データの保存方法
3種類のデータ保存があります。
1. プロジェクトとして保存（ファイル）
2. 作品として保存（ファイル）
3. ブラウザに自動保存

#### 1. プロジェクトとして保存（ファイル）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362731/b82cc809-8c8e-4882-6278-19811f7b13a1.png)
右上のフロッピーアイコンから、作品タイトル、段落を全部そのままファイルにしてダウンロードできます。保存したファイルは左のアップロードアイコンから読み込めます。

#### 2. 作品として保存（ファイル）
作品タイトル、段落タイトル、本文をまとめてファイルにしてダウンロードします。作品が完成したときに使ってください。

#### 3. ブラウザに自動保存
１つ目の「プロジェクトとして保存」と同じ情報をブラウザに自動しています。
次にHAKOGAKIを使うとき、前回の最後の状態がロードされます。

### 進捗機能
段落とTodoには完了のチェックボックスがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362731/a03970cd-3cb6-9be9-9b42-a865f5564c46.png)

そして、プロジェクトとして保存したときに、書き始めたときからの進捗をお知らせします。
進捗として計測しているのは、完了させた段落、Todo、書いた文字数です。
小さな達成感を感じられ、書き続けるモチベーションになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362731/e2c1c08e-24ca-196d-3d60-c93109d684f1.png)

### シンプルさ
全体のUIをシンプルにすることを心がけています。
今まで説明を書いてきましたが、ほとんど直感的に扱えると思います。

# 技術的なお話
現在はクライアントサイドで完結しているアプリで非常にシンプルです。
個人的には、React, Next.jsでの開発が初めてで戸惑うところもありましたが、特別なことはあまりないかなと思います。アプリの公開はVercelを利用しています。

ざっと主要な技術を上げると、以下の通りです。
* React
* Next.js
* Redux Toolkit
* Typescript
* MUI
* styled-components
* Google Analytics
* Jest
* sinon
* Vercel

開発期間は、一ヶ月程度かなと思います。
（間が空いているので正確ではないですが・・・）

# おわりに
まだまだスタートラインに立ったアプリです。今後、いろいろな機能を作っていきたいと考えています。現在、自分の頭にあるものだと
- 作品出力時のカスタマイズ
- undo/redo機能
- スマホ対応
- サーバへのデータ保存
- 履歴保存
とか便利かなあと考えています。

たくさん使って、たくさんフィードバックを頂けると嬉しいです！
（右上アイコンの「ヘルプ」 -> 「お問い合わせ」からどうぞ）

最後までご覧いただき、ありがとうございました！
OFDMA とは(わからないなりに調べてみた)

## 勉強前イメージ

wifi6で見たけど、混信しないような仕組み？方法？

## 調査

### OFDMA とは

Orthogonal Frequency Division Multiple Access の略で、
日本語では 直交周波数分割多元接続 と呼びます。

従来のOFDM(直交周波数分割多重)を複数ユーザによってアクセス出来るようにする方式のことです。

・・・よくわからないのですが、、、、

元々 FDM(周波数分割多重化) という
2種類以上の情報をそれぞれの周波数によって情報の種類を区別するやり方があります。

そして、その次に
FDMA(周波数分割多重化) という
`多対1の接続(多元接続)` において周波数によって情報の種類を区別するやり方があります。
FDMの多元接続バージョンです。

そしてそして、その次に
OFDM(直交周波数分割多重) という
周波数によって情報の種類を区別する、情報を電波に乗せる際のやり方の一つです。
FDMの直交バージョン。パワーアップ版

そしてそして、その次に
OFDMA(直交周波数分割多元接続) という
同じ電波を使った、多対1の接続(多元接続)において
周波数によって情報の種類を区別するやり方になります。
OFDM と FDMA が合わさったようなやつ。
従来のOFDMより小さい2MHzを最小単位で異なる周波数で同時に通信できるので、
多くのデバイスが同時に接続できます。

## 勉強後イメージ

結構いろいろ調べたけど、↑がわかっただけだった・・・
そもそも周波数とかの話を理解しないとあまり進まない気がする。
元々のFDMを次は調べてみよう。
こういうのがあるんだなーくらいに知っておく。。。
難しすぎた

## 参考

- [周波数分割多重化 (FDM)](https://wa3.i-3-i.info/word13224.html)
- [周波数分割多元接続 (FDMA)](https://wa3.i-3-i.info/word13233.html)
- [直交周波数分割多重 (OFDM)](https://wa3.i-3-i.info/word13236.html)
- [直交周波数分割多元接続 (OFDMA)](https://wa3.i-3-i.info/word13237.html)
Ruby　gemとは何なのか？

## はじめに

ruby on railsで開発していて、gemについて改めて理解しようと記事にしました。

##gemとは？
rubyのライブラリを指す。
ライブラリが存在することで「車輪の再開発」を防ぎ、効率的な開発が可能になります。
ruby以外のプログラミング言語にもライブラリが存在しており、フロントエンド界隈で有名なj-queryもJavaScriptのライブラリです。

##そもそもライブラリとは？

>ライブラリとは、プログラム言語において、ある特定の機能を持つプログラムを定型化して、他のプログラムが引用できる状態にしたものを、複数集めてまとめたファイルのことである。

https://www.sophia-it.com/content/%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA

こちらのページから引用させていただきました。

同じ様な機能は一つの部品にまとめておいて、使う時に引用すれば楽じゃね？ということ。
ライブラリをそのまま使用することで一からプログラミングする必要がなくなり、スピード感のある開発が可能になる。

##改めてgemへの説明に戻ります
gemfileのほとんどはRubyGems.orgにあります。

https://rubygems.org/

上のサイトでgemを探すにはgem searchと入力して検索することでリポジトリを検索することができる。

またGitHubにもGemfileのリポジトリとしても使用されています。

gemをインストールするには

```
gem install ライブラリ
```

gem installコマンドを使用します。


##bundler  --gemを管理するためのgem 

bundlerはgemとgemが正常に機能するように管理を行なってくれるgemです。

bundlerがないと、他のgemと互換性の持たないgemがインストールされる事態も生じ、gemが正常に動作しなくなる場合がある。


###参考


[ライブラリ? gem? bundler? -- Rubyのgem管理に関するあれこれまとめ](https://qiita.com/3no3_tw/items/8c1e3e95c75edae1036d )

[RubyGems.org](https://rubygems.org/)

[ライブラリ - Ruby](https://www.ruby-lang.org/ja/libraries/)