File size: 3,808 Bytes
2afa69c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
857bbdd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2afa69c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

import numpy as np
import math
from .grid import WorldGrid
from .fluids import HydroKernel
from .erosion_process import ErosionProcess

class ScriptExecutor:
    """
    ์‚ฌ์šฉ์ž ์ •์˜ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰ ์—”์ง„
    ๋ณด์•ˆ์„ ์œ„ํ•ด ์ œํ•œ๋œ ํ™˜๊ฒฝ์—์„œ Python ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    """
    def __init__(self, grid: WorldGrid):
        self.grid = grid
        self.hydro = HydroKernel(grid)
        self.erosion = ErosionProcess(grid)
        
    def execute(self, script: str, dt: float = 1.0, allowed_modules: list = ['numpy', 'math']):
        """
        ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰
        
        Args:
            script: ์‹คํ–‰ํ•  Python ์ฝ”๋“œ ๋ฌธ์ž์—ด
            dt: ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ (Time Step)
            allowed_modules: ํ—ˆ์šฉํ•  ๋ชจ๋“ˆ ๋ฆฌ์ŠคํŠธ (๊ธฐ๋ณธ: numpy, math)
        
        Available Variables in Context:
            - grid: WorldGrid ๊ฐ์ฒด
            - elevation: grid.elevation (Numpy Array)
            - bedrock: grid.bedrock
            - sediment: grid.sediment
            - water_depth: grid.water_depth
            - dt: Delta Time
            - np: numpy module
            - math: math module
            - hydro: HydroKernel ๊ฐ์ฒด
            - erosion: ErosionProcess ๊ฐ์ฒด
        """
        
        # 1. ์‹คํ–‰ ์ปจํ…์ŠคํŠธ(Namespace) ์ค€๋น„
        context = {
            'grid': self.grid,
            'elevation': self.grid.elevation,
            'bedrock': self.grid.bedrock,
            'sediment': self.grid.sediment,
            'water_depth': self.grid.water_depth,
            'dt': dt,
            'np': np,
            'math': math,
            'hydro': self.hydro,
            'erosion': self.erosion,
            # Helper functions
            'max': max,
            'min': min,
            'abs': abs,
            'pow': pow,
            'print': print,  # ๋””๋ฒ„๊น…์šฉ
            'range': range,
            'len': len,
            'int': int,
            'float': float,
            'round': round,
            'sum': sum,
            'enumerate': enumerate,
            'zip': zip,
            'list': list,
            'tuple': tuple,
            'dict': dict,
            'set': set,
            'str': str,
            'bool': bool,
            'True': True,
            'False': False,
            'None': None,
        }
        
        # 2. ๊ธˆ์ง€๋œ ํ‚ค์›Œ๋“œ ์ฒดํฌ (๊ธฐ๋ณธ์ ์ธ ๋ณด์•ˆ)
        # ์™„๋ฒฝํ•œ ์ƒŒ๋“œ๋ฐ•์Šค๋Š” ์•„๋‹ˆ์ง€๋งŒ, ์‹ค์ˆ˜ ๋ฐฉ์ง€์šฉ
        forbidden = ['import os', 'import sys', 'open(', 'exec(', 'eval(', '__import__']
        for bad in forbidden:
            if bad in script:
                raise ValueError(f"๋ณด์•ˆ ๊ฒฝ๊ณ : ํ—ˆ์šฉ๋˜์ง€ ์•Š๋Š” ํ‚ค์›Œ๋“œ '{bad}'๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.")
                
        # 3. ์ฝ”๋“œ ์‹คํ–‰
        try:
            exec(script, {"__builtins__": {}}, context)
            
            # 4. ๋ณ€๊ฒฝ ์‚ฌํ•ญ ๋ฐ˜์˜ (Elevation์€ derived property์ง€๋งŒ, ์ง์ ‘ ์ˆ˜์ •ํ–ˆ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ)
            # ์‚ฌ์šฉ์ž๊ฐ€ elevation์„ ์ˆ˜์ •ํ–ˆ๋‹ค๋ฉด bedrock/sediment ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ชจํ˜ธํ•ด์ง.
            # Grid ํด๋ž˜์Šค์˜ update_elevation()์€ bedrock+sediment -> elevation์ด๋ฏ€๋กœ,
            # ์‚ฌ์šฉ์ž๊ฐ€ elevation์„ ์ˆ˜์ •ํ•˜๋ฉด ๋ฌด์‹œ๋  ์ˆ˜ ์žˆ์Œ.
            # ๊ฐ€์ด๋“œ: "bedrock"์ด๋‚˜ "sediment"๋ฅผ ์ˆ˜์ •ํ•˜์„ธ์š”.
            # ํ•˜์ง€๋งŒ ํŽธ์˜๋ฅผ ์œ„ํ•ด elevation์ด ๋ฐ”๋€Œ์—ˆ์œผ๋ฉด bedrock์— ๋ฐ˜์˜ํ•˜๋Š” ๋กœ์ง ์ถ”๊ฐ€
            
            # ๋ณ€๊ฒฝ ์ „ elevation๊ณผ ๋น„๊ตํ•ด์•ผ ํ•˜๋‚˜?
            # ์ผ๋‹จ grid.update_elevation()์„ ํ˜ธ์ถœํ•˜์—ฌ ๋™๊ธฐํ™”
            # (๋งŒ์•ฝ ์‚ฌ์šฉ์ž๊ฐ€ bedrock์„ ๋ฐ”๊ฟจ๋‹ค๋ฉด ๋ฐ˜์˜๋จ)
            self.grid.update_elevation()
            
            return True, "์‹คํ–‰ ์„ฑ๊ณต"
            
        except Exception as e:
            return False, f"์‹คํ–‰ ์˜ค๋ฅ˜: {str(e)}"