OmniAICreator/Qiita-1.07M huggingface dataset:
XAMPPでローカルにWordpress開発環境 を構築する

#手順１，XAMPPをダウンロードしてインストール
https://www.apachefriends.org/jp/index.html

#手順２，PHPMyAdminからデータベースを作成
XAMPPのコントロールパネルから、もしくはhttp://localhost/phpmyadmin/

もし聞かれたら
初期ID:root
pass:空欄のままでOK

新規作成 -> データベースを作成する -> 名前を入力 ->　utf8_general_ci -> 作成

今回は名前は：your_site_db

#手順３，wordpressの本体をダウンロードして設置
https://ja.wordpress.org/download/

ダウンロードしたファイルを解凍してXAMPPのドキュメントルートに(c:\\xammp\\htdocs)に貼り付ける
この時フォルダ名はhttp://localhost/------/
------に該当する

ここではフォルダ名をyour-siteに設定します。

#手順４，wordpressをインストール

Webブラウザで
http://localhost/your-site/
にアクセスします。

データベース名：手順２で決めたデータベース名
ユーザー名：root
パスワード:空欄のままでOK
データベースのホスト名：localhost
テーブル接頭辞：そのまま

->送信をクリック ->インストール実行

あとは表示される手順通りやっていけば大丈夫。
JavaScriptでURL切って間にパスを挿入する方法

`https://demo.jp/hoge`
↓
`https://demo.jp/ogp/hoge`
のようにURL切って間にパスを挿入する方法です。

## splitメソッドを使用する
`split()`を使用して、URLを切ります。

```javascript
const originallUrl = 'https://demo.jp/hoge'

const url = originallUrl.split('https://demo.jp/')
console.log(url)  //[ '', 'hoge' ]

const newUrl = 'https://demo.jp/' + 'ogp/' + url[1]
console.log(newUrl) //https://demo.jp/ogp/hoge
```
`split()`を使用すると配列で取得できるので、`url[1]` で新しいURLに代入しています。
ubuntu: キーボード無効化

```.sh:terminal
# 内蔵キーボードのidを取得(AT Tranlated Set 2 keyboard の idが12であることを確認)
$ xinput
⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad              	id=13	[slave  pointer  (2)]
⎣ Virtual core keyboard                   	id=3	[master keyboard (2)]
    ↳ Virtual core XTEST keyboard             	id=5	[slave  keyboard (3)]
    ↳ Video Bus                               	id=7	[slave  keyboard (3)]
    ↳ MSI WMI hotkeys                         	id=14	[slave  keyboard (3)]
    ↳ Power Button                            	id=8	[slave  keyboard (3)]
    ↳ Power Button                            	id=6	[slave  keyboard (3)]
    ↳ Bose Solo 5 system (AVRCP)              	id=15	[slave  keyboard (3)]
    ↳ HD Webcam: HD Webcam                    	id=11	[slave  keyboard (3)]
    ↳ Sleep Button                            	id=9	[slave  keyboard (3)]
    ↳ Topre Corporation HHKB Professional     	id=10	[slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard            	id=12	[slave  keyboard (3)]

# 内蔵キーボードを無効化
$ xinput disable 12
```

![IMG_2100.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463263/dd93fa2b-94d0-a6df-09a3-a7b2f800048b.jpeg)

```.sh:terminal
# 内蔵キーボードを有効化する際は、以下
xinput enable 12
```
Railsで急にアセットコンパイルができなくなった時の原因

##事象
本番環境でCSSが読めていないのに気付きローカルで原因を調べていたところ、ローカルでもCSSが読めなくなった。

##予想
添付したエラーを見る限りCSSだけでなくアセット全体が読めてないのでturbolinksあたりが原因だと思われる。また、通常のブラウザでCSSが読めなくなった後、シークレットウィンドウでみたらしばらくCSSが読めてたが１０分ぐらいで同様に読めこめなくなってしまったので、キャッシュも影響しているのかもしれない。

##解決方法
https://qiita.com/mnbdyunan/items/5110be489b6c3034f3e9
https://blog.office-aship.info/rails5-superclass-method-silence/
上記２つの記事を参考に

```ruby:development.rb
config.logger = Logger.new(STDOUT)
```

の部分を

```ruby:development.rb
logger = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
```
に書き換えると解決する。


##原因
正しくはわからないが、おそらくActiveSupportの仕様が変わり、古い記法で不具合が出るようになったということが原因と思われる。
【CircleCI】【RSpec】【mysql】CircleCIでRSpecを自動化するときに詰まったこと

# Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

`<%= ENV['DB_HOST'] %>` に渡してあげる感じ


```yml:.circleci/config.yml
- image: circleci/ruby:2.7.1-node-browsers
    environment:
      RAILS_ENV: test
      DB_HOST: 127.0.0.1
- image: circleci/mysql:8.0.21
    command: |
      mysqld --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_DATABASE: app_test
      MYSQL_ROOT_PASSWORD: 任意
```

```yml:config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: 任意
  host: <%= ENV['DB_HOST'] %> 

development:
  <<: *default
  database: app_development

test:
  <<: *default
  database: app_test
```

# NoMethodError: Cannot load database configuration: undefined method `[]' for nil:NilClass

ローカルはこんな感じで`Rails.application.credentials`を渡して開発していた。
`.circleci/config.ymlではRAILS_ENV=test`を渡しているので開発環境関係ないやろと思ってたんだけど、案の定Error吐かれた。
pushする時は消すか、もうちょっとうまく環境変数でやれると思う。

```yml:config/database.yml
development:
  <<: *default
  database: app_development
  username: <%= Rails.application.credentials.mysql[:username] %>
  password: <%= Rails.application.credentials.mysql[:pass] %>
```

# 参考

