class_docstr: Structured environment version of the cutting 2D environment.
  The environment alternates between the two sub-steps:
  
  - Select cutting piece
  - Select cutting configuration (cutting order and cutting orientation)
  
  :param maze_env: The "flat" cutting 2D environment to wrap.
class_docstr_tok: ["Structured","environment","version","of","the","cutting","2D","environment",".","The","environment","alternates","between","the","two","sub-steps",":","-","Select","cutting","piece","-","Select","cutting","configuration","(","cutting","order","and","cutting","orientation",")",":","param","maze_env",":","The","``","flat","''","cutting","2D","environment","to","wrap","."]
docstr: Convert the flat action and MazeAction from Maze env into the structured ones.
  
  Note that both MazeState and MazeAction needs to be supplied together, otherwise actions/observations for the
  individual sub-steps cannot be produced.
docstr_tok: ["Convert","the","flat","action","and","MazeAction","from","Maze","env","into","the","structured","ones",".","Note","that","both","MazeState","and","MazeAction","needs","to","be","supplied","together",",","otherwise","actions\/observations","for","the","individual","sub-steps","can","not","be","produced","."]
code: def get_observation_and_action_dicts(
      self,
      maze_state: MazeStateType,
      maze_action: MazeActionType,
      first_step_in_episode: bool,
  ) -> Tuple[
      Optional[Dict[Union[int, str], Any]],
      Optional[Dict[Union[int, str], Any]],
  ]:
      """Convert the flat action and MazeAction from Maze env into the structured ones.
  
      Note that both MazeState and MazeAction needs to be supplied together, otherwise actions/observations for the
      individual sub-steps cannot be produced.
      """
      assert (
          maze_state is not None and maze_action is not None
      ), "This wrapper needs both MazeState and MazeAction for the conversion (as there are multiple sub-steps)."
      (
          observation_dict,
          action_dict,
      ) = self.env.get_observation_and_action_dicts(
          maze_state, maze_action, first_step_in_episode
      )
      assert (
          len(observation_dict.items()) == 1
          and len(action_dict.items()) == 1
      ), "wrapped env should be single-step"
  
      flat_action = list(action_dict.values())[0]
      flat_obs = list(observation_dict.values())[0]
  
      flat_obs["ordered_piece"] = flat_obs["ordered_piece"]
  
      obs_dict = {
          0: self._obs_selection_step(flat_obs),
          1: self._obs_cutting_step(flat_obs, flat_action["piece_idx"]),
      }
  
      act_dict = {
          0: {k: flat_action[k] for k in ["piece_idx"]},
          1: {k: flat_action[k] for k in ["cut_rotation", "cut_order"]},
      }
  
      return obs_dict, act_dict
  
imports: from copy import deepcopy
  from typing import Dict, Any, Union, Tuple, Optional, List
  import gym
  import numpy
  from maze.core.env.maze_action import MazeActionType
  from maze.core.env.maze_env import MazeEnv
  from maze.core.env.maze_state import MazeStateType
  from maze.core.env.structured_env import StructuredEnv, ActorID
  from maze.core.env.structured_env_spaces_mixin import StructuredEnvSpacesMixin
  from maze.core.wrappers.wrapper import Wrapper
  from .maze_env import maze_env_factory
label_desc: Use image node_id 18 for calling the StructuredCutting2DEnvironment obj's underlying member method code with example usage: obj.get_observation_and_action_dicts(maze_state, maze_action, first_step_in_episode) and returns: obs_dict,  act_dict