Posted on

PHPライブラリをPackagistに登録する方法

PHPのライブラリをPackagistに登録する方法を書いておきます。PackagistはPHPのパッケージリポジトリで、登録しておくとcomposerを使ってプロジェクトへインストールすることができます。ここではとあるプロジェクトをPackagistに登録する前提の流れで進めていきます。

Packagistに登録するプロジェクトを作成する

新規でプロジェクトを作成しcomposer initを実行します。

mkdir amazon-photo-formatter
cd amazon-photo-formatter
composer init

composer initを実行すると色々と聞かれるので順番に進めていきます。まずはパッケージ名が聞かれます。<vendor>にはGitHubのアカウント名を指定し、<name>にはライブラリ名を記載します。ここではtaisa831/amazon-photo-formatterと記載しました。

Package name (/) [taisa831/packagist]:

Descriptionはライブラリについての説明文なので、Format amazon photo file name to amazon photo's format.と書きました。その他についてもサジェストされている内容とするか必要な内容を決めて進めていきます。

Description []:
Author [Masaki Sato , n to skip]:
Minimum Stability []:
Package Type (e.g. library, project, metapackage, composer-plugin) []: library
License []: MIT

次にこのライブラリが依存しているものがあればこの時点で指定することができます(後から手動で記載することも可能)。ここではphpunitを利用するのでrequire-devphpunitを指定しました。

Would you like to define your dependencies (require) interactively [yes]? no
Would you like to define your dev dependencies (require-dev) interactively [yes]?
Search for a package: phpunit
Found 15 packages matching phpunit
   [0] phpunit/phpunit
   [1] phpunit/phpunit-mock-objects Abandoned. Use  instead.
   [2] phpunit/php-token-stream
   [3] phpunit/php-timer
   [4] phpunit/php-text-template
   [5] phpunit/php-file-iterator
   [6] phpunit/php-code-coverage
   [7] symfony/phpunit-bridge
   [8] phpunit/phpunit-selenium
   [9] johnkary/phpunit-speedtrap
  [10] codedungeon/phpunit-result-printer
  [11] jean85/pretty-package-versions
  [12] brianium/paratest
  [13] codeception/stub
  [14] spatie/phpunit-snapshot-assertions
Enter package # to add, or the complete package name if it is not listed: 0
Enter the version constraint to require (or leave blank to use the latest version):
Using version ^7.5 for phpunit/phpunit

そうすることで次のようなcomposer.jsonファイルができあがり、このままgenerateするか、composer installするかを聞かれるのでyesとして進めていきます。実行が終わったらプロジェクト直下にsrctestsディレクトリを作成しておきます。

{
    "name": "taisa831/amazon-photo-formatter",
    "description": "Format amazon photo file name to amazon photo format.",
    "type": "library",
    "license": "MIT",
    "authors": [
        {
            "name": "taisa",
            "email": "g5.taisa831@gmail.com"
        }
    ],
    "require": {},
    "require-dev": {
        "phpunit/phpunit": "^7.5"
    }
}
Do you confirm generation [yes]? yes
Would you like to install dependencies now [yes]? yes
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 28 installs, 0 updates, 0 removals
  - Installing sebastian/version (2.0.1): Loading from cache
  - Installing sebastian/resource-operations (2.0.1): Loading from cache
  - Installing sebastian/recursion-context (3.0.0): Loading from cache
  - Installing sebastian/object-reflector (1.1.1): Loading from cache
  - Installing sebastian/object-enumerator (3.0.3): Loading from cache
  - Installing sebastian/global-state (2.0.0): Loading from cache
  - Installing sebastian/exporter (3.1.0): Loading from cache
  - Installing sebastian/environment (4.1.0): Loading from cache
  - Installing sebastian/diff (3.0.2): Loading from cache
  - Installing sebastian/comparator (3.0.2): Loading from cache
  - Installing phpunit/php-timer (2.1.1): Loading from cache
  - Installing phpunit/php-text-template (1.2.1): Loading from cache
  - Installing phpunit/php-file-iterator (2.0.2): Loading from cache
  - Installing theseer/tokenizer (1.1.0): Loading from cache
  - Installing sebastian/code-unit-reverse-lookup (1.0.1): Loading from cache
  - Installing phpunit/php-token-stream (3.0.1): Loading from cache
  - Installing phpunit/php-code-coverage (6.1.4): Loading from cache
  - Installing doctrine/instantiator (1.1.0): Loading from cache
  - Installing symfony/polyfill-ctype (v1.10.0): Loading from cache
  - Installing webmozart/assert (1.4.0): Loading from cache
  - Installing phpdocumentor/reflection-common (1.0.1): Loading from cache
  - Installing phpdocumentor/type-resolver (0.4.0): Loading from cache
  - Installing phpdocumentor/reflection-docblock (4.3.0): Loading from cache
  - Installing phpspec/prophecy (1.8.0): Loading from cache
  - Installing phar-io/version (2.0.1): Loading from cache
  - Installing phar-io/manifest (1.0.3): Loading from cache
  - Installing myclabs/deep-copy (1.8.1): Loading from cache
  - Installing phpunit/phpunit (7.5.7): Downloading (100%)
sebastian/global-state suggests installing ext-uopz (*)
phpunit/php-code-coverage suggests installing ext-xdebug (^2.6.0)
phpunit/phpunit suggests installing phpunit/php-invoker (^2.0)
phpunit/phpunit suggests installing ext-xdebug (*)
Writing lock file
Generating autoload files

登録するライブラリを作成する

