OmniAICreator/Qiita-1.07M huggingface dataset:
UITextViewを継承せずにPlaceholderを設定する

# 概要

表題の通り `UITextView` にプレースホルダーを設定していきます。
サブクラスを作って実装する例はいくつかあったので、違う方法で実装していきたいと思います。

1分くらいで読み終わります。恐らく。

# 環境
- Xcode 12.4
- Swift 5.3.2

# GIF
編集状態に入るとプレースホルダーが消え、
編集状態を終えると **文字が未入力の場合は** プレースホルダーが表示される様子です。

|文字入力なし|文字入力あり|
|:---:|:---:|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429630/31a5d027-88ff-9583-bd6b-352348a2ad40.gif" width=400>|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429630/b7b86846-55cc-84bd-fbb8-72fa6e10a522.gif" width=400>|

# 実装コード
編集状態が切り替わった際に、Delegateで受け取るtextViewを評価してplaceholderを設定したり、取り除いたりしています。
※表題に関係のある箇所のみ載せています。

```swift
class ViewController: UIViewController {
    private let placeholderText = "ここに文字入力してね"

    override func loadView() {
        /* 
        上部にあるUITextFieldの追加・設定等
        */
        let textView = UITextView()
        textView.setPlaceholder(text: placeholderText)
        textView.delegate = self
        view.addSubview(textView)
        /* 
        AutoLayoutの設定やUIの整形等
        */
    }
}

extension ViewController: UITextViewDelegate {
    // 編集状態に入った時に走る処理
    func textViewDidEndEditing(_ textView: UITextView) {
        if textView.text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
            textView.setPlaceholder(text: placeholderText)
        }
    }
    // 編集状態を終えた時に走る処理
    func textViewDidBeginEditing(_ textView: UITextView) {
        if !textView.text.isEmpty && textView.text == placeholderText {
            textView.removePlaceholder()
        }
    }
}

private extension UITextView {
    func setPlaceholder(text: String)  {
        self.text = text
        textColor = .placeholderText // iOS13未満をサポートする場合は使えない色です。
    }

    func removePlaceholder() {
        text = nil
        textColor = .label // 上に同じく
    }
}

```


# 終わりに
サブクラスを作成する実装と比較して以下のような利点・欠点があると思います。
##### 利点
- 余計なクラスファイルを作る必要がない
- 複数箇所で用いる場合、設定する文言や色、評価の条件を変更しやすい

##### 欠点
- 複数箇所で用いる場合、似たような処理をそれぞれ記述する必要がある



簡単にはなりましたが、以上となります。

他にも良い方法があれば、ぜひ教えて頂けると嬉しいです:ok_woman:



