OmniAICreator/Qiita-1.07M huggingface dataset:
Untiyなで初め Unityってなんじゃろな編

# Unityとは？
Unityは**ゲームエンジン**と呼ばれるジャンルのソフトウェアで、ゲームの開発を効率的に行うことのできるツール。

ゲームエンジンとして有名なものはUnityの他にUnreal Engine、Cry Engine辺りだろうか？
RPGツクールとか吉里吉里なんかも一応ゲームエンジンなのかな...？

2Dゲームも3Dゲームも、パソコンのゲームもスマホのゲームもVRのゲームも、3DCG動画も。
高機能で柔軟なUnityは様々なものを作られるのに利用されている。

代表例を上げるなら出不精の人も500kmほど歩くようになるポケモンGO、インディー発の超人気タイトルCuphead。
ゲーム実況者御用達の恐怖の森、シノアリス...などなど。

最近では大企業のスマホゲーなんかでも見受けらる。

## Unityのいいところ
* インストールがありえんほど楽
* すべてが**GameObject**、**Component**の関係で一貫性があり、適当に扱ってもとりあえず動く
* Microsoft製のレトロな構文ながらもモダンな書き方もできる言語、**C#**を使う
* 初心者も熟練者も多く、日本語での情報がめちゃくちゃ多い
* よくできたComponentが多く、扱いやすい
* Assetが無料、有料問わずAsset Store上で多数公開されており、素材には困らない

## Unityのよくないところ
* 完成したゲームがちょっと重たい
* オブジェクト同士が複雑に絡み合いがち。不具合の修正に時間がかかることがある。
* Unityでいろいろなことが簡単にできるあまりクオリティを高望みしてしまい、なかなか作品が完成しない
* キーコンフィグの実装がめんどくさい。標準ではゲーム起動前にUnityのダイアログを用いて行う。ダサい。

良くないところも意識していれば大きな問題にはならない。
それほど素敵なツールだってことだ。

# お言葉の説明

## GameObject
**GameObject**はUnityで表示されるキャラクターや障害物、UIなどを含めたすべてのもののこと。
GameObjectという存在によってUnity上ではなんでも同じように扱うことができる。

## Component
GameObjectに対して機能や特殊効果を追加したいときに使うものが**Component**。

音を出したり、重力を計算したり、エフェクトを出したり、アニメーションさせたり、当たり判定をつけたり、光らせたり...
星の数ほどComponentがあるので、やりたいことがきっと実現できるはず。

## C＃
Javaみたいな構文なのに、Kotlinみたいなモダンな書き方もできるMicrosoft製の言語。
オートプロパティや式形式のif文、foreach文も型推論などと機能が豊富で書いていて楽しい。

Unityの他にWindowsフォームアプリケーションや、Xamarinなどで使われているらしい。

# インストールしてみよう
## インストーラのダウンロード
こちらからインストーラをダウンロードしよう。
[Download - Unity](https://unity3d.com/jp/get-unity/download)

`Unity を選択 + ダウンロード`を選ぶ。

<img width="1440" alt="スクリーンショット 2019-04-15 13.25.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273517/0e7038cd-6f9d-b123-19fe-d52547f02c6b.png">

Unityには3エディションあるが、今回は無料のPersonalを利用する。

<img width="1440" alt="スクリーンショット 2019-04-15 13.25.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273517/7cc187de-2533-de42-95b9-3269dc4e270c.png">

もし貴方が神ゲーの作者で収益をたくさん受け取っている場合はProやPlusを購読する必要があるので、心配な人は収益を確認してこよう。
有料のUnityにはデバッグツールや、素材が付属しているらしい。
その他にもゲーム起動時に表示されるUnityのロゴを消したりできる。

無料のPersonalでもUnityロゴの表示がされる以外の機能制限が特にあるわけではないのでありがたく使わせてもらおう。

規約に同意して、ココをクリックするとインストーラがダウンロードされる！！

<img width="1440" alt="スクリーンショット 2019-04-15 13.25.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273517/c1e59da7-90c6-b280-63fb-62938f1e64bf.png">

## インストーラによるインストール
インストーラを起動して、規約を読み、ポチポチと進めていくとこんな画面になる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273517/b2f421a9-512d-b1b6-6c5a-585a457919a2.png)

ここにチェックを入れることでUnity本体と、ゲームを実行可能な形式として書き出すときに必要なツールと、開発環境のVisual Studioをインストールすることができる。

`Build Support`は必要に応じてチェックを入れておこう。
チェックを入れ忘れても後から簡単に追加できるのでとりあえず何にもチェックを入れなくても大丈夫。

Visual Studioにはデバッグツールも揃っており、高機能なIDEではあるが...
Windows向けの様々なビルドツールのせいでかなりストレージが圧迫されるし、インストールに長い時間を要するので、飲めるコーヒーが大量にあり、時間に余裕のある場合はチェックを入れてもいいかもしれない。

ストレージに余裕がなかったり、時間が惜しい人は[Visual Studio Code](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)でいいんじゃないかな。

チェックを入れ、適当にプチプチ進めていくとインストールが始まるのでコーヒーでもガブ飲みしながらゆっくり待とう。
Unityのみのインストールでもそこそこ時間がかかる。そしてそこそこ容量も食われる。

#

インストールが済んだな？
それではUnityの沼へとハマっていこう！！

次 -> 執筆中...
pykwalifyを使ったYaml検証

yamlファイルのバリデーションをおこなうpykwalifyというPythonのツールを使う機会があったので
使い方をまとめる

### 環境情報

検証に使用した環境のバージョン情報

* python3 --version
  * Python 3.6.5

* pip3.6 --version
  * pip 9.0.1 from /usr/lib/python3.6/site-packages (python 3.6)

* インストール
  * pip install pykwalify

### バリデーションの種類

|type|チェック対象|
|:--|:--|
|str|文字列|
|int|整数|
|float|浮動小数点数|
|number|intとfloat|
|text|numberとstr|
|bool|真理値|
|seq|シーケンス|
|map|マップ|
|scalar|スカラー|
|date|日付|
|timestamp|日付と時刻|
|any|なんでも|

### 使い方

* 値の形式チェック

チェックするYamlファイル

```
hoge:
  hoge1: 1
  hoge2: hoge
```

スキーマファイル

```
type: map
mapping:
  hoge:
    type: map
    mapping:
      hoge1:
        type: int
      hoge2:
        type: str
```

  * 値の必須チェック

スキーマファイル

```
type: map
mapping:
  hoge:
    type: map
    mapping:
      hoge1:
        type: int
        required: true
      hoge2:
        type: str
        required: true
```
required: true を指定する

  * 正規表現を使用した文字列形式チェック

スキーマファイル

```
type: map
mapping:
  hoge:
    type: map
    mapping:
      hoge1:
        type: int
        required: true
      hoge2:
        type: str
        pattern: '[a-zA-z]'
        required: true
```
pattern にチェックする正規表現を定義する

* リスト

チェックするYamlファイル

```
hoge:
  seq
    - hoge1
      hoge2
```

スキーマファイル

```
type: map
mapping:
  seq:
    type: seq
    sequence:
      - type: str
        required: true
```

* Mapのリスト

チェックするYamlファイル

```
hoge:
  seq
    - hoge1: 1
      hoge2: hoge
```

スキーマファイル

```
type: map
mapping:
  seq:
    type: seq
    sequence:
      - type: map
        mapping:
          hoge1:
            type: int
            required: true
          hoge2:
            type: str
            required: true
```

実行例

* OK

```
# pykwalify -d hoge.yml -s hoge-schema.yml 
 INFO - validation.valid
```

* NG
  * type: int 項目に文字列を指定

```
# pykwalify -d hoge.yml -s hoge-schema.yml 
 ERROR - validation.invalid
 ERROR -  --- All found errors ---
 ERROR - ["Value 'fuga' is not of type 'int'. Path: '/hoge/hoge1'"]
Traceback (most recent call last):
  File "/usr/bin/pykwalify", line 11, in <module>
    sys.exit(cli_entrypoint())
  File "/usr/lib/python3.6/site-packages/pykwalify/cli.py", line 95, in cli_entrypoint
    run(parse_cli())
  File "/usr/lib/python3.6/site-packages/pykwalify/cli.py", line 82, in run
    c.validate()
  File "/usr/lib/python3.6/site-packages/pykwalify/core.py", line 167, in validate
    error_msg=u'.\n - '.join(self.validation_errors)))
pykwalify.errors.SchemaError: <SchemaError: error code 2: Schema validation failed:
 - Value 'fuga' is not of type 'int'. Path: '/hoge/hoge1'.: Path: '/'>
```
ログイン後にさっきのページに戻りたい

ログインが必要なページに対して直接リンクから飛んだ時、トークン切れなどで再ログインが必要な場合は大抵ログイン画面に飛ばされます。

そしてログインしなおしたら、 **さっき飛んだページではなくトップページ** に戻ってしまった...ということはないでしょうか。

普通に実装すると、「ログインしたらトップに移動」で終わってしまいますが、 UX 的にこれは微妙です。

nuxt.js で「ログインしたらさっき飛んだページに戻る」を実装してみます。

