notes and questions

Notes:

  • probably will need a class that is an Article_Data container - reference to Article_Data, and then all the logic to process the entities and relations contained within.

Questions:

  • Do we want an Identifier Type separate from Entity and Relation identifiers? I think we do, so we can specify the entity type(s) a given identifier should be used on.

    • Created abstract one, and created a concrete entity identifier type. Will create one for relation identifiers if needed.

Setup


In [1]:
me = "render-context-networks-dev"

Setup - Debug


In [2]:
debug_flag = False

Setup - Imports


In [3]:
import datetime
from django.db.models import Avg, Max, Min, Q
from django.utils.text import slugify
import json
import logging
import six

Setup - working folder paths


In [4]:
%pwd


Out[4]:
'/home/jonathanmorgan/work/django/research/work/phd_work/analysis'

In [5]:
# current working folder
current_working_folder = "/home/jonathanmorgan/work/django/research/work/phd_work/analysis"
current_datetime = datetime.datetime.now()
current_date_string = current_datetime.strftime( "%Y-%m-%d-%H-%M-%S" )

Setup - logging

configure logging for this notebook's kernel (If you do not run this cell, you'll get the django application's logging configuration.


In [6]:
logging_file_name = "{}/logs/{}-{}.log.txt".format( current_working_folder, me, current_date_string )
logging.basicConfig(
    level = logging.DEBUG,
    format = '%(asctime)s - %(levelname)s - %(name)s - %(message)s',
    filename = logging_file_name,
    filemode = 'w' # set to 'a' if you want to append, rather than overwrite each time.
)
print( "Logging initialized, to {}".format( logging_file_name ) )


Logging initialized, to /home/jonathanmorgan/work/django/research/work/phd_work/analysis/logs/render-context-networks-dev-2020-02-04-21-16-39.log.txt

Setup - virtualenv jupyter kernel

If you are using a virtualenv, make sure that you:

  • have installed your virtualenv as a kernel.
  • choose the kernel for your virtualenv as the kernel for your notebook (Kernel --> Change kernel).

Since I use a virtualenv, need to get that activated somehow inside this notebook. One option is to run ../dev/wsgi.py in this notebook, to configure the python environment manually as if you had activated the sourcenet virtualenv. To do this, you'd make a code cell that contains:

%run ../dev/wsgi.py

This is sketchy, however, because of the changes it makes to your Python environment within the context of whatever your current kernel is. I'd worry about collisions with the actual Python 3 kernel. Better, one can install their virtualenv as a separate kernel. Steps:

  • activate your virtualenv:

      workon research
  • in your virtualenv, install the package ipykernel.

      pip install ipykernel
  • use the ipykernel python program to install the current environment as a kernel:

      python -m ipykernel install --user --name <env_name> --display-name "<display_name>"
    
    

    sourcenet example:

      python -m ipykernel install --user --name sourcenet --display-name "research (Python 3)"

More details: http://ipython.readthedocs.io/en/stable/install/kernel_install.html

Setup - Initialize Django

First, initialize my dev django project, so I can run code in this notebook that references my django models and can talk to the database using my project's settings.


In [7]:
# init django
django_init_folder = "/home/jonathanmorgan/work/django/research/work/phd_work"
django_init_path = "django_init.py"
if( ( django_init_folder is not None ) and ( django_init_folder != "" ) ):
    
    # add folder to front of path.
    django_init_path = "{}/{}".format( django_init_folder, django_init_path )
    
#-- END check to see if django_init folder. --#

In [8]:
%run $django_init_path


django initialized at 2020-02-04 21:16:44.765746

In [9]:
# context imports
from context.export.network.filter_spec import FilterSpec
from context.export.network.network_data_request import NetworkDataRequest
from context.export.network.network_output import NetworkOutput
from context.models import Entity
from context.models import Entity_Identifier_Type
from context.models import Entity_Identifier
from context.models import Entity_Relation
from context.models import Entity_Relation_Type
from context.models import Entity_Type
from context.shared.context_base import ContextBase
from context.tests.export.network.test_helper import TestHelper
from context.tests.export.network.test_NetworkDataOutput_class import NetworkDataOutputTest

Setup - Initialize LoggingHelper

Create a LoggingHelper instance to use to log debug and also print at the same time.

Preconditions: Must be run after Django is initialized, since python_utilities is in the django path.


In [10]:
# python_utilities
from python_utilities.logging.logging_helper import LoggingHelper

# init
my_logging_helper = LoggingHelper()
my_logging_helper.set_logger_name( me )
log_message = None

Render network data

Now, we need to render out our network data from context, so we can then test it out and make sure we are getting the same answers we got from the old way.

Specify filter criteria

First step is to translate the filter criteria for nodes and ties from the existing admin for the querying context.

Old filter criteria

Configuration of Network Builder, from methods-network_analysis-create_network_data.ipynb:

  • Configuration to generate network files for prelim:

    • Config of "Select Articles" - fields in bold need to be changed from default values:

      • Start date (YYYY-MM-DD): 2009-12-01
      • End date (YYYY-MM-DD): 2009-12-31
      • Fancy date range: - Empty.
      • Publications: "Grand Rapids Press, The"
      • Coders: None selected.
      • Coder IDs to include, in order of highest to lowest priority:

        • for human sample: 13,8,9,10
        • for automated: 2
      • if automated: Article_Data coder_type Filter Type and coder_type 'Value In' List (comma-delimited):

        • only for coder "automated" (2), for now.
        • use the coder_type filter fields to filter automatically coded Article_Data on coder type if you have tried different automated coder types:

          • Article_Data coder_type Filter Type: - Just automated
          • coder_type 'Value In' List (comma-delimited): - Enter the coder types you want included. Examples:

            • OpenCalais v2: "OpenCalais_REST_API_v2"
      • Topics: None selected.

      • Article Tag List (comma-delimited): - "grp_month"
      • Unique Identifier List (comma-delimited): - Empty.
      • Allow duplicate articles: - "No"
    • Configure "Network Settings" - fields in bold need to be changed from default values:

      • relations - Include source contact types - All selected.
      • relations - Include source capacities: - None selected.
      • relations - Exclude source capacities: - None selected.
      • Download as File? - "Yes"
      • Include render details? - "No"
      • Data Format: - "Tab-Delimited Matrix"
      • Data Output Type: - "Network + Attribute Columns"
      • Network Label: - Empty.
      • Include Headers: - "Yes"
    • Config of "Select People" - fields in bold need to be changed from default values:

      • NOTE: This will be the same for all networks you want to compare (different weeks within a month, compared to the whole month, for instance). For each, get people from articles that are filtered to include all people used by either human or automated, and all the days covered by any of the networks you want to compare. This means you'll have the same dimensions of network (same set of nodes/people) regardless of the particular network you are generating, allowing the matrices that result to be compared.
      • Person Query Type: - "Custom, defined below"
      • People from (YYYY-MM-DD): - 2009-12-01
      • People to (YYYY-MM-DD): - 2009-12-31
      • Fancy person date range: - Empty.
      • Person publications: - "Grand Rapids Press, The"
      • Person coders: - "automated", "minnesota1", "minnesota2", "minnesota3", "ground_truth"
      • Coder IDs to include, in order of highest to lowest priority: - Empty.
      • Article_Data coder_type Filter Type and coder_type 'Value In' List (comma-delimited):

        • NOTE: not just for automated - since this includes all coders, automated and human, you need to always specify the coder type filter if you need it for automated network.
        • use the coder_type filter fields to filter automatically coded Article_Data on coder type if you have tried different automated coder types:

          • Article_Data coder_type Filter Type: - Just automated
          • coder_type 'Value In' List (comma-delimited): - Enter the coder types you want included. Examples:

            • OpenCalais v2: "OpenCalais_REST_API_v2"
      • Person Topics: None

      • Article Tag List (comma-delimited): - "grp_month"
      • Unique Identifier List (comma-delimited): - Empty.
      • Person allow duplicate articles: - "Yes"

JSON files of filter criteria for just automated coding

Below is a JSON file that is just the automated coding for the month from 2009-12-01 through 2009-12-31, articles in the Grand Rapids Press. Just about all of the complexity of the original screens is possible here, as long as you loaded the entities and ties and all of the needed traits, including some way of adding tags...

{
    "output_specification": {
        "output_type": "file",
        "output_file_path": "./NetworkDataRequest_test_output.txt",
        "output_format": "TSV_matrix",
        "output_structure": "both_trait_columns",
        "output_include_column_headers": true
    },
    "relation_selection": {
        "relation_type_slug_filter_combine_type": "AND",
        "relation_type_slug_filters": [
            {
                "comparison_type": "includes",
                "value_list": [ "mentioned", "qouted", "shared_byline" ]
            }
        ],
        "relation_trait_filter_combine_type": "AND",
        "relation_trait_filters": [
            {
                "name": "pub_date",
                "data_type": "date",
                "comparison_type": "in_range",
                "value_from": "2009-12-01",
                "value_to": "2009-12-31"
            },
            {
                "name": "sourcenet-coder-User-username",
                "data_type": "string",
                "comparison_type": "includes",
                "value_list": [ "automated" ]
            },
            {
                "name": "coder_type",
                "data_type": "string",
                "comparison_type": "includes",
                "value_list": [ "OpenCalais_REST_API_v2" ]
            }
        ],
        "entity_type_slug_filter_combine_type": "AND",
        "entity_type_slug_filters": [
            {
                "comparison_type": "includes",
                "value_list": [ "person" ],
                "relation_roles_list": [ "FROM" ]
            },
            {
                "comparison_type": "includes",
                "value_list": [ "person" ],
                "relation_roles_list": [ "TO" ]
            },
            {
                "comparison_type": "includes",
                "value_list": [ "article" ],
                "relation_roles_list": [ "THROUGH" ]
            }            
        ],
        "entity_trait_filter_combine_type": "AND",
        "entity_trait_filters": [
            {
                "name": "sourcenet-Newspaper-ID",
                "data_type": "int",
                "comparison_type": "includes",
                "value_list": [ 1 ],
                "relation_roles_list": [ "THROUGH" ]
            }
        ]
    }
}

Context network output

Steps:

  • make sure settings.py is referring to the full database (research, not the testing database research_temp)
  • run all the initialization code above in section 2.
  • load a request into a NetworkDataRequest instance (example below uses the unit test TestHelper class to load the basic configuration, which is the same as the above, for 12/1/2009 through 12/31/2009, automated coder, Grand Rapids Press only).

    • using TestHelper: data_request = TestHelper.load_basic()
    • from file path:

        data_request = NetworkDataRequest()
        path_to_file = "./request.json"
        data_request.load_network_data_request_json_file( path_to_file )
  • update details of the request post-load. Examples:

    • call "data_request.set_output_file_path( path )" to change where the file will be output.
    • call "data_request.set_output_format( format )" to change the output format. Values:

      • "simple_matrix" ( NetworkDataRequest.PROP_VALUE_OUTPUT_FORMAT_SIMPLE_MATRIX ) - format for UCINet where contents of tie file and attribute files are all concatenated into one text file.
      • "CSV_matrix" ( NetworkDataRequest.PROP_VALUE_OUTPUT_FORMAT_CSV_MATRIX )
      • "TSV_matrix" ( NetworkDataRequest.PROP_VALUE_OUTPUT_FORMAT_TSV_MATRIX )
    • call "data_request.set_output_type( type )" to change the output type.

  • make an instance of NetworkOutput: network_output = NetworkOutput().

  • initialize it by calling "network_output.set_network_data_request( data_request )", passing in the request you loaded.
  • call "network_output.render_network_data()". The method returns the contents of the file it created, and outputs to file as directed inside the request.

In [14]:
# load basic NetworkDataRequest
#data_request = TestHelper.load_basic()

# or, load from file path
data_request = NetworkDataRequest()
path_to_file = "./grp_month_from_context.json"
data_request.load_network_data_request_json_file( path_to_file )


Out[14]:
<python_utilities.status.status_container.StatusContainer at 0x7fcc6f2cd908>

In [12]:
# configure output
#overridden_output_path = "{}/automated_grp_month.tsv".format( current_working_folder )
#data_request.set_output_file_path( overridden_output_path )


Out[12]:
'/home/jonathanmorgan/work/django/research/work/phd_work/analysis/automated_grp_month.tsv'

In [15]:
# make and initialize instance of NetworkOutput
network_output = NetworkOutput()
network_output.set_network_data_request( data_request )


Out[15]:
<context.export.network.network_data_request.NetworkDataRequest at 0x7fcc6f7d81d0>

In [16]:
# call render, see what happens.
network_data = network_output.render_network_data()


In context.export.network.network_output.NetworkOutput.render_network_data(): Calling NetworkDataRequest.process_entities() @ 2020-02-04 21:37:14.739044
In get_selection_filters(): use_entity_selection_IN is True
In get_selection_filters(): "entity_selection" filtering was requested, but not specified in the request.  Defaulting to "relation_selection".
In context.export.network.network_output.NetworkOutput.render_network_data(): After calling NetworkDataRequest.process_entities(), calling NetworkDataRequest.filter_relation_query_set() @ 2020-02-04 21:37:45.084237
In get_selection_filters(): use_entity_selection_IN is False
In context.export.network.network_output.NetworkOutput.render_network_data(): After calling NetworkDataRequest.filter_relation_query_set(), initializing NetworkDataOutput instance @ 2020-02-04 21:37:45.090883
In context.export.network.network_output.NetworkOutput.render_network_data(): After initializing NetworkDataOutput instance, calling NetworkDataOutput.render() @ 2020-02-04 21:37:45.091193
In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Starting loop over relations to create ties @ 2020-02-04 21:37:45.658421
----> In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Processed 100 of 1311 relations @ 2020-02-04 21:37:46.548948
----> In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Processed 200 of 1311 relations @ 2020-02-04 21:37:46.917056
----> In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Processed 300 of 1311 relations @ 2020-02-04 21:37:47.404619
----> In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Processed 400 of 1311 relations @ 2020-02-04 21:37:48.065762
----> In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Processed 500 of 1311 relations @ 2020-02-04 21:37:48.956263
----> In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Processed 600 of 1311 relations @ 2020-02-04 21:37:50.061245
----> In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Processed 700 of 1311 relations @ 2020-02-04 21:37:51.432327
----> In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Processed 800 of 1311 relations @ 2020-02-04 21:37:53.085812
----> In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Processed 900 of 1311 relations @ 2020-02-04 21:37:55.070394
----> In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Processed 1000 of 1311 relations @ 2020-02-04 21:38:00.995072
----> In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Processed 1100 of 1311 relations @ 2020-02-04 21:38:11.896740
----> In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Processed 1200 of 1311 relations @ 2020-02-04 21:38:24.656246
----> In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Processed 1300 of 1311 relations @ 2020-02-04 21:38:40.311361
In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Ties created, generating master entity list @ 2020-02-04 21:38:42.206772
In generate_master_entity_list: len( entity_dict ) = 1088; entity_dict: {274: None, 687: None, 132: None, 12279: None, 12558: None, 12559: None, 1683: None, 4857: None, 238: None, 876: None, 721: None, 437: None, 1384: None, 16: None, 1969: None, 4422: None, 3821: None, 5653: None, 12439: None, 4575: None, 69: None, 12593: None, 12594: None, 221: None, 240: None, 12597: None, 12600: None, 6548: None, 5527: None, 10804: None, 12607: None, 1179: None, 218: None, 440: None, 12619: None, 12621: None, 275: None, 12623: None, 593: None, 62: None, 12625: None, 12627: None, 12628: None, 104: None, 12643: None, 667: None, 975: None, 384: None, 974: None, 12555: None, 424: None, 12660: None, 12661: None, 177: None, 12663: None, 12664: None, 12665: None, 12666: None, 12680: None, 9603: None, 1898: None, 7972: None, 12492: None, 2330: None, 12493: None, 866: None, 12714: None, 12715: None, 12717: None, 3350: None, 12722: None, 10091: None, 12747: None, 972: None, 12748: None, 12750: None, 5246: None, 5813: None, 2522: None, 12758: None, 12760: None, 380: None, 12781: None, 12783: None, 316: None, 12792: None, 12793: None, 11185: None, 11593: None, 2870: None, 12854: None, 12859: None, 1185: None, 12880: None, 12881: None, 12884: None, 12885: None, 2611: None, 12887: None, 12889: None, 2482: None, 9511: None, 2275: None, 211: None, 12914: None, 497: None, 12916: None, 554: None, 12917: None, 12919: None, 12920: None, 12921: None, 1647: None, 6824: None, 12932: None, 12934: None, 12935: None, 12936: None, 5562: None, 12937: None, 12938: None, 1549: None, 12968: None, 12982: None, 12983: None, 204: None, 12985: None, 12986: None, 1871: None, 49: None, 12999: None, 13000: None, 13001: None, 56: None, 13003: None, 431: None, 13016: None, 13017: None, 13018: None, 13019: None, 64: None, 13043: None, 13047: None, 2209: None, 195: None, 1197: None, 1329: None, 22: None, 13058: None, 13061: None, 469: None, 11165: None, 2834: None, 5591: None, 13070: None, 13072: None, 13090: None, 2015: None, 13092: None, 2016: None, 13093: None, 565: None, 13109: None, 11117: None, 4753: None, 105: None, 7: None, 13129: None, 13130: None, 2281: None, 13134: None, 13135: None, 117: None, 13151: None, 4187: None, 13153: None, 13154: None, 13159: None, 13162: None, 1668: None, 11719: None, 13210: None, 13213: None, 8733: None, 4097: None, 401: None, 13217: None, 13218: None, 13221: None, 171: None, 3057: None, 13248: None, 100: None, 1822: None, 1823: None, 13264: None, 13267: None, 13268: None, 1101: None, 10724: None, 9814: None, 13293: None, 13294: None, 13296: None, 13298: None, 13299: None, 12052: None, 13300: None, 13316: None, 13317: None, 13320: None, 13321: None, 13322: None, 13323: None, 11921: None, 13337: None, 3822: None, 13336: None, 5266: None, 5645: None, 184: None, 9007: None, 13362: None, 13371: None, 13372: None, 13373: None, 8634: None, 13374: None, 13376: None, 13377: None, 13394: None, 146: None, 8102: None, 13399: None, 13417: None, 13418: None, 8345: None, 13354: None, 9012: None, 414: None, 1272: None, 13436: None, 2678: None, 2675: None, 13439: None, 13458: None, 13463: None, 13464: None, 13468: None, 13469: None, 13470: None, 13472: None, 13473: None, 13484: None, 3382: None, 3483: None, 13489: None, 13490: None, 13491: None, 529: None, 7543: None, 13510: None, 13512: None, 13515: None, 2282: None, 13531: None, 13533: None, 13534: None, 13536: None, 3909: None, 13562: None, 13563: None, 13564: None, 13565: None, 13566: None, 5451: None, 2434: None, 13586: None, 13610: None, 13613: None, 13614: None, 13624: None, 9599: None, 13625: None, 13626: None, 13628: None, 6543: None, 2484: None, 9127: None, 13641: None, 13642: None, 8990: None, 9632: None, 13643: None, 10940: None, 13644: None, 8882: None, 13648: None, 13649: None, 13650: None, 13651: None, 688: None, 13652: None, 13653: None, 1564: None, 13660: None, 13661: None, 13664: None, 13667: None, 13669: None, 13670: None, 953: None, 13672: None, 13678: None, 13679: None, 13680: None, 12456: None, 9865: None, 6283: None, 13683: None, 12022: None, 13688: None, 13699: None, 13700: None, 13703: None, 13707: None, 13708: None, 13722: None, 1851: None, 13723: None, 13724: None, 13725: None, 9812: None, 11777: None, 13738: None, 13740: None, 13741: None, 13742: None, 13743: None, 13746: None, 13748: None, 1221: None, 971: None, 2767: None, 6871: None, 13768: None, 13771: None, 13773: None, 13774: None, 13775: None, 13634: None, 13785: None, 703: None, 704: None, 1046: None, 1396: None, 5499: None, 13795: None, 13797: None, 13798: None, 13800: None, 13802: None, 13803: None, 1593: None, 13806: None, 13809: None, 13811: None, 13812: None, 13813: None, 13814: None, 13815: None, 880: None, 13817: None, 2940: None, 12679: None, 2694: None, 13829: None, 13830: None, 13832: None, 13833: None, 13834: None, 6968: None, 13836: None, 13845: None, 8205: None, 13848: None, 13849: None, 13851: None, 13852: None, 13853: None, 5141: None, 13856: None, 13858: None, 13859: None, 13140: None, 13870: None, 13871: None, 13874: None, 13875: None, 13876: None, 13877: None, 13881: None, 1670: None, 13617: None, 13620: None, 13904: None, 3727: None, 13906: None, 12332: None, 13715: None, 13932: None, 13933: None, 13937: None, 13940: None, 13941: None, 1996: None, 13954: None, 13958: None, 13959: None, 13960: None, 13961: None, 1787: None, 13077: None, 13973: None, 13974: None, 13975: None, 13976: None, 13978: None, 13994: None, 13998: None, 11216: None, 13999: None, 14002: None, 3073: None, 14004: None, 14005: None, 14006: None, 14007: None, 14020: None, 14022: None, 14023: None, 14024: None, 1504: None, 1208: None, 14031: None, 14032: None, 14033: None, 1361: None, 14053: None, 14055: None, 518: None, 14065: None, 14066: None, 14067: None, 1729: None, 1730: None, 14088: None, 14091: None, 14093: None, 14101: None, 14102: None, 4400: None, 14116: None, 14118: None, 14119: None, 14120: None, 5638: None, 14121: None, 444: None, 14135: None, 14137: None, 3098: None, 1128: None, 14057: None, 14146: None, 14148: None, 328: None, 14163: None, 14164: None, 14166: None, 14173: None, 432: None, 500: None, 506: None, 1299: None, 14178: None, 14180: None, 4462: None, 4463: None, 14186: None, 14187: None, 14188: None, 14189: None, 14193: None, 14195: None, 14200: None, 14202: None, 14203: None, 5220: None, 241: None, 14207: None, 14209: None, 14214: None, 14215: None, 13020: None, 9018: None, 3316: None, 7922: None, 14220: None, 7924: None, 20: None, 14222: None, 12551: None, 12552: None, 12556: None, 367: None, 10141: None, 4959: None, 12565: None, 6624: None, 216: None, 225: None, 223: None, 9517: None, 12572: None, 1169: None, 1348: None, 12574: None, 5222: None, 12576: None, 3595: None, 12577: None, 1680: None, 12584: None, 12587: None, 12588: None, 6895: None, 2497: None, 235: None, 534: None, 5044: None, 830: None, 9626: None, 434: None, 12610: None, 12611: None, 12613: None, 12614: None, 47: None, 12615: None, 12281: None, 1076: None, 8104: None, 12632: None, 12633: None, 12634: None, 12636: None, 12637: None, 12638: None, 12640: None, 11280: None, 12641: None, 4957: None, 12646: None, 12647: None, 5989: None, 387: None, 12652: None, 12653: None, 8283: None, 375: None, 12655: None, 12656: None, 12657: None, 12658: None, 12668: None, 8956: None, 814: None, 12671: None, 12672: None, 12673: None, 12674: None, 9458: None, 4648: None, 1383: None, 12685: None, 12686: None, 12688: None, 12689: None, 12692: None, 7577: None, 12698: None, 4427: None, 12702: None, 12703: None, 12704: None, 12705: None, 12707: None, 12708: None, 2753: None, 12729: None, 12731: None, 12734: None, 12735: None, 12738: None, 12739: None, 12740: None, 12742: None, 298: None, 12744: None, 12745: None, 12751: None, 4195: None, 12752: None, 12753: None, 900: None, 12756: None, 2524: None, 12761: None, 12762: None, 12764: None, 9008: None, 12767: None, 12769: None, 12771: None, 12773: None, 12775: None, 1470: None, 1407: None, 3784: None, 12796: None, 11246: None, 12802: None, 153: None, 12804: None, 12806: None, 12808: None, 12809: None, 2048: None, 8746: None, 12817: None, 12818: None, 12819: None, 12820: None, 12821: None, 12863: None, 8066: None, 8067: None, 438: None, 12867: None, 12876: None, 12894: None, 2607: None, 12897: None, 12899: None, 6933: None, 12901: None, 12909: None, 7642: None, 12912: None, 12913: None, 12333: None, 10924: None, 879: None, 12928: None, 12929: None, 12147: None, 10411: None, 12940: None, 12941: None, 12942: None, 12943: None, 12184: None, 4086: None, 10366: None, 12951: None, 11294: None, 12954: None, 12955: None, 12957: None, 12959: None, 12960: None, 12961: None, 12964: None, 12965: None, 12970: None, 12971: None, 12972: None, 12973: None, 12976: None, 12978: None, 12979: None, 12988: None, 5146: None, 2830: None, 12991: None, 12996: None, 11363: None, 13005: None, 13006: None, 13007: None, 13009: None, 13010: None, 13011: None, 13012: None, 13022: None, 13023: None, 220: None, 13026: None, 11043: None, 3488: None, 3162: None, 13033: None, 13036: None, 13038: None, 3572: None, 13039: None, 7119: None, 9601: None, 7478: None, 13051: None, 13052: None, 13053: None, 13054: None, 13055: None, 12294: None, 13063: None, 12292: None, 3688: None, 3063: None, 9473: None, 13066: None, 5168: None, 165: None, 3381: None, 6863: None, 7542: None, 5422: None, 13080: None, 6964: None, 2863: None, 13084: None, 13086: None, 13087: None, 1581: None, 7436: None, 9162: None, 200: None, 5397: None, 4604: None, 13103: None, 13105: None, 13106: None, 13112: None, 292: None, 13114: None, 2055: None, 13120: None, 13122: None, 13123: None, 13126: None, 8325: None, 11046: None, 9790: None, 13138: None, 13139: None, 13142: None, 13146: None, 13164: None, 13165: None, 13166: None, 9870: None, 13169: None, 13170: None, 1474: None, 1300: None, 12726: None, 13173: None, 13175: None, 13176: None, 13178: None, 601: None, 13179: None, 13181: None, 13182: None, 13183: None, 13185: None, 9791: None, 13201: None, 13204: None, 7677: None, 13206: None, 1441: None, 6900: None, 7040: None, 13228: None, 13230: None, 245: None, 242: None, 13232: None, 13233: None, 13234: None, 13236: None, 13237: None, 13238: None, 13240: None, 13241: None, 13242: None, 13243: None, 10759: None, 13252: None, 13254: None, 13256: None, 13257: None, 13259: None, 13261: None, 13262: None, 13274: None, 13275: None, 13279: None, 13280: None, 13281: None, 13284: None, 13285: None, 13286: None, 13288: None, 13289: None, 2038: None, 13306: None, 13308: None, 8133: None, 13310: None, 13312: None, 13313: None, 13326: None, 13328: None, 13329: None, 13330: None, 13332: None, 13333: None, 13340: None, 13341: None, 13342: None, 13343: None, 13346: None, 13347: None, 13350: None, 2571: None, 1896: None, 13353: None, 10843: None, 2752: None, 13368: None, 1899: None, 13379: None, 3942: None, 13382: None, 13384: None, 262: None, 544: None, 13386: None, 13387: None, 13390: None, 13391: None, 13392: None, 2984: None, 13404: None, 13407: None, 13409: None, 13411: None, 13415: None, 13422: None, 10013: None, 1385: None, 5265: None, 13430: None, 13431: None, 13432: None, 13442: None, 13444: None, 13446: None, 13448: None, 8149: None, 422: None, 3318: None, 13453: None, 13454: None, 13455: None, 2651: None, 2380: None, 2379: None, 7667: None, 13477: None, 13478: None, 2143: None, 13480: None, 1283: None, 5565: None, 13493: None, 13494: None, 13495: None, 5095: None, 9959: None, 13: None, 697: None, 6577: None, 13502: None, 13503: None, 3773: None, 13521: None, 13522: None, 13523: None, 13529: None, 13538: None, 13539: None, 13540: None, 13541: None, 13542: None, 13545: None, 5088: None, 148: None, 13552: None, 13554: None, 13555: None, 13556: None, 493: None, 11697: None, 13559: None, 1126: None, 3747: None, 13569: None, 13570: None, 13572: None, 13573: None, 13574: None, 2903: None, 13621: None, 676: None, 13630: None, 5515: None, 13633: None, 13635: None, 396: None, 5059: None, 5619: None, 5197: None, 13674: None, 5226: None, 13675: None, 13676: None, 1533: None, 13711: None, 13716: None, 13718: None, 13719: None, 13729: None, 13733: None, 10905: None, 2210: None, 13750: None, 13752: None, 13755: None, 13759: None, 13760: None, 13777: None, 13778: None, 13780: None, 13782: None, 13783: None, 1134: None, 13789: None, 13793: None, 3433: None, 3432: None, 13822: None, 13823: None, 13824: None, 13826: None, 13838: None, 8442: None, 9131: None, 13840: None, 13841: None, 10100: None, 8727: None, 8135: None, 2266: None, 13879: None, 8846: None, 13887: None, 13890: None, 12181: None, 12182: None, 13892: None, 13896: None, 13897: None, 13898: None, 13899: None, 13900: None, 13902: None, 13911: None, 13912: None, 13913: None, 13916: None, 618: None, 13919: None, 13920: None, 13921: None, 13922: None, 13924: None, 13929: None, 13943: None, 1050: None, 13946: None, 13947: None, 13949: None, 6322: None, 13951: None, 13963: None, 13967: None, 13970: None, 13971: None, 13980: None, 13981: None, 2814: None, 13984: None, 13986: None, 13987: None, 13988: None, 13989: None, 13990: None, 8708: None, 14009: None, 14011: None, 14012: None, 14043: None, 14046: None, 14047: None, 14048: None, 14049: None, 14050: None, 8508: None, 14061: None, 14062: None, 6716: None, 6717: None, 14063: None, 14070: None, 14073: None, 14083: None, 14084: None, 5215: None, 552: None, 1432: None, 9506: None, 202: None, 14104: None, 14105: None, 14107: None, 14108: None, 14110: None, 14111: None, 14112: None, 14113: None, 14123: None, 14125: None, 14126: None, 9465: None, 14130: None, 14131: None, 5761: None, 11042: None, 1062: None, 8729: None, 14150: None, 14154: None, 14157: None, 14158: None, 14159: None, 14160: None, 2686: None, 4532: None, 2687: None, 14168: None, 14169: None, 6401: None, 2684: None, 134: None}
In generate_master_entity_list(): master entity ID list length: 1088 ( list: [7, 13, 16, 20, 22, 47, 49, 56, 62, 64, 69, 100, 104, 105, 117, 132, 134, 146, 148, 153, 165, 171, 177, 184, 195, 200, 202, 204, 211, 216, 218, 220, 221, 223, 225, 235, 238, 240, 241, 242, 245, 262, 274, 275, 292, 298, 316, 328, 367, 375, 380, 384, 387, 396, 401, 414, 422, 424, 431, 432, 434, 437, 438, 440, 444, 469, 493, 497, 500, 506, 518, 529, 534, 544, 552, 554, 565, 593, 601, 618, 667, 676, 687, 688, 697, 703, 704, 721, 814, 830, 866, 876, 879, 880, 900, 953, 971, 972, 974, 975, 1046, 1050, 1062, 1076, 1101, 1126, 1128, 1134, 1169, 1179, 1185, 1197, 1208, 1221, 1272, 1283, 1299, 1300, 1329, 1348, 1361, 1383, 1384, 1385, 1396, 1407, 1432, 1441, 1470, 1474, 1504, 1533, 1549, 1564, 1581, 1593, 1647, 1668, 1670, 1680, 1683, 1729, 1730, 1787, 1822, 1823, 1851, 1871, 1896, 1898, 1899, 1969, 1996, 2015, 2016, 2038, 2048, 2055, 2143, 2209, 2210, 2266, 2275, 2281, 2282, 2330, 2379, 2380, 2434, 2482, 2484, 2497, 2522, 2524, 2571, 2607, 2611, 2651, 2675, 2678, 2684, 2686, 2687, 2694, 2752, 2753, 2767, 2814, 2830, 2834, 2863, 2870, 2903, 2940, 2984, 3057, 3063, 3073, 3098, 3162, 3316, 3318, 3350, 3381, 3382, 3432, 3433, 3483, 3488, 3572, 3595, 3688, 3727, 3747, 3773, 3784, 3821, 3822, 3909, 3942, 4086, 4097, 4187, 4195, 4400, 4422, 4427, 4462, 4463, 4532, 4575, 4604, 4648, 4753, 4857, 4957, 4959, 5044, 5059, 5088, 5095, 5141, 5146, 5168, 5197, 5215, 5220, 5222, 5226, 5246, 5265, 5266, 5397, 5422, 5451, 5499, 5515, 5527, 5562, 5565, 5591, 5619, 5638, 5645, 5653, 5761, 5813, 5989, 6283, 6322, 6401, 6543, 6548, 6577, 6624, 6716, 6717, 6824, 6863, 6871, 6895, 6900, 6933, 6964, 6968, 7040, 7119, 7436, 7478, 7542, 7543, 7577, 7642, 7667, 7677, 7922, 7924, 7972, 8066, 8067, 8102, 8104, 8133, 8135, 8149, 8205, 8283, 8325, 8345, 8442, 8508, 8634, 8708, 8727, 8729, 8733, 8746, 8846, 8882, 8956, 8990, 9007, 9008, 9012, 9018, 9127, 9131, 9162, 9458, 9465, 9473, 9506, 9511, 9517, 9599, 9601, 9603, 9626, 9632, 9790, 9791, 9812, 9814, 9865, 9870, 9959, 10013, 10091, 10100, 10141, 10366, 10411, 10724, 10759, 10804, 10843, 10905, 10924, 10940, 11042, 11043, 11046, 11117, 11165, 11185, 11216, 11246, 11280, 11294, 11363, 11593, 11697, 11719, 11777, 11921, 12022, 12052, 12147, 12181, 12182, 12184, 12279, 12281, 12292, 12294, 12332, 12333, 12439, 12456, 12492, 12493, 12551, 12552, 12555, 12556, 12558, 12559, 12565, 12572, 12574, 12576, 12577, 12584, 12587, 12588, 12593, 12594, 12597, 12600, 12607, 12610, 12611, 12613, 12614, 12615, 12619, 12621, 12623, 12625, 12627, 12628, 12632, 12633, 12634, 12636, 12637, 12638, 12640, 12641, 12643, 12646, 12647, 12652, 12653, 12655, 12656, 12657, 12658, 12660, 12661, 12663, 12664, 12665, 12666, 12668, 12671, 12672, 12673, 12674, 12679, 12680, 12685, 12686, 12688, 12689, 12692, 12698, 12702, 12703, 12704, 12705, 12707, 12708, 12714, 12715, 12717, 12722, 12726, 12729, 12731, 12734, 12735, 12738, 12739, 12740, 12742, 12744, 12745, 12747, 12748, 12750, 12751, 12752, 12753, 12756, 12758, 12760, 12761, 12762, 12764, 12767, 12769, 12771, 12773, 12775, 12781, 12783, 12792, 12793, 12796, 12802, 12804, 12806, 12808, 12809, 12817, 12818, 12819, 12820, 12821, 12854, 12859, 12863, 12867, 12876, 12880, 12881, 12884, 12885, 12887, 12889, 12894, 12897, 12899, 12901, 12909, 12912, 12913, 12914, 12916, 12917, 12919, 12920, 12921, 12928, 12929, 12932, 12934, 12935, 12936, 12937, 12938, 12940, 12941, 12942, 12943, 12951, 12954, 12955, 12957, 12959, 12960, 12961, 12964, 12965, 12968, 12970, 12971, 12972, 12973, 12976, 12978, 12979, 12982, 12983, 12985, 12986, 12988, 12991, 12996, 12999, 13000, 13001, 13003, 13005, 13006, 13007, 13009, 13010, 13011, 13012, 13016, 13017, 13018, 13019, 13020, 13022, 13023, 13026, 13033, 13036, 13038, 13039, 13043, 13047, 13051, 13052, 13053, 13054, 13055, 13058, 13061, 13063, 13066, 13070, 13072, 13077, 13080, 13084, 13086, 13087, 13090, 13092, 13093, 13103, 13105, 13106, 13109, 13112, 13114, 13120, 13122, 13123, 13126, 13129, 13130, 13134, 13135, 13138, 13139, 13140, 13142, 13146, 13151, 13153, 13154, 13159, 13162, 13164, 13165, 13166, 13169, 13170, 13173, 13175, 13176, 13178, 13179, 13181, 13182, 13183, 13185, 13201, 13204, 13206, 13210, 13213, 13217, 13218, 13221, 13228, 13230, 13232, 13233, 13234, 13236, 13237, 13238, 13240, 13241, 13242, 13243, 13248, 13252, 13254, 13256, 13257, 13259, 13261, 13262, 13264, 13267, 13268, 13274, 13275, 13279, 13280, 13281, 13284, 13285, 13286, 13288, 13289, 13293, 13294, 13296, 13298, 13299, 13300, 13306, 13308, 13310, 13312, 13313, 13316, 13317, 13320, 13321, 13322, 13323, 13326, 13328, 13329, 13330, 13332, 13333, 13336, 13337, 13340, 13341, 13342, 13343, 13346, 13347, 13350, 13353, 13354, 13362, 13368, 13371, 13372, 13373, 13374, 13376, 13377, 13379, 13382, 13384, 13386, 13387, 13390, 13391, 13392, 13394, 13399, 13404, 13407, 13409, 13411, 13415, 13417, 13418, 13422, 13430, 13431, 13432, 13436, 13439, 13442, 13444, 13446, 13448, 13453, 13454, 13455, 13458, 13463, 13464, 13468, 13469, 13470, 13472, 13473, 13477, 13478, 13480, 13484, 13489, 13490, 13491, 13493, 13494, 13495, 13502, 13503, 13510, 13512, 13515, 13521, 13522, 13523, 13529, 13531, 13533, 13534, 13536, 13538, 13539, 13540, 13541, 13542, 13545, 13552, 13554, 13555, 13556, 13559, 13562, 13563, 13564, 13565, 13566, 13569, 13570, 13572, 13573, 13574, 13586, 13610, 13613, 13614, 13617, 13620, 13621, 13624, 13625, 13626, 13628, 13630, 13633, 13634, 13635, 13641, 13642, 13643, 13644, 13648, 13649, 13650, 13651, 13652, 13653, 13660, 13661, 13664, 13667, 13669, 13670, 13672, 13674, 13675, 13676, 13678, 13679, 13680, 13683, 13688, 13699, 13700, 13703, 13707, 13708, 13711, 13715, 13716, 13718, 13719, 13722, 13723, 13724, 13725, 13729, 13733, 13738, 13740, 13741, 13742, 13743, 13746, 13748, 13750, 13752, 13755, 13759, 13760, 13768, 13771, 13773, 13774, 13775, 13777, 13778, 13780, 13782, 13783, 13785, 13789, 13793, 13795, 13797, 13798, 13800, 13802, 13803, 13806, 13809, 13811, 13812, 13813, 13814, 13815, 13817, 13822, 13823, 13824, 13826, 13829, 13830, 13832, 13833, 13834, 13836, 13838, 13840, 13841, 13845, 13848, 13849, 13851, 13852, 13853, 13856, 13858, 13859, 13870, 13871, 13874, 13875, 13876, 13877, 13879, 13881, 13887, 13890, 13892, 13896, 13897, 13898, 13899, 13900, 13902, 13904, 13906, 13911, 13912, 13913, 13916, 13919, 13920, 13921, 13922, 13924, 13929, 13932, 13933, 13937, 13940, 13941, 13943, 13946, 13947, 13949, 13951, 13954, 13958, 13959, 13960, 13961, 13963, 13967, 13970, 13971, 13973, 13974, 13975, 13976, 13978, 13980, 13981, 13984, 13986, 13987, 13988, 13989, 13990, 13994, 13998, 13999, 14002, 14004, 14005, 14006, 14007, 14009, 14011, 14012, 14020, 14022, 14023, 14024, 14031, 14032, 14033, 14043, 14046, 14047, 14048, 14049, 14050, 14053, 14055, 14057, 14061, 14062, 14063, 14065, 14066, 14067, 14070, 14073, 14083, 14084, 14088, 14091, 14093, 14101, 14102, 14104, 14105, 14107, 14108, 14110, 14111, 14112, 14113, 14116, 14118, 14119, 14120, 14121, 14123, 14125, 14126, 14130, 14131, 14135, 14137, 14146, 14148, 14150, 14154, 14157, 14158, 14159, 14160, 14163, 14164, 14166, 14168, 14169, 14173, 14178, 14180, 14186, 14187, 14188, 14189, 14193, 14195, 14200, 14202, 14203, 14207, 14209, 14214, 14215, 14220, 14222] )
In context.export.network.ndo_tab_delimited_matrix.NDO_TabDelimitedMatrix.render(): Master entity list created, rendering network data @ 2020-02-04 21:38:42.275018
In context.export.network.network_output.NetworkOutput.render_network_data(): After calling NetworkDataOutput.render(), doing output @ 2020-02-04 21:39:17.897726
In context.export.network.network_output.NetworkOutput.render_network_data(): Finished @ 2020-02-04 21:39:17.900605