ここまででプロジェクトの形ができあがったのでsrc配下にソースファイルを作成します。今回は簡単なサンプルプログラムとしています。

.
├── composer.json
├── composer.lock
├── package-lock.json
├── vendor
├── src
└── tests
setCurrentDir($currentDir);
    }
    public function format()
    {
        $this->createFormatDir();
        $this->formatPictures();
    }
    public function createFormatDir()
    {
        if (file_exists('format') === false) {
            mkdir('format');
        }
    }
    /**
     * @throws \Exception
     */
    public function formatPictures()
    {
        foreach(glob($this->getCurrentDir() . '/{*.jpeg,*.jpg}', GLOB_BRACE) as $fileName) {
            if (is_file($fileName) === false) continue;
            $photoImg = file_get_contents($fileName);
            $ext = substr($fileName, strrpos($fileName, '.') + 1);
            $exif = @exif_read_data($fileName);
            $dateTime = new \DateTime($exif['DateTimeOriginal']);
            $formatFileName = $dateTime->format('Y-m-d_H-i-s');
            file_put_contents('./format/' . $formatFileName . '.' . $ext, $photoImg);
        }
    }
    /**
     * @return mixed
     */
    public function getCurrentDir()
    {
        return $this->currentDir;
    }
    /**
     * @param mixed $currentDir
     */
    public function setCurrentDir($currentDir)
    {
        $this->currentDir = $currentDir;
    }
}

unittestを作成する

続いて、`src`配下に先程作成したソースのテストを書いていきます。他の依存ライブラリを利用している場合は`bootstrap.php`ファイルも作成しておきます。

getMockBuilder(AmazonPhotoFormatter::class)
            ->setConstructorArgs([$dir])
            ->setMethods(null)
            ->getMock();
        $currentDir = $amazonPhotoFormatter->getCurrentDir();
        $this->assertEquals($dir, $currentDir);
    }
    public function test_format()
    {
        $amazonPhotoFormatter = $this->createPartialMock(AmazonPhotoFormatter::class, ['createFormatDir', 'formatPictures']);
        $amazonPhotoFormatter->expects($this->once())->method('createFormatDir');
        $amazonPhotoFormatter->expects($this->once())->method('formatPictures');
        $amazonPhotoFormatter->format();
    }
}

`bootstrap.php`を作成する場合はこんな感じ

<?php
error_reporting(E_ALL | E_STRICT);
require_once __DIR__ . '/../vendor/autoload.php';

これで`tests`配下で以下のコマンドを実行するとテストがいくつか実行されます。

../vendor/bin/phpunit AmazonPhotoFormatterTest.php
PHPUnit 7.5.7 by Sebastian Bergmann and contributors.
...                                                                 3 / 3 (100%)
Time: 51 ms, Memory: 4.00 MB
OK (3 tests, 3 assertions)

`phpunit.xml.dist`ファイルをプロジェクト直下に置いておくとプロジェクト直下で次のコマンドでも実行可能になります。

vendor/bin/phpunit
PHPUnit 7.5.7 by Sebastian Bergmann and contributors.
...                                                                 3 / 3 (100%)
Time: 25 ms, Memory: 4.00 MB
OK (3 tests, 3 assertions)


    
        
            ./tests/
        
    
    
        
            ./src/
        
    

Travis CIと連携する

Travis CIとGitHubのリポジトリを連携させ、以下のような.travis.ymlを作成しプロジェクト直下に配置することでgit pushした際にテストが実行されるようになります。

language: php
php:
  - 7.3
before_script:
  - composer self-update
  - composer install
script:
  - vendor/bin/phpunit

Packagistに登録する

作成したプロジェクトを自分のGitHubへアップしたら、Packagistへ登録をします。packagistにGitHubアカウントでログインした後、Submit 画面へ進み、登録したいリポジトリのURLを入力すると登録することができます。

GitHubとPackagistを連携する

最後にGitHubにプッシュしたらPackagistも自動的に更新するように連携しておきます。連携は、GitHubリポジトリのSettings>Webhooksから行うことができます。PackagistのプロフィールからAPI Tokenを取得しておき、GitHubのWebhooksへ次のように登録します。

  • Payload URL:https://packagist.org/api/github?username=[GitHubのユーザ名]
  • Content type:application/json
  • Secret:PackagistのAPI Token

ライブラリを使ってプロジェクトを作成してみる

ここまでで一通りの登録が完了したので、実際にプロジェクトから呼び出してみます。新規でプロジェクトを作成するには以下のコマンドを実行します。プロジェクト名の後ろにdev-master(masterブランチ)やGitHubのタグを指定することでバージョンを指定することが可能です。また、composer.jsonにライブラリ名とバージョンを記載してcomposer installして利用することも可能です。

composer create-project taisa831/amazon-photo-formatter project-name dev-master
composer create-project taisa831/amazon-photo-formatter project-name v1.0.0
{
    "name": "masakisato/testprj",
    "authors": [
        {
            "name": "taisa",
            "email": "g5.taisa831@gmail.com"
        }
    ],
    "require": {
            "taisa831/amazon-photo-formatter": "1.0.0"
    }
}
$ composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing taisa831/amazon-photo-formatter (v1.0.0): Loading from cache
Writing lock file
Generating autoload files

参考

Packagistに登録するのはもう怖くない

Posted on

PHPの empty, isset, is_null の違いをしっかり理解する

PHPの isset、empty、is_null をしっかり理解して使おうと思い整理してみました。既にこのような記事「PHP isset, empty, is_null の違い早見表」もあるのでここではこれより少し踏み込んだところまで書いてみます。

empty, isset, is_nullの違い早見表

if ($var) empty isset is_null
$var = 1 true false true false
$var = array(1) true false true false
$var = “” false true true false
$var = “0” false true true false
$var = 0 false true true false
$var = array() false true true false
$var = false false true true false
$var = NULL; false true false true
$var false true false true

まず表ですが、順番を理解しやすい形に変えてみました。下記のように赤と青のグループで分けて考えておくと理解しやすいです。これをみると「if ($var)empty」、「issetis_null」が対になっているのがわかります。

感覚的には、if ($var)は値がありそうだなと思うものがtrueになり、emptyも値がなさそうだな思うものがtrueになる感じがします。issetは、何かしら値がセットされてばtrue(つまり値がfalseでも結果はtrue)、is_nullは値がnullであればtrueということになります。
実際の挙動の動作確認についてはPHPUnitを使ってテストしたものをGitHubにあげているので合わせて確認してみてください。https://github.com/taisa831/AimaiPHP

empty, isset, is_null の Notice や Error 出力早見表

次に、PHPのerror_reportingE_ALLにした場合に、indexのない配列にアクセスした場合やオブジェクトが空の変数や関数にアクセスした場合の挙動をまとめてみました。

if ($var) empty isset is_null
$var = [];
$var[0];
Undefined offset: 0 true false Undefined offset: 0
$var = [];
$var[‘hoge’]
Undefined index: hoge true false Undefined index: hoge
$var = null;
$var[‘hoge’]
null true false null
$var = (object)[];
$var->var;
Undefined property: stdClass::$func true false Undefined property: stdClass::$func
$var = null;
$var->var;
Trying to get property of non-object true false Trying to get property of non-object
$var = (object)[];
$var->func();
Error: Call to undefined method stdClass::func() Error: Call to undefined method stdClass::func() 実行不可 Error: Call to undefined method stdClass::func()
$var = null;
$var->func();
Error: Call to undefined method stdClass::func() Error: Call to undefined method stdClass::func() 実行不可 Error: Call to undefined method stdClass::func()

結果は、上の表のようになりました。オブジェクトに対して未定義の関数にアクセスした場合やnullから関数を呼ぼうとした場合全てにおいてErrorになります。それ以外では、emptyissetを使うとNoticeは出でませんが、if ($var)is_nullを使うとNoticeがでるという違いがあります。この辺の違いを理解しておくとPHPによる開発が進めやすくなると思います。スマホだと表が切れてしまうので画像も貼っておきます。

Posted on

2019年の抱負

本業頑張るのはもとより、2019年の抱負がある程度固まってきたので書いておきます。

Google Cloud Platformを使う

これまでAWSを自分で多く触るケースはあまりありませんでしたが、GCPを使うケースが増えてきたので今年からはAWSではなくGCPをたくさん触っていこうと思います。

数学をやる

高校3年になるまでは大学行く気もなく全く授業をまともに受けていませんでした。高校2年の終わり頃に少しまじめに授業を受けるようになり、少しずつ数学が楽しくなってきた頃大学進学も視野に入ってきました。そんなときに自分が文系を選択していたことを知り、私立受験は英国社の三教科であることを知り(国立など受験の仕組みすら知らず)、そこで自分の数学学習人生は終わりました。そんなこんなで今までやってきたのですが、ふと最近以下の投稿をみてなんとなくやってみようかなと思いはじめました。記事のようにAIや機械学習の為ということも少しはありますが、自分としてはただの興味ですのでどこまでやれるかはわかりませんが、今小学中学の復習を終え数I・Aをちらちらみはじめています。
文系エンジニアが機械学習に入門するために小学校の算数から高校数学までを一気に復習してみました。

宅建をとる

今の本業が不動産テックということもありますが、これもただ興味が出てきたのでやってみようかなという感じです。宅建みやざき塾というYoutube動画が秀逸なので今はこの動画を移動中などにみています。

体力をつける

小さい子供が2人いると休日にランニングすることもままならないので去年は体重がかなり増えてしまいました。運動ができてないだけでなく、肩こりなど疲れやすい状態になっていたのでこれを今年は改善しようと思います。最近は食事や運動を気にしつつ「長生き味噌汁」をはじめました。

まとめ

どこに向かっているのかという感じはありますが、本業で事業を伸ばすことを頑張りつつこれらをやっていこうと思います。

Posted on

2018年振り返り、プレイングマネージャーは難しく

2018年は1月から正式に新しい環境で働き出した年になりました。また7月に2人目の子供が生まれたのも大きなイベントの1つとなりました。そんな中、個人としてはある程度やれたかなと思うところもありますが、逆に色々と反省することも多くあった年になりました。

主目標

業務として

業務として立てた目標は、今年1年で目安としていたところまで到達することができたように思います。ただその反面、目標に固執するあまり他のことに手が回らず結果的に周りに迷惑を掛けてしまいました。この点においては反省すべき点でしたが、昨年自分の活動していたことは今年につながることだと信じてやっていたことでもあるので、今年を大事にしていこうと思います。

CTOとして

選択と集中

