OmniAICreator/Qiita-1.07M huggingface dataset:
CentOS7サーバーにデプロイしたLaravelにPuppeteerを導入する

## 概要
Laravel×PuppeteerをCentOS7サーバーで稼働させる場合に役に立ちます。




## node.jsのインストール方法(CentOS7)
サーバーにリポジトリを追加

```
$ curl -sL https://rpm.nodesource.com/setup_14.x | sudo bash -
```
node.jsインストール

```
$ sudo yum install nodejs
```
node.jsバージョン確認

```
$node -v
```
npmバージョン確認

``` 
$npm -v
```

##chromeのインストール方法(CentOS7)
chromeのインストール

```
$ sudo yum install https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
```
日本語フォントインストール

```
$ sudo yum install ipa-gothic-fonts ipa-mincho-fonts ipa-pgothic-fonts ipa-pmincho-fonts
```
chromeバージョン確認

```
$ google-chrome --version
```


## Puppeteerインストール

下記をLaravelプロジェクトのpackage.jsonに追記


```
"puppeteer": "^5.5.0"
```
Puppeteerをインストール（他のnodemoduleも同時にインストールされます。）

```
$npm install
```

あとは、プロジェクトのディレクトリにpuppeteerのJSファイルを配置したら完成です！！
React開発者向けオンラインサロン「React Fan」のランディングページをExcalidrawで作った

これまで運営していたMeteor Fanというコミュニティを実態に合わせて「React Fan」に変えて、オンラインベースに移行しました。

