<jupyter_start><jupyter_text>Adding some random dates so that I can test the temporal controls<jupyter_code>days = datetime.timedelta(days=1)
weeks = datetime.timedelta(weeks=1)
months = 30*days
years = datetime.timedelta(days=365)
def random_date(start=datetime.date(year=1800, month=1, day=1), end=datetime.date(year=1890, month=12, day=31),
                within=None):
    if within:
        start = within[0]
        end = within[1]

    start = datetime.datetime.combine(start, datetime.time()).timestamp()
    end = datetime.datetime.combine(end, datetime.time()).timestamp()
    result = start + random.random() * (end - start)
    return datetime.datetime.fromtimestamp(result).date()
def random_duration(start=datetime.date(year=1800, month=1, day=1), 
                    end=datetime.date(year=1890, month=12, day=31),
                    within=None,
                    minimum=20*years, maximum=80*years,
                    breach_maximum=False):
    if within:
        start = within[0]
        end = within[1]
    mindur = minimum.total_seconds()
    maxdur = maximum.total_seconds()
    start = random_date(start=start, end=end)

    if not breach_maximum:
        lifedur = (end - start).total_seconds()
        if maxdur > lifedur:
            maxdur = lifedur
        if mindur > maxdur:
            mindur = 0.5*maxdur

    dur = mindur + random.random() * (maxdur-mindur)

    return (start, start + datetime.timedelta(seconds=dur))
def random_lifetime(start=datetime.date(year=1800, month=1, day=1),
                    end=datetime.date(year=1890, month=12, day=31),
                    maximum_age=80*years, all_adults=True):
    if all_adults:
        minimum = 18*years
    else:
        minimum = 1*day
        
    return random_duration(start=start, end=end, minimum=minimum, maximum=maximum_age, breach_maximum=True)
def adult(lifetime):
    start = lifetime[0]
    end = lifetime[1]
    start = start + 18*years
    if start > end:
        raise ValueError("Not an adult %s => %s" % (start.isoformat(), end.isoformat()))
    return (start, end)
lifetime = random_lifetime()
print(lifetime)
print(adult(lifetime))
print(random_duration(within=adult(lifetime), minimum=6*months, maximum=5*years))
print(f"Lived {(lifetime[1]-lifetime[0]).total_seconds() / (3600*24*365)} years")
def get_earliest(start, end, ids):
    try:
        start = ids[start][0]
    except KeyError:
        try:
            return ids[end][0]
        except KeyError:
            return None
        
    try:
        end = ids[end][0]
    except KeyError:
        return start
    
    if start < end:
        return end
    else:
        return start
def get_latest(start, end, ids):
    try:
        start = ids[start][1]
    except KeyError:
        try:
            return ids[end][1]
        except KeyError:
            return None
        
    try:
        end = ids[end][1]
    except KeyError:
        return start
    
    if start < end:
        return start
    else:
        return end
Brunel.DateRange(start=lifetime[0], end=lifetime[1])
lifetimes = {}
def add_random_dates_to_node(node):
    lifetime = random_lifetime()
    duration = lifetime
    
    if "alive" in node.state:
        node.state["alive"] = Brunel.DateRange(start=lifetime[0], end=lifetime[1])
        lifetimes[node.getID()] = lifetime
        duration = adult(lifetime)
    
    if "positions" in node.state:
        pos = node.state["positions"]
        for key in pos.keys():
            member = random_duration(within=duration, minimum=6*months, maximum=20*years)
            pos[key] = Brunel.DateRange(start=member[0], end=member[1])

        node.state["positions"] = pos
    
    if "affiliations" in node.state:
        aff = node.state["affiliations"]
        for key in aff.keys():
            member = random_duration(within=duration, minimum=5*years, maximum=20*years)
            aff[key] = Brunel.DateRange(start=member[0], end=member[1])
        
        node.state["affiliations"] = aff
    
    return node
def add_random_dates_to_message(message):
    start = get_earliest(message.getSender(), message.getReceiver(), lifetimes)
    end = get_latest(message.getSender(), message.getReceiver(), lifetimes)
    
    if not start:
        start = datetime.date(year=1850, month=1, day=1)
        end = datetime.date(year=1870, month=12, day=31)
    
    if not end:
        end = start + 12*months
    
    sent = random_date(start=start, end=end)
    message.state["sent"] = Brunel.DateRange(start=sent, end=sent)
    return message
social = Brunel.Social.load_from_csv("input/nodes.csv", "input/edges.csv",
                                     modifiers={"person": add_random_dates_to_node,
                                                "business": add_random_dates_to_node,
                                                "message": add_random_dates_to_message})
with open("data.json", "w") as FILE:
    FILE.write(Brunel.stringify(social))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.121765295887663, 'fraction_numerical': 0.023470411233701104, 'mean_word_length': 2.5487544483985767, 'pattern_counts': {'":': 3, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '149840', 'license': 'MIT', 'n_tokens_mistral': 1641, 'n_tokens_neox': 1540, 'n_words': 322, 'path': 'python/create_data.ipynb', 'repo_name': 'gareth-j/brunel', 'size': '4985'}