7月に2人目が生まれたことで1人目以上に個人の時間がなくなりました。なので2人目が生まれてから、まずはコミュニティ活動を抑えることにしました。また、業務でも自分のやることは限定していたつもりでしたが、それでもいつのまにか設計・レビュー・マネージメント・運用・外部連携等やることが増えていき上記にもあるように周りに迷惑をかけてしまいました。
プレイングマネージャーは難しい
前職でも現職でもやっていて毎回思うことですが、プレイングマネージャーは難しいです。クライアントと調整しながら、社内マネージメントしながらどちらにおいても自分がコードを書くことを並行して進めると、自分でもびっくりするようなイージーミスをしてしまったりします。こういう場合、自分が思っている以上に割り切って余裕をもってタスクをこなすのが必要なんだと思います。

速度と品質担保

速度と品質については、色々と考えた上で薄い自社フレームワークを導入しました。これ自体はよかったと思いますが、導入時に不具合を起こしてしまったこともあり、早い段階だったとはいえイケイケゴーゴーでいきすぎたなと反省しました。

チームビルディング

その時にあった開発体制をと思い、自分がスクラムマスター役をやり開発メンバーには開発に専念してもらうというゆるい感じのスクラムを導入しました。ただそれはチームにとっては逆効果(メンバーに開発タスクを丸投げのような形)になってしまいました。前職で最後1年間ガッチリスクラムでやっていたこともあり、同じ感覚で進めてしまっていたのがよくなかったです。リモートが多いというのもありますが、コミュニケーションは大事だなとあらためて思いました。

エンジニアリング

自分と後輩エンジニアだけでやっていたことですが、サブプロジェクト的に社内WebフレームワークをGitLab内で公開、社内ツールをGitHubに公開するなどの取り込みをしました。このような取り組みは好きで以前からやっていることで、効果が大きいことも多いので続けていこう思います。

学習技術は機械学習

今年からAIPyハンズオン勉強会を不定期で開催しました。参加人数は少ないもののなんとか4回程実施できたのでよかったと思います。
https://aipy.connpass.com/

ブログ継続

ブログは最低月1(年12投稿)、最高月2(年24投稿)以上が目標でしたが今年は18投稿にとどまりました。

英語でコミュニケーションできるように

この件は別投稿に書いたのでスキップします。

2018年の英語振り返り

毎年英語力向上を目指して何かしらやったりやめたりしていますが、今年の英語はどうだったかなと振り返ってみます。そもそも海外で働く予定もなく日々英語でコミュニケーションを取るという状況にはすぐにはならないのでゆるゆるとやっています。とはいえ年1で海外に行った時に簡単なコミュニケーションくらいはできるようになりたいというのが今年の目標でした。 今年は5月にシンガポールへ行きました。PyCon …

株に投資をする

年始めにやる予定でしたが、マイナンバーカードが紛失していて再発行手続きするまで時間があいてしまったため口座開設までにとどまりました。口座は楽天銀行、イオン銀行に開設しました。少しずつ資金を集めてやってみようと思います。

執筆

共著ではあるものの個人的には今年最大の取り組みとも言えるものでした。関係者には感謝です。

コニュニティ活動

今年は、マレーシアで開催されたPyCon APACに参加し、参加レポートをgihyoさんに寄稿することができました。

「PyCon APAC 2018 in Singapore」参加レポート

2018年5月31日(木)~6月2日(土)にかけて行われた「PyCon APAC 2018 in Singapore」。後半の2日間に行われたカンファレンスデイの様子やセッション以外の現地滞在の様子などを,当日参加したメンバーが2回にわたってお届けします。

まとめ

新しいことに挑戦することができたり色々失敗したりと多くのことが経験できた年になりました。また、業界関係ない人と飲むことが多く普通に色んな人と楽しく飲んだり遊んだりできたのも今までにない感じで楽しく過ごせました。今年も健康と安全第一になるだけ楽しくやっていきたいと思います。

Posted on

2018年の英語振り返り

毎年英語力向上を目指して何かしらやったりやめたりしていますが、今年の英語はどうだったかなと振り返ってみます。そもそも海外で働く予定もなく日々英語でコミュニケーションを取るという状況にはすぐにはならないのでゆるゆるとやっています。とはいえ年1で海外に行った時に簡単なコミュニケーションくらいはできるようになりたいというのが今年の目標でした。

PyCon APAC 2018の参加の為シンガポールへ

今年は5月にシンガポールへ行きました。PyCon APACへの参加は去年のマレーシアに続き二年目です。マレーシアに行った時はひたすら英語を聞き続けるのに疲れ果て、コミュニケーションもままならなかったのですが、今年は比較的余裕を持って聞いたりコミュニケーションをすることができた気がします。ただそれは話している人の英語の癖がたまたま少なかったからとかそういうのもあったかもしれないのでなんとも言えません。それでも今年は gihyo.jp に参加レポートを寄稿することができたのはよかったです。

「PyCon APAC 2018 in Singapore」参加レポート

2018年5月31日(木)~6月2日(土)にかけて行われた「PyCon APAC 2018 in Singapore」。後半の2日間に行われたカンファレンスデイの様子やセッション以外の現地滞在の様子などを,当日参加したメンバーが2回にわたってお届けします。

DMM英会話

DMM英会話は、去年マレーシア行った後に来年のシンガポールに向けてと思いはじめました。はじめは普段できない英語でのコミュニケーションができるというのがあって、ある程度時間をさいてやってましたが、通勤時間が長い、仕事がある程度忙しくなる、子供が2人になるというのがありシンガポール行った後に退会しました。ただそのおかげもあってか上記の通りシンガポールには比較的リラックスして望むことができました。

英会話

Podcast

今年もPodcastは「Talk Python To Me」だけ通勤中にだらだらと聞いていました。ここはスクリプトを全文公開してくれるので嬉しいです。来年は他の技術系Podcastも聞いてみようと思っています。

Talk Python To Me Podcast

Talk Python To Me is a podcast for developers who are passionate about Python. Learn about the language and related technologies.

語彙力

語彙力アップにはDuo 3.0を選びました。同期としてはCDがついてて例文を移動中に聞き流すことができるから。これまで色々試してみたけど単語帳で単語を覚えるのは日常的に英語を使わない人間にとっては厳しいものがあるのがわかったのでこれもだらだら聞き流せるものをチョイスしました。

英語ブログ

コミュニケーションをする機会がなくインプットばかりになってしまうので書くことで英語に慣れる為に英語でちょっとしたことを書くことをはじめました。これはほとんど書けていないので来年はもうちょっと書いていこうと思います。

たいさのライフログ – taisa’s life log

I’m Masaki Sato. 34 years old.I’m a engineer of cocolive.inc for about 4 years. It&#8217 …

まとめ

英語を使わない環境で英語を頑張るってのは無理があることがここ数年で分かってきたので、なんとなくモチベーションが湧いた時に少しずつ楽しみながらやっていき来たる将来に向けての準備をしていけたらなと思っています。

Posted on

申告と節税について整理した。税率?青色?白色?扶養控除?など

フリーランスではないけど確定申告する機会があったりと税金のことを考える機会が増えたので大分昔に買った「フリーランスを代表して 申告と節税について教わってきました。」という本を読み返しました。かなり昔の本ですが大きくは変わっていないと思うのでまだ大丈夫かなと思っています。ただ間違いがある可能性もあるのでその点はご注意ください。指摘も大歓迎です。税金については、その時理解した気になってもすぐ忘れてしまうので大事なところだけメモとして残しておきます。

フリーランスを代表して 申告と節税について教わってきました。 Amazonより

最終的な納税額はどのように決まるか

最終的な納税額は次のように決まります。
年の稼ぎ
売上(収入)- 経費 = 所得
税金の対象
所得 – 各種控除 = 課税所得
最終的な税額
課税所得 × 所得税率 = 納付税額

所得税の速算表
課税される所得金額 税率 控除
以下
195万円 5% 0
195万円 330万円 10% 97,500円
330万円 695万円 20% 427,500円
695万円 900万円 23% 636,500円
900万円 1800万円 33% 1,536,000円
1800万円 40% 2,796,000円

ここで初めて知ったのが、所得に応じて税率はあがっていきますが、限度額を超えた分だけがその税率で納税する対象になるという仕組みでした。つまりそれが「控除」に該当するもの。少し控除はあるものの課税所得の限度額を超えたら全ての所得がその税率で計算されると思ってました。どういうことか具体例をあげてみます。

課税される所得金額が200万円の場合

5%までの金額を計算
195万円 × 5% = 97,500円
10%になった分の金額を計算
5万円 × 10% = 5,000円
5%までのと10%分の金額を足す
97,500円 + 5,000円 = 102,500円
所得金額が200万円の場合は、195万円を超えた5万円分んだけ税率が10%になり、納税額は102,500円となります。これは単純に以下のように控除額を引く計算方法でやっても同じ結果となります。
単純に計算して後から控除額を引く
200万円 × 10% – 97,500 = 102,500円
じゃあ税率があがった場合はどうなるの?というのが疑問になったので同じように計算してみました。

課税される所得金額が340万円の場合

順番に計算した場合(10%の控除額を引く)
330万円 × 10% + 10万円 * 20% – 97,500円 = 252,500円
単純に計算して後から控除額を引いた場合
340万円 × 20% – 427,500円 = 252,500円
このように計算してみるとどちらの計算方法でも金額は同じになりました。同様に他のケースもやってみます。

課税される所得金額が700万円の場合

順番に計算した場合(20%の控除額を引く)
695万円 × 20% + 5万円 × 23% – 427,500円 = 974,000円
単純に計算して後から控除額を引いた場合
700万円 × 23% – 636,500円 = 973,500円
何故か500円の差分が出てしまったのですが大体同じになりました。

課税される所得金額が910万円の場合

順番に計算した場合(23%の控除額を引く)
900万円 × 23% + 10万円 × 33% – 636,500円 = 1,466,500円
単純に計算して後から控除額を引いた場合
910万円 × 33% – 1,536,000円 = 1,467,000円
何故か500円の差分が出てしまったのですが大体同じになりました。

課税される所得金額が1810万円の場合

順番に計算した場合(33%の控除額を引く)
1800万円 × 33% + 10万 × 40% – 1,536,000円 = 4,444,000円
単純に計算して後から控除額を引いた場合
1810万円 × 40% – 2,796,000円 = 4,444,000円
つまり納付税額で所得税率を算出してそこから控除額を引くだけで最終納税額が算出できます。

税金の色々

税金といっても様々な税があるので主なところを取り上げておきます。

所得税

所得税は上記で記載した通りですが、支払うタイミングが住民税とは違うので注意が必要です。所得税は年末調整または確定申告にてその年1年の納税額を確定し納税します。

住民税

住民税はその年の納税額の10%を翌年に支払う形となります。税率は一律10%で都道府県民税:4%、市町村区民税:6%という割合です。

消費税

消費税は売上が1千万円超えないと免税事業者となるので1千万円以下の場合は気にする必要がありません。

社会保険

社会保険は基本的に以下のようになります。

  • 会社員:健康保険、厚生年金(会社が半分負担してくれる)
  • フリーランス:国民健康保険、国民年金

健康保険のメリット

  • 傷病手当金

