Skip to content

Surveys

Generate random surveys on grids.

SurveyParams

Bases: BaseModel

Parameters for survey generation.

Parameters:

Name Type Description Default
number int

Number of surveys

3
size int

Survey size

15
start_date date

Start date for specimen collection

datetime.date(2024, 3, 1)
max_interval int

Maximum interval between samples

7
Source code in src/snailz/surveys.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class SurveyParams(BaseModel):
    """Parameters for survey generation."""

    number: int = Field(default=3, gt=0, description="Number of surveys")
    size: int = Field(
        default=utils.DEFAULT_SURVEY_SIZE, gt=0, description="Survey size"
    )
    start_date: date = Field(
        default=date.fromisoformat("2024-03-01"),
        description="Start date for specimen collection",
    )
    max_interval: int = Field(
        gt=0, default=7, description="Maximum interval between samples"
    )

    model_config = {"extra": "forbid"}

Survey

Bases: BaseModel

A single survey.

Parameters:

Name Type Description Default
ident str

survey identifier

required
size int

survey size

required
start_date date

Start date for specimen collection

datetime.date(2024, 3, 1)
end_date date

End date for specimen collection

datetime.date(2024, 4, 30)
cells Grid[int] | None

survey cells

None
Source code in src/snailz/surveys.py
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
class Survey(BaseModel):
    """A single survey."""

    ident: str = Field(description="survey identifier")
    size: int = Field(description="survey size")
    start_date: date = Field(
        default=date.fromisoformat("2024-03-01"),
        description="Start date for specimen collection",
    )
    end_date: date = Field(
        default=date.fromisoformat("2024-04-30"),
        description="End date for specimen collection",
    )
    cells: Grid[int] | None = Field(default=None, description="survey cells")

    model_config = {"extra": "forbid"}

    @model_validator(mode="after")
    def initialize_grid(self):
        self.cells = Grid(width=self.size, height=self.size, default=0)
        self.fill_cells()
        return self

    def fill_cells(self) -> None:
        """Fill survey grid with fractal of random values."""
        assert isinstance(self.cells, Grid)
        size_1 = self.size - 1
        center = self.size // 2
        moves = [[-1, 0], [1, 0], [0, -1], [0, 1]]
        x, y = center, center
        self.cells[x, y] = 1
        while (x != 0) and (x != size_1) and (y != 0) and (y != size_1):
            self.cells[x, y] += 1
            m = random.choice(moves)
            x += m[0]
            y += m[1]

    def max_value(self) -> float:
        """Maximum cell value in this survey."""
        assert self.cells is not None  # for type checking
        result = self.cells[0, 0]
        for x in range(self.size):
            for y in range(self.size):
                result = max(result, self.cells[x, y])
        return result

    def to_csv(self) -> str:
        """Create a CSV representation of a single survey.

        Returns:
            A CSV-formatted string with survey cells.
        """
        assert isinstance(self.cells, Grid)
        output = io.StringIO()
        for y in range(self.size - 1, -1, -1):
            temp = [f"{self.cells[x, y]}" for x in range(self.size)]
            print(",".join(temp), file=output)
        return output.getvalue()

fill_cells()

Fill survey grid with fractal of random values.

Source code in src/snailz/surveys.py
54
55
56
57
58
59
60
61
62
63
64
65
66
def fill_cells(self) -> None:
    """Fill survey grid with fractal of random values."""
    assert isinstance(self.cells, Grid)
    size_1 = self.size - 1
    center = self.size // 2
    moves = [[-1, 0], [1, 0], [0, -1], [0, 1]]
    x, y = center, center
    self.cells[x, y] = 1
    while (x != 0) and (x != size_1) and (y != 0) and (y != size_1):
        self.cells[x, y] += 1
        m = random.choice(moves)
        x += m[0]
        y += m[1]

max_value()

Maximum cell value in this survey.

Source code in src/snailz/surveys.py
68
69
70
71
72
73
74
75
def max_value(self) -> float:
    """Maximum cell value in this survey."""
    assert self.cells is not None  # for type checking
    result = self.cells[0, 0]
    for x in range(self.size):
        for y in range(self.size):
            result = max(result, self.cells[x, y])
    return result

to_csv()

Create a CSV representation of a single survey.

Returns:

Type Description
str

A CSV-formatted string with survey cells.

Source code in src/snailz/surveys.py
77
78
79
80
81
82
83
84
85
86
87
88
def to_csv(self) -> str:
    """Create a CSV representation of a single survey.

    Returns:
        A CSV-formatted string with survey cells.
    """
    assert isinstance(self.cells, Grid)
    output = io.StringIO()
    for y in range(self.size - 1, -1, -1):
        temp = [f"{self.cells[x, y]}" for x in range(self.size)]
        print(",".join(temp), file=output)
    return output.getvalue()

AllSurveys

Bases: BaseModel

A set of generated surveys.

Parameters:

Name Type Description Default
items list[Survey]

all surveys

required
Source code in src/snailz/surveys.py
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
class AllSurveys(BaseModel):
    """A set of generated surveys."""

    items: list[Survey] = Field(description="all surveys")

    model_config = {"extra": "forbid"}

    def max_value(self) -> float:
        """Maximum cell value of all surveys in this set."""
        return max(survey.max_value() for survey in self.items)

max_value()

Maximum cell value of all surveys in this set.

Source code in src/snailz/surveys.py
 98
 99
100
def max_value(self) -> float:
    """Maximum cell value of all surveys in this set."""
    return max(survey.max_value() for survey in self.items)

surveys_generate(params)

Generate random surveys.

Parameters:

Name Type Description Default
params SurveyParams

Data generation parameters.

required

Returns:

Type Description
AllSurveys

Data model including all surveys.

Source code in src/snailz/surveys.py
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
def surveys_generate(params: SurveyParams) -> AllSurveys:
    """Generate random surveys.

    Parameters:
        params: Data generation parameters.

    Returns:
        Data model including all surveys.
    """

    gen = utils.unique_id("survey", _survey_id_generator)
    current_date = params.start_date
    items = []
    for _ in range(params.number):
        next_date = current_date + timedelta(
            days=random.randint(1, params.max_interval)
        )
        items.append(
            Survey(
                ident=next(gen),
                size=params.size,
                start_date=current_date,
                end_date=next_date,
            )
        )
        current_date = next_date + timedelta(days=1)

    return AllSurveys(items=items)

_survey_id_generator()

Generate unique ID for a survey.

Returns:

Type Description
str

Candidate ID 'gNNN'.

Source code in src/snailz/surveys.py
133
134
135
136
137
138
139
140
141
def _survey_id_generator() -> str:
    """Generate unique ID for a survey.

    Returns:
        Candidate ID 'gNNN'.
    """

    num = random.randint(0, 999)
    return f"S{num:03d}"