iPhoneを自分で修理してみた。

自作PCを作れるくらいの人なら、簡単にできるかも。

妻が落としてしまい、バックカメラが不調になってしまったiPhone6s Plus。 妻がiPhone Xs Maxに新調し、お古として長男に渡ったのを機に、自分で修理してみました。

Amazonで、1400円の修理キットと5000円のカメラモジュールを購入し、いざ分解。 最大のハードルかなと思っていたフロントパネルの取り外しは、事前にドライヤーで温めてシールを柔らかくしておいたうえで、金属ヘラで少しずつ抉るようにしていくと、割と力をかけずに開くことができました。

あとは、ネットの情報を見て、然るべき手順で分解していき、カメラを交換。

組み立てた後に電源ONしたら、サウンドやバイブレーションは動いているけど、画面が真っ暗なままで一時は焦りましたが、強制再起動したら無事元通りになりました。 カメラも正常作動。

自分でiPhoneを修理できるようになったので、画面割れとかもう怖くなくなりました。

GoPro Heroのヒミツ

7月頃、以前から欲しいな〜と思っていたGoProのHPにアクセスしてみると、随分安いモデルが発売されているのに気がついて、早速購入。子供達の夏休みを撮影するのに役立ってくれました。

購入したのはHero(2018)と呼ばれる一番安いモデルです。その一つ上のHero5とは2万円ほどの価格差があります。 (なお、2018年9月、GoProの製品ラインナップが一新されて、Hero(2018)もHero5も在庫分のみとなっています。)

さてこのHero(2018)、ハードウェアは上位機種のHero5と全く同じで、ファームウェアの書き換えで、Hero(2018)をHero5にできる、という情報を掴みました。(Redditの記事) Youtubeにも実際にハッキングしてHero(2018)がHero5になった動画があり、どうやら本当のようです。 Hero(2018)は、Hero5の一部機能を、ソフトウェアで制限した製品だった、という訳です。

これは、おそらく、こういうことだと思います。

GoPro社は、以前からあるHero5の下位モデルを追加して、アクションカメラの新規ユーザ(僕のような)を取り込みたいという意向があった。 しかし、新モデルの開発や、それ専用の製造ラインにはお金がかかる。それに比べ、ソフトウェアで一部機能を制限することなら、ごく安価で実現できる。 そこでHero5の機能制限版をHero(2018)として売り出した。

もちろん、Hero5の原価は、Hero(2018)の売価よりも安いものの筈です。 じゃあ、あっさりHero5を値下げすれば、新規ユーザーを獲得できるのでは、と思われるかもしれません。

しかし、市場には、「この機能・性能の製品なら、価格はこのくらい」とう値ごろ感があります。GoPro社はアクションカメラという市場を自ら作りだした会社であり、この値ごろ感に大きな影響を与えることが出来ます。Hero5を安価で販売すれば、短期的には新規ユーザを獲得できますが、値ごろ感を引き下げてしまい、長期的な利益の喪失に繋がります。ということで、今回のような手法を採用したのでしょう。

GoPro社にとって誤算だったのは、これがあっさりと見破られてしまったことと、これまたあっさりとハッキング方法が見つかってしまったことでしょう。

Pythonistaで自分専用RPN電卓を作る(04)

lambda関数を使って重複する処理をまとめる

pythonは関数を変数に代入することができます。

def add(x, y):
    return x+y

a = add

a(1, 2)

とすれば、

>>> 3

が得られます。これでも関数を変数に代入できますが、いちいち関数の定義が必要で、コードが長くなります。

a = lambda x, y : x+y
a(1,2)

>>>3

このようにlambda関数を使えば、より短く実現できます。

lambda関数をつかって処理をまとめたRPN電卓のコア部分は以下のようになります。

class RPN():
    _stack = []

    def push(val):
        RPN._stack.append(val)

    def pop():
        return RPN._stack.pop()

    def _calc(op):
        y = RPN._stack.pop()
        x = RPN._stack.pop()
        z = op(x, y)
        RPN._stack.append(z)
        return

    def add():
        RPN._calc(lambda x, y: x+y)
        return

    def sub():
        RPN._calc(lambda x, y: x-y)
        return

    def mul():
        RPN._calc(lambda x, y: x*y)
        return

    def div():
        RPN._calc(lambda x, y: x/y)
        return

前回のコードでは、例えば'a+b'を計算する際、aはスタックの一番上からとってきて、bは関数の引数として与えていました。 今回、_calc()を設計する際、引数に性質の異なるものを混在させるのが嫌だったので、引数としてはlambda関数だけ渡し、演算する値(a+bのうち、aとb)は、スタックからとってくるようにしました。

Pythonistaで自分専用RPN電卓を作る(03)

重複した処理について

四則演算の機能は実現できましたが、それぞれの関数で同じコードが繰り返されています。 四則演算だけならまだマシですが、今後計算機能を拡充していくと、どんどんコードが汚くなってしまいそうです。

今のうちになんとかします。

class RPN():
    _stack = []

    def push(val):
        RPN._stack.append(val)

    def pop():
        return RPN._stack.pop()

    def add(val):
        x = RPN._stack.pop()
        y = x+val
        RPN._stack.append(y)
        return y

    def sub(val):
        x = RPN._stack.pop()
        y = x-val
        RPN._stack.append(y)
        return y

    def mul(val):
        x = RPN._stack.pop()
        y = x*val
        RPN._stack.append(y)
        return y

    def div(val):
        x = RPN._stack.pop()
        y = x/val
        RPN._stack.append(y)
        return y

演算機能を実現する関数は、

順番 処理
(1) スタックから数値を取り出す
(2) 計算する
(3) 計算結果をスタックに格納
(4) 返値を返す

という構造になっていて、(2)の計算処理だけが異なります。 これを関数外部から切り替えることができれば、重複する処理を1つの関数にまとめることができます。

調べてみると、lambda関数でこれが実現できそうなことが分かりました。

Pythonistaで自分専用RPN電卓を作る(02)

四則演算機能を追加

スタックに四則演算機能をつけて、RPN電卓への一歩を踏み出します。

class RPN():
    _stack = []

    def push(val):
        RPN._stack.append(val)

    def pop():
        return RPN._stack.pop()

    def add(val):
        x = RPN._stack.pop()
        y = x+val
        RPN._stack.append(y)
        return y

    def sub(val):
        x = RPN._stack.pop()
        y = x-val
        RPN._stack.append(y)
        return y

    def mul(val):
        x = RPN._stack.pop()
        y = x*val
        RPN._stack.append(y)
        return y

    def div(val):
        x = RPN._stack.pop()
        y = x/val
        RPN._stack.append(y)
        return y

スタックの一番上にある値を取り出し、引数で受け取った値と計算し、その結果をスタックに戻します。 残りの演算も、計算式が異なるだけで、あとは同じです。

Pythonistaで自分専用RPN電卓を作る(01)

RPN電卓アプリは数が少なくて、自分にあったものがない…。 ないなら作ってしまおう。

Pythonistaとは

こちらのBlogに詳細があります。参考にさせて頂きました。

iOS上で動作する革命的ものづくり環境「Pythonista 3」の魅力をとくと語る

まずはコアの構造を作ってみる

A級B型C++入門という本で、行き当たりばったりにコードを修正しながら仕上げていくやりかたを、B型人間のプログラミングと呼んでました。

それでいうと、僕は正にB型プログラマーです。

まずは、RPN電卓のコア構造になるスタックを作ってみます。Pythonではリストを使えば、あっという間です。 C言語の時代を知る人間としては、感動的な簡単さです。

class RPN():
    _stack = []

    def push(val):
        RPN._stack.append(val)

    def pop():
        return RPN._stack.pop()

スタックの中身は外部からいじるものではないので、アンダースコア"_"をつけてプライベート変数、ということにしました。 Pythonにはアクセス制限の機能はなく、アンダースコアをつけても、実際には外部から参照できてしまうのですが、「アンダースコアで始まる変数はプライベート変数」というお約束と周知して、擬似的にアクセス制限のを実現しているそうです。 C++のように、いちいちPublicだ、Privateだと指定してるのに、デバッグのためにPrivate変数を覗くためだけの関数をわざわざ書いて…といったことを経験した身からすると、エレガントな解決方法だな〜と思います。