[DockerオフィシャルのMySQL（MariaDB）コンテナの挙動をDockerfile周辺から読み解く](https://qiita.com/kazuyoshikakihara/items/f0c5158c700bb7a5df9f)
[【CircleCI】設定とエラー対処法](https://qiita.com/aiandrox/items/babfa4aba0ccf923487c)
[CircleCIでRails+MySQLプロジェクトの自動テストを行うための最低限の設定](https://qiita.com/t-izaki/items/c6ef3239176f9c6697f2)
[CircleCIでmysql8を使用する設定](https://carefree-se.hatenablog.com/entry/2019/02/12/223417)
nuxtとnpmアップデート後にERR_CONNECTION_REFUSEDとなる


npmアップデート後redirect-sslというパッケージが更新された影響だったらしい。
以下のように修正したら治った。


```` before.rb

export default {
  mode: 'universal',
  buildModules: ['@nuxt/typescript-build'],

  server: {
    port: process.env.PORT || 8000,
    host: process.env.HOST || 'localhost'
  },

  serverMiddleware: [
    'redirect-ssl'
  ],
````

```` after.rb
import redirectSSL from 'redirect-ssl'

export default {
  mode: 'universal',
  buildModules: ['@nuxt/typescript-build'],

  server: {
    port: process.env.PORT || 8000,
    host: process.env.HOST || 'localhost'
  },

  serverMiddleware: [
    redirectSSL.create({
      enabled: process.env.NODE_ENV === 'production'
    })
  ],
````

参考:
https://github.com/nuxt-contrib/redirect-ssl#using-with-nuxtjs
分割代入メモ

###オーソドックスな配列内の値の取得方法

````js
var array = ["apple", "banana", "peach"];

var firstItem = array[0]; 
var secondItem = array[1];

console.log(firstItem);
// "apple"
console.log(secondItem);
// "banana"

````

###分割代入を使った方法

````js
var array = ["apple", "banana", "peach"]

var [firstItem, secondItem] = array;
console.log(firstItem);
// "apple"
console.log(secondItem);
// "banana"

````

###オーソドックスなオブジェクトのプロパティの取得方法

````js
var obj = {apple : "りんご", banana : "バナナ", peach : "桃"};

var apple = obj.apple;
console.log(apple);
// "りんご"
var banana = obj.banana;
console.log(banana);
// バナナ
````

###分割代入を使った方法
メンバがない場合undefinedになるが、メンバがない場合の値を設定することもできる。

````js
var obj = {apple : "りんご", banana : "バナナ", peach : "桃"};

var{apple, banana, peach = "該当なし", orange, grape = "該当なし"} = obj;
var apple = obj.apple;
console.log(apple);
// "りんご"
var peach = obj.peach;
console.log(peach);
// "桃"
console.log(orange);
// undefined
console.log(grape);
// "該当なし"
````

###値の入れ替え
個人的に使える場面がありそうだと感じたのは値の入れ替え。
オーソドックスな方法では一時的に退避を作る必要がある。

````js
var a = 1;
var b = 2;
// 退避
var c = a;
// 入れ替え
a = b;
b = c;
console.log(a);
// 2
console.log(b);
// 1
````

###分割代入を使った方法

````js
var a = 1;
var b = 2;
[a, b] = [b, a];
console.log(a);
// 2
console.log(b);
// 1
````
###関数の引数での分割代入の利用
呼び出し側で引数としてオブジェクトを渡し、関数側ではオブジェクトの特定のメンバを受け取ることができる。

````js
var show = ({mid, name}) => {
	console.log(mid);
    console.log(name);
};

var member = {mid : "Y001", name : "山田",address : "yamada@example.com"};

show(member);
// "Y001"
// "山田"

````
LaravelのCacheでpaginateを使う

Laravelに標準で組み込まれているCache機能は、強力かつ簡単にキャッシュを実装できます。
キャッシュは大量の件数や高頻度のSQLで使われる事が多いため、必然的にページネーションと併用したいケースもあるかと思います。

```php:TestController.php
namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use App\Models\Test;

class TestController extends Controller
{
    public function tests(Request $request)
    {
      $sec = "86400"; // 1day
      $page = $request->has('page') ? $request->query('page') : 1;
      $limit = $request->has('limit') ? $request->query('limit') : 25;
      $tests = Cache::remember('test_'.$page.'_limit_'.$limit, $sec, function() use ($limit) {
        return Test::paginate($limit);
      });
    }
}
```

sec や limit の数字は適時変更してください。
ModelとViewは割愛します。

こうすると、ある程度動的にページングをキャッシュできます。
ちなみに ```Cache::remember```を使うと、「○秒間、キャッシュが存在しない場合のみfunctionの内容を実行する」となります。

Cacheの使い方の詳細はこちら。
Laravel 7.x キャッシュ
[https://readouble.com/laravel/7.x/ja/cache.html](https://readouble.com/laravel/7.x/ja/cache.html)

page と limit の組み合わせで何パターンかキャッシュファイルが生成されますので、一度のアクセスで全パターンのキャッシュは出来ませんが、毎回高負荷のSQLを叩かれるのと比べれば良い選択肢となるのではないでしょうか。

ページネーションではなく日時や変数を使いたい場合にも応用できるかと思います。
AWS認定クラウドプラクティショナー取得に向けた勉強法

## はじめに
### 本記事を作成した目的
　現在、勤務している会社内でAWSの関心が高まっており、実運用に向けての検討も進んでいる中、基礎知識を身につける必要があると考えたため、まずは入門の位置づけであるクラウドプラクティショナーを受験することを決意しました。無事合格しましたので、今後受験される方に対して少しでも参考になればと思い本記事を作成しました。

### 筆者のスペック
* 仕事はシステム導入・開発を主軸としており、10数年の実務経験あり。
* クラウド/インフラの実務経験はほぼなし。知識は情報処理技術者試験等の資格取得に向けた勉強によるものがほどんど。
* スキルアップの意欲は満々。

### 勉強期間
　約3ヵ月(最初の2ヵ月は気が向いたときに勉強し、試験日を決めた後の1ヵ月は本格的に試験対策を行いました)

## 勉強方法
以下3ステップで勉強を進めていきました。
### STEP 1. 基礎固め
　まずは、AWSのサービス概要、クラウド/インフラの基礎知識が確認できる書籍を斜め読みしました。

 * [図解即戦力 Amazon Web Servicesのしくみと技術がこれ1冊でしっかりわかる教科書](https://www.amazon.co.jp/dp/4297108895)

　隙間時間に読み、読み終えた後は辞書がわり(Webでやみくもに調べるより早い！)として使用しました。試験範囲とならない箇所もありましたが、AWSの仕組みを理解することができる良書だと思っています。

　次に、AWSパートナーネットワークのみで受講できるオンラインセミナーを活用しました。。模擬問題の数問あるので、試験のイメージもつかめました。パートナーネットワークに参加されているのであれば、無料で受講可能で概ね毎月開催されており、利用価値大です。試験に出るポイントが押さえられています。

　また、AWSが提供している無料デジタルトレーニング[(AWS Cloud Practitioner Essentials (Second Edition))](https://www.aws.training/Details/Curriculum?id=34408)
も利用しました。他の方の体験記でよくおすすめされているものですが、AWSや前提のインフラ知識があまりなかった私にとっては、頭に入りにくかったため、途中で受講をやめました。ある程度、理解してから観るとよいかもしれません。

### STEP 2. 理解度の向上
　下記にある書籍・動画を利用しました。書籍はSTEP 1.で取り組んだ成果を確認していくことを意識して2周読み込みしました。動画はEC2/VPC/S3など主要なサービスの理解を深めるのに役立ちました。

* ＜書籍＞[AWS認定資格試験テキスト AWS認定 クラウドプラクティショナー](https://www.amazon.co.jp/dp/4797397403)
* ＜動画＞[くろかわこうへい【渋谷で働くクラウドエンジニアTV】](https://www.youtube.com/channel/UCX30pfp4p82rIiSJmBygADw)

　AWSのサービスが幾多もあり、試験対策本といえど十分にカバーできていないため、自分で補填する必要があります。私はWebやAmazon公式サイトから情報収集を行い、各サービスの概要・ポイントをノートに書き留めました。知識が増えてくるとややこしい用語・類似用語に苛まれましたので、1つ1つ丁寧に違いを書き留めて、繰り返し見返すよう心掛けました。隙間時間でも確認できるよう単語帳のアプリを活用し、理解を定着させるようにしました。

　Webで調べるとAWSの情報は山ほど出てきます。情報に埋もれないよう自分にあったページを見つけるようにすると効率的に学習できるかと思います。

### STEP 3. 試験対策
　AWSのサンプル問題やWebに掲載されている練習問題では心もとなかったため、udemyの問題集を利用しました。(Webクーポンを使って格安で購入。udemyは定期的にセールがあるので、それを狙って購入しましょう。定価ですと結構な値段になります。。)
　7回分の問題がありましたが基本レベルの2回分を合格ラインに到達するまで繰り返し解きました。最初は正答率が半分もなく焦りましたが、試験前には80%以上の正答率までもっていきました。

* [この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（7回分455問）](https://www.udemy.com/course/aws-4260/)

 　また、AWSの個別サービスの理解を深めるため、[Amazon Web Services Japan 公式](https://www.youtube.com/channel/UCnjKWUK2t5QJYfeqqilhJhQ)にあるsummit・blackbeltの最新版の動画を確認しました。ボリュームが多いので、サービス概要の部分のみを視聴した上、自分なりに要点をまとめることを繰り返しました。**結果的にこの取り組みが点数の底上げにつながりました。**

　試験前日は先述したAWSパートナーネットワークのオンラインセミナーの資料を見返し、今まで得た知識の再点検を行いました。

## 試験実施
　申込みはAWSパートナーネットワーク経由でピアソンVUEで行いました。
当日はテストセンターへ行き、所要時間は100分(試験要領確認5分、試験時間90分、アンケート回答5分)でした。試験は45分で答え終え、残り時間は見直しに費やしました。結果は即時で分かりますが、獲得点数は分かりません。合否判定の画面表示のフォントが小さく、本当に合格したのか受験時は少し不安でした。。数時間後にAWSアカウント上に反映され、合格証も確認できるようになっていました。

## おわりに
　合格特典として、次回受験料割引・模擬試験無料のチケットを獲得しました。これを活かして上位資格のソリューションアーキテクト - アソシエイトの受験に向けた準備を進めていきたいと思います。今回の学習時はAWS自体に触れてはいなかったので、今後は触れながら知識習得、および理解を深めていこうと考えております。
Composerの使い方〜忘備録

##はじめに
この記事は個人的な忘備録用に調べたことを纏めていきますので第三者が読んでわかりにくい点があると思われます。また、誤った解釈も出てくるかと思いますので気軽にコメント頂ければ修正を致します。

##参考
[Composerドキュメント日本語訳](https://kohkimakimoto.github.io/getcomposer.org_doc_jp/doc/03-cli.html"Composer")

##Composerの使い方
<details><summary>`create-project`</summary>
<div>
新しいプロジェクトを作成するのに使用する
`create-project`コマンドで３番目の引数にバージョンを指定することが出来る

```
php composer.phar create-project doctrine/orm path 2.2.0
```

ここでは「2.2.0」がバージョンの指定をしている。
</div>
</details>

・・・更新中
Spring-Boot-2.3ではjavax.validationを依存関係に追加しなければならない

Spring Boot 2.3.1を利用してバリデーション機能を実装していたところ
@Sizeや@NotNullなどのアノテーション(javax.validation*)が利用できなくなっていました。

### 結論

以下の依存関係を追加。

## mavenの場合

```
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
```

### gradleの場合

```
dependencies {
  ...
  implementation 'org.springframework.boot:spring-boot-starter-validation'
}
```

### 理由

バージョン2.3以前を利用していた時は以下のスターターを読み込めばjavax.validation*のライブラリが利用できていましたが、
2.3からは含まれなくなっていたようです。

```
implementation 'org.springframework.boot:spring-boot-starter-web'
```

> 参考
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.3-Release-Notes#validation-starter-no-longer-included-in-web-starters
Reactでchartを表示する

https://mdbootstrap.com/docs/react/advanced/charts/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324917/fe429e77-7656-e376-b7e2-6086dfa30e72.png)
このようなチャートを表示してくれる。

そのほかにも、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324917/fca8d6ae-39e2-3501-eff8-734b6eb63e88.png)

navbarも作成できる。
Transparent persistence とは何ぞや

ORM(Object Relational Mapping)に関する文章を読んでいると、しばしば "transparent persistence" という表現に出くわします。

日本語に訳すと「透過的永続性」あたりでしょうか。
訳したところでいまいち意味がわかりません。

transparent persistence をググってみると、「transparent persistenceについて」「transparent persistenceって何」みたいな英語の記事がたくさんヒットします。どうやら非英語話者にとっての英語の難しさというよりは、日常的な表現とは異なる独特の慣習的な表現としての難しさがあるようです。

実は情報工学において transparency ([透過性](https://ja.wikipedia.org/wiki/透過性_(情報工学))) という語は「ユーザーが意識することがない」という意味で広く用いられています。

それを踏まえると、 transparent persistence は「ユーザーが意識することなく永続化が行われること」ぐらいの意味かなと推測することができます。

実際のところ transparent persistence が何を表すのかについては、 stack overflow の以下の回答が簡潔でわかりやすかったので引用します。
[In the context of an ORM what is Transparent Persistence?](https://stackoverflow.com/questions/20863150/in-the-context-of-an-orm-what-is-transparent-persistence)

> What it means is that the database is abstracted away from your application so much, that the concepts of "saving" to the database doesn't show up on the highest levels.
> 
> In other words, your application would set data on an business object, and somewhere deep down below, in a lower layer, that would be saved, but automatically. Transparently.

transparent persistence とは何か。それは、

「データベースが十分に抽象化されていてアプリケーションと分離しており、データベースに「保存する」という概念が表面的なところには現れてこないということ。言い換えれば、ビジネスオブジェクトにデータをセットしたら、より深い低レベルなレイヤーでそれが自動的に、つまり透過的に、保存されるということ。」

です。

そしてこの回答者の方は、アプリケーションとデータベースの分離というのは、いわゆる「聖杯」、つまり追い求められるけど決して手に入らない理想であるとまとめています。これには残念ながら頷くしかありません。

ちなみに直接関係はありませんが、関数型言語の文脈でよく出てくる referential transparency (参照透過性) という、これまたちょっと戸惑う用語がありますが、この語は実は分析哲学と絡む経緯があるようで、以下の記事が面白かったので興味がある方はぜひ読んでみてください。

[「参照透過である」とは、何から何への参照がどういう条件を満たすことを言うのか](https://qiita.com/knaka/items/b18134d9d11b51da4e2e)
【Python】データサイエンス100本ノック（構造化データ加工編） 005 解説

- データサイエンス100本ノックをやりきる会を作りました🎉
- こちらの[Slack招待URL](https://join.slack.com/t/data-science-100nocks/shared_invite/zt-gfncg9vm-8W8b3UrDg8R~TKaqUkQpgw)からご参加ください！！
- ぜひ一緒に励まし合いながら、データサイエンス100本ノックをやり切りたいと思っています！

##Youtube
[動画解説](https://youtu.be/wVPJm9EFL9M)もしています。

##問題
P-005: レシート明細のデータフレーム（df_receipt）から売上日（sales_ymd）、顧客ID（customer_id）、商品コード（product_cd）、売上金額（amount）の順に列を指定し、以下の条件を満たすデータを抽出せよ。
- 顧客ID（customer_id）が"CS018205000001"
- 売上金額（amount）が1,000以上

##解答
```:コード
df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']] \
.query('customer_id == "CS018205000001" & amount >= 1000')
```

##出力
|  | sales_ymd | customer_id | product_cd | amount |
|--:|--:|:--|:--|--:|
| 36 | 20180911 | CS018205000001 | P071401012 | 2200 |
| 68117 | 20190226 | CS018205000001 | P071401020 | 2200 |
| 72254 | 20180911 | CS018205000001 | P071401005 | 1100 |

##解説
・PandasのDataFrame/Seriesにて、列を指定しつつ、指定した行のうち、条件に当てはまる行を確認する方法です。
・列情報を絞り、かつ、行を指定して、かつ、条件に当てはまる情報を確認したい時に使用します。
・**'<データ名>[['<列名A>','<列名B>','<列名C>']].guery('<列名A> == "<行情報A>" & <列名B> >= 1000')'**で、指定した列(列名A,列名B,列名C)のうち、列名A が指定した 行情報A に該当する行で、かつ、列名B が1000以上の行を表示します。

※Pythonの比較演算子は[こちら](https://www.javadrive.jp/python/if/index4.html)を参照ください
linux commands

何度も、検索してしまうたまに使うコマンドをまとめていきたいと思います。

## 文字コード変換
ダウンロードしたデータの文字コードがshift_JISだったりしたときの変換。
確認コマンド

```
$ nkf --guess file_name
```

変換コマンド

```
$ nkf -(option) old_file > new_file
```
-w(utf8)です。
【Mac】文字入力でホームポジションのままカーソル移動や文字削除を行う標準ショートカットキー

# 概要
コードを書いてるとき、Finderでファイル名を変更しているとき、Chromeでググってるときなど、Macで文字入力をしているときにホームポジションを離れてカーソルキーを押しにいく動作を無くしたい、ツールを導入せずに何かいい方法はないか？
と思い調べてみると、標準搭載されているショートカットキーがありました。
Appleの[Macのキーボードショートカット](https://support.apple.com/ja-jp/HT201236)ページに記載されている中から、自分がよく使うカーソル移動と文字削除に関するショートカットキーです。（使用出来ないアプリもあります）
**慣れるまで戸惑いましたが、慣れるとホームポジションを保てるので便利です。**

#ショートカットキー
### カーソル移動に関するショートカットキー
| ショートカットキー     | 機能                            |
|:----------------:|:-------------------------------|
| control + F      | 1文字進む                        |
| control + B      | 1文字戻る                        |
| control + P      | 1行上に移動                      |
| control + N      | 1行下に移動                      |
| control + A      | 行または段落の先頭に移動            |
| control + E      | 行または段落の末尾に移動          　|

### 文字の削除に関するショートカットキー
| ショートカットキー     | 機能                            |
|:----------------:|:-------------------------------|
| control + D      | 右の1文字を削除                   |
| control + H      | 左の1文字を削除                   |
| control + K      | カーソルから行または段落の末尾まで削除　|
ESP32-CAM の HTTP CLIENTのサンプルを動かす手順

- Arduinoを用いて、PC ⇔ USBシリアル ⇔ ESP32-CAM を繋いで　Ｌチカなどで一度は動いてることは確認できているという前提で　以下　手順を書きます。

- http clientのスケッチ例を選びます。

![2020-07-18 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131546/c8c99cc3-ef01-9ada-e167-56baa28b1e9c.png)

- SSID、password、アクセスしたいホームページのアドレス　を編集します。

```cpp:BasicHTTPClient.ino
(中略)

const char* ssid = "アクセス先のWIFI親機のSSID";
const char* password = "アクセス先のWIFI親機のPASSWORD";

void setup() {

    USE_SERIAL.begin(115200);

    USE_SERIAL.println();
    USE_SERIAL.println();
    USE_SERIAL.println();

    for(uint8_t t = 4; t > 0; t--) {
        USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
        USE_SERIAL.flush();
        delay(1000);
    }

//    wifiMulti.addAP("SSID", "PASSWORD");
    wifiMulti.addAP(ssid, password);

}

void loop() {
    // wait for WiFi connection
    if((wifiMulti.run() == WL_CONNECTED)) {

        HTTPClient http;

        USE_SERIAL.print("[HTTP] begin...\n");
        // configure traged server and url
        //http.begin("https://www.howsmyssl.com/a/check", ca); //HTTPS:relaxed:
        http.begin("http://osakawaraji.jpn.org/"); //HTTP　←　ここをアクセスしたいホームページのURLにする。

        USE_SERIAL.print("[HTTP] GET...\n");
        // start connection and send HTTP header
        int httpCode = http.GET();

        // httpCode will be negative on error
        if(httpCode > 0) {
            // HTTP header has been send and Server response header has been handled
            USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);

            // file found at server
            if(httpCode == HTTP_CODE_OK) {
                String payload = http.getString();
                USE_SERIAL.println(payload);
            }
        } else {
            USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
        }

        http.end();
    }

    delay(5000);
}
```

- USBシリアルを外し、IO0⇔GNDをショートにしてから USBシリアルを接続

- スケッチ→マイコンボードに書き込むを選んで下のペインに「Leaving...Hard resetting via RTS pin...」と表示されるまで待つ。

- USBシリアルを外し、IO0⇔GNDのショートを　オープンにしてから USBシリアルを再度接続
- ツール→シリアルモニタ　を起動。↓のような画面が表示され、ホームページにアクセスしてることが分かります。
![2020-07-18 (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131546/c3f3c3a2-8e39-e0e4-cf9d-7a3c80eb24ba.png)

- お疲れ様でした

- これから　やろうとしていること
カメラで撮った画像からデータを作成し、あるURLにアクセスして　そのデータ（文字列）を渡そうとしています。
【u-blox】u-blox 受信機のスペアナ機能を試す

u-blox 社の２周波の受信機F9Pにスペアナ機能があるので試してみました。
[RTKLIBの作者の方の記事](http://gpspp.sakura.ne.jp/diary202006.htm)にインスパイアされました。

以下、u-blox 社の提供するu-center には詳しいことを前提に書きます。

- 方法は簡単：F9P受信機をＰＣとＵＳＢで接続し、u-center で見れます
- ハマりポイント：古いu-center (ver 19)と購入時のＦＷ(HPG1.12)では動きません

## Spectrum Analyzer

UBX-MON-SPANメッセージで出力しているようです。

(1) UBX-MON-SPANメッセージを出力するように設定する。これは、Configuration View を起動して、 MSG で　0A-31 MON-SPAN を USBから出力するようにコマンドをSend します
![conf.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294040/8d9d16e6-bea6-2163-a49e-91c838f6be55.jpeg)

(2) Message View を立ち上げて、UBX-MON-SPANを開くと見えます。
![span-ex1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294040/748a3b8a-6bcc-4728-e563-82a7ba8ead65.jpeg)

(3) RFの情報を他にも出しています。Jamming indicator も。
![rf.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294040/94e66957-89e8-9ff9-974a-e2fab4b1f834.jpeg)


## 動作環境についてのメモ

### 動作環境

古いu-center だとスペアナ機能の選択ができません。また、受信機の方は、FWVER=HPG1.12だとスペアナ出力のデータをpoll できませんでした。私は以下のversion で動作しました。

```
Windows ソフト: u-center ver 20.06.01
受信機F9P: FWVER=HPG 1.13, MOD=ZED-F9P
```
### Version 確認

u-center でUBX-MON-VER メッセージをpoll　すれば良いです。Message View から可能です。
![version.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294040/c3d94654-e0a4-1589-b9bf-9d6c0d39d774.jpeg)


### FW update(必要なら)

HPG1.12 からHPG1.13にupdate しました。

- FWをサイトから[ダウンロード](https://www.u-blox.com/en/product-resources/field_file_category/firmware-update-223) (u-blox社のページのSupport からたどれます)
- u-center を起動。 "Tools" --> "Firmware Update..." を起動
- ダウンロードしたＦＷを選択する。
![fw-update-ui.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294040/2b299bff-d439-2bbb-2efd-4fb724da1e77.jpeg)
- あとは緑のGoボタンを押すだけ。baudrate 9600 ですが、あっという間に終わりました。あと、Goを押す前は普通に受信機は動いている状態で停止させる特別な操作は行いませんでした。
- 以下の画面になりました。
![firmware-update-complete.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294040/1fd93053-a92e-053e-39bd-c69cfe49e8e9.jpeg)

## 雑感

これまでＧＰＳ受信機のRFの情報はなかなか手に入りませんでしたが、ここで手軽に取得できるようになったので、アプリの開発が進むのではと思います。また、GPSのJamming indicator は今後の自動車やドローンなどの自動化において大きなリスクとなることが認知されていて、そこに適切に対応した機能追加だと思います。これをユーザが使いこなして、より良い未来が訪れるのでしょう。
Cipher途中で止まる問題

また嵌ったので、共有したかったんや。。。

### 起こったこと

大切な情報をHDDで運んだ。
それ自体は致し方ないことだったが、運んだHDDからデータを削除するにあたって、
フォーマット+cipherすることにした。
いくらでも復元できちゃうからね。仕方ないね。

cipherは、他に情報は検索すればいくらでもあると思うけど、
簡単にはファイルのデータが書き込まれていない事になっているスペースに3回ほどいろいろ書き込んで、
そこを読み込んでもデータを復元できないようにする仕組みだと理解している。

対象ドライブがeでマウントされているなら、
コマンドプロンプトで

~~~
cipher /W:e:
~~~

で後は待つだけである。
コマンドプロンプトは背景に押しやって良い子のみんなは他の仕事をしようね。


で、このcipher君が途中で止まる。
コマンドプロンプトは別にアクティブになっていないが、唐突に動作が止まる。

![コメント 2020-07-18 162943.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676634/c67891a5-505b-5c09-a52b-3fd43373da1b.png)


原因はどうやら何らかの原因で作業が一時停止してしまっているようだ。
コマンドプロンプトを別にアクティブにして無くても何らかの入力をきっかけにしているのだろうか。
詳しい人教えてクレメンス。。。
http://hirotaka-k.hatenablog.com/entry/2016/02/24/073429

コマンドプロンプトをアクティブウインドウにして適当にキーを押すと再開する。
とりあえずは解決した気分になる。


## 環境
- Windows10 home
vscodeのデバックができない(フリーズする)

##vscodeのデバックができなくなった(c++の）
状況としては、デバック開始のボタンを押してもコードにハイライトが表示されず、step in,step outなどの動作ボタンを押しても動かない。
errorやwarningも出てなくフリーズしてる感じ。

1日前まで動いていたのに、急に動かなくなりました。
(憶測だけど、vscodeが自動でアップデートされたせい?)

##解決方法
extensionのc/c++を削除して入れ直しました。
具体的には、
`~/.vscode/extensions`にある`ms-vscode.cpptools-0.29.0`を削除し、普通にvscodeのmarketplaceからサイドインストール。

##感想
errorやwarningが出ずに動かなくなったときは、いろいろ調べるよりも一回消して入れ直した方が早いのかもしれない。
あと、特定のextensionを入れ直すだけでフリーズが治ったのは意外でした。
競技プログラミング練習記 No.47【ABC115練習】

初回 -> [はじめに](https://qiita.com/easychoco/items/a9ae28aca97cfe47091f)

[ABC115](https://atcoder.jp/contests/abc115)を解きました。
4完です！

|問題|時間|アルゴリズム|実行時間
|:-:|:-:|:-:|:-:|
| A |  2min |-| 6ms|
| B |  3min |-| 6ms|
| C |  7min |-| 28ms|
| D | 49min |二分探索| 6ms|


# まとめ
先にまとめを載せます。これ自体は最後に書いてます。

配列内の最大値を知るだけならソートは不要です。
不要ですが、計算量が許されるならソートするのもありです。

求めるものが入力された順番に関係なく、数値の大小に関係あるときはまずソートを考えます。


D問題はもうちょっと早く解きたかったです。
二分探索に慣れられたのでよしとします。


## A - 	Christmas Eve Eve Eve

```c++
  int d;
  cin >> d;
  string ans;
  if (d == 25) ans = "Christmas";
  if (d == 24) ans = "Christmas Eve";
  if (d == 23) ans = "Christmas Eve Eve";
  if (d == 22) ans = "Christmas Eve Eve Eve";
  cout << ans;
```
入力が4通りなので、複雑なことはせずに愚直にかきました。

## B - Christmas Eve Eve

``` c++
  int n;
  cin >> n;
  vector<int> p(n);
  for(int i = 0; i < n; ++i)
  {
    cin >> p[i];
  }
  int ans = accumulate(p.begin(), p.end(), 0) - *max_element(p.begin(), p.end()) / 2;
  cout << ans;
```
合計を計算して、その値から最大要素の半分を引けば答えになります。
`std::accumulate()`関数で要素の総和を計算して、
`std::max_element()`関数で最大要素のイテレータを取得します。

練習がてら`std`の関数を使ってみたのですが、私はイテレータに慣れていないので少し複雑に見えます。。
昇順でソートすることで最大要素が末尾にくるので、これを利用しても解けます。
(ソートすると`O(N logN)`かかり、最大要素を知るだけなら`O(N)`で済むことに注意です)


## C - Christmas Eve

``` c++
  ll n, k;
  cin >> n >> k;
  vector<ll> h(n);
  for(int i = 0; i < n; ++i)
  {
    cin >> h[i];
  }

  sort(h.begin(), h.end());
  ll ans = 1LL << 60;
  for(int i = 0; i <= n - k; ++i)
  {
    ans = min(ans, h[i + k - 1] - h[i]);
  }
  cout << ans;
```
最大要素と最小要素の差が小さくなるように`K`本選べばよいので、入力順は関係ありませんね。
入力順は関係なくて数値の大きさは関係あるので、まずソートをします。
ソート後の配列で順に`K`本選べば差は最小化できそうですね。
これを踏まえて、`K`本選んだ時の最大要素と最小要素の差は`h[i + k - 1] - h[i]`になります。
範囲に注意しながら要素を比較すると答えがわかります。

## D - Christmas

``` c++
ll b_num[55], p_num[55];

void solve()
{
  ll n, x;
  cin >> n >> x;

  b_num[0] = 1;
  p_num[0] = 1;

  for(int i = 1; i <= 50; ++i)
  {
    b_num[i] = b_num[i - 1] * 2 + 3;
    p_num[i] = p_num[i - 1] * 2 + 1;
  }

  auto lv_mid = [&](ll lv){ return (b_num[lv] + 1) / 2LL; };
  ll ans = 0;
  ll pos = 0;
  for(int lv = n; lv >= 0; --lv)
  {
    ll mid = lv_mid(lv);

    // 半分より左
    if (x < mid + pos)
    {
      pos++;
      continue;
    }

    if (lv > 0) ans += p_num[lv - 1] + 1;
    else ans++;

    // ちょうど半分
    if (x == mid + pos) break;

    // 半分より右
    pos += mid;
  }
  cout << ans;
}

```

二分探索ですね(厳密には違います)。
二分探索のイメージで解けます。

前準備として、
`b_num`にレベル50までのバーガーの枚数
`p_num`にレベル50までのパンの枚数
を記録します。

それぞれ
`b_num[i] = b_num[i - 1] * 2 + 3;`
`p_num[i] = p_num[i - 1] * 2 + 1;`

になります。数値は指数的に増えますね。
制約から最大レベルが50なので、枚数の最大値も2^50枚程度だといえます。
(正確にはもっと大きくなって、2^51と2^52の中間の数値になります。)
`int`型は2^31まで、`long long`型は2^63まで入るので、これは`long long`型の範囲内です。

バーガーの形は `[pan] [左のバーガー] [ban] [右のバーガー] [pan]` ですね。

回答の方針としては、各レベルのバーガーの中央の位置と`X`を比較してその結果で分岐します。
`X`のほうが大きければ右のバーガーを見る
`X`のほうが小さければ左のバーガーを見る
`X`と等しければ答え
を、繰り返します。

バーガーの中央の位置の更新に注意です。
右のバーガーを見る際は左側にあるパンの枚数を答えに加算します。
計算量は`O(N)`です。
二分探索なのに`log`が出てこないと思うかもしれませんが、
バーガーの枚数を`A`とすると`A ≈ 2^N` となり、`O(log A)` の問題になります。

以上です。ありがとうございました。
DataFrameにてMeanを使う


値を含むDataFrameにてMeanを使うと平均値のDataFrameが取得できる。
その際に対象項目にNULLが含まれている場合にどうなるかを確認する。
 
※今回の希望としてはNULLの分は除いて平均をとってほしい。。

``` python

import pandas as pd

df_ExistNone = pd.DataFrame({'a': [1, 2, 1,None, 3],
                   'b': [0.4, 1.1,None, 0.1, 0.8],
                   'c': ['X', 'Y',None, 'X', 'Z'],
                   'd': ['3',None, '5', '2', '1'],
                   'e': [True,None, True, False, True]})

df = pd.DataFrame({'a': [1, 2, 1, 3],
                   'b': [0.4, 1.1, 0.1, 0.8],
                   'c': ['X', 'Y', 'X', 'Z'],
                   'd': ['3', '5', '2', '1'],
                   'e': [True, True, False, True]})

df_0 = pd.DataFrame({'a': [1, 2, 1,0, 3],
                   'b': [0.4, 1.1,0, 0.1, 0.8],
                   'c': ['X', 'Y',None, 'X', 'Z'],
                   'd': ['3','0', '5', '2', '1'],
                   'e': [True,None, True, False, True]})

print(df)
print(df_ExistNone)
print(df_0)

print("-------------------")

print(df.mean())
print(df_ExistNone.mean())
print(df_0.mean())

```

結果

``` python
   a    b  c  d      e
0  1  0.4  X  3   True
1  2  1.1  Y  5   True
2  1  0.1  X  2  False
3  3  0.8  Z  1   True
     a    b     c     d      e
0  1.0  0.4     X     3   True
1  2.0  1.1     Y  None   None
2  1.0  NaN  None     5   True
3  NaN  0.1     X     2  False
4  3.0  0.8     Z     1   True
   a    b     c  d      e
0  1  0.4     X  3   True
1  2  1.1     Y  0   None
2  1  0.0  None  5   True
3  0  0.1     X  2  False
4  3  0.8     Z  1   True

-------------------
a      1.75
b      0.60
d    880.25
e      0.75
dtype: float64
a    1.75
b    0.60
e    0.75
dtype: float64
a       1.40
b       0.48
d    6104.20
e       0.75
dtype: float64

```

Noneの項目については、計算から除外されていることがわかる

Noneを含みたい場合は
skipna = False/True

``` python
print(df_ExistNone.mean(skipna = True))
print(df_ExistNone.mean(skipna = False))
```
``` python
a    1.75
b    0.60
e    0.75
dtype: float64
a   NaN
b   NaN
dtype: float64
```
Google App Engineに別ユーザーでデプロイするまで

なんかGoogle App Engine使うのを拒否されたので自分のアカウントのところにホストしたやつを仕事用アカウントで運用してやろうかと思いました。
#GAEを組織なしで使う
私はなんか組織とか今更作るのも面倒なので単純に他のユーザーを追加して利用できないかと考えました。
Google Cloud PlatformにはIAMという狙っているとしか思えないサービス名のサービスがあり、こいつで色んなサービスの権限を管理します。IAMに＋追加というボタンがあるのでそこに件のアカウントを放り込んで権限を与えるだけです。課金を有効にしていなくても問題ないです。
#GAEを使うのに必要な権限とは
初めにそれっぽい権限を放り込めば動くだろうと思ってApp Engineデプロイ担当者というやつを突っ込んでみました。
一応この時点でプロジェクトには参加できているので、`gcloud init`でプロジェクトを選択できます。
ではアプリケーションを作ろうとコンソールでぽちぽちとしようとしたら、作成する権限はないといわれました。
まあよく見たらデプロイなのでしかたなく管理アカウントのほうで作ってデプロイしてみました。
するとこんなエラーが。

```
ERROR: (gcloud.app.deploy) 403 Could not list bucket [staging.foobar.appspot.com]: 
hogehoge@gmail.com does not have storage.objects.list access to the Google Cloud Storage bucket.
```
なるほど、なんか別の権限が必要みたいだったのでこれも追加しました。追加した権限はCloud Storageのストレージ管理者です。
これでうまく行くだろうと思ったのですが、やっぱり別のエラーが出ました。

```
ERROR: (gcloud.app.deploy) Error Response: [7] Unable to write to staging bucket staging.foobar.appspot.com.
 Please grant access to the App Engine service accounton your project by visiting https://console.developers.google.com/storage/browser?project=foobar
```
これでどの権限を追加したらいいのかわからなかったのですが、適当にいろいろやっていたらCloud Build サービスアカウントというのがその権限だったようです。
これで無事に別のアカウントからGoogle App Engineにデプロイできるようになりました。
エスケープおさらい


## はじめに

MySQLのエスケープ処理について真面目に考えたことなかったので、簡単にまとめる。

## その前にエスケープ関連の言葉をおさらい

エスケープの言葉をおさらいするだけでも結構スッキリした

#### エスケープ処理
プログラミング言語やソフトウェアで文字列を扱う際に、特定の記号文字などに続けて記された文字（の並び）に、その文字本来の意味とは異なる特別な意味や機能を与える


#### エスケープシーケンス

特殊な文字を、普通の文字の組み合わせで表現したもの
例えば、「\n」（「\」と「n」の組み合わせ）で改行を意味する（プログラミング言語によって異なるが）

#### エスケープ文字

２つの意味で使われている、意味が真逆なので文脈から読み取る必要がある

- 特別な意味を無効にするための文字
- 特別な意味を付与するための文字

#### サニタイジング

入力データの無害化で、エスケープ処理はその手段の一つ

##### 特別な意味を無効にするための文字

「^a」はコンピュータでは「aではじまる文字列」と解釈されるが、「\^a」と書くことで「^a」の二つの文字列と解釈される
ここでいうバックスラッシュがエスケープ文字にあたる

##### 特別な意味を付与するための文字

エスケープシーケンスで説明した「\」（バックスラッシュ）のこと

## MySQLではどんな文字がエスケープ処理されるのか

### MySQLのエスケープシーケンス

| エスケープシーケンス | シーケンスが表す文字 |
|:--|:--|
| \0 | ASCII NUL (0x00) 文字。 |
| \' | 単一引用符 (「'」) 文字。 |
| \" | 二重引用符 (「"」) 文字。 |
| \b | バックスペース文字。 |
| \n | 改行 (ラインフィード) 文字。 |
| \r | 復帰改行文字。 |
| \t | タブ文字。 |
| \Z | ASCII 26 (Ctrl+Z)。表に続いて記されている注釈を参照してください。 |
| \\ | バックスラッシュ (「\」) 文字。 |
| \% | 「%」文字。表に続いて記されている注釈を参照してください。 |
| \_ | 「_」文字。表に続いて記されている注釈を参照してください。 |


エスケープされる例

```sql
select "hello\nworld"
```

```sql:実行結果
hello
world
```

上記以外の文字に「\」(エスケープ文字)がついていても無視される

```sql
select "\h\e\l\l\o \w\o\r\l\d"
```

```sql:実行結果
hello world
```

### 他の言語のエスケープシークエンスは？

#### html

| エスケープ文字 | 文字 | 名称 |
|:--|:--|:--|
| < | \&lt; | 小なり |
| > | \&gt; | 大なり |
| (半角スペース) | \&nbsp; | 半角スペース |
| & | \&amp; | アンパサンド |
| © | \&copy; | コピーライト |
| " | \&quot | ダブルクォーテーション |
| ' | \&#39; | シングルクォーテーション |
| ¥ | \&yen; | 円マーク |


#### javascript

| エスケープシーケンス | 意味 |
|:--|:--|
| ¥b | バックスペース |
| ¥t | 水平タブ |
| ¥v | 垂直タブ |
| ¥n | 改行 |
| ¥r | 復帰 |
| ¥f | 改ページ |
| ¥' | シングルクオーテーション |
| ¥" | ダブルクオーテーション |
| ¥¥ | ¥文字 |
| ¥0 | NULL文字 |
| ¥xXX | 2桁のXX(16進数)が表すLatin-1文字 |
| ¥uXXXX | 4桁のXXXX(16進数)が表すUnicode文字 |

## まとめ

MySQLがどの文字をエスケープするのかはまとめることでスッキリしたが、アプリケーション側でMySQLのエスケープ文字をどのように扱ってデータを保存しているのかを見ていきたい。

## 参考

この記事は以下の情報を参考にして執筆しました。

https://wa3.i-3-i.info/word11732.html
http://e-words.jp/w/%E3%82%A8%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97%E5%87%A6%E7%90%86.html
https://dev.mysql.com/doc/refman/5.6/ja/string-literals.html
https://pasomaki.com/html-escape/
https://www.javadrive.jp/javascript/num/index2.html
Android StudioでTODO以外にアノテーションコメントを増やす

Android Studio等のIntelliJ系IDEを使っている方がこの記事に行き着いたんだと思います。

IntelliJ系IDEは標準で`TOOD`と`FIXME`のコメントを検出して、ツールウィンドウ内のTODO機能に表示してくれます。
![スクリーンショット 2020-07-18 16.21.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401312/a26c63ab-e964-341d-029a-48cf92711c64.png)

ただ、実際に開発をしていると、もっといろいろな種類を利用したいと思うことも多いです。
個人的には下記くらいは利用できたら、と考えていました。

| コメント            | 用途              |
|:-----------------|:------------------|
| TODO             | やることを記載        |
| FIXME            | 修正する必要があることを記載        |
| OPTIMIZE         | 最適化したいことを記載        |
| NOTE             | メモ書き(個人開発とかで使います)       |

調べたところ、他にも`XXX`とか`HACK`とか`WARNING`とかが使われることがあるらしいです。

で、これをAndroid Studioで設定する方法が下記です。

1. メニューバーより、Android Studio→Preferencesを開く
2. 左メニューより、Editor→TODOを開く
3. Patternに正規表現を追加する
4. OKを押して保存

![スクリーンショット 2020-07-18 16.33.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401312/586b29b4-4d4a-6011-40cc-a839a7e35387.png)

文章にしてみたらものすごくシンプルでした。
Ionic/Angularではどのブラウザをサポートするべきか

Angular8からDifferential Loadingが実装され、browserslistでそのサポート範囲を指定することができるようになりました。サポート範囲がES2015対応ブラウザでいい場合は、ES2015のみのビルド、そうでない場合は、ES2015とES5の両方のビルドが行われるようになっています。

ちなみに現在の初期サポート範囲です。

```
> 0.5%
last 2 versions
Firefox ESR
not dead
not IE 9-11 # For IE 9-11 support, remove 'not'.
```

なんですが、本当にES5をサポートする必要があるのかという問題がありますので、 https://browserl.ist/ を使って、ES5サポートを切るとどれぐらいのブラウザで表示できないか確認してみました。


__ES2015 + ES5（初期値）__
https://browserl.ist/?q=%3E+0.5%25%2C+last+2+versions%2C+Firefox+ESR%2C+not+dead%2C+not+IE+9-11

__S2015のみ（モバイルブラウザ）__
https://browserl.ist/?q=last+3+iOS+versions%2C+last+3+ChromeAndroid+versions

以下がサポート対象となります。

- Chrome for Android78
- iOS Safari13.2
- iOS Safari13.0-13.1
- iOS Safari12.2-12.4

Ionicでモバイルアプリ向けにビルドする場合、ES2015のみで大丈夫そうですね。ちょっと検証つづけますが、多分私のbrowserslistは

```
last 3 iOS versions
last 3 ChromeAndroid versions
```

のみになると思います。

それでは、また。
TwitterAPIで別アカウントから投稿する

## 概要
TwitterAPIを使い、自分のアカウントから自動でつぶやくのは簡単だけど、別アカウントからつぶやく方法が分からず調べた際のメモ[^1]。
[^1]: APIの申請時に利用目的など記載しているはずなので、その範囲を超える使い方は当然NG。自己責任で。

## 前提
- Pythonが利用可能な状況である（私はバージョン3.7.0）
- TwitterのAPI申請が済んでいる

## 準備
### パッケージのインストール
[こちら](https://github.com/sixohsix/twitter)を利用させてもらう（私はバージョン1.18.0）。

```python
pip install twitter
```

### アプリケーションの作成
これからメモする方法はおそらく[PIN-based authorization](https://developer.twitter.com/en/docs/basics/authentication/oauth-1-0a/pin-based-oauth)を利用しているので、callback_urlは使わなそう。ただ公式ドキュメントに以下のようにあるので、一応画像のようにCallback URLsも埋めておく[^2]。
[^2]: 使われないはずなので何でもいいが、私はとりあえず自分のgithubのページのURLにした。

> The callback_url within the Twitter app settings is still required, even when using PIN-based auth.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540947/ef58866d-f7ec-777f-f623-7761dfe936ef.png)


### Pythonスクリプトの準備
以下2つのファイルを同じディレクトリに準備。

```config.py
app_name = "XXXXXXXXXX" # 上で作成したアプリケーション名
consumer_key = "XXXXXXXXXX" # アプリケーション管理画面のConsumer API Keys > API key
consumer_secret = "XXXXXXXXXX"  # アプリケーション管理画面のConsumer API Keys > API secret key
```


```main.py
from twitter import *
from config import *
oauth_dance(app_name, consumer_key, consumer_secret, token_filename="./config.txt", open_browser=False)
```

### Pythonスクリプトの実行
`main.py`を実行すると、以下のようにURLが表示され、PINの入力を要求される。

```
Hi there! We're gonna get you all set up to use sample.
Opening: https://api.twitter.com/oauth/authorize?oauth_token=xxxxxxxxxx


Please go to the following URL, authorize the app, and copy the PIN:

https://api.twitter.com/oauth/authorize?oauth_token=xxxxxxxxxx
Please enter the PIN:
```

ブラウザでURLを開き、**つぶやきたいアカウントでログインのうえ**PINを取得する[^3]。PINを入力すると以下のメッセージが表示され、`config.txt`にtokenとtoken_secretが保存される。

[^3]: 通常は自分のアプリケーションのユーザーにログインしてもらうのだろうが、動作確認は自分のサブアカで行った。

```
That's it! Your authorization keys have been written to ./config.txt.
```

## 投稿
実際につぶやくPythonスクリプトは以下の通り。なお、準備の際と同じパッケージを利用している。

```python
from twitter import *
from config import *
t = Twitter(
    auth=OAuth(
        'XXXXXXXXXX', # token（config.txtの1行目）
        'XXXXXXXXXX', # token_secret（config.txtの2行目）
        consumer_key,
        consumer_secret,
    )
)
t.statuses.update(status="message")
```
最終行の`"message"`を任意の文字列に変えれば、好きなようにつぶやけるはず。
MySQLのDBからAWSのRDSへデータをインポートする（LightSailからAWS編）

https://qiita.com/hikey/items/ab5fca33849d3e3929cb

Amazon LightsailからAWS RDSに移行しようと思ったが、上記記事を参照すると思いの他面倒そうだった。
素直にエクスポート、インポートするとなるほど、下記のエラーでインポート出来ない。

> ERROR 1227 (42000) at line 18: Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation

これはAmazon RDSの問題なのでLightsail以外のどんなMysqlからインポートしようとしても同様のエラーが出ると思う。
上記記事では色々な手法でエラーを回避しているが、よくよく読んだらmysqldumpを実行時に下記のようなワーニングが出ていた。

> Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events. 

ん？これは素直にこのオプションを付けてエクスポートすれば良いのでは無いだろうか。
というわけで実践。

旧DBからエクスポート
`mysqldump dbname -u username -h hostname --routines=0 --triggers=0 --events=0 --set-gtid-purged=OFF -p > dbname.sql`

新DBへインポート
`mysql -u new_username -p -h new_hostname new_dbname < dbname.sql`

無事にインポート出来ました。

※オプションを付ける事で何が起こるのか理解してません。
※新DBでは予め空のデータベースを作成しておく必要はあります。
※記事冒頭に記載したリンクを参照して作業を始めたので、log_bin_trust_function_creators の値を1に変更しているが、恐らくこの作業はしなくてもインポート出来ると思います。
Djangoでadminのデータベース設定をmysqlで行おうとしたときに起きたケアレスミス

とある日。

DjangoでMySQLを使用しデータベースのあれこれを設定していましたとさ。

```
python3 manage.py makemigrations
```
を行いまして、正常に作れそう。

```
python3 manage.py showmigrations
```
チェック全部ついてないね。

よし、

```
python3 manage.py sqlmigrate message 0001
```

できたね～じゃあmysqlにアクセスしてちゃんとデータベース生成されているか見よう！

```
mysql> show tables;
Empty set (0.00 sec)
```

###???????????
へいへい、なぜできてないんだい？！

```
python3 manage.py showmigrations

admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
message
 [X] 0001_initial
sessions
 [X] 0001_initial
```

ん？ちゃんと生成されてるな～

じゃあ、サイトにアクセスして実際にadmin動くかやってみるか。
ちゃんとデータベースできてるし、情報も入ってるね！？！？
追加もできるし？！（画像無くてすみません）

##種明かし
根本に帰り、setting.pyを再度見てみる

```
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
　　　（省略）
    }
}
```

###sqlite3?????

そうです、ここの設定が違いました。正しくは、

```
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
　　　（省略）
    }
}
```

ですね。もし、データベース空っぽでも動いた方いたら参考にしていただければ・・・・
しょうもないミスでした。
【Python】データサイエンス100本ノック（構造化データ加工編） 004 解説

- データサイエンス100本ノックをやりきる会を作りました🎉
- こちらの[Slack招待URL](https://join.slack.com/t/data-science-100nocks/shared_invite/zt-gfncg9vm-8W8b3UrDg8R~TKaqUkQpgw)からご参加ください！！
- ぜひ一緒に励まし合いながら、データサイエンス100本ノックをやり切りたいと思っています！

##Youtube
[動画解説](https://youtu.be/Le2h4Um1OIs)もしています。

##問題
P-004: レシート明細のデータフレーム（df_receipt）から売上日（sales_ymd）、顧客ID（customer_id）、商品コード（product_cd）、売上金額（amount）の順に列を指定し、以下の条件を満たすデータを抽出せよ。
- 顧客ID（customer_id）が"CS018205000001"

##解答
```:コード
df_receipt[['sales_ymd', 'customer_id', 'product_cd', 'amount']] \
.query('customer_id == "CS018205000001"')
```

##出力
|  | sales_ymd | customer_id | product_cd | amount |
|--:|--:|:--|:--|--:|
| 36 | 20180911 | CS018205000001 | P071401012 | 2200 |
| 9843 | 20180414 | CS018205000001 | P060104007 | 600 |
| 21110 | 20170614 | CS018205000001 | P050206001 | 990 |
| 27673 | 20170614 | CS018205000001 | P060702015 | 108 |
| 27840 | 20190216 | CS018205000001 | P071005024 | 102 |
| 28757 | 20180414 | CS018205000001 | P071101002 | 278 |
| 39256 | 20190226 | CS018205000001 | P070902035 | 168 |
| 58121 | 20190924 | CS018205000001 | P060805001 | 495 |
| 68117 | 20190226 | CS018205000001 | P071401020 | 2200 |
| 72254 | 20180911 | CS018205000001 | P071401005 | 1100 |
| 88508 | 20190216 | CS018205000001 | P040101002 | 218 |
| 91525 | 20190924 | CS018205000001 | P091503001 | 280 |

##解説
・PandasのDataFrame/Seriesにて、列を指定しつつ、指定した行を確認する方法です。
・列情報を絞り、かつ、行を指定して確認したい時に使用します。
・**'<データ名>[['<列名A>','<列名B>','<列名C>']].guery('<列名A>=="<行情報A>"')'**で、指定した列(列名A,列名B,列名C)のうち、列名A が指定した 行情報A に該当する行を表示します。
・ちなみに、"=="は一致することを表します。"="は代入を表すので、ご注意ください。

※Pythonの比較演算子は[こちら](https://www.javadrive.jp/python/if/index4.html)を参照ください
R言語: マイナス文字の仕様

思いっきり嵌ったので、共有したかったんや。。。。


## 起こったこと
某氏より依頼を受けた。
このエクセルのデータを解析してくれとの旨。

ある事象を説明する各種の変数がテーブルになっていた。
Rであれこれやっていたが、コンソールで走らせた結果と、Rmarkdownで実行した結果が一致しないという自体に遭遇した。


## 原因

いわゆる陰性所見が

~~~

"－"
~~~
を使っていたのが問題だった。
"−"と"－"は、コンソールで実行する分には別の文字である。
しかし、Rmarkdownに記載して、knitrすると、同じ文字として扱われる。
文字コード的な問題だろうか。その先は調べきれていない。

![コメント 2020-07-18 160905.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676634/b18bbd3a-7902-e56f-c4dc-738db1b7cf7e.png)


### 対策

紛らわしいマイナス文字は、一旦全部0に変換してしまえば多分大丈夫。
ファクターだったり、名義尺度だったりした場合にはまたちょっと工夫が必要ですね。


## 環境
- windows10
- R 3.6.3
docker: next.js

next.js with mongodb in Docker

## dev環境

```.yml:docker-compose.yml
version: '3.8'
services:
  web:
    image: node:alpine
    working_dir: /home/node/app
    volumes:
      - ./:/home/node/app
    ports:
      - 3000:3000
    command: npm run dev:calledFromDockerCompose
  db:
    image: mongo
    volumes:
      - ./db:/data/db
    ports:
      - 27017:27017
```

## production環境

```.yml:docker-compose-production.yml
version: '3.8'
services:
  web:
    image: node:alpine
    working_dir: /home/node/app
    volumes:
      - ./:/home/node/app
    ports:
      - 3000:3000
    command: ash -c "npx next build && npx next start"
  db:
    image: mongo
    volumes:
      - ./db:/data/db
```

## コマンド
```.json:package.json
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "pages/index.tsx",
  "scripts": {
    "dev": "docker-compose up",
    "dev:stop": "docker-compose down",
    "dev:calledFromDockerCompose": "NODE_OPTIONS='--inspect' npx next dev",
    "production": "docker-compose -f docker-compose-production.yml up -d",
    "production:stop": "docker-compose -f docker-compose-production.yml down"
  },
```
M5StickCによるジェスチャ認識(2)～サンプルコードによるジェスチャ認識

# M5StickCによるジェスチャー認識
- 今回は、サンプルコードによるジェスチャ認識を目標にします。

# M5StickC系のプログラム関連記事
1. [M5StickCによるジェスチャ認識(1)～インストールから加速度取得まで](https://qiita.com/chimamedia/items/7aa8dac10dc178009943)
2. [M5StickCによるジェスチャ認識(2)～サンプルコードによるジェスチャ認識](https://qiita.com/chimamedia/items/9d8a4703dcd9940d40be)（この記事）
3. [M5StickCによるジェスチャ認識(3)～Wi-Fi接続と学習データの生成](https://qiita.com/chimamedia/items/fd367f75c3979541c49d)
4. M5StickCによるジェスチャ認識(4)～オリジナルデータによるジェスチャ認識
5. M5StickCによる音声認識
※現状の予定になります

# ジェスチャー認識
- Tensorflow-liteを用いてMagic Wandをしている例がありましたので、まずはサンプルを動かしてみて、そのあとにオリジナルのジェスチャーを認識することまでを目的とする
- 参考は以下のサイトから

> [M5Stick-C＋TensorFlow Liteでジェスチャ認識
](https://blog.boochow.com/article/m5stickc-tflite-magic-wand.html)

- サンプルに関しては、著者のかたが[GitHub](https://github.com/boochow/TFLite_Micro_MagicWand_M5Stack/tree/m5stickc)にまとめてくれているので、使わせていただきましょう。
- まずは、GitHubからダウンロードしてきます。
- 次に、PlatformIOで新しいプロジェクトを作成します。その後、先ほどGitHubでダウンロードしたファイルを、PlatformIOで作成したプロジェクトの中にドラッグ＆ドロップします（コピーします）。
- このプロジェクトは、「〇」「W」「∠」の動きを認識し、ディスプレイに表示しするようになっています。
- ディスプレイの出力は「output_handler.cc」で定義されています。
- ジェスチャーを認識するための学習データは「magic_wand_model_data.cc」の中で定義されています。また、「magic_wand_model_data.cc.new」にも定義されており、こちらのほうが新しいモデルのようなので、中身を入れ替えてもいいかと思います。
- ダウンロードしてきたサンプルで、画面上に取得している加速度のデータを表示させたい場合は、「loop関数」の中で以下を追加するとよい

```cpp:main.cpp
M5.Lcd.printf("ID: %d\n", gesture_index);
M5.Lcd.printf("%+4.0f : %+4.0f : %+4.0f\nW %3.2f/R %3.2f/S %3.2f", \
            f[381], f[382], f[383], p[0], p[1], p[2]);
```

- プログラムを書き終えたら「Build」を押して、ビルドする。エラーがなければ、そのまま「Upload」すると、加速度がディスプレイに表示される。また「Upload and Monitor」をクリックすると、PlatformIO内でシリアル通信で取得した加速度のデータを見ることができる。

![6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214668/84d30cf6-0a06-543c-8606-a7f83db14082.jpeg)
macosにてdocker上にwineを実行

macosでwineを動かすのが難しそうだったので docker経由で実行するスクリプトを作成

# 環境
macOS Catalina 10.15.5
Docker desktop 2.3.0.3
Microsoft Remote Desktop 10.3.12

# 概要
https://hub.docker.com/r/scottyhardy/docker-wine/
のイメージを実行して， RDPで使用する

"Documents/Docker/winedir/" フォルダをwineと共有する

# 準備
+ Docker desktop と
+ Microsoft Remote Desktop をインストール
+ 
https://hub.docker.com/r/scottyhardy/docker-wine/
から
docker-wine スクリプトをダウンロードして
Documents/Docker/ に置く

```
cd Documents/Docker/
curl -O https://raw.githubusercontent.com/scottyhardy/docker-wine/master/docker-wine
chmod +x docker-wine
```

# 起動スクリプト
runwine.command を Documents/Docker/ に置き，
ターミナルで実行権限をつける

```
chmod +x runwine.command
```

```zsh:runwine.command
#!/bin/zsh

# https://hub.docker.com/r/scottyhardy/docker-wine/

open "/Applications/Docker.app"
echo -n "waiting"
# Docker.appが起動するまで待つ
while ! docker system info >/dev/null 2>&1; do
    echo -n  "." && sleep 5
done
echo "."

open "/Applications/Microsoft Remote Desktop.app"

docdir=$HOME/Documents/Docker
if [ ! -f $docdir ]; then
    docdir=$HOME/Library/Mobile\ Documents/com~apple~CloudDocs/Documents/Docker
fi
cd $docdir && ./docker-wine  --volume="$docdir/winedir:/home/wineuser/winedir" --rdp
```
# 使用
1. runwine.command をダブルクリック
2. Docker.app と Microsoft Remote Desktop が起動
3. docker-wine が起動するまで待つ（ターミナル.app で xrdp関係の表示出るまで）
4. Microsoft Remote Desktop から docker-wine にwineuserユーザで接続（証明書の警告が出るが continue）
javascript namespace implementation

```js
var VSKULL = {
    v1: "aiueo",
    f1: function(a1){
        return this.v1 + ":" + a1;    // 'this' is needed
    },
    v2: {},
}

let LSKULL = {
    l1: "l1l1l1"
}

const CSKULL = {
    c1: "c1c1c1"
}

const asdf = 'abc'
let l1 = 'lll'

console.log(asdf)
console.log(VSKULL.v1)
console.log(VSKULL.f1("hoge"))
console.log(l1, VSKULL.v2)

console.log(LSKULL.l1)
console.log(CSKULL.c1)

```

```
abc
aiueo
aiueo:hoge
lll {}
l1l1l1
c1c1c1
```

## Refs.
https://techacademy.jp/magazine/14872
https://b.hatena.ne.jp/entry/s/codezine.jp/article/detail/11353
Flutter・Firebase 初期環境構築後のビルドエラー解消方法  雑記

※ メモ用

### 「Running pod install... でビルドが止まる」

ios フォルダの下でPod installを事前に叩く必要あり(万が一podfile.lockがあるなら一旦削除してから実行)

```
Pod install
```

### 「Configuring the default Firebase app...で止まる」

```
Configuring the default Firebase app...
*** First throw call stack:
(
    0   CoreFoundation                      0x00000001096e36fb __exceptionPreprocess + 331
    1   libobjc.A.dylib                     0x0000000108c87ac5 objc_exception_throw + 48
    2   CoreFoundation                      0x00000001096e3555 +[NSException raise:format:] + 197
    3   Runner                              0x00000001033de1d2 +[FIRApp configure] + 562
    4   Runner                              0x0000000103936566 -[FLTCloudFirestorePlugin init] + 214
    5   Runner                              0x00000001039363f9 +[FLTCloudFirestorePlugin registerWithRegistrar:] + 297
    6   Runner                              0x000000010323c300 +[GeneratedPluginRegistrant registerWithRegistry:] + 112
    7   Runner                        <…>
```

FirebaseでiOSアプリを登録した際にGoogleService-Info.plistをダウンロードしてローカルに配置する際に、XcodeからRunnerディレクトリにAddをして上げる必要あり

<img width="327" alt="スクリーンショット 2020-07-18 15.34.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601576/1b3d1227-f2e2-502a-9f70-0b42047ba920.png">
Nuxt.jsでFontAwesomeを導入

##基本手順

おおまかな手順としては以下です。

**①FomtAwesome関連をコマンドからインストール、FomtAwesomeライブラリを準備
↓
②Nuxt.js内でそれらをライブラリとして読み込み
↓
③必要なコマンドだけをライブラリから抽出、各コンポーネントで使用**

##詳細
下記記事を参照にしてください。


**Nuxt.jsでFontAwesomeを使う方法。必要なアイコンだけインポートする！**
https://qiita.com/hiropy0123/items/ee03cdc407692196adf4

なお上記記事はyarnを対象に書かれているため、npmでのfontawesomeインストールに関しては以下をどうぞ。
**Font Awesome を Vue.js で使ってみよう**
https://qiita.com/kurararara/items/d76776a7dc2d763a068b

##補足

上記だけでは初心者には少しわかりづらいところもあったので説明します。

**必要なコマンドだけをライブラリから抽出、各コンポーネントで使用する方法**

###①まずFont Awesomeのサイトに行きます。
**Font Awesome**
https://fontawesome.com/

###②使いたいアイコンのページへ行きます。
<img width="1238" alt="スクリーンショット 2020-07-18 13.08.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550650/a3377535-81ee-127e-0c50-77e225bcbb70.png">

###③名前をアレンジ
そしてここに注目です。
<img width="1238" alt="スクリーンショット 2020-07-18 13.08.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550650/be8a4167-fceb-3844-b15e-e92965758e51.png">

**i class="fas fa-map-marker-alt"**
と書かれています。
この**fa-map-marker-alt**がこのアイコン独自の名前になります。
しかしこれはNuxtで使う用の形式ではありません。
少しアレンジします。


アレンジといっても

- 「-」を除去
- 各単語の先頭を大文字化

するだけです。

つまりこの場合
**fa-map-marker-alt**
が
**faMapMarkerAlt**となります。

これがNuxtで使えるアイコンの名前です。

###④アイコンをライブラリからインポートして使う

そして後は上記ページにもあった通り、アイコンをライブラリからインポートして使うだけです。

このインポートの際に上記の名前を利用下さい。

つまり

```*.vue
<script>
import { faMapMarkerAlt } from ‘@fortawesome/free-solid-svg-icons’
</script>
```

みたいな感じです。

ちなみにコチラは、必要なアイコンのみをインポートする方法です。

いくつもアイコンを使う必要がある場合は以下に詳細が書いてます。
**Font Awesome を Vue.js で使ってみよう**
https://qiita.com/kurararara/items/d76776a7dc2d763a068b