Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
9ee15bb
improve readability of the main function
Aug 3, 2021
c184117
step_size implemented in walker function
Aug 3, 2021
4f5a844
added rudimentary landscape walker
Aug 3, 2021
d71f078
multiple walkers implemented
kolarius27 Aug 3, 2021
4604f99
Merge pull request #1 from BoSott/input_multiple
kolarius27 Aug 3, 2021
f6811d3
Merge branch 'main' into other_walkers
kolarius27 Aug 3, 2021
bb90997
Merge pull request #2 from BoSott/other_walkers
kolarius27 Aug 3, 2021
ad8e7a5
command line input implemented using click
Aug 3, 2021
a2337b9
branches merged (hopefully)
kolarius27 Aug 3, 2021
584e8f1
Merge pull request #3 from BoSott/input_multiple
kolarius27 Aug 3, 2021
7fc5f59
Merge branch 'main' into user_input
kolarius27 Aug 3, 2021
d8cc706
Merge pull request #4 from BoSott/user_input
kolarius27 Aug 3, 2021
6a5d85c
Add files via upload
kolarius27 Aug 3, 2021
10eaff8
Delete rand_walk_100000.png
kolarius27 Aug 3, 2021
9cf49a1
Delete test_plot.py
kolarius27 Aug 3, 2021
1d70861
edited the ReadME
Aug 3, 2021
eacd692
comments and docstrings added
kolarius27 Aug 3, 2021
e04040a
deleted rand_walk_10000.png image
Aug 3, 2021
cf723f9
Merge branch 'main' into input_multiple
kolarius27 Aug 3, 2021
1ffafda
Merge pull request #5 from BoSott/input_multiple
kolarius27 Aug 3, 2021
174a529
png's added to gitignored, main functions merged and docstrings compl…
Aug 3, 2021
4ef8608
Merge pull request #6 from BoSott/user_input
kolarius27 Aug 3, 2021
0755a68
included review comments
Aug 4, 2021
2609013
included some extra review comments
Aug 4, 2021
e81a359
extracted the next_step in walker to another function for testing
Aug 4, 2021
e8d3b60
Merge pull request #7 from BoSott/user_input
kolarius27 Aug 4, 2021
d207d63
added moor'sche neighboorhood
Aug 4, 2021
ce2a133
split the code into more files
Aug 4, 2021
833151c
Merge pull request #8 from BoSott/user_input
BoSott Aug 4, 2021
0986413
wrote some tests and extended raster plotting
Aug 4, 2021
8a24cf5
vector_walker.py fixed according to PEP-8
kolarius27 Aug 4, 2021
ba79ce9
Merge pull request #9 from BoSott/vector_walker
kolarius27 Aug 4, 2021
6b74922
all ready except the raster test cases
Aug 4, 2021
5c97ae9
Merge pull request #10 from BoSott/raster_test
kolarius27 Aug 4, 2021
c08ab03
tests finished and code adjusted to pep8 standards
Aug 4, 2021
bd74c7f
main.py fixed according to PEP-8
kolarius27 Aug 4, 2021
5c44fe6
updated ReadME.md
Aug 4, 2021
85344f5
Merge pull request #11 from BoSott/raster_test
BoSott Aug 4, 2021
ebbd117
Merge branch 'main' into vector_walker
kolarius27 Aug 4, 2021
178117c
Merge pull request #12 from BoSott/vector_walker
kolarius27 Aug 4, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,6 @@ dmypy.json

# Pyre type checker
.pyre/

# image results
*.png
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/.name

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/random_walk.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

78 changes: 47 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,71 @@
# Random Walk Simulation

This is a **group exercise**, so you should be working in pairs of two students. It's **30% of your final grade**.
## Write an extended random walk program

