Techvenience

Technology × Convenience - Vue / React / Next / Nuxt / ChatGPTなどのIT技術がもたらす便利さをお伝えします。最近はChatGPTなどのAI技術を使ってブログを書いています。

【一日一驚】靴下を手袋みたいに手にはめてみた

【一日一驚】靴下を手袋みたいに手にはめてみた

昨日から始めた一日一驚ですが、今日からtwitterとブログに書いていくことにしました。
最初の方は探り探りになると思いますがよろしくお願いします。

今日の一驚

今日は朝からかなりご機嫌な娘。
自分で靴下を履こうとして「お父さん履けないー」(履けるのに)と言って、履かせろオーラを出してきました。
そこで靴下を履かせるフリをして、手にはめてみました。
「手袋かな〜?笑」というと、母親の元に行き「お母さん!手袋かな〜?」と言いに行き、結構喜んでいました。
それが気に入ったのか普通に履かせようとしたら嫌がって、靴下はしばらく手袋として活躍。
このタイムロスで普段乗っている電車に乗れなかったけど娘はなかなかの反応だったのでno problem

一日一驚
一日一驚

結果

結構喜んでいました。それを見て癒してもらいました。
星3つです!⭐️⭐️⭐️

その他

今日思ったことですが、平日は朝しか娘に会えないことが多いです。
一日一驚をやるチャンスは基本朝しかない。難しいですね。
明日はどんなことをしようか考えないと。

私心を捨てるってかなり難しい件

私心を捨てるってかなり難しい件

私心を捨てるという考えすら無かったので、感銘を受けました。
その話を書いていきたいと思います。

私心を捨てる

松下幸之助さんの講演

昨日、ちょうど松下幸之助さんの講演の動画がおすすめで出てきたので見てみました
その動画がこちらになります

www.youtube.com

要約すると賢い人でも会社を潰す人・興す人の二種類がいて、その違いは「私心」があるかどうかと言うことです。
松下さんご本人も、常に私心が出てくるけど頑張って潰している。潰したらまた出てくるけど、それもまた頑張って潰しているとおっしゃっていました。

自分自身は会社を興すとかは考えていないですが、自分なりの目標とかもあります。
考えてみると、この目標はまあ私欲だらけですよw
もちろん社会のため(特に日本のため)にやりたいこともあるけど、まずは「自分」と言う考えが強いんですよね。

そもそも自分が幸せ(不満がない状態)じゃないと、周りに優しくできない自己中なので自然とそうなっちゃいます。そう思い込んでいるだけの可能性もありますが。
そんな時は大好きな奥さんにも優しくできなくなってしまいます。時には当たってしまい後悔することもしばしば。
ただ例外があって娘や姪、甥、飼い犬には絶対に優しくできる不思議。これはなんて言う現象でしょう??
彼らからは癒しをもらっているから当たり前なのかもしれないですね。

恐ろしい養子縁組のニュース

子供の話が出たところで、今日twitterでこんな記事を見つけました。

www.yomiuri.co.jp


これは言葉で表すことのできない怒りを覚えました。
いや幸せに暮らしているかもしれないので想像に過ぎないですが、そうじゃない可能性もありますよね。
そもそも養子縁組を「原則国内」にしているのは、そういった事態が容易に想像できるからでしょう。
斡旋業者もそのくらいわかっているはずです。
養子縁組の場合、それを追跡する仕組みとかあるのでしょうか。
子供たちがみんな幸せであることを願うことしかできないのが悔しいです。

私心を捨てることができるものを大切にした方がいいのかも

話が逸れましたが、自分の場合は子供やペットに関することであれば「私心」を捨てやすそうだなと思った次第です。
そう思えることに力を注ぐことが重要なのかもしれないですね。
小さくても自分のできることを着実にやっていこうと思います。

【一日一驚】アイデア一覧

【一日一驚】アイデア一覧

一日一驚のアイデアを一覧にしました。また実施済みのもに関しては評価とリンクを設定しています。
f:id:duo-taro100:20210324111227j:plain

食事

食事に関する驚き。楽しく作ったり、食べたり

新しい食材を食べてもらう

模索中

一緒に料理する

パンケーキ
蒸しパン
卵焼き

盛り付けを工夫して楽しんでもらう

似顔絵サラダを作る
初めての器に盛り付ける

芸術・創作

新しいものを創る・遊ぶ・楽しむ