病気や怪我によって働けなくなった場合、標準報酬月額の2/3(交通費や残業代も含む)が最大1年6ヶ月受け取れる

  • 被扶養者も無料で社会保険に入れる

年間収入が130万未満であれば被扶養者として無料で旦那の保険に加入することができる
参考:健康保険・厚生年金保険料の金額の推移「平成30年4月分(5月納付分)からの健康保険・厚生年金保険の保険料額表」
平成30年4月分(5月納付分)からの健康保険・厚生年金保険の保険料額表

青色か白色か

白色申告は青色の簡易簿記とほとんど違いがないので「10万円の控除」が受けられる青色の簡易簿記にしない手はないようです。65万円の控除が受けられる複式簿記になるにはいくつか条件があるようです。

扶養控除

扶養控除は主には150万円(前は103万円)の壁と130万円の壁があります。

  • 所得税の扶養控除限度額は150万円
  • 社会保険料の扶養控除限度額は130万円(一概に130万円というだけでなく月給88,000円以上など色々と別の条件があります)

所得税の扶養控除限度額は150万円の壁とは

150万円の壁の理由を書いておきます。給与所得控除を受ける人は誰でも必ず最低65万円は控除されます。なので控除される対象者は正しくは「合計所得金額が85万円以下(以前は38万円以下)」の人ということになります。

領収書は最低でも額面15%の金券

税率は最低でも5%で住民税の10%を加えると15%になります。領収書を経費として申請するとその分の納税額が減るので領収書の15%分は戻ってくることになります。課税所得が190万円の人が10万円分経費を上乗せできると課税所得は180万円になります。28万5千円だったのが、27万円になります。つまり10万円の15%である1万5千円が浮くことになります。こう考えてみるとわかりやすくこれはなるほどと思いました。
また、領収書は必ず領収書でなくてもレシートでも伝票処理でもよく何に使ったかがわかればよいようです。(レシートは消えちゃったりするのでそういう意味で良くなかったりはする)

まとめ

ここ最近は個人で確定申告することが出てきて、知らないだけで損したりビクビクしたくないなと思い読み返しました。当時読んだ時はなんとなくスルーしていたことが今読んでみるとなるほどーということが沢山ありました。

Posted on

Rust+WebAssembly で Hello, World!

以前 Rust をはじめてみよう!という記事を書いた。今回は Rust + WebAssembly を使って Hello, World!の出力をやってみた。

WebAssembly について

まず WebAssembly とは何か。本家サイトの Overview をみてみる。ここにある通り、WebAssembly(WASM)は C/C++/Rust などの高級言語を使って開発をしバイナリ形式で動かすことができる。その為 Web 上で高速に動かすことができる。とりわけゲームなどの実行速度が求められるような分野で有効になる。Chrome、Firefox、Safari、Edgeで利用が可能。

WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.
https://webassembly.org/

よくデモに出てくる Unity を使った動画
https://webassembly.org/demo/Tanks/

Youtube動画

再生回数が一番多い動画をあげておく。2018年2月の動画ですごく分かりやすく説明されている。

Rust+WebAssembly のドキュメント

ここからは以下の記事を実際にやってみる。実際にほぼそのまま実行しているだけなので以下についてはリンクをチェックするだけでも良いです。
https://rustwasm.github.io/book/game-of-life/hello-world.html

事前準備

参考URL:https://rustwasm.github.io/book/game-of-life/setup.html

rustup を使って rust をインストールする

curl https://sh.rustup.rs -sSf | sh
source $HOME/.cargo/env

source $HOME/.cargo/envは .zshrc などに記述しておくとよい

wasm-pack インストール

wasm-pack を使うとビルド・テスト・公開などが簡単にできる

curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh

cargo-generate インストール

cargo-generate を入れるとcargo generateコマンドが使えるようになり、この後の Git リポジトリからのソース取得ができる

cargo install cargo-generate

npm インストール

最新の npm を入れておく

npm install npm@latest -g

サンプルプロジェクトのテンプレート

Hello, World!のサンプルプロジェクトを取得する

cargo generate --git https://github.com/rustwasm/wasm-pack-template
// プロジェクト名を聞かれるのでここはドキュメントの通り`wasm-game-of-life`とする

ドキュメントツリーは以下のようになる。ドキュメントにはないtestsが追加されていた。ここでsrc/lib.rsgreet関数の文字列が、Hello, wasm-game-of-life!となっているので一応Hello, World!と変えておく。

wasm-game-of-life
├── Cargo.toml
├── LICENSE_APACHE
├── LICENSE_MIT
├── README.md
├── src
│   ├── lib.rs
│   └── utils.rs
└── tests
    └── web.rs

wasm-packコマンドでビルドしてみる。rustcのバージョンが1.30以上でないとエラーが発生するけどrustup updateコマンドでアップデートすれば問題なく進められる。

wasm-pack build
| [1/9]   Checking `rustc` version...
Your version of Rust, '1.29', is not supported. Please install Rust version 1.30.0 or higher.

rustupを使ってrustcをアップデートする

rustup update

ビルドが完了するとpkgディレクトリができる

wasm-pack build
pkg
├── README.md
├── package.json
├── wasm_game_of_life.d.ts
├── wasm_game_of_life.js
└── wasm_game_of_life_bg.wasm

Webページを作成する為に以下のコマンドを実行する。するとあらたにwwwディレクトリができる。

npm init wasm-app www
npx: 1個のパッケージを3.137秒でインストールしました。
 Rust +  Wasm = ❤

wwwのドキュメントツリー