In [14]:
ndo_instance = network_output.m_NDO_instance
test1 = ndo_instance.get_entity_relation_type_summary_dict()
print( test1 )

test2 = ndo_instance.m_relation_type_slug_list
print( "\n\nEntity_Relation_Type slug list: {}".format( test2 ) )

test3 = ndo_instance.m_relation_type_slug_to_instance_map
print( "\n\nEntity_Relation_Type slug to instance map: {}".format( test3 ) )


{35: {'quoted': {'FROM': 1, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 1, 'TO': 0, 'THROUGH': 0}}, 36: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 18: {'quoted': {'FROM': 6, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 7, 'TO': 0, 'THROUGH': 0}}, 24: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 23: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 22: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 21: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 20: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 19: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 25: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 8: {'shared_byline': {'FROM': 1, 'TO': 1, 'THROUGH': 0}, 'quoted': {'FROM': 4, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 7, 'TO': 0, 'THROUGH': 0}}, 9: {'shared_byline': {'FROM': 1, 'TO': 1, 'THROUGH': 0}, 'quoted': {'FROM': 9, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 24, 'TO': 0, 'THROUGH': 0}}, 16: {'quoted': {'FROM': 0, 'TO': 2, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 2, 'THROUGH': 0}}, 13: {'quoted': {'FROM': 0, 'TO': 2, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 2, 'THROUGH': 0}}, 12: {'quoted': {'FROM': 0, 'TO': 2, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 2, 'THROUGH': 0}}, 11: {'quoted': {'FROM': 0, 'TO': 2, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 2, 'THROUGH': 0}}, 15: {'mentioned': {'FROM': 0, 'TO': 2, 'THROUGH': 0}}, 14: {'mentioned': {'FROM': 0, 'TO': 2, 'THROUGH': 0}}, 10: {'mentioned': {'FROM': 0, 'TO': 2, 'THROUGH': 0}}, 80: {'quoted': {'FROM': 3, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 3, 'TO': 0, 'THROUGH': 0}}, 83: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 82: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 81: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 69: {'quoted': {'FROM': 3, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 3, 'TO': 0, 'THROUGH': 0}}, 72: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 71: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 70: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 46: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 44: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 40: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 47: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 45: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 43: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 42: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 41: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 39: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 38: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 32: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 28: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 33: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 31: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 30: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 29: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 27: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 85: {'quoted': {'FROM': 2, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 5, 'TO': 0, 'THROUGH': 0}}, 89: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 87: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 90: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 88: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 86: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 74: {'quoted': {'FROM': 4, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 4, 'TO': 0, 'THROUGH': 0}}, 78: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 77: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 76: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 75: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 63: {'quoted': {'FROM': 4, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 4, 'TO': 0, 'THROUGH': 0}}, 67: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 66: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 65: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 64: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 49: {'quoted': {'FROM': 3, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 4, 'TO': 0, 'THROUGH': 0}}, 53: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 52: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 51: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 50: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 55: {'quoted': {'FROM': 3, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 6, 'TO': 0, 'THROUGH': 0}}, 61: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 59: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 58: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 60: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 57: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 56: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}}


Entity_Relation_Type slug list: ['mentioned', 'quoted', 'shared_byline']


Entity_Relation_Type slug to instance map: {'quoted': <Entity_Relation_Type: 1 - quoted - quoted>, 'mentioned': <Entity_Relation_Type: 2 - mentioned - mentioned>, 'shared_byline': <Entity_Relation_Type: 3 - shared_byline - Shared Byline>}

Network output

Convert code from using Article_Data to derive ties to just loop over Entity_Relation instances.

Network output - sourcenet logic

Network output - sourcenet logic - NetworkOutput

Pseudocode:

  • NetworkOutput.render_network_data( query_set_IN )

    • accepts Article_Data QuerySet.
    • create person dictionary - self.create_person_dict()

      • retrieve Article_Data QuerySet to traverse to pull in all authors and subjects - self.create_person_query_set()

        • if ALL, return all Article_Data
        • if type of articles, retrieve just those specified as being used for ties - self.create_person_query_set()
        • if type of custom, retrieve Article_Data to match custom person lookup parameters - self.create_query_set( NetworkOutput.PARAM_PERSON_PREFIX )
      • for each Article_Data:

        • retrieve author and source QuerySets.
        • for each, call self.add_people_to_dict() on the QuerySet.

          • for each person, retrieve person instance and ID, add to dictionary, storing instance as value if store_person_IN == True.
      • return dictionary into "person_dictionary".

    • get NetworkDataOutput (NDO) instance - self.get_NDO_instance()

    • initialize NDO

      • NDO.set_query_set( query_set_IN )
      • NDO.set_person_dictionary( person_dictionary )
      • initialize from parameters: NDO.initialize_from_params()
    • render - NDO.render()

Network output - sourcenet logic - NetworkDataOutput

Pseudocode:

  • NetworkDataOutput.render()

    • get query_set and person_dictionary.
    • create ties

      • loop over query_set:

        • check if authors. If none, move on.
        • if authors:

          • retrieve author and sources QuerySets from Article_Data
          • process author relations (shared byline and qouted): self.process_author_relations( author_qs, source_qs )

            • makes list of author IDs in Article_Data by building dictionary that maps author person ID to author Person instance, then getting .keys().
            • loops over authors:

              • - for each, pop from dictionary, make relation to all authors remaining in the dictionary (bi-directional, so just need to make relations to people past the current in the list): self.add_reciprocal_relation() - adds bidirectional ties between authors in nested connection map (calls self.add_directed_relation( person_1_id_IN, person_2_id_IN ), then self.add_directed_relation( person_2_id_IN, person_1_id_IN )). - self.add_directed_relation(): updates self.relation_map, map of FROM IDs to dictionary of TO IDs, where each TO maps to a count of the ties between the two. Solely ID-based, so methods to add relations can stay as-is! Yay! - set person's type to "author": self.update_person_type( current_person_id, NetworkDataOutput.PERSON_TYPE_AUTHOR ) - accepts person ID and type. - looks for person ID in self.person_type_dict. - If not present, adds current type. - If present but not same as what is passed in, sets to BOTH. - add relations to sources: self.process_source_relations( current_person_id, source_qs_IN ) - accepts author ID and source QuerySet. - if author ID and source QuerySet has something in it, proceeds. - checks if source is connected: self.is_source_connected( current_source ) - calls Article_Subject.is_connected( self.inclusion_params ) - if connected, retrieves person ID for source, if source has ID adds reciprocal relation between author and source: self.add_reciprocal_relation().
          • update the types of the sources (from source_qs): self.update_source_person_types( source_qs )

            • for each source, calls self.update_person_type( current_person_id, NetworkDataOutput.PERSON_TYPE_SOURCE )
      • build master person list: self.generate_master_person_list()

        • combines the person dictionary with dictionary that maps person to source type based on Article_Data processed for ties.
      • actually render the network data: self.render_network_data()

        • based on output parameters, implemented in NDO child classes.