歌う

子供が主役の歌を作って一緒に歌う
いつもより早いテンポで歌う

描く

筆を使ってお絵描きする

一緒に作る

模索中

作ったもので遊ぶ

カエルの折り紙
飛行機の折り紙

栽培

何かを栽培してみる

模索中

野菜

模索中

家事

模索中

一人でやってもらう

洋服を着る

予想外なこと

常識とは違うことをしてみる

お出掛け

行ったことのない場所に行く
いつもと違う道を通る

服装・装飾

今までとは違うファッションをしてみる

フリーダム

普段は止めることでも、危険がない限りは好きなことをやらせてみる

おもちゃ

新しいおもちゃ・絵本に触れる

絵本
おもちゃ

逆立ちゴマ

言葉

知らない言葉を覚える

【エラー】This DBMS allows only a single AutoInc column to be returned from an INSERT

Slickを使用していたときにタイトルのエラーが出たので解消していきます。

f:id:duo-taro100:20160218004611p:plain

こちらはpkに対してAUTOINCREMENTが設定されている場合には起こりません。
逆にAUTOINCREMENTではない状態でreturning を使用するとこのエラーが発生します。
なので、解決策は2つです。

①pkにAUTOINCREMENTを設定すべきなのに、設定されていない場合はAUTOINCREMENTにしましょう。

pkであるカラム(ここではid)にAUTOINCREMENTを設定してあげましょう。
■変更前

def id = column[Long]("id", O.PrimaryKey)

■変更後

def id = column[Long]("id", O.PrimaryKey, O.AutoInc)

こうすればエラーは起こりません。

②returningを使わないようにしましょう。

AUTOINCREMENTをつけたくない場合は、レコードinsert時にreturningを使わないように変更します。
■変更前

def create(data:dbData) =(tableQuery returning tableQuery.map(_.id)) += data

■変更後

def create(data:dbData) =tableQuery += data

これでOKです。

【Vue】GASでデータを取ってくるメモ

まずGASでコードを書いて公開する

qiita.com

あとは呼び出すだけ。
axios.get

CORSの問題が出るときは、単にCORSの問題もあるし、GASでエラーがある可能性もある。その他、GASの公開範囲を間違えてもCORSの問題が出てくるので注意

Vue.jsでFirebase Storageを使う

Vue.jsでFirebase Storageを使う

f:id:duo-taro100:20160218004611p:plain

今回はVue.jsで開発しているアプリケーションでVue.jsでFirebase Storageを使う方法を解説します。
今回の開発環境は以下のページで解説している環境を使いますが、他の環境を使用しても大差ありません。
www.sky-limit-future.com

コンテンツ

Firebase側の設定

Firebaseコンソール上でのプロジェクト作成・アプリ追加は以下のページを参考にしてください。
www.sky-limit-future.com


アプリの追加までができたら、Storageを有効化します。
Firebaseコンソールから該当プロジェクトに入り、画面左メニューの「Storage」を選択します

storage設定
storage設定

画面上部に「始める」というボタンがありますのでクリックしてください。
以下の画面が表示されますが、今は無視でOKです。Storageは権限(閲覧/書き込みなど)の設定ができますが、デフォルトではこのようになっているという説明になります。

権限の説明
権限の説明

次に進んでロケーション を設定します。ここでは東京を示すasia-northeast1を選択します。

ロケーション
ロケーション

完了を押すとデフォルトバケットが作成されます。

デフォルトバケット
デフォルトバケット

ここでテスト用のバケットを作成しておきます。Filesタブ選択すると右側に追加ボタンがあります。

f:id:duo-taro100:20200930135307p:plain
バケット追加
名称入力
名称入力

名前を入力して追加しましょう。今回は「test」という名前で作りました。
ここの画面の「Rules」タブを後で使うので覚えておいてください!

これでStorageを使用する準備ができました。

最後に該当アプリで使用するAPIキーなどを取得します。

Firebaseを使うためにVue.js側で設定

プロジェクトの上部に作成したアプリが表示されていると思うので、アプリを選択してください。

アプリ選択
アプリ選択

選択すると歯車マーク(設定)へのリンクが表示されます。

設定画面へ
設定画面へ

設定画面の「全般」タブの一番下に、「マイアプリ」というエリアがあります。その中の「Firebase SDK snippet」という項目で「構成」を選択します。

アプリ設定
アプリ設定

