OmniAICreator/Qiita-1.07M huggingface dataset:
代理キーと代替キーの違いについて

# はじめに
リレーショナルデータベースの文脈において混同されがちな、代理キー(alternate key)と代替キー(surrogate key)についてまとめました。

# 代理キーとは
**代理キーは主キーに選ばれなかった候補キー**のことを指します。オルターネイトキーとも呼ばれます。混乱を避けるため、オルターネイトキーと呼ぶことをおすすめします。

例を示します。

```
Personnel(company_id, emp_id, name, mail_address)
```

関係変数`Personnel`には`(company_id, emp_id, name, mail_address)`属性が含まれます。全ての社員は一意な`company_id`と`emp_id`の組を持ち、またすべての社員は一意な`mail_address`を持つという要件があるとします。
このとき、関数従属性は以下の通りです。

```
{company_id, emp_id} -> {name, mail_address}
{mail_address} -> {company_id, emp_id, name}
```

よって、候補キーは`{company_id, emp_id}`または`{mail_address}`です。[^1]
ここで、`{company_id, emp_id}`を主キーに設定したとします。すると、候補キー`{mail_address}`が余ります。この主キーに選ばれなかった候補キーこそが、オルターネイトキーです。

[^1]: キー属性からキー属性への関数従属性があるため、この関係変数は第三正規形であってボイスコッド正規形ではありません。

# 代替キーとは
**代替キーは人工的に付与されたキー属性**の事を指します。対義語は自然キー（ナチュラルキー）です。**サロゲートキー**とも呼ばれますが、たいていの場合は**代理キーと混同されて呼ばれています**。混乱を避けるため、サロゲートキーと呼ぶことをおすすめします。
Ruby on RailsなどのORMフレームワークによってテーブルを作成すると、自動的に連番のidが付与されることがあります。このidがサロゲートキーです。サロゲートキーは開発環境と本番環境とでidがずれるなどの**厄介な問題を引き起こす**ことがあるため、開発にRailsを利用しているなどのやむを得ない事情がなければ、自然キーを主キーに設定することをおすすめします。

例を示します。
先ほどの関係変数`Personnel`をRailsのマイグレーションで実装したとします。Railsは自動的に連番のidを付与する仕様になっているため、出来上がった`Personnel`テーブルの構造は次の通りになりました。

```
Personnel(personnel_id, company_id, emp_id, name, mail_address)
```

主キーは**サロゲートキー**である`{personnel_id}`、**オルターネイトキー**は`{company_id, emp_id}`および`{mail_address}`ということになります。
お察しの通り、この文脈で代理キーと代替キーとを混同した場合、相当ややこしいことになるでしょう。

# まとめ
代替キーと代理キーとの混同は、サイゼリアでアボガド料理を食べながらファイヤーエンブレムを遊ぶようなものなのでやめましょう。
PlayCanvas で class を使う

少し前に ES6 に対応していたようで、よく見たら class にも対応していました。

https://developer.playcanvas.com/en/api/pc.html#registerScript

以下の書き方で class の記法で ScriptRegistry への登録を行えます。

```javascript
// define a ES6 script class
class PlayerController extends pc.ScriptType {

    initialize() {
        // called once on initialize
    }

    update(dt) {
        // called each tick
    }
}

// register the class as a script
pc.registerScript(PlayerController);

// declare script attributes (Must be after pc.registerScript())
PlayerController.attributes.add('attribute1', {type: 'number'});
```

リンク先の公式ページにも書いてありますが、 pc.ScriptType の継承は必須です。
また、`pc.registerScript()`の後でしか`attributes.add()`できないらしいです。

---

個人的には、こっちの書き方の方がUnityっぽくていいのですが、
`attributes.add()`がメソッドの定義より下に来てしまうのがなんとなく気持ち悪いので、
prototype を使う普通の書き方を使用しようか迷い中です。
Excel ファイルを共有すると、印刷範囲がズレる。プリント範囲を追加ボタンがない

問題
Mac、３６５エクセルで作った資料を共有すると（Windowsの人が見ると）印刷範囲がずれてしま
２ページ目がみきれちゃってる...



印刷範囲を設定しよう！
としたけれど、
１ページ目はできた。
２ページ目を作ろうとしたけど、
「印刷範囲を追加」ボタンが出てこない。。。
これ↓
![スクリーンショット 2021-05-14 16.32.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/44c14325-b1ff-3cd8-0d10-22b33c2f6906.png)


解決策
「表示」の「改ページプレビュー」だ！
これ
![スクリーンショット 2021-05-14 16.38.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/661620ad-1016-c1a0-c1e9-db126f5a1290.png)
手順
１、まず
ページレイアウト→ページ設定→ページ
拡大縮小にチェック
![スクリーンショット 2021-05-14 16.40.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/cdc03e0d-d3ee-051d-f6bd-429ffd8c1e52.png)
![スクリーンショット 2021-05-14 16.27.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/7b8195f2-c156-ceb2-f242-8f5b207e1413.png)

２、印刷したい範囲のセルを選択し、
ページレイアウト→プリント範囲を設定
![スクリーンショット 2021-05-14 16.45.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/f6ba9682-f316-9148-dac9-2dc207945f89.png)

３、表示→改ページプレビュー
青い線が出てきたらマウスで引っ張ると、
「２、」で指定した範囲で下に伸びてくれる！
![スクリーンショット 2021-05-14 16.47.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/a25f3fd8-8710-012e-4301-d3cb07a0c1ef.png)

![スクリーンショット 2021-05-14 16.49.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/f838d411-b6af-9f2d-d8e6-4c721daac1ff.png)
React×Amplifyでブログサイトを作成

React、TypeScript、ReduxToolKit、Amplifyの学習の一環と自前のブログサイトが欲しいと思いがあったので、実際にブログサイトを作ってみました。

#仕様技術/ライブラリー
* React
* TypeScript
* Redux（ToolKit)
* Amplify、Appsync、AWS
* GraphQL
* chakra-ui
* react-share
* react-simplemde-editor

#UI画像一覧

 **一般ユーザーのHome画面**
![スクリーンショット 2021-05-14 14.40.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233228/563ec409-2032-4821-be9d-e21a1a790652.png)
**一般ユーザー記事詳細画面**
![screenshot-www.ryota-programming-blog.com-2021.05.14-14_43_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233228/4eb13738-1ddf-c956-47e6-6138f578671d.png)
**ログイン画面**
![スクリーンショット 2021-05-14 14.45.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233228/6634ec92-2df8-3a94-93a9-f61b74cad955.png)
**管理者側記事詳細画面**
(編集と削除ボタンあり)
![スクリーンショット 2021-05-14 14.45.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233228/eb925736-35aa-e938-82c3-e30eaeea5cfa.png)
**記事編集画面**

![スクリーンショット 2021-05-14 14.49.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233228/7a3faa59-934a-9e66-5b21-abc75ab7cc7e.png)

**新規投稿画面**
![スクリーンショット 2021-05-14 14.46.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233228/15b00ebd-e7df-4fb8-03f6-3c88b08d3f05.png)

#仕様

* 一般ユーザーページ<br>
①記事一覧画面<br>
②記事詳細画面<br>
記事詳細画面トップ画像、作成日、更新日、コメント数、タイトル、本文、コメント機能、SNSシェア機能を実装。
コメント機能は記事に対してフィードバックが貰えたら嬉しいなという思いで実装しました。
（コメントするのにログインは必要なく、名前を記入しなくとも大丈夫です。）

* 管理者ユーザーページ<br>
①ログインページ
UIは自前ですが実際のログイン機能はAmplifyのAuthを使用。
サインアップはできないようにログイン機能のみを実装。
②記事一覧画面<br>
基本的には一般ユーザーと同様です。
③記事詳細画面<br>
基本的には一般ユーザーと同じ仕様ですが管理者側には編集と削除ボタンがあり。
（同じコンポーネントを使用してログインしているかどうかでボタンを表示したり非表示したりしています。）
④記事編集画面
記事の編集を行えます。
⑤新規投稿画面
マークダウン形式で記事の投稿、トップ画像の設定が可能。
（画像を設定しない際にはデフォルトでNO_IMAGEとなります）
またリロードしても内容が消えないようにローカルストレージを使用して一時保存可能。

Reduxでユーザー情報、コメント情報、投稿情報を管理させています。
DBはAmplify経由でDynamoDBを利用、GraphQLでAPIを叩いています。

# 制作を通して苦労した点
GraphQLのスキーマ定義にかなり苦戦しました。
特にauthの理解が乏しく最後の最後にログインしていないユーザーがコメントできないという事象が発生しました。
この原因が権限を userPoolsにしか付与していなかったことでした。なのでログインしていないユーザーにも権限を付与するためにGraphQLのスキーマを再定義してなんとか解消しました。GraphQLとAWSのインプットとアウトプットをもっと行い知識として定着させたいです。
# 制作を通しての感想
chakra-uiが便利で感動しました..。レスポンシブを容易に組めるのでUI構築がサクサクと進んでかなり効率的にアプリの作成ができました。
以前まで苦労していたTypeScriptはかなり慣れることができました。
この作品を作る前に別のアプリを作った際にTypeScriptを導入しませんでした。その時は思わぬところでエラーが出たりと苦戦することが多かったのでやっとTypeScriptの恩恵を得られるようになりました。

参考サイト

https://qiita.com/too/items/cb1dfb4f44536a3e9855
https://qiita.com/kazuhiro1982/items/b1183103f41b8e976f6a
https://qiita.com/Engineer_Grotle/items/fa37a3924d1e66082889
[rails] DateTime#agoがRails5.2まで1.dayといった引数を受け付けていたが6.0からダメになった原因を調べた

Rails6.0への更新中、理由が不明だった為調べました

```ruby
# DateTime#agoの実装
def ago(seconds)
  since(-seconds)
end
```

```ruby
# rails 5.2
DateTime.current
=> Fri, 14 May 2021 16:20:00 +0900
DateTime.current.ago(1.day)
=> Thu, 13 May 2021 16:14:26 +0900

# rails 6.0
DateTime.current
=> Fri, 14 May 2021 16:31:41 +0900
DateTime.current.ago(1.day)
TypeError: not an integer
from /bundle/gems/activesupport-6.0.3.7/lib/active_support/core_ext/date_time/calculations.rb:113:in `Rational'
```

5.2ではagoで呼ばれている`DateTime#since`の実装で、agoの引数をroundしてintegerとなっていたのが、roundしなくなりRationalの引数として不適切になったから出たエラーのようです。
PRを見た感じ、昔はroundをする意味があったが今は無いのでしなくなったという事かな?
そもそも、secondsを要求されているので1.dayといった値を渡していたのがおかしくて、たまたまroundされていただけで意図しない使い方していた気がする...!

素直にこう書いておきます

```ruby
DateTime.current - 1.day 
=> Thu, 13 May 2021 16:34:06 +0900
```


- [修正PR](https://github.com/rails/rails/commit/c85e3f65f3409fc329732912908c3601d8e5fac9#diff-0a796f781c7d02730f56174a5bb314a7102cf9fd16488c7f02ae6d897a70af89)
- [5.2 実装](https://github.com/rails/rails/blob/5-2-stable/activesupport/lib/active_support/core_ext/date_time/calculations.rb)
- [6.0 実装](https://github.com/rails/rails/blob/6-0-stable/activesupport/lib/active_support/core_ext/date_time/calculations.rb)
JSを使わず、animationプロパティを使ってマウスホバー時のスライドを作りました

``JS``を使わず　 ``animationプロパティ``を使ってマウスホバーした時画像がスライドするを作ってみました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">animation と <a href="https://twitter.com/keyfram?ref_src=twsrc%5Etfw">@keyfram</a> を使って画像をスライダーしてみた。<br><br>これのcodeをQiitaに掲載<br> <a href="https://twitter.com/hashtag/web%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2?src=hash&amp;ref_src=twsrc%5Etfw">#webエンジニア</a><a href="https://twitter.com/hashtag/animation?src=hash&amp;ref_src=twsrc%5Etfw">#animation</a> <a href="https://twitter.com/hashtag/HTML?src=hash&amp;ref_src=twsrc%5Etfw">#HTML</a> <a href="https://t.co/6yOEGZtEZW">pic.twitter.com/6yOEGZtEZW</a></p>&mdash; トモゑ☛Web作成の37🌺 (@swan2pink) <a href="https://twitter.com/swan2pink/status/1393093048574251009?ref_src=twsrc%5Etfw">May 14, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

codepenでコードを書いてみました

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="html,result" data-user="swan2pink" data-slug-hash="VwpazmV" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="VwpazmV">
  <span>See the Pen <a href="https://codepen.io/swan2pink/pen/VwpazmV">
  VwpazmV</a> by トモゑ☛Web作成の37🌺 (<a href="https://codepen.io/swan2pink">@swan2pink</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


```css
.main1 {
  position: relative;
  width: 300px;
  height: 300px;
  overflow: hidden; ※
}
.second {
  position: absolute;
  top: 0;
  left: 0;
}
```
``@keyfram``　でスライドした際の画像格納場所をどうすれば良いかを悩みました。
結果、``overflow: hidden``を親要素につけたら上手に納まりました。

参考資料
[overflow:hiddenやscrollが効かない原因と対応方法] (https://csshtml.work/overflow-bad/)


##まとめ
こんなcodeもシンプルで良いですよとかありましたらご連絡ください
とっても喜びます！

今回は以上です
ありがとうございます！！
const と auto と pointer

よくわかんなくなるので。

|宣言|実際の t の型|値が不変|ポインタが不変|
|--|--|--|--|
|const auto t = new T();|T *const|×|〇|
|const auto *t = new T();|const T*|〇|×|
|const auto *const t = new T();|const T *const|〇|〇|
|auto const t = new T();|T *const|×|〇|
|auto const *t = new T();|const T*|〇|×|
|auto *const t = new T(); |T *const|×|〇|
|auto const *const t = new T();|const T *const|〇|〇|

覚え方としては

1. const auto が auto const に置き換えられる
1. auto が T* ないし T に置き換えられる
1. T const が const T に置き換えられる

で実際の型が決まったうえで、

- const のすぐ左にくるものが不変となる
- const が一番左のときはすぐ右にくるものが不変となる

で値やポインタが不変かどうかが分かる。

ようするに const auto って書かないで auto const って書くようにしてたほうがすんなり理解できるようになるんじゃないかな、たぶん
react-native-webviewのキャッシュを使用しない設定

## cacheEnabled
公式のAPIリファレンスに `cacheEnabled` というプロパティがあったので、
 `cacheEnabled={false}` を追加するとAndroidはキャッシュを使用しなくなったがiOSは変わらなかった。

## incognito
`incognito={true}` を追加するとiOSもキャッシュを使用しなくなった。

## 参考
[公式APIリファレンス](https://github.com/react-native-webview/react-native-webview/blob/master/docs/Reference.md)
[WebView still reads resources from the cache with cacheEnabled={false} #880](https://github.com/react-native-webview/react-native-webview/issues/880)
UiPathとノーブレークスペース

#1.ノーブレークスペースのこと
突然ですが、ここで問題です。
下図のワークフローを実行すると、どちらのメッセージボックスが出現するでしょうか？
![ui10.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1401870/96e12373-4cb6-a33c-611b-8c8cd0dda035.jpeg)

答えは「『不一致です』が出現する(=Elseルート)」です。
![ui11.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1401870/028df21c-362d-9081-a5b6-bc19ec7cae20.jpeg)

もちろん、【普通のデータ】なら『一致しています』メッセージが出現しますし、人の目だと一致してるように見えるので「なんで？？？」と思いますよね。私も当時そう思ってました。

ところが…実はCellA2の冒頭に「ノーブレークスペース」という見えない空白が存在しています。
カーソルを末端に置いた後、1個ずつ左にカーソルを移動させると「何かある」というのが分かります。
![ui12.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1401870/15998d1b-b0a4-a6e5-634f-b35ebdc1a8c5.jpeg)

#2.対処法
ノーブレークスペースが出現した原因は不明ですが、対処法はあります。
これの対処、つまり「CellA1=CellA2」と判定させる方法の1つは

①データを一度、メモ帳にShift-JISで書き出し、
![ui13.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1401870/88780cfe-9adf-25fd-1c25-b755c88dc31e.jpeg)
②それをShift-JISとして改めて読み込み、
![ui14.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1401870/e3e79512-815e-d9cf-54b1-7aee2b82d621.jpeg)
③読み込んだデータからノーブレークスペース部分を削除し、これで上書きする。
これで完了です。
![ui15.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1401870/d96242f9-cfcc-38da-ba01-3bb80e479059.jpeg)

#3.余談
私がこのノーブレークスペースに遭遇したのは、過去3年間でこの「BBU」の1度だけでした。
それぐらいレアなケース(※個人的主観)ですが、この記事が他の人の助けになれれば幸いです。

ちなみに、私自身も、この資料を提供したお客さんも「ナニコレ…？」状態だったので、未だに発生原因は謎です。おしえてくわしいひと（他力本願）
起こらないはずの duplicate symbolが起こったときの対処法(備忘録)

# 問題
以下のようなコードがあり、コンパイルしてみる

```C++:Main.cpp
# include "Main.h"
...
```

```C++:Main.h
# pragma once
int f(int a){
    ...
}
```
```C++:hoge.cpp
#include "hoge.h"
...
```
```C++:hoge.h
#pragma once
#include "Main.h"
...
```

そうすると、あるエラーが。(多少パスは省略)

```
duplicate symbol 'f(int)' in:
    .../Main.o
    .../hoge.o
ld: 1 duplicate symbol for architecture x86_64
```

どうやら、`f(int a)`がMain.hとhoge.hで二重で定義されているようだ。

...ん？
確か、しっかりとMain.hに`#pragma once`はついてるが...

# 解決法
~~関数の定義に`static`を追加したら直った(こんな感じ)~~
追記:
`static`ではなく`inline`を使った方がいいらしい。
staticは定義の区別で、inlineは重複定義の許容なので、inlineを使った方が軽くなるとのこと
@makia さんthanks!

```C++:Main.h
# pragma once
inline int f(int a){
    ...
}
```

なんでかはわからないけど、なんでだろう

# 原因
@tenmyo さんthanks!
まず、エラーが出ているのはコンパイルではなくそのあとのリンクの時に出ていた。
確かに、`#pragma once`で重複は防いでいたが、それは「コンパイル時のソースコードの重複」を防いでいただけでその後のリンク時には関係していない。
つまり、コンパイル時に生成された`main.o`と`hoge.o`の両方に`f(int a)`が定義されて、そこまではよかったけど、いざリンクするとなった時に同じ定義が出てきてエラー。と言った流れ

そこで、`inline`で重複定義を許容することで解決する
WEBアプリケーションが表示される仕組みについて

インターネットを切断したら、Webアプリケーションは利用できない。つまり、Webアプリケーションnを表示するまでには、インターネットを介した情報やデータの送受信がある。情報やデータの送受信には、```HTTP通信```と呼ばれる通信方法がある。

```
HTTPとは
Webアプリケーションを表示する際の、情報やデータなどを送受信するための通信方法である。
この通信は情報を持っていて、HTMLなどが含まれる。
通信後に情報やデータを画面に表示することで、私達はWebアプリケーションを使うことができる。
HTTP通信でやり取りをする場所を、URLが示している。
```

```
URLとは？
インターネットのサービスの場所を表す住所🏠。
URLにアクセスすることで、そのURLにあてはまるWebアプリケーションと通信を行うことができる。
```
```
リクエストとレスポンスとは？
データのやり取りのこと。
リクエスト→データや情報を要求すること。
レスポンス→リクエストに対応するデータや情報を返却すること
モダンJavaScriptの使用にあたって覚えておきたいこと

#本記事
本記事は筆者がJavaScriptを学習している中で学んだことを記したものです。
備忘録的な位置付けですので、間違い等あるかもしれませんが、よろしくお願いします。

#モダンJavaScriptとは
仮想DOMを用いるライブラリ/フレームワークを使用している、npm/yarn等のパッケージマネージャーを使用している、ES2015(ES6)以降の記法を使用している。webpack等のモジュールパンドラーを使用していること。Babel等のトランスパイラを使用していること。

#JavaScriptとは
・Webブラウザ上(HTMLやCSSで構成される)で複雑な動きをするためのもの。



#仮想DOMとは
DOMとはdocument object modelの略。HTMLなどを解釈して木構造で表現したもの。JavaScript上でかそうDOMを使用して差分を抽出して変更分のみDOMで操作する。

#npm/yarn等のパッケージマネージャー
かつて、JavaScript開発では一つのJSファイルに全てを記述していた。
それを大きな処理ごとに分割して使う様になった。
しかし、読み込む順番等を意識しないとエラーが出てしまっていた。。。

現在では、npm/yarn等のパッケージマネージャーを使用して開発している。
Node.jsが裏で動いている際に、それぞれの依存関係を整理してくれる。

#ESとは
ECMAScriptの略。JavaScriptの標準規格のこと。毎年一回発表されている。ES5=2009、ES6＝2015 （機能追加が多くされた。）
ex)let,constアローファンクション、Class構文、分割代入...etc

#モジュールバンドラーとトランスパイラ
モジュールバンドラーとは、複数のファイルを一つにまとめるもの。上で述べた通り、JSは分けて開発した方が良いが、本番では分かれる必要がなく、最終的に一つに纏めていい感じにしてくれるの。

トランスパイラは,新しいJavaScriptの記法を古い記法に変換してくれるもの。
ブラウザによっては使用できない機能ががあることがあり、先程の様な処理をしてくれる。どのブラウザ上でも動く様にしてくれる。

#アロー関数の注意点
１.引数が一つの時、引数の()の省略ができる.
※prrettier等の自動整形ツールを使用していると保存する際に()がつく。
2.中が単一式の場合、以下の様な書き方ができる。
2021年 給料が一番高いプログラミング言語 5選

多くの人が高給のためにプログラミング業界を選びますが、世界で最も収益性の高いプログラミング言語は何か知っていますか？
##1）Java
「Javaは時代遅れですか？」と尋ねるかもしれません。もちろん、そうではありません。
なぜJavaはまだ人気があるのですか？Javaは最も古く、堅牢なプログラミング言語の1つです。また、主にAndroidアプリケーション開発に使用されるオブジェクト指向言語です。これが、今日でも使用されている主な理由の1つです。しかし、Kotlin（Android開発にも適しています）のようなプログラミング言語の出現により、Javaの人気は低下しています。
![Java.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/d279971b-2269-8c56-943d-a8e72896a1c6.jpeg)
ただし、Javaは依然として最も高額なプログラミング言語の1つであり、かなりの需要があります。Indeedによると、ソフトウェア開発会社はJava開発者に興味があり、毎年10万ドル以上の給料を支払う。

##2）Swift
Swift iOSアプリケーション開発は現在非常に人気があります。Swiftは非常に安定したプログラミング言語であり、勉強する価値があります。Javaに比べて、習得しやすいです。YouTubeには、学習に役立つリソースがたくさんあり、それを使ったプログラミングも楽しいものです。今Swiftの自由開発者であると、或いは関する仕事を従業すると、年給11.5万ドルに達する可能もあります。
![iphone-410324.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/972916a8-d883-70cd-0a43-2724592370f5.jpeg)
##3）SQL
SQLまたはSequelは構造的な検索言語です。実際にはプログラミング言語ではないと思う人がいます。SQLは主にデータの管理とインタラクティブに用いられる。ですから、SQLはプログラミングに欠かせないスキルであり、どのタイプのWeb開発（バックエンドまたはフルスタック）でも、データを管理するためにそれを学ぶ必要があります。統計によると、SQL開発者の平均年収は9万ドルを超えています。
![data-5933101_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/6c6c9315-9de6-15d1-8b95-c643bb86a2fb.jpeg)
##4）JavaScript
これは不思議なプログラミング言語で、一部の人はそれが一番いいと思っています。JavaScriptは非常に人気のある言語です。GitHubをチェックすると、JavaScriptをサポートする新しいフレームワークが常に表示されます。さらに、すべてのブラウザはJavaScriptをサポートします。したがって、JavaScriptを習得することは、ソフトウェア開発に把握しなければならないスキルの一つであると言えます。JavaScript開発者は、9万ドルから11.3万ドルの範囲の収入を得ることができます。
![code-5113374_1920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/bdb558e9-5133-3fa8-4576-02e5e08abe87.jpeg)
##5）Python
GoogleトレンドとPyPI人気指数によると、Pythonは世界で最も人気のあるプログラミング言語の1つであり、確かに最も高額なプログラミング言語の1つです。GoogleはPythonで構築され、YouTubeもPythonで開発されました。
![python２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/3cf4b9c3-b6e7-0ba4-bc00-096ca5d0e0e1.png)
Pythonの驚くべき点は、汎用プログラミング言語であり、幅広いアプリケーションを構築するために使われています。更に人工知能に活躍しています。自動運転車、ウォルマートの自動精算、多くの自動化とマシン学習（ML）アプリはPythonを通じて開発されました。これはこの言語をより重要にし、急速に普及させます。さらに、Pythonは他のすべての言語よりも習得が容易であり、初心者にも優しいです。 また、複雑なアプリケーションを比較的簡単かつ迅速に構築することもできます。米国では、Python開発者の平均給与は約7.8万ドルですが、経験豊富な開発者は12.2万ドルにもなります。
Template 内でkeyが空白となるdictのvalueを読む

##きっかけ
django-pandasでpivotTableを使用したところ、下記の様にindexが空白となる辞書を取得したがなかなか値を取り出すことができなかった。
　ほかにも良い方法があるのかもしれないがとりあえず目的は達成できたので、備忘録的に記載する。

##コード

```python:python
 dic = {'':100, 'a': 120, 'b': 130}
```


```html:html
{% for key, value in dic.items %}
    <!-- keyが空の時に、keyを「nothing」で埋める。そのうえでkeyの値を確認する。-->
    {% if key|default:"nothing" == "nothing" %}
        <td >{{value}}</td>
    {% endif %}
{% endfor %}

```

以上
単語をfor文を用いて接続

<h1>単語をfor文を用いて接続</h1>
言語: Javascript

```javascript
const mySports = ["野球" , "サッカー" ,"テニス"]
let text = "私の好きなスポーツは"
for (let i = 0; i < mySports.length ; i++){
  text += mySports[i]
  if (i !=mySports.length - 1){
    text +="と"
  }
}
text += "です。"
console.log(text)
```
<strong>上記のコードで重要な点</strong>
・リストの長さを取得するメソッドはリスト.length
・for 文のなかにif文を用いて場合わけする点
[Android] RxJava + RetrofitでAPIをポーリング（状態変化を検出）したい。




題目の通りです。
RxJava + RetrofitでAPIをポーリングしたい。

> Retrofitで書いたSingleを返すgetStatusAPIがあり、
> これを叩くと状態statusが取れます。
> 状態が変わるまで5秒間隔でポーリングしたいのですがどうすれば良い?

自己解決したので、メモのためここに書きます。
 Observable.interval() で指定した間隔で購読します。
 Observable.take() は一定時間経過後に購読を停止します。
 Observable.takeWhile() は条件が真のあいだ購読を継続します。

キモは Observable.takeWhile() の位置。
doOnNext() より前に書くと、状態が変わったとき、doOnNext()がよばれなくなります。


```java:hoge.java
    private void polling(String checkoutId, int interval, int timeout) {
        Disposable disposable = Observable.interval(interval, TimeUnit.SECONDS)
                .take(timeout, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .flatMap(repeat -> API.getStatus(checkoutId).toObservable())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(response -> {
                    Log.d("DBG", "repeat polling.");
                    if (response.status.equals("COMPLETED")) {
                        Toast.makeText(this, "Checkout COMPLETED!", Toast.LENGTH_SHORT).show();
                    }
                })
                .doOnError(throwable -> {
                    Log.d("DBG", "polling has received error.");
                    Toast.makeText(this, "Checkout failed.", Toast.LENGTH_SHORT).show();
                })
                .doOnComplete(() -> {
                    Log.d("DBG", "stopped polling.");
                })
                .takeWhile(response -> response.status.equals("PENDING")) // subscribeの直前で購読停止を判定する
                .subscribe(); // 
        compositeDisposable.add(disposable);
    }
```
ジョブ実行の長期化を避けるには？

Xplentyでは、APIのエンドポイントや接続先(ソース、送信先)での障害やレスポンス遅延などの理由により、ジョブが長時間実行中となることを避けるために、パッケージ（Dataflow/Workflow）実行時の最大実行時間を制限する変数を用意しています。

#ジョブの最大時間を設定しておくメリット
ジョブの最大実行時間を設定しておくことで、最大時間を超過したジョブはエラーとなり、通知機能を通して障害をいち早く把握し、対処することが可能です。

#設定方法
パッケージ・エディターの変数画面（User変数）にて「**_TIMEOUT_IN_SECONDS**」を設定する。
以下は、ジョブのタイムアウトとして3600秒（１時間）を設定する場合の例です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/130a3514-41ed-e005-1683-66378ea708d7.png)

#ジョブ時間を超過した場合
最大時間を超過した場合、ジョブは強制的にストップされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/84aa587a-7c11-8427-943d-47fad965e1b3.png)


また、エラーの詳細画面には以下のメッセージが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/fa6ef89f-6e99-33f8-dc82-f7aff7959960.png)


#通知設定
タイムアウトで自動的にストップされた場合も通知を受け取る場合、通知条件で「**Job Stopped**」についても設定ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65461/106683de-d248-0f62-0e4f-adcd70baa7e6.png)
Moonlander MKII Halmak レイアウト

Moonlander用のHalmakレイアウトを作った。とても快適なので、どうぞ自由に改良してお使いください。
[https://configure.zsa.io/embed/moonlander/layouts/mzLPV/latest/0](https://configure.zsa.io/embed/moonlander/layouts/mzLPV/latest/0)

https://configure.zsa.io/embed/moonlander/layouts/mzLPV/latest/0



### 特徴
1. Halmakを一部変更 → Gが使いづらいのでXとGの位置を入れ替え。
2. 下段寄せ → 手の小さい日本人でも親指ボタンに届くよう、全体を一段下に移動。
1. 最小限のキーのみ使用 → 将来的に、より小型のキーボードへ移行することを想定して、記号と数字はサブレイヤーに配置し、使用するキーを最小限に抑えた。
1. Dual-Function keys →　ホームポジションから指を離さずにレイヤー切り替えや⌘/CTRL/ALT/SHIFTにアクセスできる。

### BASE レイヤー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26419/c9074749-d214-abed-7f6c-f26ca68135e1.png)

### SUB レイヤー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26419/f1a5ef86-10bb-ca4d-d5e0-fe1cc8541da0.png)

### NUM レイヤー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26419/629b0810-7ad7-dc5d-1722-36a2e1ff694e.png)
[Outlook VBA]午後イチ会議のリマインダをお昼休み前に表示する

# やりたいこと
午後イチに会議の予定が入っているとき、お昼休み中に何の意味もないリマインダが表示されて会議に遅れることがないように、リマインダの表示時間をお昼休み前にずらします。

# 仕様
Outlook VBAのイベントには「予定の保存」をトリガーにするイベントがないため、起動時にその日の予定からお昼休みにリマインダ表示される予定を抽出して、リマインダの時間を変更します。
このため、お昼休み終了後に起動した時は何もしないこととします。
- ***昼休み時間***
    - 12:00-13:00
- ***変更後のリマインダ表示時間***
    - 11:50

## 動作環境
- Outlook2016
たぶんもっと前のバージョンでも動作します。

# 設定方法
1. [開発]タブから[Visual Basic]を選択し、Visual Basic for Applicationsを起動する。
2. 左側[プロジェクト]から[ThisOutlookSession]をダブルクリックし、VbaProject.OTM - ThisOutlookSession(コード)を開く。
3. 以下のソースをコピー&ペーストし、Visual Basic for Applicationを終了する。

※[開発]タブが表示されていない場合、以下の方法で表示する。
- [ファイル]-[オプション]でOutlookのオプションを開く。
- 左側から[リボンのユーザー設定]を選択し、右側[リボンのユーザー設定]でメインタブ[開発]にチェックを入れる。

# ソース

```vb
Private Sub Application_Startup()
    
    ' 13:00以降に起動した場合は処理を実行しない
    If Now > DateAdd("h", 13, Date) Then
        Exit Sub
    End If
    
    ' Name Space
    Dim myNamespace As NameSpace
    Set myNamespace = GetNamespace("MAPI")
    
    ' 自分のカレンダーアイテムフォルダ
    Dim myFolder As Outlook.Folder
    Set myFolder = myNamespace.GetDefaultFolder(olFolderCalendar)
    
    ' カレンダーアイテム
    Dim myItems As Outlook.Items
    Set myItems = myFolder.Items
    
    ' 定期的な予定を含める
    myItems.IncludeRecurrences = True
    
    ' 開始日でソート
    myItems.Sort "[start]"
        
    ' 開始日を戻り値の日付でフィルタ
    Dim strFilter As String
    strFilter = "[Start] >= '" & Format$(Date, "mm/dd/yyyy hh:mm AMPM") & "' AND " & _
                "[Start] <= '" & Format$(DateAdd("d", 1, Date), "mm/dd/yyyy hh:mm AMPM") & "'"
    
    ' フィルタの結果を取得
    Set myItems = myItems.Restrict(strFilter)
    
    Dim apptItem As Outlook.AppointmentItem
    For Each apptItem In myItems
        ' 抽出したアイテムを検索
        Dim reminderTime As Date
        reminderTime = DateAdd("n", -apptItem.ReminderMinutesBeforeStart, apptItem.Start)
        If reminderTime >= DateAdd("h", 12, Date) And reminderTime <= DateAdd("h", 13, Date) Then
            ' リマインダ表示時間が12:00-13:00の間だった場合、リマインダ時間を11:50に変更
            With apptItem
                .ReminderMinutesBeforeStart = DateDiff("n", DateAdd("h", 11, DateAdd("n", 50, Date)), .Start)
                .Save
            End With
        End If
    Next apptItem

End Sub
```
## 解説
### `Application_Startup()`

Outlookの起動時に呼び出されるイベントです。

# 参考にしたサイト
[ある期間内の予定のうちで件名に特定の語を含むものを予定表で検索する](https://docs.microsoft.com/ja-jp/office/vba/outlook/how-to/search-and-filter/search-the-calendar-for-appointments-within-a-date-range-that-contain-a-specific)
[【Outlook VBA】メールや予定をフィルターで検索する]
(https://qiita.com/vicugna-pacos/items/977fd4c32ebe0486869b)
VScodeで指定したパスにPython.exeが存在するのにインタプリタを選択できない

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412006/926c30c2-cec8-814d-6c34-0ca48c571aef.png)
ターミナルからも起動できるのでインタプリタには問題ない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412006/aa5ae761-3386-eb57-0a09-1d9e4eccb974.png)

解決法
同じ階層にある.vscode>setting.jsonの一部が壊れていた(波括弧が閉じていなかった)のでそこを修正したら選択できた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412006/9ebfb204-412d-f08c-6f35-45d5859d887a.png)
【WordPress】XサーバーからFTPを使ってソースコードをローカルに展開（ダウンロード）する方法

#はじめに
この記事では、XサーバーからFTPを使ってソースコードをローカルに展開（ダウンロード）する方法を紹介します。

#Xサーバー
まずXサーバーにログインして管理画面に移動します。

![スクリーンショット 2021-05-14 13.22.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769854/32db4d6a-8736-75c8-b867-c46eaca0681f.png)

次に、サブFTPアカウントを設定からサブアカウントを追加します。
この際に設定する`FTPユーザーID`と`パスワード`、FTPソフト設定から確認できる`FTPサーバー名`が必要になってきます。

![スクリーンショット 2021-05-14 14.09.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769854/1c37d3bd-52dd-bce4-abce-9f0319319a61.png)


#FileZillaのダウンロード
こちらがFTPソフトになります。
![スクリーンショット 2021-05-14 14.17.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769854/92601b5b-5fef-b132-d80f-122838e7647b.png)

https://filezilla-project.org/
こちらの公式ページからClientの方を無料ダウンロードしてください。
ダウンロードしたFileZillaを立ち上げてます。
![スクリーンショット 2021-05-14 14.26.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769854/ee25c496-25d1-ca00-26af-7156731ad963.png)

左側のウィンドウが自分のローカルで右側のウィンドウが接続したデータベース（サーバー）になります。
画面上部にある入力窓に先程設定した、`FTPユーザーID`、`パスワード`、`FTPサーバー名`を入力し、接続ボタンを押します。
するとデータベースの情報が右側に出てくるので、ローカルの移したいフォルダへドラック＆ドロップすることでデータをダウンロードすることができます。
※コピペだとできない時があるので、うまく接続できない時は手入力の試して下さい。

#おまけ
get_optionで引っ張ってきている値をデータベースから編集する方法。


![スクリーンショット 2021-05-14 13.27.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769854/ed2039b0-8247-ad97-e796-55a73340a21e.png)

サーバーの管理画面からphpmyadminに移動。
option_nameがカラム名で、option_valueが値です。
value列の値を編集すると、データベースの情報を書き換えたことになります。
WEBアプリ『ひとこと日記ver2』概要

この記事は、関口 厚がポートフォリオ用に開発したWEBアプリの紹介記事です。

#アプリの概要
アプリ名：**[ひとこと日記ver2](https://diary-app.sekiguchiportfolio.net/)**
日々の記録をテキスト形式で保存する、シンプルな**日記アプリ**です。
コードはGithubにてご覧いただけます。(**[フロントエンドのコード](https://github.com/Sekiguchi-Atsushi-WEB/vuecli-app)**・**[バックエンドのコード](https://github.com/Sekiguchi-Atsushi-WEB/express-app)**)

#作成環境
・インフラ：**AWS**
・バックエンド：**node.js** ＋ **Express**
・フロントエンド：**Vue.js**
・データベース：**MySQL**

**●各バージョン**
node.js v12.18.2, Express 4.17.1, Vue.js 2.6.12, Veu-CLI 4.4.6, MySQL 8.0

#アプリで行う主な処理
- ユーザー登録・認証処理
- 日記のCRUD処理

#アプリの構成
・**インフラ**は、**AWS**の**EC2**上に**Express**サーバーを立て、**RDS**上に**MySQL**データベースを立てています。
・**フロントエンド**は、**Veu-CLI**を使って構築し、**SPA**にしています。（Nuxt.jsは使っていません）
・**Expressサーバー**にて、**SPAのホスティング**と、データベース処理用の**エンドポイントの提供**を行っています。
・Vue.js-Express間の通信は、**axios**でデータをやり取りしています。

#サーバーとクライアントの構成図
![01_server-client.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284186/74731017-20aa-edc6-927b-e007e7607ba0.png)

#ユーザー登録・認証機能の動作
・UIから**ユーザー登録**、**ログイン**を行います。
・**Vue.js**から**axios**で通信し、**Expressサーバーのエンドポイント**へアクセスすることで、**ユーザー登録**、**ログインの処理**を実現します。
・ログインすると**トークンが発行**され、以降の処理はトークンによって**ユーザーを一意に特定**します。

#日記機能の動作
・UIから日記の**表示・作成・更新・削除**を行います。
・**Vue.js**から**axios**で通信し、Expressサーバーの**エンドポイントへアクセス**することで、日記の**CRUD処理**を実現します。
・axios通信時に**サーバーにトークンを送信**することで、**ユーザーを一意に特定**して、日記データを処理します。

#フォルダツリー

●vuecli-appのフォルダ構成（フロントエンド）

    [ルート]
     └ [public]フォルダ
         └ [images]フォルダ 
           　└ 各種imageは全てここに格納
         └ index.html
         └ favicon-diary.ico
     └ [src]フォルダ
         └ [asset]フォルダ
         └ [components]フォルダ
          　└ [diary]フォルダ　日記関係のVueコンポーネントを格納するフォルダ
                 └ Index.vue　トップページ（アプリの紹介ページ）
                 └ Mypage.vue　日記の一覧表示ページ
                 └ Edit_Create.vue　日記作成ページ
                 └ Edit_Update.vue　日記更新・削除ページ
                 └ Header.vue　ログイン時のヘッダーコンポーネント
                 └ Help.vue　機能紹介ページ
          　└ [login]フォルダ　ユーザー認証関係のVueコンポーネントを格納するフォルダ
                 └ Regist.vue　ユーザー登録ページ
                 └ Login.vue　ログインページ
                 └ Trial.vue　お試しユーザーログインページ
         └ App.vue
         └ main.js
         └ router.js　Vue.jsのルーティングを記述したJS
         └ store.js　Vuexの設定を記述したJS


●express-appのフォルダ構成（バックエンド）

    [ルート]
     └ [public]フォルダ　ビルドしたVue.jsのファイルをここに格納している。
         └ 各種ファイル。Vue-CLIでビルドしたdistフォルダ内のファイルをそのままコピーしたもの。
     └ [routes]フォルダ　axiosリクエストのエンドポイントを提供するためのルーターモジュールを格納したフォルダ
         └ get_diaries.js　一ヶ月分の日記を取得する処理のモジュール
         └ get_one_diary.js　一日分の日記を取得する処理のモジュール
         └ edit_create.js　日記を作成する処理のモジュール
         └ edit_update.js　日記を更新する処理のモジュール
         └ edit_delete.js　日記を削除する処理のモジュール
         └ user_regist.js　ユーザー登録する処理のモジュール
         └ user_login.js　ログインする処理のモジュール
         └ user_delete.js　ユーザーを削除する処理のモジュール
         └ user_auth.js　認証トークンを延長する処理のモジュール
     └ [function]フォルダ　サーバーに機能を与えるモジュールを格納したフォルダ
         └ db_connect.js　データベース接続設定モジュール
         └ token.js　認証トークン発行モジュール
         └ clear_auth.js　有効期限切れのトークン情報を削除するモジュール
     └ app.js
PointCloudの型変換

PointCloudT型をPointCloudXYZI型に変換するときは次のような関数として定義できる.

```c++:pcl_to_xyzi
void pcl_to_xyzi(pcl::PointCloud(pcl::PointCloudT>& input_cloud, pcl::PointCloudT>& output_cloud, double intencity)
{

   pcl::PointCloud<pcl::PointXYZI> output_cloud;
   pcl::PointXYZI p;

   for(int i=0;i<input_cloud.size();i++)
   {
      p.x = input_cloud[i].x;  
      p.y = input_cloud[i].y;  
      p.z = input_cloud[i].z;  
      p.intensity = intensity;  

      output_cloud.push_back(p);
   }
   return;
}

```
JAVA KeyStore 作成手順 (windows)

備忘録として記事にしました。

<h2>はじめに</h2>
Androidアプリをリリースする際、KeyStoreが必要になりました。
KeyStoreの作成手順を残しておきます。

<h2>JDKのインストール</h2>
・JDKのダウンロードをします
https://www.oracle.com/java/technologies/javase-downloads.html
![java001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223039/4e483ecf-cfca-a4d3-ca72-6b75cfc15142.png)

Windows x64 Installerをクリック
バージョン：jdk-16.0.1
![java002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223039/a047839d-6e13-e45c-1288-969e2ed88c68.png)

I reviewed and accept the Oracle Technology Network License Agreement for Oracle Java SE
(訳：Oracle JavaSEのOracleTechnologyNetworkライセンス契約を確認して同意します)
にチェックを入れてexeファイルをダウンロード
![java003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223039/5710a082-e69c-4881-33ad-788d2b3f2775.png)

exeファイルを起動させるとセットアップ画面が出てきます
次へをクリック
![java004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223039/90a06eb6-4e8c-b182-ef70-1cc830d18e76.png)

そのまま次へ
![java005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223039/0592304d-747d-bb36-1ef2-63bf87a323c8.png)

インストールが始まります
![java006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223039/f724bfd5-1738-c591-b57b-831d8de773d1.png)

完了したら閉じます
![java007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223039/f259da85-00d6-5f31-5e97-bf9f87d305e3.png)

<h2>KeyStoreの作成</h2>
先ほどインストールしたJDKを確認します。
僕の場合は前のバージョンのフォルダが残っています
jdk-16.0.1のフォルダができていますね
![java008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223039/b70bdf16-15f5-2244-0c72-12b9e8c12a73.png)

``keytool.exe``の場所を確認します
![java009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223039/e915d9e0-d461-6d23-63ef-786e04e3a5e0.png)

この場所をコピーします
![java010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223039/509e31d4-e189-a61f-315c-541213cd184d.png)

Windows →　Windowsシステムツール → ファイル名を指定して実行 を開き、[cmd]を記載したら　Ctrl + Shift + Enter　で開きます。
そうすることで管理者として実行することができます。
通常起動で作成しようとするとエラーになります。(僕はなりました)

![java011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223039/e7c46499-9c6d-1cbf-ab55-a1db3787445b.png)

コマンドプロンプトが開けたら、cdコマンドでKeyStoreのある場所へ移動します。

``cd C:\Program Files\Java\jdk-16.0.1\bin``

移動したら keytoolコマンドをします。

``keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key``

実行するとKeyStore生成の為の質問をされます。
下記はサンプル返答になります。

``キーストアのパスワード：password
姓名：name
組織単位名：personal
組織名：personal
都市名：Shinagawa
都道府県：Tokyo
2文字国コード：JP``

※キーストアのパスワードは忘れてしまうと大変困ることになります。
　絶対に忘れないようにしましょう。

すべて書き終わると``jksファイル``が
``C:\Program Files\Java\jdk-16.0.1\bin``
のフォルダ内に作成されます。

<h2>さいごに</h2>

間違いなどございましたらご教授ください。
dbdbを使って複数データベースサーバーとバージョンを管理する

# `dbdb`とは?
- https://github.com/yuki777/dbdb
- ローカル環境のDatabase Version Managerです

# こんなときに`dbdb`でDB管理が楽になります
- ローカルにデータベースが必要な場合
- 複数のデータベース(MySQL, PostgreSQL, MongoDB, Redis)が必要な場合
- また、複数のバージョン(MySQL 5.7, MySQL 8.0)がプロジェクト内で混在している場合
- 開発用データベースとテスト用データベースでポートを分けている場合

# Install
```bash
git clone https://github.com/yuki777/dbdb.git
cd dbdb
```

# MySQLサーバを作成して起動してみる
```bash

# ./mysql/create.sh {name} {mysqlVersion} {port}

# MySQLサーバを、バージョン5.7.31で、ポート3306で作ってみる
./mysql/create.sh mysql5-foo 5.7.31 3306
./mysql/start.sh  mysql5-foo 5.7.31 3306 # 起動

# MySQLサーバを、バージョン8.0.23で、ポート13306で作ってみる
./mysql/create.sh mysql8-bar 8.0.23 13306
./mysql/start.sh  mysql8-bar 8.0.23 13306 # 起動
```

# 接続してみる
```bash
./mysql/connect.sh mysql5-foo 5.7.31 3306
./mysql/connect.sh mysql8-bar 8.0.23 13306

# 普通にMySQLが起動しているだけなのでデフォルトのrootアカウントでログインもできます
mysql --user=root --port=3306 --host=127.0.0.1 
# host=localhostでもok
mysql --user=root --port=3306 --host=localhost --socket=/tmp/dbdb_mysql_3306.sock
# mysqlクライアントがなければdbdbがインストールしたクライアントを使うこともできます
./mysql/versions/5.7.31/basedir/bin/mysql --user=root --port=3306 --host=127.0.0.1
```

# 起動中のデータベース一覧を表示する
```bash
./dbdb.sh

mysql.5.7.31.mysql5-foo is running.
/Users/yuki/git/dbdb/mysql/start.sh   mysql5-foo 5.7.31 3306 # これを実行すると起動します
/Users/yuki/git/dbdb/mysql/stop.sh    mysql5-foo 5.7.31 3306 # これを実行すると終了します
/Users/yuki/git/dbdb/mysql/restart.sh mysql5-foo 5.7.31 3306 # これを実行すると再起動します
/Users/yuki/git/dbdb/mysql/status.sh  mysql5-foo 5.7.31 3306 # これを実行するとステータスを表示します
/Users/yuki/git/dbdb/mysql/connect.sh mysql5-foo 5.7.31 3306 # これを実行すると接続します
/Users/yuki/git/dbdb/mysql/delete.sh  mysql5-foo 5.7.31 3306 # これを実行すると削除します

mysql.8.0.23.mysql8-bar is running.
/Users/yuki/git/dbdb/mysql/start.sh   mysql8-bar 8.0.23 13306
/Users/yuki/git/dbdb/mysql/stop.sh    mysql8-bar 8.0.23 13306
/Users/yuki/git/dbdb/mysql/restart.sh mysql8-bar 8.0.23 13306
/Users/yuki/git/dbdb/mysql/status.sh  mysql8-bar 8.0.23 13306
/Users/yuki/git/dbdb/mysql/connect.sh mysql8-bar 8.0.23 13306
/Users/yuki/git/dbdb/mysql/delete.sh  mysql8-bar 8.0.23 13306
```

# ほか
- データベースサーバが存在しなければ作成して起動したい場合

```bash
./create-start.sh mysql5-hoge 5.7.31 23306
```

- 起動時にデータベースサーバも起動したい場合

```bash
# Start mysql5
@reboot /path/to/dbdb/mysql/start.sh mysql5-foo 5.7.31 3306

# Start mysql8 with port 13306
@reboot /path/to/dbdb/mysql/start.sh mysql8-bar 8.0.23 13306

# Try create, then start the server
@reboot /path/to/dbdb/redis/create-start.sh  redis6-hoge 6.0.10 6379
```

- 需要があればもう少し書きます
【GAS】終日＆不参加のイベントを除いて取得する方法

Google Apps Script(GAS)でGoogle Calenderの予定を取得するとき、
終日イベントや不参加予定のイベントは取得したくないなら、以下の2つの関数を使えば解決できる。

- `event.isAllDayEvent()`
    - 選択したeventが終日イベントかを確認する
    - `true` or `false`を返す

- `event.getMyStatus()`
    - 選択したeventでの自分の状態を確認できる
    - outputの種類
        - `INVITED`：予定には招待されたが、参加表示をしなかった場合
        - `YES`：参加しますか？に**「はい」**を押した場合
        - `NO`：参加しますか？に**「いいえ」**を押した場合
        - `MAYBE`：参加しますか？に**「未定」**を押した場合
        - `OWNER`：その予定の**主催者**である場合
            - （主催者は上記の`YES``NO``MAYBE`より優先される）

###例）Google calenderに登録された当日の予定の中、終日＆不参加予定以外を取得するscript

```javascript:getSchedulefromGcal.gs
  function getSchedulefromGcal() {
  
  //1　スプレッドシートを読み込む
    var sp =SpreadsheetApp.getActiveSheet(); 
  
  //スプレッドシートをクリア
    sp.clear();
  
  //2　カレンダーをIDで読み込む
    var cal=CalendarApp.getCalendarById('YourMailAddress@gmail.com');
    
  //3　カレンダーのイベントの期間を指定
    var date = new Date();
    var today = new Date(date.getFullYear(),date.getMonth(),date.getDate(),0,0);　　　
    var endday = new Date(date.getFullYear(),date.getMonth(),date.getDate()+0,23,59);　
    
    var event　=　cal.getEvents(today,endday); 
    var j=1;
	
  //4　イベントをスプレッドシートへ書き出す
    for(var i=1;i<event.length+1; i++){
      var status = event[i-1].getMyStatus();
      if(event[i-1].isAllDayEvent() == false　&& status != "NO"){  //終日＆不参加じゃない予定だけ
        sp.getRange('a'+j).setValue(event[i-1].getTitle()); 　//イベントタイトルを書き出し
        j=j+1;
      }
    }
  
  };
```
Djangoで無思考開発 〜環境構築編〜

環境構築って面倒臭い...そんな声が聞こえる。
僕もそう思う。環境構築なんかに思考を割きたくないよね。
だから簡単なマニュアルを作った。

# 前提
開発PC：Mac
（Windowsの人はごめんなさい...）

# 目次
* pyenvを使って指定のpythonバージョン実行環境を用意
* venvを使って仮想python実行環境を作成
* `setuptools`, `pip`をアップデート
* `django`をインストール
* 上記をまとめたコマンド手順
* 開発エディタはお好みで

# 本編
### pyenvを使って指定のpythonバージョン実行環境を用意
pyenvというpythonの実行環境を用意してくれる便利ツールがある
しかも、バージョン2, 3にかかわらず様々なバージョンの環境を用意してくれる凄いやつ
インストール方法と利用方法は以下のリンクを参考に。
[MacOSとHomebrewとpyenvで快適python環境を。 - Qiita](https://qiita.com/crankcube/items/15f06b32ec56736fc43a#%E6%86%A7%E3%82%8C%E3%81%AEpython%E3%81%A7%E3%82%82%E3%81%9D%E3%81%AE%E5%89%8D%E3%81%ABpyenv%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)
 最低限の流れ
 1. `brew install pyenv`で簡単インストール
 2. 補完機能が使えるように`.bashrc`or`.bashprofile`に設定
 3. 好きなバージョンのpython環境をpyenvでインストール
 4. 普段使うpythonバージョンをglobalに設定
  注意）指定のディレクトリでは、このバージョンを使いたい！みたいな場合は、`.python-version`を利用する

### venvを使って仮想python実行環境を作成
pyenvでpython実行環境を利用できるのはいいが、このまま進むとインストールするライブラリ一覧が汚れていく恐れがある。
例えば、pjtAとpjtBが同じpython実行環境を使う場合、それぞれの利用ライブラリが同じ場所で管理されてしまう。
この状況だと、pjtBの必要ライブラリの変更がpjtAに影響する恐れがある。他にも似たような問題が出てくる。
こういう問題を起こさないようにするためにも、それぞれのpjtには専用のpython環境を用意したい。
どうすればいいかというと、`venv`を利用する。
`venv`を利用すれば、そのpjt専用のpython仮想環境を作ることができる。
使い方は簡単
仮想環境を利用したいpjtディレクトリのルート直下で以下のコマンドを実行する

```:bash
$ pip -m venv venv
$ source venv/bin/activate
```
これでそのpjt専用のpython実行環境が使えるようになる。

### `setuptools`, `pip`をアップデート
`pip`を使ってると「アップデートしなよ」と推奨されるので、無思考でアップデート

```:bash
$ pip install -U setuptools pip
```


### `django`をインストール
最後にdjangoを利用するためにpipでライブラリをインストールすれば環境構築完成

```:bash
$ pip install django
```

### 上記をまとめたコマンド手順
```:bash
　 $ brew install pyenv
　 $ vim ~/.bashrc				# pyenvのコマンド補完内容を記載
　 $ pyenv -v					# pyenvが正常にインストールされてるか確認
　 $ pyenv install 3.8.0		# バージョン3.8.0のpython実行環境をインストール
 	$ pyenv global 3.8.0
 	$ cd ~
 	$ mkdir sample-pjt			# pjt用のディレクトリ作成
 	$ cd sample-pjt
 	$ python -m venv venv		# 仮想環境を作成
 	$ source venv/bin/activate	# 仮想環境を有効化
 	(venv)$ pip install -U setuptools pip
 	(venv)$ pip install djago
```


### 開発エディタはお好みで
初心者の方々なら`VSCode`か`Pycharm`がオススメですが、使いやすいものを選んでもらえば大丈夫です。
Turtle ファイルを Jena のコマンドラインツールで SPARQL する

# 背景

普段は Python の RDFLib を使っているのだけれど、SPARQL はそれぞれのエンジンで独自の関数や使用の違う実装があったりするので、Jena でも試してみたくなり Fuseki まではいらないんだよー、コマンドラインでサクッと試したいんだよー、ってことがあった。Docker 使えば一瞬だった。

## ローカルのファイルを使えるようにしつつ Docker を起動

```
docker run -v /home/kameda/temp:/rdf -it stain/jena bash
```

`/home/kameda/temp` の部分は自分の RDF ファイル や sparql クエリの書かれたファイルがあるローカルのディレクトリに書き換えてください。

## クエリを行う

```
sparql --data=datesample1.ttl --query=ttest1.sparql --results=tsv
```

対象のデータとクエリを指定して、実行。出力形式も `--results` フラグで指定できます。データとクエリは好きなエディタで編集しながら試行錯誤すればよいです。
【Rails】カラム型の種類

# カラム型の種類

|  データ型         |  種類                                     |
| --------------- | ---------------------------------------- |
|  string         |  文字列(1〜255文字)                        |
|  text           |  長い文字列(1〜4,294,967,296文字)           |
|  integer        |  整数(4バイト)                              |
|  bigint         |  整数(8バイト)                              |
|  float          |  浮動小数                                  |
|  decimal        |  精度の高い小数                             |
|  numeric        |  数値                                     |
|  datetime       |  日時                                     |
|  time           |  時刻                                     |
|  date           |  日付                                     |
|  binary         |  バイナリデータ                              |
|  timestamp      |  タイムスタンプ                              |
|  boolean        |  真偽値型                                  |
|  primary_key    |  プライマリーキー(主キー)                      |
|  references     |  他のテーブルへの外部キーの定義、_id が付いた整数  |
Github プルリク作成時のコミット解消の「Resolve Conflicts」がグレーアウトされて押下できない

# 目的

- Githubでのプルリク作成時にコンフリクトして`Resolve Conflicts`がグレーアウトされて押下できない問題の回避方法をまとめる

# 症状

- Githubでプルリクを作成したところコンフリクトが発生した。
- コンフリクトを解消しようとしたが下記画像の様に`Resolve Conflicts`のボタンがグレーアウトされて押下できない。

    ![Dev_by_miriwo0104_·_Pull_Request__53_·_miriwo0104_todos.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/177d0e00-0787-3b36-6277-0c7a2aec9901.png)

# 結論

- コンフリクト原因を一個一個解消していくしか無い。

# 情報

- プルリクにてマージ先のブランチを`ターゲットブランチ`と呼ぶことにする。
- プルリクにてマージ先にマージされるブランチを`ソースブランチ`と呼ぶことにする。

# 実例

1. 自分の場合、ターゲットブランチから作成したステージングブランチ、さらにステージングブランチから作成した作業ブランチA、更に作業ブランチAから作成した作業ブランチBからソースブランチを作成していた。
1. ターゲットブランチをステージングブランチに設定してプルリクを作成たところコンフリクトは発生しなかった。
各種アップデートコマンド一覧

普段いろいろな場面でパッケージ管理システムとかライブラリの管理システムとか使うのですが、それぞれのツールごとに最新版へのアップデート方法とかが微妙に違って毎回それを調べて確認するのがストレスなので記事にまとめておきます。自分用メモ。

# apt
```shell
apt update # パッケージ情報の更新
apt upgrade # パッケージのアップグレード
```

# Python pip
```shell
pip list -o # 更新が必要なパッケージを一覧表示
pip install -U 'パッケージ名' # パッケージごとに指定
pip install -U pip # pip 自身をアップデートするときの例

pip-review --auto # pip-review パッケージを利用することで更新が必要なパッケージを一括アップデート
```

# Anaconda

# Ruby gem
```shell
gem update --system # gem 自体のアップデート

gem update # gem で管理するパッケージの一括アップデート
gem update 'パッケージ名' # 個別のアップデート
```

# Rust cargo
```shell
rustup update # rust そのもののアップデート
cargo install cargo-update # cargo で使う更新自動化ツール
cargo install-update -a # 更新可能なパッケージを全てアップデート
```

# HomeBrew
```shell
brew update # 更新の確認
brew upgrade # パッケージの更新
```

# texlive
```shell
tlmgr update --list # アップデートが必要なパッケージの一覧表示
tlmgr update --self # tlgmr 自体のアップデート
tlmgr update --all # 全てのパッケージのアップデート
```

# R
R 起動後のプロンプトで作業する。
```R
update.packages(ask = FALSE) # ライブラリごとに更新の可否を聞かない
update.packages() # ライブラリごとに更新の可否を聞かれる
```
テレワークの導入にあたり、必要な知識

#【テレワークの導入にあたり、必要な知識】

基本情報技術者試験の過去問から抜粋しました。

##HTTP（Hypertext Transfer Protocol Secure）

WebサーバとWebブラウザ間の通信プロトコルのHTTPに暗号機能を追加したもの。
安全性が向上し、通信経路上での第三者によるなりすましや盗聴を防ぐ。
　→ 情報を暗号化して送受信するプロトコルSSLが使用されている。

WebブラウザのURLに鍵マークのようなものがあれば、HTTPS通信がされている。

##SSH（Secure Shell）

ネットワーク上のコンピュータに手元のPCから接続して、遠隔操作する通信プロトコル。
　→ 通信データの盗聴対策や通信相手のなりすましを防ぐ仕組みを持つ。

##VPN（Virtual Private Network）

暗号化技術などを用いて、通信事業者のネットワークやインターネット上で仮想的な専用線を実現する。
　→ コストパフォーマンスに優れている。
　→ ネットワーク拠点間の通信内容の漏洩や不正アクセスを防止する。

###VDI（:Virtual Desktop Infrastructure）：仮想デスクトップ

ユーザーが使用するアプリやデータをサーバ上に集約して、仮想化されたデスクトップ環境で稼働させる仕組み。
　→ ユーザーは使用するクライアント端末からネットワーク経由で仮想デスクトップ環境に接続する。
　→ サーバ上に集約させているので管理が容易で端末からの情報漏洩リスクを抑えられる。

###thin client（シンクライアント）

ユーザーが使用するクライアント端末に記憶装置を搭載せず、必要最低限の機能のみを持たせて、サーバ側で主に処理を行うようにするシステム構成。
  → VDIは、シンクライアントを実現する方法で主流。

※ 大学のパソコンルームもシンクライアントだったような。
gitでグローバルにignoreをする

以前書いた記事

https://qiita.com/padawan_e15/items/7ba90f09e3ecd559f95b


# 結論

`~/.config/git/ignore`に記述する。

# 例
```~/.config/git/ignore
.DS_Store
.vscode
.python-version
venv*
```

これで一括でステージングした際にaddされて余計なものがリポジトリに入る心配がない。。。はず。
ReduxとRedux ToolKitを比較

Reactでアプリを作成する際に皆さんは状態管理ライブラリーは何を使用されていますか？
私はほとんどの場合はRedux ToolKitを使用しています。

おそらく個人開発レベルでReduxを導入するのはどうなのかと疑問を持つ方が多いのかなと思います。
少し前は私も個人開発ではpropsのバケツリレーで良いのでは？Reduxもかなり複雑で扱いにくいしと思っていました。

しかしRedux ToolKitというライブラリーを知ってから便利さゆえにどんな小さいアプリにも導入してしまいます。
そこで生のReduxとRedux ToolKitを比較してRedux ToolKitの有り難さを改めて実感したいと思います！

# そもそもReduxとは？
Reduxは状態を管理するためのライブラリーです。
開発の規模が大きくなるほどに開発が容易になるので恩恵を受けることができる。

例えば素のReactでは親コンポーネントの情報を１０階層にある子コンポーネントに渡したい際には、その親コンポーネントと１０階層目の子コンポーネント内にある全てのコンポーネントでpropsのバケツリレーをする必要があります。また、新たな情報を渡したい際には全ての子コンポーネントを書き換える作業が発生します。このような作業はミスやエラーの温床になり兼ねない状態です。

ではReduxを導入するとどうなるのか。
開発者は状態管理とUIを分離して実装することができます。先程の例で言うと１０階層目のコンポーネントにReduxをコネクトするので、他のコンポーネントで状態のバケツリレーをする必要はなくなります。

上記のように便利に状態管理するためにReduxには大きく三つの機能があります。
一つずつ概要を説明していきたいと思います。

1.  **action creator（action）**
2.  **store**
3.  **reducer**

１.  **action creator（action）**<br>
ユーザーがインプット/アクションをした際にActionCreatorにAction制作の依頼が飛びActionが作成されます。
Actionを生成するだけではStore内のStateを更新することは出来ません。なので、ActionCreatorで生成されたActionをdispatchしてstoreに変更情報を送ります。

２. **store** <br>
Storeはアプリケーションの全ての状態が集まっている場所です。
Storeはアプリケーション内で一つ存在し、一つの状態を保持しています。
状態などの情報が欲しい際にはこのstoreが受け渡しを行っています。

３. **reducer** <br>
ReducerによってStore内のStateを更新する役割があります。引数のstateを更新するのではなく、新しいstateのオブジェクトを作成して返しています。

# ReduxToolKitとは？
Reduxを簡単に実装するためのライブラリーです。
またTypeScript製なのでTypeScriptとの相性がとても良い特徴があります。

# ReduxとRedux ToolKitを比較

生のReduxは必要最低限の機能しかないため、色々なモジュールを各自で揃える必要があります。それらを初学者が実装するにはかなりハードルが高いです。またReduxに慣れてきた人にとっては面倒に感じたりするのではないでしょうか。

Redux ToolKitではそのような煩雑な部分を解消してくれます。

**初期設定**

以下のmiddlewareが初期段階で組み込まれています。

* immutable-state-invariant
* serializable-state-invariant-middleware
* Redux Thunk

これらのmiddlewareが既に組み込まれているので初期設定が大分楽になり効率よくReduxの実装をすることでできます。

**createSlice関数でaction creator（action）のコードが不要**
createSlice()の中でreducerを実装する中で自動的にaction creator（action）が生成されます。

**テンプレートがある**
テンプレートがあるので、そのテンプレートを自分で色々と触って手軽に一連の動作を学ぶことができる。
以下がテンプレートのURLです。
https://github.com/reduxjs/cra-template-redux-typescript


#　最後に

私自身まだプログラミング初学者なのでReduxの恩恵をふんだんに味わえるような開発はできていないです。
しかし、個人開発の小さいアプリに導入するだけでかなり楽に状態管理をすることができています。

これからReduxに手を出す方に個人的にお勧めしたいのはRedux ToolKitのテンプレートを触ることです。
言葉では理解できないところが実際に触ることで理解できたりすると思います。


参考サイト

https://www.youtube.com/watch?v=yQz2gSQiOZA&t=521s

https://qiita.com/kitagawamac/items/49a1f03445b19cf407b7
Rails ユーザー登録機能を一瞬で作ろう

見てくださりありがとうございます。
自分は独学でrailsを勉強しているものです。
railsでWEBアプリケーションを作っているとユーザー登録の作成は必ず行いますよね！
なので今回はユーザー登録機能を実装するまでに必要なコードを淡々と書いて、コピペするだけでユーザー登録機能が作成できるようにします


###前提
アプリはすでに作成されている状態を想定しています(rails new アプリ名)
今回のユーザー登録機能とはユーザー登録画面でユーザーを新規登録するまでであり、登録内容の修正、ユーザー削除等の機能は作りません
あくまでもユーザー新規登録機能を作成し、成功すればユーザー詳細画面に飛ぶだけです
登録情報は名前とメールアドレスだけにしておきます

###ユーザーコントローラーの作成

```ruby:コマンド
rails generate controller Users  show new
```

###ユーザーモデルの作成

```ruby:コマンド
rails generate model User name:string email:string 
```


###ルートの作成

```ruby:config/routes.rb
Rails.application.routes.draw do
  resources :users
end
```

###ユーザーコントローラーのアクションの作成

```ruby:コマンド
class UsersController < ApplicationController

  def show
    @user = User.find_by(params[:id])
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to @user
    else
      render 'new'
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email)
  end
end

```
createアクションに@user = User.new(user_params)このような記述がありますが、
実は@user = User.new(params[:user])　このようにも記述できます。
しかし後者はセキュリティー上良くありません。理由は後者の記述だと悪意のあるユーザーにでアプリケーションのデータベースが書き換えらる可能性があるからです。
今回で言うとname,email以外の例えばadminという値をリクエストに紛れ込ませ、管理者権限を奪い取ることができてしまいます。
ですのでuser_paramsによってnameとemail以外はリクエストの対象にならないように制限をかけることが正しい記述方法になります

redirect_to @user　は　redirect_to user_url(@user)と等価になります
これはユーザー作成が成功し、データベースへの保存が完了したらユーザー詳細ページに飛ぶことを示しています


###ユーザー登録画面の作成

```ruby:app/views/users/new.html.erb
<h1>ユーザー登録</h1>
<%= form_with(model: @user, local: true) do |f| %>
    <%= f.label :name %>
    <%= f.text_field :name %>

    <%= f.label :email %>
    <%= f.email_field :email %>

    <%= f.submit "新規ユーザー登録", class: "btn btn-primary" %>
<% end %>
```


###ユーザー登録画面の作成（簡素ですが許して下さい）

```ruby:app/views/users/show.html.erb
<h1>ユーザー詳細ページ</h1>
<p><%= @user.name %>,<%= @user.email %></p>
```

以上これだけの記述でユーザー登録が完成します。
登録内容にパスワードが必要だったり、ユーザー情報の編集、ユーザーの削除機能が追加されても簡単に少ない記述で多くの機能が作成できるのがrailsのいいところですよね！
見てくださりありがとうございました。
PHPのdate関数、timestampを使って2021/01/01から12/31までのカレンダーを作ってみる。

#date関数
日付とか時刻を返してくれる関数です。試しに色々と書いてみます。

```
print(date('G時i分s秒')."\n");
->4時47分57秒

print(date('Y/n/j')."\n");
->2021/5/14

print(date('Y F,j')."\n");
->2021 May,14

print(date('n/j(D)')."\n");
->5/14(Fri)
```
こんな感じになります。
date関数のパラメータ（GとかY,n,jなどは下記のqiitaなどを参照してください。
https://qiita.com/shuntaro_tamura/items/b7908e6db527e1543837

##date関数の引数
date関数のリファレンスでdate関数の書式を確認してみます。
>
> date ( string $format , int|null $timestamp = null ) : string
>

これはdate関数が日時をどう表すのかのフォーマットです。
第二引数にタイムスタンプなるものが指定されています。
ではこのタイムスタンプとは何か。
#タイムスタンプ
タイムスタンプとは1970年01月01日から数えられている秒数を表しています。
今日現在のタイムスタンプは1620950400で1970年01月01日から1620950400経ったことを意味してます。
###strtotime関数

文字列をタイムスタンプに変換してくれる関数です。

(文字列) (を)　(タイムスタンプ)
string to timestamp = str to time = srttotime

```
//今日のタイムスタンプ
print(strtotime(today));
-> 1620950400

//2日後のタイムスタンプ
print(strtotime('+2day');

//信長が光秀に殺された日
print(strtotime('1582-6-21'));
-> -12229315200

```
こんな感じです。

###date関数の引数にタイムスタンプを渡してみる。
date関数の引数にタイムスタンプを渡してみるとどうなるか実際に確認してみます。

```
print(date('Y/n/j', 86400));
->1970/1/2

print(date('Y/n/j', 72800));
->1970/1/3
```

これはタイムスタンプに86400秒を指定しています。これはつまり24時間後なので、タイムスタンプを数え始めた1970年1月1日の24時間後の日付を出力しています。２番目のprintは72時間後の1月3日です。




ではこれを元に2021/01/01のタイムスタンプと12/31のタイムスタンプを取得して、後はループで86400秒、つまり1日置きにループしたいと思います。

```
//2021年1月1日のタイムスタンプを取得
$first_date = strtotime('2021-01-01');

//2021年12月31日のタイムスタンプを取得
$end_date = strtotime('2021-12-31');

//$first_dateが$end_dateより大きくなるまで86400秒を足して1日後を表示する
for($i=$first_date; $i<=$end_date;$i = $i + 86400){
    print(date('Y/n/d(D)'."\n", '+'.$i.'day'));
}
```

これで表示結果が
2021/1/01(Fri)
2021/1/02(Sat)
2021/1/03(Sun)
2021/1/04(Mon)
2021/1/05(Tue)
2021/1/06(Wed)
2021/1/07(Thu)
2021/1/08(Fri)
2021/1/09(Sat)
     .
     .
     .
2021/12/30(Thu)
2021/12/31(Fri)

と表示されるはずです。