# 参考にした記事
[stack overflow - Add placeholder text inside UITextView in Swift?](https://stackoverflow.com/questions/27652227/add-placeholder-text-inside-uitextview-in-swift)（よく見たら古の記事でした）
certbot ドメインを新規追加

ドメインの追加方法

まずはconohaのサーバーを設定し


```/etc/nginx/conf.d/default.conf

server {
    listen 80;
    server_name pro-nail.me;
    return       301 https://pro-nail.me$request_uri;
}

server {
    listen 443 ssl http2;
    server_name pro-nail.me;
    return       301 https://pro-nail.me$request_uri;
｝

```

ドメインを追記後、nginxを再起動

```
service nginx restart
```


certbot を 以下の形で動かすと、
ドメインリストが表示されるので数字を入力してOKする

```
/home/hideki/certbot/certbot-auto
```

以上
【Maven】VPN/Proxyが無ければアクセスできないリポジトリから依存を取得する

社内ネットワーク等で運用されている、`VPN`/`Proxy`が無ければアクセスできない`Maven`リポジトリから依存を取得するためのセッティング方法をまとめます。

この記事で紹介するやり方は`${Maven home}/conf/settings.xml`を書き換えるものです。
コマンドラインオプションで指定する方法はおまけとして最後に書きます。

# やり方
## Maven homeの取得
以下のように、`mvn -v`で出てくる情報の中に有ります。

```bash
$ mvn -v
Apache Maven ${Mavenのバージョン}
Maven home: ${Mavenのhomeディレクトリ}

-- 略 --

```

自分の環境の`Maven home`は`/usr/local/Cellar/maven/3.6.2/libexec`でした。

## settings.xmlの書き換え
`${Maven home}/conf`の下に`settings.xml`というファイルが有るので、それを開いて`proxies`という項目を探します。

自分の環境では、以下のように幾らかの説明とサンプルが書かれた状態になっていました。

<details><summary>`settings.xml`</summary><div>

```xml
  <!-- 略 -->

  <!-- proxies
   | This is a list of proxies which can be used on this machine to connect to the network.
   | Unless otherwise specified (by system property or command-line switch), the first proxy
   | specification in this list marked as active will be used.
   |-->
  <proxies>
    <!-- proxy
     | Specification for one proxy, to be used in connecting to the network.
     |
    <proxy>
      <id>optional</id>
      <active>true</active>
      <protocol>http</protocol>
      <username>proxyuser</username>
      <password>proxypass</password>
      <host>proxy.host.net</host>
      <port>80</port>
      <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
    </proxy>
    -->
  </proxies>

  <!-- 略 -->
```
</div></details>

ここを以下のように編集しました（個々の項目は個別に設定をお願いします）。

```xml:settings.xml(編集後、コメントは省略)
  <!-- 略 -->

  <proxies>
    <proxy>
      <active>true</active>
      <protocol>http</protocol>
      <host>${Proxyのホスト}</host>
      <port>8080</port>
    </proxy>
  </proxies>

  <!-- 略 -->
```

後はファイルを保存し、プロジェクトの`pom`が有る所で`mvn install`すればできました。

# おまけ
## コマンドラインオプションでの指定方法
（自分は試していませんが）以下のオプション類を指定することで、同様の動作ができるそうです。

```bash
-DproxySet=true -DproxyHost=${Proxyのホスト}  -DproxyPort=8080
```

## Intellij Idea
これをやっても自分の環境では`Intellij Idea`の更新ボタン（`Reload All Maven Projects`）経由では反映できませんでした。
`cli`から同期すれば直ったので自分は試していませんが、`Intellij Idea`の方では上記オプションを以下のように指定するとできるそうです。

![スクリーンショット 2021-02-18 15.50.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280230/a4f4db04-4b08-990d-f6c0-1c094275de2d.png)

# 参考にさせて頂いた記事
- [mavenのプロキシ設定 \- Qiita](https://qiita.com/taito-ITO/items/9763e7b3618b46691c83)
goenvのバージョンを上げる(1系から2系にアップデート)

#goenvとは？
goのバージョンを簡単に切り替えられるツール
python使ってる人は、使い方もpyenvと同じ感じ

#環境
macOS Big Sur
goenv1系(brew installのもの)
　→このgoenvを2系にするよ
#バージョンアップさせた理由(GOPATHの設定)
2系からGOPATHの設定をgoenvがやってくれるようになっているため、
go getでインストールする場所がバージョン別に別れてくれる。

##1系と2系のGOPATHの場所の違い

```
1系のGOPATH
GOPATH="/Users/user/go"
```
```
2系のGOPATH
GOPATH="/Users/user/go/1.11.4"
```


#前提
goenvのインストールはbrewで1系をインストール。
go installでインストール済み
goenv global　で設定も済み
goコマンドを通すため、下記のパスをzshrcに設定ずみ

```
export PATH="$HOME/.goenv/bin:$PATH"
eval "$(goenv init -)"
```



#バージョンをあげた方法
##まず1系のgoenvをアンインストール
```
brew uninstall goenv
```

##2系はgitリポジトリから引っ張ってくるしか無いので、下記で持ってくる
```
git clone https://github.com/syndbg/goenv.git ~/.goenv
```
~/以下に.goenvディレクトリができて、そこにソースが落ちる。
ちなみに1系をbrewでインストールした場合も同じ場所に.goenvができます

##ディレクトリ既にありますというエラーがでた時
1系の.goenvディレクトリが残ってるっていうことなので、下記コマンドで削除

```
rm -r .goenv
```

再度git cloneをするとうまくいくはず。

#goenvのバージョン確認
```
goenv --version
goenv 2.0.0beta11
```
2系beta版が入ってる。

#goenvの設定について
1系でやったgoenv installや、goenv globalの設定は全て消えるので、
改めてやり直す必要がある
jupyter notebookからBig Queryに(credentialの設定をして)クエリを投げる設定方法

⚠️このページは殴り書きです。

## 認証が不要な場合。

BQと同じGCPプロジェクト上のインスタンス上のjupyter notebookからクエリを投げる場合などは認証がいらない。

BQのテーブルのデータをもつpandas dataframeを初期化したいとする。この場合m、以下のコマンドをjupyter notebookで叩けば良い。超簡単！

```py
pip install --upgrade pydata-google-auth google-cloud-bigquery[pandas]
```

```py
%%bigquery df_users
SELECT
    user_id,
    scoutable
FROM `my_project.dataset.users`
```


## 認証が必要な場合

https://google-auth.readthedocs.io/en/latest/user-guide.html#obtaining-credentials に全部書いてある。

自分が使用したのは、`Service account private key files`の `Use service_account.Credentials.from_service_account_info`のケース。GCPで発行したJSON keyをBase64encodingした`./keyfile`をインスタンス上にアップロードし、以下を実装した。(なお、`./keyfile`の中身が、**Base64 encoding**されていないオリジナルのjson文字列だったなら、`Service account private key files`という方法を使ってもよいだろう。)

```python

import json
import base64
from google.cloud.bigquery import magics
from google.oauth2 import service_account
with open('./keyfile') as f:
    json_credential = (
        json.loads(base64.b64decode(f.read()))
    )
credentials = service_account.Credentials.from_service_account_info(json_credential)
magics.context.credentials = credentials # 肝
```
これを実行後、magic commandでプロジェクト名を指定して、


```py
%%bigquery df_users --project secret_project
SELECT
    user_id,
    scoutable
FROM `secret_project.dataset.users`
```








## 備考

GCPのアカウントには**サービスアカウント**と、**ユーザーアカウント**が存在する。

GCP上で人間が手動でクエリを走らせている時はユーザーアカウントを使っている。(GCP上で立てた)サーバーからクエリを投げてデータをとってきたいときは、サーバーアカウントを使用していることになる。上記のユースケースは後者に属する。

jupyter notebookからmagic commandでクエリを投げるのであれば、[pydata/pydata-google-auth](https://www.google.com/search?ei=OAsuYJXWJtDZhwOIuLOIAg&q=pydata_google_auth+&oq=pydata_google_auth+&gs_lcp=Cgdnd3Mtd2l6EAMyBAgAEB46BwgAEEcQsANQrlVYsVZg7FdoAXACeACAAbgBiAHTA5IBAzAuM5gBAKABAaoBB2d3cy13aXrIAQjAAQE&sclient=gws-wiz&ved=0ahUKEwiV0uOV6fLuAhXQ7GEKHQjcDCEQ4dUDCA0&uact=5)を使用して、ユーザーのcredentialを使うことでもいけるっぽい。

ただし、自分は以下のようなエラーが発生し、この方法はためせていない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534442/fb8cd463-8de9-8f33-f46e-256ed00ab956.png)


参考: https://medium.com/john-lewis-software-engineering/authenticating-jupyter-notebook-against-bigquery-957884f78527
【Android】TextView内の文中の装飾

例として、`Hello Wolrd!`の`World`部分を装飾します。

# 文中の文字色・太さ・大きさ・下線・上付き文字・下付き文字
```strings.xml
	<string name="text1">Hello <font color="red">World</font>!</string>
	<string name="text2">Hello <b>World</b>!</string>
	<string name="text3">Hello <big>World</big>!</string>
	<string name="text4">Hello <font size="40">World</font>!</string>
	<string name="text5">Hello <u>World</u>!</string>
	<string name="text6">Hello <sup>World</sup>!</string>
	<string name="text7">Hello <sub>World</sub>!</string>
```
出力結果：
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/241ba973-0167-ff23-0f21-dc53fb448388.png" width=40%>

# spで大きさ指定
`Hello World!`の6番目から11番目の文字を大きくする

```style.xml
<style name="Text8">
	<item name="android:textSize">20sp</item>
</style>
```

```MainActivity.kt
binding.text8.text = SpannableString(getString(R.string.text8)).apply {
	setSpan(
		TextAppearanceSpan(this@MainActivity, R.style.Text8),
		6,
		11,
		Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
	)
}
```

# URLリンク
```strings.xml
	<string name="text9">Hello <a href="https://www.example.com">World</a>!</string>
```

```MainActivity.kt
	binding.text9.movementMethod = LinkMovementMethod.getInstance()
```

![Screenshot_1613631090.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/467192fe-fba3-6e21-556b-0ba4ea17ffa8.png)


# URLリンク(下線なし)
```MainActivity.kt
	val clickableSpan = object : ClickableSpan() {
		override fun onClick(p0: View) {
			startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://www.example.com")))
		}

		override fun updateDrawState(ds: TextPaint) {
			super.updateDrawState(ds)
			ds.color = ContextCompat.getColor(this@MainActivity, R.color.design_default_color_primary)
			ds.isUnderlineText = false
		}
	}

	binding.text10.text = SpannableString(getString(R.string.text10)).apply {
		setSpan(clickableSpan, 6, 11, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
	}
	binding.text10.movementMethod = LinkMovementMethod.getInstance()
```
![Screenshot_1613631090 - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/d1048962-731b-5ad2-9b59-05b4954c8b4f.png)
Touchableなコンポーネントのネスト

例えば、モーダルが画面に表示されて、モーダル中のOKボタンを押したら閉じる。さらにモーダルの周りのグレーエリアをタッチしても閉じる、というようにTouchableな中に、更にTouchable要素を配置したい。

単純に以下のようなイメージでnestして配置したがこれが上手く動かない。

```javascript
<TouchableWithoutFeedback>
    <TouchableWithoutFeedback>

    </TouchableWithoutFeedback>
</TouchableWithoutFeedback>

```
親要素＝囲っている要素のイベントしか発生しない

以下でResponderでなんかコントロールすると書いてあるが、パットは理解出来ず..
https://stackoverflow.com/questions/49835883/how-can-i-propagate-touch-event-in-nested-touchable-in-react-native

### 対応方法
ネストさせたい要素を並列に並べて、中に置きたい方の要素をposiiton:absoluteで位置調整して重ねれば、期待の動きは実現できた。
うまく数値で位置指定しないといけないから、使える状況は選ばれる。万能では無い。モーダル的に画面のセンターに置くぐらいなら、なんとか...
Ubuntu18.04にdump1090-faをインストールする

Ubuntu18.04でdump1090-faをインストールするときにつまづいたのでメモしておく。

# インストール時の環境
OS: Ubuntu18.04 
CPU: Intel Core2 Duo
メモリ: 4GB
# 前提
RTL-SDRのセットアップが終わっている。

# 必要なパッケージのインストール
ターミナルを起動して以下のコマンドを入力して実行する。

```
$ sudo apt install git lighttpd debhelper librtlsdr-dev pkg-config dh-systemd libncurses5-dev libbladerf-dev libusb-1.0-0-dev
$ sudo apt install librtlsdr-dev libbladerf-dev dh-systemd libncurses5-dev
$ sudo apt install libhackrf-dev liblimesuite-dev 
```

dump1090-fa4.0からはLimeSuiteも必要らしいので[ここ](https://wiki.myriadrf.org/Lime_Suite)を見ながらインストールした。
以下のコマンドを入力するとインストールできる

```
$ sudo add-apt-repository -y ppa:myriadrf/drivers
$ sudo apt-get update
$ sudo apt-get install limesuite liblimesuite-dev limesuite-udev limesuite-images
$ sudo apt-get install soapysdr-tools soapysdr-module-lms7
```

# dump1090-faのダウンロード
必要なパッケージのインストールが完了したら以下のコマンドを入力してdump1090-faのソースコードをダウンロードする。

```
$ git clone https://github.com/flightaware/dump1090 dump1090-fa
```

# dump1090-faのビルド
以下のコマンドを入力して.deb形式でビルドする。deb形式でビルドするとインストールがかなり楽(deb形式でビルドしないときのインストール方法はわかりませんが…)。

```
$ cd dump1090-fa
$ dpkg-buildpackage -b --no-sign
```

## エラーが発生したとき
ぼくの環境では以下のようなエラーが出た。

```
Error: No dependency information found for /usr/local/lib/librtlsdr.so.0 (used by debian/dump1090-fa/usr/bin/dump1090-fa)
```

これは`debian/rules`を編集し、末尾に以下を追加すると解決する。([ここ](https://forum.flightradar24.com/forum/radar-forums/flightradar24-feeding-data-to-flightradar24/12330-dump1090-mutability-1-15-on-mint-linux)に書いてあった)

```
override_dh_shlibdeps: 
        dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info
```
この2行目の先頭の空白部分はスペースでなくタブで入力しないとエラーになるので注意。
編集後、再度ビルドすると問題なくビルドされる。

# dump1090-faのインストール
以下のコマンドを入力してインストールする。

```
$ cd ..
$ sudo dpkg -i dump1090-fa_4.0_amd64.deb
```

インストールする.debファイルは`dump1090-fa_[バージョン番号]_amd64.deb`となっているものを選択する。
末尾の`amd64`のところは使用してるPCないしraspiのアーキテクチャが違えば変わります。

# dump1090-faの起動
以下のコマンドを入力してdump1090-faを起動する

```
$ sudo systemctl enable dump1090-fa.service
$ sudo service dump1090-fa start
```
ここまできたらブラウザを立ち上げ、[localhost:8080](http://localhost:8080/)にアクセスするとdump1090-faが動いているのが確認できるはず。

# 参考文献
・[RaspberryPiでADS-Bを受信してFlightrader24にフィードしてみた｜cope｜note](https://note.com/cope731/n/n517087d5eb57)
・[Lime Suite - Myriad-RF Wiki](https://wiki.myriadrf.org/Lime_Suite)
・[Dump1090 mutability 1-15 on Mint linux - Flightradar24 Forum](https://forum.flightradar24.com/forum/radar-forums/flightradar24-feeding-data-to-flightradar24/12330-dump1090-mutability-1-15-on-mint-linux)
iOS14.5からIDFA対応しておかないとデフォルトでadvertisingIdentifierが取得できなくなります！

iOS14.5からIDFA対応しておかないとデフォルトで取得できなくなります！！！

iOS14.4までの動作はこちら
https://qiita.com/rd0501/items/4cd65ac973cc2736908f

### 環境

iOS 14.5 Developer Beta 2, 14.4 (実機)
Xcode Version 12.5 beta 2 (12E5234g)

### 検証結果

| OS | isAdvertisingTrackingEnabled | trackingAuthorizationStatus | uuidString |
|:-----------:|:------------:|:------------:|:------------:|
| iOS14.5 | false | notDetermined | 00000000-0000-0000-0000-000000000000 |
| iOS14.5 | false | denied | 00000000-0000-0000-0000-000000000000 |
| iOS14.5 | false | authorized | 取得できた |
| iOS14.4 | true | notDetermined | 取得できた |
| iOS14.4 | true | denied | 00000000-0000-0000-0000-000000000000 |
| iOS14.4 | true | authorized | 取得できた |
| iOS14.4 | false | authorized | 取得できた |
| iOS14.4 | false | denied | 00000000-0000-0000-0000-000000000000 |

14.5以降の場合のみ許可を求めるのが一番コスパよさそう

### 備考

- iOS14.5から`isAdvertisingTrackingEnabled`が`false`になってました
- iOS14.5の設定アプリから`Privacy > Tracking > Allow Apps to Request to Track` をOFFにすると`trackingAuthorizationStatus`がdefaultで`denied`になる(14.4と一緒)(アラートは出ない)
- iOS14.5 でアラートが出ている状態で端末の電源を切ると`denied`になる(14.4と一緒)
- simulatorでは問答無用で`00000000-0000-0000-0000-000000000000`になるので注意(14.4と一緒)
- restricted はよくわかりませんでしたが denied と同じ扱いで良さそう？(14.4と一緒)


### その他

```swift

    @available(iOS, introduced: 6, deprecated: 14, message: "This has been replaced by functionality in AppTrackingTransparency's ATTrackingManager class.")
    open var isAdvertisingTrackingEnabled: Bool { get }
```

isAdvertisingTrackingEnabledが非推奨になってて何してもfalseになるようになった
14.4まではtrueも返ってきてた気がします

### コード

```swift
if #available(iOS 14, *) {
    print(ATTrackingManager.trackingAuthorizationStatus.rawValue)
    ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
        print(status.rawValue)
        print(ATTrackingManager.trackingAuthorizationStatus.rawValue)
        print(ASIdentifierManager.shared().isAdvertisingTrackingEnabled)
        print(ASIdentifierManager.shared().advertisingIdentifier)
    })
} else {
    // Fallback on earlier versions
}
print(ASIdentifierManager.shared().isAdvertisingTrackingEnabled)
print(ASIdentifierManager.shared().advertisingIdentifier)
```
【JavaScript】スクロールのアニメーションの実装

#はじめに
この記事は、JavaScriptを勉強中の方向けに書いています。また私自身のアウトプットとして書いています。
内容は以下の通りです。

- **scrollTo()メソッドを使ったページのスクロール実装**
- **setInterval()メソッドでアニメーション化**

#scrollToメソッドとは
scrollToメソッドは指定ページまでスクロールさせるメソッドです。引数を渡してどこまでスクロールするか指定できます。

```.js
window.scroll(0,1000);  //第１引数は水平方向、第２引数は垂直方向を渡す
```

#setIntervalメソッドとは
setIntervalメソッドは渡された引数ミリ秒後に関数を実行するメソッドです。第１引数にコールバック関数、第２引数に何秒間隔で実行するかを指定します。（単位はミリ秒）

```.js
setInterval(()=>{
  //処理
},1000);
```

#準備
あるボタンをクリックしたら下方向にスクロールするというものを実装したいと思います。
事前にhtmlとスタイルシートを準備しました。
100vhごとに赤色、青色、黄色背景にするようにしています。スクロールボタンも設置しています。

```test.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/test.css">
    <title>Test</title>
</head>
<body>
    <div class='red'>
        <a href="#" class="arrow"></a>
    </div>
    <div class='blue'>
        <a href="#" class="arrow"></a>
    </div>
    <div class='yellow'>
    </div>
</body>
</html>
```

```test.css
.arrow{
    position: center bottom;
    display: block;
    width: 80px;
    height: 80px;
    border-top: 10px solid #b0b0b0;
    border-right: 10px solid #b0b0b0;
    transform: rotate(135deg);
    margin-top: 80vh;
}
.red{
    background-color: red;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;

}
.blue{
    background-color: blue;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}
.yellow{
    background-color: yellow;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}
```

#実装
arrowクラスをつけているaタグをクリックした時に、スクロールの関数を実行するようにします。
またスクロールの移動にアニメーション要素を入れたいので、数十ミリ秒間隔で関数を呼ぶようにします。

```.scroll.js
const scrollDown = (position)=>{
    let count = position
    setInterval( ()=>{
        count += 50
        if(count<position + 1000){
            window.scrollTo(0, count)
        }
    },10)
}
```

次に、ボタンをクリックした時にこの関数を呼び出したいので、onclick属性を追加します。
また、jsファイルの読み込みも追加します。

```test.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="css/test.css">
    <script src='scroll.js' defer></script>
    <title>Test</title>
</head>
<body>
    <div class='red'>
        <a href="#" class="arrow" onclick='scrollDown(0)'></a>
    </div>
    <div class='blue'>
        <a href="#" class="arrow" onclick='scrollDown(1000)'></a>
    </div>
    <div class='yellow'>
    </div>
</body>
</html>
```

これで矢印をクリックすると
赤色→青色→黄色
というようにスクロールされるはずです。

#参考
[CSSで作るシンプルな矢印アイコン29個](https://www.pressmantech.com/tech/design/2738)
MySQLにバイナリ文字列で保存されたデータを見てわかる形で表示する

## 概要
バイナリ文字列で保存されたデータをわかりやすくselectするための方法の備忘録。
実行環境は`MySQL5.6`

## 具体例
他のサービスと連携してログインできるようなテーブル`Users`があるとします。

|カラム名|id|name|auth_type|
|---|---|---|---|
|データ型|int|varchar(255)|barbinary(255)|

とりあえずselectして中身を見てみる

```
select * from Users;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210364/5541d21d-471e-7b4f-e978-89757c0ec1ef.png)
...?

## どうするか

cast関数で囲って変換しましょう

```
select id,name,cast(auth_type as char(255)) as auth_type from Users;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210364/1f82983e-2fa1-3f4f-eae1-e14c09ba1dc2.png)

## 参考

ブラウザ上で実行できる[sqlfiddle](http://sqlfiddle.com/#!9)というサイトを利用してみました。
記事内で利用したクエリは[こちら](http://sqlfiddle.com/#!9/9cd1dc/3/0)
【Nginx】htmlをphpで実行する

この記事はcentos7+nginx+php7の環境で書いています。
#やりたいこと
**Apache**のときにこんな感じで書いていました。

```httpd.conf
AddType application/x-httpd-php .html
```
これをnginxで設定したい。

#PHP-FPM
`# vi /etc/php-fpm.d/www.conf`

```www.conf
security.limit_extensions = .php .php3 .php4 .php5 .html
```

#NGINX
必要なディレクティブに下記を加える。

```
location ~ \.html$ {
  fastcgi_split_path_info ^(.+\.php)(/.+)$;
  if (!-f $document_root$fastcgi_script_name) {
     return 404;
  }
  include /etc/nginx/fastcgi_params;
  fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
  fastcgi_index  index.html;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
```

#最後に
再起動を忘れずに
`# systemctl reload php-fpm.service`
`# systemctl reload nginx.service`
Gitを利用する際の初学者用のページ紹介

# 簡単な自分へのメモ
この記事は自分のメモとして作成しました。
Gitの勉強として、分かりやすいサイトの記事を紹介します

##　リンク先
[Gitの簡単な使い方の記事]https://qiita.com/yuina/items/78cdc1fe8df3a6586cc5
[Gitのホスティングサービスの紹介] 　https://tracpath.com/works/development/git-hosting-service/
[Git GUIクライアント比較5選]https://hajipro.com/git/mac-git-client

2021/03/11 追記
[[新人教育] 何も知らない人がGitとGitHubを独学で知る] https://qiita.com/ikenji/items/367e8344490dd37e14f0

###　あとがき
自分用のメモですが、他にも分かりやすい記事などをご存知の方は紹介してくださると大変ありがたく思います。

2021/03/11 追記
[新人教育] 何も知らない人がGitとGitHubを独学で知る　
この記事で紹介しているサービスは特に分かりやすかったです。
指示通りに行えば、Gitの使い方の一通りは理解しやすいかと思います。
AppStreamのユーザを削除する方法

そもそもAppStreamってなんぞ
-
デスクトップアプリをWEBブラウザで操作できるという夢のようなサービス。WindowsアプリもWEBブラウザでMACからも操作できます。古い業務アプリとかあるところは大変有用なサービスかと思いますのでぜひオンプレサーバをなくしたいけど、いろいろな事情により移行はできない諦めている皆様はAppStreamをご検討ください(AWSの回し者ではございませんw)

AWSのWEBコンソールでは削除できない
-
* え、まじで?と思った皆様、こちらの画像を御覧ください
![aaaaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585901/1031d6bd-a29e-0c18-a6fb-89a23e3c370a.png)
* Disableはあるけど、Delete userっていうのはどこ探してもありません
* そう削除は甘え

それでは困るので、どうにか無いかと探したところありました
-
* そう__aws-cli__です

```
aws appstream delete-user --user-name hogehoge@yzrh.jp --authentication-type USERPOOL
```

* これだけです。CLIには実装してるということはAPIあるはずなのにWEBコンソールに実装しないのはなぜという気しかおこりません。これ以上フロント側を開発するリソースはかけないという方針なんでしょうけども、使ってる身としては困るので早く実装してほしい次第でございます。
C 言語による Logistic map の1次元分岐図計算プログラム

# はじめに
離散写像の1次元分岐図は簡単なプログラムで実装できる．
これまでは必要に応じて昔のプログラムを参照していたが，ファイルを探すのが面倒であったりするので Qiita 上に残すことにした．
必要に応じて適宜修正を加えていく．
> 現状，汎用性の低い書き方になっており，あまりおもしろくないので，以降の修正で検討していく．

# Logistic map
[Logistic map](https://en.wikipedia.org/wiki/Logistic_map) は，代表的な非線形力学系であり，次式で定義される．

$$
x_{n+1} = rx_n(1-x_n)
$$

力学系の解軌道 $\\{x_0, x_1, x_2, \ldots\\}$ はあるパラメタを境にカオス的に振る舞う．

# C 言語によるコード
ここでは C 言語で実装したが，どの言語で書くにしてもプログラムの大枠は変わらない．

```C
#include<stdio.h>                                                                                                                                         
#include<stdlib.h>
#include<math.h>

// Definition of Logistic map
double logistic_map(double x, double r){
  return (r*x*(1.0-x));
}

int main (void){
  double range[2] = {2.4, 4.0};       // Parameter domain
  double r = range[0], x0 = 0.5;      // Initial parameter and state
  int resolution = 2000, maps= 2000;  // Resolution of diagram, count of maps

  double step = (range[1]-range[0])/(double)resolution;

  FILE *fp;
  fp = fopen("out.bf1", "w");         // Output filename

  // Print initial value, parameter, and environment information                                                                                                
  char header[256];
  sprintf(header,
          "# Logistic map bifurcation diagram\n"
          "# x0 = %lf, range = [%lf %lf], resolution = %d, maps = %d\n",
          x0, range[0], range[1], resolution, maps);
  fprintf(fp, "%s", header);
  fprintf(stdout, "%s", header);

  // Main loop                                                                                                                                            
  for(int ri = 0; ri <= resolution; ri++){
    fprintf(fp, "%lf %lf\n", r, x0);

    for(int mi = 1; mi <= maps; mi++){
      x0 = logistic_map(x0, r);

      // if x0 got divergent                                                                                                                              
      if (isinf(x0)){
        fprintf(stderr, "Got divergent at ri = %d, mi = %d\n", ri, mi);
        fclose(fp);
        return -1;
      }
      // else print                                                                                                                                       
      fprintf(fp, "%lf %lf\n", r, x0);
      fprintf(stdout, "\t[%04d/%04d] [%04d/%04d] %+.5lf %+.5lf\r",
              ri, resolution, mi, maps, r, x0);
    }
    // iterate paramter                                                                                                                                   
    r += step;
    fprintf(fp, "\n");
  }

  fprintf(stdout, "\n");
  fclose(fp);
  return 0;
}

```

## Gnuplot による図示
上記のプログラムによって出力される `out.bf1` から，次のような図が得られる．
plot のいろはは[別の記事](https://qiita.com/Yuu-Miino/items/cafbf3929a325e0c183c)に任せることにする．

![out.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467925/f2ff5d6e-43b5-8d8a-fd98-ca07bf8b8906.jpeg)
ASP.NET MVC はデフォルトでレスポンスをフルバッファリングする

# ASP.NET MVC はデフォルトでレスポンスをフルバッファリングする

\# 以下の記事が書かれた時の版数は .NET Framework 4.7.2 / Microsoft.AspNet.Mvc 5.2.7 となります.

ASP.NET MVC はデフォルトでレスポンスボディをフルバッファリングしてから返すようで、何も考えずに大きいストリームとかを返すと `OutOfMemoryException` になります.

```cs
        public ActionResult Download()
        {
            return new FileStreamResult(new BlobClient("connection-string", "container", "large.zip").OpenRead(), "application/zip")
            {
                FileDownloadName = "large.zip"
            };
        }
```

これを回避するには、以下のように `Response.BufferOutput` を `false` にします.

```cs
        public ActionResult Download()
        {
            Response.BufferOutput = false;
            return new FileStreamResult(new BlobClient("connection-string", "container", "large.zip").OpenRead(), "application/zip")
            {
                FileDownloadName = "large.zip"
            };
        }
```

ただし、`Transfer-Encoding` が `chunked` になってしまうので、ブラウザ側でサイズが分からなくなり、ダウンロード残り時間なども表示されなくなってしまいます.

ちなみに ASP.NET Core にはこれらの問題はありません. (ASP.NET Core 3.1 で確認)

`OutOfMemoryException` になりませんし、`Transfer-Encoding: chunked` にもならないので、ダウンロードの残り時間もブラウザが表示してくれます. 古い ASP.NET MVC なんか使ってないで、さっさと ASP.NET Core MVC に移行しろってことですね.

```cs
        public ActionResult Download()
        {
            return new FileStreamResult(new BlobClient("connection-string", "container", "large.zip").OpenRead(), "application/zip")
            {
                FileDownloadName = "large.zip"
            };
        }
```
MySQLでDATETIME 型にnullを挿入する方法

今回、返却日：DATETIME 型に空文字が自動で挿入され、登録ができないということがありました。

nullは登録することは可能でした。（workbenchで直接、値を入力して）

空文字をnullに変更する方法を書いていきたいとと思います。

#空文字をnullに変更(例)

前提
HashMapクラス（連想配列）に空文字が入っています。
その空文字をnullに変換して出力します。


```java
package sa;

import java.util.HashMap;

public class Main {

	public static void main(String[] args) {

		//型引数を指定してHashMapクラスのオブジェクトを生成
		//Map<データ型, データ型> マップ変数 = new HashMap<データ型, データ型>();
		 HashMap<String, Object> resultMap = new HashMap<String, Object>();

		 //値を追加  map.put(キー名, 値);
		 resultMap.put("返却日", "2019-10-04 15:25:07");
		 resultMap.put("返却日1", "");//値は空文字

		 try {
			 if(resultMap.get("返却日").equals("")) {
			      System.out.println("空文字です");//返却日の値が空文字だった場合
			    }else {
				      System.out.println(resultMap.get("返却日"));//それ以外は返却日の値を表示

			    }
	        } catch(NullPointerException e) {
			      System.out.println("nullです");
	        }

		 if(resultMap.get("返却日1").equals("")) {
			 resultMap.put("返却日1",null);//値にnull代入
		    }

		 try {
			 if(resultMap.get("返却日1").equals("")) {
			      System.out.println("空文字です");
			    }else {
				      System.out.println(resultMap.get("返却日1"));

			    }
	        } catch(NullPointerException e) {
	        	//NullPointerExceptionは参照型変数にnull値が格納されている時に、参照型変数を参照しようとした場合に発生する例外
	        	//返却日1の値はnullのため「返却日1の値はnullです」が表示される
			      System.out.println("返却日1の値はnullです");

	        }

	}
}
```
```java
2019-10-04 15:25:07    //返却日
返却日1の値はnullです  //返却日1

```

返却日1は元々空文字だったのですが、nullを代入することができました。
[Rails]current_page?を活用する。

# 書くこと
railsのcurrent_page?を用いた条件分岐について

##環境
Ruby 2.6.5
Rails 6.0.3.4

## 結論
current_page?で、現在のページに指定のURLが含まれているかを判断する。

## ぶち当たった課題
現在取り組んでいるポートフォリオの作成において、**問い合わせフォーム**の作成を行うことにした。そこで、「問い合わせフォームの画面以外に」、そのリンクを設置しようとした。（具体的にはfooter）

```application.html.erb
(中略）
<footer>
  お問い合わせはこちらから<br/>
  <%= link_to "お問い合わせフォーム", new_contact_path%>
</footer>
（中略）
```
しかし、application.html.erbに記述すると、すべてのerbページに表示されてしまうため、これではお問い合わせページにも反映されてしまう。

##current_page?で条件分岐させる。
そこで、前述のcurrent_page?を~~[公式ドキュメント](https://railsdoc.com/page/current_page_q)~~
（2021/02/22追記 公式ドキュメントは[こちら](https://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-current_page-3F)]）で発見し、その用法のうち、

```example.rb
#コントローラとアクションを指定
current_page?(controller: 'library', action: 'checkout')
```
こちらの記述を見つけたので、contactsコントローラーのnewアクション以外で表示するよう条件分岐させた。（2行目）


```application.html.erb
<footer>
   <% unless current_page?(controller:"contacts", action: "new") %>　
     お問い合わせはこちらから<br/>
      <%= link_to "お問い合わせフォーム", new_contact_path%> 
    <% end %>
</footer>
```
うまくいきました。

## 補足
[Railsドキュメント](https://railsdoc.com/page/current_page_q)では、

>指定したURLが、現在表示されているかチェック

するために用いると書かれています。今回使用したコントローラーとアクションを指定する以外にも直接URLを指定できたりするようなので、自分の状況に応じて利用してみてください。

#最後に
最後まで読んでいただき、ありがとうございます。
ソースコード、記事の書き方について**「もっとこうしたほうがいいよ！」というご意見、「そこどうなっているの？」というご質問**など、お待ちしております。

#参考文献
- [Railsドキュメント](https://railsdoc.com/page/current_page_q)
- [Ruby on Rails API Module
ActionView::Helpers::UrlHelper] (https://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-current_page-3F)
llコマンドを使えるようにする[Mac]


便利なエイリアスである、`ll`コマンドをMacOSで使えるようにしました。

## 本記事での前提

 - ターミナルはMac標準

 - シェルは`bash`(以下ならOK) 

```言語:ターミナル
  $ echo $SHELL
  /bin/bash
```
`/bin/zsh`は本記事では取り扱いません。`.zshrc`に反映させるかシェルを`bash`に変更するかになると思います。
参考：[Macでzshからbashへ戻す方法(Catalina)](https://qiita.com/___xxx_/items/c9a30e78196998f4160c)





## 手順

1. `.bashrc`を修正する
2. `.bash_profile`を修正する
3. sourceコマンドで設定内容の反映

## 詳細

####1. `.bashrc`を修正する

vimでホームディレクトリ(~)にある`.bashrc`を開きます。
(`sudo`コマンドでスーパユーザとしてコマンドを実行しているので、パスワードが要求されます)

```言語:ターミナル
  $ sudo vim ~/.bashrc
```
以下を追加し、ファイルを上書き保存(:wq)して終了します。

```言語:.bashrcに追加
  alias ll='ls -la'
```
(簡単なvimの使い方)
 - `i` : インサートモード⇄`esc`でノーマルモードの切り替え
 - `:wq` : ファイルを上書き保存して終了
 - `:q!` : ファイルを保存せずにvim終了
 
参考：[すぐわかる！viの保存と終了の方法【Linux基礎知識】](https://eng-entrance.com/linux-vi-save)

今回は`ls`のオプションに`-l`と`-a`をつけました。`-F`をつける方も多いみたいです。

(lsオプション要約)
 - `-l` : ファイルの詳細表示
 - `-a` : すべて表示(.bashrcや.git等の設定ファイルも表示)
 - `-F` : ディレクトリに`/`、実行可能ファイルに`*`を付加する

####2. `.bash_profile`を修正する

vimでホームディレクトリ(~)にある`.bash_profile`を開きます。
（一度エイリアスを作られたことがあれば、この手順は必要ないと思います。）

```言語:ターミナル
  $ sudo vim ~/.bash_profile
```
以下を追加し、ファイルを上書き保存(:wq)して終了します。

```言語:.bash_profileに追加
  source ~/.bashrc
```

####3. sourceコマンドで設定内容の反映

sourceコマンドで設定内容を反映させます。

```言語:ターミナル
  $ source ~/.bash_profile
```

##結果
`ll`コマンドが使えるようになりました。
上手くいかないときは一度ターミナルを閉じてから開き直してください。
もちろん`ll`だけでなく、他のエイリアスの作成も同様の手順でできるので自分にあったエイリアスを作成する参考にしていただけたらと思います。


```言語:ターミナル
user-MacBook-pro:~ user$ ll
total 408
drwxr-xr-x@ 40 user  staff   1280  2 18 11:21 .
drwxr-xr-x   6 root  admin    192  8  3  2020 ..
-r--------   1 user  staff      7  7 14  2020 .CFUserTextEncoding
-rw-r--r--@  1 user  staff  34820  2 16 17:50 .DS_Store
drwx------  11 user  staff    352  2 17 13:07 .Trash
drwxr-xr-x  15 user  staff    480 11 11 15:22 .atom
-rw-------   1 user  staff  49822  2 17 16:56 .bash_history
-rw-r--r--   1 user  staff     83  2  1 17:46 .bash_profile

(省略)
```

## 参考
お世話になりました。
[【Linux】エイリアスの設定方法](https://qiita.com/_ydah/items/18d242b632e5486fe912)
[Macでzshからbashへ戻す方法(Catalina)](https://qiita.com/___xxx_/items/c9a30e78196998f4160c)
[すぐわかる！viの保存と終了の方法【Linux基礎知識】](https://eng-entrance.com/linux-vi-save)
VM VirtualBoxのエラーについて

（個人の忘備録です。）

VirtualBoxをちゃんと終了させなかったため、エラーで「繋げませんから解決してください」と言われました。

VirtualBoxマネージャーを開くと

```
Runtime error opening 'C:\Users\user_name\VirtualBox VMs\xxx\xxx.vbox' for reading: -102 (File not found.).
F:\tinderbox\win-5.2\src\VBox\Main\src-server\MachineImpl.cpp[745] (long __cdecl Machine::i_registeredInit(void)).
終了コード :  E_FAIL (0x80004005)
コンポーネント: MachineWrap

```

と出ます。

この手のエラーはHyper-Vによって接続できなくなることで発生することが多いのですが、今回は(file not found)とあるので、期待していたファイルが存在していませんという事のようです。

VM起動中はtempファイルになっているこのファイルを、ちゃんと終了しなかった故に.vboxファイルに戻らず、.vbox-tmpファイルのままになってしまい「.vboxファイルないよ」と怒られてしまった次第です。

なので__.vboxに戻すのが正解__となります。

私の場合は、
C:\Users\user_name\VirtualBox VMs\xxxフォルダ下の
`xxx.vbox-tmp`となっているファイルを
`xxx.vbox`にリネームするだけです。

単純なミスなのですが、意外と解決法をを見つけられず時間がかかりました。
眠さに負けて適当にシャットダウンしたことを後悔しました...


参照:
https://doruby.jp/users/road_of_beginners/entries/VirtualBox___for_reading__-102_File_not_found.__E_FAIL__0x80004005_
ショートカットを実行したフォルダパスをスクリプトに反映した

###概要
PowerShellスクリプトを一つのフォルダで管理して、ショートカットを使うフォルダ内に作成して使用することがあるためパス入力が手間だった。ショートカットの実行時にフォルダパスを反映することで解消した。

```batch:リンク先&#x20;(cmd)
C:\Windows\System32\cmd.exe /C pwsh "C:\Users\%username%\Documents\PowerShell\なんとか.ps1" "%CD%"
```

```batch:コマンドと引数
CMD /C    "文字列" に指定されたコマンドを実行した後、終了します。
CMD /K    "文字列" に指定されたコマンドを実行しますが、終了しません。
CMD /Q    エコーをオフにします。
pwsh      ver.5 まで powershell / ver.6 以降は pwsh
%CD%	  実行したフォルダのパスを取り出す変数
```

###実装
ショートカットに書き込む
![ショートカットでps1を呼んでカレントディレクトリのパスを投げるtestのプロパティ 2021_02_11 11_32_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170171/bed4668d-97d5-a8af-c082-da67f3e0727e.png)
確認のため ``/C`` を ``/Q /K`` に置き換えて実行

###テスト
``$Arg[0]``でパスを取り出す

```powershell:なんとか.ps1
write-host "現在のディレクトリ"
get-location # (*1)
write-host "`$Args[0]の中身" $Args[0]
set-location $Args[0]
write-host "セットしました"
get-location # (*1)

Read-Host "終わります"
EXIT
```

```:実行結果
現在のディレクトリ
# 空
$Args[0]の中身 E:\folder
セットしました
終わります: # Enterを押す
Path # (*1)
----
E:\folder # (*2,3)
E:\folder


D:\folder>
```
*1 ``get-location``コマンドが``Read-Host``の後に実行される
*2 パスに[ ]が含まれる場合``-LiteralPath``を指定
*3 ドライブ直下の場合 (例)``C:"`` となるので`"`を削除する
　`%CD%` ではスペースがあるとパスが切れる

###補足
スクリプトの実行ポリシーが許可されていない場合 ``-ExecutionPolicy RemoteSigned``

```batch
C:\Windows\System32\cmd.exe /C pwsh -ExecutionPolicy RemoteSigned "C:\Users\%USERNAME%\Documents\PowerShell\なんとか.ps1" "%CD%"
```
【Python】flushって何のために書くん？

#追記(2021.02.18）
早速ですが、嘘書いたので訂正します。


#Pythonでファイル操作するときにflushを書く理由

##flushって何？
ファイルへの書き込みを実行します。

##flushっていつ使うの？
ファイル操作するときに、読み書きしますね。
その時、withを使って操作するのがPythonでは一般的でしょう。

```python:with
with open("hoge.txt", 'r') as f:
  print(f.read())
```
こんな感じです。
withは優秀なので、ファイルクローズし忘れという大罪を防いでくれます。
withを使わないで書くなら、こうなります。

```python:no_with
f = open("hoge.txt", 'r') as f:
  print(f.read())
f.close()
```
最後に必ず、closeを書く必要があります。
これ書かないと、pythonがずっとファイルを握っちゃいます（たぶん）。

さて、ただファイルを読み書きするだけならwithだけで問題ないのです。
しかし、同一のファイルを複数の処理からアクセスするときにflushが必要になります。

そもそも、flushはファイルがクローズされるときに勝手に実行されるため、普段は明示的に書いて上げる必要はありません。
ですが、例えば、次のような場合を考えてみてください。

```python:duplicate
def read1():
  with open("hoge.txt", 'r') as f:
    print(f.read())

def read2():
  with open("hoge.txt" , 'w') as f:
    f.write("hoge")
    read1()
```

これは、read2でhoge.txtにhogeと書き込んで、read1でhoge.txtの中身を参照しようとしています。
read2を実行すると、出力結果はどうなるでしょうか。。。

```python:answer

```
答え：（出力なし）
です。
ぱっと見た感じ、問題なくhogeと出力されそうですよね。
ですが、アベンドもしないし、想定した出力も出ません。
この問題の重要な点は、__「いつcloseが呼ばれるか」__です。
f.writeで書き込んだはずのhogeですが、これがhoge.txtに書き込まれるタイミングは、~~withのスコープが終了したとき~~時と場合によるです。
~~つまり、ココです。~~

```python:duplicate（再掲）
def read1():
  with open("hoge.txt", 'r') as f:
    print(f.read())

def read2():
  with open("hoge.txt" , 'w') as f:
    f.write("hoge")
    read1()
  # ココ！！（2021.02.18追記：嘘でした、ごめんなさい。）
  # 実際は、スコープを抜けても書き込まれてるかは、運次第です。
```
~~ということは、read2のwithのスコープが終了する前にread1で読み込んだhoge.txtには、まだhogeが書き込まれていないのです！
では、read2のwithスコープ内で書き込んだ内容を読み込むには、スコープを一旦抜けないといけないのでしょうか。~~
writeで書き込もうとしたデータは、一度ファイルバッファという場所に保管され、いつ書き込まれるかは、わかりません。
さっさと書き込まれる事もあれば、そうでないときもあります。
自分のタイミングで書き込んでほしい！
そこで、flushの登場です。
flushはcloseされるときに自動で呼ばれますが、自分で明示的に書いても問題ありません。
なので、こう書けば丸く収まります。

```python:duplicate（再々掲）
def read1():
  with open("hoge.txt", 'r') as f:
    print(f.read())

def read2():
  with open("hoge.txt" , 'w') as f:
    f.write("hoge")
    f.flush()  # ←ここでflush!!
    read1()
```
これで、無事hogeが出力されるようになりました。

```python:answer
hoge
```

##まとめ
今回取り上げた例は、わかりやすさのために、かなり極端な例を挙げました。
ですが、同じファイルに複数の処理からアクセスする場面は多くあるでしょう。
そういったときに問題なのが、「アベンドしないけど、出力結果がおかしい！」という場合です。
なので、私的には、flushはなるたけ書いとく、という結論に至りました。
もちろん、一つの処理でしか読み書きしないなら、不要なコードなので書く必要は皆無ですが、便利機能を使いすぎてると
ついつい書き込みタイミングとかの意識が薄れてしまいがちなので、意識付けのためにも書こうかなーと思ってます。
IBMCloud VRA MIB-OID情報

#SNMP管理を実施する際に必要となる情報の取得方法


デフォルトOIDはこちら

```
sysObjectID = 1.3.6.1.4.1.30803
sysDescr = Vyatta VSE6.6R0S6
```

MIBはこちらに入っている

```
vyatta@vra11:/usr/share/snmp/mibs$ ls
AGENTX-MIB.txt                       INET-ADDRESS-MIB.txt              NET-SNMP-VACM-MIB.txt        SNMPv2-CONF.txt
BGP4-MIB.txt                         IP-FORWARD-MIB.txt                NETWORK-SERVICES-MIB.txt     SNMPv2-MIB.txt
BRIDGE-MIB.txt                       IP-MIB.txt                        NOTIFICATION-LOG-MIB.txt     SNMPv2-SMI.txt
BROCADE-IPSEC-MIB.txt                IPV6-FLOW-LABEL-MIB.txt           OSPF-MIB.txt                 SNMPv2-TC.txt
BROCADE-REG-MIB.txt                  IPV6-ICMP-MIB.txt                 OSPF-TRAP-MIB.txt            SNMPv2-TM.txt
DISMAN-EVENT-MIB.txt                 IPV6-MIB.txt                      RFC1155-SMI.txt              SNMP-VIEW-BASED-ACM-MIB.txt
DISMAN-EXPRESSION-MIB.txt            IPV6-TCP-MIB.txt                  RFC1213-MIB.txt              SOURCE-ROUTING-MIB.txt
DISMAN-NSLOOKUP-MIB.txt              IPV6-TC.txt                       RFC-1215.txt                 TCP-MIB.txt
DISMAN-PING-MIB.txt                  IPV6-UDP-MIB.txt                  RIPv2-MIB.txt                TRANSPORT-ADDRESS-MIB.txt
DISMAN-SCHEDULE-MIB.txt              KEEPALIVED-MIB.txt                RMON-MIB.txt                 TUNNEL-MIB.txt
DISMAN-SCRIPT-MIB.txt                LM-SENSORS-MIB.txt                SCTP-MIB.txt                 UCD-DEMO-MIB.txt
DISMAN-TRACEROUTE-MIB.txt            miblist.txt                       SMUX-MIB.txt                 UCD-DISKIO-MIB.txt
EtherLike-MIB.txt                    MTA-MIB.txt                       SNMP-COMMUNITY-MIB.txt       UCD-DLMOD-MIB.txt
GNOME-SMI.txt                        NAT-MIB.txt                       SNMP-FRAMEWORK-MIB.txt       UCD-IPFILTER-MIB.txt
HCNUM-TC.txt                         NET-SNMP-AGENT-MIB.txt            SNMP-MPD-MIB.txt             UCD-IPFWACC-MIB.txt
HOST-RESOURCES-MIB.txt               NET-SNMP-EXAMPLES-MIB.txt         SNMP-NOTIFICATION-MIB.txt    UCD-SNMP-MIB-OLD.txt
HOST-RESOURCES-TYPES.txt             NET-SNMP-EXTEND-MIB.txt           SNMP-PROXY-MIB.txt           UCD-SNMP-MIB.txt
IANA-ADDRESS-FAMILY-NUMBERS-MIB.txt  NET-SNMP-MIB.txt                  SNMP-TARGET-MIB.txt          UDP-MIB.txt
IANAifType-MIB.txt                   NET-SNMP-MONITOR-MIB.txt          SNMP-TLS-TM-MIB.txt          VRRP-MIB.txt
IANA-LANGUAGE-MIB.txt                NET-SNMP-PASS-MIB.txt             SNMP-TSM-MIB.txt             VRRPv3-MIB.txt
IANA-RTPROTO-MIB.txt                 NET-SNMP-PERIODIC-NOTIFY-MIB.txt  SNMP-USER-BASED-SM-MIB.txt   VYATTA-TRAP-MIB.txt
IF-INVERTED-STACK-MIB.txt            NET-SNMP-SYSTEM-MIB.txt           SNMP-USM-AES-MIB.txt
IF-MIB.txt                           NET-SNMP-TC.txt                   SNMP-USM-DH-OBJECTS-MIB.txt
```

より細かいOID情報が必要な場合はこちら
[Supported MIBs](https://public.dhe.ibm.com/cloud/bluemix/network/vra/18_remote_management_configuration_5600.pdf) p72
SVN引っ越し

# SVNサーバお引越し
オンプレSVNサーバがEOSLとかで新サーバに引っ越しする必要が発生しました。
で、この際にgitに変えちゃわない？
とも思ったのですが、以下の理由でソースとドキュメントごった煮のSVNリポジトリから
ドキュメント類だけを履歴含めて新SVNに引っ越しすることにしました。

- gitにバイナリファイル上げるのはちょっと。。。勢がいる。
- gitはCloneの単位が基本プロジェクト。ドキュメントはこのフォルダから下取得とかやりがちでsvnはこれができる。


## やり方
ざっくり言うと旧リポジトリからダンプ→必要なディレクトリだけフィルタ→新リポジトリにロード

まずはダンプ。こんな感じ

```
# リポジトリ全量ダンプ
svnadmin dump [リポジトリルート] > xxxx.dump
# リビジョン指定も可能
svnadmin dump -r 0:100 [リポジトリルート] > xxxx.dump
# ファイルサイズを気にして分割する場合とかはこんな感じ
svnadmin dump -r 0:100 [リポジトリルート] > xxxx_0-100.dump
svnadmin dump -r 101:200 --incremental [リポジトリルート] > xxxx_101-200.dump
svnadmin dump -r 201:HEAD --incremental [リポジトリルート] > xxxx_201-HEAD.dump
```

で、そこにパイプ経由でフィルタをかけられる。

```
# ディレクトリ指定で狙い撃つinclude　これだと[リポジトリルート]/hoge/fuga配下のみdumpに含まれる
svnadmin dump [リポジトリルート] | svndumpfilter include hoge/fuga > xxxx.dump
# ディレクトリを除外するexclude　これだと[リポジトリルート]/hoge/fuga以外がdumpに含まれる
svnadmin dump [リポジトリルート] | svndumpfilter exclude hoge/fuga > xxxx.dump
# フィルタをかけた場合、除外されたディレクトリに対するリビジョンが消える。
# デフォルトでは便宜上のリビジョンです。みたいなゴミリビジョンに置き換わってしまうので
# このゴミリビジョンを削除するオプション(--drop-empty-revs)、と再度採番するオプション(--renumber-revs)がある
svnadmin dump [リポジトリルート] | svndumpfilter --drop-empty-revs --renumber-revs exclude hoge/fuga > xxxx.dump
```

で、できたファイルを新SVNサーバにロードする

```
svnadmin load [新リポジトリルート] < xxxx.dump
# リビジョン単位で分けて複数分割した場合は積み重ねていく感じ
svnadmin load [新リポジトリルート] < xxxx_0-100.dump
svnadmin load [新リポジトリルート] < xxxx_101-200.dump
svnadmin load [新リポジトリルート] < xxxx_201-HEAD.dump
```

## 注意事項
リビジョンで複数に割ってー。とかやった場合、フィルタされたリビジョンとかに依存したコミットがあると
load時に参照先無しで失敗してしまう。
またリビジョン分けつつ--drop-empty-revs --renumber-revsこのへんのオプションを使うと
リビジョン番号がファイル分割した前後で辿れなくなってしまいやっぱり失敗する。
結構ナイーブ。フィルタと分割は必要最低限の組み合わせで使わないと引っ越しに大変苦労するはめになる。

## 今回のケースだと最終的にどうしたか。

```
svnadmin dump [旧リポジトリルート] | svndumpfilter --drop-empty-revs --renumber-revs exclude [ドキュメント以外のディレクトリ] [ドキュメント以外のディレクトリ2] [ドキュメント以外のディレクトリ3]・・・　> document.dump
svnadmin load [新リポジトリルート] < document.dump
```
XAMMP Laravelで遊んだメモ

Windows10 pro
PHP 7.4.11
Composer 1.10.20
Laravel 8.28.1
npm 7.5.4

#xamppインストール（php）
>https://qiita.com/hitotch/items/0e1751ef38f83a9f3bf4

#Composerインストール
>https://qiita.com/hitotch/items/927337632c7ae1f1963f

#Laravelインストーラーのインストール
>https://readouble.com/laravel/8.x/ja/installation.html

```
composer global require laravel/installer
```
Windows インストール先: %USERPROFILE%\AppData\Roaming\Composer\vendor\bin

#Laravelアプリインストール（Laravelインストーラー
```
laravel new example-app
```

#Laravelアプリインストール（composer
```
composer create-project -–prefer-dist laravel/laravel example-app
```
–prefer-distはzipでインストール

#Laravelアプリ ローカル起動①
```
php artisan serve
```

#Laravelアプリ ローカル起動②
Xamppのhtdocsにlaravelアプリをインストール後xamppのApacheを起動

#Laravelのpublicフォルダを見せるためのApacheのconf設定
D:\xampp\apache\conf\httpd.conf の末尾に以下を追加
Listen 40555
（Listenするポートは既存のものと被らないようにする。

D:\xampp\apache\conf\extra\httpd-vhosts.conf の末尾に以下を追加
>	<VirtualHost localhost:40555>
>	  DocumentRoot "D:\xampp\htdocs\example-app\public"
>	  ServerName localhost
>	  <Directory "D:\xampp\htdocs\example-app\public">
>	    AllowOverride All
>	    Options All
>	    Require all granted
>	  </Directory>
>	</VirtualHost>
VirtualHost：ドメイン:ポート（ポートはhttpd.confでListenしたものを指定する。
DocumentRoot：publicにするディレクトリ
ServerName：VirtualHostのドメインと同じ
Directory：DocumentRootと同じ

保存してApacheを再起動すると今まで「http://localhost/example-app/public」で見えていたものが「http://localhost:40555/」で見えるようになる。
ドメイン部分をlocalhostではなく適当なものにする方法もあるが、Windowsにhostsの例外を登録したりLaravelのAPP_URLを変更するのが手間なので省略（実運用では必要）

#bootstrapのインストール
>https://mebee.info/2020/05/01/post-10614/

##laravel/ui導入
```
php -d memory_limit=-1 "C:\ProgramData\ComposerSetup\bin\composer.phar" 　require laravel/ui
```
（メモリの話https://polidog.jp/2018/02/04/php-memory/

##bootstrap導入
```
php artisan ui bootstrap
npm install
npm run dev
```

##cssタグ
```
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
```


##Honoka
>https://gn-office.pro/archives/343
Composer.jsonとComposer.lockの違い

#Composer.json
パッケージ名を書き込んで
`composer install`したら、そのパッケージをvendorフォルダーの中にインストールしてくれる。
#Composer.lock
`composer install`でインストールしたパッケージのバージョン情報とその他諸々が書き込まれる。
JavaScriptにも宗教がある。

#JavaScriptのオブジェクトの表記方法
JavaScriptはオブジェクトをいわゆる辞書型として定義しています。
この表記方法はJSのほかの文法同様、柔軟性があるというか許容されている表記が多いです。
これを見てください。

```javascript
let a = {"foo":1, "bar":2};
let b = {foo:1,bar:2,}
```
この2つはコーディングの厳格性が求められる言語だったら、ほぼ別言語並みに仕様が違うといえるでしょう。
セミコロンは省略可、これはまあいいんですが、キーの文字列の""を外していいというのはどうかしてませんかね。
そして、配列の最後に空の項目が許されるというのは結構いいですよね。
これの何がいいかというとGitでプルリクエストを送るときに変更した行の数を少なくすることができます。
いちいち追加のたびに前の行も変わっていたら、その分変更の確認量増えるので。
セミコロン、キーの""の有無、最後のカンマなど許容されている範囲が広いせいでどれが好きなのか宗教戦争してそう、という話でした。
homebrewを使ったnodebrew, node, yarnのinstall 環境設定（macOS Big Sur編）

#目的
node.jsを使ったプログラムをlocal環境で動かすために、
nodebrew, node, yarnをインストールする。

インストール順：homebrew → nodebrew → node → yarn

##環境
homebrew インストール済み
macOS Big Sur

#macOS Big Surおける homebrewのエラー対応
早速 nodebrew をインストールしようとすると、homebrewコマンドが使えないというエラーが発生した。要は、macOS Big Surにアップグレードした関係で使えなくなった。(homebrewはインストール済み)

##エラー文の内容と解決


```
Error: Your CLT does not support macOS.
It is either outdated or was modified.
Please update your CLT or delete it if no updates are available.
Update them from Software Update in System Preferences or run:
  softwareupdate --all --install --force

If that doesn't show you an update run:
  sudo rm -rf /Library/Developer/CommandLineTools
  sudo xcode-select --install

Alternatively, manually download them from:
  https://developer.apple.com/download/more/.
```

上記にも記載してあるが、sudo ~ の2文を実行することで解決ができた。


```
  $ sudo rm -rf /Library/Developer/CommandLineTools
  $ sudo xcode-select --install
```

これで、macOS Big Surにてhomebrewコマンドが実行可能になる。

#nodebrewのインストールをする前の確認

nodeがすでにインストールされているかどうかを確認する。
あればアンイストール、なければnodebrewのインストールを行う。

```
//brewに存在するディレクトリを確認
$ brew ls  

// nodeが表示されたら、以下のコマンドでアンイストール
$ brew uninstall --force node
```

これでnodeを入れる準備ができた！


#nodebrewのインストール

nodeの複数のバージョン管理を行う事ができる、nodebrewからインストールする。


```
//インストールの実行
$ brew install nodebrew

//インストールされたかどうかの確認(バージョンが確認されればOK！)
$ nodebrew -v

//環境変数を追加
$ vi ~/.bash_profile

//以下の環境変数を上記ディレクトリ内に追加
　export PATH=$HOME/.nodebrew/current/bin:$PATH

//上書き保存後、bash_proileを更新
$ source ~/.bash_profile

//設定の完了
$ nodebrew setup
```

nodebrew setup まで行わないと、インストールが完了されないため注意。


#使うバージョンを指定してnodeをインストール
nodebrewは最新版でよいが、nodeは指定されたバージョンを確認してからインストールすることが好ましい。なぜなら、nodeは更新頻度が高いため、様々なバージョンが存在する。そのためバージョン指定をしないと、インストールに時間を要してしまうからだ。

```
//インストール可能なバージョンを確認
$ nodebrew ls-remote

//今回は v12.18.3を指定してインストール
$ nodebrew install-binary v12.18.3

//インストールしたバージョンを確認（currrentの確認）
$ nodebrew ls

//使用するバージョンを指定
$ nodebrew use v12.18.3

//currentで表示されるものが指定したバージョンと合っているかを確認
$ nodebrew ls

//nodeのバージョン確認
$ node -v
```

nodebrew ls を打つと、nodeのバージョンが複数存在する。その際は、nodebrew use vxx.xx.xのように指定することで、currentとして使うバージョン指定が可能である。

"プロジェクトによってはnpmのバージョン互換が問題になることが多いため、nodebrewを使うことで複数のプロジェクトで、別々のNodeを使い分けられるようになる点がnodebrewのメリットである"


#yarnのインストール
yarnのインストールはnodeよりも簡単

```
//yarnのインストール
$ brew install yarn

//yarnのバージョン確認
$ yarn --version
```

yarnのバージョンが確認できれば問題なし！

以上

# 参考記事
・[Homebrewで「Your CLT does not support macOS 11」エラーの対応](https://www.yokoweb.net/2020/12/05/homebrew-clt-macos11-error/) 
・[nodebrewでNode.jsをインストールする。](https://qiita.com/yukibe/items/bae442fa6314bd8f9d7a)
・[Mac: yarn install]
(https://qiita.com/miiiii/items/970ec5e3a80eae313c06)
・[NodebrewでNodeをインストールする](https://qiita.com/mame_daifuku/items/373daf5f49ee585ea498)
API Inspectorを使う

コンソールのヘッダーにある謎のボタンがすごい便利だった

これ
![スクリーンショット 2021-02-18 13.49.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294537/0e8ba050-a36e-c03f-a4e9-97c67b364fcd.png)

これをを押すとAPI Inspectorが開く![スクリーンショット 2021-02-18 13.50.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294537/36050a7a-0648-2c7e-cde3-4c887b85750a.png)

API Inspectorを開いた状態でCMVのimagesを開く
すると開く過程で使用したAPI一覧が表示される
![スクリーンショット 2021-02-18 13.52.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294537/1384948c-1730-b55f-127a-a5acbe987e40.png)


DescribeImagesを選択すると、sdkの記述方法のサンプルが表示される
![スクリーンショット 2021-02-18 13.53.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294537/31973b1d-acd5-f72d-7715-d7fa926cf5f4.png)


言語もpython,Java,Go,Node.js,PHP,.Netから選択可能
とても便利
AWSにもこの機能ないかな
Developers Summit 2021 の「ソフトウェア品質を高める開発者テスト」で学んだこと


# はじめに

本稿は、Developers Summit 2021 の以下のセッションで学んだことを書きます。

セッション名：ソフトウェア品質を高める開発者テスト
講演者：高橋 寿一[ロジギアジャパン]
セッション詳細：https://event.shoeisha.jp/devsumi/20210218/session/3019/

# 学んだこと

上流品質を担保(Shift Left)するためには？というテーマのセッション。

上流テストを十分行った方が、出荷後品質が良いというアンケート結果もある。

デイリーで上流品質を担保するために重要なことは以下。

- 単体テスト
- リファクタリング
- 要求仕様のテストケース展開

Googleの話

- Googleの単体テストの網羅率の中央値は78%で、システムテストはほとんど実施しない。
- Google単体テスト基準として、最初は60%以上としている。
- よく変更されるコードの網羅率を上げる。レガシーコードはある程度、ほおっておいても良いという考え方。

2割の部分に8割以上のバグが潜んでいる。

- よく変更されるファイル
- 長いファイル
- 複雑度が高いファイル

関数単位でなく、ファイル単位で単体テスト計画を立てる必要がある。

既存プロダクトに対しては、上記の2割の部分を抽出して、単体テスト計画を立てるようなコンサルをすることもある。

長いファイル・複雑度が高いファイルは分けるようにリファクタリングする。
大きいクラスを分けるだけで、バグが凄く減る。

要求仕様のテストケース展開

- 要求仕様とテストケースは、関連付けてテストを行うことが必要。
- 要件定義を明確に行った場合と、行わない場合で検出不具数は2.7倍違う。

テストは基本すべて自動化し、すべての自動テストは最低その日に終了する。
その日に品質担保できないものは、出荷後の不具合に繋がりやすい。

自動化健全性チェックリスト

- 網羅率上がっているか
- スピード十分あるか
- 自動化ですべてのバグが見つからないことを認識しているか

セキュリティバグや非機能バグは、自動単体テストでなく、別の方法で実施する。

テストスピードが重要なので、そういう意味では単体テストがお得。
MVC分離でUIテストのテスト時間の最小化する。

事例の紹介

プルリク作成後、2分間でビルドし、3分間で単体テストを実施し、3分間で静的解析し、1時間に1回の頻度で8分間でシステムテストを実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403606/4f21d986-a207-7ab7-40e1-de02e1476064.png)

# まとめ
出荷前に品質を高めるためのノウハウを学ぶことができました。

ちなみに私は、普段はエンジニアリングマネージャーとして、チームの皆で楽しく開発する施策を色々実施しています。詳しくは以下を参照ください。
[1年以上かけて生産性倍増＋成長し続けるチームになった施策を全部公開](https://qiita.com/kojimadev/items/4b28f801863cf4e8f0da)

Twitterでも開発に役立つ情報を発信しています → [@kojimadev](https://twitter.com/kojimadev)