Create a command line tool to convert dollars to yen using Python

Overview

  1. Get a list of rates from the Exchange Confirmation API (http://api.aoikujira.com/kawase/)
  2. Convert the value received as a command line argument from dollar to yen
$ brew tap kei-sato/usdex
$ brew install usdex
$ usdex -p 2.5 -v
1(USD) => 122.54078(JPY)
2.5(USD) => 306.35195(JPY)

Gist is here https://gist.github.com/kei-sato/98675769952ec7538d6a

Here's how to enable brew install Allow brew install of command line tools made in Python

Commentary

The current exchange information is published in various formats including JSON (http://api.aoikujira.com/kawase/). There was a person, so I used this to create a command to convert dollars to yen from the command line. First, check the value returned from the API.

$ curl -s http://api.aoikujira.com/kawase/json/usd | jq .
{
  "result": "ok",
  "basecode": "USD",
  "update": "2015-07-13 17:41:44",
  "source": "*",
  "API_URL": "http://api.aoikujira.com/kawase/",
  ...(Omission)
  "JPY": "123.44644",
  "KRW": "1131.46557",
  "HKD": "7.75138",
  ...(Omission)
  "LBP": "1514.20449"
}

You can see that JPY contains the value of 1 dollar converted into yen. (There are also KRW (won) and HKD (Hong Kong dollar)) For the time being, let's write a simple script that just extracts this value and multiplies it by the number given as an argument.

exchange1.py


#coding:utf-8

import sys
import urllib
import json

URL = "http://api.aoikujira.com/kawase/json/usd"

if __name__ == "__main__":
    price = float(sys.argv[1])

    response = urllib.urlopen(URL)
    data = json.loads(response.read())
    rate = float(data[u'JPY'])
    print "{0}(USD) => {1}(JPY)".format(1, rate)
    print "{0}(USD) => {1}(JPY)".format(price, price * rate)
$ python exchange1.py 2.5
1(USD) => 122.568(JPY)
2.5(USD) => 306.42(JPY)

Given 2.5 (dollars) as an argument, the answer was 306 yen. I'm also returning yen per dollar.

You have achieved your goal. That's it.

I'd like to go, but this time I want to publish it, so I'll make it a little better.

API hit prevention

It is not good to hit the API continuously, so I will try to access the API once a day.

import urllib
import json

URL = "http://api.aoikujira.com/kawase/json/usd"
FPATH = "/tmp/exchange"


def readCache():
    with open(FPATH, 'r') as f:
        body = f.read()
    return body


def writeCache(body):
    with open(FPATH, 'w') as f:
        f.write(body)


def fetchRates():
    # fetch rate list from remote
    response = urllib.urlopen(URL)
    body = response.read()

    writeCache(body)

    return body

Access the API with fetchRates and save the contents to a file with writeCache. Read the contents saved in the file with readCache.

import os.path
from datetime import date, datetime

FPATH = "/tmp/exchange"


def hasCache():
    if os.path.isfile(FPATH):
        d = date.today()
        today = datetime.combine(d, datetime.min.time())
        mtime = datetime.fromtimestamp(os.path.getmtime(FPATH))
        if mtime > today:
            return True
    return False

Checks with hasCache for cache files and returns True if last modified date is today. Returns False if the cache file does not exist or if the cache file was last modified before today.

When combined, it looks like this:

exchange2.py


#!/usr/bin/env python

import sys
import os.path
from datetime import date, datetime
import urllib
import json

URL = "http://api.aoikujira.com/kawase/json/usd"
FPATH = "/tmp/exchange"


def hasCache():
    if os.path.isfile(FPATH):
        d = date.today()
        today = datetime.combine(d, datetime.min.time())
        mtime = datetime.fromtimestamp(os.path.getmtime(FPATH))
        if mtime > today:
            return True
    return False


def readCache():
    with open(FPATH, 'r') as f:
        body = f.read()
    return body


def writeCache(body):
    with open(FPATH, 'w') as f:
        f.write(body)


def fetchRates():
    # fetch rate list from remote
    response = urllib.urlopen(URL)
    body = response.read()

    writeCache(body)

    return body

if __name__ == "__main__":
    price = float(sys.argv[1])

    if hasCache():
        body = readCache()
    else:
        body = fetchRates()

    data = json.loads(body)
    rate = float(data[u'JPY'])
    print "{0}(USD) => {1}(JPY)".format(1, rate)
    print "{0}(USD) => {1}(JPY)".format(price, price * rate)

When hasCache returns True, readCache reads from the cache file, and when returns False, fetchRates fetches from the API.

I want to make it look like a command line tool

You can easily create command line tools using argparse

options.py


#coding:utf-8

import argparse

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='convert usd to any currency.')
    parser.add_argument('-p', '--price', nargs='?', type=float, help='price', default=1.0)
    parser.add_argument('-c', '--currency', nargs='?', help='currency', default=u'JPY')
    parser.add_argument('-r', '--reverse', action='store_true', help='reverse the direction')
    parser.add_argument('-v', '--verbosity', action='count', help='increase output verbosity')

    args = parser.parse_args()
    price = args.price
    currency = args.currency
    reverse = args.reverse
    verbosity = args.verbosity

    print "price:",     price
    print "currency:",  currency
    print "reverse:",   reverse
    print "verbosity:", verbosity

Save the above and let's run it

#No arguments
$ python options.py
price: 1.0
currency: JPY
reverse: False
verbosity: None

#With arguments
$ python options.py -p 2.5 -c EUR -r -vvv
price: 2.5
currency: EUR
reverse: True
verbosity: 3

#Help message is automatically generated
$ python options.py -h
usage: options.py [-h] [-p [PRICE]] [-c [CURRENCY]] [-r] [-v]

convert usd to any currency.

optional arguments:
  -h, --help            show this help message and exit
  -p [PRICE], --price [PRICE]
                        price
  -c [CURRENCY], --currency [CURRENCY]
                        currency
  -r, --reverse         reverse the direction
  -v, --verbosity       increase output verbosity

It's easy!

The whole thing up to this point is on Gist https://gist.github.com/kei-sato/98675769952ec7538d6a

Summary

Recommended Posts

Create a command line tool to convert dollars to yen using Python
Create a tool to automatically furigana with html using Mecab from Python3
A note I looked up to make a command line tool in Python
Try to make a command standby tool with python
How to manage arguments when implementing a Python script as a command line tool
How to execute a command using subprocess in Python
Create a tool to check scraping rules (robots.txt) in Python
Create a python GUI using tkinter
5 Ways to Create a Python Chatbot
A tool to convert Juniper config
How to get a string from a command line argument in python
[Python] How to convert a 2D list to a 1D list
[Python] Create a Batch environment using AWS-CDK
[Python] [LINE Bot] Create a parrot return LINE Bot
[Python] I tried to make a simple program that works on the command line using argparse.
I tried to create a program to convert hexadecimal numbers to decimal numbers with python
[Python] [Word] [python-docx] Try to create a template of a word sentence in Python using python-docx
I tried to create a sample to access Salesforce using Python and Bottle
Edit Excel from Python to create a PivotTable
[Python] How to test command line parser click
How to receive command line arguments in Python
Send a message to LINE with Python (LINE Notify)
Create a GIF file using Pillow in Python
How to create a Python virtual environment (venv)
Create a command to encode / decode Splunk base64
Create a web map using Python and GDAL
Use click to create a sub-sub command --netsted sub-sub command -
Steps to create a Twitter bot with python
Try to create a new command on linux
How to create a shortcut command for LINUX
How to create a Kivy 1-line input box
Convert STL to Voxel mesh using Python VTK
Convert XLSX to CSV on the command line
Create a Mac app using py2app and Python3! !!
Create a MIDI file in Python using pretty_midi
Create a command to get the work log
Build a command line app in Python to understand setup.py, argparse, GitHub Actions
Convert the cURL API to a Python script (using IBM Cloud object storage)
How to convert / restore a string with [] in python
How to write a GUI using the maya command
[Python] How to draw a line graph with Matplotlib
How to set up a Python environment using pyenv
Specify a subcommand as a command line argument in Python
Create a Python module
(Python) Try to develop a web application using Django
[CRUD] [Django] Create a CRUD site using the Python framework Django ~ 1 ~
[Python] Create a ValueObject with a complete constructor using dataclasses
Create a plugin to run Python Doctest in Vim (2)
Create a plugin to run Python Doctest in Vim (1)
[CRUD] [Django] Create a CRUD site using the Python framework Django ~ 2 ~
[Python] Created a method to convert radix in 1 second
Python script to create a JSON file from a CSV file
[Python] How to create a 2D histogram with Matplotlib
How to create a radial profile from astronomical images (Chandra, XMM etc.) using python
Create a company name extractor with python using JCLdic
[CRUD] [Django] Create a CRUD site using the Python framework Django ~ 3 ~
How to create a kubernetes pod from python code
[CRUD] [Django] Create a CRUD site using the Python framework Django ~ 4 ~
[CRUD] [Django] Create a CRUD site using the Python framework Django ~ 5 ~
How to create an instance of a particular class from dict using __new__ () in python
I want to create a karaoke sound source by separating instruments and vocals using Python