Let's write FizzBuzz with an error: Python Version

Introduction

Before, after practicing Ruby, I posted an article on my blog called Writing FizzBuzz with errors. However, there was a surprising reaction, and the following story was written in Qiita:

-FizzBuzz with errors in Python -Fizzbuzz with exception handling

I'm originally from Python, so I wrote the code quickly in the spirit of "By the way, I haven't written Python for a long time, my skill will be dull, and I'm the person who wrote in the original article, so MOTTAINAI !!" Saw.

However, since the pattern has already been decided within me, it took about 20 minutes, so it may be a good idea to try it as a guide (for those who are confident in Python).

Answer for the time being

class FizzBuzzError(Exception):
    def __init__(self, message, errors):
        self.message = message
        self.errors = errors


def fizzbuzz_function(n, message):
    def _return_fizz(i):
        try:
            1 / (i % n)
            return ''
        except ZeroDivisionError:
            raise FizzBuzzError(message, message)
    return _return_fizz


def error_message(f, *args, **kargs):
    def _f(n):
        try:
            return f(n)
        except FizzBuzzError as e:
            return e.message
    return _f


@error_message
def fizz(n):
    return fizzbuzz_function(3, "Fizz")(n)


@error_message
def buzz(n):
    return fizzbuzz_function(5, "Buzz")(n)


def fizzbuzz(n):
    return "".join([fizz(n), buzz(n)]) or n


def main():
    for i in [fizzbuzz(n + 1) for n in range(99)]:
        print(i)


if __name__ == "__main__":
    main()

This is a Python3 specification. If you are using Python2, please use ʻimport future from print_function``;) `

Commentary

I don't understand the specifications of Python's custom error ...!

I can't say anything because I haven't pursued deeply because I'm a little away from Python, but I'm wondering if such an implementation is okay. For the time being, I am using this StackOverflow without understanding it, so maybe This implementation may be redundant.

class FizzBuzzError(Exception):
    def __init__(self, message, errors):
        self.message = message
        self.errors = errors

After all Python uses closures

What makes Python a little better than Ruby is the ease of writing closures? To be honest, I honestly think that it is troublesome to make a proc and hoge in Ruby, and if you do not add () in Python, I personally prefer the specification of handling function objects (Rubyist Masakari welcomed) ……!).

By the way, fizzbuzz is abstracted to ** if it is a multiple of something, it issues a message corresponding to it **. If you take out only that part and make it, it is convenient to use closures in Python. As an actual usage example, it looks like the following.

def fizzbuzz_function(n, message):
    def _return_fizz(i):
        try:
            1 / (i % n)
            return ''
        except ZeroDivisionError:
            raise FizzBuzzError(message, message)
    return _return_fizz


def fizz(n):
    return fizzbuzz_function(3, "Fizz")(n)

The message acquisition part can also be abstracted ... It's a decoration!

Now, let's think further. We want an error hyperreturn, we don't want an error.

If you understand closures, you should try using decorators next. The definition of the decorator is quoted from the following explanation of PEP 318 because it is the easiest to understand:

@dec2
@dec1
def func(arg1, arg2, ...):
    pass

This is equivalent to:

def func(arg1, arg2, ...):
    pass
func = dec2(dec1(func))

Here in this code:

def error_message(f, *args, **kargs):
    def _f(n):
        try:
            return f(n)
        except FizzBuzzError as e:
            return e.message
    return _f

In Python, " " is False!

This is a controversial point, but " " is False in the Python specification. In other words, if the join of the two results is an empty string, it is already False, so all you have to do is return the received number as it is. It seems convenient because it can be written only with the so-called ʻor operator`! I don't need a ternary operator!

def fizzbuzz(n):
    return "".join([fizz(n), buzz(n)]) or n

Summary

So, this time I wrote about the error FizzBuzz by Python based on the unexpected reaction.

However, since the original article is used as a Super return, I think it is most likely to point out that raise is no different from just return in this case. When I tried to emphasize the Python-ness of decorator and its surroundings, I ended up with the above code.

Task

Now, what if the language doesn't have error handling?

For example, I remember that Go doesn't have a syntax dedicated to error handling (I know that panic and recover are available ...), but in Haskell. There are times when you want to see something;)

Recommended Posts

Let's write FizzBuzz with an error: Python Version
Let's write python with cinema4d.
FizzBuzz with Python3
Let's develop an investment algorithm with Python 1
Check version with python
Let's run Excel with Python
Creating an egg with python
Error when playing with python
Write to csv with Python
Specify python version with virtualenv
Let's build git-cat with Python
Error resolution python version check
Let's get started with Python ~ Building an environment on Windows 10 ~
Cut out an image with python
[Python] Write to csv file with Python
Let's make a GUI with python.
Write an HTTP / 2 server in Python
[Python] Let's write briefly about comprehensions
Create an Excel file with Python3
I sent an SMS with Python
Let's play with Excel with Python [Beginner]
Let's do image scraping with Python
Manage each Python version with Homebrew
Let's make a graph with python! !!
Draw an illustration with Python + OpenCV
[Python] Send an email with outlook
Let's analyze voice with Python # 1 FFT
Write a batch script with Python3.5 ~
[Python Windows] pip install with Python version
I get an error with import pandas.
[Python] Building an environment with Anaconda [Mac]
Write test-driven FizzBuzz code using Python doctest.
Note when creating an environment with python
Let's create a free group with Python
Quickly create an excel file with Python #python
I tried sending an email with python.
When I get an error with PyInstaller
[Introduction to Python] Let's use foreach with Python
Let's read the RINEX file with Python ①
Let's make a voice slowly with Python
[Python] Let's make matplotlib compatible with Japanese
Write a TCP client with Python Twisted
[Python] Quickly create an API with Flask
Scraping from an authenticated site with python
Let's do MySQL data manipulation with Python
Create an English word app with python
Let's make a web framework with Python! (1)
Send an email with Amazon SES + Python
Join an online judge with Python 3.x
Let's make a Twitter Bot with Python!
Let's get along with Python # 0 (Environment construction)
Let's make a web framework with Python! (2)
[Blender x Python] Let's get started with Blender Python !!
Let's explain the asset allocation by the Black-Litterman model (with an execution example by Python)
I got an error when I put opencv in python3 with Raspberry Pi [Remedy]
I want to send Gmail with Python, but I can't because of an error
What to do if you get an error when installing python with pyenv
Searching for an efficient way to write a Dockerfile in Python with poetry
I got an error when saving with OpenCV
Python hand play (let's get started with AtCoder?)
Let's solve simultaneous linear equations with Python sympy!