The Goal is to **practise writing readable, maintainable and reliable code collaboratively.**
In this repo you find a basic implementation of a [random walk simulation](https://en.wikipedia.org/wiki/Random_walk) in 2-dimensional space taken from [this blogpost](https://www.geeksforgeeks.org/random-walk-implementation-python/). Running the code yields an image which shows the path of the random walk.

## Group Exercise
The result will be directly shown to the user and additionally saved as png.

1. One student of your group forks the code from [https://github.com/advanced-geoscripting-2021/random_walker.git](https://github.com/advanced-geoscripting-2021/random_walker.git)
![random_walk](rand_walk_5_100.png)
start: point; end: cross

2. This student invites the other student as a collaborator to the forked repository. Now you can both work on the code.
An example for the landscape raster walker
![img_1.png](img_1.png)

3. Adapt the code to fulfil the requirements (see below).
## Setting up the project
1. clone repository
2. setup a virtual environment
3. activate the virtual environment
4. install required libs and packages locally (see requirements.txt)

4. Code review: Each group reviews the code of another group.
#### For the advanced geoscripting course:
- activate the corresponding virtual environment
- run ``conda install -c conda-forge click``
- run ``pip install --editable .``

5. Improve your code based on the review you got.

## How to run the tool
````
$ random_walker

## Write an extended random walk program

In this repo you find a basic implementation of a [random walk simulation](https://en.wikipedia.org/wiki/Random_walk) in 2-dimensional space taken from [this blogpost](https://www.geeksforgeeks.org/random-walk-implementation-python/). Running the code yields an image which shows the path of the random walk.
Usage: random_walker [OPTIONS] COMMAND [ARGS]...

![random_walk](rand_walk_100000.png)
Options:
--verbose TEXT Will print verbose messages.
--help Show this message and exit.

The program works but it is not very readable. In addition, you should **extend the program based on the requirements listed below.
Commands:
run execute command to generate random walkers
````

**Remember to apply the best practices in scientific computing** to make the code more readable, maintainable, reusable and efficient.
### How to use the run method
````
Usage: random_walker run [OPTIONS]

### Minimum requirements:
execute command to generate random walkers

Extend the program so the following requirements are met:
Options:
-ts, --total_steps INTEGER Specify the number of total steps for each
random walker, Default is 10,000, Minimum 100

1. The program should be able to simulate multiple random walkers.
2. The program should be executable from the command line.
3. The user should be able to specify the number of random walkers through a command line parameter.
4. Document the dependencies and instructions of how to run the program in your README.md.
-tw, --total_walkers INTEGER Specify the number of total walkers, Default
is 1, Minimum is 1

### Additional requirements:
-ss, --step_size INTEGER Specify the size of the steps taken, Default
is 1

1. Create three different types of walkers, e.g. a "fast walker" which has a bigger step size.
2. Add a "landscape" in which the random walkers are walking in which contains obstacles which the walkers cannot cross (e.g. a lake)
3. Invent and implement another functionality of your own.
-l, --landscape BOOLEAN Specify whether a grid landscape exists as
base layer or not, Default is False

Be creative here! :)
-sp, --start_point BOOLEAN Specify whether the walkers shall start from
the same point or not, Default is False

## Code Review
-mp, --mov_pattern BOOLEAN Specify the neighborhood movement pattern,
False is Neumann, True is Moor

Review the code of another group: (tuesday afternoon or wednesday morning)
--help Show this message and exit.

1. Does it work properly? Try to make it fail!
2. Are the best-practices implemented in the code?
3. Is the documentation clear?
4. Can you adapt the code easily? E.g. try to create a new type of random walker which moves two cells per iteration.
````

## Example
``random_walker run --total_steps 10000 --step_size 2 -l False``
172 changes: 141 additions & 31 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,147 @@

# Python code for 2D random walk.
# Source: https://www.geeksforgeeks.org/random-walk-implementation-python/
import numpy
import matplotlib.pyplot as plt
import random

# defining the number of steps
n = 100000

# creating two array for containing x and y coordinate
# of size equals to the number of size and filled up with 0's
x = numpy.zeros(n)
y = numpy.zeros(n)

# filling the coordinates with random variables
for i in range(1, n):
val = random.randint(1, 4)
if val == 1:
x[i] = x[i - 1] + 1
y[i] = y[i - 1]
elif val == 2:
x[i] = x[i - 1] - 1
y[i] = y[i - 1]
elif val == 3:
x[i] = x[i - 1]
y[i] = y[i - 1] + 1

import click
import raster_walker as rw
import vector_walker as vw


# user input – click
_total_steps_option = [
click.option(
"--total_steps",
"-ts",
default=10000,
type=int,
help="Specify the number of total steps for each random walker,"
"Default is 10,000, Minimum 100",
)
]

_total_walkers_option = [
click.option(
"--total_walkers",
"-tw",
default=1,
type=int,
help="Specify the number of total walkers, Default is 1, Minimum is 1",
)
]

_step_size_option = [
click.option(
"--step_size",
"-ss",
default=1,
type=int,
help="Specify the size of the steps taken, Default is 1",
)
]

_landscape_option = [
click.option(
"--landscape",
"-l",
default=False,
type=bool,
help="Specify whether a grid landscape exists as base layer or not, Default is False",
)
]

_start_point_option = [
click.option(
"--start_point",
"-sp",
default=False,
type=bool,
help="Specify whether the walkers shall start from the same point or not, Default is False",
)
]

_mov_pattern_option = [
click.option(
"--mov_pattern",
"-mp",
default=False,
type=bool,
help="Specify the neighborhood movement pattern, False is Neumann, True is Moor",
)
]


def add_options(options):
"""Functions adds options to cli."""

def _add_options(func):
for option in reversed(options):
func = option(func)
return func
return _add_options


@click.group()
@click.option('--verbose', '-v', is_flag=False, help="Will print verbose messages.")
def cli(verbose: bool) -> None:
if verbose:
click.echo("We are in the verbose mode. Which does not make any"
"difference right now.. but hey, have fun!")


@cli.command()
@add_options(_total_steps_option)
@add_options(_total_walkers_option)
@add_options(_step_size_option)
@add_options(_landscape_option)
@add_options(_start_point_option)
@add_options(_mov_pattern_option)
def run(
total_steps: int,
total_walkers: int,
step_size: int,
landscape: bool,
start_point: bool,
mov_pattern: bool
) -> None:
""" execute command to generate random walkers """
run_random_walkers(total_steps, total_walkers, step_size, landscape, start_point, mov_pattern)


def run_random_walkers(total_steps, total_walkers, step_size, landscape, diff_start, mov_pattern):
"""
executes the random walker tool based on input data
:param total_steps: number of total steps of the random walker
:param total_walkers: number of walkers
:param step_size: step size for each step
:param landscape: boolean, if True, 2D area with obstacles is generated as base layer
:param diff_start: boolean, if True, different start points for each walker
:param mov_pattern: boolean, if True, Moor'sche neighboorhood is used, else Neumann
:return:
"""

# adjust wrong input
total_steps = max(total_steps, 100)
total_walkers = max(total_walkers, 1)

# diverted because of the completely different implementation methods ->
# could be done better in the future
if landscape:
# percentage of how much space obstacles shall block
fill_percentage = 0.1
landscape_raster = rw.create_raster(total_steps, fill_percentage)
walk = rw.r_walker(total_steps, landscape_raster)
# plot landscape raster with obstacles and walker
rw.plot_raster(walk, total_steps)
else:
x[i] = x[i - 1]
y[i] = y[i - 1] - 1
# creating two arrays for containing x and y coordinate
# of size equals to the number of size and filled up with 0's
x_arr, y_arr = vw.create_walking_space(total_steps)

# multiple walkers
list_x, list_y = vw.multiple_v_walkers(x_arr, y_arr, total_steps, total_walkers,
step_size, diff_start, mov_pattern)
vw.plot_v_walkers(total_steps, total_walkers, list_x, list_y)


# plotting the walk
plt.title("Random Walk ($n = " + str(n) + "$ steps)")
plt.plot(x, y)
plt.savefig("./rand_walk_{}.png".format(n))
plt.show()
if __name__ == "__main__":
run_random_walkers(100, 5, 1, True, True, True)
Binary file removed rand_walk_100000.png
Binary file not shown.
Binary file added rand_walk_5_100.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading