粗大メモ置き場

個人用,たまーに来訪者を意識する雑記メモ

Python Anacondaの仮想環境上での開発環境

前の記事で仮想環境を立てましたが,エディタをデスクトップから起動するとメインの環境で立ち上がるという問題があります。

Spyderを仮想環境上で呼ぶ。

Matlabコンソールぽくてとりあえず気に入ったspyderについて。

spyderを仮想環境上にインストー

仮想環境名は前回を引き継いで「tf35」とします。

conda install -n tf35 spyder

仮想環境から呼び出し

activate tf35

とした後に

spyder

と打つだけでした。楽ちんですね。

Jupyterの場合

正直はじめてまともに起動します。

インストー

同じ!!

ひょっとしたらいらないのかも?

起動

activate後に

jupyter notebook

とうって起動。

使い方はまた後ほど。

Windows上でTensorflow/Opencvの環境構築(Anaconda使用)

むかぁしTensorflowをUbuntuに入れてたことが合ったのですが引っ越しの際に全て消し飛ばしてしまったのでしばらく放置していました。
気がついたらWindowsでもTensorflowを出来るということなのでやってみました。

Anaconda で Python環境構築

これは既にやっているものとします。
ossyaritoori.hatenablog.com

そういやTwitterでJupyterを使おうと言われたので使用感を試しているところです。

Anaconda でTensorflowの環境構築(CPU版)

Anacondaって使う環境を分けることが出来るんですね。
上手く言えないけど開発毎にパッケージ群を分離して選択できるというかなんというか。

環境の構築

んで,今回は「tf35」と名前をつけた環境を作ります。

以下のように打ってください。

conda create -n tf35 python=3.5

これでtf35という名前の独立した環境が立ち上がります。

Anacondaを介してインストールする際の罠として「TensorflowはPython3.5しかサポートしていない」というのがあります。

Anacondaで最新版をインストールすると3.6系になるので私はこれでハマりました。
「No matching distribution found for tensorflow」ってエラーを見かけたらこれかもって思ってください。

したがって,後ろについている「python=3.5」とすることによってこの環境は3.5系を基準に動かすことが出来るようにセットアップされます。

アクティベーション

作った「tf35」という環境をactivateするには

activate tf35

終了する際には

deactivate

としてください。

Tensorflowのダウンロード

以下の公式?の通りにコマンドを打って最新版を手に入れてください(2017/5/25現在)
Installing TensorFlow on Windows  |  TensorFlow

pip install --ignore-installed --upgrade https://storage.googleapis.com/tensorflow/windows/cpu/tensorflow-1.1.0-cp35-cp35m-win_amd64.whl

アクティベーション結果のチェック

正直変なエラー出たら全部消してやり直すかStackflowみてください。

 import tensorflow as tf
 hello = tf.constant('Hello, TensorFlow!')
 sess = tf.Session()
 print(sess.run(hello))

これで何もエラーが出なかったらOKです。
もう一度付けるときはくれぐれもactivateを忘れずに。

そういやTensorflowの英語版の教科書もあったんですね。
誰か勝手送ってくれ~(お金ない)

Learning Tensorflow: A Guide to Building Deep Learning Systems

Learning Tensorflow: A Guide to Building Deep Learning Systems


次は仮想環境上でのエディタ環境について。

2017年9月追記:anaconda 標準環境のセットアップ

どうも新しい環境(condaprompt)で試した所、いろいろとパッケージが入っていない現象にぶち当たりました。
以下のコマンドでPython3.5のanaconda標準環境をダウンロードできます。

conda install anaconda python=3.5

なお、いくつかのパッケージはダウングレードされるようなのですがまぁ問題なさそうではあります。

おまけ

折角tensorflowを入れるのでOpencvもついでに入れようと思います。
先程作ったtf35の環境上で

anaconda search -t conda opencv

としてopencvディレクトリを探します。

ver228/opencv というところが3.2のwindows64bit版対応を公開しているようなので

anaconda show ver228/opencv3

として出てきたURLからダウンロードします。

conda install --channel https://conda.anaconda.org/ver228 opencv3

はい。pythonを起動して以下のように確認できたらOKです。(>>>はコマンドではない)

