2. Discussion: Should the walker become a class? What should the interface look like? #2

Open
opened 2025-09-17 14:51:52 +02:00 by Aitor · 10 comments
Owner

Right now, the walker logic is implemented as a collection of standalone functions (sample_next_step, next_step_proposal, compute_next_step_probability, etc.). While this works, it might be more maintainable to encapsulate the walker’s state and behavior into a Walker class.

Exercise instructions:
Open the notebook walker/Step_1_classes and follow the instructions. Think about what you think the Walker interface should look like and post your ideas as a comment to this issue.

Feel free to comment on other group's suggestions, respectfully.

Make sure to include your suggested code snippet(s)

Right now, the walker logic is implemented as a collection of standalone functions (`sample_next_step`, `next_step_proposal`, `compute_next_step_probability`, etc.). While this works, it might be more maintainable to encapsulate the walker’s state and behavior into a Walker class. **Exercise instructions:** Open the notebook `walker/Step_1_classes` and follow the instructions. Think about what you think the Walker interface should look like and post your ideas as a comment to this issue. Feel free to comment on other group's suggestions, respectfully. **Make sure to include your suggested code snippet(s)**
lisa changed title from Turn the walker code in to a class to 2. Walker code interface as a class 2025-09-22 17:30:42 +02:00
lisa changed title from 2. Walker code interface as a class to 2. Refactor: Walker code interface as a class 2025-09-22 17:32:22 +02:00
lisa changed title from 2. Refactor: Walker code interface as a class to 2. Discussion: Should the walker become a class? What should the interface look like? 2025-09-22 17:37:57 +02:00
Owner

Actually, I think the current interface is fine as it is @Aitor ! No changes needed at all. I like calling it like this:

i, j = 100, 50  # initial position
sigma_i, sigma_j = 3, 4  # parameters of the next step map
size = 200  # size of the image
context_map = create_context_map(size, 'hills')  # fixed context map

# Sample a next step 1000 times
trajectory = []
for _ in range(1000):
    i, j = sample_next_step(i, j, sigma_i, sigma_j, context_map)
    trajectory.append((i, j))

plot_trajectory(trajectory, context_map)
Actually, I think the current interface is fine as it is @Aitor ! No changes needed at all. I like calling it like this: ```python i, j = 100, 50 # initial position sigma_i, sigma_j = 3, 4 # parameters of the next step map size = 200 # size of the image context_map = create_context_map(size, 'hills') # fixed context map # Sample a next step 1000 times trajectory = [] for _ in range(1000): i, j = sample_next_step(i, j, sigma_i, sigma_j, context_map) trajectory.append((i, j)) plot_trajectory(trajectory, context_map) ```
Aitor added the
Conceptual
Enhancement
labels 2025-09-24 10:01:54 +02:00
Author
Owner

Thanks for the suggestion @lisa, but we do want to include modularity! I think re-structuring is much needed!

Thanks for the suggestion @lisa, but we do want to include modularity! I think re-structuring is much needed!
Member

We suggest to implement two classes:
Walker, with attributes

  • current_i
  • current_j
  • sigma_i
  • sigma_j
  • context_map
    methods:
    sample_next_step
    next_step_proposal
    compute_next_step_probability

ContextMap, with attributes

  • size
  • map type
    create_context_map is basically init and plot_trajectory could be a method
We suggest to implement two classes: Walker, with attributes - current_i - current_j - sigma_i - sigma_j - context_map methods: sample_next_step next_step_proposal compute_next_step_probability ContextMap, with attributes - size - map type create_context_map is basically init and plot_trajectory could be a method
Member

In walker.py, the functions sample_next_step, next_step_proposal and compute_next_step_probability can be consolidated into a class. This is because sample_next_step, next_step_proposal use similar inputs hence they seem to be an attribute of the walker. compute_next_step_probability uses and input from next_step_proposal and also seems to be an attribute of the walker.

class Walker:
   __init__(self, current_i, current_j, sigma_i, sigma_j, context_map, size):
     ....
    
def sample_next_step(self):

....

def next_step_proposal(self):
self.next_step_probability = ...
....

def compute_next_step_probability(self):
....