Network output - context logic

Network output - context logic - NetworkOutput

Pseudocode:

  • NetworkOutput.render_network_data( relation_qs_IN, network_data_request_IN )

    • accepts optional Entity_Relation QuerySet and optional request.
    • create entity dictionary - self.create_entity_dict()

      • retrieve Entity_Relation QuerySet to traverse to pull in all relations - network_data_request.filter_relation_query_set( use_entity_selection_IN = True )
      • call self.add_entities_to_dict() to add entities from the relation QuerySet.

        • loops over relations, retrieves FROM, TO, and optionally THROUGH entities, calls self.add_entity_to_dict() on each entity to be added.

          • for each entity, retrieve Entity instance and ID, add to dictionary, storing instance as value if store_entity_IN == True.
      • return dictionary into "entity_dictionary".

    • get NetworkDataOutput (NDO) instance - self.get_NDO_instance()

    • initialize NDO

      • NDO.set_query_set( query_set_IN )
      • NDO.set_entity_dictionary( entity_dictionary )
      • initialize from request: NDO.initialize_from_request( network_data_request )
    • render - NDO.render()

Network output - context logic - NetworkDataOutput

Pseudocode:

  • NetworkDataOutput.render()

    • get Entity_Relation query_set and entity_dictionary.
    • create ties

      • loop over query_set:

        • // retrieve FROM and TO entities.
        • // pull out their IDs.
        • // add relation - check if directed:

          • directed:

            • self.add_directed_relation( from_id, to_id )
          • not directed:

            • self.add_reciprocal_relation( from_id, to_id )
        • // update roles of entities...

          • one thought is to make a map of relation types for each person that maps to a dictionary of FROM, TO, and THROUGH, each mapped to counts of the times the person was in each role.
          • replaces:

            • calls to: self.update_person_type( current_person_id, NetworkDataOutput.PERSON_TYPE_SOURCE ) with update_entity_relations_details( self, entity_id_IN, relation_type_slug_IN, relation_role_IN ):
            • references to self.person_type_dict with something more nuanced (no longer can depend on a single type).
      • // build master entity list: self.generate_master_entity_list()

        • combines the person dictionary with dictionary that maps person to source type based on Article_Data processed for ties.
        • should be able to use it as is with some variable name changes.
        • // also, change name to "m_master_entity_list", and make a getter(), and then always retrieve using get().
      • actually render the network data: self.render_network_data()

        • based on output parameters, implemented in NDO child classes.

Context network output test code

Try loading the basic file and using it to render network data...


In [15]:
# load basic NetworkDataRequest
data_request_basic = TestHelper.load_basic()

In [16]:
# make and initialize instance of NetworkOutput
network_output = NetworkOutput()
network_output.set_network_data_request( data_request_basic )


Out[16]:
<context.export.network.network_data_request.NetworkDataRequest at 0x7f05157513c8>

In [17]:
# call render, see what happens.
network_data = network_output.render_network_data()


In get_selection_filters(): use_entity_selection_IN is True
In get_selection_filters(): "entity_selection" filtering was requested, but not specified in the request.  Defaulting to "relation_selection".
In get_selection_filters(): use_entity_selection_IN is False
In generate_master_entity_list: len( entity_dict ) = 72; entity_dict: {35: None, 36: None, 18: None, 24: None, 23: None, 22: None, 21: None, 20: None, 19: None, 25: None, 8: None, 9: None, 16: None, 13: None, 12: None, 11: None, 15: None, 14: None, 10: None, 80: None, 83: None, 82: None, 81: None, 69: None, 72: None, 71: None, 70: None, 46: None, 44: None, 40: None, 47: None, 45: None, 43: None, 42: None, 41: None, 39: None, 38: None, 32: None, 28: None, 33: None, 31: None, 30: None, 29: None, 27: None, 85: None, 89: None, 87: None, 90: None, 88: None, 86: None, 74: None, 78: None, 77: None, 76: None, 75: None, 63: None, 67: None, 66: None, 65: None, 64: None, 49: None, 53: None, 52: None, 51: None, 50: None, 55: None, 61: None, 59: None, 58: None, 60: None, 57: None, 56: None}
In generate_master_entity_list(): master entity ID list length: 72 ( list: [8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 35, 36, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 49, 50, 51, 52, 53, 55, 56, 57, 58, 59, 60, 61, 63, 64, 65, 66, 67, 69, 70, 71, 72, 74, 75, 76, 77, 78, 80, 81, 82, 83, 85, 86, 87, 88, 89, 90] )

In [14]:
ndo_instance = network_output.m_NDO_instance
test1 = ndo_instance.get_entity_relation_type_summary_dict()
print( test1 )

test2 = ndo_instance.m_relation_type_slug_list
print( "\n\nEntity_Relation_Type slug list: {}".format( test2 ) )

test3 = ndo_instance.m_relation_type_slug_to_instance_map
print( "\n\nEntity_Relation_Type slug to instance map: {}".format( test3 ) )