>>> import cv2
>>> cv2.__version__
'3.2.0-dev'

Python Figureの管理と動画作成についてメモ

Python覚えてたてマンなのでFigureの管理について。
使用するのはMatplotlibです。

使うパッケージ

matplotlibを主につかっていきます。

import matplotlib.pyplot as plt                   #   for plotting data
import matplotlib.animation as animation          #   for animation data

関数の定義と引数の返し方について

Pythonではdefのところで引数について書かないっぽいです。
代わりに一番下にreturnを書くことで引数を返せます。

1.plot関数からハンドルを出力させるようにする。

前の記事では以下のようなplot関数を書いていましたが,こいつが使いづらかった原因は出力を指定していなかったからですね。
plt.figureで出力した図のハンドルをreturnするようにするのが実用的でしょう。

def draw(i,observations):
    fig = plt.figure(i,figsize=(8, 8))
    sp = fig.add_subplot(111, aspect='equal')
    sp.set_xlim(-1.0,1.0)
    sp.set_ylim(-0.5,1.5)

    robot.draw(sp,observations)
    
    actual_landmarks.draw()

    plt.legend()
    
    return fig

2.出力されたハンドルを配列で保持

次に,出力されたハンドルを配列へと格納します。
ims=[] みたいな感じで初期化して,.append()というのを使って要素を追加できます。

従って以下のような流れになります。

ims = [] #初期化

for i in range(0,18):
    im = draw(i,None)             #描画関数
    ims.append(im)                #格納
    robot.move(0.2,math.pi / 180.0 * 20) #ここはまぁ気にするな

3.まとめてplot

imsに配列で全ての図を保存したので,plt.show()に具体的なハンドルを与える事ができます。
まとめてやるなら配列ごと突っ込むのが良いでしょう。

plt.show(ims)

これで随分心が晴れました。

4.動画にする

結論から言うとうまく行っていません。
なんでも保存するのにまた別のパッケージがいるとかなんとか。
以下のような感じで行けるらしいです。

fig = plt.figure()
ani = animation.ArtistAnimation(fig, ims, interval=1000)
plt.show()

モンテカルロ自己位置推定のテストとmatplotlibの覚書

こないだ千葉工大の上田先生の講演を聞いてきました。
そうです。あの「確率ロボティクス」を翻訳した方です。

確率ロボティクス (Mynavi Advanced Library)

確率ロボティクス (Mynavi Advanced Library)


はじめてお会いしましたが,講演もフランクで親しみやすそうという印象でした。

講演資料の一部がGithub上にある!

先生のGit上には講演で話された幾つかの種類についてipythonで書いたサンプルコードがあります。

probrobo_practice/1.monte_calro_localization.ipynb at master · ryuichiueda/probrobo_practice · GitHub

ということでこれを試して見たかったわけですね。

Python環境のセットアップ

先日書いた記事はこれに相当します。
ossyaritoori.hatenablog.com

コピペで実行。

確率ロボティクスではロボットが自身の位置に対する信念を「制御」と「観測」の値から推定しながら動くわけですが,
その最たる例が今回のMCL(Monte Carlo Localization)というわけです。

パーティクルフィルタよろしく,確率分布から取った複数のサンプル点でもって自らの信念を表示するわけですね。

f:id:ossyaritoori:20170524214304p:plain

matplotlibについて

今回ほぼはじめてPythonでまともなコード走らせるんですが,matplotlibというのも当然はじめてでして…

Referenceは以下になります。
pyplot — Matplotlib 2.0.2 documentation

基本的な流れは以下のような感じ?(pltとしてimportしてます。)
①figureハンドルを作成する。
.figureで以下のように図番号iとfigureサイズを指定してハンドルを作成するのでしょう。

fig = plt.figure(i,figsize=(8, 8))

②その後 figからなんかいろいろする。
普通にplt.~~でlineやcircleなど書けるようですが以下のプログラムではハンドル渡して.quiverなんかで矢印書いていますね

③表示 plt.show()
ここが少し不思議だったんですが一度作ったhandleは外でも生きているらしく,for文を抜けた後にまとめて表示してくれます。
matlabみたいにworkspaceを確認する手法があればわかりやすいのですが…spyderを使おう!(なおfigureハンドルは見えない模様)

