OmniAICreator/Qiita-1.07M huggingface dataset:
SARIMAモデル（季節自己回帰和分移動平均モデル）による未来予測において生じる問題への対処法

自分で記事を書くということをしたことがなかったのですが、今回詰まってしまった所が検索してもなかなか解決しなかったので、知恵として残しておこうと思います。

問題があったのは時系列分析で用いられるSARIMAモデルを使った予測においてです。（あくまで詰まってしまった部分の解説なので、具体的なSARIMAモデルの使い方の勉強は別の場所でお願いします）




次のような形で所与の時系列データに対してSARIMAモデルを適応させます。

```python:qiita.rb
SARIMA_2_1_3_011 = sm.tsa.SARIMAX(train.y, order=(2,1,3), seasonal_order=(0,1,1,20)).fit()
```
このモデルを用いて次のように未来予測を行おうとしました。
（つまり169から206のindexは元データの範囲を超えていて、それを予測したかった）

```python:qiita.rb
pred3 = SARIMA_2_1_3_011.predict(start=169,end=206)

KeyError: 'The `start` argument could not be matched to a location related to the index of the data.'

```
するとこのようなエラーが生じてしまいました。
英語ができないのでなんとなくでしか意味を察せないため、よく分からないけどindexの範囲が越えているのが問題のようでした。
しかし、参考にしたサイトでは何の問題もなく未来予測ができていました。


そこから色々と手を加えたりエラーをコピペして海外の質問サイトに飛んで調べたりしたのですが、かれこれ３０分以上は苦戦した気がします。


で、結果的に辿り着いた予想は「元データにおけるindexである日付の現れ方が不規則なため、未来予測するためのindexが決められないということではないか」というものです。
（例えば元データのindexが1/1,1/2,1/3なら次の予測は1/4,1/5...と続くが、1/1,1/2,1/4となっていると次のindex（日付)が決まらない）

したがってこの問題の解決策は次の２つが挙げられると思います。

①なんとかしてindexの規則性を整える
②元データに空のデータ（ただしindex付）を結合して、未来のindexを用意しておく（もちろん目的変数は空のまま）

実際に２つ目の方法を行うとうまくいったので、恐らくこれらが解決法としては正しいと思います。




初めて記事を書くので見にくかったかもしれませんが、ご了承ください...。
また、力不足で至らない点も多々あると思いますが、お気づきの方はご指摘してくださると嬉しいです。
少しでもこの問題で立ち往生している方の助けになれば幸いです。
pandasで動的に新たなデータフレームを作る

pandasでどうしても、for文を回して一行ずつデータを加工しながら、
insertしたいということがある気がします。

（globで別々のテキストファイルから持ってくるときは不可避。他にもあるはず。自分の場合は、考えるのが面倒で、この方法を取る方がある気がします、それは良くないすね、、）

まぁということで、そういうときのやり方。

```python
# まずcolumnだけのdfを用意
df = pd.DataFrame( columns=['A','B'] )

# 行を作る
for i in range(10000):
    tmp_se = pd.Series( [ i, i**2 ], index=df.columns )

    # dfに行をレコードとして追加
    df = df.append( tmp_se, ignore_index=True )
```

だと思ってたのですが遅い・・。
以下の方が高速

```python
# 空の辞書
series_dict = {}

# 行を作る
for i in range(10000):
    tmp_se = pd.Series( [ i, i**2 ], index=['A','B'] )
    series_dict[i] = tmp_se #辞書に追加
   
df = pd.DataFrame.from_dict(series_dict, orient="index")


```
VBAでSingleton（シングルトン）パターン

# はじめに
VBAでクラスモジュールを作ることが少ないからか資料があまり見つからなかったので、勉強がてらデザインパターンを無理やりVBAに適用してみました。 
デザインパターンを利用するには制約の多いVBAですが、少しでも綺麗なコードになるよう積極的に取り入れていこうと思います。

<!-- textlint-disable -->

