<commit_before>#
# Author    : Manuel Bernal Llinares
# Project   : trackhub-creator
# Timestamp : 07-09-2017 11:24
# ---
# © 2017 Manuel Bernal Llinares <mbdebian@gmail.com>
# All rights reserved.
#

"""
This pipeline creates a trackhub for a PRIDE project, based on the information provided via a JSON formatted file, as it
can be seen on this sample:
{
  "trackHubName" : "PXD000625",
  "trackHubShortLabel" : "PXD000625 - Hepatoc...",
  "trackHubLongLabel" : "Experimental design For the label-free ...",
  "trackHubType" : "PROTEOMICS",
  "trackHubEmail" : "pride-support@ebi.ac.uk",
  "trackHubInternalAbsolutePath" : "...",
  "trackMaps" : [ {
    "trackName" : "PXD000625_10090_Original",
    "trackShortLabel" : "PXD000625 - Mus musc...",
    "trackLongLabel" : "Experimental design For the label-free proteome analysis 17 mice were used composed of 5 ...",
    "trackSpecie" : "10090",
    "pogoFile" : "..."
  } ]
}
"""

import os
import time
# App imports
import config_manager
import ensembl.service
import toolbox.general as general_toolbox
from pipelines.template_pipeline import PogoBasedPipelineDirector, DirectorConfigurationManager

# Globals
__configuration_file = None
__pipeline_arguments = None
__pipeline_director = None

# Pipeline properties access
def set_configuration_file(config_file):
    global __configuration_file
    if __configuration_file is None:
        __configuration_file = config_file
    return __configuration_file

def set_pipeline_arguments(pipeline_arguments):
    global __pipeline_arguments
    if __pipeline_arguments is None:
        __pipeline_arguments = pipeline_arguments
    return __pipeline_arguments

def get_pipeline_director():
    global __pipeline_director
    if __pipeline_director is None:
        __pipeline_director = TrackhubCreatorForProject(config_manager.read_config_from_file(__configuration_file),
                                                        __configuration_file,
                                                        __pipeline_arguments)
    return __pipeline_director

class ConfigManager(DirectorConfigurationManager):
    # Command Line Arguments for this pipeline look like
    #   # This is a JSON formatted file that contains all the relevant information needed for processing the project
    #   # data and create its trackhub
    #   project_data_file=project_data.json

    # Command Line Argument keys
    _CONFIG_COMMAND_LINE_ARGUMENT_KEY_PROJECT_DATA_FILE = 'project_data_file'

    def __init__(self, configuration_object, configuration_file, pipeline_arguments):
        super(ConfigManager, self).__init__(configuration_object, configuration_file, pipeline_arguments)
        # Lazy Process command line arguments
        self.__pipeline_arguments_object = None
        self.__running_mode = None

    def get_project_data_file_path(self):
        return self._get_value_for_pipeline_argument_key(self._CONFIG_COMMAND_LINE_ARGUMENT_KEY_PROJECT_DATA_FILE)

# Models for dealing with the data file that describes the project
class ProjectTrackDescriptor:
    # Project Data File keys relative to every TrackMap object
    _PROJECT_DATA_FILE_KEY_TRACK_NAME = 'trackName'
    _PROJECT_DATA_FILE_KEY_TRACK_SHORT_LABEL = 'trackShortLabel'
    _PROJECT_DATA_FILE_KEY_TRACK_LONG_LABEL = 'trackLongLabel'
    _PROJECT_DATA_FILE_KEY_TRACK_SPECIES = 'trackSpecie'
    _PROJECT_DATA_FILE_KEY_TRACK_POGO_FILE_PATH = 'pogoFile'

    def __init__(self, project_track_descriptor_object):
        self.__project_track_descriptor_object = project_track_descriptor_object

    def _get_value_for_key(self, key, default=""):
        if self.__project_track_descriptor_object and (key in self.__project_track_descriptor_object):
            return self.__project_track_descriptor_object[key]
        return default

    def get_track_name(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACK_NAME)

    def get_track_short_label(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACK_SHORT_LABEL)

    def get_track_long_label(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACK_LONG_LABEL)

    def get_track_species(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACK_SPECIES)

    def get_track_file_path_pogo(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACK_POGO_FILE_PATH)

class ProjectTrackhubDescriptor:
    # Project Data File keys
    _PROJECT_DATA_FILE_KEY_TRACKHUB_NAME = 'trackHubName'
    _PROJECT_DATA_FILE_KEY_TRACKHUB_SHORT_LABEL = 'trackHubShortLabel'
    _PROJECT_DATA_FILE_KEY_TRACKHUB_LONG_LABEL = 'trackHubLongLabel'
    _PROJECT_DATA_FILE_KEY_TRACKHUB_HUB_TYPE = 'trackHubType'
    _PROJECT_DATA_FILE_KEY_TRACKHUB_EMAIL = 'trackHubEmail'
    _PROJECT_DATA_FILE_KEY_TRACKHUB_INTERNAL_ABSOLUTE_PATH = 'trackHubInternalAbsolutePath'
    _PROJECT_DATA_FILE_KEY_TRACKHUB_SECTION_TRACKMAPS = 'trackMaps'

    def __init__(self, project_data_file_path):
        self.__project_data_file_path = project_data_file_path
        self.__project_data_object = None
        self.__project_tracks_descriptors = None

    def _get_project_data_object(self):
        if not self.__project_data_object:
            self.__project_data_object = general_toolbox.read_json(self.__project_data_file_path)
        return self.__project_data_object

    def _get_value_for_key(self, key, default=""):
        # TODO - I should start thinking about refactoring this out
        if key in self._get_project_data_object():
            return self._get_project_data_object()[key]
        return default

    def get_trackhub_name(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACKHUB_NAME,
                                       os.path.basename(self.__project_data_file_path))

    def get_trackhub_short_label(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACKHUB_SHORT_LABEL,
                                       "--- NO SHORT LABEL HAS BEEN DEFINED FOR THIS TRACKHUB ---")

    def get_trackhub_long_label(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACKHUB_LONG_LABEL,
                                       "--- NO LONG LABEL HAS BEEN DEFINED FOR THIS TRACKHUB ---")

    def get_trackhub_hub_type(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACKHUB_HUB_TYPE,
                                       "PROTEOMICS")

    def get_trackhub_email(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACKHUB_EMAIL,
                                       "pride-support@ebi.ac.uk")

    def get_trackhub_destination_path(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACKHUB_INTERNAL_ABSOLUTE_PATH)

    def get_trackhub_project_defined_tracks(self):
        if not self.__project_tracks_descriptors:
            # Default value is an empty list of tracks
            self.__project_tracks_descriptors = []
            data_file_project_track_description_objects = \
                self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACKHUB_SECTION_TRACKMAPS)
            if data_file_project_track_description_objects:
                self.__project_tracks_descriptors = \
                    [ProjectTrackDescriptor(data_file_project_track_description_object)
                     for data_file_project_track_description_object
                     in data_file_project_track_description_objects]
        return self.__project_tracks_descriptors

class PipelineResult:
    # TODO
    _VALUE_STATUS_SUCCESS = 'success'
    _VALUE_STATUS_ERROR = 'error'

    def __init__(self):
        self.status = self._VALUE_STATUS_SUCCESS
        self.error_messages = []
        self.success_messages = []
        self.hub_descriptor_file_path = ""

    def set_status_error(self):
        self.status = self._VALUE_STATUS_ERROR

    def add_error_message(self, error_message):
        # This is the report on the final result from running the pipeline
        self.set_status_error()
        self.error_messages.append(error_message)

class TrackhubCreatorForProject(PogoBasedPipelineDirector):
    # TODO
    def __init__(self, configuration_object, configuration_file, pipeline_arguments):
        runner_id = "{}-{}".format(__name__, time.time())
        super(TrackhubCreatorForProject, self).__init__(runner_id)
        self.__config_manager = ConfigManager(configuration_object, configuration_file, pipeline_arguments)
        self.__project_trackhub_descriptor = None
        # Only the valid project tracks will be processed for being included in the trackhub
        self.__valid_project_tracks = None
        # Pipeline result object
        self.__pipeline_result_object = PipelineResult()

    def __get_valid_project_tracks(self):
        """
        This helper creates a list of valid trackhub tracks from the given project, i.e. tracks that meet this cirteria:
            - Its taxonomy ID is available on Ensembl
        :return: a list of valid trackhub tracks for the given project
        """
        if not self.__valid_project_tracks:
            self.__valid_project_tracks = []
            ensembl_service = ensembl.service.get_service()
            for project_track_descriptor in self.__project_trackhub_descriptor.get_trackhub_project_defined_tracks():
                if ensembl_service.get_species_data_service().get_species_entry_for_taxonomy_id(
                        project_track_descriptor.get_track_species()):
                    self.__valid_project_tracks.append(project_track_descriptor)
        return self.__valid_project_tracks

    def _before(self):
        if self.__config_manager.get_project_data_file_path():
            self._get_logger().info("Reading Project Trackhub Descriptor from file at '{}'"
                                    .format(self.__config_manager.get_project_data_file_path()))
            self.__project_trackhub_descriptor = \
                ProjectTrackhubDescriptor(self.__config_manager.get_project_data_file_path())
            # Check that the destination folder exists
            if not os.path.isdir(self.__project_trackhub_descriptor.get_trackhub_destination_path()):
                self._get_logger().error("Trackhub destination path NOT VALID, '{}'"
                                         .format(self.__project_trackhub_descriptor.get_trackhub_destination_path()))
                return False
            # TODO - Check valid project tracks
            if not self.__get_valid_project_tracks():
                # TODO
                pass
            return True
        self._get_logger().error("INVALID / MISSING Project Trackhub Descriptor file, '{}'"
                                 .format(self.__config_manager.get_project_data_file_path()))
        return False

    def _after(self):
        # TODO - Export to file the pipeline result object
        pass

if __name__ == '__main__':
    print("ERROR: This script is part of a pipeline collection and it is not meant to be run in stand alone mode")
<commit_msg>add_success_message<commit_after>#
# Author    : Manuel Bernal Llinares
# Project   : trackhub-creator
# Timestamp : 07-09-2017 11:24
# ---
# © 2017 Manuel Bernal Llinares <mbdebian@gmail.com>
# All rights reserved.
#

"""
This pipeline creates a trackhub for a PRIDE project, based on the information provided via a JSON formatted file, as it
can be seen on this sample:
{
  "trackHubName" : "PXD000625",
  "trackHubShortLabel" : "PXD000625 - Hepatoc...",
  "trackHubLongLabel" : "Experimental design For the label-free ...",
  "trackHubType" : "PROTEOMICS",
  "trackHubEmail" : "pride-support@ebi.ac.uk",
  "trackHubInternalAbsolutePath" : "...",
  "trackMaps" : [ {
    "trackName" : "PXD000625_10090_Original",
    "trackShortLabel" : "PXD000625 - Mus musc...",
    "trackLongLabel" : "Experimental design For the label-free proteome analysis 17 mice were used composed of 5 ...",
    "trackSpecie" : "10090",
    "pogoFile" : "..."
  } ]
}
"""

import os
import time
# App imports
import config_manager
import ensembl.service
import toolbox.general as general_toolbox
from pipelines.template_pipeline import PogoBasedPipelineDirector, DirectorConfigurationManager

# Globals
__configuration_file = None
__pipeline_arguments = None
__pipeline_director = None

# Pipeline properties access
def set_configuration_file(config_file):
    global __configuration_file
    if __configuration_file is None:
        __configuration_file = config_file
    return __configuration_file

def set_pipeline_arguments(pipeline_arguments):
    global __pipeline_arguments
    if __pipeline_arguments is None:
        __pipeline_arguments = pipeline_arguments
    return __pipeline_arguments

def get_pipeline_director():
    global __pipeline_director
    if __pipeline_director is None:
        __pipeline_director = TrackhubCreatorForProject(config_manager.read_config_from_file(__configuration_file),
                                                        __configuration_file,
                                                        __pipeline_arguments)
    return __pipeline_director

class ConfigManager(DirectorConfigurationManager):
    # Command Line Arguments for this pipeline look like
    #   # This is a JSON formatted file that contains all the relevant information needed for processing the project
    #   # data and create its trackhub
    #   project_data_file=project_data.json

    # Command Line Argument keys
    _CONFIG_COMMAND_LINE_ARGUMENT_KEY_PROJECT_DATA_FILE = 'project_data_file'

    def __init__(self, configuration_object, configuration_file, pipeline_arguments):
        super(ConfigManager, self).__init__(configuration_object, configuration_file, pipeline_arguments)
        # Lazy Process command line arguments
        self.__pipeline_arguments_object = None
        self.__running_mode = None

    def get_project_data_file_path(self):
        return self._get_value_for_pipeline_argument_key(self._CONFIG_COMMAND_LINE_ARGUMENT_KEY_PROJECT_DATA_FILE)

# Models for dealing with the data file that describes the project
class ProjectTrackDescriptor:
    # Project Data File keys relative to every TrackMap object
    _PROJECT_DATA_FILE_KEY_TRACK_NAME = 'trackName'
    _PROJECT_DATA_FILE_KEY_TRACK_SHORT_LABEL = 'trackShortLabel'
    _PROJECT_DATA_FILE_KEY_TRACK_LONG_LABEL = 'trackLongLabel'
    _PROJECT_DATA_FILE_KEY_TRACK_SPECIES = 'trackSpecie'
    _PROJECT_DATA_FILE_KEY_TRACK_POGO_FILE_PATH = 'pogoFile'

    def __init__(self, project_track_descriptor_object):
        self.__project_track_descriptor_object = project_track_descriptor_object

    def _get_value_for_key(self, key, default=""):
        if self.__project_track_descriptor_object and (key in self.__project_track_descriptor_object):
            return self.__project_track_descriptor_object[key]
        return default

    def get_track_name(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACK_NAME)

    def get_track_short_label(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACK_SHORT_LABEL)

    def get_track_long_label(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACK_LONG_LABEL)

    def get_track_species(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACK_SPECIES)

    def get_track_file_path_pogo(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACK_POGO_FILE_PATH)

class ProjectTrackhubDescriptor:
    # Project Data File keys
    _PROJECT_DATA_FILE_KEY_TRACKHUB_NAME = 'trackHubName'
    _PROJECT_DATA_FILE_KEY_TRACKHUB_SHORT_LABEL = 'trackHubShortLabel'
    _PROJECT_DATA_FILE_KEY_TRACKHUB_LONG_LABEL = 'trackHubLongLabel'
    _PROJECT_DATA_FILE_KEY_TRACKHUB_HUB_TYPE = 'trackHubType'
    _PROJECT_DATA_FILE_KEY_TRACKHUB_EMAIL = 'trackHubEmail'
    _PROJECT_DATA_FILE_KEY_TRACKHUB_INTERNAL_ABSOLUTE_PATH = 'trackHubInternalAbsolutePath'
    _PROJECT_DATA_FILE_KEY_TRACKHUB_SECTION_TRACKMAPS = 'trackMaps'

    def __init__(self, project_data_file_path):
        self.__project_data_file_path = project_data_file_path
        self.__project_data_object = None
        self.__project_tracks_descriptors = None

    def _get_project_data_object(self):
        if not self.__project_data_object:
            self.__project_data_object = general_toolbox.read_json(self.__project_data_file_path)
        return self.__project_data_object

    def _get_value_for_key(self, key, default=""):
        # TODO - I should start thinking about refactoring this out
        if key in self._get_project_data_object():
            return self._get_project_data_object()[key]
        return default

    def get_trackhub_name(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACKHUB_NAME,
                                       os.path.basename(self.__project_data_file_path))

    def get_trackhub_short_label(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACKHUB_SHORT_LABEL,
                                       "--- NO SHORT LABEL HAS BEEN DEFINED FOR THIS TRACKHUB ---")

    def get_trackhub_long_label(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACKHUB_LONG_LABEL,
                                       "--- NO LONG LABEL HAS BEEN DEFINED FOR THIS TRACKHUB ---")

    def get_trackhub_hub_type(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACKHUB_HUB_TYPE,
                                       "PROTEOMICS")

    def get_trackhub_email(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACKHUB_EMAIL,
                                       "pride-support@ebi.ac.uk")

    def get_trackhub_destination_path(self):
        return self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACKHUB_INTERNAL_ABSOLUTE_PATH)

    def get_trackhub_project_defined_tracks(self):
        if not self.__project_tracks_descriptors:
            # Default value is an empty list of tracks
            self.__project_tracks_descriptors = []
            data_file_project_track_description_objects = \
                self._get_value_for_key(self._PROJECT_DATA_FILE_KEY_TRACKHUB_SECTION_TRACKMAPS)
            if data_file_project_track_description_objects:
                self.__project_tracks_descriptors = \
                    [ProjectTrackDescriptor(data_file_project_track_description_object)
                     for data_file_project_track_description_object
                     in data_file_project_track_description_objects]
        return self.__project_tracks_descriptors

class PipelineResult:
    # TODO
    _VALUE_STATUS_SUCCESS = 'success'
    _VALUE_STATUS_ERROR = 'error'

    def __init__(self):
        self.status = self._VALUE_STATUS_SUCCESS
        self.error_messages = []
        self.success_messages = []
        self.hub_descriptor_file_path = ""

    def set_status_error(self):
        self.status = self._VALUE_STATUS_ERROR

    def add_error_message(self, error_message):
        # This is the report on the final result from running the pipeline
        self.set_status_error()
        self.error_messages.append(error_message)

    def add_success_message(self, success_message):
        self.success_messages.append(success_message)

