OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonのリストのコピーを行う際に注意すること

#はじめに
Pythonでリストのコピーを行う際に注意することをメモします。詳しい内容は「値渡し・参照渡し」などで検索してみてください。　
#注意すること
言葉で説明するよりも先に、以下のコードをご覧ください。

```
X = 2
Y = X
Y = 5
print('Y = ', Y)
print('X = ', X)
```

これを実行すると、もちろん

```
Y =  5
X =  2
```
という結果が得られます。
次に、以下のコードを実行してみてくだいさい。

```
i = [1, 2, 3, 4, 5]
j = i
j[0] = 100
print('j = ', j)
print('i = ', i)
```
ここでは、iというリストを決め、jにiを代入し、jのインデックス番号0の値を100にし、iとjをそれぞれ出力するものです。その結果は、

```
j =  [100, 2, 3, 4, 5]
i =  [100, 2, 3, 4, 5]
```
となり、 iの方も変更がされてしまいました。
この原因は、次のコードで確かめることができます。

```
print(id(X))
print(id(Y))
print(id(i))
print(id(j))
```

```
4436251808
4436251904
4304286176
4304286176
```

となり、値を代入したXとYはそれぞれ違うidを持つのに対し、リストを代入したiとjは同じidを持つことがわかりました。そのため、リストではjで行った変更はiにも反映されることになります。
そのため、リストのコピーを行う際は、

```
j = i.copy()
```

#最後に
リストをコピーすることは少ないと聞いたので、あまり使用頻度は高くないと思いますが、バグに繋がらないよう、注意してください。
P5.js 日本語リファレンス(getItem)