# Singleton（シングルトン）パターンとは
>
■Singleton（シングルトン）パターン
あるクラスのインスタンスが、プログラム内に1つしかないことを保証したいケースがあります。それを実現するために、全てのメンバーに「インスタンスを生成するなよ！」と注意をうながし、厳密にレビューをするということはあまり現実的ではないですよね。そんなとき、効果があるのがSingletonパターンです。  
[5分で分かるJavaデザインパターン](https://geechs-magazine.com/tag/tech/20160304)

<!-- textlint-enable -->

ということで、サンプルで記載されていた以下のクラスを自分なりにVBAに置き換えてみました。

## Javaサンプルコード
```Java
public class Moon{
    private static Moon moon = new Moon();
    private Moon(){}
    public static Moon getInstance(){
        return moon;
    }
}
```
## VBA適用例
```VB:FSO_Class.cls
Private cFSO As Object
Private Sub Class_Initialize()
    Set cFSO = CreateObject("Scripting.FileSystemObject")
End Sub
Private Sub Class_Terminate()
    Set cFSO = Nothing
End Sub
Public Property Get GetFSO() As Object
    Set GetFSO = cFSO
End Property


Public Function Sample(ByVal url As String) As String
    With New FSO_Class
        Sample = .GetFSO.GetAbsolutePathName(url)
    End With
End Function
```
上のサンプルではあまりメリットが感じられないような…
Dictionaryとかで利用すると恩恵がありそうですが、
もはや他のパターンになっていきそうなのでこのくらいにしておきます。
# まとめ
VBAで適用するとコードがちょっとスッキリします。
ただ、適用するインスタンスは考えないと変数への格納だけでいいじゃん…となってしましそうです。
ぼんやりとIEの操作や外部ブックの呼び出しとかで適用すると良さそうな感じがしました。

# 最後に
独学で基礎すっ飛ばしてプログラミングしているため、間違いや勘違いしているかもしれませんが、温かい目で見ていただけると幸いです。
そのときは、コメントでご指摘いただければ修正しますので、
ご支援よろしくお願いします。
AWS SageMaker Studioに含まれる個別機能を一通り触ってみた

# 概要
以下を一通り触ってみた。クラスメソッドさんの解説サイトを読みながら、[AWS labs](https://github.com/awslabs/amazon-sagemaker-examples)のサンプルを写経しました。
 * [Autopilot](https://dev.classmethod.jp/cloud/aws/try-amazon-sagemaker-autopilot/)
 * [Experiments](https://dev.classmethod.jp/cloud/aws/yoshim-amazon-sagemaker-experiments/)
 * [Model Monitoring](https://dev.classmethod.jp/cloud/aws/yoshim-amazon-sagemaker-model-monitor/)
 * [SageMaker Debugger](https://dev.classmethod.jp/cloud/aws/yoshim-amazon-sagemaker-debugger-example/)

※Studioからの見え方ではありません。

# Autopilot
 * XGBoostなどのアルゴリズムやハイパーパラメータを様々試してくれる
   * 実行するとSageMakerのジョブが250個走りました
     * なんだかんだでXGBoostが選ばれることが多い
   * データサイエンティストが要らなくなる、とまでは言えないまでもかなりの作業が楽になると思います
 * 電話によるマーケティングで定期預金を契約するユースケース
   * 
[Direct Marketing with Amazon SageMaker Autopilot](https://github.com/awslabs/amazon-sagemaker-examples/blob/master/autopilot/sagemaker_autopilot_direct_marketing.ipynb)

# Experiments
 * 機械学習は言うまでもなく、様々な学習を試行錯誤します
 　 * 学習結果をタンキングし、後々比較検証できるようにします
 　 * Autopilotは比較検証まで自動でやってくれるものだとすると、比較検証の部分を目検するイメージ
 * MNISTの手書き文字を判別するユースケース
   * [
MNIST Handwritten Digits Classification Experiment](https://github.com/awslabs/amazon-sagemaker-examples/blob/master/sagemaker-experiments/mnist-handwritten-digits-classification-experiment.ipynb) 

# Model Monitoring
 * 高精度が得られた学習モデルも時間変化などにより劣化する場合があります
   * 推論時に学習モデルの精度の劣化をモニタリングしてくれます
   * システム開発でもCI/CDにより品質デグレードを日々確認しますが、機械学習でも同様のことが必要なイメージ
 * 学習済みモデルに対して推論をかけてモニタリングするユースケース
   * [Monitor a live endpoint for violations against constraints](https://github.com/awslabs/amazon-sagemaker-examples/blob/master/sagemaker_model_monitor/introduction/SageMaker-ModelMonitoring.ipynb)

# Debugger
 * 化学の実験のように機械学習の学習時間は非常に長く、結果が出ないこともしばしば
   * 途中経過がどのような状態かは確認したいものです
   * 勾配やロスなどの状態を取得し、その内容に応じた分析が可能になります
 * MNISTのデータセットに対する学習中に勾配消失やロスが減らない状態を監視するケース
   * [Amazon SageMaker Debugger - Using built-in rule](https://github.com/awslabs/amazon-sagemaker-examples/blob/master/sagemaker-debugger/tensorflow_builtin_rule/tf-mnist-builtin-rule.ipynb)
 
# まとめ
今回紹介した機能を統合したSageMaker Studioを使えばさらに簡単に使えるようになること間違いなしです。AutopilotをSageMaker Studioで使ってみたりもしましたが、より簡易に使えるようになるなという印象でした。
[JavaScript] スプレッド構文

<p class="codepen" data-height="1080" data-theme-id="light" data-default-tab="result" data-user="mykysyk" data-slug-hash="XWbXrYb" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="リストにリストの追加">
  <span>See the Pen <a href="https://codepen.io/mykysyk/pen/XWbXrYb">
  リストにリストの追加</a> by mykysyk (<a href="https://codepen.io/mykysyk">@mykysyk</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
爆速でelmを始めるリンク集

最近フロントエンドを調べているとelm言語を聞くことが多いと思います。
ですが、新しい言語に挑戦して見るのは結構大変だと思います。

そこで、学習のレベル別に参考となるリンクを用意してみました。

elmは協力な型システムと小さな仕様によって、サンプルを真似てたらいつの間にか完成してるような言語です。

だから以下のリンクを参考にたくさんコピペすると上達も早いと思います。
皆さんの学習の手助けになれば幸いです。

# まず試してみる
https://elm-lang.org/try
こちらは公式のブラウザからElmを体験できるSandboxです。
適当に数字とかいじってみるといいかもしれません。

# チュートリアルを見てみる
https://guide.elm-lang.jp/
こちらは公式日本語チュートリアルです。

適当にコピペするのもいいですし、写経してみるのも学習になります。
パターンマッチあたりまでは理解しやすいので、そこまで読み進めてみるといいと思います。

様々な点でJavaScriptと異なるため慣れない点もあると思いますが、その一つ一つにも理由があるので、とりあえず次に進んでいくとスムーズに進みます。

ただ、型の恩恵やキーワード補完の恩恵を受けるためにローカルで作業するとまた違った感触になると思います。環境構築に関しては次で説明します。


# 環境構築
https://marketplace.visualstudio.com/items?itemName=Elmtooling.elm-ls-vscode

チュートリアルで読んだ内容を実践してみましょう。
通常はローカルでテキストエディタを用いてソースコードを編集すると思います。

おすすめのエディタはVSCodeです。上記の拡張機能の説明の従って環境構築を行うと、簡単に快適な環境を作成できます。

# 書籍で詳しく知る
https://www.amazon.co.jp/dp/B07P253FPG/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

チュートリアルだけじゃわからない箇所がある、もっとElmを知りたくなったら書籍を読んでみましょう。
こちらは昨年出た本ですが、Elmの最新版に対応しており、
この本を読むだけでElmに必要な知識がまんべんなく身に付きます。

# SPAを作ってみる
https://www.elm-spa.dev/

Elmのデフォルトの機能だけでもSPA(アプリ内で複数ページを持つもの)は作成できますが、個人的には冗長な記述が多くて面倒です。代わりにフレームワークを使ってみてはどうでしょうか。

こちらは最近話題になっているSPA構築用のフレームワークです。
冗長な記述を減らしてより直感的にSPAを構築することができます。


# Awesome Elm
https://github.com/sporto/awesome-elm/

もっとElmを知りたい場合は、こちらのリポジトリを見てはどうでしょうか
Awesome ~~というgithubのリポジトリは、大抵関連する優良なコンテンツを集めたリンク集になっています。

# 最後に
もっとElmユーザーが増えて、フロントエンドでStateを大事にする文化が栄えますように！！
勉強メモ

### SOLIDの原則
- **S**: `SPR` 単一責任の原則 -> 責任は1つにすること。
- **O**: `OCP` 開放閉鎖の原則 -> クラスの種類を拡張しても修正がないように。
- **L**: `LSP` リスコフの原則 -> サブクラスはスパークラスで代用できること。
- **I**: `ISP` インタフェースの原則 -> 粒度を考えろ。使用しない関数を無理にimplementしないこと。
- **D**: `DIP` 依存性逆転の原則 -> 高水準は低水準に、抽象は詳細に依存してはならない。

[開発者が知っておくべきSOLIDの原則 | POSTD](https://postd.cc/solid-principles-every-developer-should-know/)
docstring

```python:docstring.py
def say_dic(word, *args, **kwargs):
    """
    test
    :param word:
    :param args:
    :param kwargs:
    :return: nothing
    """
    print(word)
    print(args)
    print(kwargs)
    for k, v in kwargs.items():
        print(k,v)

print(say_dic.__doc__)
print(help(say_dic))
```

```
test
    :param word:
    :param args:
    :param kwargs:
    :return: nothing
    
Help on function say_dic in module __main__:

say_dic(word, *args, **kwargs)
    test
    :param word:
    :param args:
    :param kwargs:
    :return: nothing

None
```
キーワード引数の辞書化

```python:kwargs.py
#argsとkwargsを併用する場合は、順番に注意
def say_dic(word, *args, **kwargs):
    print(word)
    print(args)
    print(kwargs)
    for k, v in kwargs.items():
        print(k,v)

say_dic('hello', 'Mike',1,  desert='banana', drink='beer')

t = {'math':15, 'science':100}
#辞書を渡す場合は、**をつけて渡す
say_dic('hi', 'Nancy', 2, **t)
```
出力結果：

```
hello
('Mike', 1)
{'desert': 'banana', 'drink': 'beer'}
desert banana
drink beer
hi
('Nancy', 2)
{'math': 15, 'science': 100}
math 15
science 100
```
Rubyで固定長ファイルを楽しく扱う

# はじめに
ホストコンピュータ（死語？）から吐き出されたような超長い固定長ファイルが好物です。嘘です。
１行が数百バイト以上（２５００バイトとかのファイルあるからね！）、数十から数百項目のExcelの定義書をもらったら時に、私がいつもやっているやり方です。

# 準備
固定長ファイルなので、定義書は神Excelです！
まずはExcelからキーと１カラムの長さの列を取得して、ペアを作ります。

```ruby:column_def.rb
Column_def =%w[
any_id 10
any_field1 2
cyclic_1 4
cyclic_2 4
cyclic_3 4
]
# キーと列長のペア
Columns = Hash[*Column_def]
# => {"any_id"=>"10","any_field1"=>"2","cyclic_1"=>"4","cyclic_2"=>"4","cyclic_3"=>"4"}

# 一行のサンプル
input_sample = "0123456789xx12345678abcd"

```

# 分解

```ruby:column_def.rb

# unpackが有能なのでunpackのパターンを作る
column_def = Columns.values.map{|c| "a#{c}"}.join
#=> "a10a2a4a4a4"

arr = input_sample.unpack(column_def)
#=> ["0123456789", "xx", "1234", "5678", "abcd"]

```
この通り綺麗に分解してくれます。String#unpack有能。

# 構築

```ruby:column_def.rb

# Columnを再利用して、さらに扱いやすく
any_item = Hash[Columns.keys.zip(arr)]
#=> {"any_id"=>"0123456789","any_field1"=>"xx", "cyclic_1"=>"1234", "cyclic_2"=>"5678", "cyclic_3"=>"abcd"}

```
zipした２重配列を連想配列にしてくれるHash有能。
これならjsonや欲しい形に変換して使いやすい。ですよね？

```ruby:column_def.rb
require "json"

any_item.to_json
#=> "{\"any_id\":\"0123456789\",\"any_field1\":\"xx\",\"cyclic_1\":\"1234\",\"cyclic_2\":\"5678\",\"cyclic_3\":\"abcd\"}"

```

# まとめ
このやり方でいろんな固定長ファイルをサクッと片付けてください。（もっといいやり方、教えて・・・）
CSVでも連想配列にするところは使えますよ。(CSVのクラスはよく使い方忘れるので、ただのArray、Hashが好き)
固定長ファイルは正規化されていないことが多いから、group_byも有能である事はまた今度書こうかな。
Ruby有能。String#unpack有能。Hash有能。
・・・本当はPythonで同じことをやりたい・・・けどRuby以外書けないのです。
【備忘録】vagrantでssh.configを作成して、scpコマンドでローカルからファイルを転送する

接続設定ファイル`vagrant ssh-config`を`ssh.config`に吐き出す

```
% vagrant ssh-config > ssh.config
```

`ssh.config`を元にscpコマンドを実行する

```
% sudo scp -F ssh.config [送信したいファイル] vagrant@default:[送信先のパス]
```

例）

```
% sudo scp -F ssh.config /Users/username/Desktop/index.html vagrant@default:/var/www/html
```

送信完了。
args

```python:args.py
#位置引数のタプル化（可変個の引数取れる）
def say_something(word, *args):
    print('word=', word)
    print(args)
    for arg in args:
        print(arg)

say_something('I', 'like', 'sushi')
```
出力結果：2番目以降の引数はargsに格納される

```
word= I
('like', 'sushi')
like
sushi
```
Eloquentのクエリからのコレクションがヤバい便利！

# はじめに
laravel使ってて、Eloquentのクエリからのコレクションの使い勝手がヤバかったので（こういうのに慣れてる人にとっては当たり前かもしれませんが）、とりあえずメモを残します。

# 例
例えば車モデルを使って車一覧に利用可能なフラグを追加したい時、条件がカオスすぎてクエリ作るのを諦めてしまったとします。
１クエリだけで頑張ろうとすると大変ですが、クエリ＆コレクションだとこんなにすっきり書ける！？

```php:コントローラ
class HogeController extends Controller
{
   /**
     * 公開中の車をJSONで取得
     */
    public function getCarList(Request $request){
        $from_at = $request->get('from_at');
        $to_at = $request->get('to_at');

        // 利用可能な車のコレクションを取得
        $available_cars = Car::getAvailableCars($from_at, $to_at);

        // 車リストに利用可能フラグを追加して車種別にグルーピングしてjsonで返す
        $cars = Car::query()
            ->where('is_publish', '=', 1)
            ->get()
            ->map(
                function ($row) use($available_cars){
                    $row['is_available'] = $available_cars->find($row['id']) ? 1 : 0;
                    return $row;
                }
            )->groupBy('type_id');
        return response()->json($cars);
    }
}
```

```php:モデル
class Car extends Model
{
   /**
     * 利用可能な車を取得
     */
    public static function getAvailableCars($from_at, $to_at)
    {
        return Car::query()->whereNotIn('id',
            function ($query) use ($from_at, $to_at) {
                $query->select('car_id')
                    ->from('reservations')
                    ->whereRaw("見るのも嫌な条件..",[$from_at, $to_at])
                    ->whereNull('cancel_at');
            })->where('is_publish', '=', 1)->get();
    }
}
```

この程度ならクエリだけでいけるだって！？
でもこういう方法が役に立つ場面に今後絶対出くわすはず！

# おわりに
やっぱりDoctrineよりEloquentが好き
位置引数、キーワード引数、デフォルト引数

```python:argument.py
#desertのデフォルト引数はorange
def menu(drink, food, desert = 'orange'):
    print('drink:', drink)
    print('food:',food)
    print('desert:', desert)

#キーワード引数による関数呼び出し（desertは何も指定していないのでデフォルト引数が渡される）
menu(food ='egg', drink = 'beer')
```
出力結果：

```
drink: beer
food: egg
desert: orange
```
vagrantとロードバランサーについて簡単に学習したのでその記録

# 用語
- **オンプレミス**：自社で物理サーバや通信回路、その他サービスを保有し運用すること
- **クラウド**：インターネット経由でサーバを利用することができるサービス。物理的にサーバを設置する必要がなく、定額な初期コストから開始が可能。
- **DNSサーバ**：ドメインとIPアドレスとを紐づけるもの。紐付け＋変換の処理を「名前解決」という。
- **HTTPS**：SSL暗号化通信を行うため、HTTPよりセキュアに通信をすることが可能。
- **ロードバランサー（負荷分散装置）**：サーバにかかる負荷を、平等に振り分けるための装置のこと。ロード(負荷)＋バランサー(平衡を保つためのもの)

# ロードバランサーについて
## 速度低下を防ぐ
ロードバランサー（負荷分散装置）とは、サーバにかかる負荷を、平等に振り分けるための装置のこと。ロード(負荷)＋バランサー(平衡を保つためのもの)。

これを利用することで、処理件数が増加してサーバのリソース(CPUやメモリなど)を奪い合うことが軽減される。つまり、サーバに負荷がかかることを防ぐことができる。

実際のサーバの台数を増やすことを**スケールアウト**、サーバの性能を上げることを**スケールアップ**という。

## ダウンしたサーバを回避できる
ロードバランサーの仕組みは、サーバを複数台で構成しているため、1台故障しても他のサーバに自動切り替えすることで、継続的にサービスを提供できる。

## サーバのメンテナンスも停止せずに可能
サービスを停止せずに、サーバのメンテナンスを行うことができる。これは、ロードバランサーの設定を、メンテナンス中のサーバに振り分けないようにすることで実現可能。

## 特定のユーザのアクセスを同一サーバに集約する
これによって、Webアプリケーションのトランザクション(決済など)の整合性を維持することができる。これを**パーシステンス**という。

# AWSのサービス
- [Route53](https://aws.amazon.com/jp/route53/)：DNSにあたる。ドメインの取得やDNSレコードの設定を行う。
- [EC2](https://aws.amazon.com/jp/ec2/)：アプリケーションを動かすWebサーバにあたる。ストレージやスペックを自由に選択可能。
- [RDS](https://aws.amazon.com/jp/rds/)：データベース。ストレージやスペックを自由に選択可能。
- [ELB/ALB](https://aws.amazon.com/jp/elasticloadbalancing/)：ロードバランサーにあたる。

# Vagrantの基本操作
vagrantのバージョン確認

```
% vagrant -v
Vagrant 2.2.7
```

boxファイルのインストール

```
% vagrant box add [Boxファイルの名前(任意の文字列)] [インストールしたいBoxのURL]
```

インストールしたBoxファイルの確認

```
% vagrant box list
[Boxファイルの名前(任意の文字列)が表示される]
```
Vagrantの初期化（Vagrantファイルが作成される）

```
% vagrant init [Boxファイルの名前(任意の文字列)]
```

vagrantの実行

```
% vagrant up
```

vagrantへのログイン

```
% vagrant ssh
```

# 参考
- [【図で理解】ロードバランサーとは？負荷分散の仕組みを解説](https://www.kagoya.jp/howto/network/loadvalancer/)
- [Vagrantの使い方](https://qiita.com/IK12_info/items/28ac74bfa92a39e886ef)
GoogleSearchConsoleの審査の抜粋（リッチリザルトレポート）機能について

こんにちは、[株式会社BINAR](https://binar.jp/?bintrcd=0QITA202002A0001)の小畑です。
エンジニア × マーケティングな人材として働いています。
今回はGoogleSearchConsoleに新しく追加された__審査の抜粋__機能について日本語で説明されている記事があまりないので説明していきます。

## ■ 審査の抜粋とは
GoogleSearchConsoleに[レビュー機能](https://webmasters.googleblog.com/2020/02/review-snippets.html)が追加されました。
日本語では__審査の抜粋__という項目でメニューに表示されています。
このレビュー機能は、対象のサイトがGoogleのリッチリザルト表示の基準に満たしているかどうかをレポートしてくれます。
リッチリザルトは基本的に構造化データにならっています。

Googleがサポートしているのは[schema.org](https://schema.org/)という構造化データの手法です。
サイトのデータを構造化して記載することで、そのサイトがどういったサイトなのかを明示的に示すことになります。
おそらくGoogleは検索者にとって、より有意義な情報を届けるために今後もおそらくデータをより整理していきますし、ライターにそれを求めていきます。
今までは構造化データはSEOに影響しないとしていましたが、これからは構造化データはSEOに影響すると発言しているので、SEO担当者にとっては必ず必須な知識になります。

気をつけなければいけないのが、__審査の抜粋__は[schema.org](https://schema.org/)リッチリザルト結果に影響するのみということです。
違いを理解するために、__構造化データテスト__と__リッチリザルトテスト__を利用していきます。

## ■ 構造化データテストとリッチリザルトテスト
[構造化データテスト](https://search.google.com/structured-data/testing-tool/u/0/?hl=JA)と[リッチリザルトテスト](https://search.google.com/test/rich-results?hl=ja)の違いは明確です。

|構造化データテスト  |リッチリザルトテスト  |
|---|---|
|schema.org通りに定義されているかどうか  |Googleのリッチリザルトにふさわしい定義になっているかどうか  |

この違いによって何が起きるかというと、構造化データテストではOKが出ても、リッチリザルトテストではNGが出る場合があるということです。
Googleは[schema.org](https://schema.org/)の記法をサポートはしていますが、リッチリザルトとしては全てを対応している訳ではありません。
リッチリザルトとしてサポートしているのは以下の通りです。
### Googleがサポートしている構造化データ

- schema.org/Book
- schema.org/Course
- schema.org/CreativeWorkSeason
- schema.org/CreativeWorkSeries
- schema.org/Episode
- schema.org/Event
- schema.org/Game
- schema.org/HowTo
- schema.org/LocalBusiness
- schema.org/MediaObject
- schema.org/Movie
- schema.org/MusicPlaylist
- schema.org/MusicRecording
- schema.org/Organization
- schema.org/Product
- schema.org/Recipe
- schema.org/SoftwareApplication

参考） [Making Review Rich Results more helpful](https://webmasters.googleblog.com/2019/09/making-review-rich-results-more-helpful.html)

例えば、__schema.org/Review__などはまだサポートされていません。
なので、、構造化データテストでは問題なくグリーンになりますが、リッチリザルトテストでは以下のようにレッド（エラー）になります。
<img width="868" alt="GoogleSearchConsole_review_error.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75243/d19f8012-72e6-06ef-35c3-67f740a61c27.png">

__項目がレビューに対応していません__と出てきてもちょっとよくわからないですよね。笑
筆者自身もいくつか調べてみたのですが、日本語ドキュメントが皆無でした。（2020/02/13時点）

構造化データテストが通っていれば、書き方は問題ありません。
しかし、Googleの評価機能としてはまだサポートしていないということです。

## ■ エラーが出た時の対処法
サポートされていないので、正直現状としては対処のしようがありません。
方法は二つです。

 1. サポートされるまで放置する
 2. いったん、サポートされていないのは削除する。

エラーが出ている状態のままだとSEO的にどうなのかが気になるポイントかと思います。
これは憶測でしかないですが、おそらく影響しません。
そもそもGoogleが明確に提示していないので、Google自体評価を下げてもいいのかあげてもいいのか判断がついていないからまだサポートしていないはずです。

ただし、影響として想定されるものは検索結果がリッチリザルトではなくなる可能性はあります。
それによってCVはおそらく変化するので、無難に引き下がっておくのも一つの手です。
ただし、Googleサポートした時にすぐに気づけない可能性があるので、トレードオフではあります。

## ■ 今後のSEO
これからのSEOのトピックスは大きく分けて3つ。

- サイトの作りは最低限の要件（モバイルファースト、キッシュ、canonicalタグなど）
- 記事の内容の質が求められる。（読み手に価値のある情報かどうかをBERTを使って判断する。）
- 構造化データを利用して、どういうサイトなのかを明確にする。

ようは、検索者そして読み手に対して本当にいいサイトなのかどうかがより評価されます。
かつ、インターネット上でポジショニングを獲得しなければいけません。
求められる要件はグッと上がっていくことが今後も想定されるので、今のうちにサイトの運用方針などを定めるのが吉かと思います。
【Go】配列のサンプルメモ


```go
package main

import (
	"fmt"
)

func main() {
	// 配列の型
	// [長さ] 要素型
	// [長さ] 要素型 {要素の初期値..}

	// 配列の宣言
	var arr1 [2]string
	arr1[0] = "a"
	arr1[1] = "b"
	fmt.Println(arr1)

	// 配列初期化
	arr2 := [2]string{"a", "b"}
	fmt.Println(arr2)

	// https://yttm-work.jp/lang/go/go_0005.html#head_line_03
	var arr3 [2]string = [2]string{"a", "b"}
	fmt.Println(arr3)

	// 初期値で指定した要素の数が自動的に長さとなる
	arr4 := [...]string{"a", "b"}
	fmt.Println(arr4)
}
```
【Go】スライスのサンプルメモ

package main

import (
	"fmt"
	"reflect"
)

func main() {
    // 配列
    arr := [3]string{"a", "b", "c"}

    // スライス型の変数を宣言
    var s1 []string
    // スライス
    s1 = arr[:]
		fmt.Println(s1) // [a b c]

		fmt.Println(reflect.TypeOf(s1)) // []string

    // var を使わないVersion
    s2 := arr[:]
    fmt.Println(s2) // [a b c]

    // インデックスを指定
    s3 := arr[1:2]
    fmt.Println(s3) // [b c]

    s4 := arr[1:3]
    fmt.Println(s4) // [b c]

    // append
    s5 := append(s4, "d", "e")
    fmt.Println(s4) // [b c]
    fmt.Println(s5) // [b c d e]

    // 配列とスライスを同時に宣言
    s6 := []string{"A", "B", "C"}
    fmt.Println(s6)

    // 長さ、キャパシティ
    fmt.Println(len(s6)) // 3
    fmt.Println(cap(s6)) // 3

    s7 := append(s6, "D")
    fmt.Println(len(s7)) // 4
    fmt.Println(cap(s7)) // 6 --> 倍になった

    a8 := [...]int{0, 1, 2, 3, 4}
    s8 := a8[1:4]
    fmt.Println(s8) // [1 2 3]
    fmt.Println(len(s8)) // 3
    fmt.Println(cap(s8)) // 4

    s9 := a8[1:2]
    fmt.Println(len(s9)) // 1
    fmt.Println(cap(s9)) // 4

    s10 := a8[0:5]
    fmt.Println(len(s10)) // 5
    fmt.Println(cap(s10)) // 5
}
PackageCompiler.jl で Makie.jl  の呼び出しを速くする

# 本日は

旧 PackageCompilerX.jl がPackageCompiler.jlにアップデートされたので
Makie.jl できるかなを試しました．Makiejl のリポジトリ自体結構不安定なので今後できるかはわかりませんが・・・．


# これでできるはず


```console
$ julia -q
pkg> dev PackageCompiler # 最新のコードをチェックアウトする
julia> using PackageCompiler
julia> PackageCompiler.create_sysimage([:Makie, :AbstractPlotting],sysimage_path="makie.so")
julia> exit() # 一回終了
$ ls
makie.so # システムイメージが生成される
$ julia -J makie.so # -J でシステムイメージ makie.so を読み込む
julia> using Makie; display(AbstractPlotting.PlotDisplay(),plot([1,2,3]))
```

PackageCompiler.jl でMakie.jl を固めると　

```
juli> plot([1,2,3])
```

のようにすると長い文字列しか出ず，実際にグラフが表示されません．ですので

`display(AbstractPlotting.PlotDisplay(),plot([1,2,3]))` という方法で出力させています．これは Makie.jl のリポジトリのREADME.md に書いてある通りです．

以上
PHP 三項演算子

# 目的

- 三項演算子の概要をまとめる

# 書き方の例

- 下記に三項演算子の例を記載する。

```php
$変数 = (条件式) ? 真の時変数に格納する値 : 偽の時変数に格納する値;
```

- 下記に前述の三項演算子をif文で書く例を記載する。

```php
if (条件式) {
  $変数 = 真の時変数に格納する値;
} else {
  $変数 = 偽の時変数に格納する値;
}
```
敢えてRubyで学ぶ「ゼロから作るDeep Learning」閑話 Numo::GSLの導入と正規乱数

第4章に正規(ガウス)分布の乱数を生成するコードが有る。

## 擬似的に正規分布の乱数を最も簡単に作る方法
-0.5~0.5の乱数の12回の平均。

```ruby
def norm_rand
  random = Random.new()
  result = 0
  12.times do
    result += random.rand(-0.5..0.5)
  end
  result / 12
end
```

とはいえ、色々面倒だし、これを使って行列を作るのもなんとも不便。
そこで、乱数を生成してくれるライブラリ、Numo::GSLを導入する。

## Numo::GSLの導入

基本的にはDockerのRuby上で行っています。
環境構築に関しては、[敢えてRubyで学ぶ「ゼロから作るDeep Learning」Docker環境構築編](https://qiita.com/michihito_t/items/02e5056764de6d2b7655)をご確認ください。


```sh
# まずは元となるGSLを導入
$ apt install -y gsl-bin
# 次にNumo::GSLのgemを導入
$ gem install numo-gsl
```

## Numo::GSLでの正規乱数の生成

```ruby
require 'numo/gsl'
require 'numo/narray'

## 標準正規分布のrow * colの行列を作る
def randn(row, col)
  r = Numo::GSL::Rng::Rand.new
  r.gaussian(1, row * col).reshape(row, col)
end
```

## 追記 Numo::Narrayから正規乱数の生成

@kojix2 さんよりコメント頂きました、Numo::NArrayで正規乱数を作る方法も記載しておきます。

```ruby
require 'numo/narray'

# 標準正規分布のrow * colの行列を作る
# rand_norm = rand_norm(0,1) 平均0、標準偏差1の標準正規分布
Numo::DFloat.new(row,col).rand_norm
```
Bashのhistoryで表示される重複したコマンドを消したい

# history で重複したコマンドを消したい

## historyを叩いた

入力したコマンドを確認したくて`history`コマンドを入力すること、ありますよね。

```
$ history
...
2000  ll
2001  cd ./hoge
2002  ls
2003  ll
2004  cd ../
2005  history
2006  ll
2007  cd ~
2008  ls
2009  history
...
```

**「いやllとかls多いな？」**

## 重複したコマンドの消し方

重複したコマンドを消去するには.bashrc に

```
HISTCONTROL=erasedups
```

を追記すればよいです。

```
$ source .bashrc
```
で.bashrcを再度読み込めば設定が反映されます。

## HISTCONTROLとは

入力したコマンドがどのように保存されるか決定する値。
http://www.gnu.org/software/bash/manual/bash.html#index-HISTCONTROL

```
HISTCONTROL=value
```

|value|設定内容|
|---|---|
|ignorespace|空白文字で始まる行を保存しない|
|ignoredups|ひとつ前の履歴エントリと一致する行を保存しない|
|ignoreboth|ignorespace と ignoredups の省略形|
|erasedups|現在の行と一致する履歴を保存前にすべて削除する|

`ignoredups`と`erasedups`は似ているように思えますが、

- `ignoredups`は直前に入力したコマンドと同一のコマンドを入力した場合、そのコマンドを保存しない設定
- `erasedups`は入力したコマンドと同一のコマンドが履歴に存在した場合、昔の履歴を削除する設定

という違いがあります。

### 注意点

`erasedups` を設定すると、昔の履歴も消去するので、コマンド履歴が時系列順に並ばなくなります。
コマンド履歴が時系列順に並んでいることを期待する場合は使わないほうがよさそう。

## lsとかcdだけ保存しないようにできないの？

そういった細かい設定をしたい場合は、HISTIGNOREを使えば良いようです。
この記事では割愛します。
http://www.gnu.org/software/bash/manual/bash.html#index-HISTIGNORE

## 参考
http://www.gnu.org/software/bash/manual/bash.html#Bash-Variables
https://qiita.com/bezeklik/items/56a597acc2eb568860d7
AirMac Express + RasPi Zero で WPA2 Enterprise 環境

# 要約

AirMac Express のセカンダリ（ゲスト用） WiFi に接続されている機器を RADIUS Server に出来ます。
AirMac Express は、例えば 10.0.0.1 であると同時に 172.16.0.1 でもあり、いつでも 172.16.0/24 宛に通信を開始するのです。


# 背景

もしあなたが WPA2 Enterprise の実験やらテストやらをしなければならないとしましょう。
もしあなたが Apple 製品を好きだったとしましょう。

手元には使っていない AirMac Express MC414J/A が転がっていますよね？

はい、AirMac Express は WPA2 Enterprise ネットワークを作り出せます。

ただここで、普通の発想では「RADIUS Server は有線接続」となりますよね？　だって WiFi 接続を成立させるための機器を予め WiFi で接続しておく、なんて、矛盾しています。なので、例えば Raspberry Pi に freeradius をインストール＆セットアップして Ethernet HUB 経由で有線で AirMac Express に接続するわけです。

１つ１つはパームトップ・サイズの機器とはいえ、これが３つも在るとなると、もはや机を１つ専有します。悲劇。

でも、AirMac Express は２つの WiFi をセットアップ出来ますし、WPA2 Personal には外部機器（RADIUS Server のこと）なしに接続できます。

そして・・・「AirMac Express から接続する RADIUS Server はプライマリ・サブネット上に存在しなければならない」なんて、誰も言ってないのでは？
（プライマリ WiFi のクライアントからセカンダリ WiFi サブネットにはアクセス出来ません。もちろん逆も。）


# それ、出来ます

「どうやるの？」って特に示すことが無いので、スニペットを示すことなく本記事は終了しますｗ

やったら出来ました。やれば出来ます。


# それも、出来ます

ちなみに機材を減らしたいだけなら、Ethernet HUB を使わずケーブル直結という手があります。

でも、「RADIUS Server を繋げるのも WiFi でいい」となれば、RADIUS Server のセットアップ先は Raspbery Pi Zero W でもいいわけです。

そういえば AirMac Express には USB ポートが搭載されていたような。ここから電源とれるかな？　←これは試していません、悪しからず。
お絵かきできるSNSを作りたい！4

今回は少しでもアプリに近づけるためにmanifest.jsonを追加したいと思います。

これを追加することでAndroidでページを開いた際、ホーム画面にタイルを置きませんか？とメッセージを表示することが出来るんだとか。

場所はHEADの中に一行以下の記述を書くだけです。

```HTML:
<link rel="manifest" href="manifest.json">
```

manifest.jsonの中身は↓こんな感じです。

```JavaScript:
{
  "lang": "ja",
  "name": "sakura",
  "short_name": "お絵かき",
  "icons": [{
        "src": "icon.png",
        "sizes": "129x129",
        "type": "image/png"
      }],
  "start_url": "https://127.0.0.1/",
  "display": "standalone"
}
```
言語、アプリ名・短縮アプリ名とタイルに置く画像を指定します。
start_urlはサーバがないので適当です。
最終的にはElectronでアプリ化もしておきたいですね。

最後に自分がやりたそうにしていることをまとめておきます。
・PWA
・線の太さを変える
・線の色を変える
・画像を保存
・レイヤー
・戻る(Ctrl+Z)
・進む(Ctrl+Y)
・Webプッシュ通知対応
・好きな画像を下絵にしてトレースできるようにする

次：[お絵かきできるSNSを作りたい！5](https://qiita.com/cardcapt/items/c7436295ffc359c42126)
最初：[お絵かきできるSNSを作りたい！](https://qiita.com/cardcapt/items/d15fedf80d336f6b4bb9)
【Python】スクリーンショットからメインカラーを取得する


今回は、読み込んだ画像からメインカラーを取得していきます。
通常色のポケモンと色違いのポケモンを５つのメインカラーに分けて、比較できるようにします。

#インポート

```
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import argparse
import utils
import cv2
import numpy as np
```

#画像取得

画像をOpenCVで読み込んだ場合、そのままだとBGRになっているためRGBに変換させます。

```
image_path = "./ウオノラゴン00001.jpg"

image = cv2.imread(image_path)

image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
```

NumPy配列を形成して、RGBピクセルのリストにします。

```
image = image.reshape((image.shape[0] * image.shape[1], 3))
```
#k-means

k-meansを使用して最も支配的な色をみつけます。
クラスタ数を５つにし、RGBピクセルのリストをクラスター化させます。

```
clt = KMeans(n_clusters = 5)
clt.fit(image)
```

ヒストグラムからメインカラーの割合をだします。

```
numLabels = np.arange(0, len(np.unique(clt.labels_)) + 1)
(hist, _) = np.histogram(clt.labels_, bins=numLabels)

hist = hist.astype("float")
hist /= hist.sum()
```

# メインカラーを取得
for文で５つメインカラーとその割合を取り出します。

```
bar = np.zeros((50, 300, 3), dtype="uint8")
cluster_centers_arr = clt.cluster_centers_.astype(int, copy=False)
startX = 0

for (percent, color) in zip(hist, cluster_centers_arr):
    color_hex_str = '#%02x%02x%02x' % tuple(color)
    print(percent , color_hex_str)
    endX = startX + (percent * 300)
    cv2.rectangle(bar, (int(startX), 0), (int(endX), 50),color.astype("uint8").tolist(), -1)
    startX = endX
```

５つのメインカラーを表示します。

```
plt.figure()
plt.axis("off")
plt.imshow(bar)
plt.show()
```

# 実行結果

元のスクリーンショット（ウオノラゴン）
<img width="617" alt="ウオノラゴン.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431502/c2e2e725-50dd-2353-e860-bbf072d87b50.png">

実行結果

```
0.7486892361111112 #dd4928
0.05908420138888889 #0b0403
0.038871527777777776 #b7d1e0
0.13411458333333334 #d21d1d
0.01924045138888889 #294e37
```

<img width="752" alt="通常配色.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431502/4a71db8d-1fde-70f2-12c4-cfccda9f2144.png">






元のスクリーンショット（色違い ウオノラゴン）
<img width="617" alt="色違いウオノラゴン.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431502/ab132f6a-fa6c-ac15-ef00-79e96b261002.png">

実行結果

```
0.7698796296296296 #dd4828
0.03972407407407407 #c9d0ca
0.026488888888888888 #262220
0.025824074074074076 #6e6166
0.13808333333333334 #d41d1a
```

<img width="752" alt="色違い配色.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431502/0109a47f-874a-a981-155a-99b8efe70004.png">



５つのメインカラーを取得できましたが、そのままだと背景の割合が多くなってしまいました。
背景色のメインカラーを除いた、３色からポケモンのメインカラーを出せたため、
そこから色違いであるかどうかを判断できそうです。

#参考
[OpenCV and Python K-Means Color Clustering
](https://www.pyimagesearch.com/2014/05/26/opencv-python-k-means-color-clustering/)

[Pythonで画像からメインカラーを抽出する
](https://qiita.com/simonritchie/items/396112fb8a10702a3644)
機構制御とは？　そして、前エントリーの内容について

# 機構制御とは？
前エントリーをFacebookに投稿した所、機構制御とは何でしょう？初耳です。と言った内容があったので
少し機構制御とはどういうものなのかについて記載したいと思います。
機構制御とは、メカ屋さんが設計した機構を制御するものです。機構とは樹脂や板金で設計したモノの事です。
例えばキーボードのキーの設計も機構と言えます。（キーボードは機構制御しませんが・・・）
身近なものではATMや駅の券売機、改札などですね。よく、メンテナンス会社の人が改札を開けて修理なんか
をしてると思いますが、その中には板金でシャッターや切符などの搬送路、ギア、なんかで敷き詰められていると
思います。　そして、搬送する為にはモーター、シャッター制御ではソレノイド（電磁石で棒を引っ張ったり
押したりする部品）があります。　そして、特定の位置には光学式センサがあります。透過型のセンサだったり、反射型のセンサだったり、時には光学式ではなくコイルで何かしら特定の波形を検知するセンサだったりします。
それらモーターやソレノイドの駆動、センサの検知をしてモーターの駆動を変えたり、ソレノイドを制御して搬送路を切り替えたり、ギアなどでも何かしらを制御したりとする事を称して **機構制御** と言っています。
一般的では無いので、人によってはそれは機構制御とは言わないという人も居ると思います。

駅の改札では磁気切符の表裏に関わらず読んで場合によっては改札の出口では表で排出したりしていると思いますが、これは内部で**機構制御ソフト**が複雑な **機構制御**　を行っている為です。
少なくとも表裏を反転差せる機構があるのと、読み取りエラーであっても何回かは再読み込みをさせる制御は入ってると思います。　磁気センサが両面あるのか片面なのかまでは知りません(^^;

# 前エントリーで書いた事は当たり前なのか
当たり前といえば、当たり前なのですが、私はこの当たり前の事が守られていないプログラムに遭遇する事が
よくあります。　というか、ほんの一握りの人以外はこの当たり前の事が守られていません。
そして、特にハード寄りで無い人は特にそうですね。
外注に頼むともう泣けるようなプログラムが上がってきて、温度環境（高温、低温、多湿、低湿）や電気環境（電源ノイズ、放射ノイズ、伝導ノイズ）の試験をするとホラ見た事かと不具合を出しまくって、その場を凌ぐだけの修正をして、更に市場では不具合が出まくる灯言う事例を見てきました。

少し話題が逸れましたね。
上記の通り、”至極当たり前事”の事が書いたのですが、この”至極当たり前”ではない人が多いのが事実だと、少なくとも私はそう思っています。
そういう事があって、**前エントリーを書かせて頂きました。**

余談ですが、この辺りの割り込み処理のプログラムは大抵は泥臭いプログラムである事が多いです。
悲しい事に若い人はこの泥臭いプログラムを嫌って、制御系ソフトを組みたがらない人が増えてるように感じます。（弊社もプログラマは古参ばかりです。そして、ハードウェア設計経験者も多いです・・。）

あまり為に為らないような記事でしたが、次回こそRTOS(itron)でのタスク設計について書きたいと思います。
Educational Codeforces Round 82B. National Project

# 題意
- $n, g, b$ (道の長さ$n$, 晴れの日数$g$, 雨の日数$b$) が与えられる
- 今日から天気は 晴れ$g$日間, 雨$b$日間, 晴れ$g$日間...を繰り返す
    - つまり、$g=2$, $b=3$なら $ggbbbggbbbggb...$
- あなたは1日に"1"の道を作っても良い。晴れの日は`良い道`ができ、雨の日は`悪い道`ができる。
- あなたは1日に道を作らなくてもいい
- あなたはnの半分を`良い道`で作らないといけない。残りは良い道でも悪い道でも`どちらでもよい`
- 半分、とは、$n=4$のとき$2$, $n=5$のとき$3$などである。つまり、$ceil(n/2)$が良い道でないといけない
- 最短でこの目的を達成するのに何日かかるか？

# 考察
例を見てもあまりヒントとなる例がないので$n, g, b = 9, 2, 3$を図に示す。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/8a2d8870-7456-5035-1899-f64131a83cfa.png" width=50%>

赤が良い道を作る日、緑が悪い道を作る日、黒はおやすみの日である。

まず、`rg = 必要な良い道` と `rb = その他必要な道`は `rg = ceil(n/2) = 5`として`rb = n-rg = 4`は自明である。
`良い道`だけに着目すると、良い道が埋まるのは`ceil(rg / g) = xceil(5 / 2) = 3`サイクル目になる。つまり、2サイクル目までは必ず必要となり、3サイクル目は図のように、途中で終わる可能性がある。
次に、2サイクル目いっぱいで処理できる`どちらでもよい道`は$b * 2$サイクルである。($g$の分の作業日はすべて`良い道`を作るのにあてられる)ただし、この例のように、途中で`どちらでもよい道`は作り終わってしまうこともある。

以上を考えると3サイクル目に入った瞬間には、`rg - g*2` + `max(0, rb - b*2)`の道を作らないといけない。ここで、`良い道`は上記の通りこのサイクルで必ず作り終わることが分かっているため、必要な日数は単なる足し算となる。maxを取っているのは$rb - b*2$は負になりうるからである。

# 実装

```Python
q = int(input())
import math
for _ in range(q):
    n, g, b = map(int, input().split())
    rg = math.ceil(n / 2) # 引くべき良い道
    rb = n - rg # 引くべき、どちらでもよい道
    res = 0
    needcycle = math.ceil(rg / g)  # 何回目で引き終わる？
    # 前まででどこまで引き終わった？
    rg = rg - (g * (needcycle - 1)) # 引かないといけない良い道
    rb = max(0, rb - b * (needcycle - 1)) # 引かないといけないどちらでもよい道
    # 必要な日数というのは 前のサイクルまでの日数＋最後のサイクルで必要な日数
    res = ((g + b) * (needcycle - 1)) + (rg + rb)
    print(res)
```
https://codeforces.com/contest/1303/submission/70981948
AngularでNetlifyにng build –prodしたら簡単にデプロイでき・・・なかった話

#昔話

よし！もうすぐバレンタイン
モテないエンジニアのためにチョコレートが貰えるサイトをAngularでつくってやるか～～

お金ないから無料でできるNetlifyで公開しよ～

デプロイの記事もあるし簡単じゃん
→実装後

ng build –prodしてもデプロイできないじゃん！！！

というわけで別の方法でデプロイする方法を書きます。
ちなみに[こちら](https://keen-banach-af3de9.netlify.com/)が公開したサイトなのでぜひチョコレートを貰ってください。

#デプロイ方法

まずは必要なライブラリをインストール

```
ng add @netlify-builder/deploy
```

API IDを求められるので入力
APIは下記ルートからどうぞ
公開したいサイトのページからSettingsを押下

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390321/75226287-c2f7-1901-3663-0f1a6c2fadcd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390321/a7173e9f-a43a-590f-5658-f5771021a448.png)


次にPersonal Access Tokensを入力

取得経路は右上のアイコンからUser settingsページに飛びApplicationsボタンをクリック
からのPersonal access tokensでなんやかんや作れます。

（注）***今回はすぐに非公開にする予定のサービスなのでセキュリティがばがばですが
きちんとしたい方は[こちら](https://www.netlify.com/blog/2019/09/17/using-the-angular-builder-for-netlify/)を参考にしてください！***
laravel ログイン後のリダイレクト先を指定

こんにちは！

laravelのデフォルトで実装されているログイン機能について、ログイン後のリダイレクト先を変更する方法を紹介します。

laravel 6.x系です

前提として、ログイン機能が実装済みとします！（リファレンスに記載されているコマンドを打てば実装できるはず）

で、デフォルト状態だと、ログイン画面でログインすると、'/home'にリダイレクトする仕様になっていると思いますが、任意のurlを指定すことができます

```app/Http/Controllers/Auth/LoginController.php
//省略

public function redirectPath()
    {
        return '任意のurl';
        //例）return 'costs/index';
    }
```

Auth/LoginControllerに↑の関数を追記することで、任意のurlにリダイレクトさせることができます！

自分はこのコントローラの一番下に記述しました。

これだけの内容です！

リダイレクトの条件分岐もできますので、気になる方はいろんな記事をググってみてください！

## 追記

ログイン後だけでなく、新規登録後も、'app/Http/Controllers/Auth/RegisterController'に同じように記述すれば、リダイレクト先を指定できます！

ちなみに、'追記'すればいいだけなので、もとから記述されている内容はそのまま残しておいて大丈夫ですよ！
devise token auth の email のフォーマットバリデーションの正規表現は devise とは違う

# 概要
devise token auth は devise を依存ライブラリとして使っているので、email のフォーマットバリデーションの正規表現も devise のものを使っていると思ったのですが、違いました。勘違いしやすいところかと思ったので共有です。

# コード
下記が devise token auth の email バリデーションの正規表現です。

```
/\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
```

ソースコードは下記。

https://github.com/lynndylanhurley/devise_token_auth/blob/master/app/validators/devise_token_auth_email_validator.rb
RSpec で ある要素のみが入った配列かどうかを確認したいときは contain_exactly を使う

# 概要
a,b,c のリソースがあるときに、a,c のみが順番は関係なく返されることをテストしたいときには、contain_exactly が便利です。

# コード

```
let!(:user_a) { create(:user, name: 'a') }
let!(:user_b) { create(:user, name: 'b') }
let!(:user_c) { create(:user, name: 'c') }

it 'returns ac users do
  expect(User.hoge).to contain_exactly(user_a, user_c)
end

```

順番もテストするときは素直に eq matcher で配列を使う。

```
it 'returns ac users do
  expect(User.hoge).to eq [user_a, user_c]
end
```

参考：
`contain_exactly` matcher
https://relishapp.com/rspec/rspec-expectations/v/3-9/docs/built-in-matchers/contain-exactly-matcher
dynamic rendering で Twitter OGP が表示されないときは Response Header に Content-Type に text/html を入れる

# 概要
Cloud Front などでホスティングする SPA で OGP イメージを表示するために dynamic rendering をすることがあります。

その際に slack や facebook では表示されるのに、Twitter OGP だけ表示されなかったので、その解決方法を共有します。

# 解決方法
response header に Content-Type に text/html を入れてレスポンスを返せば表示されます。
Content-Type を指定しないと、ボディの文字列をどのように解釈すればよいかわからないので meta タグを読み込めなかったのだと思います。

aws lambda の例

```
        const response = {
            body: #html, 
            bodyEncoding: "text",
            headers: {
                "content-type": [
                    {
                        key: "Content-Type",
                        value: "text/html"
                    }
                ]},
            status: 200
        };
```
S3 で SPA をホスティングするとき、アクセスする URL が 404 のときに index.html を返す方法

# 概要
S3 で SPA をホスティングするときに、404のときにindex.htmlを返してくれないと正常にSPAを動かせません。
Cloud Front であればエラーコード時の返すページを設定できますが、S3のみでホスティングしたときのやり方で少しはまったので共有です。

# やり方
エラードキュメントに index.html を設定すればよいだけです。

<img width="509" alt="スクリーンショット 2020-01-19 23.39.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557058/2f6687b8-95dc-60b2-f2c5-00359c443b7c.png">
ruby で公開鍵の文字列から public key オブジェクトを作成する方法

# 概要
公開鍵の文字列から public key オブジェクトを生成する方法について少しはまったので、共有します。

# コード
下記のような公開鍵があるときは

```
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0bXcnrheJ2snfq1wv6Qz 8+TEPDGKHCM0SsrQjxEFpXSEycL2/A+oW1ZGUzCuhz4HH4wkvc4CDJl25johSIUT Vyo4mrFrJ0ab0QAhrWE7gMyWFIfraj9cksPAGyVAiXLCN9Ly2xuoJxFjCAZXw1VO 8i7RTYK8ZP6dhcosiyzdhYt7C/65B5ikmCS4AymXIa83QQanCtjoGiwy4Cf2pLnn 9zXMZEnqQ+wwSoGn32YExmap7GAtjOwHNWU5zpW3dwNMq+zkcln3ICEBwxDpWJhE ZHZPBpPWgN+dQZDR2FiGHJgUFE3EM+CIcwxekrRBP+R3xEUeMFf5z1HeQNK8sjZe RwIDAQAB
-----END PUBLIC KEY-----
```

「-----BEGIN PUBLIC KEY-----」の後と「-----END PUBLIC KEY-----」の前に改行記号を入れた文字列を作ります。改行記号の前後にスペースがあるとエラーが出ます。

```
str = 
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0bXcnrheJ2snfq1wv6Qz 8+TEPDGKHCM0SsrQjxEFpXSEycL2/A+oW1ZGUzCuhz4HH4wkvc4CDJl25johSIUT Vyo4mrFrJ0ab0QAhrWE7gMyWFIfraj9cksPAGyVAiXLCN9Ly2xuoJxFjCAZXw1VO 8i7RTYK8ZP6dhcosiyzdhYt7C/65B5ikmCS4AymXIa83QQanCtjoGiwy4Cf2pLnn 9zXMZEnqQ+wwSoGn32YExmap7GAtjOwHNWU5zpW3dwNMq+zkcln3ICEBwxDpWJhE ZHZPBpPWgN+dQZDR2FiGHJgUFE3EM+CIcwxekrRBP+R3xEUeMFf5z1HeQNK8sjZe RwIDAQAB\n-----END PUBLIC KEY-----"
```

その文字列を OpenSSL::PKey::RSA に渡します。

```
public_key_object = OpenSSL::PKey::RSA.new(str)
```
RSpecで gem config の環境を任意の環境に指定するとき

# 概要
rspec を書くときに、テストが実行される環境だけではなく、任意の環境で config で設定した値が関わる処理をテストしたいときがあります。

# コード
下記でできます。

```
Config.load_and_set_settings(Config.setting_files(Rails.root.join('config'), 環境変数))
```

例: プロダクション環境のときの config を試したいとき


```
Config.load_and_set_settings(Config.setting_files(Rails.root.join('config'), production))
```

参考
https://github.com/rubyconfig/config
github actions で任意のブランチのみで job を実行する方法

# 概要
github actions で 特定のブランチだけで実行したい特定の job があるときは、 on オプションでは対応しきれません。
なぜなら、 on オプションではワークフローの実行に対する条件だからです。

# ref を参照して、 if を使う
master ブランチのみで実行する job の例
`if: github.ref == 'refs/heads/master'`

```
  production_deploy:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master'
    steps:
      - name: Execute git checkout
        uses: actions/checkout@v2
```

参考記事
[GitHub Actions] branch conditional
https://github.community/t5/GitHub-Actions/GitHub-Actions-branch-conditional/td-p/29794
PCの動作が重い時の対処


可能性１：レジストリのごみが溜まって、無いリンクパスを確認しまくり遅くなる。

<B> 対処法：
CCleaner をDL＆インストールして起動して、レジストリを綺麗にする
数クリックぐらいで簡単で便利なツール

これを使って早くなった事例はいくつも遭遇した。


可能性２：Windows10システムファイルが部分的におかしくて重い、起動すらおかしい

<B> 対処法２：
グレイリーユーティリティをDL&インストールして実行し、部分的なシステムの修理をしてもらう。
数クリックでできるくらい簡単で便利なツール

運が良くないと起動成功しないくらいの壊れかけていたノートPCが、なんと直る！
もちろん、HDDはクローンして入れ替えた。

可能性その他： フォルダ制御や過去履歴データなどが膨大になり、それのせいで重くなる

対処法：
https://aprico-media.com/posts/1598

ファイルインディックスを試したところ、かなり改善されたケースあり。
ファイルを開く行為は良く行うので、フォルダ動作のリフレッシュも兼ねて
行うといいかもしれない。
Raspbian Raspberry Pi (ラズパイ) でGPIOコマンドがなにも表示されなかったので動くようにした

## Raspberry  触ってみた

今回は、Raspberry Pi3 が会社にあったので、勉強も兼ねて触って見ました。

Raspbianをインストールして、初歩の初歩のgpioというコマンドで、
エラーがでたり、なにも表示されなかったりと思いどおりに動かず、四苦八苦したので解決方法を記載します。

---

ちなみに、余談ですが今回購入したキットはこちらになります

[OSOYOO(オソヨー) Raspberry Pi 学ぶ電子工作キット (メーカー型番:DKRK100600JP)]
(https://www.amazon.co.jp/gp/product/B01M6ZFNSS/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1)


---

そこで、C言語のライブラリ のwiringpiが紹介されてましたが古い方法だとインストールに失敗します。
( wiringpi自体は有名だそうです )


## 1. 初期状態

( 初期というか少し触ってしまっていたかもしれません )

```
gpio -v 
gpio readall
```

上のコマンドを実行してみましたが
`This board is not ODROID.` というエラーがでてまったく動かず...


## 2. drogonからcloneしてみようとした

キットの中に説明書みたいのがあって記載があったのでやってみた。

```
git clone git://git.drogon.net/wiringPi

git.drogon.net[xxxxxxxxxx]: errno=接続を拒否されました
```

という表示がでて失敗...


## 3. 作者? 　のページを拝見していた

http://wiringpi.com/download-and-install/


`sudo apt-get install wiringpi` すればいいよって書いてあった。

なんだ、楽勝じゃん...って思いました。
んが、しかしapt-get後は gpio -v をしたらなにも表示されなくなりました...

(´・ω・`)

ここで、ライブラリがだめなのか、使っているRaspberry Piがだめなのか配線の問題なのか
不明だったので、Pythonで `RPi.GPI` をimportして、プログラムを組んだら
普通にLED を光らせることができたので、やはりライブラリの問題だとわかりました。



## 4. 他の方のページを参考にさせて頂いた

[参考にさせて頂いたページ(ラズベリーパイ・・wiringPiが動かない)](https://www.over-rabbit.com/pc/mycom-diary/16570/)

```
sudo apt-get purge wiringpi
hash -r
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install wiringpi
```

期待に胸を膨らませて実行してみた。。。
しかし、gpio -v は、変わらずなにも表示されてなかった

うーーん

## 5. ほぼ諦めかけで、下の方法をやったらうまくいきました

まず一旦きれいにした

```
sudo apt-get purge wiringpi
hash -r
## ここから cloneをして再ビルドしてみました
git clone https://github.com/WiringPi/WiringPi.git
cd WiringPi
sudo ./build uninstall
sudo ldconfig
sudo ./build install
```

上記のページには下記記載があり、おそらく有志の方がやられているところではなかろうか...

> これは、ポート（Python / Ruby / etc）をサポートするためのWiringPiの非公式のミラーです。公式開発が 終了すると、このリポジトリは最新の「公式」ソースリリースのミラーになり、新しいハードウェア（主にポートで使用するため）をサポートする小さな更新のソースになります。

~~ほぼダメ元でやってみたら~~　 なんと、、おっっ！！！
やっとこさgpioコマンドが正常に作動しました！！！

```
pi@raspberrypi:~ $ gpio -v
gpio version: 2.60
Copyright (c) 2012-2018 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

Raspberry Pi Details:
   ～略～
pi@raspberrypi:~ $ 
```


## 最後に

kernelのバージョンとかの問題でおきるようです。
私の場合clone先が良かったのか一度uninstallしたのが良かったのか
ldconfig コマンドをうったのがよかったのか不明ですが、動くようになってよかったです。


私同様に初心者の方で、困る方がいるのではと思い、記事にさせていただきました。
これからラズパイで遊ぶぞー！



以上、最後までご覧いただきありがとうございました。
ルートとサブの両方のドメインが稼働している場合のSSLアクセス統一に関して

今回、単純なことで大きくハマってしまったので、自戒の念を込めて書きます。

ルートのみSSL対応
https://www.ドメイン.com
サブドメイン
http://sub.ドメイン.com

この状況で、ルートからサブドメインに設定されているディレクトリにアクセスできます。

こうした状況で、最初下記のサイトにあるコードで、wwwありhttpsアクセス統一するように、WordPressで作成された.htaccessに追記しました。
[.htaccessでhttps化かつwwwありに統一するクールな方法](https://www.garunimo.com/program/p35.php)

そして、アクセスして確認したところ、WordPressは、大丈夫でした。
でも、サブドメインの方が、保護されていないと赤いエラーになってしまいました。

そのため、下記の記事で書いているコードを追記して、サブドメインにアクセスできるようにしました。
[SSL化したらサブドメインにアクセスできない時の対策](https://qiita.com/masaru21/items/db7bb96cd431f9eeb261)

でも、やはりディレクトリにアクセスする方法ではなく、サブドメインでアクセスできるようにしないといけないです。
そのため、試行錯誤している中で、このような現象が起きてしまいました。
[サブドメインにアクセスすると、ディレクトリがたくさん繰り返しURLに含まれエラーになる](https://teratail.com/questions/241205)

ChromeのキャッシュやCookieを削除する方法を試しても、改善しません。

そのためネット検索したら、この記事を見つけました。
[.htaccessなどで301リダイレクトを設定するとchromeで結果をキャッシュしてしまう開発者泣かせの仕様](https://xov.jp/e/83/)

[Google Chrome のキャッシュを無効化する方法。](http://www-creators.com/archives/2781)

![スクリーンショット 2020-02-13 23.28.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20977/c5fb3822-8003-07cb-8f05-fc77b2654c77.png)


この画像のように、Chromeのデベロッパーツールを使い、301リダイレクトのキャッシュを無効にする方法を行ったところ、正常にアクセスできるようになりました。

#.htaccessの作成、修正のサイトは、Chromeのデベロッパーツールで、301リダイレクトのキャッシュを無効化して行いましょう。
このことを学ぶために、昨日は午前３時くらいまで起きていました。
単純なことにハマってしまい、本当に恥ずかしいです。

#サブドメインがある時は、安易に.htaccessにSSL化のコードを追記しない。
ネットで見つけた記事を、そのまま利用すると私のように痛い目に遭ってしまいます。
ルート（親）ドメインのみの時は、今回私が利用したコードは、有効です。
でも、サブドメインがある時は、この方法は、使えません。

WordPressのプラグインでSSL化できるもので生成される.htaccessに記載されるコードも、削除した方が良いと思います。
私は、このコードも削除しましたが、正常にSSLでwwwありhttpsアクセスに統一されています。

今回は、本当に恥ずかしい思いをしました。
クライアントから請負った仕事だったので、解決した方法がお粗末で恥ずかしいです。

#今回勉強になったこと
.htaccessの記載の方法を、色々を知ることができました。
ServiceNow CSAを受験してきた

#はじめに
2020年2月13日、ServiceNow CSA（Certified System Administrator）を受験しました。
今後受験する人の参考になればと思い投稿します。

##CSA概要
※[公式](https://community.servicenow.com/community?id=community_blog&sys_id=2c79ebebdb16af00f0612183ca961970)から抜粋

- ServiceNowを管理・運用するために必要な知識の認定
- 日本語/英語で受験可能
- 90分
- 60問
- NewYork

(おそらく70%(42問)以上正解で合格) 
~~この70%というラインが絶妙です~~

##申し込み方法
ここ注意です。**ピアソンVUEではありません**
Kryterionというテストセンターになります。
都内でもまだ5箇所（秋葉原、池袋など）くらいしかなく、
時期によっては満席のこともありますので
計画を立てて早めに予約しておきましょう。
(AWS、GCP、Salesforceなどもこちらのようですね)
この方の[記事](https://qiita.com/diapers_and_snow/items/965f302bfcc262a9f629)を参考にして、
アカウントの登録や試験の予約をしてみてください。

##試験範囲
ServiceNow Fundamentalsの研修で使用する**テキストの中**から出題されます。

##問題傾向
出題傾向を書きます。

####用語
ServiceNowで使われる用語を**テキストに載っている言葉**でおさえましょう。
####機能
用語とも関連するかと思いますが、その機能で**どんなことができるのか**、おさえましょう。
####操作
 どのような操作をすれば、目的が達成できるか、おさえておきましょう。
####テーブル名
テキストに載っているテーブル名はおさえておきましょう。

##勉強方法
私が実践した勉強方法です。

・[公式のBlue Print(PDF)](https://www.servicenow.com/content/dam/servicenow/other-documents/training/servicenow-sys-admin-exam-specs.pdf)を一通り確認
　問題のウエイトなどを翻訳しながら確認
　出題の雰囲気を掴みましょう。例題が数問あります。
・ラボを2回実施
　一回目は操作に慣れるために、二回目は何を行っているのかを考えながら実施しました。
・出題傾向の「用語」「機能」「操作」「テーブル名」を整理
・無償インスタンスで色々と弄る
　ユーザ、グループ、ロール、List、Form、ACL、テーブルなどを作成しました。

#試験を終えて
- クリアボートやペンなどは渡されず**すぐに試験開始**しました。
- 試験時間には余裕があり、慎重に解いても**40分くらい余りました**。
- 試験の終了後「合格」とだけ画面上に出て、とてもシュールでした。
- スコアレポートもなく30分後くらいにはPDF付きのメールが来ました。
- **あいまいに覚えていると2択で悩みます**。
- 各問題にはチェックボックスがあり、**後で見返すときに便利**です。活用しましょう。
- **ラボをしっかり**やっておきましょう。
- 変な日本語訳は**英語だと何かを推測する**こともありました。

#おわりに
どんな試験を受けても緊張しますね。
試験に合格できたことで、ServiceNowに関わる者として一歩を踏み出せたと感じます。

これからCSAを受験される方、一発合格できることを祈ってます。
cockpit (Linux サーバ管理ツール) のローカルユーザを制限する

cockpit は PAM(8) を使ってローカルユーザの認証を行っています。
PAM は access.conf(5) でユーザ/グループ/IP 制限がかけられるのでこれを利用することで cockpit にログインできるユーザを制限することができます。

### PAM の設定
インストールすると `/etc/pam.d/cockpit` ができているので
適当なエディタで編集してpam_access.so の行を追加します.
`accessfile=path/to/access.config` はなくてもかまいません。指定しなければ `/etc/security/access.conf` が利用されます。

```text:/etc/pam.d/cockpit
#%PAM-1.0
# this MUST be first in the "auth" stack as it sets PAM_USER
# user_unknown is definitive, so die instead of ignore to avoid subsequent modules mess up the error code
-auth      [success=done new_authtok_reqd=done user_unknown=die default=ignore]   pam_cockpit_cert.so
auth       required     pam_sepermit.so
auth       substack     password-auth
auth       include      postlogin
auth       optional     pam_ssh_add.so
account    required     pam_nologin.so
account    required     pam_access.so accessfile=/etc/security/cockpit_access.conf ★この行を追加
account    include      password-auth
password   include      password-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open env_params
session    optional     pam_keyinit.so force revoke
session    optional     pam_ssh_add.so
session    include      password-auth
session    include      postlogin
```
追加する箇所は `account include password-auth` より前にする必要があります。
この順序を逆にすると、`account include password-auth` で読み込まれている password-auth に　sufficient 行が含まれているため、そこで認証に成功しているとそのあとに書いた制限が評価されません。

### access.conf の設定
accessfile に指定したパスに access.conf(5) の書式でファイルを用意します。
例えば、 cockpit グループを作ってそのグループに入っているユーザのみログインできるようにする場合は以下のようにします。

```text:/etc/security/cockpit_access.conf
-:ALL EXCEPT (cockpit):LOCAL
```

書き方は `<permission>:<user or group>:<access>` で
- `<permission>` は '-' (許可) または`-` (拒否) のどちらか
- user または group 名、ALL は全ユーザまたは全グループにを表していて、 EXCEPT は続くユーザ・グループの除外を指定します
   - group の時は `()` をつけたほうがいいらしい？
   - `ALL EXCEPT (cockpit)` は cockpit に属するユーザを除く全ユーザが対象
- `<from>` はアクセス元
  - cockpit の場合は LOCALのみ利用している（？）

### 確認
ログインしてみて `Permission Denied` が出れば成功
![codkpit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110478/2d790445-100b-4dd9-151e-19acf0f53e76.png)
Educational Codeforces Round 82A. Erasing Zeroes

# 題意
- 100文字以内の0と1で構成された文字列が与えられる
- 1が存在する場合、それらはすべて連続していなければならない
- 消さなければならない最小の"0"の数を述べよ

# 方針
例が非常に親切。

- 010011 -> 真ん中の00を消す -> 0111 (2つ)
- 0 -> なにも消さなくていい(1がない場合、0でいい) -> 0つ
- 1111000 -> なにも消さなくていい(すでに連続している) -> 0つ

の通り `両端の0を消しその中に含まれる0の数をカウントする`が求めたい答えとなる。

# 実装1: 短く書く
```Python
[print(input().strip("0").count("0")) for i in range(int(input()))]
```
https://codeforces.com/contest/1303/submission/70961317

で通る。分解すると以下のコード。

```Python
q=int(input())
for _ in range(q):
    s = input()
    print(s.strip("0").count("0"))
```

# 実装2: 文字をまとめてカウントして計算
本番中に通したのはこのコード

```Python

import itertools
"""
>>> countstrs("1110000111")->    [('1', 3), ('0', 4), ('1', 3)]
>>> countstrs("") ->    []
>>> countstrs("aaa") ->    [('a', 3)]
"""
def countstrs(s):
    return [(k, len(list(g))) for k, g in itertools.groupby(s)]
q = int(input())
for i in range(q):
    s = input()
    c = countstrs(s) # 上記の関数で(文字, 連続する数)のリストに変換
    if c[0][0] == "0": # 最初の項目が0に関する要素ならそれを削除
        del c[0]
    if len(c) > 0: # 最後の項目が0に関する要素ならそれを削除
        if c[-1][0] == "0":
            del c[-1]
    res = 0
    for i in range(len(c)): # 残りの"0"の個数を書くんと
        if c[i][0] == "0":
            res += c[i][1]
    print(res)
```
https://codeforces.com/contest/1303/submission/70852456
Unity勉強日誌~ブレンドシェイプ操作方法その①

## はじめに。
ゲーム作ってみたいな~と思い、つい先日からUnityをさわり始めましたHITOMI2236です。今回ブレンドシェイプについて調べたのでここに記録しようと思います。個人用のメモですが、もし同じところで迷っている人がいたら、時間短縮のために読んでくれたら幸いです。


## 1 . ブレンドシェイプのモデルについて

ブレンドシェイプ検証用にMayaで簡単なモデルを作りました。HumanIKの各関節部分にCubeを配置しただけのモデルです。頭部の部分に簡単なブレンドシェイプをつけており、わかりやすくするために名前を「face_object」に変更しています。
[blendShape_01_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584811/b4ddb777-bf5f-b7db-80f5-2539a5801dee.png)
![blendShape_01_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584811/b5523dd6-5591-bc2f-9885-5e336bd1a17e.png)


これをFBXで書き出します。書き出す時にはもちろんですがアニメーション項目ないのブレンドシェイプのチェックボックスをオンにしましょう。私は結構忘れます。


書き出したFBXをUnityにドラッグアンドドロップしてPrefab化し、Hierarchyに追加します。



ブレンドシェイプがついてるオブジェクトを確認してみるとInspecterに「Skinned Mesh Render」という項目が表示されているのがわかります。その中にBlendShapesという項目があり、どうやらこの数値を増やすと形が変形するようです。

![blendShape_01_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584811/d7251389-91ba-8689-608c-4c7c49438854.png)



## 2 . ブレンドシェイプを制御するプログラム。

モデルの名前は「blendShapeCharacter」,
ブレンドシェイプ情報を持っているオブジェクト名は「face_object」です。
「face_object」が持っているブレンドシェイプの名前は「blendShape1.blendAction」です。

```c#:skinShape.rb
using System.Collections;
using System.Collections.Generic;
using UnityEngine;



public class blenderShapeControll : MonoBehaviour {
	public GameObject head;
	public SkinnedMeshRenderer skinnedMeshRenderer;
	private float m_weight;
	private int m_Index;


	void Start() {

		m_weight = 0;
		head = GameObject.Find("blendShapeCharacter/face_object");
		skinnedMeshRenderer = head.GetComponent<SkinnedMeshRenderer>();
		m_Index = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("blendShape1.blendAction");

	}
		
	void Update() {
		
		if (Input.GetKey(KeyCode.A))
		{
			if (m_weight == 0) {
				m_weight = 100;
			} else {
				m_weight = 0;
			}
			skinnedMeshRenderer.SetBlendShapeWeight(m_Index, m_weight);
		} 
	}
}
```

Aボタンを押すとブレンドシェイプが100と0に切り替わるシンプルなプログラムです。

```
GameObject.Find("blendShapeCharacter/face_object");
```
ここでブレンドシェイプの情報を持っているオブジェクトを検索して、

```
skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex("blendShape1.blendAction");
```
ここでそのオブジェクトが持っているスキンメッシュのインデックスを取得しているようです.

```
skinnedMeshRenderer.SetBlendShapeWeight(index, weight);
```
SetBlendShapeWeightで対象のウェイトを操作する。
以上のような手順?になりました。




##最後に
多分クラス化しようと考えているので、フェイシャルのブレンドやインデックスの一覧取得方法など調べてみようかなと考えています。

**趣味で3D作品を作っています。**もしよければ見て上げてください。星つけてくれたら嬉しいな!
そして、フレンドになって技術共有しましょう!
[sketchfab](https://sketchfab.com/hitomi942)