class TrackhubCreatorForProject(PogoBasedPipelineDirector):
    # TODO
    def __init__(self, configuration_object, configuration_file, pipeline_arguments):
        runner_id = "{}-{}".format(__name__, time.time())
        super(TrackhubCreatorForProject, self).__init__(runner_id)
        self.__config_manager = ConfigManager(configuration_object, configuration_file, pipeline_arguments)
        self.__project_trackhub_descriptor = None
        # Only the valid project tracks will be processed for being included in the trackhub
        self.__valid_project_tracks = None
        # Pipeline result object
        self.__pipeline_result_object = PipelineResult()

    def __get_valid_project_tracks(self):
        """
        This helper creates a list of valid trackhub tracks from the given project, i.e. tracks that meet this cirteria:
            - Its taxonomy ID is available on Ensembl
        :return: a list of valid trackhub tracks for the given project
        """
        if not self.__valid_project_tracks:
            self.__valid_project_tracks = []
            ensembl_service = ensembl.service.get_service()
            for project_track_descriptor in self.__project_trackhub_descriptor.get_trackhub_project_defined_tracks():
                if ensembl_service.get_species_data_service().get_species_entry_for_taxonomy_id(
                        project_track_descriptor.get_track_species()):
                    self.__valid_project_tracks.append(project_track_descriptor)
        return self.__valid_project_tracks

    def _before(self):
        if self.__config_manager.get_project_data_file_path():
            self._get_logger().info("Reading Project Trackhub Descriptor from file at '{}'"
                                    .format(self.__config_manager.get_project_data_file_path()))
            self.__project_trackhub_descriptor = \
                ProjectTrackhubDescriptor(self.__config_manager.get_project_data_file_path())
            # Check that the destination folder exists
            if not os.path.isdir(self.__project_trackhub_descriptor.get_trackhub_destination_path()):
                self._get_logger().error("Trackhub destination path NOT VALID, '{}'"
                                         .format(self.__project_trackhub_descriptor.get_trackhub_destination_path()))
                return False
            # TODO - Check valid project tracks
            if not self.__get_valid_project_tracks():
                # TODO
                pass
            return True
        self._get_logger().error("INVALID / MISSING Project Trackhub Descriptor file, '{}'"
                                 .format(self.__config_manager.get_project_data_file_path()))
        return False

    def _after(self):
        # TODO - Export to file the pipeline result object
        pass

if __name__ == '__main__':
    print("ERROR: This script is part of a pipeline collection and it is not meant to be run in stand alone mode")
<|endoftext|>


<commit_before># -------------------------------------------------------------------------------
# Copyright IBM Corp. 2018
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# -------------------------------------------------------------------------------
import warnings
import inspect
import sys
import argparse
from pixiedust.display.app import *
from pixiedust.utils import Logger
from pixiedust.utils.astParse import get_matches_lineno
from six import iteritems
from IPython.core.magic import (Magics, magics_class, line_cell_magic)
from IPython.core.getipython import get_ipython

@magics_class
class PixiedustDebuggerMagics(Magics):
    def __init__(self, shell):
        super(PixiedustDebuggerMagics,self).__init__(shell=shell)

    @line_cell_magic
    def pixie_debugger(self, line, cell=None):
        args = None
        if line is not None:
            parser = argparse.ArgumentParser(description='PixieDebugger options')
            parser.add_argument('-b', '--breakpoints', nargs='*', help='set breakpoints')
            args = parser.parse_args(line.split())
        PixieDebugger().run({
            "breakpoints": args.breakpoints if args is not None else [],
            "code": cell
        })

try:
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        get_ipython().register_magics(PixiedustDebuggerMagics)
except NameError:
    #IPython not available we must be in a spark executor
    pass

class NoTraceback(Exception):
    "Marker exception for signaling that no traceback was found"
    pass

@PixieApp
@Logger()
class PixieDebugger():
    def initialize(self):
        self.is_post_mortem = False
        self.code =  ""
        self.breakpoints = []
        self.is_post_mortem = self.pixieapp_entity is None or self.pixieapp_entity["code"] is None
        if self.is_post_mortem:
            if sys.last_traceback is None:
                raise NoTraceback()
            if self.options.get("debug_route", "false" ) == "true":
                stack = [tb.function for tb in inspect.getinnerframes(sys.last_traceback)]
                method_name = stack[-1]
                for method in reversed(stack):
                    code = self.parent_pixieapp.exceptions.get(method, None)
                    if code:
                        break
                self.pixieapp_entity = {
                    "breakpoints": ["{}.{}".format(self.parent_pixieapp.__pixieapp_class_name__, method_name)],
                    "code": code or ""
                }
                self.debug("Invoking PixieDebugger for route with {}".format(self.pixieapp_entity))
                self.is_post_mortem = False

        if not self.is_post_mortem:
            self.code = self.renderTemplateString("""
def pixie_run():
    import pdb
    pdb.set_trace()
{{this.pixieapp_entity["code"]|indent(4, indentfirst=True)}}
pixie_run()
        """.strip())
            bps_lines = set()
            bps_fns = set()
            for breakpoint in self.pixieapp_entity["breakpoints"] or []:
                try:
                    bps_lines.add( int(breakpoint))
                except ValueError:
                    matches = get_matches_lineno(self.code, breakpoint)
                    if len(matches) == 0:
                        bps_fns.add(breakpoint)
                    else:
                        for match in matches:
                            bps_lines.add(match)
            self.breakpoints = list(sorted(bps_lines)) + list(sorted(bps_fns))
        else:
            self.code="""
import pdb
pdb.pm()
            """

    @property
    def pm_prefix(self):
        return "$$" if self.is_post_mortem else ""

    @route()
    def main_screen(self):
        self.initialize()
        return self.env.getTemplate("mainScreen.html")

    @route(done="*")
    def done_screen(self):
        return "
Thank you for using PixieDust Debugger
"
<commit_msg>Fail gracefully when PixieDebugger is invoked postmortem with no traceback available<commit_after># -------------------------------------------------------------------------------
# Copyright IBM Corp. 2018
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# -------------------------------------------------------------------------------
import warnings
import inspect
import sys
import argparse
from pixiedust.display.app import *
from pixiedust.utils import Logger
from pixiedust.utils.astParse import get_matches_lineno
from six import iteritems
from IPython.core.magic import (Magics, magics_class, line_cell_magic)
from IPython.core.getipython import get_ipython

@magics_class
class PixiedustDebuggerMagics(Magics):
    def __init__(self, shell):
        super(PixiedustDebuggerMagics,self).__init__(shell=shell)

    @line_cell_magic
    def pixie_debugger(self, line, cell=None):
        args = None
        if line is not None:
            parser = argparse.ArgumentParser(description='PixieDebugger options')
            parser.add_argument('-b', '--breakpoints', nargs='*', help='set breakpoints')
            args = parser.parse_args(line.split())
        PixieDebugger().run({
            "breakpoints": args.breakpoints if args is not None else [],
            "code": cell
        })

try:
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        get_ipython().register_magics(PixiedustDebuggerMagics)
except NameError:
    #IPython not available we must be in a spark executor
    pass

class NoTraceback(Exception):
    "Marker exception for signaling that no traceback was found"
    pass

@PixieApp
@Logger()
class PixieDebugger():
    def initialize(self):
        self.is_post_mortem = False
        self.code =  ""
        self.breakpoints = []
        self.is_post_mortem = self.pixieapp_entity is None or self.pixieapp_entity["code"] is None
        if self.is_post_mortem:
            if not hasattr(sys, "last_traceback") or sys.last_traceback is None:
                raise NoTraceback()
            if self.options.get("debug_route", "false" ) == "true":
                stack = [tb.function for tb in inspect.getinnerframes(sys.last_traceback)]
                method_name = stack[-1]
                for method in reversed(stack):
                    code = self.parent_pixieapp.exceptions.get(method, None)
                    if code:
                        break
                self.pixieapp_entity = {
                    "breakpoints": ["{}.{}".format(self.parent_pixieapp.__pixieapp_class_name__, method_name)],
                    "code": code or ""
                }
                self.debug("Invoking PixieDebugger for route with {}".format(self.pixieapp_entity))
                self.is_post_mortem = False

        if not self.is_post_mortem:
            self.code = self.renderTemplateString("""
def pixie_run():
    import pdb
    pdb.set_trace()
{{this.pixieapp_entity["code"]|indent(4, indentfirst=True)}}
pixie_run()
        """.strip())
            bps_lines = set()
            bps_fns = set()
            for breakpoint in self.pixieapp_entity["breakpoints"] or []:
                try:
                    bps_lines.add( int(breakpoint))
                except ValueError:
                    matches = get_matches_lineno(self.code, breakpoint)
                    if len(matches) == 0:
                        bps_fns.add(breakpoint)
                    else:
                        for match in matches:
                            bps_lines.add(match)
            self.breakpoints = list(sorted(bps_lines)) + list(sorted(bps_fns))
        else:
            self.code="""
import pdb
pdb.pm()
            """

    @property
    def pm_prefix(self):
        return "$$" if self.is_post_mortem else ""

    @route()
    def main_screen(self):
        try:
            self.initialize()
        except NoTraceback:
            return "
Nothing to debug because no Traceback has been produced
"
        return self.env.getTemplate("mainScreen.html")

    @route(done="*")
    def done_screen(self):
        return "
Thank you for using PixieDust Debugger
"
<|endoftext|>


<commit_before>from slackclient import SlackClient
import re, time, cfg, ast
from json import loads
print("Ready to connect to Slack.")

token = cfg.USTOKEN
sc = SlackClient(token)

userIDs = []
userNames = []
userchannels = []

def readfile():
    d = {}
    try:
        with open("usdict.txt", 'r') as f:
            for line in f:
                (key, val) = line.split("|")
                d[key] = ast.literal_eval(val)
    except:
        f = open("usdict.txt", 'w')
    f.close()
    return(d)

def writedict(d):
    s = ""
    keys = list(d.keys())
    for i in range(0, len(d)):
        s = (s + keys[i] + "|" + str(d[keys[i]]) + "\n")
    f = open("usdict.txt", 'w')
    f.write(s)
    f.close()

def newidea(name, text):
    d = readfile()
    try:
        d[name].append(text)
    except:
        d[name] = [text]
    writedict(d)

def createlists():
    #Get the user list
    userlist = loads(str(sc.api_call("users.list").decode("utf-8")))['members']
    #Parse for user IDs
    for i in range(0, len(userlist)):
        userID = userlist[i]["id"]
        userIDs.append(userID)
        #Find the user's name
        try:
            #Find the user's username if they haven't set a name
            userName = userlist[i]["profile"]["first_name"]
        except:
            userName = userlist[i]["name"]
        userNames.append(userName.lower())
    for n in range(0, len(userIDs)):
        #Find the DM channels for each user
        openstring = str((sc.api_call("im.open", user=userIDs[n])))
        searchObj = re.search(r'"id":"(.*?)"', openstring)
        userchannel = searchObj.group(1)
        userchannels.append(userchannel)
    return()

def send(msgchannel, msgtext):
    sc.api_call("chat.postMessage", as_user="true:", channel=msgchannel, text=msgtext)

def debug(msg):
    send("#pybotdebug", msg)

if sc.rtm_connect():
    print("Connected to Slack.")
    createlists()
    debug("Bot (unstable version) started.")
    readfile()
    while True:
        try:
            #Get new information from the channel
            channelstatus = sc.rtm_read()
            if (channelstatus == []):
                #Discard empty channel status
                print("Nothing happened")
            else:
                #Do literally everything
                #Find the status type
                statustype = channelstatus[0]["type"]
                if statustype:
                    statustype = str(statustype)
                    if statustype == "hello":
                        #Filter out hello message from server
                        print("Hello message received from server.")
                    else:
                        #Find the user ID of the active user
                        try:
                            userID = channelstatus[0]["user"]
                        except:
                            debug("Unknown status! Here are the details:\n" + str(channelstatus))
                        if not (userID == "U0H16CK8T" or userID == "USLACKBOT"):
                            #Only run if the user is not pybot or Slackbot
                            if statustype == "presence_change":
                                #Handle presence changes
                                presencestatus = channelstatus[0]["presence"]
                                if userID in userIDs:
                                    userName = userNames[userIDs.index(userID)]
                                    print(userName.title() + " is now " + presencestatus + ".")
                            elif statustype == "user_typing":
                                #Handle typing
                                if userID in userIDs:
                                    userName = userNames[userIDs.index(userID)]
                                    print(userName + " is typing.")
                                else:
                                    debug("User not found in list! Here are the details:\n" + str(channelstatus))
                            elif statustype == "message":
                                if userID in userIDs:
                                    #Find where the user is in the lists
                                    userpos = userIDs.index(userID)
                                    #Find the user's name and channel
                                    userName = userNames[userpos]
                                    userchannel = userchannels[userpos]
                                    message = channelstatus[0]['text']
                                    print(userName.title() + " says: " + message)
                                    if channelstatus[0]['channel'] == userchannel:
                                        if message.lower()[:5] == "hello":
                                            send(userchannel, "Hi!")
                                    if (message.lower()[:8] == "us!idea:") and (channelstatus[0]['channel'] == "G0H17UA5S"):
                                        (m, idea) = message.split(": ")
                                        try:
                                            newidea(userID, idea)
                                            send("G0H17UA5S", userName.title() + "'s idea has been added.")
                                        except:
                                            send("G0H17UA5S", "Sorry, I couldn't add your idea. Please try again!")
                                    elif (message.lower()[:11] == "us!getideas") and (channelstatus[0]['channel'] == "G0H17UA5S"):
                                        (m, name) = message.split(" ")
                                        if name.lower() in userNames:
                                            userpos = userNames.index(name.lower())
                                            userID = userIDs[userpos]
                                            d = readfile()
                                            if userID in d:
                                                if len(d[userID]) > 0:
                                                    s = ("Ideas for " + name.lower().title() + ":")
                                                    for i in range(0, len(d[userID])):
                                                        s = (s + ("\n" + str(i+1) + ": " + d[userID][i]))
                                                    send("G0H17UA5S", s)
                                                else:
                                                    send("G0H17UA5S", name.lower().title() + " has not entered any ideas yet!")
                                            else:
                                                send("G0H17UA5S", name.lower().title() + " has not entered any ideas yet!")
                                        else:
                                            send("G0H17UA5S", "Name not found! Please try again!")
                                    elif (message.lower()[:10] == "us!delidea") and (channelstatus[0]['channel'] == "G0H17UA5S"):
                                        (m, num) = message.split(" ")
                                        try:
                                            num = int(num) - 1
                                            d = readfile()
                                            if (num + 1) > len(d[userID]):
                                                send("G0H17UA5S", "The number you entered is too large. Please try again.")
                                            else:
                                                e = d[userID].pop(num)
                                                writedict(d)
                                                send("G0H17UA5S", "Idea `" + e + "` deleted.")
                                        except:
                                            send("G0H17UA5S", "Invalid number. Please try again.")
                                else:
                                    debug("User not found in list! Here are the details:\n" + str(channelstatus) + "\nNote: User may have joined between bot restarts. Problem will be fixed next time bot restarts.")
                            else:
                                debug("Unimplemented status! Here are the details:\n" + str(channelstatus))
                        else:
                            print("Pybot and/or Slackbot did something.")
                else:
                    debug("This error should never happen. Here are the details:\n" + str(channelstatus))
            time.sleep(0.5)
        except:
            debug("Fatal error encountered. Restarting!")
#'text': (["'])(.*?)\1
#print(sc.api_call("im.open", user=userID))
#'text': 'This is my legit "test" \'message\' with "lots" of \'quotation marks\''}]
<commit_msg>Fixed a bug, commented everything<commit_after>from slackclient import SlackClient
import re, time, cfg, ast
from json import loads
print("Ready to connect to Slack.")

token = cfg.USTOKEN
sc = SlackClient(token)

userIDs = []
userNames = []
userchannels = []

def readfile():
    #Initialize placeholder empty dictionary
    d = {}
    try:
        #Open the file
        with open("usdict.txt", 'r') as f:
            #Iterate through the lines
            for line in f:
                #Grab the keys and values
                (key, val) = line.split("|")
                #Rebuild the dictionary
                d[key] = ast.literal_eval(val)
    except:
        #Create a new file if it doesn't exist
        f = open("usdict.txt", 'w')
    f.close()
    return(d)

def writedict(d):
    #Create placeholder empty string
    s = ""
    #Get the keys to match them with index numbers
    keys = list(d.keys())
    for i in range(0, len(d)):
        #Write each line of the file with the proper syntax
        s = (s + keys[i] + "|" + str(d[keys[i]]) + "\n")
    f = open("usdict.txt", 'w')
    #Overwrite the file with the new content
    f.write(s)
    f.close()

def newidea(name, text):
    #Grab the dictionary from the file
    d = readfile()
    try:
        #Add the idea to the user's list of ideas
        d[name].append(text)
    except:
        #Create the user in the dictionary if they don't exist
        d[name] = [text]
    writedict(d)

def createlists():
    #Get the user list
    userlist = loads(str(sc.api_call("users.list").decode("utf-8")))['members']
    #Parse for user IDs
    for i in range(0, len(userlist)):
        userID = userlist[i]["id"]
        userIDs.append(userID)
        #Find the user's name
        try:
            #Find the user's username if they haven't set a name
            userName = userlist[i]["profile"]["first_name"]
        except:
            userName = userlist[i]["name"]
        userNames.append(userName.lower())
    for n in range(0, len(userIDs)):
        #Find the DM channels for each user
        openstring = str((sc.api_call("im.open", user=userIDs[n])))
        searchObj = re.search(r'"id":"(.*?)"', openstring)
        userchannel = searchObj.group(1)
        userchannels.append(userchannel)
    return()

def send(msgchannel, msgtext):
    sc.api_call("chat.postMessage", as_user="true:", channel=msgchannel, text=msgtext)

def debug(msg):
    send("#pybotdebug", msg)

if sc.rtm_connect():
    print(time.strftime("%Y-%m-%d %H:%M:%S") + ": Connected to Slack.")
    createlists()
    debug("Bot (unstable version) started.")
    readfile()
    while True:
        #Get new information from the channel
        channelstatus = sc.rtm_read()
        if (channelstatus != []):
            #Do literally everything
            #Find the status type
            statustype = channelstatus[0]["type"]
            if statustype:
                statustype = str(statustype)
                if statustype == "hello":
                    #Filter out hello message from server
                    print(time.strftime("%Y-%m-%d %H:%M:%S") + ": Hello message received from server.")
                else:
                    #Find the user ID of the active user
                    try:
                        userID = channelstatus[0]["user"]
                    except:
                        debug("Unknown status! Here are the details:\n" + str(channelstatus))
                    if not (userID == "U0H16CK8T" or userID == "USLACKBOT"):
                        #Only run if the user is not pybot or Slackbot
                        if statustype == "presence_change":
                            #Handle presence changes
                            presencestatus = channelstatus[0]["presence"]
                            if userID in userIDs:
                                userName = userNames[userIDs.index(userID)]
                                print(time.strftime("%Y-%m-%d %H:%M:%S") + ": " + userName.title() + " is now " + presencestatus + ".")
                        elif statustype == "user_typing":
                            #Handle typing
                            if userID in userIDs:
                                userName = userNames[userIDs.index(userID)]
                                print(time.strftime("%Y-%m-%d %H:%M:%S") + ": " + userName + " is typing.")
                            else:
                                debug("User not found in list! Here are the details:\n" + str(channelstatus))
                        elif statustype == "message":
                            try:
                                #Filter out 'messages' with a subtype
                                #(Gets rid of bots and edits)
                                subtype = channelstatus[0]['subtype']
                            except:
                                if userID in userIDs:
                                    #Find where the user is in the lists
                                    userpos = userIDs.index(userID)
                                    #Find the user's name and channel
                                    userName = userNames[userpos]
                                    #Get the full text of the message
                                    message = channelstatus[0]['text']
                                    print(time.strftime("%Y-%m-%d %H:%M:%S") + ": " + userName.title() + " says: " + message)
                                    #Handle new ideas
                                    if (message.lower()[:8] == "us!idea:") and (channelstatus[0]['channel'] == "G0H17UA5S"):
                                        (m, idea) = message.split(": ")
                                        try:
                                            newidea(userID, idea)
                                            send("G0H17UA5S", userName.title() + "'s idea has been added.")
                                        except:
                                            send("G0H17UA5S", "Sorry, I couldn't add your idea. Please try again!")
                                    #Handle !getideas calls
                                    elif (message.lower()[:11] == "us!getideas") and (channelstatus[0]['channel'] == "G0H17UA5S"):
                                        (m, name) = message.split(" ")
                                        #Check if the user exists
                                        if name.lower() in userNames:
                                            userpos = userNames.index(name.lower())
                                            userID = userIDs[userpos]
                                            #Grab the dictionary from the text file
                                            d = readfile()
                                            #Check if the user is in the idea dictionary
                                            if userID in d:
                                                #Check if the user has any ideas
                                                if len(d[userID]) > 0:
                                                    #Output a numbered list of the user's ideas
                                                    s = ("Ideas for " + name.lower().title() + ":")
                                                    for i in range(0, len(d[userID])):
                                                        s = (s + ("\n" + str(i+1) + ": " + d[userID][i]))
                                                    send("G0H17UA5S", s)
                                                else:
                                                    send("G0H17UA5S", name.lower().title() + " has not entered any ideas yet!")
                                            else:
                                                send("G0H17UA5S", name.lower().title() + " has not entered any ideas yet!")
                                        else:
                                            send("G0H17UA5S", "Name not found! Please try again!")
                                    #Handle idea deletion
                                    elif (message.lower()[:10] == "us!delidea") and (channelstatus[0]['channel'] == "G0H17UA5S"):
                                        (m, num) = message.split(" ")
                                        try:
                                            #Makes sure "1" points to d[userID][0]
                                            num = int(num) - 1
                                            #Grab the dictionary from the text file
                                            d = readfile()
                                            #Make sure the number is not greater than the amount of elements
                                            if (num + 1) > len(d[userID]):
                                                send("G0H17UA5S", "The number you entered is too large. Please try again.")
                                            else:
                                                #Get rid of the element
                                                e = d[userID].pop(num)
                                                #Rebuild the dictionary
                                                writedict(d)
                                                send("G0H17UA5S", "Idea `" + e + "` deleted.")
                                        except:
                                            send("G0H17UA5S", "Invalid number. Please try again.")
                                else:
                                    debug("User not found in list! Here are the details:\n" + str(channelstatus) + "\nNote: User may have joined between bot restarts. Problem will be fixed next time bot restarts.")
                        else:
                            debug("Unimplemented status! Here are the details:\n" + str(channelstatus))
                    else:
                        print(time.strftime("%Y-%m-%d %H:%M:%S") + ": Pybot and/or Slackbot did something.")
            else:
                debug("This error should never happen. Here are the details:\n" + str(channelstatus))
        time.sleep(0.5)
<|endoftext|>


<commit_before>from ply import lex
import ply.yacc as yacc
import sys, getopt
import os
import re

tokens = (
    'CLAUSE',
    'RELATION',
    'PUNCT',
    'SQUAREBR',
    'SQUAREBL',
    'ROUNDBR',
    'ROUNDBL',
    'EQUAL',
    "CITE",
    "UNDER",
    'CURLYBR',
    'CURLYBL',
    'ANGLEBR',
    'ANGLEBL',
    'DASH'
)

t_ignore = ' \t'

t_RELATION = r'([A-Z]+\/[0-9]+)|([A-Z]+_[A-Z]+)|([A-Z]+)'
t_CLAUSE = r'([a-z-_]+\/[0-9]+)|(@[a-zA-Z-_]+)|(\b(?!FOLLOW|AT|TO|INTO|HAS|ABOUT|ON|IN|IS|PART\_OF|IS\_A|NEXT\_TO|INSTRUMENT|CAUSE|MARK|LACK|ER|FROM|BETWEEN|_)\b[a-zA-Z0-9-_]+)'#r'(\b(?!FOLLOW|AT|INTO|HAS|ABOUT)\b[a-zA-Z]+)|(^[a-zA-Z]+\/[0-9]+)|(^@[a-zA-Z]+)|(^"[a-zA-Z]+"$)|(^/=[A-Z]+)'
t_EQUAL = r'(=[A-Z-_]+)'
t_PUNCT = r','
t_SQUAREBR = r'\]'
t_SQUAREBL = r'\['
t_ROUNDBR = r'\)'
t_ROUNDBL = r'\('
t_CURLYBR = r'\}'
t_CURLYBL = r'\{'
t_ANGLEBR = r'\>'
t_ANGLEBL = r'\<'
t_CITE = '"'
t_UNDER = "_"
t_DASH = "-"

def t_newline( t ):
  r'\n+'
  t.lexer.lineno += len( t.value )

def t_error( t ):
  print("Invalid Token:",t.value[0])
  raise TypeError("Invalid token %r" % (t.value[0],))
  t.lexer.skip( 1 )

lexer = lex.lex()

def p_start(p):
    '''start : expr rec'''

def p_rec(p):
    '''rec : PUNCT expr rec
    |'''

def p_clause(p):
    '''expr : CLAUSE '''
    p[0] = p[1]

def p_clause_angle(p):
    '''expr : ANGLEBL start ANGLEBR'''

def p_cite(p):
  '''expr : CITE CLAUSE CITE'''

def p_dash_cite(p):
  '''expr : CITE UNDER DASH CLAUSE CITE'''

def p_under_cite(p):
  '''expr : CITE UNDER CLAUSE CITE'''

def p_under_slash(p):
  '''expr : CITE CLAUSE UNDER CITE'''

def p_under_slash_relation(p):
  '''expr : CITE RELATION UNDER CITE'''

def p_under_cite_relation(p):
  '''expr : CITE UNDER RELATION CITE'''

def p_under_cite_relation_under(p):
  '''expr : CITE UNDER RELATION UNDER CITE'''

def p_cite_relation(p):
  '''expr : CITE RELATION CITE'''

def p_under_cite_clause_under(p):
  '''expr : CITE UNDER CLAUSE UNDER CITE'''

def p_clause_under_cite_clause_under(p):
  '''expr : CITE CLAUSE UNDER CLAUSE CITE'''

def p_expr_curly(p):
    '''expr : CURLYBL start CURLYBR'''

def p_equal(p):
    'expr : EQUAL'

def p_relation_clause(p):
    'expr : RELATION expr'

def p_equal_clause(p):
    'expr : EQUAL start'

def p_equal_clause_equal(p):
    'expr : EQUAL start EQUAL'

def p_relation_clause_binary(p):
    'expr : expr RELATION expr'

def p_clause_relation(p):
    'expr : expr RELATION'
    #print(p[1])

def p_clause_binary(p):
    'expr : expr CLAUSE expr'

def p_expr_clause(p):
    'expr : expr CLAUSE'
    #print(p[1])

def p_clause_expr(p):
    'expr : CLAUSE expr'

def p_relation(p):
    'expr : RELATION'
    #print(p[1])

def p_square(p):
    '''expr : expr SQUAREBL start SQUAREBR
    | EQUAL SQUAREBL start SQUAREBR
    | RELATION  SQUAREBL start SQUAREBR'''
    #print(p[1])
    #print(p[3])

def p_round(p):
    '''expr : expr ROUNDBL start ROUNDBR
    | EQUAL ROUNDBL start ROUNDBR
    | CITE CLAUSE CITE ROUNDBL start ROUNDBR
    | RELATION ROUNDBL start ROUNDBR'''

def p_error(p):
    raise TypeError("unknown text at %r" % (p,))

parser = yacc.yacc()

defs_to_parse = {}
def_states = {}
defs = {}

def filter_line(line, mode="4lang"):
    l = line.strip().split("\t")
    if mode == "4lang":
        definition = l[7]
        def_phrases = re.split(''',(?=(?:[^\[\]{}<>]|\[[^\]]*\]|{[^}]*}|<[^>]*>|\([^\)]*\))*$)''', definition)
        found = False
        filtered_definition = []
        for phrase in def_phrases:
            if "HAS" in phrase:
                filtered_definition.append(phrase.strip())
                found = True
        if found:
            filtered_line = "\t".join(l[:7]) + "\t" + ", ".join(filtered_definition)
            return filtered_line.strip("\n") + "\n"
        else:
            return line
    else:
        definition = l[1]
        def_phrases = re.split(''',(?=(?:[^\[\]{}<>]|\[[^\]]*\]|{[^}]*}|<[^>]*>|\([^\)]*\))*$)''', definition)
        found = False
        filtered_definition = []
        for phrase in def_phrases:
            if "HAS" in phrase:
                filtered_definition.append(phrase.strip())
                found = True
        if found:
            filtered_line = l[0] + "\t" + ", ".join(filtered_definition)
            return filtered_line.strip("\n") + "\n"
        else:
            return line

def readfile(filename, mode="4lang"):
    with open(filename, encoding='utf-8') as f:
        for i, line in enumerate(f):
            if mode == "4lang":
                l = line.strip().split("\t")
                if l[4] in defs:
                    print(l[4])
                defs[l[4]] = line
                if len(l) >= 8:
                    if "%" in l[7]:
                        l[7] = l[7].split("%")[0].strip()
                    defs_to_parse[l[4]] = (l[0], l[7])
                    def_states[l[4]] = None
                else:
                    def_states[l[4]] = 'err bad columns (maybe spaces instead of TABS?)'
            else:
                l = line.strip().split("\t")
                defs[i] = line
                if len(l) >= 2:
                    if "%" in l[1]:
                        l[1] = l[1].split("%")[0].strip()
                    defs_to_parse[i] = (l[0], l[1])
                    def_states[i] = None
                else:
                    def_states[i] = "err bad columns (maybe spaces instead of TABS?)"

def process(outputdir):
    for element in defs_to_parse:
        d = defs_to_parse[element][1]
        if d is not None:
            try:
                res = parser.parse(d)
            except TypeError as e:
                def_states[element] = "err syntax error " + str(e)

def main(argv):
    inputfile = ''
    outputdir = ''
    mode = "4lang"
    try:
        opts, args = getopt.getopt(argv,"hi:o:f:",["ifile=","odir=", "format="])
    except getopt.GetoptError:
        print('def_ply_parser.py -i <inputfile> -o <outputdir> -f <format>')
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-h':
            print('4lang_parser.py -i <inputfile> -o <outputdir> -f <4lang|cut>')
            sys.exit()
        elif opt in ("-i", "--ifile"):
            inputfile = arg
        elif opt in ("-o", "--odir"):
            outputdir = arg
        elif opt in ("-f", "--format"):
            mode = arg

    f = inputfile
    readfile(f, mode)
    o = outputdir
    process(o)
    errors = []
    correct = []
    for state in def_states:
        if def_states[state] and 'err' in def_states[state]:
            errors.append(defs[state].strip() + "\t" + def_states[state] + "\n")
        else:
            correct.append(defs[state])
    errors.sort()
    correct.sort()
    if not os.path.exists(outputdir):
        os.makedirs(outputdir)
    with open(os.path.join(outputdir, "4lang_def_errors"), 'w', encoding="utf-8") as f:
        for item in errors:
            if not item.startswith("%"):
                f.write("%s" % item)
    with open(os.path.join(outputdir, "4lang_def_correct"), 'w', encoding="utf-8") as f:
        with open(os.path.join(outputdir, "4lang_def_correct_filtered"), "w", encoding="utf-8") as filtered:
            for item in correct:
                if not item.startswith("%"):
                    filtered.write("%s" % filter_line(item, mode))
                    f.write("%s" % item)

if __name__ == "__main__":
    main(sys.argv[1:])
<commit_msg>Clause is now an argument<commit_after>from ply import lex
import ply.yacc as yacc
import sys, getopt
import os
import re

tokens = (
    'CLAUSE',
    'RELATION',
    'PUNCT',
    'SQUAREBR',
    'SQUAREBL',
    'ROUNDBR',
    'ROUNDBL',
    'EQUAL',
    "CITE",
    "UNDER",
    'CURLYBR',
    'CURLYBL',
    'ANGLEBR',
    'ANGLEBL',
    'DASH'
)

t_ignore = ' \t'

t_RELATION = r'([A-Z]+\/[0-9]+)|([A-Z]+_[A-Z]+)|([A-Z]+)'
t_CLAUSE = r'([a-z-_]+\/[0-9]+)|(@[a-zA-Z-_]+)|(\b(?!FOLLOW|AT|TO|INTO|HAS|ABOUT|ON|IN|IS|PART\_OF|IS\_A|NEXT\_TO|INSTRUMENT|CAUSE|MARK|LACK|ER|FROM|BETWEEN|_)\b[a-zA-Z0-9-_]+)'#r'(\b(?!FOLLOW|AT|INTO|HAS|ABOUT)\b[a-zA-Z]+)|(^[a-zA-Z]+\/[0-9]+)|(^@[a-zA-Z]+)|(^"[a-zA-Z]+"$)|(^/=[A-Z]+)'
t_EQUAL = r'(=[A-Z-_]+)'
t_PUNCT = r','
t_SQUAREBR = r'\]'
t_SQUAREBL = r'\['
t_ROUNDBR = r'\)'
t_ROUNDBL = r'\('
t_CURLYBR = r'\}'
t_CURLYBL = r'\{'
t_ANGLEBR = r'\>'
t_ANGLEBL = r'\<'
t_CITE = '"'
t_UNDER = "_"
t_DASH = "-"

def t_newline( t ):
  r'\n+'
  t.lexer.lineno += len( t.value )

def t_error( t ):
  print("Invalid Token:",t.value[0])
  raise TypeError("Invalid token %r" % (t.value[0],))
  t.lexer.skip( 1 )

lexer = lex.lex()

def p_start(p):
    '''start : expr rec'''

def p_rec(p):
    '''rec : PUNCT expr rec
    |'''

def p_clause(p):
    '''expr : CLAUSE '''
    p[0] = p[1]

def p_clause_angle(p):
    '''expr : ANGLEBL start ANGLEBR'''

def p_cite(p):
  '''expr : CITE CLAUSE CITE'''

def p_dash_cite(p):
  '''expr : CITE UNDER DASH CLAUSE CITE'''

def p_under_cite(p):
  '''expr : CITE UNDER CLAUSE CITE'''

def p_under_slash(p):
  '''expr : CITE CLAUSE UNDER CITE'''

def p_under_slash_relation(p):
  '''expr : CITE RELATION UNDER CITE'''

def p_under_cite_relation(p):
  '''expr : CITE UNDER RELATION CITE'''

def p_under_cite_relation_under(p):
  '''expr : CITE UNDER RELATION UNDER CITE'''

def p_cite_relation(p):
  '''expr : CITE RELATION CITE'''

def p_under_cite_clause_under(p):
  '''expr : CITE UNDER CLAUSE UNDER CITE'''

def p_clause_under_cite_clause_under(p):
  '''expr : CITE CLAUSE UNDER CLAUSE CITE'''

def p_expr_curly(p):
    '''expr : CURLYBL start CURLYBR'''

def p_equal(p):
    'expr : EQUAL'

def p_relation_clause(p):
    'expr : RELATION expr'

def p_equal_clause(p):
    'expr : EQUAL start'

def p_equal_clause_equal(p):
    'expr : EQUAL start EQUAL'

def p_relation_clause_binary(p):
    'expr : expr RELATION expr'

def p_clause_relation(p):
    'expr : expr RELATION'
    #print(p[1])

def p_clause_binary(p):
    'expr : expr CLAUSE expr'

def p_expr_clause(p):
    'expr : expr CLAUSE'
    #print(p[1])

def p_clause_expr(p):
    'expr : CLAUSE expr'

def p_relation(p):
    'expr : RELATION'
    #print(p[1])

def p_square(p):
    '''expr : expr SQUAREBL start SQUAREBR
    | EQUAL SQUAREBL start SQUAREBR
    | RELATION  SQUAREBL start SQUAREBR'''
    #print(p[1])
    #print(p[3])

def p_round(p):
    '''expr : expr ROUNDBL start ROUNDBR
    | EQUAL ROUNDBL start ROUNDBR
    | CITE CLAUSE CITE ROUNDBL start ROUNDBR
    | RELATION ROUNDBL start ROUNDBR'''

def p_error(p):
    raise TypeError("unknown text at %r" % (p,))

parser = yacc.yacc()

defs_to_parse = {}
def_states = {}
defs = {}

def filter_line(line, clause, mode="4lang"):
    l = line.strip().split("\t")
    if mode == "4lang":
        definition = l[7]
        def_phrases = re.split(''',(?=(?:[^\[\]{}<>]|\[[^\]]*\]|{[^}]*}|<[^>]*>|\([^\)]*\))*$)''', definition)
        found = False
        filtered_definition = []
        for phrase in def_phrases:
            if clause in phrase:
                filtered_definition.append(phrase.strip())
                found = True
        if found:
            filtered_line = "\t".join(l[:7]) + "\t" + ", ".join(filtered_definition)
            return filtered_line.strip("\n") + "\n"
        else:
            return line
    else:
        definition = l[1]
        def_phrases = re.split(''',(?=(?:[^\[\]{}<>]|\[[^\]]*\]|{[^}]*}|<[^>]*>|\([^\)]*\))*$)''', definition)
        found = False
        filtered_definition = []
        for phrase in def_phrases:
            if clause in phrase:
                filtered_definition.append(phrase.strip())
                found = True
        if found:
            filtered_line = l[0] + "\t" + ", ".join(filtered_definition)
            return filtered_line.strip("\n") + "\n"
        else:
            return line

def readfile(filename, mode="4lang"):
    with open(filename, encoding='utf-8') as f:
        for i, line in enumerate(f):
            if mode == "4lang":
                l = line.strip().split("\t")
                if l[4] in defs:
                    print(l[4])
                defs[l[4]] = line
                if len(l) >= 8:
                    if "%" in l[7]:
                        l[7] = l[7].split("%")[0].strip()
                    defs_to_parse[l[4]] = (l[0], l[7])
                    def_states[l[4]] = None
                else:
                    def_states[l[4]] = 'err bad columns (maybe spaces instead of TABS?)'
            else:
                l = line.strip().split("\t")
                defs[i] = line
                if len(l) >= 2:
                    if "%" in l[1]:
                        l[1] = l[1].split("%")[0].strip()
                    defs_to_parse[i] = (l[0], l[1])
                    def_states[i] = None
                else:
                    def_states[i] = "err bad columns (maybe spaces instead of TABS?)"

