I use Project Euler to teach me programming and not to submit any results. As such I look up the expected return values to double check my solutions.
To organise my files I use the following folder structure:
main.py \euler # The problem files __init__.py # empty e001.py e002.py ... \input # Additional input files 8.dat 11.dat ...
My main.py
file is the common entry point. It can either run all the solved examples so far or a specific one. This second option is added that I don't need to add an if __name__ == '__main__'
guard in every file. The file looks as follows:
TOP_LEVEL = "euler"
def run_module(num):
"""Run specific Problem"""
mod = importlib.import_module('%s.e%0.3i' % (TOP_LEVEL, num))
start = time.time()
ist = mod.run()
print(" %5i | %6.3f | %s | %i" % \
(num, time.time() - start, "ox"[ist == mod.SOLL], ist))
if __name__ == '__main__':
N_MAX = 67
# Pre Header
print('Problem | Time | x/o | Solution')
print("--------+--------+-----+---------")
global_time = time.time()
# Run over all problems
if len(sys.argv) == 2:
run_module(int(sys.argv[1]))
else:
for num in range(1, N_MAX + 1):
run_module(num)
# End Header
print("--------+--------+-----+---------")
print("Total: %.3f s" % (time.time() - global_time))
I'll show now two example files to show the source files and how old code can be reused. e018.py
:
"""By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.
3
7 4
2 4 6
8 5 9 3
That is, 3 +たす 7 +たす 4 +たす 9 =わ 23.
Find the maximum total from top to bottom of the triangle below"""
SOLL = 1074
def run(file = "input/18.dat"):
# Parse File
with open(file) as fid:
tri = [[int(num) for num in line.split(' ')] for line in fid.read().split('\n')]
# From bottom's up find the maximal value
for row in range(len(tri) - 2, -1, -1):
for col in range(row + 1):
tri[row][col] += max(tri[row + 1][col], tri[row + 1][col + 1])
return tri[0][0]
and e067.py
"""By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.
3
7 4
2 4 6
8 5 9 3
That is, 3 +たす 7 +たす 4 +たす 9 =わ 23.
Find the maximum total from top to bottom of the triangle below"""
import e018
SOLL = 7273
def run(file = "input/67.dat"):
# problem has been solved in set 18
return e018.run(file = file)
Since this is the first time I tried to structure such a project, I'm quite sure there is plenty of room for optimization. I'm happy for any feedback I can get.
1 Answer 1
Use .format
Using %
is considered old style, so:
print(" %5i | %6.3f | %s | %i".format(
(num, time.time() - start, "ox"[ist == mod.SOLL], ist)))
Be generous with long variables names
For example ist
is impossible to understand for me, solution
is more natural
Don't abuse Code-Golf techniques
The line:
"ox"[ist == mod.SOLL]
is a well known Code-Golf trick that relies on implicit boolean to integer conversion that is equivalent to:
"x" if ist == mod.SOLL else "o"
please use the latter.
Use argparse
C-Style arguments such as sys.argv[1]
should be avoided, I suggest argparse
(help to get started here: https://stackoverflow.com/questions/7427101/dead-simple-argparse-example-wanted-1-argument-3-results)
Don't shadow built-ins
def run(file = "input/18.dat"):
# Parse File
with open(file) as fid:
file
is a built-in, you should use file_
in your code.
Explode long lines
Divide the following lines in two please.
tri = [[int(num) for num in line.split(' ')] for line in fid.read().split('\n')]
-
\$\begingroup\$ Thank you for this input. I definitely have to look into the
.format
since I still stick to c formatting all the time. I also started usingargparse
meanwhile and learned to like it. Once thing I'm myself not really certain about is the shadowing of the file variable. A better name might have beenpath
anyway but is it really so bad to shadow a builtin for which nearly nobody is ever gonna call its constructor directly? Conserning the data structure I was also wondering if you had any input about that. \$\endgroup\$magu_– magu_2015年06月15日 16:18:16 +00:00Commented Jun 15, 2015 at 16:18 -
\$\begingroup\$ @magu_ it is better not to, because, for example in an IDE
file
will change colour, and seeing an ordinary variable of another colour is distracting \$\endgroup\$Caridorc– Caridorc2015年06月15日 16:19:43 +00:00Commented Jun 15, 2015 at 16:19 -
\$\begingroup\$ Yes, I guess your right. \$\endgroup\$magu_– magu_2015年06月15日 18:32:11 +00:00Commented Jun 15, 2015 at 18:32