www
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── bootstrap.js
├── index.html
├── index.js
├── package-lock.json
├── package.json
└── webpack.config.js

wwwディレクトリへ移動し依存関係をインストールする

npm install

pkgディレクトリへ移動し以下のコマンドを実行する

npm link
/usr/local/lib/node_modules/wasm-game-of-life -> /Users/satomasaki/Dev/taisa/wasm-game-of-life/pkg

更にwwwディレクトリへ移動して以下のコマンドを実行する

npm link wasm-game-of-life
/Users/satomasaki/Dev/taisa/wasm-game-of-life/www/node_modules/wasm-game-of-life -> /usr/local/lib/node_modules/wasm-game-of-life -> /Users/satomasaki/Dev/taisa/wasm-game-of-life/pkg

index.jsimport箇所のhello-wasm-packwasm-game-of-lifeに更新する

import * as wasm from "wasm-game-of-life";
wasm.greet();

実行しページを開いてみるとHello, World!が表示される。

npm run start

ソースを少し変更してみる

wasm-game-of-life/src/lib.rsgreet関数を以下のように少し変更しwasm-game-of-life/www/index.jsgreet関数の引数に文字列を入れてみると渡した文字列が出力される

#[wasm_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, {}!", name));
}
wasm.greet("wasm!");

Webサーバを立ち上げたままでもwasm-pack buildと実行するだけでソースが更新され動作確認をすることができる。

まとめ

本当に少し触っただけながら、便利なツールがちゃんとあって、ある程度形ができて慣れてくればそれほどストレスなく開発が進められそう。

Posted on

平成最後にEvernoteの昔のエモい感じのメモ達を供養する

今年、持ってる本をすべてリサイクルに出した。そして今や自分の荷物はほとんどないと言っていいくらい無くなった。情報も整理したくなったのでとりあえずEvernoteに残ってるよくわからないメモ達も消してみた。すると昔悶々としてたんだな〜みたいなメモが見つかった。折角だからそんな昔のエモい感じのメモ達をさらしてから削除する。

SI会社に残らない理由

近い将来移民が大量に入ってくる
その頃には課長または部長になっている程度
エンジニアとして対応できるようになってたい
求心力がない
名前だけでかくて組織が時代についていけていない
40代以上の人間がぎりぎり、50代以上の人間は定年を待つばかり
使えない派遣が集まる
会社自体に魅力がない
優秀な人材は入ってこないし出ていく

君がオヤジになる前に

一週間に一本アプリリリース
モテル
家を持つリスク
結婚するリスク
オヤジ化が加速する
子供にいい思いをさせることはそこまで必要か
狭い家に住んでいた時代も経験していてよいのでは?
そのような体験が逆にうらやましかったこともある。
情報量
突き抜けること
保険には入らない
何十年先のことを憂う必要があるのか
気持ち悪い昔からの風習がある
昔の美徳は今の美徳ではない
英語はのりで


「君がオヤジになる前に」という本を読んだ時のメモとその時に感じがことが書いてあると思われる

『今はまだ』という呪文

起業時代
今はまだ実力がないから
というがその気になれば実は一週間または一ヶ月死ぬ気でやればそれなりに戦える実力がつくのではないか
そういう人間に限って本を買って終了ということがほとんど
何年かすればそれなりにできる自分になっていると思い込んでいる
SIer時代
同様に人材派遣をするSE業界でも、
今はまだ我慢してやってくれ。
そのうち景気が上向きになるときを待つ
今はまだ動き時でない
ではいつなのか?
周囲の人たち、親
今はまだやめとけ
とりあえず大手に入っておけ
『今はまだ』と『とりあえず』のダブルパンチ
とりあえずといって何十年も経過していくのが目に見えている
そしてかぶせるようにサラリーマンは我慢だと

戦わない人が多すぎる

Noと言えない日本人ニアルイコール
ただNoと言う必要があるのではなく、交渉しよう、戦おう
日本の政治も同様
いいカッコしいはやめよう
どうせいいカッコするのであれば我慢はやめよう、戦う姿を見せよう
部下に迷惑がかかる
さされそうになったら必死で抵抗するだろう
上司だろうが客であろうが頭が上がらない人であろうと関係ない
交渉しよう
交渉することを楽しもう
恋愛もそう
後からでは遅い、そのとき戦わなくては
その為に準備している必要があるだろう
また、急に戦場にたたされ先制攻撃を受けてしまったら
一旦保留して戦略を練ろう
体制を整えよう
少しだけでも有利にしよう
常に先制攻撃ができるようにしよう
リスクを回避しよう
最悪の事態を避けよう
アラームをあげよう

人生の命題

世界中でアプリケーションを作る
世界をアプリケーションを作りしながらまわる

超解釈

変化に対応していく対応力
対応していくしかない
変化は能力のあるひとがやるのさ
他にはないものをつくる
もしくは他にあるもののコピーをつくる

無題ノート

ふけとか、衰えとか、関係、かいもん、ねー!
いずれのメモも平成22年〜26年くらいに書かれたメモだった。
平成最後にこれらのメモ達をここに供養します。

Posted on

Rust をはじめてみよう!

Rust をはじめてみよう!ということで Rust をはじめてみました。

Rust ってなに?

Rust言語は速度、並行性、安全性を言語仕様として保証するC言語、C++に代わるシステムプログラミング(英語版)に適したプログラミング言語を目指している[4]。2006年の開発初期はグレイドン・ホアレの個人プロジェクトだったが、2009年にMozillaが開発に関わり始めてMozilla Researchの公式プロジェクトとなった
参考 : Rust (プログラミング言語) – Wikipedia