def process(outputdir):
    for element in defs_to_parse:
        d = defs_to_parse[element][1]
        if d is not None:
            try:
                res = parser.parse(d)
            except TypeError as e:
                def_states[element] = "err syntax error " + str(e)

def main(argv):
    inputfile = ''
    outputdir = ''
    mode = "4lang"
    clause = None
    try:
        opts, args = getopt.getopt(argv,"hi:o:f:c:",["ifile=","odir=", "format=", "clause="])
    except getopt.GetoptError:
        print('def_ply_parser.py -i <inputfile> -o <outputdir> -f <format> -c <clause>')
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-h':
            print('4lang_parser.py -i <inputfile> -o <outputdir> -f <4lang|cut> -c <clause to filter by>')
            sys.exit()
        elif opt in ("-i", "--ifile"):
            inputfile = arg
        elif opt in ("-o", "--odir"):
            outputdir = arg
        elif opt in ("-f", "--format"):
            mode = arg
        elif opt in ("-c", "--clause"):
            clause = arg

    f = inputfile
    readfile(f, mode)
    o = outputdir
    process(o)
    errors = []
    correct = []
    for state in def_states:
        if def_states[state] and 'err' in def_states[state]:
            errors.append(defs[state].strip() + "\t" + def_states[state] + "\n")
        else:
            correct.append(defs[state])
    errors.sort()
    correct.sort()
    if not os.path.exists(outputdir):
        os.makedirs(outputdir)
    with open(os.path.join(outputdir, "4lang_def_errors"), 'w', encoding="utf-8") as f:
        for item in errors:
            if not item.startswith("%"):
                f.write("%s" % item)
    with open(os.path.join(outputdir, "4lang_def_correct"), 'w', encoding="utf-8") as f:
        with open(os.path.join(outputdir, "4lang_def_correct_filtered"), "w", encoding="utf-8") as filtered:
            for item in correct:
                if not item.startswith("%"):
                    if clause:
                        filtered.write("%s" % filter_line(item, clause, mode))
                    f.write("%s" % item)

if __name__ == "__main__":
    main(sys.argv[1:])
<|endoftext|>


<commit_before>#!/usr/bin/env python
# vim: fdm=indent
'''
author:     Fabio Zanini
date:       07/08/17
content:    Test Dataset class.
'''
import numpy as np

# Script
if __name__ == '__main__':

    # NOTE: an env variable for the config file needs to be set when
    # calling this script
    from singlet.dataset import Dataset
    ds = Dataset(
            samplesheet='example_sheet_tsv',
            counts_table='example_table_tsv')

    ds.counts.exclude_features(spikeins=True, other=True, inplace=True)

    print('Test feature selection by expression')
    res = ds.feature_selection.expressed(n_samples=1, exp_min=1)
    assert(res[0] == 'TSPAN6')
    print('Done!')

    print('Test feature selection by expression, in place')
    dsp = ds.copy()
    dsp.feature_selection.expressed(n_samples=1, exp_min=1, inplace=True)
    assert(dsp.featurenames[0] == 'TSPAN6')
    print('Done!')

    print('Test feature selection by overdispersed strata')
    res = ds.feature_selection.overdispersed_strata()
    assert(res[-1] == 'FTL')
    print('Done!')

    print('Test feature selection by overdispersed strata, in place')
    dsp = ds.copy()
    dsp.feature_selection.overdispersed_strata(inplace=True)
    assert(dsp.featurenames[-1] == 'FTL')
    print('Done!')

    print('Test feature weight by self assembling manifolds')
    dsp = ds.copy()
    sam = dsp.feature_selection.sam(npcs=3)
    weights = sam.output_vars['gene_weights']
    print(weights)
    assert(dsp.featurenames[-1] == 'FTL')
    print('Done!')
<commit_msg>Answer to SAM test<commit_after>#!/usr/bin/env python
# vim: fdm=indent
'''
author:     Fabio Zanini
date:       07/08/17
content:    Test Dataset class.
'''
import sys
import numpy as np

# Script
if __name__ == '__main__':

    # NOTE: an env variable for the config file needs to be set when
    # calling this script
    from singlet.dataset import Dataset
    ds = Dataset(
            samplesheet='example_sheet_tsv',
            counts_table='example_table_tsv')

    ds.counts.exclude_features(spikeins=True, other=True, inplace=True)

    print('Test feature selection by expression')
    res = ds.feature_selection.expressed(n_samples=1, exp_min=1)
    assert(res[0] == 'TSPAN6')
    print('Done!')

    print('Test feature selection by expression, in place')
    dsp = ds.copy()
    dsp.feature_selection.expressed(n_samples=1, exp_min=1, inplace=True)
    assert(dsp.featurenames[0] == 'TSPAN6')
    print('Done!')

    print('Test feature selection by overdispersed strata')
    res = ds.feature_selection.overdispersed_strata()
    assert(res[-1] == 'FTL')
    print('Done!')

    print('Test feature selection by overdispersed strata, in place')
    dsp = ds.copy()
    dsp.feature_selection.overdispersed_strata(inplace=True)
    assert(dsp.featurenames[-1] == 'FTL')
    print('Done!')

    if (sys.version_info[0] == 3) and (sys.version_info[1] >= 5):
        print('Test feature weight by self assembling manifolds')
        dsp = ds.copy()
        sam = dsp.feature_selection.sam(npcs=3)
        weights = sam.output_vars['gene_weights']
        assert(weights[0] in (0.23189447, 0.13759565))
        print('Done!')
<|endoftext|>


<commit_before>__author__ = "David Katz-Wigmore"

from File_Creator import WriteFile

import ttk
import Tkinter as tk

import Get_Providers

class App(tk.Frame):
    def __init__(self, master, dictionary):
        """
        Initializes the main frame which will be known as self
        :param master:
        :param dictionary:
        :return:
        """
        tk.Frame.__init__(self, master)

        self.grid(column=0, row=1, sticky="N,W,S,E")
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)

        self.dict = dictionary
        self.values_dict = {}

        self.grant_choices = ["C15", "ZZ-127"]
        self.hp_or_rrh = ["HP", "RRH"]
        self.reporting_categories = sorted(["Choose a reporting category",
                                            "Name",
                                            "Social Security Number",
                                            "Date of Birth",
                                            "Race",
                                            "Ethnicity",
                                            "Gender",
                                            "Veteran Status",
                                            "Disabling Condition",
                                            "Homeless Living Situation",
                                            "Project Entry Date",
                                            "Project Exit Date",
                                            "Destination",
                                            "Personal ID",
                                            "Household ID",
                                            "Relationship to Head of Household",
                                            "Client Location",
                                            "Length of Time on Street",
                                            "Income Sources (Entry)",
                                            "Income Sources (Exit)",
                                            "Non-Cash Benefits (Entry)",
                                            "Non-Cash Benefits (Exit)",
                                            "Insurance (Entry)",
                                            "Insurance (Exit)",
                                            "Services Provided",
                                            "Financial Assistance Provided",
                                            "Move-In Date",
                                            "Non-Homeless Living Situation",
                                            "Date of Move-In",
                                            "Year Entered Military Service",
                                            "Year Separated from Military Service",
                                            "Theaters of Operation",
                                            "Military Branch",
                                            "Discharge Status",
                                            "Household Income as a % of AMI",
                                            "Last Permanent Address",
                                            "Total Monthly Income (Entry)",
                                            "Total Monthly Income (Exit)",
                                            "Continuously Homeless One Year",
                                            "Times Homeless Past Three Years",
                                            "No Head of Household",
                                            "Residence Prior to Project Entry",
                                            "Multiple Heads of Household",
                                            "Very High Monthly Income (Entry)",
                                            "Very High Monthly Income (Exit)"
                                            ])

        self.state = tk.StringVar(self)
        self.provider = tk.StringVar(self)
        self.hp_rrh = tk.StringVar(self)
        self.grant = tk.StringVar(self)
        self.reporting_category = tk.StringVar(self)
        self.value = tk.StringVar(self)

        self.state.trace("w", self.update_options)

        self.state_menu = tk.OptionMenu(self, self.state, *self.dict.keys())
        self.provider_menu = tk.OptionMenu(self, self.provider, "")
        self.hp_rrh_menu = tk.OptionMenu(self, self.hp_rrh, *self.hp_or_rrh)
        self.grant_menu = tk.OptionMenu(self, self.grant, *self.grant_choices)
        self.reporting_categories_menu = tk.OptionMenu(self, self.reporting_category, *self.reporting_categories)

        self.values = ttk.Entry(self, width=48, textvariable=self.value)
        self.add_button = ttk.Button(self, command=self.addition, text="Add")

        self.tree = ttk.Treeview(self,
                                 columns=("Reporting Category", "Error Values"),
                                 selectmode="extended",
                                 show="headings"
                                 )
        self.tree.column("#0", width=10)
        self.tree.column("Reporting Category", width=50)
        self.tree.heading(0, text="Reporting Category")
        self.tree.heading(1, text="Error Values")

        self.y_scroll = ttk.Scrollbar(self, orient="vertical", command=self.tree.yview)
        self.tree.configure(yscrollcommand=self.y_scroll.set)

        self.clear = ttk.Button(self, command=self.clear_all, text="Clear All")
        self.process_button = ttk.Button(self, command=self.process, text="Process")

        self.state.set("Select Your State")
        self.provider.set("Select Your Provider")
        self.grant.set("Select Your Grant")
        self.hp_rrh.set("Select HP or RRH")
        self.reporting_category.set("Choose the Reporting Category")

        self.state_menu.grid(column=0, row=1, padx=2, sticky="E")
        self.provider_menu.grid(column=1, row=1, padx=2, sticky="E")
        self.grant_menu.grid(column=2, row=1, padx=2, sticky="W")
        self.hp_rrh_menu.grid(column=3, row=1, padx=2, sticky="w")
        self.reporting_categories_menu.grid(column=0, row=2, padx=2, sticky="E")
        self.values.grid(column=1, columnspan=2, row=2, sticky="W, E")
        self.add_button.grid(column=3, row=2, sticky="W")
        self.tree.grid(column=0, columnspan=4, row=3, sticky="E, W")
        self.y_scroll.grid(column=4, row=3, sticky="N, W, S")
        self.clear.grid(column=2, row=4, sticky="E")
        self.process_button.grid(column=3, row=4, sticky="E")

    def addition(self):
        """
        Adds a new value to the val_dict where the category is the key and the ctid#'s (along with the other included
        information) is the value.
        :return:
        """
        self.values_dict[self.reporting_category.get()] = self.value.get()
        self.set_list()

    def clear_all(self):
        """
        Clears all the values from the tree widget and the value_dict allowing a new report to be processed
        without closing and re-opening the program.
        :return:
        """
        self.values_dict.clear()
        for child_id in self.tree.get_children():
            self.tree.delete(child_id)

    def process(self):
        """
        Calls the WriteFile function, which converts the value_dict into an excel file.
        The name of this file will be printed to the terminal window to show that the process
        is complete
        :return:
        """
        name = self.provider.get() + " " + self.grant.get() + " " + self.hp_rrh.get() + ".xls"
        try:
            WriteFile(str(name), self.values_dict)
            print(name)
        except ValueError:
            print("An error occurred and your file was not saved.")

    def set_list(self):
        """
        defines the listbox that displays the keys & values of the values_dict.
        :return:
        """
        for child_id in self.tree.get_children():
            self.tree.delete(child_id)
        for key in self.values_dict.keys():
            self.tree.insert("", index="end", values=(key, self.values_dict[key]))

    def update_options(self, *args):
        """
        This method allows the provider menu to update depending on which state is selected.
        :param args:
        :return:
        """
        providers = self.dict[self.state.get()]

        menu = self.provider_menu["menu"]
        menu.delete(0, 'end')

        for provider in providers:
            menu.add_command(label=provider, command=lambda region=provider: self.provider.set(region))

