7
\$\begingroup\$

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.

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Jan 27, 2015 at 11:16
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

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')]
answered Jun 14, 2015 at 19:08
\$\endgroup\$
3
  • \$\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 using argparse 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 been path 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\$ Commented 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\$ Commented Jun 15, 2015 at 16:19
  • \$\begingroup\$ Yes, I guess your right. \$\endgroup\$ Commented Jun 15, 2015 at 18:32

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.