text: # TODO rename some of these variables to be more sensible
  
  import os
  import configparser
  from numpy import nan
  from datetime import datetime
  import matplotlib as mpl
  import matplotlib.cm 
  
  def get_date(date):
      return datetime.strptime(date, '%Y-%m-%d')
  
  config = configparser.ConfigParser()
  config.read(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'config.ini'))
  
  # Directory where all data is stored
  ALL_DATA = config['data']['all_data']
  
  # Path to where appinventor data is stored
  AI_DATA = os.path.join(ALL_DATA, config['data']['ai_data'])
  
  # Path to where edx data is stored
  EDX_DATA = os.path.join(ALL_DATA, config['data']['edx_data'])
  
  # Path to where the course data is stored
  COURSE_PATH = os.path.join(EDX_DATA, config['data']['course_data'])
  
  # Path to save appinventor server plots to
  PLOT_SAVE_PATH = config['graph']['save_path']
  
  # Paths to save edx files to
  EDX_SAVE_PATH = config['data']['edx_out']
  NO_PII_PATH = os.path.join(EDX_SAVE_PATH, config['data']['no_pii'])
  
  GRADE_FILE_NAME = config['data']['grades']
  ID_MAP_FILE_NAME = config['data']['id_map']
  CLICKSTREAM_FILE_NAME = config['data']['clickstream']
  
  # Sample test folder 1
  TEST_FOLDER = os.path.join(AI_DATA, config['data']['test1'])
  
  # Sample test folder 2
  TEST_FOLDER_2 = os.path.join(AI_DATA, config['data']['test2'])
  
  # Sample User with only 1 SCM backup and 1 BKY backup
  TEST_USER_SINGLE = os.path.join(AI_DATA, config['data']['test_single_scm_bky'])
  
  # Sample test data
  TEST_DATA = os.path.join(TEST_FOLDER, config['data']['test_user'])
  
  # JSON describing the order of resources in the course
  # Generated by running `resource_order.py`
  RESOURCE_JSON = config['data']['resource_order']
  
  # CSV describing the category of each resource in the course
  CATEGORY_CSV = config['data']['categories']
  
  # JSON with every video component and their attributes
  VIDEO_JSON = config['data']['videos']
  
  # CSV with extra urls for different resources
  EXTRA_URLS_CSV = config['data']['extra_urls']
  
  # CSV with urls for the navigation tabs at the top of the course page
  NAV_URLS_CSV = config['data']['nav_urls']
  
  # Location of color palettes
  COLOR_PALETTES = config['graph']['palettes']
  
  # The default color palette
  DEFAULT_PALETTE = os.path.join(COLOR_PALETTES, config['graph']['default_palette'])
  
  # Whether to save the plots to files
  # Can be modified per cell. This is easier than passing true
  # or false to every function for graph. It also allows for easy
  # saving when plotting outside of a function. 
  to_file = config['graph']['to_file']
  
  # Names of the different cohorts
  STAFF = 'Staff'
  TEACHERS = 'Teachers'
  NAN = nan
  
  # Define cohorts to ignore
  IGNORE_COHORTS = []
  
  for i in config['graph']['ignore_cohorts'].split(','):
      if i.strip().lower() == STAFF.lower():
          IGNORE_COHORTS.append(STAFF)
      if i.strip().lower() == TEACHERS.lower():
          IGNORE_COHORTS.append(TEACHERS)
      if i.strip().lower() == 'nan':
          IGNORE_COHORTS.append(NAN)
  
  # Resources to ignore
  IGNORE_RESOURCES = [i.strip() for i in config['graph']['ignore_resources'].split(',')]
  
  BKY = 'bky'
  SCM = 'scm'
  BKY_TYPE = 'type'
  SCM_TYPE = '$Type'
  BACKUP = 'backup'
  DISPLAY_NAME = 'display_name'
  PARENT_NAME = 'resource_type'
  FILE_NAME = 'resource_file_name'
  CATEGORY_RESOURCE_COLUMN = "Resource"
  TWO_HOURS = 7200 # seconds
  
  # The dates of the workshops that took place
  # during the course in month-day format
  date_strings = ['2019-1-19', '2019-1-24', '2019-3-2']
  WORKSHOPS = [get_date(d) for d in date_strings]
  HOMEPAGE_NAMES = ['Develop Apps', 
                    'course-v1:COURSE', 
                    'course']
  
  display_name_errors = {
      'Audio & Video': 'Unit 6 Intro',
      'Canvas Component & Component Layout': 'Canvas Component',
      'Code Blocks': 'Introduction to Code Blocks',
      'Code2App - Sustainability Background Information': 'Background Information',
      'Coding techniques': 'Code Comment',
      'Course Information': 'Syllabus',
      'Drawing Application Interface and Coding': 'Clearing Canvas',
      'File': 'Starting Notebook Project',
      'Finishing HelloWorld Project & Project Sharing': 'Testing HelloWorld Project',
      'ImageSprite Component & Random Number': 'ImageSprite Component',
      'Important Workshops': 'Computational Thinking Workshop',
      'Location Determination': 'Location Information',
      'Logical and Conditional Operations': 'if-then Code & Logic Code Blocks',
      'MathQuiz Assignment': 'Math Quiz App Assignment',
      'NumberMatching Assignment': 'NumberMatching Game Assignment',
      'SequenceCalculator Assignment': 'SequenceCalculator App',
      'Sound and Clock Components': 'Clock Component',
      'Specific MIT App Inventor Server': 'Server',
      'Spinner, Slider and TextBox Components': 'Unit 7',
      'Starting App Inventor and HelloWorld Project': 'App Inventor Project & Starting HelloWorld Project',
      'Super-dolphin Game Coding': 'Stopping Game',
      'Super-dolphin Game Interface and Assets': 'Starting Superdolphin Project & Game Assets',
      'TimePicker Component & Project Asset': 'Project Asset',
      'Unit 10 Intro': 'Unit 10',
      'Using Component (Button, Label and TextToSpeech)': 'Component',
      'Variable & Loop': 'Starting UsingLoop Project',
      'Working With Boolean Values & Choice Dialog': 'Choice Dialog & Starting UsingIfThen Project',
      'Working With Numbers': 'Unit 3 Intro',
      'Working With Text & Message Dialog': 'Notifier Component & Starting UsingMath Project',
  }
  
  # Generated from running `link_edx_appinventor.ipnb`
  GRADE_PATH = os.path.join(NO_PII_PATH, "ed_" + GRADE_FILE_NAME)
  ID_MAP_FILE_PATH = os.path.join(NO_PII_PATH, "ed_" + ID_MAP_FILE_NAME)
  APPINVENTOR_FILE_PATH = os.path.join(NO_PII_PATH, 'ed_appinventor_files.csv')
  EDX_CLICKSTREAM_FILE_PATH = os.path.join(NO_PII_PATH, 'ed_' + CLICKSTREAM_FILE_NAME)
  
  SUFFIX = '.xml'
  ID_MAP_APP = 'id_map_app'
  EVENT_TYPE = 'event_type'
  CLICK_ID_MAP = 'click_id_map'
  USERNAME = 'username'
  COHORT_NAME = 'Cohort Name'
  FROM = 'from'
  TO = 'to'
  DURATION_AVERAGE_THRESHOLD = 300
  REVIEW_THRESHOLD = 6000
  ELEMENTARY = 5
  FORWARD = 'forward'
  BACKWARD = 'backward'
  KTYPES = ['factual', 'procedural', 'conceptual']
  UNIT_NAV_EVENTS_OLD = ['seq_next', 'seq_prev', 'seq_goto']
  STOP_EVENTS = ['pause_video', 'seek_video', 'stop_video']
  INTERESTING_EVENTS = ['play_video', 'load_video', 'stop_video', 
                        'seek_video', 'pause_video', 'speed_change_video',
                        'hide_transcript', 'show_transcript']
  ARROW_SIZE = 20
  N_TICKS = 5
  CMAP = mpl.cm.get_cmap('Reds')
  CMAP_2 = mpl.cm.get_cmap('winter')
  NODE_SIZE = 300
  EM_DASH = u'\u2014'
  MAX_LINE_LENGTH = 40
  MAX_RGB = 255
  