また、公式ドキュメントが充実しているのでそちらをみれば大体分かるようになっています。

特徴

  • ゼロコスト抽象化
  • ムーブセマンティクス
  • 保証されたメモリ安全性
  • データ競合のないスレッド
  • トレイトによるジェネリクス
  • パターンマッチング
  • 型推論
  • 最小限のランタイム
  • 効率的なCバインディング

インストール

rustup を使ってインストールします。

$ curl https://sh.rustup.rs -sSf | sh

実行すると以下のように言われるので設定を反映させます。

To get started you need Cargo's bin directory ($HOME/.cargo/bin) in your PATH
environment variable. Next time you log in this will be done automatically.
To configure your current shell run source $HOME/.cargo/env
$ cargo
command not found: cargo
$ source $HOME/.cargo/env
$ cargo --version
cargo 1.29.0 (524a578d7 2018-08-05)

rustc というのコンパイラもインストールされます。

$ rustc --version
rustc 1.29.1 (b801ae664 2018-09-20

rustc を使って Hello, World!

まずは rustc を使って Hello, World! を実行してみます。


$ mkdir hello_rust
$ cd hello_rust
$ vi hello.rs
fn main() {
    println!("Hello, world!)
}

ファイルを作成したら rustc を使ってコンパイルし実行すると 「Hello, world!」 が出力されます。

$ rustc hello.rs
$ ./hello
Hello, world!

Cargo を使って Hello, world!

実際のプロジェクトでは Cargo というパッケージマネージャーを使っていくことになると思います。Cargo を使って新しくプロジェクトを作成してみます。

$ cargo new hello_cargo
Created binary (application) `hello_cargo` project

ディレクトリツリーは以下のようになっています。

hello_cargo
├── Cargo.toml
└── src
    └── main.rs

Cargo.toml ファイルがパッケージを管理するファイルです。

[package]
name = "hello_cargo"
version = "0.1.0"
authors = ["taisa "]
[dependencies]

デフォルトでは main.rs に 「Hello, world!」 を出力する実装がされているのでそのまま実行してみます。build コマンドはコンパイルのみで、run コマンドはコンパイルと実行が行われます。

# コンパイル
$ cargo build
   Compiling hello_cargo v0.1.0 (file:///Users/satomasaki/Dev/taisa/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 1.99s
# コンパイルと実行
$ cargo run
   Compiling hello_cargo v0.1.0 (file:///Users/satomasaki/Dev/taisa/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 1.33s
     Running `target/debug/hello_cargo`
Hello, world!

cargo は test コマンドも備えていて、test を実行することができます。(test 自体が存在しないのですべて0)

$ cargo test
   Compiling hello_cargo v0.1.0 (file:///Users/satomasaki/Dev/taisa/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 1.51s
     Running target/debug/deps/hello_cargo-666fd07beeac7bb5
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

サンプル集

Rust は公式ドキュメントが充実していてサンプル集などもあるので今後はそれらを参考にしてみます。
https://doc.rust-lang.org/rust-by-example/

Posted on

カンファレンスを最大限に楽しむ方法

Talk Python To Me という PodCast を聞いている中で興味深い話があった。

Talk Python To Me Podcast

Talk Python To Me is a podcast for developers who are passionate about Python. Learn about the language and related technologies.

Episode #161: Django 2.0 の 00:58:20〜のトーク内容で「カンファレンスを最大限に楽しむ方法は?」という質問に対する回答

まず第一に参加できるなら参加しましょう。もし US や北アメリカのカンファレンスに行けない場合は、ローカルで開催されているカンファレンスに参加しましょう。そしてもし参加したら友達とくつろぐのはやめて新しい友だちをつくりましょう。自分の視野を広げるために参加しているのだから。それが簡単でないことはわかります。でもそうすることで新しいアイデアやコネクションをつくることができて新しい視野がひろがります。そして、それができた場合でも自分の知識をみせびらかすようなことはやめて、そのかわりに質問をしましょう。そして私は、カンファレンスに参加してハイヤリングをした立場として分かりますが、知識があるひとよりもむしろ、新しいことを見つけ出して熱心に学ぼうとしている人を雇おうとします。
以前にカンファレンスに参加したことがある人もそうでない人も、カンファレンスのボランティアをやるのもよいです。ボランティアをする中で関係ができあがり、新しいコネクションができます。私はボランティアをすることで自分のキャリアの中で大きな変化を得ることができ、とても良い人で出会うきっかけになりました。恥ずかしいとか思うかもしれませんが、そんなことは誰も気にしてはいません。自分もとても恥ずかしいことをした経験があるけど誰も覚えてはいませんよ。
ソース:https://talkpython.fm/episodes/transcript/161/django-2.0

内容は意訳してる箇所や多少省略してる箇所があるので詳しく知りたい方はソースを見てください。この内容はトークする側ではなく単純に参加する側へ向けた話。
そしてある意味当たり前のような話ではある。ただ、恥ずかしがるとかそういった考えはなんとなく日本的もしくはアジア的なところがあるのかなと思っていたので、アメリカでもこういったことが話されてるんだなっていうところに興味が持てた内容でした。

話し手はこの方

Daniel Roy Greenfeld (@pydanny) | Twitter

The latest Tweets from Daniel Roy Greenfeld (@pydanny). Co-Author Two Scoops of Django (https://t.co/h98NETIALQ), open source coder, husband of @audreyr, former NASA coder. Los Angeles, CA