すると以下のような形で、設定値が記載されています。(内容はサンプルです)

const firebaseConfig = {
  apiKey: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  authDomain: "project_id.firebase.com",
  databaseURL: "https://project_id.firebase.com",
  projectId: "project_id",
  storageBucket: "project_id.appsss.com",
  messagingSenderId: "111111111111",
  appId: "9:99999999999:app:7777777777777777",
  measurementId: "A-88888888888"
};

firebaseとの接続で必要になるのでコピーしておきましょう。

ここで、実際のソースコードに変更を加えていきます。
いくつか設定方法があるのですが、私の場合は役割をはっきりとさせたいタイプなので、firebaseの設定だけが記載されているjsを作成します。

/src/firebase/firebase.js

こちらに作成しました。
中身は以下の通りです。

import firebase from "firebase/app";
import "firebase/storage";

// 以下に先ほどコピーしたものを貼り付け
const firebaseConfig = {
    apiKey: process.env.FIREBASE_API_KEY,
    authDomain: process.env.FIREBASE_AUTH_DOMAIN,
    databaseURL: process.env.FIREBASE_DATABASE_URL,
    projectId: process.env.FIREBASE_PROJECT_ID,
    storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
    messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
    appId: process.env.FIREBASE_APP_ID,
    measurementId: process.env.FIREBASE_MEASUREMENT_ID,
};

firebase.initializeApp(firebaseConfig);

export default firebase;

先ほどFirebaseコンソールでコピーしたAPIキーなどの設定値をここに記載します。
私は環境変数(configファイル)を使って記載していますが、Firebaseコンソールでコピーしたものをそのまま貼り付けても問題ないです。
今回はFirebase Stoargeの使い方なので、2行目の

import "firebase/storage";

これの追加も忘れないようにしましょう。
これで実装準備は完了です。次にサンプルページを作成し動作確認を行いましょう。

サンプル画面の作成

サンプルページはデフォルトで用意されているファイルを編集していきます。

/src/components/HelloWorld.vue

まずはこのファイルの中身を以下のように上書きします。

<template>
  <div class="hello">
    <div>ここを編集していきます。</div>
  </div>
</template>

<script>

export default {
  name: 'HelloWorld',
}
</script>

文字列が表示されるだけの画面になりました。
サンプルとして、選択した画像がStorageにアップロードされること。
アップロードされた画像を指定して取得できること、指定バケットに格納されている画像全てを取得できることを確認します。

画面を作成する前に、Firebase Storageの処理を記載するファイルを作成します。
HelloWorld.vue内に記載してもいいのですが、個人的な考えでファイルごとに役割を持たせたいということでこのようにします。
実際はどこに記載していただいてもOKです。
処理の内容はドキュメントを参考にして作成しました。

firebase.google.com


作成ファイルは以下の通りです。

/src/firebase/storage.js

中身は以下のようになります

import firebase from "./firebase.js";

export const STORAGE = firebase.storage();

export const STORAGE_REF = STORAGE.ref();

/**
 * 指定したファイルのダウンロードurlを取得します
 * @param {*} childName
 */
export function  findStorage(childName){
    const downRef = STORAGE_REF.child(childName)
    downRef.getDownloadURL()
    .then((url) => {
       return url;
    })
    .catch(function(error) {
        
    });
};

/**
 * 指定ディレクトリ内にあるファイルのダウンロードurlを取得します
 * @param {*} childName 
 */
export async function findListStorage(childName){
    var listRef = STORAGE_REF.child(childName);
    return listRef.listAll()
}

/**
 * 画像をアップロードします
 * @param inputFile ファイル
 * @param directory バケット名
 */
export function attachImage(inputFile, bucket) {
    const file = inputFile
    if(!file || !bucket) {
      return;
    }

    const uploadTask = STORAGE_REF.child(`${bucket}${file.name}`).put(file)
    uploadTask.on('state_changed',
      (snapshot) => {
        // 成功時の処理
      },
      (error) => {
        // エラー
        console.log('err', error)
      },
      () => {
        uploadTask.snapshot.ref.getDownloadURL().then(function(downloadURL) {
          // ファイルアップロードして使えるようになったときの処理
        })
      }
    )
};

HelloWorld.vueも以下のように変更します。

<template>
  <div class="hello">
    
  
    <b-form-file
      v-model="file1"
      :state="Boolean(file1)"
      placeholder="Choose a file or drop it here..."
      drop-placeholder="Drop file here..."
    ></b-form-file>
    <button v-on:click="addImage()">アップロード</button>

  </div>
</template>

<script>
import {attachImage, findListStorage} from "../firebase/storage";
export default {
  name: 'HelloWorld',
  // 追加
  data () {
    return {
      file1 : null,
    }
  },
  // 追加
  methods : {
    /**
     * 指定画像を追加します
     */
    addImage: function() {
      const file = this.file1;
      if(!file) {
        alert("画像を選択してください");
        return;
      }

      attachImage(file, "test/");

    }
  }
}
</script>

この段階で以下のように表示されます。

画面作成
画面作成


簡単に説明すると

<b-form-file v-model="file1" ....省略></b-form-file>

上記でinputを作成し、画像選択を実行できるようになりました。選択されたファイルをfile1として、v-modelに指定しました。
そのため、dataも用意する必要がありましたので、以下のようにしています。

data () {
    return {
      file1 : null,
    }
  }

また、アップロードボタンを用意しました

    <button v-on:click="addImage()">アップロード</button>

クリック時に呼ばれるメソッドも追加しました。

  methods : {
    /**
     * 指定画像を追加します
     */
    addImage: function() {
      const file = this.file1;
      if(!file) {
        alert("画像を選択してください");
        return;
      }

      attachImage(file, "test/");

    }
  }

さて、実際に動かしてみましょう!
結論からいうとこのままでは正しくアップロードができません。
アップロード時にエラーがあった場合にはログが出るようにしていたので確認してみると以下のように出ています。

FirebaseStorageError {
code_: "storage/unauthorized", message_: "Firebase Storage: User does not have permission to access 'test/スクリーンショット 2019-04-24 16.30.58.png'.", serverResponse_: "{"error": {"code": 403,  ... 省略 .... FirebaseError"}

要するに権限がないとうことにになります。

ここで権限の設定を行います。

権限の設定

再びFirebaseコンソールに戻ります。
Firebaseコンソールから該当プロジェクトに入り、画面左メニューの「Storage」を選択します

storage設定
storage設定

「Rules」タブがあるので移動してください。
ここで権限の設定が可能です。

権限の設定
権限の設定

デフォルトでは以下のようになっています。

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

これを変更します。使い方に関する詳細は以下のドキュメントを参考にしてください。
firebase.google.com

今回は

: if request.auth != null;

上記の箇所を削除し、以下のようにします。

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write
    }
  }
}

変更を加えると、変更を反映させるかどうかのボタンが出てくるので「公開」を選択します

公開
公開

ルール変更には多少時間がかかることがありますが、これで完了です。

画像のアップロード

先ほど失敗した画像アップロードですが今度は成功するはずですので、もう一度試してみてください。
今の実装では成功した場合でも何も起きないので、成功したか分かりません。
実際にFirebaseコンソールのtestバケットに画像がアップロードされているか確認してみましょう。

画像アップロード確認
画像アップロード確認

正常に動いていますね。

画像の取得

続いてアップロードした画像を取得します。

HelloWorld.vueを以下のように変更します。

<template>
  <div class="hello">
    <h3>アップロード</h3>
    <b-form-file
      v-model="file1"
      :state="Boolean(file1)"
      placeholder="Choose a file or drop it here..."
      drop-placeholder="Drop file here..."
    ></b-form-file>
    <button v-on:click="addImage()">アップロード</button>

    <h3>指定画像取得</h3>
    <b-form-group
      description="バケット名を入力してください."
      label="バケット名:"
      label-for="bucketName"
    >
      <b-form-input id="bucketName" v-model="bucketName" trim></b-form-input>
    </b-form-group>

    <b-form-group
      description="ファイル名を入力してください."
      label="ファイル名:"
      label-for="fileName"
    >
      <b-form-input id="fileName" v-model="fileName" trim></b-form-input>
    </b-form-group>
    <button v-on:click="findImage()">取得</button>


    <div v-if="sampleImage">
      <img :src="sampleImage" />
    </div>


  </div>
</template>

<script>
import {attachImage, findListStorage, findStorage} from "../firebase/storage";
export default {
  name: 'HelloWorld',
  // 追加
  data () {
    return {
      file1 : null,
      bucketName : null,
      fileName: null,
      sampleImage : null,
    }
  },
  // 追加
  methods : {
    /**
     * 指定した画像を取得します
     */
    findImage: async function(){
      if(!this.bucketName) {
        alert("バケット名を指定してください。")
        return;
      }
      if(!this.fileName) {
        alert("ファイル名を指定してください。")
        return;
      }
      const image = findStorage(this.bucketName + "/" + this.fileName);
      image.getDownloadURL()
      .then((url) => {
        this.sampleImage = url;
      })
      .catch(function(error) {
          alert("画像ダウンロードURLの取得に失敗しました。")
      });
    },
    /**
     * 指定画像を追加します
     */
    addImage: function() {
      const file = this.file1;
      if(!file) {
        alert("画像を選択してください");
        return;
      }

      attachImage(file, "test/");

    }
  }
}
</script>


こちらも簡単に解説すると

<h3>指定画像取得</h3>
    <b-form-group
      description="バケット名を入力してください."
      label="バケット名:"
      label-for="bucketName"
    >
      <b-form-input id="bucketName" v-model="bucketName" trim></b-form-input>
    </b-form-group>

    <b-form-group
      description="ファイル名を入力してください."
      label="ファイル名:"
      label-for="fileName"
    >
      <b-form-input id="fileName" v-model="fileName" trim></b-form-input>
    </b-form-group>
    <button v-on:click="findImage()">取得</button>

ここで取得したいバケット名とファイル名を入力できるようにしています。
それぞれを保持するためにdataにも変更を加え以下のようにしています。

  // 追加
  data () {
    return {
      file1 : null,
      bucketName : null,
      fileName: null,
      sampleImage : null,
    }
  }

sampleImageは取得した画像のダウンロードURLを保持するために使いますので、ここで作成しておきます。
「取得」ボタンを押すと実際の取得処理が走ります。

その処理を以下のように定義しました。

    /**
     * 指定した画像を取得します
     */
    findImage: async function(){
      if(!this.bucketName) {
        alert("バケット名を指定してください。")
        return;
      }
      if(!this.fileName) {
        alert("ファイル名を指定してください。")
        return;
      }
      const image = findStorage(this.bucketName + "/" + this.fileName);
      image.getDownloadURL()
      .then((url) => {
        this.sampleImage = url;
      })
      .catch(function(error) {
          alert("画像ダウンロードURLの取得に失敗しました。")
      });
    }

bucketNameやfileNameが空の場合はエラーになります。

/src/firebase/storage.js

に定義したfindStorageを利用して、指定した画像を取得する処理になっています。
取得に成功したらsampleImageにダウンロードURLを詰め込み、失敗したらalertダイアログが上がるようになっています。
sampleImageに値が入ると、以下の実装により画像が表示されます。

    <div v-if="sampleImage">
      <img :src="sampleImage" />
    </div>

実際に動かしてみます。
まずは存在しないファイルを指定してみます。
エラーとなりました。
次に正常系。私の場合は、testバケット内に「ハートのマーク.png」という画像があるのでそのように指定してみます。

存在するファイルの入力
存在するファイルの入力
画像の取得
画像の取得

画像が表示されました。
以下は実際にStorageに存在する画像です。

Storageにある画像情報
Storageにある画像情報

今回はここまでです。
画像リストの取得に関しては別の機会にやりたいと思います!

【WEB】Firebaseコンソールでプロジェクト作成

【WEB】Firebaseコンソールでプロジェクト作成

f:id:duo-taro100:20160218004611p:plain

今回はFirebaseコンソールでプロジェクト作成し、アプリケーションを追加するところまでをやってみたいと思います。

firebaseコンソールでプロジェクト作成

まずはログインしてください。googleアカウントがあればOKだったはずです。
console.firebase.google.com

fiebaseは有料プランもありますが、無料でも使えます。
firebase.google.com

FIrebaseコンソールに入ったら、早速プロジェクトを作成します。「プロジェクトを追加」を選択してください。

プロジェクト作成
プロジェクト作成

プロジェクト名の入力を求められます。
ここで入力したプロジェクト名を元にプロジェクトIDが決まりますが、Hostingも利用する場合には独自ドメインを使用しないのであれば、このIDを使ってURLが構築されますので、こだわりがあれば適当に決めないほうがいいと思います。
おそらくプロジェクト名に重複がある場合は適当な文字列が後に付与されるような仕様っぽいので注意しましょう。

プロジェクト名入力
プロジェクト名入力

入力するとアナリティクス利用選択画面が出てきます。後で設定もできるので、不要であればここは「有効にする」をOFFにするといいと思います。
OFFにすると右下のボタンが「プロジェクトを作成」に変わりますので、そのボタンを押しましょう
(ONにした場合、この次の画面でアカウントを選択することになります。)

アナリティクス利用選択
アナリティクス利用選択

ボタンを押すとプロジェクト作成中の画面が表示され、しばらくすると作成完了となります。

プロジェクト名作成完了
プロジェクト名作成完了

ここまででプロジェクト作成が完了しましたが、利用するにはさらにアプリの登録が必要です。

アプリ追加(WEB)

今回はwebアプリであることを想定して進めます。

WEBアプリ追加
WEBアプリ追加

クリックするとアプリ名の入力を求められます。Hostingの設定もこちらでできますが、今回は割愛します。

アプリ名入力
アプリ名入力

アプリ名入力後、SDKの追加方法が記載されている画面が表示されます。

SDK追加
SDK追加

ここに記載されているscriptタグを埋め込んでもいいのですが、今回はnpmでインストールする方法を採用したいと思います。ここはご自分の環境に合わせてみてください。
一度、Firebaseコンソールを離れます。
ターミナルから該当プロジェクトに移動し、以下のコマンドを実行します。

npm install firebase --save

成功すれば

  1. firebase@7.21.1

added 109 packages in 12.678s

のように表示されます(バージョンによって多少の違いがあります)
これでSDKインストールはOKです。
Firebaseコンソールに戻ります。Hostingを有効にした場合は続きがありますが、無効の場合はここで終了でOKです。
「コンソールに進む」を選択するとアプリケーションが追加されます。
アプリの追加作業はこれで完了です。

アプリが追加されるとプロジェクトの上部にアプリが表示されているので、正しく作成できているか確認しましょう。

アプリ追加完了
アプリ追加完了

【Vue.js】BootstrapVueの開発環境を作る

【Vue.js】BootstrapVueの開発環境を作る

f:id:duo-taro100:20160218004611p:plain

今回はBootstrapVueを使った開発環境の構築方法を解説します。
bootstrap-vue.org
BootstrapVueを使うことによってかっこいいデザインが組み込まれたcomponentが使用できるなど、開発がかなり楽になります。
(元となる環境はVue.js + webpackで作成したアプリケーションになります。)

コンテンツ

VueCLIでプロジェクト作成

元となるプロジェクト作成は以下のページで解説しています。(数分で終わります)
www.sky-limit-future.com

BootstrapVue導入

プロジェクトを作成したら、プロジェクト内でBootstarpを使えるようにします。
該当プロジェクトに移動し、ターミナルで以下のコマンドを実行してください。

npm install vue bootstrap-vue bootstrap

成功すれば以下のように表示されます

  1. bootstrap@4.5.2
  2. vue@2.6.12
  3. bootstrap-vue@2.17.3

added 8 packages and updated 1 package in 7.054s

成功したら、プロジェクトの「/src/main.js」を変更します。

変更前
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

ここに5行追加します(コメント除く)

import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.use(BootstrapVue)
Vue.use(IconsPlugin)

変更後
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'

// add
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

Vue.config.productionTip = false

// add 
Vue.use(BootstrapVue)
Vue.use(IconsPlugin)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

これで完成です。実際に使えるかどうか試してみます。

サンプル画面の作成

今回はプロジェクト作成時にデフォルトで作成されるHelloWorld.vueファイルを上書きしていきます。
場所は以下の通りです。

/src/components/HelloWorld.vue

HelloWorld.vue

変更前はどうでもいいので、まず以下のようにします。

<template>
  <div class="hello">
    <div>このエリアを編集していきます</div>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
}
</script>

試しに以下のcomponentsを使ってみます。
bootstrap-vue.org
カード形式ですね。
HelloWorld.vueを以下のように変更しました。

<template>
  <div class="hello">
    <div>
      <b-card
        title="カードタイトルです"
        img-src="https://picsum.photos/600/300/?image=25"
        img-alt="Image"
        img-top
        tag="article"
        style="max-width: 20rem;"
        class="mb-2">
        <b-card-text>
          テストのテキストです!
        </b-card-text>
      </b-card>
      </div>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
}
</script>

これで画面を開くと以下のようになりました。

