assert self.sender<EOL>if not self.round_lockset.num_eligible_votes == len(validators_H):<EOL><INDENT>raise InvalidProposalError('<STR_LIT>')<EOL><DEDENT>for v in self.round_lockset:<EOL><INDENT>if v.sender not in validators_H:<EOL><INDENT>raise InvalidProposalError('<STR_LIT>')<EOL><DEDENT><DEDENT>


privkeys = []<EOL>assert num <= num_colors<EOL>for i in range(num):<EOL><INDENT>j = <NUM_LIT:0><EOL>while True:<EOL><INDENT>k = sha3(str(j))<EOL>a = privtoaddr(k)<EOL>an = big_endian_to_int(a)<EOL>if an % num_colors == i:<EOL><INDENT>break<EOL><DEDENT>j += <NUM_LIT:1><EOL><DEDENT>privkeys.append(k)<EOL><DEDENT>return privkeys<EOL>

make privkeys that support coloring, see utils.cstr


def delay(self, sender, receiver, packet, add_delay=<NUM_LIT:0>):

bw = min(sender.ul_bandwidth, receiver.dl_bandwidth)<EOL>delay = sender.base_latency + receiver.base_latency<EOL>delay += len(packet) / bw<EOL>delay += add_delay<EOL>return delay<EOL>

bandwidths are inaccurate, as we don't account for parallel transfers here


def deliver(self, sender, receiver, packet):

to = ConsensusManager.round_timeout<EOL>assert to > <NUM_LIT:0><EOL>print("<STR_LIT>")<EOL>super(SlowTransport, self).deliver(sender, receiver, packet, add_delay=to)<EOL>


missing = self.missing<EOL>self.cm.log('<STR_LIT>', missing=len(missing), requested=len(self.requested),<EOL>received=len(self.received))<EOL>if self.requested:<EOL><INDENT>self.cm.log('<STR_LIT>')<EOL>return<EOL><DEDENT>if len(self.received) + self.max_getproposals_count >= self.max_queued:<EOL><INDENT>self.cm.log('<STR_LIT>')<EOL>return<EOL><DEDENT>if not missing:<EOL><INDENT>self.cm.log('<STR_LIT>')<EOL>return<EOL><DEDENT>if self.last_active_protocol is None:  <EOL><INDENT>self.cm.log('<STR_LIT>', last_active_protocol=self.last_active_protocol)<EOL>return<EOL><DEDENT>self.cm.log('<STR_LIT>')<EOL>blocknumbers = []<EOL>for h in missing:<EOL><INDENT>if h not in self.received and h not in self.requested:<EOL><INDENT>blocknumbers.append(h)<EOL>self.requested.add(h)<EOL>if len(blocknumbers) == self.max_getproposals_count:<EOL><INDENT>break<EOL><DEDENT><DEDENT><DEDENT>self.cm.log('<STR_LIT>', num=len(blocknumbers))<EOL>if not blocknumbers:<EOL><INDENT>return<EOL><DEDENT>self.cm.log('<STR_LIT>', num=len(blocknumbers),<EOL>requesting_range=(blocknumbers[<NUM_LIT:0>], blocknumbers[-<NUM_LIT:1>]))<EOL>self.last_active_protocol.send_getblockproposals(*blocknumbers)<EOL>self.cm.chainservice.setup_alarm(self.timeout, self.on_alarm, blocknumbers)<EOL>

sync the missing blocks between:
    head
    highest height with signing lockset

we get these locksets by collecting votes on all heights


assert isinstance(proto, HDCProtocol)<EOL>assert isinstance(proposal, Proposal)<EOL>if proposal.height >= self.cm.height:<EOL><INDENT>assert proposal.lockset.is_valid<EOL>self.last_active_protocol = proto<EOL><DEDENT>


def iter_attribute(iterable_name) -> Union[Iterable, Callable]:

def create_new_class(decorated_class) -> Union[Iterable, Callable]:<EOL><INDENT>"""<STR_LIT>"""<EOL>assert inspect.isclass(decorated_class), '<STR_LIT>'<EOL>assert isinstance(iterable_name, str), '<STR_LIT>'<EOL>decorated_class.iterator_attr_index = <NUM_LIT:0><EOL>def __iter__(instance) -> Iterable:<EOL><INDENT>"""<STR_LIT>"""<EOL>return instance<EOL><DEDENT>def __next__(instance) -> Any:<EOL><INDENT>"""<STR_LIT>"""<EOL>assert hasattr(instance, iterable_name),'<STR_LIT>'.format(iterable_name)<EOL>assert isinstance(getattr(instance, iterable_name), collections.Iterable),'<STR_LIT>'.format(iterable_name, instance.__class__.__name__)<EOL>ind = instance.iterator_attr_index<EOL>while ind < len(getattr(instance, iterable_name)):<EOL><INDENT>val = getattr(instance, iterable_name)[ind]<EOL>instance.iterator_attr_index += <NUM_LIT:1><EOL>return val<EOL><DEDENT>instance.iterator_attr_index = <NUM_LIT:0><EOL>raise StopIteration<EOL><DEDENT>dct = dict(decorated_class.__dict__)<EOL>dct['<STR_LIT>'] = __iter__<EOL>dct['<STR_LIT>'] = __next__<EOL>dct['<STR_LIT>'] = decorated_class.iterator_attr_index<EOL>return type(decorated_class.__name__, (collections.Iterable,), dct)<EOL><DEDENT>return create_new_class<EOL>

Decorator implementing Iterator interface with nicer manner.

    Example
    -------

    @iter_attribute('my_attr'):
    class DecoratedClass:
        ...

    Warning:
    ========

    When using PyCharm or MYPY you'll probably see issues with decorated class not being recognized as Iterator.
    That's an issue which I could not overcome yet, it's probably due to the fact that interpretation of object
    is being done statically rather than dynamically. MYPY checks for definition of methods in class code which
    changes at runtime. Since __iter__ and __next__ are added dynamically MYPY cannot find those
    defined in objects before object of a class is created. Possible workarounds for this issue are:

        1. Define ``dummy`` __iter__ class like:

            @iter_attribute('attr')
            class Test:
                def __init__(self) -> None:
                    self.attr = [1, 2, 3]

                def __iter__(self):
                    pass

        2. After creating object use cast or assert function denoting that particular instance inherits
            from collections.Iterator:

            assert isinstance(my_object, collections.Iterator)

    :param iterable_name: string representing attribute name which has to be iterated
    :return: DecoratedClass with implemented '__iter__' and '__next__' methods.


if server is None:<EOL><INDENT>from wsgiref.simple_server import make_server<EOL>server = lambda app: make_server('<STR_LIT>', <NUM_LIT>, app).serve_forever()<EOL>print('<STR_LIT>')<EOL><DEDENT>try:<EOL><INDENT>server(self)<EOL><DEDENT>finally:<EOL><INDENT>server.socket.close()<EOL><DEDENT>

Serve app using wsgiref or provided server.

        Args:
        - server (callable): An callable


def run_subprocess(command, cwd=None, stdout=None, stderr=None, shell=False, beat_freq=None):

sys.encoding = CONF.encoding<EOL>stdout = sys.stdout if stdout is None else stdout<EOL>stderr = sys.stderr if stderr is None else stderr<EOL>with subprocess.Popen(<EOL>command,<EOL>stdout=subprocess.PIPE,<EOL>stderr=subprocess.PIPE,<EOL>cwd=cwd,<EOL>shell=shell,<EOL>universal_newlines=True<EOL>) as sub_p:<EOL><INDENT>with redirect_stream(sub_p.stdout, stdout), redirect_stream(sub_p.stderr, stderr):<EOL><INDENT>while True:<EOL><INDENT>try:<EOL><INDENT>sub_p.wait(timeout=beat_freq)<EOL>break<EOL><DEDENT>except subprocess.TimeoutExpired:<EOL><INDENT>stdout.write("<STR_LIT>")<EOL>if hasattr(sys.stdout, "<STR_LIT>"):<EOL><INDENT>sys.stdout.flush()<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return sub_p.returncode<EOL><DEDENT>

Parameters
----------
command: command
cwd: current working directory
stdout: output info stream (must have 'write' method)
stderr: output error stream (must have 'write' method)
shell: see subprocess.Popen
beat_freq: if not none, stdout will be used at least every beat_freq (in seconds)


buffer, path = None, None<EOL>if isinstance(path_or_content, str):<EOL><INDENT>if path_or_content[-len(expected_extension)-<NUM_LIT:1>:] == "<STR_LIT>" % expected_extension:<EOL><INDENT>if not os.path.isfile(path_or_content):<EOL><INDENT>raise FileNotFoundError("<STR_LIT>" % path_or_content)<EOL><DEDENT>buffer, path = open(path_or_content, encoding=CONF.encoding), path_or_content<EOL><DEDENT>else:<EOL><INDENT>buffer = io.StringIO(path_or_content, )<EOL><DEDENT><DEDENT>elif isinstance(path_or_content, io.TextIOBase):<EOL><INDENT>buffer = path_or_content<EOL><DEDENT>elif isinstance(path_or_content, bytes):<EOL><INDENT>buffer = io.StringIO(path_or_content.decode(encoding=CONF.encoding))<EOL><DEDENT>elif isinstance(path_or_content, io.BufferedIOBase):<EOL><INDENT>buffer = io.StringIO(path_or_content.read().decode(encoding=CONF.encoding))<EOL><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return buffer, path<EOL>

path_or_content: path or content_str or content_bts or string_io or bytes_io

Returns
-------
string_buffer, path

path will be None if input was not a path


def switch_to_datetime_instants(df, start_year, eplus_frequency):

<EOL>if eplus_frequency in (TIMESTEP, DAILY, HOURLY, MONTHLY):<EOL><INDENT>if eplus_frequency in (TIMESTEP, HOURLY, DAILY):<EOL><INDENT>year_counter = (<EOL>(df[["<STR_LIT>", "<STR_LIT>"]] - df[["<STR_LIT>", "<STR_LIT>"]].shift()) ==<EOL>pd.Series(dict(month=<NUM_LIT:12>, day=-<NUM_LIT>))<EOL>).all(axis=<NUM_LIT:1>).cumsum()<EOL><DEDENT>else:<EOL><INDENT>year_counter = ((df["<STR_LIT>"] - df["<STR_LIT>"].shift()) == -<NUM_LIT:12>).cumsum()<EOL><DEDENT>df["<STR_LIT>"] = year_counter + start_year<EOL>columns = {<EOL>TIMESTEP: ("<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>"),<EOL>HOURLY: ("<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>"),<EOL>DAILY: ("<STR_LIT>", "<STR_LIT>", "<STR_LIT>"),<EOL>MONTHLY: ("<STR_LIT>", "<STR_LIT>")<EOL>}[eplus_frequency]<EOL>if eplus_frequency == MONTHLY:<EOL><INDENT>df.index = df.apply(  <EOL>lambda x: dt.datetime(*(tuple(int(x[k]) for k in columns) + (<NUM_LIT:1>,))),<EOL>axis=<NUM_LIT:1><EOL>)<EOL><DEDENT>else:<EOL><INDENT>df.index = df.apply(lambda x: dt.datetime(*(int(x[k]) for k in columns)), axis=<NUM_LIT:1>)<EOL><DEDENT>df.drop(columns=list(columns), inplace=True)<EOL>if eplus_frequency == TIMESTEP:<EOL><INDENT>ts = df.index[<NUM_LIT:1>] - df.index[<NUM_LIT:0>]<EOL>forced_df = df.asfreq(ts)<EOL><DEDENT>else:<EOL><INDENT>forced_df = df.asfreq({<EOL>HOURLY: "<STR_LIT:H>",<EOL>DAILY: "<STR_LIT:D>",<EOL>MONTHLY: "<STR_LIT>"<EOL>}[eplus_frequency])<EOL><DEDENT>if eplus_frequency in (TIMESTEP, HOURLY, DAILY):<EOL><INDENT>try:<EOL><INDENT>assert_index_equal(df.index, forced_df.index)<EOL><DEDENT>except AssertionError:<EOL><INDENT>raise ValueError(<EOL>f"<STR_LIT>"<EOL>f"<STR_LIT>"<EOL>) from None<EOL><DEDENT><DEDENT>return forced_df<EOL><DEDENT>if eplus_frequency == ANNUAL:<EOL><INDENT>if df["<STR_LIT>"].iloc[<NUM_LIT:0>] != start_year:<EOL><INDENT>raise ValueError(<EOL>f"<STR_LIT>"<EOL>f"<STR_LIT>")<EOL><DEDENT>df.index = df["<STR_LIT>"].map(lambda x: dt.datetime(x, <NUM_LIT:1>, <NUM_LIT:1>))<EOL>del df["<STR_LIT>"]<EOL>df = df.asfreq("<STR_LIT>")<EOL>return df<EOL><DEDENT>if eplus_frequency == RUN_PERIOD:<EOL><INDENT>return df<EOL><DEDENT>raise AssertionError("<STR_LIT>")<EOL>


self._path = None<EOL>self._path, buffer = to_buffer(buffer_or_path)<EOL>with buffer as f:<EOL><INDENT>self._raw_environments, self._raw_variables_info, self._dfs = parse_eso(f)<EOL><DEDENT>self._start_year = None<EOL>

Parameters
----------
buffer_or_path

Initially, standard_output will have tuple instants (using 'year', 'month', 'day', 'hour', 'minute' columns,
    depending on given frequency). It is possible to change to datetime mode later.


def get_data(self, environment_title_or_num=-<NUM_LIT:1>, frequency=None):

<EOL>if isinstance(environment_title_or_num, int):<EOL><INDENT>environment_title = tuple(self._raw_environments.keys())[environment_title_or_num]<EOL><DEDENT>else:<EOL><INDENT>environment_title = environment_title_or_num<EOL><DEDENT>if environment_title not in self._dfs:<EOL><INDENT>raise ValueError(f"<STR_LIT>")<EOL><DEDENT>environment_dfs = self._dfs[environment_title]<EOL>if frequency is None:<EOL><INDENT>for frequency in FREQUENCIES:<EOL><INDENT>if environment_dfs[frequency] is not None:<EOL><INDENT>break<EOL><DEDENT><DEDENT><DEDENT>if frequency not in FREQUENCIES:<EOL><INDENT>raise ValueError(f"<STR_LIT>")<EOL><DEDENT>return self._dfs[environment_title][frequency]<EOL>

Parameters
----------
environment_title_or_num
frequency: 'str', default None
    'timestep', 'hourly', 'daily', 'monthly', 'annual', 'run_period'
    If None, will look for the smallest frequency of environment.


def run_eplus(epm_or_idf_path, weather_data_or_epw_path, simulation_dir_path, stdout=None, stderr=None, beat_freq=None):

