OmniAICreator/Qiita-1.07M huggingface dataset:
read_csvとDataFrameを少し読み解く

今日は、前回のデータを取り込む部分を勉強しましたが、今回は、read_csvと、DataFrameについて少し掘り下げたいと思います。
実際、これがわからないとどういうデータが利用されているのかが読めないので、、、。

ということで、今回も、[ワイン](https://qiita.com/tanakadaichi_1989/items/c655d93a1fae56f2be07)のサイトのコードを拝借。

# read_csv
まず、**read_csv**だが、Pandasに含まれるCSVデータを読み込む関数。
**read_csv**と言うぐらいなのだから、やはり**read_xx**シリーズがあるのだろうと思ったら、
http://pandas.pydata.org/pandas-docs/stable/api.html
こちらのサイトで[read]でテキスト検索するとわかる通り、ぎょうさんございました。

- read_csv
- read_table
- read_excel
- read_json
- read_html

などなど、これらは一部です。
それぞれは先程のリンクでわかると思うので、今回はサンプルコードにある情報に沿った内容のみを解読していきます。

```
#CSVファイルの読み込み
wine_data_set = pd.read_csv("winequality-red.csv",sep=";",header=0)
```
まず、ここで気になるのは、最初の引数はファイル名として、2つ目はセパレート文字ですね。
通常は、**CSV(Comma Separeted Value)**と言われるように「,」が一般的ですが、今回のCSVデータを見ると「;」が使われているようなので、そこは引数で変更したようですね。
その次の**header=0**ですが、これがCSVデータの1行目が見出し(header)で有ることを指定していますね。
当たり前のことですが、データは1行目が[0]となりますので、**header=0**なんですね。

# DataFrame
これは前回でも見出しを書きましたが、今回は少し掘り下げます。

```
#説明変数(ワインに含まれる成分)
x = DataFrame(wine_data_set.drop("quality",axis=1))

#目的変数(各ワインの品質を10段階評価したもの)
y = DataFrame(wine_data_set["quality"])
```
この2行について読み解いていきます。

```
#説明変数(ワインに含まれる成分)
x = DataFrame(wine_data_set.drop("quality",axis=1))
```
DataFrameですが、詳細は( https://deepage.net/features/pandas-dataframe.html )にあるが、基本的にデータの配列を所有する変数クラス。という表現が近いのでしょうか。

ここではDataFrameは簡易的な使い方をしているが、それよりも引数内に定義されているものが気になります。

>wine_data_set.drop("quality",axis=1)

ですね。
まずは、この**.drop**。これがなにかわからない。

https://note.nkmk.me/python-pandas-drop/
こちらに書いてありました。
これを解釈すると、最初のデータについては、元データから**"quality"**と言う**列axis=1**を削除するということだった。
**axis=0**の場合は行となる。

では、2つ目の

>wine_data_set["quality"]

逆にこっちは**"quality"**と言う列のみ。と言うことだった。

# train_test_split
次はこいつです。

```
#説明変数・目的変数をそれぞれ訓練データ・テストデータに分割
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.05)
```

https://docs.pyq.jp/python/machine_learning/tips/train_test_split.html
によると、先程のDataFrameで抽出した**特徴データ**と、**評価**を引数にして、**test_size=0.05**と言うことで、**5%をテストデータ**、**残り95%をトレーニングデータ**と定義しているようです。

# astype

```
#データの整形
x_train = x_train.astype(np.float)
x_test = x_test.astype(np.float)
```

次は**astype**と、**np.float**です。
これは**NumPy配列**の型について変換するのですね。
https://note.nkmk.me/python-numpy-dtype-astype/
こちらにもある通り、各データにといて**float型**に変換しているようですね。

# to_categorical

```
y_train = keras.utils.to_categorical(y_train,10)
y_test = keras.utils.to_categorical(y_test,10)
```

最後に**to_categorical**ですね。
あとは次回にまわします。

これについては、先程のやつとまとめて、**データ整形**とまとめられていたわけですが、
https://techacademy.jp/magazine/17694
ここにある通り、Kerasで扱いやすいデータに変換しているらしい。
評価として扱うのが「10段階」のようなので、第2引数に10としているようですね。

今日はここまで。
【Angular】NgFormを用いて画像のアップロードとPreview表示をする


こんにちは
昨日、画像のアップロードとPreview表示について記事を書きました。
https://qiita.com/TakahitoNakashima/items/354ebd4ceee90bf01696
その部分について、本来はAngularが用意をしている「NgFormを用いるべきだろう」と感じたので、その方法での実装へ変えました。
おそらく、これが一般的なやり方なのではないかと考えています。

## ゴール
・無理やり用意した投稿フォームを、NgFormを用いた形へ書き換える

## やったこと
・以下２つのページを参考にNgFormへの書き換えを行う
https://angular.jp/guide/forms
https://angular.jp/api/forms/NgForm

## 詰まったこと
・model.contents , model.fileに値が入らなかった
　→ name属性を定義していなかったため。
　　以下の２つは必須です。
　　　・"ngForm"を読み込ませる
　　　・name属性を定義する

## 以下、before・afterのソースコード
【before】

``` content-main.component.html
<div class="home-tweet-box tweet-box-component tweet-user">
    <input class="tweet-input" [(ngModel)]="newTweetContents" placeholder="いまどうしてる？">
    <button (click)="setTweetContents(newTweetContents)">ツイート</button>
    <input type='file' accept="image/*" (change)="onChangeInput($event)">
</div>
<img [src]=imageSrc alt="" />
```

``` content-main.component.ts
imageSrc = '';
reader = new FileReader();

onChangeInput(evt) {
 const file = evt.target.files[0];
 this.reader.onload = ((e) => {
   this.imageSrc = e.target['result'];
 });
 this.reader.readAsDataURL(file);
}
```

【after】

``` content-main.component.html
<app-tweet-form></app-tweet-form>
```

``` tweet-form.component.html
<div class="timeline-tweet-box">
  <div class="home-tweet-box tweet-box-component tweet-user">
    <form (ngSubmit)="onSubmit()" #tweetForm="ngForm">
      <div class="form-group">
        <input type='text' class="tweet-input form-control" [(ngModel)]="model.contents" #contents="ngModel" name="contents" placeholder="いまどうしてる？">
        <label class='choice-image'>
          +
          <input type='file' class="form-control" accept="image/*" [ngModel]="model.file" #file="ngModel" name="file"  (change)="onChangeInput($event)" style="display:none;">
        </label>
        <button type='submit' class="tweet-button" (click)="setTweetContents(); tweetForm.reset()">ツイート</button>
      </div>
    </form>
  </div>
  <div *ngIf="fileUrl" class="preview-image">
    <img [src]=fileUrl alt="" />
  </div>
</div>
```

``` tweet-form.component.ts
model = new TweetContents(1, '@Taka', '' , '');
  reader = new FileReader();
  fileUrl = '';
  submitted = false;

  constructor(private tweetContentsService: TweetContentsService) { }

  ngOnInit() {
  }

  onSubmit() { this.submitted = true; }

  setTweetContents(): void {
    if (this.model.contents) {
      this.tweetContentsService.setTweetContents(this.model.contents, this.fileUrl);
      this.prepareNewTweet();
    }
  }

  private prepareNewTweet() {
    this.model = new TweetContents(1, '@taka', '', '');
  }

  onChangeInput(evt) {
    const file = evt.target.files[0];
    this.reader.onload = ((e) => {
      this.fileUrl = e.target['result'];
    });
    this.reader.readAsDataURL(file);
  }
```

## まとめ
きれいになったと思われる。


読んでいただいて、ありがとうございました。
railsでGAEにデプロイしようとしたらエラーがでる


こんな感じのエラーが出るんですけどどうしたらいいですか?

macのバージョンはmacOS Mojave 10.14.2
rails はRails 5.2.2
rubyはruby 2.3.7
rbenvはrbenv 1.1.1



```ruby-build: definition not found: ruby-2.3.7
Step #1: 
Step #1: See all available versions with `rbenv install --list'.
Step #1: 
Step #1: If the version you need is missing, try upgrading ruby-build:
Step #1: 
Step #1:   cd /opt/rbenv/plugins/ruby-build && git pull && cd -
Step #1: The command '/bin/sh -c if [ ! -x ${RBENV_ROOT}/versions/${ruby_version}/bin/ruby ];     then       cd ${RBENV_ROOT}/plugins/ruby-build         && git pull         && rbenv install -s ${ruby_version}         && rbenv global ${ruby_version}         && rbenv rehash         && (bundle version > /dev/null 2>&1           || gem install bundler --version ${DEFAULT_BUNDLER_VERSION})         && rbenv rehash;     fi' returned a non-zero code: 2
Finished Step #1
ERROR
ERROR: build step 1 "gcr.io/cloud-builders/docker@sha256:xxxxxxx" failed: exit status 2```
CLI だけで CloudFormer を使って既存のリソースから CloudFormation テンプレートを取得する → できない

チラ裏. [CloudFormer を使用して既存の AWS リソースから AWS CloudFormation のテンプレートを作成する](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-using-cloudformer.html) に書いてある以下の手順を CLI だけでやりたい。

1. CloudFormer スタックを作成して起動します。
2. CloudFormer を使用して、既存の AWS リソースでテンプレートを作成し、そのテンプレートを Amazon S3 バケットに保存します。
3. CloudFormer スタックを削除します。

# TL; DR

CloudFormerがWebアプリなので、Selenium なりを使わないとできない...
YAML欲しいだけなのにナニコレ...

terraform なら terraformer とかありますね。

# 1. CloudFormer スタックの作成

以下のテンプレート、Capability、パラメータを指定すれば良い。

```
$ aws cloudformation create-stack --stack-name cloudformer \
  --template-url https://s3-ap-northeast-1.amazonaws.com/cloudformation-templates-ap-northeast-1/CloudFormer.template \
  --capabilities CAPABILITY_IAM \
  --parameters ParameterKey=Username,ParameterValue=test ParameterKey=Password,ParameterValue=test
```

EC2インスタンスやらEC2ゲートウェイやらができるので時間かかる。辛い。

CloudFormer 画面への URL を取得する

```
$ aws cloudformation describe-stacks --stack-name former-test | grep OutputValue
                    "OutputValue": "https://ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com",
```

# 2. CloudFormer にアクセスしてテンプレートを作る

取得した URL にブラウザからアクセスして、ぽちぽちしてテンプレートを作って s3 に保存する.

なんでウェブアプリ...

# 3. CloudFormer スタックを削除する


```
$ aws cloudformation delete-stack --stack-name cloudformer
```
素因数分解の現状 (量子ゲート計算編)

この記事は [Fujitsu Advent Calendar 2018](https://qiita.com/advent-calendar/2018/fujitsu) 22日目の記事です。

この記事は素因数分解の現状をまとめた一連の記事の一つです。
* [古典計算編](https://qiita.com/izutetsuya/items/ff0347d26d1699ae3a94)
* 量子ゲート計算編 (本記事)
* [アニーリング計算編](https://qiita.com/izutetsuya/items/b05c3a9e6e2dac75ef03)

(2020年06月07日変更：アニーリング計算編を作成したため、リンクを追加しました)

# 量子ゲート計算による素因数分解

量子計算とは、量子物理学によって説明される物理原理を用いた計算、もっと簡単に言うと、量子ビットを用いた計算のことです。通常の計算機（量子計算機との比べるために古典計算機と呼ぶことが多い）の記憶単位はビットと表され、0 と 1 という 2 種類の状態を記憶できます。これに対し量子ビットは 0 と 1 を同時に重ね合わせた状態を記憶することが可能です。このため、古典計算機では手に負えなかったような問題でも、量子計算機によって解くことができる可能性があります。反面、量子ビットを読み出した値は確率的（毎回同じとは限らない）であるため、量子計算機を読み出す値が高い確率で一致するような工夫が必要となります。このような工夫を量子アルゴリズムと呼びます。任意の量子アルゴリズムを実装可能な計算機を、特に、量子ゲート計算機、または量子ユニバーサル計算機と呼びます。以前は「量子計算＝量子ゲート計算」だったのですが、近年は必ずしもそうでないので、注意が必要です。本記事では、量子ゲート計算機を用いた素因数分解アルゴリズムと、その実験状況を紹介します。なお、筆者は量子計算の専門家ではないので、正確で詳細な技術内容については他記事を参照下さい [^1]。

[^1]: [量子コンピュータ関する Qiita での参考記事へのリンク](https://qiita.com/tags/%E9%87%8F%E5%AD%90%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF/items)

1994 年に Shor が考案した素因数分解アルゴリズム (Shor アルゴリズム) は、合成数 $N$ を $N$ のサイズの多項式時間で分解できるため、注目を集めました。というのも、Shor アルゴリズムを量子計算機上に実現することで、巨大な合成数を素因数分解することが可能となり、RSA 暗号が容易に解読できてしまうからです。しかし現時点では、Shor アルゴリズムは大きな脅威にはなっていません。これは、量子ゲート計算機の実現が想像以上に困難であり、多量子ビット化が思うように進んでいないからです。以下では Shor アルゴリズムによる素因数分解の概要と、その実装状況について紹介します。

## Shor アルゴリズムの概要

Shor アルゴリズムとは、量子ゲート計算機を用いた素因数分解アルゴリズムです。合成数 $N$ を分解するには、以下の手順を処理します。
1. $N$ と互いに素な (2 以上の) 自然数 $a$ を生成する
2. $\bmod{N}$ における $a$ の位数 $r$、つまり $a^r \equiv 1 \pmod{N}$ となる最小の自然数 $r$ を求める
3. $r$ が奇数なら 1．からやり直す
4. $\gcd(a^{r/2-1}-1,N)$ を計算し、出力値が $1, N$ 以外ならば終了、そうでなければ 1. からやり直す

上の処理のうち、2. 以外は古典計算機で簡単に処理できますので、Shor アルゴリズムの本質は 2. の処理です。残念ながら古典計算機はこの処理を効率的に計算することができません。そこで古典ゲート計算機の出番となります。量子ゲート計算による位数計算の具体的な方法は、本記事では扱いませんので、他記事を参照下さい。

## Shor アルゴリズムによる素因数分解実験

Shor アルゴリズムを実装した素因数分解結果を以下にまとめます。

| 年 | 実装方法| 合成数 | サイズ | 使用量子ビット数 | 文献 | 備考 |
|:---:|:----:|:----:|:----:|:----:|:----:|:----:|:----:|
|2001年12月|核磁気共鳴|15|4|7|[VSB+01]|最初の素因数分解報告|
|2007年12月|光子|15|4|4|[LWL+07]| |
|2007年12月|光子|15|4|4|[LBY+07]| |
|2009年09月|光集積回路|15|4|5|[PMO'B09]||
|2012年08月|ジョセフソン素子|15|4|3|[LBC+12]| |
|2012年11月|光子|21|5|1+$\log{3}$|[MLL+12]| |
|2016年03月|イオントラップ|15|4|5|[NMM+16]| |

Shor アルゴリズムによる最初の実験報告は 2001 年であり、核磁気共鳴 (NMR)を用いた物理環境下で 4 ビットの合成数 $N = 15$ (4 ビット) の素因数分解に成功しました。
この実験では 7 量子ビットが必要でしたが、核磁気共鳴による多量子ビット化は困難だったため、以降は他の物理現象を利用した実験が同じ合成数 $N = 15$ に対して行われてきました。具体的には、光子、光集積回路、ジョセフソン素子、イオントラップの利用結果が報告されています。素因数分解できた合成数のサイズという観点での現時点での記録は、光子を用いた $N = 21$ の分解です。なお、Shor アルゴリズムを用いて合成数 $N$ を素因数分解するには、理論的には約 $2 \log{N}$ 量子ビットが必要であるのに対し、近年の実験報告では必要量子ビット数が削減傾向にあります。これは、$N=15$ に対する Shor アルゴリズムが最適化されたためであり、Shor アルゴリズム自体が改良されたわけではないことに注意が必要です。

## 備考

2010年代に入り、量子ゲート計算機の本格的な開発が進み、数十量子ビットを処理可能な量子ゲート計算機が実現されています。しかし同時に、多量子ビット化した際のノイズが無視できず、量子的な誤り訂正が想像以上に重要であることがわかってきました。従って、例えば50量子ビットが処理可能な量子ゲート計算機であっても、計算結果が保証されるような実行性のある量子ビット数はもっと小さくなることに注意が必要です。

# まとめ

量子ゲート計算による素因数分解アルゴリズムとして、Shor アルゴリズムの概要と、その実験状況をまとめました。現時点ではまだ 5 ビット合成数しか素因数分解できていないため、Shor アルゴリズムがセキュリティに与える影響は小さいです。しかし、理論的な Shor アルゴリズムの優位性は保証されていますので、数千量子ビットが処理可能な量子ゲート計算機が実現された場合には、RSA の安全性は揺らぐことになります。Keep Factoring!
vue.js laravel5.7 動的 og タグ

OGタグ

雑に書きすぎたので修正。


概要

vue.jsを利用。
ただし、twitterbotではjsを解析できないので、bot系が来たら og を表示する。



# まずは普通に表示させる

URLは https://your.net/og/7


```web.php

Route::match(['get', 'post'] , '/og/{id}', 'OgController@index');

Route::get('/{app}', function () {
    return view('vue');
})->where('app', '.*');


```



```OgController.php

    public function index($id = "")
    {
        $title = 'タイトルだよ';
        $description = 'ここに説明文';
        $image = config('app.url').'/img/card.png';//https://your.net/img/card.png を用意してね。

        $domain = request()->getHttpHost();//your.net
        $site = '@yourtwiaccount';//ユーザー名


        return view('og', [
            'id' => $id,
            'description' => $description,
            'title' => $title,
            'image' => $image,
            'domain' => $domain,
            'site' => $site
        ]);
    }



```



```og.blade.php


<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
    <meta charset="utf-8">
    <title>{{$title}}</title>

    <meta name="description" content="{{$description}}">
    <meta name="twitter:image" content="{{$image}}" />
    <meta property="og:image" content="{{$image}}" />


    <meta name="twitter:title" content="{{$title}}" />
    <meta name="twitter:card" content="summary_large_image" />
    <meta name="twitter:description" content="{{$description}}" />
    <meta name="twitter:url" content="{{config('app.url')}}" />
    <meta name="twitter:site" content="{{$site}}" />
    <meta name="twitter:domain" content="{{$domain}}" />

    <meta property="og:title" content="{{$title}}" />
    <meta property="og:url" content="{{config('app.url')}}" />
    <meta property="og:site_name" content="{{config('app.name')}}" />
    <meta property="og:description" content='{{$description}}' />
    <meta property="og:locale" content="ja_JP" />

</head>
<body>

title<br>
{{$title}}<br><br>


description<br>
{{$description}}<br><br>

画像<br>
{{$image}}<br><br>


URL<br>
{{config('app.url')}}<br><br>


ドメイン<br>
{{$domain}}<br><br>


Twitterユーザー名<br>
{{$site}}<br><br>


</body>
</html>


```


と、ここまでやれば
https://cards-dev.twitter.com/validator

で

https://your.net/og/7

と入れれば表示される。



# それでは、twitterbot が来た場合のみ表示させる

これで
https://your.net/question/526/
に来た場合、

bot系 は og 用 view を表示
普通のアクセスは vue.js を用いて /question/526/ を表示させる 


```web.php


if(!empty($_SERVER['REQUEST_URI'])){


    if(preg_match('/\/question\//',$_SERVER['REQUEST_URI'])){

        if(preg_match("/baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator/i",$_SERVER['HTTP_USER_AGENT'])){
            Route::match(['get', 'post'] , '/question/{id}/', 'OgController@index');//ここ、 /ogp/101 で来たら、 hogeのindexへ飛ばせ。ってこと。
        } else {
            Route::prefix('question')->group(function() {
                Route::match(['get', 'post'] , 'view', 'QuestionController@view');
            });
        }
    }


}


Route::get('/{app}', function () {
    return view('vue');
})->where('app', '.*');

```
bitbucketからgithubにレポジトリを移行してみた

# やること

githubが無料でprivateレポジトリが使えるようになったということで個人で使っているアカウントをgithubに移行してみた。

# 状況

* すでにbitbucketにリモートレポジトリがある
* ローカルにgitもコードもある
* gitの履歴なども一緒にbitbucketからgithubに移行したい

# remoteのurlを変更する

```
git remote set-url origin URL
```

このあとpush

```
git push -u origin master
```

https://qiita.com/ironsand/items/6c301fef730d53f35bc3

# 参考

https://help.github.com/articles/changing-a-remote-s-url/

ミラーでやるならこれが詳しそう

https://qiita.com/TsutomuNakamura/items/058cb851a61bbb1f715b
postgresがPG::ConnectionBad: could not connect to server: No such file or directory 17:02:08 web.1    | 	connections on Unix domain socket "/tmp/.s.PGSQL.5432"?と出て起動しない

# 環境
- macOS
- Homebrewでpostgres入れた

# 状況
```
PG::ConnectionBad: could not connect to server: No such file or directory
17:02:08 web.1    | 	connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
```
というエラー。
よくある[これ](https://stackoverflow.com/questions/19828385/pgconnectionbad-could-not-connect-to-server-connection-refused)はできず（`rm postmaster.pid`が見つからない）。

`tail /usr/local/var/log/postgres.log`
をすると、

```
dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib
  Referenced from: /usr/local/bin/postgres
  Reason: image not found
```
が出てくる。

Postgresコマンドを実行しても同じエラーが出る。

psqlコマンドだとこういうエラーが出る、

```
psql: could not connect to server: No such file or directory
	Is the server running locally and accepting
	connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
```

# 解決
これでpostgres Updateしたら直った。。
http://carefree-se.hatenablog.com/entry/2016/12/18/005421

`libicui18n.62` が原因？上記の方法でやったら、`postgres@11`にアップデートにする中で、`libicui18n.63`になって動くようになった。
MacBookを閉じたときにスリープを防ぐ方法 (Monterey対応)

MacBook の蓋を閉じたときも含め、すべてのスリープ機能を一時的に無効にする方法です。
AC電源に接続していないときでもスリープしなくなってしまうので注意してください。

※蓋を閉じたときではなく通常の時間経過によるスリープを無効化したい場合は、システム環境設定の「省エネルギー」から行うことができます。

スリープを無効化中も、システム環境設定→「Dock」→「ホットコーナー」から設定することでディスプレイをスリープすることはできます。

# スリープを無効にする方法
1. 「アプリケーション」フォルダ→「ユーティリティ」フォルダにある「ターミナル」を開く
2. 以下のコマンドを入力し、Enterキーを押す

```shell
sudo pmset -a disablesleep 1
```

スリープが無効になっているかは、Apple メニューの「スリープ」が、グレーになってクリックできない状態になっているかどうかで判断できます。

# 元に戻す方法
上のコマンドの `1` を `0` にして実行します。

```shell
sudo pmset -a disablesleep 0
```

# ステータス確認

```shell
pmset -g
```

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155587/2cba52ed-979b-c45a-5dfd-ff02527d748d.png)

# クラムシェルモードについて

外付けディスプレイを接続していると蓋を閉じたときにスリープしない場合があります。その際はクラムシェルモードをオフにするとスリープするようにすることができます。
復元モード (`Command+R`) で起動してユーティリティ→ターミナルから以下のコマンドを実行します。

```sh
nvram boot-args="niog=1"
```

# 参考
https://support.apple.com/ja-jp/HT200106
https://discussionsjapan.apple.com/thread/110190796

# エイリアス
`~/.bashrc` ファイルに以下を書き込むことで `sleepon` `sleepoff` で無効化/有効化が可能になります。

```shell:~/.bashrc
alias sleepon='sudo pmset -a disablesleep 0'
alias sleepoff='sudo pmset -a disablesleep 1'
```
[書籍]たった2日でマスターできるiPhoneアプリ開発集中講座で「はまった」点と解決方法【2日目】

このメモでは、書籍「[たった2日でマスターできるiPhoneアプリ開発集中講座 Xcode 10　Swift 4.2対応](http://www.socym.co.jp/book/1187)を読みながら試していく際に、手順通りに行っても同じように実行できずに、はまった点と解決方法について述べています。この記事は、2日目分となります。（1日目分は[こちら](https://qiita.com/TaroNakasendo/items/09ec5c68ff62beb2dbee)です)
#【2日目】

|Page|問題点|原因|解決方法|備考|
|----|-----|----|-----|----|
|P215|プロジェクトの作成方法が書いていない。|すでに何回もやっているので省いた？|これまでのプロジェクトと同様に作成する。名前は、「MyTimer」とする。|新規に作成できると、このページと同じ状態になる。|
|P237|保存場所の選択画面が、図と違う。|フォルダの表示方法が、Listではなく、Column（3列表示）になっている。|３列表示になっている場合は、MyTimerの中のMyTimerフォルダ(中央の列のMyTimerフォルダ)を選択する。|List表示に切り替えると書籍と同じになる。|
|P238|SettingViewControllerが、外側のMyTimerフォルダ内に作成されている。|NewFile...を選択する際に、内側のMyTimerフォルダ内で右クリックしなかった。|NavigatorのSettingViewController.swiftをドラッグ&ドロップして、内側のMyTimer内に移動する。|実際のファイルの作成位置も一つ内側のフォルダに移動される。|
|P253|\\が入力できない。|キーボードによっては、「\\」キーを押しても違う文字が入力される。|「バックスラッシュ」と入力してから変換する。|「¥」では代用できないようだ。書籍のP255によると、日本語キーボードでは、「option (Alt)」+「¥」でも可能とのこと。|
|P278|Debug View Hierarchyボタンをクリックしたら、元のレイアウトに戻れない。|通常モード？を表示するボタンがない |画面の一番左上の「Show the Project navigator」ボタンをクリックし、ViewController.swiftを再度選択する。|コードを表示するだけなら、中央のエディタエリア上部にある「<」(Go Back)ボタンでも戻ることができる。|
|P309|TwitterとFacebookに投稿しようとすると落ちる。それ以外のメールやメモに追加などでは落ちない。|機種によっては画像のサイズが大きすぎるため、落ちるとのこと。|画像を縮小する必要があるが、現時点では、コードが複雑となるため、このまま進める。|公式サポートページのWebフォームより問い合わせると、すぐに(数時間で)回答をいただきました。|
|P328|Document Outlineに、Effect View Controllerではなく、View Controllerが２つある。|3-2の手順をまだ実行していない。|3-2の手順を実行する。|画面は、実行後の状態で、実行前は、図と異なります。|
|P334|Add 13 Constraints ではなく、 Add 14 Constraints　になる。|ボタンが２つ重なっていて見えなくなっていたようです。|一度制約を解除して、不要なボタンがあれば削除して、やり直す。|制約を解除するには、右上のShow the Size Inspectorボタンを押して、各ボタンの全てのConstrainsをdeleteボタンで削除する。|
|P335|ボタンが上下に３つ綺麗に並ばない|制約付けする前のボタンの位置が上下に３つ並んでいない。|一度制約を解除して、ある程度ボタンを上下に３つ並べてからやり直す。|ボタンが左右に並ぶことがあると、そのボタン同士で左右の制約ができてしまう。|
|P347|Instance member 'createCGImage' cannot be used on type 'CIContext';というエラーが出る。|CIContext.createCGImage()になっている。|インスタンスのciContext.createCGImage() (小文字で始まる)に修正する。|大文字と小文字の違いで全く別の意味になるので注意する。|
|P385|シミュレータではなく、実機で実行しようとすると、「App Installation faild - The maximum number of apps for free development profiles has been reached」エラーとなる。|実機に４つ目のアプリを登録しようとした。|「設定」ー「一般」-「プロファイルとデバイス管理」-「デベロッパAPP」-「Appを削除」を行ってから、再度実行する。または以前に作成したいずれかのAppアイコンを長押しして、✖️をタップして削除しても良い。|Xcodeの無料版では実機に一度に配置できるアプリの数は３つまでという制限がある。シミュレータでは数の制限が無いようです。|
|P386|req_urlがnilになってしまい、正常にリクエストURLが作成されない。Outputに、(lldb)と表示される。|URLとして不正な、エンコードされていない文字(全角文字など)が入っている。|URLとして使用できない文字が入っていないかどうか確認し、あったら削除する。|私の場合は、&が全角の＆になっていた箇所があった。|

 [1日目分](https://qiita.com/TaroNakasendo/items/09ec5c68ff62beb2dbee)の記事からもう12日も経ってしまいましたが、なんとかSwiftによるiPhoneアプリの開発をマスターできました。思ったよりも時間がかかってしまいましたが、以前Objective-Cで挑戦したときよりは、細かい内容まで時間をかけて考えられたので理解が深まった気がします。また、以前（〜2015年）は、有料のApple Developer Program に参加しないと、実機での開発はできなかったのですが、App Storeに載せないのであれば、無料でも開発できるように変わっていたりして、iPhoneアプリの開発に対して、敷居が下がっている気がします。今後は、Deep Learningとアプリを組み合わせたりしていけたらと思います。「2日でできる！」に釣られて本書を買ってしまいましたが、アプリ開発の理解の第一歩として良いきっかけでした。最後になりましたが、Webフォームでのお問い合わせにすぐに応じていただいたサポートの皆様、ありがとうございました。
No usable default provider could be found for your system.

UdacityのLinux Command Line Basics
のLesson 1のセットアップをしていたら、以下のエラーが出ました。

VirtualBoxを最新6.0.0にしたら解決しました。

$ vagrant up

No usable default provider could be found for your system.

Vagrant relies on interactions with 3rd party systems, known as
"providers", to provide Vagrant with resources to run development
environments. Examples are VirtualBox, VMware, Hyper-V.

The easiest solution to this message is to install VirtualBox, which
is available for free on all major platforms.

If you believe you already have a provider available, make sure it
is properly installed and configured. You can see more details about
why a particular provider isn't working by forcing usage with
`vagrant up --provider=PROVIDER`, which should give you a more specific
error message for that particular provider.
Sass 入れ子で要素にもクラスを付ける

どう説明していいか分からないですが。


```
.test {
    background-color: #fff;
}
p.test {
   background-color: #f00;
}
```

を Sass の入れ子でどう書くか

```
.test {
    background-color: #fff;

    @at-root {

        p#{&} {
            background-color: #f00;
        }
    }
}
```

で多分大丈夫かと。
pythonでログイン認証ありサイトからスクレイピング

#目的
毎回ログイン認証するのが面倒なので。

#参考サイト
こちらを参考にしました。
[Python + Selenium で Chrome の自動操作を一通り](https://qiita.com/memakura/items/20a02161fa7e18d8a693)

#環境
Windows10 home 64bit
python3.6.5

#準備
```
pip install selenium
pip install chromedriver-binary 
```
ChromeDriver を Python でのみ利用するため実行ファイルはダウンロードせず、コード内でchromedriver-binaryをimportします。

#実行
コードはこちら 
[gist](https://gist.github.com/meznat/6e00f635528ee56bf98378b8d8bca409)

はじめに、安全のためログインID・パスワードを環境変数へ書き出し、実行のたびに環境変数から読み込むようにします。

```.py
#書き込み
import os
os.environ["MY_LOGIN_ID"] = "YOUR_LOGIN_ID"
os.environ["MY_LOGIN_PASSWORD"] = "YOUR_LOGIN_PASSWORD"

```

メインクラスを作成します。

```ScrapeLoginAuthSite.py
import chromedriver_binary
from selenium import webdriver

class ScrapeLoginAuthSite():
    def __init__(self,username,password):
        self.username = username
        self.password = password
        self.url = "WEBSITE_URL"
        #chrome driver -headless mode
        options = webdriver.ChromeOptions()
        options.add_argument('--headless')
        self.driver = webdriver.Chrome(options=options)
        #if you want debug 
        #self.driver = webdriver.Chrome()
```
実際はheadlessモードで実行しますが、ブラウザを表示し画面の挙動を確認しながら実行するには`options`を無効にします。

認証を行うメイン関数を実装します。実際のログイン画面を見ながら取得する要素を決定します。こちらのサイトが参考になりました。[Selenium API(逆引き)](http://www.seleniumqref.com/api/webdriver_gyaku.html)
最後に`submit_button.submit()`で認証ボタンを押します。

```ScrapeLoginAuthSite.py
    def main(self):
        driver = self.driver
        #Login window
        print("login window open")
        driver.get(self.url)
        username_box = driver.find_element_by_id("userId")
        username_box.send_keys(self.username)
        password_box = driver.find_element_by_id("password")
        password_box.send_keys(self.password)
        submit_button = driver.find_element_by_id("loginButton")
        submit_button.submit()
```
ログインが成功したら、任意の要素を取得し、テキストを返します。

```ScrapeLoginAuthSite.py
    # Mypage window
        if "https://MYPAGE_URL" in driver.current_url:
            print("Mypage window open")
            element = driver.find_element_by_id("element_id")
            return element.text 
```
最後にブラウザを閉じて終了します。

```ScrapeLoginAuthSite.py
# destractor
    def __del__(self):
        print("del:driver")
        self.driver.quit()
```

実装が完了したら、以下のように実行します。

```.py
if __name__ == "__main__":
  login_id = os.environ.get("MY_LOGIN_ID")
  login_pass = os.environ.get("MY_LOGIN_PASSWORD")
  text = ScrapeLoginAuthSite(login_id,login_pass).main()
```

以上
git diff 実行時に nkf コマンドが無いって怒られた話

2019年の初記事ですね。
今年もたぶんこんなのが多くなりますがよろしくお願いいたします。

というわけで今日の話です。

## 環境
- Windows 8.1(今時めずらしい)
- Git for Windows 2.20.1

## 事の発端
とある作業中、ステージング前の差分確認のため `git diff {%filename%}` を打ってみたところ、下記のようなメッセージが表示されました。

```sh
$ git diff
nkf -s | LESSCHARSET=utf-8 less: nkf: command not found
```

less ってキーワードから察するにページャー動作付近の問題に見えます。ただ、 less の前にパイプでつながっている nkf のコマンドがなくて今回はエラーになっているようです。

## そもそも nkf ってなに？
[Network Kanji Filter - Wikipedia](https://ja.wikipedia.org/wiki/Network_Kanji_Filter)

> Network Kanji Filter（またはnkf）は異なる文字コード間の変換を行うソフトウェア、そのAPI。

ネットワーク漢字フィルターの頭文字をとって nkf らしいです。まさかの日本語( ﾟДﾟ)まあ細かいことはよくわかりませんが文字コード変換周りに使うソフトってことですかね(雑

### パス確認
一応確認してみます

```
$ which nkf
which: no nkf in (/*****)
```

### 実行ファイル確認
こちらも念のため確認します。"Program Files" をコマンドに含めるとスペースのせいで面倒ｗ

```sh
$ ls /c/Program\ Files/Git/bin/ | grep nkf
$ ls /c/Program\ Files/Git/usr/bin/ | grep nkf
```

パスも通ってないし、実行ファイルもないということで nkf をインストールすることにします。

## nkf のインストール
[Mac と Windows に nkf をインストールする - Corredor](http://neos21.hatenablog.com/entry/2018/04/10/080000)

ネット上にいろいろ記事はありますが個人的に上記エントリが非常にわかりやすかったです。
windows 用は tar コマンドで解凍するように記載がありますが、windows の場合は環境によって tar コマンド使えない場合もあるので、その場合はふつうに [**7-Zip**](https://sevenzip.osdn.jp/) などの解凍ソフトでOKです。余談ですが7-zipはけっこう優秀で個人的には気に入ってます。


## インストールがおわったら
再度 git diff してみます。

```diff
$ git diff
diff --git a/lib/********************.rb b/lib/********************.rb
index 911f53edf..87c1ddaf4 100644
--- a/lib/********************.rb
+++ b/lib/********************.rb
```

なおりましたね！

## なんだったのか
今回、問題が起きた端末は実は人のおさがりで、Gitのバージョンも1.8系で古い状態でした。Git for Windows を最新に上げたり、もろもろ環境の作り直しをしていたのですが、git のページャーの設定は古いままだったのかもしれません。(推定ですが。)

めったにないケースだとおもいますが、もし似たような事象を見かけたら参考にしてみてください。
Node.jsでpsqlコマンドがうまくいかないとき

# 環境
- macOS
- PostgreSQLはHomebrewで入れてある

# エラーメッセージ
```
[Sun Jan 13 2019 00:28:27 GMT+0900 (Japan Standard Time)] ERROR { Error: ENOENT: no such file or directory, open './config/app.yml'
    at Object.openSync (fs.js:439:3)
    at Object.readFileSync (fs.js:344:35)
    at Object.readConfig (/Users/hidehiro/code/hidehiro98/line-bot-database/node_modules/yaml-config/lib/yaml-config.js:57:25)
    at Object.<anonymous> (/Users/hidehiro/code/hidehiro98/line-bot-database/node_modules/psql/lib/config.js:2:23)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Module.require (internal/modules/cjs/loader.js:637:17)
  errno: -2,
  syscall: 'open',
  code: 'ENOENT',
  path: './config/app.yml' }
Usage: ../../../.nodebrew/node/v10.15.0/bin/node ./node_modules/.bin/psql [query] [database]
とでる。
```

# 解決
`mv ./node_modules/.bin/psql ~/`とでもしてnodeのpsqlを使わないようにすると、Homebrewのpsqlが使われて直った
東京公共交通オープンデータチャレンジに、応募してみた。その２

#概要

東京公共交通オープンデータチャレンジに、応募してみた。
バスリンク

#応募の手順

説明、ヘルプを書く。
写真を撮る。
ビデオを撮る。

#応募時、413 Request Entity Too Largeが出た。

画像をダイエットした。

#成果物

https://www.youtube.com/watch?v=avyOmK6-X_A
http://jsrun.it/ohisama1/q8mi
http://jsrun.it/ohisama1/yRMZ

以上。
手軽に虹色を生成する

<h2>実行例</h2>

ブラウザのアドレスバーに以下を入力すると、ページの内容がクリアされ、背景が虹色に変化する。

<pre>
javascript:body=document.getElementsByTagName("body")[0];body.innerHTML="";x=0;id=setInterval(()=>{x+=5;r=128+127*Math.cos(x/180*Math.PI);g=128+127*Math.cos((x+120)/180*Math.PI);b=128+127*Math.cos((x-120)/180*Math.PI);body.setAttribute("style",`background-color:rgb(${r},${g},${b});`);},100);
</pre>

以下を入力すると、色の変化が停止する。

<pre>
javascript:clearInterval(id);
</pre>

<h2>コード</h2>

<pre>
body = document.getElementsByTagName("body")[0];
body.innerHTML = "";
x = 0;
id = setInterval(() => {
  x += 5;
  r = 128 + 127 * Math.cos(x / 180 * Math.PI);
  g = 128 + 127 * Math.cos((x + 120) / 180 * Math.PI);
  b = 128 + 127 * Math.cos((x - 120) / 180 * Math.PI);
  body.setAttribute("style", `background-color: rgb(${r}, ${g}, ${b});`);
}, 100);
</pre>

<h2>コア部分</h2>

<pre>
  r = 128 + 127 * Math.cos(x / 180 * Math.PI);
  g = 128 + 127 * Math.cos((x + 120) / 180 * Math.PI);
  b = 128 + 127 * Math.cos((x - 120) / 180 * Math.PI);
</pre>

角度(位相)を120度ずつずらすことで、
`rとgとbのうち1つが強い時は他の2つが弱い`
`rとgとbのうち2つが強い時は他の1つが弱い`
という関係になる。

イメージとしては<a href="https://www.google.com/search?q=%E4%B8%89%E7%9B%B8%E4%BA%A4%E6%B5%81&source=lnms&tbm=isch&sa=X&ved=0ahUKEwiYlOSby-zfAhUHA4gKHfokAcMQ_AUIDigB&biw=1523&bih=780">三相交流</a>が近い。

ここでは簡単のため、1周期を360としている。

<h3>メリット</h3>
R,G,BやC,M,Yといった原色を通らないので、（彩度は落ちるが）やさしい印象になる。
色相を例えば5分割にしたいとき、360を5で割れば済むので便利。

<h3>デメリット</h3>
三相交流のイメージがないと分かりにくい。

<h2>原色を通るようにする</h2>

<pre>
body = document.getElementsByTagName("body")[0];
body.innerHTML = "";
x = 0;
id = setInterval(() => {
  x += 0.1;
  r = Math.min(Math.max(Math.abs((x + 5) % 6 - 3) - 1, 0), 1);
  g = Math.min(Math.max(Math.abs((x + 3) % 6 - 3) - 1, 0), 1);
  b = Math.min(Math.max(Math.abs((x + 1) % 6 - 3) - 1, 0), 1);
  body.setAttribute("style", `background-color: rgb(${r*255}, ${g*255}, ${b*255});`);
}, 100);
</pre>
M -> R -> Y -> G -> C -> B -> M ...
こちらも位相をずらしている点では同じ。

ここでは簡単のため、1周期を6としている。

<h3>メリット</h3>
原色とその組み合わせで線形に表現できるので、分かりやすい。
色相を例えば5分割にしたいとき、6を5で割れば済むので便利。

<h3>デメリット</h3>
強いて言えば、上記の例が簡単な書き方の一例でしかない。
例えばx<0では使えない。
Asciidocの編集環境を作る

# はじめに
Asciidocの編集環境を構築する手順を解説します。
Asciidocで文章を書く利点とかは[ここ](https://qiita.com/hyt126/items/7a070bc2b1e185b9146f)を参照。

# 構築する環境
- ruby(ubuntuなら多分デフォルトで入っている，18.04LTSは入ってなかった)
- graphviz(グラフ描くのに何かと使う)
- jdk8(PlantUMLでUML描くのに必要)
- Visual Studio Code
- Asciidoctor

# 想定環境
以下の環境を想定して環境構築方法を解説します。

- Windows
    - chocolateyがインストール済み
        - 環境構築がまだの場合は[こちら](https://qiita.com/hyt126/items/7ea279327da05a63ec23)を参照
- Linux
    - ubuntu等、aptが使える環境

# Windowsでの環境構築
chocolateyを使って構築していきます。ただし、rubyのインストールに以下の注意点があるので、chocolateyを使うかは自分で判断してください。

## Windowsでの環境構築の注意点
chocolateyでcup all -yでアップデートをかけたところ、新しいバージョンのrubyがインストールされ、新しいバージョンがpathで優先されるよう自動で設定されてしまいました。
これだとgemコマンドを叩いたときに新しい方のruby環境のgemが動いてしまうので都合が悪いです。こうなった場合、追加で入った方をパスから削除する必要があると思います。

また、知らないうちにrubyの環境が複数出来て、優先度が変わるのは開発環境として嬉しくないので、rubyは手動で[windowsのインストーラー](https://rubyinstaller.org/)を使っていれるのも良いかと思います。

## インストールコマンド
```
cinst ruby -y
cinst graphviz -y
cinst jdk8 -y
cinst vscode -y
```

以降は、上記のrubyとvscodeがインストールされたあとに実行

```
gem install bundler
gem install asciidoctor
gem install asciidoctor-pdf --pre
gem install asciidoctor-pdf-cjk
gem install asciidoctor-diagram
gem install coderay
gem install rouge
gem install concurrent-ruby
code --install-extension joaompinto.asciidoctor-vscode
```

## 環境変数の設定
以降は、インストールしたバージョンに併せて読み替えてください。

pathにgraphvizのbinディレクトリの場所を追加する

```
C:\Program Files (x86)\Graphviz2.38\bin
```

GRAPHVIZ_DOTにdotの場所を追加する。

```
C:\Program Files (x86)\Graphviz2.38\bin\dot.exe
```

# Linuxでの環境構築
```
sudo apt -y install ruby
sudo apt -y install graphviz

# java setup, for plantuml
sudo add-apt-repository ppa:webupd8team/java
sudo apt -y update
sudo apt -y install oracle-java8-installer

# vscode
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list'
#↓ないとGPG エラー: https://packages.microsoft.com stable InReleaseが出る
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EB3E94ADBE1229CF
sudo apt -y update
sudo apt -y install code
```

以降は、上記のrubyとvscodeがインストールされたあとに実行

```
sudo gem install bundler
sudo gem install asciidoctor
sudo gem install asciidoctor-pdf --pre
sudo gem install asciidoctor-pdf-cjk
sudo gem install asciidoctor-diagram
sudo gem install coderay
sudo gem install rouge
sudo gem install concurrent-ruby

code --install-extension joaompinto.asciidoctor-vscode
```

# Visual Studio Codeの設定
環境構築のところで入れた拡張機能によって、vscodeでasciidocのプレビューができるようになっています。
デフォルトではjavascriptのライブラリを使って、実行するようになっていますが、このままだとgrapvizなどのグラフのプレビューができないので設定を変更します。

設定→asciidoctorと絞りこんで、以下のように設定します。

- asciidotor_command
    - asciidoctor -r asciidoctor-diagram
- use_asciidoctor_js
    - false(チェックを外す)

![vscode設定](https://qiita-image-store.s3.amazonaws.com/0/99189/4a38c7c9-7339-2cae-07e3-ceaa9b2d21a1.jpeg)

以上で、asciidocのvscodeでプレビューしながら編集することができます。

![編集画面](https://qiita-image-store.s3.amazonaws.com/0/99189/98aefd5a-49b1-aefd-4503-ae627540c74b.jpeg)

# サンプル
私が作ったサンプルを以下においています。
https://github.com/hayato-m126/AsciidoctorSample
Asciidocのプレビュー環境を作る

# はじめに
Asciidocをプレビューする環境を構築する手順を解説します。
Asciidocで文章を書く利点とかは[ここ](https://qiita.com/hyt126/items/7a070bc2b1e185b9146f)を参照。

# 作業手順
1. ChromeかFirefoxに拡張機能Asciidoctor.js Live Previewを入れる。(Chrome推奨。理由は後述)
2. 拡張機能の設定を変更する

## Asciidoctor.js Live Preview
Asciidoctorの拡張機能、Chrome,Firefox用が提供されている。アドオンサイトから検索して導入する。

### Chrome推奨理由
Firefoxだとローカルにあるファイルのプレビューは出来たが、ウェブにあるファイルがブラウザ上で直接開けずダウンロードになったり、開けてもレンダリングされませんでした。よって、Chromeを推奨します。

ローカルにダウンロードしてから見る前提であればFirefoxでも特に不都合はなかったです。

## 拡張機能の設定
インストール後に拡張機能の設定を変更する。
Chromeの画面を例に解説します。

1. 拡張機能からAsciidoctor.js Live Previewの詳細を選択
2. 「ファイルのURLへのアクセスを許可する」を有効にする
3. 拡張機能オプションを選択し、「safe mode」をsafeにする。

![拡張機能設定](https://qiita-image-store.s3.amazonaws.com/0/99189/8bb60a3c-2eec-476e-1627-1254569598e9.jpeg)

これだけで、adoc, asciidoc, asc, adの拡張子のファイルをプレビューしてくれます。

# 拡張子毎の動作の違い
ローカルにあるadoc, asciidoc, asc, adについては、プラグインを用いてどのファイルも表示出来ます。ウェブに置かれているファイルについては拡張子毎に動作が違います。

Gitのバージョン管理サーバーと、ウェブサーバーにasciidocのファイルを置き、Chromeでアクセスして拡張子毎に動作の違いを調べ、以下の結果を得ました。

GitのサーバーについてはRAW表示したときの動作。
ブラウザ拡張機能でプレビューが見れるのを○としています。

||Github|Gitlab|Bitbucket|Gitbucket|Apacheウェブサーバー|
|:---|:---|:---|:---|:---|:---|
|**adoc**|○|○|○|○|○|
|**asciidoc**|○|○|○|○|○|
|**asc**|○|○|○|ダウンロード実行|ダウンロード実行|
|**ad**|untitled|○|untitled|untitled|○|

ローカルにファイルをダウンロードすることになしに、ブラウザ上で簡単にプレビューができるという都合を考えると、作成するファイルの拡張子はadocかasciidocが良いということになりそうです。
拡張子の長さも考慮するとadocでしょうか。

# プレビューを試す
試しにgithubで公開されているPro Git日本語版のファイルをプレビューしてみます。

1. https://github.com/progit/progit2-ja にアクセスする
2. 適当なascファイルをクリック。例えば、ch01-introduction.asc
3. RAWを押す(ascファイルを直接で開く)
4. プラグインによりレンダリングされ画像のような感じに表示されるはずです。

![プレビュー](https://qiita-image-store.s3.amazonaws.com/0/99189/21abd51d-964d-507e-ac01-22eaed0e11d0.jpeg)

# サンプル
私が作ったサンプルを以下においています。
https://github.com/hayato-m126/AsciidoctorSample
Asciidocで技術文章を作成する

# はじめに
Asciidocは、Markdownとほとんど同じような記述法でお手軽にかけて、規模の大きい文章を書くことにも適しています。

例えば、[Pro Git](https://git-scm.com/book/ja/v2)は、日本語版PDFで500ページを超えるGitの解説書ですがAsciidocで書かれています。

ソフトウェアの設計書など、そこそこの規模になる技術文章を記述するのにAsciidocが良いと思い導入してみました。
参考にしたページの紹介と、実際に使ってみて、感じた利点などを紹介します。

# 参考
以下のリンクのComparison by exampleにMarkdownの記法と比較して、どう書くかが記載されているので参考になります。

[AsciiDoc vs Markdown, asciidoctor docs](https://asciidoctor.org/docs/asciidoc-vs-markdown/)

少し分量が多いですが、日本語化されたリファレンスもあります。

[Asciidoctor 文法クイックリファレンス(日本語訳)](https://takumon.github.io/asciidoc-syntax-quick-reference-japanese-translation/)

とりあえず、Markdownの書き方の違いを確認すれば書き始められるでしょう。

# 利点
- テーブルの結合が使える。テーブル内で箇条書きや、画像挿入等も可能
    - USDMなどを書くのに便利
- 動画を直接埋め込める
    - Markdownではアニメーションgifを活用するのが一般的。asciidocならyoutubeを直接埋め込める
- 外部ファイルをincludeできる。
    - asciidocのファイルを分割して他のファイルから読み込める。TeXのように使える。長いドキュメントを作るにはほぼ必須機能。
        - Pro Gitはチャプターごとに分割して作られていた。
    - ソースコードを読み込んで文章にそのまま貼れる
    - dotファイル、PlantUMLなどの図の元となるテキスト形式ファイルを読み込める
- ブラウザの拡張機能で簡単にプレビュー環境をつくれる。([別記事参照](https://qiita.com/hyt126/items/9503ac50ab72553d1032))
    - Githubなどのバージョン管理サーバー上での文章レビューがやりやすい。レビューワーにも優しい
- vscodeでリアルタイムプレビュー付きの編集環境を作れる([別記事参照](https://qiita.com/hyt126/items/fdeff36f09bb221dfac0))
- asciidoctor-pdfでそこそこな見栄えのPDF文章を出せる
    - 仕事で文章を残すのに、表紙だけワード等の指定フォーマットで作って合成できる。
- テキストなのでバージョン管理しやすい
    - ソースコードと一緒に設計文章もgitで管理できる

上記のような利点があり、ソフトウェアの設計文章を作るのに向いていると思っています。
Markdownより高機能で、TeXよりもお手軽な文章作成環境という印象です。

# 現状認識している欠点
使っていて、以下の点が気になりました。

- 画像の読み込みが相対パス指定
    - includeで別ファイルを読み込んだ場合は、呼び出し側のファイルから相対パス

例えば、Pro Gitのフォルダ構成は以下のようになっており、ルートにあるチャプターファイルで章の中のセクションファイルをincludeしています。

```
│  チャプター1.asc (この中でbook配下のセクションを読み込んでいる)
|  チャプター2.asc (この中でbook配下のセクションを読み込んでいる)
|  ・・・
|
├─book
│  ├─チャプター1フォルダ
│  │  └─セクションフォルダ
|  |        セクション1.asc
|  |        ・・・
│  ├─チャプター2フォルダ
│  │  └─セクションフォルダ
|  |        セクション1.asc
|  |        ・・・
|
├─images
|       すべての画像ファイル
|
```

しかし、セクションのファイルから読み出す画像ファイルの指定は、チャプターからの相対パスなので、画像の読み込みはimage::images/xxx.pngのような形で指定します。
これだと、セクションファイルを単体で開いたときに自分の配下にimagesフォルダはないので読み込みが出来ません。
TeXに慣れていると、この辺の動作の違いに戸惑います。

せっかく、include機能でファイルを分割して作成できるのに、画像が読み込み側からの相対パス指定となると、分割したファイルがどうincludeされるのか意識して、パスの指定をする必要が出てきてしまいますので、この仕様はいまいちだと思っています。

imagesdirコマンドで、画像を読み込む基準のディレクトリを変更することが出来ます。都度ディレクトリを指定するということも考えられますが、asciidocのファイルと、使用する画像は同じフォルダに置くか、サブフォルダに画像フォルダを作るといったように、予めフォルダ構成を考えた方が懸命かと思います。

# 拡張子何にするか
adocが良さそうです。
理由は[ここ](https://qiita.com/hyt126/items/9503ac50ab72553d1032#%E6%8B%A1%E5%BC%B5%E5%AD%90%E6%AF%8E%E3%81%AE%E5%8B%95%E4%BD%9C%E3%81%AE%E9%81%95%E3%81%84)

# 仕事で使う場合の文章作成プロセス案
以下のような感じでやれば、文章の改定も管理出来て、良いかなと思っています。

1. バージョン管理サーバーのmasterブランチからpullする
2. 編集用にブランチを切って，文章を作成する
3. 完成した文章をコミット＆プッシュ
4. バージョン管理サーバー上でプルリクエストを投げる
5. バージョン管理サーバー上で承認行為を行う。
6. 承認者が内容を確認したら，ワードやエクセル製の社用の独自の表紙に記名日付を入れて表紙のPDFを保存する
7. 承認者が表紙をコミット＆pushし，マージする。
8. Jenkinsのジョブで自動でPDFを作成する。
9. 出来上がったPDFを適当な場所に配布(PDF合成のジョブの中で一緒にやる)

# asciidoctor-pdfで独自の表紙を合成するコマンド
本体はsample.adoc、表紙はcover.pdfの場合

```
$ asciidoctor-pdf sample.adoc -o sample.pdf -a notitle -a front-cover-image=image:cover.pdf[] -n -r asciidoctor-diagram
```

# サンプル
私が作ったサンプルを以下においています。
https://github.com/hayato-m126/AsciidoctorSample
SRE_1章

# はじめに

* SRE（サイトリライアビリティエンジニアリング）とは何か？→エンジニア、システムの信頼性を向上させる者、運用について考慮する者

# 第Ⅰ部 イントロダクション

* 第Ⅰ部では、SREとは何か、そしてSREがIT業界における従来型手法と何が異なるかをみていく。

## 第1章 イントロダクション

### 1.1 サービス管理へのシステム管理者のアプローチ

* シスアドを用意することと、開発と運用を分断することの利点と欠点について
* 基本的に、開発は新しい機能を早くリリースしたい、運用は変更をしたくない、と考えているので対立する

## 1.2 サービス管理へのGoogleのアプローチ：サイトリライアビリティエンジニアリング

* SREチームにとってスキルセットの多様性は重要
* GoogleのSREチームでは運用にあてる作業時間を50%以下に抑えるように定めた
* SREチームのメンバー採用は、求めるものが高いため難しい

## 1.3 SREの信条

* 各SREチームの持つべき信条は同じ
* SREチームは、サービスの可用性、レイテンシ、パフォーマンス、効率性、変更管理、モニタリング、緊急対応、キャパシティプランニングに責任を持つ

### 1.3.1 エンジニアリングへの継続的な注力の保証

* SREが行う運用作業の量が50%を超過した場合、超過分を開発チームに差し戻す
* インシデント後にはポストモーテム（障害報告書みたいな）を書く
* SREチームと開発チームの関わりは https://qiita.com/san-tak/items/1e8a6aae062c5f6c4c64 の下のほうの図が分かりやすい

### 1.3.2 サービスのSLOを下回ることなく、変更の速度の最大化を追求する

* **100%を信頼性の目標とすることは、基本的にいかなる場合にも間違っている**という所見のもと、サービス障害を悪とみなさず、開発とSREの対立構造を解消する

### 1.3.3 モニタリング

* 人間に判断、解釈させるようなアラートを出してはならない
* 効果的なモニタリング出力には3種類ある

1. アラート：人間が即座にアクションを起こして対応し、状況を改善しなければならないことが生じていることを知らせる
2. チケット：人間がアクションを起こさねばならないことを知らせる（即座でなくてもよい）
3. ロギング：人間が見る必要がないもの。診断やフォレンジックに使用

### 1.3.4 緊急対応

* 緊急対応の評価にはMTTRを使う
* 人間の作業を介さないシステムが良い
* オンコールエンジニアの出番となった場合に備え、事前に十分な手順書を用意しておく

### 1.3.5 変更管理

* 70%のサービス障害は、動作中のシステム変更によっておこる
* 自動化で以下を実現することを目指すべき
  * 漸進的なロールアウトの実装
  * 高速かつ正確な問題の検出
  * 問題が生じた際の安全なロールバック

### 1.3.6 需要の予測とキャパシティプランニング

* 以下のステップでキャパシティプランニングを実施する
  * 自然な需要の正確な予測。この予測は、キャパシティのリソース確保に必要なリードタイムも踏まえる
  * 需要予測に突発的な需要の発生源を正確に織り込む
  * 計算リソースのキャパシティ（サーバー、ディスク等）とサービスのキャパシティの関連を把握するための、定期的なシステム負荷テスト

### 1.3.7 プロビジョニング

* プロビジョニングは変更管理とキャパシティプランニングの組み合わせ（？）
* プロビジョニングは素早くかつ必要な場合に、正確に行う
* プロビジョニングによって追加されたキャパシティが、正しく動作することも検証する

### 1.3.7 効率とパフォーマンス

* リソースの効率的な活用が、サービスのトータルコストに大きな影響を与える
* 特定のパフォーマンスを維持できるように、プロビジョニングを行うため、パフォーマンスの改善は大事

## 1.4 始まりの終わり

* これ以降、SREの詳細を見ていく
kotlinでhibernate経由のDB更新時に@CreationTimestampの値がnullで更新されないようにする。

以下のような、 @CreationTimestampを使用した`createdAt`を有するテーブルで、
データ作成時は`createdAt`に値が入るが、
データ更新時は`createdAt`の値が`null`になってしまう件。

```
@Entity
@Table(name = "my_table")
class MyTableEntity {

    @Id
    var id: String = ""

    @UpdateTimestamp
    @Column(name = "updated_at")
    lateinit var updatedAt: Date

    @CreationTimestamp
    @Column(name = "created_at")
    lateinit var createdAt: Date
}
```

下から３行目の、

```
    @Column(name = "created_at")
```

を、

```
    @Column(name = "created_at", updatable = false)
```

のように更新不可にすることで解決できる。


---

`@UpdateTimestamp `の代わりに、
`@Generated(value = GenerationTime.ALWAYS)`
を使ってる人も、動作がいまいちなので（うまく更新されない場合がある）、

最新の[hibernate-core](https://mvnrepository.com/artifact/org.hibernate/hibernate-core)を入れて下さい。

```
dependencyManagement {
	dependencies {
		dependency 'org.hibernate:hibernate-core:5.4.0.Final'
		dependency 'org.hibernate:hibernate-entitymanager:5.4.0.Final'
		dependency 'org.hibernate:hibernate-validator:5.4.0.Final'
	}
}
```
Pythonで文字列操作

##文字列の分割
文字列を分割するにはsplit(スプリット)メソッドを使います。

方法としては

```Python
変数='文字列,文字列,文字列'
変数list=変数.split(',')#区切りとしての文字列
```
例として私はポテトチップスが大好きなのでポテトチップスを例にあげてみます。

```Python
potatoes="塩,のり塩,だし"
print(potatoes)
```
ここまでで結果を出すと
```塩,のり塩,だし
```
になり文字列で表示されます。
この文字列を分割します。

```Python
potatolist=potatoes.split(',')#splitメソッドを使用
for potato in potatolist:#for文を使用
    print(potato)
```
この３行を追加すると結果は
```塩
のり塩
だし```
になり縦に配列出来ます。

##文字列の結合
文字列の結合の書き方は

```Python
変数='文字列'
print(変数+'文字列')

````

ポテトチップスで例をあげると

```Python
potato=('塩')#文字列に当てはめるものは１つでも２つでもOK
print(potato+'ポテチ食べたい')#結合したい文字列を追加
```
この結果は
```塩ポテチ食べたい```
になります。

※配列化されているすべての文字列を結合したいときは、join(ジョイン)メソッドを使います。

##文字列の置換(ちかん)

文字列の中で特定の文字列を置き換えるときはreplace(リプレース)メソッドを使います。
書き方は

```Python
変数1='文字列'
変数2=変数1.replace('文字列1','文字列2')
#2行目の変数1には置き換え対象の文字列を書きます
#2行目は文字列1から文字列2へ置換します
```
ポテトチップスの例ですと

```Python
potatoes="塩,のり塩,だし"
potatoes=potatoes.replace(',','*')#replaceメソッドを使用
```
上記は文字列を区切っている’，’を’＊’へ置換しています。
結果は
```塩*のり塩*だし```
になります。

##文字列の検索
文字列の中から特定の文字列を調べたい場合はfind(ファインド)メソッドを使います。
書き方は

```Python
変数1='文字列'
変数2=変数1.find('文字列')#文字列には調べたい対象の文字列を書く
#２行目の変数1は検索対象の文字列を書く
```

ポテトチップスの例

```Python
potatoes="塩*のり塩*だし"
i=potatoes.find('のり塩')#のり塩を検索したい
print(i)
```
この書き方で結果を出すと２という数字が出ます。
数字は０スタートになっており、１つの単語ごとに区切られるのではなく、下記のように１つの文字ごとに区切られます。

```
 塩  * の り 塩  *  だ し
0  1  2  3  4  5  6  7
```
また、文字列の中に指定した文字列がない場合は、－１と表示されます。
※findメソッドと似た働きをするindex(インデックス)メソッドがあり、違いは文字列がない場合にエラーが表示されます。

###文字列が何個含まれているか調べる方法
count(カウント)メソッドを使います。
書き方は

```Python
変数1='文字列'
変数2=変数1.count('文字列')#countメソッドを使用
```
ポテトチップスの例

```Python
potatoes="塩*のり塩*だし"
#文字列が存在する場合の例
n=potatoes.count('塩')#countメソッドの使用
print(n)#変数nの出力

#文字列が存在しない場合の例
n=potatoes.count('梅')
print(n)
```
結果を出すと
文字列が存在する場合、２という数字が出ます。
※```塩```とのり```塩```の２つ
逆に文字列が存在しない場合、０が出ます。

###文字列が存在するかしないかの確認方法
inが使えます。

書き方は

```Python
変数1='文字列'
print='文字列' in 変数1 #検索したい文字列を入れる
```

ポテトチップスの例

```Python
potatoes="塩*のり塩*だし"

#文字列が存在する場合の例
print('塩' in potatoes)

#文字列が存在しない場合の例
print('コンソメ' in potatoes)
```
文字列が存在する場合、Trueが出ます。
文字列が存在しない場合、Falseが出ます。


###ポテトチップスの話
ポテトチップスが大好きで今回ポテトチップスで例を沢山あげました。
中学生の頃、毎日おばあちゃんの家に学校終わりに遊びに行ってました。
おばあちゃんは私のために散歩がてら２日に１回のペースで、地元の薬局で１袋６９円で売っているポテトチップス（７０ｇぐらい）を１０袋買ってきてくれてたので、その時期私は毎日ポテトチップスを５袋食べて幸せな日々を送っていました。
私が好きなのはカルビーのうすしお、コンソメ、関西だししょうゆ、のり塩です。
中学生の頃は、特に関西だししょうゆがお気に入りでした。
最近はセブイレで売ってるセブンプレミアムシリーズの“石垣の塩で味付けした厚切りポテト１５０ｇ入り”がお気に入りで自分で買ってよく食べています。
無料で使えるデータセットまとめ

## このメモなに？
* 勉強やライブラリ試すときに使えるデータリストを記載

## ウェブサイト
* [UCIデータ](http://archive.ics.uci.edu/ml/datasets.html)
* [Kaggle](https://www.kaggle.com/)
* [国立情報学研究所](https://www.nii.ac.jp/dsc/idr/datalist.html)
* [ハーバード](https://dataverse.harvard.edu/)

## pythonパッケージ内
* Scikit-learn

| 関数名 | 内容 |
|:--|:--|
| load_boston([return_X_y]) | Load and return the boston house-prices dataset (regression). |
| load_iris([return_X_y]) | Load and return the iris dataset (classification). |
| load_diabetes([return_X_y]) | Load and return the diabetes dataset (regression). |
| load_digits([n_class, return_X_y]) | Load and return the digits dataset (classification). |
| load_linnerud([return_X_y]) | Load and return the linnerud dataset (multivariate regression). |
| load_wine([return_X_y]) | Load and return the wine dataset (classification). |
| load_breast_cancer([return_X_y]) | Load and return the breast cancer wisconsin dataset (classification). |

## その他
* 随時更新
Selenium Gridで新しいセッションが作れないときの対処

docker-composeでSelenium Gridを立ち上げてテストに使っていたのですが、新しいセッションを立ち上げるときに下記のようなメッセージが出たまま長時間待たされてタイムアウトで死ぬという症状に悩まされていました。

```
hub_1      | 05:12:56.822 INFO [RequestHandler.process] - Got a request to create a new session: Capabilities {browserName: chrome}
```

`docker-compose.yml` はこんな感じ。

```yaml

version: '2'
services:
  hub:
    image: selenium/hub
    ports:
      - 4444:4444

  chrome:
    image: selenium/node-chrome
    volumes:
      - /dev/shm:/dev/shm
    depends_on:
      - hub
    environment:
      HUB_HOST: hub
    ports:
      - 5900:5900
```

調べたところ、 `NODE_MAX_SESSION` という環境変数に最大セッション数を格納する必要がある様子。
`NODE_MAX_SESSION: 5` を `environment:` に追加すると上手く動きました。
新米SEのExcel Tips ②


前回に続き、Excelのショートカットを紹介します。
今回はキーボードの図付きです。

#移動・選択に関するショートカット
###・1画面分右/左に移動

|移動|キー|
|:--:|:--:|
|1画面分右に移動|[Alt] + [PgDn]|
|1画面分左に移動|[Alt] + [PgUp]|
![image.png](https://qiita-image-store.s3.amazonaws.com/0/266259/fa77ac92-38e6-a609-4600-9a483456c187.png)

スクロールバーを使わずに移動できます。

###・表の領域を選択
|移動|キー|
|:--:|:--:|
|表の領域を選択|[Ctrl] + [Shift] + [ * ]|
![image.png](https://qiita-image-store.s3.amazonaws.com/0/266259/f2e1d2e0-a15e-7a56-139f-22728b57c7b2.png)

その表の範囲を認識して、選択してくれます。
データの入っていないセルがあっても大丈夫です。

#入力に関するショートカット
###・データを下/右にコピー&ペースト

|移動|キー|
|:--:|:--:|
|データを下にコピー|[Ctrl] + [D]|
|データを右にコピー|[Ctrl] + [R]|

![image.png](https://qiita-image-store.s3.amazonaws.com/0/266259/2ffd220d-05c6-71b1-1b4c-d8f74c8b8d65.png)

作業速度に影響大かと思います。
覚えるなら"D"ownと"R"ightで。

###・行・列・セルを挿入
|移動|キー|
|:--:|:--:|
|行・列・セルを挿入|[Ctrl] + [Shift] + [+]|

![image.png](https://qiita-image-store.s3.amazonaws.com/0/266259/3c907deb-02a0-546b-7ea9-d0b692fc7042.png)

空の行・列・セルを挿入するのに加えて、コピーしている行なども挿入できます。

#書式設定に関するショートカット
###・セルの書式設定を開く

|移動|キー|
|:--:|:--:|
|セルの書式設定を開く|[Ctrl] + [1]|

![image.png](https://qiita-image-store.s3.amazonaws.com/0/266259/f69fea8e-8cbb-214b-861d-d207118434d9.png)

テンキーのないキーボードでは若干押しづらいです。
罫線をつけるときに重宝するかと思います。

###・表示形式を日付(yyyy/M/d)に設定
|移動|キー|
|:--:|:--:|
|表示形式を日付(yyyy/M/d)に設定|[Ctrl] + [Shift] + [3]|

![image.png](https://qiita-image-store.s3.amazonaws.com/0/266259/9d1fa79c-163d-7218-3e07-93af86b218b2.png)

プルダウンと大差ないかとは思いますが一応・・・
MM/ddに設定するショートカットは無いようです。

#差分検知用条件付き書式

①リボンの「条件付き書式」＞「新しいルール」＞「数式を利用して、書式設定するセルを決定」

②ボックスに「=(比較したいセルその1)<>(比較したセルその2)」を入力
※矢印キーはセルの選択に使われてしまうので注意
※相対参照がおすすめ
※例：「=B2<>D2」

③「書式(F)」ボタンを押下し、条件を満たしたとき(=差分を検知したとき)にセルにつけたい塗りつぶしなどを設定

④「OK」を押下し、作成したルールの「適用先」に、塗りつぶしをしたいセルを選択する。
※範囲選択可能

![image.png](https://qiita-image-store.s3.amazonaws.com/0/266259/1aec8130-94ad-6f49-4224-14ca88cb8365.png)
【今日から携わる】CSS Gridの使い方。テンプレートを使って、さっくり実装しよう。

最近、Gridでレイアウトをするようになったため、よく使うスタイルをテンプレート化して共有したいと思います。
実際にはgulpのAutoprefixerなどを使用しないと、gapがIEに対応しなかったりするので注意が必要です。

#CSS Gridで、カラムを分けて格子状にする方法

<p data-height="265" data-theme-id="0" data-slug-hash="GPPQxM" data-default-tab="html,result" data-user="abenosite" data-pen-title="CSS Grid（格子状）" class="codepen">See the Pen <a href="https://codepen.io/abenosite/pen/GPPQxM/">CSS Grid（格子状）</a> by abenosite (<a href="https://codepen.io/abenosite">@abenosite</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

よくある格子状の2次元レイアウトです。
親要素にクラスをするだけで、簡単に実装できます。

## 2カラム
アイテムが1:1に並び、下に追加されていきます。
スマホ時の指定もすれば、４カラム→２カラムも簡単に実装できます。
<img width="940" alt="スクリーンショット 2019-01-15 1.01.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/254652/a26f583c-5008-98ae-ba48-e64d26bda1de.png">

```
.grid-2 {
    display: grid; //Gridレイアウトのコンテナにする
    grid-template-columns: 1fr 1fr; //アイテムを2カラムに並べる（1:1）
    gap: 10px; //アイテム同士の余白は10px
}
```

## autoカラム
auto-fitを使うことで、`@media screen`を書かずにレスポンシブに対応させることができます。

```
.grid-auto {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-auto-rows: minmax(120px, auto);
  gap: 10px;
}
//auto-fit：レスポンシブ時に、Gridアイテムの幅を変化させることで余った余白を埋めることができます。
```

![0.06.gif](https://qiita-image-store.s3.amazonaws.com/0/254652/3ba641b1-4f0f-a23d-54a6-9e901ff2f8b0.gif)





#CSS Gridで、ページテンプレートをつくる方法

<p data-height="265" data-theme-id="0" data-slug-hash="REEJWG" data-default-tab="css,result" data-user="abenosite" data-pen-title="CSS Grid（ページレイアウト）" class="codepen">See the Pen <a href="https://codepen.io/abenosite/pen/REEJWG/">CSS Grid（ページレイアウト）</a> by abenosite (<a href="https://codepen.io/abenosite">@abenosite</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


#CSS Gridで、新着記事一覧をつくる方法

<p data-height="265" data-theme-id="0" data-slug-hash="QzYLMx" data-default-tab="html,result" data-user="abenosite" data-pen-title="QzYLMx" class="codepen">See the Pen <a href="https://codepen.io/abenosite/pen/QzYLMx/">QzYLMx</a> by abenosite (<a href="https://codepen.io/abenosite">@abenosite</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>