f:id:duo-taro100:20200929150415p:plain
BootstrapVueの導入完了!

ちゃんと使えていますね。
これで完了となります。

【Vue.js】VueCLIを使用したアプリケーション作成【Webpack】

【Vue.js】VueCLIを使用したアプリケーション作成【Webpack】

Macでの導入になります。Windowsもほとんど変わらないかと思いますが、ツール名などはMacを前提に話していますのでご注意ください。

VueCLI導入

VueCLIの導入については以下のページで説明しています。数分くらいで終わりますので、VueCLIを導入してみてください!
www.sky-limit-future.com

プロジェクト作成

プロジェクト名はご自分で決めてください!ここでは「trading」という名前で作成します。
ターミナルで実行します。

vue init webpack trading

いくつか質問されますが適当でもOKです。vue-routerを使いたい場合は「Y」を入力しましょう。
私はテスト関連を全てNoにしました。最後の質問ではnpmを選択しました。
質問に答えるとプロジェクトが作成されます。

ローカル起動

作成したプロジェクトの動作確認を行います。
プロジェクトに移動します。(ターミナル)

cd trading

ここはご自分で作成したプロジェクト名を指定してください。
該当ディレクトリに移動したら以下のコマンドを実行します。

npm run dev

実行後、以下のurlにアクセスすればデフォルト実装の画面が表示されます。

http://localhost:8080

正しく表示されれば環境構築完了です。

【Vue.js】VueCLIを使用したアプリケーション作成【Webpack】

【Vue.js】VueCLIを使用したアプリケーション作成【Webpack】

Macでの導入になります。Windowsもほとんど変わらないかと思いますが、ツール名などはMacを前提に話していますのでご注意ください。

VueCLI導入

VueCLIの導入については以下のページで説明しています。数分くらいで終わりますので、VueCLIを導入してみてください!
www.sky-limit-future.com

プロジェクト作成

プロジェクト名はご自分で決めてください!ここでは「trading」という名前で作成します。
ターミナルで実行します。

vue init webpack trading

いくつか質問されますが適当でもOKです。vue-routerを使いたい場合は「Y」を入力しましょう。
私はテスト関連を全てNoにしました。最後の質問ではnpmを選択しました。
質問に答えるとプロジェクトが作成されます。

ローカル起動

作成したプロジェクトの動作確認を行います。
プロジェクトに移動します。(ターミナル)

cd trading

ここはご自分で作成したプロジェクト名を指定してください。
該当ディレクトリに移動したら以下のコマンドを実行します。

npm run dev

実行後、以下のurlにアクセスすればデフォルト実装の画面が表示されます。

http://localhost:8080

正しく表示されれば環境構築完了です。

【Mac】VueCLIの導入方法

【Mac】VueCLIの導入方法

f:id:duo-taro100:20160218004611p:plain
npmを使って導入しますが、npmが使える前提で記載します。
npmの導入については以下のページを参考にしてください。

qiita.com

ターミナルでコマンド実行

ターミナルを開き以下のコマンドを実行してください。

 npm install -g vue-cli

正しくインストールできたか確認しましょう。
同じくターミナルで以下のコマンドを実行してください。

 vue --version

3.11.0

こんな感じでバージョンが出たら完了です!

WEBエンジニアが独学でAIを学んでみる - 目的とやること

WEBエンジニアが独学でAIを学んでみる - 目的とやること

f:id:duo-taro100:20160218004611p:plain

施工管理からWEBエンジニアに転身して4年目の私が、独学でAIについて学ぶシリーズの第一回目の記事です。
第一回目の今回は、AIを学ぶ目的や今後の流れなどを書いていきたいと思います。

AIを学ぶ目的

システムエンジニアとしてのステップアップ

システムエンジニアとして成長したい気持ちはありますが、最近モチベーションが低下してきています。何か興味があり、刺激のある体験をしながら成長できないか考えたときに思い浮かんだのが「AI」でした。
そもそもシステムエンジニアを志したのも「かっこいい」と言う思いがあったからですが、「AI」はもっとかっこいいですよね!ちなみに、「システムエンジニアがかっこいい」と思ったのはダイハード4をみたときに感じたことです。単純ですが、私は何か燃えるものがないと進めないのです。

