Debugging in python


#1

Hello, so I have relative experience with Python but cannot figure out how to write anything to the command line. I looked up the docs on the logger module and cannot find a way to output variable values, which would be an acceptable alternative. I'm familiar with writing to cmd, yet I get the following error when using the command print ("test"):

Game constants: all default
Seed: 877396728 Dimensions: 240x160
Init Message sent to player 0.
Init Message sent to player 1.
Init Message received from player 1, MyBot.
Init Message received from player 0, MyBot.
Turn 1
ERROR: Bot #0: Received invalid character 'teste'. (at character 2.)
Input received from bot:
test
^
ERROR: Bot #1: Received invalid character 'teste'. (at charact

I am confused as to why this causes an error like it is passing it to the bot when it should just go to the command prompt terminal. This makes it challenging to debug since I cannot output information other than explicitly programmed strings in logs.

I was also wondering if anyone had some tips in using the error log that is created when your bot fails.


#2

You cannot write anything to the commandline. You have to use file logging. Halite bots communicate over stdin and stdout. So you should log to a file always


#3
import logging
logging.info("test")

Will be output in your Bots log: 0_MyBot.log (or whatever number/name your bot has)


#4

@csheldrick @harikmenon1 Thanks for the responses; I still get the same error when using the logger, perhaps I am using it incorrectly, but I have looked at many different formats and parameters. A basic example of one thing I tried is:


logger = logging.getLogger()
handler = logging.StreamHandler()
formatter= logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
testVar = 'test'
logger.info(testVar)

Where I get the same error, but with the log output:

ERROR: Bot #0: Received invalid character '2017-10-25 16:11:40,272 root INFO test:'. (at character 14.)
Input received from bot:
2017-10-25 16:11:40,272 root INFO test


#5

For some reason you are still logging into stdout. It doesnt look like you are specifying a file name but just a stream handler. Is it still routing to stdout?


#6

The Python start kit initializes logging this way:

log_file = "{}_{}.log".format(tag, name)
logging.basicConfig(filename=log_file, level=logging.DEBUG, filemode='w')
logging.info("Initialized bot {}".format(name))

Where:
* tag = user tag from server (retrieved from game data)
* name = arbitrary string you provide

Of course if you're using the Python start kit you don't have to do anything, just use the originally initialized 'logger'.

Insofar as debugging goes, I wrap my main loop in a try/except clause. Then log any exceptions for analysis:

except:
	logging.exception('An exception occurred')
	exit(1)

#7

I found the best way to log exceptions to the log is to add this at the start after logging enabled:

# Then we print our start message to the logs
logging.info("Starting...")


def exception_handler(exception_type, exception, tb):
    logging.error(traceback.format_exception(exception_type, exception, tb))


sys.excepthook = exception_handler

#8

Hi all, I finally logged this exception:
line 22, in sendstring
sys.stdout.flush()
OSError: [Errno 22] Invalid argument

This is happening while sending commands. specifically, this command: t 3 1 4
any ideas were this is coming from?


#9

I fixed it by following this discussion:
https://forums.halite.io/t/prevent-hlt-engine-from-getting-output-from-training-a-model-in-game/537/7


#10

Hello,

I use 26.2. pdb for debugging in Python.

The typical prompt is (Pdb). Typical usage to run a program under control of the debugger is:

import pdb
import mymodule
pdb.run('mymodule.test()')
(0)?()
(Pdb) continue
(1)?()
(Pdb) continue
NameError: 'spam'
(1)?()
(Pdb)

Hope this is useful.

Python training


#11

Hi, here is your answer... I think this may helpful to you..

In PHP, you were probably used to the awesome xdebug extension.

In Python, spawn the classic debugger with (put this anywhere you'd put xdebug_break():

import pdb; pdb.set_trace()
My favorite is with the ipdb module (pip install ipdb):

import ipdb; ipdb.set_trace()
You can also use werkzeug (pip install werkzeug) and django-extensions (pip install django-extensions and add django_extensions to settings.INSTALLED_APPS), which provides the runserver_plus command.

It's really great. That is also one of the things that I'll probably make you never look back at python php again. Anyway, runserver_plus is like runserver but it will replace the default django stacktrace page with an ajax interactive shell available at each frame of the stacktrace. Of course you can get it by puting something like crash or random_undefined_variable_name anywhere in your code.