How to move to a linked agent which has a particular value for the link - hyperlink

I am trying to select the agents to which I link that have a high value for my link to that agent. Then, I want to move to one of those agents. I cannot figure out how to select the agents at the other end of my link, where the link has a particular value and then move to one-of those agents with a high value of 0.9 for the link. How can I achieve this?
breed [ people ]
undirected-link-breed [ connections connection ]
connections-own [ trust ]
to setup-all-connections
ask people [setup-connection]
end
to setup-connection
create-connections-with other people [set trust 0.4]
end
to go
move-people
tick
end
to move-people
ask people [
let chance random 100
if chance < 80
[
let highTrust my-out-connections with [trust = 0.9]
move-to one-of people with [member? other-end highTrust]
]
]
end

How about
let highTrust turtle-set [other-end] of my-out-connections with [trust = 0.9]
move-to one-of highTrust
I.e., get a list of the appropriate other-ends, turn that list into an agentset, and then move to one of them. Or, more economically
move-to one-of [other-end] of my-out-connections with [trust = 0.9]
since one-of works on lists of agents as well as agentsets. You may need to be sure that their is at least one such trusted agent before applying one-of. You might also want to check if there is already a trusted agent at the same location so that it does not move away from it.

Related

change the value of a link

I try to change the values of links for only the links to particular agents. So, I want to set the links of myself to every agent in the agent set relatedPersons to 0.6 and keep all other links unchanged. Can I achieve this using ask my-out-links? My code is:
breed [ persons person ]
undirected-link-breed [ connections connection]
connections-own [ trust ]
to setup
clear-all
create-persons 10
[
set grouped false
]
create-connections
reset-ticks
end
to create-connections
ask persons
[ setup-connection ]
end
to setup-connection
create-connections-with other persons
[ set trust 0.4 ]
end
to increaseConnection
let alonePersons count persons with [grouped = false]
let relatedPersons n-of (random alonePersons) persons
ask relatedPersons [
ask my-out-links [ set trust 0.6 ]
]
end
to go
increaseConnection
tick
end
I think that this is the line that you want. Not terribly efficient as the intimacy value is set by both members of the pair, but it is intuitive and unless you have a lot of protesters, it should not be a problem.
ask my-out-links with [member? other-end NRelatedProtesters] [ set intimacy 0.8 ]
Each protester is looking for its links where the other end is a member of the NRelatedProtesters group.
Actually, to be consistent with your model, it should be
ask my-out-relationships with [member? other-end NRelatedProtesters] [ set intimacy 0.8 ]
Do note that your code is not complete. If one wanted to test it, they would have to fill in a number of missing parts.

How to convert guild.permissions number into an array of persmissions discord.js oauth2

I need to verify if a user logging into the website has sufficient permissions to modify my bot's behavior on a guild. I used passport-discord to get information on the user, and this is what I got:
{
...
guilds: [
{
id: 'guild id',
name: 'guild name',
icon: 'guild icon',
owner: false,
permissions: 104189504,
features: [Array],
permissions_new: '1037338791488'
}
...
]
}
For confidentiality purposes, I replaced the guild information above "owner". Now my question: How to convert the "permissions" section into an array of the user's permissions ?
I don't know if there is an API where you can do it (probably not), but it's not that complicated to implement this. Discord provides two community-created calculators for permissions, which do the opposite thing - you select which permissions you need and you get a calculated permissions result:
https://discordapi.com/permissions.html#104189504
https://finitereality.github.io/permissions-calculator/?v=104189504
You could quite easily create a function that will do the reverse - convert the decimal permissions number into a hex number, then map the hexes to named permissions.
E.g. your permission from example 104189504 is 635CE40 in hex representation. Permissions are mapped to 1, 2, 4, or 8, so if you encounter any other hex, it means there is a sum. Thus, your permission int contains the following permissions:
4000000
2000000
200000
100000
40000
10000
8000
4000
800
400
200
40
Which you can then map to names, e.g. 4000000 is "Change nickname", and so on.
If you want to keep your bot's permission checks simple, you might find it sufficient to check if the member executing the command has a specific role.