if __name__ == "__main__":
    root = tk.Tk()
    make_dict = Get_Providers.MakeDictionary()
    app = App(root, make_dict.read_csv())
    app.mainloop()
<commit_msg>Updated to match new reporting standards<commit_after>__author__ = "David Katz-Wigmore"

from File_Creator import WriteFile

import ttk
import Tkinter as tk

import Get_Providers

class App(tk.Frame):
    def __init__(self, master, dictionary):
        """
        Initializes the main frame which will be known as self
        :param master:
        :param dictionary:
        :return:
        """
        tk.Frame.__init__(self, master)

        self.grid(column=0, row=1, sticky="N,W,S,E")
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)

        self.dict = dictionary
        self.values_dict = {}

        self.grant_choices = ["C15", "ZZ-127"]
        self.hp_or_rrh = ["HP", "RRH"]
        self.reporting_categories = sorted(["Choose a reporting category",
                                            "Name",
                                            "Social Security Number",
                                            "Date of Birth",
                                            "Race",
                                            "Ethnicity",
                                            "Gender",
                                            "Veteran Status",
                                            "Disabling Condition",
                                            "Homeless Living Situation",
                                            "Project Entry Date",
                                            "Project Exit Date",
                                            "Destination",
                                            "Personal ID",
                                            "Household ID",
                                            "Relationship to Head of Household",
                                            "Client Location",
                                            "Length of Time on Street",
                                            "Income Sources (Entry)",
                                            "Income Sources (Exit)",
                                            "Non-Cash Benefits (Entry)",
                                            "Non-Cash Benefits (Exit)",
                                            "Insurance (Entry)",
                                            "Insurance (Exit)",
                                            "Services Provided",
                                            "Financial Assistance Provided",
                                            "Move-In Date",
                                            "Non-Homeless Living Situation",
                                            "Date of Move-In",
                                            "Year Entered Military Service",
                                            "Year Separated from Military Service",
                                            "Theaters of Operation",
                                            "Military Branch",
                                            "Discharge Status",
                                            "Household Income as a % of AMI",
                                            "HP Screening Score",
                                            "Last Permanent Address",
                                            "Total Monthly Income (Entry)",
                                            "Total Monthly Income (Exit)",
                                            "Continuously Homeless One Year",
                                            "Times Homeless Past Three Years",
                                            "No Head of Household",
                                            "Residence Prior to Project Entry",
                                            "Multiple Heads of Household",
                                            "VAMC Station Number",
                                            "Very High Monthly Income (Entry)",
                                            "Very High Monthly Income (Exit)"
                                            ])

        self.state = tk.StringVar(self)
        self.provider = tk.StringVar(self)
        self.hp_rrh = tk.StringVar(self)
        self.grant = tk.StringVar(self)
        self.reporting_category = tk.StringVar(self)
        self.value = tk.StringVar(self)

        self.state.trace("w", self.update_options)

        self.state_menu = tk.OptionMenu(self, self.state, *self.dict.keys())
        self.provider_menu = tk.OptionMenu(self, self.provider, "")
        self.hp_rrh_menu = tk.OptionMenu(self, self.hp_rrh, *self.hp_or_rrh)
        self.grant_menu = tk.OptionMenu(self, self.grant, *self.grant_choices)
        self.reporting_categories_menu = tk.OptionMenu(self, self.reporting_category, *self.reporting_categories)

        self.values = ttk.Entry(self, width=48, textvariable=self.value)
        self.add_button = ttk.Button(self, command=self.addition, text="Add")

        self.tree = ttk.Treeview(self,
                                 columns=("Reporting Category", "Error Values"),
                                 selectmode="extended",
                                 show="headings"
                                 )
        self.tree.column("#0", width=10)
        self.tree.column("Reporting Category", width=50)
        self.tree.heading(0, text="Reporting Category")
        self.tree.heading(1, text="Error Values")

        self.y_scroll = ttk.Scrollbar(self, orient="vertical", command=self.tree.yview)
        self.tree.configure(yscrollcommand=self.y_scroll.set)

        self.clear = ttk.Button(self, command=self.clear_all, text="Clear All")
        self.process_button = ttk.Button(self, command=self.process, text="Process")

        self.state.set("Select Your State")
        self.provider.set("Select Your Provider")
        self.grant.set("Select Your Grant")
        self.hp_rrh.set("Select HP or RRH")
        self.reporting_category.set("Choose the Reporting Category")

        self.state_menu.grid(column=0, row=1, padx=2, sticky="E")
        self.provider_menu.grid(column=1, row=1, padx=2, sticky="E")
        self.grant_menu.grid(column=2, row=1, padx=2, sticky="W")
        self.hp_rrh_menu.grid(column=3, row=1, padx=2, sticky="w")
        self.reporting_categories_menu.grid(column=0, row=2, padx=2, sticky="E")
        self.values.grid(column=1, columnspan=2, row=2, sticky="W, E")
        self.add_button.grid(column=3, row=2, sticky="W")
        self.tree.grid(column=0, columnspan=4, row=3, sticky="E, W")
        self.y_scroll.grid(column=4, row=3, sticky="N, W, S")
        self.clear.grid(column=2, row=4, sticky="E")
        self.process_button.grid(column=3, row=4, sticky="E")

    def addition(self):
        """
        Adds a new value to the val_dict where the category is the key and the ctid#'s (along with the other included
        information) is the value.
        :return:
        """
        self.values_dict[self.reporting_category.get()] = self.value.get()
        self.set_list()

    def clear_all(self):
        """
        Clears all the values from the tree widget and the value_dict allowing a new report to be processed
        without closing and re-opening the program.
        :return:
        """
        self.values_dict.clear()
        for child_id in self.tree.get_children():
            self.tree.delete(child_id)

    def process(self):
        """
        Calls the WriteFile function, which converts the value_dict into an excel file.
        The name of this file will be printed to the terminal window to show that the process
        is complete
        :return:
        """
        name = self.provider.get() + " " + self.grant.get() + " " + self.hp_rrh.get() + ".xls"
        try:
            WriteFile(str(name), self.values_dict)
            print(name)
        except ValueError:
            print("An error occurred and your file was not saved.")

    def set_list(self):
        """
        defines the listbox that displays the keys & values of the values_dict.
        :return:
        """
        for child_id in self.tree.get_children():
            self.tree.delete(child_id)
        for key in self.values_dict.keys():
            self.tree.insert("", index="end", values=(key, self.values_dict[key]))

    def update_options(self, *args):
        """
        This method allows the provider menu to update depending on which state is selected.
        :param args:
        :return:
        """
        providers = self.dict[self.state.get()]

        menu = self.provider_menu["menu"]
        menu.delete(0, 'end')

        for provider in providers:
            menu.add_command(label=provider, command=lambda region=provider: self.provider.set(region))

if __name__ == "__main__":
    root = tk.Tk()
    make_dict = Get_Providers.MakeDictionary()
    app = App(root, make_dict.read_csv())
    app.mainloop()
<|endoftext|>