<EOL>simulation_dir_path = os.path.abspath(simulation_dir_path)<EOL>if not os.path.isdir(simulation_dir_path):<EOL><INDENT>raise NotADirectoryError("<STR_LIT>" % simulation_dir_path)<EOL><DEDENT>if not isinstance(epm_or_idf_path, Epm):<EOL><INDENT>epm = Epm.from_idf(epm_or_idf_path)<EOL><DEDENT>else:<EOL><INDENT>epm = epm_or_idf_path<EOL><DEDENT>simulation_idf_path = os.path.join(simulation_dir_path, CONF.default_model_name + "<STR_LIT>")<EOL>epm.to_idf(simulation_idf_path)<EOL>simulation_epw_path = os.path.join(simulation_dir_path, CONF.default_model_name + "<STR_LIT>")<EOL>if isinstance(weather_data_or_epw_path, WeatherData):<EOL><INDENT>weather_data_or_epw_path.to_epw(simulation_epw_path)<EOL><DEDENT>else:<EOL><INDENT>_copy_without_read_only(weather_data_or_epw_path, simulation_epw_path)<EOL><DEDENT>temp_epw_path = get_simulated_epw_path()<EOL>if temp_epw_path is not None:<EOL><INDENT>_copy_without_read_only(simulation_epw_path, temp_epw_path)<EOL><DEDENT>eplus_relative_cmd = get_simulation_base_command()<EOL>eplus_cmd = os.path.join(CONF.eplus_base_dir_path, eplus_relative_cmd)<EOL>idf_command_style = get_simulation_input_command_style("<STR_LIT>")<EOL>if idf_command_style == SIMULATION_INPUT_COMMAND_STYLES.simu_dir:<EOL><INDENT>idf_file_cmd = os.path.join(simulation_dir_path, CONF.default_model_name)<EOL><DEDENT>elif idf_command_style == SIMULATION_INPUT_COMMAND_STYLES.file_path:<EOL><INDENT>idf_file_cmd = simulation_idf_path<EOL><DEDENT>else:<EOL><INDENT>raise AssertionError("<STR_LIT>")<EOL><DEDENT>epw_command_style = get_simulation_input_command_style("<STR_LIT>")<EOL>if epw_command_style == SIMULATION_INPUT_COMMAND_STYLES.simu_dir:<EOL><INDENT>epw_file_cmd = os.path.join(simulation_dir_path, CONF.default_model_name)<EOL><DEDENT>elif epw_command_style == SIMULATION_INPUT_COMMAND_STYLES.file_path:<EOL><INDENT>epw_file_cmd = simulation_epw_path<EOL><DEDENT>else:<EOL><INDENT>raise AssertionError("<STR_LIT>")<EOL><DEDENT>simulation_command_style = get_simulation_command_style()<EOL>if simulation_command_style == SIMULATION_COMMAND_STYLES.args:<EOL><INDENT>cmd_l = [eplus_cmd, idf_file_cmd, epw_file_cmd]<EOL><DEDENT>elif simulation_command_style == SIMULATION_COMMAND_STYLES.kwargs:<EOL><INDENT>cmd_l = [eplus_cmd, "<STR_LIT>", epw_file_cmd, "<STR_LIT>", idf_file_cmd]<EOL><DEDENT>else:<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>run_subprocess(<EOL>cmd_l,<EOL>cwd=simulation_dir_path,<EOL>stdout=stdout,<EOL>stderr=stderr,<EOL>beat_freq=beat_freq<EOL>)<EOL>if (temp_epw_path is not None) and os.path.isfile(temp_epw_path):<EOL><INDENT>os.remove(os.path.join(temp_epw_path))<EOL><DEDENT>

Parameters
----------
epm_or_idf_path:
weather_data_or_epw_path
simulation_dir_path
stdout: default sys.stdout
stderr: default sys.stderr
beat_freq: if not none, stdout will be used at least every beat_freq (in seconds)


<EOL>if not os.path.isdir(base_dir_path):<EOL><INDENT>raise NotADirectoryError("<STR_LIT>" % base_dir_path)<EOL><DEDENT>simulation_dir_path = base_dir_path if simulation_name is None else os.path.join(base_dir_path, simulation_name)<EOL>if not os.path.exists(simulation_dir_path):<EOL><INDENT>os.mkdir(simulation_dir_path)<EOL><DEDENT>stdout = LoggerStreamWriter(logger_name=__name__, level=logging.INFO) if stdout is None else stdout<EOL>stderr = LoggerStreamWriter(logger_name=__name__, level=logging.ERROR) if stderr is None else stderr<EOL>run_eplus(<EOL>epm_or_path,<EOL>weather_data_or_path,<EOL>simulation_dir_path,<EOL>stdout=stdout,<EOL>stderr=stderr,<EOL>beat_freq=beat_freq<EOL>)<EOL>return cls(<EOL>base_dir_path,<EOL>simulation_name=simulation_name<EOL>)<EOL>

Parameters
----------
epm_or_path
weather_data_or_path
base_dir_path: simulation dir path
simulation_name: str, default None
    if provided, simulation will be done in {base_dir_path}/{simulation_name}
    else, simulation will be done in {base_dir_path}
stdout: stream, default logger.info
    stream where EnergyPlus standard output is redirected
stderr: stream, default logger.error
    stream where EnergyPlus standard error is redirected
beat_freq: float, default None
    if provided, subprocess in which EnergyPlus is run will write at given frequency in standard output. May
    be used to monitor subprocess state.

Returns
-------
Simulation instance


self._dir_path = base_dir_path if simulation_name is None else os.path.join(base_dir_path, simulation_name)<EOL>self._prepared_file_refs = None<EOL>self._outputs_cache = dict()<EOL>if not os.path.isdir(self._dir_path):<EOL><INDENT>raise NotADirectoryError("<STR_LIT>" % self._dir_path)<EOL><DEDENT>

Parameters
----------
base_dir_path: simulation dir path
simulation_name: str, default None
    if provided, simulation will be looked for in {base_dir_path}/{simulation_name}
    else, simulation will be looked for in {base_dir_path}

A simulation is not characterized by it's input files but by it's base_dir_path. This approach makes it
possible to load an already simulated directory without having to define it's idf or epw.


if self._prepared_file_refs is None:<EOL><INDENT>self._prepared_file_refs = {<EOL>FILE_REFS.idf: FileInfo(<EOL>constructor=lambda path: self._epm_cls.from_idf(path, idd_or_buffer_or_path=self._idd),<EOL>get_path=lambda: get_input_file_path(self.dir_path, FILE_REFS.idf)<EOL>),<EOL>FILE_REFS.epw: FileInfo(<EOL>constructor=lambda path: self._weather_data_cls.from_epw(path),<EOL>get_path=lambda: get_input_file_path(self.dir_path, FILE_REFS.epw)<EOL>),<EOL>FILE_REFS.eio: FileInfo(<EOL>constructor=lambda path: self._eio_cls(path),<EOL>get_path=lambda: get_output_file_path(self.dir_path, FILE_REFS.eio)<EOL>),<EOL>FILE_REFS.eso: FileInfo(<EOL>constructor=lambda path: self._standard_output_cls(path),<EOL>get_path=lambda: get_output_file_path(<EOL>self.dir_path,<EOL>FILE_REFS.eso<EOL>)<EOL>),<EOL>FILE_REFS.mtr: FileInfo(<EOL>constructor=lambda path: self._standard_output_cls(path),<EOL>get_path=lambda: get_output_file_path(self.dir_path, FILE_REFS.mtr)<EOL>),<EOL>FILE_REFS.mtd: FileInfo(<EOL>constructor=lambda path: self._mtd_cls(path),<EOL>get_path=lambda: get_output_file_path(self.dir_path, FILE_REFS.mtd)<EOL>),<EOL>FILE_REFS.mdd: FileInfo(<EOL>constructor=lambda path: open(path).read(),<EOL>get_path=lambda: get_output_file_path(self.dir_path, FILE_REFS.mdd)<EOL>),<EOL>FILE_REFS.err: FileInfo(<EOL>constructor=lambda path: self._err_cls(path),<EOL>get_path=lambda: get_output_file_path(self.dir_path, FILE_REFS.err)<EOL>),<EOL>FILE_REFS.summary_table: FileInfo(<EOL>constructor=lambda path: self._summary_table_cls(path),<EOL>get_path=lambda: get_output_file_path(self.dir_path, FILE_REFS.summary_table)<EOL>)<EOL>}<EOL><DEDENT>return self._prepared_file_refs<EOL>

Defined here so that we can use the class variables, in order to subclass in oplusplus


return self._dir_path<EOL>

Returns
-------
simulation directory path


if file_ref not in FILE_REFS:<EOL><INDENT>raise ValueError("<STR_LIT>" % (file_ref, list(sorted(FILE_REFS._fields))))<EOL><DEDENT>return os.path.isfile(self._path(file_ref))<EOL>

Parameters
----------
file_ref: str
    reference of file.
    Available references:  'idf', 'epw', 'eio', 'eso', 'mtr', 'mtd', 'mdd', 'err', 'summary_table'
    See EnergyPlus documentation for more information.

Returns
-------
Boolean


if not self.exists(file_ref):<EOL><INDENT>raise FileNotFoundError("<STR_LIT>" % (file_ref, self._path(file_ref)))<EOL><DEDENT>return self._path(file_ref)<EOL>

Parameters
----------
file_ref: str
    reference of file.
    Available references:  'idf', 'epw', 'eio', 'eso', 'mtr', 'mtd', 'mdd', 'err', 'summary_table'
    See EnergyPlus documentation for more information.

Returns
-------
Instance of required output.


<EOL>if df is None or len(df) == <NUM_LIT:0>:<EOL><INDENT>return df<EOL><DEDENT>if not isinstance(df.index, pd.DatetimeIndex):<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if df.index.freq != "<STR_LIT:H>":<EOL><INDENT>forced_df = df.asfreq("<STR_LIT:H>")<EOL>try:<EOL><INDENT>assert_index_equal(df.index, forced_df.index)<EOL><DEDENT>except AssertionError:<EOL><INDENT>raise ValueError(<EOL>f"<STR_LIT>"<EOL>f"<STR_LIT>"<EOL>) from None<EOL><DEDENT>df = forced_df<EOL><DEDENT>if df.index[<NUM_LIT:0>].minute != <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return df<EOL>

Parameters
----------
df

Returns
-------
sanitized df


<EOL>self._weather_series = _check_and_sanitize_weather_series(weather_series)<EOL>self._start_day_of_week = None<EOL>if self.has_tuple_instants and start_day_of_week is not None:<EOL><INDENT>self._start_day_of_week = start_day_of_week<EOL><DEDENT>else:<EOL><INDENT>self._set_start_day_of_week()<EOL><DEDENT>self._headers = dict(<EOL>latitude=latitude,<EOL>longitude=longitude,<EOL>timezone_offset=timezone_offset,<EOL>elevation=elevation,<EOL>city=city,<EOL>state_province_region=state_province_region,<EOL>country=country,<EOL>source=source,<EOL>wmo=wmo,<EOL>design_condition_source=design_condition_source,<EOL>design_conditions=[] if design_conditions is None else design_conditions,<EOL>typical_extreme_periods=[] if typical_extreme_periods is None else typical_extreme_periods,<EOL>ground_temperatures=[] if ground_temperatures is None else ground_temperatures,<EOL>leap_year_observed=leap_year_observed,<EOL>daylight_savings_start_day=daylight_savings_start_day,<EOL>daylight_savings_end_day=daylight_savings_end_day,<EOL>holidays=[] if holidays is None else holidays,  <EOL>comments_1=comments_1,<EOL>comments_2=comments_2<EOL>)<EOL>

For more information on following concepts, see EnergyPlus documentation :
    AuxiliaryPrograms.pdf: Weather Converter Program/EnergyPlus Weather File (EPW) Data Dictionary

Parameters
----------
weather_series: dataframe
    Must at least contain mandatory columns: 'drybulb', 'dewpoint', 'relhum', 'atmos_pressure', 'glohorrad',
    'dirnorrad', 'difhorrad', 'winddir',  'windspd'.

    Two instants modes are available:
     - datetime instants mode: index must be a hourly datetime index
     - tuple mode: index does not matter, and dataframe must have following instants columns: 'year', 'month',
         'day', 'hour', 'minute'. 'hour' is not written in a epw fashion ([0, 23], not [1, 24] as epw).

    Note that it will be possible, after weather data is created, to switch from datetime to tuple instants (or
    vice versa).
latitude
longitude
timezone_offset
elevation
city
state_province_region
country
source
wmo
design_condition_source
design_conditions
typical_extreme_periods
ground_temperatures
leap_year_observed
daylight_savings_start_day
daylight_savings_end_day
holidays
comments_1
comments_2
start_day_of_week


return self._weather_series.copy()<EOL>

Returns
-------
weather series dataframe, which contains all the timeseries data. Will be a datetime series or a tuple instants
series depending on current mode.


start, end = None, None<EOL>if len(self._weather_series) == <NUM_LIT:0>:<EOL><INDENT>return start, end<EOL><DEDENT>for i in (<NUM_LIT:0>, -<NUM_LIT:1>):<EOL><INDENT>if self.has_tuple_instants:<EOL><INDENT>row = self._weather_series.iloc[i, :]<EOL>instant = dt.datetime(row["<STR_LIT>"], row["<STR_LIT>"], row["<STR_LIT>"], row["<STR_LIT>"], row["<STR_LIT>"])<EOL><DEDENT>else:<EOL><INDENT>instant = self._weather_series.index[i].to_pydatetime()<EOL><DEDENT>if i == <NUM_LIT:0>:<EOL><INDENT>start = instant<EOL><DEDENT>else:<EOL><INDENT>end = instant<EOL><DEDENT><DEDENT>return start, end<EOL>

Returns
-------
(start, end)

Datetime instants of beginning and end of data. If no data, will be: (None, None).


from .epw_parse import parse_epw<EOL>_, buffer = to_buffer(buffer_or_path)<EOL>with buffer as f:<EOL><INDENT>return parse_epw(f)<EOL><DEDENT>

Parameters
----------
buffer_or_path: buffer or path containing epw format.

Returns
-------
WeatherData instance.


<EOL>df = self._weather_series.copy()<EOL>df["<STR_LIT>"] += <NUM_LIT:1><EOL>epw_content = self._headers_to_epw() + df.to_csv(header=False, index=False, line_terminator="<STR_LIT:\n>")<EOL>return multi_mode_write(<EOL>lambda buffer: buffer.write(epw_content),<EOL>lambda: epw_content,<EOL>buffer_or_path=buffer_or_path<EOL>)<EOL>

Parameters
----------
buffer_or_path: buffer or path, default None
    Buffer or path to write into. If None, will return a string containing epw info.

Returns
-------
None or a string if buffer_or_path is None.


<EOL>col_len = len(columns)<EOL>for i, r in enumerate(data):<EOL><INDENT>if len(r) != col_len:<EOL><INDENT>raise RuntimeError("<STR_LIT>" % (i, ref))<EOL><DEDENT><DEDENT>self._ref = ref<EOL>self._columns = columns<EOL>self._data = data<EOL>

Stores dataframe info without parsing types (otherwise dtypes are changed even if dtyp='object' is asked...)


def get_value(self, column_name_or_i, filter_column_name_or_i, filter_criterion):

<EOL>column_i = self._get_column_index(column_name_or_i)<EOL>filter_column_i = self._get_column_index(filter_column_name_or_i)<EOL>filter_fct = {<EOL>float: lambda x: float(x) == filter_criterion,<EOL>int: lambda x: int(x) == filter_criterion,<EOL>str: lambda x: x.lower() == filter_criterion.lower()<EOL>}[type(filter_criterion)]<EOL>for row_i, row in enumerate(self._data):<EOL><INDENT>if filter_fct(row[filter_column_i]):<EOL><INDENT>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return self._data[row_i][column_i]<EOL>