{35: {'quoted': {'FROM': 1, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 1, 'TO': 0, 'THROUGH': 0}}, 36: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 18: {'quoted': {'FROM': 6, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 7, 'TO': 0, 'THROUGH': 0}}, 24: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 23: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 22: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 21: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 20: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 19: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 25: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 8: {'shared_byline': {'FROM': 1, 'TO': 1, 'THROUGH': 0}, 'quoted': {'FROM': 4, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 7, 'TO': 0, 'THROUGH': 0}}, 9: {'shared_byline': {'FROM': 1, 'TO': 1, 'THROUGH': 0}, 'quoted': {'FROM': 9, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 24, 'TO': 0, 'THROUGH': 0}}, 16: {'quoted': {'FROM': 0, 'TO': 2, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 2, 'THROUGH': 0}}, 13: {'quoted': {'FROM': 0, 'TO': 2, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 2, 'THROUGH': 0}}, 12: {'quoted': {'FROM': 0, 'TO': 2, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 2, 'THROUGH': 0}}, 11: {'quoted': {'FROM': 0, 'TO': 2, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 2, 'THROUGH': 0}}, 15: {'mentioned': {'FROM': 0, 'TO': 2, 'THROUGH': 0}}, 14: {'mentioned': {'FROM': 0, 'TO': 2, 'THROUGH': 0}}, 10: {'mentioned': {'FROM': 0, 'TO': 2, 'THROUGH': 0}}, 80: {'quoted': {'FROM': 3, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 3, 'TO': 0, 'THROUGH': 0}}, 83: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 82: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 81: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 69: {'quoted': {'FROM': 3, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 3, 'TO': 0, 'THROUGH': 0}}, 72: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 71: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 70: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 46: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 44: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 40: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 47: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 45: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 43: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 42: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 41: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 39: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 38: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 32: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 28: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 33: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 31: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 30: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 29: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 27: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 85: {'quoted': {'FROM': 2, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 5, 'TO': 0, 'THROUGH': 0}}, 89: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 87: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 90: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 88: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 86: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 74: {'quoted': {'FROM': 4, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 4, 'TO': 0, 'THROUGH': 0}}, 78: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 77: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 76: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 75: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 63: {'quoted': {'FROM': 4, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 4, 'TO': 0, 'THROUGH': 0}}, 67: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 66: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 65: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 64: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 49: {'quoted': {'FROM': 3, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 4, 'TO': 0, 'THROUGH': 0}}, 53: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 52: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 51: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 50: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 55: {'quoted': {'FROM': 3, 'TO': 0, 'THROUGH': 0}, 'mentioned': {'FROM': 6, 'TO': 0, 'THROUGH': 0}}, 61: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 59: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 58: {'quoted': {'FROM': 0, 'TO': 1, 'THROUGH': 0}, 'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 60: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 57: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}, 56: {'mentioned': {'FROM': 0, 'TO': 1, 'THROUGH': 0}}}


Entity_Relation_Type slug list: ['mentioned', 'quoted', 'shared_byline']


Entity_Relation_Type slug to instance map: {'quoted': <Entity_Relation_Type: 1 - quoted - quoted>, 'mentioned': <Entity_Relation_Type: 2 - mentioned - mentioned>, 'shared_byline': <Entity_Relation_Type: 3 - shared_byline - Shared Byline>}

Building Unit Tests

Code to test out and find answers for unit tests.


In [17]:
# randomly pick 5 or so relations that have THROUGH.
relation_qs = Entity_Relation.objects.all()
relation_qs = relation_qs.exclude( relation_through__isnull = True )
relation_qs = relation_qs.order_by('?')[:5]
relation_count = len( relation_qs )
print( "relation count: {}".format( relation_count ) )


relation count: 5

In [21]:
# randomly pick 5 or so relations that have THROUGH.
relation_qs = Entity_Relation.objects.all()
relation_qs = relation_qs.exclude( pk__in = [ 1101, 1245, 2264, 2687, 2973 ] )
relation_qs = relation_qs.filter( relation_from__in = [ 80, 128, 147, 151, 246, 248, 271, 279, 288, 291 ] )
relation_qs = relation_qs.order_by('?')[:5]
relation_count = len( relation_qs )
print( "relation count: {}".format( relation_count ) )

# loop
for relation in relation_qs:
    
    print( "Relation ID: {}".format( relation.id ) )
    
#-- END loop over relations --#


relation count: 5
Relation ID: 2638
Relation ID: 3086
Relation ID: 2271
Relation ID: 2595
Relation ID: 2288

In [23]:
relation_id_list = [ 1101, 1245, 2264, 2271, 2288, 2595, 2638, 2687, 2973, 3086 ]
#relation_id_list = TestHelper.TEST_RELATION_IDS_WITH_THROUGH
relation_qs = Entity_Relation.objects.all()
relation_qs = relation_qs.filter( pk__in = relation_id_list )

print( "relation count: {}".format( relation_count ) )

# loop
for relation in relation_qs:
    
    print( "Relation ID: {}".format( relation.id ) )
    
#-- END loop over relations --#


relation count: 5
Relation ID: 1101
Relation ID: 1245
Relation ID: 2264
Relation ID: 2271
Relation ID: 2288
Relation ID: 2595
Relation ID: 2638
Relation ID: 2687
Relation ID: 2973
Relation ID: 3086

In [25]:
# declare variables
relation_id_list = None
relation = None
relation_id = None
relation_from = None
relation_from_id = None
relation_to = None
relation_to_id = None
relation_through = None
relation_through_id = None
from_to_entity_id_list = None
all_entity_id_list = None
relation_counter = None

# init
relation_id_list = []
from_to_entity_id_list = []
all_entity_id_list = []

# loop
relation_counter = 0
for relation in relation_qs:
    
    # increment counter
    relation_counter += 1
    
    # get relation ID
    relation_id = relation.id
    
    # add it to list?
    if ( relation_id not in relation_id_list ):
    
        # not already in list.  Add it.
        relation_id_list.append( relation_id )
        relation_id_list.sort()
    
    #-- END check to see if ID already in list. --#
    
    # get entities
    relation_from = relation.relation_from
    relation_to = relation.relation_to
    relation_through = relation.relation_through
    
    # get IDs, check for each in entity ID lists
    relation_from_id = relation_from.id

    if ( relation_from_id not in from_to_entity_id_list ):
        
        # append it and sort.
        from_to_entity_id_list.append( relation_from_id )
        from_to_entity_id_list.sort()
        
    #-- END check to see if FROM in FROM-TO list --#
    
    if ( relation_from_id not in all_entity_id_list ):
        
        # append it and sort.
        all_entity_id_list.append( relation_from_id )
        all_entity_id_list.sort()
        
    #-- END check to see if FROM in FROM-TO list --#
    
    relation_to_id = relation_to.id

    if ( relation_to_id not in from_to_entity_id_list ):
        
        # append it and sort.
        from_to_entity_id_list.append( relation_to_id )
        from_to_entity_id_list.sort()
        
    #-- END check to see if FROM in FROM-TO list --#
    
    if ( relation_to_id not in all_entity_id_list ):
        
        # append it and sort.
        all_entity_id_list.append( relation_to_id )
        all_entity_id_list.sort()
        
    #-- END check to see if FROM in FROM-TO list --#
    
    relation_through_id = relation_through.id
    
    if ( relation_through_id not in all_entity_id_list ):
        
        # append it and sort.
        all_entity_id_list.append( relation_through_id )
        all_entity_id_list.sort()
        
    #-- END check to see if FROM in FROM-TO list --#
    
    print( "\n- after relation #{} - {}:".format( relation_counter, relation ) )
    print( "----> Relation ID List ( {} ): {}".format( len( relation_id_list ), relation_id_list ) )
    print( "----> from_to_entity_id_list ( {} ): {}".format( len( from_to_entity_id_list ), from_to_entity_id_list ) )
    print( "----> all_entity_id_list ( {} ): {}".format( len( all_entity_id_list ), all_entity_id_list ) )

#-- END loop over Relations --#

print( "Relation ID List ( {} ): {}".format( len( relation_id_list ), relation_id_list ) )
print( "from_to_entity_id_list ( {} ): {}".format( len( from_to_entity_id_list ), from_to_entity_id_list ) )
print( "all_entity_id_list ( {} ): {}".format( len( all_entity_id_list ), all_entity_id_list ) )


- after relation #1 - 1101 - FROM: 80 - context_text-Person-591 - TO: 128 - context_text-Person-1044 - THROUGH: 125 - context_text-Article-28846 - DIRECTED?: False - ( type: 2 - mentioned ):
----> Relation ID List ( 1 ): [1101]
----> from_to_entity_id_list ( 2 ): [80, 128]
----> all_entity_id_list ( 3 ): [80, 125, 128]

- after relation #2 - 1245 - FROM: 147 - context_text-Person-56 - TO: 151 - context_text-Person-170 - THROUGH: 146 - context_text-Article-91000 - DIRECTED?: False - ( type: 2 - mentioned ):
----> Relation ID List ( 2 ): [1101, 1245]
----> from_to_entity_id_list ( 4 ): [80, 128, 147, 151]
----> all_entity_id_list ( 6 ): [80, 125, 128, 146, 147, 151]

- after relation #3 - 2264 - FROM: 246 - context_text-Person-1016 - TO: 248 - context_text-Person-905 - THROUGH: 244 - context_text-Article-94125 - DIRECTED?: False - ( type: 9 - same_article_subjects ):
----> Relation ID List ( 3 ): [1101, 1245, 2264]
----> from_to_entity_id_list ( 6 ): [80, 128, 147, 151, 246, 248]
----> all_entity_id_list ( 9 ): [80, 125, 128, 146, 147, 151, 244, 246, 248]

- after relation #4 - 2271 - FROM: 246 - context_text-Person-1016 - TO: 253 - context_text-Person-438 - THROUGH: 244 - context_text-Article-94125 - DIRECTED?: False - ( type: 9 - same_article_subjects ):
----> Relation ID List ( 4 ): [1101, 1245, 2264, 2271]
----> from_to_entity_id_list ( 7 ): [80, 128, 147, 151, 246, 248, 253]
----> all_entity_id_list ( 10 ): [80, 125, 128, 146, 147, 151, 244, 246, 248, 253]

- after relation #5 - 2288 - FROM: 248 - context_text-Person-905 - TO: 245 - context_text-Person-1014 - THROUGH: 244 - context_text-Article-94125 - DIRECTED?: False - ( type: 9 - same_article_subjects ):
----> Relation ID List ( 5 ): [1101, 1245, 2264, 2271, 2288]
----> from_to_entity_id_list ( 8 ): [80, 128, 147, 151, 245, 246, 248, 253]
----> all_entity_id_list ( 11 ): [80, 125, 128, 146, 147, 151, 244, 245, 246, 248, 253]

- after relation #6 - 2595 - FROM: 147 - context_text-Person-56 - TO: 284 - context_text-Person-254 - THROUGH: 270 - context_text-Article-94311 - DIRECTED?: False - ( type: 1 - quoted ):
----> Relation ID List ( 6 ): [1101, 1245, 2264, 2271, 2288, 2595]
----> from_to_entity_id_list ( 9 ): [80, 128, 147, 151, 245, 246, 248, 253, 284]
----> all_entity_id_list ( 13 ): [80, 125, 128, 146, 147, 151, 244, 245, 246, 248, 253, 270, 284]

- after relation #7 - 2638 - FROM: 279 - context_text-Person-755 - TO: 277 - context_text-Person-251 - THROUGH: 270 - context_text-Article-94311 - DIRECTED?: False - ( type: 8 - same_article_sources ):
----> Relation ID List ( 7 ): [1101, 1245, 2264, 2271, 2288, 2595, 2638]
----> from_to_entity_id_list ( 11 ): [80, 128, 147, 151, 245, 246, 248, 253, 277, 279, 284]
----> all_entity_id_list ( 15 ): [80, 125, 128, 146, 147, 151, 244, 245, 246, 248, 253, 270, 277, 279, 284]

- after relation #8 - 2687 - FROM: 271 - context_text-Person-1026 - TO: 279 - context_text-Person-755 - THROUGH: 270 - context_text-Article-94311 - DIRECTED?: False - ( type: 9 - same_article_subjects ):
----> Relation ID List ( 8 ): [1101, 1245, 2264, 2271, 2288, 2595, 2638, 2687]
----> from_to_entity_id_list ( 12 ): [80, 128, 147, 151, 245, 246, 248, 253, 271, 277, 279, 284]
----> all_entity_id_list ( 16 ): [80, 125, 128, 146, 147, 151, 244, 245, 246, 248, 253, 270, 271, 277, 279, 284]

- after relation #9 - 2973 - FROM: 291 - context_text-Person-148 - TO: 288 - context_text-Person-1034 - THROUGH: 286 - context_text-Article-94326 - DIRECTED?: False - ( type: 9 - same_article_subjects ):
----> Relation ID List ( 9 ): [1101, 1245, 2264, 2271, 2288, 2595, 2638, 2687, 2973]
----> from_to_entity_id_list ( 14 ): [80, 128, 147, 151, 245, 246, 248, 253, 271, 277, 279, 284, 288, 291]
----> all_entity_id_list ( 19 ): [80, 125, 128, 146, 147, 151, 244, 245, 246, 248, 253, 270, 271, 277, 279, 284, 286, 288, 291]

- after relation #10 - 3086 - FROM: 147 - context_text-Person-56 - TO: 308 - context_text-Person-1041 - THROUGH: 307 - context_text-Article-94430 - DIRECTED?: False - ( type: 2 - mentioned ):
----> Relation ID List ( 10 ): [1101, 1245, 2264, 2271, 2288, 2595, 2638, 2687, 2973, 3086]
----> from_to_entity_id_list ( 15 ): [80, 128, 147, 151, 245, 246, 248, 253, 271, 277, 279, 284, 288, 291, 308]
----> all_entity_id_list ( 21 ): [80, 125, 128, 146, 147, 151, 244, 245, 246, 248, 253, 270, 271, 277, 279, 284, 286, 288, 291, 307, 308]
Relation ID List ( 10 ): [1101, 1245, 2264, 2271, 2288, 2595, 2638, 2687, 2973, 3086]
from_to_entity_id_list ( 15 ): [80, 128, 147, 151, 245, 246, 248, 253, 271, 277, 279, 284, 288, 291, 308]
all_entity_id_list ( 21 ): [80, 125, 128, 146, 147, 151, 244, 245, 246, 248, 253, 270, 271, 277, 279, 284, 286, 288, 291, 307, 308]

unit test - relation type role value lists

unit test - relation type role value lists - BASIC


In [12]:
# make test instance.
test_instance = NetworkDataOutputTest()

# set up basic
basic_instance = test_instance.set_up_basic_test_instance()

# render
basic_instance.render()

# get relation QuerySet
relation_qs = basic_instance.get_query_set()

# get master ID list
entity_id_list = basic_instance.get_master_entity_list()


In get_selection_filters(): use_entity_selection_IN is True
In get_selection_filters(): "entity_selection" filtering was requested, but not specified in the request.  Defaulting to "relation_selection".
In get_selection_filters(): use_entity_selection_IN is False
In generate_master_entity_list: len( entity_dict ) = 72; entity_dict: {35: None, 36: None, 18: None, 24: None, 23: None, 22: None, 21: None, 20: None, 19: None, 25: None, 8: None, 9: None, 16: None, 13: None, 12: None, 11: None, 15: None, 14: None, 10: None, 80: None, 83: None, 82: None, 81: None, 69: None, 72: None, 71: None, 70: None, 46: None, 44: None, 40: None, 47: None, 45: None, 43: None, 42: None, 41: None, 39: None, 38: None, 32: None, 28: None, 33: None, 31: None, 30: None, 29: None, 27: None, 85: None, 89: None, 87: None, 90: None, 88: None, 86: None, 74: None, 78: None, 77: None, 76: None, 75: None, 63: None, 67: None, 66: None, 65: None, 64: None, 49: None, 53: None, 52: None, 51: None, 50: None, 55: None, 61: None, 59: None, 58: None, 60: None, 57: None, 56: None}
In generate_master_entity_list(): master entity ID list length: 72 ( list: [8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 35, 36, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 49, 50, 51, 52, 53, 55, 56, 57, 58, 59, 60, 61, 63, 64, 65, 66, 67, 69, 70, 71, 72, 74, 75, 76, 77, 78, 80, 81, 82, 83, 85, 86, 87, 88, 89, 90] )

In [16]:
test_entity = Entity.objects.get( id = 18 )
print( test_entity )

test_qs = relation_qs.filter( relation_through = test_entity )
print( "match count: {}".format( test_qs.count() ) )

test_qs = relation_qs.filter( relation_through_id = 18 )
print( "match count: {}".format( test_qs.count() ) )


18 - context_text-Person-30
match count: 0
match count: 0

In [21]:
mentioned_type = Entity_Relation_Type.objects.get( slug = "mentioned" )
quoted_type = Entity_Relation_Type.objects.get( slug = "quoted" )
shared_byline_type = Entity_Relation_Type.objects.get( slug = "shared_byline" )
type_list = [ mentioned_type, quoted_type, shared_byline_type ]
role_list = [ ContextBase.RELATION_ROLES_FROM, ContextBase.RELATION_ROLES_TO, ContextBase.RELATION_ROLES_THROUGH ]

# declare variables
current_type_slug = None
type_to_roles_map = {}
role_to_list_map = {}

# loop over types
for current_type in type_list:
    
    # add to type_to_roles_map
    current_type_slug = current_type.slug
    role_to_list_map = {}
    type_to_roles_map[ current_type_slug ] = role_to_list_map
    
    # loop over roles
    for current_role in role_list:
        
        # init list
        type_role_list = []
        
        # loop over IDs.
        for entity_id in entity_id_list:
            
            # do lookup in relations.  relation type...
            test_qs = relation_qs.filter( relation_type = current_type )

            # and entity in requested role...
            if ( current_role == ContextBase.RELATION_ROLES_FROM ):
                test_qs = test_qs.filter( relation_from_id = entity_id )
            elif ( current_role == ContextBase.RELATION_ROLES_TO ):
                test_qs = test_qs.filter( relation_to_id = entity_id )
            elif ( current_role == ContextBase.RELATION_ROLES_THROUGH ):
                test_qs = test_qs.filter( relation_through_id = entity_id )
            #-- END check to see which role we are filtering on. --#
            
            # get count of matches for this entity, requested type and role
            entity_count = test_qs.count()
            
            # add count to list.
            type_role_list.append( entity_count )
            
        #-- END loop over entities. --#
        
        # output the list.
        print( "----> type: {}; role: {}; list: {}".format( current_type, current_role, type_role_list ) )
        
        # add it to role map for current type
        role_to_list_map[ current_role ] = type_role_list
        
    #-- END loop over roles --#
    
#-- END loop over relation types. --#


----> type: 2 - mentioned - mentioned; role: FROM; list: [7, 24, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 0, 0]
----> type: 2 - mentioned - mentioned; role: TO; list: [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1]
----> type: 2 - mentioned - mentioned; role: THROUGH; list: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
----> type: 1 - quoted - quoted; role: FROM; list: [4, 9, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0]
----> type: 1 - quoted - quoted; role: TO; list: [0, 0, 0, 2, 2, 2, 0, 0, 2, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0]
----> type: 1 - quoted - quoted; role: THROUGH; list: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
----> type: 3 - shared_byline - Shared Byline; role: FROM; list: [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
----> type: 3 - shared_byline - Shared Byline; role: TO; list: [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
----> type: 3 - shared_byline - Shared Byline; role: THROUGH; list: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

unit test - relation type role value lists - ENTITY_SELECTION


In [22]:
# make test instance.
test_instance = NetworkDataOutputTest()

# set up basic
ndo_instance = test_instance.set_up_entity_selection_test_instance()

# render
ndo_instance.render()

# get relation QuerySet
relation_qs = ndo_instance.get_query_set()

# get master ID list
entity_id_list = ndo_instance.get_master_entity_list()


In get_selection_filters(): use_entity_selection_IN is True
In get_selection_filters(): use_entity_selection_IN is False
In generate_master_entity_list: len( entity_dict ) = 153; entity_dict: {135: None, 140: None, 139: None, 138: None, 136: None, 137: None, 161: None, 209: None, 218: None, 217: None, 216: None, 215: None, 214: None, 213: None, 212: None, 211: None, 72: None, 157: None, 210: None, 162: None, 163: None, 188: None, 190: None, 189: None, 171: None, 176: None, 175: None, 174: None, 173: None, 172: None, 35: None, 36: None, 220: None, 221: None, 222: None, 142: None, 144: None, 145: None, 143: None, 18: None, 24: None, 23: None, 22: None, 21: None, 20: None, 19: None, 25: None, 178: None, 181: None, 180: None, 185: None, 184: None, 183: None, 182: None, 179: None, 8: None, 9: None, 16: None, 13: None, 12: None, 11: None, 15: None, 14: None, 10: None, 80: None, 83: None, 82: None, 81: None, 192: None, 201: None, 200: None, 195: None, 194: None, 199: None, 198: None, 197: None, 196: None, 193: None, 69: None, 71: None, 70: None, 153: None, 159: None, 158: None, 155: None, 154: None, 156: None, 147: None, 206: None, 204: None, 207: None, 205: None, 203: None, 151: None, 148: None, 150: None, 149: None, 46: None, 44: None, 40: None, 47: None, 45: None, 43: None, 42: None, 41: None, 39: None, 38: None, 32: None, 28: None, 33: None, 31: None, 30: None, 29: None, 27: None, 85: None, 89: None, 87: None, 90: None, 88: None, 86: None, 165: None, 168: None, 167: None, 169: None, 166: None, 74: None, 78: None, 77: None, 76: None, 75: None, 63: None, 67: None, 66: None, 65: None, 64: None, 224: None, 229: None, 228: None, 227: None, 226: None, 225: None, 49: None, 53: None, 52: None, 51: None, 50: None, 55: None, 61: None, 59: None, 58: None, 60: None, 57: None, 56: None}
In generate_master_entity_list(): master entity ID list length: 153 ( list: [8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 35, 36, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 49, 50, 51, 52, 53, 55, 56, 57, 58, 59, 60, 61, 63, 64, 65, 66, 67, 69, 70, 71, 72, 74, 75, 76, 77, 78, 80, 81, 82, 83, 85, 86, 87, 88, 89, 90, 135, 136, 137, 138, 139, 140, 142, 143, 144, 145, 147, 148, 149, 150, 151, 153, 154, 155, 156, 157, 158, 159, 161, 162, 163, 165, 166, 167, 168, 169, 171, 172, 173, 174, 175, 176, 178, 179, 180, 181, 182, 183, 184, 185, 188, 189, 190, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 203, 204, 205, 206, 207, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 220, 221, 222, 224, 225, 226, 227, 228, 229] )

In [23]:
test_entity = Entity.objects.get( id = 18 )
print( test_entity )

test_qs = relation_qs.filter( relation_through = test_entity )
print( "match count: {}".format( test_qs.count() ) )

test_qs = relation_qs.filter( relation_through_id = 18 )
print( "match count: {}".format( test_qs.count() ) )


18 - context_text-Person-30
match count: 0
match count: 0

In [24]:
mentioned_type = Entity_Relation_Type.objects.get( slug = "mentioned" )
quoted_type = Entity_Relation_Type.objects.get( slug = "quoted" )
shared_byline_type = Entity_Relation_Type.objects.get( slug = "shared_byline" )
type_list = [ mentioned_type, quoted_type, shared_byline_type ]
role_list = [ ContextBase.RELATION_ROLES_FROM, ContextBase.RELATION_ROLES_TO, ContextBase.RELATION_ROLES_THROUGH ]

# declare variables
current_type_slug = None
entity_selection_type_to_roles_map = {}
role_to_list_map = {}

# loop over types
for current_type in type_list:
    
    # add to type_to_roles_map
    current_type_slug = current_type.slug
    role_to_list_map = {}
    entity_selection_type_to_roles_map[ current_type_slug ] = role_to_list_map
    
    # loop over roles
    for current_role in role_list:
        
        # init list
        type_role_list = []
        
        # loop over IDs.
        for entity_id in entity_id_list:
            
            # do lookup in relations.  relation type...
            test_qs = relation_qs.filter( relation_type = current_type )

            # and entity in requested role...
            if ( current_role == ContextBase.RELATION_ROLES_FROM ):
                test_qs = test_qs.filter( relation_from_id = entity_id )
            elif ( current_role == ContextBase.RELATION_ROLES_TO ):
                test_qs = test_qs.filter( relation_to_id = entity_id )
            elif ( current_role == ContextBase.RELATION_ROLES_THROUGH ):
                test_qs = test_qs.filter( relation_through_id = entity_id )
            #-- END check to see which role we are filtering on. --#
            
            # get count of matches for this entity, requested type and role
            entity_count = test_qs.count()
            
            # add count to list.
            type_role_list.append( entity_count )
            
        #-- END loop over entities. --#
        
        # output the list.
        print( "----> type: {}; role: {}; list: {}".format( current_type, current_role, type_role_list ) )
        
        # add it to role map for current type
        role_to_list_map[ current_role ] = type_role_list
        
    #-- END loop over roles --#
    
#-- END loop over relation types. --#


----> type: 2 - mentioned - mentioned; role: FROM; list: [7, 24, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
----> type: 2 - mentioned - mentioned; role: TO; list: [0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
----> type: 2 - mentioned - mentioned; role: THROUGH; list: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
----> type: 1 - quoted - quoted; role: FROM; list: [4, 9, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
----> type: 1 - quoted - quoted; role: TO; list: [0, 0, 0, 2, 2, 2, 0, 0, 2, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
----> type: 1 - quoted - quoted; role: THROUGH; list: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
----> type: 3 - shared_byline - Shared Byline; role: FROM; list: [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
----> type: 3 - shared_byline - Shared Byline; role: TO; list: [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
----> type: 3 - shared_byline - Shared Byline; role: THROUGH; list: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

TODO

TODO - Network data creation

TODO - Network data creation - framework

Framework todos:

  • add in a little more detailed updates on rendering network data (every X relations, output timestamp).
  • build basic framework where each output type accepts these two QuerySets, renders and returns desired output format.

    • have child NDO classes implement "initialize_from_request" if needed, call parent, then init format-specific stuff.
    • update to use StatusContainer instead of status strings.
  • add type checking to setters of dictionaries and lists, to make sure either None or correct type passed in.

TODO - Network data creation - testing

Testing todos:

  • // first, get it running, then unit tests.
  • // make plan for unit testing for all export instances, fill in outline below.
  • find a way to put method validate_string_against_file_contents() into python_utilities - new unittest_helper class, and call the stock unittest asserts instead of those on the instance?

    • make a parent class that extends the base unittest class? (unittest.TestCase)
    • // make a parent class that extends Django's unit test class (django.test.TestCase).
  • unit testing:

    • NetworkDataRequest

      • // do_output_entity_traits_or_ids
      • // class method create_entity_id_header_label
      • // class method create_entity_trait_header_label
      • // create_entity_ids_and_traits_header_list
      • // get/set_entity_ids_and_traits_header_list
      • // get/set_entity_id_to_instance_map
      • // get/set_entity_id_to_traits_map
      • // process_entities - add to test to include entity traits and IDs

      • NOTE: Add process_entities as precondition for the following:

      • // create_ids_and_traits_values_for_entity

        • // get_ids_and_traits_for_entity
      • // get/set_entity_id_list

      • // generate_entity_id_list
      • create_entity_ids_and_traits_value_dict( entity_id_list_IN )

        • loop over labels, calling the validate method for create_entity_ids_and_traits_value_list for each.
        • create_entity_ids_and_traits_value_list( self, header_label_IN, entity_id_list_IN = None ): - make a "validate" method that accepts...? and:

          • check default list
          • check a smaller list
          • check a smaller list that includes entities who were not loaded
      • load_ids_and_traits_for_entities( self, entity_id_list_IN, dictionary_IN )

      • process_entities_from_id_list
    • NetworkDataOutput

      • dependencies for child classes:

        • create_header_list()
        • create_label_list()
        • create_relation_type_roles_for_entity()
        • create_relation_type_roles_header_list()
        • do_output_attribute_columns()
        • do_output_attribute_rows()
        • do_output_network()
        • get_entity_label()
        • get_relation_roles_for_entity()
        • get_relations_for_entity()
      • notes

        • register_relation_type(), and the places that call it: render(), optionally also update_entity_relation_details()
    • NDO children

      • NDO_SimpleMatrix

        • render_network_data() - at a high level, render the basic, compare to a pre-rendered file.

          • create_label_string()
        • create_network_string() - the worker method, effectively, testing render_network_data() tests this.

          • create_entity_row_string() - per row method.
        • create_entity_relation_types_attribute_string()

      • NDO_CSVMatrix

        • append_entity_ids_and_traits_rows
        • render_network_data() - at a high level, render the basic, compare to a pre-rendered file.

          • create_csv_string()

            • init_csv_output()
            • create_csv_document()

              • - create_header_list() - append_row_to_csv() - append_entity_row() - create_relation_type_roles_for_entity() - (duplicate) append_row_to_csv() - append_entity_id_row() - (duplicate) append_row_to_csv() - append_entity_relation_type_rows() - (duplicate) append_row_to_csv()
            • cleanup()

      • NDO_TabDelimitedMatrix

        • nothing but an init - maybe just run the basic config through, make sure it comes out as we expect.
  • // look at relation filtering/tie creation/rendering - Entity 10 (person 872) has two ties in test output for "basic" (to entities 8 and 9), should only have 1. Article (21409) had two authors, so single article resulted in two ties to the subject, one from each author.

  • test by comparing to output from the original tool, including derived statistics.

TODO - general

general TODO:

  • methods to find relations, similar to filter_entities() and lookup_entities() in Entity model class. Include:

    • // Entity_Relation_Type by either slug or instance
    • // from =
    • from_in
    • from_type_in
    • from_identifiers_in
    • from_entity_traits

      • AND dictionary
      • OR dictionary
      • fancy
    • // to =

    • to_in
    • to_type_in
    • to_identifiers_in
    • to_entity_traits

      • AND dictionary
      • OR dictionary
      • fancy
    • // through =

    • through_in
    • through_identifiers_in
    • through_entity_traits

      • AND dictionary
      • OR dictionary
      • fancy
    • either FROM or TO (so undirected search - "I don't care which side")

      • IDs
      • identifiers
      • traits
    • any of FROM, TO, THROUGH

      • IDs
      • identifiers
      • traits
    • relation_traits

      • // AND dictionary
      • OR dictionary
      • fancy
    • NOTE for trait matching types (and probably entity identifiers, also):

      • "AND dictionary" - to start, accept a dictionary of trait names and values that all must match (AND match).
      • "OR dictionary" - could add an "OR" trait match dictionary as well.
      • "fancy" - Eventually, could add ability to spec trait name (or unsaved model instance?), then specify test for value (equals, contains, etc.) and test value. This would likely be a new little object.
    • Tags on Entity and/or Entity_Relation.

  • make small dummy person and organization classes in context, so I can use them to test Abstract_Entity_Container without needing context_text.

  • come up with better way to seed entities and relations for sourcenet - store spec in context_text base, then method to create or update all.

    • store the JSON from the context fixture in Context_Text_Base? Or in a sourcenet class somewhere?
    • make a class in context/shared that contains variables and methods to loops over the items in context fixture JSON and update the database based on what is inside. For each item in the fixture JSON, looks each up based on unique idnetifying information (name, slug, label, etc.). If it finds it, moves on. If not, creates it.
    • This will need to build up a basic object mapping based on foriegn keys before it creates anything, then create things in the right order (Entity_Types and related first, then Entity_Identifier_Types, then Relation_Types). Order:

      • context.Trait_Type \
      • context.Entity_Type \
      • context.Entity_Type_Trait \
      • context.Entity_Identifier_Type
      • context.Entity_Relation_Type \
      • context.Entity_Relation_Type_Trait \
      • context.Term_Relation_Type \
      • context.Vocabulary \
      • context.Term \
      • context.Term_Relation \
    • for each type:

      • make a map of id to fields for each item of that type.
      • make a method for creating an instance of that type from fields.
      • to associate related, retrieve instance from in-memory map based on ID, then if db_id present, use it to look up, else look up in database based on name. If not found, error, but could create.
    • To actually load, go in order of types outlined above, creating as you go.

    • When one of the items is added to the database, add a db_id field to their "fields".
  • abstraction:

    • make an abstract parent for a type that has associated trait specs (parent to Entity_Type and Entity_Relation_Type).

      • share method get_trait_spec().
    • make an abstract parent for trait containers that have associated types with associated trait specs (parent to Entity and Entity_Relation).

      • share method `

DONE

DONE - TODO - Network data creation

Network data creation TODO:

DONE - TODO - Network data creation - framework

Framework todos:

2020.01.06

  • then, build basic framework where each output type accepts these two QuerySets, renders and returns desired output format.

    • refactoring from old NetworkOutput, NetworkDataOutput, and NDO objects:

      • // change so they refer to entities, not persons.
      • // pull out all of the Article_Data stuff.
      • // maintain the data structures used when actually rendering, just build from Entity_Relation, not Article_Data. Might be able to get rid of some stuff, too.
      • // terms to search for and consider replacing "person" with "entity" (if they aren't in sections that will just be ripped out because they are no longer needed):

        • // person_dictionary
        • // person_dict
        • // article_data_query_set
        • // generate_master_person_list
        • // person_ids_list
        • // current_person_id
        • // current_article_data
        • // article_data_counter
        • // master_person_list
      • todo:

        • // remove references to "include_render_details"
        • // remove "inclusion_params"

          • // remove references to self.inclusion_params
          • // remove references to inclusion_params
          • // remove references to self.is_source_connected( current_source )
        • // remove network_label

        • // update generate_master_person_list() to reference new variables (generate_master_entity_list).
        • // what to do about get_person_label()? - updated to get_entity_label, for now just uses Entity ID. Could make it also include more IF Entity instances are cached. We'll see if that is helpful.
        • // remove get_person_type and get_person_type_id (functions themselves are removed, need to mop up around the other classes: grep -r -n "get_person_type" .; grep -r -n "get_person_type_id" .
        • // rename get_relations_for_person to get_relations_for_entity
        • // rename get_master_person_list to get_master_entity_list
        • // rename create_person_id_list to create_entity_id_list
        • // rename get_person_label to get_entity_label (and made it a lot simpler).
        • // remove PERSON_QUERY_TYPE_CHOICES_LIST and related.
        • // remove CODER_TYPE_FILTER_*
        • // remove PERSON_TYPE_* variables (check in all files)
        • // search for "person", "people" in all NDO files in context.

          • // ndo_simple_matrix.py
          • // ndo_csv_matrix.py
          • // ndo_tab_delimited_matrix.py
        • // Article_Subject

        • // append_person_row...
        • // get rid of fancy date range code...
        • // remove PARAM_*? Not for now - used in places, is a good signal for needing changes.
      • update person type stuff so it stores a list, rather than "author", "source", or "both".

        • // As you build data, keep track centrally of all relation types seen - register_relation_type( relation_type_IN ), called from render(), optionally also from update_entity_relation_details().

2020.01.08

  • build basic framework where each output type accepts these two QuerySets, renders and returns desired output format.

    • refactoring from old NetworkOutput, NetworkDataOutput, and NDO objects:

      • // NetworkOutput.render_network_data(): add outputting to file if file output path specified in request.
      • // add check to see if master list is larger after integrating items from network processing - if so, output error - for the entity filter to be effective, it must be a superset of the network set of relations.
      • // update person type stuff so it stores a list, rather than "author", "source", or "both".

        • // remove update_person_type()
        • // check for places that retrieve person type dictionary ( self.person_type_dict ) - removed all.
        • // create a variable, getter and setter for relation_type_slug_to_instance_map and relation_type_slug_list.
        • // removed NDO.create_person_type_id_list - figure out ramifications. Might need to create a set of columns for each relation type, one for each of FROM, TO, and THROUGH, then populate appropriately from the new relation type map.
        • // As you build data, keep track centrally of all relation types seen - call register_relation_type( relation_type_IN ) to update map and list created above. Updated from render(), optionally also from update_entity_relation_details().
        • then, when outputting:

          • // for headers, grab this list of relation types and create FROM, TO, and THROUGH column headers for each.
          • // for tabular (ndo_csv_matrix and children):

            • // NetworkDataOutput.create_relation_type_roles_for_entity(): for data rows (attribute columns at right), walk the entity's relation type data structure in the same order as the relation type list, and output FROM, TO, and THROUGH numbers for each, 0 if not found. Will result in many attribute columns.
            • for data columns (attribute rows at bottom), pull in all relation types, then for each entity-->type-->role, walk all entities and output their value for that relation type in the row. So, will result in many rows of attribute values.

              • - // NetworkDataOutput.create_relation_type_role_value_list(): create method that accepts a relation type slug and a role, creates list of values for all entities in master entity list for that combination of slug and role. If not present for a given entity, sets to 0. - // NetworkDataOutput.create_relation_type_value_dict(): create a method that accepts a relation type slug, loops over all roles, calls NetworkDataOutput.create_relation_type_role_value_list() to build the list of values for each, then makes and returns dictionary mapping roles to value lists. - // NetworkDataOutput.create_all_relation_type_values_lists(): create a method that loops over relation type slugs, then for each, calls NetworkDataOutput.create_relation_type_value_dict() to create dictionary that maps roles to values lists. Creates a dictionary that maps relation type slugs to these dictionaries, then returns the new dictionary. - // NDO_CSVMatrix.append_entity_relation_type_rows(): implement logic in the ndo_csv_matrix class that retrieves the values lists and uses them appropriately.
          • // for ndo_simple_matrix.py (UCINet native format), need to implement create_entity_relation_types_attribute_string() - it assumed a single entity type value per person - need to re-do it so it pulls in all relation types, then outputs a list per person-->type-->role. So, will result in many lists.

2020.01.23

  • add ability in JSON to tell which entity traits we want to include in output traits, then when loading entities, look for those traits in each as it is loaded, store in a separate entity ID to trait name-value map.

    • // add place in output spec for:

      • traits (output_entity_traits_list?) - store the list of names/slugs of traits you want included if traits are output. Possible filter criteria:

        • name
        • slug
        • entity_type_trait ID
      • identifiers (output_entity_identifiers_list) - list of identifiers you want to include - to effectively target, might need an object with more than just name. Possible filter criteria:

        • name
        • id_type
        • source
        • identifier type ID
      • includes updating NetworkDataRequest and its tests to know of and allow for easy retrieval of these lists.

    • // add to processing a step in generating the master entity list where you loop over the list of traits if one present in the request and make a map of the values for those traits for each entity (map entity ID --> trait dict).

      • move the logic for processing entities to NetworkDataRequest, so it can be used to pass the entity dictionary, master entity list, and entry traits to NetworkDataOutput and children.

        • process_entities

          • add_entities_to_dict
          • add_entity_to_dict
          • entity dictionary and trait map, and getters and setters.

             self.m_entity_id_to_instance_map = {}
             self.m_entity_id_to_traits_map = {}
          • it checks if traits specified (call to NetworkDataRequest.do_output_entity_traits_or_ids()).

          • if so, calls load_entities_traits_and_ids. Inside:

            • load_entity_traits
            • load_entity_identifiers
      • need to remove all that stuff from NetworkOutput, fix everything so it works again.

      • move all the test cases over to NetworkDataRequest.
    • // in rendering output, if traits output, update to render:

      • 1) entity ID
      • 2) entity relation type role information
      • 3) any requested traits

DONE - TODO - Network data creation - testing

Testing todos:

  • unit testing:

    • // NetworkOutput

      • // create_ndo_instance()
      • // get_NDO_instance()
      • // get_network_data_request()
      • // get_relation_query_set()
      • // set_NDO_instance()
      • // set_network_data_request()
      • // set_relation_query_set()
    • NetworkDataOutput

      • // getters and setters

        • // get_entity_dictionary()/set_entity_dictionary()
        • // get_entity_relation_type_summary_dict()/set_entity_relation_type_summary_dict()
        • // get_master_entity_list()/set_master_entity_list()
        • // get_network_data_request()/set_network_data_request()
        • // get_output_format()/set_output_format()
        • // get_output_structure()/set_output_structure()
        • // get_output_type()/set_output_type()
        • // get_query_set()/set_query_set()
        • // get_relation_map()/set_relation_map()
        • // get_relation_type_slug_list()/set_relation_type_slug_list()
        • // get_relation_type_slug_to_instance_map()/set_relation_type_slug_to_instance_map()
      • // set_query_set()

      • // set_entity_dictionary()
      • // initialize_from_request()
      • // render()

        • // get_query_set()
        • // get_entity_dictionary()
        • // add_directed_relation()

          • // get_relation_map()
        • // add_reciprocal_relation()

          • // (duplicate) add_directed_relation()
        • // register_relation_type()

          • // get_relation_type_slug_to_instance_map()
          • // get_relation_type_slug_list()
        • // update_entity_relations_details()

          • // (duplicate) register_relation_type()
          • // (duplicate)get_entity_relation_type_summary_dict()
        • // generate_master_entity_list()

          • // get_entity_dictionary()
          • // (duplicate) get_entity_relation_type_summary_dict()
          • // (duplicate) set_master_entity_list()
          • // (duplicate) get_master_entity_list()
        • abstract render_network_data()

      • dependencies for child classes:

        • // create_entity_id_list()
        • // create_all_relation_type_values_lists()

          • // get_relation_type_slug_list()
          • // create_relation_type_value_dict()

            • // create_relation_type_role_value_list()

              • - // (duplicate) get_master_entity_list() - // get_entity_relation_type_summary_dict() - // create goal data: - write program to, for basic, then entity_selection: - setup and render. - retrieve relation QS. - retrieve master entity ID list. - for each relation type - for each role: - loop over ID list, and filter to count all relations where the current ID is in the selected type and role.
    • // NetworkDataRequest

      • // process_entities()

        • // create_entity_dict()

          • // add_entities_to_dict()

            • // add_entity_to_dict()

DONE - TODO - general

Nothing yet...