React FanはSlackを使ったコミュニケーションの場を中心とします。[connpassのイベントページ](https://meteor-fan.connpass.com/event/202235/)にはSlackの招待リンクがあるのですが、そもそも入り口のページが存在しないことに気づき、ランディングページを作ることにしました。

ランディングページをユニークでありつつ手軽に作りたいと思い、試しに[Excalidraw](https://excalidraw.com)で作ってみたのですが、思いの外面白かったので共有します。

作ったサイトはこちらです。

[React Fanのサイト](https://react-fan.axlight.com)

スクリーンショットを貼るよりも、開いた方がわかると思います。

フルSVGになっています。ちなみにホスティングはGitLab Pagesを使ってみました。SVGはExcalidrawでエクススポートしたものに `<a>` タグを追加して、サイズを少し調整しました。

気づいたこと:
- Excalidrawで描いたものがそのままページになるのでめっちゃ楽
- `<a>` タグ追加は自動化したいかも
- サイズ固定なので、デスクトップとモバイルでだいぶ見え方が違う
- SEOはどうなるんだろう

以上です。興味があればReact FanのSlackにもご参加ください。
Vue.jsのv-forについて

Vuejsで配列やオブジェクトなどを、v-forで表現することが多くなりました。

ちょっと基本的な内容をメモっておきたいと思います。



####配列で使用する場合

####1. v-for = "要素 in 配列"
(要素の変数名は任意)

```javascript:js
Vue.createApp({
 data:function(){
   return {
     items: ['item-1', 'item-2'],
   }
  },
}).mount('#app')
```

```html:html
<div id="app">
 <div v-for="item in items">{{ item }}</div>
</div>


result:
<div id="app">
 <div>item-1</div>
 <div>item-2</div>
</div>
```

####2. v-for = "(要素, インデックス) in 配列"
要素、インデックスの変数名も任意


```html:html
<div id="app">
 <div v-for="(item, index) in items">{{ index }}: {{ item }}</div>
</div>


result:
<div id="app">
 <div>0: item-1</div>
 <div>1: item-2</div>
</div>
```

####オブジェクトで使用する場合

####1. v-for = "値 in オブジェクト"

```html:html
<div id="app">
 <div v-for="value in object">{{ value }}</div>
</div>


result:
<div id="app">
 <div>ヤマダ</div>
 <div>40</div>
 <div>女</div>
</div>
```

```javascript:js
Vue.createApp({
 data:function(){
   return {
     object: {
        name:'ヤマダ',
        age:40,
        gender:'女',
     },
   }
  },
}).mount('#app')
```

####2. v-for = "(値、プロパティ名、インデックス値） in オブジェクト"

```html:html
<div id="app">
 <div v-for="(value, key, index) in object">
    {{ index }}: [{{ key }}] {{ value }}
 </div>
</div>


result:
<div id="app">
 <div>0: [name] ヤマダ</div>
 <div>1: [age] 40</div>
 <div>2: [gender] 女</div>
</div>
```
以上が、典型的な使用パターンですが、
ただ、効率よく運用する上では下記を意識して使った方がよさそうです。
####key属性を付与する。
v-forで注意しないといけないと感じたのがkey属性の付与
Vueでは要素を識別するために、特別なkeyと言う属性を参照し一つ一つの要素を認識しています。
key属性を付与することで、Vueは要素の変更前後の差分を検出し、効率の良い処理を行うことが可能となっています。

```javascript:js
Vue.createApp({
 data:function(){
   return {
     items: [
        {
          id:1,
          name:'item-1',
        },
        {
          id:2,
          name:'item-2',
        },
     },
   }
  },
}).mount('#app')
```


```html:html
<div id="app">
 <div v-for="item in items" :key="item,id">
    {{ item.name }}
 </div>
</div>
```

また、インデックス値をkeyの値として指定することもできますが、
sortやfilterなどによって配列の順番が変更になると意図した出力にならないので注意が必要です。
例：sortで順番が変わった場合、インデックス値0の要素は別の要素になりますが、keyの値は変更していないので、Vueはその要素の変更をスキップします。

####まとめ
基本的な記載パターンを描きました。
ただ、v-forで繰り返し処理をする配列またはオブジェクトでは、要素に一意となる値を用意することが理想的です。
順番変更などが生じるようなケースでの取り扱いには注意が必要です。
djangoを使って新しくTODOアプリを作る１

・今回受けさせていただいた講座
<a href="https://www.udemy.com/course/django-3app/">【徹底的に解説！】Djangoの基礎をマスターして、3つのアプリを作ろう！（Django2版 / 3版を同時公開中です）</a>
一からdjangoを学ぶことができ、エラーが出るコードをあえて作ることで、どう対処するのかの姿勢も学べました。

今回の目標
・講座で習ったtodoアプリとサインイン機能を実装
・よりtodoアプリっぽくするために、期限に到達したらなんらかの方法でPCもしくはモバイルに通知を送る（メールで送信とか？）
・復習を兼ねて一から作る（わからなくなってきたら講座を見直しながら作る）
・bootstrapを使って実際にありそうな見た目にする

##早速作っていく
```
仮想環境作成コマンド
 python3 -m venv　＋ venv(名前)
仮想環境実行コマンド
.   venv(仮想環境の名前)/bin/activate
pip django
Django-admin startproject next
cd 名前
python manage.py startapp todo
```
##setting.pyを編集

INSTALLED_APPS =
    'todoapp.apps.TodoappConfig'を追加
TEMPLATES = 
        'DIRS': [BASE_DIR / "templates"],　を追加
base_dir の階層にtemplatesのフォルダを作る（今回はmanage.pyと同じ階層）

次にurls.pyの設定
プロジェクトのurls.py に
from django.urls import path , include
    urlpatterns =[path("", include("todo.urls")),]　を追加

todo の　urls.pyにも
urls.pyをコピペし、編集していく。
今日はこのくらいでまた明日以降やっていきます。
公開中のアプリを開いたら「サーバーが見つからない」となって焦った件

# 原因

ドメインの有効期限切れ。

# 対処
お金を払いましょう。

# 「サーバーが見つからない」と表示されてからの行動。

**１．サーバーへssh接続。**　→　接続できた。

**２．サーバーの容量がいっぱいになっているのか？？**

```
$ df -h
```
容量はいずれも使用率に問題なさそう。

**３．ログの確認**

```
/var/log
/var/www/html/アプリディレクトリ/log

$ tail -f ログファイル
とすると終わりの方のログを確認しやすい。
必要に応じて管理者権限で。
```
上記のログを確認。　→　原因を特定できるログは見つけられず。

**４．サーバーの管理画面を確認。**　→　起動中の表示
ここで再起動することも考えたが、まだその手を下すまでの調査はしていないのでここでは行わなかった。

**５．念の為大事なデータだけバックアップ**

**６．「サーバーが見つからない　さくら」で検索**
そう、さくらのインターネットを使って公開しております。
すると、メールアドレスの認証確認すること。というteratailの記事を発見。。。
もしやメールでお知らせが来ているのではないか？

**７．Gmailを確認**
それらしいメールは見つからず。。

**８．ドメインの認証なんてことがあるのだろうか。**
Xdomainにてドメインを購入しております。
マイページにアクセスすると、有効期限が切れているではありませんか！！
さっさとカードで支払いをすると、ページが表示されました！

**９．答えがわかってから再度メールを確認。**
結構前からメールが来ていました。
メールは見落としますね。。
Evernoteでメモをしているので、有効期限も管理しておくべきでした。反省。。

# おわりに
サイトにアクセスできなくなっていたときはとても焦りました。個人開発といえども使ってくださっている方がいる本番環境です。
すぐに解決できるような問題なのかもわからず、自分ひとりでなんとかするしかない状況になり心臓に悪かったです。。
直接的な記事がすぐには見つからなかったので、記事を投稿させていただきました。
僕のようなチョンボをする人はいないのかもしれませんが、お気をつけくださいm(_ _)m
Rust の re-exporting 小技

外部クレートを改造しながら自分のクレートにモジュールとして埋め込みます。

# 3 通りの re-export

[thunderdome](https://docs.rs/thunderdome/latest/thunderdome/) を 3 通りの方法で re-export します。

## 1. `pub use external_crate;`

```rust:rlbox/src/tmp.rs
//! Tmp

pub use thunderdome;
// or:
// pub extern crate thunderdome;
```

![Screen Shot 2021-01-26 at 22.37.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/aa355dd2-ff7a-b9eb-9d26-b990c0a41424.png)

クリックすると、外部クレートのドキュメントにジャンプしました:

![Screen Shot 2021-01-26 at 22.31.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/5017d26d-35b0-1808-0a11-88444f11b61e.png)

## 2. `#[doc(inline)] pub use external_crate`

Rust by Example の [meta](https://doc.rust-lang.org/rust-by-example/meta/doc.html) の項に載っている `#[doc(inline)]` を試します。

```rust:rlbox/src/tmp.rs
//! Tmp

// 実は docstring の頭に自分の文章を追加できる:
/// [`thunderdome`] re-exported as `generational_aerna`
///
///
#[doc(inline)]
pub use thunderdome as generational_arena;

// as 以下はあってもなくてもいい
```

![Screen Shot 2021-01-26 at 22.36.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/25d4c65b-f681-bfa8-e858-9a994926fcea.png)

クリックすると、直下のモジュールとして表示されました:

![Screen Shot 2021-01-26 at 22.30.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/7e6744c6-0a2f-dae0-8e4a-ec9a09dfe430.png)

また、 docstring に自分が書いた文章 (`thunderdome` re-exported ..) が追加されていることに注目してください。

## 3. `pub use external_crate::*`

```rust:rlbox/src/tmp.rs
//! Tmp

pub mod arena {
    /*!
    [`thunderdome`] re-exported. Note that [`Index`] is not reference-counted.
    */

    pub use thunderdome::*;
}
```

![Screen Shot 2021-01-26 at 22.35.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/382f8357-97dd-94a9-3c59-b6f33f39dfa0.png)

クリックすると:

![Screen Shot 2021-01-26 at 22.36.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/8633b7a0-1b84-7081-61a3-6132eacba52e.png)

`thunderdome` の docstring を消去できました。 Docstring 中の `thunderdome` をクリックすると、オリジナルのドキュメントを見ることができます。

> 僕が書いた文章 (docstring) がおかしいのは許してください……。

# 活用例: soloud-rs を改造しながら re-export

```rust:snow2d/src/audio.rs
/*!
[`soloud-rs`] re-exported with additional types and [`snow2d::asset`] integration

[SoLoud] is an easy to use, free, portable c/c++ audio engine for games.
*/

pub use soloud::{audio as src, filter, prelude, Handle, Soloud as AudioDrop};

use std::{
    ops::{Deref, DerefMut},
    rc::Rc,
};

/// Reference-counted ownership of [`AudioDrop`]
#[derive(Debug, Clone)]
pub struct Audio {
    inner: Rc<AudioDrop>,
}

impl Audio { /* ~~ */ }
impl Deref for Audio { /* ~~ */ }
impl DerefMut for Audio { /* ~~ */

pub mod asset {
    //! [`snow2d::asset`](crate::asset) integration

    // ~~
}
```

![Screen Shot 2021-01-26 at 22.49.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/b668a9bc-7d83-c4a5-e0e9-d1c6f74f498a.png)

[オリジナルのドキュメント](https://docs.rs/soloud/latest/soloud/) と比較しても分かる通り、型の名前を変えたり、一部の re-export を削除して、また `Audio` 型と `asset` モジュールを追加しています。
require_treeについて

#目次
<b>①require_tree.とは</b>
<b>②記述されている場所</b>
<b>③読み込まれる流れ</b>


##①require_tree.とは
フォルダ配下にある全ファイルを対象として読み込むという意味。

```php:app/assets/stylesheets/application.css
/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
 * vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
 * files in this directory. Styles in this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *
 *= require_tree .　←これ！この「.」はカレントディレクトリという意味。
 *= require_self
 */

```
上記のように書かれる。現在のディレクトリはstylesheetsなので、ディレクトリ内にあるファイルを全て読み込まれることになる。
「*=」と一見コメントアウトされているかのように見えるが、コメントアウトされているかに見えるが、実際はコードとして意味のある行になりまる。( コメントアウト行の先頭がイコールで始まる行はdirectiveと呼ばれ、Ruby on Railsがapp/assets を管理する際に用いられる記法です )




##②記述されている場所

上記のように記載されている場所は、application.cssファイルに記述されている。


##③読み込まれる流れ

```php:app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= yield(:tittle)%>|ニコッとできるキャリプランを</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
     上記の記述でapplication.cssファイルが読み込まれ,aplication.cssに記述されているrequire_tree.が発動する
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>
```
Djangoで mysqlclient のインストールエラーが発生 in AWS Elastic Beanstalk

## エラー内容

Beanstalk へ Djangoのアプリケーションをデプロイしようとしたら、以下のエラーが発生しました。どうやら mysqlclient のインストールが原因のようです。
(requirements.txtにmysqlcilentの記載があります。)

```
2021/01/26 09:37:34.723109 [ERROR] An error occurred during execution of command [app-deploy] - [InstallDependency]. Stop running the command. Error: fail to install dependencies with requirements.txt 
file with error Command /bin/sh -c /var/app/venv/staging-LQM1lest/bin/pip install -r requirements.txt failed with error exit status 1. Stderr:    ERROR: Command errored out with exit status 1:
     command: /var/app/venv/staging-LQM1lest/bin/python -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-nebdennp/mysqlclient_9261c2b2f0fb4076a2579325b6b9c90f/setup.py'"'"'; __file__='"'"'/tmp/pip-install-nebdennp/mysqlclient_9261c2b2f0fb4076a2579325b6b9c90f/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-en_mkkv0
         cwd: /tmp/pip-install-nebdennp/mysqlclient_9261c2b2f0fb4076a2579325b6b9c90f/
    Complete output (12 lines):
    /bin/sh: mysql_config: command not found
    /bin/sh: mariadb_config: command not found
    /bin/sh: mysql_config: command not found
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-nebdennp/mysqlclient_9261c2b2f0fb4076a2579325b6b9c90f/setup.py", line 15, in <module>
        metadata, options = get_config()
      File "/tmp/pip-install-nebdennp/mysqlclient_9261c2b2f0fb4076a2579325b6b9c90f/setup_posix.py", line 65, in get_config
        libs = mysql_config("libs")
      File "/tmp/pip-install-nebdennp/mysqlclient_9261c2b2f0fb4076a2579325b6b9c90f/setup_posix.py", line 31, in mysql_config
        raise OSError("{} not found".format(_mysql_config_path))
    OSError: mysql_config not found
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
```

## 解決策
.ebextensions/01_packages.config というファイルを作成して以下を記載します。

```
packages: 
  yum:
    python3-devel: []
    mariadb-devel: []
```

## 関連
[Elastic Beanstalk で python の Django アプリケーションをデプロイする方法](https://qiita.com/taiba/items/02bef4b3a3ca7e611d0d)

.ebextensionsについては以下を参考にしてください。
[設定ファイル (.ebextensions) による高度な環境のカスタマイズ](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/ebextensions.html)
Gitリポジトリのコード量を知る

# 方法
コマンドラインツール「cloc」を使用。
Mac、Windows共に利用可能。ここではMac。

# インストール
`$ brew install cloc`

# 使い方
## 基本
コマンドライン上に出力
`$ cloc 対象のディレクトリまたはファイル`

## CSVファイルに出力
`$ cloc 対象のディレクトリまたはファイル --csv --out="出力ファイル名.csv"`

# 参考
- [AlDanial/cloc - GitHub](https://github.com/AlDanial/cloc)
- [ステップ数のカウントツール「cloc」 | デーコムラボ](https://www.dcom-web.co.jp/lab/tool/cloc)
さくらのレンタルサーバにLaravelで作ったアプリをデプロイしたときのメモ

初めてレンタルサーバでデプロイしてみました。
いろんなブログを参考に進めたのですがかかなり詰まったので自分用に残すメモ。
今回は元々作ってGithub上に置いていたものをクローンしました。

色々ブログを参考にやってみたけど結局これ。
Laravelプロジェクトのpublicからシンボリックリンクを貼れば問題なく動くのだと思う。

```
ln -s /home/{FTPアカウント名}/{laravelプロジェクト名}/public /home/{FTPアカウント名}/www/{シンボリックリンク名}
```
ローカル環境でシンボリックリンクはつかったことあったのですがコマンドで入力が初めて。
シンボリックリンクが何なのかもわかっておらずまた、さくらサーバー上では無効なリンクと表示されるのでできているかどうかがわからなかった。



#手順

さくらのレンタルサーバのサーバコントロールパネルからデータベースを作成

Tera TermにSSHでログイン。
必要な情報はさくらインターネットのレンタルサーバ申し込みをした際に、さくらインターネット側から届く「仮登録完了のお知らせ」というタイトルのメールの中に記載されています。



```
pwd
/home/{アカウント名}
mkdir laravel
```

laravelフォルダの中にLaravelプロジェクトのデータを取り込む

```
cd laravel
git clone https://something.git
```

composerをインストール。

```
curl -sS https://getcomposer.org/installer | php

php composer.phar
```
composerを使って/vendor/のデータをインストールする

```
php composer.phar install
```

.envを作成。

```
vim .env
```
.envに情報を入力する。できたらキーを作成。

```
php artisan key:generate
```
マイグレーション

```
php aritsan migrate
```

ここからいろんな方のブログや記事を参考に公開フォルダ(www)に新しくフォルダを作り、laravelプロジェクトのpublicの中身のコピーしたのですが。こんな感じ↓

```
cp -r /home/アカウント名/Laravelプロジェクト名/public/* /home/アカウント名/www/フォルダ名

```
そしてindex.phpを修正したのですが。こんな感じ↓

```
require __DIR__.'/../../Laravelプロジェクト名/vendor/autoload.php';
$app = require_once __DIR__.'/../../Laravelプロジェクト名/bootstrap/app.php';

```

このやり方だとGit pullしてもwww/フォルダ名の中にあるCSSやJSへgit上での変更は読み込まれません。なのでサーバコントロールパネルのファイルマネージャーから手動で書き換える必要がありました。
また、画像を読み込ませたくてもローカルで動いていたコードの書き方だとviewに反映せず、ずっと詰まってました。。

下のようにシンボリックリンクを貼ってみたところ動いた。

```
ln -s /home/{FTPアカウント名}/{laravelプロジェクト名}/public /home/{FTPアカウント名}/www/{シンボリックリンク名}

#sakuraという名前のシンボリックリンクがwww下につくられます。
ln -s /home/{FTPアカウント名}/{laravelプロジェクト名}/public /home/{FTPアカウント名}/www/sakura
```

フォルダのコピーとかせずにただpublicからリンクを貼ればよかったぽいです。



シンボリックリンクは公開するフォルダの中にsymlink()を書いたPHPファイルを作ってweb上で読み込ませることでも作成できます。



かなり時間がかかった。
サーバーは全然わからないことだらけで勉強になりましたーー。

作ったもの。
https://kasihkasih.net/
Composerを用いたLaravelの環境構築

#はじめに
本記事は、私がLaravelの勉強をする際に参考にした本「[PHPフレームワーク Laravel入門](https://www.amazon.co.jp/PHP%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF-Laravel%E5%85%A5%E9%96%80-%E6%8E%8C%E7%94%B0%E6%B4%A5%E8%80%B6%E4%B9%83/dp/4798052582)」通り進めてもうまくいかない点が多く、調べることが多かったので同じように悩んでいる方向けに、実際に私が環境構築した手順をまとめたものです。
#使用した環境
MacOS Catalina v10.15.7
PHP 7.3.11(Macだとデフォルトで入ってます)
#環境構築
##Composerの設定
###1.composerのinstall
Composerのサイトから、最新版の``composer.phar``をダウンロードする。`Latest Stable`をクリックする。
![スクリーンショット 2021-01-25 20.08.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849084/03635605-c60d-2152-0243-a18f03bba340.png)
###2 usr/local/binに移動
ポジションをダウンロードフォルダに移した後、以下のコマンドを実行してください。これで`compsoser.phar`をいつでも呼び出せるようになります。


```terminal:terminal
cd Downloads
sudo mv composer.phar /usr/local/bin/composer
```

###3パーミッションを設定
composerのアクセス権を取得するために以下のコマンドを実行してください。

```terminal:terminal
chmod a+x /usr/local/bin/composer
```

ここまでできたら、composerの設定は終了です。`composer -v`でversionを確認してみてください！

#Laravelのインストール
Dockerをインストールしていれば、以下のコマンドで、Laravelのプロジェクトを立ち上げることができます。`example-app`の部分は自分のプロジェクト名を適用してください。

```terminal:terminal
curl -s https://laravel.build/example-app | bash
```

次に以下のコマンドを実行すると、Sailのアプリケーションコンテナがマシン上に構築されます。初めて実行する場合にはそこそこ時間がかかります。私がした時は15分ほどかかりました。

```terminal:terminal
./vendor/bin/sail up
```

ここまでできたら``Artisan CLI``のサーブコマンドを実行します。

```terminal:terminal
php artisan serve
```

``localhost:8000``を開くと、Laravelの初期画面が見えるようになっています。
![スクリーンショット 2021-01-26 22.19.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/849084/e43286c1-fe9b-5efd-f034-0b9ffe5f5c9c.png)
ruby構文における変数　＠有無

#目的
・ruby構文における@の使用方法について理解を深める

#内容
下記のindex.html.erbとshow.html.erbを比較するとリストタグ内

```
 <%= link_to '編集', edit_tweet_path(@tweet.id), method: :get %>
```



```index.html.erb
edit_tweet_path(tweet.id)
```


```show.html.erb
edit_tweet_path(＠tweet.id)
```
となっているが、indexとshowで@の有無の違いが生じるのは何故でしょうか。
どちらもコントローラーでは＠tweet（もしくは@tweets）に値を代入しているので、HTML.erbで使用する際は@が必要と思われるが、どうしてindexに@が無いのかと疑問に思いませんか。
内容を深掘りしていきましょう。

〜記〜

```index.html.erb
<div class="contents row">
  <% @tweets.each do |tweet| %>
    <div class="content_post" style="background-image: url(<%= tweet.image %>);">
      <div class="more">
        <span><%= image_tag 'arrow_top.png' %></span>
        <ul class="more_list">
          <li>
            <%= link_to '詳細', tweet_path(tweet.id), method: :get %>
          </li>
          <li>
            <%= link_to '編集', edit_tweet_path(tweet.id), method: :get %>
          </li>
          <li>
            <%= link_to '削除', tweet_path(tweet.id), method: :delete %>
          </li>
        </ul>
      </div>
      <p><%= tweet.text %></p>
      <span class="name">
        <%= tweet.name %>
      </span>
    </div>
  <% end %>
</div>
```

```show.html.erb
<div class="contents row">
  <div class="content_post" style="background-image: url(<%= @tweet.image %>);">
    <div class="more">
      <span><%= image_tag 'arrow_top.png' %></span>
      <ul class="more_list">
        <li>
          <%= link_to '編集', edit_tweet_path(@tweet.id), method: :get %>
        </li>
        <li>
          <%= link_to '削除', tweet_path(@tweet.id), method: :delete %>
        </li>
      </ul>
    </div>
    <p><%= @tweet.text %></p>
    <span class="name"><%= @tweet.name %>
    </span>
  </div>
</div>
```

```tweets_controller.rb
class TweetsController < ApplicationController

  def index
    @tweets = Tweet.all
  end

  def new
    @tweet = Tweet.new
  end

  def create
    Tweet.create(tweet_params)
  end

  def destroy
    tweet = Tweet.find(params[:id])
    tweet.destroy
  end

  def edit
    @tweet = Tweet.find(params[:id])
  end

  def update
    tweet = Tweet.find(params[:id])
    tweet.update(tweet_params)
  end

  def show
    @tweet = Tweet.find(params[:id])
  end

  private

  def tweet_params
    params.require(:tweet).permit(:name, :image, :text)
  end
end
```

#答え
index.html.erbの２行目に注目すると

```index.html.erb
@tweets.each do |tweet|
```
というeach構文があリます。
ここでは@tweetsというインスタンス変数をtweetという変数に置き換えている処理が行われています。
つまり、indexの2行目で＠tweetsはtweetという変数に置き換わるため、以降はtweetをもいて、コードを組み立てる必要があるため、indexではtweetを使っているのです。
＠tweet＝tweetsのように分かりやすい形では無いが、eachメソッドで値が変換されることについては意外と謳われていないのでは無いでしょうか？

備忘録として残しておきます。
Xcodeでよく使うショートカット一覧

Xcodeのデバッグでよく使うショートカット一覧
# 目次
[・コード追跡](#コード追跡)
[・コード編集](#編集)
[・実行、ビルド](#実行、ビルド)
[・デバッグ](#デバッグ)

## コード追跡
| ショートカット | 動作 |
|:-----------|:------------|
| ctrl + command + J | 関数定義に飛ぶ |
| ctrl + command + > | 進む |
| ctrl + command + < | 戻る |
| command + shift + O | プロジェクト内検索 |
| ctrl + 1 | callerをチェック |
| command + L | 行移動 |

## コード編集
| ショートカット | 動作 |
|:-----------|:------------|
| command + / | コメントアウト |
| command + shift + T | 新しいタブを開く |
| command + J | タブ移動 |
| command + opt + / | 関数にカーソル当てた状態でショートカットキー打つと関数コメント挿入 |
| command + ' | 次のエラーにジャンプ |
| command + " | 前のエラーにジャンプ |
| command + I | インデント編集 |
| command + ↑↓ | hとmや、hとcppの表示を切り替え |


## 実行、ビルド
| ショートカット | 動作 |
|:-----------|:------------|
| command + B | ビルド |
| command + shift + K | クリーンビルド |
| command + R | 実行 |
| command + . | 終了 |

## デバッグ
| ショートカット | 動作 |
|:-----------|:------------|
| F6 | ステップオーバー |
| F7 | ステップイン |
| command + \ | ブレークポイントの設定/解除 |
| command + ctrl + Y | ブレークポイント停止位置からの再開 |


VisualStudioみたいにマーク機能とか、置き換えじゃなくて使っている関数内の変数の名前置換みたいなのないかな。
テストケース

#【テストケース】

##ブラックボックステスト, ホワイトボックステスト

プログラムをテストするために用意する一連のデータをテストケースという。
ブラックボックステストとホワイトボックステストの2種類がある。

<strong>ブラックボックステスト</strong>は、プログラムの内部構造には関知せず、与えられたデータに対して、あらかじめ決められた通りに動作するかを確認するテスト

<strong>ホワイトボックステスト</strong>は、プログラムの内部構造に着目して、ロジックが正しいかどうかを確認するテスト

##ホワイトボックステストのテストケース

<strong>命令網羅</strong>　プログラム中のすべての命令を実行

<strong>判定条件網羅</strong>　プログラム中のすべての分岐経路を実行

<strong>条件網羅</strong>　個々の条件の真偽を少なくとも1回実行
（判定条件が複数条件の場合は、個々の条件の真偽を1回ずつ実行）

<strong>判定条件/条件網羅</strong>　条件網羅だけではすべての経路が実行されない場合がある。
その時、条件網羅と判定条件網羅を組み合わせ、すべての経路と条件の真偽を少なくとも1回実行

<strong>複数条件網羅</strong>　判定条件の全真偽の組合せを網羅し、全命令を実行
Railsチュートリアル　第1章1.16でのエラー: GitHubをリモートoriginに追加してそのリポジトリにpushする　

#環境
Windows10
AWS Cloud9

#事象
リスト 1.16: GitHubをリモートoriginに追加してそのリポジトリにpushする
で**git push -u origin main**で下記のエラーがでた。

```ruby:AWScloud9_console
ubuntu:~/environment/hello_app (master) $ git push -u origin main
error: src refspec main does not match any.
error: failed to push some refs to 'https://github.com/●●●●●/hello_app.git'
```

#試したこと
**git push -u origin --all**と[ここの記事](https://qiita.com/kohga/items/dccf135b0af395f69144")でレポジトリ作った最初のpushならOKということだったのでとりあえず打ってみた

```ruby:AWScloud9_console
ubuntu:~/environment/hello_app (master) $ git push -u origin --all
Username for 'https://github.com/●●●●●/hello_app.git': ●●●●●
Password for 'https://●●●●●@github.com/●●●●●/hello_app.git': 
Counting objects: 104, done.
Compressing objects: 100% (86/86), done.
Writing objects: 100% (104/104), 148.90 KiB | 3.24 MiB/s, done.
Total 104 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), done.
To https://github.com/●●●●●/hello_app.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
```

#結果
その結果、Githubリポジトリにもpushされたことを確認できた。
とりあえずこのやり方でOKでした。
IBM Cloud 仮想サーバーの物理ロケーションを調べる

#仮想サーバーがどこの物理サーバーにデプロイされたのか。を調べるAPI。の備忘録。
計画保守などで仮想サーバーを旧物理サーバーから新物理サーバーへ移動させる場合、本当に移動が成功したのか新旧の物理ロケーションをAPIで取得することで検査できる。久しぶりに実行した、忘れないように記録という目的。

#APIで取得できるフォーマットの例
pythonスクリプトを実行すると出力する。例えば、ホスト名「host.name.com」は、東京データセンター「tok02」の、サーバールーム「sr01」の、物理ラック「rk111」の、物理サーバー「sl01」にデプロイされていることが解る。移動前の物理ロケーションと移動後の物理ロケーションを見比べて、仮想サーバーが移動できたことを検査する。
仮想サーバーがどこで稼働しているか見えるので透過性の高いサポートが出来て便利なんです（でも...移動させる必要がなければもっといいんだけどね）。


```
"(761****, 'host.name.com', 'tok02.sr01.rk111.sl01')"
```

#pythonスクリプト
必要なモジュールをインストールする。
python3, pip3, softlayer

```
# pip3 install softlayer
```

IBM Cloud のIAMユーザで、APIキーとシークレットキーを取得してスクリプトを実行する。

``` get_physical.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

SL_USERNAME = raw_input("please set the user ID of SoftLayer :")
SL_API_KEY  = raw_input("please set the API key :")

import SoftLayer

_mask='''
        id,
        fullyQualifiedDomainName,
        location.pathString'''

client = SoftLayer.Client(username=SL_USERNAME, api_key=SL_API_KEY)
virtualGuests = client['Account'].getVirtualGuests(mask=_mask)
for vg in virtualGuests:
        print(vg['id'],
                vg['fullyQualifiedDomainName'],
                vg['location']['pathString'])

```

実行結果（ダミーです）

```
$ python get_physical.py
please set the user ID of SoftLayer :1234567_namae@hoge.com
please set the API key :6d3***************************************************ed9dea6
(12345678, 'gateway001.my.local', 'tok02.sr01.rk123.sl01')
```

ハマりどころ：　クラウド管理ポータルでユーザIDとAPIキーを取得する。SoftLayerアカウントを利用している場合は、ユーザIDにSoftLayerユーザ名を代入する。またAPIキーはクラシック・インフラストラクチャー・キーを作成する。

▼SoftLayerユーザー名の取得
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/04899936-5610-c994-c899-d4d9b702f193.png)

▼APIキー（クラシック・インフラストラクチャー・キー）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/2ec0d65c-4fcd-0e37-a15b-e58cb833da14.png)

以上、仮想サーバーの計画保守で便利な物理ロケーションの調べ方でした。i
レイアウトテンプレートについて

#目次
<b>①レイアウトテンプレートとは</b>
<b>②application.html.erbとは</b>
<b>③yieldメソッドとは</b>


##①レイアウトテンプレートとは
アプリケーションのビューファイルの共通部分をまとめたもの。
railsではアプリケーションを作成した際に、app/views/layouts/application.html.erbに自動生成される。
コントローラーで定義したアクションからビューファイルがあるとする。この場合、そのビューが呼び出されているのではなく、上記のファイルに埋め込まれてクライアントに返されている。


##②application.html.erbとは
railsのレイアウトテンプレートに該当するファイルのこと


##③yieldメソッドとは
共通のプログラムと個別のプログラムで分割してコーディングするRubyのメソッド。
例えば、application.html.erbでは、bodyの中に<%= yield %>という記述がある。この記述があることで、各ビューフアイルが埋め込まれるようになる。<%= yield %>の前後に書かれた内容は共通の部分、埋め込まれるものは、各ビューによって変わる。
エクセルで○○以上○○未満の数値がいくつあるかをカウントする

知り合いのプログラム未経験者の人にエクセルを使ってデータを集計したいけど○○以上○○未満ができないという相談を受けました。他にもそういった方のお役にたてばいいと思います。


```コード
=COUNTIFS(セルの範囲,">=数値",セルの範囲,"<数値")
```
【JavaScript】日付(Dateオブジェクト)の使い方を全てまとめる

#プログラミング勉強日記
2021年1月26日
日付や時間を操作することのできるDateオブジェクトについてまとめる。

#Dateオブジェクトの使い方
　Dateオブジェクトを使って日付や時間を操作するためには、`new`を使ってインスタンスを作成する。
　引数なしで利用する場合、現在の日時を取得する。

```js
let now = new Date();
console.log(now);
```

```:実行結果
Tue Jan 26 2021 21:25:35 GMT+0900 (日本標準時)
```

　引数を指定すると、3種類の取得方法がある。

```js
let today1 = new Date();
// 文字列から求める
let today2 = new Date( '2020/10/04 12:30' );
// 年月日時分の数値を順番にカンマ区切りで指定する
// (※月は1引いた数を指定する)
let today3 = new Date( 2020, 9, 4, 12, 30 );
// 1970年1月1日 00:00:00からの経過ミリ秒で日時を求める
let today4 = new Date( 1601782200000 );
 
console.log(today1);
console.log(today2);
console.log(today3);
console.log(today4);
```

```:実行結果
Tue Jan 26 2021 21:32:14 GMT+0900 (日本標準時)
Sun Oct 04 2020 12:30:00 GMT+0900 (日本標準時)
Sun Oct 04 2020 12:30:00 GMT+0900 (日本標準時)
Sun Oct 04 2020 12:30:00 GMT+0900 (日本標準時)
```

#Dateのフォーマット
　日付データから年・月・日・曜日・時・分・秒などのデータを個別に取得できるメソッドがある。注意すべきなのは、<b>月を取得する際には`getMonth()`メソッドに`+1`する必要がある</b>こと。

| メソッド | 説明 |
|:--:|:--:|
| getFullYear()	| 日付の「年」を取得する（4桁） |
| getMonth()	| 日付の「月」を取得する（0~11） |
| getDate()	| 日付の「日」を取得する（1~31）|
| getDay()	| 日付の「曜日」を取得する（0~6）|
| getHours()	| 日付の「時」を取得する（0~23）|
| getMinutes()	| 日付の「分」を取得する（0~59）|
| getSeconds()	| 日付の「秒」を取得する（0~59）|

```js
let today = new Date();
 
let year = today.getFullYear();
let month = today.getMonth() + 1;
let day = today.getDate();
 
console.log(year + '年' + month + '月' + day + '日');
```

```:実行結果
2021年1月26日
```

#Dateオブジェクトのメソッド

##now()メソッド
　現在の日時データを経過ミリ秒で取得する。

```js
let day = Date.now();
console.log(day);
```

```:実行結果
1611665266675
```

##toString()メソッド
　日付データを文字列に変換するメソッド。

```js
let day = new Date();
 
console.log(day.toString());
```

```:実行結果
Tue Jan 26 2021 21:51:15 GMT+0900 (日本標準時)
```

##toISOString()メソッド
　日時をUTCとしてISO 8601に基づいたフォーマット`YYYY-MM-DDThh:mm:ss.uuuZ`で返す。

```js
let date = new Date();

console.log(date.toISOString());
```

```:実行結果
2021-01-26T12:56:50.098Z
```


#日付を計算する方法
　通常の四則演算処理だけで日付を計算することができる。なので、月終わりが30日か31日か考える必要がなく、すべて自動で計算してくれる。

```js
let day = new Date();
console.log(day);  //今日の日付

day.setDate(day.getDate() + 50);
console.log(day);  //50日後の日付

day.setMonth( day.getMonth() - 3 );
console.log(day); // 3か月前の日付
```

```:実行結果
Tue Jan 26 2021 21:35:58 GMT+0900 (日本標準時)
Wed Mar 17 2021 21:35:58 GMT+0900 (日本標準時)
Thu Dec 17 2020 21:37:49 GMT+0900 (日本標準時)
```

#日付を比較する方法
　比較演算子を使って日付を比較することができる。JavaScriptでは古い日時が小さい値になって、新しい日時が大きい値になる。

```js
var date1 = new Date('2020/8/1');
var date2 = new Date('2020/9/1');
 
console.log('date1 > date2 = ' + (date1 > date2));
console.log('date1 < date2 = ' + (date1 < date2));
```

```:実行結果
date1 > date2 = false
date1 < date2 = true
```
ある日突然HGWのVPN接続ができなくなった件

出張中、自宅のRasberryPiをいじろうとVPN接続しようとしたら繋がらない
グローバルIPは変更メールが届いたばかり、間違いはないはず
結局繋がらず、帰宅してから調査開始した記録です。
###環境：
回線:フレッツ光ネクスト NTT東日本
ISP:OCN
HGW:RS-500KI
###原因:
PPPoE接続サービスがIPoE(ipv4 over ipv6)に切り替えられたため
グローバルIPアドレスがシェアされることになり、都合悪いVPN設定メニューが消された。
PPPoeの設定もグレーになった。
###OCNInfo
https://www.ntt.com/personal/signup/internet/hikari/ipoe.html

###対処
IPoE設定をPPPoEに戻せばよいという情報があったが、OCNはだめでした。
さて、どうしたらVPN接続できるようにするか検討しなければ。。。

https://www.open-circuit.ne.jp/isp/settei/v6neo-hgw.html
設定URL:http://192.168.1.1:8888/t/
WPFでDataGrid内にEnumのComboboxを置く時のやり方

# 基本的にはhttps://teratail.com/questions/233982 のやり方。個人の備忘録
## ポイント
- DataGridTemplateColumnとDataGridComboBoxColumn  
前者はコンボボックスに限らずカスタマイズ性が高い。  
コンボボックスを作成したときにワンクリックで切り替えができる。  
後者はコンボボックス専用で独特。（未検証）  
コンボボックス作成時に二回クリックしないと切り替えられない。  
- DataGrid.AutoGenerateColumns  
単にObservableCollection表示するだけなら自動で作成されるのでこれをTrueにすると早い  
AutoGenerate字のコールバックを登録できて若干のカスタムはできるがよりいじりたい場合はFalseにする
- Comboboxの初期を設定するために
EnumのComboBoxは初期値が設定できないようである。手動で選択して表示させることはできた。  
DataGridのロード時のコールバックで全部のCellのSelectedIndexを設定した  
SelectedIndexは「現在コンボボックスの何番目を選択しているか」が記録されるプロパティ  
SelectedItemには「現在コンボボックスで選択されているVM」が入っていて、SelectedIndexを設定したらこのプロパティにも設定されているのを確認したが、SelectedIndexに値を設定してもそんな値ないといわれた
  - SelectedIndexとかSelectedItemとかSelectedValueとか  
SelectedIndexは上記。SelectedItemはコントロールによくある、選択してるオブジェクトがそのまま入ってくるやつなので、Bindしたりすればいい
  - DataGridのDataTemplateとしてComboBoxを使用すると、ComboBoxにx:Nameで名前付けしてもコードビハインドから参照することはできない  
  http://gacken.com/wp/program/wpf/641/ の例のようにVisualTreeから取得するのが良い。公式にもVisualTreeから取得するサンプルはあるがこのサイトのほうが使えた

## WPF全般
- x:Nameでコントロールに名前を付けてコードビハインドから参照する際に、デバッグ中に書き換えてもそんな名前はないといわれる
Streamlitで複数ページのWebアプリを作る

[2022/09/28追記]
- 最新の方法についてまとめた記事を作りました。こっちを参照してください。こっちの方が簡単なので。
    - https://qiita.com/yoichi_t/items/065779ddf0a528289cbf

[2022/09/07追記]
- マルチページアプリ作成の方法が公式にサポートされているようです（まだ試してない）
  - https://blog.streamlit.io/introducing-multipage-apps/
  - 上記公式ブログで書かれています
- なので、ここで書いている方法はもう古いです
    - 最新のやり方については試してから別途まとめると思います

# 概要

- Streamlitを使うとデータ閲覧用のWebアプリが簡単に作れる([参考１](https://qiita.com/yoichi_t/items/41ec07286a963b5e2eee), [参考２](https://qiita.com/yoichi_t/items/f99f4153f9b6b6ce7331)) 
- しかし、１ページにたくさんの情報が並ぶと読みにくい
- なので、複数ページのWebアプリにした
- ということで、できたもの → [Chocolate Ball Viewer](https://chocolate-view.herokuapp.com/)


# Streamlit

[Streamlit](https://www.streamlit.io/)はWebアプリを作るためのPythonフレームワークです。細かい調整はできないけど、めちゃめちゃ簡単にWebアプリを構築することができます。
[公式ドキュメント](https://docs.streamlit.io/en/stable/)でチュートリアルを眺めれば雰囲気が掴めるかなと思います。

例えば, `single_app.py`として以下のPythonファイルを作ったとします。

```python
import streamlit as st

def greeting1():
    st.header('こんにちは, 世界！')
    st.write('ねこはかわいい')

def greeting2():
    st.header('またまたこんにちは, 世界！！')
    st.write('ねこはとてもかわいい')

greeting1()
greeting2()
```

あとは以下のコマンドでデフォルト8063ポートでローカルにWebサーバが立ち上がります。

```
$ streamlit run single_app.py
```

これだと一つのページに全ての情報が記載されてしまいます。種類の違う情報は別ページに分けたいですね。
ということで、複数ページのWebアプリを作ります。


# Streamlitで複数ページを作る

[こちらの記事](https://medium.com/@u.praneel.nihar/building-multi-page-web-app-using-streamlit-7a40d55fa5b4)をほぼ丸々コピーしただけなので、こっちを読んでください。

Streamlitで複数ページのWebアプリを作るためには、アプリを一つの関数で呼び出せるように書いておきます。例えば、上記の例では、`greeting1`や`greeting2`のことです。
そして、サイドバーにアプリを選択するためのウィジットを設置し、対応する関数を呼び出します。(上記の参考ページを見てください)

これでも実装は簡単なのですが、便利なクラスが公開されています（[streamlit-multiapps](https://github.com/upraneelnihar/streamlit-multiapps)）。
この、「streamlit-multiapps」を使ってMultiPageのWebアプリを作るには以下の4つのステップを踏みます。

1. `MultiApp`クラスをimportしてインスタンスを生成
2. 別ファイルなどで、表示するコンテンツを定義（例えば`greeting1`や`greeting2`）
3. `MultiApp`クラスのインスタンスに`add_app(title, func)`でコンテンツを登録
4. runする

これで、サイドバーにラジオボタンが設置され、表示するコンテンツを選択できるようになります。

例えば、

```python
import streamlit as st
from multiapp import MultiApp

def greeting1():
    st.title('こんにちは, 世界！')
    st.write('ねこはかわいい')

def greeting2():
    st.title('またまたこんにちは, 世界！！')
    st.write('ねこはとてもかわいい')


app = MultiApp()
app.add_app("page1", greeting1)
app.add_app("page2", greeting2)
app.run()
```

こんなページができます。

![multi_page_sample1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66005/d324aa9a-9e56-551b-6940-976ac2c810dc.gif)


# できた

[前回](https://qiita.com/yoichi_t/items/f99f4153f9b6b6ce7331)公開したチョコボールデータを閲覧するためのWebアプリを複数ページにしました。
[Chocolate Ball Viewer](https://chocolate-view.herokuapp.com/)

内容量の閲覧と、エンゼル出現確率のシミュレーションは内容が結構異なるので、別ページに分けたということです。

![multi_page_choco.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66005/78c0d5a2-421f-0b71-c1ce-fc8461ca9140.gif)

おわり


# 参考

1. [Building Multi Page Web App Using Streamlit](https://medium.com/@u.praneel.nihar/building-multi-page-web-app-using-streamlit-7a40d55fa5b4)
1. [streamlit-multiapps](https://github.com/upraneelnihar/streamlit-multiapps)
1. [Streamlitでデータを可視化する](https://qiita.com/yoichi_t/items/41ec07286a963b5e2eee)
ヘッダーに変な隙間ができる原因2選とそれぞれの解決方法

#どうも7noteです。ヘッダーに隙間ができる謎を解明していきます。

大きく2つの原因が考えられます。

**・body,htmlの標準marginが効いている
・ファイルがBOM付きファイルである**

それぞれの原因の確認方法を見ていきたいと思います。

## ヘッダーの隙間を解決するなら「marginを見る」

※googleChromeでの手順です。ほかのブラウザではボタンやメニューの名称が異なるかも。

### 原因確認方法
[ブラウザを右クリック]→[検証]→[検証ツールのElementsでbodyタグをクリック]→オレンジ色になっている部分があれば標準のmarginが効いているということ。

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/6c9ab44d-b14e-3fef-2100-e79b6f32937d.png)

↓↓↓↓↓↓↓↓↓↓

**「初期のmarginは無効化させる」**

```style.css
/* 無難な書き方 */
body,html {
  margin: 0;  /* 解決するため */
  padding: 0; /* 入れておくと無難 */
}
```

これで対応できます。

## それでも解決できないならファイルがBOM付きファイルでないか確認する。

UTF-8には2種類あり、BOM付きのファイルかBOM無しのファイルがあります。
もしBOM付きのファイルだとソース上に謎の1行が増えているはずです。

**確認方法**

BOM付きか判断できるエディタで、ファイルの文字コードを確認する。
もしBOM付きになっていれば、チェックを外すなどして文字コードを変更。

エディタでBOM付きかどうかを見る方法は→[こちら](https://www.1-firststep.com/archives/2258#link-scroll-6)

この写真はBOM無しの例。もしBOM付きであれば「UTF-8(BOM付き)」などの表記になっていたり、文字コードを選択する欄の近くにBOMをつけるかどうかのチェックがあるかを確認します。

![sample2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/1c77ebe9-7fd3-3f82-9585-04594ec89af4.png)

## まとめ

原因不明の余白がある時はほぼこの2つの問題のどちらかである場合が多いです。
ふとした瞬間にひっかかってしまいますが、原因さえ知っていれば対策は簡単です。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
バリデーションについて

#目次
<b>①バリデーションとは</b>
<b>②バリデーションを行う理由</b>
<b>③バリデーションの基本的な実装</b>
<b>④様々なバリデーションの例</b>

##①バリデーションとは
データを登録する際に、一定の制約をかけること。

以下のようなものがある。
・空データを登録をできないようにする
・文字数の制限を設ける
・空を許可する
・同一データは一つのみ許可する
など
##②バリデーションを行う理由
正しいデータだけをデータベースに保存するために行われる。
たとえば、自分のアプリケーションで、すべてのユーザーには必ず電子メールアドレスとメーリングリストアドレスが必要だとする。正しいデータだけをデータベースに保存するのであれば、モデルレベルでバリデーションを実行するのが最適になる。モデルレベルでのバリデーションは、データベースに依存せず、テストもメンテナンスもやりやすくなる。


##③バリデーションの基本的な実装
バリデーションを設定するときは、モデルにvalidatesメソッドを使用して記述する。

```

validates :カラム名, バリデーションの種類
#書き方
```

##④様々なバリデーションの例
<b>◯空データを登録できないようにする

```
class Human < ApplicationRecord
　validates :name, presence:true
end
```

<b>◯文字制限を設ける

```
class Human < ApplicationRecord
　validates :name, presence:true,length: {maximum:30}
  #名前の長さの上限を30文字

　validates :name, presence:true,length: {minimum:2}
  #名前の長さの下限を2文字

  validates :name, presence:true,length: {in:2..30}
  #名前の範囲を2-30文字

　validates :name, presence:true,length: {is:5}
  #名前の範囲を5文字に指定

end
```

<b>◯空を許可する

```
class Human < ApplicationRecord
　validates :age, allow_blank: true
end
```

<b>◯同じデータは一つのみ許可する

```
class Human < ApplicationRecord
　validates :email, presence:true,uniqueness: true
end
```
「今あるもので」できたウェブカメラの話

半分備忘録な記事ですが、どなたかのお役に立てばと思って公開します。

背景には「すでに持ってるものを使いたい、そのままだと勿体ない」という考えがあります。
2020の春ぐらいから、自分のデスクの下の方の棚に使わなくなって（下取りの期限をうっかり見逃した :sweat_smile: ） iPhone 6s が眠っていました。
今回は、この若干ボロい iPhone 6s をウエブカメラにした手順を説明します。

必要なもの：

- いうまでもなく、iPhone とパソコン :wink: 
- iPhone をPCかマックにつなぐためのケーブル
- EpocCam というアプリと、PC/Macにインストールするドライバー
- 時間が少し

## EpocCam

https://www.elgato.com/ja/epoccam

基本的に無料ですが贅沢した場合、有料版では：
- HD画質の対応
- カメラの映像をピンチでズームできる機能
- スマフォのライトを使う
なども出来ます。

1000円もしないので接続を無料版で試してから購入をおすすめします。

パソコンにインストールするためのドライバはここから落としてインストールします。終わったら再起動しておきましょう。

Windows >> https://www.elgato.com/gaming/downloads#epoccam-win
MacOS >>  https://www.elgato.com/gaming/downloads#epoccam-mac

インストールと再起動終わったら、iPhoneにアプリを入れましょう。
カメラ、ネットワークへのアクセス許可は必須なので、設定を忘れず。

## 接続して、使うまで

無料版のアプリでは、使う接続（ケーブルか、Wifiか）が選べず、試した限りWifiが優先のようです。
Wifi でつなげたい場合は、パソコンとiPhoneが同じネットワークに接続している必要があります。
（同じWifiルーター、という意味です。同じネットワーク内にあるWifiとLANそれぞれでつないだ場合、自分の場合はうまくつながらなかったです。）

ケーブルでつなげる場合は、iPhoneのWifiをオフにしておけば、素直に接続してくれます。

Meet でためしたときの画面ですが、このようにカメラの一覧から選択できるようになります。

![スクリーンショット 2021-01-26 21.03.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155732/a0f9a1e3-7a20-4d8c-87f1-e266c21c7879.png)


## 画質は？！

（スクショ取る時、ミラーリングするのを失念！デフォルトではスクショの通りに写ります。）

無料版だと、まあ・・・ 角々します。

![スクリーンショット 2021-01-26 21.03.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155732/212d4bb9-5dcb-5758-9e13-03c4c9ee8345.png)

有料版（うまくつながったので買いました！980円〜）は流石にそれなりにきれいです。iPhoneも古いので、新しい機種だったらもっとくっきりした映像になりそうです。

![スクリーンショット 2021-01-26 21.10.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155732/c36c7149-0814-8967-fd28-d9f28d708533.png)

## 最後に

以上、接続までの手順は本当にかんたんで、眠ってる iPhone がこれで役割ができて嬉しい限り。
明日から、内蔵カメラで頑張る日々が終わりそうです! :smile:
log

@echo off

rem 出力されたファイル名に日時を付く
if exist %1%2%3 (
	cd %1
	rename %2%3 %2"_%date:‾0,4%-%date:‾5,2%-%date:‾8,2%_%time:‾0,2%-%time:‾3,2%-%time:‾6,2%"%3
)
GitHub Pagesでポートフォリオを公開する手順

無料で簡単に静的なサイトを公開できるGitHub Pages。
ポートフォリオなどを手軽に公開できるため、多くのエンジニアやデザイナーが使っていると思います。
今回はGitHub Pagesでリポジトリを公開するまでの手順をまとめます。

> …手順という手順が無いレベルの話ではあるんですけどね…。

## 公開用のリポジトリを用意する
モノがなくては始まらないので、リポジトリを用意しましょう。
ルートフォルダの`index.html`がいちばん最初に表示されるページになります。これも作っておきましょう。

特にセンシティブなデータを扱うことがないなら、この時点でPrivateではなくPublicなリポジトリにしておくことをオススメします。

## リポジトリを公開する
公開方法は簡単で、リポジトリの`Settings`ページにある`GitHub Pages`の欄をいじるだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007176/5cc40ea6-e948-ff20-90eb-ae5bfd98fd40.png)

`Source`のところがプルダウンになっています。プルダウンメニューから公開したいブランチを選択してください。

ブランチを選んだら以下のようにフォルダを選ぶメニューも出てきます。公開したい方を選んでください。
`/(root)`ならリポジトリ直下のすべてが、`/docs`ならdocsフォルダ内のファイルが公開されるようです。（今回はrootでいきました）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007176/d1ce30ca-5a26-6a92-2285-3dc95c0388ba.png)

## Privateリポジトリを公開したい場合
僕は今回プライベートリポジトリで開発していたため、公開するときにつまずきました。
プライベートリポジトリで先ほどと同じくSettingsのページを見ると、以下のようになっていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1007176/464469b2-0ae2-4604-77ab-d84a352a4eaf.png)

どうやら執筆時点では、プライベートリポジトリを公開するなら有料会員になる必要があるようです。
**「ソースコードは内緒にしたいけど作品は公開したい！」**という人は有料会員になってみてくださいまし。

## まとめ
あっという間にページが公開できました。手順(?)をざっくりまとめると以下。

1. Publicなリポジトリを作る
2. ソースコードを書く
3. リポジトリのSettingsで公開するブランチとフォルダを選ぶ

ちなみに、データベースとやりとりするような、バックエンドを孕むアプリは公開できないため注意が必要です。
あくまで静的なページに限ります。

もっと詳しく知りたいかたは、公式ドキュメントをぜひご覧ください。
https://docs.github.com/ja/github/working-with-github-pages/about-github-pages

> なんだか公開するのが簡単すぎて、ちょっと感動でした。ちゃんちゃん。
【Swift】FirebaseAuthを使ったログイン判定でVCを分ける

# 前提

- Firebaseのインストールなどは済ませておく
- ストーリーボード（この記事ではMain.storyboard）でViewControllerそれぞれの `identifier` に名前を付けておく
  - この記事ではログインしてる場合のVCを `viewVC` 、ログインしてない場合のVCは `loginVC`

## SceneDelegate.swiftに書く

```swift:SceneDelegate.swift
import UIKit
import FirebaseAuth

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

  var window: UIWindow?

  func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

    // ここから追記

    // ログイン判定
    if Auth.auth().currentUser?.uid != nil {
        
        // ログインしている場合
        let window = UIWindow(windowScene: scene as! UIWindowScene)
        self.window = window
        window.makeKeyAndVisible()
        
        // Main.storyboardを指定
        let storyBoard = UIStoryboard(name: "Main", bundle: nil)
        // storyboardのidentifierで名付けたVCをインスタンス化
        let viewVC = storyBoard.instantiateViewController(identifier: "viewVC")
        // 上記をrootのコントローラとしてインスタンス化
        let navVC = UINavigationController(rootViewController: viewVC)
        
        window.rootViewController = navVC
        
    } else {
        
        // ログインしてない場合
        let window = UIWindow(windowScene: scene as! UIWindowScene)
        self.window = window
        window.makeKeyAndVisible()
        
        let storyBoard = UIStoryboard(name: "Main", bundle: nil)
        let loginVC = storyBoard.instantiateViewController(identifier: "loginVC")
        let navVC = UINavigationController(rootViewController: loginVC)
        window.rootViewController = navVC
    }
    
    guard let _ = (scene as? UIWindowScene) else { return }
  }

// 以下略
```

`scene` のメソッドに追記するだけです。
条件が合えばコピペでいけると思います。チャオ。
Tensowflow "Could not load dynamic libary 'cudart64_110.dll'; dlerror: cudart64_110.dll not found

#上記のエラーが出たときの対処法

解発環境
OS: Windows 10
ターミナル: Anaconda Prompt(Anaconda 同梱)

大まかな手順
- CUDA Toolkitのインストール
- ターミナルを閉じて再度開く
- ターミナルでテストコードを再実行

## CUDA Toolkitのインストール
[CUDA Toolkit 11.2 Downloads](https://developer.nvidia.com/cuda-downloads?target_os=Windows&target_arch=x86_64&target_version=10&target_type=exelocal)からCUDA Toolkitというのをダウンロードします。(自身の環境に合わせて選択して下さい。)
![cuda download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531595/2d0306d2-80ce-db1d-3f8c-a4c0b2e0c7ce.png)

ダウンロードしたら次は、インストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531595/c2d8d84b-d989-1d0d-bb82-27a64cac2f1c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531595/7500cc6e-a00a-813e-6918-4ae793bbc944.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531595/4e7752da-65f7-1b24-d3b8-d9d1cbad1894.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531595/4568e579-c7c5-7eed-e9f0-26648f05762f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531595/c20f52e7-43e3-604d-9225-69602bfce4ca.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531595/843c5e3e-7f46-0651-8829-63a285538bf2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531595/b0588129-31ea-e094-ef14-2c7cfca485d7.png)

インストールが終わったら、起動せずに閉じて大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531595/7d10224c-ced0-8304-3776-68280c63323f.png)

`Anaconda Promptは一度閉じて、再度開きます。`

## テストコードを再実行

```qiita:anaconda-prompt
(t3.8) C:\Users\owner>python
>>>import tensorflow as tf
>>>mnist = tf.keras.datasets.mnist
>>>
>>>(x_train, y_train),(x_test, y_test) = mnist.load_data()
>>>x_train, x_test = x_train / 255.0, x_test / 255.0
>>>
>>>model = tf.keras.models.Sequential([
>>>  tf.keras.layers.Flatten(input_shape=(28, 28)),
>>>  tf.keras.layers.Dense(128, activation='relu'),
>>>  tf.keras.layers.Dropout(0.2),
>>>  tf.keras.layers.Dense(10, activation='softmax')
>>>])
>>>
>>>model.compile(optimizer='adam',
>>>              loss='sparse_categorical_crossentropy',
>>>              metrics=['accuracy'])
>>>
>>>model.fit(x_train, y_train, epochs=5)
>>>model.evaluate(x_test, y_test)
```

(実行結果)

```qiita:anaconda-prompt
2021-01-26 20:47:14.909869: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:116] None of the MLIR optimization passes are enabled (registered 2)
Epoch 1/5
.
~(途中省略)~
.
1875/1875 [==============================] - 1s 789us/step - loss: 0.0743 - accuracy: 0.9760
```
これで、実行に成功しました。

参考ページ: [How to fix TensorFlow warning: Could not load dynamic library 'cudart64_110.dll'; dlerror: cudart64_110.dll not found](https://ourcodeworld.com/articles/read/1433/how-to-fix-tensorflow-warning-could-not-load-dynamic-library-cudart64-110dll-dlerror-cudart64-110dll-not-found)
matplotlibでグラフを表示しないで画像として保存する

#１．背景
　第2回Neural Network Console Challengeへ参加させていただき、試行錯誤した内容を備忘録としてピックアップします。何回かに分けて投稿予定（あくまで予定）。初心者のプログラミングなので、面倒くさいことをやっている可能性大ですが、暖かい目で見守ってください:sweat_smile:。チャレンジ内容詳細は[過去の投稿](https://qiita.com/n91-takayuki/items/5e289c898cdddd2a6e2f)を参照ください。

#２．コード
　ディープラーニングの学習データとして、音声データをメル周波数スペクトログラムの画像へ特徴量化する必要があり、[librosa](https://librosa.org/doc/latest/index.html)を使って変換しました。librosaには結果を表示する関数が用意されており"librosa.display.specshow"を使いmatplotlibで可視化するのが一般的かと思います。この時、いちいちグラフが表示されてしまい、すぐにメモリ不足の状態になります。plt.close()を使うとこれを簡単に回避できます。コードはざっくり下記。

```python
plt.figure(figsize=(2, 1), dpi=100)
librosa.display.specshow(log_S, sr=sr) #librosaの結果表示
plt.subplots_adjust(left=0, right=1, bottom=0, top=1) #余白を調整
plt.savefig("fig.png")
plt.close() #←これ！
```
これをfor文で繰り返し保存してけばOK。Neural Network Console Challengeでは10,000点を超える音声データをグラフ（画像）データへ変換し保存しましたが、問題なしでした。
【効率化】Emmetの使い方

#はじめに
最近Web制作の案件を受注できたプログラミング初心者。
Emmetついて、まとめたので投稿しますわ😇


##目次
[Emmetとは](#Emmetとは)
[HTMLの雛形](#HTMLの雛形)
[単体](#単体)
[要素を入れ子にする](#要素を入れ子にする)
[要素を複数作成する](#要素を複数作成する)
[要素を同階層に作成する](#要素を同階層に作成する)
[idとclass](#idとclass)
[混ぜて使用してみた](#混ぜて使用してみた)
[CSSの記述](#CSSの記述)

##Emmetとは
HTMLやCSSの記述をサポートしてくるプラグインのこと。
独自の省略記法によるコーディング作業を効率化している。
Web制作のお仕事は出来上がった成果物に対して報酬が出るので、
時給という概念では捉えづらい🤔

作業時間が長くても報酬には比例しないため、作業時間を短縮できれば単価向上に繋がる。
そのため、Emmetを使いこなすことは重要かと考える👍

##HTMLの雛形
```html
!
↓
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
</body>
</html>
```

##単体
```html
div
↓
<div></div>
```

##要素を入れ子にする
```html
div>p
↓
<div>
  <p></p>
</div>
```

##要素を複数作成する
```html
li*5
↓
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
```

##要素を同階層に作成する
```html
header>h1+p
↓
<header>
  <h1></h1>
  <p></p>
</header>
```

##idとclass
☆id

```html
#box
↓
<div id="box"></div>
```

☆class

```html
.p
↓
<div class="p"></div>

p[class=box]
↓
<p class="box"></p>
```
<font color="red">★[]外で指定しなければ自動的にdivタグとなる。</font>


##混ぜて使用してみた
```html
ul>(li[class=box$]>a{たくみの分身$})*5
↓
<ul>
  <li class="box1"><a href="">たくみの分身1</a></li>
  <li class="box2"><a href="">たくみの分身2</a></li>
  <li class="box3"><a href="">たくみの分身3</a></li>
  <li class="box4"><a href="">たくみの分身4</a></li>
  <li class="box5"><a href="">たくみの分身5</a></li>
</ul>
```

<font color="red">★連番で名前をつける場合は「$」を使用する。
　テキストの挿入には{}を使用する。</font>

##CSSの記述
```css
.container{
  w70+h70+m70e+p70r
}
↓
.container{
  width: 70px;
  height: 70px;
  margin: 70em;
  padding: 70rem;
}
```

#参考
・1分を節約する為にEmmetのHTMLとCSS記述方法を学び直し&まとめシートを作る。
　https://qiita.com/tanimoto-hikari/items/8848445babdfe3586592
・Emmetでマークアップを効率化しよう（HTML&カスタマイズ編）
　https://www.granfairs.com/blog/staff/efficiency-by-emmet-01

#おわりに
軽く目を通す
⇅
使う時が来たら思い出して使用する
を繰り返して覚えていきました。

また、Emmetをタイピングアプリの感覚で遊べるツールがあったので
紹介しておきます🙌
https://emmpra.com/
Adobe Acrobatを開くときに数十秒フリーズする

Adobe Acrobatを開く際に, 数秒から30秒程度フリーズすることがあり悩まされていたので解決策を残します.

#発生する現象と条件

* Acrobat起動時, 及びPDFファイルオープン時
* PDFの表示はされるものの, その直後に最大30秒程度"応答なし"になる
* 心当たりはないが, 気づいたら発生するようになっていた
* PDFファイルのサイズには関係なく, 1ページのファイルを開いただけでも固まる


#解明した原因

* Recently used list(最近使用したファイル)の中に, 切断されたネットワークアドレスのファイルがある

自宅から職場にVPNで繋ぎ職場のNASのPDFを開いていましたが, そのファイルがRecentに追加され, VPNを切った際にAcrobatが探しに行くもののアクセスできないせいでフリーズが起きていました.


#解決策

* 新しくPDFを開きまくって, Recentから見つからないファイルを消す (効率が悪いので今回はやりませんでした)
* Recentに保存するファイル数を少なくする(以下参照)

Acrobatの上部 `Edit > Preferences...` へと進み, `Documents` 内の `Documents in recently used list` の数字を変更する.
デフォルトが100だったため, 今回は5まで減らした.
元々このリストからファイルを開くことは無かったので問題なし.
![2021-01-26_LI_Moment.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219949/1352b114-d913-88ea-6eb2-38a91ac63848.jpeg)

#結果
色々試しましたが, この操作をした直後から, 普段どおりのサクサク動作に戻りました.
Acrobatがフリーズする要因として, 他にはセキュリティ関係の設定変更で解消する方も多いようですが, 今回は違う原因だったようです.
rails sを実行してもサーバーが動かない！サーバー起動の解決方法【var_6.0.0_】

#状況
ターミナルにてサーバーを動かすコマンドを実行してもサーバーが動きませんでした。
`% rails s
`

#ターミナルのエラー内容

以下がターミナルに表示されたエラー内容です。
Rails is not currently installed on this system. To get the latest version, simply type:

　$ sudo gem install rails

You can then rerun your "rails" command.

今までRailsを使ってきましたがこのようなエラーは初めてでした。
そのまま検索すると、エラー内容について詳しく解説が載っています。

こちらのエラー内容は「Railaはインストールされていない」という意味です。

「ん？前日夜までターミナルでサーバー動かしていたよな？」
と思ったのですが、エラーでRailsがないと言われているので大人しく従います。


#エラーの原因
私の場合なぜ急にこのような事態になったのかというと、MacOSが自動でアップデートされたことが原因と考えられます。
エラーの原因はrbenvとgemが入り組んだことによって引き起されるものらしいです。
以下の記事で、rbenvとgemが入り組んだ状況をわかりやすく解説しているので気になたかたはご覧ください！
https://qiita.com/w7tree/items/0860e2856f2429b20eee

#解決策
ターミナルで以下のコードを実行していきます。

`$ export PATH="$HOME/.rbenv/shims:$PATH"
`

この後、gem install rails を行い、railsをインストールすることができました。