コード

ほぼ全て上田先生の所にあったのをコピペしています。
これに適当にmcl1.pyとでも名前をつけて保存した後に実行するのが良いでしょう。

綺麗に書かれているのでこれを参考にしていろいろ書いて見ようかと思います。

#matplotlib inline
import numpy as np
from copy import copy
import math, random
import matplotlib.pyplot as plt                   #   for plotting data
from matplotlib.patches import Ellipse      #  for drawing

class Gaussian2D:
    # 共分散行列、中心の座標を属性に持つ
    def __init__(self,sigma_x = 1.0, sigma_y = 1.0, cov_xy = 0.0,mu_x = 0.0, mu_y = 0.0):
        self.cov = np.array([[sigma_x**2,cov_xy],[cov_xy,sigma_y**2]])
        self.mean = np.array([mu_x,mu_y]).T
        
    # ガウス分布の移動
    def shift(self,delta,angle):
        ca = math.cos(angle)
        sa = math.sin(angle)
        rot = np.array([[ca,sa],[-sa,ca]])
        
        self.cov = rot.dot(self.cov).dot(rot.T)
        self.mean = self.mean + delta
        
    # 密度の算出
    def value(self, pos):
        delta = pos - self.mean
        numerator = math.exp(-0.5 * (delta.T).dot(np.linalg.inv(self.cov)).dot(delta))
        denominator = 2 * math.pi * math.sqrt(np.linalg.det(self.cov))
        return numerator / denominator




class Landmarks:
    def __init__(self,array):
        self.positions = array
    
    def draw(self):
        xs = [ e[0] for e in self.positions]
        ys = [ e[1] for e in self.positions]
        plt.scatter(xs,ys,s=300,marker="*",label="landmarks",color="orange")


