<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 So my the code for my solution can be found in
Step1:  The above bit of boiler-plate code is useful in a number of situations. Indeed, this is a pattern I regularly find myself using when writing scripts.
The if-statement asks if the file has been opened 'directly'. If it has, we call main.  This means that if I call the above bit of code from the command line like so
Step2:  As for the main function itself, this ought to be at least somewhat easy to follow. We have a debug switch that allows us to determine where bombs are placed. We use this for testing. 
The only other new things is that we have a class object called PlayGame. In this guide I've only briefly touched on classes, and so I shall not go into super detail about how classes work. But the short version is that the game object stores information about the game in progress, and the game continues all the while game.is_playing is set to True.
The input function waits for the user to give us information. This is how we can make a move.
Step3:  Most of the code in the PlayGame function is concerned with parsing information from the user. When writing code, sometimes you have to make trade-offs, you can make things faster as the cost of memory, for example.
In this particular case I've made the code quite flexible and concise, at the cost of complexity.
Step4:  So the above code snippet is a smaller, simpler version of the code you will find in my mindsweeper implementation. Here's the problem
Step5:  So this code would more or less do the same job. And although its easier to understand it does have the drawback that for every additional command we add we need to add several lines of code. Meanwhile, the solution I went for does away with all those nested if statements. In fact, adding an extra command requires just a single line of code (which we add to the COMMANDS dictionary).  
The 'cleverness' of my implementation can be seen in these two lines
Step6:  By the way, in python it is possible to save a function as a variable (with the idea of calling it later), which the code below below hopefully illustrates
Step8:  Combining all of these things means it is possible to write an argument parser in just a few lines of code. Moreover, adding new commands requires very little effort.
another reason why my implementation is more powerful than if statements is that I can, with minor modifications use it in other projects. For example
<ASSISTANT_TASK:>
Python Code:
## Assume that this code exists in a file named example.py
def main():
    print(1 + 1)
if __name__ == "__main__":
    main()
