Instruction:
Can you implement a function in Python 3 that
stores the data in the native memory.

Response:
def _store_in_native_memory(self, data, data_type, addr=None):
        """
        Store in native memory.

        :param data:      Either a single value or a list.
                          Lists get interpreted as an array.
        :param data_type: Java type of the element(s).
        :param addr:      Native store address.
                          If not set, native memory is allocated.
        :return:          Native addr of the stored data.
        """
        # check if addr is symbolic
        if addr is not None and self.state.solver.symbolic(addr):
            raise NotImplementedError('Symbolic addresses are not supported.')
        # lookup native size of the type
        type_size = ArchSoot.sizeof[data_type]
        native_memory_endness = self.state.arch.memory_endness
        # store single value
        if isinstance(data, int):
            if addr is None:
                addr = self._allocate_native_memory(size=type_size//8)
            value = self.state.solver.BVV(data, type_size)
            self.state.memory.store(addr, value, endness=native_memory_endness)
        # store array
        elif isinstance(data, list):
            if addr is None:
                addr = self._allocate_native_memory(size=type_size*len(data)//8)
            for idx, value in enumerate(data):
                memory_addr = addr+idx*type_size//8
                self.state.memory.store(memory_addr, value, endness=native_memory_endness)
        # return native addr
        return addr


Instruction:
Write a Python 3 script for
loading the elements from native memory.

Response:
def _load_from_native_memory(self, addr, data_type=None, data_size=None,
                                no_of_elements=1, return_as_list=False):
        """
        Load from native memory.

        :param addr:            Native load address.
        :param data_type:       Java type of elements.
                                If set, all loaded elements are casted to this type.
        :param data_size:       Size of each element.
                                If not set, size is determined based on the given type.
        :param no_of_elements:  Number of elements to load.
        :param return_as_list:  Whether to wrap a single element in a list.
        :return:                The value or a list of loaded element(s).
        """
        # check if addr is symbolic
        if addr is not None and self.state.solver.symbolic(addr):
            raise NotImplementedError('Symbolic addresses are not supported.')
        # if data size is not set, derive it from the type
        if not data_size:
            if data_type:
                data_size = ArchSoot.sizeof[data_type]//8
            else:
                raise ValueError("Cannot determine the data size w/o a type.")
        native_memory_endness = self.state.arch.memory_endness
        # load elements
        values = []
        for i in range(no_of_elements):
            value = self.state.memory.load(addr + i*data_size,
                                          size=data_size,
                                          endness=native_memory_endness)
            if data_type:
                value = self.state.project.simos.cast_primitive(self.state, value=value, to_type=data_type)
            values.append(value)
        # return element(s)
        if no_of_elements == 1 and not return_as_list:
            return values[0]
        else:
            return values


Instruction:
How would you implement a function in Python 3 that
loads a string from native memory.

Response:
def _load_string_from_native_memory(self, addr_):
        """
        Load zero terminated UTF-8 string from native memory.

        :param addr_: Native load address.
        :return:      Loaded string.
        """
        # check if addr is symbolic
        if self.state.solver.symbolic(addr_):
            l.error("Loading strings from symbolic addresses is not implemented. "
                    "Continue execution with an empty string.")
            return ""
        addr = self.state.solver.eval(addr_)

        # load chars one by one
        chars = []
        for i in itertools.count():
            str_byte = self.state.memory.load(addr+i, size=1)
            if self.state.solver.symbolic(str_byte):
                l.error("Loading of strings with symbolic chars is not supported. "
                        "Character %d is concretized.", i)
            str_byte = self.state.solver.eval(str_byte)
            if str_byte == 0:
                break
            chars.append(chr(str_byte))

        return "".join(chars)


Instruction:
How would you code a function in Python 3 to
store given string in native memory.

Response:
def _store_string_in_native_memory(self, string, addr=None):
        """
        Store given string UTF-8 encoded and zero terminated in native memory.

        :param str string:  String
        :param addr:        Native store address.
                            If not set, native memory is allocated.
        :return:            Native address of the string.
        """
        if addr is None:
            addr = self._allocate_native_memory(size=len(string)+1)
        else:
            # check if addr is symbolic
            if self.state.solver.symbolic(addr):
                l.error("Storing strings at symbolic addresses is not implemented. "
                        "Continue execution with concretized address.")
            addr = self.state.solver.eval(addr)

        # warn if string is symbolic
        if self.state.solver.symbolic(string):
            l.warning('Support for symbolic strings, passed to native code, is limited. '
                      'String will get concretized after `ReleaseStringUTFChars` is called.')

        # store chars one by one
        str_len = len(string) // 8
        for idx in range(str_len):
            str_byte = StrSubstr(idx, 1, string)
            self.state.memory.store(addr+idx, str_byte)

        # store terminating zero
        self.state.memory.store(len(string), BVV(0, 8))

        return addr


Instruction:
Write a Python 3 script for
giving the target object and a set of hooks apply them to the target object.

Response:
def install_hooks(target, **hooks):
        """
        Given the target `target`, apply the hooks given as keyword arguments to it.
        If any targeted method has already been hooked, the hooks will not be overridden but will instead be pushed
        into a list of pending hooks. The final behavior should be that all hooks call each other in a nested stack.

        :param target:  Any object. Its methods named as keys in `hooks` will be replaced by `HookedMethod` objects.
        :param hooks:   Any keywords will be interpreted as hooks to apply. Each method named will hooked with the
                        coresponding function value.
        """
        for name, hook in hooks.items():
            func = getattr(target, name)
            if not isinstance(func, HookedMethod):
                func = HookedMethod(func)
                setattr(target, name, func)
            func.pending.append(hook)


Instruction:
Can you tell what is the following Python 3 function doing
def remove_hooks(target, **hooks):
        for name, hook in hooks.items():
            hooked = getattr(target, name)
            if hook in hooked.pending:
                try:
                    hooked.pending.remove(hook)
                except ValueError as e:
                    raise ValueError("%s is not hooked by %s" % (target, hook)) from e
            if not hooked.pending:
                setattr(target, name, hooked.func)

Response: Removes the given hooks from the given target object.


Instruction:
Can you tell what is the following Python 3 function doing
def reset(self):

        self._sorted_nodes.clear()
        self._node_to_index.clear()
        self._reached_fixedpoint.clear()

        for i, n in enumerate(self.sort_nodes()):
            self._node_to_index[n] = i
            self._sorted_nodes.add(n)

Response: Reset the internal node traversal state.


Instruction:
Create a Python 3 function for
returning all successors to the given node.

Response:
def all_successors(self, node, skip_reached_fixedpoint=False):
        """
        Returns all successors to the specific node.

        :param node: A node in the graph.
        :return:     A set of nodes that are all successors to the given node.
        :rtype:      set
        """

        successors = set()

        stack = [ node ]
        while stack:
            n = stack.pop()
            successors.add(n)
            stack.extend(succ for succ in self.successors(n) if
                         succ not in successors and
                            (not skip_reached_fixedpoint or succ not in self._reached_fixedpoint)
                         )

        return successors


Instruction:
Implement a Python 3 function for
revisiting a node in the future.

Response:
def revisit(self, node, include_self=True):
        """
        Revisit a node in the future. As a result, the successors to this node will be revisited as well.

        :param node: The node to revisit in the future.
        :return:     None
        """

        successors = self.successors(node) #, skip_reached_fixedpoint=True)

        if include_self:
            self._sorted_nodes.add(node)

        for succ in successors:
            self._sorted_nodes.add(succ)

        # reorder it
        self._sorted_nodes = OrderedSet(sorted(self._sorted_nodes, key=lambda n: self._node_to_index[n]))


Instruction:
Create a Python 3 function for
adding a new job to the job list.

Response:
def add_job(self, job, merged=False, widened=False):
        """
        Appended a new job to this JobInfo node.
        :param job: The new job to append.
        :param bool merged: Whether it is a merged job or not.
        :param bool widened: Whether it is a widened job or not.
        """

        job_type = ''
        if merged:
            job_type = 'merged'
        elif widened:
            job_type = 'widened'
        self.jobs.append((job, job_type))


Instruction:
How would you implement a function in Python 3 that
checks whether there exists another job with the same key.

Response:
def has_job(self, job):
        """
        Checks whether there exists another job which has the same job key.
        :param job: The job to check.

        :return:    True if there exists another job with the same key, False otherwise.
        """
        job_key = self._job_key(job)
        return job_key in self._job_map


Instruction:
Can you create a Python 3 function that
analyzes the current base graph and returns None.

Response:
def _analyze(self):
        """
        The main analysis routine.

        :return: None
        """

        self._pre_analysis()

        if self._graph_visitor is None:
            # There is no base graph that we can rely on. The analysis itself should generate successors for the
            # current job.
            # An example is the CFG recovery.

            self._analysis_core_baremetal()

        else:
            # We have a base graph to follow. Just handle the current job.

            self._analysis_core_graph()

        self._post_analysis()


Instruction:
How would you explain what the following Python 3 function does
def _add_input_state(self, node, input_state):

        successors = self._graph_visitor.successors(node)

        for succ in successors:
            if succ in self._state_map:
                self._state_map[succ] = self._merge_states(succ, *([ self._state_map[succ], input_state ]))
            else:
                self._state_map[succ] = input_state

Response: Adds the input state to all successors of the given node.


Instruction:
How would you code a function in Python 3 to
get the input abstract state for this node and remove it from the state map.

Response:
def _pop_input_state(self, node):
        """
        Get the input abstract state for this node, and remove it from the state map.

        :param node: The node in graph.
        :return:     A merged state, or None if there is no input state for this node available.
        """

        if node in self._state_map:
            return self._state_map.pop(node)
        return None


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _merge_state_from_predecessors(self, node):

        preds = self._graph_visitor.predecessors(node)

        states = [ self._state_map[n] for n in preds if n in self._state_map ]

        if not states:
            return None

        return reduce(lambda s0, s1: self._merge_states(node, s0, s1), states[1:], states[0])

Response: Get abstract states for all predecessors of the node and merge them and return the merged state.


Instruction:
Explain what the following Python 3 code does
def _process_job_and_get_successors(self, job_info):

        job = job_info.job

        successors = self._get_successors(job)

        all_new_jobs = [ ]

        for successor in successors:
            new_jobs = self._handle_successor(job, successor, successors)

            if new_jobs:
                all_new_jobs.extend(new_jobs)

                for new_job in new_jobs:
                    self._insert_job(new_job)

        self._post_job_handling(job, all_new_jobs, successors)

Response: Process a job and get all successors of this job and call _handle_successor on each successor.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _insert_job(self, job):

        key = self._job_key(job)

        if self._allow_merging:
            if key in self._job_map:
                job_info = self._job_map[key]

                # decide if we want to trigger a widening
                # if not, we'll simply do the merge
                # TODO: save all previous jobs for the sake of widening
                job_added = False
                if self._allow_widening and self._should_widen_jobs(job_info.job, job):
                    try:
                        widened_job = self._widen_jobs(job_info.job, job)
                        # remove the old job since now we have a widened one
                        if job_info in self._job_info_queue:
                            self._job_info_queue.remove(job_info)
                        job_info.add_job(widened_job, widened=True)
                        job_added = True
                    except AngrJobWideningFailureNotice:
                        # widening failed
                        # fall back to merging...
                        pass

                if not job_added:
                    try:
                        merged_job = self._merge_jobs(job_info.job, job)
                        # remove the old job since now we have a merged one
                        if job_info in self._job_info_queue:
                            self._job_info_queue.remove(job_info)
                        job_info.add_job(merged_job, merged=True)
                    except AngrJobMergingFailureNotice:
                        # merging failed
                        job_info = JobInfo(key, job)
                        # update the job map
                        self._job_map[key] = job_info

            else:
                job_info = JobInfo(key, job)
                self._job_map[key] = job_info

        else:
            job_info = JobInfo(key, job)
            self._job_map[key] = job_info

        if self._order_jobs:
            self._binary_insert(self._job_info_queue, job_info, lambda elem: self._job_sorting_key(elem.job))

        else:
            self._job_info_queue.append(job_info)

Response: Insert a new job into the job queue.


Instruction:
Given the following Python 3 function, write the documentation
def _peek_job(self, pos):

        if pos < len(self._job_info_queue):
            return self._job_info_queue[pos].job

        raise IndexError()

Response: Return the job currently at the given position.


Instruction:
How would you explain what the following Python 3 function does
def _binary_insert(lst, elem, key, lo=0, hi=None):

        if lo < 0:
            raise ValueError("lo must be a non-negative number")

        if hi is None:
            hi = len(lst)

        while lo < hi:
            mid = (lo + hi) // 2
            if key(lst[mid]) < key(elem):
                lo = mid + 1
            else:
                hi = mid

        lst.insert(lo, elem)

Response: Insert an element into a sorted list and keep the list sorted.


Instruction:
Can you write a function in Python 3 where it
merges this SimMemory with the others SimMemory.

Response:
def merge(self, others, merge_conditions, common_ancestor=None): # pylint: disable=unused-argument
        """
        Merge this SimMemory with the other SimMemory
        """

        changed_bytes = self._changes_to_merge(others)

        l.info("Merging %d bytes", len(changed_bytes))
        l.info("... %s has changed bytes %s", self.id, changed_bytes)

        self.read_strategies = self._merge_strategies(self.read_strategies, *[
            o.read_strategies for o in others
        ])
        self.write_strategies = self._merge_strategies(self.write_strategies, *[
            o.write_strategies for o in others
        ])
        merged_bytes = self._merge(others, changed_bytes, merge_conditions=merge_conditions)

        return len(merged_bytes) > 0


Instruction:
Implement a Python 3 function for
making a symbolic variable of length bytes starting at addr.

Response:
def make_symbolic(self, name, addr, length=None):
        """
        Replaces `length` bytes starting at `addr` with a symbolic variable named name. Adds a constraint equaling that
        symbolic variable to the value previously at `addr`, and returns the variable.
        """
        l.debug("making %s bytes symbolic", length)

        if isinstance(addr, str):
            addr, length = self.state.arch.registers[addr]
        else:
            if length is None:
                raise Exception("Unspecified length!")

        r = self.load(addr, length)

        v = self.get_unconstrained_bytes(name, r.size())
        self.store(addr, v)
        self.state.add_constraints(r == v)
        l.debug("... eq constraints: %s", r == v)
        return v


Instruction:
Here you have a function in Python 3, explain what it does
def _apply_concretization_strategies(self, addr, strategies, action):

        # we try all the strategies in order
        for s in strategies:
            # first, we trigger the SimInspect breakpoint and give it a chance to intervene
            e = addr
            self.state._inspect(
                'address_concretization', BP_BEFORE, address_concretization_strategy=s,
                address_concretization_action=action, address_concretization_memory=self,
                address_concretization_expr=e, address_concretization_add_constraints=True
            )
            s = self.state._inspect_getattr('address_concretization_strategy', s)
            e = self.state._inspect_getattr('address_concretization_expr', addr)

            # if the breakpoint None'd out the strategy, we skip it
            if s is None:
                continue

            # let's try to apply it!
            try:
                a = s.concretize(self, e)
            except SimUnsatError:
                a = None

            # trigger the AFTER breakpoint and give it a chance to intervene
            self.state._inspect(
                'address_concretization', BP_AFTER,
                address_concretization_result=a
            )
            a = self.state._inspect_getattr('address_concretization_result', a)

            # return the result if not None!
            if a is not None:
                return a

        # well, we tried
        raise SimMemoryAddressError(
            "Unable to concretize address for %s with the provided strategies." % action
        )

Response: Applies concretization strategies on the address until one of them succeeds.


Instruction:
Explain what the following Python 3 code does
def concretize_write_addr(self, addr, strategies=None):

        if isinstance(addr, int):
            return [ addr ]
        elif not self.state.solver.symbolic(addr):
            return [ self.state.solver.eval(addr) ]

        strategies = self.write_strategies if strategies is None else strategies
        return self._apply_concretization_strategies(addr, strategies, 'store')

Response: Concretizes an address meant for writing.


Instruction:
Here you have a function in Python 3, explain what it does
def dbg_print(self, indent=0):
        lst = []
        more_data = False
        for i, addr in enumerate(self.mem.keys()):
            lst.append(addr)
            if i >= 20:
                more_data = True
                break

        for addr in sorted(lst):
            data = self.mem[addr]
            if isinstance(data, SimMemoryObject):
                memobj = data
                print("%s%xh: (%s)[%d]" % (" " * indent, addr, memobj, addr - memobj.base))
            else:
                print("%s%xh: <default data>" % (" " * indent, addr))
        if more_data:
            print("%s..." % (" " * indent))

Response: Print out debugging information.


Instruction:
Implement a Python 3 function for
retrieving the permissions of the page at the given address.

Response:
def permissions(self, addr, permissions=None):
        """
        Retrieve the permissions of the page at address `addr`.

        :param addr:        address to get the page permissions
        :param permissions: Integer or BVV to optionally set page permissions to
        :return:            AST representing the permissions on the page
        """
        out = self.mem.permissions(addr, permissions)
        # if unicorn is in play and we've marked a page writable, it must be uncached
        if permissions is not None and self.state.solver.is_true(permissions & 2 == 2):
            if self.state.has_plugin('unicorn'):
                self.state.unicorn.uncache_page(addr)
        return out


Instruction:
How would you code a function in Python 3 to
map a number of pages at address addr with permissions permissions.

Response:
def map_region(self, addr, length, permissions, init_zero=False):
        """
        Map a number of pages at address `addr` with permissions `permissions`.
        :param addr: address to map the pages at
        :param length: length in bytes of region to map, will be rounded upwards to the page size
        :param permissions: AST of permissions to map, will be a bitvalue representing flags
        :param init_zero: Initialize page with zeros
        """
        l.info("Mapping [%#x, %#x] as %s", addr, addr + length - 1, permissions)
        return self.mem.map_region(addr, length, permissions, init_zero=init_zero)


Instruction:
Can you tell what is the following Python 3 function doing
def successors(self, *args, **kwargs):

        return self.project.engines.successors(*args, **kwargs)

Response: Return a SimSuccessors object that represents the results of the current execution using any applicable engine.


Instruction:
Write a Python 3 function that can
return a state object initialized to the start of a given function, as if it were called with given parameters. :param addr: The address the state should start at instead of the entry point. :param args: Any additional positional arguments will be used as arguments to the function call. The following parametrs are optional. :param base_state: Use this SimState as the base for the new state instead of a blank state. :param cc: Optionally provide a SimCC object to use a specific calling convention. :param ret_addr: Use this address as the function's return target. :param stack_base: An optional pointer to use as the top of the stack, circa the function entry point :param alloc_base: An optional pointer to use as the place to put excess argument data :param grow_like_stack: When allocating data at alloc_base, whether to allocate at decreasing addresses :param toc: The address of the table of contents for ppc64 :param initial_prefix: If this is provided, all symbolic registers will hold symbolic values with names prefixed by this string. :param fs: A dictionary of file names with associated preset SimFile objects. :param concrete_fs: bool describing whether the host filesystem should be consulted when opening files. :param chroot: A path to use as a fake root directory, Behaves similarly to a real chroot. Used only when concrete_fs is set to True. :param kwargs: Any additional keyword args will be passed to the SimState constructor. :return: The state at the beginning of the function. :rtype: SimState The idea here is that you can provide almost any kind of python type in `args` and it'll be translated to a binary format to be placed into simulated memory. Lists (representing arrays) must be entirely elements of the same type and size, while tuples (representing structs) can be elements of any type and size. If you'd like there to be a pointer to a given value, wrap the value in a `SimCC.PointerWrapper`. Any value that can't fit in a register will be automatically put in a PointerWrapper. If stack_base is not provided, the current stack pointer will be used, and it will be updated. If alloc_base is not provided, the current stack pointer will be used, and it will be updated. You might not like the results if you provide stack_base but not alloc_base. grow_like_stack controls the behavior of allocating data at alloc_base. When data from args needs to be wrapped in a pointer, the pointer needs to point somewhere, so that data is dumped into memory at alloc_base. If you set alloc_base to point to somewhere other than the stack, set grow_like_stack to False so that sequencial allocations happen at increasing addresses.

Response:
def call_state(self, addr, *args, **kwargs):
        """
        Returns a state object initialized to the start of a given function, as if it were called with given parameters.

        :param addr:            The address the state should start at instead of the entry point.
        :param args:            Any additional positional arguments will be used as arguments to the function call.

        The following parametrs are optional.

        :param base_state:      Use this SimState as the base for the new state instead of a blank state.
        :param cc:              Optionally provide a SimCC object to use a specific calling convention.
        :param ret_addr:        Use this address as the function's return target.
        :param stack_base:      An optional pointer to use as the top of the stack, circa the function entry point
        :param alloc_base:      An optional pointer to use as the place to put excess argument data
        :param grow_like_stack: When allocating data at alloc_base, whether to allocate at decreasing addresses
        :param toc:             The address of the table of contents for ppc64
        :param initial_prefix:  If this is provided, all symbolic registers will hold symbolic values with names
                                prefixed by this string.
        :param fs:              A dictionary of file names with associated preset SimFile objects.
        :param concrete_fs:     bool describing whether the host filesystem should be consulted when opening files.
        :param chroot:          A path to use as a fake root directory, Behaves similarly to a real chroot. Used only
                                when concrete_fs is set to True.
        :param kwargs:          Any additional keyword args will be passed to the SimState constructor.
        :return:                The state at the beginning of the function.
        :rtype:                 SimState

        The idea here is that you can provide almost any kind of python type in `args` and it'll be translated to a
        binary format to be placed into simulated memory. Lists (representing arrays) must be entirely elements of the
        same type and size, while tuples (representing structs) can be elements of any type and size.
        If you'd like there to be a pointer to a given value, wrap the value in a `SimCC.PointerWrapper`. Any value
        that can't fit in a register will be automatically put in a
        PointerWrapper.

        If stack_base is not provided, the current stack pointer will be used, and it will be updated.
        If alloc_base is not provided, the current stack pointer will be used, and it will be updated.
        You might not like the results if you provide stack_base but not alloc_base.

        grow_like_stack controls the behavior of allocating data at alloc_base. When data from args needs to be wrapped
        in a pointer, the pointer needs to point somewhere, so that data is dumped into memory at alloc_base. If you
        set alloc_base to point to somewhere other than the stack, set grow_like_stack to False so that sequencial
        allocations happen at increasing addresses.
        """
        return self.project.simos.state_call(addr, *args, **kwargs)


Instruction:
Implement a function in Python 3 to
return a new SimulationManager object initialized with the given thing.

Response:
def simulation_manager(self, thing=None, **kwargs):
        """
        Constructs a new simulation manager.

        :param thing:           Optional - What to put in the new SimulationManager's active stash (either a SimState or a list of SimStates).
        :param kwargs:          Any additional keyword arguments will be passed to the SimulationManager constructor
        :returns:               The new SimulationManager
        :rtype:                 angr.sim_manager.SimulationManager

        Many different types can be passed to this method:

        * If nothing is passed in, the SimulationManager is seeded with a state initialized for the program
          entry point, i.e. :meth:`entry_state()`.
        * If a :class:`SimState` is passed in, the SimulationManager is seeded with that state.
        * If a list is passed in, the list must contain only SimStates and the whole list will be used to seed the SimulationManager.
        """
        if thing is None:
            thing = [ self.entry_state() ]
        elif isinstance(thing, (list, tuple)):
            if any(not isinstance(val, SimState) for val in thing):
                raise AngrError("Bad type to initialize SimulationManager")
        elif isinstance(thing, SimState):
            thing = [ thing ]
        else:
            raise AngrError("BadType to initialze SimulationManager: %s" % repr(thing))

        return SimulationManager(self.project, active_states=thing, **kwargs)


Instruction:
How would you implement a function in Python 3 that
returns a Callable object that can be used as a interface for executing a virtual machine code like a native python function.

Response:
def callable(self, addr, concrete_only=False, perform_merge=True, base_state=None, toc=None, cc=None):
        """
        A Callable is a representation of a function in the binary that can be interacted with like a native python
        function.

        :param addr:            The address of the function to use
        :param concrete_only:   Throw an exception if the execution splits into multiple states
        :param perform_merge:   Merge all result states into one at the end (only relevant if concrete_only=False)
        :param base_state:      The state from which to do these runs
        :param toc:             The address of the table of contents for ppc64
        :param cc:              The SimCC to use for a calling convention
        :returns:               A Callable object that can be used as a interface for executing guest code like a
                                python function.
        :rtype:                 angr.callable.Callable
        """
        return Callable(self.project,
                        addr=addr,
                        concrete_only=concrete_only,
                        perform_merge=perform_merge,
                        base_state=base_state,
                        toc=toc,
                        cc=cc)


Instruction:
Create a Python 3 function for
returning a SimCC object parametrized for this project and optionally a given function.

Response:
def cc(self, args=None, ret_val=None, sp_delta=None, func_ty=None):
        """
        Return a SimCC (calling convention) parametrized for this project and, optionally, a given function.

        :param args:        A list of argument storage locations, as SimFunctionArguments.
        :param ret_val:     The return value storage location, as a SimFunctionArgument.
        :param sp_delta:    Does this even matter??
        :param func_ty:     The prototype for the given function, as a SimType or a C-style function declaration that
                            can be parsed into a SimTypeFunction instance.

        Example func_ty strings:
        >>> "int func(char*, int)"
        >>> "int f(int, int, int*);"
        Function names are ignored.

        Relevant subclasses of SimFunctionArgument are SimRegArg and SimStackArg, and shortcuts to them can be found on
        this `cc` object.

        For stack arguments, offsets are relative to the stack pointer on function entry.
        """

        return self._default_cc(arch=self.project.arch,
                                  args=args,
                                  ret_val=ret_val,
                                  sp_delta=sp_delta,
                                  func_ty=func_ty)


Instruction:
Create a Python 3 function to
return a SimCC instance that will extract the arguments of the function.

Response:
def cc_from_arg_kinds(self, fp_args, ret_fp=None, sizes=None, sp_delta=None, func_ty=None):
        """
        Get a SimCC (calling convention) that will extract floating-point/integral args correctly.

        :param arch:        The Archinfo arch for this CC
        :param fp_args:     A list, with one entry for each argument the function can take. True if the argument is fp,
                            false if it is integral.
        :param ret_fp:      True if the return value for the function is fp.
        :param sizes:       Optional: A list, with one entry for each argument the function can take. Each entry is the
                            size of the corresponding argument in bytes.
        :param sp_delta:    The amount the stack pointer changes over the course of this function - CURRENTLY UNUSED
        :param func_ty:     A SimType for the function itself or a C-style function declaration that can be parsed into
                            a SimTypeFunction instance.

        Example func_ty strings:
        >>> "int func(char*, int)"
        >>> "int f(int, int, int*);"
        Function names are ignored.

        """
        return self._default_cc.from_arg_kinds(arch=self.project.arch,
                fp_args=fp_args,
                ret_fp=ret_fp,
                sizes=sizes,
                sp_delta=sp_delta,
                func_ty=func_ty)


Instruction:
Can you tell what is the following Python 3 function doing
def operations(self):
        return [op for block in self.blocks for op in block.vex.operations]

Response: Returns a list of all of the operations done by this functions.


Instruction:
Can you tell what is the following Python 3 function doing
def string_references(self, minimum_length=2, vex_only=False):
        strings = []
        memory = self._project.loader.memory

        # get known instruction addresses and call targets
        # these addresses cannot be string references, but show up frequently in the runtime values
        known_executable_addresses = set()
        for block in self.blocks:
            known_executable_addresses.update(block.instruction_addrs)
        for function in self._function_manager.values():
            known_executable_addresses.update(set(x.addr for x in function.graph.nodes()))

        # loop over all local runtime values and check if the value points to a printable string
        for addr in self.local_runtime_values if not vex_only else self.code_constants:
            if not isinstance(addr, claripy.fp.FPV) and addr in memory:
                # check that the address isn't an pointing to known executable code
                # and that it isn't an indirect pointer to known executable code
                try:
                    possible_pointer = memory.unpack_word(addr)
                    if addr not in known_executable_addresses and possible_pointer not in known_executable_addresses:
                        # build string
                        stn = ""
                        offset = 0
                        current_char = chr(memory[addr + offset])
                        while current_char in string.printable:
                            stn += current_char
                            offset += 1
                            current_char = chr(memory[addr + offset])

                        # check that the string was a null terminated string with minimum length
                        if current_char == "\x00" and len(stn) >= minimum_length:
                            strings.append((addr, stn))
                except KeyError:
                    pass
        return strings

Response: Return a list of tuples of address and string that are used by this function.


Instruction:
Can you write a function in Python 3 where it
tries to find all runtime values of this function which do not come from inputs.

Response:
def local_runtime_values(self):
        """
        Tries to find all runtime values of this function which do not come from inputs.
        These values are generated by starting from a blank state and reanalyzing the basic blocks once each.
        Function calls are skipped, and back edges are never taken so these values are often unreliable,
        This function is good at finding simple constant addresses which the function will use or calculate.

        :return: a set of constants
        """
        constants = set()

        if not self._project.loader.main_object.contains_addr(self.addr):
            return constants

        # FIXME the old way was better for architectures like mips, but we need the initial irsb
        # reanalyze function with a new initial state (use persistent registers)
        # initial_state = self._function_manager._cfg.get_any_irsb(self.addr).initial_state
        # fresh_state = self._project.factory.blank_state(mode="fastpath")
        # for reg in initial_state.arch.persistent_regs + ['ip']:
        #     fresh_state.registers.store(reg, initial_state.registers.load(reg))

        # reanalyze function with a new initial state
        fresh_state = self._project.factory.blank_state(mode="fastpath")
        fresh_state.regs.ip = self.addr

        graph_addrs = set(x.addr for x in self.graph.nodes() if isinstance(x, BlockNode))

        # process the nodes in a breadth-first order keeping track of which nodes have already been analyzed
        analyzed = set()
        q = [fresh_state]
        analyzed.add(fresh_state.solver.eval(fresh_state.ip))
        while len(q) > 0:
            state = q.pop()
            # make sure its in this function
            if state.solver.eval(state.ip) not in graph_addrs:
                continue
            # don't trace into simprocedures
            if self._project.is_hooked(state.solver.eval(state.ip)):
                continue
            # don't trace outside of the binary
            if not self._project.loader.main_object.contains_addr(state.solver.eval(state.ip)):
                continue
            # don't trace unreachable blocks
            if state.history.jumpkind in {'Ijk_EmWarn', 'Ijk_NoDecode',
                                          'Ijk_MapFail', 'Ijk_NoRedir',
                                          'Ijk_SigTRAP', 'Ijk_SigSEGV',
                                          'Ijk_ClientReq'}:
                continue

            curr_ip = state.solver.eval(state.ip)

            # get runtime values from logs of successors
            successors = self._project.factory.successors(state)
            for succ in successors.flat_successors + successors.unsat_successors:
                for a in succ.history.recent_actions:
                    for ao in a.all_objects:
                        if not isinstance(ao.ast, claripy.ast.Base):
                            constants.add(ao.ast)
                        elif not ao.ast.symbolic:
                            constants.add(succ.solver.eval(ao.ast))

                # add successors to the queue to analyze
                if not succ.solver.symbolic(succ.ip):
                    succ_ip = succ.solver.eval(succ.ip)
                    if succ_ip in self and succ_ip not in analyzed:
                        analyzed.add(succ_ip)
                        q.insert(0, succ)

            # force jumps to missing successors
            # (this is a slightly hacky way to force it to explore all the nodes in the function)
            node = self.get_node(curr_ip)
            if node is None:
                # the node does not exist. maybe it's not a block node.
                continue
            missing = set(x.addr for x in list(self.graph.successors(node))) - analyzed
            for succ_addr in missing:
                l.info("Forcing jump to missing successor: %#x", succ_addr)
                if succ_addr not in analyzed:
                    all_successors = successors.unconstrained_successors + \
                                     successors.flat_successors + \
                                     successors.unsat_successors
                    if len(all_successors) > 0:
                        # set the ip of a copied successor to the successor address
                        succ = all_successors[0].copy()
                        succ.ip = succ_addr
                        analyzed.add(succ_addr)
                        q.insert(0, succ)
                    else:
                        l.warning("Could not reach successor: %#x", succ_addr)

        return constants


Instruction:
Make a summary of the following Python 3 code
def runtime_values(self):
        constants = set()
        for b in self.block_addrs:
            for sirsb in self._function_manager._cfg.get_all_irsbs(b):
                for s in sirsb.successors + sirsb.unsat_successors:
                    for a in s.history.recent_actions:
                        for ao in a.all_objects:
                            if not isinstance(ao.ast, claripy.ast.Base):
                                constants.add(ao.ast)
                            elif not ao.ast.symbolic:
                                constants.add(s.solver.eval(ao.ast))
        return constants

Response: Returns a set of concrete values used by this function at runtime.


Instruction:
Can you write a function in Python 3 where it
returns the object this function belongs to.

Response:
def binary(self):
        """
        Get the object this function belongs to.
        :return: The object this function belongs to.
        """

        return self._project.loader.find_object_containing(self.addr, membership_check=False)


Instruction:
Create a Python 3 function for
adding a custom jumpout site.

Response:
def add_jumpout_site(self, node):
        """
        Add a custom jumpout site.

        :param node:    The address of the basic block that control flow leaves during this transition.
        :return:        None
        """

        self._register_nodes(True, node)
        self._jumpout_sites.add(node)
        self._add_endpoint(node, 'transition')


Instruction:
Write a Python 3 script to
add a custom retout site.

Response:
def add_retout_site(self, node):
        """
        Add a custom retout site.

        Retout (returning to outside of the function) sites are very rare. It mostly occurs during CFG recovery when we
        incorrectly identify the beginning of a function in the first iteration, and then correctly identify that
        function later in the same iteration (function alignments can lead to this bizarre case). We will mark all edges
        going out of the header of that function as a outside edge, because all successors now belong to the
        incorrectly-identified function. This identification error will be fixed in the second iteration of CFG
        recovery. However, we still want to keep track of jumpouts/retouts during the first iteration so other logic in
        CFG recovery still work.

        :param node: The address of the basic block that control flow leaves the current function after a call.
        :return:     None
        """

        self._register_nodes(True, node)
        self._retout_sites.add(node)
        self._add_endpoint(node, 'return')


Instruction:
Implement a Python 3 function for
determining the most suitable name of the function.

Response:
def _get_initial_name(self):
        """
        Determine the most suitable name of the function.

        :return:    The initial function name.
        :rtype:     string
        """

        name = None
        addr = self.addr

        # Try to get a name from existing labels
        if self._function_manager is not None:
            if addr in self._function_manager._kb.labels:
                name = self._function_manager._kb.labels[addr]

        # try to get the name from a hook
        if name is None and self.project is not None:
            project = self.project
            if project.is_hooked(addr):
                hooker = project.hooked_by(addr)
                name = hooker.display_name
            elif project.simos.is_syscall_addr(addr):
                syscall_inst = project.simos.syscall_from_addr(addr)
                name = syscall_inst.display_name

        # generate an IDA-style sub_X name
        if name is None:
            name = 'sub_%x' % addr

        return name


Instruction:
Given the following Python 3 function, write the documentation
def _get_initial_binary_name(self):

        binary_name = None

        # if this function is a simprocedure but not a syscall, use its library name as
        # its binary name
        # if it is a syscall, fall back to use self.binary.binary which explicitly says cle##kernel
        if self.project and self.is_simprocedure and not self.is_syscall:
            hooker = self.project.hooked_by(self.addr)
            if hooker is not None:
                binary_name = hooker.library_name

        if binary_name is None and self.binary is not None:
            binary_name = os.path.basename(self.binary.binary)

        return binary_name

Response: Determine the name of the initial binary name for this function.


Instruction:
Can you tell what is the following Python 3 function doing
def _get_initial_returning(self):

        hooker = None
        if self.is_syscall:
            hooker = self.project.simos.syscall_from_addr(self.addr)
        elif self.is_simprocedure:
            hooker = self.project.hooked_by(self.addr)
        if hooker and hasattr(hooker, 'NO_RET'):
            return not hooker.NO_RET

        # Cannot determine
        return None

Response: Determine if this function returns or not.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _transit_to(self, from_node, to_node, outside=False, ins_addr=None, stmt_idx=None):

        if outside:
            self._register_nodes(True, from_node)
            if to_node is not None:
                self._register_nodes(False, to_node)

            self._jumpout_sites.add(from_node)
        else:
            if to_node is not None:
                self._register_nodes(True, from_node, to_node)
            else:
                self._register_nodes(True, from_node)

        if to_node is not None:
            self.transition_graph.add_edge(from_node, to_node, type='transition', outside=outside, ins_addr=ins_addr,
                                           stmt_idx=stmt_idx
                                           )

        if outside:
            # this node is an endpoint of the current function
            self._add_endpoint(from_node, 'transition')

        # clear the cache
        self._local_transition_graph = None

Response: Internal method that creates a transition between two basic blocks.


Instruction:
Write a Python 3 script to
register an edge between the caller basic block and callee function. :param from_addr: The basic block that control flow leaves during the transition. :type from_addr: angr.knowledge.CodeNode :param to_func: The function that we are calling :type to_func: Function :param ret_node The basic block that control flow should return to after the function call. :type to_func: angr.knowledge.CodeNode or None :param stmt_idx: Statement ID of this call. :type stmt_idx: int, str or None :param ins_addr: Instruction address of this call. :type ins_addr: int or None

Response:
def _call_to(self, from_node, to_func, ret_node, stmt_idx=None, ins_addr=None, return_to_outside=False):
        """
        Registers an edge between the caller basic block and callee function.

        :param from_addr:   The basic block that control flow leaves during the transition.
        :type  from_addr:   angr.knowledge.CodeNode
        :param to_func:     The function that we are calling
        :type  to_func:     Function
        :param ret_node     The basic block that control flow should return to after the
                            function call.
        :type  to_func:     angr.knowledge.CodeNode or None
        :param stmt_idx:    Statement ID of this call.
        :type  stmt_idx:    int, str or None
        :param ins_addr:    Instruction address of this call.
        :type  ins_addr:    int or None
        """

        self._register_nodes(True, from_node)

        if to_func.is_syscall:
            self.transition_graph.add_edge(from_node, to_func, type='syscall', stmt_idx=stmt_idx, ins_addr=ins_addr)
        else:
            self.transition_graph.add_edge(from_node, to_func, type='call', stmt_idx=stmt_idx, ins_addr=ins_addr)
            if ret_node is not None:
                self._fakeret_to(from_node, ret_node, to_outside=return_to_outside)

        self._local_transition_graph = None


Instruction:
How would you explain what the following Python 3 function does
def _add_return_site(self, return_site):
        self._register_nodes(True, return_site)

        self._ret_sites.add(return_site)
        # A return site must be an endpoint of the function - you cannot continue execution of the current function
        # after returning
        self._add_endpoint(return_site, 'return')

Response: Adds a return site to the list of return sites that this function returns.


Instruction:
Explain what the following Python 3 code does
def _add_call_site(self, call_site_addr, call_target_addr, retn_addr):
        self._call_sites[call_site_addr] = (call_target_addr, retn_addr)

Response: Adds a call site to the internal list of call sites.


Instruction:
Explain what the following Python 3 code does
def mark_nonreturning_calls_endpoints(self):

        for src, dst, data in self.transition_graph.edges(data=True):
            if 'type' in data and data['type'] == 'call':
                func_addr = dst.addr
                if func_addr in self._function_manager:
                    function = self._function_manager[func_addr]
                    if function.returning is False:
                        # the target function does not return
                        the_node = self.get_node(src.addr)
                        self._callout_sites.add(the_node)
                        self._add_endpoint(the_node, 'call')

Response: Iterate through all non - returning functions and mark their endpoints as non - returning calls.


Instruction:
How would you explain what the following Python 3 function does
def graph(self):

        if self._local_transition_graph is not None:
            return self._local_transition_graph

        g = networkx.DiGraph()
        if self.startpoint is not None:
            g.add_node(self.startpoint)
        for block in self._local_blocks.values():
            g.add_node(block)
        for src, dst, data in self.transition_graph.edges(data=True):
            if 'type' in data:
                if data['type']  == 'transition' and ('outside' not in data or data['outside'] is False):
                    g.add_edge(src, dst, **data)
                elif data['type'] == 'fake_return' and 'confirmed' in data and \
                        ('outside' not in data or data['outside'] is False):
                    g.add_edge(src, dst, **data)

        self._local_transition_graph = g

        return g

Response: Return a networkx. DiGraph that only contains nodes in current function.


Instruction:
Write a Python 3 script for
generating a sub - control flow graph of instruction addresses based on self. graph MimeType.

Response:
def subgraph(self, ins_addrs):
        """
        Generate a sub control flow graph of instruction addresses based on self.graph

        :param iterable ins_addrs: A collection of instruction addresses that should be included in the subgraph.
        :return: A subgraph.
        :rtype: networkx.DiGraph
        """

        # find all basic blocks that include those instructions
        blocks = []
        block_addr_to_insns = {}

        for b in self._local_blocks.values():
            # TODO: should I call get_blocks?
            block = self._get_block(b.addr, size=b.size, byte_string=b.bytestr)
            common_insns = set(block.instruction_addrs).intersection(ins_addrs)
            if common_insns:
                blocks.append(b)
                block_addr_to_insns[b.addr] = sorted(common_insns)

       #subgraph = networkx.subgraph(self.graph, blocks)
        subgraph = self.graph.subgraph(blocks).copy()
        g = networkx.DiGraph()

        for n in subgraph.nodes():
            insns = block_addr_to_insns[n.addr]

            in_edges = subgraph.in_edges(n)
            # out_edges = subgraph.out_edges(n)
            if len(in_edges) > 1:
                # the first instruction address should be included
                if n.addr not in insns:
                    insns = [n.addr] + insns

            for src, _ in in_edges:
                last_instr = block_addr_to_insns[src.addr][-1]
                g.add_edge(last_instr, insns[0])

            for i in range(0, len(insns) - 1):
                g.add_edge(insns[i], insns[i + 1])

        return g


Instruction:
Can you implement a function in Python 3 that
gets the size of the instruction specified by insn_addr.

Response:
def instruction_size(self, insn_addr):
        """
        Get the size of the instruction specified by `insn_addr`.

        :param int insn_addr: Address of the instruction
        :return: Size of the instruction in bytes, or None if the instruction is not found.
        :rtype: int
        """

        for b in self.blocks:
            block = self._get_block(b.addr, size=b.size, byte_string=b.bytestr)
            if insn_addr in block.instruction_addrs:
                index = block.instruction_addrs.index(insn_addr)
                if index == len(block.instruction_addrs) - 1:
                    # the very last instruction
                    size = block.addr + block.size - insn_addr
                else:
                    size = block.instruction_addrs[index + 1] - insn_addr
                return size

        return None


Instruction:
Create a Python 3 function to
draw the graph and save it to a PNG file.

Response:
def dbg_draw(self, filename):
        """
        Draw the graph and save it to a PNG file.
        """
        import matplotlib.pyplot as pyplot  # pylint: disable=import-error
        from networkx.drawing.nx_agraph import graphviz_layout  # pylint: disable=import-error

        tmp_graph = networkx.DiGraph()
        for from_block, to_block in self.transition_graph.edges():
            node_a = "%#08x" % from_block.addr
            node_b = "%#08x" % to_block.addr
            if node_b in self._ret_sites:
                node_b += "[Ret]"
            if node_a in self._call_sites:
                node_a += "[Call]"
            tmp_graph.add_edge(node_a, node_b)
        pos = graphviz_layout(tmp_graph, prog='fdp')   # pylint: disable=no-member
        networkx.draw(tmp_graph, pos, node_size=1200)
        pyplot.savefig(filename)


Instruction:
Can you create a Python 3 function that
adds an offset to the list of registers that are used as an argument to the function.

Response:
def _add_argument_register(self, reg_offset):
        """
        Registers a register offset as being used as an argument to the function.

        :param reg_offset:          The offset of the register to register.
        """
        if reg_offset in self._function_manager._arg_registers and \
                    reg_offset not in self._argument_registers:
            self._argument_registers.append(reg_offset)


Instruction:
Can you generate the documentation for the following Python 3 function
def normalize(self):

        # let's put a check here
        if self.startpoint is None:
            # this function is empty
            l.debug('Unexpected error: %s does not have any blocks. normalize() fails.', repr(self))
            return

        graph = self.transition_graph
        end_addresses = defaultdict(list)

        for block in self.nodes:
            if isinstance(block, BlockNode):
                end_addr = block.addr + block.size
                end_addresses[end_addr].append(block)

        while any(len(x) > 1 for x in end_addresses.values()):
            end_addr, all_nodes = \
                next((end_addr, x) for (end_addr, x) in end_addresses.items() if len(x) > 1)

            all_nodes = sorted(all_nodes, key=lambda node: node.size)
            smallest_node = all_nodes[0]
            other_nodes = all_nodes[1:]

            is_outside_node = False
            if smallest_node not in graph:
                is_outside_node = True

            # Break other nodes
            for n in other_nodes:
                new_size = get_real_address_if_arm(self._project.arch, smallest_node.addr) - get_real_address_if_arm(self._project.arch, n.addr)
                if new_size == 0:
                    # This is the node that has the same size as the smallest one
                    continue

                new_end_addr = n.addr + new_size

                # Does it already exist?
                new_node = None
                if new_end_addr in end_addresses:
                    nodes = [i for i in end_addresses[new_end_addr] if i.addr == n.addr]
                    if len(nodes) > 0:
                        new_node = nodes[0]

                if new_node is None:
                    # TODO: Do this correctly for hook nodes
                    # Create a new one
                    new_node = BlockNode(n.addr, new_size, graph=graph, thumb=n.thumb)
                    self._block_sizes[n.addr] = new_size
                    self._addr_to_block_node[n.addr] = new_node
                    # Put the newnode into end_addresses
                    end_addresses[new_end_addr].append(new_node)

                # Modify the CFG
                original_predecessors = list(graph.in_edges([n], data=True))
                original_successors = list(graph.out_edges([n], data=True))

                for _, d, data in original_successors:
                    ins_addr = data.get('ins_addr', data.get('pseudo_ins_addr', None))
                    if ins_addr is not None and ins_addr < d.addr:
                        continue
                    if d not in graph[smallest_node]:
                        if d is n:
                            graph.add_edge(smallest_node, new_node, **data)
                        else:
                            graph.add_edge(smallest_node, d, **data)

                for p, _, _ in original_predecessors:
                    graph.remove_edge(p, n)
                graph.remove_node(n)

                # update local_blocks
                if n.addr in self._local_blocks and self._local_blocks[n.addr].size != new_node.size:
                    del self._local_blocks[n.addr]
                    self._local_blocks[n.addr] = new_node

                # update block_cache and block_sizes
                if (n.addr in self._block_cache and self._block_cache[n.addr].size != new_node.size) or \
                        (n.addr in self._block_sizes and self._block_sizes[n.addr] != new_node.size):
                    # the cache needs updating
                    self._block_cache.pop(n.addr, None)
                    self._block_sizes[n.addr] = new_node.size

                for p, _, data in original_predecessors:
                    if p not in other_nodes:
                        graph.add_edge(p, new_node, **data)

                # We should find the correct successor
                new_successors = [i for i in all_nodes
                                  if i.addr == smallest_node.addr]
                if new_successors:
                    new_successor = new_successors[0]
                    graph.add_edge(new_node, new_successor,
                                   type="transition",
                                   outside=is_outside_node,
                                   # it's named "pseudo_ins_addr" because we have no way to know what the actual last
                                   # instruction is at this moment (without re-lifting the block, which would be a
                                   # waste of time).
                                   pseudo_ins_addr=new_node.addr + new_node.size - 1,
                                   )
                else:
                    # We gotta create a new one
                    l.error('normalize(): Please report it to Fish/maybe john.')

            end_addresses[end_addr] = [smallest_node]

        # Rebuild startpoint
        if self.startpoint.size != self._block_sizes[self.startpoint.addr]:
            self.startpoint = self.get_node(self.startpoint.addr)

        # Clear the cache
        self._local_transition_graph = None

        self.normalized = True

Response: This function is used to normalize the CFG by removing all basic blocks that are not part of the transition graph.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def find_declaration(self):

        # determine the library name

        if not self.is_plt:
            binary_name = self.binary_name
            if binary_name not in SIM_LIBRARIES:
                return
        else:
            binary_name = None
            # PLT entries must have the same declaration as their jump targets
            # Try to determine which library this PLT entry will jump to
            edges = self.transition_graph.edges()
            node = next(iter(edges))[1]
            if len(edges) == 1 and (type(node) is HookNode or type(node) is SyscallNode):
                target = node.addr
                if target in self._function_manager:
                    target_func = self._function_manager[target]
                    binary_name = target_func.binary_name

        if binary_name is None:
            return

        library = SIM_LIBRARIES.get(binary_name, None)

        if library is None:
            return

        if not library.has_prototype(self.name):
            return

        proto = library.prototypes[self.name]

        self.prototype = proto
        if self.calling_convention is not None:
            self.calling_convention.args = None
            self.calling_convention.func_ty = proto

Response: Find the most likely function declaration from the embedded collection of prototypes set self. prototype and self. calling_convention with the declaration.


Instruction:
Can you implement a function in Python 3 that
reverses look - up.

Response:
def _rfind(lst, item):
        """
        Reverse look-up.

        :param list lst: The list to look up in.
        :param item: The item to look for.
        :return: Offset of the item if found. A ValueError is raised if the item is not in the list.
        :rtype: int
        """

        try:
            return dropwhile(lambda x: lst[x] != item,
                             next(reversed(range(len(lst)))))
        except Exception:
            raise ValueError("%s not in the list" % item)


Instruction:
Can you implement a function in Python 3 that
pushes the frame cf onto the stack. Return the new stack.

Response:
def push(self, cf):
        """
        Push the frame cf onto the stack. Return the new stack.
        """
        cf.next = self
        if self.state is not None:
            self.state.register_plugin('callstack', cf)
            self.state.history.recent_stack_actions.append(CallStackAction(
                hash(cf), len(cf), 'push', callframe=cf.copy({}, with_tail=False)
            ))

        return cf


Instruction:
How would you code a function in Python 3 to
pop the top frame from the stack. Return the new stack.

Response:
def pop(self):
        """
        Pop the top frame from the stack. Return the new stack.
        """
        if self.next is None:
            raise SimEmptyCallStackError("Cannot pop a frame from an empty call stack.")
        new_list = self.next.copy({})

        if self.state is not None:
            self.state.register_plugin('callstack', new_list)
            self.state.history.recent_stack_actions.append(CallStackAction(
                hash(new_list), len(new_list), 'pop', ret_site_addr=self.ret_addr
            ))

        return new_list


Instruction:
Given the following Python 3 function, write the documentation
def call(self, callsite_addr, addr, retn_target=None, stack_pointer=None):

        frame = CallStack(call_site_addr=callsite_addr, func_addr=addr, ret_addr=retn_target,
                          stack_ptr=stack_pointer)
        return self.push(frame)

Response: Push a stack frame into the call stack. This method is called when calling a function in CFG recovery.


Instruction:
How would you explain what the following Python 3 function does
def ret(self, retn_target=None):

        if retn_target is None:
            return self.pop()

        # We may want to return to several levels up there, not only a
        # single stack frame
        return_target_index = self._find_return_target(retn_target)

        if return_target_index is not None:

            o = self
            while return_target_index >= 0:
                o = o.pop()
                return_target_index -= 1
            return o

        l.warning("Returning to an unexpected address %#x", retn_target)
        return self

Response: Pop one or many call frames from the stack.


Instruction:
Write a Python 3 script to
debug representation of this CalLStack object.

Response:
def dbg_repr(self):
        """
        Debugging representation of this CallStack object.

        :return: Details of this CalLStack
        :rtype: str
        """

        stack = [ ]
        for i, frame in enumerate(self):
            s = "%d | %s -> %s, returning to %s" % (
                i,
                "None" if frame.call_site_addr is None else "%#x" % frame.call_site_addr,
                "None" if frame.func_addr is None else "%#x" % frame.func_addr,
                "None" if frame.return_target is None else "%#x" % frame.return_target,
            )
            stack.append(s)

        return "\n".join(stack)


Instruction:
Can you write a function in Python 3 where it
generates the stack suffix.

Response:
def stack_suffix(self, context_sensitivity_level):
        """
        Generate the stack suffix. A stack suffix can be used as the key to a SimRun in CFG recovery.

        :param int context_sensitivity_level: Level of context sensitivity.
        :return: A tuple of stack suffix.
        :rtype: tuple
        """

        ret = ()

        for frame in self:
            if len(ret) >= context_sensitivity_level*2:
                break
            ret = (frame.call_site_addr, frame.func_addr) + ret

        while len(ret) < context_sensitivity_level*2:
            ret = (None, None) + ret

        return ret


Instruction:
Explain what the following Python 3 code does
def _find_return_target(self, target):

        for i, frame in enumerate(self):
            if frame.ret_addr == target:
                return i
        return None

Response: Searches the stack for the return target and returns the index if exists.


Instruction:
Explain what the following Python 3 code does
def update_stock_codes():
    all_stock_codes_url = "http://www.shdjt.com/js/lib/astock.js"
    grep_stock_codes = re.compile(r"~(\d+)`")
    response = requests.get(all_stock_codes_url)
    all_stock_codes = grep_stock_codes.findall(response.text)
    with open(stock_code_path(), "w") as f:
        f.write(json.dumps(dict(stock=all_stock_codes)))

Response: Update all_stock_code with the new stock codes


Instruction:
Explain what the following Python 3 code does
def get_stock_codes(realtime=False):
    if realtime:
        all_stock_codes_url = "http://www.shdjt.com/js/lib/astock.js"
        grep_stock_codes = re.compile(r"~(\d+)`")
        response = requests.get(all_stock_codes_url)
        stock_codes = grep_stock_codes.findall(response.text)
        with open(stock_code_path(), "w") as f:
            f.write(json.dumps(dict(stock=stock_codes)))
        return stock_codes

    with open(stock_code_path()) as f:
        return json.load(f)["stock"]

Response: Get all stock codes


Instruction:
Write a Python 3 script to
return specific stocks real quotation

Response:
def real(self, stock_codes, prefix=False):
        """return specific stocks real quotation
        :param stock_codes: stock code or list of stock code,
                when prefix is True, stock code must start with sh/sz
        :param prefix: if prefix i True, stock_codes must contain sh/sz market
            flag. If prefix is False, index quotation can't return
        :return quotation dict, key is stock_code, value is real quotation.
            If prefix with True, key start with sh/sz market flag

        """
        if not isinstance(stock_codes, list):
            stock_codes = [stock_codes]

        stock_list = self.gen_stock_list(stock_codes)
        return self.get_stock_data(stock_list, prefix=prefix)


Instruction:
Can you create a Python 3 function that
returns all market quotation snapshot

Response:
def market_snapshot(self, prefix=False):
        """return all market quotation snapshot
        :param prefix: if prefix is True, return quotation dict's  stock_code
             key start with sh/sz market flag
        """
        return self.get_stock_data(self.stock_list, prefix=prefix)


Instruction:
Here you have a function in Python 3, explain what it does
def _fetch_stock_data(self, stock_list):
        pool = multiprocessing.pool.ThreadPool(len(stock_list))
        try:
            res = pool.map(self.get_stocks_by_range, stock_list)
        finally:
            pool.close()
        return [d for d in res if d is not None]

Response: Get stock data from list


Instruction:
Write a Python 3 function that can
fetch stock data from timekline

Response:
def _fetch_stock_data(self, stock_list):
        """因为 timekline 的返回没有带对应的股票代码，所以要手动带上"""
        res = super()._fetch_stock_data(stock_list)

        with_stock = []
        for stock, resp in zip(stock_list, res):
            if resp is not None:
                with_stock.append((stock, resp))
        return with_stock


Instruction:
Here you have a function in Python 3, explain what it does
def formatfundajson(fundajson):
        result = {}
        for row in fundajson["rows"]:
            funda_id = row["id"]
            cell = row["cell"]
            result[funda_id] = cell
        return result

Response: format fundajson to dict


Instruction:
Can you generate a brief explanation for the following Python 3 code
def formatfundbjson(fundbjson):
        result = {}
        for row in fundbjson["rows"]:
            cell = row["cell"]
            fundb_id = cell["fundb_id"]
            result[fundb_id] = cell
        return result

Response: format fundbjson to dict


Instruction:
How would you explain what the following Python 3 function does
def formatetfindexjson(fundbjson):
        result = {}
        for row in fundbjson["rows"]:
            cell = row["cell"]
            fundb_id = cell["fund_id"]
            result[fundb_id] = cell
        return result

Response: formatetfindexjson - 指数ETF 的 json 数据


Instruction:
Can you generate the documentation for the following Python 3 function
def fundb(self, fields=None, min_volume=0, min_discount=0, forever=False):
        if fields is None:
            fields = []
        # 添加当前的ctime
        self.__fundb_url = self.__fundb_url.format(ctime=int(time.time()))
        # 请求数据
        rep = requests.get(self.__fundb_url)
        # 获取返回的json字符串
        fundbjson = json.loads(rep.text)
        # 格式化返回的json字符串
        data = self.formatfundbjson(fundbjson)
        # 过滤小于指定交易量的数据
        if min_volume:
            data = {
                k: data[k]
                for k in data
                if float(data[k]["fundb_volume"]) > min_volume
            }
        if len(fields):
            data = {
                k: data[k]
                for k in data
                if data[k]["coupon_descr_s"] in "".join(fields)
            }
        if forever:
            data = {
                k: data[k]
                for k in data
                if data[k]["fundb_left_year"].find("永续") != -1
            }
        if min_discount:
            data = {
                k: data[k]
                for k in data
                if float(data[k]["fundb_discount_rt"][:-1]) > min_discount
            }
        self.__fundb = data
        return self.__fundb

Response: Fundb 单位为 0. 0


Instruction:
How would you explain what the following Python 3 function does
def etfindex(
        self, index_id="", min_volume=0, max_discount=None, min_discount=None
    ):
        """
        以字典形式返回 指数ETF 数据
        :param index_id: 获取指定的指数
        :param min_volume: 最小成交量
        :param min_discount: 最低溢价率, 适用于溢价套利, 格式 "-1.2%", "-1.2", -0.012 三种均可
        :param max_discount: 最高溢价率, 适用于折价套利, 格式 "-1.2%", "-1.2", -0.012 三种均可
        :return: {"fund_id":{}}
        """
        # 添加当前的ctime
        self.__etf_index_url = self.__etf_index_url.format(
            ctime=int(time.time())
        )
        # 请求数据
        rep = requests.get(self.__etf_index_url)
        # 获取返回的json字符串, 转化为字典
        etf_json = rep.json()

        # 格式化返回的json字符串
        data = self.formatetfindexjson(etf_json)

        # 过滤
        if index_id:
            # 指定跟踪的指数代码
            data = {
                fund_id: cell
                for fund_id, cell in data.items()
                if cell["index_id"] == index_id
            }
        if min_volume:
            # 过滤小于指定交易量的数据
            data = {
                fund_id: cell
                for fund_id, cell in data.items()
                if float(cell["volume"]) >= min_volume
            }
        if min_discount is not None:
            # 指定最小溢价率
            if isinstance(min_discount, str):
                if min_discount.endswith("%"):
                    # 如果是字符串形式,先转为浮点形式
                    min_discount = self.percentage2float(min_discount)
                else:
                    min_discount = float(min_discount) / 100.
            data = {
                fund_id: cell
                for fund_id, cell in data.items()
                if self.percentage2float(cell["discount_rt"]) >= min_discount
            }
        if max_discount is not None:
            # 指定最大溢价率
            if isinstance(max_discount, str):
                if max_discount.endswith("%"):
                    # 如果是字符串形式,先转为浮点形式
                    max_discount = self.percentage2float(max_discount)
                else:
                    max_discount = float(max_discount) / 100.
            data = {
                fund_id: cell
                for fund_id, cell in data.items()
                if self.percentage2float(cell["discount_rt"]) <= max_discount
            }

        self.__etfindex = data
        return self.__etfindex

Response: Get the etfindex index for the current neccesary set of items


Instruction:
Can you tell what is the following Python 3 function doing
def cb(self, min_volume=0):
        # 添加当前的ctime
        self.__cb_url = self.__cb_url.format(ctime=int(time.time()))
        # 请求数据
        rep = requests.get(self.__cb_url)
        # 获取返回的json字符串
        fundjson = json.loads(rep.text)
        # 格式化返回的json字符串
        data = self.formatjisilujson(fundjson)
        # 过滤小于指定交易量的数据
        if min_volume:
            data = {
                k: data[k]
                for k in data
                if float(data[k]["volume"]) > min_volume
            }

        self.__cb = data
        return self.__cb

Response: get the callback url


Instruction:
Can you generate a brief explanation for the following Python 3 code
def update(self):
        # Had to convert it to string because datetime is not JSON serializable
        self.stats = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        # Add the time zone (issue #1249 and issue #1337)
        if 'tmzone' in localtime():
            self.stats += ' {}'.format(localtime().tm_zone)
        elif len(tzname) > 0:
            self.stats += ' {}'.format(tzname[1])

        return self.stats

Response: Update the current date and time.


Instruction:
Write a Python 3 script for
returning the string to display in the curse interface.

Response:
def msg_curse(self, args=None, max_width=None):
        """Return the string to display in the curse interface."""
        # Init the return message
        ret = []

        # Build the string message
        # 23 is the padding for the process list
        msg = '{:23}'.format(self.stats)
        ret.append(self.curse_add_line(msg))

        return ret


Instruction:
How would you implement a function in Python 3 that
loads the web list from the configuration file.

Response:
def load(self, config):
        """Load the web list from the configuration file."""
        web_list = []

        if config is None:
            logger.debug("No configuration file available. Cannot load ports list.")
        elif not config.has_section(self._section):
            logger.debug("No [%s] section in the configuration file. Cannot load ports list." % self._section)
        else:
            logger.debug("Start reading the [%s] section in the configuration file" % self._section)

            refresh = int(config.get_value(self._section, 'refresh', default=self._default_refresh))
            timeout = int(config.get_value(self._section, 'timeout', default=self._default_timeout))

            # Read the web/url list
            for i in range(1, 256):
                new_web = {}
                postfix = 'web_%s_' % str(i)

                # Read mandatories configuration key: host
                new_web['url'] = config.get_value(self._section, '%s%s' % (postfix, 'url'))
                if new_web['url'] is None:
                    continue
                url_parse = urlparse(new_web['url'])
                if not bool(url_parse.scheme) or not bool(url_parse.netloc):
                    logger.error('Bad URL (%s) in the [%s] section of configuration file.' % (new_web['url'],
                                                                                self._section))
                    continue

                # Read optionals configuration keys
                # Default description is the URL without the http://
                new_web['description'] = config.get_value(self._section,
                                                          '%sdescription' % postfix,
                                                          default="%s" % url_parse.netloc)

                # Default status
                new_web['status'] = None
                new_web['elapsed'] = 0

                # Refresh rate in second
                new_web['refresh'] = refresh

                # Timeout in second
                new_web['timeout'] = int(config.get_value(self._section,
                                                          '%stimeout' % postfix,
                                                          default=timeout))

                # RTT warning
                new_web['rtt_warning'] = config.get_value(self._section,
                                                          '%srtt_warning' % postfix,
                                                          default=None)
                if new_web['rtt_warning'] is not None:
                    # Convert to second
                    new_web['rtt_warning'] = int(new_web['rtt_warning']) / 1000.0

                # Indice
                new_web['indice'] = 'web_' + str(i)

                # ssl_verify
                new_web['ssl_verify'] = config.get_value(self._section,
                                                        '%sssl_verify' % postfix,
                                                         default=True)
                # Proxy
                http_proxy = config.get_value(self._section,
                                                '%shttp_proxy' % postfix,
                                                default=None)

                https_proxy = config.get_value(self._section,
                                                '%shttps_proxy' % postfix,
                                                default=None)

                if https_proxy is None and http_proxy is None:
                    new_web['proxies'] = None
                else:
                    new_web['proxies'] = {'http' : http_proxy,
                                          'https' : https_proxy }

                # Add the server to the list
                logger.debug("Add Web URL %s to the static list" % new_web['url'])
                web_list.append(new_web)

            # Ports list loaded
            logger.debug("Web list loaded: %s" % web_list)

        return web_list


Instruction:
Implement a function in Python 3 to
set the key to the value for the pos

Response:
def set_server(self, pos, key, value):
        """Set the key to the value for the pos (position in the list)."""
        self._web_list[pos][key] = value


Instruction:
Can you create a Python 3 function that
updates sensors stats using the input method.

Response:
def update(self):
        """Update sensors stats using the input method."""
        # Init new stats
        stats = self.get_init_value()

        if self.input_method == 'local':
            # Update stats using the dedicated lib
            stats = []
            # Get the temperature
            try:
                temperature = self.__set_type(self.glancesgrabsensors.get('temperature_core'),
                                              'temperature_core')
            except Exception as e:
                logger.error("Cannot grab sensors temperatures (%s)" % e)
            else:
                # Append temperature
                stats.extend(temperature)
            # Get the FAN speed
            try:
                fan_speed = self.__set_type(self.glancesgrabsensors.get('fan_speed'),
                                            'fan_speed')
            except Exception as e:
                logger.error("Cannot grab FAN speed (%s)" % e)
            else:
                # Append FAN speed
                stats.extend(fan_speed)
            # Update HDDtemp stats
            try:
                hddtemp = self.__set_type(self.hddtemp_plugin.update(),
                                          'temperature_hdd')
            except Exception as e:
                logger.error("Cannot grab HDD temperature (%s)" % e)
            else:
                # Append HDD temperature
                stats.extend(hddtemp)
            # Update batteries stats
            try:
                batpercent = self.__set_type(self.batpercent_plugin.update(),
                                             'battery')
            except Exception as e:
                logger.error("Cannot grab battery percent (%s)" % e)
            else:
                # Append Batteries %
                stats.extend(batpercent)

        elif self.input_method == 'snmp':
            # Update stats using SNMP
            # No standard:
            # http://www.net-snmp.org/wiki/index.php/Net-SNMP_and_lm-sensors_on_Ubuntu_10.04

            pass

        # Set the alias for each stat
        for stat in stats:
            alias = self.has_alias(stat["label"].lower())
            if alias:
                stat["label"] = alias

        # Update the stats
        self.stats = stats

        return self.stats


Instruction:
Explain what the following Python 3 code does
def __set_type(self, stats, sensor_type):
        for i in stats:
            # Set the sensors type
            i.update({'type': sensor_type})
            # also add the key name
            i.update({'key': self.get_key()})

        return stats

Response: Set the type of sensors in the plugin.


Instruction:
Write a Python 3 function that can
return the dict to display in the curse interface.

Response:
def msg_curse(self, args=None, max_width=None):
        """Return the dict to display in the curse interface."""
        # Init the return message
        ret = []

        # Only process if stats exist and display plugin enable...
        if not self.stats or self.is_disable():
            return ret

        # Max size for the interface name
        name_max_width = max_width - 12

        # Header
        msg = '{:{width}}'.format('SENSORS', width=name_max_width)
        ret.append(self.curse_add_line(msg, "TITLE"))

        # Stats
        for i in self.stats:
            # Do not display anything if no battery are detected
            if i['type'] == 'battery' and i['value'] == []:
                continue
            # New line
            ret.append(self.curse_new_line())
            msg = '{:{width}}'.format(i["label"][:name_max_width],
                                      width=name_max_width)
            ret.append(self.curse_add_line(msg))
            if i['value'] in (b'ERR', b'SLP', b'UNK', b'NOS'):
                msg = '{:>13}'.format(i['value'])
                ret.append(self.curse_add_line(
                    msg, self.get_views(item=i[self.get_key()],
                                        key='value',
                                        option='decoration')))
            else:
                if (args.fahrenheit and i['type'] != 'battery' and
                        i['type'] != 'fan_speed'):
                    value = to_fahrenheit(i['value'])
                    unit = 'F'
                else:
                    value = i['value']
                    unit = i['unit']
                try:
                    msg = '{:>13.0f}{}'.format(value, unit)
                    ret.append(self.curse_add_line(
                        msg, self.get_views(item=i[self.get_key()],
                                            key='value',
                                            option='decoration')))
                except (TypeError, ValueError):
                    pass

        return ret


Instruction:
Create a Python 3 function to
build the sensors list depending of the type.

Response:
def build_sensors_list(self, type):
        """Build the sensors list depending of the type.

        type: SENSOR_TEMP_UNIT or SENSOR_FAN_UNIT

        output: a list
        """
        ret = []
        if type == SENSOR_TEMP_UNIT and self.init_temp:
            input_list = self.stemps
            self.stemps = psutil.sensors_temperatures()
        elif type == SENSOR_FAN_UNIT and self.init_fan:
            input_list = self.sfans
            self.sfans = psutil.sensors_fans()
        else:
            return ret
        for chipname, chip in iteritems(input_list):
            i = 1
            for feature in chip:
                sensors_current = {}
                # Sensor name
                if feature.label == '':
                    sensors_current['label'] = chipname + ' ' + str(i)
                else:
                    sensors_current['label'] = feature.label
                # Fan speed and unit
                sensors_current['value'] = int(feature.current)
                sensors_current['unit'] = type
                # Add sensor to the list
                ret.append(sensors_current)
                i += 1
        return ret


Instruction:
Can you implement a function in Python 3 that
adds a user to the dictionary.

Response:
def add_user(self, username, password):
        """Add an user to the dictionary."""
        self.server.user_dict[username] = password
        self.server.isAuth = True


Instruction:
Can you tell what is the following Python 3 function doing
def serve_forever(self):
        # Set the server login/password (if -P/--password tag)
        if self.args.password != "":
            self.add_user(self.args.username, self.args.password)
        # Serve forever
        self.server.serve_forever()

Response: Call the main loop.


Instruction:
Given the following Python 3 function, write the documentation
def end(self):
        if not self.args.disable_autodiscover:
            self.autodiscover_client.close()
        self.server.end()

Response: End of the Glances server session.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get(self, stat_name=None):
        if stat_name is None:
            return self._thresholds

        if stat_name in self._thresholds:
            return self._thresholds[stat_name]
        else:
            return {}

Response: Return the threshold dict.


Instruction:
Can you implement a function in Python 3 that
adds a new threshold to the dict

Response:
def add(self, stat_name, threshold_description):
        """Add a new threshold to the dict (key = stat_name)"""
        if threshold_description not in self.threshold_list:
            return False
        else:
            self._thresholds[stat_name] = getattr(self.current_module,
                                                  'GlancesThreshold' + threshold_description.capitalize())()
            return True


Instruction:
Here you have a function in Python 3, explain what it does
def init(self):
        if not self.export_enable:
            return None
        try:
            parameters = pika.URLParameters(
                'amqp://' + self.user +
                ':' + self.password +
                '@' + self.host +
                ':' + self.port + '/')
            connection = pika.BlockingConnection(parameters)
            channel = connection.channel()
            return channel
        except Exception as e:
            logger.critical("Connection to rabbitMQ failed : %s " % e)
            return None

Response: Init the connection to the rabbitmq server.


Instruction:
How would you code a function in Python 3 to
write the points in RabbitMQ.

Response:
def export(self, name, columns, points):
        """Write the points in RabbitMQ."""
        data = ('hostname=' + self.hostname + ', name=' + name +
                ', dateinfo=' + datetime.datetime.utcnow().isoformat())
        for i in range(len(columns)):
            if not isinstance(points[i], Number):
                continue
            else:
                data += ", " + columns[i] + "=" + str(points[i])
        logger.debug(data)
        try:
            self.client.basic_publish(exchange='', routing_key=self.queue, body=data)
        except Exception as e:
            logger.error("Can not export stats to RabbitMQ (%s)" % e)


Instruction:
Implement a Python 3 function for
normalizing a name for the Statsd convention

Response:
def normalize(name):
    """Normalize name for the Statsd convention"""

    # Name should not contain some specials chars (issue #1068)
    ret = name.replace(':', '')
    ret = ret.replace('%', '')
    ret = ret.replace(' ', '_')

    return ret


Instruction:
Make a summary of the following Python 3 code
def init(self):
        if not self.export_enable:
            return None
        logger.info(
            "Stats will be exported to StatsD server: {}:{}".format(self.host,
                                                                    self.port))
        return StatsClient(self.host,
                           int(self.port),
                           prefix=self.prefix)

Response: Initialize the connection to the Statsd server.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def export(self, name, columns, points):
        for i in range(len(columns)):
            if not isinstance(points[i], Number):
                continue
            stat_name = '{}.{}'.format(name, columns[i])
            stat_value = points[i]
            try:
                self.client.gauge(normalize(stat_name),
                                  stat_value)
            except Exception as e:
                logger.error("Can not export stats to Statsd (%s)" % e)
        logger.debug("Export {} stats to Statsd".format(name))

Response: Export the stats to the Statsd server.


Instruction:
Make a summary of the following Python 3 code
def load(self, config):
        ports_list = []

        if config is None:
            logger.debug("No configuration file available. Cannot load ports list.")
        elif not config.has_section(self._section):
            logger.debug("No [%s] section in the configuration file. Cannot load ports list." % self._section)
        else:
            logger.debug("Start reading the [%s] section in the configuration file" % self._section)

            refresh = int(config.get_value(self._section, 'refresh', default=self._default_refresh))
            timeout = int(config.get_value(self._section, 'timeout', default=self._default_timeout))

            # Add default gateway on top of the ports_list lits
            default_gateway = config.get_value(self._section, 'port_default_gateway', default='False')
            if default_gateway.lower().startswith('true') and netifaces_tag:
                new_port = {}
                try:
                    new_port['host'] = netifaces.gateways()['default'][netifaces.AF_INET][0]
                except KeyError:
                    new_port['host'] = None
                # ICMP
                new_port['port'] = 0
                new_port['description'] = 'DefaultGateway'
                new_port['refresh'] = refresh
                new_port['timeout'] = timeout
                new_port['status'] = None
                new_port['rtt_warning'] = None
                new_port['indice'] = str('port_0')
                logger.debug("Add default gateway %s to the static list" % (new_port['host']))
                ports_list.append(new_port)

            # Read the scan list
            for i in range(1, 256):
                new_port = {}
                postfix = 'port_%s_' % str(i)

                # Read mandatories configuration key: host
                new_port['host'] = config.get_value(self._section, '%s%s' % (postfix, 'host'))

                if new_port['host'] is None:
                    continue

                # Read optionals configuration keys
                # Port is set to 0 by default. 0 mean ICMP check instead of TCP check
                new_port['port'] = config.get_value(self._section,
                                                    '%s%s' % (postfix, 'port'),
                                                    0)
                new_port['description'] = config.get_value(self._section,
                                                           '%sdescription' % postfix,
                                                           default="%s:%s" % (new_port['host'], new_port['port']))

                # Default status
                new_port['status'] = None

                # Refresh rate in second
                new_port['refresh'] = refresh

                # Timeout in second
                new_port['timeout'] = int(config.get_value(self._section,
                                                           '%stimeout' % postfix,
                                                           default=timeout))

                # RTT warning
                new_port['rtt_warning'] = config.get_value(self._section,
                                                           '%srtt_warning' % postfix,
                                                           default=None)
                if new_port['rtt_warning'] is not None:
                    # Convert to second
                    new_port['rtt_warning'] = int(new_port['rtt_warning']) / 1000.0

                # Indice
                new_port['indice'] = 'port_' + str(i)

                # Add the server to the list
                logger.debug("Add port %s:%s to the static list" % (new_port['host'], new_port['port']))
                ports_list.append(new_port)

            # Ports list loaded
            logger.debug("Ports list loaded: %s" % ports_list)

        return ports_list

Response: Load the ports list from the configuration file.


Instruction:
Write a Python 3 function for
setting the key to the value for the pos

Response:
def set_server(self, pos, key, value):
        """Set the key to the value for the pos (position in the list)."""
        self._ports_list[pos][key] = value


Instruction:
Given the following Python 3 function, write the documentation
def init(self):
        if not self.export_enable:
            return None

        try:
            db = potsdb.Client(self.host,
                               port=int(self.port),
                               check_host=True)
        except Exception as e:
            logger.critical("Cannot connect to OpenTSDB server %s:%s (%s)" % (self.host, self.port, e))
            sys.exit(2)

        return db

Response: Init the connection to the OpenTSDB server.


Instruction:
Create a Python 3 function to
export the stats to the Statsd server.

Response:
def export(self, name, columns, points):
        """Export the stats to the Statsd server."""
        for i in range(len(columns)):
            if not isinstance(points[i], Number):
                continue
            stat_name = '{}.{}.{}'.format(self.prefix, name, columns[i])
            stat_value = points[i]
            tags = self.parse_tags(self.tags)
            try:
                self.client.send(stat_name, stat_value, **tags)
            except Exception as e:
                logger.error("Can not export stats %s to OpenTSDB (%s)" % (name, e))
        logger.debug("Export {} stats to OpenTSDB".format(name))