## ログインチェックミドルウェア

まずはログイン状態が大丈夫かどうかを確認するミドルウェアをグローバルに配置します。

```javascript:middleware/auth.js
export default (ctx) => {
  if (store.getters['auth/check']) {
    // 認証されているので何もしない
    return
  }

  // ログイン画面へ誘導
  const redirectUri = encodeURIComponent(ctx.route.fullPath)
  ctx.redirect(`/login?redirect_uri=${redirectUri}`)
}
```

`ctx.route.fullPath` を利用して、今飛ぼうとしたページのパス情報を `redirect_uri` クエリストリングに記録します。

## ログインページ

ログイン後の処理を少し改善します。

```javascript:pages/login.vue
<template>
  <div>DOM は省略</div>
</template>

<script>
export default {
  asyncData(ctx) {
    const redirectUri = decodeURIComponent(ctx.query.redirect_uri || '/')
    if (redirectUri.startsWith('/') === false || redirectUri.startsWith('//')) {
      // 相対パスでない・ // 開始で別ドメインに移動するパスは許可しない
      return {
        redirectUri: '/',
      }
    }
    return {
      redirectUri,
    }
  },
  methods: {
    async login(username, password) {
      await this.$store.dispatch('auth/login', { username, password })

      // 事前に取得していたパスへ移動
      this.$router.push(this.redirectUri)
    },
  },
}
</script>
```

これで元のページに戻ることが出来るようになります。

OAuth によるログインを伴う場合は、一度 sessionStorage などに値を保存して、トークンと共に戻ってきてから保存したパスを読みだして移動することになるので、処理が煩雑になりがちな部分です。

~~(動作確認していないので動かないかも)~~
10行で画像の判別やってみる【TensorFlow】

windowsです。anacondaです。
すべてDOS画面で完結します
pythonは開きません
ブラックホールとポンデリングを見分ける人がいて、これならできそうと感じたので、
やってみたかった画像認識に踏み出してみる

仮想環境の作成
まず現状の環境を確認
windowsのコマンドプロンプトから

```
conda info -e
```
デフォルトだとbaseがあるだけ
どうもkerasやtensolを入れようとするとエラーが起こる。
baseに悪影響を及ぼしたこともあるので仮想環境を作っておくほうがいい。
pythonを起動するたびにエラーが出る事もあった・・・

```
conda create -n IR python=3.7
```
IRという名前で仮想環境を作成

```
activate tensorflow
```
プロンプト画面でbaseからIRに切り替わるのが確認できる
IRという仮想環境に切り替わったことを確認してpip installを行う
(baseに戻るときはdeactivat)
(間違えて作って消したいときはconda remove -n IR --all)
(名前を確認したいときはconda info -e)

```
pip install tensorflow
pip install tensorflow_hub
pip install tensorboard
```
cd でディレクトリを移動する
認識したい画像が入っているフォルダまで移動
仮にフォルダ名「train」とする

```
C:\user\desktop> cd train
C:\user\desktop\train>
```

trainというフォルダーの中にはimagesというフォルダとtestというフォルダ、retrain.pyとlabel_image.pyのスクリプトを置く。
testには学習に使わない画像であり、判別したい画像を入れておく。仮に画像名をcat_test_01.pngというものを入れてあるとする。
スクリプトはここから。（ありがたい）

```
https://raw.githubusercontent.com/tensorflow/hub/master/examples/image_retraining/retrain.py
https://github.com/tensorflow/tensorflow/raw/master/tensorflow/examples/label_image/label_image.py
```
さらにimagesというフォルダの中に判別したい画像をフォルダわけして入れておく。
↓↓↓↓↓↓↓ あなたの記事の内容


───────

↑↑↑↑↑↑↑ 編集リクエストの内容
```
train
-images
 -cat
   |-cat01.png
 -dog
   |-dog02.png
```

プロンプトの画面から

```
python retrain.py --image_dir images --how_many_training_steps 1000
```
を実行
学習のステップ数が1000回
imagesはフォルダを指定

学習が終わってから
tensorboard --logdir /tmp/retrain_logs
を入力すると学習のステップが確認できる
交差誤差はプロンプトの画面でもどんどん減っていくのが見える
ステップを何回に増やすとうまくいくのか、
データが少ないときの回数など試してみたい

学習が終了した後、Cドライブ直下のtmpに
output_graph.pb
output_labels.txt
が出来ていた。
続いて以下のコマンドを打ち込む。
最後のpngでテストフォルダの中の画像を指定する。

```
python label_image.py --graph /tmp/output_graph.pb --labels /tmp/output_labels.txt --input_layer Placeholder --output_layer final_result --image "C:\Users\Desktop\train\tes\cat_test_01.png"
```
結果は

```
cat 0.90095603
dog 0.09904399
```
ネコである確率が90%です。という判断が出てくる。

今回はアニメキャラの顔画像が都合よくフォルダわけされているこちら

```
http://www.nurs.or.jp/~nagadomi/animeface-character-dataset/
```
のデータセットを使用させていただいたが、正確に判断できていた。

実際に判断出来ると感動する。
というか拾いものだけでこんなに簡単にできてしまう便利さに感動。

データセットは顔部分を切り取って、サイズを統一して、とやっているのできれいにできたが、写真を撮る(集める)・学習用に振り分ける、といった前処理が大変そう。
画像をデータセットでなく自分でやるときは便利そうな手法を知っていると楽になりそう。

あとは原理も理解していきたい。
マインクラフトをUSBに入れてポータブル化する(1.13.2Rift対応)

**2019/08/26追記
1.13.2用のRiftのダウンロードリンクがリンク切れを起こしていたため現在ダウンロード可能なリンクに差し替えました。
ただこのリンクは筆者の独自調査の結果発見したものであり公式のアナウンス等のソースがないため正常に作動しない場合もあり得ます。予めご了承ください。**
##はじめに注意事項
これはマインクラフトJava版をUSBに入れる手順を紹介する記事です。
・これはあなたを暇さえあればマイクラしたい廃人の道へ引き込みかねません。覚悟がないならブラウザバックしてください。
・これは何にも言えることだけど、自己責任でやってください。
この記事内容の実践によって発生したデータの破損、アカウント情報漏洩、リアルにおける評価の低下等の被害については一切責任取りません。
##そもそもポータブル化すると何ができる？
いつでもどこでもプレイできます。
ネカフェ、ホテルや他人に借りたPCなど、内部ストレージにインストールするのが憚られるときがありますよね。
USB一本さえあればすべて解決。
スティックを挿して起動してみましょう。
画面に映るのは使い慣れたMOD、リソースパックが導入されたいつものマインクラフトです。
「プレイするのは自分のPCでだけ」という人はわざわざUSB使うメリットはありません。そのままお楽しみください。
###動作環境
-Windows10(64bit)
-Minecraft Java edition

##実際にインストールしてみよう
####事前に用意するもの
* USBメモリ(マインクラフトは非常に軽いので容量は経験上2GBあれば十分遊べると思います。むしろ転送速度を重視しましょう。USB3.0が望ましいです。)
* テキストエディタ(メモ帳で十分です)

