Skip to content

General style updates #2

Description

@LiamPattinson

There are a few style changes that could be made to make the project more 'pythonic' and to make future development easier. The aim here wouldn't be to change any behaviour, but instead to simplify some code and reduce the potential for bugs to creep in. Let me know your thoughts on any of these suggestions.

while loops

A common pattern throughout the project is to use while loops in places where a for loop might be safer:

# while version
i = 0 # developers might forget to set this when 'i' is reused within a function
while (i < num):
    # do something...
    i += 1 # developers might also forget this line, leading to infinite loops

# for version
for i in range(num):
    # do something...

There are also places where loops are used to build lists, and they could instead be replaced with a list comprehension:

# while version
my_list = []
i = 0
while (i < list_len):
    my_list.append(some_function(i))
    i += 1

# list comprehension version
my_list = [some_function(i) for i in range(list_len)]

This might perform a little better (although it's never guaranteed), and it leads to much more compact code. I find them quite easy to read, but I understand that some other programmers aren't too keen on them, so it's personal preference if they're used or not. It's easy to fall into the trap of over-engineering list comprehensions until they're near-unreadable, so it's best to keep them simple.

Repeat code

There are some places where a long line of complex arithmetic is repeated on several lines. It'd be better to break these lines down into a few variables, as then there's less risk of developers modifying a line of code but forgetting to make similar changes to later lines (or simply making a mistake when updating later lines). e.g:

https://github.com/AleksandarJ1984/FEDM/blob/720e18015a994defab8c44d01b433bc4ddefaf5d/fedm_modules/functions.py#L220-L228

Could modify to something like:

# Ideally, should break this down further to aid readability
common_part = 2.0*pi*exp(u)*((((1.0+2.0*dt/dt_old)/(1.0+dt/dt_old))*(u - (pow(1.0+dt/dt_old, 2.0)/(1.0+2.0*dt/dt_old))*u_old\
         + (pow(dt/dt_old, 2.0)/(1.0+2.0*dt/dt_old))*u_old1))*v/dt)*r*dx
if (equation_type == 'reaction'):
    return common_part - 2.0*pi*f*v*r*dx
elif (equation_type == 'diffusion-reaction'):
    return common_part - 2.0*pi*dot(-grad(D*exp(u)), grad(v))*r*dx - 2.0*pi*f*v*r*dx
elif (equation_type == 'drift-diffusion-reaction'):
    return common_part - 2.0*pi*dot(Gamma, grad(v))*r*dx - 2.0*pi*f*v*r*dx
else: # handle incorrect 'equation_type'
    raise ValueError(f"Equation type {equation_type} not recognised")

Formatting with an autoformatter/linter

I've found some of the longer lines in the project difficult to read, especially if I'm looking at two files side-by-side in my terminal. We could use a tool like Black to automate the formatting of the project, which in my experience tends to do a really good job of producing consistent and readable code (it sometimes does questionable things, but if it makes your code less readable it's usually an indication that you're doing too much on one line anyway).

We could also use flake8 to enforce style further and catch any potential bugs (it's good for catching unused variables). These can both be configured using setup.cfg/pyproject.toml, which would be implemented for Issue #1.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions