Skip to content

Instantly share code, notes, and snippets.

@yuq-1s
Last active September 29, 2021 09:28
Show Gist options
  • Save yuq-1s/4328eed4e03cd52fb5432b26c93974ce to your computer and use it in GitHub Desktop.
Save yuq-1s/4328eed4e03cd52fb5432b26c93974ce to your computer and use it in GitHub Desktop.
Comparing income of Beijing and Singapore.
import sys
import fire
class Beijing:
max_base = 28221
min_base = 5360
def __init__(self, total):
self.total = total
def wuxianyijin(self):
base = max(min(self.max_base, self.total / 12), self.min_base) * 12
xian = base * (0.08 + 0.005 + 0 + 0.02 + 0)
jin = base * 0.12
cost = xian + jin
return cost, jin
def tax(self):
cost, jin = self.wuxianyijin()
taxable_income = self.total - cost - jin
return self.do_tax(taxable_income)
def do_tax(self, money):
if money <= 60000:
return 0
money -= 60000
if money <= 36000:
return money * 0.03
elif money <= 144000:
return money * 0.1 - 2520
elif money <= 300000:
return money * 0.2 - 16920
elif money <= 420000:
return money * 0.25 - 31920
elif money <= 660000:
return money * 0.3 - 52920
elif money <= 960000:
return money * 0.35 - 85920
else:
return money * 0.45 - 181920
def run(self):
cost, jin = self.wuxianyijin()
tax = self.tax()
daoshou = self.total - cost - tax
jin *= 2
# return {'total': self.total, 'daoshou': daoshou, 'daoshou+jin': daoshou + jin, 'jin': jin, '5xian': cost, 'tax': tax}
return {'税前': self.total, '到手': daoshou, '到手+买房钱': daoshou + jin, '公积金': jin, '五险': cost, '个税': tax}
class Singapore:
conv = 4.778
def __init__(self, total, num_xin, has_cpf):
self.total = total / self.conv
self.num_xin = num_xin
self.has_cpf = has_cpf
assert self.num_xin >= 12
def cpf(self, money):
ow_ceiling = 6000
monthly = self.total / self.num_xin
ow = min(monthly, ow_ceiling)
total_cpf = ow * 12 * 0.37 + (self.num_xin - 12) * monthly * 0.37
return total_cpf * (0.2 / 0.37), total_cpf * (0.23 / 0.37)
def do_tax(self, money):
'''
>>> sg = Singapore(4, 14, False)
>>> round(sg.do_tax(20000))
0
>>> round(sg.do_tax(10000))
0
>>> round(sg.do_tax(30000))
200
>>> round(sg.do_tax(40000))
550
>>> round(sg.do_tax(50000))
1250
>>> round(sg.do_tax(80000))
3350
>>> round(sg.do_tax(120000))
7950
'''
total_tax = 0
steps = [20000, 10000, 10000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 99999999999]
rates = [0., 0.02, 0.035, 0.07, 0.115, 0.15, 0.18, 0.19, 0.195, 0.20, 0.22]
for step, next_step, rate in zip(steps[:-1], steps[1:], rates):
if money >= step:
total_tax += step * rate
money -= step
else:
break
return total_tax + money * rate
def _run(self):
taxable_income = self.total
if self.has_cpf:
paied_jin, got_jin = self.cpf(self.total)
taxable_income -= paied_jin
else:
paied_jin, got_jin = 0., 0.
tax = self.do_tax(taxable_income)
daoshou = self.total - tax - paied_jin
# return {'total': self.total, 'daoshou': daoshou, 'daoshou+jin': daoshou + got_jin, 'tax': tax, 'jin': paied_jin, '5xian': got_jin / 0.23 * 0.14}
return {'税前': self.total, '到手': daoshou, '到手+买房钱': daoshou + got_jin, '个税': tax, '交的CPF': paied_jin, '非买房CPF': got_jin / 0.23 * 0.14}
def run(self):
return {k: v * self.conv for k, v in self._run().items()}
def main(total: int, place: str, num_xin: int = 14, has_cpf: bool = False):
table = {'bj': Beijing(total), 'sg': Singapore(total, num_xin, has_cpf)}
print(table[place].run())
'''
$ python income.py --total=481622.39999999997 --place=bj
{'税前': 481622.39999999997, '到手': 361148.83499999996, '到手+买房钱': 442425.31499999994, '公积金': 81276.48, '五险': 76196.70000000001, '个税': 44276.86499999999}
$ python income.py --total=481622.39999999997 --place=sg
{'税前': 481622.39999999997, '到手': 454187.12399999995, '到手+买房钱': 454187.12399999995, '个税': 27435.275999999998, '交的CPF': 0.0, '非买房CPF': 0.0}
$ python income.py --total=481622.39999999997 --place=sg --has_cpf
{'税前': 481622.39999999997, '到手': 381118.12559999997, '到手+买房钱': 476066.54159999994, '个税': 17940.434400000002, '交的CPF': 82563.84, '非买房CPF': 57794.688}
'''
if __name__ == '__main__':
import doctest
doctest.testmod()
fire.Fire(main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment