数年前に「ソフトスキル」という本を買って読んでブログを書くようにしました。
2000円ぐらいで買ったと思います。ブログの内容は日々業務で経験したソフトウェア開発の話が主でした。1年ぐらい続けた後にブログを見てくれた、とある企業からオファーをもらい転職することにしました。その時、投資した2000円+行動に対して数百倍収入が増えました。
この本に出会わない、または行動しなければ転職することもなかったでしょう。
読書をしてそこから得られたことを行動としてアウトプットしてみましょう。
数年前に「ソフトスキル」という本を買って読んでブログを書くようにしました。
2000円ぐらいで買ったと思います。ブログの内容は日々業務で経験したソフトウェア開発の話が主でした。1年ぐらい続けた後にブログを見てくれた、とある企業からオファーをもらい転職することにしました。その時、投資した2000円+行動に対して数百倍収入が増えました。
この本に出会わない、または行動しなければ転職することもなかったでしょう。
読書をしてそこから得られたことを行動としてアウトプットしてみましょう。
These are my photos taken in NYC in 2014. I posted these photos to Flickr and re-post here. Because I like these photos and Flickr will change the plan for free users, and my photos over 1000 will be deleted. So I deleted my Flickr's account and moved here for now.
Cloud Deployment Managerでプロビジョニングするとき、エラー表記で少しハマったところについてメモ。
Cloud Storageをプロビジョニングするとき以下のようなエラーが出ることがあります。
$ gcloud deployment-manager deployments create example --config vm.yaml The fingerprint of the deployment is YjuHda-HR8_aaaaaaaaaaa== Waiting for create [operation-1549936918163-581a8cf6e71ac-aaaaaaaa-3f20fe82]...failed. ERROR: (gcloud.deployment-manager.deployments.create) Error in Operation [operation-1549936918163-581a8cf6e71ac-aaaaaaaa-3f20fe82]: errors: - code: RESOURCE_ERROR location: /deployments/batch/resources/example message: '{"ResourceType":"gcp-types/cloudfunctions-v1:projects.locations.functions","ResourceErrorCode":"500","ResourceErrorMessage":"Failed to retrieve function source code"}' - code: RESOURCE_ERROR location: /deployments/batch/resources/image message: '{"ResourceType":"gcp-types/storage-v1:buckets","ResourceErrorCode":"403","ResourceErrorMessage":{"code":403,"errors":[{"domain":"global","message":"example@cloudservices.gserviceaccount.com does not have storage.buckets.get access to image.","reason":"forbidden"}],"message":"example@cloudservices.gserviceaccount.com does not have storage.buckets.get access to image.","statusMessage":"Forbidden","requestPath":"https://www.googleapis.com/storage/v1/b/image","httpMethod":"GET","suggestion":"Consider granting permissions to example@cloudservices.gserviceaccount.com"}}'
does not have storage.buckets.get access to image.","statusMessage":"Forbidden" や Consider granting permissions to example@cloudservices.gserviceaccount.com と言われるので、普通に考えるとパーミッションかなと思いサービスアカウントの権限を確認しますが十分な権限が付与されていました。
結論としては、作成しようとしているバケットの名前が他のユーザーのバケット名と被っているためです。バケットの名前は全てのユーザーでユニークな名前にする必要があります。
当たり前ですが作成しようとしているバケットが自分のものではない場合、そのバケットにアクセスする権限はありません。なので、does not have storage.buckets.get access to image のような表記になっています。
カバーといっても書店の店員さんが後からつけてくれるやつではなくて、初めから付いている値段やバーコードが書かれているカバーです。
本を読むときに邪魔になっていたのでなぜ必要なのか以前から気になっていました。
「本を汚れから守る」ようなことを見かけましたが、出典元を探せていませんでした。多分それっぽいとは思っていましたが。
それについて、先日たまたま読んだ「出版」に記載がありました。
p.52
カバーの存在理由。それはひとつに、「取り替えられる」からである。
間違いなさそうです。
取り替えのサイクルとして
の流れがあるようです。カバーがあるおかげで、汚れた本を処分することなく新品として書店に戻るわけです。
また、取次に戻らずに出版の営業の人が書店でカバーだけを変えていくパターンもあるようです。
ちなみにカバーも編集の人に依頼された(出版に所属するか外部の)デザイナーさんが考えて作ってくれたものなので、捨てるときはその辺を思い出してみるといいかもしれません!
PythonでgRPCを扱う方法です。クライアント側だけの紹介です。
Protocol Buffersの定義ファイルを用意します。
crawl.proto
syntax = 'proto3'; package proto; service Crawler { rpc Crawl(CrawlRequest) returns (CrawlResponse); } message CrawlRequest { string url = 1; } message CrawlResponse { string content = 2; }
Protocol Buffersの定義ファイルを、Pythonのソースファイルにコンパイルします。
以下のコマンドを実行します。
$ protoc -I=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/crawl.proto
$SRC_DIR
: protoファイルがあるディレクトリ
$DST_DIR
: コンパイルしたソースファイルの保存先
crawl_pb2.py
とcrawl_pb2_grpc.py
のファイルが生成されます。
生成されたPythonのファイルを利用してgRPCのサーバーに対してリクエストします。
import grpc from crawl_pb2_grpc import CrawlerStub from import CrawlRequest def crawl(url): channel = grpc.insecure_channel('localhost:50005') crawl_request = CrawlRequest(url=url) # リクエストで送るデータの生成 stub = CrawlerStub(channel) result = stub.Crawl(crawl_request) # リクエスト print(result.content) # レスポンスのcontentを取得
ここではPython 3.7を使った方法を紹介します。
現時点の最新版であるUnicode® Emoji Charts v11.0では、絵文字のUnicodeは1F600から1F3F4の範囲でコードが振られています。
なので、Unicodeの範囲を指定すればいけるじゃんと思っていたのですが、絵文字についてはUnicodeが連番ではなかったので正規表現で範囲を指定した方法ができませんでした。WikipediaのUnicode表を参考に範囲を指定していますが、絵文字以外も判定されてしまいます。
以下がダメなサンプルコードです。
text = '今日はいい天気' if re.search('[\U00010000-\U0010ffff]|[\U000000A9-\U00003299]', text): print('found it!') else: print('not found')
ちなみに、新しい絵文字を扱うため \U
(UTF-32) を使っています。
上記のサンプルコードの範囲の間にはひらがななどの絵文字ではない文字が含まれているのでこのコードでは絵文字を判定できません。
いろいろ調べてみて最終的にemojiというライブラリが良さそうなのでこちらを使用しました。
import emoji def text_is_emoji(text): for c in text: if c in emoji.UNICODE_EMOJI: return True return False text = '今日はいい天気' if text_is_emoji(text): print('found it!') else: print('not found')
結果
not found
import emoji def text_is_emoji(text): for c in text: if c in emoji.UNICODE_EMOJI: return True return False text = '今日はいい天気☀️' if text_is_emoji(text): print('found it!') else: print('not found')
結果
found it!
半角カタカナのUnicodeはFF61からFF9Fまでの範囲が決まっていので簡単です。
以下は半角カタカナを判定するサンプルコードです。UnicodeのエンコーディングにはUTF-8を使います。
全角カタカナ
import re text = '今日はイイ天気' if re.search('[\uFF61-\uFF9F]', text): print('found it!') else: print('not found')
結果
not found
半角カタカナ
import re text = '今日はイイ天気' if re.search('[\uFF61-\uFF9F]', text): print('found it!') else: print('not found')
結果
found it!
Pythonの正規表現でUnicodeを扱うにはコードの前に \u
または \U
を使用します。
UTF-8の場合は \u
、UTF-32の場合は \U
を使います。詳しくは公式ドキュメントを参照してください。
絵文字に関してはUnicode® Emoji Charts v11.0のようにバージョンが振られていることからもわかるように、絵文字の数が年々増えています。なので、絵文字が正しく判定されているか適宜見直していく必要がありそうです。