OmniAICreator/Qiita-1.07M huggingface dataset:
市の名前と市長の名前が紛らわしいやつでループ構造は組めるか

## 結論

　**組めない**。

　最長のリレーは

- 粟原市の千葉市長
- 千葉市の熊谷市長
- 熊谷氏の富岡市長
- 富岡市の榎本市長

　の4市。

　なお上の結果は2020年11月時点のものです。

# 序論

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/e8321cde-1ebc-29a7-ce6b-094019239153.png)
（ご本人のtwitterより引用）

　千葉市の[熊谷市長](https://twitter.com/kumagai_chiba)（もうすぐ県知事になりそうですけど）は有名ですよね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/8ad36d9c-8011-e7b1-7747-ee57f224c42a.png)
（[Wikipedia](https://ja.wikipedia.org/wiki/%E7%86%8A%E8%B0%B7%E5%B8%82)より引用）

　しかし熊谷市長というと**埼玉県熊谷市**の市長さんと混同しそうになります。生まれ持った名字なので仕方ないのですが、時々こういう名前衝突が起こります。更に言うと、理論的には「XX市のYY市長　→　YY市のZZ市長　→　ZZ市のXX市長」という無限ループが発生してしまう可能性がありますし、そうなったら大変です！　調べなければなりません。

# 調査方法

　[全国市長会ホームページ](http://www.mayors.or.jp/city_mayorssearch_result.php)が全自治体（町村は含まれていないようです）の市長名を公開してくれているので、これを全探索していきます。向こうのページの仕様で、検索結果がユニークアドレスを持っていないので、もし下のコードを実際に実行したいという奇特な方がいたら実際にページにアクセスして検索クエリを出してhtmlファイルを入手してください。下のコードで言うと`source.html`がそれに当たります。

　以下ソースコード：

```python
import re
import requests

def search(p,result):
    print('{}市の{}市長を探索中 ... '.format(p[0],p[1]))
    for r in result:
        if r[0] == p[1]:
            return 1+search(r,result)  
    print('{}市は存在しないようです\n'.format(p[1]))
    return 1

def main():
    t = open('source.html').read()
    pattern = r'<tr><td class="city_info">(.*?)市</td><td class="city_info">(.*?)　(.*?)</td><td class="city_info">'
    result = re.findall(pattern,t)
    max_length = 0
    for r in result:
        max_length = max(max_length,search(r,result))
        if max_length == 4:
            break
    return

main()
```

　実行の様子。

```console
釜石市の野田市長を探索中 ...
野田市の鈴木市長を探索中 ...
鈴木市は存在しないようです

二戸市の藤原市長を探索中 ...
藤原市は存在しないようです

八幡平市の田村市長を探索中 ...
田村市の本田市長を探索中 ...
本田市は存在しないようです

奥州市の小沢市長を探索中 ...
小沢市は存在しないようです

滝沢市の主濱市長を探索中 ...
主濱市は存在しないようです

仙台市の郡市長を探索中 ...
郡市は存在しないようです

石巻市の亀山市長を探索中 ...
亀山市の櫻井市長を探索中 ...
櫻井市は存在しないようです

塩竈市の佐藤市長を探索中 ...
佐藤市は存在しないようです

気仙沼市の菅原市長を探索中 ...
菅原市は存在しないようです

白石市の山田市長を探索中 ...
山田市は存在しないようです

名取市の山田市長を探索中 ...
山田市は存在しないようです

角田市の黑須市長を探索中 ...
黑須市は存在しないようです

多賀城市の深谷市長を探索中 ...
深谷市の小島市長を探索中 ...
小島市は存在しないようです

岩沼市の菊地市長を探索中 ...
菊地市は存在しないようです

登米市の熊谷市長を探索中 ...
熊谷市の富岡市長を探索中 ...
富岡市の榎本市長を探索中 ...
榎本市は存在しないようです

栗原市の千葉市長を探索中 ...
千葉市の熊谷市長を探索中 ...
熊谷市の富岡市長を探索中 ...
富岡市の榎本市長を探索中 ...
榎本市は存在しないようです
```

# 結果

　もしループ構造がある場合、このコードだと無限ループを起こして無限行の出力が出されるはずですが、幸か不幸かそうはなりませんでした。最大の長さを調べてみると4個でした。6個ぐらい行くと思っていましたが、案外少ないものですね……。

　ちなみに4個のラインは、冒頭にも示した**粟原市→千葉市→熊谷市→富岡市ライン**です。ただ、千葉市の熊谷俊人市長が県知事に立候補してたぶん確実に当選するでしょうからこのラインは崩壊することが予想されます。市長名ループ化の実現は遠そうです。
[Python] うちの湯婆婆が「𠮷田」さんに対応しているか知りたい

# はじめに

元ネタ: [Javaで湯婆婆を実装してみる - Qiita](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)
これをPythonで実装してみた前回の記事: [Python 3で湯婆婆を実装してみる - Qiita](https://qiita.com/everylittle/items/aae58c241194c0e5f515)


お前は湯婆婆で何本書く気なのか。


湯婆婆のもとにはいろんな人が働かせてもらいに来ますが、ある名前の人が来ると湯婆婆が崩壊するかもしれないと心配していました。実際に調べてみたら大丈夫だったという話です。
今回は空文字列 "" は無しです


# コード

[前回の記事](https://qiita.com/everylittle/items/aae58c241194c0e5f515)の再掲です。Python 3.6以降に対応。

```python:yubaba.py
import sys
import random

print("契約書だよ。そこに名前を書きな。")
name = sys.stdin.readline().rstrip()
print(f"フン。{name}というのかい。贅沢な名だねぇ。")

newName = random.choice(name)

print(f"今からお前の名前は{newName}だ。いいかい、{newName}だよ。分かったら返事をするんだ、{newName}!!")
```

# 「𠮷田」さんがやってきた

湯婆婆を訪ねた「𠮷田」さんの**「𠮷」の字は「土」の下に「口」と書く、いわゆる「つちよし」です。**「𠮷野家」の「𠮷」であり「𠮷澤ひとみ」の「𠮷」でもあります。

Windowsのコマンドプロンプトだと入力時点で崩壊するので、LinuxやCygwin環境で実行してください。

```
$ python3 yubaba.py
契約書だよ。そこに名前を書きな。
𠮷田
フン。𠮷田というのかい。贅沢な名だねぇ。
今からお前の名前は𠮷だ。いいかい、𠮷だよ。分かったら返事をするんだ、𠮷!!
```

**無事に「𠮷」と呼んでもらえたら成功です。**

一方、
もしかするとこうなってしまった方もいるかもしれません。
おそらくいないと思います（後述）。

```
契約書だよ。そこに名前を書きな。
𠮷田
フン。𠮷田というのかい。贅沢な名だねぇ。
今からお前の名前は▒だ。いいかい、▒だよ。分かったら返事をするんだ、▒!!
```


𠮷田さんにまともな名前をつけてあげてください。


## サロゲートペア

「𠮷」の字は16ビットのコード1つでは表現できません。16ビットのコードを使って表すときは2つ組み合わせることになります。これをサロゲートペアと呼びます。
Python湯婆婆が𠮷田さんにまともな名前をつけられるかどうかは、Python内部で1文字を何ビットで表現しているかによって決まります。

[sys — System-specific parameters and functions — Python 3.9.0 documentation](https://docs.python.org/3/library/sys.html#sys.maxunicode)

```python
import sys
print(sys.maxunicode)
1114111
```

65535 より大きい値が出たら、文字列の内部表現はUCS-4 (32ビット) です。このとき、湯婆婆は𠮷田さんを無事に受け入れることができます。「𠮷」を正しく1文字として認識しているからです。

```python
import sys
print(sys.maxunicode)
65535
```

65535 ならば、文字列の内部表現はUCS-2 (16ビット) です。この場合、残念ながら湯婆婆は𠮷田さんの訪問を想定していません（偶然「田」と命名されれば問題ないのですが）。「𠮷」は本来1文字なのに、内部では16ビットの文字2個として扱われます。2個並びの片方だけをとっても意味をなさないため、文字化けしてしまいます。

関連: [UCS-2 か UCS-4 かによって len や unichr の戻り値が変わることがある - Qiita](https://qiita.com/masakielastic/items/60e28d9f2a4b472a0b55)

## Python 3.3以降では問題なくサポートされる

実のところ、Python 3.3以降では常にUCS-4が使われるようになったそうなので、「𠮷田」さんに悩む必要はありません。

[What's New In Python 3.3 — Python 3.9.0 ドキュメント](https://docs.python.org/ja/3/whatsnew/3.3.html#functionality)

>Python は今や非 BMP 面の文字を含む Unicode コードポイントの完全な範囲 (つまり U+0000 から U+10FFFF まで) を常にサポートします。narrow ビルド / wide ビルドという区別は今では存在していないため、Python は今ではいつでもかつての wide ビルドのように振る舞い、Windows でもこれは例外ではありません。

Python 2.xのときは、UCS-2でビルドされることも多かったので、「𠮷田」さんが来るとバグる湯婆婆がいたと思われます。もうサポート期限切れなので良いですよね。

## configureのオプションが命運を握っていた (Python 2の時代)

Python 2をソースコードからビルドする場合には、configureのオプションとして ``--enable-unicode=ucs4`` をつけることで、内部表現をUCS-4にすることができます（した）。
パッケージマネージャでインストールするとUCS-4版になっていることも多いですが、もしUCS-2版のPythonだったら、上記オプションをつけてソースコードからビルドすることにより解決できます。

関連: [unicode - How to find out if Python is compiled with UCS-2 or UCS-4? - Stack Overflow](https://stackoverflow.com/questions/1446347/how-to-find-out-if-python-is-compiled-with-ucs-2-or-ucs-4)

# 最後に

Python 3なら「髙田」さんも「山﨑」さんも「草彅」さんもどんと来い。
【Docker】Herokuでコンテナを使い更新するやり方とMigrateErrorの対処方法について

#環境
macOS 10.15.5
Rails 5.2.4.2
Docker 19.03.12

#Herokuで更新するやり方について
Dockerの環境でHerokuでデプロイをしてその後更新する際には下記のコマンドを実行してDockerのコンテナの内容を更新します。

```ruby:terminal
#ログインをします
$ heroku container:login
#pushをして
$ heroku container:push web
#最後に反映させます
$ heroku container:release web
```
これだけでHerokuにデプロイしたDockerコンテナの内容が更新されます！

#もし「ActiveRecord::PendingMigrationError」とエラーが出てしまったら...

Dockerの環境でブラウザに反映させた場合に問題ないのにHeroku上でマイグレーションエラーが出てしまったら...

![スクリーンショット 2020-10-09 18.48.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587506/bb017b5e-642a-816e-bcd1-d0c12bc97099.png)

その場合はHerokuでは別にマイグレーションする必要があります。

```ruby:terminal
$ heroku run rails db:migrate
```
その後そのままでデプロイしないでHerokuを再度読み込んでみると正常にブラウザに表示がされるかと思います！
C#で性能のいい湯婆婆

名前を削って「今日からお前の名前は～だ」を生成するC#のプログラムを高速化する方法を検討している記事がある。

[C# で湯婆婆を実装してみる「性能のいい湯婆婆を目指して」](https://qiita.com/okazuki/items/0a9e009b3f8736140393)

これにもう一つアプローチを加えてみたい。

文字列をたくさん連結する場合は、一般にStringBuilderを使うのがよいとされているが、一つの式で+でつなぐことができるならそうしたほうが速い。そうすると、+でつないだ文字列をすべて配列に格納して`String.Concat`を一回呼ぶコードが吐かれるからだ。

```csharp
[Benchmark]
public string ConcatWorkstyle()
{
    var newName = Name[1];
    return "契約書だよ。そこに名前を書きな。\r\nフン。" + Name + "というのかい。贅沢な名だねぇ。\r\n今からお前の名前は" +
           newName + "だ。いいかい、" + newName + "だよ。分かったら返事をするんだ、" + newName + "!!";
}
```

ベンチマークは.NET Core 3.1 on AMD Ryzen 7 3800Xで。それでもZStringが最速なので、使える場合はZStringを使うべきかと。

```
|               Method |      Mean |    Error |   StdDev |
|--------------------- |----------:|---------:|---------:|
| TraditionalWorkstyle | 455.32 ns | 6.832 ns | 6.391 ns |
|         NewWorkstyle | 194.72 ns | 3.654 ns | 4.751 ns |
|     AnotherWorkstyle | 284.55 ns | 5.091 ns | 4.762 ns |
|     ZStringWorkstyle |  97.90 ns | 1.102 ns | 1.031 ns |
|      ConcatWorkstyle | 101.58 ns | 1.525 ns | 1.427 ns |

```
ActiveStorageを導入する

#ActiveStorage
画像アップロードをするためにはActiveStorageを使用します。
これと併せて、画像変換できるImageMagickというソフトウェアと、それをrails上で使う為のMiniMagickというGemもインストールします。

・ImageMagick:画像変換ツール（コマンドラインから画像に処理を加えることができるGem)
・MiniMagick:ImageMagickの機能をRubyで使用できるようにしてくれるGem
・ImageProcessing:MiniMagickには提供できない画像サイズを調整する機能を提供するGem

まずターミナルでImageMagickをHomebrewからインストールする

```Ruby:imagemagickのインストール
% brew install imagemagick
```

```Ruby:gemfile
#Gemfileの一番下に記述
gem 'mini_magic'
gem 'imaged_processing', '~> 1.2'
```
追記できたら`bundle install`します。
最後に`rails c`で一旦ローカルサーバの接続を切って、`rails s`でサーバーを立ち上げます。

ここでやっとActiveStorageインストールします。

```Ruby:ターミナル
% rails active_storage:install
#↑コマンドを実行するとテーブルで画像を管理するためのマイグレーションファイルが生成されるので↓コマンドでmigrateします
% rails db:migrate
```
DBに`active_storage_attachments`と`active_storage_blogs`が反映されていればActiveStorageと画像加工ツールの導入の成功です。
loggingの小数点を,から.に変える


検索の上位に出てくる
[Python logging_ use milliseconds in time format - Stack Overflow](https://stackoverflow.com/questions/6290739/python-logging-use-milliseconds-in-time-format)
がちょっと求めているものと違う＋何度か忘れているのでメモする。

```python
import logging
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s.%(msecs)03d  %(message)s",
    datefmt="%H:%M:%S"
)
```

datefmtで秒まで表示するようにして、formatで`%(msecs)03d`をつける。
Could not build the application for the simulator. Error launching application on iPhone  の対応

Flutter歴2日目のひよこの私にこのエラーと出会いビルド実行ができなくなるというくじけそうになりながら解決したので残します。
##バージョン
Flutter 1.22.3 • channel stable
Tools • Dart 2.10.3
AndroidStudio 4.1

##事前にやったこと
- 構築した初日は動いていた。　ならば、覚えていろ、私たちは.......確かに生きていたんだ。
- タイトルのエラーをコピってググってでた１P目の項目は、自分の環境を治すものではなかった。　
- AndroidStudioのFlutter、Dartプラグイン入れ直し　→　Error
- Xcode,AndroidStudioのアンインストールからの再インストールする →　Error
- ターミナルからFlutter doctor みるも！もみつからずチェックで至って健康だった。

##解決
作成したプロジェクトファイル内の、ios/Runner.xcodeprojをXcode側で開く。
![ios.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/809299/d63e686e-2aa4-81e9-773b-650bca0f74d1.png)
初めて開いたら下記のようになっている
![Runner_xcodeproj.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/809299/e683dd9e-6cb6-0fee-fc25-71a477887138.png)
右上三角マークを押すか、左のタブの三角タブを押すと、画面左が次のように変わる。
![Runner_xcodeproj.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/809299/2f08a60b-00dd-af5f-614b-e61c3c4026a1.png)
三角マークがでているUpdate to recommended settingsを押すと、
![Runner_xcodeproj.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/809299/1c2db5ff-eafe-51c7-16c8-d607cf2618aa.png)
このようなものが出てくるので、Peform Changesを押す

お疲れさまでした。本当にお疲れさまでした。

その後、ターミナルなりAndroidStudioでFlutter runをして確認してください。私はコレで動きました。

#注意
新規プロジェクトごとにコレをしないと行けないようなので注意です。
この書きなぐりが少しでも誰かのためになれば幸いです。
vue.jsとhls.jsでスクロールして動画が画面上にある時にだけ動画を再生したい

vue.jsとhls.jsで動画を再生させる基礎
https://qiita.com/asa1084/items/07195a77762e345abb7a


```
<template>
  <div>
    <div style="margin-bottom: 1000px"></div>
    <video id="video" controls muted playsinline loop width="300px"></video>
    <div style="margin-bottom: 1000px"></div>
  </div>
</template>
<script>
import Hls from "hls.js";

export default {
  data: () => {
    return {
      hls: null,
      isPlaying: false,
      screenHeight: 0,
    };
  },

  methods: {
    playVide() {
      const video = document.getElementById("video");

      // ビデオの現在の位置を取得
      const videoTop = video.getBoundingClientRect().top;

      const videoUrl =
        "https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8";

      // ビデオ位置（高さ200込み）が画面サイズに収まっている場合 ※高さ200は仮です
      if (this.screenHeight - (videoTop + 200) > 0 && videoTop + 200 > 0) {
        // 再生中の場合何もしない
        if (this.isPlaying) return;

        // 再生中はplayVideを無効化
        this.isPlaying = true;

        // 動画を取得済の場合は再生処理のみ行う
        if (this.hls != null) {
          video.play();
          return;
        }

        // 終了時、再度再生できるようにする。
        video.addEventListener("ended", (event) => {
          this.isPlaying = false;
        });

        if (Hls.isSupported()) {
          this.hls = new Hls();
          this.hls.loadSource(videoUrl);
          this.hls.attachMedia(video);
          video.play();
        } else if (video.canPlayType("application/vnd.apple.mpegurl")) {
          video.src =
            "https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8";
          video.addEventListener("canplay", () => {
            video.play();
          });
        }
      } else {
        // 再生中の場合、ビデオを停止
        if (this.isPlaying) {
          video.pause();
          this.isPlaying = false;
        }
      }
    },
  },
  mounted() {
    // scrollすると動画再生関数発火
    window.addEventListener("scroll", () => {
      this.playVide();
    });

    // 画面の縦のサイズを取得
    this.screenHeight = window.innerHeight;
  },
  computed: {},
  beforeDestroy() {
    window.removeEventListener("scroll", () => {
      this.playVide();
    });
  },
};
</script>

<style scoped>
</style>
```


解説していきます。

まず動画が画面をスクロールするとmounted内にあるaddEventListenerが呼ばれます。
addEventListenerではvideoを再生する関数を実行させます。

methodsないで動画を再生させる関数videoPlayを定義。

画面上に動画がある時だけ再生させる必要がりますが、デバイスによって画面の大きさが変わるので、動的に決めていく必要があります。

window.innerHeight で画面のたての高さが取得できる。

video.getBoundingClientRect().top()で動画の一番上を取得できます。
詳しいgetBoundingClientRectの使い方は[こちら]
(https://ja.javascript.info/coordinates)

上記を使ってどこに動画がある時に動画再生スタートさせるか決めます。

addEventListenerのendedで動画の再生が終わった時にbooleanを渡してくれます。
なので、動画再生が終わるとisPlayをfalseにしてまたスクロールされると動画が再生されるようにします。

vue.jsはシングルページアプリケーションなので
window.addEventListenerを使っていないページでもaddEventListenerが呼ばれてしまいます。
メモリを食う！ページ高速化のためにも必ずbeforeDestroyで他の箇所では呼ばれないようにしましょう。
AccessのVBAでフォームを閉じたらAccessファイルも閉じる（キー操作でアプリケーション終了）

# やり方

フォームに読み込み解除時のイベントを登録。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/d0a6bb2d-59c7-0055-587e-0898cff0a5b4.png)

```vb:読み込み解除時のイベントコード
Private Sub Form_Unload(Cancel As Integer)
    Application.Quit
End Sub
```

いちいちマウスで右上の×ボタン押さなくても ```Command + W``` でフォームを閉じると同時にファイルも閉じられる。


だが…。これだとフォームを閉じたり、 **デザインモードで開いた時** に **問答無用でファイルが閉じてしまいます** 。

フォーム自体を編集したい場合は開発者モードで開く必要が出ます。
（開発者モードで開く = Shift + ダブルクリックでファイル開く） 

# 若干改良版

```vb:読み込み解除時のイベントコード
Private Sub Form_Unload(Cancel As Integer)
    If MsgBox("ファイル閉じるのん？", vbYesNo + vbDefaultButton1, "確認") = vbYes Then
        Application.Quit
        Exit Sub
    End If
End Sub
```

デフォルトの選択肢がYesなので、通常使う時はCommand + W ⇒ Enterのキーボード操作だけでファイルを閉じられます。
フォームをデザインモードで変更したい時はダイアログでいいえを選択すればOK。

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.1865
Microsoft Access for Microsoft 365 MSO (バージョン 2207 ビルド 16.0.15427.20166) 32 ビット
色々な言語でHello World

# プログラミング言語

## C系

### C
```c
#include <stdio.h>

int main(){
 printf("Hello World!");
}
```

```
gcc hello.c -o hello.out
./hello.out
```

### C++
```cpp
#include <iostream>

int main(){
 std::cout << "Hello World!" << std::endl;
 return 0;
}
```
```
g++ hello.cpp -o hello.out
./hello.out
```

### C Sharp
```csharp
using System;
  class Hello{
  public static void Main(string[] args){
    System.Console.WriteLine("Hello World!");
  }
}
```
```
mcs hello.cs
./hello.exe
```

## なんか人気なやつ
### Vimscript
```vimscript
echo "Hello World!"
```
```
vim -c ":so hello.vim"
```

### Python3
```python
if __name__ == "__main__":
  print("Hello World!")
```
```
python3 hello.py
```
### Node.js (Javascript)
```javascript
console.log("Hello World!")
```
```
node hello.js
```

### Ruby

```ruby
if __FILE__==$0
 puts "Hello World!"
end
```
```
ruby hello.rb
```

### Go
```golang
package main

import "fmt"

func main(){
 fmt.Println("Hello World!")
}
```
```
go run hello.go
```
```
go build hello.go
./hello
```

### R
```r
print("Hello World!")
```
```
Rscript hello.r
```
### Rust
```rust
fn main(){
  println!("Hello World!")
}
```
```
rustc hello.rs
./hello
```

### Common Lisp
```common-lisp
(print "Hello World!")
```
```
clisp hello.lisp
```

### Java
```java
class hello{
  public static void main(String[] args){
    System.out.println("Hello World!")
  }
}
```
```
javac hello.java
java hello
```
クラス名と一致してないといけないのめんどくさい。
### Julia
```julia

print("Hello World!")
```
```
julia hello.jl
```

## その他
### bash
```bash
echo Hello World
```
```
bash hello.bash
```
### fish
```fish
echo "Hello World!"
```
```
fish hello.fish
```

### nim
```nim
echo "Hello World!"
```
```
nim c hello.nim
./hello
```

### 文言
```wenyan-lang
吾有一言。曰「「Hello World!」」。書之。
```
実行はオンラインでどうぞ。。
[Wenyan-lang ide](https://ide.wy-lang.org/)

### brainfuck
```brainfuck
>>>>> >>>>>

< +++++ +++++
[
 >+++
 >+++++ + 
 >+++++ ++
 >+++++ +++
 >+++++ ++++
 >+++++ +++++
 >+++++ +++++ +
 <<<<<<<-
]

>>>++.--
>>>+.-
>--..++
+.-

<<<< <<++.--

>>>> ---.+++
>>+.-
++++.----
--.++
<.

```
```
bf hello.bf
```
## 英語
`Hello World!`

## スペイン語
`¡Hola Mundo!`

## 日本語
`こんにちは、世界！`

## 中国語
`你好，世界!`

気が向いたら適宜追加していきます。
ミスなどありましたら指摘お願いします。
LaravelのJavascript内で環境変数を呼び出す方法

なかなか記事が見つからないのでメモ

.envファイル側

```:.env
GOOGLE_CALENDAR_ID=test@gmail.com
GOOGLE_CALENDAR_APIKEY=*********************abcde8
```

環境変数の呼び出し

```php:test.blade.php
<script>
=== 省略 ===
    events:{
      googleCalendarId: "{{ env("GOOGLE_CALENDAR_ID") }}"
    },

  googleCalendarApiKey: "{{ env("GOOGLE_CALENDAR_APIKEY") }}",
=== 省略 ===
</script>
```
【Rails・Docker】gemを追加したらブラウザ(localhost:3000)でアクセスが拒否されてしまう場合の対処方法

#環境
macOS 10.15.5
Rails 5.2.4.2
Docker 19.03.12

#gemを追加したらブラウザ(localhost:3000)でアクセスが拒否されてしまう場合の対処方法

Dockerの環境でページネーション機能を追加しようとした際に下記のgemを追加してその後```bundle install```を実行しサーバーを再起動...

```ruby:gemfile
gem 'kaminari'
```

```ruby:terminal
$ bundle install
$ docker-compose restart
```

しかしブラウザではアクセスが拒否されてしまいました...

![スクリーンショット 2020-11-06 22.40.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587506/6ea31afa-a691-d4b7-6a0f-e6d1e61bf761.png)

#Dockerの動作確認
まずは```docker-compose up```を実行するとDockerが落ちてしまっていることが確認できましたので下記の操作で再度ブラウザと接続できるかを試みます。

```ruby:terminal
$ docker-compose build
```
そして再度```docker-compose up```を実行します。

```ruby:terminal
$ docker-compose up
```

するとgemを追加した状態でもブラウザへの接続が成功できるかと思います！Dockerの環境でgemの追加の際に落ちてしまった場合に試してください。
Neural Network Console Challenge 入賞作品リスト

#はじめに
 　**Neural Network Console Challenge** (NNC-Challenge) とは、SONYさんが開発したAI開発ツール**Neural Network Console**を使い、協賛企業が提供するデータを用いてディープラーニングに挑戦するAI開発コンテストで、今までに2回開催されています。

　ここでは、今後のChallengeの参考になるように、第1回・第2回の入賞作品リストを備忘録として残します。

#第2回 NNC-Challenge 入賞作品
　[第2回](https://ledge.ai/nnc-challenge-by-audiostock-start/)の協賛企業は、映像制作・イベント・音効業務用のBGM・効果音などを販売している[Audiostock](https://audiostock.jp/)さんです。提供されたデータは、10,000点を超えるBGMデータで、2020.09.16 ~ 2020.10.19 の期間で開催されました。　

**最優秀賞**：[類似曲検索を実現する](http://cedro3.com/ai/nnc-challenge/)
　実際にAudiostockのUXの中であったら良いと感じた類似曲検索をテーマに設定。結果的に有効で高精度な類似曲検索アルゴリズムを開発している。

**Ledge.ai賞**：[会話の内容に合わせてBGMを自動選曲する](https://qiita.com/zakiyama2918/items/e4d38816297668e4cf91)
　BERTによって日常会話を自然言語処理し、"ロック","ポップ","バラード"いずれかに類似度を自動判定し、曲をレコメンドするエンジンを開発。

**NNC賞**：[音声データの喜怒哀楽分類とレコメンド](https://qiita.com/cforestw/items/f8d874fad8b9e5056a84)
　音楽を喜怒哀楽の尺度で数値化し、類似度の高い曲のレコメンドをしている。レコメンド精度は高かった。また、音楽にあった画像のレコメンドという新しい検索方法についても提示している。

**特別奨励賞１**：[楽器「ピアノ」と「エレキギター」を自動分類する](https://www.slideshare.net/yoshi1966/neural-network-console-contest-report-2020-by-kitagawa)
　BGMがピアノ/エレキギターが使われているかを自動分類するアルゴリズム。合計4ステップの学習プロセスで高精度を実現している。

**特別奨励賞２**：[BGMから飲食店をレコメンド](https://qiita.com/n91-takayuki/items/5e289c898cdddd2a6e2f)
　BGMからおすすめなお店（ランチ）を分類するアルゴリズム作成。さらにはそのアルゴリズムで、作者がよく聞く音声データからどんなお店がレコメンドされるかも検証している。

#第1回 NNC-Challenge 入賞作品
　[第1回](https://ledge.ai/nnc-challenge-pixta-report/)の協賛企業は、商業写真を販売している[PIXTA](https://pixta.jp/)さんです。提供されたデータは、10,000点を超える画像データで、2020.03.04 ~ 2020.03.31 の期間で開催されました。

**最優秀賞**：[笑い顔と微笑み顔のニコニコ笑顔分類器](https://qiita.com/cforestw/items/6db745eced1e9c3d5b82)
　人物の表情画像からNeural Network Consoleを用いて、「笑い声が聞こえてきそうな笑顔」「ニッコリ微笑む笑顔」「笑顔以外」の3種類に分類する笑顔分類器を製作した。

**Ledge.ai賞**：[森鴎外の小説からキーワードを選定して分類](https://qiita.com/marico55/items/9d46e96e7c28a9fa199c)
　森鴎外の短編小説「杯」から本編と小説に寄せられた感想やレビューを元に形態素解析し、Neural Network Consoleを用いて抽出したキーワード毎に画像分類した。

**NNC賞**：[画像に写っている人数で分類](https://qiita.com/jun40vn/items/f93b6506c7bc4a2735db)
　さまざまなカテゴリーの画像データに写る人数が1人、2人、グループ（3人以上）なのかをデータセット作成までをNeural Network Console Windows版で、それ以後はCloud版を活用して画像分類した。
Bootstrap4.5で設置したcarouselスライドの画像が変更出来ない

#やりたいこと
作成しているWebページにBootstrapでcarouselスライドを設置したい

#問題
Bootstrapのドキュメントからコピペしたcarouselスライドのimg部分がsvgタグになっていて、用意したimgファイルに入替が出来ない。

コピペしたBootstrap/Components/carouselは以下の日本語ドキュメントサイトを参照
https://getbootstrap.jp/docs/4.5/components/carousel/

⇓ With indicatorsからimg部分を抜粋 ⇓


```html
<div class="carousel-item">
  <svg class="bd-placeholder-img bd-placeholder-img-lg d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: First slide"><title>Placeholder</title><rect width="100%" height="100%" fill="#777"/><text x="50%" y="50%" fill="#555" dy=".3em">First slide</text></svg>
</div>
```
※コードは(carousel-innerの中の１つのitem)
<br>
⇓ With captions ⇓

```html
<div class="carousel-item">
  <img src="..." alt="...">
  <div class="carousel-caption d-none d-md-block">
    <h5>...</h5>
    <p>...</p>
  </div>
</div>
```
<br>
With indicatorsの```carousel-item```の中にWith captionsの```imgタグとdivタグ(h2,p)```を入れ子にすれば良いのか??と思い、実行したところsvgタグの描画は消えず、その下にWith captionsのimgタグで設定した画像が表示される。

#環境
Windouws10
Bootstrap v-4.5


#原因
Bootstrapのドキュメントからコピペしたcarouselスライドのimg部分が日本語ドキュメントサイトと英語ドキュメントサイトとで違っていた。
Bootstrap 日本語ドキュメントサイト　With indicatorsとWith captionsが分かれている記載されている
https://getbootstrap.jp/docs/4.5/components/carousel/

```html
<div class="carousel-item active">
  <svg class="bd-placeholder-img bd-placeholder-img-lg d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: First slide"><title>Placeholder</title><rect width="100%" height="100%" fill="#777"/><text x="50%" y="50%" fill="#555" dy=".3em">First slide</text></svg>
</div>
```
※コードは(carousel-innerの中の１つのitem)
<br>
Bootstrap 英語ドキュメントサイト With indicatorsとWith captionsが分かれていない
https://getbootstrap.com/docs/4.5/components/carousel/

```html
<div class="carousel-item active">
  <img src="..." class="d-block w-100" alt="...">
  <div class="carousel-caption d-none d-md-block">
    <h5>First slide label</h5>
    <p>Nulla vitae elit libero, a pharetra augue mollis interdum.</p>
  </div>
</div>
```
※コードは(carousel-innerの中の１つのitem)
<br>
比較すると日本語ドキュメントは画像部分がsvgタグとなっていて、英語ドキュメントは画像部分がimgタグになっている。

#解決
英語ドキュメントのcarousel/With captionsをコピペして使用した。


#あとがき
日本語版と英語版のどちらも公式のドキュメントだと思っていましたが、それぞれ違っている場合があるので注意が必要。
Linux シンボリックとハードリンクの特徴

#【Linux シンボリックとハードリンクの特徴】

##シンボリックリンク

シンボリックリンクとは、オペレーティングシステム（OS）のファイルシステムの機能の一つで、特定のファイルやディレクトリを指し示す別のファイルを作成し、それを通じて本体を参照できるようにする仕組み。（IT用語辞典 e-Words）

<strong>特徴</strong>

・リンクファイルが使用するiノードはオリジナルファイルと異なる番号
・ディレクトリを基にリンクファイル作成可能
・オリジナルファイルと別のパーティションにリンクファイル作成可能
・パーミションの先頭は、ファイルタイプとしてシンボリックリンクファイルを表す「l」が表示される。

##ハードリンク

ハードリンクとは、ファイルの実体に名前を付けること(ディレクトリに名前を登録すること)、そのものを指す。
そのため、名無しでファイルを作るような状況を除いては必ずハードリンクができる。

（ハードリンクを複数作ることもでき、同じ実体を別名で扱えるので、シンボリックリンクと比較される）

<strong>特徴</strong>

・iノードが同じなので、iノード番号も当然同じになる。
・ディレクトリは、好きな名前で別名としてのハードリンクは不可
・別ファイルシステムのファイル実体に名前を付けることができないので、異なるパーティションのハードリンクは作成不可
（シンボリックリンクは実体ではなくて名前ベースなので、ファイルシステムの違いは問題でないが。）

##※追記

@angel_p_57 様
ご丁寧に誤りの指摘をしていただき、ありがとうございました。
【CSS】transformプロパティで画像や文字を回転させる方法

#プログラミング勉強日記
2020年11月9日
画像を回転させたいときは画像自体を編集していたが、transformプロパティを使うことで回転できることを知ったのでまとめる。

#transformプロパティとは
　トランスフォーム関数(変形関数)と呼ばれる特別な値を指定することで対象要素を3次元で変形させることができる。
　transformプロパティの値に`rotate`というトランスフォーム関数を使って角度を指定すれば指定した角度で文字や画像などHTMLの要素を丸ごと回転できる。また、2Dの平面空間だけでなくX軸・Y軸・Z軸を基準にした3D空間での回転もできる。

```css:2Dと3Dで回転させる場合の記述方法
/* 2D(平面)で回転 */
transform: rotate( 角度 );  
/* 3DのX軸(水平)で回転 */
transform: rotateX( 角度 ); 
/* 3DのY軸(垂直)で回転 */
transform: rotateY( 角度 ); 
 /* 3DのZ軸(奥行)で回転 */
transform: rotateZ( 角度 );
```
　CSSで角度を表す単位は`deg`で、`90deg`であれば90度を示す。(マイナスの値を使うこともできる)

##トランスフォーム関数

| 関数名 | 説明 |
|:--:|:--:|
|none | 要素を変形しない |
|matrix3d() | 行列式によって要素を変形する。16個の任意の数値をカンマで区切って指定する |
|translate3d()	| 要素のxyz座標を移動する。移動距離を単位付きの数値でカンマで区切って指定する。|
|translateZ()	| 要素のz座標を移動する。移動距離を単位付きの数値で指定する。|
|scale()3d	| 要素をx軸、y軸、z軸方向に拡大・縮小する。値はカンマ（,）で区切って指定する。|
|scaleZ()	| 要素をz軸方向に拡大・縮小する。任意の実数で倍率を指定する。|
|rotate3d()	| 要素を回転する。値はカンマで区切って指定する。|
|rotateX()	| 要素をx軸を中心に回転する。回転角度を単位付きの数値で指定する。|
|rotateY()	| 要素をy軸を中心に回転する。回転角度を単位付きの数値で指定する。|
|rotateZ()	| 要素をz軸を中心に、xy平面上を回転する。回転角度を単位付きの数値で指定する。|
|perspective()	| 画面からの視点の距離を指定して、z 軸方向に変形した要素の奥行きを表す。|


#2D回転させる方法
　2D(平面)回転において、`-30deg`を指定して反時計回りに30度回転させてみる。

```css:CSS
.sagrada { 
	transform: rotate( -30deg );  
}
```

```html:HTML
<p class="sagrada">
   <img src="SagradaFamília.jpg" alt="サグラダファミリア">
   サグラダファミリア
</p>
```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/dbdfd243-3a20-532e-6d6e-ae5f16128395.png)

#X軸で3D回転させる方法
　X軸(水平方向の軸)を基準にして180度回転させてみる。

```css:CSS
.sagrada {
	transform: rotateX( 180deg );
}
```


```html:HTML
<p class="sagrada">
   <img src="SagradaFamília.jpg" alt="サグラダファミリア">
   サグラダファミリア
</p>
```

実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/8f8ef026-b857-0343-4d40-1d8bc05c172f.png)

#Y軸で3D回転させる方法
　Y軸(垂直方向の軸)を基準にして180度回転させてみる。(左右反転させてみる)

```css:CSS
.sagrada {
	transform: rotateY( 180deg );
}
```


```html:HTML
<p class="sagrada">
   <img src="SagradaFamília.jpg" alt="サグラダファミリア">
   サグラダファミリア
</p>
```

実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/66a06381-50aa-410f-5da7-3eff3148d56b.png)

#Z軸で3D回転させる方法
　Z軸(奥行きの軸)を基準にして反時計回りに30度回転させてみる。

```css:CSS
.sagrada {
	transform: rotateZ( -30deg );
}
```

```html:HTML
<p class="sagrada">
   <img src="SagradaFamília.jpg" alt="サグラダファミリア">
   サグラダファミリア
</p>
```

実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/4fd1922d-de9f-6434-7967-5de749ec7e62.png)

　これから、Z軸を基準に3D回転させたときは2Dで回転させた時と同じ結果が得られる。


#参考文献
[CSSのtransform:rotateで画像や文字を回転させる方法](https://allabout.co.jp/gm/gc/406310/?FM=compi_linkitem-7)
[transformプロパティの意味と使い方（3D空間での変形）](https://dekiru.net/article/13251/)
【初心者でもわかる】webサイトのショートカットアイコン（スマホ用アイコン）の設定方法（iPhone側のショートカットの作り方も！）

# どうも7noteです。WEBサイトが完成したら忘れずに設定しましょうショートカットアイコン。

どうも7noteです。
この記事は以下へ引っ越しました。

https://naruweb.com/coding/iosicon/
sklearnのtrain_test_splitのrandom_stateの必要性

# train_test_splitとは
機械学習でよく使われる関数としてtrain_test_splitがあります。
これはlistや、numpy.arrayや、pandas.DataFrameなどを、学習用のtrainデータとtestデータに分割してくれる関数です。

# random_stateとは
まず、train_test_splitのデフォルトの引数であるshuffle=Trueによってデータを分割する前に、データの行の順番がランダムにされています。そして、random_stateとはこの時のデータのランダムな行の順番を固定する引数です。固定するにはrandom_stateにint型の任意の値を設定します。(0、42など)
random_stateのデフォルトにはNoneが入っており、Noneのままだと、データのランダムな行の順番が固定されず、train_test_splitを再実行すると再実行前と異なるtrainデータ、testデータを返します。

# random_stateで行の順番を固定する必要性
testデータが実行する度に異なると、ハイパーパラメータのチューニングが無意味になったり、複数モデルを作って多数決を取る際(アンサンブル法)に予測結果が異様に高い精度を出す現象を引き起こします。

以下に予測結果が異様に高い精度を出す実例を紹介します。

まず実験用のデータフレームを作ります。

```python
import pandas as pd
from sklearn.model_selection import train_test_split
df=pd.DataFrame({"a":[1,2,3,4,5],"b":[1,2,3,4,5]})
print(df)
```
```
   a  b
0  1  1
1  2  2
2  3  3
3  4  4
4  5  5
```

次にtrain_test_splitをします。引数であるtrain_sizeとtest_sizeのどちらか片方にfloat型の任意の値を入れることで行数に対しての割合、int型の任意の値を入れることで行数の内何個であるという個数を指定できます。
片方だけ指定するとtrainデータとtestデータのどちらを指定しているか紛らわしいので、本例のようにデータ数が5個ならばtrain_size=4(個)、test_size=1(個)と両者明示的に指定しておくのがいいかと思います。

```python
train_x, test_x = train_test_split(df, train_size=4, test_size=1)
print(train_x)
print(test_x)
```
```
   a  b
1  2  2
2  3  3
0  1  1
3  4  4
```
# random_stateに何も指定しない場合のコード
random_stateに何も指定しない場合(つまりtrain_test_splitのデフォルトであるrandom_state=Noneである場合)train_test_splitを実行する度に違うtrainデータとtestデータを返します。

```python
for i in range(3):
    train_x, test_x = train_test_split(df, train_size=4, test_size=1)
    print()
    print(i,"回目")
    print(train_x)
    print(test_x)
```

```
0 回目
   a  b
2  3  3
3  4  4
4  5  5
0  1  1
   a  b
1  2  2

1 回目
   a  b
2  3  3
4  5  5
1  2  2
0  1  1
   a  b
3  4  4

2 回目
   a  b
4  5  5
0  1  1
1  2  2
3  4  4
   a  b
2  3  3
```

例えば、この3データを3つの異なるモデルにそれぞれ学習させtestデータの予測結果で、多数決を取ろうとする(アンサンブル法)と
![asdfasdf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369642/bd3ab33c-a80d-97cb-f401-cc0049192353.png)
この画像のようにモデルごとに学習したtrainデータが異なり、モデルに学習データとして未知の部分がないためtestデータの予測結果の多数決の際に異様に高い精度を出してしまうことが予想されます。これを避けるためにrandom_stateが必要です。

# random_stateに42を指定した場合のコード

```python
for i in range(3):
    train_x, test_x= train_test_split(df, train_size=4, test_size=1, random_state=42)
    print()
    print(i,"回目")
    print(train_x)
    print(test_x)
```

```
0 回目
   a  b
4  5  5
2  3  3
0  1  1
3  4  4
   a  b
1  2  2

1 回目
   a  b
4  5  5
2  3  3
0  1  1
3  4  4
   a  b
1  2  2

2 回目
   a  b
4  5  5
2  3  3
0  1  1
3  4  4
   a  b
1  2  2
```
random_stateを42に指定したため、test_xが[2 2]に固定されているように、train_test_splitを再実行しても固定されたランダムなtrainデータが返ってくるので、学習の際に未知のデータを確保でき、予測結果が異様に高い精度となるのを避けることが出来ます。
[Swift]TableViewで特定のセルだけ削除できなくするメモ

#今回の題
とある機能の作成過程で配列の先頭(0番目)をデフォルトで持たせておいて、その値は削除できない様にしたかった時に使った方法をここに書き残します。
シンプルな内容です。


#やり方

これだけ。
UITableViewDelegateのdelegateメソッドで、各セルのediting styleを設定します。
今回は０番目に対してnoneを当て、それ以外にdeleteを当てる事で０番目だけ削除不可を実装しました。

```swift
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
    indexPath.row == 0 ? .none : .delete
}
```

swiftは{}内が一行であればreturnを省略できるので三項演算子を使って書くと良き。
ちなみにif文で書くとこう。

```swift
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
    if indexPath.row == 0 {
        return .none
    }
    return .delete
}
```

以上です。
日本の情報通信産業の部門別雇用者数の推移を可視化

[令和2年版の情報通信白書](https://www.soumu.go.jp/johotsusintokei/whitepaper/ja/r02/pdf/index.html)の日本の情報通信産業の部門別雇用者数の推移を可視化

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">令和2年版の情報通信白書が総務省から公開されている。<br>個人的に面白いのはデータ編、情報通信産業の部門別雇用者数の推移。2000年度から18年度まで、さぞ増えているかと思いきや、9つある分野の中で増えているのは情報サービス業とインターネット付随サービス業のみ。他はすべて減少している。 <a href="https://t.co/L6EIxY2M9p">pic.twitter.com/L6EIxY2M9p</a></p>&mdash; 荻原 和樹 / Kazuki OGIWARA (@kaz_ogiwara) <a href="https://twitter.com/kaz_ogiwara/status/1325710263614500867?ref_src=twsrc%5Etfw">November 9, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

# ダウンロード

```shell
wget https://www.soumu.go.jp/johotsusintokei/whitepaper/ja/r02/pdf/02data.pdf -O data.pdf
```

# プログラム

```python
import pandas as pd
import pdfplumber

with pdfplumber.open("data.pdf") as pdf:

    page = pdf.pages[4]

    # 範囲を切り取り
    crop = page.within_bbox((50, 100, page.width - 50, page.height - 400))

    table_settings = {
        "vertical_strategy": "lines",
        "horizontal_strategy": "lines",
        "intersection_x_tolerance": 15,
    }

    im = crop.to_image()

    # テーブル確認
    im.debug_tablefinder(table_settings)

    table = crop.extract_table(table_settings)

    table[0][0] = "中分類"
    table[0][1] = "小分類"

    df = pd.DataFrame(table[1:], columns=table[0])

    df1 = df[
        df["中分類"].str.startswith(("1", "2", "3", "4", "5", "6", "7", "8", "9"))
    ].drop("小分類", axis=1)

    df1["中分類"] = df1["中分類"].str.lstrip("123456789．")

    df1.set_index("中分類", inplace=True)

    # カンマを除去、整数に変換
    df2 = df1.applymap(lambda s: s.replace(",", "")).astype(int)

    df2
```
# テーブル確認結果

![table.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36151/2276af19-15fa-99ba-9de9-3c13ca4695ed.png)

# 可視化
```python
import japanize_matplotlib
import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.rcParams["figure.dpi"] = 200

df2.T.plot(grid=True)

plt.legend(bbox_to_anchor=(1.05, 1), loc="upper left", borderaxespad=0, fontsize=8)

# グラフを保存
plt.savefig("01.png", dpi=200, bbox_inches="tight")
plt.show()
```

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36151/2194aa6b-be5d-ef3f-dd01-948a3cb7e5cc.png)
Raspberry Pi 時計同期設定

## 時刻同期先サーバ設定

```sh
$ sudo vi /etc/systemd/timesyncd.conf
```

以下を追加する

```
NTP=ntp.nict.jp
FallbackNTP=time.google.com
```

以下を実行する。

```sh
$ sudo systemctl enable systemd-timesyncd
$ sudo timedatectl set-ntp true
$ sudo systemctl restart systemd-timesyncd
```

## タイムゾーン設定

日本時間にする。

```sh
$ sudo timedatectl set-timezone Asia/Tokyo
```

日時を確認する。

```sh
$ date
Mon Nov  9 21:15:16 JST 2020
```
Gitで使えない文字列を調べてみた

# 概要

ドキュメントを確認してgitで使えない文字列を調べまとめた。

# 調査方法

公式のドキュメントを確認した。

以下コマンドでドキュメントを参照できる。

```jsx
git help check-ref-format
```

以下にドキュメントがある。

`file:///C:/Program%20Files/Git/mingw64/share/doc/git-doc/git-check-ref-format.html`

> 参照は、Git でブランチやタグを指定するために使われます。ブランチの先頭は refs/heads 階層に、タグは ref 名前空間の refs/tags 階層に格納されます (通常は $GIT_DIR/refs/heads や $GIT_DIR/refs/tags ディレクトリに格納されます。)

Gitをふんわり使っていたので、実際にGit管理されているリポジトリを確認してみたら理解ができた。

Gitのブランチやタグの実態は階層構造で管理されていて、以下をたどると`refs`フォルダがある。

タグ：/.git/refs/tags

リモートブランチ：/.git/refs/remotes/origin

HEADS：/.git/refs/heads/

# 結論

ドット.、クエスチョンマーク?、スラッシュ/、アットマーク@、バックスラッシュ\の使用には注意が必要。

Git は、参照の名前の付け方について次のようなルールを課しています。

## ドットの使用には注意

- 始端終端はドットにできない

階層的な(ディレクトリの)グループ化のためにスラッシュ `/` を含めることができますが、スラッシュで区切られたコンポーネントは、ドット `.`で始まったり、.lock で終わったりすることはできない。

これにより、`head/`や`tags/`などのカテゴリの存在が強制されますが、実際の名前は制限されません。もし `--allow-onelevel` オプションが使われている場合、この規則は放棄される。

- 2つの連続したドットを持つことはできない

それらは、ASCII制御文字(すなわち、値が\040, または\177 DELより小さいバイト)、スペース、チルダ`〜`、キャレット`^`、またはコロン `:` をどこにも持つことはできない。

- ドットで終わることはできない

## クエスチョンマークの使用には注意

- クエスチョンマーク ? この規則の例外については、以下の `--refspec-pattern` オプションを参照すべし。

## スラッシュの使い方には注意

- スラッシュ `/` で始まったり終わったり、複数の連続したスラッシュを含むことはできない

## アットマークの使用

- シーケンス `@{` を含むことはできない。
- `@`を一文字にはできない。

## バックスラッシュの使用

- バックスラッシュ`\`を含めることはできない。

# ブランチ名のチェック

以下のコマンドで妥当なブランチ名なのかチェックができる。

```jsx
git check-ref-format --branch <ブランチ名>
```

例：

```jsx
$ git check-ref-format --branch //next
fatal: '/next' is not a valid branch name
```

# 終わりに

今回、Gitが内部的にどう動いているか意識するきっかけになった。

内部的なことを知らなくてもググればわかりやすい資料やら記事が出てくるけど、ドキュメントを読むと読み解くために必要な用語を調べなきゃいけなかったりするので世界が広がってよいなあと思った。

知れば知るほどGit難しい。

Headやブランチについては今後調べて理解を深めていきたい所存、、！

この方の記事とか参考になりそう。

[GitのHEADとは何者なのか - Qiita](https://qiita.com/ymzk-jp/items/00ff664da60c37458aaa)
Precompiling assets failed.の対処法（自分流）

Precompiling assets failed.ってなかなか消えないときありますよね。

```
rails assets:precompile
rails assets:precompile RAILS_ENV=production
```
特に上記のコマンドをやっても治んないとき。

##解決法
適当なファイルひらき
①適当な１文字を追加
② git add .とgit commit -m "commit"で保存
③さっき追加した文字を削除
④またgit add .とgit commit -m "commit"で保存

こんな適当なので治るの？と思うかもしれませんが僕の環境ではこれでかなりの確率で治ります。理由はわかりませんが...。

####プチ宣伝
こんな記事で宣伝なんかすんな！って人、僕もそう思います。
プログラムコードを販売できるサービスを作りました。
今なら手数料無料です！
URL
https://www.code-sell.net/

紹介記事
https://qiita.com/UTOG/items/40baefaf9a4a668d39cc
[symfony]twigからリポジトリのメソッドの呼び出し方

# 経緯
やりたいことは複数のViewページでResourceのBlockを表示すること。
Repositoryに処理を記載し、Blockとして用意したtwigからメソッドを呼び出す方法がわかりませんでした。

# 結論
```twig
{% set 変数 = repository('Eccube\\Entity\\エンティティ名').メソッド名() %}
```
これで、Entity配下の名前と一致するリポジトリ内にあるメソッドの処理結果を取り出すことができます。


### 記載例
例としてこのように書きます。

```twig
// カテゴリ一覧
{% set Categories = repository('Eccube\\Entity\\Category').getList() %}
```

# 参考
https://homupedia.com/eccube4-template-data.html
addEventListenerメソッド

addEventListenerメソッドについて学習したため、アウトプットいたします。

#addEventListenerメソッドとは？
ある要素に対してクリックする、マウスを乗せる等のイベント（以後イベントと記述します）が起きたときに何か処理を実行したい場合、このメソッドを使って定義することができる

使い方

```csharp
(DOMオブジェクト）.addEventListner("イベント名", 関数)；
```

実際に使ってみましょう

```csharp
var text.querySelector("review");
//読み込んでくるDOMオブジェクトを定義。今回はtextという何かのレビューが入った文章をDOMオブジェクトとしている

function print_selected(){
 console.log("レビューが選択されました");
//addEventListenerで実行される関数を定義

text.addEventListener("select", print_selected);
//DOMメソッドであるtextにイベント時（今回は選択されたとき）起こる関数をここで定義
```

これで完了です
VirtualBoxを利用してCentOS8を起動させる

# 概要
プログラム初学者が、Linuxコマンドの習得のため「[Linux標準教科書](https://linuc.org/textbooks/linux/)」に沿って学習中していました。
カリキュラム上でCentOSをインストールする記述がありましたが、CentOS8に関する記載がなかったので自分で調べてみました。
CentOSのダウンロードページとか結構変わっているので参考になれば幸いです。

## 環境
macOS Catalina
MacBookAir(光学ドライブなし)
※教科書にはDVDを使ってインストールする手順が書いてあるけど、DVDは読み込めない。

## 何をするのか
教科書を読んだときには、linuxをインストールすれば良いのね。サイトからダウンロードするのかしら？って感じの理解だったけど、よく考えるとOSソフトなので普通にインストールできないと気づく。
調べた結果、VirtualBoxという仮想化ソフトを使うことでMacOS上でもCentOSを仮想的に動かすことができるとわかりました。

###### 参考
[MacでVirtualBoxを使ってCentOS 7をインストールしてみた](https://qiita.com/nooboolean/items/de4e6bbae5df040177af)
ほとんどここに書いてあるので、CentOS8が無事にダウンロードできれば問題ないかと。

[Mac上でVirtualBoxをインストールして、CentOS 8を構築した時の詰まった点]
(https://qiita.com/blackpeach7/items/bc181a6115bbb8cf97ba)

## VirtualBoxをインストール
[公式](https://www.virtualbox.org/)にダウンロードリンクがあるのでそこから普通にダウンロードするだけ。
![スクリーンショット 2020-11-09 20.25.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702799/8d7b6b6c-5821-6070-5ce9-352fa1ab1627.png)
「OS X hosts」というリンクからdmgファイルがダウンロードできるので、開いてインストール。

## CentOSをダウンロード
[公式](https://www.centos.org/)からダウンロード。
いろいろバージョンがあって迷いますが、ここは「CentOS Linux」を選択。
![スクリーンショット 2020-11-09 20.30.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702799/025e567b-6d7d-3d52-0aa3-dfdc6c42c942.png)

次にISOファイルの「x86_64」を選択。
![スクリーンショット 2020-11-09 20.32.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702799/a02e3c89-6ef8-1753-e916-bd651a9abb81.png)

どの種類をダウンロードするのか選択するページが表示されます。
`The following mirrors in your region`と書いてあるところならどれでもOKみたいですが、私は`http://ftp.iij.ad.jp/pub/linux/centos/8.2.2004/isos/x86_64/`と書いてあるところからダウンロードしました。（rikenって書いてある物を選択したけど、ダウンロードがかなり進まなかったのでiijに変更しました。）
![スクリーンショット 2020-11-09 20.33.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702799/67012692-1b30-0be0-9eed-80e02e38178f.png)
このダウンロードしたデータがISO形式で、CentOS8のインストーラーが入っているファイルのようです。
この後にVirtualBoxを起動して、その仮想マシンにCentOS8をインストールします。

## VirtualBoxの仮想マシンにCentOSをインストール
ここからの手順は基本的に、[参考のURL](https://qiita.com/nooboolean/items/de4e6bbae5df040177af)と一緒なのでそちらを参考にしてください。キャプチャの画像通り進めれば問題なくCentOS起動するかと思います。
私が詰まったのはネットワークの接続の部分です。

それはこちらの[記事を参考](https://aw1.jp/web/virtualbox-centos8-ssh/)にしてNATで接続しました。
ゲストOS（CentOS）→VirtualBox(ルーターの役目)→ホストOS(macOS)という設定をして、ネットワーク設定が構築できました。

# まとめ
この後、CentOSをGUIではなくCLIで操作したくなったので、再度OSのインストールのやり直しなど行いましたが無事にLinuxの学習を進めることができました。
ネットワークの接続の部分に関しては、Linux標準教科書の後に「[AWS基礎からのネットワーク＆サーバー構築](https://www.amazon.co.jp/Amazon-Web-Services-%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E3%81%AE%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E6%A7%8B%E7%AF%89/dp/4822237443)」で学習して、NATとかIPアドレスの記載方法とか理解したので、今記事を書いているときに何をしていたかわかるようになりました。
networkx2neo4j

## 前書き

**記事のタイトルだけ見て来てしまった人は，この前書きを読む必要が一切ありません**

これは[上智大学エレクトロニクス研究部のアドベントカレンダー](https://qiita.com/advent-calendar/2020/sophia_ele_lab)2日目ですが，この記事の内容は上智大学エレクトロニクス研究部とは1ミリも関係ないです．



### 動機
生成コストの高いクソデカグラフを生成する必要があったので，それを保存したいな～～～と思ったのが事の発端です．しかしneo4jを利用する必要があったのでしょうか？


## neonx

networkxからneo4jへグラフをコンバートするためのモジュールですが，[リポジトリ](https://github.com/ducky427/neonx)を見る限り2014年で開発が途絶えてて怖いので，ここでは使わないことにします．

## neo4j

グラフデータベースの一つです．
エンタープライズ版はお金がかかるのでコミュニティ版を利用します．

### 構築

いろいろ出されていますが，今回はDockerを利用します．

#### プラグイン

標準モジュールだけでは今回やりたいことは出来なさそうなので，`apoc.import.graphml`を使えるようにします．
[ここ](https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/)からjarファイルをダウンロードしたら`./plugins` に配置してください．

#### docker-compose

`docker-comose up -d`すれば[localhost:7474](localhost:7474)にアクセスして使えるようになります．うれし～～～．

```yml:docker-compose.yml

version: '3'
services:
  neo4j:
    image: 'neo4j:4.1'
    container_name: neo4j
    ports:
      - "7473:7473"
      - "7474:7474"
      - "7687:7687"
    volumes: 
      - "./data:/data"
      - "./logs:/logs"
      - "./conf:/conf"
      - "./import:/var/lib/neo4j/import"
      - "./plugins:/plugins"
    environment: 
      NEO4J_dbms_security_procedures_unrestricted: "apoc*,algo*"
      NEO4J_AUTH: "user/password"

```

## networkx

グラフをごにょごにょするためのPythonのモジュール．

### 構築

pipでインストールするだけ．

```bash
pip install networkx
```

## 実行

手順は以下の通り

1. グラフを生成
2. pythonから`write_graphml`を呼んでエクスポート
3. neo4jから`call apoc.import.grahml`を呼んでインポート

実際のコードは以下


```python:sample.py
import networkx as nx

#例として頂点数10の完全グラフを生成する
graph = nx.complete_graph( 10 )

#graphML形式で書き出し
nx.write_graphml( graph, './import/example.graphml' , named_key_ids=True )
```

次にneo4j．
[localhost:7474](localhost:7474)にアクセスして接続設定をしたのちに，以下を打ち込みます．

```cypher:neo4j
CALL apoc.import.graphml("./import/example.graphml", {})
```

これでインポートして完了．


## まとめ

単にnetworkxのグラフを保存したい人はgraphmlでもgmlでも好きな形式で保存すればよいと思います．neo4jを利用する必要はたぶんないです．

## あとがき

### 上智大学エレクトロニクス研究部について

人の家でコンデンサ爆破して楽しむ人の集まりです．めちゃくちゃ臭かったし絶対許さないからな．

### 小学生並みの感想


顔も知らないハチャメチャに優秀なメンバーが気合の入った記事を1日目に書いてしまったので辛かったです．
[php]cookieの説明 +ページ遷移で消えてしまう際の対応

# 経緯
setcookieで保存したクッキーがページ遷移した際に消えてしまう現象が起きました。
その対処法をここに記載致します。

# 結論
このような記述を書いていました。

```php
setcookie(cookie名, cookie保存内容);
```


上の記述を以下のように記述する。

```php
setcookie(cookie名, cookie保存内容, (time()+1800), "/");
```

# クッキーとは
HTTPにおける情報を管理する通信プロトコルやウェブブラウザに一時的に保存できる情報のことを指します。
HTTPにおけるウェブサーバとウェブブラウザ間で状態を管理する通信プロトコル、またそこで用いられるウェブブラウザに保存された情報のことを指します。
ユーザ識別やセッション管理を実現する目的などに利用されます。
Cookieを残しておくと第三者に不正使用される可能性があるため、個人情報は載せてはいけないです。

# setcookieの説明
クッキーを保存できます。

```php

例）
setcookie('cookie_name', 'クッキーです');
```

上の例のように引数2個だけでも、クッキーへ値を渡せます。

# ブラウザでクッキーの確認
![スクリーンショット 2020-11-09 20.17.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574173/32c95be0-2e8c-a021-fb36-634dd2329bfb.png)

ディベロッパーツールを開いて、画像中①のようにApplicationタブを押下し、
Storage配下のCookiesを見ると保存したクッキー情報が入っています。

例で入力した「cookie_name」が入ってることが確認できます。

## クッキーの取り出し方

`$_COOKIE['クッキー名']`で取り出せます。

```php
echo $_COOKIE['cookie_name'];
```

# ページ遷移でcookieが消える理由
有効範囲がpathで指定されてるからです。

先ほどブラウザでクッキーを確認したところにpathが書いてあります。

![スクリーンショット 2020-11-09 20.32.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574173/678e33e8-8de2-5bf5-b5e0-e00e92e4fb28.png)

pathは`/products/detail`になっています。（※例として使っています。）
よって、productsディレクトリ配下のファイルであればクッキーへアクセスできます。

しかし、productsディレクトリ配下ではない別のディレクトリからクッキーへはアクセスできないようになっています。
これがsetcookieの仕様でマニュアルに記載されています。

↓マニュアルです。
https://www.php.net/manual/ja/function.setcookie.php

# 対処方法
先ほどの例ではsetcookieを使用する際に、
`setcookie('cookie_name', 'クッキーです')`
このように第２引数までしか付けず、有効期限やpathを指定していませんでした。

このpathを指定を変えることで別のディレクトリでも使用できるようになります。

```php
`setcookie('cookie_name', 'クッキーです', (time()+1800), '/')`
```

有効期限を30分、pathを`'/'`にしました。
`'/'`はルートディレクトリを表しています。どのページからでもアクセスすることができます。

ブラウザを更新すると、pathが変更されて表示されます。
![スクリーンショット 2020-11-09 20.48.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574173/aed03321-7e7d-6b09-5e5b-9d0b5c95f5ed.png)

# 参考
https://office-obata.com/report/memorandum/post-4546/
【R1C1→A1用】Excelの列番号を英文字に変換する【VB.NET】

# Introduction

[
Excel の列番号を英文字に変換する方法 | Microsoft Docs](https://docs.microsoft.com/ja-jp/office/troubleshoot/excel/convert-excel-column-numbers)
を自分用にVB.NETでちょい編集。

諸事情でR1C1形式が使えなく、仕方なしでA1形式に変換しなければいけないので、、、

# Program

```vb:Program.vb

Imports System

Module Program
    Sub Main(args As String())
        ' 標準入力
        Console.Write("Please Input x : ")
        Dim x AS Decimal = Console.ReadLine()

        ' 変換して標準出力
        Console.WriteLine(ConvertToLetter(x))
    End Sub


    ' Excel の列番号を英文字に変換する
    ' 例) 1 -> A , 26 -> Z , 29 -> AC
    ' https://docs.microsoft.com/ja-jp/office/troubleshoot/excel/convert-excel-column-numbers
    Function ConvertToLetter(iCol As Decimal) As String
        Dim a As Decimal
        Dim b As Decimal
        a = iCol
        ConvertToLetter = String.Empty

        ' iCol が1未満の場合、終了
        Do While iCol > 0
            a = Int((iCol - 1) / 26)    ' (iCol-1) を 26で除算した商
            b = (iCol - 1) Mod 26       ' (iCol-1) を 26で除算した余り

            ' b を 対応するアルファベット文字 ( 0 => A , 25 => Z )に変換し、結果を文字列の先頭に付加
            ConvertToLetter = Chr(b + 65) & ConvertToLetter

            ' iCal に a を代入してループ
            iCol = a
        Loop
    End Function
End Module

```

## Output

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198686/1b82a4c4-f864-8109-327a-94985da428f2.png)
【Linux】リソース確認系のコマンドをまとめてみた

最近、LPIC201の学習を開始したのですが、リソース確認系のコマンドが多いのでまとめることにした。

# sarコマンド
sar [オプション] [表示間隔(秒) [回数]]
sadcコマンドが収集したバイナリデータをテキスト形式に変換し、様々な情報を表示。

|オプション|意味|
|---|---|
|-u|CPU使用率を表示|
|-P 番号かALL|指定したCPU使用率を表示|
|-r|物理メモリの使用状況を表示|
|-S|スワップ領域の使用状況を表示
|-b|ディスクI/Oの状況を表示|
|-n DEV|ネットワークインターフェースの送信・受信パケットの情報を表示|
|-n EDEV|ネットワークインターフェースの送信・受信エラーパケットに関する情報を表示|
|-f ファイル名|データを取り出すログファイルを指定|

# ssコマンド
ss [オプション]
ネットワークの状態に関する情報を表示。netstatの代替。

|オプション|意味|
|---|---|
|-a|全てのソケットを表示|
|-n|アドレス・ポートを数字で表示|
|-t|tcpを表示|
|-u|udpを表示|

# その他

|コマンド|意味|
|---|---|
|w|ログインしているユーザとそのプロセス情報を表示|
|mpstat|マルチプロセッサシステムのCPUの使用状況を表示|
|vmstat|物理メモリ、スワップ領域の詳細な情報と、プロセスやCPUの統計情報などを表示|
|iostat|ディスクI/O情報、CPU使用率を表示|
|netstat|ネットワークの状態に関する情報を表示|
|free|メモリやスワップ領域の使用状況を表示|
|pidstat|実行中のプロセスごとの稼働状況を表示|
|uptime|システムの稼働時間や負荷平均を表示|
|top|全体、プロセスごとのCPUやメモリの使用状況を一定時間ごとに更新して表示|
|htop|topコマンドのパワーアップ版|
|iotop|ディスクI/Oの情報をプロセスごとに表示|

# 終わりに
似たような意味のコマンドが多くて覚えづらい・・・
また新しいコマンドを学んだら更新していきます！
PHPでHTTPデータのダブルクォーテーションが勝手にエスケープされる

# 事象
GETやPOSTで送信されるデータにダブルクォーテーションが含まれている場合、勝手にエスケープされてされてしまい少しハマりました。

```
\"保登心愛\"香風智乃\"
```

# 原因

原因はphp.iniの`magic_quotes_gpc`が有効の為でした。

> GPC(Get/Post/Cookie) 処理に関する magic_quotes の設定を行います。 magic_quotes が on の場合、'(シングルクオート)、" (ダブルクオート)、\(バックスラッシュ) 、NULL には全て自動的に バックスラッシュでエスケープ処理が行われます。magic_quotes_sybase も on の場合、シングルクオートは、バックスラッシュではなく シングルクオートでエスケープされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29324/ec27572c-471a-2871-88fc-1ca5e66c59d3.png)

ちなみに`magic_quotes_runtime`と`magic_quotes_sybase`は以下
> magic_quotes_runtime が有効の場合、 データベースおよびテクストファイルを含む外部ソースから データを返す全ての関数のクオートは、バックスラッシュで エスケープされます。
> magic_quotes_sybase 有効な場合、シングルクオートはバックスラッシュではなくシングルクオートで エスケープされます。 onの場合、 magic_quotes_gpc の指定を完全に上書きします。 これら両方のディレクティブを有効にすると、シングルクオートは ''とエスケープされます。 ダブルクオートやNULLはそのままとなり、エスケープされません。  

# 対策

対策方法は３つあります。

## php.ini

```
magic_quotes_gpc = Off
```

## .htaccess

```
php_flag magic_quotes_gpc Off
```

## プログラム

```
$str = stripslashes($_POST['coco_chino']);
```

この仕様は5.4.0で削除されたのでほとんどの人は遭遇しないと思われます。。。
[マジッククオートとは](https://www.php.net/manual/ja/security.magicquotes.what.php)

- - -

参考記事
[PHPでクォーテーションが勝手にエスケープされてしまう時は](https://staku.designbits.jp/magic-quotes-gpc-on/)
[【PHP】POST送信時にクォーテーションが勝手にバックスラッシュでエスケープされてしまう【マジッククオート】【WordPress】](https://sakura.monte-verita.biz/3786)
DNS(ドメイン、IPアドレス)について解説

<h1>DNSについて</h1>

Domain Name Systemの略。

DNSはドメイン名とIPアドレスを紐付けて、変換する際に使われる。


<h2>ドメインとは</h2>

インターネット上の住所のことをさしており、メールアドレスの「gmail.com」のgmailの部分をこと。

インターネット上の住所と言われているIPアドレスは覚えにくいため、ドメインが使われている。


<h2>IPアドレスとは</h2>

インターネット上の住所のような役割を果たすもの。

IPv4,Ipv6の２種類があり、172.16.254.2といった表記で表される。
【PHP8.1】8進数も基数表示を明記したい

PHPの数値リテラルは、いくつかの基数をサポートしています。

```php:全部16
$a = 16;         // 10進数
$a = 0x10;       // 16進数
$a = 0b00010000; // 2進数
$a = 020;        // 8進数
```

8進数だけおかしくない？
ということで[Explicit octal integer literal notation](https://wiki.php.net/rfc/explicit_octal_notation)というRFCが提出されました。

# Explicit octal integer literal notation

## Introduction

PHPの8進数リテラル表記は、`"016" == 016`がfalseになるなどよくわからない結果になることがあります。
これは`016`が8進数であり、10進数でいう`14`になるからです。

この表記は、Java、C、C#、Golang、Haskellその他諸々の言語と同じ規則であり、たしかに確立された文法ではあります。
一方[Python](https://docs.python.org/3/reference/lexical_analysis.html#integer-literals)・[JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Numbers_and_dates)・[Rust](https://doc.rust-lang.org/rust-by-example/primitives/literals.html)は`0o`表記のみをサポートしています。

　※RFCにはこう書かれてるけど、実際はC#には[8進数リテラルはない](#comment-fe2162e5b49e68d10a1c)みたい。


PHPの[octdec](http://www.php.net/octdec)や[base_convert](https://www.php.net/base-convert)関数は、実はしれっと`0o`表記をサポートしていたりします。


## Proposal

16進数の`0x`、2進数の`0b`と同じように、8進数リテラルを表す接頭辞`0o`をサポートします。

```php
0o16 === 14; // true
0o123 === 83; // true

016 === 0o16; // true
```

## Behaviour of numeric strings

PHP7.0では、文字列での基数表記は[サポートされていません](https://wiki.php.net/rfc/remove_hex_support_in_numeric_strings)。
数値型文字列における基数サポートは、複雑で混乱を招くため却下されました。

> However supporting octal numbers is not possible, because handling the string '0123' as the number 83 would be highly unexpected for end users of an application.
> 8進数のサポートは不可能です。
> なぜなら文字列`'0123'`を数値`83`と解釈することは、ユーザにとって全く予期せぬ結果になります。

従ってこのRFCも、文字列に対しては何の影響も及ぼしません。
`'0o16'`は今後もただの文字列です。

## Backward Incompatible Changes

互換性のない変更はありません。

## Proposed PHP Version(s)

PHP8.x

## RFC Impact

### To Existing Extensions

GMPエクステンションは8進数表記への対応が必要。
FILTER_VALIDATE_INTフラグのFILTER_FLAG_ALLOW_OCTALは対応が必要。

### To Opcache

特になし。


## Unaffected PHP Functionality

現在の、暗黙の8進数表記の動作に変更はありません。


## Future Scope

・いずれ暗黙の8進数表記を非対応にする。
・数値型文字列において進数表記をサポートする。


## Patches and Tests

[GitHub](https://github.com/php/php-src/pull/6360)には既にパッチが上がっています。


# 感想

えっマジかよ。
[マジだった](https://3v4l.org/Aq6T0)。

```php
var_dump(octdec('020')); // 16
var_dump(octdec('0o20')); // 16
var_dump(base_convert('020', 8, 10)); // "16"
var_dump(base_convert('0o20', 8, 10)); // "16"
```

[マニュアル](https://www.php.net/manual/ja/function.octdec)にもユーザノートにも一切書かれていない超絶秘密機能が隠されていたとはびっくりだよ。
こういうのって、探せば他にもあるかもしれませんね。

さて、このRFCはまだ提出されただけです。
今後受理されるか却下されるかは、投票を待たなければいけません。
しかし特に反対するような理由もないだろうし、さらに[Sara Golemon](https://externals.io/message/112090#112094)と[Nikita](https://externals.io/message/112090#112115)の二人が早々と賛成しているので、まず間違いなく通るでしょう。

そしてそんなに重たい内容でもなさそうなので、おそらくPHP8.1あたりでさくっと導入されると思います。
今後は以下のようにわかりやすく表記できるようになることでしょう。

```php:全部16
$a = 16;         // 10進数
$a = 0x10;       // 16進数
$a = 0b00010000; // 2進数
$a = 0o20;        // 8進数
```

0とoがわかりにくいな。
Spring Bootがアプリケーションの実行環境を判定するロジック

# 目的

Spring Bootの公式ドキュメントを見ていると、 ["If your application runs in Cloud Foundry or Heroku"](https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/htmlsingle/#howto-use-behind-a-proxy-server) のように、アプリケーションの実行環境を判定している記述があるので、判定方法を調べました


# 結論

`CloudPlatform` が環境変数の有無で判定していました。

Spring Boot 2.3.xの場合
https://github.com/spring-projects/spring-boot/blob/2.3.x/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/cloud/CloudPlatform.java

- Cloud Foundry, Heroku, SAP, K8s が検知対象
- NONEを指定すると特に検知しないことも可能
- `application.properties` で `spring.main.cloud-platform` を指定すれば、強制的に実行環境を指定可能

でした。

Spring Bootのバージョンによって `CloudPlatform` の判定内容は異なるので、お使いのバージョンに沿ったソースを参照してみてください。