Explanation: So my the code for my solution can be found in:
../misc/minesweeper.py
In this lecture I shall be going through some bits of code and explaining parts of it. I encourage you to read it before going any further with this lecture.
The first thing you may notice is that this file in actually a jupyter notebook. There are a few reasons why I ended up making this a normal .py file, but the main was that as projects get bigger the harder it is to use jupyter notebook. Moreover, notebooks have limited debugging capabilities, so by having a file that I could open with a code editor allowed me to spot my mistakes a bit faster.
Anyway, the code is more or less split up into three main parts:
The game logic (i.e. code for creating boards, revealing squares, etc)
Code to understand user input (that is, the code that can map an instruction such as 'flag 0 0' to a function call.
Code to that starts the game and runs the game-loop.
Part 1 should be straight-forward, its just the combination of all the mini-projects we have done with a few tweeks modifications here and there to fix bugs and general improvements to code quality (such as improved variable naming). 
Part 2 is a bit of a beast, so I'll leave that till last.
This leaves Part 3 to talk about.
if __name__ == "__main__"
End of explanation
def main():
    DEBUG = False #True
    if DEBUG:
        random.seed(243)
    print("+--------------------------------+")
    print("|   WELCOME TO MINSWEEPER 1.0!   |")
    print("+--------------------------------+")
    print("How to play: type 'commands' for a list of valid inputs. Then type 'help x' for information about how to use command 'x'")
    print("")
    game = PlayGame()
    while game.is_playing:
        s = input("Command: ")
        game.parse_command(s)
        display_board(game.player_board)
        print("\n")
Explanation: The above bit of boiler-plate code is useful in a number of situations. Indeed, this is a pattern I regularly find myself using when writing scripts.
The if-statement asks if the file has been opened 'directly'. If it has, we call main.  This means that if I call the above bit of code from the command line like so:
&gt; python example.py
then the code works and it prints 2 to the console. 
However if I create a new python file and try to import the module like so:
import example
Nothing happens. This is because when you import a file, its __name__ is not equal to __main__.  
We can however have our cake and eat it too; we can make the code work in both cases by calling main when importing the file. for example:
import example
example.main()
So by using this pattern I can make it possible to import minesweeper.py into a jupyter notebook and it also works when you call minesweeper.py directly from the command line.
Main Function
End of explanation
number = input("give me a number: ")
print("your selected number is: ", number)
Explanation: As for the main function itself, this ought to be at least somewhat easy to follow. We have a debug switch that allows us to determine where bombs are placed. We use this for testing. 
The only other new things is that we have a class object called PlayGame. In this guide I've only briefly touched on classes, and so I shall not go into super detail about how classes work. But the short version is that the game object stores information about the game in progress, and the game continues all the while game.is_playing is set to True.
The input function waits for the user to give us information. This is how we can make a move.
End of explanation
def flag(x, y):
    print(f"flag function was called. x = {x}, y = {y}")
def _help(topic=None):
    if topic:
        print(COMMANDS[topic][1])
def cheat():
    print("cheating!")
## Command -> (function, help text)
COMMANDS = {
            "flag": (flag, "Flags/deflags square(x,y). Example useage: flag x y"),
            "help": (_help,  "Selects square(x, y) to reveal, its game over if you reveal a bomb. Example useage: pick x y"),
            "cheat": (cheat, "Shows the location of all bombs. Example useage: cheat") }
    
def parse_command(command):
        instruction, *arguments = command.split(" ")
        if instruction in COMMANDS:
            return COMMANDS[instruction][0](*arguments)
        else:
            print("Parsing instruction failed")
            
# Example Calls:
command = "help cheat"
parse_command(command)
command2 = "flag 0 7"
parse_command(command2)
command3 = "cheat"
parse_command(command3)
Explanation: Most of the code in the PlayGame function is concerned with parsing information from the user. When writing code, sometimes you have to make trade-offs, you can make things faster as the cost of memory, for example.
In this particular case I've made the code quite flexible and concise, at the cost of complexity.
End of explanation
def parse_command_if_version(command):
    c = command.split(" ")
    
    instruction = c[0]
    args = c[1:]
    
    if instruction == "help":     
        if len(args) == 0:
            return _help()
        if len(args) == 1:
            topic = args[0]
            return _help(topic)
    if instruction == "cheat":
        return cheat()
    
    if instruction == "flag":
        x = args[0]
        y = args[1]
        
        return flag(x, y)
    
# Example Calls:
command = "help cheat"
parse_command_if_version(command)
command2 = "flag 0 7"
parse_command_if_version(command2)
command3 = "cheat"
parse_command_if_version(command3)
Explanation: So the above code snippet is a smaller, simpler version of the code you will find in my mindsweeper implementation. Here's the problem: what want to support multiple commands, each of which have their own arguments. Some need several arguments from the user to work, others need zero arguments from the user. How can we handle multiple cases?
Well, one possible way to do it would be to use multiple if statements like this:
End of explanation
def add(a, b):
    return a + b
nums = [1, 2]
    
# add(nums) # this would fail 
print(add(nums[0], nums[1])) 
print(add(*nums))
Explanation: So this code would more or less do the same job. And although its easier to understand it does have the drawback that for every additional command we add we need to add several lines of code. Meanwhile, the solution I went for does away with all those nested if statements. In fact, adding an extra command requires just a single line of code (which we add to the COMMANDS dictionary).  
The 'cleverness' of my implementation can be seen in these two lines:
instruction, *arguments = command.split(" ")
COMMANDS[instruction][0](*arguments)
The first line is more or less equivlent to the following:
instruction = command[0]
arguments   = command[1:]
The second line can only be understood with reference to the COMMANDS dictionary. Basically every command has a tuple with two elements. The first element (index 0) is the function we want to call (index 1 is the 'help text'). Meanwhile *arguments will take a list of items and pass them to the function individually.
End of explanation
def example(number):
    return number
m = example # example is NOT called. m is merely a reference to a function.
n = example(20) # n calls example with the argument 20. The result is a number 
print(n)
print(m(20)) # m(20) is the same as example(20)
Explanation: By the way, in python it is possible to save a function as a variable (with the idea of calling it later), which the code below below hopefully illustrates:
End of explanation
def parse_command(command, command_dictionary):
    
    command: str
    command_dictionary: dict where the key a command and the value is a function reference 
    
    instruction, *arguments = command.split(" ")
    if instruction in command_dictionary:
        return command_dictionary[instruction](*arguments)
    else:
        return f"ERROR: '{instruction}' is not a valid command"
            
math_dict = { "sqrt": lambda x: int(x)**0.5, 
              "round": lambda x, precision: round(float(x), int(precision)),
              "neg": lambda x: -float(x) }
string_dict = { "toCaps": str.upper,
                "reverse": lambda x: x[::-1],
                "join": lambda *x: "".join(list(x))} 
print("STRING_DICT EXAMPLES...")
print(parse_command("toCaps hello", string_dict))
print(parse_command("reverse dlrow", string_dict))
print(parse_command("join h e l l o _ w o r l d", string_dict))
print()
print("MATH_DICT EXAMPLES...")
print(parse_command("sqrt 2", math_dict))
print(parse_command("round 10.98 1", math_dict))
print(parse_command("neg -2", math_dict))
print(parse_command("missing a b c", math_dict))
Explanation: Combining all of these things means it is possible to write an argument parser in just a few lines of code. Moreover, adding new commands requires very little effort.
another reason why my implementation is more powerful than if statements is that I can, with minor modifications use it in other projects. For example:
End of explanation
<END_TASK>