Can I pull a list of info out of an email?

I get a daily email that lists upcoming appointments, and their length. The number of appointments vary from day to day.
The emails go like this:
================
Today's Schedule
9:30 AM
3h
Brazilian Blowout
[Client #1 name]
12:30 PM
1h
Women's Cut
[Client 2 name]
6:00 PM
45m
Men's Cut
[Client #3 name]
Projected Revenue
===================
I want to create an event in a Google Calendar for each appointment, and it seems like zapier MIGHT be able to do this, but all the help resources I can find are very general in nature.
Is this do-able on Zapier? If so, any nudges in the right direction would be awesome.
Any thoughts greatly appreciated.
I had some time to kill and enjoy the odd challenge. So I have put together a solution that should do what you are looking for. I will break it down by steps.
TEMPLATE
Zapier Trigger - Step 1
Type: Trigger
Module: Gmail
Criteria: User Dependent
Comments: For the trigger zap you will want to use a Gmail specific trigger, something to the effect of "execute trigger on emails titled 'xyz'", or "emails labeled 'xyz'" if you setup a filter in your inbox.
Input screenshot:
Output Screenshot:
Zapier Action - Step 2
Type: Action
Module: Code (Python 3)
Comments: The Code offered by Zapier executes whatever (properly written) code you place in its container. It is especially handy as it allows you to incorporate data from previous steps in it through the use of a dictionary variable titled 'input_data'. Zapier offers the Code module in two languages: Javascript and Python. As I am most familiar with Python my solution for this step was written in Python. I will append the code to the end of this answer. Using the data held in the body of the email (retrieved in step 1) we can execute some string manipulations and datetime conversions to break apart the email into its component parts and pass those on to the following Action Step: Create Calendar Event.
Input Screenshot:
Output Screenshot:
Zapier Action - Step 3
Type: Action
Module: Google Calendar - Create Event
Comments: Using the data outputted from the previous code step we can fill out the required fields for creating a new appointment.
Input Screenshot:
Output Screenshot:
PYTHON CODE
from datetime import timedelta, date, datetime
'''
Goal: Extract individual appointment details from variable length email
Steps:
Remove all extraneous and new line characters.
Isolate each individual appointment and group its relevant details.
Derive appointment start and end times using appointment time and duration.
Return all appointments in a list.
'''
def format_appt_times(appt_dict):
appt_start_str = appt_dict.get("appt_start")
appt_dur_str = appt_dict.get("appt_length")
# isolate hour and minutes from appointment time
appt_s_hour = int(appt_start_str[:appt_start_str.find(":")])
if ("pm" in appt_start_str.lower()):
appt_s_hour = 12 if appt_s_hour + 12 >= 24 else appt_s_hour + 12
appt_s_min = int(appt_start_str[appt_start_str.find(":") + 1 :
appt_start_str.find(":") + 3])
# isolate hour and minutes from duration time
appt_d_hour = 0
appt_d_min = 0
if ("h" in appt_dur_str):
appt_d_hour = int(appt_dur_str[:appt_dur_str.find("h")])
if ("m" in appt_dur_str):
appt_d_min = int(appt_dur_str[appt_dur_str.find("m") - 2 : appt_dur_str.find("m")])
# NOTE: adjust timedelta hours depending on your relation to UTC
# create datetime objects for appointment start and end times
time_zone = timedelta(hours=0)
tdy = date.today() - time_zone
duration = timedelta(hours=appt_d_hour, minutes=appt_d_min)
appt_start_dto = datetime(year=tdy.year,
month=tdy.month,
day=tdy.day,
hour=appt_s_hour,
minute=appt_s_min)
appt_end_dto = appt_start_dto + duration
# return properly formatted datetime as string for use in next step.
return (appt_start_dto.strftime("%Y-%m-%dT%H:%M"),
appt_end_dto.strftime("%Y-%m-%dT%H:%M"))
def partition_list(target, part_size):
for data in range(0, len(target), part_size):
yield target[data : data + part_size]
def main():
# Remove all extraneous and new line characters.
email_body = input_data.get("email_body")
head,delin,*email_body,delin,foot = [text for text in email_body.splitlines() if text != ""]
appointment_list = []
# Isolate each individual appointment and group its relevant details.
for text in partition_list(email_body, 4):
template = {
"appt_start" : text[0],
"appt_end" : None,
"appt_length" : text[1],
"appt_title" : text[2],
"appt_client" : text[3]
}
appointment_list.append(template)
for appt in appointment_list:
appt["appt_start"], appt["appt_end"] = format_appt_times(appt)
return appointment_list
return main()
I am not sure of your familiarity with Python, or programming more generally, but the comments in the code explain what each section is doing. If you have any specific questions regarding aspects of the code let me know. Assuming your email template does not change this setup should work exactly as needed. Let me know if anything is unclear.
UPDATE
I thought it best to address your question in the original answer should anyone else have similar questions.
explaining how this code is removing the extra characters:
There is actually a fair bit going on in the first line, so I will do my best to break it down, and provide resources where necessary.
The code in question:
head,delin,*email_body,delin,foot = [text for text in email_body.splitlines() if text != ""]
First step here was to break the text into manageable chunks. I did so with the line email_body.splitlines() which, by default, breaks strings into a list at each newline character found (you can specify your own delimiter).
If we were to inspect the list at this moment its contents would be something of the following:
["================", "", "Today's Schedule", "", "9:30 AM", "", "3h", ..., "[Client #3 name]", "", "Projected Revenue", "", "==================="]
You will notice there is a fair amount of information in there that we really don't want.
First lets look at the "" elements. These are left over as a result of the blank lines between each line of text, which even though they are blank do still have newline characters at the end of them. There a number of ways you could address this within python. We could simply write a for-loop to go through and copy all elements that are not "" to a new list.
To me this felt like additional work, and besides, Python offers list comprehension for just such a scenario. I won't go too deep into list comprehension as there is a lot that can be said about it, and in more insightful ways than I could muster, but it essentially allows you to provide logic against a set of 'data' to form a list. In this case, I specifically wanted to filter out the "" elements returned from the call to splitlines().
And so you will see I address this with the following line
[text for text in email_body.splitlines() if text != ""]
With that we have a list as above less the "" elements. Now we must turn our attention towards the more 'dynamic' garbage strings. Again there are a number of ways to do this. A, not particularly flexible, option could be to simply store the strings we want to remove in variables something to the effect of:
garb_1 = "==================="
garb_2 = "Projected Revenue"
garb_3 = ...
and once again filter the list with yet another for-loop. I instead chose to leverage Python's list unpacking idiom. Which allows us to 'unpack' list objects (and I believe tuples) into variables. As an example:
one, two, three = ["a", "b", "c"]
I'm sure you can guess what is happening above, as long as we provide the same number of variables as are in the list we can 'unpack' it in this fashion. But wait! In our case we don't know how long the list is going to be as it is entirely dependent on the number of appointments you have for any given day. Well this is where star unpacking enters to elevate the functionality. Using my code as the example:
head,delin,*email_body,delin,foot = [text for text in email_body.splitlines() if text != ""]
The *, in plain-English, is saying "I don't know how many elements to expect just give me all of them in a list". As we know that there will always be two lines of garbage at the beginning and end of the email we can assign them to throw away variables and capture everything in between using our variable length *email_body container.
With all of this complete we now have a list with only the data we are looking to capture. If, as you say, there are additional lines of garbage before or after the email_body, you can simply add additional throw away variables to account for them.
Once again feel free to ask any follow up questions.
Michael
Resources
List Comprehension
Star Unpacking

NetLogo - exchanging variable values across links or agentsets (not within breeds)

I am building a NetLogo model that tries to explain how agents find information they need to make a decision by bumping into other agents as they move about a space. There are three types of agents, each type has their own behavior rules and interact with their environment in different ways. The three types of agents, however, are all part of the same organization [Organization A].
The code below shows the breed names and the kinds of variables I'm using.
breed [Implementers Implementer];; Member of Organization A
breed [IMDeployeds IMDeployed];; Member of Organization A
breed [IMremotes IMremote];; Member of Organization A
... [other breeds]
Turtles-own [exchangeinfo holdinfo inforelevant infoarray
taskcomplexity done];; is an info exchange going to happen, does the
turtle have info, is info relevant, and then an array
extensions [array]
globals [complete routinemeeting]
I want to do three things:
1&2 Create a mechanism that joins the IMRemotes to the IMDeployeds and the IMDeployeds to the Implementers.
(I've already tried creating links - I'm not sure that the mechanism does what I want the third thing to do:)
3: Periodically check in with the agents that are linked together to cross-check variable values so that "information" can be "exchanged". Code I have for when agents are in the same space and can use "turtles-here" is below:
ask Implementers [
ifelse any? other Implementers [have-info-same-team] [change-location]
ifelse any? IMDeployeds-here [have-info-same-team] [change-location]
end
to have-info-same-team
ifelse any? turtles-here with [holdinfo > 0] [checkarray9] [change-
location]
end
to checkarray9
ifelse any? other turtles-here with [array:item infoarray 9 > 0]
[array:set infoarray 9 1 set holdinfo 1 checkarray8][checkarray8]
end
[etc, checking each position from 9 down to 0 in the array until you've gotten all the new information from that agent that you need]
When I try to ask my-links to do any of these things [so that the agents in the same organization, but different "functions, if you will, can have purposeful meetings rather than relying on being in the same space with each other to communicate], I'm told that the procedure is a "turtle only" procedure or that infoarray is a turtle-only variable.
Any help or suggestions greatly appreciated!
Rather than asking the links to do these things, you want to ask the turtles at the other end of the links. I don't know if you have created directed or undirected links, but something like
ask turtle-set [other-end] of my-out-links [do something]
or
ask my-out-links [ask other-end [do something]]
will make the ask of the turtles at the other end of the links to this turtle. (Note that [other-end] of my-out-links yields a list of turtles rather than a turtleset, thus the use of turtle-set to turn the list into a turtleset. my-out-links seems to work with both directed and undirected links. See http://ccl.northwestern.edu/netlogo/docs/dictionary.html#my-out-links.)
Hope this helps,
Charles

Count number of patches with specific value within specific clusters of patches

I am new to NetLogo and I am still struggling with the links between patches and agents. I am building a land-use change model, where the agents are farmers. The patches in my model have a "lotid-farmer" value (to know which patch belongs to which farmer; all of them together correspond to the farmer's farm) and a "land-use" value. I am trying to count how many "land-use = 1" patches I have in each "lotid-farmer" (farms) and assign that to a variable that the agents have called "forest-size". I have tried many different things, like this piece of code (which does not work):
(foreach lotid-farmer count patches [ land-use = 1 ] set forest-size )
I wonder if anyone could explain why this statement makes no sense and suggest something else that could work or a tutorial on how to loop in NetLogo with "foreach"? Thank you in advance.
lotid is a value. foreach requires a list and a command-task. Also, your set operator doesn't have a value associated with it.
Actually, I wouldn't use a foreach and just ask farmers to set the variable. I'm going to assume lotid-farmer is the who of the farmer.
ask farmers [
set forest-size count patches with [land-use = 1 and lotid-farmer = myself]
]

Resources