OmniAICreator/Qiita-1.07M huggingface dataset:
フラクタル図形を描く(道具編)


# フラクタル図形とは
フラクタル図形は「自己相似」という構造をもった図形です。自己相似な図形は全体と部分が似た構造を持つ、不思議な絵になります。このような構造は、自然界にも多くあらわれるので、逆に、フラクタル構造をもつ図形を自分のプログラムで生成できるようになれば、なんとなく「自然界にある～っぽい図形」を描く事ができます。
以下の絵は非常に単純な再帰的なプログラムから描かれますが、どことなく、自然界にある「木」の構造に似ているところがあると思いませんか？
![turtle_tree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101445/5a96bcd0-99f5-9b0d-d001-504c3200867f.png)

# 道具＝タートルグラフィクス

よく知られているフラクタル図形が他にもいくつかありますが、それらをを描くプログラムをそれぞれ作るよりも、いったんタートルグラフィックスのライブラリを用意してそれを利用して作るのが楽ではないか、と思いますので、ここ超略式のタートルグラフィクスライブラリを準備し、フラクタル図形を描く道具とします。

## ところで、タートルグラフィクスとは

タートルグラフィックスは、描画スクリーン上に生息する「ペンを持った亀（タートル）」を使った描画の方法、と考える事ができます。タートルは与えられた命令に従って動きます。タートルが受け付ける基本命令は以下の６つです。

|  命令  |  略称  |  意味  |
| ---- | ---- | ---- |
|  forward len|  fd  |前にlen進む |
|  back len|  bk  |後ろにlen下がる  |
|  right th |  rt  | 右にth度方向を変える  |
|  left th |  lt  |左にth度方向を変える  |
|  penup |  pu  |ペンを上げる  |
|  pendown |  pd  |ペンを上げる  |

タートルは、penを上げている状態で前に進んでも移動するだけ、penを下げている状態では、進んだときに軌跡が残ります。タートルグラフィクスでは、この軌跡をもって描きたい図形とみなします。

なお、この考え方はLogoというプログラミング言語のインタラクティブな描画環境として提供されているものです。

### 例
例えば、一辺の長さが10の正方形を描くタートルへの命令列は以下になります。

```
pd; 
fd 10; rt 90;
fd 10; rt 90; 
fd 10; rt 90; 
fd 10; rt 90; 
```
# タートルグラフィックスライブラリの実装
6つの命令は以下のように実装できます(c++)。

```c++
// turtle.cxx Simple Turtle Graphics Library
#include <iostream>
#include <math.h>
using namespace std;

float x = 0.0;
float y = 0.0;
float angle = 0.0;
bool pendown = false;

void pd() { pendown = true; }
void pu() { pendown = false; }
void rt(float th) { angle += th; }
void lt(float th) { angle -= th; }
void fd(float len) {
  float tx = x + len * sin(M_PI*angle/180.0);
  float ty = y + len * cos(M_PI*angle/180.0);
  if(pendown) {
     cout << x  << " " << y  << endl;    // gnuplot's line
     cout << tx << " " << ty << endl << endl;
  }
  x = tx;
  y = ty;
}
void bk(float len) {fd(-len);}


```
注意点としては、このままだとangleのオーバフロー可能性があるので、更新タイミングで360とのmodを取っておいたほうが安全かもしれません。

なお、タートルは明らかにオブジェクトとして定義できるので、Turtleクラスを定義したいところですが、短さ+見やすさを追求した結果、ここではこれに留めておきます（ほぼ、コード全体をclass Turtle { ... } で囲むだけ、ですが)。


## fd命令の説明

他は問題ないと思いますが、fd(forward)命令のところの式だけは簡単に説明しておきます。

![turtle_impl_fd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101445/c39244f9-38bb-49a8-128a-b8a7f3de22ae.png)



sin, cosの引数で M_PI*angle/180.0という計算をしているところは、sin, cosの引数はラジアン単位なので、度(degree)から以下の関係式を使った変換となっています。

```math
180(degree) = \pi (rad)
```

# 再帰Tree

最後にTurtleグラフィクスでフラクタル図形を１つ描いてみます。すでに示したタートルグラフィクスのコードと一緒にビルドしてみてください。

```c++
// treemain.cxx

void pd();
void pu();
void rt(float th);
void lt(float th);
void fd(float len);
void bk(float len);

void tree(float len, float th, float r, int n) {
  if(n > 0) {
    fd(len);
    lt(th);
    tree(len*r, th, r, n-1);
    rt(2.0*th);
    tree(len*r, th, r, n-1);
    lt(th);
    bk(len);
  }
}
int main()
{
   pd();
   tree(10.0, 30, 0.7, 12);
}

```
# ビルド、実行

以下で。

```sh
$ g++ treemain.cxx turtle.cxx -o treemain
$ ./treemain > tt.dat
```

# 描画

gnuplotを利用します。gnuplotのコマンドは以下で。

```sh
gnuplot> set size ratio -1
gnuplot> plot "tt.dat" w l
```
gnuplotコマンドの一行目でx,y軸の比を同じにします。
また、描画結果は本記事冒頭のものです。

# まとめ

今回は、フラクタル図形を描くための道具立てとしてのタートルグラフィックスの実装方法を紹介しました。また、最後に再帰的に描かれるTreeの描画を行いました（あまり説明していませんが）。

以上、です。
AndroidからGoogle Cloud TTS を使ってみる 【SSML】

# 概要
[AndoirdからGoogle Cloud Text To Speech を使ってみる【音声を合成する】]
(https://qiita.com/maKunugi/items/16f2fcfbe5d4567b44bd)
の続きになります。

上記の記事では、Google Cloud Text To Speechを用いてAndroidアプリから音声合成を行う方法について紹介しました。

今回は、読み上げる音声がより自然な発話になるよう、SSMLを用いて発話をさせる方法についてメモしています。
SSMLについては下記をご参照ください。
[音声合成マークアップ言語](https://cloud.google.com/text-to-speech/docs/ssml?hl=ja)

# 実装方法
前回同様、下記のREST APIを利用していきます。
https://cloud.google.com/text-to-speech/docs/apis?hl=ja
（エンドポイント）
```/v1beta1/text:synthesize```

前回は文字列をそのまま投げていましたが、今回はSSMLをリクエストとして送信します。

（原文）

```
The SSML standard is defined by the W3C.
```

（SSML）

```
<speak>The <say-as interpret-as="characters">SSML</say-as>
          standard <break time="1s"/>is defined by the
          <sub alias="World Wide Web Consortium">W3C</sub>.</speak>
```

SSMLの文法については下記を参照
https://cloud.google.com/text-to-speech/docs/ssml?hl=ja

```
{
  "input": {
    object (SynthesisInput)
  },
  "voice": {
    object (VoiceSelectionParams)
  },
  "audioConfig": {
    object (AudioConfig)
  }
}
```
今回は上記のリクエストボディのSynthesisInputにSSML文字列を入れていきます。

```kotlin

    data class SynthesisInput(
        val ssml: String
    )
```

SSMLサンプル ("をエスケープ)

```
<speak>The <say-as interpret-as=\\\"characters\\\">SSML</say-as>" +
            "standard <break time=\\\"1s\\\"/>is defined by the " +
            "<sub alias=\\\"World Wide Web Consortium\\\">W3C</sub>.</speak>
```

前回のサンプルを上記のSSMLを用いた実装に書き換えるとより自然な音声読み上げを試すことができます。

今回のサンプルの全てのコードはこちらのGithubリポジトリをご参照ください
https://github.com/k-masashi/GoogleCloudTtsAndroidSample/tree/ssml
お客様が加入して○日後は○月○日ですをGoogleスプレッドシートで簡単にもとめられるの？

## タイトルの背景

弊社の、カスタマーサポートのspringcat :cat: さんから
「**お客様へ、加入して60日後の日にちを案内する時に、スプレッドシートで簡単にもとめたりできるの？**」
と質問があり、スプレッドシートで簡単にもとめる方法をQiita見ながらspringcatさんに作ってもらおうと思ったのがきっかけです。

## 完成イメージ
見た目はしょぼいですけどこんな感じ。加入して何日かも表示してみました。
薄オレンジ色セルはspringcatさんが直接入力するセルで、それ以外は式いれたりしてさわらないセルです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181001/7d7a87dc-5a88-9f65-bfc1-ebd469d84b36.png)


## 説明
ポイントは、スプレッドシート上での日にちの加算減算は **+1** や **-1** するだけで簡単にできることです。（エクセルも多分同じ）

### 今日の日にちは{B1セル}です。
**B1** のセルに `=TODAY()` 関数を入れると、スプレッドシートを開いた時いつも **今日の日付** を表示してくれます。

### お客様の加入日は{B3セル}です。
**B3** セルは、お客様の加入日をspringcatさんが直接入力するだけのセルになります。

### お客様が加入して{B5セル}日後は{D5セル}です。
本題の、加入して60日後（本当に案内したいのは、60日**目**かもしれない。。。未確認）の表示方法です。**B5** セルは60日後の `60` をspringcatさんが直接入力するだけのセルになります。
30日後が知りたければ30を入力すればOK。
60日後の日付を表示したい **D5** セルに `=B3+B5` を入れます。 `加入日＋60` としているだけでとても簡単ですね。
（加入日を1日**目**として60日**目**としたい場合は `=B3+B5+1` をしましょう。）

### （おまけ）加入して{B7セル}日経過を表示
**B7** セルに `=B1-B3`と入れます。 `今日の日付－加入日` してるだけです。

## 日付の表示形式の変更方法
`表示形式` -> `数字` -> `表示形式の詳細設定` -> `その他の日付や時刻の形式` で表示形式をスラッシュ区切りから年月日とか色々変更できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181001/4562d699-b748-f2e5-2048-099bc8838c29.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181001/3818ce4d-b74c-332e-5282-a96b25c6f4ff.png)


## さいごに
足し算と引き算だけで簡単にツールがつくれました。
こんな簡単なことでもシステム化しようとするとけっこう手間がかかるので、スプレッドシートなど上手く活用する方法を社内で共有できたらなーと思いました。
[Python3] FXチャートにサポートライン生成を試みる

# 概要

テクニカル分析を行うためには、サポート（レジスタンス）ラインは必須
でも意外と誰も作ってない....？
ように見えたので、オリジナルで生成する処理を書いてみました。

# 前提データ

こんなデータが既にあるとして話を進めます。
（200行以上）

```python:python
> csv_path = 'hoge.csv'
> pd.read_csv(csv_path, index_col=0)

 	close 	high 	low 	open
time 				
2019-08-29 01:30:00 	129.310 	129.420 	129.302 	129.420
2019-08-29 01:40:00 	129.258 	129.324 	129.254 	129.312
2019-08-29 01:50:00 	129.229 	129.264 	129.221 	129.256
2019-08-29 02:00:00 	129.260 	129.262 	129.184 	129.232
2019-08-29 02:10:00 	129.264 	129.295 	129.241 	129.258
...
```

# ソースコード

```python:python
import matplotlib
import matplotlib.pyplot as plt
import mplfinance.original_flavor as mpf
import numpy as np
import pandas as pd

csv_path = 'hoge.csv'
candles = pd.read_csv(csv_path, index_col=0)[-200:].copy()

# INFO: ちょうどいい感じにサポートラインの支点を作る（※詳細は後述）
support_points = (pd.Series.rolling(candles.low, window=7).min() == candles.low) \
                 & (candles.low.shift(1) > candles.low) \
                 & (candles.low < candles.low.shift(-1))

# サポートラインの支点から、次の支点までの間は同じ価格をsupportラインとする
candles.loc[support_points, 'support'] = candles[support_points].low
candles['support'] = candles.support.fillna(method='ffill')


# - - - - - - - - - - - - - - - - - - - - - - - -
#               以降は単なる描画処理
# - - - - - - - - - - - - - - - - - - - - - - - -
figure, (axis1) = plt.subplots(nrows=1, ncols=1, figsize=(20, 8), dpi=200)
mpf.candlestick2_ohlc(
    axis1,
    opens  = candles.open.values,
    highs  = candles.high.values,
    lows   = candles.low.values,
    closes = candles.close.values,
    width=0.6, colorup='#77d879', colordown='#db3f3f'
)

axis1.scatter(x=candles.index.values, y=candles.support.values, label='support', c='orangered', marker= '_', s=3)

# グラフの見た目を整形
### X軸の見た目を整える
xticks_number  = 12 # 12本(60分)刻みに目盛りを書く
xticks_index   = range(0, len(candles), xticks_number)
xticks_display = [candles.index.values[i][:16] for i in xticks_index] # 時間を切り出すため、先頭12文字目から取る
# axis1を装飾
plt.sca(axis1)
plt.xticks(xticks_index, xticks_display, rotation=30)
plt.show()

```

# 解説

計算方法としては、

- 候補抽出1  
連続する3本分の足をセットとして考え、真ん中の足の安値が両脇の足の安値より低くなっている点を絞り込む
- 候補抽出2  
1で絞り込んだ結果からさらに、過去直近7本分の安値の中で最安値となっている点だけを残す
（この結果を「最安値配列」とする）
- サポートライン生成  
最安値配列の隙間は`.fillna(method='ffill')`で埋める

# 結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/7b6e0eca-4b04-eb6a-b448-5b627de1ce9c.png)

うーん...まぁそこそこか

### 注意点

- 見ての通り、下降トレンドのときは使い物にならない
使うなら上昇トレンドか、レンジ相場か...？
- 単独では特に役に立たない

# 関連記事

- [scipyでピーク値の抽出](https://qiita.com/wrblue_mica34/items/e174a71570abb710dcfb)  
ピーク値を上手く使えばサポート/レジスタンスラインを引けそう
- [Pythonでサポートラインとレジスタンスラインを引いてみる](http://www.algo-fx-blog.com/python-sup-res-line-fx/)
見た感じ適切なラインが引けているように見えないので、使う予定はなさそう
ただ、この記事に掲載されている  

    > savgol_filter関数を使い終値を平準化して、ローカルのミニマとマキシマを求める方法

    というのはなかなか興味深いので、試してみたい気持ちはある...
Solidity公式Exampleでつまづいたことメモ

#Solidity 
##Solidity公式Exampleでつまづいたことメモ。

OS：(Mac)Mojave
メモリ：8GB
開発環境：VsCode

[公式サイト]
https://solidity-jp.readthedocs.io/ja/latest/solidity-by-example.html#voting

<img width="847" alt="スクリーンショット 2019-12-27 23.48.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/443312/20c20010-bb12-e471-2cfe-70f4bdb0b6ac.png">

settigs.jsonのユーザー設定で下記を設定すると直った。
なお、Windows10では起きていない。
対処：
```
// 以下、追記
    "solidity.soliumRules": {
        "linebreak-style": "windows"
      }
// 追記、終わり
```
【Rails】migrationファイル内でDML操作（データ補正）を行うやり方

# 環境

- Rails 5.2.2

# 想定されるシチュエーション

- migrationの中でカラムを追加した後に、併せてデータを追加したい。 
  - `reset_column_information`を使って、modelが確実に新しいカラムを持っているようにする。
  - [参考](https://github.com/rails/rails/blob/v5.1.4/activerecord/lib/active_record/migration.rb#L409-L424)
- migrationを書いた後になってから、クラス名が変わる場合がある。
  - クラスとテーブルがmigrationファイルの中で整合性が取れるように、クラス定義をする。

# 参考

https://github.com/rubocop-hq/rails-style-guide#define-model-class-migrations

## 例1

```ruby
class AddStatusToStripePayments < ActiveRecord::Migration[5.2]
  class StripePayment < ApplicationRecord
    self.table_name = :stripe_payments
  end

  def change
    add_column :stripe_payments, :object, :string
    add_column :stripe_payments, :status, :string

    StripePayment.reset_column_information

    reversible do |dir|
      dir.up do
        StripePayment.find_each do |payment|
          resp = payment.response
          payment.update!(object: resp['object'], status: resp['status'])
        end

        change_column :stripe_payments, :object, :string, null: false
        change_column :stripe_payments, :status, :string, null: false
      end
    end

    reversible do |dir|
      dir.up do
        StripePayment.find_each do |payment|
          unless payment.object.present? && payment.status.present?
            fail "object and/or status of the payment (id: #{payment.id}) is empty"
          end
        end
      end
    end
  end
end

```

## 例2



```ruby
class AddFormatToWorks < ActiveRecord::Migration[5.2]
  def change
    add_column :works, :format, :integer, after: :title

    reversible do |dir|
      dir.up do
        execute("UPDATE works SET format = 0")
        change_column :works, :format, :integer, null: false
      end
    end
  end
end
```

# 備考

上記では、Railsのソースコード内のコメントに倣って、`add_column`した後に`reset_column_information`していますが、[ここ](https://blog.onk.ninja/2017/10/18/use_reset_column_information)では「modelを触ったので後始末としてリセットする」と書かれています。
どっちが正しいんでしょ？（時間がある時に検証します）

# 追記

- [migration_data](https://github.com/ka8725/migration_data) という gem を使えば、前述のことを考えなくて済むかもしれない。
M5StackでAmazon FreeRTOSを使用する４（SDカード編）

# はじめに

[第１回](https://qiita.com/fukuebiz/items/54f765d12c084ceea392)、[第２回](https://qiita.com/fukuebiz/items/3b803912bf51b1f46d79)、[前回](https://qiita.com/fukuebiz/items/732296b84e68a1a08d41)と、M5StackでAmazon FreeRTOSが動作する環境が出来上がってきました。あとは、SDカードにもアクセスしたいですね。SDカードは日本語フォントの表示や、オフライン時のデータ保存に大活躍です。

仕事で関わっている[Record Meeting](https://www.recordmeeting.jp/)という自動議事メモ作成サービスでも、日本語を表示させています。

![COET Record Meeting](https://www.tis.co.jp/images/jp/news/2019/tis_news/0725_1/20190725_1_01.png)

SDカードのアクセスを含めて、ESD-IDFで提供されているAPIが利用できます。SDカードのアクセス以外にもESD-IDFでAPIが多数提供されていますので、詳細は[ESP-IDF Programming Guide/API Reference](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/index.html) を参照してください。

[SDカードアクセスサンプル](https://github.com/fukuen/m5stack-freertos-sd)の実行は、Git bashから、任意の場所にデモアプリをダウンロードします

```bash:
git clone https://github.com/fukuen/m5stack-freertos-sd --recursive
```

ダウンロードしたディレクトリーに移動して、アプリケーションをビルドします。

```bash:
cd m5stack-freertos-tft
cmake -DCMAKE_TOOLCHAIN_FILE=amazon-freertos/tools/cmake/toolchains/xtensa-esp32.cmake -GNinja -S . -B build
cd build
ninja
```

ビルドが完了したら、フラッシュします。

```bash:
cd ..
idf.py flash
```

シリアルコンソールでモニターしてみます。

```bash:
idf.py monitor
```

無事SDカードにアクセスできました。

# 最後に

必要な環境がそろってきたので、OTAなどAmazon FreeRTOSの機能を使っていきたいと思います。
#Rails の delete でレコードが削除できない？ それ where みたいな引数指定をしてませんか？

`User.delete(name: 'Alice')` 

書けそうに思うじゃないですか、ダメなんですよね、これが。

`User.where(name: 'Alice').destroy_all`

ってやりたかった。

毎回忘れる頃に忘れてる。

---

User.delete class method is not like "where" style
User.delete class mathod takes id or ids in arguments

```rb
User.delete(name: 'Alice')
  User Destroy (0.7ms)  DELETE FROM `users` WHERE `users`.`id` = NULL
=> 0
```

Specify id

```rb
User.delete(24)
  User Destroy (2.8ms)  DELETE FROM `users` WHERE `users`.`id` = 24
=> 1
```

Specify ids

```rb
User.delete([25,26])
  User Destroy (5.0ms)  DELETE FROM `users` WHERE `users`.`id` IN (25, 26)
=> 2
```

return value is "deleted recourds" num

btw User.destory class method not exists

```rb
User.destroy(name: 'Alice')
# ActiveRecord::RecordNotFound: Couldn't find User with 'id'={:name=>"Alice"}
```

You must find user instance and delete
But delete not consider abount association

```rb
User.find_by(name: 'Alice').delete
  # User Load (0.9ms)  SELECT  `users`.* FROM `users` WHERE `users`.`name` = 'Alice' LIMIT 1
  # User Destroy (3.1ms)  DELETE FROM `users` WHERE `users`.`id` = 12
```

You must use "destory" usally because "destroy" take care abount association

```rb
User.find_by(name: 'Alice').destroy
#  User Load (0.6ms)  SELECT  `users`.* FROM `users` WHERE `users`.`name` = 'Alice' LIMIT 1
#   (0.4ms)  BEGIN
#  User Destroy (0.8ms)  DELETE FROM `users` WHERE `users`.`id` = 23
#   (1.5ms)  COMMIT
```

You can delete multiple records with "where" and "delete_all"

```rb
[79] pry(main)> User.where(name: 'Alice').delete_all
  User Destroy (3.7ms)  DELETE FROM `users` WHERE `users`.`name` = 'Alice'
=> 2
```

You can delete multiple records with "where" and "destroy_all"

```rb
[82] pry(main)> User.where(name: 'Alice').destroy_all
  User Load (0.8ms)  SELECT `users`.* FROM `users` WHERE `users`.`name` = 'Alice'
   (0.7ms)  BEGIN
  User Destroy (3.3ms)  DELETE FROM `users` WHERE `users`.`id` = 21
   (6.1ms)  COMMIT
   (0.6ms)  BEGIN
  User Destroy (0.9ms)  DELETE FROM `users` WHERE `users`.`id` = 22
   (3.4ms)  COMMIT

````


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2880








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
ChromeのログインID、パスワードのプリセットを外す

#はじめに
Chromeの機能でログインID、パスワードは保存することはできます。
保存するとその以降、入力不要でログインできます。
ただし、新規アカウント作成画面、パスワード変更画面でもプリセットをしてしまう場合もありあす。
このような画面はプリセットがあると、邪魔になります。

autocomplete="off" を設定しても回避できません。

#利用者のブラウザから外す
危ないと感じた場合は、Chromeのパスワードの保存機能をOFFにすることで回避できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/a0143add-78cd-4c0a-1f3c-65fdee7af8d0.png)

#アプリ側で強制解除
##javascriptコードリセット
##入力フォーム
```html
<form name="form1" method="post">
  <input type="text" name="emailAddress" id="emailAddress">
  <input type="password" name="password" id="password">
<form/>
```

例えば一秒後、空白で設定する


```javascript
setTimeout(function() {
  document.form1.password.value = "";
}, 1000)
```

##readonlyとして初期表示してプリセットされないようにする
```html
<form name="form1" method="post">
  <input type="text" name="emailAddress" id="emailAddress">
  <input type="password" name="password" id="password" readonly  onFocus="this.readOnly = false">
<form/>
```

フォーカスする際にreadonlyを外します。


以上
M2Crypto を python3から使おうと「pip install M2Crypto」したらエラーが出た

# 背景
- Ubuntu 18.04 に M2Cryptoを入れてpython3から使おうとしたら、必要なパッケージが入っていなくてエラーがでた。
- 環境
  - Ubuntu 18.04.3 LTS
  - Python 3.6.9
  - (python2系は入っていない)


# 結論: インストール方法
```
$ sudo apt-get install build-essential python3-dev openssl libssl-dev swig
$ pip install M2Crypto
```
のように、必要なパッケージをapt-getで入れておけば問題なし。

# step by step で入れようとした時のエラー
- エラーメッセージでググってもドンピシャのページが見つからなかったので、メモを残しておく。

---
- c++ (またはbuild-essential)が入っていない

```
error: [Errno 2] No such file or directory: 'cpp': 'cpp'
```
と出てインストールできなかったら、
$ sudo apt-get install cpp

---
- gcc (またはbuild-essential)が入っていない

```
    unable to execute 'x86_64-linux-gnu-gcc': No such file or directory
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
```
と出てインストールできなかったら、
$ sudo apt-get install gcc

---
- python3-develが入っていない

```
    SWIG/_m2crypto_wrap.c:127:10: fatal error: Python.h: No such file or directory
     #include <Python.h>
              ^~~~~~~~~~
    compilation terminated.
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
```
と出てインストールできなかったら、
$ sudo apt-get install python3-dev

---
- openssl, libssl-devが入っていない

```
    SWIG/_m2crypto_wrap.c:3561:10: fatal error: openssl/err.h: No such file or directory
     #include <openssl/err.h>
              ^~~~~~~~~~~~~~~
    compilation terminated.
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
```
と出てインストールできなかったら、
$ sudo apt-get install openssl libssl-dev

---
- swigが入っていない

```
    SWIG/_m2crypto_wrap.c:31151:5: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
         (PyObject*) 0,                            /* ht_slots */
         ^
    SWIG/_m2crypto_wrap.c:31151:5: note: (near initialization for ‘SwigPyBuiltin___cbd_t_type.as_buffer.bf_releasebuffer’)
    SWIG/_m2crypto_wrap.c:30993:54: warning: missing braces around initializer [-Wmissing-braces]
     static PyHeapTypeObject SwigPyBuiltin___cbd_t_type = {
                                                          ^
    SWIG/_m2crypto_wrap.c:31150:5:
         (PyObject*) 0,                            /* ht_name */
         {
    SWIG/_m2crypto_wrap.c:31152:1:
     };
     }
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
```
と出てインストールできなかったら、
$ sudo apt-get install swig
(3.0.12-1が入った)

---
- この後も続きそうですが、上述のインストール方法のように普通に必要パッケージを入れてからM2Cryptoを入れました。
Azure Solutions Architect Expert合格記

Azure Solutions Architect Expertの合格記です。
取得を考えている方の参考になれば幸いです。

# 試験概要
AZ-300とAZ-301に合格する必要があります。

- [Exam AZ-300: Microsoft Azure Architect Technologies](https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-300)
- [Exam AZ-301: Microsoft Azure Architect Design](https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-301)

- 時間：180分
- 700点以上で合格

# 結果
- AZ-300 776点で合格
    - ほぼ準備なしで無事合格。
- AZ-301 1回目 654点で不合格
    - 公式のオンライン学習を軽くやった程度で受けたら、撃沈。
- AZ-301 2回目 760点で合格
    - オンライン学習を再度ちゃんとやったら合格したものの点数は伸びず。。。

# 受験者のスペック

- Azureの実務経験なし
- 過去にMCSA Cloud Platform合格
    - 532 Developing Microsoft Azure Solutions
    - 533 Implementing Microsoft Azure Infrastructure Solutions
- クラウド歴：5年10カ月
- Azure以外の保有資格
    - GCP: プロフェッショナル×5(Architect+Data+Developer+Network+Security)
    - AWS: アソシエイト×3＋プロフェッショナル×2＋Specialty×5(Big Data＋Security＋Network+ML＋Alexa)＋Practitioner
- 外観：メガネぼーず

# 難易度等

- 1個落ちているのに言うのもなんですが、過去合格した532・533と比べれば重箱の隅感がなく簡単に感じました。
- AZ-300はAzureポータルの実技が結構あったためか、時間はギリギリでした。
- 逆にAZ-301は時間はなかり余りました。
- Azureを実務でバリバリ利用されている方であれば、結構簡単に感じるのではないかと思います。

# おすすめの対策

- 公式のオンライン学習がおすすめです。Azureのサンドボックス環境が無料で利用できます。
    - https://docs.microsoft.com/ja-jp/learn/certifications/azure-solutions-architect
- なぜか上のリストにはAzure AD関連がないので、別途Active Directoryで検索して出てくる学習コースと、Azure ADのドキュメントをよく読んでおくことを強くおすすめします。
    - https://docs.microsoft.com/ja-jp/learn/browse/?term=active%20directory
    - https://docs.microsoft.com/ja-jp/azure/active-directory/

# 雑感
- GCPの再認定試験もあり12月は毎週何らかの試験を受けていたのでちょっと疲れました。
- 来年のAWSとGCPのベータ試験の本番リリースまでは時間があくので、FintechのtechでなくFin系を受けてみようかな。
    - https://www.kinzai.or.jp/kentei/5h7.html
Ruby on #Rails  - Model#delete does not work? can not delete records? delete class method take argument takes only ids. not like "where". Recommend use find_by / find / where and "destroy"

x `User.delete(name: 'Alice')`  
o `User.where(name: 'Alice').destroy_all`


---

User.delete class method is not like "where" style
User.delete class mathod takes id or ids in arguments

```rb
User.delete(name: 'Alice')
  User Destroy (0.7ms)  DELETE FROM `users` WHERE `users`.`id` = NULL
=> 0
```

Specify id

```rb
User.delete(24)
  User Destroy (2.8ms)  DELETE FROM `users` WHERE `users`.`id` = 24
=> 1
```

Specify ids

```rb
User.delete([25,26])
  User Destroy (5.0ms)  DELETE FROM `users` WHERE `users`.`id` IN (25, 26)
=> 2
```

return value is "deleted recourds" num

btw User.destory class method not exists

```rb
User.destroy(name: 'Alice')
# ActiveRecord::RecordNotFound: Couldn't find User with 'id'={:name=>"Alice"}
```

You must find user instance and delete
But delete not consider abount association

```rb
User.find_by(name: 'Alice').delete
  # User Load (0.9ms)  SELECT  `users`.* FROM `users` WHERE `users`.`name` = 'Alice' LIMIT 1
  # User Destroy (3.1ms)  DELETE FROM `users` WHERE `users`.`id` = 12
```

You must use "destory" usally because "destroy" take care abount association

```rb
User.find_by(name: 'Alice').destroy
#  User Load (0.6ms)  SELECT  `users`.* FROM `users` WHERE `users`.`name` = 'Alice' LIMIT 1
#   (0.4ms)  BEGIN
#  User Destroy (0.8ms)  DELETE FROM `users` WHERE `users`.`id` = 23
#   (1.5ms)  COMMIT
```

You can delete multiple records with "where" and "delete_all"

```rb
[79] pry(main)> User.where(name: 'Alice').delete_all
  User Destroy (3.7ms)  DELETE FROM `users` WHERE `users`.`name` = 'Alice'
=> 2
```

You can delete multiple records with "where" and "destroy_all"

```rb
[82] pry(main)> User.where(name: 'Alice').destroy_all
  User Load (0.8ms)  SELECT `users`.* FROM `users` WHERE `users`.`name` = 'Alice'
   (0.7ms)  BEGIN
  User Destroy (3.3ms)  DELETE FROM `users` WHERE `users`.`id` = 21
   (6.1ms)  COMMIT
   (0.6ms)  BEGIN
  User Destroy (0.9ms)  DELETE FROM `users` WHERE `users`.`id` = 22
   (3.4ms)  COMMIT

````


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2879








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
初学者によるプログラミングMemo　#15 ハッシュのvalueだけ取り出したい

# はじめに
今回はハッシュの中のvalueだけを取り出して配列に入れ直すお話です
簡単なので短めです
なお、本記述はMacにおいて、Railsでの開発を前提としています
また、まだまだひよっこですので、不備等ございましたらご指摘いただけると幸いです

# 目次
- ハッシュを作ろう
- ハッシュから値を取り出して配列に入れ直そう
- おまけ


## ハッシュを作ろう
この項目がいるか悩みましたが、ハッシュの復習も兼ねて書きます
まずは空のハッシュを作らないと始まりませんね

```.rb
hush = {}
```
できました
次になんでもいいので値を入れていき、ついでに確認しましょう

```.rb
hush = {}
hush[:food] = "唐揚げ"
hush[:event] = "お祭り"
hush[:taste] = "さほど美味しくない"
hush[:action] = "食べてしまう"

p hush

=>{:food=>"唐揚げ", :event=>"お祭り", :taste=>"さほど美味しくない", :action=>"食べてしまう"}
```
できました

## ハッシュから値を取り出して配列に入れ直そう
では本題に入りましょう
やり方は至ってシンプルです
ハッシュからひたすら"key"と"value"を取り出して、新しい配列に入れるだけです

```.rb
hush = {}
hush[:food] = "唐揚げ"
hush[:event] = "お祭り"
hush[:taste] = "さほど美味しくない"
hush[:action] = "食べてしまう"

values = []
hush.each do |key, value|
  values << value
end

p values

=>["唐揚げ", "お祭り", "さほど美味しくない", "食べてしまう"]
```
できました
each文で"key"と"value"を回して"value"だけを配列"values"にぶち込んでいます

## おまけ
もちろん"key"だけを配列に入れることもできます

```.rb
hush = {}
hush[:food] = "唐揚げ"
hush[:event] = "お祭り"
hush[:taste] = "さほど美味しくない"
hush[:action] = "食べてしまう"

keys = []
values = []
hush.each do |key, value|
  keys << key
  values << value
end

p keys
p values

=> [:food, :event, :taste, :action]
=> ["唐揚げ", "お祭り", "さほど美味しくない", "食べてしまう"]

```
現段階では"key"だけ取り出して配列化するメリットが私にはわかりませんが、できましたね

しかしなぜお祭りの唐揚げの大半はさほど美味しくはないのに食べてしまうのでしょうか

それは…

**唐揚げが大好きだからです**
Vue functional componentでのmethods,filter

functional componentの基本については[以前](https://qiita.com/ryuseiyarou/items/2e8ab162d173085c273d)記載したので、
今回はfilterとmethodについてまとめます。

#filter
通常のcomponent同様

```vuejs
<template functional>
  <div>
    {{ props.num | yen }}
  </div>
</template>

<script>
export default {
  props: {
    num: { type: Number, default: 0 }
  },
  filters: {
    yen: function(str) {
      return str + "yen";
    }
  }
};
</script>
```

#method

*$optionsを通してアクセスできる。*

通常のcomponentと同じように「methods:{}」とオブジェクトの中に定義しても問題ないが、テンプレートで「$options.methods.XXX()」となって見づらくなるだけのため直接。
またmethodの中で「this.XXX(props)」はできないため、使用するならmethodの引数として渡す。

```vuejs
<template functional>
  <div>
    {{ $options.double(props.num) }}
  </div>
</template>

<script>
export default {
  props: {
    num: { type: Number, default: 0 }
  },
  double: function(num) {
    return num * 2;
  }
};
</script>
```
カートの中にある商品を全て削除する

商品をいっぱい入れたけど、カートの中を空にしたい！
eccube4ではデフォルトではカートを空にする機能はないので実装する必要があります。

```CartController.php
declare(strict_types=1);
namespace Customize\Controller;

use Eccube\Controller\AbstractController;
use Eccube\Service\CartService;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Annotation\Route;

class CartController extends AbstractController
{
    protected $cartService;

    public function __construct(CartService $cartService)
    {
        $this->cartService = $cartService;
    }

    /**
     * カートの中にある商品を全て削除する
     * @Route("/cart/clear", name="cart_clear")
     */
    public function clear(): RedirectResponse
    {
        $this->cartService->clear();

        return $this->redirectToRoute('cart');
    }
}

```

後はhtml書いてあげればおｋ

```html
<a href="{{ path('cart_clear') }}">カートを空にする</a>
```
CDN別 どこのエッジに接続しているかの判別方法

# はじめに
CDN経由でアクセスしているとき、どこのエッジに接続しているのか？と思ったことがある人も多いと思います。特にパブリックDNSリゾルバーを使っている場合、適切にエッジを選択できないケースがあるため、ちゃんと近くのエッジに接続しているか確認したくなるケースも多いと思います。
一部のCDN業者は明示的or暗黙的にエッジの地域を出力しています。ここでは代表的なCDN業者について調べてみました。

# CDNごとの判別方法

## CloudFront
エッジのIPv4アドレスの逆引きレコードが **空港の3レターコード+数字2桁.r.cloudfront.net** という形式です。IPv6アドレスの逆引きレコードは存在しません。kix, itmなどは見たことがないので、日本のエッジはすべてnrtになり、国内での識別は枝番で行われるようです。
例
```server-***-***-***-***.nrt53.r.cloudfront.net```

## Cloudflare
Cloudflareはエッジロケーションの取得方法が公開されています。
利用しているドメインルート直下に `cdn-cgi/trace` をつけると、エッジの情報が表示されます。`colo=`の後ろに **空港の3レターコード** で表示されます。東京はnrt, 大阪はkixです。その他地域は[ステータスダッシュボード](https://www.cloudflarestatus.com/)から確認できます。
[Identify the Cloudflare data center serving your request](https://support.cloudflare.com/hc/en-us/articles/203118044-Gathering-information-to-troubleshoot-site-issues#h_22b01241-01a5-4bed-a897-6e97cff5c288)
他にHTTPレスポンスの`cf-ray`ヘッダからも確認できます。
例
```cf-ray: 54c27032db4ba5d6-NRT```

## CDNetworks
CDNetworksはHTTPレスポンスの`x-px`ヘッダに出力しているようです。**PSからはじまる文字列の末尾が3レターコード**です。複数入っている場合はオリジンに近いエッジでキャッシュしてから、下流のキャッシュに配信する設定になっていると思われます。おそらく左側がエッジ側、右側がオリジン側です。この機能はAkamaiやCloudFront（オリジンがEC2, S3の場合のみ）にも搭載されています。
例
```x-px: ms PSrbJP1am225HND,ms PSrbJP1cu59HND,ht PSxjpSIN4yt204SIN```
`via`ヘッダにはSIN, JPなど途中経路らしき文字列が見られますが、これが何を意味するのかはよくわかりません。
例
```via: 1.1 PSxjpSIN4yt204:0 (W), 1.1 PSrbJP1cu59:6 (W), 1.1 PSrbJP1am225:4 (W)```
余談ですが、www.cdnetworks.comの`x-hello-human`ヘッダには求人メッセージが入っています。気になる人は見てみましょう。


## Fastly
HTTPレスポンスの`x-served-by`ヘッダに出力します。**末尾が3レターコード**です。Fastlyは少し特殊で、各地域にエッジが複数ある場合、それぞれ別の名前が設定されます。例えば東京には3カ所エッジがありますが、それぞれHND, NRT, TYOという名前が割り当てられています。大阪は1カ所だけでITMです。東京に第4のエッジを作る場合どうするのか気になりますね。そのほかの地域は[ステータスダッシュボード](https://status.fastly.com/)から確認できます。
例
```x-served-by: cache-tyo19937-TYO```


## 確認方法がなさそうなCDN
- Akamai
- EdgeCast
- Google Cloud CDN, Google Cloud Storage

# IATAの空港3レターコード一覧
[Wikipedia](https://ja.wikipedia.org/wiki/Category:IATA%E7%A9%BA%E6%B8%AF%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E4%B8%80%E8%A6%A7)などを参照してください。
Swiftメモ：⚠️Initialization of immutable value 'xxxxxx' was never used;の意味

Xcodeでコードを書いていると表示される↓の:warning:

Initialization of immutable value 'xxxxxx' was never used; consider replacing with assignment to '_' or removing it

書き進めるといつの間にか消える時もあるのはなぜなのか？

調べてみると

「'xxxxxx'の変数・定数が使用されていないけど大丈夫？削除します？」

とお知らせしてくれているというもの。

コードを書き進めて変数・定数が使用されると表示されなくなるので
いつの間にか消えていると思ってしまっていました。

基盤系だとプログラミングの開発環境に触れる機会がないので
こういう心遣いに戸惑いつつもありがたい😭
GoでpexelsのAPIライブラリを作った

画像横断検索できるライブラリ作ろうと思ったけど、1日で作るの無理っぽかったのであきらめて、とりあえず1サービスだけAPIライブラリ作ったので公開します。

https://github.com/usk81/go-pixels

# 懺悔

Advent Calendarにあげ忘れておりました。
期間中プログラム大量生産してたので、記事書いてないことに気がついてませんでした

# What is pexels?

Pexelsは画像素材のシェアサービスです。
Getty ImageやUnsplashなんかみたいな感じのやつです。

Pexels選んだのはAPIがシンプルだったのと、他のサービスは試してはいないもののとりあえずGoのライブラリがありそうだったため。
あとそれなりの知名度。

# 使い方

Pexels公式のAPIはこちらです。
とてもシンプル（シンプルすぎて逆に分かりづらい）
https://www.pexels.com/ja-jp/api/documentation/

ライブラリはシンプルにAPIドキュメント丸写ししたような作りにしました。

``` go
// create new instance
s, _ := pixels.New(http.DefaultClient, "your pixels api key")

// Get a photo
result, err := s.GetPhoto(406014)

// Search photos
result, err := s.SearchPhotos(pixels.PhotoOptions{
		Query: "dog",
	})

// Get curated photos
result, err := s.CuratedPhotos(pixels.PhotoOptions{
		PerPage: 15,
		Page:    1,
	})

// Get a video
result, err := s.GetVideo(2035391)

// Search videos
result, err := s.SearchVideos(pixels.VideoOptions{
		Query: "cat",
	})

// Get popular videos
result, err := s.PopularVideos(pixels.VideoOptions{
		PerPage: 15,
		Page:    1,
	})
```

# ポイント

特に苦労したポイントも少なかったので、やってみてよかったポイントだけ取り上げてみます。

## クエリパラメータをStructで定義する

GoogleがStructからQuery stringを生成するパッケージを作っています。
https://github.com/google/go-querystring

今回作ったライブラリの該当箇所を例にするとこんな感じになります。

```go
// PhotoOptions is define that search photos API's query options
type PhotoOptions struct {
	Query   string `url:"query"`
	PerPage int    `url:"per_page"`
	Page    int    `url:"page"`
}

// ToQuery builds query string from PhotoOptions
func (po PhotoOptions) ToQuery() (q string, err error) {
	if po.PerPage == 0 {
		po.PerPage = minPerPage
	}
	if po.Page < 1 {
		po.Page = 1
	}
	v, err := query.Values(po)
	if err != nil {
		return
	}
	return v.Encode(), nil
}
```


種類が少ないときはこういう方法もありだと思いました。
APIが大量にある場合は定義が増えぎて死んでしまいそうです、

# あとがき

作り終わるまで、`Pexels`じゃなくて`Pixels`だと思ってました。
恥ずかしい...
ライブラリもgo-pixelsにしてしまったので、どっかのタイミングで直します
初学者によるプログラミングMemo　#14 Ruby計算〜別解〜

# はじめに
[前回の問題](https://qiita.com/Ikuy_h/items/2bc82fe6ac6e7af15588#comment-b23cb09caaca4f2adc32)の別解です
[scivoia](https://qiita.com/scivola)さんにdigitsメソッドを教えていただいたので記述します
なお、本記述はMacにおいて、Railsでの開発を前提としています
また、まだまだひよっこですので、不備等ございましたらご指摘いただけると幸いです

# 目次
- 別解
- 解説

# 別解
[前回の問題](https://qiita.com/Ikuy_h/items/2bc82fe6ac6e7af15588#comment-b23cb09caaca4f2adc32)をご覧になっていない方は先にご覧ください

```.rb
p "何桁でもいいから正の整数を入力してやー"
input = gets.to_i
item = []
item = input.digits

# sum = 0
# item.each{ |i| sum += i} sum使用が推奨なので修正しました
sum = item.sum

# mul = 1
# item.each{ |a| mul *= a} 教えていただいたinjectを使った方が簡潔に仕上がりました
mul = item.inject(1,:*)

num = sum + mul

p "足したんと掛けたん合わせたら#{num}やで"
```


## 解説
前回の投稿後"Integer#digits"というものを教えていただきました
"digits"メソッドは各桁の項目を取り出すことができるメソッドです
教えていただいてほんまに感謝です

まずは"digits"メソッドの簡単な使い方から行ってみましょう

```.rb
num = gets.to_i

x,y,z = num.digits

p "#{x},#{y},#{z}"

# 123を入力した結果
=> "3,2,1"
```
このような使い方ができます
また、気づいたかもしれませんが、1の位から順番に出力されています
今回に関しては計算順序を意識する必要がありませんが、順番が大切な場合は注意が必要です
さて、これを応用していきましょう
何桁の正の整数を入力されても対応できるようにしたいですね
しかしx,y,zなどの変数では何桁入力されるかわからない以上、使えません
そこで配列の出番です

```.rb
item = []
item = input.digits
```
まず空の配列"item"を作ります
そこに、digitsメソッドで取り出してきた値を全てぶち込みましょう
これで何桁入力されても各桁の数値を一つずつ取得することができました
あとは計算です
足し算は"sum"メソッドがあるので簡単ですが、掛け算は~~通常通り計算しなくてはいけません~~コメント欄に追加でご教示いただきました、元のは残しつつ、追加で記入します

```.rb
sum = 0
# item.each{ |i| sum += i} sum推奨ですので修正します
sum = item.sum
```
足し算はまず、計算結果を代入するための"sum"を用意します
初期値は足し算に影響がない"0"を入れておきます
そして、each文で配列"item"の中身をひたすら足していきます

```.rb
mul = 1
item.each{ |a| mul *= a}
```
掛け算も同様に、計算結果を代入するための"mul"を用意します
初期値は掛け算に影響がない"1"を入れておきます
そして、each文で配列"item"の中身をひたすら掛けていきます

### 掛け算の別解（追記）

```.rb
mul = item.inject(1,:*)
```
injectを教えていただきました
[解説ページ](https://docs.ruby-lang.org/ja/2.6.0/method/Enumerable/i/inject.html)にはこう書かれています

```
1.
# 自乗和を計算する。初期値をセットする必要がある。
p [2, 3, 4, 5].inject(0) {|result, item| result + item**2 }  #=> 54

2.
result = 0
[1, 2, 3, 4, 5].each {|v| result += v }
p result   # => 15

3.
p [1, 2, 3, 4, 5].inject(:+)                    #=> 15
p ["b", "c", "d"].inject("abbccddde", :squeeze) #=> "abcde"
```
1.だけで考えてみましたが、これだと

```
array = [2, 3, 4, 5]
p array.inject(1){|result, item| result * item}
```
までが今の私の頭では限界でした
2.は解説で書いているものです
そして今回教えていただいたのが3.でした
"(:+)"の部分を応用して"(:*)"とすることで掛け算に変更できました

初期値を設定してあげれば完了"(1, :*)"です

あとはそれを足し合わせるだけです


##### 参考記事
https://docs.ruby-lang.org/ja/2.6.0/method/Integer/i/digits.html
KaggleのKernel手法まとめ[画像編]

前回の記事はこちら
[KaggleのKernelまとめ[テーブル時系列データ編]](https://qiita.com/risako_/items/4c0f3baea58582b5a19c)

この記事では、私を含めてKaggleコンペにおいてデータ型ごとの定石みたいなものを知りたい！みたいな人のために書いていきます。また、コンペ関係なく精度が出ない時のヒントなどになれば良いなと思います。

![alt](https://media.giphy.com/media/5tonarDXufq3KbNs15/giphy.gif)


今回はコンペ限らず様々なKernelからみていきます。
画像の場合の可視化といったら、
- CNNの層ごとの可視化
- 画像の寄与率の可視化
- データセット画像自体の可視化(表示)

といった感じでしょうか？(もし何か他にあったらコメントで教えていただきたいです)
他のデータ型に比べて、幅が少ない印象なので、今回は手法に注目していきます。

## [Introduction to CNN Keras - 0.997 (top 6%)](https://www.kaggle.com/yassineghouzam/introduction-to-cnn-keras-0-997-top-6)

普通のCNN、モデルのアーキテクチャが絶妙らしい

## [EDA and LSTM-CNN](https://www.kaggle.com/artgor/eda-and-lstm-cnn)

LSTM-CNNを使っている

## [CNN Architectures : VGG, ResNet, Inception + TL](https://www.kaggle.com/shivamb/cnn-architectures-vgg-resnet-inception-tl)

 VGG16、VGG19、InceptionNet、Resnet、XceptionNetなどを使ってTransfer Learningを組み合わせている。

##[How to choose CNN Architecture MNIST](https://www.kaggle.com/cdeotte/how-to-choose-cnn-architecture-mnist)

いろんなアーキテクチャを試している


# まとめ

随時更新していきたいと思います。良いお年を！
![alt](https://media.giphy.com/media/Q7GFECYDnzJ0HJU2XE/giphy.gif)
Python フィボナッチ数列で知る メモ化再帰と動的計画法 

# はじめに
この記事はフィボナッチ数列の計算を通して計算の工夫の重要性を学んだためメモとして投稿します. 

# フィボナッチ数列とは?
An = An-1 + An-2 (A0 = A1 = 1)の式で表される数列です.

1 1 2 3 5 8 .... と自身の前の2項を足したものが項となる数列です.

# 実装(再帰, メモ化再帰, 動的計画法)
## まず, 再帰で実装
pythonにてフィボナッチ数列の任意の項を求める関数を実装しました. 

```python:fib.py
def fib(n):
    if n == 0 or n == 1:
        return 1

    return fib(n-1) + fib(n-2) 
```
この関数により, 任意のフィボナッチ数列の項が求められます.
しかし, この関数では計算量が大きいです. 
fib(5)を求めるためにはfib(4)とfib(3)を求めます.
fib(4)を求めるときはfib(3)とfib(2)を求めます.
この場合においてfib(3)は2回計算されます. 
このように再帰での実装では無駄な計算が生じてしまいます. 

## メモ化再帰での実装
メモ化再帰では通常の再帰に加えて, 計算した項の情報を保持します. 
今回はpythonの辞書型の構造を用います. 

```python:fib.py
class Fib_memo:
    def __init__(self):
        self.fib_memo = {}

    def cal_fib(self, n):
        if n == 0 or n == 1:
            self.fib_memo[n] = 1
            return 1

        #既に計算した項なら保存した情報を使う
        if n in self.fib_memo.keys():
            return self.fib_memo[n]
        
        self.fib_memo[n] = self.cal_fib(n-1) + self.cal_fib(n-2)
        return self.fib_memo[n]
```

既に計算した項を保存して置き, それを用いることで計算の無駄が省けています.

## 動的計画法での実装
動的計画法では, フィボナッチ数列の項を小さい方から計算することで
計算の無駄を省いています.

```python:fib.py
def fib_dynamic(n):
    # 結果を保持する辞書
    cal_result = {}

    # 初期値の設定
    cal_result[0] = 1
    cal_result[1] = 1

    if n == 0 or n == 1:
        return 1

    for i in range(2, n+1):
        cal_result[i] = cal_result[i-1] + cal_result[i-2]

    return cal_result[n]
```

# 検証
n = 1 ~ 15 で　3つの実装についての実行コスト(秒)を計算しました.
結果のグラフを以下に示します. 

![cal_time.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482108/32dd89e8-fc0f-cdab-ee51-ea2199053b80.png)

Normalが通常の再帰,  Memoがメモ化再帰,   Dynamic が 動的計画法 です. 
グラフより, n = 10 くらいから実行速度について大きな差が出てくることがわかります. 

# 結論
以上より, 簡単な工夫で実行速度が大きく異なることがわかりました.
普段は実行速度についてあまり意識することもなく, 重要性もわかりにくいです.
今回の結果から重い計算においては, データ構造とアルゴリズムの工夫が必須であると感じました.
digispark 互換品 セットアップ

# 初期情報
- 公式ページ
    - https://digistump.com/wiki/digispark/tutorials/digispark
    - https://digistump.com/wiki/digispark?redirect=1
- 回路図
    - https://s3.amazonaws.com/digispark/DigisparkSchematicFinal.pdf
- 購入したのはこれ
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/5a44f6cf-7ade-35a8-840a-16cc2fdf065a.png)
    - https://ae01.alicdn.com/kf/H145290597a30476a9c3f1897b434309cC.jpg
- ピンアウト図
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/df526cef-f098-e52b-db39-3fcb9d21ddd6.png)
    - https://hackster.imgix.net/uploads/attachments/883904/FS3Z3YNJUSNE16Y.png?auto=compress%2Cformat&w=900&h=675&fit=min

# arduino IDE 準備

- 参考
    - https://digistump.com/wiki/digispark/tutorials/connecting
- ボード URL
    - `http://digistump.com/package_digistump_index.json`
- ボードマネージャでDigistump AVR Boardsを探してインストール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/69528d2b-4dec-277c-d479-ad9a6a574fb1.png)

# Lチカ と fade
- https://qiita.com/keitasumiya/items/ac228139f524bc6c8b4f
- 私のボードは，LED=1でした。

# コンパイル，書き込み
- https://qiita.com/keitasumiya/items/ac228139f524bc6c8b4f
- 私のmacも，右のUSB端子の方が成功率が高いようでした。
- それなりの頻度で失敗する。気長に，「一度はずす」「書き込み指示」「arduinoが待機状態になったら接続」を繰り返すと良いようだ。

# Macとの通信

これ，一番試してみたかったこと。MacBook Pro 15 Mid 2014, Mojave 10.14.6

https://digistump.com/board/index.php?topic=199.0

- スケッチ例 - Digispark - DigispartUSB - Echo を書き込んでおく。

- 以下をterminalで実行。

```sh
brew install ruby libusb libusb-compat
sudo gem install digiusb
```
- 一度digisparkをはずしておき，terminalから`digiterm`を実行。digisparkを接続。terminalで文字をタイプ，[enter]すると，digisparkがそのまま返してくる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/978204a0-b065-97c8-15ac-d7d68e564694.png)

以下のページでは，`gem install digiusb` としていましたが，私の環境では`sudo`を付け加えないとダメでした。
http://shokai.org/blog/archives/8665

# （追記）Windowsマシンとの通信

- Windows 10 Home Bootcamp上ですがまあいいでしょう。
- 上記を書き込んだ digispark を準備
- 以下を一式 zip でダウンロード，展開
    - https://github.com/digistump/DigisparkExamplePrograms
- `展開した場所\DigisparkExamplePrograms-master\C++\DigiUSB Windows Driver`にある `InstallDriver.exe` を実行。
- digisparkを接続。
- `展開した場所\DigisparkExamplePrograms-master\Python\DigiUSB\windows` にある monitor.exe を実行。
- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/cf45bec7-2108-bc84-f130-05197ab62bf4.png)

うんすばらしい（自画自賛）諸先輩の皆様，ありがとうございました。
PyTorch1.3.1をCUDA9.0環境でDocker Buildする

PyTorch1.3.1はCUDA9.2や10.0のwheelが用意されているが、CUDA9.0環境が無い。
ので、自分でビルドしないといけない。そのときにちょっと苦戦したのでメモ。

[PyTorch1.3.1のコード](https://github.com/pytorch/pytorch/tree/v1.3.1)のコードをビルドしていく。
[docker/pytorch/Dockerfile](https://github.com/pytorch/pytorch/blob/v1.3.1/docker/pytorch/Dockerfile)があるのでまずこれをベースにする。

1行目をCUDA9.0のイメージにすれば良いと思ってたんだけど、どうやら28行目の`TORCH_CUDA_ARCH_LIST`も変えないといけないらしい。
`TORCH_CUDA_ARCH_LIST`で検索して、どうやらCUDA9.0のときは`TORCH_CUDA_ARCH_LIST="3.7+PTX;5.0;6.0;7.0"`を指定すればいいことに気づいたけど、何をヒントにそう思ったのかは忘れてしまった。

この２箇所を変えたDockerfileが↓のようになる。
`github checkout v1.3.1`したあとに`docker built .`すればいいはず。

```dockerfile
FROM nvidia/cuda:9.0-cudnn7-devel-ubuntu16.04
ARG PYTHON_VERSION=3.6
ARG WITH_TORCHVISION=1
RUN apt-get update && apt-get install -y --no-install-recommends \
         build-essential \
         cmake \
         git \
         curl \
         ca-certificates \
         libjpeg-dev \
         libpng-dev && \
     rm -rf /var/lib/apt/lists/*


RUN curl -o ~/miniconda.sh -O  https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh  && \
     chmod +x ~/miniconda.sh && \
     ~/miniconda.sh -b -p /opt/conda && \
     rm ~/miniconda.sh && \
     /opt/conda/bin/conda install -y python=$PYTHON_VERSION numpy pyyaml scipy ipython mkl mkl-include ninja cython typing && \
     /opt/conda/bin/conda install -y -c pytorch magma-cuda100 && \
     /opt/conda/bin/conda clean -ya
ENV PATH /opt/conda/bin:$PATH
# This must be done before pip so that requirements.txt is available
WORKDIR /opt/pytorch
COPY . .

RUN git submodule update --init --recursive
RUN TORCH_CUDA_ARCH_LIST="3.7+PTX;5.0;6.0;7.0" TORCH_NVCC_FLAGS="-Xfatbin -compress-all" \
    CMAKE_PREFIX_PATH="$(dirname $(which conda))/../" \
    pip install -v .

RUN if [ "$WITH_TORCHVISION" = "1" ] ; then git clone https://github.com/pytorch/vision.git && cd vision && pip install -v . ; else echo "building without torchvision" ; fi

WORKDIR /workspace
RUN chmod -R a+w .
```
【PHP】引数の初期値を設定した関数｜優先度（初期値 ＜ 引数）

web系エンジニアを目指し、MENTAを利用し、PHPを学習している初学者です。
日々学習していることの忘備録、モチベ維持、ちゃんとやってることの証明！で、投稿していきます。
#対象者
PHPを学びはじめた、初学者
#内容
関数で引数の初期値を設定した際の、値の扱い
#動作環境
PHP 7.1.32
##基本のおさらい
###関数・引数とは
```php5
$a = 1;
$b = 2;
$c = 3;
//仮定：組み合わせごとの和を求めたい
$ab = $a + $b;  //3
$ac = $a + $c;  //4
$bc = $b + $c;  //5

//関数にする
function sum($number1, $number2) {
    $sum = $number1 + $number2;
    return $sum;
}
関数：上記の4行
引数：関数に渡す/受け取る値（$number1, $number2)

//関数を使用する
$ab = sum($a, $b);  //3
$ac = sum($a, $c);  //4
$bc = sum($b, $c);  //5
```
ここまでは簡単！
#これが本題！
関数はとても便利（＝使いこなさなきゃダメ）で、メンターさんから、
「それ、関数にしてみましょう。」
「その処理は、関数にすればコードがスッキリしますよ。」
と指摘をもらい、どんどん関数化していきます。

今回書きたいのは、関数を量産する内に知った、
**引数の初期値を設定した関数を呼び出す**際、
**引数を渡さないと、初期値が代入**され、
**引数を渡すと、そちらが代入**される。
つまり優先度は**初期値 ＜ 引数**である。

文章だとわかりづらいですが、例を見れば簡単です！

```php5
//初期値を設定した関数
function sum($a=5, $b=10) {
    $sum = $a + $b;
    return $sum;
}

//呼び出し方で結果が変わる
$case1 = sum();      //15 (=5+10)
$case2 = sum(1, 2);  //3  (=1+2)
$case3 = sum(1);     //11 (=1+10)
```
**引数を渡さないと、初期値が代入**され・・
`$case1 = sum();      //15 (=5+10)`

**引数を渡すと、そちらが代入**される・・
`$case2 = sum(1, 2);  //3  (=1+2)`

おまけ：**引数を1つだけ指定した場合、（引数、初期値）で代入**される・・
`$case3 = sum(1);     //11 (=1+10)`

以上、簡単でしたね！

「・・・だから？」
「これ、何の役に立つの？」
そんな初学者の方向けに、実例を出して終了します。
#役に立った実例
「〜ゲームを作成せよ」
というような課題で、「すぐ終わったらつまらない」と思い、**「３ポイント先取」**として、作成開始。
勝利数を保持するのに詰まってしまった時に、メンターさんからアドバイスをもらいました。

```php5
//ゲーム関数
function game($victory = 0, $com_victory = 0) {
    //ゲーム実行
    //プレイヤーが勝利すれば、$victory++
    //COMが勝利すれば、$com_victory++
    //どちらかが「３」に達していたら、終了
    //達していなければ、再度ゲーム関数呼び出し（いわゆる、再帰関数！）
}
```
「ゲーム関数を呼び出すたびに`$victory,$com_victoryが0`になって、永遠にゲームをやめられないのでは:scream:」
「でもメンターさんがこんな間違えをするはずない・・」
と調べる内に、初期値の優先度を理解して納得。

```php5
//ゲーム関数を、最初に呼び出す場合
game();
//再帰関数として呼び出す場合
game($victory, $com_victory);
```
こうすることで、最初に呼び出す時は初期値（勝利数=0）が適用され、
再帰関数で呼び出す時は、それぞれの勝利数が引き継がれ、
「３ポイント先取」を実現出来ましたとさ。
ちゃんちゃん。
「あーなんかサービス作りてぇ！」と思ったあなたへ

# 「あーなんかサービス作りてぇ！」と思ったあなたへ
## サービス作りしたくなったら
- 自分のポートフォリオが欲しい！
- 学んだことをアウトプットしたい！

こういう時に「よし！自分でサービス作ってみるか！」って気分になると思います。
ただ、作ろう作ろうと思ってもなかなかうまく行かないもの。

## 結論:ますは、仲間を見つけよう
僕のおすすめですが、最初にやることは

**「一緒にサービスを作ってくれる仲間をみるけること！」**

これに尽きる気がします。

僕は今まで業務とは別で個人開発を何回かしてきましたが、圧倒的に二人以上で開発してる時の方がいいな〜と思ってます。（今も友人と一緒に作ってます。）

## 自己紹介
- エンジニア歴2年半
- 個人開発でサービスをいくつか作ってました。
- 8月に個人開発に関する勉強会の講師をやりました。
- https://supporterz-seminar.connpass.com/event/141834/

## みんなで開発すると、単純に楽しい！
この記事で言いたいことの9割はこれで終わりです。
僕の場合は、一人で黙々とやっていても、どっかで飽きます。
そんな時に一緒にやってる人がいると、単純に一緒にわいわい開発できるから楽しいし、機能ができたりリリースできたタイミングで毎回喜びを共有できます。
あとはやっぱり、会社帰りとか土日とかに一人で開発しようと思ってもついついサボってしまうので、みんなでスケジュールを切ってやった方がちゃんとリリースまで行きました。

## サービスやコードのレベルが上がる
モチベだけでなく、アウトプットとしてレベルが上がると思います。
コードに関しては、二人いればお互いにコードレビューできるので、自分しか読めないクソコードを書かなくなります。
また、自分の書いたコードを相手に説明する時に、「意外とここ理解できてなかったな」とか気付けたりします。

サービスに関しても同様です。UIに関することなんかも二人で議論できるので、一人の偏った意見ではなく、ちゃんとしたデザインになります。

## 役割分担できたらなおよし
これはできたらいいな、ってくらいですが、二人でやる場合は役割がしっかりしてると効果が上がるなと思います。
僕の場合は、僕がインフラとバックエンドを担当して、もう一人はデザインとフロントをやっていました。
こうするとそれぞれが責任持って自分の担当にコミットできます。


## 結論：仲間を見つけよう！
個人開発したくなった皆さん。
会社の先輩、同期、後輩、インターン、勉強会であった人、大学の友達、誰かしら、一緒にやる人を見つけたらいいな！と思います。
僕の感覚的には「漠然とサービス作りたいなと思ってるけど、行動に移してはない人」は結構多い気がするので、「一緒に作ってみない？」って言ったら意外と「やるか！」ってなる気がします。
ぜひ仲間を見つけて、楽しくサービス作りしましょう！

## 最後に
僕は6月~8月に「みんなの通信簿」というサービスをエンジニアの友人と作ったのですが、その友人とは今一緒に起業しています。
「みんなの通信簿」自体はもう全然動いていませんが、このサービスのおかげで起業仲間ができたので、本当にやってよかったです。
個人開発で意気投合して、そのままもっと一緒にやろう！ってケースはそこそこ多い気がします。
この記事を読んでる皆さんも、個人開発がきっかけで、今後の人生に大きく関わるような素敵な出会いがあるかもしれません
React コンポーネントの仕組みを掴む！！(create-react-appを使用して爆速Hello World表示)

## 概要
初めてReactを触ってみて、コンポーネントの仕組みを掴むまでに時間が掛かったため、
流れを備忘録として残します。
create-react-appパッケージを利用するため、環境構築は必要ありません。

※細かい設定をされる方は環境構築からご自身でやられるのが良いかと思われます！:rolling_eyes:

## 流れ
1.コンポーネントとは
2.Node.jsインストール
3.アプリ作成
4.コード

## 1.コンポーネントとは
コンポーネントとは、部品、パーツのことを指します。
Reactでは機能ごとにコンポーネント化し、以下参考画像の様に、複数のコンポーネントを組み合わせ見た目を作っています。

[![Image from Gyazo](https://i.gyazo.com/bdbeda633fad89d6a072075a4e93e500.png)](https://gyazo.com/bdbeda633fad89d6a072075a4e93e500)

コンポーネントを表示させるには、
作成したコンポーネントをApp.jsで呼び出し、index.jsでJSX形式をHTML形式にすることで、表示が可能になるという仕組みです！！
※Todo.jsは作成したコンポーネントの例です！
[![Image from Gyazo](https://i.gyazo.com/aa462be62b519e70276be5963a1d3d79.png)](https://gyazo.com/aa462be62b519e70276be5963a1d3d79)




## 2. Node.jsインストール
以下リンクからインストールが良いかと思われます
https://nodejs.org/ja/
元々はサーバサイドJavaScriptで使用されていたみたいですが、現在はフロントエンドでも使用されているとのことです。

## 3.アプリの作成
```
npx create-react-app '任意のアプリ名'
cd '任意のアプリ名'
npm start
```

公式より
>Create React App は React を学習するのに快適な環境であり、React で新しいシングルページアプリケーションを作成するのに最も良い方法です。

上のコマンド実行にて以下の様な画面が立ち上がればOKです！
[![Image from Gyazo](https://i.gyazo.com/a7314c18258e2fc89522a0baaa35098b.png)](https://gyazo.com/a7314c18258e2fc89522a0baaa35098b)


## 4. コード
次に作成したアプリを開き、src以下にjsのファイルを作成します。
※今回は、Todo.jsとします

```js:Todo.js

import React, { Component } from 'react'; ①Reactをインポートする

class Todo extends Component {　②class名がcomponentの名前
  render(){
    return(
      <div className = "title">　③
        Hello World
      </div>
    );
  }
}
export default Todo; ④コンポネートをexportする
```
**①作成したjsファイルでreactを使用します！という宣言をします**
**②class名がコンポーネント名になり、このクラスそのものがコンポーネントされます。**
**③return内はJSXで記載します。JSX内ではclassを`className`とします！**
**④この記述によりコンポネートをexportし、`App.js`にimportできる様にします**

```js:App.js
import React from 'react';
import Todo from './Todo';　①コンポーネントをインポート

function App() {
  return (
    < Todo/> ②JSX内にコンポネート記載
  );
}

export default App;

```
**①作成したコンポーネントをimportします**
  **　※`import コンポーネント名 from './ファイル名'`**
**②JSX内に`<コンポーネント名/>`と書きます**

以上で、Hello Worldが表示されたはずです！



## 最後に
コンポーネントの説明メインになってしまったので、アプリ実装できたらまた記事にしたいと思います！

## 参考
https://ja.reactjs.org/
https://webkikaku.co.jp/blog/javascript/react-start/
Docker 関連 備忘録

## Dockerを使用している時に、あれどうやるんだっけ？と忘れることが多いので、忘備録として記録しておきます。

## Dockerイメージを探す  
```shell
$ docker search {イメージ名}
## ubuntuを探す場合
docker search ubuntu:latest
```
## Dockerイメージを取得する  
```shell
$ docker pull {イメージ名}
```
## 稼働中のコンテナイメージを確認する
```shell
$ docker ps
```
## (停止中のものも含め)稼働中のDockerイメージを確認する
```shell
$ docker ps -a
```

## Dockerのログを表示する
```shell
$ docker logs {コンテナID}
# -f をつけると、リアルタイムでログが追加されていく様子がわかる(tail -fと同じ)
$ docker logs -f {コンテナID}
```

## Dockerコンテナを削除する
```shell
$ docker rm {コンテナID}
```

## Dockerプロセスにログインする  
```shell
$ docker exec -it {コンテナID} /bin/bash
```

## Dockerプロセスに(rootで)ログインする  
```shell
$ docker exec -it --user root {コンテナ名} /bin/bash
```

## Docker起動して、必要なものを実行して削除(ps -aにも残らない)
```shell
$ docker run -rm {コンテナ名} {コマンド} 
```
実行した後、いちいち削除しなくてよいので、意外と便利

## ローカルのディレクトリをdocker imageから参照できるようにする(-vオプション)。さらにカレントディレクトリをそのディレクトリにする(-wオプション)
```shell
$ docker run -rm -v {ローカルディレクトリへのパス}:{docker内でのパス〜例えば/mytest} -w {docker内でのパス〜例えば/mytest} {コンテナ名} {コマンド}
```

## docker imageにインストールなど実行した後、コンテナをイメージに反映する。
```shell
$ docker commit {コンテナID} {コンテナ名}
```

## VScodeから remote container拡張機能を利用して、リモートマシンのdockerコンテナに接続する(ローカルマシンとリモートマシンは別ノード)
今回はローカルがMacOS(mojave)、リモートがUbuntu18.04
### ステップ0
vscodeに、remote container追加
### ステップ1
.settings.jsonに以下を追記する

```shell
 "docker.host": "ssh://user_id@www.xxx.yyy.zzz"
```
これでremote os上のdockerのイメージもしくはプロセスに接続できる。
リモート一覧には、dockerコンテナが表示されるようになる。
vscodeからattachしにいくと、vscode-serverがインストールされる模様。
しかし、これではコンテナ上でvscodeの初期設定をしなくてはならない。
extensionやら、launch.jsonやらなにやら、、、
そもそもリモートマシン上でコンテナを起動しなくてはならない。
他にもdocker内でgit使えるようにするためにsshのconfigとか置くのが面倒くさい。

### ステップ2(途中)
やっぱり、VScodeから直接image作成したり、ステップ1で上記のことをしないで住むようにしたい。
vscodeの以下のディレクトリ(.vscodeディレクトリと同等の場所)
.devcontainerに、以下のファイルを配置して、
devcontainer.json
Dockerfile
vscodeから直接imageの作成、必要なvscodeのextensionのインストール設定ができる模様。
軽く設定してみて実行してみたところ、リモートのディレクトリとローカルのディレクトリがマウントできないといったあたりでエラー、それ以上進まず。
アイディアに困ったらCodePen!!

こんにちは
日々、UIについて勉強しています！そんな私が今回紹介したいのは **CodePen** です。
もしかしたら他の記事にもあるかもしれませんが使いやすかったので紹介させてください。


#CodePen
CodePenとは、Webブラウザ上でHTML/CSS/Javascriptのコーディングができるサービスです。
 **世界中のプログラマーがこんなのいいよ！** と投稿しています。
![codepen-ec.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509309/9cc4ad9c-2541-7086-409c-c2adffe2279d.png)

![codepen2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509309/b82f4094-3e0a-2f57-27a2-3cf092c1fa23.png)


　　　
　　　

　　　
#特徴として

* 沢山のアイディアを参考にできる
* 既存のコードをその場で編集、反映してくれる
* 自分の作品を公開することができる
　　
　　　　　
　　　　
　　　　

変更を加えるとすぐにプレビューが更新されて反映されるので、リアルタイムでデザインを確認しながらコーディングできます。
実際私も作ってみました ネオンVer.のQiitaロゴです↓↓
![スクリーンショット 2019-12-28 17.29.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509309/2aafadbb-4e88-ff69-11bc-59750842d7ff.png)



CodePen公式↓
https://codepen.io/

ネオンロゴ↓
https://codepen.io/takaharatoru/pen/LYEjyMw


皆さん興味は湧きましたか？
このサイトを観ると、 **html、cssでこんなことまでできるのと感じる** と思います！！
今回紹介仕切れていないくらいCodePenにはまだまだ機能があります。
ナビゲーションやボタンのデザイン、スライダー、他にも様々なアイディアが紹介されていますので皆さん是非使用してみてください！！