このページでは[「P5.js 日本語リファレンス」] (https://qiita.com/bit0101/items/91818244dc26c767a0fe) の getItem 関数を説明します。

## getItem() 

### 説明文

storeItem() を使用してローカルストレージに保存したアイテムの値を取得します。

ローカルストレージとは、ブラウザに保存され、ブラウジングセッションとページの再読み込みの間も保持されているものです。

### 構文

getItem(key)

### パラメタ

- key  
String：ローカルストレージに保存するために使用した名前

### 戻り値

Number  |  Object  |  String  |  Boolean  |  p5.Color  |  p5.Vector：保存されたアイテムの値

### 例1

```javascript
// マウスをクリックすると背景色が変わります
// 色を変更した後、ページをリロードしても色は変わりません
// (変更した背景色はローカルストレージに保存してあるため)
let myColor;

function setup()  {
   createCanvas(100, 100);

   // key "myColor" にはまだ一度も保存していないので NULL を取得
   myColor = getItem('myColor'); 
 }

function draw()  {
   if (myColor !== null) {
     background(myColor);
   }
 }

// マウスをクリックすると呼ばれる
function mousePressed()  {
   myColor = color(random(255), random(255), random(255));

  //  random() で求めた color を key "myColor" に保存
   storeItem('myColor', myColor);
 }
```

### 実行結果
https://editor.p5js.org/bit0101/sketches/ksjXkEkkn


### 著作権

p5.js was created by Lauren McCarthy and is developed by a community of collaborators, with support from the Processing Foundation and NYU ITP. Identity and graphic design by Jerel Johnson.

### ライセンス

Creative Commons(CC BY-NC-SA 4.0) に従います。
P5.js 日本語リファレンス(clearStorage)

このページでは[「P5.js 日本語リファレンス」] (https://qiita.com/bit0101/items/91818244dc26c767a0fe) の clearStorage関数を説明します。

## clearStorage() 

### 説明文

storeItem() で保存したすべてのローカルストレージアイテムをクリアします。

### 構文

clearStorage() 

### 例

```javascript
function setup() {
  let myNum = 10;
  let myBool = false;
  storeItem('key1', myNum); // key1 に 10 を保存します  
  storeItem('key2', myBool); // key2 に false を保存します
  print(getItem('key1'));
  print(getItem('key2'));
  clearStorage() ;        // クリアします 
  print(getItem('key1')); // 再度、key1 を取得します -> NULL を表示
  print(getItem('key2')); // 再度、key2 を取得します -> NULL を表示
}
```

### 著作権

p5.js was created by Lauren McCarthy and is developed by a community of collaborators, with support from the Processing Foundation and NYU ITP. Identity and graphic design by Jerel Johnson.

### ライセンス

Creative Commons(CC BY-NC-SA 4.0) に従います。
[discord.js] グローバルチャットを作る！

# 概要
discord.js のバージョンが v12 になり、グローバルチャットの機構を作ったので、メモしとこうかなと思います。
(ほかの人も記事を書いているので参考程度に...)
**解説**とありますが、まだまだすごい discord.js が扱えるわけではないので、間違っているかもしれないので
気軽に見てってください。

BOTの導入や Node.js 等のインストールはすでに済んでいるものとします。

# 環境
| 名前 | versionとか | 
| :-- | --: |
| Node.js | v12.16.3 |
| discord.js | v12.2.0 |
**OS : Windows10** 

# コード
```js:index.js
const Discord = require("discord.js"); // --1
const client = new Discord.Client();

client.on("message", async message => { // --2
  if (message.channel.name === "チャンネル名") { // --3
    if (message.author.bot) return; // --4
    if (!message.attachments.size) message.delete();

    client.channels.cache.forEach(channel => { // --5
      if (channel.type === "text") { // --6
        if (!message.attachments.size) {
          const embed = new Discord.MessageEmbed() // --7
            .setAuthor(message.author.tag, message.author.avatarURL())
            .setDescription(message.content)
            .setColor(0x2c2f33);
          if (channel.name === "チャンネル名") { // --8
            channel.send(embed);
          }
        } else {
          message.attachments.forEach(attachment => { //--9
            const embed = new Discord.MessageEmbed()
              .setAuthor(message.author.tag, message.author.avatarURL())
              .setImage(attachment.url)
              .setDescription(attachment.url)
              .setColor(0x2c2f33);
            if (channel.name === "チャンネル名") {
              channel.send(embed);
            }
          });
        }
      }
    });

    return;
  }
});

client.login("BOT_TOKEN"); // --10
```

# 解説
**--1** : discord.jsの読み込みをしています
**--2** : Message イベントが起こったときに、この括弧内の処理がされます
**--3** : Message が送信されたチャンネルが `チャンネル名` だった場合になるように条件分岐をしています
**--4** : 再帰を防ぐために、Messageを送信した人がBOTだった場合は処理を行わないように `return` を書いています

**--5** : BOTが参加しているすべてのサーバーのチャンネルを取得しています (簡単に言うと forEach は for に似たようなもの)
**--6** : 取得したチャンネルのうちチャンネルがテキストチャンネルか否かを判断する条件分岐です
**--7** : v11.xでは `Discord.RichEmbed()` でしたが、v12.x では `Discord.MessageEmbed()` になりました
**--8** : 取得したチャンネルのうちチャンネルの名前が `チャンネル名` か否かを判断する条件分岐です
**--9** : 写真等が送信されたときに処理が行われます (解説が書けそうでしたら後日書きます)
**--10** : これがなければBOTにはログインしてくれません



# まとめ
グローバルチャットはBOTが導入されているサーバーで会話することができます。
ただトラブル等起きやすいので、グローバルチャットを利用するときは常識を守りましょう。

上のコードはシンプルな方です。まだまだいろんな機能を付け加えられると思うのでぜひチャレンジしてみてください！
IQ Botインストール手順（２）DBのインストールと設定

このページは<a href="https://qiita.com/IQ_Bocchi/items/529dc72b6ab3d26dbfe0" target="_blank">IQ Bot インストール手順（検証用）</a>のサブカテゴリです。

前のステップ：<a href="https://qiita.com/IQ_Bocchi/items/2fe2b46f43d8728c34d7" target="_blank">（１）インストールに必要な環境を揃える</a>

このページでは、Automation Anywhere Enterprise (Control Room, Client) および IQ Botを動かすのに必要なDBのインストールと設定について説明します。

#（２）DBのインストールと設定

##事前の確認事項

[こちら](https://qiita.com/IQ_Bocchi/items/4a989eeb3c3f388a45c7)のページに記載のとおり、WindowsのロケールのUTF-8のベータ機能にチェックが入っていないかを確認し、入っていたら外します。

##①SQL Server のインストール

ステップバイステップの手順を以下のページに掲載しています。

https://qiita.com/IQ_Bocchi/items/3d830c2c0771dd7a7e96

##②SQL Server の設定

ステップバイステップの手順を以下のページに掲載しています。

https://qiita.com/IQ_Bocchi/items/d3001507b313a7849eeb


##③SSMSのインストールとログインの作成

ステップバイステップの手順を以下のページに掲載しています。

https://qiita.com/IQ_Bocchi/items/1a32db34514634260a6e


##④必要なテーブルの手作成（V11.3.4のみ）

V11.3.4では、必要なテーブルを手作成する必要があります。
ステップバイステップの手順を以下のページに掲載しています。

https://qiita.com/IQ_Bocchi/items/cebffe71025bd14f6809

#次のステップ

次は[CRのインストール](https://qiita.com/IQ_Bocchi/items/37d0632770bffb1e33f8)を行います。

https://qiita.com/IQ_Bocchi/items/37d0632770bffb1e33f8
IQ Botインストール手順（２）DBのインストールと設定　②SQL Serverの設定

この記事は、以下の記事のサブカテゴリです。

[IQ Bot インストール手順](https://qiita.com/IQ_Bocchi/items/529dc72b6ab3d26dbfe0)　＞　[（２）DBのインストールと設定](https://qiita.com/items/7f02939799347b4db501/)

[前のステップ：①SQL Serverのインストール](https://qiita.com/IQ_Bocchi/items/3d830c2c0771dd7a7e96)

#②SQL Serverの設定

###1) SQL Server 構成マネージャを起動します
起動方法（参考）　※この方法でなくても、構成マネージャーが起動できればOKです
![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/84b2478f-57c5-411f-e86b-e0414c7e2e71.jpeg)

###2) 「このアプリがデバイスに変更を加えることを許可しますか？」と聞かれたら、「はい」をクリック。

###3) SQL Server Browser の起動モードが「自動」になっていることを確認します。

「SQL Serverのサービス」から、「SQL Server Browser」の「開始モード」が「自動」になっているかどうかを確認。
![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/7673b08f-7975-c2f5-5031-26df2b838310.jpeg)

<details><summary>なっていない場合は、こちらの手順で変更します。</summary><div>

「SQL Server Browser」を 右クリック→「プロパティ」を選択します
![02_Browserのプロパティ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/e0ea4457-df80-b038-aee3-495cf2bb4f95.jpeg)

「サービス」タブから「開始モード」を「自動」に設定し、「適用」をクリックしたあとで「OK」をクリックします。
![05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/9b1440ad-24d7-f534-2040-e72004895fee.jpeg)

</div></details>

###4) SQL Serverネットワークの構成＞AACRSQLEXPRESSのプロトコル配下のサービスをすべて有効にします

やりかたはこちら。
![06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/e42c784f-bdb8-e90f-810a-c998e7dfaee8.jpeg)

以下の警告が出ても、気にせず「OK」を押します。
![07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/f2da4c48-3d8b-8420-3ec3-bdd74c2ac6d7.jpeg)

最終的にこのようになっていればOKです。
![08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/815913d8-170f-45c3-da15-e4d796f7bdd3.jpeg)

###5) TCP/IPの、IP ALLのTCPポートを1433に設定します。

やりかたはこちら。

TCP/IPを右クリックし、「プロパティ」を選択します。
![05_TCPIP.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/4b0d17d7-fd0c-8862-afb0-b94aecc0d018.jpeg)

「IP アドレス」タブを選択し、一番下までスクロールします。
「IP ALL」配下の「TCP ポート」（※動的ポート**じゃないほう**）に「1433」と入力し、「適用」をクリックします。
![09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/bd5facef-a39d-d260-67fd-b94ded15a773.jpeg)

以下の警告が出てきても、気にせず「OK」をクリックします。
![10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/05141561-5d81-f338-0f5c-afebb490fce6.jpeg)

「OK」をクリックします。
![11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/0eb9b05c-f688-8a9f-5cd4-c2f35fce40e0.jpeg)

###6) SQL ServerとSQL Server Browserを再起動します

「SQL Serverのサービス」から、該当のサービスを右クリックすると再起動できます。
![12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/6ce672b4-e141-48d8-744f-2e6609eb3f20.jpeg)

最終的に、このような状態になっていればOKです。
![13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/aff297d7-a730-e532-bac6-6c5de8c4c2d8.jpeg)

#次のステップ
次は[③SSMSのインストールと設定](https://qiita.com/items/1a32db34514634260a6e)を行います。
Reactで一番下までスクロール

ちょっとしたことですが、以下のようなスクロールでちょっと詰まったので覚書程度に。。:writing_hand:
![ダウンロード (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325594/a4eeea7f-3d46-c5eb-973b-387b6ef57b8d.gif)

# やりたいこと

コンポーネント内でボタンを押す
↓
アコーディオンが開く
↓
指定位置までスクロールする

スクロールなかったら下にちょろっと出てくるだけなのであんまりよろしく無いかな〜と思いやってみました。

# アコーディオン開くまで

```App.js

const App = () => {
  const [isOpen, setIsOpen] = useState(false);

  const changeIsOpen = () => {
    setIsOpen(!isOpen);
  };

  return (
    <div className="App">
      <div className="wrapper">
        <button onClick={changeIsOpen}>Click Me!</button>
        <ul id="target" className={isOpen ? "ul open" : "ul close"}>
          <li>list1</li>
          <li>list2</li>
        </ul>
      </div>
    </div>
  );
};

export default App;

```

(styled-component使ってましたがとりあえず参考に…）

```style.css
.ul {
  margin: auto;
  list-style: none;
  max-height: 0;
  overflow: hidden;
}

.open {
  max-height: 500px;
  transition: max-height 0.5s;
}

.close {
  max-height: 0;
  transition: max-height 0.5s;
}

```

# 試したこと1

```js

const App = () => {
  const [isOpen, setIsOpen] = useState(false);

  const changeIsOpen = () => {
    setIsOpen(!isOpen);
    const target = document.getElementById("target");
    target.scrollIntoView({ behavior: "smooth", block: "end" });
  };

  return (
    <div className="App">
      <div className="wrapper">
        <button onClick={changeIsOpen}>Click Me!</button>
        <ul id="target" className={isOpen ? "ul open" : "ul close"}>
          <li>list1</li>
          <li>list2</li>
        </ul>
      </div>
    </div>
  );
};

export default App;

```

onClickの時に一緒に処理しようと思ったけどisOpenが変わる前に処理が走ってしまうので上手くいかなかった。

# 試したこと２

そりゃそうか…と思いながらuseEffectを使いましたがまだちゃんと動かない…

```js

const App = () => {
  const [isOpen, setIsOpen] = useState(false);

  const ScrollBottom = target => {
    if (target) {
      target.scrollIntoView({ behavior: "smooth", block: "end" });
    }
  };

  const changeIsOpen = () => {
    setIsOpen(!isOpen);
  };

  useEffect(() => {
     const target = document.getElementById("target");
     if (target) {
         ScrollBottom(target)
     }
   }, [isOpen]);

  return (
    <div className="App">
      <div className="wrapper">
        <button onClick={changeIsOpen}>Click Me!</button>
        <ul id="target" className={isOpen ? "ul open" : "ul close"}>
          <li>list1</li>
          <li>list2</li>
        </ul>
      </div>
    </div>
  );
};

export default App;

```
原因はCSSのtransitionでした。
transitionで0.5s指定しているので、アコーディオンが開く前にjs動いていたようです。


# 解決

アコーディオンの要素に`addEventListener`で`transitionend`をとってスクロールを動かしました。あとイベントが残っていくのでreturnで`removeEventListener`も。

```js

  useEffect(() => {
    const target = document.getElementById("target");
    if (target) {
      target.addEventListener("transitionend", () => {
        ScrollBottom(target);
      });
      return () => {
        target.removeEventListener("transitionend", () => {
          ScrollBottom(target);
        });
      };
    }
  }, [isOpen]);

```

サンプル
https://codesandbox.io/s/transition-l0o2z?file=/src/App.js
Windows環境US101/102設定でCapsLockにIMEオン/オフを割り当てたい

同じことで悩んでいる人がいそうだったので共有しておきます．
US配列キーボードを使っている人，もしくはJIS配列キーボードを無理矢理US配列で使おうとしている頭のおかしい人(私のことです)向けです．

アプリケーションを使用せずに済む方法を探したのですが，見つからなかったのでChangeKeyを使う方法を備忘録として載せておきます．
(2020.5.20 追記)
キー割り当ての変更は，レジストリをいじることでやれるそうです．
ただし，なにか間違えるとどうなるかわからないので自己責任になります．

#やり方
1. ChangeKeyをダウンロードする
2. IMEの設定で適当なキー(私は一生使わないINSキーにしました)にIMEオン/オフを割り当てる
3. ChangeKeyでCapsLockキーに2.でIMEオン/オフを割り当てたキーを割り当てる(私の場合，CapsLockがINSになりますね)
4. 再起動する

これでCapsLockにIMEオン/オフが割り当てられるはずです．

IMEの設定でINSにIMEオン/オフの機能を割り当て，ChangeKeyでCapsLockキーをINSキーにすることで，CapsLockでIMEのオン/オフができるようになるわけです．無理矢理ですね．

色々とアレな方法なので推奨はできませんが，とりあえずこれで目的は達成できます．

なぜこんな方法をとらなければならないかというと，Windowsで使用キーボードの設定をUS101/102にすると，IMEのキー設定における英数(CapsLock)がCapsLock+Shiftになってしまうからです．
そんでCapsLockキーの管理はどこか別のところでされているようです．

そのため，その状態でCapsLockキーになにかしらの機能を割り当てようとすると，このようにキー配置を変更するしかないようです．
このような~~クソ~~仕様のため，このような方法をとる羽目になります．




#注意
US配列における元々のCapsLockキーの役割である大文字・小文字の切り替え機能は失われます．
私は大文字入力の際はShiftキーとの同時押しで入力するのでまったく困りませんが．
大体の人はそうなんじゃないですかね．
AWS 認定ソリューションアーキテクト – アソシエイト試験の勉強ログ

[３週間でAWS認定ソリューションアーキテクト-アソシエイト-とったので、勉強法などまとめてみる - Qiita](https://qiita.com/fukubaka0825/items/238225f9e4c1962bc00c)を読んで、即試験申し込んだ人の12日間に渡る勉強のログです。

ほとんど「動画をみる」しか書いてないので、あまり参考にならないかもしれないですが・・・。
（ハンズオンの動画の際は、手を動かしてました。）

## 1日目

- [３週間でAWS認定ソリューションアーキテクト-アソシエイト-とったので、勉強法などまとめてみる - Qiita](https://qiita.com/fukubaka0825/items/238225f9e4c1962bc00c)を読む。
- Udemyで動画購入
- 試験申込
- 動画みる（13.IAMの概要まで）

## 2日目

- 動画みる（13.IAMの概要まで）

## 3日目

- 動画みる（33.VPCの設計まで）

## 4日目

- 動画みる（67.Well Architected Frameworkのまとめまで）

## 5日目

- 動画みる（81.RDSによるマスタースレーブ構成の構築まで）

↓AutoScaleのハンズオン時、CPUに負荷をかけるプログラム実行例

``` ストレステストでAutoScalingの検証.txt
#stressのインストール
wget http://ftp.riken.jp/Linux/dag/redhat/el7/en/x86_64/rpmforge/RPMS/stress-1.0.2-1.el7.rf.x86_64.rpm

rpm -ivh stress-1.0.2-1.el7.rf.x86_64.rpm

rpm -qa|grep stress

stress --version

#stressによるCPU負荷がけコマンド
stress -c 1 -q &
```

## 6日目


- 動画みる（101.データベースの基礎まで）

## 7日目


- 動画みる（109.EFSの構築まで）

## 8日目

- 動画みる（122.SNSの構築まで）

## 9日目

- 動画見る（終了）
- 動画についてる模擬試験1をやる

154.おまけ講座：クラウド基礎
155.AWSの位置付け

の動画については最初に見たほうがいいかもしれません。

### 模擬試験の結果

![スクリーンショット 2020-05-17 1.29.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510204/586833d3-42ae-6689-509f-0d08d13decd3.png)

思ったより正解してました。

## 10日目

- 模擬試験1の回答確認&復習
- 模擬試験2をやる

## 11日目

- 模擬試験2の回答確認&復習
- 模擬試験3をやる

## 12日目

- 模擬試験3をやる
- 本番試験

## 結果

72%以上で合格ですが結果67%で不合格でした。
（模擬試験3を最後までやり切れなかったのが反省）

12日間で受かりたい人はこれより速いペースで進めれば受かる確率が上がると思います。

## 感想

不合格という結果は悔しいですが、AWSの知識が12日前より圧倒的に身についたのでヨシ！ 
試験のための勉強は一旦終了とし、プライベートの開発や業務で使って理解が深まったタイミングでまた受けてみようと思います:smiley_cat:
AtCoderでRuby学習8【第一回アルゴリズム実技検定 2倍チェック 】正規表現

## はじめに
Ruby学習の一環として「アルゴリズム実技検定」に挑戦します。
そのための学習の中で学んだことをアウトプットしていきます。
今回は「第一回アルゴリズム実技検定」の一問目（2倍チェック）より。
[第一回アルゴリズム実技検定 過去問](https://atcoder.jp/contests/past201912-open/tasks/past201912_a)

自分の解答と、解答する中で学んだ表現・メソッドなどを紹介していきます。


## 問題
3桁の整数を受け取り、それを2倍にして出力するプログラムの作成をします。
しかし、入力される文字列 S には英小文字が紛れ込むことがあります。その場合はエラーを出力します。
S が3桁の整数である場合（'0'で始まる場合も含む）はその2倍の整数を出力し、そうでない場合は'error'と出力すること。

制約
・S は長さ3の文字列である
・S の各文字は、数字もしくは英小文字である

入力は以下の形で与えられる。

```ruby
S

入力例①
678
入力例②
4g4
```

```ruby
出力例
# 入力例①678
=> 678
# 入力例②4g4
=> error
```

## 解答
まずは僕が提出した解答から。

```ruby
s = gets.chomp
print /^[0-9]+$/ === s ? s.to_i * 2 : "error"
```
受け取った文字列を、正規表現を用いて各桁の文字列が0から9であるかを判定し、
真ならInteger型に変換した後に2倍した数字を、偽ならerrorと出力するようにしました。

### 正規表現
ここで、正規表現とは何か、を改めて確認しておきたいと思います。
初めは、「正規表現」という言葉自体わかりづらかったのですが、
こちらの記事を読んでなんとなく腑に落ちました。
[正規表現とは？](https://qiita.com/soarflat/items/2b50c1efe2ea54a762d7)

正規表現とは**「様々な文字列をひとつの文字列で表現する表現法」**
そして**「文字列の検索や置換に便利」**。

他にもあるかもしれませんが、"他"は、その"他"に出会った時に覚えることにします。

### 整数を表現した正規表現で判定する
正規表現とは何かをひとまず定義したところで、今回用いた正規表現を見ていきます。

```ruby
/^[0-9]+$/ === s
```

ここで使用している正規表現に関係するものは以下の通り


**===** 
左辺の正規表現の文字列パターンが、右辺の文字列に含まれているかを判定します。
左辺と右辺は入れ替えて記述してはいけません。

**/ /**
//で囲むことで正規表現オブジェクトを生成することが出来ます。
つまり、「//で囲まれたものが正規表現だよ」という宣言になります。

**[ ]**
角括弧[ ]で挟まれた部分を文字クラスと言います。
1個以上の文字を列挙したもので、いずれかの1文字にマッチします(上記では0から9のうち1文字)。

**-(ハイフン)**
文字の範囲を示します。
[A-C]ならA,B,Cのいずれか、[0-9]なら0から9のうちいずれか、となります。

**^（/^xxx/）**
行頭。文字列の先頭や改行文字の直後の位置にマッチします。

**+**
1回以上の繰り返しを表します。

**$****（/xxx$/）**
行末。文字列の末尾や改行文字の直前の位置にマッチします。

よって、下記の記述の意味は、
「sは、全ての文字が0から9の数字から成る文字列か」を判定していることになります。

```ruby
/^[0-9]+$/ === s
```


## 最後に
以上、「第一回アルゴリズム実技検定」の一問目（2倍チェック）を解く中で学んだ正規表現についてまとめました。
正規表現は、とにかく問題をこなして慣れていくのが大事かなと思います。
使えそうな場面では、積極的に調べながら使っていきたいです。

もし間違いなどございましたら、ご指摘いただけると嬉しいです。
FlutterでNavigator.pushNamedの引数を管理しやすくする

Flutterの公式ドキュメントに[Navigate with named routes](https://flutter.dev/docs/cookbook/navigation/named-routes)というサンプルがありますが、こちらの書き方でページ遷移を実装すると、簡潔に書くことができます。

しかし、文字列をそのまま与えてしまうと、typo等で間違ってしまうことがあるので、以下のようなクラスを作ってあげることでそれを解決します。

```dart
class RouteNames {
  static const String first = '/';
  static const String second = '/second';
}
```

```dart
Navigator.push(context, RouteNames.second);
```

### Before

```dart
import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Named Routes Demo',
    initialRoute: '/',
    routes: {
      '/': (context) => FirstScreen(),
      '/second': (context) => SecondScreen(),
    },
  ));
}

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Screen'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('Launch screen'),
          onPressed: () {
            Navigator.pushNamed(context, '/second');
          },
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Screen"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Go back!'),
        ),
      ),
    );
  }
}
```

### After
```dart
import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Named Routes Demo',
    initialRoute: '/',
    routes: {
      RouteNames.first: (context) => FirstScreen(),
      RouteNames.second: (context) => SecondScreen(),
    },
  ));
}

class RouteNames {
  static const String first = '/';
  static const String second = '/second';
}

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Screen'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('Launch screen'),
          onPressed: () {
            Navigator.pushNamed(context, RouteNames.second);
          },
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Screen"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Go back!'),
        ),
      ),
    );
  }
}
```
Nuxt.js＋Firebaseでログイン情報を保持したい

Nuxt.js+Firebaseの勉強を始めたばかりです。
みなさんの記事を見よう見まねで、Googleアカウントでのログイン認証ができるWebページを作成しました。

# やりたいこと
ログイン後に、ログイン画面 `https://xxx.firebaseapp.com/login/` に遷移したところ、画面が真っ白になりました。ログイン情報を保存して、ログインしていればリダイレクトするようにしたいです。

# 環境
- 開発環境 WindowsPC
- node 12.13.0
- npm 6.12.0
- npx 6.12.0
- Firebase 7.3.0
- Vue CLI 4.0.5
- Nuxt.js 2.10.2

# リダイレクト処理＋ログイン情報の保持
- ~/pages
    - login.vue
- ~/middleware
    - notAuthenticated.js
- ~/store
    - auth.js

ログイン画面 `login.vue` のmiddlewareにリダイレクト処理を含むミドルウェア `notAuthenticated` を追加しました。

``` pages/login.vue
<template>
  <div>
    <FirebaseAuth/>
  </div>
</template>

<script>
import FirebaseAuth from '@/components/FirebaseAuth.vue';
import { mapState, mapGetters, mapActions } from "vuex";

export default {
  middleware: 'notAuthenticated',
  name: 'Login',
  components: {
    FirebaseAuth
  }
}
</script>
```

リダイレクト処理を含むミドルウェア `notAuthenticated` は次のようにしました。

```middleware/notAuthenticated.js
export default function ({ store, redirect }) {  
  if (store.getters["auth/isLoggedIn"]) {
    return redirect('/');
  }
}
```

これでログイン画面にアクセスした時に、ミドルウェアで認証情報の有無をチェックし、適切なページへリダイレクトしてくれます。
補足ですが、ミドルウェアの実行順序は以下の順とのこと。

1. nuxt.config.js
1. Layout Middleware
1. Page Middleware

続いて、ログイン情報を保持するための処理です。

```store/auth.js
import Vue from 'vue';
import { auth } from '~/plugins/firebase';

export const state = () => ({
        user: {},
        status: ""
    });

export const mutations = {
        setUser(state, user) {
            state.status = "loggedIn";
            state.user = user;
        },
        logout(state) {
            state.status = "loggedOut";
            state.user = {};
        }
    };

export const getters = {
        isLoggedIn: (state) => {
          return state.status === "loggedIn";
        },
        getUsername: (state) => state.user.displayName
    };

export const actions = {
        gotUser({ commit }, user) {
            commit("setUser", user);
        },
        logout({ commit }) {
            auth.signOut().then(() => {
                commit("logout");
            })
        },
    };
```

このコードを書くだけでは `state.status` の値は保存されません。
リロード・画面遷移でデータが消えてしまうので、vuex-persistedstateを試すことにしました。

# vuex-persistedstate
まずはインストールします。コマンドは `npm install vuex-persistedstate --save` です。

- ~/plugins
    - persistedstate.js
- ~/store
    - index.js
- ~/nuxt.config.js

```plugins/persistedstate.js
export default async (context) => {
  await context.store.dispatch("nuxtClientInit", context);
};
```

```store/index.js
import { vuexfireMutations } from 'vuexfire';
import createPersistedState from "vuex-persistedstate";

export const mutations = {
  ...vuexfireMutations
};

export const actions = {
  nuxtClientInit ({ commit, state, dispatch }, { req }) {
    createPersistedState()(this);
  },
};
```

```nuxt.config.js
  plugins: [
    '~/plugins/firebase',
    { src: "~plugins/persistedstate.js", ssr: false },
  ],
```
Go言語入門[学習素材編]

# TL;DR
どうも。[シュウタ](https://twitter.com/syuta_sugawara)といいます。
これからgolangの学習を始める方々に向けてお役に立てていただければと思い、学習素材等をまとめていきたいと思います。
LGTM数が増えれば更新していこうかなと思います。

#無料編

## [Tour of Go](https://tour.golang.org/)
https://tour.golang.org/
https://go-tour-jp.appspot.com/

公式チュートリアルです。
ブラウザ上でコードの実行を試すことができます。

エクササイズ含めて大体100個ほどあります。

##[はじめてのGo言語](http://cuto.unirita.co.jp/gostudy/)
http://cuto.unirita.co.jp/gostudy/

僕は実際にこちらのサイトを順を追って進めた訳ではないのですが
golangでわからないことがある時にググった際、
ヒットすることは多かったです。


##[go.div](https://go.dev/)

https://go.dev/
https://learn.go.dev/

goの学習素材が紹介されているサイトです。
現時点ではあまり見れていないのですが
有効性が高そうです。

##[Go by Example](https://gobyexample.com/)
サンプルコードを使ってgolangの学習をすることができます。
初見で利用するより言語仕様を一通り把握したあとや
実際にコードを書く際に利用すると良いです。

日本語・英語両方あります。

https://gobyexample.com/
https://oohira.github.io/gobyexample-jp/

##[Go Web プログラミング](https://astaxie.gitbooks.io/build-web-application-with-golang/content/ja/)
https://astaxie.gitbooks.io/build-web-application-with-golang/content/ja/

初期設定からweb開発までカバーしているサイト。
これから使ってみたいと思っています。

##[Go code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments)
https://github.com/golang/go/wiki/CodeReviewComments
こちらはgolangの言語仕様を学ぶというより
コードの書き方を学ぶというニュアンスに近いかと思います。
一通り基礎を学んだ後に利用してみても良いかもしれません！

日本語訳はこちらです。
https://knsh14.github.io/translations/go-codereview-comments/

#有料編

##[ドットインストール](https://dotinstall.com/)
https://dotinstall.com/

プログラミングを学習し始めて
もう何年か立ちますが未だに
新しく何かを学習する際にはドットインストールを利用することがあります。
基本を抑えるのにコスパが良いと思います。

2020年5月段階では下記の二つのコースがあります。

* 初めてのGo言語[全10回]
* Go言語入[全24回]

#その他

##[The Go PlayGround](https://play.golang.org/)
https://play.golang.org/

学習している際、実際にコードを書いて試したくなることも多いかと思います。
そんな時はこれです！
開発環境の構築無しでgolangのコードを試すことが可能です。

##コミュニティのすすめ
Goエンジニアと繋がることで
モチベーションのアップや最新ニュースのキャッチアップを行うことができる機会も増えるでしょう！

##[Gophers Slack](https://invite.slack.golangbridge.org) 
https://invite.slack.golangbridge.org
世界のGoエンジニアがいるようです。
japanチャンネルに参加してみましょう。

##[golang.tokyo](https://golangtokyo.github.io/)
Goを採用している企業の方々が運営しているコミュニティのようです。


#最後に
質問やコメントもお待ちしています！
他にもこれ足してほしい！などの要望もがあればおっしゃっていただけると幸いです。
最高のGo学習まとめコンテンツつくりましょう！