Lambda on PythonでOpenCVライブラリを使う
AWS S3(以下、S3)に画像ファイルをアップロードした際、
AWS Lambda(以下、Lambda)で画像加工を行う、というのは
よく使われるケースの一つかと思います。
そこで、Lambda on Python 2.7でOpenCVライブラリを使用するための手順について、ご紹介したいと思います。
AWS S3(以下、S3)に画像ファイルをアップロードした際、
AWS Lambda(以下、Lambda)で画像加工を行う、というのは
よく使われるケースの一つかと思います。
そこで、Lambda on Python 2.7でOpenCVライブラリを使用するための手順について、ご紹介したいと思います。
AWS Fargate(以下Fargate)は、
AWSが提供するコンテナ実行サービスであるElastic Container Service (以下ECS)のサービスの一種です。
バージニア北部のリージョンでのみ提供されていたサービスですが、
ついに、2018年07月東京リージョンでも提供が開始されました!!
既存のECSの仕組みが、ユーザが管理するEC2のクラスタの上でコンテナが起動されるのに対し、
FargateはEC2の管理をする必要がなく、コンテナが使用するvCPU、メモリを指定するだけでコンテナを実行できます。
冒頭でECSのサービスの一種です、という言い方をしましたが、
基本的には、ECSの仕組みと同じように動作します。
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
セイバープラグイン、ライトセイバーのようなエフェクト他パチンコとかによくあるオーラ系の演出で使われるエフェクトが簡単に作れます
https://www.flashbackj.com/video_copilot/saber/
Color Vibrance、真っ白や真っ黒な画像でも色相や彩度を自在に補正かけることができます。
https://www.flashbackj.com/video_copilot/free_plugin/
サンプルとしてカグヅチさんに燃えていただきました
ざっくりですが手順としましては
1AfterEffectsにエフェクトつけたい画像を読み込む
2レイヤー→オートトレースでキャラとかエフェクトをつけたい物の型のパスを取る
3オートトレースしたレイヤーにエフェクトからセイバーを選択。今回はカグヅチなので火をベースにするためPresetはInfernoを元に適当に数値いじります(この辺は個人差あるので適当にいじってもらった方が楽しいかもです)
Customize Coreの項目にあるCore typeをLayer Maskにするとエフェクトがトレースしたパスに沿ってオーラをまとった感じになります
そのままだとリアルなエフェクトになるのでキャラの雰囲気に合わせて
ポスタリゼーション、ブラー(詳細)、カートゥーンのエフェクトを入れていい感じに調整したら
VC Color Vibranceで好みの色味に調整します。
これは別にサンプルなんで適当にざっくりやっちゃってますがもう少し細かく数値設定してあげればもう少し面白く仕上がるかなと思います。
ちなみにセイバープラグインはAfterEffectsの最新バージョンだと対応していないため要注意です
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
VirtualBox 上で CentOS や Ubuntu を起動させ、 Samba でファイル共有
sudo yum install -y samba
sudo chmod 755 /home/$USER
sudo smbpasswd -a $USER
sudo cp -a /etc/samba/smb.conf /etc/samba/smb.conf.org
sudo vi /etc/samba/smb.conf # 編集方法は以下参照
sudo /etc/rc.d/init.d/smb start
sudo /etc/rc.d/init.d/nmb start
sudo chkconfig smb on
sudo chkconfig nmb on
sudo setsebool -P samba_export_all_rw 1
sudo /etc/rc.d/init.d/iptables stop
sudo chkconfig iptables off
sudo chkconfig ip6tables off
58 ### START ###
59 unix charset = UTF-8
60 dos charset = CP932
61 display charset = UTF-8
62 ### END ###
79 ### START ###
80 # workgroup = MYGROUP
81 workgroup = WORKGROUP
82 ### END ###
89 ### START ###
90 hosts allow = 127.0.0.1 10. 172.16. 192.168.
91 ### END ###
232 ### START ###
233 # load printers = yes
234 load printers = no
235 disable spoolss = yes
236 ### END ###
267 ### START ###
268 create mask = 644
269 directory mask = 755
270 ### END ###
sudo yum install -y samba
sudo chmod 755 /home/$USER
sudo smbpasswd -a $USER
sudo cp -a /etc/samba/smb.conf /etc/samba/smb.conf.org
sudo cp /etc/samba/smb.conf.example /etc/samba/smb.conf
sudo vi /etc/samba/smb.conf # 編集方法は以下参照
sudo systemctl enable smb.service
sudo systemctl enable nmb.service
sudo systemctl restart smb.service
sudo systemctl restart nmb.service
sudo setsebool -P samba_export_all_rw 1
sudo systemctl stop firewalld
差分が以下のようになるよう修正する
[admin@localhost ~]$ diff -uprN /etc/samba/smb.conf.example /etc/samba/smb.conf
--- /etc/samba/smb.conf.example 2017-11-28 01:21:52.000000000 +0900
+++ /etc/samba/smb.conf 2018-05-02 20:50:00.157765018 +0900
@@ -60,6 +60,9 @@
#======================= Global Settings =====================================
[global]
+unix charset = UTF-8
+dos charset = CP932
+display charset = UTF-8
# ----------------------- Network-Related Options -------------------------
#
@@ -81,13 +84,13 @@
# hosts deny = the hosts not allowed to connect. This option can also be used on
# a per-share basis.
#
- workgroup = MYGROUP
+ workgroup = WORKGROUP
server string = Samba Server Version %v
; netbios name = MYSERVER
; interfaces = lo eth0 192.168.12.2/24 192.168.13.2/24
-; hosts allow = 127. 192.168.12. 192.168.13.
+ hosts allow = 127.0.0.1 10. 172.16. 192.168.
# --------------------------- Logging Options -----------------------------
#
@@ -244,7 +247,8 @@
# printcap name = used to specify an alternative printcap file.
#
- load printers = yes
+ load printers = no
+ disable spoolss = yes
cups options = raw
; printcap name = /etc/printcap
@@ -278,6 +282,8 @@
writable = yes
; valid users = %S
; valid users = MYDOMAIN\%S
+ create mask = 644
+ directory mask = 755
[printers]
comment = All Printers
sudo apt-get install -y samba
sudo pdbedit -a $USER
sudo cp -a /etc/samba/smb.conf /etc/samba/smb.conf.org
sudo vi /etc/samba/smb.conf # 以下参照
sudo systemctl restart smbd
sudo systemctl restart nmbd
差分が以下のようになるよう修正する
$ diff -uprN /etc/samba/smb.conf.org /etc/samba/smb.conf
--- /etc/samba/smb.conf.org 2018-05-02 18:16:25.567600455 +0900
+++ /etc/samba/smb.conf 2018-05-02 18:20:40.762445925 +0900
@@ -190,13 +190,13 @@
# Un-comment the following (and tweak the other settings below to suit)
# to enable the default home directory shares. This will share each
# user's home directory as \\server\username
-;[homes]
-; comment = Home Directories
-; browseable = no
+[homes]
+ comment = Home Directories
+ browseable = no
# By default, the home directories are exported read-only. Change the
# next parameter to 'no' if you want to be able to write to them.
-; read only = yes
+ read only = no
# File creation mask is set to 0700 for security reasons. If you want to
# create files with group=rw permissions, set next parameter to 0775.
@@ -211,7 +211,7 @@
# Un-comment the following parameter to make sure that only "username"
# can connect to \\server\username
# This might need tweaking when using external authentication schemes
-; valid users = %S
+ valid users = %S
# Un-comment the following and create the netlogon directory for Domain Logons
# (you need to configure Samba to act as a domain controller too.)
sudo ufw allow 137
sudo ufw allow 138
sudo ufw allow 139
sudo ufw allow 445
sudo ufw default ALLOW
sudo apt-get install -y cifs-utils
sudo mkdir /mnt/XXX
※「XXX」は任意
sudo mount.cifs //AAA.AAA.AAA.AAA/BBB /mnt/XXX/ -o username=BBB,uid=$(id -u),gid=$(id -g)
AAA : サーバIP
BBB : サーバ側のユーザ名
sudo umount /mnt/XXX
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
今年に入って花粉症を発症し、症状がひどくストレスに満ちた生活を送っているBe82Mです。
集中力が散漫になりがちで困っているので、今回軽減するために必要なことをまとめてみました。
どの病気にも言えることですが、睡眠をしっかりとって免疫力を高めることが大切です。
また、帰ってきたときに服を軽く叩くなど極力家に花粉を持ち込まないようにし、こまめに部屋の掃除を行いましょう。
外出した日は特に体に付着した花粉を洗い流すため、朝シャンは避けて寝る前に入る方がいいそうです。
外出の必要がない日は無闇に外出せず、花粉を必要以上に吸引しないように心がけましょう。
ストレスも免疫を低めてしまう原因になっているので、極力ストレスは趣味や適度な運動を行うことで発散するようにしましょう。
花粉症の症状がひどくなると、なかなか寝付けなかったり、普段の生活でも花粉症の症状だけで大きなストレスになってしまい、悪循環になってしまいます。
症状はすぐに軽減できないので、他のストレスとなる要因を絶ったり、どうしようもない場合は発散する時間を作るように心がけましょう。
アルコールは血管を拡張させるため、目の充血や鼻づまりを引き起こしてしまう要因となるようです。
また、粘膜を乾燥させてしまうため体内への花粉の侵入を防ぎにくくなってしまいます。
加湿器などを使って空気の乾燥を防ぐことで粘膜の乾燥も防ぐことは可能ですが、水分補給を行うなど内部からも水分を補うように心がけましょう。
煙が鼻の粘膜を刺激することで、鼻づまりなど症状を悪化させてしまうようです。
そのため喫煙者の近くにいるだけでも症状悪化の原因となってしまいます。
しかし、タバコに含まれるニコチンは血管を収縮させる作用があり、症状が軽減される要素も含んでいます。
粘膜の乾燥を防ぎ、煙によって症状を引き起こさないように対策しつつ、周囲に気を遣って喫煙をすれば特に問題はないかもしれません。
先々月に奥多摩町に遊びに行ったことを激しく後悔しています。とても楽しかったですが、あれから本当に症状がひどくなり、その後数日まで症状がひどい状態が続きました。
興味本位で1平方センチメートルあたりの花粉飛散量を調べましたが、23区内の平均が40〜50個なのに対し、奥多摩町は6000個を超えているそうです…。
確かに辺りは靄のようになっているし、1時間足らずで車が緑色になってしまうくらい目に見えて飛散量が違いました。
必要以上に対策したにも関わらず、目は真っ赤で涙がボロボロ出るし、くしゃみは止まらない…普段よりひどい症状に苦しめられる結果になりました。
景観はいいし、車やバイクで走るにもトレッキングにも最適。また、わらび餅が美味しいことで有名で魅力多い町ですが、花粉症を発症してしまったり、既に発症している人は症状悪化に繋がってしまいます。
観光に行こうと思っていた方は時期をずらして行くことをおすすめします。
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢
みなさーん! 快適Railsライフ送ってますかー!!?? 私は快適ではありません……。先日も訳の分からないエラーに引っかかって四苦八苦しました……。
メモ化という事柄に関してです。
メモ化って便利だよなー。マスタを一々データベースから参照せずに取ってこれるから高速に取ってこれるんだぜ!
使いやすいgemもあるし。
/app/models/oden_master.rb
class OdenMaster < ActiveRecord::Base
extend Memoist
class << self
def oden_data_memo(oden_code)
find_by(code: oden_code)
end
memoize :oden_data_memo
end
end
こんな感じにしちゃえば、同じ名前のおでんマスタは1度参照して来てしまえばキャッシュされるからもうSQLを呼ばずに取って来れる!
某日:
くらいあんと「おでん情報にユーザーの好みくっつけて送ってくれない?」
ぼく「わかりました!」
ぼく「うーん、どうしようかな。インスタンスに属性付けちゃえば楽だな」
/app/models/oden_master.rb
class OdenMaster < ActiveRecord::Base
extend Memoist
attr_accessor :preference_data
class << self
def oden_data_memo(oden_code)
find_by(code: oden_code)
end
memoize :oden_data_memo
end
def set_user_preference_data(user_data)
self.preference_data = user_data
end
end
で、コントローラはこんな感じにして、後はviewをいい感じに作れば完了!(結構簡略化してます)
app/controllers/oden_controller.rb
def current_oden
user = User.find_by(code: params[:user_code])
raise InvalidUser unless user
oden_code = params[:oden_code]
@oden_master = OdenMaster.oden_data_memo(oden_code)
raise InvalidOden unless oden_master
user_oden_data = user.oden_preferences.find_by(oden_code: oden_code)
@oden_master.set_user_preference_data(user_oden_data) if user_oden_data
end
end
テストも簡単に作って、通ったし問題無いな! メモ化して一度呼んできたマスタはもう取ってきてあるし、大丈夫!
コミットしてマージしてプッシュして開発環境にデプロイして(要するにクライアントが開発環境で試せる環境を作る)。
くらいあんと「大丈夫そうですね」
ぼく「お仕事完了!」
……しかしこのコードには致命的なミスがあるのがまだ、この時点では分からなかった。
数日後
てすたー「なんか別のユーザーのデータ入ってきてるよ」
ぼく「えっ」
ぼく「なんでだろう……。コンソール上で実際に動かしても何の問題も無いし……。うーん、うーん……」
てすたー「まだ、このおでんマスタに対するおでんデータ作ってないのに、入っちゃってるんだよね。それに私、こんなに辛子を大根に付けないんですよ」
ぼく「そうですか……。何でだろう。因みに私はたっぷり付けてゲホゲホ言いながら食べるのが好きです。」
てすたー「変態かよ。まあ、おでんデータ入れればちゃんと自分の入ってくるんだけど」
ぼく「むせる感覚が最高なんですよ。なんでこんな短いコードでそんな事が起きるんだろうなぁ……。調べてみます」
多分悩んだのは30分~1時間位だった。
問題は、memoizeをちゃんと読み込んでいなかった事にありました。
以下が、memoizeのソースになります。
def memoize(*method_names)
if method_names.last.is_a?(Hash)
identifier = method_names.pop[:identifier]
end
method_names.each do |method_name|
unmemoized_method = Memoist.unmemoized_method_for(method_name, identifier)
memoized_ivar = Memoist.memoized_ivar_for(method_name, identifier)
Memoist.memoist_eval(self) do
include InstanceMethods
if method_defined?(unmemoized_method)
warn "Already memoized #{method_name}"
return
end
alias_method unmemoized_method, method_name
if instance_method(method_name).arity == 0
# define a method like this;
# def mime_type(reload=true)
# skip_cache = reload || !instance_variable_defined?("@_memoized_mime_type")
# set_cache = skip_cache && !frozen?
#
# if skip_cache
# value = _unmemoized_mime_type
# else
# value = @_memoized_mime_type
# end
#
# if set_cache
# @_memoized_mime_type = value
# end
#
# value
# end
module_eval <<-EOS, __FILE__, __LINE__ + 1
def #{method_name}(reload = false)
skip_cache = reload || !instance_variable_defined?("#{memoized_ivar}")
set_cache = skip_cache && !frozen?
if skip_cache
value = #{unmemoized_method}
else
value = #{memoized_ivar}
end
if set_cache
#{memoized_ivar} = value
end
value
end
EOS
else
# define a method like this;
# def mime_type(*args)
# reload = Memoist.extract_reload!(method(:_unmemoized_mime_type), args)
#
# skip_cache = reload || !memoized_with_args?(:mime_type, args)
# set_cache = skip_cache && !frozen
#
# if skip_cache
# value = _unmemoized_mime_type(*args)
# else
# value = @_memoized_mime_type[args]
# end
#
# if set_cache
# @_memoized_mime_type ||= {}
# @_memoized_mime_type[args] = value
# end
#
# value
# end
module_eval <<-EOS, __FILE__, __LINE__ + 1
def #{method_name}(*args)
reload = Memoist.extract_reload!(method(#{unmemoized_method.inspect}), args)
skip_cache = reload || !(instance_variable_defined?(#{memoized_ivar.inspect}) && #{memoized_ivar} && #{memoized_ivar}.has_key?(args))
set_cache = skip_cache && !frozen?
if skip_cache
value = #{unmemoized_method}(*args)
else
value = #{memoized_ivar}[args]
end
if set_cache
#{memoized_ivar} ||= {}
#{memoized_ivar}[args] = value
end
value
end
EOS
end
if private_method_defined?(unmemoized_method)
private method_name
elsif protected_method_defined?(unmemoized_method)
protected method_name
end
end
end
# return a chainable method_name symbol if we can
method_names.length == 1 ? method_names.first : method_names
end
まあ、コードの解説は抜きにして、端的に言えば、メモ化で参照されるデータは単一のものである、という事です。
その単一のものに対して破壊的変更をしてしまえば、そのメモ化で参照されるデータにも勿論影響が及びます。
上記のコードだと、
ユーザーA: おでんコードXに対するユーザーデータを持つ ユーザーB: おでんコードXに対するユーザーデータは持たない
と言う条件の下で、
1. ユーザーAがおでんコードXに対する情報を取得 メモ化されたおでんコードXのマスタの属性にデータが入る。 2. ユーザーBがおでんコードXに対する情報を取得 メモ化されたおでんコードXのマスタの属性はユーザーAのものが入ったままデータが送られてしまう。
と言う事が起きてしまう訳です。カラムに変更を掛けてしまっても同じ事が起こります。
まあ、策としては色々あります。
・メモ化して取ってきてくる時に属性を初期化する
・データが無くてもnilなどを明示的に入れる
・属性を使わない。メモ化したデータを弄る事をそもそもしないように心掛ける
等々。
自分は一番上の、メモ化して取ってきてくる時に属性を初期化する、を選びました。下のような感じにメソッドを作ったりしてそれを取ってくるようにして。
def attr_initialized_oden_data_memo(oden_code)
oden_data = oden_data_memo(oden_code)
oden_data.preference_data = nil
oden_data
end
理由としては、まあ実装上の設計の問題みたいな感じですが。
そこ辺りは設計と相談にもなってきます。
それではより良いおでんライフを。
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
Unityのシェーダーについて自分で調べたことをまとめました。
どうもmotsuka です。
今回はシェーダーを書いてみたくなったのでいろいろと調べてみたことをまとめてみたいと思います。
シェーダーとはシェーディング処理(陰影処理)を行うプログラムのことで、オブジェクトの頂点や色を変えるプログラムのことを指します。ポリゴンやテクスチャ等の画像をどのように画面に表示するかを決めるプログラムです。
またUnityでは3つのシェーダーがあり、
Unityでシェーダーを書くときこれらを使い分けて書く必要があります。
これらを簡単に説明すると
これらUnityで動くすべてのシェーダーでShaderLabという書式で書かれます。
これらの項目はまとめにURLが書いてあるので詳しく読みたい方はそちらをご覧ください。
では、簡単なシェーダーを書いてみましょう
今回は簡単な例として画面上に置かれた立方体の色を変えるプログラムを書いていきたいと思います。
まず、プロジェクト内で右クリックをして Create -> Shader -> Standard Surface Shaderをクリックしてシェーダーを作ります。
それをテキストエディタで開いてみましょう。
Shader "Custom/Test" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Standard fullforwardshadows
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
UNITY_INSTANCING_BUFFER_START(Props)
UNITY_INSTANCING_BUFFER_END(Props)
void surf (Input IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse" }
上のようなソースができたと思います。
上から読んでいきましょう
大きく分けて二つの枠に分けることができます。
ではこのソースを変えてこのシェーダーがついているオブジェクトの色を変えましょう。
_Color (“Color”, Color) = (1,1,1,1)
の行を下のように書き換えます。
_Color (“Color”, Color) = (1,0,0,1)
に変えて保存したシェーダーからマテリアルをつくって適当なオブジェクトにアタッチしてみてください。
そうすると色が赤色に変わったことが確認できます。
書いたことがなかったシェーダーですが、やってみるとあまり難しくなくさっくりとできる印象ですので皆さんもやってみてはいかがでしょうか?ですが、C#とは全く違う書き方や最初はよくわからないパラメータが多く出てくるので最初はきついかもしれませんが、慣れるとすんなり読めるようになるので皆さんもシェーダーを書いてみましょう。
次は文字のアウトラインをシェーダーで書いてみたいですね。余裕があったらまた書きたいと思います。
参考にしたURLを下にのせておくのでそこから読んでもらうと理解がより深まると思います。
Unity Documentation シェーダーマニュアル
https://docs.unity3d.com/ja/current/Manual/ShadersOverview.html
Unity のシェーダの基礎を勉強してみたのでやる気出してまとめてみた
http://tips.hecomi.com/entry/2014/03/16/233943
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
アニメやゲーム等、どこかで聞いたことありそうな物理学ワードを、生まれた背景や意味などを添えて集めてみました。意味が分かることで、より世界観を楽しめるようになるのではないでしょうか。
恐らくこの記事で最も有名な物理学ワードです。
これは、量子力学という分野において、粒子の状態が1つに決まらないことを元にしたパラドックスになります。
日常的に考えると、物事の状態は必ず一つに決まっていきます。(コインを投げれば表か裏かのどちらかに決まる、など)
しかし、量子力学の世界では、小さな粒子は複数の状態の重ね合わせで表現され、人間が観測するまで状態が決まりません。これが日常的認識と大きく違っているために、この量子力学を批判する次のような逸話が生まれました。
「Aの状態とBの状態の重ね合わせで表現される粒子があり、Aの状態になると毒ガスが出る箱を作って、猫を閉じ込める。
すると、箱を開けて観測するまで、粒子はAとBの重ね合わせなので、猫もまた生きている状態と死んでいる状態の重ね合わせになってしまう。」
※これは思考実験であり、実際に猫が犠牲にされた実験ではありません。
これがシュレディンガーの猫と言われるパラドックスです。
猫の生きている状態と死んでいる状態との重ね合わせという、日常的にあり得ないことが起こってしまう、と批判している文言なのですが、非常に小さい粒子の状態を、猫という大きなものへ影響させるということは、現代の技術でも発展途上のため、この話の真偽はまだ分かりません。
これも量子力学の分野の話です。
ディラックという有名な物理学者が、量子力学の世界での粒子の状態を表す式を導き出しました。しかし、この式ではエネルギーがいくらでもマイナスの状態である粒子が存在しても良いことが分かりました。粒子の性質として、エネルギーが小さい方へ行く性質があるので、これでは実在する全ての粒子がマイナス状態へ落ちていってしまう、と懸念されました。
これを説明するために、「マイナスの状態はすでに粒子が満員状態になっている」という概念を提唱しました。
これがディラックの海と呼ばれるものです。これらは、のちに別の理論によって解決され、ディラックの海は不要となってしまいました。
これは単純に物理学用語です。
エントロピーは物事の状態の「散らかり具合」を示す量で、物理学だけでなく、情報理論にも用いられている概念です。
このエントロピーは増える方向(散らかっていく方向)にしか動かない性質があり、エントロピー増大の法則と言われます。
(局所的にはエントロピーは減少することもあり得ます。しかし、全体で見れば増加しています)
これは物理学だけでなく情報理論にも関わるお話です。
空気の温度は、空気中の分子の温度の高いモノと低いモノの平均で出来上がっています。そこで、マクスウェルという物理学者は次のような思考実験を考えました。
「仕切りで2つの部屋に分けた箱を用意し、温度の高いモノを右の部屋へ、低いモノを左の部屋へ移すことが出来れば、何も特別なこと(「仕事」と言います)をする必要もなしに部屋の温度を上げたり下げたりできるのではないか。」
この思考実験は、上述のエントロピー増大則に反するため、注目を浴びました。
文中の、「熱い分子と冷たい分子を見分ける存在」が、のちにマクスウェルの悪魔と呼ばれるようになりました。
この問題の解決には、物理学だけでなく情報理論の助けも必要でした。
この見分けている悪魔が、何の仕事もしていないように見えて実は仕事をしていたのです。この悪魔は粒子状態の情報を取得し、次の粒子を観測するために、前の情報を消去する必要があり、この過程で仕事をしていることが分かったため、結論として熱力学の法則と矛盾しない、ということが分かりました。
物理学というよりは少し哲学的なお話です。
止まっている物Bに、物Aがぶつかって物Bを吹き飛ばしたとします。この時、物Aと物Bの重さ等の性質が分かっていれば、物Bがどのぐらいの速さで吹き飛んでいったのか計算することが出来ます。
つまり、物同士がぶつかる前からその先の未来を予言できてしまうわけです。
これの究極的な主張として、
「現在の、この世の全ての物の状態が分かってしまえば、この先の未来全ての状態が分かってしまうだろう。また、逆に現在より過去の全ての状態も分かってしまうだろう。」
ということを数学者ラプラスが主張しました。のちに、この世全ての状態を知っている存在が、「ラプラスの悪魔」と呼ばれるようになりました。
これは、この世のすべての出来事は決まっていることなのだ、という決定論的な考えにも見ることが出来ます。
現代では非常に小さい粒子の挙動は確率で記述されるため、起こるまで分からないという見方がされています。
一方で、確率変動で世界が分からないのではなく、粒子が取り得る状態の数だけ世界が分岐しているという見方もされています(エヴェレットの多世界解釈)。
いかがでしたでしょうか。結構聞いたことがある言葉が多かったのではないでしょうか。
これで今後の創作物にこのようなワードが出てきた時も、にやにやしながら世界に浸ることが出来ますね。
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
近年たくさんの素材サイトがありとても便利です。
柄などの素材をイラストに取り入れた際どう見えるのか
柄が浮いてしまったり、線画が素材に負けてしまうのを自然に見せるやり方をご紹介します。
※Photoshopを使用しています。
素材はURLのフリー素材のサイトから使用しています。
・がま口テクスチャ:http://bg-patterns.com/
・柄テクスチャ: http://frame-illust.com/
線画に素材を加えます。
この際に線の色を変えるだけで素材の色味と馴染みやすくなりアイコンのようにシンプルな見た目になります。これをいろいろいじってみます。
影のレイヤーを乗算にすることでベースの白と素材にも影をつけます。
そうすることで絵に厚みをつけることができます。
素材自体の色を変えた場合は全体の配色を同系色で統一させ、
線の色だけでなく影も色を変えます。
影色を調整する際は(彩色・彩度)からバーを動かせば簡単に変更できます。
編集>変形>ワープ
で素材を変形させることで立体感を表現することができます。
柄を複製してチェック柄に変えることもできます。
今回はフリー素材を使用し個人的な方法をご紹介しましたが、仕事の場は各現場のルールがあると思いますのでそれに合わせていきましょう。
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
ボキャブラリーとは、日本語に訳すと「語彙(ごい)」という意味です。
語彙とは、簡単に言うと「世の中に存在する言葉全て」です。
「ボキャブラリーが乏しい」というのは、「知っている単語」又は「使える単語」が乏しいという意味になる。
ボキャブラリーは自分の意見や考えていることを伝えるために必要になります。
今回はボキャブラリーを増やす方法をご紹介します。
一番わかりやすく手っ取り早い方法です。
最初は自分の興味のあるジャンルからはじめて
徐々に幅を広げていけば
今まで知らなかった言い回しを見つけたり、
間違って覚えていた、使っていた言葉の正しい使い方を確認することができます。
結果としてボキャブラリーは増えているはずです。
インプットするだけでなく、
調べたこと、知ったことをまとめることで
アウトプットもできるとより身に付くのではないでしょうか。
普段、自分の頭の中で考えられることは基本的に
自分が知っている言葉の中で行われています。
知らないことは当然思考には入りません。
知らない分だけ思考に制限がかかってしまうのです。
知らない言葉や気になる言葉を見つけたときはボキャブラリーを増やすチャンス!
すぐに調べましょう!
いまはスマートフォンで簡単に調べることができるのでそこまで手間ではありません。
後回しにすると大抵の場合、調べないままほったらかしになります。
「やばい」という言葉は様々な状況で使えてしまうため
便利である一方、正確な意味が伝わりづらいです。
例
・このお店、雰囲気やばくない?
・このゲーム、難易度やばい!
良いとも悪いともとれる、その場のテンションなどでなんとなく意味は
推し量れますがあくまで推測に過ぎません。
自分の意見、考えを正確に伝えたい場合は避けるべきでしょう。
・読書
・調べる癖をつける
・「やばい」禁止
以上、ボキャブラリーを増やす方法をご紹介しました。
ボキャブラリーを増やしたいと思っている方は意識してみてはいかがでしょうか。
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
最近購入したメカニカルキーボードが良い意味で変態的な仕様でしたのでご紹介したいと思います。
フルサイズキーボードとは、テンキーが付いている標準的なキーボードのことで、日本語配列では108キーあります。
横に長いためスペースを取りますが、数字の入力がスムーズに行えるため、表計算ソフト等で数値入力を頻繁に行う人には向いています。
テンキーレスキーボードとは、その名前の通りテンキーがないキーボードのことです。日本語配列では91キーあります。
フルサイズキーボードに比べデスク上でのスペースを削減できるため、自分の好みのポジションに動かしやすいという利点がありますが、数値入力を頻繁に行う方にはあまり向いていません。
最近私は「Vortex Core」というキーボードを購入し、オフィスで使用しています。
画像検索すると分かりますが、とても小さいキーボードなので持ち運びに便利です。
vortex core – Google 検索
数字キーやファンクションキーは廃され、矢印キーすらなくなっています。
その大きさは248 x 76.2 x 25.5mmというサイズです。iPhone7 Plusのサイズが158.2 x 77.9 x 7.3 mmですので、幅についてはこのキーボードのほうが小さいということが分かります。
ここまで小さいと使いづらくないのか、と皆さんお思いになるでしょうが、その通り使いづらいです。
非常に使いづらいです。
このキーボードには「Fnキー」と「Fn1キー」があり、それらと他のキーの組み合わせで数字を入力したり矢印キーを使うことになります。
慣れればどうということはないと思いますが、慣れるまでに時間がかかります。
ですが、本体はとてもシンプルな作りで持ち運びもしやすいため、Macbookと一緒にオシャレな喫茶店で広げればドヤれるかもしれませんね。
ちなみにこのキーボードはWin版しかないため、Macでご利用いただく場合は各々工夫が必要となります。
世の中にはさらに特殊なキーボードもありますが、小ささを求めるとこのキーボードに行きつくのかもしれません。
皆さんもキーボー道を極めていきましょう。
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
OGPで画像を設定してシェア時に目立たせる様な対応を行ったのでそれについて記事にします。
連続投稿となります。待ちに待ったプロ野球が開幕してテンション高めのむらさきです。
今回はFacebook等SNSでのシェアでたくさんの人の目に留まるように画像やタイトル等を設定するOGPについて書いていきたいと思います。
OGPとはOpen Graph Protocolの略です。FacebookなどのSNSにウェブページの情報を載せる際に必要なタグのことです。
OGPを設定することで下図のようにシェア時に任意の画像やタイトルを入れることができます!
画像を入れることで多くの人の目に留まるようになりたくさんの人に見てもらえる機会が増えるので是非設定しましょう!
OGPは設定したいページのhead内に以下のようなmetaタグを入れることで設定できます。
<meta property="og:locale" content="ja_JP">
<meta property="og:site_name" context="DoRuby">
<meta property="og:title" context="RailsでLoggerを使ってLogローテーション">
<meta property="og:description" context="DoRubyは、株式会社Appirits(アピリッツ)が運営するWeb技術・マーケティング情報発信ブログです。Ruby on Railsを中心に開発現場ならではの実践的な情報を随時掲載していきます。">
<meta property="og:type" context="article">
<meta property="og:url" context="https://doruby.jp/users/ueki/entries/Rails%E3%81%A7Logger%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6Log%E3%83%AD%E3%83%BC%E3%83%86%E3%82%B7%E3%83%A7%E3%83%B3">
<meta property="og:image" context="https://doruby.jp/images/doruby_og.png">
今回はこのように設定しました。
OGPには必須で入れないといけないものが4つあります。
og:title ページのタイトル
og:type どんなページなのか(今回は記事のページなのでarticleを設定しました。blogやwebsiteなどもあります。)
og:url ページのurl
og:image ページの画像
です。それ以外に書かれているmetaタグは必須ではないですが入れることでより詳しく表示させることができます。
og:description ページの説明文
og:locale サポートしている言語
og:site_name サイトの名前
となっています。自分のページに合わせて設定しましょう!
OGPが正しく設定されているかを確認するにはfacebook for developersのシェアデバッガーを使用しましょう。
ここに確認したいページのurlを入れることで正しく設定されているかを確認できます。
また、設定してもfacebookのクローラーにクロールされないと設定した画像等には切り替わらないのですが、「もう一度スクレイピング」を押すことですぐに設定した情報を反映させることができます。
いかがだったでしょうか。
OGPを設定して画像を変えたのに変わっていない!?と焦りましたが、シェアデバッガーで確認と同時に更新が出来るのでクロールされるのを待つ必要がないのはとてもいいですね。
OGPを正しく設定してたくさんの人の目に留まるサイト作りを目指しましょう!
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
皆さんはどのように変数名を決めているでしょうか。
命名規則がしっかり決まっているようであればそれに合わせれば良いのでしょうが、
複数人でプログラムしている場合、同じ単語を使っていても違った使い方をされる変数だったりすることがあります。
そんなことが自分自身にもありましたので命名規則の内の一つ、ハンガリアン記法について書いていきます。
ハンガリアン記法とは?
キャメルケース、スネークケースなどの単語と単語のつなげ方を意味するものではなく、
変数の意味や用途をわかやすくするために情報つけて命名するもので、以下の二つのものがあります。
アプリケーションハンガリアン
変数名にその変数の情報をつけてぱっと見で間違いを分かりやすくする方式です。
例えば何かの座標を入れる変数名にpositionX
positionY
と命名するのではなく、absPositionX
relPositionY
といったように絶対座標なのか相対座標なのかといった情報を付け加えるといった感じです。
そうすることによって書かれたコードが間違いであることを分かりやすくします。
Player.posX = absPositionX; Player.posY = relPositionY;
上記のような代入がされていたら誰でも疑問を抱くと思います。
アプリケーションハンガリアンなんて知らなくても、用途を分かりやすくしようと
変数名をつけるときにこのような形にしている人もいるんではないでしょうか。
システムハンガリアン
ハンガリアン記法といったらこっちのイメージが強いです。
変数名の頭などにその変数の型やスコープなどの情報となる文字をつける方式です。
一般的な例を以下の表にまとめました。
型,スコープなど | 追加文字 | 使用例 |
---|---|---|
論理型 | b | bEnable |
整数型 | n | nCount |
浮動小数型 | f | fAngle |
文字列 | s | sDescription |
ポインタ | p | pParent |
グローバル変数 | g_ | g_pManager |
クラス | C | CManager |
クラス内のメンバ変数 | m_ | m_nCount |
デメリット
おわりに
個人的にシステムハンガリアンに関しては型宣言を必要とするc++やc#においては全く必要がないかと思います。
コンパイル時点でエラーや警告でわかる場合が多いですし。
ですが型宣言を必要としないrubyなどの言語ではシステムハンガリアンで記述してもいいなと思いました。
変数にいろんな型のデータを代入できるがゆえに、何を入れるための変数なのか、何が入っている変数なのか役割をしっかり定義しておいたほうがいいと思います。
目次
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
新卒研修合宿でDoruby月1投稿を決めてから約10ヵ月。 ゴールに設定していた3月までの投稿が一通り終わったということで、新卒の「記事投稿数」「記事view数」「累計view数」をランキング形式で振り返ってみたいと思います。
記事右下のview数は同じ人の複数閲覧はカウントされておらず、社内IPの閲覧もカウントしているためssekiさんがこのプロジェクト開始時に作成してくれたデータスタジオの集計データを使用していきます。
データは2018/3/29 17:35のものを使用しています。
第3位は11記事を書いたHelloWorld?さんです
文章が独特で内容についての知識がなくてもついつい最後まで読んでしまう…そんな記事が多い印象でした。
記事画像が毎回食べ物関連なのは謎です。
第2位は13記事を書いたssekiさんです
彼の記事はデータスタジオについてのみで13記事書かれています。
流石アナリスト、記事もとてもきれいに書かれていてデータスタジオについて全く知らなくても使いこなせる気になってきます。
第1位は驚異の16記事を書いたLionさんです!
内容はゲームレビューやライフハック自身の経験談など様々でとても面白い記事が沢山ありますので見たことがない人はぜひご覧ください!
記事view数第3位はくじらさんのRedashがAWSで使えるようになる方法をまとめた記事でした!
第2位はknagataさんのExcelでINSERT文を発行する方法を示した記事でした。
第1位は断トツの9000view越え、nocoさんの立ち絵の書き方のポイントを共有した記事でした!
pixiv等でも参考にして書いてみたなどで使われておりたくさんの人に見てもらえている記事になってます!
第3位はActiveRecordやUnityなどについての記事が多かった くじらさんです!
C#やUnityについての記事が多かったinoooooocchiさんが第2位にランクイン!
Unity関連の記事は検索されやすい傾向にありそうですね!
記事view数で断トツの1位を取ったnocoさんが累計記事view数でも1位でした!
かわいい絵がたくさんなのでさっきからこれしか言ってませんが是非ご覧ください!
累計記事view数はすべてアピゲー部(弊社の自社開発ゲーム部署名)の社員が総取りでした!
いかがだったでしょうか。
17新卒で決めたDoRuby投稿が3月で終わり、気づいたらもう4月。1年間がとてもあっという間でした。
自分で投稿した記事のview数が伸びてるか確認するのが毎日のちょっとした楽しみでした。
記事を投稿することで自分の取り組んだタスクの復習にもなりとても勉強になりました。
17新卒が投稿する頻度は落ちるかと思いますが17新卒の記事かな?っていうのを見かけたら覗いてもらえると嬉しいです。
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
fugitive.vimプラグインを使うとvimでファイルの編集をしながらgitの操作ができます。
前回コミットとの差分の表示などを簡単に表示できるのでとっても便利です。
導入
dein.vimを使っているので.vimrcに以下を追記
call dein#add('tpope/vim-fugitive')
これでvim上のコマンドでgitの操作が可能になります。
主なコマンド
:Gstatus
git statusが上部に表示される。
statusの確認だけでなく、
表示されているstatusのファイル名にカーソルを合わせてキーを打つことで動作を行える。
D | vimdiffで直前のコミットとの差分を表示 |
– | addとresetを切り替え |
Enter | ファイルを表示 |
:Gdiff
vimdiffで直前のコミットとの差分を表示する。
自分はこれを一番多用してます。
:Gread
開いているファイルを直前のコミットの状態でみる。
:Gwrite
開いているファイルをgit addする。
:Gremove
開いているファイルをgit rmする。
:Gblame
開いているファイルをgit blameする。
見ていた行から表示してくれるので便利です。
普通のgit blameとは違いvimの設定の色がついてくれるので見やすいですが少し重いです。
かなり便利なので使ったことない人は一度使ってみてはいかがでしょうか。
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
rubyのMethodやProcにはsource_locationというメソッドがあります。これを使うことでゴーストメソッドでも定義場所を発見できRubyコードの探索を簡単に行うことができます。
新卒最終日になりました。くろすです。
今回はメソッド探索に使うと便利な Method#source_location, Proc#source_location の紹介をします。
メソッドクラスは Object#methodによりオブジェクト化する際に使われるクラスです。
詳しいことはだいたいドキュメントに書いてありますが、Procオブジェクトと違いレシーバーの情報も持っていて、クロージャーではないというのが大きな特徴です。
すでに定義してあるメソッドをオブジェクトとして取ってこれるという点で便利だなと思います。
https://docs.ruby-lang.org/ja/latest/class/Method.html
さてそんなMethodClassの source_location
ですが、色々話すより見てもらう方が早いと思います。
[1] pry(main)> ActiveRecord::Base.methods.grep(/transaction/)
=> [:transaction]
[2] pry(main)> ActiveRecord::Base.method(:transaction)
=> #<Method: Class(ActiveRecord::Transactions::ClassMethods)#transaction>
[3] pry(main)> ActiveRecord::Base.method(:transaction).source_location
=> ["path/to/gems/activerecord-4.1.15/lib/active_record/transactions.rb", 206]
使ってるgemが古いのは置いといてgemの中でもrubyで定義してあれば探すことができます。
[1] pry(main)> class Ghost
[1] pry(main)* (1..3).each{|n| define_method("method_#{n}"){ puts n } }
[1] pry(main)* end
=> 1..3
[2] pry(main)> g = Ghost.new
=> #<Ghost:0x007f99da931d38>
[3] pry(main)> g.method_1
1
=> nil
[4] pry(main)> g.method(:method_1).source_location
=> ["(pry)", 2]
ご覧の通りdefine_methodでも余裕です。
が、method_missingを利用したゴーストメソッドはさすがに追い切れないです。
[1] pry(main)> Hash.method(:new).source_location
=> nil
ruby外で定義されているメソッドは残念ながら探せません。
ぶっちゃけると define_method
対策として紹介しているので、define_methodを使わないようなコードではあまり使いどころがないと思います。
僕自身は開発にneovimを使うのでコードジャンプできなかった場合、ターミナルエミュレータを起動、highway、rails consoleからのsouce_location の順番でメソッドを探しています。
プログラムを読むために検索するというのは日常的なことだと思うのでその検索が少しでも早くなる手助けになればと思います。
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
今回は社内ブログを書くことで得られたメリットをご紹介します。
記事としてまとめるために、自分の中の知識だけでは不安があります。
そのため、間違った理解をしていないか、なるべく多くの情報を集めます。
情報を集める中で
いままで気付けなかったことに気付くことができたり、
実際に記事には書いていなくても新たな知識として蓄積されます。
①で身に付けた知識や日々の仕事で学んだことをまとめることで
一度自分の思考が整理されます。
ごちゃごちゃしていた頭の中を整理することでより深く考えられるようになります。
アウトプットする機会は意識しないと意外と少ないもので、
その機会を得られるのは社内ブログを書くことの大きなメリットだと思います。
文章を書くのは正直苦手でしたが10記事書く頃には大分抵抗も減りました。
当たり前ですが書かないと一生書けるようにはなりません。
まずは書く。書く習慣を持つキッカケになりました。
①新たな知識が身に付く
②思考力がつく
③文章を書く練習になる
以上、社内ブログを書くことで得られる3つのことをご紹介しました。
社内ブログでなくとも何かを発信することは自分にとって大きなプラスになるはずです!
※本記事の内容は個人の見解によるものになります。
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
今回はストレスをため過ぎないようオフィスで簡単にできるストレス解消方法をご紹介します。
外部から刺激を受けたときに生じる緊張状態のこと。
外部からの刺激には、
天候や騒音など環境的要因や、睡眠不足などの身体的要因、
不安や悩みなどの心理的要因、人間関係が上手くいかない、
仕事のノルマや締め切りに追われてるなどの社会的要因があります。
日常的に起こる色々な出来事がストレスの要因になってしまうのです。
ストレスはためすぎると体調を崩したり、気持ちが不安定になったり、
さらには心の病気にもなってしまうこともあります。
【引用】厚生労働省:知ることからはじめよう、みんなのメンタルヘルス
今回はストレスをため過ぎないようオフィスで簡単にできるストレス解消方法をご紹介します。
ずっと同じ姿勢というのは体にもよくありません。
またそもそも集中力は長時間持たないので適度な休息が大切です。
トイレにいったり、軽くストレッチをしたり、何でも良いので席から立ちあがりましょう。
他の人の仕事の邪魔にならない程度であれば、誰かとお話するのも良いと思います。
噛むという行為が脳への血流を良くするため、
不安な気持ちを落ち着かせ、前向きな気持ちになれる効果があるそうです。
ストレス解消に役立つ食べ物でダークチョコレートも有名ですが、
チョコレートは太ってしまうんじゃないか…
という不安が新たなストレスに繋がってしまう可能性も。
その点、ガムであれば低カロリーなので安心です。
仕事の中には嫌なことも理不尽なこともあると思います。
心が折れてしまいそうな出来事であっても一度冷静に、5年10年後、忘れられないようなことか
考えてみましょう。
大抵のことは忘れることができる、それほど重要なことではないはずです。
・こまめに席を立つ
・ガムを噛む
・5年や10年後も忘れない出来事か自答する
以上、オフィスで簡単にできるストレス解消方法をご紹介しました。
どれも簡単に出来ることだと思うのでストレスが気になる方はぜひお試しください。
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
アプリレビュー機能を実装する際に使ったAssetについて使い方を備忘録的にまとめます。
皆さんはスマートフォン向けアプリを探しているとき、どこに目が行くでしょうか?
私はまずアイコンを見て、タイトルを見て、それから星の数を見ます。
または、アイコンやタイトルに惹かれて詳細画面に進んだ後に、星の数をチェックします。
皆さんご存知の通り、星の数はアプリに対する評価の高さを意味します。
もちろん、AppStore・GooglePlayStore共に、ユーザーが自由にレビュー出来るシステムなので、不当な評価をされている可能性も無くはないのですが、それでも星の数はおおよそアプリの評価を表します。
評価の低いアプリをわざわざインストールしたいと思うユーザーはいないでしょうし、似たような機能のアプリがあれば評価の高い方を選びたくなるのがユーザー心理だと思います。
今回は、そんなアプリの評価を高めるため、ユーザーに対してレビューを依頼する機能をUnityの有料Assetを用いて実装する方法をご紹介します。
https://assetstore.unity.com/packages/tools/integration/ratebox-ios-android-rate-review-popup-75190
今回ご紹介するAssetは、こちらの「RateBox」です。
2018年3月末現在の価格は$12.95、だいたい1400円ぐらいです。
Unityのバージョン5.0.0以降に対応しています。
このRateBoxは、iOSのバージョン10.3.3以上のiOS内蔵のレビュー機能に対応しています。
RateBoxの話を進める前に、アプリのレビュー機能に関して気をつけなければならないことがあるのでお話しておきます。
iOSのバージョンが10.3.3以上の場合、AppleはiOSのSDKが提供するレビュー依頼用のウィンドウを表示することを義務付けています。
このウィンドウは、アプリから離れることなくウィンドウ上で星の数を選んでレビューを行うことが出来るもので、ユーザー的にも煩わしい遷移を行うことなく手軽にアプリの評価が行えるものになっています。
iOS10.3.3に対応するアプリなのに、このiOS内蔵のレビューウィンドウを使用しない場合、審査のリジェクト対象となる可能性があるため、RateBoxに備わっている機能を用いて対応することが望ましいでしょう。
無事Assetを購入し終えたら、Unityにインポートしましょう。
デフォルトではデモシーンやそれに伴うプレハブが付属してきますが、デモシーンを活用せずともドキュメントを読むことで大雑把な使い方は理解できるため、アプリ容量等を気にしている場合はインポートしなくても問題ありません。
以下、そのドキュメントや実装の経験談をもとに、簡単に使い方をまとめていこうと思います。
※今回は、アプリのレビュー誘導のためにオリジナルのウィンドウを表示させたいケースを想定して説明していきます
IAlertPlatformAdapter
インターフェースを継承させ、各種メソッドをオーバーライドする必要があります。IAlertPlatformAdapter.Show
と IAlertPlatformAdapter.Dismiss
で、前者はウィンドウを表示する時に呼ばれる関数、後者はウィンドウを閉じる時に呼ばれる関数です。ウィンドウを表示したり消したりする処理はここで行うといいでしょう。RateBox.Instance.Init
を、レビュー依頼を出したい画面より前に実行します。(アプリの起動時に行うのが良さそう)RateBoxConditions
クラスのインスタンスRateBoxTextSettings
クラスのインスタンスRateBoxSettings
クラスのインスタンスこれらのクラスに関しては、次の項目で詳しく説明します。
RateBoxConditions
、RateBoxTextSettings
、 RateBoxSettings
が存在します。RateBoxConditions
クラスはレビュー依頼ウィンドウを出す条件に関するプロパティを持ち、それぞれの設定項目は以下の通りです。MinSessionCount
RateBox.Instance.Initの呼ばれた回数が MinSessionCount
以上のときにレビュー依頼が表示されるようになります。MinCustomEventsCount
カスタムイベント(任意の条件)のカウンターの数が MinCustomEventsCount
以上のときにレビュー依頼が表示されるようになります。カウンターは RateBox.Instance.IncrementCustomCounter()
で増やすことが出来ます。(例:ミニゲームを1回クリアするごとにカウンターを1増やし、5回クリアした時点で表示する)DelayAfterInstallInSeconds
インストールされてからの秒数が DelayAfterInstallInSeconds
に指定した秒数以上のときに表示されるようになります。DelayAfterLaunchInSeconds
アプリを起動してからの秒数が DelayAfterLaunchInSeconds
に指定した秒数以上のときに表示されるようになります。PostponeCooldownInSeconds
一度レビュー依頼ウィンドウが表示されてから、次に表示可能になるまでの秒数です。デフォルトでは22時間(=79200秒)になっています。RequireInternetConnection
trueのとき、インターネット接続がされている状態でのみ表示します。RateBoxTextSettings
クラスは以下のプロパティを持ちます。それぞれ意味はプロパティ名そのままで、渡した値がRateBox備え付けのUIに反映されます。Title
Message
RateButtonTitle
PostponeButtonTitle
RejectButtonTitle
ただし、 RejectButtonTitle
だけは重要で、これが空だと「二度と表示しない」ボタンを押した時のコールバックが機能しなくなってしまいます。自作ウィンドウで「二度と表示しない」ボタンを表示したい場合は、適当な文字列を渡すといいでしょう。
RateBoxSettings
クラスは、 UseIOSReview
プロパティを持ちます。これがtrueのとき、RateBoxは端末のOSを参照し、iOS10.3.3以上の場合はiOS内蔵のレビュー依頼ウィンドウを表示します。その場合、自作のウィンドウを用意していてもiOS内蔵のウィンドウが優先的に表示されます。 ここで注意する必要があるのが、仮にこの設定を行っていても、ビルドに用いるXCodeのバージョンが8.3未満の場合、iOS10.3に対応していないためiOS内蔵のレビュー依頼ウィンドウが表示できない点です。 また、iOS内蔵のレビュー依頼ウィンドウは SKStoreReviewController
というiOSのSDKを使用しており、365日あたり3回までしかレビュー依頼ウィンドウが出せません。これは、Apple側の「ユーザーに執拗にレビューを求めるのは良いことではない」という考えに基づいた仕様です。 このため、iOS10.3.3以上の場合、 RateBoxConditions
の条件を完全にクリアした状態でレビュー依頼ウィンドウを出そうとしても表示されないことがあります。従って、Appleは「ボタンを押したら必ずレビュー依頼ウィンドウが出る」など、ユーザーの動作に直結したレビュー依頼の出し方をすることは望ましくないと表明しています。(詳細はこちら)4.レビュー依頼の表示
レビュー依頼を出したいタイミングで RateBox.Instance.Show()
を実行することで、RateBoxがレビュー依頼のウィンドウを表示してくれます。
引数も存在しますが、引数はRateBoxに備え付けのUIでレビュー依頼ウィンドウを出す際の各種テキストなので、自作ウィンドウの場合はウィンドウ側で文字列の制御をし、引数は渡さなくても大丈夫です。
また、RateBox.Instance.ForceShow()
という関数も存在し、こちらは RateBoxConditions
で設定した条件を無視して必ず表示させる関数です。使用の際は、前述のiOS10.3.3以上のSDKの制限に注意しましょう。
5.レビューのコールバック
残念ながら、レビュー依頼ウィンドウで「レビューする」を押した場合、実際に遷移先でレビューしたかどうかのコールバックは存在しません。
すなわち、少なくともRateBoxでは「レビューしてくれたらアイテムを差し上げます」タイプの実装は出来ないということです。
ただ、そもそも報酬を目当てにレビューさせることは各ストアの規約に違反する恐れがあるため、望ましいことではありません。
6.統計情報の削除
RateBoxConditions
で設定した条件の統計情報(カスタムイベントの回数など)は、 RateBoxStatistics
クラスに保持されています。
何らかの目的でこの統計情報をリセットしたい場合、 RateBox.Instance.ClearStatistics()
を実行します。
ちなみに、この統計情報はアプリのバージョンが更新されたり、アンインストールされたりすると削除されます。
このため、「二度と表示しない」を押したり、カスタムイベントを達成して表示されない状態になったユーザーに対して、アプリのアップデートをすることで再度レビュー依頼を出すことが出来ます。
基本的な使い方は以上になります。
最後に、RateBoxのドキュメントに記載されているこの一文を載せておきます。
Call Show function when user is satisfied (level up, complete the stage, receive bonus, etc).
レビュー依頼は、適切なタイミングで表示しないとかえってアプリの評価を落とすことに繋がりかねません。
ユーザーがレビューをしたくなるタイミングを考え、アプリの構造・システムに応じて、最適なレビュー依頼を行えるように各種条件を使いこなしましょう。
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
デスクワークをされている方は、一日の中で座っている時間が一番多いかと思います。
座るのは楽というイメージがある方もいるかもしれませんが、
長時間座り続けるのは立っている以上に体に負担がかかるとも言われています。
そんなデスクワークと長く付き合っていくために、意識したいことを3つご紹介します。
猫背、足組み、頬杖、斜め座り…作業に集中するとつい姿勢を崩してしまいがちです。
悪い姿勢は、腰痛や肩こりを引き起こす原因になります。
体が痛み始めると集中力がとぎれがちになり、作業効率も落ちてしまいます。
よって、正しい姿勢を保つことは作業効率の向上につながります。
骨盤を立て、背筋を伸ばして座るように心がけましょう。
意識してもなかなか姿勢が直らない!という方は姿勢矯正椅子の使用をおすすめします。
座るだけで自然と背筋が伸びる構造になっているため、無理なく姿勢を正すことができます。
長時間同じ体勢でいると血行が悪くなったり、筋肉がコリ固まってしまいます。
体の痛みの原因になるだけでなく、早期死亡のリスクも高まると言われています。
集中するあまり一日中座りっぱなしで作業をしてしまったことはありませんか?
立ち上がった直後うまく体が動かず、体が緊張してしまっているのを感じます。
眠気覚ましやリフレッシュも兼ねて時々立ち上がって歩いたり、
座ったままでも思い切りのびをしたり、肩を回したり、体をひねったり…
本格的なストレッチでなくとも、やるとやらないでは体の調子が大きく変わります。
2時間に1度は軽い運動を含めた休憩をとるようにしましょう。
デスクワークはパソコンと長時間向き合うため、目に疲れがたまります。
機械のディスプレイから放たれるブルーライトは目にダメージを与えます。
作業をするときはブルーライトカット眼鏡を使用し、目へのダメージを軽減すると良いでしょう。
カット率の高いメガネのレンズは黄~橙色をしているため、景色の色が目に見えて変わります。
グラフィックを扱う作業の場合は注意が必要です。
疲れた目を休ませるときにはホットアイマスクがおすすめです。
目元の筋肉を温めることでコリをほぐし、疲れを癒してくれます。
使い捨てタイプや繰り返し使えるタイプ、電気充電式のものまで様々な商品が展開されています。
また、ホットアイマスクと同様の効果を持つ蒸しタオルを自宅でも簡単に作ることができます。
タオルを水で濡らしてしぼった後、そのままレンジで30秒〜1分加熱するだけで完成です。
取り出した直後はかなり熱くなっているため、やけどには十分注意してください。
作業中はもちろん起床後の眠気覚ましに、就寝前のリラックスタイムにもおすすめです。
デスクワークにおいて自分が日々実践していることを書かせていただきました。
簡単なことですが、少し気を付けるだけで体への負担が大分減っているように感じられます。
健康あっての生活ですから、体を大切に暮らしていきたいですね。
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
Unityをインストールする際に(特に設定しなければ)付属してくるIDE「MonoDevelop」でコーディング規約を設定する方法をご紹介いたします。
気がついたらもう春ですね。
春になると、卒業研究を終えた内定者たちのインターンシップ参加率が上がり、それに伴ってプロジェクトに新しいエンジニアが来てくれます。
自分は今まで新卒という立場で、先輩方に色々と教わりながら1年間業務を行ってきたわけですが、そんな自分にも後輩ができるみたいです。全然実感がありません。
さて、後輩たちの環境構築やプロジェクトの説明をする際に忘れてはならないのが、コーディング規約についてです。
変数名の付け方やプログラムの構造だけでなく、改行、スペース、インデント等もプロジェクト間で揃えないと読み辛いソースコードが出来上がってしまいます。
とはいえ、開発経験が乏しい場合でも、なんとなく自分の慣れ親しんでいるコードの書き方というのはあるかと思います。
そんな状態で、「お前は今日からこのプロジェクトの一員だ、この規約に従ってコーディングしろ」と言われても(※実際にはそんな言い方はしません)、ただでさえ不慣れな環境の中、気を遣うことが多すぎて集中できないと思います。
そこで、Unityに標準でついてくるIDE「MonoDevelop」の機能を使えば、他の人が作ったコーディング規約をインポートしてコードを自動整形することができます。
[MonoDevelop-Unity]
-> [Custom Policies...]
-> Add Policy
-> From file...
-> 拡張子「.mdpolicy」のファイルを選択
上記の手順を踏むと、.mdpolicy
ファイルを読み込んでコーディング規約を生成してくれます。
.mdpolicy
ファイルの中身を見てみると、以下のようになっています。
<NameConventionPolicy>
<Rules>
<NamingRule>
<Name>Namespaces</Name>
<AffectedEntity>Namespace</AffectedEntity>
<VisibilityMask>VisibilityMask</VisibilityMask>
<NamingStyle>PascalCase</NamingStyle>
<IncludeInstanceMembers>True</IncludeInstanceMembers>
<IncludeStaticEntities>True</IncludeStaticEntities>
</NamingRule>
<NamingRule>
<Name>Types</Name>
<AffectedEntity>Class, Struct, Enum, Delegate</AffectedEntity>
<VisibilityMask>VisibilityMask</VisibilityMask>
<NamingStyle>PascalCase</NamingStyle>
<IncludeInstanceMembers>True</IncludeInstanceMembers>
<IncludeStaticEntities>True</IncludeStaticEntities>
</NamingRule>
<NamingRule>
<Name>Interfaces</Name>
<RequiredPrefixes>
<String>I</String>
</RequiredPrefixes>
<AffectedEntity>Interface</AffectedEntity>
<VisibilityMask>VisibilityMask</VisibilityMask>
<NamingStyle>PascalCase</NamingStyle>
<IncludeInstanceMembers>True</IncludeInstanceMembers>
<IncludeStaticEntities>True</IncludeStaticEntities>
</NamingRule>
...以下省略
このように、命名規約やインデント規約などが細分化された状態でxml形式で記述されています。
これをプロジェクトの共有フォルダ等に置いておくことで、誰でも簡単にプロジェクトのコーディング規約を設定することができます。
さて、.mdpolicy
ファイルですが、当然プロジェクト間で共有するためには誰かが最初に作成しないといけません。
理論上、先ほどの例のような感じでxml形式で記述したファイルを.mdpolicy
拡張子で保存すれば作成できますが、果てしなく面倒な作業ですね。
当然ですが、MonoDevelopはインポートだけでなくエクスポートもできます。
もちろん、xmlを書かなくても、MonoDevelop上で各規約の設定を行って保存することができます。
先ほどインポートの際に説明した画面の左側のメニューから、
[Source Code] -> [Code Formatting] -> お好みの形式
を選び(今回はC#)、画面右側で 「C# Format」を選択し、Editを押すと
このように、各種規約に対するパターンがずらっと並んだ画面が表示されます。
ここでチェックボックスをいじったりして、右側のプレビューを参考にしつつ簡単に規約を設定できます。
そして、無事に規約を作成し終えたら、先ほどの 「Add Policy」の右にある「Export」でファイルに出力しましょう!
最後に、ファイル保存時に自動でフォーマットを行ってくれる機能をご紹介します。
[MonoDevelop-Unity] -> [Preferences] -> Text Editor -> Behaviour
の、「Format document on save」にチェックを入れて保存しましょう。
これで、ファイルを保存した際に自動的に設定された規約に基いてコードを整形してくれます。
以上、MonoDevelopにコーディング規約を設定する方法でした。