Returns first occurrence of value of filter column matching filter criterion.


from oplus import CONF  <EOL>cv = CONF.eplus_version[:<NUM_LIT:2>]<EOL>for v, value in sorted(d.items(), reverse=True):<EOL><INDENT>if cv >= v:<EOL><INDENT>return value<EOL><DEDENT><DEDENT>

Finds the value depending in current eplus version.

Parameters
----------
d: dict
    {(0, 0): value, (x, x): value, ...}
    for current version (cv), current value is the value of version v such as v <= cv < v+1


from oplus import CONF  <EOL>if OS_NAME == "<STR_LIT>":<EOL><INDENT>return os.path.join(CONF.eplus_base_dir_path, "<STR_LIT>", "<STR_LIT>" % CONF.default_model_name)<EOL><DEDENT>

Returns
-------
None if epw can be anywhere


<EOL>if output_category not in ("<STR_LIT>", "<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>raise RuntimeError(f"<STR_LIT>")<EOL><DEDENT>layouts = _layouts_matrix[OS_NAME][output_category]<EOL>return get_value_by_version(layouts)<EOL>

Parameters
----------
output_category: str
    inputs: epw, idf
    table: summary table
    other: other


<EOL>if len(self.eplus_available_versions) == <NUM_LIT:0>:<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>if self._eplus_version is not None:<EOL><INDENT>return self._eplus_version<EOL><DEDENT>return sorted(self.eplus_available_versions.keys(), reverse=True)[<NUM_LIT:0>]<EOL>

if _eplus_version is defined => _eplus_version
else most recent eplus available version


def get_data(self, simulation_step=None, error_category=None):

if simulation_step is None and error_category is None:<EOL><INDENT>return self._df.dropna(axis="<STR_LIT>", how="<STR_LIT:all>")<EOL><DEDENT>if simulation_step is not None:<EOL><INDENT>if simulation_step not in self._simulation_step_list:<EOL><INDENT>raise RuntimeError("<STR_LIT>" % simulation_step)<EOL><DEDENT>if error_category is not None:<EOL><INDENT>if error_category not in self.CATEGORIES:<EOL><INDENT>raise RuntimeError("<STR_LIT>" % error_category)<EOL><DEDENT>iterables = [simulation_step, error_category]<EOL>columns = pd.MultiIndex.from_product(iterables)<EOL>series = self._df[simulation_step][error_category].dropna(axis="<STR_LIT>", how="<STR_LIT:all>")<EOL>df = pd.DataFrame(index=series.index, columns=columns)<EOL>df[simulation_step] = series<EOL>return df<EOL><DEDENT>return self._df[simulation_step].dropna(axis="<STR_LIT>", how="<STR_LIT:all>")<EOL><DEDENT>if error_category is not None:<EOL><INDENT>if error_category not in self.CATEGORIES:<EOL><INDENT>raise RuntimeError("<STR_LIT>" % error_category)<EOL><DEDENT>df = self._df.copy()<EOL>df.columns = df.columns.swaplevel(<NUM_LIT:0>, <NUM_LIT:1>)<EOL>return df[error_category].dropna(axis="<STR_LIT>", how="<STR_LIT:all>")<EOL><DEDENT>

Parameters
----------
simulation_step: if not given, returns a raw report
error_category: if only one argument is specified, swaps dataframe report


def add(data=None, **or_data):<EOL><INDENT>"""<STR_LIT>"""<EOL>return self.batch_add([or_data if data is None else data])[<NUM_LIT:0>]<EOL><DEDENT>add.__doc__ = "<STR_LIT:\n>".join([fd.ref.lower() for fd in record_descriptors if fd.ref is not None])<EOL>return add<EOL>

this hack is used to document add function
a methods __doc__ attribute is read-only (or must use metaclasses, what I certainly don't want to do...)
we therefore create a function (who's __doc__ attribute is read/write), and will bind it to Table in __init__


added_records = []<EOL>for r_data in records_data:<EOL><INDENT>record = Record(<EOL>self,<EOL>data=r_data<EOL>)<EOL>self._records[record.get_pk()] = record<EOL>added_records.append(record)<EOL><DEDENT>return added_records<EOL>

inert: hooks and links are not activated


if isinstance(item, str):<EOL><INDENT>if self._dev_auto_pk:<EOL><INDENT>raise KeyError(f"<STR_LIT>")<EOL><DEDENT>try:<EOL><INDENT>return self._records[item]<EOL><DEDENT>except KeyError:<EOL><INDENT>raise KeyError(f"<STR_LIT>")<EOL><DEDENT><DEDENT>if isinstance(item, int):<EOL><INDENT>return self.select()[item]  <EOL><DEDENT>raise KeyError("<STR_LIT>")<EOL>

Parameters
----------
item: str or int
    if str: value of record name. If table does not have a name field, raises a KeyError
    if int: record position (records are ordered by their content, not by creation order)

Returns
-------
Record instance


return self._dev_descriptor.table_ref<EOL>

The table ref is the converted name, in order to be compatible with Python variable rules (so we can access
table from Epm using __getattr__.
Conversion rule: all non alphanumeric characters are transformed to underscores.
Example: 'Schedule_Compact'


return self._dev_descriptor.table_name<EOL>

The table name is the name given by EnergyPlus.
Example: 'Schedule:Compact'


records = self._records.values() if filter_by is None else filter(filter_by, self._records.values())<EOL>return Queryset(self, records=records)<EOL>

Parameters
----------
filter_by: callable, default None
    Callable must take one argument (a record of table), and return True to keep record, or False to skip it.
    Example : .select(lambda x: x.name == "my_name").
    If None, records are not filtered.

Returns
-------
Queryset instance, containing all selected records.


return Queryset(self, records=self._records.values()).one(filter_by=filter_by)<EOL>

Parameters
----------
filter_by: callable, default None
    Callable must take one argument (a record of table), and return True to keep record, or False to skip it.
    Example : .one(lambda x: x.name == "my_name").
    If None, records are not filtered.

Returns
-------
Record instance if one and only one record is found. Else raises.

Raises
------
RecordDoesNotExistError if no record is found
MultipleRecordsReturnedError if multiple records are found


<EOL>added_records = self._dev_add_inert(records_data)<EOL>for r in added_records:<EOL><INDENT>r._dev_activate_hooks()<EOL><DEDENT>for r in added_records:<EOL><INDENT>r._dev_activate_links()<EOL>r._dev_activate_external_files()<EOL><DEDENT>return Queryset(self, records=added_records)<EOL>

Parameters
----------
records_data: list of dictionaries containing records data. Keys of dictionary may be field names and/or field
    indexes

Returns
-------
Queryset instance of added records


self.select().delete()<EOL>


return self.select().to_json_data()<EOL>

Returns
-------
A dictionary of serialized data.


self._table = table  <EOL>self._data = {}<EOL>self._initialized = True<EOL>if data is not None:<EOL><INDENT>self._update_inert(data)<EOL><DEDENT>

Parameters
----------
table
data: dict, default {}
    key: index_or_ref, value: raw value or value


def _update_value_inert(self, index, value):

<EOL>field_descriptor = self._table._dev_descriptor.get_field_descriptor(index)<EOL>value = field_descriptor.deserialize(value, index)<EOL>if isinstance(value, Link):<EOL><INDENT>current_link = self._data.get(index)<EOL>if current_link is not None:<EOL><INDENT>current_link.unregister()<EOL><DEDENT><DEDENT>if isinstance(value, RecordHook):<EOL><INDENT>current_record_hook = self._data.get(index)<EOL>if current_record_hook is not None:<EOL><INDENT>current_record_hook.unregister()<EOL><DEDENT><DEDENT>if isinstance(value, ExternalFile):<EOL><INDENT>current_external_file = self._data.get(index)<EOL>if current_external_file is not None:<EOL><INDENT>current_external_file._dev_unregister()<EOL><DEDENT><DEDENT>if value in (None, NONE_RECORD_HOOK, NONE_LINK, NONE_EXTERNAL_FILE):<EOL><INDENT>self._dev_set_none_without_unregistering(index, check_not_required=False)<EOL>return<EOL><DEDENT>old_hook = None<EOL>if index == <NUM_LIT:0> and not self._table._dev_auto_pk:<EOL><INDENT>old_hook = self._data.get(<NUM_LIT:0>)  <EOL><DEDENT>self._data[index] = value<EOL>if old_hook is not None:<EOL><INDENT>self._table._dev_record_pk_was_updated(old_hook.target_value)<EOL><DEDENT>


<EOL>item = self._field_key_to_index(item)<EOL>if item > len(self):<EOL><INDENT>raise IndexError("<STR_LIT>")<EOL><DEDENT>value = self._data.get(item)<EOL>if isinstance(value, RecordHook):<EOL><INDENT>return value.target_value<EOL><DEDENT>if isinstance(value, Link):<EOL><INDENT>return value.target_record<EOL><DEDENT>return value<EOL>

Parameters
----------
item: field lowercase name or index

Returns
-------
Field value


self.update({key: value})<EOL>

Parameters
----------
key: field lowercase name or index
value: value to set


index = self._table._dev_descriptor.get_field_index(item)<EOL>return self[index]<EOL>


if name in self.__dict__ or not self._initialized:<EOL><INDENT>super().__setattr__(name, value)<EOL>return<EOL><DEDENT>self.update({name: value})<EOL>

Parameters
----------
name: field lowercase name
value: value to set


return id(self) if self._table._dev_auto_pk else self[<NUM_LIT:0>]<EOL>

Returns
-------
If record has a name, returns its name, else returns record's python id.


def get_serialized_value(self, ref_or_index, model_name=None):

index = (<EOL>self._table._dev_descriptor.get_field_index(ref_or_index) if isinstance(ref_or_index, str)<EOL>else ref_or_index<EOL>)<EOL>value = self._data.get(index)<EOL>value = value.serialize() if isinstance(value, (Link, RecordHook)) else value<EOL>if isinstance(value, ExternalFile):<EOL><INDENT>value = os.path.join(get_external_files_dir_name(model_name=model_name), value.naive_short_ref)<EOL><DEDENT>return value<EOL>

Parameters
----------
ref_or_index
external_files_mode: str, default 'path'
    'path', 'pointer'
model_file_path: str, default None
    if external files are asked in a relative fashion, relative path will be calculated relatively to
    model_file_path if given, else current directory

Returns
-------
serialized value (only basic types: string, int, float, None, ...)


return self.get_epm()._dev_relations_manager.get_pointed_from(self)<EOL>

Returns
-------
MultiTableQueryset of all records pointing on record.


return self.get_epm()._dev_relations_manager.get_pointing_on(self)<EOL>

Returns
-------
MultiTableQueryset of all records pointed by record.


return [v for v in self._data.values() if isinstance(v, ExternalFile)]<EOL>

Returns
-------
List of ExternalFiles instances contained by record.


<EOL>data = or_data if data is None else data<EOL>self._update_inert(data)<EOL>self._dev_activate_hooks()<EOL>self._dev_activate_links()<EOL>self._dev_activate_external_files()<EOL>

Updates simultaneously all given fields.

Parameters
----------
data: dictionary containing field lowercase names or index as keys, and field values as values (dict syntax)
or_data: keyword arguments containing field names as keys (kwargs syntax)


<EOL>if self._table._dev_auto_pk:<EOL><INDENT>return self._table.add(self._data)<EOL><DEDENT>name = str(uuid.uuid4()) if new_name is None else new_name<EOL>new_data = dict((k, name if k == <NUM_LIT:0> else v) for (k, v) in self._data.items())<EOL>return self._table.add(new_data)<EOL>

Parameters
----------
new_name: str, default None
    record's new name (if table has a name). If None although record has a name, a random uuid will be given.

Returns
-------
Copied record.


defaults = {}<EOL>for i in range(len(self)):<EOL><INDENT>if i in self._data:<EOL><INDENT>continue<EOL><DEDENT>default = self.get_field_descriptor(i).tags.get("<STR_LIT:default>", [None])[<NUM_LIT:0>]<EOL>if default is not None:<EOL><INDENT>defaults[i] = default<EOL><DEDENT><DEDENT>self.update(defaults)<EOL>

sets all empty fields for which a default value is defined to default value


if not self.is_extensible():<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>self_len = len(self)<EOL>data = dict([(self_len + i, args[i]) for i in range(len(args))])<EOL>self.update(data)<EOL>

This method only works for extensible fields. It allows to add values without precising their fields' names
or indexes.

Parameters
----------
args: field values


<EOL>index = self._prepare_pop_insert_index(index=index)<EOL>cycle_start, cycle_len, patterns = self.get_extensible_info()<EOL>fields = self.clear_extensible_fields()<EOL>serialized_value = fields.pop(index-cycle_start)<EOL>self.add_fields(*fields)<EOL>return serialized_value<EOL>

This method only works for extensible fields. It allows to remove a value and shift all other values to fill
the gap.

Parameters
----------
index: int, default None
    index of field to remove.

Returns
-------
serialize value of popped field


<EOL>index = self._prepare_pop_insert_index(index=index)<EOL>fields = self.clear_extensible_fields()<EOL>fields.insert(index, value)<EOL>self.add_fields(*fields)<EOL>

This method only works for extensible fields. It allows to insert a value, and shifts all other following
values.

Parameters
----------
index: position of insertion
value: value to insert


if not self.is_extensible():<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>cycle_start, cycle_len, patterns = self.get_extensible_info()<EOL>return [self.get_serialized_value(i) for i in range(cycle_start, len(self))]<EOL>

Returns
-------
list of cleared fields (serialized)


<EOL>self._unregister_links()<EOL>self._unregister_hooks()<EOL>self._unregister_external_files()<EOL>self.get_table()._dev_remove_record_without_unregistering(self)<EOL>self._table = None<EOL>self._data = None<EOL>

Deletes record, and removes it from database.


if isinstance(ref_or_index, int):<EOL><INDENT>index = ref_or_index<EOL><DEDENT>else:<EOL><INDENT>index = self._table._dev_descriptor.get_field_index(ref_or_index)<EOL><DEDENT>return self._table._dev_descriptor.get_field_descriptor(index)<EOL>

Parameters
----------
ref_or_index: str or int
    field lowercase name, or field position

Returns
-------
Field descriptor (info contained in Idd)


return self._table._dev_descriptor.extensible_info<EOL>

Returns
-------
cycle_start, cycle_len, patterns


return collections.OrderedDict([(k, self.get_serialized_value(k, model_name=model_name )) for k in self._data])<EOL>

Parameters
----------
model_name: str, default None
    if given, will be used as external file directory base name

Returns
-------
A dictionary of serialized data.


json_data = self.to_json_data(model_name=model_name)<EOL>s = f"<STR_LIT>"<EOL>fields_nb = max(self._data)+<NUM_LIT:1><EOL>for i in range(fields_nb):<EOL><INDENT>tab = "<STR_LIT:U+0020>" * TAB_LEN<EOL>raw_value = json_data.get(i, "<STR_LIT>")<EOL>content = f"<STR_LIT>"<EOL>spaces_nb = COMMENT_COLUMN_START - len(content)<EOL>if spaces_nb < <NUM_LIT:0>:<EOL><INDENT>spaces_nb = TAB_LEN<EOL><DEDENT>name = self._table._dev_descriptor.get_extended_name(i)<EOL>comment = "<STR_LIT>" if name is None else "<STR_LIT:U+0020>" * spaces_nb + f"<STR_LIT>"<EOL>s += f"<STR_LIT>"<EOL><DEDENT>return s<EOL>

Parameters
----------
 model_name: str, default None
    if given, will be used as external file directory base name

Returns
-------
idf string


tables_data = {}<EOL>head_comment = "<STR_LIT>"<EOL>record_data = None<EOL>make_new_record = True<EOL>copyright_list = get_multi_line_copyright_message().split("<STR_LIT:\n>")<EOL>for i, raw_line in enumerate(file_like):<EOL><INDENT>try:<EOL><INDENT>copyright_line = copyright_list[i]<EOL>if raw_line.strip() == copyright_line:<EOL><INDENT>continue<EOL><DEDENT><DEDENT>except IndexError:<EOL><INDENT>pass<EOL><DEDENT>split_line = raw_line.split("<STR_LIT:!>")<EOL>if len(split_line) == <NUM_LIT:1>:<EOL><INDENT>if len(split_line[<NUM_LIT:0>].strip()) == <NUM_LIT:0>:<EOL><INDENT>content, comment = None, None<EOL><DEDENT>else:<EOL><INDENT>content, comment = split_line[<NUM_LIT:0>].strip(), None<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if len(split_line[<NUM_LIT:0>].strip()) == <NUM_LIT:0>:<EOL><INDENT>content, comment = None, "<STR_LIT:!>".join(split_line[<NUM_LIT:1>:])<EOL><DEDENT>else:<EOL><INDENT>content, comment = split_line[<NUM_LIT:0>].strip(), "<STR_LIT:!>".join(split_line[<NUM_LIT:1>:])<EOL><DEDENT><DEDENT>if (content, comment) == (None, None):<EOL><INDENT>continue<EOL><DEDENT>if not content:<EOL><INDENT>if record_data is None:  <EOL><INDENT>head_comment += comment.strip() + "<STR_LIT:\n>"<EOL><DEDENT>continue<EOL><DEDENT>record_end = content[-<NUM_LIT:1>] == "<STR_LIT:;>"<EOL>content = content[:-<NUM_LIT:1>]  <EOL>content_l = [text.strip() for text in content.split("<STR_LIT:U+002C>")]<EOL>if make_new_record:<EOL><INDENT>table_ref = table_name_to_ref(content_l[<NUM_LIT:0>].strip())<EOL>if table_ref.lower() in (<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>",<EOL>"<STR_LIT>"<EOL>):<EOL><INDENT>continue<EOL><DEDENT>if table_ref not in tables_data:<EOL><INDENT>tables_data[table_ref] = []<EOL><DEDENT>record_data = dict()<EOL>tables_data[table_ref].append(record_data)<EOL>content_l = content_l[<NUM_LIT:1>:]<EOL>make_new_record = False<EOL><DEDENT>for value_s in content_l:<EOL><INDENT>field_index = len(record_data)<EOL>record_data[field_index] = value_s<EOL><DEDENT>if record_end:<EOL><INDENT>make_new_record = True<EOL><DEDENT><DEDENT>tables_data["<STR_LIT>"] = head_comment<EOL>return tables_data<EOL>

Records are created from string.
They are not attached to idf yet.
in idf: header comment, chapter comments, records
in record: head comment, field comments, tail comment


def __init__(self, hook_references, hook_value, source_index):

self.hook_references = hook_references<EOL>self.initial_hook_value = hook_value<EOL>self.source_index = source_index<EOL>self.source_record = None<EOL>self.target_record = None<EOL>self.target_table = None<EOL>

initial_hook_value may become obsolete when activated


<EOL>for k in self._tags:<EOL><INDENT>if "<STR_LIT>" in k:<EOL><INDENT>cycle_len = int(k.split("<STR_LIT::>")[<NUM_LIT:1>])<EOL>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>return<EOL><DEDENT>cycle_start = None<EOL>cycle_patterns = []<EOL>for i, field_descriptor in enumerate(self._field_descriptors):<EOL><INDENT>if (cycle_start is not None) and (i >= (cycle_start + cycle_len)):<EOL><INDENT>break<EOL><DEDENT>if (cycle_start is None) and ("<STR_LIT>" in field_descriptor.tags):<EOL><INDENT>cycle_start = i<EOL><DEDENT>if cycle_start is None:<EOL><INDENT>continue<EOL><DEDENT>cycle_patterns.append(field_descriptor.ref.replace("<STR_LIT:1>", r"<STR_LIT>"))<EOL><DEDENT>else:<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>self._field_descriptors = self._field_descriptors[:cycle_start + cycle_len]<EOL>self.extensible_info = (cycle_start, cycle_len, tuple(cycle_patterns))<EOL>for i, fd in enumerate(self._field_descriptors[cycle_start:]):<EOL><INDENT>fd.set_extensible_info(cycle_start, cycle_len, cycle_patterns[i])<EOL><DEDENT>

This function finishes initialization, must be called once all field descriptors and tag have been filled.


return len(self._field_descriptors) if self.extensible_info is None else self.extensible_info[<NUM_LIT:0>]<EOL>


<EOL>if self.extensible_info is None:<EOL><INDENT>return index<EOL><DEDENT>cycle_start, cycle_len, _ = self.extensible_info<EOL>if index < cycle_start:<EOL><INDENT>return index<EOL><DEDENT>return cycle_start + ((index - cycle_start) % cycle_len)<EOL>

reduced index: modulo of extensible has been applied


field_descriptor = self.get_field_descriptor(index)<EOL>if self.extensible_info is None:<EOL><INDENT>return field_descriptor.name<EOL><DEDENT>cycle_start, cycle_len, _ = self.extensible_info<EOL>cycle_num = (index - cycle_start) // cycle_len<EOL>return None if field_descriptor.name is None else field_descriptor.name.replace("<STR_LIT:1>", str(cycle_num))<EOL>


name, ext = os.path.splitext(model_name)<EOL>return name + CONF.external_files_suffix<EOL>

Parameters
----------
model_name: with or without extension


def __init__(self, check_required=True, idd_or_buffer_or_path=None):

self._dev_idd = (<EOL>idd_or_buffer_or_path if isinstance(idd_or_buffer_or_path, Idd) else<EOL>self._dev_idd_cls(idd_or_buffer_or_path)<EOL>)<EOL>self._dev_relations_manager = RelationsManager(self)<EOL>self._dev_external_files_manager = ExternalFilesManager(self)<EOL>self._tables = collections.OrderedDict(sorted([  <EOL>(table_descriptor.table_ref.lower(), Table(table_descriptor, self))<EOL>for table_descriptor in self._dev_idd.table_descriptors.values()<EOL>]))<EOL>self._dev_check_required = check_required<EOL>self._comment = "<STR_LIT>"<EOL>

An Epm is an Energy Plus Model.
It can come from and idf, a epjson (not coded yet), or a json.
It can be transformed in an idf, an epjson (not coded yet) or a json.

Parameters
----------
idd_or_buffer_or_path: (expert) if you wan't to use a specific idd.
check_required: boolean, default True
    If True, will raise an exception if a required field is missing. If False, not not perform any checks.


<EOL>comment = json_data.pop("<STR_LIT>", None)<EOL>if comment is not None:<EOL><INDENT>self._comment = comment<EOL><DEDENT>external_files_data = json_data.pop("<STR_LIT>", dict())<EOL>self._dev_external_files_manager.populate_from_json_data(external_files_data)<EOL>added_records = []<EOL>for table_ref, json_data_records in json_data.items():<EOL><INDENT>table = getattr(self, table_ref)<EOL>records = table._dev_add_inert(json_data_records)<EOL>added_records.extend(records)<EOL><DEDENT>for r in added_records:<EOL><INDENT>r._dev_activate_hooks()<EOL><DEDENT>for r in added_records:<EOL><INDENT>r._dev_activate_links()<EOL>r._dev_activate_external_files()<EOL><DEDENT>

!! Must only be called once, when empty !!


external_files = []<EOL>for table in self._tables.values():<EOL><INDENT>for r in table:<EOL><INDENT>external_files.extend([ef for ef in r.get_external_files()])<EOL><DEDENT><DEDENT>return external_files<EOL>


for table in self._tables.values():<EOL><INDENT>for r in table:<EOL><INDENT>r.set_defaults()<EOL><DEDENT><DEDENT>

All fields of Epm with a default value and that are null will be set to their default value.


self._dev_external_files_manager.dump_external_files(target_dir_path=target_dir_path)<EOL>


@classmethod<EOL><INDENT>def from_json_data(cls, json_data, check_required=True, idd_or_buffer_or_path=None):<DEDENT>

epm = cls(<EOL>idd_or_buffer_or_path=idd_or_buffer_or_path,<EOL>check_required=check_required<EOL>)<EOL>epm._dev_populate_from_json_data(json_data)<EOL>return epm<EOL>

Parameters
----------
json_data: dict
    Dictionary of serialized data (text, floats, ints, ...). For more information on data structure, create an
    Epm and use to_json_data or to_json.
check_required: boolean, default True
    If True, will raise an exception if a required field is missing. If False, not not perform any checks.
idd_or_buffer_or_path: (expert) to load using a custom idd

Returns
-------
An Epm instance.


@classmethod<EOL><INDENT>def from_idf(cls, buffer_or_path, check_required=True, idd_or_buffer_or_path=None):<DEDENT>

<EOL>return cls._create_from_buffer_or_path(<EOL>parse_idf,<EOL>buffer_or_path,<EOL>idd_or_buffer_or_path=idd_or_buffer_or_path,<EOL>check_required=check_required<EOL>)<EOL>

Parameters
----------
buffer_or_path: idf buffer or path
check_required: boolean, default True
    If True, will raise an exception if a required field is missing. If False, not not perform any checks.
idd_or_buffer_or_path: (expert) to load using a custom idd

Returns
-------
An Epm instance.


@classmethod<EOL><INDENT>def from_json(cls, buffer_or_path, check_required=True, idd_or_buffer_or_path=None):<DEDENT>

return cls._create_from_buffer_or_path(<EOL>json.load,<EOL>buffer_or_path,<EOL>idd_or_buffer_or_path=idd_or_buffer_or_path,<EOL>check_required=check_required<EOL>)<EOL>

Parameters
----------
buffer_or_path: json buffer or path
check_required: boolean, default True
    If True, will raise an exception if a required field is missing. If False, not not perform any checks.
idd_or_buffer_or_path: (expert) to load using a custom idd

Returns
-------
An Epm instance.


<EOL>d = collections.OrderedDict((t.get_ref(), t.to_json_data()) for t in self._tables.values())<EOL>d["<STR_LIT>"] = self._comment<EOL>d.move_to_end("<STR_LIT>", last=False)<EOL>d["<STR_LIT>"] = self._dev_external_files_manager<EOL>return d<EOL>

Returns
-------
A dictionary of serialized data.


def to_json(self, buffer_or_path=None, indent=<NUM_LIT:2>):

<EOL>return json_data_to_json(<EOL>self.to_json_data(),<EOL>buffer_or_path=buffer_or_path,<EOL>indent=indent<EOL>)<EOL>

Parameters
----------
buffer_or_path: buffer or path, default None
    output to write into. If None, will return a json string.
indent: int, default 2
    Defines the indentation of the json

Returns
-------
None, or a json string (if buffer_or_path is None).


def to_idf(self, buffer_or_path=None, dump_external_files=True):

<EOL>comment = get_multi_line_copyright_message()<EOL>if self._comment != "<STR_LIT>":<EOL><INDENT>comment += textwrap.indent(self._comment, "<STR_LIT>", lambda line: True)<EOL><DEDENT>comment += "<STR_LIT>"<EOL>if isinstance(buffer_or_path, str):<EOL><INDENT>dir_path, file_name = os.path.split(buffer_or_path)<EOL>model_name, _ = os.path.splitext(file_name)<EOL><DEDENT>else:<EOL><INDENT>model_name, dir_path = None, os.path.curdir<EOL><DEDENT>if dump_external_files:<EOL><INDENT>self.dump_external_files(<EOL>target_dir_path=os.path.join(dir_path, get_external_files_dir_name(model_name=model_name))<EOL>)<EOL><DEDENT>formatted_records = []<EOL>for table_ref, table in self._tables.items():  <EOL><INDENT>formatted_records.extend([r.to_idf(model_name=model_name) for r in sorted(table)])<EOL><DEDENT>body = "<STR_LIT>".join(formatted_records)<EOL>content = comment + body<EOL>return multi_mode_write(<EOL>lambda f: f.write(content),<EOL>lambda: content,<EOL>buffer_or_path<EOL>)<EOL>

Parameters
----------
buffer_or_path: buffer or path, default None
    output to write into. If None, will return a json string.
dump_external_files: boolean, default True
    if True, external files will be dumped in external files directory

Returns
-------
None, or an idf string (if buffer_or_path is None).


for key in hook.keys:<EOL><INDENT>if key in self._record_hooks:<EOL><INDENT>field_descriptor = hook.target_record.get_field_descriptor(hook.target_index)<EOL>raise FieldValidationError(<EOL>f"<STR_LIT>"<EOL>f"<STR_LIT>"<EOL>)<EOL><DEDENT>self._record_hooks[key] = hook<EOL><DEDENT>


keys = tuple((ref, link.initial_hook_value) for ref in link.hook_references)<EOL>for k in keys:<EOL><INDENT>if k in self._record_hooks:<EOL><INDENT>link.set_target(target_record=self._record_hooks[k].target_record)<EOL>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>for k in keys:<EOL><INDENT>if k in self._table_hooks:<EOL><INDENT>link.set_target(target_table=self._table_hooks[k])<EOL>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>field_descriptor = link.source_record.get_field_descriptor(link.source_index)<EOL>raise FieldValidationError(<EOL>f"<STR_LIT>"<EOL>f"<STR_LIT>"<EOL>)<EOL><DEDENT><DEDENT>if link.source_record not in self._links_by_source:<EOL><INDENT>self._links_by_source[link.source_record] = set()<EOL><DEDENT>self._links_by_source[link.source_record].add(link)<EOL>if link.target not in self._links_by_target:<EOL><INDENT>self._links_by_target[link.target] = set()<EOL><DEDENT>self._links_by_target[link.target].add(link)<EOL>

source record and index must have been set


<EOL>if isinstance(value, ExternalFile):<EOL><INDENT>value = value.pointer<EOL><DEDENT>if isinstance(value, Record):<EOL><INDENT>try:<EOL><INDENT>value = value[<NUM_LIT:0>]<EOL><DEDENT>except IndexError:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT><DEDENT>if isinstance(value, str):<EOL><INDENT>value = re.sub(spaces_and_newlines_pattern, lambda x: "<STR_LIT:U+0020>", value.strip())<EOL>if value == "<STR_LIT>":<EOL><INDENT>return None<EOL><DEDENT>value = unidecode.unidecode(value)<EOL>if "<STR_LIT>" not in self.tags:<EOL><INDENT>value = value.lower()<EOL><DEDENT>if len(value) >= <NUM_LIT:100>:<EOL><INDENT>raise FieldValidationError(<EOL>f"<STR_LIT>"<EOL>f"<STR_LIT>"<EOL>)<EOL><DEDENT><DEDENT>if self.is_file_name:<EOL><INDENT>value = ExternalFile.deserialize(value)<EOL><DEDENT>if self.detailed_type in ("<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>if value is None:<EOL><INDENT>return None<EOL><DEDENT>if value in ("<STR_LIT>", "<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>return value<EOL><DEDENT>if self.detailed_type == "<STR_LIT>":<EOL><INDENT>try:<EOL><INDENT>return int(value)<EOL><DEDENT>except:<EOL><INDENT>raise FieldValidationError(<EOL>f"<STR_LIT>"<EOL>)<EOL><DEDENT><DEDENT>try:<EOL><INDENT>return float(value)<EOL><DEDENT>except:<EOL><INDENT>raise FieldValidationError(<EOL>f"<STR_LIT>"<EOL>)<EOL><DEDENT><DEDENT>if self.detailed_type in ("<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>if value is None:<EOL><INDENT>return None<EOL><DEDENT>if not isinstance_str(value):<EOL><INDENT>raise FieldValidationError(<EOL>f"<STR_LIT>"<EOL>)<EOL><DEDENT>return value<EOL><DEDENT>if self.detailed_type == "<STR_LIT>":<EOL><INDENT>if value is None:<EOL><INDENT>return NONE_RECORD_HOOK<EOL><DEDENT>references = self.tags.get("<STR_LIT>", [])<EOL>return RecordHook(references, index, value)<EOL><DEDENT>if self.detailed_type == "<STR_LIT>":<EOL><INDENT>if value is None:<EOL><INDENT>return NONE_LINK<EOL><DEDENT>return Link(self.tags["<STR_LIT>"], value, index)<EOL><DEDENT>raise RuntimeError("<STR_LIT>")<EOL>

index is used for extensible fields error messages (if given)


if self._detailed_type is None:<EOL><INDENT>if ("<STR_LIT>" in self.tags) or ("<STR_LIT>" in self.tags):<EOL><INDENT>self._detailed_type = "<STR_LIT>"<EOL><DEDENT>elif "<STR_LIT:type>" in self.tags:<EOL><INDENT>self._detailed_type = self.tags["<STR_LIT:type>"][<NUM_LIT:0>].lower()  <EOL><DEDENT>elif "<STR_LIT:key>" in self.tags:<EOL><INDENT>self._detailed_type = "<STR_LIT>"<EOL><DEDENT>elif "<STR_LIT>" in self.tags:<EOL><INDENT>self._detailed_type = "<STR_LIT>"<EOL><DEDENT>elif "<STR_LIT>" in self.tags:<EOL><INDENT>self._detailed_type = "<STR_LIT>"<EOL><DEDENT>elif self.basic_type == "<STR_LIT:A>":<EOL><INDENT>self._detailed_type = "<STR_LIT>"<EOL><DEDENT>elif self.basic_type == "<STR_LIT:N>":<EOL><INDENT>self._detailed_type = "<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT><DEDENT>return self._detailed_type<EOL>

Uses EPlus double approach of type ('type' tag, and/or 'key', 'object-list', 'external-list', 'reference' tags)
to determine detailed type.

Returns
-------
"integer", "real", "alpha", "choice", "reference", "object-list", "external-list", "node"


<EOL>return [g[<NUM_LIT:0>].get_table_ref() for g in self._querysets.values()] + list(self.__dict__)<EOL>

Returns
-------
only returns non-empty querysets


self._contents = json_data<EOL>


naive_short_refs_d = dict()  <EOL>for ef in self._external_files:<EOL><INDENT>if ef.naive_short_ref not in naive_short_refs_d:<EOL><INDENT>naive_short_refs_d[ef.naive_short_ref] = set()<EOL><DEDENT>naive_short_refs_d[ef.naive_short_ref].add(ef.ref)<EOL><DEDENT>short_refs = dict()<EOL>for naive_short_ref, refs in naive_short_refs_d.items():<EOL><INDENT>if len(refs) == <NUM_LIT:1>:<EOL><INDENT>short_refs[refs.pop()] = naive_short_ref<EOL>continue<EOL><DEDENT>base, ext = os.path.splitext(naive_short_ref)<EOL>for i, ref in enumerate(sorted(refs)):<EOL><INDENT>short_refs[ref] = f"<STR_LIT>"<EOL><DEDENT><DEDENT>return short_refs<EOL>

we calculate on the fly to avoid managing registrations and un-registrations

Returns
-------
{ref: short_ref, ...


seen = set()<EOL>seen_add = seen.add<EOL>if key is None:<EOL><INDENT>for element in filterfalse(seen.__contains__, iterable):<EOL><INDENT>seen_add(element)<EOL>yield element<EOL><DEDENT><DEDENT>else:<EOL><INDENT>for element in iterable:<EOL><INDENT>k = key(element)<EOL>if k not in seen:<EOL><INDENT>seen_add(k)<EOL>yield element<EOL><DEDENT><DEDENT><DEDENT>

https://docs.python.org/3.6/library/itertools.html#itertools-recipes
List unique elements, preserving order. Remember all elements ever seen.

unique_ever_seen('AAAABBBCCDAABBB') --> A B C D
unique_ever_seen('ABBCcAD', str.lower) --> A B C D


return Queryset(self._table, list(self) + list(other))<EOL>

Add new query set to query set (only new records will be added since uniqueness is ensured in __init__).


iterator = self._records if filter_by is None else filter(filter_by, self._records)<EOL>return Queryset(self._table, iterator)<EOL>

Parameters
----------
filter_by: callable, default None
    Callable must take one argument (a record of queryset), and return True to keep record, or False to skip it.
    Example : .select(lambda x: x.name == "my_name").
    If None, records are not filtered.

Returns
-------
Queryset instance, containing all selected records.


<EOL>qs = self if filter_by is None else self.select(filter_by=filter_by)<EOL>if len(qs) == <NUM_LIT:0>:<EOL><INDENT>raise RecordDoesNotExistError("<STR_LIT>")<EOL><DEDENT>if len(qs) > <NUM_LIT:1>:<EOL><INDENT>raise MultipleRecordsReturnedError("<STR_LIT>")<EOL><DEDENT>return qs[<NUM_LIT:0>]<EOL>

Parameters
----------
filter_by: callable, default None
    Callable must take one argument (a record of table), and return True to keep record, or False to skip it.
    Example : .one(lambda x: x.name == "my_name").
    If None, records are not filtered.

Returns
-------
Record instance if one and only one record is found. Else raises.

Raises
------
RecordDoesNotExistError if no record is found
MultipleRecordsReturnedError if multiple records are found


<EOL>for r in self:<EOL><INDENT>r.delete()<EOL><DEDENT>self._records = ()<EOL>


<EOL>return [r.to_json_data() for r in self._records]<EOL>


def __init__(self, references, index, value):

self.references = references<EOL>self.target_index = index<EOL>self.target_value = value<EOL>self.target_record = None<EOL>

target_value must always be relevant : !! don't forget to deactivate hook if field of record changes !!


self.category = category<EOL>self.text = "<STR_LIT>"<EOL>

Parameters
----------
category: str,
    code, markdown


<EOL>epw_path = os.path.join(CONF.eplus_base_dir_path, "<STR_LIT>",<EOL>"<STR_LIT>")<EOL>idf_dir_path = os.path.join(CONF.eplus_base_dir_path, "<STR_LIT>")<EOL>test_num = <NUM_LIT:0><EOL>for file_num, file_name in enumerate(os.listdir(idf_dir_path)):<EOL><INDENT>if file_num < START_FILE_NUM:<EOL><INDENT>continue<EOL><DEDENT>base, ext = os.path.splitext(file_name)<EOL>if ext == "<STR_LIT>":<EOL><INDENT>with tempfile.TemporaryDirectory() as simulation_dir_path:<EOL><INDENT>s = simulate(os.path.join(idf_dir_path, file_name), epw_path,<EOL>simulation_dir_path if DEBUG_SIMUL_DIR_PATH is None else<EOL>DEBUG_SIMUL_DIR_PATH)<EOL>if s.exists("<STR_LIT>"):<EOL><INDENT>eio = Eio(s.get_file_path("<STR_LIT>"))  <EOL>test_num += <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT>if test_num == MAX_TESTS_NB:<EOL><INDENT>break<EOL><DEDENT><DEDENT>

Tested under EPlus 8.1.0 on Windows (Geoffroy).


_base, ext = os.path.splitext(fname)<EOL>if not ext:<EOL><INDENT>return None<EOL><DEDENT>try:<EOL><INDENT>format = known_extensions[ext.replace('<STR_LIT:.>','<STR_LIT>')]<EOL><DEDENT>except KeyError:<EOL><INDENT>format = None<EOL><DEDENT>return format<EOL>

Tries to infer a protocol from the file extension.


for component in components:<EOL><INDENT>if isinstance(component, Ellipse):<EOL><INDENT>component.x_origin = component.e_width<EOL>component.y_origin = component.e_height<EOL><DEDENT>elif isinstance(component, (Polygon, BSpline)):<EOL><INDENT>min_x = min( [t[<NUM_LIT:0>] for t in component.points] )<EOL>min_y = min( [t[<NUM_LIT:1>] for t in component.points] )<EOL>component.points = [<EOL>( p[<NUM_LIT:0>]-min_x, p[<NUM_LIT:1>]-min_y ) for p in component.points<EOL>]<EOL><DEDENT>elif isinstance(component, Text):<EOL><INDENT>font = str_to_font( str(component.pen.font) )<EOL>component.text_x = <NUM_LIT:0><EOL>component.text_y = <NUM_LIT:0><EOL><DEDENT><DEDENT>

Components are positioned relative to their container. Use this
        method to position the bottom-left corner of the components at
        the origin.


def save_to_file_like(self, flo, format=None, **kwargs):

format = self.format if format is None else format<EOL>save = getattr(self, "<STR_LIT>" % format, None)<EOL>if save is None:<EOL><INDENT>raise ValueError("<STR_LIT>" % format)<EOL><DEDENT>save(flo, **kwargs)<EOL>

Save the object to a given file like object in the given format.


@classmethod<EOL><INDENT>def load_from_file_like(cls, flo, format=None):<DEDENT>

format = self.format if format is None else format<EOL>load = getattr(cls, "<STR_LIT>" % format, None)<EOL>if load is None:<EOL><INDENT>raise ValueError("<STR_LIT>" % format)<EOL><DEDENT>return load(flo)<EOL>

Load the object to a given file like object with the given
            protocol.


def save_to_file(self, filename, format=None, **kwargs):

if format is None:<EOL><INDENT>format = format_from_extension(filename)<EOL><DEDENT>with file(filename, '<STR_LIT:wb>') as fp:<EOL><INDENT>self.save_to_file_like(fp, format, **kwargs)<EOL><DEDENT>

Save the object to file given by filename.


@classmethod<EOL><INDENT>def load_from_file(cls, filename, format=None):<DEDENT>

if format is None:<EOL><INDENT>format = format_from_extension(filename)<EOL><DEDENT>with file(filename,'<STR_LIT>') as fp:<EOL><INDENT>obj = cls.load_from_file_like(fp, format)<EOL>obj.filename = filename<EOL>return obj<EOL><DEDENT>

Return an instance of the class that is saved in the file with the
            given filename in the specified format.


def make_unique_name(base, existing=[], format="<STR_LIT>"):

count = <NUM_LIT:2><EOL>name = base<EOL>while name in existing:<EOL><INDENT>name = format % (base, count)<EOL>count += <NUM_LIT:1><EOL><DEDENT>return name<EOL>

Return a name, unique within a context, based on the specified name.

base: the desired base name of the generated unique name.
existing: a sequence of the existing names to avoid returning.
format: a formatting specification for how the name is made unique.


return [xy for xy in zip(*[iter(seq)]*n)]<EOL>

Split a sequence into pieces of length n

    If the length of the sequence isn't a multiple of n, the rest is discarded.
    Note that nsplit will split strings into individual characters.

    Examples:
    >>> nsplit("aabbcc")
    [("a", "a"), ("b", "b"), ("c", "c")]
    >>> nsplit("aabbcc",n=3)
    [("a", "a", "b"), ("b", "c", "c")]

    # Note that cc is discarded
    >>> nsplit("aabbcc",n=4)
    [("a", "a", "b", "b")]


def windows(iterable, length=<NUM_LIT:2>, overlap=<NUM_LIT:0>, padding=True):

it = iter(iterable)<EOL>results = list(itertools.islice(it, length))<EOL>while len(results) == length:<EOL><INDENT>yield results<EOL>results = results[length-overlap:]<EOL>results.extend(itertools.islice(it, length-overlap))<EOL><DEDENT>if padding and results:<EOL><INDENT>results.extend(itertools.repeat(None, length-len(results)))<EOL>yield results<EOL><DEDENT>

Code snippet from Python Cookbook, 2nd Edition by David Ascher,
    Alex Martelli and Anna Ravenscroft; O'Reilly 2005

    Problem: You have an iterable s and need to make another iterable whose
    items are sublists (i.e., sliding windows), each of the same given length,
    over s' items, with successive windows overlapping by a specified amount.


def postParse(self, instring, loc, tokenlist):

return bool(tokenlist[<NUM_LIT:0>])<EOL>


return int(tokenlist[<NUM_LIT:0>])<EOL>


return float(tokenlist[<NUM_LIT:0>])<EOL>


return tuple(tokenlist)<EOL>

Returns a tuple initialised from the token sequence.


return list(tokenlist)<EOL>

Returns a list initialised from the token sequence.


return len(self.nodes)<EOL>

Return the order of the graph when requested by len().

            @rtype:  number
            @return: Size of the graph.


for each in self.nodes:<EOL><INDENT>yield each<EOL><DEDENT>

Return a iterator passing through all nodes in the graph.

            @rtype:  iterator
            @return: Iterator passing through all nodes in the graph.


for each_edge in self.edges:<EOL><INDENT>if (each_edge.tail_node == node) or (each_edge.head_node == node):<EOL><INDENT>yield each_edge<EOL><DEDENT><DEDENT>

Return a iterator passing through all neighbours of the given node.

            @rtype:  iterator
            @return: Iterator passing through all neighbours of the given node.


s = "<STR_LIT>"<EOL>padding = self.padding<EOL>if self.ID:<EOL><INDENT>s += "<STR_LIT>" % self.ID<EOL><DEDENT>else:<EOL><INDENT>s += "<STR_LIT>"<EOL><DEDENT>for trait_name, trait in self.traits(graphviz=True).items():<EOL><INDENT>value = getattr(self, trait_name)<EOL>if ( value != trait.default ) and ( trait.default is not None ):<EOL><INDENT>if isinstance( value, str ):<EOL><INDENT>valstr = '<STR_LIT>' % value<EOL><DEDENT>else:<EOL><INDENT>valstr = str(value)<EOL><DEDENT>s += "<STR_LIT>" % ( padding, trait_name, valstr )<EOL><DEDENT><DEDENT>def prepend_padding(s):<EOL><INDENT>return "<STR_LIT:\n>".join( [padding + line for line in s.splitlines()] )<EOL><DEDENT>for node in self.nodes:<EOL><INDENT>s += "<STR_LIT>" % ( padding, str(node) )<EOL><DEDENT>for edge in self.edges:<EOL><INDENT>s += "<STR_LIT>" % ( padding, str(edge) )<EOL><DEDENT>for subgraph in self.subgraphs:<EOL><INDENT>s += prepend_padding( str( subgraph ) ) + "<STR_LIT:\n>"<EOL><DEDENT>for cluster in self.clusters:<EOL><INDENT>s += prepend_padding( str( cluster ) ) + "<STR_LIT:\n>"<EOL><DEDENT>s += "<STR_LIT:}>"<EOL>return s<EOL>

Returns a string representation of the graph in dot language. It
            will return the graph and all its subelements in string form.


return Node("<STR_LIT:default>")<EOL>


return Edge("<STR_LIT>", "<STR_LIT>")<EOL>


return godot.cluster.Cluster(ID="<STR_LIT>")<EOL>


progs = find_graphviz()<EOL>if progs is None:<EOL><INDENT>logger.warning("<STR_LIT>")<EOL>return {}<EOL><DEDENT>else:<EOL><INDENT>return progs<EOL><DEDENT>


return Container(draw_axes=True, fit_window=False, auto_size=True)<EOL>


vp = Viewport(component=self.component)<EOL>vp.enable_zoom=True<EOL>vp.view_position = [-<NUM_LIT:5>, -<NUM_LIT:5>]<EOL>vp.tools.append(ViewportPanTool(vp))<EOL>return vp<EOL>


flo.write( str(self) )<EOL>

Writes a graph to a file.

            Given a file like object 'flo' it will truncate it and write a
            representation of the graph defined by the dot object and in the
            format specified.
            The format 'raw' is used to dump the string representation
            of the Dot object, without further processing.
            The output can be processed by any of graphviz tools, defined
            in 'prog', which defaults to 'dot'.


def create(self, prog=None, format=None):

prog = self.program if prog is None else prog<EOL>format = self.format if format is None else format<EOL>tmp_fd, tmp_name = tempfile.mkstemp()<EOL>os.close( tmp_fd )<EOL>dot_fd = file( tmp_name, "<STR_LIT>" )<EOL>self.save_dot( dot_fd )<EOL>dot_fd.close()<EOL>tmp_dir = os.path.dirname( tmp_name )<EOL>p = subprocess.Popen(<EOL>( self.programs[ prog ], '<STR_LIT>'+format, tmp_name ),<EOL>cwd=tmp_dir,<EOL>stderr=subprocess.PIPE, stdout=subprocess.PIPE)<EOL>stderr = p.stderr<EOL>stdout = p.stdout<EOL>stdout_output = list()<EOL>while True:<EOL><INDENT>data = stdout.read()<EOL>if not data:<EOL><INDENT>break<EOL><DEDENT>stdout_output.append(data)<EOL><DEDENT>stdout.close()<EOL>if stdout_output:<EOL><INDENT>stdout_output = '<STR_LIT>'.join(stdout_output)<EOL><DEDENT>if not stderr.closed:<EOL><INDENT>stderr_output = list()<EOL>while True:<EOL><INDENT>data = stderr.read()<EOL>if not data:<EOL><INDENT>break<EOL><DEDENT>stderr_output.append(data)<EOL><DEDENT>stderr.close()<EOL>if stderr_output:<EOL><INDENT>stderr_output = '<STR_LIT>'.join(stderr_output)<EOL><DEDENT><DEDENT>status = p.wait()<EOL>if status != <NUM_LIT:0> :<EOL><INDENT>logger.error("<STR_LIT>""<STR_LIT>" % ( status, stderr_output ) )<EOL><DEDENT>elif stderr_output:<EOL><INDENT>logger.error( "<STR_LIT:%s>", stderr_output )<EOL><DEDENT>os.unlink(tmp_name)<EOL>return stdout_output<EOL>

Creates and returns a representation of the graph using the
            Graphviz layout program given by 'prog', according to the given
            format.

            Writes the graph to a temporary dot file and processes it with
            the program given by 'prog' (which defaults to 'dot'), reading
            the output and returning it as a string if the operation is
            successful. On failure None is returned.


import godot.dot_data_parser<EOL>parser = godot.dot_data_parser.GodotDataParser()<EOL>xdot_data = self.create( format = "<STR_LIT>" )<EOL>print("<STR_LIT>", str( self ))<EOL>print("<STR_LIT>", xdot_data)<EOL>parser.dotparser.parseWithTabs()<EOL>ndata = xdot_data.replace( "<STR_LIT>", "<STR_LIT>" )<EOL>tokens = parser.dotparser.parseString( ndata )[<NUM_LIT:0>]<EOL>parser.build_graph( graph=self, tokens=tokens[<NUM_LIT:3>] )<EOL>

Sets for the _draw_ and _ldraw_ attributes for each of the graph
            sub-elements by processing the xdot format of the graph.


if not isinstance(node_or_ID, Node):<EOL><INDENT>nodeID = str( node_or_ID )<EOL>if nodeID in self.nodes:<EOL><INDENT>node = self.nodes[ self.nodes.index(nodeID) ]<EOL><DEDENT>else:<EOL><INDENT>if self.default_node is not None:<EOL><INDENT>node = self.default_node.clone_traits(copy="<STR_LIT>")<EOL>node.ID = nodeID<EOL><DEDENT>else:<EOL><INDENT>node = Node(nodeID)<EOL><DEDENT>self.nodes.append( node )<EOL><DEDENT><DEDENT>else:<EOL><INDENT>node = node_or_ID<EOL>if node in self.nodes:<EOL><INDENT>node = self.nodes[ self.nodes.index(node_or_ID) ]<EOL><DEDENT>else:<EOL><INDENT>self.nodes.append( node )<EOL><DEDENT><DEDENT>node.set( **kwds )<EOL>return node<EOL>


if isinstance(node_or_ID, Node):<EOL><INDENT>name = node_or_ID.ID<EOL>


for node in self.nodes:<EOL><INDENT>if node.ID == str(ID):<EOL><INDENT>return node<EOL><DEDENT><DEDENT>return None<EOL>

Returns the node with the given ID or None.


def delete_edge(self, tail_node_or_ID, head_node_or_ID):

if isinstance(tail_node_or_ID, Node):<EOL><INDENT>tail_node = tail_node_or_ID<EOL><DEDENT>else:<EOL><INDENT>tail_node = self.get_node(tail_node_or_ID)<EOL><DEDENT>if isinstance(head_node_or_ID, Node):<EOL><INDENT>head_node = head_node_or_ID<EOL><DEDENT>else:<EOL><INDENT>head_node = self.get_node(head_node_or_ID)<EOL><DEDENT>if (tail_node is None) or (head_node is None):<EOL><INDENT>return None<EOL><DEDENT>for i, edge in enumerate(self.edges):<EOL><INDENT>if (edge.tail_node == tail_node) and (edge.head_node == head_node):<EOL><INDENT>edge = self.edges.pop(i)<EOL>return edge<EOL><DEDENT><DEDENT>return None<EOL>

Removes an edge from the graph. Returns the deleted edge or None.


def add_edge(self, tail_node_or_ID, head_node_or_ID, **kwds):

tail_node = self.add_node(tail_node_or_ID)<EOL>head_node = self.add_node(head_node_or_ID)<EOL>if "<STR_LIT>" in self.trait_names():<EOL><INDENT>directed = self.directed<EOL><DEDENT>else:<EOL><INDENT>directed = False<EOL><DEDENT>if self.default_edge is not None:<EOL><INDENT>edge = self.default_edge.clone_traits(copy="<STR_LIT>")<EOL>edge.tail_node = tail_node<EOL>edge.head_node = head_node<EOL>edge.conn = "<STR_LIT>" if directed else "<STR_LIT>"<EOL>edge.set( **kwds )<EOL><DEDENT>else:<EOL><INDENT>edge = Edge(tail_node, head_node, directed, **kwds)<EOL><DEDENT>if "<STR_LIT:strict>" in self.trait_names():<EOL><INDENT>if not self.strict:<EOL><INDENT>self.edges.append(edge)<EOL><DEDENT>else:<EOL><INDENT>self.edges.append(edge)<EOL><INDENT>raise NotImplementedError<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>self.edges.append(edge)<EOL><DEDENT>


if not isinstance(subgraph_or_ID, (godot.subgraph.Subgraph,<EOL>godot.cluster.Cluster)):<EOL><INDENT>subgraphID = str( subgraph_or_ID )<EOL>if subgraph_or_ID.startswith("<STR_LIT>"):<EOL><INDENT>subgraph = godot.cluster.Cluster(ID=subgraphID)<EOL><DEDENT>else:<EOL><INDENT>subgraph = godot.subgraph.Subgraph(ID=subgraphID)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>subgraph = subgraph_or_ID<EOL><DEDENT>subgraph.default_node = self.default_node<EOL>subgraph.default_edge = self.default_edge<EOL><INDENT>subgraph.level = self.level + <NUM_LIT:1><EOL>subgraph.padding += self.padding<EOL><DEDENT>if isinstance(subgraph, godot.subgraph.Subgraph):<EOL><INDENT>self.subgraphs.append(subgraph)<EOL><DEDENT>elif isinstance(subgraph, godot.cluster.Cluster):<EOL><INDENT>self.clusters.append(subgraph)<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT>return subgraph<EOL>


return self.add_subgraph(cluster_or_ID)<EOL>


progs = self.progs<EOL>if prog not in progs:<EOL><INDENT>logger.warning( '<STR_LIT>' % prog )<EOL><DEDENT>if not os.path.exists( progs[prog] ) or notos.path.isfile( progs[prog] ):<EOL><INDENT>logger.warning( "<STR_LIT>"<EOL>"<STR_LIT>" % progs[prog] )<EOL><DEDENT>

Handles the Graphviz layout program selection changing.


self.vp.component = new<EOL>


for edge in self.edges:<EOL><INDENT>edge._nodes = self.nodes<EOL><DEDENT>

Maintains each edge's list of available nodes.


fd = None<EOL>try:<EOL><INDENT>fd = open(self.dot_file.absolute_path, "<STR_LIT:wb>")<EOL>obj.save_dot(fd)<EOL><DEDENT>finally:<EOL><INDENT>if fd is not None:<EOL><INDENT>fd.close()<EOL>


fd = None<EOL>try:<EOL><INDENT>obj = parse_dot_file( self.dot_file.absolute_path )<EOL><DEDENT>finally:<EOL><INDENT>if fd is not None:<EOL><INDENT>fd.close()<EOL><DEDENT><DEDENT>return obj<EOL>


return DotFileIResourceAdapter(file)<EOL>

Returns the new adapted resource. Override in subclasses.


return Graph(name=name)<EOL>

Returns the content for the new resource. Override in subclasses.


<EOL>self.obj.on_trait_change(self.on_path, "<STR_LIT:path>")<EOL>return basename(self.obj.path)<EOL>


self.name = basename(new)<EOL>self.graph = self.editor_input.load()<EOL>


return self.obj<EOL>


self.graph = self.editor_input.load()<EOL>view = View(Item(name="<STR_LIT>", editor=graph_tree_editor,<EOL>show_label=False),<EOL>id="<STR_LIT>", kind="<STR_LIT>", resizable=True)<EOL>ui = self.edit_traits(view=view, parent=parent, kind="<STR_LIT>")<EOL>return ui<EOL>

Creates the toolkit-specific control that represents the
            editor. 'parent' is the toolkit-specific control that is
            the editor's parent.


pass<EOL>

Saves the editor content to a new file name.


from graph_editor import GraphEditorExtension<EOL>from tree_editor import TreeEditorExtension<EOL>return [GraphEditorExtension, TreeEditorExtension]<EOL>


from wizard import NewDotWizardExtension<EOL>return [NewDotWizardExtension]<EOL>


from action import GodotWorkbenchActionSet<EOL>return [GodotWorkbenchActionSet]<EOL>


wizard = NewDotGraphWizard(parent=self.window.control,<EOL>window=self.window, title="<STR_LIT>")<EOL>if wizard.open() == OK:<EOL><INDENT>wizard.finished = True<EOL><DEDENT>


self.graph = self.editor_input.load()<EOL>view = View(Item(name="<STR_LIT>", style="<STR_LIT>", show_label=False),<EOL>id="<STR_LIT>", kind="<STR_LIT>", resizable=True)<EOL>ui = self.edit_traits(view=view, parent=parent, kind="<STR_LIT>")<EOL>return ui<EOL>


pass<EOL>


s = "<STR_LIT>"<EOL>return "<STR_LIT>" % ( s, super(Subgraph, self).__str__() )<EOL>

Returns a string representation of the cluster in dot language.


def _draw_mainlayer(self, gc, view_bounds=None, mode="<STR_LIT:default>"):

gc.save_state()<EOL>try:<EOL><INDENT>self._draw_bounds(gc)<EOL>


point_array = array(((point_x, point_y),))<EOL>vertices = array(self.points)<EOL>winding = self.inside_rule == "<STR_LIT>"<EOL>result = points_in_polygon(point_array, vertices, winding)<EOL>return result[<NUM_LIT:0>]<EOL>

Test if a point is within this polygonal region


dx, dy = self.bounds<EOL>x, y = self.position<EOL>gc.rect(x, y, dx, dy)<EOL>gc.stroke_path()<EOL>

Draws the component bounds for testing purposes


print("<STR_LIT>" % (event.x, event.y))<EOL>

Handles left mouse button clicks in 'normal' mode


x_origin = self.x_origin<EOL>y_origin = self.y_origin<EOL>gc.save_state()<EOL>try:<EOL><INDENT>self._draw_bounds(gc)<EOL>


x = self.x_origin<EOL>y = self.y_origin<EOL>a = self.e_width<EOL>b = self.e_height<EOL>return ((point_x-x)**<NUM_LIT:2>/(a**<NUM_LIT:2>)) + ((point_y-y)**<NUM_LIT:2>/(b**<NUM_LIT:2>)) < <NUM_LIT:1.0><EOL>

Test if the point is within this ellipse


gc.save_state()<EOL>try:<EOL><INDENT>font = str_to_font(str(self.pen.font))<EOL>gc.set_font(font)<EOL>gc.set_fill_color(self.pen.color_)<EOL>x = self.text_x - ( self.text_w / <NUM_LIT:2> )<EOL>y = self.text_y - ( font.size / <NUM_LIT:2> )<EOL>ctm = gc.get_ctm()<EOL>if hasattr(ctm, "<STR_LIT>") and len(ctm) == <NUM_LIT:6>:<EOL><INDENT>scale = sqrt( (ctm[<NUM_LIT:0>] + ctm[<NUM_LIT:1>]) * (ctm[<NUM_LIT:0>] + ctm[<NUM_LIT:1>]) / <NUM_LIT> +(ctm[<NUM_LIT:2>] + ctm[<NUM_LIT:3>]) * (ctm[<NUM_LIT:2>] + ctm[<NUM_LIT:3>]) / <NUM_LIT> )<EOL><DEDENT>elif hasattr(gc, "<STR_LIT>"):<EOL><INDENT>scale = gc.get_ctm_scale()<EOL><DEDENT>else:<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>x *= scale<EOL>y *= scale<EOL>gc.show_text_at_point(self.text, x, y)<EOL><DEDENT>finally:<EOL><INDENT>gc.restore_state()<EOL><DEDENT>


return [xy for xy in zip(*[iter(seq)]*n)]<EOL>

Split a sequence into pieces of length n

    If the length of the sequence isn't a multiple of n, the rest is discarded.
    Note that nsplit will split strings into individual characters.

    Examples:
    >>> nsplit('aabbcc')
    [('a', 'a'), ('b', 'b'), ('c', 'c')]
    >>> nsplit('aabbcc',n=3)
    [('a', 'a', 'b'), ('b', 'c', 'c')]

    # Note that cc is discarded
    >>> nsplit('aabbcc',n=4)
    [('a', 'a', 'b', 'b')]


if not self.points: return<EOL>gc.save_state()<EOL>try:<EOL><INDENT>gc.set_fill_color(self.pen.fill_color_)<EOL>gc.set_line_width(self.pen.line_width)<EOL>gc.set_stroke_color(self.pen.color_)<EOL>gc.begin_path()<EOL>start_x, start_y = self.points[<NUM_LIT:0>]<EOL>gc.move_to(start_x, start_y)<EOL>for triple in nsplit(self.points[<NUM_LIT:1>:], <NUM_LIT:3>):<EOL><INDENT>x1, y1 = triple[<NUM_LIT:0>]<EOL>x2, y2 = triple[<NUM_LIT:1>]<EOL>end_x, end_y = triple[<NUM_LIT:2>]<EOL>gc.curve_to(x1, y1, x2, y2, end_x, end_y)<EOL>gc.move_to(end_x, end_y)<EOL><DEDENT>gc.stroke_path()<EOL><DEDENT>finally:<EOL><INDENT>gc.restore_state()<EOL><DEDENT>


if not self.points:<EOL><INDENT>return<EOL><DEDENT>x_points = [x for x, y in self.points]<EOL>y_points = [y for x, y in self.points]<EOL>x  = min(x_points)<EOL>x2 = max(x_points)<EOL>y  = min(y_points)<EOL>y2 = max(y_points)<EOL>self.position = [x, y]<EOL>self.bounds = [max(x2-x, <NUM_LIT:5>), max(y2-y, <NUM_LIT:5>)]<EOL>self.request_redraw()<EOL>

Updates the position and bounds of the component.


canvas = Canvas(draw_axes=True, bgcolor="<STR_LIT>")<EOL>return canvas<EOL>


viewport = Viewport(component=self.canvas, enable_zoom=True)<EOL>viewport.tools.append(ViewportPanTool(viewport))<EOL>return viewport<EOL>


canvas = self.canvas<EOL>if old is not None:<EOL><INDENT>canvas.remove(old)<EOL><DEDENT>if new is not None:<EOL><INDENT>canvas.add(new)<EOL><DEDENT>


Draws the component bounds for testing purposes.


if x >= <NUM_LIT:0>:<EOL><INDENT>return pow(x, <NUM_LIT:1.0>/<NUM_LIT>)<EOL><DEDENT>else:<EOL><INDENT>return -pow(abs(x), <NUM_LIT:1.0>/<NUM_LIT>)<EOL><DEDENT>


if deg:<EOL><INDENT>return hypot(x, y), <NUM_LIT> * atan2(y, x) / pi<EOL><DEDENT>else:<EOL><INDENT>return hypot(x, y), atan2(y, x)<EOL><DEDENT>

Convert from rectangular (x,y) to polar (r,w)
        r = sqrt(x^2 + y^2)
        w = arctan(y/x) = [-\pi,\pi] = [-180,180]


if c: <EOL><INDENT>a, b = b / float(a), c / float(a)<EOL><DEDENT>t = a / <NUM_LIT><EOL>r = t**<NUM_LIT:2> - b<EOL>if r >= <NUM_LIT:0>: <EOL><INDENT>y1 = sqrt(r)<EOL><DEDENT>else: <EOL><INDENT>y1 = cmath.sqrt(r)<EOL><DEDENT>y2 = -y1<EOL>return y1 - t, y2 - t<EOL>

x^2 + ax + b = 0  (or ax^2 + bx + c = 0)
    By substituting x = y-t and t = a/2, the equation reduces to
        y^2 + (b-t^2) = 0
    which has easy solution
        y = +/- sqrt(t^2-b)


if d: <EOL><INDENT>a, b, c = b / float(a), c / float(a), d / float(a)<EOL><DEDENT>t = a / <NUM_LIT><EOL>p, q = b - <NUM_LIT:3> * t**<NUM_LIT:2>, c - b * t + <NUM_LIT:2> * t**<NUM_LIT:3><EOL>u, v = quadratic(q, -(p/<NUM_LIT>)**<NUM_LIT:3>)<EOL>if type(u) == type(<NUM_LIT>): <EOL><INDENT>r, w = polar(u.real, u.imag)<EOL>y1 = <NUM_LIT:2> * cbrt(r) * cos(w / <NUM_LIT>)<EOL><DEDENT>else: <EOL><INDENT>y1 = cbrt(u) + cbrt(v)<EOL><DEDENT>y2, y3 = quadratic(y1, p + y1**<NUM_LIT:2>)<EOL>return y1 - t, y2 - t, y3 - t<EOL>

x^3 + ax^2 + bx + c = 0  (or ax^3 + bx^2 + cx + d = 0)
    With substitution x = y-t and t = a/3, the cubic equation reduces to
        y^3 + py + q = 0,
    where p = b-3t^2 and q = c-bt+2t^3.  Then, one real root y1 = u+v can
    be determined by solving
        w^2 + qw - (p/3)^3 = 0
    where w = u^3, v^3.  From Vieta's theorem,
        y1 + y2 + y3 = 0
        y1 y2 + y1 y3 + y2 y3 = p
        y1 y2 y3 = -q,
    the other two (real or complex) roots can be obtained by solving
        y^2 + (y1)y + (p+y1^2) = 0


def __init__(self, tailnode_or_ID, headnode_or_ID, directed=False,<EOL>**traits):

if not isinstance(tailnode_or_ID, Node):<EOL><INDENT>tailnodeID = str( tailnode_or_ID )<EOL>tail_node = Node(tailnodeID)<EOL><DEDENT>else:<EOL><INDENT>tail_node = tailnode_or_ID<EOL><DEDENT>if not isinstance(headnode_or_ID, Node):<EOL><INDENT>headnodeID = str( headnode_or_ID )<EOL>head_node = Node(headnodeID)<EOL><DEDENT>else:<EOL><INDENT>head_node = headnode_or_ID<EOL><DEDENT>self.tail_node = tail_node<EOL>self.head_node = head_node<EOL>if directed:<EOL><INDENT>self.conn = "<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>self.conn = "<STR_LIT>"<EOL><DEDENT>super(Edge, self).__init__(**traits)<EOL>


attrs = []<EOL>for trait_name, trait in self.traits(graphviz=True).items():<EOL><INDENT>value = getattr(self, trait_name)<EOL>if (value != trait.default) and (trait.default is not None):<EOL><INDENT>if isinstance( value, str ):<EOL><INDENT>valstr = '<STR_LIT>' % value<EOL><DEDENT>else:<EOL><INDENT>valstr = str( value )<EOL><DEDENT>attrs.append('<STR_LIT>' % (trait_name, valstr))<EOL><DEDENT><DEDENT>if attrs:<EOL><INDENT>attrstr = "<STR_LIT>" % "<STR_LIT:U+002CU+0020>".join(attrs)<EOL><DEDENT>else:<EOL><INDENT>attrstr = "<STR_LIT>"<EOL><DEDENT>edge_str = "<STR_LIT>" % ( self.tail_node.ID, self.tailport,<EOL>self.conn,<EOL>self.head_node.ID, self.headport,<EOL>attrstr )<EOL>return edge_str<EOL>

Returns a string representation of the edge.


component = Container(auto_size=True, bgcolor="<STR_LIT>")<EOL><INDENT>component.tools.append( MoveTool(component) )<EOL>component.tools.append( TraitsTool(component) )<EOL><DEDENT>return component<EOL>


vp = Viewport( component=self.component )<EOL>vp.enable_zoom=True<EOL>vp.tools.append( ViewportPanTool(vp) )<EOL>return vp<EOL>


if (self.tail_node is not None) and (self.head_node is not None):<EOL><INDENT>return "<STR_LIT>" % (self.tail_node.ID, self.conn,<EOL>self.head_node.ID)<EOL><DEDENT>else:<EOL><INDENT>return "<STR_LIT>"<EOL><DEDENT>


<EOL>import godot.dot_data_parser<EOL>import godot.graph<EOL>graph = godot.graph.Graph( ID="<STR_LIT:g>", directed=True )<EOL>self.conn = "<STR_LIT>"<EOL>graph.edges.append( self )<EOL>xdot_data = graph.create( format="<STR_LIT>" )<EOL><INDENT>print "<STR_LIT>", xdot_data<EOL><DEDENT>parser = godot.dot_data_parser.GodotDataParser()<EOL>ndata = xdot_data.replace('<STR_LIT>','<STR_LIT>')<EOL>tokens = parser.dotparser.parseString(ndata)[<NUM_LIT:0>]<EOL>for element in tokens[<NUM_LIT:3>]:<EOL><INDENT>cmd = element[<NUM_LIT:0>]<EOL>if cmd == "<STR_LIT>":<EOL><INDENT>cmd, src, dest, opts = element<EOL>self.set( **opts )<EOL><DEDENT><DEDENT>

Arrange the components of the node using Graphviz.


def _parse_xdot_directive(self, name, new):

parser = XdotAttrParser()<EOL>components = parser.parse_xdot_data(new)<EOL>x1 = min( [c.x for c in components] )<EOL>y1 = min( [c.y for c in components] )<EOL>print("<STR_LIT>", name, x1, y1)<EOL><INDENT>move_to_origin( components )<EOL><DEDENT>for c in components:<EOL><INDENT>if isinstance(c, Ellipse):<EOL><INDENT>component.x_origin -= x1<EOL>component.y_origin -= y1<EOL><INDENT>c.position = [ c.x - x1, c.y - y1 ]<EOL><DEDENT><DEDENT>elif isinstance(c, (Polygon, BSpline)):<EOL><INDENT>print("<STR_LIT>", c.points)<EOL>c.points = [ (t[<NUM_LIT:0>] - x1, t[<NUM_LIT:1>] - y1) for t in c.points ]<EOL>print("<STR_LIT>", c.points)<EOL><DEDENT>elif isinstance(c, Text):<EOL><INDENT>font = str_to_font( str(c.pen.font) )<EOL>

Handles parsing Xdot drawing directives.


@on_trait_change("<STR_LIT>")<EOL><INDENT>def _on_drawing(self, object, name, old, new):<DEDENT>

attrs = [ "<STR_LIT>", "<STR_LIT>" ]<EOL>others = [getattr(self, a) for a in attrsif (a != name) and (getattr(self, a) is not None)]<EOL>x, y = self.component.position<EOL>print("<STR_LIT>", x, y, self.component.position)<EOL>abs_x = [d.x + x for d in others]<EOL>abs_y = [d.y + y for d in others]<EOL>print("<STR_LIT>", abs_x, abs_y)<EOL>x1 = min( abs_x + [new.x] )<EOL>y1 = min( abs_y + [new.y] )<EOL>print("<STR_LIT>", new.position)<EOL>new.position = [ new.x - x1, new.y - y1 ]<EOL>print("<STR_LIT>", new.position)<EOL><INDENT>for i, b in enumerate( others ):<EOL><INDENT>self.drawing.position = [<NUM_LIT:100>, <NUM_LIT:100>]<EOL>self.drawing.request_redraw()<EOL>print "<STR_LIT>", b.position, abs_x[i] - x1<EOL>b.position = [ abs_x[i] - x1, abs_y[i] - y1 ]<EOL>b.x = <NUM_LIT:50><EOL>b.y = <NUM_LIT:50><EOL>print "<STR_LIT>", b.position, abs_x[i], x1<EOL><DEDENT>for attr in attrs:<EOL><INDENT>if attr != name:<EOL><INDENT>if getattr(self, attr) is not None:<EOL><INDENT>drawing = getattr(self, attr)<EOL>drawing.position = [<NUM_LIT:50>, <NUM_LIT:50>]<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if old is not None:<EOL><INDENT>self.component.remove( old )<EOL><DEDENT>if new is not None:<EOL><INDENT>self.component.add( new )<EOL><DEDENT>print("<STR_LIT>", self.component.position)<EOL>self.component.position = [ x1, y1 ]<EOL>print("<STR_LIT>", self.component.position)<EOL>self.component.request_redraw()<EOL>print("<STR_LIT>", self.component.position)<EOL>

Handles the containers of drawing components being set.


node1 = DomainNode(name="<STR_LIT>")<EOL>node2 = DomainNode(name="<STR_LIT>")<EOL>edge1 = DomainEdge(source=node1, target=node2)<EOL>model = DomainModel(nodes=[node1, node2], edges=[edge1])<EOL>self.view_model = DomainViewModel(model=model)<EOL>

Prepares the test fixture before each test method is called.


self.parser = XdotAttrParser()<EOL>


self.mapping = Mapping(<EOL>nodes=[<EOL>NodeMapping(<EOL>containment_trait="<STR_LIT>", element=DomainNode,<EOL>dot_node=DotGraphNode(shape=NODE_SHAPE),<EOL>tools=[MoveTool, ElementTool]<EOL>),<EOL>NodeMapping(<EOL>containment_trait="<STR_LIT>", element=OtherNode,<EOL>dot_node=DotGraphNode(shape=OTHER_NODE_SHAPE),<EOL>tools=[MoveTool, ElementTool]<EOL>)<EOL>]<EOL>)<EOL>node1 = DomainNode(name="<STR_LIT>")<EOL>node2 = DomainNode(name="<STR_LIT>")<EOL>self.model = DomainModel(<EOL>nodes=[node1, node2],<EOL>edges=[DomainEdge(source=node1, target=node2)]<EOL>)<EOL>return<EOL>


return<EOL>

Called immediately after each test method has been called.


parser = GodotDataParser()<EOL>graph  = parser.parse_dot_file(filename)<EOL>del parser<EOL>return graph<EOL>

Parses a DOT file and returns a Godot graph.


opts = toks[<NUM_LIT:1>]<EOL>dummy_node = Node("<STR_LIT>")<EOL>for key, value in opts.items():<EOL><INDENT>trait = dummy_node.trait(key)<EOL>if trait is not None:<EOL><INDENT>if trait.is_trait_type( Float ):<EOL><INDENT>opts[key] = float( value )<EOL><DEDENT>elif trait.is_trait_type( Tuple ):<EOL><INDENT>opts[key] = tuple( [float(c) for c in value.split("<STR_LIT:U+002C>")] )<EOL><DEDENT><DEDENT><DEDENT>return super(GodotDataParser, self)._proc_node_stmt(toks)<EOL>


opts = toks[<NUM_LIT:3>]<EOL>dummy_edge = Edge("<STR_LIT>", "<STR_LIT>")<EOL>for key, value in opts.items():<EOL><INDENT>trait = dummy_edge.trait(key)<EOL>if trait is not None:<EOL><INDENT>if trait.is_trait_type( List ):<EOL><INDENT>p = [] <EOL>for t in value.split( "<STR_LIT:U+0020>" ):<EOL><INDENT>l = t.split( "<STR_LIT:U+002C>" )<EOL>if len(l) == <NUM_LIT:3>: <EOL><INDENT>l.pop(<NUM_LIT:0>)<EOL><DEDENT>f = [ float(a) for a in l ]<EOL>p.append( tuple(f) )<EOL><DEDENT>opts[key] = p<EOL><DEDENT>elif trait.is_trait_type( Float ):<EOL><INDENT>opts[key] = float( value )<EOL><DEDENT>elif trait.is_trait_type( Tuple ):<EOL><INDENT>opts[key] = tuple( [float(c) for c in value.split("<STR_LIT:U+002C>")] )<EOL><DEDENT><DEDENT><DEDENT>return super(GodotDataParser, self)._proc_edge_stmt(toks)<EOL>

Returns a tuple of the form (ADD_EDGE, src, dest, options).


if isinstance(file_or_filename, str):<EOL><INDENT>file = None<EOL>try:<EOL><INDENT>file = open(file_or_filename, "<STR_LIT:rb>")<EOL>data = file.read()<EOL><DEDENT>except:<EOL><INDENT>print("<STR_LIT>" % file_or_filename)<EOL>return None<EOL><DEDENT>finally:<EOL><INDENT>if file is not None:<EOL><INDENT>file.close()<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>file = file_or_filename<EOL>data = file.read()<EOL><DEDENT>return self.parse_dot_data(data)<EOL>

Returns a graph given a file or a filename.


<EOL>strict = tokens[<NUM_LIT:0>] == '<STR_LIT:strict>'<EOL>graphtype = tokens[<NUM_LIT:1>]<EOL>directed = graphtype == '<STR_LIT>'<EOL>graphname = tokens[<NUM_LIT:2>]<EOL>graph = Graph(ID=graphname, strict=strict, directed=directed)<EOL>self.graph = self.build_graph(graph, tokens[<NUM_LIT:3>])<EOL>

Build a Godot graph instance from parsed data.


subgraph = None<EOL>for element in tokens:<EOL><INDENT>cmd = element[<NUM_LIT:0>]<EOL>if cmd == ADD_NODE:<EOL><INDENT>cmd, nodename, opts = element<EOL>graph.add_node(nodename, **opts)<EOL><DEDENT>elif cmd == ADD_EDGE:<EOL><INDENT>cmd, src, dest, opts = element<EOL>srcport = destport = "<STR_LIT>"<EOL>if isinstance(src,tuple):<EOL><INDENT>srcport = src[<NUM_LIT:1>]<EOL>src = src[<NUM_LIT:0>]<EOL><DEDENT>if isinstance(dest,tuple):<EOL><INDENT>destport = dest[<NUM_LIT:1>]<EOL>dest = dest[<NUM_LIT:0>]<EOL><DEDENT>graph.add_edge(src, dest, tailport=srcport, headport=destport,<EOL>**opts)<EOL><DEDENT>elif cmd in [ADD_GRAPH_TO_NODE_EDGE,<EOL>ADD_GRAPH_TO_GRAPH_EDGE,<EOL>ADD_NODE_TO_GRAPH_EDGE]:<EOL><INDENT>cmd, src, dest, opts = element<EOL>srcport = destport = "<STR_LIT>"<EOL>if isinstance(src,tuple):<EOL><INDENT>srcport = src[<NUM_LIT:1>]<EOL><DEDENT>if isinstance(dest,tuple):<EOL><INDENT>destport = dest[<NUM_LIT:1>]<EOL><DEDENT>if not (cmd == ADD_NODE_TO_GRAPH_EDGE):<EOL><INDENT>if cmd == ADD_GRAPH_TO_NODE_EDGE:<EOL><INDENT>src = subgraph<EOL><DEDENT>else:<EOL><INDENT>src = prev_subgraph<EOL>dest = subgraph<EOL><DEDENT><DEDENT>else:<EOL><INDENT>dest = subgraph<EOL><DEDENT>src_is_graph = isinstance(src, (Subgraph, Cluster))<EOL>dst_is_graph = isinstance(dst, (Subgraph, Cluster))<EOL>if src_is_graph:<EOL><INDENT>src_nodes = src.nodes<EOL><DEDENT>else:<EOL><INDENT>src_nodes = [src]<EOL><DEDENT>if dst_is_graph:<EOL><INDENT>dst_nodes = dst.nodes<EOL><DEDENT>else:<EOL><INDENT>dst_nodes = [dst]<EOL><DEDENT>for src_node in src_nodes:<EOL><INDENT>for dst_node in dst_nodes:<EOL><INDENT>graph.add_edge(from_node=src_node, to_node=dst_node,<EOL>tailport=srcport, headport=destport,<EOL>**kwds)<EOL><DEDENT><DEDENT><DEDENT>elif cmd == SET_GRAPH_ATTR:<EOL><INDENT>graph.set( **element[<NUM_LIT:1>] )<EOL><DEDENT>elif cmd == SET_DEF_NODE_ATTR:<EOL><INDENT>graph.default_node.set( **element[<NUM_LIT:1>] )<EOL><DEDENT>elif cmd == SET_DEF_EDGE_ATTR:<EOL><INDENT>graph.default_edge.set( **element[<NUM_LIT:1>] )<EOL><DEDENT>elif cmd == SET_DEF_GRAPH_ATTR:<EOL><INDENT>graph.default_graph.set( **element[<NUM_LIT:1>] )<EOL><DEDENT>elif cmd == ADD_SUBGRAPH:<EOL><INDENT>cmd, name, elements = element<EOL>if subgraph:<EOL><INDENT>prev_subgraph = subgraph<EOL><DEDENT>if name.startswith("<STR_LIT>"):<EOL><INDENT>cluster = Cluster(ID=name)<EOL>cluster = self.build_graph(cluster, elements)<EOL>graph.add_cluster(cluster)<EOL><DEDENT>else:<EOL><INDENT>subgraph = Subgraph(ID=name)<EOL>subgraph = self.build_graph(subgraph, elements)<EOL>graph.add_subgraph(subgraph)<EOL><DEDENT><DEDENT><DEDENT>return graph<EOL>


return Property(lambda obj: getattr(obj, name),<EOL>lambda obj, val: setattr(obj, name, val),<EOL>**metadata)<EOL>

Syntactically concise alias trait but creates a pair of lambda
    functions for every alias you declare.

    class MyClass(HasTraits):
        line_width = Float(3.0)
        thickness = Alias("line_width")


application = GodotApplication( id="<STR_LIT>",<EOL>plugins=[CorePlugin(),<EOL>PuddlePlugin(),<EOL>WorkbenchPlugin(),<EOL>ResourcePlugin(),<EOL>GodotPlugin()] )<EOL>application.run()<EOL>


if "<STR_LIT>" in row_factory_kw:<EOL><INDENT>graph = row_factory_kw["<STR_LIT>"].object<EOL>ID = make_unique_name("<STR_LIT:n>", [node.ID for node in graph.nodes])<EOL>del row_factory_kw["<STR_LIT>"]<EOL>return godot.node.Node(ID)<EOL><DEDENT>else:<EOL><INDENT>return godot.node.Node(uuid.uuid4().hex[:<NUM_LIT:6>])<EOL><DEDENT>


if "<STR_LIT>" in row_factory_kw:<EOL><INDENT>table_editor = row_factory_kw["<STR_LIT>"]<EOL>graph = table_editor.object<EOL>ID = make_unique_name("<STR_LIT>", [node.ID for node in graph.nodes])<EOL>n_nodes = len(graph.nodes)<EOL>IDs = [v.ID for v in graph.nodes]<EOL>if n_nodes == <NUM_LIT:0>:<EOL><INDENT>tail_node = godot.Node(ID=make_unique_name("<STR_LIT:n>", IDs))<EOL>head_node = godot.Node(ID=make_unique_name("<STR_LIT:n>", IDs))<EOL><DEDENT>elif n_nodes == <NUM_LIT:1>:<EOL><INDENT>tail_node = graph.nodes[<NUM_LIT:0>]<EOL>head_node = godot.Node(ID=make_unique_name("<STR_LIT:n>", IDs))<EOL><DEDENT>else:<EOL><INDENT>tail_node = graph.nodes[<NUM_LIT:0>]<EOL>head_node = graph.nodes[<NUM_LIT:1>]<EOL><DEDENT>return godot.edge.Edge(tail_node, head_node, _nodes=graph.nodes)<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>


return self.model<EOL>


parser = GodotDataParser()<EOL>graph  = parser.parse_dot_data(self.dot_code)<EOL>if graph is not None:<EOL><INDENT>self.model = graph<EOL><DEDENT>

Parses the dot_code string and replaces the existing model.


self.selected_graph = new<EOL>


if info.initialized:<EOL><INDENT>retval = confirm(parent  = info.ui.control,<EOL>message = "<STR_LIT>",<EOL>title   = "<STR_LIT>",<EOL>default = YES)<EOL>if retval == YES:<EOL><INDENT>self.model = Graph()<EOL><DEDENT><DEDENT>


if not info.initialized: return <EOL><INDENT>retval = self.edit_traits(parent=info.ui.control, view="<STR_LIT>")<EOL><DEDENT>dlg = FileDialog( action = "<STR_LIT>",<EOL>wildcard = "<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL>if dlg.open() == OK:<EOL><INDENT>parser = GodotDataParser()<EOL>model = parser.parse_dot_file(dlg.path)<EOL>if model is not None:<EOL><INDENT>self.model = model<EOL><DEDENT>else:<EOL><INDENT>print("<STR_LIT>" % dlg.path)<EOL><DEDENT>self.save_file = dlg.path<EOL><DEDENT>del dlg<EOL>


save_file = self.save_file<EOL>if not isfile(save_file):<EOL><INDENT>self.save_as(info)<EOL><DEDENT>else:<EOL><INDENT>fd = None<EOL>try:<EOL><INDENT>fd = open(save_file, "<STR_LIT:wb>")<EOL>dot_code = str(self.model)<EOL>fd.write(dot_code)<EOL><DEDENT>finally:<EOL><INDENT>if fd is not None:<EOL><INDENT>fd.close()<EOL><DEDENT><DEDENT><DEDENT>

Handles saving the current model to the last file.


if not info.initialized:<EOL><INDENT>return<EOL>

Handles saving the current model to file.


if info.initialized:<EOL><INDENT>self.model.edit_traits(parent=info.ui.control,<EOL>kind="<STR_LIT>", view=attr_view)<EOL><DEDENT>

Handles display of the graph dot traits.


if info.initialized:<EOL><INDENT>self.model.edit_traits(parent=info.ui.control,<EOL>kind="<STR_LIT>", view=nodes_view)<EOL><DEDENT>


if info.initialized:<EOL><INDENT>self.model.edit_traits(parent=info.ui.control,<EOL>kind="<STR_LIT>", view=edges_view)<EOL><DEDENT>


if info.initialized:<EOL><INDENT>self.edit_traits(parent=info.ui.control,<EOL>kind="<STR_LIT>", view=about_view)<EOL><DEDENT>


if not info.initialized:<EOL><INDENT>return<EOL><DEDENT>graph = self._request_graph(info.ui.control)<EOL>if graph is None:<EOL><INDENT>return<EOL><DEDENT>IDs = [v.ID for v in graph.nodes]<EOL>node = Node(ID=make_unique_name("<STR_LIT>", IDs))<EOL>graph.nodes.append(node)<EOL>retval = node.edit_traits(parent=info.ui.control, kind="<STR_LIT>")<EOL>if not retval.result:<EOL><INDENT>graph.nodes.remove(node)<EOL><DEDENT>


if not info.initialized:<EOL><INDENT>return<EOL><DEDENT>graph = self._request_graph(info.ui.control)<EOL>if graph is None:<EOL><INDENT>return<EOL><DEDENT>n_nodes = len(graph.nodes)<EOL>IDs = [v.ID for v in graph.nodes]<EOL>if n_nodes == <NUM_LIT:0>:<EOL><INDENT>tail_node = Node(ID=make_unique_name("<STR_LIT>", IDs))<EOL>head_name = make_unique_name("<STR_LIT>", IDs + [tail_node.ID])<EOL>head_node = Node(ID=head_name)<EOL><DEDENT>elif n_nodes == <NUM_LIT:1>:<EOL><INDENT>tail_node = graph.nodes[<NUM_LIT:0>]<EOL>head_node = Node(ID=make_unique_name("<STR_LIT>", IDs))<EOL><DEDENT>else:<EOL><INDENT>tail_node = graph.nodes[<NUM_LIT:0>]<EOL>head_node = graph.nodes[<NUM_LIT:1>]<EOL><DEDENT>edge = Edge(tail_node, head_node, _nodes=graph.nodes)<EOL>retval = edge.edit_traits(parent=info.ui.control, kind="<STR_LIT>")<EOL>if retval.result:<EOL><INDENT>graph.edges.append(edge)<EOL><DEDENT>


if not info.initialized:<EOL><INDENT>return<EOL><DEDENT>graph = self._request_graph(info.ui.control)<EOL>if graph is not None:<EOL><INDENT>subgraph = Subgraph()<EOL>retval = subgraph.edit_traits(parent = info.ui.control,<EOL>kind   = "<STR_LIT>")<EOL>if retval.result:<EOL><INDENT>graph.subgraphs.append(subgraph)<EOL><DEDENT><DEDENT>

Handles adding a Subgraph to the main graph.


if not info.initialized:<EOL><INDENT>return<EOL><DEDENT>graph = self._request_graph(info.ui.control)<EOL>if graph is not None:<EOL><INDENT>cluster = Cluster()<EOL>retval = cluster.edit_traits(parent = info.ui.control,<EOL>kind   = "<STR_LIT>")<EOL>if retval.result:<EOL><INDENT>graph.clusters.append(cluster)<EOL><DEDENT><DEDENT>

Handles adding a Cluster to the main graph.


if (len(self.all_graphs) > <NUM_LIT:1>) and (self.select_graph):<EOL><INDENT>retval = self.edit_traits(parent = parent,<EOL>view   = "<STR_LIT>")<EOL>if not retval.result:<EOL><INDENT>return None<EOL><DEDENT><DEDENT>if self.selected_graph is not None:<EOL><INDENT>return self.selected_graph<EOL><DEDENT>else:<EOL><INDENT>return self.model<EOL><DEDENT>

Displays a dialog for graph selection if more than one exists.
            Returns None if the dialog is canceled.


if info.initialized:<EOL><INDENT>self.show_tree = not self.show_tree<EOL><DEDENT>


if info.initialized:<EOL><INDENT>self.edit_traits( parent = info.ui.control,<EOL>kind   = "<STR_LIT>",<EOL>view   = "<STR_LIT>" )<EOL><DEDENT>


if not info.initialized:<EOL><INDENT>return<EOL><DEDENT>self.dot_code = str(self.model)<EOL>retval = self.edit_traits( parent = info.ui.control,<EOL>kind   = "<STR_LIT>",<EOL>view   = "<STR_LIT>" )<EOL>

Handles display of the dot code in a text editor.