Skip to content

A cheatsheet of Fortran syntax for Python programmers

Notifications You must be signed in to change notification settings

wusunlab/fortran-vs-python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 

Repository files navigation

A Cheatsheet for Fortran 2008 Syntax: Comparison with Python 3

Wu Sun

Last updated: 2022-02-11

This is a simple cheatsheet to aid scientific programmers who work at the interfaces of both languages. It is by no means an exhaustive list. (I have yet to explore some advanced features in the Fortran 2008 and newer standards.)

Make Fortran Modern Again!

This work is licensed under the Creative Commons Attribution 4.0 International License.

Fortran 2008 Python 3
Top-level constructs
the main program
program my_program
    ...
end program
Not required. Use __main__() if needed.
modules
module my_module
    ...
end module my_module
A source file is a module.
subroutines
subroutine my_subroutine
    ...
end subroutine my_subroutine
Functions that have side effects.
functions
function f(x) result(res)
    res = ...
end function f
def my_function(x):
    ...
    return res
submodules
module main_module
    ...
contains
<submodule statements>
end module main_module
Use folders, __init__.py, and import statement to manage submodules.
import statement
use my_module
use my_module, only : fun1, var1
use my_module, only : new_var => var
from my_module import *
from my_module import fun1, var1
from my_module import var as new_var
call subroutines and functions
call my_subroutine(args)
my_function(args)
my_function(args)
abort a program
stop
exit()
inline comments
! This is a comment
# This is a comment
line continuation & \
include external source files
include 'source_file_name'
Not supported. Use module import.
Control flow patterns
if construct
if <logical expr> then
    ...
else if <logical expr> then
    ...
else
    ...
end if
if <logical expr>:
    ...
elif <logical expr>:
    ...
else:
    ...
case construct
select case <expr>
    case <value>
        ...
    case <value>
        ...
    case default
        ...
end select
Structural pattern matching, supported since Python 3.10:
match <expr>:
    case <pattern>:
        ...
    case <pattern>:
        ...
    case _:
        ...
do construct
do start_value, end_value, step
    ...
end do
for i in range(start, end, step):
    ...
do while construct
do while <logical expr>
    ...
end do
while <logical expr>:
    ...
break from a loop
exit
break
leave this iteration and continue to the next iteration
cycle
continue
Data types
declaration
integer(kind=kind_number) :: n = 0
real(kind=kind_number) :: x = 0.
n = 0
x = 0.
named constants
integer, parameter :: answer = 42
real(8), parameter :: pi = 4d0 * atan(1d0)
Not supported in Python. Names are bindings.
complex number
complex :: z = (1., -1.)
z = 1 - 1j
string
character(len=10) :: str_fixed_length
character(len=:), allocatable :: str_var_length
string = "this is a string"
pointer
real, pointer :: p
real, target :: r
p => r
No built-in support. May invoke from Python C API.
(Why would you need it in Python anyway?)
boolean
.true.
.false.
True
False
logical operators
.not.
.and.
.or.
.eqv.
.neqv.
not
and
or
Other logical operators do not have built-in support.
equal to
==, .eq.
==
not equal to
/=, .ne.
!=
Note: <> is deprecated in Python 3.
greater than
>, .gt.
>
less than
<, .lt.
<
greater than or equal to
>=, .ge.
>=
less than or equal to
<=, .ge.
<=
array declaration
real(8), dimension(3) :: a = [1., 2., 3.]
import numpy as np
a = np.array([1., 2., 3.])
string array declaration
character(len=20), dimension(3, 4) :: char_arr
char_arr = np.chararray((3, 4), itemsize=20)
elementwise array operations
a op b
op can be +, -, *, /, **, =, ==, etc.
This is supported since the Fortran 90 standard.
Supported through numpy.ndarray type.
first element
a(1)
a[0]
slicing
a(1:5)
This slice includes a(5).
a[0:5]
This slice does not include a[5].
slicing with steps
a(1:100:2)
a[0:100:2]
size
size(a)
a.size
shape
shape(a)
a.shape
shape along a dimension
size(a, dim)
a.shape[dim]
Type conversion
to integer by truncation
int()
int()
to integer by rounding
nint()
int(round())
integer to float
real(a[, kind])
float()
complex to real
real(z[, kind])
z.real
to complex
cmplx(x [, y [, kind]])
complex()
to boolean
logical()
bool()
Derived data types
definition
type Point
    real(8) :: x, y
end type Point
class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
instantiation
type(Point) :: point1 = Point(-1., 1.)
point1 = Point(-1., 1.)
get attributes
point1%x
point1%y
point1.x
point1.y
array of derived type
type(Point), dimension(:), allocatable :: point_arr
No built-in support. You may need to subtype the NumPy array.
(Why not use a structured array instead of an array of structure?)
type bound procedures (aka class method) Assume that Circle has a type bound procedure (subroutine) print_area.
type(Circle) :: c
call c%print_area
Assume that Circle has a class method print_area().
c = Circle()
c.print_area()
Built-in mathematical functions
functions with the same names
abs(), cos(), cosh(), exp(), floor(), log(),
log10(), max(), min(), sin(), sinh(), sqrt(),
sum(), tan(), tanh()
Have the same name in NumPy.
functions with different names
acos()
aimag()
asin()
atan()
atan2(x, y)
ceiling()
conjg(z)
modulo()
call random_number()
np.arccos()
z.imag
np.arcsin()
np.arctan()
np.arctan2(x, y)
np.ceil()
np.conjugate(z), z.conjugate()
np.mod(), %
np.random.random_sample()
Built-in string functions
string length
len()
len()
string to ASCII code
iachar()
ord()
ASCII code to string
achar()
chr()
string slicing Same as 1D array slicing. Same as 1D array slicing.
find the position of a substring
index(string, substring)
string.index(substring)
string concatenation
"hello" // "world"
"hello" + "world"
"hello" "world"
("hello" "world")
The operator may be omitted.
Array constructs
where construct
where a > 0
    b = 0
elsewhere
    b = 1
end where
For NumPy arrays,
b[a > 0] = 0
b[a <= 0] = 1
For lists, use the higher order function filter() or list comprehension.
forall construct
real, dimension(10, 10) :: a = 0
int :: i, j
...
forall (i = 1:10, j = 1:10, i <= j)
    a(i, j) = i + j
end forall
import itertools
import numpy as np
a = np.zeros((10, 10))
for i, j in itertools.product(range(10), range(10)):
    if i <= j:
        a[i, j] = i + j
Note: this is a simple example to reproduce the forall construct in Python. There are definitely other (and more Pythonic) ways of doing the same thing.
Other built-in subroutines
CPU time
call cpu_time()
import time
time.time()
command line arguments
call command_argument_count()
call get_command()
call get_command_argument()
For basic parsing, use sys.argv. For more advanced use, see the built-in argparse module.
Input/output
print
print fmt, <output list>
print()
read from the command prompt
read fmt, <input list>
input(prompt)
open a file
open(unit, file, ...)
f = open(file, mode='r', ...)
read from a file
read(unit, fmt, ...) <input list>
f.read(size)
f.readline()
write to a file
write(unit, fmt, ...) <output list>
f.write()
close a file
close(unit, ...)
f.close()
file inquiry
inquire(unit, ...)
Use the file utilities provide by the os module.
backspace in a file
backspace(unit, ...)
f.seek(-1, 1)
Note: this works only when the file is open as a binary file.
end of file (EOF)
endfile(unit, ...)
f.read() == ''
However, this is generally not needed.
return to the start of a file
rewind(unit, ...)
f.seek(0)

About

A cheatsheet of Fortran syntax for Python programmers

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published