ブログですが、下記に引っ越ししました。
RE:ENGINES https://re-engines.com/
徐々にこちらのブログ記事の一部は引っ越しをすると思います。
また、新しい記事の掲載や活動内容なども掲載をしておりますので、
新しいブログサイトのRE:ENGINESをよろしくお願いします。
2017年4月27日木曜日
2017年2月10日金曜日
Swift3でSCLAlertViewを使ってみた
こんにちは、onukiです。
今回はSwiftでフラットなデザインの
アニメーション付きアラートビューが扱える
SCLAlertViewを試してみたいと思います。
今回はSwiftでフラットなデザインの
アニメーション付きアラートビューが扱える
SCLAlertViewを試してみたいと思います。
準備
おなじみCocoaPodでインストールします。
pod 'SCLAlertView'
実装
今回はボタン付きのアラートを表示したいと思います。
まずはSCLAlertViewをインポートします。
import SCLAlertView
アラートビューを表示します、ボタンは二つ用意します。
let alertView = SCLAlertView()
//ボタンの追加
alertView.addButton("ボタン1") {
//タップ時の処理
print("ボタン1をタップしました")
}
alertView.addButton("ボタン2") {
print("ボタン2をタップしました")
}
//表示実行
alertView.showSuccess("ボタン付きアラート", subTitle: "説明")
そうするとこのように表示されます。
今回は基本的なボタン付きのアラートでしたが、
他にもテキスト入力できるもの、ボタンなしで時間指定で閉じるもの等
色々あるので、興味を持たれた方は作者のgithubを拝見してみてください。
2017年2月9日木曜日
はじめの一歩 -Rails ActiveRecord編- UPDATE2
どうも、はじめです。
前回はUPDATEについて書いてみました。
はじめの一歩 -Rails ActiveRecord編- UPDATE
今回はUPDATEの際readonlyやvalidationで更新ができなかった場合に関して書いていこうと思います。
はじめに
今回も前回と同じテーブルを使用しようと思います。
usersテーブル
[id: 1, user_name: 'Aさん'],
[id: 2, user_name: 'Bさん'],
[Id: 3, user_name: 'Cさん']
itemsテーブル
[id: 1, item_name: 'Rubyの本'],
[id: 2, item_name: 'Railsの本'],
[id: 3, item_name: 'PHPの本']
user_itemsテーブル(userが持っているitemを管理するテーブル)
[id: 1, user_id: 1, item_id: 1],
[id: 2, user_id: 1, item_id: 2],
[id: 3, user_id: 2, item_id: 3]
関連性
user : user_item => 1 : n
item : user_item => 1 : n
ではまず【readonly】で更新できなかった場合の対処法を書いてみます。
readonly
下のように更新をしてみます。
[id: 2, user_id: 1, item_id: 2]
↓
[id: 2, user_id: 1, item_id: 3]
手元でなかなかreadonlyになる状況を再現できなかったため以下の方法でreadonlyにしました。
user_item = UserItem.readonly(true)
この状態で変更しようとしても更新できません。
user_item.find(2).update(item_id: 3)
# ActiveRecord::ReadOnlyRecord: UserItem is marked as readonly
これだとreadonlyでrollbackされてしまいます。
モデルからインスタンスを取得する際にreadonlyをfalseにしてあげれば更新が可能になります。
user_item = UserItem.readonly(false)
user_item.find(2).update(item_id: 3)
次に【validation】でエラーになった場合です。
validation
ユーザーの登録の際、user_nameを入力必須にしていたとします。
入力必須のバリデーションを定義するにはUserモデルに対し以下のように定義します。
# app/models/user.rb
class User < ApplicationRecord
validates :user_name, presence: true
end
この状態でユーザー名を空で登録しようとするとエラーになります。
user = User.new
user.save
次のように記述することで一時的にバリデーションを無効にすることができます。
user = User.new
user.save(:validate => false)
最後に
validationを一時的に無効にすることは可能ですが、
今回例としてあげたのケースの場合、
DBでuser_nameにnot null制約がかかっているとバリデーションを無視することができても、
DBへの登録時にエラーになってしまいますので気をつけましょう。
次回はupdate_attributeとupdate_attributesを使ってみようと思います。
2017年2月8日水曜日
アニメーション

どうもーデザイナーのnottyです。
先日AirbnbDesignからAfter Effectsで作成したアニメーションをレンダリングして
iOS・Android・React Native向けのアニメーションに変換してくれる、『Lottie』が公開されました!
In the past, building complex animations for Android, iOS, and React Native apps was a difficult and lengthy process. You either had to add bulky image files for each screen size or write a thousand lines of brittle, hard-to-maintain code. Because of this, most apps weren’t using animation — despite it being a powerful tool for communicating ideas and creating compelling user experiences. One year ago, we set out to change that.複雑なアニメーションを作るためには、保守が大変で大量のコードを書かないといけない必要だったが、Lottieによって、それは変わりました。的なことが書かれています。
『Lottie introducing』

現在、私が使用しているアプリで
お気に入りや、ローディング、いいねボタンなど
いたるところにアニメーションが使用されています。
ユーザーにとって、ストレスにもなりうるウォークスルーなどに
見てて気持ちの良いアニメーションを作成すると非常に効果的かもしれません。
このライブラリがでて非常に良かったのですが、
それ以上に事業会社からこういった技術(デザイン)をシェアするという事に
毎回興奮します。日本からもこういうプロダクト(技術)などもっといっぱいでると良いなと思う次第でございます。
2017年2月7日火曜日
2017年2月6日月曜日
配牌からあがれる可能性を予測する!(その5 実際にテストしてみる)
テストに使用した配牌について
Youtubeであがっていた○凰のプレイ動画を1半荘分試しました。
結果
# 第一要素があがれる方、第二要素があがれない方
# 重み
[[-0.09800755 0.09915648] # 順子
[ 0.15426824 -0.17342399] # 対子
[-0.61190551 0.61323983]] # 暗刻
# バイアス
[-0.84420447 0.84420447]
この結果だけ見ると、対子の数があがれる方に寄与しているように見えます。
逆に暗刻があるとあがりにくいようです笑
ちょっとリャンメンやカンチャンの形も要素に入れた方が良かったかな、と後悔し始めておりますが、とりあえずこのまま進めたいと思います。
結果を記載しますが、配牌を記載するとおさまりきらないので、「あがれた」か「あがれなかった」を記載します。
逆に暗刻があるとあがりにくいようです笑
ちょっとリャンメンやカンチャンの形も要素に入れた方が良かったかな、と後悔し始めておりますが、とりあえずこのまま進めたいと思います。
結果を記載しますが、配牌を記載するとおさまりきらないので、「あがれた」か「あがれなかった」を記載します。
| 局 | 結果 | あがれる確率 | あがれない確率 |
|---|---|---|---|
| 東1局 | あがれない | 17% | 83% |
| 東2局 | あがれない | 29% | 71% |
| 東3局 | あがれない | 7% | 93% |
| 東3局1本場 | あがれない | 17% | 83% |
| 東4局 | あがれない | 33% | 67% |
| 南1局 | あがれる | 20% | 80% |
| 南1局1本場 | あがれない | 26% | 74% |
| 南2局 | あがれない | 17% | 83% |
| 南3局 | あがれる | 26% | 74% |
| 南4局 | あがれる | 23% | 77% |
パッと見、ちゃんと予測できているようには見えないです。
よく考えたら、麻雀は4人のうち1人があがれるゲームなので、単純計算でアガれる確率は25%です。
教師データが足りないのかもしれないと思い、とりあえずプロの対局1局分追加してみました。
よく考えたら、麻雀は4人のうち1人があがれるゲームなので、単純計算でアガれる確率は25%です。
教師データが足りないのかもしれないと思い、とりあえずプロの対局1局分追加してみました。
結果②
# 第一要素があがれる方、第二要素があがれない方
# 重み
[[ 0.17258578 -0.17396835] # 順子
[ 0.20088727 -0.20564398] # 対子
[-0.33262621 0.34681625]] # 暗刻
# バイアス
[-1.07893278 1.07893278]
先ほどとは重みが変わり、順子もアガれる確率に寄与するようになりました。
それではこちらのパラメータをもとに同じテストデータで実験してみます。
比較しやすいよう先ほど求めた結果を①とし、アガれない確率のみ記載します。
それではこちらのパラメータをもとに同じテストデータで実験してみます。
比較しやすいよう先ほど求めた結果を①とし、アガれない確率のみ記載します。
| 局 | 結果 | 結果①のアガれない確率 | 結果②のアガれない確率 |
|---|---|---|---|
| 東1局 | あがれない | 83% | 73% |
| 東2局 | あがれない | 71% | 64% |
| 東3局 | あがれない | 93% | 92% |
| 東3局1本場 | あがれない | 83% | 80% |
| 東4局 | あがれない | 67% | 72% |
| 南1局 | あがれる | 80% | 85% |
| 南1局1本場 | あがれない | 74% | 79% |
| 南2局 | あがれない | 83% | 80% |
| 南3局 | あがれる | 74% | 79% |
| 南4局 | あがれる | 77% | 73% |
結果の方も変化しました。
10局のうち、6局の「アガれない確率」が下がっています。
つまり「アガれる確率」が上昇しています。
このことから、結果①の時点では、「アガれる」可能性を過少評価していることが考えられます。
10局のうち、6局の「アガれない確率」が下がっています。
つまり「アガれる確率」が上昇しています。
このことから、結果①の時点では、「アガれる」可能性を過少評価していることが考えられます。
おわりに
今後の目標としては、
とりあえず、まずは教師データを作成するのが楽になるインターフェースを実装したいと思います。
参考のソースコードはこちらになります。
https://github.com/naoki85/python_mahjong
- 教師データを増やす
- レイヤーのノードを追加(リャンメン、カンチャン、ペンチャン)の数
とりあえず、まずは教師データを作成するのが楽になるインターフェースを実装したいと思います。
参考のソースコードはこちらになります。
https://github.com/naoki85/python_mahjong
2017年2月4日土曜日
Swift3でLTMorphingLabelを使ってみた
こんにちは、onukiです。
今回はLTMorphingLabelというライブラリが
面白そうなので使ってみました。
今回はLTMorphingLabelというライブラリが
面白そうなので使ってみました。
LTMorphingLabelとは
ラベルのテキスト変更時にエフェクトをつけてくれるライブラリです。
作者のgithubにエフェクトのサンプルがあるのですが、
見ているだけで試してみたい欲に駆られますね。
準備
今回はCocoaPodsで追加します。
ただし、現在Swift3ではブランチの指定をしないと
ビルドが通らないみたいなので気をつけて下さい。
pod 'LTMorphingLabel', :git => 'https://github.com/lexrus/LTMorphingLabel.git', :branch => 'swift3'
実装
まずはLTMorphingLabelをimportします。
import LTMorphingLabel
StoryboardにUILabelを適当に用意し
ClassにLTMorphingLabelを指定してください。
それをIBOutlet接続します。
エフェクトの定義を行います。
これでmorphingLabelのtextを変更すると
エフェクトがかかるようになります。
これだけだとイマイチエフェクトの切り替わりを実感できないのでTimerで
morphingLabelのtextを更新するようにしてみたいと思います。
実装も簡単ですし、見た目も素晴らしいので色々使ってみたいですね。
@IBOutlet weak var morphingLabel: LTMorphingLabel!
エフェクトの定義を行います。
morphingLabel.morphingEffect = .evaporate
エフェクトの種類、サンプルに関しては作者のgithubを参照してください。これでmorphingLabelのtextを変更すると
エフェクトがかかるようになります。
これだけだとイマイチエフェクトの切り替わりを実感できないのでTimerで
morphingLabelのtextを更新するようにしてみたいと思います。
@IBOutlet weak var morphingLabel: LTMorphingLabel!
//表示制御用タイマー
private var timer: Timer?
//String配列のindex用
private var index: Int = 0
//表示するString配列
private let textList = ["シンプルであることは、", "複雑であることよりも", "難しい"]
override func viewDidLoad() {
super.viewDidLoad()
// エフェクトの定義
morphingLabel.morphingEffect = .evaporate
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
//タイマーの追加
timer = Timer.scheduledTimer(timeInterval: 3.0,
target: self,
selector: #selector(update(timer:)), userInfo: nil,
repeats: true)
timer?.fire()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
timer?.invalidate()
}
func update(timer: Timer) {
//ここでtextの更新
morphingLabel.text = textList[index]
index += 1
if index >= textList.count {
index = 0
}
}
これでLTMorphingLabelのエフェクトを堪能できると思います。実装も簡単ですし、見た目も素晴らしいので色々使ってみたいですね。
2017年2月3日金曜日
Swift3でTTTAttributedLabelリンク表示の指定をやってみた
こんにちは、onukiです。
以前、TTTAttributedLabelでのリンク表示を紹介しましたが
今回は応用でLabelにリンクを表示したくない時などに使える
リンク表示の指定をやって見たいと思います。
実行するとこのような表示になります。
「URL」をタップすると以下のメソッドが呼ばれます。
遷移するURLを画面に表示しないので色々使えると思います。
以前、TTTAttributedLabelでのリンク表示を紹介しましたが
今回は応用でLabelにリンクを表示したくない時などに使える
リンク表示の指定をやって見たいと思います。
準備
前回の記事を参照してください。
実装
今回は表示の文字列から「URL」の部分をタップできるようにします。
//リンクをタップできるように設定
linkLabel.enabledTextCheckingTypes = NSTextCheckingResult.CheckingType.link.rawValue
//リンクのタップを制御するために設定
linkLabel.delegate = self
let label = "URLをタップできます。"
linkLabel.text = label
//labelから“URL”を部分を選択
let range = NSRange.init(location: 0, length: 3)
//タップした時の接続先
let url = URL(string: "https://www.google.co.jp/")
//TTTAttributedLabelにリンクを指定
linkLabel.addLink(to: url, with: range)
実行するとこのような表示になります。
「URL」をタップすると以下のメソッドが呼ばれます。
func attributedLabel(_ label: TTTAttributedLabel!, didSelectLinkWith url: URL!) {
print(url)//url => https://www.google.co.jp/
}
遷移するURLを画面に表示しないので色々使えると思います。
2017年2月2日木曜日
はじめの一歩 -Rails ActiveRecord編- UPDATE
どうも、はじめです。
前回はJOINについて書いてみました。
はじめの一歩 -Rails ActiveRecord編- SELECT4
今回はUPDATEに関して書いていこうと思います。
はじめに
今回も前回と同じテーブルを使用しようと思います。
usersテーブル
[id: 1, user_name: 'Aさん'],
[id: 2, user_name: 'Bさん'],
[Id: 3, user_name: 'Cさん']
itemsテーブル
[id: 1, item_name: 'Rubyの本'],
[id: 2, item_name: 'Railsの本'],
[id: 3, item_name: 'PHPの本']
user_itemsテーブル(userが持っているitemを管理するテーブル)
[id: 1, user_id: 1, item_id: 1],
[id: 2, user_id: 1, item_id: 2],
[id: 3, user_id: 2, item_id: 3]
関連性
user : user_item => 1 : n
item : user_item => 1 : n
UPDATEを行うには主に以下の二つの方法があります。
・saveメソッドを使用する。
・updateメソッドを使用する。
でははじめに【saveメソッド】を使用した方法から書いていきます。
save
user_itemsを以下のように変更したいと思います。
[id: 3, user_id: 2, item_id: 3]
↓
[id: 3, user_id: 3, item_id: 3]
1.変更したいモデルインスタンスを取得
user_item = UserItem.find(3)
2.変更したい値を代入
user_item.user_id = 3
3.代入が完了したら登録
user_item.save
以上の手順でupdateが完了します。
2で複数のカラムを変更することも可能です。
次に【updateメソッド】を使用した方法を書いてみます。
update
updateでも同様にuser_itemsを以下のように変更したいと思います。
[id: 3, user_id: 2, item_id: 3]
↓
[id: 3, user_id: 3, item_id: 3]
updateメソッドを使用する際も2つの方法があります。
一つはsaveメソッドと同じように変更したいモデルインスタンスを取得し、
updateという流れになります。
user_item = UserItem.find(3)
user_item.update(user_id: 3)
もう一つは一度変数にインスタンスを取得するという工程を飛ばす方法です。
UserItem.find(3).update(user_id: 3)
どれも結果は同じになります。
まとめ
updateをする際変更したいレコードがreadonlyになっていた場合や、
validation等の関係で更新が失敗する場合があります。
その場合の対処法等を次回書いてみようと思います。
2017年2月1日水曜日
作業用BGMについて
デザイナーの nottyです。今日は普段、作業する際に聞く音楽を紹介したいと思います。
音楽を聴くと捗る場合や、逆に捗らない時もあります。
どんな時に聴いているかも記載するので、参考になればと思います。
こういう音楽は特に集中すると聴こえなくなります。
【日本語ラップ MIX】DJ KRO
TOKYO AFTERNOON JAPANESE HIPHOP MIX
Nujabes - Modal Soul
出演するDJが流す曲、主にイベントで流れる曲を聴いて作成します。
サウンドクラウドでDJを検索するとMIXが上がっていたりします。
他にもゲームのデザインをした時は名作ゲームの音楽を聴いてました。
ブレスト/資料作成系
気分をあげたり、リラックスしたり感情の浮き沈みがあるタスクの時は
Spotify
・気分によってプレイリストを選択
Prime music
・プライムラジオで垂れ流し
と使い分けています。
他にも
ジ・居酒屋サウンド
http://413tmks.s3.amazonaws.com/izakayasound/index.html
おと風景
http://otofukei.com/
などの環境音を作業用BGMにします。
気分に合わせて、捗る音楽をチョイスできるのもスキルだと思うので、
普段聴かない音楽を聴いてタスクへ向かうのも良いのではないでしょうか。
個人的にはEDMをガンガンにかけて体を揺らしながらデザインがしたいものです。
音楽を聴くと捗る場合や、逆に捗らない時もあります。
どんな時に聴いているかも記載するので、参考になればと思います。
ルーチンワーク系
主にMIXをかけています。同じトーン,テンポが続く曲は繰り返し行う作業系に向いてると思います。またMIXなので変化があり、飽きずに聴くことができます。こういう音楽は特に集中すると聴こえなくなります。
【日本語ラップ MIX】DJ KRO
TOKYO AFTERNOON JAPANESE HIPHOP MIX
Nujabes - Modal Soul
クリエイティブ系
製作する内容にあわせて音楽を変えています。クラブイベントのフライヤーを作成するときは、出演するDJが流す曲、主にイベントで流れる曲を聴いて作成します。
サウンドクラウドでDJを検索するとMIXが上がっていたりします。
他にもゲームのデザインをした時は名作ゲームの音楽を聴いてました。
ブレスト/資料作成系
気分をあげたり、リラックスしたり感情の浮き沈みがあるタスクの時は
Spotify
・気分によってプレイリストを選択
Prime music
・プライムラジオで垂れ流し
と使い分けています。
他にも
ジ・居酒屋サウンド
http://413tmks.s3.amazonaws.com/izakayasound/index.html
おと風景
http://otofukei.com/
などの環境音を作業用BGMにします。
気分に合わせて、捗る音楽をチョイスできるのもスキルだと思うので、
普段聴かない音楽を聴いてタスクへ向かうのも良いのではないでしょうか。
2017年1月31日火曜日
Gemのバージョンをプロジェクトごとに分ける方法
こんにちは。h_ono_222です。
複数のアプリケーションを同時に開発している場合、同じGemでもそれぞれのアプリケーションごとにバージョンを分けたい場合があると思います。
今回はその方法を紹介します。
以上です。
複数のアプリケーションを同時に開発している場合、同じGemでもそれぞれのアプリケーションごとにバージョンを分けたい場合があると思います。
今回はその方法を紹介します。
1. 空のプロジェクトを作成する
$ mkdir test_app && cd test_app
$ bundle init
Writing new Gemfile to /Users/user_name/test_app/Gemfile
2. Gemfileを修正する
# gem "rails"のコメントアウトを外します。3. インストール先を指定してbundle install
$ bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/
Fetching version metadata from https://rubygems.org/
Fetching dependency metadata from https://rubygems.org/
Resolving dependencies....
# 〜中略〜
Bundle complete! 1 Gemfile dependency, 38 gems now installed.
Bundled gems are installed into ./vendor/bundle.
4. アプリケーションを作成する
$ bundle exec rails new .
exist
create README.md
create Rakefile
create config.ru
create .gitignore
conflict Gemfile
Overwrite /Users/DevWork/Documents/test_app/Gemfile? (enter "h" for help) [Ynaqdh] Y # Yを入力してEnter
force Gemfile
# 〜中略〜
Bundle complete! 15 Gemfile dependencies, 62 gems now installed.
Bundled gems are installed into ./vendor/bundle.
run bundle exec spring binstub --all
* bin/rake: spring inserted
* bin/rails: spring inserted
以上です。
2017年1月30日月曜日
配牌からあがれる可能性を予測する!(その4 勾配を求める際に詰まったこと)
こんにちは、Taroです。
前回の記事の記事の続きになります。
配牌からあがれる可能性を予測する!(その3 学習の実装)
本日は学習を実装する上で、すぐに理解できなかった勾配算出に関わる部分をまとめたいと思います。
前回の記事の記事の続きになります。
配牌からあがれる可能性を予測する!(その3 学習の実装)
本日は学習を実装する上で、すぐに理解できなかった勾配算出に関わる部分をまとめたいと思います。
前回の訂正
損失値を算出して、グラフ化しておりましたが、1回ごとの平均値として算出しておりませんでした。
そのため、実際にどれくらいの誤差が生じているか分かりづらかったため、平均値で図をプロットするよう修正しました。
差分はこちらです。
https://github.com/naoki85/python_mahjong/commit
そのため、実際にどれくらいの誤差が生じているか分かりづらかったため、平均値で図をプロットするよう修正しました。
差分はこちらです。
https://github.com/naoki85/python_mahjong/commit
勾配法について
ある重み、バイアスパラメーターのときの、損失関数の勾配(傾き)を求め、傾きが小さくなるようパラメーターを変化させる手法とのことです。
機械学習はこの最適パラメーターを求めるのが1つの命題となっています。
ただ、パラメーターを決めると一口で言っても無限に近い数値の海から探さなければいけません。
ここで本の中で使っていた例えは、思わずへ〜、と頷いてしまいました。
文中ででてくるSGDは、確率的勾配降下法という手法の略です。
機械学習はこの最適パラメーターを求めるのが1つの命題となっています。
ただ、パラメーターを決めると一口で言っても無限に近い数値の海から探さなければいけません。
ここで本の中で使っていた例えは、思わずへ〜、と頷いてしまいました。
文中ででてくるSGDは、確率的勾配降下法という手法の略です。
ここに風変わりな冒険家がいます。彼は広大な乾燥地帯を旅しながら、日々深い谷底を求めて旅を続けています。
~~中略~~
しかも、彼は、厳しい”制約”を2つ自分に課しています。ひとつは地図を見ないこと、もうひとつは目隠しをすることです。
~~中略~~
この困難な状況で重要となってくるのが、地面の「傾斜」です。
~~中略~~
そこで、今いる場所で一番傾斜がきつい方向に進もうというのが、SGDの戦略です。
「ゼロから作るDeep Learning」第6章より引用
勾配を算出する関数について
さて、実際に勾配を算出する段になりまして、少し理解が追いつきませんでした。
例えば、損失関数に対する微分は下記のようになります。(本の中の式)
(Pythonではlambda式で一行で書けるようですが、あえてこちらで記載します。)
fをWに関して微分して勾配を求めます。
ここで、高校数学程度の知識しかない私はこう思いました。
あれ、fをWに関して微分しても、Wが要素になってないから0なんじゃないか、と。
とりあえずこの疑問は置いておいて、本を読み進めていくと、どう考えても勾配を0として計算しているようには見えませんでした。
Wをどこかで関わらせているのかと思い、勾配を求める関数をちゃんと読んでみました。
恥ずかしながら、ここで引っかかり、いまいち以降の処理を理解できておりませんでした。
もし、こちらの本で勉強していて、同じような場所で詰まっているという方がいらっしゃれば、参考にしていただければ、と思います。
例えば、損失関数に対する微分は下記のようになります。(本の中の式)
# xはテストデータ、tは教師データです。
# lossは損失関数です。
def f(W):
return net.loss(x, t)
ここで関数fはxとtから求める損失関数、f(W)でWに関する関数になります。(Pythonではlambda式で一行で書けるようですが、あえてこちらで記載します。)
fをWに関して微分して勾配を求めます。
ここで、高校数学程度の知識しかない私はこう思いました。
あれ、fをWに関して微分しても、Wが要素になってないから0なんじゃないか、と。
とりあえずこの疑問は置いておいて、本を読み進めていくと、どう考えても勾配を0として計算しているようには見えませんでした。
Wをどこかで関わらせているのかと思い、勾配を求める関数をちゃんと読んでみました。
# 実際に呼んでいるコード
# net.Wはネットワーククラスが持つ重みの値(クラスプロパティ)
dW = numerical_gradient(f, net.W)
def numerical_gradient(self, f, x):
h = 1e-4
grad = np.zeros_like(x)
it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
while not it.finished:
idx = it.multi_index
tmp_val = x[idx]
# ここでプロパティの値を上書きしている!
x[idx] = float(tmp_val) + h
fxh1 = f(x)
x[idx] = tmp_val - h
fxh2 = f(x)
grad[idx] = (fxh1 - fxh2) / (2*h)
# ここで元に戻している!
x[idx] = tmp_val
it.iternext()
return grad
つまり、重みパラメーターをクラスに持たせることで、微分式内で値を暫定的に書き換えて処理をさせています。恥ずかしながら、ここで引っかかり、いまいち以降の処理を理解できておりませんでした。
もし、こちらの本で勉強していて、同じような場所で詰まっているという方がいらっしゃれば、参考にしていただければ、と思います。
2017年1月28日土曜日
iOS SwiftでS3への画像アップロード
こんにちは、Hiroです。今回はSwiftでAWSのS3へ画像をアップロードする方法について、ブログを書きたいと思います。
AWS Cognitoでの認証が本来は望ましいのですが、今回は簡単にIAMユーザを作成し、ACCESS KEYとSECRET ACCESS KEYを利用した方法で紹介したいと思います。アプリをリリースする場合は、AWS Cognitoを利用するか、IAMユーザの場合は、アクセス権限を十分に絞ってください。
AWS上での準備については、省略しますが下記の2つを準備してください。IAMユーザについては、作成したS3のバケットへアップロード(PutObject)できる権限を付与しておく必要があります。
Podfileに下記を記載して、インストールします。
冒頭で記載したとおり、今回はIAMユーザでの認証を行います。accessKeyとsecretKeyにはAWSで作成したIAMユーザのものを設定してください。
下記の処理は、S3で画像などをアップロードする前に1度だけ実行するようにします。
S3へ投稿するファイルは、一時的に端末内に保存して、そのURLをS3のSDKに指定する必要があります。
下記のメソッドで、S3へのアップロードする画像が保存されているURLを取得できます。
下記のメソッドでS3へアップロードができます。下記のメソッドを呼ぶ前には、上記で記載している認証の設定を事前に実行する必要があります。
また、「uploadRequest?.bucket」にはAWS上で作成したバケット名を指定し、「uploadRequest?.key」にはS3上に保存したいファイル名を指定します。 なお、ファイル名は「test/hello.jpg」とするとAWSコンソールなどから見た際にtestフォルダ内にhello.jpgファイルが保存されているように見えるので、ファイルをまとめて管理したい場合には、「test/」などのプレフィックスをつけるとよいでしょう。
AWS Cognitoでの認証が本来は望ましいのですが、今回は簡単にIAMユーザを作成し、ACCESS KEYとSECRET ACCESS KEYを利用した方法で紹介したいと思います。アプリをリリースする場合は、AWS Cognitoを利用するか、IAMユーザの場合は、アクセス権限を十分に絞ってください。
AWS上での事前準備
AWS上での準備については、省略しますが下記の2つを準備してください。IAMユーザについては、作成したS3のバケットへアップロード(PutObject)できる権限を付与しておく必要があります。
- S3にバケットを作成
- IAMユーザの作成(上記のバケットへの「s3:PutObject」権限あり)
CocoaPodsでAWS SDKをインストールをする
Podfileに下記を記載して、インストールします。
use_frameworks!
pod 'AWSS3'
$ pod install
認証の設定をする
冒頭で記載したとおり、今回はIAMユーザでの認証を行います。accessKeyとsecretKeyにはAWSで作成したIAMユーザのものを設定してください。
下記の処理は、S3で画像などをアップロードする前に1度だけ実行するようにします。
import AWSCore
...
...
func configureService() {
let credentialsProvider = AWSStaticCredentialsProvider(accessKey: "your access key", secretKey: "your secret key")
let serviceConfiguration = AWSServiceConfiguration(region: AWSRegionType.apNortheast1, credentialsProvider: credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = serviceConfiguration
}
UIImageを保存して、URLを取得する
S3へ投稿するファイルは、一時的に端末内に保存して、そのURLをS3のSDKに指定する必要があります。
下記のメソッドで、S3へのアップロードする画像が保存されているURLを取得できます。
private func generateImageUrl(_ uploadImage: UIImage) -> URL {
let imageURL = URL(fileURLWithPath: NSTemporaryDirectory().appendingFormat("upload.jpg"))
if let jpegData = UIImageJPEGRepresentation(uploadImage, 80) {
try! jpegData.write(to: imageURL, options: [.atomicWrite])
}
return imageURL
}
S3へアップロードする
下記のメソッドでS3へアップロードができます。下記のメソッドを呼ぶ前には、上記で記載している認証の設定を事前に実行する必要があります。
また、「uploadRequest?.bucket」にはAWS上で作成したバケット名を指定し、「uploadRequest?.key」にはS3上に保存したいファイル名を指定します。 なお、ファイル名は「test/hello.jpg」とするとAWSコンソールなどから見た際にtestフォルダ内にhello.jpgファイルが保存されているように見えるので、ファイルをまとめて管理したい場合には、「test/」などのプレフィックスをつけるとよいでしょう。
import AWSS3
...
...
public func uploadImage(_ uploadImage: UIImage) {
let transferManager = AWSS3TransferManager.default()
let uploadRequest = AWSS3TransferManagerUploadRequest()
uploadRequest?.bucket = "your S3 bucket name"
uploadRequest?.key = "your file name on S3"
uploadRequest?.body = generateImageUrl(uploadImage)
transferManager?.upload(uploadRequest).continue({ (task: AWSTask) -> Any? in
if task.error != nil || task.exception != nil {
// エラー
}
return nil
})
}
2017年1月27日金曜日
Swift3でDateからその月の月末のDateを取得
こんにちはonukiです。
今回はSwift3でDateの月末が何日か取得したかったので
備忘録がてら、私が行った方法を紹介したいと思います。
上記では現在日時からDateを作成し、その月の月末にしてるので
例えば2017年1月に実行した場合下記のフォーマットで整形しprintすると「20170131」になります。
今回はSwift3でDateの月末が何日か取得したかったので
備忘録がてら、私が行った方法を紹介したいと思います。
実装
var date = Date()
let calendar = NSCalendar(identifier: NSCalendar.Identifier.gregorian)!
// 年月日時分秒のNSComponents
var comp = calendar.components([.year, .month, .day, .hour, .minute, .second], from: date as Date)
// 月初の0時0分0秒に設定
comp.day = 1
comp.hour = 0
comp.minute = 0
comp.second = 0
// ここでcalendar.date(from: comp)!すれば月初のDateが取得できます
// その月が何日あるかを計算します
let range = calendar.range(of: .day, in: .month, for: date as Date)
let lastDay = range.length
// ここで月末の日に変えます
comp.day = lastDay
// Dateを作成
let retDate = calendar.date(from: comp)!
上記では現在日時からDateを作成し、その月の月末にしてるので
例えば2017年1月に実行した場合下記のフォーマットで整形しprintすると「20170131」になります。
let formatter = DateFormatter()
formatter.dateFormat = "yyyyMMdd"
let dateStr: String = formatter.string(from: retDate as Date)
print(dateStr)
2017年1月26日木曜日
はじめの一歩 -Rails ActiveRecord編- SELECT4
どうも、はじめです。
前回はJOINについて書いてみました。
はじめの一歩 -Rails ActiveRecord編- SELECT3
今回も引き続きJOINに関する内容ですが、JOINでも3つ以上のテーブルの結合について書いていこうと思います。
はじめに
3つ以上のテーブルの結合なので、結合できるテーブルを3つ用意します。
usersテーブル
[id: 1, user_name: 'Aさん'],
[id: 2, user_name: 'Bさん'],
[Id: 3, user_name: 'Cさん']
itemsテーブル
[id: 1, item_name: 'Rubyの本'],
[id: 2, item_name: 'Railsの本'],
[id: 3, item_name: 'PHPの本']
user_itemsテーブル(userが持っているitemを管理するテーブル)
[id: 1, user_id: 1, item_id: 1],
[id: 2, user_id: 1, item_id: 2],
[id: 3, user_id: 2, item_id: 3]
関連を説明すると以下のようになります。
user : user_item => 1 : n
item : user_item => 1 : n
それでは前回使用したincludesを使用して書いていこうと思います。
取得
・Aさんが持っているアイテムを全て取得したい場合
user_items = User.includes(user_items: :item).find(1)
上記のように記述することで以下のようなSQLが実行されます。
SELECT `users`.* FROM `users` WHERE `users`.`id` = 1;
SELECT `user_items`.* FROM `user_items` WHERE `user_items`.`id` in (1,2);
SELECT `items`.* FROM `items` WHERE `items`.`id` in (1,2);
joinsの場合も同様の書き方となります。
表示
アイテム名を表示したい場合は以下のようにします。
user_items.user_items.each do |user_item|
p user_item.item.item_name
end
# => 'Rubyの本'
# => 'Railsの本'
さらにテーブルが増えた場合
itemsにcategoryテーブルを関連付けして色々なパターンで取得をしてみたいと思います。
以下のような関連性でitemsに対し、categoriesテーブルを作成します。
items : category => n : 1
itemsテーブル
[id: 1, item_name: 'Rubyの本', category_id: 1],
[id: 2, item_name: 'Railsの本', category_id: 1],
[id: 3, item_name: 'PHPの本', category_id: 2]
categoriesテーブル
[id: 1, category_name: 'Ruby'],
[id: 2, category_name: 'PHP']
パターン1
・Aさんが持っているアイテムのカテゴリーまで取得したい場合
User.includes(user_items: {item: :category}).find(1)
パターン2
・"Rubyの本"のカテゴリーと持っているユーザーを取得したい場合
Item.includes(:category, {user_items: :user}).find(1)
まとめ
以下のような関連性だった場合
a:b:c => 1:n:1
c:d =>n:1
隣接しているテーブルを複数結合したい場合はのように「,」でつなげることができます。
B.includes(:a, :c)
二つ隣のテーブルの情報を取得する場合は「:」を向かい合わせに記述をします。A.includes(b: :c)
さらに深いテーブルの情報を取得する場合は{}を使用しますA.includes(b: {c: :d})
前回も記述をしたように
3つ以上のテーブルを結合する場合でもテーブル名は
複数系、単数系を意識しなければいけませんので注意してください。
以上でSELECT系(JOIN系)を終了し、
次回からはUPDATEに入ろうと思います。
2017年1月25日水曜日
360度カメラ買いました
どうもー。デザイナーのnottyです。
今年から、NowDevelopingに参加しました。どうぞお見知り置きを 〜
さて、話は変わりまして、最近360度カメラを購入しました。※この記事は360度カメラの模索中のメモです
購入した経緯
正直、まだまだVRが普及するとは思えませんが、360度カメラはWebでコンテンツを見るときに全体の雰囲気や様子を掴めるので使いどころによっては、効果があると思います。(旅行先,不動産,水族館,フェス,山頂,クラブetx...)
今年から、NowDevelopingに参加しました。どうぞお見知り置きを 〜
さて、話は変わりまして、最近360度カメラを購入しました。※この記事は360度カメラの模索中のメモです
THETA SC という機種です。
購入した経緯
正直、何も考えずに買いました。
だから使い道を探るため毎日持ち歩き、撮影しています。
自分の顔やいろんな人の顔が映ってしまうので、公式からですが、
こんな感じの写真が撮れます。
こんな感じの写真が撮れます。
撮った後、写真を見るのが楽しくなるプロダクトです。
技術的に相性が良いのはVRに当たるのかな?
360度カメラのコンテンツはまだまだ面白いのが生まれると感じています。
みたいなWebVRフレームワークが登場したり(2015年で古いですが...)
VRの空間?に絵を描いたり(これ半端ないす)
2017年となった今では情報がたくさんあって、デバイスの性能も良くなったので、利用する人、モノ作りする人は、VRへの参入障壁が低くなったと思います。
今年はVRコンテンツが増えるのか
正直、まだまだVRが普及するとは思えませんが、360度カメラはWebでコンテンツを見るときに全体の雰囲気や様子を掴めるので使いどころによっては、効果があると思います。(旅行先,不動産,水族館,フェス,山頂,クラブetx...)
世の中にあったコンテンツを提供できるように、先回りして技術を知っておく事によって、タイミング良く出せると思います。
今年は研究も兼ねて360×◯◯のようなコンテンツに挑戦します。
_以上
2017年1月24日火曜日
macOS SierraにDocker for Macをインストールしてみる
こんにちは、h_ono_222です。
今回はmacOS SierraにDocker for Macをインストールしてみました。
・OS X El Capitan 10.11以降のOS(10.10.3 Yosemiteは限定的にサポート)
・4GB以上のRAM
・version 4.3.30より前のVirtualBoxがインストールされていないこと
無事にnginxが起動しました。
今回は以上です。
今回はmacOS SierraにDocker for Macをインストールしてみました。
要求スペック
・2010年以降に製造されたMac・OS X El Capitan 10.11以降のOS(10.10.3 Yosemiteは限定的にサポート)
・4GB以上のRAM
・version 4.3.30より前のVirtualBoxがインストールされていないこと
1. Docker for Macのインストール
下記のサイトにアクセスし、Get Docker for Mac[stable]をクリックしてDocker.dmgをダウンロードします。
https://docs.docker.com/docker-for-mac/
Docker.dmgをダブルクリックし、表示されたFinderのDockerアイコンをApplicationsにドラッグ&ドロップします。
Dockerが起動し、メニューバーにDockerのアイコンが表示されます。
Terminalを起動し、Docker commandを入力してみます。
https://docs.docker.com/docker-for-mac/
Docker.dmgをダブルクリックし、表示されたFinderのDockerアイコンをApplicationsにドラッグ&ドロップします。
2. Dockerを起動する
Dockerをダブルクリックするとポップアップが表示されるのでOKを選択し、自分のMacにログインする際のパスワードを入力します。Dockerが起動し、メニューバーにDockerのアイコンが表示されます。
Terminalを起動し、Docker commandを入力してみます。
Users-MacBook-Pro:Desktop User$ docker version
Client:
Version: 1.13.0
API version: 1.25
Go version: go1.7.3
Git commit: 49bf474
Built: Wed Jan 18 16:20:26 2017
OS/Arch: darwin/amd64
Server:
Version: 1.13.0
API version: 1.25 (minimum version 1.12)
Go version: go1.7.3
Git commit: 49bf474
Built: Wed Jan 18 16:20:26 2017
OS/Arch: linux/amd64
Experimental: true
3. サーバを起動する
Users-MacBook-Pro:Desktop user$ docker run -d -p 80:80 --name webserver nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
5040bd298390: Pull complete
d7a91cdb22f0: Pull complete
9cac4850e5df: Pull complete
Digest: sha256:33ff28a2763feccc1e1071a97960b7fef714d6e17e2d0ff573b74825d0049303
Status: Downloaded newer image for nginx:latest
61a7880cc6d001376f222cb3214c457c3d625720a5111a72dba14415a0d2d40f
無事にnginxが起動しました。
今回は以上です。
2017年1月23日月曜日
配牌からあがれる可能性を予測する!(その3 学習の実装)
前回の記事はこちらです。
配牌からあがれる可能性を予測する!(その2 教師データの作成)
配牌からあがれる可能性を予測する!(その2 教師データの作成)
前回の訂正
CSVファイルからの読み込み時、String型になってしまうので、Int型にキャストしなければなりませんでした。
差分はこちらになりますが、その中でリスト内包記述というfor文を1行で書くように修正しております。
差分はこちらになりますが、その中でリスト内包記述というfor文を1行で書くように修正しております。
# 修正前
tmp_hand = []
for tile in range(0, 12):
tmp_hand.append(row[tile])
# 修正後
tmp_hand = [int(tile) for tile in row]
学習の実装開始
今回より学習機能をつけていきたいと思います。
基本的には、「ゼロから作るディープラーニング」の手順で論理を進めています。
(誤差を求め、その誤差の微分値からパラメータを求める。)
ソースコードはこちらになります。
https://github.com/naoki85/python_mahjong
基本的には、「ゼロから作るディープラーニング」の手順で論理を進めています。
(誤差を求め、その誤差の微分値からパラメータを求める。)
ソースコードはこちらになります。
https://github.com/naoki85/python_mahjong
matplotlib について
その前に、グラフを描画する便利ライブラリであるmatplotlibの準備をしておきます。
まだそこまで複雑なグラフはいらないので、基本的な書き方で大丈夫そうです。
今回はX軸はループの回数、Yは誤差(教師データとの誤差とします。)
まだそこまで複雑なグラフはいらないので、基本的な書き方で大丈夫そうです。
今回はX軸はループの回数、Yは誤差(教師データとの誤差とします。)
# xの値を1ずつ定義
x = range(0, 100)
# ループごとに誤差を格納しておく
y = loss_array
plt.xlabel("x")
plt.ylabel("loss")
plt.plot(x, y)
plt.show()
ためしに作ってみた図はこちらです。
ループ回数を重ねるごとに、誤差がちいさくなっていることが分かります。
ただし、こちらの正当性はまだ確認できていないので、実際に次回は学習後の重み、バイアスを使用してテストしてみます。
ただし、こちらの正当性はまだ確認できていないので、実際に次回は学習後の重み、バイアスを使用してテストしてみます。
学習結果の保存について(pickleモジュール)
学習結果はpickle形式で保存しました。
pickleは「漬物」という意味で、オブジェクトをそのまま保存してくれます。(ピクルスのことか、と覚えました。)
はじめはCSV形式にしようと思ったのですが、いちいち分解して保存するのも、取り出すときに再度辞書型にするのも面倒です。
例えば、下記の結果を保存するとします。
pickleは「漬物」という意味で、オブジェクトをそのまま保存してくれます。(ピクルスのことか、と覚えました。)
はじめはCSV形式にしようと思ったのですが、いちいち分解して保存するのも、取り出すときに再度辞書型にするのも面倒です。
例えば、下記の結果を保存するとします。
{'W': [1, 2, 3], 'b': [4, 5]}
これを特に前処理なしで下記のように保存(漬物)にしてしまいます。(基本的なファイルの読み書きと同じ感じです。)with open(pickle_filepath, 'wb') as f:
writer = pickle.dump(results, f)
取り出すときも下記のようにかけば、なんとびっくりそのまま取り出せます。with open(pickle_filepath, 'rb') as f:
params = pickle.load(f)
{'W': [1, 2, 3], 'b': [4, 5]}
そのため、重み、バイアスの値は教師データとは異なりpickleで管理することとしました。
おわりに
まだ私自身、微分して最適な重みを求める「勾配法」について、 腑に落ちていないところがあるので、
そちらを理解して、実装を踏まえて書きたいと思います。
そちらを理解して、実装を踏まえて書きたいと思います。
2017年1月21日土曜日
配牌からあがれる可能性を予測する!(その2 教師データの作成)
こんにちは、Taroです。
前回の記事の記事の続きになります。
配牌からあがれる可能性を予測する!(その1 推論処理)
次回は学習を実装する、と記載しましたが、その前に教師データを取得する方法を実装したいと思います。
今回はDeep LearningというよりはPythonの勉強といった感じです。
前回の記事の記事の続きになります。
配牌からあがれる可能性を予測する!(その1 推論処理)
次回は学習を実装する、と記載しましたが、その前に教師データを取得する方法を実装したいと思います。
今回はDeep LearningというよりはPythonの勉強といった感じです。
教師データの選定
麻雀のようなギャンブルにおいて、教師になるデータは何なのか?
考え出すとキリがなさそうなので、ひとまずプロの対局からデータを作成しました。
プロであれば、(もちろん技術や個性、状況で異なってくるとは思いますが)あがりやすい配牌は必ず仕上げてくれるはずです。
そのため、Youtubeでプロの対局を見続けました(ある種これが苦行かもしれません笑)。
余談ですが、個人的に好きなプロ雀士は土田浩翔プロです。
考え出すとキリがなさそうなので、ひとまずプロの対局からデータを作成しました。
プロであれば、(もちろん技術や個性、状況で異なってくるとは思いますが)あがりやすい配牌は必ず仕上げてくれるはずです。
そのため、Youtubeでプロの対局を見続けました(ある種これが苦行かもしれません笑)。
余談ですが、個人的に好きなプロ雀士は土田浩翔プロです。
CSVファイルの作成
教師データはCSVファイルにまとめます。
今回必要なデータは、 配牌 と 結果 なので、下記のようにまとめました。
今回必要なデータは、 配牌 と 結果 なので、下記のようにまとめました。
| tile_1 | tile_2 | tile_3 | tile_4 | tile_5 | tile_6 | tile_7 | tile_8 | tile_9 | tile_10 | tile_11 | tile_12 | tile_13 | win | loss |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 11 | 13 | 17 | 21 | 25 | 27 | 29 | 31 | 31 | 31 | 35 | 43 | 47 | 1 | 0 |
このデータを読み込んでいきたいと思います。
CSVファイルの読み込み
Pythonの
(というよりこれくらいしか分からない。。。)
csvモジュールを利用して簡単に実装します。(というよりこれくらいしか分からない。。。)
def load_trainig_data(self):
u"""
CSVファイルから教師データを読み込み、データを返します。
@return array
[0]で教師データの配牌、[1]で結果を返します
"""
with open('csv/training_data.csv', 'r', newline='') as csvfile:
reader = csv.reader(csvfile)
header = next(reader)
hand = []
results = []
for row in reader:
tmp_hand = []
for tile in range(0, 12):
tmp_hand.append(row[tile])
results.append([row[13], row[14]])
hand.append(tmp_hand)
return hand, results
このメソッドをMyHandクラスに追加しました。
from my_hand import *
my_hand = MyHand()
input_data, results = my_hand.load_trainig_data()
print(input_data)
[['47', '26', '17', '21', '47', '12', '42', '43', '34', '15', '45', '37'], ['42', '42', '41', '17', '39', '21', '39', '15', '37', '11', '11', '21'], ['47', '35', '22', '22', '23', '26', '12', '13', '17', '18', '39', '38'], ['22', '24', '24', '25', '28', '31', '32', '33', '13', '13', '14', '16'], ['41', '47', '31', '12', '29', '18', '45', '34', '19', '22', '18', '39'], ['46', '15', '15', '16', '16', '47', '45', '11', '43', '32', '34', '27'], ['41', '41', '43', '44', '44', '17', '14', '13', '13', '23', '23', '33'], ['35', '38', '39', '39', '23', '25', '26', '27', '28', '16', '42', '42'], ['45', '47', '39', '44', '43', '21', '36', '27', '13', '32', '39', '16'], ['21', '28', '32', '35', '21', '23', '35', '12', '18', '37', '45', '14'], ['12', '14', '15', '17', '41', '44', '34', '35', '22', '23', '23', '26'], ['24', '24', '29', '31', '32', '36', '37', '38', '39', '13', '17', '47']]
print(results)
[['0', '1'], ['1', '0'], ['0', '1'], ['0', '1'], ['0', '1'], ['0', '1'], ['1', '0'], ['0', '0'], ['1', '0'], ['0', '0'], ['0', '0'], ['0', '0']]
これだとちょっと分かりづらいので、1つ目の要素だけ抜き出します。
print(input_data[0])
['47', '26', '17', '21', '47', '12', '42', '43', '34', '15', '45', '37']
print(results)
['0', '1']
これで、教師データが読み込めました。
(これで正しいのかは置いておきます笑)
(これで正しいのかは置いておきます笑)
Jupyter Notebookで書いてみたよ!
Jupyterという単語は見たことがあったのですが、ずっとライブラリの1つだと思っていました笑。
実はエディタのようで、データサイエンティストの人などが、実際に実行したプログラムを確認しながら文章を書いたりするもののようです。
Anacondaをインストールすると一緒についてきます。
詳しいことは諸先輩方が記述しておりますので、割愛しますが、本記事も下図のように書きました。
実はエディタのようで、データサイエンティストの人などが、実際に実行したプログラムを確認しながら文章を書いたりするもののようです。
Anacondaをインストールすると一緒についてきます。
詳しいことは諸先輩方が記述しておりますので、割愛しますが、本記事も下図のように書きました。
プロジェクト上に配置しておけば、自作のコードも読み込んで実行してくれます。
Python以外の言語もサポートしているようなので、コードと実行結果をブログにのせたいときは使用を検討しても良いのではないでしょうか?
Python以外の言語もサポートしているようなので、コードと実行結果をブログにのせたいときは使用を検討しても良いのではないでしょうか?
2017.01.21 追記
何も考えずに、Jupyterが生成してくれたソースコードを貼り付けたら、Google bloggerのCSSなどを上書きしてしまったようで、不都合が生じました。
急いで書き直したので、結局普通になってしまいました。。。笑
ブログなどに貼り付けるときは事前に検討が必要です。
急いで書き直したので、結局普通になってしまいました。。。笑
ブログなどに貼り付けるときは事前に検討が必要です。
おわりに
今回のソースコードは下記になります。
Jupyter Notebookで作成したファイルは.ipynb拡張子で保存されています。
https://github.com/naoki85/python_mahjong
次回は、今度こそ学習ロジックの実装をしたいと思います!
Jupyter Notebookで作成したファイルは.ipynb拡張子で保存されています。
https://github.com/naoki85/python_mahjong
次回は、今度こそ学習ロジックの実装をしたいと思います!
第3回書きました!
配牌からあがれる可能性を予測する!(その3 学習の実装)
配牌からあがれる可能性を予測する!(その3 学習の実装)
2017年1月20日金曜日
Swift3でTTTAttributedLabelの文字列からリンク表示をやってみた
こんにちはonukiです。
今回はTTTAttributedLabelを使用し、
文字列からリンクを表示、リンクタップ制御を
Swiftでの実装方法を書いてこうと思います。
今回はTTTAttributedLabelを使用し、
文字列からリンクを表示、リンクタップ制御を
Swiftでの実装方法を書いてこうと思います。
TTTAttributedLabelとは
リッチなテキストを表示するためのUILabelの機能を拡張するOSSです。
その機能の一つに文字列からリンクを検出してくれる機能があるので
今回は主にその部分の実装についてになります。
準備
インストールにはCocoaPodsを使用します。
pod 'TTTAttributedLabel'
それと、TTTAttributedLabelはObjective-Cで書かれているので
Bridging-Header.hにimportしてください。
#import <TTTAttributedLabel/TTTAttributedLabel.h>
実装
まずはTTTAttributedLabelをimportします
import TTTAttributedLabel
StoryboardにUILabelを適当に用意し
ClassにTTTAttributedLabelを指定してください。
それをIBOutlet接続します。
@IBOutlet weak var linkLabel: TTTAttributedLabel!
テキストのリンクをタップできるように設定します。
linkLabel.enabledTextCheckingTypes = NSTextCheckingResult.CheckingType.link.rawValue
リンクを含むテキストをセットします。
linkLabel.text = "URLにタップできます。\nhttps://www.google.co.jp/"
そうするとこのような表示になります。
このままだとタップが検知できないので
TTTAttributedLabelDelegateを設定します。
class ViewController: UIViewController, TTTAttributedLabelDelegate {
TTTAttributedLabelのDelegateを設定します。
linkLabel.delegate = self
テキスト内のリンクがタップされた場合、以下のメソッドが呼ばれます。
func attributedLabel(_ label: TTTAttributedLabel!, didSelectLinkWith url: URL!) {
//処理
}
これで、文字列からリンクを表示、リンクタップ制御ができたと思います。
登録:
投稿 (Atom)






