OmniAICreator/Qiita-1.07M huggingface dataset:
Unity BuildSetting フレームレート可変


### Folderを設定して Ctrl+B

```C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CubeRole : MonoBehaviour
{
    int[] mode={20,30,60,120};//フレームレート確認用
    int tick=0;
    void Update()
    {  
        gameObject.transform.localRotation
         =Quaternion.Euler(0,Time.frameCount % 360,0);
        
        if(Input.anyKeyDown){
            //if fps working:
            //FIle->BuildSetting->Player Settings(look! left down)->Quality
            // VSync Conut ->Don't Sync 
            // Ctrl+B build run
            var i=tick%mode.Length;
            Application.targetFrameRate=mode[i];
            Debug.Log(mode[i]);
            tick++;
        }
    }
}

```
Ruby｜csv_box を使ってもっと楽に CSV をつくりたい

# やりたいこと

CSV 出力は案件ごとに手製で作ることが多いと思います。業務で関わるサービスだと列数も多く、並び替えや条件による列の追加・削除でバグが起きやすいですよね。

問題はデータ部の出力と列の並びが直結しているので、それを分けてやると管理しやすいと考えました :smile:

```ruby
require 'csv'

Book = Struct.new(:id, :title, :price)
books = [Book.new(1, 'How to cook delicious meals', 1500), Book.new(2, '10 tips to lose weight', 250)]

table = CSV::Table.new([])

headers = [
  'id',
  'title',
  ...
  'price'
]

# メンテナが代わることによる無理な列名の追加...
headers << 'tax price' if ....

books.each do |book|
  # ヘッダ部をみながらデータ部の並びを整えるのが大変...
  table << CSV::Row.new(headers, [book.id, book.title, ..., book.price])
end

puts table.to_csv
```

# やってみたこと

数年前ですが、csv_box を作ってみました。Rails で使われることを想定していて、いまのところカラムの内容をそのまま出力します。

https://rubygems.org/gems/csv_box

`CSVBox.add` で出力したい列を定義します。ここでは並びは関係なく、何を出力したいかです。引数にはモデル名など対象がわかるようにすると良いと思います。

```ruby
CSVBox.add 'book' do
  field 'id'
  field 'title'
  field 'price'
end
```

`CSVBox.layouts` は `CSVBox.add` で登録した対象にどの順番で出力したいかを決めることができます。レイアウトに `layout` で名前をつけることができて CSV の作成時に使います。

```ruby
CSVBox.layouts 'book' do
  layout 'shuffled layout' do |box|
    box.price
    box.id
    box.title
  end

　layout 'simple layout' do |box|
    box.title
    box.price
  end
end
```

`CSVBox.take` で対象の名前とレイアウト名を指定して、何をどうやって出力するかを決めます。`<<` で `CSV::Table` を使って行を追加してたように追加することができます。

```ruby
box = CSVBox.take 'book', 'shuffled layout'

books.each do |book|
  box << book
end

puts box.to_csv

__END__
price,id,title
1500,1,How to cook delicious meals
250,2,10 tips to lose weight
```

レイアウトの変更も楽で条件によって変えるのであれば次のようになります。

```ruby
box = if ...
        CSVBox.take 'book', 'shuffled layout'
      else
        CSVBox.take 'book', 'simple layout'
      end

books.each do |book|
  box << book
end

puts box.to_csv
```

CSV 出力と分けて、対象の何を出力するのか、カラムの順番や条件をレイアウト毎に変えてやることによってかなりスッキリしたのではないでしょうか？今後ですが、例えば税込価格を表示したいなどその時だけの計算もあると思いますデコレータで逃げてもいいと思いますが、計算も組み込めるようになるのが今後の展望です。
【CUI】Linuxコマンドよく使うものをまとめて練習しよう！


#はじめに


* Linuxってなに？
* 実務でもスムーズに使えるようにしたい

このように考えて記事にまとめることにしました。
実際に自分のデスクトップで練習しながら書いていきます。


#目的

* Linuxコマンドを練習して息をするように使うことができる

#そもそも「Linux」とは

下記の記事によると,

> Mac OS,Windows XP,Windows 10などと同じOSです。OSとは、コンピューターのすべてのハードウェアを管理しているソフトウェアのことです。
Linuxは、主にサーバー用として使うOSです。

とありました。LinuxというひとつのOSを動かすためのコマンドを今から練習していきます。

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

#よく使うLinuxコマンド

| コマンド | 説明 | 使用例|
|:-:|:-:|:-:|
|  cd | フォルダやディレクトリの移動  | cd 移動先|
| cd ..  | 前のフォルダやディレクトリに戻る  | |
|  ls | フォルダの内容を表示  |  |
|  mv |  名前の変更、フォルダやファイル移動 | mv 変更前のファイル名 変更後のファイル名| 
|cp| フォルダやファイルのコピー|cp コピーしたいファイル名　コピー先のファイル名|
|clear|画面をきれいにする（ファイルやフォルダの削除はしない）||
|mkdir|フォルダ作成||
|touch|ファイル作成||
|rmdir|からのフォルダ削除||
|rm|フォルダやファイルの削除||
|pwd|現在いる場所（ディレクトリ）を表示||
|find|ファイル検索する|find / -name ファイル名|
|cat|ファイルの内容表示|||
|diff|ファイルとファイルの差分表示|diff 旧ファイル　新ファイル|
|chomd|ファイルやフォルダのアクセス権限を変更する|chomd 権限変更したいファイル名|
|history|コマンドの履歴を見る||
|man|コマンドのマニュアルを表示|　man コマンド名|
|less|テキストファイルを閲覧する|less ファイル名|


ざっと書きましたがまだまだありそうなので、
これよく使うかもと思ったら随時更新していきたいと思います！

2021/09/14
今日学んだ中で使ってなかったけど今後使いたいとおもったのはmanとlessです◎


#参照