やりたいこと・興味のあること
漠然となんでもいいからAIにデータの処理をさせたいと考えています。
今は知識がないので、現実的にどんなことができるのか分からない状態ですが、こんなことできたらいいなと思うことはあります。

  • 作曲・作文自動化
  • プログラミング自動化
  • 株の値動き予測
  • ブログの記事自動作成
AIエンジニアになるための近道を探る

近道なんてないかもしれませんが、効率厨の私はそこを求めてしまいます。
私の今の状況を正直に言うと「何から始めたらいいか分からない」です。
何から始めたらいいか分からない
今の会社にはプログラミング初心者で入りましたが、その時の感覚と似ています。
Javaの本を読みながら、「意味わかんない」って思いながら取り敢えず読み進めていました。
その時のことを考えて見ると、ある程度知識がつくまでは全体像は見えなかったように思うのでとりあえず最初はがむしゃらにやってみようと思います。
試行錯誤しながら必要なもの・不要なものを見極めて、最終的にはこれから学習を始める方の道標となれるくらいに効率良い勉強方法などを紹介できたらと思っています。

今後の流れ

初めてのことばかりなので、ブログは体系的なものにならないと思います。
まずは自分の学習経過、学習方法などをまとめる感じで、その中で感じたことなどをまとめる専用ページを作れたらと思っています。
最初にやること

  • 「ゼロから作る DeepLearning」を読む
  • Udemyで最適なコースを受講する

androidアプリの課金情報はβ版からリリース版に引き継がれる

androidアプリの課金情報はβ版からリリース版に引き継がれる

f:id:duo-taro100:20160218004611p:plain

最近、androidアプリをリリースしました。
課金要素を入れたアプリは初めてだったので、タイトルの件を知らなかった。

androidアプリの課金情報はβ版からリリース版に引き継がれる

リリース版をインストールしたのに、すでに課金されたことになっている!バグだ!
と思って調査していました。
でもネット上にそんな情報ないなー、と思ってandroidアプリ開発に詳しい人に相談してみることに。

同じアプリと判定されているから、それが正解!
β版とリリース版の区別ってないと思っていいです。

とのことでした。
なるほどねー。ということでバグではありませんでした。
でもちょっと気になることがあって、テスト購入の注文をGooglePlayConsoleの注文管理で払い戻し -> 払い戻し済みのステータスになっても、購入状態で取得できてしまうんですよね。

払戻済みなのに
払戻済みなのに

以下のような情報もあったけど
asacloud9.hatenablog.com

キャッシュクリアとかたくさんやったんですけど。。。こちらのバグなのかもしれない。
もうちょっと調査してわかったら記事にしたいと思います。

awslogsを実行したらbad interpreter: No such file or directoryというエラー

Mojaveでawslogsを実行したらbad interpreter: No such file or directoryというエラー

f:id:duo-taro100:20160218004611p:plain

macOSをMojave最新にしたら、awslogsのコマンド実行時にエラーが発生しました。
エラー内容は

/usr/local/bin/awslogs /usr/local/opt/python/bin/python2.7: bad interpreter: No such file or directory

というものでした。
「/usr/local/bin/awslogs」の中身をみてみると、一番上にエラーとして出ている以下のような記述がありました。

#!/usr/local/opt/python/bin/python2.7

これが指す箇所をみてみると、python2.7がありませんでした。
Mojaveにしたことが問題ではないのかもしれません、最近Anacondaを入れたのですがそれが関係するかも??

www.python.jp

とにかく理由がわからなかったので、awslogsをインストールし直しました。

$ pip install awslogs

特にアンインストールなどもしていませんが、この後にコマンドを実行したら正常に動きました。
これをやったからといって、

/usr/local/opt/python/bin/python2.7

が作られるわけもなく、かといって「/usr/local/bin/awslogs」の以下の記述も変更はありませんでした

#!/usr/local/opt/python/bin/python2.7

一部「/usr/local/bin/awslogs」の中身が変更されていたようですが。。。
とりあえず直ったので良しとします。

Collections.emptyMap()に対してputするとUnsupportedOperationExceptionが起こる

Collections.emptyMap()に対してputするとUnsupportedOperationExceptionが起こる

f:id:duo-taro100:20160218004611p:plain

タイトル通りですが、とある条件の場合に

map =  Collections.emptyMap();

として、そのあとに

map.put(key, value);

とすると「UnsupportedOperationException」が発生します。

Collections.emptyMap()

にはputなどの処理はできないようです。
知らなかった。