###１.Minecraft本体のダウンロード
これがないと始まらない。Minecraft実行ファイルをダウンロードしましょう。
[公式サイトのダウンロードページ](https://www.minecraft.net/ja-jp/download/alternative/)にジャンプすると様々なプラットフォーム向けのDLリンクがあるでしょう。その中から**「Minecraft.exe」**を見つけてダウンロードしましょう。
ダウンロードしたexeファイルはマインクラフトを導入したいUSBの中に入れておきます。
###２．USBで動かすための命令ファイルを作成
はい、USBに入れたファイルですが、こいつ何も設定せずに起動すると内部ストレージの予め決められたフォルダをわざわざ探し出して実行ディレクトリに設定してしまうのです。
なのでこのexeファイルに**「お前が今いるUSBの中にフォルダとか作りなさい！」**という命令をつけて起動してやる必要があります。

やること自体はいたって簡単。
メモ帳起動しましょう。

```bat:run.bat
@echo off
start Minecraft.exe --workDir .
```

上記コードの内容をコピペ。**「run.bat」**と名前をつけ、USB内部のexeファイルと同じところに保存します。
###３．初回起動
先程作ったrun.batをクリックして起動しましょう。(初回に限らず以後はこのbatファイルから起動することになります)
一瞬コンソールの黒い画面が出て消え、マインクラフトのランチャーが起動すれば成功です。
とりあえず最新バージョンでも起動してゲームに必要なファイルを揃えましょう。自動でUSB内に揃えてくれます。
####最低限のセットアップは以上です。ForgeやRift等のMOD導入する人は引き続きがんばりましょう！
##ForgeをUSBにインストール(ver1.12.2以前)
Forgeは簡単です。
１．まずForgeを導入したいバージョンをバニラで起動しておきましょう。
**※ランチャー設定からゲームディレクトリを設定しておくことを強く推奨します。**
２．[Forge公式サイト](https://files.minecraftforge.net/)から「Windows Installer」をダウンロード。クリックで起動し、インストールディレクトリをUSBの中のForgeを入れるバージョンが保存されてるフォルダに指定、実行するだけです。
##RiftをUSBにインストール(ver1.13以降)
こっちはちと面倒くさい。
１．まずForgeのときと同じようにUSB上で1.13(1.13.2)バニラを起動するまでは同じです。

２．ここで早速面倒です。
1.13で遊びたい人は[CurseForgeのRift配布ページ](https://minecraft.curseforge.com/projects/rift)からDLすればいいのですが、現在の最新版1.13.2は本家が対応していないのでChocohead氏が開発された~~[Rift-jitpack-SNAPSHOT.jar](https://jitpack.io/com/github/Chocohead/Rift/jitpack-SNAPSHOT/Rift-jitpack-SNAPSHOT.jar)をDLしましょう。~~ダウンロード可能と思われるリンクは[こちら](https://jitpack.io/com/github/Chocohead/rift/1.0.4-77/rift-1.0.4-77-dev.jar)です。

３．DLしたファイルをクリック起動。ダイアログボックスが出たらそのままOK押して閉じます。
Riftはインストール時に導入先を指定できず、何が何でもPC本体にファイルを作成するようです。なのでPC内に作成されたフォルダを手動で移動する必要があります。

※ちなみにこれはインストール先に該当バージョンのフォルダが既にあるか否かに関わらず作られるようなので、**PC本体のほうでマイクラを起動する必要はありません**。
PC本体に作成されたファイルを見てみると

* 「.minecraft\libraries **\org\dimdev**」
* 「.minecraft\versions **\1.13.2-rift-1.0.4-SNAPSHOT**」
* 
の２フォルダが新しく出来てると思います。各ファイルをUSBに移動しましょう。

* .minecraft\liblaries\org内の「dimdev」フォルダをUSB内の「liblaries\org」(orgフォルダがなければ作成しましょう)に移動
* versions内の「1.13.2-rift-1.0.4-SNAPSHOT」フォルダをUSB内の「versions」フォルダ内に移動
* 最後にインストールするバージョンのフォルダ内に**「mods」フォルダを作成**して完了です。

###全行程完了です。お疲れ様でした！
TortoiseSVNを既にインストールしてる時のコマンドラインツールの追加方法

# 対象の人
既にTortoiseSvnをインストールしてしまって、でもコマンドラインからTortoiseSvnを打てるコマンドラインツールを後から欲しくなった場合

# 対象環境
Windows

# 手順
1.コントロールパネル → プログラムと機能
2.インストールされたプログラムの一覧からTortoiseSVNをクリック
3.上のところに「変更」と出るので、それをクリック
4.TortoiseSVNのセットアップ画面が出てくるので、「次へ」クリック
5.変更またはModifyをクリック
6.「command line client tools」のところが×になっているので、クリックしてローカルハードドライブへのインストールを選択し、「次へ」をクリック
7.「インストール」をクリック

以上です。
Google Apps Script でスプレッドシート内の文字列を検索する TextFinder を試してみる

こんにちは。プライベートではいろいろ模索中の @wezardnet です👻

それはさておき Google Apps Script(GAS) エキスパートの @soundTricker さんが何やらつぶやいていたので目を留めて見ると、やっと GAS に実装されたのか！と思い試してみることにしました (ﾟ∀ﾟ)ｷﾀｺﾚ!!

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">NextでGASのアップデートは特になかった(GSuite Add-onsはベータになりました)ですが、少し前(4/5)にいくつかアップデートがありました<br><br>大きいのはSheetsでFind TextがGASから使えるようになりました。 <a href="https://twitter.com/hashtag/gasja?src=hash&amp;ref_src=twsrc%5Etfw">#gasja</a></p>&mdash; おーはし(さんとりー) (@soundTricker318) <a href="https://twitter.com/soundTricker318/status/1116144853367148544?ref_src=twsrc%5Etfw">April 11, 2019</a></blockquote>

これまでスプレッドシートで文字列を検索する機能は GAS にはなく、自力でがんばるしかありませんでした💦💦

今回は TextFinder クラスでよく使われると思われる文字列検索と文字列置換を試してみたので、情報共有したいと思います✍️
尚、公式ドキュメントは [Class TextFinder](https://developers.google.com/apps-script/reference/spreadsheet/text-finder) になりますので、他の機能（メソッド）を知りたい方はお読みください。


# サンプルデータ
文字列検索するためにはある程度のデータが必要になるので、得意先マスタのスプレッドシートを使うことにします。このシートには 10,000 件のダミーデータが入力されています。

![image01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12023/2b29f065-8bd0-3ab0-bbe0-e9d4cd9d7ae7.png)


# 文字列検索（TextFinder:findAll）
まずはスプレッドシート内の文字列を検索してみます。雑なサンプルコードを以下に示します ☆(・ω<)

```javascript
function findAll(){
	var spread = SpreadsheetApp.getActiveSpreadsheet() ;
	var sheet = spread.getSheets()[0] ;

	var textFinder = sheet.createTextFinder('日本料理');
	var ranges = textFinder.findAll();
	Logger.log('ranges.length = ' + ranges.length) ;

	for ( var i = 0; i < ranges.length; i++ ) {
		Logger.log('A1Notation = ' + ranges[i].getA1Notation()) ;
	}
}
```

上記のスクリプトを実行した結果はログに吐かれます。「日本料理」にヒットするセルの件数は 134 件のようです。

![image02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12023/820865a1-3dd5-5a3d-4383-ec8a01bf3e2b.png)

本当に合ってるかどうかスプレッドシート標準機能で確認します。

![image05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12023/ce802876-746e-3696-6c07-114a0de2c95a.png)

双方で一致するので OK そうです。



# 文字列置換（TextFinder:replaceAllWith）
次にスプレッドシート内の任意の文字列を置換してみます。雑なサンプルコードを以下に示します ☆(・ω<)

```javascript
function replaceAllWith(){
	var spread = SpreadsheetApp.getActiveSpreadsheet() ;
	var sheet = spread.getSheets()[0] ;

	var textFinder = sheet.createTextFinder('日本料理');
	var result = textFinder.replaceAllWith('ねこぽん');

	Logger.log('result = ' + result) ;
}
```

上記のスクリプトを実行した結果はログに吐かれます。「日本料理」 → 「ねこぽん」に文字列置換した結果は 134 件になります。

![image03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12023/f4de094f-7afa-f105-37f3-74aeefbe489b.png)

本当に合ってるかどうかスプレッドシート標準機能で「ねこぽん」 → 「日本料理」の逆パターンを確認してみます。

![image04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12023/88a97a59-61b3-17b9-8975-30b36d60850d.png)

こちらも双方で一致するので OK そうですね。

スプレッドシートを簡易データベースとして扱う時に少し楽になりますね👍
本記事で紹介したスクリプトは [GitHub](https://github.com/wezardnet/gas-SheetTextFinder) に置いておきます。。。
Javascript 「良いパーツ」によるベストプラクティス を読んで

# はじめに
JavaScript 「良いパーツ」によるベストプラクティスを読んだ感想です。

[amazon](https://www.amazon.co.jp/JavaScript-Parts-%E2%80%95%E3%80%8C%E8%89%AF%E3%81%84%E3%83%91%E3%83%BC%E3%83%84%E3%80%8D%E3%81%AB%E3%82%88%E3%82%8B%E3%83%99%E3%82%B9%E3%83%88%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9-Douglas-Crockford/dp/4873113911)

間違い等ありましたら、指摘をお願いいたします。

# 感想
JavaScriptを題材にしていますが、すべての言語に対して共通の考え方ができる部分も多く、大変勉強になりました。
JavaScriptはJavaAppletの失敗により世に出てすぐに使われはじめ、研究機関などによるブラッシュアップを受けていない言語だということを初めて知りました。
というより、様々な言語も最初は完成度が低く、ブラッシュアップを経て、盤石な言語へと進化していくという当たり前のことを認識させられました。
これが、OSSへの貢献の重要性などにつながってくるのだと考えました。

また、JavaScriptの良くない部分は使わず、良い部分を選択して使用する、という考え方が非常に大事です。
この考え方は、JavaScriptだけに留まらず、様々な言語で活用できるかと思います。
良くないパーツ = 誤解を招く可能性があるパーツ。
これまでわかりにくい実装は、ユーティリティコードを自身で書いて対応してきましたが、そもそも使わないという選択があるのであればそれが最善であることがわかりました。

これらの気づきを実現するためには、柔軟にコーディングを変更するスキルが必要であり、悪魔的な書き方で1行で書けてしまうという甘い誘惑に打ち勝つ考えが必要だと感じました。

# 今後に生かすこと
コールバック、クロージャ、メモ化などの実例が順序立ててわかりやすく記載されています。
コールバックとクロージャの必要性と理解できたことは自身の考え方に大きな変化を生んでいると思います。
メモ化は、どんな言語でも適用できるキャッシュ技術だと思います。
今まで自身で作成してきたプログラムに思いをはせると、メモ化で高速化できるものがあったように思います。
アプリケーション側でキャッシュするという考え方、とても素晴らしいです。

簡単ですが、アウトプットします。
Rails version update 覚書 その3

前回 https://qiita.com/takakuda/items/f7ea279778971b71cd9b

依存関係のあるgemを一通りupdateし終えたらrails自体のupdateをする

## rails update

Gemfileを編集する

```
- gem "rails", "5.1.~"
+ gem "rails", "5.2.~"
```

`--conservative` optionを使って依存関係のあるgemのupdateを行わないようにする

```
bundle update  --conservative rails
```

その１ https://qiita.com/takakuda/items/895bd6e776e8e7ec08bf
こちらの手順を実行していく。
依存関係のあるgemの更新が終了していれば`bundle update`自体は成功するはず

`bundle update`が成功したらちゃんとrailsが起動できるかを確認していく

たぶん起動しないので起動しない原因を調査し、1つずつ修正していく
今回は実際に自分がupdateしたときに発生した修正箇所もろもろ

## `ArgumentError: Passing string to be evaluated in :if and :unless conditional options is not supported. Pass a symbol for an instance method, or a lambda, proc or block, instead.`

:if, :unless を使っている時にstringがサポートされなくなりました

```
☓ if: 'first_name.blank?'
○ if: proc { |s| s.first_name.blank? }
```

error messageに書いてある通りに対応すれば大丈夫です

## `undefined method halt_callback_chains_on_return_false= for ActiveSupport:Module (NoMethodError)`

halt_callback_chains_on_return_falseはRails 4との後方互換のためのメソッド。
5.2よりhalt_callback_chains_on_return_falseは削除されたため、`config/initializers/new_framework_defaults.rb`の中のhalt_callback_chains_on_return_falseの行をコメントアウトすればおっけー。
セッション機能(SESSION)

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

私は、立命館大学ロボティクス学科４回生です。
現在、未来電子テクノロジーでインターンを行なっています。
日々のプログラミングで気になったことをブログに書いています。

#初めに
私は、データベース連携フォームを作っている際に、ファイル間のデータの受け渡しに困っていました。
そこで、今回は、一番引っかかったSESSION機能について簡単にお話しします。

#SESSION機能とは
SESSION機能は、webサイトにアクセスして作業を行う一連のことを言います。
これだとわからなかったため、簡単に解釈すると、ログインしてから、ログアウトするまでのようなことです。
つまり、ある状態に入ることなのです。

#SESSION機能を使う理由
Webで使われるHTTPプロトコルに、状態を維持する、管理する方法がないからです。
HTTPプロトコルとは、HTMLなどのコンテンツの送受信で用いられる通信プロトコルのことです。
また、Webページに、アクセエスした人、経緯、回数をHTTPプロトコルでは、保持できないのです。

#私が使ったSESSION機能のコード

```php
session_start();

$number = htmlspecialchars( $_SESSION["number"], ENT_QUOTES );
$name = htmlspecialchars( $_SESSION["name"], ENT_QUOTES );
$grade = htmlspecialchars( $_SESSION["grade"], ENT_QUOTES );
$other = htmlspecialchars( $_SESSION["biko"], ENT_QUOTES );

session_destroy();


```

#まとめ
この記事だけでは、SESSION機能について、存在くらいしかわからないと思います。
ぜひ、興味がある方は、調べてみてはいかがでしょうか？
where後に配列に入っている値をハッシュ形式にする方法。（レコード1件のみ時）

whereで値を取得した後は配列に入っています。
下記のコードですが、Entryモデル中の１つのroom_idには送信者、受信者のuser_idがある。
（1つのroom_idにつき最小、最大２名のみ）
したがって自分以外のuser_idを残すためにwhere.notで自分のuser_idを取得しないようにしている。

@room_idには１つのuser_idしかないのがわかっている中で、
each文での取り出しはスマートではない。

##### コード

```ここに言語を入力
    28:   @room_id = Entry.where(room_id: params[:id]).where.not(user_id: current_user.id)
    29:   @room_id.each do |user|
    30:   @reception_user = User.find(user.user_id)
 => 31:   binding.pry
    32:   end
    33:   link "#{@reception_user.name}さんとのチャットルーム", user_room_path
```

@room_idに入っている値です。

```ここに言語を入力
> @room_id
=> [#<Entry:0x00007ff76be33a40
  id: 2,
  user_id: 2,
  room_id: 1,

```

##### 試したこと
配列からハッシュにするto_hメソッドを見つけて試したが、無理な様子。


```
@room_id = Entry.where(room_id: params[:id]).where.not(user_id: current_user.id)
@room = @room_id.to_h
```


エラー内容

```
wrong element type Entry (expected array)
```

### 解決法
レコードが1件しかないのがわかっているので、firstで配列を展開から展開されハッシュ形式で@entryに渡っている。

```
@room_id = Entry.where(room_id: params[:id]).where.not(user_id: current_user.id).first
```
Humhub(オープンソースSocial Network Kit)をdocker-composeでセットアップ

# TL;DR

* オープンソースSNSキット [Humhub](https://www.humhub.org/) をdockerで稼働させる方法を紹介します
    * [humhub-docker-compose](https://github.com/myoshimi/humhub-docker-compose)を作りましたので，こちらを使用すると簡単です
        * humhubを利用したAPIを使いたいので，開発版(githubのリポジトリ)と公式版（リリースバージョン）の両方でコンテナを立ち上げられるようにしています

# Humhub概要

* 柔軟なSNSキットです．Facebookのようなサイトを作ることができます
    * [各種プラグイン](https://www.humhub.org/en/marketplace)が提供されています
    * オープンソースなので[カスタマイズ](https://www.humhub.org/en/service/customization)も比較的容易です
    * PHPベースなので（好き嫌いはあるものの），phpのライブラリなどで拡張できます

# 構成

* docker-composeで，下図の２つのコンテナを立ち上げます
    * app: Humhub本体
    * db: MariaDB

![humhub-compose.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/3b4086f3-17c4-e2f7-1dd6-28abca2af3bc.png)

* Humhub: 80/TCPを受け付けます．外部公開の際にはリバースプロキシなどで適切なセキュリティ保全を行ってください．
* MariaDB: 3306/TCPでアクセスを受け付けます．dockerネットワークからの接続のみを受け付けます

# 使い方

* 2種類のdocker-compose.ymlを用意しています
    * 開発版([Humhub-github](https://github.com/humhub/humhub)からgit cloneする)のdocker-compose-dev.yml
    * 公式版([Humhub](https://www.humhub.org/)からダウンロードするtar.gz)のdocker-compose-rel.yml
* 開発版は，公式版には含まれているphpライブラリをcomposerでダウンロードする必要があるので，phpのDockerfile(docker-compose.yml内部でビルド時に使用する)の記述が異なります
    * php/Dockerfile.devとphp/Dockerfile.phpの２種類があります

## 公式版

* docker-compose.ymlリポジトリをgithubからダウンロードします
* [Humhub](https://www.humhub.org/)から，最新のコミュニティエディションをダウンロードします
* リポジトリ内に```humhub```ディレクトリを作り，その中にダウンロードしたファイルを展開します
* docker-compose-rel.ymlを指定して```docker-compose```コマンドを実行します

```bash
git clone https://github.com/myoshimi/humhub-docker-compose
cd humhub-docker-compose
mkdir humhub
tar xzvf <Download Directory>/humhub-X.Y.Z.tar.gz \
  -C <path to humhub-docker-compose>/humhub --strip=1

docker-compose -f docker-compose-rel build
docker-compose -f docker-compose-rel up -d
```

## github版

* githubリポジトリからhumhub-docker-composeを```git clone```します
* humhub-docker-composeディレクトリ内で，humhubを```git clone```します
* docker-compose-dev.ymlを指定して```docker-compose```コマンドを実行します

```bash
git clone https://github.com/myoshimi/humhub-docker-compose
cd humhub-docker-compose
git clone https://github.com/humhub/humhub

docker-compose -f docker-compose-dev build
docker-compose -f docker-compose-dev up -d
```

* 初回はcomposerコンテナがライブラリのインストールを終了するまで，数分時間がかかります．
    * ```docker ps -a```で，```humhub-docker-compose_composer_1```がExited状態になれば，稼働しています．

# 不揮発ボリューム

* humhub-docker-composeディレクトリ直下に，```volumes/db```が作られます
    * MariaDBのデータ(```/var/lib/mysql```)が格納されます
* ```humhub```ディレクトリは，appコンテナがマウント(```/var/www/html```)します

# 参考

* [Humhub](https://www.humhub.org/)
* [Humhub-github](https://github.com/humhub/humhub)
ABC - 040- A&B&C

#AtCoder ABC 040 A&B&C
[AtCoder - 040](https://atcoder.jp/contests/abc040)

#A問題

```java
	private void solveA() {
		int numN = nextInt();
		int numX = nextInt();

		out.println(numN - numX > numX - 1 ? numX - 1 : numN - numX);
	}
```

#B問題

```java
	private void solveB() {
		int numN = nextInt();

		int res = 99999999;
		for (int i = 1; i <= numN; i++) {
			for (int j = 1; j <= numN; j++) {
				//タイルが何枚余るか
				int amari = numN - (i * j);
				//タイルを使い切っているならこれ以上の探索は無意味
				if (amari < 0) {
					break;
				}
				res = Math.min(Math.abs(i - j) + amari, res);
			}
		}

		out.println(res);
	}
```

#C問題

 - DPの一番初歩の形
    - 貰うDPと配るDPの両方を試した

```java
private void solveC() {
		int numN = nextInt();
		int[] wk = IntStream.range(0, numN).map(i -> nextInt()).toArray();

		int[] dp = new int[numN];
		Arrays.fill(dp, Integer.MAX_VALUE - 1);

		/*
		 * 貰うDP
		 */
		//		dp[0] = 0;
		//		dp[1] = Math.abs(wk[1] - wk[0]);
		//		for (int i = 2; i < dp.length; i++) {
		//			for (int j = 1; j <= 2; j++) {
		//				dp[i] = Math.min(Math.abs(wk[i] - wk[i - j]) + dp[i - j], dp[i]);
		//			}
		//		}

		/*
		 * 配るDP
		 */
		dp[0] = 0;
		for (int i = 0; i < dp.length; i++) {
			for (int j = 1; j <= 2; j++) {
				if (i + j >= dp.length) {
					continue;
				}
				dp[i + j] = Math.min(Math.abs(wk[i] - wk[i + j]) + dp[i], dp[i + j]);
			}
		}

		out.println(dp[numN - 1]);
	}
```
optionalな配列からnilを取り除く（compactMap）

Swiftプログラムのコードレビューをしていて、オプショナル型の配列をフィルタリングするコードを見かけました。

```swift
self.linkFiles.map{ getLinkFile($0) }.filter{ $0 != nil }.map{ path + "/" + $0! }
```

最後のmapの`$0!`の部分は[forced-unwrapping（【Swift】Optional型を安全にunwrapしよう \- Qiita）](https://qiita.com/mokumoku/items/5fef496f4e97a053e53e#forced-unwrapping) している。
できれば安全にアンラップされたデータを扱いたい。

そこで`filter`の部分で、`nilを取り除いて、アンラップされたデータだけの配列`が手に入ればいいなと考えました。

**Swiftならこんなケースには対応しているはず!!** と思えたので調べてみると、スタックオーバーフローに答えがありました。


- [ios \- Cleaner way to filter nil in Swift array \- Stack Overflow](https://stackoverflow.com/questions/47839097/cleaner-way-to-filter-nil-in-swift-array?rq=1)

ただ、使用している`flatMap`は非推奨となっているようで、`compactMap`をつかった以下のような書きかたが良いようです。

```swift
// Swift version 4.2.1 (swift-4.2.1-RELEASE)
struct Animal {
  let name: String
}
let array:[Animal?] = [
    nil,
    Animal(name: "Tiger"),
    nil, 
    Animal(name: "Lion")]
print( array )
//[
//  nil,
//  Optional(main.Animal(name: "Tiger")),
//  nil,
//  Optional(main.Animal(name: "Lion"))
//]

// 非推奨
// let filterd = array.flatMap{ $0 }
let filterd = array.compactMap{ $0 }

print( filterd )
//[
//  main.Animal(name: "Tiger"),
//  main.Animal(name: "Lion")
//]
```
interactive tabindex='-1'

-demo https://codepen.io/gnjo/pen/ZZXrGY
-delete keyを押すと自身を削除する。

```js
///core
 el.setAttribute('tabindex','-1') //interactive-able
```

```js

let fn={}
fn.deleteMe=function(el){
 let is={}; 
 is.element=function(o){return !!(o && o.nodeType === 1)}
 ;
 if(!is.element(el)){
  console.log('delemteMe not element',el)
  return el;
 }
 el.setAttribute('tabindex','-1') //interactive-able
 el.style.outline='none'
 el.onkeydown=(e)=>{
  if(e.which===46) e.target.remove();//46 delete
 }
 return el;
}


let a=document.querySelector('#a')
a.onkeydown=(e)=>{
 console.log(e.type,e)
}
let b=document.querySelector('#b')
fn.deleteMe(b)///////
```

```html
<img id="a" src="https://i.imgur.com/KkuF4ga.png">

<img id="b" src="https://i.imgur.com/KkuF4ga.png">
```
GO111 で GAE用の外部ライブラリを使っていて unresolved referenceになる問題

今まで使えていたメソッドがなぜか呼び出せなくなっていてかなりハマったのでメモ。

結論としてはパッケージの先頭に以下のように書いてあったのが原因

```go
// +build appengine
```

要するにappengineな環境だけでビルドする設定が入っていた。GAEでgo111対応するとこれは動かなくなるっぽい。

とりあえずこの部分のコメントを外したら動いた。

まだ理解しきってないがとりあえずメモということで。
case文での条件分岐方法

滞在しているページごとにサイドバーに表示させるリストの内容を変更したかったので
if文を使い行っていたが、条件が多くなるに連れて可読性が悪くなってきたため、
case文でコードを書き直したが条件分岐が行われなかった。

if文でviewに書いたコード

```
- if params[:controller] == 'users' && params[:action] == 'show'
```

case文を使い書き直したコード

```
- case params[:controller]
- when 'users' && params[:action] == 'show'
```

teratailで質問し解決したのでメモ。
https://teratail.com/questions/184492
下記のようにすることでコントローラーのアクションごとに異なるviewの切り替えを実現できた。

```
- case params.values_at :controller, :action
- when ['rooms', 'show']
```
Mac OS MojaveでOpenCVでのカメラ使用時に出るエラーの対処メモ

OpenCVのサンプルプログラムで、カメラを開くプログラムを実行したらエラーがでたという話。
どうやらMac OS Mojaveからは、カメラなどを使用するのに一つ手間を加えないといけないらしい...

#動作環境
Mac OS Mojave 10.14.3
Xcode 10.2
OpenCV 4.0.1

#対処法
エラー内容は以下の通り
>This app has crashed because it attempted to access privacy-sensitive data without a usage description.  The app's Info.plist must contain an NSCameraUsageDescription key with a string value explaining to the user how the app uses this data.

info.plistにNSCameraUsageDescriptionを追加して、利用目的を書かないといけないらしいです。
どうやらこの問題はちょっと前からあったらしく、サイトをいくつか参照しましたが
`info.plist`があるであろう場所にありませんでした。

なので作ります。

## info.plistの作成 (既にある人は次項へ)

File→New→FileでProperty Listを選択、`info.plist`と名前をつける。
<img width="729" alt="スクリーンショット 2019-04-15 14.01.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395025/2f09b271-17f2-45e7-7c2d-32eda6d37f6e.png">

左の項目の`info.plist`を選択して、Rootを右クリック

Property List Typeから`info.plist`を選択

これで`info.plist`が作成できました

## カメラを使えるようにする

information Property Listの横の+ボタンを押し、`Privacy - Camera Usage Description`を選択
(NSCameraUsageDescriptionに書き換わるかも)

選択したkeyのValueを埋める
(利用目的を書くらしいが、審査に通したりしないなら何か適当に書いておけば大丈夫です)

`info.plist`の内容を保存
<img width="1140" alt="スクリーンショット 2019-04-15 14.02.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395025/40064e09-a708-e7d6-d3c9-0e5df57f46af.png">

projectの一番上のファイル名を選択、Generalタブに移動

一番上にボタンが出ているので押す(Choose info.plist File...と書かれたボタン)
<img width="1139" alt="スクリーンショット 2019-04-15 14.02.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395025/cf0cc663-5070-e5b4-b9f0-aa2df71e845e.png">
<img width="1137" alt="スクリーンショット 2019-04-15 14.03.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395025/95007c8b-c27f-ad67-5359-98909f7916ff.png">

Build Phasesタブに移動

Copy Filesを開き、以下の操作を実行
　・Destination を Products Directory に変更
　・Subpathを削除
　・Copy only when installing のチェックボックスを外す
　・下の＋をおし、info.plistを選択しAddボタンを押す
<img width="1137" alt="スクリーンショット 2019-04-15 14.03.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395025/9bbd2aa0-65fd-a837-715f-04b88cd0b624.png">
これを
<img width="1138" alt="スクリーンショット 2019-04-15 14.03.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395025/b60698f4-ad84-5812-8205-b7cbcad0341b.png">
こう

自分はこれでできました。

プログラムを動かしたらポップアップが出るので、
OK押したらカメラが開きます。
<img width="488" alt="スクリーンショット 2019-04-15 14.07.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395025/c7831bf2-f6d3-6145-203a-1ec444e8533a.png">


メモ終わり。
Craft CMS の管理画面 URL を変更する

Craft CMS では、管理画面へのリクエストかどうかを判別するトリガーとなるテキストが、デフォルトで `admin` と決まっている。

これを変更するには `config/general.php` に `cpTrigger` を追記する。

```php:config/general.php
<?php

return [
    // Global settings
    '*' => [
        // 管理画面のトリガーワード
        'cpTrigger' => 'fooBar',
    ],
];
```

この例では、管理画面の URL が下記となる。
https://localhost/fooBar

## 参考

**General Config Settings > cpTrigger**
https://docs.craftcms.com/v3/config/config-settings.html#cptrigger
DockerでGatsbyを使うときに「このページは動作していません」と出る問題について

DockerにGatsbyをインストールし、 https://www.gatsbyjs.org/tutorial/part-zero/ にある通りにHello world!を出そうとしたところ、``このページは動作していません``というエラーで表示が出来ませんでした。
なにこれ困る…。

# CheckPoint 1

Dockerfileの適当な場所にポートを解放する設定を書きます。

```dockerfile:Dockerfile
# Expose port
EXPOSE 8000
```

# CheckPoint 2

``docker run``コマンドにホストとコンテナのポートをつなぐオプションをつけて起動します。

```sh
docker run -p 8000:8000 -it
```

``ホスト側のポート:コンテナ側のポート``の順番です。

# CheckPoint 3

https://www.gatsbyjs.org/tutorial/part-zero/#view-your-site-locally のNotesにある通り、 

```sh
gatsby develop --host=0.0.0.0
```
としてホストオプションを指定します（上記サイトで--が一つ多いのはタイポみたいです）。

これで無事に http://localhost:8000/ にホストのブラウザからアクセスしてHello worldできました。
FontAwesomeを使おうとしたら、Could not find one or more icon(s) というエラーが出た話

#概要
FontAwesomeをVue.jsに入れようとした。
他のアイコンでも使えるか試したところ、Could not find one or more icon(s) というエラーが出た。

### FontAwesomeの入れ方
入れ方は、こちらの記事を参照
https://fontawesome.com/how-to-use/on-the-web/using-with/vuejs

#エラーの詳細
<img width="512" alt="スクリーンショット 2019-04-15 13.31.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163480/17412f2d-9283-0f93-d179-7a7aae3cb199.png">

#解決策
prefixを変更する。

Before

```
font-awesome-icon(icon='envelope' )
```

After

```
font-awesome-icon(:icon="['far', 'envelope']" )
```

#解説
FontAwesomeのアイコンには、複数のスタイルが用意されている。
それぞれ、違うprefixを指定する必要がある。


例：

|Prefix|Style|
|:----:|:---:|
|fas|Solid|
|far|Regular|
|fal|Light|
|fab|Brand|

参考：https://fontawesome.com/how-to-use/on-the-web/setup/getting-started
[Mac] LaTexのエラー「output file removed」対処

#概要
久しぶりにLaTexでタイプセットをすると, dviファイルからpdfファイルへと変換されず. 「output file removed」というエラーが発生した. このエラー対処として, 自分の備忘録としても記録しておく.

#エラー対処

奥村先生のLaTeX2e美文書作成入門のサポートページhttps://okumuralab.org/bibun7/の方法を実践したところ解決した. このページからgithubに移動し, 最新版である「Bibunsho7-patch-1.3-20181128.dmg」ダウンロードした. ダウンロード先はデスクトップとし, そこで解凍, アプリケーションの実行を行なった. こうすることで, 正常にpdfが出力されるようになった. 

#参考Webページ
・https://oku.edu.mie-u.ac.jp/tex/mod/forum/discuss.php?d=2306
Texフォーラムでの奥村先生の回答が載っています.
・https://github.com/munepi/bibunsho7-patch/releases
パッチファイルのダウンロード元です.
【WinActor】一次元配列

開発には欠かせない存在、一次元配列ですが、WinActorでは使い方が少々特殊でした。
使えずに諦めて、別の方法で何とか回避された方もいらっしゃると思いますので、実際に開発現場で行った初期化から格納・参照まで紹介していきます。

１．配列の初期化
配列を使用する場合、必須です。
使用する配列が1つだけであれば、最初に一度初期化しておくだけでいいです。
※複数使用する場合は、後述の「３．一次元配列使用時の注意点」を参照してください。

こちらのノードを使用します。
03_変数\02_辞書と配列\１次元配列操作(初期化)

初期状態だと、配列名の設定ができません。
以下のようにスクリプトを変更すると、配列名を指定することができます。

```vb:array.vb

Dim rootArray
arrayName = !配列名!

'ルート配列の存在確認
Set rootArray = WScript.CreateObject("Scripting.Dictionary")
rootArray.RemoveAll()
If rootArray.Exists(arrayName) Then
  getArray = rootArray.Item(arrayName)
  Erase getArray
  rootArray.Remove arrayName
End If

```



２．配列の格納・参照
一次元配列への値格納と参照はこちらのノードを使用します。
・格納：03_変数\02_辞書と配列\１次元配列操作(情報挿入)
・参照：03_変数\02_辞書と配列\１次元配列操作(情報取得)

どちらも、配列名を設定することができます。
ですが、配列名を指定しているにも関わらず、「配列を指定してください」というエラーが発生するので、以下のスクリプトをコメントアウトすることで正常に作動しました。

```vb:array.vb

'入力チェック
If (Len(arrayName) = 0) Then
  errorMsg = "配列名を入力してください"
  Err.Raise 1, "", errorMsg
  WScript.Quit
End If

```

↓↓↓↓↓

```vb:array.vb

'入力チェック
'If (Len(arrayName) = 0) Then
'  errorMsg = "配列名を入力してください"
'  Err.Raise 1, "", errorMsg
'  WScript.Quit
'End If

```



３．一次元配列使用時の注意点
３－１．インデックスについて
配列のノードにある説明文では、インデックスは0～となっていますが、0を指定すると範囲外でエラーとなるため、1から指定する必要があります。

３－２．配列を複数使用する場合
WinActorでは、なぜか1ロボットにつき1配列しか使わない前提で作成されており、
配列を複数用意して、それぞれに値を格納すると、事前に格納した配列に領域が侵されるという事態が発生します。

例：
手順1:
配列Aに以下の値を格納
1
2
3

↓

手順2:
配列Bに以下の値を格納
4
5

↓

手順3:
配列Aの1番目を参照
4

対策としては、その配列を本当に使用する直前で初期化し、
格納・参照を行う必要があります。
初期処理で最初にまとめて初期化しておきたくなりますが、上記のような状態に陥ります。
間で別の配列格納処理(例だと配列B)を挟む場合は、再度初期化と格納処理が必要なので、
共通関数化しておくと便利です。

以上が、WinActorでの一次元配列の初期化、格納・参照でした。
Docker for widnowsでdocker.errors.TLSParameterErrorが発生した場合

# 事象
Windows 10でDocker tool boxから、Dcoker for windowsに乗り換える際に発生

# 解決方法
1. Windowsの検索機能で、キーワード`環境変数`を入力し、`ユーザの環境変数`変更画面を表示
2. 変数名で、Docker_*となっているものを削除

# 参考
https://github.com/docker/for-win/issues/2706
BaserCMSのカスタムフィールドプラグインを4系対応して機能追加してみた

BaserCMSにはPetitCustomFieldと言う結構高機能な3系用のカスタムフィールドプラグインがあるのですが、4系用の更新がされておらず止まったままなので使えるようにしてみました。それに合わせて幾つか機能を追加しています。

※2019/08 オリジナルのカスタムフィールドプラグインも作りました。
[CakePHPユーザーがbaserCMSを開発しやすくするためのカスタムフィールドを作ってみた。](https://qiita.com/BigFly/items/eccbe4e1ce14b46a9c75)
こちらは緊急ニュースの表示をしたりやスライダー画像の差し替えみたいな用途で使うものです。開発者寄りのプラグインですがカスタマイズの自由度は高いです。


## ファイルアップロード機能
とりあえず一番欲しいと思われるファイルアップロード機能を追加しました。
BaserCMS標準のアップロード機能を利用してアップロード出来るようにしているので、そこに追加された画像も含めて選択することが可能です。

![up01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320569/77142d32-2ba3-aabd-f427-3e94afe5a0b9.jpeg)

ファイル選択するとこのような感じになります。

![up02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320569/e46c1ef2-2c6c-ecb2-a725-ccdf2d9128da.jpeg)


## カスタムフィールドの設置する位置を追加
![pos01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320569/e79f5370-729f-5fae-e4f3-e8027c6a9f59.jpeg)

カスタムフィールドの表示位置が上と下しかなく、ちょっと位置が中途半端だったので【エディターの下】を選択できるようにしました。

## 管理画面のUI文言などを調整
使ったことある人しかわからないかもですが登録画面が少し迷子になりやすい感じなので、少しわかりやすく名称などを変更しました。

- カスタムフィールド → フィールドグループ
- フィールド → フィールド項目
- ブログIDで表示 → ブログ名称で表示　など

## 新管理画面テーマに対応 <font color="Red">2019/7 NEW</font>
「拡張機能がサポートしてないからテーマ変更出来ない」だと悲しいので、新テーマに対応しました。  
新管理画面のテーマを設定すると自動で切り替わるようになっています。
パンくずが無くなって操作感が変わったのでボタンなども追加して調整しています。
![admin_theme_support.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320569/d1530c64-487c-0ad9-9440-bc4d511b2e49.jpeg)


## 登録したデータの表示
ヘルパー周りは自分もあまりよくわかっていないのですが、登録されたデータはアーカイブだと\$posts、単ページでは\$postとして紐づいているようです。

※2019/07　追記
**登録しただけではデータは表示されないので**テーマの対象ファイルに追記する必要があります。

```html:テーマの場所
    /theme/blog/設定しているテーマ名/default/
```

- index.php //ブログトップ　例 /news/
- archives.php //カテゴリーやタグなど　例 /news/archives/tag/【タグ名】
- single.php //単記事ページ　例 /news/archives/2【記事番号】
- posts.php //固定ページなどでBcBaser->blogPostsからデータ取る時

詳しくは[テーマガイド]
(http://wiki.basercms.net/ver4/%E3%83%86%E3%83%BC%E3%83%9E%E3%82%AC%E3%82%A4%E3%83%89)を確認してください。

```php:シンプルな出力方法
<?php if (!empty($post['PetitCustomField']['フィールド名'])): ?>
   <?php echo h($post['PetitCustomField']['フィールド名']);?>  
<?php endif; ?>
```

ヘルパー使わずシンプルに変数から出力する方が良いと思います。
自分はPetitCustomFieldヘルパー使っていないので気づかなかったのですが、標準インストール時にTOPページなどの固定ページで使われる\$this->BcBaser->blogPosts();だと**PetitCustomFieldヘルパーが動かない**みたいです。

[baserCMSフォーラム 固定ページでデータが表示できない](https://forum.basercms.net/t/topic/60/2)

直そうかと思ってのですが、イベント噛ませるのが面倒くさそうなのと、値の表示だけだと必要性も感じないので対応しない予定です。



## 今回の修正したファイル
以下にforkして修正した内容を上げてあります。
https://github.com/BigFly3/PetitCustomField

あんまりデバッグ出来てませんが良かったらお試しください。

## インストール時注意
※19/05/30
[baserCmsのフォーラム](https://forum.basercms.net/t/topic/81/2)でインストールできない質問が上がっていたので追記

gitからZIPでダウンロードして解凍すると、フォルダ名が「**PetitCustomField-master**」になっているので、フォルダ名を「**PetitCustomField**」にリネームしてからご利用ください。
#python で値を持った既存の辞書に、デフォルト値つきの辞書をマージする例 ( もう if 'key' in dict なんて書きたくないんですよ‥ )

collections の defaultdict と ChainMap を合わせて使う

# wanna do

- こういう辞書を `d = {"a":1, "b",2}` 
- こう呼び出した時 `d["c"]`
-  KeyError ではなくデフォルト値が入っていてほしい

# example

```py
from collections import defaultdict
import collections

existing_dict = {"a":1, "b":2}

default_dict = defaultdict(int)

merged_dict = collections.ChainMap(existing_dict, default_dict)
```

# exe

```py
Python 3.7.2 (default, Jan 13 2019, 12:50:01)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from collections import defaultdict
>>> import collections
>>> existing_dict = {"a":1, "b":2}
>>> default_dict = defaultdict(int)
>>> merged_dict = collections.ChainMap(existing_dict, default_dict)
>>> merged_dict["a"]
1
>>> merged_dict["b"]
2
>>> merged_dict["c"]
0
>>> merged_dict["d"]
0
```

# p.s

- もしかしたらものすごく迂遠なことをやっていないだろうか
- 何か変だったら白ヤギさんからお手紙ください

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1289








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
OpenLDAP refintモジュールの利用

# OpenLDAPのrefintモジュール
OpenLDAPのrefintモジュールは、LDAPのユーザーエントリの削除・DN変更に合わせて、グループメンバーのエントリを自動的に更新してくれる機能です。

例えば、LDAPのユーザーエントリとグループエントリとして次のエントリが存在する時を考えてみます。

~~~
dn: cn=user1,ou=Users,dc=example,dc=com
objectClass: person
cn: user1
sn: user1

dn: cn=group1,ou=Groups,dc=example,dc=com
objectClass: groupOfNames
cn: group1
description: group1
member: cn=master,dc=example,dc=com
member: cn=user1,ou=Users,dc=example,dc=com
~~~

通常の設定では、user1エントリを削除やDNの変更をするときに、合わせて group1エントリから 「member:cn=user1,ou=Users,dc=example,dc=com」のエントリの削除やDN変更も実行する必要があります。

refintモジュールを利用すると、ユーザー削除やDN変更操作のときに group1エントリの 「member:cn=user1,ou=Users,dc=example,dc=com」属性の更新処理を自動化することができます。

slapd.conf形式で必要な設定は次のようになります。

~~~
moduleload refint
...
overlay refint
refint_attributes member
refint_nothing "cn=master,dc=example,dc=com"
~~~

refintの処理は各LDAPサーバーごとのoverlayにより実施されるため、レプリケーション設定で繋がっているプロバイダー(マスター)、コンシューマー(スレーブ)の全てのサーバーに同じ内容で設定が必要です。

また、refint_nothingパラメーターには、refint処理を行わないDNを指定します。
上記の例では、グループエントリが groupOfNamesオブジェクトクラスで構成されており、必ず1つのmember属性が必要なため、cn=masterのエントリが自動的に削除されないように、refint_nothingパラメーターで指定しています。
Chromeで画面キャプチャ

いつも使っていたキャプチャツールが使えなかったので、調べました。

Chromeではツールを入れなくても画面キャプチャができるらしい。

#ショートカットキー
【Mac】
command + option + I
command + shift + P
「full」→returnキー

【Win】
Ctrl + Shift + I
Ctrl + Shift + P
full + Enterキー

キャプチャ画像がダウンロードされる
今まで知らなかった。。。。

>参照記事
https://requlog.com/self-branding/blog/chrome-full-screen-capture/
【JS】フォームでデータ送信後、サブウィンドウを開く方法

JS勉強中の初心者の覚書です。

サブウィンドウは、window.openで開くことができます。

```java:サブウィンドウを開く
window.open("url", "window_name", "width=100,height=300,scrollbars=yes");
```

普通にサブウィンドウを開くだけなら、
上記のコードをonclickなりで指定してあげれば問題ありません。

私は、
フォームからデータをPOSTしつつサブウィンドウを開きたいなあ、と思いました。
上記のコードでは、指定したURLを開くことはできますが
当然、データを送信することはできません。

そういうことをするためには、
先にサブウィンドウを開いた後で、
そのサブウィンドウをtargetに指定してsubmitしてあげればOKです。

```html:フォーム
<form action="/action" method="post" name="form_hoge" id="form_hoge">
  <input type="text" name="name" value="">
  <input type="button" name="button" value="submit" onclick="open()">
</form>
```

```javascript:サブウィンドウを開く
function open() {
    window.open("about:blank","window_name","width=100,height=300,scrollbars=yes");
    document.form_hoge.target = "window_name";
    document.form_hoge.submit();
}
```

こうすることによって
あたかもデータ送信しながらサブウィンドウが開いたように見えるわけですね。
カンタン！
Eclipseのビューが消えてしまった時にすること

Eclipseで次のようなことが起きたことはありませんか？

* あるソースファイルの編集画面が消えてしまい、パッケージエクスプローラのファイルをクリックしても表示されない
* コンソールや内部ブラウザのような専用ビューが消えてしまい、ウインドウメニューからビューを開こうとしても表示されない

私も何回かこんな目にあったことがあります。マウスを動かした際に、突然ビューが消えてしまうことが多いようです。この場合、どうやらビューは「開いている」のですが、表示だけされないようなのです。

おそらく、ワークスペースファルダ直下にある.metadataフォルダ以下のどこかがおかしくなっているはずなのですが、それを見つけるのが難しい。かと言って.metadata以下を全部削除してしまうと、ソースファイルなどは残るものの、プロジェクトを再設定しなおさなければならないので大変です。

こんな時は、次のどちらかで復旧するはずです。

* パースペクティブを一旦閉じて、開き直す
（Window -> Perspective -> Close Perspective の後、Window -> Perspective -> Open Perpective -> パースペクティブを選択して開く）

または、

* パースペクティブをリセットする
（Window -> Perspective -> Reset Perspective...）

両方やれという説もありますが、私の場合はどちらか一方だけでビューが回復しました。
![perspective.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52659/3176fb59-a12d-aaa7-345e-38a4b7e7440e.png)
Composer: どのパッケージが依存しているか調べる方法

Composerで、あるパッケージが、どのパッケージから依存されているかを調べる方法です。

```
composer why --tree パッケージ名
```

例えば、`symfony/yaml`がどのパッケージで使われているか調べるには、次のようにします。

```
composer why --tree symfony/yaml
```

<img width="512" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/6c5da9a7-ff32-1b77-7e41-7e37245d7bab.png">
Reactで複数のタグを使いたい時

未だにFlagmentの省略した書き方してない人もいると思うので書き残しておきます。

## Flagmentってなに？
JSXのreturnでは、一つの要素しか返しちゃいけないルールがあるので何かのタグでくくらないといけないんだけど`<div>`を使うと無駄な`<div>`があちこちで発生してしまうため、Flagmentってもので記述をするやり方。
確かclassとか属性値も普通の要素のように割り当てられるんじゃなかったかな？(適当な記憶)

## 全体を`<div>`で囲むのは遅れてる。
昔のコードをみると`<div>`で囲っているコードよくありますよね。それしかできなかったんだから仕方ないです。でも今は、もっといい方法があるので覚えておいてください。

```jsx
const Sample = () => {
  return(
    <div>
      <h1>Hello World</h1>
      <p>サンプルコード</p>
    </div>
  );
};
export default Sample;
```

### なぜダメなのか
無駄な`<div>`を生成しちゃうから

## ` <React.Flagment>`のコード
`<div>`の次に考えられたのが`<React.Flagment>`でコンポーネントを囲む方法。
これで記述すれば無駄な`<div>`コードを生み出さなくていい少しだけ全体的にネストが浅くなるはずです。

```jsx
const Sample = () => {
  return(
    <React.Fragment>
      <h1>Hello World2</h1>
      <p>サンプルコード2</p>
    </React.Fragment>
  );
};
export default Sample;
```

## なぜダメなのか
記述が長い。いちいち`<React.Flagment>`なんて書いてられないよ...。

## 本当は、`<>`これでいいんだよ
結論は、これ。
これは、`<React.Flagment>`を省略しただけの書き方
最近React Hooksの公式ドキュメント見たときも使われていたし
ガンガンこれ使っちゃっていいと思う。

```jsx
const Sample = () => {
  return(
    <>
      <h1>Hello World3</h1>
      <p>サンプルコード3</p>
    </>
  );
};
export default Sample;
```

これで終わりです。
Happy hacking!😆
#python の defaultdict を利用して KeyError を防ぎたい

# import

```
>>> from collections import defaultdict
```

# int

どんなキーでもデフォルト値が0のディクショナリを作る

```py
>>> a = defaultdict(int)
>>> a
defaultdict(<class 'int'>, {})
>>> a["1"]
0
>>> a[1]
0
>>> a["a"]
0
>>> a["b"]
0
>>> a["c"]
0
>>> a[0]
0
>>> a[1]
0
>>> a[2]
0
>>> a[1]
0
```

# str

どんなキーでもデフォルトが空白文字列の辞書を作る

```py
>>> a = defaultdict(str)
>>> a[0]
''
>>> a[1]
''
>>> a['some']
''
>>> a['what']
''
```

# dict

デフォルト値がディクショナリのディクショナリ

```py
>>> a = defaultdict(dict)
>>> a[0]
{}
>>> a['some']
{}
```

# nested

デフォルト値が defaultdict の defaultdict

```py
>>> a = defaultdict(lambda: defaultdict(int))
>>> a[0]
defaultdict(<class 'int'>, {})
>>> a[0][0]
0
>>> a["a"]["b"]
0
```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1288








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
delayed_job再起動手順

ローカル開発環境でdelayed_jobを利用してメール送信などの実装をしている場合、delayed_jobが起動していないせいでメールが確認できないということがある。
そのような場合はdelayed_jobを再起動してあげる必要がある。


```
### delayed_jobの再起動
$ bin/delayed_job restart
```

なお、キューがたくさん溜まっているとdelayed_jobを再起動したタイミングで一気にメールが飛ぶので、全部削除しておくとよい

```
$ bundle exec rails c

### 現在溜まっているジョブ数の確認
pry(main)>　Delayed::Job.count

### キューの削除
pry(main)>　Delayed::Job.delete_all
```
Web班 オリエンテーション

# メンター自己紹介
- 下山 (@undermountainaf)
- 荻原 (@designpatterngf)
- 鳥見 

***


# 参加者の自己紹介
班に分かれて自己紹介


***

# Web班について
https://github.com/kcs1959/web-php


***
# 簡単な方針 
- 馬を水飲み場まで連れて行くことはできるが、水を飲ませることはできない
- 上級者より初・中級者が教えた方が上手かも
- Twitterやろう！
ローカル実行でAndroidアプリの課金をテストする

`debug`証明書を使用したビルドでは課金のテストはできませんが、`release`証明書を使用すればAndroid Studioのローカル実行で課金をテストすることができます。
Google Play アプリ署名を有効にしている場合でも、アップロード証明書で署名すれば課金をテストできます。

以下にGUIを使用した手順を紹介します。

1. Android Studioで`Build Variant` を `release` に設定しておく
  <img width="601" alt="f1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18273/4332a84f-0580-85ad-2a5b-a7aae126587b.png">

1. File -> Project Structure -> appモジュール -> signing でアップロード証明書の情報を入力する
  <img width="827" alt="f2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18273/abb0e30e-08b2-7ee0-0092-15c5195c74ea.png">

1. Build Typesタブに移動し、Signing Configに↑で作成したものを設定する
  必要に応じて `debuggable` を `true` に設定する。
  <img width="820" alt="f3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18273/20319a2f-c3a0-b02f-214d-ebd9de5e1d9b.png">

1. Android Studioからアプリを実行する
  <img width="662" alt="f4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18273/3252fd58-a0ab-8c2d-6e2f-350a9e23687f.png">


もちろんreleaseビルドの証明書の設定などは`build.gradle`を手動で修正しても構いません。
NetBeansでフォントを綺麗にする方法

NetBeansで開発するときにデフォルトだと
文字が荒くて非常に見ずらいと思いますが、
以下の対応をすることで綺麗な文字にすることが出来ました。

# 環境
netbeans-8.2
CentOS7

# 対応内容

netbeans-8.2/etc/netbeans.confを開く

netbeans_default_optionsの設定に下記を加える

-J-Dawt.useSystemAAFontSettings=on

NetBeansを開いている場合は再起動
Nuxt.jsにVS Code上でブレークポイントをかける

# 前提
まず↓こちらの記事に沿ってpackage.jsonとlaunch.jsonを作ります。
https://qiita.com/idani/items/ac638d5a0786aaefb8cf （@idani様 ありがとうございます）

これでデバッガは起動するのですが、VS Code上でBreakpointが張れなかったので、もう一歩調べてみました。

# Source Map 有効化
webpackされている関係で、ブラウザが認識しているファイルとVS Codeが認識しているファイルが一致しない。
これを一致させるため、source mapを有効化する。

```javascript:nuxt.config.js
module.exports = {
  ...
  build: {
    extend(config, ctx) {
+     if (ctx.isDev) {
+       config.devtool = 'inline-cheap-module-source-map'
+     }
      // Run ESLint on save
      if (ctx.isDev && ctx.isClient) {
        ...
```
# 設定追加
ここまででとりあえずVS Code上でブレークポイントを設定できるようになるが、実際は止めたい位置で止まらないことがある。
原因は、単一のXXX.vueファイルがブラウザ上では
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398513/6bf72c4a-dccd-8e2f-ef58-338bdb6ce85a.png)
このように複数に分かれて認識されているため。間違ったファイルにブレークポイントがかかってしまう。
これを解決するため、launch.jsonに`sourceMapPathOverrides`を指定する。

```javascript:launch.json
    ...
    "configurations": [
      {
        "type": "chrome",
        "request": "launch",
        "name": "Launch Chrome",
        "url": "http://localhost:3000",
        "webRoot": "${workspaceFolder}",
        "runtimeArgs": [
          "--remote-debugging-port=9222"
        ],
+       "sourceMapPathOverrides": {
+         "webpack:///*.vue": "${workspaceFolder}/*.vue"
+       }
      },
      ...
```
↑このように拡張子.vueまで指定するのがポイント。
unable to open file in targetのエラーが発生しシミュレータービルドができない

# 概要
友人のプロジェクトを手伝うことになり、プロジェクトをgit cloneし、シミュレーターでビルドしようとしたところ`unable to open file in target`のエラーが発生し、シミュレーターでのビルドに失敗したので、対処方法について記述したいと思います。

# エラー画像
<img width="865" alt="スクリーンショット 2019-04-15 11.18.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116254/3c167428-5061-d052-340e-e67bd851b34f.png">


# 環境
Swift4.2
Xcode10.1

# 対処方法
1. Podfile.lockを削除する
2. `pod install`を実行する
3. シミュレーターでビルドする　

# 参考資料
- unable to open file in target xcode 10
https://stackoverflow.com/questions/53117077/unable-to-open-file-in-target-xcode-10
Progate中級編で学んだこと

未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているtatsukichi0803です。

□背景画像の指定
➤background-image:url(画像のurl);

□背景画像の大きさの指定
➤background-size:cover;

□要素を中央に配置する
➤margin:auto;
※必ずwidthもつける

□変化の対象や変化にかかる時間の指定
➤transition:all 1s;
※多くの場合hoverと組み合わせる

□縦方向の中央に文字を配置する
➤要素の高さとline-heightプロパティの高さを同じ値にすると、中央に配置される
➤line-height:65px;

□aタグで全体をクリックする
➤aタグをブロック要素にする
➤display:block;

□影をつける
➤box-shadow:水平方向　垂直方向　色;
➤box-shadaow:10px 10px white;

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。
zipでディレクトリを除外

```bash
zip -r tmp/design.zip design -x \*/.git/\* design/img/\* design/css/\*
```

-r でディレクトリ再帰。なければディレクトリの内容は追加されない
-x で除外。除外のディレクトリ指定はできないのでファイルとして指定

参考

* https://www.atmarkit.co.jp/ait/articles/1607/25/news021.html
* http://kagen88.blogspot.com/2012/12/linuxzip.html