class Observation:
    def __init__(self,robot_pos, landmark,lid):
        # センサの有効範囲の設定
        self.sensor_max_range = 1.0
        self.sensor_min_range = 0.1
        self.sensor_max_angle = math.pi / 2
        self.sensor_min_angle = - math.pi /2 
        
        # ランドマークのIDを保存しておく属性。ランドマークがセンサの有効範囲にないとNoneのまま
        self.lid = None
        
        # 真の位置の情報をセットする。ロボットの真の姿勢はシミュレーション用でロボットは知らないという前提。
        # 真のランドマークの位置は、ロボットは知っているのでこのインスタンスの属性として保存します。
        rx,ry,rt = robot_pos
        self.true_lx,self.true_ly = landmark
        
        # ロボットからランドマークまでの距離の真値を算出
        distance = math.sqrt((rx-self.true_lx)**2 + (ry-self.true_ly)**2)
        if distance > self.sensor_max_range or distance < self.sensor_min_range:
            return
        
        # ロボットからランドマークがどの方向に見えるか真値を算出
        direction = math.atan2(self.true_ly-ry, self.true_lx-rx) - rt
        if direction > math.pi:    direction -= 2*math.pi
        if direction < -math.pi:   direction += 2*math.pi     
        if direction > self.sensor_max_angle or direction < self.sensor_min_angle:
            return
        
        # 真値に混入する雑音の大きさ(標準偏差)を設定
        sigma_distance = distance * 0.1           # 距離に対して10%の標準偏差
        sigma_direction = math.pi * 3 / 180    # ランドマークの方向に対して3degの標準偏差
        
        # 雑音を混ぜてセンサの値とする
        self.distance = random.gauss(distance, sigma_distance)   
        self.direction = random.gauss(direction, sigma_direction)
     
        # ロボット座標系での共分散行列を作っておく。あとで尤度を計算するときに使用
        # x方向が奥行きで、sigma_distanceを標準偏差に設定。y方向がロボットから見て横方向の誤差で、距離*sin(3[deg])となる。
        self.error_ellipse = Gaussian2D(sigma_x = sigma_distance, sigma_y = self.distance * math.sin(sigma_direction) , cov_xy = 0.0)

        self.lid = lid
        
    # 尤度の計算(遅い実装です。)
    # パーティクルの姿勢とランドマークの計測値からランドマークの位置を推定し、その位置に誤差楕円を置き、
    # ランドマークの真の位置が誤差楕円からどれだけ外れているかを確率密度関数の密度として返します。
    # この計算はもっと簡略化できますが、描画の関係でこういう手順を踏んでいます。
    # 簡略な方法: パーティクルの姿勢とランドマークの真の位置から、想定されるランドマークの距離・方向を算出し、
    # 実際の距離・方向とそれぞれ比較する方法。距離の誤差の傾向、方向の誤差の傾向をそれぞれ1次元のガウス分布で表現し、
    # それぞれを独立して計算して尤度を算出し、掛け算する。
    def likelihood(self,particle_pos): 
        # パーティクルの姿勢と、このインスタンスに保存されているセンサの値から、ランドマークの位置を求める
        rx, ry, rt = particle_pos
        proposed_lx = rx + self.distance * math.cos(rt + self.direction)
        proposed_ly = ry + self.distance * math.sin(rt + self.direction)
                
        # このインスタンスに保存されている共分散行列を、計算されたランドマークの位置に移し、パーティクルの向きに合わせて共分散行列を回転
        e = copy(self.error_ellipse)
        e.shift(np.array([proposed_lx, proposed_ly]).T, rt + self.direction)

        # そのままガウス分布の計算式から密度(尤度)を返します。
        return e.value(np.array([self.true_lx,self.true_ly]).T)
        
    # 描画用
    def ellipse(self,robot_pos):
        rx, ry, rt = robot_pos[0], robot_pos[1], robot_pos[2]
        proposed_lx = rx + self.distance * math.cos(rt + self.direction)
        proposed_ly = ry + self.distance * math.sin(rt + self.direction)
        
        e = copy(self.error_ellipse)
        e.shift(np.array([proposed_lx, proposed_ly]).T, rt + self.direction)
        
        # 固有ベクトルを二つ求めて、それぞれの大きさを求めて楕円を作り、幅を計算した方の固有ベクトルの向きに楕円を回転すると誤差楕円になります。
        eigen = np.linalg.eig(e.cov)
        
        v1 = eigen[0][0] * eigen[1][0]
        v2 = eigen[0][1] * eigen[1][1]
        v1_direction = math.atan2(v1[1],v1[0])
        
        elli = Ellipse([proposed_lx, proposed_ly],width=math.sqrt(np.linalg.norm(v1)),height=math.sqrt(np.linalg.norm(v2)),angle=v1_direction/3.14*180)
        elli.set_alpha(0.2)
        
        return elli
    
    # 描画用
    def draw(self,sp,robot_pos):
        sp.add_artist(self.ellipse(robot_pos))




actual_landmarks = Landmarks(np.array([[-0.5,0.0],[0.5,0.0],[0.0,0.5]]))
actual_landmarks.draw()


# パーティクルのクラス。単なる構造体
class Particle:
    def __init__(self,x,y,t,w):
        self.pos = np.array([x,y,t])
        self.w = w

# パーティクルフィルタのクラス
class ParticleFilter:
    # この実装ではコンストラクタはパーティクルの個数だけを引数にとる
    def __init__(self,num):
        # 空のパーティクルのリストを作って一つずつ追加していく(実装がベタ)
        self.particles = []
        for i in range(num):
            self.particles.append(Particle(0.0,0.0,0.0,1.0/num))    # パーティクルは重みを持つ。全パーティクルの重みの合計は1。1つのパーティクルの重みは1/個数
            
    # ロボットが動いたときにパーティクルを動かすためのメソッド
    # 引数の「motion」はメソッドで、ロボットの移動を再現するためのもの。
    # ロボットは自身がどのように動作するとどう姿勢が変化するかを知っており、このメソッドがその知識となる。
    def moveParticles(self,fw,rot,motion):
        self.resampling()       # このメソッドについては後述
        
        # パーティクルごとに移動した後の姿勢を計算し、姿勢を更新する。
        for p in self.particles:
            after = motion(p.pos,fw,rot) 
            p.pos = after
            
    # リサンプリングのためのメソッド。
    # リサンプリングは、重みがごく少数のパーティクルに偏ることを防ぐための措置で、近似していない理論上の数式では出現しない。
    def resampling(self):
        num = len(self.particles)                # numはパーティクルの個数
        ws = [e.w for e in self.particles]    # 重みのリストを作る
        
        print(sum(ws))
        if sum(ws) < 1e-100:                     #重みの和がゼロに丸め込まれるとサンプリングできなくなるので小さな数を足しておく
            ws = [e + 1e-100 for e in ws]
            
        ps = random.choices(self.particles, weights=ws, k=num)    # パーティクルのリストから、weightsのリストの重みに比例した確率で、num個選ぶ
        self.particles = [Particle(*e.pos,1.0/num) for e in ps]          # 選んだリストからパーティクルを取り出し、パーティクルの姿勢から重み1/numの新しいパーティクルを作成

    # 描画用
    def draw(self,c="blue",lbl="particles"):
        xs = [p.pos[0] for p in self.particles]
        ys = [p.pos[1] for p in self.particles]
        vxs = [math.cos(p.pos[2]) for p in self.particles]
        vys = [math.sin(p.pos[2]) for p in self.particles]
        plt.quiver(xs,ys,vxs,vys,color=c,label=lbl,alpha=0.7)


class Robot:
    def __init__(self,x,y,rad):
        random.seed()
        
        # actual_poses: ロボットの姿勢の真値を1ステップごとに記録したもの
        # (ロボットのクラス内にいるけどロボットはこの情報を使えない)
        self.actual_poses = [np.array([x,y,rad])]
        
        # パーティクルフィルタの準備(パーティクル数30個)
        self.pf = ParticleFilter(30)
    
    # ロボットの動作をシミュレートするメソッド。シミュレーションだけでなく、ロボットがパーティクルを移動するときにも用いる。
    # つまり実機に実装する場合もこのメソッドが必要となる。雑音の度合いは事前に計測するか、
    # ざっくり決めてフィルタのロバスト性に頼る。
    def motion(self, pos, fw, rot):
        # fwだけ前進してその後rotだけ回転。雑音を混入させる
        actual_fw = random.gauss(fw,fw/10)    #進む距離に対して標準偏差10%の雑音を混入
        dir_error = random.gauss(0.0, math.pi / 180.0 * 3.0) # 前進方向がヨレる雑音を標準偏差3[deg]で混入
        
        px, py, pt = pos
        # 移動後の位置を算出
        x = px + actual_fw * math.cos(pt + dir_error)
        y = py + actual_fw * math.sin(pt + dir_error)
        # 雑音込みの回転各を算出。rotに対して標準偏差10%の雑音を混ぜる
        actual_rot = random.gauss(rot,rot/10)
        t = pt + dir_error + actual_rot      # さらにヨレの分の角度を足す
        
        return np.array([x,y,t])
    
    # ロボットが動くときに呼び出すメソッド。ロボットの位置の更新とパーティクルの位置の更新
    def move(self,fw,rot):
        self.actual_poses.append(self.motion(self.actual_poses[-1],fw,rot))
        self.pf.moveParticles(fw,rot,self.motion)
        
    # ロボットがランドマーク観測するときに呼び出すメソッド
    def observation(self,landmarks):
        obss = []
        for i,landmark in enumerate(landmarks.positions):            # 3つあるランドマークを1つずつ観測
            obss.append(Observation(self.actual_poses[-1],landmark,i))
            obss = list(filter(lambda e : e.lid != None, obss))            # 観測データのないものを除去
            
        # 重みに尤度をかける
        for obs in obss:
            for p in self.pf.particles:
                p.w *= obs.likelihood(p.pos)
        
        # 描画用に観測のリストを返す
        return obss
        
    # 描画用
    def draw(self,sp,observations):
        for obs in observations:
            for p in self.pf.particles:
                obs.draw(sp,p.pos)
        
        self.pf.draw()
        
        xs = [e[0] for e in self.actual_poses]
        ys = [e[1] for e in self.actual_poses]
        vxs = [math.cos(e[2]) for e in self.actual_poses]
        vys = [math.sin(e[2]) for e in self.actual_poses]
        plt.quiver(xs,ys,vxs,vys,color="red",label="actual robot motion")

def draw(i,observations):
    fig = plt.figure(i,figsize=(8, 8))
    sp = fig.add_subplot(111, aspect='equal')
    sp.set_xlim(-1.0,1.0)
    sp.set_ylim(-0.5,1.5)

    robot.draw(sp,observations)
    
    actual_landmarks.draw()

    plt.legend()


robot = Robot(0,0,0)      # ロボットを原点に

# 観測、描画、移動の繰り返し
for i in range(0,18):
    obss = robot.observation(actual_landmarks)
    draw(i,obss)
    robot.move(0.2,math.pi / 180.0 * 20)

plt.show()

お言葉

最後に講演で先生がおっしゃった言葉で,
「便利なツールがあるなら使ってください。勉強以外の目的で自分で組むのはおすすめしません。」
というのが印象に残っています。
殊,Pythonに関しては情報にアクセスさえできればツールは使えますもんね。

情強になりたい…

Anacondaとspyderでwindows上にPython環境構築

Pythonは無料で使える上に有志がたくさんパッケージを作ってくれていて,
非常にPopularな手段になりつつあるのですが,依存関係やパッケージの管理が面倒です。

Anaconda

Anacondaが楽と聞いたので以下を参考にセットアップしました。
http://qiita.com/t2y/items/2a3eb58103e85d8064b6

Anaconda とは

「Anaconda はデータサイエンス向けに一連のパッケージ群を含むディストリビューションですが、一方で Python と conda のみを最小構成でインストールすることもできます。その最小構成のディストリビューションを Miniconda と呼んでいます。」

なるほど~。

インストール

公式サイトからAnacondaの3.x系の64bitインストーラーを入れます。
https://www.continuum.io/downloads
ここからexeをダウンロードして実行すれば完了です。

何やらいろいろ聞かれますが全部デフォルトで行くのが今のところ間違いがないです。
大体10分弱かかるかと思います。

なお、一連のファイルが占拠する容量は大体2G近いのでそこだけ要注意です。

動作確認

適当なところでコマンドプロンプトを起動して,以下のようにAnacondaについて説明が出れば完了です。
試しに"conda"などを打ち込むのが良いでしょう。何か説明が出たら成功です。

その後pythonとかを起動してanacondaに紐付けられているのを確認できたらHappy.
f:id:ossyaritoori:20170523230721p:plain


なんか32bitって出てるけどこれはいいのかしら?

追記

いつの間にかWindowsではanacondaのpathを自動で追加しないようになっていました。
したがってコマンドプロンプトではなくAnacondaプロンプトなるものを使う必要がありそうです。要はanacondaのpathが登録されたcmdってことですね。

ちょっと気持ち不便ですがこちらを使っていきましょう。

numpyの確認

試しに

import numpy
numpy.__file__

と実行してみてAnaconda以下のパッケージが参照されていれば完了です。
なんて簡単なんだ。

Matlab ライクなエディタ spyderを導入

Pythonを少し触って困ったのが定義した変数を簡単に確認できないこと。
matlabライクなコンソールを出してくれるspyderというのがあるということで導入しました。


こんな感じ。
f:id:ossyaritoori:20170524220154p:plain

おそらくanacondaを使えばデフォルトで入っているはずです。

私は以下のページからダウンロード&解凍をしちゃったんですが無いときはこちらで。
spyder-ide / spyderlib / Downloads — Bitbucket

pipなどでもダウンロード可なようです。

変数として定義したxやnumpyで作ったarray?も見えています。figureハンドルは見えなかったけどね…
f:id:ossyaritoori:20170524221025p:plain

発展編

TensorflowやOpencvを使いたい場合は次の記事へとどうぞ
ossyaritoori.hatenablog.com

参考文献

参考にさせていただいたサイトです。
親matlab派に向けたpythonでのデータ解析入門 | Advanced Technology Lab

Amazonのクーポンが使えないのはAmazonの出品する商品を買わないから

こんにちは。今日大学でAmazonのクーポンが配ってたので嬉々として使おうとしたら使えなかったのでかなり時間を消費してしまいました。
これは人生の損失です。二度と同じことに引っかからないよう備忘録を残しておきます。

AmazonのクーポンはAmazon.jpが販売する商品にしか適用できない!

最近Amazonでは割引クーポンなんかも配っているようですが,そっちではなく,N円分の金券のような扱いのクーポンのことです。

例えば最近はこんなキャンペーンがやってますね
Amazon.co.jp: Amazon Student プライムビデオ視聴で2,000円クーポンプレゼント: 本

こういうので2000円とかもらってウキウキしてレジ行くと以下のようにエラーが出たりします。


「入力されたクーポン番号は、お客様のご注文にはご利用いただけません」
f:id:ossyaritoori:20170518220724p:plain

ふぁ?
f:id:ossyaritoori:20170518220828j:plain

公式の記述

これはきちんと公式に記述があって,
Amazon.co.jp ヘルプ: クーポンについて
「クーポンは、マーケットプレイスなど第三者によって売買、供給されるAmazon.co.jp の商品の購入にはご利用いただけません。」f:id:ossyaritoori:20170518222739j:plain


もう少しでっかく書いて欲しいものです。マーケットプレイスとは?って話は後でします。

Amazonの販売する商品を探すには?

ということで,Amazonが販売する商品からほしいものを選ばないとクーポンが使えないようです。
う~ん面倒だなぁ。ところでAmazonマーケットプレイスってなんでしょう?

Amazonマーケットプレイスとの違い

AmazonにはAmazonが直接販売している商品と他の会社や個人が出品している商品に2パターンがあります。
amazonマーケットプレイスでは後者の商品を扱っています。売り場のことなんですね。(直訳)

これは時々悪質な詐欺が行われているようで,とてつもなく安い値段だったり,レビューがおかしかったりした場合は敬遠したほうが良いらしいです。(自分はよく使います。安いので。)

Amazonの販売する商品を検索する方法

ガラケーの場合は
アマゾンで、「アマゾン販売」商品のみを表示させる方法は? - アマゾ... - Yahoo!知恵袋
が参考になりそうです。

PCの場合は次のURLなんかにアクセスしてこの詳細選択のダイアログで指定することが可能です。

Amazon.co.jp: 本
この図の右下。
f:id:ossyaritoori:20170518222201p:plain

なお,僕がこの方法で探せたのは本だけでした。(本のカテゴリになってるし)
f:id:ossyaritoori:20170518222714j:plain

ここにも情報はあります。「本以外も可能」とありますができなかったんだよなぁ。
Amazonが発送する商品のみを検索する方法 | トリセド


一応,Amazonが販売している商品にはその旨が記載されているので地味に探すもよしですが…
f:id:ossyaritoori:20170518223122p:plain



ていうかこれ公式がもっと周知したりUIを改善すれば済む話なのでAmazonさん頑張って改善してください~~。

GitHubで部分的にフォルダをダウンロードする方法(含Windows版)

最近ファイル管理でぼちぼちGitを使い始めていますが
Dropbox等,他のクラウドサービスとの違って他のPCからデータに簡単にアクセスできないのが面倒ですね。
Gitで管理するのはソースだけにすべきですが,フォルダ分離するの少し面倒くさい…

GitHubのWebサイトから単一のファイルをダウンロード

これは欲しいファイルをクリックして開く画面の右端に下のようにDownloadボタンが現れるので問題無いかと思います。
f:id:ossyaritoori:20170507140703p:plain

svnコマンドを用いた特定のディレクトリのダウンロード

Linuxならsvnコマンドを用いて,以下の様に落とせるようです。

例えば,以下のディレクトリにファイルが存在するとして,

https://github.com/XXX/YYY/tree/master/ZZZ

/tree/masterの部分を/trunkに書き換えて以下のコマンドを打ちます。

svn checkout https://github.com/XXX/YYY/trunk/ZZZ

svn exportでも良いとかなんとか。
しかし,これWindowsのGit Shellだと出来ないんですよね。

GitShell(Git for Windows)を用いた場合

GitShellを用いた場合は,svnコマンドはgit svnと打つことで模擬できます。
ただ,上のコマンドは登録されてないか,initが必要っぽいのでめんどくさそうです。

最も簡単なのは恐らくcloneしてしまうことでしょう。

git svn clone https://github.com/XXX/YYY/trunk/ZZZ

(当然,tree/masterをtrunkに変更することを忘れずに!)

cloneして出来たフォルダの処理

cloneして出来たフォルダですが,Gitの管理から外すには
以下のように.gitと書いてあるフォルダを削除します。
f:id:ossyaritoori:20170507142508p:plain