In `walker.py`, the functions `sample_next_step`, `next_step_proposal` and `compute_next_step_probability` can be consolidated into a class. This is because `sample_next_step`, `next_step_proposal` use similar inputs hence they seem to be an attribute of the walker. `compute_next_step_probability` uses and input from `next_step_proposal` and also seems to be an attribute of the walker. ```python class Walker: __init__(self, current_i, current_j, sigma_i, sigma_j, context_map, size): .... def sample_next_step(self): .... def next_step_proposal(self): self.next_step_probability = ... .... def compute_next_step_probability(self): .... ```
Owner

Could you add a Pseudo-code snippet to show what it would look like?

Could you add a Pseudo-code snippet to show what it would look like?
Member

We agree that a Walker class would be a good idea. However, what should be the attributes of this class probably depends on whether your walker is designed for only one specific use case. For instance, the context_map should only be a part of a Walker class if there is one specific use case.

We agree that a `Walker class` would be a good idea. However, what should be the attributes of this class probably depends on whether your walker is designed for only one specific use case. For instance, the `context_map` should only be a part of a Walker class if there is one specific use case.
Member

Pseudo Code

class Walker:
    def __init__(current_i, current_j, sigma_i, sigma_j, context_map):
    self.current_i = current_i
    ...
    def sample_next_step(self):
    ...
    def next_step_proposal(self):
    ...
    def compute_next_step_probability(self):
    ...


class ContextMap:
def __init__(size, map_type):

def plot_trajectory(self):

# Pseudo Code ```python class Walker: def __init__(current_i, current_j, sigma_i, sigma_j, context_map): self.current_i = current_i ... def sample_next_step(self): ... def next_step_proposal(self): ... def compute_next_step_probability(self): ... class ContextMap: def __init__(size, map_type): def plot_trajectory(self): ```
Member

We would definitely add a Walker class,, could be instantiated with pos and Gaussian parameters (some walkers might follow different probability distributions in their decision making). We could have simulate_trajectory as a classmethod with arguments context_map, nsteps. Plotting should be separate from the class, so trajectory needs to be returned.

We would definitely add a Walker class,, could be instantiated with pos and Gaussian parameters (some walkers might follow different probability distributions in their decision making). We could have `simulate_trajectory` as a classmethod with arguments `context_map`, nsteps. Plotting should be separate from the class, so trajectory needs to be returned.
Member

We agree that walker should be a class. Here's a rough implementation draft:

class Walker:
    def __init__(self, i, j, sigma_i, sigma_j, context_map, trajectory=None):
        self.i = i
        self.j = j
        self.sigma_i = sigma_i
        self.sigma_j = sigma_j
        self.context_map = context_map

        if trajectory is None:
            self.trajectory = []

    def walk_step(self):
        self.i, self.j = sample_next_step(self.i, self.j, self.sigma_i, self.sigma_j, self.context_map)

        self.trajectory.append((self.i, self.j))

    def walk_steps(self, n):
        for _ in range(n):
            self.walk_step()

    def show_trajectory(self):
        plot_trajectory(self.trajectory, self.context_map)

size = 200  # size of the image
context_map = create_context_map(size, 'hills')

walker = Walker(100, 50, 3, 4, context_map)
walker.walk_steps(1000)
walker.show_trajectory()
We agree that walker should be a class. Here's a rough implementation draft: ```python class Walker: def __init__(self, i, j, sigma_i, sigma_j, context_map, trajectory=None): self.i = i self.j = j self.sigma_i = sigma_i self.sigma_j = sigma_j self.context_map = context_map if trajectory is None: self.trajectory = [] def walk_step(self): self.i, self.j = sample_next_step(self.i, self.j, self.sigma_i, self.sigma_j, self.context_map) self.trajectory.append((self.i, self.j)) def walk_steps(self, n): for _ in range(n): self.walk_step() def show_trajectory(self): plot_trajectory(self.trajectory, self.context_map) size = 200 # size of the image context_map = create_context_map(size, 'hills') walker = Walker(100, 50, 3, 4, context_map) walker.walk_steps(1000) walker.show_trajectory() ```
Member

walker into class

class Walker
def init(i,j, sigma_i, sigma_j):
self.i= i
self.j =j
...
def context_map(self): .....
def next_step_sim(self): ....

# walker into class class Walker def __init__(i,j, sigma_i, sigma_j): self.i= i self.j =j ... def context_map(self): ..... def next_step_sim(self): ....
Sign in to join this conversation.
No milestone
No project
No assignees
8 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: ASPP/2025-plovdiv-scientific-patterns#2
No description provided.