OmniAICreator/Qiita-1.07M huggingface dataset:
PythonでYahoo Newsをスクレイピングしてみた

#はじめに
プログラミング初心者の私がPythonを使ってYahoo Newsをスクレイピングしてみたのでその手順を書き記したいと思います。(自分用のメモみたいなもの)
事前にBeautiful Soupとrequestsのインストールが必要です。

#やること
今回はYahoo Newsのアクセスランキングを取得してみます。画像の右下に「アクセスランキング」というものがありますね。これを1位から5位までスクレイピングで取得します。
![スクリーンショット 2021-01-02 12.19.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974569/b979585e-e98b-8a46-bdfc-01e2fa36e2e7.png)

#書いたコード
短いコードですがたったこれだけでスクレイピングができてしまいます。(BeautifulSoupしゅごい)

```py
import requests
from bs4 import BeautifulSoup

url = 'https://news.yahoo.co.jp/'
res = requests.get(url)

soup = BeautifulSoup(res.content, "html.parser")
ranking = soup.find(class_="yjnSub_section")
items = ranking.find_all("li",class_="yjnSub_list_item")
print("【アクセスランキング】")
for i,item in enumerate(items):
    text = item.find("p", class_="yjnSub_list_headline")
    news_url = item.find("a")
    print(str(i+1) + "位：" + text.getText())
    print(news_url.get('href'))
```

**いざ、ターミナルで実行**
![スクリーンショット 2021-01-02 12.34.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974569/2b0bbbf4-12a9-71eb-88d5-8d502ec3eb4a.png)
ちゃんと動いてくれました。
(なんか、若干ランキング変動してるけど大体合ってるからヨシ！)

#ざっと解説
Chrome上で右クリック→検証でHTMLが閲覧できるのでそれを活用します。

```py
ranking = soup.find(class_="yjnSub_section")
```
アクセスランキングはsectionタグのyjnSub_sectionというクラスに入っていたので、この部分を取得します。

```py
items = ranking.find_all("li",class_="yjnSub_list_item")
```

ranking変数には、まだ1位から5位のニュースの情報が丸々入っているので、リスト化してitems変数に入れます。それぞれのニュースはliタグのyjnSub_list_itemというクラスに入っていたので、この部分を取得します。

```py
text = item.find("p", class_="yjnSub_list_headline")
```
記事のタイトルを取得します。pタグのyjnSub_list_headlineというクラスに入っていたので、この部分を取得します。

```py
news_url = item.find("a")
```
記事のURLはaタグに入っていたので、この部分を取得します。

```py
print(str(i+1) + "位：" + text.getText())
print(news_url.get('href'))
```
textとnews_urlにはいらん部分まで入ってるのでtext.getText()とnews_url.get('href')で必要な部分だけを出力するようにします。
これで無事スクレイピングができるようになりました。
#最後に
Pythonを使えばこんな感じに簡単にスクレイピングができてしまいます。
是非興味があったらやってみてください。
ただし、サイトによってはスクレイピングを禁止しているところもあるのでそこは注意。
【SQL】SQL文の基本知識

##SQLとは

**クエリ(データベースに送る命令)を書くための言語**

`Ruby on Rails`でモデルを介してDBからデータを取得した際などに、SQL文がターミナル上に出力される
![スクリーンショット 2021-01-02 11.11.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/936377/7ed4ff2c-c5da-ed38-0aa3-618bf36c3d12.png)