* [よく使うLinuxコマンド一覧表【全33種】](https://www.sejuku.net/blog/5465)
【TED動画】大人が陥るバイアス。もしかして私も？

久々にいい話を聴けた。二日前、子どもらも聴かせたいとLINEで転送したが、観てくれたであろうか？
まだ感想はない。

思うは招くー植松努さんのTED×SAPPOROの2011年の講演。

植松努さんのプロフィール。
技術者、実業家。北海道にある産業機器メーカー、植松電機の二代目社長。
従業員20人程度の小さい会社ながら、クレーンなどに取り付ける車両積載型の電磁石システムの開発・製造販売において、
リサイクル用機器の製作・販売のシェアは9割を誇るという。
2002年から北海道大学との共同研究としてCAMUIロケット開発も手掛ける。
1966年生まれ。御年、今年で55歳。
リアル「下町ロケット」みたいな社長さんである。

「どうせ無理」この言葉は究極のところ戦争にもつながりかねない危険な言葉だという。
植松さんはこの言葉を世界から無くしたいと本気で考えている。そして実践している。

日本の、世界の大人たちが勘違いしているバイアス。
その大人たちが未来の子どもたちから夢を奪っているかもしれない。
20分のプレゼンだが、惹き込まれた。飽きない。人間的で、ユーモラスで、泣ける。

社会人の我々にも勇気を与えてくれる。
今日を頑張ろうと思える。「あしたっていまさ！」って思える。

お勧めです。ちょっとしたブレイク時間に、元気が欲しいときに。

https://tedxsapporo.com/talk/hope-invites/
Application を ViewModelStoreOwner にする方法

## はじめに

気軽に Activity 間でデータを共有する場合は、Application を継承したクラスを ViewModelStoreOwner にすると良いです。このように設計することで、Application を継承したクラスが肥大化することなく、Application にグローバルな値を持たせることができます。

## 実装

```kotlin
class MyApplication : Application(), ViewModelStoreOwner {
  private val store = ViewModelStore()
  override fun getViewModelStore(): ViewModelStore {
    return store
  }
}
```

Application の実装はこれだけです。今後グローバルな状態が増えたとしても、Application が肥大化することはありません。代わりに ViewModel の数が増えます。

## 使用例

次のコードは、`SubActivity` で加算した値が `MainActivity` にすぐに反映されるコードです。Jetpack Compose を使用しています。

```kotlin
class MyViewModel : ViewModel() {
  var count by mutableStateOf(0)
}
```

```kotlin
class MainActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // ViewModel の実体を取得するコード。このコードは SubActivity でも使われる
    val vm = ViewModelProvider(application as MyApplication).get(MyViewModel::class.java)
    setContent {
      MainScreen(vm, ::move)
    }
  }
  private fun move() {
    val intent = Intent(this, SubActivity::class.java)
    startActivity(intent)
  }
}

@Composable
fun MainScreen(vm: MyViewModel, onClick: () -> Unit) {
  Button(onClick = onClick) {
    Text("click me! ${vm.count}")
  }
}
```

```kotlin
class SubActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val vm = ViewModelProvider(application as MyApplication).get(MyViewModel::class.java)
    setContent {
      SubScreen(vm)
    }
  }
}

@Composable
fun SubScreen(vm: MyViewModel) {
  Button(onClick = { vm.count += 1 }) {
    Text("click add! ${vm.count}")
  }
}
```

## おわりに

この実装パターンを使うことで、いいね問題が解決すると思います。

## 余談

次のようにシングルトンオブジェクトを作れば、Application を継承したクラスを作る必要すらありません。

```kotlin
object MyData {
  var count by mutableStateOf(0)
}
```

このオブジェクトを使うようにしたとき、MainActivity と SubActivity のコードにある `val vm = ViewModelProvider(application as MyApplication).get(MyViewModel::class.java)` がなくなります。もし Application とシングルトンオブジェクトの生存期間が同じなのであれば、こちらでもいい気がします。ただ、Composable の依存する状態が引数として表れないのは少し良くないかもしれないです。
App.config



asp.net coreだと、appsetting.jsonがテンプレートに入ってくるので、設定ファイルは、json一択かと思っていましたが
XMLで書くApp.configもサポートとされているのですね。
今頃気づきました
CofigrationManagerクラスが存在するので、同じように使えるのですね。
基礎から学ぶReact/React Hooks学習メモ 5-4 useRef

# React Hooksを基礎から理解する 5-4 useRef

参考
[基礎から学ぶReact/React Hooks](https://www.amazon.co.jp/dp/B09CP8T4TX)

## useRefとは

- 要素の参照を行う。主にDOMへのアクセスに利用される。
- コンポーネント内において、変数に値を保持することができる。
- 値を更新してもコンポーネントが再レンダリングされることはない。→ useState()と異なる点
- インポート

```js
import React, { useRef } from "react";
```

- useRefの基本構文。関数コンポーネントのトップレベルで宣言する。

```js
const refObjct = useRef(初期値);
```

- refObjectの`current`プロパティの値は1000になる。

```js
const refObject = useRef(1000);
console.log(refObject.current); // 1000
```

### useRefの利用例（useStateとの比較）

- ref属性で、inputRefObjectとinput要素を関連付ける
- ボタンをクリックすると、`inputRefObject.current.focus()`でテキストボックスにフォーカスする。
- useStateのほうに文字を入力すると「レンダリング！」のログが出るが、useRefのほうは出ない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/d546207c-cc6b-ea56-b6e9-316a4af0678a.png)


```js
import React, { useState, useEffect, useRef } from "react";
import "./styles.css";

const SampleComponent = () => {
  const inputRefObject = useRef(null);

  const [inputValue, setInputValue] = useState("");

  const handleClick = () => {
    inputRefObject.current.focus();
  };

  // useEffectの第2引数がない場合、レンダリングされるたびに呼び出される
  useEffect(() => {
    console.log("レンダリング！");
  });

  const handleChange = (e) => {
    setInputValue(e.target.value);
  };

  // ref属性で、inputRefObjectとinput要素を関連付ける
  return (
    <>
      useState: <input onChange={handleChange} type="text" />
      <br />
      useRef: <input ref={inputRefObject} type="text" />
      <button onClick={handleClick}>入力エリアをフォーカス</button>
    </>
  );
};

export default function App() {
  return <SampleComponent />;
}

```
Dockerでofficialのイメージとdocker-compose使ってWordPressの環境作った時にハマったこと

Apple silicon （M1）macの**Docker Desktop**とDockerのオフィシャルのWordPressイメージ使ってローカルの開発環境構築しようとしたらめっちゃハマったのでメモ

https://hub.docker.com/_/wordpress

# docker-compose.yml

参考までに今回使った``docker-compose.yml``

```yaml
version: "3"

networks:
  backend:
    driver: bridge

volumes:
    db_data:
      driver: local

services:
  db:
    image: arm64v8/mariadb
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    ports:
      - 13306:3306
    networks:
      - backend

  wp:
    depends_on:
      - db
    image: wordpress:latest
    volumes:
      - ./:/var/www/html
    networks:
      - backend
    ports:
      - 8000:80
      - 4430:443
    restart: always
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
```

```yaml
    volumes:
      - ./:/var/www/html
```
ここで``./``（docker-compose.ymlがあるディレクトリ）をDocumentRootにしてる。

# あとからmysqlのユーザ名とか変えると再ビルドが必要

再ビルドしなくてもDB側で変更したユーザを追加すれば良いんだけど、面倒だった。
面倒なのでステージングと同じユーザ名使おうとしたのがいけなかった。ローカルとは環境変数分けよう。

# ドキュメントルートに``php.ini``とかあると読み込まれる。

php.iniは必要に応じて消しておく。

# https（SSL）でアクセスできない
## デフォルトだとそもそもSSLが有効になっていない

- ``/etc/apache2/conf-enable``
- ``/etc/apache2/site-enable``

あたりを見るとわかる。

### 自己証明書を作る

[こちら](https://www.server-world.info/query?os=Debian_8&p=httpd&f=7)を参考に証明書を``/etc/ssl/private``に作る
ssl-cert packageは使えなくなってた

https://www.server-world.info/query?os=Debian_8&p=httpd&f=7

### SSL moduleを有効化する

```console
# cd /etc/apache2/mods-enabled
# a2enmod ssl
```

apache 再起動

```console
# service apache2 restart
```

### default-sslを有効化する

```console
# cd /etc/apache2/sites-enabled
# a2ensite
Your choices are: 000-default default-ssl
Which site(s) do you want to enable (wildcards ok)?
*
Site 000-default already enabled
Enabling site default-ssl.
To activate the new configuration, you need to run:
  service apache2 reload
```

### 作成したオレオレ証明書に合わせてdefault-sslを編集する

```apache
#   A self-signed (snakeoil) certificate can be created by installing
#   the ssl-cert package. See
#   /usr/share/doc/apache2/README.Debian.gz for more info.
#   If both key and certificate are stored in the same file, only the
#   SSLCertificateFile directive is needed.
SSLCertificateFile	/etc/ssl/private/server.crt
SSLCertificateKeyFile /etc/ssl/private/server.key
```

apache リロード

```console
# service apache2 reload
```

### chromeでアクセス

不正な通信とかいわれるので、``thisisunsafe``とタイプして読み込む。　

# まとめ

面倒なんで誰か1個のコンテナでMySQLもSSLも動くWordPressのイメージ作ってくれ。

# その他

[KUSANAGIのdocker](https://kusanagi.tokyo/cloud/kusanagi-runs-on-docker/)使おうとしたら、コンテナいっぱい立ち上がるし、動かすディレクトリのパスにスペース入ってると動かなかった。
これ速いし、Drupalやconcrete5が動く環境も簡単に作れるから便利だから今回は残念だった。

https://kusanagi.tokyo/cloud/kusanagi-runs-on-docker/
Markdown (とHTMLとCSS少し) でスライドを作るremark

## remarkとは

こういうのでいいんだよ、
「HTMLとCSSを使いこなせる人をターゲットにした、シンプルなブラウザ内マークダウン駆動のスライドショーツール」

https://github.com/gnab/remark

> A simple, in-browser, markdown-driven slideshow tool targeted at people who know their way around HTML and CSS


```html

<!DOCTYPE html>
<html>
  <head>
    <title>タイトル</title>
    <meta charset="utf-8">
    <style>
      @import url('https://fonts.googleapis.com/css?family=Noto Sans JP&display=swap');
      @import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz);
      @import url(https://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic);
      @import url(https://fonts.googleapis.com/css?family=Ubuntu+Mono:400,700,400italic);
      body { 
        font-family: 'Noto Sans JP', serif; 
      }
      h1, h2, h3 {
        font-family: 'Noto Sans JP', serif;
        font-weight: normal;
      }
      
      .remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; }
    </style>
  </head>
  <body>
    <textarea id="source">

class: center, middle

# タイトル

---

# アジェンダ

1. はじめに
2. 本日のメニュー
3. ...

---

# はじめに

    ```
     System.out.println("Hello, world!!!");

    ```

    </textarea>
    <script src="https://remarkjs.com/downloads/remark-latest.min.js">
    </script>
    <script>
      var slideshow = remark.create();
    </script>
  </body>
</html>


```

## 仕上がり

![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/8165fc3a-5eb1-f5b0-ad82-45c2a59b07a6.gif)



## 関連

https://qiita.com/harasou/items/1fa3cca6ac1ef175c876

https://qiita.com/basictomonokai/items/2aff5fa5318c45dd2f1f

https://qiita.com/opengl-8080/items/d44aec7c6c643996916b

凝りたかったらCSSでおめかしして、内容はMarkdownで書いておけば良いやつ。
参考になればさいわいです。
【AR】Lightshipは拡張現実の常識を変える！（かもしれない）

# 概要
Qiita10周年おめでとうございます！

https://qiita.com/official-events/12fc7bacec894d33a981

サービス提供が開始されてもう10年も経つんですね・・いや、まだ10年しか経っていないと言うべきか・・？まぁどちらでもいいか。なんにせよおめでとう！！

テーマが「10年後のために今勉強しておきたい技術」ということで、個人的に注目しているNianticのLightshipについて、何がどう凄いのか記しておきたいと思います。

# Lightshipとは？
![lightship.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122485/ce9b2cad-41d0-838d-529f-debb78cd77be.png)

[Lightship](https://niantic.dev/)は、Nianticが開発しているAR(拡張現実)アプリの作成キットです。
以前は「Niantic Real World Platform」という名称でしたが、プライベートベータ版の発表に合わせて改名されました。
残念ながらプライベートベータ版ゆえにLightshipは完全には一般公開されていません。利用には申請のあと審査があります。

ちなみに[Niantic](https://nianticlabs.com/)は[ポケモンGO](https://pokemongolive.com/ja/)や[ハリーポッター 魔法同盟](https://harrypotterwizardsunite.com/ja/)、[INGRESS](https://ingress.com/)などのARゲームを開発している企業です。

では、Lightshipは何が凄いのかというと、以下の3つの機能強化が図られています。

* リアルタイムマッピング
* セマンティックセグメンテーション
* マルチプレイヤー

## リアルタイムマッピング
リアルタイムマッピングはスマートフォンのカメラに写された壁や建物などの物理的な世界を機械的に読み取る機能です。
この機能を使用すると永続的にリアルタイムなマップが作成され、仮想オブジェクトに対してより現実的な反応を起こさせることができます。
例えば、ユーザが投げたバーチャル上のボールが現実に存在する壁にぶつかって跳ね返り地面に落ちる、といった物理の法則を実現することができます。
![dice-outdoors.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122485/a64b32a1-6300-b148-a6da-dcfdd5cf14a9.gif)


## セマンティックセグメンテーション
セマンティックセグメンテーションは地面、空、建物など空間を区別する機能です。
この機能を使用すると仮想オブジェクトを特定の空間にだけ適用することができます。
例えば、「空」のセグメンテーションにだけ仮想オブジェクトを適用すると、大きなARオブジェクトを地平線上に表示させたり、建物や地面によって仮想オブジェクトを適切に遮らせることができます。
![semantic-segmentation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122485/11706dee-f91c-83fc-dd62-b52197ea61e1.gif)

## マルチプレイヤー
マルチプレイヤーはその名の通り最大8人のプレイヤーが同時に同じ現実世界の空間で同じAR体験を共有できる機能です。いわゆるマルチプレイが実現できます。
![multiplayer.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122485/bdd01ece-5b17-3c05-ce3b-30705b824b60.gif)

# Lightshipの特徴
LightshipはLiDARスキャナーのような一部の超高性能なデバイスに搭載されているカメラを必要とはせず、一般的なカメラに搭載されているRGBカラーセンサーを利用して拡張現実を映し出します。
つまり、スマートフォンさえあれば誰もがLightshipで作成されたARアプリを利用できます。

スマートフォン上で描いた仮想オブジェクトは自分の動作に合わせて、インタラクティブに形や色を変えながら空間上に現れます。
その仮想オブジェクトに近づけば近くにあるように映り、離れれば遠くにあるように映ります。
そして、第3者のスマートフォンを通じても表示・共有されます。

<iframe width="560" height="315" src="https://www.youtube.com/embed/TWss6XPfSSk" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

また、LightshipにはP2P型のメッセージ機能とバックエンドのサーバ機能が内臓されます。
これにより複数人でのマルチプレイが可能となり、仮想オブジェクトを一緒に触れたり動かしたり色を足したりすることができます。
ARアプリでのマルチプレイはユーザに今までにない全く新しい体験と言えます。

<iframe width="560" height="315" src="https://www.youtube.com/embed/H5nLq-TEldM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# Lightshipの今後
Lightshipは仮想測位システム（VPS）と正確な位置情報を提供し、世界中で利用できるAR体験を作り出すことができる高度なツールとして、いずれ一般公開されると考えられます。
今後、今までにないARを活用したゲームやサービス、エンターテインメント、アート、ARを組み合わせたテクノロジーが作り出されるでしょう。

# 出典
[Niantic Lightship](https://niantic.dev/)
[Niantic blog](https://nianticlabs.com/blog/lightship/?hl=ja)
AtCoder Beginner Contest 216 バーチャル参戦記

# AtCoder Beginner Contest 216 バーチャル参戦記

58:40でABCDE完. 参加できてたらパフォ1486だった模様. レーティング上がってたな、惜しい.

## [ABC216A - Signed Difficulty](https://atcoder.jp/contests/abc216/tasks/abc216_a)

3分で突破. 書くだけ.

```python
X, Y = map(int, open(0).read().split('.'))

if 0 <= Y <= 2:
    print('%d-' % X)
elif 3 <= Y <= 6:
    print('%d' % X)
elif 7 <= Y <= 9:
    print('%d+' % X)
```

## [ABC216B - Same Name](https://atcoder.jp/contests/abc216/tasks/abc216_b)

3分半で突破. ダブりチェックと言えばセット.

```python
N = int(input())

t = set()
for _ in range(N):
    S, T = input().split()
    t.add(S + ' ' + T)

if len(t) != N:
    print('Yes')
else:
    print('No')
```

## [ABC216C - Many Balls](https://atcoder.jp/contests/abc216/tasks/abc216_c)

5分で突破. 見た瞬間に逆向きにやれば最短が作れると思いました. なので、逆向きにやって、反転させて答えとして出力しておしまい.

```python
N = int(input())

a = []
while N != 0:
    if N % 2 == 0:
        a.append('B')
        N //= 2
    else:
        a.append('A')
        N -= 1
print(*reversed(a), sep='')
```

## [ABC216D - Pair of Balls](https://atcoder.jp/contests/abc216/tasks/abc216_d)

15分半で突破. ナイーブに書くと TLE するのは火を見るよりも明らか. 新しい色は今取り出して捨てた筒からしかでてこないということを大事にし、その2つの筒から新しく先頭になったボールと、一致する先頭のボールがあるのであればその筒番号が O(1) で判明するように実装しました.

```python
from sys import stdin
from collections import deque

readline = stdin.readline

N, M = map(int, readline().split())
a = [None] * M
for i in range(M):
    k = int(readline())
    a[i] = deque(map(int, readline().split()))

q = deque(range(M))
t = {}
while q:
    i = q.popleft()
    if len(a[i]) == 0:
        continue
    x = a[i].popleft()
    if x not in t:
        t[x] = i
        continue
    q.append(i)
    q.append(t[x])
    del t[x]

if all(len(d) == 0 for d in a):
    print('Yes')
else:
    print('No')
```

## [ABC216E - Amusement Park](https://atcoder.jp/contests/abc216/tasks/abc216_e)

31分半で突破. 素直に一番満足度が高いアトラクションに乗って、満足度を1下げるのループをシミュレーションするのは K≤2×10<sup>9</sup> から TLE するのは明らか. ざっくりとどの満足度まで下がるまで乗り倒せばいいかをにぶたんで求めて、余った部分は素直にシミュレーションすれば TLE しないだろうというあまり厳密ではない考察をして、書いて出したら通った. なお、最初は必ずK回乗る実装になっていて、入出力例2に救われた. 危ない.

```python
from heapq import heappop, heappush

N, K, *A = map(int, open(0).read().split())


def is_ok(n):
    result = 0
    for a in A:
        if a <= n:
            continue
        result += a - n
    return result <= K


ok = 10 ** 10
ng = 0
while ok - ng > 1:
    m = ng + (ok - ng) // 2
    if is_ok(m):
        ok = m
    else:
        ng = m

result = 0
n = 0
t = []
for a in A:
    if a <= ok:
        heappush(t, -a)
        continue
    heappush(t, -ok)
    result += a * (a + 1) // 2 - ok * (ok + 1) // 2
    n += a - ok
for _ in range(K - n):
    x = -heappop(t)
    if x < 0:
        break
    result += x
    heappush(t, -(x - 1))
print(result)
```
vueでvue-pdfを使う時にしたエラーの対処

2021/9/14時点の対応

■[SyntaxError: Unexpected token <]の対処法

```
// ver4.3.0時点での公式のバグらしい
.\node_modules\vue-pdf\src\vuePdfNoSss.vue:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){<style src="./annotationLayer.css"></style>

SyntaxError: Unexpected token <
```

1. ./plugins/vue-pdf.jsを作成

```
import Vue from 'vue'
import pdf from 'vue-pdf'

Vue.component('pdf', pdf)

export default {
    //
}
```

2.main.jsに追記

```
import Vue from 'vue'
import App from './App.vue'
import vuetify from './plugins/vuetify'
import router from './route'
import store from './store/store'
import pdf from './plugins/vue-pdf.js' // pluginsフォルダのvue-pdf.jsを指定

Vue.config.productionTip = false


// 定期的なセッション更新処理を稼働
polling.methods.refreshSession()

new Vue({
    router,
    vuetify,
    pdf,
    store,
}).$mount('#app')
```




■[TypeError: Cannot read property 'catch' of undefined]の対処法

```
// このバージョンならエラーが出ない
"pdfjs-dist": "2.5.207",
"vue-pdf": "4.2.0"
```
ブラウザ上でcsvやxlsx等のシートを読み込む

csvデータをアップロードするための入力方法を色々まとめてみる。

## csvファイル

```js
const chardet = require("chardet")
const iconv = require("iconv-lite")

var csvReader = new FileReader();
csvReader.onload = (e) => {
  let data = new Uint8Array(e.target.result);
  let encoding = chardet.detect(data);
  let csv = iconv.decode(data, encoding);
  document.getElementById("<text field>").value = csv;
};

document.getElementById("<file filed>").addEventListener("change", (e) => {
  let sheetFile = e.target.files[0];
  csvReader.readAsArrayBuffer(sheetFile);
});
```

[chardet](https://www.npmjs.com/package/chardet)と[iconv-lite](https://www.npmjs.com/package/iconv-lite)を使うことで文字コードによらずに読み込めるようにしている。
ファイルが読み込まれたらFileReaderでバッファーとして読み込んで、それをcsvにしてテキストフィールドに入力する。

## xlsxファイル

```js
import XLSX from "xlsx"

var xlsxReader = new FileReader();
xlsxReader.onload = (e) => {
  let data = new Uint8Array(e.target.result);
  let workbook = XLSX.read(data, {type: "array"});
  let sheetName = document.getElementById("<text filed to input a sheet name>").value;
  let csv = XLSX.utils.sheet_to_csv(workbook.Sheets[sheetName]);
  document.getElementById("<text field>").value = csv;
};

document.getElementById("<file filed>").addEventListener("change", (e) => {
  let sheetFile = e.target.files[0];
  xlsxReader.readAsArrayBuffer(sheetFile);
});
document.getElementById("<text filed to input a sheet name>").addEventListener("change", (e) => {
  let sheetFile = document.getElementById("<file filed>").files[0];
  xlsxReader.readAsArrayBuffer(sheetFile);
});
```

[xlsx](https://www.npmjs.com/package/xlsx)で読み込みと変換を行っている。上のcsvReaderと使い分けるならファイルのmimeタイプで分岐させる。xlsx, xlsm(マクロ入)はそれぞれ以下。

- application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
- application/vnd.ms-excel.sheet.macroEnabled.12

ただしエクセルをインストールしているとcsvのmimeタイプがapplication/vnd.ms-excelという2003年以前のエクセル(.xls)のものに変わってしまうので.xlsを入力する場合は注意。

## Google スプレッドシート

```js
import Axios from "axios"

document.getElementById("<text filed to input a sheet url>").addEventListener("change", (e) => {
  let spreadsheetId = /(?<=\/spreadsheets\/d\/).*?(?=\/)/.exec(e.target.value)[0]
  let sheetUrl = "https://docs.google.com/spreadsheets/d/" + spreadsheetId + "/export"

  Axios.get(sheetUrl, {params: {format: "csv"}}).then((res) => {
    document.getElementById("<text field>").value = res.data;
  }).catch((err) => {
    outputErrors(err);
  });
});
```

Googleスプレッドシートは
https://docs.google.com/spreadsheets/d/{spreadsheetId}/export?format={format}
でファイルをダウンロードできる。テキストフィールドには共有リンクを渡す。
[jenkins-cli] Jenkins へファイルを POST する


# 概要

CLI で Jenkins ジョブへファイルを渡す方法.


### 手順

#### 1. 「ファイル」形式のパラメータを定義する

ここでは「ATFILE」というパラメータ名にする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/ec006b01-eef3-6166-84eb-54378add1dd5.png)


#### 2. 「ジョブ名/buildWithParameters?」に「--form ATFILE=@ファイルパス」を付与する

「/tmp/a.txt」を Jenkins ジョブに渡したい場合

```bash
$ curl -X POST --user 'ユーザ名:APIトークン' \
       'http://IP:PORT/job/ジョブ名/buildWithParameters?' \
       --form ATFILE=@/tmp/a.txt
```

以上.
[備忘] Jenkins CLI の使用例


# 概要

Jenkins 2.x 系で動作実績がありの Jenkins CLI の一覧である.

Jenkins バージョンによって エンドポイントが異なるのか知らないが、
Web 上の情報では動かないことが多々あったので、あくまでも参考程度に.

|コンテンツ|一言|
|:--|:--|
|[[jenkins-cli] Jenkins へファイルを POST する](https://qiita.com/robozushi10/items/cc9e89b80d27014150af)|Web上には各種方法があるが、私の場合はこの方法のみ成功した|
|[[jenkins-cli] Jenkins の実行済みジョブの全ジョブ番号を得る](https://qiita.com/robozushi10/items/d698706db6a304241f2f)|ジョブ番号一覧が欲しい、という状況は滅多にないとは思うが..|
|[[jenkins-cli] Jenkins の実行済みジョブからパラメータを抽出する](https://qiita.com/robozushi10/items/eaa514f5703b3980bad7)|実行記録を収集することになり必要になった|
Azure Service Bus (Queue) へ一度に送信できるメッセージの上限

Azure Service Bus Queue の高負荷試験を考えていた時に遭遇したエラーおよび上限について、残しておきます。

# 事象

[こちら](https://docs.microsoft.com/ja-jp/azure/service-bus-messaging/service-bus-dotnet-get-started-with-queues)のドキュメントを参考に、Service Bus へのメッセージ送信を検証していたところ、コードに修正を加えて 1度に 5,000件程度のメッセージを送信しようとしたところ、下記の例外が返ってくることを確認。

> The service was unable to process the request; please retry the operation. For more information on exception types and proper exception handling, please refer to http://go.microsoft.com/fwlink/?LinkId=761101 Reference:<Reference GUID>, TrackingId:7878a908000001ff001dfb5a60e6fafa_G4_B12, SystemTracker:<Service Bus Name>:<Queue Name>, Timestamp:2021-07-08T13:18:00 (GeneralError)

# 原因

何かしらの上限系が原因かと想定して公式ドキュメントも確認したのですが、いまいち分からず…。サポートに問い合わせたところ、下記のドキュメントに記載の制限だそうです。

https://github.com/Azure/azure-service-bus/issues/397

> After additional testing, it seems that Basic and Standard are 4500. Premium seems to be ~15885.

Basic および Standard SKU では 4,500件とのこと。また、Premium では 15,885 件のようですが、実際には 16,000件まで送ることができました。

# 対処

対処としては、残念ながら上記の上限以内の件数で送信するしかないようです。4,500件以上送る場合は、複数回に分けて送る必要がありますね。

-----

※なお、本件の情報については、Microsoft社サポートの方にも公開許可を得ております。ありがたや🤗
【忙しい人のための】Azureの基礎第5部【Azureの認証・ガバナンス・プライバシー・コンプライアンス】

AzureについてMS Learnで勉強される場合、第5部は1時間32分のラーニングパスになっています。
ここでは、自身の勉強の復習も兼ねて、MS Learn Azureの基礎第5部の要点をまとめておきますので、Azureの情報を素早く知りたいという方の参考になれば幸いです。
自身の勉強の力点を踏まえて記述するので、詳細な情報を得たい方はMS Learnにアクセスください。

本家様

https://docs.microsoft.com/ja-jp/learn/paths/az-900-describe-identity-governance-privacy-compliance-features/

第4部はこちら

https://qiita.com/enurinri/items/dece9d9020bf93315046

# AzureのIDサービスによるアクセス制御
前提として、
**認証**とは、リソースにアクセスする個人やサービスの身元を特定することで、
**承認**とは、認証された個人やサービスに付与されるアクセス権を確認すること。

また、**多要素認証**とは、

* ユーザが知っていること：メールアドレス・パスワード etc
* ユーザが持っているもの：ユーザが所持するデバイスにコードを送信 etc
* ユーザ自身の特徴：指紋 etc

の中から２つ以上のカテゴリを組み合わせて、認証を行うこと。

## Active Directory
Active Directoryは、オンプレミス環境で、自分の組織によって管理されるIDやアクセス管理サービスを提供。

## Azure AD (Azure Active Directory)
Azure ADは、クラウドベースで提供されるActive Directory機能。
不審なサインイン試行を検出するとともに、組織におけるIT管理者・アプリ管理者・ユーザ・オンラインサービスのサブスクライバーを対象とした、認証・**シングルサインオン**・アプリケーション管理・Microsoft Intuneによるデバイス管理を行う。
シングルサインオンとは、単一のIDとパスで複数のサービスにアクセスできるようになること。

### Azure AD Multi-Factor Authentication
Microsoftによる多要素認証機能提供サービス。
Azure ADやOffice 365の多要素認証でも利用。

### 条件つきアクセス
IDの**シグナル**に基づいてリソースへのアクセスを許可すること。
シグナルとは、ユーザが誰であるか・ユーザがどこにいるか・ユーザがどのデバイスでアクセスしているのかという情報。
Azure ADでも利用。

# Azureでのクラウドガバナンス戦略
## ロールベースのアクセス制御(RBAC)
RBACは、指定したAzure ADのユーザやグループに対して、実行可能な操作や管理範囲のスコープ(サブスクリプションやリソースグループなど)を割り当てることで、Azureリソースに対するアクセス管理を制御可能。

## リソースロック
リソースロックは、Azureリソースを誤って削除や変更することを防ぐ設定。

## タグ
タグは、Azureリソースに関してメタデータを付す(印をつける)ことで、リソースの集計や分類を効率化する方法。
Power Shellや　Azure Portalで追加・変更・削除可能。
Azure Policyによりタグ付けルールを適用可能。

## Azure Policy
Azure Policyは、Azureリソースを制御または監視するポリシー(方針)の作成・割り当て・管理を行う。
個別のポリシーと、関連するポリシーのグループ(イニシアティブ)を作成。
実装については、ポリシー定義を作成→定義をリソースに割り当て→評価の結果を確認、の流れ。

## Azure Blueprints
Azure Blueprintsは、組織で必要なガバナンスツールや、コンプライアンスを遵守した開発環境や運用環境のために標準のAzureリソース群を用いた構成を定義可能。
定義した構成を繰り返し適用可能なため、開発者は迅速に新環境を構築してデプロイ可能。

## クラウド導入フレームワーク
1. 戦略定義：クラウド移行の理由と目的を明確化
1. 計画作成
1. 組織の準備：クラウド内の環境作成
1. クラウド導入：移行＆イノベーション
1. クラウド環境のガバナンスと管理

### サブスクリプションガバナンス戦略
サブスクリプション(デプロイの境界)を分割統治する目的として

* 課金や経費の切り分け
* アクセス制御
* サブスクリプションの制限：Azure ExpressRouteの回線が最大10であることなど

が存在。

# Azureのプライバシー・コンプライアンス・データに関する保護方針
## Data Protection Addendum
Data Protection Addendumでは、オンラインサービスのデータ処理及びセキュリティに関する条項を定義。

## トラストセンター
トラストセンターは、Microsoftのセキュリティ・プライバシー・コンプライアンスに関する[総合情報サイト](https://www.microsoft.com/ja-jp/trust-center)
企業の法務部やコンプライアンスコミュニティにも向けている。

## Azure コンプライアンスドキュメント
Azure コンプライアンスドキュメントは、Azureの法律と規制に関する基準やコンプライアンスについて詳細に記された[ドキュメント](https://docs.microsoft.com/ja-jp/azure/compliance/)。
Azureサブスクリプションに適用可能な標準のBlueprintが存在。

## Azure Government
Azure Governmentは、アメリカの連邦政府機関・州政府・地方自治体とそのパートナーのみが利用可能な特殊リージョン。

## Azure Germany(ソブリン)
Azure Germanyは、イギリスも含めてEU圏内でビジネスを行う人なら誰でも利用可能なリージョン

## Azure China 21Vianet
Azure Chinaは、中国でAzureの名前で提供される中国政府の規制に準拠したクラウドサービスであり、21Vianetによって運用される。
[jenkins-cli] Jenkins の実行済みジョブの全ジョブ番号を得る


# 概要

滅多に無いとは思うが、どうしても実行済みの全ジョブ番号を取り出す必要があった.[^1]

このとき、`job/ジョブ名/api/json` だと直近 100件ほどの情報しか取得できていなかった.

`job/ジョブ名/api/json?tree=allBuilds[number]&depth=1` で全件取り出せた.

```bash
$ curl -X GET --user '<ユーザ名>:<APIキー>' \
   "http://<IP>:<PORT>/job/ジョブ名/api/json?tree=allBuilds[number]&depth=1" | \
  jq -r '.allBuilds[].number'
```

## 参考にした情報

・https://stackoverflow.com/questions/48921231/how-to-retrieve-all-previous-builds-for-a-jenkins-job-through-the-api


[^1]: このとき、「最終ジョブ番号」を求めてから 1〜「最終ジョブ番号」とする方法では都合が悪かった
githubでプルリクエストを作った人を自動でassigneesにする

# githubでプルリクエストを作った人を自動でassigneesにする

## はじめに
こんにちは。webエンジニア社会人をしている [ningenMe](https://twitter.com/ningenMe) です。

タイトル通り、assignees設定を自動化します。  
下記のことを行います。

- プルリクエストを作った人を自動で `assignees` にする
- github actionsで処理を行う
- yamlではパースなどを自分で書かずに、[GitHub Actions公式](https://github.com/actions) のものを使う

## GitHub
実際に動くソースはこちら

- [assignees-sample.yml](https://gist.github.com/ningenMe/3380446f230ad2919e4f5d759961a106)

```yaml
name: assignees-sample

on:
  pull_request:
    branches: [ main ]

jobs:
  assignees:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - uses: actions/github-script@v4.1.0
        if: github.event_name == 'pull_request'
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            github.issues.addAssignees({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              assignees: `${{ github.actor }}`
            });
```

### UI上でどうなるか
botがassignしてくれます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246454/59d65a1f-d65d-101e-ae92-03f2b7083a77.png)

PRの右側らへんを見るとassigneesが付いているのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246454/a84b32af-6d51-d433-2ff6-ea21916ac693.png)


## 説明
説明と言うほど説明することはないです。  
[actions/github-script](https://github.com/actions/github-script) という便利なものがあるのでそれを活用します。
バージョンは 2021/09/14 時点での最新のものを記載しています。  
実際に使う場合は https://github.com/actions/github-script/tags で最新を確認すると良いと思います。

## 先行研究
- [GitHub Actions でプルリクエストの自動アサインをする](https://qiita.com/hkusu/items/39eb92dbd4d6db8a14d8)
- [PR の assignees が空だったときに自動アサイン](https://zenn.dev/snowcait/articles/d6bc5eafd8ab75)

一応上記とはやり方が別になっていると思います。大した処理ではないのでなんでも良い気はします。


## さいごに

超ライトな記事でした。  
ではでは。
[jenkins-cli] Jenkins の実行済みジョブからパラメータを抽出する


# 概要

とある Jenkins ジョブは、入力パラメータとして以下を持つものとする.

|パラメータ名|型|用途|
|:--|:--|:--|:--|
|UPLOAD_FILE|文字列|Jenkins ジョブに投じられるファイル|
|FILEPATH|文字列|上記 UPLOAD_FILE の元パス情報|

本記事では、Jenkins CLI を使って、
実行済みジョブからこの「FILEPATH」に設定された値を取り出す例である.

なお、試行錯誤したので、参考にしたサイトなどはメモできなかった.


### 手順

#### 1. GET「ジョブ名/ジョブ番号/api/json?build&depth=1」を発行する

本例の場合は以下である.

```bash
$ curl -X GET --user 'ユーザ名:APIキー' \
  'http://IP:PORT/job/ジョブ名/ジョブ番号/api/json?build&depth=1'
```

#### 2. 上記 1 の応答が得られる

今回取り出したい値(下記🛑) が存在している.

```json
{
  "_class": "hudson.model.FreeStyleBuild",
  "actions": [
    {
      "_class": "hudson.model.ParametersAction",
      "parameters": [
        {
          "_class": "hudson.model.FileParameterValue",
          "name": "UPLOAD_FILE"
        },
        {
          "_class": "hudson.model.StringParameterValue",
          "name": "FILEPATH",
      🛑  "value": "/fileserver/dir/a.txt"
        }
      ]
    },
    {
      "_class": "hudson.model.CauseAction",
      "causes": [
        {
          "_class": "hudson.model.Cause$UserIdCause",
          "shortDescription": "Started by user robozushi10",
          "userId": "robozushi10",
          "userName": "robozushi10"
        }
      ]
    },
    略
```

#### 3. JSON を解析して値を取り出す

苦行だが、本例の場合に jq コマンドで取り出すと次のようになる.
(Python や Ruby といった 高級言語で取り出す方が楽だと思う)

```bash
$ curl -X GET --user 'ユーザ名:APIキー' \
  'http://IP:PORT/job/ジョブ名/ジョブ番号/api/json?build&depth=1' | \
    jq -r '.actions[] | select( ._class == "hudson.model.ParametersAction" ) | \
     .parameters[] | select( .name == "FILEPATH" ) | .value'
```

　

以上
type-graphqlからのserver+client

# 目標
- type-graphqlでサーバ側のスキーマ定義
- expressで公開
- clientは自動生成
- subscriptionは対象外

# サーバ構築
## type-graphql インストールする
https://typegraphql.com/docs/installation.html

## Resolver作る
公式ドキュメントそのまま

``` resolver.ts
@InputType()
class NewRecipeInput {
  @Field()
  @MaxLength(30)
  title: string;

  @Field({ nullable: true })
  @Length(30, 255)
  description?: string;

  @Field(type => [String])
  @ArrayMaxSize(30)
  ingredients: string[];
}

@ArgsType()
class RecipesArgs {
  @Field(type => Int)
  @Min(0)
  skip: number = 0;

  @Field(type => Int)
  @Min(1)
  @Max(50)
  take: number = 25;
}

@Resolver(Recipe)
class RecipeResolver {
  constructor(private recipeService: RecipeService) {}

  @Query(returns => Recipe)
  async recipe(@Arg("id") id: string) {
    const recipe = await this.recipeService.findById(id);
    if (recipe === undefined) {
      throw new RecipeNotFoundError(id);
    }
    return recipe;
  }

  @Query(returns => [Recipe])
  recipes(@Args() { skip, take }: RecipesArgs) {
    return this.recipeService.findAll({ skip, take });
  }

  @Mutation(returns => Recipe)
  @Authorized()
  addRecipe(
    @Arg("newRecipeData") newRecipeData: NewRecipeInput,
    @Ctx("user") user: User,
  ): Promise<Recipe> {
    return this.recipeService.addNew({ data: newRecipeData, user });
  }

  @Mutation(returns => Boolean)
  @Authorized(Roles.Admin)
  async removeRecipe(@Arg("id") id: string) {
    try {
      await this.recipeService.removeById(id);
      return true;
    } catch {
      return false;
    }
  }
}
```

## express-graphqlで公開する

``` express-app.ts

import { graphqlHTTP } from "express-graphql";
import { buildSchemaSync } from "type-graphql";

const app = express();
const schema = buildSchemaSync({
  resolvers: [RecipeResolver]
});

app.use("/graphql", graphqlHTTP({ schema: schema, graphiql: true }));

```

node + express + graphql subsctiption

# client側のコード生成

## ↑のschemaを出力する

``` write_schema.ts
const schema = buildSchemaSync({
  resolvers: [RecipeResolver]
});
const schema_str = printSchema(schema);
fs.writeFileSync("schema.graphql", schema_str);
```
## documentを作る
``` documents/recipe.graphql
query getRecipe($id: String!) {
  recipe(id: $id) {
    id
    title
    description
    creationDate
    ingredients
  }
}

```

## graphql code generatorのインストール
https://www.graphql-code-generator.com/

plugin いっぱいある
https://www.graphql-code-generator.com/docs/plugins/index
以下を今回は使う、対象のプラグインをインストールしておく
- typescript
- typescript-operations
- typescript-graphql-request

設定ファイル

``` codegen.yml
schema: schema.graphql
documents: "documents/*.graphql"

generates:
  dist/client_sdk.ts:
    plugins:
      - typescript
      - typescript-operations
      - typescript-graphql-request
```
## 生成
clientコードが生成される
npx graphql-codegen --config codegen.yml

## クライアント側でのデータ取得
``` client.ts
import { getSdk } from "client_sdk.ts";
const client = new GraphQLClient("/graphql");
const sdk = getSdk(client);
const recipe = await sdk.getRecipe('aaa')
```

# あとがき
rest apiに比べて、やはり面倒くさいが、型チェックなどをしっかり作ってくれる安心感がある
client sdkを自動生成してくれるのはかなり便利
documentsさえ生成出来れば完璧なのだが。。
[Java基礎⑦]文字列の比較　比較演算子とequals メソッドの違い　[paiza]スキルチェック見本問題 単純な条件分岐 Java編

<h2>初めに</h2>

今回、以下の問題に挑戦し、Javaでの文字列と文字列の比較について学びました。
普通に比較演算子を使用したところ不正解になってしまいました。
（以下は見本問題のため、問題、解答コードの公開は自由です。）

https://paiza.jp/works/mondai/conditions_branch/conditions_branch__simple_step1

```
文字列Sが与えられます。Sがpaizaと一致する場合はYESを、
一致しない場合はNOを出力してください。
```

<h2>誤答　:point_up:文字列の比較演算子に注意！</h2>

標準入力をlineで受け取り、＝＝の比較演算子を使い、
"paiza"と一致するかをif文で条件分岐させました。
しかしこれだと不正解です。
(line == "paiza")が成立してくれません。

```java:
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        if(line == "paiza"){
            System.out.println("YES");
        }else{
            System.out.println("NO");
        }
    }
}
```

<h3>問題点　比較演算子ではオブジェクトを比較する</h3>

問題は```(line == "paiza")```の箇所です。
配列や文字列を比較する場合、比較演算子を使用すると、
同じオブジェクトを参照してればtrue、違えばfalseが返ってきます。

```java:
//同じオブジェクトを参照している場合には、
//比較演算子で比較するとtrueが返って来る
String line1 = "paiza";
String line2 = line1;
if(line1 == line2) → true
```

今回比較すべきなのは、「値」です。
入力された「値」がpaizaに等しいかどうかです。


<h2>使うべきは equalsメソッド</h2>

現状、```(line == "paiza")```としてる箇所は、
```if (line.equals("paiza")```とすることで、値の比較になります。

<h3>正解のコード</h3>

```java:
import java.util.*;


public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        if(line.equals("paiza")){
            System.out.println("YES");
        }else{
            System.out.println("NO");
        }
    }
}
```

<h2>参考にしたサイト</h2>


https://www.javadrive.jp/start/string/index4.html
【JavaScript】ECMAScriptモジュール③

# 概要
[...【JavaScript】ECMAScriptモジュール②](https://qiita.com/andota05/items/22676d733bf1b4db9809)の続きです。
[...【JavaScript】ECMAScriptモジュール①](https://qiita.com/andota05/items/d91086102326b2bd3dbb)もあります。

JavaScriptを学習、理解を深めるため「[JavaScript Primer 迷わないための入門書](https://jsprimer.net/)」を読み、
理解した内容等を記載していく。

[JavaScript入門一覧](https://qiita.com/andota05/items/22fae452225b785fd405)に他の記事をまとめています。

# ECMAScriptモジュール(その他構文)
これまで記載したECMAScriptモジュールについて、その他の構文についても記載する。
※下記「動作環境情報」を参考にし、開発者コンソールで結果を確認してください

<details><summary>動作環境情報はコチラ</summary><div>

**【環境】**
PC：Mac
エディタ：Visual Studio Code
プラグイン：`Live Server`というVisual Studio Codeのプラグインを使用し、サーバ環境を用意。
開発者コンソール：GoogleChrome

**【登場ファイル】**
export.js：エクスポートに関するコードを記述した`エクスポート側`のファイル
import.js：インポートに関するコードを記述した`インポート側`のファイル
index.html：「import.js」を使用、および開発者コンソールで確認する際に開くファイル

**【★ポイント】**
index.htmlの`headタグ`内に`<script src="import.js" type="module"></script>`のように記述する

```index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript入門</title>
    <script src="import.js" type="module"></script>
</head>

<body>
</body>

</html>
```

※最終的に以下のような構成になる。
(任意の場所に「js」フォルダを作成および、フォルダに上記3ファイルを作成・配置する)
![スクリーンショット 2021-09-13 17.47.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640274/92a261d4-1f95-d668-e72b-ab5da7211eb8.png)

</div></details>

## 再エクスポート
* 別のモジュールをインポートし、再度自身のファイル内でエクスポートすること。
* エクスポートされた複数のモジュールをまとめたモジュールを作成する際などに使用する。
* 再エクスポート方法は`export モジュール名 from モジュールパス;`と記載する。

```export.js
// 名前つきエクスポートを再エクスポート
export { foo, bar } from './export1.js';

// すべての名前つきエクスポートを再エクスポート
export * from './export1.js';

// ..などその他にも様々なパターンで活用可能
```

## すべてをインポート
* すべての名前つきエクスポートをまとめてインポートする方法
* モジュールごとの`名前空間`となるオブジェクトを`import as`構文で宣言する。
* 変数や関数にアクセスす際は名前空間オブジェクトのプロパティを使用する。
* `default`という固有名を使用するとデフォルトエクスポートにもアクセス可能

```export.js
// wordという変数を定義
const word = 'word';

// helloという関数を定義
function hello() {
    console.log('Hello JavaScript');
};

//　デフォルトエクスポート用の関数を定義
export default function defaultFunc() {
    console.log('defaultFunc');
}

// 「word」「hello」を名前つきエクスポート
export { word, hello }; 
```

```import.js
// 名前空間となるオブジェクトをimport as構文で宣言
import * as exportModule from './export.js';

console.log(exportModule.word); // => word
exportModule.hello();           // => Hello JavaScript
exportModule.default();         // => defaultFunc
```

## 副作用のためのインポート
* 単にモジュールのコードを実行し、変数や値など参照する必要のない場合などに使用(何かしらのセットアップするなど)
* `import モジュールパス;`でモジュールファイル全体をインポートする。

```export.js
console.log('毎回このメッセージを表示する!');
```

```import.js
// import モジュールパス;で副作用のためのインポート
import './export.js' // => 読み込んだ時点で「毎回このメッセージを表示する!」が表示される
```
【Swift】ボイスチェンジャーアプリでBluetoothイヤホンを使用して録音再生できるようにしてみた

「おばけだぞう」と子供がしつこく言うので、変声機アプリを作ってみた。

#サンプル画像：
![RPReplay_Final1631489151.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/715627/bd07fb63-7aa5-59e7-49b7-5db7208e06a7.gif)






#アプリ概要：
-「Record」ボタンで音声を録音
-スライダー「Speed」「Pitch」、スイッチ「Echo」「Reverb」で声のエフェクトをかける
-「Play」ボタンで再生、モーダルに画面遷移してお化けアイコンの表示

参考サイト:
[[Swift4.2]蝶ネクタイ型変声期作ってみた](https://qiita.com/tosh_3/items/95e9e41279ba0ffcd3f4)

#課題:
再生時に「音量」が上がらない。
Bluetoothイヤホンを接続すると「録音・再生」が機能しない。

下記のサイトを参考：
[AVAudioSessionで録音する際に、音はbluetoothイヤホン、マイクはデバイスマイクを使いたい](https://zenn.dev/yoonchulkoh/articles/073bdcd1f7f818)


追加したコード。

```Audio.swift

try session.setCategory(
                .playAndRecord,
                mode: .default,
                // オプションの内容は[]で閉じると良い
                options: [.defaultToSpeaker,      // マイク/レシーバーからマイク/スピーカーに変更
                          .allowAirPlay,          // AirPlayデバイスにストリーミング
                          .allowBluetoothA2DP])   // Bluetoothイヤホンで録音再生可能

```




githubにコード全文を載せています。
(https://github.com/r-tattsu2060/Voicechange/tree/main/Voicechange)
スクレイピングの前提

#はじめに
スクレイピングによるアクセスが膨大だと、相手のサーバに大きな負荷を掛けることになります。 これが業務妨害に該当するとして、逮捕者が出た例もあります。 アクセスの頻度を抑え、相手サーバの負荷が過大にならないように注意しなければいけません。

#スクレイピングを始めるにあたって
スクレイピングの常識について少し触れていきましょう。
動画は3つあるので、この３つを見ていきましょう。

・ [スクレイピングとは？（動画）](https://youtu.be/PbQFVZTF-Bk)<iframe width="100%" height="506" src="https://www.youtube.com/embed/PbQFVZTF-Bk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
・[スクレイピングの準備（動画）](https://www.youtube.com/watch?v=6I8zt854xt4)
<iframe width="100%" height="506" src="https://www.youtube.com/embed/6I8zt854xt4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
・[法律関係（動画）](https://www.youtube.com/watch?v=tqzgRxYNfno&feature=youtu.be)
<iframe width="810" height="506" src="https://www.youtube.com/embed/tqzgRxYNfno" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

#スクレイピングをする上での知識
また、スクレイピングをするにあたって、HTMLの構造とタグの仕組みなどを理解すると、スムーズにスクレイピングができるようになるのでこちらも確認していきましょう。

・[外)GETとPOST](https://www.youtube.com/watch?v=MRFh4tGdns4)
・[外)HTMLとは](https://www.youtube.com/watch?v=2JLiGSUohEo)
・[外)タグ](https://youtu.be/rCUBR2ZL4m4)
【Python】ターミナル上でさっとカラーコード色を確認する方法

Pythonでターミナル上でさっとカラーコード色を確認したいな、と思うことがあったので対応ライブラリを探して試しに使ってみた。

# 利用ライブラリ

下記2つのライブラリを利用 (`pip install colour colr`)

- **[colr](https://github.com/welbornprod/colr)**  
  ターミナル上で文字を指定色で出力可能にするライブラリ
- **[colour](https://github.com/vaab/colour)**  
  色情報関連のユーティリティーライブラリ  
  (カラーコード変換、グラデーション色生成等)

# ターミナル上での色表示実行

colrライブラリの`color()`関数を利用することで、ターミナル上で色を表示できる。
`fore`引数指定で文字色、`back`引数指定で文字背景色を変更可能。

### 単純な表示方法確認

```python:simple_color_demo.py
from colr import color

# 文字列で直接色指定
print(color("hello world!!", fore="red", back="white"))
# 256色を数値(0 - 255)で指定
print(color("hello world!!", fore=20, back=82))
# カラーコード指定
print(color("hello world!!", fore="#ffff00", back="#ff0000"))
```

![simple_color_demo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138429/62ca5b6c-9982-c62e-39ea-6851e89c7cdb.png)


### カラーコード色確認

```python:color_gradient_demo.py
from colour import Color
from colr import color

# 青から赤へのグラデーションを30色生成して対応するカラーコード取得
color_gradient_list = Color("blue").range_to(Color("red"), steps=30)
hexcolor_gradient_list = [c.get_hex_l() for c in color_gradient_list]

# 各カラーコードと対応する色を出力
for hexcolor in hexcolor_gradient_list:
    print(hexcolor, color("       ", back=hexcolor))
```

![color_gradient_demo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138429/702aee3b-a1d2-660d-4e1e-3442cedfdbd8.png)
目的であったターミナル上でのカラーコード色の確認ができた。
しかし、ターミナル上では256色までしか表現できないので、一部グラデーションは色が同一になっているっぽい。

### ターミナル上で表現可能な全256色をついでに確認

```python:terminal_all_color.py
from colr import color

for i in range(256):
    print(color("   ", back=i), end="")
print()
```
![terminal_all_color.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138429/92ab94f6-7f89-1c8b-3a58-afe3f73bc1de.png)
DynamicBoneはアタッチした順番によって挙動が変わる場合がある

↓の記事で検証したんですが、同じクラスのコンポーネントの実行順はアタッチした順の逆順になります。
[【Unity】同じクラスのコンポーネントの実行順はアタッチした順の逆順になる説](https://qiita.com/KenCreator/items/2461c588cc32e10d8109)

それだけ聞くと、だから何だって感じなんですが、実はこれがDynamicBoneの挙動に影響する場合があります。
以下のような場合です。

#DynamicBoneで揺らすオブジェクトにDynamicBoneColliderをアタッチする
DynamicBone"A"と"B"があり、"A"にDynamicBoneCollider"C"がアタッチされていて、"B"は"C"と衝突するように設定されています。
そして、"A"に何らかの力が加わって右に揺れた場合を考えてみます。
![DynamicBoneの実行順について_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283994/ea25bff0-91e2-ff38-f048-9cee45eb7890.png)
![DynamicBoneの実行順について_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283994/54ac5151-09e8-bd2c-e0aa-6796078597aa.png)

###"A"が先に実行された場合
まず"A"が先に実行され、右に揺れます。
![DynamicBoneの実行順について_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283994/54ac5151-09e8-bd2c-e0aa-6796078597aa.png)

その後、"B"がコライダーに押しのけられて右に移動します。
![DynamicBoneの実行順について_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283994/27729ab5-cb66-b1a6-eec2-a1db45926d87.png)
これは想定通りの動きですね。

###"B"が先に実行された場合
問題はここからです。

まず"B"が先に実行されます。何の力も加わっていないので、"B"は動きません。
![DynamicBoneの実行順について_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283994/aa1a6105-022b-8181-5f40-11b00a83a7df.png)

その後、"A"が右に揺れます。
![DynamicBoneの実行順について_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283994/2b507d99-db57-83ae-8ef5-0f0c3b041a24.png)
この時、すでに"B"の計算は終わっているので"B"は動きません。
DynamicBoneは毎フレームDynamicBoneの影響を受けていない状態から計算するので、この場合では"B"が"A"の動きに影響されて動くことはありません。
DynamicBoneの子オブジェクトに別のDynamicBoneをアタッチした場合も、このような挙動になります。

これでは困りますね。

#対策
同じクラスのコンポーネントは最後にアタッチしたものから順に実行されるので、コンポーネントをコピーしてから削除してアタッチし直すことで実行順を変えることが出来ます。
先に実行されて欲しいコンポーネントをアタッチし直しましょう。

この挙動の原因が分からなくて２時間くらいのたうち回ったので、この情報が誰かの役に立てば幸いです…
ダブルチェックとクロスチェックに関する参考情報

# はじめに
「ダブルチェック（double-check）」と「クロスチェック（cross-check）」という言葉を使い分けずに使ってしまうことがよくあるために、注意が必要です。自分自身も。
無駄なダブルチェック（トリプルチェック）はやめ、有効なクロスチェックを実施したいと思っています。
ダブルチェックをやるにしても、連続型でやるのか双方向型でやるのかを明確にしようと思います。
ダブルチェックはやるとしても、ツールで実行できないかを検討したほうがよいと感じています。

チェックやレビューのやり方を改善するために、今後自分が参考にする情報をまとめておきます。

# 参考情報
## ダブルチェックとクロスチェックの違い

以下の参考記事でダブルチェックとクロスチェックの違いが述べらています。
ある対象に対して、同じ観点・方法で人を変えてチェックをすることをダブルチェック、観点・方法を変えてチェックをすることがクロスチェックと呼ばれるようです（自分一人でやってもクロスチェックと位置付けられるようです）。

### 参考記事
* @N-Masaya，「「ダブルチェック」と「クロスチェック」の違い」  
https://qiita.com/N-Masaya/items/bc87fc324d7778bef7de
* 喜友紅，「ダブルチェックの意味と効果｜クロスチェックとの違い・医療で使う？」  
https://mayonez.jp/topic/4025
* 佐々木真，「「ダブルチェック」と「クロスチェック」の違い」  
https://wa3.i-3-i.info/diff300check.html

## ダブルチェックの有効性
松村由美さんの「ダブルチェックの有効性を再考する」という資料に、トリプルチェックから、エラー検出率が下がるという研究結果が示されています。
このような現象を、「リンゲルマン効果：社会的手抜き」という言葉で説明されています。

### 参考文献
* 松村由美，「ダブルチェックの有効性を再考する」，平成30年度医療安全セミナー，2018  
https://kouseikyoku.mhlw.go.jp/shikoku/kenko_fukushi/000085434.pdf

### 参考ツイート
また、以下のツイートでも同じようなことが示されています。

https://twitter.com/yossiyosio/status/1176287346334920704


## ダブルチェックの方法
ダブルチェックの方法には「連続型」と「双方向型」がある。「連続型」より「双方向型」のほうが問題の検出率が上がるという調査結果がある。

https://www.nursing-ehime.or.jp/chiebukuro/safety/vol151.html#:~:text=%E3%83%80%E3%83%96%E3%83%AB%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%81%AE%E6%96%B9%E6%B3%95&text=1%E4%BA%BA%E9%80%A3%E7%B6%9A%E5%9E%8B%E3%83%BB%E3%83%BB%E3%83%BB,%E6%96%B9%E5%90%91%E3%82%92%E9%80%86%E3%81%AB%E3%81%99%E3%82%8B%E3%80%82


## 一人HAZOPを組み合わせた効率的な分析作業
一人HAZOPは、有効なクロスチェックとなる可能性が高いです。
ガイドワードにより、視点を変えてチェックしている状態になりやすいです。

### 参考文献
* 小川清, 「一人HAZOPを組み合わせた効率的な分析作業」, WOCS2011 JAXA/IPA, 2011  
https://www.ipa.go.jp/files/000005325.pdf

# 関連記事

https://qiita.com/kazuo_reve/items/c467504084ba3441101b

https://qiita.com/kazuo_reve/items/c1c1d32baed5d60d55c7