OmniAICreator/Qiita-1.07M huggingface dataset:
JavaScriptのクイズの選択ボタンのプログラムと説明

ブログの知識と教養と雑学の百問、[前半（芸能と文学と芸術と時事と自然）](https://www.nagahitoyuki.com/2022/07/the-first-half-of-a-hundred-questions-of-knowledge-education-and-trivia.html)と[後半（歴史とITと健康とスポーツと生活）](https://www.nagahitoyuki.com/2022/07/the-last-half-of-a-hundred-questions-of-knowledge-education-and-trivia.html)でクイズ形式の三択ボタンをJavaScriptで作成したときのプログラムの内容を説明する。
![正解の緑が一つと誤解の赤が二つの三択ボタン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747915/9735e97f-6e38-77f7-4508-79f011ef943b.jpeg)
```JavaScript:JavaScript
// 誤解数と正解数の変数の宣言
let now = 0, noc = 0;
// 全てのクイズのol要素と最終結果のp要素の取得
const slbtns = document.querySelectorAll("ol.selection"), fnrs = document.querySelector("p.final-result");
// 最終結果のp要素にCSSでデザインを付ける
fnrs.style.cssText = "display:flex;justify-content:center;align-items:center;fonts-size:x-large;font-weight:bold;height:3em;";
// クイズ毎の正誤の判定の関数
function check(event) {
// クリックイベントとクリックされたボタンと同じクイズの残りのボタンのli要素の取得（クイズを三択ボタンのどれかが押されたときに終了させるため）
const et = event.target, aits = et.parentElement.querySelectorAll("li");
// クリックされたボタンと同じクイズの残りのボタンのli要素の配列処理
aits.forEach(ait => {
// 正解のボタンの場合
if (ait.classList.contains("correct")) {
// ボタンの背景色を「#00ff7f」に変えて前方に「正解」と追記する
ait.style.backgroundColor = "#00ff7f"; ait.insertAdjacentHTML("afterbegin", "正解　"); }
// 誤解のボタンの場合
else {
// ボタンの背景色を「#ff6347」に変えて前方に「誤解」と追記する
ait.style.backgroundColor = "#ff6347"; ait.insertAdjacentHTML("afterbegin", "誤解　"); }
// ボタンのクリックのイベントリスナーを終了する
ait.removeEventListener("click", check); });
// クリックされたボタンの後方に「✓」を追記する
et.insertAdjacentHTML("beforeend", "　✓");
// クリックされたボタンが正解か誤解かを数える
if (et.classList.contains("correct")) ++noc; else ++ now;
// 正解と誤解の合計がクイズの数と同じ（全てのクイズが解答された）場合
if (slbtns.length === noc + now) {
// 最終結果に正解数を表示する
fnrs.firstElementChild.textContent = noc; }}
// 全てのクイズの配列処理
slbtns.forEach(slbtn => {
// クイズのol要素にCSSでデザインを付ける
slbtn.style.cssText = "padding-left:0;list-style-type:none;width:80%;margin:auto;text-align:center;border:2px #c0c0c0 solid;border-radius:4px;";
// 三択ボタンのli要素の取得
const items = slbtn.querySelectorAll("li");
// 三択ボタンのli要素の配列処理
items.forEach(item => {
// 三択ボタンのli要素にCSSでデザインを付ける
item.style.cssText = "padding:.5em;transition:all .3s ease-out;"; 
// 三択ボタンの三番目だけCSSでデザインを付ける
if (item.nextElementSibling) item.style.borderBottom = "2px #c0c0c0 solid";
// ボタンのli要素のクリックのイベントリスナーの設置
item.addEventListener ("click", check); }); });
```
出典：[JavaScriptのクイズの選択ボタンのプログラム](https://www.nagahitoyuki.com/2022/07/javascript-quiz-selection-button-program.html)
three.jsでverticesを更新しても一回しかされなかったり、見る角度によって表示されなくなったりしたけど直った

three.js r69,r70でのはなし　
（※はてブからの移植 https://fkef.hatenablog.com/entry/2015/03/10/014318 ）

---

# 頂点編集が反映されなかった話

物のpositionを変えるのはNeedUpdateなどしなくても問題なく反映されるが、
vertices(頂点)座標を更新するときには毎回`geometry.verticesNeedUpdate = true`をかまさないと アニメーション`render()`ごとにフラグがもと(`false`)に戻ってしまうらしい

booleanだからなんかずっとupdateしてくれるもんかとおもってたけど違うのね

[verticesneedupdate - Google 検索](https://www.google.co.jp/search?q=verticesneedupdate)
[javascript - ThreeJS Dynamic Line Change - Stack Overflow](https://stackoverflow.com/questions/18814177/threejs-dynamic-line-change)

その他geometry関係のパラメータを変えた場合には毎回対応したneedupdateをtrueにしてあげないといけないのか、なるほど

---

# それでもカメラアングルによって見えないときがあった話

もうひとつ、verticesを変更したときになんか見るアングルによって表示されたりしなくなったりして、なんじゃこりゃなんか重なってんのかなこれ…とかいろいろ検証したけど、
結局geometryの`.computeBoundingSphere()`をやっとかなかったので表示判定が前の場所に取り残されていたということでございました

で前にverticesがあった場所が入らないアングルになると表示されなくなる・・というわけだなこんちくしょう！

https://threejs.org/docs/#Reference/Core/Geometry

THREE.Lineでは他の `.computeBoundingBox()`は効かなかったのでlineはSphereで判定しているということだろうか

うーんなおってよかった
Google ColabとGit hubは悪くない組み合わせだ。

## 初めに
どうも、python歴5カ月目でゆくゆくは転職を目指している者です。
今回､google Colabとgit hubがいい感じに連携をとれている事に気が付いたのでシェア致します。少しでも参考になれば幸いです。

### 前提知識
ごく簡単なgit hubについての理解。⇒ 関連記事を参照下さいませ。
git hubのアカウント。https://github.co.jp/


### 関連記事
CUIやgitそのものに馴染みがない方々向けにこのような記事を作成致しました。

- [cmdの簡単なまとめ](https://qiita.com/The_Boys/items/50d608f139e04f157d19)
- [git実装前に確認したい概要や用語](https://qiita.com/The_Boys/private/cfdb09f7ceead0d9bd6f)
- [gitの実装](https://qiita.com/The_Boys/private/aa85e1d6d107b5802f73)

## 本編

### colabから直接GithubにPushしたい。
この画像の通りです。

![2022-08-29_14h39_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2719278/94800f43-4553-c1f3-c8a5-ccd47850417b.png)

![2022-08-29_14h40_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2719278/a50d5c84-c0ae-1a45-379d-0d5e24f77d01.png)

これでこんな感じに簡単にpushする事が出来るわけです。
入れ物(レポジトリ)はgit hubの方から作成してくださいね。

![2022-08-29_14h44_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2719278/9a451f1f-6ebe-de17-14b3-b7c6527f99d8.png)

### Githubに挙げたcolabのipynbを編集して保存したい。
上記の手順で無事colabを保存する事が出来ましたと。
しかしそれを編集する事もありますよね。これも凄く簡単なのです。

![2022-08-29_14h50_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2719278/704be687-6e9f-26ed-385e-98910c7ee558.png)
これでしばらく待ちます。1~2分位。
そしたらこのようなVSコードチックな画面に映ります。そして下記の操作。これはVS codeとgit hubの連携と一緒。


![2022-08-29_14h54_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2719278/21cb9d3f-c3ac-1b7a-e4e7-401d674b38b1.png)

![2022-08-29_14h57_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2719278/696ac2d2-f849-23fb-d455-683e0fd30fd8.png)

そうしましたら確認して完了です。

![2022-08-29_15h01_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2719278/c9dc8d62-924c-29a8-239b-c68e9b36f5af.png)

### 終わりに

かなり楽ちんでしょう。git hubに保存して何が嬉しいの？という方は是非関連記事を訪れて頂けると嬉しいです。
僕の場合はqiita等で他人にコードシェアするときは多用しておりますね。
AWS Lambda を時刻起動する

EventBridgeの時刻起動ルールを作成して、指定時刻にAWS Lambdaを起動する方法を解説します。

## Lambda関数のアクセス権限を設定する

EventBridgeからLambda関数を起動できるよう、アクセス権限を設定します。

- [設定]から[アクセス権限]を選択します。

![image](https://user-images.githubusercontent.com/38905609/187126403-5a8ef77e-653d-4513-9d22-b136be7c2a3d.png)

- [アクセス権限を追加]を選択します。

![image](https://user-images.githubusercontent.com/38905609/187126658-ebfdeaea-677f-4eca-af19-14645c9b3346.png)

- ポリシーステートメントを指定します。

1. [AWS]のサービスを選択
1. サービスに[EventBridge]を選択
1. ステートメントIDは任意のIDを指定
1. プリンシパルは初期表示値を指定
1. ソースARNは[arn:aws:events:リージョンID:アカウントID:rule/*]を指定
1. アクションは[lambda:InvokeFunction]を指定

![image](https://user-images.githubusercontent.com/38905609/187127695-605e0e2a-9044-4f6b-9b37-fed7dd29f76e.png)

## イベントルールを作成し、Lambda関数へターゲットを設定する

以下の順でイベントルールを作成し、Lambda関数へターゲットを設定します。

1. cron形式で起動時刻を定義する（ここで指定する時刻は協定世界時[UTC]です。）
1. イベントルールを作成する
1. イベントのターゲットにLambda関数を設定する

```python
import os
import boto3
import json
from datetime import timezone,timedelta,datetime

def main_logic():
    event_name = "event-sample"
    
    JST = timezone(timedelta(hours=+9), 'JST')
    now = datetime.now(JST)
    # ３分後を起動時刻に設定
    target_time = now + timedelta(minutes=+3)
    # cron時刻表現を作成([UTC]で指定)
    cron_expression = "cron(" + target_time.astimezone(timezone.utc).strftime("%M %H %d %m ? %Y") + ")"
    
    events_client = boto3.client('events')
    response = events_client.put_rule(
        Name=event_name,
        ScheduleExpression=cron_expression,
    )

    param = {}
    
    response = events_client.put_targets(
        Rule=event_name,
        Targets=[
            {
                'Id': "sample-lambda-func",
                'Arn': "arn:aws:lambda:ap-southeast-1:xxxxxxxxxxxxx:function:sample-lambda-func",
                'Input': json.dumps(param)
            }
        ]
    )

```

## 👇参考URL

- <https://boto3.amazonaws.com/v1/documentation/api/1.9.42/reference/services/events.html#CloudWatchEvents.Client.put_rule>
- <https://boto3.amazonaws.com/v1/documentation/api/1.9.42/reference/services/events.html#CloudWatchEvents.Client.put_targets>
- <https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/access-control-resource-based.html>
vimでコピペする時によく使うコマンド


### オートインデントのON/OFF
コピペした時に、がーっとインデントされてどんどん右にズレちゃうのを防ぐ／いつも通りにインデントさせる

```
:set noai
```

```
:set ai
```

### 行番号のON/OFF

行番号があると複数行のコピペが邪魔になる時があるので、行番号の表示は切り替えたい


```
:set nu
```
Javaでファイルを新規作成し処理する。

## 流れ
ファイル作成をする時、同名のファイルが存在することがあるので、それを考慮した流れになっています。

1. ファイル取得
2. ファイルが無ければ作成。既にあれば、処理へ。
3. 処理

## 説明
### ファイル取得
Fileクラスのコンストラクタにパス名を渡して、任意のファイルをFileオブジェクトに変換します。
```java
    String fileName = "任意のファイル名";

    //保存場所を指定している
    String uri = "dir/"+fileName;

    //ファイル作成のためのPathオブジェクトを作成
    Path path = Paths.get(uri);

    //ファイル参照
    File file = new File(uri);
```

### ファイル作成
```java
	try {
            //ファイルの新規作成
            Files.createFile(path);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
```
すでに同名のファイルが存在していた場合について処理を分岐させています。

ランタイムエラーになるので、必要に応じてtry/catch文を記述します。
```java
	if(!(file.exists())){
            try {
                //ファイルの新規作成
                Files.createFile(path);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

```

https://www.javadrive.jp/start/file/index4.html
### 処理
以下、任意の処理を記述します。

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

<br>
<br>
<br>

以上です。

## 参考文献
https://docs.oracle.com/javase/jp/8/docs/api/java/io/File.html#exists--
私のソフトウェア品質強化活動について

## 初めに

私はSESで、お客様の保守チームに参画し、ソフトウェア開発の品質強化のお手伝いをさせていただいております。主な活動内容は下記3つです。
それぞれの活動で行っていることを備忘も兼ねて書いていきたいと思います。

1. 第三者レビュー
1. 開発ドキュメントに対する対策検討・実施
1. 開発プロセスの改善

## 1. 第三者レビュー
開発ドキュメントに対して第三者としてレビューを行っています。
またレビュー結果を分析し、2. 開発ドキュメントに対する対策検討・実施や3. 開発プロセスの改善に繋げております。

例えば、要件漏れや設計漏れが多い場合は設計書に対して曖昧な記載をさせないように物理名と論理名を必ずセットで記載してもらうようにしたり、デシジョンテーブルを作成してもらうようにしています。

第三者レビューは案件参画時から積極的に参加することをお勧めします。なぜならプロジェクトの状態が良く見えるからです。ドキュメントのフォーマットが定まってない、誤字脱字が多い、なんとなくドキュメントを作成してるだけというのは第三者レビューを行えばすぐにわかります。

## 2.開発ドキュメントに対する対策検討・実施
第三者レビューの結果や不具合管理票の分析から当プロジェクトに対して何を行えばいいかを検討します。
要件漏れや設計漏れが多い場合は、上位工程に対して対策を検討したり、単体テスト時の不具合が多かったり、コーディングミスによる不具合が多い場合は、下位工程に対する対策を検討したりしています。

対策内容が決まれば、今度はその対策をメンバーに実施してもらわないといけないので説明用の資料を作成します。要領の良い人は、文章だけでも理解してくれますが、そういう人だけではないのが会社と言うものです。
サンプルを用意し、理解してもらえるようにする必要があります。

また、1回伝えただけではダメです。必ず忘れる人がいます。ここは根気強くいかないといけません。


## 3. 開発プロセスの改善
ウォーターフォール開発をしているのですが、必要な工程を行わずに進める人がいます。
単純にプロセスを知らない人もいれば、時間がないのを言い訳に独断で単体テストをすっ飛ばしてシステムテストでの不具合が収束せずに大炎上と言うこともあります。

そこでルールを作成し、ドキュメント化やルールの説明、ルールが守られているかのチェックポイントについても検討・実施をしております。

## 最後に
今、品質強化活動を行っていて感じるのは、「自分の常識は他人の非常識」と言うことです。
例えば私は単体テスト仕様のインプットとして詳細設計書とソースコードを使いますが、人によって（現場によって）は詳細設計書しか使わなかったり、要件確認書のみをインプットにする人（現場）もあります。

何が良いかは現場によって異なるので、私の常識を人に押し付けるのも良くありません。
現場の状況を考慮したうえで最適な対策を考える必要があります。

また、品質担当者（QAエンジニア）だけが品質対策を行っても効果は薄いです。
開発者はもちろん、管理者、顧客、ユーザーの全員が協力しないと良いものはできません。

今後も周りの人を巻き込んで、世の中からくだらない障害を取り除くお手伝いが出来れば幸いです。
【PHP】implementsとextendsの違い

implementsってなんぞや？extendsしか知らんぞ？ってなったので調べてみました。

## TL;DR
* implementsはインターフェイスを使いたい時の演算子
* extendsはオブジェクトを継承したい時の演算子

## implements
implementsはインターフェイスを使いたい時の演算子です。

https://www.php.net/manual/ja/language.oop5.interfaces.php

### インターフェイスとは？
> クラスが実装する必要があるメソッドを指定するコード

そのクラスに実装しないといけないメソッドをまとめた、パッケージみたいなものです。
複数のファイル（クラス）を作成する際に、決まったメソッドを実装してほしい時に使えます。

#### 例）
##### ▼インターフェイス
```php
<?php

interface Template
{
    public function setVariable($name, $var);
    public function getHtml($template);
}
   
```

##### ▼インターフェイスに則ったクラス
インターフェイスで定義している `setVariable` と `getHtml` を実装している。
```php
<?php

class Hoge implements Template
{
    public function setVariable($name, $var)
    {
       // メソッドの中身 
    }
  
    public function getHtml($template)
    {
        // メソッドの中身
    }
}
```

##### ▼動かないクラス
インターフェイスを使っているのに、インターフェイスで定義しているメソッドを全て実装していない。
```php
<?php

class Fuga implements Template
{
    public function setVariable($name, $var)
    {
       // メソッドの中身 
    }
}
```

## extends
オブジェクトを継承したい時の演算子です。

https://www.php.net/manual/ja/language.oop5.inheritance.php

### 継承とは？
* extendsしたオブジェクトで定義しているメソッドを使える
* extendsしたオブジェクトで定義しているメソッドの中身を上書きして使える

#### 例）
##### ▼継承元のオブジェクト
```php
<?php

class Foo
{
    public function printItem($string)
    {
        echo 'Foo: ' . $string . PHP_EOL;
    }
}
```

##### ▼継承したメソッドをそのまま使う場合
```php
<?php

class Bar extends Foo
{
    public function printItems($arr)
    {
        foreach ($arr as $item)
        {
            echo printItem($item);
        }
    }
}
```

```php
<?php

$bar = new Bar();
$arr = ["hoge", "fuga"];
$bar->printItems($arr);
```
結果
```
'Foo: hoge'
'Foo: fuga'
```

##### ▼継承したメソッドを上書きする場合
```php
<?php

class Bar extends Foo
{
    public function printItem($string)
    {
        echo 'Bar: ' . $string . PHP_EOL;
    }
}
```

```php
<?php

$bar = new Bar();
$bar->printItem("hoge");
```
結果
```
'Bar: hoge'
```
CloudFront CloudFrontFunctions  を使って許可されたIP以外は特定のURL（エラーページ）にリダイレクトさせる

## 問題点
CloudFrontFunctionsを使って、許可されたIP以外からのアクセスがあった場合は、
特定のページにリダイレクトしたい。
という処理は以下のような内容で実装することができました。

## 解決方法
内容はいたってシンプルで、
elseの中身のstatusCodeを302に設定
↓
headersにリダイレクトしたいURLを設定した変数をセットする
これだけです。

```
function handler(event) {
    var request = event.request;
    var clientIP = event.viewer.ip;
    var IP_ALLOW_LIST = [
     'XX.XXX.XX.XX',
     'XX.XXX.XX.XX',
    ];
    var isPermittedIp = IP_ALLOW_LIST.includes(clientIP);
    var newurl = `https://qiita.com/`
    if (isPermittedIp) {
　　　　// IP_ALLOW_LISTのIPは正常に処理する
        return request;
    } else {
        // IP_ALLOW_LIST以外のIPはQiitaに飛ばす
        var response = {
            statusCode: 302,
            statusDescription: 'Found',
            headers:
              { "location": { "value": newurl } }
        }
        return response;
    }
}
```

## 所感
CloudFrontFunctionsはCFに対して、js処理を手軽に入れることができるため自由度が高く大変便利です。
是非是非皆さんも使ってみてください😊

## 参考資料
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/example-function-redirect-url.html

https://dev.classmethod.jp/articles/cloudfront-functions-ip-control/

## 最後に
いいね！いただけると励みになります👍
KotlinでJavamail4android（添付ファイルを添えて）

# きっかけ
よく使うので備忘録

# Gradle
``` Gradle
    //javamail
    implementation 'com.sun.mail:android-mail:1.6.7'
    implementation 'com.sun.mail:android-activation:1.6.7'
```


# コード
``` kotlin
private fun sendMail(
        smtpServer: String,     //SMTPサーバ
        srcMailAddress: String, //自分のメールアドレス
        password: String,       //メールアドレスのパスワード
        dstMailAddress: String, //相手先のメールアドレス
        displayName: String,    //相手先の表示名
        subject: String,        //メール件名
        body: String,           //メール本文
        attachedPath: String    //添付ファイルのパス
    ) {
        thread {
            val properties = Properties()
            properties["mail.smtp.host"] = smtpServer
            properties["mail.smtp.auth"] = "true"
            properties["mail.smtp.port"] = "465"
            properties["mail.smtp.socketFactory.post"] = "465"
            properties["mail.smtp.socketFactory.class"] = "javax.net.ssl.SSLSocketFactory"
            properties["mail.smtp.connectiontimeout"] = 2000
            properties["mail.smtp.timeout"] = 2000

            val message: MimeMessage =
                MimeMessage(Session.getDefaultInstance(properties, object : Authenticator() {
                    override fun getPasswordAuthentication(): PasswordAuthentication {
                        return PasswordAuthentication(srcMailAddress, password)
                    }
                }))
            message.setFrom(InternetAddress(dstMailAddress, displayName))
            message.setRecipient(
                MimeMessage.RecipientType.TO,
                InternetAddress(dstMailAddress, displayName)
            )
            message.subject = subject

            // 本文
            val multipart = MimeMultipart("mixed")

            // 本文テキスト
            val textPart = MimeBodyPart()
            textPart.setText(body, "UTF-8")

            // 添付ファイル
            val attachedPart = MimeBodyPart()
            val myFile: File = File(attachedPath)
            // 実ファイルを利用する場合は実ファイルでDataSourceを作成
            val dataSource: DataSource = FileDataSource(myFile)
            attachedPart.dataHandler = DataHandler(dataSource)
            attachedPart.fileName = myFile.name

            multipart.addBodyPart(textPart)
            multipart.addBodyPart(attachedPart)

            message.setHeader("X-Mailer", "kotlin de mail ver. 0.9b [ja]")
            message.sentDate = Date()
            message.setContent(multipart)
            Transport.send(message)
        }
    }
```

# メモ
電波悪かったりしたら，エラー吐くので，そのあたりの処理を忘れない。

+ SMTPSendFailedException
+ MessagingException

がよく出ると思います。

# 免責
javaから，AndroidStudioの機能を用いてkotlinへ変換したので，動作保証は致しかねます。
Vue CLIプロジェクトの開発サーバのポート番号を変更する

Vue CLIプロジェクトの開発サーバのポート番号はデフォルトでは"8080"になります。
このポート番号を変更するには、vue.config.jsに開発サーバのポート番号を設定します。

【変更前】
```vue.config.js
const { defineConfig } = require('@vue/cli-service')

module.exports = defineConfig({
  transpileDependencies: true
})
```
【追記情報】8081に指定
```
  devServer: {
    port: 8081,
    host: 'localhost'
  }
```
【変更後】
```vue.config.js
const { defineConfig } = require('@vue/cli-service')

module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port: 8081,
    host: 'localhost'
  }
})
```
![スクリーンショット 2022-08-29 13.25.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223785/4ca4335f-a002-84cd-7b6b-5bb696d9aeed.png)
![スクリーンショット 2022-08-29 13.26.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223785/bceac5cd-861b-3a4f-7e1f-5af988d1ef2f.png)
MinecraftにTwitter4jを読み込ませる時にClassNotFoundExceptionで詰まった話(解決)

# implementationだけだと読み込んでくれないらしい

これだとエラーを吐いた

```gradle build.gradle

dependencies {
    minecraft 'net.minecraftforge:forge:1.19.2-43.1.1'
    implementation group: 'org.twitter4j', name: 'twitter4j-core', version: '4.0.7'
}

```

# 解決策

minecraftLibraryとminecraftEmbedを追加する

```gradle build.gradle
dependencies {
    minecraft 'net.minecraftforge:forge:1.19.2-43.1.1'
    implementation group: 'org.twitter4j', name: 'twitter4j-core', version: '4.0.7'
    minecraftLibrary group: 'org.twitter4j', name: 'twitter4j-core', version: '4.0.7'
    minecraftEmbed group: 'org.twitter4j', name: 'twitter4j-core', version: '4.0.7'
}

```

呼び出す側

```Java
TwitterFactory twitter = new TwitterFactory();
LOGGER.info(twitter.toString());
```

![2022-08-29-01-05-32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1086026/c90c2184-83c5-0684-44fb-e63ccd500083.png)

Twitter4jが使えるようになっている

```build\classpath```をみると```runClient_minecraftClasspath.txt```などのテキストファイルがあってそこでjarを通しているらしい

**一応本番環境でも実行出来たのでヨシ！！！**
Amazon CloudWatch Logsからslackにエラーログを投稿する

# Amazon CloudWatch Logsからslackにエラーログを投稿する

今回は、うまく行った構成と、うまくいかなかった構成を記述しています。

## 目的
AWS上のアプリケーションが、エラーログを吐いたときに、Slackにエラー情報を通知し、運用の迅速化を図る。

## 準備

* AWS上のアプリケーションがAmazon CloudWatch Logsに出力するように設定しておいてください。この部分は割愛します。
* また、ログの出力をJSON形式で出力します。それにより、クエリが使用できるようになります。

## うまくいかなかった構成

### Amazon CloudWatch Alarmsの構成

`Amazon CloudWatch Logs -> Amazon CloudWatch メトリクス -> Amazon CloudWatch Alarms -> Amazon SNS Topics -> AWS Chatbot Slack` で通知するように設定してみました。
通知はできたのですが、エラーがあったことしか通知されず。
通知でありメッセージ投稿ではない。
メッセージのカスタマイズなど必要な情報を伝えることができませんでした。
そんな気が初めからしていましたが。

### lambda to AWS Chatbot Slack

`Amazon CloudWatch Logs -> Amazon CloudWatch サブスクリプションフィルタ -> AWS Lambda -> Amazon SNS Topics -> AWS Chatbot Slack`

エラーログの内容が送れなかったので、サブスクリプションフィルタとLambdaを使用してみました。
しかし、`Amazon SNS Topics -> AWS Chatbot Slack`の部分は、上の通知には使用できるが、Lambdaから自由なメッセージの送信には現時点では対応しておらず、いろいろなパターンで出力してみましたが、ダメでした。
```
Event received is not supported (see https://docs.aws.amazon.com/chatbot/latest/adminguide/related-services.html ):
```
というメッセージがチャネルのログに出力されました。

## うまく行った構成

`Amazon CloudWatch Logs -> Amazon CloudWatch サブスクリプションフィルタ -> AWS Lambda -> Slack incoming webhook`

AWS Chatbot Slack がうまくいかなかったので、直接Slackに送るようにしました。
AWSだけで完結したかったのですが。
それぞれの設定の資料は以下です。

### Amazon CloudWatch サブスクリプションフィルタ

フィルターに
```
{ $.level= "ERROR" }
```
に設定する。ログレベルがERRORの場合に出力されるようになります。

### AWS Lambda

Amazon CloudWatch サブスクリプションフィルタ
からエラーログを受け取り、整形し、
Slack incoming webhook
にわたす処理が必要です。

ログ受け取りは、base64とgzipを使用します。
下記参照

https://stackoverflow.com/questions/50295838/cloudwatch-logs-stream-to-lambda-python

### Slack

下記ページから設定し、
URLを取得し、
URLにメッセージを送れば連携が完成します。

https://api.slack.com/messaging/webhooks
はじめてのGAN～基礎理論～

# GANの原著論文を読む手助けになったら幸いです！

<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vQgaTCi7AZwe1bIbfZt9fbUj6_546NMJvaD8Zh2Icp5JVc4Q-7S18hKrJpLn0w5Ng/embed?start=false&loop=false&delayms=3000" frameborder="0" width="1280" height="749" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
【パブリッシャー】メニューレポ―トを作成してみる

今回は、各Webレポートへのアクセスを容易にするためのメニューレポートを作成してみます。[Sharperlight](https://sharperlight.jp/)アプリケーションメニューから**パブリッシャー**を起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/0c05dc23-d779-337c-79e7-7f5b110e6ae6.png)
パブリッシャーの右クリックメニューから**その他** -> **メニューレポートの作成**を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/51153029-e773-099f-77c1-19759a522b6d.png)
最初のオプションを選択し次に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/323cb8ec-315d-4f8e-b1e2-09d0ff4e185a.png)
索引ダイアログでは**演算子または値**フィールドに`<like>`、**値**フィールドに`SAPB1%`と入力し、`更新`を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/dd1bdd4b-5f49-4e4d-fedd-dd462c1152af.png)
レポートが絞り込まれるので、右クリックメニューから**すべて選択**を選びます。`OK`を押して次に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/a57a0c64-64fe-d977-370e-3408bca8f59e.png)
以下の画面では何もせず`OK`で次に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/56d6eaad-43d8-8449-b3ee-9a0edaa0bf51.png)
次のダイアログでは、**グループ**と**タイトル**を入力してから`OK`で次に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/0b54b8ba-a191-33ea-4d97-dad4b9674335.png)
これで完成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/c6e33c59-fe83-fa4b-1664-6d51342bb47f.png)
早速、表示してみましょう。Sharperlight Restサービスの起動をお忘れなく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/5a026dbd-3be6-4cc1-0cb9-fdbb331b6919.png)
このようなメニューページが表示されます。シンプルですね。これに味付けを行っていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/c286ac28-3922-a1a3-6deb-238f6e95e62f.png)
メニューレポートを開きクエリの編集を行います。
メニューレポートのクエリは、カスタムデータ定義でこのように作成されています。このデータセットを編集していきます。グリッド表示すると見易くなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/b91dc1cc-b00d-7fb7-a203-86ea6812d2b0.png)
2列目が、メニューレポートのタブの定義で、レポートの分類に役立ちます。3列目が、各レポートの名称。そして4列目が、各レポートのURLとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/139cb710-3972-d9fd-2c79-3fceb00e8cb6.png)
今回は、このように編集してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/e03b500d-73d7-2678-e906-f9cb3c39e7f3.png)
`OK`を押して保存し、早速拝見します。すこし格好よくなりましたね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/2cd21a1c-4f87-bfdb-0d4c-306257126787.png)
次にメニューページの既定のコンテンツを指定します。編集ダイアログを開き、**オプション**タブの**既定の内容**オプションにコンテンツのURLを指定します。今回はあらかじめ用意しておいたコンテンツのURLを設定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/e1a0c6f1-37c1-51e6-b879-d72322e2b570.png)
メニューページを再表示すると、指定したコンテンツがこのように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/ed08a918-df30-b553-3cee-451d786ff3ae.png)
いかがでしたか？
メニューページのヘッダー部も**オプション**タブの`ヘッダー`の`編集`で行えます。一般的なHTMLで記述するよう出来ているので自由に編集ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/de2f73d2-0a4e-4749-e18f-65b6a1b0fce2.png)

では、失礼します。
お母さんでもわかるimgタグとbackgroundの違い

# imgタグとbackgroundどっち使えばいいの？
私は画像を表示させる際にどちらを使えばいいか全く気にしていなく、

「文字と重ならないからimgタグかな！」
「画像の上に文字を表示させたいからbackgroundかな！」

くらいの気持ちで実装していました・・・。しかし今回も当たり前ながら、少しでも適切な場面があると思うので共有したいと思います！
## 使用例
### imgタグ
```index.html
<div class="image">
   <img src="images/IMG_7737.PNG" alt="">
</div>
```
```style.css
img {
  width: 100%;
  height: auto;
}
```
### background
```index.html
<div class="background-image"></div>
```
```style.css
.background-image {
  background: url(../images/IMG_7737.PNG);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  height: 0;
  width: 100%;
  padding-bottom: 56.25%;
}
```
どちらもしっかり可変します！！！
## 大前提
大前提として

・画像自体に意味がある場合(画像がないと成立しない内容) → imgタグを使用
・画像自体には深い意味はなく、デザインのための場合 → backgroundを使う

・・・という考え方が基本だが、場面によっては逆を使いたい時があると思う。

# それぞれのメリット・デメリットは？

|  |メリット  | デメリット |
|---|---|---|
| imgタグ | ・どこに画像を挿入したのかわかりやすい<br>・cssの記述が少ない<br>・alt属性を使うことができる | ・HTMLの記述が増えて見づらい<br> |
| background | ・HTMLの記述が少なくなる<br>・画像自体には深い意味がないことを伝えられる(デザインのため)<br> | ・cssの記述が増える<br>・可変時に[縦の大きさ/横の大きさ＊１００]の計算が必要 |

上記の表を見ると「HTMLの記述が増える」「cssの記述が増える」「計算がめんどくさい」などのデメリットが出てきているため、これらを回避するため逆を使ってもいいのかなと思った(チームでやる場合は規約に従うか、相談してください)。

## まとめ
HTMLやcssの記述量によって変えるのもありかなと思いました！
あまり水準する人はいないかもしれませんが、一人実装するときにでも活用してください！
[Shell] Create a simple server with shell script

# Introduction

Sometimes when our application is not ready for devployment, but we hope to setup a environment to test the network connectivity, host a simple test server is a really usefull. If your server or container contains python, it will be very easy with command like this `python -m http.server 8000` to achieve this. but if your environment does not have python. Then it also has a way to create a simple server.

# Create a simple server with shell script

On Unix-like operating systems, the `nc` command runs Netcat, a utility for sending raw data over a network connection. We can use `nc` coomand to host a http server.

```sh
#!/bin/sh

# response
response() {
    echo "HTTP/1.0 200 OK"
    echo "Content-Type: text/plain"
    echo ""
    echo "Hello"
}

# listen ctrl-c
trap exit INT

# loop and listen port 8000
# if you want to listen IPv6, use -l6
while true; do
    response | nc -l 8000 -w 1
done
```
実績がなく欠損した日付レコードを補間する(SPSS Modeler データ加工逆引き5-10)

# 実績がなく欠損した日付レコードを補間

![スクリーンショット 2022-08-09 18.15.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/8cebf567-7cc8-d485-3d7e-8924da1de81d.png)

## 1.想定される利用目的

・論理在庫の推定
・設備IoTデータの欠損値の処理

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/blob/main/missing_date.str?raw=true

## 3.サンプルストリームの説明

![スクリーンショット 2022-08-10 8.16.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/2aafb516-ede2-a668-ee5a-a0993f848fb1.png)

a.入力するデータは以下の通りです。休日のデータが欠けていてこのままでは時系列モデリングにかけられません。
![スクリーンショット 2022-08-10 8.18.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/adae007b-fc56-4411-671b-c8e4218c7f69.png)

b.モデルを作成するために必要な期間の日付マスタを準備します。
![スクリーンショット 2022-08-10 8.19.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/445e777e-8c25-b0c6-f28a-d693b2624b2a.png)

c.[レコード結合]ノードを編集します。[レコード結合方式]は[キー]を選択し[Date]で[完全外部結合]します。
![スクリーンショット 2022-08-10 8.19.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/41c3bd58-3877-c014-6d0e-b1e1b865a279.png)

[プレビュー]します。あとはNULLを処理します。
![スクリーンショット 2022-08-10 8.20.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/f617777b-19a7-f5ce-3dab-e9995a2f9db8.png)

c.[置換]ノードを編集します。売上がNULLの場合には[0]にします。
![スクリーンショット 2022-08-10 8.20.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/deb92711-7a31-1237-bff5-c50a295af8f0.png)

d.[置換]ノードを編集します。すでに存在する曜日を活かしても良いのですがここでは作り直すため[置換え条件]を[常時]にします。
![スクリーンショット 2022-08-10 8.27.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/25113434-db68-965e-1139-c8d81d96dcd1.png)

曜日の求め方は以下の記事で詳しく説明しています。

https://qiita.com/416nishimaki/items/1c9f1e1ebe7f14f6f79f

e.[データ型]ノードを編集します。後続fのために曜日を数値から名義型に変更して[値の読み込み]ボタンを押し確定します。
![スクリーンショット 2022-08-10 8.26.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/a0675d48-fa8f-b595-5899-e3dff1a4eec8.png)

f.[データ分類]ノードを編集します。
![スクリーンショット 2022-08-10 8.27.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/861d5c2f-6bcb-377a-aa39-de6bb09406e5.png)

[プレビュー]します。
![スクリーンショット 2022-08-10 8.28.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/3d832e6e-1432-381f-aa5c-32c1e27792af.png)

#### 注意点

売上列をNULLにしておくと、週次で要約して割り戻すなどの後続処理で不整合が起きるため[0]にします。

トレンド予測モデルを作る場合には日付の欠落が原因でうまくモデルが作れない場合がありますが、一方で実績がない日付を含んだ間欠需要を予測するには事前に工夫しないとマイナスの予測をするので注意します。

## 4.参考情報

#### 類似の問題を取り扱っている記事

https://qiita.com/kawada2017/items/be56ae15ded415253faa

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
vistaでandroid studio その5

# 概要
vistaでandroid studio 1.0.1やってみた。
練習問題やってみた。

# 練習問題
九九を実装せよ。

# 写真

![device-2022-08-29-094434.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1c92d2a5-d226-9750-0d6d-0297f48658d1.png)


# サンプルコード

```
    public void run(View view) {
        TextView tv = (TextView) findViewById(R.id.chage);
        String dis = "";
        for (int col = 1; col <= 9; col++)
        {
            for (int row = 1; row <= 9; row++)
            {
                if (col * row < 10) dis += " ";
                dis += String.valueOf(col * row);
                dis += " ";
            }
            dis += "\n";
        }
        tv.setText(dis);
    }
```

以上。
Linux アドレスとネットワーク関連ファイルについて（自分用メモ

●IPアドレスのクラス分け

・A　0.0.0.0~127.255.255.255　255.0.0.0
・B　128.0.0.0~191.255.255.255　255.255.0.0
・C　192.0.0.0~233.255.255.255　255.255.255.0
・D　244.0.0.0~239.255.255.255
・E　240.0.0.0~255.255.255.255

IPアドレスのクラスの概念を使わず、任意の長さのサブネットマスクを利用する事を「CIDR」（サイダー）という

●プライベートアドレス
プライベートアドレスの範囲

・クラスA 10.0.0.0~10.255.255.255
・クラスB 172.16.0.0~172.31.255.255
・クラスC 192.162.0.0~192.168.255.255

IPアドレスのうち、ローカルネットワークでのみ使用が許可されているアドレスをプライベートアドレスと言い、クラスごとに範囲が定められている。プライベートアドレスはIANA（アイアナ：Internet Assigned Numbers Authority）によって予約されている


●ネットワーク関連ファイル

ファイル名と設定内容

・/etc/hostname ホスト名を設定(Debian系)
・/etc/sysconfig/network ホスト名を設定(Red Hat系)
・/etc/hosts IPアドレスとホスト名の対応付け
・/etc/nsswitch.conf 名前解決やサービス名解決の際の問い合わせ順序を指定
・/etc/resolv.conf ドメイン名やDNSサーバの指定
・.etc/services サービス名とポート番号の対応付け


●getentコマンド 
「/etc/nsswitch.conf」の設定に従って検索を行うコマンド。

getent データベース名 [ キー ... ]

データベース名に nsswitch.conf で指定できるサービス名、検索したい情報をキーに指定することで、名前解決順序設定に従って検索した結果を得られる。
名前解決の順序は「/etc/nsswitch.conf」で指定。ホスト名の名前解決順序は「hosts」項目で設定します。/etc/hostsから検索し、見つからなければ次にDNSサーバに問い合わせを行う。
vistaでandroid studio その4

# 概要
vistaでandroid studio 1.0.1やってみた。
練習問題やってみた。

# 練習問題
ズンドコを実装せよ。

# 方針

- 乱数 new Random

# 写真

![device-2022-08-29-093621.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1b260ffa-9e2a-7560-1366-682ef11df84a.png)


# サンプルコード

```
    public void run(View view) {
        TextView tv = (TextView) findViewById(R.id.chage);
        final String success = "ズンズンズンズンドコ";
        final List<String> zundoko = Arrays.asList("ズン", "ドコ");
        StringBuilder sb = new StringBuilder();
        Random rand = new Random();
        while (true)
        {
            String zd = zundoko.get(rand.nextInt(2));
            sb.append(zd);
            if (zd.equals("ドコ"))
            {
                String check = sb.toString();
                if (check.endsWith(success))
                {
                    sb.append(" キヨシ!!");
                    break;
                }
                sb.setLength(0);
            }
        }
        tv.setText(sb.toString());
    }

```

以上。
【Jetpack Compose】値を引き継いで画面遷移する

# 概要
画面遷移をする際に、遷移元の値を遷移先の画面に引き継ぎたいと思ったのですが、少し手こずりました。

# コード
```Kotlin:test.kt
        composable("favorite") {
            FavoriteScreen (
                toFavorite = {navController.navigate("favorite")},
                toDetail = {productId -> navController.navigate("detail/${productId}")}
            )
        }
        composable(
            "detail/{productId}",
            arguments = listOf(
                navArgument("productId"){
                    type = NavType.IntType
                }
            )
        ) { backStackEntry ->
            val productId = backStackEntry.arguments?.getInt("productId")?:0
            val viewModel:FavoriteScreenViewModel = FavoriteScreenViewModel()
            ProductDetailScreen (productId,viewModel)
        }
```
# 内容
Int型の商品番号productIdをFavoriteScreenからProductDetailScreenに渡しています。


# 注意点
これでひっかかったのは私だけかもしれませんが、引き継ぎ先を指定せずに引き継ぐ値だけ決めてしまうとエラーを吐きます。
どうしてエラーが出てるのかわからなかったので気づくのに時間がかかりました。
Zapp!でFlutterアプリをWebブラウザだけで開発する

[Zapp!](https://zapp.run/)というサービスがリリースしました。WebブラウザだけでFlutterアプリを開発できるサンドボックス環境です。これまでに[DartPad](https://dartpad.dev/)という似たサービスがありましたが、一番大きく違うのは **任意のパッケージ** が利用できると言うことでしょう。

DartPadも便利だったのですが、Firebase向けのライブラリしか使えませんでした。何となくGoogleの囲い込みを感じてもやっていたんですよね。そんな中、Zapp!は任意の（といってもWebに対応している必要はあるでしょう）Dartパッケージが利用できます。

ということで、簡単なNCMBを使ったデモを作ってみました。[こちらのリンク](https://zb206tnb306.zapp.page/#/)で確認できるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/cbb24e42-6057-87fe-1c36-168b5bf5e3bf.png)

[実際のコードはこちら](https://zapp.run/edit/flutter-zb206tnb306?entry=lib%2Fmain.dart&file=lib%2Fmain.dart%3A801-806)で確認できます。

## 使い方

Zapp!の使い方は簡単で、[こちらのURL](https://zapp.run/edit/flutter)からアクセスすればすぐに開発環境が開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/95d1b11f-0cea-7963-c65f-e8b178381350.png)


後は開発しながら `Ctrl+R` を押せば、プレビューに反映されます。恐らく最初の保存時にユニークなURLが発行されるので、後はそれを外部公開すれば誰でもWebアプリケーションが利用できます。

## パッケージの追加

パッケージの追加はコマンドではなく、pubspec.yamlの修正になります。例えば `ncmb` パッケージであれば、下記のように `cupertino_icons` の下辺りに追加します。バージョンは[ncmb | Dart Package](https://pub.dev/packages/ncmb/install)にて確認できますが、 `any` にする手もあるようです。

```yaml
dependencies:
  flutter:
    sdk: flutter
  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  ncmb: ^2.6.6
```

追加したら、画面中央上にある `Pub Get` ボタンを押すと、入力補完にも表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/26d3ea37-85e8-108f-aa5b-e753930c3176.png)


## 追加時の注意

NCMBに限らないと思いますが、パッケージが依存しているライブラリがうまく追加されない場合があるようです。NCMBの場合は[shared\_preferences | Flutter Package](https://pub.dev/packages/shared_preferences/install)が入ってくれなかったので、別途pubspec.yamlに追加しています。

```yaml
dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2
  ncmb: ^2.6.6
  shared_preferences: ^2.0.15
```

後、WebアプリケーションなのでiOSやAndroid、デスクトップ向けのライブラリはインストールできないでしょう。

## Tips

後は書いていて気がついた点です。

- main関数はmain.dartの一番下にありました
- 最初のコードはStateが定義されていないので注意してください

## まとめ

Zapp!によって、Flutterのファーストステップがとても楽になるかと思います。少なくとも数GBのファイルをダウンロードしたり、Android StudioやXcodeなどの開発環境を整えることなく開発体験をはじめられます。

ハンズオンなどがとても手軽になりそうで良い感じです。

[Zapp! Build Flutter apps in the browser](https://zapp.run/)
vistaでandroid studio その3

# 概要
vistaでandroid studio 1.0.1やってみた。
練習問題やってみた。

# 練習問題
fizzbuzzを実装せよ。

# 方針

- textview,button,stringを使う。
- 剰余 %
- 文字列の加算 +=
- 数値の文字列化 String.valueOf

# 写真

![device-2022-08-29-092521.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/5c3c744a-f64c-e18c-fdda-b608f950a6f0.png)

# レイアウト

```
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <TextView android:text="@string/hello_world" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/chage"
        android:text="Hello World!!"
        android:textSize="32sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="41dp"
        android:layout_marginTop="81dp" />

    <Button
        android:id="@+id/mybottun"
        android:onClick="run"
        android:text="押す"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="81dp"
        android:layout_marginTop="601dp" />

</RelativeLayout>
```

# サンプルコード

```
package com.ohisamallc.ohiapp154.ohiapp154;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.view.View;

public class MainActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings)
        {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    public void run(View view) {
        TextView tv = (TextView) findViewById(R.id.chage);
        String dis = "";
        for (int i = 1; i < 101; i ++)
        {
            if (i % 15 == 0)
            {
                dis += "FizzBuzz ";
            }
            else if (i % 3 == 0)
            {
                dis += "Fizz ";
            }
            else if (i % 5 == 0)
            {
                dis += "Buzz ";
            }
            else
            {
                dis += String.valueOf(i);
                dis += " ";
            }
        }
        tv.setText(dis);
    }
}

```

以上。
初心者　Flutter x MySQL8 に挑戦する 20 with mysql_client

# Minimum Step

- 一昨日は、動いて、その様子がconsoleに表示された。
- 昨日は、UIと接続して、ちゃんと動いたけど、表示はやっぱりconsoleだけだった。
- 今日の目標は、取得したデータをUIに表示。

　ほんとは一気にリスト表示まで持っていきたかったけれども、そこ欲張ると、また、何が問題か判別するのが複雑になるので、ぐっとがまんして最低限の変更だけ加える。　

　見本がない。ほんとにこれは困る。一番近い見本は、やっぱりメンターさんにつくってもらったmysql1のコードなので、それをじっくり読んでまずこんなふうに書いてみた。 

```
    for (final row in result.rows) {
      setState((){
        name = row[0];
      });
```
　すると[ ]にinidifinedだって、クレームがつく。え〜、ふつうに配列じゃん、と思うが、エラーでは走らないので、どうにかしなきゃならない。　
　
　mysql_clientのサンプルコードでprint()になっている箇所をしげしげ眺めると、例えばこんなのがある。　

```
print(row.colAt(0));
```

　お、もしや配列は(　)なの？　で、こうする。

```
    for (final row in result.rows) {
      setState((){
        name = row.colAt(0);
      });
```
　うーむ、まだ真っ赤だ。でもマウスを載せてみると、
- 「null check (!) 」と出る。


　え、そうなのかい。

 ということで最終案

```
    for (final row in result.rows) {
      setState((){
        name = row.colAt(0)!;
      });
```

 エラーはなくなりました。　では、debug。　

　行け！　
　
　ウンとも、スンとも・・・だけど、これ、もう慣れてきた。やたら遅いということだ。　

　行け！　

　はい、今度は行きましたよ、そして無事、

## 新規登録者の名前がsimulatorの中央に表示されました！

　でも、この「遅い」をどうにかしなくちゃね。「早くする」はとりあえずムリそうなので、「ちょっと待ってねグルグルをつける」かな。userが連打したくなるのを抑えないと。いや、私が、か笑

https://qiita.com/dongri727/items/c8799f1ab84dfc6acd9f

https://qiita.com/dongri727/items/14191b6c6e6dce23ac20
環境変数を含むパスからパスを取得する

# 環境変数を含むパスからパスを取得する処理C++
## std::string の場合 
```c++
		std::string GetEnvInclusive(std::string path)
		{
			auto  pos1 = path.find("%");
			if (pos1 == std::string::npos) {
				return path;
			}
			auto  pos2 = path.find("%", pos1 + 1);
			if (pos2 == std::string::npos) {
				return path;
			}

			auto startPath = path.substr(0, pos1);
			auto envPath = path.substr(pos1 + 1, pos2 - 1);
			auto endPath = path.substr(pos2 + 1);

			char cPath[MAX_PATH + 1];
			std::string strPath;

			if (::GetEnvironmentVariableA(envPath.c_str(), cPath, MAX_PATH) > 0) {
				envPath = cPath;
			}
			else {
				envPath = envPath;
			}

			path = startPath + envPath + endPath;
			return path;
		}
```

## std::wstring の場合 
```c++
		std::wstring GetEnvInclusive(std::wstring path)
		{
			auto pos1 = path.find(L"%");
			if (pos1 == std::string::npos) {
				return path;
			}
			auto pos2 = path.find(L"%", pos1 + 1);
			if (pos2 == std::string::npos) {
				return path;
			}

			auto startPath = path.substr(0, pos1);
			auto envPath = path.substr(pos1 + 1, pos2 - 1);
			auto endPath = path.substr(pos2 + 1);

			wchar_t cPath[MAX_PATH + 1];
			std::wstring strPath;

			if (::GetEnvironmentVariableW(envPath.c_str(), cPath, MAX_PATH) > 0) {
				envPath = cPath;
			}
			else {
				envPath = envPath;
			}

			path = startPath + envPath + endPath;
			return path;
		}
```

# 環境変数を含むパスからパスを取得する処理C#
```csharp
        string GetEnvInclusive(string path)
        {
            if (string.IsNullOrEmpty(path) == true)
            {
                return "";
            }

            var strResult = path;
            if (path.IndexOf('%') == 0)
            {
                var nEndPos = path.IndexOf('%', 1) + 1;
                var env = path.Substring(0, nEndPos);
                strResult = System.Environment.ExpandEnvironmentVariables(env) + path.Substring(nEndPos);
            }

            return strResult;
        }
```
vistaでandroid studio その2

# 概要
vistaでandroid studio 1.0.1やってみた。
0.8.0消して、1.0.1入れた。

# インストール手順

ダウンロード

- android-studio-bundle-135.1641136.exe

# 写真

![studio.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e0880171-dd93-d995-b8eb-9e31ae2ee970.jpeg)

# プロジェクト作成手順

1) 「新規 Android Studio プロジェクトの開始」をクリック

2) "アプリケーション名" / "会社ドメイン" を指定し「次へ」
アプリケーション名 : ohiapp154
会社ドメイン : ohiapp154.ohisamallc.com （任意のドメインを入力。以降自作するクラスのパッケージ名として利用される。）
プロジェクトのロケーション : 上記２項目から自動的に生成されるため、入力は不要

3) "スマホおよびタブレット" を指定し「次へ」
api-21
※サポートする最も古いAndroid APIバージョンの指定を切り替えると、何%のデバイスをサポートできるかがわかるようになっている
どのような端末向けのアプリケーションかを指定

4) "モバイルへアクティビティを追記"
空のアクティビティーを選択

5) Configure Activity
ここではデフォルトのままで進める
アクティビティー名 : MainActivity
レイアウト名 : activity_main
チェックボックス : そのままでOK

6) Build Toolのインストール
"Hello World" アプリケーションのプロジェクトが表示されるが、 "Build Tools" がインストールされていないというエラーメッセージが表示されている場合
"Install Build Tools" のリンクをクリックしインストールを行う

7) 実行
メニュー > 実行 > 実行 を選択
"デプロイ対象の選択" ウィンドウで、 "新規仮想デバイスの作成" ボタンを押下
ハードウェアの選択 ウィンドウで、 "Nexus 7" を選択し 「次へ」
仮想デバイス がいくつか表示される。 Download のリンクが表示されている場合はまた端末のダウンロードが行われていないためクリックしダウンロード
ダウンロード完了後は該当デバイスを選択し「完了」ボタンを押下


以上。
仮想環境の作成とactivate

# 仮想環境の作成とactivateの流れ（Linux, Mac, Windows）

## Linux, Mac
```shell:Linux, Mac
$ cd Desktop
$ mkdir dir名
$ cd dir名
$ python3 -m venv 仮想環境名 # 仮想環境作成
$ source 仮想環境名/bin/activate # activate
```

## Windows
```:共通部分
C:\> cd Desktop
C:\> mkdir dir名
C:\> cd dir名
```

```cmd.exe
C:\> python -m venv 仮想環境名
C:\> 仮想環境名\Scripts\activate.bat
```

```powershell:powershell
C:\> python -m venv 仮想環境名
C:\> 仮想環境名\Scripts\Activate.ps1
```
- 上記コマンドが実行できない場合以下を入力
    - 2行目は、念のため
```
C:\>Set-ExecutionPolicy RemoteSigned -Scope Process
C:\>python -m pip install --upgrade pip　←pip がインストールされていない場合
```

## deactivate
```shell
$ deactivate # 仮想環境の終了
```
Nuxt　nuxt_link, $router.push, hrefの使い分け

## ページ遷移の方法は３種類あるので、その使い分け。

### nuxt-linkの使用方法　
```
<nuxt-link to="/home">ホーム</nuxt-link>
```
- メリット スピートが早い
#### 使用時
`<template>`内でページ遷移をしたい時に使用

### $router.pushの使用方法
```
  toHomePage() {
   this.$router.push('/home')
  }
```
- メリット メソッド内で使える
- $router内にページ遷移の記録を残せる
#### 使用時
`<script>`内でページ遷移をしたい時。例メソッドを使用あとに画面遷移


### aタグ
```
  <a href="/home">ホーム</a>
```
- メリット ドメインの外への使える
#### 使用時
自身のドメインの外へ移動したいときに使用する

参考記事
[[SOLVED]-WHAT IS THE DIFFERENCE BETWEEN <ROUTER-LINK> AND $ROUTER.PUSH?-VUE.JS](https://www.appsloveworld.com/vuejs/100/28/what-is-the-difference-between-router-link-and-router-push)
Excelで書いた手順書を印刷するときの設定（作業備忘録）

# はじめ
リリース作業でセキュリティ的に厳しい場所ではPCを持ち込めないときがあるかと思います。
そんな時は手順書を印刷して持ち込む必要があるかと思うのですが、あまり複合機（印刷）を使わないため、設定を毎回忘れてしまうんですね。

次、手順書を印刷するときの私のために、作業メモを残します。

# 印刷設定
1. 表示形式の変更
表示→改ページプレビューの選択（これで印刷範囲がわかる）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1612369/7e38dfbc-1933-455a-3c8d-888def559829.png)


2. フッターの設定
2.1 シート名を右クリックして"すべてのシートを選択"を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1612369/2f12a641-1fdc-7c53-2500-1a6338d8e37e.png)
　
2.2 ページレイアウト>ページ設定>ヘッダーフッター>フッターの編集をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1612369/7266e1cf-b125-9c39-d78a-bf477b9747c2.png)
　
　
2.3 左側に"&[シート名]"、中央部に"&[ページ番号]/&[総ページ数]ページ"を設定する
　
3. 印刷時の横幅をページに合わせる
3.1 ページレイアウト>"ページ"を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1612369/92736f8e-70ee-06c9-1f6b-068117d91f4d.png)
　
3.2 拡大縮小印刷の次のページ数に合わせて印刷を "横：縦 = 1：ブランク" に設定する


# 終わり
次は忘れないといいな。この設定。
cross_val_predictを予測精度評価に使ってはいけない（場合がある）

### 結論
　クロスバリデーションにおいて、各分割のサンプル数が異なる場合
　cross_val_predictによる予測結果を基にr2やMAEなどを計算することには注意しましょう。


### sklearn
scikit-learnのcross-validationに関するドキュメントには、以下の様なコメントやWarningがあります

> The function cross_val_predict has a similar interface to cross_val_score, but returns, for each element in the input, the prediction that was obtained for that element when it was in the test set. Only cross-validation strategies that assign all elements to a test set exactly once can be used (otherwise, an exception is raised).

まず、 Only cross-validation strategies that assign all elements to a test set exactly once can be used (otherwise, an exception is raised).　について

全てのデータが1回のみテストセットとして呼び出されるCV以外ではエラーになります。

例えば、[RepeatedKFold](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.RepeatedKFold.html#sklearn.model_selection.RepeatedKFold), [TimeSeriesSplit](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.TimeSeriesSplit.html)などが該当します。

以下のコードを実行するとValueErrorが発生します。

```
from sklearn.datasets import load_diabetes
from sklearn.model_selection import cross_val_predict, cross_val_score
from sklearn.model_selection import RepeatedKFold
from sklearn.ensemble import RandomForestRegressor

X,y = load_diabetes(return_X_y=True)
model = RandomForestRegressor()

y_pred_cv = cross_val_predict(model,X,y , cv=RepeatedKFold(n_splits=5,n_repeats=3))

```

各データに対して複数回予測値を求めるRepeatedKFoldの様なCV手法には対応しない。ということです。
一方、cross_val_predictの代わりにcross_validate、cross_val_scoreではn_splits*n_repeatsの15回分のスコアが求まります。


> Warning Note on inappropriate usage of cross_val_predict
The result of cross_val_predict may be different from those obtained using cross_val_score as the elements are grouped in different ways. The function cross_val_score takes an average over cross-validation folds, whereas cross_val_predict simply returns the labels (or probabilities) from several distinct models undistinguished. Thus, cross_val_predict is not an appropriate measure of generalization error.

https://scikit-learn.org/stable/modules/cross_validation.html#obtaining-predictions-by-cross-validation

さらに重要な話として、そもそもcross_val_predictで求めたy_pred_cvをスコア評価に使うのは適切ではないとWarningに記載されています。

これについては、以下のQ&Aが分かりやすいです。
[Tutorial More](https://tutorialmore.com/questions-1645974.htm)

分かりやすくするために、平均絶対誤差や平均二乗誤差ではなく最大絶対誤差(max-abs-errors)で評価する場合を考えています。

3-Foldで評価した場合、それぞれの最大絶対誤差(a, b, c)が求まります。
cross_val_scoreではmean(a, b, c)を求めます。この値を構築した機械学習の最大絶対誤差とすることは妥当です。

一方で、cross_val_predictで求めたy_pred_cv からmax-abs-errorsを求めるとmax(a, b, c)であり、これをモデルの最大絶対誤差とするのは合理的ではありません。

ただし、KFoldやLOOにおいては各バッチセットのサイズが（ほぼ）等しいためcross_val_predictの結果から平均絶対誤差や平均二乗誤差などの予測精度を求めても結果的には問題ありません。
UnrealEngineのSceneCaptureComponentでCaptureEveryFrameをオフにしてキャプチャすると視界に入れていないWidgetが表示されない

UnrealEngineで以下のような現象があったため記録として残しておきます。
SceneCaputreComponentでCaptureEveryFrameをオフにしてCaptureSceneをしているとレベルに配置したWidgetを視界に入れるかCaptureEveryFrameをオンにしたSceneCaptureComponentで映しておかないと表示されない。

# 確認環境

UE4.27.2

# 確認方法

* SceneCaptureComponent2DのCaptureEveryFrameをオフにしてTickごとにCaptureSceneし撮影した画像を表示するPlaneを正面に配置する
* 背後にWidgetを表示するアクタを配置する

**結果**

* プレイ初回時には背後のWidgetが正面に配置したPlaneに表示されていない
* 後ろを振り向いてWidgetを確認し正面を見るとWidgetが表示される
* CaptureEveryFrameをオンにすると最初からWidgetが表示される
* 別のCaptureEveryFrameをオンにしたSceneCaptureComponentでWidgetを映しておいてもWidgetが表示される

![ダウンロード.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16768/56799218-ca60-4b0a-1869-d587768d1707.gif)

# まとめ

* CaptureEveryFrameがオフのSceneCaptureComponentでは視界に入れてなかったりCaptureEveryFrameがオンのSceneCaptureComponentで映していないとキャプチャできない
* なぜそうなるかは追えていない
* 上記の例だと素直にCaptureEveryFrameをオンにすればいいが、負荷をさけるためにCaptureEveryFrameをオフにして必要な時にCaptureSceneするような場合だと発生する
* CaptureEveryFrameがオフだとアウトラインのポストプロセスが表示されないような現象もある(参考：[UnrealEngineで全天球(360度)画像を撮影してファイルに保存する - Qiita](https://qiita.com/mechamogera/items/f0e22ecf80e8f36fd5fe#%E6%92%AE%E5%BD%B1%E7%94%A8blueprint%E3%81%AE%E8%BF%BD%E5%8A%A0))
SpringBootで画像データをControllerで受け取る

## 結論
画像データは、MultipartFile型で受け取る

引用 : 

https://spring.pleiades.io/guides/gs/uploading-files/

## 説明
"https://spring.pleiades.io/guides/gs/uploading-files/"
を参考にされるといいです。

以下のようにMultipartFile型の引数で受け取っています。
```java
@PostMapping("/")
	public String handleFileUpload(@RequestParam("file") MultipartFile file) {
…
```
## 補足

あと、
アップロードされた画像のファイル名も取得できます
```java
        ...
		storageService.store(file);
		redirectAttributes.addFlashAttribute("message",
				"You successfully uploaded " + file.getOriginalFilename() + "!");

		return "redirect:/";
	}
```

この部分です。
```java
file.getOriginalFilename()
```
Node.js Shift-JISに変換する方法

Node.jsで簡単に文字列をShift_JISに変換する方法を明記します。

環境：　Mac OSX

利用するライブラリ [iconv-lite](https://www.npmjs.com/package/iconv-lite)
まずはライブラリのインストールをします。

```qiita:ターミナル
$npm install --save iconv-lite
```

```convert.ts
import {convert} from 'iconv-lite';

const str = '変換したい文字列';
const encoded = encode(str, 'SJIS'); //文字列をShift_JISに変換
console.log(encoded);
```