## 基本形 
* (どのテーブルのどのカラムのデータを呼び出すかを指定）

```sql:sample.sql
SELECT "カラム名"
FROM "テーブル名"; 
/* 実際のカラム指定はクォーテーション無し */
```

* 具体例

``` sql:sample.sql
/* 基本形 */
SELECT name
FROM users;

/* 複数指定 */
SELECT name, email
FROM users;

/* 全てのカラムを指定 */
SELECT *
FROM users; 
```

##特定のデータの取得（ WHERE カラム名 = 値の指定 ）

性別やカテゴリーなどの一意でないカラムから特定のデータを抜き出す
例：男性のみを指定

| id |name|email|address|sex  |
|----|----|-----|-------|-----|
|  1 |... |...  |...    |男性　|
|  2 |... |...  |...    |女性　|
|  3 |... |...  |...    |男性　|
|  4 |... |...  |...    |男性　|
|  5 |... |...  |...    |女性　|

```sql
SELECT *
FROM users
WHERE sex = "男性";
/* 文字列型のデータは""で囲む */
```

##特定の範囲のデータ取得（ WHERE + 比較演算子)

```sql 
SELECT *
FROM products
WHERE price > 1000;
/* 値段が1000円より高いのデータを取得 */

SELECT *
FROM posts
WHERE created_at <= "2020-12-01";
/* 2020/12/01より前に投稿されたデータを取得 */
```

##特定の情報の含まれるデータの取得( WHERE + LIKE　)

| id |name             | price   |    
|----|-----------------|---------|
| 1  |ショートケーキ     | ...     |　　　    　 
| 2  |チョコレートケーキ　| ...     |
| 3  |チーズケーキ       |...      |
| 4  |チョコレートアイス　|...      |
| 5  |生チョコレート     |...      |

```sql
SELECT *
FROM products
WHERE name LIKE "%ケーキ%";
/* 文字列"ケーキ"が含まれる(id:1,2,3)データが取得 */

SELECT *
FROM products 
WHERE name LIKE "チョコレート%";
/* 文頭に文字列"チョコレート"が含まれる(id:2,4)データが取得 */

SELECT *
FROM products 
WHERE name LIKE "%チョコレート";
/* 文末に文字列"チョコレート"が含まれる(id:5)データが取得 */
```

##特定の条件に該当しないデータの取得( WHERE + NOT)

```sql
SELECT *
FROM products
WHERE NOT name LIKE "%ケーキ%";
/* （文字列"ケーキ"を含む）に該当しないデータの取得　*/

SELECT *
FROM products
WHERE NOT price >= 1000;
/* （値段が1000円以上）に該当しないデータの取得　*/

SELECT *
FROM users
WHERE NOT created_at <= "2020-12-1";
/* (登録日が2020/12/01より前）に該当しないデータの取得　*/
```

##カラム =（NULL or NOT NULL）のデータの取得

```sql
SELECT *
FROM users
WHERE introduction IS NULL;
/* introductionがnull（空）のデータを取得　*/

SELECT *
FROM users 
WHERE image_id IS NOT NULL;
/* image_idがnull（空）でないデータを取得 */
```

##複数条件の指定（WHERE + AND / OR )

```sql
SELECT *
FROM users
WHERE address LIKE "%東京都%"
AND age >= 20;
/* （addressカラムに文字列"東京都"を含む）かつ (ageカラムが20以上）のデータの取得 */
/* 東京都に住んでいる20歳以上の人のデータ　*/

SELECT *
FROM users
WHERE address LIKE "%千葉県%"
OR address LIKE "%茨城県%";
/* 住所が（千葉県 あるいは 茨城県）の人のデータの取得　*/
```

##取得したデータの並び替え（ORDER BY 昇順 or 降順）

```sql
SELECT *
FROM users 
ORDER BY age ASC;
/* 昇順：年齢が若い（ageの値が小さい）データから順に並べ替え　*/

SELECT *
FROM products
ORDER BY price DESC;
/* 降順：値段が高い（priceの値が大きい）データから順に並べ替え */

SELECT *
FORM products
WHERE price <= 1000
ORDER BY calorie ASC;
/* 複数指定 + 並べ替え：1000円以下でカロリーが低いものから順に並べ替え　*/
```

##取得するデータ個数の制限（LIMIT）

```sql
SELECT *
FROM posts
WHERE user_id = 1
LIMIT 5;
/* user_idが１のユーザーの投稿を5件のみ取得 */

SELECT *
FROM orders
WHERE user_id = 2
ORDER BY charge DESC
LIMIT 10;
/* (user_idが２のユーザー) ＆（注文金額が高いものから順に）10件のみ取得　*/
```

##補足

SQL文はRudy on Railsアプリケーションでのデータ取得の際、ターミナル上にて目にすることが多い為、基本文法を理解するだけでもターミナルの標準出力を理解し易くなるかと思います。

記載内容に間違い等ございましたらご連絡頂けると幸いです。
【 Ruby on Rails　】jQueryでプラグインを使わずにスライドを実装

# はじめに
jQueryには便利なプラグインがたくさん存在します。
しかし、今回はjQueryの練習という目的のためにあえて、プラグインは使用せずにコードを書いてみたいと思いました。

仕様としては、フェードイン・フェードアウトで次々に項目が入れ替わるカルーセルを実装したいと思います。
↓
[実装イメージ](https://gyazo.com/2b8a14af788cbca89986912eba92eaef)

# 目次
[1.jQueryの導入](#1-jQueryの導入)
[2.実装手順](#2-実装手順)

## 1. jQueryの導入
RailsにjQueryを導入する方法としては別途で記事を書いたのでご参照ください。
[jQueryを導入](https://qiita.com/anago1030/items/df3169906235680024e1)
[Turbolinksの無効化](https://qiita.com/anago1030/items/8ee2158fd0b498a31da8)

最新のRailsのバージョンだとデフォルトで`gem turbolinks`というジェムがインストールされています。
このturbolinksはページの読み込み速度を高速化してくれるものなのですが、ページ読み込み時にjavascriptを無効化にしてしまうので`jsファイル`に特別な記述をしなくてはいけません。
詳しくは記事を御覧ください。

## 2.実装手順

###hamlを記述します。

```php:index.html.haml
%div#slide（divタグにslideという名前のidを付与する）
  %ul
    - @events.each do |event|
      %li
        = link_to event_path(event.id), class: "event-link" do
          .event-image-area
            = image_tag event.image.url, class: "event-image"
```
今回はコントローラー側で`@events`を定義してeachメソッドの繰り返し処理でviewに表示させています。
`#slide ul`の下に繰り返し処理を記述して`#slide li`をeventの数だけ表示させます。

###次にscssです

```php:_index.scss
#slide {
  height: 300px;

  ul {
    position: relative;
    height: 300px;

    li {
      position: absolute;
      width: 100%;
      height: 300px;
    }
  }
}
```
ポイントは`#slide ul`に`#slide li`をピッタリ重ねることです。
なので親要素に**position:relative**、子要素に**position:absolute**を設定します。

イメージとしては１つ目のeventの下に2つ目、２つ目の下に3つ目...という構造になります。
１つ目のeventがフェードアウトしながら、次のeventがフェードインしていくという流れです。

###jQuery

```php:index.js
$(document).on('turbolinks:load', function() {
  // turbolinksを無効化したい処理
  $(function() {
    //イベントの件数
    let count = $("#slide li").length
  
    //現在表示されているイベント（最初は一番目のイベント）
    let current = 1;
  
    //次に表示するイベント
    let next = 2;
  
    //フェードイン・フェードアウトのインターバル
    let interval = 5000;
  
    //フェードイン・フェードアウトのスピード
    let duration = 600;
  
    //タイマー用の変数
    let timer;
  
    //一番目のイベント以外は非表示に
    $("#slide li:not(:first-child)").hide();
  
    //3000ミリ秒(変数intervalの値)ごとにsliderTimer()関数を実行
    timer = setInterval(slideTimer, interval);
    //sliderTimer()関数
    function slideTimer() {
      //現在のイベントをフェードアウト
      $("#slide li:nth-child(" + current + ")").fadeOut(duration);
      //次のイベントをフェードイン
      $("#slide li:nth-child(" + next + ")").fadeIn(duration);
      //変数currentの新しい値:変数nextのもとの値
      current = next;
      //変数nextの新しい値:変数currentの新しい値+1
      next = ++next;
      //変数nextの値がイベントの総数を超える場合は1に戻す
      if(next > count) {
        next = 1;
      }
    }
  });
});
```
ポイントとしては`current`と`next`の変数を定義してループさせる処理を記述します。
`#slide li`は繰り返し処理でviewに表示させているのでcreateアクションでeventが増えると自動的にこのjsファイルにも反映されます。

durationの値やintervalの値はお好みで調整可能です。

#おわりに
最後まで読んでいただきありがとうございました。
お疲れさまでした。。。
Pythonの競技プログラミングサイトまとめ

## AtCoder

国内最大級の競技プログラミングサイトです。
リアルタイムのオンラインコンテストへの出場や、3000以上の過去問にいつでもチャレンジすることができます。
まず過去問で操作や形式に慣れてから、オンラインコンテストに挑むと良いでしょう。

GoogleやDeNA、キーエンス等名だたる大手企業にも採用されており、AtCoderで優秀な成績を残すとそれらの企業からスカウトが届きます。

プログラミングスキルやアルゴリズムの知識だけでなく、ある程度数学のセンスが要求されます。

余談ですが、最近の東大生はAt Coderのランクでマウント取り合うとか・・・。青どころか赤もゴロゴロいるそうです。
日本で一番数学得意な人たちなので親和性は高いですね。

[AtCoder](https://past.atcoder.jp/)

## Kaggle

世界最大級の機械学習・データサイエンスコミュニティです。
膨大なデータセットも簡単に入手できます。

やはりKaggle最大の目玉はCompetetionです。
企業や政府が提示した課題に対して、競技形式で参加し、最も精度が高いモデルを買い取るという、プログラミングのバトルロイヤルとビジコンが一緒になったようなものです。

Competetionは世界でも最高峰にハイレベルな競技ですが、初心者向けにもKernelやDiscussionのような機能が提供されています。

[Kaggle](https://www.kaggle.com/)

## Codility

こちらは法人向けのコーディングテストのSaaSです。
世界で最も導入されているコーディングテストの一つで、国内でもGoogleやメルカリに採用されています。
エンジニアとして就職活動する際はほぼコーディングテストは必須になるので、Codilityのエンジニア向けの練習問題で対策しておくと良いでしょう。

[Codility for Programmers](https://app.codility.com/programmers/lessons/1-iterations/)

## 参考


[AtCoderで青色（8割以上のIT企業でアルゴリズム力はカンスト）になったので青になるまでに必要そうなことをまとめる](https://qiita.com/kami634/items/e452f804ba9d585a8b57)
[レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【初級編：競プロを始めよう】](https://qiita.com/e869120/items/f1c6f98364d1443148b3)
[Kaggleに登録したら次にやること ～ これだけやれば十分闘える！Titanicの先へ行く入門 10 Kernel ～](https://qiita.com/upura/items/3c10ff6fed4e7c3d70f0)
[Kaggleの練習問題（Regression）を解いてKagglerになる](https://qiita.com/katsu1110/items/a1c3185fec39e5629bcb)

[[第2版]Python 機械学習プログラミング 達人データサイエンティストによる理論と実践](https://amzn.to/3rX83Qc)

[Kaggleで勝つデータ分析の技術 ](https://amzn.to/3pPKvLr)

[【キカガク流】人工知能・機械学習 脱ブラックボックス講座 - 初級編 -](https://px.a8.net/svt/ejp?a8mat=3BK8OP+16V8C2+3L4M+BW8O2&a8ejpredirect=https%3A%2F%2Fwww.udemy.com%2Fcourse%2Fkikagaku_blackbox_1%2F)

Aidemyでも待望の[Kaggle対策コース(「実践データサイエンス講座 β版」)](//af.moshimo.com/af/c/click?a_id=2279296&p_id=1386&pc_id=2364&pl_id=20670&guid=ON)をリリースしたそうです。
class,idの時短記入方法について

htmlでclass,idを書く際の時短方法についてまとめていきたいと思います。
(例)　containerクラスのdivを記入 →　「div.container」と記入してエンターキー
(例)　btnクラスのbuttonを記入 →　「button#btn」と記入してエンターキー

このようにちょっとした時短テクニックですが、チリも積もれば山となり、非常に大幅な時短につながると思うので、知らなかった人は試していただけるとい幸いです。
rubyファイルで環境変数を読み込む【超初心者】

数年ぶりにrubyを触ろうと思い、GoogleのSpeechToTextというAPIを使ってみた。
その過程で.envファイルに記載した環境変数を.rbファイルで読み込むやり方を忘れてしまい苦労したので、まとめておく。

#まずは.envファイルを作成
.rbファイルと同じディレクトリ に.envファイルを設置する

#Dotenvインストール
dotenvというgemを使って環境変数を読み込む
どういうgemなのかは[dotenvって何？](https://qiita.com/4geru/items/33c123f853f72a758866)を参照してほしい。

コマンドラインで以下を実行

```
$ gem install dotenv
```
そして

```
bundle install
```
#.rbファイルに環境変数読み込みメソッドを書く

```sample.rb
require 'dotenv'
Dotenv.load
```
以上
ログイン機能をつける

gem 'devise'
を使用してログイン機能を付ける。


<% if user_signed_in? %>
    <%= link_to "編集",  edit_user_password_path%>
    <%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
<% else %>
    <%= link_to "ログイン", new_user_session_path %>
<% end %>
【Java】ラムダでforEachとsorted

Java8が出てから結構たつのに、ラムダの書き方を知らない方が結構多いみたいなので、
備忘録も兼ねてラムダを使って、アルファベットをSysoutするやつ
基本のForEachとsortedを使ってみた感じ

```java

	public static void main(String[] args) {
		// アルファベット
		List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
				"p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
				"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z");
		// とりあえ頭からSysout
		list.forEach(System.out::println);

		// マルチスレッドでSysout
		list.parallelStream().forEach(System.out::println);

		// ソート(文字コード順)してSysout
		list.stream().sorted().forEach(System.out::println);

		// ソート(アルファベット順で(同じアルファベットなら小文字→大文字の順))してSysout
		list.stream().sorted(String::compareToIgnoreCase).forEach(System.out::println);
	}
```
Raspberry Pi WiFi設定(WPA-PSKの暗号化方式でさらにステルス)

WiFIアクセスポイントをステルスAP設定している人向け。
MACアドレスフィルタリングしている人向け。

1.ルーターにMACアドレスを登録する。
2.ラズパイにステルスAPの設定をする。

以下のものが表示されるはず。
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=JP

これの下に打つのは

network={
	ssid="自分のWiFiのSSIDを入力"
	scan_ssid=1
	psk= 暗号化されたpassphraseを入力
	proto=RSN
	key_mgmt=WPA-PSK
	pairwise=CCMP
	group=CCMP
}

参照したもの
1. RaspberryPiでWPA-PSKのWiFiに接続する方法: https://qiita.com/teao26/items/970a721b5351e4c9918c
2. ラズパイをWPA2とAESに接続: http://lime-piko.blog.jp/archives/11502644.html
3. Setting up a wireless LAN via the command line: https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md
4. Raspberry Pi ステルスSSIDへの接続方法: https://qiita.com/minatomirai21/items/6397ba560626f09fe42b
5. WiFi data encryption AES and WAP2: https://www.raspberrypi.org/forums/viewtopic.php?t=50312
【PHP】【初心者】in_arrayを正しく使うために

##軽い気持ちで使うと怖いin_array
PHPのin_arrayという関数はご存知でしょうか。
値と配列を比較して、配列の中に値が入っていればtrue、入っていなければfalseを返す関数です。
軽い気持ちで使って渋い思いをしたので、自分への戒めも含めた投稿です。

##かんたんにまとめると
in_arrayの第３引数に

* true を入れると演算子===での比較
* false もしくは なにも入れないと演算子==での比較

##試してみると
それぞれの演算子の比較がどう違うのかは[ここ](https://www.php.net/manual/ja/types.comparisons.php)を確認しましょう。
そちらのページの「==による穏やかな比較」という項目にて

```php
"PHP" == 0
```
これがtrueとなることが確認できます。とっても穏やかな比較ですね。つまり、

```php
$array = ["PHP", "Hoge", "PHogeP"];
in_array(0, $array);
```
こうするとtrueになりました。
だから、

```php
$array = ["PHP", "Hoge", "PHogeP"];
in_array(0, $array, true);
```
こうすることによって、求めているであろうfalseが返ってきます。
悲しい事故を起こさないためにも、「第3引数にtrue」は絶対に入れましょう。

参考記事(むしろこれを読むべき)：
[PHPのin_arrayは罠が多いので注意喚起が必要](https://qiita.com/tadsan/items/2a4c3e6b0b74a408c038)
keccak256って何？

# まとめ

- `keccak256` = `sha3`
- `sha256` = `sha2`

※Solidity では `keccak256`、`sha256` を使う（= `sha3`、`sha2`は使わない）ようになっているので、それに従うのが良いようです。

# ツール毎の使い方

```
                        keccak256 (sha3)        sha256 (sha2)
                        ----------------        -------------
Solidity                keccak256               sha256

ethers.js               utils.keccak256         utils.sha256

web3.js                 utils.keccak256         NOT available
                        utils.sha3 (alias)

ethereumjs-util         keccak256               sha256
                        sha3 (alias)
```
古いWindowsノートPCをChromeOSのデュアルブートにする

# 概要
Chromebookで通常の作業はほぼ完結するのだが、稀にWindowsでやったほうが遥かに効率的にかんたんにできる作業があるので、中古のWindowsノートPCにWindowsを残しつつ、Chromebook化してみた。
ChromiumOSとしてはCloudReadyがインストールが簡単なのだが、残念ながら現時点でデュアルブートに対応していないようだ。少し手順は複雑になるが、androidアプリも使えるので、ChromeOSをインストールすることにした。

**試してみる方は自己責任で行ってください。何が起きても著者は責任は取れません。**

# 使用マシン & 導入OS
+ Let's Note CF-AX3(CF-AX3GFCCS)
 + 11.6 inch　タッチパネル
 + Intel Core-i5 4300U
 + メモリ4GB
 + SSD: 128GB
 + Xi LTE対応
 + 重量: 1.14kg
+ OS
 + Windows10 (もともとLets Noteにインストールされていたもの)
 + ChromeOS **(今回導入したもの)**

# 結果
YouTubeが我慢できれば実用に耐えるレベルだと思う

+ 正常と思われる点
 + Wifi、Bluetooth
 + 画面（タッチスクリーンもOK）、スピーカー
 + タッチパッド、外付けUSBマウス
 + Google Play、linux(Crostini)
+ 少しおかしい点
 + 再生自体はできるが、youtubeの動画上にマウスオーバするとメニュー表示とともに細い横線が何本か入る
 ※elementaryOSのChromeでも同様となるため、Chromeとこの機種の問題の可能性が高い
+ デメリット
 + ブートセレクトする分起動は遅くなる
+ 未確認
 + 上記以外（Xiは試す可能性あり）

# 導入方法
基本的なインストール方法は[こちら](https://beebom.com/dual-boot-chrome-os-windows-10/)の通りに進めれば以下の点を除いてほぼそのままインストールできる。

## 手順通りではない箇所のメモ
+ ChromeOS (rammus Recovery87) 2020/12/30時点最新
    + Core-iの４世代目以降はrammusをインストールする
+ SSD容量が128GBなので、ChromeOSを44GB、共用パーティション6GBとした
    + 共用パーティションはインストールイメージ＋少し余裕を持ったサイズとした
+ Linux MintはUSBにrufusで作成し、「Chrome OS」フォルダは共用パーティションに保存した。
+ 「sudo sh multi_install.sh」ではなくsudo sh **./**multi_install.shだと思う。
+ multi_install.shが異常終了する
 + grubのlist閲覧ができないというエラーになって正常に終了しなかった。
 + 小一時間悪戦苦闘したが、結論から言うと、インストーラーがgrub設定まで進んでいればエラーを無視して「Dual Boot Chrome OS and Windows 10」まで飛ばしてしまって良かった。
 + Grub2Winの「Edit Custom Code」に記述する内容は、ChromeOSをインストールしたパーティションのchromeos.grub.txtファイルに記載されている。（txtファイルを見るにはWindowsでアクセスすること）

# モバイルネットワーク
 + iijmioのSIMを利用
 + Windowsを先に設定→問題なく通信できる
 + ChromeOS側を立ち上げたところ、すでにiijmioのSIMであることが認識されていて、なんの設定もなく使えた。Wifiなどの他の通信が使えないときにモバイルネットワーク通信が使われるようだ。

# その後
 + 共通パーティションを14GBに拡張してelementary OSを更に入れて、トリプルブートにした。問題なく使えている。ChromeOSのクラウド印刷が2020/12/31で終了してしまったので、同じ用途なら、こちらのほうがいいかも。
【clusterワールド作成】掴まれている状態のアイテムの衝突（当たり）判定にハマった件

clusterのゲームワールドを作成中でハマった事例、解決方法を紹介します。

##環境
Windows10
Unity 2019.4.13f1
Cluster Creators Kit 1.11.0 

##ハマったこと
<B>AがBに衝突するとBが消える</B>
（例）剣がモンスターを刺したらモンスターが消える

というのを実装しようとして、公式ブログの「[的あてゲームの作り方](https://creator.cluster.mu/2020/06/11/howto_shootinggame/)」を見ながら、各Inspectorを以下のように実装。
なお、Aは剣のようなプレイヤーが掴めるアイテムです。（公式ブログの「[掴めるアイテムの作り方](https://creator.cluster.mu/2020/03/30/howto-item-create/)」を参考にしました。

###各Inspector
###A
１．掴めるアイテムにするため、Grabbable Item を追加
２．自動的に、Item、Rigidbody、Movable Item が追加される
３．衝突を検知するするため、On Collide Item を追加し、以下の画像のように設定
[![Image from Gyazo](https://i.gyazo.com/a7e907d824ffe9b0e5f51c784f7e9b46.png)](https://gyazo.com/a7e907d824ffe9b0e5f51c784f7e9b46)


###B
Destroy Item Gimmickを追加する。
Itemは自動についてくる。
[![Image from Gyazo](https://i.gyazo.com/9efe59d02ad60a210084c66311e32c98.png)](https://gyazo.com/9efe59d02ad60a210084c66311e32c98)

<BR>
### 結果
RUNすると、AがBに衝突してもBが消えない。

なぜだ？

<BR>

##解決方法

結構時間を溶かして諦めかけたとき、

公式の [Cluster Creator Kit ドキュメント](https://clustervr.gitbook.io/creatorkit/triggers/on-collide-item-trigger)に以下の記載あり

> <B>掴まれている状態のアイテムはそのRigidbodyがIsKinematicに変更されているため、上述のコライダーとのCollision判定が行われません</B>


私が作成してるオブジェクトAは、プレイヤーに掴んでもらうものでしたので、collisionでは判定されなかったということでした。

その対策方法を公式より引用
><B>それらのアイテムでの衝突判定が必要な場合は、どちらかにIsTriggerなコライダーを設定してTriggerイベントを検知するか、設置されているコライダーにIsKinematicがオフでConstraintを全てオンにしたRigidbodyを設定して下さい</B>

私は上記方法から、Istriggerなコライダーを設定しました。
公式には「どちらかに」と記載されてますが、私の場合どちらかだと反応せず、両方（AとB）に設定したらうまくいきました。（つまり、AがBに衝突するとBが消えました）

###各Inspector
###A
Colliderの IsTrigger をチェックし、
On Collide Item Trigger の Collision Type を Triggerにします。
[![Image from Gyazo](https://i.gyazo.com/eef75165e4f668215ed376f7e121ae41.png)](https://gyazo.com/eef75165e4f668215ed376f7e121ae41)


###B
Colliderの IsTrigger をチェック
[![Image from Gyazo](https://i.gyazo.com/df7922f467fbb3731c1f9d7dd6ef934c.png)](https://gyazo.com/df7922f467fbb3731c1f9d7dd6ef934c)


<br><br>
これで、AとBが衝突すると、Bが消えるようになりました。

<br><br>
AWS認定 ソリューションアーキテクト – アソシエイト(SAA-C02)でやっておいたほうがよいこと

今年中に合格する目標でしたが、仕事自体の忙しさや新型コロナによる影響で、試験を受けるのが2020年12月19日まで延びてしまいました。
（ただの言い訳です）

とはいえ年内に合格するという目標は達成できました。
今回試験を受けたのですが、こんなことをやっておけばよかったと思うことがたくさんありましたので、これから試験を受けられる方の参考になればと思い、書き残しておきます。


##AWSの実務経験
セミナーや勉強程度ではAWSを触ったことがあるものの、実務としてAWSを使用することになったのは、ほんの2ヶ月前くらいです。それまではVPC、EC2、S3、RDSの簡単なものを構築したことがあるレベルなので、とても実用的なレベルではなかったと思います。
2020年10月から仕事で実際にサーバ構築を開始しましたが、それでもEC2、ELB、Autoスケーリング、S3、RDS、Codeシリーズを触っていたレベルで難しい要件もほとんどない案件であったため、AWSの基本的なことしか知らないレベルでした。
##勉強期間
資格を取るぞと決めてから勉強を始めるまでに少し時間がかかったと思いますが、今年の3月くらいからだったと思います。
本格的に勉強を開始したのは2020年10月くらいからだと思います。実際は9か月かかった計算になりますが、実質的には2ヶ月かと思います。
##試験方法
私は今回自宅で試験を受けました。自宅での受験に関して、制限事項や注意事項があるので、それについても記載しておきます。
##勉強開始から試験前日までにやっておいたほうがよいと思ったこと
- **模擬試験をやっておく**<br>本番試験までに模擬試験を受けられている方はいると思いますが、私は試験当日も勉強時間に費やしており、模擬試験をやる時間を失ってしまいました。そのおかげで一発試験となってしまい緊張が全然解けず、試験時間はずっと手汗がひどく、手が冷たい状態で試験をしました。<br>
模擬試験をやっておけば、もっと緊張せずに試験を受けることができたと思います。
- **AWSを実際に触って覚える**<br>
この試験に関する書籍を2冊買いましたが、本を読むだけで覚えるのは、かなり難しいと思いました。<br>
しかしAWSを実際に触るといっても、どのように触ったらよいのかわからないと思います。そこで私はudemyというオンライン動画学習サイトの「**これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座**」で勉強することをお勧めします。<br>
この動画はサービスの概要や説明はもちろん、実際に触って覚えることができるように**ハンズオン**を実施してくれます。そのため実際に触って覚えることができます。このudemyは頻繁にセールをしているので、セール中に買うことをお勧めします。1000円台であれば買いだと思います。私は1300円のときに買うことができました。URLは以下の通りです。<br>
https://www.udemy.com/course/aws-associate/<br>

##試験開始前までにやっておいたほうがよいと思ったこと
- **試験開始30分前までには着席しておく**
- **試験前に必ずトイレに行く**
- **身分証明書を用意しておく**
- **部屋をキレイにしておく**
- **家族がいる場合、音を立てたり部屋に入ってこないように伝えておく**
- **部屋にテレビがある場合、画面を裏に向けるか布でカバーしておく**

##最後に
試験監督の確認が終わると試験開始となります。試験開始の準備に手間取ってしまうと、それだけで精神的にやられてしまう可能性もあるので、試験前の事前準備は必ずやっておいたほうがよいと思います。
これから試験を受けられる方の参考になればと思います。
gradleで実行可能Jarを作る

# 前提
Spring Bootはまた別の手順がある。

# もの
```gradle
compileJava.dependsOn('clean')

task fatJarDependCopy(type: Copy, dependsOn: compileJava){
    println "fatJarDependCopy called."
    from {
        configurations.runtimeClasspath
    }
    into "build/libs/lib"
}
task fatJar(type: Jar, dependsOn: "fatJarDependCopy") {
    from sourceSets.main.output
    def manifestClasspath = configurations.runtimeClasspath.collect { "lib/" + it.getName() }.join(' ')
    manifest {
        attributes 'Main-Class': "service.Test"
        attributes 'Class-Path': manifestClasspath
    }
}

archivesBaseName = "Test"
group = "sample"
version = '1.0.0'
```

### `compileJava.dependsOn('clean')`の働き
コンパイル前にクリーンを実行する。

### fatJarDependCopyの働き
ランタイムクラスパスから依存関係を`build/libs/lib`へコピー。
`dependsOn: compileJava`はJar作成の事前条件。`dependsOn`にタスクを指定することで自動実行する。
ここでは、事前にコンパイルをする。

### fatJarの働き
* ソース指定
* マニフェストファイル用の`Class-Path`用変数の定義、指定
* マニフェストファイル用の`Main-Class`の指定

### その他
| 変数 | 定義 |
|:-:|:-:|
| archiveBaseName | JarのBaseName  |
| group  | installタスクのgroup名  |
| version  | Jarのサフィックス |

#### Jarの名称
`[archiveBaseName]-[version].jar`
Linux MINT でLAMP構築中mysqlのrootパスワードでログインできない件

awsのCloud9でwordpressの開発環を作って作業していました。
でも、私が使っているモバイルのWi−Fiの回線速度の問題もあるようで、作業が止まってしまいどうにもならないので、古いノートパソコンに入れてあるLinux MINTの環境で、LAMPを久々に構築しようとしました。

こちらの記事を参考に、構築しました。

[【プログラミング】LinuxMintにPHP開発環境をインストールしてみた。](https://ko-log.net/tech-log/archives/php-dev.html)

[LinuxMintでのApache2のDocumentRoot変更](https://qiita.com/wakaba260/items/6005a7a3f0a7d0cca954)

[WordPressを公開用フォルダに格納して、公開する方法](https://ko-log.net/tech-log/archives/2548302.html)

[Linux MintにLAMP(Linux,Apache,MySQL,PHP)開発環境をインストール](https://omachizura.com/2016/09/linux-lamp.html)

##ROOTのパスワードが受け付けてくれない
```linux
ERROR 1698 (28000): Access denied for user 'root'@'localhost'
```
私は、パスワードが違うと思い込み、rootパスワードの再設定、リセットの方法ばかり探していました。

でも、色々検索している中で、パスワードの認証方法の問題と分かりました。

[mysql8 エラー「ERROR 1698 (28000): Access denied for user ‘root’@’localhost’」が発生した場合の対処法](https://mebee.info/2020/08/17/post-16820/)

上記のリンク先の記事から、引用転載します。
>rootユーザーの認証方式が「auth_socket」になっているため。
「auth_socket」になっていると、mysql -u 実行時に指定されているユーザ名が、Ubuntuにログイン中のユーザ名と同じでなければいけない。

そのため下記のコマンドを入力した後、rootのパスワードを入力できました。

```linux
sudo mysql -u root -pi
```

##MySQLは、バージョンの違いに注意
MySQLは、バージョンによってPassword関数が使えないことがあるので、rootのパスワードのリセット方法がことなります。
使っているMySQLのバージョンを確認して、さらにエラーメッセージをよく読み、分からなければエラーメッセージをネット検索して調べると早く解決できると思います。
ただ見つかる記事が古いので、気をつけないといけないです。
【Ruby on Rails】ActiveStorageで保存した画像のURLを取得したい

#課題
ActiveStorageで保存した画像のURLを簡単に取れると思ったら案外手古摺ったのでメモ。

```erb:image_tagを使ったerb
<%= image_tag recipe.image.variant(resize: '200x200').processed %>
```

```html:実際のHTML
<img src=\"http://localhost:3000/rails/active_storage/representations/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--d3fb1fe3b017a6060dd908f2463551e10cfbacb0/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCam9MY21WemFYcGxTU0lNTWpBd2VESXdNQVk2QmtWVSIsImV4cCI6bnVsbCwicHVyIjoidmFyaWF0aW9uIn19--306915654d885f72af9e428f63f831384a058376/01.png\" />
```

image_tag を使わずにURLだけ欲しい。

#結論
rails_representation_url を使うと取れた。

```ruby:コンソールで検証
irb(main):001:0> Rails.application.routes.url_helpers.rails_representation_url(recipe.image.variant(resize: "200x200").processed, only_path: true)
=> "/rails/active_storage/representations/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--d3fb1fe3b017a6060dd908f2463551e10cfbacb0/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCam9MY21WemFYcGxTU0lNTWpBd2VESXdNQVk2QmtWVSIsImV4cCI6bnVsbCwicHVyIjoidmFyaWF0aW9uIn19--306915654d885f72af9e428f63f831384a058376/01.png"
```

出涸らしになった情報かもしれませんが念の為。

#参考情報
How can I get url of image variant in model (outside of controller/view)? Active Storage
https://stackoverflow.com/questions/53542627/how-can-i-get-url-of-image-variant-in-model-outside-of-controller-view-active
【注意点まとめ】Ruby 時間(Time型/Date型/DateTime型)をカラムに設定する

# Time型・Date型・DateTime型
### Time型
- UNIXタイムで日時を扱うクラス

```
irb(main):001:0> Time.now
=> 2021-01-02 01:41:25.0792755 +0000
```

### Date型
- 日付を扱うクラス

```
irb(main):004:0> Date.today
=> Sat, 02 Jan 2021
```

### DateTime型
- 日付と時刻を扱うクラス
- Dateのサブクラスなので、Dateのメソッドが使える

```
irb(main):003:0> DateTime.now
=> Sat, 02 Jan 2021 01:41:40 +0000
```

# validation
- いつも通りのやり方(integer型やstring型と同じやり方)が通用しない。
- エラー文を追加するメソッドを独自に定義し、validationとする必要がある。


```ruby

validate :day_after_today

def day_after_today
    errors.add(:food_date, 'は、今日を含む過去の日付を入力して下さい') if !food_date.nil? && (food_date > Time.zone.today)
end
```

- 明日以降の日付を入力するとエラーとなるvalidationの例
- validateで、sは要らない

# 東京時間の設定
time_zoneの設定をしないと、デフォルトで協定世界時間(UTC)で記録されてしまいます。

```ruby
module App
  class Application < Rails::Application
    config.time_zone = 'Tokyo'
  end
end
```

# 比較
- Time型と、DateTime型の比較は、秒単位
- 以下は、DateTime型の変数の差が12時間以上となる様、validationをかけた時の例

```ruby
def time_before_give
  errors.add(:limit_time, 'は、お裾分け時間より12時間以上前の日時を入力して下さい') if !limit_time.nil? && give_time - limit_time < 12 * 60 * 60
end
```

# カラムの型変更
- Time型から、DateTime型に変更することはできないため、「カラムの削除⇨カラムの追加」の手順を踏む必要がある。
特定のFlutter SDK バージョンを使用する

特定のSDKバージョンを使用する方法のメモ。

背景：Flutter v1.18以上で Google Mapで不具合が発生したので、少し古いv1.17.5を使用する必要があった（v1.22.5で解消されているのを確認した）。

Codemagicではプロジェクトの設定画面で指定できる。

ローカルの場合は下記の通り

まず、最新版にアップデート。[参考](https://flutter.dev/docs/development/tools/sdk/upgrading#upgrading-the-flutter-sdk)

```shell
flutter upgrade
```

そして、バージョン指定して切り替える。[参考](https://flutter.dev/docs/development/tools/sdk/upgrading#selecting-a-specific-version)

```shell
flutter version v1.17.5
```

最新 (stableチャネル) に戻るには

```shell
flutter channel stable
```
「VCS入門」の勧めとメモ

## はじめに
Gitを理解するためには、その前提として「VCS」という思想を学ぶ必要があります。
[VCS入門](https://github.com/masaru-b-cl/introduction-to-vcs)で勉強した時のメモです。

## VCSの意義
VCSの能力は、主に次の2つです。

- 履歴を残す
- 作業の競合を防ぐ

### 履歴を残す
履歴が残ると何ができるのか。大まかには次の3つができるようになります。

- 履歴を残す
    - 参照
    - 再現
    - 分岐 
    
#### 参照
履歴をたどることで、誰がいつ何をやったかを確認することができます.
一般的なVCSでは履歴の検索機能もありますので、簡単に対象となる履歴を参照することができます。

#### 再現
VCSを使うと、履歴を参照するだけでなく、その時点の状態を再現することも可能です。つまり、動かなくなったとしても正常に動作していた状態に巻き戻せる、ということです。

#### 分岐
過去の状態を再現した上で、そこから別の変更を加えることで、履歴を分岐することもできます。つまり、複数のアプローチにより、作業を行うことができるということです。

### 作業の競合を防ぐ
VCSのもう一つの大きな機能が、「作業の競合を防ぐ」です。VCSを使うことで、誰かが先に変更していればそのことを検知し、VCSが競合箇所を知らせてくれます
また、使うVCSによっては、ファイル内の変更箇所を解析し、自動的に自分が行った変更内容と統合（マージ）する機能を持っています。この機能を活用することで、他のメンバーと効率よく並行して作業を進めることができるようになります。

## VCSの限界
1. 「とりあえず」反映している
2. 「どうやったのか」をメッセージに書いている
3. 動かないものも反映している
4. 複数の変更を盛り込んでいる

⇨VCSは便利ですが、あくまでツールです。ツールは人の作業を補助はしてくれますが、それだけではうまくいきません。ましてやシステム開発はチームで行うものです。2人以上がコミュニケーションを取るには、最低限のルールが必要です。

このことを言い換えると、VCSはルールと対になって初めてその真価を発揮する
守るべきルールが見えてきます。それが次のルールです。

- 「時間」ではなく「作業」の単位で行う
- 「どのように」ではなく、その作業を「何故」「何を」「何のために」行うかをメッセージに残す
- 動かない成果物はリポジトリに反映しない
- 一度に一つの変更だけ反映する

「一言で何をやるのか表せる単位で作業を区切って、リポジトリに反映する」ことが重要です。一言で表せないのならば、それは行おうとしている作業が大きすぎるのです。こんなときは、より小さな単位に分けて作業を行えないか考えてみましょう。

## SCMという智慧
VCSがない状態では、次の問題がありました。

- 作業履歴が残らない
- 他の人と作業がぶつかる

また、VCSを導入した後、ルールが無ければこんな問題がありました。

- 履歴から目的の変更を探せない
- 履歴の一つが、どういったきっかけで変更されたかわからない

以上の問題から、VCSを使って行いたかった事とは、

- 各バージョンを識別したい
- 特定のバージョンを再現したい
- 何故変更が行われたのか知りたい
- 他の人と連携して作業を行いたい

ともいえると思います。

これらを実現するための考え方が「SCM（Software Configuration Management、ソフトウェア構成管理）」です。
- Software : ソフトウェア
- Configuration : 構成
- Management : 管理
「ソフトウェア構成」とは「ソフトウェアというまとまりがどのような要素の組み合わせでできているか」

ある時点でのソフトウェアを構成する要素すべてを、識別、再現、追跡出来るようメンバー間で成果物を共有し、連携を促すための仕組み、ルール、プロセスを構築し、運用する
SCMでやりたいことを今一度まとめると、仕様変更、バグなどをトリガーとした「変更依頼」で発生した、ソフトウェア構成の変更履歴について、

- 識別
- 参照
- 再現
が出来なくてはなりません。

このことから、VCSを使う際には次のことを意識する必要があります。

- ソースコード以外も管理する
- 履歴を識別するメタデータを付加する
- 「タグ」を活用する

## SCMの次のステップ
SCMは「変更依頼」の管理も含めてSCMである、と説明してきました。主な変更依頼のトリガーとしては、「バグ」、「仕様変更」等があります。

そこで、変更依頼を管理するためのツールの出番です。こういったツールは一般的に「ITS（Issue Tracking System、課題管理システム）」と呼ばれます。

ITSでは、Issue（課題）を「Ticket（チケット）」という単位で登録します。このチケットには一意となる番号（チケット番号）が振られ、担当者を割り当てたり、関連する内容をコメントしたりする機能があり、課題を完了したらチケットを「閉じる（クローズする）」決まりになっています。

これにより、今残っている課題、終わった課題、誰が担当しているかなどが明確になり、管理が容易になります。

## 参考文献
[VCS入門](https://github.com/masaru-b-cl/introduction-to-vcs)
Github上で無償公開されています。本当に素晴らしい資料です。

[Gitをはじめからていねいに ](https://github.com/Shinpeim/introduction-to-git)
こちらもGithub上で無償公開されています。本当に素晴らしい資料です。
Meshlab server quadric edge collapse decimation error

下記投稿に従い、Meshlabserverでメッシュの削減をしていく際に、下記画像のようにエラーが発生する。
https://qiita.com/matterd/items/3a15bf30031707ab2cfd

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100466/092075c3-27e3-7980-eb83-8426f53283a6.png)


これは、Meshlabのバージョンにより、フィルタの名前が違う事が原因である。
例えば今回用いた”Quadric Edge Collapse Decimation”に関していえば、
古いバージョン：　Quadric Edge Collapse Decimation
新しいバージョン：　Simplification: Quadric Edge Collapse Decimation
となっている。

同様の報告は下記URLでも報告されている。
https://sourceforge.net/p/meshlab/discussion/499533/thread/1f5fb3df/

そのため、保存してあるフィルタースクリプト（xmlファイル）のfilter nameを変更する等を行うか、
また新たにMeshlab上でフィルタースクリプトを作成する。
Sassの色に関する組み込み関数について

## はじめに

タイトルについて記事にしました。
この記事で得る内容は以下の通りです。

・ Sassの組み込み関数（lighten,darken,transparentize,adjust-hue）について

数あるSassの組み込み関数の内、色に関するものを今回ご紹介します。

## 例

#### lighten

明るくする関数で、引数を2つつけることができます。
1つ目に色を指定し、2つ目にどれくらい明るくするのかを指定します。

下の例では、赤色を20%明るい色に変換します。

```scss
$sample: #f00;

background-color: lighten($sample, 20%);
```

#### darken

`lighten`とは対照的に、色を暗くする関数で`lighten`と使い方は同じです。
下の例では、赤色を40%暗い色に変換します。

```scss
$sample: #f00;

background-color: darken($sample, 40%);
```

#### transparentize

透明度を指定する時に使う関数です。CSSファイルでは`rgba`に変換されます。
`opacity`のように0〜1までの値で指定します。

下の例では、赤色を50%透過します。

```scss
$sample: #f00;

background-color: transparentize($sample, .5);
```

#### adjust-hue

色相を調整する関数です。

##### 色相
赤、青、緑の色味を360度で表すもので、どの角度がどの色に対応している色相環というものがあります。
下の例では、黄色になります。

```scss
$sample: #f00;

background-color: adjust-hue($sample, 45);
```

`adjust-hue`を使ってグラデーションを効率よく作る方法をご紹介します。
`linear-gradient`関数を使って次のように指定します。

```scss
$sample: #f00;

background-image: linear-gradient($sample, adjust-hue($sample, 50));
```

そうすると、CSSでは、下のようにコンパイルされます。
※ セレクタの指定がなくて文字が赤いですけど気にしないで下さい

```css
background-image: linear-gradient(#f00, #ffd500);
```

実際の画面はこちらです。

![スクリーンショット 2021-01-02 10.52.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/43188adc-0abe-4de2-4b04-121ff81cf8d8.png)

グラデーションを使って背景を指定したい時に使えそうです。
修正も変数か`adjust-hue`の値を変えるだけで管理できますので、とても楽ですね。
ログイン機能において、他者の投稿の編集や削除をできないようにする処理（Rails・初心者向け）

webアプリケーションで他人と投稿を編集したり消すことができたらまずいですよね。
そこで、ログイン機能において他者の投稿の編集や削除ができないようにするための処理を実装していきます。
この記事では簡単な掲示板サイトを想定して説明しております。
Messageモデルやmessagesコントローラーがあるとして、考えてみましょう。

`$ rails g helper sessions`でhelperを用意して、`current_user`と`logged_in?`を実装します。ここは、今回メインで解説する箇所ではないので、簡単な説明で留めておきます。

```Ruby:app/helpers/sessions_helper.rb
module SessionsHelper
  def current_user
    @current_user ||= User.find_by(id: session[:user_id])
  end

  def logged_in?
    !!current_user
  end
end
```
`def current_user`は、現在ログインしているユーザーを取得するメソッドです。

`@current_user ||= User.find_by(id: session[:user_id])`は
`@current_user`に現在のログインユーザーが代入されている場合　→　何もしません。
`@current_user`に現在のログインユーザーが代入されていない場合　→　`User.find_by(...) `からログインユーザーを取得し、`@current_user`に代入します。

`def logged_in?`はユーザーがログインしている時はtrueを、ログインしていなければfalseを返します。


コントローラーについて考えていきます。

```Ruby:app/contorollers/messages_controller.rb
class MessagesController < ApplicationController
  before_action :correct_user, only: [:edit, :destroy]

  #中略

  private

  def correct_user
    @message = current_user.messages.find_by(id: params[:id])
    unless @message
      redirect_back(fallback_location: root_path)
    end
  end
end
```
`before_action`によって、editアクションとdestroyアクションが実行される前に`correct_user`メソッドが実行されます。

`correct_user`メソッドでは、編集もしくは削除をしようとしている`Message`がログインユーザーが所有しているいるものかどうか、確認を行っています。

`@message = current_user.messages.find_by(id: params[:id])`は、ログインしているユーザーの`Messages`限定で検索をしています。

`@message`が見つかった場合は、ここでは何も実行されず、editアクションやdestroyアクションが実行されます。
見つからなかったときは、`unless @message`でnillを判定し、`redirect_back(fallback_location: root_path)`を実行します。

`redirect_back(fallback_location: root_path)`は、直前のページにリダイレクトしています。
例えば、message#indexで他者の`Message`の編集をしたらmessage#indexに戻し、message#showで他者の`Message`の削除をしたらmesssage#showに戻します。

`unless @message`が実行された（直前のページへ戻した）際には、editアクションやdestroyアクションは実行されません。
このようにして、他の人が投稿したものを編集したり削除できないようする処理ができました。
以上です。

######参照元
[直前のページにリダイレクト]
(https://railsdoc.com/page/redirect_back)
【Swift】スクリーンショットをシェアする処理

# これはなに

例えば『シェアボタン』を押したとき、その画面をスクリーンショットしてTwitterなどに投稿するモーダルが下から出てくるのを想定する。
たぶんコピペでいける。

## スクリーンショットを撮るメソッド

```swift
  func takeScreenShot() {
    
    let width = CGFloat(UIScreen.main.bounds.size.width)
    // ステータスバーなど、写したくない部分を考慮して高さを計算する
    let height = CGFloat(UIScreen.main.bounds.size.height/1.3)
    let size = CGSize(width: width, height: height)
    
    UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
    
    // viewに書き出す
    self.view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
    screenShotImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
  }
```

## シェアボタンの処理

```swift
  // シェアボタンを押したとき
  @IBAction func share(_ sender: Any) {
    
    // スクリーンショットを撮る
    takeScreenShot()
    
    let items = [screenShotImage] as [Any]
    
    // アクティビティビューに乗せてシェアする
    let activityVC = UIActivityViewController(activityItems: items, applicationActivities: nil)
    
    // モーダルが出現
    present(activityVC, animated: true, completion: nil)
  }
```
Dedicated Instance と Dedicated Hosts の違い

## 勉強前イメージ

AWS側のハードウェアが自分のアカウントだけなのかそうじゃないのか、のイメージ。
ただ、2つの違いはわからない

## 調査

### 共通すること

- AWSでアカウント専用の物理サーバにインスタンスを起動することができる
- コンプライアンスなどで物理サーバ専有が必要なアカウントに適している

### Dedicated Instance とは

EC2インスタンスはAWS側で任意の物理サーバの上で起動する、
その為、物理サーバ上のインスタンスには別アカウントのインスタンスも存在する。
しかし、ソフトウェアのライセンス等で物理サーバを専有したい場合があり、その際に使用する。
`別アカウントのEC2インスタンスが同じサーバ上で起動しないことを保証する` のが Dedicated Instance です。

### Dedicated Hosts とは

Dedicated Hosts は Dedicated Instance の上位版なやつです。
Dedicated Instance では、`別アカウントのEC2インスタンスが同じサーバ上で起動しないことを保証する` が、同じアカウントのインスタンスを同じ物理サーバ上で起動させることができなかったが、
Dedicated Hosts は `物理サーバでのインスタンスの配置を制御する` ことができます。


### Dedicated Instance と Dedicated Hosts の違い

`Dedicated Instance` では、`別アカウントのインスタンスが同じ物理サーバ上で起動しないこと` だけを保証しますが、
`Dedicated Hosts` では、`別アカウントのインスタンスが同じ物理サーバ上で起動しないこと` だけでなく、 `同じアカウントのインスタンスを配置させることが可能` になります。 (アカウントはIAM別ではなく、Rootアカウントが違えば違うアカウントとなる)


![Untitled Diagram.drawio - diagrams.net 2020-12-29 15-47-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/a2902f41-a45f-ac66-edab-550b21bb22f1.png)


## 勉強後イメージ

似たような名前だからわかりづらいけど、
物理サーバに他のアカウントが入ってこないことは一緒だけど、
他のインスタンスを入れたりすることができるのはライセンス的なアレで必須な場合があるのか・・
今勉強したけど、またどっちやったっけ？ってなりそうｗ

## 参考

- [DedicatedインスタンスとDedicated ホスト](https://www.guri2o1667.work/entry/2019/12/03/Dedicated%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%A8Dedicated_%E3%83%9B%E3%82%B9%E3%83%88)
- [ハードウェア専有インスタンス (Dedicated Instance) とAmazon EC2 Dedicated Hostの違い](https://zatoima.github.io/aws-ec2-dedicated-instance-host.html)
- [Amazon EC2 Dedicated Hosts を使ってみた](https://dev.classmethod.jp/articles/using-ec2-dedicated-hosts/)
【初心者】【PHP】strlenとmb_strlenを勘違いした話

##結論
初心者が調子づいてきた頃にやりがちだけど、
具体的な言葉で検索しようね、そして説明はよく読もうね！　と言う話。

##詰まりの始まり
私がPHP開発をしていたある日、処理の中で文字列の文字数カウントが必要になりました。
##「PHP 文字列 長さ」で検索する
すると出てきたのは

* 文字列の長さを取得(strlen, mb_strlen) →というまとめ記事
* strlen - Manual - PHP →というPHP公式ページ
* mb_strlen - PHP →PHP公式ページ

それを見た素人はこう思いました。
###「ははーん、strlenを使えばいいんだな？」
殴りたくなる思考回路ですが、こんなクソとぼけたゴミがいるのも事実です。

**そんな複雑ではない関数だろう**と思い込み、
公式の説明など読まないままstrlenを自分が作成していた処理に当て込みました。

##一向に想定とは違う動きをするstrlen
```php5
strlen('あいうえお');
```
5を返すはずのこの関数、

```php5
int(15)
```
一向に3倍の文字数を返すのをやめてくれません。
慌ててPHP公式のstrlenを読みます。

>strlen — 文字列の長さを得る
>
>説明 ¶
>strlen ( string $string ) : int
>与えられた string の長さを返します。

why!? PHPeople!?
合ってるじゃんと公式に文句を吐きながら、まとめ記事を読み漁った結果、
無事に「文字列の長さ**（バイト数）**」を返す関数だと理解してここに至ります。

書くまでも無いでしょうが、全角や半角を含む文字数をカウントしたい場合は
mb_strlenを使いましょう。

##なぜ素人がそういう失敗に陥ったのか
* 文字数をカウントしてくれる関数に種類なんてないという思い込み
* そこからくる説明を読まないという怠惰

そして

* 文字列の長さという曖昧な表現での検索

これが理由だと思っています。
上記2つは言うまでもない、私自身のゴミ精神が招いたことです。

話したいのは3つ目です。
「文字列の長さ」はバイト数、文字数、両方に捉えられる言葉です。

たとえば「画像のサイズ」と聞いた時、

* 「画像の横幅と縦幅」
* 「画像ファイルのバイト数」

この2つが想定されるように、「長さ」や「大きさ」といった言葉は
意味を広く取れてしまう、という意味で自分が想定しない結果を
連れてくることがあるのではないでしょうか。

今回も、**「PHP 文字列 文字数」で検索をしていれば**、
strlenよりもmb_strlenが検索結果の上位にきていました。

具体的な検索をすること、そしてよく読み、理解すること。
初心者が調子に乗り出してきた頃にはよくある話だと思うので気をつけましょう。
Ｐｙｔｈｏｎのサンプルソースを少し変えてみただけです。

![00000.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591320/7a2670a6-45e0-80e6-23dd-ece488194142.jpeg)
今日この頃、タゴメです。

Ａｎａｃｏｎｄａベースの参考書通りに中々自己解決が無理なので、
Ｐｙｔｈｏｎ関連の多くの参考書の中で理解できた奴のサンプルソースを少し変えてやってみました。

これが正直、初めての成功であり、コードを描くための参考書やマイクロソフトの有名プログラマーの著書を読破して知ったオリジナルのコードなんてまだまだです。

ここからもう少し、マシで自分自身のオリジナルソフトウェアデザインエンジニア的に近づけば良いと思います。

本のようにうまく行きませんが、カトラーのようにうまく行きたいです。
SnapKitを使った時に出たエラー

## 出現したエラー
Fatal error: Expected superview but found nil when attempting make constraint `equalToSuperview`.

## 原因と解決方法
`equalToSuperView`の後に`addSubview(recordingButton)`としていたことが原因でした。親ビューを先に確定させないと、親から相対的に決めることはできないので、当たり前といえば当たり前なのですが。

```swift
private func setupRecordingButton() {
        recordingButton.setTitle("録音する", for: .normal)
        recordingButton.backgroundColor = .yellow
        
        recordingButton.snp.makeConstraints {
            $0.center.equalToSuperview()
            $0.width.equalTo(100)
            $0.height.equalTo(100)
        }
        addSubview(recordingButton)
}
```

解決方法は`addSubview`の場所を変更することです。

```swift
private func setupRecordingButton() {
        recordingButton.setTitle("録音する", for: .normal)
        recordingButton.backgroundColor = .yellow
        
        addSubview(recordingButton)
        recordingButton.snp.makeConstraints {
            $0.center.equalToSuperview()
            $0.width.equalTo(100)
            $0.height.equalTo(100)
        }
}
```
Linux Mint Mate 20でCUDAをインストールする

#はじめに
最近、linux Mintを最新版のMINT20に入れ替えました。それまで動かしていたCUDAを再インストールしました。この間、わかったことなどを後日のために記録します。


#Linux　Mint
Linux Mint 20 MATE　
ハード　GALLERIA　DT（ドスパラ）


#インストール手順
Nvidia社の下記のページよりインストール
https://developer.nvidia.com/cuda-downloads

Linux -> x86_64 -> Ubunut -> 20.04 -> dev[network]

この後に表示されたインストールの指示にしたがい端末にコピーペーストして作業しました。所要時間はおよそ40分

```
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub
sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /"
sudo apt-get update
sudo apt-get -y install cuda

```

インストールは順調に進んでいたのですが、最後になって次のメッセージがでてストップしました。

```

Your system has UEFI Secure Boot enabled.

UEFI Secure Boot requires additional configuration to work with third-party drivers.

```
スクロールして読んでいきますと最後にパスワードの入力を求められました。2度、linuxに設定したのと同じパスワードを入力すると先に進むことができました。その後、すぐにインストールは終了しました。

その後、再起動しました。すると画面の表示が妙です。画像が大きく表示されています。画面設定が変更になったようでした。端末からnvccを起動しようと試みるもの認識されていません。そこで、さらに、再度、再起動しました。すると画面サイズは正常に戻っていました。でも、まだnvccは起動しません。再度、sudo apt-get -y install cuda　を実行すると、すでにCUDAはインストールされているというメッセージがでてきました。ドライバもちゃんとnvidia社のものが設定されていました。


#後処理
最後にもうひとつやらなければならないことがありました。パスの設定です。
https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#post-installation-actions

```
$ export PATH=/usr/local/cuda-11.2/bin${PATH:+:${PATH}}
```
このように端末から入力することによりnvccが起動するようになりました。

#パスの設定
パスの設定をhomeディレクトリにあるprofileというファイルの最後に追加しておきます。これでいつでも端末からnvccを呼び出せるようになりました。

```
nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2020 NVIDIA Corporation
Built on Mon_Nov_30_19:08:53_PST_2020
Cuda compilation tools, release 11.2, V11.2.67
Build cuda_11.2.r11.2/compiler.29373293_0


```
「Flutter 完全に理解した」状態を抜けた時に書いた記事たち

Flutter の公式ドキュメントの 1 ページである、 "Inside Flutter" を頑張って読んでみました。

https://flutter.dev/docs/resources/inside-flutter

元々はアドベントカレンダーのネタ探しのために読んでみたのですが、読んでいるうちに Widget が画面に描画される過程で何が起きているかが分かってきたり、 `Text` や `setState()` といった普段何気なく使っているクラスやメソッドの実装を読んで何が起きているのかが理解できるようになったりといろいろな発見がありました。

さらに、Flutter の仕組みを知れば知るほど、そこから派生する新しい発見や疑問が次々と湧いてきて、これは「Flutter 完全に理解した」状態を抜けて「Flutter 全然わからん」の状態に入ったと言えるのではないかと思い、その時に得た知見をいくつか [Zenn](https://zenn.dev/chooyan) に書いています。

この記事では、同じように 「Flutter 完全に理解した」 状態から一歩踏み出したい方の手がかりのひとつとして、それらの記事を一覧で紹介してみたいと思います。

## 【Flutter】Navigator.of(context) から理解する 3つのツリー

https://zenn.dev/chooyan/articles/77a2ba6b02dd4f

Inside Flutter の内容を、「なんとなく Flutter でのアプリ開発に慣れてきた人」向けの説明、という切り口で説明した記事です。

Widget ツリーや Element ツリー、 RenderObject、 BuildContext といった Flutter でたびたび目にするけれどもあまり意識されない要素について、 Inside Flutter の文章と Flutter のソースコードを読みながら説明した記事です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134943/2d777098-3c34-f820-75e9-cce6be3bb4ef.png)

こんな感じの図に興味がある方向けの記事です。

## 【Flutter】最小限のコードで理解する「宣言的な画面遷移」と Navigator 2.0

https://zenn.dev/chooyan/articles/cb09f63a57f0fb

[Navigator 2.0 and Router](https://docs.google.com/document/d/1Q0jx0l4-xymph9O6zLaOY4d_f7YFpNWX_eGbzYxr9wY/edit#) で説明されている Router API や Page API を使った「宣言的な画面遷移」について、モバイルアプリ開発の視点から説明してみたものです。

Navigator 2.0 は Web アプリにおける URL 直接入力や戻る / 進むボタンに対応できるようになることが目的の 1 つであるため、そのための記述が多くサンプルコードを読んでもなかなか理解が難しいのですが、モバイルアプリ開発だけであればだいぶすっきりしたコードで実現が可能であることや、「宣言的」な画面遷移は `Navigator.push` などの「命令的」な画面遷移から大きく設計や発想を変える必要があることを説明しています。

Navigator 2.0 の導入は学習コストが高いものではありますが、UI 構築と同じように画面遷移も宣言的に記述することによってさまざまなメリットも得られるため、まずは考え方だけでも頭に入れておいて損はないと思います。

## 【Flutter】 StatelessWidget が静的であるという誤解

https://zenn.dev/chooyan/articles/cea8f55d9bbeec

Flutter 初学者向けの説明として、動的な UI は StatefulWidget で、静的な UI は StatelessWidget で、というものを良くみますが、ドキュメントやソースコードを読むとその説明があまり実際的ではなく、「自分専用の `State` を必要とするかどうか」の違いで使い分けるのが良いことが読み取れます。

それを踏まえた上で、それぞれの Widget の効果的な使い分け方や、 State を使わずに動的な UI を作る Flutter の仕組みについても説明しています。

## その他

その他、普段何気なく利用するいくつかの Widget のドキュメントやソースコードから読み取れる内容をまとめた記事をいくつか書いています。

[【Flutter】 InheritedWidget とは何か](https://zenn.dev/chooyan/articles/bd8b5990eb210f)
[【Flutter】 MediaQuery とは何か](https://zenn.dev/articles/3c2691e93f4038/edit)
[【Flutter】 setState() とは何か](https://zenn.dev/chooyan/articles/7c2bf39f81cbed)
[【Flutter】 Text とは何か](https://zenn.dev/chooyan/articles/d48faae7352e32)

ただ「使い方」を覚えるのではなく、どのような仕組みでそれができているのか、どのように使うことを想定・推奨されているのかを理解することで、その考え方を自作の Widget のコーディングに活かせるのではないかと思います。

特に InheritedWidget は Provider パッケージの陰に隠れて直接使われることはありませんが、 MediaQuery や DefaultTextStyle, Navigator など、 Flutter の各種 Widget を実現する上で欠かせない存在となっていますので、これを知っているとだいぶ Flutter の Widget の使い方の理解が進むと思います。


---

ここで紹介している他にも、最近は [Zenn](https://zenn.dev) の方に Flutter 関連の記事を書いていますので、よければ読んでみてください。
デフォルトゲートウェイに送るとはいかに？

# デフォルトゲートウェイに送るとは？
ネットワークのテキストなどに、同じネットワーク（サブネット）内ではない宛先に通信を行うときには、デフォルトゲートウェイに送るなどの説明がある。ネットマスクと宛先IPアドレスとから判断するものであるが、実際のデータ列に説明しているものをあまり見かけない。基本的なことではあるが、これについて私なりの説明をしてみたい。

## ネットワーク例
ルータを介して２つのネットワーク（「Network 1”:192.168.1.x/24」および「Network 2”:192.168.2.x/24」）が存在する。デフォルトゲートウェイは、それぞれ「192.168.1.254」および「192.168.2.254」、ネットマスクはいずれも「255.255.255.0」である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/88ce5988-205c-6140-69c1-67ae849f5252.png)
PC1とPC2とが「Network 1」に、PC3が「Network 2」に存在している。IPアドレスやMACアドレスは図を参照。

## PC1から、PC2およびPC3への通信
PC1の設定は下記のとおり。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/f40db984-7189-d85e-f1ef-a6d774c6f935.png)

PC1から、PC2およびPC3へ通信するときに、ネットマスクと宛先IPアドレスから同じサブネット内にあるかどうかの計算をする（IPアドレスとネットマスクとのANDをとる）。その結果として、最初の通信先（宛先）が決まる。下記表参照。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/7255a7aa-cf4d-e030-edb4-025492d1e5d2.png", width=120%>

### PC2への通信
ARP Broadcastにより、IPアドレス192.168.1.2を持つMACアドレスを取得する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/59a47dce-2b71-1cb4-5adb-cc8f2e727604.png)

この結果として、PC1からPC2へのEthernetヘッダ+IPヘッダは下記のようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/3df5afa5-2625-2f05-1263-f7c6964f27bb.png)

### PC3への通信
同一サブネット内にPC3は存在しないので、デフォルトゲートウェイ192.168.1.254を持つMACアドレスをARP Broadcastにより取得する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/994de3c2-ec6c-bb12-c3e9-691f08e71eee.png)

この結果として、PC1からデフォルトゲートウェイ（Router）へのEthernetヘッダ+IPヘッダは下記のようになる。宛先MACアドレスはデフォルトゲートウェイ、宛先IPアドレスはPC3である。（送信元はいずれもPC1。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/4897cffd-2e5f-824b-0f48-78492ef067c8.png)

上記データ列を受けたRouterは、PC3のMACアドレスを同じくARP Broadcastによる取得する。この結果として、RouterからPC3へのEthernetヘッダ+IPヘッダは下記のようになる。送信元MACアドレスはRouter（デフォルトゲートウェイ）、送信元IPアドレスはPC1である。（宛先はいずれもPC3。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/bf8bfe6c-c97f-bb4f-025d-63f3bb9a5b4d.png)

## つまり
IPパケットは基本的に同じ（NATが関わる場合を除く）、Ethernetヘッダはサブネットを越えるたびに変わるのである。
Docker基本コマンド

Pythonでデータ分析したり、Webアプリ開発するのに、Python仮想環境ではなく、Dockerを使おう。
Docker基本コマンドについて、まとめました。

# DockerHubからPullしてPushする
Docker Hubからimageをpullして、コンテナをrunし、コンテナからimageを作成し、Docker Hubにpushする。

|コマンド |説明 |
|:--|:--|
|docker login   |dockerにログイン   |
|docker pull \<image>   |docker hubからimageをとってくる   |
|docker run -it \<image> bash   |imageからコンテナをbashプログラムでrunする。runはcreate + start。bashは\<command>が入り、デフォルトコマンドを上書きしている。   |
|exit   |コンテナから出る   |
|docker ps -a   |コンテナの一覧を表示process status。-aで止まっているコンテナも表示   |
|docker images   |image一覧を表示   |
|docker restart \<container>   |コンテナを再起動 statusをexitからupに   |
|docker exec -it \<container> bash   |コンテナをbashプログラムで実行する   |
|docker commit \<container> \<image>   |コンテナからimageをつくる   |
|docker tag \<source> \<target>   |imageにタグ名をつける（docker hubにアップするためdocker hubのリポジトリと同じ名前にする）   |
|docker push \<image>   |Docker Hubにpushする   |
|docker rmi \<image>   |imageを削除する   |

# 削除コマンド

|コマンド |説明 |
|:--|:--|
|docker rm \<container>   |コンテナを削除   |
|docker system prune   |コンテナを一括削除   |
|docker rmi \<image>   |イメージを削除   |
|docker image prune   |イメージを一括削除   |

# runオプション
コンテナを起動する際のオプション。

|オプション |説明 |
|:--|:--|
|-it   |基本的に使う。-iはインプット可能。-tは表示が綺麗になる   |
|--name \<container_name> \<image>   |コンテナ名を指定   |
|--d \<image>   |コンテナを起動後にdetachする（バックグラウンドで動かす）   |
|--rm \<image>   |コンテナをExit後に削除する（一回きりのコンテナ）   |
|-v \<host/path>:\<container/path>   |ファイルシステムの共有   |
|-u \$(id -u):$(id -g)   |ファイルへのアクセス権限   |
|-p \<host_port>:\<container/port>   |ポートをつなげる   |
|--cpus \<#ofCPUs> --memory \<byte>   |コンピュータリソースの上限。下記コマンドの\<something>にcpuなど入れて現状を確認   |

`docker inspect <container> | grep -i <something>`でコンテナを詳細を調べられる。

# DockerfileからImageをつくる

|コマンド |説明 |
|:--|:--|
|docker build \<directory>   |\<directory>には「.」を指定することが多い。Dockerfileが保存されているフォルダに移動し、カレントディレクトリでbuild   |
|docker build -t \<name> \<directory>   |イメージ名を指定   |
|docker build -f \<docker file> \<build context>   |Dockerfileがbuil context（カレントディレクトリなど）にない場合に使う。Dockerfileを開発用、test用に複数作っている場合   |

docker buildに関するキーワード：Docker daemon、build context
2021年どうせなら英語でもTechblog書きますまいか (dev.to紹介) 

昨日 [QiitaとZennに書くぞ](https://qiita.com/e99h2121/items/153fa1e96662358e7a82) なんて書いておいて何だがもう1つチャレンジを始めたのでお勧めのため書きます。

## dev.to

- 海外の投稿サイト (内容は大体QiitaかZennか辺り)
- 2016年オープン
- [阿部寛のホームページ](https://qiita.com/naru0504/items/7d652681d698f6d88c4f) とのスピード対決で有名
- [記事](https://www.itmedia.co.jp/news/articles/1711/15/news133.html#:~:text=2016%E5%B9%B4%E3%81%AB%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3%E3%81%97%E3%81%9F,%E3%81%8C%E2%80%9C%E4%B8%80%E7%9E%AC%E2%80%9D%E3%81%AA%E3%81%AE%E3%81%A0%E3%80%82)
- [insanely fast](https://qiita.com/saboyutaka/items/1f528ec3ce85476d7561)



## ポイント
1. リアクションが多くて楽しい。[dev.toにpostした感想を1行で](https://qiita.com/taroyanaka/items/c8627e77973bae8a7091)は割と本当。[自己紹介スレ](https://dev.to/welcome) に至っては投稿即いいね 
（そういう仕様）

2. お作法緩め（[2～3行の挨拶でも割と許される](https://dev.to/whitneym5/wow-2021-1nlp)）
2. 海外のトレンドを追える
3. 英語の勉強になる（本題ではないが）


## 2021年版記事
ひとまず、今年ならではの記事で高評価のものを読んでみる。

- [50+ Free Awesome Certificates to Earn in 2021 (2021年版、無料で獲れる資格50+)](https://dev.to/panx/50-free-awesome-certificates-to-earn-in-2021-2l7g)
- [{FREE} Ultimate Resources for Front-End Development in 2021 + Giveaway(無料。2021年フロントエンド開発のための究極のリソース+オマケ付)](https://dev.to/rahxuls/free-ultimate-resources-for-front-end-development-in-2021-giveaway-3838)
- [5 Must-Have Skills For Developers 2021 (2021年開発者が備えておくべき5つのスキル)](https://dev.to/kaperskyguru/5-must-have-skills-for-developers-2021-5d9n)
- [My journey into software engineering role at Microsoft (Microsoftエンジニアへの旅)](https://dev.to/elamoscicka/my-journey-into-software-engineering-role-at-microsoft-35o3) 

## 登録は簡単
Twitter or Github アカウントがあればすぐ。好みのジャンルを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/16c2f01c-c159-00ad-43a6-09f571bbbde6.png)

### 投稿5分でリアクション貰った

で、お試し投稿です。[昨日の記事を簡単翻訳した版](https://qiita.com/e99h2121/items/153fa1e96662358e7a82)。

https://dev.to/e99h2121/thing-i-try-my-resolution-for-2021-2l72

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/e33d5fbf-ce8a-3d0c-1057-46987e45a2f9.png)

その後特に努力無しに勝手に良いね貰える。嬉しい。

この緩いノリは海外旅行や海外滞在で味わうそれに近いですね。
海外旅行が身近でなくなってしまった2021年年明けの今、こんなところで気軽に、広い海外と触れ合ってみるのもいかがでしょうかというお話。今年こそ良い年になると良いね。

（日本語勢も居るみたいだけど。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/f9865fd7-2eac-ea8f-b472-7e1c0c4ec82c.png)